テキスト分類をDNNでやってみて思うところ

Pocket

以前このような記事を書きました。

複数の単語から構成される文章を、Bag-of-Wordsと対応する単語分散ベクトルで表現し、特徴ベクトルの最大値のみを抽出する、という感じの手法です。

これの実装を書いた時はまだあんまり機械学習のことがよくわかっていなく(今もよくわかっていませんが)、それでも実験的、感覚的に「この手法は特に単語が増えると精度でないだろうな」と思っていました。

なので、その後畳み込みネットワークベースの手法を試しています。他の人が書いたChainer実装は既にあったので、自分はそれの最上層をSPP-Netに置き換えただけのものを試しています。

基本的に、こちらのほうが特徴量をより多く捉えているはず(層の数とか種類とかから類推)なので、きっと性能は高いと思います(未検証)。そこは同じテータセットを使ってちゃんと試したいところですが、GPUの空き時間ができたらということで…

そんなわけでRecurrent CNN(RCNNはRegions with CNNと混同しやすい略称なのでこう記述します)は「自分も論文だけ見て実装することはできたので満足。だけど手法としてはいまいちっぽいよね」という気分でいました。

ふと先日この記事が目に飛び込んできました。

ちょっと過大に扱われてしまったのではないかと思い、この記事を書いています。

分類結果の出力

自分の実装では評価時に最終出力として、全層結合層(Fully Connection layer)の値を生のまま出しています。実際にはこれにソフトマックス関数をかませて0〜1の確率値に整えるべきなのですが、そこをちょっとさぼっています。

ともかく、ソフトマックス関数で計算される分類タスクの出力は、全ラベルそれぞれの確率の合計が1になるよう調整されます。

Recurrent CNNでは分散表現の実数をそのまま加算するため、全体としては大きな値になりがちでです。その辺りの正規化が皆無なので、おそらく文章が長くなるほどあやしい挙動を示すでしょう。

分散表現獲得

また、分散表現の獲得もあまりよろしくない作りになっていると思います。乱数を初期値とし、逆誤差伝搬で各文字の分散表現を獲得しています。

十分なデータ量がないと、適切な分散表現は獲得できないと思います。代わりに、例えば一般的な表現が多数出現するデータ量の多いコーパス(Wikipediaの記事、新聞記事など)から、word2vec等で獲得した分散表現を初期値に設定してやる、といったことで性能が向上する可能性があります。

2017/8/30 追記: 今回のケースだとWikipediaよりも2chの各種書き込み、Twitterのツイートから分散表現を事前訓練したほうが良い気がしてきました。

「その他」というラベルの扱いの難しさ

MNIST, ImageNet, CIFAR10等誰もが入手できるデータセットは非常に限られた分類のデータしかありません。それらを識別するモデルを用意したとして、まったく関係ないデータを与えると、識別器は無理やり何かしらの値を出力します。運が良ければ何かしらの要素が似ているものへの確率が高く出ますが、最悪まったく関係ないラベルだと推論してしまいます。

これを回避するために、たとえば雑多なデータをたくさん用意して「その他」ラベルを作るという解決方法がありますが、これも一筋縄ではいきません。

今年2017年の人工知能学会でクックパッドが発表した論文に、この過大に取り組んだ話が掲載されています。

「料理・非料理判別問題」というタスクを設定しています。単純に2クラスに分けると全く関係ない画像が料理判定されるケースについて言及があります。

彼らはあえてより多くのクラスに分類した時、そうで無い時で分類精度を評価しています。以下論文の引用になります。

F 値が最も高いモデルは料理・非料理ともに多クラス化したものだが, 提供するサービスの性質上, 我々は料理クラスは単一クラスで非料理クラスは多クラス化したものを採用している.

客観的な指標(F-measure)では料理、非料理それぞれ多クラス分類した方が精度は高かったが、サービスの特性上適合率(precision)よりも再現率(recall)が高い手法を採択したとのことです。

分類対象がテキストであったとしても、同様の傾向が出るであろうことは予想されます(CNNベースなら画像と扱いとしては同じため)。

つまるところ、分類クラスを増やすことで「そのクラス固有の特徴が分類器(の中間層)で獲得できる」ということであり、それを雑多に「その他」にまとめてしまうと特徴にバリエーションがありすぎて、かえってうまく特徴を捉えられないことが起きうるというわけです。

Conclusion

結局何がいいたかったかというと、

  • Recurrent CNNは感触としてあまり高い精度出ない
    • 単語分散表現の初期値にword2vecを使えば精度は上がると予想
    • 多分CNNベースの方が良い結果が出る
      • SPP-Netを使ったコードを書いたので、可変長データも扱えるはず
  • 単純な2値分類は危険
    • 問答無用でどちらかのクラスに分類されてしまう
    • 他クラスに分けることで精度を上げられる

といったところです。さすがにはてなブックマークのコメント100文字(http://b.hatena.ne.jp/entry/344063592/comment/knok)では伝えきれないので、記事にしてみました。

おまけ

こちらの記事でRecurrent Highway Networksという、highway networksをRNNに適用する論文の紹介資料があります。このページから直接speakerdeckへのリンクにとぼうとすると404になってしまうので、このページの埋め込み資料を見てください。元論文は以下のようです。

ブックマークコメントについて

こんな感じで修正していったように記憶しています。

  • RCNNの実装書いた本人です。2価分類はそれぞれの選択肢の確立が1になるような出力になるので、関係ない人物何人かも含めて訓練した方がもうちょっとマシな結果が出るかもしれません
  • RCNNの実装書いた本人です。2価分類はそれぞれの選択肢の確立が1になるような出力になるので、関係ない人物何人かも含めて訓練した方がもうちょっとマシな結果が出るかもしれません/多値分類でも合計は1
  • RCNNの実装書いた本人です。分類問題はすべての選択肢の確率合計が1になるような出力になるので、関係ない人物何人かも含めて訓練した方がもうちょっと良い推論結果が出るかもしれません/追記しきれないので誤字修正