ベクトル類似検索の実行
このトピックでは、Milvusを使用してエンティティを検索する方法について紹介します。
Milvusでは、ベクトル類似検索は、クエリベクトルとコレクション内のベクトルとの間の距離(指定された類似度尺度を使用して)を計算し、最も類似した結果を返します。また、スカラーまたはプライマリキーのフィールドをフィルタリングするために論理式を指定して、混合検索を実行できます。
次の例は、データセットに含まれる書籍ID(プライマリキー)、単語数(スカラーフィールド)、および書籍の概要(ベクトルフィールド)を含む2000行のデータでベクトル類似検索を実行する方法を示しており、ベクトル化された記述に基づいて特定の書籍を検索するシミュレーションを行います。Milvusは、クエリベクトルと定義した検索パラメータに基づいて、最も類似した結果を返します。
コレクションの読み込み
Milvus内でのすべての検索およびクエリ操作はメモリ内で実行されます。ベクトル類似検索を実行する前に、コレクションをメモリに読み込みます。
from pymilvus import Collection
collection = Collection("book") # 既存のコレクションを取得します。
collection.load()
検索パラメータの準備
検索シナリオに対応するパラメータを準備します。次の例では、Euclidean距離を使用して距離を計算し、IVF_FLATインデックスによって構築された10個の最も近いクラスタからベクトルを取得するために検索が使用するパラメータを定義しています。
search_params = {
"metric_type": "L2",
"offset": 5,
"ignore_growing": False,
"params": {"nprobe": 10}
}
パラメータ | 説明 |
---|---|
metric_type |
検索中にベクトル間の距離を測定するために使用される方法。これは、インデックス構築プロセスで指定された方法と同じである必要があります。詳細については類似度尺度を参照してください。 |
offset |
検索中にスキップするエンティティの数。この値とsearch メソッドのlimit の合計は16384 より小さくなければなりません。たとえば、クエリベクトルの9番目と10番目の最近傍をクエリしたい場合は、limit を2に設定し、offset を8に設定します。 |
ignore_growing |
類似度検索中に成長セグメントを無視するかどうか。デフォルト値はFalse で、検索に成長セグメントが含まれることを示します。 |
params |
指定されたインデックスタイプに固有の検索パラメータ。詳細については、ベクトルインデックスを参照してください。可能なオプションには次のものがあります: - nprobe は検索するクラスタリングユニットの数を示します。このパラメータは、index_type をIVF_FLAT 、IVF_SQ8 、またはIVF_PQ に設定する場合にのみ使用できます。値はインデックス構築プロセスで指定されたnlist の値より小さい必要があります。 - ef は検索範囲を示します。このパラメータはindex_type をHNSW に設定する場合にのみ使用できます。値はtop_k と32768 の間である必要があります。 - radius は最も低い類似度を持つベクトルが位置する角度を示します。 - range_filter は、クエリベクトルとの類似度が特定の範囲内にあるベクトルフィールドの値をフィルタリングするために使用されるフィルタを示します。 |
ベクトル検索の実行
Milvusを使用してベクトル検索を行います。特定のパーティション内で検索するには、パーティション名のリストを指定します。
Milvusでは検索のための一貫性レベルの設定がサポートされています。このトピックの例では、一貫性レベルを「強力」に設定しています。他にも「境界付き」、「セッション」、「最終的に」などの一貫性レベルを設定することができます。Milvusの4つの一貫性レベルについての詳細は一貫性を参照してください。
results = collection.search(
data=[[0.1, 0.2]],
anns_field="book_intro",
param=search_params,
limit=10,
expr=None,
output_fields=['title'],
consistency_level="Strong"
)
results[0].ids
results[0].distances
hit = results[0][0]
hit.entity.get('title')
パラメーター | 説明 |
---|---|
data |
検索に使用されるベクトル。 |
anns_field |
検索されるフィールドの名前。 |
param |
インデックスに固有の検索パラメーター。詳細はベクトルインデックスを参照してください。 |
limit |
返される結果の数。この値とparam 内のoffset を合わせたものは16,384未満である必要があります。 |
expr |
プロパティをフィルタリングするためのブール式。詳細はブール式のルールを参照してください。 |
output_fields (オプション) |
返されるフィールドの名前。ベクトルフィールドは現在サポートされていません。 |
consistency_level (オプション) |
検索の一貫性レベル。 |
最も類似したベクトルの主キー値と距離をチェックします。
results[0].ids
results[0].distances
検索が完了したら、Milvusの読み込まれたコレクションを解放してメモリ消費量を削減します。
collection.release()
制限事項
機能 | 最大制限 |
---|---|
コレクション名の長さ | 255 文字 |
コレクション内のパーティション数 | 4,096 |
コレクション内のフィールド数 | 256 |
コレクション内のシャード数 | 256 |
ベクトル次元 | 32,768 |
Top K | 16,384 |
入力ベクトル | 16,384 |
複合検索の実行
複合検索は、基本的には属性のフィルタリングとともにベクトル検索です。ブール式を指定することで、特定の条件下で検索を限定できます。
以下の例は、通常のベクトル検索
に基づいた複合検索の実行方法を示しています。例えば、要約のベクトル化された書籍を検索したいが、特定の字数の範囲内でのみ検索したい場合、検索パラメーターでword_count
フィールドをフィルタリングするブール式を指定します。Milvusは、ブール式に一致するエンティティ内でのみ類似したベクトルを検索します。
ブール式を指定することで、ベクトル検索中にエンティティのスカラーフィールドをフィルタリングすることができます。以下の例では、特定のword_count
値の範囲内のベクトルのみを検索範囲として制限しています。
フィルタリング式で動的なフィールドを使用したり、検索リクエストで出力フィールドを使用したりすることができます。例えば、動的パターンを参照してください。
search_param = {
"data": [[0.1, 0.2]],
"anns_field": "book_intro",
"param": {"metric_type": "L2", "params": {"nprobe": 10}, "offset": 0},
"limit": 10,
"expr": "word_count <= 11000",
}
res = collection.search(**search_param)
返された結果をチェックします。
assert len(res) == 1
hits = res[0]
assert len(hits) == 2
print(f"- 合計ヒット数: {len(hits)}, ヒットID: {hits.ids} ")
print(f"- Top1 ヒットID: {hits[0].id}, 距離: {hits[0].distance}, スコア: {hits[0].score} ")
範囲検索の実行
範囲検索は、クエリベクトルとベクトルフィールド値との間の距離に基づいて検索結果をフィルタリングする方法です。異なる距離メトリクスを使用して距離を測定することができます。
範囲検索を実行する際、Milvusはまずベクトル類似度検索を行います。その後、指定された距離条件に基づいてベクトルをフィルタリングし、特定の範囲内の距離にあるベクトルを返します。
以下の例は、通常のベクトル検索に基づいた範囲検索の実行方法を示しています。
コレクションの読み込み
Milvusでのすべての検索およびクエリ操作はメモリ内で実行されます。ベクトル類似性検索を実行する前に、コレクションをメモリに読み込む必要があります。
from pymilvus import Collection
collection = Collection("book") # 既存のコレクションを取得
collection.load()
ベクトルフィルタリング範囲の設定
通常のベクトル検索と比較して、Milvusにおける範囲検索は、特定の検索範囲内で所望の検索結果を取得するために、radius
とrange_filter
という2つの新しいパラメータを導入して制御されます。
radius
は、ベクトルが類似とみなされる最小の角度を指定します。radius
と併用できるオプションのrange_filter
は、クエリベクトルに対する類似性に基づいてベクトルフィールドの値を特定範囲内でフィルタリングするために利用できます。radius
とrange_filter
の両方のパラメータは、FLOATのデータ型を持ちます。これら2つのパラメータを設定することで、検索の正確さと効率を効果的にバランスさせることができます。
通常、類似性はベクトルフィールドの値とクエリベクトルの間の距離で測定されます。異なる距離メトリクスの選択は、radius
とrange_filter
の設定に重要な影響を与えます。
例えば、L2距離の場合、検索結果はradius
よりも距離が小さいベクトルフィールドの値でフィルタリングする必要があります。なぜなら、L2距離では、より小さい距離がより大きな類似性を示すからです。この知識をもとに、最も類似するいくつかのベクトルをフィルタリングしたい場合は、range_filter
の値をradius
よりも小さい値に指定することができます。
search_params = {
"metric_type": "L2",
"params": {
"radius": 10.0,
"range_filter" : 5.0
}
}
一方で、IP距離の場合は状況が異なります。IP距離では、より大きな距離がより大きな類似性を示します。したがって、L2距離とは対照的に、IP距離におけるradius
とrange_filter
の値は逆になります。つまり、IP距離に基づいて最も類似するいくつかのベクトルをrange_filter
でフィルタリングしたい場合、有効なrange_filter
の値はradius
よりも大きい必要があり、検索されたベクトルの距離はradius
よりも大きく、かつrange_filter
以下である必要があります。
search_params = {
"metric_type": "IP",
"params": {
"radius": 0.8,
"range_filter" : 1.0
}
}
範囲検索の実行
距離測定タイプに基づいてradius
とrange_filter
を指定することで、返される結果ベクトルの範囲を定義することができます。
L2距離に基づいて、類似性の範囲が5.0
と10.0
の範囲内で範囲検索を実行します。
search_param = {
"data": [[0.1, 0.2]], # クエリベクトル
"anns_field": "book_intro", # 検索するフィールド
"param": { "metric_type": "L2", "params": { "nprobe": 10, "radius": 10.0, "range_filter" : 5.0 }, "offset": 0 },
"limit": 2,
"output_fields": ["int64", "float"] # 返されるフィールド
}
res = collection.search(**search_param)
IP距離に基づいて、類似性の範囲が1.0
と0.8
の範囲内で範囲検索を実行します。
search_param = {
"data": [[0.1, 0.2]], # クエリベクトル
"anns_field": "book_intro", # 検索するフィールド
"param": {"metric_type": "IP", "params": { "nprobe": 10, "radius": 0.8, "range_filter" : 1.0 }, "offset": 0 },
"limit": 2,
"output_fields": ["int64", "float"] # 返されるフィールド
}
res = collection.search(**search_param)
要約
Milvusでは、範囲検索によって指定された距離範囲内で類似するベクトル結果を返すことができます。この機能は、検索パラメータでradius
とrange_filter
を指定することで有効になります。以下の表は、異なる距離測定タイプにおけるこれら2つのパラメータの設定をまとめたものです。
距離測定タイプ | 設定 |
---|---|
L2およびその他の距離 | range_filter <= distance < radius |
IPおよびコサイン距離 | radius < distance <= range_filter |