反復交差検証 Repeated Cross-Validationの安定性のシミュレーションを行った。 反復交差検証については以下のエントリを参照。
安定性のシミュレーションはLOOCVやnーfolds CVの場合と同様に異なった乱数シードを使い、50回推定して、各変数が選ばれた回数と推定値の平均・標準偏差を計算した
データの読み込みと前処理
library(haven) library(tidyr) auto <- haven::read_dta("http://www.stata-press.com/data/r9/auto.dta") auto <- auto %>% drop_na() # 全カラムに対してNAがない行を抽出 auto$foreign <- as.integer(auto$foreign)
並列計算の準備
doParallelパッケージを用いて1コアではなく複数コアで計算するようにして、計算時間を短縮させるようにした。
library(doParallel) # 並列処理の設定 num_cores <- detectCores() - 2 # システム全体のコア数から2つを引いた数を使用 cl <- makeCluster(num_cores) registerDoParallel(cl)
Lasso回帰の安定性を調べる
反復交差検証の反復回数はこちらで調べたように14回に設定した。
library(caret) library(glmnet) library(dplyr) # 結果を格納するリスト selected_variables <- list() coefficients <- list() # 50回のシミュレーション for (i in 1:50) { set.seed(i) train_control <- trainControl(method = "repeatedcv", number = 10, # 10-fold CV repeats = 14, # 14回繰り返す savePredictions = "final") model <- train(price ~ mpg + rep78 + headroom + trunk + weight + length + turn + displacement + gear_ratio + foreign, data = auto, method = "glmnet", # Lasso回帰 trControl = train_control, tuneLength = 10) # チューニングするλの数 # 最適なモデルの係数を取得 best_lambda <- model$bestTune$lambda coef_best <- coef(model$finalModel, s = best_lambda) # 選ばれた変数とその係数を保存 non_zero_coefs <- as.matrix(coef_best) non_zero_coefs <- non_zero_coefs[non_zero_coefs[, 1] != 0, , drop = FALSE] selected_variables[[i]] <- rownames(non_zero_coefs) coefficients[[i]] <- non_zero_coefs } # 並行処理の停止 stopCluster(cl) # 選ばれた変数の回数をカウント variable_counts <- table(unlist(selected_variables)) # 選ばれた変数の推定値の平均と標準偏差を計算 variable_stats <- lapply(names(variable_counts), function(var) { coefs <- unlist(lapply(coefficients, function(coef) if (var %in% rownames(coef)) coef[var, 1] else NA)) coefs <- coefs[!is.na(coefs)] # NAを除外 mean_coef <- mean(coefs) sd_coef <- sd(coefs) data.frame(variable = var, mean = mean_coef, sd = sd_coef) }) variable_stats <- do.call(rbind, variable_stats)
変数が選ばれた回数
variable_counts_df <- as.data.frame(variable_counts) colnames(variable_counts_df) <- c("Variable", "Count") print(variable_counts_df)
Variable Count 1 (Intercept) 50 2 displacement 50 3 foreign 50 4 gear_ratio 32 5 headroom 50 6 length 12 7 mpg 16 8 rep78 50 9 trunk 12 10 turn 49 11 weight 50
推定値の平均と標準偏差
print(variable_stats)
variable mean sd 1 (Intercept) 349.73377 2330.9384052 2 displacement 13.57817 0.3616850 3 foreign 2839.84030 124.6804858 4 gear_ratio -203.81945 189.8846262 5 headroom -464.11233 54.2174071 6 length -12.02154 10.8404136 7 mpg -29.14755 8.0687846 8 rep78 159.76717 47.6848193 9 trunk 19.99706 10.3307869 10 turn -42.77568 22.0358426 11 weight 1.92157 0.2248898