🦉

Kaggle日記という戦い方

2020/09/29に公開

はじめに

こんにちは、fkubota(Kaggle Expert 20200929現在)です。先日(2020/09/26)行なわれた鳥コンペ反省会kaggle日記というものを紹介させていただきました。思いの外反響が大きく、もっと詳しく知りたいという声も大きかったのでここで詳しく紹介させていただこうと思い、記事を書くに至りました。ちなみに、技術ブログというものをこれまで書いたことがないため、稚拙な文になるかと思いますがご了承ください。

(追記20210603: Kaggle日記についてというスライドを作りました。Kaggle日記を作るに至った背景を書いています。)

想定読者

この記事を見ている人のレベルはさまざまだと思いますが、想定読者としては、ビギナーに向けて書こうと思います。Kaggle始めてみたけど途中で諦めて最後まで取り組むことがなかなかできない人、これから本格的にメダルを取りたい人が想定です。とはいえ、それなりに参加している人、例えばMasterの称号を持っている方にも有用な情報はなくはないと思いますので最後まで見ていただけますと幸いです。

動機

そもそもなぜ僕がコンペの取り組み方を紹介しようと思ったかを話しますと、Kaggleのテクニックの記事が世に多く出ていますが、取り組み方に焦点を当てた記事は少ないなと思ったことが発端です。
僕自身はKaggleについて以下のようなイメージを持っています。

"「Kaggleは長期戦」=「情報戦」である。故に取り組み方というのも一つのテクニックである。"

Kaggleは長期戦です。長いときであれば3ヶ月も戦うことになります。ビギナーであればあるほど、入ってくる情報は新しく膨大になります。それらをうまく処理しなければ情報の波に飲まれ途中で断念するということになります。僕はこれまで3回コンペに参戦していますがどれも楽ではありませんでした。なかなかうまく行かないことが多い状況を数カ月続けるのはそれなりに大変です。

この長期戦であるKaggleをうまく戦うというテクニックの一つとしてKaggle日記を紹介しようと思います。

長期戦であると何がおこるのか

長期戦であるKaggle、コンペが中盤から後半にかけて以下のことを経験した人は少なくないのではないでしょうか。

  • 以前良いなと思ったdiscussionが見つからない。
  • なんとなくいいなと思った記事や論文を保存しているがどれを読んだのか読んでいないのか把握していない。読んでいたとしても正直覚えていない。
  • notebookの命名規則が破綻。手に負えない。
  • 1月前にやったことの記憶が曖昧。

などなど。

僕はこれらの問題に対して、Kaggle日記という方法で対処しています。これから順を追って説明していきます。

長期戦に備える

僕が長期戦を意識して取り組んでいることは大きく分けて3つほどあります。

  • アイデアの吐き出し場所を作ること
  • ファイル名で管理しないこと
  • Kaggle日記をつけること

それぞれ紹介していきます。

アイデアの吐き出し場所を作る

Kaggleをしているとあらゆる場面でアイデアは浮かんできます。notebookを編集している時、discussionを読んでいる時、論文を読んでいる時、Submitした結果が返ってきた時、散歩している時など、様々な場面でアイデアは生まれます。僕はこれらのアイデアを脳で管理することは難しいと思っています。その都度どこかに書き出しておくことをオススメします。僕はこれまで、markdownのtodoリスト(分子コンペイオンコンペ)で管理したり、githubのissue(鳥コンペ)で管理したりしてきました。どの方法でもいいので思いついたらどこかにすぐ書くということをおすすめします。ちなみに鳥コンペでは、ゴミのようなアイデアも多いですがまだアイデアが40個ほど余っていました。これまでのコンペでアイデアが付きてやることがないという状況を一度も体験していません。

あるノートブックを読んでいて、これ試してみたいなと思えば書き出します。それを試した結果、パラメータを変えたほうがいいと考えたのであれば書き出します。パラメータを変えて提出してみるとスコアが下がりました。仮説が否定されたことになります。そして新しい仮説を思いつきました。それを検証するにはこうしたほうがいいなと思ったのでそれを書き出します。

こんな感じでどんどん消化したり溜まってきたりします。

ファイル名で管理しない

個人的にファイル名管理は確実に破綻すると考えています。そのため僕ははじめからファイル名で管理しません。ファイル名で管理しないということがどういうことかを説明するより以下の図を見るほうが明らかだと思います。

先頭の番号以外全て同じ名前です。違いがわかりません。では、ノートブックを開らかなければ中身がわからないのでしょうか。もちろんそんなことありません。後ほどKaggle日記とともに紹介します。ここで大事なのは、徹底的にファイル名で管理しないことです。ファイル名ではなにもわからないという不便な状況を作っておけば人間どうにか対処しようと考えるものです。

Kaggle日記をつける

いよいよ本題です。僕はKaggleで発生するあらゆる情報をこのKaggle日記で管理しています。本当にいろいろなタイミングでKaggle日記を利用するので簡単に説明できないのが歯がゆいですが、例を交えながら伝えていきたいと思います。具体的な書き方、使い方に入る前に一度目を通してもらいましょう。今回の鳥コンペのKaggle日記です。

Kaggle日記(鳥コンペ): https://github.com/fkubota/kaggle-Cornell-Birdcall-Identification

書く場所はどこでも良いですが、僕はコンペ用のgithubリポジトリのREADME.mdに書いています。これはそのまま外部へのアピール、実績になるとも考えています。今回の鳥コンペのKaggle日記はpdfにして50ページ以上にも膨れ上がっていました。この量に驚く方もいるかもしれませんが、2ヶ月近く戦ったことを考えるとそこまでの量ではありません。1日に書く量はごく少量です。

Kaggle日記の全体構成

Kaggle日記の全体構成としては以下のようになります。

大部分をLog が占めていますがこれが重要です。その他部分は見てもらえればわかると思いますし人によって使い方は変わってくると思いますが僕がどのように使っているかを簡単に紹介したいと思います。

Kaggle日記のその他部分

Dataset
鳥コンペでは、 Pytorchを使用していたため、Datasetを作ることが多かったのでまとめました。データセットの簡単な説明とそのデータセットを作成したときのノートブックNoが記入されています。テーブルコンペであれば、このような形で特徴量を整理していました。

Paper
論文などを整理する部分です。statusが大事です。Todo, Doing, Done の3ステータスで管理していました。また、Noを振っています。これは僕にとっては非常に重要で、 issueやKaggle日記、notebook内で、paper04paper07 などという名前で登場します。僕のリポジトリでは、あらゆる情報がこの通し番号によって管理されそのデータベースとしてKaggle日記が機能しています。このあたりもこの後徐々に明らかになっていきます。

Kaggle日記のLog部分

僕の(Kaggleやってるときの)1日のスタートは、Kaggle日記に 20200726 といったように日付を書くことから始まります。鳥コンペ参加した初日は以下のような感じです。

こんな感じで気づいたことを書いておきます。全てでなくていいです。無理して続かないぐらいならクオリティを落とすべきというスタンスです。

他にも見てみましょう。この日は有用そうなdiscussionを見つけた日のようです。以下のようにメモをとっていました。

鳥コンペ反省会でも登場していたカエルの人や鳥コンペを終始引っ張っていたアライ大先生が出てきています。カエルの人は僕の場合はカエル先生と呼んでいました。上のようにざっくりと要点だけをメモしておきます。これが毎日のように蓄積されかなりの量になります。1ヶ月後に「カエル先生とアライさんが会話してたディスカッションそういやあったなーどこだっけなー」となれば、ctrl+f カエル先生で適当に探せば上の会話が見つかります。

次は、notebookKaggle日記 の関わりについて見ていきます。前述したようにnotebook名は非常に簡素でNo以外同じというファイルも多く有ります。

このnotebookは、Kaggle日記内では、nbxxx という名前で出てきます。 例えば、以下のような感じです。

この nb030 という名前はあらゆるところで出てきます。issue内で使われることもありますし、nb030 で作られた生成物(モデルなど)のファイル名には、nb030 という文字列が登場します。

次にKaggle上で作成したnotebookについてです。上記のnotebookと同様に番号で管理します。名前は、kagglenbxx_hogehoge といったように作成しました。

また、鳥コンペはコードコンペでしたので、

  1. ローカルでモデル作成
  2. kaggle notebook にモデルを渡す
  3. submit

という方法を取りました。そのため、kagglenb24_from_nb030 といった名前を付けています。nb030で作成したモデルをkagglenb24で使用するという意味になります。このkaggle notebookはKaggle日記では下記のように記入しています。

以上がKaggle日記のLog部分の書き方になります。
ざっと説明したところでもう一度見てもらいましょう。そこまで複雑なことをしていないことが解ると思います。

Kaggle日記(鳥コンペ): https://github.com/fkubota/kaggle-Cornell-Birdcall-Identification

トレーサビリティ

トレーサビリティ。かっこよく言いましたが、情報のソースにたどり着けるようにしているよという話です。仕事でもそうですが、トレーサビリティというものは大事にしています(当たり前ですが)。ここでちょっとKaggle日記の便利さを体験してもらいましょう。

イメージとしては1ヶ月前のKaggle日記を見ていると思ってください。

どうやら、信じられないほどの低スコアを出したようです。文字からストレスが滲み出ています。nb013で作ったモデルをサブしたようですのでnb013の日記を見てみましょう。

ここでも事件が起こってるようですが今は良いでしょう。どうやらSpectrogramEventRmsDataset
というデータセットを使用しているようです。そしてnb012で作ったものであることもメモからわかります。メモがないとしても、Kaggle日記上方には以下のメモがあるのでここでもトレーサビリティは取れています。

SpectrogramEventRmsDatasetの詳細を知るためにKaggle日記を見てもいいのですがここでは、nb012を見てみましょう(こちら)。
まずは、Overview。

このnotebookの概要です。仕事でもKaggleでもかならず一番上にOverviewという名前でnotebookをスタートさせています。ここでも nbxxx というキーワードが頻出しています。nb011nb012 ではどのような処理をしていたのでしょうか?気になる場合は、notebookを開かずともKaggle日記を見れば概要を掴めます。さらにnotebookを下方にスクロールさせるとConst が見えてきます。

ここもとても重要です。使うモデル、特徴量、その他のデータを列挙します。図の赤い矢印を見てください。僕はかならず、最初にNB という変数、つまりnotebookの番号を定義します。例えばモデルを保存するときの名前は、

save_path = f'{NB}_model_{model.__class__.__name__}.pth'

という形で定義しています。このように生成物には必ずnotebookの番号がひも付きます。いくつか例をお見せします。

その生成物が作られた過程を知るためにnotebookを開く必要はありません。もうご存知のようにKaggle日記に簡単なレシピが書かれています。より詳細な情報が必要になったときにnotebookを開けば良いのです。

見返す

Kaggle日記は書いただけで終わってはいけません。蓄積された情報もそのまま腐らせてはいけません。
僕の場合、3~5日に一度Kaggle日記を上から下まで眺めます(15分もあればできるかと)。今まで何をやって何を失敗したのか。そして今どこに向かって実験をしているのかを把握します。これをすることにより迷子になることを避けることができます。この見返しの時にもアイデアは生まれます。1ヶ月前に「ふーん」とだけ思っていたdiscussionの何気ないコメントが1ヶ月後に光り輝いて見えるときがあります。また、情報の分岐が激しくなったときはマインドマップを使って状況を整理することもよくやります。この時必要な情報をKaggle日記からピックアップして整理するので早く行なうことができます。
下記の図は、自分で埋め込んでしまったバグをfixするために整理したものです。あるノードが否定されればその下の枝はさっぱり考えなくていいので思考がすっきりします。

これは余談ですが、イオンコンペの時にはマインドマップを使ってアンサンブルの作戦を立てていました(url)。先にマインドマップを作ってそれを埋めるようにモデルを作成しました。

続けるために

続けるための工夫もあります。無理をしないことです。ここまで見てもらったようにかなりラフに書いています。もし後になってラフな情報に足りないものがあればその時に足せばいいです。また、以下のようなこともよくやります。

- nb010 <--------- 書け!!

- nb011 <--------- 書け!!

#### 20200930
翌日のオレへ。nb010とnb011へ追記をしなさい。

翌日(20200930)の気が向いた時間に書き込みます。穴があったら埋めたくなるのが人間というものだと思ってこの作戦を多用しています。

メダルを取るために

今の所3回参戦したコンペ全てでメダル(銀1, 銅2)を取ることができています。一番のコツは最後までやることです。メダルを取った多くの人が言うように銅メダルを取ることはそれほど難易度は高くないと思っています。難しくはないですが大変ではあります。僕は長期戦を戦い抜くためにKaggle日記という戦い方を選びました。この方法は万人ウケする方法ではないとも思ってはいます。興味を持ってくれた方はこの方法をベースに自分なりの方法で戦っていただけると幸いです。また質問がある場合はtiwitter のDMでも構いませんのでお気軽に質問してください。最後まで読んでくださりありがとうございました!!!

Discussion