脱・Kaggle初心者 〜 一歩先に行くためのノウハウ:Kaggle入門
Kaggle初心者が「初心者」から抜け出して一歩先に行くために何をすればよいのか。実際のコンペでの実践事例を示しながら、ランクを上げていくためのノウハウを紹介する。
導入
この連載では、近年話題のコンペティションプラットフォーム「Kaggle」について、リクルート所属のKaggle Master 4人がKaggleの仕組みや取り組み方、初心者から一歩先に行くためのノウハウについて解説を行います。
第1回では、これからKaggleを始めようと思っている方向けに、Kaggleの仕組みや実際にコンペティションに出場した後の取り組み方、初心者におすすめのコンテンツについて解説を行いました。第2回では、ランクを上げていくために筆者が「実際に何をしていたか」について、実際の事例を交えながら解説していきます。
自己紹介
羽鳥冬星(はとりとうせい)
- 株式会社リクルート データソリューション2ユニット HRエージェントデータソリューション 2グループ
- 2015年新卒入社
- 人材領域のレコメンドシステムの改善を担当しています
- 趣味:分析コンペティションとスマブラ
阿内宏武(あうちひろむ)
- 株式会社リクルート データソリューション2ユニット マリッジ&ファミリー・自動車領域データソリューション2グループ
- 2016年新卒入社
- 販促領域のデータ活用全般を担当しています
- 趣味:オセロ
佐々木彬(ささきあきら)
- 株式会社リクルート データソリューション2ユニット HRエージェントデータソリューション2グループ
- 2018年新卒入社
- 人材領域のレコメンドシステム、検索システムの改善を担当しています
- 趣味:ルービックキューブ
小畑堅人(おばたけんと)
- 株式会社リクルート データソリューション2ユニット HRエージェントデータソリューション 2グループ
- 2018年新卒入社
- HR領域の集客周りの改善を担当しています
- 趣味:子育て
コンペティションに参加してからやるべきこと
内容理解とルール確認
コンペティションに参加してまず着手すべきことは、何よりも内容の理解とルールの確認です。特に重要なページは、Description(コンペティション概要)、Rules(ルール)、Data(データ説明)、Evaluation(評価指標)、Code Requirements(コードの要件、※コンペティションの形式次第では存在しない場合もある)です。その他に、コンペティションによってはDiscussionの中にコンペティション主催者と会話できるスレッドも立っている場合があり、ここでもルールやデータの性質などに関する重要な議論が交わされることが多いので、必ず確認するようにしましょう。
特に、最近の自然言語処理系コンペティションや画像系コンペティションの場合、事前学習済みモデルを使える場合も多く、それによって最終的な成績が大きく変わることもあります。この際、コンペティションのルールによっては利用する事前学習済みモデルをDiscussionで書いておかなければ、ルール違反となる場合もあるので注意してください。
ベースライン作成
コンペティションの概要やルールについて十分に理解できたら、次はEDA(探索的データ解析、前回の記事を参照)を実施しながら必要最低限のベースラインを作ることが多くなります。この際、コンペティションによっては複雑なデータの前処理が必要なこともあるので、Notebook中のベースラインを参考にするとよいでしょう。ただし注意点として、コードの中身を理解せずにコピペだけでベースラインを作ってしまうと、その後に改善することが困難になってしまいます。そのため、できる限りベースラインのコードを理解し、時には自分なりに使いやすいようにアレンジ、リファクタリングしながらベースラインを作るのがおすすめです。
サブミット
無事にベースラインができたら、早速サブミットしてみましょう。サブミットして、参考にしたNotebookと同程度のスコアが出ていればひとまず安心です、お疲れさまでした!(これは長い戦いの始まりに過ぎませんが……)
パイプライン構築
「ベースラインができたら、次は改善です!」……といきたいところですが、もしここで時間に余裕があったらひと手間を加えて自分なりのパイプラインを作ると、この後の改善がしやすくなります。仮にパイプラインを作っておかないと、以下のような場面で困ることになります。
- 特徴量をどんどん追加したはいいが、数が増えすぎて、どの特徴量が効いていたのかが分からなくなってしまう
- 最高性能をたたき出していた時のハイパーパラメーターを見失ってしまう
- 実験のたびに、前処理、特徴量の生成、学習、予測、後処理のそれぞれでスクリプトを手作業で回すことになり、つきっきりで実験を見守ることになってしまう
パイプラインを作っておかないと、このような困りごとが生じてしまい、結果として改善のサイクルが遅くなってしまうことにもなりかねません。
それでは、パイプラインにはどのような要素が含まれるとよいでしょうか? 明確な正解はありませんが、以下のような要素を取り入れている傾向が見られます。
- 実験全体を1コマンドで実行できるように抽象化する
- ハイパーパラメーターや利用する特徴量など実験ごとに変わり得る部分はスクリプト中にベタ書きせず、設定ファイルなどに分ける
- 実験ごとにどの設定ファイルを使ってどのような結果が出たかをCSVなどに記録し、振り返られるようにする
- 設定ファイルを含めてGitでバージョン管理をするなどして、実験結果とスクリプトをいつでも振り返られるようにし、かつ巻き戻せるようにする
- Kaggle APIを使うなどして、サブミットの実行やその結果の取得なども、スクリプト中から実行可能にする
- 実験状況をSlackなどに送信し、いつでもモニタリングできるようにする
コンペティションの落とし穴
次に、Kaggle初心者が陥りがちなコンペティションの落とし穴について、実例を挙げながら説明します。これから説明する、Kaggleでありがちな落とし穴を回避することもランクを上げていく上で重要です。
事例1:Train/Public/Privateデータ間の質の違い
まずは、「Private LeaderboardのTestデータとTrainデータの分布の違いに注意」することです。
前回の記事でも説明した通り、コンペティションの期間中はPublic Leaderboard(以下、Public LB)、最終的にはPrivate Leaderboard(以下、Private LB)での評価が行われます。ここで大事になるのは、学習に使うTrainデータと、Public LBおよびPrivate LBの計算のために使うTestデータの間にどの程度の相関がありそうかを事前に把握しておくことです。特に、Public LBのTestデータ(以下、Publicデータ)とPrivate LBのTestデータ(以下、Privateデータ)の質に予期せぬ違いがある場合、Public LBの順位とPrivate LBの順位が大きく異なるなどということも発生します。
「TalkingData AdTracking Fraud Detection Challenge」は、Testデータを使って未来の情報をうまく取り入れる特徴量の作成方法が重要となるコンペティションでした。特徴量としてIPアドレスやOS、アプリ、デバイスの情報とクリックした時刻が与えられており、Trainデータ、Publicデータ、そしてPrivateデータは時間軸に沿って分割されているシンプルなデータセットです。このコンペティションでは、多くの参加者が未来の情報をモデルに入れるために、「あるIPアドレスが次にクリックするまでの時間」などの特徴量を作成していました。
しかし、このようにして作った特徴量には一つの落とし穴がありました。それは「Privateデータにのみnullが多く発生する」ということです。例えば下記の表1のような[ip]と[click_time]からなるログが与えられていた場合、「あるIPアドレスが次にクリックするまでの時間」は[next_click_ip]列のようになります。この表から各IPアドレスについて、時間軸の最後に出現したものについては[next_click_ip]がnullになることが分かります。
ip | click_time | next_click_ip |
---|---|---|
18787 | 2017-11-06 14:34:52 | 60 |
18787 | 2017-11-06 14:35:52 | 8 |
18787 | 2017-11-06 14:36:00 | 892 |
18787 | 2017-11-06 14:50:52 | null |
19000 | 2017-11-06 14:32:02 | 510 |
19000 | 2017-11-06 14:40:32 | null |
表1 時系列データから未来の情報を特徴量として作成した例 |
今回は、Privateデータが時系列の後半に設定されていたために、「Trainデータではnullがあまり発生しないが、Privateデータには比較的多くnullが発生する」という現象が生じていました。これに対処するには特徴量を計算するウィンドウを日や時間で区切る必要があったのですが、それに気が付かなかった参加者はPrivate LBで順位を大きく落としてしまったようです。私(羽鳥)もその一人です。
事例2:Train/Public/Privateデータ間の分布の違い
次に、「Microsoft Malware Prediction」の例を挙げてみたいと思います。このコンペティションは、Malware(マルウェア)に感染したWindows PCを判別するコンペティションでした。データとしてはマシンのIDやデフォルトブラウザの種類といった基本的なものから、「ファイアウォールが有効か」などの比較的詳細な情報までが与えられていました。
結論からいえば、このコンペティションはKaggleの歴史に残る大規模なshake down(※shake:Public LBとPrivate LBの順位が乖離すること。shake downはPublic LBと比較してPrivate LBで大きく順位を下げることを指す)を生み出しました。私(羽鳥)もそれに巻き込まれた一人です。驚くべきことにPrivate LB TOP 5の参加者はPublic LBから全員1000位以上順位を上げており、反対にPublic LBで金メダル圏内にいた参加者はPrivate LBでほとんど消え去ってしまいました。
その理由の一つは、PublicデータとPrivateデータの分布の違いにあったようです。Public LBでも上位に入り、Private LBでも6位に入ったCPMPさんの解法では、図1のように赤い線のTrainデータと青い線のTestデータで分布が違う状態だったので変数を手作業でビニング(=変数を幾つかのビン、つまり一定の区間ごとでまとめる手法)したそうです。
図1 TrainデータとTestデータで分布が違う状態
コンペティション「Microsoft Malware Prediction」のDiscussion「Our Solution (CPMP view)」(=CPMPさんの解法)より引用。
この結果、図2のようにTrainデータとTestデータの分布の違いが軽減され、adversarial validation(TrainデータとTestデータの分布の差を測る手法)のスコアが0.98程度から0.7程度まで小さくなったようです。このようにしてTrainデータとTestデータ全体の性質を似たものにすることで、Trainデータを使ったlocal validationのスコア、LBのスコア、Privateのスコアが相関することになり、結果的にshake downを防ぐことができたようです。
図2 変数を手作業でビニングした結果
コンペティション「Microsoft Malware Prediction」のDiscussion「Our Solution (CPMP view)」(=CPMPさんの解法)より引用。
事例3:Publicデータへの過剰適合
次に、「Public LBにoverfit(過剰適合)してしまうことの危険性」について、2つの実例を交えながら共有します。
Copyright© Digital Advantage Corp. All Rights Reserved.