RNN/LSTMでテキスト分類をしたいと思い、まず自分でネットワーク構造を考えてみました。word embeddingとLSTMを組み合わせて、単純な和を文章全体のベクトルとして扱うことを考えてみたのですが、これは思うように動きませんでした。さっぱり学習する気配がありません。
そこで既に提案されている手法を探してみると、word embeddingの配列をx軸固定の畳み込み演算するという手法がひとつありました(CNNによるテキスト分類)。TensorFlowでの実装もあったのですが、chainerでできないかと思いmax_poolingでstride=(0, 1)といった感じで指定してみたのですが、chainerではstrideの値が0より大きいことを想定しているため0除算が発生して動かせませんでした。
仕方がないので、もうひとつの手法「Recurrent Convolutional Neural Networks for Text Classification」を試してみました(参考: 研究開発:RNNで文書分類(Text Classification) )。
構造としては、いわゆる双方向RNNで単語の出現順、その逆順の2つの方向からRNN(実際にはLSTM)を使って、それらを結合し単語ごとに一つのベクトルを生成します。そして、すべての単語についてベクトル各要素の中の最大の値を取り出したベクトルを生成します。最大プーリングに相当する処理ですが、chainerのmax_pooling_2dは今回の用途には使えませんでした。代わりに、function.maximumが使えたのでそちらを使っています。
結果として、おおよそ望むような挙動を得られました。目視で分類したネガティブな文章とポシティブな文章とを分類することができました。
ソースコードは https://github.com/knok/rcnn-text-classification にあります。Qiitaにも解説記事を書きました(Recurrent Convolutional NNでテキスト分類)。