返回列表

Private 2nd/Public 5th solution: Py-Boost and GCN

588. CAFA 5 Protein Function Prediction | cafa-5-protein-function-prediction

开始: 2023-04-18 结束: 2023-12-20 药物研发 数据算法赛
私有第二名/公开第五名解决方案:Py-Boost 和 GCN

私有第二名/公开第五名解决方案:Py-Boost 和 GCN

作者:Btbpanda(Kaggle Grandmaster)
发布时间:2023年8月23日
最后更新:2024年1月14日
票数:59票
团队:Btbpanda, Alexander Chervov, Sergei Fironov

大家好!

首先,感谢 Kaggle 和 CAFA 团队举办的比赛。我们解决的问题既重要又充满挑战,尽管过程中有些令人沮丧的时刻,例如 LB 中低蛋白数量以及不明确的评估代码,但我们非常享受解决这个问题的过程。

以下是公开第五名解决方案的简要概述:

1) 序列嵌入

我们尝试使用以下嵌入列表:T5、esm2-large、ankh-large。最终,大多数模型仅使用 T5,但其中一些使用了 T5+ESM 的拼接。此外,我们将 one-hot 分类特征拼接到嵌入中。我们仅选择在训练和测试特征中都有足够代表性的分类(总共约 30 个),其他分类被合并为一个单独的组。

2) 基础模型

验证

我们无法创建比简单 5 折 CV 更好的验证方案。我们对此进行了一些实验,但其他 CV 方案导致模型在 LB 上的得分更低。

Py-boost

在 CV 和 LB 上表现最好的模型来自梯度提升家族。我们使用了一个名为 py-boost 的自定义 GBDT 实现。这是我几年前专门为处理极端多输出数据集而制作的,因为那是我当时的主要研究领域。它只能在 GPU 上运行,并且能够训练多标签任务,速度比流行知名实现快数十甚至数百倍。您可以在 GitHub 上查看 py-boost,或阅读我们的 NeurIPS 论文,其中我们解释了所有加速多输出训练的策略。

在本地,我能够在单个 V100 32GB GPU 上拟合 4.5K 输出(3000/1000/500)的 py-boost,单个折叠大约需要 1.5 小时。

逻辑回归

我们还训练了一个简单的 13K 输出逻辑回归。它在常见术语上的表现远不如 GBDT,但能够在罕见输出上表现出色。

神经网络

在模型集成中,我们使用了公开笔记 Pytorch,Keras,Etc 3 Blend, CAFA metric, etc 的稍微修改版本。唯一的区别是使用最佳交叉验证超参数组合并进行多次平均。

3) 替代建模方法 - 预测条件概率

这种方法是在比赛初期发现的,因此它对数据做出了一些错误的假设。但不知何故,它对 CV 和 LB 都很有用。这种方法的主要优势是在推理阶段利用 OBO 图,甚至可以帮助预测训练中未使用的术语。以下是主要要点:

  • 我们假设,术语只有在其至少一个父术语存在的情况下才能存在于蛋白质中。这是错误的。实际上,如果术语存在,由于传播规则,它的所有父术语也都存在。
  • 我们重新制定了经典的多标签方案,其中目标矩阵形状为 (n_protein, n_terms),由 0 和 1 组成,改为新方案。现在目标可以是 0、1 和 NaN。如果蛋白质没有值为 1 的父术语,则矩阵中该术语对应位置为 NaN。
  • 在模型训练阶段,目标矩阵中的 NaN 单元格被屏蔽并忽略
  • 现在,我们的模型输出在至少一个父术语存在的条件下术语的条件概率。在推理阶段,我们需要将其转换回原始概率
  • 转换按照图的顺序进行。当我们处理术语时,它的所有父术语已经被处理并拥有原始概率。所有术语都被包含在方案中,即使它们未在训练中使用。对于未用于训练的术语,我们使用先验均值。
  • 在处理术语时,我们做出了另一个错误假设,即术语的父术语概率是独立的。但如果我们这样假设,根据 [1],我们可以将术语的原始概率计算为
    p_term_raw = p_term_cond * (1 - (1 - p_parent_0_raw) * (1 - p_parent_1_raw) * ... * (1 - p_parent_N_raw))
    请记住,在处理术语时,它的所有父术语都已经计算出了原始概率。

该方法在 CV 和 LB 上的得分都更好,但幅度不大。其主要优势在于模型与经典多标签方法非常不同,将它们全部组合在一起可以大幅提升我们的得分。我们将此技术应用于 GBDT 和 LogReg,因此最终我们有 2 个 GBDT、2 个 LogReg 和单个混合 NN 作为基础模型。

4) 使用 GCN 进行堆叠

我们使用图卷积网络来聚合所有预测。它针对节点分类任务进行训练,其中每个节点是一个术语,每个蛋白质是一个图(但所有蛋白质具有相同的邻接矩阵)。作为节点特征,我们使用基础模型的预测以及从头训练的节点嵌入。我们还添加了下一节描述的 GO 注释特征。

我们通过一个错误发现了一个有趣的特征。在推理阶段,我们虽然模型 ID 错误,但仍获得了不错的分数,因此我们通过将预测与打乱的模型进行平均,实现了一种测试时增强。

另一个重要的事情是关于评估指标。据我理解,我们仅在实验发现的蛋白质/本体对上被评估。因此,如果我们预测的本体不存在,我们根本不会受到任何惩罚!这意味着,我们实际上需要估计在本体存在时术语的条件概率。因此,为本体 X 拟合最终堆叠模型的正确方法是截断样本,仅保留包含来自本体 X 术语的蛋白质。这给得分带来了一些小幅提升,并加速了计算。

5) GO 注释

我们发现 GO 注释数据集由该链接提供。它们不仅提供标签,还提供每个术语的证据代码。我们将 Kaggle 认为是实验性的代码与电子代码分开(希望我们理解正确)。因此,我们可以将电子标签作为特征来预测 Kaggle 给出的实验性标签。根据我们的分析,我们发现大约 30% 的电子标签会变成实验性标签,因此将其用作模型特征比直接添加效果更好。对于我们能在此数据集中找到的约 500 个蛋白质,我们直接添加了实验性标签。如果无法在我们的数据集中观察到 MT 提供的原始标签,我们也添加了它。最后一步几乎没有改变我们的得分,因此这些来源几乎相同。

6) 后处理

我们还使用 OBO 图进行后处理。机器学习模型预测蛋白质术语的问题在于它不一致。根据应用于目标传播规则(我在 CAFA-Evaluator 仓库中检查过),如果术语存在,则其所有父术语也被认为存在。因此,一致的模型永远不会预测父术语的概率低于子术语概率。但我们的模型完全不关心这一点。因此,我们可以手动修复这种情况。我们的最终术语预测是术语概率、最大传播子术语概率和最小传播父术语概率的平均值。这个技巧在 LB 上略微提升了得分,但希望它使模型更加稳定。

附言

我们祝所有参赛者好运,因为我们和你们很多人一样,期待这次比赛会有很大的变动。希望我们所有的努力都不会白费 :). 期待看到最终结果。

更新 所有解决方案代码现已开源,可在 GitHub 获取。

同比赛其他方案