Chapter 5 · Rethinking Statistics with Bayesian Methods
Section 5.2 · Chapter 5 · Learning Statistics with Python
Rethinking Statistics with Bayesian Methods
Prof. Xuhu Wan
ISOM, HKUST Business School · 2026 Edition
A regression is a statement that \(y\) is normal with a mean that moves with \(x\). You will simulate from the prior before touching the data, discover which prior is absurd, then simulate from the posterior to see whether the model can reproduce what it was fitted to.
\[y_i \sim N(\mu_i,\ \sigma^2), \qquad \mu_i = \beta_0 + \beta_1 x_i\]
The notebook’s artificial data: \(\beta_0 = 1\), \(\beta_1 = 2\), \(\sigma = 0.5\).
In the Bayesian regression, which quantities get a prior?
y mean 2.041, sd 0.759. The sd of \(y\) (0.76) exceeds \(\sigma\) (0.5) because part of the spread is the line itself. Keep that distinction: spread of y ≠ noise.
In Colab
The notebook fits this with NUTS. We will get the same posterior in closed form on the next slides.
with pm.Model() as linear_regression1:
std = pm.HalfCauchy("sigma", beta=10, initval=1)
beta0 = pm.Normal("intercept", 0, sigma=20)
beta1 = pm.Normal("slope", 0, sigma=20)
likelihood = pm.Normal("y", mu=beta0 + beta1 * data["x"], sigma=std,
observed=data["y"])
trace1 = pm.sample(tune=6000, draws=2500, chains=2)The posterior draws come back as a table: one row per draw, one column per parameter. Every plot in this section is built from that table.
Before fitting, draw parameters from the prior and plot the regression lines they imply. If the lines are absurd, the prior is absurd — and you found out for free.
\(x \in [-10, 10]\), \(y = 0.5 + 3x + N(0, 6^2)\), 200 points.
\(x\) has sd 5.8 and the slope is 3, noise sd 6. Roughly what is the sd of \(y\)? (\(\sqrt{3^2 \cdot 5.8^2 + 6^2}\))
18.4
Draw 100 lines with \(\beta_0, \beta_1 \sim N(0, 10)\). At \(x = 10\), what range covers 95 % of them?
Prior I: [-173.8, 209.7]. Prior II: [-20.8, 25.2]. The data at \(x = 10\) sit near 30. Prior II covers plausible slopes without covering nonsense — but it puts the true slope 3 at 2.5 prior sd. With 200 points the data will drag it there anyway; with 10 points they might not.
Normal likelihood, normal prior on \(\beta\): the posterior is normal and you can write it down. The formula is the same precision-weighting you saw on the grid, now in matrix form.
\[\Sigma_n = \left(\Sigma_0^{-1} + \tfrac{1}{\sigma^2} X^\top X\right)^{-1}, \qquad \mu_n = \Sigma_n\left(\Sigma_0^{-1}\mu_0 + \tfrac{1}{\sigma^2} X^\top y\right)\]
OLS on (xt, yt) gives slope 3.011. Prior II is \(N(0, 1.2^2)\) on the slope, and the data precision on the slope is about \(\sum x^2/\sigma^2 \approx 6700/32.5 \approx 206\). Will the posterior mean slope be nearer 3.011 or 0?
≈ 3.00 — data precision 206 vs prior precision 0.69
OLS [0.385, 3.011], posterior mean [0.331, 3.000], posterior sd [0.374, 0.069]. The intercept is shrunk a little toward 0 (its prior sd 1 competes with a data sd 0.4); the slope barely moves. With \(n = 200\) the prior is a rounding error.
The 50 red lines are 50 rows of post_df. Slope credible interval [2.861, 3.139] — the same information a classical CI gives, but readable as a probability.
Now go one step further: for each posterior draw, simulate a whole replicated data set. If the replicas do not look like the data, the model is missing something.
For posterior draw \(s\): \(\mu_i^{(s)} = b_0^{(s)} + b_1^{(s)}x_i\), then \(y_i^{\text{rep},(s)} \sim N(\mu_i^{(s)}, \sigma)\) for every \(i\).
yrep has shape (1000, 200). What is yrep[7]?
Thirty cyan replicas and the black data share one shape. If the data had a bump the replicas never produce, the normal likelihood would be wrong — this is how the §5.3 outliers will announce themselves.
A Bayesian p-value: the fraction of replicas whose statistic exceeds the observed statistic. Near 0.5 is good; near 0 or 1 means the model cannot produce what you saw.
p_mean is done. Fix p_max so it compares the maximum of each replica row with the observed maximum yt.max(). Expect about 0.13 — the normal model slightly under-produces the largest value.
p_max = 0.13 is the first hint that normal tails are thin.Next: §5.3 — put three outliers in and watch the normal likelihood surrender.
Prof. Xuhu Wan · HKUST ISOM · Learning Statistics with Python