返回列表

5th place: 100 OOFs, laziness, and a blunder or two

649. Playground Series - Season 5, Episode 4 | playground-series-s5e4

开始: 2025-04-01 结束: 2025-04-30 音视频处理 数据算法赛
第 5 名:100 个 OOF,一点懒惰,以及一两个失误

第 5 名:100 个 OOF,一点懒惰,以及一两个失误

作者: Optimistix (Master)
发布时间: 2025-05-01
竞赛排名: 第 5 名
竞赛: Playground Series S5E4

简而言之: 我的整体方法与大多数 Playground 系列比赛相同 - 例如参见 S4E9 的 Gather, Ridge, Repeat 帖子。我收集了 100 个 OOFs,专注于模型多样性,差点因为未对最后两个提交中的一个进行 clipping 而在排行榜上暴跌。我也有点懒,没有把很多想法付诸实践。尽管如此,这还是很有趣,尤其是在最后一周,我首先追逐并进入了前三名,但后来被 @greysky@stopwhispering 超越。

在详细介绍之前,我想感谢那些分享见解、发现和代码的人,包括但不限于

@greysky, @masayakawamata, @yekenot, @pirhosseinlou, @crisbebop, @act18l, @cdeotte, @siukeitin, @ravaghi@mikhailnaumov

第一阶段:热身 经过几个月不寻常的时间序列、近乎随机的数据以及非常少的数据之后,Playground 系列回到了“舒适区” - 充足的数据和充足的信号。对于我们中 GPU 不足的人来说,数据有点太多了 - 我就是其中之一,因为我使用的唯一 GPU 是 Kaggle 提供的。所以像去年几期一样,这次也耗尽了很多 GPU 配额,以及 12 小时运行时间或内存。无论如何,我终于开始花更多时间在 Kaggle 的奖金比赛上,所以在第一周左右我没有花太多时间在这一期上,只是尝试了一些 Autogluon 提交并熟悉数据。它遵循了最近的趋势,即原始数据本身是合成的(并且由一位印度 Kaggle 用户生成——最近也很常见!),但值得庆幸的是,创建者 @ysthehurricane 在设计富含信号的数据集方面做得很好。

第二阶段:进入状态: 我想这大约是从 @greysky 打破竞争局面时开始的 - 直到这一点,大多数解决方案都在最佳 Autogluon 解决方案的范围内,得分在 12.35-12.40 之间。@greyskynotebook 令人印象深刻地跃升至 12.15,并打开了大量目标编码和配对编码的大门。我实验了他的代码不少,修改它以保存 OOFs,并调整参数以收集几个有用的 OOFs。我也用 XGBoost 代替 LGBM 做了同样的事情。@masayakawamata 也贡献了几个非常有用的 notebooks - 那些带有精选特征的特别有用,因为它们可以在不使用宝贵 GPU 配额的基础上构建。很快,我有了几十个 OOFs,我正在路上,在排行榜上上升,但还没有接近绝对顶部。

第三阶段:追逐前三名,有点懒惰: 即使我在勤奋地收集更多 OOFs,我也懒得去追求各种想法(稍后详述)。尽管如此,我继续保持上升,并发现对一些更强的模型运行 30 折交叉验证带来了相当显著的改进 - 我最强的单一模型是 @pirhosseinlou强单一 XGB 的更新版本,添加了特征,使用中位数而不是均值进行编码,以及 30 折交叉验证。该模型在公共排行榜上得分 11.75387 —— 在私有排行榜上,得分 11.67004,这将排在第 34 位,对于单一模型来说不错。有几个模型在 11.75-12 范围内,这个集合帮助我最终突破了前三名,尽管进进出出,因为接近尾声时事情变得有趣了。

结局 —— 险些崩溃,但侥幸逃脱: 当我在前三名进进出出时,倒数第二天情况看起来不错,但由于各种原因,我最终只做了一个提交。我的电脑也在所有集成工作的重压下开始呻吟,几次迭代花费的时间比预期长得多。第二名和第三名之间有一场激动人心的争夺(@cdeotte 在第一名遥遥领先),这很有趣,即使 @greysky@stopwhispering 最终超越了我,还有 @ravi20076(恭喜 guys!)。在整个比赛过程中,特别是在 @hamedabedi 的一个讨论帖子中,我们讨论了测试数据中有一些异常值,所以也许 clip 这些值,或者所有要提交的预测,或者两者都是个好主意。尽管如此,我还是粗心到没有 clip 我在公共排行榜上最好的提交(11.62534)—— 令我惊恐的是,我只在 RMSE 在私有排行榜上绝对膨胀时(177.25179)才意识到这一点!幸运的是,我的另一个选定提交仍然让我获得了第 5 名(结果证明这是我在私有排行榜上的第四好成绩 —— 最好的也会排在第 5 名)。之后,我 clip 了最好的公共排行榜提交,发现它本可以排在第 4 名。哎呀!我应该更小心一点 —— 如果两个提交都没有 clip,我会想踢自己!

我懒惰事项简短列表:

  • 使用 parquet 格式:与 csv 相比,这节省了大量空间,进而节省了时间,特别是在上传和下载期间。我在上传 OOFs 到 Kaggle 时等了很长时间(以便使用 Autogluon 组装),但直到最后两天才着手使用 parquet。
  • 使用 LightAutoML:这是我通常早期会做的事情,用于 GBDTs 的集成。
  • 使用自动特征生成:一直在想这个,但直到最后一天才使用 OpenFE(没太大帮助)。
  • 使用 TabNet
  • 使用 LightAutoML 提供的各种 NN 架构
  • 特征选择:没有系统地进行,只是对少数特征做了一些有限的分析。
  • 模型选择/剪枝:我本可以大概剪枝我的 OOF 集合不少,同时保持相同或稍好的性能。最后,我只做了一次,删除了所有被 Ridge 回归分配低权重的模型,用于让我获得第 5 名的提交(70 个 OOFs 而不是 100 个)。事实证明,所有 100 个 OOFs 的相应提交得分更好,如果被选中也会排在第 5 名。
  • 实验 @masaishi 的发现,即 Episode_Length_minutes 中超过 2 位小数的小数点数据点与实际的 Listening_Time_minutes 强相关
  • 建模残差:我本打算在下一个回归比赛中这样做,但没来得及做。事后看来,这可能没什么大不了的,因为我使用的绝大多数模型都是 GBDTs。

关于集成的说明: 我并不总是详细说明这一点,因为感觉像是在重复自己,而且阅读我帖子的人可能都知道这些内容。但总会有新人,所以详细说明几点可能很有意义。对于新手来说 —— 构建强大的集成涉及寻找模型多样性。例如,GBDTs 和 NNs 往往结合得很好,所以把它们混合在一起总是一个好主意。您还可以通过为不同数量的折运行相同的模型,或使用不同的特征子集来生成多样性。另一种方法是玩转模型参数,例如使用 bootstrapping、评分函数、采样策略、损失函数等的各种选项。最终,您希望每个模型都能做对一些其他模型错过的事情,以便它们集体尽可能做对更多事情。您还需要能够很好地将所有模型组合成一个强大的最终解决方案的集成方法 - Ridge 回归总是一个不错的选择,但我也使用 Lasso、Hill Climbing 和 Autogluon(偶尔我会尝试其他方法,例如 LightAutoML 或单个 GBDTs)。有时,我会扔进一个由集成器生成的 OOF —— 技术上来说,这是有争议的,因为您正在将 L2 OOF 与 L1 OOFs 混合在一起,但它在 Playground 解决方案中通常效果很好。例如,在这次比赛中,我得分最好的解决方案总是包含一个使用 Autogluon (AG) 集成生成的 OOF。通常,我会将 AG OOF 与 fed 给它的所有 OOFs 一起使用 —— 接近尾声时,这不同步了,我的最终提交使用了 99 个 OOFs 以及基于其中 95 个的 AG OOF。

最后,我想祝贺 @cdeotte, @greysky, @stopwhispering, @ravi20076, @masaishi 以及所有表现强劲的人。祝大家 Kaggle 愉快!

同比赛其他方案