評価指標
田中VPoE:「モデルの精度が95%です!と言われたら、良いモデルだと思うか?」
あなた:「95%なら十分高いと思いますが…。」
田中VPoE:「ところが、もし顧客の95%が離反しないデータだったら、『全員離反しない』と予測するだけで95%の正解率が出る。それでは離反予測として全く意味がない。評価指標の選び方を間違えると、こういう罠にハマる。」
正解率(Accuracy)の落とし穴
正解率 = 正しく予測できた数 / 全データ数
# 離反率5%のデータで「全員離反しない」と予測
import numpy as np
y_true = np.array([0]*950 + [1]*50) # 5%が離反
y_pred = np.array([0]*1000) # 全員「離反しない」と予測
accuracy = (y_true == y_pred).mean()
print(f"正解率: {accuracy:.1%}") # 95.0%
# → 高い正解率だが、離反者を1人も見つけられていない
不均衡データでは正解率だけで判断してはいけません。
混同行列(Confusion Matrix)
予測結果を4つのカテゴリに分類します。
予測: 離反しない(0) 予測: 離反する(1)
実際: 離反しない(0) TN FP
実際: 離反する(1) FN TP
| 略称 | 名称 | 意味 |
|---|---|---|
| TP | True Positive | 離反を正しく予測 |
| TN | True Negative | 継続を正しく予測 |
| FP | False Positive | 継続なのに離反と誤予測(偽陽性) |
| FN | False Negative | 離反なのに継続と誤予測(偽陰性) |
from sklearn.metrics import confusion_matrix, classification_report
y_true = [0, 1, 0, 1, 0, 0, 1, 0, 1, 0]
y_pred = [0, 1, 0, 0, 0, 1, 1, 0, 0, 0]
cm = confusion_matrix(y_true, y_pred)
print("混同行列:")
print(cm)
print("\n分類レポート:")
print(classification_report(y_true, y_pred,
target_names=['継続', '離反']))
主要な評価指標
適合率(Precision)
「離反と予測した中で、実際に離反した割合」
Precision = TP / (TP + FP)
- 高いほど: 無駄なクーポン配布が減る
- 低いと: 離反しない顧客にもクーポンを配ってコスト増
再現率(Recall)
「実際の離反者のうち、正しく予測できた割合」
Recall = TP / (TP + FN)
- 高いほど: 離反者の見逃しが減る
- 低いと: 離反者を見逃して顧客を失う
F1スコア
適合率と再現率の調和平均。両方のバランスを取る指標です。
F1 = 2 * (Precision * Recall) / (Precision + Recall)
from sklearn.metrics import precision_score, recall_score, f1_score
precision = precision_score(y_true, y_pred)
recall = recall_score(y_true, y_pred)
f1 = f1_score(y_true, y_pred)
print(f"適合率: {precision:.3f}")
print(f"再現率: {recall:.3f}")
print(f"F1スコア: {f1:.3f}")
AUC-ROC
モデルの閾値に依存しない総合的な性能指標です。
from sklearn.metrics import roc_auc_score, roc_curve
import matplotlib.pyplot as plt
# 予測確率が必要
y_prob = model.predict_proba(X_test)[:, 1]
auc = roc_auc_score(y_test, y_prob)
fpr, tpr, thresholds = roc_curve(y_test, y_prob)
plt.figure(figsize=(8, 6))
plt.plot(fpr, tpr, label=f'AUC = {auc:.3f}')
plt.plot([0, 1], [0, 1], 'k--', label='ランダム')
plt.xlabel('偽陽性率 (FPR)')
plt.ylabel('真陽性率 (TPR)')
plt.title('ROC曲線')
plt.legend()
plt.grid(True)
plt.show()
- AUC = 1.0: 完璧な分類
- AUC = 0.5: ランダムと同等
- AUC > 0.8: 一般的に良好
ビジネス指標との対応
| ビジネスの関心 | 重視すべき指標 | 理由 |
|---|---|---|
| 離反者を見逃したくない | 再現率 | FN(見逃し)を減らす |
| クーポンコストを抑えたい | 適合率 | FP(無駄な配布)を減らす |
| バランスよく予測したい | F1スコア | Precision と Recall の調和 |
| モデルの総合力を見たい | AUC-ROC | 閾値に依存しない評価 |
NetShop の場合、顧客の離反は大きな損失につながるため、再現率を重視しつつ F1スコアで総合評価する方針が適切です。
まとめ
- 不均衡データでは正解率だけで判断してはいけない
- 混同行列で TP/TN/FP/FN を把握する
- 適合率は「予測の正確さ」、再現率は「見逃しの少なさ」
- F1スコアは両者の調和平均
- AUC-ROC は閾値に依存しない総合指標
- ビジネス目的に応じて重視する指標を選ぶ
チェックリスト
- 正解率の落とし穴を説明できる
- 混同行列の4つのセルの意味を理解した
- 適合率・再現率・F1スコアの違いを説明できる
- ビジネス目的に応じた指標選択ができる
次のステップへ
次は演習です。NetShop のビジネス課題を ML 問題として設計し、適切な評価指標を選択する実践に取り組みましょう。
推定読了時間: 30分