5

ランク付けの学習問題に 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 でした。これは修正され、結果がより意味のあるものになりました。

4

1 に答える 1