362. Google QUEST Q&A Labeling | google-quest-challenge
祝贺本次比赛的所有获奖者,你们的辛勤付出得到了回报!
首先,我要感谢以下三个已发布 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 的模型中。但在分析了问题内容和回答的长度分布后,我们发现了两个主要问题:
后来我们做了一些实验(我会在文章末尾列出一些,结果证明帮助不大),最终决定训练两个独立的模型。第一个模型只输入问题标题和问题内容。第二个模型只输入问题标题和回答。这样,几乎所有的问题内容和回答都能放入模型中。
像讨论区的其他作者一样,我们将 30 个输出特征分成了两部分。我们使用问题标题和问题内容来预测与问题相关的特征,使用问题标题和回答来预测与回答相关的特征。我们训练了多次权重,最终输出是这些模型权重的平均值。
做完这些后,我们在公共榜单上获得了 0.415 的分数(当时排名 90 左右)。在剩下的日子里,我们将重心转移到了数据后处理部分,因为当时最高分已经超过了 0.480。但我们不相信我们使用的模型会有这么大的差距。肯定有一些我们还没意识到的“技巧”部分。
于是,我检查并比较了模型预测的分布和训练集的标准分布。我们发现了“神奇”的部分:训练集中的评分是离散的。这很有道理,对吧?评分者可能只能选择某些“合理”的分数。现实生活中没人会给出像 0.76354237 这样的分数 :). 所以,我做了一个简单的调整:取出每个预测输出,找到最接近的“合理”分数,然后替换它。这个简单的改变极大地提高了我的分数和排名(LB 超过 0.450)。
然后我再次绘制了预测分布和训练集标准分布图,并对每一列进行了微调(实际上是一些硬编码)。这个过程花了我大约两天时间。我提交了很多版本,但结果并不好,存在过拟合的风险。最后,我选择了一个未微调的内核和一个经过微调(硬编码)的内核作为最终提交,结果未微调的那个胜出了。
这是我在尝试比较训练数据集和预测分布时的一个例子。
在下图中,我试图标记哪些列需要微调。黄色的水平线表示我不需要对这些列做太多处理。其他图表中像 0.5 和 1.0 这样的分数表示我需要对这些值进行额外的阈值处理。
受公开 Kernel 的启发,我们从 url 列中提取了 URL,并对 URL 和类别列进行了独热编码。独热编码后有 64 个新特征列(51 个用于 url,13 个用于 category)。根据论文