Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download

📚 The CoCalc Library - books, templates and other resources

Views: 95636
License: OTHER
Kernel: Python 3
%matplotlib inline import pymc3 as pm import numpy as np import scipy.stats as stats import matplotlib.pyplot as plt %config InlineBackend.figure_format = 'retina' plt.style.use(['seaborn-colorblind', 'seaborn-darkgrid'])

Code 2.1

ways = np.array([0, 3, 8, 9, 0]) ways / ways.sum()
array([ 0. , 0.15, 0.4 , 0.45, 0. ])

Code 2.2

Pr(w∣n,p)=n!w!(n−w)!pw(1−p)n−wPr(w \mid n, p) = \frac{n!}{w!(n − w)!} p^w (1 − p)^{n−w}

The probability of observing six W’s in nine tosses—under a value of p=0.5

stats.binom.pmf(6, n=9, p=0.5)
0.16406250000000006

Code 2.3 and 2.5

Computing the posterior using a grid approximation.

In the book the following code is not inside a function, but this way is easier to play with different parameters

def posterior_grid_approx(grid_points=5, success=6, tosses=9): """ """ # define grid p_grid = np.linspace(0, 1, grid_points) # define prior prior = np.repeat(5, grid_points) # uniform #prior = (p_grid >= 0.5).astype(int) # truncated #prior = np.exp(- 5 * abs(p_grid - 0.5)) # double exp # compute likelihood at each point in the grid likelihood = stats.binom.pmf(success, tosses, p_grid) # compute product of likelihood and prior unstd_posterior = likelihood * prior # standardize the posterior, so it sums to 1 posterior = unstd_posterior / unstd_posterior.sum() return p_grid, posterior

Code 2.3

points = 20 w, n = 6, 9 p_grid, posterior = posterior_grid_approx(points, w, n) plt.plot(p_grid, posterior, 'o-', label='success = {}\ntosses = {}'.format(w, n)) plt.xlabel('probability of water', fontsize=14) plt.ylabel('posterior probability', fontsize=14) plt.title('{} points'.format(points)) plt.legend(loc=0);
Image in a Jupyter notebook

Code 2.6

Computing the posterior using the quadratic approximation

data = np.repeat((0, 1), (3, 6)) with pm.Model() as normal_approximation: p = pm.Uniform('p', 0, 1) w = pm.Binomial('w', n=len(data), p=p, observed=data.sum()) mean_q = pm.find_MAP() std_q = ((1/pm.find_hessian(mean_q, vars=[p]))**0.5)[0] mean_q['p'], std_q
logp = -1.8075, ||grad|| = 1.5: 100%|██████████| 7/7 [00:00<00:00, 120.75it/s]
(array(0.6666666671652423), array([ 0.15713484]))
norm = stats.norm(mean_q, std_q) prob = .89 z = stats.norm.ppf([(1-prob)/2, (1+prob)/2]) pi = mean_q['p'] + std_q * z pi
array([ 0.41553484, 0.91779849])

Code 2.7

# analytical calculation w, n = 6, 9 x = np.linspace(0, 1, 100) plt.plot(x, stats.beta.pdf(x , w+1, n-w+1), label='True posterior') # quadratic approximation plt.plot(x, stats.norm.pdf(x, mean_q['p'], std_q), label='Quadratic approximation') plt.legend(loc=0, fontsize=13) plt.title('n = {}'.format(n), fontsize=14) plt.xlabel('Proportion water', fontsize=14) plt.ylabel('Density', fontsize=14);
Image in a Jupyter notebook
import sys, IPython, scipy, matplotlib, platform print("This notebook was createad on a computer %s running %s and using:\nPython %s\nIPython %s\nPyMC3 %s\nNumPy %s\nSciPy %s\nMatplotlib %s\n" % (platform.machine(), ' '.join(platform.linux_distribution()[:2]), sys.version[:5], IPython.__version__, pm.__version__, np.__version__, scipy.__version__, matplotlib.__version__))
This notebook was createad on a computer x86_64 running debian stretch/sid and using: Python 3.6.2 IPython 6.1.0 PyMC3 3.2 NumPy 1.13.3 SciPy 0.19.1 Matplotlib 2.1.0