加权融合在做什么
混合检索会拿到两路分数:稠密向量相似度与 BM25(或稀疏向量)得分,两者量纲和分布都不同,直接相加没有意义。加权融合先做归一化(min-max 或 z-score)让两路可比,再按权重求和排序。相比只用名次融合的 RRF,它保留了分数差距信息,但权重与归一化方式都必须在带标注的查询集上调整。
基本信息
| 归一化方式 | min-max、z-score,或先统一候选池再归一化 |
|---|---|
| 权重参数 | alpha 控制两路占比,需在评测集上网格搜索 |
| 调参前提 | 固定候选池与评测集,一次只调一个变量 |
| 与 RRF 对比 | RRF 免标定但融合更粗,加权融合保留分数差异 |
典型使用场景
- 关键词与向量并存:产品型号、错误码靠关键词命中,语义问题靠向量命中
- 专用名词较多的语料:术语需要精确匹配,纯向量容易漏
- 已用 RRF 起量想继续优化:在 RRF 之上引入分数信息争取更高排序质量
- 多路检索扩展:加入第三路(如标题匹配)后需要统一打分口径
- 效果回退排查:对比融合权重调整前后的 MRR 变化,定位是哪一路变差
归一化后加权
归一化后加权
def normalize(scores):
lo, hi = min(scores), max(scores) # 用固定候选池的分数做归一化
span = (hi - lo) or 1.0 # 全等分时避免除零
return [(s - lo) / span for s in scores]
# alpha 在评测集上网格搜索,先从 0.5 附近起步
alpha = 0.6
fused = [
alpha * s_dense + (1 - alpha) * s_sparse
for s_dense, s_sparse in zip(normalize(dense_scores), normalize(sparse_scores))
]
归一化方式对比
| 方式 | 特点 | 风险 |
|---|---|---|
| min-max | 压到 0 到 1,实现简单 | 受异常值影响,单次查询上下界不稳定 |
| z-score | 按均值与方差标准化 | 分布明显偏斜时仍不理想 |
| 按名次归一化 | 只看排名,抗分布差异 | 退化成排名融合,丢掉分数信息 |
| 固定上下界 | 跨查询可比 | 需要历史数据估计边界 |
归一化与权重都要在带标注的查询集上调:先固定 top-k 候选池,再网格搜索 alpha 这类权重,避免两个变量同时变化。
上线后仍要定期复核权重:语料构成变化(如新增大量型号类文档)会让原先的 alpha 不再最优。