Berechnung des p-Wertes mit Bootstrap mit R

28

Ich benutze das "boot" -Paket, um einen ungefähren 2-seitigen Bootstrap-P-Wert zu berechnen, aber das Ergebnis ist zu weit vom P-Wert entfernt, als dass man t.test verwenden könnte. Ich kann nicht herausfinden, was ich in meinem R-Code falsch gemacht habe. Kann mir bitte jemand einen Hinweis dazu geben

time = c(14,18,11,13,18,17,21,9,16,17,14,15,
         12,12,14,13,6,18,14,16,10,7,15,10)
group=c(rep(1:2, each=12))
sleep = data.frame(time, group)

require(boot)
diff = function(d1,i){
    d = d1[i,]
    Mean= tapply(X=d$time, INDEX=d$group, mean)
    Diff = Mean[1]-Mean[2]
    Diff
}

set.seed(1234)
b3 = boot(data = sleep, statistic = diff, R = 5000, strata=sleep$group)

pvalue = mean(abs(b3$t) > abs(b3$t0))
pvalue 

Der zweiseitige Bootstrapped-p-Wert (p-Wert) = 0,4804, aber der zweiseitige p-Wert von t.test ist 0,04342. Beide p-Werte sind ca. 11-fach unterschiedlich. Wie kann das passieren?

Tu.2
quelle
Wie kommt es, dass b3 $ t0 zwei Einträge hat?
Xi'an,
1
Es ist ein Colname!
Elvis
2
Sie berechnen einen Wert falsch. Die Dokumentation besagt, dass t 0 die beobachtete Statistik ist, nicht die Nullverteilung, wie die Notation vermuten lässt. Sie müssen eine Schätzung des Stichprobenabstands n unter der Null erstellen. Siehe meine Antwort für weitere Informationen. Versuchen Sie einen unkorrigierten Bias-Test. pt0mean(abs(b3$t0) < abs(b3$t-mean(b3$t)))
AdamO

Antworten:

31

Sie verwenden Bootstrap, um Daten unter der empirischen Verteilung der beobachteten Daten zu generieren. Dies kann nützlich sein, um ein Konfidenzintervall für die Differenz zwischen den beiden Mitteln anzugeben:

> quantile(b3$t,c(0.025,0.975))
     2.5%     97.5% 
0.4166667 5.5833333 

Um einen Wert zu erhalten, müssen Sie Permutationen unter der Nullhypothese generieren. Dies kann zB so gemacht werden:p

diff2 = function(d1,i){
    d = d1; 
    d$group <- d$group[i];  # randomly re-assign groups
    Mean= tapply(X=d$time, INDEX=d$group, mean)
    Diff = Mean[1]-Mean[2]
    Diff
}

> set.seed(1234)
> b4 = boot(data = sleep, statistic = diff2, R = 5000)
> mean(abs(b4$t) > abs(b4$t0))
[1] 0.046

In dieser Lösung ist die Größe der Gruppen nicht festgelegt. Sie weisen jeder Person nach dem Zufallsprinzip eine Gruppe zu, indem Sie vom ursprünglichen Gruppensatz aus bootstrapen. Ich halte es für legitim, aber eine klassischere Lösung besteht darin, die Anzahl der Einzelpersonen jeder Gruppe zu bestimmen, sodass Sie nur die Gruppen permutieren, anstatt sie zu booten (dies wird normalerweise durch die Versuchsplanung motiviert, bei der die Gruppengrößen im Voraus festgelegt werden ):

> R <- 10000; d <- sleep
> b5 <- numeric(R); for(i in 1:R) { 
+    d$group <- sample(d$group, length(d$group)); 
+    b5[i] <- mean(d$time[d$group==1])-mean(d$time[d$group==2]); 
+ }
> mean(abs(b5) > 3)
[1] 0.0372
Elvis
quelle
5
Dies ist technisch gesehen der Permutationstest, kein Bootstrap-p-Wert.
AdamO
@AdamO Ich bin damit einverstanden, dass in dieser Antwort der Permutationstest (und seine leicht modifizierte Variante) dargestellt wird. Dies liegt daran, dass während des Resamplings die Gruppen zusammengefasst werden. Im Gegensatz dazu sollten in einem Bootstrap-basierten Test die Werte für jede Gruppe nur mit den Daten für dieselbe Gruppe abgetastet werden. Hier ist eine Antwort, die erklärt, wie es geht: stats.stackexchange.com/a/187630/28666 .
Amöbe sagt Reinstate Monica
@amoeba Ich denke, die Antwort, die Sie verlinken, ist auch ein Permutationstest, der sich nur auf das Bootstrap bezieht, sofern es sich um ein Resampling handelt. Es ist vollkommen in Ordnung zu melden, aber für das Melden werden zwei Methoden verwendet. Ein nichtparametrischer Bootstrap ist technisch nicht in der Lage, Daten unter einer Nullhypothese zu generieren. In meiner Antwort erfahren Sie, wie P-Werte aus einer Bootstrap-Distribution generiert werden.
AdamO
@AdamO Ich denke, es ist eine Frage der Terminologie, aber ich verstehe nicht, wie die in der verknüpften Antwort beschriebene Prozedur als "Permutation" -Test bezeichnet werden kann, da dort nichts permutiert wird: Aus den Daten werden für jede Gruppe neu abgetastete Werte generiert nur Gruppe.
Amöbe sagt Reinstate Monica
1
Elvis, ich denke, der erste Code in deiner Antwort ist auch der Permutationstest. Beim Resampling bündeln Sie die Gruppen! Dies definiert den Permutationstest.
Amöbe sagt Reinstate Monica
25

Die Antwort von Elvis beruht auf Permutationen, aber meiner Meinung nach macht es nicht klar, was am ursprünglichen Bootstrap-Ansatz falsch ist. Lassen Sie mich eine Lösung diskutieren, die ausschließlich auf Bootstrap basiert.

Das entscheidende Problem Ihrer ursprünglichen Simulation ist, dass Bootstrap Ihnen immer die WAHRE Verteilung der Teststatistik liefert. Bei der Berechnung des p-Wertes muss jedoch der ermittelte Wert der Teststatistik mit seiner Verteilung UNTER H0 verglichen werden, dh nicht mit der wahren Verteilung!

[Machen wir es klar. Beispielsweise ist bekannt, dass die Teststatistik T des klassischen t-Tests die klassische "zentrale" t-Verteilung unter H0 und im Allgemeinen eine nichtzentrale Verteilung aufweist. Es ist jedoch jedem bekannt, dass der beobachtete Wert von T mit der klassischen "zentralen" t-Verteilung verglichen wird, dh man versucht nicht, die wahre [nicht-zentrale] t-Verteilung zu erhalten, um den Vergleich mit T durchzuführen.

Ihr p-Wert 0,4804 ist so groß, weil der beobachtete Wert "t0" der Teststatistik Mean [1] -Mean [2] sehr nahe an der Mitte der Bootstrap-Probe "t" liegt. Es ist natürlich und normalerweise immer so [dh unabhängig von der Gültigkeit von H0], da das Bootstrap-Sample "t" die IST-Verteilung von Mean [1] -Mean [2] emuliert. Aber, wie oben [und auch von Elvis] erwähnt, brauchen Sie wirklich die Verteilung von Mean [1] -Mean [2] UNDER H0. Es ist offensichtlich das

1) unter H0 wird die Verteilung von Mittelwert [1] -Mittelwert [2] um 0 zentriert,

2) seine Form hängt nicht von der Gültigkeit von H0 ab.

Diese beiden Punkte implizieren, dass die Verteilung von Mean [1] -Mean [2] unter H0 durch das Bootstrap-Sample "t" SHIFTED emuliert werden kann, so dass es um 0 zentriert ist. In R:

b3.under.H0 <- b3$t - mean(b3$t)

und der entsprechende p-Wert ist:

mean(abs(b3.under.H0) > abs(b3$t0))

Das gibt Ihnen einen "sehr schönen" Wert von 0,0232. :-)

Lassen Sie mich feststellen, dass der oben erwähnte Punkt "2)" als "Übersetzungsäquivarianz" der Teststatistik bezeichnet wird und NICHT generell gelten muss! Dh für einige Teststatistiken liefert das Verschieben des Bootstraps "t" keine gültige Schätzung der Verteilung der Teststatistik unter HO! Schauen Sie sich diese Diskussion und insbesondere die Antwort von P. Dalgaard an: http://tolstoy.newcastle.edu.au/R/e6/help/09/04/11096.html

Ihr Testproblem führt zu einer perfekt symmetrischen Verteilung der Teststatistik. Bedenken Sie jedoch, dass es bei einer verzerrten Bootstrap-Verteilung der Teststatistik einige Probleme gibt, ZWEI-SEITIGE p-Werte zu erhalten. Lesen Sie erneut den obigen Link.

[Und schließlich würde ich den "reinen" Permutationstest in Ihrer Situation verwenden; dh die zweite Hälfte von Elvis antworten. :-)]

jan s.
quelle
17

Es gibt zahlreiche Möglichkeiten, Bootstrap-CIs und p-Werte zu berechnen. Das Hauptproblem ist, dass es für den Bootstrap unmöglich ist, Daten unter einer Nullhypothese zu generieren. Der Permutationstest ist eine realisierbare, auf Resampling basierende Alternative dazu. Um einen geeigneten Bootstrap zu verwenden, müssen Sie einige Annahmen über die Stichprobenverteilung der Teststatistik treffen.

β0=β^-β^β0=β^-β^

normaler Bootstrap

Ein Ansatz ist ein normaler Bootstrap, bei dem Sie den Mittelwert und die Standardabweichung der Bootstrap-Verteilung verwenden, um die Stichprobenverteilung unter der Null zu berechnen, indem Sie die Verteilung verschieben und die normalen Perzentile von der Nullverteilung zum Zeitpunkt der Schätzung im ursprünglichen Bootstrap-Beispiel verwenden . Dies ist ein vernünftiger Ansatz, wenn die Bootstrap-Verteilung normal ist. In der Regel ist hier eine Sichtprüfung ausreichend. Die Ergebnisse, die diesen Ansatz verwenden, liegen normalerweise sehr nahe an einer robusten oder sandwichbasierten Fehlerschätzung, die robust gegenüber Heteroskedastizität und / oder Annahmen zur Varianz endlicher Stichproben ist. Die Annahme einer normalen Teststatistik ist eine stärkere Voraussetzung für die Annahmen im nächsten Bootstrap-Test, den ich diskutieren werde.

Perzentil-Bootstrap

Ein weiterer Ansatz ist der Perzentil-Bootstrap, den die meisten von uns meiner Meinung nach in Betracht ziehen, wenn wir vom Bootstrap sprechen. Hier schätzt die Bootstrap-Verteilung der Parameter eine empirische Verteilung der Stichprobe unter der alternativen Hypothese. Diese Verteilung kann möglicherweise nicht normal sein. Ein 95% CI lässt sich leicht aus den empirischen Quantilen berechnen. Eine wichtige Annahme ist jedoch, dass eine solche Verteilung von entscheidender Bedeutung ist . Das heißt, wenn sich der zugrunde liegende Parameter ändert, wird die Form der Verteilung nur um eine Konstante verschoben, und die Skala ändert sich nicht unbedingt. Dies ist eine starke Annahme! Wenn dies zutrifft, können Sie die "Verteilung der Statistik unter der Nullhypothese" (DSNH oder erzeugenF02×Mindest(F0(β^),1-F0(β^))

Studentized Bootstrap

p

Programmierbeispiel

Als Beispiel verwende ich die cityDaten im Bootstrap-Paket. Die Bootstrap-Konfidenzintervalle werden mit diesem Code berechnet:

ratio <- function(d, w) sum(d$x * w)/sum(d$u * w)
city.boot <- boot(city, ratio, R = 999, stype = "w", sim = "ordinary")
boot.ci(city.boot, conf = c(0.90, 0.95),
        type = c("norm", "basic", "perc", "bca"))

und erzeugen diese Ausgabe:

BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
Based on 999 bootstrap replicates

CALL : 
boot.ci(boot.out = city.boot, conf = c(0.9, 0.95), type = c("norm", 
    "basic", "perc", "bca"))

Intervals : 
Level      Normal              Basic         
90%   ( 1.111,  1.837 )   ( 1.030,  1.750 )   
95%   ( 1.042,  1.906 )   ( 0.895,  1.790 )  

Level     Percentile            BCa          
90%   ( 1.291,  2.011 )   ( 1.292,  2.023 )   
95%   ( 1.251,  2.146 )   ( 1.255,  2.155 )  
Calculations and Intervals on Original Scale

Der 95% CI für den normalen Bootstrap ergibt sich aus:

with(city.boot, 2*t0 - mean(t) + qnorm(c(0.025, 0.975)) %o% sqrt(var(t)[1,1]))

Der p-Wert wird so erhalten:

> with(city.boot, pnorm(abs((2*t0 - mean(t) - 1) / sqrt(var(t)[1,1])), lower.tail=F)*2)
[1] 0.0315

Das stimmt überein, dass der 95% -Normal-CI den Nullverhältniswert von 1 nicht enthält.

Der Perzentil-CI wird erhalten (mit einigen Unterschieden aufgrund der Bindungsmethoden):

quantile(city.boot$t, c(0.025, 0.975))

Und der p-Wert für den Perzentil-Bootstrap ist:

cvs <- quantile(city.boot$t0 - city.boot$t + 1, c(0.025, 0.975))
mean(city.boot$t > cvs[1] & city.boot$t < cvs[2])

Gibt ap von 0,035 an, was auch mit dem Konfidenzintervall hinsichtlich des Ausschlusses von 1 vom Wert übereinstimmt. Wir können im Allgemeinen nicht beobachten, dass, während die Breite des Perzentil-CI fast so breit ist wie die des normalen CI und dass das Perzentil-CI weiter von der Null entfernt ist, dass das Perzentil-CI niedrigere p-Werte liefern sollte. Dies liegt daran, dass die Form der dem CI für die Perzentilmethode zugrunde liegenden Stichprobenverteilung nicht normal ist.

AdamO
quelle
Es ist eine sehr interessante Antwort @AdamO, aber könnten Sie einige Beispiele nennen? In R können Sie mithilfe der Funktion boot.ciund des Arguments "type" ein studentisiertes CI auswählen (Sie können auch ein BCA-CI auswählen). Wie können Sie jedoch p-Werte berechnen? Verwenden Sie die Schätzung oder die Teststatistik? Ich hatte eine ähnliche Frage, deren Beantwortung ich sehr schätze.
Kevin Zarca
1
+1 für eine klare Erklärung der Vorteile des studentisierten Bootstraps.
Eric_kernfeld
@ KevinOunet Ich gab zwei Beispiele für die Replikation von p-Werten von CIs im Boot-Paket. Hilft das?
AdamO
1
Danke @AdamO, das hilft ja! Könnten Sie ein letztes Beispiel für einen studentisierten Bootstrap geben?
Kevin Zarca