NDCG原理和实现

1. 原理

对于搜索引擎,本质是用户搜一个query, 引擎返回一个结果列表,那么如何衡量这个结果列表的好坏?

  1. 我们希望把最相关的结果放到排名最靠前的位置,因为大部分用户都是从上往下阅读的, 那么最相关的前面可以最大程度减少用户的阅读时间。

  2. 我们希望整个列表的结果尽可能的和query相关。

第一个条件的满足是首要的,而第二个条件的加入是保证整体结果质量,而这两个条件都体现在了NDCG里面,首先,计算NDCG,需要计算Gain,这个gain即是每条结果的质量的定义,NDCG把所有结果相加最终相加保证,整体质量越高的列表NDCG值越大。同时,Discounted的设计使得越靠前的结果权重越大,这保证了第一条,更相关的排在靠前的结果会有更大的NDCG值。从这两点看,以NDCG为优化目标,保证了搜索引擎在返回结果总体质量好的情况下,把更高质量结果排在更前面。

计算公式如下:

https://images0.cnblogs.com/blog/115277/201401/282051166874413.png

CG的实现, 即将所有的打分进行累加, 如下:

https://images0.cnblogs.com/blog/115277/201401/282051173595041.png

其是个不断累加的值,gain可以使自己定义的一种获得,用来衡量网页的相关性程度:

https://images0.cnblogs.com/blog/115277/201401/282051177507455.png

DCG(Discounted Cumulative Gain),Discounted的factor为:

https://images0.cnblogs.com/blog/115277/201401/282051180781656.png

那么,NDCG就是被IDEA DCG规格化的值,即DCG/IDCG。

2. 实现

改造自github的代码, 输入即是 label, qid, score----样本,查询id,分数。实现的功能是计算多个query的平均ncdg。

import sys, math

topK = int(sys.argv[1])

def DCG(label_list):
    dcgsum = 0
    for i in range(len(label_list)):
        dcg = (2**label_list[i] - 1)/math.log(i+2, 2)
        dcgsum += dcg
    return dcgsum

def NDCG(label_list):
    global topK
    dcg = DCG(label_list[0:topK])
    ideal_list = sorted(label_list, reverse=True)
    ideal_dcg = DCG(ideal_list[0:topK])
    if ideal_dcg == 0:
        return 0
    return dcg/ideal_dcg

def queryNDCG(label_qid_score):
    tmp = sorted(label_qid_score, key = lambda x:-x[2])
    label_list = []
    for label,q,s in tmp:
        label_list.append(label)
    return NDCG(label_list)
    
last_qid = ""
l_q_s = []

ndcg = 0
cnt = 0

for line in sys.stdin:
    label, qid, score = line.rstrip().split(" ")
    if last_qid != "" and qid != last_qid:
        ndcg += queryNDCG(l_q_s)
        cnt += 1
        l_q_s= []
    last_qid = qid
    l_q_s.append([int(label),qid, float(score)])

if last_qid != "":
    ndcg += queryNDCG(l_q_s)
    cnt += 1

#print cnt
print ndcg/cnt

3. 应用

主要是应用评价搜索引擎的排序是否合理。应用主要有三种不同的方案:

  1. 最精准的方案是,用人工标注的方案,如果doc的数据量较少的时候,可以采用这种方案, 如果数据量较大, 会花费很多人力物力。
  2. 拉取竞品的排序数据,可以为一个排序打分参考, 如果竞品做得比较好的,还是值得参考的。
  3. 拉取用户点击行为进行评估。

有了排序的分值,即可实现NDCG的评估和计算。

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
NDCG(Normalized Discounted Cumulative Gain)是用来衡量推荐算法排序效果的一种指标,其值越大说明算法排序效果越好。下面是利用NDCG评估AFM算法代码实现的详细步骤: 1. 首先,我们需要准备数据集。通常情况下,我们需要将数据集分成训练集和测试集两部分,其中训练集用来训练模型,测试集用来评估模型的性能。 2. 在训练集上训练AFM模型,并在测试集上进行预测。预测结果通常是每个用户对所有物品的评分,我们需要根据评分对物品进行排序。 3. 计算每个用户的NDCG值。具体来说,对于每个用户,我们需要将其预测评分按照从高到低的顺序排列,并根据真实评分计算NDCG值。NDCG的计算公式如下: $$ NDCG_k = \frac{DCG_k}{IDCG_k} $$ 其中,$k$表示推荐列表的长度,$DCG_k$表示在推荐列表中前$k$个物品的折损累加收益,$IDCG_k$表示在所有物品中按照真实评分排名前$k$个物品的折损累加收益。具体来说,$DCG_k$和$IDCG_k$的计算公式分别为: $$ DCG_k = \sum\limits_{i=1}^k \frac{2^{rel_i}-1}{log_2(i+1)} $$ $$ IDCG_k =\sum\limits_{i=1}^k \frac{2^{rel_i}-1}{log_2(i+1)} $$ 其中,$rel_i$表示第$i$个物品的真实评分,$log_2(i+1)$是一个惩罚因子,表示排名越靠后的物品权重越小。 4. 最后,我们需要对所有用户的NDCG值求平均,得到AFM算法的平均NDCG值,用于评估模型的性能。 下面是利用Python实现计算NDCG的代码示例: ```python import numpy as np def dcg_k(scores, k): # 计算DCG值 rel = scores[:k] dcg = np.sum((2 ** rel - 1) / np.log2(np.arange(2, k+2))) return dcg def idcg_k(scores, k): # 计算IDCG值 rel = np.sort(scores)[::-1][:k] idcg = np.sum((2 ** rel - 1) / np.log2(np.arange(2, k+2))) return idcg def ndcg_k(scores, k): # 计算NDCG值 dcg = dcg_k(scores, k) idcg = idcg_k(scores, k) ndcg = dcg / idcg if idcg > 0 else 0 return ndcg def evaluate_ndcg(model, test_set, k): # 计算平均NDCGndcg_list = [] for user in test_set.keys(): items = list(test_set[user].keys()) scores = model.predict(user, items) ranked_scores = np.argsort(-scores) ranked_items = [items[i] for i in ranked_scores] ranked_ratings = [test_set[user][item] for item in ranked_items] ndcg = ndcg_k(ranked_ratings, k) ndcg_list.append(ndcg) return np.mean(ndcg_list) ``` 其中,`evaluate_ndcg`函数接收三个参数:`model`表示训练好的AFM模型,`test_set`表示测试集数据,`k`表示推荐列表的长度。函数的返回值是AFM算法在测试集上的平均NDCG值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值