KS曲线和ROC曲线在本质上是相同的,同样关注命中率(TPR)和假警报率(FPR),希望命中率(TPR)尽可能高,即尽可能揪出潜在流失客户,同时也希望假警报率(FPR)尽可能低,即不要把未流失客户误判为流失客户。区别于ROC曲线将假警报率(FPR)作为横坐标,将命中率(TPR)作为纵坐标,KS曲线将阈值作为横坐标,将命中率(TPR)与假警报率(FPR)之差作为纵坐标,如下图所示。
和ROC曲线一样,除了可视化的图形外,还需要一个可以量化的指标来衡量模型预测效果,与ROC曲线对应的是AUC值,而与KS曲线对应的则是KS值。KS值的计算公式如下。
KS=max(TPR-FPR)
KS值就是KS曲线的峰值。具体来说,每一个阈值都对应一个(TPR-FPR)值,那么一定存在一个阈值,使得在该阈值条件下,(TPR-FPR)值最大,那么此时的(TPR-FPR)值便称为KS值。例如,上图中当阈值等于40%时,命中率(TPR)为80%,假警报率(FPR)为25%,所以(TPR-FPR)值为55%,该值是所有阈值条件下最大的(TPR-FPR)值,因此,这个模型的KS值为55%。
更通俗易懂的话来说,该模型在阈值为40%时能尽可能地识别坏人,并尽可能地不误伤好人,此时命中率(TPR)减去假警报率(FPR)的差值为55%,即该模型的KS值。
用KS曲线评估客户流失预警模型
与ROC曲线的绘制相同,可通过如下代码求出在不同阈值下的假警报率(FPR)和命中率(TPR),从这一点也可以看出KS曲线和ROC曲线其实是同根同源的。
from sklearn.metrics import roc_curvefpr, tpr, thres = roc_curve(y_test, y_pred_proba[:,1])
通过同样的代码整理此时的阈值、假警报率、命中率。
a = pd.DataFrame()a['阈值'] = list(thres)a['假警报率'] = list(fpr)a['命中率'] = list(tpr)
整理结果见下表(为了美观,将数据保留4位小数)
现在已知不同阈值下的假警报率和命中率,用Matplotlib库相关知识点绘制KS曲线,代码如下。
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-frp'])plt.gca().invert_xaxis()plt.show()
第1~3行代码绘制的曲线均以阈值为横坐标,而纵坐标分别为命中率、假警报率及两者之差。因为表格第1行中的阈值大于1,无意义,会导致绘制出的图形不美观,所以通过切片的方式将第1行剔除,其中thres[1:]、tpr[1:]、fpr[1:]都表示从第2个元素开始绘制。
第4行代码给x轴加上“threshold”的标签。
第5行代码用于添加图例。
第6行代码反转x轴,即把阈值从大到小排序再绘制KS曲线,之前讲解原理时也提到过这一点。具体来说,先用gca()函数(gca代表get current axes)获取坐标轴信息,再用invert_xaxis()函数反转x轴。
绘制的KS曲线如下图所示。
通过如下代码则可以快速求出KS值。打印输出该KS值,结果为0.4744,在[0.3,0.5]区间内,因此,该模型具有较强的区分能力。
max(tpr - fpr)
