メインコンテンツまでスキップ

Grouping Search

Grouping Search を使用すると、Zilliz Cloud は検索結果を指定されたフィールドの値ごとにグループ化し、より高いレベルでデータを集約できます。たとえば、基本的な ANN 検索を使用して手元の本に似た本を見つけることはできますが、Grouping Search を使用すると、その本で議論されているトピックに関連する可能性のある本のカテゴリを見つけることができます。このトピックでは、主な考慮事項とあわせて Grouping Search の使用方法について説明します。

概要​

検索結果内のエンティティがスカラーフィールドで同じ値を共有している場合、それらが特定の属性において類似していることを示しており、検索結果に悪影響を与える可能性があります。

あるコレクションに複数のドキュメント(docId で示す)が保存されているとします。ドキュメントをベクトルに変換する際にできるだけ多くの意味情報を保持するため、各ドキュメントはより小さく扱いやすい段落(または chunks)に分割され、個別のエンティティとして保存されます。ドキュメントがより小さなセクションに分割されていても、ユーザーは多くの場合、どのドキュメントが自分のニーズに最も関連しているかを特定したいと考えています。

LhJEwzWiphLWxobMaiCcbVDPnNb

このようなコレクションに対して近似最近傍(ANN)検索を実行すると、検索結果に同じドキュメントの複数の段落が含まれることがあり、その結果、他のドキュメントが見落とされる可能性があり、意図したユースケースに沿わないことがあります。

Ktj8wigrHhvz4nbDES5coKZJnZe

検索結果の多様性を向上させるには、検索リクエストに group_by_field パラメーターを追加して Grouping Search を有効にできます。図に示すように、group_by_field を docId に設定できます。このリクエストを受信すると、Zilliz Cloud は次の処理を行います。

  • 指定されたクエリベクトルに基づいて ANN 検索を実行し、クエリに最も類似したすべてのエンティティを見つけます。

  • 検索結果を、指定された group_by_field(たとえば docId)でグループ化します。

  • limit パラメーターで定義された各グループの上位結果を、各グループで最も類似したエンティティとともに返します。

Notes

デフォルトでは、Grouping Search は各グループにつき 1 つのエンティティのみを返します。グループごとに返す結果の数を増やしたい場合は、group_size と strict_group_size パラメーターで制御できます。

このセクションでは、Grouping Search の使用方法を示すサンプルコードを提供します。次の例では、コレクションに id、vector、chunk、docId の各フィールドが含まれていることを前提としています。

plaintext
[
{"id": 0, "vector": [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592], "chunk": "pink_8682", "docId": 1},
{"id": 1, "vector": [0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501, 0.838729485096104], "chunk": "red_7025", "docId": 5},
{"id": 2, "vector": [0.43742130801983836, -0.5597502546264526, 0.6457887650909682, 0.7894058910881185, 0.20785793220625592], "chunk": "orange_6781", "docId": 2},
{"id": 3, "vector": [0.3172005263489739, 0.9719044792798428, -0.36981146090600725, -0.4860894583077995, 0.95791889146345], "chunk": "pink_9298", "docId": 3},
{"id": 4, "vector": [0.4452349528804562, -0.8757026943054742, 0.8220779437047674, 0.46406290649483184, 0.30337481143159106], "chunk": "red_4794", "docId": 3},
{"id": 5, "vector": [0.985825131989184, -0.8144651566660419, 0.6299267002202009, 0.1206906911183383, -0.1446277761879955], "chunk": "yellow_4222", "docId": 4},
{"id": 6, "vector": [0.8371977790571115, -0.015764369584852833, -0.31062937026679327, -0.562666951622192, -0.8984947637863987], "chunk": "red_9392", "docId": 1},
{"id": 7, "vector": [-0.33445148015177995, -0.2567135004164067, 0.8987539745369246, 0.9402995886420709, 0.5378064918413052], "chunk": "grey_8510", "docId": 2},
{"id": 8, "vector": [0.39524717779832685, 0.4000257286739164, -0.5890507376891594, -0.8650502298996872, -0.6140360785406336], "chunk": "white_9381", "docId": 5},
{"id": 9, "vector": [0.5718280481994695, 0.24070317428066512, -0.3737913482606834, -0.06726932177492717, -0.6980531615588608], "chunk": "purple_4976", "docId": 3},
]

検索リクエストでは、group_by_field と output_fields の両方を docId に設定します。Zilliz Cloud は結果を指定されたフィールドでグループ化し、各グループで最も類似したエンティティを、返される各エンティティの docId の値を含めて返します。

python
from pymilvus import MilvusClient

client = MilvusClient(
uri="YOUR_CLUSTER_ENDPOINT",
token="YOUR_CLUSTER_TOKEN"
)

query_vectors = [
[0.14529211512077012, 0.9147257273453546, 0.7965055218724449, 0.7009258593102812, 0.5605206522382088]]

# Group search results
res = client.search(
collection_name="my_collection",
data=query_vectors,
limit=3,
group_by_field="docId",
output_fields=["docId"]
)

# Retrieve the values in the `docId` column
doc_ids = [result['entity']['docId'] for result in res[0]]

上記のリクエストでは、limit=3 は、システムが 3 つのグループから検索結果を返し、各グループにクエリベクトルに最も類似した 1 つのエンティティが含まれることを示します。

グループサイズを設定する​

デフォルトでは、Grouping Search は各グループにつき 1 つのエンティティのみを返します。グループごとに複数の結果が必要な場合は、group_size と strict_group_size パラメーターを調整します。

python
# Group search results

res = client.search(
collection_name="my_collection",
data=query_vectors, # query vector
limit=5, # number of groups to return
group_by_field="docId", # grouping field
group_size=2, # p to 2 entities to return from each group
strict_group_size=True, # return exact 2 entities from each group
output_fields=["docId"]
)

上記の例では:

  • group_size: グループごとに返すエンティティ数を指定します。たとえば、group_size=2 に設定すると、各グループ(または各 docId)は理想的には最も類似した 2 つの段落(または chunks)を返す必要があります。group_size が設定されていない場合、システムはデフォルトでグループごとに 1 件の結果を返します。

  • strict_group_size: このブール値のパラメーターは、システムが group_size で設定された件数を厳密に適用するかどうかを制御します。strict_group_size=True の場合、システムは、そのグループに十分なデータがない場合を除き、各グループに group_size で指定された正確な数のエンティティ(たとえば 2 つの段落)を含めようとします。デフォルト(strict_group_size=False)では、システムは各グループに group_size 個のエンティティが含まれることを保証するよりも、limit パラメーターで指定されたグループ数を満たすことを優先します。このアプローチは、データ分布が不均一な場合に一般的により効率的です。

追加のパラメーターの詳細については、search を参照してください。

スカラーフィールドでグループを並べ替える | ONDEMAND​

Grouping Search を order_by_fields と組み合わせることで、スカラーフィールドによってグループを並べ替えることができます。これは、グループ間で多様な結果を得たい一方で、価格や評価のようなビジネス上重要な順序に従ってグループを並べ替えたい場合に役立ちます。

次の例では、検索結果を category でグループ化し、各グループにつき最大 3 つのエンティティを返し、返されたグループを price の低い順に並べ替えます。

python
res = client.search(
collection_name="product_catalog",
data=query_vectors,
anns_field="embedding",
limit=20,
group_by_field="category",
group_size=3,
strict_group_size=True,
output_fields=["category", "price", "rating"],
order_by_fields=[
{"field": "price", "order": "asc"}
],
)

上記のリクエストでは、limit=20 は、Zilliz Cloud が最大 20 個のグループを選択することを意味し、20 個のエンティティを選択することを意味するものではありません。group_size=3 であるため、フラットな結果リストには合計で最大 60 個のエンティティを含めることができます。

group_by_field とあわせて order_by_fields を使用すると、Zilliz Cloud は各グループの先頭エンティティの指定されたスカラーフィールド値に基づいてグループを並べ替えます。各グループ内では、エンティティはクエリベクトルに対する類似度スコアの順に保たれます。

考慮事項​

  • グループ数: limit パラメーターは、各グループ内の具体的なエンティティ数ではなく、検索結果が返されるグループ数を制御します。適切な limit を設定すると、検索の多様性とクエリのパフォーマンスを制御しやすくなります。データが密に分布している場合やパフォーマンスが懸念される場合は、limit を減らすことで計算コストを削減できます。

  • グループあたりのエンティティ数: group_size パラメーターは、グループごとに返されるエンティティ数を制御します。ユースケースに応じて group_size を調整すると、検索結果の豊富さを高めることができます。ただし、データが不均一に分布している場合、特にデータが限られているシナリオでは、一部のグループが group_size で指定された数よりも少ないエンティティしか返さないことがあります。

  • 厳密なグループサイズ: strict_group_size=True の場合、システムは、そのグループに十分なデータがない場合を除き、各グループに対して指定された数のエンティティ(group_size)を返そうとします。この設定により、グループごとのエンティティ数を一定に保つことができますが、データ分布が不均一な場合やリソースが限られている場合はパフォーマンスが低下する可能性があります。厳密なエンティティ数が必要ない場合は、strict_group_size=False に設定するとクエリ速度を向上させることができます。

  • クエリベクトルが対象のコレクションにすでに存在する場合は、検索前にそれらを取得する代わりに ids を使用することを検討してください。詳細については、Primary-Key Search を参照してください。