tl; dr: เริ่มต้นด้วยชุดข้อมูลที่สร้างขึ้นภายใต้ null ฉัน resampled กรณีที่มีการเปลี่ยนและดำเนินการทดสอบสมมติฐานในแต่ละชุดข้อมูล resampled การทดสอบสมมติฐานเหล่านี้ปฏิเสธค่าว่างมากกว่า 5% ของเวลา
ในด้านล่างการจำลองที่ง่ายมากฉันสร้างชุดข้อมูลด้วยและฉันพอดีกับ OLS แบบง่าย ๆ จากนั้นสำหรับแต่ละชุดข้อมูลฉันสร้างชุดข้อมูลใหม่ 1,000 ชุดโดยการสุ่มแถวใหม่ของชุดข้อมูลเดิมพร้อมการแทนที่ (อัลกอริทึมที่อธิบายไว้โดยเฉพาะในข้อความคลาสสิกของ Davison & Hinkley ว่าเหมาะสมสำหรับการถดถอยเชิงเส้น) สำหรับแต่ละอันฉันพอดีกับ OLS รุ่นเดียวกัน ในที่สุดประมาณ 16% ของการทดสอบสมมติฐานในตัวอย่าง bootstrap ปฏิเสธ nullในขณะที่เราควรได้รับ 5% (ตามที่เราทำในชุดข้อมูลดั้งเดิม)
ฉันสงสัยว่ามันมีบางอย่างเกี่ยวกับการสังเกตซ้ำ ๆ ทำให้เกิดความสัมพันธ์ที่สูงเกินจริงดังนั้นในการเปรียบเทียบฉันลองวิธีอื่นสองวิธีในรหัสด้านล่าง (แสดงความคิดเห็น) ในวิธีที่ 2 ฉันแก้ไขจากนั้นแทนที่ด้วยส่วนที่เหลือ resampled จากโมเดล OLS ในชุดข้อมูลดั้งเดิม ในวิธีที่ 3 ฉันวาดตัวอย่างย่อยแบบสุ่มโดยไม่มีการแทนที่ ทั้งสองตัวเลือกเหล่านี้ทำงานกล่าวคือการทดสอบสมมติฐานของพวกเขาปฏิเสธโมฆะ 5% ของเวลา
คำถามของฉัน: ฉันถูกไหมที่การสังเกตซ้ำ ๆ เป็นผู้ร้าย? ถ้าเป็นเช่นนั้นนี่เป็นวิธีมาตรฐานในการบูตสแตรปเราจะละเมิดทฤษฎีบูตสแตรปมาตรฐานได้อย่างไร
อัปเดต # 1: จำลองเพิ่มเติม
ฉันพยายามสถานการณ์ได้ง่ายแบบจำลองการถดถอยตัดเท่านั้นสำหรับYปัญหาเดียวกันเกิดขึ้น
# 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)
อัปเดต # 2: คำตอบ
มีการเสนอความเป็นไปได้หลายอย่างในการแสดงความคิดเห็นและคำตอบและฉันทำการจำลองเพิ่มเติมเพื่อทดสอบเชิงประจักษ์ แต่กลับกลายเป็นว่า JWalker ถูกต้องว่าปัญหาอยู่ที่เราต้องการไปยังศูนย์สถิติบูตโดยประมาณการข้อมูลเดิมในการสั่งซื้อที่จะได้รับการกระจายการสุ่มตัวอย่างที่ถูกต้องภายใต้H_0อย่างไรก็ตามฉันคิดว่าความคิดเห็นของ whuber เกี่ยวกับการฝ่าฝืนสมมติฐานการทดสอบพารามิเตอร์นั้นถูกต้องเช่นกัน แต่ในกรณีนี้เราได้รับผลบวกเล็กน้อยจริง ๆ เมื่อเราแก้ไขปัญหาของ JWalker
ids
ids <- unique(ids)