web-dev-qa-db-ja.com

lm()関数を使用して、one-one-out相互検証を行う簡単なコマンドはありますか?

Rのlm()関数を使用して、one-one-out相互検証を行う簡単なコマンドはありますか?

具体的には、以下のコード用の簡単なコマンドがありますか?

x <- rnorm(1000,3,2)
y <- 2*x + rnorm(1000)

pred_error_sq <- c(0)
for(i in 1:1000) {
  x_i <- x[-i]
  y_i <- y[-i]
  mdl <- lm(y_i ~ x_i) # leave i'th observation out
  y_pred <- predict(mdl, data.frame(x_i = x[i])) # predict i'th observation
  pred_error_sq <- pred_error_sq + (y[i] - y_pred)^2 # cumulate squared prediction errors
}

y_squared <- sum((y-mean(y))^2)/100 # Variation of the data

R_squared <- 1 - (pred_error_sq/y_squared) # Measure for goodness of fit
5
stollenm

別の解決策はcaretを使用することです

library(caret)

data <- data.frame(x = rnorm(1000, 3, 2), y = 2*x + rnorm(1000))

train(y ~ x, method = "lm", data = data, trControl = trainControl(method = "LOOCV"))

線形回帰

1000サンプル1予測子

前処理なしリサンプリング:リーブワンアウト相互検証サンプルサイズの概要:999、999、999、999、999、999、999、...リサンプリング結果:

RMSE Rsquared MAE
1.050268 0.940619 0.836808

調整パラメーター 'intercept'はTRUEの値で一定に保持されました

9
amarchin

N個のモデルすべてを実際に計算しないようにする統計的トリックを使用して、カスタム関数を使用できます。

loocv=function(fit){
  h=lm.influence(fit)$h
  mean((residuals(fit)/(1-h))^2)
}

これはここで説明されています: https://gerardnico.com/wiki/lang/r/cross_validation 線形モデルでのみ機能します。そして、式。

4
agenis

あなたが試すことができます cv.lm DAAGパッケージから:

cv.lm(data = DAAG::houseprices, form.lm = formula(sale.price ~ area),
              m = 3, dots = FALSE, seed = 29, plotit = c("Observed","Residual"),
              main="Small symbols show cross-validation predicted values",
              legend.pos="topleft", printit = TRUE)

Arguments

data        a data frame
form.lm,    a formula or lm call or lm object
m           the number of folds
dots        uses pch=16 for the plotting character
seed        random number generator seed
plotit      This can be one of the text strings "Observed", "Residual", or a logical value. The logical TRUE is equivalent to "Observed", while FALSE is equivalent to "" (no plot)
main        main title for graph
legend.pos      position of legend: one of "bottomright", "bottom", "bottomleft", "left", "topleft", "top", "topright", "right", "center".
printit     if TRUE, output is printed to the screen
1
Ale

cv.glm in https://www.rdocumentation.org/packages/boot/versions/1.3-20/topics/cv.glm デフォルトではLOOCVを実行し、データとlmまたはglm関数。

0
dgisser

独自のコードを作成し、インデックス変数を使用して、サンプルから外れている1つの観測をマークします。キャレットを使用して、このメソッドを最高投票数に対してテストします。キャレットはシンプルで使いやすいですが、私の残忍な方法は時間がかかりません。 (lmの代わりに、LDAを使用しましたが、大きな違いはありません)

for (index in 1:dim(df)[1]){
   # here write your lm function
}
0
pockeystar