ベクトル検索での関連性
ベクトル クエリの実行時、検索エンジンは類似のベクトルを検索して、検索結果に返される最適な候補を見つけます。 ベクトル コンテンツのインデックス付け方法に応じて、関連する一致の検索は網羅的であるか、ニアネイバーに制限されて処理が高速化されます。 候補が見つかると、類似性メトリックを使用して、一致の強度に基づいて各結果のスコアが付けられます。
この記事では、関連性のある一致を見つけるために使用されるアルゴリズムと、スコアリングに使用される類似性メトリックについて説明します。 また、検索結果が期待に沿っていない場合に関連性を向上させるヒントも提供します。
ベクトル検索で使用されるアルゴリズム
ベクトル検索アルゴリズムには、完全な k ニアレスト ネイバー (KNN) や Hierarchical Navigable Small World (HNSW) があります。
完全な KNN は、ベクトル空間全体をスキャンするブルート フォース検索を実行します。
HNSW は、近似ニアレスト ネイバー (ANN) 検索を実行します。
検索とスコアリングに使用されるのは、インデックスに searchable
としてマークされているフィールド、またはクエリの searchFields
としてマークされたベクトル フィールドだけです。
完全な KNN を使用する場合
完全な KNN は、データ ポイントのすべてのペア間の距離を計算し、クエリ ポイントの正確な k
ニアレスト ネイバーを見つけます。 これは、高い再現率が最も重要であり、ユーザーにクエリ待ち時間のトレードオフを受け入れる意思があるシナリオを対象としています。 計算負荷が高いため、小規模から中規模のデータセット、または精度要件がクエリ パフォーマンスの考慮事項を上回る場合は、完全な KNN を使用します。
2 つ目のユース ケースは、近似ニアレストネイバー アルゴリズムの再現率を評価するためのデータセットの構築です。 完全な KNN を使用して、ニアレストネイバーのグラウンド トゥルースのセットを構築できます。
HNSW を使用する場合
インデックス作成中に、HNSW は、データ ポイントを階層グラフ構造に編成して、より高速な検索のために追加のデータ構造を作成します。 HNSW には、検索アプリケーションのスループット、待機時間、および再現目標を達成するために調整できるいくつかの構成パラメーターがあります。 たとえば、クエリ時に、ベクトル フィールドに HNSW のインデックスが付いている場合でも、包括的な検索のオプションを指定できます。
クエリの実行中、HNSW はグラフ内を移動して高速な近隣クエリを有効にします。 このアプローチにより、検索の正確さと計算効率のバランスが取れます。 HNSW は、大規模なデータ セットを検索するときの効率が高いため、ほとんどのシナリオに推奨されます。
ニアレストネイバー検索のしくみ
ベクトル クエリは、同じ埋め込みモデルから生成されたベクトルで構成される埋め込み空間に対して実行されます。 一般に、クエリ要求内の入力値は、ベクトル インデックスに埋め込みを生成したのと同じ機械学習モデルにフィードされます。 出力は、同じ埋め込み空間内のベクトルです。 同様のベクトルが近接してクラスター化されるため、一致を見つけることは、クエリ ベクトルに最も近いベクトルを見つけ、関連するドキュメントを検索結果として返すのと同じです。
たとえば、クエリ要求がホテルに関する場合、モデルは、ホテルに関するドキュメントを表すベクトルのクラスター内のどこかに存在するベクトルにクエリをマップします。 類似度メトリックに基づいて、クエリに最も似ているベクトルを特定すると、最も関連性の高いドキュメントが決まります。
完全な KNN に対してベクトル フィールドのインデックスが作成されると、クエリは "all neighbors" に対して実行されます。 HNSW 用にインデックスが作成されたフィールドの場合、検索エンジンは HNSW グラフを使用して、ベクトル インデックス内のノードのサブセットを検索します。
HNSW グラフの作成
インデックス作成中、検索サービスは HNSW グラフを構築します。 HNSW グラフに新しいベクトルのインデックスを作成する目的は、効率的なニアレストネイバー検索できるような方法でグラフ構造に追加することです。 次の手順は、このプロセスをまとめたものです。
初期化: 空の HNSW グラフ、または新しいインデックスでない場合は既存の HNSW グラフから開始します。
エントリ ポイント: これは階層グラフの最上位レベルであり、インデックス作成の開始点として機能します。
グラフへの追加: 階層レベルが異なると、グラフの細分性が異なり、レベルが高いほどグローバルになり、レベルが低いほど細かく表示されます。 グラフ内の各ノードは、ベクトル ポイントを表します。
各ノードは、近隣にある最大
m
個のネイバーに接続されます。 これがm
パラメーターです。候補接続と見なされるデータ ポイントの数は、
efConstruction
パラメーターによって管理されます。 この動的リストは、アルゴリズムが考慮する既存のグラフ内の最も近いポイントのセットを形成します。efConstruction
値が大きいほど、多くのノード数が考慮され、多くの場合、各ベクトルのローカル近傍が高密度になります。これらの接続では、構成された類似性
metric
を使用して距離を決定します。 一部の接続は、さまざまな階層レベルで接続する "長距離" 接続であり、検索効率を向上させるショートカットをグラフに作成します。
グラフの枝刈りと最適化: これは、すべてのベクトルのインデックス作成後に発生する可能性があり、HNSW グラフのナビゲート性と効率が向上します。
クエリ時の HNSW グラフ内の移動
ベクトル クエリは、一致をスキャンするために階層グラフ構造内を移動します。 プロセスの手順の概要を次に示します:
初期化: アルゴリズムは、階層グラフの最上位レベルで検索を開始します。 このエントリ ポイントには、検索の開始点として機能するベクトルのセットが含まれています。
トラバーサル: 次に、グラフをレベルごとに走査し、最上位レベルから下位レベルに移動し、コサイン類似性など、構成された距離メトリックに基づいてクエリ ベクトルに近い候補ノードを選択します。
枝刈り: 効率を向上させるために、アルゴリズムは、ニアレストネイバーを含む可能性が高いノードのみを考慮して、検索領域を刈り込みます。 これは、潜在的な候補の優先順位キューを維持し、検索が進むにつれてそれを更新することによって達成されます。 このキューの長さは、パラメーター
efSearch
によって構成されます。絞り込み: アルゴリズムがより低く、より細かいレベルに移行すると、HNSW はクエリの近くでより多くのネイバーを考慮し、ベクトルの候補セットを絞り込み、精度を向上させます。
完了: 検索は、ニアレストネイバーの必要な数が特定された場合、または他の停止条件が満たされたときに完了します。 このニアレスト米バーのこの必要な数は、クエリ時間パラメーター
k
によって制御されます。
類似性の測定に使用される類似性メトリック
アルゴリズムは、類似性を評価する候補ベクトルを検索します。 このタスクを実行するために、類似性メトリック計算では、候補ベクトルとクエリ ベクトルを比較し、類似性を測定します。 アルゴリズムは、検索された最も類似しているベクトルの順序付けされたセットを追跡し続け、アルゴリズムが完了したときにランク付けされた結果セットを形成します。
メトリック | 説明 |
---|---|
cosine |
このメトリックは、2 つのベクトル間の角度を測定し、ベクトルの長さの違いによる影響を受けません。 数学的には、2 つのベクトル間の角度を計算します。 コサインは Azure OpenAI 埋め込みモデルで使用される類似性メトリックであるため、Azure OpenAI を使用している場合は、ベクトル構成で cosine を指定します。 |
dotProduct |
このメトリックは、2 つのベクトルの各ペアの長さと、それらの間の角度の両方を測定します。 数学的には、ベクトルの大きさとそれらの間の角度の積を計算します。 正規化されたベクトルの場合、これは cosine 類似性と同じですが、パフォーマンスは若干高くなります。 |
euclidean |
(別名 l2 norm ) このメトリックは、2 つのベクトル間のベクトル長の差を測定します。 数学的には、2 つのベクトルの差の l2ノルムである 2 つのベクトル間のユークリッド距離を計算します。 |
ベクトル検索結果のスコア
スコアが計算されて、それぞれの一致に割り当てられ、最も高い一致が k
の結果として返されます。 @search.score
プロパティにスコアが含まれています。 次の表は、スコアが該当する範囲を示しています。
検索メソッド | パラメーター | スコアリング メトリック | Range |
---|---|---|---|
ベクトル検索 | @search.score |
コサイン | 0.333 - 1.00 |
cosine
メトリックについては、計算された @search.score
がクエリ ベクトルとドキュメント ベクトルの間のコサイン値ではないことに注意することが重要です。 代わりに、Azure AI Search では、スコア関数が単調に減少するような変換が適用されます。つまり、スコア値は、類似性が悪化すると常に値が減少します。 この変換により、検索スコアをランク付け目的で使用できます。
類似性スコアにはいくつかの微妙な違いがあります:
- コサイン類似性は、2 つのベクトル間の角度のコサインとして定義されます。
- コサイン距離は
1 - cosine_similarity
として定義されます。
単調に減少する関数が作成されるように @search.score
は 1 / (1 + cosine_distance)
として定義されます。
合成値の代わりにコサイン値が必要な開発者は、数式を使用して、検索スコアをコサイン距離に戻すことができます:
double ScoreToSimilarity(double score)
{
double cosineDistance = (1 - score) / score;
return -cosineDistance + 1;
}
元のコサイン値を持たせておくと、低品質の結果をトリミングするためのしきい値を設定するカスタム ソリューションにおいて有用です。
関連性のチューニングに関するヒント
関連性のある結果が得られない場合は、クエリの構成の変更を試してください。 ベクトル クエリには、スコアリング プロファイルやフィールド、用語ブーストなどの特定のチューニング機能はありません。
チャンク サイズと重複について実験します。 チャンク サイズを大きくし、チャンク間のコンテキストまたは継続性を維持するのに十分な重複を確保します。
HNSW の場合は、近接グラフの内部構成を変更するさまざまなレベルの
efConstruction
を試します。 既定値は 400 です。 範囲は 100 ~ 1,000 です。チャット モデルを使用している場合は、
k
の結果を増やして、より多くの検索結果をチャット モデルにフィードします。セマンティック ランク付けを使用してハイブリッド クエリを試します。 ベンチマーク テストでは、この組み合わせが一貫して最も関連性の高い結果をもたらしました。