Hoppa till innehållet
AI-grafen
E· Universitetstatistik-sannolikhet· ca 60 min· utvecklande· verifierad 2026-09-20

Bootstrap och resampling

Kunna skatta osäkerhet i en modells mått med bootstrap.

Förkunskaper

Intuition

Du har ett stickprov och vill veta hur osäker din skattning är. Idealt skulle du dra hundra nya stickprov ur populationen — men du har bara detta.

Bootstrap: behandla ditt stickprov som om det vore populationen. Dra n observationer med återläggning, beräkna måttet, upprepa några tusen gånger. Spridningen i de tusen värdena skattar spridningen i din skattning.

Varför det är så användbart i ML: det fungerar för vilket mått som helst — F1, AUC, BLEU, grundningsgrad, kostnad per löst uppgift, medianlatens. Formler finns bara för de enklaste måtten; bootstrap behöver inga.

Formellt

Percentilmetoden (enklast, oftast tillräcklig): kör B ≈ 2 000–10 000 resamplingar, sortera skattningarna, ta percentil 2,5 och 97,5.

Varianter att känna till:

VariantNär
Percentilstandardvalet
BCa (bias-corrected and accelerated)skev fördelning eller bias — mer korrekt täckning
Parad bootstrapjämförelse av två modeller på samma fall — resampla fallen, behåll paren
Block-bootstraptidsserier — resampla sammanhängande block, inte enskilda punkter
Stratifieradbevara klassfördelningen vid obalans

Där bootstrap inte fungerar:

  • Extremvärden (max, min) — resamplingen kan inte se bortom stickprovets största värde.
  • Mycket små stickprov (n < 20) — resamplingarna blir för lika varandra.
  • Beroende data utan blockstruktur — oberoenderesampling underskattar osäkerheten kraftigt.

Den vanligaste feltillämpningen i ML: att resampla förutsägelser i stället för testfall. Det är fallen som är den slumpmässiga enheten — och vid jämförelse mellan modeller måste samma resamplade index användas för båda.

Kod

import numpy as np
from sklearn.metrics import f1_score

def bootstrap_ki(y, pred, matt=lambda y, p: f1_score(y, p, average="macro"),
                 B=5000, alfa=0.05, seed=0):
    rng = np.random.default_rng(seed)
    n = len(y)
    varden = np.empty(B)
    for b in range(B):
        idx = rng.integers(0, n, n)                     # med återläggning
        varden[b] = matt(y[idx], pred[idx])
    lo, hi = np.percentile(varden, [100*alfa/2, 100*(1-alfa/2)])
    return {"skattning": float(matt(y, pred)), "ki": (float(lo), float(hi))}

def parad_bootstrap(y, pred_a, pred_b, matt, B=5000, seed=0):
    """SAMMA index för båda modellerna — annars mäter du fel sak."""
    rng = np.random.default_rng(seed); n = len(y)
    diff = np.empty(B)
    for b in range(B):
        idx = rng.integers(0, n, n)
        diff[b] = matt(y[idx], pred_b[idx]) - matt(y[idx], pred_a[idx])
    lo, hi = np.percentile(diff, [2.5, 97.5])
    return {"skillnad": float(diff.mean()), "ki": (float(lo), float(hi)),
            "andel_over_noll": float((diff > 0).mean())}

Behärskning innebär

  • Skattar osäkerhet i ett mått med bootstrap
  • Väljer rätt bootstrap-variant
  • Känner till metodens gränser

Logga in för att göra övningarna och bygga upp din behärskning.

Källor

Alla källor och licenser