23 — Make Decisions

Bootstrap Methods#

ResamplingStatistical 1 min read
◆ The PatternEstimate anything with resampling — the nonparametric Swiss army knife for uncertainty

Bootstrap resamples your data with replacement thousands of times, computing your statistic each time. The distribution of bootstrap estimates approximates the sampling distribution of your statistic — giving you standard errors and CIs without formulas.

θ* = statistic(resample(data))
Repeat B times → distribution of θ* → SE = std(θ*)  |  CI = percentiles
// Interactive — bootstrap distribution of the mean
Resamples1000
SE—
BCa (bias-corrected and accelerated): The basic percentile method works but BCa is more accurate for skewed distributions. scipy.stats.bootstrap offers this.
Pattern bridge: Resampling with replacement is also how bagging builds varied models — see forecast ensembles — and resampling past returns is how historical value at risk estimates a bad day without assuming a bell curve.
Worked example

Bootstrapping the maximum of 50 values: in 63.8% of resamples the “new” maximum is just the original maximum, matching the theoretical 1 − (1 − 1/50)⁵⁰ = 63.6%. The bootstrap distribution piles up on one value and cannot see beyond the sample. The bootstrap works for smooth statistics like means; it fails for extremes.

Where it misleads
  • Other failures: very small samples, heavy tails with infinite variance, and dependent data resampled as if independent.
  • Dependent data need block or stationary bootstraps that keep neighbours together.
  • The bootstrap estimates sampling variability, not bias from a flawed design.
In code
rng = np.random.default_rng(15)
x = rng.uniform(0, 1, 50)
boot_max = np.array([rng.choice(x, 50).max() for _ in range(10_000)])
share_equal = (boot_max == x.max()).mean()            # resamples whose max is just the sample max
theory = 1 - (1 - 1 / 50) ** 50
Python, in your browser — edit the code and run it again

Assumes import numpy as np and import pandas as pd (and SciPy where imported). Each snippet simulates or makes up its own data, as the comments say.

The same idea with a library
# Python — bootstrap for any statistic
import numpy as np

def bootstrap(data, stat_fn, B=10000):
    n = len(data)
    estimates = [stat_fn(np.random.choice(data, n, replace=True))
                 for _ in range(B)]
    return np.array(estimates)

# Bootstrap the median (no formula needed!)
boots = bootstrap(data, np.median)
ci = np.percentile(boots, [2.5, 97.5])
se = boots.std()
Sources
  • B. Efron, “Bootstrap Methods: Another Look at the Jackknife”, Annals of Statistics 7(1), 1979
  • P. J. Bickel & D. A. Freedman, “Some Asymptotic Theory for the Bootstrap”, Annals of Statistics 9(6), 1981
  • An Introduction to the Bootstrap, B. Efron & R. J. Tibshirani, Chapman & Hall, 1993

Last reviewed October 2026 · How this site checks its content · Report a mistake

Linked from 1
← Previous
Confidence Intervals
Open in the full reader, with the topic sidebar