Kazalo
- Premica po metodi najmanjših kvadratov
- Predstavitev z histogramom
- Premica po metodi najmanjših kvadratov z upoštevanjem napak
1. Primer iskanja koeficientov premice po metodi najmanjših kvadratov
Skripta v pythonu poišče koeficiente premice in napake koeficientov. Podatki se nahajajo v datoteki test.txt v dveh stolpcih. V prvem stolpcu je x, v drugem je y.
from scipy import polyval,sqrt,stats import matplotlib.pyplot as plt import numpy as np data=np.loadtxt("test.txt") x=data[:,0] y=data[:,1] slope, intercept, r, prob2, see = stats.linregress(x, y) mx = x.mean() sx2 = ((x-mx)**2).sum() sd_intercept = see * sqrt(1./len(x) + mx*mx/sx2) sd_slope = see * sqrt(1./sx2) print "intercept:",intercept," error:",sd_intercept print "slope:",slope," error:",sd_slope yr=polyval([slope,intercept],x) #matplotlib ploting plt.title('Linear Regression Example') plt.plot(x,y,'go') plt.plot(x,yr,'--') plt.legend(['measurement','fit']) plt.ylabel('y label (units)') plt.xlabel('x label (units)') plt.axis([0,100,0,1000]) plt.show()
Rezultat zgornje skripte je prikazan na sliki (levo). matplotlib ponuja še nešteto izboljšav slike. Skripta izpiše v terminalu vrednosti koeficientov in njihove napake:
intercept: -73.7 error: 4.0 slope: 10.17 error: 0.075
Statistično gledano trdimo, da je koeficient naklona 10.17 ± 0.08 ter koeficient preseka -74 ± 4.
2. Primer predstavitve podatkov v obliki histograma in normalne porazdelitve
Spodnja skripta (avtor M.Živec), predstavi podatke iz datoteke text.txt, ki so podani v enem stolpcu, v obliki histograma. Na to sliko doda še normalno porazdelitev. Sredina in širina normalne krivulje sta povprečna vrednost in varianca vzorca.
import matplotlib.pyplot as plt import numpy as np import matplotlib.mlab as mlab from scipy.stats import norm import math data=np.loadtxt("text.txt") (mu, sigma) = norm.fit(data) w=data.max()-data.min() x=np.arange(data.min()-w*0.2,data.max()+w*0.2,w/50.0) y = mlab.normpdf( x, mu, sigma) plt.plot(x, y) n, bins, patches = plt.hist(data, math.sqrt(data.size),normed=1) plt.legend(['Normalna','Meritev']) plt.xlabel('t (ms)') plt.ylabel('verjetnost (1/ms)') print mu,sigma, data.mean(), math.sqrt(data.var()) plt.show()
3. Primer iskanja koeficientov premice z upoštevanjem napak
Skripta v pythonu poišče koeficiente premice ali drugega modela podanega v funkciji func. Nato poišče napake koeficientov. Podatki se nahajajo v datoteki podatki.txt v treh stolpcih. V prvem stolpcu je x, v drugem je y, v tretjem je napaka y. Vrednosti y in napake se nato še preračunajo na željene količine. Pri računanju napake upoštevamo pravilo za izračun napak.
from scipy import sqrt from scipy.optimize import curve_fit import matplotlib.pyplot as plt import numpy as np data = np.loadtxt("podatki.txt") x = data[:, 0] tlak = data[:, 1] #tlak bomo preracunali za vrednosti y et = data[:, 2] #napaka meritve tlaka #izracun izkoristka iz tlaka y = (790 * 9.81 * 1.695) / (tlak * 1e5 * 1.695 * 0.002590) ey = y / tlak * et #izracun napake iz tlaka #model - v tem primeru je premica z koeficienti a in b def func(x, a, b): return a+b*x #iskanje koeficientov z upostevanjem napake fitpar,fitcov = curve_fit(func,xdata=x, ydata=y, sigma=ey) print "presek:",fitpar[0],"+-",sqrt(fitcov[0,0]) print "naklon",fitpar[1],"+-",sqrt(fitcov[1,1]) #iskanje koeficientov brez upostevanja napake #fitpar2,fitcov2 = curve_fit(func,xdata=x,ydata=y) #print "brez upostevanja napak" #print "presek:",fitpar2[0],"+-",sqrt(fitcov2[0,0]) #print "naklon",fitpar2[1],"+-",sqrt(fitcov2[1,1]) #matplotlib plotting plt.errorbar(x, y, yerr=ey, fmt='go') plt.plot(x, func(x, fitpar[0], fitpar[1]), '--') plt.legend(['meritev 790kg', 'linearni model']) plt.ylabel('izkoristek') plt.xlabel('pretok (l/min)') plt.axis([10, 40, 0.7, 1]) plt.show()
4. Primer iskanja koeficientov kompleksnejšega modela
Skripta v pythonu poišče koeficiente modela podanega v funkciji func. Ker funkcija obdela celoten array v enem klicu in ker je problem ko je kot 0, moramo ročno preračunati vsako vrednost posebej. Nato poišče napake koeficientov. Podatki se nahajajo v datoteki podatki.txt v dveh stolpcih. V prvem stolpcu je x, v drugem je y.
import matplotlib.pyplot as plt import numpy as np from scipy.optimize import curve_fit import math data = np.loadtxt("podatki.txt",skiprows=3) y = data[:,1] x = data[:,0] #model izracuna ga za vse elemente naenkrat def func(x, a, b, c,d): #problem is when x is zero division doesnt work arg = b * (x-d) ans = arg #make a copy for i in range(len(ans)): #calculate for each element if arg[i] == 0.0: ans[i] = 1.0 else: ans[i] = np.power(np.divide(np.sin(arg[i]),arg[i]),2) return a * ans + c fitpar,fitcov = curve_fit(func,xdata=x, ydata=y) print "parametri:",fitpar print "napake:",np.sqrt(np.diag(fitcov)) plt.plot(x,y,linewidth=2.0) plt.plot(x,func(x,fitpar[0],fitpar[1],fitpar[2],fitpar[3]),"r",linewidth=2.0) plt.title("Naslov") plt.xlabel(r'Kot ($\degree$)') plt.ylabel("Amplituda (V)") plt.legend(["meritev","model"]) plt.show()
Egon Pavlica, 21. maj 2014