はじめに
はじめまして。DX Technology Unit 通信セキュリティ技術開発 Teamの福嶋です。ARISE Kaggle部の活動記へようこそ。
今回、データ分析コンペティションプラットフォームであるKaggleにて開催されたCommonLit – Evaluate Student Summariesにソロで参加し、2064人中12位で入賞(金メダル!)、そして念願のKaggle Competition Masterとなることができました。
今回は、そのコンペの解法を紹介したいと思います。
コンペの概要
このコンペの目標は、学生が要約した文章の質を定量的に評価することです。
データセットとしては、ある特定の文章の全文とタイトル、設問、それに対する学生の要約文、教師がRubric[1]に則り評価した二種類のスコアが与えられます。要約文を入力として教師の評価した二種類(Content, Wording)のスコアをより精度よく予測できるモデルを作成することが最終的な目標となります。
このような自動採点モデルは、多くの学生が要約した文章に対し迅速なフィードバックを可能にし、読解力や文章力の向上の助けになることが期待されています。
方針
Kaggleで上位入賞している方々の特徴として「異なる特徴によって学習された、精度が高い複数のモデルをアンサンブル」している傾向があります。それを参考に今回は以下の二パターンのモデルを作成し、改良することで精度を上げていくことにしました。
- 「元の文章」「設問」と「要約文」の関係性に焦点を合わせたモデル(長文を入力するので、便宜上Long Modelと呼ぶ)
- 「要点が捉えられているか」「設問に正しく答えられているか」等マクロ的な特徴を捉える
- 「要約文」のみの焦点を合わせたモデル(上記と比較して短い文を入力するので、便宜上 Short Modelと呼ぶ)
- 「良い単語・熟語を使っている」「関係代名詞を使っている」等ミクロ的な特徴を捉える
前者はContent、後者はWordingの精度向上を意図していますが、ContentとWordingには正の相関関係があり、互いに影響しあっている可能性があったため、両モデルとも両方のスコアを目的変数としました。
解法
Long Model
まず、基本的な構造を決めていきます。
入力データはQAタスクと同様に考え、「要約文」+ [SEP] + 「設問」+ [SEP] +「元の文章」の形式で入力し、自然言語モデルのTokenizerに与えることとしました。なお、最大長は1536トークンです。
(※ [SEP]は、自然言語処理において複数のテキスト文を入力する際に用いられる区切りトークン(Separate Token))
バックボーン(BERT, RoBERTaなど)は、入力データが最大約1500単語であったこともあり、長文が入力できるものである必要がありました。長文が入力できるものとして、DeBERTa[3]、LongFormer[4], BigBird[5]などが挙げられますが、精度検証した結果deberta-v3-largeが最も精度が高かったため、今回はこちらを採用しました。
次にハイパーパラメータや細かい調整についてです。
学習率、エポック数などのパラメータのチューニングの多くはあまり精度に影響がありませんでしたが、Pooling, Freezing, Ensembleの改良が特にこのモデルの精度向上に寄与しました。他にもいくつかありますが、今回はこの3つに焦点をあてます。
Pooling
Transformer系統のモデルは、入力のトークン単位でベクトルを出力するため、文章の分類においてはPooling処理を通し、文章単位のベクトルに圧縮する必要があります。
Poolingの方法にはいくつか存在し、有名なところだとCLS Pooling, MaxPooling, Concat Pooling, GeMPoolingなどが挙げられます。
有名どころのPoolingを試した結果、Concat Pooling(最終N層のCLSベクトルを連結させる)が最も精度が良かったのですが、予測に8時間かかることが判明しました。今回のコンペでは9時間以内に予測しなければならず、このままではアンサンブルを行う時間的余裕がありません。そこでCLSベクトルを連結させるのではなく平均を取ることでモデル必要パラメータ数が減少し、僅かな精度劣化で推論時間の短縮(8時間→6時間)に成功しました。(なおAMP[7]によっても推論時間の短縮は可能なのですが、なぜか精度が極端に悪くなってしまったので断念しました。)
class CLSMeanPooling(nn.Module):
def __init__(self, n_layers=4):
super(CLSMeanPooling, self,).__init__()
self.n_layers = n_layers
def forward(self, all_hidden_states):
concatenate_pooling = torch.cat(
[
all_hidden_states[-(i +1)][:,0].unsqueeze(-1)
for i inrange(self.n_layers)
],-1
).mean(-1).squeeze(-1)
Freezing
これは、過去の自然言語コンペでも多くの使用例がありますが、バックボーンの先頭N層の学習を行わない(Freezing)というものです。deberta-v3-largeは24層のTransformerによって構成されるためそのうち先頭の12層分を固定することで、過学習を抑制できます。今回の入力データに用いている「元の文章」は4種類しかありませんでしたので、これを行わないと特定の文章構造に最適化されてしまい精度が出ませんでした。
def top_half_layer_freeze(module, n_layer):
for i inrange(0,n_layer//2+1,1):
for n,p in module.encoder.layer[i].named_parameters():
p.requires_grad =False
top_half_layer_freeze(deberta_model,24)
Ensemble(LightGBM with Pooling)
「deverta-v3-large」– 「Pooling」– 「Linear(1024 → 2)」のモデルでも一定精度が出ていました(Private LBで60位ぐらい)。
しかし、損失の下がり方が不安定で汎化性能に不安を覚えたため、Long Model内部でもアンサンブルを行うことにしました。とはいえ既に6時間近く推論に使っているため、同じ大きさのモデルをアンサンブルを行うのは不可能です。そのとき、このコンペでzero-shot-learningが活用できないかと考えていた際に偶然見ていた記事[8]を参考に「Pooling層を抜き出してLightGBMで学習し、アンサンブル」することを思いつきます。
これが大幅な精度向上につながりました(Private 36位ぐらい)。
図2: Long Model アーキテクチャ
Short Model
Long Modelの精度改善が一段落し、Short Modelの検討に移りました。
一から作成することも考えましたが、既にPublicで多く引用されていたNotebook[9]があったため、こちらを参考に一部改良を加えることにしました。
このNotebookの特徴として、「バックボーン + huggingfaceのSequenceClassification」によって学習されたスコアとFeature Engineeringで作成した変数(文章の長さ、誤字数など)を合わせLightGBMで再度スコアを予測する、といった構造があります。(詳細は引用元をご確認ください。)
今回は、バックボーン・Feature Engineeringの一部を変更することで精度改善を行います。
バックボーンは元のNotebookではdebera-v3-base[10]を用いていましたが、いくつかのパターンを精度検証した結果、Long Modelと同様deberta-v3-largeが最も精度が高かったため、こちらに変更します。
またFeature Engineeringの方法として以下の変更を行うことで(CVは上がりませんでしたが)Private LBの精度向上につながりました。
- 「元の文章の長さ」の削除
- 4種類しか元の文章がなく、過学習していそうだったため(実際これを入れた場合はPrivate 16位ぐらいで金圏から脱落していた。)
- 「誤字数」や「引用Overlap数」など〇〇の件数になっていた部分を比率に変更
- 「件数」だと元の文章や要約文の長さに比例してしまい本来評価したい意味合いが変わってしまうような気がしたため比率に変更しました。
- 例えば, 「誤字数」は「誤字しやすいほどスコアが低い」ことを判断したいが, 今回のコンペでは, 「誤字数が多いほど要約文が長くスコアが高い」となっており, 真逆の意味になっていた。
Long & Short Ensemble
最後にLong ModelとShort Modelをアンサンブルします。
過去のコンペではOptunaで重みを最適化している例も存在しましたが、あまり精度向上につながらなかったため、単純に平均を取っています。
終わりに
今回は、CommonLit – Evaluate Student Summariesで入賞した際の解法についてご紹介しました。
ARISE analyticsでは、Kaggle等の分析コンペティションで上位成績を残すと、インセンティブとして報奨がもらえるARISE Tech Master制度があります!(今回は30万貰えます!)
次はGrandMaster目指して頑張っていきたいと思います。
我々と一緒にKaggle部を盛り上げてくださる方はこちらのページからご連絡お待ちしております!!!!
参考文献
[1]: https://ja.wikipedia.org/wiki/%E3%83%AB%E3%83%BC%E3%83%96%E3%83%AA%E3%83%83%E3%82%AF
[2]:https://www.kaggle.com/competitions/commonlit-evaluate-student-summaries/discussion/424402
[3]: https://arxiv.org/abs/2006.03654
[4]: https://arxiv.org/pdf/2004.05150.pdf
[5]: https://arxiv.org/pdf/2007.14062.pdf
[6]: https://huggingface.co/microsoft/deberta-v3-large
[7]: https://developer.nvidia.com/automatic-mixed-precision
[8]: Zero-shot learningの紹介:見たことがない画像やニュースを予測してみました – GMOインターネットグループ グループ研究開発本部