Slide 1

Slide 1 text

ALLPPT.com _ Free PowerPoint Templates, Diagrams and Charts Jack (Japan) https://www.kaggle.com/rsakata Feature Importanceによる 特徴量選択とリーク 2023/10/20 関西Kaggler会 #3

Slide 2

Slide 2 text

主旨 • 特徴量選択をCV全体でやるとリークするというお話 • X(旧Twitter)上では時折指摘される内容ではあるが、具体的な事 例抜きに言葉だけで説明されても、いまいちピンと来ない人も多い のでは? • 本資料では、簡単な人工データで検証を行った結果を共有する • 実は、ちゃんと考えると意外に難しい問題

Slide 3

Slide 3 text

今回生成した人工データ • データ数 – Train: 50,000, Test: 50,000 • ターゲット – 各レコードに対して20個ずつ正規乱数(σ=1.0)を生成し、その平均が0より大 きいか小さいか(均衡な二値分類タスク) • 特徴量 ① 上記20個の正規乱数に正規乱数ノイズ(σ=2.0)を上乗せしたもの ② + 上記特徴量にさらに正規乱数ノイズ(σ=1.0)を上乗せしたもの×10(劣化特 徴量) – つまり、特徴量数は 20 + 200 = 220

Slide 4

Slide 4 text

y ターゲット因子 特徴量 劣化特徴量 データ生成の概念図 正規乱数 (σ=1.0) 平均が0以上か否か +正規乱数 (σ=2.0) +正規乱数 (σ=1.0) ×10

Slide 5

Slide 5 text

実験条件 • モデル – LightGBM • 評価指標 – Log-Loss, ROC-AUC • バリデーション – 5-fold CV × 5 seeds(ランダム性を低減するため、ただしCV分割は変えない) • 特徴量選択 – 後述 hyperparameter learning_rate 0.1 (default) feature_fraction 0.5 early_stopping_rounds 100 その他 default

Slide 6

Slide 6 text

事前検証:特徴量選択を行わない場合 ① 20特徴量だけ使った場合 ② 劣化特徴量を加えた場合(全220特徴量) Log-Loss AUC CV Score 0.6320 ± 0.0001 0.6945 ± 0.0002 Test (単モデル予測) 0.6315 ± 0.0005 0.6951 ± 0.0007 Test (CV平均)※参考値 0.6292 ± 0.0001 0.6990 ± 0.0002 Log-Loss AUC CV Score 0.6332 ± 0.0001 0.6925 ± 0.0001 Test (単モデル予測) 0.6333 ± 0.0003 0.6922 ± 0.0005 Test (CV平均)※参考値 0.6304 ± 0.0001 0.6970 ± 0.0001 多数の劣化特徴量を 含めることで、やや スコア悪化している ただし、CV/Testに 大きな乖離は無い

Slide 7

Slide 7 text

事前検証:特徴量選択を行わない場合 ① 20特徴量だけ使った場合 ② 劣化特徴量を加えた場合(全220特徴量) Log-Loss AUC CV Score 0.6320 ± 0.0001 0.6945 ± 0.0002 Test (単モデル予測) 0.6315 ± 0.0005 0.6951 ± 0.0007 Test (CV平均)※参考値 0.6292 ± 0.0001 0.6990 ± 0.0002 Log-Loss AUC CV Score 0.6332 ± 0.0001 0.6925 ± 0.0001 Test (単モデル予測) 0.6333 ± 0.0003 0.6922 ± 0.0005 Test (CV平均)※参考値 0.6304 ± 0.0001 0.6970 ± 0.0001 多数の劣化特徴量を 含めることで、やや スコア悪化している ただし、CV/Testに 大きな乖離は無い 期待:特徴量選択により劣化特徴量を 除外できればスコア回復しそう?

Slide 8

Slide 8 text

検証1:CV全体で特徴量選択 • LightGBMのGain ImportanceのCV平均値 (5-fold CV × 5 seeds) を計算し、 上位100個の特徴量を選択 Log-Loss AUC CV Score 0.6317 ± 0.0002 0.6951 ± 0.0003 Test (単モデル予測) Test (CV平均)※参考値 Log-Loss AUC CV Score 0.6332 ± 0.0001 0.6925 ± 0.0001 Test (単モデル予測) 0.6333 ± 0.0003 0.6922 ± 0.0005 Test (CV平均)※参考値 0.6304 ± 0.0001 0.6970 ± 0.0001 特徴量選択 (再掲) CV改善!

Slide 9

Slide 9 text

検証1:CV全体で特徴量選択 • LightGBMのGain ImportanceのCV平均値 (5-fold CV × 5 seeds) を計算し、 上位100個の特徴量を選択 Log-Loss AUC CV Score 0.6317 ± 0.0002 0.6951 ± 0.0003 Test (単モデル予測) 0.6341 ± 0.0004 0.6909 ± 0.0006 Test (CV平均)※参考値 0.6314 ± 0.0001 0.6954 ± 0.0003 Log-Loss AUC CV Score 0.6332 ± 0.0001 0.6925 ± 0.0001 Test (単モデル予測) 0.6333 ± 0.0003 0.6922 ± 0.0005 Test (CV平均)※参考値 0.6304 ± 0.0001 0.6970 ± 0.0001 特徴量選択 (再掲) Testはむしろ悪化… (=リークの発生)

Slide 10

Slide 10 text

なぜリークするのか? • Gain Importanceは、学習データのノイズ※も含めてフィッティングした結果、算出 されたもの • CVにおけるバリデーションデータは、当然他のfoldでは学習データに含まれている • 特徴量重要度をCV全体で平均してしまうと、バリデーションデータのノイズ情報も 入り込んでしまい、それが反映された特徴量選択になってしまう この特徴量のノイズは ターゲットと相関してますよ リークさん ※ノイズの例:ターゲットと真に相関は無くても、データが 少数だとたまたま相関係数が出てしまうなど

Slide 11

Slide 11 text

検証2:CVのfold毎に特徴量選択 • LightGBMのGain Importanceの平均値をfold毎 (5 seeds) に計算し、 上位100個の特徴量をfold毎に選択 Log-Loss AUC CV Score 0.6338 ± 0.0003 0.6916 ± 0.0004 Test (単モデル予測) 0.6341 ± 0.0003 0.6909 ± 0.0006 Test (CV平均)※参考値 0.6309 ± 0.0001 0.6963 ± 0.0002 特徴量選択 (再掲) CVとTestの乖離は 小さくて済む 判断を誤らない! Log-Loss AUC CV Score 0.6332 ± 0.0001 0.6925 ± 0.0001 Test (単モデル予測) 0.6333 ± 0.0003 0.6922 ± 0.0005 Test (CV平均)※参考値 0.6304 ± 0.0001 0.6970 ± 0.0001

Slide 12

Slide 12 text

ここまでの結果の整理 • 期待に反して、特徴量重要度を用いた特徴量選択で、予測精度はむしろ悪 化した(有効な特徴量20に対して100を選択したが、それでもダメ) – 必ず効果が無いとは言い切れないが、経験的によく知られている話 – ただ、これは今回のメインメッセージではない • 一方、精度改善ではなく、学習・推論時間の短縮、モデルの軽量化などを 目的に、特徴量選択をやりたい場面がある(某PSPコンペ) – できる限り精度低下しないギリギリを攻めたい(CVでの判断が必要) • そういったときに、特徴量選択はCVの分割毎にやらないと、CVとTestでス コアの傾向が乖離する恐れがある – 某PSPコンペでは数千の特徴を数百に絞る必要があったため、先述の方法を 採った(CV平均で試してみると、案の定同じ現象に遭遇した)

Slide 13

Slide 13 text

なぜリークするのか?(続) • 特徴量選択にバリデーションデータのノイズ情報が含まれていたとしても、 splitting point や leaf weight の情報も無いと、その情報は活かせないのでは? 個人的な理解 • 特徴量重要度はそのときの学習データ全体で計算されるものなので、特徴量ノイズとターゲット の関係性が、学習データ全体で(たまたま)一致しているほど、その特徴量重要度は大きくなる • つまり、fold間で非本質的なノイズの相関がある特徴量ほど、より上位に来る可能性が高い • 結果的に、学習データでご一緒した他のfoldの特徴量ノイズから、間接的にバリデーションデー タのノイズ情報を拾うことができてしまう → 学習データに回ったときの情報を使わなければOK この特徴量のノイズは ターゲットと相関してますよ リークさん どこで切ったらいいか わからないじゃない! とはならないのか?

Slide 14

Slide 14 text

Permutation Importanceの場合は? • Permutation Importanceのように、バリデーションデータを使って重要度 を算出するようなタイプの場合、当該foldの情報を使うのはむしろアウト – ノイズを拾ってバリデーションスコアが上がるような特徴量を直接的に選択す ることになるので • じゃあ逆に、学習データに回ったときのみの情報を使えばいい? – つまり、5-fold CVであれば、自身がバリデーションデータに回ったとき以外の 4fold分の情報を使って特徴量選択を行えばいいのでは?

Slide 15

Slide 15 text

検証3:CV全体で特徴量選択 • バリデーションデータに対するPermutation ImportanceのCV平均値 (5-fold CV × 5 seeds) を計算し、上位100個の特徴量を選択 Log-Loss AUC CV Score 0.6317 ± 0.0002 0.6949 ± 0.0003 Test (単モデル予測) 0.6342 ± 0.0005 0.6907 ± 0.0007 Test (CV平均)※参考値 0.6314 ± 0.0002 0.6952 ± 0.0002 Log-Loss AUC CV Score 0.6332 ± 0.0001 0.6925 ± 0.0001 Test (単モデル予測) 0.6333 ± 0.0003 0.6922 ± 0.0005 Test (CV平均)※参考値 0.6304 ± 0.0001 0.6970 ± 0.0001 特徴量選択 (再掲) 当然、CV平均を使うと Perm. Importanceでも 同様の問題が生じる

Slide 16

Slide 16 text

検証4:CVのfold毎に特徴量選択 • 当該fold以外のPermutation Importanceの平均値 (4 folds × 5 seeds) を 計算し、上位100個の特徴量をfold毎に選択 Log-Loss AUC CV Score 0.6318 ± 0.0001 0.6949 ± 0.0003 Test (単モデル予測) 0.6341 ± 0.0004 0.6909 ± 0.0006 Test (CV平均)※参考値 0.6310 ± 0.0002 0.6960 ± 0.0002 Log-Loss AUC CV Score 0.6332 ± 0.0001 0.6925 ± 0.0001 Test (単モデル予測) 0.6333 ± 0.0003 0.6922 ± 0.0005 Test (CV平均)※参考値 0.6304 ± 0.0001 0.6970 ± 0.0001 特徴量選択 (再掲) CVとTestは乖離したまま… これでもやっぱりダメ!?

Slide 17

Slide 17 text

なぜダメだったのか? • 「学習データで分割した結果」を「バリデーションデータで評価」してい る時点で、どうしても両者のノイズの共通傾向を拾ってしまう • 原理的に、バリデーションデータで算出するタイプの重要度で特徴量選択 を行うと、どうあがいてもCVが不当に上がってしまう と理解しています(ちょっと自信無いけど… )

Slide 18

Slide 18 text

まとめ • 特徴量重要度で特徴量選択を行うことによる精度向上は、期待しない方がよい – 背景知識による特徴量選択は有効なことがあるので、特徴量選択そのものを否定するわけで はない • 他の理由で特徴量選択を行いたい場合、以下を守る方が、精度評価の意味では安全 – CVのfold毎に特徴量選択を行う – バリデーションデータを元に算出するタイプの重要度を使わない • もちろん、Gain ImportanceよりもPermutation Importanceを使いたい場面もある ので、これまでの議論はあくまで一つの観点に過ぎない • 一連の実験結果はこちら(Speaker Deck上ではリンクが効かない…) – https://www.kaggle.com/code/rsakata/feature-importance