TL

全文検索の内部:逆引きインデックスとスコアリング(BM25)

検索結果が「なぜこの順で並ぶのか」が原理から分かります。転置インデックスのポスティングリストやスキップリストの構造、TF-IDF・BM25 の数理、フレーズ検索の仕組みまで内部動作を解説します。

応用全文検索転置インデックスBM25TF-IDF検索エンジンアルゴリズム最終更新: 2026-06-21
TL;DR要点だけ先に
  • 1.転置インデックスは term dictionary とポスティングリストの二層構造。語から文書 ID 列へ直行し、スキップリストで AND 結合のマージを加速する。
  • 2.TF-IDF は出現頻度(TF)と希少性(IDF)の積。BM25 は TF の飽和と文書長の正規化を加えた改良版で、現代の検索の事実上の標準。
  • 3.フレーズ・近接検索はポスティングに語の出現位置を持たせて実現する。位置情報の有無で索引サイズとできる検索が変わる。

転置インデックスの二層構造

全文検索の基礎は 全文検索 で触れた 転置インデックス(inverted index) ですが、その内部は単純な「語 → 文書一覧」の表ではありません。実装は二つの層に分かれます。

  • term dictionary(辞書): 索引対象の全語(term)をソート済みで保持し、各語からポスティングリストの位置へポインタを持つ。語の数は文書数より遥かに少なく、ここを引いて目的の語に到達する。
  • posting list(ポスティングリスト): 各語ごとに、その語を含む文書 ID(doc id)を 昇順に並べた列。多くの場合さらに語の出現頻度や出現位置を併せ持つ。

term dictionary は、Lucene では FST(有限状態トランスデューサ)で圧縮され、共通接頭辞を共有して数百万語でもメモリに載るよう設計されます。検索はまず辞書で語を引き、得たオフセットからポスティングリストを読む、という二段で進みます。

ポスティングリストと差分圧縮

ポスティングリストは doc id の昇順列なので、値そのものではなく 隣との差(delta) を記録すると小さくできます。

元の doc id 列 : 5, 9, 13, 28, 31
delta 符号化   : 5, 4,  4, 15,  3   ← 前の値との差だけを保存

差は元の値より小さいため、可変長整数(VByte)や PForDelta、Roaring Bitmap といった手法で少ビットに詰められます。索引が小さいほどキャッシュに載りやすく、I/O も減るため、圧縮は速度のためにも効きます。複数語の AND 検索は、各語のポスティングリスト(いずれも昇順)を同時に前進させる マージ結合 で交差を求めます。a AND b なら両方に出る doc id だけを残す処理です。

スキップリストでマージを加速

単純なマージは両リストを端から舐めるため、片方が極端に短いと無駄が出ます。たとえば 稀な語 AND ありふれた語 では、ありふれた語の長大なリストを一件ずつ進めるのは非効率です。そこで各ポスティングリストに スキップリスト(skip list) を重ねます。

一定間隔ごとに「この先 K 件先の doc id とその格納位置」を記録しておき、目標の doc id がまだ先なら途中を読み飛ばします。スキップ間隔を sqrt(リスト長) 程度に取ると、交差判定が線形から準線形に改善します。

スキップは“どこまで読み飛ばせるか”の道標

スキップリストの各エントリは「ここまでの最大 doc id」と「ジャンプ先のファイルオフセット」の組です。求める doc id がエントリの最大値を超えていれば、その区間のポスティングは答えに含まれ得ないので丸ごと飛ばせます。B+Tree の内部ノードが探索を振り分ける道標であるように、スキップリストはマージ走査の道標として働きます。

TF-IDF:頻度と希少性の積

ヒットした文書をどの順に並べるか、それが スコアリング です。古典的な指標が TF-IDF で、二つの直感を掛け合わせます。

  • TF(term frequency): 文書 d 中で語 t が多く出るほど、その語に関連が深い。
  • IDF(inverse document frequency): 多くの文書に出る語(「の」「する」等)は識別力が低く、稀な語ほど重い。
idf(t) = log( N / df(t) )      N=総文書数, df(t)=t を含む文書数
score(d, q) = Σ_(t∈q) tf(t,d) × idf(t)

df が大きい(ありふれた)語ほど idf は 0 に近づき、スコアへの寄与が小さくなります。これにより「珍しい検索語の一致」が「ありふれた語の一致」より高く評価されます。

BM25:飽和と文書長の正規化

TF-IDF には二つの弱点があります。TF が線形なので語が 100 回出る文書が 10 回の文書より単純に 10 倍重くなること、そして長い文書ほど語が増えて不当に有利になることです。これを補正したのが BM25(Best Matching 25) で、現代の検索エンジンの事実上の標準です。

score(d,q) = Σ_(t∈q) idf(t) ×
             ( tf(t,d) × (k1 + 1) ) /
             ( tf(t,d) + k1 × (1 - b + b × |d| / avgdl) )

  k1   : TF の飽和を制御 (一般に 1.2〜2.0)
  b    : 文書長正規化の強さ (0〜1、既定 0.75)
  |d|  : 文書 d の長さ(語数)
  avgdl: 全文書の平均長

要点は二つです。第一に、分母に tf を含む形のため TF は 飽和 します。語が増えるほどスコアは伸びますが頭打ちになり、k1 がその曲がり具合を決めます。第二に、b による 文書長正規化 で、平均より長い文書(|d| / avgdl が 1 より大きい)はスコアが割り引かれます。b=0 なら長さを無視、b=1 なら完全に正規化します。

観点TF-IDFBM25
TF の扱い出現回数に線形比例飽和する(頭打ち、k1 で調整)
文書長の補正原則なしb で正規化し長文の過大評価を抑制
調整パラメータ実質なしk1・b で挙動を調整可能
位置づけ古典・教科書的Lucene/Elasticsearch 既定の標準
パラメータは語数の分布で決める

k1 を上げると TF の効きが強まり、語の繰り返しが多い長文コーパス(論文・マニュアル)で差が出やすくなります。b を下げると長い文書のペナルティが弱まり、文書長がまちまちで「長い=情報量が多い」場合に有効です。既定 k1=1.2, b=0.75 は多くのコーパスで無難ですが、評価データで A/B 比較して調整するのが定石です。

位置情報とフレーズ・近接検索

AND 検索は語の共起しか見ないため、"機械 学習" というフレーズを「機械」と「学習」が離れて出る文書とは区別できません。フレーズ検索や近接検索を実現するには、ポスティングリストに doc id・頻度だけでなく 語の出現位置(position) を持たせます。

term "学習" の posting:
  doc 7 : freq=3, positions=[12, 45, 88]
  doc 9 : freq=1, positions=[5]

フレーズ "機械 学習" は、両語のポスティングを取り、同じ文書内で「機械」の位置 p の直後 p+1 に「学習」があるかを位置リストの突き合わせで確認します。近接検索(NEAR/3 等)は、その位置差が指定値以下かを判定するだけです。位置を持つ索引(positional index)は doc id だけの索引よりサイズが増えますが、フレーズ・近接という重要な検索を可能にします。

位置情報を切ると索引は小さくなるが検索が制限される

出現位置の格納は索引サイズの大きな部分を占めます。ログ全文検索のようにフレーズ一致が不要なら位置を省いて索引を軽くできますが、その索引ではフレーズ・近接検索が一切できなくなります。後から位置を足すには再索引(reindex)が必要です。何を検索したいかを索引設計の段階で決める必要がある、という典型例です。

索引としての位置づけ

転置インデックスは B+Tree インデックス と同じ「索引」ですが、向く問題が異なります。B+Tree は値の順序と範囲に強く一意制約や主キーに使われ、転置インデックスは「語を含むか」の集合演算とスコア順位付けに特化します。

転置インデックスのもう一つの工夫は、存在しない語の問い合わせを早く弾く前段フィルタです。語が辞書になければポスティングを読むまでもなく空集合と分かり、確率的に存在を判定する ブルームフィルタ が併用されることもあります。スコア順 top-k だけ欲しい場合は、BM25 の上限を見積もって低スコア文書を打ち切る WAND/Block-Max WAND といった枝刈りで、ポスティング全走査を避けます。索引を引いて クエリ最適化 と同じく「読まずに済ませる」のが、全文検索を速くする一貫した発想です。

データベース Article

全文検索の内部:逆引きインデックスとスコアリング(BM25)を実務で読む

TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。

解決すること

全文検索

比較で見る軸

難易度: advanced / カテゴリ: データベース / タグ数: 6

導入後に効く点

TF-IDF は出現頻度(TF)と希少性(IDF)の積。BM25 は TF の飽和と文書長の正規化を加えた改良版で、現代の検索の事実上の標準。

先に潰すリスク

用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。

数字・仕様の読み方
難易度
advanced
カテゴリ
データベース
タグ数
6

判断チェックリスト

  • 自社の用途が「全文検索 / 転置インデックス」に近いか確認する。
  • 強みである「転置インデックスは term dictionary とポスティングリストの二層構造。語から文書 ID 列へ直行し、スキップリストで AND 結合のマージを加速する。」が本当に評価軸になるか確認する。
  • 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
  • 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
  • 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
  • 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。

次に確認する観点

全文検索転置インデックスBM25TF-IDF検索エンジン全文検索転置インデックスBM25
参考: 公式情報