1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
//
// Created by joe on 4/12/15.
//
#include "rankaccu.h"
#include "../tools/easylogging++.h"
using namespace std;
const double offset = 1;
void ranksort(int l,int r,vector<int> &rank,const vector<double> &ref1,const vector<double> &ref2)
{
int i=l,j=r,k;
double mid1=ref1[rank[(l+r)>>1]],mid2=ref2[rank[(l+r)>>1]];
while (i<=j)
{
while (ref1[rank[i]]>mid1 || (ref1[rank[i]]==mid1 && ref2[rank[i]]>mid2)) ++i;
while (ref1[rank[j]]<mid1 || (ref1[rank[j]]==mid1 && ref2[rank[j]]<mid2)) --j;
if (i<=j)
{
k=rank[i];
rank[i]=rank[j];
rank[j]=k;
++i;
--j;
}
}
if (j>l)
ranksort(l,j,rank,ref1,ref2);
if (i<r)
ranksort(i,r,rank,ref1,ref2);
}
void rankmerge(int l,int r,vector<int> &C,vector<int> &rank,const vector<double> &ref1,const vector<double> &ref2)
{
if (l==r)
return;
int i=l,j=((l+r)>>1)+1;
rankmerge(i,j-1,C,rank,ref1,ref2);
rankmerge(j,r,C,rank,ref1,ref2);
vector<int> stage_r(r-l+1),stage_c(r-l+1);
int cnt=0;
int k=0;
while (i<=((l+r)>>1) && j<=r)
{
if (ref1[rank[i]]>ref1[rank[j]] || (ref1[rank[i]]==ref1[rank[j]] && ref2[rank[i]]>ref2[rank[j]])) {
stage_c[k] = C[i];
stage_r[k++] = rank[i++];
++cnt;
}
else{
stage_c[k] = C[j]+cnt;
stage_r[k++] = rank[j++];
}
}
while (i<=((l+r)>>1))
{
stage_c[k] = C[i];
stage_r[k++] = rank[i++];
}
while (j<=r)
{
stage_c[k] = C[j]+cnt;
stage_r[k++] = rank[j++];
}
for (i=l;i<=r;++i)
{
C[i]=stage_c[i-l];
rank[i]=stage_r[i-l];
}
}
int rank_accu(DataList &D,const vector<double> pred)
{
unsigned long n = D.getSize();
vector<int> orig_rank(n),pred_rank(n),C(n);
vector<double> orig(n);
int i,j;
for (i=0;i<D.getSize();++i)
{
orig_rank[i]=i;
pred_rank[i]=i;
orig[i]=D.getData()[i]->rank;
}
int cnt=0;
double accu_nDCG=0;
double accu_AP=0;
i=j=0;
while (i<D.getSize())
{
if ((i+1 == D.getSize())|| D.getData()[i]->qid!=D.getData()[i+1]->qid)
{
double Y=0,Z=0;
double AP=0;
ranksort(j,i,orig_rank,orig,pred);
ranksort(j,i,pred_rank,pred,orig);
for (int k = j;k<=i;++k)
{
Z += (pow(2,offset+orig[orig_rank[k]]) - 1)/log2(2+k-j);
Y += (pow(2,offset+orig[pred_rank[k]]) - 1)/log2(2+k-j);
}
accu_nDCG+=Y/Z;
rankmerge(j,i,C,orig_rank,pred,orig);
for (int k = j+1;k<=i;++k)
AP += ((double)C[k])/(k-j);
AP=AP*2/(i-j)-1;
accu_AP+=AP;
j = i+1;
++cnt;
}
++i;
}
LOG(INFO)<<"over "<< cnt<< " queries. "<<"Average nDGC: "<< accu_nDCG/cnt<< " Average AP: "<<accu_AP/cnt;
}
|