次のデータを用いて新車購入の確率を予測する。
options(digits = 2) # 表示の有効桁数2桁に設定
d0 <- read.csv(file = 'https://stats.dip.jp/01_ds/data/car_data_jp.csv')
summary(d0) # 要約統計量
## お客様番号 性別 年齢 年収 購入判断
## Min. : 1 Length:1000 Min. :18 Min. : 15000 Min. :0.0
## 1st Qu.: 251 Class :character 1st Qu.:32 1st Qu.: 46375 1st Qu.:0.0
## Median : 500 Mode :character Median :40 Median : 72000 Median :0.0
## Mean : 500 Mean :40 Mean : 72689 Mean :0.4
## 3rd Qu.: 750 3rd Qu.:48 3rd Qu.: 90000 3rd Qu.:1.0
## Max. :1000 Max. :63 Max. :152500 Max. :1.0
head(d0) # 先頭の5レコード表示
## お客様番号 性別 年齢 年収 購入判断
## 1 385 男性 35 20000 0
## 2 681 男性 40 43500 0
## 3 353 男性 49 74000 0
## 4 895 男性 40 107500 1
## 5 661 男性 25 79000 0
## 6 846 女性 47 33500 1
tail(d0) # 末尾の5レコード表示
## お客様番号 性別 年齢 年収 購入判断
## 995 951 女性 53 104000 1
## 996 863 男性 38 59000 0
## 997 800 女性 47 23500 0
## 998 407 女性 28 138500 1
## 999 299 女性 48 134000 1
## 1000 687 女性 44 73500 0
(n <- nrow(d0)) # 全レコードサイズ
## [1] 1000
# 乱数シード(乱数の種):
# 無作為標本抽出でプログラム実行のたびに同じ標本が抽出される。
# 数字を変えると異なる組み合わせで毎回同じ標本が抽出される。
set.seed(5)
# 訓練データと試験データに分割
# 層化無作為標本抽出
# prop:訓練データの分割割合
# strata:設定した変数の割合がそれぞれのデータセットで均等になる(層化分割)。
library(rsample)
d.trte <- initial_split(d0, prop = 4/5, strata = 購入判断)
d.trte
## <Training/Testing/Total>
## <799/201/1000>
d.tr <- training(d.trte) # 訓練データ
d.te <- testing (d.trte) # 試験データ
\[ \begin{align} \hat{p}&=\frac{1}{1+\exp\{-(\beta_0+\beta_1 x_{i}+\cdots+\beta_k x_{k})\}}\\ &ここで,\\ &\quad \hat{p}:確率の推定値\\ &\quad x_{k}: 説明変数\\ &\quad \beta_k: 偏回帰係数\\ \end{align} \]
fit.all <- glm(購入判断 ~ ., data = d.tr, family = 'binomial')
summary(fit.all)
##
## Call:
## glm(formula = 購入判断 ~ ., family = "binomial", data = d.tr)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -1.24e+01 9.34e-01 -13.25 <2e-16 ***
## お客様番号 1.30e-04 3.56e-04 0.37 0.71
## 性別男性 2.49e-01 2.10e-01 1.19 0.23
## 年齢 2.22e-01 1.72e-02 12.93 <2e-16 ***
## 年収 3.43e-05 3.68e-06 9.32 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 1076.60 on 798 degrees of freedom
## Residual deviance: 584.57 on 794 degrees of freedom
## AIC: 594.6
##
## Number of Fisher Scoring iterations: 6
#(注意)
# 回帰係数の統計的有意性の判定には,
# 二値データを扱うロジスティック回帰分析ではt値ではなくてz値を使用する。
お客様番号と性別の回帰係数は有意水準5%で有意でない。 これらは購入判断に寄与しない説明変数だが, モデルを予測用に使うときは,そのまま残しておいてもよい。
有意だった説明変数だけでフィッティング
fit <- glm(購入判断 ~ 年齢 + 年収, data = d.tr, family = 'binomial')
summary(fit)
##
## Call:
## glm(formula = 購入判断 ~ 年齢 + 年収, family = "binomial",
## data = d.tr)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -1.20e+01 8.74e-01 -13.78 <2e-16 ***
## 年齢 2.20e-01 1.69e-02 12.99 <2e-16 ***
## 年収 3.40e-05 3.67e-06 9.27 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 1076.60 on 798 degrees of freedom
## Residual deviance: 586.09 on 796 degrees of freedom
## AIC: 592.1
##
## Number of Fisher Scoring iterations: 6
年収80,000US$の45歳の人の新車購入確率を求める。
d.new <- data.frame(年齢 = 45, 年収 = 80000)
p.hat <- predict(fit, type = 'response', newdata = d.new) # 予測確率
sprintf('新車購入確率:%2.1f%', p.hat * 100)
## [1] "新車購入確率:63.5%"
混同行列を作成して精度を計算する。
\[ Accuracy = \frac{TP+TN}{TP+FP+TN+FN} \] ここで,\(Accuracy\)は精度
TP: True positive;真陽性数
TN: True negative;真陰性数
FP: False positive;偽陽性数
FN: False negative;偽陰性数
この指標は2値クラスの要素がいくつ正確に分類されたかを示す。 2値クラスの要素数が大きく異なる(アンバランスな)場合は,この指標を評価には用いては行けない。 なぜなら,大多数側に単純に分類することで高精度が得られるためである。
p.hat <- predict(fit, type = 'response', newdata = d.te)
threshold <- 0.5 # 閾値(しきいち),カットオフ値(cut-off)とも呼ばれる。
is.pred <- p.hat > threshold
is.ref <- d.te$購入判断 == 1
table(予測値 = is.pred, 真値 = is.ref)
## 真値
## 予測値 FALSE TRUE
## FALSE 106 24
## TRUE 14 57
is.ok <- is.pred == is.ref
n.ok <- sum(is.ok)
sprintf('新車購入予測精度:%2.1f%', n.ok / nrow(d.te) * 100)
## [1] "新車購入予測精度:81.1%"
# 混同(こんどう)行列 (confusion matrix) caretパッケージ利用による詳細分析
library(caret)
confusionMatrix(data = as.factor(is.pred),
reference = as.factor(is.ref))
## Confusion Matrix and Statistics
##
## Reference
## Prediction FALSE TRUE
## FALSE 106 24
## TRUE 14 57
##
## Accuracy : 0.811
## 95% CI : (0.75, 0.863)
## No Information Rate : 0.597
## P-Value [Acc > NIR] : 7e-11
##
## Kappa : 0.599
##
## Mcnemar's Test P-Value : 0.144
##
## Sensitivity : 0.883
## Specificity : 0.704
## Pos Pred Value : 0.815
## Neg Pred Value : 0.803
## Prevalence : 0.597
## Detection Rate : 0.527
## Detection Prevalence : 0.647
## Balanced Accuracy : 0.794
##
## 'Positive' Class : FALSE
##
真陽性率(TPR)と偽陽性率(FPR)のトレードオフを表す曲線。 分類器としての性能はAUC(Area under the curve),つまり曲線下側面積の大きさで表される。 精度とは異なり,真陽性と偽陽性の確率値で表されるため,クラスのどちらかが大多数のときに生ずる問題がない。
2値判別の閾値(しきいち)は,確率50%のところに置くことが基本だが, ROC曲線を描くことにより,最適な閾値を求めることができる。 閾値が50%以外のときは,予測値には「確率」ではなく「判別スコア」という用語を使うこと。
library(pROC)
roc1 <- roc(response = d.te$購入判断, predict = p.hat,
of = 'thresholds', thresholds = 'best', print.thres = 'best',
percent = F, plot = T, print.auc = T, grid = T, ci = T, auc.polygon=T)
coords(roc1, 'best') # 最適閾値 (optimal threshold)
## threshold specificity sensitivity
## 1 0.31 0.77 0.9
c <- coords(roc1) # 閾値 (threshold)ごとの値 (sensitivity, specificity)
library(DT)
datatable(round(c, 3))
次のタイタニック号の乗船者データを用いてロジスティック回帰分析を行え。
また,次の問いに答えよ。
d0 <- read.csv(file = 'https://stats.dip.jp/01_ds/data/titanic_data_jp.csv')
datatable(d0)