Ebben a notebookban bemutatjuk, hogyan kell az illesztési feladatokat elvégezni.
%pylab inline
figsize(6,6) #Képméret megváltoztatása
Az adatainkra is ugyanolyan függvényt kell illeszteni, mint amit fentebb megismertünk.
A függvények illesztéséhez a curve_fit
eljárást használjuk, a scipy
csomagból, mely a Gnuplot-hoz hasonló elven keresi meg a paraméterek ideális értékét.
adat=loadtxt("sinusadatok.dat")
x=adat[:,0]
y=adat[:,1]
z=adat[:,2]
from scipy.optimize import curve_fit
figsize(10,10)
def func(x, a,b,c,d):
return a*cos((d*(x+c)))+b
parameter, covariance_matrix = curve_fit(func, x, z)
Az illesztett paraméterek:
print(parameter)
A kovariancia mátrix diagonális elemei megegyeznek a hiba négyzetével, tehát az illesztési hiba Ãgy számolandó:
print(sqrt(diag(covariance_matrix)))
Kicsit "szofisztikáltabban" Ãgy lehet lerÃni:
print("Amplitúdó:",parameter[0], "+/-", sqrt(diag(covariance_matrix)[0]))
print("y eltolás:",parameter[1], "+/-", sqrt(diag(covariance_matrix)[1]))
print("x eltolás:",parameter[2], "+/-", sqrt(diag(covariance_matrix)[2]))
print("Fázisnyújtás:",parameter[3], "+/-", sqrt(diag(covariance_matrix)[3]))
plot(x,z, "go")
xlabel("Idő [sec]")
ylabel("Elmozdulás [m]")
title("Lengés")
grid(True)
plot(x, func(x, *parameter), 'r-', label='fit',linewidth=5.0)
Lehetőség van kezdőfeltételt is megadni az illesztéshez. Erre a "p0" parameter szolgál. A mérési hibát a "sigma" paraméter után kell megadni.
error=randn(len(z)) # normál eloszlású random tömböt választunk hibának
print(error[0])
# Megadunk kezdőfeltétlet, és azt mondjuk, hogy az előbb számolt hiba a mérési hibánk.
param, cov = curve_fit(func, x, z, p0=(1.,3.,0,1), sigma=error)
figure(figsize=(6,6))
plot(x,z, "go")
xlabel("Idő [sec]")
ylabel("Elmozdulás [m]")
title("Lengés")
grid(True)
plot(x, func(x, *param), 'r-', label='fit',linewidth=5.0)
print("Amplitúdó:",param[0], "+/-", sqrt(diag(cov)[0]))
print("y eltolás:",param[1], "+/-", sqrt(diag(cov)[1]))
print("x eltolás:",param[2], "+/-", sqrt(diag(cov)[2]))
print("Fázisnyújtás:",param[3], "+/-", sqrt(diag(cov)[3]))
Gyakran elÅ‘fordul, hogy olyan függvényt kell illeszteni, ami nehezen találja meg a megfelelÅ‘ illeszkedést (erÅ‘sen függ a kezdeti értékek helyes megadásától). Az elÅ‘re definiált kezdÅ‘ értékekbÅ‘l gyakran rossz eredményt fogunk kapni. Ekkor szükséges olyan, közel helyes paramétereket beállÃtani a függvénynél, ahonnan könnyen megtalálja az algoritmus a helyes megoldást.
Található a mappában egy "fitting.csv" állomány, ami egy csillapÃtott rezgÅ‘mozgás adatsorát tartalmazza. Az illesztendÅ‘ függvény alakja: $$f(x)=A*sin(2\pi\cdot\frac{x}{T} -\phi)*exp(\frac{-x}{\tau})+F0 , $$ ahol A az amplitúdót, $\phi$ a kezdÅ‘ fázist, T a periódusidÅ‘t, $\tau$ a csillapÃtást és F0 a nyugalmi kitérést mutatja.
A függvény bonyolultsága miatt az illesztést csakis a kezdÅ‘paraméterek helyes becslése után lehet jól elvégezni. A tapasztalatok azt mutatják, hogy a periódusidÅ‘ becslése a legfontosabb az ilyen periodikus jelek illesztése során, Ãgy a T jó megválasztása nélkülözhetetlen a sikeres illesztéshez.
Első lépésben nézzünk bele a fájlba:
%%bash
head fitting.csv
Rajzoljuk ki az adatokat, hogy meg tudjuk becsülni a paraméterek értékét:
fitting=loadtxt('fitting.csv')
x=fitting[:,0]
data=fitting[:,1]
plot(fitting[:,0],fitting[:,1], ".-")
grid()
Próbáljuk meg a szokott módon az illesztést:
def func(x, amp,t,phi,tau,f0):
return amp*sin(x/t*2*pi-phi)*exp(-x/tau)+f0
parameter, covariance_matrix = curve_fit(func, x, data)
print(parameter)
figure(figsize=(10,10))
plot(x,data, "g.")
xlabel("Idő [sec]")
ylabel("Elmozdulás [m]")
title("Lengés")
grid(True)
plot(x, func(x, *parameter), 'r-', label='fit',linewidth=1.0)
Mivel a fenti illesztés láthatóan nem helyes, adjunk meg közel helyes kezdőértéket az illesztéshez. Ehhez a curve_fit parancs p0 kapcsolóját kell ismét használni.
def func(x, amp,t,phi,tau,f0):
return amp*sin(x/t*2*pi-phi)*exp(-x/tau)+f0
parameter, covariance_matrix = curve_fit(func, x, data, p0=[95., 2.5, -pi/2, 50.,120.])
print(parameter)
figure(figsize=(10,10))
plot(x,data, "g*")
xlabel("Idő [sec]")
ylabel("Elmozdulás [m]")
title("Lengés")
grid(True)
plot(x, func(x, *parameter), 'r-', label='fit',linewidth=2.0)