返回列表

A general walk through my solution with trick 55th

362. Google QUEST Q&A Labeling | google-quest-challenge

开始: 2019-11-22 结束: 2020-02-10 自然语言处理 数据算法赛
我的解决方案概览(第55名)

我的解决方案概览(第55名)

作者: Liyan Tang (jay0606) | 排名: 55th

祝贺本次比赛的所有获奖者,你们的辛勤付出得到了回报!

首先,我要感谢以下三个已发布 Notebook 的作者:
https://www.kaggle.com/akensert/bert-base-tf2-0-now-huggingface-transformer
https://www.kaggle.com/abhishek/distilbert-use-features-oof
https://www.kaggle.com/codename007/start-from-here-quest-complete-eda-fe

这些 Notebook 展示了构建模型、可视化数据集以及从非文本数据中提取特征的绝佳方法。

我们最初的计划是将问题标题问题内容回答全部输入到一个基于 BERT 的模型中。但在分析了问题内容和回答的长度分布后,我们发现了两个主要问题:

  • 如果将这三部分都作为输入,由于 BERT 类模型输入大小的限制,我们必须调整问题内容回答的输入空间。为此,我们不得不截断大量文本,这浪费了训练数据。此外,如何截断长文本也是一个棘手的问题。
  • 大约一半的问题内容和回答中包含代码。在实现分词时,这给我们带来了一些麻烦。代码的分词结果看起来非常奇怪,我们不知道这是否会对模型预测产生很大影响。

后来我们做了一些实验(我会在文章末尾列出一些,结果证明帮助不大),最终决定训练两个独立的模型。第一个模型只输入问题标题问题内容。第二个模型只输入问题标题回答。这样,几乎所有的问题内容和回答都能放入模型中。

像讨论区的其他作者一样,我们将 30 个输出特征分成了两部分。我们使用问题标题问题内容来预测与问题相关的特征,使用问题标题回答来预测与回答相关的特征。我们训练了多次权重,最终输出是这些模型权重的平均值。

做完这些后,我们在公共榜单上获得了 0.415 的分数(当时排名 90 左右)。在剩下的日子里,我们将重心转移到了数据后处理部分,因为当时最高分已经超过了 0.480。但我们不相信我们使用的模型会有这么大的差距。肯定有一些我们还没意识到的“技巧”部分。

于是,我检查并比较了模型预测的分布和训练集的标准分布。我们发现了“神奇”的部分:训练集中的评分是离散的。这很有道理,对吧?评分者可能只能选择某些“合理”的分数。现实生活中没人会给出像 0.76354237 这样的分数 :). 所以,我做了一个简单的调整:取出每个预测输出,找到最接近的“合理”分数,然后替换它。这个简单的改变极大地提高了我的分数和排名(LB 超过 0.450)。

然后我再次绘制了预测分布和训练集标准分布图,并对每一列进行了微调(实际上是一些硬编码)。这个过程花了我大约两天时间。我提交了很多版本,但结果并不好,存在过拟合的风险。最后,我选择了一个未微调的内核和一个经过微调(硬编码)的内核作为最终提交,结果未微调的那个胜出了。

那些没起作用的方法:

  • 既然人类即使句子中缺少一些单词也能理解,我尝试定义一个函数,可以随机从文本中删除一些单词,使其与输入兼容。这确实让我的公共 LB 分数提高了 0.003-0.004 左右,但在我们决定构建两个独立部分的模型后,效果甚微。
  • 我粗略浏览了数据集的文本,试图找出包含代码的文本之间的共同点(这花了我几乎一整天 >_< )。然后我使用了一些正则表达式,试图删除所有文本中的代码和链接。然而,我不确定删除它们是否是好事。创建一些特殊标记可能是更好的主意,但我们真的没有足够的时间去做。结果效果并不好,甚至降低了分数,所以我们决定不使用它。

更新:

这是我在尝试比较训练数据集和预测分布时的一个例子。

分布示例图

在下图中,我试图标记哪些列需要微调。黄色的水平线表示我不需要对这些列做太多处理。其他图表中像 0.5 和 1.0 这样的分数表示我需要对这些值进行额外的阈值处理。

标准分布图

更新技术部分:

特征工程:

受公开 Kernel 的启发,我们从 url 列中提取了 URL,并对 URL 和类别列进行了独热编码。独热编码后有 64 个新特征列(51 个用于 url,13 个用于 category)。根据论文

同比赛其他方案