pravé hodnoty odpovídají polynomu 4. stupně (dominantně kvadratický)
testujeme modely pro polynomy 1. - 10. stupně
%matplotlib inline
from numpy import *
from matplotlib import pyplot as pl
x=r_[-3:3:20j]
sigy=3.
tres=[0.5,0.2,7,-0.5,0] #skutecne parametry
ytrue=polyval(tres,x)
pl.plot(x,ytrue,'k')
y=ytrue+random.normal(0,sigy,size=x.shape)
pl.plot(x,y,'*')
ords=arange(1,10)
res=[polyfit(x,y,i,cov=True) for i in ords]
#[[round(p,3) for p in r[0][::-1]] for r in res]
[" ".join(["%6.3f"%p for p in r[0][::-1]]) for r in res]
errs=[[round(p,5) for p in sqrt(r[1].diagonal()[::-1])/sigy] for r in res]
print('směrodatná odchylka koeficientů:')
[" ".join(["%6.3f"%p for p in e]) for e in errs]
s0=[((y-polyval(r[0],x))**2).sum() for r in res]
siges=sqrt(array(s0)/(20-1-ords))
print("redukov. chi2: \n",siges)
from scipy import stats
print("5% kvantil Stud. rozdělení (s kles. počtem stupňů volnosti): \n",stats.t(19-ords).isf(0.05))
statistické významnosti (t-hodnoty pro nulovou hypotézu) jednotlivých parametrů
pro dané měření mohou vycházet významné hodnoty i u vyšších momentů
[" ".join(["%6.3f"%p for p in abs(res[i][0][::-1]/array(errs[i]))]) for i in range(len(res))]
strue=[((ytrue-polyval(r[0],x))**2).sum() for r in res]
sigcom=sqrt(array(s0)/(20-1-ords)) # redukovany chi2
pl.semilogy(ords,sigcom)
pl.semilogy(ords,sqrt(array(strue)/(20-1-ords)))
pl.legend(['red. chi2','true chi2'])
pl.grid()
správným kritériem je validace - chi2 na testovacím vzorku:
from numpy.random import normal
def test_poly(x,ytrue,sigy,ords=r_[1:10],rep=1):
'''podle rep:
1: rozdil skutecne funkce a modelu
2: rozdil nove sady dat a modelu
'''
y=ytrue+normal(0,sigy,size=x.shape)
res=[polyfit(x,y,i,cov=True) for i in ords]
if rep==1:
scom=[((ytrue-polyval(r[0],x))**2).sum() for r in res]
return array(scom)/(len(x)-1-ords)
if rep==2:
ycom=ytrue+normal(0,sigy,size=x.shape)
scom=[((ycom-polyval(r[0],x))**2).sum() for r in res]
return array(scom)/(len(x)-1-ords)
return res
# provedeme 100 opakování testu
fullmat=r_[[test_poly(x,ytrue,2,rep=1) for k in range(100)]]
fullmat.mean(0)
fullmat2=r_[[test_poly(x,ytrue,2,rep=2) for k in range(100)]]
pl.errorbar(ords[1:],fullmat.mean(0)[1:],fullmat.std(0)[1:]/10.)
pl.errorbar(ords[1:],fullmat2.mean(0)[1:],fullmat2.std(0)[1:]/10.)
pl.xlabel("stupen polynomu")
pl.legend(["gen. chyba","validace"])
apars=[test_poly(x,ytrue,2,rep=0) for k in range(100)] #zaznam hodnot nafitovanych parametru
def rep_pars(iord=4):
zmat=r_[[a[iord][0] for a in apars]]
cmat=r_[[a[iord][1].diagonal() for a in apars]]
zrep=array([zmat.mean(0),zmat.std(0),sqrt(cmat.mean(0)),sqrt(cmat).std(0)])
return zrep[:,::-1]
zot6=rep_pars(6)
zot6[0]/zot6[1] # podil stredni hodnoty a nejistoty
kovarianční matice dobře odpovídá rozptylu parametrů
zot6[1]/zot6[2]
zotx=[rep_pars(i) for i in range(7)]
[' '.join(['%6.3f'%ww for ww in zz[0]/zz[1]]) for zz in zotx]