LESSON

演習:アンサンブルとAutoMLで精度を追求しよう

田中VPoE:「ここまでの知識を総動員して、最高精度のモデルを構築してみよう。アンサンブル手法と AutoML を組み合わせて、離反予測の精度を限界まで引き上げてくれ。」

あなた:「Voting、Stacking、FLAML を試して、最も良い結果を採用します。」

田中VPoE:「精度だけでなく、SHAP で解釈性も確保すること。ビジネスに使えるモデルは精度と説明力の両方が必要だ。」

ミッション概要

アンサンブル手法と AutoML を活用して NetShop の離反予測モデルの精度を最大化し、SHAP による解釈性も確保します。


Mission 1: Voting と Stacking で精度を追求する

異なるモデルを組み合わせたアンサンブルを構築してください。

要件

  1. Soft Voting を構築する(3つ以上のモデル)
  2. Stacking を構築する(メタモデルはロジスティック回帰)
  3. 単体モデルとの精度差を比較する
from sklearn.ensemble import VotingClassifier, StackingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
import lightgbm as lgb
from xgboost import XGBClassifier

# ここにアンサンブルモデルのコードを書く
解答例
from sklearn.ensemble import VotingClassifier, StackingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
import lightgbm as lgb
from sklearn.model_selection import cross_val_score
from sklearn.metrics import f1_score
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.impute import SimpleImputer

# 前処理(Step 4 のデータを使用)
preprocessor = Pipeline([
    ('imputer', SimpleImputer(strategy='median')),
    ('scaler', StandardScaler()),
])

X_train_proc = preprocessor.fit_transform(X_train)
X_test_proc = preprocessor.transform(X_test)

# 個別モデル
models = {
    'LR': LogisticRegression(max_iter=1000, random_state=42),
    'RF': RandomForestClassifier(n_estimators=200, max_depth=10, random_state=42),
    'LightGBM': lgb.LGBMClassifier(n_estimators=200, learning_rate=0.1, random_state=42, verbose=-1),
    'XGBoost': XGBClassifier(n_estimators=200, learning_rate=0.1, random_state=42, eval_metric='logloss'),
}

# 個別モデルの評価
print("=== 個別モデル ===")
for name, model in models.items():
    scores = cross_val_score(model, X_train_proc, y_train, cv=5, scoring='f1')
    print(f"{name:10s}: F1 = {scores.mean():.3f} (+/- {scores.std():.3f})")

# Soft Voting
voting = VotingClassifier(
    estimators=list(models.items()),
    voting='soft',
    weights=[1, 2, 3, 3],
)
scores_voting = cross_val_score(voting, X_train_proc, y_train, cv=5, scoring='f1')
print(f"\n{'Voting':10s}: F1 = {scores_voting.mean():.3f} (+/- {scores_voting.std():.3f})")

# Stacking
stacking = StackingClassifier(
    estimators=list(models.items()),
    final_estimator=LogisticRegression(random_state=42),
    cv=5,
    stack_method='predict_proba',
)
scores_stacking = cross_val_score(stacking, X_train_proc, y_train, cv=5, scoring='f1')
print(f"{'Stacking':10s}: F1 = {scores_stacking.mean():.3f} (+/- {scores_stacking.std():.3f})")

# テストデータでの最終評価
voting.fit(X_train_proc, y_train)
stacking.fit(X_train_proc, y_train)

print(f"\n=== テストデータ評価 ===")
print(f"Voting F1:   {f1_score(y_test, voting.predict(X_test_proc)):.3f}")
print(f"Stacking F1: {f1_score(y_test, stacking.predict(X_test_proc)):.3f}")

Mission 2: FLAML で AutoML ベースラインと比較する

FLAML で自動モデル構築を行い、手動モデルとの精度差を確認してください。

要件

  1. FLAML を60秒の時間制約で実行する
  2. 最適モデルの種類とパラメータを確認する
  3. 手動構築モデルとの精度差を比較する
from flaml import AutoML

# ここに FLAML のコードを書く
解答例
from flaml import AutoML

automl = AutoML()

automl.fit(
    X_train_proc, y_train,
    task='classification',
    metric='f1',
    time_budget=60,
    eval_method='cv',
    n_splits=5,
    verbose=0,
)

print(f"=== FLAML 結果 ===")
print(f"最適モデル: {automl.best_estimator}")
print(f"CV F1スコア: {automl.best_loss * -1 if automl.best_loss else 'N/A'}")

y_pred_automl = automl.predict(X_test_proc)
automl_f1 = f1_score(y_test, y_pred_automl)
print(f"テスト F1: {automl_f1:.3f}")

# 全モデルの比較
print(f"\n=== 全モデル比較 ===")
all_results = {
    'Voting': f1_score(y_test, voting.predict(X_test_proc)),
    'Stacking': f1_score(y_test, stacking.predict(X_test_proc)),
    'FLAML': automl_f1,
}

for name, f1_val in sorted(all_results.items(), key=lambda x: x[1], reverse=True):
    print(f"{name:12s}: F1 = {f1_val:.3f}")

best_model_name = max(all_results, key=all_results.get)
print(f"\n最良モデル: {best_model_name}")

Mission 3: SHAP でモデルの解釈性を確保する

最良モデルに対して SHAP 分析を行い、ビジネス向けのレポートを作成してください。

要件

  1. SHAP 値を計算する
  2. グローバルな特徴量重要度を可視化する
  3. 離反リスクが高い顧客3人について個別の説明を生成する
  4. ビジネス向けのサマリーレポートを出力する
import shap

# ここに SHAP 分析のコードを書く
解答例
import shap
import matplotlib.pyplot as plt

# LightGBM 単体モデルで SHAP 分析(アンサンブルは直接 SHAP 適用が難しい)
lgbm_model = lgb.LGBMClassifier(n_estimators=200, learning_rate=0.1, random_state=42, verbose=-1)
lgbm_model.fit(X_train_proc, y_train)

# SHAP値の計算
explainer = shap.TreeExplainer(lgbm_model)
shap_values = explainer.shap_values(X_test_proc)

# グローバルな特徴量重要度
feature_names = [f"feature_{i}" for i in range(X_test_proc.shape[1])]
if hasattr(X_test, 'columns'):
    feature_names = list(X_test.columns)

print("=== SHAP ベース特徴量重要度 ===")
import numpy as np
mean_abs_shap = np.abs(shap_values[1]).mean(axis=0)
importance_shap = pd.Series(mean_abs_shap, index=feature_names)
importance_shap = importance_shap.sort_values(ascending=False)
for feat, imp in importance_shap.items():
    print(f"  {feat}: {imp:.4f}")

# 離反リスクが高い顧客の分析
y_prob_lgbm = lgbm_model.predict_proba(X_test_proc)[:, 1]
high_risk_idx = np.argsort(y_prob_lgbm)[-3:][::-1]

print(f"\n=== 離反リスクが高い顧客 TOP 3 ===")
for rank, idx in enumerate(high_risk_idx, 1):
    print(f"\n--- 顧客 #{rank} (離反確率: {y_prob_lgbm[idx]:.1%}) ---")
    effects = sorted(
        zip(feature_names, shap_values[1][idx]),
        key=lambda x: abs(x[1]), reverse=True,
    )
    for name, effect in effects[:5]:
        direction = "リスク上昇" if effect > 0 else "リスク低下"
        print(f"  {name}: {effect:+.3f} ({direction})")

# ビジネスサマリーレポート
print(f"\n{'='*60}")
print("=== ビジネスサマリーレポート ===")
print(f"{'='*60}")
print(f"モデル: LightGBM(F1スコア: {f1_score(y_test, lgbm_model.predict(X_test_proc)):.3f})")
print(f"テストデータ: {len(y_test)}人")
print(f"離反予測人数: {(y_prob_lgbm >= 0.5).sum()}人")
print(f"\n離反の主要因(SHAP分析より):")
for i, (feat, imp) in enumerate(importance_shap.head(3).items(), 1):
    print(f"  {i}. {feat}(重要度: {imp:.4f})")
print(f"\n推奨施策:")
print(f"  - 離反確率50%以上の顧客{(y_prob_lgbm >= 0.5).sum()}人にクーポン配布")
print(f"  - 離反確率30-50%の顧客{((y_prob_lgbm >= 0.3) & (y_prob_lgbm < 0.5)).sum()}人にフォローメール送信")

達成度チェック

  • Soft Voting と Stacking を構築し、精度を比較した
  • FLAML で AutoML を実行し、手動モデルと比較した
  • SHAP でグローバルな特徴量重要度を可視化した
  • 離反リスクが高い顧客の個別説明を生成した
  • ビジネス向けのサマリーレポートを作成した

推定所要時間: 60分