一文完全理解模型ks指标含义并画出ks曲线(包含代码和详细解释)
KS(Kolmogorov-Smirnov):KS用于模型风险区分能力进行评估, 指标衡量的是好坏样本累计分部之间的差值。
好坏样本累计差异越大,KS指标越大,那么模型的风险区分能力越强。
ks=max(Cum.BiBadtotal−Cum.GiGoodtotal)ks = max(\frac{Cum. B_i}{Bad_{total}} - \frac{Cum.G_i}{Good_{total}}) ks=max(BadtotalCum.Bi−GoodtotalCum.Gi)
上面是ks的简单介绍,相信大家看了这几句话和一个公式,肯定还是不懂ks到底是个什么。我也是研究了一下,终于搞清楚了ks的具体计算方式。搞清楚了计算方式后,ks的含义自然就清楚了。
下面我会详细讲解实现方法,相信如果你看完本文章,肯定可以理解ks。以下内容均为个人纯手打,难免有些疏漏,如有错误,请大家指出。
本文会介绍两种计算ks的方法:
第一种是我自己手动写代码实现的,可以帮助你理解ks含义;
第二种是sklearn模块里面的roc_curve函数计算,通过第一种方法理解了ks后,实际应用中使用第二种方法,更方便。
ks的计算流程
话不多说,先看代码,后面会解释代码,顺便解释清楚ks含义。
import numpy as np
import pandas as pddef ks(df, y_true, y_pre, num=10, good=0, bad=1):# 1.将数据从小到大平均分成num组df_ks = df.sort_values(y_pre).reset_index(drop=True)df_ks['rank'] = np.floor((df_ks.index / len(df_ks) * num) + 1)df_ks['set_1'] = 1# 2.统计结果result_ks = pd.DataFrame()result_ks['group_sum'] = df_ks.groupby('rank')['set_1'].sum()result_ks['group_min'] = df_ks.groupby('rank')[y_pre].min()result_ks['group_max'] = df_ks.groupby('rank')[y_pre].max()result_ks['group_mean'] = df_ks.groupby('rank')[y_pre].mean()# 3.最后一行添加total汇总数据result_ks.loc['total', 'group_sum'] = df_ks['set_1'].sum()result_ks.loc['total', 'group_min'] = df_ks[y_pre].min()result_ks.loc['total', 'group_max'] = df_ks[y_pre].max()result_ks.loc['total', 'group_mean'] = df_ks[y_pre].mean()# 4.好用户统计result_ks['good_sum'] = df_ks[df_ks[y_true] == good].groupby('rank')['set_1'].sum()result_ks.good_sum.replace(np.nan, 0, inplace=True)result_ks.loc['total', 'good_sum'] = result_ks['good_sum'].sum()result_ks['good_percent'] = result_ks['good_sum'] / result_ks.loc['total', 'good_sum']result_ks['good_percent_cum'] = result_ks['good_sum'].cumsum() / result_ks.loc['total', 'good_sum']# 5.坏用户统计result_ks['bad_sum'] = df_ks[df_ks[y_true] == bad].groupby('rank')['set_1'].sum()result_ks.bad_sum.replace(np.nan, 0, inplace=True)result_ks.loc['total', 'bad_sum'] = result_ks['bad_sum'].sum()result_ks['bad_percent'] = result_ks['bad_sum'] / result_ks.loc['total', 'bad_sum']result_ks['bad_percent_cum'] = result_ks['bad_sum'].cumsum() / result_ks.loc['total', 'bad_sum']# 6.计算ks值result_ks['diff'] = result_ks['bad_percent_cum'] - result_ks['good_percent_cum']# 7.更新最后一行total的数据result_ks.loc['total', 'bad_percent_cum'] = np.nanresult_ks.loc['total', 'good_percent_cum'] = np.nanresult_ks.loc['total', 'diff'] = result_ks['diff'].max()result_ks = result_ks.reset_index()return result_ks
接下来看一下生成的 result_ks
结果,如下图,代码和结果结合起来看更容易理解:
讲解之前先说一下函数中各个参数的含义。
df
是pandas的DataFrame表,表中必须包含两列:预测值和真实值。
预测值即模型预测的结果,一般为范围在0~1之间的概率值;
真实值是实际的好坏用户的label,一般为0或1,代表着好用户或者坏用户。
本文中使用的df
前几列如下图。
y_true
是真实值在df表中的列名,此处为“label”;
y_pre
是预测值在df表中的列名,此处为“score”;
num
是需要分组的数量,具体含义后面会说;
good
和bad
是真实值中0和1代表的含义,如果好用户用0表示,那么good=0
、bad=1
,反之亦然。
下面按照代码中的注释分步讲解。
- 先将
df
按照score
列从小到大进行排序。排序完成后,如果num=10
,则将所有的样本划分为10个区间,新增rank
列,此列对每个区间从上到下使用1~10个数字标记。为了方便之后求和统计,新增set_1列,此列所有值均为1; - 对
score
列进行统计,group_sum
为每个区间的个数,相应的max
、min
、mean
为区间的最大值、最小值和平均值; - 在最后新增一行
total
,进行整列数据的统计; - 好用户统计,
good_sum
列中计算了每个区间的好用户数量,good_percent
列中则是每个区间的好用户数占全部好用户数的比例。最重要的是计算good_percent_cum
,计算各行的累加值占好用户数量的比例,不理解的话建议搜索cumsum
好好看看。其实这里计算的good_percent_cum
就是就是在不同阈值下的TPR
,true positive rate; - 坏用户统计,与好用户计算方法一致,
bad_percent_cum
计算的是不同阈值下的FPR
,false positive rate; diff
列中保存bad_percent_cum - good_percent_cum
的结果, 两列的差值的最大值即为ks;- 最后更新一下
total
中的内容。
以上就是ks的全部计算步骤,其实结果生成那么多列,大部分都是帮助理解数据结构,真正用于计算的也就是good_percent_cum
、bad_percent_cum
这两列,ks其实也是max(df['good_percent_cum'] - df['bad_percent_cum'])
。ks越大,表示计算预测值的模型区分好坏用户的能力越强。
ks值 | 含义 |
---|---|
> 0.3 | 模型预测性较好 |
0,2~0.3 | 模型可用 |
0~0.2 | 模型预测能力较差 |
< 0 | 模型错误 |
ks曲线绘制
import matlibplot.pyplot as plt
import seaborn as sns
sns.set()def ks_curve(df, num=10):# 防止中文乱码plt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=Falseks_value = df['diff'].max()# 获取绘制曲线所需要的数据x_curve = range(num + 1)y_curve1 = [0] + list(df['bad_percent_cum'].values[:-1])y_curve2 = [0] + list(df['good_percent_cum'].values[:-1])y_curve3 = [0] + list(df['diff'].values[:-1])# 获取绘制ks点所需要的数据df_ks_max = df[df['diff'] == ks_value]x_point = [df_ks_max['rank'].values[0], df_ks_max['rank'].values[0]]y_point = [df_ks_max['bad_percent_cum'].values[0], df_ks_max['good_percent_cum'].values[0]]# 绘制曲线plt.plot(x_curve, y_curve1, label='bad', linewidth=2)plt.plot(x_curve, y_curve2, label='good', linewidth=2)plt.plot(x_curve, y_curve3, label='diff', linewidth=2)# 标记ksplt.plot(x_point, y_point, label='ks - {:.2f}'.format(ks_value), color='r', marker='o', markerfacecolor='r', markersize=5)plt.scatter(x_point, y_point, color='r')plt.legend()plt.show()return ks_value
运行下面代码,得到ks曲线图
result_ks = ks(df, 'label', 'score')
ks_curve(result_ks)
roc_curve函数实现
上面说了计算ks其实只用得到关键的两列,而这两列可以通过sklearn.metrics
中函数roc_curve
直接获取。
下面代码中,ks_value
即为ks值。
from sklearn.metrics import roc_curvefpr, tpr, thresholds= roc_curve(df.label, df.score)
ks_value = max(abs(fpr-tpr))# 画图,画出曲线
plt.plot(fpr, label='bad')
plt.plot(tpr, label='good')
plt.plot(abs(fpr-tpr), label='diff')
# 标记ks
x = np.argwhere(abs(fpr-tpr) == ks_value)[0, 0]
plt.plot((x, x), (0, ks_value), label='ks - {:.2f}'.format(ks_value), color='r', marker='o', markerfacecolor='r', markersize=5)
plt.scatter((x, x), (0, ks_value), color='r')
plt.legend()
plt.show()
最后,讲另外一种画法。
ks_value = max(abs(fpr-tpr))
# 画图,画出曲线
plt.plot(fpr, tpr)
plt.plot([0,1], [0,1], linestyle='--')
# 标记ks
x = np.argwhere(abs(fpr-tpr) == ks_value)[0, 0]
plt.plot([fpr[x], fpr[x]], [fpr[x], tpr[x]], linewidth=4, color='r')
# plt.scatter((x, x), (0, ks_value), color='r')
plt.xlabel('False positive', fontsize=20)
plt.ylabel('True positive', fontsize=20)
plt.show()
X轴的含义
看两张ks图,X轴的含义其实是区间序号,第一张图划分了10个区间,所以X轴是0~10。
第二个sklearn会根据你的数据大小进行划分区间,这里我使用的数据量比较大,划分了600个区间计算的,所以X轴范围是0~600。
本文引用:
神秘的KS值和GINI系数
一文完全理解模型ks指标含义并画出ks曲线(包含代码和详细解释)相关推荐
- AIGC周报|30秒定制一个文生图模型;60美元让AI玩转《我的世界》;手机版“文生图”模型:2秒不到出一张图
AIGC(AI Generated Content)即人工智能生成内容.近期爆火的 AI 聊天机器人 ChatGPT,以及 Dall·E 2.Stable Diffusion 等文生图模型,都属于 A ...
- 分类模型-评估指标(2):ROC曲线、 AUC值(ROC曲线下的面积)【只能用于二分类模型的评价】【不受类别数量不平衡的影响;不受阈值取值的影响】【AUC的计算方式:统计所有正负样本对中的正序对】
评价二值分类器的指标很多,比如precision.recall.F1 score.P-R曲线等.但这些指标或多或少只能反映模型在某一方面的性能.相比而言,ROC曲线则有很多优点,经常作为评估二值分类器 ...
- 【机器学习】--模型评估指标之混淆矩阵,ROC曲线和AUC面积
一.前述 怎么样对训练出来的模型进行评估是有一定指标的,本文就相关指标做一个总结. 二.具体 1.混淆矩阵 混淆矩阵如图: 第一个参数true,false是指预测的正确性. 第二个参数true,p ...
- 干货 | 一文完全理解AUC-ROC曲线
点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 来源: https://towardsdatascience.co ...
- 模型评估指标(Confusion Matrix、ROC、AUC)
文章目录 1.选择合适的模型评估指标的依据 2.混淆矩阵(Confusion Matrix) 2.1 模型整体效果:准确率 2.2 捕捉少数类:精确率(Precision).召回率(Recall)和F ...
- SVC模型评估指标与ROC曲线
目录 1.解决二分类SVC中的样本不均衡问题 1.1 概述 1.2 SVC参数class_weight 1.3 参数class_weight的使用 2.SVC模型评估指标 2.1 混淆矩阵(Confu ...
- (8) 支持向量机(下)(模型评估指标、ROC曲线)
文章目录 1 二分类SVC的进阶 1.1 参数C的理解进阶 1.2 二分类SVC中的样本不均衡问题:重要参数class_weight 2 SVC的模型评估指标 2.1 混淆矩阵 2.1.1 模型整体效 ...
- 机器学习模型评估指标总结!
↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过 Datawhale干货 作者:太子长琴,Datawhale优秀学习者 本文对机器学习模型评估指标 ...
- 【机器学习基础】非常详细!机器学习模型评估指标总结!
作者:太子长琴,Datawhale优秀学习者 本文对机器学习模型评估指标进行了完整总结.机器学习的数据集一般被划分为训练集和测试集,训练集用于训练模型,测试集则用于评估模型.针对不同的机器学习问题(分 ...
最新文章
- Nature对数千篇论文提出质疑:隐藏的细菌蛋白为自然界的“电网”提供动力
- 微软宣布 Visual Studio 2019 将于4月2日正式发布
- unity之中级工程师
- 江西省2019计算机二级报名日期,2020年3月江西计算机等级报名时间、报名入口【2019年12月18日-27日】...
- java.lang.IllegalArgumentException: invalid comparison: java.time.LocalDateTime and java.lang.String
- nginx搭建文件服务器脚本,基于docker搭建nginx文件服务器的方法步骤
- webstorm更换主题后快捷键失效
- c 获取char*的长度_C/C++编程笔记:C语言字符串比较函数,超详细,值得收藏!...
- 键盘迷情--Treo650 VS P50 【ZZ】
- griddata三维空间插值
- 共有76款 WIKI系统开源软件
- Git commit --amend 修改提交信息
- JOI2014Final 飞天鼠
- vm虚拟机开启蓝屏问题
- android oppo 闪退,为什么oppo手机老是闪退?三个原因分析帮你解决问题
- 程序员界改BUG“神”发明,学会10分钟搞定一个BUG
- ios 图表_在ios应用中实现蜘蛛网图表
- Flutter 全局弹窗
- 一首同音叠字诗“石室诗士施氏”
- 利用python进行excel格式处理并关联
热门文章
- 程序员人人都会遇到的“画饼”,一招教你破解
- QTP10破解时,运行mgn-mqt82.exe 就提示已停止工作
- php时区设置为prc还是错误,关于php时区时间错误问题的解决,以及Unix时间戳转换工具...
- uni-app map 地图
- 一维卷积的意义和二维卷积(图像处理)的简单理解
- 什么是交叉检验(K-fold cross-validation)
- STM32智能门锁之调试步进电机
- vue跳转链接(新页签)
- Java基础案例 | 第二弹(持续更新...xdm冲啊)
- 个人网站实现收款的几种方式