外贸英语学习网站,高德街景地图全景在线,易语言如何做网站,wordpress天气接口目录
一、文本处理的基本方法
1.1 分词
1.2 命名体实体识别
1.3 词性标注
二、文本张量的表示形式
2.1 one-hot编码
2.2 word2vec 模型
2.2.1 CBOW模式
2.2.2 skipgram模式
2.3 词嵌入word embedding
三、文本数据分析
3.1 标签数量分布
3.2 句子长度分布
3.3 词…目录
一、文本处理的基本方法
1.1 分词
1.2 命名体实体识别
1.3 词性标注
二、文本张量的表示形式
2.1 one-hot编码
2.2 word2vec 模型
2.2.1 CBOW模式
2.2.2 skipgram模式
2.3 词嵌入word embedding
三、文本数据分析
3.1 标签数量分布
3.2 句子长度分布
3.3 词频统计与关键词词云
四、文本特征处理
4.1 n-gram特征
4.2 文本长度规范
五、文本数据增强 文本语料在输送给模型前一般需要一系列的预处理工作才能符合模型输入的要求如将文本转化成模型需要的张量规范张量的尺寸等而且科学的文本预处理环节还将有效指导模型超参数的选择提升模型的评估指标
一、文本处理的基本方法
1.1 分词
分词就是将连续的字序列按照一定的规范重新组合成词序列的过程。在英文的行文中单词之间是以空格作为自然分界符的而中文只是字、句和段能通过明显的分界符来简单划界唯独词没有一个形式上的分界符分词过程就是找到这样分界符的过程
无线电法国别研究
[无线电法, 国别, 研究]词作为语言语义理解的最小单元是人类理解文本语言的基础。因此也是AI解决NLP领域高阶任务如自动问答、机器翻译、文本生成的重要基础环节
精确模式分词试图将句子最精确地切开适合文本分析全模式分词把句子中所有的可以成词的词语都扫描出来, 速度非常快但是不能消除歧义搜索引擎模式分词在精确模式基础上对长词再次切分提高召回率适合搜索引擎分词
import jieba# 精确模式
def test01():text 无线电法国别研究# cut_all默认为Falseobj jieba.cut(text, cut_allFalse)print(obj)# generator object Tokenizer.cut at 0x0000019CB8CDC148# lcut直接返回分词列表内容words jieba.lcut(text, cut_allFalse)print(words)# [无线电, 法国, 别, 研究]# 全模式分词
def test02():text 无线电法国别研究obj jieba.cut(text, cut_allTrue)print(obj)# generator object Tokenizer.cut at 0x000001E6304AC148words jieba.lcut(text, cut_allTrue)print(words)# [无线, 无线电, 法国, 国别, 研究]# 搜索引擎模式分词
def test03():text 无线电法国别研究obj jieba.cut_for_search(text)print(obj)# generator object Tokenizer.cut_for_search at 0x000001CCE75DA748words jieba.lcut_for_search(text)print(words)# [无线, 无线电, 法国, 别, 研究]if __name__ __main__:# test01()# test02()test03() 使用用户自定义词典 添加自定义词典后jieba能够准确识别词典中出现的词汇提升整体的识别准确率词典格式一行分三部分词语、词频可略、词性可略空格隔开顺序不可颠倒
云计算 5 n
李小福 2 nr
easy_install 3 eng
好用 300
韩玉赏鉴 3 nz
八一双鹿 3 nz
import jiebadef main():text 八一双鹿更名为八一南昌篮球队# 精确模式words jieba.lcut(text)print(words)# [八, 一双, 鹿, 更名, 为, 八一, 南昌, 篮球队, ]# 自定义词表jieba.load_userdict(./data/userdict.txt)words jieba.lcut(text)print(words)# [八一双鹿, 更名, 为, 八一, 南昌, 篮球队, ]if __name__ __main__:main() 1.2 命名体实体识别
命名实体通常将人名、地名、机构名等专有名词统称命名实体.。如周杰伦、黑山县、孔子学院、24辊方钢矫直机命名实体识别Named Entity Recognition简称NER就是识别出一段文本中可能存在的命名实体
鲁迅, 浙江绍兴人, 五四新文化运动的重要参与者, 代表作朝花夕拾.鲁迅(人名) / 浙江绍兴(地名)人 / 五四新文化运动(专有名词) / 重要参与者 / 代表作 / 朝花夕拾(专有名词)同词汇一样命名实体也是人类理解文本的基础单元是AI解决NLP领域高阶任务的重要基础环节 1.3 词性标注
语言中对词的一种分类方法以语法特征为主要依据、兼顾词汇意义对词进行划分的结果常见的词性有14种如名词、动词、形容词等词性标注Part-Of-Speech tagging简称POS就是标注出一段文本中每个词汇的词性
我爱自然语言处理我/rr, 爱/v, 自然语言/n, 处理/vnrr: 人称代词
v: 动词
n: 名词
vn: 动名词词性标注以分词为基础是对文本语言的另一个角度的理解因此也常常成为AI解决NLP领域高阶任务的重要基础环节
import jieba.posseg as psegdef main():text 我爱北京天安门words pseg.lcut(text)print(words)# [pair(我, r), pair(爱, v), pair(北京, ns), pair(天安门, ns)]if __name__ __main__:main() 二、文本张量的表示形式
将一段文本使用张量进行表示其中一般将词汇为表示成向量称作词向量再由各个词向量按顺序组成矩阵形成文本表示
[人生, 该, 如何, 起头]# 每个词对应矩阵中的一个向量
[[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]]
将文本表示成张量矩阵形式能够使语言文本可以作为计算机处理程序的输入进行接下来一系列的解析工作
2.1 one-hot编码
独热编码将每个词表示成具有n个元素的向量这个词向量中只有一个元素是1其他元素都是0不同词汇元素为0的位置不同其中n的大小是整个语料中不同词汇的总数
[改变, 要, 如何, 起手][[1, 0, 0, 0],[0, 1, 0, 0],[0, 0, 1, 0],[0, 0, 0, 1]]
onehot 编码实现
import joblib
from keras.preprocessing.text import Tokenizervocab {周杰伦, 陈奕迅, 王力宏, 李宗盛, 吴亦凡, 鹿晗}
# 实例化一个词汇映射器对象
tokenizer Tokenizer(num_wordsNone, char_levelFalse)
# 使用映射器拟合现有文本数据
tokenizer.fit_on_texts(vocab)for token in vocab:zero_list [0] * len(vocab)# 使用映射器转化现有文本数据, 每个词汇对应从1开始的自然数# 返回样式如: [[2]], 取出其中的数字需要使用[0][0]index tokenizer.texts_to_sequences([token])[0][0] - 1zero_list[index] 1print(token, 的one-hot编码是:, zero_list)# 使用joblib工具保存映射器, 以便之后使用
tokenizer_path ./data/Tokenizer
joblib.dump(tokenizer, tokenizer_path)# 李宗盛 的one-hot编码是: [1, 0, 0, 0, 0, 0]
# 周杰伦 的one-hot编码是: [0, 1, 0, 0, 0, 0]
# 王力宏 的one-hot编码是: [0, 0, 1, 0, 0, 0]
# 陈奕迅 的one-hot编码是: [0, 0, 0, 1, 0, 0]
# 吴亦凡 的one-hot编码是: [0, 0, 0, 0, 1, 0]
# 鹿晗 的one-hot编码是: [0, 0, 0, 0, 0, 1]
one-hot 编码器的使用
import joblibvocab {周杰伦, 陈奕迅, 王力宏, 李宗盛, 吴亦凡, 鹿晗}
tokenizer_path ./data/Tokenizer
tokenizer joblib.load(tokenizer_path)token 李宗盛
# 使用 token 获取 token_index
index tokenizer.texts_to_sequences([token])[0][0] - 1
# 得到 one-hot 编码
zero_list [0] * len(vocab)
zero_list[index] 1
print(token, 的one-hot编码是:, zero_list)
# 李宗盛 的one-hot编码是: [1, 0, 0, 0, 0, 0]
one-hot 编码的优劣势
优势操作简单容易理解劣势完全割裂了词与词之间的联系在大语料集下每个向量的长度过大占据大量内存因为one-hot编码明显的劣势这种编码方式被应用的地方越来越少取而代之的是稠密向量的表示方法 word2vec 和 word embedding 2.2 word2vec 模型
word2vec 是一种流行的将词汇表示成向量的无监督训练方法该过程将构建神经网络模型将网络参数作为词汇的向量表示包含 CBOW 和 skipgram 两种训练模式
2.2.1 CBOW模式
Continuous bag of words
给定一段文本语料再选定某段长度窗口作为研究对象使用上下文词汇预测目标词汇 上图中窗口大小为9使用前后4个词汇对目标词汇进行预测 过程详解 假设给定的训练语料只有一句话Hope can set you free (愿你自由成长)窗口大小为3因此模型的第一个训练样本来自Hope can set因为是CBOW模式所以将使用Hope和set作为输入can作为输出。在模型训练时 Hopecanset 等词汇都使用其 one-hot 编码。输入数据的每个 one-hot 编码5*1与各自的变换矩阵即参数矩阵3*5这里的 3 是指最后得到的词向量维度相乘之后再相加得到上下文表示矩阵3*1 将上下文表示矩阵与变换矩阵(参数矩阵 5*3所有的变换矩阵共享参数相乘得到 5*1 的结果矩阵结果矩阵与目标矩阵即 can 的 one-hot 编码矩阵 (5*1) 进行损失的计算然后更新网络参数完成一次模型迭代 2.2.2 skipgram模式
给定一段用于训练的文本语料再选定某段长度窗口作为研究对象使用目标词汇预测上下文词汇 图中窗口大小为9使用目标词汇对前后四个词汇进行预测 过程详解 假设给定的训练语料只有一句话Hope can set you free (愿你自由成长)窗口大小为3因此模型的第一个训练样本来自Hope can set。因为是skipgram模式所以将使用can作为输入 Hope和set作为输出在模型训练时 Hopecanset 等词汇都使用其 one-hot 编码。将 can 的 one-hot 编码与变换矩阵即参数矩阵3*53是指最后得到的词向量维度相乘得到目标词汇表示矩阵3*1
将目标词汇表示矩阵与多个变换矩阵参数矩阵5*3相乘得到多个 5*1 的结果矩阵将与 Hope 和 set 对应的 one-hot 编码矩阵5*1进行损失计算, 然后更新网络参数完成一次模型迭代 最后窗口按序向后移动重新更新参数直到所有语料被遍历完成得到最终的变换矩阵即参数矩阵3*5这个变换矩阵与每个词汇的one-hot编码5*1相乘得到的3x1的矩阵就是该词汇的 word2vec 张量表示 2.3 词嵌入word embedding
通过一定的方式将词汇映射到指定维度(一般是更高维度)的空间广义的 word embedding 包括所有密集词汇向量的表示方法如之前学习的 word2vec 可认为是 word embedding 的一种狭义的 word embedding 是指在神经网络中加入的 embedding 层对整个网络进行训练的同时产生的 embedding 矩阵embedding层的参数这个 embedding 矩阵就是训练过程中所有输入词汇的向量表示组成的矩阵
词嵌入层会根据输入的词的数量构建一个词向量矩阵。如有 100 个词每个词希望转换成 128 维度的向量那么构建的矩阵形状即为100 * 128输入的每个词都对应了矩阵中的一个向量
在 PyTorch 中可以使用 nn.Embedding 词嵌入层来实现输入词的向量化
先将语料进行分词构建词与索引的映射可以将这个映射称为词表词表中每个词都对应了一个唯一的索引然后使用 nn.Embedding 构建词嵌入矩阵词索引对应的向量即为该词对应的数值化后的向量表示
nn.Embedding 对象构建时最主要有两个参数:
num_embeddings 表示词的数量embedding_dim 表示用多少维的向量来表示每个词
import torch
import torch.nn as nn
import jiebadef main():text 北京冬奥的进度条已经过半不少外国运动员在完成自己的比赛后踏上归途。# 1. 分词words jieba.lcut(text)print(words:, words)# 2. 构建词表index_to_word {}word_to_index {}# 分词去重unique_words list(set(words))for idx, word in enumerate(unique_words):index_to_word[idx] wordword_to_index[word] idx# 3.构建词嵌入层# num_embeddings为词的数量embedding_dim为词嵌入的维度embedding nn.Embedding(num_embeddingslen(index_to_word), embedding_dim4)# 4.文本转为词向量表示for word in words:idx word_to_index[word]word_vector embedding(torch.tensor(idx))print(%3s\t % word, word_vector)if __name__ __main__:main()
words: [北京, 冬奥, 的, 进度条, 已经, 过半, , 不少, 外国, 运动员, 在, 完成, 自己, 的, 比赛, 后, 踏上, 归途, 。]北京 tensor([1.1339, 1.1262, 0.6638, 1.5691], grad_fnEmbeddingBackward0)冬奥 tensor([0.2753, 0.3262, 1.7691, 1.2225], grad_fnEmbeddingBackward0)的 tensor([-0.7507, 1.8850, 1.4340, -0.8074], grad_fnEmbeddingBackward0)
进度条 tensor([ 0.5693, -0.0951, -0.4607, 0.0555], grad_fnEmbeddingBackward0)已经 tensor([-0.5726, 0.0812, 1.1051, -0.0020], grad_fnEmbeddingBackward0)过半 tensor([0.0691, 0.1430, 1.9346, 1.4653], grad_fnEmbeddingBackward0) tensor([-1.1009, 0.7833, -0.9021, 1.8811], grad_fnEmbeddingBackward0)不少 tensor([ 0.7913, 0.0890, -0.7459, 1.1473], grad_fnEmbeddingBackward0)外国 tensor([-0.6079, 0.2563, 0.8344, -0.5977], grad_fnEmbeddingBackward0)
运动员 tensor([-1.9587, 0.0995, -1.0728, -0.2779], grad_fnEmbeddingBackward0)在 tensor([-1.6571, -1.2508, -0.8138, -2.6821], grad_fnEmbeddingBackward0)完成 tensor([-1.4124, -0.5624, 1.2548, 0.1708], grad_fnEmbeddingBackward0)自己 tensor([-2.5485, -0.1839, -0.0079, 0.1326], grad_fnEmbeddingBackward0)的 tensor([-0.7507, 1.8850, 1.4340, -0.8074], grad_fnEmbeddingBackward0)比赛 tensor([ 0.3826, -1.8883, 0.5677, 0.1951], grad_fnEmbeddingBackward0)后 tensor([ 0.2585, -1.2181, 1.0165, -0.4775], grad_fnEmbeddingBackward0)踏上 tensor([-1.6933, 1.2826, 0.9993, -0.2306], grad_fnEmbeddingBackward0)归途 tensor([ 3.8709, 0.5133, 0.1683, -0.9699], grad_fnEmbeddingBackward0)。 tensor([-0.9352, -1.2663, -1.5860, -0.2301], grad_fnEmbeddingBackward0)
词嵌入层默认使用的是均值为 0标准差为 1 的正态分布进行初始化也可以理解为是随机初始化。这个用来表示词的文本真的能够表达出词的含义吗
nn.Embedding 中对每个词的向量表示都是随机生成的当一个词输入进来后会使用随机产生的向量来表示该词。该词向量参与到下游任务的计算下游任务计算后会和目标结果进行对比产生损失。接下来通过反向传播更新所有的网络参数就包括了 nn.Embedding 中的词向量表示。这样通过反复的前向计算、反向传播、参数更新最终每个词的向量表示就会变得更合理 三、文本数据分析
文本数据分析能够有效帮助理解数据语料快速检查出语料可能存在的问题并指导之后模型训练过程中一些超参数的选择
后续文章中采用中文酒店评论语料来讲解
sentence label
早餐不好,服务不到位,晚餐无西餐,早餐晚餐相同,房间条件不好,餐厅不分吸烟区.房间不分有无烟房. 0
去的时候 ,酒店大厅和餐厅在装修,感觉大厅有点挤.由于餐厅装修本来该享受的早饭,也没有享受(他们是8点开始每个房间送,但是我时间来不及了)不过前台服务员态度好! 1
有很长时间没有在西藏大厦住了以前去北京在这里住的较多。这次住进来发现换了液晶电视但网络不是很好他们自己说是收费的原因造成的。其它还好。 1
非常好的地理位置住的是豪华海景房打开窗户就可以看见栈桥和海景。记得很早以前也住过现在重新装修了。总的来说比较满意以后还会住 1
交通很方便房间小了一点但是干净整洁很有香港的特色性价比较高推荐一下哦 1
酒店的装修比较陈旧房间的隔音主要是卫生间的隔音非常差只能算是一般的 0
酒店有点旧房间比较小但酒店的位子不错就在海边可以直接去游泳。8楼的海景打开窗户就是海。如果想住在热闹的地带这里不是一个很好的选择不过威海城市真的比较小打车还是相当便宜的。晚上酒店门口出租车比较少。 1
位置很好走路到文庙、清凉寺5分钟都用不了周边公交车很多很方便就是出租车不太爱去老城区路窄爱堵车因为是老宾馆所以设施要陈旧些 1
酒店设备一般套房里卧室的不能上网要到客厅去。 0
...
第一列数据代表具有感情色彩的评论文本第二列数据 0 或 1代表每条文本数据是积极或者消极的评论0代表消极1代表积极
3.1 标签数量分布
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt# 设置显示风格
plt.style.use(fivethirtyeight)# 分别读取训练tsv和验证tsv
train_data pd.read_csv(data/cn_data/train.tsv, sep\t)
valid_data pd.read_csv(data/cn_data/dev.tsv, sep\t)# 获得训练数据标签数量分布
sns.countplot(xlabel, datatrain_data)
plt.title(train_data)
plt.show()# 获取验证数据标签数量分布
sns.countplot(xlabel, datavalid_data)
plt.title(valid_data)
plt.show() 在深度学习模型评估中一般使用ACC作为评估指标若想将ACC的基线定义在50%左右随机猜测的准确率是 50%则需要正负样本比例维持在1:1左右否则就要进行必要的数据增强或数据删减。上图中训练和验证集正负样本都稍有不均衡可以进行一些数据增强 3.2 句子长度分布
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt# 设置显示风格
plt.style.use(fivethirtyeight)# 分别读取训练tsv和验证tsv
train_data pd.read_csv(data/cn_data/train.tsv, sep\t)
valid_data pd.read_csv(data/cn_data/dev.tsv, sep\t)# 在训练数据中添加新的句子长度列, 每个元素的值都是对应的句子列的长度
train_data[sentence_length] list(map(lambda x: len(x), train_data[sentence]))
# 在验证数据中添加新的句子长度列, 每个元素的值都是对应的句子列的长度
valid_data[sentence_length] list(map(lambda x: len(x), valid_data[sentence]))# 绘制句子长度列的数量分布图
sns.countplot(xsentence_length, datatrain_data)
# 主要关注count长度分布的纵坐标, 不需要绘制横坐标, 横坐标范围通过dist图进行查看
plt.xticks([])
plt.show()
# 绘制dist长度分布图
sns.distplot(train_data[sentence_length])
# 主要关注dist长度分布横坐标, 不需要绘制纵坐标
plt.yticks([])
plt.show()# 绘制句子长度列的数量分布图
sns.countplot(xsentence_length, datavalid_data)
# 主要关注count长度分布的纵坐标, 不需要绘制横坐标, 横坐标范围通过dist图进行查看
plt.xticks([])
plt.show()
# 绘制dist长度分布图
sns.distplot(valid_data[sentence_length])
# 主要关注dist长度分布横坐标, 不需要绘制纵坐标
plt.yticks([])
plt.show() 训练集句子长度分布 验证集句子长度分布 通过绘制句子长度分布图可以得知语料中大部分句子长度的分布范围因为模型的输入要求为固定尺寸的张量合理的长度范围对之后进行句子截断补齐规范长度起到关键的指导作用。上图中大部分句子长度的范围大致为20-250之间 获取正负样本长度散点分布 # 绘制训练集长度分布的散点图
sns.stripplot(ysentence_length, xlabel, datatrain_data)
plt.show()# 绘制验证集长度分布的散点图
sns.stripplot(ysentence_length, xlabel, datavalid_data)
plt.show()
训练集上正负样本的长度散点分布 验证集上正负样本的长度散点分布 通过查看正负样本长度散点图可以有效定位异常点的出现位置能更准确进行人工语料审查。上图中在训练集正样本中出现了异常点句子长度近3500左右需要人工审查 3.3 词频统计与关键词词云 不同词汇总数统计 import jieba
import pandas as pd
# 导入chain方法用于扁平化列表
from itertools import chain# 分别读取训练tsv和验证tsv
train_data pd.read_csv(data/cn_data/train.tsv, sep\t)
valid_data pd.read_csv(data/cn_data/dev.tsv, sep\t)# 进行训练集的句子进行分词, 并统计出不同词汇的总数
train_vocab set(chain(*map(lambda x: jieba.lcut(x), train_data[sentence])))
print(训练集共包含不同词汇总数为, len(train_vocab))# 进行验证集的句子进行分词, 并统计出不同词汇的总数
valid_vocab set(chain(*map(lambda x: jieba.lcut(x), valid_data[sentence])))
print(训练集共包含不同词汇总数为, len(valid_vocab))# 训练集共包含不同词汇总数为 12162
# 训练集共包含不同词汇总数为 6857 获取高频形容词词云 import jieba.posseg as pseg
import pandas as pd
import matplotlib.pyplot as plt
# 导入绘制词云的工具包
from wordcloud import WordCloud
# 导入chain方法用于扁平化列表
from itertools import chaindef get_a_list(text):用于获取形容词列表# 使用jieba的词性标注方法切分文本,获得具有词性属性flag和词汇属性word的对象# 从而判断flag是否为形容词,来返回对应的词汇r []for g in pseg.lcut(text):if g.flag a:r.append(g.word)return rdef get_word_cloud(keywords_list):# 实例化绘制词云的类, 其中参数font_path是字体路径, 为了能够显示中文,# max_words指词云图像最多显示多少个词, background_color为背景颜色wordcloud WordCloud(font_path./data/SimHei.ttf, max_words100, background_colorwhite)# 将传入的列表转化成词云生成器需要的字符串形式keywords_string .join(keywords_list)# 生成词云wordcloud.generate(keywords_string)# 绘制图像并显示plt.figure()plt.imshow(wordcloud, interpolationbilinear)plt.axis(off)plt.show()# 分别读取训练tsv和验证tsv
train_data pd.read_csv(data/cn_data/train.tsv, sep\t)
valid_data pd.read_csv(data/cn_data/dev.tsv, sep\t)# 获得训练集上正样本
p_train_data train_data[train_data[label] 1][sentence]
# 获得训练集上负样本
n_train_data train_data[train_data[label] 0][sentence]
# 获得验证集上正样本
p_valid_data valid_data[valid_data[label] 1][sentence]
# 获得验证集上负样本
n_valid_data valid_data[valid_data[label] 0][sentence]# 对训练集正样本的每个句子的形容词
train_p_a_vocab chain(*map(lambda x: get_a_list(x), p_train_data))
#print(train_p_n_vocab)
# 获取训练集负样本的每个句子的形容词
train_n_a_vocab chain(*map(lambda x: get_a_list(x), n_train_data))
# 对验证集正样本的每个句子的形容词
valid_p_a_vocab chain(*map(lambda x: get_a_list(x), p_valid_data))
#print(train_p_n_vocab)
# 获取验证集负样本的每个句子的形容词
valid_n_a_vocab chain(*map(lambda x: get_a_list(x), n_valid_data))# 调用绘制词云函数
get_word_cloud(train_p_a_vocab)
get_word_cloud(train_n_a_vocab)
get_word_cloud(valid_p_a_vocab)
get_word_cloud(valid_n_a_vocab)
训练集正样本形容词词云 训练集负样本形容词词云 验证集正样本形容词词云 验证集负样本形容词词云 根据高频形容词词云显示可以对当前语料质量进行简单评估同时对违反语料标签含义的词汇进行人工审查和修正来保证绝大多数语料符合训练标准。上图中的正样本大多数是褒义词而负样本大多数是贬义词但是负样本词云中也存在好这样的褒义词因此可以人工进行审查 四、文本特征处理
文本特征处理包括为语料添加具有普适性的文本特征如n-gram特征以及对加入特征之后的文本语料进行必要的处理如长度规范。这些特征处理工作能够有效的将重要的文本特征加入模型训练中增强模型评估指标
4.1 n-gram特征
给定一段文本序列其中n个词或字的相邻共现特征即 n-gram 特征常用的 n-gram 特征是 bi-gram 和 tri-gram 特征分别对应n为2和3
假设给定分词列表: [是谁, 敲动, 我心]对应的数值映射列表为: [1, 34, 21]可以认为数值映射列表中的每个数字是词汇特征除此之外, 还可以把是谁和敲动两个词共同出现且相邻也作为一种特征加入到序列列表中假设1000就代表是谁和敲动共同出现且相邻此时数值映射列表就变成了包含 2-gram 特征的特征列表: [1, 34, 21, 1000]这里的是谁和敲动共同出现且相邻就是bi-gram特征中的一个敲动和我心也是共现且相邻的两个词汇, 因此也是 bi-gram 特征假设1001代表敲动和我心共同出现且相邻那么, 最后原始的数值映射列表 [1, 34, 21] 添加了bi-gram特征之后就变成了 [1, 34, 21, 1000, 1001] 提取n-gram特征 n_gram_range 2def create_n_gram_set(input_list):description: 从数值列表中提取所有的 n-gram 特征:param input_list: 输入的数值列表, 可以看作是词汇映射后的列表,里面每个数字的取值范围为[1, 25000]:return: n-gram特征组成的集合 create_ngram_set([1, 4, 9, 4, 1, 4]){(4, 9), (4, 1), (1, 4), (9, 4)}return set(zip(*[input_list[i:] for i in range(n_gram_range)]))input_list [1, 3, 2, 1, 5, 3]
result create_n_gram_set(input_list)
print(result)
# {(3, 2), (1, 3), (2, 1), (1, 5), (5, 3)} 4.2 文本长度规范
一般模型的输入需要等尺寸大小的矩阵因此在进入模型前需要对每条文本数值映射后的长度进行规范此时将根据句子长度分布分析出覆盖绝大多数文本的合理长度对超长文本进行截断, 对不足文本进行补齐(一般使用数字0)这个过程就是文本长度规范
from keras.utils import pad_sequences
text_length 10def padding_cut(data):description: 对输入文本张量进行长度规范:param x_train: 文本的张量表示, 形如: [[1, 32, 32, 61], [2, 54, 21, 7, 19]]:return: 进行截断补齐后的文本张量表示# 使用pad_sequences即可完成return pad_sequences(data, text_length)data [[1, 23, 5, 32, 55, 63, 2, 21, 78, 32, 23, 1], [2, 32, 1, 23, 1]]
res padding_cut(data)
print(res)
# [[ 5 32 55 63 2 21 78 32 23 1]
# [ 0 0 0 0 0 2 32 1 23 1]] 五、文本数据增强
回译数据增强目前是文本数据增强方面效果较好的增强方法一般基于google翻译接口将文本数据翻译成另外一种语言(一般选择小语种)之后再翻译回原语言即可认为得到与与原语料同标签的新语料新语料加入到原数据集中即可认为是对原数据集数据增强
操作简便, 获得新语料质量高.在短文本回译过程中新语料与原语料可能存在很高重复率并不能有效增大样本的特征空间
高重复率解决办法
进行连续的多语言翻译如中文→韩文→日语→英文→中文。根据经验最多只采用3次连续翻译更多的翻译次数将产生效率低下语义失真等问题