Loan Prediction 貸款數據的預測分析,通過使用python來分析申請人哪些條件對貸款有影響,並預測哪些客戶更容易獲得銀行貸款。
- 查看數據集
import numpy as np import pandas as pd from matplotlib import pyplot as plt import seaborn as sns %matplotlib inline # 導入數據 full_data = pd.read_csv('../Loan_Prediction/loan_train.csv') full_data.shape # 查看前五行數據 full_data.head()
數據有614行,13列。
""" 數據集的 有這些子段
Loan_ID 貸款人ID Gender 性別 (Male, female) ApplicantIncome 申請人收入Coapplicant Income 申請收入 Credit_History 信用記錄 Dependents 親屬人數
Education 教育程度 LoanAmount 貸款額度 Loan_Amount_Term 貸款時間長
Loan_Status 貸款狀態 (Y, N) Married 婚姻狀況(NO,Yes)
Property_Area 所在區域包括:城市地區、半城區和農村地區
Self_Employed 職業狀況:自僱還是非自僱
這裏是 前面 五條的 數據
""" -
Loan_ID Gender Married Dependents Education Self_Employed ApplicantIncome CoapplicantIncome LoanAmount Loan_Amount_Term Credit_History Property_Area Loan_Status 0 LP001002 Male No 0 Graduate No 5849 0.0 NaN 360.0 1.0 Urban Y 1 LP001003 Male Yes 1 Graduate No 4583 1508.0 128.0 360.0 1.0 Rural N 2 LP001005 Male Yes 0 Graduate Yes 3000 0.0 66.0 360.0 1.0 Urban Y 3 LP001006 Male Yes 0 Not Graduate No 2583 2358.0 120.0 360.0 1.0 Urban Y 4 LP001008 Male No 0 Graduate No 6000 0.0 141.0 360.0 1.0 Urban Y - 查看描述統計數據 可以查看 每個字段的 記數—平均值——方差——最小值——25%的值——50%的值——75%的值——Max的 值 full_data.describe() # 它只會描述 數值型的 子段
- 查看數據集
full_data.info() #會看到 數據缺失值 情況 - 一. 開始從 單變量 進行分析 1. 分析目標變量Loan_Status貸款狀態
# 目標變量統計 full_data['Loan_Status'].value_counts() #Y 422 #N 192 #Name: Loan_Status, dtype: int64 #統計百分比 full_data['Loan_Status'].value_counts(normalize=True) # 614個人中有422人(約69%)獲得貸款批准 sns.countplot(x='Loan_Status', data=full_data, palette = 'Set1') # 畫圖查看
2.Gender 性別特徵
# 2.Gender 性別特徵 full_data['Gender'].value_counts(normalize=True) # 數據集中80%的申請人是男性。 sns.countplot(x='Gender', data=full_data, palette = 'Set1') #畫圖 分析
3.Married 婚姻特徵
# 3.Married 婚姻特徵 full_data['Married'].value_counts(normalize=True) #Yes 0.651391 #No 0.348609 #Name: Married, dtype: float64 sns.countplot(x='Married', data=full_data, palette = 'Set1')
4. Dependent親屬特徵
# 4.Dependent親屬特徵 Dependents=full_data['Dependents'].value_counts(normalize=True) # 貸款客戶主要集中在沒有親屬關係中,佔到57%. Dependents.plot.bar(title= 'Dependents')
5.是否自僱人士
# 5.是否自僱人士 Self_Employed=full_data['Self_Employed'].value_counts(normalize=True) Self_Employed #No 0.859107 #Yes 0.140893 #Name: Self_Employed, dtype: float64 Self_Employed.plot.bar(title= 'Self_Employed')
6. 貸款人 天數 分佈情況
# 貸款人 時間分佈情況 full_data['Loan_Amount_Term'].value_counts(normalize=True) # 貸款時間主要集中在360天 (1年) full_data['Loan_Amount_Term'].value_counts().plot.bar(title= 'Loan_Amount_Term')
7.Credit_History 信用記錄變量
# 7.Credit_History 信用記錄變量 Credit_History=full_data['Credit_History'].value_counts(normalize=True) #1.0 0.842199 #0.0 0.157801 #Name: Credit_History, dtype: float64 Credit_History.plot.bar(title= 'Credit_History')
8.Education 教育程度
# 8.Education 教育程度 Education=full_data['Education'].value_counts(normalize=True) Education #Graduate 0.781759 #Not Graduate 0.218241 #Name: Education, dtype: float64 Education.plot.bar(title= 'Education') # 貸款的客戶中有接近80%的客戶主要是受教育的畢業生
單變量分析完,後面看多變量分析,在往後面進一步分析
-
二、雙變量分析各個特徵與目標變量(Loan_Status)的關係 1.性別與貸款關係
# 1.性別與貸款關係 Gender=pd.crosstab(full_data['Gender'],full_data['Loan_Status']) # crosstab 交叉表 Gender.plot(kind="bar", stacked=True, figsize=(5,5)) #stacked=True 倆個圖是否畫一起 Gender # 男性更容易申請通過貸款
2.結婚與貸款關係
# 2.結婚與貸款關係 Married=pd.crosstab(full_data['Married'],full_data['Loan_Status']) Married.plot(kind="bar", stacked=True, figsize=(5,5)) # 已經結婚的客戶申請貸款通過的最高
3.親屬人數與貸款關係
# 3.親屬人數與貸款關係 Dependents=pd.crosstab(full_data['Dependents'],full_data['Loan_Status']) Dependents.plot(kind="bar", stacked=True, figsize=(5,5)) # 親屬關係的客戶越少 ---> 越容易獲得申請通過貸款
4.教育與貸款關係
# 4.教育與貸款關係 Education=pd.crosstab(full_data['Education'],full_data['Loan_Status']) Education.plot(kind="bar", stacked=True, figsize=(5,5)) # 已經受教育畢業的客戶獲得貸款更容易
5.職業與貸款關係
# 5.職業與貸款關係 Self_Employed=pd.crosstab(full_data['Self_Employed'],full_data['Loan_Status']) Self_Employed.plot(kind="bar", stacked=True, figsize=(5,5)) # 不是自僱客戶申請通過的最高,就是上班的吧
6.信用記錄與貸款之間的關係
7.區域與貸款關係
# 7.區域與貸款關係 Property_Area=pd.crosstab(full_data['Property_Area'],full_data['Loan_Status']) Property_Area.plot(kind="bar", stacked=True, figsize=(5,5)) # 在半城市區獲得批准的貸款要高於農村或城市地區
看了變量 與目標變量的 關係,之後再看 變量與變量的 關係
- 三、熱圖來可視化相關性
用於查看所有數值變量之間的相關性。
首先將類別特徵值轉爲數值型,方便熱圖分析相關性
# replace 方法 full_data['Gender'].replace(('Female','Male'),(0,1),inplace=True) full_data['Dependents'].replace(('0', '1', '2', '3+'),(0, 1, 2, 3),inplace=True) full_data['Education'].replace(('Not Graduate', 'Graduate'),(0, 1),inplace=True) full_data['Property_Area'].replace(('Semiurban','Urban','Rural'),(0,1,2),inplace=True) # map 方法 maps = {'Yes':1,'No':0} maps_status = {'Y':1,'N':0} full_data['Married'] = full_data['Married'].map(maps) full_data['Self_Employed'] = full_data['Self_Employed'].map(maps) full_data['Loan_Status'] = full_data['Loan_Status'].map(maps_statusstatus) # 目標變量 full_data
這些把 字符串 轉換成 整型 後好做進一步 操作
# 通過着色的變化來顯示數據。顏色較深的變量意味着它們的相關性更高。 matrix = full_data.corr() # corr 相關性計算 f, ax = plt.subplots(figsize=(8, 8)) # sns.heatmap(matrix,vmax=.8, square=True,cmap="BuPu"); # annot=True 顯示數字 表示 sns.heatmap(matrix,vmax=.1, square=True,cmap="BuPu",annot=True); matrix # 計算 協方差矩陣,看相關性
這是 所以 變量的協方差 矩陣
這是 熱力圖 ,用數字 顯示更精準,好看直觀 這缺失值 可以作爲第一部分析也可以Gender Married Dependents Education Self_Employed ApplicantIncome CoapplicantIncome LoanAmount Loan_Amount_Term Credit_History Property_Area Gender 1.000000 0.369612 0.175970 -0.049258 -0.009829 0.053989 0.083946 0.106947 -0.075117 0.016337 0.111964 Married 0.369612 1.000000 0.343417 -0.014223 0.001909 0.051332 0.077770 0.149519 -0.103810 0.004381 -0.004754 Dependents 0.175970 0.343417 1.000000 -0.059161 0.057867 0.118679 0.027259 0.163997 -0.100484 -0.050082 -0.005747 Education -0.049258 -0.014223 -0.059161 1.000000 0.012333 0.140760 0.062290 0.171133 0.078784 0.081822 -0.066740 Self_Employed -0.009829 0.001909 0.057867 0.012333 1.000000 0.140826 -0.011152 0.123931 -0.037069 0.003883 0.009740 ApplicantIncome 0.053989 0.051332 0.118679 0.140760 0.140826 1.000000 -0.116605 0.570909 -0.045306 -0.014715 0.017321 CoapplicantIncome 0.083946 0.077770 0.027259 0.062290 -0.011152 -0.116605 1.000000 0.188619 -0.059878 -0.002056 0.019087 LoanAmount 0.106947 0.149519 0.163997 0.171133 0.123931 0.570909 0.188619 1.000000 0.039447 -0.008433 0.029437 Loan_Amount_Term -0.075117 -0.103810 -0.100484 0.078784 -0.037069 -0.045306 -0.059878 0.039447 1.000000 0.001470 -0.017506 Credit_History 0.016337 0.004381 -0.050082 0.081822 0.003883 -0.014715 -0.002056 -0.008433 0.001470 1.000000 -0.036906 Property_Area 0.111964 -0.004754 -0.005747 -0.066740 0.009740 0.017321 0.019087 0.029437 -0.017506 -0.036906 1.00000 - 四、缺失值和異常值的處理
# 連續變量特徵分析是否有異常值 # 申請人收入數據分析 plt.figure() plt.subplot(121) sns.distplot(full_data['ApplicantIncome']); # seaborn.displot查看變量分佈 plt.subplot(122) full_data['ApplicantIncome'].plot.box(figsize=(16,5)) # box 箱線圖 plt.show() # 收入分配的大部分數據主要偏在左邊,沒有呈現正態分佈, # 箱線圖確認存在大量異常值,收入差距較大,需要進行處理
2. 按教育分開繪製
# 按教育分開繪製 full_data.boxplot(column='ApplicantIncome', by = 'Education') plt.suptitle("") # 可以看到受教育的人,有很多的高收入,出現異常值。
3. 貸款額度分析
# 貸款額度分析 plt.figure(1) plt.subplot(121) df=full_data.dropna() sns.distplot(df['LoanAmount']); plt.subplot(122) full_data['LoanAmount'].plot.box(figsize=(16,5)) plt.show() # 貸款額度數呈現正態分佈, # 但是從箱線圖中看到出現很多的異常值,下面需要進行處理異常值。
4. 處理缺失值
# 查看有多少缺失值 full_data.isnull().sum() # Gender,Married,Dependents,Self_Employed,LoanAmount, # Loan_Amount_Term和Credit_History 功能中缺少值
5. 填充缺失的值的方法:
# 填充缺失的值的方法: # 對於數值變量:使用均值或中位數進行插補 # 對於分類變量:使用常見衆數進行插補,這裏主要使用衆數進行插補空值 full_data['Gender'].fillna(full_data['Gender'].value_counts().idxmax(), inplace=True) full_data['Married'].fillna(full_data['Married'].value_counts().idxmax(), inplace=True) full_data['Dependents'].fillna(full_data['Dependents'].value_counts().idxmax(), inplace=True) full_data['Self_Employed'].fillna(full_data['Self_Employed'].value_counts().idxmax(), inplace=True) full_data["LoanAmount"].fillna(full_data["LoanAmount"].mean(skipna=True), inplace=True) full_data['Loan_Amount_Term'].fillna(full_data['Loan_Amount_Term'].value_counts().idxmax(), inplace=True) full_data['Credit_History'].fillna(full_data['Credit_History'].value_counts().idxmax(), inplace=True) # 查看是否存在缺失值 full_data.info() # 可以看到數據集中已填充所有缺失值,沒有缺失值存在。
6. 異常值處理
1 Winsorizing 這種方法把值(0.05,0.95)外的值使用這個區間的最小或最大值代替。
2 去除法 使用IQR或者其他方法檢測異常值後,直接去除
3 變換法 使用 log 變換,改變原來變量的分佈。
# 對於異常值需要進行處理, # 這裏採用對數log轉化處理,消除異常值的影響,讓數據迴歸正態分佈 full_data['LoanAmount_log'] = np.log(full_data['LoanAmount']) full_data['LoanAmount_log'].hist(bins=20)
full_data['ApplicantIncomeLog'] = np.log(full_data['ApplicantIncome']) full_data['ApplicantIncomeLog'].hist(bins=20)
這之間 還可以做一些 特徵工程的,由於這特徵個數比較少 但是 還是可以做一些 , 像還款日期30,60,90 ... 360,可以按月 分段離散化數據等
- 五、構建模型(邏輯迴歸模型)
# Loan_ID變量對貸款狀態沒有影響,需要刪除更改 full_data = full_data.drop('Loan_ID',axis=1) # 刪除目標變量Loan_Status,並將它保存在另一個數據集中 # 劃分 變量 和 目標 X = full_data.drop('Loan_Status',1) y = full_data.Loan_Status X=pd.get_dummies(X) full_data=pd.get_dummies(full_data) full_data.head()
Gender Married Dependents Education Self_Employed ApplicantIncome CoapplicantIncome LoanAmount Loan_Amount_Term Credit_History Property_Area LoanAmount_log ApplicantIncomeLog Loan_Status_N Loan_Status_Y 0 1.0 0.0 0.0 1 0.0 5849 0.0 146.412162 360.0 1.0 1 4.986426 8.674026 0 1 1 1.0 1.0 1.0 1 0.0 4583 1508.0 128.000000 360.0 1.0 2 4.852030 8.430109 1 0 2 1.0 1.0 0.0 1 1.0 3000 0.0 66.000000 360.0 1.0 1 4.189655 8.006368 0 1 3 1.0 1.0 0.0 0 0.0 2583 2358.0 120.000000 360.0 1.0 1 4.787492 7.856707 0 1 4 1.0 0.0 0.0 1 0.0 6000 0.0 141.000000 360.0 1.0 1 4.948760 8.699515 0 1 5 1.0 1.0 2.0 1 1.0 5417 4196.0 267.000000 360.0 1.0 1 5.587249 8.597297 0 1 6 1.0 1.0 0.0 0 0.0 2333 1516.0 95.000000 360.0 1.0 1 4.553877 7.754910 0 1
數據準備好以後 可以搭建模型
# 導入導入train_test_split
from sklearn.model_selection import train_test_split
#建立訓練集合測試集
x_train, x_cv, y_train, y_cv = train_test_split(X,y, test_size =0.3)
# 從sklearn導入LogisticRegression和accuracy_score並擬合邏輯迴歸模型
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
# 創建模型邏輯迴歸和訓練模型
model = LogisticRegression()
model.fit(x_train, y_train)
# LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
# intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,
# penalty='l2', random_state=None, solver='liblinear', tol=0.0001,
# verbose=0, warm_start=False)
最後 評估模型
# 評估模型
pred_cv = model.predict(x_cv)
accuracy_score(y_cv,pred_cv)
# 預測幾乎達到80%準確,說明正確識別80%的貸款狀態
# 0.8216216216216217
這算是完成最後一步了,後面還可以進一步操作,在時間處理的時候還可以進行一些特徵工程,會讓模型預測的效果更好,在搭建模型的時候,也可以選擇一些複雜的模型或多種模型來進行預測並求取他們的平均值作爲結果,可以說後面用到的模型融合會的到的效果更好,在模型搭建好後還需要選擇相對最好的參數,會更逼近上限值。