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