<jupyter_start><jupyter_text>Code 2.1<jupyter_code>ways = np.array([0, 3, 8, 9, 0])
ways / ways.sum()<jupyter_output><empty_output><jupyter_text>Code 2.2$$Pr(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<jupyter_code>stats.binom.pmf(6, n=9, p=0.5)<jupyter_output><empty_output><jupyter_text>Code 2.3 and 2.5Computing 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<jupyter_code>def posterior_grid_approx(prior_gen, grid_points=5, success=6, tosses=9):
    """
    """
    # define grid
    p_grid = np.linspace(0, 1, grid_points)

    # define prior
    prior = prior_gen(p_grid)
    
    # 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
def uniform_prior(p_grid):
    return np.repeat(5, len(p_grid))  # uniform

def truncated_prior(p_grid):
    return (p_grid >= 0.5).astype(int)  # truncated

def double_exp_prior(p_grid):
    return np.exp(- 5 * abs(p_grid - 0.5))  # double exp<jupyter_output><empty_output><jupyter_text>Code 2.3<jupyter_code>w, n = 6, 9
points = (5, 20, 100, 1000)
def do_plotting(prior_func, points, w, n):
    _, ax = plt.subplots(1, len(points), figsize=(20, 5))

    for idx, ps in enumerate(points):
        p_grid, posterior = posterior_grid_approx(prior_func, ps, w, n)
        ax[idx].plot(p_grid, posterior, "o-", label=f"success = {w}\ntosses = {n}")
        ax[idx].set_xlabel("probability of water")
        ax[idx].set_ylabel("posterior probability")
        ax[idx].set_title(f"{ps} points")
        ax[idx].legend(loc=0)
do_plotting(uniform_prior, points, w, n)
do_plotting(truncated_prior, points, w, n)
do_plotting(double_exp_prior, points, w, n)<jupyter_output><empty_output><jupyter_text>Code 2.6Computing the posterior using the quadratic aproximation<jupyter_code>data = np.repeat((0, 1), (3, 6))
with pm.Model() as normal_aproximation:
    p = pm.Uniform("p", 0, 1)
    w = pm.Binomial("w", n=len(data), p=p, observed=data.sum())
    mean_q = pm.find_MAP(maxeval=1e6)
    std_q = ((1 / pm.find_hessian(mean_q, vars=[p])) ** 0.5)[0]
mean_q["p"], std_q
norm = stats.norm(mean_q, std_q)
prob = 0.89
z = stats.norm.ppf([(1 - prob) / 2, (1 + prob) / 2])
pi = mean_q["p"] + std_q * z
pi<jupyter_output><empty_output><jupyter_text>Code 2.7<jupyter_code># 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)

plt.title(f"n = {n}")
plt.xlabel("Proportion water");<jupyter_output><empty_output><jupyter_text>Code 2.8<jupyter_code>n_samples = 1000
p = np.zeros(n_samples)
p[0] = 0.5
W = 6
L = 3
for i in range(1, n_samples):
    p_new = stats.norm(p[i - 1], 0.1).rvs(1)
    if p_new < 0:
        p_new = -p_new
    if p_new > 1:
        p_new = 2 - p_new
    q0 = stats.binom.pmf(W, n=W + L, p=p[i - 1])
    q1 = stats.binom.pmf(W, n=W + L, p=p_new)
    if stats.uniform.rvs(0, 1) < q1 / q0:
        p[i] = p_new
    else:
        p[i] = p[i - 1]
az.plot_kde(p, label="Metropolis approximation")
x = np.linspace(0, 1, 100)
plt.plot(x, stats.beta.pdf(x, W + 1, L + 1), "C1", label="True posterior")
plt.legend();<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1587865537031976, 'fraction_numerical': 0.03252254714402842, 'mean_word_length': 4.076282940360611, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '417787', 'license': 'MIT', 'n_tokens_mistral': 1583, 'n_tokens_neox': 1473, 'n_words': 341, 'path': 'Rethinking_2/Chp_02.ipynb', 'repo_name': 'eiliven/resources', 'size': '3659'}