586. Child Mind Institute - Detect Sleep States | child-mind-institute-detect-sleep-states
这次竞赛对我来说是一次很棒的学习经历。我要感谢主办方!
我的解决方案的代码笔记本如下:
上述笔记本的public/private分数分别为:无后处理时为0.748/0.822,有后处理时为0.768/0.822。这些差异似乎是由于代码重构过程中的微小变动或仅仅是随机性导致的。(我认为这并非关键。)
每个series_id的数据被划分为每日片段并输入神经网络。但为了避免CNN中填充的影响,实际输入时会将前一天和后一天的部分数据组合在一起。
神经网络输入通道数为三个,具体如下:
与其他参赛者类似,虚拟数据通过在同一series_id中复制(anglez, enmo, time)来检测。在计算损失前,虚拟数据的预测值被设为0,以避免影响反向传播。(因此第三个输入并不重要。)
时间相关的特征未被加入神经网络的输入,所有时间趋势均在后处理中考虑。
本次竞赛的评估指标允许事件检测结果在时间点上略有偏差仍能获得分数,因此在训练时,目标不仅应反映事件发生的时刻,还应反映其周边情况。
然而,若目标衰减不足,则往往只能粗略预测峰值的大致时间,导致在更小阈值下得分降低。经过搜索能获得最佳验证分数的方法后,最终采用如下图中所示的指数衰减形式。

我的神经网络架构基于K_mat(本次竞赛第2名)所写的以下笔记:
U-Net 1D-CNN with Keras
输入粒度为每5秒,但输出粒度为每分钟,这与常规U-Net不同。我尝试了多种结构,包括层数、通道数、核大小等,但搜索有限,相信存在更好的配置。
关于模型结构的详细信息,请参见上述笔记本。
神经网络未输入时间信息,时间因素在后处理中考虑。神经网络输出的每分钟分数根据一天中不同时间段的趋势乘以相应的权重。
具体如下:
此外,作为一个与时间无关的后处理步骤,分数会根据虚拟数据所占百分比乘以一个系数。这是因为虚拟数据较多的series_id往往更难以准确猜测峰值,我旨在通过将更自信的预测置于列表顶部来改善PR-AUC。
使用scipy.signals.find_peaks函数对调整后的分数进行峰值提取。采用两步策略:首先提取较大的峰值,然后提取较小的峰值。前者每天大约提取一个峰值,后者则有无数个。通过放大前者的分数,我旨在改善PR-AUC。
这些后处理将CV分数提高了约0.005至0.01,但如前所述,这些后处理对Private LB分数的影响有限。