第四回atmaCupに参加してきました
オンサイトのデータ分析コンペティションのatmaCupの第四回に参加してきました。 これは1週間の間にお題について最も良い制度の予測をした人が勝ちというkaggleの期間が短い版です。 atmaCupは問題の質に定評があるコンペで、自分はこれで三回目の参加になります。
コンペについて
今回のお題はリテール予測で、買い物の履歴が与えられるので、ある買い物時に特定カテゴリの商品が一緒に買われたかどうかを予測するという課題でした。 特定カテゴリは全部で13種類あり、買い物ごとに13カテゴリ分それぞれ購入されたかどうかを01で予測し、macroAUCで評価します。 訓練データとテストデータは時系列で分割されていて、訓練データには二年分の特定カテゴリ以外の購入履歴と、一年三か月分の特定カテゴリの購入履歴が与えられました。
データは
- 購入日時
- 買い物ごとに付与されるID
- ユーザーごとに付与されるID
- 店舗ごとに付与されるID
- 購入された商品のIDと名前
- 商品について粒度ごとに四段階に分割されたカテゴリ名
- 商品ごとの数量と価格
等の情報が与えられました。
また、データセット自体にも特徴があり
- テストデータのうち半分のユーザーは訓練データに出現しない(コールドスタート問題)
- 購入データは一度に5品以上の商品が購入されたデータに限る
という特徴がありました(後者についてはユーザーの情報ではなく、商品の組み合わせの情報から特定カテゴリの商品が購入されるかを予測してほしいという目的があったようです)
今回の共同開催者であるリテールAI研究会さんの記事(https://diamond-rm.net/technology/28705/)を見ると、 目的のカテゴリがどのような場合にセットで買われやすいかの分析をすることで、 ある商品を買った人にセットで特定カテゴリの商品を勧める、 あるいはセットで買いやすいような商品配置にできるようになり消費者も店もハッピーになれそうな感じがしました。
分析やモデルについて
データの分析では特定カテゴリ以外と特定カテゴリでクロス集計を行い、買い物やユーザー、アイテムごとに集計や次元圧縮を行って統計的に特徴量を作ったり、平日の昼間に買い物をしているか、おつまみを一緒に買っているかといったデータの分析途中で得られた知見を元にした温かみ(?)のある特徴量を作ったりしてモデルに組み込まれていました。
予測モデルは勾配ブースティング木の一種であるLightGBMが圧倒的に人気で、上位陣はモデルをホットスタートとコールドスタート用にモデルを分けて取り組んでいる人が多かったです。
バリデーションもホットスタートではStratifiedKFold、コールドスタートではユーザーごとのGroupKFoldが人気だったように感じます。
自分のモデルについて
特徴量関連ではtarget encoding関連は強力な特徴だったのですが、データの正例と負例に大きな偏りがあり、件数の少ないカテゴリでうかつな操作をするとすぐにオーバーフィットしてバリデーションのスコアが下がってしまうのでスコアの推移を見ながら慎重にtarget encodingの方法を選ぶ必要がありました。
バリデーションについては時系列データだったので脳死で時系列による分割を考え、ホットスタートの方は時系列のhold-out、コールドスタートの方は時系列のhold-out × GroupKFold(5fold)で分割しました。CVは.841+.680で平均するとちょうどLBと対応していて妙な安心感はあったものの、上位陣は時系列で分割していなかったので使えるデータが少ない分損していて、late submissionで時系列の分割をやめたら順位で二つ分くらい上がりました……
また、モデルについては13個バラバラのモデルを予測するのではなく、目的のカテゴリを変数にして一つのモデルで学習させていました。初手でこれをやっていたので13個モデルを作る方は試していなかったのですが、両方試してアンサンブルしとけばよかったなと反省しています。
計算環境について
データ自体も刺激的で学びがあったのですが、今回はMicrosoftさんに計算環境を提供して頂いたので、計算をAzure上で無料で実行することができいい経験になりました。 これまでクラウド関連はなんとなく避けて通ってきたのですが、初日のチュートリアルやslack上でのサポートのおかげで初心者の自分でも使うことができました。 特に良かったのは、普段使っているエディタのVSCodeとの相性が良かった点で、ローカルと似た感じの雰囲気でコードを書けたのが使いやすかったです。
感想
順位は15位で自分の実力的には妥当かなというラインなのですが、late subの結果を見るともう少し上を狙えたかも……という気がします。 次のatma杯では10位以内を目指して精進を重ねていきたいです。