665. CMI - Detect Behavior with Sensor Data | cmi-detect-behavior-with-sensor-data
首先,感谢组织了一场如此精彩的比赛!向组织者和所有辛勤工作的参与者致敬!
以下是我的方法概述。
我使用了 Transformer、GRU 和 Squeezeformer 模型的集成。模型分为两类:仅 IMU 和全数据。对于全数据,我只使用了 GRU 模型。下面是 GRU 模型的结构(其他模型非常相似)。
一个关键特征是在输入后添加了一个 1D CNN 层,而不是单独使用 GRU。这显著提高了交叉验证 (CV) 分数。
由于这是时间序列数据,我主要添加了包含当前行之外的信息的特征。例如,对 acc_x 应用滚动标准差提高了 CV。我还包括了中心滚动统计量:
train_df['acc_x_std'] = train_df.groupby('sequence_id')['acc_x'].transform(lambda x: x.rolling(window=5, min_periods=1).std())
train_df['acc_x_center_std'] = train_df.groupby('sequence_id')['acc_x'].transform(lambda x: x.rolling(window=5, center=True, min_periods=1).std())
有趣的是,发生了一些意想不到的事情:我不小心重复添加了一个来自 thm 的特征,出于某种原因,CV 提高了 0.01。虽然原因尚不清楚,但我保留了它,因为它增强了性能。
Incorporating EMA helped improve CV while also enhancing generalization. (引入 EMA 有助于提高 CV,同时也增强了泛化能力。)
tof 数据包含相当多的缺失值,因此适当的空值处理至关重要。我使用线性插值和中位数填补来平滑地填充缺失值。以下是训练期间用于空值处理的代码:
for group_prefix in tof_groups:
group_cols = [col for col in train_df.columns if col.startswith(group_prefix)]
train_df[group_cols] = train_df[group_cols].replace(-1, np.nan)
train_df[group_cols] = train_df[group_cols].apply(
lambda row: row.interpolate(method='linear', limit_direction='both', limit=5), axis=1
)
train_df[group_cols] = train_df[group_cols].apply(
lambda row: row.fillna(row.median()), axis=1
)
train_df[group_cols] = train_df[group_cols].fillna(-1)
我将 mixup alpha 设置为 1.0。这是为了提高泛化能力,它确实带来了更好的 CV。
带有早停 (early stopping) 的模型被视为“最佳模型”,而没有早停的模型被视为“最终模型”。这两种类型都用于集成中。以下是细分:
仅 IMU:
全数据:
我使用简单平均法进行集成。
方向的辅助损失 (Auxiliary Loss for orientation):它略微提高了 CV,但恶化了排行榜 (LB) 分数,所以我没有采用它。
感谢阅读!