学习笔记219— ROC曲线概念和具体的coding实现(超详细)
一、什么是ROC曲线
对于分类模型,常见的模型评价指标有精确率、召回率以及ROC曲线等,看名字不太好理解,下面来仔细分析。
混淆矩阵:
表中结果分为四类:
真正样 TP(True Positive):预测为正样本的正样本,预测正确体现在True,预测值体现在Positive。
假负样 FN(False Negative):预测为负样本的正样本,预测错误体现在False,预测值体现在Negative。
真负样 TN(True Negative):预测为负样本的负样本。
假负样 FP(False Negative):预测为正样本的负样本。
以此为基础可以得出下列指标:
真正率 TPR(True Positive Rate)又称“敏感性”、“灵敏性”、“召回率”或者“查全率”(Sensitivity):预测正确的正样本/正样本总数
假负率 FNR(False Negative Rate):预测错误的正样本/正样本总数
真负率TNR(True Negative Rate)又称特异性(Specificity):预测正确的负样本/负样本总数
假正率FPR(False Positive Rate):预测错误的负样本/负样本总数
最后由混淆矩阵能得到下列指标:
准确率(Accuracy):分类正确的样本数/样本总数
错误率(Error):分类错误的样本数/样本总数
精确率(Precision):
又称查准率,能够体现模型分类为正样本的数量中分类正确的比例,分母靠预测值决定。
正样本的预测数/被预测为正样本的数量(包含错误预测为正样本的负样本)
召回率Recall(敏感度):
又称查全率,即上述的TPR。
分类正确的样本书/正样本的数量
那么按照西瓜书中的解释,精确率就是挑出的西瓜中有多少比例是好瓜,召回率就是所有好瓜中有多少比例被挑出来。
F-Measure是Precision和Recall加权调和平均
当参数a=1时,就是最常见的F1:
也就是:F1 = 2 * 召回率 * 准确率/ (召回率+准确率)
E值 是Precision和Recall加权平均值,b>1表示更重视P
不妨举这样一个例子:
某池塘有1400条鲤鱼,300只虾,300只鳖。现在以捕鲤鱼为目的。撒一大网,逮着了700条鲤鱼,200只虾,100只鳖。那么,这些指标分别如下:
不妨看看如果把池子里的所有的鲤鱼、虾和鳖都一网打尽,这些指标又有何变化:
由此可见,准确率是评估捕获的成果中目标成果所占得比例;召回率,顾名思义,就是从关注领域中,召回目标类别的比例;而F值,则是综合这二者指标的评估指标,用于综合反映整体的指标。
总结:
精确率和召回率是一对矛盾的度量,如果希望精确率提高,那么可以让模型阈值提高,减少FP数量,但是同样会降低TP数量因为要求更严格了,会导致召回率降低,因为有一些本可以预测为正样本的样本被阈值卡在了外面。故而精确率precision又称为查准率,突出的就是一个准字,召回率recall又称查全率,突出一个全字。
ROC曲线
ROC的全称是Receiver Operating Characteristic Curve,中文名字叫“受试者工作特征曲线”
首先是由二战中的电子工程师和雷达工程师发明的,用来侦测战场上的敌军载具(飞机、船舰),也就是信号检测理论。之后很快就被引入了心理学来进行信号的知觉检测。此后被引入机器学习领域,用来评判分类、检测结果的好坏。
从图中可以看出,ROC曲线的横坐标为FPR(假正率),纵坐标为TPR(真正率)
纵轴:真正率(击中率)true positive rate ,TPR,称为灵敏度。所有实际正例中,正确识别的正例比例。
横轴:假正率(虚报率)false positiverate, FPR,称为(1-特异度)。所有实际负例中,错误得识别为正例的负例比例。
举个简单的例子:
有10张图片其中猫8张(Positive) 狗2张(Negative),通过模型产生了10个预测结果,其中预测为猫的有9张,狗1张。那么TP=8 FN=0 TN=1 FP=1 即TPR=1 FPR=0.5 (0.5,1)就是ROC曲线上的一个点。
如何通过ROC曲线判断模型好坏?
有了ROC曲线需要对模型有一个定量的分析,这里就需要引入AUC(Area under ROC Curve)面积,AUC指的就是ROC曲线下方的面积,计算AUC只需要沿着ROC的横轴做积分即可,真实场景下ROC曲线一般在y=x直线的上方,所以AUC的取值一般在0.5~1之间,AUC值越大说明模型的性能越好。
如何ROC曲线?
当我们改变模型的阈值,预测结果中的TP FN TN FP都会相应的改变,即每一个阈值都会有一组(TPR, FPR)对应,ROC曲线就是不断的移动分类器的阈值来产生曲线上的关键点。
举个例子:(https://www.zhihu.com/question/22844912/answer/246037337)
图中是一个二分类模型的输出结果,一共20个样本,输出的概率就是模型判定为正样本的概率,第二列是真实label
如果我们指定阈值为0.9,那么只有第一个样本会被定为正样本,其他样本都定位负样本,可以算出TPR=0.1 FRP=0,所以(0,0.1)是ROC曲线上的一点,这样继续改变阈值(截断点)就可以得到更多的关键点,最后连接所有的关键点就能得到ROC曲线。
二、如何通过代码画出ROC曲线?
现在我们知道ROC曲线上的一组组(FPR,TPR)值是通过改变阈值得到,那么具体在程序中是如何实现的?
首先我们需要了解sklearn.metrics中的roc_curve方法(metrics是度量、指标,curve是曲线)roc_curve(y_true, y_score, pos_label=None, sample_weight=None, drop_intermediate=None)
roc_curve函数中参数含义:
y_true:简单来说就是label,范围在(0,1)或(-1,1)的二进制标签,若非二进制则需提供pos_label。
y_score:模型预测的类别概率值。
pos_label:label中被认定为正样本的标签。若label=[1,2,2,1]且pos_label=2,则2为positive,其他为negative。
sample_weight:采样权重,可选择一部分来计算。
drop_intermediate:可以去掉一些对ROC曲线不好的阈值,使得曲线展现的性能更好。
返回值:(tpr,fpr,thershold)
tpr:根据不同阈值得到一组tpr值。
fpr:根据不同阈值的到一组fpr值,与tpr一一对应。(这两个值就是绘制ROC曲线的关键)
thresholds:选择的不同阈值,按照降序排列。
有了以上参数和返回值的基础,举个例子来验证一下:
输出结果:
分析:
代码中故意将label设置为非二进制,展示了pos_label这个参数的用处,如果pos_label设置错误程序会报错,大家可以自己尝试,y_label是标签,y_pre和y_labe相对应是模型预测为label的概率值,当pos_label=2则标签为2的看作正样本,标签为1的看做负样本。
我们都知道ROC曲线是需要通过改变阈值来获取一组组(fprp, tpr),那么roc_curve方法中是如何选取阈值?
从输出结果可以看到,第三列代表返回值thersholds记录的就是roc_curve所选取的阈值,其阈值就是将y_pre降序排列并依次选取,如果选取的阈值对fpr和tpr值无影响则忽略,输出结果中没有记录阈值为0.8时情况。
需要注意的是,输出结果第一行therholds=1.9,这个值很奇怪,乍一看不知道为什么会出现这个值。这里我们阅读sklearn官网的原文对therholds这个参数的解释:Decreasing thresholds on the decision function used to compute fpr and tpr. thresholds[0] represents no instances being predicted and is arbitrarily set to max(y_score) + 1.
thresholds[0] 表示没有任何预测的实例 并且被设置为max(y_score) + 1,这样就知道1.9其实是y_pre中最大的0.9 +1,再简单点来说,第一行其实就是ROC曲线的起点(0,0)。
到这里roc_curve方法的用法应该已经非常清楚了,画ROC曲线之前还有一个评估模型优劣重要的值AUC需要得到。
算AUC的方法很简单,使用auc方法即可。
最后就是画出ROC曲线了,完整代码如下:
输出结果:
三、python实现LOOCV并画ROC曲线(以sklearn中的iris数据为例)
用的是Adaboost算法
代码如下:
<图中链接:https://scikit-learn.org/stable/modules/classes.html#module-sklearn.metrics>
参考链接:https://blog.csdn.net/AugustMe/article/details/94717440
https://blog.csdn.net/hesongzefairy/article/details/104302499
https://blog.csdn.net/hesongzefairy/article/details/104295431
https://scikit-learn.org/stable/auto_examples/model_selection/plot_roc_crossval.html#sphx-glr-auto-examples-model-selection-plot-roc-crossval-py
https://scikit-learn.org/stable/auto_examples/model_selection/plot_roc.html#sphx-glr-auto-examples-model-selection-plot-roc-py
https://scikit-learn.org/stable/modules/generated/sklearn.metrics.roc_curve.html?highlight=roc_curve#sklearn.metrics.roc_curve
https://www.zhihu.com/question/22844912/answer/246037337
https://my.oschina.net/u/3702502/blog/1841599
https://blog.csdn.net/jiandanjinxin/article/details/51840829
https://blog.csdn.net/xiahouzuoxin/article/details/43165253
https://blog.csdn.net/zuyuanzhu/article/details/21516397
https://scikit-learn.org/stable/modules/classes.html#module-sklearn.metrics
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2019-06-18 学习笔记82—如何单独卸载office onenote
2019-06-18 学习笔记81—matlab通过界面按钮查看回调函数