返回列表

14th place solution

386. Tweet Sentiment Extraction | tweet-sentiment-extraction

开始: 2020-03-23 结束: 2020-06-16 自然语言处理 数据算法赛
第14名解决方案

第14名解决方案

作者:Chenying Li
原文发布时间:2020-06-19

首先,我想感谢 Kaggle 团队举办这场有趣的比赛。这是我第一次参加 Kaggle 比赛,也是第一次参与讨论,我很高兴也很幸运能获得金牌。唯一的遗憾是,之前我使用了快速提交方法,在最后几个小时我必须上传模型权重。上传速度非常慢,所以我放弃了模型融合。

我的解决方案并不特别。我尝试了很多技巧,但大多数都没能提高我的分数,例如对抗训练、语言模型预训练、高 dropout、训练两个模型并拼接嵌入、联合训练添加分类损失、训练不同的模型(albert, xlnet, bert, roberta large, roberta base squad)。

我的有效解决方案总结

  • 预处理 (preprocess)
    当我使用预处理时,分数从 0.712 提升到了 0.717。
  • 伪标签 (pseudo labeling)
    当我使用伪标签时,分数从 0.717 提升到了 0.720。伪标签应该使用更高的学习率,并通过三个模型的投票来生成标签。我的基础模型学习率是 2e-5,当使用带标签数据时,变为 4e-5。
  • 后处理 (postprocess)
    当我使用后处理时,分数从 0.720 提升到了 0.729。

后处理代码

def get_orgin_tweet_idx(origin_tweet, selected_text):

    selected_text = selected_text.strip()
    selected_start = selected_text.split()[0]
    for num, i in enumerate(origin_tweet):
        if origin_tweet[num:num + len(selected_start)] == selected_start:
            if ' '.join(origin_tweet[num:].split())[:len(selected_text)] == selected_text:
                return num

def get_pp_result5(orign_tweet, selected_text):
    selected_text = selected_text.strip()
    standard_orig_text = ' '.join(orign_tweet.split())
    standard_selected_text = ' '.join(selected_text.split())
    if standard_orig_text == standard_selected_text:
        return selected_text

    if selected_text == None or selected_text.strip() == '':
        return orign_tweet
    idx = get_orgin_tweet_idx(orign_tweet, selected_text)

    if idx == None:
        return orign_tweet

    if idx == 0:
        return selected_text

    if selected_text[-1].isalpha():
        selected_text = selected_text + ' '
    else:
        if selected_text.endswith('.') and orign_tweet[0] == ' ':
            lst = selected_text.split()[-1]
            tp_idx = -2
            for sst in range(len(lst) - 1, -1, -1):
                if lst[sst] == '.':
                    tp_idx = sst

            if tp_idx != 0:
                selected_text = ' '.join(selected_text.split()[:-1] + [selected_text.split()[-1][:tp_idx + 1]])

        else:
            selected_text = selected_text

    if orign_tweet[idx - 1] == ' ':
        selected_text = ' ' + selected_text

    if orign_tweet[:idx - 1].split(' ').count('') < 2:

        if orign_tweet[:idx - 1].split(' ').count('') == 1 and orign_tweet[idx - 1] == '.':
            return '.' + selected_text.strip()
        return selected_text

    else:
        if orign_tweet[idx - 1] == '.':
            selected_text = '.' + selected_text.strip()
        selected_text = orign_tweet[idx - 1 - (orign_tweet[:idx - 1].split(' ').count('') - 1):idx - 1] + selected_text
        selected_text = selected_text[:len(selected_text) - (orign_tweet[:idx - 1].split(' ').count('') - 1)]
        return selected_text

如有任何问题,您可以联系我,我愿意交流和学习。

同比赛其他方案