【NLP02-文本处理的基本方法】

文本处理的基本方法

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)

  • 17
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值