
の続きです。前回はデータをRに読み込ませて前処理をしました。
今回は実際に分類器を作ります。glmnetパッケージでElastic-Netでやってみようと思います。
glmnetパッケージを読み込みます。

glmnetは特徴量はマトリックス型、targetはベクトル型にする必要があるので、dfをxとyにわけます。

トレーニング用のインデックスを作成します。

alpha = 0.2, alpha = 0.5, alpha = 0.8 の3つのalpha水準でモデルを作りました。

この3つの中で、どれが一番よかったか調べます。

alpha = 0.8 の cvm が0.182で一番小さいので、c0.8を使って予測しましょう。
その前にこのモデルは、どんな係数か確認します。

alpha = 0.8 なので、LASSOよりのElastic-Netですが、あんまり特徴量の削減はされていないですね。
predict()関数で予測します。

混合行列をtable()関数で作ります。

お!結構あたっていますね。TN(True Negative), FN(False Negative), FP(False Negative), TP(True Positive)をあてはめます。

正解率(Accuracy)を計算します。

97.2%です。たいしたもんですね。
Sensitivityを計算します。

96.8%です。
Specitifityを計算します。

97.6%です。
Precisionを計算します。

97.8%です。
F-1 Scoreを計算します。

97.3%です。
どうでしょうか?結構いい分類結果だと思います。
glmnetパッケージには、assess.glmnet()関数、confusion.glmnet()関数がありますので、それも使ってみます。

$classが0.02815433でした。1 - 0.02815433 = 0.9718457 で先ほどのAccuracyと一致します。
$aucが0.9959663です。これはほぼ完璧レベルですね。
confusion.glmnet()関数も実行してみます。

confusion.glmnet()関数は、混合行列を作り、Accuracy(Percent Correct)を計算する関数でした。
roc.glmnet()関数を使ってROC曲線も描けます。


今回は以上です。AUCが0.996ですから、とても素晴らしいROC曲線ですね。
次回は
です。
はじめから読むには、
です。
今回のコートは以下になります。
#
# まず、tidymodelsを使わないElastic-Net
#
library(glmnet)
#
# はじめに、dfをx, y にわける
x <- df |>
select(-target) |>
makeX()
#
y <- df$target
#
# トレーニング用のインデックス
set.seed(1919)
train <- sample(1:length(y), 0.7 * length(y), replace = FALSE)
#
# alpha = 0.2
set.seed(1)
c0.2 <- cv.glmnet(x[train, ], y[train], family = "binomial",
alpha = 0.2)
#
# alpha = 0.5
set.seed(1)
c0.5 <- cv.glmnet(x[train, ], y[train], family = "binomial",
alpha = 0.5)
#
# alpha = 0.8
set.seed(1)
c0.8 <- cv.glmnet(x[train, ], y[train], family = "binomial",
alpha = 0.8)
#
# c0.2, c0.5, c0.8の中でどれが一番か調べます
tibble(
cvm = c0.2$cvm,
lambda = c0.2$lambda
) |>
filter(lambda == c0.2$lambda.1se)
#
tibble(
cvm = c0.5$cvm,
lambda = c0.5$lambda
) |>
filter(lambda == c0.5$lambda.1se)
#
tibble(
cvm = c0.8$cvm,
lambda = c0.8$lambda
) |>
filter(lambda == c0.8$lambda.1se)
#
# c0.8が一番でした。
# c0.8(lambda.1se)の係数を確認します。
coef(c0.8, s = "lambda.1se")
#
# c0.8(lambda.1se)で予測してみます。
c0.8_pred <- predict(c0.8, newx = x[-train, ], s = "lambda.1se",
type = "class")
head(c0.8_pred)
#
# 実際のyとの比較(混合行列)
table(c0.8_pred, y[-train])
#
# TN, FN, FP, TPを当てはめる
TN <- 444; FN <- 16; FP <- 11; TP <- 488
#
# Accuracy(正解率):
# 全体のうち、正しく予測できた割合
(TN + TP) / (TN + FN + FP + TP)
#
# Sensitivity(Recall, True Positive Rate):
# 実際にwonのものを正しくwonとできた割合
TP / (TP + FN)
#
# Specificity(True Negative Rate):
# 実際にnowinのものを正しくnowinとできた割合
TN / (TN + FP)
#
# Precision(適合率):
# wonと予測したもののうち、実際にwonだった割合
TP / (TP + FP)
#
# F-1 Score:
# PrecisionとRecallの調和平均
# 予測が当たっているか(Precision), 見逃していないか(Recall)の両方を同時に評価
2 * (TP / (TP + FP)) * (TP / (TP + FN)) /
*1 + (TP / (TP + FN)))
#
# assess.glmnet()
assess.glmnet(c0.8, newx = x[-train, ], newy = y[-train],
family = "binomial", s = "lambda.1se")
#
# confusion.glmnet()
confusion.glmnet(c0.8, newx = x[-train, ], newy = y[-train],
family = "binomial", s = "lambda.1se")
#
#
# roc.glmnet()でROC曲線
roc <- roc.glmnet(c0.8, newx = x[-train, ], newy = y[-train],
family = "binomial", s = "lambda.min")
#
plot(roc$FPR, roc$TPR, type = "l",
xlab = "False Positive Rate",
ylab = "True Positive Rate")
abline(0, 1, lty = 2, col = "red")
(冒頭の画像は、Bing Image Creator で生成しました。プロンプトは、Natural landscape of rice field, close up of purple violet flowers, there is a white cloud in the high blue sky, photo です。)
*1:TP / (TP + FP