부트 스트랩 예측 간격


29

선형 회귀 또는 다른 회귀 방법 (k- 최근 접 이웃, 회귀 트리 등)에서 얻은 점 예측에 대한 예측 간격을 계산하는 데 사용할 수있는 부트 스트랩 기술이 있습니까?

어떻게 든 포인트 예측을 부트 스트랩하는 제안 된 방법 (예 : 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

분명히 95 % 기본 부트 스트랩 간격은 95 % 예측 간격이 아니라 95 % 신뢰 구간과 일치합니다. 그래서 내 질문 : 제대로하는 방법?


최소한 일반적인 최소 제곱의 경우 포인트 예측 이상이 필요합니다. 예측 구간을 구성하기 위해 추정 잔차 오차를 사용하려고합니다.
Kodiologist


@duplo : 이것을 지적 해 주셔서 감사합니다. 고전적인 예측 구간의 올바른 길이는 오류 항의 정규성 가정에 직접 의존하므로 너무 낙관적 인 경우 부트 스트랩 버전이 파생 된 경우에도 상당히 확실합니다. 회귀에서 작동하는 일반적인 부트 스트랩 방법이 있는지 궁금합니다 (반드시 OLS는 아님).
Michael M

1
나는 \ textit {conformal inference}가 당신이 원하는 것일 수 있다고 생각하는데, 이는 유한 한 유한 샘플 커버리지를 가지고 리 커밍 기반 예측 구간을 구성하고 너무 많이 커버하지는 않습니다. arxiv.org/pdf/1604.04173.pdf 에는 좋은 주제가 있으며 github.com/ryantibs/conformal 에서 사용할 수있는 R 패키지와 주제에 대한 소개로 읽을 수 있습니다 .
Simon Boge Brant

답변:


26

아래에 제시된 방법은 Davidson and Hinckley (1997)의 섹션 6.3.3, 부트 스트랩 방법 및 응용에 설명 된 방법 입니다. Glen_b 자신의 의견 덕분에 여기 . 이 주제에 대해 Cross Validated에 대해 몇 가지 질문이 있다고 생각하면 쓸만한 가치가 있다고 생각했습니다.

선형 회귀 모델은 다음과 같습니다.

Yi=Xiβ+ϵi

데이터는 이며 를 다음과 같이 추정하는 데 사용합니다 : i=1,2,,Nβ

β^OLS=(XX)1XY

이제 대해 알고 있다면 새로운 데이터 포인트에 대해 가 무엇인지 예측하려고 합니다. 이것이 예측 문제입니다. 새로운 (우리가 알고있는) 과 새로운 (예상하고 싶은)를 이라고하겠습니다 . 일반적인 예측 ( 가 iid이고 와 상관 관계 가 없다고 가정하는 경우 )는 다음 과 같습니다. YXXXN+1YYN+1ϵiX

YN+1p=XN+1β^OLS

이 예측으로 인한 예측 오류는 다음과 같습니다.

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

과 같은 방정식을 다시 쓸 수 있습니다.

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

이제 이 이미 계산되었습니다. 그래서, 우리가 바운드를 원하는 경우 간격으로 말하자면, 시간의 90 %가, 우리가해야 할 일은 추정 지속적이고 과 의 백분위 / 분위 , 하면 예측 구간은 .YN+1pYN+15th95theN+1pe5,e95[YN+1p+e5,YN+1p+e95]

의 분위수 / 백분위 수를 추정하는 방법은 무엇입니까? 글을 쓸 수 있습니다 : eN+1p

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

전략은 에서 여러 번 (부트 스트랩 방식으로) 샘플링 한 다음 일반적인 방식으로 백분위 수를 계산하는 것입니다. 따라서 우리는 에서 10,000 번 샘플링 한 다음 및 백분위 수를 및 가장 작은 멤버 로 추정합니다. 샘플.eN+1peN+1p5th95th500th9,500th

에 그리려면 , 우리는 오류가 (경우도 괜찮을 것 부트 스트랩 수 있지만, 우리는 IID를 가정합니다 어쨌든 오류). 따라서 각 부트 스트랩 복제 에서 분산 조정 잔차 (다음 단락 참조)를 대체하여 을 그려 를 얻은 다음 새로운 다음 새 데이터 세트 에서 OLS를 실행 하여이 복제의 을 가져옵니다 . 마지막으로 에 대한이 복제의 추첨 은XN+1(ββ^OLS)NϵiYi=Xiβ^OLS+ϵi(Y,X)βrXN+1(ββ^OLS)XN+1(β^OLSβr)

iid 이라고 가정 하면 방정식 의 부분 에서 추출하는 자연적인 방법 은 회귀에서 얻은 잔차 입니다. 잔차가 다르고 일반적으로 너무 작은 분산이 있으므로 , 분산 보정 잔차. 여기서 및 는 관측치 입니다.ϵϵN+1{e1,e2,,eN}{s1s¯,s2s¯,,sNs¯}si=ei/(1hi)hii

그리고, 마지막으로 90 %에 대한 예측 기간을 결정하는 알고리즘 주어진, 이다 이다 :YN+1XXN+1

  1. 예측을 만드십시오 .YN+1p=XN+1β^OLS
  2. 분산 조정 잔차를 로 . 여기서 .{s1s¯,s2s¯,,sNs¯}si=ei/(1hi)
  3. 복제의 경우 : r=1,2,,R
    • 조정 된 잔차에 번을 그려 부트 스트랩 잔차를 로 만듭니다. N{ϵ1,ϵ2,,ϵN}
    • 부트 스트랩Y=Xβ^OLS+ϵ
    • 이 복제에 대한 부트 스트랩 OLS 추정값을 계산하십시오. βr=(XX)1XY
    • 이 복제에서 부트 스트랩 잔차를 얻습니다.er=YXβr
    • 이 복제에서 부트 스트랩 분산 조정 잔차를 계산합니다 (ss¯
    • 이 복제에서 부트 스트랩 분산 조정 잔차 중 하나를 그립니다.ϵN+1,r
    • , 에서이 복제의 추첨을 계산하십시오. eN+1perp=XN+1(β^OLSβr)+ϵN+1,r
  4. 찾기 및 의 백분위 ,5th95theN+1pe5,e95
  5. 90 % 예측 간격 은 입니다.YN+1[YN+1p+e5,YN+1p+e95]

R코드 는 다음과 같습니다 .

# 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))

유용하고 자세한 설명을 주셔서 감사합니다. 이 라인을 따라 OLS 외부의 일반적인 기술 (트리 기반 기술, 가장 가까운 이웃 등)을 쉽게 사용할 수 없다고 생각합니다.
Michael M

1
임의의 포리스트에는 stats.stackexchange.com/questions/49750/… 이 있습니다.
Bill

내가 알 수있는 한 를 추상화하면 이 기술은 모든 모델에서 작동합니다. Xβf(X,θ)
shadowtalker

OLS 접근법이 레버리지에 의존하는 "분산 조정 잔차"를 어떻게 일반화합니까? 임의의 f (X) 추정기에 대한 레버리지 계산이 있습니까?
David Waterworth
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.