Loan Prediction Problem

問題綜述
About Company
Dream Housing Finance company deals in all home loans. They have presence across all urban, semi urban and rural areas. Customer first apply for home loan after that company validates the customer eligibility for loan.

Problem
Company wants to automate the loan eligibility process (real time) based on customer detail provided while filling online application form. These details are Gender, Marital Status, Education, Number of Dependents, Income, Loan Amount, Credit History and others. To automate this process, they have given a problem to identify the customers segments, those are eligible for loan amount so that they can specifically target these customers. Here they have provided a partial data set.
用已知數(shù)據(jù)預(yù)測(cè)某人是否可以得到貸款,這是一個(gè)分類問題,我們可以用logistic regression,決策數(shù)和隨機(jī)森林等模型建模。
數(shù)據(jù)連接:https://github.com/Paliking/ML_examples/tree/master/LoanPrediction

理解數(shù)據(jù)

VARIABLE DESCRIPTIONS:
Variable                    Description
Loan_ID                     ID
Gender                      性別
Married                     是否結(jié)婚(Y/N)
Dependents                  家屬人數(shù)
Education                   是否是大學(xué)畢業(yè)生
Self_Employed               自雇人士(Y/N)
ApplicantIncome             申報(bào)收入
CoapplicantIncome           家庭收入
LoanAmount                  貸款金額
Loan_Amount_Term            貸款天數(shù)
Credit_History              信用記錄
Property_Area               房產(chǎn)位置
Loan_Status                 是否批準(zhǔn)貸款(Y/N)

觀察數(shù)據(jù)特征

對(duì)數(shù)據(jù)的觀察是為了更好的了解數(shù)據(jù),判斷出有用的變量,也為數(shù)據(jù)預(yù)處理提供依據(jù)。

數(shù)值觀察

先讀取數(shù)據(jù)集

# -*- coding: utf-8 -*-
%matplotlib inline 
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False#防止作圖中文亂碼
import pandas as pd
import numpy as np
import matplotlib as plt
df = pd.read_csv(r'C:\Users\Administrator\Desktop\train_u6lujuX_CVtuZ9i.csv',index_col=0)

總覽數(shù)據(jù)集

df.shape
image.png

觀察前20條數(shù)據(jù)

df.head(20)
前20條數(shù)據(jù)

可以使用info跟能看到全局

df.info()
image.png

用describe描述統(tǒng)計(jì)數(shù)據(jù)

df.describe()
image.png

看看空值


image.png
total =df.isnull().sum().sort_values(ascending=False)
percent_1 =df.isnull().sum()/df.isnull().count()*100
percent_2 = (round(percent_1, 1)).sort_values(ascending=False)
missing_data = pd.concat([total, percent_2], axis=1, keys=['Total', '%'])
missing_data.head(8)
空值占比

對(duì)于非數(shù)值變量我們可以用value_counts來計(jì)數(shù)


image.png

image.png

約有69%的人得到了貸款

從統(tǒng)計(jì)結(jié)果我們可以看到:
1,7個(gè)變量存在空值。
2,84%的人有信用記錄,約有69%的人得到了貸款。
3,從分位數(shù)看申請(qǐng)人收入情況,大致情況沒有異常;從最大值來看申報(bào)收入和家庭收入都有離群值

申請(qǐng)者各屬性分布

申報(bào)收入箱線圖

df.boxplot(column='ApplicantIncome')
申報(bào)收入箱線圖

極端值過多了,這種現(xiàn)象的原因有很多,在我們的數(shù)據(jù)集中我們可以用是否受大學(xué)教育來解釋


image.png

我們?cè)賮砜纯促J款金額(LoanAmount)

image.png
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(15,10))
fig.set(alpha=0.2)   

plt.subplot2grid((2,3),(0,0))            
df.Loan_Status.value_counts().plot(kind='bar')
plt.title(u"貸款批準(zhǔn)人數(shù)") # 標(biāo)題
plt.ylabel(u"人數(shù)")  

plt.subplot2grid((2,3),(0,1),colspan=2)
df['LoanAmount'].hist(bins=50)
plt.ylabel(u"人數(shù)")
plt.title(u"貸款金額")

plt.subplot2grid((2,3),(1,0))
df.Education.value_counts().plot(kind='bar')
plt.title(u"是否接受大學(xué)教育") # 標(biāo)題
plt.ylabel(u"人數(shù)") 

plt.subplot2grid((2,3),(1,1),colspan=2)
plt.scatter(df.ApplicantIncome, df.CoapplicantIncome,alpha=0.4,marker='o',)
plt.xlim(0,10000)
plt.ylim(0,10000)
plt.ylabel(u"年齡")                         # 設(shè)定縱坐標(biāo)名稱
plt.grid(b=True, which='major', axis='y') 
plt.title(u"申報(bào)收入和家庭收入")

plt.show()
幾個(gè)屬性

我們看散點(diǎn)圖(申報(bào)收入和家庭收入在一萬內(nèi)收入的人),有一個(gè)現(xiàn)象:申報(bào)收入為0的人是有家庭收入,在加入收入這個(gè)特征時(shí)我們可以把它們加起來看成是收入(Income)
貸款金額也是存在離群值的

各屬性與貸款批準(zhǔn)與否的關(guān)系

我們用pandas.crosstab形成交叉表


image.png

繪制堆疊圖


信用歷史和貸款批準(zhǔn)與否

信用是一個(gè)有力的特征,信用好的更容易得到貸款。

性別和貸款批準(zhǔn)與否

結(jié)婚與否和是否貸款
大學(xué)與貸款批準(zhǔn)與否

接受大學(xué)教育與否也是一個(gè)特征

a=df.groupby(['Credit_History','Gender','Loan_Status'])
dfa=pd.DataFrame(a.count()['Loan_ID'])
dfa
申請(qǐng)金額和貸款批準(zhǔn)與否

申請(qǐng)金額小更容易通過。


是否受雇傭與貸款批準(zhǔn)與否
grid = sns.FacetGrid(df, col='Loan_Status', row='Dependents', size=2.2, aspect=2)
grid.map(plt.hist, 'LoanAmount', alpha=.5, bins=50)
grid.add_legend()
家庭人數(shù)與借款額和貸款是否批準(zhǔn)

我們看不出家庭人數(shù)和借款額與Loan_Status的關(guān)系


我們可以從以上的圖里發(fā)現(xiàn)一些關(guān)系和現(xiàn)實(shí)合理的假設(shè):
1,有信用記錄的人更容易得到貸款
2,受大學(xué)教育與否對(duì)是否貸款有些影響
3,結(jié)婚人士更容易得到貸款
4,申請(qǐng)金額小更容易通過
這四個(gè)特征將先用于初步訓(xùn)練模型


數(shù)據(jù)處理

數(shù)據(jù)處理通常是對(duì)空缺值,離群值和非數(shù)值變量進(jìn)行處理。在處理時(shí)我們要衡量變量的缺失程度和特征的重要性,對(duì)一些具有意義的離群值要消除它的過度影響。

我們先對(duì)空缺值進(jìn)行處理
該怎么處理空值呢?有以下幾點(diǎn):
1,大量樣本缺失時(shí),我們可能選擇刪除該變量,這類樣本再加入模型可能影響模型結(jié)果。
2,適度樣本缺失時(shí),我們分兩種情況:
a,連續(xù)型:做一個(gè)步長(step)。b,非連續(xù)型:把空值作為一類加入到變量中
3,缺失值不是很多,我們可以放入模型試試,也可以根據(jù)現(xiàn)有數(shù)據(jù)補(bǔ)全。

我們把訓(xùn)練集和測(cè)試集合并取出要預(yù)測(cè)的變量Loan_Status

train_df = pd.read_csv(r'C:\Users\Administrator\Desktop\train_u6lujuX_CVtuZ9i.csv',index_col=0)
test_df=pd.read_csv(r'C:\Users\Administrator\Desktop\test_Y3wMUE5_7gLdaTN.csv',index_col=0)#讀取兩個(gè)數(shù)據(jù)集合

把Loan_Status編碼化(0,1),取出Loan_Status等于y待用

col_Loan_Status=pd.Categorical(train_df['Loan_Status'])
y=pd.DataFrame({'Loan_Status':col_Loan_Status.codes})
train_df=train_df.drop(['Loan_Status'],axis=1)
df=pd.concat((train_df,test_df),axis=0)

把兩個(gè)收入相加生成新的列,看看他的分布

df['Income'] = df['ApplicantIncome'] + df['CoapplicantIncome']
df['Income'].hist(bins=50)
image.png

這是一個(gè)有偏分布,在做計(jì)算判斷可能也會(huì)偏,我們可以讓它平穩(wěn)一點(diǎn)。

df['Income_log'] = np.log1p(df['Income'])
df.drop(['Income','ApplicantIncome','CoapplicantIncome'],axis=1,inplace=True)
df['Income_log'].hist(bins=25)
image.png

這樣分布更符合正態(tài)分布

同樣的我們也把LoanAmount進(jìn)行對(duì)數(shù)處理,處理前先把空值填充,方法是從均值加減標(biāo)準(zhǔn)差隨機(jī)取數(shù)

mean = df["LoanAmount"].mean()
std = df["LoanAmount"].std()
is_null = df["LoanAmount"].isnull().sum()
# compute random numbers between the mean, std and is_null
rand_LoanAmount = np.random.randint(mean - std, mean + std, size = is_null)
# fill NaN values in Age column with random values generated
LoanAmount_slice = df["LoanAmount"].copy()
LoanAmount_slice[np.isnan(LoanAmount_slice)] = rand_LoanAmount
df["LoanAmount"] = LoanAmount_slice
df["LoanAmount"] = df["LoanAmount"].astype(int)

對(duì)數(shù)處理

df['LoanAmount_log']=np.log1p(df['LoanAmount'])
df.drop(['LoanAmount'],axis=1,inplace=True)

看看還剩什么要處理


空缺值

Married缺失值只有三個(gè),我們使用pandas中fillna填充,先編碼化


M={'Yes':1,'No':0}
df['Married']=df['Married'].map(M)
df['Married']=df['Married'].fillna(method='pad')
df['Married']=df['Married'].astype(int)

同樣的方法對(duì)Gender,Self_Employed,Dependents,LoanAmount,Education


image.png
S={'Yes':1,'No':0}
df['Self_Employed']=df['Self_Employed'].map(S)
df['Self_Employed']=df['Self_Employed'].fillna(method='pad').astype(int)

df['Loan_Amount_Term']=df['Loan_Amount_Term'].fillna(method='pad').astype(int)

G={'Male':1,'Female':0}
df['Gender']=df['Gender'].map(G)
df['Gender']=df['Gender'].fillna(method='pad').astype(int)

df['Dependents'].replace(['0','1','2','3+'],[0,1,2,3],inplace=True)
df['Dependents']=df['Dependents'].fillna(method='pad').astype(int)

E={'Graduate':1,'Not Graduate':0}
df['Education']=df['Education'].map(E)
df['Education']=df['Education'].fillna(method='pad').astype(int)

看看我們的數(shù)據(jù)。


image.png

image.png

好多了,還剩下Property_Area和Credit_History的缺失值
對(duì)Property_Area的處理,由于數(shù)字是有大小的,如果對(duì)Property_Area數(shù)字編碼的話可能數(shù)字的大小對(duì)模型產(chǎn)生影響,因此我們對(duì)它使用pandas自帶的get_dummiesOne-Hot處理。實(shí)際上以上某些變量也可以用這個(gè)方法處理。

dummy_Property_Area=pd.get_dummies(df['Property_Area'])
df=pd.concat([df,dummy_Property_Area],axis=1)
df.drop(['Property_Area'],axis=1,inplace=True)

jiexialai對(duì)Credit_History進(jìn)行處理
在這里我們可以對(duì)信用記錄是否是缺失分為兩類看看他們與是否批準(zhǔn)貸款的分布

fig = plt.figure()
fig.set(alpha=0.2) 
noCH=df.Loan_Status[pd.isnull(df.Credit_History)].value_counts()
CH = df.Loan_Status[pd.notnull(df.Credit_History)].value_counts()
df1=pd.DataFrame({'不缺失':CH,'缺失':noCH}).transpose()
df1.plot(kind='bar',stacked=True,color=['blue','red'])
plt.title("按信用記錄是否缺失看是否貸款")
plt.xlabel("信用記錄是否缺失")
plt.ylabel("人數(shù)")
image.png
image.png

信用記錄是缺失值的似乎更難得到貸款。
我把空值作為一類即,再對(duì)它One-Hot處理。

dummy_Credit_History=pd.get_dummies(df['Credit_History'])
df=pd.concat([df,dummy_Credit_History],axis=1)
df.drop(['Credit_History'],axis=1,inplace=True)

都處理完了。我們看看


image.png

特征建立

日平均還款的對(duì)數(shù):用于衡量平均每日還款

df['Day_Payment']=cc['LoanAmount']/cc['Loan_Amount_Term']
df['Day_Payment'].fillna(df['Day_Payment'].mean(),inplace=True)

家庭收入比總收入和申報(bào)收入比總收入:用來衡量收入來源

aa = pd.read_csv(r'C:\Users\Administrator\Desktop\train_u6lujuX_CVtuZ9i.csv',index_col=0)
bb = pd.read_csv(r'C:\Users\Administrator\Desktop\test_Y3wMUE5_7gLdaTN.csv',index_col=0)#讀取兩個(gè)數(shù)據(jù)集合
cc=pd.concat((aa,bb),axis=0)
cc['ApplicantIncome']=np.log1p(cc['ApplicantIncome'])
cc['CoapplicantIncome']=np.log1p(cc['CoapplicantIncome'])
cc['Income']=cc['ApplicantIncome']+cc['CoapplicantIncome']
df['CoIncome_index']=cc['CoapplicantIncome']/cc['Income']
df['AppIncome_index']=cc['ApplicantIncome']/cc['Income']

建立機(jī)器學(xué)習(xí)模型

先把兩個(gè)集合分開

D_train_df =df.loc[train_df.index]
D_test_df =df.loc[test_df.index]
D_train_df.shape,D_test_df.shape
image.png
最后編輯于
?著作權(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ù)。

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

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