利用Logistic回歸擬合信用評分卡模型

一、關于互聯(lián)網(wǎng)金融授信產(chǎn)品的風控建模

如何利用機器學習以及大數(shù)據(jù)技術來降低風險呢?如何建立信用評分的模型呢?
本文將針對這些問題簡單介紹互金行業(yè)中授信產(chǎn)品的風控建模過程,內(nèi)容主要如下:
·信用風險定義
·信用風險評分卡類型
·信用評分模型建立的基本流程

1.信用風險定義

①風險管理的概念
風險管理最早起源于美國。1930年由美國管理協(xié)會保險部最先倡導風險管理,后面在全球流行開來,隨著互聯(lián)網(wǎng)的迅猛發(fā)展,大數(shù)據(jù)、數(shù)據(jù)挖掘和機器學習等新興技術開始出現(xiàn),讓風險管理更為精準。
他們通過收集銀行系統(tǒng)本身的征信數(shù)據(jù)以及用戶在互聯(lián)網(wǎng)上的的各種數(shù)據(jù),包括人際關系、歷史消費行為、身份特征等,通過大數(shù)據(jù)“畫像”技術,對用戶進行全面的定位,由此來預測用戶的履約能力、降低信貸風險。

②什么是信用風險?
信用風險又稱違約風險,是指借款人、證券發(fā)行人或交易對方因種種原因,不愿或無力履行合同條件而構成違約,致使銀行、投資者或交易對方遭受損失的可能性。即受信人不能履行還本付息的責任而使授信人的預期收益與實際收益發(fā)生偏離的可能性,它是金融風險的主要類型。
萬事都有風險,但對于金融行業(yè)來講,風險控制尤為重要。對于海量的用戶數(shù)據(jù)處理,傳統(tǒng)的人工授信方式顯然是很乏力的,因此現(xiàn)在大多互聯(lián)網(wǎng)金融P2P公司都采用機器學習、大數(shù)據(jù)等技術對風險進行自動化評估,來最大程度的降低風險。當然,這些技術的應用并不能百分百的保證零風險,因為有很多人為因素是不可控的,但是信用風控技術在很大程度上幫助金融企業(yè)進行了很好的風險管控,通過降低風險減少損失來間接增加利潤。

2.信用風險評分卡類型

①信用評級
用過信用卡的朋友都知道,開卡需要申請(篩選好壞用戶),消費了就需要定期進行債務償還,如果不償還就有人發(fā)短信催你。因此,信用評級可根據(jù)用戶的整個使用周期分為以下四種類型:
1)申請者評級(Application):個人客戶申請相應金融產(chǎn)品,對用戶進行篩選分類,判斷時好時壞,是否通過申請(A卡)
2)行為評級(Behavier):個人客戶通過申請后在使用期間的歷史行為數(shù)據(jù)進行評級,對客戶可能出現(xiàn)的逾期、延期等行為進行預測(B卡)
3)催收評級(Collection):對業(yè)務中存量客戶是否需要催收的預測(C卡)
4)欺詐評級(Fraud):業(yè)務中新客戶可能存在的欺詐行為的預測(F卡)
每個評級階段的模型都是不一樣的,因為每個階段的用戶顯現(xiàn)的特征都不一樣,因此需要針對各個階段進行單獨的模型開發(fā)。

②信用評分卡
盡管有了評級分類,但是信用對于我們來說仍然是一個比較抽象的概念,因此可以通過量化的方式來更直觀的使用信用,而分數(shù)是一種不錯的量化方式,通過分數(shù)的高低來衡量風險概率,分數(shù)越高代表信用越好。信用評分卡就是通過大數(shù)據(jù)的統(tǒng)計分析,根據(jù)用戶的各種資料信息,對用戶信用進行評估(打分)。根據(jù)以上信用評級,相應的可以分為四種評分卡:
1)申請評分卡(A卡)
2)行為評分卡(B卡)
3)催收評分卡(C卡)
4)欺詐評分卡(F卡)
是一種以分數(shù)的形式來衡量風險幾率的一種手段,也是對未來一段時間內(nèi)違約、逾期、失聯(lián)概率的預測。一般來說,分數(shù)越高,風險越小。
A卡一般可做貸款0-1年的信用分析,B卡則是在申請人有了一定行為后,有了較大數(shù)據(jù)進行的分析,一般為3-5年,C卡則對數(shù)據(jù)要求更大,需加入催收后客戶反應等屬性數(shù)據(jù)。每種評分卡的模型會不一樣。在A卡中常用的有邏輯回歸,AHP等,而在后面兩種卡中,常使用多因素邏輯回歸,精度等方面更好。 基于個人借貸的場景,確定“違約”的定義: 根據(jù)新的Basel II Capital Accord(巴塞爾二資本協(xié)議),一般逾期90天算作違約

3. 信用評分建模的基本流程
通過對消費者的人口特征、信用歷史記錄、交易記錄等大量數(shù)據(jù)進行系統(tǒng)的分析、挖掘數(shù)據(jù)蘊含的行為模式、信用特征,發(fā)展出預測行的模式,結合信用卡評分的構建原理,完成數(shù)據(jù)的清洗,主要包括缺失數(shù)據(jù)的填充、異常的刪除和數(shù)據(jù)的分箱;調(diào)用Logistic回歸模型建立信用卡評分的基礎模型,借助自變量的證據(jù)權重轉換(WOE)創(chuàng)建信用卡評分卡,并開發(fā)一個簡單的信用評分系統(tǒng)。
在開發(fā)信用風險模型之前,首先要明確我們需要解決的問題,確定評分卡模型的類別。下面將對申請評分卡建模(主要目的是區(qū)分好壞客戶)流程進行簡單的介紹。

①數(shù)據(jù)獲取
除了企業(yè)內(nèi)部自有的數(shù)據(jù)外,還有第三方機構數(shù)據(jù)支持,比如芝麻信用,征信局等。通過大數(shù)據(jù)分析用戶的各種數(shù)據(jù)來達到最終目的,數(shù)據(jù)維度很廣,可以包括:用戶基礎屬性,用戶行為,用戶網(wǎng)購,用戶APP行為等。在數(shù)據(jù)質量不差的情況下,數(shù)量越多越好,能留的一個不落下,后續(xù)再進行甄別篩選。
這部分的技術棧主要有:Mysql,Hive,Hbase,Spark,Python等。

②EDA數(shù)據(jù)探索
數(shù)據(jù)探索也是很重要的一步,主要考察數(shù)據(jù)的質量,包括:數(shù)據(jù)缺失值,數(shù)據(jù)異常值,數(shù)據(jù)一致性,數(shù)據(jù)分布特征,以及數(shù)據(jù)之間的關聯(lián)性等。通常可以使用描述性統(tǒng)計指標,如均值,中位數(shù),眾數(shù),方差/標準差等進行宏觀上的度量,也可以使用可視化方法輔助進行數(shù)據(jù)分布,以及關聯(lián)性等的初步分析工作。
1)缺失值處理
根據(jù)缺失情況(是否隨機,以及缺失量等)可選擇使用均值,眾數(shù),中位數(shù)等填充,也可以用機器學習模型來填充缺失值(常見算法有隨機森林,決策樹,kNN等)。
2)異常值處理
可根據(jù)異常的情況考慮使用3?原則,箱線圖,散點圖,基于距離,基于密度,基于聚類等一系列的方法進行離群點檢測。對于異常值的處理可以采用移除,平均值修正,視為缺失值,或者不處理等。
3)數(shù)據(jù)分布以及關聯(lián)性
可以考慮結合可視化的方法進一步的觀察:數(shù)據(jù)分布是否均衡,數(shù)據(jù)特征之間的聯(lián)系,以及數(shù)據(jù)特征與目標變量之間的聯(lián)系等進行了解

③數(shù)據(jù)預處理
數(shù)據(jù)預處理主要包括特征轉換,特征編碼,特征選擇,特征共線性處理,以及創(chuàng)建衍生變量等一系列的處理方法。
1)特征轉換和編碼
在信用評分模型的變量選擇中,如果使用邏輯回歸模型,那么就需對所有特征進行分箱離散化(一般是先細分再粗分),這樣可以增加模型對非線性的表達,讓模型更穩(wěn)定。然后再進行woe編碼,因為woe的轉換公式與邏輯回歸模型上非常相似,便于生成評分系統(tǒng)。
2)特征選擇
特征選擇,在數(shù)據(jù)中是非常中重要,目的在于幫助我們挑選出最有意義的特征。選擇特征最終目的是挑選能區(qū)分好用戶或壞用戶的強相關特征。
根據(jù)所使用的模型可以通過基尼系數(shù)或信息價值IV找到顯著特征項,也可以通過LASSO、LR、RF模型等對特征做重要性的篩選。當然,還有很多其它的方法,這里僅介紹這幾種。
a)IV:基于woe編碼,可以衡量特征信息重要程序;
b)LASSO:主要適合基于L1的正則懲罰過濾對區(qū)分好壞用戶不重要的特征;
c)LR:通過擬合的參數(shù)排序得到特征的重要性程度;
d)RF:集成學習(bagging),依據(jù)算法的附加功能進行特征的重要性排序;
最后要說的是,特征選擇要結合業(yè)務,根據(jù)業(yè)務的理解挑選解釋型強且權重較大的特征變量。

④模型建立
模型建立會根據(jù)實際情況進行選擇,比如是否要使用單模型,或者在單模型中各種模型好壞的比較而最終確認。
在信用評分卡建模中,用到最常用的方法就是邏輯回歸(LR)。雖然是傳統(tǒng)的模型,但是由于其自身特點,加上自變量進行了證據(jù)權重轉換(WOE),Logistic回歸的結果可以直接轉換為一個匯總表,即所謂的標準評分卡格式,這對于區(qū)分好壞用戶以及評分卡的建立非常適用。目前對于它的使用和部署上線等已經(jīng)非常成熟,是很多企業(yè)的不二選擇。
除了LR外,神經(jīng)網(wǎng)絡,Xgboost等高級模型也會被使用,不過綜合考慮LR目前能夠滿足大部分的需求且部署上線容易。

⑤模型評估(對于離散型因變量)
針對信用評分卡應用的評估模型有很多,包括:ROC/AUC,KS,PSI,LIFT等一些評估方法,下面著重介紹兩個ROC和KS值。

1)混淆矩陣
以腫瘤為例,對于實際的數(shù)據(jù)集存在兩種分類,即良性和惡性,基于Logistic回歸模型會預測出樣本所屬的類別,得到兩列數(shù)據(jù):真實地;預測的,將兩個序列得到一個匯總的列聯(lián)表,即混淆矩陣。

0表示良性(負例),1表示惡性(正例,一般被理解為研究者所感興趣或者關心的那個分類),

A:表示正確預測負例的樣本個數(shù),TN
A+B:表示預測負例的樣本個數(shù),PN
準確率:(A+D)/(A+B+C+D),用來衡量模型對整體數(shù)據(jù)的預測效果,用Accuracy表示
正例覆蓋率:D/(B+D),反映模型能夠在多大程度上覆蓋所關心的類別,即TPR=TP/P,稱為靈敏度(sensitivity)/召回率(recall)
負例覆蓋率:A/(A+C),即TNR=TN/N稱為特指度(specicity)
正例命中率:D/(C+D),即(TP+TN)/T ,表示分類器預測正確的比例稱正確率(accuracy)
一般準確率、正例覆蓋率、負例覆蓋率越高,模型越理想

還有,F(xiàn)PR=FP/P稱誤警率(Fallout),FNR=FP/N稱為漏查率(miss).
分類器預測錯誤的比例稱錯誤率(error rate):(FP+FN)/T

又可以定義下面兩個比率: TPR又可稱為查全率,表示正確分類的正例占實際正例(TP/(TP+FN))的比例,用于衡量分類器預測正例的可信程度。 相對應的概念有查準率(precision),表示正確分類的正例占全部預測正例的比例(TP/(TP+FP))。

2)ROC/AUC
通常一個二值分類器可以通過ROC(Receiver Operating Characteristic)曲線和AUC值來評價優(yōu)劣。

很多二元分類器會產(chǎn)生一個概率預測值,而非僅僅是0-1預測值。我們可以使用某個臨界點/閾值(例如0.5),以劃分哪些預測為1,哪些預測為0。得到二元預測值后,可以構建一個混淆矩陣來評價二元分類器的預測效果。所有的訓練數(shù)據(jù)都會落入這個矩陣中,而對角線上的數(shù)字代表了預測正確的數(shù)目,即true positive + true nagetive。同時可以相應算出TPR(正例覆蓋率或稱為真正率或稱為靈敏度)和TNR(負例覆蓋率或稱為真負率或稱為特異度)。我們主觀上希望這兩個指標越大越好,但可惜二者是一個此消彼漲的關系。除了分類器的訓練參數(shù),臨界點的選擇,也會大大的影響TPR和TNR。有時可以根據(jù)具體問題和需要,來選擇具體的臨界點。

如果我們選擇一系列的臨界點/閾值,就會得到一系列的TPR和TNR,將這些值對應的點連接起來,就構成了ROC曲線。ROC曲線可以幫助我們清楚的了解到這個分類器的性能表現(xiàn),還能方便比較不同分類器的性能。在繪制ROC曲線的時候,習慣上是使用1-TNR作為橫坐標即FPR(false positive rate),TPR作為縱坐標。這是就形成了ROC曲線。

而AUC(Area Under Curve)被定義為ROC曲線下的面積,顯然這個面積的數(shù)值不會大于1。又由于ROC曲線一般都處于y=x這條直線的上方,所以AUC的取值范圍在0.5和1之間。使用AUC值作為評價標準是因為很多時候ROC曲線并不能清晰的說明哪個分類器的效果更好,而作為一個數(shù)值,對應AUC更大的分類器效果更好。

ROC基于混淆矩陣,對于數(shù)據(jù)類別不均衡有很好的效果。ROC曲線使用兩個指標值進行繪制,其中x軸為1-Specificity,即負例錯判率;y軸為Sensitivity,即正例覆蓋率。ROC值一般在0.5-1.0之間。值越大表示模型判斷準確性越高(曲線越偏左上方越好),即越接近1越好。ROC=0.5表示模型的預測能力與隨機結果沒有差別,AUC代表曲線下的面積,不依賴于閾值,AUC值越高,模型的風險區(qū)分能力越強。通常AUC在0.8以上時,模型基本可以接受了。

提升度和提升曲線
分類器分類為正例的比例稱為深度(depth):(TP+FP)/T,T是全部待判樣本數(shù)量。

提升度(lift)等于TPR/depth 以深度為橫軸,以提升度為縱軸繪制曲線,得到提升曲線。 繪制提升曲線的思路和ROC類似。當閾值為0的時候,所有的樣本都會判為正例,此時深度為1,提升為1;隨閾值增大,深度減小,提升隨之逐漸增大。一個好的模型要在大的深度下得到盡量大的提升。

3)KS值
KS值表示了模型正負區(qū)分開來的能力。值越大,模型的預測準確性越好。一般,KS>0.4即可認為模型有比較好的預測準確性,KS值只能反映出哪個分段是區(qū)分最大的,而不能總體反映出所有分段的效果。

具體步驟為:
按照模型計算score值,從大到小排序;
取出10%,20%,..,90%所對應的分位數(shù),并以此作為score的閾值,計算Sensitivity和1-Specificity的值,將10%、20%、..、90%這樣的分位點用作繪圖的x軸,將Sensitivity和1-Specifity兩個指標值用作繪圖的y軸,進而得到兩條曲線;
分別代表各分位點下的正例覆蓋率和1-負例覆蓋率,一般選用最大的KS值作為衡量指標;
KS=Sensitivity-(1-Specificity),通常KS>0.4即可認為模型有比較好的預測準確性

下面是一個真實的在線授信產(chǎn)品的風控建模的流程圖,可參考進行理解:



二、數(shù)據(jù)獲取

1.數(shù)據(jù)描述
數(shù)據(jù)屬于個人消費類貸款,只考慮評分卡最終實施時能夠使用到的數(shù)據(jù)應從如下一些方面獲取數(shù)據(jù):
基本屬性:包括了借款人當時的年齡。
償債能力:包括了借款人的月收入、負債比率。
信用往來:兩年內(nèi)35-59天逾期次數(shù)、兩年內(nèi)60-89天逾期次數(shù)、兩年內(nèi)90天或高于90天逾期的次數(shù)。
財產(chǎn)狀況:包括了開放式信貸和貸款數(shù)量、不動產(chǎn)貸款或額度數(shù)量。
貸款屬性:暫無。
其他因素:包括了借款人的家屬數(shù)量(不包括本人在內(nèi))。

2.數(shù)據(jù)導入以及給列重命名

rm(list = ls())
setwd('F:\\kaggle\\評分卡模型')
getwd()
data<-read.csv('cs-training.csv',header = T,stringsAsFactors = F)
str(data)
colnames(data)<-c("id","y","x0","x1","x2","x3","x4","x5","x6","x7","x8","x9")
attach(data)
summary(data)

通過summary了解數(shù)據(jù)的整體情況,可以看到x4和x9變量有缺失值,即MonthlyIncome變量和NumberOfDependents兩個變量存在缺失值,monthlyincome列共有缺失值29731個,numberofdependents有3924個。

三、數(shù)據(jù)預處理

1.缺失值分析及處理
在正式分析前,我們先通過圖形進行對觀測字段的缺失情況有一個直觀的感受。

library(mice)
md.pattern(data)


同樣得出monthlyincome(X4)列共有缺失值29731個,numberofdependents(X9)有3924個。由于MonthlyIncome(X4)缺失值達到29731條數(shù)據(jù),比例較大,因此不能直接將缺失值刪除,選擇隨機森林法。而NumberOfDependents(X9)的缺失較少,對數(shù)據(jù)影響不大,因此直接刪除。對于缺失值的處理方法非常多,例如基于聚類的方法,基于回歸的方法,基于均值的方法,在這里,我們使用mean方法對缺失值進行填補。

#保留x9中不是缺失值的數(shù)據(jù)
data<- data[!is.na(x9),]
x4_var<-c(var="x4",mean=mean(x4,na.rm=TRUE),median=median(x4,na.rm=TRUE),quantile(x4,c(0,0.01,0.1,0.25,0.5,0.75,0.9,0.99,1),na.rm=TRUE),max=max(x4,na.rm=TRUE),missing=sum(is.na(x4)))
View(t(x4_var))
#用mean填補x4的缺失值
x4<-ifelse(is.na(x4)==T,6670.2,x4)
#或者
library(Hmisc)
impute(x4, mean)  # 均值替代

2.異常值處理
異常值是指明顯偏離大多數(shù)抽樣數(shù)據(jù)的數(shù)值,比如個人客戶的年齡大于100或小于0時,通常認為該值為異常值。找出樣本總體中的異常值,通常采用離群值檢測的方法。 離群值檢測的方法有單變量離群值檢測、局部離群值因子檢測、基于聚類方法的離群值檢測等方法。在本數(shù)據(jù)集中,采用單變量離群值檢測來判斷異常值,采用箱線圖。常把低于 Q1-1.5IQR的值和高于Q3+1.5IQR的值作為異常值。通過繪制箱型圖能很明顯的看到異常值,
處理異常值:通常采用蓋帽法,即用數(shù)據(jù)分布在1%的數(shù)據(jù)覆蓋在1%以下的數(shù)據(jù),用在99%的數(shù)據(jù)覆蓋99%以上的數(shù)據(jù)。

block<-function(x,lower=T,upper=T){
  if(lower){
    q1<-quantile(x,0.01)
    x[x<=q1]<-q1
  }
  if(upper){
    q99<-quantile(x,0.99)
    x[x>q99]<-q99
  }
  return(x)
}

對于age變量而言,我們認為大于100歲小于等于0歲的為異常值,由箱線圖可知,異常值樣本不多,故直接刪除。

par(mfrow=c(2,1))
boxplot(x1,data=data,horizontal=T,frame=F,col="lightgray")
x1<-block(x1)
boxplot(x1,data=data,horizontal=T,frame=F,col="lightgray")
#col : 箱體的填充
#border : 箱體中線條的顏色,默認為黑色

可以看出經(jīng)過蓋帽法,大于100,小于等于0的值被刪除
對于RevolvingUtilizationOfUnsecuredLines(可用額度比值x0)及DebtRatio(負債率x3)而言,箱線圖如下圖:

par(mfrow=c(1,2))
boxplot(x0,frame=F,ylab ="%")
abline(h=1,col="red")
data<-data[which(data$x0<=1),]
boxplot(x3,frame=F,ylab ="%")
abline(h=1,col="red")
data<-data[which(data$x3<=1),]

因為上述兩變量的數(shù)值型為百分比,故大于1的值全部刪除。
對于變量x2(逾期30-59天筆數(shù))、x6(逾期90天筆數(shù))、x8(逾期60-89天筆數(shù)做箱線圖,由圖可知,有兩異常值點,數(shù)值為96、98,刪除。
同時會發(fā)現(xiàn)剔除其中一個變量的96、98值,其他變量的96、98兩個值也會相應被剔除。

par(mfrow=c(1,1))
boxplot(x2,x6,x8,data=data,frame=F)
data<-data[-which(data$x2==96),]
data<-data[-which(data$x2==98),]

四、探索性分析切分數(shù)據(jù)集

在建立模型之前,我們一般會對現(xiàn)有的數(shù)據(jù)進行 探索性數(shù)據(jù)分析(Exploratory Data Analysis) 。 EDA是指對已有的數(shù)據(jù)(特別是調(diào)查或觀察得來的原始數(shù)據(jù))在盡量少的先驗假定下進行探索。常用的探索性數(shù)據(jù)分析方法有:直方圖、散點圖和箱線圖等。
探索數(shù)據(jù)主要是為了分析各變量對輸出結果的影響,在本項目中,主要關注的是違約客戶與各變量間的關系。
1.單變量分析

hist(x1,freq = F,col="lightgreen")
lines(density(x1),col="red")

可以看到年齡變量大致呈正態(tài)分布,符合統(tǒng)計分析的假設。

library(ggplot2)
ggplot(data, aes(x = x4, y = ..density..)) + geom_histogram(fill = "blue", colour = "grey60", size = 0.2, alpha = 0.2) + geom_density() + xlim(1, 20000)


月收入也大致呈正態(tài)分布,符合統(tǒng)計分析的需要。
2.多變量分析
我們會用經(jīng)過清洗后的數(shù)據(jù)看一下變量間的相關性。注意,這里的相關性分析只是初步的檢查,進一步檢查模型的IV(證據(jù)權重)作為變量篩選的依據(jù)。此處較簡單,在此不贅述。
總之,數(shù)據(jù)處理的過程是占據(jù)整個標準評分卡構建的最大的工作量,整體的目標是:排除異常值對模型訓練的干擾,將所有變量進行量化處理,自變量對因變量有明顯的解釋性,變量之間無明顯相關性。
建模之前需要先檢驗變量之間的相關性,,如果變量之間具有強相關性,則會影響模型的準確性.調(diào)用R中的cor()函數(shù)來計算不同變量之間的相關系數(shù),同時,調(diào)用corrplot包中的corrplot()函數(shù)來將相關系數(shù)可視化

cor1<-cor(data[,2:12])
library(corrplot)
corrplot(cor1)
corrplot(cor1,method = "number")

由上圖可知:各個變量之間的相關系數(shù)較小,相關性較弱,不存在明顯的多重共線問題,采用logistic回歸需要考慮多重共線問題,不過此處由于各變量之間的相關性較小,可以初步判斷不存在多重共線問題.在建模之后也可以通過VIF(方差膨脹因子)來檢驗多重共線問題.如果存在多重共線性,即有可能存在兩個變量高度相關,需要降維或剔除處理,需要進行降維或剔除處理.

五、切分數(shù)據(jù)集

table(y)

由上表看出,對于響應變量SeriousDlqin2yrs,存在明顯的類失衡問題,SeriousDlqin2yrs等于1的觀測為9879,僅為所有觀測值的6.6%。數(shù)據(jù)正負比例不平衡,因此我們需要對非平衡數(shù)據(jù)進行處理,在這里可以采用SMOTE算法,smote算法的思想是合成新的少數(shù)類樣本,合成的策略是對每個少數(shù)類樣本a,從它的最近鄰中隨機選一個樣本b,然后在a、b之間的連線上隨機選一點作為新合成的少數(shù)類樣本。用R對稀有事件進行超級采樣。
非平衡樣本的解決方法
過采樣 容易過擬合
欠采樣 容易丟失信息
SMOTE算法 不能對有缺失值和類別變量做處理
SMOTE算法介紹:
采樣K近鄰
從K近鄰中隨機挑選N個樣本進行隨機線性插值
new=xi+rand(0,1)*(yj-xi),j=1…N
其中xi為少類中的一個觀測點,yj為從K近鄰中隨機抽取的樣本。

我們利用caret包中的createDataPartition(數(shù)據(jù)分割功能)函數(shù)將數(shù)據(jù)隨機分成相同的兩份。

set.seed(1234) 
library(caret)
splitIndex<-createDataPartition(y,time=1, p=0.5,list=FALSE) 
train<-data[splitIndex,] 
test<-data[-splitIndex,]
prop.table(table(train$y))
prop.table(table(test$y))

兩者分類后的結果是平衡的,y等于1的概率均為6.0%左右,處于良好的水平,因此,可以采用切割后的數(shù)據(jù)進行建模和預測分析。

六、建立模型

Logistic回歸在信用評分卡開發(fā)中起到核心作用。由于其特點,以及對自變量進行了證據(jù)權重轉換(WOE),Logistic回歸的結果可以直接轉換為一個匯總表,即所謂的標準評分卡格式。
1.模型解釋


2.建立模型
①首先利用glm函數(shù)對所有變量進行Logistic回歸建模,模型如下

fit<-glm(y~.,train,family = "binomial")
summary(fit)

②可以看出,利用全變量進行回歸,模型擬合效果并不是很好,其中id,x7三個變量的p值未能通過檢驗,在此直接剔除這兩個變量,利用剩余的變量對y進行回歸。

fit2<-glm(y~x0+x1+x2+x3+x4+x5+x6+x8+x9,train,family = "binomial")
summary(fit2)

第二個回歸模型所有變量都通過了檢驗,所有模型的擬合效果更好些。
③使用逐步法剔除變量。

step(fit2, direction = "both")

可以看到?jīng)]有變量被剔除
④VIF多重共線性檢驗

library(car)
library(carData)
vif(fit2)

一般認為VIF值大于2的話,表明變量間存在共線性。此時沒有大于2的值,各個變量間相互獨立
⑤預測

train_pred <- predict(fit2, data = train , type = "response")
test_pred <- predict(fit2, data = test , type = "response")

⑥模型評估
下面首先利用模型對test數(shù)據(jù)進行預測,生成概率預測值

test_prob <- predict(fit2, test)

調(diào)用R語言中pROC包中的roc函數(shù)計算分類器的AUC值,可以方便的比較兩個分類器,并且自動標注出最優(yōu)的臨界點。

install.packages("pROC")
library(pROC)
modelroc <- roc(test$y,test_prob)
plot(modelroc, print.auc=TRUE, auc.polygon=TRUE, grid=c(0.1, 0.2),
     grid.col=c("green", "red"), max.auc.polygon=TRUE,
     auc.polygon.col="skyblue", print.thres=TRUE)

如圖所示:最優(yōu)點FPR=1-TNR=0.778,TPR=0.732,AUC值為0.832,說明該模型的預測效果不錯,正確率較高。

(到這里為用戶貸款預測模型)

七、特征變量選擇

特征選擇非常重要,好的特征能夠構造出較好的模型,在此,我們采用信用卡評分模型常用的IV值篩選。
1.特征分箱
特征分箱指的是將連續(xù)變量離散化或將多狀態(tài)的離散變量合并成少狀態(tài)。離散特征的增加和減少都很容易,易于模型的快速迭代,離散化后的特征對異常數(shù)據(jù)有很強的魯棒性,能夠減少未離散化之前異常值對模型的干擾,同時離散化后可以進行特征交叉。此外本文所選的模型算法為邏輯回歸,邏輯回歸屬于廣義線性模型,表達能力受限;單變量離散化為N個后,每個變量有單獨的權重,相當于為模型引入非線性,提升模型表達能力,加大擬合,同時也降低了模型過擬合的風險。特征分箱常用的有以下幾種方法:有監(jiān)督的有Best-KS,ChiMerge(卡分分箱),無監(jiān)督的包括等頻、等距、聚類。根據(jù)數(shù)據(jù)特征,針對不同數(shù)據(jù)采用不同分箱方式。
信用評分卡開發(fā)中一般有常用的等距分段、等深分段、最優(yōu)分段。
如年齡,在外面的業(yè)務場景中年齡越小和年齡越大,違約概率都會偏大,所以這塊需要做好分箱處理。

cutx1= c(-Inf,30,35,40,45,50,55,60,65,75,Inf)
plot(cut(train$x1,cutx1))
cutx2 = c(-Inf,0,1,3,5,Inf)
plot(cut(train$x2,cutx2))
cutx4 = c(-Inf,1000,2000,3000,4000,5000,6000,7500,9500,12000,Inf)
plot(cut(train$x4,cutx4))
cutx6 = c(-Inf,0,1,3,5,10,Inf)
plot(cut(train$x6,cutx6))
cutx8 = c(-Inf,0,1,3,5,Inf)
plot(cut(train$x8,cutx8))
cutx9 = c(-Inf,0,1,2,3,5,Inf)
plot(cut(train$x9,cutx9))


2.WOE值計算
在分箱的過程中,同時計算了WOE(Weight of Evidence)和IV(Information Value),前者在建立邏輯回歸模型是需要將所有的變量轉為WOE,而后者則可以很好的展示變量的預測能力。這兩個值的計算方式如下:

證據(jù)權重(Weight of Evidence,WOE)轉換可以將Logistic回歸模型轉化為標準評分卡格式,引入WOE轉換的目的并不是為了提高模型質量,而是由于一些變量不應該被納入模型,或者是因為它們不能增加模型值,或者是因為與其模型相關系數(shù)有關的誤差較大,其實建立標準信用評分卡也可以不采用WOE轉換。這種情況下,Logistic回歸模型需要處理更大數(shù)量的自變量。盡管這樣會增加建模程序的復雜性,但最終得到的評分卡都是一樣的。
用WOE(x)替換變量x,WOE()=ln[(違約/總違約)/(正常/總正常)]。由于模型中剔除id,x7兩個變量,因此對剩下的變量進行WOE轉換。
WOE分箱原則:
1.分箱數(shù)量適中,不宜過多和過少。
2.各個分箱內(nèi)的記錄數(shù)應該合理,不應過多或者或過少。
3.結合目標變量,分箱應該表現(xiàn)出明顯的趨勢。
4.相鄰分箱的目標變量分布差異盡可能大。

#計算WOE的函數(shù)
totalgood = as.numeric(table(train$y))[1]
totalbad = as.numeric(table(train$y))[2]
getWOE <- function(a,p,q)
{
  Good <- as.numeric(table(train$y[a > p & a <= q]))[1]
  Bad <- as.numeric(table(train$y[a > p & a <= q]))[2]
  WOE <- log((Bad/totalbad)/(Good/totalgood),base = exp(1))
  return(WOE)
}

如age變量(x1)

Agelessthan30.WOE=getWOE(train$x1,-Inf,30)
Age30to35.WOE=getWOE(train$x1,30,35)
Age35to40.WOE=getWOE(train$x1,35,40)
Age40to45.WOE=getWOE(train$x1,40,45)
Age45to50.WOE=getWOE(train$x1,45,50)
Age50to55.WOE=getWOE(train$x1,50,55)
Age55to60.WOE=getWOE(train$x1,55,60)
Age60to65.WOE=getWOE(train$x1,60,65)
Age65to75.WOE=getWOE(train$x1,65,75)
Agemorethan.WOE=getWOE(train$x1,75,Inf)
age.WOE=c(Agelessthan30.WOE,Age30to35.WOE,Age35to40.WOE,Age40to45.WOE,Age45to50.WOE,
          Age50to55.WOE,Age55to60.WOE,Age60to65.WOE,Age65to75.WOE,Agemorethan.WOE)
age.WOE


NumberOftIME30-59Days(x4)


以上截圖中的x10指x9,其他類推
3.對變量進行WOE變換
如age變量(x1)

tmp.age <- 0
for(i in 1:nrow(train)) {
  if(train$x1[i] <= 30)
    tmp.age[i] <- Agelessthan30.WOE
  else if(train$x1[i] <= 35)
    tmp.age[i] <- Age30to35.WOE
  else if(train$x1[i] <= 40)
    tmp.age[i] <- Age35to40.WOE
  else if(train$x1[i] <= 45)
    tmp.age[i] <- Age40to45.WOE
  else if(train$x1[i] <= 50)
    tmp.age[i] <- Age45to50.WOE
  else if(train$x1[i] <= 55)
    tmp.age[i] <- Age50to55.WOE
  else if(train$x1[i] <= 60)
    tmp.age[i] <- Age55to60.WOE
  else if(train$x1[i] <= 65)
    tmp.age[i] <- Age60to65.WOE
  else if(train$x1[i] <= 75)
    tmp.age[i] <- Age65to75.WOE
  else
    tmp.age[i] <- Agemorethan.WOE
}
table(tmp.age)
tmp.age[1:10]
train$x1[1:10]





4.WOE DataFrame構建

trainWOE =cbind.data.frame(tmp.age,tmp.NumberOfTime30.59DaysPastDueNotWorse,tmp.MonthlyIncome,tmp.NumberOfTime60.89DaysPastDueNotWorse<br data-filtered="filtered">                           ,tmp.NumberOfTimes90DaysLate,tmp.NumberRealEstateLoansOrLines,tmp.NumberOfDependents)

5.看一下各個變量的IV值


八、評分卡的創(chuàng)建和實施



邏輯回歸建模

#因為數(shù)據(jù)中“1”代表的是違約,直接建模預測,求的是“發(fā)生違約的概率”,log(odds)即為“壞好比”。為了符合常規(guī)理解,分數(shù)越高,信用越好,所有就調(diào)換“0”和“1”,使建模預測結果為“不發(fā)生違約的概率”,最后log(odds)即表示為“好壞比”。
trainWOE$y = 1-train$y
glm.fit = glm(y~.,data = trainWOE,family = binomial(link = logit))
summary(glm.fit)
coe = (glm.fit$coefficients)
p <- 20/log(2)
q <- 600-20*log(15)/log(2)
Score=q + p*{as.numeric(coe[1])+as.numeric(coe[2])*tmp.age +as.numeric(coe[3])*tmp.NumberOfTime30.59DaysPastDueNotWorse+p*as.numeric(coe[4])*tmp.MonthlyIncome+p*as.numeric(coe[5])*tmp.NumberOfTime60.89DaysPastDueNotWorse+p*as.numeric(coe[6])*tmp.NumberOfTimes90DaysLate+p*as.numeric(coe[7])*tmp.NumberRealEstateLoansOrLines+p*as.numeric(coe[8])*tmp.NumberOfDependents

個人總評分=基礎分+各部分得分
基礎分為:

base <- q + p*as.numeric(coe[1])
base

對各變量進行打分

Agelessthan30.SCORE = p*as.numeric(coe[2])*Agelessthan30.WOE
Age30to35.SCORE = p*as.numeric(coe[2])*Age30to35.WOE
Age35to40.SCORE = p*as.numeric(coe[2])*Age35to40.WOE
Age40to45.SCORE = p*as.numeric(coe[2])*Age40to45.WOE
Age45to50.SCORE = p*as.numeric(coe[2])*Age45to50.WOE
Age50to55.SCORE = p*as.numeric(coe[2])*Age50to55.WOE
Age55to60.SCORE = p*as.numeric(coe[2])*Age55to60.WOE
Age60to65.SCORE = p*as.numeric(coe[2])*Age60to65.WOE
Age65to75.SCORE = p*as.numeric(coe[2])*Age65to75.WOE
Agemorethan.SCORE=p*as.numeric(coe[2])*Agemorethan.WOE
Age.SCORE =c(Age30to35.SCORE,Age35to40.SCORE,Age40to45.SCORE,Age45to50.SCORE,Age50to55.SCORE,Age55to60.SCORE,Age60to65.SCORE,Age65to75.SCORE,Agemorethan.SCORE)
Age.SCORE


計算各變量分箱得分:

Agelessthan30.SCORE = getscore(2,Agelessthan30.WOE)
Age30to35.SCORE = getscore(2,Age30to35.WOE)
Age35to40.SCORE = getscore(2,Age35to40.WOE)
Age40to45.SCORE = getscore(2,Age40to45.WOE)
Age45to50.SCORE = getscore(2,Age45to50.WOE)
Age50to55.SCORE = getscore(2,Age50to55.WOE)
Age55to60.SCORE = getscore(2,Age55to60.WOE)
Age60to65.SCORE = getscore(2,Age60to65.WOE)
Age65to75.SCORE = getscore(2,Age65to75.WOE)
Agemorethan.SCORE = getscore(2,Agemorethan.WOE)
Age.SCORE = c(Agelessthan30.SCORE,Age30to35.SCORE,Age35to40.SCORE,Age40to45.SCORE,Age45to50.SCORE,Age50to55.SCORE,Age55to60.SCORE,Age60to65.SCORE,Age65to75.SCORE,Agemorethan.SCORE)
Age.SCORE


最終生成的評分卡如下:



個人評分計算案例:

所以這個人的總評分 = 基礎分(base)+ 各特征分數(shù)
總評分 = 446.2841+7+47+10+38-3+62+2 = 609.2841
建立自動評分系統(tǒng):

#計算每一個借款人的信用評分
#age
score.age <- 0
for(i in 1:nrow(train)) {
  if(train$x2[i] <= 30)
    score.age[i] <- Agelessthan30.SCORE
  else if(train$x2[i] <= 35)
    score.age[i] <- Age30to35.SCORE
  else if(train$x2[i] <= 40)
    score.age[i] <- Age35to40.SCORE
  else if(train$x2[i] <= 45)
    score.age[i] <- Age40to45.SCORE
  else if(train$x2[i] <= 50)
    score.age[i] <- Age45to50.SCORE
  else if(train$x2[i] <= 55)
    score.age[i] <- Age50to55.SCORE
  else if(train$x2[i] <= 60)
    score.age[i] <- Age55to60.SCORE
  else if(train$x2[i] <= 65)
    score.age[i] <- Age60to65.SCORE
  else if(train$x2[i] <= 75)
    score.age[i] <- Age65to75.SCORE
  else
    score.age[i] <- Agemorethan.SCORE
}
for(i in 1:nrow(train)){
creditScore[i]<-score.age[i]+score.PastDue[i]+score.MonthIncome[i]+
score.Days90PastDue[i]+score.RealEstate[i]+score.Days60.89PastDue[i]+score.Dependents[i]+baseScore
}
train$creditScore<-round(creditScore,0)


本文通過對于Kaggle上項目的數(shù)據(jù)進行分析,利用邏輯回歸制作了一個簡單的評分卡。在建立評分卡的過程中,首先進行了數(shù)據(jù)清洗,對缺失值和異常值進行了處理并對數(shù)據(jù)分布進行了宏觀展示。然后對特征值進行了處理,將連續(xù)的變量分箱,同時計算了woe和iv值,并保留了iv值較高的變量對其woe轉化。最后將woe轉化后的數(shù)據(jù)進行邏輯回歸分析,利用得到變量系數(shù)并自行擬定了評分標準建立了評分卡。
本項目還有許多不足之處,比如分箱應當使用最優(yōu)分箱或卡方分箱,減少人為分箱的隨機性,此外模型采用的是邏輯回歸算法,還可以多多嘗試其他模型。
PS:
信用卡評分模型學習筆記總結(轉)
https://blog.csdn.net/huipingx/article/details/85225711
其他代碼

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容