NDCG(标准化贴现收益)是不是存在缺陷?我已经计算了一些替代的排名质量衡量标准,但我无法得出正面或反面

Posted

技术标签:

【中文标题】NDCG(标准化贴现收益)是不是存在缺陷?我已经计算了一些替代的排名质量衡量标准,但我无法得出正面或反面【英文标题】:Is NDCG (normalized discounted gain) flawed? I have calculated a few alternative ranking quality measures, and I can't make heads or tails of itNDCG(标准化贴现收益)是否存在缺陷?我已经计算了一些替代的排名质量衡量标准,但我无法得出正面或反面 【发布时间】:2014-11-26 16:41:10 【问题描述】:

我正在使用 python 来解决学习排名问题,我正在使用以下 DCG 和 NDCG 代码(来自 http://nbviewer.ipython.org/github/ogrisel/notebooks/blob/master/Learning%20to%20Rank.ipynb)评估我的成功

def dcg(relevances, rank=20):
    relevances = np.asarray(relevances)[:rank]
    n_relevances = len(relevances)
    if n_relevances == 0:
        return 0.
    discounts = np.log2(np.arange(n_relevances) + 2)
    return np.sum(relevances / discounts)

def ndcg(relevances, rank=20):
    best_dcg = dcg(sorted(relevances, reverse=True), rank)
    if best_dcg == 0:
        return 0.
    return dcg(relevances, rank) / best_dcg

以下是 3 个项目列表中最好和最坏情况的 DCG 值,没有重复排名...

>>> ndcg(np.asarray([3,2,1]))
1.0
>>> ndcg(np.asarray([1,2,3]))
0.78999800424603583

我们可以使用这个指标来比较两个排名,看看哪个更好。但是,如果我计算 4 项列表的最坏情况...

>>> ndcg(np.asarray([1,2,3,4]))
0.74890302967841715

4 项列表似乎不再与 3 项列表相提并论。

我还计算了两个替代 NDCG。 NDCG2 将实现的 dcg 与 bot 的最佳和最坏情况进行比较...

def ndcg2(relevances, rank=20):
    best_dcg = dcg(sorted(relevances, reverse=True), rank)
    worst_dcg=dcg(sorted(relevances, reverse=False),rank)
    if best_dcg == 0:
        return 0.
    return (dcg(relevances, rank)-worst_dcg) / (best_dcg-worst_dcg)

NDCG 将我的实际排名列表随机化 50 次,计算每个的 dcg,并将其与我的实际 DCG 进行比较。

def ndcg3(relevances, rank=20):
    shuffled=np.copy(relevances)
    rands=[]
    for i in range(50):
        np.random.shuffle(shuffled)
        rands.append(dcg(shuffled,rank))
    avg_rand_dcg=np.mean(np.asarray(rands))
    return dcg(relevances, rank) / avg_rand_dcg

在我的各种列表中,我得到以下指标...

NDCG:平均值为 0.87(听起来不错) Spearman 军衔:大约 0.25(不惊人,但有一些东西) NDCG2:0.58(平均而言,比最差的 dcg 更接近最佳 dcg) NDCG3:1.04(略好于随机排序的列表)

老实说,我无法对这些结果做出正面或反面。我的 NDCG 值看起来不错,但它们真的可以在列表中进行比较吗?替代指标是否更有意义?

edit:在我的第一次随机比较中,我没有使用 np.copy()。因此,我的随机分数几乎总是 0.99。现在已经修复,结果更有意义。

【问题讨论】:

relevances 数组中的值是二进制的还是连续的?同样,当您评估 k 等级的relevances 向量的 dcg 时,向量中有多少元素 (n)?是 n 我正在玩一些不同的选项,其中一些对于 DCG 来说似乎不寻常。 a) 对排名和相关性使用连续变量,b) 使用 array.argsort().argsort() 将连续变量转换为排名(最高排名等于数组长度),c) 将项目分为 5 个相关类别并进行比较它们到预测的相关性类别(多个元素将具有相同的相关性)。 【参考方案1】:

一种可能会误导您的想法是标准化 NDCG 的方法。通常,您有许多文档要排名,但您的 NDCG 会在文档数量较少时被截断(例如 NCDG@3)。在您的代码中,这由参数“rank”确定。

假设您要对 5 个相关性 R = [1, 2, 3, 4, 0] 的文档进行排名,并计算 NDCG@3。如果您的算法认为最优顺序是 [doc1, doc2, doc3, doc4, doc5],那么您将有:

NDCG@3 = DCG([1, 2, 3]) / DCG([4, 3, 2])

而不是

NDCG@3 = DGC([1, 2, 3]) / DCG([3, 2, 1])   # Incorrect

所以从某种意义上说,NDCG([1, 2, 3]) 和 NDCG([1, 2, 3, 4]) 没有可比性。分子完全一样,但分母完全不同。如果你想让 NDCG 有直观的含义,你必须设置 'rank' 小于或等于您的文档数。

【讨论】:

以上是关于NDCG(标准化贴现收益)是不是存在缺陷?我已经计算了一些替代的排名质量衡量标准,但我无法得出正面或反面的主要内容,如果未能解决你的问题,请参考以下文章

二叉树股票期权定价的几大硬伤

问题 1076: 内部收益率

cv::Mat 类是不是存在设计缺陷?

QuantLib 金融计算——基本组件之 InterestRate 类

sklearn 中 nDCG 的输入

内存回收策略