大学生课程|统计基础与python分析6|主流的评估方法:ROC曲线和KS曲线(免费下载所有课程材料)

news2024/9/29 23:29:47

目录

1 ROC曲线

2.查看混淆矩阵

3.实战评估股票客户流失预警模型

4.阈值的取值方法

5.KS曲线与KS值

6.获取KS值对应的阈值

7.获取KS值


对于二分类模型来说,主流的评估方法有ROC曲线和KS曲线两种方法

1 ROC曲线

之前已经获得了模型的准确度为79.77%,但是这个准确度并不可靠

在商业实战中,更关心下面两个指标

命中率(真正率)

True Positive Rate(TPR)

TPR=TP/ (TP+ FN)

假警报率(假正率)

False Positive Rate(FPR)

FPR= FP / (FP + TN)

TP、FP、TN、FN的含义如下表所示,这个表也叫作混淆矩阵:

1(预测流失)

0(预测不流失)

合计

1(实际流失)

True Positive(TP)

正确肯定

False Negative(FN)

漏报

TP + FN

0(实际不流失)

False Positive(FP)

虚报

True Negative(TN)

正确否定

FP + TN

7000客户中有2000个流失,5000个不流失客户,假设模型预测所有客户都不会流失,如下表所示,那么模型的假警报率(FPR)为0,即没有误伤一个未流失客户,但是此时模型的命中率(TPR)也为0,即没有揪出一个流失客户。

命中率计算的便是在所有实际流失的人中,预测为流失的比例,也称真正率或召回率;

而假警报率则是计算在所有实际没有流失的人当中,预测为流失的比例,也称假正率。

一个优秀的客户违约预测模型,我们希望命中率(TPR)尽可能的高,即能尽可能地揪出坏人,同时也希望假警报率(FPR)能尽可能的低,即不要误伤好人。

然而这两者往往成正相关性,因为一旦当调高阈值,比如认为违约率超过90%的才认定为流失,那么会导致假警报率很低,但是命中率也很低。

而如果降低阈值的话,比如认为违约率超过10%就认定为流失,那么命中率就会很高,但是假警报率也会很高。

因此为了衡量一个模型的优劣,数据科学家根据不同阈值下的命中率和假警报率绘制了如下的曲线图,称之为ROC曲线:

ROC曲线的横坐标为假警报率(FPR),其纵坐标为命中率(TPR),在某一个阈值条件下,我们希望命中率能尽可能的高,而假警报率尽可能的低。

举例来说,某一检测样本总量为100,其中流失客户为20人,当阈值为20%的时候,即流失概率超过20%的时候即认为客户会流失时,模型A和模型B预测出来的流失客户都是15人。

如果模型A预测流失的15人中有10人的确流失,有5人属于误判,那么命中率达10/20=50%,此时假警报率为5/80=6.25%。

如果模型B预测流失的15人中只有5人的确流失,有10人属于误判,那么其命中率为5/20=25%,假警报率为10/80=12.5%。

此时模型A的命中率是模型B的2倍,假警报率是模型B的一半,因此我们认为模型A是一个较优的模型。

如果把假警报率理解为代价的话,那么命中率就是收益,所以也可以说在相同阈值的情况下,我们希望假警报率(代价)尽量小的情况下,命中率(收益)尽量的高,该思想反映在图形上就是这个曲线尽可能的陡峭,曲线越靠近左上角说明在同样的阈值条件下,命中率越高,假警报率越小,模型越完善。换一个角度来理解,一个完美的模型是在不同的阈值下,假警报率(FPR)都接近于0,而命中率(TPR)接近于1,该特征反映在图形上,就是曲线非常接近(0,1)这个点,也即曲线非常陡峭。

2.查看混淆矩阵

customer_warning_ROC.py

# 查看混淆矩阵

from sklearn.metrics import confusion_matrix as cm

m = cm(y_test, y_pred) # 代入实际值和预测值,前者为实际值,后者为预测值

print(m)

显示:

[[940 101]

 [219 149]]

其中第一行为实际分类为0的数量,第二行为实际分类为1的数量;第一列为预测分类为0的数量,第二列为预测分类为1的数量。

# 增加表头

a = pd.DataFrame(m, index=['0(实际不流失)', '1(实际流失)'], columns=['0(预测不流失)', '1(预测流失)'])

print(a)

显示:

          0(预测不流失)  1(预测流失)

0(实际不流失)       940      101

1(实际流失)         219      149

由此可见

0(预测不流失)

1(预测流失)

合计

0(实际不流失)

True Negative(TN)

正确否定,940

False Positive(FP)

虚报,93

FP + TN

1033

1(实际流失)

False Negative(FN)

漏报,219

True Positive(TP)

正确肯定,149

TP + FN

368

命中率(真正率)

True Positive Rate(TPR)

TPR=TP/ (TP+ FN)=149/368=40.50%

假警报率(假正率)

False Positive Rate(FPR)

FPR= FP / (FP + TN)=93/1033=9.00%

这里的TPR和FPR都是基于50%阈值情况下的

通过如下代码打印查看命中率情况,而无需手动计算

# 通过如下代码打印查看命中率情况

from sklearn.metrics import classification_report as cr

print(cr(y_test, y_pred)) # 代入实际值和预测值,前者为实际值,后者为预测值

显示:

              precision    recall  f1-score   support

           0       0.81      0.90      0.85      1041

           1       0.60      0.40      0.48       368

    accuracy                           0.77      1409

   macro avg       0.70      0.65      0.67      1409

weighted avg       0.75      0.77      0.76      1409

recall表示召回率(相当于命中率)

0行的0.90,表示假警报预测准确度,可以理解为(1-假警报率),与手工计算的一致

1行的0.40,表示命中率,与手工计算的一致

support表示样本数

accuracy表示整体准确度,与以下代码计算的一致:

from sklearn.metrics import accuracy_score as accs

score = accs(y_pred, y_test)

print('预测准确度:' + str(score))

这两个指标重要度不如命中率(TPR)和假警报率(FPR)

3.实战评估股票客户流失预警模型

数值比较上可以使用AUC值来衡量模型的好坏,AUC值(Area Under Curver)指在曲线下面的面积,该面积的取值范围通常为0.5到1,0.5表示随机判断,1则代表完美的模型。

在商业实战中:

AUC值能达到0.75以上就已经可以接受了

如果能达到0.85以上,则为非常不错的模型了

# 引入roc_curve()函数

from sklearn.metrics import roc_curve

# 代入测试集和预测的流失概率。:表示所有行,1表示第1列

# roc_curve()函数返回三个值,均为数组

# 第一个元素为假警报率

# 第二个元素为命中率

# 第三元素为阈值

fpr, tpr, thres = roc_curve(y_test, y_pred_proba[:, 1])

# 做成表格显示

b = pd.DataFrame()

b['阈值'] = list(thres)

b['假警报率'] = list(fpr)

b['命中率'] = list(tpr)

print(b)

显示:

           阈值      假警报率       命中率

0    1.932647  0.000000  0.000000

1    0.932647  0.000000  0.002717

2    0.917318  0.000000  0.010870

3    0.881889  0.000961  0.010870

4    0.858468  0.000961  0.021739

..        ...       ...       ...

443  0.033706  0.912584  0.994565

444  0.033667  0.912584  0.997283

445  0.033095  0.915466  0.997283

446  0.033000  0.915466  1.000000

447  0.022619  1.000000  1.000000

[448 rows x 3 columns]

注意:

print(b.head())

print(b.tail())

显示前五个、后五个

随着阈值降低,命中率在上升、假警报率也在上升

注意点:

1、第一行的阈值表示只有当一个客户被预测流失的概率>=193%,才判定其会流失,但因为概率不会超过100%,所以此时不会有人被判定为流失,即所有人都不会被预测为流失,那么命中率和假警报率都为0,所以第一行的阈值其实没有什么意义。

那为什么还要设置它呢,这个是roc_curve函数的默认设置,下面是它的官方介绍:“thresholds[0] represents no instances being predicted and is arbitrarily set to max(y_score) + 1.”

其中文含义是第一个阈值没有含义,其往往设置为最大的阈值(本案例中为0.932647)+1,保证没有任何记录被选中。

2、表格第2行数据表示只有当一个客户被预测流失的概率大于等于93.26%,才判定其会流失。其他行类似。

# 用户绘图方式呈现不同阈值下的假警报率和命中率

import matplotlib.pyplot as plt

plt.plot(fpr, tpr)  # 用plot()函数绘制折线图

plt.title('ROC')  # 添加标题

plt.xlabel('FPR')  # 添加x轴标签

plt.ylabel('TPR')  # 添加y轴标签

plt.show()

显示:


# 快速求模型AUC值

from sklearn.metrics import roc_auc_score

score = roc_auc_score(y_test,y_pred_proba[:, 1])

print(score)

显示:

0.789382596165894

AUC值打印出来为:0.789382596165894,可以说预测效果还是不错的

4.阈值的取值方法

本质就是分类为1 的概率

# 利用sort_values()函数,对'分类为1的概率'排序

# ascending参数为False表示降序

temp = pd.DataFrame(y_pred_proba, columns=['分类为0的概率', '分类为1的概率'])

temp = temp.sort_values('分类为1的概率', ascending=False)

print(temp)

显示:

       分类为0的概率   分类为1的概率

651   0.067353  0.932647

768   0.075344  0.924656

1386  0.082178  0.917822

954   0.082682  0.917318

329   0.118111  0.881889

...        ...       ...

204   0.976082  0.023918

665   0.976140  0.023860

1377  0.976499  0.023501

958   0.976726  0.023274

839   0.977381  0.022619

[1409 rows x 2 columns]

以651项,阈值为0.932647为例

表示概率大于等于0.932647,才归类为1

5.KS曲线与KS值

KS曲线和ROC曲线的本质其实是相同的,同样关注命中率(TPR)和假警报率(FPR),希望命中率(TPR)尽可能的高,即能尽可能地揪出潜在流失客户,同时也希望假警报率(FPR)能尽可能的低,即不要把未流失客户误判断为流失客户。

区别于ROC曲线将假警报率(FPR)作为横轴,命中率(TPR)作为纵轴,KS曲线的横坐标为阈值,其纵坐标为命中率(TPR)与假警报率(FPR)之差,如下图所示:

需要一个可以量化的指标来衡量模型预测效果,与ROC曲线对应的是AUC值,而与KS曲线相对应的就是KS值。KS值的定义如下所示:

例如上图中当阈值等于40%时,命中率(TPR)为80%,假警报率(FPR)为25%,所以(TPR-FPR)为55%,该值是所有不同阈值条件下(TPR-FPR)中最大的,因此此时这个模型的KS值就是55%

通常来说,我们希望模型有较大的KS值,较大的KS值说明模型有较强的区分能力,其处在不同范围的模型的含义如下所示:

KS值小于0.2,一般认为模型区分能力较弱。

KS值在[0.2,0.3]区间内,模型具有一定区分能力。

KS值在[0.3,0.5]区间内,模型具有较强的区分能力。

但KS值也不是越大越好,如果KS值大于0.75,往往表示模型有异常。其实在真正的生产实际中,KS值处于[0.2,0.3]区间类,就已经挺不错了。

customer_warning_KS.py

# 绘制KS曲线

import matplotlib.pyplot as plt

# 表格的第0行都不要,所以1:表示

plt.plot(thres[1:], tpr[1:])  # 绘制tpr曲线

plt.plot(thres[1:], fpr[1:])  # 绘制fpr曲线

plt.plot(thres[1:], tpr[1:] - fpr[1:])  # 绘制tpr与fpr之差曲线

plt.xlabel('threshold')  # 横坐标加threshold标签

plt.legend(['tpr', 'fpr', 'tpr-fpr'])  # 添加图例

# 反转x轴,把阈值从大到小排序再绘制KS曲线

# gca()函数,get current axes,获取坐标轴信息

# invert_xaxis()反转x轴

plt.gca().invert_xaxis()

plt.show()

显示:


如果没有plt.gca().invert_xaxis(),显示:

阈值变成从小到大了

# 求KS值

print(max(tpr - fpr))

显示:

0.44002422419913967

阈值在[0.3, 0.5]区间,具有较强的区分能力

6.获取KS值对应的阈值

# 算出每一个阈值对应的(TPR-FPR)值

b['TPR-FPR'] = b['命中率'] - b['假警报率']

print(b)

显示:

     阈值      假警报率   命中率   TPR-FPR

0    1.932647  0.000000  0.000000  0.000000

1    0.932647  0.000000  0.002717  0.002717

2    0.917318  0.000000  0.010870  0.010870

3    0.881889  0.000961  0.010870  0.009909

4    0.858468  0.000961  0.021739  0.020779

..        ...       ...       ...       ...

443  0.033706  0.912584  0.994565  0.081981

444  0.033667  0.912584  0.997283  0.084699

445  0.033095  0.915466  0.997283  0.081817

446  0.033000  0.915466  1.000000  0.084534

447  0.022619  1.000000  1.000000  0.000000

[448 rows x 4 columns]

7.获取KS值

# 获取KS值

print(max(b['TPR-FPR']))

显示:

0.44002422419913967

和之前计算一致

# 选取KS值对应的阈值及相关信息

print(b[b['TPR-FPR'] == max(b['TPR-FPR'])])

# max(b['TPR-FPR']),计算出KS,假设名为KS

# 从b['TPR-FPR']中,挑出值为KS的项,假设项名为k

# 显示b[k]

显示:

           阈值      假警报率      命中率   TPR-FPR

306  0.224835  0.320845  0.76087  0.440024

逻辑回归模型,在银行信贷场景中的信用评分卡模型中,经常使用

此系列为基础学习系列,请自行学习,课程资源免费获取地址:

https://download.csdn.net/download/weixin_68126662/88866689

久菜盒子工作室:大数据科学团队/全网可搜索的久菜盒子工作室 我们是:985硕博/美国全奖doctor/计算机7年产品负责人/医学大数据公司医学研究员/SCI一区2篇/Nature子刊一篇/中文二区核心一篇/都是我们 主要领域:医学大数据分析/经管数据分析/金融模型/统计数理基础/统计学/卫生经济学/流行与统计学/ 擅长软件:R/python/stata/spss/matlab/mySQL

团队理念:从零开始,让每一个人都得到优质的科研教育

点点关注,一起成长,会变更强哦

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1472939.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【USENIX论文阅读】Day2

Birds of a Feather Flock Together: How Set Bias Helps to Deanonymize You via Revealed Intersection Sizes("物以类聚:集合偏差如何帮助去匿名化——通过揭示交集大小) Xiaojie Guo, Ye Han, Zheli Liu, Ding Wang, Yan Jia, Jin L…

高级光线传播与高级外观建模

一.高级光线传播 1、无偏的 ①有偏VS无偏 蒙特卡洛估计出的结果的期望永远是对的 eg:PT中不管有多少样本,期望都是定积分的值 有偏的:估计出的结果的期望和积分的值不一样 一个特殊情况(一致的):极限定…

【web APIs】1、(学习笔记)有案例!

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、概念二、使用步骤1.获取DOM对象2.操作元素内容3.属性修改3.1.常用属性修改3.2.控制样式属性3.3.操作类名(className) 操作CSS3.4.操作表单元素属性3.5.自定…

Mysql常见函数和用法(重点)

where子句中经常使用的运算符 -- 查询总分大于200分的所有同学 select * from student2 where (chineseenglishmath)>200; -- 查询math大于60 并且(and)id大于4的学生成绩 select * from student2 where math>60 and id>4; -- 查询英语成绩大于语文成绩的同学 select …

面试总结之JVM入门

文章目录 🐒个人主页🏅JavaEE系列专栏📖前言:🎀你为什么要学习JVM?🎀JVM的作用 🎀JVM的构成(5大类)🏨1.类加载系统🐕类什么时候会被加…

《Docker 简易速速上手小册》第2章 容器和镜像(2024 最新版)

文章目录 2.1 理解 Docker 容器2.1.1 重点基础知识2.1.2 重点案例:使用 Docker 运行 Python 应用2.1.3 拓展案例 1:Docker 中的 Flask 应用2.1.4 拓展案例 2:Docker 容器中的数据分析 2.2 创建与管理 Docker 镜像2.2.1 重点基础知识2.2.2 重点…

k8s(5)

目录 使用Kubeadm安装k8s集群: 初始化操作: 每台主从节点: 升级内核: 所有节点安装docker : 所有节点安装kubeadm,kubelet和kubectl: 修改了 kubeadm-config.yaml,将其传输给…

网络攻防之网络扫描

目录 1、进行ping扫描 2、进行TCP SYN扫描 3、进行TCP全连接扫描 4、进行FIN扫描 5、进行UDP扫描 6、进行操作系统扫描 7、进行主机全面扫描 8、对网络号进行扫描 环境配置拓扑图: 实验前准备 查看kali和靶机的ip地址信息: 查看两台主机是否能互…

vue中循环多个li(表格)并获取对应的ref

有种场景是这样的 <ul><li v-for"(item,index) in data" :key"index" ref"???">{{item}}</li> </ul> //key值在项目中别直接用index&#xff0c;最好用id或其它关键值const data [1,2,3,4,5,6]我想要获取每一个循环并…

数据结构知识点总结-线性表(3)-双向链表定义、循环单链表、、循环双向链表、静态链表、顺序表与链表的比较

双向链表定义 单链表结点中只有一个指向其后继的指针&#xff0c;这使得单链表只能从头结点依次顺序地向后遍历。若要访问某个结点的前驱结点&#xff08;插入、删除操作时&#xff09;&#xff0c;只能从头开始遍历&#xff0c;访问后继结点的时间复杂度为 O(1) &#xff0c; …

详解java类型转换

✨✨ 所属专栏&#xff1a; Java基石&#xff1a;深入探索Java核心基础✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; 引言 在Java编程中&#xff0c;类型转换是将一个数据类型的值转换为另一个数据类型的过程。Java中的类型转换主…

Django学习笔记-ModelForm使用(完全依赖)

1.创建模型 ,code,name,sex,entrydate 2.模型映射 python manage.py makemigrations myapp01,python manage.py migrate 3.创建模型表单,继承forms.ModelForm,Meta:元数据,models需引入,fields填写引用的模型变量 4.创建testModelForm.html,添加urls 5.views编写testmodelfo…

前端sql条件拼接js工具

因为项目原因&#xff0c;需要前端写sql&#xff0c;所以弄了一套sql条件拼接的js工具 ​ /*常量 LT : " < ", LE : " < ", GT : " > ", GE : " > ", NE : " ! ", EQ : " ", LIKE : " like &qu…

字典树入门

//本题是一道字典树的模板题 //字典树是一种高效率存储多个字符串的数据结构 //其每个结点的权值代表以该结点结尾的字符串的数量,每条边存储一个字符 //从根结点开始,按某一路径遍历到某一结点,即得到一种字符串,其个数等于当前结点存储的数值 //如从根结点开始,依次走过abc三…

【iOS ARKit】ARWorldMap

ARWorldMap 用于存储 ARSession 检测扫描到的空间信息数据&#xff0c;包括地标&#xff08;Landmark&#xff09;、特征点&#xff08;Feature Point&#xff09;、平面&#xff08;Plane&#xff09;等&#xff0c;以及使用者的操作信息&#xff0c;如使用者添加的 ARAnchor …

【Vue】组件通信组件通信

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;JVM ⛺️稳中求进&#xff0c;晒太阳 组件通信 组件通信&#xff0c;就是指组件与组件之间的数据传递 组件的数据是独立的&#xff0c;无法直接访问其他组件的数据想用其他组件的数据--&…

【深度学习】Pytorch教程(十三):PyTorch数据结构:5、张量的梯度计算:变量(Variable)、自动微分、计算图及其可视化

文章目录 一、前言二、实验环境三、PyTorch数据结构1、Tensor&#xff08;张量&#xff09;1. 维度&#xff08;Dimensions&#xff09;2. 数据类型&#xff08;Data Types&#xff09;3. GPU加速&#xff08;GPU Acceleration&#xff09; 2、张量的数学运算1. 向量运算2. 矩阵…

景联文科技:引领战场数据标注服务,赋能态势感知升级

自21世纪初&#xff0c;信息化战争使战场环境变得更为复杂和难以预测&#xff0c;持续涌入的海量、多样化、多来源和高维度数据&#xff0c;加大了指挥员的认知负担&#xff0c;使其需要具备更强的数据处理能力。 同时&#xff0c;计算机技术和人工智能技术的飞速发展&#xff…

EMQX Enterprise 5.5 发布:新增 Elasticsearch 数据集成

EMQX Enterprise 5.5.0 版本已正式发布&#xff01; 在这个版本中&#xff0c;我们引入了一系列新的功能和改进&#xff0c;包括对 Elasticsearch 的集成、Apache IoTDB 和 OpenTSDB 数据集成优化、授权缓存支持排除主题等功能。此外&#xff0c;新版本还进行了多项改进以及 B…

Gemma谷歌(google)开源大模型微调实战(fintune gemma-2b)

Gemma-SFT Gemma-SFT(谷歌, Google), gemma-2b/gemma-7b微调(transformers)/LORA(peft)/推理 项目地址 https://github.com/yongzhuo/gemma-sft全部weights要用fp32/tf32, 使用fp16微调十几或几十的步数后大概率lossnan;(即便layer-norm是fp32也不行, LLaMA就没有这个问题, …