Rで何かをしたり、読書をするブログ

政府統計の総合窓口のデータや、OECDやUCIやのデータを使って、Rの練習をしています。ときどき、読書記録も載せています。

都道府県別の電子レンジ所有数量のデータの分析8 - ランダムフォレストモデルで予測して、予測結果をCopilotに解釈してもらいました。

www.crosshyou.info

の続きです。

今回はランダムフォレストで予測をしてみましょう。

レシピをrecipe()関数で作成します。

モデルを作成します。rand_forest()関数でエンジンはrangerを使いました。

ランダムフォレストモデルでは、チューニングするパラメータは、mtry, trees, min_nの3つです。

チューングリッドを作成します。grid_regular()関数を使います。

tune_grid()関数でチューニングします。

最適なパラメータを確認します。select_best()関数を使います。

finalize_workflow()関数で最終ワークフローを作成します。

パラメータは、mtry = 2, trees = 1000, min_n = 2 ですね。

fit()関数でモデルの学習をします。

predict()関数でテスト用データの予測をします。

実際の値と予測値を一つのデータフレームにします。

RMSEなどの評価指標を算出します。

線形モデル、Elastic-Netモデルと比較してみます。

3つのモデルの中では、ランダムフォレストモデルは、MAEは一番よくて、RMSEやR-Squareは一番悪いですね。

前々回、前回の結果を踏まえて、Copilotに聞いてみました。

Copilotへの質問:「観測数が75、特徴量が5個のデータの回帰モデルを作成しました。 linear regressionモデルは、RMSEが18.4, MAEが16.2, R2が0.475 elastic-netモデルは、RMSEが18.4, MAEが16.0, R2が0.465 random forestモデルは、RMSEが20.9, MAEが16.0, R2が0.338 でした。 これらの結果から、このデータセットはどのような特徴があると示唆されますか?」

Copilotの回答: ---------------------------------------------------------------------- 

🔍 モデル比較から読み取れるデータの特徴
1. 線形性が比較的強い(=線形モデルが最も良い)
- linear regression と elastic-net が ほぼ同じ性能(RMSE 18.4、MAE 16前後、R² ≈ 0.47)
- elastic-net の正則化がほとんど改善をもたらしていない
👉 特徴量と目的変数の関係が、比較的シンプルな線形構造に近い
👉 非線形性や複雑な相互作用はあまり強くない

2. データ量が少ないため、複雑モデルが不利
- 観測数 75 は、ランダムフォレストにはかなり少ない
- RF の R² が 0.338 と大きく悪化しているのは典型的な「データ不足での過学習」
👉 データ量が少ない状況では、木系モデルは安定しにくい
👉 線形モデルの方がバイアスはあるが分散が小さく、結果的に良い性能を出している

3. 特徴量の情報量がそこまで高くない
- R² ≈ 0.47 は「説明できているのは半分弱」
- MAE ≈ 16、RMSE ≈ 18.4 という誤差の大きさも、モデル間でほぼ変わらない
👉 5つの特徴量だけでは、目的変数を十分に説明しきれていない可能性
👉 追加の特徴量(非線形変換、交互作用、外部データ)が必要かもしれない

4. 多重共線性は強くなさそう
- elastic-net(L1+L2)が線形回帰とほぼ同じ性能
→ L1 によるスパース化がほぼ効いていない
👉 特徴量間の強い共線性はあまりない
👉 どの特徴量もある程度は独立した情報を持っている

🧭 全体として示唆されること
まとめると、このデータセットは次のような特徴を持っていると考えられます。
✔ 線形性が比較的強い
✔ 非線形モデル(RF)が性能を出せないほどデータ量が少ない
✔ 特徴量の説明力は中程度(R² ≈ 0.47)
✔ 多重共線性は強くない
✔ 追加の特徴量や変換を検討する余地がある

-------------------------------------------------------------------------------------------------

このCopilotの回答を読んで、なるほど~と思いました。観測数が少ないとランダムフォレストモデルでは過学習しやすいんですね。

今回は以上です。

次回は、

www.crosshyou.info

です。

 

はじめから読むには、

www.crosshyou.info

です。

今回のコードは以下になります。

#
# ランダムフォレスト(ranger)
#
# レシピを作成 (_rec)
rf_rec <- recipe(microwave ~ year + l_mitsudo + conve + single + income,
                 data = train_data) |>
  step_dummy(all_nominal_predictors()) |>
  step_normalize(all_predictors())
rf_rec
#
# モデルを作成 (_mod)
rf_mod <- rand_forest(
  mtry  = tune(),
  min_n = tune(),
  trees = tune()
) |>
  set_engine("ranger") |>
  set_mode("regression")
rf_mod
#
# ワークフローを作成 (_wf)
rf_wf <- workflow() |>
  add_recipe(rf_rec) |>
  add_model(rf_mod)
rf_wf
#
# チューニンググリッドを作成 (_grid)
rf_grid <- grid_regular(
  mtry(range = c(1, 5)),
  min_n(range = c(2, 20)),
  trees(range = c(200, 1000)),
  levels = 5
)
rf_grid
#
# チューニングの実行 (_tuned)
rf_tuned <- tune_grid(
  rf_wf,
  resamples = folds,
  grid = rf_grid
)
rf_tuned
#
# 最適パラメータ (_params)
rf_params <- select_best(rf_tuned, metric = "rmse")
rf_params
#
# 最終ワークフローを作成 (_final_wf)
rf_final_wf <- finalize_workflow(
  rf_wf,
  rf_params
)
rf_final_wf
#
# トレーニングデータで学習 (_fit)
rf_fit <- fit(rf_final_wf, train_data)
#
# テストデータで予測 (_pred)
rf_pred <- predict(rf_fit, new_data = test_data)
#
# 実際の値と予測値 (_result)
rf_result <- test_data |>
  select(microwave) |>
  bind_cols(rf_pred)
rf_result
#
# 評価 (_metric)
rf_metric <- rf_result |>
  metrics(truth = microwave, .pred) |>
  mutate(model = "Random_Forest")
rf_metric
#
# 3つのモデルの比較
lm_metric |> 
  bind_rows(glmnet_metric, rf_metric) |> 
  arrange(.metric, .estimate)
#

 

(冒頭の画像は、Bing Image Creator で生成しました。プロンプトは、 Landscape of beautiful deep forests, blue sky, shining white flowers, photo です。)