基于机器学习与深度学习的金融风控贷款违约预测

Posted 上山打老虎D

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于机器学习与深度学习的金融风控贷款违约预测相关的知识,希望对你有一定的参考价值。

基于机器学习与深度学习的金融风控贷款违约预测

目录

一、赛题分析

1. 任务分析

2. 数据属性

3. 评价指标

4. 问题归类

5. 整体思路

二、数据可视化分析

1. 总体数据分析

2. 数值型数据分析

3. 非数值型数据分析

4. 多变量分布与相关性分析

三、数据清洗与特征工程

1. 数据清洗与特征构造

2. 数据分箱

3. 特征交叉

4. 选取特征

5. 数据持久化

四、模型选择并预测

1. 模型选择

2. 进行训练并融合

五、比赛结果

六、困难与解决

1. 使用GPU进行训练

2. 运行过程中报错semlock leak

3. 关于模型选择

4. 数值特征与类别特征

5. 避免过拟合

七、收获与心得


一、赛题分析

1. 任务分析

本次大作业选题为《零基础入门金融风控-贷款违约预测》。本题以金融风控中的个人信贷为背景,需要根据贷款申请人的数据信息预测其是否有违约的可能,并对违约的可能性进行预测。

2. 数据属性

本次赛题的任务为预测用户贷款是否违约。数据来自某信贷平台的贷款记录,总数据量超过120w,包含47列变量信息,其中15列为匿名变量。本次比赛从超过120w的数据中抽取80万条作为训练集,20万条作为测试集。此外,本次比赛中所有数据已经进行充分的脱敏处理。

本次比赛中,数据共含有47个字段,其中15列为匿名变量,其余为非匿名变量。各个变量名与描述对应关系如下:

①Id:为贷款清单分配的唯一信用证标识

②loanAmnt:贷款金额

③term:贷款年限

④interestRate:贷款利率

⑤installment:分期付款金额

⑥grade:贷款等级

⑦subGrade:贷款等级之子级

⑧employmentTitle:就业职称

⑨employmentLength:就业年限(年)

⑩homeOwnership:借款人在登记时提供的房屋所有权状况

⑪annualIncome:年收入

⑫verificationStatus:验证状态

⑬issueDate:贷款发放的月份

⑭purpose:借款人在贷款申请时的贷款用途类别

⑮postCode:借款人在贷款申请中提供的邮政编码的前3位数字

⑯regionCode:地区编码

⑰dti:债务收入比

⑱delinquency_2years:借款人过去2年信用档案中逾期30天以上的违约事件数

⑲ficoRangeLow:借款人在贷款发放时的fico所属的下限范围

⑳ficoRangeHigh:借款人在贷款发放时的fico所属的上限范围

㉑openAcc:借款人信用档案中未结信用额度的数量

㉒pubRec:贬损公共记录的数量

㉓pubRecBankruptcies:公开记录清除的数量

㉔revolBal:信贷周转余额合计

㉕revolUtil:循环额度利用率,或借款人使用的相对于所有可用循环信贷的信贷金额

㉖totalAcc:借款人信用档案中当前的信用额度总数

㉗initialListStatus:贷款的初始列表状态

㉘applicationType:表明贷款是个人申请还是与两个共同借款人的联合申请

㉙earliesCreditLine:借款人最早报告的信用额度开立的月份

㉚title:借款人提供的贷款名称

㉛policyCode:公开可用的策略_代码=1新产品不公开可用的策略_代码=2

3. 评价指标

       评价标准是衡量模型好坏的最终指标。本次比赛最后提交结果为对每条测试样本为1的概率,并采用AUC进行评价。

       AUC(Area Under Curve)即为ROC曲线下方面积,是二分类问题比较经典的评价指标,它表示随机抽取一个正样本和一个负样本,分类器正确给出正样本的score高于负样本的概率。

       ROC(Receiver Operating Characteristic Curve)曲线为接收者操作特征曲线,它以伪阳性率为横坐标,以真阳性率为纵坐标对模型的预测能力进行评价。二分类模型的阈值可能设定为高或低,每种阈值的设定会得出不同的 FPR 和 TPR ,将同一模型每个阈值的FPR和TPR 坐标都画在 ROC 空间里,就成为特定模型的ROC曲线。

       AUC的取值范围为0~1,越趋近于1,分类器的性能越好。

图 1:AUC示意图

4. 问题归类

       本次赛题要求对贷款申请人是否违约的可能性进行预测,因此是常见的分类问题(Classification Problem)。又因为对于每个贷款申请人,只有违约或不违约两种可能,因此,本赛题又是常见的二分类问题(Binary Classification Problem)。即将给定测试集分成两类,如下图。

图 2:二分类问题示意图

       对于此类二分类问题,可以使用机器学习或深度学习进行解决。若使用机器学习,常见的解决方法有逻辑回归(Logistic Regression),KNN最近邻算法(K - Nearest Neighbors),支持向量机(Support Vector Machine),朴素贝叶斯(Naive Bayes),梯度提升(Gradient Boosting)等等……若使用深度学习,可以通过构建神经网络模型对贷款的违约情况进行预测。

       针对以上多种方法,在完成特征工程后,我进行了多次尝试,并通过交叉验证,堆叠(Stacking)等方法对模型进行检验与融合。

5. 整体思路

       通过对题目的理解,本次大作业选题是比较经典的二分类问题《贷款违约预测》。本次比赛的数据量比较大,所有数据包括100W行47列。比较大的数据量对数据清洗与模型训练提出了挑战。

初步分析题目,贷款违约率是本赛题重点关注的概念。在我看来,影响贷款违约率的因素可以从用户个人属性、贷款属性两个维度出发。个人属性,不同用户的年收入、工作时间和个人信用等级等会影响用户对贷款的偿还能力。贷款属性,贷款利率、贷款的种类等也会影响贷款的偿还率。

基于本赛题特点和数据挖掘的工程思路,我将整个赛题的思路画成如下的思维导图,后续的工作以本图为指引进行。

图 3:流程图

二、数据可视化分析

1. 总体数据分析

首先,将训练集数据与测试集数据读入,并将测试集与训练集数据合并,以便于数据可视化分析。

图 4:读入训练集并合并

       首先查看合并后数据原始特征维度。

图 5:查看原始特征维度

       可以发现,一共有一百万条数据,其中八十万为训练数据,另外20万为测试数据。一共包含47个字段,每个字段的含义已经在上一部分给出。具体各个列名如下:

图 6:各个字段显示

       为了更好的进行数据分析以便对数据进行处理,需要查看数据类型。通过df.info()查看所有数据的数据类型。

图 7:数据类型一览

       可以看到,所有47个特征中,有42个数值型特征,5个非数值型特征。对于数值型特征,需要进一步分析以便特征工程,对于非数值型特征,需要转成数值型特征,以便模型处理。接下来,将对数据的缺失情况进行分析:

图 8:缺失值个数

图 9:缺失值统计图

       可以看到,47个特征中共有23个特征出现了缺失值的情况。并且,数据缺失的情况大都出现在匿名特征中。

图 10:缺失值零度矩阵

       通过查看缺失值零度矩阵,可以发现特征缺失出现了聚集情况,即存在某些数据中缺少多个特征值的情况。

      

图 11:唯一值特征

       由于特征一般都是由类别型特征和数值型特征组成,而数值型特征又分为连续型和离散型。类别型特征有时具有非数值关系,有时也具有数值关系。比如‘grade’中的等级ABC等,是否只是单纯的分类,还是A优于其他要具体进行判断。接下来,将对特征的类别进行判断,分成数值型特征与非数值型特征分别进行处理。

图 12:数值型特征

图 13:非数值型特征

2. 数值型数据分析

对于数值型特征,包括离散型变量和连续型变量。在此认为对于一个特征而言,如果其存在10个以上不同的值,则认为是连续型变量,否则认为是离散型变量。据此,划分出连续型变量和随机型变量如下:

图 14:连续型变量

图 15:离散型变量

      

对于离散型变量,可以对数据的分布及取值进行分析如下:

Term特征分析:

图 16:Term特征分析

homeOwnership特征分析:

图 17:homeOwnership特征分析

       VerificationStatus特征分析:

图 18 :VerificationStatus特征分析

initialListStatus特征分析:

图 19:initialListStatus特征分析

applicationType特征分析:

图 20:applicationType特征分析

policyCode特征分析:

图 21:policyCode特征分析

      

N11特征分析:

图 22 :N11特征分析

N12特征分析:

图 23:N12特征分析

       通过对离散型变量的分析,可以发现,一部分特征(applicationType,n11,n12)出现的比较明显的偏移现象,一部分取值占比超过99%,而其余比值不到1%,我们将在特征工程中对此变量进行处理。此外,policyCode特征只含有一个值,因此它不能被认为是一个可供学习研究的特征,而是一个常量,因此在特征处理时直接删掉即可。

       对于连续型变量,可视化其数据分布,以便更好的获取特征信息。

图 24:八个连续变量的数据分布图

图 25:二十四个连续变量的数据分布图

图 26:连续变量的数据分布图

       通过对上面连续变量数据分布的观察,不难发现,loanAmnt的分布与正态分布比较相近,为了在训练拟合时模型更快收敛,可以将其正态化,观察正态化后的数值分布。

图 27:loanAmnt数据特征

图 28:loanAmnt正态化后数值分布

3. 非数值型数据分析

       通过前面的分析,可以知道一共有如下5个非数值型数据。

图 29:5个非数值型特征

       接下来将对这些特征一一分析。Grade特征:

图 30:Grade特征

SubGrade特征:

图 31:SubGrade特征

       可以发现,Grade和SubGrade都是字符串格式的数据,并且通过进一步数据分析,可以发现,subGrade中第一个字母即为Grade中的字母,因此在数据清洗时可以考虑去掉Grade特征,并将SubGrade进行数值化。

       EmploymentLength特征:

图 32:EmploymentLength特征

       对于EmploymentLength特征,发现其中全为年限之类的字符,因此在数据清洗时可以直接去掉years并将其转换为整数,以便模型处理。

       IssueDate特征:

图 33:IssueDate特征

       IssueDate特征是时间格式的,它储存的时间范围是从2007年到2018年。

       earliesCreditLine特征:

图 34:earliesCreditLine特征

       earliesCreditLine特征也是时间格式的,但与上面IssueDate的时间格式不太一样,并且earliesCreditLine数据有很高的分散性,是高数量类别特征(high cardinality categorical attributes)。因此可以在数据清洗时对数据格式进行统一。

4. 多变量分布与相关性分析

       在此部分,将对各个变量特征的数据分布进行分析,以便后续完成数据清洗以及特征工程。employmentLength是一个比较重要的特征,将其数据分布可视化如下

图 35:employmentLength数据分布可视化

       此外,多个变量之间的综合分布情况也比较重要,可以根据一个不同特征来可视化另一个特征的交叉分布。

图 36:Grade和employmentLength对于isDefault的分布

上图为对于违约或不违约人的grade和employmentLength分布图。可以发现,他们employmentLength的分布大致相同,而Grade存在比较大的差别。不违约的人群中AB等级的占比要比违约人群中AB等级占比高很多。

图 37:LoanAmnt对于isDefault的分布

       上图为对于违约或不违约人的LoanAmnt的分布图。可以发现他们的LoanAmnt分布大致相同,但对于违约的人群他们的欠款数量更少。这不难理解,对于“老赖”,他们的信用等级更差,因此银行可能不会把比较多的钱借给他们;而及时还款的人群由于信用比较好,则会借比较多的钱。

图 38:违约人群与不违约人群对比图

       可以看到违约的人群要比不违约的人群少很多,不违约的人的数量大约是违约的人的数量的五倍左右。

图 39:特征热力图

图 40:斯皮尔曼等级相关系数图

热力图及相关系数图可以清晰的看到各个特征之间的相关性,从而更好的完成数据清洗。通过上方特征热力图,可以看出,几个匿名变量间都有比较高的相关性。此外,一些其他的特征间也都有比较高的相关性,如installment与loanAmnt,purpose与title,postCode与regionCode等等。

三、数据清洗与特征工程

       俗话说:“特征工程决定模型预测上限”。精准充分的特征工程是很重要的,结合上方数据分析,我完成了如下的特征工程。

1. 数据清洗与特征构造

       首先观察到Grade字段和SubGrade字段全为等级类字母,则直接通过替换将其换成数字以便模型处理。

图 41:Grade字段

图 42:SubGrade字段

图 43:清洗Grade字段和SubGrade字段

       同理,将employmentLength也处理为整型,去掉years并进行替换即可。

图 44:employmentLength字段

图 45:清洗employmentLength字段

       此外,将两个日期处理为整型,并构建以整数时间间隔的方式的新特征,以便模型学习。

图 46:日期格式的字段处理

       然后将dti字段的缺失值填入1000,并过滤掉非法负值。

图 47:dti字段处理

图 48:空值处理

       最后,为了降低特征数量,降低训练时特征维度以提高训练效率以及训练准确率,结合各个变量的实际意义。对于一部分特征,不将原值入摸,而利用比值关系构建新的特征,再将新特征入模。需要注意的是,由于部分特征存在空值或0值,因此不能直接做比,需要对数据加0.1处理。

图 49:构建新特征

2. 数据分箱

       通过数据分析,可以发现新构造出的特征为连续型变量,并且数量很多,为简化模型处理,提高对异常数据的鲁棒性,可以通过分箱将连续型数据转为离散型数据,从而大大提高模型处理速度。

       常用的数据分箱方法分无监督分箱和有监督分箱。本次选择比较容易实现的无监督分箱中的等距分箱法完成分箱操作。

       分箱的数量对最终学习结果有比较大的影响,通过数据分析以及实际测试可以得出比较好的分箱结果。annualIncome_bin和loanAmnt_bin两个特征分10个箱。将interestRate_bin,dti_bin,installment_bin,revolBal_bin,revolUtil_bin共五个特征分100个箱。

图 50:对七个特征进行分箱

3. 特征交叉

       为了更进一步提取特征,在此,我对几个比较有重要的特征(loanAmnt, installment, interestRate, annualIncome, dti, openAcc, revolBal, revolUtil, totalAcc)进行了特征交叉。由于本问题为金融类问题,通过查阅资料,金融类问题的特征数据在近期时间内的有效性比较高;而很长时间前的特征反应出的规律比较弱,不利于模型学习。因此,选择六个月内的数据进行交叉。此外,在交叉过程中,为了提升鲁棒性,我不选择使用原始数据进行交叉,而是选择使用中位数的均值编码进行交叉。通过实验对比,这大大提高了特征交叉的效果,提高了鲁棒性。

图 51:特征交叉

4. 选取特征

       经过数据清洗,特征构造,数据分箱以及特征交叉,我们已经获取了足够的特征,但现在数据量比较大,如果全部入模会导致运行时间很长,并且其中存在一些容易混淆的冗杂特征。因此需要选择合适的特征入模,而不将所有数据入模。

图 52:特征选择前原始数据大小

本赛题为风控模型的风险预测,在风控中,稳定性压倒一切。原因在于,一套风控模型正式上线运行后往往需要很久(通常一年以上)才会被替换下线。如果模型不稳定,意味着模型不可控,对于业务本身而言就是一种不确定性风险,直接影响决策的合理性。这是不可接受的。为此,通过查阅资料,引入了群体稳定性指标(Population Stability Index,PSI)对特征的稳定性进行衡量并取舍选择出合适的特征。PSI反映了验证样本在各分数段的分布与建模样本分布的稳定性。在建模中,我们常用来筛选特征变量、评估模型稳定性。

PSI可由如下公式求得:

在此,我们不对PSI进行过深入的了解,只需要知道他表示的含义即可。此处,我通过toad库,对PSI的结果进行计算并进行降序输出,具体结果如下:

图 53:经过数据清洗和特征构造后PSI指标排序图

       PSI越大,表明特征越不稳定,特征在训练集和测试集中的分布可能不太一致,我们就可以考虑将这样的特征从特征列表当中删除。因此利用PSI排序后,将PSI大于0.1的特征全部丢弃掉。

5. 数据持久化

       在写好代码进行数据清洗过程中,发现由于数据比较多,每次运行起来十分耗时。此外,由于训练将在计算服务器上进行,服务器的CPU主频一般较低,运行数据清洗代码将花费更长时间。因此考虑在PC机上完成全部数据处理与特征工程后,将模型导出为Pickle文件,存于硬盘,在训练时只需将Pickle文件拷贝到训练用计算服务器上即可。

图 54:训练数据持久化

四、模型选择并预测

1. 模型选择

经过数据分析,数据清洗以及模型构建,接下来将处理好的数据入模进行预测即可。为了使最后预测结果更好,通过查阅相关论文,我首先通过已经清洗好的数据,借助MLJAR的自动学习库(Automated Machine Learning)选择了Decision Tree,Extra Tree,Random Forest,XGBoost,Neural Network,LightGBM,CatBoost,Ensemble这几种可能完成本预测问题的经典模型算法,进行自动学习,确定选择模型的大方向。自动学习箱型图结果如下:

图 55:自动学习箱型图

通过图中观察,可以发现,XGBoost,LightGBM,Catboost三种基于Gradient Boosting的树模型有比较高的AUC,神经网络模型的AUC稍差,但神经网络预测结果的AUC分散度比较大,因此考虑使用XGBoost,LightGBM,Catboost三种模型结合k折交叉验证进行Stacking模型融合,并将输出的预测结果作为一个新的特征与之前的特征一起,作为神经网络模型的输入,并利用神经网络模型获得最终结果。(本处仅体现最优模型,实际上我使用很多模型进行了多次尝试,具体可见“六、困难与解决”部分)

图 56:模型预测流程图

2. 进行训练并融合

       训练过程分为如下几步:

首先,在训练集上采用算法XGBoost,LightGBM,Catboost训练出三个基学习器。然后,用这些基学习器的输出结果组成新的训练集,在其上训练一个元学习器(meta-classifier),用于组织利用基学习器的答案,也就是将基层模型的答案作为输入,让元学习器学习组织给基层模型的答案分配对应的权重。为了使训练过程更加准确,同时避免过拟合,我使用了五折交叉验证。

图 57:三个基学习器

图 58:5折Stacking进行模型融合

       完成Stacking后,将预测出的结果作为新的特征,与原特征一起进入神经网络模型进行预测。我定义了如下的网络,每层大小之比为300:64:32:8:1。

图 59:神经网络模型结构

       为了避免神经网络模型过拟合,我定义了学习率会随着epcho而减小,从而避免过拟合。

图 60:动态修改学习率

       待神经网络运行完成后,将结果以提交格式的csv文件保存到本地,并提交至比赛页面。

图 61:将结果保存至本地

五、比赛结果

       经过上一部分中对模型的选择以及多次提交尝试,我的最终线上得分为0.7491,排名3/9391,位次比0.03%

图 62:提交名次与成绩图

图 63:提交结果图

图 64:总Rank排行图

六、困难与解决

1. 使用GPU进行训练

       由于本次比赛的数据量比较大,模型训练过程耗时比较长,因此我选择了使用GPU服务器进行加速。我选择了学院提供的服务器来运行代码,服务器使用Intel(R) Xeon(R) Silver 4210R CPU @ 2.40GHz的CPU,Ubuntu20.04的系统并搭载两张Nvidia Tesla A100显卡。

       发现将代码直接移植到服务器上后不能正常运行,即虽然开启了GPU加速,但显示GPU的资源占用为0%,通过查阅资料,发现对于XGBoost和LightGBM这两种库模型,通过pip直接下载的版本是不能使用GPU加速的,若想使用GPU加速,需要下载CMAKE并自行编译。

图 65:在Linux上编译LightGBM的GPU版本

       安装完成后,即可以使用GPU对训练进行加速。(通过pip安装的Catboost库即包含了对GPU的支持,故不需自行编译)

使用迁移学习进行金融小样本风控实践(基于tradaboost进行个贷违约迁移学习比赛)

数据挖掘机器学习[六]---项目实战金融风控之贷款违约预测

零基础入门金融风控-贷款违约预测-机器学习-数据分析

实战案例:使用机器学习算法预测用户贷款是否违约?

数据挖掘实践(金融风控):金融风控之贷款违约预测挑战赛(下篇)[xgboots/lightgbm/Catboost等模型]--模型融合:stackingblending

使用迁移学习进行金融小样本风控实践 ---- 原理简介