一. NLP介绍
1957年, 怛特摩斯会议
二. 文本预处理
文本预处理及作用
将文本转换成模型可以识别的数据
文本转化成张量(可以利用GPU计算), 规范张量的尺寸. 科学的文本预处理可以有效的指导模型超参数的选择, 提升模型的评估指标
文本处理形式
分词
词性标注
命名实体识别
三. 文本处理的基本方法
分词及工具使用
分词将连续的字序列按照实际业务需求规定重新组合成词序列的过程
英文中除特殊需求外, 一般用空格作为分界符即可
分词过程就是找到分界符的该过程
例如: 我爱中国
我 爱 中国 (这些词叫tocken(词源))
三种分词模式
import jieba # 精确模式 # 试图将句子最精确地切开,适合文本分析. sent = '门上别别别的别别别的, 非得别别的, 别上了吧' # 默认:精确模式, 返回的时迭代器 res = jieba.cut(sent, cut_all=False) print(res) # <generator object Tokenizer.cut at 0x00000237E71DB350> print(list(res)) # 直接返回列表 res1 = jieba.lcut(sent) # 等价于list(res) print('精确模式', res1) # 全模式: 返回句中所有可以组成的词 # 把句子中所有的可以成词的词语都扫描出来(按照时序), 速度非常快,但是不能消除歧义。 sent1 = '我也想过过过过过过的生活' res2 = jieba.lcut(sent1, cut_all=True) print('全模式', res2) # 搜索引擎模式: 精确模式的基础上 # 在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。 res3 = jieba.lcut_for_search(sent) print('搜索引擎模式:', res3)
两个提点
繁体分词
# 繁体分词 sent2 = '煩惱即是菩提,我暫且不提' print('繁体字', jieba.lcut(sent2)) sent2 = '长叹息以掩涕兮, 哀吾生之须臾' print('文言文', jieba.lcut(sent2))
自定义词典
-
使用用户自定义词典:
-
添加自定义词典后, jieba能够准确识别词典中出现的词汇,提升整体的识别准确率。
-
词典格式: 每一行分三部分:词语、词频(可省略)、词性(可省略),用空格隔开,顺序不可颠倒。
-
词典样式如下, 具体词性含义请参照jieba词性表, 将该词典存为userdict.txt, 方便之后加载使用。
# 用户自定义词典 # 1. 不加载, 分词sent res4 = jieba.lcut(sent) print('不加载词典:', res4) # 2. 加载, 分词sent jieba.load_userdict('./userdict.txt') res5 = jieba.lcut(sent, cut_all=Trur) # 全模式才会完整加载自定义词典 print('加载词典:', res5) print(jieba.lcut_for_search(sent))
命名实体NER
概念
属于信息抽取
命名实体识别(Named Entity Recognition,简称NER)就是识别出一段文本中可能存在的命名实体.
人名, 地名, 机构名, 时间, 日期, 货币, 百分比
示例:
鲁迅, 浙江绍兴人, 五四新文化运动的重要参与者, 代表作朝花夕拾. ==> 鲁迅(人名) / 浙江绍兴(地名)人 / 五四新文化运动(专有名词) / 重要参与者 / 代表作 / 朝花夕拾(专有名词)
命名实体识别的作用:
同词汇一样, 命名实体也是人类理解文本的基础单元, 因此也是AI解决NLP领域高阶任务的重要基础环节.
uie命名实体识别
github源地址: https://github.com/HUSTAI/uie_pytorch
实体抽取
>>> from uie_predictor import UIEPredictor >>> from pprint import pprint >>> schema = ['时间', '选手', '赛事名称'] # Define the schema for entity extraction >>> ie = UIEPredictor(model='uie-base', schema=schema) >>> pprint(ie("2月8日上午北京冬奥会自由式滑雪女子大跳台决赛中中国选手谷爱凌以188.25分获得金牌!")) # Better print results using pprint [{'时间': [{'end': 6,'probability': 0.9857378532924486,'start': 0,'text': '2月8日上午'}],'赛事名称': [{'end': 23,'probability': 0.8503089953268272,'start': 6,'text': '北京冬奥会自由式滑雪女子大跳台决赛'}],'选手': [{'end': 31,'probability': 0.8981548639781138,'start': 28,'text': '谷爱凌'}]}]
词性标注
概念
词性: 语言中对词的一种分类方法,以语法特征为主要依据、兼顾词汇意义对词进行划分的结果, 常见的词性有14种, 如: 名词, 动词, 形容词等.
顾名思义, 词性标注(Part-Of-Speech tagging, 简称POS)就是标注出一段文本中每个词汇的词性.
import jieba.posseg as pseg pseg.lcut("我爱北京天安门") [pair('我', 'r'), pair('爱', 'v'), pair('北京', 'ns'), pair('天安门', 'ns')] # 结果返回一个装有pair元组的列表, 每个pair元组中分别是词汇及其对应的词性, 具体词性含义请参照[附录: jieba词性对照表]()
jieba词性对照表
- a 形容词 - ad 副形词 - ag 形容词性语素 - an 名形词 - b 区别词 - c 连词 - d 副词 - df - dg 副语素 - e 叹词 - f 方位词 - g 语素 - h 前接成分 - i 成语 - j 简称略称 - k 后接成分 - l 习用语 - m 数词 - mg - mq 数量词 n 名词 ng 名词性语素 nr 人名 - nrfg - nrt ns 地名 nt 机构团体名 nz 其他专名 - o 拟声词 - p 介词 - q 量词 - r 代词 - rg 代词性语素 - rr 人称代词 - rz 指示代词 - s 处所词 - t 时间词 - tg 时语素 - u 助词 - ud 结构助词 得- ug 时态助词- uj 结构助词 的- ul 时态助词 了- uv 结构助词 地- uz 时态助词 着 - v 动词 - vd 副动词- vg 动词性语素 - vi 不及物动词 - vn 名动词 - vq - x 非语素词 - y 语气词 - z 状态词 - zg
hanlp词性对照表
【Proper Noun——NR,专有名词】 【Temporal Noun——NT,时间名词】 【Localizer——LC,定位词】如“内”,“左右” 【Pronoun——PN,代词】 【Determiner——DT,限定词】如“这”,“全体” 【Cardinal Number——CD,量词】 【Ordinal Number——OD,次序词】如“第三十一” 【Measure word——M,单位词】如“杯” 【Verb:VA,VC,VE,VV,动词】 【Adverb:AD,副词】如“近”,“极大” 【Preposition:P,介词】如“随着” 【Subordinating conjunctions:CS,从属连词】 【Conjuctions:CC,连词】如“和” 【Particle:DEC,DEG,DEV,DER,AS,SP,ETC,MSP,小品词】如“的话” 【Interjections:IJ,感叹词】如“哈” 【onomatopoeia:ON,拟声词】如“哗啦啦” 【Other Noun-modifier:JJ】如“发稿/JJ 时间/NN” 【Punctuation:PU,标点符号】 【Foreign word:FW,外国词语】如“OK
三. 文本张量表示方法
介绍
原理
将一段文本使用张量进行表示,其中一般将词汇表示成向量,称作词向量,再由各个词向量按顺序组成矩阵形成文本表示.
["人生", "该", "如何", "起头"] 一个词就是一个tocken==># 每个词对应矩阵中的一个向量, 整个张量表示为词表 [[1.32, 4,32, 0,32, 5.2], # 一行就是一个词向量[3.1, 5.43, 0.34, 3.2],[3.21, 5.32, 2, 4.32],[2.54, 7.32, 5.12, 9.54]]
文本张量表示的作用
将文本表示成张量(矩阵)形式,能够使语言文本可以作为计算机处理程序的输入,进行接下来一系列的解析工作
one-hot词向量表示
原理
又称独热编码,将每个词表示成具有n个元素(词表长度)的向量,这个词向量中只有一个元素是1,其他元素都是0,不同词汇元素为0的位置不同,其中n的大小是整个语料中不同词汇的总数.
示例
["改变", "要", "如何", "起手"]` ==>[[1, 0, 0, 0],[0, 1, 0, 0],[0, 0, 1, 0],[0, 0, 0, 1]]
代码演示
import jieba import joblib from tensorflow.keras.preprocessing.text import Tokenizerdef one_hot_gen(sent):vocabs = list(set(sent))# 实例化Tokenizertockenizer = Tokenizer()tockenizer.fit_on_texts(vocabs)# 查看独热编码for vocab in vocabs:zero_idx = [0] * len(vocabs)idx = tockenizer.word_index[vocab] - 1zero_idx[idx] = 1print(vocab, '的独热编码是', zero_idx)# 保存映射joblib.dump(tockenizer, 'tokenizer.pkl')print('保存成功')# 查看tockenizerprint(tockenizer.word_index)print(tockenizer.index_word)one_hot_gen('两只黄鹂鸣翠柳, 一行白鹿上青天')
优缺点
-
优势:操作简单,容易理解.
-
劣势:完全割裂了词与词之间的联系,而且在大语料集下,每个向量的长度过大,占据大量内存, 维度爆炸.
-
正因为one-hot编码明显的劣势,这种编码方式被应用的地方越来越少,取而代之的是接下来我们要学习的稠密向量的表示方法word2vec和word embedding.
word2vec模型
介绍
word2vec是一种流行的将词汇表示成向量的无监督训练方法
, 该过程将构建神经网络模型, 将网络参数作为词汇的向量表示, 它包含CBOW和skipgram两种训练模式.
CBOW模式
又连续词袋模型
给定用于训练的语料, 选定某段长度作为窗口(研究对象), 用上下文预测目标值(中间tocken)
CBOW过程(word2vec)
假设我们给定的训练语料只有一句话: Hope can set you free (愿你自由成长),窗口大小为3,因此模型的第一个训练样本来自Hope can set,因为是CBOW模式,所以将使用Hope和set作为输入,can作为输出,在模型训练时, Hope,can,set等词汇都使用它们的one-hot编码. 如图所示: 每个one-hot编码的单词与各自的变换矩阵(即参数矩阵3x5, 这里的3是指最后得到的词向量维度)相乘之后再相加, 得到上下文表示矩阵(3x1).
接着, 将上下文表示矩阵与变换矩阵(参数矩阵5x3, 所有的变换矩阵共享参数)相乘, 得到5x1的结果矩阵, 它将与我们真正的目标矩阵即can的one-hot编码矩阵(5x1)进行损失的计算, 然后更新网络参数完成一次模型迭代.
最后窗口按序向后移动,重新更新参数,直到所有语料被遍历完成,得到最终的变换矩阵(3x5),这个变换矩阵与每个词汇的one-hot编码(5x1)相乘,得到的3x1的矩阵就是该词汇的word2vec张量表示.
skip-gram模式
又称跳词模型
给定一段用于训练的文本语料, 再选定某段长度(窗口)作为研究对象, 使用目标词汇预测上下文词汇.
skip-gram过程
假设我们给定的训练语料只有一句话: Hope can set you free (愿你自由成长),窗口大小为3,因此模型的第一个训练样本来自Hope can set,因为是skipgram模式,所以将使用can作为输入 ,Hope和set作为输出,在模型训练时, Hope,can,set等词汇都使用它们的one-hot编码. 如图所示: 将can的one-hot编码与变换矩阵(即参数矩阵3x5, 这里的3是指最后得到的词向量维度)相乘, 得到目标词汇表示矩阵(3x1).
接着, 将目标词汇表示矩阵与多个变换矩阵(参数矩阵5x3)相乘, 得到多个5x1的结果矩阵, 它将与我们Hope和set对应的one-hot编码矩阵(5x1)进行损失的计算, 然后更新网络参数完成一次模 型迭代.
最后窗口按序向后移动,重新更新参数,直到所有语料被遍历完成,得到最终的变换矩阵即参数矩阵(3x5),这个变换矩阵与每个词汇的one-hot编码(5x1)相乘,得到的3x1的矩阵就是该词汇的word2vec张量表示.
图解
原理总结
神经网络训练完毕后,神经网络的参数矩阵w就我们的想要词向量。如何检索某1个单词的向量呢?以CBOW方式举例说明如何检索a单词的词向量。
如下图所示:a的onehot编码[10000],用参数矩阵[3,5] * a的onehot编码[10000],可以把参数矩阵的第1列参数给取出来,这个[3,1]的值就是a的词向量。
word2vec训练及使用
import jieba import fasttext# 定义函数训练模型, 保存并测试加载 def dm_model_train_save():# 模型训练my_model = fasttext.train_unsupervised('./data/fil9')print('模型训练完成')# 保存模型my_model.save_model('./data/my_fil9.bin')print('模型保存完成')# 加载模型my_model = fasttext.load_model('./data/my_fil9.bin')print('模型加载完成')# 查看单词词向量 def dm_fasttext_get_word_vector(word):# 加载模型my_model = fasttext.load_model("./data/my_fil9.bin")# 获取指定词的词向量res = my_model.get_word_vector(word)# 输出词向量结果print('donkey的词向量是:', res)print('donkey的词向量类型是:', type(res)) # <class 'numpy.ndarray'>print('donkey的词向量形状是:', res.shape) # 默认是100维, (100,)# 检验模型效果, 查看目标词的临近词 def dm_fasttext_get_nearest(word):# 加载模型my_model = fasttext.load_model("./data/my_fil9.bin")# 获取目标词的临近词res = my_model.get_nearest_neighbors(word)# 输出临近词结果print(f'{word}的近义词是:', res)# 模型参数设置 def dm_fasttext_set_args():data_path = './data/fil9'my_model = fasttext.train_unsupervised(data_path,model='cbow',epoch=5,lr=0.1,dim=300,thread=13)print('模型训练完成')# 保存模型my_model.save_model('./data/my_new_fil9.bin')print('模型保存完成')# 加载模型my_model = fasttext.load_model('./data/my_new_fil9.bin')print('模型加载完成')if __name__ == '__main__':# dm_model_train_save()# dm_fasttext_get_word_vector('dog')# dm_fasttext_get_nearest('donkey')dm_fasttext_set_args()
词嵌入word embedding
word2vec与Embedding区别:
广义:
word2vec 先训练 --> 得到成熟的词向量 --> 下游任务
狭义:
nn.Embedding() 初始化数据是没有意义的, 伴随着下游任务, 一起得到训练
概念
原理
通过一定的方式将词汇映射到指定维度(一般是更高维度)的空间.
广义的word embedding包括所有密集词汇向量的表示方法,如之前学习的word2vec, 即可认为是word embedding的一种.
狭义的word embedding是指在神经网络中加入的embedding层, 对整个网络进行训练的同时产生的embedding矩阵(embedding层的参数), 这个embedding矩阵就是训练过程中所有输入词汇的向量表示组成的矩阵.
embedding可视化
代码
import jieba import torch import torch.nn as nn from torch.utils.tensorboard import SummaryWriter from tensorflow.keras.preprocessing.text import Tokenizerdef embedding_show():# 1. 获得语料sent1 = '我爱自然语言处理, 我也爱人工智能'sent2 = 'openai是一家致力于开源人工智能的科技公司'sents = [sent1, sent2]# 2. 对句子做分词word_listword_list = []for s in sents:word_list.append(jieba.lcut(s))print('word_list: ', word_list) # 有顺序的word_list# 3. 实例化Tokenizer# 会对分词后的词表做去重操作, 并且按照词频排序, 没有原始句子的顺序my_tockenizer = Tokenizer()my_tockenizer.fit_on_texts(word_list)print(my_tockenizer.word_index)print(my_tockenizer.index_word)# 4. 拿到所有的tockenmy_tocken_list = my_tockenizer.index_word.values()print('my_tocken_list: ', my_tocken_list) # 去重后的, 无序的tocken_list# 5. 打印句子id# 将句子中的tocken转换成在tocken_list(词表)中的id --> 文本数值化seq2id = my_tockenizer.texts_to_sequences(word_list)print('seq2id: ', seq2id)# 6. 拿到embedding矩阵 也叫查表矩阵embd = nn.Embedding(len(my_tocken_list), 8)print('embd.shape:', embd.weight.shape)print('embd.data:', embd.weight.data)# 7. 查询tocken vecfor idx in range(len(my_tocken_list)):word = my_tockenizer.index_word[idx + 1]vec = embd(torch.tensor(idx))print(word, ':', vec)# 8. 可视化logdir = r'./data/runs'writer = SummaryWriter(logdir)writer.add_embedding(embd.weight.data, my_tocken_list)writer.close()if __name__ == '__main__':embedding_show()
结果图
在文件资源管理器中打开刚生成的runs, 进入到cmd窗口, 输入:
tensorboard --logdir=runs --host 0.0.0.0
四. 文数据分析
介绍
文本数据分析作用
文本数据分析能够有效帮助我们理解数据语料, 快速检查出语料可能存在的问题, 并指导之后模型训练过程中一些超参数的选择.
常用文本数据分析方法
-
标签数量分布
-
句子长度分布
-
词频统计与关键词词云
获取标签数量分布
查看正负样本是否均衡
import seaborn as sns import pandas as pd import matplotlib.pyplot as plt # 获取标签数据分析 def dm_label_sns_countplot():# 1. 设置显示风格plt.style.use('fivethirtyeight') # 2. 读取数据train_data = pd.read_csv('cn_data/train.tsv', sep='\t')print(train_data.head())print(type(train_data))dev_data = pd.read_csv('cn_data/dev.tsv', sep='\t') # 3. 统计训练集的01标签, countplot条形图sns.countplot(x='label', data=train_data, hue='label')plt.title('train_data')plt.show() # 4. 统计devsns.countplot(x='label', data=dev_data, hue='label')plt.title('dev_data')plt.show() if __name__ == '__main__':dm_label_sns_countplot()
获取句子长度分布
绘制句子长度分布图, 可以得知我们的语料中大部分句子长度的分布范围, 因为模型的输入要求为固定尺寸的张量,合理的长度范围对之后进行句子截断补齐(规范长度)起到关键的指导作用. 图中大部分句子长度的范围大致为20-250之间.
# 获取句子长度分布 : 查看句子长度分布情况 def dm_len_sns_countplot():# 1. 设置显示风格plt.style.use('fivethirtyeight') # 2. 读取数据train_data = pd.read_csv('cn_data/train.tsv', sep='\t')dev_data = pd.read_csv('cn_data/dev.tsv', sep='\t') # 3. 添加一列句子长度train_data['sentence_length'] = list(map(lambda x: len(x), train_data['sentence']))print(train_data.head())dev_data['sentence_length'] = list(map(lambda x: len(x), dev_data['sentence']))print(dev_data.head()) print(train_data['sentence_length'].max())print(dev_data['sentence_length'].max()) # 4. 绘制图像 train# countplot 条形图, displot 直方图, kde=True密度曲线sns.countplot(x='sentence_length', data=train_data, hue='label')plt.title('train_data')plt.xticks([]) # 不显示x轴刻度plt.show() sns.displot(x='sentence_length', data=train_data, kde=True)plt.xticks([i for i in range(0, 8000, 1000)])plt.show() # 5. 绘制图像 devsns.countplot(x='sentence_length', data=dev_data, hue='label')plt.title('train_data')plt.show() sns.displot(x='sentence_length', data=dev_data, kde=True)plt.xticks([i for i in range(0, 1000, 200)])plt.show()
正负样本长度散点图
查看离群样本(异常样本)
# 获取正负样本长度散点图 : 查看异常样本(离群值) def dm_sns_stripplot():# 1. 设置显示风格plt.style.use('fivethirtyeight') # 2. 读取数据train_data = pd.read_csv('cn_data/train.tsv', sep='\t')dev_data = pd.read_csv('cn_data/dev.tsv', sep='\t') # 3. 添加一列句子长度train_data['sentence_length'] = list(map(lambda x: len(x), train_data['sentence']))print(train_data.head())dev_data['sentence_length'] = list(map(lambda x: len(x), dev_data['sentence']))print(dev_data.head()) # 绘制训练集散点图sns.stripplot(y='sentence_length', x='label', data=train_data, hue='label')plt.title('train_data')plt.show() # 绘制验证集散点图sns.stripplot(y='sentence_length', x='label', data=dev_data, hue='label')plt.title('dev_data')plt.show()
获取不同词汇总数统计
方便构建词表
# 获取词频分布 : 查看词频分布情况 def dm_words_count():# 1. 读取数据train_data = pd.read_csv('cn_data/train.tsv', sep='\t')dev_data = pd.read_csv('cn_data/dev.tsv', sep='\t') # 2. 获取train词语数量print(chain(*map(lambda x: jieba.lcut(x), train_data['sentence'])))print(map(lambda x: jieba.lcut(x), train_data['sentence'])) # 直接输出map对象print(type(chain(*map(lambda x: jieba.lcut(x), train_data['sentence']))))train_vocab = set(chain(*map(lambda x: jieba.lcut(x), train_data['sentence'])))print('训练集token数量: ', len(train_vocab)) # 12162 # 3. 获取dev词语数量dev_vocab = set(chain(*map(lambda x: jieba.lcut(x), dev_data['sentence'])))print('验证集token数量: ', len(dev_vocab)) # 6857
获取训练集高频形容词词云
# 获取训练集高频adj词云 # (1) 获取每个句子的adj的列表 def get_a_list(sentence):r = []for x in pseg.lcut(sentence):# x.flag表示词性; x.word表示具体的tokenif x.flag == 'a':r.append(x.word)return r # (2) 绘制词云 def get_word_cloud(keywords_list):# 1. 实例化词云对象my_wordcloud = WordCloud(font_path='./cn_data/SimHei.ttf', max_words=100, background_color='white') # 2. 准备数据a_str = ' '.join(keywords_list) # 3. 产生词云my_wordcloud.generate(a_str) # 4. 绘制图像plt.figure()plt.imshow(my_wordcloud, interpolation='bilinear')plt.axis('off')plt.show() # (3) 绘制训练集词云 def dm_word_cloud_train():# 1. 读取数据train_data = pd.read_csv('cn_data/train.tsv', sep='\t') # 2. 获取正样本数据p_train = train_data[train_data['label'] == 1]['sentence'] # 3. 获取全部数据的adj列表p_a_words = list(chain(*map(lambda x: get_a_list(x), p_train)))get_word_cloud(p_a_words) # 4. 获取负样本数据n_train = train_data[train_data['label'] == 0]['sentence'] # 5. 获取每个句子的adj列表, 绘制词云n_a_words = list(chain(*map(lambda x: get_a_list(x), n_train)))get_word_cloud(n_a_words) # 绘制验证集词云 def dm_word_cloud_dev():# 1. 读取数据dev_data = pd.read_csv('cn_data/dev.tsv', sep='\t') # 2. 获取正样本数据p_dev = dev_data[dev_data['label'] == 1]['sentence'] # 3. 获取全部数据的adj列表p_a_words = list(chain(*map(lambda x: get_a_list(x), p_dev)))get_word_cloud(p_a_words) # 4. 获取负样本数据n_dev = dev_data[dev_data['label'] == 0]['sentence'] # 5. 获取每个句子的adj列表, 绘制词云n_a_words = list(chain(*map(lambda x: get_a_list(x), n_dev)))get_word_cloud(n_a_words)
五. 文本特征分析
介绍
文本特征处理的作用
文本特征处理包括为语料添加具有普适性的文本特征, 如:n-gram特征, 以及对加入特征之后的文本语料进行必要的处理, 如: 长度规范. 这些特征处理工作能够有效的将重要的文本特征加入模型训练中, 增强模型评估指标.
常见文本特征处理方法
添加n-gram特征
文本长度规范
n_gram特征
原理
给定一段文本序列, 其中n个词或字的相邻共现特征即n-gram特征, 常用的n-gram特征是bi-gram和tri-gram特征, 分别对应n为2和3.
提取n_gram特征
def add_ngram(a: list):n_gram = 2# *:表示解包, 第一次返回所有, 第二次返回除第一元素意外的数据# zip: 返回(参数中)相同索引的数据return set(zip(*[a[i:] for i in range(n_gram)])) input_list = [1, 3, 2, 1, 5, 3] res = add_ngram(input_list) print(res) # {(2, 1), (1, 5), (5, 3), (3, 2), (1, 3)}
文本长度规范
一般模型的输入需要等尺寸大小的矩阵, 因此在进入模型前需要对每条文本数值映射后的长度进行规范, 此时将根据句子长度分布分析出覆盖绝大多数文本的合理长度, 对超长文本进行截断, 对不足文本进行补齐(一般使用数字0), 这个过程就是文本长度规范.
超参数选择:
大于固定长度切除
小于固定长度补0
from tensorflow.keras.preprocessing import sequence def padding(x_train):max_len = 10# padding : 设置补全位置, 默认从前补全# truncating : 设置截断位置, 默认从前截断return sequence.pad_sequences(x_train, maxlen=max_len, padding='post', truncating='post') if __name__ == '__main__':# 假定x_train里面有两条文本, 一条长度大于10, 一天小于10x_train = [[1, 23, 5, 32, 55, 63, 2, 21, 78, 32, 23, 1],[2, 32, 1, 23, 1]] res = padding(x_train)print(res) >>>[[ 5 32 55 63 2 21 78 32 23 1][ 0 0 0 0 0 2 32 1 23 1]]
六. 文本数据增强
回译数据增强法
解决不平衡数据集, 最大程度减少标注工作
-
回译数据增强目前是文本数据增强方面效果较好的增强方法, 一般基于google、有道等翻译接口, 将文本数据翻译成另外一种语言(一般选择小语种),之后再翻译回原语言, 即可认为得到与与原语料同标签的新语料, 新语料加入到原数据集中即可认为是对原数据集数据增强.
-
回译数据增强优势:
-
操作简便, 获得新语料质量高.
-
-
回译数据增强存在的问题:
-
在短文本回译过程中, 新语料与原语料可能存在很高的重复率, 并不能有效增大样本的特征空间.
-
-
高重复率解决办法:
-
进行连续的多语言翻译, 如: 中文→韩文→日语→英文→中文, 根据经验, 最多只采用3次连续翻译, 更多的翻译次数将产生效率低下, 语义失真等问题.
-
说明 项目为有道智云paas接口的python语言调用示例。您可以通过执行项目中的main函数快速调用有道智云相关api服务。
运行环境 python 3.6版本及以上。 运行方式 在执行前您需要根据代码中的 中文提示 填写相关接口参数,具体参数取值可以访问 智云官网:有道智云AI开放平台 文档获取。 同时您需要获取智云相关 应用ID 及 应用密钥 信息。具体获取方式可以访问 入门指南:帮助文档-有道智云AI开放平台 获取帮助。 注意事项 项目中的代码有些仅作展示及参考,生产环境中请根据业务的实际情况进行修改。 项目中接口返回的数据仅在控制台输出,实际使用中请根据实际情况进行解析。
import requests from utils.AuthV3Util import addAuthParams # 您的应用ID APP_KEY = '0ca98e755399cde3' # 您的应用密钥 APP_SECRET = '9t4buOfvetT309zK4EeJ3G5pntMdUsiL' def createRequest(text):'''note: 将下列变量替换为需要请求的参数支持语言https://ai.youdao.com/DOCSIRMA/html/trans/api/wbfy/index.html#section-9'AUTO': '自动检测语言''zh-CHS': '中文','en': '英文''ja': '日语''ko': '韩语''fr': '法语''de': '德语''''q = textlang_from = 'zh-CHS'lang_to = 'en'# vocab_id = '您的用户词表ID'vocab_id = None data = {'q': q, 'from': lang_from, 'to': lang_to, 'vocabId': vocab_id} addAuthParams(APP_KEY, APP_SECRET, data) header = {'Content-Type': 'application/x-www-form-urlencoded'}res = doCall('https://openapi.youdao.com/api', header, data, 'post')print(str(res.content, 'utf-8'))print(res.json()['translation'][0]) def doCall(url, header, params, method):if 'get' == method:return requests.get(url, params)elif 'post' == method:return requests.post(url, params, header) # 网易有道智云翻译服务api调用demo # api接口: https://openapi.youdao.com/api if __name__ == '__main__':text = '我爱北京天安门,天安门上太阳升。'createRequest(text)