我正在使用 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 与机器人的最佳和最坏情况进行比较......
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(听起来不错)
- 斯皮尔曼等级:大约 0.25(并不令人惊讶,但有一些东西)
- NDCG2:0.58(平均而言,比最差的 DCG 更接近最佳 DCG)
- NDCG3:1.04(略好于随机排序的列表)
老实说,我无法对这些结果做出正面或反面。我的 NDCG 值看起来不错,但它们真的可以在列表中进行比较吗?替代指标是否更有意义?
编辑:在我的第一次随机比较中,我没有使用 np.copy()。因此,我的随机分数几乎总是 0.99。现在已经解决了,结果更有意义。