日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

(六十二)基于logistic回归的信用评级和分类模型评估

發布時間:2024/3/13 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (六十二)基于logistic回归的信用评级和分类模型评估 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

案例數據介紹

本案例中的企業從事個人汽車金融服務,向購車的個人提供信用貸款。該公司的風控部門根據貸款申請者的基本屬性、信貸歷史、歷史信用情況、貸款標的物的情況等信息構建貸款違約頂測模型,其中是否違約bad_ind是因變量。數據來自《Python數據科學:技術詳解與商業實踐》第八章。

import numpy as np from sklearn.linear_model import LogisticRegression,LogisticRegressionCV from sklearn.model_selection import train_test_split import pandas as pd from sklearn.metrics import classification_report,confusion_matrix import matplotlib.pyplot as plt accepts = pd.read_csv(r'C:\Users\accepts2.csv').dropna() #%% ##數據說明:本數據是一份汽車貸款違約數據 ##名稱---中文含義 ##application_id---申請者ID ##account_number---帳戶號 ##bad_ind---是否違約 ##vehicle_year---汽車購買時間 ##vehicle_make---汽車制造商 ##bankruptcy_ind---曾經破產標識 ##tot_derog---五年內信用不良事件數量(比如手機欠費消號) ##tot_tr---全部帳戶數量 ##age_oldest_tr---最久賬號存續時間(月) ##tot_open_tr---在使用帳戶數量 ##tot_rev_tr---在使用可循環貸款帳戶數量(比如信用卡) ##tot_rev_debt---在使用可循環貸款帳戶余額(比如信用卡欠款) ##tot_rev_line---可循環貸款帳戶限額(信用卡授權額度) ##rev_util---可循環貸款帳戶使用比例(余額/限額) ##fico_score---FICO打分,越高信用越好 ##purch_price---汽車購買金額(元) ##msrp---建議售價 ##down_pyt---分期付款的首次交款 ##loan_term---貸款期限(月) ##loan_amt---貸款金額 ##ltv---貸款金額/建議售價*100 ##tot_income---月均收入(元) ##veh_mileage---行使里程(Mile) ##used_ind---是否二手車 Out[2]: application_id account_number bad_ind ... veh_mileage used_ind weight 0 2314049 11613 1 ... 24000.0 1 1.00 1 63539 13449 0 ... 22.0 0 4.75 3 8725187 15359 1 ... 10000.0 1 1.00 4 4275127 15812 0 ... 14.0 0 4.75 5 8712513 16979 0 ... 1.0 0 4.75... ... ... ... ... ... ... 5840 2291068 10005156 0 ... 45000.0 1 4.75 5841 7647192 10005616 0 ... 21.0 0 4.75 5842 5993246 10006591 0 ... 25000.0 1 4.75 5843 4766566 10010208 0 ... 0.0 0 4.75 5844 1928782 10010219 0 ... 12.0 0 4.75[4105 rows x 25 columns]

下面對數據進行預處理,并生成一些衍生比值指標:

##衍生變量計算函數: def divMy(x,y):if x==np.nan or y==np.nan:return np.nanelif y==0:return -1else:return x/y ##歷史負債收入比:tot_rev_line/tot_income accepts["dti_hist"]=accepts[["tot_rev_line","tot_income"]].apply(lambda x:divMy(x[0],x[1]),axis = 1) ##本次新增負債收入比:loan_amt/tot_income accepts["dti_mew"]=accepts[["loan_amt","tot_income"]].apply(lambda x:divMy(x[0],x[1]),axis = 1) ##本次貸款首付比例:down_pyt/loan_amt accepts["fta"]=accepts[["down_pyt","loan_amt"]].apply(lambda x:divMy(x[0],x[1]),axis = 1) ##新增債務比:loan_amt/tot_rev_debt accepts["nth"]=accepts[["loan_amt","tot_rev_debt"]].apply(lambda x:divMy(x[0],x[1]),axis = 1) ##新增債務額度比:loan_amt/tot_rev_line accepts["nta"]=accepts[["loan_amt","tot_rev_line"]].apply(lambda x:divMy(x[0],x[1]),axis = 1) ##bankruptcy_ind的'Y'和'N'轉換為1和0 accepts["bankruptcy_ind"]=accepts["bankruptcy_ind"].apply(lambda x:1 if x=='Y' else (0 if x=='N' else np.nan))

Logistic回歸

Logistic回歸通過logit轉換將取值為正負無窮的線性方程的值域轉化為(0,1) ,正好與概率的取值范圍一致,如下所示:

其中 Pi / (1-Pi) 可解釋為在樣本中違約的概率是不違約的概率的多少倍。在scikit-learn中,與邏輯回歸有關的主要是LogisticRegression、LogisticRegressionCV等。主要區別是LogisticRegressionCV使用了交叉驗證來選擇正則化系數C,而LogisticRegression需要自己每次指定一個正則化系數(其中C參數為正則化系數λ的倒數,默認為1)。

一、LogisticRegression()

sklearn.linear_model.LogisticRegression(penalty=‘l2’, dual=False, tol=0.0001, C=1.0,fit_intercept=True, intercept_scaling=1, class_weight=None, random_state=None,solver=‘liblinear’, max_iter=100, multi_class=‘ovr’, verbose=0,warm_start=False, n_jobs=1),其中最常使用的參數有正則化選擇參數:penalty,優化算法選擇參數:solver,分類方式選擇參數:multi_class,類型權重參數:class_weight以及樣本權重參數:sample_weight等,具體可參閱sun_shengyun:sklearn邏輯回歸類庫使用小結。

正則化選擇參數penalty

  • LogisticRegression默認帶了正則化項L2。penalty參數可選擇的值為"l1"和"l2"。
  • 上篇博客也說到,在調參時如果主要目的只是為了解決過擬合,一般penalty選擇L2正則化就夠了。如果選擇L2發現還是過擬合,即預測效果差時,就可以考慮L1正則化。另外,如果模型的特征非常多,我們希望一些不重要的特征系數歸零,從而讓模型系數稀疏化的話,也可以使用L1正則化。
  • penalty參數的選擇會影響我們損失函數優化算法參數solver的選擇。如果是L2正則化,那么4種可選的算法{‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’}都可選。但如果是L1正則化,就只能選擇‘liblinear’了。這是因為L1正則化的損失函數不是連續可導的,而{‘newton-cg’, ‘lbfgs’,‘sag’}這三種優化算法時都需要損失函數的一階或者二階連續導數。

優化算法選擇參數solver

  • solver參數決定了我們對邏輯回歸損失函數的優化方法,有4種算法可以選擇,分別是:liblinear、 lbfgs、newton-cg、sag。
  • L1、liblinear:適用于小數據集;如果選擇L2正則化發現還是過擬合,就可以考慮L1正則化;如果模型的特征非常多,希望一些不重要的特征系數歸零,也可以使用L1正則化。
  • L2、liblinear:libniear只支持多元邏輯回歸的OvR,不支持MvM,但MVM相對精確。
  • L2、lbfgs/newton-cg/sag:較大數據集,支持one-vs-rest(OvR)和many-vs-many(MvM)兩種分類方式選擇參數下的多元邏輯回歸。
  • L2、sag:如果樣本量非常大,比如大于10萬,sag是第一選擇;但不能用于L1正則化。

分類方式選擇參數multi_class

  • multi_class參數決定了分類方式的選擇,有 ovr和multinomial兩個值可以選擇,默認是 ovr。
  • ovr即前面提到的one-vs-rest(OvR),而multinomial即前面提到的many-vs-many(MvM)。如果是二元邏輯回歸(即只有兩種可能結果,如違約和不違約),ovr和multinomial并沒有任何區別,區別主要在多元邏輯回歸上。

類型權重參數class_weight

  • 考慮誤分類代價敏感、分類類型不平衡的問題,class_weight可選 : ‘balanced’, default: None
  • class_weight參數用于標示分類模型中各種類型的權重,可以不輸入,即不考慮權重,或者說所有類型的權重一樣。如果選擇輸入的話,可以選擇balanced讓類庫自己計算類型權重,或者我們自己輸入各個類型的權重,比如對于0,1的二元模型,我們可以定義class_weight={0:0.9,1:0.1},這樣類型0的權重為90%,而類型1的權重為10%。
  • 如果class_weight選擇balanced,那么類庫會根據訓練樣本量來計算權重。某種類型樣本量越多,則權重越低,樣本量越少,則權重越高。

樣本權重參數sample_weight

  • 當樣本是高度失衡的,導致樣本不是總體樣本的無偏估計,從而可能導致我們的模型預測能力下降。調節樣本權重的方法有兩種,第一種是在class_weight使用balanced。第二種是在調用fit函數時,通過sample_weight來自己調節每個樣本權重
  • 如果上面兩種方法都用到了,那么樣本的真正權重是class_weight*sample_weight。

這里我們選擇C=0.01(即λ=100),penalty = ‘l2’,solver=‘lbfgs’。下面根據數據集中25個特征(排除application_id、account_number、vehicle_make)以及bad_ind進行多變量邏輯回歸:

data=accepts.iloc[:,4:]#25個特征數據 target=accepts.bad_ind train_X,test_X,train_y,test_y = train_test_split(data,target,test_size = 0.3,random_state = 0) logit=LogisticRegression(C = 0.01,penalty = 'l2',solver='lbfgs',max_iter = 100000).fit(train_X,train_y) coef = pd.Series(logit.coef_[0,:],index = train_X.columns) ###繪制特征系數大小排名圖 from pylab import mpl mpl.rcParams['font.sans-serif'] = ['SimHei'] mpl.rcParams['axes.unicode_minus']=False plt.figure(figsize=(8,6)) coef.sort_values().plot(kind = "barh",width = 0.35) plt.title("模型中各特征的系數") plt.grid() plt.show()


可以看到25個特征中有不少特征系數幾乎為0,因此可以剔除這些特征再進行邏輯回歸,此處不再贅述。下面是LogisticRegression自帶的一些方法,可以查看對測試集的預測效果:

prob0_test = logit.predict_proba(test_X)[:,0]#預測屬于0的概率 prob1_test = logit.predict_proba(test_X)[:,1]#預測屬于1的概率 pred_test = logit.predict(test_X)#預測標簽 test_table = pd.DataFrame({'預測標簽':pred_test,'預測為0的概率':prob0_test,'預測為1的概率':prob1_test}) test_table.head(16) Out[106]: 預測標簽 預測為0的概率 預測為1的概率 0 0 0.877870 0.122130 1 0 0.592357 0.407643 2 0 0.967154 0.032846 3 0 0.874919 0.125081 4 0 0.552422 0.447578 5 0 0.611668 0.388332 6 0 0.904147 0.095853 7 0 0.834194 0.165806 8 0 0.664811 0.335189 9 0 0.890139 0.109861 10 0 0.653965 0.346035 11 0 0.670883 0.329117 12 0 0.707951 0.292049 13 0 0.858788 0.141212 14 0 0.990260 0.009740 15 1 0.439046 0.560954 print(logit.score(train_X,train_y),logit.score(test_X,test_y))#返回平均準確率 0.8172641837800209 0.8051948051948052

可以看到第一列為預測結果,二、三列為預測為0(不違約)和1(違約)的概率。在第15條數據中,由于預測為0的概率小于預測為1的概率,因此分類標簽為1。訓練集和測試集的準確率均在80%以上且相差不大,擬合效果較好。

二、LogisticRegressionCV()

交叉驗證法(cross validation)先將數據集劃分為 k 個大小相似的互斥子集,每次用 k-1 個子集的并集作為訓練集,余下的那個子集作為測試集,這樣就可獲得 k 組訓練/測試集,從而可進行 k 次訓練和測試,最終返回的是這 k 個測試結果的均值。交叉驗證法評估結果的穩定性和保真性在很大程度上取決于 k 的取值,為強調這一點,通常把交叉驗證法稱為 k 折交叉驗證 (k-fold cross validation),k 最常用的取值是 5、10、20等。下圖給出了10折交叉驗證的示意:

LogisticRegressionCV(*, self, Cs=10, fit_intercept=True, cv=None, dual=False, penalty=‘l2’, scoring=None, solver=‘lbfgs’, tol=1e-4, max_iter=100, class_weight=None, n_jobs=None, verbose=0, refit=True, intercept_scaling=1., multi_class=‘auto’, random_state=None, l1_ratios=None),其中:

  • Cs表示產生C的個數,例如Cs=10,會產生相應的10個C:10(-4), 10(-3.11),10(-2.22), … , 10(-3.11), 104,LogisticRegressionCV會自動進行交叉驗證,從上面10個C里面挑出最佳的C;
  • 交叉驗證參數cv,默認fold數量為3,使用3折交叉驗證;
  • 并行數n_jobs,默認值1,-1表示與CPU個數一致。
  • 其它參數含義可參考官方文檔。
logitCV=LogisticRegressionCV(Cs = 10,penalty = 'l2',solver='lbfgs',max_iter = 100000).fit(train_X,train_y) print(logitCV.score(train_X,train_y),logitCV.score(test_X,test_y))#返回給出的數據和標簽的平均準確率 0.8169161155586495 0.8051948051948052 logitCV.C_#搜索出的最佳得分下的C值 Out[114]: array([1291.54966501])

查準率、查全率及F1值

sklearn中的classification_report函數用于顯示主要分類指標的文本報告,在報告中顯示每個類的查準率、查全率及F1值等信息。其中左邊的一列為分類的標簽名、準確度、宏平均和加權平均等,support列為每個標簽的出現次數/總和,precision、recall、f1-score三列分別為各個類別的查準率、查全率及F1值

print(confusion_matrix(test_y,pred_test,labels=[0,1]))#LogisticRegression方法下的混淆矩陣 print(classification_report(test_y,pred_test))#LogisticRegression方法下的分類結果報告 [[970 18][222 22]]precision recall f1-score support0 0.81 0.98 0.89 9881 0.55 0.09 0.15 244accuracy 0.81 1232macro avg 0.68 0.54 0.52 1232 weighted avg 0.76 0.81 0.74 1232

對于二分類問題,可將樣例根據其真實類別與學習器預測類別的組合劃分為真正例(true positive)、假正例(false positive)、真反例(true negative)、 假反例(false negative)四種情形,令TP、FP、TN、FN分別表示其對應的樣例數,則顯然有TP+FP+TN+FN=樣例總數。分類結果的混淆矩陣如下:

查準率和查全率是一對矛盾的度量。一般來說,查準率高時,查全率往往偏低;而查全率高時,查準率往往偏低。F1是基于查準率與查全率的調和平均定義的:

對混淆矩陣結果的判斷可參考Vincent__Lai:如何通過Recall和Precise快速判斷自己模型的問題。在一些應用中,對查準率和查全率的重視程度有所不同。例如在商品推薦系統中,為了盡可能少打擾用戶,更希望推薦內容確是用戶感興趣的,此時查準率更重要;而在逃犯信息檢索系統中,更希望盡可能少漏掉逃犯,此時查全率更重要。而本案例的貸款發生違約的后果嚴重,因此查全率更加重要,后續工作應該是著力于提高標簽1預測的查全率,比如修改分類的默認閾值0.5、提高標簽為1樣本的權重等。下面通過修改class_weight='balanced’來提高查全率:

logit3 = LogisticRegression(C = 0.01,penalty = 'l2',solver='lbfgs',class_weight\ = 'balanced',max_iter = 100000).fit(train_X,train_y) pred_test3 = logit3.predict(test_X) print(classification_report(test_y, pred_test3))precision recall f1-score support0 0.91 0.65 0.76 9881 0.35 0.75 0.47 244accuracy 0.67 1232macro avg 0.63 0.70 0.62 1232 weighted avg 0.80 0.67 0.70 1232

可以看到標簽1的查全率大大提高了。

ROC和AUC

ROC全稱是"受試者工作特征" (Receiver Operating Characteristic) 曲線。ROC 曲線的縱軸是"真正例率" (True Positive Rate,簡稱 TPR),橫軸是"假正例率" (False Positive Rate,簡稱 FPR),基于前文混淆矩陣中的符號,兩者分別定義為:

顯示 ROC 曲線的圖稱為 ROC 圖,下圖給出了一個示意圖,顯然對角線對應于"隨機猜測"模型,而點 (0,1) 則對應于將所有正例排在所有反例之前的"理想模型"。

繪圖過程很簡單:給定m+個正例和m-個反例,根據學習器預測結果對樣例進行排序,然后把分類閾值設為最大,即把所有樣例均預測為反例,此時真正例率和假正例率均為0,在坐標 (0,0) 處標記一個點。然后,將分類閾值依次設為每個樣例的預測值,即依次將每個樣例劃分為正例。設前一個標記點坐標為 (x,y), 當前若為真正例,則對應標記點的坐標為 (x,y+1/m+);當前若為假正例,則對應標記點的坐標為 (x+1/m-,y),然后用線段連接相鄰點即得。

進行學習器的比較時,若一個學習器的 ROC 曲線被另一個學習器的曲線完全"包住",則可斷言后者的性能優于前者;若兩個學習器的 ROC 曲線發生交叉,則難以斷言兩者孰優孰劣。此時如果一定要進行比較,則較為合理的判據是比較 ROC 曲線下的面積,即AUC (Area Under ROC Curve),如上圖所示。

sklearn.metrics.roc_curve函數可繪制ROC曲線。fpr, tpr, thresholds = roc_curve(y_true, y_score, pos_label = None, sample_weight = None, drop_intermediate = True):

  • y_true是真實的樣本標簽,默認為{0,1}或者{-1,1}。如果要設置為其它值,則 pos_label 參數要設置為特定值。
  • y_score是預測為正label的概率;
  • pos_label即標簽中認定為正的label;
  • sample_weight即采樣權重,可選擇取其中的一部分進行計算;
  • drop_intermediate(default=True)即可選擇去掉一些對于ROC性能不利的閾值,使得到的曲線有更好的表現性能。
  • 返回值fpr, tpr, thresholds即前文提到的假正例率、真正例率和閾值。

下面以LogisticRegression得出的結果為例,畫出ROC曲線,計算AUC值。此處正label為0,因此pos_label=0,y_score為預測標簽為0的概率prob0_test:

from sklearn.metrics import roc_curve,auc false_positive_rate,true_positive_rate,thresholds=roc_curve(test_y,prob0_test,pos_label=0) roc_auc=auc(false_positive_rate, true_positive_rate) plt.title('ROC') plt.plot(false_positive_rate, true_positive_rate,'b',label='AUC = %0.2f'% roc_auc) plt.legend(loc='best') plt.plot([0,1],[0,1],'r--')#隨機猜測45°線 plt.ylabel('TPR') plt.xlabel('FPR') plt.show()

參考文獻

https://blog.csdn.net/sun_shengyun/article/details/53811483
https://blog.csdn.net/w1301100424/article/details/84546194
http://www.sofasofa.io/forum_main_post.php?postid=1000383
周志華《機器學習》,清華大學出版社
常國珍等《Python數據科學:技術詳解與商業實踐》,機械工業出版社

總結

以上是生活随笔為你收集整理的(六十二)基于logistic回归的信用评级和分类模型评估的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。