library(mlbench)
data(PimaIndiansDiabetes)
df <- PimaIndiansDiabetes
tar.idx <- 9tuneRanger
パッケージの概要
機械学習におけるランダムフォレストモデルの構築を行えます。また、tuneRangerではハイパーパラメータのチューニングを行う機能も提供されます。
使用例:PimaIndiansDiabetesデータの分類
データの確認
PimaIndiansDiabetesデータを用いて、種々の項目からその患者が糖尿病患者であるかを判定するランダムフォレストモデルをtuneRangerパッケージを用いて構築します。
データの中身の確認です。(head)
head(df) pregnant glucose pressure triceps insulin mass pedigree age diabetes
1 6 148 72 35 0 33.6 0.627 50 pos
2 1 85 66 29 0 26.6 0.351 31 neg
3 8 183 64 0 0 23.3 0.672 32 pos
4 1 89 66 23 94 28.1 0.167 21 neg
5 0 137 40 35 168 43.1 2.288 33 pos
6 5 116 74 0 0 25.6 0.201 30 neg
データの中身の確認です。(str)
str(df)'data.frame': 768 obs. of 9 variables:
$ pregnant: num 6 1 8 1 0 5 3 10 2 8 ...
$ glucose : num 148 85 183 89 137 116 78 115 197 125 ...
$ pressure: num 72 66 64 66 40 74 50 0 70 96 ...
$ triceps : num 35 29 0 23 35 0 32 0 45 0 ...
$ insulin : num 0 0 0 94 168 0 88 0 543 0 ...
$ mass : num 33.6 26.6 23.3 28.1 43.1 25.6 31 35.3 30.5 0 ...
$ pedigree: num 0.627 0.351 0.672 0.167 2.288 ...
$ age : num 50 31 32 21 33 30 26 29 53 54 ...
$ diabetes: Factor w/ 2 levels "neg","pos": 2 1 2 1 2 1 2 1 2 2 ...
各変数の意味は以下の通りです。
| 変数名 | データ型 | 概要 |
|---|---|---|
| pregnant | num | 妊娠回数 |
| glucose | num | 血漿グルコース濃度(負荷試験) |
| pressure | num | 拡張期血圧 [mm Hg] |
| triceps | num | 上腕三頭筋皮膚襞の厚さ [mm ] |
| insulin | num | 2時間血清インスリン [mu U/ml] |
| mass | num | BMI |
| pedigree | num | 糖尿病血統機能 |
| age | num | 年齢 |
| diabetes | Factor | クラス変数(糖尿病の検査) |
summaryを表示します。
summary(df) pregnant glucose pressure triceps
Min. : 0.000 Min. : 0.0 Min. : 0.00 Min. : 0.00
1st Qu.: 1.000 1st Qu.: 99.0 1st Qu.: 62.00 1st Qu.: 0.00
Median : 3.000 Median :117.0 Median : 72.00 Median :23.00
Mean : 3.845 Mean :120.9 Mean : 69.11 Mean :20.54
3rd Qu.: 6.000 3rd Qu.:140.2 3rd Qu.: 80.00 3rd Qu.:32.00
Max. :17.000 Max. :199.0 Max. :122.00 Max. :99.00
insulin mass pedigree age diabetes
Min. : 0.0 Min. : 0.00 Min. :0.0780 Min. :21.00 neg:500
1st Qu.: 0.0 1st Qu.:27.30 1st Qu.:0.2437 1st Qu.:24.00 pos:268
Median : 30.5 Median :32.00 Median :0.3725 Median :29.00
Mean : 79.8 Mean :31.99 Mean :0.4719 Mean :33.24
3rd Qu.:127.2 3rd Qu.:36.60 3rd Qu.:0.6262 3rd Qu.:41.00
Max. :846.0 Max. :67.10 Max. :2.4200 Max. :81.00
psychパッケージのpairs.panelsを用いて、散布図の一覧を表示します。
library(psych)df.x <- df[-tar.idx]
df.y <- df[tar.idx]
df.y <- ifelse(df.y == "pos", 1, 2)
pairs.panels(df.x, bg=c("skyblue", "salmon")[df.y], pch=21)
ggplot2パッケージを用いて、ヒストグラムを表示します。変数ごとにpos/negの分布の傾向を把握することができます。
library(ggplot2)
Attaching package: 'ggplot2'
The following objects are masked from 'package:psych':
%+%, alpha
library(tidyr)
library(dplyr)
Attaching package: 'dplyr'
The following objects are masked from 'package:stats':
filter, lag
The following objects are masked from 'package:base':
intersect, setdiff, setequal, union
# 数値変数だけを抽出(diabetes以外)
num_vars <- names(df)[sapply(df, is.numeric)]
# 長い形式に変換
df_long <- df %>%
pivot_longer(cols = all_of(num_vars), names_to = "variable", values_to = "value")
# ヒストグラムを1つの図にまとめて作成
ggplot(df_long, aes(x = value, fill = diabetes)) +
geom_histogram(position = "identity", alpha = 0.5, bins = 30) +
facet_wrap(~variable, scales = "free") +
labs(title = "Histograms of Variables by Diabetes",
x = "Value", y = "Count") +
theme_minimal()
データセットの準備
PimaIndiansDiabetesデータを、モデル生成のための訓練データとモデル評価のためのテストデータに分割します。データ割合は、訓練データ7割・テストデータ3割とします。確認のためにデータサイズを出力します。
# 再現性のためにシードを設定
set.seed(123)
# データの分割
sample_indices <- sample(1:nrow(df), 0.7 * nrow(df))
train_data <- df[sample_indices, ]
test_data <- df[-sample_indices, ]
# データサイズの確認
c(nrow(df), nrow(train_data), nrow(test_data))[1] 768 537 231
モデル生成
makeClassifTaskにてタスクの定義を行い、makeLearnerにて適用するアルゴリズムの選択を行います。
library(mlr)Loading required package: ParamHelpers
task <- makeClassifTask(data = train_data, target = "diabetes")
lrn <- makeLearner("classif.rpart")分割したデータセットを基にモデルの訓練を行います。
model <- train(lrn, task)予測結果を変数に格納します。
res_pred <- predict(model, newdata = test_data)$data$response実際の結果と予測結果を比較できる混同行列を出力します。
res_act <- test_data[[tar.idx]]
(conf_mat <- table(res_act, res_pred)) res_pred
res_act neg pos
neg 129 21
pos 46 35
各種評価指標を確認します。まずは計算用の関数を定義します。
create_df_res <- function(cmat){
TN <- cmat[1,1]
FP <- cmat[1,2]
FN <- cmat[2,1]
TP <- cmat[2,2]
# 正解率:どれだけ正しく分類できたかの割合
acc <- round((TP + TN) / (TP + TN + FN + FP), 3)
# 適合率:陽性と判定されたものがどれだけ正しく陽性であるかの割合
prec <- round(TP / (TP + FP), 3)
# 再現率(真陽性率):実際に陽性のものをどれだけ正しく陽性と判定できたかの割合
rec <- round(TP / (TP + FN), 3)
# F値:適合率と再現率の調和平均(両者はトレードオフの関係)
Fval <- round(2 * rec * prec / (rec + prec), 3)
# 真陰性率:実際に陰性のものをどれだけ正しく陰性と判定できたかの割合
TNRat <- round(TN / (TN + FP), 3)
df_rat <- data.frame(
Item = c("正解率", "適合率", "再現率(真陽性率)", "F値", "真陰性率"),
Rate = c(acc, prec, rec, Fval, TNRat)
)
df_rat
}data.frameの出力整形用の関数を定義します。
library(knitr)
library(kableExtra)
Attaching package: 'kableExtra'
The following object is masked from 'package:dplyr':
group_rows
show_df <- function(df, cap=""){
if(is_html_output()){
kable(df, format = "html", caption = cap) %>%
kable_styling(bootstrap_options = "striped", full_width = FALSE, position = "left")
}else{
kable(df, format = "pipe", caption = cap)
}
}評価指標を確認します。
df_res <- create_df_res (conf_mat)
show_df(df_res)| Item | Rate |
|---|---|
| 正解率 | 0.710 |
| 適合率 | 0.625 |
| 再現率(真陽性率) | 0.432 |
| F値 | 0.511 |
| 真陰性率 | 0.860 |
パラメータチューニング
tuneRangerパッケージを使用して、パラメータチューニングを行ってゆきます。
パラメータチューニングのための実行時間を事前に知ることが出来ます。
library(tuneRanger)Loading required package: ranger
Loading required package: mlrMBO
Loading required package: smoof
Loading required package: checkmate
Loading required package: parallel
Loading required package: lhs
estimateTimeTuneRanger(task, num.trees = 500, num.threads = 3, iters = 30)Approximated time for tuning: 51S
tuneRangerを使用して、実際にパラメータチューニングをやってみます。
# 再現性のためにシードを設定
set.seed(123)
res <- tuneRanger(task, measure = list(multiclass.brier), num.trees = 500,
num.threads = 3, iters = 30, save.file.path = NULL, show.info = FALSE)チューニングされたパラメータです。
show_df(as.data.frame(t(res$recommended.pars)), "パラメータ")| V1 | |
|---|---|
| mtry | 5.0000000 |
| min.node.size | 42.0000000 |
| sample.fraction | 0.5282881 |
| multiclass.brier | 0.3167057 |
| exec.time | 0.1866667 |
チューニング後のモデルの混同行列です。
res_pred_tuned <- predict(res$model, newdata = test_data)$data$response
(conf_mat_tuned <- table(res_act, res_pred_tuned)) res_pred_tuned
res_act neg pos
neg 127 23
pos 42 39
評価指標を確認します。モデル性能がおおむね向上していることが確認できます。
df_res_tuned <- create_df_res (conf_mat_tuned)
df_res_all <- cbind(
df_res,
df_res_tuned[, 2])
colnames(df_res_all) <- c("Item", "df_res", "df_res_tuned")
show_df(df_res_all)| Item | df_res | df_res_tuned |
|---|---|---|
| 正解率 | 0.710 | 0.719 |
| 適合率 | 0.625 | 0.629 |
| 再現率(真陽性率) | 0.432 | 0.481 |
| F値 | 0.511 | 0.545 |
| 真陰性率 | 0.860 | 0.847 |