井出草平の研究ノート

LOOCVを用いたLassoにおける変数選択の安定性[R]

一つ抜き交差検証(Leave-One-Out Cross-Validation, LOOCV)は、各データポイントを一度だけ検証データとして使用し、残りのデータを訓練データとして使用する交差検証である。具体的には、まずデータセットから1つのデータポイント(1ケース分のデータ)を検証データとして抜き出し、残りを訓練データとする。次に、この訓練データを用いてモデルを訓練する。訓練されたモデルを、先に抜き出した1つのデータポイントを用いて評価し、このとき評価指標を計算する。この手順をデータセットの全データポイントについて繰り返す。最後に、全データポイントに対する評価指標を集計し、平均やその他の統計量を計算することで、モデルの性能を評価する。

nestedcvパッケージを用いたLOOCV Lasso

データの用意

library(haven)
library(tidyr)
auto <- haven::read_dta("http://www.stata-press.com/data/r9/auto.dta")
auto <- auto %>% drop_na()  # 全カラムに対してNAがない行を抽出

n <- nrow(auto)
price <- auto$price
X <- auto[, c("mpg", "rep78", "headroom", "trunk", "weight", "length",
              "turn", "displacement", "gear_ratio", "foreign")]
X$foreign <- as.integer(X$foreign)
X <- as.matrix(X)

乱数の設定

set.seed(1234)

LOOCVを用いたLasso回帰の実行

# 乱数の設定
set.seed(123)

# LOOCVを用いたLasso回帰の実行
library(nestedcv)
library(glmnet)

fit2 <- nestcv.glmnet(
  y = price,
  x = X,
  family = "gaussian",
  alphaSet = 1,
  outer_method = "LOOCV",  # LOOCVを指定
  n_outer_folds = nrow(X),  # データポイント数に一致させる
  n_inner_folds = 10,  # 内側のCVのfold数
  cv.cores = num_cores  # 並列処理のためのコア数
)

# 結果の表示
summary(fit2)
plot_lambdas(fit2, showLegend = "bottomright")
Nested cross-validation with glmnet
No filter
Outer loop:  leave-one-out CV
Inner loop:  10-fold CV
69 observations, 10 predictors


Final parameters:
lambda   alpha  
   141       1  

Final coefficients:
 (Intercept)      foreign     headroom        rep78 displacement       weight 
   -1709.658     2762.669     -364.985      111.492       12.954        1.704 

Result:
     RMSE    Rsquared         MAE   
2240.9408      0.4009   1706.8891