12th Place Solution
はじめに
(N)th Place Solution、このタイトルでトピックを書くのが夢だったんだ...
マイソリューション
2つのモデルをアンダーサンプリングして学習させたモデルを、平均アンサンブルして(スパムの確率)-(非スパムの確率)が大きい順に17000個スパムと判定。(テストセット中のスパムの数が決まっていたので)
アンダーサンプリングとテキストの前処理は、cha_kabuさんの素晴らしいトピックを完全に参考にしました。ほんとうにありがとうございました。
MultinomialNBを使ったbaseline(参考)
コンペ開始早々、このLB:0.9688243693のトピックが投稿されたあの衝撃は忘れられません。
2つのモデル
- テキストの前処理ありbert(public: 0.9826005173)
- テキストの前処理なしroberta(public: 0.9808447353)
これらを以下のパラメータで学習させました。
結構テキストの分量が多かったので、max_seq_length大きくしたかったのと、もっとバッチサイズも大きくしたかったのですが、Google colabのメモリが悲鳴をあげたので、ギリギリここまでにしかできませんでした。特にmax_seq_lengthはもっと大きくすれば精度もうちょい出た気がします。
args = {
"overwrite_output_dir": True,
"show_running_loss": True,
"max_seq_length": 256,
"train_batch_size": 32,
"eval_batch_size": 32,
"num_train_epochs": 20,
"learning_rate": 1e-4,
"manual_seed":777,
}
考えるのが面倒だったので、スタッキングとかはせず、平均アンサンブルしました。普通にargmaxしたのがpublic: 0.9851625059、(スパムの確率)-(非スパムの確率)が大きい順に17000個スパムと判定したのがpublic: 0.9856538100でした。
privateもだいたい同じスコアです。
感想
ここからが本編です。
学習済みモデル問題
今回は、学習済みモデル使用禁止というのを完全に読み落としていたので、このコンペの前にあった某NATEで作ったBERTを使うコードを使いまわして、最初っからBERTを使っていました。
トピックで指摘された時に「あっ終わった」と思い、運営の返答次第で自首する準備をしていたのですが、運営がBERT利用を許可してくれたので助かりました。ルールはきちんと読みましょう。(戒め)
モチベーション問題
割と早い段階でみんなのF値が0.9超えして団子になったので、こっから先争ってもどうせ誤差の範囲だろと早々にやる気をなくしてしまいました。
また、ダウンサンプリングを行っていたこともあって、バリデーションの精度がどのモデルもあまり差が出ず、バリデーションが実質役に立たなくて、実際にサブミットしないとモデルの性能を測れなかったのも辛かったです。以上の理由からかなり放置していました。
終わってみると、12位と金圏も狙えたのではないかと思うと昔の自分を殴りたいです。コンペのモチベーション、皆さんはどうやって保っていますか?ソロプレイだとなかなかつらい時もありますよね?ね?
テキストの前処理
テキストの前処理って精度が上がったり、落ちたりいまいちよくわかりません。これって実際やっとくべきなんですかね?
他に取った手法
参考までに...
テキストのヘッダー情報にre(返信)、fwd(転送)のような情報があったので、これらはスパム判定に効きそうだなと、cha_kabuさんの上記ディスカッションで使われていたテキストのベクトル化と組み合わせてLightGBMで学習させたのですが、全く効きませんでした。LightGBMはスパースな特徴量には弱いんですかね?
以前もスパースな特徴量だとLightGBMでは、精度が出なかったことがあります。誰か有識者に聞いてみたいです。
ダウンサンプリングの逆で、データ量を増やすアップサンプリングの手法としてSMOTEというものがあります。これを初期に試したのですが、過学習気味な気がしたので使うのをやめました。
でも面白いアルゴリズムだなと思いました。こういうアルゴリズムは好みです。
最後に
気が向いたら追記してソース公開したり、もう少し自分色をいれつつ、自分のブログで詳しくコードについて書いたりなんだりすると思います。気が向いたら探してください。ここではこの辺で。
(割といいスコアだったので、少し調子に乗って自分色を入れすぎました。誰も不快にならないといいのですが...反省してます。)