ベクトル検索と埋め込み — 「犬」と「猫」がお隣さんの、言葉の星屑マップ
検索窓に「わんちゃん」と打ったとき、ふつうの検索は「わんちゃん」という文字が入った文書しか見つけられません。「犬」と書かれた文書は、意味は同じなのに引っかからない。文字が一致するかどうかしか見ていないからです。
ベクトル検索は、言葉を意味の地図の上の座標に置き換えてから探します。この座標を作ることを埋め込み(Embedding)と呼びます。意味が似た言葉ほど近くに置かれるので、「わんちゃん」の座標のまわりを見れば、そこに「犬」や「子犬」が浮かんでいる。下の図1は、言葉を3次元に置いた星屑の地図です。ドラッグで回しながら、いろいろな言葉で探してみてください。
埋め込み — 言葉を、意味の座標に変える
ベクトル検索の土台は、埋め込みモデルです。文章を入れると、[-0.60, 0.40, 0.20] のような数字の並び(ベクトル)を返します。大量の文章から「一緒に使われやすい言葉は意味が近い」というパターンを学んでいるので、「犬」と「子犬」、「犬」と「猫」は近い数字に、「犬」と「新幹線」は遠い数字になります。
図1は分かりやすいように3次元ですが、実際の埋め込みは数百〜数千次元あります。次元が多いぶん、「動物」「かわいい」「家で飼える」のような意味の違いを、別々の方向として細かく表せるのです。図1で「猫」を探すと、文字の一致では「子猫」しか見つからないのに、ベクトル検索では犬やうさぎまで近くに並びます。どちらも「家で飼う小さな動物」の方向にいるからです。
検索 — 近い星を、上から k 個
探すときは、質問も同じモデルで座標に変え、その座標に近い順に k 個を返します。近さの物差しには、図1のような距離のほか、2本の矢印の向きがどれだけそろっているかを測るコサイン類似度がよく使われます。
ただし、何百万個もの星と1つずつ距離を測っていては間に合いません。そこでベクトルDB(pgvector、Pinecone など)は、地図をあらかじめ区画に分けておき、近そうな区画だけを調べる索引を持っています。ほんのまれに一番近い星を取りこぼす代わりに、桁違いに速く探せる。これを近似最近傍探索(ANN)と呼びます。
ベクトル検索は万能ではありません。型番や人名のように文字がぴったり合ってほしい検索はキーワード検索のほうが確実で、実務では両方を組み合わせることもよくあります。LLMに資料を渡すRAGで「質問に関係する資料」を探しているのも、たいていこのベクトル検索です。
- ベクトル
- 数字の並び。ここでは、言葉や文章の意味を表す座標。
- 埋め込み(Embedding)
- 言葉や文章を、意味が近いほど近くなるようなベクトルに変換すること。またはそのベクトル。
- k近傍(k-NN)
- ある点に近い順に k 個の点を取ってくること。ベクトル検索の基本の形。
- コサイン類似度
- 2つのベクトルの向きのそろい具合。1に近いほど意味が近い。
- 近似最近傍探索(ANN)
- 厳密さを少しだけあきらめて、大量のベクトルから近いものを高速に探す方法。
まとめ
ベクトル検索は、言葉を意味の地図の座標に変え(埋め込み)、近くにある星を拾う検索です。文字が一致しなくても、「わんちゃん」から「犬」、「麺類」から「ラーメン」が見つかる。キーワード検索が「同じ文字か」を見るのに対して、ベクトル検索は「同じあたりの意味か」を見ている――違いはこの一点です。