第六课:综合应用
评估指标
【原理】KS与KS曲线
作者 : 老饼 日期 : 2022-06-26 03:56:44 更新 : 2022-12-05 21:03:35
本站原创文章,转载请说明来自《老饼讲解-机器学习》ml.bbbdata.com


KS与AUC类似,也是专门针对逻辑回归这种输出概率(或评分)的二分类模型设计的模型效果评估指标

本文我们详细介绍什么是KS的含义,用途



   01. KS值    


本节介绍KS的计算公式及如何理解KS的意义



   KS的原始定义公式与意义   


KS与AUC类似,也是专门针对逻辑回归这种输出概率(或评分)的二分类模型设计的模型效果评估指标
KS的公式定义如下:

 
 
 

 
 
其中:
TPR(True PositiveRate) 查全率
 : 是 1 的样本,被检查出来的概率    
FPR(False PositiveRate)虚警率 : 是 0 的样本,被误检成1的概率     
 
 如果把TPR看作收益,FPR看作成本,则KS为利润最大值



   KS计算公式   


在实际中,KS更常用的是如下计算公式,会更方便计算:



可以记忆为切点  以下,类0的占比与类1占比差距的最大值
✍️补充
 KS的计算公式可由原始定义公式推导得到,
推导过程如下

 





    02. KS曲线    


本节介绍KS曲线是什么


   KS曲线   


将TPR、FPR、(TPR-FPR)三条曲线画在一起,并标出KS,就是KS曲线
 
   说明: x轴代表thresholds(阈值切割点)




    03. KS的计算方法及实例代码    


本节讲解KS的具体计算方法,从而更形象更具体地了解KS是如何计算出来的


    KS计算方法   


方式1.通过计算公式计算KS
按p排序,统计0,1标签累计占比,两类标签占比之差最大者,就是KS
 0标签累计占比计算方法:预测值<p的0标签个数/0标签总个数
 
 
方式2.通过定义公式(TPR、FPR)计算KS
 
先计算FPR和TPR,TPR与FPR的之差最大者,就是KS
✍️说明
用python代码计算KS时,可以直接调用roc_curve函数获取fpr,tpr,然后用定义公式计算KS
如果是用excel或sql等无法调包直接算得fpr、tpr时,则用计算公式会更简便



下面通过两个实例,分别讲解两种计算方式



   实例讲解1-计算公式的方式   


下面以计算公式的计算方法,计算一个例子
 
 
现已获得模型的预测值P和真实标签如下
 
 


则KS的计算流程如下:

  ✍️ 需要注意的是,如上例所示,
KS所对应的阈值应是下一行的0.55,而不是0.846所对应的行的0.44
这是因为上述表格统计占比时用的是"<=",而公式中需要的是"<"
✍️补充 KS模糊计算方法
数据量过大时,为节省计算量,可采用以下分组统计方法:
1.按p排序,并按大小分组,例如分为5组                
2.统计每组的(0,1)标签占比、累计占比和累计占比差异   
3.占比差异最大者,即为KS值    
                                     



   实例讲解2-定义公式(Fpr-Tpr)的方式   


在python代码实现时,由于sklearn的roc_curve函数提供了fpr和tpr,
因此,更倾向于用定义公式计算更为简洁,
下面展示一个用python调用sklearn的roc_curve函数计算KS和绘制KS曲线的代码
 
 
   python计算KS及画KS曲线代码如下
# -*- coding: utf-8 -*-
"""
ks计算DEMO
"""

from sklearn.metrics import roc_curve
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

#需要计算KS的数据
test_dict = {'score':[0.71,0.612,0.127,0.330,0.428,0.889,0.188,0.229,0.889,0.022,
                      0.43,0.952,0.622,0.11,0.22,0.33,0.44,0.55,0.66,0.77,0.88,0.99]
             ,'label':[1,0,0,0,0,1,0,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1]}
df = pd.DataFrame(test_dict)

# 计算fpr, tpr
fpr, tpr, thresholds= roc_curve(df.label, df.score)  

# 计算KS: abs(fpr - tpr)最大者就是KS
ks_value = max(abs(fpr-tpr))

# 画图,画出曲线
thresholds[0] = max(test_dict['score'])+0.01    # 修正thresholds的最大值
plt.figure(figsize=(10, 5))
plt.plot(thresholds,fpr, label='fpr')
plt.plot(thresholds,tpr, label='tpr')
plt.plot(thresholds,abs(fpr-tpr), label='diff')
plt.xlabel('thresholds')

# 标记ks
idx = np.argwhere(abs(fpr-tpr) == ks_value)[0, 0]
ks_thresholds   = thresholds[idx]
plt.plot((ks_thresholds, ks_thresholds), (fpr[idx], tpr[idx]), 
         label='ks - {:.2f}'.format(ks_value), 
         color='r', marker='o', markerfacecolor='r', markersize=5)
plt.scatter((ks_thresholds, ks_thresholds), (fpr[idx], tpr[idx]), color='r')
plt.legend()
plt.show()
print('阈值:',ks_thresholds)
print('KS:',ks_value)
运行结果如下:
阈值 : 0.55                          
KS   : 0.8461538                

  End  







联系老饼