我正在使用python进行学习排序问题,并且我正在使用以下DCG和NDCG代码评估我的成功(从http://nbviewer.ipython.org/github/ogrisel/notebooks/blob/master/Learning%20to%20Rank.ipynb)NDCG(标准化折扣收益)是否有缺陷?我已经计算了一些可选的排名质量度量,但我无法做出正面或反面的结果
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。现在已经修复,结果更有意义。
是你的'相关'数组二进制或连续值?当你评估一个位于k的“相关”向量的dcg时,向量中有多少个元素(n)?是n << k? – greeness 2014-10-01 23:38:39
我正在玩几种不同的选项,其中一些对DCG来说看起来很不寻常。 a)使用连续变量用于排序和关联,b)使用array.argsort()。argsort()将连续变量转换为排名(最高排名等于数组长度),c)将项目分为5个相关类别并进行比较他们预测的相关性类别(多个元素将具有相同的相关性)。 – neelshiv 2014-10-02 12:55:13