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

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

UCI Machine Learning Repository の Chess (King-Rook vs. King-Pawn) のデータの分析2 - glmnetのElastic-Netで分類してみる。ROCのAUCが0.996と高性能でした。

www.crosshyou.info

の続きです。前回はデータを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曲線ですね。

次回は

 

www.crosshyou.info

です。

はじめから読むには、

www.crosshyou.info

です。

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

#
# まず、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