Skip to content

NDCG 归一化折损累计增益

五层读懂一个词。这次拆的是:NDCG (Normalized Discounted Cumulative Gain)--考虑排序位置和分级相关性的综合指标,搜索引擎排序评估的事实标准。


L1 · 一句话点破

NDCG@K = 实际排序的 DCG / 理想排序的 DCG。DCG 把每个位置的相关性按 $1/\log_2(\text{rank}+1)$ 折损累加,NDCG 归一化到 [0, 1]。考虑排序位置(top 重)和分级相关性(高度相关 vs 一般相关),是排序质量评估的金标准。


L2 · 通俗类比

继续用考试比喻,但这次答案有"质量分":

  • 高度相关答案 = 3 分
  • 一般相关答案 = 1 分
  • 不相关 = 0 分

学生答 5 题(top-5),老师评分:

学生 A 的答案(高度相关排前):

  • 第 1 名:3 分(高度相关)
  • 第 2 名:3 分(高度相关)
  • 第 3 名:1 分(一般)
  • 第 4 名:0 分
  • 第 5 名:0 分

学生 B 的答案(高度相关排后):

  • 第 1 名:1 分(一般)
  • 第 2 名:0 分
  • 第 3 名:3 分(高度相关)
  • 第 4 名:3 分(高度相关)
  • 第 5 名:0 分

谁更好? 直觉是 A(高度相关排前)。但简单累加分数都是 7 分,区分不出。

DCG 的做法:位置折损。第 1 名权重 1,第 2 名权重 $1/\log_2 3 \approx 0.63$,第 3 名 $1/\log_2 4 = 0.5$,...

  • 学生 A DCG = 3×1 + 3×0.63 + 1×0.5 + 0 + 0 = 5.39
  • 学生 B DCG = 1×1 + 0 + 3×0.5 + 3×0.43 + 0 = 3.79

A 的 DCG 高,符合直觉。

NDCG 的做法:除以理想 DCG(高度相关全排前),归一化到 [0, 1]。

  • 理想 DCG = 3×1 + 3×0.63 + 1×0.5 + 0 + 0 = 5.39(高度相关排前 2,一般排第 3)
  • 学生 A NDCG = 5.39 / 5.39 = 1.0(完美)
  • 学生 B NDCG = 3.79 / 5.39 = 0.70

NDCG 综合考虑了位置(top 重)和相关性分级(高度 vs 一般),是排序评估最全面的指标。


L3 · 正经定义

NDCG (Normalized Discounted Cumulative Gain)

步骤 1:CG (Cumulative Gain)

$$ \text{CG@K} = \sum_{i=1}^{K} \text{rel}_i $$

$\text{rel}_i$ 是位置 $i$ 文档的相关性等级(如 0/1/2/3)。

步骤 2:DCG (Discounted Cumulative Gain)

$$ \text{DCG@K} = \sum_{i=1}^{K} \frac{\text{rel}_i}{\log_2(i+1)} $$

位置折损:第 1 名权重 1,第 $i$ 名权重 $1/\log_2(i+1)$。

变体 DCG(工业常用,强调高相关性):

$$ \text{DCG@K} = \sum_{i=1}^{K} \frac{2^{\text{rel}_i} - 1}{\log_2(i+1)} $$

$2^{\text{rel}_i} - 1$ 让高相关性(rel=3)贡献远大于低相关性(rel=1)。

步骤 3:IDCG (Ideal DCG)

理想排序(相关性从高到低排列)的 DCG:

$$ \text{IDCG@K} = \sum_{i=1}^{K} \frac{2^{\text{rel}_i^{\text{sorted}}} - 1}{\log_2(i+1)} $$

$\text{rel}^{\text{sorted}}$ 是相关性按降序排列。

步骤 4:NDCG

$$ \text{NDCG@K} = \frac{\text{DCG@K}}{\text{IDCG@K}} $$

归一化到 [0, 1],1.0 表示完美排序。

多查询平均

$$ \text{NDCG@K} = \frac{1}{|Q|} \sum_{q \in Q} \text{NDCG@K}(q) $$

伪代码

python
import math

def dcg_at_k(relevances, k):
    """relevances: list of relevance scores, 已按检索排序"""
    dcg = 0.0
    for i, rel in enumerate(relevances[:k], start=1):
        dcg += (2 ** rel - 1) / math.log2(i + 1)
    return dcg

def ndcg_at_k(retrieved_relevances, k):
    """
    retrieved_relevances: list of relevance scores, 按检索排序
    """
    dcg = dcg_at_k(retrieved_relevances, k)
    idcg = dcg_at_k(sorted(retrieved_relevances, reverse=True), k)
    return dcg / idcg if idcg > 0 else 0.0

# 示例
# 检索返回 5 个文档,相关性 [3, 3, 1, 0, 0](高度相关排前)
relevances = [3, 3, 1, 0, 0]
print(ndcg_at_k(relevances, k=5))  # 1.0(完美排序)

# 相关性 [1, 0, 3, 3, 0](高度相关排后)
relevances = [1, 0, 3, 3, 0]
print(ndcg_at_k(relevances, k=5))  # ~0.70(高度相关排后,NDCG 低)

L4 · 原理深挖

4.1 为什么需要 NDCG

Hit Rate / Recall / Precision 的局限

  • 只考虑"是否相关"(二元)
  • 不考虑相关性分级(高度相关 vs 一般相关)
  • 不考虑排序位置(top-1 和 top-10 同等对待)

MRR 的局限

  • 只看第一个相关文档
  • 不考虑后续排序
  • 二元相关性

NDCG 的优势

  • 分级相关性:rel=0/1/2/3,区分高度相关和一般相关
  • 位置折损:top 位置权重高,长尾权重低
  • 全排序:考虑 top-K 内所有相关文档的位置
  • 归一化:跨查询可比

4.2 位置折损函数:为什么用 $1/\log_2(\text{rank}+1)$

折损函数的选择

位置$1/\log_2(\text{rank}+1)$$1/\text{rank}$$1/\text{rank}^2$
11.01.01.0
20.630.50.25
50.390.20.04
100.300.10.01

$1/\log_2(\text{rank}+1)$ 的特性

  • 衰减适中:top 重但长尾不忽略
  • 对数衰减:符合用户注意力衰减(研究表明用户注意力对数衰减)
  • 第 1 名和第 2 名差异适中(1.0 vs 0.63)

对比 $1/\text{rank}$(MRR 用):

  • 衰减更快:第 10 名 0.1(vs DCG 的 0.30)
  • top 主导更强

对比 $1/\text{rank}^2$

  • 衰减极快:第 10 名 0.01
  • 几乎只看 top-3

实践:DCG 的对数折损是经验最优,兼顾 top 重和长尾贡献。

4.3 相关性分级:为什么用 $2^{\text{rel}} - 1$

原始 DCG:直接用 $\text{rel}$(如 0/1/2/3)

变体 DCG:用 $2^{\text{rel}} - 1$

rel原始$2^{\text{rel}} - 1$
000
111
223
337

$2^{\text{rel}} - 1$ 的优势

  • 高相关性贡献指数增长(rel=3 贡献 7,远超 rel=1 的 1)
  • 鼓励把高度相关排 top(top 位置高权重 × 高相关性高分)

实践:工业搜索引擎(Google、Bing)用变体 DCG($2^{\text{rel}} - 1$),学术评估两者都有。

4.4 NDCG 的归一化

为什么要归一化

  • 不同查询的相关文档数量不同
  • DCG 绝对值跨查询不可比
  • 归一化到 [0, 1] 后跨查询可比

IDCG 的计算

  • 把相关性按降序排列
  • 计算 DCG

边界情况

  • 无相关文档:IDCG = 0,NDCG = 0/0,通常记为 0
  • 单相关文档:IDCG = DCG(如果排第 1),NDCG = 1.0

4.5 NDCG@K 的 K 选择

K 的选择与场景

场景K原因
网页搜索10用户看 top-10
移动搜索5屏幕小
电商搜索20用户浏览多
RAG5~10LLM context 限制
推荐系统10~50用户浏览深度

NDCG@10 是搜索引擎最常用,对应用户看首页的体验。

4.6 NDCG 与其他指标的对比

指标分级相关位置折损全排序归一化适用
Hit Rate@K否(二元)RAG
Recall@K召回
Precision@K精确
MRR@K是(1/rank)否(只第一)问答
MAP是(隐式)多相关
NDCG@K综合排序

NDCG 是最全面的指标:分级 + 位置 + 全排序 + 归一化。

4.7 NDCG 的局限

局限 1:依赖相关性分级标注

需要人工标注分级相关性(0/1/2/3),成本高。二元标注时 NDCG 退化为类似 DCG。

局限 2:对标注噪声敏感

分级标注主观,不同标注者可能给不同等级。需多标注者投票。

局限 3:IDCG 计算需所有相关文档

如果只标了 top-K 内的相关性,IDCG 可能低估(漏标的相关文档未计入理想排序)。

局限 4:不区分"几乎相关"和"完全不相关"

rel=0 的文档无论排第几都不贡献,但用户看到"几乎相关"和"完全不相关"的 rel=0 体验不同。

局限 5:跨查询平均的 bias

简单平均 NDCG 可能偏向相关文档少的查询(容易得高 NDCG)。可加权平均。

4.8 NDCG 在工业中的应用

搜索引擎

  • Google、Bing、百度都用 NDCG@10 评估排序质量
  • 人工标注分级相关性
  • A/B 测试看 NDCG 变化

推荐系统

  • 用 NDCG@10 / NDCG@50 评估推荐排序
  • 相关性 = 用户行为(点击、购买、停留)

电商搜索

  • NDCG@20 评估商品排序
  • 相关性 = 购买转化率

RAG

  • 辅助指标(非主指标)
  • 评估 chunk 排序质量
  • 主指标仍是 Hit Rate@K

4.9 NDCG 的计算优化

增量计算

DCG 可增量更新(新文档加入时只算新位置)。适合在线评估。

近似计算

大规模评估时,可只算 top-K 的 DCG(忽略长尾),加速。

缓存 IDCG

IDCG 只依赖相关性分布,可预计算缓存。


L5 · 沿革与坑

5.1 历史脉络

  • 2000sJärvelin & Kekäläinen 2002 提出 NDCG
  • 2000s:TREC 评测采用 NDCG
  • 2010s:Yahoo Learning to Rank Challenge、Yandex 用 NDCG 评估
  • 2010s:搜索引擎工业标准(Google、Bing)
  • 2020+:推荐系统、RAG 也用 NDCG 评估排序

5.2 使用常见坑

坑 1:用二元相关性

rel 只用 0/1,NDCG 退化为类似 DCG,丢失分级信息。要标注 0/1/2/3 分级。

坑 2:标注不全

只标 top-K 内相关性,IDCG 低估(漏标的相关文档未计入理想排序)。要标全所有可能相关文档。

坑 3:标注噪声

分级标注主观,需多标注者投票。单标注者 NDCG 方差大。

坑 4:K 选错

NDCG@1000 让长尾贡献稀释 top,NDCG@1 太严格。搜索引擎用 NDCG@10。

坑 5:跨查询简单平均

相关文档少的查询容易高 NDCG,简单平均偏向这类查询。可按相关文档数加权。

坑 6:评估集太小

100 query 的 NDCG 方差大。建议至少 500 query。

坑 7:用 NDCG 评估 RAG

RAG 关心 top-k 是否含答案(Hit Rate@K),不关心排序质量(LLM 能从 top-k 中找)。NDCG 是辅助指标。

坑 8:忘了归一化

报告 DCG 而非 NDCG,跨查询不可比。要用 NDCG。

坑 9:IDCG=0 时除零

无相关文档时 IDCG=0,NDCG=0/0。要特殊处理(通常记 0)。

坑 10:相关性定义不一致

不同标注者对"高度相关"定义不同。要制定标注规范,多标注者投票。

5.3 NDCG 的变体

Alpha-NDCG

评估排序的多样性(novelty)。每个文档有主题,重复主题折扣。

Intent-Aware NDCG

多意图查询,每意图分别算 NDCG 后平均。

NDCG with Click Feedback

用点击数据估计相关性,降低人工标注成本。但有位置偏置。

5.4 NDCG 提升策略

提升 NDCG@10 的方法

  1. 更好排序模型:Cross-encoder / LTR 精排
  2. 分级相关性训练:用分级标注训练,而非二元
  3. 难负样本训练:区分"几乎相关"和"一般相关"
  4. 个性化:用户偏好让高度相关排前
  5. 多样性重排:避免 top-10 都是相似结果

典型提升幅度

  • 单 BM25:NDCG@10 ≈ 0.40
  • 单 Dense:NDCG@10 ≈ 0.50
  • 混合检索:NDCG@10 ≈ 0.55
  • 混合 + 精排:NDCG@10 ≈ 0.65
  • 混合 + LTR:NDCG@10 ≈ 0.70

5.5 NDCG vs MAP vs MRR

指标分级位置全排序适用
NDCG@K综合排序
MAP是(隐式)多相关二元
MRR@K问答单答案

选择建议

  • 分级相关性 + 综合排序:NDCG@K
  • 二元相关性 + 多相关:MAP
  • 单答案 + 位置:MRR@K
  • RAG:Hit Rate@K

速记卡

维度NDCG
公式DCG / IDCG
DCG$\sum (2^{\text{rel}_i} - 1) / \log_2(i+1)$
IDCG理想排序的 DCG
范围[0, 1]
分级相关性是(0/1/2/3)
位置折损$1/\log_2(\text{rank}+1)$
全排序
归一化
适用综合排序评估

与其他指标对比

指标分级位置全排序归一化
Hit Rate@K
MRR@K
MAP
NDCG@K

位置折损数值

位置$1/\log_2(\text{rank}+1)$
11.0
20.63
50.39
100.30

一句话记忆:NDCG = DCG / IDCG,DCG 用 $1/\log_2(\text{rank}+1)$ 折损累加分级相关性,归一化到 [0, 1]。考虑位置(top 重)和分级(高度 vs 一般),是排序评估的金标准。搜索引擎用 NDCG@10,RAG 用 Hit Rate@K。


上一篇:MRR 平均倒数排名 -- 关心第一个相关文档位置。下一篇:知识库 Knowledge Base -- RAG 的知识存储与管理。

内容采用 CC BY-SA 4.0,代码采用 MIT。