データセットから検知モデルへ

Rで学ぶ不正検知

Sebastiaan Höppner

PhD researcher in Data Science at KU Leuven

ロードマップ

  • (1) データを 学習用テスト用 に分割
  • (2) 機械学習の モデル選択
  • (3) 学習用に SMOTE 適用(クラス分布を調整)
  • (4) 調整後データで モデル学習
  • (5) (元の)テスト用で 性能評価
Rで学ぶ不正検知

データを学習用・テスト用に分割

  • データセットを 学習用テスト用 に分割(例: 50/50, 75/25 など)
  • まずは両集合でクラス分布を同一に保つ
  • 例: 学習50%、テスト50%
prop.table(table(train$Class))
   0    1 
0.98 0.02
prop.table(table(test$Class))
   0    1 
0.98 0.02
Rで学ぶ不正検知

機械学習モデルの選択と学習

  • 決定木、人工ニューラルネット、SVM、ロジスティック回帰、ランダムフォレスト、ナイーブベイズ、k近傍 など
  • 例: Classification And Regression Tree(CART)アルゴリズム
  • rpart パッケージの関数 rpart
library(rpart)

model1 = rpart(Class ~ ., data = train)
Rで学ぶ不正検知
library(partykit)
plot(as.party(model1))

tree1

Rで学ぶ不正検知
## テスト集合の不正確率を予測
scores1 = predict(model1, newdata = test, type = "prob")[, 2]

## テスト集合のクラス(不正/非不正)を予測 predicted_class1 = factor(ifelse(scores1 > 0.5, 1, 0))
## 混同行列と正解率 library(caret) CM1 = confusionMatrix(data = predicted_class1, reference = test$Class)
          Reference         
Prediction     0     1
         0 12046    55
         1     8   191       Accuracy : 0.994878
library(pROC)
auc(roc(response = test$Class, predictor = scores1)) ## ROC 曲線下面積 (AUC)
Area under the ROC curve: 0.8938
Rで学ぶ不正検知

SMOTE を学習用データに適用

library(smotefamily)
set.seed(123)

smote_result = SMOTE(X = train[, -17],
                     target = train$Class,
                     K = 5,
                     dup_size = 10)

train_oversampled = smote_result$data colnames(train_oversampled)[17] = "Class"
prop.table(table(train_oversampled$Class))
        0         1 
0.8166667 0.1833333
Rで学ぶ不正検知
library(rpart)
model2 = rpart(Class ~ ., data = train_oversampled)

tree2

Rで学ぶ不正検知
## テスト集合の不正確率を予測
scores2 = predict(model2, newdata = test, type = "prob")[, 2]

## テスト集合のクラス(不正/非不正)を予測 predicted_class2 = factor(ifelse(scores2 > 0.5, 1, 0))
## 混同行列と正解率 library(caret) CM2 = confusionMatrix(data = predicted_class2, reference = test$Class)
          Reference
Prediction     0     1
         0 11967    34
         1    87   212       Accuracy : 0.9901626                                
library(pROC)
auc(roc(response = test$Class, predictor = scores2)) ## ROC 曲線下面積 (AUC)
Area under the curve: 0.9538
Rで学ぶ不正検知

検知モデル導入のコスト

  • アルゴリズム評価では、不正検知のコスト を考慮する
  • コストは以下に紐づく
    • 誤分類(偽陽性・偽陰性)
    • 正分類(真陽性・真陰性)
Rで学ぶ不正検知

コスト行列

コスト行列1

  • $y_i$ = 事例 $i$ の真のクラス
  • $c_i$ = 事例 $i$ の予測クラス
Rで学ぶ不正検知

コスト行列

コスト行列2

  • $y_i$ = 事例 $i$ の真のクラス
  • $c_i$ = 事例 $i$ の予測クラス
Rで学ぶ不正検知

コスト行列

コスト行列3

  • $C_a$ = 事例分析のコスト
Rで学ぶ不正検知

コスト行列

コスト行列4

  • $C_a$ = 事例分析のコスト
Rで学ぶ不正検知

検知モデルのコスト指標

  • 各事例の実コストを考慮: $$Cost(model)=\sum_{i=1}^{N}y_i(1-c_i)Amount_i + c_iC_a$$
    • $y_i$ = 事例 $i$ の真のクラス
    • $c_i$ = 事例 $i$ の予測クラス
cost_model = function(predicted.classes, true.classes, amounts, fixedcost) {

    cost = sum(true.classes * (1 - predicted.classes) * amounts +
               predicted.classes * fixedcost)

    return(cost)
}
Rで学ぶ不正検知

不正検知の真のコスト

## SMOTE 未使用の総コスト:
cost_model(predicted_class1, test$Class, test$Amount, fixedcost = 10)
10061.8
## SMOTE 使用時の総コスト:
cost_model(predicted_class2, test$Class, test$Amount, fixedcost = 10)
7431.93
  • 損失は 26% 減少!
Rで学ぶ不正検知

Let's practice!

Rで学ぶ不正検知

Preparing Video For Download...