オブジェクトの広場は株式会社オージス総研グループのエンジニアによる技術発表サイトです

AI

はじめての自然言語処理

第1回 類似文書検索の手法と精度比較
技術部 AIテクノロジセンター
鵜野 和也
2019年3月26日

自然言語処理とは、人間が自然に使っている英語や日本語などの言語をコンピュータで処理する技術です。自然言語処理でできることには機械翻訳、要約生成、感情分析などがありますが、今回は比較的シンプルな例として類似文書検索に焦点を当ててみたいと思います。類似文書検索はテーマとしては真新しいものではありませんが、本記事では単語の分散表現を用いる手法や Watson Discovery も含めた各種の類似文書検索手法について、日本語データに対して精度比較試験をした結果を紹介します。複数の手法を同一の日本語データで比較した記事はあまり見ないので面白いのではないでしょうか。

1. 始めに

本記事では類似文書検索の各手法について、単語の分散表現を用いる手法や Watson Discovery も含めて精度比較試験をした結果を紹介します。まず各手法の概要を紹介しますが、ここでは数学的な細かい説明などは省くので概念的な考え方を理解してもらえればと思います。精度比較試験の結果は本記事の最後の章で紹介します。

2. 類似文書検索の基本

類似文書検索を一言で表現すると、「文章を何らかの方法で数値化し、その数値の類似度をもって検索対象の文書集合の中から検索条件に近い文章を選択する技術」となるでしょうか。この数値化や類似度計算の仕方で精度や特性が変わってくることになります。

文章の類似度を算出する処理は基本的に「文章のベクトル(数値)化」 → 「文章ベクトル同士の類似度を算出」という流れになります。 各処理についてまず説明していきましょう。

2.1 文章のベクトル(数値)化

文章をベクトル(数値)化する一番単純な手法が Bag of Words(BOW) です。

文書のベクトル化

まず、日本語は英語のように単語が空白で分かれていないので、形態素解析と呼ばれる処理で単語単位に分割を行います。単語に分割できたら、文章毎に各単語が何回出現したかを数え上げ、長さが語彙数となるベクトルにします。上の図で言うと、③の a の行が文書 a のベクトル、 b の行が文書 b のベクトルです。単語の並びを無視しているので Bag of Words(以後、BOW)と呼ばれます。語順を無視すると重要な情報が飛んでしまいそうな気がしますが、類似文書検索タスクでは、十分精度がでます。

2.2 ベクトルの類似度

文章をベクトル化できれば、あとは類似度を計算するだけです。計算の仕方もいろいろですが、コサイン類似度を用いることが多いです 。ベクトルの向きがどの程度同じ方向を向いているか?という指標で、-1~1の範囲をとります。コサイン類似度を数式で記述すると以下のようになります。

コサイン類似度

次章以降では類似文書検索の各手法について、その概要を紹介していきます。「こんな考え方で出来てるんだな」という感覚をもってもらえる程度の記述レベルに抑えていますので、より詳細を理解されたい方は別途、書籍や論文等を参照してください。

  • 3章:単語の出現回数による文章のベクトル化
    • TF-IDF
    • LSI
  • 4章:単語の分散表現を用いた手法
    • Word2Vec
    • WMD
    • LC-RWMD
  • 5章:文章の分散表現を用いた手法
    • Dec2Vec
    • Sent2Vec

3. 単語の出現回数による文章のベクトル化

単純な手法として BOW を紹介しましたが、実際によく使われる手法をさらにいくつか紹介します。

3.1 TF-IDF

TF-IDF は Term Frequency – Inverse Document Frequency の略で、文書中の単語の重要度を評価する手法の一つです。Solr や Elastic Search で有名な Lucene でも少し前までデフォルトのアルゴリズムだったのでご存じの方も多いかと思います。TF, IDF はそれぞれ以下のような意味合いで、TF と IDF の積が TF-IDF です*1

  • TF(t,d) … ある単語(t)がある文書(d)中で何回出現したか
  • IDF(t) … ある単語(t)が全文書集合(D)中のどれだけの文書で出現したかの逆数

早い話が「ある文書の中で何度も出現する単語は重要度が高いが、多くの文書に共通して出現する単語はそうでもない」と理解してもらえれば良いです。文書 d 中の単語 t の TF-IDF(t, d) は以下のようになります。

TF-IDF

先程の例で文書a, b の TF-IDF ベクトルを算出すると以下のようになります。図中の DF、IDF は文書集合全体(この例では a と b )に対する値です。

TF-IDFの算出

3.2 LSI

LSI(潜在的意味索引)では、トピックという文書と単語の間に存在する抽象的な概念を導入します。 各文書の BOW あるいは TF-IDF ベクトルを行とする文書数×単語数の行列を特異値分解し、文書数×トピック数に次元削減します。 以下は文章 a ~ d の4つの TF-IDF ベクトルに LSI を適用した場合の図です。

LSI

BOW 、あるいは TF-IDF ベクトルの欠点として「どんなに意味が似ていても検索対象に存在していない単語では検索できない」という性質があります。上記の例では文章 b の TF-IDF ベクトルを「自動車」で検索することはできません。LSI を適用するとトピック T2 が 0.32*自動車+0.49*車+0.81*運転 という配合となっているため、「自動車」というキーワードからトピック T2 を経由して文章 b を検索できます。このように LSI を用いると複数の単語があるトピックに関連づく(あるいはその逆)ことにより、類義語、多義語にある程度の対応が可能となります。

4. 単語の分散表現を用いた手法

前章までの手法は、文書中の単語出現数を元に文書ベクトルを導出していましたが、ここからは単語の持つ意味的な情報を用いる手法として、単語の分散表現について説明します。 単語の分散表現では単語を多次元空間上の座標にマッピングすることで、単語同士の類似度を比較したり、加減算したりすることができるようになります。「王」-「男」+「女」≒「女王」という例が有名ですね。

4.1 Word2Vec (CBoW)

単語の分散表現の獲得方法は様々な手法が紹介されています。手法の皮切りとして2013年に登場した Word2Vec*2 は 同じ文脈で登場する単語は似た意味を持つという分布仮説をベースとしています。 以下は Word2Vec で実装された CBoW(Continuous Bag of words) の動作イメージです。”Yes We Can” という文章があったとして、周辺単語(”Yes”, “Can”)から注目する単語(”We”)を予測するモデルになります。

Word2Vec

学習後に入力重みの行列からある単語に対応する行を取り出すと、その行ベクトルが単語の分散表現になっています。深層学習を用いる自然言語処理では、このように獲得した分散表現が翻訳、要約、対話等の様々なタスクへの入力として用いられます。

4.2 Retrofitting

前述の Word2Vec ですが実は対義語が苦手です。「最近は野菜が高い/安い」のように対義語は同じ文脈で出現するので、前述の分布仮説に基づいた手法ではどうしても似通った分散表現になってしまいます。

Retrofitting*3 はWordNet*4 などの意味辞書を用いて、意味的に関連している単語群は似たベクトルになるように fine-tuning する手法です。

Retrofitting

細かい説明は省きますが、似た意味の単語同士の間(青線)、それぞれの単語の初期座標との間(赤線)に張力の異なるゴム紐を張り、それらの張力が均衡した場所が fine-tuning 後の座標となります。

Word2Vec は対義語だけでなく多義語も苦手です。最近ですと「ヤバい」とかでしょうか。単語を「座標系上の1点」にマッピングする訳ですから、同じ字面で異なる意味を持つ単語の扱いが難しいのは直感的に理解できると思います。こうした文脈に応じた表現の獲得手法として ELMo*5 やBERT*6が提案されています(BERTについては、また別の機会に紹介したいと思います)。

ここまでで単語の分散表現が獲得できました。ただ単語の分散表現を用いて文章の類似度を評価するには一工夫必要になってきます。 ここからは単語の分散表現を用いて文章間の類似度を評価する手法として Word Mover’s Distance、及びその簡略計算である LC-RWMD について紹介します。

4.3 Word Mover’s Distance

それでは、単語の分散表現を用いて文章間の類似度を評価する手法について考えてみましょう。 まずA:「大谷が代打でホームラン」、B:「田中が先発で好投」という二文の類似度を単語の分散表現で算出しようとすると、以下のように対応する単語同士の距離を算出して合計すれば良さそうです。

文書間の距離

ですが、単語間の対応関係などわかりようないですし、そもそも文章間で単語の数から異なるでしょう。ですので、単語を一対一で対応づけるのではなく、下図のような重み付きの対応関係を考えます。

単語間の重み

重みには、図中の青線のように単語に紐つく重みの和が頻度に等しくなるよう制約をかけ、重みと単語間距離の積の総和が最小となるように重みを調整します。調整済みの重みと単語間距離の積の総和が2文間の距離(=Word Mover’s Distance)となります。

この手法の欠点は計算量が大きいことです(語数の3乗に比例)。類似文書検索のようにクエリと検索対象間で多数の類似度計算が必要な場面では現実的ではないと思われます。

4.4 LC-RWMD (Linear-Complexity Relaxed Word Mover’s Distance)

WMD と比較して精度と引き換えに計算量を大幅に削減する手法が LC-RWMD *7 です。”LC-“の名のとおり、計算量は語数に比例です。

大まかな計算の流れは以下のとおりです。感覚的には検索対象とクエリの単語間の重み計算を省略し、検索対象の単語から見て一番近いクエリの単語との距離を、検索対象の単語とクエリ文との距離とみなしていると考えてもらえばよいです。

LC-RWMD

LC-RWMD(istance)という名前が示すとおり、この処理は文章 A と文章 B の間の距離(的な値)を計測するものです。ただし、LC-RMD では 「A から B を図った距離」と 「B から A を図った距離」が一致しないので、A から B, B から A と二回距離計算して、値の大きい方を採るとより正確な近似ができます。また、WMD, LC-RWMD に共通するTipsとして、単語ベクトルの長さを1に揃えてから計算すると精度が向上する傾向があるようです*8

5. 文書の分散表現を用いた手法

ここからは単語ではなく文書の分散表現を取得する手法を紹介していきます。単語の分散表現では、文の類似度を得るためにアレコレと計算が必要でしたが、文書を固定長のベクトルに変換できれば、後はコサイン類似度で評価できるので簡単ですね。

5.1 Doc2Vec

Doc2Vec*9 は Word2Vec を文章に適用できるようにアレンジした手法です。 Doc2Vec には PV-DM、PV-DBoW の二つの手法があり、以下が PV-DM のイメージです。 学習対象の各文書に文書IDを割り当てます。Word2Vec の CBoW の計算に、文書入力重みから文書IDに対応する行を取り出して混ぜ込みます。学習後は図中の文書入力重みの部分に文書IDに対応する文書ベクトルが出来上がっています。

Dec2Vec

類似文書検索のクエリとして新規文書を投入されたときのベクトルはどうするの?と疑問に思われるかもしれません。新規文書に対しては、単語入力重み、単語出力重みを固定した状態で、新規の文に対応する文書入力重みを改めて学習して文書ベクトルを生成することになります。

5.2 Sent2Vec

Sent2Vec*10も Word2Vec のアレンジといってよいでしょう。こちらの学習では単語とNグラムの分散表現が得られます。Nグラムは連続するN個の単語(あるいは文字)を単位とするもので、文章が"I have a very interesting book" なら 2グラムは “I have”, “have a”, “a very”, … に、3グラムなら"I have a", “have a very”, … という具合です。Sent2Vec では1グラムと2グラムで良好な結果が得られるようです。学習が終われば、新規文書の分散表現が文書中の単語とNグラムの分散表現を平均するだけで得られます。

Sent2Vec

学習過程でも平均を使っている為か、Sent2Vec で学習した分散表現は希少語と頻出語のベクトルの大きさが小さくなる(=平均したときの影響度が小さい)とのことです。

6. 類似文書検索における各手法の精度比較

ここまでで、単語の出現回数、単語の分散表現、文章の分散表現等によって文章の類似度を評価する手法を紹介してきました。 ここからは、前章までに紹介した手法に IBM の文書情報検索サービスである Watson Discovery *11 を含めて類似文書検索の精度比較試験を行ったので、その結果を紹介します。

6.1 日本語データセットの準備

類似文書検索の精度評価に適当な日本語データセットが見つからなかったので、翻訳者が異なる英文小説の訳文を類似文書として使用しました。まず、手作業でほぼ同じ内容になるよう文章をサンプルに切り分けます。翻訳者により単語の選択に傾向があったので、サンプルの半数を入れ替えた上で、片方をクエリ、もう片方を検索対象文書としています。半数の入れ替えにより、文章の意味合いを評価する力が重視されるデータセットになったと思います。

クエリ、検索対象それぞれサンプル数は918。サンプルの平均文長は126文字といったサイズ感です。

6.2 精度評価手法

類似文書検索の精度評価指標には Mean Reciprocal Rank を使用しました。 各クエリの検索結果(類似度の降順)に含まれる正解の順位の逆数を全クエリで平均した値で 1.0 ~ 0.0 の範囲(1.0が最良)となります。

MRR

6.3 使用した主なソフトウェア

以下を使用しています。MeCaB + IPADIC で形態素解析を行い、以降の処理に自然言語処理用の Python ライブラリである gensim を用いています。 ただし、LC-RWMD の計算は tensorflow で実装し、Sent2Vec の学習は sent2vec で行いました。

ソフトウェア バージョン
Python 2.7.12 (SENT2VECのみ 3.5.2)
MeCaB 0.996-1.2ubuntu1
IPADIC 2.7.0-20070801+main-1
gensim 3.4.0
tensorflow 1.8.0
sent2vec https://github.com/epfml/sent2vec/tree/a3c4cda47de

6.4 類似文書検索手法の比較結果

実験結果は以下の通りです。Watson はさすがの商用サービスで若干抜けています。また、LSI、TF-IDF といった単語カウントによるシンプルな方法でWMD系と遜色ない精度が得られました。0.84 ~ 0.75 という数字ですが、「すべての検索において正解が検索結果中で2位になるケースで MRR = 0.5になる」感覚で捉えてもらえばよいと思います。データセットが変わると違う傾向になるかもしれませんが、複雑な手法を適用すればよいという訳ではないことが見て取れます。

Result

それぞれの手法の内容は以下のとおり。投入する品詞、頻出/希少語の閾値、ユニット数など試行錯誤して各手法で最良の結果だったものを示しました。

手法名 パラメータ等
Watson Watson Discovery を使用。コレクションは 2018/8/13 に作成し文書をロード。関連性学習なし。 language: ja, enrichment: entity, category, sentiment, concept が有効。
TF-IDF 全品詞の原形をnoabove= 0.7, nobellow = 0 でフィルタ。smartirs = “atc"。
LSI 全品詞の原形をnoabove= 0.5, nobellow = 0でフィルタ。smartirs = "atc"。トピック数 = 400。
WMD 名詞、動詞、形容詞、形容動詞の原形をnoabove= 0.7, nobellow = 0でフィルタ。朝日新聞単語ベクトル*12のcbow-retrofitting.txtを使用(次元数=300)。
LC-RWMD 名詞、動詞、形容詞、形容動詞の原形をnoabove= 0.7, nobellow = 0でフィルタ。朝日新聞単語ベクトルのcbow-retrofitting.txtを使用(次元数=300)。LC-RWMDはtensorflowで実装したものを使用。
SENT2VEC 日本語Wikipediaを全品詞の表層形、900次元、2gram で12 epoch学習。
DOC2VEC 全品詞の原形をnoabove= 0.7, nobellow = 0でフィルタ。朝日新聞単語ベクトルのcbow-retrofitting.txtを初期値(次元数=300)として、window = 5, sample = 1e-6, negative = 5 で学習。

Doc2Vec のスコアがやたら悪いですが、学習対象の文長が短すぎたと思われます*13 。また、形態素解析では IPADIC にWeb上の新語や人名等が追加された NEologd も試しましたが、全般的に IPADIC を越えるスコアは得られませんでした。これに関しては、今回の対象とした文書が著作権切れの英文小説の和訳なので当然と言えば当然かもしれません。

7. おわりに

今回は各種の類似文書検索手法と日本語の文書に対する精度比較結果をご紹介しました。ソースコードは説明してませんが、gensim を用いる例は良質な技術記事が豊富にあるので、そちらを参考にしてもらえれば良いと思います。

次回は、NLU(Natural Language Understanding:自然言語理解)について紹介する予定です。

1: TF や IDFの計算にはいろいろと変種があります(SMART notation)。あっちやこっちに + 1 したり。詳しくはお使いになるライブラリのソースをご確認下さい。
2: https://arxiv.org/abs/1301.3781
3: https://www.aclweb.org/anthology/N/N15/N15-1184.pdf
4: 日本語WordNet:http://compling.hss.ntu.edu.sg/wnja/
5: https://arxiv.org/abs/1802.05365
6: https://arxiv.org/abs/1810.04805
7: https://arxiv.org/abs/1711.07227
8: GensimのWMD実装はデフォルトでそうなっています。また手元で実装したLC-RWMDでも効果が確認できました。
9: https://arxiv.org/abs/1507.07998
10: https://arxiv.org/abs/1703.02507
11: https://www.ibm.com/watson/jp-ja/developercloud/discovery.html
12: http://www.asahi.com/shimbun/medialab/word_embedding/
13: サンプルを5つ結合、文長をおよそ5倍にして再実験したところ、学習データの全体量はそのままで、0.6強まで改善しました。