SHAPとは?機械学習モデルの予測結果を説明する手法をわかりやすく解説

目次

イントロダクション:「黒い箱」の問題

XGBoostやランダムフォレストなどの機械学習モデルは、素晴らしい特性を持っています。

高精度な予測ができる

例えば、鋼板の製造条件(温度・圧力・流量)を入力すると、完成後の強度を95%の精度で予測できます。

しかし同時に、大きな課題があります。

なぜその予測になったのか、分からない

例えば「この製品の強度は380 MPa」と予測されたとして、設計エンジニアは疑問を持ちます:

「なぜ380 MPaなの?」 「どの工程条件が強度に最も影響してるの?」 「もし温度を上げたら、どの程度強度が上がるの?」

この「予測精度は高いけど理由が分からない」という状況を、ブラックボックス問題 と呼びます。

そしてこの問題を解決するのが、本記事で解説する SHAP(SHapley Additive exPlanations) です。


SHAPとは何か

定義

SHAP は、機械学習モデルの予測結果に対して、各特徴量(入力変数)がどの程度貢献しているかを定量化する手法 です。

より詳しく言うと、以下が可能になります:

  • 個別の予測の理由を明確化:「この値が予測されたのはなぜか」を説明できる
  • 特徴量ごとの寄与度を数値化:温度は+20 MPa、圧力は+15 MPaなど、各要因の具体的な影響を定量化
  • 全体的な重要性を把握:全データを通じて、どの要因が最も影響力を持つかを判定
  • 要因の影響方向を判定:その要因が予測値を上げるのか下げるのか、を自動判定

SHAPの基本的な考え方:「ゲーム理論」

SHAPを理解するには、ゲーム理論 の簡単な考え方を知る必要があります。

ゲーム理論では、複数のプレイヤーが協力ゲームを行う際に「各プレイヤーが全体の成果にどれだけ貢献したか」を公平に配分する問題が出てきます。

具体例

3人でビジネスを始めた場合、利益を公平に分配したいとします。

  • A が参加した場合、利益は 100万円
  • B が参加した場合、利益は 80万円
  • C が参加した場合、利益は 60万円
  • A+B で参加した場合、利益は 250万円(相乗効果)
  • A+B+C で参加した場合、利益は 400万円

この時、「A の貢献度は幾ら?」「B の貢献度は幾ら?」を公平に計算するのが Shapley値 です。

機械学習への応用

SHAP は、この考え方を機械学習に応用したものです:

プレイヤー → 特徴量(温度、圧力、流量) ゲーム → 予測モデル 利益 → 予測値

つまり、「各特徴量が予測値(モデルの出力)に対してどれだけ貢献しているか」を、ゲーム理論的に公平に計算するということです。


SHAP値の基本:具体的な計算例

シンプルな例:強度予測モデル

以下の予測モデルが学習済みだとします:

温度(℃)圧力(kPa)流量(L/min)予測強度(MPa)
85010010380 ←今、このサンプルを説明したい
870958365
90012012420

ステップバイステップ計算

【基準値 (平均)】
温度、圧力、流量がすべて平均値の時の予測 = 350 MPa

【特徴量1:温度 = 850℃の影響】
• 温度だけが 850℃の場合の予測 = 356 MPa
• 温度の寄与度 = 356 - 350 = +6 MPa

【特徴量2:圧力 = 100 kPa の影響】
• 温度 + 圧力が実値の場合の予測 = 371 MPa
• 圧力の追加寄与度 = 371 - 356 = +15 MPa

【特徴量3:流量 = 10 L/min の影響】
• 温度 + 圧力 + 流量がすべて実値の場合 = 380 MPa
• 流量の追加寄与度 = 380 - 371 = +9 MPa

【最終計算】
基準値 + 温度の寄与 + 圧力の寄与 + 流量の寄与
= 350 + 6 + 15 + 9 = 380 MPa ✓

このように、各特徴量の寄与度を足し合わせると、予測値になる という性質が重要です。この性質を 加法的説明可能性(Additive Explainability) と呼びます。


特徴量重要度との決定的な違い

この点が、初心者が最も混同しやすいポイントです。

特徴量重要度(Feature Importance)の場合

特徴量重要度 は、「このモデルにおいて、全体的にどの特徴量が重要か」を示します。

XGBoostの feature_importance で得られるもので、例えば:

1. 温度:45%(最も重要)
2. 圧力:35%
3. 流量:20%

わかること:温度が最も重要 わからないこと:「具体的にどう影響しているのか」「この予測値に対しては温度がどれくらい効いているのか」

SHAP値の場合

SHAP値は、「このデータに対する個別の予測では、各特徴量がどう効いたか」 を示します。

【サンプルA】
基準値:350 MPa
• 温度 850℃:+6 MPa
• 圧力 100kPa:+15 MPa
• 流量 10L/min:+9 MPa
→ 予測値:380 MPa

【サンプルB】
基準値:350 MPa
• 温度 920℃:+40 MPa
• 圧力 80kPa:-5 MPa
• 流量 15L/min:+5 MPa
→ 予測値:390 MPa

わかること

  • 「サンプルAでは温度より圧力が効いている」
  • 「サンプルBでは温度が圧倒的に重要」
  • 「圧力80kPaはマイナス方向(強度低下)」
  • などなど、個別の詳細情報

直感的な比較

項目特徴量重要度SHAP値
知ること「全体的に何が重要か」「この予測では何が効いたか」
例えば温度が全体で45%重要サンプルAでは温度が+6の寄与
レベルグローバル(全体)ローカル(個別)
用途モデルの理解予測の説明

SHAP値の可視化:図で理解する

SHAP は単なる数値ではなく、複数の可視化方法があります。これが非常に強力です。

① Force Plot:個別予測の理由を矢印で表現

Force Plot では、「基準値からどの要因がどう動かしたか」が一目でわかります。

② Waterfall Plot:段階的な寄与を階段で表現

各ステップで「どの要因が、どれだけ加わったか」が視覚的にわかります。

③ Summary Plot:全データを通じた傾向を把握

特徴量重要度と色分けを組み合わせたプロット


XGBoostとSHAPの連携:実装フロー

実務では、通常以下のステップで使用します。

Step 1. XGBoostでモデルを構築

import xgboost as xgb
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split

# データ準備
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

# XGBoostモデル学習
model = xgb.XGBClassifier(max_depth=5, learning_rate=0.1, n_estimators=100)
model.fit(X_train, y_train)

# 予測精度確認
accuracy = model.score(X_test, y_test)
print(f"精度: {accuracy:.3f}")  # 例:0.965

Step 2. SHAP Explainerの準備

import shap

# TreeExplainer を初期化(XGBoost用)
explainer = shap.TreeExplainer(model)

# SHAP値を計算
shap_values = explainer.shap_values(X_test)

Step 3. 個別予測の理由を分析

# サンプルインデックス 0 の予測を分析
shap.force_plot(explainer.expected_value, 
                shap_values[0], 
                X_test.iloc[0])

Step 4. 全体傾向を可視化

# Summary Plot(全データを対象)
shap.summary_plot(shap_values, X_test)

# Waterfall Plot(個別サンプルの詳細)
shap.waterfall_plot(shap.Explanation(
    values=shap_values[0],
    base_values=explainer.expected_value,
    data=X_test.iloc[0]
))

製造業での実践的な活用例

例1:鋼板強度予測の要因分析

背景:強度が低い製品が一定数発生。原因を調べたい。

データ:過去1年間の製造データ500件

工程温度(℃)圧力(kPa)冷却速度(℃/min)強度(MPa)
8501002.1365
8801201.8405
810852.5320

XGBoost + SHAP の分析

不良品(強度320 MPa)についてSHAP分析すると:

基準値(平均強度):380 MPa
   ↓
工程温度 810℃:-25 MPa(負の寄与 ← 原因!)
圧力 85kPa:-10 MPa(負の寄与)
冷却速度 2.5℃/min:+10 MPa
   ↓
予測強度:320 MPa

結論:「温度が低すぎること」が強度低下の主原因と判定 → 工程条件を改善

例2:半導体ウェーハの不良判定

背景:クラス分類(良品/不良品)を行うモデルを構築。なぜ不良と判定されたのかを知りたい。

SHAP分析結果(不良と判定されたサンプル):

基準値(良品確率):72%
   ↓
膜厚 0.45μm:-15%(厚すぎる ← 不良原因)
ガス圧力 95Pa:-8%
温度 615℃:+5%
   ↓
予測:不良品確率 54%(← 不良と判定)

これにより、「膜厚が規格外」であることが不良判定の主要因と明確化。検査・改善プロセスに活かせます。

例3:燃料電池の発電効率予測

背景:セル温度、ガス流量、湿度などから発電効率を予測。効率を最大化するには何を改善すべきか。

全サンプルのSHAP Summary Plot 分析

セル温度:最も重要(赤と青が混在 ← 相互作用がある)
ガス流量:次に重要(赤寄り ← 高いほど効率UP)
相対湿度:負の寄与が多い ← 低いほど効率UP
圧力:弱い寄与

活用方法

  • セル温度を70℃に保つ ← 最も効率に影響
  • ガス流量を増やす ← 効率向上
  • 湿度を下げる ← 効率向上

このような最適化の優先順位が明確になります。


SHAP の実務的なメリット

✅ モデルの信頼度が上がる

「モデルが何を見ているか」が明確になるため、エンジニアやマネージャーが信頼しやすくなります。

「黒い箱がこう言ってるから」ではなく、「温度と圧力の組み合わせが強度に影響するから、このような予測結果になった」という説明ができます。

✅ 不具合の原因特定が容易

品質問題や不良が発生した時、「なぜ起きたのか」を SHAP で分析すると、改善すべき工程条件が明確になります。

✅ 設計最適化の優先順位が決まる

複数の改善案がある場合、SHAP で「どの特徴量が最も効果的か」が判定でき、限られたリソースを効率的に投下できます。

✅ ステークホルダーへの説明が簡単

Waterfall Plot や Force Plot などの図を見せると、非技術的な関係者でも「この予測が合理的だ」と理解できます。


SHAP のデメリットと限界

❌ 計算量が多い

SHAP値の計算は、モデルの複雑さに応じて計算時間がかかることがあります。

  • XGBoost の場合:比較的高速(TreeExplainer 使用)
  • ニューラルネットワークの場合:遅い場合がある
  • 大規模データセット + 複雑なモデル:かなり時間がかかる

対策

  • データ量を1000件程度に絞る
  • KernelExplainer など別の手法を検討

❌ 特徴量が多いと解釈が難しい

50個以上の特徴量がある場合、どの特徴量が重要かの判断が難しくなります。

対策

  • 事前に特徴量選択を実施(重要なものだけに絞る)
  • Summary Plot で上位10個だけ表示

❌ 因果関係を証明するものではない

SHAP値は「相関」を示すもので、「因果関係」を示すものではありません。

例えば「温度が高い日は強度が高い」という相関があっても、実は「季節が関係している」という別の因果関係かもしれません。

対策

  • 事前知識や実験により、因果関係の妥当性を確認
  • ドメイン知識とSHAPを組み合わせて解釈

SHAP と特徴量重要度をいつ使い分けるか

特徴量重要度を使う場面

  • 「このモデルは、全体的に何を見ているのか」を理解したい
  • モデルの構造や学習が正しいか、ざっくり確認したい

SHAP値を使う場面(おすすめ)

  • 個別の予測結果を説明したい ← 実務ではこれが圧倒的に多い
  • 不良品が出た時、原因を追跡したい
  • ステークホルダーに結果を説明する必要がある
  • 設計条件の最適化を検討している

Python での完全実装例:鋼板強度予測

import xgboost as xgb
import shap
import pandas as pd
from sklearn.model_selection import train_test_split

# 1. サンプルデータの準備
data = pd.DataFrame({
    'Temperature': [850, 880, 900, 820, 870, 910, 830, 890],
    'Pressure': [100, 120, 115, 95, 110, 125, 90, 105],
    'FlowRate': [10, 12, 11, 8, 10.5, 13, 7.5, 11],
    'Strength': [380, 415, 428, 365, 405, 435, 350, 410]
})

X = data[['Temperature', 'Pressure', 'FlowRate']]
y = data['Strength']

# 2. XGBoost モデル学習
model = xgb.XGBRegressor(max_depth=3, learning_rate=0.1, n_estimators=50)
model.fit(X, y)

# 3. SHAP の準備
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X)

# 4. 個別予測の説明(最初のサンプル)
print("=== サンプル0 の予測説明 ===")
print(f"実際の強度: {y.iloc[0]} MPa")
print(f"予測値: {model.predict(X)[0]:.1f} MPa")
print(f"基準値(平均): {y.mean():.1f} MPa")
print()
print("各特徴量の寄与:")
for i, col in enumerate(X.columns):
    contribution = shap_values[0, i]
    actual_value = X.iloc[0, i]
    print(f"  {col} ({actual_value}): {contribution:+.1f} MPa")

# 5. Force Plot で可視化
shap.force_plot(explainer.expected_value, 
                shap_values[0], 
                X.iloc[0],
                feature_names=X.columns.tolist())

# 6. Summary Plot(全サンプルの傾向)
shap.summary_plot(shap_values, X, feature_names=X.columns.tolist())

実行結果の例

=== サンプル0 の予測説明 ===
実際の強度: 380 MPa
予測値: 382.5 MPa
基準値(平均): 398.9 MPa

各特徴量の寄与:
  Temperature (850): -18.2 MPa
  Pressure (100): -8.5 MPa
  FlowRate (10): +10.3 MPa

XGBoost と SHAP を使った実務フロー

段階1:モデル構築(1~2週間)

  1. データ収集・前処理
  2. XGBoost で学習
  3. テストデータで精度確認

段階2:解釈・分析(1週間)

  1. 特徴量重要度で大まかな傾向を把握
  2. SHAP で個別事例を詳細分析
  3. ドメイン知識と照合して妥当性確認

段階3:現場への説明・導入(1週間)

  1. Waterfall Plot や Force Plot で視覚的に説明
  2. 「なぜこの予測か」を明確化
  3. 設計改善や工程最適化に活かす

段階4:運用・改善(継続的)

  1. 定期的に新データで再学習
  2. 変化していないか、SHAP で監視
  3. 必要に応じて特徴量や閾値を修正

よくある質問

Q1. SHAPの計算時間が長い場合は?

A. TreeExplainer(XGBoost用)であれば最も高速です。それでも遅い場合は、データを1000件程度にサンプリングするか、sampling 引数を使って計算量を削減できます。

Q2. 特徴量が50個以上ある場合、どうすればいい?

A. まず特徴量選択(特徴量重要度で上位20個に絞る)を行ってから SHAP を適用するのがおすすめです。

Q3. 負の寄与度がある場合、その要因を改善すべき?

A. いいえ。SHAP は相関を示すだけなので、因果関係は別途確認が必要です。例えば「湿度が高い→発電効率が低い」という相関でも、実は「季節が関連している」かもしれません。

Q4. SHAPは回帰問題と分類問題の両方で使える?

A. はい。どちらでも使えます。回帰は数値予測の理由、分類はクラス予測の理由を説明できます。


競合手法との比較

手法計算速度解釈性理論的妥当性XGBoost連携
特徴量重要度⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
SHAP(TreeExplainer)⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐◎◎◎
LIME⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Permutation重要度⭐⭐⭐⭐⭐⭐⭐⭐⭐

結論:XGBoost を使う場合、SHAP(特に TreeExplainer)が最強です。


まとめ

SHAPの核になる考え方

SHAP は、ゲーム理論の Shapley値を機械学習に応用 したもので、以下を実現します:

個別の予測を説明できる:「なぜこの値が予測されたのか」を定量的に示す
特徴量の寄与を可視化できる:Force Plot、Waterfall Plot などで直感的に理解できる
全体傾向も把握できる:Summary Plot で全データを通じた傾向を分析できる
XGBoostとの相性が最高:TreeExplainer で高速に計算可能

製造業での活用

  • 品質予測モデルの説明:「予測精度95%、理由も明確」という信頼度の高い導入
  • 不良原因の追跡:「なぜこの製品は不合格か」を数値と図で説明
  • 設計最適化:「温度を上げたらこれくらい強度が上がる」という予測ベースの最適化
  • ステークホルダー説明:経営層にも理解しやすい形で結果報告

次のステップ

  1. XGBoost でモデルを構築する
  2. SHAP で個別事例を分析する
  3. Waterfall Plot で関係者に説明する
  4. 設計・工程改善に活かす

このサイクルを回すことで、データドリブンな設計・製造が実現できます。


関連記事・参考

Optunaとは?Pythonでベイズ最適化を実装する方法をわかりやすく解説

XGBoostとは?製造業のデータ分析で人気の機械学習手法をわかりやすく解説

ベイズ最適化とは?少ない実験回数で最適条件を見つける手法を解説

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次