tl; dr: comenzando con un conjunto de datos generado bajo nulo, volví a muestrear casos con reemplazo y realicé una prueba de hipótesis en cada conjunto de datos remuestreado. Estas pruebas de hipótesis rechazan el nulo más del 5% del tiempo.
En la siguiente simulación, muy simple, genero conjuntos de datos con , y un modelo OLS simple para cada uno. Luego, para cada conjunto de datos, genero 1000 nuevos conjuntos de datos al volver a muestrear filas del conjunto de datos original con reemplazo (un algoritmo específicamente descrito en el texto clásico de Davison & Hinkley como apropiado para la regresión lineal). Para cada uno de ellos, me ajusto al mismo modelo OLS. En última instancia, aproximadamente el 16% de las pruebas de hipótesis dentro de las muestras de bootstrap rechazan el valor nulo , mientras que deberíamos obtener el 5% (como lo hacemos en los conjuntos de datos originales).
Sospeché que tiene algo que ver con las observaciones repetidas que causan asociaciones infladas, por lo que, para comparar, probé otros dos enfoques en el siguiente código (comentado). En el Método 2, reparo , luego reemplazo con residuos muestreados del modelo OLS en el conjunto de datos original. En el Método 3, dibujo una submuestra aleatoria sin reemplazo. Ambas alternativas funcionan, es decir, sus pruebas de hipótesis rechazan el nulo el 5% del tiempo.Y
Mi pregunta: ¿tengo razón en que las repetidas observaciones son las culpables? Si es así, dado que este es un enfoque estándar para el arranque, ¿ dónde estamos violando exactamente la teoría del arranque estándar?
Actualización n. ° 1: más simulaciones
Probé un escenario aún más simple, un modelo de regresión de sólo intersección de . El mismo problema ocurre.
# note: simulation takes 5-10 min on my laptop; can reduce boot.reps
# and n.sims.run if wanted
# set the number of cores: can change this to match your machine
library(doParallel)
registerDoParallel(cores=8)
boot.reps = 1000
n.sims.run = 1000
for ( j in 1:n.sims.run ) {
# make initial dataset from which to bootstrap
# generate under null
d = data.frame( X1 = rnorm( n = 1000 ), Y1 = rnorm( n = 1000 ) )
# fit OLS to original data
mod.orig = lm( Y1 ~ X1, data = d )
bhat = coef( mod.orig )[["X1"]]
se = coef(summary(mod.orig))["X1",2]
rej = coef(summary(mod.orig))["X1",4] < 0.05
# run all bootstrap iterates
parallel.time = system.time( {
r = foreach( icount( boot.reps ), .combine=rbind ) %dopar% {
# Algorithm 6.2: Resample entire cases - FAILS
# residuals of this model are repeated, so not normal?
ids = sample( 1:nrow(d), replace=TRUE )
b = d[ ids, ]
# # Method 2: Resample just the residuals themselves - WORKS
# b = data.frame( X1 = d$X1, Y1 = sample(mod.orig$residuals, replace = TRUE) )
# # Method 3: Subsampling without replacement - WORKS
# ids = sample( 1:nrow(d), size = 500, replace=FALSE )
# b = d[ ids, ]
# save stats from bootstrap sample
mod = lm( Y1 ~ X1, data = b )
data.frame( bhat = coef( mod )[["X1"]],
se = coef(summary(mod))["X1",2],
rej = coef(summary(mod))["X1",4] < 0.05 )
}
} )[3]
###### Results for This Simulation Rep #####
r = data.frame(r)
names(r) = c( "bhat.bt", "se.bt", "rej.bt" )
# return results of each bootstrap iterate
new.rows = data.frame( bt.iterate = 1:boot.reps,
bhat.bt = r$bhat.bt,
se.bt = r$se.bt,
rej.bt = r$rej.bt )
# along with results from original sample
new.rows$bhat = bhat
new.rows$se = se
new.rows$rej = rej
# add row to output file
if ( j == 1 ) res = new.rows
else res = rbind( res, new.rows )
# res should have boot.reps rows per "j" in the for-loop
# simulation rep counter
d$sim.rep = j
} # end loop over j simulation reps
##### Analyze results #####
# dataset with only one row per simulation
s = res[ res$bt.iterate == 1, ]
# prob of rejecting within each resample
# should be 0.05
mean(res$rej.bt); mean(s$rej)
Actualización n. ° 2: la respuesta
Se propusieron varias posibilidades en los comentarios y respuestas, e hice más simulaciones para probarlas empíricamente. Resulta que JWalker tiene razón en que el problema es que necesitábamos centrar las estadísticas de bootstrap por la estimación de los datos originales para obtener la distribución de muestreo correcta en . Sin embargo, también creo que el comentario de Whuber sobre la violación de los supuestos de la prueba paramétrica también es correcto, aunque en este caso en realidad obtenemos falsos positivos nominales cuando solucionamos el problema de JWalker.
ids
ids <- unique(ids)