文本数据增强
概述
数据增强技术已经是图像领域的标配,通过对图像的翻转、旋转、镜像、高斯白噪声等技巧实现数据增强。对图像数据的增强不仅方法多种多样,而且像keras
框在做数据预处理的时候已经集成了一些数据增强的方法可以直接调用。
相较于图像数据增强,文本数据增强,现在还是有很多问题的。往更严格的角度看,文本数据增强更像是同义句生成,但又不完全是,它是一个更大范围的概念。很多时候,需要文本数据增强,一个是常常遇到的数据不足,另一个就是数据不均衡。大方向上看,文本的数据增强有几种方式,EDA
、Back Translation
、生成对抗网络
、语境增强
。
EDA
ICLR 2019 workshop 论文《EDA: Easy Data Augmentation Techniques for Boosting Performance on Text Classification Tasks》介绍了几种NLP数据增强技术,并推出了EDA github代码。EDA github repo
提出了四种简单的操作来进行数据增强,以防止过拟合,并提高模型的泛化能力。其实就是EDA
的四种形式。
同义词替换(SR: Synonyms Replace)
不考虑
stopwords
,在句子中随机抽取n个词,然后从同义词词典中随机抽取同义词,并进行替换。
def synonym_replacement(words, n):
new_words = words.copy()
random_word_list = list(set([word for word in words if word not in stop_words]))
random.shuffle(random_word_list)
num_replaced = 0
for random_word in random_word_list:
synonyms_word = get_synonyms(random_word)
if len(synonyms_word) >= 1:
synonym = random.choice(synonyms_word)
new_words = [synonym if word == random_word else word for word in new_words]
num_replaced += 1
if num_replaced >= n:
break
sentence = ' '.join(new_words)
new_words = sentence.split(' ')
return new_words
def get_synonyms(word):
return synonyms.nearby(word)[0]
input: 我要像风一样自由
output: ['我要 像 风 一样 受限制', '我要 像 风 一样 公民权利', '我要 像 和风 一样 自由']
随机插入(RI: Randomly Insert)
不考虑
stopwords
,随机抽取一个词,然后在该词的同义词集合中随机选择一个,插入原句子中的随机位置。该过程可以重复n次。
def random_swap(words, n):
new_words = words.copy()
for _ in range(n):
new_words = swap_word(new_words)
return new_words
def swap_word(new_words):
random_idx_1 = random.randint(0, len(new_words) - 1)
random_idx_2 = random_idx_1
counter = 0
while random_idx_2 == random_idx_1:
random_idx_2 = random.randint(0, len(new_words) - 1)
counter += 1
if counter > 3:
return new_words
new_words[random_idx_1], new_words[random_idx_2] = new_words[random_idx_2], new_words[random_idx_1]
return new_words
input: 我要像风一样自由
output: ['我要 像 和风 风 一样 自由', '我要 像 风 公民权利 一样 自由', '我要 像 风 风 一样 自由']
随机交换(RS: Randomly Swap)
句子中,随机选择两个词,位置交换。该过程可以重复n次。
def random_swap(words, n):
new_words = words.copy()
for _ in range(n):
new_words = swap_word(new_words)
return new_words
def swap_word(new_words):
random_idx_1 = random.randint(0, len(new_words) - 1)
random_idx_2 = random_idx_1
counter = 0
while random_idx_2 == random_idx_1:
random_idx_2 = random.randint(0, len(new_words) - 1)
counter += 1
if counter > 3:
return new_words
new_words[random_idx_1], new_words[random_idx_2] = new_words[random_idx_2], new_words[random_idx_1]
return new_words
input: 我要像风一样自由
output: ['我要 一样 风 像 自由', '我要 风 像 一样 自由', '我要 像 自由 一样 风']
随机删除(RD: Randomly Delete)
句子中的每个词,以概率p随机删除。
def random_deletion(words, p):
if len(words) == 1:
return words
new_words = []
for word in words:
r = random.uniform(0, 1)
if r > p:
new_words.append(word)
if len(new_words) == 0:
rand_int = random.randint(0, len(words) - 1)
return [words[rand_int]]
return new_words
input: 我要像风一样自由
output: ['我要 像 风 自由', '我要 像 风 一样 自由', '我要 像 一样 自由']
Back Translation
回译(Back Translation)
是机器翻译中非常常用的数据增强的方式,其主要的思想就是通过翻译工具将一个句子翻译为另一种语言,再把这翻译的另一种语言再翻译为原来的语言,最后得到一个意思相近但表达方式不同的句子。这种方式也是目前相对靠谱的方式,这种方式不仅有同义词替换,词语增删,还具有对句子结构语序调整的效果,并还能保持与原句子意思相近,是目前一种非常有效的文本数据增强方式。
生成对抗网络
随着深度学习的发展,这几年生成对抗网络模型(GAN)以及它的各种变形
,通过生成器和判别器的相互博弈,以达到一个****纳什平衡,不断迭代增强训练数据达到以假乱真的效果,最后用生成器大量生成同分布的数据,以达到数据增强的效果。但是GAN模型比较难训练,所以需要对GAN模型训练的足够好,才能更加有效的生成高质量的数据。