- 按预测值和标签升序排序
- 遍历数组,遇到负样本neg+1,遇到正样本sum+=neg
- 考虑到存在正负样本预测值相同,需要加0.5的情况,增加辅助变量tmp和val
- 理论看这里
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct val_np {
double val;
char np;
};
bool auc_cmp(val_np a, val_np b) {
if(a.val == b.val) return a.np < b.np;
return a.val < b.val;
}
double AUC(vector<val_np> v) {
sort(v.begin(), v.end(), auc_cmp);
int neg = 0, tmp = 0, n = v.size(), m = 0;
double val = 0, sum = 0;
for(int i = 0; i < n; ++i) {
if(v[i].np == 'p') ++m;
}
if(m == 0 || m == n) return 0;
for(int i = 0; i < n; ++i) {
if(v[i].val != val) {
val = v[i].val;
neg += tmp;
tmp = 1;
if(v[i].np == 'p') {
tmp = 0;
sum += neg;
}
} else {
if(v[i].np == 'p') {
sum += neg+0.5*tmp;
} else {
++tmp;
}
}
}
return sum/m/(n-m);
}
int main(int argc, char **argv) {
vector<val_np> v(8);
v[0].val = 0.2, v[0].np = 'p';
v[1].val = 0.2, v[1].np = 'n';
v[2].val = 0.1, v[2].np = 'n';
v[3].val = 0.2, v[3].np = 'n';
v[4].val = 0.3, v[4].np = 'p';
v[5].val = 0.2, v[5].np = 'p';
v[6].val = 0.3, v[6].np = 'n';;
v[7].val = 0.2, v[7].np = 'n';
cout << AUC(v) << endl;
return 0;
}