返回列表

Private 7th place solution

633. Child Mind Institute — Problematic Internet Use | child-mind-institute-problematic-internet-use

开始: 2024-09-19 结束: 2024-12-19 健康管理与公共卫生 数据算法赛
私有第 7 名解决方案 - sqrt4kaido

私有第 7 名解决方案

作者: sqrt4kaido (Grandmaster)
排名: 第 7 名
发布时间: 2024-12-20

大家好。

首先,我想感谢组织者举办这次比赛。处理真实世界的数据具有挑战性,但这为提升我在实际应用中的技术技能提供了绝佳机会。

下面,我分享我的解决方案:

模型

  • 我使用了这个基线:CMI Single LGBM CV 0.471 LB 0.460
  • 主要模型是 LGBM(集成中也包含了 XGBoost)。
  • 缺失值使用中位数插补处理,仅在每个 fold 的训练数据上计算,并应用于验证/测试集。
  • 序列数据统计信息的处理与公开 notebook 相同,但使用 Polars 进行了速度优化。
  • 我使用 Tweedie loss 作为主要损失函数(集成中也包含了分类)。→ 重要
  • 针对不存在 'sii' 的数据生成预测,并将其用作伪标签进行训练。→ 重要
  • 数据字典中定义为分类整数的特征,既作为分类特征使用,也作为数值特征使用。

阈值优化 → 重要

阈值优化在每个 fold 的训练数据上执行,并应用于验证/测试集。使用百分位数进一步提高了准确性和鲁棒性。初始优化值 derived from 讨论 此处

def calc_initial_th(y, y_pred):
    tmp_df = pd.DataFrame({"sii": y, "prediction": y_pred})
    oof_initial_thresholds = (
        tmp_df.groupby("sii")["prediction"].mean().iloc[1:].values.tolist()
    )

    oof_threshold_percentiles = [
        (tmp_df["prediction"] <= threshold).mean()
        for threshold in oof_initial_thresholds
    ]

    return oof_threshold_percentiles

oof_initial_thresholds = calc_initial_th(y, y_pred)

self.optimizer = minimize(
    eval_preds_percentile,
    x0=oof_initial_thresholds,
    args=(y, y_pred),
    method="Nelder-Mead",
    bounds=[(0, 1), (0, 1), (0, 1)],
)

CV 策略与模型评估

我使用了 5 折 StratifiedKFold。然而,众所周知,分数可能会根据种子(seed)显著变化。在上述 notebook 中,提交结果是对 10 个种子的结果取平均。同样,在验证中,我将 10 个种子的投票结果作为每个实验的分数进行评估。我还评估了验证中的 10 种子结果,并使用 Optuna 针对每个种子优化了参数。

例如,一次提交产生了以下依赖于种子的分数变化:

[0.4924600384356978,
 0.480933892862644,
 0.4896986007283455,
 0.4848801590924426,
 0.47931930137389445,
 0.48348085393094636,
 0.48327061771577756,
 0.47943771383186834,
 0.47465614619853563,
 0.4909707394562764]

我同时监控了投票分数和单个分数的平均值。例如,在上面的例子中,投票分数是 0.49218340134866767,平均分数是 0.4839108063626429。对于提交,我使用了 5 折 × 每个模型 10 个种子的投票集成。

虽然我旨在使评估和学习过程尽可能鲁棒,但我认为我的排名仍然很大程度上取决于运气。
感谢阅读!

同比赛其他方案