返回列表

3rd solution - single TRANSFORMER model, link to kernel

360. 2019 Data Science Bowl | data-science-bowl-2019

开始: 2019-10-24 结束: 2020-01-22 学习效果预测 数据算法赛
第3名方案 - 单TRANSFORMER模型

第3名方案 - 单TRANSFORMER模型

作者: Limerobot | 排名: 第3名

很抱歉,因为之前一直是韩国的传统节日,直到今天我才抽出时间来写这篇文章。感谢大家的耐心等待。

首先,我要感谢 Booz Allen Hamilton 主办了这场有趣的比赛。同时祝贺所有的参与者,特别是获奖者们!

我非常喜欢深度神经网络,所以我倾向于用深度神经网络来解决所有问题。😃

相比于理解输入数据本身,我更关注输入数据的结构。我专注于构建模型的输入,尽可能避免信息缺失,希望模型能表现出超出我预期的效果。😊

换句话说,我较少关注特征工程,而更多关注寻找适合数据的神经网络模型架构。

有趣的发现

  • 有趣的是,使用位置相关信息(特别是位置嵌入)反而降低了本地交叉验证(CV)分数。
    • BERT、ALBERT 和 GPT2 模型的表现并不好。(因为这些模型使用了位置嵌入)
    • 所以我使用了不带位置嵌入的 TRANSFORMER 模型。

预处理

按 game_session 聚合

installation_id 的序列太长,无法直接使用。因此我按 game_session 聚合了日志数据 (train_df)。请看下面的示例。

df = train_df
event_code = pd.crosstab(df['game_session'], df['event_code'])
event_id = pd.crosstab(df['game_session'], df['event_id'])
...
agged_df = pd.concat([event_code, event_id, game_accuracy, max_round])
session_df = df.drop_duplicates('game_session', keep='last').reset_index(drop=True)
session_df = session_df.merge(agged_df, how='left', on='game_session')

NLP 中的 LSTM 和 TRANSFORMER 模型接收单词序列(或句子)作为输入。类似地,我在这里使用 game_sessions 序列(或 installation_id)作为输入。

模型

最佳私有分数:0.564
使用了单个 Transformer 模型。

TRANSFORMER 模型块

Transformer Model Block

根据 installation_id 的 game_sessions 进行预测。

这里的关键是如何从 game_session 创建嵌入。

Categorical columns(如 event_code, title, world 等)分别进行嵌入。然后,通过拼接这些嵌入得到 categorical_vector。接下来应用 nn.linear 层对 categorical_vector 进行降维。

self.categorical_proj = nn.Sequential(
            nn.Linear(cfg.emb_size*num_categorical_columns, cfg.hidden_size//2),
            nn.LayerNorm(cfg.hidden_size//2),
        )  

Continuous columns 直接通过线性层进行嵌入。

self.continuous_emb = nn.Sequential(                
            nn.Linear(num_continuous_columns, cfg.hidden_size//2),
            nn.LayerNorm(cfg.hidden_size//2),
        )
  • 我使用 np.log1p 对连续列进行归一化。

超参数

  • optimizer: AdamW
  • schedular: WarmupLinearSchedule
  • learning_rate: 1e-04
  • dropout: 0.2
  • number of layers : 2
  • embedding_size: 100
  • hidden_size: 500

改进的损失函数

正如此链接中提到的,accuracy_group 的类别 0 和 3 可能非常接近。

num_correct 可以为 0 或 1,如果 num_correct 为 1,则 accuracy_group 增加 3 分。
另一方面,当 num_incorrect 为 1 时减 1 分,当 num_incorrect 为 2 或更多时减 2 分。

这可以表示为:

# num_incorrect[num