一、购房贷款违约预测
1.1 实验题目:购房贷款违约预测
任务:使用机器学习相关知识完成购房贷款违约预测,给定特征字段,输出是否会发生逾期的预测。
1.2 实验要求
1.2 题目背景
随着世界经济的蓬勃发展和中国改革开放的逐渐深入,无论是企业的发展还是从人们消费观念的转变,贷款已经成为企业和个人解决经济问题的一种重要方式。随着银行各种贷款业务的推出和人们日益膨胀的需求,不良贷款也就是贷款违约的概率也随之激增。为了避免贷款违约,银行等金融机构在发放贷款时会对借款人的信用风险进行评估或打分,预测贷款违约的概率并根据结果做出是否发放贷款的判断。如何在发放贷款前有效的评价和识别借款人潜在的违约风险,是金融机构信用风险管理的基础和重要环节,用一套科学的模型和系统来判定贷款违约的风险性可以将风险最小化和利润最大化。
1.2 数据集
数据集在…/dataset 目录下,train.csv 为训练集数据,包含 120000 条数据,每条数据除去 id 和结果共有 50 个特征。test.csv 为预测集数据,包含 30000 条数据等待预测。
1.2 任务描述
本任务研究如何借助非平衡数据分类的思想对银行等金融机构的购房贷款数据进行分析,并基于随机森林分类模型预测贷款违约的可能性。
1.2 评测标准
采用 F1 score 指标,正样本为 1,
计算方法参考 https://en.wikipedia.org/wiki/F1_score
1.3 算法设计
1.3 数据处理
载入.csv 文件后,使用.describe 方法显示数据特征,并输出到文件中,保存位置为"…/dataset/tmp.csv"。该文件记录了数据的最大最小值、均值、中位数以及数据样本以百分比出现的值等信息,如图 1 所示。
图 1 数据信息类型
观察信息,可知本次数据集的数据较为分散且稀疏,数据中某一类(多数类)的数据远远超过另一类(少数类)的数据,为非平衡数据且填充值 0 数量庞大,计划采用人为地构造缺失值并填充的方式将数据中的 0 进行替换,如 3.1.1 所示。此外,在分析数据时发现了 inf 数据,inf 数据在模型预测过程中由于无精确取值将报错,对 inf 数据的处理如 3.1.2 所示。
在选取训练特征时,首先观察 tmp.csv 文件,找到误差很大的项,如仅有 10% 的数据有不为 0 的取值等。而后借助 matplotlib 画图等分析工具,对所有项的取值分布和相应取值下违约率的显示与分析,选择对预测影响较小的项进行去除。以对年龄分析举例,如 3.1.3。对其他项的分析举例,如 3.1.4。
1.3 人为设置缺失值并处理
人为设置缺失值并处理的基本思想为得到数据的行列数据后,使用随机生成的随机因子和想要认为设置缺失值数量的比例将数据中相应随机位置的值置为 NaN,而后使用 Imputer 方法,将 NaN 数据根据本人设置为相应的取值,此程序中设置为平均值。值得注意的是,由于观察得数据比例在 50% 的值为 0 的项较多,所以此时采用中位数填充并不合适。
1.3 inf 数据的处理
通过观察 tmp.csv 文件,得到 inf 数据出现的列,使用 replace 方法将 inf 数值设置为该列的中位数,从而完成对 inf 数据的处理。
1.3 age 项的数据分析
首先使用 matplotlib.pyplot 工具分别绘出 age 数据中已偿还贷款和未偿还贷款人数的 KDE 图并显示在同一图上,如图 2 所示,代码实现如图 3 所示。
图 2 人数密度的年龄
图 3 求 KDE 的代码实现
观察图 2 可得,数据集中的年龄数据在 20-30 岁这个区间上较多,且在此区间上,未偿还贷款的人数比已偿还的人数多,初步猜测模型与 age 有强相关关系。
而后继续使用绘图工具,此时着重关注未偿还贷款的数据。在 age 的 20-70 的区间上,划分长度为 5 的小区间,计算出区间上未偿还人数占总人数的比例,如图 4 所示,代码实现如图 5 所示。
图 5 未偿还贷款的年龄分布
图 6 求年龄分布的代码实现
观察图 5 可知,在普遍的人群中,年龄较低的未偿还贷款的人数比例占比较大且随着年龄增长,该比例逐渐降低。由此可得 age 与贷款偿还有相关关系,应保留该项。
1.3 其他项数据特征分析举例
同样使用 matplotlib.pyplot 工具绘制,绘制出取值的数量和相应取值未偿还贷款占该取值总人数的比例,如图 7 所示,代码实现如图 8 所示。值得注意到是,由于本数据集中许多数据的类型为浮点类型,此处绘制由于取值过多造成重叠,解决方法为对这些浮点数取小集合,使用集合的中位数代替处于这个小区间内的所有浮点数。
图 7 半年内申请贷款数量
图 8 特征数据分析绘制代码
以图 7 中半年内申请贷款数量为例,左图为半年内申请贷款个数量的人数分布,可见申请了 0 次的人数最多。右图为各申请次数下未偿还贷款的比例,由此可见,半年内申请贷款数量越多,其违规的规律则越大,两者大致呈现正相关关系,保留该项。
半年内申请贷款的数量仅为 50 项名录中的一项,本次特征寻取时对这 50 项数据分别绘制该表并观察,其余举例保存在…/pic 目录下得到有较强相关关系的项则保留,若观察到无关的项则去除。
1.3 特征选择的思考
在特征的构建时,有两种方式可以选择,一种为选择几个强相关特征重新构建数据集,另一种为在原数据集的基础上,保留强相关特征并去除某些对训练影响不大的特征。本实验选择后者,考虑在于本实验数据集表项较多,若采用前者进行特征工程,在单纯的绘制肉眼观察并不能很好的选择出最具有参考性的表象,在观察违约率图片时,许多特征的图表具有比较类似的特征,难以选取最优特征。若采用后者,在对 50 个特性进行观察时,去除肉眼可见的对模型无影响的特征即可,既减轻了工作量,又尽量不破坏原有的可能具有参考性的特征。
1.3 模型算法
数据集中数据为非平衡数据,且首尾差距较大,选择随机森林算法中的分类算法。
1.3 随机算林算法
随机森林算法直观理解,我认为是每棵决策树都是一个分类器,那么对于输入样本,N 棵树会有 N 个分类结果。而随机森林集成了所有的分类投票结果,将投票次数最多的类别指定为最终的输出。
每棵决策树的生成规则为:
1)如果训练集大小为 N,对于每棵树而言,随机且有放回地从训练集中的抽取 N 个训练样本,作为该树的训练集。每棵树的训练集都会有重复。若没有重复,则每棵树的训练集都是一样的且都是整个训练集,没有意义。
如果每个样本又 M 个特征,则指定一个常数 m<<M,随机地从 M 个特征中选取 m 个特征子集,每次树进行分裂时,从这 m 个特征中选择最优的。
每棵树都尽最大程度的生长,并且没有剪枝过程。
1.3 随机森林算法参数
在实验过程中,了解到的随机森林某些重要参数如下:
_estimators:数值型取值,森林中决策树的个数,实验过程中感受为该值与模型训练运算时间成指数相关关系,默认为 100,当输入为 1000 时,约需要等待 10 分钟左右。
min_samples_leaf:数值型取值,叶子节点上包含的样本最小值,一般为 50,若小于 50,则有可能受到噪声影响。
bootstrap:boolean 类型取值,为是否采用有放回式的抽样方式,若选择 False,感觉应该就不是标准的随机森林算法了。
oob_score:boolean 类型取值,为是否使用袋外样本来估计该模型大概的准确率。袋外样本即未参与该决策树训练的样本,采用袋外样本错误率来计算,可以完善一颗决策树对整个数据集的使用。
1.3 模型评估
1.3 gridSearchCV 网格搜索
在随机森林算法创建调整参数时,对于 max_features、min_samples_leaf 这两个参数总是琢磨不定。而后了解到 gridSearchCV 网格搜索的方式。感觉为类似自动测试方法,将想要搜索最佳参数的各个取值传入,并合理设置其他参数,即可自动运算得到最合适的参数。缺点在于网格化搜索耗费时间过长,我通过网格化搜索运行耗费了 3 天时间才得到合适的参数,实现网格搜索的代码如图 9 所示。
图 9 gridSearchCV 代码
1.3 评估标准
无自定义评估标准,采用 F1-score 在 educoder 相应模块进行测试。
1.3 模型融合
在本次实验中此模块并未使用多模型融合的训练方法,在确定使用随机森林算法之前,使用过感知机模型、SVM 支持向量机模型、KNN 算法模型等进行过训练。同样的训练集数据,在选择了较为合理的参数选择时,感知机模型、KNN 算法模型的 F1-score 均为 0.5 上下浮动,而在使用 SVM 支持向量机模型进行训练时,完全跑不出结果,程序运行时间太长了以至于崩溃。思考其原理,我认为是由于数据集 0 的取值数量过多,样本高维特征向量集中汇集在原点附近,而 SVM 算法是通过计算一条一条样本与超平面的关系得出 W 和 B 两个模型参数。而本实验中绝大多数的样本高维特征向量位置较为相近,在超平面的修正过程中,始终找不到满足样本集的取值。即使设置了宽松训练条件,也没有能完成超平面的取参操作。
1.4 实验环境与平台
实验环境为 AMD Ryzen 7 4800U with Radeon Graphics 1.80 GHz 16GB window 环境内存和华为云虚拟机 Ubuntu 环境。Python 版本为 3.7,使用 sklearn 库进行模型的选择与训练,matplotlib 库进行数据特性的绘图。软件为 pyCharm。
1.5 程序实现
该程序不仅实现了预测功能,在随机森林算法训练结束后,使用 feature_importances_函数输出各个特性对于模型重要性,如图 10 所示,以便于在使用模型预测之后自己进行人工预测以纠正相关结果。
图 10 特性重要性输出
在使用模型进行训练前,将训练集和测试集传入 StandardScaler()进行标准化操作,对于 F1-score 提升有好处。
1.6 实验结果
最新一次结果如图 11 所示:
图 11 实验结果
1.7 结果分析
测试结果中,F1-score 分数始终不高,最高一次仅仅取到了 0.587,而大多情况下在 0.56-0.58 之间浮动。浮动的原因为在数据处理中进行了人为的通过随机数的选取缺失值并处理。其他主流的机器学习模型在处理这样的非平衡数据时表现也不好,我想原因可能有因为 F1-score 评价公式为两倍的精确率与召回率之和除以精确率与召回率之和,而通过观察标签与直观感受,未贷款违约的概率远远高于贷款违约的概率,模型对于标签取 0,即未贷款违约的样本估计更加敏感,而对于正样本的预测较为迟钝,从而导致以正样本为主要评价的 F1-socre 较低。
还有原因是在数据清洗的过程中,缺乏过程控制,在清洗过程中没有合适的实时评价指标进行清洗方向的引导,导致数据清洗时凭借个人观察数据分布、个人数据分析等方式实行处理。对在各种清洗模式的尝试过程中,大部分的过程均很复杂且结果不如人意。
1.8 实验感受
本次大实验让我受益匪浅。首先是在对大数据集的清洗过程中,不断尝试,认识并学习了许多对数据进行清洗、划分的方法。枯燥的数据原来可以通过各种处理变成符合我们想要的重要数据,且他们形象的通过图表形式表现在面前时令我十分惊喜。其次在是对机器学习模型的探索与使用的过程中,第一次让我体会到了传说中“炼丹”是一种什么体验。每次模型都有自己适用的领域,要根据合适的数据集,综合考虑效率等方面选择合适的学习模型。