2014-05-16 4 views
6

Kiedy próbuję dopasować moje dane, wyniki są nieco dziwne, a ja nie rozumiem dlaczego? Uzyskane dopasowanie jest płaskie, a pierwsze wejście e = 0. wydaje się gdzieś podnosić błąd podziału. Sprawa jest tylko pracuje kiedy modyfikować e [0] = 1.0e-9scipy dziwne wyniki z dopasowania krzywej

Wynik jest następujący: enter image description here

Od przykład here wydaje się, że mój przykład nie jest tak daleko od tego co czytałem , ale utknąłem, więc czy możesz mi pomóc, proszę, co się dzieje w moim przypadku?

import numpy as np 
from scipy.optimize import curve_fit 
import matplotlib.pyplot as plt 

src_s = np.array((45.59,50.66664,59.74871,65.71018,72.76012,79.06256,84.13755,90.39944, 
        96.33653,101.65667,106.27968,110.76301,114.41808,117.21922,120.51836)) 
src_e = np.array((0.0,0.00126,0.00503,0.00804,0.01228,0.01685,0.02127,0.02846,0.03666, 
        0.04581,0.05620,0.06882,0.08005,0.09031,0.10327)) 
# plot source data 
plt.plot(src_e, src_s, 'o') 
# fitting function 
def sigma(e, k ,n): return k*(e**n) 
# find parameters curve fitting 
param, var = curve_fit(sigma, src_e, src_s) 
new_e = np.linspace(src_e.min(), src_e.max(), 50) 
plt.plot(new_e, sigma(new_e, *param)) 

# modify first input 
src_e[0]=1.0e-9 
# relaunch parameters curve fitting 
param, var = curve_fit(sigma, src_e, src_s) 
new_e = np.linspace(src_e.min(), src_e.max(), 50) 
plt.plot(new_e, sigma(new_e, *param)) 

plt.show() 

Z góry dziękuję za pomoc.

+0

Proszę wyjaśnić „Wyniki są nieco dziwne, a ja nie rozumiem, dlaczego” –

+1

dodałem zdjęcie dla Ciebie. Witamy w SO! ;) –

+0

Dziękuję przyjacielu;) Weź piwo! – Jyb

Odpowiedz

2

Źródłem problemu jest takie złe pierwsze przybliżenie parametrów (właściwie żaden parametr wyjściowy przewidzianego curve_fit).

Funkcja docelowa może być łatwo linearyzacji. Zróbmy to, zrób regresji liniowej, aby uzyskać dobry zestaw parametrów początkowych odgadnięcia curve_fit (przechodzą mu przez p0=). Otrzymany lepsze dopasowanie (o mniejszej pozostałości) i nie ma potrzeby, aby zastąpić pierwszą wartość być 1e-9:

In [38]: 

src_e[0]=1.0e-9 
# relaunch parameters curve fitting 
param, var = curve_fit(sigma, src_e, src_s) 
new_e = np.linspace(src_e.min(), src_e.max(), 50) 
src_e[0]=0 
plt.plot(new_e, sigma(new_e, *param)) 
plt.plot(src_e, src_s, 'ro') 
plt.savefig('1.png') 
print 'Residue is:', ((sigma(src_e, *param)-src_s)**2).sum() 
Residue is: 2168.65307587 

enter image description here

In [39]: 

import scipy.stats as ss 
src_e[0]=0 
V=ss.linregress(np.log(src_e)[1:], np.log(src_s)[1:]) #avoid log(0) 
param, var = curve_fit(sigma, src_e, src_s, p0=(np.exp(V[1]), V[0])) 
new_e = np.linspace(src_e.min(), src_e.max(), 50) 
plt.plot(new_e, sigma(new_e, *param)) 
plt.plot(src_e, src_s, 'ro') 
plt.savefig('1.png') 
print 'Residue is:', ((sigma(src_e, *param)-src_s)**2).sum() 
Residue is: 2128.85364181 

enter image description here

+0

Dziękuję za pomoc, zapamiętam twoje podejście, ale postaram się pracować z następną odpowiedź od okucia wydaje się być wizualnie lepiej na początku krzywej, a to najważniejsze zachowanie w moim przypadku. – Jyb

0

Pierwszy punkt nie być na krzywej, więc musisz zmienić formułę krzywej:

import numpy as np 
from scipy.optimize import curve_fit 
import matplotlib.pyplot as plt 

src_s = np.array((45.59,50.66664,59.74871,65.71018,72.76012,79.06256,84.13755,90.39944, 
        96.33653,101.65667,106.27968,110.76301,114.41808,117.21922,120.51836)) 
src_e = np.array((0.0,0.00126,0.00503,0.00804,0.01228,0.01685,0.02127,0.02846,0.03666, 
        0.04581,0.05620,0.06882,0.08005,0.09031,0.10327)) 
# plot source data 
plt.plot(src_e, src_s, 'o') 

def sigma(e, k ,n, offset): return k*((e+offset)**n) 
# find parameters curve fitting 
param, var = curve_fit(sigma, src_e, src_s) 
new_e = np.linspace(src_e.min(), src_e.max(), 50) 
plt.plot(new_e, sigma(new_e, *param)) 

tu jest wyjście:

enter image description here

+0

Wielkie dzięki za cynk. przesunięcie może być rzeczywiście dodatkowy parametr dla funkcji docelowej , ale zależy to od wyników eksperymentalnych. Tutaj wygląda na to, że przesunięcie zapewnia najlepsze dopasowanie i uniknięcie błędu z podziałem zerowym. – Jyb