NDCG及其实现

1、 NDCG的目标: 希望得到的排序列表,质量越高越好。并且,如果将更相关的排到更前面,那么计算得到的NDCG是会越高的
AUC和NDCG的区别:
1、AUC的含义:把正样本排在负样本前的概率。AUC关注的是全局的排序,只要正样本排在负样本之前,就可以得分。并没有加权。
2、NDCG也是关注排序,但是NDCG关注的是,加权排序。比如我们希望top10的排序准确度,要比bottom10的排序准确度重要。对于这种加权排序,NDCG会更加合适。

因此,AUC和NDCG的区别是,加权与否。AUC的评估中,top-10的排序质量和bottom-10的排序质量是一样重要的。但是,在NDCG中,是需要加权的,top-10的排序质量和bottom-10的排序质量的权重是不一样的。


2、

说明:sklearn只有到0.20版本才支持NDCG误差的计算,因此我们可以将该代码拷贝出来。

import numpy as np
from sklearn.preprocessing import LabelBinarizer
from sklearn.metrics import make_scorer
from sklearn.utils import check_X_y
import sys

def dcg_score(y_true, y_score, k=5):
    order = np.argsort(y_score)[::-1]
    y_true = np.take(y_true, order[:k])
    gain = 2 ** y_true - 1
    #print(gain)
    discounts = np.log2(np.arange(len(y_true)) + 2)
    #print(discounts)
    return np.sum(gain / discounts)


def ndcg_score(y_true, y_score, k=5):
    y_score, y_true = check_X_y(y_score, y_true)

    # Make sure we use all the labels (max between the length and the higher
    # number in the array)
    lb = LabelBinarizer()
    lb.fit(np.arange(max(np.max(y_true) + 1, len(y_true))))
    binarized_y_true = lb.transform(y_true)
    print(binarized_y_true)
    if binarized_y_true.shape != y_score.shape:
        raise ValueError("y_true and y_score have different value ranges")

    scores = []

    # Iterate over each y_value_true and compute the DCG score
    for y_value_true, y_value_score in zip(binarized_y_true, y_score):
        actual = dcg_score(y_value_true, y_value_score, k)
        best = dcg_score(y_value_true, y_value_true, k)
        #print(best)
        scores.append(actual / best)
    return np.mean(scores)


# NDCG Scorer function
# sklearn的NDCG对二维的计算有点问题,可以转化为三分类问题
y_true = [0, 1, 0]
y_score = [[0.0, 1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]
print(ndcg_score(y_true, y_score, k=2))
说明:sklearn对二分类的NDCG貌似不是支持得很好,所以折中一下,换成三分类,第三类补成概率为0.

  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
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值。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值