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

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

日銀が保有する国債残高のデータの分析4 - Rで機械学習 - tidymodelsでglmnetエンジンでtypeの分類 - 92%の正解率

www.crosshyou.info

の続きです。前回はRでt検定とANOVAをやりました。今回は機械学習でtype: 5年債とか10年債とかを分類してみましょう。

その前に、一応の確認として、seriesとtypeの関係をグラフで見ておきます。

seriesの分布をヒストグラムにします。

seriesは国債の回号です。正規分布にはなっていないですね。dateとseriesの関係を箱ひげ図でみてみます。

2025年と2026年で大きな違いは無いです。

typeとseriesはどうでしょうか?

これは明らかに違いますね。

seriesとamtはどうでしょうか。両方とも数値型のデータなので、散布図を描いてみます。

何かしらの関係はありそうですが、線形の関係ではないですね。

では、typeの数を確認してみましょう。

今回は、y5, y10, y20, y30の4つに絞って、この4つを分類する機械学習をします。

まず、この4つだけのデータフレームを作成します。

tidymodelsのパッケージの読み込みをします。

トレーニング用のデータとテスト用のデータを作ります。

initial_split()関数で、strata = type としているので、トレーニング用のデータとテスト用のデータでtypeの比率は同じくらいになっているはずです。確認します。

トレーニング用のデータとテスト用のデータで比率に大きな違いはないですね。

はじめのモデルはglmnetのfamily = "multinomial" でやってみます。

tidymodelsのワークフローでは、multinom_reg()でエンジンをglmnetにするとできます。

次は、レシピを作ります。

前処理は、ダミー変数にするのと、標準化です。

モデルとレシピを合わせて、ワークフローを作ります。

クロスバリデーションのfoldsを作ります。8個にしてみました。深い意味は無いです。

チューニング・グリッドを作ります。

クロスバリデーションを実行します。

最適なパラメータを確認します。

最適なパラメータで、ワークフローを最終決定します。

最終ワークフローでfitします。

モデルの係数を確認してみます。

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

実際のtypeとの混合行列を作成します。

交差項や多項式を入れていない単純なモデルでしたが、結構当たってますね。

正解率を計算しましょう。

正解率は92%でした。

今回は以上です。

次回は

www.crosshyou.info

です。

 

はじめから読むには、

www.crosshyou.info

です。

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

#
# seriesの分布
df |> 
  ggplot(aes(x = series)) +
  geom_histogram(color = "white") +
  theme_minimal()
#
# dateとseries
df |> 
  ggplot(aes(x = series, fill = date)) +
  geom_boxplot() +
  theme_minimal()
#
# typeとseries
df |> 
  ggplot(aes(x = series, fill = type)) +
  geom_boxplot() +
  theme_minimal()
#
# amtとseries
df |> 
  ggplot(aes(x = amt, y = series)) +
  geom_point() +
  theme_minimal()
#
# typeの数の確認
df |> 
  count(type)
#
# y5, y10, y20, y30だけのデータフレームを作成
df_small <- df |> 
  filter(type %in% c("y5", "y10", "y20", "y30")) |> 
  mutate(type = as.character(type)) |> 
  mutate(type = as.factor(type))
summary(df_small)
#
# date, series, amtを説明変数にして、typeを予測するモデルを作る
#
# tidymodelsパッケージの読み込み
library(tidymodels)
#
# df_smallをトレーニング用とテスト用にわける
set.seed(222)
splits <- initial_split(df_small, prop = 0.75, strata = type)
df_train <- training(splits)
df_test <- testing(splits)
#
# typeの比率の確認
# トレーニング用のデータ
df_train |> 
  count(type) |> 
  mutate(prop = n / sum(n))
#
# テスト用のデータ
df_test |> 
  count(type) |> 
  mutate(prop = n / sum(n))
#
# シンプルなglmnetエンジン
# Step 1: モデルの構築
glmnet_mod <- multinom_reg(
  penalty = tune(),
  mixture = tune()
) |> 
  set_engine("glmnet")
#
# Step 2: レシピの構築
glmnet_rec <- recipe(type ~ date + series + amt, data = df_train) |> 
  step_dummy(all_nominal_predictors()) |> 
  step_normalize(all_predictors())
#
# Step 3: ワークフローの構築
glmnet_wf <- workflow() |> 
  add_model(glmnet_mod) |> 
  add_recipe(glmnet_rec)
#
# Step 4: クロスバリデーションの設定
set.seed(1)
glmnet_folds <- vfold_cv(df_train, v = 8)
#
# Step 5: チューニング・グリッドの設定
glmnet_grid <- grid_regular(
  penalty(range = c(-5, 1)),
  mixture(range = c(0.15, 0.95)),
  levels = 6
)
#
# Step 6: クロスバリデーションの実行
glmnet_tuned <- tune_grid(
  glmnet_wf,
  resamples = glmnet_folds,
  grid = glmnet_grid,
  metrics = metric_set(accuracy, roc_auc)
)
#
# Step 7: 最適なパラメータの確認
glmnet_params <- select_best(glmnet_tuned, metric = "accuracy") 
glmnet_params
#
# Step 8: 最適なパラメータで最終ワークフローを構築
glmnet_final_wf <- finalize_workflow(glmnet_wf, glmnet_params)
#
# Step 9: 最終ワークフローでfit
glmnet_fit <- fit(glmnet_final_wf, df_train)
#
# Step 10: モデルの係数の確認
glmnet_fit |> 
  extract_fit_parsnip() |> 
  tidy()
#
# Step 11: テスト用のデータで予測
glmnet_pred <- predict(glmnet_fit, new_data = df_test)
glmnet_pred
#
# Step 12: Confusion Matrix
glmnet_cm <- table(glmnet_pred$.pred_class, df_test$type)
glmnet_cm
#
# Step 13: 正解率
glmnet_accuracy <- sum(diag(glmnet_cm)) / sum(glmnet_cm)
glmnet_accuracy
#

(冒頭の画像は、Bing Image Creator で生成しました。プロンプトは、Beautiful, natural landscape of vast wild field, close up of various color pansy flowers, blue sky, photo です。)