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
这算是完成最后一步了,后面还可以进一步操作,在时间处理的时候还可以进行一些特征工程,会让模型预测的效果更好,在搭建模型的时候,也可以选择一些复杂的模型或多种模型来进行预测并求取他们的平均值作为结果,可以说后面用到的模型融合会的到的效果更好,在模型搭建好后还需要选择相对最好的参数,会更逼近上限值。