From data back to the world
In a trial of a malaria vaccine in West Africa, some children receive the vaccine and some a control injection, and the numbers of malaria cases in the two groups are counted. The counts are data; the question is about the world: how well does the vaccine protect children in general? A soil scientist in Punjab measures wheat yields on forty plots treated with a new fertiliser. A survey team in Nairobi asks four hundred households whether they use mobile money. In each case we see a finite, random sample and want to say something about an unknown quantity — a protection rate, a mean yield, a population proportion — with an honest statement of how uncertain we are.
Probability theory goes forwards: given the model (a coin with ), what data should we expect? Statistical inference goes backwards: given the data, what can we say about ? It does so by imagining the study repeated: an estimate computed from the data is itself a random variable, and its distribution across hypothetical repetitions — its sampling distribution — tells us how far to trust it.
This lesson builds on probability theory (expectation, variance, the law of large numbers and the central limit theorem) and on the school-level ideas of samples, bias and margins of error in statistical inference: first steps. Matrix notation from linear algebra appears in the section on regression.
Which parameter makes the data least surprising?
Suppose of seeds germinate. If the germination probability were , seeing only would be astonishing; if it were , also astonishing. The likelihood measures, for each candidate , how probable the observed data would be. It is largest at : the maximum likelihood estimate.
Relative likelihood of a success probability
Both curves peak at the observed proportion. With four times as much data the likelihood is about half as wide: more data, less uncertainty.
- n = 20 trials
- n = 80 trials, same proportion
- n = 20 trials: y = 0
- n = 80 trials, same proportion: y = 0
Two features of the picture carry the whole subject. The peak is our estimate. The width tells us how well the data pin the parameter down; with observations it shrinks like , the same square-root law as the standard deviation of a sample mean. Confidence intervals, tests and Bayesian posteriors are different ways of turning that width into a statement of uncertainty.
Models, estimators, intervals and tests
Definition— statistical model, statistic, estimator
A parametric statistical model is a family of distributions for the data ; often the are independent and identically distributed (an i.i.d. sample) from a density or mass function . A statistic is any function of the data (not of ). An estimator of (or of a function ) is a statistic used to estimate it; its value on the observed data is an estimate.
Definition— bias, mean squared error, standard error, consistency
The bias of an estimator is ; is unbiased if this is for every . Its mean squared error is , and its standard error is its standard deviation (or an estimate of it). A sequence of estimators is consistent if for every and every .
Definition— likelihood and maximum likelihood
For observed data , the likelihood is — the probability or density of the data, regarded as a function of the parameter. For an i.i.d. sample , and the log-likelihood is . A maximum likelihood estimate (MLE) maximises (equivalently ) over .
Definition— confidence interval
A confidence interval for is a pair of statistics such that for every . The probability is over the data, with fixed: it is the interval that is random.
Definition— hypothesis test, errors, p-value
A test of a null hypothesis against an alternative rejects when a test statistic falls in a rejection region . A type I error is rejecting a true ; a type II error is failing to reject a false one. The test has level if for all , and its power at is . If large values of count against and is the observed value, the p-value is : the probability, computed assuming the null hypothesis, of a result at least as extreme as the one observed.
Good estimators: bias, variance and Bessel's correction
Theorem— Theorem (bias–variance decomposition)
If has finite variance, then .
Proof
Write and . Squaring and taking expectations, the cross term vanishes because , leaving .
∎
So an estimator can be bad in two ways — systematically off (bias) or erratic (variance) — and reducing one may increase the other.
Theorem— Theorem (the sample mean)
Let have common mean . Then is unbiased for . If moreover they are pairwise uncorrelated with common variance , then , and is consistent: .
Proof
Unbiasedness is linearity of expectation. The variance of a sum of uncorrelated variables is the sum of the variances, so . Consistency is Chebyshev's inequality applied to (this is the weak law of large numbers).
∎
The standard error of a mean is therefore : to halve it, quadruple the sample.
How should we estimate ? The natural guess is too small on average, because the data are closer to their own mean than to the true mean . The key is an algebraic identity.
Theorem— Lemma (shift identity)
For any numbers with mean , and any , In particular minimises .
Proof
Expand and sum, using : the middle terms give and the last ones .
∎
Theorem— Theorem (Bessel's correction)
Let () be pairwise uncorrelated with common mean and variance . Then , so the sample variance
is an unbiased estimator of .
Proof
By the shift identity with , . Taking expectations, and , so the expectation is .
∎
Geometrically, the residual vector is confined to the -dimensional subspace of vectors whose entries sum to zero: one "degree of freedom" was used up in estimating (see the viewpoints).
Example— Unbiased is not the same as best
For a normal sample, (a fact about the distribution), so . The biased estimator has bias and variance , so , which is smaller than for every . A little bias can buy a larger reduction in variance — the idea behind shrinkage estimators and much of modern statistics.
Maximum likelihood
Theorem— Proposition (the Bernoulli MLE)
If of independent trials succeed, with , the log-likelihood on is maximised exactly at .
Proof
With calculus: is positive for and negative for , so increases and then decreases. Without calculus: write and use (with equality only at ):
using and . Equality forces . (The second proof is the one formalised in Lean, and it is Gibbs' inequality from information theory in disguise.)
∎
Example— A gallery of maximum likelihood estimators
- Poisson: , so gives .
- Exponential with rate : , so . It is biased: since has a Gamma distribution, for . (An MLE need not be unbiased; it is invariant under reparametrisation — the MLE of the mean is , which is unbiased.)
- Normal: setting both partial derivatives of to zero gives and , which is the biased .
- Uniform on : if and otherwise. It is not differentiable at its maximum, which is at the boundary: . Since has density on , ; the estimator is unbiased.
How good can an estimator be? Define the score and the Fisher information .
Theorem— Theorem (Cramér–Rao inequality)
Let be i.i.d. with density (or mass function) , in an open interval, and assume the regularity conditions: the set where does not depend on , , and differentiation in may be taken under the integral (or sum) sign in the identities below. If is an unbiased estimator of with finite variance, then
Proof
Write , so . Differentiating gives . The terms of are i.i.d. with mean , so . Differentiating gives , hence . By the Cauchy–Schwarz inequality for covariances, .
∎
For the Bernoulli model, and , so the bound is : the sample proportion is efficient. The uniform model violates the regularity conditions (its support depends on ), and indeed its unbiased estimator has variance of order , beating the "bound". Under regularity conditions the MLE is consistent and asymptotically normal: in distribution (Fisher, 1925; made rigorous by Cramér, 1946) — it attains the Cramér–Rao bound in the limit, which is the main justification for using it.
Confidence intervals
Theorem— Theorem (the z-interval)
If are i.i.d. with known, and (so that for ), then is a confidence interval for .
Proof
is normal (a sum of independent normals is normal) with mean and variance , so for every . The event is the event , which has probability .
∎
The pattern — find a pivot, a function of the data and whose distribution does not depend on , and invert it — gives most classical intervals:
- Unknown , normal data. Replacing by changes the pivot to , which has Student's distribution with degrees of freedom (Gosset, writing as "Student", 1908; proved by Fisher). The interval has exact coverage; (for example ) accounts for the extra uncertainty of estimating .
- Large samples. By the central limit theorem, has coverage approximately for large , for any distribution with finite variance.
- A proportion. The Wald interval comes from the CLT. Its actual coverage can be far below when is small (with and it is ); the Wilson interval (1927), obtained by inverting the test rather than plugging in , behaves much better. The first experiment below computes these coverages exactly.
Example— A survey of mobile-money use
Suppose of randomly chosen households in a city report using mobile money. Then , the estimated standard error is , and the Wald interval is ; the Wilson interval is . The honest report is "about , give or take percentage points" — together with how the households were sampled, since no interval repairs a biased sample.
What "95% confidence" means. Before the data are collected, the procedure has a chance of producing an interval that covers . After the data are in, either contains or it does not; is not random in this framework, so "" is not a frequentist statement. If the survey were repeated many times, about of the intervals would cover the true . (The Bayesian credible interval below does support a probability statement about , at the price of a prior.)
Hypothesis tests and p-values
Example— Is the die loaded?
A die is rolled times and shows sixes; a fair die would give on average. Take against , with test statistic = number of sixes. Under , has mean and standard deviation , and the p-value is (exactly, from the binomial distribution; the normal approximation with continuity correction gives ). At level we reject . This does not mean : it means that a fair die would produce or more sixes in about of such experiments.
Theorem— Theorem (p-values are uniform under the null)
Suppose that under the test statistic has a continuous distribution function , and the p-value is . Then for every : the test "reject when " has type I error exactly .
Proof
It suffices to show that is uniform on , since then . Let . Because is continuous, non-decreasing and tends to and at , the set is a closed half-line with (intermediate value theorem). Hence .
∎
The power of a test depends on the true effect, the noise and the sample size. For a one-sided -test of at level with known , we reject when ; if the true mean is , the power is . For an effect of half a standard deviation (), the power is with , with and with .
Type I error, type II error and power
Shaded: the 5% chance of rejecting a true null (type I error). The part of the second curve to the left of 1.645 is the type II error; to the right, the power. Increase d by increasing n.
- test statistic if H₀ is true
- test statistic if the effect is d
- Signed area: above the axis counts as positive, below (hatched) as negative
- test statistic if H₀ is true: y = 0.242
- test statistic if the effect is d: y = 0.1295
- Signed area from 1.645 to 8 ≈ 0.05 (numerical integration)
Three facts complete the picture.
- Tests and intervals are two views of one thing. The two-sided -test rejects at level exactly when lies outside the -interval. A confidence interval is the set of parameter values that the data do not reject — and it shows the size of the effect, which a p-value alone hides.
- Not rejecting is not accepting. A study with low power will usually fail to reject even when the effect is real. "" means the data are compatible with no effect; they may be equally compatible with a large one. Report the interval.
- Significance is not importance. With enough data, a trivially small effect becomes "significant"; with too little, an important one does not.
Multiple testing
Run independent tests of true null hypotheses at level . The chance that at least one is "significant" is . Search through enough variables, subgroups or outcome measures, and a spurious discovery is almost guaranteed — and if only the significant results are reported, the literature fills with false positives. The family-wise error rate (FWER) is the probability of at least one false rejection.
Theorem— Theorem (Bonferroni correction)
If each of tests is carried out at level , the family-wise error rate is at most , whatever the dependence between the tests.
Proof
Let be the event that test falsely rejects; for true nulls (for false nulls there is nothing to count). By the union bound . The union bound itself follows from additivity: is the disjoint union of the sets , each contained in .
∎
For independent tests the exact FWER is , and Bernoulli's inequality shows how close the union bound is. Bonferroni is safe but conservative: with many tests it loses power. The Benjamini–Hochberg procedure (1995) controls instead the false discovery rate, the expected proportion of false discoveries among all discoveries: sort the p-values , find the largest with , and reject the smallest. For independent tests it guarantees false discovery rate at most , where is the number of true nulls (stated here without proof). The second experiment compares both procedures by simulation.
Multiplicity also hides in choices that are never written down — which outcome, which subgroup, which covariates, when to stop collecting data. Pre-registering the analysis, reporting every test performed, and publishing code, data and random seeds so that others can rerun the analysis (see computational reproducibility) are the practical defences.
Linear regression and the normal equations
In the linear model , the matrix holds the explanatory variables (a first column of ones gives an intercept), is unknown, and is random noise. The least-squares estimate minimises the residual sum of squares .
Theorem— Theorem (normal equations)
A vector minimises if and only if it satisfies the normal equations . If the columns of are linearly independent, is invertible and the unique minimiser is .
Proof
If. Let , so the normal equations say : the residual is orthogonal to every column of . For any , put ; then and
Only if. If is a minimiser, let and . The same expansion gives , which must be at least for every . If , small make negative; so . Uniqueness. If then , so , and when the columns are independent; thus is invertible.
∎
The fitted values are the orthogonal projection of onto the column space of — the viewpoints section takes this picture further. For a straight line , the two normal equations and give
so the line passes through , and the residuals sum to zero and are uncorrelated with .
Example— Hooke's law in a school laboratory
A physics class hangs masses of g on a spring and records the extensions cm (illustrative numbers). With in hundreds of grams, the normal equations give exactly cm and cm per g, with . The third experiment below solves the normal equations in exact arithmetic and checks the residuals.
Statistical properties. If is fixed with independent columns, and , then (unbiased) and . The Gauss–Markov theorem (stated without proof) says has the smallest variance among all linear unbiased estimators. The residual sum of squares divided by is unbiased for — Bessel's correction is the special case , a column of ones. When an intercept is included, (Pythagoras), and is the fraction of variation "explained"; for a straight line, .
Check the residuals. Every one of these properties rests on assumptions — linearity, constant variance, independence, and for intervals and tests often normality of the noise. They are checked by looking at the residuals : plotted against the fitted values they should show no pattern (a curve signals non-linearity, a funnel signals non-constant variance); a normal quantile plot checks normality; and points with large leverage (the diagonal of the projection matrix ) deserve scrutiny, because they pull the line towards themselves. Anscombe's quartet (1973) makes the point unforgettable: four data sets with the same means, variances, correlation () and fitted line — one roughly linear, one a smooth curve, one linear with a single outlier, and one where a single point determines the slope. And no residual check turns correlation into causation: that needs design, such as randomisation.
Bayesian inference
The Bayesian approach treats the unknown parameter as random, with a prior distribution expressing what is believed before the data. Bayes' theorem gives the posterior
and all conclusions are read off it: a posterior mean as an estimate, an interval of posterior probability (a credible interval) as a statement of uncertainty.
Theorem— Theorem (beta–binomial conjugacy)
If has the Beta prior, with density proportional to on (), and successes are observed in independent trials, then the posterior is Beta, with mean
Proof
The posterior density is proportional to , which is the Beta density up to its normalising constant; since both integrate to , the constants agree. The mean of Beta is , and the weighted-average form is a rearrangement.
∎
The posterior mean is a compromise between the prior mean and the data, and the data's weight tends to as grows. With the uniform prior Beta it is , Laplace's rule of succession. For the survey above ( of ), the uniform prior gives the posterior Beta, with mean and central credible interval — numerically almost the same as the confidence intervals, with a different meaning: given the model and the prior, . This agreement is no accident: under regularity conditions, the Bernstein–von Mises theorem says that for large the posterior is approximately , whatever the (smooth, positive) prior. With little data, or many parameters, the prior matters, and should be reported and examined like any other assumption.
Statistics in Lean and Mathlib
Mathlib has no "statistics" library as such, but its probability theory — random variables as functions X : Ω → ℝ, expectation μ[X], variance Var[X; μ], independence X ⟂ᵢ[μ] Y — is exactly what the theory of estimation needs, and its linear algebra handles least squares. Data sets are functions summed over a Finset.
Estimators. The sample mean as a definition; the shift identity; unbiasedness and the variance of the sample mean; and Bessel's correction, proved as in the lesson. The hypotheses are pairwise independence (Mathlib's form of "uncorrelated" in IndepFun.variance_sum) with common mean and variance:
/-- The **sample mean** `x̄ = (∑ᵢ xᵢ)/|s|` of the data `xᵢ`, `i ∈ s`. (For the empty data set
Lean's convention `a / 0 = 0` gives `0`.) -/
noncomputable def sampleMean {ι : Type*} (s : Finset ι) (x : ι → ℝ) : ℝ :=
(∑ i ∈ s, x i) / s.card/-- The total of the data is `n · x̄`. -/
theorem sum_eq_card_mul_mean {ι : Type*} (s : Finset ι) (x : ι → ℝ) :
∑ i ∈ s, x i = s.card * sampleMean s x := by
unfold sampleMean
rcases Nat.eq_zero_or_pos s.card with h | h
· rw [Finset.card_eq_zero.mp h]
simp
· have : (s.card : ℝ) ≠ 0 := Nat.cast_ne_zero.mpr h.ne'
field_simp/-- **The shift identity.** For any number `c`,
`∑ (xᵢ − x̄)² = ∑ (xᵢ − c)² − n (x̄ − c)²`. In particular (taking `c` arbitrary) the sample
mean minimises `c ↦ ∑ (xᵢ − c)²`, and (taking `c = μ`) it is the key step in Bessel's
correction. Proof: expand `((xᵢ − c) − (x̄ − c))²` and use `∑ (xᵢ − c) = n (x̄ − c)`. -/
theorem sum_sq_dev_eq {ι : Type*} (s : Finset ι) (x : ι → ℝ) (c : ℝ) :
∑ i ∈ s, (x i - sampleMean s x) ^ 2 =
∑ i ∈ s, (x i - c) ^ 2 - s.card * (sampleMean s x - c) ^ 2 := by
set m := sampleMean s x
have hsum : ∑ i ∈ s, (x i - c) = s.card * (m - c) := by
rw [sum_sub_distrib, sum_eq_card_mul_mean s x, sum_const, nsmul_eq_mul]
ring
have hpt : ∀ i ∈ s, (x i - m) ^ 2 = (x i - c) ^ 2 - 2 * (m - c) * (x i - c) + (m - c) ^ 2 := by
intro i _
ring
rw [sum_congr rfl hpt, sum_add_distrib, sum_sub_distrib, ← mul_sum, hsum, sum_const,
nsmul_eq_mul]
ring/-- **The sample mean is unbiased:** if each `Xᵢ` has mean `m`, then `E[X̄ₙ] = m` (`n ≥ 1`).
Only linearity of expectation is used — no independence. -/
theorem sample_mean_unbiased (hint : ∀ i, Integrable (X i) μ) (hmean : ∀ i, μ[X i] = m)
{n : ℕ} (hn : 0 < n) : μ[fun ω => sampleMean (range n) (fun i => X i ω)] = m := by
have hnR : (n : ℝ) ≠ 0 := Nat.cast_ne_zero.mpr hn.ne'
simp only [sampleMean, card_range]
rw [integral_div, integral_finsetSum _ fun i _ => hint i]
simp only [hmean, sum_const, card_range, nsmul_eq_mul]
field_simp/-- **The variance of the sample mean is `σ²/n`** for pairwise independent observations with
common variance `σ² = v`: variances of independent variables add (`IndepFun.variance_sum`),
and `Var(X/n) = Var(X)/n²`. -/
theorem variance_sample_mean (hL2 : ∀ i, MemLp (X i) 2 μ)
(hindep : Pairwise fun i j => X i ⟂ᵢ[μ] X j) (hvar : ∀ i, Var[X i; μ] = v) (n : ℕ) :
Var[fun ω => sampleMean (range n) (fun i => X i ω); μ] = v / n := by
have h : (fun ω => sampleMean (range n) (fun i => X i ω)) =
fun ω => (n : ℝ)⁻¹ * (∑ i ∈ range n, X i) ω := by
funext ω
simp [sampleMean, Finset.sum_apply, div_eq_inv_mul]
rw [h, variance_const_mul,
IndepFun.variance_sum (fun i _ => hL2 i) (fun i _ j _ hij => hindep hij)]
simp only [hvar, sum_const, card_range, nsmul_eq_mul]
rcases Nat.eq_zero_or_pos n with rfl | hn
· simp
· have hnR : (n : ℝ) ≠ 0 := Nat.cast_ne_zero.mpr hn.ne'
field_simp/-- The sample mean of finitely many observations with finite variance has finite variance. -/
theorem sample_mean_memLp [IsProbabilityMeasure μ] (hL2 : ∀ i, MemLp (X i) 2 μ) (n : ℕ) :
MemLp (fun ω => sampleMean (range n) (fun i => X i ω)) 2 μ := by
have hsum : MemLp (∑ i ∈ range n, X i) 2 μ := memLp_finsetSum' _ fun i _ => hL2 i
have := hsum.const_mul ((n : ℝ)⁻¹)
convert this using 1
funext ω
simp [sampleMean, Finset.sum_apply, div_eq_inv_mul]/-- **Bessel's correction.** For pairwise independent observations with common mean `m` and
common variance `v`, and `n ≥ 1`, `E[∑ (Xᵢ − X̄)²] = (n − 1) v`. Hence the sample variance
`S² = ∑ (Xᵢ − X̄)²/(n − 1)` is an unbiased estimator of `v` (for `n ≥ 2`), while dividing by
`n` underestimates it on average. Proof, as in the lesson: by the shift identity with `c = m`,
`∑ (Xᵢ − X̄)² = ∑ (Xᵢ − m)² − n (X̄ − m)²`; the expectations are `n v` and `n · v/n`. -/
theorem bessel [IsProbabilityMeasure μ] (hL2 : ∀ i, MemLp (X i) 2 μ) (hindep : Pairwise fun i j => X i ⟂ᵢ[μ] X j)
(hmean : ∀ i, μ[X i] = m) (hvar : ∀ i, Var[X i; μ] = v) {n : ℕ} (hn : 0 < n) :
∫ ω, ∑ i ∈ range n, (X i ω - sampleMean (range n) (fun j => X j ω)) ^ 2 ∂μ =
(n - 1) * v := by
set Xbar : Ω → ℝ := fun ω => sampleMean (range n) (fun j => X j ω) with hXbar
have hnR : (n : ℝ) ≠ 0 := Nat.cast_ne_zero.mpr hn.ne'
-- Pointwise, the shift identity with `c = m`.
have hpt : (fun ω => ∑ i ∈ range n, (X i ω - Xbar ω) ^ 2) =
fun ω => ∑ i ∈ range n, (X i ω - m) ^ 2 - n * (Xbar ω - m) ^ 2 := by
funext ω
rw [hXbar]
simp only
rw [sum_sq_dev_eq (range n) (fun j => X j ω) m, card_range]
-- Integrability of the two pieces.
have hint_i : ∀ i, Integrable (fun ω => (X i ω - m) ^ 2) μ := fun i =>
((hL2 i).sub (memLp_const m)).integrable_sq
have hint_bar : Integrable (fun ω => (Xbar ω - m) ^ 2) μ :=
((sample_mean_memLp hL2 n).sub (memLp_const m)).integrable_sq
-- Each `E[(Xᵢ − m)²] = v`, and `E[(X̄ − m)²] = Var X̄ = v/n`.
have hEi : ∀ i, ∫ ω, (X i ω - m) ^ 2 ∂μ = v := by
intro i
rw [← hvar i, variance_eq_integral (hL2 i).aestronglyMeasurable.aemeasurable, hmean i]
have hEbar : ∫ ω, (Xbar ω - m) ^ 2 ∂μ = v / n := by
have hm : μ[Xbar] = m :=
sample_mean_unbiased (fun i => (hL2 i).integrable one_le_two) hmean hn
rw [← variance_sample_mean hL2 hindep hvar n, ← hXbar,
variance_eq_integral (sample_mean_memLp hL2 n).aestronglyMeasurable.aemeasurable, hm]
show ∫ ω, (fun ω => ∑ i ∈ range n, (X i ω - Xbar ω) ^ 2) ω ∂μ = (n - 1) * v
rw [hpt, integral_sub (integrable_finsetSum _ fun i _ => hint_i i) (hint_bar.const_mul _),
integral_finsetSum _ fun i _ => hint_i i, integral_const_mul, hEbar]
simp only [hEi, sum_const, card_range, nsmul_eq_mul]
field_simpConsistency of the sample mean (Mathlib's Chebyshev inequality applied to ), the computing formula for the variance, and the bias–variance decomposition:
/-- **Consistency of the sample mean**, with a rate: `P(|X̄ₙ − m| ≥ ε) ≤ v / (n ε²)`. Proof:
Mathlib's Chebyshev inequality (`meas_ge_le_variance_div_sq`) applied to `X̄ₙ`, whose mean is
`m` and whose variance is `v/n`. As `n → ∞` the bound tends to `0`. -/
theorem sample_mean_consistent [IsProbabilityMeasure μ] (hL2 : ∀ i, MemLp (X i) 2 μ)
(hindep : Pairwise fun i j => X i ⟂ᵢ[μ] X j) (hmean : ∀ i, μ[X i] = m)
(hvar : ∀ i, Var[X i; μ] = v) {n : ℕ} (hn : 0 < n) {ε : ℝ} (hε : 0 < ε) :
μ {ω | ε ≤ |sampleMean (range n) (fun i => X i ω) - m|} ≤
ENNReal.ofReal (v / (n * ε ^ 2)) := by
have h := meas_ge_le_variance_div_sq (sample_mean_memLp hL2 n) hε
rw [sample_mean_unbiased (fun i => (hL2 i).integrable one_le_two) hmean hn,
variance_sample_mean hL2 hindep hvar n, div_div] at h
exact h/-- The computing formula `Var X = E[X²] − (E X)²`, for `X` with finite variance. This is
Mathlib's `ProbabilityTheory.variance_eq_sub`. -/
theorem variance_computing_formula [IsProbabilityMeasure μ] {X : Ω → ℝ} (hX : MemLp X 2 μ) :
Var[X; μ] = μ[X ^ 2] - μ[X] ^ 2 :=
variance_eq_sub hX/-- **Mean squared error = variance + bias².** For an estimator `T` with finite variance and
a parameter value `θ`, `E[(T − θ)²] = Var T + (E T − θ)²`. Proof: write
`T − θ = (T − E T) + (E T − θ)`; the cross term has expectation `0`. -/
theorem mse_decomposition [IsProbabilityMeasure μ] {T : Ω → ℝ} (hT : MemLp T 2 μ) (θ : ℝ) :
∫ ω, (T ω - θ) ^ 2 ∂μ = Var[T; μ] + (μ[T] - θ) ^ 2 := by
set a := μ[T]
have hTi : Integrable T μ := hT.integrable one_le_two
have hpt : (fun ω => (T ω - θ) ^ 2) =
fun ω => (T ω - a) ^ 2 + (2 * (a - θ) * (T ω - a) + (a - θ) ^ 2) := by
funext ω
ring
have h1 : Integrable (fun ω => (T ω - a) ^ 2) μ := (hT.sub (memLp_const a)).integrable_sq
have h2 : Integrable (fun ω => 2 * (a - θ) * (T ω - a)) μ :=
(hTi.sub (integrable_const a)).const_mul _
have h3 : Integrable (fun ω => 2 * (a - θ) * (T ω - a) + (a - θ) ^ 2) μ :=
h2.add (integrable_const _)
rw [hpt, integral_add h1 h3, integral_add h2 (integrable_const _),
integral_const_mul, integral_sub hTi (integrable_const a),
variance_eq_integral hT.aestronglyMeasurable.aemeasurable]
simp [a]Likelihood. The calculus-free proof that maximises the Bernoulli log-likelihood, using Mathlib's Real.log_le_sub_one_of_pos:
/-- **The Bernoulli maximum likelihood estimator is `k/n`.** With `k` successes in `n`
independent trials (`0 < k < n`), the log-likelihood `ℓ(p) = k log p + (n − k) log(1 − p)` is
largest at `p̂ = k/n`. Proof without calculus, as in the lesson: with `q = k/n`,
`ℓ(p) − ℓ(q) = k log(p/q) + (n − k) log((1 − p)/(1 − q))
≤ k (p/q − 1) + (n − k)((1 − p)/(1 − q) − 1) = 0`, using `log x ≤ x − 1`
(Mathlib's `Real.log_le_sub_one_of_pos`). -/
theorem bernoulli_mle {n k : ℕ} (hk : 0 < k) (hkn : k < n) {p : ℝ} (hp0 : 0 < p) (hp1 : p < 1) :
k * Real.log p + (n - k) * Real.log (1 - p) ≤
k * Real.log (k / n) + (n - k) * Real.log (1 - k / n) := by
have hkR : (0 : ℝ) < k := by exact_mod_cast hk
have hknR : (k : ℝ) < n := by exact_mod_cast hkn
have hnR : (0 : ℝ) < n := hkR.trans hknR
set q : ℝ := k / n with hq
have hq0 : 0 < q := div_pos hkR hnR
have hq1 : q < 1 := (div_lt_one hnR).mpr hknR
have h1 : Real.log p - Real.log q ≤ p / q - 1 := by
rw [← Real.log_div hp0.ne' hq0.ne']
exact Real.log_le_sub_one_of_pos (div_pos hp0 hq0)
have h2 : Real.log (1 - p) - Real.log (1 - q) ≤ (1 - p) / (1 - q) - 1 := by
rw [← Real.log_div (by linarith) (by linarith)]
exact Real.log_le_sub_one_of_pos (div_pos (by linarith) (by linarith))
have hzero : (k : ℝ) * (p / q - 1) + (n - k) * ((1 - p) / (1 - q) - 1) = 0 := by
have hnk : (n : ℝ) - k ≠ 0 := by linarith
rw [hq]
field_simp
ring
have e1 := mul_le_mul_of_nonneg_left h1 hkR.le
have e2 := mul_le_mul_of_nonneg_left h2 (show (0 : ℝ) ≤ n - k by linarith)
linarithLeast squares. Both directions of the normal-equations theorem, for any real matrix X : Matrix n p ℝ, with ⬝ᵥ the dot product and *ᵥ matrix–vector multiplication:
/-- **Least squares via the normal equations.** If `b` satisfies `(XᵀX) b = Xᵀy`, then `b`
minimises the residual sum of squares `‖y − Xβ‖²` over all `β`. Proof (Pythagoras): with
`r = y − Xb` and `w = b − β`, `y − Xβ = r + Xw`, and the cross term `r · Xw = (Xᵀr) · w`
vanishes because `Xᵀr = Xᵀy − XᵀXb = 0`; so `‖y − Xβ‖² = ‖r‖² + ‖Xw‖² ≥ ‖r‖²`. -/
theorem normal_equations_minimize {n p : Type*} [Fintype n] [Fintype p] (X : Matrix n p ℝ)
(y : n → ℝ) (b : p → ℝ) (hb : (Xᵀ * X) *ᵥ b = Xᵀ *ᵥ y) (β : p → ℝ) :
(y - X *ᵥ b) ⬝ᵥ (y - X *ᵥ b) ≤ (y - X *ᵥ β) ⬝ᵥ (y - X *ᵥ β) := by
set r := y - X *ᵥ b
set w := b - β
have hr : Xᵀ *ᵥ r = 0 := by
simp only [r, mulVec_sub, mulVec_mulVec, hb, sub_self]
have hcross : r ⬝ᵥ (X *ᵥ w) = 0 := by
rw [dotProduct_mulVec, ← mulVec_transpose, hr, zero_dotProduct]
have hsplit : y - X *ᵥ β = r + X *ᵥ w := by
simp only [r, w, mulVec_sub]
abel
have hsq : 0 ≤ (X *ᵥ w) ⬝ᵥ (X *ᵥ w) :=
Finset.sum_nonneg fun i _ => mul_self_nonneg _
rw [hsplit, add_dotProduct, dotProduct_add, dotProduct_add, hcross, dotProduct_comm (X *ᵥ w) r,
hcross]
linarith/-- **Conversely, every least-squares solution satisfies the normal equations.** If `b`
minimises `‖y − Xβ‖²`, then `(XᵀX) b = Xᵀy`. Proof: for each direction `w` and real `t`,
`‖y − X(b + tw)‖² = ‖r‖² − 2t (Xᵀr)·w + t² ‖Xw‖²` must be at least `‖r‖²`; a quadratic
`−2ta + t²c` with `c ≥ 0` that is never negative has `a = 0`. Taking `w = Xᵀr` gives
`‖Xᵀr‖² = 0`. -/
theorem minimizer_normal_equations {n p : Type*} [Fintype n] [Fintype p] (X : Matrix n p ℝ)
(y : n → ℝ) (b : p → ℝ)
(hmin : ∀ β, (y - X *ᵥ b) ⬝ᵥ (y - X *ᵥ b) ≤ (y - X *ᵥ β) ⬝ᵥ (y - X *ᵥ β)) :
(Xᵀ * X) *ᵥ b = Xᵀ *ᵥ y := by
set r := y - X *ᵥ b
set g := Xᵀ *ᵥ r
-- Expand the residual sum of squares at `b + t g`.
have hexp : ∀ t : ℝ, (y - X *ᵥ (b + t • g)) ⬝ᵥ (y - X *ᵥ (b + t • g)) =
r ⬝ᵥ r - 2 * t * (g ⬝ᵥ g) + t ^ 2 * ((X *ᵥ g) ⬝ᵥ (X *ᵥ g)) := by
intro t
have hsplit : y - X *ᵥ (b + t • g) = r - t • (X *ᵥ g) := by
simp only [r, mulVec_add, mulVec_smul]
abel
have hrg : r ⬝ᵥ (X *ᵥ g) = g ⬝ᵥ g := by
rw [dotProduct_mulVec, ← mulVec_transpose]
rw [hsplit]
simp only [sub_dotProduct, dotProduct_sub, smul_dotProduct, dotProduct_smul, smul_eq_mul,
hrg, dotProduct_comm (X *ᵥ g) r]
ring
set a := g ⬝ᵥ g
set c := (X *ᵥ g) ⬝ᵥ (X *ᵥ g)
have hc : 0 ≤ c := Finset.sum_nonneg fun i _ => mul_self_nonneg _
have ha : 0 ≤ a := Finset.sum_nonneg fun i _ => mul_self_nonneg _
-- Choose `t = a/(c + 1)`: the quadratic becomes `−a²(c + 2)/(c + 1)² ≤ 0`, so `a = 0`.
have key := hmin (b + (a / (c + 1)) • g)
rw [hexp] at key
have hc1 : 0 < c + 1 := by linarith
have hq : -2 * (a / (c + 1)) * a + (a / (c + 1)) ^ 2 * c = -(a ^ 2 * (c + 2)) / (c + 1) ^ 2 := by
field_simp
ring
have h0 : 0 ≤ -(a ^ 2 * (c + 2)) / (c + 1) ^ 2 := by
rw [← hq]
linarith
have h0' : a ^ 2 * (c + 2) ≤ 0 := by
by_contra hneg
have hpos : 0 < a ^ 2 * (c + 2) := not_le.mp hneg
have : -(a ^ 2 * (c + 2)) / (c + 1) ^ 2 < 0 := div_neg_of_neg_of_pos (by linarith) (by positivity)
linarith
have ha0 : a = 0 := by
have ha2 : a ^ 2 = 0 := by nlinarith [sq_nonneg a]
exact pow_eq_zero_iff (two_ne_zero) |>.mp ha2
-- `g · g = 0` forces `g = 0`, i.e. `Xᵀ(y − Xb) = 0`.
have hg : g = 0 := by
funext i
have hsum : ∑ j, g j * g j = 0 := ha0
have := (Finset.sum_eq_zero_iff_of_nonneg fun j _ => mul_self_nonneg (g j)).mp hsum i
(Finset.mem_univ i)
simpa using this
have : Xᵀ *ᵥ y - (Xᵀ * X) *ᵥ b = 0 := by
rw [← mulVec_mulVec, ← mulVec_sub]
exact hg
exact (sub_eq_zero.mp this).symmMultiple testing. The union bound from Mathlib, the Bonferroni correction, Bernoulli's inequality for independent tests, and the "twenty tests" number:
/-- **The union bound** (Boole's inequality): `P(A₁ ∪ ⋯ ∪ Aₘ) ≤ P(A₁) + ⋯ + P(Aₘ)`, for any
events, dependent or not. This is Mathlib's `measureReal_biUnion_finset_le`. -/
theorem union_bound [IsFiniteMeasure μ] {ι : Type*} (s : Finset ι) (A : ι → Set Ω) :
μ.real (⋃ i ∈ s, A i) ≤ ∑ i ∈ s, μ.real (A i) :=
measureReal_biUnion_finset_le s A/-- **The Bonferroni correction controls the family-wise error rate.** If each of `m` tests
has probability at most `α/m` of a false rejection (event `Aᵢ`), then the probability of at
least one false rejection is at most `α` — whatever the dependence between the tests.
Proof: the union bound, then `m · (α/m) = α`. -/
theorem bonferroni [IsFiniteMeasure μ] {ι : Type*} (s : Finset ι) (A : ι → Set Ω) {α : ℝ}
(hα : 0 ≤ α) (h : ∀ i ∈ s, μ.real (A i) ≤ α / s.card) :
μ.real (⋃ i ∈ s, A i) ≤ α := by
calc μ.real (⋃ i ∈ s, A i) ≤ ∑ i ∈ s, μ.real (A i) := union_bound s A
_ ≤ ∑ _i ∈ s, α / s.card := sum_le_sum h
_ = s.card * (α / s.card) := by rw [sum_const, nsmul_eq_mul]
_ ≤ α := by
rcases Nat.eq_zero_or_pos s.card with h0 | h0
· rw [h0]
simp [hα]
· have : (s.card : ℝ) ≠ 0 := Nat.cast_ne_zero.mpr h0.ne'
rw [mul_div_cancel₀ α this]/-- For `m` **independent** tests each at level `α`, the family-wise error rate is exactly
`1 − (1 − α)ᵐ`, and this is at most `mα` — Bernoulli's inequality `(1 + a)ᵐ ≥ 1 + ma`
(Mathlib's `one_add_mul_le_pow`, valid for `a ≥ −2`) with `a = −α`; we only need `α ≤ 1`. So Bonferroni's union bound is close to exact
for independent tests with small `α`. -/
theorem fwer_independent_le {α : ℝ} (h1 : α ≤ 1) (m : ℕ) :
1 - (1 - α) ^ m ≤ m * α := by
have h := one_add_mul_le_pow (a := -α) (by linarith) m
have : (1 + -α) = 1 - α := by ring
rw [this] at h
linarith/-- Twenty independent tests of true null hypotheses at level `0.05` produce at least one
"significant" result with probability `1 − 0.95²⁰ > 0.64`. Checked by exact arithmetic. -/
theorem twenty_tests : (1 : ℚ) - (95 / 100) ^ 20 > 64 / 100 := by
norm_numWhat is and is not formalised. Proved here: the shift identity, unbiasedness of the sample mean and of , the variance of the sample mean and its consistency bound, the bias–variance decomposition, the Bernoulli MLE, the normal equations in both directions, Bonferroni's correction and the multiple-testing inequalities. Cited from Mathlib: the union bound and the computing formula for the variance (and, inside the consistency proof, Chebyshev's inequality and the additivity of variance). Not formalised: the Cramér–Rao inequality, the asymptotic normality of the MLE, the uniformity of p-values, Student's distribution and the coverage of the -interval, Gauss–Markov, Benjamini–Hochberg and beta–binomial conjugacy. The interval coverages, test sizes and powers in this lesson are computed numerically.
Coverage, false positives and residuals
Do confidence intervals deliver what they promise? First, the exact coverage of the Wald and Wilson intervals for a proportion, computed by summing binomial probabilities; then a simulation comparing the -interval, the -interval and the naive interval that plugs the sample standard deviation into the -formula.
"""Do 95% confidence intervals cover the truth 95% of the time?
Part 1 is exact. For a binomial count X ~ Bin(n, p), the coverage of an
interval method is the sum of P(X = k) over the k whose interval contains p.
We compute it for the textbook Wald interval p_hat +- 1.96 sqrt(p_hat(1 -
p_hat)/n) and for the Wilson score interval. Part 2 is a seeded simulation:
for normal samples of size 5 we compare the z-interval with known sigma, the
Student t-interval, and the naive z-interval that plugs in the sample
standard deviation.
"""
import math
import random
import statistics
Z = 1.959963984540054 # the 97.5% point of N(0, 1)
T4 = 2.776445105197799 # the 97.5% point of Student's t with 4 degrees of freedom
def binomial_pmf(n, k, p):
"""P(X = k) for X ~ Bin(n, p), computed with logarithms (no overflow)."""
if p in (0.0, 1.0):
return float(k == round(n * p))
log_c = math.lgamma(n + 1) - math.lgamma(k + 1) - math.lgamma(n - k + 1)
return math.exp(log_c + k * math.log(p) + (n - k) * math.log(1 - p))
def wald_interval(k, n, z=Z):
"""The Wald interval p_hat +- z sqrt(p_hat (1 - p_hat) / n)."""
p_hat = k / n
half = z * math.sqrt(p_hat * (1 - p_hat) / n)
return p_hat - half, p_hat + half
def wilson_interval(k, n, z=Z):
"""The Wilson score interval (Wilson, 1927)."""
p_hat = k / n
denom = 1 + z * z / n
centre = (p_hat + z * z / (2 * n)) / denom
half = z / denom * math.sqrt(p_hat * (1 - p_hat) / n + z * z / (4 * n * n))
return centre - half, centre + half
def coverage(method, n, p):
"""Exact probability that the interval method(X, n) contains p."""
total = 0.0
for k in range(n + 1):
low, high = method(k, n)
if low <= p <= high:
total += binomial_pmf(n, k, p)
return total
def simulate_normal_intervals(n=5, reps=4000, seed=2024):
"""Coverage of three 95% intervals for the mean of N(10, 2^2) samples.
Returns (z with known sigma, t with S, naive z with S) as proportions.
"""
rng = random.Random(seed)
mu, sigma = 10.0, 2.0
hits = [0, 0, 0]
for _ in range(reps):
xs = [rng.gauss(mu, sigma) for _ in range(n)]
mean, s = statistics.fmean(xs), statistics.stdev(xs)
for j, half in enumerate([Z * sigma / math.sqrt(n),
T4 * s / math.sqrt(n),
Z * s / math.sqrt(n)]):
hits[j] += abs(mean - mu) <= half
return [h / reps for h in hits]
def main():
print("Part 1 (exact): coverage of nominal 95% intervals for a proportion")
print(f"{'n':>6} {'p':>6} {'Wald':>8} {'Wilson':>8}")
for n in [10, 30, 100, 1000]:
for p in [0.5, 0.2, 0.05]:
print(f"{n:>6} {p:>6} {coverage(wald_interval, n, p):>8.3f}"
f" {coverage(wilson_interval, n, p):>8.3f}")
print("The Wald interval can undercover badly when n p is small; the")
print("Wilson interval stays much closer to 95%.")
print()
print("Part 2 (simulation, 4000 normal samples of size n = 5):")
known, t_int, naive = simulate_normal_intervals()
print(f" z-interval, sigma known: {known:.3f}")
print(f" t-interval, S and t(4) = 2.776: {t_int:.3f}")
print(f" naive z-interval with S: {naive:.3f}")
print("Plugging S into the z-interval ignores the uncertainty in S;")
print("Student's t-distribution corrects for it exactly for normal data.")
print()
print("Epistemic status: part 1 is an exact computation of coverage")
print("probabilities (in floating point) for the listed n and p. Part 2 is")
print("a seeded Monte Carlo estimate with standard error about 0.004; it")
print("illustrates, but does not prove, that the t-interval has coverage")
print("exactly 95% for normal samples (a theorem).")
if __name__ == "__main__":
main()Next, multiple testing by simulation: null p-values are uniform, twenty uncorrected tests produce a false positive about of the time, Bonferroni restores control, and Benjamini–Hochberg finds more real effects at the price of a controlled fraction of false ones.
"""Multiple testing: why twenty tests find a 'significant' effect that is not there.
We simulate many studies, each running m two-sided z-tests. Under a true null
hypothesis the test statistic is N(0, 1); under a real effect it is N(3, 1).
We check that null p-values are uniformly distributed, measure the family-wise
error rate (the chance of at least one false positive) with and without the
Bonferroni correction, and compare Bonferroni with the Benjamini-Hochberg
procedure, which controls the false discovery rate instead.
"""
import math
import random
def p_value(z):
"""Two-sided p-value of a standard normal test statistic z."""
return math.erfc(abs(z) / math.sqrt(2))
def bonferroni(pvalues, alpha):
"""Indices rejected by Bonferroni: p <= alpha / m."""
m = len(pvalues)
return {i for i, p in enumerate(pvalues) if p <= alpha / m}
def benjamini_hochberg(pvalues, alpha):
"""Indices rejected by the Benjamini-Hochberg step-up procedure (1995).
Sort the p-values; find the largest k with p_(k) <= k alpha / m and reject
the k smallest.
"""
m = len(pvalues)
order = sorted(range(m), key=lambda i: pvalues[i])
k_max = 0
for rank, i in enumerate(order, start=1):
if pvalues[i] <= rank * alpha / m:
k_max = rank
return set(order[:k_max])
def simulate(rng, m, effects, shift=3.0):
"""p-values for one study: the first ``effects`` tests have a real effect."""
return [p_value(rng.gauss(shift if i < effects else 0.0, 1.0))
for i in range(m)]
def main():
rng = random.Random(1995)
alpha, reps = 0.05, 2000
deciles = [0] * 10
any_raw = any_bonf = 0
for _ in range(reps):
ps = simulate(rng, 20, 0)
for p in ps:
deciles[min(int(p * 10), 9)] += 1
any_raw += any(p <= alpha for p in ps)
any_bonf += bool(bonferroni(ps, alpha))
print(f"{reps} studies, each with 20 true null hypotheses, alpha = 0.05")
print("Null p-values per tenth of [0, 1] (uniform means about 4000 each):")
print(" " + " ".join(f"{c:>5}" for c in deciles))
print(f"P(at least one p <= 0.05), uncorrected: {any_raw / reps:.3f}"
f" (exact 1 - 0.95^20 = {1 - 0.95 ** 20:.3f})")
print(f"P(at least one rejection), Bonferroni: {any_bonf / reps:.3f}"
f" (guaranteed <= 0.05)")
print()
print("Studies with 50 tests, of which 10 have a real effect (mean 3):")
totals = {"Bonferroni": [0, 0], "Benjamini-Hochberg": [0, 0]}
fdp_bh = 0.0
for _ in range(reps):
ps = simulate(rng, 50, 10)
for name, rule in [("Bonferroni", bonferroni),
("Benjamini-Hochberg", benjamini_hochberg)]:
rejected = rule(ps, alpha)
true_hits = sum(1 for i in rejected if i < 10)
totals[name][0] += true_hits
totals[name][1] += len(rejected) - true_hits
if name == "Benjamini-Hochberg" and rejected:
fdp_bh += (len(rejected) - true_hits) / len(rejected)
for name, (hits, false) in totals.items():
print(f" {name:<19} real effects found {hits / reps:5.2f} of 10,"
f" false positives {false / reps:4.2f}")
print(f" Average false discovery proportion for BH: {fdp_bh / reps:.3f}")
print(" (BH guarantees at most 0.05 x 40/50 = 0.04 for independent tests)")
print()
print("Epistemic status: seeded Monte Carlo simulation (2000 studies per")
print("scenario), so every proportion has sampling error of order 0.01.")
print("The guarantees quoted (Bonferroni's union bound, the BH theorem for")
print("independent tests) are theorems; the simulation only illustrates")
print("them in two scenarios.")
if __name__ == "__main__":
main()Finally, least squares: the normal equations solved exactly, residuals orthogonal to the columns of , and Anscombe's quartet — identical summaries, different residual stories.
"""Least squares by the normal equations, and why you must look at residuals.
Part 1 fits a straight line to a small (illustrative) data set of spring
extensions by solving the normal equations X^T X b = X^T y exactly in
rational arithmetic, and checks the answer against numpy's least-squares
solver. Part 2 uses Anscombe's quartet (1973): four data sets with the same
means, variances, correlation and fitted line, but completely different
residual patterns - curvature, an outlier, and a single point of high
leverage.
"""
from fractions import Fraction
import numpy as np
#: Illustrative data: mass on a spring (hundreds of grams) and extension (cm).
MASS = [0, 1, 2, 3, 4, 5]
EXTENSION = ["0.1", "2.0", "4.1", "5.9", "8.2", "9.9"]
#: Anscombe, "Graphs in statistical analysis", The American Statistician (1973).
ANSCOMBE_X = [10, 8, 13, 9, 11, 14, 6, 4, 12, 7, 5]
ANSCOMBE = {
"I": (ANSCOMBE_X, [8.04, 6.95, 7.58, 8.81, 8.33, 9.96, 7.24, 4.26, 10.84,
4.82, 5.68]),
"II": (ANSCOMBE_X, [9.14, 8.14, 8.74, 8.77, 9.26, 8.10, 6.13, 3.10, 9.13,
7.26, 4.74]),
"III": (ANSCOMBE_X, [7.46, 6.77, 12.74, 7.11, 7.81, 8.84, 6.08, 5.39,
8.15, 6.42, 5.73]),
"IV": ([8, 8, 8, 8, 8, 8, 8, 19, 8, 8, 8],
[6.58, 5.76, 7.71, 8.84, 8.47, 7.04, 5.25, 12.50, 5.56, 7.91, 6.89]),
}
def normal_equations_line(xs, ys):
"""Exact (intercept, slope) solving X^T X b = X^T y for X = [1, x].
The 2 x 2 system [[n, Sx], [Sx, Sxx]] b = [Sy, Sxy] is solved by
Cramer's rule in rational arithmetic.
"""
xs = [Fraction(x) for x in xs]
ys = [Fraction(y) for y in ys]
n = len(xs)
sx, sy = sum(xs), sum(ys)
sxx = sum(x * x for x in xs)
sxy = sum(x * y for x, y in zip(xs, ys))
det = n * sxx - sx * sx
if det == 0:
raise ValueError("all x values are equal: the slope is not determined")
return (sxx * sy - sx * sxy) / det, (n * sxy - sx * sy) / det
def residuals(xs, ys, intercept, slope):
"""y_i - (intercept + slope x_i)."""
return [Fraction(y) - (intercept + slope * Fraction(x))
for x, y in zip(xs, ys)]
def summary(xs, ys):
"""Mean of x, mean of y, slope, intercept, correlation r and R^2."""
x, y = np.asarray(xs, float), np.asarray(ys, float)
design = np.column_stack([np.ones_like(x), x])
(b0, b1), *_ = np.linalg.lstsq(design, y, rcond=None)
r = float(np.corrcoef(x, y)[0, 1])
return float(x.mean()), float(y.mean()), float(b1), float(b0), r, r * r
def diagnostics(xs, ys):
"""Largest |residual|, its index, and the largest leverage h_ii."""
x, y = np.asarray(xs, float), np.asarray(ys, float)
design = np.column_stack([np.ones_like(x), x])
hat = design @ np.linalg.inv(design.T @ design) @ design.T
b = np.linalg.solve(design.T @ design, design.T @ y)
res = y - design @ b
i = int(np.argmax(np.abs(res)))
return float(abs(res[i])), i, float(np.max(np.diag(hat)))
def curvature(xs, ys):
"""Correlation between residuals and (x - mean x)^2: large if curved."""
x, y = np.asarray(xs, float), np.asarray(ys, float)
_, _, b1, b0, _, _ = summary(xs, ys)
res = y - (b0 + b1 * x)
sq = (x - x.mean()) ** 2
if np.std(sq) == 0:
return 0.0
return float(np.corrcoef(res, sq)[0, 1])
def main():
b0, b1 = normal_equations_line(MASS, EXTENSION)
res = residuals(MASS, EXTENSION, b0, b1)
print("Part 1: spring extension (cm) against mass (100 g)")
print(f" exact normal-equation fit: y = {b0} + {b1} x"
f" = {float(b0):.4f} + {float(b1):.4f} x")
_, _, nb1, nb0, _, r2 = summary(MASS, [float(e) for e in EXTENSION])
print(f" numpy lstsq: y = {nb0:.4f} + {nb1:.4f} x,"
f" R^2 = {r2:.4f}")
print(f" sum of residuals = {sum(res)}, sum of x * residual ="
f" {sum(Fraction(x) * e for x, e in zip(MASS, res))}")
print()
print("Part 2: Anscombe's quartet")
print(" set mean x mean y slope intercept r R^2 | max|res|"
" leverage curve")
for name, (xs, ys) in ANSCOMBE.items():
mx, my, s, c, r, r2 = summary(xs, ys)
big, _, lev = diagnostics(xs, ys)
print(f" {name:>3} {mx:7.2f} {my:7.2f} {s:6.3f} {c:10.2f} {r:5.3f}"
f" {r2:5.2f} | {big:8.2f} {lev:8.2f} {curvature(xs, ys):5.2f}")
print("Same summary statistics; different stories. II is curved (residuals")
print("track (x - mean)^2), III has one outlier, and in IV a single point")
print("with leverage 1 determines the slope by itself.")
print()
print("Epistemic status: part 1 is exact rational arithmetic, confirmed")
print("numerically; part 2 is floating-point computation on published data.")
print("The diagnostics illustrate what residual plots show; they are not")
print("formal tests, and the spring data are illustrative, not measured.")
if __name__ == "__main__":
main()Part 1 of the first experiment is an exact computation; its part 2 and the second experiment are statistical evidence (seeded simulations with sampling error of about ); the third is exact and numerical. Simulations illustrate the theorems about coverage and error rates; they do not prove them.
Exercises
1. Statistical inference
Warm-upHumanA test of : "the new fertiliser has no effect on mean yield" gives . Which statement is correct?
2. Statistical inference
Warm-upHumanA health clinic records the number of patients arriving in five consecutive hours: . Modelling the counts as independent Poisson, what is the maximum likelihood estimate of ?
3. Statistical inference
Warm-upHumanCompute the sample variance of the data .
4. Statistical inference
StretchHumanFor an i.i.d. sample from the uniform distribution on , the MLE is , and . Which estimator is unbiased for ?
5. Statistical inference
CoreHumanIn the proof that the normal equations give the least-squares solution, we expand with and . Why does the cross term vanish?
6. Statistical inference
CoreHumanA study tests hypotheses and obtains the p-values . Using the Bonferroni correction with family-wise error rate , how many hypotheses are rejected?
7. Statistical inference
CoreHumanA small trial of a new treatment (20 patients) finds a confidence interval of days for the reduction in recovery time, with . What is the best conclusion?
8. Statistical inference
CoreHumanFrom of households, a confidence interval for the proportion is , and with a uniform prior the Bayesian posterior is Beta with credible interval . Which statements are correct? (Choose all that apply.)
9. Statistical inference
CoreFormalWhich Lean statement says that a solution b of the normal equations minimises the residual sum of squares? (Xᵀ is the transpose, *ᵥ multiplies a matrix by a vector, ⬝ᵥ is the dot product.)
10. Statistical inference
StretchComputationalWrite fit_line(xs, ys) returning the least-squares (intercept, slope) for the model , using and . Use Fraction so the answers are exact. The tests also check that the residuals sum to zero and are orthogonal to — the normal equations.
Common misconceptions
Misconception
"The p-value is the probability that the null hypothesis is true." The p-value is computed assuming is true: it is , not . Turning one into the other needs Bayes' theorem and a prior probability for — the same base-rate reasoning as in diagnostic testing. A p-value of can coexist with a high probability that is true if real effects are rare.
Misconception
"A non-significant result proves there is no effect." Failing to reject may simply reflect low power. A small trial with can be compatible both with no effect and with a large benefit; the confidence interval shows which effect sizes remain plausible. Absence of evidence is not evidence of absence — claims of "no effect" need high power or an equivalence test.
Misconception
"There is a 95% probability that the true value lies in this computed interval." For a frequentist confidence interval, the describes the procedure over repeated samples; a particular interval either contains the fixed true value or not. A Bayesian credible interval does carry a probability statement — conditional on the model and the prior.
Misconception
"An unbiased estimator is always better than a biased one." Mean squared error is variance plus squared bias, and a small bias can buy a large reduction in variance: for normal data, dividing by (or ) gives a smaller mean squared error than dividing by .
Misconception
"Each test is at the 5% level, so my conclusions are 95% reliable." With many tests, false positives accumulate: twenty independent true nulls give at least one "significant" result with probability . Correct for multiplicity (Bonferroni, Benjamini–Hochberg), and count the tests that were run but not reported.
Misconception
"A high means the model is right." measures how much variation a straight-line (or linear) fit captures, not whether the model's assumptions hold or whether causes . All four of Anscombe's data sets have ; only residual plots tell them apart. Causal conclusions need randomised design or careful causal reasoning.
Many ways of seeing
Geometry— Least squares is orthogonal projection; degrees of freedom are dimensions
Think of the data as a single point of . The model's possible means fill the column space , a -dimensional subspace, and least squares picks the point of nearest to : the orthogonal projection , with a symmetric idempotent matrix (). The normal equations say that the residual is perpendicular to , and the decomposition is Pythagoras' theorem; is of the angle between the centred data and the centred fit. "Degrees of freedom" are dimensions: if the noise is times a standard normal vector in , its projection onto any -dimensional subspace has , by the rotational symmetry of the normal distribution. The residual lives in the -dimensional orthogonal complement of — which is why the residual sum of squares is divided by , and why Bessel divides by (the complement of the line spanned by ). For normal data this geometry also explains why and are independent (Cochran's theorem): they are built from projections onto orthogonal subspaces.
Analysis— Information as curvature
The Fisher information has an analytic meaning: under the regularity conditions, , the expected curvature of the log-likelihood at its peak. A sharply curved likelihood pins down; a flat one does not — exactly the widths in the likelihood widget. The asymptotic normality of the MLE comes from a Taylor expansion of the score around : , where by the central limit theorem and by the law of large numbers. The Cramér–Rao inequality is the Cauchy–Schwarz inequality in , and the whole asymptotic theory is an exercise in limits, estimates and uniformity — Le Cam's theory of local asymptotic normality (1960s) makes it precise. See measure theory.
Probability— Two meanings of probability
The frequentist reads as long-run frequency in repetitions of the experiment, so only data are random; parameters are fixed unknowns, and guarantees are statements about procedures (coverage, error rates). The Bayesian reads as a coherent degree of belief, so parameters may have distributions and the posterior answers directly "how probable is it that ?". De Finetti's representation theorem (1931) connects the two: if a sequence of 0–1 observations is exchangeable (its probabilities are unchanged by permuting the order), then it is a mixture of i.i.d. Bernoulli sequences — mathematically, a prior over appears automatically. In practice the two schools usually agree when data are plentiful (Bernstein–von Mises) and differ instructively when they are not.
Computation— Resampling and simulation
When formulas are unavailable, computation substitutes for algebra. The bootstrap (Efron, 1979) estimates the sampling distribution of an estimator by recomputing it on many samples drawn with replacement from the data; permutation tests (Fisher's idea from the 1930s) obtain exact p-values by recomputing a statistic over rearrangements of group labels, which are equally likely under the null hypothesis of no difference; and Markov chain Monte Carlo (see Markov chains) samples from posterior distributions that cannot be computed in closed form, which made Bayesian methods practical from the 1990s. Each comes with its own conditions — the bootstrap, for example, can fail for the maximum of a uniform sample — so computation does not remove the need for theory.
History and global context
- Early data. John Graunt's analysis of London's bills of mortality (1662) is often called the beginning of statistics; in the 18th century Thomas Bayes' essay (published by Richard Price in 1763) and Pierre-Simon Laplace's "inverse probability" (1774 onwards) gave the first systematic methods of inference, including the rule of succession.
- Least squares. Adrien-Marie Legendre published the method of least squares in 1805; Carl Friedrich Gauss (1809) justified it with the normal law of errors and claimed earlier use, and later (1821–23) proved the optimality now called the Gauss–Markov theorem. Francis Galton's studies of heredity (1886) gave "regression" its name — regression towards the mean — and Karl Pearson developed correlation and the test (1900).
- The 20th-century synthesis. William Sealy Gosset, a chemist at the Guinness brewery in Dublin, published the distribution as "Student" (1908) to analyse small samples. Ronald Fisher introduced maximum likelihood (1912–22), Fisher information, significance testing with p-values and the randomised design of experiments (Statistical Methods for Research Workers, 1925; The Design of Experiments, 1935). Jerzy Neyman and Egon Pearson formulated tests with two types of error and proved their optimal-test lemma (1933), and Neyman introduced confidence intervals (1937). Edwin Wilson's score interval dates from 1927.
- A global discipline. Prasanta Chandra Mahalanobis founded the Indian Statistical Institute in Kolkata (1931) and pioneered large-scale sample surveys, used for India's National Sample Survey from 1950. C. R. Rao, working there, proved the information inequality in 1945; Harald Cramér proved it independently in Stockholm, and his Mathematical Methods of Statistics (1946) gave the subject its rigorous asymptotic theory. Bruno de Finetti in Italy (1931–37) and Harold Jeffreys in England (1939) developed Bayesian foundations.
- Computers and many tests. Bradley Efron's bootstrap (1979) and Markov chain Monte Carlo methods transformed practice, and Yoav Benjamini and Yosef Hochberg's false discovery rate (1995) answered the needs of genomics and other fields where thousands of hypotheses are tested at once. Concerns about reproducibility led the American Statistical Association to issue a statement on the meaning and misuse of p-values in 2016.
Further reading
- George Casella and Roger L. Berger, Statistical Inference (2nd edition, 2002) — the standard rigorous course: sufficiency, likelihood, Cramér–Rao, tests and intervals.
- Larry Wasserman, All of Statistics (2004) — a fast, modern tour, including the bootstrap, multiple testing and Bayesian inference.
- John A. Rice, Mathematical Statistics and Data Analysis (3rd edition, 2007) — theory with real data sets.
- David Freedman, Robert Pisani and Roger Purves, Statistics (4th edition, 2007) — the clearest non-technical account of what tests, intervals and regression mean, and how they are misused.
- Andrew Gelman, John Carlin, Hal Stern, David Dunson, Aki Vehtari and Donald Rubin, Bayesian Data Analysis (3rd edition, 2013).
- Bradley Efron and Trevor Hastie, Computer Age Statistical Inference (2016) — how computation reshaped the classical theory.