不均衡データ - ROC曲線欠点の実装例
目次:
はじめに
前回はROC AUCの欠点に関して少し言及しましたが、
今回は実装例に基づいて、ROC曲線が不均衡データ(imbalanced data)に対して簡単に0.90+上がってしまうという欠点に関して説明していきたいと思います。
必要なライブラリ:
import numpy as np import matplotlib.pyplot as plt from sklearn.datasets import make_classification from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split from sklearn.metrics import roc_curve from sklearn.metrics import roc_auc_score from sklearn.metrics import classification_report
不均衡データ:Positiveは少数クラスの場合
例
10000個の疑似データが約0 : 1 = 0.95 : 0.05の割合で生成されます(ノイズ含む):
X, y = make_classification(n_samples=10000, n_classes=2, weights=[0.95,0.05], random_state=42) trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.2, random_state=2)
LogisticRegressionで学習します:
model = LogisticRegression() model.fit(trainX, trainy)
プロットします:
probs = model.predict_proba(testX) probs = probs[:, 1] fpr, tpr, thresholds = roc_curve(testy, probs) plt.plot([0, 1], [0, 1], linestyle='--', label="random") plt.plot(fpr, tpr, marker='.', label="LR") plt.xlabel("False Positive Rate") plt.ylabel("True Positive Rate") plt.show() auc_score = roc_auc_score(testy, probs) print('AUC: %.3f' % auc_score)
AUC:0.920 ! めちゃ良いモデルと思われがちですが、実はそうではない:
predictions = model.predict(testX)
print(classification_report(testy, predictions))
少数クラスのrecallとf1_scoreわずか0.4, 0.5くらいものです!!!
不均衡データ:Negativeは少数クラスの場合
同様に、
例
10000個の疑似データが約0 : 1 = 0.05 : 0.95の割合で生成されます(ノイズ含む):
X, y = make_classification(n_samples=10000, n_classes=2, weights=[0.05,0.95], random_state=42) trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.2, random_state=2)
LogisticRegressionで学習します:
model = LogisticRegression() model.fit(trainX, trainy)
プロットします:
probs = model.predict_proba(testX) probs = probs[:, 1] fpr, tpr, thresholds = roc_curve(testy, probs) plt.plot([0, 1], [0, 1], linestyle='--', label="random") plt.plot(fpr, tpr, marker='.', label="LR") plt.xlabel("False Positive Rate") plt.ylabel("True Positive Rate") plt.show() auc_score = roc_auc_score(testy, probs) print('AUC: %.3f' % auc_score)
AUC:0.895 !
predictions = model.predict(testX)
print(classification_report(testy, predictions))
少数クラスのrecallとf1_scoreわずか0.4, 0.5くらい!
というわけで、不均衡データの分類モデルを評価する際に、絶対ROC_AUC曲線を信じちゃダメです〜それより評価指標としてMCCやF1_scoreの方が良いです。
次回は不均衡データにも適切に評価できるマシューズ相関係数(Matthews Correlation Coefficient)とF1_scoreについて紹介と比較したいと思います、ぜひご覧ください: