开集识别中的AUROC计算(原理+代码)

1、什么是AUROC?

接受者操作特征曲线下面积(area under the receiver operating characteristic,AUROC) 是一个用来衡量分类器性能的指标。其通过接受者操作特征曲线(receiver operating characteristic curve)与坐标轴之间的面积大小来反应分类器的性能,其意义可以理解为均匀抽取的随机阳性样本(正样本)排名在均匀抽取的随机阴性样本(负样本)之前的期望。AUROC是一个介于0到1之间的数值,当AUROC值接近于1是,表示分类器可以较好的分类正负样本。

2、二分类问题中ROC曲线的绘制

ROC曲线也称为感受性曲线(sensitivity curve),该曲线反应的是同一信号刺激在不同的判定标准下的不同判定结果。在介绍ROC曲线前,首先介绍一些基本的概念。

2.1一些基本概念

ROC曲线也称为感受性曲线(sensitivity curve),该曲线反应的是同一信号刺激在不同的判定标准下的不同判定结果。在介绍ROC曲线前,首先介绍一些二分类问题中的基本的表示。

P (Positive) :正样本,一般用1来表示。

N (Negative) :负样本,一般用0来表示。

TP(True Positive): 真阳,预测为1,真实为1

FP(False Positive):假阳,预测为1,真实为0。

TN(Ture Negative):真阴,预测为0,真实为0。

FN(False Negative): 假阴:预测为0,真实为1。

TPR (True Positive Rate):真阳率,所有真实(标签)为1的样本中,预测为1的样本的比例。该值越高越好。

FPR(False Positive Rate): 假阳率:所有真实(标签)为0的样本中,预测为1的样本的比例。该值越低越好。

2.2 ROC曲线绘制

在二分类问题中,我们可以得到一个样本为1的概率值,该概率值是一个0到1之间的数值,同时,我们也可以设定一个阈值,当概率值大于阈值时,则认为该样本为正样本,反之,则认为该样本为负样本。

我们可以设置多个阈值,每一个阈值下,都可以得到测试样本的测试结果,以及该阈值下的TPR与FPR,对于一个样本数为N的测试集,我们可以设置N+2个阈值,得到N+2组TPR与FPR值,将TPR作为x轴,FPR作为y轴,便可以将N个点放在坐标系中,将所有的点连接起来,便可以得到ROC曲线。

2.3 一个示例

示例:有2个正样本A与B,其预测为正样本的概率分别为0.4,0.9,有两个负样本C与D,其预测为正样本的概率分别为0.2,0.5。

由于我们有四个样本,所以我们可以设置5个阈值,0,0.2,0.4,0.5,0.9,置信度大于阈值,则视为正样本

当阈值为0时,A,B,C,D 均预测为正样本,此时TPR为2/2 = 1,FPR为2/2 = 1;

当阈值为0.2时,A,B,D预测为正样本,C预测为负样本,TPR为2/2 = 1,FPR为1/2 = 0.5;

当阈值为0.4时,B,D预测为正样本,A,C预测为负样本,TPR为1/2 = 0.5,FPR为1/2 = 0.5;

当阈值为0.5时,B 预测为正样本,A,C,D预测为负样本,TPR为1/2 = 0.5,FPR为0/2 = 0;

当阈值为0.9时,A,B,C,D均预测为负样本,TPR为0/2 = 0,FPR为0/2 = 0;

我们将5组TPR与FPR画在坐标轴,就可以得到ROC曲线了,重复的可以看作一个点。

2.4 程序实现

根据上述实例,我们可以发现一些规律。

(1)阈值可以用置信度的排序来选取。

(2)随着阈值的增加,TPR与FPR的分母是不变的,只有分子在变化。

(3)随着阈值的增加,分子的变化是单调递减的。

因此,只要知道了随着阈值的改变,分子是怎么变的,就可以得到ROC曲线了。

换言之,阈值每改变一次,只需要知道是TPR的分子减1还是FPR的分子减1就好了。

下面详细介绍ROC的绘制函数。

def compute_roc(pred_p, pred_n, labels):

函数的输入为两个变量,

pred_p:正样本经过Softmax得到的分类为正样本的置信度 N*1,N为样本数,

pred_q: 负样本经过Softmax得到分类为负样本的置信度 M*1,M为样本数

可以看到,正样本的总数为N,负样本的总数为M,因此,TPR与FPR的分母分别为N与M。

    predict = np.concatenate((pred_p, pred_q), axis=0)

将所有的置信度拼接起来。

    TPR_target = np.concatenate((np.ones(len(x1)), np.zeros(len(x2))), axis=0)

    FPR_target = np.concatenate((np.zeros(len(x1)), np.ones(len(x2))), axis=0)

创建两个矩阵,分别记录样本的属性,

在TPR_target 中,正样本为1,负样本为0(TPR更关注正样本的个数,即有多少个正样本被正确分类)

在FPR_target 中,正样本为0,负样本为1(FPR更关注负样本的个数,即有多少个负样本被错误分类)

    idx = predict.argsort()

    s_TPR_target = TPR_target[idx]

    s_FPR_target = FPR_target[idx]

    n = len(predict) #样本总个数,N+M

将拼接后的置信度根据大小进行排序,得到索引,样例中,[0.4,0.9,0.2,0.5]的排序结果为[0.2,0.4,0.5,0.9],所以索引为[2,0,3,1 ]

即原始的predict中predict[2] 是最小的,predict[0]是第二小的,依次类推。排序后,标签也要根据排序结果重新排列,

s_ TPR _target [0] = TPR _target[2],s_ TPR _target [1] = TPR _target[0],依次类推。这个过程可以简写为  s_ TPR _target =  TPR _target[idx]。

    TPR = [0 for x in range(n+1)]   

    FPR = [0 for x in range(n+1)] 

创建两个空数组,用于存放不同阈值下的TPR值与FPR值

下面开始计算不同的阈值下,TP的个数与FP的个数

首先,不考虑阈值为0,因为阈值为0时,所有样本都是正样本,此时TPR与FPR均为1 。当阈值为最小值0.2时,0.2对应的样本被分为负样本,其他被分为正样本,此时TP个数为s_ TPR _target 中[1:]的和,时TP个数为s_ FPR _target 中[2:]的和。根据这个方法,可得如下程序

    for k in range(n-1):

 # k表示第k个阈值(不包含0和1)

       TP = s_ TPR _targe[k+1:].sum()

        FP =  s_ FPR _targe[k:].sum()

        TPR [k] = TP  / float(len(x1))

        FPR [k] = FP  / float(len(x2))

 # 补充阈值为0的情况

    CCR[n] = 0.0

    FPR[n] = 0.0

3、开集问题中ROC曲线的绘制

开集识别是一个特殊的二分类问题,这里把测试集中的已知类看作正样本,未知类看作负样本。认为某一阈值下,低于阈值的样本为开集。

开集识别与普通二分类问题的区别在于,开集识别不仅仅要把已知类识别为已知类,还要把已知类正确分类,才认为分类正确。所以有人提出了OSCR这一指标来对AUROC进行补充。

开集识别中,需要对 TPR _targe进行纠正,将即使识别为已知类,也不能正确分类的样本的值定义为0。即TPR不会受到此样本的影响。

4、OSCR计算代码

def compute_oscr(pred_k, pred_u, labels):

    # pred_k:已知类别经过Softmax得到的置信度 N*C,N为样本数,C为已知类的类别数

    # pred_u:未知类别经过Softmax得到的置信度 M*C,M为样本数,C为已知类的类别数

    # labels:已知类别标签 N*1,N为样本数

    # x1,x2 最大置信度 N*1,M*1

    x1, x2 = np.max(pred_k, axis=1), np.max(pred_u, axis=1)

    # pred_k中最大置信度对应的类别

    pred = np.argmax(pred_k, axis=1)

    # pred_k中预测正确的样本

    correct = (pred == labels)

    m_x1 = np.zeros(len(x1))

    m_x1[pred == labels] = 1

    #注意,不同点在于这里

    k_target = np.concatenate((m_x1, np.zeros(len(x2))), axis=0)

    u_target = np.concatenate((np.zeros(len(x1)), np.ones(len(x2))), axis=0)

    predict = np.concatenate((x1, x2), axis=0)

    n = len(predict)

    # Cutoffs are of prediction values

    CCR = [0 for x in range(n+1)]

    FPR = [0 for x in range(n+1)] 

    idx = predict.argsort()

    s_k_target = k_target[idx]

    s_u_target = u_target[idx]

    for k in range(n-1):

        CC = s_k_target[k+1:].sum()

        FP = s_u_target[k:].sum()

        # True  Positive Rate

        CCR[k] = float(CC) / float(len(x1))

        # False Positive Rate

        FPR[k] = float(FP) / float(len(x2))

    CCR[n] = 0.0

    FPR[n] = 0.0

    # Positions of ROC curve (FPR, TPR)

    ROC = sorted(zip(FPR, CCR), reverse=True)

    OSCR = 0

    # Compute AUROC Using Trapezoidal Rule

    for j in range(n):

        h =   ROC[j][0] - ROC[j+1][0]

        w =  (ROC[j][1] + ROC[j+1][1]) / 2.0

        OSCR = OSCR + h*w

    return OSCR

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容

  • 线性回归** (属于回归算法,解决回归问题,即目标值为连续性的数据) 应用场景:房价预测,销售额度预测,贷款额度预...
    xiaopar阅读 1,542评论 0 1
  • 机器学习的目的是使学到的模型不仅对已知数据,而且对未知数据都能有很好的预测能力。当损失函数给定时,基于损失函数的模...
    隐士飞猪阅读 2,686评论 0 3
  • X[:,0]是numpy中数组的一种写法,取数组的索引,表示对一个二维数组,取该二维数组第一维中的所有数据,第二维...
    当安东尼遇到玛丽阅读 2,189评论 0 1
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,531评论 28 53
  • 人工智能是什么?什么是人工智能?人工智能是未来发展的必然趋势吗?以后人工智能技术真的能达到电影里机器人的智能水平吗...
    ZLLZ阅读 3,768评论 0 5