返回列表

16th Place - Single Model

416. Riiid Answer Correctness Prediction | riiid-test-answer-prediction

开始: 2020-10-05 结束: 2021-01-07 学习效果预测 数据算法赛
第16名 - 单模型方案

第16名 - 单模型方案

作者: MPWARE 及团队成员
比赛: RIIID Test Answer Prediction

大家好,

这里是我们两个解决方案的见解,这两个方案的公榜分数均为 0.812,私榜分数为 0.815,最终获得了第16名金牌。

这次比赛既是机器学习也是工程优化的挑战,需要在 9 小时内、13GB 内存/16GB GPU 的限制下让一切正常运行。我们花费了近 30% 的时间进行优化,以便在内存中保留每个用户最后的 512 次交互、按内容的尝试次数以及我们特征所需的其它数据。

我们要感谢 Kaggle 和 RIIID 的组织者举办这场精彩的比赛!祝贺顶尖团队和所有参赛者在整个挑战过程中保持的动力。我要感谢我的队友 @rafiko1, @cdeotte, @titericz 和 @matthiasanderer。你们太棒了,我从你们那里学到了很多。我真的很享受这次比赛。

方案 1:单一 Transformer 模型

SAINT+ 模型的描述见此处:https://arxiv.org/pdf/2010.12042.pdf
我们 SAINT+ 适配的代码可在此处获取:https://github.com/rafiko1/Riiid-sharing

SAINT模型图

我们的单一模型 SAINT++ 取得了以下成绩:CV: 0.812,Public LB: 0.812,Private LB: 0.815。

我们首先使用 95% 的用户进行训练,然后使用智能窗口技术对所有数据进行微调(参见下图 SAKT 的示例)。该模型在特征方面非常简单。它仅包含 SAINT+ 的四个特征(如上图所示),并增加了一个特征——用户针对特定内容的尝试次数(因此称为 SAINT++):

  • 内容 ID (Content id)
  • 滞后时间
  • 前一问题耗时
  • 之前的回答
  • 尝试次数

与 SAINT+ 相比,特征上最大的改进是将滞后时间按“秒”进行分组,而不是论文中按“分钟”分组。

随后,我们在架构上越做越大,并燃烧了一些 GPU 算力 🔥。我们增加了模型的参数,最重要的是序列长度和层数。模型的最终参数如下:

  1. 输入序列长度:512
  2. 编码器层数:4
  3. 解码器层数:4
  4. 嵌入大小:288
  5. 全连接层:768
  6. 注意力头数:8
  7. Dropout:0.20

我们使用了 Noam 学习率调度器:初始预热,然后指数衰减至 2e-5。

最后的改进来自我们在推理过程中的递归技巧。在这里,我们将来自同一个 bundle 的预测值四舍五入为 0 或 1——因为此时它们的真实响应在时间上还是未知的。然后,这些四舍五入后的预测值被反馈给模型,用于预测同一个 bundle 内的下一个响应。这个技巧让 CV LB 提升了 +0.0025,但这要求 batch size 为 1,因此我们无法集成多个 transformer 模型。

方案 2:Transformer、改进版 SAKT 和 LGB 的集成

  • LightGBM 模型 得分 CV=0.793,Public LB=0.792,包含 44 个特征。
    我们的主要特征包括:
    按内容和用户划分的问题正确率、标签 1 和 2、部分、耗时、是否有解释、尝试次数、多种滞后时间、移动平均值(回答)、多种滚动均值/中位数(回答、滞后、耗时)+ 加权平均、30 次交互前后的均值、多种动量(滞后、回答)、按部分的正确率、按会话(8小时分割)的移动平均值。只有 3 个类别特征:part, tags1, tags2。训练/验证集划分来自 Tito

  • Pytorch SAKT 改进版 得分 CV=0.786,LB=0.789,增加了额外特征。训练过程使用了智能窗口。