这一章我们不聊模型来聊聊数据,解决实际问题时90%的时间其实都是在和数据作斗争,于是无标注,弱标注,少标注,半标注对应的各类解决方案可谓是百花齐放。在第二章我们也尝试通过多目标对抗学习的方式引入额外的NER样本,或者分词边界来提高people daily小样本数据集的效果。
以下我会结合一些业界的案例和新鲜出炉的NLP数据增强综述,聊聊都有哪些数据增强方案,其中哪些适用于NER以及效果提升。代码详见 people_daily_augment
NLP数据增强综述
Paper:Data Augmentation Approaches in Natural Language Processing: A Survey
Blog:https://amitness.com/2020/05/data-augmentation-for-nlp/
数据增强可以分成三大类Paraphrasing, Nosing和Sampling,以下我们按类别分别介绍下各类的实现方案
方案一 Paraphrasing
目标:在尽可能保留句子整体语义的情况下,增加文本丰富度,包括让每个词拥有更加丰富的上下文context,让相似的语义表达有更多样的语法构成,词汇构成等等
方案 | 粒度 | 丰富度 | 使用成本 |
---|---|---|---|
同义词词林 | 词 | 低 | 低 |
词向量 | 词 | 中 | 低 |
语言模型 | 词 | 高 | 中 |
规则 | 词 | 低 | depends |
翻译 | 任意 | 高 | 高 |
生成 | 任意 | 高 | 高 |
同义词词林
基于词典中严格同义词的定义,对句子中非stopword的词汇进行随机替换,覆盖比较有限,但准确率很高。 中文同义词库
词向量
选择和当前文本预料相似的预训练词向量(word2vec/glove/fasttext etc),来生成most_similar词作为替换词,替换粒度可以是词,可以是字,可以是mix,取决于你使用的词向量本身的分词粒度。丰富度和覆盖率都比以上词典更高,这里的相似词是指上下文相似的词汇,对词性,实体类型等语法特征没有严格约束,所以在序列标注问题中需要小心使用。
语言模型
以上词典和向量都局限于词袋模型,无法解决一词多义的ambiguity问题。使用预训练语言模型做完形填空,可以基于上下文对随机MASK的部分进行生成。粒度可以是单词,也可以是long span,生成的文本丰富程度更高。不过也需注意因为丰富程度高,所以要控制句子中被替换的文本占比,占比过高会导致整个语义发生变化。
规则
哈哈规则这里其实是最能搞事情的,其实尤其是针对中文,多用于特殊业务场景(搜索/对话等等),以及垂直领域 中文缩写库,医学等领域词典
- 领域词典:例如医学,电力工程都有类似的比赛用利用领域内同义词典来进行样本增强
- 简写/缩写<->完整单词: yyds—>永远的神,哈工大<->哈尔滨工业大学
- 上下位词替换:手机价格->华为手机价格
- 英文特有的,否定句的多种写法,主动句变被动句等等
以上四种方案都在词粒度进行文本增强,会遍历句子中的每个词,有p的概率对该词进行替换,每个原始样本生成N个新样本。因为保留了原始句子的句法语法结构,应用场景相对广泛,对局部建模的序列标注问题以及全局建模的文本分类问题都适用。下面的两种方案会直接从句子整体进行改写,所以不适用于序列标注类任务。
回译
把原始样本语言翻译成另一种语言,再翻译回来,如果和原始输入不同则算一个增强的新样本。好处是保证了语义的一致性,以及语法的正确性。不过因为句子整体变化所以不适用于所有对局部建模的任务,例如关系抽取,序列标注等。
文本生成
直接用seq2seq,生成训练样本的同义表达。这个方法需要依赖额外的训练样本,来训练生成模型,和以上方案相比这个方案成本最高,虽然文本丰富程度最高,但不确定性也最高,所以。。。你懂的。。。
方案二 Noising
目标:增加模型稳健性,在不过多影响training error的前提下,降低模型的复杂度从而降低generalization error, 类比dropout,l2,random noise injection,etc
换位
对文本中,任意两个词,span,句子,段落进行位置交换得到新的文本。这个方法尤其适用于分类任务,因为多数分类任务语序信息并不十分重要。但是在序列标注任务中,因为局部label强依赖于周围信息,因此词粒度swapping可能会造成更严重的边界问题,更推荐在更大粒度进行shuffle,例如句子之间进行shuffle。
删除
中文删除需要考虑你的模型输入粒度,如果输入粒度是词,则按照词粒度进行随机删除,避免因为删除带来更多的OOV。当然对长文本也可以在句子,段落级别进行删除。对于序列标注任务,最好对整个Span粒度进行删除,避免影响实体label,以及label周边信息。例如存在实体'北京民政局',这时如果对‘民政局’进行随机删除,会改变'北京'的标签,如果删除实体周边词,可能会导致边界识别不准。
插入
最初在EDA中insertion是随机在句子中选择一个非stop words的词,把该词的同义词随机插入到句子中,增强相关信息。也有一些其他场景的改良操作
- 对长文本分类任务,可以把相同标签的其他文档中的句子随机抽取插入到当前文档任意位置
- 对UGC文本,可以尝试随机插入语气词,来增加口语化表达程度
替换
这里和上述的同义词替换不同,替换的并非同义词,需要按照使用场景设计替换方式。
例如搜索场景,针对用户键盘输入的typo,看到过的增强方式有
- 谐音字替换: de 的 地 得 德 嘚 徳 谐音词库
- 常见错别字替换: 高梁-高粱 pycorrector 中文文本纠错工具。音似、形似错字,中文拼音、笔画输入法的错误纠正
- 中文<->拼音(全写/缩写):xingfu-幸福, sz-深圳
- 英文字母键盘上相邻字母的替换
对实体抽任务,可以对同类型的实体进行替换,这里可以用当前样本的训练集构建实体词典,也可以用额外的实体词库,或者挖掘得到的领域词库。
Mixup
从图像领域的mixup衍生而来,和以上的方案都不尽相同,不对文本进行增强,而是对向量空间进行融合。原始图像的mixup在实验中发现对原始图片输入进行mixup效果最好,在文本领域,对原始输入的词向量,或者Encoder输出的文本向量进行融合,都有类似的尝试。
mixup会按一定比例对两个样本的向量空间求和,同时对label进行融合。把label融合这里有一点难理解,其实模型实现还是对融合的两个label各自计算cross-entropy,再对loss进行加权,只不过这个计算等价于下面写的对label进行融合,从one-hot变成带权重的multi-hot。
[begin{align} x &= lambda * x_i (1- lambda) * x_j \ y &= lambda * y_i (1 -lambda) * y_j \ end{align} ]
mixup确实比较黑盒,让人难以理解它为啥会work,不过看到过一个观点感觉比较有束缚里
提高模型泛化能力的一个方式,就是在训练样本没有覆盖的空间上控制模型的复杂程度,mixup通过插值,在训练样本没有覆盖的空间上让模型学到一个简单线性插值的函数
当然对比上面的数据增强方式,都在单一label内部进行增强,mixup是唯一一个对多label进行融合数据增强方案
方案三 Sampling(基于任务的样本生成)
以上两种方案是Task Independent,可以直接用于任何任务,而Sampling是任务依赖的,需要基于当前样本训练模型或者制定挖掘规则。
规则
paper中给的规则主要还是基于文本的,实际应用中有不少基于用户行为的规则挖掘。举几个