アペフチ

全文検索とスコアリングの仕組み

久し振りにGroongaで学ぶ全文検索 2016-08-26@イーライセンスシステムズに参加してきた。

今日は、全文検索がどういう物かよく分かっていないという人が複数人いたことから、全文検索の仕組みと、スコアリングについて話をしてもらった。

全文検索の仕組み

ホテルデータベースを考える。ホテルのある場所、種類(ホテルか旅館か)、泊数や日付、説明があって、それぞれで絞り込みができる。このうち、説明が全文検索(テキスト検索)の対象になる。

ある言葉(「軽井沢」)で検索する時に、全ホテルを順番に見て、それぞれに検索語が含まれているかを調べる方法は、非常に時間が掛かる。耐えられる時間内に検索結果が返ってこない。そこで、検索結果を速く返すための準備をすることになる。この準備をしたデータのことをインデックスと呼ぶ。

インデックスというのは、日本語では索引で、考え方は本の末尾にある索引と同じ。本の方の索引は、専門用語などの「言葉」と、その言葉が出てくる「ページのリスト」を並べた物だ。全文検索エンジンのインデックスも同様で、キーワードと、そのキーワードを含んでいる文書(のIDなど)のペアを並べた物になっている。検索語がこのインデックスに載っていると、検索するのが速い。但し、インデックスに載っていない検索語は、検索できなくなる。そこで、インデックスのキーに載っている単語を増やすのがコツになる。

元々の説明文などからこのキーを作る方法は二種類ある。一つは、説明を日本語として解釈して分割し、分割結果をキーにする方法。形態素解析と呼ばれる。

もう一つは単純に決めた文字数で区切ること。「軽井沢に行こう」という説明文だったら、「軽井」「井沢」「沢に」「に行」「行こ」「う」と区切ることができる。この時、「軽井沢」で検索すると、どこにもこれと同じキーはないのでヒットしない。そこで、検索語の方も同じように区切って「軽井」「井沢」とする。それから「説明文に『軽井』を含んでいるホテル一覧」と「『井沢』を含んでいるホテル一覧」を取得し、その共通部分を取ると、「軽井沢」を含むホテル情報が手に入る。正確には、「『軽井沢』を含む可能性のあるホテル情報一覧」が手に入る。「井沢さんと軽井さんが経営しています」という文書もヒットするからだ。それを防ぐため、共通部分を取る時に、「キーワードの順番と離れ具合を見て、この順番で隣り合っているような説明文のホテル一覧」を取得するようにする。すると「説明文に『軽井沢』を含んでいるホテル一覧」になる。

スコアリング

なぜスコアをつけるのか、という話を最初にした。それは、検索結果一覧の中のそれぞれで、ユーザーの欲しそう度合いが違うから。欲しそうな度合いの大きい物を先に提示して、そうでない物を後に提示すると、ユーザーが本当に欲しかった物をよりうまく提供できるだろうという考え方による。この欲しそう度合いを決める際に、エリアなどの項目をどれくらい重視するかというのを数値にした物のことを「重み」と呼んで、重みを決めることを「重み付け」と言う。検索スコアをつける際、それぞれの重みを考慮したスコアをつけることになる。

スコアリングの際には、確実さと重要さの二つを考えて行う。

確実さというのは、「軽井沢」で検索した時に、説明文で「軽井沢にほど近い」となっているホテルよりも、エリアがズバリ「軽井沢」となっている方が重くなるようにスコアをつけること。

重要さというのは、仮に説明文にタイトルと本文があった時に、タイトルの方が大事だろうと考えて、タイトルにヒットした場合により高いスコアをつけること。