
みなさんこんにちは。エンジニアの佐藤です。
今回は「あいまい検索」を掘り下げたいと思います。
あいまい検索とは
あいまい検索とは、検索キーワードに完全一致しない語句や表現でも関連する結果を返す検索技術の総称です。筆者が案件で経験した範囲では、n-gram方式による製品名のキーワード検索や、ベクトル検索による社内文書検索がありますが、目的の動作のために、それぞれ調整に苦労した覚えがあります。
簡単に説明すると、キーワード検索とは、1. 文書からキーワードを抽出し、その「キーワード -> 文書」の対応関係を網羅したデータベースを作成し、2. ユーザーが持ち込んだ検索キーワードにあらかじめ抽出したキーワードが一致する場合は該当する文書を回答する技術です。また、ベクトル検索は、1. テキスト埋め込みモデルを用いて文書を事前ベクトルに変換し、2. ユーザーが持ち込んだ検索キーワードを同じテキスト埋め込みモデルでベクトルに変換してベクトルが似ている文書を回答する技術です。
ハイブリッド検索の登場、だが
そんな折、Salesforce Data 360(当時はData Cloud)にハイブリッド検索の機能が登場しました。(1年ほど前の話です。)
ハイブリッド検索とは、キーワード検索とベクトル検索の両方を実行し、結果を合算して検索結果の列挙順を決めます。こうすることで、注文番号など完全一致で高い選択性が要求される場合にはキーワード検索の効果を、感覚などの類似性の検出が要求される場合にはベクトル検索の効果を、一つの仕掛けで同時に期待することができるというわけです。
しかし、このハイブリッド検索、本当に期待通りの結果を出すものでしょうか?
こう質問されると、内心不安になる方もいらっしゃるのではないでしょうか。筆者も、実のところ不安なところがあります。そしてその不安とはつまり、「ベクトル検索の結果が読めない」に尽きるのではないでしょうか。そうです、これがなかなか難しいのです。
テキスト埋め込みモデル「Multilingual E5 Large」を調べてみると
Data 360で使える、日本語対応しているテキスト埋め込みモデルは Multilingual E5 Largeと呼ばれ、Hugging Faceに公開されています。元々はMicrosoftが開発したもので、PyTorchで使えるモデルのファイルは2GB以上あります。このニューラルネットワークの中を入力文書が駆け巡り、最終的に1024個の数値(ベクトル)に変換されるわけです。
ですが、はっきり言語化できるのは、ここまでです。あとはもう、モデル作成のために収集されたデータが形作る、決定論的には記述できないAIの世界に入っていくわけです。
なかなか、つかみどころが見つからない感じがしますよね。
そこで、ちょっとした実験と、ベクトル検索ではなくLLMを用いたあいまい検索の実装方法を考えてみました。(後述)
試してみる
あいまい検索の題材に、以下のような赤から黄色の11段階の色表現を考えてみます。
- 赤
- 濃い赤
- 赤寄りオレンジ
- オレンジ寄り赤
- オレンジ
- 中間的オレンジ
- 黄寄りオレンジ
- 明るいオレンジ
- オレンジ寄り黄色
- 淡い黄色
- 黄色
※: 色相との日本語表現は必ずしも一致しているわけではないので、その辺りは参考程度で考えてください。
これらについて、以下のような「あいまい検索」を実行します。
- 検索対象は「赤」と「黄色」の2つ
- これらに対し、赤〜黄色の11種類の色表現を検索し、「赤」と「黄色」の検索スコアを観察する。
以下のような3つの検索方法を試しました。
| 名称 | 説明 |
|---|---|
| BM25 | キーワード検索を行います。あいまい検索ではありませんが、ハイブリッド検索の動作を推測する際の参考として実行しました。 |
| ベクトル検索 | Multilingual E5 Largeを用いたベクトル類似度の評価を行います。ベクトル類似度の評価にはコサイン類似度を選びました。 |
| LLMを用いたあいまい検索 | (下の説明をご覧ください) |
「LLMを用いたあいまい検索」とは
この手法は筆者が考えたもので、検索というよりも、「入力表現をどのカテゴリに分類するか」という意味解釈の問題をLLMに委ねる方法です。手法は以下のようなものです。
例えば、以下のようなレコードがあるとします。
- 製品1: 色=赤
- 製品2: 色=黄色
ここへ「濃い赤」という検索文字列が渡されたら、以下のようなプロンプトでLLMに赤か黄色か判断させるわけです。
与えられた色に近いのは「赤」と「黄色」のどちらかを選んでください。
与えられた色: {濃い赤}
一言だけで答えてください: 「赤」または「黄色」。
LLMは「赤」か「黄色」のいずれかを出力します。あとはこれをWHERE句に渡せば、あいまい検索が実現するというわけです。
プロンプトはごく短く、文脈も浅いので、モデルにはGoogle Gemini 2.5 Flash Liteを使用しました。また、生成時の揺らぎを回避するため、温度は0、top-pとtop-kは1に設定しました。
キーワード検索(BM25)の結果
「赤」「黄色」に対する、11種類の色表現検索のスコアは以下のようになりました。(今回の実験では、比較のためスコアを0〜1に正規化しています。)
| 色表現 | 赤 | 黄色 |
|---|---|---|
| 赤 | 1.0000 | 0.0000 |
| 濃い赤 | 0.0000 | 0.0000 |
| 赤寄りオレンジ | 0.0000 | 0.0000 |
| オレンジ寄り赤 | 0.0000 | 0.0000 |
| オレンジ | 0.0000 | 0.0000 |
| 中間的オレンジ | 0.0000 | 0.0000 |
| 黄寄りオレンジ | 0.0000 | 0.0000 |
| 明るいオレンジ | 0.0000 | 0.0000 |
| オレンジ寄り黄色 | 0.0000 | 0.0000 |
| 淡い黄色 | 0.0000 | 0.0000 |
| 黄色 | 0.0000 | 1.0000 |

こちらは予想通りの結果と言えると思います。今回はキーワードの分割や派生語の生成を行っていないので、「赤」と「濃い赤」は完全に異なります。「黄色」についても同様です。完全一致すればスコアは1.0、そうでなければスコアはゼロです。
ベクトル検索(Multilingual E5 Large)の結果
こちらは複雑な結果となりました。
| 色表現 | 赤 | 黄色 | 優勢 |
|---|---|---|---|
| 赤 | 1.0000 | 0.4863 | 赤 |
| 濃い赤 | 0.5264 | 0.2398 | 赤 |
| 赤寄りオレンジ | 0.3537 | 0.1445 | 赤 |
| オレンジ寄り赤 | 0.3606 | 0.1805 | 赤 |
| オレンジ | 0.3276 | 0.3111 | 赤 |
| 中間的オレンジ | 0.1065 | 0.1590 | 黄色 |
| 黄寄りオレンジ | 0.1415 | 0.2735 | 黄色 |
| 明るいオレンジ | 0.0552 | 0.0324 | 赤 |
| オレンジ寄り黄色 | 0.1776 | 0.4531 | 黄色 |
| 淡い黄色 | 0.2284 | 0.6495 | 黄色 |
| 黄色 | 0.4863 | 1.0000 | 黄色 |

テキスト埋め込みモデルのトレーニングデータは、さまざまな人の主観で書かれた色表現が混在していると思います。しかしその点を考慮しても、疑問を感じる点はあります。
- 赤のスコアを順番に見ていくと、「オレンジ」より「黄色」の方が赤との類似性が高い。同様に黄色のスコアを順番に見ていくと、「オレンジ」より「赤」の方が黄色との類似性が高い。
- 「明るいオレンジ」より「淡い黄色」の方が赤との類似性が高い。同様に「明るいオレンジ」より「黄寄りオレンジ」の方が黄色との類似性が高い。
ここでは実施しませんでしたが、他の埋め込みモデルではどうなるのか、気になるところです。
LLMを用いたあいまい検索の結果
こちらは以下のような結果になりました。
| 色表現 | LLM判定 |
|---|---|
| 赤 | 赤 |
| 濃い赤 | 赤 |
| 赤寄りオレンジ | 赤 |
| オレンジ寄り赤 | 赤 |
| オレンジ | 赤 |
| 中間的オレンジ | 赤 |
| 黄寄りオレンジ | 黄色 |
| 明るいオレンジ | 赤 |
| オレンジ寄り黄色 | 黄色 |
| 淡い黄色 | 黄色 |
| 黄色 | 黄色 |

この結果は、ベクトル検索でスコアが優勢となった色に近い結果になっています。これはひょっとすると、トレーニングのために収集した色表現文書の母集団が似通ったものだったからかもしれません。
全ての実験コードはこちらのNotebookからご覧になれます。興味のある方はご自身で実行されてはいかがでしょうか。(ただし、Google Cloudのアカウントとキーの発行が必要になります。)
ハイブリッド検索のスコアを想像すると
ハイブリッド検索のスコアは、キーワード検索とベクトル検索のスコアの和ですが、実際にはどちらを優勢にするか、スコアの違いをどのように解釈するかでさまざまな実装が考えられます。Salesforce Data 360でもクエリ時に調整することができます。また、Data 360はキーワードサーチのトークン化ルールを公表していませんので、例えば「深い赤」は、「深い」と「赤」に分断され、「赤」の部分が部分点を稼ぐという可能性もあるでしょう。
しかし、どのように調整しようとも、今回の用途では、「赤=赤」「黄色=黄色」のキーワードが突出して強烈な(期待通りの)スコアとなり、それ以外は凸凹する(期待外れのスコアが含まれる)、というのは避けられないと思います。よって、例えば、検索対象の製品(色鉛筆など)に、今回あげた11色の色が書いてあって、それらを赤色に近い順に紹介しようと思った時、検索文字列「赤」に対するハイブリッド検索のスコアの大きい順にソートしたら、「黄色」が「オレンジ」より先に出てきてしまうというおかしな話になってしまいます。
さらに、色に関するこのような状態が、味や形状といった評価軸との複合になった時、それらがどのように相互作用するかは、まさに「やってみないとわからない」としか表現できないような気がします。
こうしてみてみると、ベクトル検索は「他では拾えない候補を拾える可能性がある」点が魅力である一方、「不適切な検索結果の意図的排除が難しい」検索技術であると言えると思います。
LLMを用いたあいまい検索のメリット
LLMを用いたあいまい検索もまた、ベクトル検索と同じくトレーニングデータに影響される理解し難い過程を経由していると思われますが、こちらはLLMの判定結果が「赤」や「黄色」と一度はっきり示される点がシステムの透明性を高めます。また、他の検索にはないメリットとして、否定表現の解釈や、追加プロンプトによる結果の微調整の余地がある点も魅力です。
ただし、実行する際のコンピュータ的コストは大きくなります。
皆さんはどのように感じられたでしょうか。実際のECや業務システムでは、ここに在庫数や販売実績といった制約が加わるため、「どの段階で曖昧さを許容するか」が設計上の重要な判断点になります。
最後までお読みくださり、ありがとうございました。