In [1]:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats
from functools import partial
plt.style.use('ggplot')
In [2]:
def mcmc_step(pdf, xs):
ds = np.random.uniform(-3, 3, size=len(xs))
r = np.random.uniform()
nxs = xs + ds
p0 = pdf(xs)
p1 = pdf(nxs)
if p1 > p0 or r < (p1 / p0):
return nxs
return xs
def mcmc_sample(pdf, xs, size=100000):
xss = []
for _ in range(size):
xs = mcmc_step(pdf, xs)
xss.append(xs)
return np.array(xss).T
def mcmc_generate(pdf, xs, size=100000):
ds = np.random.uniform(-3, 3, size=(size, len(xs)))
r = np.random.uniform(size=size)
p0 = pdf(xs)
xss = []
for i in range(size):
nxs = xs + ds[i]
p1 = pdf(nxs)
if p1 > p0 or r[i] < (p1 / p0):
xs = nxs
p0 = p1
xss.append(xs)
return np.array(xss).T
def pdf(xs):
x, y = xs
return np.exp(-((x - 2) * x + y ** 2) / 10) * np.sin(x * y + x) ** 2
%time xs, ys = mcmc_sample(pdf, np.array([0, 0]))
%time xs, ys = mcmc_generate(pdf, np.array([0, 0]))
In [3]:
plt.hist2d(xs, ys, bins=40)
plt.show()
plt.hist(np.sqrt(xs ** 2 + ys ** 2), bins=40)
plt.show()
Ein Experiment beobachtet $n$ Ereignisse. Die Nachweiswahrscheinlichkeit für ein Ereignis sei $ε$. Die wahre Anzahl ist Poisson-verteilt mit einem Mittelwert $μ$, der eine Funktion zweier Theorieparameter $a$ und $b$ ist, $μ = a^b$. Aus Kalibrationsmessungen ist bekannt dass $ε$ Gauss-verteilt ist mit $ε = 0.75 \pm 0.05$. Vom Parameter $b$ ist bekannt dass er nahe bei $b = 1$ liegt. Für ihn wird eine gleichförmige Verteilung im Bereich $0.9 < b < 1.1$ angenommen. Der Parameter $a$ muss positiv sein. Verwenden Sie bayes’sche Statistik und MCMC, und bestimmen Sie für $n = 1$ und $n = 10$ die posterior Verteilung von $a$ nach Integration über die Nuissance-Parameter $ε$ und $b$.
Zunächst müssen wir berechnen, wie die Effizienz die Verteilung der $n$ beeinflusst. Es sei $q_n$ die Wahrscheinlichkeit $n$ Ereignisse zu beobachten, wenn die $n$ um einen Mittelwert $\mu$ Poisson-verteilt sind und mit einer Effizienz $\varepsilon$ beobachtet werden. Es kann also sein, dass genau $n$ Ereignisse auftreten und alle beobachtet werden, oder $n+1$ beobachtet werden und eins nicht usw. Das bedeutet
\begin{align} q_n &= \sum_{k=n}^\infty \mathrm{Poisson}(k, \mu) \binom{k}{n} \varepsilon^n (1-\varepsilon)^{k-n} \\ &= \sum_{k=n}^\infty \exp(-\mu) \frac{\mu^k}{k!} \frac{k!}{n!(k-n)!} \varepsilon^n (1-\varepsilon)^{k-n} \\ &= \exp(-\mu) \frac{\mu^n}{n!} \sum_{k=n}^\infty \frac{\mu^k (1-\varepsilon)^{k-n}}{(k-n)!} \\ &= \exp(-\mu) \frac{(\varepsilon\mu)^n}{n!} \sum_{k=n}^\infty \frac{(\mu(1-\varepsilon)^{k-n}}{(k-n)!} \\ &= \exp(-\mu) \frac{(\varepsilon\mu)^n}{n!} \sum_{k=0}^\infty \frac{(\mu(1-\varepsilon)^{k}}{(k)!} \\ &= \exp(-\mu) \frac{(\varepsilon\mu)^n}{n!} \exp(\mu(1-\varepsilon)) \\ &= \exp(-\varepsilon\mu) \frac{(\varepsilon\mu)^n}{n!} \\ &= \mathrm{Poisson}(n, \varepsilon\mu) \\ \end{align}Damit ist
\begin{equation} p(n\,|\,a,b,\varepsilon) \propto \exp\left(\mu\varepsilon\right)\cdot\left(\mu\varepsilon\right)^n \quad\text{mit}\quad \mu = a^b \,. \end{equation}Mit Hilfe von Bayes Theorem können wir nun die Posteriorverteilung der unbekannten Parameter $\left\{a,b,\varepsilon\right\}$ ausdrücken. Es ist
\begin{equation} p(a, b, \varepsilon\,|\,n) \propto p(n\,|\,a, b, \varepsilon) \cdot p(a, b, \varepsilon) \end{equation}mit der Priorwahrscheinlichkeitsdichte
\begin{equation} p(a, b, \varepsilon) \propto \Theta(a) \cdot \Theta(b - 0.9) \cdot \Theta(1.1 - b) \cdot \exp\left(-200(\varepsilon - 0.75)^2\right) \,. \end{equation}Dieser Ausdruck wird jetzt per MCMC über $\varepsilon$ und $b$ integriert um die Verteilung von $p(a\,|\,n)$ zu erhalten.
In [4]:
uniform_b = scipy.stats.uniform(0.9, 1.1).pdf
gaussian_eps = scipy.stats.norm(0.75, 0.05).pdf
def p(a, n, eps, b):
if a <= 0:
return 0
epsab = eps * a**b
return scipy.stats.poisson.pmf(n, epsab) * uniform_b(b) * gaussian_eps(eps)
Diese können wir dann bequem mit unseren, in Aufgabe 1 formulierten, MCMC-Funktionen verwenden. Wir müssen uns nur einen kleinen Wrapper schreiben.
In [ ]:
def p_n(n, pars):
a, eps, b = pars
return p(a, n, eps, b)
p_1 = partial(p_n, 1)
as1, _, _ = mcmc_generate(p_1, np.array([0.01, 0.75, 1]), size=1000000)
plt.hist(as1, bins=40)
plt.title('$n = 1$')
plt.xlabel('$a$')
plt.ylabel('Absolute Häufigkeit')
plt.show()
In [ ]:
p_10 = partial(p_n, 10)
as10, _, _ = mcmc_generate(p_10, np.array([0.01, 0.75, 1]), size=1000000)
plt.hist(as10, bins=40)
plt.title('$n = 10$')
plt.xlabel('$a$')
plt.ylabel('Absolute Häufigkeit')
plt.show()