GBM系ライブラリの変数重要度計算ロジックメモ(特にcatboostについて)
Gradient Boosting Machine系のライブラリは予測の初手としてよく使われるアルゴリズムで、予測分析といったらとりあえずこれをつかうのではないかという程度に普及した手法です。
ところで、何気なく使っている説明変数重要度の値ですがアルゴリズム毎に計算ロジックが違うので、ここにまとめて読めるように情報を残しておこうと思います。
特に、私が好んで使っているcatboostについては、公式ドキュメントが細かくは書かれていない計算についてデバッグ用コードを仕込んでビルドし理解した内容も含めてメモしておきます。
※手計算で出した想定結果と実際の値と照らし合わせると大きく値が違ってて、なぜだ?とハマったのがこのメモ記事を書くメインモチベーションだったりします。。。
まず、各GBMライブラリで実装されているFeature Importanceの計算ロジックは次の画像の通りで、そもそも実装されているロジックが違うことがわかります。
これらの計算ロジックは、ばっくり分けるならば3種類のタイプに分けられます。
- 不純度を計算するタイプ(Gain)
- Tree内で説明変数が分岐条件として使われる回数を基準とするタイプ(split, weight, cover)
- 出力結果への影響度を計算するタイプ(PredictionValuesChange)
説明変数重要度の計算ロジックが違うので、もちろん異なるモデル同士の説明変数重要度は比較しても意味が無いということになります。
説明力の強弱の相対関係を把握するだけに留めなければなりませんね。
さて、詳細説明について1はDecision treeの計算でも出てくるものですし、2はxgboostの説明記事がたくさんあるのでそれぞれ別な記事に任せるとして、 3の詳細を次に紹介したいと思います。
公式の説明ページによるとLeaf pairsと書かれているので、Leaf nodeだけが算出対象になるのかな?とミスリーディングなワーディングですが、実際には全組み合わせパターンで網羅的に計算されています。
計算されるノードペアの選ばれる様子のイメージは図の右側の通りです。
また、catboostの説明変数重要度は全説明変数重要度の総和が100になるようリスケールされている点にも取り扱いに注意が必要です。 つまり、同じcatboostのモデル同士でもその説明変数重要度の絶対値では比較できないということです。
※ 参考リンク
sklearn: 3.2.4.3.5. sklearn.ensemble.GradientBoostingClassifier — scikit-learn 0.23.2 documentation
xgboost: Python API Reference — xgboost 1.3.0-SNAPSHOT documentation
lightgbm: lightgbm.Booster — LightGBM 3.0.0.99 documentation
catboost: Feature importance - CatBoost. Documentation