Core Tech Blog

株式会社Coreのエンジニアチームが日々習得した技術やTipsを公開するブログです

センチメント分析と1次元CNN

開発部Sです。

今回は自然言語処理の中でも、教師あり深層学習の中でもセンチメント分析を取り上げます。

自然言語処理における RNNと1次元CNN

文章がポジティブな内容か、それともネガティブな内容かをAIが理解できれば、顧客の声の収集やマーケティングキャンペーンの効果判定に有効活用できます。 ここ最近の自然言語処理の技術的発展に伴って、こうしたニーズは、ホットなトピックの1としてセンチメント分析または感情分析と呼ばれ、深層学習の手法として様々な方法が提案されています。

深層学習で文章のようなシーケンスを扱う方法としては、大きく分けて2つのアプローチがあります。

もっともよく知られているのはRNN(Recurrent Neural Network )です。シーケンスを順次入力にしながらも、自身の出力を(再帰的に)入力に使う分類器です。再帰する分、層が深く重なったDNNと似た構造になります。深いので学習には時間がかかります。ただ、RNNをそのまま使っても精度はあまり期待できず、様々な改良が施されてきた歴史があり、とりわけ、モデル内部に「記憶」を情報として保持させることで性能を大幅に向上させたLSTM(long short term memory)が、RNNの発展形としての代表格となります。

もう一つのアプローチは畳み込み・CNN(Convolutional Neural Network)を使う方法です。 CNNというと一般的には画像認識の領域で使われる2次元畳み込みが連想されますが、ここでのCNNは2次元ではなく、1次元CNNです。

1次元の畳み込み?

聞いたことがないな、何だろう?ということで、調べてみました。 今回は、センチメント分析に1次元CNNを使って成功したKim (2014)論文にフォーカスをあて、その概要を紹介します。

Kim (2014)概要

元の論文とpdfのリンクです。

Kim, Y. (2014). Convolutional neural networks for sentence classification. arXiv preprint arXiv:1408.5882.

https://arxiv.org/pdf/1408.5882.pdf

映画レビューのテキストやツイート等の文章に、良い・悪いの評価がタグづけられている複数のデータセットを使って、文章から書かれている内容が良いのか悪いのかを予測する、という方法論の提案です。 他の論文でも、たくさん引用されています。

多次元シーケンス

例は、なんでも構わないのですが、簡単な日本語で、

  山の上に花が咲きました。

とかにしておきます(センチメント分析的には、この文面はニュートラルかポジティブか、いずれかですが、あくまで手法説明のための例とします)。

通常はこれを分かち書きします。

  山 の 上 に 花 が 咲き まし た 。

さらに、処理を簡易にするため、各語にインデックスを与えます('山'は35番、'の'は9番・・・)。

  山 の 上 に 花 が 咲き まし た 。
  35 9 101 21 150 6 151  10  7 12

このように文章を「離散値インデックスのシーケンス」に一旦、変換します。

続いて、インデックスが付与された語に対応する分散表現に置き換えます。 ※分散表現は、語を高次元空間で表したベクトルのことで、以前の記事でも紹介しました。 分散表現が仮に5次元だとすると(実際にはもっと高次元でKim 2014なら300次元)、上記の例は、順に

  山の上に花が咲きました。
  山 の 上 に 花 が 咲き まし た 。
  35 9 101 21 150 6 151  10  7 12

 [  .12    .05    …     … -.42    ]
 [ -.51   -.21    …     … -.34    ]
 [  .05    .00    …     …  .10    ]
 [  .10   -.08    …     … -.28    ]
 [ -.73   -.16    …     …  .33    ]

のようになります(… の部分も全部数値です)。 文章の長さに応じてこの行列はもっと横に長くなり、分散表現の次元数が高ければもっと太いシーケンスに。 これが、センチメント分類器の入力部分となります。

フィルタの役割

で、肝心の1次元畳み込み。

1次元畳み込みは、各単語のベクトル値を先頭から順にみて、幅を持つ「フィルタ」を使って、掛け合わせた値の流れに変換します。

f:id:coreinc:20181204114445p:plain

仮に、幅が2のフィルタを使うと、先頭から数えて2語(山、の)の分散表現を、まとめて1つの分散表現に圧縮する働きになります。 図の同じ色をそれぞれ掛け算して合算し(内積)、切片値を加えるとできあがり。

(.12×-.40) + (-.51×.12) + (.05×.54) + (.10×-.37) + (-.73×-.47) (.05×-.05) + (-.21×-.36) + (.00×.13) + (-.08×.48) + (-.16×-.23) + .03 = .33

この処理をスライドして次に処理する2語(の、上)のフィルタ適用後の分散表現を得て2つ目の値とし、順次くり返してその次、その次、と進めて文章の末尾まで処理を続けます。

f:id:coreinc:20181204114304g:plain
畳み込み処理を順次適用

このように畳み込むことで、元々は「単語の分散表現が並んでいたシーケンス」が、「2語間の関係に関する分散表現のシーケンス」へと変換されるので、語の前後の関係に関する情報として利用できるかたちに整います。

当然ながら、フィルタ幅は必ずしも2と限らず、3でも5でも構いません。その場合に得られる情報は「3語間の関係性」や「5語間の関係性」だったりして、そのような語間関係性の表現に最適なフィルタが学習中に作られ(推定され)ます。フィルタが持つ値は、学習の中で最適化されていくとしても(語の分散表現自体と同様に)その値はもはや人が見て理解できるものではありません。分析者の仕事は、最も性能の高いと思われるフィルタ幅と数の調整になります(Kimの場合、3,4,5の3種類)。

フィルタ適用後の出力は語間の関係を意味する数値のベクトルで、文全体でみると「元の文章の語数よりも少し短くなった長さ、元の分散表現の次元数、を持つ行列」となり、深層学習ではこれを「特徴マップ」と呼んだりします。 そして、特徴マップは複数用意するのが一般的です。Kim(2014)の場合でいえば、幅3の畳み込みフィルタから、特徴マップを100本用意します。このことは「3語の関係性」を次元数100で表現する試みで、(やや多いのですが)結果的に100種類の語間表現専用のフィルタが、分類器の中で計算・推定されることになります。

単語間の関係自体を高次元空間で表現し、マッピングする… ここまでくると、文章の持つ意味も分類できる特徴に変換されてくるのか?と、期待も高まります。

畳み込みの後

畳み込みの後の処理は、プーリングです。MaxPooling(最大値プーリング)といって、特徴マップの中でも、最も高い値を取ってくる、というもので(要約統計量としてマップ内の最大値をとる)、この処理によって「当該文章が持っている語間関係の中でも、最も特徴的な側面」を取り出す仕組みができるわけです。上記の例でいえば100個のプーリングされた値が得られます(※ちなみに、Kim(2014)では、フィルタ幅が3,4,5の3種類でそれぞれに100の特徴マップを持たせ、Maxpoolingで特徴マップに対して1つの値を得ます)。

入力時には単語の分散表現が並んでいただけのシーケンスが、畳み込み処理を経ていく中で、次第に、語間の関係の情報に圧縮され、その圧縮のしかたも多様に拡張する過程として、理解できると思います。

原論文の図です。

f:id:coreinc:20181128135140p:plain 出典:https://arxiv.org/pdf/1408.5882.pdf

最後は、プーリングで得られた層を全て束ねて(全結合)、分析対象となる文章がポジティブなのかネガティブなのかを判定させる層につなぎ、処理します。ロジスティック回帰のような二値分類と同じですが、束ねる値が多いので、説明変数が多量にあるロジスティック回帰に相当します。分類器の予測出力に対してシグモイド関数等をかぶせて、出力が確率値と解釈できるようにすれば完成です。

まとめ

Kim(2014)のオリジナリティは、1次元CNNをセンチメント分析に適用したこと、語の埋め込み分散表現について、①乱数で初期化・調整、②訓練済みベクトルで固定、③訓練済みベクトルから学習、④訓練済み固定と学習のマルチチャンネル(②と③)を比較検討して、全体として高いパフォーマンスを示したところにあります(映画評定の2択データセット(IMDb)では8割の正解率を達成、他のデータセットでも既存の手法と比べて遜色ないか、高い正解率を達成しています)。

個人的に驚いたのは、乱数で初期化(①)しても性能が良いこと、上記のマルチチャンネル(④)が良い結果につながっていること、でしょうか。学習後の固定チャンネルと学習チャンネルそれぞれに、コサイン距離の近い語を求めた結果が表になっています。 類似語といっても分散表現が異なるので、個性が出ているんですね。 へえー、という感じです。

f:id:coreinc:20181128134548p:plain 出典:https://arxiv.org/pdf/1408.5882.pdf

センチメント分析を考える上で、非常に参考になる論文だと思います。

最初は、訓練済みのベクトルを使って値を固定したほうがいいのかと思ってたのですが、 実際に、Kim(2014)と同じモデルを使って、手元のデータを分析してみると 必ずしも固定がよいわけではなく、むしろ、固定せずに学習する(ファインチューニングする)ほうが性能が向上するようです。 結局のところ、訓練済みベクトルの使用するアドバンテージは良い初期値で開始できる、ということなんでしょう。

RNNやCNNについて人の五感で喩えるなら、伝統的なRNNの分類器は聴覚的符号化を使って音で入る情報を聞きながら、目を閉じて判断をするようなもので、まさに文章を声に出して読む情報処理のような特徴があります。 一方で今回紹介した1次元CNNは、文章を読む際に心の中で音に出している声を消して、速読のように目で読む処理に近いと感じられます。文章も視覚的符号化を通してざっとスキャンして頭に入れるわけです。当然人間の場合も視覚を使うほうが速いのですが、深層学習でも同じようにCNNで処理するほうがLSTMに比べて計算速度もずっと速くなります。

そして現在の自然言語処理では、音読的なRNNに比べて、速読的な1次元CNNの性能の良さに注目が集まっている状況です。 何せ、計算時間が速い。。 今後の技術的発展にも注目です。