Hoppa till innehållet
AI-grafen
F· AI engineeringstatistik-sannolikhet· ca 90 min· volatil — kontrolleras ofta· verifierad 2026-09-20

Multipla jämförelser

Kunna korrigera för många samtidiga test och förklara varför benchmark-jakt ger falska framsteg.

Förkunskaper

Intuition

Testar du en hypotes med α = 0,05 är risken för falsklarm 5 %. Testar du tjugo oberoende hypoteser är risken att minst en ger falsklarm:

1 − 0,95²⁰ ≈ 64 %

Det är matematiken bakom en stor del av det som ser ut som framsteg i ML. Prova tjugo arkitekturvarianter, rapportera den som vann — och du har rapporterat brus.

Antal testP(minst ett falsklarm)
15 %
523 %
2064 %
10099,4 %

Formellt

Bonferroni: använd tröskeln α/m\alpha/m för mm test. Kontrollerar familywise error rate (risken för något falsklarm). Enkelt och konservativt — med 20 test blir tröskeln 0,0025, och verkliga effekter missas lätt.

Benjamini–Hochberg (FDR): sortera p-värdena p(1)≤⋯≤p(m)p_{(1)}\le\dots\le p_{(m)}, hitta största kk med p(k)≤kmαp_{(k)} \le \frac{k}{m}\alpha, förkasta alla upp till kk. Kontrollerar andelen falska bland de förkastade i stället för risken för någon enda. Mycket mer kraftfull när många test görs, och standard i exempelvis genetik.

Det viktigaste är ändå inte korrektionen utan redovisningen: rapportera hur många varianter som provades. Ett resultat från «vi testade tre konfigurationer» och ett från «vi testade hundra» är olika starka, även med samma p-värde.

Benchmark-jakt är samma fenomen på fältnivå: hundratals forskargrupper testar mot samma benchmark, och de som råkar få höga tal publicerar. Därför krävs replikering på nya data — inte bara ett rekord.

Kod

import numpy as np

def bonferroni(p, alfa=0.05):
    p = np.asarray(p)
    return p <= alfa / len(p)

def benjamini_hochberg(p, alfa=0.05):
    p = np.asarray(p); m = len(p)
    ordning = np.argsort(p)
    trosklar = (np.arange(1, m + 1) / m) * alfa
    under = p[ordning] <= trosklar
    k = np.max(np.where(under)[0]) + 1 if under.any() else 0
    ut = np.zeros(m, bool); ut[ordning[:k]] = True
    return ut

p = [0.001, 0.008, 0.02, 0.04, 0.06, 0.20, 0.31, 0.55]
print(bonferroni(p).astype(int))            # [1 0 0 0 0 0 0 0]
print(benjamini_hochberg(p).astype(int))    # [1 1 1 0 0 0 0 0]

# risken för minst ett falsklarm utan korrektion
for m in (1, 5, 20, 100):
    print(m, round(1 - 0.95 ** m, 3))

Behärskning innebär

  • Korrigerar för många samtidiga test
  • Förklarar varför benchmark-jakt ger falska framsteg
  • Väljer mellan Bonferroni och FDR

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

Källor

Alla källor och licenser