返回列表

47th place solution

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

开始: 2019-11-22 结束: 2020-02-10 自然语言处理 数据算法赛
第47名解决方案
作者:kenmatsu4 (Master) | 排名:第47名 | 发布日期:2020-02-11

感谢 Google 作为主办方以及 Kaggle 团队!通过这次比赛,我真的学到了很多 NLP 技术,特别是 BERT。

最终模型的关键点

  • 如果文本长度超过 max_seq_length,则使用文本的开头和结尾部分
  • 对 4 个 BERT base-uncased 模型的结果进行平均
  • 后处理:利用训练数据拟合目标分布(针对部分目标列)
    • 详情见下文。
  • 将 bert_layer 的 pool_output 和 sequence_output 拼接,用于 GlobalAveragePooling1D
  • 使用 MultilabelStratifiedKFold 进行 10 折交叉验证(感谢 @ratthachat !)
  • 独自参赛需要一颗强大的心脏

对我无效的方法

  • 使用 Stack Overflow 数据进行预训练(150,000 个句子)
  • Multi-sample dropout(多样本 dropout)
  • 其他模型
    • Roberta
    • Albert
    • XLNet
  • 拼接“仅问题”输出模型和“仅回答”模型
  • 将类别 MLP 与 BERT 模型拼接
  • 在 BERT 模型上使用 LSTM 头代替 Dense 层
  • 冻结一半的 BertLayer 以降低模型复杂度
  • 跳过一半的 BertLayer 以降低模型复杂度
  • USE + MLP
  • 使用 gensim 嵌入的 LSTM 模型
  • 自定义损失函数
    • BCE & MSE
    • Focal loss
  • 词数特征
  • 将标题和问题主体拼接为一个块(移除了它们之间的 ["SEP"])
  • 对不平衡的目标列进行上采样

我的后处理类

class OptimPreds(object):
    def __init__(self, df_train):
        self.score_range_dict = {}
        for i, c in enumerate(df_train.columns[11:]):
            cnt = df_train[c].value_counts(normalize=True).sort_index()
            self.score_range_dict[i] = [cnt.index.values.tolist(), cnt.values.tolist()]
    def predict(self, preds, i):
        return pd.cut(rank_average(preds), [-np.inf] + np.cumsum(self.score_range_dict[i][1])[:-1].tolist() + [np.inf], labels = self.score_range_dict[i][0])

def optim_predict(pred, do_round=True, target=[ 2,  5,  7,  9, 11, 12, 13, 14, 15, 16, 19]):
    for i in range(pred.shape[1]):
        if i in target:
            pred[:,i] = optim.predict(pred[:,i], i)
    return pred
同比赛其他方案