概述

 

    本周是高级实训第一个项目的最后一周,根据上次课上讨论的内容进行了一些微调和改进,并结合前几次周报简要梳理了整个比赛的完成情况。

 

数据预处理

   

    首先需要对数据集中各个特征的意义、类型、取值分布有一个大致的了解,并对数据进行预处理,解决缺失、噪声、冗余、不一致等问题,使数据集能够更好地被模型利用。不同模型对这些数据集的缺陷的敏感度不同,其处理方式也可能有所不同。

高级实训第七周周报  高级实训第七周周报

上两图是训练集、测试集数据的概况,可以看到除n系列匿名特征外,缺失量并不是很大。对缺失数据的填充有很多种,对这个数据集,没有证据表明id相邻的数据条目有相关性,因此未使用相邻值填充的方法。特征类型可分为数值特征和类别特征,对类别类特征,可使用众数填充,这基于在不知道其他信息的情况下,一个缺失值的取值最可能是该特征出现频次最高的取值,而对连续数值类的特征,可采用平均值填充,可使误差(填充值与真实值的差)的期望达到最小。

特别地,对一些类型为int或float的特征,其取值数量较少,且多集中与0到10之间的整数(如n0等特征),我把它们当做类别特征处理:

高级实训第七周周报

对于连续值,取值的范围非常重要,且很多模型对范围的大小很敏感(特别是KNN、回归等基于距离和权重计算的模型),需要对噪声(显著的离群点进行检测和处理),并在必要时进行归一化。对正态分布,偏离均值3个标准差以上的点即可被认为是噪声,而事实上这些连续属性分布都与正态分布很不相同,导致采用这种方法检测有些特征会有50%的点以上被归为噪声,如果将偏离3个标准差的都归为等于3个标准差,将显著改变数据分布,从而破坏其蕴含的有效信息。此外,根据特征的实际意义,一些显著大于其他值的“噪声”是有其合理性的,比如有些人的年收入高于均值很多倍,这是符合常识的,且与其偿债能力有很大关系,如果简单地将其设定一个阈值(比如3个标准差内)可能反而对数据造成破坏。

    Log变换是一种常用的映射函数,它的单调性保证了不改变原有的大小关系,同时能有效控制取值区间大小,缓解模型过度偏向区间大的特征的问题。通过可视化工具,可以直观地对特征取值的分布有一个了解,对分布过于偏态的可进行变换。同时还可观察特征不同取值对应的违约率的分布,我们希望取不同值时违约率差异越大越好,这样该特征则具有较好的区分性(对决策树模型,选择该特征可获得较大熵增益)。比如信用评级grade的高低显著地反映了违约风险的大小:

高级实训第七周周报高级实训第七周周报

 

    最后,对一些类别(object)类特征,主要是时间序列,其重点在于相对的先后关系,单纯的字符串不能很好地反映该情况,因此转化为据现在的时间长度,即数值类特征。

特征工程

   

    本数据集的特征数较多,如果直接把填充后的所有特征加入特征集并训练,得到的结果会很不理想,因为各特征的关键程度大不相同,有些甚至会起负作用。特征工程部分的工作除了对一些特征做处理、转化使其更适与模型外,更多的是一个做减法的过程,即根据特征的取值分布及其与其他特征的关系筛选掉一些特征,得到一个更精简、有效的特征集。

    对于policyCode,其取值只有1个值,这样的特征显然无助于提升模型的区分能力(比如对决策树模型,其熵增益为0),因此予以舍弃。类似地,根据课上提到的一个经验原则,对95%以上集中于一个值的偏斜特征,也予以舍弃(如n11,n12等

经验证,subGrade中包含grade信息,即存在数据冗余,因此可舍弃grade,只用subGrade即可。并且此类信用评级的类别存在顺序或大小关系,例如A类肯定比C类好,这种情况下将其映射到从小到大的数字可有效反应单纯的类别编号无法表达的信息,我将A1到G5依次映射为1到35。

由于n系列匿名特征缺失量较大,且无法得知其对应的实际意义,我在一开始并未将其加入特征集。我最开始用的是KNN模型,使用上述特征集大约能跑到0.62左右,效果不算很理想。换用决策树模型并调参后有了较大提升,可达到约0.69(加入了n系列匿名特征),决策树模型能够根据最大化熵增益的原则自动选择有效的特征,效果好于直接在所有维度求距离的KNN,且运行速度非常快。此外,树模型可以量化地评估特征的重要性,可视化后可作为特征选择的一个很好的参考:

高级实训第七周周报

    基于上述优点,我后面主要使用基于树的模型,但树模型存在易过拟合且对特征有偏向性的缺陷,需要在模型的选择与调参上予以改进。

模型选择与调参

 

对单一决策树,最常用的调节参数包括最大深度、叶节点最小样本数、内部节点再划分最小样本数,通常情况下前者越小后两者越大越能控制过拟合,但也面临更高的欠拟合的风险,需要通过尝试来确定。

单一决策树通常深度小于10,只能利用到数据集中少部分特征,调节参数后仍很可能出现过拟合。为缓解该问题,可使用多颗决策树,并引入一定的随机性,综合所有树的结果,得到一个考虑更全面、泛化性能更佳的结果。随机森林就是上述思想对应的模型,也是Bagging方法(通过综合若干若分类器的结果得到一个强分类器)的一个特例(基分类器都是决策树)。除决策树的参数外,随机森林需要考虑的额外参数主要有基分类器数和随机状态。

    在这之后,结合课上提到的内容和论坛教程,我又尝试了XGBoost模型。XGBoost模型是GBDT(梯度提升决策树)的一种实现,它与随机森林的主要不同在于它给分类错误的样本更高的权重以进一步学习(即Boosting),此外它还引入了L2正则项和叶子节点权重,有利于降低模型方差并加快收敛速度。在我尝试的这些模型中,XGBoost经调参后的表现最好(以score评价),且运行速度相对较快,方便调试。

 

模型融合

 

在之前的讨论中了解到有些同学尝试了模型融合的方法,我阅读了相关教程,尝试了其中最简单的平均法,可考虑对不同模型得到的结果做平均,选取的模型相互越独立越好。但我使用过的有较好效果的基本都基于树模型,并且它们还存在一个没有解决的问题:特征选取的倾向性。在计算特征重要性时,可能取值数多的特征更容易被树模型选择,结合之前打印的特征重要性的柱状图,排名靠前的确实都是一些取值数较多的数值特征,而理论上应该很重要的信用评级subgrade只排在中间位置(由object类映射到数值类,仅35个取值)。因此我考虑分别用3组不重合的特征集分别用XGBoost做训练,根据取值数分组,最后对3次训练的结果取平均,以强制给予取值数少的那组特征更多的权重。然而最终发现3次训练的结果都比使用完整特征集略差,取平均值也没有明显提高。我自认为可能是这种方法同时放大了一些不太相干的特征的干扰,且某几种特征可能组合在一颗树里会有比较好的效果,而这种做法将它们强行拆散了。

 

小结

   

    我的最好结果如下图所示:

高级实训第七周周报

    实际上换用XGBoost模型并初步完成调参后的这一个多星期来,我的score基本进入了一个瓶颈期,尝试了很多组参数和特征集并对数据预处理做了微调后,从0.72左右提升到了0.726,再往上感觉非常困难了。上次讨论课上听到两位达到了0.73的同学使用的分别是lightGBM和神经网络模型,前者与XGBoost类似,都是GBDT的一种改进实现,而后者从原理上还是有较大不同的,我希望在后面布置的比赛中尝试一下,或许还可以与基于树的模型做一个融合,以达到更好的效果。当然XGBoost作为一个久经证明的模型,应该是可以达到0.73甚至更好的效果的,可能还是我在前期数据预处理和特征工程方面经验不足,这方面还要在后面慢慢学习、尝试。

相关文章: