第五名解决方案(完整撰写)
(注意:我在第一天分享了一份 撰写报告,但并未尝试涵盖所有内容。我觉得使用 Kaggle 为获奖者提供的模板公开分享我的文档撰写报告会更好。)
A. 模型摘要
A1. 关于你/你的团队的背景
A3. 摘要
- 使用的模型类型:手工调优的 LGB,使用 AutoGluon 和公开 Notebook 参数的 CatBoost,基于公开 Notebook 手工调优的 TabM,来自公开资源的 ODST Pairwise NN,以及直接使用 AutoGluon(主要包含 XGBoost 和一些相当简单的 NN 模型)。
- 使用了 42 个模型:
- 20 个 Catboost (11 个 AG, 2 个公开 Notebook, 7 个个人变体)
- 13 个 LightGBM (7 个 AG, 5 个手工调优,1 个公开 Notebook)
- 4 个 XGBoost (4 个 AG)
- 3 个 TabM (3 个基于公开 Notebook 起点手工调优)
- 1 个 NN (1 个 AG)
- 1 个 ODST Pairwise NN (1 个公开 Notebook)
- 最终 Kaggle Notebook: https://www.kaggle.com/code/roberthatch/cibmtr-5th-place-official-submission
- 使用的目标变量:
- 我使用了 A 和 B 模型拆分,这对所有前 7 名以上的竞争者都非常成功。我的公式版本如下:
P = (a * b) - ((1 - a) * (S_RATIO))
- A 是预测 'efs' 标签的自定义变体。B 是仅针对 efs==1 情况预测 'efs_time' 排名的自定义变体。
- 此外,我针对超过 1000 种 NelsonAalen 目标变量的变体进行了 3d 网格搜索。变量包括:按百分比减少 efs==0 情况的目标,
t[efs==0] *= y。另一个是随后通过固定值 shifting 目标,t[efs==0] -= x。最后第三个变量是减少 efs==0 情况的样本权重。表现最好的目标和集成目标随后针对所有模型类型进行了训练。
- 使用的特征工程:
- GBDT:重新计算 HLA 总和,但制作
hla_nmlp_6_new 并且不要替换原始的 hla_nmlp_6 特征。
- NNs:移除除
hla_nmlp_6 之外的所有 hla_6 和 hla_8 总和。
- NNs:强制除 2 个特征外的所有特征为类别型。
- 对 2 个数值年龄特征进行舍入。
- 在我自己的测试中拒绝了许多特征。但为了多样性,有时会在我的大型集成中包含带有原始特征工程的公开 Notebook。
- 最终精简后的模型训练大约需要 6 小时 GPU 和 14 小时 CPU。然而,这实际上是一个更大的多阶段“集成选择”的一部分,其中包括 1780 个 LGB 模型、数百个 AutoGluon 模型,以及针对我使用的主要 6+ 目标的相当多的 TabM 和 Catboost 模型。因此,可以说大约有 15 小时 GPU 和 60 小时 CPU 的模型被输入到完整集成中以选择最终模型,这还不包括所做的许多其他实验和调优。
A4. 特征选择/工程
- 最重要的特征是目标变量。
- 目标变量:
- 主要目标是 A 和 B,见下文。
P = (a * b) - ((1 - a) * (S_RATIO))
S_RATIO 是一个常数 (~0.42456), simply 平衡了 b=1.0(风险最高的条目)与 b=0.5(平均风险 efs==1)与平均 efs==0 的相对值,就预期的一致性 wins 和 losses 而言。因此,它是从训练数据的分布和一致性指标公式的性质数学推导出来的。
- 对于变量 'a',我没有直接预测 efs==1(相对于 efs==0)的机会,而是预测 efs_time 低于“转折点”的机会,此时训练数据中处于该点“错误”一侧的行数最少。该数据集的此值为
EFS_SPLIT = 13.326。对于这个分类器,如果 efs==0 且 efs_time < EFS_SPLIT,我移除(删失)了它们。这仍然留下了大约 28600 行 (99%)。如果有更多时间,我更喜欢针对更标准的 efs==1 训练所有模型,如果该集成的训练 CV 显示有改进,则在最终集成中使用两者。
- 同样,对于变量 'b',我仅使用 efs==1 且
efs_time < EFS_SPLIT,并转换为均匀分布的 0.03 到 0.97。然后取该值的 logit 并针对该值训练 RMSE 回归器。LGB 能够持续改进数千次迭代。不寻常的是,我在训练中使用 efs==0 观测值,但 sample_weight=0,这不知何故似乎有助于模型分组。LGB 对此目标特别擅长。公开 LB 分数低于预期,因此担心过拟合。然而,这最终被证明是一种错觉,LGB 有可能被进一步推动以准确预测排名。像 'a' 一样,如果有更多时间,训练一个更传统的跨所有 efs==1 的排名预测器可能会有帮助,包括 efs_time 高于 EFS_SPLIT 转折点的 2%。
- 除了主要目标外,训练一组多样的 1d 目标作为 2d 'efs' 和 'efs_time' 的代理也很有帮助。关键见解:
- 使用 NelsonAalen,
1-cumulative_hazard 是一个很好的起点,并且始终未修改地使用,对于 efs==1 数据点 sample_weight = 1。对于 efs==0,问题是如何 shift 数据以更好地预测真实风险 OR 更好地与其他目标和模型变体集成。作为起点,我没有设置 sample_weight = 1,而是将 sample_weight 设置为 cumulative_hazard 值。因此,非常早期的删失事件将获得非常低的权重。为了进一步细化 efs==0,我使用的三个维度是:
- 目标的固定 shift (X),如公开 Notebook 中所示。增加分离度以更好地区分 efs==0。
- 乘数 (Y) aka 目标的百分比。直觉是,如果 efs==0 后来以与总体人群分布相等的可能性变为 efs==1,则目标的 50% 将是平均分数。
Sample_weight (WM) 通过乘数进一步降低, aka 原始样本权重的百分比。
- 最后,最有帮助的是两个处于相反极端的目标,一个将所有 efs==0 压缩在一起并 shift 得离 efs==1 超级远,但 efs==0 仍然具有低样本权重,因此它可以学习 efs==1 排名,但由于巨大的差距,仍然强烈强调 efs==0。与一个根本没有 shift efs==0 目标,仅减少其权重的目标作为平等集成配对。它们是
x=0, y=1.0, WM=0.35 和 x=1.0, y=0.1, WM=0.4。
- 另一个出乎意料有效的配对是
X=0.7, y=0.6, WM=0.15(并且 WM=0.1 也很好),不知何故,这是与 ODST Pairwise NN 公开 Notebook 配对的最佳单一目标。
- 还使用了 Andrew 公开 Notebook 中的 Cox Loss。我做的唯一更改是后处理更改。我使用原始分数集成所有模型,我不集成它们的排名。由于我使用原始模型分数,与我获取此模型的公开 Notebook 不同,重要的是我注意到我使用的 Cox Loss 模型的预测是 logit 形式。一旦我使用 "expit" 函数从 logit 转换为概率,它的集成效果要好得多。
- ODST pairwise Notebook 直接使用一致性分数,因此是另一个直接使用 efs 和 efs_time 作为标签的模型。
- 对于竞赛重点,我不 closely 查看特征选择或特征重要性,除了查看其他人的公开 EDA Notebook。模型最好在不发生过拟合的情况下自我优化。如果基于特征选择或重要性做出决策,可能会发生过拟合。可解释性不是我的重点。
- 你是如何选择特征的?
- 我避免选择(即移除),这对基于 GBDT 的模型没有帮助。添加可以是好的,但对于这个具有小数据和合成数据的竞赛,这不是我的重点,也没有人在论坛或公开 Notebook 中报告超过最小的成功。
- 你是否进行了任何重要的特征转换?
- 并没有真的。Hla_recalculate 和舍入可能略有帮助。
- 对于舍入,我将显然不那么重要的捐赠者年龄舍入到最近的偶数年。直觉是,某人 60 岁与 30 岁可能很重要,但他们是 19 岁 2 个月还是 19 岁 7 个月,与数据集的整体噪声相比,差异太小了。目标是平衡“显然不重要”与“让模型弄清楚”。对于 HCT 时的年龄,我舍入到第一位小数,因此大约到最近的月份。同样,也许一个人多少个月大可能很重要,但绝不可能重要的是 person A 是否比 person B 早出生 3 天。这显然是一个无关紧要的细节。
A5. 训练方法
- 你使用了什么训练方法?
- 手工调优的 LGB
- 来自公开超参数的 Catboost,以及对我自己的模型只是稍微手工调整超参数
- 基于公开 Notebook 的 TabM,然后花费了大量时间更新和调优。我使用了带热重启的余弦学习率 (Cosine LR with Warm Restarts) 和增加周期(如原始论文建议,T=10 且每次重启加倍)。
也许因为模型在后期轮次有很多随机变化和噪声,并且“受启发于”原始 Notebook 意外没有早停工作的奇怪高公开 LB 分数,并且因为热重启论文建议使用此 LR 方法时早停不是必要的,我尝试了有和没有早停,最终没有使用早停,而是运行固定数量的轮次。
- 优点:CV 不会因为挑选“最佳”随机变化而膨胀。不同的折对于 OOF CV 和测试预测混合得更好,它们可能更相似,因为训练轮次相同。如果变化主要是噪声,可能会避免过拟合 CV。
- 缺点:可能比挑选最佳轮次稍微不那么优化,特别是如果后期轮次由于正常过训练导致过拟合而分数更差。
- ODST Pairwise NN:
- 虽然我尝试了很多事情,但我坚持使用相同的基本模型和不同的种子。选择不同的种子是为了减少疯狂的过拟合(更高的 CV,更低的 LB),但我也推测模型某些运行 genuinely“聪明”,而其他时候“未能找到好的最优值”,所以挑选幸运的种子可能 (?) 比不幸的种子 plain 更好。所以我平衡了对过拟合 LB 甚至可能过拟合 CV 的恐惧(因为我 took 了一个好的 CV 和单次折叠上第二好的 LB),与如果我取更平均的种子或 3 次运行的平均,可能会减少它在公开 LB 上聪明的某种方式,这可能转化为私有 LB 的恐惧。所以我不一定认为这是最好的,但我想通过对冲保持在公开 LB 上强劲。
- 该模型使用 SWA (Stochastic Weight Averaging),这与公开 Notebook 的"checkpoint"有奇怪的交互。如果你从 checkpoint 加载权重,似乎你完全失去了 SWA(我想?)。所以它最终成为另一个模型,我训练它固定数量的轮次,没有早停。不过在这个模型上,你然后通过 SWA 获得最后 15 个轮次的混合。
- 向 TabM 添加 SWA 可能会通过微小但显著的边际改善它。使用 TabM 接口,实现它可能 trivial 也可能不 trivial。SWA 示例使用的是 PyTorch Lightning,而 TabM 有很多自己的样板代码,所以将 TabM 移植到 PyTorch Lightning 看起来一点也不 trivial,而且我面前没有关于在不使用 PyTorch Lightning 在后台完成所有工作的情况下进行 SWA 的代码示例。
- AutoGluon v1.1.1 带有 150 个 zeroshot 模型/超参数预设。
- 我在 5 个折的每个折上针对 6 个不同的目标训练了 112 个(如果仅 CPU 训练,则跳过 NNs)或 150 个 AutoGluon 模型。我还针对目标 A 运行了目标编码。(以及针对其他目标的目标编码模型运行,但这是在最后一天,由于未知的管道问题,用完了提交次数,放弃了测试将这些额外模型添加到集成中)。
- 我没有使用 AutoGluon 内置逻辑的 stacking 或集成,我自己做了集成。
- 你是否集成了模型?
- 是的,我使用了我自己的贪婪集成选择 (GES) 变体,基于且非常类似于 AutoGluon 的内部集成技术。它可能比其他集成技术稍微弱一点,但可以减少最终集成中的模型数量,并且开箱即用更不易过拟合,所以当我像在这次竞赛中故意添加数千个模型时,它非常有效。
- 该技术不仅用于我构建的 50+ 模型和数百个 AutoGluon 模型,以削减到最终解决方案中的最终模型集。而且还用于 1780 个 LGB 模型,具有相同的 LGB 模型和相同的特征,只是不同的目标和样本权重,以选择最佳目标。
- 我有 3 种模型类型:A、B 和 normal。A 和 B 我使用 logit 预测分别集成,只有在两者都集成后,我才将预测从 logits 转换,然后应用公式以获得真正的 AB 预测。Normal 预测是第三个单独的集成。在 normal 预测集成完成后,我将它与 AB 预测集成,以获得集成之集成的最终权重。
- 如果你进行了集成,你是如何加权不同模型的?
- 使用 GES 方法加权是取最佳模型权重=1,然后检查每个可能的添加也权重=1(所以 50/50%)并取最佳,然后继续。我使用训练验证拆分,并在验证分数停止改进时早停。我决定竞赛指标太噪声了,并使用所有数据的一致性指数作为优化的指标。使用种族组 drastically 减少了总配对对,并且标准差可以说主要由不可约噪声控制。所以简单的一致性指数分数是我在整个竞赛中信任的,并在许多情况下用于早停。
A6. 有趣的发现
- 除了首先使用 A + B 目标,这是整个前 5 名的黄金技巧,后处理那些 A 和 B 预测是我最终分数的关键。
- 首先,当我记得并花时间时——而且对于这个拆分预测案例似乎非常重要——我坚信尽可能长时间地保持预测为 logits,并平均和集成 logit 值而不是预测。这更 closely 匹配 GBDT 模型如何进行自己的内部加法集成,并且是一个数学上吸引人的方法。
- 所以对于后处理,我发现出于某种原因,乘以和/或添加到 logits A 和/或 B 中的一个或两个 greatly 增加了 CV 分数。但它没有增加公开 LB 分数,所以对于我的最终提交,一个没有后处理,另一个对 A 和 B 都有保守的 1.5 乘法,对 A 只有 0.25 +/- additive boost 远离 0。这可能有助于模型更好地排名和强调 LOCAL 一致性相对配对风险,因为全局配对分数对于相邻预测不重要,理想的情况是当且仅当较低数据点更可能是 head-to-head 更高风险赢家时,交换相邻预测,无论哪一个更可能赢得或失去最多的 GLOBAL 配对排名。
- 知道公开 LB 不是超级可信,而 CV 最终对每个人都非常可信,这至少可以比我使用的保守值进一步通过 CV 优化推动一点。
A7. 简单特征和方法
- 简单集成:
- Catboost 对 A 最重要,LGB 对 B 最重要。
- 有一个非常有效的 4 模型集成:
- Catboost + TabM 用于 A
- LGB + Catboost 用于 B
- 后处理 (2.0 置信度)
- 仅凭这些,这 4 个模型得分为 0.69812,在完整 42 模型最终集成得分 0.69881 的 99.9% 以内。
A8. 模型执行时间
- 训练你的模型需要多长时间?
- 42 个模型需要 20 小时(6 GPU, 14 CPU)。如果包括集成选择模型的所有输入,大约 75 小时。
- 使用你的模型生成预测需要多长时间?
- 提交管道可能需要 45 分钟,但有些时间是用于 Yunbase 中的目标编码和我自己的目标编码。
- 训练简化模型(参考 A6 节)需要多长时间?
- 从简化模型生成预测需要多长时间?
A9. 参考文献
- 论文:
- 贪婪集成选择 (Greedy Ensemble Selection):
- CARUANA, Rich, NICULESCU-MIZIL, Alexandru, CREW, Geoff, et al. Ensemble selection from libraries of models. In: Proceedings of the twenty-first international conference on Machine learning. ACM, 2004. p. 18.
- TabM:
- TabM: Advancing Tabular Deep Learning with Parameter-Efficient Ensembling
Y Gorishniy, A Kotelnikov, A Babenko
arXiv preprint arXiv:2410.24210