Bootstrap ช่วงการทำนาย


29

มีเทคนิค bootstrap ใดบ้างในการคำนวณช่วงการทำนายสำหรับการทำนายจุดที่ได้รับเช่นจากการถดถอยเชิงเส้นหรือวิธีการถดถอยอื่น ๆ (เพื่อนบ้านที่ใกล้ที่สุด k-tree ที่ถดถอยเป็นต้น)

ยังไงก็เถอะฉันรู้สึกว่าบางครั้งวิธีที่เสนอให้เพียงแค่ดึงรองเท้าทำนายจุด (ดูเช่นช่วงเวลาการทำนายสำหรับการถดถอย kNN ) ไม่ได้ให้ช่วงการทำนาย แต่เป็นช่วงความมั่นใจ

ตัวอย่างใน R

# STEP 1: GENERATE DATA

set.seed(34345)

n <- 100 
x <- runif(n)
y <- 1 + 0.2*x + rnorm(n)
data <- data.frame(x, y)


# STEP 2: COMPUTE CLASSIC 95%-PREDICTION INTERVAL
fit <- lm(y ~ x)
plot(fit) # not shown but looks fine with respect to all relevant aspects

# Classic prediction interval based on standard error of forecast
predict(fit, list(x = 0.1), interval = "p")
# -0.6588168 3.093755

# Classic confidence interval based on standard error of estimation
predict(fit, list(x = 0.1), interval = "c")
# 0.893388 1.54155


# STEP 3: NOW BY BOOTSTRAP
B <- 1000
pred <- numeric(B)
for (i in 1:B) {
  boot <- sample(n, n, replace = TRUE)
  fit.b <- lm(y ~ x, data = data[boot,])
  pred[i] <- predict(fit.b, list(x = 0.1))
}
quantile(pred, c(0.025, 0.975))
# 0.8699302 1.5399179

เห็นได้ชัดว่าช่วง bootstrap พื้นฐาน 95% นั้นตรงกับช่วงความมั่นใจ 95% ไม่ใช่ช่วงการทำนาย 95% ดังนั้นคำถามของฉัน: วิธีการทำอย่างถูกต้อง?


อย่างน้อยในกรณีที่มีกำลังสองน้อยสุดสามัญคุณจะต้องมากกว่าแค่การทำนายจุด คุณต้องการใช้ข้อผิดพลาดที่เหลือโดยประมาณเพื่อสร้างช่วงเวลาการทำนายเช่นกัน
Kodiologist

1
เกี่ยวข้อง: stats.stackexchange.com/q/44860

@duplo: ขอบคุณที่ชี้ให้เห็น ความยาวที่ถูกต้องของช่วงการทำนายคลาสสิกนั้นขึ้นอยู่กับสมมติฐานเชิงบรรทัดฐานของข้อผิดพลาดโดยตรงดังนั้นหากมันเป็นแง่ดีเกินไปก็ค่อนข้างแน่นอนว่าเวอร์ชั่น bootstrapped จะมาจากที่นั่น ฉันสงสัยว่ามีวิธี bootstrap ทั่วไปทำงานในการถดถอย (ไม่จำเป็นต้อง OLS)
Michael M

1
ฉันคิดว่า \ textit {conformal อนุมาน} อาจเป็นสิ่งที่คุณต้องการซึ่งช่วยให้คุณสร้างช่วงการคาดการณ์ตามการสุ่มตัวอย่างใหม่ที่มีขอบเขตการสุ่มตัวอย่างตัวอย่างที่ถูกต้องและไม่ครอบคลุมมากเกินไป มีกระดาษที่ดีที่สามารถใช้ได้ที่เป็นarxiv.org/pdf/1604.04173.pdfซึ่งเป็นไปได้ที่จะอ่านเป็นเบื้องต้นเกี่ยวกับหัวข้อและแพคเกจ R ที่สามารถใช้ได้จากgithub.com/ryantibs/conformal
Simon Boge Brant

คำตอบ:


26

วิธีการที่ออกมาวางข้างล่างนี้เป็นหนึ่งที่อธิบายไว้ในมาตรา 6.3.3 ของเดวิดสันและคลีย์ (1997), วิธีการบูตและการประยุกต์ใช้ของพวกเขา ขอขอบคุณที่ Glen_b และแสดงความคิดเห็นของเขาที่นี่ เนื่องจากมีคำถามหลายข้อเกี่ยวกับการตรวจสอบข้ามในหัวข้อนี้ฉันคิดว่ามันคุ้มค่าที่จะเขียน

ตัวแบบการถดถอยเชิงเส้นคือ:

Yi=Xiβ+ϵi

เรามีข้อมูลที่เราใช้ในการประมาณβ เป็น: β OLSi=1,2,,Nβ

β^OLS=(XX)1XY

ทีนี้เราต้องการทำนายว่าจะเป็นอะไรสำหรับจุดข้อมูลใหม่เนื่องจากเรารู้ว่าXสำหรับมัน นี่คือปัญหาการทำนาย ขอเรียกใหม่X (ซึ่งเรารู้) X N + 1และใหม่Y (ซึ่งเราอยากที่จะคาดการณ์) Y N + 1 การคาดการณ์ตามปกติ (ถ้าเราสมมติว่าϵ iเป็น iid และไม่เกี่ยวข้องกับX ) คือ: Y p N + 1YXXXN+1YYN+1ϵiX

YN+1p=XN+1β^OLS

eN+1p=YN+1YN+1p

YN+1=YN+1p+eN+1p

Now, YN+1p we have already calculated. So, if we want to bound YN+1 in an interval, say, 90% of the time, all we need to do is estimate consistently the 5th and 95th percentiles/quantiles of eN+1p, call them e5,e95, and the prediction interval will be [YN+1p+e5,YN+1p+e95].

How to estimate the quantiles/percentiles of eN+1p? Well, we can write:

eN+1p=YN+1YN+1p=XN+1β+ϵN+1XN+1β^OLS=XN+1(ββ^OLS)+ϵN+1

The strategy will be to sample (in a bootstrap kind of way) many times from eN+1p and then calculate percentiles in the usual way. So, maybe we will sample 10,000 times from eN+1p, and then estimate the 5th and 95th percentiles as the 500th and 9,500th smallest members of the sample.

To draw on XN+1(ββ^OLS), we can bootstrap errors (cases would be fine, too, but we are assuming iid errors anyway). So, on each bootstrap replication, you draw N times with replacement from the variance-adjusted residuals (see next para) to get ϵi, then make new Yi=Xiβ^OLS+ϵi, then run OLS on the new dataset, (Y,X) to get this replication's βr. At last, this replication's draw on XN+1(ββ^OLS) is XN+1(β^OLSβr)

Given we are assuming iid ϵ, the natural way to sample from the ϵN+1 part of the equation is to use the residuals we have from the regression, {e1,e2,,eN}. Residuals have different and generally too small variances, so we will want to sample from {s1s¯,s2s¯,,sNs¯}, the variance-corrected residuals, where si=ei/(1hi) and hi is the leverage of observation i.

And, finally, the algorithm for making a 90% prediction interval for YN+1, given that X is XN+1 is:

  1. Make the prediction YN+1p=XN+1β^OLS.
  2. Make the variance-adjusted residuals, {s1s¯,s2s¯,,sNs¯}, where si=ei/(1hi).
  3. For replications r=1,2,,R:
    • Draw N times on the adjusted residuals to make bootstrap residuals {ϵ1,ϵ2,,ϵN}
    • Generate bootstrap Y=Xβ^OLS+ϵ
    • Calculate bootstrap OLS estimator for this replication, βr=(XX)1XY
    • Obtain bootstrap residuals from this replication, er=YXβr
    • Calculate bootstrap variance-adjusted residuals from this replication, ss¯
    • Draw one of the bootstrap variance-adjusted residuals from this replication, ϵN+1,r
    • Calculate this replication's draw on eN+1p, erp=XN+1(β^OLSβr)+ϵN+1,r
  4. Find 5th and 95th percentiles of eN+1p, e5,e95
  5. 90% prediction interval for YN+1 is [YN+1p+e5,YN+1p+e95].

Here is R code:

# This script gives an example of the procedure to construct a prediction interval
# for a linear regression model using a bootstrap method.  The method is the one
# described in Section 6.3.3 of Davidson and Hinckley (1997),
# _Bootstrap Methods and Their Application_.


#rm(list=ls())
set.seed(12344321)
library(MASS)
library(Hmisc)

# Generate bivariate regression data
x <- runif(n=100,min=0,max=100)
y <- 1 + x + (rexp(n=100,rate=0.25)-4)

my.reg <- lm(y~x)
summary(my.reg)

# Predict y for x=78:
y.p <- coef(my.reg)["(Intercept)"] + coef(my.reg)["x"]*78
y.p

# Create adjusted residuals
leverage <- influence(my.reg)$hat
my.s.resid <- residuals(my.reg)/sqrt(1-leverage)
my.s.resid <- my.s.resid - mean(my.s.resid)


reg <- my.reg
s <- my.s.resid

the.replication <- function(reg,s,x_Np1=0){
  # Make bootstrap residuals
  ep.star <- sample(s,size=length(reg$residuals),replace=TRUE)

  # Make bootstrap Y
  y.star <- fitted(reg)+ep.star

  # Do bootstrap regression
  x <- model.frame(reg)[,2]
  bs.reg <- lm(y.star~x)

  # Create bootstrapped adjusted residuals
  bs.lev <- influence(bs.reg)$hat
  bs.s   <- residuals(bs.reg)/sqrt(1-bs.lev)
  bs.s   <- bs.s - mean(bs.s)

  # Calculate draw on prediction error
  xb.xb <- coef(my.reg)["(Intercept)"] - coef(bs.reg)["(Intercept)"] 
  xb.xb <- xb.xb + (coef(my.reg)["x"] - coef(bs.reg)["x"])*x_Np1
  return(unname(xb.xb + sample(bs.s,size=1)))
}

# Do bootstrap with 10,000 replications
ep.draws <- replicate(n=10000,the.replication(reg=my.reg,s=my.s.resid,x_Np1=78))

# Create prediction interval
y.p+quantile(ep.draws,probs=c(0.05,0.95))

# prediction interval using normal assumption
predict(my.reg,newdata=data.frame(x=78),interval="prediction",level=0.90)


# Quick and dirty Monte Carlo to see which prediction interval is better
# That is, what are the 5th and 95th percentiles of Y_{N+1}
# 
# To do it properly, I guess we would want to do the whole procedure above
# 10,000 times and then see what percentage of the time each prediction 
# interval covered Y_{N+1}

y.np1 <- 1 + 78 + (rexp(n=10000,rate=0.25)-4)
quantile(y.np1,probs=c(0.05,0.95))

Thank you for the useful, detailed explanations. Following these lines, I think that a general technique outside OLS (tree based techniques, nearest neighbour etc.) wont be easily available, right?
Michael M

1
There is this one for random forests: stats.stackexchange.com/questions/49750/… which sounds similar.
Bill

As far as I can tell, if you abstract Xβ to f(X,θ), this technique works for any model.
shadowtalker

How do you generalise the "variance adjusted residuals" - the OLS approach relies on the leverage - is there a leverage calculation for an arbitrary f(X) estimator?
David Waterworth
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.