tl; dr: Ausgehend von einem unter Null generierten Datensatz habe ich Fälle mit Ersetzung neu abgetastet und einen Hypothesentest für jeden neu abgetasteten Datensatz durchgeführt. Diese Hypothesentests lehnen die Null in mehr als 5% der Fälle ab.
In der folgenden sehr einfachen Simulation generiere ich Datensätze mit und passe jedem ein einfaches OLS-Modell an. Dann generiere ich für jeden Datensatz 1000 neue Datensätze, indem ich Zeilen des ursprünglichen Datensatzes mit Ersetzung neu abtastet (ein Algorithmus, der speziell in Davison & Hinkleys klassischem Text als für die lineare Regression geeignet beschrieben wird). Für jedes davon passe ich das gleiche OLS-Modell an. Letztendlich lehnen etwa 16% der Hypothesentests in den Bootstrap-Beispielen die Null ab , während wir 5% erhalten sollten (wie in den ursprünglichen Datensätzen).
Ich vermutete, dass dies etwas mit wiederholten Beobachtungen zu tun hat, die überhöhte Assoziationen verursachen. Zum Vergleich habe ich im folgenden Code zwei andere Ansätze ausprobiert (auskommentiert). In Methode 2 repariere ich und ersetze durch neu abgetastete Residuen aus dem OLS-Modell im Originaldatensatz. In Methode 3 zeichne ich eine zufällige Teilstichprobe ohne Ersatz. Beide Alternativen funktionieren, dh ihre Hypothesentests lehnen die Null in 5% der Fälle ab.Y.
Meine Frage: Habe ich Recht, dass wiederholte Beobachtungen der Schuldige sind? Wenn ja, da dies ein Standardansatz für das Bootstrapping ist, wo genau verletzen wir dann die Standard-Bootstrap-Theorie?
Update Nr. 1: Weitere Simulationen
Ich habe versucht , ein noch einfacheres Szenario, ein Intercept-only Regressionsmodell für . Das gleiche Problem tritt auf.
# 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)
Update Nr. 2: Die Antwort
In den Kommentaren und Antworten wurden mehrere Möglichkeiten vorgeschlagen, und ich habe mehr Simulationen durchgeführt, um sie empirisch zu testen. Es stellt sich heraus, dass JWalker richtig ist, dass das Problem darin besteht, dass wir die Bootstrap-Statistiken nach der Schätzung der Originaldaten zentrieren mussten, um die korrekte Stichprobenverteilung unter . Ich denke jedoch auch, dass Whubers Kommentar zur Verletzung der parametrischen Testannahmen ebenfalls richtig ist, obwohl wir in diesem Fall tatsächlich nominelle Fehlalarme erhalten, wenn wir das Problem von JWalker beheben.
ids
ids <- unique(ids)