<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          干貨 | 基于 Python 的信用評(píng)分模型實(shí)戰(zhàn)!

          共 4265字,需瀏覽 9分鐘

           ·

          2020-09-10 01:49

          源 | 知乎??作者 |?Carl
          文章鏈接 |?https://zhuanlan.zhihu.com/p/35284849

          信用評(píng)分模型可用“四張卡”來表示,分別是 A卡(Application score card,申請(qǐng)?jiān)u分卡)、B卡(Behavior score card,行為評(píng)分卡)、C卡(Collection score card,催收評(píng)分卡)和 F卡(Anti-Fraud Card,反欺詐評(píng)分卡),分別應(yīng)用于貸前、貸中、貸后。

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

          ???
          項(xiàng)目流程?

          典型的信用評(píng)分模型如圖1-1所示。信用風(fēng)險(xiǎn)評(píng)級(jí)模型的主要開發(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ù)分析,該步驟主要是獲取樣本總體的大概情況,描述樣本總體情況的指標(biāo)主要有直方圖、箱形圖等。

          4.變量選擇,該步驟主要是通過統(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)。

          圖1-1 信用評(píng)分模型開發(fā)流程


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

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

          數(shù)據(jù)屬于個(gè)人消費(fèi)類貸款,只考慮信用評(píng)分最終實(shí)施時(shí)能夠使用到的數(shù)據(jù)應(yīng)從如下一些方面獲取數(shù)據(jù):

          – 基本屬性:包括了借款人當(dāng)時(shí)的年齡。
          – 償債能力:包括了借款人的月收入、負(fù)債比率。
          – 信用往來:兩年內(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ù)量。
          – 貸款屬性:暫無。
          – 其他因素:包括了借款人的家屬數(shù)量(不包括本人在內(nèi))。
          – 時(shí)間窗口:自變量的觀察窗口為過去兩年,因變量表現(xiàn)窗口為未來兩年。

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


          ?????
          ?數(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ì)情況:
          圖3-1 變量詳細(xì)情況


          從上圖可知,變量 MonthlyIncome 和 NumberOfDependents 存在缺失,變量 MonthlyIncome 共有缺失值 29731 個(gè),NumberOfDependents 有 3924 個(gè)缺失值。

          3.1缺失值處理


          這種情況在現(xiàn)實(shí)問題中非常普遍,這會(huì)導(dǎo)致一些不能處理缺失值的分析方法無法應(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ù)值型特征取出來
          ????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)被剔除。

          圖3-2 箱形圖


          剔除變量 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_splitY?=?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)行 EDA(Exploratory Data Analysis,探索性數(shù)據(jù)分析) 。EDA 是指對(duì)已有的數(shù)據(jù)(特別是調(diào)查或觀察得來的原始數(shù)據(jù))在盡量少的先驗(yàn)假定下進(jìn)行探索。常用的探索性數(shù)據(jù)分析方法有:直方圖、散點(diǎn)圖和箱線圖等。

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

          圖4-1 客戶年齡分布


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

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


          ??
          變量選擇?

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

          在本文中,我們采用信用評(píng)分模型的變量選擇方法,通過?WOE分析方法,即是通過比較指標(biāo)分箱和對(duì)應(yīng)分箱的違約概率來確定指標(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)行分類。

          圖5-1 RevolvingUtilizationOfUnsecuredLines分箱情況

          圖5-2 age分箱情況

          圖5-3 DebtRatio分箱情況

          圖5-4 MonthlyIncome分箱情況

          針對(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.2WOE


          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)的正斜率越大,則說明指標(biāo)區(qū)分能力好。WOE 值趨近于直線,則意味指標(biāo)判斷能力較弱。若正向指標(biāo)和 WOE 正相關(guān)趨勢(shì)、反向指標(biāo)同 WOE 出現(xiàn)負(fù)相關(guān)趨勢(shì),則說明此指標(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篩選


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

          相關(guān)性圖我們通過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()

          圖5-5 數(shù)據(jù)集各變量的相關(guān)性


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

          接下來,進(jìn)一步計(jì)算每個(gè)變量的 Infomation Value(IV) 。IV 指標(biāo)是一般用來確定自變量的預(yù)測(cè)能力。其公式為:

          IV=sum((goodattribute-badattribute)*ln(goodattribute/badattribute))

          通過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]
          #各變量
          IVindex=['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))+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ù)字標(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()

          輸出圖像:
          圖5-6 輸出的各變量IV圖

          可以看出, 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.1WOE轉(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????????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 文件中:
          #?替換成
          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.2Logisic模型建立


          我們直接調(diào)用 statsmodels 包來實(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é)果:

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


          通過圖 6-1 可知,邏輯回歸各變量都已通過顯著性檢驗(yàn),滿足要求。

          6.3模型檢驗(yàn)


          到這里,我們的建模部分基本結(jié)束了。我們需要驗(yàn)證一下模型的預(yù)測(cè)能力如何。我們使用在建模開始階段預(yù)留的 test 數(shù)據(jù)進(jìn)行檢驗(yàn)。通過 ROC 曲線和 AUC 來評(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ì)算
          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曲線

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

          ????
          ?信用評(píng)分?

          我們已經(jīng)基本完成了建模相關(guān)的工作,并用ROC曲線驗(yàn)證了模型的預(yù)測(cè)能力。接下來的步驟,就是將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 所示:

          圖7-1 各變量的評(píng)分標(biāo)準(zhǔn)


          ?????
          ?自動(dòng)評(píng)分系統(tǒng)?

          根據(jù)變量來計(jì)算分?jǐn)?shù),實(shí)現(xiàn)如下:
          #根據(jù)變量計(jì)算分?jǐn)?shù)
          def?compute_score(series,cut,score):
          ????list?=?[]
          ????i?=?0
          ????while?i?????????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

          我們來計(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é)果:

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


          ??????
          總結(jié)以及展望?

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

          基于 AI 的機(jī)器學(xué)習(xí)評(píng)分卡系統(tǒng)可通過把舊數(shù)據(jù)(某個(gè)時(shí)間點(diǎn)后,例如2年)剔除掉后再進(jìn)行自動(dòng)建模、模型評(píng)估、并不斷優(yōu)化特征變量,可以使系統(tǒng)更加強(qiáng)大。
          推 薦關(guān) 注

          瀏覽 93
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  大香蕉视频网站 | 一本道无码在线观看 | 人人摸人人操人人操看 | 偷拍自拍第一页 | 香蕉久久国产AV一区二区 |