RRFランカー
RRF(Reciprocal Rank Fusion)Rankerは、Milvusハイブリッド検索のための再順位付け戦略で、複数のベクトル検索パスからの結果を、生の類似度スコアではなく、順位に基づいてバランスさせます。スポーツのトーナメントが個々の統計ではなく選手のランキングを考慮するように、RRF Rankerは異なる検索パスにおける各項目のランキングの高さに基づいて検索結果を組み合わせ、公平でバランスの取れた最終ランキングを作成します。
RRF Rankerの使用時期
RRF Rankerは、明示的な重要度ウェイトを割り当てずに、複数のベクトル検索パスからの結果をバランスさせたいハイブリッド検索シナリオのために特別に設計されています。特に次のような場合に効果的です:
使用例 |
使用例 |
RRF ランカーが有効な理由 |
|---|---|---|
重要度が等しいマルチモーダル検索 |
両方のモダリティが等しく重要な画像-テキスト検索 |
任意の重み割り当てを必要とせず、結果のバランスをとる |
アンサンブルベクトル検索 |
異なる埋め込みモデルの結果を組み合わせる |
特定のモデルのスコア分布を優先することなく、民主的にランキングを統合 |
クロスリンガル検索 |
複数の言語にまたがる文書を検索 |
言語固有の埋め込み特性に関係なく、結果を公平にランク付け |
専門家の推奨 |
複数の専門家システムからの推薦を統合 |
異なるシステムが比較不可能なスコアリング方法を使用している場合、コンセンサスランキングを作成します。 |
もし、あなたのハイブリッド検索アプリケーションが、明示的な重み付けをすることなく、民主的に複数の検索パスのバランスを取る必要がある場合、RRF Rankerは理想的な選択です。
RRF Rankerのメカニズム
RRFRanker戦略の主なワークフローは以下の通りです:
検索順位を収集する:ベクトル検索の各パスの結果のランキングを収集する(rank_1、rank_2)。
順位をマージする:各パスの順位(rank_rrf_1, rank_rrf_2)を計算式に従って変換する。
ranki(d)はi(番目の)検索によって生成された文書dのランキング位置である。
ランキングの集約:最終的な検索結果を得るために、検索結果のランキングを再集計する。
RRFランカー
RRFランカーの例
この例では、疎な密なベクトルに対するハイブリッド検索(topK=5)を示し、RRFRankerストラテジーが2つのANN検索の結果をどのようにランク付けし直すかを説明する。
疎なテキストベクトルに対するANN検索結果(topK=5)::::(topK=5
ID
ランク(スパース)
101
1
203
2
150
3
198
4
175
5
テキストの密なベクトルに対するANN検索の結果(topK=5):ID
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.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
該当なし
1/(60+2) = 0.01612903
150
3
N/A
1/(60+3) = 0.01587302
110
該当なし
3
1/(60+3) = 0.01587302
250
該当なし
5
1/(60+5) = 0.01538462
再ランク付け後の最終結果(topK=5):順位
順位
順位
最終スコア
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 ランカーの使用法
RRFリランキング戦略を使用する場合、パラメータk を設定する必要がある。これはスムージング・パラメータで、全文検索とベクトル検索の相対的な重みを効果的に変えることができる。このパラメータのデフォルト値は60で、(0, 16384)の範囲で調整することができる。値は浮動小数点数でなければならない。推奨値は[10, 100]の間である。k=60 は一般的な選択ですが、最適なk の値は、特定のアプリケーションやデータセットによって異なります。最高のパフォーマンスを達成するために、特定のユースケースに基づいてこのパラメータをテストし、調整することをお勧めします。
RRF ランカーの作成
コレクションが複数のベクトルフィールドでセットアップされたら、適切なスムージングパラメータで RRF ランカーを作成します:
Milvus 2.6.x以降では、Function APIを介して直接リランキング戦略を設定することができます。それ以前のリリース(v2.6.0以前)を使用している場合は、Rerankingのドキュメントを参照して設定を行ってください。
from pymilvus import Function, FunctionType
ranker = 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 ranker = {
name: "weight",
input_field_names: [],
function_type: FunctionType.RERANK,
params: {
reranker: "weighted",
weights: [0.1, 0.9],
norm_score: true,
},
};
// Go
# Restful
パラメータ |
必須か? |
説明 |
値/例 |
|---|---|---|---|
|
はい |
このファンクションの一意な識別子 |
|
|
はい |
関数を適用するベクトルフィールドのリスト(RRFランカーの場合は空でなければならない) |
[] |
|
はい |
呼び出すFunctionのタイプ。リランキング戦略を指定するには |
|
|
はい |
使用するリランキング法を指定する。 RRF ランカーを使用するには、 |
|
|
いいえ |
文書ランクの影響を制御するスムージングパラメータ。 詳細はRRF Rankerのメカニズムを参照。 |
|
ハイブリッド検索への適用
RRF Rankerは複数のベクトル場を組み合わせたハイブリッド検索操作に特化して設計されています。ハイブリッド検索での使い方を紹介しよう:
from pymilvus import MilvusClient, AnnSearchRequest
# Connect to Milvus server
milvus_client = MilvusClient(uri="http://localhost:19530")
# 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=ranker, # 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("http://localhost:19530")
.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: "http://localhost:19530" });
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
ハイブリッド検索の詳細については、マルチベクター・ハイブリッド検索を参照してください。