DCG, NDCG
Normalized Discounted Cumulative Gain(归一化折损累计增益)
NDCG用作排序结果的评价指标,评价排序的准确性。
推荐系统通常为某用户返回一个item列表,假设列表长度为K,这时可以用NDCG@K评价该排序列表与用户真实交互列表的差距。
解释:
- Gain: 表示列表中每一个item的相关性分数
Gain = r(i)
- Cumulative Gain:表示对K个item的Gain进行累加
CG@K = \sum_i^K{r(i)}
- Discounted Cumulative Gain:考虑排序顺序的因素,使得排名靠前的item增益更高,对排名靠后的item进行折损。
DCG = \sum_i^k{\frac{r(i)}{log_2(i+1)}}
- Normalized Discounted Cumulative Gain:DCG能够对一个用户的推荐列表进行评价,如果用该指标评价某个推荐算法,需要对所有用户的推荐列表进行评价,而不同用户之间的DCG相比没有意义(不同用户兴趣不同,对同样的item排名前后不同)。所以要对不同用户的指标进行归一化,自然的想法就是对每个用户计算一个理想情况(或者说是实际情况)下的DCG分数,用IDCG表示,然后用每个用户的DCG与IDCG之比作为每个用户归一化后的分值,最后对每个用户取平均得到最终的分值,即NDCG。
NDCG_u@K = \frac{DCG_u@K}{IDCG_u}
NDCG@K = \frac{NDCG_u@K}{|u|}
代码实现
import numpy as np
def getDCG(scores):
return np.sum(
np.divide(np.power(2, scores) - 1, np.log(np.arange(scores.shape[0], dtype=np.float32) + 2)),
dtype=np.float32)
def getNDCG(rank_list, pos_items):
relevance = np.ones_like(pos_items)
it2rel = {it: r for it, r in zip(pos_items, relevance)}
rank_scores = np.asarray([it2rel.get(it, 0.0) for it in rank_list], dtype=np.float32)
idcg = getDCG(np.sort(relevance)[::-1])
dcg = getDCG(rank_scores)
if dcg == 0.0:
return 0.0
ndcg = dcg / idcg
return ndcg
l1 = [1, 4, 5]
l2 = [1, 2, 3]
a = getNDCG(l1, l2)
print(a)
# 0.4692787
原文链接 https://zhuanlan.zhihu.com/p/84206752