当前位置:   article > 正文

模型评估方法:ROC曲线与KS曲线_ks曲线和roc曲线

ks曲线和roc曲线

本文代码及数据集来自《Python大数据分析与机器学习商业案例实战》

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

一、ROC曲线

如果把假警报率理解为代价的话,那么命中率就是收益,所以也可以说在阈值相同的情况下,希望假警报率(代价)尽可能小,命中率(收益)尽可能高,该思想反映在图形上就是ROC曲线尽可能地陡峭。曲线越靠近左上角,说明在相同的阈值条件下,命中率越高,假警报率越低,模型越完善。
在这里插入图片描述

#混淆矩阵的Python代码实现
from sklearn.metrics import confusion_matrix
m = confusion_matrix(y_test, y_pred)  # 传入预测值和真实值
print(m)
  • 1
  • 2
  • 3
  • 4

m的打印结果是一个2行2列的二维数组,其中第1行为实际分类为0的数量,第2行为实际分类为1的数量;第1列为预测分类为0的数量,第2列为预测分类为1的数量。可以通过如下代码为表格添加行列索引。

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

运行结果:
在这里插入图片描述

#计算命中率
from sklearn.metrics import classification_report
print(classification_report(y_test, y_pred))
  • 1
  • 2
  • 3

运行结果:
在这里插入图片描述

# 1.计算ROC曲线需要的假警报率(fpr)、命中率(tpr)及阈值(thres)
from sklearn.metrics import roc_curve
fpr, tpr, thres = roc_curve(y_test, y_pred_proba[:,1])
  • 1
  • 2
  • 3

roc_curve()函数返回的是一个含有3个元素的元组,其中默认第1个元素为假警报率,第2个元素为命中率,第3个元素为阈值,所以这里将三者分别赋给变量fpr(假警报率)、tpr(命中率)、thres(阈值)。此时获得的fpr、tpr、thres为3个一维数组,通过如下代码可以将三者合并成一个二维数据表。

# 2.查看假警报率(fpr)、命中率(tpr)及阈值(thres)
a = pd.DataFrame()
a['阈值'] = list(thres)
a['假警报率'] = list(fpr)
a['命中率'] = list(tpr)
print(a.head())
print(a.tail())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

运行结果:
在这里插入图片描述
表格第1行的阈值表示只有当一个客户被预测流失的概率≥193%,才判定其会流失,但因为概率不会超过100%,所以此时所有客户都不会被预测为流失,此时命中率和假警报率都为0。可见这个阈值其实没有什么意义,那么为什么还要设置它呢?这个阈值是roc_curve()函数的默认设置,官方文档中对它的介绍是:“thresholds[0]represents no instances being predicted and is arbitrarily setto max(y_score)+1.”。这句话的意思是第一个阈值没有含义,其往往设置为最大阈值(本案例中为0.9303)+1,以保证没有任何记录被选中。
下面来解释这些阈值。在测试样本中,对预测分类为1的概率进行排序,使用sort_values()函数,并设置ascending参数为False进行降序排列,代码如下。

a = pd.DataFrame(y_pred_proba, columns=['分类为0概率', '分类为1概率'])
a = a.sort_values('分类为1概率', ascending=False)
a.head(15)
  • 1
  • 2
  • 3

在这里插入图片描述
可以看到,序号326的样本其分类为1的概率最高,为0.930369,这个概率就是之前提到的阈值,分类为1的概率小于该阈值的样本都被列为分类0,大于等于该阈值的样本都被列为分类1。
再举个例子,序号49的样本其分类为1的概率为0.867342,在之前的表格中,它是除1.930369外第二大的阈值。序号49的样本在本表格中排在第12位,因此大于等于该概率的共有12个样本,这12个样本会被列为分类1,其余样本则被列为分类0。

# 3.绘制ROC曲线
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.plot(fpr, tpr)
plt.title('ROC曲线')
plt.xlabel('FPR')
plt.ylabel('TPR')
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

运行结果:
在这里插入图片描述

# 4.求出模型的AUC值
from sklearn.metrics import roc_auc_score
score = roc_auc_score(y_test, y_pred_proba[:,1])
print(score)
  • 1
  • 2
  • 3
  • 4

AUC(Area Under Curve)被定义为ROC曲线下与坐标轴围成的面积,显然这个面积的数值不会大于1。又由于ROC曲线一般都处于y=x这条直线的上方,所以AUC的取值范围在0.5和1之间。AUC越接近1.0,检测方法真实性越高;等于0.5时,则真实性最低,无应用价值。结果为0.8103854528908967,可见模型预测效果还是不错。

二、KS曲线

区别于ROC曲线将假警报率(FPR)作为横坐标,将命中率(TPR)作为纵坐标,KS曲线将阈值作为横坐标,将命中率(TPR)与假警报率(FPR)之差作为纵坐标,如下图所示。
在这里插入图片描述
和ROC曲线一样,除了可视化的图形外,还需要一个可以量化的指标来衡量模型预测效果,与ROC曲线对应的是AUC值,而与KS曲线对应的则是KS值,KS值就是KS曲线的峰值。
一般情况下,我们希望模型有较大的KS值,因为较大的KS值说明模型有较强的区分能力。不同取值范围的KS值的含义如下:

  • KS值小于0.2,一般认为模型的区分能力较弱;
  • KS值在[0.2,0.3]区间内,模型具有一定区分能力;
  • KS值在[0.3,0.5]区间内,模型具有较强的区分能力。

但KS值也不是越大越好,如果KS值大于0.75,往往表示模型有异常。在商业实战中,KS值处于[0.2,0.3]区间内就已经算是挺不错的了。

from sklearn.metrics import roc_curve
fpr, tpr, thres = roc_curve(y_test, y_pred_proba[:,1])

a = pd.DataFrame()  # 创建一个空DataFrame
a['阈值'] = list(thres)
a['假警报率'] = list(fpr)
a['命中率'] = list(tpr)
a.head()

plt.plot(thres[1:], tpr[1:])
plt.plot(thres[1:], fpr[1:])
plt.plot(thres[1:], tpr[1:] - fpr[1:])
plt.xlabel('threshold')
plt.legend(['tpr', 'fpr', 'tpr-fpr'])
plt.gca().invert_xaxis() 
plt.show()

print(max(tpr - fpr))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

运行结果:
在这里插入图片描述

#获取KS值对应的阈值
a['TPR-FPR'] = a['命中率'] - a['假警报率']
a.head()

print(max(a['TPR-FPR'])) #获取KS值法二

#通过如下代码可以获取KS值对应的行,从表中可以看到该KS值对应的阈值
print(a[a['TPR-FPR'] == max(a['TPR-FPR'])])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/279299
推荐阅读
相关标签
  

闽ICP备14008679号