kaggle風(fēng)控(二)——lending club

本案例數(shù)據(jù)取自kaggle競(jìng)賽lending club(美國(guó)最大的P2P公司)。
導(dǎo)入包

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# 解決坐標(biāo)軸刻度負(fù)號(hào)亂碼
plt.rcParams['axes.unicode_minus'] = False
# 解決中文亂碼問(wèn)題
plt.rcParams['font.sans-serif'] = ['Simhei']

import warnings
warnings.filterwarnings("ignore")

#顯示全部特征
pd.set_option('display.max_columns', None)

讀入數(shù)據(jù)

data=pd.read_csv('data_all_values.csv')
data.head()

查看數(shù)據(jù)維度

data.shape

數(shù)據(jù)維度是(103434, 19)。
查看數(shù)據(jù)類(lèi)型

data.info()

可以看到,只有“貸款目的”是字符型變量。
查看標(biāo)簽分布

data['target'].value_counts()

y的分布大致為10:1的比例,存在數(shù)據(jù)不平衡的情況。

1、LightGBM重要性選擇變量

我們采用LightGBM對(duì)特征進(jìn)行篩選(本案例總共只有18個(gè)特征,其實(shí)可以不需要做特征篩選;如果實(shí)際工程中有成百上千的特征,可以按照這個(gè)步驟篩選出重要特征)。
查看每個(gè)變量的取值個(gè)數(shù)用以判斷是否為分類(lèi)變量。

data_copy=data.copy()

allFeatures = list(data.columns)   
allFeatures.remove('target')
for i in allFeatures:
    print('變量 [{}] 的不同水平值有 {} 個(gè)'.format(i,len(data[i].unique())))   

可以看出,取值個(gè)數(shù)少的變量為分類(lèi)變量,將連續(xù)變量和分類(lèi)變量分別拆開(kāi)。

# 分類(lèi)變量
categorical_var=['貸款期限', '貸款等級(jí)', '工作年限', '房屋所有權(quán)', '收入是否由LC驗(yàn)證', '貸款目的', 
'過(guò)去6個(gè)月內(nèi)被查詢次數(shù)', '留置稅數(shù)量']

# 連續(xù)變量
continuous_var=['貸款金額', '利率', '每月還款金額', '年收入', '月負(fù)債比', '過(guò)去兩年借款人逾期30天以上的數(shù)字', 
'摧毀公共記錄的數(shù)量', '額度循環(huán)使用率', '總貸款筆數(shù)', '拖欠的逾期款項(xiàng)']

查看分類(lèi)變量的取值范圍。

# 查看分類(lèi)變量數(shù)據(jù)
for var in categorical_var:
    print('變量 {} 的取值為:{}'.format(var,set(data[var])))

將連續(xù)變量標(biāo)準(zhǔn)化

from sklearn.preprocessing import StandardScaler

sc = StandardScaler()                                 
data[continuous_var] = sc.fit_transform(data[continuous_var])  

將數(shù)值型的分類(lèi)變量轉(zhuǎn)為整型

# 字符分類(lèi)變量
string_var=list(data.select_dtypes(include=["object"]).columns) 
# 從分類(lèi)變量中減去字符分類(lèi)變量就是數(shù)值分類(lèi)變量
col=list(set(categorical_var)-set(string_var))
data[col]=data[col].astype(int)

字符分類(lèi)變量按照壞樣本率進(jìn)行編碼(之前我們已經(jīng)看過(guò)了,字符型的變量只有“貸款目的”)

def Encoder(df, col, target):           
    encoder = {}
    for v in set(df[col]):
        if v == v:
            subDf = df[df[col] == v]
        else:
            xList = list(df[col])
            nanInd = [i for i in range(len(xList)) if xList[i] != xList[i]]
            subDf = df.loc[nanInd]
        encoder[v] = sum(subDf[target])*1.0/subDf.shape[0]
    newCol = [encoder[i] for i in df[col]]
    return newCol

string_var=list(data.select_dtypes(include=["object"]).columns) 
col=list(set(categorical_var)&set(string_var))

for i in col:
    data[i] = Encoder(data, i, 'target')
data['貸款目的'].value_counts()

此時(shí)再查看一下我們的數(shù)據(jù)集data。



LighGBM模型有個(gè)非常好的功能,就是能指定分類(lèi)變量,省去了one-hot編碼的步驟。

# 保存變量和文件
import pickle
f =open('lgb_col.pkl','wb')
pickle.dump(col,f)
f.close() 

# 建模
allFeatures = list(data.columns)   
allFeatures.remove('target')
X = data[allFeatures]
y = data['target']
from sklearn.model_selection import train_test_split as sp
X_train, X_test, y_train, y_test = sp(X, y, test_size=0.3, random_state=1)

# 加載分類(lèi)變量
f =open('lgb_col.pkl','rb')
col = pickle.load(f)
f.close()

# lightgbm建模
import lightgbm as LGB
params = {
'objective': 'binary', 
"boosting" : "gbdt",
'num_leaves': 4,    
'min_data_in_leaf': 20,
"subsample": 0.9,
"colsample_bytree": 0.8,
'learning_rate':0.09,
'tree_learner': 'voting',
'metric': 'auc'
        }
dtrain = LGB.Dataset(X_train, y_train, categorical_feature=col)
dtest = LGB.Dataset(X_test, y_test, reference=dtrain, categorical_feature=col)
lgb = LGB.train(params, dtrain, valid_sets=[dtrain, dtest], 
                num_boost_round=3000, early_stopping_rounds=100, verbose_eval=10)

訓(xùn)練好LightGMB模型后,計(jì)算變量重要性。

# lightgbm重要性選擇變量
importace = list(lgb.feature_importance())
allFeatures=list(lgb.feature_name())
featureImportance = zip(allFeatures,importace)
featureImportanceSorted = sorted(featureImportance, key=lambda k: k[1],reverse=True)

plt.figure(figsize = (5, 10))                                                                                   
sns.barplot(x=[k[1] for k in featureImportanceSorted],y=[k[0] for k in featureImportanceSorted])
plt.xticks(rotation='vertical') 
plt.show()

我們從18個(gè)特征中選取重要性排名前13的變量。

feature_selection_lgb = [k[0] for k in featureImportanceSorted[:13]] 

2、分箱

分箱方法有手動(dòng)、等頻、等寬、卡方和決策樹(shù)分箱5種。本案例選擇手動(dòng)分箱的方法。
為避免在原數(shù)據(jù)集上修改,我們將數(shù)據(jù)集復(fù)制一份。

data=data_copy.copy()
data=data[feature_selection_lgb+['target']]
data_copy=data.copy()

2.1 分類(lèi)變量的分箱

分類(lèi)變量不用做離散化,可以先拿來(lái)分箱。

# 定義計(jì)算WOE的函數(shù)
def Ln_odds(df, col, target):
    # 每個(gè)箱子總?cè)藬?shù)
    total = df.groupby([col])[target].count()
    total = pd.DataFrame({'total': total})
    # 每個(gè)箱子壞樣本個(gè)數(shù)
    bad = df.groupby([col])[target].sum()   
    bad = pd.DataFrame({'bad': bad})
    # 合并
    regroup = total.merge(bad, left_index=True, right_index=True, how='left')
    regroup.reset_index(level=0, inplace=True)
    # 計(jì)算總?cè)藬?shù)和總壞客戶數(shù)
    N = sum(regroup['total'])  
    B = sum(regroup['bad'])
    # 每個(gè)箱子好樣本個(gè)數(shù)
    regroup['good'] = regroup['total'] - regroup['bad']
    # 好樣本總?cè)藬?shù)
    G = N - B
    # 計(jì)算每個(gè)箱子的WOE值
    regroup['bad_pcnt'] = regroup['bad'].map(lambda x: x*1.0/B)
    regroup['good_pcnt'] = regroup['good'].map(lambda x: x * 1.0 / G)
    regroup[col+'_WOE'] = regroup.apply(lambda x: np.log(x.good_pcnt*1.0/x.bad_pcnt),axis = 1)
    # 合并,得到總的WOE表
    df=pd.merge(df, regroup[[col,col+'_WOE']], on=col, how='left')
    return df

# 對(duì)分類(lèi)變量進(jìn)行分箱
categorical_var=list(set(categorical_var)&set(feature_selection_lgb))
categorical_var=['貸款期限', '房屋所有權(quán)', '貸款等級(jí)', '過(guò)去6個(gè)月內(nèi)被查詢次數(shù)','工作年限']
for i in categorical_var:   
    data=Ln_odds(data, i, 'target')
    sns.pointplot(x=i, y=i+'_WOE', data=data)      
    plt.xticks(rotation=0)     
    plt.show()





一般分箱會(huì)遵循以下3個(gè)原則:
①分箱個(gè)數(shù)不宜過(guò)多,一般不超過(guò)5個(gè)
②每個(gè)箱子中的樣本比例不宜過(guò)少,一般不少于整體個(gè)數(shù)的5%
③分箱曲線盡量呈現(xiàn)單調(diào)性
我們可以看到,只有“貸款等級(jí)”和“過(guò)去6個(gè)月內(nèi)被查詢次數(shù)”是單調(diào)的,我們需要對(duì)每個(gè)特征進(jìn)行逐一地調(diào)整分箱。

2.1.1 貸款等級(jí)

data=data_copy.copy()

data['貸款等級(jí)'].value_counts()

可以看到,貸款等級(jí)最后3個(gè)箱子樣本個(gè)數(shù)過(guò)少。

i='貸款等級(jí)'
data[i]=data[i].apply(lambda x: 2 if 2<=x<5 else x)
data[i]=data[i].apply(lambda x: 3 if x>=5 else x)

data=Ln_odds(data, i, 'target')
sns.pointplot(x=i, y=i+'_WOE', data=data)     
plt.xticks(rotation=0)     
plt.show()

下面左圖為調(diào)整分箱前,右圖為調(diào)整分箱后的WOE曲線(后同)。


2.1.2 過(guò)去6個(gè)月內(nèi)被查詢次數(shù)

i='過(guò)去6個(gè)月內(nèi)被查詢次數(shù)'
data[i].value_counts()

直接將分類(lèi)3之后的箱子合并

data[i]=data[i].apply(lambda x: 4 if x>3 else x)

data=Ln_odds(data, i, 'target')
sns.pointplot(x=i, y=i+'_WOE', data=data)  
plt.xticks(rotation=0)     
plt.show()

2.1.3 工作年限

i='工作年限'
data[i].value_counts()

將分類(lèi)1-4合并為一箱,5-10合并為一箱。

data[i]=data[i].apply(lambda x: 1 if 1<=x<5 else x)
data[i]=data[i].apply(lambda x: 2 if x>=5 else x)

data=Ln_odds(data, i, 'target')
sns.pointplot(x=i, y=i+'_WOE', data=data)     
plt.xticks(rotation=0)     
plt.show()

可以看一下此時(shí)的數(shù)據(jù)集:


'''保存文件''' 
col=[]
for i in list(data.columns):
    if i.find('_WOE')<0:
        col.append(i)    
data=data[col]
data.to_csv('categorical_bins.csv', index=False, encoding='utf-8')

2.2 連續(xù)變量的分箱

先看一下連續(xù)型變量的描述性統(tǒng)計(jì)。

data=pd.read_csv('categorical_bins.csv')
data.head()

continuous_var=list(set(continuous_var)&set(feature_selection_lgb))
continuous_var=['總貸款筆數(shù)', '每月還款金額', '過(guò)去兩年借款人逾期30天以上的數(shù)字', 
                '貸款金額', '年收入', '利率', '月負(fù)債比', '額度循環(huán)使用率']

describe=data[continuous_var].describe().T[['max','min']]
describe

2.2.1 總貸款筆數(shù)

i='總貸款筆數(shù)'
sns.distplot(data[i][data['target'] == 0].dropna(),color='blue') 
sns.distplot(data[i][data['target'] == 1].dropna(),color='red')
plt.show() 

選取20和30兩個(gè)分割點(diǎn)

bins=[-1, 20, 30, 200]   #左開(kāi)右閉,如果可能出現(xiàn)0,那么需要以-1開(kāi)始
cats=pd.cut(list(data[i]), bins, precision=0)        #指定分組區(qū)間
cats.value_counts()  
data[i+'組別']=pd.Series(cats)
data=Ln_odds(data, i+'組別', 'target')
sns.pointplot(x=i+'組別', y=i+'組別_WOE', data=data.sort_values(i+'組別_WOE',ascending=False))      
plt.show()  

2.2.2 每月還款金額

i='每月還款金額'
sns.distplot(data[i][data['target'] == 0].dropna(),color='blue') 
sns.distplot(data[i][data['target'] == 1].dropna(),color='red')
plt.show() 

選擇300和750兩個(gè)分割點(diǎn)

bins=[-1, 300, 750, 2000]
cats=pd.cut(list(data[i]), bins, precision=0)        #指定分組區(qū)間
cats.value_counts()  
data[i+'組別']=pd.Series(cats)
data=Ln_odds(data, i+'組別', 'target')
sns.pointplot(x=i+'組別', y=i+'組別_WOE', data=data.sort_values(i+'組別_WOE',ascending=False))  
plt.show()  

2.2.3 過(guò)去兩年借款人逾期30天以上的數(shù)字

i='過(guò)去兩年借款人逾期30天以上的數(shù)字'
sns.distplot(data[i][data['target'] == 0].dropna(),color='blue') 
sns.distplot(data[i][data['target'] == 1].dropna(),color='red')
plt.show() 

分布呈現(xiàn)嚴(yán)重的長(zhǎng)尾,選擇1作為分割點(diǎn)將特征分為兩箱。

bins=[-1, 1, 50]
cats=pd.cut(list(data[i]), bins, precision=0)        #指定分組區(qū)間
cats.value_counts()  
data[i+'組別']=pd.Series(cats)
data=Ln_odds(data, i+'組別', 'target')
sns.pointplot(x=i+'組別', y=i+'組別_WOE', data=data.sort_values(i+'組別_WOE',ascending=False))  
plt.show()  

2.2.4 貸款金額

i='貸款金額'
sns.distplot(data[i][data['target'] == 0].dropna(),color='blue') 
sns.distplot(data[i][data['target'] == 1].dropna(),color='red')
plt.show() 

選擇10000和20000作為分割點(diǎn)

bins=[-1, 10000, 20000, 50000]
cats=pd.cut(list(data[i]), bins, precision=0)        #指定分組區(qū)間
cats.value_counts()  
data[i+'組別']=pd.Series(cats)
data=Ln_odds(data, i+'組別', 'target')
sns.pointplot(x=i+'組別', y=i+'組別_WOE', data=data.sort_values(i+'組別_WOE',ascending=False))  
plt.show() 

2.2.5 年收入

i='年收入'
sns.distplot(data[i][data['target'] == 0].dropna(),color='blue') 
sns.distplot(data[i][data['target'] == 1].dropna(),color='red')
plt.xlim([0,1000000])
plt.show() 

選擇150000和300000作為分割點(diǎn)

bins=[-1, 150000, 300000, 10000000]
cats=pd.cut(list(data[i]), bins, precision=0)        #指定分組區(qū)間
cats.value_counts()  
data[i+'組別']=pd.Series(cats)
data=Ln_odds(data, i+'組別', 'target')
sns.pointplot(x=i+'組別', y=i+'組別_WOE', data=data.sort_values(i+'組別_WOE',ascending=False))  
plt.show() 

2.2.6 利率

i='利率'
sns.distplot(data[i][data['target'] == 0].dropna(),color='blue') 
sns.distplot(data[i][data['target'] == 1].dropna(),color='red')
plt.show() 

選擇8和13作為分割點(diǎn)

bins=[0, 8, 13, 50]
cats=pd.cut(list(data[i]), bins, precision=0)        #指定分組區(qū)間
cats.value_counts()  
data[i+'組別']=pd.Series(cats)
data=Ln_odds(data, i+'組別', 'target')
sns.pointplot(x=i+'組別', y=i+'組別_WOE', data=data.sort_values(i+'組別_WOE',ascending=False))  
plt.show()  

2.2.7 月負(fù)債比

i='月負(fù)債比'
sns.distplot(data[i][data['target'] == 0].dropna(),color='blue') 
sns.distplot(data[i][data['target'] == 1].dropna(),color='red')
plt.xlim([0,200])
plt.show() 

選擇20作為分割點(diǎn)

bins=[-1, 20, 1000]
cats=pd.cut(list(data[i]), bins, precision=0)        #指定分組區(qū)間
cats.value_counts()  
data[i+'組別']=pd.Series(cats)
data=Ln_odds(data, i+'組別', 'target')
sns.pointplot(x=i+'組別', y=i+'組別_WOE', data=data.sort_values(i+'組別_WOE',ascending=False))  
plt.show() 

2.2.8 額度循環(huán)使用率

i='額度循環(huán)使用率'
sns.distplot(data[i][data['target'] == 0].dropna(),color='blue') 
sns.distplot(data[i][data['target'] == 1].dropna(),color='red')
plt.show() 

選擇50作為分割點(diǎn)

bins=[-1, 50, 200]
cats=pd.cut(list(data[i]), bins, precision=0)        #指定分組區(qū)間
cats.value_counts()  
data[i+'組別']=pd.Series(cats)
data=Ln_odds(data, i+'組別', 'target')
sns.pointplot(x=i+'組別', y=i+'組別_WOE', data=data.sort_values(i+'組別_WOE',ascending=False))  
plt.show() 
'''保存文件''' 
col=[]
for i in list(data.columns):
    if i.find('_WOE')<0:
        col.append(i)    
data=data[col]
data.to_csv('cut_bins.csv', index=False, encoding='utf-8')

查看一下此時(shí)的數(shù)據(jù)集data,可以看到,連續(xù)變量已經(jīng)分箱了。


2.3 計(jì)算WOE和IV值

# 定義函數(shù)計(jì)算WOE和IV
def CalcWOE(df, col, target):
    # 每個(gè)箱子總?cè)藬?shù)
    total = df.groupby([col])[target].count()
    total = pd.DataFrame({'total': total})
    # 每個(gè)箱子壞樣本數(shù)
    bad = df.groupby([col])[target].sum()   
    bad = pd.DataFrame({'bad': bad})
    # 合并
    regroup = total.merge(bad, left_index=True, right_index=True, how='left')
    regroup.reset_index(level=0, inplace=True)
    # 計(jì)算總?cè)藬?shù)和總壞樣本數(shù)
    N = sum(regroup['total']) 
    B = sum(regroup['bad']) 
    # 計(jì)算好客戶個(gè)數(shù)
    regroup['good'] = regroup['total'] - regroup['bad']
    G = N - B
    # 計(jì)算好客戶比例和壞客戶比例,并算出WOE
    regroup['bad_pcnt'] = regroup['bad'].map(lambda x: x*1.0/B)
    regroup['good_pcnt'] = regroup['good'].map(lambda x: x * 1.0 / G)
    regroup['WOE'] = regroup.apply(lambda x: np.log(x.good_pcnt*1.0/x.bad_pcnt),axis = 1)
    WOE_dict = regroup[[col,'WOE']].set_index(col).to_dict(orient='index')
    for k, v in WOE_dict.items():
        WOE_dict[k] = v['WOE']
    # 計(jì)算每個(gè)變量的IV值
    IV = regroup.apply(lambda x: (x.good_pcnt-x.bad_pcnt)*np.log(x.good_pcnt*1.0/x.bad_pcnt),axis = 1)
    IV = sum(IV)
    return {"WOE": WOE_dict, 'IV':IV}

# 取出經(jīng)過(guò)分箱的連續(xù)變量和分類(lèi)變量
all_var=[]
for i in list(data.columns):
    if i.find('組別')>0:
        all_var.append(i)      
all_var=all_var+categorical_var

# 得到每個(gè)特征變量的WOE和IV值
WOE_dict = {}
IV_dict = {}
for var in all_var:
    woe_iv = CalcWOE(data, var, 'target')
    WOE_dict[var] = woe_iv['WOE']
    IV_dict[var] = woe_iv['IV']

# 查看每個(gè)特征變量的IV值
pd.Series(IV_dict).sort_values(ascending=False)

3、LR建模

3.1 IV特征篩選

IV值同樣可以對(duì)特征重要性進(jìn)行篩選:
IV<0.02 無(wú)作用
0.02-0.1 弱作用
0.1-0.3 中等
0.3-0.5 強(qiáng)作用
IV>0.5 過(guò)強(qiáng),需要檢查是否有問(wèn)題

'''選取IV>=0.02的變量'''
IV_dict_sorted = sorted(IV_dict.items(), key=lambda x: x[1], reverse=True)
IV_values = [i[1] for i in IV_dict_sorted]
IV_name = [i[0] for i in IV_dict_sorted]

high_IV = {k:v for k, v in IV_dict.items() if v >= 0.02}
high_IV_sorted = sorted(high_IV.items(),key=lambda x:x[1],reverse=True)
print ('總共',len(high_IV_sorted),'個(gè)變量IV >= 0.02')  

總共 6 個(gè)變量IV >= 0.02

3.2 WOE映射

將IV值篩選出來(lái)的6個(gè)特征做WOE映射,將各自的每個(gè)箱子替換成對(duì)應(yīng)的WOE值。

# short_list記錄6個(gè)特征名,short_list_2記錄6個(gè)新的WOE特征名
short_list = high_IV.keys()
short_list_2 = []
for var in short_list:
    newVar = var + '_WOE'
    data[newVar] = data[var].map(lambda x:WOE_dict[var][x])
    short_list_2.append(newVar)

dataWOE = data[short_list_2]
dataWOE.head()

3.3 共線性檢驗(yàn)

做LR建模需要檢驗(yàn)變量之間的共線性。

# 生成相關(guān)性矩陣
corr = round(dataWOE.corr(),2)

mask = np.zeros_like(corr, dtype=np.bool)
mask[np.triu_indices_from(mask)] = True             
plt.figure(figsize = (5, 5))
cmap = sns.diverging_palette(220, 10, as_cmap=True) 
sns.heatmap(corr, mask=mask, cmap=cmap, center=0, annot =True, cbar_kws={"shrink": .5})
plt.show()

計(jì)算相關(guān)系數(shù)之后,還需要考慮多重共線性問(wèn)題,即計(jì)算VIF值。VIF值越大,代表共線性越嚴(yán)重。VIF值:
0<VIF<10,不存在多重共線性
10<=VIF<100,存在較強(qiáng)的多重共線性
VIF>=100,存在嚴(yán)重的多重共線性

# 選擇方差共線性<10的變量
from statsmodels.stats.outliers_influence import variance_inflation_factor as vif

col = np.array(data[short_list_2],dtype='float')

for i in range(len(short_list_2)):                                              
    print ('{} VIF是{}'.format(short_list_2[i], vif(col, i))) 

可以看到,6個(gè)特征之間不存在多重共線性。

3.4 邏輯回歸

在確定變量之間不存在多重共線性之后,就要對(duì)變量進(jìn)行顯著性分析,刪除p值不顯著的變量。

# 構(gòu)建X和y
X = data[short_list_2]
for col in short_list_2:
    X[col]=X[col].astype('float')
X['intercept'] = [1]*X.shape[0]
y = data['target']

# 建模
import statsmodels.api as sm
lr_sm=sm.Logit(y, X).fit()
glmodel = sm.GLM(y,X,family=sm.families.Binomial()).fit()
glmodel.summary()

可以看到,6個(gè)變量都是顯著的。
用機(jī)器學(xué)習(xí)中的LR建模。

from sklearn.model_selection import train_test_split as sp
X_train, X_test, y_train, y_test = sp(X, y, test_size=0.3, random_state=1)

from sklearn.linear_model import LogisticRegression as LR  
lr=LR(random_state=1)
lr.fit(X_train, y_train)
from sklearn import metrics
y_test_label = lr.predict(X_test)
y_test_value = lr.predict_proba(X_test)[:, 1] 
print("測(cè)試集準(zhǔn)確率是: {:.2%}".format(metrics.accuracy_score(y_test, y_test_label)))  
print("測(cè)試集AUC是: {:.4}".format(metrics.roc_auc_score(y_test, y_test_value)))  

4、創(chuàng)建評(píng)分卡

在確定模型的準(zhǔn)確度和AUC值的可接受范圍后,可以對(duì)每個(gè)入模變量進(jìn)行單變量得分計(jì)算,從而求出變量不同取值下的得分。
計(jì)算評(píng)分卡的公式:



其中A叫做“補(bǔ)償”,B叫做“刻度”,log(odds)代表了一個(gè)人違約的可能性。A、B兩個(gè)常數(shù)可以通過(guò)兩個(gè)假設(shè)的分值帶入公式求出。這兩個(gè)假設(shè)分別是:
①某個(gè)特定的違約概率下的預(yù)期分值
②指定的違約概率翻倍的分?jǐn)?shù)(PDO)

b=lr.intercept_       #截距

coe=lr.coef_          #系數(shù)
a0 = coe[0][0]        #每月還款金額組別 系數(shù)          
a1 = coe[0][1]        #貸款金額組別 系數(shù) 
a2 = coe[0][2]        #利率組別 系數(shù) 
a3 = coe[0][3]        #月負(fù)債比組別 系數(shù) 
a4 = coe[0][4]        #貸款等級(jí) 系數(shù) 
a5 = coe[0][5]        #過(guò)去6個(gè)月內(nèi)被查詢次數(shù) 系數(shù) 

A = 500
PDO = 20              #每增加20分,odds(好壞比)增加1倍
B=PDO/np.log(2)

接下來(lái)對(duì)6個(gè)變量做單變量得分。

4.1 每月還款金額

WOE_dict['每月還款金額組別']  #獲取字典key,即變量水平值

woe1 = WOE_dict['每月還款金額組別']['(-1, 300]']
score1 = -(B * a0* woe1) + (A-B*b)/dataWOE.shape[0]

woe2 = WOE_dict['每月還款金額組別']['(300, 750]']
score2 = -(B * a0 * woe2) + (A-B*b)/dataWOE.shape[0]

woe3 = WOE_dict['每月還款金額組別']['(750, 2000]']
score3 = -(B * a0 * woe3) + (A-B*b)/dataWOE.shape[0]

4.2 貸款金額

WOE_dict['貸款金額組別']

woe1 = WOE_dict['貸款金額組別']['(-1, 10000]']
score1 = -(B * a1* woe1) + (A-B*b)/dataWOE.shape[0]

woe2 = WOE_dict['貸款金額組別']['(10000, 20000]']
score2 = -(B * a1 * woe2) + (A-B*b)/dataWOE.shape[0]

woe3 = WOE_dict['貸款金額組別']['(20000, 50000]']
score3 = -(B * a1 * woe3) + (A-B*b)/dataWOE.shape[0]

4.3 利率

WOE_dict['利率組別']

woe1 = WOE_dict['利率組別']['(0, 8]']
score1 = -(B * a2* woe1) + (A-B*b)/dataWOE.shape[0]

woe2 = WOE_dict['利率組別']['(8, 13]']
score2 = -(B * a2 * woe2) + (A-B*b)/dataWOE.shape[0]

woe3 = WOE_dict['利率組別']['(13, 50]']
score3 = -(B * a2 * woe3) + (A-B*b)/dataWOE.shape[0]

4.4 月負(fù)債比

WOE_dict['月負(fù)債比組別']

woe1 = WOE_dict['月負(fù)債比組別']['(-1, 20]']
score1 = -(B * a3* woe1) + (A-B*b)/dataWOE.shape[0]

woe2 = WOE_dict['月負(fù)債比組別']['(20, 1000]']
score2 = -(B * a3 * woe2) + (A-B*b)/dataWOE.shape[0]

4.5 貸款等級(jí)

WOE_dict['貸款等級(jí)']  

woe1 = WOE_dict['貸款等級(jí)'][1]
score1 = -(B * a4* woe1) + (A-B*b)/dataWOE.shape[0]

woe2 = WOE_dict['貸款等級(jí)'][2]
score2 = -(B * a4 * woe2) + (A-B*b)/dataWOE.shape[0]

woe3 = WOE_dict['貸款等級(jí)'][3]
score3 = -(B * a4 * woe3) + (A-B*b)/dataWOE.shape[0]

4.6 過(guò)去6個(gè)月內(nèi)被查詢次數(shù)

WOE_dict['過(guò)去6個(gè)月內(nèi)被查詢次數(shù)']  

woe1 = WOE_dict['過(guò)去6個(gè)月內(nèi)被查詢次數(shù)'][0]
score1 = -(B * a5* woe1) + (A-B*b)/dataWOE.shape[0]

woe2 = WOE_dict['過(guò)去6個(gè)月內(nèi)被查詢次數(shù)'][1]
score2 = -(B * a5 * woe2) + (A-B*b)/dataWOE.shape[0]

woe3 = WOE_dict['過(guò)去6個(gè)月內(nèi)被查詢次數(shù)'][2]
score3 = -(B * a5 * woe3) + (A-B*b)/dataWOE.shape[0]

woe4 = WOE_dict['過(guò)去6個(gè)月內(nèi)被查詢次數(shù)'][3]
score4 = -(B * a5 * woe4) + (A-B*b)/dataWOE.shape[0]

woe5 = WOE_dict['過(guò)去6個(gè)月內(nèi)被查詢次數(shù)'][4]
score5 = -(B * a5 * woe5) + (A-B*b)/dataWOE.shape[0]
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 申請(qǐng)?jiān)u分卡對(duì)于從事信貸風(fēng)控行業(yè)的人來(lái)說(shuō)肯定不陌生,甚至每天都會(huì)應(yīng)用到。申請(qǐng)?jiān)u分,即對(duì)申請(qǐng)客戶打分,對(duì)于業(yè)務(wù)專家來(lái)說(shuō)...
    紅栗灰閱讀 7,199評(píng)論 7 19
  • 1.IV的用途 IV的全稱是InformationValue,中文意思是信息價(jià)值,或者信息量。 我們?cè)谟眠壿嫽貧w、...
    peiyang閱讀 8,393評(píng)論 0 14
  • 1.IV的用途 IV的全稱是InformationValue,中文意思是信息價(jià)值,或者信息量。 我們?cè)谟眠壿嫽貧w、...
    Arya鑫閱讀 4,379評(píng)論 1 20
  • 一模型方法 (1)LR-邏輯回歸,線性回歸原理一樣。 Sigmoid函數(shù):公式如下,作用就是把Y轉(zhuǎn)換成0-1之間(...
    AithusaSponge閱讀 1,334評(píng)論 0 0
  • 2017-05-06 華杉 讀書(shū)是要以書(shū)為鏡,來(lái)觀照自己,把自己的心搞通,不是要把書(shū)讀通。如果心不通,卻要把那書(shū)搞...
    郁萍閱讀 1,232評(píng)論 0 0

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