KS(Kolmogorov-Smirnov)值越大,表示模型能夠將正、負客戶區分開的程度越大。KS值的取值范圍是[0,1]
ks越大,表示計算預測值的模型區分好壞用戶的能力越強。
| ks值 | 含義 |
|---|---|
| > 0.3 | 模型預測性較好 |
| 0,2~0.3 | 模型可用 |
| 0~0.2 | 模型預測能力較差 |
| < 0 | 模型錯誤 |
通常來講,KS>0.2即表示模型有較好的預測准確性。
ks求解方法:
ks需要TPR和FPR兩個值:真正類率(true positive rate ,TPR), 計算公式為TPR=TP/ (TP+ FN),刻畫的是分類器所識別出的 正實例占所有正實例的比例。另外一個是假正類率(false positive rate, FPR),計算公式為FPR= FP / (FP + TN),計算的是分類器錯認為正類的負實例占所有負實例的比例。KS=max(TPR-FPR)。其中:
TP:真實為1且預測為1的數目
FN:真實為1且預測為0的數目
FP:真實為0的且預測為1的數目
TN:真實為0的且預測為0的數目
一句話概括:
KS曲線是兩條線,其橫軸是閾值,縱軸是TPR(上面那條)與FPR(下面那條)的值,值范圍[0,1] 。兩條曲線之間之間相距最遠的地方對應的閾值,就是最能划分模型的閾值。
計算步驟:
1. 按照分類模型返回的概率升序排列 ,也可以直接是數據,根據某一閾值判斷為1或0即可
2. 把0-1之間等分N份,等分點為閾值,計算TPR、FPR (可以將每一個都作為閾值)
3. 對TPR、FPR描點畫圖即可 (以10%*k(k=1,2,3,…,9)為橫坐標,分別以TPR和FPR的值為縱坐標,就可以畫出兩個曲線,這就是K-S曲線。)
KS值即為Max(TPR-FPR)
Python代碼實現:
#-*- coding:utf-8 -*-
#自己實現計算ks與調包
from sklearn.metrics import roc_curve
import matplotlib.pyplot as plt
import seaborn as sns
#%matplotlib inline
#%config InlineBackend.figure_format = 'retina'
plt.rcParams['font.sans-serif'] = ['SimHei'] # 中文字體設置-黑體
plt.rcParams['axes.unicode_minus'] = False # 解決保存圖像是負號'-'顯示為方塊的問題
sns.set(font='SimHei') # 解決Seaborn中文顯示問題
class BinJianAna:
def __init__(self):
pass
def ComuTF(self,lst1,lst2):
#計算TPR和FPR
#lst1為真實值,lst2為預測值
TP = sum([1 if a==b==1 else 0 for a,b in zip(lst1,lst2)])#正例被預測為正例
FN = sum([1 if a==1 and b==0 else 0 for a,b in zip(lst1,lst2)])#正例被預測為反例
TPR = TP/(TP+FN)
TN = sum([1 if a==b==0 else 0 for a,b in zip(lst1,lst2)])#反例被預測為反例
FP = sum([1 if a==0 and b==1 else 0 for a,b in zip(lst1,lst2)])#反例被預測為正例
FPR = FP/(TN+FP)
return TPR - FPR
def Getps_ks(self,real_data,data):
#real_data為真實值,data為原數據
d = []
for i in data:
pre_data = [1 if line >=i else 0 for line in data]
d.append(self.ComuTF(real_data,pre_data))
return max(d),data[d.index(max(d))]
def GetKS(self,y_test,y_pred_prob):
'''
功能: 計算KS值,輸出對應分割點和累計分布函數曲線圖
輸入值:
y_pred_prob: 一維數組或series,代表模型得分(一般為預測正類的概率)
y_test: 真實值,一維數組或series,代表真實的標簽({0,1}或{-1,1})
'''
fpr,tpr,thresholds = roc_curve(y_test,y_pred_prob)
ks = max(tpr-fpr)
#畫ROC曲線
plt.plot([0,1],[0,1],'k--')
plt.plot(fpr,tpr)
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.show()
#畫ks曲線
plt.plot(tpr)
plt.plot(fpr)
plt.plot(tpr-fpr)
plt.show()
return fpr,tpr,thresholds,ks
if __name__ == '__main__':
a = BinJianAna()
data = [790,22,345,543,564,342,344,666,789,123,231,234,235,347,234,237,178,198,567,222]#原始評分數據
real_data = [1,1,1,1,1,1,0,0,0,1,1,0,0,1,1,0,0,1,1,0]
y_pred_prob = [0.42,0.73,0.55,0.37,0.57,0.70,0.25,0.23,0.46,0.62,0.76,0.46,0.55,0.56,0.56,0.38,0.37,0.73,0.77,0.21]
#以下只為演示如何調用方法,2種方法獨立計算,數據之間無關聯,因此得出的ks不一樣
print(a.Getps_ks(real_data,data))#自己實現
print(a.GetKS(real_data,y_pred_prob))#代碼實現
本文鏈接:https://blog.csdn.net/sinat_30316741/article/details/80018932
