2

我正在使用python进行学习排序问题,并且我正在使用以下DCG和NDCG代码评估我的成功(从http://nbviewer.ipython.org/github/ogrisel/notebooks/blob/master/Learning%20to%20Rank.ipynbNDCG(标准化折扣收益)是否有缺陷?我已经计算了一些可选的排名质量度量,但我无法做出正面或反面的结果

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 

这里是DCG值中的3项,没有重复的队伍列表中最好的和最坏的情况......

>>> 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:平均值为1.87(听起来不错)
  • Spearman等级:约1.25(不惊人,但有那么点意思)
  • NDCG2:1.58(平均而言,稍微接近比它是最坏的最好的DCG)
  • NDCG3:1.04(略好于随机排序的列表)

我诚实地不能使这些结果的正面或反面。我的NDCG值看起来不错,但它们在列表中真的可比吗?替代指标是否更有意义?

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

+0

是你的'相关'数组二进制或连续值?当你评估一个位于k的“相关”向量的dcg时,向量中有多少个元素(n)?是n << k? – greeness 2014-10-01 23:38:39

+0

我正在玩几种不同的选项,其中一些对DCG来说看起来很不寻常。 a)使用连续变量用于排序和关联,b)使用array.argsort()。argsort()将连续变量转换为排名(最高排名等于数组长度),c)将项目分为5个相关类别并进行比较他们预测的相关性类别(多个元素将具有相同的相关性)。 – neelshiv 2014-10-02 12:55:13

回答

2

一个人认为可能会误导你是正常化NDCG的方法。通常情况下,您有许多文件需要排名,但是您的NDCG会在较少数量的文件中截断(例如NCDG @ 3)。在你的代码中,这是由参数'rank'决定的。

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

[email protected] = DCG([1, 2, 3])/DCG([4, 3, 2]) 

,而不是

[email protected] = DGC([1, 2, 3])/DCG([3, 2, 1]) # Incorrect 
在某种意义上

所以,NDCG([ 1,2,3])和NDCG([1,2,3,4])不具有可比性。分子是完全相同的,但分母是完全不同的。如果您希望NDCG具有直观意义,则必须将 '排名'设置为小于或等于您的文档数量。

相关问题