
の続きです。前回はチューニング・グリッドを作成しましたから、今回は tune_grid()関数で実際にチューニングをしていきます。
線形モデルは、fit_resample()関数を使います。

futureパッケージとtuneパッケージを読み込み、plan()関数で並列処理をしています。チューニングの計算時間を少しでも短くするためです。
ペナルティ付き線形モデル(glmnet)以降は、tune_grid()関数を使います。

警告メッセージが表示されていますが、気にしなくていいです。Fold06のデータで、推定値が定数になってしまった、という意味ですが、他のFoldでは推定できているので大丈夫です。




勾配ブースティング回帰モデル(xgboost)でたくさん警告メッセージが出てしまいました。Copilotに相談したら、レシピとチューニング・グリッドがダメだったようです。
レシピは
xgboost_rec <- recipe(target ~ ., data = train_data) |>
step_zv(all_predictors()) |> # ゼロ分散の列を削除
step_dummy(all_nominal_predictors()) |> # カテゴリ変数をダミー化
step_normalize(all_numeric_predictors()) # 数値を標準化
チューニンググリッドは、
xgboost_grid <- grid_space_filling(
mtry(range = c(1L, 8L)),
min_n(range = c(2L, 20L)),
tree_depth(range = c(3L, 8L)),
learn_rate(range = c(-1.5, -0.5)), # 0.03〜0.3
loss_reduction(range = c(0, 5)), # gamma >= 0 が安定
sample_size(range = c(0, 1)), # 0〜1 の実数を自動生成
size = 20
)
このように変えたらいいらしいです。
変えてやってみます。

変えてもだめでした。。。
さらにCopilotに相談したら、train_dataのglimpse()を見せて、ということだったので、見せたら、

ということでした。
そして、ここでは割愛しますが、さらに調整したコードを走らせたのですが、結果は改善しませんでした。
そして、最終的なCopilotの結論は、

でした。
ということなので、勾配ブースティング回帰モデルはあきらめます。
Copilotによる詳しい説明は、以下のようでした。
🔍 なぜこのデータで xgboost が木を作れないのか
① 特徴量が 8 列しかない(低次元)
xgboost は本来:
- 数百〜数千の特徴量
- 非線形な関係
- カテゴリ変数の大量の dummy
- ノイズの多いデータ
で威力を発揮します。
しかし今回のデータは:
- 数値 8 列
- 112 行
- 分布も比較的素直
→ 木が分割する余地がほとんどない
② v3, v4, v7, v8 に “0 が大量に含まれる”
例:
- v4: 0 が多い
- v8: 0 が多い
- v3, v7: 負の値が多く偏りが強い
fold によっては:
- ほぼ 0 しかない
- ほぼ負の値しかない
- 分散が極端に小さい
→ xgboost は「分割しても意味がない」と判断
→ 定数予測
③ 112 行 × 5-fold CV → fold が小さすぎる
1 fold あたり 22 行。
この規模だと:
- 目的変数の分布が fold ごとに大きく変わる
- 特徴量の分散も fold ごとに変わる
- → 分割が成立しない fold が大量に発生
- → 全部同じ値を返す
④ このデータは “ほぼ線形” の可能性が高い
あなたのデータを見る限り:
- v1〜v8 が target と線形関係に見える
- 変数間の相関も高そう
- 非線形性が弱い
xgboost は非線形を掘りに行くモデルなので、
線形に近いデータでは 木が成長しない → 定数予測 が起きます。
🔥 つまり、xgboost が悪いのではなく、
このデータが xgboost に向いていない
今回のデータは、勾配ブースティング回帰モデルのような高性能モデルは必要ない、ということですね。
今回は以上です。
次回は、
です。
はじめから読むには、
です。
今回のコードは以下になります。
#
# 6. 各モデルのチューニング
# 6-1. 線形モデル(lm)
library(future)
library(tune)
plan(multisession, workers = parallel::detectCores() - 1) # 並列処理スタート
set.seed(123)
lm_tuned <- fit_resamples(
lm_wf,
resamples = folds,
control = control_resamples(save_pred = TRUE)
)
#
# 6-2. ペナルティ付き線形モデル(glmnet)
set.seed(123)
glmnet_tuned <- tune_grid(
glmnet_wf,
grid = glmnet_grid,
resamples = folds,
control = control_grid(save_pred = TRUE)
)
# 6-3. 決定木モデル(rpart)
set.seed(123)
rpart_tuned <- tune_grid(
rpart_wf,
grid = rpart_grid,
resamples = folds,
control = control_grid(save_pred = TRUE)
)
#
# 6-4. ランダムフォレストモデル(ranger)
set.seed(123)
ranger_tuned <- tune_grid(
ranger_wf,
grid = ranger_grid,
resamples = folds,
control = control_grid(save_pred = TRUE)
)
# 6-5. サポートベクター回帰(SVR)モデル(kernlab)
library(kernlab)
set.seed(123)
kernlab_tuned <- tune_grid(
kernlab_wf,
grid = kernlab_grid,
resamples = folds,
control = control_grid(save_pred = TRUE)
)
#
# 6-6. k-NN回帰モデル(kknn)
set.seed(123)
kknn_tuned <- tune_grid(
kknn_wf,
grid = kknn_grid,
resamples = folds,
control = control_grid(save_pred = TRUE)
)
#
# 6-7. ニューラルネットワークモデル(nnet)
set.seed(123)
nnet_tuned <- tune_grid(
nnet_wf,
grid = nnet_grid,
resamples = folds,
control = control_grid(save_pred = TRUE)
)
#
# 6-8. 勾配ブースティング回帰モデル(xgboost)
set.seed(123)
xgboost_tuned <- tune_grid(
xgboost_wf,
grid = xgboost_grid,
resamples = folds,
control = control_grid(save_pred = TRUE)
)
plan(sequential) # 並列処理エンド
#
# 勾配ブースティング回帰モデルのレシピを再定義
xgboost_rec <- recipe(target ~ ., data = train_data) |>
step_zv(all_predictors()) |> # ゼロ分散の列を削除
step_dummy(all_nominal_predictors()) |> # カテゴリ変数をダミー化
step_normalize(all_numeric_predictors()) # 数値を標準化
#
# 勾配ブースティング回帰モデルのワークフローを再定義
xgboost_wf <- workflow() |>
add_model(xgboost_mod) |>
add_recipe(xgboost_rec)
#
# 勾配ブースティング回帰モデルのチューニンググリッドを再定義
xgboost_grid <- grid_space_filling(
mtry(range = c(1L, 8L)),
min_n(range = c(2L, 20L)),
tree_depth(range = c(3L, 8L)),
learn_rate(range = c(-1.5, -0.5)), # 0.03〜0.3
loss_reduction(range = c(0, 5)), # gamma >= 0 が安定
sample_size(range = c(0, 1)), # 0〜1 の実数を自動生成
size = 20
)
#
# 勾配ブースティング回帰モデルの再チューニング
plan(multisession, workers = parallel::detectCores() - 1) # 並列処理スタート
set.seed(123)
xgboost_tuned <- tune_grid(
xgboost_wf,
grid = xgboost_grid,
resamples = folds,
control = control_grid(save_pred = TRUE)
)
plan(sequential) # 並列処理エンド
#
# さらに再定義
xgboost_rec <- recipe(target ~ ., data = train_data) %>%
step_normalize(all_numeric_predictors())
xgboost_wf <- workflow() |>
add_model(xgboost_mod) |>
add_recipe(xgboost_rec)
folds <- vfold_cv(train_data, v = 5, repeats = 3)
xgboost_grid <- grid_space_filling(
tree_depth(range = c(3L, 6L)),
learn_rate(range = c(-1.3, -0.7)), # 0.05〜0.2
min_n(range = c(2L, 10L)),
loss_reduction(range = c(0, 2)),
sample_size(range = c(0, 1)),
mtry(range = c(1L, 8L)),
size = 20
)
plan(multisession, workers = parallel::detectCores() - 1) # 並列処理スタート
set.seed(123)
xgboost_tuned <- tune_grid(
xgboost_wf,
grid = xgboost_grid,
resamples = folds,
control = control_grid(save_pred = TRUE)
)
plan(sequential) # 並列処理エンド
#
(冒頭の画像は、Bing Image Creator で生成しました。プロンプトは、Natural scene landscape, close up rainbow color flowers, green grass fields, one tall tree, blue sky, photo です。)