狠狠撸

狠狠撸Share a Scribd company logo
Toxic Comment Classification
参加記録
NSK
1
● 自己紹介
● Kaggleとは
● 参加したコンペの概要
● アプローチ
● 上位陣のSolutionの紹介
● 個人的に役に立った(メタな)テクニック
● Kaggleに参加する意義
目次
2
● 現職
○ Algorithms Engineer & Software Engineer
● 前職
○ Machine Learning Engineer
○ 仕事内容
■ オンライン広告のCVR予測?広告出稿システムの構築
■ 検索エンジンの精度向上
■ チャットボットのプッシュ配信の最適化
自己紹介
3
● データ解析コンペティションを開催するプラットフォーム
● 企業がデータ?タスクを提供し、競技者がタスクを解く
Kaggleとは
4
● 参加者は自分が作成したモデルの予測値をcsvにしてsubmitする
● submitされたcsvからスコアが算出され、スコア順にリーダーボードに名前が掲載され
る
Kaggleの特徴: リーダーボード
5
● スクリプト/notebookをKaggle上で実行/公開することが出来る
● 公開されているKernelを読むだけでも非常に勉強になる
Kaggleの特徴: Kernel
6
● コンペに関するトピックについてKaggle上で議論が出来る
○ Kernel/Discussion以外でのチーム外の情報共有 (private sharing)は禁止されている
● Kernelと同様にコンペに関する有益な情報が共有されており、コンペ上位を目指すな
ら一通り目を通しておくと良い
Kaggleの特徴: Discussion
7
● タスク
○ テキストデータに対するラベリング
● データセット
○ Wikipediaの記事に対するコメントのデータ
○ ラベルは以下の6種類で、前述のコメントに対して人間のアノテーターがラベルを付与
■ toxic, severe_toxic, obscene, threat, insult, identity_hate
○ マルチラベルなので複数のラベルが単一のコメントに付与されることもある
● 評価指標
○ 各ラベルに対する予測値の AUCの平均
参加したコンペの問題設定
8
● テストデータがオープンソースとしてダウンロード出来ることがコンペの最中に判明
し、テストデータの入れ替えが行われた
○ 元々のテストデータは訓練データに追加された
○ 同時にコンペの期限が 1ヶ月延長された
● 同じタイミングで評価指標がlogloss → AUCに変更
○ 以下のような背景に基づいているものと思われる。
■ loglossはラベルの分布に敏感な指標であり、(変更前は)訓練データとテストデータで明らかに
ラベルの分布に明らかに違いがあった
■ このような状況下だと LB(リーダーボード)のスコアからテストデータのラベルの分布を探る必要
があり、スコアを上げるために本質的でない作業が必要になる為批判をされていた
余談: コンペの途中でデータセット & 評価指標が変更された
9
最終順位
Score:
0.9867
Rank:
187 / 4551
(top 4.1%)
ちなみに、
1位: 0.9885
2位: 0.9882
3位: 0.9880
50位: 0.9871
10
コンペタスクの一連の流れ
データ拡張
前処理
特徴抽出
モデリング
アンサンブル
訓練データを増やす
特徴を抽出しやすいように文章?単語に処理をかける
モデルが解釈しやすいように文章から特徴量を抽出する
教師データを入力するモデルを設計?学習する
学習したモデルを統合して予測値を算出する
11
コンペタスクの一連の流れ: 今回試したテクニック?手法
Google翻訳→再翻訳によるデータ拡張
ステミング, 正規表現
tf-idf, handmade feature
GRU, CNN, GBDT, NB-SVM, LSTM, Naive Bayes, MLP
model averaging, stacking
データ拡張
前処理
特徴作成
モデリング
アンサンブル
オレンジ色は最終的にsubmitしたファイルで活用したもの 12
● 初期にKernelに投稿され、Baseline的な扱いとなったモデル
● Christopher Manningの論文が元ネタ
○ Baselines and Bigrams: Simple, Good Sentiment and Topic Classification
● 各単語が各ラベルにどれだけ寄与するかを考慮
● SVMと表されつつKernelではロジスティック回帰が使われていた
モデリング: NB-SVM(Naive Bayes SVM)
13
● 元ネタは2014年のEMNLPの論文
○ Convolutional Neural Networks
for Sentence Classification
● pre-trainedなword embeddingを使って
文章を2次元行列として表現
● Conv2D -> MaxPool -> Concatをとる
○ 畳み込みはカーネルのサイズを複数用意
○ それぞれのカーネルに対して複数の
フィルタを適用
モデリング: CNN
※画像は2クラス分類の例 14
● 前述のCNNと比較すると
○ カーネルのサイズに依らずドキュメント
中の全ての単語が考慮できる
○ 語順が考慮出来る
● シングルモデルでは今回の
コンペ中最も性能が高かった
(Public LBで0.9856)
モデリング: BiGRU
15
● Blend(Model Averaging)
○ 複数のモデルの出力値を重みをつけて足し合わせ、最終的な出力値とする手法
○ 単純で実装も簡単に出来るが強力で、今回のコンペで非常に流行った
○ Blendにも色んな流派があるらしい
● 一方でBlendに対するアンチテーゼも
アンサンブル: Model Averaging
16
● Kernelのスコア上位がBlendで埋まる
● BlendしたKernelの予測値を提出する
だけで割と良い順位を取れてしまう
● スコアが良いのでVoteも集まる
余談: ヘイトが向けられるBlend
Blendに対するヘイトが無限に溜まる
17
その他: ルールベースの後処理
18
● 英語以外の言語のlabelを0に置換
○ train/test dataに非英語のコメントのデータが混じっていた
○ アノテーターは英語圏の人間なので、英語以外のコメントに対してアノテーション出来ない
■ 訓練データ中で、非英語のコメントで内容が toxicなものであってもlabelに1は立っていなかった
らしい
● 10-foldで各種モデルを学習
● OOF predictionを使ってラベル毎に各モデルの出力をblendする比率を決定
○ AUCを最大化する比率に決定
● 非英語のレコードの後処理
187th place solution overview
GRU
(twitter, crawl)
LGBM
CNN
(crawl)
NBSVM
Blend
19
試したが最終的に不採用となったアプローチ
20
● ラベル毎にネットワークを個別に用意して学習する
○ ラベル毎に最適なネットワークの構造は異なるので、ラベル毎にネットワークを学習したら上がるので
は?と思ってやってみた
○ 個別に学習した方がスコアが高くなるモデルもあったが、最もスコアが高かったモデルでは 6ラベル同
時に学習した方が良かった
● 諸々の前処理
○ ステミングや正規表現による単語の正規化等、色々試したが最終的には前処理を加えない方が方が
方がスコアが高かった
● Stacking
○ 各種モデルの10-foldの予測値 + handmade feature等試したが、blendの方がスコアが高かった
○ やり方を間違えてたかも? (foldの切り方が違うモデルがあった )
● Diverse pre-trained embeddings (baseline public LB of 0.9877)
● Translations as train/test-time augmentation (TTA) (boosted LB from 0.9877 to
0.9880)
● Rough-bore pseudo-labelling (PL) (boosted LB from 0.9880 to 0.9885)
● Robust CV + stacking framework (boosted LB from 0.9885 to 0.9890)
上位陣の解法: 1st place solution
21
● 英語 -> 他言語 -> 英語で翻訳すると元文章と再翻訳後で表現に差分が生まれる
○ より多様な表現の訓練データを得られる
● ただし、適当にvalidation setを作るとLeakageが発生する
○ train - validationを分割する際に同じ元文章から生成されたレコードは、同じデータセット (train or
validation)に入れる必要がある
○ 拡張したデータセットの利用は自分も試していたが、諸にこれにハマってしまった
1st place solution: Google翻訳によるData Augmentation
22
● モデルの出力値を(メタ)モデルの特徴量として学習を行う手法
1st place solution: Stacking
Model 1
Model 2
Model N
Meta
Model
Prediction
Prediction
Prediction
Prediction
train data
23
● 訓練データをK-foldに分割し、(K-1)-foldのデータで学習
● 訓練したモデルで残りの1-foldのデータに対する予測値を算出
● 算出した予測値でメタモデルを学習
1st place solution: OOF(Out of Fold) predictionによるStacking
fold 1
fold 2
fold 3
Meta
Model
Model
fold 3
Prediction
train
data
24
● スペル訂正
○ 入力文に含まれる単語のスペルが間違っていた場合にスペルを自動で訂正する技術
● CPMP’s kernel spell correction
○ Googleが公開しているword2vec モデルを活用
■ ただし、分散表現を利用しているわけではなく単語の出現頻度の取得に利用しているだけ
○ アルゴリズム
■ 単語がword2vecモデルに含まれていれば訂正せず、
■ 単語が含まれていなければ、
● 元の単語と編集距離が 1の単語の中で最も出現頻度が高い単語に置換
● 編集距離が1の単語も含まれていなければ編集距離が 2の単語の中で最も出現頻度が高
い単語に置換
○ 単語を打ち間違える確率は通常簡単には求まらないので、編集距離と出現頻度で代用するヒューリ
スティクス
上位陣の解法: スペル訂正
25
● BPE(Byte Pair Encoding)によるサブワードの考慮(15th place)
● 単語ベースの特徴量に加えて、handmade featureをGRUに入れる(3rd place)
その他上位陣の解法
26
個人的に役に立ったテクニック: パイプラインの構築
● 前処理?学習までの一連の処理の中で、毎回実行する必要がない処理がある
○ テキストの前処理 -> トークナイザーの構築 -> Embedding matrixの構築 -> 学習
○ 前処理及びパラメータが決まっていればトークナイザーや Embedding matrixは同じものが再利用出来
る
● 前処理やTokenizer等のパラメータを引数として渡し、なるべく同じ処理は繰り返さな
いようにパイプラインを構築した
○ 学習の前段階までで地味に 2,30分近くかかるので、省略することでサイクルが回しやすくなった
○ ちゃんとしたパイプラインを作るなら Luigi等を使ったほうが良い
■ 今回は面倒だったので if文で対応
27
個人的に役に立ったテクニック: Colaboratoryの活用
● クラウドでJupyter Notebookが使えるツール
○ Googleが提供
● 制約はあるものの、GPUが無料で利用可能
○ 最大連続稼働時間が 12時間なので重めの処理をするときは工夫が必要
○ ローカルデータを読み込む際は Google Driveにデータを置かなければならず、また新しく Notebookを走
らせる際に毎回認証が必要など、若干クセがある
● 自宅でも(会社でも)同じ環境でプログラムの実行が可能
○ 会社で学習を回した Notebookで、自宅から処理の追加などが可能
28
その他個人的に役に立ったテクニック
● Gitを使ってバージョン管理する
● ロギングをちゃんとする
○ どんなパラメータで、どんなモデルで、どれだけの精度が出たか
● fireの利用
○ CLIの自動生成ライブラリ
○ パラメータを引数として渡すのに利用
29
Kaggleに参加する理由
● 業務に活きる
● キャリアに繋がる
○ 客観的な自分の実力が分かる?実力の証明になる
○ Kaggleへの参加経験を奨励する求人も最近はちらほら見かける
● 楽しい
○ 実務に近いレイヤーの手法?テクニックを効率よく学べて楽しい
○ Leader Boardで順位が上がっていくのが楽しい
■ たぶんリーダーボードがなければここまでハマらなかった
■ LBの順位を上げる為に勉強をするモチベーションが出る
30

More Related Content

Toxic comment classification