「オレシカナイトデータコンペティションvol.2」で準優勝でした
はじめに
1月26日に、AbemaTVの実データを使ったデータ分析のコンテストに参加し、準優勝でした。本記事では、運営の確認を経て、問題ない範囲でコンテストの概要や私の解法を紹介します。
コンテストの概要
オレシカナイトとは
オレシカナイトとは、「AbemaTV」や「Ameba」をはじめとしたサイバーエージェントグループが運営するメディアのアドテクノロジー開発を行うエンジニアの横断組織「Cyberagent Publisher adTechnology Associaion」が主催する技術者向けの勉強会です。
今回はオレシカナイトの一企画として、AbemaTVの実データを用いて、広告視聴数の予測モデルの精度を競うコンテストが開催されました。同様の枠組みでの開催は二度目で、前回は学生のみを対象に実施されたとのことです。
今回の参加者は15人でした。大半が社会人で、学生は3人でした。
競技概要
過去2カ月分のデータを基に広告のインプレッション数を予測するモデルを構築し、将来1週間分の値を当てるコンテストでした。競技時間は10:30〜17:15。データは300MB程度のcsvファイルで提供され、クラウドサービスなどの利用も可能でした。
- train: 543万レコード
- test: 59万レコード
ビジネス的な意義
- 出稿の段階で広告主とAbemaTV側でインプレッション数の値に関して契約を交わしている
- 例:広告配信期間の2週間の間に、合計100万インプレッションを獲得する
- この値を保証している関係上、予測の上で広告を配信し、合意した値に満たないと契約違反になる
- 予測をあまりにも上回ると、実質的な値引きになってしまいビジネス上AbemaTV側が損をする
- 上にも下にも外さない予測モデルが重要になる
既存の説明変数
既存の説明変数としては、以下のような情報が格納されていました。
- チャンネルやCMの配信位置など広告枠に関する情報
- CMの開始時刻などの広告配信タイミングに関する情報
- インプレッション数(trainのみ)
広告枠に関する情報は匿名化されており、CMの開始時刻も順序を変えないままに一定期間ずらされているとのことでした。
評価指標
評価指標としては、AbemaTVが実際の運用の際に使っている指標を用いました。以下、便宜上「スコア」と表現します。
スコアは、以下の手順で算出されます。
- ある一定の塊でレコードをまとめ上げる
- 塊ごとに「実測値の合計/予測値の合計」の値を計算
- 値が0.9〜1.1に収まった塊の割合が「スコア」になる
例えば、以下の4レコードが一つの塊になっている場合を考えます。この時、(ユーザに非公開の)実測値がある中で、次の予測値を提出した状況です。
レコード | 予測値 | 実測値 |
---|---|---|
0000001 | 80 | 100 |
0000002 | 110 | 100 |
0000003 | 100 | 100 |
0000004 | 120 | 100 |
この時、「実測値の合計」は400で、「予測値の合計」は410になります。「実測値の合計/予測値の合計」は400/410=0.975となり、この塊はスコアに貢献します。
このような評価指標を用いているのは、実際のビジネスでの運用において「個々のレコード単位の予測精度」よりも「一定の塊単位での予測精度」の方が価値を持つからだそうです。詳細部分は都合上割愛しますが、広告主側・AbemaTV側が扱いやすい塊で集計が実施されているようです。
専用のオンライン採点ツールにcsvファイルを提出すると、スコアが表示され、リアルタイムで順位表が更新される仕組みとなっていました。予測値の提出は何度でも可能です。testデータの全ての値を用いたスコアが表示されていたので、不健全ではありますがtestに合わせたチューニングも可能な状況ではありました。
今回参加者側では、実際にどのような塊でtestのレコードがまとめ上げられているかは把握できませんでした。そこで参考値として、提出したファイルのスコアと合わせてMSEも表示されていました。
自分の解法
戦略
とにかく時間が短いコンテストだったので、Kaggle・Signateのコンペ、業務、ブログで過去に作成したコードを使い回す方針を徹底しました。
競技概要を聞いた際に、下記のSignateの公園コンペと類似していると感じました。実際に、特徴量作成のコードは、ほぼコピペで完了しています。適宜こちらの解説もご参照ください。
端的に言えば「特徴量を作りLightGBMに投げ込む」という思考停止の戦略です。早い段階でベンチマークを作成し、中盤以降は探索的データ分析(EDA)もしながら、徐々に精度を高めていきました。
説明変数
- 既存の広告枠に関する情報をカテゴリ変数として投入
- CMの開始時刻からはmonth, day, day of the week, hour, minuteを抽出
- day, day of the week, hour + minuteは、循環性を基に(sin, cos)にencoding
- target mean encoding(5 fold)
学習モデル
- LightGBM(Single model, 5 fold)
- 参考値としてはMSEが表示されていましたが、大きな値に影響を受けづらいRMSEを最適化した方がスコアに寄与すると考え、RMSEをmetricに指定しました
- MLPも試しましたが、カテゴリ変数が多いせいか、全く上手くいきませんでした
結果
惜しくも2位という結果になりました。開始1時間弱で最終的に4位となるスコアを出し、その後も1位を走っていただけに、終盤の16:30に抜かれてしまったのが非常に悔しいです。
#オレシカナイト 朝からずっと1位を走ってたのですが、最後に @hiding_koukyo さんに抜かれて準優勝でした( ; ; )完全に自分の中の甘えが原因なので、精進します。楽しかったです。運営さん、ありがとうございました! pic.twitter.com/LyfDaWe3aX
— u++ (@upura0) January 26, 2019
1位の @hiding_koukyo さんの解法は下記をご参照ください。
所感
1日で全日程を終える都合上、朝9:45集合という、私にとっては平日の定時よりも早い集合時間でした。
案の定やらかしたので、タクシーで高速道路に課金して10分前に間に合った・・・ #オレシカナイト
— u++ (@upura0) January 26, 2019
運営の方々のサポートは、端的に言って素晴らしかったです。Slackでのやり取りは迅速でしたし、飲食物で言えば弁当も豪華でデザートの提供もありました。
#オレシカナイト 弁当の豪華さが凄い pic.twitter.com/BxruPB7U6Z
— u++ (@upura0) January 26, 2019
#オレシカナイト の過酷さを物語ってる pic.twitter.com/hOPi0YJuDn
— u++ (@upura0) January 26, 2019
運営さんの差し入れがとても良い #オレシカナイト pic.twitter.com/v9vZdoF8zs
— u++ (@upura0) January 26, 2019
2位の賞品としては、人形を頂きました。
賞品として頂きました #オレシカナイト pic.twitter.com/oO0IVHkln3
— u++ (@upura0) January 26, 2019
私は今回の題材となったAbemaTVのプレミアム会員で、「相棒」をはじめとして頻繁にサービスを利用していました。残念ながら匿名化されている部分が多くドメイン知識を活かせる余地は少なかったですが、自分に馴染みの深いデータに触れられる貴重な体験でした。コンテストの評価指標もビジネス要件に紐付いており、独特な部分にどう立ち向かうか思考を凝らすことができ、非常に楽しかったです。
学びある、とても素晴らしい1日を送ることができました。参加者の皆さま、運営の皆さまに改めてお礼申し上げます。