
の続きです。前回は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%でした。
今回は以上です。
次回は
です。
はじめから読むには、
です。
今回のコードは以下になります。
#
# 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 です。)