AnyLearn
All lessons
Mathintermediate

Estimation and Hypothesis Testing

From raw data to defensible conclusions: derive Maximum Likelihood Estimators for Bernoulli and Gaussian, understand bias-variance in estimation, construct confidence intervals, and learn what p-values actually say — and don't say — including the most common misinterpretation that has corrupted thousands of papers.

Updated · AI-authored, review-gated · how lessons are made

Not signed in: your progress and quiz score won't be saved.
Progress1 / 9

Point estimates: what we want from data

Given i.i.d. data X1,…,Xn∼PθX_1, \ldots, X_n \sim P_\theta, a point estimator θ^n=T(X1,…,Xn)\hat{\theta}_n = T(X_1, \ldots, X_n) is any function of the data that produces a single guess for θ\theta. Common examples:

  • Sample mean Xˉn\bar{X}_n estimates the population mean μ\mu.
  • Sample variance s2=1n−1∑(Xi−Xˉ)2s^2 = \frac{1}{n-1}\sum(X_i - \bar{X})^2 estimates σ2\sigma^2.
  • Empirical proportion p^=k/n\hat{p} = k/n estimates a Bernoulli parameter.

An estimator is itself a random variable — it changes across different datasets. Two questions define its quality:

  1. Bias: is its expectation equal to the true θ\theta?
  2. Variance: how much does it fluctuate across repeated samples?

Notice n−1n-1 in s2s^2 instead of nn. That's not a typo — it's the correction that makes s2s^2 unbiased. The naive 1/n1/n version systematically underestimates σ2\sigma^2.

Full lesson text

All 9 steps on one page, for reading, reference, and search.

Show

1. Point estimates: what we want from data

Given i.i.d. data X1,…,Xn∼PθX_1, \ldots, X_n \sim P_\theta, a point estimator θ^n=T(X1,…,Xn)\hat{\theta}_n = T(X_1, \ldots, X_n) is any function of the data that produces a single guess for θ\theta. Common examples:

  • Sample mean Xˉn\bar{X}_n estimates the population mean μ\mu.
  • Sample variance s2=1n−1∑(Xi−Xˉ)2s^2 = \frac{1}{n-1}\sum(X_i - \bar{X})^2 estimates σ2\sigma^2.
  • Empirical proportion p^=k/n\hat{p} = k/n estimates a Bernoulli parameter.

An estimator is itself a random variable — it changes across different datasets. Two questions define its quality:

  1. Bias: is its expectation equal to the true θ\theta?
  2. Variance: how much does it fluctuate across repeated samples?

Notice n−1n-1 in s2s^2 instead of nn. That's not a typo — it's the correction that makes s2s^2 unbiased. The naive 1/n1/n version systematically underestimates σ2\sigma^2.

2. Bias and variance of an estimator

The bias of θ^\hat{\theta} is Bias(θ^)=E[θ^]−θ\text{Bias}(\hat{\theta}) = \mathbb{E}[\hat{\theta}] - \theta. An estimator is unbiased if Bias=0\text{Bias} = 0.

The mean squared error decomposes cleanly: MSE(θ^)=E[(θ^−θ)2]=Var(θ^)⏟variance+(Bias(θ^))2⏟bias2.\text{MSE}(\hat{\theta}) = \mathbb{E}[(\hat{\theta} - \theta)^2] = \underbrace{\text{Var}(\hat{\theta})}_{\text{variance}} + \underbrace{(\text{Bias}(\hat{\theta}))^2}_{\text{bias}^2}.

This is the bias-variance decomposition for estimation. A biased estimator can have lower MSE if it dramatically reduces variance — the logic behind ridge regression, early stopping, and shrinkage estimators like James-Stein.

Example: The sample mean Xˉn\bar{X}_n is unbiased (Bias=0\text{Bias}=0) with Var(Xˉn)=σ2/n\text{Var}(\bar{X}_n) = \sigma^2/n. As nn grows, variance shrinks to zero and θ^→θ\hat{\theta} \to \theta in probability — this is consistency.

3. Maximum Likelihood Estimation (MLE)

Principle: choose θ\theta that makes the observed data most probable.

θ^MLE=arg⁡max⁡θ L(θ)=arg⁡max⁡θ∏i=1nP(Xi∣θ).\hat{\theta}_{\text{MLE}} = \arg\max_\theta\, \mathcal{L}(\theta) = \arg\max_\theta \prod_{i=1}^n P(X_i \mid \theta).

Taking logs (monotone transform, doesn't change the argmax): θ^MLE=arg⁡max⁡θ∑i=1nlog⁡P(Xi∣θ).\hat{\theta}_{\text{MLE}} = \arg\max_\theta \sum_{i=1}^n \log P(X_i \mid \theta).

Log-likelihood is almost always easier to maximize. Key properties of MLE:

  • Consistent: θ^MLE→θ⋆\hat{\theta}_{\text{MLE}} \to \theta^\star as n→∞n \to \infty (under regularity).
  • Asymptotically normal: n(θ^MLE−θ⋆)→dN(0,I(θ⋆)−1)\sqrt{n}(\hat{\theta}_{\text{MLE}} - \theta^\star) \xrightarrow{d} \mathcal{N}(0, I(\theta^\star)^{-1}) where I(θ)I(\theta) is the Fisher information.
  • Asymptotically efficient: achieves the Cramér-Rao lower bound.
  • Invariant: if θ^\hat{\theta} is MLE of θ\theta, then g(θ^)g(\hat{\theta}) is MLE of g(θ)g(\theta).

4. Deriving the MLE: Bernoulli and Gaussian

Bernoulli(p)(p): observe kk successes in nn trials. Log-likelihood: ℓ(p)=klog⁡p+(n−k)log⁡(1−p).\ell(p) = k \log p + (n-k) \log(1-p). Set dℓ/dp=k/p−(n−k)/(1−p)=0d\ell/dp = k/p - (n-k)/(1-p) = 0. Solve: p^MLE=k/n\hat{p}_{\text{MLE}} = k/n. The sample proportion — obvious in hindsight, derived rigorously here.

Gaussian N(μ,σ2)\mathcal{N}(\mu, \sigma^2): log-likelihood is ℓ(μ,σ2)=−n2log⁡(2πσ2)−12σ2∑i=1n(Xi−μ)2.\ell(\mu, \sigma^2) = -\frac{n}{2}\log(2\pi\sigma^2) - \frac{1}{2\sigma^2}\sum_{i=1}^n (X_i - \mu)^2. Maximizing over μ\mu: μ^=Xˉn\hat{\mu} = \bar{X}_n. Maximizing over σ2\sigma^2: σ^2=1n∑i(Xi−Xˉ)2\hat{\sigma}^2 = \frac{1}{n}\sum_i(X_i - \bar{X})^2.

Note: σ^MLE2\hat{\sigma}^2_{\text{MLE}} uses 1/n1/n, making it biased (underestimates by factor (n−1)/n(n-1)/n). The unbiased fix is s2=nn−1σ^2s^2 = \frac{n}{n-1}\hat{\sigma}^2.

import numpy as np
np.random.seed(0)
data = np.random.normal(loc=5.0, scale=2.0, size=100)
print(f"MLE mu    = {data.mean():.3f}")
print(f"MLE sigma2 (biased) = {data.var(ddof=0):.3f}")
print(f"Unbiased s2         = {data.var(ddof=1):.3f}")

5. Confidence intervals

A (1−α)(1-\alpha) confidence interval [L,U][L, U] satisfies P(L≤θ≤U)=1−αP(L \le \theta \le U) = 1 - \alpha — but θ\theta is fixed, so this is a statement about the procedure: if you repeated the experiment many times, (1−α)(1-\alpha) fraction of the intervals you construct would contain θ\theta.

Common mistake: "There is a 95% probability that θ\theta is in this specific interval." Wrong. Once you have the data and compute [L,U][L, U], θ\theta is either in it or it isn't — no probability involved. The confidence is in the method, not the result.

For a Gaussian mean with known σ\sigma, the 95% CI is: Xˉn±1.96⋅σn.\bar{X}_n \pm 1.96 \cdot \frac{\sigma}{\sqrt{n}}. With unknown σ\sigma (the real case), replace 1.961.96 with t0.975,n−1t_{0.975, n-1} and σ\sigma with ss:

from scipy import stats
import numpy as np
data = np.random.normal(5, 2, 30)
ci = stats.t.interval(0.95, df=len(data)-1,
                      loc=data.mean(), scale=stats.sem(data))
print(f"95% CI: ({ci[0]:.2f}, {ci[1]:.2f})")

6. Hypothesis testing: the framework

A hypothesis test formalizes the question "is this effect real or noise?"

  1. Null hypothesis H0H_0: the default (no effect, no difference).
  2. Alternative H1H_1: what you're trying to detect.
  3. Test statistic TT: a function of the data designed to be large when H1H_1 is true.
  4. Rejection region: reject H0H_0 if T>cT > c (or ∣T∣>c|T| > c for two-sided tests).

Two error types:

Decision \ TruthH0H_0 trueH1H_1 true
Reject H0H_0Type I error (α\alpha)Correct (power)
Fail to rejectCorrectType II error (β\beta)
  • α\alpha = significance level = tolerated false-positive rate (usually 0.05).
  • Power =1−β= 1 - \beta = probability of detecting a real effect.
  • Reducing α\alpha increases β\beta — you can't minimize both without more data.

7. The p-value: definition and misinterpretations

The p-value is: p=P(T≥tobs∣H0 true)p = P(T \ge t_{\text{obs}} \mid H_0 \text{ true}) the probability of seeing data at least as extreme as what you observed, assuming the null is true.

You reject H0H_0 if p<αp < \alpha.

What p-values are NOT:

  • pp is not the probability that H0H_0 is true.
  • pp is not the probability that the result was due to chance.
  • p<0.05p < 0.05 does not imply the effect is large or practically important.
  • p>0.05p > 0.05 does not mean H0H_0 is true — it means the data is consistent with H0H_0.

A p-value of 0.03 with n=1,000,000n = 1{,}000{,}000 may correspond to a completely negligible effect size. Always pair hypothesis tests with effect sizes (Cohen's dd, relative risk, etc.) and confidence intervals.

from scipy import stats
group_a = [0.52, 0.61, 0.58, 0.55, 0.60]
group_b = [0.48, 0.51, 0.49, 0.53, 0.47]
t_stat, p_val = stats.ttest_ind(group_a, group_b)
print(f"t={t_stat:.3f}, p={p_val:.3f}")

8. The z-test and t-test

One-sample z-test (known σ\sigma): test H0:μ=μ0H_0: \mu = \mu_0 using Z=Xˉn−μ0σ/n∼N(0,1) under H0.Z = \frac{\bar{X}_n - \mu_0}{\sigma / \sqrt{n}} \sim \mathcal{N}(0,1) \text{ under } H_0.

One-sample t-test (unknown σ\sigma): replace σ\sigma with ss: T=Xˉn−μ0s/n∼tn−1 under H0.T = \frac{\bar{X}_n - \mu_0}{s / \sqrt{n}} \sim t_{n-1} \text{ under } H_0. The tt-distribution has heavier tails than the standard normal, reflecting uncertainty about σ\sigma. With n>30n > 30 the difference is negligible in practice.

Two-sample t-test: compares means of two independent groups. Under H0:μ1=μ2H_0: \mu_1 = \mu_2, T=Xˉ1−Xˉ2s12/n1+s22/n2∼tν (Welch approximation for df ν).T = \frac{\bar{X}_1 - \bar{X}_2}{\sqrt{s_1^2/n_1 + s_2^2/n_2}} \sim t_{\nu} \text{ (Welch approximation for df }\nu\text{)}.

In ML: use two-sample tt-tests to compare two models' accuracy across kk-fold cross-validation runs. Paired t-test (one fold = one pair) is preferred when variance across folds is large.

9. Multiple testing and Type I error inflation

Run 20 independent tests each at α=0.05\alpha = 0.05. Under the null, the probability of at least one false positive is 1−0.9520≈64%1 - 0.95^{20} \approx 64\%. This is the multiple testing problem — a major source of irreproducibility in science and A/B testing.

Corrections:

  • Bonferroni: use threshold α/m\alpha/m for mm tests. Conservative but simple.
  • Benjamini-Hochberg (BH): controls the false discovery rate (FDR) = expected fraction of rejected nulls that are false positives. Less conservative than Bonferroni.

In ML specifically: hyperparameter sweeps, feature selection, neural architecture search, and leaderboard evaluation are all multiple-comparison problems. Always report whether corrections were applied.

from statsmodels.stats.multitest import multipletests
import numpy as np
np.random.seed(1)
pvals = np.random.uniform(size=50)  # all null
reject, pvals_adj, _, _ = multipletests(pvals, alpha=0.05, method='fdr_bh')
print(f"Rejected: {reject.sum()} out of 50")
# Should be ~0-3 (FDR controls the fraction, not the count)

Check your understanding

The lesson ends with a 5-question quiz. Take it in the player above to see your score.

  1. You flip a coin $n=40$ times and see $k=26$ heads. What is $\hat{p}_{\text{MLE}}$?
    • 0.5 (the prior mean)
    • 0.65
    • 0.6
    • 0.75
  2. The MLE of the Gaussian variance $\hat{\sigma}^2 = \frac{1}{n}\sum_i (X_i - \bar{X})^2$ is:
    • Unbiased and consistent.
    • Biased but consistent.
    • Unbiased but inconsistent.
    • Biased and inconsistent.
  3. A study reports $p = 0.04$ and declares the effect 'statistically significant at $\alpha=0.05$'. Which additional piece of information is most critical for evaluating the practical importance of the result?
    • The value of $\alpha$ used in the test.
    • The effect size and a confidence interval.
    • The number of hypotheses tested.
    • Whether the test was one-sided or two-sided.
  4. A 95% confidence interval for a mean is $(3.2, 7.8)$. Which interpretation is correct?
    • There is a 95% probability that the true mean lies in $(3.2, 7.8)$.
    • The procedure that produced this interval would contain the true mean in 95% of repeated experiments.
    • 95% of individual data points fall between 3.2 and 7.8.
    • The true mean equals the midpoint 5.5 with 95% confidence.
  5. You run 100 A/B tests on a platform where the null is true for all 100. Using $\alpha = 0.05$ with no multiple-testing correction, approximately how many false positives do you expect?
    • 0
    • 5
    • 1
    • 50

Related lessons