Kaggle竞赛焦虑缓解指南:在Shake-Up竞赛中的生存技巧
盲目追求LB会错失最后的蛋糕~
前言
这篇文章分享了一些在Kaggle竞赛中的技巧与建议,以帮助应对Kaggle竞赛的"shake-up"(即分数变动)并在私有排行榜上获得更好成绩。
数据泄露
在开始讨论对 Kaggle 比赛有帮助的技术之前,我们先谈谈数据泄漏。数据泄漏或简称泄漏会导致模型过于乐观,甚至完全错误的预测结果。这种情况发生在模型学习到了不该看到的信息(如验证数据),使得交叉验证变得不可靠。而你肯定不想让管道中最重要的部分失去作用。Kaggle 参赛者使用外部数据时,常常会遇到泄漏问题。
人们通常会将泄漏理解为“数据泄漏”,但在比赛中,特别要小心我称之为“模型泄漏”的情况。为了避免在交叉验证中的数据泄漏:
- 始终确保删除重复数据。
- 绝不要在验证集中包含外部数据。
模型泄漏更难察觉,其本质上与数据泄漏相关。模型泄漏发生在使用预训练模型来帮助迁移学习时。为了避免交叉验证中的模型泄漏:
- 检查预训练模型的训练数据,确保其中不包含相似度极高甚至相同的数据。
对抗性验证
对抗验证是一种简单却巧妙的方法,用于确定训练集和测试集的特征分布是否相似。这个方法其实是一个二分类问题的直接应用:
- 去除训练集的目标列。
- 在训练集和测试集中新增一个目标列,将其分别标记为0和1。
- 合并两个数据集并将其打乱。
- 训练一个二分类器并记录评价指标。
我们其实是在训练一个模型,以预测某个样本是来自训练集还是测试集。此任务的指标通常是 ROC AUC(接收者操作特征曲线下面积)。如果这个模型得分很高,则说明训练集和测试集的特征分布是可分的且不同,这并非我们希望的结果。我们希望对抗验证模型的得分接近0.5,以确保交叉验证方案的可靠性。
折外预测
交叉验证不仅是一种强大的验证策略,它还有另一个优势——折外预测(Out-of-Fold Predictions,OOF)。
折外预测是一种样本外预测,它基于未被用于训练的数据。具体而言,对于每个k-1训练折,我们都会得到一个验证折的预测集。如此一来,最终能为整个训练集提供样本外预测!这些折外预测不仅可以用于估计模型,还可以用于堆叠(stacking)。
在上一篇文章中,我提到了使用留出集的缺点,留出集会因数据划分和训练数据规模而导致模型偏差。我们通过交叉验证解决了这个问题,而通过其副产物——折外预测,我们可以使用所有数据,从而实现更好的集成。
集成学习
假设你想买一部新手机,但不确定如何选择,于是你向朋友们咨询并综合他们的建议。聚合的答案可能比单独听一家科技商店的建议要好。这种简单的思路(使用弱学习器)是集成学习的核心,也是现今最强大的技术之一。随机森林和梯度提升等算法正是基于类似的逻辑,但本文将不详细讨论这两种算法。我们关心的是堆叠或混合,这取决于你的验证策略(OOF 用于堆叠,Hold-out 用于混合)。我们继续讨论这一点。
混合和堆叠
为理解这些技术的直觉,让我们从一个简单的例子开始。假设我们已经为比赛训练了几个效果不错的模型,使用了不同的算法和超参数等。我们可以选择验证得分最高的模型来预测测试数据,但我们有多个多样性良好且得分相似的模型,不妨把它们都利用起来!最简单的形式是对每个模型的测试集预测进行平均。通常,这样的简单方法比使用单一最佳模型更能取得更好的结果。

简单模型混合
让我们进一步改进这种聚合方法。首先,将训练数据的部分数据作为“留出集”,然后在剩余数据上训练模型。训练后,使用训练好的模型对留出集进行预测。假设我们在训练数据上训练了10个不同的模型,因此我们有10个对留出集的预测。可以将这些预测视为元特征,用于训练一个元学习器。在混合的第二层,我们使用这些留出预测作为特征,将真实标签作为目标,来训练元学习器。最终,我们就构建了两层的预测器——一层多样化模型训练于实际训练数据,另一层元学习器以上一层的预测作为输入来训练。在推理阶段,这个网络会为每个测试实例预测10个特征,然后元学习器使用这些特征做最终预测。实际上,只要计算力允许,你可以增加层数,但要避免过拟合和泄漏。
你可以使用不同类型的元学习器:
- 一个简单的线性回归或逻辑回归模型,通过前一层的预测来学习做预测。
- 使用 Optuna 等优化框架。你可以使用有指导的聚合方法,通过 Optuna 优化每个模型的权重,然后使用权重加权的预测进行最终提交。
CV的重要性
- 交叉验证 (CV) 的重要性:好的CV是成功的一半。如果我找不到一种评估模型的好方法,就不会进行下一步。
- 构建稳定的CV:需要充分了解数据及其挑战。我会确保验证集的分布与训练集和测试集相似,并尽量让模型在本地CV和公共排行榜 (LB) 上都有所提升。在时间序列类竞赛中,我会将特定时间段的数据单独作为验证集。
- 谨慎的最终提交选择:我通常采取保守策略,选择我“安全”模型的加权平均集成,并选择一个相对激进的模型 (我认为参数越多风险越大)。即便某个提交的公共LB得分很高,我也不会选择我无法解释的提交。
竞赛中最受青睐的算法
在选择机器学习算法时,根据具体情况进行调整是明智的策略。使用岭回归作为集成算法的一部分是一种不错的选择,因为它通常能够在简单性和效果之间取得平衡。此外,从 ResNet-50 或类似结构开始的深度学习竞赛,可以提供一个稳定的起点,并且易于在复杂任务上进行扩展。这种方法既保留了性能,又简化了调试过程。
公共排行榜的诱惑:坚持住!
根据我的经验,很难抗拒提高公共排行榜得分的诱惑。Kaggle 比赛通常持续数月,你自然想向世界展示你的进展。权衡什么对你更重要:暂时的成就感还是持久的成功?要实现后者,你必须保持耐心,收获将更加满足。
在 Jigsaw 比赛中,我的公共排行榜得分超过了80.0(比赛使用了一个自定义指标,范围在0到100)。大多数参赛者都超过了90.0,几乎接近满分,因此我在比赛的大部分时间里,公共排名都在1700名左右。幸运的是,主办方与参赛者分享了以下信息:
在拥有此信息和合理的交叉验证方案(在上一篇文章中讨论过)之后,我确信公共排行榜在此处是无效的。


公共排行榜的意义何在?
它仍然是一个重要的指标,但不应被高估。跟踪公共排行榜有几个好处。首先,它可以判断你是否走在正确的轨道上,为你的进展提供基准。它还可以确认交叉验证中使用的指标是否与主办方的评估指标一致,因为相同的指标会被用于私有排行榜。知道你在测量什么总是有益的。
一些 Kaggle 用户将公共排行榜视为额外的验证折,当他们计算 CV 时,会将公共排行榜得分加入聚合得分中。这种方法虽然合理,但我更倾向于将公共排行榜作为指导灯塔,而不是最终目标。所以通常,我会寻找我的模型的交叉验证分数与公共排行榜之间的正相关性。如果在一些情况下得到证实,我会更专注于提升我的 CV 得分,而不是公共排行榜得分。
Jigsaw比赛的实际案例
回到我在 Jigsaw 比赛中的情况:在比赛的最后一个月,我的排名在1600–1700名之间。在整个比赛中,我根本没有接近过奖牌区。尽管如此,我还是坚守住了,不去过拟合公共测试集,尽管这样做可以让我的排名更靠前。最终,我得到了这种做法的回报:
在私有测试集(占整个测试集的95%)得分后,我几乎提高了1700个名次,几乎进入金牌区。尽管有些遗憾,以微小的分差与金牌擦肩而过,但我很高兴我信任了自己的 CV,得到了回报!
结论
在本系列中,我介绍了一些有助于在 Kaggle 比赛中取得更好成绩的技巧。更好的是,这些技巧不限于比赛,你可以轻松地将它们应用到实际任务中!这正是我最喜欢 Kaggle 比赛的地方,你在其中获得的经验将更有可能遇到于实际工作。排名波动可能让人清醒,但也充满回报。
原文链接及参考
Profiling Top Kagglers: Bestfitting, Currently #1 in the World
Kaggle Handbook: Tips & Tricks To Survive a Kaggle Shake-up