bootstrapping ใน R ทำงานอย่างไร


22

ฉันได้ดูแพ็คเกจการบูตใน R และในขณะที่ฉันพบไพรเมอร์จำนวนมากเกี่ยวกับวิธีใช้มันฉันยังไม่พบสิ่งใดที่อธิบายสิ่งที่เกิดขึ้น "เบื้องหลัง" ตัวอย่างเช่นในตัวอย่างนี้คู่มือแสดงวิธีการใช้สัมประสิทธิ์การถดถอยมาตรฐานเป็นจุดเริ่มต้นสำหรับการถดถอย bootstrap แต่ไม่ได้อธิบายว่าขั้นตอนการ bootstrap กำลังทำอยู่เพื่อให้ได้สัมประสิทธิ์การถดถอย bootstrap ดูเหมือนว่ามีกระบวนการวนซ้ำบางอย่างที่เกิดขึ้น แต่ฉันไม่สามารถเข้าใจได้อย่างชัดเจนว่าเกิดอะไรขึ้น


3
เป็นเวลานานแล้วที่ฉันเปิดมันครั้งล่าสุดดังนั้นฉันจึงไม่รู้ว่าจะตอบคำถามของคุณหรือไม่ แต่แพคเกจการบู๊ตนั้นขึ้นอยู่กับวิธีการที่มีรายละเอียดใน Davison, AC, & Hinkley, DV (1997) วิธีการ Bootstrap และการใช้งาน Cambridge: สำนักพิมพ์มหาวิทยาลัยเคมบริดจ์ (การอ้างอิงยังอ้างถึงในไฟล์ช่วยเหลือสำหรับแพคเกจการบูตด้วย)
Gala

คำตอบ:


34

มี "รสชาติ" หรือรูปแบบต่างๆของ bootstrap (เช่นที่ไม่ใช่พารามิเตอร์, พารามิเตอร์, resampling ที่เหลืออยู่และอื่น ๆ อีกมากมาย) บูตในตัวอย่างที่เรียกว่าบูตไม่ใช่ตัวแปรหรือกรณี resampling (ดูที่นี่ , ที่นี่ , ที่นี่และที่นี่สำหรับการใช้งานในการถดถอย) ความคิดพื้นฐานคือการที่คุณรักษาตัวอย่างของคุณในขณะที่ประชากรซ้ำแล้วซ้ำอีกวาดตัวอย่างใหม่จากมันด้วยการเปลี่ยน การสังเกตเดิมทั้งหมดมีความน่าจะเป็นเท่ากับที่จะถูกดึงเข้าไปในตัวอย่างใหม่ จากนั้นคุณคำนวณและเก็บสถิติที่น่าสนใจนี่อาจเป็นค่าเฉลี่ยค่ามัธยฐานหรือสัมประสิทธิ์การถดถอยโดยใช้ตัวอย่างที่วาดใหม่ด้วยการเปลี่ยนนี้ซ้ำครั้ง ในการวนซ้ำแต่ละครั้งการสังเกตจากตัวอย่างดั้งเดิมของคุณจะถูกดึงหลายครั้งในขณะที่การสังเกตบางอย่างอาจไม่ได้วาดเลย หลังจากnซ้ำคุณมีnnnnการประมาณ bootstrap ที่เก็บไว้ของสถิติที่น่าสนใจ (เช่นถ้าและสถิติที่น่าสนใจคือค่าเฉลี่ยคุณมีการประมาณค่า bootstrapped ประมาณ 1,000 ค่า) สุดท้ายสถิติสรุปเช่นค่าเฉลี่ยมัธยฐานและค่าเบี่ยงเบนมาตรฐานของnn=1000n bootstrap- ประมาณการมีการคำนวณ

Bootstrapping มักใช้สำหรับ:

  1. การคำนวณช่วงความเชื่อมั่น (และการประเมินข้อผิดพลาดมาตรฐาน)
  2. การประมาณค่าอคติของการประมาณค่าจุด

มีหลายวิธีในการคำนวณช่วงความเชื่อมั่นตามตัวอย่าง bootstrap ( บทความนี้ให้คำอธิบายและคำแนะนำ) วิธีการหนึ่งที่ง่ายมากสำหรับการคำนวณ 95% มั่นใจในช่วงเวลาที่เป็นเพียงการคำนวณเชิงประจักษ์ 2.5th และ 97.5th เปอร์เซนต์ของกลุ่มตัวอย่างบูต (ช่วงนี้เรียกว่าบูตเปอร์เซ็นต์ช่วง;เห็นรหัสด้านล่าง) วิธีเปอร์เซ็นไทล์ช่วงเวลาแบบง่าย ๆ ไม่ค่อยถูกใช้ในทางปฏิบัติเนื่องจากมีวิธีที่ดีกว่าเช่น bootstrap (BCa) ที่ถูกแก้ไขและเร่งความเร็ว (BCa) ช่วงเวลา BCa ปรับทั้งความเอนเอียงและความเบ้ในการกระจาย bootstrap

n

ลองทำซ้ำตัวอย่างจากเว็บไซต์ แต่ใช้การวนซ้ำของเราเองที่รวมแนวคิดที่ฉันได้อธิบายไว้ข้างต้น (วาดซ้ำ ๆ ด้วยการแทนที่):

#-----------------------------------------------------------------------------
# Load packages
#-----------------------------------------------------------------------------

require(ggplot2)
require(pscl)
require(MASS)
require(boot)

#-----------------------------------------------------------------------------
# Load data
#-----------------------------------------------------------------------------

zinb <- read.csv("http://www.ats.ucla.edu/stat/data/fish.csv")
zinb <- within(zinb, {
  nofish <- factor(nofish)
  livebait <- factor(livebait)
  camper <- factor(camper)
})

#-----------------------------------------------------------------------------
# Calculate zero-inflated regression
#-----------------------------------------------------------------------------

m1 <- zeroinfl(count ~ child + camper | persons, data = zinb,
               dist = "negbin", EM = TRUE)

#-----------------------------------------------------------------------------
# Store the original regression coefficients
#-----------------------------------------------------------------------------

original.estimates <- as.vector(t(do.call(rbind, coef(summary(m1)))[, 1:2]))

#-----------------------------------------------------------------------------
# Set the number of replications
#-----------------------------------------------------------------------------

n.sim <- 2000

#-----------------------------------------------------------------------------
# Set up a matrix to store the results
#-----------------------------------------------------------------------------

store.matrix <- matrix(NA, nrow=n.sim, ncol=12)

#-----------------------------------------------------------------------------
# The loop
#-----------------------------------------------------------------------------

set.seed(123)

for(i in 1:n.sim) {

  #-----------------------------------------------------------------------------
  # Draw the observations WITH replacement
  #-----------------------------------------------------------------------------

  data.new <- zinb[sample(1:dim(zinb)[1], dim(zinb)[1], replace=TRUE),]

  #-----------------------------------------------------------------------------
  # Calculate the model with this "new" data
  #-----------------------------------------------------------------------------

  m <- zeroinfl(count ~ child + camper | persons,
                data = data.new, dist = "negbin",
                start = list(count = c(1.3711, -1.5152, 0.879),
                             zero = c(1.6028, -1.6663)))

  #-----------------------------------------------------------------------------
  # Store the results
  #-----------------------------------------------------------------------------

  store.matrix[i, ] <- as.vector(t(do.call(rbind, coef(summary(m)))[, 1:2]))

}


#-----------------------------------------------------------------------------
# Save the means, medians and SDs of the bootstrapped statistics
#-----------------------------------------------------------------------------

boot.means <- colMeans(store.matrix, na.rm=T)

boot.medians <- apply(store.matrix,2,median, na.rm=T)

boot.sds <- apply(store.matrix,2,sd, na.rm=T)

#-----------------------------------------------------------------------------
# The bootstrap bias is the difference between the mean bootstrap estimates
# and the original estimates
#-----------------------------------------------------------------------------

boot.bias <- colMeans(store.matrix, na.rm=T) - original.estimates

#-----------------------------------------------------------------------------
# Basic bootstrap CIs based on the empirical quantiles
#-----------------------------------------------------------------------------

conf.mat <- matrix(apply(store.matrix, 2 ,quantile, c(0.025, 0.975), na.rm=T),
ncol=2, byrow=TRUE)
colnames(conf.mat) <- c("95%-CI Lower", "95%-CI Upper")

และนี่คือตารางสรุปของเรา:

#-----------------------------------------------------------------------------
# Set up summary data frame
#-----------------------------------------------------------------------------

summary.frame <- data.frame(mean=boot.means, median=boot.medians,
sd=boot.sds, bias=boot.bias, "CI_lower"=conf.mat[,1], "CI_upper"=conf.mat[,2])

summary.frame

      mean  median       sd       bias CI_lower CI_upper
1   1.2998  1.3013  0.39674 -0.0712912  0.51960   2.0605
2   0.2527  0.2486  0.03208 -0.0034461  0.19898   0.3229
3  -1.5662 -1.5572  0.26220 -0.0509239 -2.12900  -1.0920
4   0.2005  0.1986  0.01949  0.0049019  0.16744   0.2418
5   0.9544  0.9252  0.48915  0.0753405  0.03493   1.9025
6   0.2702  0.2688  0.02043  0.0009583  0.23272   0.3137
7  -0.8997 -0.9082  0.22174  0.0856793 -1.30664  -0.4380
8   0.1789  0.1781  0.01667  0.0029513  0.14494   0.2140
9   2.0683  1.7719  1.59102  0.4654898  0.44150   8.0471
10  4.0209  0.8270 13.23434  3.1845710  0.58114  57.6417
11 -2.0969 -1.6717  1.56311 -0.4306844 -8.43440  -1.1156
12  3.8660  0.6435 13.27525  3.1870642  0.33631  57.6062

คำอธิบายบางอย่าง

  • ความแตกต่างระหว่างค่าเฉลี่ยของการประมาณ bootstrap และการประมาณการดั้งเดิมคือสิ่งที่เรียกว่า "อคติ" ในผลลัพธ์ของ boot
  • สิ่งที่เอาต์พุตของการbootโทร "std. error" คือค่าเบี่ยงเบนมาตรฐานของการประมาณค่าบูตสแตรป

เปรียบเทียบกับผลลัพธ์จากboot:

#-----------------------------------------------------------------------------
# Compare with boot output and confidence intervals
#-----------------------------------------------------------------------------

set.seed(10)
res <- boot(zinb, f, R = 2000, parallel = "snow", ncpus = 4)

res

Bootstrap Statistics :
       original       bias    std. error
t1*   1.3710504 -0.076735010  0.39842905
t2*   0.2561136 -0.003127401  0.03172301
t3*  -1.5152609 -0.064110745  0.26554358
t4*   0.1955916  0.005819378  0.01933571
t5*   0.8790522  0.083866901  0.49476780
t6*   0.2692734  0.001475496  0.01957823
t7*  -0.9853566  0.083186595  0.22384444
t8*   0.1759504  0.002507872  0.01648298
t9*   1.6031354  0.482973831  1.58603356
t10*  0.8365225  3.240981223 13.86307093
t11* -1.6665917 -0.453059768  1.55143344
t12*  0.6793077  3.247826469 13.90167954

perc.cis <- matrix(NA, nrow=dim(res$t)[2], ncol=2)
    for( i in 1:dim(res$t)[2] ) {
  perc.cis[i,] <- boot.ci(res, conf=0.95, type="perc", index=i)$percent[4:5] 
}
colnames(perc.cis) <- c("95%-CI Lower", "95%-CI Upper")

perc.cis 

      95%-CI Lower 95%-CI Upper
 [1,]      0.52240       2.1035
 [2,]      0.19984       0.3220
 [3,]     -2.12820      -1.1012
 [4,]      0.16754       0.2430
 [5,]      0.04817       1.9084
 [6,]      0.23401       0.3124
 [7,]     -1.29964      -0.4314
 [8,]      0.14517       0.2149
 [9,]      0.29993       8.0463
[10,]      0.57248      56.6710
[11,]     -8.64798      -1.1088
[12,]      0.33048      56.6702

#-----------------------------------------------------------------------------
# Our summary table
#-----------------------------------------------------------------------------

summary.frame

      mean  median       sd       bias CI_lower CI_upper
1   1.2998  1.3013  0.39674 -0.0712912  0.51960   2.0605
2   0.2527  0.2486  0.03208 -0.0034461  0.19898   0.3229
3  -1.5662 -1.5572  0.26220 -0.0509239 -2.12900  -1.0920
4   0.2005  0.1986  0.01949  0.0049019  0.16744   0.2418
5   0.9544  0.9252  0.48915  0.0753405  0.03493   1.9025
6   0.2702  0.2688  0.02043  0.0009583  0.23272   0.3137
7  -0.8997 -0.9082  0.22174  0.0856793 -1.30664  -0.4380
8   0.1789  0.1781  0.01667  0.0029513  0.14494   0.2140
9   2.0683  1.7719  1.59102  0.4654898  0.44150   8.0471
10  4.0209  0.8270 13.23434  3.1845710  0.58114  57.6417
11 -2.0969 -1.6717  1.56311 -0.4306844 -8.43440  -1.1156
12  3.8660  0.6435 13.27525  3.1870642  0.33631  57.6062

เปรียบเทียบคอลัมน์ "bias" และ "std. error" กับคอลัมน์ "sd" ของตารางสรุปของเราเอง ช่วงเวลาการตรวจสอบความมั่นใจ 95% ของเรานั้นคล้ายกับช่วงความเชื่อมั่นที่คำนวณโดยboot.ciใช้วิธีเปอร์ไทล์


ขอบคุณสำหรับการตอบกลับอย่างละเอียด คุณกำลังบอกว่าค่าสัมประสิทธิ์เป็นค่าเฉลี่ยของ 2000 สัมประสิทธิ์ที่สร้างขึ้นหรือไม่?
zgall1

4
เสื้อ

'แนวคิดพื้นฐานคือคุณปฏิบัติต่อกลุ่มตัวอย่างของคุณในฐานะประชากรและดึงตัวอย่างใหม่จากตัวอย่างด้วยการแทนที่' - วิธีการกำหนดขนาดของกลุ่มตัวอย่างใหม่คืออะไร
Sinusx

1
@ Sinusx ตามปกติคุณวาดตัวอย่างที่มีขนาดเท่ากันกับตัวอย่างดั้งเดิม แนวคิดที่สำคัญคือการวาดตัวอย่างด้วยการแทนที่ ดังนั้นค่าบางค่าจากตัวอย่างดั้งเดิมจะถูกวาดขึ้นหลายครั้งและค่าบางค่าอาจไม่ได้เลย
COOLSerdash

6

คุณควรมุ่งเน้นไปที่ฟังก์ชั่นที่ส่งผ่านไปbootเป็นพารามิเตอร์ "สถิติ" และสังเกตว่ามันถูกสร้างขึ้นอย่างไร

f <- function(data, i) {
  require(pscl)
  m <- zeroinfl(count ~ child + camper | persons,
    data = data[i, ], dist = "negbin",
    start = list(count = c(1.3711, -1.5152, 0.879), zero = c(1.6028, -1.6663)))
  as.vector(t(do.call(rbind, coef(summary(m)))[, 1:2]))
}

อาร์กิวเมนต์ "data" กำลังจะได้รับ data frame ทั้งหมด แต่อาร์กิวเมนต์ "i" จะได้รับตัวอย่างของดัชนีแถวที่สร้างโดย "boot" และนำมาจาก 1: NROW (data) อย่างที่คุณเห็นจากรหัสนั้น "i" จะถูกใช้เพื่อสร้างตัวอย่างนีโอที่ถูกส่งผ่านไปzeroinlและจากนั้นเฉพาะบางส่วนของผลลัพธ์ที่เลือกเท่านั้นที่จะถูกส่งคืน

ลองจินตนาการว่า "i" คือ {1,2,3,3,3,6,7,7,10} ฟังก์ชัน "[" จะคืนค่าเฉพาะแถวที่มีสำเนา 3 แถว 3 และ 2 สำเนา 7 แถวซึ่งจะเป็นพื้นฐานสำหรับหนึ่งzeroinl()คำนวณจากนั้นค่าสัมประสิทธิ์จะถูกส่งกลับไปbootเป็นผลลัพธ์จากการทำซ้ำกระบวนการนั้น จำนวนของการจำลองซ้ำถูกควบคุมโดยพารามิเตอร์ "R"

เนื่องจากมีการส่งคืนค่าสัมประสิทธิ์การถดถอยเท่านั้นstatisticในกรณีนี้bootฟังก์ชันจะคืนค่าสัมประสิทธิ์ที่สะสมเหล่านี้เป็นค่าของ "t" การเปรียบเทียบเพิ่มเติมสามารถทำได้โดยฟังก์ชั่นบูตแพคเกจอื่น ๆ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.