热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

NLP简单的数据增强方法

NLP简单的数据增强方法当训练数据量不充分,或者分布单一的情况下,数据增强可以快速扩充语料以避免过拟合的问题,同时,数据增强
NLP简单的数据增强方法

  当训练数据量不充分,或者分布单一的情况下,数据增强可以快速扩充语料以避免过拟合的问题,同时,数据增强也可以提升模型的鲁棒性,避免微弱的变化使得模型无法泛化到相似的语境中。
  本文介绍几种比较简单但常用的NLP数据增强方法,包括显式和隐式两个方面,在实验或比赛中可以提升效果。可使用nlpaug工具快速实现这些技术。



一、动机


  • 机器学习和深度学习在包括文本分类等自然语言任务达到不错的效果,但他们需要依赖于大规模的标注数据,除了直接使用小样本学习外,显式数据增强格外有效;
  • 数据增强在计算机视觉中得以应用,其可以在数据量很少的情况下提升模型的鲁棒性;而在NLP中,通用的文本类型的数据增强还没有完全被挖掘出来;

二、显式数据增强

  给定一个输入文本,在尽可能不改变原是文本语义的情况下,微调或修改部分字符或词可以实现快速的增强,主要包括如下几种类型:

  • (1)同义词替换 (SR):随机挑选 nnn非停用词,分别根据其同义词表随机替换一个同义词;


对于分类、回归等任务,可以使用反义词表替换所有原始词性的词,实现负采样,也是一种数据增强方法。但使用同义词或反义词表进行替换时,很难保证文本的语义是否符合预期。


  • (2)随机插入 (RI):在句子中随机找到一个非停用词,并随机选择其对应的一个同义词,将该同义词插入句子中的随机位置。重复执行 nnn 次;
  • (3)随机交换 (RS):在句子中随机挑选两个词,并交换位置,重复执行 nnn 次;
  • (4)随机删除 (RD):对每个词,有一定概率 ppp 进行删除;
  • (5)标点插入 (PI):随机挑选若干位置,并分别随机插入标点符号;

  由于输入的文本长度长短不一,直觉上希望较长的句子 nnn 较大,因此通过一个参数 α\alphaα 控制,即 n=l×αn=l\times\alphan=l×α,对于RD,概率 p=αp=\alphap=α

  本文对标点插入 PI进行了实现,以中文为例,如下所示:

  • 借助Spacy分词工具,需要安装Spacy,使用Spacy进行分词、分析词性,根据分词和词性选择需要插入的标点。
  • 标点符号可以选择 ,。? !;“ ” 等。

import numpy as np
import spacy
import random
from typing import Dict
from tqdm import tqdmclass DataAugmentation:def __init__(self):self.nlp &#61; spacy.load(&#39;zh_core_web_sm&#39;)def fit(self, examples: Dict[str, list]):self.examples &#61; examples # {&#39;text&#39;: [], &#39;label&#39;: [], &#39;id&#39;: []}# 简单的数据增强&#xff1a;增加标点符号text_list &#61; self.examples[&#39;text&#39;]label_list &#61; self.examples[&#39;label&#39;]id_list &#61; self.examples[&#39;id&#39;]aug_text_list, aug_label_list, aug_id_list &#61; [], [], []pun &#61; [&#39;&#xff0c;&#39;, &#39;。&#39;, &#39;&#xff1f;&#39;, &#39;&#xff01;&#39;, &#39;&#xff1b;&#39;, &#39;"&#39;]for ei in tqdm(range(len(text_list))):text &#61; text_list[ei]label &#61; label_list[ei]id &#61; label_list[ei]doc &#61; self.nlp(text) # spacy分词token_list, pos_list &#61; [], []for token in doc:token_list.append(token.text)pos_list.append(token.pos_)if len(token_list) - 1 >&#61; 1:num &#61; 0state &#61; Falsewhile num < 5:num &#43;&#61; 1insert_position &#61; random.randint(1, len(token_list) - 1)if token_list[insert_position] in pun or token_list[insert_position - 1] in pun:continuetoken_list.insert(insert_position, &#39;&#xff0c;&#39;) # 随机插入一个标点符号pos_list.insert(insert_position, &#39;PUN&#39;) # 随机插入一个标点符号state &#61; Truebreakif state is True:augment_text &#61; &#39;&#39;.join(token_list)# print(&#39;origin text: {}&#39;.format(text))# print(&#39;augmen text: {}&#39;.format(augment_text))aug_text_list.append(augment_text)aug_label_list.append(label)aug_id_list.append(len(id_list) &#43; ei &#43; 1)return {&#39;text&#39;: text_list &#43; aug_text_list, &#39;label&#39;: label_list &#43; aug_label_list, &#39;id&#39;: id_list &#43; aug_id_list}if __name__ &#61;&#61; &#39;__main__&#39;:data_augmentation &#61; DataAugmentation()dataset &#61; {&#39;text&#39;: [&#39;今天的天气很好&#xff0c;非常适合去旅游。&#39;], &#39;label&#39;: [1], &#39;id&#39;: [0]}dataset &#61; data_augmentation.fit(dataset)print(dataset)

演示效果&#xff1a;
在这里插入图片描述

除了前述的几种方法&#xff0c;也可以采用如下几种新的策略&#xff1a;

  • &#xff08;6&#xff09;单词缩写、全写&#xff1a;例如可以建立一个词表&#xff0c;对所有存在简写的词进行替换&#xff0c;例如 It is可以替换为 It’s&#xff0c;England可替换为UK.等&#xff1b;
  • &#xff08;7&#xff09;错误拼写 &#xff08;WS&#xff09;&#xff1a;有时候为了提高鲁棒性&#xff0c;会故意将文本中的单词或字符使用错误拼写的单词或字符进行替换&#xff0c;在不影响语义的条件下引入少量噪声。例如 I like this book可以替换为 I like thes book。对于中文&#xff0c;也可以构建confusion set&#xff0c;替换字形或字音相似的词&#xff0c;例如“上海是经济中心”可以替换为“上海时经济中心”。但注意需要保证原始语义。
  • &#xff08;8&#xff09;统计特征 &#xff08;SF&#xff09; &#xff1a;通常很多词在大规模语料中具有一定的统计特征&#xff0c;例如TF-IDF、互信息量等。在使用TF-IDF和互信息量时&#xff0c;可选择值较小的进行随机替换。

三、隐式数据增强

  因为直接对原是文本进行数据增强&#xff0c;很难避免维持原始的文本语义&#xff0c;因此可以可以通过在语义空间上进行隐式数据增强&#xff0c;简单列出几种方法&#xff1a;

  • 词向量替换&#xff1a;通过word2vec或GloVe预训练的词向量获得相似的词&#xff0c;对于给定某个词&#xff0c;则可以直接随机选择相似的词的词向量进行替换&#xff1b;
  • 词向量的原型向量&#xff1a; 通过word2vec或GloVe预训练的词向量&#xff0c;可以通过对所有相似的词或token的embedding进行平均池化。一般认为语义相似的词在语义空间内会聚集在一起&#xff0c;因此其平均的词向量可以认为是这些相似语义词的原型向量&#xff08;prototype embedding&#xff09;&#xff0c;原型向量可以作为隐式增强表征&#xff1b;
  • Dropout&#xff1a; 在对文本使用RNN、CNN或BERT等进行表征后&#xff0c;得到融合上下文信息的embedding&#xff0c;可以采用随机dropout法。具体地说&#xff0c;假设一个embedding是 [0.1, 0.4, 0.2, -0.5]&#xff0c; 随机dropout旨在随机挑选一个元素替换为0&#xff0c;例如挑选第2个位置的元素替换为0&#xff0c;变为 [0.1, 0.0, 0.2, -0.5]。随机dropout参考了计算机视觉领域内对图像表征后的feature map进行mask的操作&#xff08;在语义特征上添加噪点&#xff09;以实现增强&#xff1b;
  • 语言模型 Masked Language Modeling&#xff08;MLM&#xff09;&#xff1a; MLM是BERT等预训练语言模型在大规模语料上自监督训练目标&#xff0c;其旨在随机挖掉一个文本中的token并让模型预测该词。由于大规模训练&#xff0c;使得模型可以预测出许多相似的结果&#xff0c;例如“I like this book because it is funny.”&#xff0c;我们可以让MLM生成与“funny”具有同等语义的词&#xff1a;


  • 机器翻译&#xff1a; 基于机器翻译的方法&#xff0c;将原始文本翻译为另一种语言&#xff0c;并再次进行回译。该方法比较类似计算机视觉中的自编码器。但该方法需要率先在领域数据上进行训练&#xff0c;且依赖于大量的平行语料&#xff0c;较为繁琐&#xff1b;
  • 文本生成&#xff1a; 基于生成的方法可以在不改变原始语义的前提下生成出上述无法显式构造的新文本。但基于生成的方法依然依赖于所属领域的训练数据。

如果需要增强的文本所属一个新的领域&#xff08;例如医疗、生物&#xff09;&#xff0c;基于翻译和生成的方法则需要先在该领域的相关语料上进行训练&#xff0c;得到较为鲁棒的翻译或生成模型。但数据增强又是为了增强数据量&#xff0c;没有充分又无法训练翻译或生成模型&#xff0c;产生矛盾。因此通常对新的领域或任务上不会首选这两种方法。


  • 对抗训练&#xff1a; 引入对抗样本实现数据增强&#xff0c;例如下图&#xff08;左&#xff09;是少量样本时学习的决策边界&#xff0c;对每个样本在一定范围内进行扰动攻击&#xff0c;使得在直观上无法辨别&#xff0c;但在语义空间内则会影响样本的决策&#xff0c;例如下图&#xff08;中&#xff09;&#xff0c;五角星则代表对抗样本。因此图&#xff08;右&#xff09;引入对抗训练目标以修改决策边界。通常对抗训练目标可以是对增强的样本伪造其标签以增强鲁棒性。


  • 对比学习&#xff1a; 如果样本少&#xff0c;那就尽可能学习这些样本之间的差异。对比学习旨在构建样本对来解决训练困难问题&#xff0c;因为构建了样本对&#xff0c;所以间接地增加了数据量。虽然对比学习最初目标不是为了数据增强&#xff0c;但可以通过添加对比学习loss来隐式地提升鲁棒性&#xff1b;
  • 自监督辅助任务&#xff1a; 如果目标NLP数据量少&#xff0c;那么可以直接引入大规模无监督语料&#xff08;例如Wikipedia&#xff09;&#xff0c;并在具体任务训练时添加辅助学习目标&#xff0c;通过语义层面上实现增强&#xff1b;

例如在进行文本分类任务上时&#xff0c;除了文本分类损失函数外&#xff0c;还可以添加类似MLM的辅助任务&#xff0c;或者添加额外的多任务信息


  • 知识图谱增强&#xff08;远程监督法&#xff09;&#xff1a; 远程监督可以快速地启发式构建大规模标注数据&#xff0c;目前在信息抽取任务上使用广泛&#xff0c;其旨在通过一个已有的知识图谱或规则来直接对无监督的语料进行标注&#xff0c;但远程监督方法容易引入大量噪声。

在关系抽取任务中&#xff0c;通过知识库中已有的三元组&#xff08;例如<乔布斯&#xff0c;创始人&#xff0c;苹果>&#xff09;&#xff0c;来标注一批新的实体对语料。但对于文本“乔布斯吃了一个苹果”而言&#xff0c;远程监督法依然会标注为“创始人”&#xff0c;但显然这是噪声。对于噪声&#xff0c;则可以通过一些规则&#xff0c;或Attention的方法解决。


  • 半监督方法&#xff1a; 半监督法旨在对少量有标签数据上进行训练&#xff0c;然后在无标签数据上进行推理&#xff0c;并获得高置信度的伪标签数据后&#xff0c;再进行训练。因此伪标签数据可以作为数据增强部分语料&#xff0c;但依然容易引入噪声。

对于噪声部分&#xff0c;则可以采用几种策略&#xff1a;&#xff08;1&#xff09;提高置信度阈值&#xff0c;&#xff08;2&#xff09;多个不同的模型共同预测伪标签&#xff0c;取全部预测正确的作为可信样本&#xff1b;&#xff08;3&#xff09;伪标签数据回测评估&#xff1a;如果加入伪标签的数据后效果变差&#xff0c;则需要剔除或更改标签。



参考文献&#xff1a;
【1】EDA: Easy Data Augmentation Techniques for Boosting Performance on Text Classification Tasks. (EMNLP2019)
【2】AEDA: An Easier Data Augmentation Technique for Text Classification. (EMNLP2021 Findings)
【3】开源NLP数据增强工具&#xff1a;https://github.com/makcedward/nlpaug&#xff0c;附加博客&#xff1a;https://towardsdatascience.com/data-augmentation-in-nlp-2801a34dfc28
【4】Data Augmentation Approaches in Natural Language Processing: A Survey
【5】哈工大总结的15个数据增强方法


推荐阅读
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 本文介绍了机器学习手册中关于日期和时区操作的重要性以及其在实际应用中的作用。文章以一个故事为背景,描述了学童们面对老先生的教导时的反应,以及上官如在这个过程中的表现。同时,文章也提到了顾慎为对上官如的恨意以及他们之间的矛盾源于早年的结局。最后,文章强调了日期和时区操作在机器学习中的重要性,并指出了其在实际应用中的作用和意义。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • WhenIusepythontoapplythepymysqlmoduletoaddafieldtoatableinthemysqldatabase,itdo ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • EPPlus绘制刻度线的方法及示例代码
    本文介绍了使用EPPlus绘制刻度线的方法,并提供了示例代码。通过ExcelPackage类和List对象,可以实现在Excel中绘制刻度线的功能。具体的方法和示例代码在文章中进行了详细的介绍和演示。 ... [详细]
author-avatar
谁的板砖在飞
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有