teaがいろいろ書くところ

kaggle MLBコンペ 振り返り

Posted at — Sep 17, 2021

こんにちは、teaです。久しぶりのブログ投稿になります。

本記事は、先日まで参加していたkaggleのコンペティションである「MLB Player Digital Engagement Forecasting」コンペ (以下MLBコンペ) の振り返り記事です。

MLBコンペとは


概要を理解するなら上に貼ったリンクの先に書いてあるOverviewを見るのが一番手取り早いですが、端的にいうと、「MLBに関する様々なデータから、各MLBプレーヤーの翌日のデジタルコンテンツに対するエンゲージメントを予測してね」というコンペです。

“様々なデータ” とは、例えば選手の基本情報、日付ごとの各選手の試合情報 (ヒット何本とか)、チームのTwitterのフォロワー数などで、各データは別々のcsvにまとめられていました。

また、デジタルコンテンツのエンゲージメントは実際に何のエンゲージメントなのかということは公表されておらず、コンペ中ではtarget1 ~ target4 というカラム名で伏せられていました。

その上、本コンペはいくつかのフェーズに分かれていることもポイントで、以下のようにフェーズ分けされていました。

このように本コンペは、なんだかよくわからないtargetを時系列で予測する必要があり、かつコンペのフェーズも意識しなくてはならないという中々に難しいコンペでした。

チーム & コンペの結果について


今回私は、Takayoshi Makabeさんsqrt4kaidoさんのお二方とチームを組んで本コンペに挑みました。

私自身、チームを組んでコンペを最後までやり切るのは今回が初めてだったので、本当に良い経験になりました。

また、コンペ期間中Slack上でたくさん議論を行いコンペに対する理解を深めていった結果、最終的には6位という好成績を残すことができました。

自分一人では絶対にこの順位をとることはできなかったので、チームメンバーのお二方には本当に感謝しています。

LB

主に工夫した点


詳細はチームのsolutionに纏まっているので、本記事では軽く触れていきます。

lag特徴量


本コンペで最も厄介だったのが、このlag特徴量 (以下lag) でした。

本コンペにおけるlagとは、予測対象の日から数えてn日前までのtargetを指します。

lagを用いることである程度スコアが良くなるというのは直感通りですが、それはlagがtargetの真値になっている場合で、本コンペのように評価期間で未来のデータに対して予測を行うタスクではlagの真値は得られません。 (例: 2021-08-05の予測を行う際には2021-08-01 ~ 2021-08-04のtargetの真値は得られない)

そのため、評価期間中でもlagを用いる場合は真値の代わりに予測値を用いる必要があります。

その場合、前半は予測がある程度正しくなるためlagを用いない場合と比較してスコアが良くなるのですが、どうしても日が経つにつれて予測が大きくブレていってしまいます。(実際、手元で日付ごとにスコアをプロットしてみると、後半になるにつれてどんどんスコアが悪化していくことが確認できました。)

そこで、私たちのチームでは、lagがある程度有効な範囲内ではlagありのモデルを優先して使い、その範囲を超える日付ではlagなしのモデルのみを使うというふうにしてアンサンブルを行いました。

ちなみに、lagの有効範囲については、lagありモデルとlagなしモデルのスコアのplotを比較して決定し、最終的には2021-08-01 ~ 2021-08-20の期間のみlagありモデルを用いるように設計しました。

このようにアンサンブルを行うことで、最終的にはlagありのsubがlagなしonlyのsubと比較して0.015ほどスコアが良くなりました。

(↓はsqrt4kaidoさんがアンサンブルについてわかりやすく表してくれた図)

Ensemble

推論を楽に行うためのコード構成


notebook提出系のコンペでは、基本的には学習はローカルで行い、その学習済みモデルを用いて推論だけを行うnotebookを作って提出するというのが定石だと思います。本コンペでもほとんどの方がそのような形式でnotebookを提出していたと思いますが、チームでこれを行おうとするとどうしてもlagだったりその他の時系列特徴を生成したりするコードがややこしく、notebookがごちゃごちゃしてしまいました。

これに対処する方法としては、例えばlagを生成したりするコードを共通化する等考えられますが、それは各々に使用するカラム名などの制約を課してしまういうこともあり、あまり得策とは思えませんでした。

そこで我々は、各メンバーそれぞれがコードをモジュール化して、メソッド1つで推論 & 時系列データの更新を行えるような設計にしました。こうすることで、notebook内にいろんな人のいろんなコードが点在したりすることを避け、コードに変更があっても自分のモジュール部分をコピペをするだけで提出ができるようになりました。

イメージとしては、↓のような感じです。

class Tea:
  def preprocess(...):
    
  def predict(...):
     ...
     update_time_series_data(...)
    
class Sqrt4kaido:
  def preprocess(...)
  
  def predict(...)
     ...
     update_time_series_data(...)
      
class Makabe:
  def preprocess(...)
  
  def predict(...)
     ...
     update_time_series_data(...)
  
some_data = read_data(...)

tea = Tea().preprocess(some_data)
sqrt4kaido = Sqrt4kaido().preprocess(some_data)
makabe = Makabe().preprocess(some_data)

for (test_df, sample_submission_df) in iter_test:
  # prediction & update time-series data
  pred_tea = tea.predict(test_df, sample_submission_df)
  pred_sqrt4kaido = sqrt4kaido.predict(test_df, sample_submission_df)
  pred_makabe = makebe.predict(test_df, sample_submission_df)
  
  pred = ensemble(pred_tea, pred_sqrt4kaido, pred_makabe)
  
  env.predict(pred)

コンペを通して学んだこと


視野を広く持つ

自分はコンペ初期の方からtargetのlagを使って色々モデルを組んでいたのですが、lagって別にtargetのものだけに限らず様々な特徴に対してとることができたので、もっとその辺りを試しておけばなあと思っています。実際、試合内容についてのlagなんかは用いているチームがいくつかありました。

直感をあてにしすぎない

普通に考えてこんなデータが予測に役立つわけないでしょw と思っていたデータが実はそこそこ効いていたという話をsolutionを読んでいるといくつか見つけたので、直感を信じすぎるのはよくないなあと思いました。

今後は (特にコンペ初期の段階では) 直感で使うデータを絞るのではなく、実際に実験してみて使うかどうかを決めるということを意識していきたいです。

実験を早く行える環境を作る

楽に特徴量を作成できたりモデルを構築できたり、試行錯誤を重ねやすい環境を予め用意しておくのって本当に大事だなと思いました。

これについては反省して既に個人的にライブラリを作っているので、次からは試行錯誤がしやすい環境でコンペに挑むことができるのではないかと思っています。

実験のバージョン管理を行う

これを実践しているkagglerの方はすでにたくさんいらっしゃるかとは思いますが、Github等を活用して実験のバージョン管理を行うのは大事だなということを学びました。今後は、どのバージョンでは具体的に何を行ったのか、またそのときのスコアはどうだったのか等の内容は記録していこうと思います。

取り組んだことについて記録をとる

やったこと・やりたいこと・効いたこと等の情報をどこかに残しておくと便利だなということを学びました。

特にチームを組むことになった場合にこうした内容が纏まっていると、この人はどういうことに取り組んできたのかということを楽に理解できるのでいいなと思いました。

もちろん、ソロで挑む場合でも記録を残しておくことで頭の整理がしやすくなるはずなので、取り組む価値は大いにあると思います。

さいごに


私は昨年12月に初めてまともにコンペに参加したのですが、まさかこんなに早く金メダルを取れるとは思っていなかったので、正直今は嬉しい気持ちでいっぱいです。

あと銀メダル1枚で当面の目標にしていたKaggle Competitions Masterになることができるので、次に参加するコンペで昇格を決めていきたいなと思っています。

少し長くなってしまいましたが、ここまで読んでいただき、ありがとうございました。

関連記事