ベクトル検索(Vector Search)において、距離尺度は「何をもって『似ている』とするか」を定義する根幹のルールです。現在、フルマネージドでスケーラブルなPinecone Serverlessや、エンタープライズ向けのストレージ最適化が進むMilvus、あるいはコスト最適化の観点からQdrantやPostgreSQLのpgvectorを採用するなど、ベクトルデータベースの選択肢は多様化しています。
中学生時代にゲームプログラミングに没頭し、高校生で業務システム開発の現場に触れて以来、35年以上の開発現場で培われた知見から言えるのは、技術の本質は「まず動くものを作る」プロトタイプ思考にあるということです。プロトタイピングの段階では、ドキュメントの推奨通りにCosine(コサイン類似度)を選んでおくのも一つの手でしょう。しかし、本格的なビジネス実装へとフェーズを移行する際、そこで思考停止してしまうのは非常にもったいないと思いませんか?
多くの開発者が陥る「とりあえずコサイン類似度」の罠
確かに、自然言語処理(NLP)の世界では、コサイン類似度は「安全な」選択肢として広く認知されています。文章の長さに関わらず、単語の出現頻度の傾向(ベクトルの向き)だけを見て類似性を判断できるからです。
しかし、AIエージェント開発や業務システム設計の現場は、もっと複雑な要件を抱えています。
- RAG(検索拡張生成): 質問に対する回答候補を検索する際、単にトピックが似ているだけでなく、情報の「密度」やソースの「確信度」も考慮したい場合があります。
- レコメンデーション: 「似ている商品」と「実際に売れている商品」は違います。ニッチな類似商品ばかりを提案しても、ユーザーは購入に至らないことが多いのです。
- 異常検知: 正常データからの「方向のズレ」だけでなく、「距離(逸脱度)」そのものが重要になります。
距離尺度の選択を誤ると、埋め込みモデル(Embedding Model)が学習したリッチな情報を、検索時に自ら捨て去ることになります。これは、高性能なスポーツカーを買って、常にエコモードでしか走らないようなものです。システム全体のパフォーマンスを最大化し、ビジネスへの最短距離を描くには、用途に応じた尺度のチューニングが不可欠です。
ベクトルの「向き」と「大きさ」が持つ情報の違い
ベクトル空間において、データは「向き(Direction)」と「大きさ(Magnitude / Norm)」という2つの重要な情報を持ちます。
- 向き: そのデータが「何についてのものか」という質的な特徴を表します(例:猫の記事か、犬の記事か)。
- 大きさ: その特徴が「どれくらい強いか」という量的な強度を表します(例:猫への言及頻度、あるいはその記事の人気度や情報の網羅性)。
コサイン類似度は、このうち「向き」しか評価しません。一方、ドット積(内積)やユークリッド距離は「大きさ」の情報も計算に含みます。
ここがシステム設計における重要な分岐点です。皆さんが現在取り組んでいるタスクにおいて、「ベクトルの大きさ」は排除すべきノイズでしょうか? それとも予測精度を高めるための重要なシグナルでしょうか?
この問いに即答できない場合、現在のベクトル検索パイプラインにおける距離尺度の見直しが必要かもしれません。アーキテクチャの根幹を再評価することで、検索精度は大きく向上する可能性があります。
【理論編】3つの距離尺度を「幾何学的」に直感理解する
数式を見ると頭痛がするかもしれませんが、安心してください。エンジニアとしてここだけは押さえておくべき幾何学的な意味を整理しましょう。概念さえ掴めば、ツール選定で迷うことはなくなります。
ユークリッド距離(L2):空間上の「絶対的な近さ」
ユークリッド距離(L2距離)は、一般的に「距離」と認識されているものそのものです。2点間を定規で測った直線の長さですね。
$ d(A, B) = \sqrt{\sum (A_i - B_i)^2} $
- 特徴: 2つのベクトルの先端がどれだけ離れているか(座標の差)を見ます。
- 直感: 「向き」と「大きさ」の両方が一致していないと、距離は近くなりません。
- 弱点: 高次元空間(数百次元以上)では「次元の呪い」により、すべての点同士の距離が均一化してしまい、差が出にくくなる傾向があります。
内積(Dot Product):射影による「相関と大きさ」の評価
内積は、一方のベクトルを他方に投影した長さと、元の長さを掛け合わせたものです。
$ A \cdot B = \sum A_i B_i = |A||B| \cos \theta $
- 特徴: ベクトルの「向きが似ている($\cos \theta$が大きい)」ほど、かつ「元のベクトルが長い($|A|, |B|$が大きい)」ほど、値が大きくなります。
- 直感: 類似性と強度のハイブリッド評価です。
- 注意: 値の上限が決まっていないため、閾値(threshold)の設定が難しい場合があります。
コサイン類似度:ベクトルの「方向」のみを見る純粋な意味類似
コサイン類似度は、内積をベクトルの大きさで割って正規化したものです。
$ \text{Cosine}(A, B) = \frac{A \cdot B}{|A||B|} = \cos \theta $
- 特徴: ベクトルの長さ(大きさ)を完全に無視し、角度(方向)だけを見ます。値は必ず -1 から 1 の間に収まります。
- 直感: どんなに長いベクトルでも、短いベクトルでも、向きが同じなら「同一」とみなします。
「正規化(L2 Norm)」を行うと内積とコサイン類似度が等価になる数学的カラクリ
ここで、ReplitやGitHub Copilotを駆使して即座に検証したくなるような、実務上非常に有効なハックを紹介しましょう。
もし、ベクトル $A$ と $B$ をあらかじめ長さ1に正規化(L2 Normalization)しておくとどうなるでしょうか?
$|A| = 1, |B| = 1$ となるため、内積の式は以下のようになります。
$ A \cdot B = 1 \cdot 1 \cdot \cos \theta = \cos \theta $
つまり、「正規化されたベクトルのドット積」は「コサイン類似度」と数学的に完全に等価になります。
多くのベクトルDB(Pineconeなど)や近似最近傍探索ライブラリ(Faissなど)では、コサイン類似度を直接計算するよりも、「データを正規化して保存し、高速なドット積(Inner Product)で検索する」ほうが計算コストが低い場合があります。コサイン類似度の計算には毎回「割り算」や「平方根」が必要ですが、ドット積は「掛け算と足し算(積和演算)」だけで済むからです。
これが、システム最適化の第一歩です。
【検証A】RAG・意味検索における「正規化ドット積」の優位性
では、具体的なユースケースに落とし込んでいきましょう。まずは現在最もホットなRAG(Retrieval-Augmented Generation)です。
OpenAI等の主要Embeddingモデルが想定する尺度
OpenAIの text-embedding-3-small や text-embedding-ada-002、あるいはCohereのモデルなどは、通常、出力されるベクトルがすでに正規化されているか、あるいは正規化して使うことを前提に設計されています。
これらのモデルは、意味的な類似性を「角度」で表現するように学習されています。したがって、基本的にはコサイン類似度が適しています。
しかし、前述の通り、実装レベルでは「正規化ドット積」を使うのがベストプラクティスです。
- インデックス時: テキストをEmbeddingし、ベクトルをL2正規化してDBに保存する。
- 検索時: クエリベクトルもL2正規化する。
- 距離尺度:
DotProductを指定する。
これにより、数学的にはコサイン類似度と同じ結果を得ながら、検索エンジンの内部処理(MIPS: Maximum Inner Product Search)を最高速で回すことができます。
長い文章と短い質問のマッチング精度比較
RAGにおいて、ユーザーの質問(短い)とドキュメントのチャンク(長い)をマッチングさせる場合、ベクトルの大きさがノイズになることがあります。
例えば、非常に長いドキュメントを埋め込むと、単語数が多い分、特定の次元の値が大きくなり、ベクトルのノルム(長さ)が大きくなる傾向があるモデルも存在します(※モデルのアーキテクチャによります)。
このとき、正規化せずに生のドット積を使うと、「内容はあまり関係ないが、とにかく長くて単語がいっぱい詰まったドキュメント」が検索上位に来てしまうリスクがあります。
純粋に「意味の一致」だけを拾いたいRAGにおいては、ベクトルの大きさを捨て、方向だけを見る(=正規化ドット積を使う)アプローチが、ハルシネーション(幻覚)を防ぐためにも有効です。
【検証B】推薦システムで「非正規化ドット積」が売上を作る理由
推薦システム(レコメンデーション)の領域では、検索システムとは異なり、あえてベクトルを正規化しない「非正規化ドット積(Dot Product)」がビジネス上の重要な役割を果たすケースがあります。これは、ベクトルの「向き」だけでなく「大きさ」にも意味を持たせるアプローチです。経営者視点で見れば、これが直接的な売上貢献につながるのです。
ベクトルの「大きさ(Magnitude)」を人気度や重要度として扱う
動画配信プラットフォームや大規模ECサイトで採用される推薦アルゴリズムの基礎となる「行列分解(Matrix Factorization)」やその派生手法において、学習されたベクトルはしばしば以下のような幾何学的特性を持ちます。
- ユーザーベクトル: ユーザーの嗜好の「方向」を表す。
- アイテムベクトル: コンテンツや商品の特性(方向)に加え、その人気度や品質を「ベクトルの長さ(ノルム)」として表現する。
モデルの学習過程において、多くのユーザーから支持される人気映画や、購入率の高い商品は、多数のユーザーベクトルとの内積値を大きくする必要があります。その結果、アイテムベクトルのノルムが自然と大きくなるようにパラメータが更新される傾向があります。
行列分解(Matrix Factorization)的なアプローチ
ここで、もし検索システムのようにすべてのベクトルを正規化(長さ=1)してコサイン類似度のみで計算してしまうと、どのような弊害が起きるでしょうか?
最大の問題は、ベクトルの長さ情報、すなわち「アイテムの人気度(Bias)」が消失してしまうことです。
その結果、ユーザーの嗜好ベクトルと方向だけは完全に一致しているものの、「誰も知らないマイナーな作品」や「信頼性の低い商品」ばかりが上位に推薦されるリスクが高まります。これは「Serendipity(予期せぬ発見)」として一部のユーザーには喜ばれるかもしれませんが、ビジネス全体としては機会損失につながりかねません。
一般的に、ユーザーは「自分の好みに合致し(適合度)」かつ「一定の社会的評価を得ている(人気度)」アイテムを求めています。非正規化ドット積は、この両方の要素を単一の計算で評価できる点が強力です。
数式で表現すると、以下のようになります。
$ \text{Score} = \text{User} \cdot \text{Item} = |\text{User}| |\text{Item}| \cos \theta $
この式において、推薦スコアは以下の2つの要素の積として構成されます。
- $\cos \theta$(コサイン類似度): ユーザーの好みとアイテムの特性がいかに一致しているか。
- $|\text{Item}|$(アイテムベクトルのノルム): そのアイテムがどれだけ強力な潜在的魅力(人気度)を持っているか。
このように、非正規化ドット積を用いることで、類似度と重要度をバランスよく加味した「売れる」推薦リストを高速に生成することが可能になります。ベクトルデータベースを選定する際は、単なる近傍探索だけでなく、こうした「内積(Inner Product)」によるスコアリングが効率的に行えるかどうかも重要な評価軸となります。
【検証C】画像検索・異常検知で「ユークリッド距離」が輝く瞬間
最後に、ユークリッド距離(L2)が必須となるケースを見てみましょう。これは主に、データの「分布」や「絶対位置」が重要な意味を持つタスクです。
画素値や特徴量の絶対的な差分を見る重要性
例えば、製造ラインでの製品画像の異常検知を考えます。正常な製品の画像ベクトルが空間上のある一点に集中しているとします。
異常な製品(傷がある、色が違うなど)は、そこから少し離れた位置にマッピングされます。このとき、異常品が正常品と同じ「方向」にある可能性もあります(例:全体的に色が薄いだけで、パターンの特徴は同じ場合など)。
コサイン類似度では、原点からの方向が同じであれば「類似度が高い(異常なし)」と判定されてしまうリスクがあります。しかし、ユークリッド距離であれば、絶対的な座標のズレを検知できるため、「似ているけれど、何かが違う」を正確に捉えることができます。
クラスタリングや分類タスクでの適合性
k-meansクラスタリングなどのアルゴリズムは、本質的にユークリッド距離に基づいて重心を計算します。したがって、これらのアルゴリズムと連携させる場合や、ベクトル空間内で物理的な近傍探索を行いたい場合は、L2距離を選択するのが整合性が取れると考えられます。
結論:タスク別・距離尺度選定ディシジョンツリー
ここまで見てきたように、距離尺度は「なんとなく」で選ぶものではなく、ビジネス要件と数理モデルの性質に合わせて設計すべきものです。
迷ったらこれを見る:状況別フローチャート
明日の実装から迷わないよう、シンプルな判断基準をまとめました。ぜひ活用してみてください。
モデルは正規化済みベクトルを出力するか?
- YES (OpenAI等) → Dot Product (実質Cosineだが高速)
- NO → 次へ
タスクは「人気度」や「強度」を考慮すべきか?
- YES (推薦システム、スコアリング) → Dot Product (非正規化)
- NO (純粋な意味検索、RAG) → ベクトルを正規化して Dot Product (またはCosine)
データの「絶対的な位置ズレ」が重要か?
- YES (異常検知、画像照合) → Euclidean (L2)
- NO → 上記に戻る
再インデックスなしでテストするための実装Tips
「すでにCosineでインデックスを作ってしまった!」という方も焦る必要はありません。多くのベクトルDBでは、検索時にクエリ側で調整が可能です。
例えば、Cosine類似度でインデックスされている場合でも、検索結果を取得した後に、アプリケーション側でメタデータとして保存しておいた「ベクトルのノルム」を掛け合わせることで、擬似的にドット積のランキングを再現することも可能です(これを「事後リランキング」と呼びます)。
重要なのは、現在使っている尺度が、解決したい課題に対して数学的に正しいアプローチなのかを、仮説を立てて即座に検証してみることです。
ベクトル検索の世界は奥が深く、距離尺度ひとつでビジネスの成果が劇的に変わる可能性があります。もし、チームで「RAGの精度が上がらない」「レコメンドのCVRが低い」といった課題を抱えているなら、一度この「数学的な設定」を見直してみてはいかがでしょうか?
コメント