評分卡項目總結

一、分析目的

信用評分A卡製作,判斷用戶是否違約。

二、數據處理

這一步不僅涉及列名修改、去重、缺失值、異常值等常規處理,還有WOE分箱處理。

2.1、列名格式規範性處理

修改部分列名,比如數據中的‘NumberOfTime60-89DaysPastDueNotWorse’和‘NumberOfTime30-59DaysPastDueNotWorse’兩列。由於一些算法或方法,列名中的某些符號會帶來問題甚至報錯,例如這裏的"-",會在迴歸公式中被認爲是減號,所以換成"_"。

train_data.columns=train_data.columns.map(lambda x:x.replace('-','_'))

2.2、重複數據處理

刪除重複行數據。重複數據,容易導致迴歸係數標準誤降低,使得對應p值減小。

train_data.drop_duplicates(inplace=True)

2.3、缺失值處理

2.3.1、查看缺失值分佈情況

我們使用missingno庫的matrix()方法查看各特徵缺失值情況。

import missingno as msno
msno.matrix(train_data)
plt.show()

在這裏插入圖片描述從上圖看,‘MonthlyIncome’和‘NumberOfDependents’兩列存在缺失值,前者佔比最多大於80%,後者佔比較少。

2.3.2、缺失值處理邏輯

1、常規的缺失值處理方法是佔比超過80%缺失值數據直接刪除。對於信用評分卡來說,由於所有變量都需要分箱,故這裏缺失值作爲單獨的箱子即可。
2、對於最後一列‘NumberOfDependents’,缺失值佔比只有2.56%,作爲單獨的箱子信息不夠,故做單一值填補,這列表示家庭人口數,有右偏的傾向,且屬於計數的數據,故使用中位數填補。

2.3.2、單一值替換缺失值

將最後一列‘NumberOfDependents’的缺失值替換成中位數。

NOD_median=train_data['NumberOfDependents'].median()
train_data['NumberOfDependents'].fillna(NOD_median,inplace=True)

2.4、異常值處理

異常值常見的處理方法有刪除所在的行、替換成缺失值(與缺失值一起處理)或蓋帽法處理。結合業務邏輯和算法需求判斷是否需要處理異常值以及如何處理,一般情況下蓋帽法即可,即將極端異常的值改成不那麼異常的極值,當然一些算法例如決策樹中連續變量的異常值也可以不做處理。我們先定義好蓋帽法函數,需要的時候再拿來用。

def block(x,lower=True,upper=True):
# x是輸入的Series對象,lower表示是否替換1%分位數,upper表示是否替換99%分位數
    ql=x.quantile(0.01)
    qu=x.quantile(0.99)
    if lower:
        out=x.mask(x<ql,ql)
    if upper:
        out=x.mask(x>qu,qu)
    return out

2.4、自定義函數,彙總數據清洗過程

我們先自定義一個函數,封裝數據清洗過程,後面新數據預測時可以使用該函數同步數據清洗工作。

def datacleaning(testdata,include_y=False):
    testdata.columns=testdata.columns.map(lambda x:x.replace('-','_'))
    testdata['NumberOfDependents'].fillna(NOD_median,inplace=True)      #新數據的缺失值需要用訓練集的填充方式處理
    if include_y:
        testdata["SeriousDlqin2yrs"]=1-testdata.SeriousDlqin2yrs  #好客戶用1表示,壞客戶用0表示,便於混淆矩陣指標分析提取
    return testdata

三、特徵選擇

首先,我們自定義一個外部文件smob.py,這個文件封裝了通過決策樹選擇特徵函數、生成WOE及計算IV值函數、計算模型評估指標函數。
注:所涉及的函數,文章最後完整代碼內已詳細羅列。

3.1、對每個X生成分箱對象

先用‘RevolvingUtilizationOfUnsecuredLines’特徵作說明,其他特徵是一樣的操作方法。
1、先初始化數據

y='SeriousDlqin2yrs' #初始化一個標籤名變量
iv_all=pd.Series()   #初始化一個空序列變量,用於存放各特徵IV值

2、調用smbin函數求出特徵的woe數據及IV值。

RUO=smbin(train_data,y,'RevolvingUtilizationOfUnsecuredLines')

在這裏插入圖片描述

3.2、查看所有特徵IV值

IV值是用於篩選重要特徵的指標之一。依據IV值刪除小於0.02的特徵。一般地,IV<0.02,對預測幾乎無幫助;0.02≤IV<0.1,具有一定幫助;0.1≤IV<0.3,對預測有較大幫助; IV≥0.3,具有很大幫助。

iv_all.sort_values(ascending=False)

在這裏插入圖片描述從結果上看,這些特徵多少重要特徵。接下來我們初步建模看看效果。

3.3、生成WOE數據

分箱原則:分箱數適中,不宜過多過少;各個分箱內記錄數合理;分箱應該體現出明顯的趨勢特性;相鄰分箱的差異不宜過大。我們是選擇有監督式分箱方式,算法選擇的是CART樹。
1、初始化列表
之前smbin和smbin_cu得到的對象根據IV值篩選後,放在一個列表中。

x_list = [RUO,age,NO3059,DebtRatio,MonthlyIncome,NOO,NO90,NRE,NO6089,NOD]

2、生成WOE數據
使用smgen函數根據得到的列表生成新數據

data_woe=smgen(train_data,x_list)
data_woe.head()

在這裏插入圖片描述

四、建模

4.1、初步建模

建立邏輯迴歸模型,擬合數據,查看回歸結果。

glmodel=sm.GLM(Y_train,X_train,family=sm.families.Binomial()).fit()
glmodel.summary()    
#可以查看係數(coef)、係數標準誤(std err)
#P>|z|,就是P檢驗,小於0.05說明顯著,說明變量是重要變量

在這裏插入圖片描述
從模型返回的結果看,IV值能幫我們篩選重要特徵,但不是準確方法。數據上看起來IV值很高並不一定是重要特徵。接下來,我們需要進行假設檢驗,我們選擇P檢驗(小於0.05,纔是重要特徵)。我們發現‘NumberOfOpenCreditLinesAndLoans_woe ’特徵的P值高於0.05,所以我們選擇刪除該特徵。

4.2、查看共線性

計算每個預測變量的vif值,查看變量間是否存在共線性。VIF值越大,係數標準誤會越來越大,置信區間就特別小。VIF在[1,3)之間,變量可以直接用;[3,7)之間,需稍微處理數據才能用;[7,10)之間,數據必須處理才能使用;大於10,出現共線性現象,需改變變量。

vif=[variance_inflation_factor(X_train.iloc[:,1:].values,i
                              ) for i in range(X_train.shape[1]-1)]
print(pd.Series(dict(zip(X_train.columns[1:],vif))))

在這裏插入圖片描述從結果上看出,變量間不存在共線現象。接下來製作評分卡。

五、生成評分卡

5.1、生成信用評分模型原理

1、對於特定分數,好客戶和壞客戶有一定的比例關係,即優比(odds),odds=xPctGood/xPctBad。
2、增加一定評分值時優比增加一倍,例如增加45分,odds增加一倍(從50:1到100:1)
3、公式(5.1):Score = Offset + Factor × ln(odds);公式(5.2):Score + pdo = Offset + Factor × ln(2 × odds)
4、此時我們需要用到自定義函數smscale(模型,特徵列表,pdo,score,odds)我們先是通過業務提供的分值範圍結合上述兩個公式來調整pdo,score,odds三個參數的值。
這裏業務提高的範圍是[300, 843],最終我們獲得參數值:pdo=43,score=1151,odds=10。

5.2、計算各分類評分

Logistic邏輯迴歸得到的迴歸方程左邊 ,代入上一步驟的信用評分公式(5.1)。
在這裏插入圖片描述我們自定義函數ScoreCard保存的就是各分類評分結果,scorecard.ScoreCard即可獲得數據。

在這裏插入圖片描述

六、評估模型

我們是通過繪製KS曲線來進行評估。
1、根據之前的分卡對象得到測試集分數。

testscore=smscoregen(scorecard,X_test)

2、通過測試集中真實的y,和預測的分數,繪製ks曲線;同時得到對應的最優閾值以及相關度量。

evaluate1=evaluate01(Y_test,testscore['Score'],index='ks',plot='ks')

在這裏插入圖片描述

七、新數據預測

1、先讀取數據。

test_data=pd.read_csv('data/CreditScore_data/give-me-some-credit-dataset/cs-test.csv',index_col=0)

2、對數據進行與訓練數據相同的清洗,即使用之前定義的清洗函數。

test0=datacleaning(test_data)

3、由之前得到的分箱對象生成包含woe列的數據。

test_woe=smgennew(test0,x_list)
test_woe.head()

4、抽取WOE數據生成預測用數據,並加上常數項列。

T=test_woe.iloc[:,-len(x_list):]
T=sm.add_constant(T)

5、預測每行數據的分數,生成總分數和每個特徵的分數。

Tscore=smscoregen(scorecard,T)

6、根據分數和訓練得到的閾值判斷客戶的好壞,好客戶是1,壞客戶是0。

test0[y]=(Tscore.Score>evaluate1.cutoff)*1
test0.head()

在這裏插入圖片描述
查看AUC值:evaluate1.AUC=0.8609421718165055。說明我們的模型泛化能力還是不錯的。

八、總結

1、本項目的重點是分箱和找出重要特徵,數據清洗的工作較少。
2、本項目難點是調參,先要固定一個score參數,然後調整其他兩個參數,觀察數據變化趨勢。score參數相當天平中線,另兩個參數pdo和odds是左右兩邊的砝碼,左右砝碼增減數據就可以達到目標。
3、需要注意的是迴歸類算法對重複值、缺失值、變量間共線現象特別敏感。在建模前一點要分析和處理到位。
4、另一個注意的細節就是我們在作缺失值處理前需要先劃分數據集,然後再進行數據處理。在對訓練集進行處理時,也要同步處理測試集數據(一定要先按訓練集的邏輯)。

附完整代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章