SHAPについての簡単な説明
SHAPは学習済み機械学習モデルの解釈を行うための指標のひとつで、協力ゲーム理論のシャープレイ値の考え方を用いて、モデルの予測した値に対して、「特徴量がどのように寄与して算出されたのか」を示す値となっています。
ジニ係数やgain(目的変数の減少)などで求める特徴量重要度はモデル1つに対し1組だけ定まる値となっていますが、SHAPはモデルと1つのデータサンプルについて定まる値であり、ひとつひとつのサンプルについて考察を行うことができる点で便利な方法となっています。
Pythonのライブラリが存在しており、簡単に算出できる値となっています。実装については以下の記事が参考になります。
直面した問題
先日、改めてSHAPのドキュメントを見返していたところ自分が使っているTreeExplainerモジュールのパラメータにdataという引数があることに気がつきました。デフォルトの設定では「data = None」となっており、自身のコードでも特に設定はしておらずそのままになっていました。
そこで試しに、dataに訓練データやテストデータを入れてSHAPの算出を行なったところ、変更前とは異なる結果が出力されてしまいました!
QiitaのpythonでSHAPを実装している他の記事のコードを見ると、多くのコードでは「data」が指定されていましたが特にそのパラメータに関する言及はなく、なぜ結果が変わってしまうのかを疑問に感じました。
今回はこの疑問を解消すべく調査を行なった結果を共有できればと思います。
行なったこと
以下の2つを行って疑問の解消を図りました。
① 公式ドキュメントの確認
② ChatGPTとの対話
※ 今回の結果には不確実な要素が含まれる可能性がありますのでご了承ください。
① 公式ドキュメントの確認
公式ドキュメントのTreeExplainer
https://shap-lrjball.readthedocs.io/en/latest/generated/shap.TreeExplainer.html
「data」パラメータの説明は以下です。
The background dataset to use for integrating out features. This argument is optional when feature_perturbation=”tree_path_dependent”, since in that case we can use the number of training samples that went down each tree path as our background dataset (this is recorded in the model object).
ここから下の2つのことがわかります。
- バックグラウンドデータ(data)は特徴量の統合のために使用される
- 「feature_perturbation」というパラメータが「tree_path_dependance」のとき、このパラメータは省略可能である。その理由は訓練サンプルをバックグラウンドデータと使用できるため
ここで新たなパラメータ「feature_perturbation」が出てきました。このパラメータの説明も見てみます。
Since SHAP values rely on conditional expectations we need to decide how to handle correlated (or otherwise dependent) input features. The “interventional” approach breaks the dependencies between features according to the rules dictated by casual inference (Janzing et al. 2019). Note that the “interventional” option requires a background dataset and its runtime scales linearly with the size of the background dataset you use. Anywhere from 100 to 1000 random background samples are good sizes to use. The “tree_path_dependent” approach is to just follow the trees and use the number of training examples that went down each leaf to represent the background distribution. This approach does not require a background dataset and so is used by default when no background dataset is provided.
ここから下の2つのことがわかります。
- 「feature_perturbation」パラメータには「interventional」及び「tree_path_dependance」が存在する
- バッググラウンドデータが指定されない場合、「tree_path_dependance」が使用される
この「feature_perturbation」パラメータが今回の問題の原因となっているんでしょうか?
② ChatGPTに質問してみる
パラメータの説明に記載の論文などを流し見してみても解決の糸口を見つけることができなかったため、最新のGPT-4oの性能検証を兼ねて質問してみることにしました。
プロンプトについては省略し、最終的な出力を示します。
このようにわかりやすい図を付して、説明してくれます!
ハルシネーションに気をつけなければなりませんが、GPT-3.5しか使ってこなかった身からすると本当に使い勝手がよくなったと感じます。
この図は出力の最初の部分だけで、説明が多少わかりにくい部分もあったため、類似の例を用いて全体の流れを説明します。
1 . 以下の様なバックグラウンドデータセット、学習済みの決定木モデル、SHAPを算出するデータサンプルを考えます
ID | X1 | X2 | X3 |
---|---|---|---|
1 | 1 | 3 | 2 |
2 | 2 | 2 | 3 | 3 | 3 | 1 | 4 |
4 | 4 | 0 | 1 |
学習済み決定木モデル
(root)
X1 <= 2
True / \False
(A) (B)
X2 <= 2 X3 <= 2
/T \F /T \F
10 25 35 45
サンプルデータ