雑記です。
2024/12/20 09:00 JSTまで行われてたCMI-Ⅱコンペにひっそりと参加していました。 一応、最後までやりきりはしたので振り返りを書いていこうと思います。
tl;dr;
- 最終順位206位, 一応銅メダルらしいです
- public: 389位(qwk=0.443), private: 208位(qwk=0.446)
- ちゃんとsub選べてたら2位だったのに、bestのsubを選べなくて銅圏まで転落してた
- solution
- 1st stage: xgboost + catboost + tabnet
- 2nd stage (stacking): xgboost + catboost + tabnet -> simple mean
- public: 389位(qwk=0.443), private: 208位(qwk=0.446)
- シェイクがすごいコンペだった
- LBとcvとの相関もそんなに取れない
- seed変えるだけでLB scoreがガラッと変わる
- trainデータセットをリークさせたのにもかかわらずLBのスコアが高い公開notebookがあるせいでLBが全く信用できない
- 結果的にprivate LBはシェイクしまくり
おみくじが当たったんだか外れたんだか微妙だなこれ pic.twitter.com/rNexkRH6gO
— 野川の側 (@nogawanogawa) 2024年12月20日
どんなコンペ?
子供のインターネット利用における問題行動の度合いを、身体活動データから予測するコンペでした。
特徴的な点としては、通常のテーブルデータに加えて、一部の子どもについては行動の時系列データが与えられていました。 また、trainデータなのにtargetが欠損しているデータがあるなど、欠損値が多いのも特徴かもしれません。
これらのデータを使って、対象の子どもの将来の異常診断の度合いを4段階で判定するコンペです。
解法など
今回、Private LBがシェイクしまくっていることからもわかる通りハチャメチャなコンペになりました。
あまりにコンペがハチャメチャ過ぎて自分の解法を公開するのもなんかもうめんどくさいんですが、一応残しておきます。
notebookはこちら。
工夫した点としては
- lossはmulti target, early stoppingはqwk (siiのsingle target)にした
- stacking
- threshold optimization
って感じです。実験してた感じ、上3つはちゃんと効いてる感じだった(cv, LBどっちも上がってた)ので多分効いたんでしょう。
うまくいかなかったこととしては、
- TabM -> 試したけどCV上がらず
- pseudo labeling: cv上がらず切り捨てた
- n_foldをめちゃくちゃ増やす -> cvは上がったがLBが上がらず切り捨て(後で確認したらprivateでは上がってたので実は効いてたらしい)
って感じでした。 他にも色々やったんですが、あんまりパッとしないものばっかりでした。
余談
ちゃんとsub選んでいれば2位のnotebook(qwk=0.480)もあったんですが、あまりにseedによって結果が変わっていたのと、そもそもちゃんと吟味する気にもならなかったので、bestのsubは結局選べず銅圏まで落ちて終了、って感じでした。
まあベストのsubを選ぶのも一つの実力なので、そういう点では実力不足ですね。 notebookに大当たりは入ってたものの、選んだ結果は大当たりを外したわけです…
上位解法
今回個人的に実験して面白い発見があったわけではなかったんで、あとは上位の解法をちょっと眺めて終わろうと思います。
1st
モデルとしては下記のアンサンブルだそうです。
• LGBMRegressor • XGBoost Regressors • CatBoostRegressor • ExtraTreesRegr
'PCIAT-PCIAT_Total' score and converted the predictions to sii labels.
とあるので、直接siiを予測するのではなく途中経過のスコアをtargetにしたようですね。
A 10-fold stratified KFold was used, stratified by the bins.
n_foldはやっぱり大きい方が良いみたいで、1位でも10個に分けているそうです。 その他、あり得ない特徴量をクリーニングしたり、PCAで次元削減したりしているようです。
3th
モデルにはLightGBMを使用したそうです。 seedを固定しないように5-foldを100回繰り返し、それをOptunaでチューニングしたそうです。
その他、特徴量エンジニアリングではNanをランダムに挿入したり、ガウシアンノイズを加えるなどしているそうです。
5th
時系列データの特徴量エンジニアリングに対して、k-meansを使用してクラスタ分割し、それを特徴量として加えているようです。 targetはやはりPCIAT-PCIAT_Totalを予測するようにしているようで、siiを直接ではなく途中経過を予測しているようです。
また、pseudo labelingが効いたようで、targetが欠損している場合にpseudo labelingで埋めていたそうです。 モデルにはLGB, cat, xgb, lasso, nnを使用しているそうです。
7th
モデルはLGBM (+アンサンブルにXGBoostを含む)だそうです。 特徴量に関して、欠損値補完は中央値にしているようですね。
特徴的なのは学習時に、Tweedie Loss(全然わからない)を使っているようです。 あとはpseudo labelingが効いたようです。(やっぱり効いたらしいんで、自分の実験はなんか間違ってたんでしょう…)
アンサンブル時にはseed10個を使って平均を取ってるらしいです。(これも自分も試したんですが、cvが上がる気配がなく…何かバグってたんでしょう)
上位解法を見て多分大事だと思ったこと
多分上位の方ではこんなことをやっているというのはだいたいこんな感じでしょうか。
- 複数のseedを使ってその平均を使う
- seedによるばらつきを抑える
- PCIAT-PCIAT_Totalを予測する
- siiを予測するよりより細かく予測できる気がする
- 特徴量エンジニアリング
- やり方は多様ではありますが、与えられたデータに嘘が入っていること前提で埋めたり、逆にノイズを付加したりすることでロバストにしていっているのが多いようです
- pseudo labeling
- targetが欠損していることがあるので、それをpseudo labelingで埋める
- cvの計算にはpseudo labelingは使用しない
感想
11月の上旬くらいにフラッと始めて数週間くらいで「このコンペやばいかも」と気づいたんですが、サンクコストを気にしてしまって結局最後までやる羽目になってしまいました。 GPUもほとんど使うことがないほど非常にデータの軽いコンペだったので、そういう意味ではやりやすかったですが、ただただLBがぶっ壊れててしんどいコンペでした。
結局最初の2週間くらいで作ったnotebookから大して良くならず、LBに振り回されながらズルズル続けちゃったのがよくなかったですね。 金圏のsubを選べなかったのは残念ですが、cvもそこまで良くなかったやつなんでどっちにしろ選べなかったですね。
あまり良い結果ではありませんでしたが、途中から宝くじ感覚でやっていたので良しとすることにします。