7.2 Bootstrap for standardfeil og simulert dekning
Estimér standardfeilen du ikke kan regne — parametrisk og ikke-parametrisk bootstrap — og simuler dekningsgraden til et konfidensintervall.
- Bootstrap for standardfeil (sjanger I): ikke-parametrisk allerede i V2015 og V2016; parametrisk i V2019 og V2021; full kjørbar Python-kode fra V2020.
- Simulert dekningsgrad (eksakt pivotal-KI mot Wald-KI) i V2024 — den bygger direkte på dekningstallene fra kap. 6.2.
- «Sjanger I» = simulering, bootstrap og Python (samme kode som i kap. 7.1).
- Sensorkrav 10: bootstrap-algoritmen skal beskrives presist og koden være kjørbar med ddof=1. All kode her er faktisk kjørt.
Prioritet: kunne (nivå 2). Sammen med kap. 7.1 er dette det som skiller en A fra en B når den analytiske standardfeilen er vanskelig eller umulig å regne ut for hånd.
np.random.uniform, vektorisering, ddof=1) og kap. 5.1 (standardfeil). Dekningsdelen henter inn det eksakte pivotal-KI-et fra kap. 6.2 og den analytiske standardfeilen fra kjeden i kap. 6.3.Sist du var her — det du må ha friskt:
1. Standardfeilen til en estimator er standardavviket til estimatoren: (fra kap. 5.1). Den forteller hvor mye estimatet ville variert fra utvalg til utvalg.
2. ddof=1 i np.std/np.var gir den forventningsrette empiriske variansen (divisor ) — vi bruker den til å regne ut bootstrap-SE-en.
3. Eksakt pivotal-KI for eksponensial (forventning , fra kap. 6.2): siden , er et -KI , der og er øvre- og nedre-halekvantilene. Dette bruker vi i dekningsstudien til slutt.
Iblant har du en estimator der du enkelt kan regne ut estimatet, men der den analytiske standardfeilen er stygg eller umulig å utlede — for eksempel medianen, eller en komplisert funksjon av flere parametre. Bootstrap løser dette ved en enkel idé: lat som utvalget ditt er hele befolkningen, trekk mange nye «utvalg», og se hvor mye estimatoren spriker. Spredningen i disse gjentatte estimatene er standardfeilen.
Vi møter to varianter (ikke-parametrisk og parametrisk), pluss det nært beslektede Monte Carlo-prinsippet: en sannsynlighet er en forventet indikator, så den estimeres med et gjennomsnitt. Til slutt setter vi alt sammen i en dekningsstudie som viser hvorfor et eksakt KI treffer 95 % mens et Wald-KI bommer for liten — mekanismen bak tallene i kap. 6.2.
Fire læringsløkker à ~13 min — ta en pause etter løkke 2.
Løkke 1 — Ikke-parametrisk bootstrap (~14 min)
1. Trekk et nytt «utvalg» av samme størrelse som dataene.
2. Regn ut estimatoren på nytt: .
Til slutt: estimer standardfeilen som det empiriske standardavviket til de verdiene:
Ikke-parametrisk bootstrap trekker de nye utvalgene med tilbakelegging fra selve dataene (np.random.choice(data, size=n, replace=True)). Vi antar altså ingen bestemt fordeling — dataene får «tale for seg selv». Nøkkelen er replace=True: uten tilbakelegging ville hvert trekk bare vært en omstokking av de samme tallene, og all variasjon forsvant.
Merk skillet mot : er utvalgsstørrelsen (fast, gitt av dataene); er hvor mange bootstrap-trekk vi gjør (vi velger den selv, typisk 1 000–10 000). Flere gir bare et mer presist SE-estimat — det endrer ikke .
Ti målte konsentrasjoner (mg/l) er . Du vil estimere standardfeilen til medianen — men det finnes ingen enkel formel. Bruk ikke-parametrisk bootstrap med .
Medianen har ingen pen analytisk standardfeil, så bootstrap er det naturlige verktøyet. Vi trekker med tilbakelegging fra de ti tallene, regner medianen på nytt hver gang, og tar standardavviket:
import numpy as np
data = np.array([2.1, 5.4, 1.2, 8.9, 3.3, 6.7, 0.8, 4.5, 12.1, 2.9])
n = len(data)
np.random.seed(0)
B = 10000
theta_b = np.empty(B)
for b in range(B):
xb = np.random.choice(data, size=n, replace=True) # med tilbakelegging!
theta_b[b] = np.median(xb)
print(np.median(data), np.std(theta_b, ddof=1))
# 3.9 1.3634...Medianen i de opprinnelige dataene er , og bootstrap-standardfeilen er . Tolkning: hadde vi samlet inn nye datasett av samme størrelse, ville medianestimatet typisk variert med rundt mg/l.
Kritisk detalj: replace=True og ddof=1. Fjerner du replace=True, blir hvert xb bare en omstokking av de samme ti tallene, medianen er (nesten) konstant, og SE-en kollapser feilaktig mot 0.
(Innsteg.) Beskriv i ord de tre stegene i ikke-parametrisk bootstrap for å estimere standardfeilen til en estimator , og si eksplisitt hvordan de nye utvalgene trekkes.
En student skriver denne bootstrap-koden for SE-en til gjennomsnittet, men får en mistenkelig liten verdi:
theta_b = np.empty(B)
for b in range(B):
xb = np.random.choice(data, size=n, replace=False)
theta_b[b] = np.mean(xb)
se = np.std(theta_b, ddof=1)a) Hva er feilen, og hvorfor blir SE-en (nesten) 0?
b) Rett koden.
Løkke 2 — Parametrisk bootstrap (~14 min)
— naturlig pausepunkt etter denne løkka —
| Trekker nye utvalg fra … | |
|---|---|
| Ikke-parametrisk | dataene, med tilbakelegging |
| Parametrisk | den tilpassede fordelingen (med satt inn) |
Når velge hva? Parametrisk bootstrap er mer presis hvis fordelingsantakelsen er riktig (den utnytter modellen); ikke-parametrisk er tryggere når du er usikker på fordelingen. Begge gir SE-en som
np.std(theta_b, ddof=1).De ti målingene fra eksempel 1 antas nå eksponensialfordelte med forventning (forventnings-parametrisering, ). Estimatoren er . Bruk parametrisk bootstrap () til å estimere standardfeilen til , og sammenlign med den analytiske .
Vi tilpasser modellen (), trekker nye eksponensiale utvalg fra eksponensial med inversjonsformelen , og regner på nytt:
import numpy as np
data = np.array([2.1, 5.4, 1.2, 8.9, 3.3, 6.7, 0.8, 4.5, 12.1, 2.9])
n = len(data)
muhat = np.mean(data)
np.random.seed(0)
B = 10000
theta_b = np.empty(B)
for b in range(B):
xb = -muhat * np.log(1 - np.random.uniform(size=n)) # fra tilpasset eksp(muhat)
theta_b[b] = np.mean(xb)
print(muhat, np.std(theta_b, ddof=1), muhat / np.sqrt(n))
# 4.79 1.5072... 1.5147...Estimatet er . Parametrisk bootstrap-SE er , og den analytiske . De to stemmer nesten perfekt — som de skal, siden vi bootstrapper fra nøyaktig den modellen den analytiske formelen forutsetter. Her kan vi regne SE-en analytisk; poenget er at bootstrap gir samme svar og fungerer også når den analytiske formelen mangler.
Forklar forskjellen på ikke-parametrisk og parametrisk bootstrap i én setning hver, og gi ett argument for når du ville foretrukket den ikke-parametriske varianten.
Levetider antas eksponensialfordelte med forventning , og du vil estimere standardfeilen til estimatoren (et estimat av medianen, siden medianen er ). Du har observasjoner med gjennomsnitt .
a) Skriv parametrisk bootstrap-kode () som estimerer .
b) Den analytiske SE-en er . Hva bør bootstrap-anslaget ligge nær?
Løkke 3 — Monte Carlo som inferensverktøy (~14 min)
Dette Monte Carlo-estimatet har fine egenskaper:
- Det er forventningsrett: (gjennomsnittet av forventningsrette indikatorer).
- Variansen er (indikatorene er uavhengige med varians ).
- Derfor er standardfeilen , som avtar som . Vil du halvere usikkerheten, må du firedoble .
Merk igjen: presisjonen styres av (antall trekk), ikke av .
En komponent har eksponensialfordelt levetid med forventning år. Estimer med Monte Carlo (), oppgi Monte Carlo-standardfeilen, og sammenlign med den eksakte verdien.
Vi trekker eksponensiale levetider og tar gjennomsnittet av indikatoren x > 8:
import numpy as np
np.random.seed(0)
B = 10**6
x = -5 * np.log(1 - np.random.uniform(size=B))
p = np.mean(x > 8)
print(p, np.sqrt(p * (1 - p) / B))
# 0.20242... 0.000402...Monte Carlo-estimatet er med standardfeil . Eksakt: . Estimatet ligger godt innenfor et par standardfeil av sannheten.
La merke til -loven: med er SE-en på fjerde desimal. Ville vi ned til , måtte opp til .
Et Monte Carlo-estimat av en sannsynlighet bygger på uavhengige trekk. Estimatet blir .
a) Hva er Monte Carlo-standardfeilen?
b) Omtrent hvor stor må være for å halvere denne standardfeilen?
(Kodelesing.) Forklar hva denne koden estimerer, og hvorfor np.mean av en betingelse gir en sannsynlighet:
import numpy as np
from scipy import stats
np.random.seed(0)
y = stats.norm.rvs(10, 2, size=10**6)
print(np.mean((y > 8) & (y < 12)))Løkke 4 — Simulert dekningsgrad: eksakt mot Wald (~14 min)
Et -konfidensintervall skal, over mange gjentatte utvalg, dekke den sanne parameteren av gangene. Simulert dekningsgrad sjekker om det stemmer:
1. Generer mange datasett fra en fordeling med kjent sann parameter.
2. Bygg KI-et i hvert datasett.
3. Tell andelen KI-er som faktisk dekker den sanne parameteren.
Dette er mekanismen bak dekningstallene fra kap. 6.2: det eksakte pivotal-KI-et treffer (fordi er en eksakt pivotal), mens Wald-KI-et underdekker for liten — fordi for eksponensiale data er høyreskjevt, ikke symmetrisk normalfordelt slik Wald antar.
«Dekker»-indikatoren er bare lo <= mu <= hi, og dekningsgraden er np.mean av den — igjen: en sannsynlighet er en forventet indikator.
For eksponensialfordelte data med forventning og : simuler dekningsgraden til (i) det eksakte pivotal-KI-et og (ii) Wald-KI-et , over datasett. Forklar forskjellen.
Vi lager datasett fra eksponensial, bygger begge KI-ene i hvert, og teller andelen som dekker :
import numpy as np
from scipy import stats
np.random.seed(0)
n, mu, M = 10, 5.0, 20000
dekk_eksakt = 0
dekk_wald = 0
for _ in range(M):
x = -mu * np.log(1 - np.random.uniform(size=n))
xbar = np.mean(x)
# eksakt pivotal: 2*n*xbar/mu ~ chi^2_{2n}
lo = 2*n*xbar / stats.chi2.ppf(0.975, 2*n)
hi = 2*n*xbar / stats.chi2.ppf(0.025, 2*n)
if lo <= mu <= hi:
dekk_eksakt += 1
# Wald: xbar +/- 1.96 * SE, med SE = xbar/sqrt(n)
se = xbar / np.sqrt(n)
if xbar - 1.96*se <= mu <= xbar + 1.96*se:
dekk_wald += 1
print(dekk_eksakt/M, dekk_wald/M)
# 0.9508 0.9015Resultat: det eksakte KI-et dekker — praktisk talt nominelt , som det skal siden pivotalen er eksakt uansett og . Wald-KI-et dekker bare — det underdekker klart.
Hvorfor? Wald antar at er tilnærmet normalfordelt og symmetrisk rundt . For eksponensiale observasjoner er fortsatt merkbart høyreskjevt, så det symmetriske -intervallet bommer oftere enn de lovede . Dette er nøyaktig asymmetrien kap. 6.2 tallfestet (der ca. mot for den oppgavens oppsett) — samme mekanisme, små forskjeller skyldes ulikt antall gjentak og tilfeldig frø. Konklusjonen er den samme: for liten er det eksakte pivotal-KI-et å foretrekke.
I dekningskoden over står linjen
lo = 2*n*xbar / stats.chi2.ppf(0.975, 2*n)
hi = 2*n*xbar / stats.chi2.ppf(0.025, 2*n)a) Forklar hvorfor den nedre grensen lo bruker den øvre kvantilen chi2.ppf(0.975, 2n).
b) Hvor mange frihetsgrader har kjikvadratfordelingen her, og hvorfor?
Du skal undersøke hvordan Wald-KI-ets underdekning avhenger av utvalgsstørrelsen for eksponensiale data.
a) Beskriv hvordan du ville endre dekningskoden for å studere i stedet for bare .
b) Hva forventer du skjer med Wald-dekningen når vokser, og hvorfor? Hva skjer med den eksakte dekningen?
- Glemme ddof=1 i bootstrap-SE-en. np.std(theta_b, ddof=1) deler på og gir standardfeilen; uten ddof=1 deles det på .
- Beskrive bootstrap upresist. Si eksplisitt at ikke-parametrisk bootstrap trekker med tilbakelegging fra dataene, og at parametrisk bootstrap trekker fra den tilpassede fordelingen (med satt inn). En beskrivelse uten dette taper poeng (sensorkrav 10).
- Forveksle og . = antall bootstrap-/Monte Carlo-trekk (styrer presisjonen, avtar som ); = utvalgsstørrelsen (fast, gitt av dataene). Flere gjør ikke datasettet ditt større.
- replace=False i ikke-parametrisk bootstrap. Uten tilbakelegging blir hvert «utvalg» en ren omstokking, og SE-en kollapser mot 0.
- Simulere dekning under feil fordeling. Skal du studere dekningen til et KI, må datasettene genereres fra den fordelingen KI-et forutsetter — ellers måler du noe annet.
Begrepsbank
Flashcard-/repetisjonsstoff — hopp trygt over ved førstegangslesing; tidsanslaget gjelder kjernestoffet. Kortene samler algoritmene og idiomene til rask repetisjon.
Å estimere usikkerheten til en estimator ved å trekke mange nye «utvalg», regne estimatoren på nytt hver gang, og måle spredningen. Man later som utvalget er hele befolkningen. Brukes særlig når den analytiske standardfeilen er vanskelig eller umulig.
Bootstrap der de nye utvalgene trekkes med tilbakelegging fra selve dataene, uten noen fordelingsantakelse. Dataene «taler for seg selv». I kode: np.random.choice(data, size=n, replace=True).
Bootstrap der de nye utvalgene trekkes fra en tilpasset fordeling med parameterestimatet satt inn. Mer presis når fordelingsantakelsen er riktig; arver feilen hvis modellen er gal.
Trekker med tilbakelegging fra et array — motoren i ikke-parametrisk bootstrap. replace=True er avgjørende: uten den blir trekket bare en omstokking og all variasjon forsvinner.
Standardfeilen estimert som det empiriske standardavviket til de bootstrap-estimatene: np.std(theta_b, ddof=1). Divisor (altså ddof=1).
For : trekk nytt utvalg, regn ; til slutt SE standardavviket til de verdiene. I kode: for _ in range(B): xb = ...; theta_b.append(estimator(xb)) deretter np.std(theta_b, ddof=1).
Kjernen i bootstrap: i hvert trekk anvendes den samme estimatoren (median, gjennomsnitt, …) på det nye utvalget. Variasjonen i disse gjenberegningene er det bootstrap måler.
En sannsynlighet er en forventet indikator: , der er 1 om hendelsen inntreffer. Derfor kan enhver sannsynlighet estimeres med et gjennomsnitt av indikatorer.
Estimatet np.mean(betingelse) av en sannsynlighet — andelen av trekk som oppfyller betingelsen. Eksempel: np.mean(x > 8) estimerer .
Monte Carlo-estimatet av en sannsynlighet er forventningsrett: , fordi det er gjennomsnittet av forventningsrette indikatorer med forventning .
Variansen til MC-estimatet er (uavhengige indikatorer, hver med varians ). Standardfeilen er .
Monte Carlo-standardfeilen avtar proporsjonalt med . For å halvere usikkerheten må antall trekk firedobles.
Standardavviket til en estimator: (fra kap. 5.1). Bootstrap gir et numerisk estimat av denne når den analytiske er utilgjengelig.
Metode for å sjekke et KI: generer mange datasett med kjent sann parameter, bygg KI-et i hvert, og tell andelen som dekker parameteren. Andelen bør ligge nær den nominelle graden (f.eks. 95 %).
For hvert simulerte datasett: lo <= param <= hi — 1 om KI-et dekker den sanne parameteren, 0 ellers. Dekningsgraden er np.mean av disse indikatorene over alle datasettene.
Et KI bygget på en eksakt pivotal (som for eksponensial) dekker den sanne parameteren nøyaktig av gangene, uansett (kobling kap. 6.2).
Wald-KI-et antar at er symmetrisk normalfordelt. For liten og skjeve data (eksponensial) underdekker det — færre enn av intervallene dekker sannheten. Nærmer seg når vokser (sentralgrensesetningen).
Velg parametrisk når du stoler på fordelingsmodellen (mer presis, utnytter modellen); velg ikke-parametrisk når du er usikker på fordelingen (mer robust mot feilspesifikasjon).
Bootstrap-SE-en regnes med np.std(theta_b, ddof=1) — divisor gir det forventningsrette standardavviksestimatet av bootstrap-fordelingen (samme grunn som i kap. 5.1).
Dette kapitlet er skrevet av Anthropics toppmodeller (Claude Opus og Claude Fable) og er foreløpig ikke manuelt gjennomgått — kvalitetskontrollen gjøres av uavhengige KI-agenter, og innmeldte feil rettes fortløpende. Funnet en feil? Meld fra, så retter vi den. Les mer om hvordan innholdet lages.
Skolesaga er en uavhengig læringsressurs og er ikke tilknyttet eller godkjent av Universitetet i Oslo. Dette er ikke offisielt studiemateriell. Les mer.