Kaggle Automated Essay Scoring 2.0 上位解法まとめ

製造業でデータサイエンティストをしている[tk2](https://x.com/kokonatsu2214)と申します。今回は2024年4月〜7月に開催されたkaggleの**エッセイ採点コンペ [Automated Essay Scoring 2.0](https://www.kaggle.com/competitions/learning-agency-lab-automated-essay-scoring-2)の上位解法**を自分用の備忘録としてまとめておきたいと思います。

私自身はまだkaggleを始めたばかりの初心者であるため、手法の解釈違いや英語の読み取り違いなどがあるかもしれませんが、ご容赦頂ければ幸いです。コンペのdiscussionやsolutionのリンクも載せていますので、正確な情報を知りたい方はそちらをご覧ください。

# コンペ概要
このコンペはタイトル通り、**学生が書いたエッセイのスコアを自動採点する**という非常にシンプルなタスクから構成されています。与えられたデータセットもessay idとエッセイのfull textのみで、初心者でも取り組みやすいシンプルなコンペだったと思います。

エッセイにはそれぞれ1点から6点までのスコアが付与されており、スコアが高いほど良いエッセイであることを意味します。なおエッセイの採点基準は[こちら](https://storage.googleapis.com/kaggle-forum-message-attachments/2733927/20538/Rubric_%20Holistic%20Essay%20Scoring.pdf)にあります。

評価指標は**Quadratic Weighted Kappa：QWK**で、順序付き変数の合致度を測る指標です。この指標は挙動が少し分かりづらいのですが、詳細についてはKaggle GrandmasterのJackさんが書かれた[こちらの記事](https://zenn.dev/jackthekaggler/articles/cf988ca341e34ed83034)をお読み頂くのが良いと思います。

訓練データ数は約17,000件、テストデータは約7,000件で、public LBは30%のテストデータで計算されます。

# コンペのポイント
私自身もこのコンペに1〜2ヶ月程度参加していましたが、このコンペの攻略ポイントは主に以下の3点にあったと思います。

**1. 外部データの情報の利用**
**2. CV/LB相関を取る方法の獲得**
**3. ハイスコアの公開notebook**

コンペ初期の[discussion](https://www.kaggle.com/competitions/learning-agency-lab-automated-essay-scoring-2/discussion/496906)において、このコンペの訓練データセットの多くがオープンデータである**Persuade2.0 corpus**と一致していることが指摘されていました。

実際に**訓練データの7割以上**がPersuade 2.0にそのまま含まれていることが確認されています。Persuade 2.0のcorpusには、full textだけでなくprompt name（エッセイ課題の名前）などが含まれており、これらの情報の取り扱いがコンペの一つのポイントになっていました。

またもう一つは**CV/LBの相関**です。これはどのコンペでも往々にしてあることですが、本コンペに関しても単純にkfold splitを行うとCVとLBの乖離が大きく、相関が取れないケースが序盤から指摘されていました。CV/LBの改善はこのコンペの最大のポイントだったと思います。

また最後に**公開notebook**です。コンペ中盤に公開された[notebook](https://www.kaggle.com/code/batprem/aes2-tuning-ensemble)のスコアが非常に高く、コンペ終盤まで多くの参加者が**公開notebookのスコアに勝てない**という現象が起こっていました。コンペ終盤まで公開notebookを上回れば即金メダル圏という状況でしたので、この強い公開notebookをどのように考えてどう扱うかも大きなポイントとなりました。

最終的な結果としてはやはり予想通りshakeが大きく、**Public金圏の参加者が何人もメダル圏外となっていました**。Kaggle GrandmasterのChris Deotte氏も、金メダル圏から大きなshake downを食らっています。

一方でPublic/Private共に金メダル圏に残り続けた参加者もいました。このようにshakeの激しいコンペにおいても上位に残り続けた参加者の解法は、非常に気になるところです。

# 上位解法の共通点
次に**上位解法**についてまとめていきます。個別のsolutionのまとめに入る前に、まずは**多くの上位解法に共通していたポイント**を個人的な観点で以下にまとめてみました。

**1. Kaggle Data（後述）に合わせた2stepの訓練**
**2. 分類ではなく回帰予測を使用**
**3. QWKのthresholdを最適化**

少なくとも私が見る限りでは、本コンペはこれまでの一般的なNLPコンペに見られるようなモデルの細かな工夫はそれほど重要ではなく、**CVの切り方**と**モデルの訓練のさせ方**にポイントがあったように見えました。

実際採用されていたモデルはほとんどがお馴染みの**Deberta**で、特徴的な手法でモデルを学習させていたケースはあまり多くありませんでした。

上位入賞のカギを握る最も大きなポイントが**Persuade2.0に含まれないデータの扱い**でした。

先に述べた通り、本コンペの訓練データにはPersuade2.0と全く同じデータが約7割含まれており（これを以降**Persuade Data**と呼びます）、逆にPersuade2.0に含まれないデータが約3割含まれていました（これを以降**Kaggle Data**と呼びます）。

上位入賞者のほとんどが**Kaggle Dataをメインに用いてモデルを訓練**させており、これによって**LBのスコアやCV/LBの相関が良くなった**と述べられていました。

実はPersuade2.0 corpusに含まれないKaggle Dataをvalidationに用いる点については、コンペ中盤の[discussion](https://www.kaggle.com/competitions/learning-agency-lab-automated-essay-scoring-2/discussion/501202)でも議論されていました。

恐らく**テストデータがKaggle Dataに近い**ことが要因であり、Persuade DataとKaggle Dataの質の違いに気付いてCVの切り方やモデルの訓練方法を決められたかどうかが勝敗を分けたコンペだったように思います。

具体的な解法としては、上記の考え方に基づいて**2stepの学習**を取っている解法が目立ちました。

まずPersuade Dataに対する学習によってモデルのweightを獲得し、次に得られたweightをロードしてKaggle Dataに対してfine-tuningを行うという解法です。上位入賞者のほとんどがこのような形式の学習を行っていたと思います。

その他のポイントとして、評価指標である**QWKのthreshold**も注目すべき点でした。

QWKはカテゴリ変数に対する評価指標であるため、回帰予測を用いる場合には特定のthresholdで予測値を整数値に丸め込む必要があります。本コンペでは**分類モデルよりも回帰モデルの方が精度が良い**傾向にあったため、多くの参加者が回帰モデルの予測値に対するQWKのthresholdを検討していました。

コンペ開始当初は単純なroundで丸めているコードが多かったですが、**thresholdをモデルに合わせて適切に最適化する**ことで精度改善が見込めたようです。

# 1st Place Solution
それでは上位解法の紹介に入っていきます。まずは[flgさんの解法](https://www.kaggle.com/competitions/learning-agency-lab-automated-essay-scoring-2/discussion/516791)です。

publicメダル圏外から**600位以上のshake up**でsolo 1st placeを獲得され、このコンペでGrandmasterになられました。解法のポイントは以下の通りです。

#### CV/validation戦略
* **prompt nameとスコアをラベルとした5fold Stratified KFold**
#### Modeling戦略
* **Deberta base, largeのRegressionを採用**
* **Persuade Dataでpretrainした後、Kaggle Dataでfine-tuning**
* **構築したモデルでPersuade Dataのpseudo-labelingを行う**
* **修正したscoreを用いて再度モデリング**
* **全てのモデルについて3seedを平均する**
* **モデルごとにQWKのthresholdをPowell法によって最適化する**
* **構築したモデルをensemble**

どのようなpretrainを行ったのか書かれていなかったのですが（恐らくMLM？）、まずPersuade Dataでpretrainを行いそのモデルを用いてKaggle Dataでfine-tuningを行っています。

:::note warn
7/27追記
MLBearさんの[解法まとめ記事](https://zenn.dev/ml_bear/articles/bd8bf184732de6)によると、どうやらこの”pretrain”は2段階の学習の1段階目を指しているようでした。
:::

これはEDAやLBのprobeなどから確認した”テストデータはKaggle Dataに近い”という考察に基づいています。Persuade DataとKaggle Dataは、採点時期や基準が異なるのではないかと推定されていました。

構築したモデルを用いてPersuade DataのPseudo Label（連続値）を得て、この”修正スコア”をもとに**再度Debertaによるモデリング**を行っています。solutionにはこの過程を2round繰り返したと記載されていましたが、2round目のモデルはLB精度が低下したため最終モデルにはあまり取り入れなかったようです。

Kaggle Dataは4,500件程度しかデータが無いため、fine-tuningの際には**seedによる予測精度のばらつき**が大きかったようです。そこで**全てのモデルについて3seedを作成して予測値を平均化する**ことで、予測の安定性を担保していました。

またコンペのポイントとなっていたQWKのthresholdについても、同じモデルにおいてもseedによって最適値が異なったそうです。そこで**モデルごとにthresholdを最適化**して予測の安定性を担保したとのことです。thresholdの最適化は、scipy.minimizeのmethod="Powell"を使ったそうです。

このようにして作成した多様なモデルを、最終的にはsimple averageing, Nelder-Mead, Hill-Climbming法（詳細は[こちら](https://www.kaggle.com/competitions/feedback-prize-english-language-learning/discussion/369609)）の３パターンでensembleしています。emsembleについてもoverfitを避けるために、QWKのthresholdと合わせてweightの最適化を行なっています。

結果としては**simple averaging**がprivateのscoreが最も良かったようです。これについてはKaggle Dataの数が少なく、weightの最適化がoverfitを引き起こしていた可能性が言及されていました。

Debertaの学習についてはGeM poolingを取り入れたり異なるtoken lengthで学習させたりと、一般的な工夫が取り入れられており、そこまで特徴的な工夫というのは無かったように思います。それよりもseed averagingの効果の方が大きかったようです。

最終的に1位を獲得したモデルはPublic 619位で、**TrustCVが重要だった**とのことでした。特にPesudo Labelによる再学習を用いた解法は、1st place solitionの特徴だったと思います。

# 2nd Place Solution
続いてsolo 2nd placeの[yaoさんの解法](https://www.kaggle.com/competitions/learning-agency-lab-automated-essay-scoring-2/discussion/516790)です。**Public/Privateともに2位**で、このshakeの大きいコンペの中でも安定して精度を上げられている点が凄いです。

2nd placeの解法も、大枠の考え方は1st place solutionと似ています。

#### CV/validation戦略
* **スコアに基づく4foldのStratified Kfold**
* **validationにはPersuade DataとKaggle Dataの両方を使用**
#### Modeling戦略
* **Regressionを採用**
* **全トレーニングデータでDeberta largeをMLM pretrain**
* **Persuade Dataでfine-tuning（step1）**
* **1st stepの重みをロードしてKaggle Dataで再fine tuning（step2）**
* **oridnal predictionに合わせたlossを設計**
* **hard votingによるensemble**

まず全てのトレーニングデータでMLMによるpre-trainingを行ったのち、このモデルをbackboneとしてPersuade Dataによる1st stepのfine-tuningを行い、**1st stepの重みをロードして**Kaggle Dataによる2nd stepのfine-tuningを行っています。

このような**2stepのfine-tuningによる学習**は、本コンペの上位解法に多く見られました。

QWKのthreshold searchについても検討を行っており、過去コンペのPetFinderの[searching method](https://www.kaggle.com/competitions/petfinder-adoption-prediction/discussion/76107)を利用してthresholdを最適化しています。当初はKaggle Dataのみでsearchしていたようですが、CVは改善したもののLBは悪化したため、最終的には全トレーニングデータでsearchしたそうです。

この理由については、テストデータのテキスト自体はKaggle Dataに近いものだと考えられましたが、**スコア分布は全データに近いものだったのではないか**と考察されています。そのためKaggle Dataだけでなく、Persuade Dataによるthreshold searchやvalidationも取り入れたようです。

そのほか**独自のoridinal regression**を設計したり（詳細はsolutionをご確認ください）、スコアを0~1に標準化してBinaryCrossEntropyで最適化する、attention poolingを取り入れるなどの工夫が見られました。

最終的には構築した5つのモデルで**hard voting**を行い、予測値を決定したとのことです。

QWKのthreshold searchは本コンペにおいて基本的に有効に働いていましたが、訓練データにoverfitしたthresholdだとLBでは大きく精度が低下するケースもありました（これは実際に私も体験しました）。

真のテストデータが何であったかは分かりませんが、テストデータの分布を適切に推測しoverfitを回避したthresholdが見つけられたかどうかも勝敗を分けるポイントの一つだったように思います。

# 3rd Place Solution
続いては日本人でsolo 3rd placeに入賞された[HOさんの解法](https://www.kaggle.com/competitions/learning-agency-lab-automated-essay-scoring-2/discussion/517014)です。HOさんも**Public1位、Private3位**で安定した高順位をキープされています。

3rd place solutionについても、1st, 2nd placeと解法の考え方は似ています。

#### CV/validation戦略
* **prompt nameとスコアに基づくMultilabel Stratified Kfold**
* **Persuade DataとKaggle Dataに分けてsplit**
#### Modeling戦略
* **Deberta base, largeのRegressionを採用**
* **MLMによるpretrainとlayer freezingを行う**
* **まず全データで学習し、Kaggle Dataの評価に基づいてモデルを保存（step1）**
* **step1モデルのweightをロードしKaggle Dataで再学習、Persuade Dataで評価（step2）**
* **Nelder-Meadによりensemble**

HOさんもPersuade DataとKaggle Dataに分けた際のモデルの精度差の分析から、**Kaggle Dataに焦点を置いた訓練**によって精度向上に繋げられています。CVにはprompt nameとスコアに基づくMultilabel Stratified KFoldを採用されています。

一方でKaggle Dataへのoverfitを避けるため、step2の学習では**Persuade Dataをvalidationとしたモデリング**も行なっています。この点は2nd place solutionとも同様ですが、ただ単にKaggle Dataに合わせて訓練すれば良いというわけでも無かったようです。

backboneはお馴染みのDebertaで、MLMによるpre-trainingとlayer freezingを行った上で学習させています。最適なfreeze層数はdeberta baseで9層、deberta largeでは6層だったそうです。またdeberta baseの方が安定したCV/LB精度を得たとのことです。

モデルのheadには、LSTMやmean pooling, attention poolingなどが採用されています。そのほか異なるmax token lengthを採用した種々のDebertaモデルが構築されています。

最終的にはこれらのモデルをNelder-MeadによりWeigted Ensembleしてsubmitしたとのことです。

# その他の解法
4th place, 5th placeくらいまでは詳しくまとめようと思ったのですが、このあたりで力尽きてしまったので詳細は以下のdiscussionをご覧ください。

基本的にはいずれも、**Kaggle Dataについて予測精度が高くなるような学習**が行われている点が主に共通しています。Kaggle Dataの取り扱いは、本コンペ最大のポイントだったと思います。以降ではごく簡単に解法をまとめておきます。

まず4th placeの[tascjさんの解法](https://www.kaggle.com/competitions/learning-agency-lab-automated-essay-scoring-2/discussion/516639)では、**わずか6回のsubmit**で1200位以上のshake upによって金メダルを獲得しています。これは流石としか言いようがありませんね。

Persuade DataとKaggle Dataが異なる性質を持つデータであることに気づき、**これらのデータを区別するためのtag（[A], [B]）をデータに付与**して、スコアの予測とデータソースの分類を同時に解くモデルを構築しています。

またdebertaの訓練においてメモリ使用量を削減し学習を高速化できるtipsもこちらの[notebook](https://www.kaggle.com/code/tascj0/aes2-submit#Model-1:-microsoft/deberta-large)で公開されています。

5th placeの[hengさんチームの解法](https://www.kaggle.com/competitions/learning-agency-lab-automated-essay-scoring-2/discussion/516922)も基本的にはこれまで紹介した解法とほとんど同じで、Persuade DataとKaggle Dataの2段階のfine-tuningを行っています。構築したモデルを、最終的にはPublic LBハイスコアのnotebookとweighted ensembleしてsubmitしたとのことでした。

その他の上位のsolutionに関しても、基本的には似たような解法が多かったように思います。

# その他コンペ雑感
冒頭で公開notebookが強かったと述べましたが、**実はこのコンペは[公開notebook](https://www.kaggle.com/code/qamarmath/deberta-lightgbm-for-automated-essay-scoring?scriptVersionId=175313277)をそのままsubmitすれば銀メダルが獲得できていました**（実際に私自身のsubmitで確認しました）。

実はこのハイスコアの公開notebookは**リークを起こしている可能性が高く**、コンペ期間中も議論になっていました（[参考](https://www.kaggle.com/competitions/learning-agency-lab-automated-essay-scoring-2/discussion/502448)）。しかし結果としてはこの公開notebookがprivate LBでも強く、そのままsubmitするだけで銀メダル圏内に入っていました。

私自身もこの公開notebookを超えるべく様々なモデルの改変を行っていましたが、結局最後まで公開notebookのスコアを超えることはできませんでした。discussionでも議論されていましたが、このnotebookが偶然にもhot spotにハマり高い予測精度が出たのでは無いかと考えられます。

このようなこともあるので、次回のコンペからは公開notebookの扱いについても慎重に行う必要があるなと感じました。上位の解法でもありましたが、1つのsubmitを公開notebookとのensembleにするなどは検討したいと思います。

またコンペ中にもう一つ議論になったポイントとして、**Persuade2.0データの利用可否**がありました。コンペのルール上、予測に使用するデータやモデルは**商用利用可能なライセンス**である必要があります。

今回の訓練データは先述の通り**Persuade2.0 corpusの一部**となっており、データの増強のためPersuade2.0の他のデータを訓練に用いるケースがコンペ序盤から散見されました。

しかしコンペ終盤になって、Persuade2.0は**商用利用不可のライセンス**であることが[discussion](https://www.kaggle.com/competitions/learning-agency-lab-automated-essay-scoring-2/discussion/513018)で指摘されました。ただそもそも訓練データがPersuade2.0を含んでいるため、使っても問題無いんじゃない？みたいな議論もありました。

これに関してホストにPersuade2.0データの使用可否を尋ねる投稿もありましたが、結局ホストから**Persuade2.0データを使って良いかどうかの回答はありませんでした。**

discussionが立てられた段階ではPersuade2.0データを使ってモデルを訓練している人も多く、またその方が精度が良い傾向にあったことから、外部データの利用可否は重要なポイントでした。しかしこの点が解消されずにdeadlineとなったため、困惑した参加者も多かったと思います。

外部データが使えるにしろ使えないにしろ、明確に方針を示してもらえると参加者としては助かったのですが、この点は少し残念なポイントだったと思います。

# まとめ
ということで、本記事では**Automated Essay Scoring 2.0の上位解法**をまとめてみました。タスクとしては非常にシンプルで取り組みやすかったですが、かなりshakeも大きくモデルのトレーニング方法に工夫が必要なコンペでした。

やはりデータをよく見て性質を理解することの重要性を改めて感じましたので、次のコンペではこの反省点を活かしてメダル獲得に向けて取り組みたいと思います。解法の解釈違いなどあるかもしれませんので、誤りを見つけた際は適宜ご指摘頂ければ幸いです。