auc
AUC(Area under curve)是机器学习常用的二分类评测手段。
AUC:一个正例,一个负例,预测为正的概率值比预测为负的概率值还要大的可能性。
所以根据定义:我们最直观的有两种计算AUC的方法
- 1:绘制ROC曲线,ROC曲线下面的面积就是AUC的
- 2:假设总共有(m+n)个样本,其中正样本m个,负样本n个,总共有mn个样本对,计数,正样本预测为正样本的概率值大于负样本预测为正样本的概率值记为1,累加计数,然后除以(mn)就是AUC的值
ROC
ROC曲线指受试者工作特征曲线 / 接收器操作特性曲线(receiver operating characteristic curve), 是反映敏感性和特异性连续变量的综合指标,是用构图法揭示敏感性和特异性的相互关系,它通过将连续变量设定出多个不同的临界值,从而计算出一系列敏感性和特异性,再以敏感性为纵坐标、(1-特异性)为横坐标绘制成曲线,曲线下面积越大,诊断准确性越高。
- 横轴:负正类率(false postive rate FPR)特异度,划分实例中所有负例占所有负例的比例;
- 纵轴:真正类率(true postive rate TPR)灵敏度,Sensitivity(正类覆盖率)
- True negative(TN),称为真负率,表明实际是负样本预测成负样本的样本数
- False positive(FP),称为假正率,表明实际是负样本预测成正样本的样本数
- False negative(FN),称为假负率,表明实际是正样本预测成负样本的样本数
- True positive(TP),称为真正率,表明实际是正样本预测成正样本的样本数
auc直接含义是ROC曲线下的面积,如下图:
AUC直观地反映了ROC曲线表达的分类能力。
- AUC = 1,代表完美分类器
- 0.5 < AUC < 1,优于随机分类器
- 0 < AUC < 0.5,差于随机分类器
AUC这个指标有两种解释方法,一种是传统的“曲线下面积”解释,另一种是关于排序能力的解释。其含义可以大概理解为:随机给定一个正样本和一个负样本,分类器输出该正样本为正的那个概率值比分类器输出该负样本为正的那个概率值大的可能性。
ROC曲线怎么得来
假设采用逻辑回归分类器,其给出针对每个实例为正类的概率,那么通过设定一个阈值如0.6,概率大于等于0.6的为正类,小于0.6的为负类。对应的就可以算出一组(FPR,TPR),在平面中得到对应坐标点。随着阈值的逐渐减小,越来越多的实例被划分为正类,但是这些正类中同样也掺杂着真正的负实例,即TPR和FPR会同时增大。阈值最大时,对应坐标点为(0,0),阈值最小时,对应坐标点(1,1)。
- step1:假设已经得出一系列样本被划分为正类的概率,然后按照大小排序,下图是一个示例,图中共有20个测试样本,“Class”一栏表示每个测试样本真正的标签(p表示正样本,n表示负样本),“Score”表示每个测试样本属于正样本的概率。
-
step2:我们从高到低,依次将“Score”值作为阈值threshold,当测试样本属于正样本的概率大于或等于这个threshold时,我们认为它为正样本,否则为负样本。举例来说,对于图中的第4个样本,其“Score”值为0.6,那么样本1,2,3,4都被认为是正样本,因为它们的“Score”值都大于等于0.6,而其他样本则都认为是负样本。每次选取一个不同的threshold,我们就可以得到一组FPR和TPR,即ROC曲线上的一点。这样一来,我们一共得到了20组FPR和TPR的值,将它们画在ROC曲线的结果如下图:
随着样本数量增多,逐渐接近理想ROC曲线。
PR指标
一个通俗解释:
F1-SCORE
from sklearn.metrics import f1_score
y_pred = [0, 1, 1, 1, 2, 2]
y_true = [0, 1, 0, 2, 1, 1]
print(f1_score(y_true, y_pred, average='macro'))
print(f1_score(y_true, y_pred, average='weighted'))
auc计算方式比较
- 面积计算:矩形面积累加,计算复杂,基本不用。
- 统计正负样本对PK情况:统计一下所有的 M×N(M为正类样本的数目,N为负类样本的数目)个正负样本对中,有多少个组中的正样本的score大于负样本的score。当二元组中正负样本的 score相等的时候,按照0.5计算。然后除以MN。实现这个方法的复杂度为O(n^2)。实际也不会用。
-
rank求取:
降序rank--> 去掉(正,正)样本对数--> 求取比例
- 按概率从高到矮排个降序, 对于正样本中score最高的,排序为rank_n, 比它概率小的有M-1个正样本(M为正样本个数), (rank_n- M) 个负样本。
- 正样本概率第二高的, 排序为rank_n-1, 比它概率小的有M-2个正样本,(rank_n-1 - M + 1) 个 负样本。
- 以此类推正样本中概率最小的, 排序为rank_1,比它概率小的有0个正样本,rank_1 - 1 个负样本。
- 总共有MxN个正负样本对(N为负样本个数)。把所有比较中 正样本概率大于负样本概率 的例子都算上, 得到公式 (rank_n - M + rank_n-1 - M + 1 .... + rank_1 - 1) / (MxN) 就是正样本概率大于负样本概率的可能性了。 化简后(因为后面是个等差数列)得:
其实就是,按正样本score降序排列情况下,负样本pk失败的数目总数占所有样本对的比例。(网上说取M,M-1,……1比M-1,M-2,……1更简便的,个人以为理解错了,其实不是去掉了比rank_i的score低的i-1个(正,正)样本对,而是留下了失败的(正,负)样本对)
知乎的解释:https://www.zhihu.com/question/39840928
Wilcoxon-Mann-Witney Test:
python实现
def calAUC(prob,labels):
f = list(zip(prob,labels))
rank = [values2 for values1,values2 in sorted(f,key=lambda x:x[0])]
rankList = [i+1 for i in range(len(rank)) if rank[i]==1]
posNum = 0
negNum = 0
for i in range(len(labels)):
if(labels[i]==1):
posNum+=1
else:
negNum+=1
auc = 0
auc = (sum(rankList)- (posNum*(posNum+1))/2)/(posNum*negNum)
print(auc)
return auc
工具调用实现
import numpy as np
from sklearn.metrics import roc_auc_score
y_true = np.array([0, 0, 1, 1])
y_scores = np.array([0.1, 0.4, 0.35, 0.8])
print(roc_auc_score(y_true,y_scores))
gauc
-
原理
auc反映的是整体样本间的一个排序能力,而在计算广告领域,我们实际要衡量的是不同用户对不同广告之间的排序能力, 实际更关注的是同一个用户对不同广告间的排序能力, group auc实际是计算每个用户的auc,然后加权平均,最后得到group auc,这样就能减少不同用户间的排序结果不太好比较这一影响。group auc具体公式如下:
- python实现
def cal_group_auc(labels, preds, user_id_list):
"""Calculate group auc"""
print('*' * 50)
if len(user_id_list) != len(labels):
raise ValueError(
"impression id num should equal to the sample num," \
"impression id num is {0}".format(len(user_id_list)))
group_score = defaultdict(lambda: [])
group_truth = defaultdict(lambda: [])
for idx, truth in enumerate(labels):
user_id = user_id_list[idx]
score = preds[idx]
truth = labels[idx]
group_score[user_id].append(score)
group_truth[user_id].append(truth)
group_flag = defaultdict(lambda: False)
for user_id in set(user_id_list):
truths = group_truth[user_id]
flag = False
for i in range(len(truths) - 1):
if truths[i] != truths[i + 1]:
flag = True
break
group_flag[user_id] = flag
impression_total = 0
total_auc = 0
#
for user_id in group_flag:
if group_flag[user_id]:
auc = roc_auc_score(np.asarray(group_truth[user_id]), np.asarray(group_score[user_id]))
total_auc += auc * len(group_truth[user_id])
impression_total += len(group_truth[user_id])
group_auc = float(total_auc) / impression_total
group_auc = round(group_auc, 4)
return group_auc
参考:
https://blog.csdn.net/natsuka/article/details/78546645
https://blog.csdn.net/u013385925/article/details/80385873
https://zhuanlan.zhihu.com/p/35583721
https://blog.csdn.net/hnu2012/article/details/87892368