【关于 EDA 】那些你不知道的事

DayNightStudy

共 5957字,需浏览 12分钟

 ·

2021-08-22 19:18

作者:杨夕

面筋地址:https://github.com/km1994/NLP-Interview-Notes

个人笔记:https://github.com/km1994/nlp_paper_study

个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。

【注:手机阅读可能图片打不开!!!】


目录


一、动机篇

1.1 什么是 数据增强?

数据增强 是通过采用一些策略 增加 训练样本的数据量,提高模型的训练效果。

1.2 为什么需要 数据增强?

在医疗、金融、法律等领域,高质量的标注数据十分稀缺、昂贵,我们通常面临少样本低资源问题。

二、常见的数据增强方法篇

2.1 词汇替换篇

2.1.1 什么是基于词典的替换方法?

  • 介绍:基于同义词替换的方法是从句子中以一定的概率随机选取一个单词,利用一些同义词数据库(注:英文可以用 WordNet 数据库,中文可以用 synonyms python 同义词词典) 将其替换成对应的同义词。

  • 举例说明:


注:对 句子 “我 喜欢 NLP ” 随机选取 其中一个词 利用 synonyms 包进行替换,可以替换为 “我 喜爱 NLP ”。

2.1.2 什么是基于词向量的替换方法?

  • 介绍:通过利用预先训练好的词向量(eg:Word2Vec、GloVe、FastText等),使用嵌入空间中最近的相邻单词替换句子中的某些单词。

  • 思路:

  1. 预先训练好的词向量(eg:Word2Vec、GloVe、FastText等);

  2. 使用嵌入空间中最近的相邻单词,如下图,在嵌入空间中,与词 “awesome” 最近的相邻单词为 amazing、perfect等


  1. 随机选取三个 与 词 “awesome” 最相近的单词替换 词 “awesome”,如下图:

  • 实现:

    import synonyms
# 功能:同义词替换,替换一个语句中的n个单词为其同义词
def synonym_replacement(words, alpha, num_words, stop_words):
n = max(1, int(alpha * num_words))
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 = get_synonyms(random_word)
if len(synonyms) >= 1:
synonym = random.choice(synonyms)
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

# 功能:获取与 word 最相近的同义词
def get_synonyms(word):
return synonyms.nearby(word)[0]

2.1.3 什么是基于 MLM 的替换方法?

  • 介绍:像BERT、ROBERTA和ALBERT这样的Transformer模型已经接受了大量的文本训练,使用一种称为“Masked Language Modeling”的预训练,即模型必须根据上下文来预测遮盖的词汇。这可以用来扩充一些文本。例如,我们可以使用一个预训练的BERT模型并屏蔽文本的某些部分。然后,我们使用BERT模型来预测遮蔽掉的token。

使用mask预测来生成文本的变体。与之前的方法相比,生成的文本在语法上更加连贯,因为模型在进行预测时考虑了上下文。

  • 实现:

注:使用开源库这很容易实现,如Hugging Face的transformers。你可以将你想要替换的token设置为并生成预测。

    from transformers import pipeline
nlp = pipeline('fill-mask')
nlp('This is <mask> cool')
[{'score': 0.515411913394928,
'sequence': '<s> This is pretty cool</s>',
'token': 1256},
{'score': 0.1166248694062233,
'sequence': '<s> This is really cool</s>',
'token': 269},
{'score': 0.07387523353099823,
'sequence': '<s> This is super cool</s>',
'token': 2422},
{'score': 0.04272908344864845,
'sequence': '<s> This is kinda cool</s>',
'token': 24282},
{'score': 0.034715913236141205,
'sequence': '<s> This is very cool</s>',
'token': 182}]

注:这种方法的一个问题是,决定要屏蔽文本的哪一部分并不是一件小事。你必须使用启发式的方法来决定掩码,否则生成的文本将不保留原句的含义。

2.1.4 什么是基于 TF-IDF 的词替换?

  • 动机:对于 query 里面 TF-IDF 值较小的词语,一般对 query 的贡献度较少

  • 基本思想:针对 TF-IDF值较低的词语贡献度低问题,所以在不影响句子所属类别的情况下替换,可以达到数据增强的作用。

2.2 词汇插入篇

2.2.1 什么是随机插入法?

  • 方法:通过在 query 里面随机插入一个或多个新词汇、相应的拼写错误、符号等噪声的方式提高 训练模型的健壮性。

  • 代码实现:

    import random
import synonyms
# 功能:随机插入,随机在语句中插入n个词
def random_insertion(words, alpha, num_words, stop_words):
n = max(1, int(alpha * num_words))
new_words = words.copy()
for _ in range(n):
self.add_word(new_words)
return new_words

# 功能:插入新词
def add_word(new_words):
synonyms = []
counter = 0
while len(synonyms) < 1:
random_word = new_words[random.randint(0, len(new_words)-1)]
synonyms = get_synonyms(random_word)
counter += 1
if counter >= 10:
return
random_synonym = random.choice(synonyms)
random_idx = random.randint(0, len(new_words)-1)
new_words.insert(random_idx, random_synonym)

# 功能:获取同义词
def get_synonyms(word):
return synonyms.nearby(word)[0]

2.3 词汇交换篇

2.3.1 什么是随机交换法?

  • 方法:通过在 query 里面随机交换一个或多个词汇的方式提高 训练模型的健壮性。

  • 代码实现:

    import random
# 功能:随机交换:随机交换句子中的两个词
def random_swap(words, alpha, num_words, stop_words):
n = max(1, int(alpha * num_words))
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

2.4 词汇删除篇

2.4.1 什么是随机删除法?

  • 方法:通过在 query 里面随机删除一个或多个词汇的方式提高 训练模型的健壮性。

  • 代码实现:

    import random
# 功能:随机删除,以概率p删除语句中的词
def random_deletion( words, alpha, num_words, stop_words):
if len(words) == 1:
return words
new_words = []
for word in words:
r = random.uniform(0, 1)
if r > alpha:
new_words.append(word)
if len(new_words) == 0:
rand_int = random.randint(0, len(words)-1)
return [words[rand_int]]
return new_words

2.5 回译篇

2.5.1 什么是回译法?

  • 方法:利用百度翻译、谷歌翻译等在线翻译器来解释文本,并重新训练文本;

  • 思路:

  1. 将待数据增强的句子(如中文句子)翻译成另外一种语言,如英语、日语等;

  2. 然后将翻译后的句子回译回中文句子;

  3. 检查新句子是否与原来的句子不同。如果是,那么我们使用这个新句子作为原始文本的数据增强。


2.6 交叉增强篇

2.6.1 什么是 交叉增强篇

  • 方法:借鉴遗传学中染色体交叉操作的方式进行数据增强。

  • 思路:将 tweets 切分未为两部分,两个具有相同极性的随机推文(即正面/负面)进行交换。这个方法的假设是,即使结果是不符合语法和语义的,新文本仍将保留情感的极性。

  • 实验结果分析:这一技术对准确性没有影响,但有助于论文中极少数类的F1分数,如tweets较少的中性类。

2.7 语法树篇

2.7.1 什么是语法树操作?

  • 思路:这项技术已经在Coulombe的论文中使用。其思想是解析和生成原始句子的依赖关系树,使用规则对其进行转换,并生成改写后的句子。

  • 举例说明:在不改变句子的含义的情况下将句子从主动转化为被动语态的方式,也是一种数据增强方式。

  • 实现方式:要使用上述所有方法,可以使用名为nlpaug的python库:https://github.com/makcedward/nlpaug。它提供了一个简单且一致的API来应用这些技术。

2.8 对抗增强篇

2.8.1 什么是对抗增强?

  • 方法:NLP中通常在词向量上添加扰动并进行对抗训练,文献[10]NLP中的对抗训练方法FGM, PGD, FreeAT, YOPO, FreeLB等进行了总结。

参考

  1. NLP中数据增强的综述,快速的生成大量的训练数据

  2. NLP中的少样本困境问题探究


浏览 22
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报