全文検索
1.
概要
全文検索 (full-text search) はテキストデータベースや文書集合として存在する非構造化テキストから特定の単語やフレーズを含む文書とその出現位置を取得する検索技術である。情報検索におけるキーワード検索 (索引語検索、疎検索) に相当し、文書とクエリーをターム (単語) の集合として表現し、転置インデックスを用いて照合する方法を指す。
テキストの先頭から末尾までを走査してパターンに一致する位置を見つけ出す逐次検索 (sequential search) (文字列マッチング) と異なり、全文検索はあらかじめ文書集合から転置インデックスを構築しておくことで、文書数の増加に対して検索時間が伸びにくい索引検索 (index search) を行う。
Table of Contents
2.
テキスト解析
全文検索におけるテキスト解析 (text analysis) は文書を効率的に検索できるようにテキストを構造化する。インデックス (索引) を作成するための前処理である。
2.1.
トークン化
トークン化 (tokenization) は文書を検索対象となる単位のトークン (token) に分割するテキスト解析の最初のステップである。トークン化を行う処理をトークナイザー (tokenizer) と呼ぶ。
トークン化の方法は言語や用途によって異なる。例えば英語では単純に空白文字を区切り文字として利用できる一方で、単語の区切りの曖昧な日本語では一般に MeCab, Kuromoji, ChaSen といった形態素解析器や N-gram を利用する。
2.1.1.
形態素解析
形態素解析は辞書を用いて単語の活用形や品詞などからトークンの区切りを推定する。IPAdic は MeCab や Kuromoji などで広く使われている形態素解析に利用可能な辞書であり、他にも Juman, UniDic などの辞書が利用できる。
例えば「東京都知事選挙」を形態素解析すると「東京」「都知事」「選挙」の 3 つのトークンに分割される。形態素解析器は文書の意味を理解するために重要な情報を提供するが、辞書に登録されていない単語や造語に対しては適切な解析ができないという欠点がある。形態素解析を使用する場合、新しい言葉に対応するために継続的な辞書のメンテナンスが必要である。
2.1.2.
N-gram
N-gram は文章を
例えば「東京都知事選挙」を 2-gram でトークン化すると「東京」「京都」「都知」「知事」「事選」「選挙」となる。N-gram を使った全文検索は形態素解析と比べて精度が低い反面、辞書を使用しないため新しい単語や造語、業界特有の言い回しなどにも適応できる利点がある。
2.2.
正規化
トークン化された文字列は活用や表記などの表現上の変化を含んでいるため、それらが検索時に意味的に同じ言葉として正しくヒットするように一貫した形式に変換する必要がある。
ここでは正規化されたトークンのことをターム (term) と呼ぶ。正規化されたタームの集合を bag-of-words (BoW) と呼ぶ。
N-gram によって切り出されたトークンは意味づけされていないためいくつかの正規化手法は難しい。
2.3.
ストップワード
一般的でどのような文章にも含まれる助詞や冠詞などのタームは検索時にノイズとして作用することが多く、またインデックスを肥大化する要因にもなる。そのようなタームをインデックスに含めない (検索対象外とする) ために指定するタームの集合をストップワード (stop word) と呼ぶ。例えば「は」「が」「the」「is/are」などのタームはストップワードに含まれることが多い。
ただし、最近の検索エンジンではインデックス時にはストップワードの除外処理を行わず、検索時に選択的にストップワードを除外する使い方が多くなっている [2]。
3.
インデックス作成
3.1.
転置インデックス
全文検索の基本的なアルゴリズムは転置インデックス (inverted index) と呼ばれるデータ構造を用いる。このデータ構造は事実上すべての情報検索システムが中核に採用している [1]。転置インデックスは、文書集合に含まれるターム (正規化されたトークン) とその出現位置を記録したデータ構造である。1 つのタームに対する出現位置のリストをポスティングリスト (posting list) と呼ぶ。ポスティングリストの位置情報は昇順にソートされている。
例として 3 つの文書をテキスト解析して作成した転置インデックスを Fig 1 に示す。それぞれの文書はテキスト解析を受けてタームに分割され、それぞれのタームに対して出現位置として文書 ID が関連付けられ転置インデックスに記録されている。
3.2.
語彙目録
転置インデックスに含まれているタームの集合を語彙目録 (lexicon) または辞書 (dictionary) と呼ぶ (形態素解析器が単語の区切りを推定するために使用する IPAdic などの辞書とは異なる)。
語彙目録の役割はクエリーに含まれるタームからそのポスティングリストが保存されている位置を取得することである。したがって、少なくとも高速な完全一致検索が可能であることが要件となるが、現実的な検索システムでは comput* のような前方一致検索や、ある範囲のタームを対象とする範囲検索のように、選択するデータ構造でタームの順序をどう保持するかも焦点となる。
ハッシュテーブル: 完全一致検索を
で行うことができる。ただしタームの順序が失われるため、前方一致検索や範囲スキャンには向いていない。 ソート済み配列と二分探索: 実装が単純で空間効率が良く順序も保たれるが、タームの追加のコストが高い。
トライ (trie): 共通の接頭辞を共有する木構造。前方一致検索に適しており、ダブル配列や LOUDS といった表現を用いることで空間効率を高めることができる。
FST (finite state transducer): 接頭辞に加えて接尾辞も共有する非巡回グラフでトライよりもコンパクトになる。Apache Lucene が語彙目録に採用している。
語彙目録は検索のたびに参照されるためメモリ上に常駐させることが望ましいが、そのサイズは文書集合の増加とともに大きくなる。文書集合に含まれる異なるタームの数
3.3.
ポスティングリストの実装
転置インデックスの記憶容量の大部分はポスティングリストが占め、また検索の処理時間もポスティングリストの走査が支配的である。このため、検索システムの性能はどれだけコンパクトかつ高速に走査できるデータ構造を選ぶかが重要になる。
ポスティングリストに含まれる文書 ID は昇順にソートされているため、値そのものではなく直前の値との差分として格納することができる。これをギャップ符号化 (gap encoding) と呼ぶ。例えば文書 ID のリスト [3, 4, 7, 9, 11] は [3, 1, 3, 2, 2] となり、出現頻度の高いタームほど小さい値に偏る。この偏りを利用して、小さい値ほど短いビット列で表現できる整数符号を適用する。
可変長バイト符号 (VByte): 7 ビットずつバイト境界で区切る単純な方式。圧縮率は高くないが復号が速い。
γ 符号 / δ 符号: 値の桁数を単進符号で、値そのものを二進符号で表す。圧縮率は高いがビット単位の処理となるため復号のコストが大きい。
PForDelta, Simple-9/16: 一定個数の値をまとめて固定ビット幅で詰め込み、その幅に収まらない例外だけを別に記録する。ワード単位で処理できるため復号が高速で SIMD 命令とも相性が良い。
Elias-Fano 符号: 単調増加列を情報理論的な下界に近い空間で表現しながら、任意の位置へのランダムアクセスも可能にする簡潔データ構造。
一方で、AND 検索やフレーズ検索ではポスティングリストを先頭から順に読むことよりも「ある文書 ID 以上の要素まで一気に読み飛ばす」操作が支配的となる。このためポスティングリストを一定件数ごとのブロックに区切り、各ブロックの先頭の文書 ID と格納位置をスキップポインタ (skip pointer) として別に保持する実装が用いられる。読み飛ばすべき距離が事前に分からない場合は、探索幅を 1, 2, 4, 8, … と倍々に広げて範囲を絞ってから二分探索に切り替えるギャロッピング探索 (galloping search; 指数探索) が有効である。
なお、タームの出現頻度は Zipf の法則に従い、一般に少数の高頻度タームが全体の大部分を占めている。ポスティングリストの長さもタームによって数件から数千万件まで大きく偏るため、短いリストと長いリストで異なる表現を使い分ける実装も多い。
4.
検索
検索エンジンやデータベースに情報を問い合わせるための入力をクエリー (query) と呼ぶ。全文検索でのクエリーは、ユーザが求めている特定の情報を記述するキーワードやフレーズで構成される。
本セクションではクエリーに一致する文書の集合を求めるマッチングを扱い、一致した文書に順序を与えるランキングについては次セクション以降で説明する。
4.1.
AND 検索
AND 検索 (AND search) は複数のキーワードがすべて含まれる文書を検索する手法である。例えばクエリー cats AND dogs と検索すると "cats" と "dogs" の両方が含まれる文書が検索される。
例としてクエリー
このような処理を
ここでは説明のためにカーソルを一つずつ進めているが、実際の実装で行われているのは「指定した文書 ID 以上の要素までカーソルを進める」操作であり、前述のスキップポインタやギャロッピング探索が用いられる。特に、ごく短いポスティングリストと非常に長いポスティングリストの AND を取る場合、長い方を線形に走査するかどうかで処理時間が大きく変わる。
4.2.
OR 検索
OR 検索 (OR search) は複数のキーワードのいずれかが含まれる文書を検索する手法である。例えばクエリー cats OR dogs を用いて検索すると "cats" または "dogs" が含まれる文書を検索する。
クエリー
上記の処理を
4.3.
フレーズ検索
フレーズ検索 (phrase search) は複数の単語が特定の順序で連続して現われる文書を検索する手法である。例えばクエリー "information retrieval" と検索すると、ターム information の直後に retrieval が存在する文書だけが検索対象となる。
フレーズ検索では文書 ID に加えてそのタームが文書中のどこに現われたかを示す情報が必要になる。フレーズ検索の転置インデックスのポスティングリストは [文書ID]
クエリー "
5.
クエリと文書の拡張
ここまでに説明した方法は、クエリーと文書に共通のタームが一つも含まれていなければ、両者が同じ内容を指していても照合することができない。この問題を語彙不一致 (vocabulary mismatch) と呼ぶ。例えば「PC」というクエリーで「パソコン」や「コンピュータ」について書かれた文書を見つけることはできない。
語彙不一致に対処するには、クエリーにタームを追加して文書側の表現に近づけるか、逆に文書にタームを追加してクエリー側の表現に近づけるかの二つの方向がある。前者をクエリ拡張 (query expansion)、後者を文書拡張 (document expansion) と呼ぶ [3]。
5.1.
クエリ拡張
もっとも単純なクエリ拡張は、シソーラス (同義語辞書) を用いてクエリーのタームを同義語や上位語に展開し、それらの OR 検索として扱う方法である。実装は容易だが辞書の整備コストがかかり、また多義語に対しては無関係な文書を大量に呼び込む原因にもなる。
検索結果そのものを手がかりにする方法もある。適合性フィードバック (relevance feedback) はユーザが検索結果の中から適合する文書を指定し、そこに出現するタームを使ってクエリーを修正する。式 (
ただし実際のユーザが適合判定を入力してくれることは稀である。そこで、最初の検索結果の上位数件を無条件に適合文書とみなして同じ操作を行う疑似適合性フィードバック (PRF; pseudo relevance feedback) が用いられる。上位の検索結果が実際に適合していれば精度が向上する一方、外れていた場合はクエリーが誤った方向に移動して結果が悪化する。この現象をクエリドリフト (query drift) と呼ぶ。
5.2.
文書拡張
文書拡張は、その文書を探し当てるであろうクエリーをあらかじめ生成して文書に付加しておく手法である。doc2query は言語モデルを用いて文書から想定されるクエリーを生成し、それを文書の一部としてインデックスに追加する。また SPLADE のように、言語モデルを用いて文書とクエリーを語彙数次元の疎なベクトルへ展開し、その重みごと転置インデックスに格納する手法もある。
クエリ拡張が検索のたびに追加の計算を必要とするのに対して、文書拡張の計算はインデックス作成時に一度だけ行われ、検索時には通常の転置インデックスの走査のみで完結する。これらは言語モデルの推論という高価な処理を行う事前計算による償却の考えに基づいた手法と言える。
6.
ランキング付きの検索
ランキング (ranking) は検索クエリーに一致した文章のうち、よりユーザの関心が高いと考えられる結果を上位に配置するプロセスである。前セクションで説明した転置インデックスを用いてクエリーがどのように文書と一致判定されるかに加えて、このセクションでは検索結果にどのように順位付けするかを説明する。
ランキングは一般的に検索クエリーと文書との類似度を算出し、よりクエリーと関連する文書を上位に表示する。例えば Apache Solr や Elasticsearch ではデフォルトのスコアリングに BM25 を使用して類似度を算出している。さらに、実用的な検索システムでは検索対象の属性情報 (価格や評価数、リリース日など) を用いてスコアを再調整することが一般的である。この属性情報によるスコアリングの調整はブースト (boost) と呼ばれ、類似度との関連をチューニングすることでランキングの精度を向上させる。
6.1.
類似度を使用したランキング
基本的なランキング手法では、文書
6.1.1.
TF-IDF
TF (term frequency) (
IDF (inverse document frequency) (
最終的に
6.1.2.
コサイン類似度
コサイン類似度 (cosine similarity) は 2 つのベクトル間の類似度を計る指標である。ベクトルがなす角度が小さいほど 1 に近づき類似度が高いと見なすことができる。ある文書を (TF-IDF のような) 特徴ベクトルで表現した文書ベクトル
6.1.3.
BM25
式 (
式 (
第 2 項は分母にも
IDF についても式 (
6.1.4.
ランキング OR 検索
例として TF-IDF を使用したランキング付き OR 検索について説明する。転置インデックスを作成するときに
4. 同様の操作でそれぞれのポスティングリストの末尾まで処理を進める。得られた
6.2.
上位 件の効率的な取得
前述のランキング OR 検索はすべてのポスティングリストを末尾まで走査してから結果を並べ替えている。しかしユーザが実際に目を通すのは上位の数十件であり、最終的な順位に影響しない文書のスコアを計算することは無駄である。文書集合が大規模になるほどこの無駄は無視できなくなる。
このため、走査の途中で上位
WAND (weak AND) はこの閾値を利用する代表的な手法である。インデックス作成時に、各タームについてそのターム単独で与えうるスコアの最大値
Block-Max WAND (BMW) はこれをさらに細かくしたもので、ポスティングリスト全体ではなくブロックごとにスコアの上限を保持する。ターム単独の上限はごく一部の文書によって決まることが多く、リスト全体の上限は大半のブロックにとって過大な見積もりとなる。ブロック単位の上限を用いることで枝刈りの機会が大幅に増える。
これらの手法は、得られる上位
動的枝刈りではスコアの計算 (ランキング) の結果によって走査 (マッチング) の範囲が変化することに注意。マッチングとランキングは概念としては分離できるが、転置インデックスに基づく検索の実装においては互いに分離できない。
6.3.
機械学習によるランキング
検索システムでの機械学習は「文書の順序関係」を予測するために利用する。この手法はランキング学習 (learning to rank; LTR) と呼ばれる。TF-IDF や BM25 といった従来の手法は主に単語の頻度などの静的な特徴量に依存している。ランキング学習モデルはユーザのクリックやメタデータ、履歴など、さまざまな特徴量を統合してランク付けを行うことができる。
6.4.
近接度によるランキング
ターム近接度 (term proximity) によるランキングは、複数の検索タームが互いに近くに出現する文書の方がランクが上に評価されるべきであるという考えに基づく。
7.
参考文献
- Stefan Buttcher, Charles L. A. Clarke, Gordon V. Cormack. 情報検索 :検索エンジンの実装と評価. 森北出版 (2020)
- 打田智子, 古澤智裕, 大谷純, 加藤遼, 鈴木翔吾, 河野晋策. 検索システム実務者のための開発改善ガイドブック. ラムダノート (2022)
- 佐藤竜馬. 検索システム ― なぜ検索システムは欲しい情報を見つけられるのか、あるいはなぜ見つけられないのか ―. 講談社 (2026)


