機器學習簡易入門(二) - 分類算法
摘要:本文簡單敘述瞭如何經過分類算法來評估銀行發放貸款的模型機器學習
聲明:(本文的內容非原創,但通過本人翻譯和總結而來,轉載請註明出處)ide
本文內容來源:https://www.dataquest.io/mission/57/classification-basics函數
在你向銀行申請信用卡或者貸款時,銀行會使用根據過往的數據所創建的模型,再根據你的實際狀況來決定是否接受你的申請。學習
原始數據展示spa
銀行在以往的某段時間爲了訓練這個評分模型,向全部申請者都發放了貸款,而後記錄所有人是否有還款以及他們的評分狀況,paid字段代表該申請人是否有如實還款,1是正常還款,0是違約。model_score字段代表該申請人在得到貸款前在評分模型中的得分翻譯
import pandas credit = pandas.read_csv("credit.csv")
評估模型3d
根據上面的歷史數據,找到適合的閥值(model_score究竟爲多少分時才接受貸款申請),而後獲取最大的利潤code
準確率orm
咱們經過設置一個model_score的閥值來決定是否接受貸款申請,若是該申請者的model_score大於該閥值就接受,反之亦然,經過控制這個閥值來控制新客戶量。衡量一個模型的準確性是經過公示:準確率 = 正確預測數 / 樣本總量
# 設置閥值爲0.5,計算這個模型的準確率(評分大於0.5,且如實還款) pred = credit["model_score"] > 0.5 accuracy = sum(pred == credit["paid"]) / len(pred) # paid字段爲1,且model_score大於0.5
這個結果代表若是隻向model_score大於0.5的申請者發放貸款,大概會有86%的人還款
混淆矩陣
下表描述二元分類問題的混淆矩陣,表中每一個表項Fij表示實際類標號爲i但被預測爲類j的記錄數,例如,F01表明本來屬於類0但被誤分爲類1的記錄數,按照混淆矩陣中的表項,被分類模型正確預測的樣本總數是(F11 + F00),而被錯誤預測的樣本總數是(F10 + F01)
|
預測的類 |
||
類 = 1 |
類 = 0 |
||
實際的類 |
類 = 1 |
F11 |
F10 |
類 = 0 |
F01 |
F00 |
在本文中的混淆矩陣是這樣的
|
實際上會還款 |
實際上不會還款 |
預測會還款 |
TP |
FP |
預測不會還款 |
FN |
TN |
真正(True Positive , TP)被模型預測爲正的正樣本;
假負(False Negative , FN)被模型預測爲負的正樣本;
假正(False Positive , FP)被模型預測爲正的負樣本;
真負(True Negative , TN)被模型預測爲負的負樣本
真正率(True Positive Rate , TPR)或靈敏度(sensitivity):TPR = TP /(TP + FN) (正樣本預測結果數 / 正樣本實際數)
假負率(False Negative Rate , FNR):FNR = FN /(TP + FN) (被預測爲負的正樣本結果數 / 正樣本實際數 )
假正率(False Positive Rate , FPR):FPR = FP /(FP + TN) (被預測爲正的負樣本結果數 /負樣本實際數)
真負率(True Negative Rate , TNR)或特指度(specificity):TNR = TN /(TN + FP) (負樣本預測結果數 / 負樣本實際數)
# 把閥值設置爲0.5,分別計算上面的混淆矩陣 TP = sum(((credit['model_score'] > 0.5) == 1) & (credit['paid'] == 1)) FN = sum(((credit['model_score'] <= 0.5) == 1) & (credit['paid'] == 1)) FP = sum(((credit['model_score'] > 0.5) == 1) & (credit['paid'] == 0)) TN = sum(((credit['model_score'] <= 0.5) == 1) & (credit['paid'] == 0))
只要咱們的模型中真正率(TPR)大於假正率(FPR),就能保證還款的人要比違約的人多,從而保證銀行不會虧本
計算ROC曲線
ROC曲線(receiver operating characteristic curve),又稱爲感覺性曲線(sensitivity curve)。得此名的緣由在於曲線上各點反映着相同的感覺性,它們都是對同一信號刺激的反應,只不過是在幾種不一樣的斷定標準下所得的結果而已。接受者操做特性曲線就是以虛驚機率爲橫軸,擊中機率爲縱軸所組成的座標圖,和被試在特定刺激條件下因爲採用不一樣的判斷標準得出的不一樣結果畫出的曲線
根據上文所述,如今要尋找一個閥值,使得真正率大於假正率
import numpy def roc_curve(observed, probs): # 將閥值由1到0,分紅100個小數 thresholds = numpy.asarray([(100-j)/100 for j in range(100)]) # 初始化爲全0 fprs = numpy.asarray([0. for j in range(100)]) tprs = numpy.asarray([0. for j in range(100)]) # 對每一個閥值進行循環 for j, thres in enumerate(thresholds): pred = probs > thres FP = sum((observed == 0) & (pred == 1)) TN = sum((observed == 0) & (pred == 0)) FPR = float(FP / (FP + TN)) TP = sum((observed == 1) & (pred == 1)) FN = sum((observed == 1) & (pred == 0)) TPR = float(TP / (TP + FN)) fprs[j] = FPR tprs[j] = TPR return fprs, tprs, thresholds fpr, tpr, thres = roc_curve(credit["paid"], credit["model_score"]) idx = numpy.where(fpr>0.20)[0][0] # 選擇假正率爲0.2的閥值,理由在下面 print('FPR: 0.2') print('TPR: {}'.format(tpr[idx])) print('Threashold: {}'.format(thres[idx])) # 以假正率作x軸,真正率作y軸做圖 plt.plot(fpr, tpr) plt.xlabel('FPR') plt.ylabel('TPR') plt.show()
說明了當閥值設置爲0.38時,FPR = 0.2,TPR = 0.93
在上圖中可見,當FPR(假正率)達到了0.2以後,整條曲線都變平了,也就是說當FPR大於0.2以後,違約的人數增長了,不違約的人數卻沒有增長多少。
計算AUC
若是用兩個模型分別做出了不一樣的ROC曲線,那麼要怎樣對比這兩條ROC曲線的優異程度呢?可使用AUC,AUC經過測量ROC曲線下面的面積來得到。若是一個模型是完美的,那麼他的TPR就會是1,因此AUC也是1,而若是一個模型的TPR是0那麼AUC也會是0.因此能夠經過比較AUC的大小來比較兩個模型的優異,越高的AUC意味着模型越完美
能夠經過roc_auc_score函數來計算
#一個簡單的例子 from sklearn.metrics import roc_auc_score probs = [ 0.98200848, 0.92088976, 0.13125231, 0.0130085, 0.35719083, 0.34381803, 0.46938187, 0.53918899, 0.63485958, 0.56959959] obs = [1, 1, 0, 0, 1, 0, 1, 0, 0, 1] testing_auc = roc_auc_score(obs, probs) print("Example AUC: {auc}".format(auc=testing_auc))
計算本文的AUC
auc = roc_auc_score(credit["paid"], credit["model_score"])
召回率和準確率
除了上面用來計算ROC的TPR和FPR以外,還有兩個重要的指標:正確率(precision)和召回率(recall)
在本文中,越高的正確率說明在發放貸款以後,還款率要比違約率高,越高的召回率說明潛在客戶(那些有能力還款,可是被銀行拒絕了發放貸款)的流失率越低
# 以閥值0.5來計算 pred = credit["model_score"] > 0.5 # True Positives TP = sum(((pred == 1) & (credit["paid"] == 1))) # False Positives FP = sum(((pred == 0) & (credit["paid"] == 1))) # False Negatives FN = sum(((pred == 1) & (credit["paid"] == 0))) precision = TP / (TP + FP) recall = TP / (TP + FN) print('precision: {}'.format(precision)) print('recall: {}'.format(recall))
相似於ROC曲線,做出正確率與召回率曲線
from sklearn.metrics import precision_recall_curve precision, recall, thresholds = precision_recall_curve(credit["paid"], credit["model_score"]) plt.plot(recall, precision) plt.xlabel('Recall') plt.ylabel('Precision') plt.show()
在上圖中,曲線在Recall = 0.8的時候才陡然降低,此時的Precision = 0.9,說明了此時只流失了少許的潛在客戶,同時違約率也很低