LESSON

ベースラインモデル構築

「EDAと前処理が完了した。いよいよモデル構築だ。」

田中VPoEが満足げにうなずく。

「まずはベースラインモデルを立てろ。いきなり複雑なモデルに飛びつくな。シンプルなモデルで基準を作り、そこから改善していく。これが実務のML開発だ。」

ベースラインモデルの重要性

ベースラインモデルの目的:
1. 性能の下限を確立する → これ以上は改善が必要
2. データの予測可能性を確認する → そもそも予測できるか
3. 特徴量の有効性を検証する → どの特徴量が効いているか
4. 比較基準を提供する → 複雑なモデルの改善幅を評価

評価指標の選定

離反予測では、Accuracy(正解率)だけでは不十分。不均衡データに適した指標を選ぶ。

主要指標

指標計算方法用途
AUC-ROCROC曲線下面積閾値非依存の全体的な識別能力
PR-AUCPrecision-Recall曲線下面積少数クラス(離反)の予測精度
F1-Score2×Precision×Recall/(P+R)精度と再現率のバランス
RecallTP/(TP+FN)離反者の見逃し率(重要)
PrecisionTP/(TP+FP)離反予測の的中率

離反予測における指標の優先順位

離反予測での優先順位:
1. AUC-ROC → 主指標(全体の識別能力)
2. Recall  → 離反者を見逃さないことが重要
3. PR-AUC  → 不均衡データでの性能
4. F1      → バランス指標
5. Precision → 介入コストとのトレードオフ

ロジスティック回帰によるベースライン

import pandas as pd
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import (
    roc_auc_score, average_precision_score,
    classification_report, confusion_matrix
)
import matplotlib.pyplot as plt

# 前処理済みデータの読み込み(Step 2で構築済み)
# X_train, X_val, X_test, y_train, y_val, y_test

# ベースラインモデル: ロジスティック回帰
baseline_model = LogisticRegression(
    max_iter=1000,
    random_state=42,
    class_weight='balanced'  # 不均衡対策
)
baseline_model.fit(X_train, y_train)

# 予測
y_val_pred = baseline_model.predict(X_val)
y_val_proba = baseline_model.predict_proba(X_val)[:, 1]

# 評価
print("=== ベースラインモデル(ロジスティック回帰)===")
print(f"AUC-ROC: {roc_auc_score(y_val, y_val_proba):.4f}")
print(f"PR-AUC:  {average_precision_score(y_val, y_val_proba):.4f}")
print(f"\n{classification_report(y_val, y_val_pred)}")

期待される結果

指標期待値備考
AUC-ROC0.82-0.85ベースラインとして十分
PR-AUC0.60-0.65不均衡を考慮すると妥当
F1-Score0.55-0.60class_weightで改善
Recall0.75-0.80離反者の検出率

混同行列の分析

from sklearn.metrics import ConfusionMatrixDisplay

cm = confusion_matrix(y_val, y_val_pred)
print("混同行列:")
print(f"  TN={cm[0,0]} FP={cm[0,1]}")
print(f"  FN={cm[1,0]} TP={cm[1,1]}")

# ビジネス観点での解釈
print(f"\n離反者の見逃し(FN): {cm[1,0]}人")
print(f"誤検知(FP): {cm[0,1]}人")
print(f"→ FN×離反コスト vs FP×介入コスト のトレードオフ")

disp = ConfusionMatrixDisplay(cm, display_labels=['Non-Churn', 'Churn'])
disp.plot(cmap='Blues')
plt.title('混同行列 - ベースラインモデル')
plt.savefig('baseline_confusion_matrix.png', dpi=150)

特徴量の重要度(係数)

# ロジスティック回帰の係数を確認
feature_importance = pd.DataFrame({
    'feature': X_train.columns,
    'coefficient': baseline_model.coef_[0]
}).sort_values('coefficient', ascending=False)

print("離反に正の影響(離反しやすい):")
print(feature_importance.head(10).to_string(index=False))
print("\n離反に負の影響(離反しにくい):")
print(feature_importance.tail(10).to_string(index=False))

class_weightの効果

# class_weightなし
model_no_weight = LogisticRegression(max_iter=1000, random_state=42)
model_no_weight.fit(X_train, y_train)
y_pred_no_weight = model_no_weight.predict(X_val)
y_proba_no_weight = model_no_weight.predict_proba(X_val)[:, 1]

print("class_weightなし:")
print(f"  AUC-ROC: {roc_auc_score(y_val, y_proba_no_weight):.4f}")
print(f"  Recall:  {(confusion_matrix(y_val, y_pred_no_weight)[1,1] / y_val.sum()):.4f}")

print("\nclass_weight='balanced':")
print(f"  AUC-ROC: {roc_auc_score(y_val, y_val_proba):.4f}")
print(f"  Recall:  {(cm[1,1] / y_val.sum()):.4f}")
# → class_weightでRecallが大幅に改善

まとめ

項目ポイント
ベースラインモデルロジスティック回帰 + class_weight=‘balanced’
主指標AUC-ROC(全体の識別能力)
補助指標Recall(離反者の見逃し防止)
ベースライン性能AUC-ROC: 0.82-0.85
特徴量分析係数の大きさで重要度を確認

チェックリスト

  • ベースラインモデルの目的を説明できる
  • 離反予測に適した評価指標を選定できる
  • ロジスティック回帰でベースラインを構築できる
  • 混同行列をビジネス観点で解釈できる
  • class_weightの効果を理解した

次のステップへ

ベースラインが確立できた。次は決定木やアンサンブルモデルを使って、さらなる性能向上を目指そう。

推定読了時間: 30分