2020icpc沈阳站K题

该博客介绍了如何计算AUC(Area Under the Curve),它是一种衡量分类器性能的指标。通过排序数据,计算不同阈值下的真正例率(TPR)和假正例率(FPR),并求和矩形面积来得到AUC。文章提供了AC代码实现,并分享了在理解和调试过程中遇到的问题,强调了正确理解TP、TN、FP、FN的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:给出 n n n个数的分类和预测值,(还有一些概念: T P R TPR TPR, F P R FPR FPR, A U C AUC AUC)求 A U C AUC AUC

分析:不难发现最后要求的是若干个矩形的面积,分段求就可以。先给n个数排序然后根据取每个 a i a_i ai θ θ θ,若 a i − 1 a_{i-1} ai1 + + + F N FN FN++,若为 − - T N TN TN++。

ac代码:

#include <bits/stdc++.h>

using namespace std;

typedef long double ld;
const int N = 1e6+6;
map<char,vector<int> >mp[4];
struct node{
	char c;ld x;int cnt;int l,r;
	bool operator<(const node&t)const{
		if(x == t.x)return c < t.c;//+,-
		return x < t.x;
	}
}p[N],q[N];
int n;
ld calf(ld fp,ld tn){
//	printf("aaaaaa%.10f\n",1.0*fp/(1.0*tn+1.0*fp));
	return (ld)fp/((ld)tn+(ld)fp);
}
ld calt(ld tp,ld fn){
	return (ld)tp/((ld)tp+(ld)fn);
}
int main(){
	ios::sync_with_stdio(false);
	cin >> n;
	for(int i = 0;i < n;i++){
		char c;ld x;cin >> c >> x;
		p[i].c = c,p[i].x = x;
	}
	sort(p,p+n);ld ans = 0.0;int idx = 0;
	for(int i = 0;i < n;i++){
		if(p[i].x == p[i-1].x)continue;
		node tmp = {'+',p[i].x},tmp1 = {'-',p[i].x};
		p[i].cnt = upper_bound(p,p+n,tmp1) - lower_bound(p,p+n,tmp);
		q[idx] = p[i];q[idx].l = lower_bound(p,p+n,tmp) - p;
		q[idx].r = upper_bound(p,p+n,tmp1) - p;idx++;
		
	}
	ld theta = q[0].x;int tp = 0,fp = 0,tn = 0,fn = 0;
	for(int i = 0;i < n;i++){
		if(p[i].c=='+')tp++;
		else fp++;
	}
//	printf("%d %d %d %d\n",tp,fp,tn,fn);
	ld f = calf((ld)fp,(ld)tn),t = calt((ld)tp,(ld)fn);
//	cout << theta << endl;
//	printf("%.10f %.10f\n",1.0*fp/(1.0*fp+1.0*tn),(ld)tp/((ld)tp+(ld)fn));
//	cout << fixed << setprecision(10) << f <<" "<<t << endl;
	for(int i = 1;i < idx;i++){
		ld theta = q[i].x;int l = q[i-1].l,r = q[i-1].r;
		for(int j = l;j < r;j++)
			if(p[j].c=='+')fn++,tp--;
			else tn++,fp--;
//		if(fp <= 0||tp <= 0)break;
//		cout << theta << endl;
//		cout << fixed << setprecision(10)<<tp<<" "<<fp<<" "<<tn<<" "<<fn<<endl;
		ld f1 = calf((ld)fp,(ld)tn),t1 = calt((ld)tp,(ld)fn);
//		cout << fixed << setprecision(10)<<f1<<" "<<t1<<endl;
		ans = ans+(f-f1)*t1;f = f1;t = t1;
	}
//	ans = ans+t*f;
	cout << fixed << setprecision(12)<<ans << endl;
//	for(int i = 0;i < idx;i++)cout << q[i].c << " " << q[i].x << " "<<q[i].cnt << endl;
	return 0;
}
/*
8
+ 34
+ 33
+ 26
- 34
- 38
+ 39
- 7
- 27

3
+ 2
- 3
- 1

6
+ 7
- 2
- 5
+ 4
- 2
+ 6
*/

p.s. 调了好几个小时人快麻了,问题主要出在 T P TP TP, T N TN TN, F P FP FP, F N FN FN的理解上。记得记录 a i − 1 a_{i-1} ai1的个数。时间复杂度 O n O_n On

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值