LESSON

モデル解釈性

田中VPoE:「精度の高いモデルができても、『なぜこの顧客が離反すると予測されたのか?』を説明できなければ、ビジネス側は納得しない。マーケティングチームに施策を提案するには、予測の根拠が必要だ。」

あなた:「ブラックボックスのままでは使えないということですね。」

田中VPoE:「そうだ。SHAP を使えば、各特徴量がどの程度予測に寄与しているかを可視化できる。」

SHAP(SHapley Additive exPlanations)

ゲーム理論に基づく特徴量の寄与度を算出する手法です。

import shap

# LightGBM モデルの場合
model = lgbm_pipeline.named_steps['model']
X_test_processed = lgbm_pipeline.named_steps['preprocessor'].transform(X_test)

# SHAP値の計算
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X_test_processed)

# 全体の特徴量重要度(SHAP ベース)
shap.summary_plot(shap_values[1], X_test_processed,
                  feature_names=feature_names, plot_type='bar')

個別の予測の説明

# 特定の顧客の予測理由を説明
customer_idx = 0
shap.force_plot(
    explainer.expected_value[1],
    shap_values[1][customer_idx],
    X_test_processed[customer_idx],
    feature_names=feature_names,
)

# テキストでの説明
print(f"顧客 {customer_idx} の離反確率: {y_prob[customer_idx]:.3f}")
print("\n予測に影響した要因:")
feature_effects = list(zip(feature_names, shap_values[1][customer_idx]))
feature_effects.sort(key=lambda x: abs(x[1]), reverse=True)
for name, effect in feature_effects[:5]:
    direction = "離反方向" if effect > 0 else "継続方向"
    print(f"  {name}: {effect:+.3f} ({direction})")

SHAP Summary Plot

# 各特徴量がどのように予測に影響するかの全体像
shap.summary_plot(shap_values[1], X_test_processed,
                  feature_names=feature_names)

LIME(Local Interpretable Model-agnostic Explanations)

個別予測の局所的な説明を生成する手法です。

import lime
import lime.lime_tabular

explainer_lime = lime.lime_tabular.LimeTabularExplainer(
    X_train_processed,
    feature_names=feature_names,
    class_names=['継続', '離反'],
    mode='classification',
)

# 特定の顧客の説明
exp = explainer_lime.explain_instance(
    X_test_processed[0],
    model.predict_proba,
    num_features=10,
)

exp.show_in_notebook()
print(exp.as_list())

Partial Dependence Plot(PDP)

特定の特徴量がモデルの予測にどう影響するかを可視化します。

from sklearn.inspection import PartialDependenceDisplay

fig, axes = plt.subplots(1, 3, figsize=(18, 5))

features_to_plot = ['days_inactive', 'purchase_count', 'support_tickets']
for ax, feature in zip(axes, features_to_plot):
    PartialDependenceDisplay.from_estimator(
        model, X_test_processed,
        features=[feature_names.index(feature)],
        feature_names=feature_names,
        ax=ax,
    )
    ax.set_title(f'{feature} の影響')

plt.tight_layout()
plt.show()

ビジネスへの説明テンプレート

def generate_churn_report(customer_data, shap_values, feature_names, threshold=0.5):
    """離反リスクレポートの生成"""
    prob = model.predict_proba(customer_data.reshape(1, -1))[0][1]

    report = f"""
    === 離反リスクレポート ===
    離反確率: {prob:.1%}
    リスクレベル: {'高' if prob > 0.7 else '中' if prob > threshold else '低'}

    主な要因:
    """

    effects = sorted(zip(feature_names, shap_values),
                    key=lambda x: abs(x[1]), reverse=True)

    for name, effect in effects[:3]:
        direction = "リスク上昇" if effect > 0 else "リスク低下"
        report += f"  - {name}: {direction}(寄与度: {abs(effect):.3f}\n"

    return report

print(generate_churn_report(X_test_processed[0], shap_values[1][0], feature_names))

まとめ

  • SHAP: 理論的に正しい特徴量寄与度を算出(最も推奨)
  • LIME: 個別予測の局所的な説明を生成
  • PDP: 特徴量と予測の関係を可視化
  • モデルの解釈性はビジネスへの説明と信頼獲得に不可欠

チェックリスト

  • SHAP の基本的な使い方を理解した
  • 個別予測の説明方法を把握した
  • ビジネス向けのレポート生成を理解した

次のステップへ

次は演習です。アンサンブルと AutoML を使って精度を追求してみましょう。


推定読了時間: 15分