atmaCup#2(オフラインコンペ)で優勝しました
先週末11/23に大阪で行われたatmaCupで優勝できたので、簡単に振り返りたいと思います。
なお、データの内容はNGでカラムや問題設定までは公開OKであるため、公開可能な範囲でのポエム記事になります。
atmaCupとは
atma株式会社が運営をするデータ分析コンペティションです。 今回は#0、#1に続き第3回目のようです。
1日かけて会場に集まった参加者(30〜40人)がデータから目的の値を予測する精度を競い合います。
kaggleなどのコンペでは約1〜3カ月かけて解くのに対し、 atmaCupでは1日(8時間)という限られた時間で問題を解く部分が最も大きな違いだと思います。
今回のタスクについて
ユーザの睡眠時間や起床時間、アプリが計測した睡眠の質、お酒を飲んだか、アンケート回答等の情報からユーザの日中のコンディションを予測するというものです。
ユーザの日中のコンディションは、ユーザ自身が入力した数値であり、評価指標はRMSE(Root Mean Square Error)でした。
kaggleと同様train/test(public/private)に分割されており、 testデータに存在するユーザidは、trainにも含まれるもので、時系列的にはtrain=>public=>privateの順になっています。
今回のコンペの詳細は下記の記事が詳細まで記載していたので 気になる方はこちらを見ることをおすすめします。
またこちらのtakapyさんの記事も非常にわかりやすかったです。
コンペ中に取り組んだ流れ
基本的なフローですが、以下の流れで取り組みました。
- 簡単なEDAでデータ把握
- パイプライン上で動くようコーディングしてベースライン作成
- 簡単なパラメータチューニング
以下4〜6の繰り返し
- 過去のコンペの経験則、データをじっくり見る(EDA)、学習の実行結果(精度、Feature Importance等)の確認しながら、仮説立てる
- 特に効果的だと思われる仮説の検証(コーディング)
結果(CV, LB, FeatureImportance)の確認
モデル同士のアンサンブル
仮説と書くと凄そうにきこえますが、「このあたりの特徴効くんじゃね?」みたいな軽いノリのものも含んでます。
時間配分としては、1, 2, 3がだいたい1時間くらいで、4〜6のループが殆どの時間、7が最後30分くらいでした。
リーダーボード
kaggleと同じようにPublicスコアの順位が表示されるので今の自分がどれくらいのスコアかが分かります。
前半はあまり順位が上がらず、5〜10位くらいをウロチョロしていました。
途中で何個か大事な発見をして、順位を4位まで上げます。
TOP3が遠い。。。#atmaCup pic.twitter.com/5v3GFgk4mv
— pao (@pppaaaooo) 2019年11月23日
しかし、3位までとの差はかなり大きいまま。。 このあたりで頭も回らなくなって、部屋を出てクリスピードーナツを買いに行きました。
ドーナツ効果もあり、重要な特徴量を発見し、4位のままでしたが、上位との差はだいぶ詰めることができました。
あと少し。。 #atmaCup pic.twitter.com/3DpGg9SHXf
— pao (@pppaaaooo) 2019年11月23日
このあとまだスコアを上げますが結局、Publicの順位は4位のままで終了。
ただ、大事なのはPrivateの順位です。 Privateスコアが全てです。
Publicの順位は当てにならない事例は下記にあるので暇な方がいたら読んでみてください。
※注意: 下記リンクのコンペと違い、今回のコンペはタスク設計もしっかりしており、Publicの順位はしっかり参考になるものです。
最終結果
まさかのShakeUp(Publicの順位よりPrivateの順位が上がる)で、1位!!!
戦略的にどうこうではなく、ShakeDown(Upの逆)に取り憑かれているので、ビックリしました。
やったー!!!優勝しました!!!金メダルにkaggleにも付与してください!! #atmaCup pic.twitter.com/xEG8ZaL0UP
— pao (@pppaaaooo) 2019年11月23日
テンション上がりすぎて日本語が変になってしまいました。
有効だった戦略・特徴量
ユーザ毎のtarget平均からの差分を予測する
今回のタスクのtargetがユーザ自身が入力するものであり、ユーザによって傾向が変わるものでした。 また、ユーザはtrainとtestで共通でした。
targetが同じ数値でもユーザによって本当のコンディションは異なります。 (今日1日の楽しさを100点満点で表してと言われたとき、自分に甘い私にとっての80点と、自分に厳しいAさんの80点は意味が異なります)
ユーザ毎のtargetの傾向を補正して「そのユーザにとって良いコンディションだったかどうか」を予測する問題に置き換えました。
重要な特徴同士の除算
これはkaggleでのテクニックとして、よく取り上げられるものですが、LightGBMなどのGBDT系モデルでは相互作用の考慮は出来るものの、直接特徴量として変数間の除算や乗算などをしたほうが効果的なことが多いです。
とはいえ、全パターンやるのも時間かかったり、組み合わせが無限になったりするので
- FeatureImportanceで上位に来るもの
- 一方の単位が時間など、何となくでも解釈できそうな特徴量になること
に絞ってやりました。 今回はその中の1つが大ヒットで大きく精度が上がりました。
過去の数値と比較
これも鉄板ですが、重要そうな特徴量について前日の値、前日との差を入れたら上がりました。 ちなみに、他の方のソリューションも参考に、コンペ終了後、2日前、3日前、7日前も入れるとさらに精度が上がりました。
Rollingさせて数日分の平均や分散を入れたりするのも定番ですが、日が連続でないケースもあって実装が簡易な前日の特徴量だけにしました。 事前に関数やスニペットを用意しておくべきだったなと思いました。
ユーザ毎の特徴量
1と似ています。 ユーザ毎の傾向、ユーザにとってその数値がどうなのかが重要でした。 睡眠時間6時間としたとき、十分かどうかと言われると人によるので、ユーザの平均と比較したりするイメージです。
また、ユーザのtargetの分散(回答にどれだけブレのあるユーザか)も有効でした。 (ただし、targetの情報を使っているのでリスキーなものです。)
振り返り(よかったこと)
効果が高そうなところの優先度を上げて取り組めた
kaggleでは思いついているもの、やれるだけやるという感じがありますが、 より時間の限られた今回のようなオフラインコンペでは 「限られた時間の中でいかに効果が高そうなところに取り組めるか」 が重要になります。
普段は子持ちkagglerのため、他の方と比べるとkaggle出来る時間は本当に限られています。 そのため、時間効率よく精度をあげていくというのは日頃から意識していて、それが活きたのかもしれません。 (結果論かもしれません。) 今回のようなオフラインコンペでは参加者皆、時間は平等に与えられるのでそういった意味でも子持ちkagglerにも優しかったです。
パイプラインがうまく働いた
パイプラインは、これまでのkaggle等のコンペで少しずつ積み重ねて作り上げた自分独自のものです。 今回のコンペでは実験を繰り返す上での高速化、過去の実験結果のログ確認などで役に立ちました。
振り返り(反省)
まだまだやれることはあった
今回1位にはなったものの他の方のソリューションを聞いていると、「それやればよかった」と思えるものがたくさんありました。
まだまだ改善の余地はたくさんあって、もう少し期間が伸びていたら抜かれていた可能性も高いと思います。
他の方のソリューションを参考にしてもっと強くなりたいと思いました。
ShakeUpしたものの
今回まさかのShakeUpしたものの、しっかりShake対策が出来ていたかというとそうではありません。
もちろんPublic/Privateの分割を気にして特徴作成したりはしていましたが、明確にこれのおかげでShakeUpしたとはいえないです。
今回はShakeの神様がたまたま振り向いてくれたにしても、次はまた落ちるかもしれないので、今後もShake対策はしっかり考えたいと思います。
感想
最近kaggleでいまいち結果が残せず、人類皆kaggle masterになっていく中、金メダルが取れない日々が続いていました。 努力しても結果が出ないというのは辛いものです。
ですが、今回強者がたくさんいる中で1位になれたというのは、運の良さがあったとはいえ、久々に努力が報われた感じがして本当に嬉しかったです。 いや今も嬉しいです。
転職活動中だったので、一つ履歴書に書けることが増えたのも嬉しいです。
参加者を見てみるとGrandMaster2人/Master8人くらいいたし、物理金メダルももらえたので、これで実質Masterですかね(笑)。
嘘です。kaggleはkaggleでしっかり結果残せるように頑張りたいと思います。
最後に
今回このイベントを開催いただいたatma株式会社の皆様、ランチスポンサーをしていただいた株式会社i-plugの皆様ありがとうございました。 とくにコンペの素晴らしいタスク設計からコンペサイトの作成までしていただいた ニューヨーカーGOTO (@nyker_goto) | Twitterさんには感謝と尊敬の念でいっぱいです。
次のatmaCupも参加できそうであれば2連覇目指してがんばります!!