Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
probml
GitHub Repository: probml/pyprobml
Path: blob/master/deprecated/scripts/beta_binom_approx_post_pymc3.py
1192 views
1
# 1d approixmation to beta binomial model
2
# https://github.com/aloctavodia/BAP
3
4
5
import superimport
6
7
import pymc3 as pm
8
import numpy as np
9
import seaborn as sns
10
import scipy.stats as stats
11
import matplotlib.pyplot as plt
12
import arviz as az
13
import math
14
import pyprobml_utils as pml
15
16
#data = np.repeat([0, 1], (10, 3))
17
data = np.repeat([0, 1], (10, 1))
18
h = data.sum()
19
t = len(data) - h
20
21
# Exact
22
23
plt.figure()
24
x = np.linspace(0, 1, 100)
25
xs = x #grid
26
dx_exact = xs[1]-xs[0]
27
post_exact = stats.beta.pdf(xs, h+1, t+1)
28
post_exact = post_exact / np.sum(post_exact)
29
plt.plot(xs, post_exact)
30
plt.yticks([])
31
plt.title('exact posterior')
32
pml.savefig('bb_exact.pdf')
33
34
35
# Grid
36
def posterior_grid(heads, tails, grid_points=100):
37
grid = np.linspace(0, 1, grid_points)
38
prior = np.repeat(1/grid_points, grid_points) # uniform prior
39
likelihood = stats.binom.pmf(heads, heads+tails, grid)
40
posterior = likelihood * prior
41
posterior /= posterior.sum()
42
#posterior = posterior * grid_points
43
return grid, posterior
44
45
46
n = 20
47
grid, posterior = posterior_grid(h, t, n)
48
dx_grid = grid[1] - grid[0]
49
sf = dx_grid / dx_exact # Jacobian scale factor
50
plt.figure()
51
#plt.stem(grid, posterior, use_line_collection=True)
52
plt.bar(grid, posterior, width=1/n, alpha=0.2)
53
plt.plot(xs, post_exact*sf)
54
plt.title('grid approximation')
55
plt.yticks([])
56
plt.xlabel('θ');
57
pml.savefig('bb_grid.pdf')
58
59
60
# Laplace
61
with pm.Model() as normal_aproximation:
62
theta = pm.Beta('theta', 1., 1.)
63
y = pm.Binomial('y', n=1, p=theta, observed=data) # Bernoulli
64
mean_q = pm.find_MAP()
65
std_q = ((1/pm.find_hessian(mean_q, vars=[theta]))**0.5)[0]
66
mu = mean_q['theta']
67
68
print([mu, std_q])
69
70
plt.figure()
71
plt.plot(xs, stats.norm.pdf(xs, mu, std_q), '--', label='Laplace')
72
post_exact = stats.beta.pdf(xs, h+1, t+1)
73
plt.plot(xs, post_exact, label='exact')
74
plt.title('Quadratic approximation')
75
plt.xlabel('θ', fontsize=14)
76
plt.yticks([])
77
plt.legend()
78
pml.savefig('bb_laplace.pdf');
79
80
81
82
# HMC
83
with pm.Model() as hmc_model:
84
theta = pm.Beta('theta', 1., 1.)
85
y = pm.Binomial('y', n=1, p=theta, observed=data) # Bernoulli
86
trace = pm.sample(1000, random_seed=42, cores=1, chains=2)
87
thetas = trace['theta']
88
axes = az.plot_posterior(thetas, hdi_prob=0.95)
89
pml.savefig('bb_hmc.pdf');
90
91
az.plot_trace(trace)
92
pml.savefig('bb_hmc_trace.pdf', dpi=300)
93
94
# ADVI
95
with pm.Model() as mf_model:
96
theta = pm.Beta('theta', 1., 1.)
97
y = pm.Binomial('y', n=1, p=theta, observed=data) # Bernoulli
98
mean_field = pm.fit(method='advi')
99
trace_mf = mean_field.sample(1000)
100
thetas = trace_mf['theta']
101
axes = az.plot_posterior(thetas, hdi_prob=0.95)
102
pml.savefig('bb_mf.pdf');
103
104
plt.show()
105
106
107
# track mean and std
108
with pm.Model() as mf_model:
109
theta = pm.Beta('theta', 1., 1.)
110
y = pm.Binomial('y', n=1, p=theta, observed=data) # Bernoulli
111
advi = pm.ADVI()
112
tracker = pm.callbacks.Tracker(
113
mean=advi.approx.mean.eval, # callable that returns mean
114
std=advi.approx.std.eval # callable that returns std
115
)
116
approx = advi.fit(callbacks=[tracker])
117
118
trace_approx = approx.sample(1000)
119
thetas = trace_approx['theta']
120
121
plt.figure()
122
plt.plot(tracker['mean'])
123
plt.title('Mean')
124
pml.savefig('bb_mf_mean.pdf');
125
126
plt.figure()
127
plt.plot(tracker['std'])
128
plt.title('Std ')
129
pml.savefig('bb_mf_std.pdf');
130
131
plt.figure()
132
plt.plot(advi.hist)
133
plt.title('Negative ELBO');
134
pml.savefig('bb_mf_elbo.pdf');
135
136
plt.figure()
137
sns.kdeplot(thetas);
138
plt.title('KDE of posterior samples')
139
pml.savefig('bb_mf_kde.pdf');
140
141
142
fig,axs = plt.subplots(1,4, figsize=(30,10))
143
mu_ax = axs[0]
144
std_ax = axs[1]
145
elbo_ax = axs[2]
146
kde_ax = axs[3]
147
mu_ax.plot(tracker['mean'])
148
mu_ax.set_title('Mean')
149
std_ax.plot(tracker['std'])
150
std_ax.set_title('Std ')
151
elbo_ax.plot(advi.hist)
152
elbo_ax.set_title('Negative ELBO');
153
kde_ax = sns.kdeplot(thetas);
154
kde_ax.set_title('KDE of posterior samples')
155
pml.savefig('bb_mf_panel.pdf');
156
157
158
fig = plt.figure(figsize=(16, 9))
159
mu_ax = fig.add_subplot(221)
160
std_ax = fig.add_subplot(222)
161
hist_ax = fig.add_subplot(212)
162
mu_ax.plot(tracker['mean'])
163
mu_ax.set_title('Mean track')
164
std_ax.plot(tracker['std'])
165
std_ax.set_title('Std track')
166
hist_ax.plot(advi.hist)
167
hist_ax.set_title('Negative ELBO track');
168
pml.savefig('bb_mf_tracker.pdf');
169
170
trace_approx = approx.sample(1000)
171
thetas = trace_approx['theta']
172
axes = az.plot_posterior(thetas, hdi_prob=0.95)
173
174
plt.show()
175