信用評分模型開發(fā)

信用評分模型可用“四張卡”來表示驻呐,分別是 A卡(Application score card垒手,申請評分卡)、B卡(Behavior score card蛉艾,行為評分卡)、C卡(Collection score card衷敌,催收評分卡)和 F卡(Anti-Fraud Card勿侯,反欺詐評分卡),分別應(yīng)用于貸前缴罗、貸中助琐、貸后。

本篇我們主要討論基于Python的信用評分模型開發(fā)面氓,并在各部分附上了相關(guān)代碼兵钮。

1 項目流程

典型的信用評分模型如圖1-1所示沟堡。信用風險評級模型的主要開發(fā)流程如下:
1.數(shù)據(jù)獲取,包括獲取存量客戶及潛在客戶的數(shù)據(jù)矢空。存量客戶是指已開展相關(guān)業(yè)務(wù)的客戶航罗;潛在客戶是指未來擬開展相關(guān)業(yè)務(wù)的客戶。
2.數(shù)據(jù)預(yù)處理屁药,主要工作包括數(shù)據(jù)清洗粥血、缺失值處理、異常值處理酿箭,主要是為了將獲取的原始數(shù)據(jù)轉(zhuǎn)化為可用作模型開發(fā)的格式化數(shù)據(jù)复亏。
3.探索性數(shù)據(jù)分析,該步驟主要是獲取樣本總體的大概情況缭嫡,描述樣本總體情況的指標主要有直方圖缔御、箱形圖等。
4.變量選擇妇蛀,該步驟主要是通過統(tǒng)計學的方法耕突,篩選出對違約狀態(tài)影響最顯著的指標。主要有單變量特征選擇方法和基于機器學習模型的方法评架。
5.模型開發(fā)眷茁,該步驟主要包括變量分段、變量的WOE(證據(jù)權(quán)重)變換和邏輯回歸估算三部分纵诞。
6.模型評估上祈,該步驟主要是評估模型的區(qū)分能力、預(yù)測能力浙芙、穩(wěn)定性登刺,并形成模型評估報告,得出模型是否可以使用的結(jié)論嗡呼。
7.信用評分纸俭,根據(jù)邏輯回歸的系數(shù)和WOE等確定信用評分的方法。將Logistic模型轉(zhuǎn)換為標準評分的形式晤锥。
8.建立評分系統(tǒng)掉蔬,根據(jù)信用評分方法,建立自動信用評分系統(tǒng)矾瘾。

圖1-1 信用評分模型開發(fā)流程.png

2 數(shù)據(jù)獲取

數(shù)據(jù)來自Kaggle的Give Me Some Credit:https://www.kaggle.com/c/GiveMeSomeCredit/data,有15萬條的樣本數(shù)據(jù)箭启,下圖可以看到這份數(shù)據(jù)的大致情況壕翩。

數(shù)據(jù)屬于個人消費類貸款,只考慮信用評分最終實施時能夠使用到的數(shù)據(jù)應(yīng)從如下一些方面獲取數(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))。
– 時間窗口:自變量的觀察窗口為過去兩年拐迁,因變量表現(xiàn)窗口為未來兩年蹭劈。

圖2-1 原始數(shù)據(jù)的變量.png

3 數(shù)據(jù)預(yù)處理

在對數(shù)據(jù)處理之前,需要對數(shù)據(jù)的缺失值和異常值情況進行了解线召。Python內(nèi)有describe()函數(shù)铺韧,可以了解數(shù)據(jù)集的缺失值、均值和中位數(shù)等缓淹。

#載入數(shù)據(jù)
data = pd.read_csv('cs-training.csv')
#數(shù)據(jù)集確實和分布情況
data.describe().to_csv('DataDescribe.csv')

數(shù)據(jù)集的詳細情況:


圖3-1 變量詳細情況.png

從上圖可知哈打,變量 MonthlyIncome 和 NumberOfDependents 存在缺失,變量 MonthlyIncome 共有缺失值 29731 個讯壶,NumberOfDependents 有 3924 個缺失值前酿。

3.1 缺失值處理

這種情況在現(xiàn)實問題中非常普遍,這會導(dǎo)致一些不能處理缺失值的分析方法無法應(yīng)用鹏溯,因此罢维,在信用風險評級模型開發(fā)的第一步我們就要進行缺失值處理。缺失值處理的方法丙挽,包括如下幾種肺孵。

1.直接刪除含有缺失值的樣本

2.根據(jù)樣本之間的相似性填補缺失值颜阐。

3.根據(jù)變量之間的相關(guān)關(guān)系填補缺失值平窘。

變量 MonthlyIncome 缺失率比較大,所以我們根據(jù)變量之間的相關(guān)關(guān)系填補缺失值凳怨,我們采用隨機森林法:

# 用隨機森林對缺失值預(yù)測填充函數(shù)
def set_missing(df):
    # 把已有的數(shù)值型特征取出來
    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é)果標簽值
    y = known[:, 0]
    # fit到RandomForestRegressor之中
    rfr = RandomForestRegressor(random_state=0,
    n_estimators=200,max_depth=3,n_jobs=-1)
    rfr.fit(X,y)
    # 用得到的模型進行未知特征值預(yù)測
    predicted = rfr.predict(unknown[:, 1:]).round(0)
    print(predicted)
    # 用得到的預(yù)測結(jié)果填補原缺失數(shù)據(jù)
    df.loc[(df.MonthlyIncome.isnull()), 'MonthlyIncome'] = predicted
    return df

NumberOfDependents 變量缺失值比較少瑰艘,直接刪除,對總體模型不會造成太大影響肤舞。對缺失值處理完之后紫新,刪除重復(fù)項。

data=set_missing(data)#用隨機森林填補比較多的缺失值
data=data.dropna()#刪除比較少的缺失值
data = data.drop_duplicates()#刪除重復(fù)項
data.to_csv('MissingData.csv',index=False)

3.2 異常值處理

缺失值處理完畢后李剖,我們還需要進行異常值處理芒率。異常值是指明顯偏離大多數(shù)抽樣數(shù)據(jù)的數(shù)值,比如個人客戶的年齡為0時篙顺,通常認為該值為異常值偶芍。找出樣本總體中的異常值充择,通常采用離群值檢測的方法。

首先匪蟀,我們發(fā)現(xiàn)變量age中存在0椎麦,顯然是異常值,直接剔除:

# 年齡等于0的異常值進行剔除
data = data[data['age'] > 0]

對于變量 NumberOfTime30-59DaysPastDueNotWorse材彪、NumberOfTimes90DaysLate 观挎、NumberOfTime60-89DaysPastDueNotWorse 這三個變量,由下面的箱線圖圖 3-2 可以看出查刻,均存在異常值键兜,且由 unique 函數(shù)可以得知均存在 96、98 兩個異常值穗泵,因此予以剔除普气。同時會發(fā)現(xiàn)剔除其中一個變量的 96、98 值佃延,其他變量的 96现诀、98 兩個值也會相應(yīng)被剔除。

圖3-2 箱形圖.png

剔除變量 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ù)切分

為了驗證模型的擬合效果荆残,我們需要對數(shù)據(jù)集進行切分奴艾,分成訓練集和測試集。

from sklearn.cross_validation import train_test_splitY = data['SeriousDlqin2yrs']
    X = data.ix[:, 1:]
    #測試集占比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)

4 探索性分析

在建立模型之前内斯,我們一般會對現(xiàn)有的數(shù)據(jù)進行 EDA(Exploratory Data Analysis,探索性數(shù)據(jù)分析) 蕴潦。EDA 是指對已有的數(shù)據(jù)(特別是調(diào)查或觀察得來的原始數(shù)據(jù))在盡量少的先驗假定下進行探索。常用的探索性數(shù)據(jù)分析方法有:直方圖俘闯、散點圖和箱線圖等潭苞。

客戶年齡分布如圖4-1所示,可以看到年齡變量大致呈正態(tài)分布备徐,符合統(tǒng)計分析的假設(shè)萄传。


圖4-1 客戶年齡分布.png

客戶年收入分布如圖4-2所示,月收入也大致呈正態(tài)分布蜜猾,符合統(tǒng)計分析的需要秀菱。


圖4-2.png

5 變量選擇

特征變量選擇(排序)對于數(shù)據(jù)分析、機器學習從業(yè)者來說非常重要蹭睡。好的特征選擇能夠提升模型的性能衍菱,更能幫助我們理解數(shù)據(jù)的特點、底層結(jié)構(gòu)肩豁,這對進一步改善模型脊串、算法都有著重要作用。至于Python的變量選擇代碼實現(xiàn)可以參考結(jié)合Scikit-learn介紹幾種常用的特征選擇方法:https://www.cnblogs.com/hhh5460/p/5186226.html清钥。

在本文中琼锋,我們采用信用評分模型的變量選擇方法,通過 WOE分析方法祟昭,即是通過比較指標分箱和對應(yīng)分箱的違約概率來確定指標是否符合經(jīng)濟意義缕坎。首先我們對變量進行離散化(分箱)處理。

5.1 分箱處理

變量分箱(binning)是對連續(xù)變量離散化(discretization)的一種稱呼篡悟。信用評分卡開發(fā)中一般有常用的等距分段谜叹、等深分段、最優(yōu)分段搬葬。

其中等距分段(Equval length intervals)是指分段的區(qū)間是一致的荷腊,比如年齡以十年作為一個分段;

等深分段(Equal frequency intervals)是先確定分段數(shù)量急凰,然后令每個分段中數(shù)據(jù)數(shù)量大致相等女仰;

最優(yōu)分段(Optimal Binning)又叫監(jiān)督離散化(supervised discretizaion),使用遞歸劃分(Recursive Partitioning)將連續(xù)變量分為分段抡锈,背后是一種基于條件推斷查找較佳分組的算法疾忍。

我們首先選擇對連續(xù)變量進行最優(yōu)分段,在連續(xù)變量的分布不滿足最優(yōu)分段的要求時企孩,再考慮對連續(xù)變量進行等距分段锭碳。最優(yōu)分箱的代碼如下:

# 定義自動分箱函數(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

針對我們將使用最優(yōu)分段對于數(shù)據(jù)集中的 RevolvingUtilizationOfUnsecuredLines 、age勿璃、 DebtRatio和MonthlyIncome 進行分類擒抛。

圖5-1 RevolvingUtilizationOfUnsecuredLines分箱情況.png
圖5-2 age分箱情況.png
圖5-3 DebtRatio分箱情況.png
圖5-4 MonthlyIncome分箱情況.png

針對不能最優(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分析补疑, 是對指標分箱歧沪、計算各個檔位的WOE值并觀察WOE值隨指標變化的趨勢。其中WOE的數(shù)學定義是:

woe=ln(goodattribute/badattribute)

在進行分析時莲组,我們需要對各指標從小到大排列诊胞,并計算出相應(yīng)分檔的 WOE 值。其中正向指標越大,WOE 值越心旃隆迈着;反向指標越大,WOE 值越大邪码。正向指標的 WOE 值負斜率越大裕菠,反響指標的正斜率越大,則說明指標區(qū)分能力好闭专。WOE 值趨近于直線奴潘,則意味指標判斷能力較弱。若正向指標和 WOE 正相關(guān)趨勢影钉、反向指標同 WOE 出現(xiàn)負相關(guān)趨勢画髓,則說明此指標不符合經(jīng)濟意義,則應(yīng)當予以去除平委。

WOE函數(shù)實現(xiàn)在上一節(jié)的mono_bin()函數(shù)里面已經(jīng)包含奈虾,這里不再重復(fù)。

5.3 相關(guān)性分析和IV篩選

接下來肆汹,我們會用經(jīng)過清洗后的數(shù)據(jù)看一下變量間的相關(guān)性愚墓。注意,這里的相關(guān)性分析只是初步的檢查昂勉,進一步檢查模型的 VI (證據(jù)權(quán)重)作為變量篩選的依據(jù)浪册。

相關(guān)性圖我們通過Python里面的seaborn包,調(diào)用heatmap()繪圖函數(shù)進行繪制岗照,實現(xiàn)代碼如下:

corr = data.corr()
#計算各變量的相關(guān)性系數(shù)
xticks = ['x0','x1','x2','x3','x4','x5','x6','x7','x8','x9','x10']#x軸標簽
yticks = list(corr.index)
#y軸標簽
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()
圖5-5 數(shù)據(jù)集各變量的相關(guān)性.png

由上圖可以看出村象,各變量之間的相關(guān)性是非常小的。NumberOfOpenCreditLinesAndLoans 和 NumberRealEstateLoansOrLines 的相關(guān)性系數(shù)為 0.43 攒至。

接下來厚者,進一步計算每個變量的 Infomation Value(IV) 。IV 指標是一般用來確定自變量的預(yù)測能力迫吐。其公式為:
IV=sum((goodattribute-badattribute)*ln(goodattribute/badattribute))
通過IV值判斷變量預(yù)測能力的標準是:
< 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的實現(xiàn)放在mono_bin()函數(shù)里面库菲,代碼實現(xiàn)如下:

# 定義自動分箱函數(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]
#各變量
IVindex=['x1','x2','x3','x4','x5','x6','x7','x8','x9','x10']
#x軸的標簽
fig1 = plt.figure(1)ax1 = fig1.add_subplot(1, 1, 1)x = np.arange(len(index))+1ax1.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ù)字標簽
for a, b in zip(x, ivlist):
    plt.text(a, b + 0.01, '%.4f' % b, ha='center', va='bottom', fontsize=10)plt.show()

輸出圖像:

圖5-6 輸出的各變量IV圖.png

可以看出, DebtRatio志膀、 MonthlyIncome熙宇、 NumberOfOpenCreditLinesAndLoans、 NumberRealEstateLoansOrLines 和 NumberOfDependents 變量的IV值明顯較低溉浙,所以予以刪除烫止。

6 模型分析

證據(jù)權(quán)重(Weight of Evidence,WOE)轉(zhuǎn)換可以將Logistic回歸模型轉(zhuǎn)變?yōu)闃藴试u分卡格式。引入WOE轉(zhuǎn)換的目的并不是為了提高模型質(zhì)量戳稽,只是一些變量不應(yīng)該被納入模型馆蠕,或者是因為它們不能增加模型值,再或者是因為與其模型相關(guān)系數(shù)有關(guān)的誤差較大,其實建立標準信用評分卡也可以不采用WOE轉(zhuǎn)換互躬。

這種情況下播赁,Logistic回歸模型需要處理更大數(shù)量的自變量。盡管這樣會增加建模程序的復(fù)雜性吨铸,但最終得到的評分卡都是一樣的行拢。

在建立模型之前祖秒,我們需要將篩選后的變量轉(zhuǎn)換為WOE值诞吱,便于信用評分。

6.1 WOE轉(zhuǎn)換

我們已經(jīng)能獲取了每個變量的分箱數(shù)據(jù)和 WOE 數(shù)據(jù)竭缝,只需要根據(jù)各變量數(shù)據(jù)進行替換房维,實現(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

我們將每個變量都進行替換,并將其保存到 WoeData.csv 文件中:

# 替換成
woedata['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 包來實現(xiàn)邏輯回歸:

導(dǎo)入數(shù)據(jù)data = pd.read_csv('WoeData.csv')
#應(yīng)變量
Y=data['SeriousDlqin2yrs']
#自變量,剔除對因變量影響不明顯的變量
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é)果:

圖6-1 邏輯回歸模型結(jié)果.png

通過圖 6-1 可知抬纸,邏輯回歸各變量都已通過顯著性檢驗咙俩,滿足要求。

6.3 模型檢驗

到這里湿故,我們的建模部分基本結(jié)束了阿趁。我們需要驗證一下模型的預(yù)測能力如何。我們使用在建模開始階段預(yù)留的 test 數(shù)據(jù)進行檢驗坛猪。通過 ROC 曲線和 AUC 來評估模型的擬合能力脖阵。

在 Python 中,可以利用 sklearn.metrics墅茉,它能方便比較兩個分類器命黔,自動計算 ROC 和 AUC 。

實現(xiàn)代碼:

#應(yīng)變量
Y_test = test['SeriousDlqin2yrs']
#自變量就斤,剔除對因變量影響不明顯的變量悍募,與模型變量對應(yīng)
X_test = test.drop(['SeriousDlqin2yrs', 'DebtRatio', 'MonthlyIncome', 'NumberOfOpenCreditLinesAndLoans','NumberRealEstateLoansOrLines', 'NumberOfDependents'], axis=1)
X3 = sm.add_constant(X_test)
resu = result.predict(X3)
#進行預(yù)測
fpr, tpr, threshold = roc_curve(Y_test, resu)
rocauc = auc(fpr, tpr)
#計算
AUCplt.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é)果:

圖6-2 ROC曲線.png

從上圖可知,AUC 值為 0.85洋机,說明該模型的預(yù)測效果還是不錯的坠宴,正確率較高。

7 信用評分

我們已經(jīng)基本完成了建模相關(guān)的工作绷旗,并用ROC曲線驗證了模型的預(yù)測能力喜鼓。接下來的步驟,就是將Logistic模型轉(zhuǎn)換為標準評分卡的形式刁标。

7.1 評分標準

image.png

依據(jù)以上論文資料得到:
a=log(p_good/P_bad)
Score = offset + factor * log(odds)
在建立標準評分卡之前颠通,我們需要選取幾個評分卡參數(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)

個人總評分=基礎(chǔ)分+各部分得分

7.2 部分評分

下面計算各變量部分的分數(shù)匙隔。各部分得分函數(shù):

#計算分數(shù)函數(shù) def get_score(coe,woe,factor):
    scores=[]
    for w in woe:
        score=round(coe*w*factor,0)
        scores.append(score)
    return scores

計算各變量得分情況:

# 各項部分分數(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)

我們可以得到各部分的評分卡如圖 7-1 所示:


圖7-1 各變量的評分標準.png

8 自動評分系統(tǒng)

根據(jù)變量來計算分數(shù),實現(xiàn)如下:

#根據(jù)變量計算分數(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

我們來計算test里面的分數(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)

批量計算的部分分結(jié)果:


圖8-1 批量計算的部分結(jié)果.png

9 總結(jié)以及展望

本文通過對 kaggle 上的 Give Me Some Credit 數(shù)據(jù)的挖掘分析熏版,結(jié)合信用評分卡的建立原理纷责,從數(shù)據(jù)的預(yù)處理、變量選擇撼短、建模分析到創(chuàng)建信用評分再膳,創(chuàng)建了一個簡單的信用評分系統(tǒng)。

基于 AI 的機器學習評分卡系統(tǒng)可通過把舊數(shù)據(jù)(某個時間點后曲横,例如2年)剔除掉后再進行自動建模喂柒、模型評估、并不斷優(yōu)化特征變量禾嫉,可以使系統(tǒng)更加強大灾杰。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市熙参,隨后出現(xiàn)的幾起案子艳吠,更是在濱河造成了極大的恐慌,老刑警劉巖尊惰,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件讲竿,死亡現(xiàn)場離奇詭異,居然都是意外死亡弄屡,警方通過查閱死者的電腦和手機题禀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來膀捷,“玉大人迈嘹,你說我怎么就攤上這事∪梗” “怎么了秀仲?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長壶笼。 經(jīng)常有香客問我神僵,道長,這世上最難降的妖魔是什么覆劈? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任保礼,我火速辦了婚禮沛励,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘炮障。我一直安慰自己目派,他們只是感情好,可當我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布胁赢。 她就那樣靜靜地躺著企蹭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪智末。 梳的紋絲不亂的頭發(fā)上谅摄,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天,我揣著相機與錄音吹害,去河邊找鬼螟凭。 笑死,一個胖子當著我的面吹牛它呀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播棒厘,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼纵穿,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了奢人?” 一聲冷哼從身側(cè)響起谓媒,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎何乎,沒想到半個月后句惯,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡支救,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年抢野,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片各墨。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡指孤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出贬堵,到底是詐尸還是另有隱情恃轩,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布黎做,位于F島的核電站叉跛,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蒸殿。R本人自食惡果不足惜筷厘,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一挽铁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧敞掘,春花似錦叽掘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至赫冬,卻和暖如春浓镜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背劲厌。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工膛薛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人补鼻。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓哄啄,卻偏偏與公主長得像,于是被迫代替她去往敵國和親风范。 傳聞我的和親對象是個殘疾皇子咨跌,可洞房花燭夜當晚...
    茶點故事閱讀 42,925評論 2 344