本文共 4073 字,大约阅读时间需要 13 分钟。
当前的模型基本求解的是数据集,而非任务,所以数据显得异常重要。
图像中可以通过旋转、翻转变换、rgb转灰度、加入白噪声等方式增强数据,其语义不会发生改变,但是NLP中却往往发生语义改变,针对NLP的一些数据增强方法进行了探索。
应该是最早的方法, 通过对于语句中的同义词替换,保证语义不变性,根据同义词的来源,又可以分为几种方案
通过WrodNet中的同义词召回相近似的词语,见
import nltkfrom nltk.corpus import wordnetnltk.download('omw')word = "空调"for each in wordnet.synsets(word, lang='cmn'): print(each.lemma_names('cmn'), )# ['冷气机', '空调', '空调器', '空调装置', '空调设备']
全量代码见:
是一个中文近义词工具包,见
import synonymsword = "空调"print(synonyms.nearby(word))# (['空调', '冷气', '空调设备', '空调系统', '波箱', '用车', '制冷', '空调机', '空气调节', '巴士在'], [1.0, 0.75175405, 0.7452018, 0.6877022, 0.6544307, 0.62812567, 0.62259305, 0.59779996, 0.57414114, 0.5611771])
全量代码见:
词向量召回主要通过将词语映射为低纬稠密向量,通过向量召回的方式来召回同义词。
from gensim.models.keyedvectors import KeyedVectorsword = "空调"# 词向量召回,词向量下载: https://docs.qq.com/sheet/DVnpkTnF6VW9UeXdh?tab=BB08J2w2v_file = "./cn_bi_fastnlp_100d.txt"w2v_model = KeyedVectors.load_word2vec_format(w2v_file)print(w2v_model.similar_by_word(word)[:10])# [('冷气', 0.832690954208374), ('暖气', 0.7806607484817505), ('电扇', 0.7694630026817322), ('电热', 0.7415034174919128), ('风扇', 0.7370954751968384), ('供暖', 0.7363734841346741), ('采暖', 0.7239724397659302), ('电暖', 0.7215089797973633), ('通风', 0.7174738645553589), ('隔音', 0.7118726968765259)]
全量代码见:
TF表示词条在文档d中出现的频率,IDF表示逆向文件频率
TF-IDF分数较低的单词不能提供信息,因此可以在不影响句子的ground-truth的情况下替换/插入它们。
原始句子:The quick brown fox jumps over the lazy dog
Tf-Idf替换:A quick brown fox jumps over the lazy dog
Tf-Idf插入:sinks The quick brown fox jumps over the lazy Sidney dog
依赖于本身语料足够丰富。
源码:
提出了数据增强方法:
synonym replacement(SR):随机选取句子中n个非停用词的词语。对于每个词语随机选取它的一个同义词替换该词语。
random insertion(RI):随机选取句子中的一个非停用词的词语,随机选取这个词语的一个近义词,将近义词随机插入到句子中,做n次。
random swap(RS):随机选取两个词语,交换他们的位置,做n次。
random deletion(RD):对于句子中的每个词语,以概率p选择删除。
同义词替换已有,其他三个方法,说实话,可用性不高,里面会生成很多错误的query。
由于随机替换、交换、删除会让原本序列化的句子的序列变得不重要,模型更关注某些词语是否出现,增加模型误识别风险。
更多细节参考
作者也开源了英文EDA代码:https://github.com/jasonwei20/eda_nlp
中文EDA:https://github.com/zhanlaoban/EDA_NLP_for_Chinese
看过很多奇奇怪怪的生成方法,有seq2seq(, , )、VAE(,)等方法,个人觉得和任务耦合,不太具备通用性,反倒是借助语言模型来做生成比较靠谱。
主要参考,通过Bi-LSTM训练语言模型,并且加入了数据label来控制生成。
,在前文基础上引入了BERT。
针对分类问题,作者将BERT原来的segment embedding换成了label embedding,然后在数据上继续使用MLM任务继续finetune, 训练好之后预测过程输入包含:
针对中文数据,笔者认为其实还可以做基于此可以在做一些优化。
基于此咱们就来尝试一把,对于原始输入,使用了此方法之后增强的数据:
原始句子:帮我查一下航班信息
生成句子:请帮我查一下航班信息、帮我查查一下航班信息、帮我查帮一下航班信息
代码见:
与其生产句子,不如从已有的语料中挖掘可能相关的数据。
从Twitter中挖掘日志,作者用聚类的方法标注出相似的数据,做一遍预标注,然后通过人工标注其中每个类簇的类别。
聚类方法中,聚类个数设置,聚类结果需要合并或拆分,之后结果再人工review。
这篇文章也提出了使用word2vec来召回同义词,做同义词替换。
通过将目标句子翻译为外语,然后将外语翻译成中文,翻译一般会重新组织句子结构,所以增强后的数据具备一定的句式丰富性,下面是使用了的结果。
if __name__ == '__main__': queries = '帮我查一下航班信息,查一下航班信息,附近有什么好玩的'.split(",") # 根据语言列表,可以翻译成多个句子, language: en,jp,kor,fra,spa,th,ara,ru,pt,de,it,el,nl,pl,bul,est,dan,fin,cs,rom,slo,swe,hu,cht,vie... for query in queries: out_arr = [] lan_list = "en,jp,kor".split(",") for tmp_lan in lan_list: for tmp_q in baidu_translate(query, tmp_lan): out_arr.extend(baidu_translate(tmp_q, 'zh')) print(list(set(out_arr))) # ['帮我查一下航班信息', '请帮我查一下飞机的情报。', '帮我检查航班信息。', '检查我的航班信息。'... # ['打听一下航班的信息。', '检查航班', '检查VOO信息', '查看航班信息', ... # ['这里有什么有趣的?', '这里有什么有趣的', '这个地方有什么有趣的?', ...
完整代码见:
提出,主要是应用于分类问题,应用于图像中,将两幅图片随机按照比例组合合成为新的图片。
将其应用于NLP之中。
即词向量上混合,将句子padding为相同的长度,然后将每个token的embedding按比例加权和为新的embedding用于下游分类,标签也是两个句子的标签比例。如下图左边
即句子向量混合,将句子向量随机加权求和,标签也是原始两个句子的标签加权。如上图右边
https://github.com/makcedward/nlpaug
https://github.com/QData/TextAttack
https://amitness.com/2020/05/data-augmentation-for-nlp/
https://towardsdatascience.com/data-augmentation-in-nlp-2801a34dfc28
工具:
转载地址:http://dxaji.baihongyu.com/