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

RRF Ranker の例
この例では、疎ベクトルと密ベクトルに対するハイブリッド検索(topK=5)を実行し、RRF Ranker 戦略が 2 つの ANN 検索結果をどのようにリランキングするかを示します。
-
テキストの疎ベクトルに対する ANN 検索結果(topK=5):
ID
Rank (sparse)
101
1
203
2
150
3
198
4
175
5
-
テキストの密ベクトルに対する ANN 検索結果(topK=5):
ID
Rank (dense)
198
1
101
2
110
3
175
4
250
5
-
RRF を使用して 2 つの検索結果セットのランキングを再構成します。平滑化パラメータ
kは 60 に設定されていると仮定します。ID
Score (Sparse)
Score (Dense)
Final Score
101
1
2
1/(60+1)+1/(60+2) = 0.03252247
198
4
1
1/(60+4)+1/(60+1) = 0.03201844
175
5
4
1/(60+5)+1/(60+4) = 0.03100962
203
2
N/A
1/(60+2) = 0.01612903
150
3
N/A
1/(60+3) = 0.01587302
110
N/A
3
1/(60+3) = 0.01587302
250
N/A
5
1/(60+5) = 0.01538462
-
リランキング後の最終結果(topK=5):
Rank
ID
Final Score
1
101
0.03252247
2
198
0.03201844
3
175
0.03100962
4
203
0.01612903
5
150
0.01587302
5
110
0.01587302
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
rerank = Function(
name="rrf",
input_field_names=[], # Must be an empty list
function_type=FunctionType.RERANK,
params={
"reranker": "rrf",
"k": 100 # Optional
}
)
import io.milvus.common.clientenum.FunctionType;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
CreateCollectionReq.Function rerank = CreateCollectionReq.Function.builder()
.name("rrf")
.functionType(FunctionType.RERANK)
.param("reranker", "rrf")
.param("k", "100")
.build();
import { FunctionType } from "@zilliz/milvus2-sdk-node";
const rerank = {
name: "rrf",
input_field_names: [],
function_type: FunctionType.RERANK,
params: {
reranker: "rrf",
k: 100,
},
};
// Go
# Restful
パラメータ | 必須? | 説明 | 値/例 |
|---|---|---|---|
| はい | このFunctionの一意な識別子 |
|
| はい | この関数を適用するベクトルフィールドのリスト(RRF Rankerの場合は空にする必要があります) | [] |
| はい | 呼び出すFunctionのタイプ。再ランキング戦略を指定するには |
|
| はい | 使用する再ランキング手法を指定します。 RRF Rankerを使用するには、 |
|
| いいえ | ドキュメントの順位への影響を制御するスムージングパラメータ。高い 詳細については、RRF Rankerの仕組みを参照してください。 |
|
ハイブリッド検索への適用
RRF Rankerは、複数のベクトルフィールドを組み合わせたハイブリッド検索操作のために特別に設計されています。以下はハイブリッド検索でこれを使用する方法です:
- Python
- Java
- NodeJS
- Go
- cURL
from pymilvus import MilvusClient, AnnSearchRequest
# Connect to Milvus server
milvus_client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT")
# Assume you have a collection setup
# Define text vector search request
text_search = AnnSearchRequest(
data=["modern dining table"],
anns_field="text_vector",
param={},
limit=10
)
# Define image vector search request
image_search = AnnSearchRequest(
data=[image_embedding], # Image embedding vector
anns_field="image_vector",
param={},
limit=10
)
# Apply RRF Ranker to product hybrid search
# The smoothing parameter k controls the balance
hybrid_results = milvus_client.hybrid_search(
collection_name,
[text_search, image_search], # Multiple search requests
ranker=rerank, # Apply the RRF ranker
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(rerank)
.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 search = await milvusClient.search({
collection_name: collection_name,
data: [text_search, image_search],
output_fields: ["product_name", "price", "category"],
limit: 10,
rerank: rerank,
});
// go
# restful
ハイブリッド検索の詳細については、マルチベクターハイブリッド検索を参照してください。