RRF Ranker
Reciprocal Rank Fusion (RRF) Rankerは、Zilliz Cloudハイブリッド検索のための再ランク付け戦略であり、複数のベクトル検索パスからの結果を、生の類似度スコアではなくランキング位置に基づいてバランスさせるものです。選手の統計ではなくランキングを考慮するスポーツトーナメントと同様に、RRF Rankerは各アイテムが異なる検索パスでどれほど高い順位にあるかに基づいて検索結果を組み合わせ、公平でバランスの取れた最終ランキングを作成します。
RRF Rankerの使用タイミング
RRF Rankerは、明示的な重要度ウェイトを割り当てずに複数のベクトル検索パスの結果をバランスさせたいハイブリッド検索シナリオのために特別に設計されています。特に効果的なのは:
使用例 | 例 | RRF Rankerがうまく機能する理由 |
|---|---|---|
同等の重要度を持つマルチモーダル検索 | 両方のモダリティが同等に重要な画像-テキスト検索 | 任意の重み付けを必要とせずに結果をバランスさせる |
アンサンブルベクトル検索 | 異なる埋め込みモデルからの結果を組み合わせる | 特定のモデルのスコア分布を優遇することなく民主的にランキングをマージする |
クロスリンガル検索 | 複数言語間の文書を検索する | 言語固有の埋め込み特性に関係なく結果を公平にランク付けする |
専門家による推薦 | 複数の専門家システムからの推薦を組み合わせる | 異なるシステムが比較不可能なスコアリング方法を使用する場合の合意されたランキングを作成する |
ハイブリッド検索アプリケーションで明示的な重みを割り当てることなく複数の検索パスを民主的にバランスさせる必要がある場合、RRF Rankerが最適な選択です。
RRF Rankerの仕組み
RRFRanker戦略の主なワークフローは以下の通りです:
-
検索ランキングの収集: ベクトル検索の各パスからの結果のランキングを収集します(rank_1, rank_2)。
-
ランキングのマージ: 各パスからのランキングを数式に従って変換します(rank_rrf_1, rank_rrf_2)。
計算式にはNが含まれ、これは検索数を表します。ranki(d)はi番目の検索器によって生成された文書dのランキング位置です。kは通常60に設定されるスムージングパラメータです。
-
ランキングの集約: 組み合わされたランキングに基づいて検索結果を再ランク付けし、最終結果を生成します。

RRF Rankerの例
この例は、スパース-デンスベクトル上のハイブリッド検索(topK=5)を示し、RRFRanker戦略が2つのANN検索からの結果をどのように再ランク付けするかを説明しています。
-
テキストのスパースベクトルに対するANN検索の結果(topK=5):
ID
ランク (スパース)
101
1
203
2
150
3
198
4
175
5
-
テキストのデンスベクトルに対するANN検索の結果(topK=5):
ID
ランク (デンス)
198
1
101
2
110
3
175
4
250
5
-
RRFを使用して2つの検索結果セットのランキングを並び替えます。スムージングパラメータ「k」が60に設定されていると仮定します。
ID
スコア (スパース)
スコア (デンス)
最終スコア
101
1
2
1/(60+1)+1/(60+2) = 0.01639
198
4
1
1/(60+4)+1/(60+1) = 0.01593
175
5
4
1/(60+5)+1/(60+4) = 0.01554
203
2
N/A
1/(60+2) = 0.01613
150
3
N/A
1/(60+3) = 0.01587
110
N/A
3
1/(60+3) = 0.01587
250
N/A
5
1/(60+5) = 0.01554
-
再ランク付け後の最終結果(topK=5):
ランク
ID
最終スコア
1
101
0.01639
2
203
0.01613
3
198
0.01593
4
150
0.01587
5
110
0.01587
RRF Rankerの使用法
RRF再ランク付け戦略を使用する際には、パラメータ「k」を設定する必要があります。これは、全文検索とベクトル検索の相対的重みを効果的に変更できるスムージングパラメータです。このパラメータのデフォルト値は60であり、(0, 16384)の範囲内で調整できます。値は浮動小数点数である必要があります。推奨される値は[10, 100]の間です。k=60が一般的な選択肢ではありますが、最適な「k」の値は特定のアプリケーションやデータセットによって異なります。最適なパフォーマンスを得るために、特定の使用例に基づいてこのパラメータをテストし調整することを推奨します。
RRF Rankerの作成
複数のベクトルフィールドでコレクションが設定された後、適切なスムージングパラメータでRRF Rankerを作成します:
- Python
- Java
- NodeJS
- Go
- cURL
from pymilvus import Function, FunctionType
ranker = Function(
name="rrf",
input_field_names=[], # 空のリストでなければなりません
function_type=FunctionType.RERANK,
params={
"reranker": "rrf",
"k": 100 # オプション
}
)
import io.milvus.common.clientenum.FunctionType;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
CreateCollectionReq.Function rr = CreateCollectionReq.Function.builder()
.functionType(FunctionType.RERANK)
.param("strategy", "rrf")
.param("params", "{\"k\": 100}")
.build();
import { FunctionType } from "@zilliz/milvus2-sdk-node";
const ranker = {
name: "weight",
input_field_names: [],
function_type: FunctionType.RERANK,
params: {
reranker: "weighted",
weights: [0.1, 0.9],
norm_score: true,
},
};
// Go
# Restful
パラメータ | 必須? | 説明 | 値/例 |
|---|---|---|---|
| はい | この関数の一意の識別子 |
|
| はい | 関数を適用するベクトルフィールドのリスト(RRF Rankerでは空のリストにする必要があります) | [] |
| はい | 呼び出す関数のタイプ。再ランク付け戦略を指定するには |
|
| はい | 使用する再ランク付け方法を指定します。 RRF Rankerを使用するには |
|
| いいえ | 文書ランキングの影響を制御するスムージングパラメータ。より高い 詳細については、RRF Rankerの仕組みを参照してください。 |
|
ハイブリッド検索への適用
RRF Rankerは、複数のベクトルフィールドを組み合わせるハイブリッド検索操作のために特別に設計されています。ハイブリッド検索で使用する方法は以下の通りです:
- Python
- Java
- NodeJS
- Go
- cURL
from pymilvus import MilvusClient, AnnSearchRequest
# Milvusサーバーに接続
milvus_client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT")
# コレクションのセットアップがあると仮定
# テキストベクトル検索リクエストを定義
text_search = AnnSearchRequest(
data=["modern dining table"],
anns_field="text_vector",
param={},
limit=10
)
# 画像ベクトル検索リクエストを定義
image_search = AnnSearchRequest(
data=[image_embedding], # 画像埋め込みベクトル
anns_field="image_vector",
param={},
limit=10
)
# RRF Rankerを製品ハイブリッド検索に適用
# スムージングパラメータkがバランスを制御
hybrid_results = milvus_client.hybrid_search(
collection_name,
[text_search, image_search], # 複数の検索リクエスト
ranker=ranker, # RRFランカーを適用
limit=10,
output_fields=["product_name", "price", "category"]
)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.request.AnnSearchReq;
import io.milvus.v2.service.vector.request.HybridSearchReq;
import io.milvus.v2.service.vector.response.SearchResp;
import io.milvus.v2.service.vector.request.data.EmbeddedText;
import io.milvus.v2.service.vector.request.data.FloatVec;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("YOUR_CLUSTER_ENDPOINT")
.build());
List<AnnSearchReq> searchRequests = new ArrayList<>();
searchRequests.add(AnnSearchReq.builder()
.vectorFieldName("text_vector")
.vectors(Collections.singletonList(new EmbeddedText("\"modern dining table\"")))
.limit(10)
.build());
searchRequests.add(AnnSearchReq.builder()
.vectorFieldName("image_vector")
.vectors(Collections.singletonList(new FloatVec(imageEmbedding)))
.limit(10)
.build());
HybridSearchReq hybridSearchReq = HybridSearchReq.builder()
.collectionName(COLLECTION_NAME)
.searchRequests(searchRequests)
.ranker(ranker)
.limit(10)
.outputFields(Arrays.asList("product_name", "price", "category"))
.build();
SearchResp searchResp = client.hybridSearch(hybridSearchReq);
import { MilvusClient, FunctionType } from "@zilliz/milvus2-sdk-node";
const milvusClient = new MilvusClient({ address: "YOUR_CLUSTER_ENDPOINT" });
const text_search = {
data: ["modern dining table"],
anns_field: "text_vector",
param: {},
limit: 10,
};
const image_search = {
data: [image_embedding],
anns_field: "image_vector",
param: {},
limit: 10,
};
const ranker = {
name: "weight",
input_field_names: [],
function_type: FunctionType.RERANK,
params: {
reranker: "weighted",
weights: [0.1, 0.9],
norm_score: true,
},
};
const search = await milvusClient.search({
collection_name: collection_name,
data: [text_search, image_search],
output_fields: ["product_name", "price", "category"],
limit: 10,
rerank: ranker,
});
// go
# restful
ハイブリッド検索の詳細については、マルチベクトルハイブリッド検索を参照してください。