import arviz as az
import pymc as pm
import scipy.stats as stats
import matplotlib.pyplot as plt
import numpy as np
= 42
SEED = np.random.default_rng(SEED) rng
Chapter 2
Code 2.1
= np.array([0, 3, 8, 9, 0])
ways / ways.sum() ways
array([0. , 0.15, 0.4 , 0.45, 0. ])
Code 2.2
6, n=9, p=0.5) stats.binom.pmf(
0.16406250000000003
Code 2.3 and 2.4
def uniform_prior(grid_points):
return np.repeat(5, grid_points)
def truncated_prior(grid_points, trunc_point=0.5):
return (np.linspace(0, 1, grid_points) >= trunc_point).astype(int)
def double_exp_prior(grid_points):
return np.exp(-5 * abs(np.linspace(0, 1, grid_points) - 0.5))
def binom_post_grid_approx(prior, grid_points=5, success=6, tosses=9):
# define grid
= np.linspace(0, 1, grid_points)
p_grid
# define prior
= prior(grid_points)
prior
# compute likelihood at each point in the grid
= stats.binom.pmf(success, tosses, p_grid)
likelihood
# compute product of likelihood and prior
= likelihood * prior
unstd_posterior
# standardize the posterior, so it sums to 1
= unstd_posterior / unstd_posterior.sum()
posterior return p_grid, posterior
= 6, 9
w, n
= (5, 20, 100)
points
= plt.subplots(1, len(points), figsize=(6 * len(points), 5))
_, ax for idx, ps in enumerate(points):
= binom_post_grid_approx(uniform_prior, ps, w, n)
p_grid, posterior "o-", label=f"successes = {w}\ntosses = {n}")
ax[idx].plot(p_grid, posterior, "probability of water")
ax[idx].set_xlabel("posterior probability")
ax[idx].set_ylabel(f"{ps} points")
ax[idx].set_title(=0) ax[idx].legend(loc
= plt.subplots(1, len(points), figsize=(6 * len(points), 5))
_, ax for idx, ps in enumerate(points):
= binom_post_grid_approx(truncated_prior, ps, w, n)
p_grid, posterior "o-", label=f"successes = {w}\ntosses = {n}")
ax[idx].plot(p_grid, posterior, "probability of water")
ax[idx].set_xlabel("posterior probability")
ax[idx].set_ylabel(f"{ps} points")
ax[idx].set_title(=0) ax[idx].legend(loc
= plt.subplots(1, len(points), figsize=(6 * len(points), 5))
_, ax for idx, ps in enumerate(points):
= binom_post_grid_approx(double_exp_prior, ps, w, n)
p_grid, posterior "o-", label=f"successes = {w}\ntosses = {n}")
ax[idx].plot(p_grid, posterior, "probability of water")
ax[idx].set_xlabel("posterior probability")
ax[idx].set_ylabel(f"{ps} points")
ax[idx].set_title(=0) ax[idx].legend(loc
Code 2.5
Code 2.6
Quadratic approximation (quap). Code taken from Ravin Kumar’s cheatsheet.
= np.repeat((0, 1), (3, 6))
data data
array([0, 0, 0, 1, 1, 1, 1, 1, 1])
with pm.Model() as normal_approximation:
# prior
= pm.Uniform("p", 0, 1)
p # likelihood
= pm.Binomial("w", n=len(data), p=p, observed=data.sum())
w # inference
= pm.find_MAP() # mean
mean_q = ((1/pm.find_hessian(mean_q, vars=[p]))**0.5)[0] # variance
std_q
print("Mean, Standard deviation\np {:.2}, {:.2}".format(mean_q["p"], std_q[0]))
100.00% [6/6 00:00<00:00 logp = -1.8075, ||grad|| = 1.5]
Mean, Standard deviation
p 0.67, 0.64
# Compute the 89% percentile interval
= stats.norm(mean_q, std_q)
norm = 0.89
prob = stats.norm.ppf([(1 - prob) / 2, (1 + prob) / 2])
z = mean_q["prior"] + std_q * z
pi print("5.5%, 94.5% \n{:.2}, {:.2}".format(pi[0], pi[1]))
5.5%, 94.5%
0.42, 0.58
Code 2.7
= 6, 9
w, n = np.linspace(0, 1, 100)
x +1, n-w+1),
plt.plot(x, stats.beta.pdf(x , w='True posterior')
label
# quadratic approximation
'prior'], std_q),
plt.plot(x, stats.norm.pdf(x, mean_q[='Quadratic approximation')
label=0, fontsize=9)
plt.legend(loc
'n = {}'.format(n), fontsize=14)
plt.title('Proportion water', fontsize=14)
plt.xlabel('Density', fontsize=14);
plt.ylabel(
#TODO: something's wrong here