navazuje na Intervaly spolehlivosti
%pylab inline
import matplotlib
matplotlib.rcParams['figure.figsize'] = [10, 5]
from scipy import stats
n=100
p=0.1
i=30
ptrue=r_[.05:1:0.05]
cont=0.01
xlo=r_[[stats.binom(n,p).ppf(cont) for p in ptrue]]
xhi=r_[[stats.binom(n,p).ppf(1-cont) for p in ptrue]]
plot(xlo,ptrue,':')
plot(xhi,ptrue,':')
cont=0.05
xlo=r_[[stats.binom(n,p).ppf(cont) for p in ptrue]]
xhi=r_[[stats.binom(n,p).ppf(1-cont) for p in ptrue]]
plot(xlo,ptrue)
plot(xhi,ptrue)
plot([0,100],[0,1.])
axvline(20)
xlabel("merena hodnota (100 pokusu)")
ylabel("skutecna hodnota")
legend(["low 1%","high 1%","low 5%","high 5%"])
(relativní) pološířka binomického rozdělení klesá s počtem pokusů (a blíží se - pro pravděp. blízkou středu 0.5 - normálnímu rozdělení)
plot(r_[:80]/80.,stats.binom(80,0.3).pmf(r_[:80])*4.)
plot(r_[:40]/40.,stats.binom(40,0.3).pmf(r_[:40])*2.)
plot(r_[:20]/20.,stats.binom(20,0.3).pmf(r_[:20]))
stats.binom(80,0.3).pmf(r_[0:40:4])
legend(["%i pokusu"%i for i in [80,40,20]])
výpočet mezí pro skutečnou hodnotu podle naměřené dosáhneme "inverzí" funkcí odpovídající modré a zelené mezi pásu spolehlivosti v prvním grafu (konstruujeme horizontálně, odečítáme vertikálně)
#jednoduchá lineární interpolace
interl = lambda a,b,z:b[0]+(b[1]-b[0])*(z-a[0])/(a[1]-a[0])
def truelims(z=20):
i,j=(xlo<z).sum(),(xhi<z).sum()
return interl(xhi[j-1:j+1],ptrue[j-1:j+1],z),interl(xlo[i-1:i+1],ptrue[i-1:i+1],z)
truelims(20),truelims(40)
ptrue=r_[.05:1:0.02]
fmap=r_[[stats.binom(80,ptrue[i]).pmf(r_[:80]) for i in range(len(ptrue))]]
imshow(fmap,origin="lower",extent=[0,80,0,1],aspect="auto")
plot(fmap.sum(0)[:70])
plot(fmap.sum(1)[:45])
fmap.sum(0)[:8]
legend(["suma sloupce","suma radku"],loc=4)
pro malé hodnoty je pravděpodob. obsah nízký
#rucni vypocet...
from scipy.special import factorial
poiss=lambda p,n:pow(p,n)/factorial(n)*exp(-p)
mod1=poiss(5.,r_[1:20])
plot(r_[1:20],mod1)
sum(mod1)
from scipy import optimize
uplim=lambda n,prob,pinit:optimize.fsolve(lambda p:sum(poiss(p,[r_[:n]]))-prob,pinit)[0]
def get_poiss_lims(prob=0.05,nmax=15,pinit=4.):
rep=[pinit]
for i in range(1,15):
rep.append(uplim(i,prob,rep[-1]))
return rep[1:]
#sum(poiss(4.,r_[:5]))-0.05
nmax=15
l1=get_poiss_lims(0.9,nmax,pinit=1.)
l2=get_poiss_lims(0.95,nmax,pinit=1.)
l3=get_poiss_lims(0.98,nmax,pinit=1.)
u1=get_poiss_lims(0.1,nmax,pinit=4.)
u2=get_poiss_lims(0.05,nmax,pinit=4.)
u3=get_poiss_lims(0.02,nmax,pinit=4.)
x=r_[1:nmax]
[plot(x,y) for y in [l1,l2,l3,u1,u2,u3]]
plot(x,x)
slist=[10,5,2]
legend(["l.l. %i%%"%a for a in slist]+["u.l. %i%%"%a for a in slist],loc=2)
xlabel("mereno")
ylabel("stred. hodnota")
axvline(7)
použijeme kvantily Poissonova rozdělení
ktrue=r_[3:25:2]
ktrue2=r_[10:35:2]
for cont in [0.1,.05,0.02]:
xlo=[stats.poisson(k).ppf(cont) for k in ktrue2]
xhi=[stats.poisson(k).ppf(1-cont) for k in ktrue]
fun=np.polyfit(xlo,ktrue2,6)
fun2=np.polyfit(xhi,ktrue,6)
plot(xlo,ktrue2,'d')
plot(xlo,polyval(fun,xlo),'b')
plot(xhi,polyval(fun2,xhi),'b')
ylim(0,40)
stats.poisson(15).ppf(0.95)
pravděpodobnost v Bayesovském přístupu vychází z poměru (integrálních) pravděpodobností
$$1-\beta=\int_{-\infty}^{\theta_{up}} p(\theta|x) d\theta = \frac{\int_{-\infty}^{\theta_{up}} L(x|\theta) \pi(\theta) d\theta}{\int_{-\infty}^{\infty} L(x|\theta) \pi(\theta) d\theta}$$
kde $\pi(\theta)$ je zvolená a-priorní pravděpodobnost pro danou hodnotu parametru
from scipy import integrate,optimize
cpos=r_[-3:2:0.1]
clasc=stats.norm(cpos,1).isf(0.05)
V nejjednodušším případě $\pi(\theta)$ je konstantní.
Pokud klademe podmínku nezápornosti, pomocí inverse survival function můžeme dopočítat polohu horní limity, kde integrál nad ní je dané procento integrálu přes celou povolenou (nezápornou) oblast.
$L(x|\theta)$ bereme opět normální rozdělení s jednotkovou disperzí.
# cpos je stredni hodnota
bayes=stats.norm(cpos,1).isf(stats.norm(cpos,1).sf(0)*0.05)
# hodnoty v prom. bayes budou odpovidat ne prsti 0.05, ale 0.05*stats.norm(cpos,1).sf(0)
plot(cpos,clasc)
plot(cpos,bayes)
fill_between(cpos,bayes,4,alpha=0.1)
axhline(0,ls=":")
axvline(0,ls=":")
grid()
xlabel(r"$\theta_{obs}$")
ylabel("95% limit")
Situace změní, pokud v Bayesovském přístupu zvolíme jinou a-priorní pravděpodobnost $\pi(\theta)$, např. podle Jeffrey $1/x$...
at0=0.1
jeff_gauss=lambda x,m:exp(-(x-m)**2)/x
jnorm=r_[[integrate.quad(jeff_gauss,at0,20,i)[0] for i in cpos]]
plot(cpos,jnorm)
xlabel("skut. hodnota")
ylabel("integr. 0-infty (Jeffrey prior)")
w1=lambda p,x:p[0]*exp(-(x-p[1])**2/2./p[2]**2)
w3=lambda p,x:p[0]*exp((-(x-p[1])**2+p[3]*(x-p[1])**3)/2./p[2]**2)
normmod=optimize.leastsq(lambda p:w1(p,cpos)-jnorm,[jnorm.sum(),0,1.])[0]
normmod3=optimize.leastsq(lambda p:w3(p,cpos)-jnorm,[jnorm.sum(),0,1.,0])[0]
plot(cpos,w1(normmod,cpos)-jnorm)
plot(cpos,w3(normmod3,cpos)-jnorm)
grid()
title("aproximace")
ylabel("reziduum")
legend(["w1: gaussovka","w3: i clen 3.radu"])
vzhledem k asymetrii neni gausovka vhodna funkce
jvars=[[integrate.quad(jeff_gauss,at0,k,i)[0] for i in cpos] for k in r_[0.4:2.5:.4]]
#ruzne horni meze 0.4-2.5
[plot(cpos,b) for b in jvars]
plot(cpos,jnorm,':')
xlabel("skut. hodnota")
ylabel("integ 0.1 -- horni mez")
legend(r_[0.4:2.5:.4],loc=2)
závislost parametru gaussovky na horní mezi se pokoušíme modelovat kvadratickými polynomy
# nadale se snazime fitovat gausovky
varep=r_[[optimize.leastsq(lambda p:w3(p,cpos)-array(b),[sum(b),0,1.,0])[0] for b in jvars]]
fullmod=[polyfit(r_[0.4:2.5:.4],v,2) for v in r_[varep].transpose()]
fullmod
# jak dobry je fit
[(abs(polyval(fullmod[i],r_[0.4:2.5:.4])-varep[:,i])).max() for i in range(4)]
i=3
plot(r_[0.4:2.5:.4],polyval(fullmod[i],r_[0.4:2.5:.4]))
plot(r_[0.4:2.5:.4],varep[:,i],'+')
ylabel("asym. clen")
title("aproximace parametru fitu asym. gaussovkou")
# horni limit v interv. [0.4:2.5]
# param. p(stred rozdeleni) v interv. [-3:2]
confid=lambda upl,cent:w3([polyval(f,upl) for f in fullmod],cent)/w3(normmod3,cent)
#funkce modelující poměr integrálů (věrohodností)
#poměr vůči integrálu přes kladná čísla pro ruzne hodnoty stredu rozdeleni (a uplim 2.0)
jvars[4]/jnorm
#bayes solution
uplims=[.5]
lolims=[4.]
for i in r_[-2.5:4:0.5]:
lolims.append(optimize.fsolve(lambda p:confid(p,i)-0.1,lolims[-1])[0])
uplims.append(optimize.fsolve(lambda p:confid(p,i)-0.9,uplims[-1])[0])# 90 %
del uplims[0]
del lolims[0]
plot(r_[-2.5:4:0.5],uplims)
plot(r_[-2.5:4:0.5],lolims)
grid()
xbas=r_[0.1:2.5:.2]
plot(xbas,[confid(q,3) for q in xbas],hold=0)
plot(xbas,[confid(q,2) for q in xbas],hold=1)
plot(xbas,[confid(q,1) for q in xbas],hold=1)
plot(xbas,[confid(q,0.) for q in xbas],hold=1)
grid()
# flat (nonnegative) prior
plot(xbas,[1-stats.norm(3,1).sf(q)/stats.norm(3,1).sf(0) for q in xbas],'b:')
plot(xbas,[1-stats.norm(2,1).sf(q)/stats.norm(2,1).sf(0) for q in xbas],'g:')
plot(xbas,[1-stats.norm(1,1).sf(q)/stats.norm(1,1).sf(0) for q in xbas],'r:')
plot(xbas,[1-stats.norm(0,1).sf(q)/stats.norm(0,1).sf(0) for q in xbas],'c:')
title("jeffrey's prior vs. flat")
legend(["cent=3","cent=2","cent=1","cent=0"],loc=4)
xlabel("upper limit")
ylabel("frac to total")
ylim(-.2,1.1)
#prime nalezeni horni meze
zept=lambda q,lp:1-stats.norm(2,1).sf(q)/stats.norm(2,1).sf(0)-lp
optimize.fsolve(zept,3,0.9)
Horni / dolni limita s rovnom. apriorni pravdepodobnosti
xbas=r_[-2.5:4:0.5]
lolims2=r_[[stats.norm(i,1).isf(stats.norm(i,1).sf(0)*0.9) for i in xbas]]
uplims2=r_[[stats.norm(i,1).isf(stats.norm(i,1).sf(0)*0.1) for i in xbas]]
plot(xbas,uplims2,hold=0)
plot(xbas,lolims2,hold=1)
import sys;sys.path.append("/Users/Admin/Code/")
import nbexport as ne
ne.odir="/Users/Admin/Documents/Vyuka/MMZM/export/"
ne.export("Index.ipynb")