Calcolo del valore p usando bootstrap con R


28

Uso il pacchetto "boot" per calcolare un valore p approssimativo con avvio parziale su 2 lati ma il risultato è troppo lontano dal valore p dell'uso di t.test. Non riesco a capire cosa ho fatto di sbagliato nel mio codice R. Qualcuno può darmi un suggerimento per questo

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 

Il valore p con avvio parziale su 2 lati (pvalue) = 0,4804 ma il valore p su 2 lati di t.test è 0,04342. Entrambi i valori di p hanno una differenza di circa 11 volte. Come può succedere?


come mai b3 $ t0 ha due voci?
Xi'an

1
è un colname!
Elvis

2
Stai calcolando un valore modo errato. La documentazione afferma che è la statistica osservata, non la distribuzione nulla come suggerirebbe la notazione. È necessario elaborare una stima della dist-n di campionamento sotto il valore null. Vedi la mia risposta per maggiori informazioni. Prova un test di correzione non distorto. t 0pt0mean(abs(b3$t0) < abs(b3$t-mean(b3$t)))
AdamO,

Risposte:


31

Stai usando bootstrap per generare dati sotto la distribuzione empirica dei dati osservati. Questo può essere utile per dare un intervallo di confidenza sulla differenza tra i due mezzi:

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

Per ottenere un valore , è necessario generare permutazioni secondo l'ipotesi nulla. Questo può essere fatto ad esempio in questo modo: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 questa soluzione, la dimensione dei gruppi non è fissa, si riassegna casualmente un gruppo a ciascun individuo eseguendo l'avvio dal set di gruppi iniziale. Mi sembra legittimo, tuttavia una soluzione più classica è quella di fissare il numero di individui di ciascun gruppo, quindi permetti solo i gruppi invece di avviare il bootstrap (questo è di solito motivato dal design dell'esperimento, in cui le dimensioni del gruppo sono fissate in anticipo ):

> 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

5
Questo è tecnicamente il test di permutazione, non un valore p di bootstrap.
AdamO,

@AdamO Sono d'accordo che ciò che viene presentato in questa risposta è il test di permutazione (e la sua variante leggermente modificata); questo perché durante il ricampionamento i gruppi vengono raggruppati. Al contrario, in un test basato su bootstrap, i valori per ciascun gruppo dovrebbero essere campionati usando solo i dati per quello stesso gruppo. Ecco una risposta che spiega come farlo: stats.stackexchange.com/a/187630/28666 .
ameba dice di reintegrare Monica

@amoeba Penso che la risposta che colleghi sia anche un test di permutazione, relativo al bootstrap solo nella misura in cui comportano il ricampionamento. Va perfettamente bene segnalare, ma per la segnalazione sono due metodi che vengono utilizzati. Un bootstrap non parametrico non è tecnicamente in grado di generare dati secondo un'ipotesi nulla. Vedi la mia risposta per alcuni dei modi in cui i valori p vengono generati da una distribuzione bootstrap.
AdamO,

@AdamO Immagino sia una questione di terminologia, ma non vedo come la procedura descritta nella risposta collegata possa essere definita un test di "permutazione" perché non è permesso nulla lì: i valori ricampionati per ciascun gruppo sono generati usando i dati di quel solo gruppo.
ameba dice di reintegrare Monica

1
Elvis, penso che anche il primo pezzo di codice nella tua risposta sia il test di permutazione. Quando ricampi, metti insieme i gruppi! Questo è ciò che definisce il test di permutazione.
ameba dice di reintegrare Monica

25

La risposta di Elvis si basa su permutazioni, ma a mio avviso non chiarisce cosa c'è di sbagliato nell'approccio bootstrap originale. Consentitemi di discutere una soluzione basata esclusivamente su bootstrap.

Il problema cruciale della tua simulazione originale è che bootstrap ti fornisce sempre la VERA distribuzione della statistica test. Tuttavia, quando si calcola il valore p, è necessario confrontare il valore ottenuto della statistica test con la sua distribuzione SOTTO H0, cioè non con la distribuzione reale!

[Mettiamolo in chiaro. Ad esempio, è noto che la statistica test T del test t classico ha la distribuzione t "centrale" classica sotto H0 e una distribuzione non centrale in generale. Tuttavia, tutti hanno familiarità con il fatto che il valore osservato di T viene confrontato con la classica distribuzione t "centrale", ovvero non si cerca di ottenere la vera distribuzione t [non centrale] per fare il confronto con T.]

Il tuo valore p 0,4804 è così grande, perché il valore osservato "t0" della statistica test Media [1] -Mean [2] si trova molto vicino al centro del campione "t" avviato dal bootstrap. È naturale e in genere lo è sempre [vale a dire indipendentemente dalla validità di H0], poiché il campione "t" avviato dalla boot emula la distribuzione ATTUALE di Mean [1] -Mean [2]. Ma, come notato sopra [e anche da Elvis], ciò di cui hai veramente bisogno è la distribuzione di Mean [1] -Mean [2] UNDER H0. E 'ovvio che

1) sotto H0 la distribuzione di Mean [1] -Mean [2] sarà centrata attorno a 0,

2) la sua forma non dipende dalla validità di H0.

Questi due punti implicano che la distribuzione di Mean [1] -Mean [2] sotto H0 può essere emulata dal campione bootstpped "t" SHIFTED in modo che sia centrato attorno a 0. In R:

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

e il corrispondente valore p sarà:

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

che ti dà un valore "molto bello" di 0,0232. :-)

Consentitemi di notare che il punto "2)" menzionato sopra è chiamato "equivalenza della traduzione" della statistica del test e NON deve valere in generale! Vale a dire per alcune statistiche di test, lo spostamento della "t" avviata non fornisce una stima valida della distribuzione della statistica di test in HO! Dai un'occhiata a questa discussione e in particolare alla risposta di P. Dalgaard: http://tolstoy.newcastle.edu.au/R/e6/help/09/04/11096.html

Il tuo problema di test produce una distribuzione perfettamente simmetrica della statistica del test, ma tieni presente che ci sono alcuni problemi con l'ottenimento di valori p a DUE LATI in caso di distribuzione distorta del bootstrap della statistica del test. Ancora una volta, leggi il link sopra.

[E infine, userò il test di permutazione "puro" nella tua situazione; cioè la seconda metà della risposta di Elvis. :-)]


17

Esistono numerosi modi per calcolare gli elementi della configurazione e i valori p di bootstrap. Il problema principale è che è impossibile per il bootstrap generare dati con un'ipotesi nulla. Il test di permutazione è una valida alternativa basata sul ricampionamento a questo. Per utilizzare un bootstrap adeguato è necessario formulare alcune ipotesi sulla distribuzione campionaria della statistica test.

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

bootstrap normale

Un approccio è un normale bootstrap in cui si prende la deviazione media e standard della distribuzione bootstrap, si calcola la distribuzione campionaria sotto il valore zero spostando la distribuzione e usando i percentili normali dalla distribuzione nulla nel punto della stima nel campione bootstrap originale . Questo è un approccio ragionevole quando la distribuzione bootstrap è normale, l'ispezione visiva di solito è sufficiente qui. I risultati che utilizzano questo approccio sono in genere molto vicini alla stima dell'errore basata su sandwich, che è robusta contro l'eteroscedasticità e / o le ipotesi di varianza del campione finito. L'assunzione di una normale statistica test è una condizione più forte delle ipotesi nel prossimo test bootstrap che discuterò.

bootstrap percentile

F0*2×min(F0*(β^),1-F0*(β^))

Bootstrap studentizzato

p

Esempio di programmazione

Ad esempio, userò i citydati nel pacchetto bootstrap. Gli intervalli di confidenza bootstrap sono calcolati con questo codice:

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"))

e produrre questo output:

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

L'IC 95% per il normale bootstrap si ottiene calcolando:

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

Il valore p si ottiene così:

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

Il che concorda sul fatto che l'IC normale al 95% non include il valore del rapporto nullo di 1.

L'IC percentuale è ottenuto (con alcune differenze dovute ai metodi per i legami):

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

E il valore p per il bootstrap percentile è:

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])

Fornisce un valore di 0,035 che concorda anche con l'intervallo di confidenza in termini di esclusione di 1 dal valore. Non possiamo in generale osservare che, mentre la larghezza dell'IC percentuale è quasi larga quanto l'IC normale e che l'IC percentuale è più nullo che l'IC percentuale dovrebbe fornire valori p inferiori. Questo perché la forma della distribuzione di campionamento alla base dell'IC per il metodo percentile non è normale.


È una risposta molto interessante @AdamO, ma potresti fornire alcuni esempi? Su R, puoi utilizzare la funzione boot.cie utilizzare l'argomento "tipo" per scegliere un elemento della configurazione studentizzato (puoi anche scegliere un elemento della configurazione BCA). Tuttavia, come è possibile calcolare i valori p? Stai utilizzando la stima o la statistica del test? Avevo una domanda simile, la cui risposta sarebbe stata molto apprezzata.
Kevin Zarca,

1
+1 per una chiara spiegazione dei vantaggi del bootstrap studentizzato.
eric_kernfeld,

@KevinOunet Ho fornito due esempi di replica dei valori p dagli elementi della configurazione nel pacchetto di avvio. questo aiuta?
AdamO

1
Grazie @AdamO, questo aiuta davvero! Potresti fornire un ultimo esempio di bootstrap studentizzato?
Kevin Zarca,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.