5th Place Solution
はじめに
コンペを開催してくださった運営の皆様、共にコンペに参加し、コンペを盛り上げてくださった参加者の皆様に感謝を申し上げます。初めての自然言語処理への取り組みであり、多くの学びを得ることができました。
簡単ではありますが解法の共有をさせていただきます。
モデルの概要
複数のモデル(MultinomialNB, NBSVM, Bertなど)の予測値でアンサンブルを行ったモデルが最終的なモデルとなりました。また、他の方のsolutionと同じくpseudo labelingも行いました。
前処理
cha_kabuさんのトピックにて紹介されていた方法をそのまま使用させていただきました。
不均衡データ対策
アンダーサンプリング+baggingを行いました。サンプリング毎にspamか非spamかを予測し、その予測結果の多数決により最終的な予測値を決定しました。
Data Augmentation
トピックを建てさせていただいたように、再翻訳によりデータの水増しを行いました。spamのデータのみを、ドイツ語とフランス語を経由して再翻訳し、spamのデータ数を3倍にして学習を行いました。MultinomialNB(pseudo labeling 未実施)で学習を行った際には以下のようにスコアが向上しました。
public:0.9826127820 → 0.9834059080
private:0.9834504294 → 0.9852590420
※単にデータが増えただけでなく、アンダーサンプリング時にサンプリングされる非spamのデータも増えた事も精度向上につながった気がしている。
ベクトル化
ベクトル化が必要なモデルは、tf-idfを用いて、文章をベクトル化しました
閾値の設定
trainデータに対してf1が最も高くなる閾値でtestデータを分類しました。今思えば、予測値の上位17000件をspamと分類した方が良かったかもしれないです。
モデル
MultinomialNB, logistic regression, lightgbm, NBSVM, LSTM, Bertを試しました。
Augmentationや試したモデルについては、以下の記事で紹介されていたkernelを参考にしました。
https://copypaste-ds.hatenablog.com/entry/2019/02/01/174135
BertはSimpletransformesを使用して実装しました。数行でBertを利用できて、非常に実装が簡単でした。
Pseudo labeling
ベースラインとして使用していたMultinomialNBの予測結果でラベル付けしたtestデータを含めて学習を行いました。精度が大きく向上したモデルもありましたが、精度が向上しなかったモデルもありました。単体のモデルで最も精度の高かったBertは以下のようにスコアが向上しました。
public:0.9847166706 → 0.9852053497
private:0.9846551319 → 0.9875463072
アンサンブル
最後に、アンサンブル学習としてAveragingやStackingを試しました。
色々試したのですが、結局、MultinomialNB,NBSVM,Bert(pseudo labeling未実施), Bert(pseudo labeling実施)の4つの予測値の平均を取ったものが最もスコアの高いモデルとなりました。このアンサンブルにより、モデル単体で最もスコアの高かったBert + pseudo labelingに比べて、大幅にスコアが向上しました。
public:0.9852053497 → 0.9893992933
private:0.9875463072 → 0.9910595247
※なぜ、1層目の予測値の組をこの4つに絞ったかは、精度が比較的良かったモデルを適当に選んで、アンサンブルしてみて、publicのスコアを参考に試行錯誤的に決めたからです。step-wise法などでシステマティックに特徴量選択すればよかったかなというのは反省点です。
※pseudo labelingを行ったモデルの予測値と行わなかったモデルの予測値の相関係数が小さかったので、pseudo labelingを行わなかったモデルでの予測値も一層目の入力の候補としました。
感想
初めてのNLPとして、非常に楽しく取り組むことができました。トピックにて、分かりやすいベースラインが公開されていたこともあり、NLPが初めてでも取り組みやすいコンペだったと思います。改めまして、運営の皆様、参加者の皆様、ありがとうございました。