返回列表

2nd Place Solution for the Regression with an Abalone Dataset Competition

606. Playground Series - Season 4, Episode 4 | playground-series-s4e4

开始: 2024-04-01 结束: 2024-04-30 生命科学 数据算法赛
Abalone 数据集回归竞赛第二名方案
作者:Lennart Purucker  |  发布日期:2024-05-02  |  排名:第二名

Abalone 数据集回归竞赛第二名方案

大家好,感谢主办方举办本次竞赛,并向活跃的社区致敬!

提交背景

我在比赛临近结束时才参赛,以测试我的自动化机器学习(AutoML)工作流程,这套流程本想用于随后开始的AutoML 大奖赛

出乎意料且令人惊喜的是,我的 AutoML 工作流程在未经任何调整的情况下表现非常出色。实际上,它在该数据集上的效果比在第一次 AutoML 大奖赛数据集上更好,因为该数据集真正受益于自动化特征工程。

我将在大奖赛的总结报告中分享该工作流程的主要代码。如果可能,我会把报告链接贴在下面,或在评论中更新。 编辑这里是报告。

AutoML 工作流程概览

  1. 自动化双样本检验训练数据
  2. 自动化特征工程(OpenFE + AutoGluon)
  3. 自动化模型选择(自定义 AutoGluon)

1. 自动化双样本检验以优化训练数据

由于这是我首次积极参加 Kaggle 竞赛,我认为拥有一个额外且可能不可靠的数据源非常有趣。因此,为了决定是否在训练数据中加入原始数据,我针对原始数据、比赛提供的训练集和测试集开展了几组双样本检验。这些检验旨在判断是否存在分布偏移;如果存在偏移,加入原始数据可能会对模型有害。

我使用 AutoGluon 来预测它能否识别出样本来源,并使用 Mann‑Whitney U 检验来评估显著性。

我检验了以下几种组合:

  • (Kaggle + 原始)训练集 对 (Kaggle)测试集
  • (Kaggle)训练集 对 (原始)训练集
  • (Kaggle)训练集 对 (Kaggle)测试集
  • (原始)训练集 对 (Kaggle)测试集

根据这些检验的观察结果,我决定将原始数据纳入训练集。不过,如何自动做出这一决定仍需进一步 formalize。该设置还有改进空间,我希望在未来加入评估「加入数据是否有可能提升性能」的检验。

2. 自动化特征工程(OpenFE + AutoGluon)

我认为这部分是获得第二名的关键。简单来说,我的做法是:① 运行定制版的 OpenFE,随后 ② 使用 AutoGluon 的特征选择 对特征进行剪枝。

在步骤②中,我尝试使用 LightGBM 作为代理模型进行特征选择。

在步骤①中,我首先手工挑选潜在的特征候选,以控制 OpenFE 搜索空间,并加入了一种新的特征生成器。随后,我使用默认参数运行 OpenFE,获得了约 200 个特征。最后,利用步骤②在 1 小时的时间限制内自动将这些特征剪枝至更小的集合。

遗憾的是,我无法提供最终特征生成器的全部细节,因为我的流程没有记录这些生成函数的名称。此外,在尝试为首届 AutoML 大奖赛数据实现自动化特征工程时(剧透:并不值得),我的代码库变得相当凌乱,难以追溯。

我使用以下代码控制特征生成器:

all_features = list(train_data.columns)
soft_ordinal = [f for f in all_features if (train_data[f].nunique() <= 100) and (f not in ordinal_columns)]
numerical_features = [f for f in all_features if f not in categorical_columns]
candidate_features = get_candidate_features(
    numerical_features=numerical_features,
    categorical_features=categorical_columns,
    ordinal_features=ordinal_columns + soft_ordinal,
    order=1,  # 2 is likely impossible to use w/o time estimate.
)

# Restrict Search Space of Candidate Features
candidate_features = [
    f
    for f in candidate_features
    if f.name
    in [
        # "abs" -> dataset specific, not useful in most cases
        # "log" -> can be done by scalers, no need for GBDTs
        # "sqrt", -> see above (s.a.)
        # "square" , -> s.a.
        # "sigmoid" , -> s.a.
        "freq", -> # do not like it but giving it a shot.
        "round",
        "residual",
        # "max", -> IMO, trivial to model for first-order features
        # "min", -> s.a.
        # "+", -> s.a.
        # "-", -> s.a.
        "/",
        "*",
        # "GroupByThenMin",  -> The essential benefit of GroupBy is captured with any of these, so I filtered this to reduce the search space.
        # "GroupByThenMax", -> s.a.
        # "GroupByThenMean", -> s.a.
        "GroupByThenMedian",
        "GroupByThenStd",
        # "GroupByThenRank", -> s.a.
        "GroupByThenFreq",
        "GroupByThenNUnique",
        "Combine",
        # New Generators
        #   - Hacked into OpenFE by adding `new_data = int(d < d.quantile(X).max())` to the generator options.
         "

3. 自动化模型选择(自定义 AutoGluon)

最终,我使用了「经过调优」的 AutoGluon 来选择最终模型。完整的细节将在 AutoML 大奖赛的报告中分享。编辑这里是报告。

在这里值得注意的是,堆叠(Stacking)在该数据集上效果非常好(相关代码涉及动态堆叠)。因此,我将 AutoGluon 配置为最多进行 6 层堆叠。最终它使用了 5 层,但查看我的提交得分时,仅使用 3 层也达到了相同的分数,而第 5 层同样没有出现过拟合。

希望这(以及更详细的报告)能够为您提供解决方案的概览。同时,也期待您和我一样对更高效、更好的自动化特征工程感到兴奋! ;)

祝好,
Lennart