AUC面试

作者: Jarkata | 来源:发表于2021-07-20 00:31 被阅读0次

    目录

    1. 混淆矩阵
    2. ROC曲线
    3. AUC定义
    4. AUC计算
    5. AUC 优点和缺点
    6. AUC的python实现代码

    1. 混淆矩阵

    混淆矩阵是了解AUC的必要前提。它是一个总结分类器所得结果的矩阵,一般为k行k列(k为分类的类别数)。以二分类为例,混淆矩阵如下图所示。

    首先牢记这2个公式:

    • 假阳性率(False Positive Rate)
      FPR= \frac{FP}{FP+TN} (意义是在所有真实的负样本中,预测结果为正的负例。越小越好)
    • 真阳性率(True Positive Rate)
      TPR = \frac{TP} {TP+FN} (意义是在所有真实的正样本中,预测结果为正的正例。等于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) 截断点取值为\{ +\infty , -\infty}就够了。+ \infty表示所有都预测为负样本,(fpr,tpr)=(0,0)。
    -\infty表示所有都预测为正样本,(fpr,tpr)=(1,1)。也就是这两个坐标点固定有,所以一般截断点默认取值就是预测值的所有唯一值。
    如何绘制,如下图所示:

    ROC曲线,横坐标FPR,纵坐标TPR

    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。

    那么在所有情况下,正样本打分大于负样本的个数=
    rank_1+rank_2+...+rank_M -(1+2+...+M)
    所以,AUC的正式计算公式也就有了,如下:

    rank(i)表示正样本i的编号,MXN表示随机从正负样本各取一个的情况数。一般考代码题,比如用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只关注正负样本之间的排序,并不关心正样本内部,或者负样本内部的排序,这样我们也无法衡量样本对于好坏客户的好坏程度的刻画能力;
    1. 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,几何概率模型)


    相关文章

      网友评论

          本文标题:AUC面试

          本文链接:https://www.haomeiwen.com/subject/repkmltx.html