02.9.1
SHAP
shap ライブラリの TreeExplainer は XGBoost / LightGBM / ランダムフォレストの木構造を使って、この平均を近似なしに高速に計算します。このページでは乳がんデータに当てた XGBClassifier を解釈し、全体の傾向を見る beeswarm、1 件の内訳を見る waterfall、交互作用を見る scatter の 3 つの図の読み方を確かめます。TreeExplainer は木の分割を 1 本ずつたどって SHAP 値を計算するので、決定木分類器 が「特徴量の閾値で枝分かれして葉の値を返す」仕組みを先に押さえておくと、なぜ木モデルだけ高速に計算できるのかが分かります。
直感 #
5 人でプロジェクトを完遂して 100 万円の報酬を得たとき、「誰がどれだけ貢献したか」を公平に分けるのが Shapley 値の考え方です。ある人の取り分は、「その人がいないチームの成果」と「その人を加えたチームの成果」の差を、加わる順番のすべてのパターン(5 人なら 120 通り)で平均したものにします。SHAP の貢献者は特徴量です。これを機械学習に応用し、1 件の予測に対して「各特徴量がどれだけ予測値を押し上げ(下げ)たか」を配ります。基準値は全データの平均予測で、たとえば悪性確率の平均が 0.37 の患者データに worst radius が +0.30、mean texture が −0.05 ……と足していくと、その患者の予測値 0.85 にぴったり届きます。すべての特徴量の SHAP 値を合計すると必ずモデルの出力と一致する、この加法性が SHAP を他の重要度と分ける性質です。
Python で確かめる #
乳がん診断データ(569 件、30 特徴)に XGBClassifier を学習します。その後 shap.TreeExplainer で 114 件のテストデータの SHAP 値を計算し、beeswarm・waterfall・scatter の 3 種類の図で読みます。
ライブラリとデータ #
| |
モデル学習と SHAP 値の計算 #
深さ 4 の木 100 本の XGBoost を学習します。続けて TreeExplainer を作り、テストデータ 114 件 × 30 特徴、合計 3420 個の SHAP 値を一度に計算します。
| |
グローバル解釈 — Summary Plot #
3420 個の SHAP 値を 1 枚に重ねます。モデル全体でどの特徴量がどの向きに効いているかを見るグローバル解釈の図です。
| |
ローカル解釈 — Waterfall Plot #
テストデータの 1 件目について、基準値から予測値までを 30 個の特徴量がどう押し上げ・押し下げたかを滝のように積み上げて表示します。
| |
特徴量間の相互作用 #
worst radius の値を横軸、その SHAP 値を縦軸にした散布図で、半径が予測に効く形を見ます。点の色は、worst radius と最も交互作用の強い別の特徴量の値です。
| |
まとめ #
SHAP は 1 件の予測を「基準値 + 各特徴量の SHAP 値」に分解し、配分には特徴量を加える全順序で増分を平均した Shapley 値を使うので、30 個の値を足すと必ず予測値に一致します。木モデルなら shap.TreeExplainer(model)(X_test) で 114 件 × 30 特徴の値が 1 秒以内に出ます。beeswarm は全件を重ねて「どの特徴量がどの向きに効くか」のグローバルな傾向を、waterfall は 1 件の内訳を、scatter は 1 特徴量の効き方の形と交互作用の相手を見せます。feature_importances_ が「平均してどれが重要か」しか答えないのに対し、SHAP は「この患者ではなぜ悪性と予測したか」に答えられる点が、実務で説明を求められたときの強みです。
使い分けのポイント #
| 手法 | 解釈レベル | 計算コスト | モデル依存 |
|---|---|---|---|
| TreeExplainer | グローバル/ローカル | 低(木モデル専用) | Yes |
| KernelExplainer | グローバル/ローカル | 高(汎用) | No |
| LinearExplainer | グローバル/ローカル | 低(線形モデル専用) | Yes |
- PDP / ICE プロット — 1 列を動かしたときの予測の平均をなぞる、SHAP の scatter と対になる可視化
- XGBoost — このページで解釈したモデル
- LightGBM — TreeExplainer で高速に解釈可能