返回列表

39th Place Solution

586. Child Mind Institute - Detect Sleep States | child-mind-institute-detect-sleep-states

开始: 2023-09-05 结束: 2023-12-05 健康管理与公共卫生 数据算法赛

第39名解决方案:儿童心理研究所-检测睡眠状态

团队:Avengers
排名:第39名(银牌)
发布时间:2023年12月7日

感谢Kaggle举办这场意义非凡的比赛。感谢所有Kagglers的讨论和分享观点。这是我们首次参加正式的表格数据竞赛,从中获益良多。

Avengers团队将继续在Kaggle的旅程。

详细解决方案

基线代码

感谢tubotubo提供的基线代码。我们并非从比赛开始就参与,这份基线代码为我们提供了思路基础和模型结构参考。

数据集准备

  • 我们未对脏数据进行处理,这可能是无法进一步提升分数的原因之一
  • 在比赛结束前一天晚上,队友发现这个讨论。我们尝试通过删除事件为空的天数数据来清洗数据,但因时间限制未取得显著进展
  • 我们相信数据清洗会有帮助,因为使用该方法的模型在私有排行榜上分数差异更小

比较结果

特征工程

我们使用shift、diff和滚动窗口函数生成新特征。最终使用了24个滚动特征,加上原始4个特征,共28个特征。新特征的使用并未显著提升模型分数,这出乎我们意料。

代码:此处

*[pl.col("anglez").diff(i).alias(f"anglez_diff_{i}") for i in range(diff_start, diff_end, diff_step)],
*[pl.col("anglez").shift(i).alias(f"anglez_lag_{i}")
  for i in range(shift_start, shift_end, shift_step) if i != 0],
*[pl.col("anglez").rolling_mean(window_size).alias(
    f"anglez_mean_{window_size}") for window_size in window_steps],
*[pl.col("anglez").rolling_min(window_size).alias(
    f"anglez_min_{window_size}") for window_size in window_steps],
*[pl.col("anglez").rolling_max(window_size).alias(
    f"anglez_max_{window_size}") for window_size in window_steps],
*[pl.col("anglez").rolling_std(window_size).alias(
    f"anglez_std_{window_size}") for window_size in window_steps]

Wandb超参优化

Wandb sweep是Wandb机器学习平台提供的超参数优化工具,可自动探索不同超参数组合以提升模型性能。

实现代码:此处

模型

  • 使用重叠:为提高序列边缘预测精度,我们采用10000长度序列预测8000长度序列的重叠方法
  • PrecTime模型实现:详见讨论。我们对其结构进行修改,增加了Transformer架构和残差连接,实验表明这些改进有效提升了模型性能

后处理技巧

我们使用动态规划算法处理重叠问题。原理:要获得高AP(平均精度),需满足三个条件:预测标签与实际标签足够接近;在实际标签的正负容忍范围内仅有一个预测点;实际标签范围外的预测点分数低于范围内的点。

def get_results_slide_window(pred, gap):
    scores = list(pred)
    stack = [0]
    dp = [-1] * len(scores)
    dp[0] = 0
    for i in range(1,len(scores)):
        if i - stack[-1] < gap:
            if scores[i] >= scores[stack[-1]]:
                stack.pop()
                if i - gap >= 0:
                    if stack:
                        if dp[i - gap] != stack[-1]:
                            while stack and dp[i - gap] - stack[-1] < gap:
                                stack.pop()
                            stack.append(dp[i - gap])
                    else:
                        stack.append(dp[i - gap])
                stack.append(i)
        else:
            stack.append(i)
        dp[i] = stack[-1]
    return stack

模型集成

我们的集成方法本质上是不同输出的加权平均。结合后处理后,模型越多或多样性越高,分数越高。

提交代码1:此处
提交代码2:此处

模型 LB分数 PB分数 是否选用
2 * 5折 PrecTime + 1 * 5折 LSTM-Unet 0.75 0.8
2 * 5折 PrecTime + 2 * 5折 LSTM-Unet + 10个单模型 0.759 0.803
1 * 5折 PrecTime + 1折 LSTM-Unet + 10个单模型 0.761 0.804
1 * 5折 PrecTime + 1 * 5折 LSTM-Unet + 10个单模型 0.759 0.803

其他说明

欢迎访问我们的GitHub代码,期待与大家交流讨论。

总结

  • 数据清洗
  • 生成新特征
  • 使用Conv1d、RNN、GRU、LSTM或Transformer等架构
  • 针对特殊评估指标编写后处理

感谢所有队友共同努力获得银牌。

同比赛其他方案