auc ks 新理解

https://www.zybuluo.com/frank-shaw/note/152851

新理解:我认为auc,和ks异曲同工。auc是根据预测概率(由大到小排序)作为阈值,可分割为不多于样本个数n个阈值。即可得到n个recall和precision把这些点连成线即为roc曲线。auc即为roc下的面积。那个点最接近左上角即为最好的阈值。1和0作阈值分别得到(0,0)和(1,1)点。样本点只是曲线上的点,理论上无穷大,不可能描绘完。横:假阳率,纵:recall。n个点为相应阈值分割得到的recall和precision.

ks可认为也是根据预测概率(由大到小排序)作为阈值,横轴为0到1的阈值,纵为n个recall和precision的点,分别绘制两条曲线,他们之间的绝对差的最大值即为ks值,横轴即为最好的阈值。

而根据金融上定义:ks是  1、根据预测值分区求原y值中各区的好坏占比(分区中好坏/比总的好坏)。  2、求好占比-坏占比的绝对差最大的值为ks值。   如:https://blog.csdn.net/u013421629/article/details/78217498

我认为这是不对的。如最大值可能是某个分区都是好的或坏的,这样的值没有意义。只有recall-假阳率绝对差最大才有实际意义。

前言

本文内容大部分来自于如下两个博客: 
http://blog.csdn.net/dinosoft/article/details/43114935 
http://my.oschina.net/liangtee/blog/340317

引子

假设有下面两个分类器,哪个好?(样本中有A类样本90个,B 类样本10个。)

A类样本 B类样本 分类精度
分类器C1 A*90(100%) A*10(0%) 90%
分类器C2 A*70 + B*20 (78%) A*5 + B*5 (50%) 75%

分类器C1把所有的测试样本都分成了A类,分类器C2把A类的90个样本分对了70个,B类的10个样本分对了5个。

则C1的分类精度为 90%,C2的分类精度为75%,但直觉上,我们感觉C2更有用些。但是依照正确率来衡量的话,那么肯定C1的效果好一点。那么这和我们认为的是不一致的。也就是说,有些时候,仅仅依靠正确率是不妥当的。

我们还需要一个评价指标,能客观反映对正样本、负样本综合预测的能力,还要考虑消除样本倾斜的影响(其实就是归一化之类的思想,实际中很重要,比如pv总是远远大于click),这就是auc指标能解决的问题。

ROC

为了理解auc,我们需要先来弄懂ROC。 
先来看一个普遍的二分类问题的结果,预测值和实际值有4种组合情况,看下面的表格: 
 
我们定义一个变量:

看图也就可以知道,TPR表示的就是预测正确且实际分类为正的数量 与 所有正样本的数量的比例。--实际的正样本中,正确预测的比例是多少?

FPR表示的是预测错误且实际分类为负的数量 与所有负样本数量的比例。 --实际的负样本当中,错误预测的比例是多少?

可以代入到上面的两个分类器当中,可以得到下面的表格(分类器C1):

预测A 预测B 合计
实际A 90 0 90
实际B 10 0 10

TPR = FPR = 1.0.

分类器C2:

预测A 预测B 合计
实际A 70 20 90
实际B 5 5 10

TPR = 0.78, FPR = 0.5

那么,以TPR为纵坐标,FPR为横坐标画图,可以得到: 
 
上图中蓝色表示C1分类器,绿色表示C2分类器。可以知道,这个时候绿色的点比较靠近左上角,可以看做是分类效果较好。所以评估标准改为离左上角近的是好的分类器(考虑了正负样本的综合分类能力)。

一连串这样的点构成了一条曲线,该曲线就是ROC曲线。而ROC曲线下的面积就是AUC(Area under the curve of ROC)。这就是AUC指标的由来。

如何画ROC曲线

对于一个特定的分类器和测试数据集,显然只能得到一个分类结果,即一组FPR和TPR结果,而要得到一个曲线,我们实际上需要一系列FPR和TPR的值才能得到这样的曲线,这又是如何得到的呢?

可以通过分类器的一个重要功能“概率输出”,即表示分类器认为某个样本具有多大的概率属于正样本(或负样本),来动态调整一个样本是否属于正负样本(还记得当时阿里比赛的时候有一个表示被判定为正样本的概率的列么?)

假如我们已经得到了所有样本的概率输出(属于正样本的概率),现在的问题是如何改变这个阈值(概率输出)?我们根据每个测试样本属于正样本的概率值从大到小排序。下图是一个示例,图中共有20个测试样本,“Class”一栏表示每个测试样本真正的标签(p表示正样本,n表示负样本),“Score”表示每个测试样本属于正样本的概率。 
 
接下来,我们从高到低,依次将“Score”值作为阈值,当测试样本属于正样本的概率大于或等于这个阈值时,我们认为它为正样本,否则为负样本。举例来说,对于图中的第4个样本,其“Score”值为0.6,那么样本1,2,3,4都被认为是正样本,因为它们的“Score”值都大于等于0.6,而其他样本则都认为是负样本。每次选取一个不同的阈值,我们就可以得到一组FPR和TPR,即ROC曲线上的一点。这样一来,我们一共得到了20组FPR和TPR的值,将它们画在ROC曲线的结果如下图: 
 
当我们将阈值设置为1和0时,分别可以得到ROC曲线上的(0,0)和(1,1)两个点。将这些(FPR,TPR)对连接起来,就得到了ROC曲线。当阈值取值越多,ROC曲线越平滑。

--在阿里比赛的时候还以为ROC是没用的!!!!真的是有眼无珠啊!!!还是有疑惑的是:如何根据ROC来判定结果的好换呢?看哪个分类器更加接近左上角吧。同时,可以根据ROC来确定划定正样本的概率边界选择在哪里比较合适!!!原来是这样!!!!!!!!!

为什么使用ROC

既然已经这么多评价标准,为什么还要使用ROC和AUC呢?因为ROC曲线有个很好的特性:当测试集中的正负样本的分布变化的时候,ROC曲线能够保持不变。在实际的数据集中经常会出现类不平衡(class imbalance)现象,即负样本比正样本多很多(或者相反),而且测试数据中的正负样本的分布也可能随着时间变化。下图是ROC曲线和Precision-Recall曲线的对比: 

在上图中,(a)和(c)为ROC曲线,(b)和(d)为Precision-Recall曲线。(a)和(b)展示的是分类其在原始测试集(正负样本分布平衡)的结果,(c)和(d)是将测试集中负样本的数量增加到原来的10倍后,分类器的结果。可以明显的看出,ROC曲线基本保持原貌,而Precision-Recall曲线则变化较大。

原文地址:https://www.cnblogs.com/fujian-code/p/9727241.html

时间: 2024-10-11 20:06:17

auc ks 新理解的相关文章

关于erlang中的进程字典(process dictionary)的新理解及其访问速度 (copy来的)

之前对于erlang的进程字典了解的不够清楚,只是知道put().get()函数,即存值和取值,而每个put.get中都有自己的一对Key--Value(键值对)与之对应.一个Key对应一个Value.在erlang中,启动进程节点之后,进程字典的put.get的值是对缓存的处理,而对数据库的操作,相当于是对硬盘的一个操作,可以理解成是一个数据的备份. 举个简单的例子:在游戏中都有好友操作,启动服务之后,玩家点击添加好友操作,进程的节点已经开启,先从内存中获取玩家的进程字典的Value的值,这里

数据库水平分库,垂直分库的新理解

水平分库:当数据量巨大时,将数据放到不同的表中,比如表1,表2,表3,...: 垂直分库:当一张表的字段太多,可拆分出一张或多张分表,根据主键唯一标示: 新理解: 垂直分库:当一张表中字段不多,当某些字段长度过长,表占用空间很大,检索表的时候需要执行大量的IO(数据库检索的本质是对硬盘中的文件进行io访问), 此时可以考虑对长度较长的字段进行拆分,单独成表,用原表主键进行唯一标示. 相反: 当数据库记录数不多,但字段较多,可对部分字段进行整合,比如用户的信息(电话,手机号...),以json字符

接口测试的新理解

最近一直关注接口测试的方方面面. 慢慢的对接口测试的一些更细节的方面有着一些理解. 简单的说,接口测试的过程中需要关注的一些是: 1. 接口的有效性. 2. 接口数据的冗余性. 先说有效性: 有效性的意思在于接口数据的重用,因为在测试的过程中遇到了一种情况,大概的情况是: App上有一个页面,做成了两个Activity,在app上展示为一个页面,上方是个人信息的图片,头像和评论数等一系列的信息.下方是详细信息的一些内容. 不可以理解的是前端做成了两个Activity,A和B ,两个Xml布局,

JavaScript——对this指针的新理解

一直以来对this的理解只在可以用,会用,却没有去深究其本质. 这次,借着<JavaScript The Good Parts>,作了一次深刻的理解. 下面我们一起来看看这个this吧. 在我们声明一个函数时,每个函数除了有定义时的parameters(形参),自身还会有额外的两个参数,一个是this,一个是arguments(实参).arguments就是函数实际接受到的参数,是一个类数组.arguments我只做个简略的介绍,重点我们放在this指针上. 在面向对象变成中,this十分重要

对Delphi控件作用的新理解

最近几天,对Delphi控件的含义有了一个新的理解.其实它不仅仅是给程序员提供功能的一个表层调用,控件本身的源代码就是一个很强的工业级源码.而且它的Main例子,往往就已经是半成品.而别的语言里没有那么多控件——换句话说,就是没有那么多工业级项目的源代码(往往都是通用工具类型)供你使用和学习(两层意思).这是我们Delphier独一无二的优势.不得不说,当年设计Delphi的两位老兄Anders Hejlsberg和Chuck Jazdzewski真是双剑合璧,无敌于天下——当然,只是产品无敌于

关于js参数传递矛盾新理解

之前看了很多人的解释,说js中,函数的参数传递都是值传递中不理解. 他们无非举了两个例子 在这两个例子中,第二个例子可以看出参数是由值传递的.因为函数内对象的变化没有影响到函数外对象的变化.但是在第一个例子中,我们却发现,函数内和函数外都指向了一个地址.但是博主并没有说明 既然是值传递,为什么参数里面的改变却影响了外面的值.博主只解释了第二个例子是值传递,却没有解释第一个例子为什么会出现这样的原因,只是一句两个变量指向一个对象 就一笔带过,我觉得这个并没有解决大多数人的理解.所以我觉查看了js高

Adaboost新理解

Adaboost有几个难点: 1.弱分类器的权重怎么理解? 误差大的弱分类器权重小,误差小的弱分类器权重大.这很好理解.在台湾大学林轩田老师的视频中,推导说,这个权值实际上貌似梯度下降,权值定义成1/2ln((1-ε)/ε),实际上是有梯度下降,求梯度取最陡得到. 2.弱分类器怎么通常选啥 可以选树(不选全树) 3.有了第一个弱分类器模型后,怎么导出其他的弱分类器,怎么理解正确分类的权值变小,错误分类的权值变大? 形象上讲,忽略正确分类的,重视错误分类的. 从数学上讲,我们希望各个分类器越不相同

java-重新理解:“instance = new Singleton();”

在Java指令中创建对象和赋值操作是分开进行的,也就是说instance = new Singleton(); 语句是分两步执行的.但是JVM并不保证这两个操作的先后顺序,也就是说有可能JVM会为 新的Singleton实例分配空间,然后直接赋值给instance成员,然后再去初始化这个Singleton实例. 这在单态设计模式的多线程中,会经常出错. 当一个A线程,执行完该语句但没有初始化这个实例,而B线程调用了该实例,则会报错. 单例模式使用内部类来维护单例的实现,JVM内部的机制能够保证当

新理解 range

aliens=[] for alien_number in range(30): new_alien={'color':'green','point':5,'speed':'slow'} aliens.append(new_alien) 创建一个列表,用range循环30次,将新的字典添加进空列表中,range原来可以或者说应该这么用