目录
- 混淆矩阵
- ROC曲线
- AUC定义
- AUC计算
- AUC 优点和缺点
- AUC的python实现代码
1. 混淆矩阵
混淆矩阵是了解AUC的必要前提。它是一个总结分类器所得结果的矩阵,一般为k行k列(k为分类的类别数)。以二分类为例,混淆矩阵如下图所示。
首先牢记这2个公式:
- 假阳性率(False Positive Rate)
(意义是在所有真实的负样本中,预测结果为正的负例。越小越好) - 真阳性率(True Positive Rate)
(意义是在所有真实的正样本中,预测结果为正的正例。等于Recall)
2. ROC曲线
ROC曲线是Receiver Operating Characteristic Curve的简称,中文名是受试者工作特征曲线。
这一节主要来学如何绘制ROC曲线
(1) 首先,ROC曲线的横坐标是假阳性率FPR,纵坐标是真阳性率TPR。怎么计算上一节已详述。
(2) 其次,明确计算AUC的时候,预测值y_pred一般都是[0, 1]的小数(代表预测为正样本的概率),真实值y_true为0或1。如果计算FPR和TPR,我们就需要知道预测的正负样本情况,但给的预测值是小数,如何划分预测的正负样本呢?答案是选取截断点。
(3) 截断点是指区分正负预测结果的阈值。比如截断点=0.1,那就表示y_pred<0.1的为预测为负样本,y_pred>=0.1预测正样本。所以绘制AUC曲线需要不断移动“截断点”来得到所有的(FPR,TPR)点,然后把这些点用线段连起来就是ROC曲线了。
(4) 截断点取值为就够了。表示所有都预测为负样本,(fpr,tpr)=(0,0)。
表示所有都预测为正样本,(fpr,tpr)=(1,1)。也就是这两个坐标点固定有,所以一般截断点默认取值就是预测值的所有唯一值。
如何绘制,如下图所示:
3. AUC定义
AUC(Area Under ROC Curve),顾名思义,即ROC曲线下的面积。
AUC越大,说明分类器越可能把正样本排在前面,衡量的是一种排序的性能。
那么问题来了,ROC曲线下的面积怎么就能衡量分类器的排序能力?且听慢慢道来。
如果ROC面积越大,说明曲线越往左上角靠过去。那么对于任意截断点,(FPR,TPR)坐标点越往左上角(0,1)靠,说明FPR较小趋于0(根据定义得知,就是在所有真实负样本中,基本没有预测为正的样本),TRP较大趋于1(根据定义得知,也就是在所有真实正样本中,基本全都是预测为正的样本)。并且上述是对于任意截断点来说的,很明显,那就是分类器对正样本的打分基本要大于负样本的打分(一般预测值也叫打分),衡量的不就是排序能力嘛!
So,现在可以给一个比较常用的AUC的定义
即:随机从正样本和负样本中各选一个,分类器对于该正样本打分大于该负样本打分的概率。
4. AUC计算
AUC如果按照原始定义ROC曲线下的面积来计算,非常之麻烦。
可以转换一下思路,按照上述给出的常用的AUC定义,即随机选出一对正负样本,分类器对于正样本打分大于负样本打分的概率。咱们就来算算这个概率到底是多少,那么也就算出AUC是多少了。
假设数据集一共有M个正样本,N个负样本,预测值也就是M+N个。我们将所有样本按照预测值进行从小到大排序,并且排序编号由1到M+N。
那么在所有情况下,正样本打分大于负样本的个数=
所以,AUC的正式计算公式也就有了,如下:
表示正样本的编号,表示随机从正负样本各取一个的情况数。一般考代码题,比如用python写个AUC计算,也是用上述公式原理。
但是,还没有完,有一个小问题,可能大家没注意到。那就是如果有预测值是一样的,那么怎么进行排序编号呢?
其实很简单,对于预测值一样的样本,我们将这些样本原先的排号平均一下,作为新的排序编号就完事啦。仔细理解可看下图:
上图中,正样本个数M=5,负样本个数N=3,预测值相同有4个。我们将预测值pred相等的情况(上图红色字体),对其进行新的排序编号,变成4.5。
那么根据公式就可以算出上图中的AUC=
用sklearn的auc计算验证一下,一样。
所以,你掌握了吗?
掌握了的话,可看看这里给出的笔者经历的腾讯面试题。
有一堆样本,其中2000个负样本,8000个正样本,其中负样本的预测值为均匀分布U(0.4, 0.6),正样本的预测值为均匀分布U(0.5, 0.7)。求AUC。需要给出详细解答过程。(答案可翻到最后)
5. AUC的有点和缺点(八股)
优点:
- AUC衡量的是一种排序能力,因此特别适合排序类业务。
- AUC对正负样本均衡并不敏感,在样本不均衡的情况下,也可以做出合理的评估。
- 其他指标比如precision, recall, F1,根据区分正负样本阈值的变化会有不同的结果,而AUC不需要手动设定阈值,是一种整体上的衡量方法。
缺点:
- 忽略了预测的概率值和模型的拟合程度;
- AUC反应了太过笼统的信息。无法反应召回率、精确率等在实际业务中经常关心的指标;
- 它没有给出模型误差的空间分布信息,AUC只关注正负样本之间的排序,并不关心正样本内部,或者负样本内部的排序,这样我们也无法衡量样本对于好坏客户的好坏程度的刻画能力;
- AUC的Python实现代码
AUC的具体计算公式都给了,理解了其中逻辑,实现起来就比较容易了。代码如下,核心代码也就10行左右:
import numpy as np
import pandas as pd
# 正例
y_pred = list(np.random.uniform(0.4,0.6,2000))+list(np.random.uniform(0.5,0.7,8000))
# 负例
y_true = [0] * 2000 + [1]*8000
def calc_auc(y_true, y_pred):
pair = list(zip(y_true,y_pred))
pair = sorted(pair, key = lambda x:x[1]) # 进行排序
df = pd.DataFrame([[x[0],x[1],i+1] for i,x in enumerate(pair)],
columns=['y_true','y_pred','rank'])
# 下面需要将预测值为一样的进行重新编号
for k,v in df.y_pred.value_counts().items():
if v==1: # 说明该预测值k只出现了一次,没有重复,不考虑
continue
rank_mean = df[df.y_pred==k]['rank'].mean()
df.loc[df.y_pred==k, 'rank'] = rank_mean
pos_df = df[df.y_true==1] # 正样本的表
m = pos_df.shape[0] # 正样本数
n = df.shape[0]-m # 负样本数
return (pos_df['rank'].sum()-m*(m+1)/2)/(m*n)
print(calc_auc(y_true,y_pred))
from sklearn.metrics import roc_auc_score
print(roc_auc_score(y_true,y_pred))
看完上述结果,你应该知道了上面的腾讯面试题结果是什么了(7/8,几何概率模型)
网友评论