Probability · Statistical Inference
📅 July 2026 ⏱ ≈ 13 min read 🎯 Intermediate

Resampling Methods: Bootstrap & Jackknife

What is the uncertainty of the median of 40 measurements, when there is no textbook formula for its standard error? Resampling gives an answer without assuming any distribution: resample the data itself. We cover the nonparametric bootstrap, percentile confidence intervals, the leave-one-out jackknife, and a full JavaScript implementation of both.

TL;DR: To find the uncertainty of a statistic like the median, resample your own data with replacement thousands of times (the bootstrap) and read off the spread, or systematically leave out one point at a time (the jackknife) to estimate bias and variance. The bootstrap handles skewed or non-smooth statistics better; the jackknife is cheaper but fails for the median.

1. Why resample? The plug-in principle

Classical statistics gives closed-form standard errors for simple statistics like the mean (σ/√n), but for the median, trimmed mean, correlation coefficient, or a ratio of two statistics, no such formula generally exists — or it depends on unknown properties of the population distribution.

Bradley Efron's plug-in principle (1979) resolves this: since we don't know the true population distribution F, we plug in the empirical distribution F̂ — the sample itself, treating each observed value as equally likely — and estimate the sampling variability of a statistic by repeatedly resampling from F̂ instead of F.

2. The bootstrap algorithm

Given an original sample x₁, …, xₙ and a statistic θ̂ = T(x₁,…,xₙ) (e.g. the mean, median, or standard deviation), the nonparametric bootstrap works as follows:

  1. Draw a bootstrap sample x₁*, …, xₙ* of size n by sampling with replacement from the original data.
  2. Compute the statistic on the resample: θ̂* = T(x₁*, …, xₙ*).
  3. Repeat steps 1–2 B times (typically B = 1 000–10 000) to get a bootstrap distribution θ̂*₁, …, θ̂*ᴮ.
  4. Use the spread of the bootstrap distribution as an estimate of the sampling distribution of θ̂.
Bootstrap standard error: SE*(θ̂) = √[ (1/(B−1)) · Σᵦ (θ̂*ᵦ − θ̄*)² ]
// θ̄* is the mean of the B bootstrap replicates
Key insight: because each bootstrap resample draws n items with replacement from n original items, on average about 63.2% of the original observations appear at least once in each resample (the rest are duplicates) — this follows from 1 − (1 − 1/n)ⁿ → 1 − e⁻¹ ≈ 0.632 as n grows.

3. Bootstrap confidence intervals

The simplest and most widely used interval is the percentile method: sort the B bootstrap replicates and take the empirical 2.5th and 97.5th percentiles as a 95% confidence interval:

CI₉₅% = [ θ̂*₍₀.₀₂₅ᴮ₎ , θ̂*₍₀.₉₇₅ᴮ₎ ]

This makes no assumption of Normality and works even for skewed sampling distributions (e.g. of the median, or of a ratio). More refined variants exist for cases where the percentile method is biased:

For comparison, the classical parametric CI for a mean under an assumed Normal population uses the t-distribution: X̄ ± tn−1,0.975·s/√n. When data really are close to Normal, this and the bootstrap percentile CI nearly coincide; when data are skewed or the statistic is nonlinear (e.g. the median), they diverge and the bootstrap is more trustworthy.

4. The jackknife: leave-one-out

The jackknife (Quenouille 1949, Tukey 1958) predates the bootstrap and uses a deterministic resampling scheme: compute the statistic n times, each time leaving out exactly one observation.

θ̂₍ᵢ₎ = T(x₁, …, xᵢ₋₁, xᵢ₊₁, …, xₙ)   for i = 1, …, n

Jackknife mean: θ̄₍·₎ = (1/n) Σᵢ θ̂₍ᵢ₎

Bias estimate

Biasjack(θ̂) = (n − 1) · ( θ̄₍·₎ − θ̂ )

Variance / standard error estimate

Varjack(θ̂) = [ (n − 1) / n ] · Σᵢ ( θ̂₍ᵢ₎ − θ̄₍·₎ )²

The factor (n−1) inflates the raw variance of the leave-one-out estimates because each θ̂₍ᵢ₎ is computed from n−1 points and hence varies less than an independent replicate would — the jackknife formula corrects for this.

The jackknife fails for non-smooth statistics. For the median, leaving out one observation typically changes the estimate by 0 or by a full data-spacing jump, never smoothly — the jackknife variance estimate is provably inconsistent for the median. Use the bootstrap instead for non-smooth statistics like the median or other quantiles.

5. Bootstrap vs jackknife

PropertyBootstrapJackknife
ResamplesB random, with replacementn deterministic, leave-one-out
Computational costO(B·n) — B often 1 000+O(n²) worst case — only n replicates
Works for the medianYesNo (inconsistent)
Confidence intervalsPercentile, BCa, pivotal — directRequires Normal approximation on top
Historical roleGeneral-purpose, standard todaySimpler precursor, still used for bias/variance of smooth statistics

In modern practice the bootstrap has largely superseded the jackknife for confidence intervals, but the jackknife remains useful as a cheap, deterministic bias-correction tool and underlies cross-validation and jackknife-after-bootstrap diagnostics.

6. JavaScript implementation

function mean(arr) { return arr.reduce((a,b) => a+b, 0) / arr.length; }

function median(arr) {
  const s = [...arr].sort((a,b) => a-b);
  const mid = Math.floor(s.length / 2);
  return s.length % 2 ? s[mid] : (s[mid-1] + s[mid]) / 2;
}

// ── Bootstrap: resample with replacement, B times ──────────────
function bootstrap(data, statFn, B = 2000) {
  const n = data.length;
  const replicates = new Array(B);
  for (let b = 0; b < B; b++) {
    const sample = new Array(n);
    for (let i = 0; i < n; i++) sample[i] = data[Math.floor(Math.random() * n)];
    replicates[b] = statFn(sample);
  }
  return replicates;
}

// ── Percentile confidence interval from bootstrap replicates ───
function percentileCI(replicates, alpha = 0.05) {
  const sorted = [...replicates].sort((a,b) => a-b);
  const lo = sorted[Math.floor((alpha/2) * sorted.length)];
  const hi = sorted[Math.ceil((1 - alpha/2) * sorted.length) - 1];
  return [lo, hi];
}

// ── Jackknife: leave-one-out bias and variance ─────────────────
function jackknife(data, statFn) {
  const n = data.length;
  const full = statFn(data);
  const looEstimates = new Array(n);
  for (let i = 0; i < n; i++) {
    const leaveOneOut = data.slice(0, i).concat(data.slice(i + 1));
    looEstimates[i] = statFn(leaveOneOut);
  }
  const jackMean = mean(looEstimates);
  const bias = (n - 1) * (jackMean - full);
  const variance = ((n - 1) / n) *
    looEstimates.reduce((s, v) => s + (v - jackMean) ** 2, 0);
  return { estimate: full, bias, se: Math.sqrt(variance) };
}

// ── Example: bootstrap and jackknife for the median ────────────
const data = [12, 15, 14, 10, 50, 13, 11, 16, 9, 14]; // right-skewed by outlier 50
const replicates = bootstrap(data, median, 5000);
console.log('bootstrap SE', Math.sqrt(bootstrap(data, median, 5000).reduce(
  (s,x,_,a) => s + (x - mean(a))**2, 0) / (replicates.length - 1)));
console.log('95% percentile CI', percentileCI(replicates));
console.log('jackknife (mean, not median!)', jackknife(data, mean));

7. Pitfalls

🎯 Explore Monte Carlo simulations

See resampling-style randomness at work: thousands of trials converging to a stable estimate.

Open simulation →

🔗 Related Simulations

🎯Monte Carlo 📈Normal Distribution 🎯Bayesian Inference 🃏Markov Chain