個(gè)人貸款用戶分析(特征分析&邏輯回歸)

1??項(xiàng)目需求背景

為了擴(kuò)大貸款業(yè)務(wù)的客戶人數(shù),該銀行去年針對(duì)現(xiàn)有的存款用戶但未辦理貸款業(yè)務(wù)的客戶展開了一項(xiàng)推廣活動(dòng),促使其辦理個(gè)人貸款業(yè)務(wù),取得了較好的轉(zhuǎn)化效果。今年希望通過識(shí)別出更有貸款潛力的客戶,提高活動(dòng)轉(zhuǎn)化率,降低營(yíng)銷費(fèi)用

2??數(shù)據(jù)收集

去年?duì)I銷活動(dòng)的用戶信息,共包含5000條記錄,14個(gè)字段,對(duì)應(yīng)字段含義如下:

ID - 客戶

Age - 客戶年齡

Experience - 客戶工作經(jīng)驗(yàn)

Income - 客戶年收入(單位:千美元)

ZIPCode - 家庭地址郵政編碼

Family - 客戶的家庭規(guī)模

CCAvg - 每月信用卡消費(fèi)額(單位:千美元)

Education - 教育水平 (1: 本科; 2: 研究生; 3: 高級(jí))

Mortgage - 房屋抵押價(jià)值(如有)(單位:千美元)

Personal Loan - 此客戶是否接受上一次活動(dòng)中提供的個(gè)人貸款?(1:是 0:否)

Securities Account - 是否有證券賬戶?(1:是 0:否)

CD Account - 是否有存款證明(CD)帳戶嗎(1:是 0:否)

Online - 是否開通網(wǎng)上銀行?(1:是 0:否)

CreditCard - 是否有信用卡?(1:是 0:否)

#導(dǎo)入相關(guān)庫
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

#設(shè)置全部行輸出
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

#讀取數(shù)據(jù)
data=pd.read_csv('Personal_Loan.csv')data.head()

3??數(shù)據(jù)探索和清洗

3.1??查看數(shù)據(jù)的形狀、類型,處理缺失值、重復(fù)值、異常值

#數(shù)據(jù)整體情況

data.info()

-- 無缺失值,需要把Mortgage和Income更改為float類型,ZIP Code改為字符型

#變量類型轉(zhuǎn)換

data.Mortgage=data.Mortgage.astype('float')

data.Income=data.Income.astype('float')

data['ZIP Code']=data['ZIP Code'].astype('str')

data.info()

#查看重復(fù)值的個(gè)數(shù)

data.duplicated().sum()

-- 無重復(fù)值

#查看異常值

data.columns

#選擇散點(diǎn)圖方式

fig = plt.figure()

plt.scatter(data.values[:,0],data.values[:,2])

-- 查看各列的散點(diǎn)圖,Experience列出現(xiàn)負(fù)數(shù)值,為異常數(shù)據(jù)

#把Experience負(fù)值改為0

data.loc[data.Experience<0,'Experience']=0

3.2??描述性統(tǒng)計(jì)

data.describe()

4??數(shù)據(jù)預(yù)處理

4.1??去年?duì)I銷活動(dòng)的效果如何

# 去年?duì)I銷活動(dòng)效果

data.groupby('Personal Loan').size()

-- 5000名客戶中,有480個(gè)客戶開通了個(gè)人貸款業(yè)務(wù),轉(zhuǎn)化率9.6%,說明此次推廣活動(dòng)的效果還是不錯(cuò)的。數(shù)據(jù)源的可信度也比較高

4.2??特征篩選

4.2.1??相關(guān)系數(shù)

#把ID設(shè)為索引,ID不屬于變量

data.set_index(['ID'],inplace=True)

#因變量Personal Loan跟其他變量的相關(guān)系數(shù)

cor = data.corr()['Personal Loan']

cor

cor[abs(cor)>0.05

#fig代表繪圖窗口(Figure);axis代表這個(gè)繪圖窗口上的坐標(biāo)系(axis)

fig,axis=plt.subplots(figsize=(10,10))

#繪制熱力圖,顏色越深,相關(guān)性越強(qiáng)

ax=sns.heatmap(data.corr(),annot=True,linecolor='black',cmap="BrBG_r",fmt='.2f')

#fmt設(shè)置小數(shù)位

#bottom代表y軸下限,top表示y軸上限(matplotlib版本畫熱力圖上下邊框只顯示一半)

bottom, top = ax.get_ylim()

ax.set_ylim(bottom + 0.5, top - 0.5);

由相關(guān)系數(shù)和熱力圖:

1.與Personal Loan強(qiáng)相關(guān)的變量:Income收入、CCAvg信用卡還款額和CD Account是否有是存款證明帳戶

2.與Personal Loan弱相關(guān)的變量:Education受教育程度,Mortgage房屋抵押價(jià)值和Family家庭人數(shù)

3.其中Age年齡、Experience工作經(jīng)驗(yàn)和ZIP Code家庭地址郵政編碼雖然關(guān)系不大,但它們屬于連續(xù)型變量,需要進(jìn)一步分析。可以分箱后再做觀察,看看是否有某一段存在特殊值,也可以考慮放在模型中

定性變量:CD Account是否有是存款證明帳戶、Education受教育程度、Family家庭人數(shù)

定量變量:Income收入、CCAvg信用卡還款額、Mortgage房屋抵押價(jià)值

4.2.2??定性變量

# rc參數(shù)

plt.rcParams['font.sans-serif']=['SimHei']

plt.rcParams['axes.unicode_minus'] = False

#CD Account

#開通CD Account的用戶貸款比例

data.groupby('CD Account')['Personal Loan'].agg(['mean','count'])

#可視化

f,ax1= plt.subplots()

sns.countplot(x='CD Account',hue='Personal Loan',data=data,ax=ax1)

ax1.set_title('用戶貸款比例')#標(biāo)題

-- 開通了CD Account的客戶,貸款的比例遠(yuǎn)高于是沒有開通的客戶,說明開通CD Account的客戶成為貸款業(yè)務(wù)的潛在客戶可能性更大;且大量客戶沒有開通CD Account,找到方法讓客戶開通CD Account也是一個(gè)提高貸款率的可能選項(xiàng)

#Education

data.groupby('Education')['Personal Loan'].agg(['mean','count'])

-- 受教育水平越高,貸款的比例越高,尤其在本科以上學(xué)歷差距明顯,說明受教育水平高的用戶成為貸款業(yè)務(wù)的潛在客戶可能性更大

#Family

data.groupby('Family')['Personal Loan'].agg(['mean','count'])

-- 單身人士與沒有孩子的家庭的貸款率都比較低,有孩子的家庭用戶相對(duì)而言更有意愿轉(zhuǎn)化為貸款用戶,特別是獨(dú)生子女家庭

4.2.3??定量分析-分箱

#Income收入

data['Income_bins']=pd.qcut(data.Income,20)

data.groupby('Income_bins')['Personal Loan'].agg(['mean','count'])

data.groupby('Income_bins')['Personal Loan'].mean().plot()

-- 高收入人群明顯申請(qǐng)貸款的,收入小于64時(shí),貸款率幾乎為零,收入超過98時(shí),貸款率急劇上升,超過170時(shí),貸款意愿達(dá)到50%

#CCAvg信用卡還款額

data['CCAvg_bins']=pd.qcut(data.CCAvg,20)

data.groupby('CCAvg_bins')['Personal Loan'].agg(['mean','count'])

data.groupby('CCAvg_bins')['Personal Loan'].mean().plot()

-- CCAvge在2.8時(shí),貸款率會(huì)增大將近4倍;在4.3-6.0區(qū)間會(huì)貸款率會(huì)達(dá)到45%;大于6時(shí),貸款率會(huì)稍有回落,但貸款意愿依舊比較強(qiáng)

#Mortgage房屋抵押價(jià)值

data['Mortgage_bins']=pd.cut(data.Mortgage,10)? #等深分箱會(huì)有重復(fù)邊界值,為0的數(shù)據(jù)占比太多

data.groupby('Mortgage_bins')['Personal Loan'].agg(['mean','count'])

plt.subplots(figsize=(15,5))

data.groupby('Mortgage_bins')['Personal Loan'].mean().plot()

-- 當(dāng)Mortgage大于190.5時(shí),貸款申請(qǐng)的意愿有明顯的提升,總體來看,抵押值越高,貸款轉(zhuǎn)化率越高。但房屋抵押價(jià)值高的客戶很少

4.2.4??對(duì)相關(guān)系數(shù)低的連續(xù)型變量分箱觀察

#Age年齡

data['Age_bins']=pd.qcut(data.Age,6)

data.groupby('Age_bins')['Personal Loan'].agg(['mean','count'])

data.groupby('Age_bins')['Personal Loan'].mean().plot()

-- Age在32-39區(qū)間時(shí)貸款率較高,但總體年齡跟貸款率的相關(guān)性不高

#Experience工作經(jīng)驗(yàn)

data['Experience_bins']=pd.qcut(data.Experience,6)

data.groupby('Experience_bins')['Personal Loan'].agg(['mean','count'])

data.groupby('Experience_bins')['Personal Loan'].mean().plot()

-- Experience在7-14區(qū)間時(shí)貸款率較高,但總體工作經(jīng)驗(yàn)跟貸款率的相關(guān)性不高

#ZIP Code家庭地址郵政編碼

#郵政編碼的第一個(gè)數(shù)字代表美國(guó)各州,第二個(gè)和第三個(gè)數(shù)字一起代表一個(gè)地區(qū)(或一個(gè)大城市),所以按照第2、3個(gè)數(shù)字分區(qū)

data['ZIP Code_bins']=data['ZIP Code'].str.extract('9(\d\d)',expand=False)

plt.subplots(figsize=(15,5))

data.groupby('ZIP Code_bins')['Personal Loan'].agg(['mean','count'])

data.groupby('ZIP Code_bins')['Personal Loan'].mean().plot()

-- ZIP Code各地區(qū)與貸款率相關(guān)性不高

5??模型搭建

用連續(xù)型變量和分箱兩種方式測(cè)試模型的效果

5.1??用原始數(shù)據(jù)的變量

data.head(2)

最終選取加入模型的6個(gè)變量:Income收入、Family家庭人數(shù)、CCAvg信用卡還款額、Education受教育程度、Mortgage房屋抵押價(jià)值和CD Account是否有是存款證明帳戶(已嘗試把Experience、Age、ZIP Code加入模型,沒有改善模型)

data.iloc[:,[2,4,5,6,7,10]].head()

# model_selection模型選擇功能

#train_test_split 訓(xùn)練測(cè)試分區(qū)

#cross_val_score 交叉驗(yàn)證得分

from sklearn.model_selection import train_test_split,cross_val_score

#劃分訓(xùn)練集和測(cè)試集

xtrain,xtest,ytrain,ytest=train_test_split(data.iloc[:,[2,4,5,6,7,10]],data.iloc[:,8]

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ,test_size=0.3)

#test_size=0.2,指定訓(xùn)練測(cè)試集隨機(jī)抽樣20%的數(shù)據(jù)

#random_state=0 隨機(jī)種子數(shù)的確定

xtrain.shape

#導(dǎo)入包和類

from sklearn.linear_model import LogisticRegression

#實(shí)例化

log=LogisticRegression(solver="lbfgs",C=0.04,max_iter=400)

#擬合數(shù)據(jù)

log.fit(xtrain,ytrain)

log.score(xtrain,ytrain)#訓(xùn)練集R方

log.score(xtest,ytest)#測(cè)試集R方

y_log=log.predict(xtest)#predict_proba 預(yù)測(cè)評(píng)分,y的估計(jì)值。根據(jù)預(yù)測(cè)的概率,大于0.5的返回1

-- 正確率都是94%,考慮到數(shù)據(jù)集0、1分布極不均衡,還要看下f1指標(biāo)

5.2??使用連續(xù)型變量分箱后的數(shù)據(jù)

df=data.copy()

df=df.loc[:,['Income_bins','Family','CCAvg_bins','Education','Mortgage_bins','CD Account','Personal Loan']]

df.head()

#數(shù)字編碼

from sklearn.preprocessing import LabelEncoder

encoder= LabelEncoder().fit(df["Income_bins"])

df["Income_bins"] = encoder.transform(df["Income_bins"])

encoder= LabelEncoder().fit(df["CCAvg_bins"])

df["CCAvg_bins"] = encoder.transform(df["CCAvg_bins"])

encoder= LabelEncoder().fit(df["Mortgage_bins"])

df["Mortgage_bins"] = encoder.transform(df["Mortgage_bins"])

df.info() #需要的變量是數(shù)值型了

# model_selection模型選擇功能

#train_test_split 訓(xùn)練測(cè)試分區(qū)

#cross_val_score 交叉驗(yàn)證得分

from sklearn.model_selection import train_test_split,cross_val_score

#劃分訓(xùn)練集和測(cè)試集

xtrain_new,xtest_new,ytrain_new,ytest_new=train_test_split(df.iloc[:,:6],df.iloc[:,-1]

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ,test_size=0.3,random_state=2)

#test_size=0.2,指定訓(xùn)練測(cè)試集隨機(jī)抽樣20%的數(shù)據(jù)

#random_state=0 隨機(jī)種子數(shù)的確定

xtrain_new.shape

log_new=LogisticRegression(solver="lbfgs",C=0.3,max_iter=100)

#擬合數(shù)據(jù)

log_new.fit(xtrain_new,ytrain_new)

log_new.score(xtrain_new,ytrain_new)

log_new.score(xtest_new,ytest_new)

y_log_new=log_new.predict(xtest_new)

-- 正確率也是94%,跟方法一差不多

6??模型評(píng)估

6.1??混淆矩陣預(yù)測(cè)

對(duì)模型進(jìn)行評(píng)價(jià)

#方法一:

from sklearn.metrics import confusion_matrix #混淆矩陣包

from sklearn.metrics import classification_report #分類報(bào)告包

cm=confusion_matrix(ytest,y_log)#行放y,列放y的預(yù)測(cè)值,形成2*2的交叉表

print(classification_report(ytest,y_log,target_names=['非貸款','貸款']))

sns.heatmap(cm,fmt="d",cmap="icefire",annot=True)#annot將數(shù)值顯示在單元格里

-- 方法一:預(yù)測(cè)正確率95%,召回率53%,精準(zhǔn)率88%,f1是66%,該數(shù)據(jù)中1和0的比例差距較大,所以不能看正確率,主要看f1,模型總體得分較低

#方法二:

from sklearn.metrics import confusion_matrix #混淆矩陣包

from sklearn.metrics import classification_report #分類報(bào)告包

cm_new=confusion_matrix(ytest_new,y_log_new)#行放y,列放y的預(yù)測(cè)值,形成2*2的交叉表

print(classification_report(ytest_new,y_log_new,target_names=['非貸款','貸款']))

sns.heatmap(cm_new,fmt="d",cmap="icefire",annot=True)#annot將數(shù)值顯示在單元格里

-- 方法二:預(yù)測(cè)正確率95%,召回率57%,精準(zhǔn)率82%,f1是68%,比方法一得分高一點(diǎn),但差距不大

6.2??交叉驗(yàn)證

評(píng)估模型的穩(wěn)定性

#方法一:

from sklearn.model_selection import cross_val_score,LeaveOneOut,KFold,GroupKFold

x,y=data.iloc[:,[1,2,4,5,6,7,10]],data.iloc[:,8]

scores=cross_val_score(log,x,y,cv=3,scoring="f1")

print('交叉驗(yàn)證:%s'%scores)

print('平均交叉驗(yàn)證得分:%s'% np.mean(scores))

-- 方法一:交叉驗(yàn)證得分之差超過2%,模型過擬合

#方法二:

x_new,y_new=df.iloc[:,:6],df.iloc[:,-1]

scores_new=cross_val_score(log_new,x_new,y_new,cv=3,scoring="f1")

print('交叉驗(yàn)證:%s'%scores_new)

print('平均交叉驗(yàn)證得分:%s'% np.mean(scores_new))


-- 方法二:得分之差減小,分組后的數(shù)據(jù)讓模型更穩(wěn)定了

6.3??解釋模型

輸出回歸系數(shù)和OR值

log.coef_

(np.exp(log.coef_)-1)*100

#順序:Income Family CCAvg Education Mortgage CD Account

#輸出回歸系數(shù)

log_new.coef_

(np.exp(log_new.coef_)-1)*100#方法二OR值

#順序:Income_bins Family CCAvg_bins Education Mortgage_bins CD Account

-- 方法一和方法二的OR值差別很大

6.4??用SGD模型 結(jié)合網(wǎng)格搜索進(jìn)行調(diào)參

#建模

from sklearn.linear_model import SGDClassifier

sgd_clf=SGDClassifier(loss="log")

sgd_clf.fit(xtrain,ytrain)#擬合訓(xùn)練集數(shù)據(jù)

sgd_clf.score(xtest,ytest)#非監(jiān)督模型是transform

from sklearn.model_selection import GridSearchCV

#參數(shù)設(shè)置

parameters=[{'penalty':['l2','l1'],'alpha':[0.04,0.05,0.06]},

? ? ? ? ? ? {'l1_ratio':[0.1,0.5,0.9,1]}

? ? ? ? ? ]

#線性回歸中叫algha系數(shù),logistic和svm叫C。懲罰系數(shù)的倒數(shù),值越小,正則化越大(懲罰越大),修正過擬合,共線性

grid_search=GridSearchCV(sgd_clf,parameters,cv=3,scoring='accuracy')#scoring='accuracy'

grid_search.fit(xtrain,ytrain)

print("測(cè)試得分:%s" %grid_search.score(xtest,ytest))

print("全部及最優(yōu)系數(shù):%s" %grid_search.best_estimator_)

-- 方法一最優(yōu)正則化系數(shù)是0.04,迭代正則化系數(shù)C

#建模

sgd_clf=SGDClassifier(loss="log")

sgd_clf.fit(xtrain_new,ytrain_new)#擬合訓(xùn)練集數(shù)據(jù)

sgd_clf.score(xtest_new,ytest_new)#非監(jiān)督模型是transform


#參數(shù)設(shè)置

parameters=[{'penalty':['l2','l1'],'alpha':[0.04,0.05,0.06]},

? ? ? ? ? ? {'l1_ratio':[0.1,0.5,0.9,1]}

? ? ? ? ? ]

#線性回歸中叫algha系數(shù),logistic和svm叫C。懲罰系數(shù)的倒數(shù),值越小,正則化越大(懲罰越大),修正過擬合,共線性

grid_search=GridSearchCV(sgd_clf,parameters,cv=3,scoring='accuracy')#scoring='accuracy'

grid_search.fit(xtrain_new,ytrain_new)

print("測(cè)試得分:%s" %grid_search.score(xtest_new,ytest_new))

print("全部及最優(yōu)系數(shù):%s" %grid_search.best_estimator_)

-- 方法二最優(yōu)正則化系數(shù)是0.0001,迭代正則化系數(shù)C(但是這個(gè)系數(shù)迭代過去效果并不好,疑問?)

7??結(jié)論

7.1??相關(guān)性部分

更容易轉(zhuǎn)化為貸款客戶的用戶有如下特征:

· 開通了銀行賬戶的用戶相對(duì)于沒有開通銀行賬戶貸款意愿更強(qiáng)

·?教育水平越高的客戶越容易接受貸款

·?家庭人口較多的家庭貸款意愿較強(qiáng),尤其是獨(dú)生子女的家庭

·?年齡區(qū)間在30-40歲的客戶相對(duì)貸款意愿更強(qiáng)

·?相對(duì)收入越高,貸款的意愿越強(qiáng)烈, 當(dāng)年收入超過82時(shí),貸款意愿會(huì)有5倍以上的上升,超過98時(shí),貸款意愿達(dá)到17%以上,超過170時(shí),貸款意愿達(dá)到一半

·?當(dāng)房屋抵押值大于190.5千美元時(shí),貸款申請(qǐng)的意愿有明顯的提升,但房屋抵押價(jià)值高的客戶很少

·?每月消費(fèi)額在2.8千美元以上的客戶,貸款申請(qǐng)的意愿有明顯的提升

7.2??模型部分

模型總體得分較低,OR值過高,還需要找原因優(yōu)化,以下只是基于目前不成熟分析的結(jié)論

分組后的數(shù)據(jù)穩(wěn)定性更好,目前得到的預(yù)測(cè)正確率95%,召回率57%,精準(zhǔn)率82%,f1是68%

在其他條件不變的情況下:

·?Income_bins增加一個(gè)單位,貸款率提高143%;

·?Family增加一個(gè)單位,貸款率提高130%;

·?CCAvg_bins增加一個(gè)單位,貸款率提高6%;

·?Education增加一個(gè)單位,貸款率提高460%;

·?Mortgage_bins增加一個(gè)單位,貸款率提高4%;

·?CD Account增加一個(gè)單位,貸款率提高614%

最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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