两个指标各看什么
MRR(平均倒数排名)只看首个相关结果排在第几位,适合答案是唯一片段的问答场景;NDCG 引入位置折损与相关度分级,更适合多个相关文档、重要程度不同的排序评估。两个指标一起看最稳妥:MRR 反映第一个正确答案有多靠前,NDCG 反映整份排序的质量与分级合理性。
基本信息
| MRR | 首个相关结果名次的倒数取平均,1.0 为理论最好 |
|---|---|
| NDCG@k | 按位置折损累加相关度并归一化,取值 0 到 1 |
| 相关度分级 | 需人工标注等级,如 2 表示直接回答、1 表示部分相关 |
| 使用建议 | 问答看 MRR,多片段排序看 NDCG,报告里同时给出 |
典型使用场景
- 检索调参:调 nprobe 或融合权重后,看 MRR 是否上升
- 重排验证:重排上线后 NDCG 提升说明排序更合理
- 回归门禁:两项指标同时不低于基线,才允许发布
- 方案对比:混合检索与纯向量检索在同一评测集上比排序质量
- 问题定位:召回够但 MRR 低,说明正确片段被挤在后面,需要看重排
MRR 与 NDCG 计算
MRR 与 NDCG 计算
import math
def mrr(runs):
total = 0.0
for ranked in runs: # 每次查询的排序列表
for i, rel in enumerate(ranked, start=1):
if rel:
total += 1 / i # 只取首个相关结果
break
return total / len(runs)
def ndcg_at_k(ranked_relevances, k):
dcg = sum(r / math.log2(i + 1) for i, r in enumerate(ranked_relevances[:k], start=1))
ideal = sorted(ranked_relevances, reverse=True)[:k]
idcg = sum(r / math.log2(i + 1) for i, r in enumerate(ideal, start=1))
return dcg / idcg if idcg else 0.0 # 归一化后可跨查询比较
指标对照
| 指标 | 关注点 | 何时优先 |
|---|---|---|
| MRR | 首个相关结果的位置 | 单一答案的问答场景 |
| NDCG@k | 整体排序质量与相关度分级 | 多片段、相关度有分级的场景 |
| Recall@k | 是否被召回,不考虑位置 | 检索阶段的覆盖体检 |
| P95 延迟 | 性能约束 | 体验与容量规划 |
NDCG 需要相关度等级(如 2 表示直接回答、1 表示部分相关):标注成本换来的是排序灵敏度,标注口径要写进文档并固定下来。
指标口径变化会让历史数据失去可比性:分级标准或 k 值调整后要重跑基线,不能直接把新旧数字放在一起比较,否则会把口径差异误读成效果变化。
报告里附上指标置信区间或样本量:小评测集上的一次提升可能只是抽样波动,给出样本规模能让评审者判断差异是否值得采纳。