当前位置:网站首页>评估指标及代码实现(NDCG)
评估指标及代码实现(NDCG)
2022-06-22 19:27:00 【Weiyaner】
针对排序常用的评估指标,给出其计算原理及代码实现
排序评估指标
NDCG
1 原理
NDCG全称为 Normalized Discounted Cumulative Gain(归一化折损累计增益),通常用在搜索排序任务中,在这样的任务里,通常会返回一个list作为搜索排序的结果进行输出,为了验证这个list的合理性,就需要对这个list的排序进行评价。这也是NDCG的由来。
Gain: G,增益。
在排序list中,增益指的就是里面的相关性得分,也就是模型的预测结果。rel(i)表示item(i)相关性得分。
Culumatative Gain:CG,累计增益。
对k个rel(i)进行叠加,不考虑位置关系。
C G k = ∑ i = 1 k r e l ( i ) CG_k=\sum_{i=1}^krel(i) CGk=i=1∑krel(i)Discounted Cumulative Gain: DCG,折损累计增益。
考虑排序顺序的因素,使得排名靠前的item增益更高,对排名靠后的item进行折损。DCG认为排在前面的贡献度更大,后面的贡献度较小,也就是对增益值进行加权求和,权重就是位置引起的。
D C G k = ∑ i = 1 k r e l ( i ) l o g 2 ( i + 1 ) DCG_k=\sum_{i=1}^k\frac{rel(i)}{log_2(i+1)} DCGk=i=1∑klog2(i+1)rel(i)
或者:
D C G k = ∑ i = 1 k 2 r e l ( i ) + 1 l o g 2 ( i + 1 ) DCG_k=\sum_{i=1}^k\frac{2^{rel(i)}+1}{log_2(i+1)} DCGk=i=1∑klog2(i+1)2rel(i)+1
也即是说:i越大,排序越往后,对应的 l o g ( i + 1 ) log(i+1) log(i+1)就越大,折损就越高。iDCG,最好排列的的DCG
根据rel(i)进行降序排列,以此序列计算DCG,也就是最好的DCG,称为iDCG。在计算中,采用labels的相关性得分计算(隐形就是0,1;显性评分则是1-5分数)。
如果是隐性评分,根据NDCG,归一化折损累计增益
由于不同搜索的结果返回长度不一样,这样的iDCG就是一个绝对值,没法比较,因此通过DCG/iDCG来表示NDCG,代表着一个相对程度。
N D C G = D C G i D C G NDCG = \frac{DCG}{iDCG} NDCG=iDCGDCG
2 代码实现
上面的理论乍一看理解起来很简单,但是真到具体应用的时候,发现还是很复杂的,以后很多问题需要思考,比如,里面的相似性得分,排序根据什么得分排序等等。代码的实现也容易绕晕。下面给出两种代码方式,分别是只能计算隐性得分的torch版本和numpy版本
torch
# socres为对应item(i)的预测得分,labels对item(i)的标签,由于是隐形评分数据,只有0,1点击值
scores = torch.tensor([[0,0.1,0.3,0.4,0.5]])
labels = torch.tensor([[0,1,1,0,1]])
k = 5
# 降序排列,获取推荐列表的id
rank = (-scores).argsort(dim=1)
cut = rank[:, :k]
# 获取相关性得分,也就是0,1,如果命中
hits = labels.gather(1, cut)
# 计算位置关系,从2开始计
position = torch.arange(2, 2+k)
# 根据位置关系计算位置权重
weights = 1 / torch.log2(position+1)
# 计算DCG
dcg = (hits* weights).sum(1)
# 计算iDCG,由于相关性得分为0,1,且经过排序,所以计算前面为1对应weights之和即可。
idcg = torch.Tensor([weights[:min(n, k)].sum() for n in labels.sum(1)])
ndcg = dcg / idcg
print(ndcg)
numpy
def getDCG(scores):
return np.sum(
np.divide(np.power(2, scores) - 1, np.log2(np.arange(scores.shape[0], dtype=np.float32) + 2)+1),
# np.divide(scores, np.log2(np.arange(scores.shape[0], dtype=np.float32) + 2)+1),
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)
print(rank_scores)
idcg = getDCG(relevance)
dcg = getDCG(rank_scores)
if dcg == 0.0:
return 0.0
ndcg = dcg / idcg
return ndcg
## l1是推荐排序列表,l2是真实点击的列表
l1 = [4,3,2,1,0]
l2 = [4,2,1]
a = getNDCG(l1, l2)
print(a)
边栏推荐
- Feign常见问题总结
- 85-这些SQL调优小'技巧',你学废了吗?
- 71-对2010年阿里一道Oracle DBA面试题目的分析
- leetcode.11 --- 盛最多水的容器
- Understand the index of like in MySQL
- Possible security vulnerabilities in NFT
- Security policy and NAT (easy IP) of firewall Foundation
- Code to Image Converter | 代码生成漂亮图片工具
- uniapp小程序商城开发thinkphp6积分商城、团购、秒杀 封装APP
- Cloud computing in the metauniverse to enhance your digital experience
猜你喜欢

迅睿CMS 自定义数据接口-php执行文件代码
Gradle Build Cache引发的Task缓存编译问题

MySQL高级(二)
![[resolved] -go_ out: protoc-gen-go: Plugin failed with status code 1.](/img/da/9ced1c0a9c386bc8da75dddaa443e5.png)
[resolved] -go_ out: protoc-gen-go: Plugin failed with status code 1.

从感知机到Transformer,一文概述深度学习简史

Cloud computing in the metauniverse to enhance your digital experience

怎样实现网页端im即时通讯中的@人功能
Code to Image Converter | 代码生成漂亮图片工具

用RNN & CNN进行情感分析 - PyTorch

软件上线前为什么要做性能测试?软件性能测试机构怎么找
随机推荐
Can financial products be redeemed on weekends?
ROS from entry to mastery (VIII) common sensors and message data
讲真,Kotlin 协程的挂起没那么神秘(原理篇)
Understand the index of like in MySQL
Xunrui CMS custom data interface PHP executable code
Easydss problem and solution summary
Oh, my God, it's a counter attack by eight part essay
A detailed solution to mysql8.0 forgetting password
Easyclick update Gallery
农产品期货开户
Introduction to JWT
73-找到业务高峰时段的sql示例(报表开发类)
An IPFs enabled email - skiff
【Proteus仿真】三极管组成的H桥驱动直流电机+按键正反转控制
Easyclick fixed status log window
他98年的,我玩不过他...
【深入理解TcaplusDB技术】单据受理之建表审批
Ribbon load balancing
极客星球 | 业务监控及告警系统体系化建设之路
一张图解码 OpenCloudOS 社区开放日