RRF 融合:不同检索分数不必强行放到同一刻度
关键词检索与向量检索的分数范围不同,直接相加容易让某一路主导结果。基于名次融合可以避免直接比较原始分数。
问题从哪里出现
关键词检索与向量检索的分数范围不同,直接相加容易让某一路主导结果。基于名次融合可以避免直接比较原始分数。
理解核心机制
RRF 为每个结果累加 1/(k+rank),其中 rank 从一开始。它偏好在多份列表中排名靠前的候选,k 控制前列差异的影响。
动手做一个小实验
Python 3.11 或更新版本,仅使用标准库;将示例保存为 demo.py 后执行 python3 demo.py。数字与样本均为教学演示,不代表真实模型或服务器的测量结果。
from collections import defaultdict
rankings = [["a", "b", "c"], ["c", "b", "d"]]
scores = defaultdict(float)
for ranking in rankings:
for rank, doc in enumerate(ranking, start=1):
scores[doc] += 1 / (60 + rank)
ordered = sorted(scores, key=lambda doc: (-scores[doc], doc))
assert ordered.index("c") < ordered.index("a")
print(ordered, dict(scores))适用边界与常见误区
每路列表应先按稳定文档 ID 去重。RRF 不利用原始分数的置信信息,也不能修复两个检索器同时遗漏的证据。
继续练习
改变 k 并加入第三路结果,观察名次变化;用固定验证集比较融合前后的 Recall@k,而不是凭一个查询判断。