Kaggleに挑戦！

こんにちは！京都大好きキョートマンです！！<br>
12月も半ばとなり、すっかり寒くなりましたね。<br>
師走の京都といえば、大根焚きに顔見せに風物詩が目白押しです！<br>
しかし京都好きな私にも、いくつか京都に対する不満点はあって、その一つがクリスマスムードの弱さです！すでにお正月の圧力に押されて、クリスマス色は弱めです・・・。<br>
東京では、クリスマスイルミネーションがあちこちにあって目を飽きさせる暇がありませんよね！六本木や表参道など、イルミネーションスポットは数多くありますが、目黒川沿いのピンク色のイルミネーションが個人的に気に入ってますね。<br>
さて、そんな目黒川沿いにある、東京は品川区の株式会社スカイウイルでは、データ分析コンペを開催しているKaggleに挑戦しています。

今回のこの記事では、スカイウイル社のメンバーで参加したKaggleへの挑戦を行なった報告を行います。学ぶことの多い実りある経験でしたので、もしこれからKaggleに参加しようとしている方がいらっしゃれば参考になるかもしれません。
## 参加したコンペ
今回わたしたちが参加したのは、「Feedback Prize - English Language Learning」という自然言語系のコンペです。<br>
以下に、コンペの趣旨や提供データなどを軽くまとめておきます。
### コンペの趣旨
![ホーム画像](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982431/b1c855ac-74ef-6383-fe00-8e2122e5bb99.png)
このコンペの趣旨は写真にある(Goal of the Competition)にまとまっています。
>The goal of this competition is to assess the language proficiency of 8th-12th grade English Language Learners (ELLs). Utilizing a dataset of essays written by ELLs will help to develop proficiency models that better supports all students.
>Your work will help ELLs receive more accurate feedback on their language development and expedite the grading cycle for teachers. These outcomes could enable ELLs to receive more appropriate learning tasks that will help them improve their English language proficiency.

簡単にまとめると以下の通りとなります。
- 英語を学ぶ8年生から12年生の生徒(ELLs)の英語力を測る
- 彼らに正確なフィードバックを与えることで、英語力向上を効率化する
### 提供されたデータ
今回のコンペで提供されたデータは全部で9.3MBと、一般的な自然言語処理のコンペのデータサイズよりかなり小さく、ストレージや計算資源の面からは取り組みやすいコンペだったと思います。<br>
具体的な提供データは、
- sample_submission.csv(178B)
- test.csv(8.82kB)
- train.csv(9.29MB)

です。<br>
例えば訓練データの中身は以下のようになっています。
![train_data.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982431/06b12c52-1173-8555-f5f3-8cc46a4c5ffd.png)
ここの"full text"を学習して、"cohesion(まとまり)","syntax(構文)","vocabulary(語彙)","phraseology(言い回し)","grammar(文法)","conventions(伝統的表現法)"の得点を予測することになります。5点満点です。
### 評価方法
mean columnwise root mean squared error(MCRMSE)で評価します。列ごと（今回の場合はcohesionやsyntaxなどのターゲット列ごと）のRMSEを求めた上で平均をとるような感覚ですね。
$$
MCRMSE = \frac{1}{N_{t}}\sum_{j=1}^{N_{t}}\sqrt{\frac{1}{n}\sum_{i=1}^{n}(y_{ij}-\bar{y_{ij}})^2}
$$
このMCRMSEの値が小さいほど良いことになります。<br>
なお今回のコンペでは、上記のスコア評価以外に、もう一つ評価方法がありました。それがEfficiency Prize Evaluationです。この評価方法では、実行時間と評価性能の両方から総合的に評価されます。そして重要なことにCPUしか使えません（GPUやTPUは不可）。一般的に言って、計算資源を多く持つ人が有利なのは間違いありません。そして普通の評価指標では、そのような計算資源をゴリゴリ回して良いスコアを取った人がスコアボードに載ることになります。しかし、そのような結果はえてして解釈や説明の難しいモデルを使っていたり、機械学習の教育には適していなかったり、何より計算資源の有無で不平等なものとなってしまいます。この問題に対処した指標がEfficiency Prize Evaluationです。このコンペでは、こちらの指標で良いスコアを取ったチームの方が賞金が高く設定されています。
![賞金](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982431/02be6e92-f4a2-d62f-01e5-c4f60a7718b5.png)

なお、Efficiency Prize Evaluationの評価式は以下の通りです。
$$
Efficiency = \frac{1}{Base - min(MCRMSE)}MCRMSE+\frac{1}{32400}RuntimeSeconds
$$
ここで$Base$はあるベースラインです（どんなベースラインかはよくわかりませんでした）。第１項でMCRMSEの成果を抑えつつ、第２項では時間経過のペナルティを与えていますね。
## 取り組んだこと
### チームでの協力方法
私たちのチームでは、チームメンバーが個々に取り組み、それによって得られた結果をアンサンブルするというアプローチでこのコンペに臨みました。そのために、使ったモデルやパラメータなどをgoogleスプレッドシートで共有するなどしました。また週に一回はオンラインミーティングの時間を設けて、進捗確認などを行いました。
### 計算環境
GPUを使うために、google colabのproを使用しました。今回のコンペでは、Kaggleにスコアを提出する際は、notebookそのものを提出するタイプでした。困ったことに、notebookを提出する際のコミット作業で一度notebookを実行する必要があり、そのためにKaggleで使うことのできるGPU使用量(一週間で30時間分)がなくなるということが多発していました。そのため、普段のモデル学習などはKaggleのGPUを使わずに温存する必要がありました。そこで用いたのがgoogle colabのproです。google colabは課金することでproと、さらに上位版のpro+にすることができます。幸いにも今回のコンペはデータ量が比較的少なかったのもあり、colab proの計算資源で足りました。
### 使ったモデルやテクニック
言語処理モデルとして使ったのは主にDeBERTaです。他にはRoBERTaやLUKEも使いましたが、今回のコンペでは、他のチームの様子を見てもほぼDeBERTaの一強だったようです。DeBERTaは特定のタスクにおいては人間の言語能力をも凌駕する言語モデルです。別記事にDeBERTaの扱い方や解説などもまとめてみたいですね。<br>
また、今回のコンペでよく効いたテクニックとしては以下のようなものがあります。
- MeanPoolingなどのPooling技術
- re-initialize last layer
- layerwise learning rate 
- inputのユニークなトークンに着目してStratified KFold

MeanPoolingは有名で、機械学習の参考書にもよく載っていますね。これ以外にも色々Poolingはあって、組み合わせたりしてスコア向上に寄与していました。例えばMeanPoolingは、各トークンに対応する埋め込み表現を平均する手法です。他によく使われるMaxPoolingでは、埋め込み表現で最大のものを抽出する手法です。re-initilize last layerは、私もこちらのコンペで初めて知りました。これはどんなものかと言いますと、再利用する学習済みの言語モデルの最後の層だけを初期化するものです。Discussionでも大いに議論が交わされていたので、これを機に勉強したいところです。layerwise learning rateはニューラルネット層ごとに学習率を変化させるテクニックです。インプット層からアウトプット層になるにつれて学習率を上げていくと効果が大きかったです。inputのユニークなトークンに着目したStratified KFoldとは、CVの精度を上げるために使用しました。実際にこちらのテクニックを使うことで、手元のCVとpublic LBの順位が相関するようになりました。<br>
これらのことももっと詳しく書きたいので、また機会があれば別記事でまとめたいです。
## 結果
上記のような取り組み方でコンペ開催中は調子よく進んでおりました。リーダーボードで140位ほどまで上がり、シルバーメダルにも手が届きそうなくらいまでいった時は興奮しましたね！しかし蓋を開けてみれば順位はダダ下がり（805位に下落）、ブロンズメダルの獲得は硬いだろうと思っていたのに、それすら獲得できない結果に終わってしまいました・・・泣<br>
今回のコンペではpublic dataとprivate dataで大きな質の違いがあったようで、public LBとprivate LBで大きな順位の入れ替えが発生していました。
![最終順位](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982431/a329a546-5e26-bb95-2be6-516df831ab70.png)
Kaggleの怖さを感じた結果となりました笑
それでも逆にランクを急上昇させたチームや、さらにすごいことには最初から最後まで上位に踏みとどまるチームもいました。やはりまだまだ道のりは長いです！
![急上昇者](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982431/23012556-c730-e0d8-2321-48a0e7e81ce8.png)
↑1000位以上ランクを上昇させているチーム（個人）
![上位者](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982431/1bc886f5-d351-bb97-e043-9715ec30155b.png)
↑1位しかランクを動かしていないチーム

## 反省点
反省点はいくつかあって、簡単に列挙すると以下のようなものがあります。
- 単純にモデルを動かして訓練を行うこと自体が大変で、サブミットまでなかなか辿り着けない
- 個人作業がメインになりがちで、チーム内で連携があまり取れなかった
- モデルに多様性がない
- discussionなどを真似してばかりで独創性がない
- 本業の業務が忙しく、なかなかKaggleに時間が割けなかった

コンペが終わった直後はやれることは全てやったような気がしていましたが、いざあまり振るわなかった成績や上位者の解法を見ると、もっと色々とやりようはあったなと反省します。<br>
一つ目の反省点であるモデルを動かすことが大変ということに関しては誰しも最初は通る道でしょうからまあ良いとして、二つ目の反省点であるチームで連携をうまく取れていなかったのは大きい反省点かなと思います。色々割り振りとかを決めておけば、三つ目の反省点であるモデルの多様性問題なども解消したかもしれません。<br>
四つめの独創性に関しては、レベル的にまだ次のステージのような気がしています。基礎的なことを学び取ったら、ぜひ自分からnotebookをdiscussionにアップするなどして、Kaggleの議論の輪に加わっていきたいところです。<br>
さて最後の反省点である業務とKaggle問題ですが、これはどうやってモチベーションを上げていくかという問題であると感じます。業務と満員電車の通勤退勤で疲れた体と頭では、あまり興味の惹かれないことに取り組むのは単なる苦行でしょう。ですからKaggleを好きになる必要があります。息抜きでやるような面白いゲームとして行うならば、業務との両立も難しくはないはずです。とはいっても、好きになろうと思って好きになれるものでもないとは思いますので、これは個人個人の性格の問題なのかなとも思います（優劣の問題ではないです）。

## 終わりに
コンペを終えてみて、非常に悔しく感じております。リベンジに燃えています！！鉄は熱いうちに打てとも言いますし、このコンペで得た知見を手放すのも惜しいですし、また似たようなコンペに参加したいです！！！<br>
次こそはメダル獲得。そしていずれはグランドマスターへ。臥薪嘗胆。