文本处理的基本方法
1、文本预处理
1.1、什么是分词
就是将连续的字序列按照一定的规范重新组合成词序列的过程
1.2、分词的作用
词作为语言语义理解最小单位,是人类理解文本语言的基础
1.3、流行中文词jieba
import jieba
content ="公信处女干事每月经过下属科室都要清口交代24口交换机等技术性器件的安排工作"
jieba.lcut(content,cut_all=False) #精确
jieba.lcut(content,cut_all=True) #全模式
jieba.lcut_for_search(content)
import jieba
content="八一双鹿更名为八一南昌篮球队"
jieba.load_userdict('D:/data/usedict.txt')
jieba.lcut(content) #精确
1.4、中英文分词工具hanlp
import hanlp
tokenizer=hanlp.load('CTB6_CONVSEG')
tokenizer("公信处女干事每月经过下属科室都要清口交代24口交换机等技术性器件的安排工作")
2、命名实体识别
命名实体:通常我们将人名,地名,机构名等专有名词统称命名实体,如周杰伦
命名实体识别(NER):识别出一段文本中可能存在的命名实体
2、文本张量
2.1、什么是文本张量表示
讲一段文本使用张量进行表示,其中一般将词汇表示成向量,称作词向量,再由各个词向量按顺序组成矩阵形成文本表示。
2.2、文本张量表示作用
将文本表示成张量(矩阵)形式,能够使语言文本可以作为计算机处理程序的输入,进行接下来一系列的解析工作
2.3、文本张量表示的方法
one-hot编码 word2vec word embedding
2.4、one-hot词向量表示
又称独热编码,将每个词表示成具有n个元素的向量,这个词向量中只有一个元素是1,其它元素都是0,不同词汇元素为0的位置不同,其中n的大小是整个语料中不同词汇的总数。
from sklearn.externals import joblib
from keras.preprocessing.text import Tokenizer
import joblib
#初始化一个词汇表
vocab ={"周杰伦","陈奕迅","王力宏","李宗盛","吴亦凡","鹿晗"}
t=Tokenizer(num_words=None,char_level=False)
t.fit_on_texts(vocab)
for token in vocab:
zero_list =[0] * len(vocab)
token_index=t.texts_to_sequences([token])[0][0] -1
zero_list[token_index] =1
print(token,"的one-hot编码为:",zero_list)
tokenizer_path="./Tokenizer"
joblib.dump(t,tokenizer_path)
#导入用于对象保存用于加载的包
import joblib
t=joblib.load("./Tokenizer")
token ="李宗盛"
#从词汇映射中得到李宗盛的index
token_index=t.texts_to_sequences([token])[0][0] -1
#初始化全0向量
zero_list=[0]*6
zero_list[token_index]=1
print(token,"的one-hot编码为:",zero_list)
2.4.1、one-hot编码的优劣势
优势:操作简单,容易理解
劣势:完全割裂了词与词之间的联系,而且在大语料集下,每个向量的长度过大,占据打了内存。
2.5、什么是word2vec
是一种流行的将词汇表示成向量的无监督训练方法,该过程将构建神经网络模型,将网络参数作为词汇的向量表示,它包含CBOW和skipgram两种训练模式。
CBOM(continuous bag of words)模式:给定一段用于训练的文本语料,再选定某段长度(窗口)作为研究对象,使用上下文词汇预测目标词汇
skipgram模式
给定一段用于训练的文本语料,再选定某段长度(窗口)作为研究对象,使用目标词汇预测上下文词汇
2.6、使用fasttext工具实现word2vec的训练和使用
1、获取训练数据 2、训练词向量 3、模型超参数设定
4、模型效果检验 5、模型的保存与重加载
2.7、什么是word embedding(词嵌入)
通过一定的方式将词汇映射到指定维度(一般是更高维度)的空间
广义的word embedding包括所有密集词汇向量的表示方法,如之前学习的word2vec,即可认为是word embedding的一种。
狭义的word embedding是指在神经网络中加入的embedding层,对整个网络进行训练的同时产生的embedding矩阵(embedding层的参数),这个embedding矩阵就是训练过程中所有输入词汇的向量表示组成的矩阵
3、文本情感分析
3.1、文本数据分析作用:
文本数据分析能够有效帮助我们理解数据语料,快速检查出语料可能存在的问题,并指导之后模型训练过程中一些超参数的选择
3.2、常用的文本数据分析方法
标签数量分布 句子长度分布 词频统计与关键词词云
3.3、基于真实的中文酒店评论语料进行几种文本数据分析方法
1、获得训练集和验证集的标签数量分布
2、获得训练集和验证集的句子长度分布
3、获得训练集和验证集的正负样本长度散点分布
4、获得训练集和验证集的不同词汇总数统计
5、获得训练集上正负的样本的高频形容词词云
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
#设置显示风格
plt.style.use('fivethirtyeight')
#分别读取训练tsv和验证tsv
train_data = pd.read_csv("D:/data/cn_data/train.tsv",sep="\t")
valid_data = pd.read_csv("D:/data/cn_data/dev.tsv",sep="\t")
#获取训练数据标签数量分布
sns.countplot("label",data=train_data)
plt.title("train_data")
plt.show()
#获取验证数据标签数量分布
sns.countplot("label",data=valid_data)
plt.title("valid_data")
plt.show()
#在训练数据中添加新的句子长度列,每个元素的值都是对应的句子列的长度
train_data["sentence_length"]=list(map(lambda x:len(x),train_data["sentence"]))
#绘制句子长度列的数量分布图
sns.countplot("sentence_length",data=train_data)
#主要关注count长度分布的纵坐标,不需要绘制横坐标,横坐标范围通过dist图进行查看
plt.xticks([])
plt.show()
#绘制dist长度分布图
sns.distplot(train_data["sentence_length"])
#主要关注dist长度分布横坐标,不需要绘制纵坐标
plt.yticks([])
plt.show()
#在验证数据中添加新的句子长度列,每个元素的值都是对应的句子列的长度
valid_data["sentence_length"] = list(map(lambda x:len(x),valid_data["sentence"]))
#绘制句子长度列的数量分布图
sns.countplot("sentence_length",data=valid_data)
#主要关注count长度分布的纵坐标,不需要绘制横坐标,横坐标范围通过dist图进行查看
plt.sticks([])
plt.show()
#绘制dist长度分布图
sns.distplot(valid_data["sentence_length"])
plt.ysticks([])
plt.show()
#获取训练集和验证集的政府样本长度散点分布
#训练集
sns.stripplot(y='sentence_length',x='label',data=train_data)
plt.show()
#验证集
sns.stripplot(y='sentence_length',x='label',data=valid_data)
plt.show()
#jieba用于分词 导入chain方法用于扁平化列表
import jieba
from itertools import chain
#进行训练集的句子进行分词,并统计出不同词汇的总数
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))
#获得训练集上正负样本的高频词云
#使用jieba中的词性标注功能
import jieba.posseg as pseg
def get_a_list(text):
"""用于获取形容词列表"""
#使用jieba词性标注方法切分文本,获得具有词性属性flag和词汇属性word的对象,从而判断flag是否为形容词,来返回对应的词汇
r=[]
for g in pseg.lcut(text):
if g.flag == "a": #a表示形容词
r.append(g.word)
return r
#导入绘制词云的工具包
from wordcloud import WordCloud
def get_word_cloud(keywords_list):
#实例化绘制词云的类,其中参数font_path是字体路径,为了能够显示中文
#max_words指词云图像最多显示多少个词,backgroud_color为背景颜色
wordcloud = WordCloud(font_path='D:\data\simhei.ttf',max_words=100,background_color='white')
keywords_string = " ".join(keywords_list)
#生成词云
wordcloud.generate(keywords_string)
#绘制图像并显示
plt.figure()
plt.imshow(wordcloud,interpolation="bilinear")
plt.axis("off")
plt.show()
#获得训练集上正样本
p_train_data = train_data[train_data["label"]==1]["sentence"]
#对正样本的每个句子的形容词
train_p_a_vocab = chain(*map(lambda x: get_a_list(x),p_train_data))
#获得训练集上负样本
n_train_data=train_data[train_data["label"] == 0]["sentence"]
##对负样本的每个句子的形容词
train_n_a_vocab = chain(*map(lambda x: get_a_list(x),n_train_data))
#调用绘制词云函数
get_word_cloud(train_p_a_vocab)
get_word_cloud(train_n_a_vocab)
4、文本特征处理
4.1、文本特征处理的作用
文本特征处理包括为语料添加具有普遍性的文本特征,如n-gram特征,以及对加入特征之后的文本语料进行必要的处理,如长度规范。这些特征处理工作能够有效的将重要的文本特征加入模型训练中,增强模型评估指标。
4.2、常见的文本特征处理方法
添加n-gram特征 文本长度规范
4.3、什么是n-gram特征
给定一段文本序列,其中n个词或字的相邻共现特征即n-gram特征,常见的n-gram特征是bi-gram(2元特征)和tri-gram(3元特征)特征,对应n为2和3.
举个例子
ngram_range=2
def create_ngram_set(input_list):
return set(zip(*[input_list[i:] for i in range(ngram_range)]))
input_list=[1,3,2,1,5,3]
res=create_ngram_set(input_list)
print(res)
4.4、文本长度规范及其作用
一般模型的输入需要等尺寸大小的矩阵,因此在进入模型前需要对每条文本数值映射后的长度进行规范,此时将根据句子长度分布分析出覆盖绝大多数文本的合理长度,对超长文本进行截断,对不足文本进行补齐(一般使用数字0),这个过程就是文本长度规范
from keras.preprocessing import sequence
#cutlen根据数据分析中句子长度分布,覆盖90%左右语料的最短长度
#这里假定cutlen为10
cutlen=10
def padding(x_train):
"""
description:对输入文本张量进行长度规范
:param x_train: 文本的张量表示,形如:[[1,32,32,61],[2,54,31,7,19]]
:return: 进行截断补齐后的文本张量表示
"""
#使用sequence.pad_sequences即可完成
return sequence.pad_sequences(x_train,cutlen)
#假定x_train里面有两条文本,一条长度大于10,一天小于10
x_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、文本数据增强
回译数据增强法:回译数据增强法是文本数据增强方面效果较好的增强方法,一般基于google翻译接口,将文本数据翻译成另外一种语言(一般选择小语种),之后再翻译回原语言,即可认为得到与与原语料同标签的新语料,新语料加入到原数据集中即可认为是对原数据集数据增强
优势:操作简便,获得新语料质量高
存在问题:再短文本回译过程中,新语料与原语料可能存在很高的重复率,并不能有效增大样本的特征空间
解决办法:进行连续翻译 如中文->韩文->英文
#假设取两条已经存在的正样本和两条负样本,将基于这四条样本产生新的同标签的四条样本
p_sample1 ="酒店设施非常不错"
p_sample2 ="这家价格很便宜"
n_sample1 ="拖鞋都发霉了,太差了"
n_sample2 ="电视不好用,没看到足球"
#导入google翻译接口工具
from googletrans import Translator
#实例化翻译对象
translator = Translator()
#进行第一次批量翻译,翻译目标是韩语
translations = translator.translate([p_sample1, p_sample2, n_sample1, n_sample2], dest="ko")
#获得翻译后的结果
ko_result = list(map(lambda x: x.text,translations))
#打印结果
print("中间翻译结果:")
print(ko_result)
#最后在翻译回中文,完成回译全部流程
translations = translator.translate(ko_result, dest='zh-cn')
cn_res = list(map(lambda x: x.text, translations))
print("回译得到的增强数据:")
print(cn_res)