2013-01-22 9 views
5

Mam problem z dopasowaniem gaussa do danych. Myślę, że problem polega na tym, że większość elementów jest bliska zeru i nie ma wielu punktów, które można by dopasować. Ale w każdym razie, myślę, że oni robią dobry zestaw danych, by dopasować, i nie dostaję tego, co jest confussing pytonem. Oto program, dodałem również linię do wykreślenia danych, dzięki czemu można zobaczyć, co staram się dopasowaćgaussian fit with scipy.optimize.curve_fit w python z błędnymi wynikami

#Gaussian function 
def gauss_function(x, a, x0, sigma): 
    return a*np.exp(-(x-x0)**2/(2*sigma**2)) 

# program 
from scipy.optimize import curve_fit 
x = np.arange(0,21.,0.2) 
# sorry about these data! 
y = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.2888599818864958e-275, 1.0099964933708256e-225, 4.9869496866403137e-184, 4.4182929795060327e-149, 7.2953754336628778e-120, 1.6214815763354974e-95, 2.5845990267696154e-75, 1.2195550372375896e-58, 5.6756631456872126e-45, 7.2520963306599953e-34, 6.0926453402093181e-25, 7.1075523112494745e-18, 2.1895584709541657e-12, 3.1040093615952226e-08, 3.2818874974043519e-05, 0.0039462011337049593, 0.077653596114448178, 0.33645159419151383, 0.40139213808285212, 0.15616093582013874, 0.0228751827752081, 0.0014423440677009125, 4.4400754532288282e-05, 7.4939123408714068e-07, 7.698340466102054e-09, 5.2805658851032628e-11, 2.6233358880470556e-13, 1.0131613609937094e-15, 3.234727006243684e-18, 9.0031014316344088e-21, 2.2867065482392331e-23, 5.5126221075296919e-26, 1.3045106781768978e-28, 3.1185031969890313e-31, 7.7170036365830092e-34, 2.0179753504732056e-36, 5.6739187799428708e-39, 1.7403776988666581e-41, 5.8939645426573027e-44, 2.2255784749636281e-46, 9.4448944519959299e-49, 4.5331936383388069e-51, 2.4727435506007072e-53, 1.5385048936078214e-55, 1.094651071873419e-57, 8.9211199390945735e-60, 8.3347561634783632e-62, 8.928140776588251e-64, 1.0960564546383266e-65, 1.5406342485015278e-67, 2.4760905399114866e-69, 4.5423744881977258e-71, 9.4921949220625905e-73, 2.2543765002199549e-74, 6.0698995872666723e-76, 1.8478996852922248e-77, 6.3431644488676084e-79, 0.0, 0.0, 0.0, 0.0] 

plot(x,y) #Plot the curve, the gaussian is quite clear 
plot(x,y,'ok') #Overplot the dots 

# Try to fit the result 
popt, pcov = curve_fit(gauss_function, x, y) 

Problemem jest to, że wyniki dla popt jest

print popt 
array([ 7.39717176e-10, 1.00000000e+00, 1.00000000e+00]) 

Każda podpowiedź dlaczego tak się dzieje?

Dzięki!

+0

Pierwszą rzeczą do zrobienia byłoby wyrzucenie zer i wszystkich tych '10 ** (70)' -s. Jeśli naprawdę chcesz użyć 'curve_fit', to znaczy. W przeciwnym razie po prostu oblicz pierwsze i drugie momenty zbioru danych - te dwa definiują całkowicie funkcję gaussowską. –

+1

Oprócz tego, że dopasowywana funkcja nie jest ograniczona do obszaru jednostki (również parametr 'a' jest dopasowywany), więc pierwsze dwie pierwsze sekundy nie wystarczą. – bogatron

Odpowiedz

13

Twój problem dotyczy początkowych parametrów curve_fit. Domyślnie, jeśli nie podano innych informacji, zaczyna się od tablicy 1, ale to oczywiście prowadzi do radykalnie błędnego wyniku. Można to skorygować po prostu dając rozsądny wektor startowy. Aby to zrobić, zacznę od szacowanej średniej i odchylenia standardowego zbioru danych

#estimate mean and standard deviation 
meam = sum(x * y) 
sigma = sum(y * (x - m)**2) 
#do the fit! 
popt, pcov = curve_fit(gauss_function, x, y, p0 = [1, mean, sigma]) 
#plot the fit results 
plot(x,gauss_function(x, *popt)) 
#confront with the given data 
plot(x,y,'ok') 

To będzie doskonale zbliżone wyniki. Pamiętaj, że dopasowywanie krzywych w ogólności nie może działać, chyba że zaczniesz od dobrego punktu (w basenie konwergencji, aby było jasne), a to nie zależy od implementacji. Nigdy nie bądź ślepy, kiedy możesz wykorzystać swoją wiedzę!

+0

Wielkie dzięki, to zadziałało! –

+0

Działa, ale dlaczego? Dlaczego zaczynasz od 'mean = sum (x * y)'? –