ワードエンベディングベクトルを使った検索アプリを作った話

この記事は、情報検索・検索エンジン Advent Calendar 2019の17日目の記事です。
https://qiita.com/advent-calendar/2019/search

昨日書いた、自然言語処理 Advent Calendar 2019の16日目の記事からの続きになっています。

Luminosoの会社と技術(昨日の記事のおさらい)

アンケートや口コミなどのデータを解析して顧客の声や従業員の声を解析したり、業務報告書などを解析してあいまい検索を行うようなサービスを提供するボストン発のMITスピンアウトのスタートアップです。

もう少しNLPの技術者向けに説明すると、セマンティック辞書に基づいて補正したワードエンベディングベクトルモデルを、ドメインデータでfine-tuningすることで、少量のデータで前処理込でユーザ毎のモデルを高速に作成するサービスを提供している会社です。

単語ベクトルを使って文書検索をする

まず、「ベクトルを使って検索する」ということですが、一番シンプルな方法はベクトルの類似度を計算するという方法です。ベクトル検索でいうと最近傍探索を思い浮かべる人がいると思いますが、私の会社で扱うデータですと数千レコード程度のごく少量で済むため(昨日の記事参照)、雑に全件分計算しても十分な速度で結果が返ってきます。

では、単語ベクトルから文書ベクトルをどのように定義するかということですが、我々は単純に文中に出現した単語のベクトルの平均を取ることで表しています。これにより、単語ベクトルと同じ次元で文書ベクトルを表現することができるため、文書と文書の比較だけでなく、単語と文書の比較もできるようになります。

利点としては、とにかく手軽に検索ができるという点です。辞書も前処理もいらずに数千行のデータに対してあいまい検索ができるようになります。例えば、電化製品の製品レビューコメントを検索するときも、「故障する」と検索するだけで「通電しなくなった」と書かれている文書を検索できるようになります。単にベクトルで距離計算しているだけなので、専用のエンジン等も一切必要ありません。

欠点としては、BoWなどと同様、文構造や単語の順序を考慮していないため、複雑な文や長文に対して精度が悪くなるということです。

類似する単語をシノニムとした検索

文書検索にはもうひとつの方法があります。単語ベクトルが既に存在しているので、ある検索キーワードと距離が近い単語をシノニムとして検索を行うことです。モデルの性質上、文脈上近い使われ方をしている単語や意味的に近い単語の類似度が高くなるため、類似度の高い高い単語をシノニムとして扱うという手法は有効です。Luminosoではこの方法を標準的な検索方法として採用しています。

ベクトル計算の応用

文書ベクトルを「単語ベクトルの平均」としたのと同様、あるフィルタ条件のベクトルも、「そのフィルタ条件にあてはまる文書ベクトルの平均」とすれば、計算は可能です。これにより、特定の検索クエリにもっとも近い「住所」「性別」「年齢」はどれか、などを計算することができるようになります。これらの属性を「ファイル」や「Webページ」ととらえれば、一般的な検索と同じことをしているということがわかるかと思います。

Luminosoでは、デモアプリとして単語ベクトルを使ったこのような検索アプリケーションを使用しています。

ベクトルを使った検索アプリの実際

例えばフィルタ処理やAND/ORなど、検索にはさまざまな機能が要求されるため、実際にはベクトル計算だけでは実運用する検索アプリケーションとしては十分な機能を提供できません。また、先述の通り、素朴なベクトル類似度計算では、少しデータが多くなるだけで性能面では全く使い物にならないほど遅くなってしまいます。このように、機能面・性能面を考慮すると、十分に開発が進んだ検索エンジンを使う必要がでてくるでしょう。Elasticsearchは、近年ベクトル検索をサポートしています。今年の検索アドベントカレンダーでもElasticsearchのベクトル検索を使った記事がありますので、この記事での紹介は省略します。


で、結局何ができるの?

LuminosoとElasticsearchを組み合わせると、数千行程度のテキストを投げ込むだけで、前処理も辞書作成も行わずに、社内用語や専門用語、類義語や表記ゆれ、typoなどに対応した検索アプリケーションを作成することができます。これができるようになれば、今までコストの面などで苦労していた、エンタープライズ領域の検索システムもより気軽に導入できるようになるでしょう。