草庐IT

1万字说明白Receiver Operating curve(ROC) 受试者操作特征曲线

公众号_python风控模型 2023-03-28 原文
概述

AUC(area under the curve)是机器学习领域中一种常见且重要的模型评估指标,用于计算二元分类器效率的方法AUC表示ROC(receiver operator characteristic)曲线下的面积,即AUC = ROC 曲线下面积

 

起源-雷达救了英国

很多统计指标来源于战争。ROC最早用于英国雷达分辨鸟或德国飞机的概率。二战期间首次用于分析雷达有效性。在早些时候雷达,有时很难从飞机上分辨出一只鸟。英国人率先使用 ROC 曲线来优化他们依赖雷达进行判别的方式在来袭的德国飞机和鸟类之间。

二战时英国的反***战备是英国为了抵抗可能发生的德军***,而于1940年和1941年间做出的准备。在这期间,英国政府建立了英国国土警卫队,并在英国全境修建了防御工事。在缺少重型装备的情况下,英军需要将手中的一切可用资源运用到极致。

由于在不列颠空战中战败,德国为***英国而开展的海狮计划遭到了无限期的推延。英国也就没能在其本土与德国陆军展开战斗。今天,英国修建的大部分防御工事都已消失,只有一些加固过的混凝土工事还较常见。

自不列颠空战正式打响开始,英国皇家空军和海军航空兵就肩负起了保卫英国领空的任务。它们与德国空军进行了激烈的战斗以使英国上空的制空权不被敌人夺走,而制空权是纳粹德国非常看重的。

如果德国空军成功地占领了英国领空,那么英国空军剩余的极少数飞机将会转移到英格兰东南部的机场。英国人在撤走时会将机场的跑道破坏掉。这些飞机将会与英国皇家海军一起打击德国舰队。尽管还未夺取制空权的德国空军比英国空军强大,但英国战机也有优势,它们大多是在己方领空执行任务,而每次任务的持续时间也会比跨越海峡飞来的德军战机长。

英国空军将所有还能飞的战斗机都调用了起来。而战斗机以外的其它飞机都被改装成了轰炸机,一些新飞行员也会开着拥有简易投弹装置的教练机对德占区进行轰炸。[11]

二战开始之前,英国在英格兰南部修建了一套雷达系统,其中有三座雷达站从1937年起开始运行。[12][13]尽管德军高层对英国此举有所怀疑,但德国空军并没有做出实际行动。后来正是这些雷达站挽救了英国。

 

 

ROC接收器操作特性曲线特点 

  • 接收器操作特性(ROC) 曲线:由分类算法的一个参数参数化的二维曲线。

  • 可以通过在 y 轴上绘制 TPR 和在 x 轴上绘制 TNR 来获得 ROC 曲线。

  • AUC 用于衡量模型的区分能力。AUC 始终介于 0 和 1 之间,AUC的值越接近1,表示模型区分能力越好,AUC的值越接近0,模型区分能力越差,AUC的值等于0.5,表示模型区分能力是随机的

  • 在风控金融领域,大数据残缺不全,垃圾数据较多,模型AUC值一般在0.6-0.7之间。如果模型AUC值能超过0.8表示,模型非常优秀,我在多年金融风控建模项目中,很少看到模型AUC能超过0.8.

ROC图如下

 

用sensitivity和specificity解释ROC图

AUC 始终介于 0 和 1 之间,AUC的值越接近1,表示模型区分能力越好,AUC的值越接近0,模型区分能力越差,AUC的值等于0.5,表示模型区分能力是随机的

 

ROC曲线的阈值问题

sensitivity=黑色竖线右边红色像素面积/红色像素总面积

false positive=黑色竖线右边绿色像素面积/蓝色像素总面积

 

当我们对不同的阈值进行遍历时,产生的 (假阳率, 真阳率) 坐标点也就可以连成ROC曲线,进而求得曲线下面积AUC。

 

TP,FP,FN,TN与ROC关系图如下

蓝色表示不接受,红色表示接受。我们用软件对两种颜色重叠不同位置时,观察左上角ROC曲线变化和阈值变化。

 

 

 

 

 

 

 这种roc很难区别分类,两种颜色基本重叠,AUC值接近0.5

 

 

 

ROC应用

ROC应用1

我们必须对属于 A 类或 B 类的产品进行分类。 
 

 

ROC 应用2

面试,(+)表示适合工作的候选人,(-)表示不适合工作的候选人。 

 

 

ROC 应用3

ROC曲线常用于医疗领域,特别是判断仪器检测效果。ROC能很容易地查出任意界限值时的对疾病的识别能力。

选择最佳的诊断界限值。ROC曲线越靠近左上角,试验的准确性就越高。最靠近左上角的ROC曲线的点是错误最少的最好阈值,其假阳性和假阴性的总数最少。

两种或两种以上不同诊断试验对疾病识别能力的比较。在对同一种疾病的两种或两种以上诊断方法进行比较时,可将各试验的ROC曲线绘制到同一坐标中,以直观地鉴别优劣,靠近左上角的ROC曲线所代表的受试者工作最准确。亦可通过分别计算各个试验的ROC曲线下的面积(AUC)进行比较,哪一种试验的 AUC最大,则哪一种试验的诊断价值最佳。

 

所有术语计算公式如下

TP,FN,TN,FP,FN

TP(True Positive)=A类产品的数量,属于A类产品。 

FN (False Negative) = A 类产品的数量,属于 B 类产品。 

TN (True Negative) = B 类产品的数量,属于 B 类产品。 

FP(False Positive)= B类产品的数量,属于A类产品。

FP = N-TP;// 其中数字 N 是 A 类产品的数量

FN = M-TN;// 其中 number M 是 B 类产品的数量

 

为了让大家更好立即,附上英文释义

TP (True Positive) = number of Class A products, which are classified as Class A products. 

FN (False Negative) = number of Class A products, which are classified as Class B products. 

TN (True Negative) = number of Class B products, which are classified as Class B products. 

FP (False Positive) = number of Class B products, which are classified as Class A products.

 

FP = N-TP;   // where number N is the number of class A type products

FN = M-TN; // where number M is the number of class B type products

 

混淆矩阵

混淆矩阵中横轴通常表示真实类别(1和0分别对应真、伪),纵轴表示预测类别(1和0分别对应阳、阴),对真实类别和真实类别进行组合,便组成混淆矩阵:

更详细混淆矩阵图如下

混淆矩阵里概念比较相似,相同指标有不同术语,为了让大家更好立即回血矩阵,我附上混淆矩阵英文图谱,如下图:

 

准确率Accuracy

准确性衡量测试对 TPR 和 TNR 的预测效果。按照混淆矩阵中的符号形式,准确率的公式可以表示为:

准确率是一种非常常见的模型效能度量指标,然而当面对样本不平衡问题时,其度量效果会产生问题。比如在一个总样本中,1类样本占90%,0类样本占10%,样本严重不平衡,此时我们只需要将全部样本预测为1即可得到高达90%的准确率。

 

精准率Precision

精准率(Precision)又称查准率,代表所有被预测为1的样本中实际为1的概率,其公式如下:

 

召回率Recall

召回率(Recall)又称查全率,代表在所有实际为1的样本中被预测为1的概率,其公式如下:

F1分数

通常情况下,查准率和查全率会随着阈值的变化而变化,我们希望查准率和查全率同时都非常高,然而这两个指标实际是此消彼长的关系,无法做到双高。对此,我们就需要一个新的指标 —— F1分数。F1分数同时考虑了查准率和查全率,通过选取最高的F1来确定分类阈值,F1公式如下:

 

ROC/AUC 相关指标介绍

为了了解ROC/AUC,我们需要了解几个指标。灵敏度sensitivity和召回率recall是同一个指标,不同场景术语叫法不一样。

灵敏度

灵敏度衡量正确识别的阳性比例

 

特异度specificity

特异度衡量被正确识别的阴性比例

 

真阳率 (TPR)

真阳率和召回率一样,代表在所有实际为1的样本中被预测为1的概率,其公式如下:

 

假阳率 (FPR)

假阳率代表在所有实际为0的样本中被预测为1的概率,其公式如下:

 

 

 

指标间关系

用条件概率理解混合矩阵容易得多

sensitivity:真阳性条件下,测试也是阳性

specificity:真阴性条件下,测试也是阴性

FALSE positive:真阴性条件下,测试却是阳性

FALSE negative:真阳性条件下,测试却是阴性

只要全部认定为阳性,敏感度就是百分之百,但说明调高敏感度同时,假阳性概率也会随之提高

当全部认定为阳性,阴性数量为0,specificity=0,  假阳性1-specificity=1,假阳性也是最高。

敏感性和假阳性率呈现正比例

敏感性和准确性(阳性预测率)呈现反比例

ROC和PRC曲线说明:敏感性(召回率)不是越高越好,敏感性太高,假阳性率也会上升(会损失掉一些好客户)。

敏感性太高,阳性预测率(准确率)会下降。

 

各指标计算举例

 

 

ROC的Excel计算逻辑

ROC可以用Excel来计算,具体计算逻辑举例如下图:

 

 

ROC 曲线的python代码

在 Python 中计算 ROC 曲线scikit-learn 使计算 ROC 曲线变得非常容易。但首先要做的是:要制作 ROC 曲线,我们首先需要一个分类模型进行评估。对于这个例子,我将制作一个合成数据集,然后使用 scikit-learn 构建一个逻辑回归模型。

#原创公众号(python风控模型) from sklearn.datasets import make_classification from sklearn.linear_model import LogisticRegression X, y = make_classification(n_samples=10000, n_features=10, n_classes=2, n_informative=5) Xtrain = X[:9000] Xtest = X[9000:] ytrain = y[:9000] ytest = y[9000:] clf = LogisticRegression() clf.fit(Xtrain, ytrain) 好的,现在我们有了我们的模型,我们可以计算 ROC 曲线了。 非常简单——从 scikit-learn 导入 roc_curve,传入我们测试集中的实际 y 值以及这些相同记录的预测概率。结果将产生您的 FPR 和 TPR。 将它们传递给 ggplot 和 BAM! 你有一个漂亮的 ROC 曲线。

from sklearn import metrics import pandas as pd from ggplot import * preds = clf.predict_proba(Xtest)[:,1] fpr, tpr, _ = metrics.roc_curve(ytest, preds) df = pd.DataFrame(dict(fpr=fpr, tpr=tpr)) ggplot(df, aes(x='fpr', y='tpr')) +\ geom_line() +\ geom_abline(linetype='dashed') 最后计算AUC:

auc = metrics.auc(fpr,tpr) ggplot(df, aes(x='fpr', ymin=0, ymax='tpr')) +\ geom_area(alpha=0.2) +\ geom_line(aes(y='tpr')) +\ ggtitle("ROC Curve w/ AUC=%s" % str(auc)) 我们得到 0.900。回顾之前,AUC 在 0 和 1 之间有界,所以这很不错。

ROC 曲线的R代码

在 R 中计算 ROC 曲线在 R 中制作 ROC 曲线也很容易。 我强烈推荐使用 ROCR 包。 它为您完成了所有艰苦的工作,并制作了一些非常漂亮的图表。对于模型,我们将构建一个分类器,该分类器使用逻辑回归模型来预测钻石数据集中的记录是否超过 2400 美元。

 

  • #原创公众号(python风控模型) library(ggplot2) diamonds$is_expensive <- diamonds$price > 2400 is_test <- runif(nrow(diamonds)) > 0.75 train <- diamonds[is_test==FALSE,] test <- diamonds[is_test==TRUE,] summary(fit <- glm(is_expensive ~ carat + cut + clarity, data=train)) Using ROCR, making the charts is relatively simple. library(ROCR) prob <- predict(fit, newdata=test, type="response") pred <- prediction(prob, test$is_expensive) perf <- performance(pred, measure = "tpr", x.measure = "fpr") # I know, the following code is bizarre. Just go with it. auc <- performance(pred, measure = "auc") auc <- auc@y.values[[1]] roc.data <- data.frame(fpr=unlist(perf@x.values), tpr=unlist(perf@y.values), model="GLM") ggplot(roc.data, aes(x=fpr, ymin=0, ymax=tpr)) + geom_ribbon(alpha=0.2) + geom_line(aes(y=tpr)) + ggtitle(paste0("ROC Curve w/ AUC=", auc))
  • 版权声明:文章,经许可,不得抄袭。遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
  •  
  • 欢迎学习更多风控建模相关知识《python金融风控评分卡模型和数据分析微专业课》
    https://edu.51cto.com/sd/f2e9b

     

 

 

 

 

有关1万字说明白Receiver Operating curve(ROC) 受试者操作特征曲线的更多相关文章

  1. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  2. spring.profiles.active和spring.profiles.include的使用及区别说明 - 2

    转自:spring.profiles.active和spring.profiles.include的使用及区别说明下文笔者讲述spring.profiles.active和spring.profiles.include的区别简介说明,如下所示我们都知道,在日常开发中,开发|测试|生产环境都拥有不同的配置信息如:jdbc地址、ip、端口等此时为了避免每次都修改全部信息,我们则可以采用以上的属性处理此类异常spring.profiles.active属性例:配置文件,可使用以下方式定义application-${profile}.properties开发环境配置文件:application-dev

  3. ruby - 如何使用 Selenium Webdriver 根据 div 的内容执行操作? - 2

    我有一个使用SeleniumWebdriver和Nokogiri的Ruby应用程序。我想选择一个类,然后对于那个类对应的每个div,我想根据div的内容执行一个Action。例如,我正在解析以下页面:https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=puppies这是一个搜索结果页面,我正在寻找描述中包含“Adoption”一词的第一个结果。因此机器人应该寻找带有className:"result"的div,对于每个检查它的.descriptiondiv是否包含单词“adoption

  4. ruby-on-rails - 如何处理 Grape 中特定操作的过滤器之前? - 2

    我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?

  5. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

  6. ruby - cucumber 特征和步骤定义 - 2

    我是Cucumber测试的新手。我创建了两个特征文件:events.featurepartner.feature并将我的步骤定义放在step_definitions文件夹中:./step_definitions/events.rbpartner.rbCucumber似乎在所有.rb文件中查找步骤信息。有没有办法限制该功能查看特定的步骤定义文件?我之所以要这样做,是因为即使我使用了--guess标志,我也会遇到不明确的匹配错误。我之所以要这样做,有以下几个原因。我正在测试CMS,并希望在不同的功能中测试每种不同的内容类型(事件和合作伙伴)。事件.特征Feature:AddpartnerA

  7. ruby - 在 Ruby 中是否有一种惯用的方法来操作 2 个数组? - 2

    a=[3,4,7,8,3]b=[5,3,6,8,3]假设数组长度相同,是否有办法使用each或其他一些惯用方法从两个数组的每个元素中获取结果?不使用计数器?例如获取每个元素的乘积:[15,12,42,64,9](0..a.count-1).eachdo|i|太丑了...ruby1.9.3 最佳答案 使用Array.zip怎么样?:>>a=[3,4,7,8,3]=>[3,4,7,8,3]>>b=[5,3,6,8,3]=>[5,3,6,8,3]>>c=[]=>[]>>a.zip(b)do|i,j|c[[3,5],[4,3],[7,6],

  8. ruby-on-rails - 如何让 Rails View 返回其关联的操作名称? - 2

    我有一个非常简单的Controller来管理我的Rails应用程序中的静态页面:classPagesController我怎样才能让View模板返回它自己的名字,这样我就可以做这样的事情:#pricing.html.erb#-->"Pricing"感谢您的帮助。 最佳答案 4.3RoutingParametersTheparamshashwillalwayscontainthe:controllerand:actionkeys,butyoushouldusethemethodscontroller_nameandaction_nam

  9. ruby-on-rails - ActiveRecord:除非另有说明,否则在保存之前使所有文本字段都调用 strip - 2

    多年来,我在各种网站上遇到过各种问题,用户在字符串和文本字段的开头/结尾放置空格。有时这些会导致格式/布局问题,有时会导致搜索问题(即搜索顺序看起来不对,但实际上并非如此),有时它们实际上会使应用程序崩溃。我认为这会很有用,而不是像我过去所做的那样放入一堆before_save回调,向ActiveRecord添加一些功能以在保存之前自动调用任何字符串/文本字段上的.strip,除非我告诉它不是,例如do_not_strip:field_x,:field_y或类定义顶部的类似内容。在我去弄清楚如何做到这一点之前,有没有人看到更好的解决方案?明确一点,我已经知道我可以做到这一点:befor

  10. ruby-on-rails - 特征未注册 : attribute name - 2

    完成这个有困难。我正在使用seed.rb+factory_girl来使用rakedb:seed填充数据库。(我知道固定装置存在,但我想以这种方式完成,这只是一个示例,数据库将填充复杂的关联对象。)我的种子.rb:require'factory_girl_rails'["QM","CDC","SI","QS"].eachdo|n|FactoryGirl.create(:grau,nome:n)end还有我的/factories/graus.rbFactoryGirl.definedofactory:graudonomeendend但是当我运行时:rakedb:seed我得到:rakeab

随机推荐