引言
信用評(píng)分卡是一個(gè)通過(guò)對(duì)個(gè)人的信用數(shù)據(jù)進(jìn)行評(píng)估進(jìn)而法對(duì)其還款能力和還款意愿進(jìn)行定量評(píng)估的系統(tǒng)留荔。在消費(fèi)金融行業(yè),信用評(píng)分卡主要有三種(A卡澜倦、B卡聚蝶、C卡):
A卡(Application score card)申請(qǐng)?jiān)u分卡,側(cè)重貸前藻治,一般用于預(yù)測(cè)客戶的違約風(fēng)險(xiǎn)碘勉。
B卡(Behavior score card)行為評(píng)分卡,側(cè)重貸中桩卵,一般用于預(yù)測(cè)客戶開戶后一定時(shí)期內(nèi)違約拖欠的風(fēng)險(xiǎn)验靡。
C卡(Collection score card)催收評(píng)分卡,側(cè)重貸后雏节,一般用于在帳戶管理期胜嗓,對(duì)逾期帳戶預(yù)測(cè)催收策略反應(yīng)的概率。
簡(jiǎn)言之钩乍,評(píng)分卡就是一個(gè)數(shù)據(jù)驅(qū)動(dòng)的辞州,用于衡量客戶是好客戶還是壞客戶的一個(gè)工具。
本文的初衷就是以經(jīng)典的邏輯回歸模型為主件蚕,完成一套標(biāo)準(zhǔn)申請(qǐng)?jiān)u分卡的構(gòu)建孙技。本篇文章主要是對(duì)評(píng)分卡建模的數(shù)據(jù)進(jìn)行分析产禾,在此基礎(chǔ)上確定預(yù)處理方案,并完成建模前的數(shù)據(jù)預(yù)處理牵啦。
一亚情、項(xiàng)目流程
典型的信用評(píng)分模型如圖1-1所示。信用風(fēng)險(xiǎn)評(píng)級(jí)模型的主要開發(fā)流程如下:
1.數(shù)據(jù)獲取哈雏,包括獲取存量客戶及潛在客戶的數(shù)據(jù)楞件。存量客戶是指已經(jīng)在證券公司開展相關(guān)融資類業(yè)務(wù)的客戶,包括個(gè)人客戶和機(jī)構(gòu)客戶裳瘪;潛在客戶是指未來(lái)擬在證券公司開展相關(guān)融資類業(yè)務(wù)的客戶土浸,主要包括機(jī)構(gòu)客戶,這也是解決證券業(yè)樣本較少的常用方法彭羹,這些潛在機(jī)構(gòu)客戶包括上市公司黄伊、公開發(fā)行債券的發(fā)債主體、新三板上市公司派殷、區(qū)域股權(quán)交易中心掛牌公司还最、非標(biāo)融資機(jī)構(gòu)等。
2.數(shù)據(jù)預(yù)處理毡惜,主要工作包括數(shù)據(jù)清洗拓轻、缺失值處理、異常值處理经伙,主要是為了將獲取的原始數(shù)據(jù)轉(zhuǎn)化為可用作模型開發(fā)的格式化數(shù)據(jù)扶叉。
3.探索性數(shù)據(jù)分析,該步驟主要是獲取樣本總體的大概情況帕膜,描述樣本總體情況的指標(biāo)主要有直方圖枣氧、箱形圖等。
4.變量選擇泳叠,該步驟主要是通過(guò)統(tǒng)計(jì)學(xué)的方法作瞄,篩選出對(duì)違約狀態(tài)影響最顯著的指標(biāo)。主要有單變量特征選擇方法和基于機(jī)器學(xué)習(xí)模型的方法危纫。
5.模型開發(fā)宗挥,該步驟主要包括變量分段、變量的WOE(證據(jù)權(quán)重)變換和邏輯回歸估算三部分种蝶。
6.模型評(píng)估契耿,該步驟主要是評(píng)估模型的區(qū)分能力、預(yù)測(cè)能力螃征、穩(wěn)定性搪桂,并形成模型評(píng)估報(bào)告,得出模型是否可以使用的結(jié)論。
7.信用評(píng)分踢械,根據(jù)邏輯回歸的系數(shù)和WOE等確定信用評(píng)分的方法酗电。將Logistic模型轉(zhuǎn)換為標(biāo)準(zhǔn)評(píng)分的形式。
8.建立評(píng)分系統(tǒng)内列,根據(jù)信用評(píng)分方法撵术,建立自動(dòng)信用評(píng)分系統(tǒng)。
二话瞧、數(shù)據(jù)獲取
數(shù)據(jù)來(lái)自Kaggle嫩与,有15萬(wàn)條的樣本數(shù)據(jù),下圖可以看到這份數(shù)據(jù)的大致情況交排。
數(shù)據(jù)屬于個(gè)人消費(fèi)類貸款划滋,只考慮信用評(píng)分最終實(shí)施時(shí)能夠使用到的數(shù)據(jù)應(yīng)從如下一些方面獲取數(shù)據(jù):
– 基本屬性:包括了借款人當(dāng)時(shí)的年齡。
– 償債能力:包括了借款人的月收入埃篓、負(fù)債比率处坪。
– 信用往來(lái):兩年內(nèi)35-59天逾期次數(shù)、兩年內(nèi)60-89天逾期次數(shù)都许、兩年內(nèi)90
天或高于90天逾期的次數(shù)稻薇。
– 財(cái)產(chǎn)狀況:包括了開放式信貸和貸款數(shù)量、不動(dòng)產(chǎn)貸款或額度數(shù)量胶征。
– 貸款屬性:暫無(wú)。
– 其他因素:包括了借款人的家屬數(shù)量(不包括本人在內(nèi))桨仿。
– 時(shí)間窗口:自變量的觀察窗口為過(guò)去兩年祷安,因變量表現(xiàn)窗口為未來(lái)兩年窑多。
三、數(shù)據(jù)預(yù)處理
在對(duì)數(shù)據(jù)處理之前,需要對(duì)數(shù)據(jù)的缺失值和異常值情況進(jìn)行了解女阀。Python內(nèi)有describe()函數(shù),可以了解數(shù)據(jù)集的缺失值晰房、均值和中位數(shù)等滨嘱。
#載入數(shù)據(jù)
data = pd.read_csv('cs-training.csv')
#數(shù)據(jù)集確實(shí)和分布情況
data.describe().to_csv('DataDescribe.csv')
數(shù)據(jù)集的詳細(xì)情況:
從上圖可知,變量MonthlyIncome和NumberOfDependents存在缺失灿椅,變量MonthlyIncome共有缺失值29731個(gè)套蒂,NumberOfDependents有3924個(gè)缺失值。
3.1 缺失值處理
這種情況在現(xiàn)實(shí)問(wèn)題中非常普遍茫蛹,這會(huì)導(dǎo)致一些不能處理缺失值的分析方法無(wú)法應(yīng)用操刀,因此,在信用風(fēng)險(xiǎn)評(píng)級(jí)模型開發(fā)的第一步我們就要進(jìn)行缺失值處理婴洼。缺失值處理的方法骨坑,包括如下幾種。
1.直接刪除含有缺失值的樣本柬采。
2.根據(jù)樣本之間的相似性填補(bǔ)缺失值欢唾。
3.根據(jù)變量之間的相關(guān)關(guān)系填補(bǔ)缺失值且警。
變量MonthlyIncome缺失率比較大,所以我們根據(jù)變量之間的相關(guān)關(guān)系填補(bǔ)缺失值礁遣,我們采用隨機(jī)森林法:
# 用隨機(jī)森林對(duì)缺失值預(yù)測(cè)填充函數(shù)
def set_missing(df):
# 把已有的數(shù)值型特征取出來(lái)
process_df = df.ix[:,[5,0,1,2,3,4,6,7,8,9]]
# 分成已知該特征和未知該特征兩部分
known = process_df[process_df.MonthlyIncome.notnull()].as_matrix()
unknown = process_df[process_df.MonthlyIncome.isnull()].as_matrix()
# X為特征屬性值
X = known[:, 1:]
# y為結(jié)果標(biāo)簽值
y = known[:, 0]
# fit到RandomForestRegressor之中
rfr = RandomForestRegressor(random_state=0,
n_estimators=200,max_depth=3,n_jobs=-1)
rfr.fit(X,y)
# 用得到的模型進(jìn)行未知特征值預(yù)測(cè)
predicted = rfr.predict(unknown[:, 1:]).round(0)
print(predicted)
# 用得到的預(yù)測(cè)結(jié)果填補(bǔ)原缺失數(shù)據(jù)
df.loc[(df.MonthlyIncome.isnull()), 'MonthlyIncome'] = predicted
return df
NumberOfDependents變量缺失值比較少斑芜,直接刪除,對(duì)總體模型不會(huì)造成太大影響亡脸。對(duì)缺失值處理完之后押搪,刪除重復(fù)項(xiàng)。
data=set_missing(data)#用隨機(jī)森林填補(bǔ)比較多的缺失值
data=data.dropna()#刪除比較少的缺失值
data = data.drop_duplicates()#刪除重復(fù)項(xiàng)
data.to_csv('MissingData.csv',index=False)
3.2 異常值處理
缺失值處理完畢后浅碾,我們還需要進(jìn)行異常值處理大州。異常值是指明顯偏離大多數(shù)抽樣數(shù)據(jù)的數(shù)值,比如個(gè)人客戶的年齡為0時(shí)垂谢,通常認(rèn)為該值為異常值厦画。找出樣本總體中的異常值,通常采用離群值檢測(cè)的方法滥朱。
首先根暑,我們發(fā)現(xiàn)變量age中存在0,顯然是異常值徙邻,直接剔除:
# 年齡等于0的異常值進(jìn)行剔除
data = data[data['age'] > 0]
對(duì)于變量NumberOfTime30-59DaysPastDueNotWorse排嫌、NumberOfTimes90DaysLate、NumberOfTime60-89DaysPastDueNotWorse這三個(gè)變量缰犁,由下面的箱線圖圖3-2可以看出淳地,均存在異常值,且由unique函數(shù)可以得知均存在96帅容、98兩個(gè)異常值颇象,因此予以剔除。同時(shí)會(huì)發(fā)現(xiàn)剔除其中一個(gè)變量的96并徘、98值遣钳,其他變量的96、98兩個(gè)值也會(huì)相應(yīng)被剔除麦乞。
剔除變量NumberOfTime30-59DaysPastDueNotWorse蕴茴、NumberOfTimes90DaysLate、NumberOfTime60-89DaysPastDueNotWorse的異常值路幸。另外荐开,數(shù)據(jù)集中好客戶為0,違約客戶為1简肴,考慮到正常的理解晃听,能正常履約并支付利息的客戶為1,所以我們將其取反。
#剔除異常值
data = data[data['NumberOfTime30-59DaysPastDueNotWorse'] < 90]
#變量SeriousDlqin2yrs取反
data['SeriousDlqin2yrs']=1-data['SeriousDlqin2yrs']
3.3 數(shù)據(jù)切分
為了驗(yàn)證模型的擬合效果能扒,我們需要對(duì)數(shù)據(jù)集進(jìn)行切分佣渴,分成訓(xùn)練集和測(cè)試集。
from sklearn.cross_validation import train_test_split
Y = data['SeriousDlqin2yrs']
X = data.ix[:, 1:]
#測(cè)試集占比30%
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=0)
# print(Y_train)
train = pd.concat([Y_train, X_train], axis=1)
test = pd.concat([Y_test, X_test], axis=1)
clasTest = test.groupby('SeriousDlqin2yrs')['SeriousDlqin2yrs'].count()
train.to_csv('TrainData.csv',index=False)
test.to_csv('TestData.csv',index=False)
四初斑、探索性分析
在建立模型之前辛润,我們一般會(huì)對(duì)現(xiàn)有的數(shù)據(jù)進(jìn)行 探索性數(shù)據(jù)分析(Exploratory Data Analysis) 。 EDA是指對(duì)已有的數(shù)據(jù)(特別是調(diào)查或觀察得來(lái)的原始數(shù)據(jù))在盡量少的先驗(yàn)假定下進(jìn)行探索见秤。常用的探索性數(shù)據(jù)分析方法有:直方圖砂竖、散點(diǎn)圖和箱線圖等。
客戶年齡分布如圖4-1所示鹃答,可以看到年齡變量大致呈正態(tài)分布乎澄,符合統(tǒng)計(jì)分析的假設(shè)。
客戶年收入分布如圖4-2所示测摔,月收入也大致呈正態(tài)分布置济,符合統(tǒng)計(jì)分析的需要
五、變量選擇
特征變量選擇(排序)對(duì)于數(shù)據(jù)分析挟纱、機(jī)器學(xué)習(xí)從業(yè)者來(lái)說(shuō)非常重要羞酗。好的特征選擇能夠提升模型的性能,更能幫助我們理解數(shù)據(jù)的特點(diǎn)紊服、底層結(jié)構(gòu)整慎,這對(duì)進(jìn)一步改善模型、算法都有著重要作用围苫。至于Python的變量選擇代碼實(shí)現(xiàn)可以參考結(jié)合Scikit-learn介紹幾種常用的特征選擇方法。
在本文中撤师,我們采用信用評(píng)分模型的變量選擇方法剂府,通過(guò)WOE分析方法,即是通過(guò)比較指標(biāo)分箱和對(duì)應(yīng)分箱的違約概率來(lái)確定指標(biāo)是否符合經(jīng)濟(jì)意義剃盾。首先我們對(duì)變量進(jìn)行離散化(分箱)處理腺占。
5.1 分箱處理
變量分箱(binning)是對(duì)連續(xù)變量離散化(discretization)的一種稱呼。信用評(píng)分卡開發(fā)中一般有常用的等距分段痒谴、等深分段衰伯、最優(yōu)分段。其中等距分段(Equval length intervals)是指分段的區(qū)間是一致的积蔚,比如年齡以十年作為一個(gè)分段意鲸;等深分段(Equal frequency intervals)是先確定分段數(shù)量,然后令每個(gè)分段中數(shù)據(jù)數(shù)量大致相等;最優(yōu)分段(Optimal Binning)又叫監(jiān)督離散化(supervised discretizaion)怎顾,使用遞歸劃分(Recursive Partitioning)將連續(xù)變量分為分段读慎,背后是一種基于條件推斷查找較佳分組的算法。
我們首先選擇對(duì)連續(xù)變量進(jìn)行最優(yōu)分段槐雾,在連續(xù)變量的分布不滿足最優(yōu)分段的要求時(shí)夭委,再考慮對(duì)連續(xù)變量進(jìn)行等距分段。最優(yōu)分箱的代碼如下:
# 定義自動(dòng)分箱函數(shù)
def mono_bin(Y, X, n = 20):
r = 0
good=Y.sum()
bad=Y.count() - good
while np.abs(r) < 1:
d1 = pd.DataFrame({"X": X, "Y": Y, "Bucket": pd.qcut(X, n)})
d2 = d1.groupby('Bucket', as_index = True)
r, p = stats.spearmanr(d2.mean().X, d2.mean().Y)
n = n - 1
d3 = pd.DataFrame(d2.X.min(), columns = ['min'])
d3['min']=d2.min().X
d3['max'] = d2.max().X
d3['sum'] = d2.sum().Y
d3['total'] = d2.count().Y
d3['rate'] = d2.mean().Y
d3['woe']=np.log((d3['rate']/(1-d3['rate']))/(good/bad))
d4 = (d3.sort_index(by = 'min')).reset_index(drop=True)
print("=" * 60)
print(d4)
return d4
針對(duì)我們將使用最優(yōu)分段對(duì)于數(shù)據(jù)集中的RevolvingUtilizationOfUnsecuredLines募强、age株灸、DebtRatio和MonthlyIncome進(jìn)行分類。
針對(duì)不能最優(yōu)分箱的變量擎值,分箱如下:
# 連續(xù)變量離散化
cutx3 = [ninf, 0, 1, 3, 5, pinf]
cutx6 = [ninf, 1, 2, 3, 5, pinf]
cutx7 = [ninf, 0, 1, 3, 5, pinf]
cutx8 = [ninf, 0,1,2, 3, pinf]
cutx9 = [ninf, 0, 1, 3, pinf]
cutx10 = [ninf, 0, 1, 2, 3, 5, pinf]
5.2 WOE
WoE分析慌烧, 是對(duì)指標(biāo)分箱、計(jì)算各個(gè)檔位的WoE值并觀察WoE值隨指標(biāo)變化的趨勢(shì)幅恋。其中WoE的數(shù)學(xué)定義是:
woe=ln(goodattribute/badattribute)
在進(jìn)行分析時(shí)杏死,我們需要對(duì)各指標(biāo)從小到大排列,并計(jì)算出相應(yīng)分檔的WoE值捆交。其中正向指標(biāo)越大淑翼,WoE值越小品追;反向指標(biāo)越大玄括,WoE值越大。正向指標(biāo)的WoE值負(fù)斜率越大肉瓦,反響指標(biāo)的正斜率越大遭京,則說(shuō)明指標(biāo)區(qū)分能力好。WoE值趨近于直線泞莉,則意味指標(biāo)判斷能力較弱哪雕。若正向指標(biāo)和WoE正相關(guān)趨勢(shì)、反向指標(biāo)同WoE出現(xiàn)負(fù)相關(guān)趨勢(shì)鲫趁,則說(shuō)明此指標(biāo)不符合經(jīng)濟(jì)意義斯嚎,則應(yīng)當(dāng)予以去除。
woe函數(shù)實(shí)現(xiàn)在上一節(jié)的mono_bin()函數(shù)里面已經(jīng)包含挨厚,這里不再重復(fù)堡僻。
5.3 相關(guān)性分析和IV篩選
接下來(lái),我們會(huì)用經(jīng)過(guò)清洗后的數(shù)據(jù)看一下變量間的相關(guān)性疫剃。注意钉疫,這里的相關(guān)性分析只是初步的檢查,進(jìn)一步檢查模型的VI(證據(jù)權(quán)重)作為變量篩選的依據(jù)巢价。
相關(guān)性圖我們通過(guò)Python里面的seaborn包牲阁,調(diào)用heatmap()繪圖函數(shù)進(jìn)行繪制固阁,實(shí)現(xiàn)代碼如下:
corr = data.corr()#計(jì)算各變量的相關(guān)性系數(shù)
xticks = ['x0','x1','x2','x3','x4','x5','x6','x7','x8','x9','x10']#x軸標(biāo)簽
yticks = list(corr.index)#y軸標(biāo)簽
fig = plt.figure()
ax1 = fig.add_subplot(1, 1, 1)
sns.heatmap(corr, annot=True, cmap='rainbow', ax=ax1, annot_kws={'size': 9, 'weight': 'bold', 'color': 'blue'})#繪制相關(guān)性系數(shù)熱力圖
ax1.set_xticklabels(xticks, rotation=0, fontsize=10)
ax1.set_yticklabels(yticks, rotation=0, fontsize=10)
plt.show()
由上圖可以看出,各變量之間的相關(guān)性是非常小的咨油。NumberOfOpenCreditLinesAndLoans和NumberRealEstateLoansOrLines的相關(guān)性系數(shù)為0.43您炉。
接下來(lái),我進(jìn)一步計(jì)算每個(gè)變量的Infomation Value(IV)役电。IV指標(biāo)是一般用來(lái)確定自變量的預(yù)測(cè)能力赚爵。 其公式為:
IV=sum((goodattribute-badattribute)*ln(goodattribute/badattribute))
通過(guò)IV值判斷變量預(yù)測(cè)能力的標(biāo)準(zhǔn)是:
< 0.02: unpredictive
0.02 to 0.1: weak
0.1 to 0.3: medium
0.3 to 0.5: strong
0.5: suspicious
IV的實(shí)現(xiàn)放在mono_bin()函數(shù)里面,代碼實(shí)現(xiàn)如下:
# 定義自動(dòng)分箱函數(shù)
def mono_bin(Y, X, n = 20):
r = 0
good=Y.sum()
bad=Y.count()-good
while np.abs(r) < 1:
d1 = pd.DataFrame({"X": X, "Y": Y, "Bucket": pd.qcut(X, n)})
d2 = d1.groupby('Bucket', as_index = True)
r, p = stats.spearmanr(d2.mean().X, d2.mean().Y)
n = n - 1
d3 = pd.DataFrame(d2.X.min(), columns = ['min'])
d3['min']=d2.min().X
d3['max'] = d2.max().X
d3['sum'] = d2.sum().Y
d3['total'] = d2.count().Y
d3['rate'] = d2.mean().Y
d3['woe']=np.log((d3['rate']/(1-d3['rate']))/(good/bad))
d3['goodattribute']=d3['sum']/good
d3['badattribute']=(d3['total']-d3['sum'])/bad
iv=((d3['goodattribute']-d3['badattribute'])*d3['woe']).sum()
d4 = (d3.sort_index(by = 'min')).reset_index(drop=True)
print("=" * 60)
print(d4)
cut=[]
cut.append(float('-inf'))
for i in range(1,n+1):
qua=X.quantile(i/(n+1))
cut.append(round(qua,4))
cut.append(float('inf'))
woe=list(d4['woe'].round(3))
return d4,iv,cut,woe
生成的IV圖代碼:
ivlist=[ivx1,ivx2,ivx3,ivx4,ivx5,ivx6,ivx7,ivx8,ivx9,ivx10]#各變量IV
index=['x1','x2','x3','x4','x5','x6','x7','x8','x9','x10']#x軸的標(biāo)簽
fig1 = plt.figure(1)
ax1 = fig1.add_subplot(1, 1, 1)
x = np.arange(len(index))+1
ax1.bar(x, ivlist, width=0.4)#生成柱狀圖
ax1.set_xticks(x)
ax1.set_xticklabels(index, rotation=0, fontsize=12)
ax1.set_ylabel('IV(Information Value)', fontsize=14)
#在柱狀圖上添加數(shù)字標(biāo)簽
for a, b in zip(x, ivlist):
plt.text(a, b + 0.01, '%.4f' % b, ha='center', va='bottom', fontsize=10)
plt.show()
輸出圖像:
可以看出法瑟,DebtRatio冀膝、MonthlyIncome、NumberOfOpenCreditLinesAndLoans霎挟、NumberRealEstateLoansOrLines和NumberOfDependents變量的IV值明顯較低窝剖,所以予以刪除。
六酥夭、模型分析
證據(jù)權(quán)重(Weight of Evidence,WOE)轉(zhuǎn)換可以將Logistic回歸模型轉(zhuǎn)變?yōu)闃?biāo)準(zhǔn)評(píng)分卡格式赐纱。引入WOE轉(zhuǎn)換的目的并不是為了提高模型質(zhì)量,只是一些變量不應(yīng)該被納入模型熬北,這或者是因?yàn)樗鼈儾荒茉黾幽P椭蹈砻瑁蛘呤且驗(yàn)榕c其模型相關(guān)系數(shù)有關(guān)的誤差較大,其實(shí)建立標(biāo)準(zhǔn)信用評(píng)分卡也可以不采用WOE轉(zhuǎn)換讶隐。這種情況下起胰,Logistic回歸模型需要處理更大數(shù)量的自變量。盡管這樣會(huì)增加建模程序的復(fù)雜性巫延,但最終得到的評(píng)分卡都是一樣的效五。
在建立模型之前,我們需要將篩選后的變量轉(zhuǎn)換為WoE值炉峰,便于信用評(píng)分畏妖。
6.1 WOE轉(zhuǎn)換
我們已經(jīng)能獲取了每個(gè)變量的分箱數(shù)據(jù)和woe數(shù)據(jù),只需要根據(jù)各變量數(shù)據(jù)進(jìn)行替換疼阔,實(shí)現(xiàn)代碼如下:
#替換成woe函數(shù)
def replace_woe(series, cut, woe):
list = []
I = 0
while i<len(series):
value=series[i]
j=len(cut) - 2
m=len(cut) - 2
while j >= 0:
if value>=cut[j]:
j = -1
else:
j -= 1
m -= 1
list.append(woe[m])
i += 1
return list
我們將每個(gè)變量都進(jìn)行替換,并將其保存到WoeData.csv文件中:
# 替換成woe
data['RevolvingUtilizationOfUnsecuredLines'] = Series(replace_woe(data['RevolvingUtilizationOfUnsecuredLines'], cutx1, woex1))
data['age'] = Series(replace_woe(data['age'], cutx2, woex2))
data['NumberOfTime30-59DaysPastDueNotWorse'] = Series(replace_woe(data['NumberOfTime30-59DaysPastDueNotWorse'], cutx3, woex3))
data['DebtRatio'] = Series(replace_woe(data['DebtRatio'], cutx4, woex4))
data['MonthlyIncome'] = Series(replace_woe(data['MonthlyIncome'], cutx5, woex5))
data['NumberOfOpenCreditLinesAndLoans'] = Series(replace_woe(data['NumberOfOpenCreditLinesAndLoans'], cutx6, woex6))
data['NumberOfTimes90DaysLate'] = Series(replace_woe(data['NumberOfTimes90DaysLate'], cutx7, woex7))
data['NumberRealEstateLoansOrLines'] = Series(replace_woe(data['NumberRealEstateLoansOrLines'], cutx8, woex8))
data['NumberOfTime60-89DaysPastDueNotWorse'] = Series(replace_woe(data['NumberOfTime60-89DaysPastDueNotWorse'], cutx9, woex9))
data['NumberOfDependents'] = Series(replace_woe(data['NumberOfDependents'], cutx10, woex10))
data.to_csv('WoeData.csv', index=False)
6.2 Logisic模型建立
我們直接調(diào)用statsmodels包來(lái)實(shí)現(xiàn)邏輯回歸:
導(dǎo)入數(shù)據(jù)
data = pd.read_csv('WoeData.csv')
#應(yīng)變量
Y=data['SeriousDlqin2yrs']
#自變量瓜客,剔除對(duì)因變量影響不明顯的變量
X=data.drop(['SeriousDlqin2yrs','DebtRatio','MonthlyIncome', 'NumberOfOpenCreditLinesAndLoans','NumberRealEstateLoansOrLines','NumberOfDependents'],axis=1)
X1=sm.add_constant(X)
logit=sm.Logit(Y,X1)
result=logit.fit()
print(result.summary())
輸出結(jié)果:
通過(guò)圖6-1可知,邏輯回歸各變量都已通過(guò)顯著性檢驗(yàn)竿开,滿足要求。
6.3 模型檢驗(yàn)
到這里玻熙,我們的建模部分基本結(jié)束了否彩。我們需要驗(yàn)證一下模型的預(yù)測(cè)能力如何。我們使用在建模開始階段預(yù)留的test數(shù)據(jù)進(jìn)行檢驗(yàn)嗦随。通過(guò)ROC曲線和AUC來(lái)評(píng)估模型的擬合能力列荔。
在Python中敬尺,可以利用sklearn.metrics,它能方便比較兩個(gè)分類器贴浙,自動(dòng)計(jì)算ROC和AUC砂吞。
實(shí)現(xiàn)代碼:
#應(yīng)變量
Y_test = test['SeriousDlqin2yrs']
#自變量,剔除對(duì)因變量影響不明顯的變量崎溃,與模型變量對(duì)應(yīng)
X_test = test.drop(['SeriousDlqin2yrs', 'DebtRatio', 'MonthlyIncome', 'NumberOfOpenCreditLinesAndLoans','NumberRealEstateLoansOrLines', 'NumberOfDependents'], axis=1)
X3 = sm.add_constant(X_test)
resu = result.predict(X3)#進(jìn)行預(yù)測(cè)
fpr, tpr, threshold = roc_curve(Y_test, resu)
rocauc = auc(fpr, tpr)#計(jì)算AUC
plt.plot(fpr, tpr, 'b', label='AUC = %0.2f' % rocauc)#生成ROC曲線
plt.legend(loc='lower right')
plt.plot([0, 1], [0, 1], 'r--')
plt.xlim([0, 1])
plt.ylim([0, 1])
plt.ylabel('真正率')
plt.xlabel('假正率')
plt.show()
輸出結(jié)果:
從上圖可知蜻直,AUC值為0.85,說(shuō)明該模型的預(yù)測(cè)效果還是不錯(cuò)的袁串,正確率較高概而。
七、信用評(píng)分
我們已經(jīng)基本完成了建模相關(guān)的工作囱修,并用ROC曲線驗(yàn)證了模型的預(yù)測(cè)能力赎瑰。接下來(lái)的步驟,就是將Logistic模型轉(zhuǎn)換為標(biāo)準(zhǔn)評(píng)分卡的形式破镰。
7.1 評(píng)分標(biāo)準(zhǔn)
依據(jù)以上論文資料得到:
a=log(p_good/P_bad)
Score = offset + factor * log(odds)
在建立標(biāo)準(zhǔn)評(píng)分卡之前餐曼,我們需要選取幾個(gè)評(píng)分卡參數(shù):基礎(chǔ)分值、 PDO(比率翻倍的分值)和好壞比鲜漩。 這里源譬, 我們?nèi)?00分為基礎(chǔ)分值,PDO為20 (每高20分好壞比翻一倍)宇整,好壞比取20瓶佳。
# 我們?nèi)?00分為基礎(chǔ)分值,PDO為20(每高20分好壞比翻一倍)鳞青,好壞比取20霸饲。
z = 20 / math.log(2)
q = 600 - 20 * math.log(20) / math.log(2)
baseScore = round(q + p * coe[0], 0)
個(gè)人總評(píng)分=基礎(chǔ)分+各部分得分
7.2 部分評(píng)分
下面計(jì)算各變量部分的分?jǐn)?shù)。各部分得分函數(shù):
#計(jì)算分?jǐn)?shù)函數(shù) def get_score(coe,woe,factor):
scores=[]
for w in woe:
score=round(coe*w*factor,0)
scores.append(score)
return scores
計(jì)算各變量得分情況:
# 各項(xiàng)部分分?jǐn)?shù)
x1 = get_score(coe[1], woex1, p)
x2 = get_score(coe[2], woex2, p)
x3 = get_score(coe[3], woex3, p)
x7 = get_score(coe[4], woex7, p)
x9 = get_score(coe[5], woex9, p)
我們可以得到各部分的評(píng)分卡如圖7-1所示:
八臂拓、自動(dòng)評(píng)分系統(tǒng)
根據(jù)變量來(lái)計(jì)算分?jǐn)?shù)厚脉,實(shí)現(xiàn)如下:
#根據(jù)變量計(jì)算分?jǐn)?shù)
def compute_score(series,cut,score):
list = []
i = 0
while i < len(series):
value = series[i]
j = len(cut) - 2
m = len(cut) - 2
while j >= 0:
if value >= cut[j]:
j = -1
else:
j -= 1
m -= 1
list.append(score[m])
i += 1
return list
我們來(lái)計(jì)算test里面的分?jǐn)?shù):
test1 = pd.read_csv('TestData.csv')
test1['BaseScore']=Series(np.zeros(len(test1)))+baseScore
test1['x1'] = Series(compute_score(test1['RevolvingUtilizationOfUnsecuredLines'], cutx1, x1))
test1['x2'] = Series(compute_score(test1['age'], cutx2, x2))
test1['x3'] = Series(compute_score(test1['NumberOfTime30-59DaysPastDueNotWorse'], cutx3, x3))
test1['x7'] = Series(compute_score(test1['NumberOfTimes90DaysLate'], cutx7, x7)
test1['x9'] = Series(compute_score(test1['NumberOfTime60-89DaysPastDueNotWorse'], cutx9, x9))
test1['Score'] = test1['x1'] + test1['x2'] + test1['x3'] + test1['x7'] +test1['x9'] + baseScore
test1.to_csv('ScoreData.csv', index=False)
批量計(jì)算的部分分結(jié)果:
九、總結(jié)以及展望
本文通過(guò)對(duì)kaggle上的Give Me Some Credit數(shù)據(jù)的挖掘分析胶惰,結(jié)合信用評(píng)分卡的建立原理傻工,從數(shù)據(jù)的預(yù)處理、變量選擇孵滞、建模分析到創(chuàng)建信用評(píng)分中捆,創(chuàng)建了一個(gè)簡(jiǎn)單的信用評(píng)分系統(tǒng)。
基于Logistic的機(jī)器學(xué)習(xí)評(píng)分卡系統(tǒng)可通過(guò)定期更新訓(xùn)練數(shù)據(jù)后再進(jìn)行自動(dòng)建模坊饶、模型評(píng)估泄伪、并不斷優(yōu)化特征變量,使得系統(tǒng)更加強(qiáng)大匿级。