Bootstrap ist ein Verfahren, um aus Stichprobendaten auf eine Grundgesamtheit zu schließen. Bradley Efron hat es 1979 in diesem Paper vorgestellt. Bootstrap basiert auf Ziehen mit Zurücklegen aus der Stichprobe. Mit dieser Technik lässt sich der Standardfehler beliebiger Statistiken schätzen und ein Konfidenzintervall (CI) dafür bestimmen. Bootstrap ist besonders hilfreich, wenn es für das CI keine geschlossene Form gibt oder sie sehr kompliziert ist.
\n
Angenommen, wir haben eine Stichprobe mit n Elementen: X = {x1, x2, …, xn} und interessieren uns für ein CI einer Statistik T = t(X). Das Bootstrap-Vorgehen ist einfach: Wir wiederholen R-mal Folgendes: Für die i-te Wiederholung ziehen wir mit Zurücklegen n Elemente aus der vorhandenen Stichprobe (einige werden mehrfach gewählt). Diese neue Stichprobe nennen wir i-te Bootstrap-Stichprobe, Xi, und berechnen die gewünschte Statistik Ti = t(Xi).
\n
Am Ende erhalten wir R Werte unserer Statistik: T1, T2, …, TR. Das sind die Bootstrap-Realisationen von T bzw. die Bootstrap-Verteilung von T. Darauf basierend können wir ein CI für T berechnen. Es gibt mehrere Wege, der Perzentilansatz ist der einfachste.
\n
Bootstrap in der Praxis
\n
Wir nutzen erneut den bekannten iris-Datensatz. Schau dir die ersten Zeilen an:
Angenommen, wir möchten CIs für den Median von Sepal.Length und Sepal.Width sowie für Spearmans Rangkorrelationskoeffizienten zwischen beiden bestimmen. Wir verwenden das boot-Paket in R und eine Funktion namens ... boot. Dafür brauchen wir eine Funktion, die aus den resampleten Daten unsere(n) Statistik(en) berechnet. Sie sollte mindestens zwei Argumente haben: ein dataset und einen Vektor mit den indices der Elemente aus dem Datensatz, die in die Bootstrap-Stichprobe gelangt sind.
\n
Wenn wir CIs für mehrere Statistiken gleichzeitig berechnen möchten, muss unsere Funktion sie als einen einzelnen Vektor zurückgeben.
foo wählt die gewünschten Elemente (deren Nummern in indices stehen) aus data und berechnet den Korrelationskoeffizienten der ersten beiden Spalten (method='s' wählt Spearman, method='p' ergibt Pearson) sowie deren Mediane.
\n
Wir können auch zusätzliche Argumente erlauben, z. B. den Korrelations-Typ auswählbar machen:
Um das Tutorial allgemeiner zu halten, nutze ich die letztere Version von foo.
\n
Jetzt können wir die Funktion boot verwenden. Wir übergeben den Namen des Datensatzes, die gerade erstellte Funktion, die Anzahl der Wiederholungen (R) und alle zusätzlichen Argumente unserer Funktion (wie cor.type). Unten setze ich set.seed für reproduzierbare Ergebnisse.
\n
set.seed(12345)\nmyBootstrap <- boot(iris, foo, R=1000, cor.type='s')Bereitgestellt von
\n
Die Funktion boot gibt ein Objekt der Klasse ... (genau!) boot zurück. Es hat zwei interessante Elemente. $t enthält die R Werte unserer Statistik(en), die durch das Bootstrap-Verfahren erzeugt wurden (Bootstrap-Realisationen von T):
original entspricht $t0. bias ist die Differenz zwischen dem Mittelwert der Bootstrap-Realisationen (den Werten aus $t), also der Bootstrap-Schätzer für T, und dem Wert im Originaldatensatz (aus $t0).
\n
colMeans(myBootstrap$t)-myBootstrap$t0\n\n## [1] 0.002546391 -0.013350000 0.007900000Bereitgestellt von
\n
std. error ist der Standardfehler des Bootstrap-Schätzers und entspricht der Standardabweichung der Bootstrap-Realisationen.
\n
apply(myBootstrap$t,2,sd)\n\n## [1] 0.07573983 0.10295571 0.02726414Bereitgestellt von
\n
Verschiedene Arten von Bootstrap-CIs
\n
Bevor wir CIs bestimmen, lohnt sich immer ein Blick auf die Verteilung der Bootstrap-Realisationen. Wir können die Funktion plot verwenden, mit index als Angabe, auf welche der in foo berechneten Statistiken wir schauen wollen. Hier ist index=1 Spearmans Korrelationskoeffizient zwischen Kelchlänge und -breite, index=2 ist der Median der Kelchlänge und index=3 der Median der Kelchbreite.
Die Verteilung der Bootstrap-Korrelationskoeffizienten wirkt recht normalverteilt. Bestimmen wir dafür ein CI. Wir nutzen boot.ci. Standardmäßig werden 95%-CIs berechnet, das lässt sich mit dem Parameter conf ändern.
\n
boot.ci(myBootstrap, index=1)\n\n## Warning in boot.ci(myBootstrap, index = 1): bootstrap variances needed for\n## studentized intervals\n\n## BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS\n## Based on 1000 bootstrap replicates\n##\n## CALL :\n## boot.ci(boot.out = myBootstrap, index = 1)\n##\n## Intervals :\n## Level Normal Basic \n## 95% (-0.3178, -0.0209 ) (-0.3212, -0.0329 ) \n##\n## Level Percentile BCa \n## 95% (-0.3007, -0.0124 ) (-0.3005, -0.0075 ) \n## Calculations and Intervals on Original ScaleBereitgestellt von
\n
boot.ci liefert 5 Arten von Bootstrap-CIs. Eine davon, das studentisierte Intervall, ist speziell. Es benötigt eine Schätzung der Bootstrap-Varianz. Da wir diese nicht angegeben haben, gibt R die Warnung aus: bootstrap variances needed for studentized intervals. Varianzschätzungen lassen sich mit einem Bootstrap zweiter Stufe oder (einfacher) per Jackknife gewinnen. Das sprengt hier den Rahmen, daher konzentrieren wir uns auf die übrigen vier CI-Typen.
\n
Wenn wir nicht alle sehen möchten, können wir im Argument type auswählen. Mögliche Werte sind norm, basic, stud, perc, bca oder ein Vektor daraus.
\n
boot.ci(myBootstrap, index=1, type=c('basic','perc'))\n\n## BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS\n## Based on 1000 bootstrap replicates\n##\n## CALL :\n## boot.ci(boot.out = myBootstrap, type = c(\"basic\", \"perc\"), index = 1)\n##\n## Intervals :\n## Level Basic Percentile \n## 95% (-0.3212, -0.0329 ) (-0.3007, -0.0124 ) \n## Calculations and Intervals on Original ScaleBereitgestellt von
\n
Die Funktion boot.ci erzeugt ein Objekt der Klasse ... (genau!) bootci. Dessen Elemente heißen wie die im type-Argument gewählten CI-Typen. $norm ist ein Vektor mit drei Elementen: Konfidenzniveau sowie untere und obere Grenze.
\n
boot.ci(myBootstrap, index=1, type='norm')$norm\n\n## conf \n## [1,] 0.95 -0.3177714 -0.02087672Bereitgestellt von
\n
$basic, $stud, $perc und $bca sind Vektoren mit fünf Elementen und enthalten zusätzlich die zur CI-Berechnung verwendeten Perzentile (dazu gleich mehr):
Das Perzentil-CI wird generell nicht empfohlen, da es bei schiefen oder seltsam auslaufenden Verteilungen schwach performt. Das Basic-CI (auch pivotal oder empirical CI) ist robuster. Die Idee: Wir berechnen die Differenzen zwischen jeder Bootstrap-Replikation und t0 und verwenden die Perzentile dieser Verteilung. Details findest du z. B. in L. Wassermans All of Statistics
\n
Die endgültige Formel für das Basic-CI ist:
\n
(2t0 − θ1 − (1 − α)/2, 2t0 − θ(1 − α)/2)
\n
BCα-CI
\n
BCα steht für bias-corrected, accelerated. Die Formel ist nicht besonders kompliziert, aber wenig intuitiv, daher spare ich sie hier aus. Wenn du Details möchtest, lies den Artikel von Thomas J. DiCiccio und Bradley Efron.
\n
Die im Namen erwähnte Beschleunigung erfordert spezielle Perzentile der Bootstrap-Realisationen. Es kann passieren, dass dies extreme Perzentile sind, möglicherweise Ausreißer. BCα kann in solchen Fällen instabil sein.
\n
Schauen wir uns das BCα-CI für den Median der Kelchblattbreite an. Im Originaldatensatz ist dieser Median genau 3.
\n
boot.ci(myBootstrap, index=3)\n\n## Warning in boot.ci(myBootstrap, index = 3): bootstrap variances needed for\n## studentized intervals\n\n## Warning in norm.inter(t, adj.alpha): extreme order statistics used as\n## endpoints\n\n## BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS\n## Based on 1000 bootstrap replicates\n##\n## CALL :\n## boot.ci(boot.out = myBootstrap, index = 3)\n##\n## Intervals :\n## Level Normal Basic \n## 95% ( 2.939, 3.046 ) ( 2.900, 3.000 ) \n##\n## Level Percentile BCa \n## 95% ( 3.0, 3.1 ) ( 2.9, 2.9 ) \n## Calculations and Intervals on Original Scale\n## Warning : BCa Intervals used Extreme Quantiles\n## Some BCa intervals may be unstableBereitgestellt von
\n
Wir erhalten ein BCα-CI von (2.9, 2.9). Das ist ungewöhnlich, aber R hat uns gewarnt: extreme order statistics used as endpoints. Schauen wir uns an, was passiert ist:
In so einer Situation springt die „Beschleunigung\" im BCα-Verfahren leicht zu Extremwerten. Hier ist das Perzentil-CI, das die Grundlage für das BCα-CI bildet, (3, 3.1). Wenn wir es nun „nach links\" erweitern, müssen wir das 0,002-Perzentil verwenden. Die Erweiterung „nach rechts\" geht ebenfalls an die Extreme: das 0,997-Perzentil.
\n
Replikation der Ergebnisse
\n
Manchmal müssen Bootstrap-Replikationen wiederhergestellt werden. Wenn wir R nutzen können, ist das dank set.seed unproblematisch. Die Replikation in anderer Software wäre jedoch deutlich aufwendiger. Und bei großem R ist auch eine Neuberechnung in R nicht immer praktikabel (z. B. aus Zeitgründen).
\n
Wir können das Problem lösen, indem wir die Indizes der Elemente des Originaldatensatzes speichern, die jede Bootstrap-Stichprobe bilden. Genau das macht die Funktion boot.array (mit dem Argument indices=T).
Mit indices=F (Standard) bekommen wir die Antwort auf die Frage: „Wie oft kam jedes Element des Originaldatensatzes in jeder Bootstrap-Stichprobe vor?\". Zum Beispiel in der ersten Stichprobe: Das 1. Element kam einmal vor, das 2. gar nicht, das 3. einmal, das 4. zweimal usw.
Mit so einer Tabelle können wir die Bootstrap-Realisationen außerhalb von R rekonstruieren. Oder auch in R selbst, wenn wir set.seed nicht nutzen und die Rechnungen nicht erneut durchführen wollen.
\n
onceAgain<-apply(tableOfIndices,1, foo, data=iris, cor.type='s')Bereitgestellt von
Gewinne Vertrauen in die OLS-Regression, indem du ihre theoretischen Grundlagen beherrschst. Erforsche, wie du einfache Implementierungen in Excel, R und Python durchführst.
Mach dich mit Python-Datenstrukturen vertraut: Lerne mehr über Datentypen und primitive sowie nicht-primitive Datenstrukturen wie Strings, Listen, Stapel usw.
Lerne, wie du Zahlen in Python mit round(), f-Strings, format(), dem decimal-Modul, NumPy und mehr auf zwei Dezimalstellen rundest — inklusive Vergleichstabelle der Methoden.
Was ist Bootstrap?
\nBootstrap ist ein Verfahren, um aus Stichprobendaten auf eine Grundgesamtheit zu schließen. Bradley Efron hat es 1979 in diesem Paper vorgestellt. Bootstrap basiert auf Ziehen mit Zurücklegen aus der Stichprobe. Mit dieser Technik lässt sich der Standardfehler beliebiger Statistiken schätzen und ein Konfidenzintervall (CI) dafür bestimmen. Bootstrap ist besonders hilfreich, wenn es für das CI keine geschlossene Form gibt oder sie sehr kompliziert ist.
\nAngenommen, wir haben eine Stichprobe mit n Elementen: X = {x1, x2, …, xn} und interessieren uns für ein CI einer Statistik T = t(X). Das Bootstrap-Vorgehen ist einfach: Wir wiederholen R-mal Folgendes: Für die i-te Wiederholung ziehen wir mit Zurücklegen n Elemente aus der vorhandenen Stichprobe (einige werden mehrfach gewählt). Diese neue Stichprobe nennen wir i-te Bootstrap-Stichprobe, Xi, und berechnen die gewünschte Statistik Ti = t(Xi).
\nAm Ende erhalten wir R Werte unserer Statistik: T1, T2, …, TR. Das sind die Bootstrap-Realisationen von T bzw. die Bootstrap-Verteilung von T. Darauf basierend können wir ein CI für T berechnen. Es gibt mehrere Wege, der Perzentilansatz ist der einfachste.
\nBootstrap in der Praxis
\nWir nutzen erneut den bekannten
\n\niris-Datensatz. Schau dir die ersten Zeilen an:Angenommen, wir möchten CIs für den Median von
\nSepal.LengthundSepal.Widthsowie für Spearmans Rangkorrelationskoeffizienten zwischen beiden bestimmen. Wir verwenden dasboot-Paket inRund eine Funktion namens ...boot. Dafür brauchen wir eine Funktion, die aus den resampleten Daten unsere(n) Statistik(en) berechnet. Sie sollte mindestens zwei Argumente haben: eindatasetund einen Vektor mit denindicesder Elemente aus dem Datensatz, die in die Bootstrap-Stichprobe gelangt sind.Wenn wir CIs für mehrere Statistiken gleichzeitig berechnen möchten, muss unsere Funktion sie als einen einzelnen Vektor zurückgeben.
\nFür unser Beispiel könnte das so aussehen:
\n\n
\nfoowählt die gewünschten Elemente (deren Nummern inindicesstehen) ausdataund berechnet den Korrelationskoeffizienten der ersten beiden Spalten (method='s'wählt Spearman,method='p'ergibt Pearson) sowie deren Mediane.Wir können auch zusätzliche Argumente erlauben, z. B. den Korrelations-Typ auswählbar machen:
\n\nUm das Tutorial allgemeiner zu halten, nutze ich die letztere Version von
\nfoo.Jetzt können wir die Funktion
\n\nbootverwenden. Wir übergeben den Namen des Datensatzes, die gerade erstellte Funktion, die Anzahl der Wiederholungen (R) und alle zusätzlichen Argumente unserer Funktion (wiecor.type). Unten setze ichset.seedfür reproduzierbare Ergebnisse.Die Funktion
\n\nbootgibt ein Objekt der Klasse ... (genau!)bootzurück. Es hat zwei interessante Elemente.$tenthält die R Werte unserer Statistik(en), die durch das Bootstrap-Verfahren erzeugt wurden (Bootstrap-Realisationen von T):
\n\n$t0enthält die Werte unserer Statistik(en) im ursprünglichen, vollständigen Datensatz:Wenn wir das
\n\nboot-Objekt ausgeben, erhalten wir weitere Informationen:
\n\noriginalentspricht$t0.biasist die Differenz zwischen dem Mittelwert der Bootstrap-Realisationen (den Werten aus$t), also der Bootstrap-Schätzer für T, und dem Wert im Originaldatensatz (aus$t0).
\n\nstd. errorist der Standardfehler des Bootstrap-Schätzers und entspricht der Standardabweichung der Bootstrap-Realisationen.Verschiedene Arten von Bootstrap-CIs
\nBevor wir CIs bestimmen, lohnt sich immer ein Blick auf die Verteilung der Bootstrap-Realisationen. Wir können die Funktion
\n\nplotverwenden, mitindexals Angabe, auf welche der infooberechneten Statistiken wir schauen wollen. Hier istindex=1Spearmans Korrelationskoeffizient zwischen Kelchlänge und -breite,index=2ist der Median der Kelchlänge undindex=3der Median der Kelchbreite.Die Verteilung der Bootstrap-Korrelationskoeffizienten wirkt recht normalverteilt. Bestimmen wir dafür ein CI. Wir nutzen
\n\nboot.ci. Standardmäßig werden 95%-CIs berechnet, das lässt sich mit dem Parameterconfändern.
\nboot.ciliefert 5 Arten von Bootstrap-CIs. Eine davon, das studentisierte Intervall, ist speziell. Es benötigt eine Schätzung der Bootstrap-Varianz. Da wir diese nicht angegeben haben, gibtRdie Warnung aus:bootstrap variances needed for studentized intervals. Varianzschätzungen lassen sich mit einem Bootstrap zweiter Stufe oder (einfacher) per Jackknife gewinnen. Das sprengt hier den Rahmen, daher konzentrieren wir uns auf die übrigen vier CI-Typen.Wenn wir nicht alle sehen möchten, können wir im Argument
\n\ntypeauswählen. Mögliche Werte sindnorm,basic,stud,perc,bcaoder ein Vektor daraus.Die Funktion
\n\nboot.cierzeugt ein Objekt der Klasse ... (genau!)bootci. Dessen Elemente heißen wie die imtype-Argument gewählten CI-Typen.$normist ein Vektor mit drei Elementen: Konfidenzniveau sowie untere und obere Grenze.
\n\n$basic,$stud,$percund$bcasind Vektoren mit fünf Elementen und enthalten zusätzlich die zur CI-Berechnung verwendeten Perzentile (dazu gleich mehr):Ein bisschen Notation (sorry!)
\nUm die verschiedenen CI-Typen einzuordnen, brauchen wir etwas Notation. Sei also:
\n\n- t⋆ der Bootstrap-Schätzer (Mittelwert der Bootstrap-Realisationen),
\n- t0 der Wert unserer Statistik im Originaldatensatz,
\n- se⋆ der Standardfehler des Bootstrap-Schätzers,
\n- b die Verzerrung (Bias) des Bootstrap-Schätzers, b = t⋆ − t0,
\n- α das Konfidenzniveau, typischerweise α = 0.95,
\n- zα das $1-\\frac \\alpha 2$-Quantil der Standardnormalverteilung,
\n- θα das α-Perzentil der Verteilung der Bootstrap-Realisationen.
\n
\nPerzentil-CI
\nMit dieser Notation lautet das Perzentil-CI:
\n
\nDas heißt: Wir nehmen einfach die entsprechenden Perzentile. Nicht mehr, nicht weniger.
Normal-CI
\nEin klassisches Wald-CI wäre:
\nim Bootstrap-Fall sollten wir jedoch den Bias korrigieren. Es wird zu:
\n$$ t_0 - b \\pm z_\\alpha \\cdot se^\\star \\\\ 2t_0 - t^\\star \\pm z_\\alpha \\cdot se^\\star$$
\nBasic-CI
\nDas Perzentil-CI wird generell nicht empfohlen, da es bei schiefen oder seltsam auslaufenden Verteilungen schwach performt. Das Basic-CI (auch pivotal oder empirical CI) ist robuster. Die Idee: Wir berechnen die Differenzen zwischen jeder Bootstrap-Replikation und t0 und verwenden die Perzentile dieser Verteilung. Details findest du z. B. in L. Wassermans All of Statistics
\nDie endgültige Formel für das Basic-CI ist:
\nBCα-CI
\nBCα steht für bias-corrected, accelerated. Die Formel ist nicht besonders kompliziert, aber wenig intuitiv, daher spare ich sie hier aus. Wenn du Details möchtest, lies den Artikel von Thomas J. DiCiccio und Bradley Efron.
\nDie im Namen erwähnte Beschleunigung erfordert spezielle Perzentile der Bootstrap-Realisationen. Es kann passieren, dass dies extreme Perzentile sind, möglicherweise Ausreißer. BCα kann in solchen Fällen instabil sein.
\nSchauen wir uns das BCα-CI für den Median der Kelchblattbreite an. Im Originaldatensatz ist dieser Median genau 3.
\n\nWir erhalten ein BCα-CI von (2.9, 2.9). Das ist ungewöhnlich, aber
\n\nRhat uns gewarnt:extreme order statistics used as endpoints. Schauen wir uns an, was passiert ist:Die Verteilung der Bootstrap-Realisationen ist ungewöhnlich. Die große Mehrheit (über 90%) sind 3er-Werte.
\n\nIn so einer Situation springt die „Beschleunigung\" im BCα-Verfahren leicht zu Extremwerten. Hier ist das Perzentil-CI, das die Grundlage für das BCα-CI bildet, (3, 3.1). Wenn wir es nun „nach links\" erweitern, müssen wir das 0,002-Perzentil verwenden. Die Erweiterung „nach rechts\" geht ebenfalls an die Extreme: das 0,997-Perzentil.
\nReplikation der Ergebnisse
\nManchmal müssen Bootstrap-Replikationen wiederhergestellt werden. Wenn wir
\nRnutzen können, ist das dankset.seedunproblematisch. Die Replikation in anderer Software wäre jedoch deutlich aufwendiger. Und bei großem R ist auch eine Neuberechnung inRnicht immer praktikabel (z. B. aus Zeitgründen).Wir können das Problem lösen, indem wir die Indizes der Elemente des Originaldatensatzes speichern, die jede Bootstrap-Stichprobe bilden. Genau das macht die Funktion
\n\nboot.array(mit dem Argumentindices=T).Jede Zeile entspricht einer Bootstrap-Stichprobe. Unsere erste Stichprobe enthält beispielsweise folgende Elemente:
\n\nMit
\n\nindices=F(Standard) bekommen wir die Antwort auf die Frage: „Wie oft kam jedes Element des Originaldatensatzes in jeder Bootstrap-Stichprobe vor?\". Zum Beispiel in der ersten Stichprobe: Das 1. Element kam einmal vor, das 2. gar nicht, das 3. einmal, das 4. zweimal usw.Mit so einer Tabelle können wir die Bootstrap-Realisationen außerhalb von
\n\nRrekonstruieren. Oder auch inRselbst, wenn wirset.seednicht nutzen und die Rechnungen nicht erneut durchführen wollen.Prüfen wir, ob die Ergebnisse identisch sind:
\n\nJa, sind sie!
\nWenn du mehr über Machine Learning in R lernen möchtest, sieh dir den DataCamp-Kurs Machine Learning Toolbox an und lies das Tutorial Machine Learning in R für Einsteiger.