使用决策树,预测贷款申请

import pandas as pd
#  忽略弹出的warnings
import warnings
warnings.filterwarnings('ignore')
text=pd.read_excel('data/LoanStats_securev1_2019Q4.xlsx')
text.head()
id loan_amnt funded_amnt funded_amnt_inv term int_rate installment grade sub_grade emp_title ... num_tl_90g_dpd_24m num_tl_op_past_12m pct_tl_nvr_dlq percent_bc_gt_75 pub_rec_bankruptcies tax_liens tot_hi_cred_lim total_bal_ex_mort total_bc_limit total_il_high_credit_limit
0 164027473 20000 20000 20000 36 months 0.1240 668.12 B B4 NaN ... 0 2 100.0 50.0 1 0 60800 42566 5200 40000.0
1 163984413 16500 16500 16500 60 months 0.1033 353.27 B B1 NaN ... 0 0 100.0 0.0 0 0 223390 40913 40500 39890.0
2 164193225 7500 7500 7500 36 months 0.1240 250.55 B B4 Rn ... 0 7 54.5 16.7 0 0 138468 102122 47700 90768.0
3 162948736 19000 19000 18975 36 months 0.0646 581.99 A A1 Tech Ops Analyst ... 0 0 100.0 40.0 0 0 184034 28461 38400 35000.0
4 164161686 10000 10000 10000 36 months 0.2055 374.45 D D2 Planner ... 0 2 100.0 16.7 0 0 639373 161516 24600 172818.0

5 rows × 114 columns

目标变量

text['loan_status'].value_counts()
Current               122625
Fully Paid              3539
In Grace Period         1079
Late (31-120 days)       509
Late (16-30 days)        304
Charged Off               80
n                          1
Name: loan_status, dtype: int64
#0为已经完成的
def function(x):if 'Current' in x:return 0elif 'Fully Paid' in x:return 0else:return 1
text['loan_status']=text.apply(lambda x:function(x['loan_status']),axis=1)
text['loan_status'].value_counts()
0    126164
1      1973
Name: loan_status, dtype: int64
pos_trainDf = text[text['loan_status'] == 1]
neg_trainDf = text[text['loan_status'] == 0].sample(n=4000, random_state=2018)
text = pd.concat([pos_trainDf, neg_trainDf], axis=0).sample(frac=1.0,random_state=2018)
text.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 5973 entries, 18821 to 92872
Columns: 114 entries, id to total_il_high_credit_limit
dtypes: datetime64[ns](1), float64(36), int64(50), object(27)
memory usage: 5.2+ MB

缺失值查看

check_null = text.isnull().sum(axis=0).sort_values(ascending=False)/float(len(text)) #查看缺失值比例
print(check_null[check_null >0.2]) # 查看缺失比例大于20%的属性。
desc                              0.999833
mths_since_last_record            0.899046
verification_status_joint         0.880629
annual_inc_joint                  0.864055
dti_joint                         0.864055
mths_since_recent_bc_dlq          0.794408
mths_since_last_major_derog       0.769965
mths_since_recent_revol_delinq    0.703164
mths_since_last_delinq            0.548468
dtype: float64
thresh_count = len(text)*0.4 # 设定阀值
data = text.dropna(thresh=thresh_count, axis=1 ) #若某一列数据缺失的数量超过阀值就会被删除
data.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 5973 entries, 18821 to 92872
Columns: 106 entries, id to total_il_high_credit_limit
dtypes: datetime64[ns](1), float64(30), int64(50), object(25)
memory usage: 4.9+ MB

删除无意义的列

sub_grade:与Grade的信息重复

emp_title :缺失值较多,同时不能反映借款人收入或资产的真实情况

zip_code:地址邮编,邮编显示不全,没有意义

addr_state:申请地址所属州,不能反映借款人的偿债能力

last_credit_pull_d :LendingClub平台最近一个提供贷款的时间,没有意义

policy_code : 变量信息全为1

pymnt_plan 基本是n

title: title与purpose的信息重复,同时title的分类信息更加离散

next_pymnt_d : 下一个付款时间,没有意义

policy_code : 没有意义

collection_recovery_fee: 全为0,没有意义

earliest_cr_line : 记录的是借款人发生第一笔借款的时间

issue_d : 贷款发行时间,这里提前向模型泄露了信息

last_pymnt_d、collection_recovery_fee、last_pymnt_amnt: 预测贷款违约模型是贷款前的风险控制手段,这些贷后信息都会影响我们训练模型的效果,在此将这些信息删除

drop_list = ['sub_grade', 'emp_title',  'title', 'zip_code', 'addr_state', 'mths_since_last_delinq' ,'initial_list_status','title','issue_d','last_pymnt_d','last_pymnt_amnt','next_pymnt_d','last_credit_pull_d','policy_code','collection_recovery_fee', 'earliest_cr_line']
data.drop(drop_list, axis=1, inplace = True)
data.head()
id loan_amnt funded_amnt funded_amnt_inv term int_rate installment grade emp_length home_ownership ... num_tl_90g_dpd_24m num_tl_op_past_12m pct_tl_nvr_dlq percent_bc_gt_75 pub_rec_bankruptcies tax_liens tot_hi_cred_lim total_bal_ex_mort total_bc_limit total_il_high_credit_limit
18821 163425898 4500 4500 4500 36 months 0.1612 158.48 C NaN RENT ... 0 2 100.0 28.6 0 0 44700 10872 32800 0.0
61234 161908366 20000 20000 20000 60 months 0.2305 564.39 D NaN OWN ... 0 0 100.0 33.3 0 0 54349 19572 10400 22349.0
119781 159901427 10000 10000 10000 60 months 0.1862 257.32 D 6 years OWN ... 0 3 100.0 0.0 0 0 69077 48184 9600 49477.0
49201 162292591 21000 21000 21000 60 months 0.1430 491.91 C < 1 year RENT ... 0 0 100.0 0.0 0 0 109894 66662 33800 67194.0
53727 162154208 40000 40000 40000 60 months 0.0819 814.70 A 10+ years RENT ... 0 0 100.0 50.0 0 0 207370 160985 98000 61725.0

5 rows × 91 columns

分类变量

objectColumns = data.select_dtypes(include=["object"]).columns
data[objectColumns].isnull().sum().sort_values(ascending=False)
emp_length             572
application_type         1
url                      1
total_acc                0
delinq_2yrs              0
purpose                  0
pymnt_plan               0
verification_status      0
annual_inc               0
home_ownership           0
grade                    0
term                     0
dtype: int64
# data['int_rate'] = data['int_rate'].str.rstrip('%').astype('float')
# data['revol_util'] = data['revol_util'].str.rstrip('%').astype('float')
# data['annual_inc'] = data['annual_inc'].str.replace(",","").astype('float')
import numpy as np
objectColumns = data.select_dtypes(include=["object"]).columns # 筛选数据类型为object的数据
data[objectColumns] = data[objectColumns].fillna("Unknown") #以分类“Unknown”填充缺失值
import missingno as msno
import matplotlib as mpl
mpl.rcParams['font.sans-serif']=[u'simHei']
mpl.rcParams['axes.unicode_minus']=False
%matplotlib inline
msno.bar(data[objectColumns]) #可视化
<matplotlib.axes._subplots.AxesSubplot at 0x2cacc08aa20>

mapping_dict = {"emp_length": {"10+ years": 10,"9 years": 9,"8 years": 8,"7 years": 7,"6 years": 6,"5 years": 5,"4 years": 4,"3 years": 3,"2 years": 2,"1 year": 1,"< 1 year": 0,"n/a": 0},"grade":{"A": 1,"B": 2,"C": 3,"D": 4,"E": 5,"F": 6,"G": 7}
}
data = data.replace(mapping_dict) #变量映射

数值类型缺失值

data.select_dtypes(include=[np.number]).isnull().sum().sort_values(ascending=False)
il_util                  883
mths_since_recent_inq    655
mo_sin_old_il_acct       203
mths_since_rcnt_il       203
bc_util                  109...
total_cu_tl                0
inq_fi                     0
total_rev_hi_lim           0
total_bc_limit             0
id                         0
Length: 80, dtype: int64
numColumns = data.select_dtypes(include=[np.number]).columns
msno.matrix(data[numColumns]) #缺失值可视化
<matplotlib.axes._subplots.AxesSubplot at 0x2caecfe1160>

data.select_dtypes(include=[np.number])
id loan_amnt funded_amnt funded_amnt_inv int_rate installment grade loan_status dti fico_range_low ... num_tl_90g_dpd_24m num_tl_op_past_12m pct_tl_nvr_dlq percent_bc_gt_75 pub_rec_bankruptcies tax_liens tot_hi_cred_lim total_bal_ex_mort total_bc_limit total_il_high_credit_limit
18821 163425898 4500 4500 4500 0.1612 158.48 3 1 16.13 705 ... 0 2 100.0 28.6 0 0 44700 10872 32800 0.0
61234 161908366 20000 20000 20000 0.2305 564.39 4 0 34.14 735 ... 0 0 100.0 33.3 0 0 54349 19572 10400 22349.0
119781 159901427 10000 10000 10000 0.1862 257.32 4 0 27.84 680 ... 0 3 100.0 0.0 0 0 69077 48184 9600 49477.0
49201 162292591 21000 21000 21000 0.1430 491.91 3 1 21.82 740 ... 0 0 100.0 0.0 0 0 109894 66662 33800 67194.0
53727 162154208 40000 40000 40000 0.0819 814.70 1 0 27.52 700 ... 0 0 100.0 50.0 0 0 207370 160985 98000 61725.0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
86547 160719957 30000 30000 30000 0.0819 611.03 1 0 5.68 740 ... 0 2 100.0 40.0 0 0 361548 46148 94500 0.0
69734 161401437 16000 16000 16000 0.1430 549.18 3 1 13.73 660 ... 0 0 90.9 66.7 0 0 21300 15022 7800 6000.0
30947 162968064 1600 1600 1600 0.1102 52.40 2 0 17.32 715 ... 0 1 100.0 50.0 0 0 63659 41808 27200 30259.0
29039 163064608 10000 10000 10000 0.1240 334.06 2 0 22.91 680 ... 0 2 66.7 0.0 0 0 230024 36479 2900 60846.0
92872 160838177 23000 23000 23000 0.1774 580.81 3 1 0.00 800 ... 0 0 100.0 0.0 0 0 85255 0 600 0.0

5973 rows × 80 columns

data.isnull().sum().sum()
mean_cols=data.mean()
data= data.fillna(mean_cols)

目标变量

y=data['loan_status']
x=data.drop(['loan_status'],axis=1)
#使用pandas库将类别变量编码
x =pd.get_dummies(x)
n_sample = y.shape[0]
n_pos_sample = y[y == 0].shape[0]
n_neg_sample = y[y == 1].shape[0]
print('样本个数:{}; 正样本占{:.2%}; 负样本占{:.2%}'.format(n_sample,n_pos_sample / n_sample,n_neg_sample / n_sample))
print('特征维数:', x.shape[1])
样本个数:5973; 正样本占66.97%; 负样本占33.03%
特征维数: 7167

特征工程

#数据进行分割(训练数据和测试数据)
from sklearn.model_selection  import train_test_split#测试集和训练集
x_train1, x_test1, y_train1, y_test1 = train_test_split(x, y, train_size=0.8, random_state=14)
x_train, x_test, y_train, y_test = x_train1, x_test1, y_train1, y_test1
print ("训练数据集样本数目:%d, 测试数据集样本数目:%d" % (x_train.shape[0], x_test.shape[0]))
y_train = y_train.astype(np.int)
y_test = y_test.astype(np.int)
训练数据集样本数目:4778, 测试数据集样本数目:1195
#参数优化
from sklearn.pipeline import Pipeline #管道
from sklearn.model_selection import GridSearchCV #网格搜索交叉验证,用于选择最优的参数
from sklearn.preprocessing import MinMaxScaler
from sklearn.decomposition import PCA
pipes =Pipeline([('mms', MinMaxScaler()), ## 归一化操作('pca', PCA()), ## 降纬('RandomForestClassifier', RandomForestClassifier(criterion='gini'))])
# 参数
#
# estimators = [1,50,100,500]
# depth = [1,2,3,7,15]
parameters = [{"pca__n_components": [1,2,3,4],"RandomForestClassifier__n_estimators":[1,50,100,500],"RandomForestClassifier__max_depth":[1,2,3,7,15]}
]
#获取数据
x_train2, x_test2, y_train2, y_test2 = x_train1, x_test1, y_train1, y_test1
gscv = GridSearchCV(pipes, param_grid=parameters)
gscv.fit(x_train2, y_train2)
print ("score值:",gscv.best_score_,"最优参数列表:", gscv.best_params_)
score值: 0.6720405704396591 最优参数列表: {'RandomForestClassifier__max_depth': 7, 'RandomForestClassifier__n_estimators': 500, 'pca__n_components': 4}
#标准化
ss = MinMaxScaler()#分类模型,经常使用的是minmaxscaler归一化,回归模型经常用standardscaler
x_train = ss.fit_transform(x_train, y_train)
x_test = ss.transform(x_test)
x_train.shape
(4778, 7167)
#降维
from sklearn.decomposition import PCA
pca = PCA(n_components=4)
x_train = pca.fit_transform(x_train)
x_test = pca.transform(x_test)
x_train.shape
print(pca.explained_variance_ratio_)
[0.08187674 0.05705152 0.05380546 0.04683824]
#随机森林模型
from sklearn.ensemble import RandomForestClassifier
forest = RandomForestClassifier(n_estimators=2000, criterion='gini', max_depth=7, random_state=0)
forest.fit(x_train, y_train)#max_depth一般不宜设置过大,把每个模型作为一个弱分类器
RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None,criterion='gini', max_depth=7, max_features='auto',max_leaf_nodes=None, max_samples=None,min_impurity_decrease=0.0, min_impurity_split=None,min_samples_leaf=1, min_samples_split=2,min_weight_fraction_leaf=0.0, n_estimators=2000,n_jobs=None, oob_score=False, random_state=0, verbose=0,warm_start=False)
#模型效果评估
from sklearn import metrics
from sklearn.metrics import roc_curve, auc
score = forest.score(x_test, y_test)
print ("准确率:%.2f%%" % (score * 100))
#模型预测
y_score = forest.predict(x_test)# prodict_proba输出概率
准确率:66.78%
# Compute ROC curve and ROC area for each class
import matplotlib.pyplot as plt
fpr,tpr,threshold = roc_curve(y_test, y_score) ###计算真正率和假正率
roc_auc = auc(fpr,tpr) ###计算auc的值
print('auc:%.2f'%(roc_auc))
auc:0.51
plt.figure()
lw = 2
plt.figure(figsize=(10,10))
plt.plot(fpr, tpr, color='darkorange',lw=lw, label='ROC curve (area = %0.2f)' % roc_auc) ###假正率为横坐标,真正率为纵坐标做曲线
plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic example')
plt.legend(loc="lower right")
plt.show()
<Figure size 432x288 with 0 Axes>

决策树

#参数优化
from sklearn.tree import DecisionTreeClassifier
pipe = Pipeline([('mms', MinMaxScaler()),('pca', PCA()),('decision', DecisionTreeClassifier(random_state=0))])# 参数
parameters = {"pca__n_components": [0.5,0.99],#设置为浮点数代表主成分方差所占最小比例的阈值"decision__criterion": ["gini", "entropy"],"decision__max_depth": [1,2,3,4,5,6,7,8,9,10]
}
#数据
x_train2, x_test2, y_train2, y_test2 = x_train1, x_test1, y_train1, y_test1
#模型构建:通过网格交叉验证,寻找最优参数列表, param_grid可选参数列表,cv:进行几折交叉验证
gscv = GridSearchCV(pipe, param_grid=parameters,cv=3)
#模型训练
gscv.fit(x_train2, y_train2)
#算法的最优解
print("最优参数列表:", gscv.best_params_)
print("score值:",gscv.best_score_)
最优参数列表: {'decision__criterion': 'gini', 'decision__max_depth': 4, 'pca__n_components': 0.99}
score值: 0.6917121178186392
#降维
from sklearn.decomposition import PCA
pca = PCA(n_components= 0.99)
x_train = pca.fit_transform(x_train)
x_test = pca.transform(x_test)
x_train.shape
print(pca.explained_variance_ratio_)
[0.34176263 0.23813938 0.22458996 0.19550803]
tree = DecisionTreeClassifier(criterion='gini', max_depth=4)
tree.fit(x_train, y_train) # fit模型训练
# 模型相关的指标输出
# print("训练集上的准确率:%.3f" % tree.score(x_train, y_train))
y_hat = tree.predict(x_test) # 获取预测值
print("准确率:%.3f" % (np.mean(y_hat == y_test)))
准确率:0.671
# Compute ROC curve and ROC area for each class
import matplotlib.pyplot as plt
fpr,tpr,threshold = roc_curve(y_test, y_hat) ###计算真正率和假正率
roc_auc = auc(fpr,tpr) ###计算auc的值
print('auc:%.2f'%(roc_auc))
auc:0.51
plt.figure()
lw = 2
plt.figure(figsize=(10,10))
plt.plot(fpr, tpr, color='darkorange',lw=lw, label='ROC curve (area = %0.2f)' % roc_auc) ###假正率为横坐标,真正率为纵坐标做曲线
plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic example')
plt.legend(loc="lower right")
plt.show()
<Figure size 432x288 with 0 Axes>

20200317_决策树预测贷款申请相关推荐

  1. Spark 数据挖掘 - 利用决策树预测森林覆盖类型

    Spark 数据挖掘-利用决策树预测森林覆盖类型 1 前言 预测问题记住一点:最垃圾的预测就是使用平均值,如果你的预测连比直接给出平均值效果都要差,那就省省吧! 统计学诞生一个多世纪之后,随着现在机器 ...

  2. 基于京东手机销售数据用回归决策树预测价格

    今天给大家推荐一个数据分析与挖掘的实战项目案例"基于京东手机销售数据用回归决策树预测价格".该项目先基于京东手机销售数据做出一系列分析后,利用回归决策树仅根据手机外部特征进行价格预 ...

  3. 【2016年第1期】基于大数据的小麦蚜虫发生程度决策树预测分类模型

    张晴晴,刘勇,牟少敏,温孚江 山东农业大学农业大数据研究中心,山东 泰安 271018 摘要:小麦蚜虫是危害小麦的主要害虫.其发生程度预测特别是短期预测一直是植物保护领域难以解决的科学问题.传统预测方 ...

  4. 【阅读笔记】使用决策树预测泰坦尼克号幸存者实例 - scikit-learn机器学习

    文章目录 使用决策树预测泰坦尼克号幸存者实例 一.数据获取 二.数据探索 数据质量分析(缺失值.异常值.一致性) 三.数据预处理 四.数据建模 五.优化模型参数 使用决策树预测泰坦尼克号幸存者实例 代 ...

  5. 徒手写代码之《机器学习实战》-----决策树算法(2)(使用决策树预测隐形眼镜类型)

    使用决策树预测隐形眼镜类型 说明: 将数据集文件 'lenses.txt' 放在当前文件夹 from math import log import operator 熵的定义 "" ...

  6. 03_使用决策树预测隐形眼镜类型

    使用决策树预测隐形眼镜类型 1.实验描述 使用Python编程,输入为隐形眼镜数据集,计算所有可能的特征的信息增益,选择最优的特征值划分数据集,进而递归地构建决策树.其中为了更加直观地呈现决策树,使用 ...

  7. 决策树(四):使用决策树预测隐形眼镜类型

    使用决策树预测隐形眼镜类型 介绍 代码部分 总结 介绍 本节我们将通过一个例子讲解决策树如何预测患者需要佩戴的隐形眼镜类型.使用小数据集 ,我们就可以利用决策树学到很多知识:眼科医生是如何判断患者需要 ...

  8. Educoder 机器学习 决策树使用之使用决策树预测隐形眼镜类型

    任务描述 相关知识 如何处理隐形眼镜数据集 编程要求 测试说明 任务描述 本关任务:编写一个例子讲解决策树如何预测患者需要佩戴的隐形眼镜类型.使用小数据集,我们就可以利用决策树学到很多知识:眼科医生是 ...

  9. 《python数据挖掘入门与实践》决策树预测nba数据集

    前言: 学到决策树预测球队输赢时,按照书中网址去下载数据集,无奈怎么也没下载成功.即使下载了excel文件也是破损的.咱可是学了python的银,那好吧,我就把它爬取下来.(资源在下面) 代码: '' ...

  10. 机器学习实战ch03: 使用决策树预测隐形眼镜类型

    决策树的一般流程 1.收集数据 2.准备数据:树构造算法只适用标称型数据,因此数据值型数据必须离散化 3.分析数据 4.训练算法 5.测试数据 6.使用算法 决策树的优点 1.数据形式非常容易理解 2 ...

最新文章

  1. c语言期末作业自己设计个小程序,帮看一个小程序吧,c语言期末考…求求各位大神了...
  2. Mongodb 自动增长 自增id 实现
  3. android打开相机拍照及打开相册选择照片
  4. BizTalk开发系列(二十九) 宏的使用
  5. 封装特效记录--持续更新
  6. Eclipse - Open Declaration
  7. eplan图纸怎么发给别人_如何保护你的EPLAN图纸
  8. 由于 Exception.tostring()失败,因此无法打印异常字符串
  9. 透明png图片和素材免费下载网站
  10. 调用快递鸟API查询物流
  11. win10 C盘右边是OEM分区扩容的解决办法
  12. hive: size与spilt连用
  13. python自动排课表_LeetCode 207. 课程表 | Python
  14. 第八章-数据处理的两个基本问题
  15. css3 text-shadow 浮雕、镂空、荧光效果
  16. 女生做软件测试工作怎么样?
  17. 从购买ECS到SpringCloud项目的自动化部署及发布
  18. SparkCore核心机制详解
  19. html div挤下去了,HTML的div相挤现象
  20. 【流媒体|从入门到出家】:流媒体协议—FLV

热门文章

  1. 简单的Jquery焦点图切换效果
  2. BZOJ4530:[BJOI2014]大融合
  3. HDU2206:IP的计算
  4. 交换排序—冒泡排序(Bubble Sort)
  5. oracle注意事项
  6. HTMLCSS 第五天 笔记
  7. 【leetcode】二分查找经典题目
  8. spark sql 的性能调优
  9. 模块化程序设计(多文件编程)介绍
  10. IIS7下访问ashx页面,显示404