0
雷锋网 AI 科技评论按:Kaggle Home Credit Default Risk 比赛日前落下帷幕,该比赛总奖金 7 万美元,第一名奖金 35000 美元,第二名奖金 25000 美元,第三名奖金 10000 美元。该竞赛从 2018 年 5 月 17 日持续到 2018 年 8 月 29 日,共吸引到 7198 支参赛队伍,竞争异常激烈。由 Michael Jahrer 担任队长的 Home Aloan 队获得第一名。
比赛介绍
许多人由于较少甚至没有使用过信用卡消费,因而很难获得贷款,而且这类群体往往又被不值得信赖的借款人利用。Home Credit 希望为没有银行账户的群体提供正当且安全的贷款服务,为了判断这类群体的贷款是否正当合理,Home Credit 利用不同来源的数据(电话和交易记录等)来预测这些人的偿债能力。基于以上原因,Home Credit 在 Kaggle 上发起了一场贷款偿债能力预测的比赛,并提供了丰富的数据。
此次比赛的评测指标采用的是 AUC,要求参赛人员或队伍对测试集的每个 SK_ID_CURR 预测 TARGET(偿清贷款)的概率并以文件形式提交到 Kaggle 平台。
冠军团队成员之一 Bojan Tunguz 在 Kaggle 上发表了这支团队的具体方案,以下是雷锋 AI 科技评论对这一方案的编译整理。
比赛冠军队伍方案
引言
根据我之前信用担保的经验,不得不承认这个问题是应用机器学习领域中最复杂的问题之一。这个领域的数据一般非常混杂,比如数据是在不同时间段上收集的,来自不同途径,且可能在收集数据的过程中发生改变。此外,找到一个合适的目标变量也很棘手,需要深厚的专业知识和高超的商业分析能力。
插一句,Home Credit 和 Kaggle 提供的这个数据集非常赞,既不会泄露用户隐私,且易于进行机器学习。
基于对信用担保的了解,通常来说,很显然,这种类型的机器学习问题要构建一个很好的比赛模型。有两种重要思路:1. 一个很好的特征集合; 2. 不同的基线算法。我们主要有四个充满多样性的数据来源,以及少量的次要特征数据来源。
数据和特征工程
我们使用的第一个比较大的特征集合是在许多 kernel 中找到的。这些特征在多对一的表格上采用不同形式聚合,另外还有申请贷款次数特征。我们一共使用了大约 700 个特征。
特征工程
跟许多人一样,对于每个 SK_ID_CURR,我们只是基于 SK_ID_PREV 和 SK_ID_BUREAU 的特征建立基础模型,另外,我们还基于除法和减法从 application_train.csv 构造了许多特征。效果最显著的除法操作是除以 EXT_SOURCE_3,这对我们的 CV(本地做交叉验证得到的分数)有一个小的提升,也带来了榜单排名的提升。我们还发现通过为类别变量使用类别编码器可以获得相当不错的提升,我对 application_train.csv 中所有的类别变量建立了类别编码器,也对 previous_appplication.csv 表中 LAST application 中的所有类别变量建立了类别编码器。除了聚合 SK_ID_PREV 和 SK_ID_BUREAU,我还使用了数据的不同部分来计算聚合特征。
Previous_application.csv 聚合了最近的 3、5 次和起初的 2、4 次申请信息。这些申请中的每个变量都有交叉验证过,使 CV 分数获得了最大的提升。Installment_payments.csv 聚合了最近的 2、3、5 次的偿还贷款信息。我对 NUM_INSTALLMENT_NUMER 上的 1、2、3、4 次分期进行了聚合,对从 DAYS_INSTALLMENT 中过滤出来的最近 60、90、180 和 365 天的分期做了聚合,还对所有逾期付款的分期做了聚合。如果 ENTRY_PAYMENT 的值比 DAYS_INSTALMENT 大,逾期变量就被定义为 1,否则就定义为 0。POS_CASH_balance.csv, credit_card_balance.csv 与 installment_payments.csv 采用了同样的方法进行特征聚合。我还使用了来自 previous_application.csv 的 lag 特征,对于每个 SK_IDCURR,当达到了最近 5 次申请时我就使用 lag 特征。
Oliver:我是这样设想的,大部分竞赛选手知道我的特征和数据集。除了 public kernel,我试着计算年利率,这一特征对模型的影响非常明显,是促进模型获得高分的特征之一。我还试过在一些表(问询表和之前的申请表)上进行预测,但是因为某些原因,我们的模型没有像其他团队那样得到提升。随着其他特征工程经验丰富的队员加入,给我们的 CV/LB 带来极大提升,我就专注于模型融合了。
Phil:我做出来的特征按照重要性(基于对 LGBM 模型带来的提升)由高到低排序如下:
1)neighbors_target_mean_500
2)Region_id
3)debt_credit_ratio_None
4)credit_annuity_ratio
5)prev_PRODUCT_COMBINATION
6)DAYS_CREDIT_mean
7)credit_goods_price_ratio
8)last_active_DAYS_CREDIT
9)credit_downpayment
10)AGE_INT
11)installment_payment_ratio_1000_mean_mean
12)annuity_to_max_installment_ratio
Yang:我对特殊特征的想法是,一些来自于公开的讨论方案,包括过去 3、5、10 次信用卡贷款申请、分期付款时间和 pos 机使用记录,但是我修改了时间段以便在特征上引入更大的差异性。同时,我应用了加权平均(使用时间段作为权重)来生成一些跟养老金、信用卡和付款相关的特征。我认为这些特征对提取个人的信用卡习惯非常有帮助。我想到的最后一个有趣且有用的特征是:根据收入、付款和时间生成一些 KPI。
Bojan:特征选择和压缩
这次比赛也需要进行特征压缩。各种各样的特征生成方式通常会导致特征集合达到上千个,同时很可能大多数特征是冗余的、有噪声的或既冗余又含有噪声。
我试了一些简单的缩减特征数量的方法,使用数值类型的频率编码分类特征,然后使用岭回归跑了一个非常简单的前向特征选择。我过去在元特征(metafeatures)上使用过这个技术,但这是我第一次试着在原始特征上使用该方法。令人惊讶的是,这一技术非常凑效。
我能够将超过 1600 个原始特征压缩到大约 240 个。然后当 Oliver 添加更多的特征到 base set 时,我只是直接将这些特征加到 240 个特征中,最后达到 287 个特征。用这 287 个特征训练,CV 分数大约为 0.7985,LB 分数大约为 0.802 - 0.803。
当又有新的成员加入队伍,试着将他们提供的特征跟我们的特征结合就变得尤为重要。Oliver 花了很大的精力来区分 Phil 的哪个特征与我们的特征是互补的,最后合并的特征集合达到了 700 多个。当 Ryan 和 Yang 加入我们队伍时,再重复那样的工作太花时间和精力了,我们只是粗略对比哪部分特征是不同的,然后将那些不同的特征加入他们的特征集。
最后,Yang 的 base set 是所有特征集中最好的。他的一个 Kernel 就能在 private leadboard 上获得 0.802 的分数,public leadboard 上获得 0.803 的分数,这在最后阶段是前 20 名。我们想要将所有其他特征集合中的特殊特征与 Yang 的 base 特征集合组合,但由于时间关系我们就大概做了一下。我们最终共留下 1800-2000 个特征。我们有一些合并集,在训练自己的模型时,我们也分别进行了特征组合。
基础模型
我们的所有模型都是采用 5 折交叉验证。我一开始就这样选择了,没有什么特别原因,最后也把这个作为默认值。
Oliver:我使用了 LightGBM,FastRGF,尝试过 FFM,但是 CV 结果比预期低很多(0.76AUC)。
Bojan:我使用了 XGBoost,LightGBM,CatBoost,还有简单的回归模型。我在 XGB 上使用了一个超参数集合,在 LightGBMs 上使用了大约三个不同的集合。大部分 XGB 模型都是在 GPU 上使用 gpu_hist 训练的,而 LightGBM 模型是在 CPU 上训练的。CatBoost 模型没有那么好,训练需要很久,我认为他们对元特征的多样性只起到一点点帮助。
Ryan 和 Yang:我们在工程数据集和工程数据集与剩下数据集的组合数据集上训练了几个 LightGBM 模型。Ryan 抱着碰运气的心态试了试 FFM,但是效果不好。
Michael Jahrer(神经网络等方面):和大多数人一样,我阅读了论坛中的许多讨论,神经网络模型从 AUC 方面来说效果不比集成类的树模型(LGBM,XGB)好。在比赛过程中,使用神经网络的话,一开始根本就达不到 0.785,但使用 LGBM 却可以超过 0.79。当准确率达到一定程度之后,神经网络是模型融合的热门之选,我尽力去做好。特征工程不是我的长项,一开始我做得很差。队伍合并后我就可以用到大家的特征集合,效果显著。所有数据集上的结果都差不多,DAE+NN 效果比只用 NN 要好(差不多高 0.005)。DAE 表示降噪自编码处理,是神经网络的输入,是为了实现更好的数据表达的无监督技术。原始特征的数量在 100 - 5000 之间,这意味着 DAE 需要非常大,确保表征是过约束的、没有完全占满的。最初尝试的几个 DAE 模型都具有 10000-10000-10000 的拓扑,这意味着把特征的数量扩增到 3 万。监督式神经网络的拓扑为 1000-1000,这是我的标准建议,在这里也能正常使用。在试了更多神经元之后,得分反而下降了。
以下是一些参数设定:
DAE:swapnoise=0.2,1000 个 epoch。监督式神经网络:lRate=2.5e-5,dropout=0.5,大约 50 个 epoch(直到过拟合),优化对数损失函数。隐藏单元使用 ReLU,SGD 优化器,minibatchsize=128,小 lRateDecay。完全跑完一次 5 折交叉验证需要在 GTX 1080Ti 上花一整天,DAE 所占的时间最多。用 rankGauss 将原始数据归一化,缺失值用 0 代替。在竞赛后期,我在 DAE 中试着减少以及增加隐藏层数目,我认为这样会更好。在这种情况下得分最高:DAE 只包括一个隐藏层,具有 5 万个神经元 ,然后接上一个 1000-1000 拓扑的监督式神经网络,在我们 6 个人的所有特征集合的并集上跑了下,分数是 CV=0.794961,public=0.80059,private=0.79433。
当不对神经网络进行优化时,一个简单的带有较小学习率的 LGBM 模型优于所有神经网络模型。LGBM 模型获得的最高 CV 分数是 0.8039,AUC 比神经网络大概高 0.01。我认为神经网络在此扮演了次要角色。我认为神经网络在这里的得分比 LGBM 差的原因是数据归一化问题,但在最后为了 0.0001 的提升,神经网络还是非常重要,这就是 Kaggle。
模型集成
我们的模型集成共分为三个阶段。
每天,当我们得到一个新的基线预测,就生成 L1 稠密矩阵,并输入到第一层 stacker(NN,XGBoost,LightGBM 和 Hill Climber 线性模型)中。我们最后实现了 90 多个基线预测。随着基线预测数量的增长,选手排行榜的排名和 CV 分数变得越来越相关。我认为 Michael 的神经网络虽然在单独使用时表现没有很好,但是对 CV 分数和选手排行榜的排名之间的关系更加稳定有很大助益。
在一段时间之后,CV 分数及排名的提升变缓,很显然,进入了下一阶段。
第 2 层模型包括一个卷积神经网络,一个 ExtraTree 和一个 Hill Climber 线性模型。这时 Silogram 建议我们应该先添加原始特征再堆叠模型。
最后的预测是将 3 个预测做平均权重融合。
Michael:我们的神经网络模型是一个成功的 stacker。这里我使用了普通的监督式神经网络,带有一个隐藏层,500 个 ReLU 单元。这里的技巧是找到合理的初始值:lRate=1e-3,lRateDecay=0.96(在每个 epoch 之后乘以 Irate)。dropout=0.3 也很重要。
Phil:ExtraTrees L3 模型是一个非常浅层的模型(max_depth=4),仅仅在 7 个 L2 模型中加上一个原始特征 AMT_INCOME_TOTAL,高度正则化 (min_samples_leaf=1000) 。得分为 CV:0.80665,LB:80842,PB:80565。
其他
如上描述,我们没有在调参上投入太多时间。我试着在 XGB 参数和 LightGBM 模型上运行 Oliver 提供的一个优化脚本,但是本地结果让人沮丧。那时候我们一直非常依赖模型集成,我们的想法是在不同的超参数上训练几个不同的模型,避免生成单个高度优化的模型。
Phil 发现了一件事情,我在论坛上也看到有人提过,有可能在训练集和测试集上把预测结果调到超过 0.98 AUC。我们在最后才发现这点,当时已经不能用到了。(一些人确信排名靠前的某些队伍实际上在探索某种对抗验证和伪标签的方法)。
我们还尝试过开发一个预测模型来分辨 EXT_* 特征起到多大的作用,那些特征的 AUC 达到 0.78,但是它对提升 CV 和公开 LB 榜的排名都毫无助益。基于我们的分析,我们相信可能是因为这些特征在训练集和测试集中比较一致,所以虽然公开排行榜上的分数高于本地 CV 模型的分数,但它在其中起到的作用并不大。
竞赛结束后,我仔细看了我们的基础模型。结果证明,我们最好的 3 个模型都能排到前 10 名,把他们平均起来也能达到第一名。在我看来,这说明了在这种类型的竞赛和问题中,特征工程和特征选择是最重要的。因为我们没有对最好的特征集合进行优化,也没有调节训练模型的超参数,我认为创造出一个能超过我们之前所有模型集成效果的单模型也是很有可能的。
via:Kaggle,雷锋网 AI 科技评论编译整理。
雷锋网
雷峰网版权文章,未经授权禁止转载。详情见转载须知。