web-dev-qa-db-ja.com

predict.lm()はどのように信頼区間と予測区間を計算しますか?

私は回帰を実行しました:

CopierDataRegression <- lm(V1~V2, data=CopierData1)

私の仕事は

  • V2=6が与えられた平均応答の90%信頼区間および
  • V2=6の場合、90%予測間隔

次のコードを使用しました。

X6 <- data.frame(V2=6)
predict(CopierDataRegression, X6, se.fit=TRUE, interval="confidence", level=0.90)
predict(CopierDataRegression, X6, se.fit=TRUE, interval="prediction", level=0.90)

そして(87.3, 91.9)(74.5, 104.8)を取得しましたが、これらはPIを広くする必要があるため正しいようです。

両方の出力には、同じse.fit = 1.39も含まれていました。 この標準エラーが何であるかわかりません。 PIとCIの標準誤差を大きくすべきではありませんか? Rでこれら2つの異なる標準エラーを見つけるにはどうすればよいですか?enter image description here


データ:

CopierData1 <- structure(list(V1 = c(20L, 60L, 46L, 41L, 12L, 137L, 68L, 89L, 
          4L, 32L, 144L, 156L, 93L, 36L, 72L, 100L, 105L, 131L, 127L, 57L, 
          66L, 101L, 109L, 74L, 134L, 112L, 18L, 73L, 111L, 96L, 123L, 
          90L, 20L, 28L, 3L, 57L, 86L, 132L, 112L, 27L, 131L, 34L, 27L, 
          61L, 77L), V2 = c(2L, 4L, 3L, 2L, 1L, 10L, 5L, 5L, 1L, 2L, 9L, 
          10L, 6L, 3L, 4L, 8L, 7L, 8L, 10L, 4L, 5L, 7L, 7L, 5L, 9L, 7L, 
          2L, 5L, 7L, 6L, 8L, 5L, 2L, 2L, 1L, 4L, 5L, 9L, 7L, 1L, 9L, 2L, 
          2L, 4L, 5L)), .Names = c("V1", "V2"),
          class = "data.frame", row.names = c(NA, -45L))
10
Mitty

intervalおよびlevel引数を指定すると、_predict.lm_は信頼区間(CI)または予測区間(PI)を返すことができます。この回答は、これらの引数を設定せずにCIとPIを取得する方法を示しています。 2つの方法があります。

  • _predict.lm_からの中間段階の結果を使用します;
  • すべてをゼロから実行します。

両方の方法で作業する方法を知っていると、予測手順を完全に理解できます。

_type = "response"_の_predict.lm_(デフォルト)の場合のみを対象とすることに注意してください。 _type = "terms"_の説明は、この回答の範囲外です。


セットアップ

ここにコードを集めて、他の読者がコピー、貼り付け、実行できるようにします。また、変数名を変更して、より明確な意味を持つようにします。さらに、newdatを展開して複数の行を含め、計算が「ベクトル化」されていることを示します。

_dat <- structure(list(V1 = c(20L, 60L, 46L, 41L, 12L, 137L, 68L, 89L, 
          4L, 32L, 144L, 156L, 93L, 36L, 72L, 100L, 105L, 131L, 127L, 57L, 
          66L, 101L, 109L, 74L, 134L, 112L, 18L, 73L, 111L, 96L, 123L, 
          90L, 20L, 28L, 3L, 57L, 86L, 132L, 112L, 27L, 131L, 34L, 27L, 
          61L, 77L), V2 = c(2L, 4L, 3L, 2L, 1L, 10L, 5L, 5L, 1L, 2L, 9L, 
          10L, 6L, 3L, 4L, 8L, 7L, 8L, 10L, 4L, 5L, 7L, 7L, 5L, 9L, 7L, 
          2L, 5L, 7L, 6L, 8L, 5L, 2L, 2L, 1L, 4L, 5L, 9L, 7L, 1L, 9L, 2L, 
          2L, 4L, 5L)), .Names = c("V1", "V2"),
          class = "data.frame", row.names = c(NA, -45L))

lmObject <- lm(V1 ~ V2, data = dat)

newdat <- data.frame(V2 = c(6, 7))
_

以下は_predict.lm_の出力であり、後で手動計算と比較します。

_predict(lmObject, newdat, se.fit = TRUE, interval = "confidence", level = 0.90)
#$fit
#        fit       lwr      upr
#1  89.63133  87.28387  91.9788
#2 104.66658 101.95686 107.3763
#
#$se.fit
#       1        2 
#1.396411 1.611900 
#
#$df
#[1] 43
#
#$residual.scale
#[1] 8.913508

predict(lmObject, newdat, se.fit = TRUE, interval = "prediction", level = 0.90)
#$fit
#        fit      lwr      upr
#1  89.63133 74.46433 104.7983
#2 104.66658 89.43930 119.8939
#
#$se.fit
#       1        2 
#1.396411 1.611900 
#
#$df
#[1] 43
#
#$residual.scale
#[1] 8.913508
_

_predict.lm_の中間段階の結果を使用する

_## use `se.fit = TRUE`
z <- predict(lmObject, newdat, se.fit = TRUE)
#$fit
#        1         2 
# 89.63133 104.66658 
#
#$se.fit
#       1        2 
#1.396411 1.611900 
#
#$df
#[1] 43
#
#$residual.scale
#[1] 8.913508
_

_se.fit_とは何ですか?

_z$se.fit_は、予測平均_z$fit_の標準誤差であり、_z$fit_のCIを構築するために使用されます。また、自由度_z$df_のt分布の分位数が必要です。

_alpha <- 0.90  ## 90%
Qt <- c(-1, 1) * qt((1 - alpha) / 2, z$df, lower.tail = FALSE)
#[1] -1.681071  1.681071

## 90% confidence interval
CI <- z$fit + outer(z$se.fit, Qt)
colnames(CI) <- c("lwr", "upr")
CI
#        lwr      upr
#1  87.28387  91.9788
#2 101.95686 107.3763
_

これはpredict.lm(, interval = "confidence")と一致することがわかります。

PIの標準エラーとは何ですか?

PIは残差分散を考慮しているため、CIよりも広くなっています。

_variance_of_PI = variance_of_CI + variance_of_residual
_

これはポイントごとに定義されることに注意してください。 (例のように)重みのない線形回帰の場合、残差分散はどこでも等しく(homoscedasticityと呼ばれます)、それは_z$residual.scale ^ 2_です。したがって、PIの標準誤差は

_se.PI <- sqrt(z$se.fit ^ 2 + z$residual.scale ^ 2)
#       1        2 
#9.022228 9.058082 
_

pIは次のように構築されます

_PI <- z$fit + outer(se.PI, Qt)
colnames(PI) <- c("lwr", "upr")
PI
#       lwr      upr
#1 74.46433 104.7983
#2 89.43930 119.8939
_

これはpredict.lm(, interval = "prediction")と一致することがわかります。

備考

_z$residual.scale ^ 2_が重み付けされるように、残差分散がどこでも等しくない重み線形回帰がある場合、事態はより複雑になります。近似値のPIを構築する方が簡単です(つまり、_type = "prediction"_を_predict.lm_で使用する場合、newdataを設定しないでください。これは、重みがわかっているためです(指定する必要があります) weightを使用する場合はlm引数を使用します)。アウトオブサンプル予測(つまり、newdataを_predict.lm_に渡す)の場合、_predict.lm_は、残差分散の重み付け方法を指示することを期待します。引数_pred.var_または_predict.lm_のweightsを使用する必要があります。そうでない場合は、PIを構築するための情報が不十分であると訴える_predict.lm_から警告が表示されます。以下は_?predict.lm_から引用されています。

_ The prediction intervals are for a single observation at each case
 in ‘newdata’ (or by default, the data used for the fit) with error
 variance(s) ‘pred.var’.  This can be a multiple of ‘res.var’, the
 estimated value of sigma^2: the default is to assume that future
 observations have the same error variance as those used for
 fitting.  If ‘weights’ is supplied, the inverse of this is used as
 a scale factor.  For a weighted fit, if the prediction is for the
 original data frame, ‘weights’ defaults to the weights used for
 the model fit, with a warning since it might not be the intended
 result.  If the fit was weighted and ‘newdata’ is given, the
 default is to assume constant prediction variance, with a warning.
_

CIの構築は、回帰のタイプの影響を受けないことに注意してください。


すべてをゼロから行う

基本的に、fitdf、_se.fit_、z、_residual.scale_を取得する方法を知りたいです。

予測平均は、行列ベクトル乗算_Xp %*% b_によって計算できます。ここで、Xpは線形予測行列であり、bは回帰係数ベクトルです。

_Xp <- model.matrix(delete.response(terms(lmObject)), newdat)
b <- coef(lmObject)
yh <- c(Xp %*% b)  ## c() reshape the single-column matrix to a vector
#[1]  89.63133 104.66658
_

そして、これは_z$fit_と一致することがわかります。 yhの分散共分散はXp %*% V %*% t(Xp)です。ここで、Vbの分散共分散行列で、

_V <- vcov(lmObject)  ## use `vcov` function in R
#             (Intercept)         V2
# (Intercept)    7.862086 -1.1927966
# V2            -1.192797  0.2333733
_

yhの完全な分散共分散行列は、点ごとのCIまたはPIを計算するために必要ではありません。メインの対角線のみが必要です。したがって、diag(Xp %*% V %*% t(Xp))を実行する代わりに、

_var.fit <- rowSums((Xp %*% V) * Xp)  ## point-wise variance for predicted mean
#       1        2 
#1.949963 2.598222 

sqrt(var.fit)  ## this agrees with `z$se.fit`
#       1        2 
#1.396411 1.611900 
_

残りの自由度は、近似モデルで簡単に利用できます。

_dof <- df.residual(lmObject)
#[1] 43
_

最後に、残差分散を計算するには、ピアソン推定器を使用します。

_sig2 <- c(crossprod(lmObject$residuals)) / dof
# [1] 79.45063

sqrt(sig2)  ## this agrees with `z$residual.scale`
#[1] 8.913508
_

備考

重み付き回帰の場合、_sig2_は次のように計算されることに注意してください。

_sig2 <- c(crossprod(sqrt(lmObject$weights) * lmObject$residuals)) / dof
_

付録:_predict.lm_を模倣する自己記述関数

「ゼロからすべてを行う」のコードは、このQ&Aの関数_lm_predict_に整理されています。 lmを含む線形モデル:予測の合計の予測分散を取得する方法値

34
李哲源

予測間隔の標準誤差をすばやく抽出する方法があるかどうかはわかりませんが、SEの間隔はいつでもバックソルブできます(非常にエレガントなアプローチではありませんが)。

m <- lm(V1 ~ V2, data = d)                                                                                                                                                                                                                

newdat <- data.frame(V2=6)                                                                                                                                                                                                                
tcrit <- qt(0.95, m$df.residual)                                                                                                                                                                                                          

a <- predict(m, newdat, interval="confidence", level=0.90)                                                                                                                                                                                
cat("CI SE", (a[1, "upr"] - a[1, "fit"]) / tcrit, "\n")                                                                                                                                                                                   

b <- predict(m, newdat, interval="prediction", level=0.90)                                                                                                                                                                                
cat("PI SE", (b[1, "upr"] - b[1, "fit"]) / tcrit, "\n") 

CI SEはse.fitと同じ値であることに注意してください。

2
MAB