ランク付けの学習問題に 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
この指標を使用して 2 つのランキングを比較し、どちらが優れているかを確認できます。ただし、4項目リストの最悪のケースを計算すると...
>>> ndcg(np.asarray([1,2,3,4]))
0.74890302967841715
4 項目のリストは、3 項目のリストとは比較になりません。
また、2 つの代替 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: 平均は .87 (良さそうですね)
- 槍兵のランク: 0.25 前後 (驚くほどではありませんが、そこには何かがあります)
- NDCG2: .58 (平均して、最悪の DCG よりも最良の DCG にわずかに近い)
- NDCG3: 1.04 (ランダムにソートされたリストよりもわずかに優れています)
正直なところ、これらの結果の頭も尻尾もわかりません。私の NDCG 値は良さそうに見えますが、実際にリスト間で比較できますか? 代替指標の方が理にかなっていますか?
編集:最初のランダムな比較では、np.copy() を使用していませんでした。そのため、私のランダム スコアはほぼ常に .99 でした。これは修正され、結果がより意味のあるものになりました。