⚽开发平台:jupyter lab
运行环境:python3、TensorFlow2.x
第6章 tensorflow和keras快速入门 | 有趣的词嵌入--word embedding(一)| 文本数据处理- 1. 数据集介绍和数据清洗
- 1.1 数据集显示
- 1.2 清洗数据
- 2. 停用词的使用(后续完善)
- 3. 词向量训练模型word2vec使用介绍
- 3.1 word2vec模型的介绍
- 3.2 word2vec的优缺点
- 3.3 word2vec的模型训练结构
- 1.4 以gensim包对数据进行训练(程序7-5)
- 4. 文本主体的提取
- 4.1 文本主体的提取:基于TF-IDF
- 4.1.1 TF-IDF的原理
- 4.1.2 TF-IDF的实现(程序7-7)
- 4.2 文本主体的提取:基于TextRank
- 4.2.1 TextRank算法的介绍
- 4.2.2 TextRank算法的实现(程序7-8)
word embedding(词嵌入),常用来进行情感分析、同义词聚类、文章分类和打标签。
(1)该部分内容介绍:通过多种计算word embedding的方法循序渐进的了解如何获取对应的word embedding,之后通过实战使用word embedding进行文本分类。
(2)该章节将分为两个部分,
1. 数据集介绍和数据清洗组建能够代表文本内容的矩阵向量的主要步骤:文本分词 --> 词向量训练 --> 特征词抽取。
1.1 数据集显示· 新闻分类数据集“AG”,是从2000多个不同的新闻来源搜索的超过一百万的新闻文章。用于研究分类、聚类、信息获取(排序、搜索)等非商业活动。
· AG News下载地址: https://s3.amazonaws.com/fast-ai-nlp/ag_news_csv.tgz
## 由于该数据集没有标题,可以添加标题列:names=rankings_colname
rankings_colname=['label','title','text']
agnews_train = pd.read_csv('./ag_news_csv/train.csv',encoding='utf-8',engine='python',header=None,names=rankings_colname)
agnews_train ##结果如下图
1.2 清洗数据
### 对文本数据的清洗类
import re
def text_clear(text):
text = text.lower() #将文本转化成小写
text = re.sub(r'[^a-z0-9]',' ',text) #用空格替换非标准字符,^为求反操作
text = re.sub(r' +',' ',text) # 替换多重空格为单空格
text = text.strip() #去除首尾空格
text = text.split(' ') # 对句子按照空格进行划分
return text
### 读取文本,并对每行数据进行遍历
import csv
import numpy as np
agnews_label = []
agnews_title = []
agnews_text = []
## 便于处理数据
agnews_train = csv.reader(open('./ag_news_csv/train.csv','r'))
for line in agnews_train:
## 对于数字,得数字化转换;对于文字,得格式处理
#print(line)
agnews_label.append(np.float32(line[0]))
agnews_title.append(line[1])
agnews_text.append(text_clear(line[2]))
## 对获取的数据进行展示
merge = pd.DataFrame({
'label':agnews_label,
'title':agnews_title,
'text':agnews_text
})
merge ##可观察到处理后的数据与原始数据的不同
2. 停用词的使用(后续完善)
import re
import nltk
def text_clear(text):
syoplist = stopwords.words('english')
text = text.lower() #将文本转化成小写
text = re.sub(r'[^a-z0-9]',' ',text) #用空格替换非标准字符,^为求反操作
text = re.sub(r' +',' ',text) # 替换多重空格为单空格
text = text.strip() #去除首尾空格
text = text.split(' ') # 对句子按照空格进行划分
text = [word for word in text if word not in stoplist] # 去除停用词
text = [PorterStemmer().stem(word) for word in text] # 还原词干部分
text.append('eos') # 添加结束符
text = ['bos'] + text #添加开始符
return text
3. 词向量训练模型word2vec使用介绍
3.1 word2vec模型的介绍
3.2 word2vec的优缺点one-hot 存在的问题:one-hot用来表达词向量非常简单,但是存在着很多问题。最大的问题是词汇表一般非常大,表达的效率不高。使用在卷积神经网络中会使得网络难以收敛。
------------------------------------------------------------分割线-------------------------------------------------------------------------
介绍:word2vec是一个NLP工具,是 Word Embedding 的方法之一,是一种可以解决one-hot的方法。
思路:通过训练将每个词都映射到一个较短的词向量上,所有的这些词向量就构成了向量空间。
特点:将所有的词向量化,这样词与词之间就可以定量的去度量他们之间的关系,挖掘词与词之间的联系。
word2vec的功能:就是将「不可计算」「非结构化」的词转化为「可计算」「结构化」的向量。
------------------------------------------------------------分割线-------------------------------------------------------------------------
百度百科版本:Word2vec,是一群用来产生词向量的相关模型。这些模型为浅而双层的神经网络,用来训练以重新建构语言学之词文本。网络以词表现,并且需猜测相邻位置的输入词,在word2vec中词袋模型假设下,词的顺序是不重要的。训练完成之后,word2vec模型可用来映射每个词到一个向量,可用来表示词对词之间的关系,该向量为神经网络之隐藏层。
3.3 word2vec的模型训练结构其优点:
(1)由于 Word2vec 会考虑上下文,跟之前的 Embedding 方法相比,效果要更好(但不如 18 年之后的方法)
(2)比之前的 Embedding方法维度更少,所以速度更快。
其缺点:
(1)由于词和向量是一对一的关系,所以多义词的问题无法解决。
(2)Word2vec 是一种静态的方式,虽然通用性强,但是无法针对特定任务做动态优化。
1.4 以gensim包对数据进行训练(程序7-5)如上图, word2vec具体的训练方法主要由2个方法:CBOW(Continuous Bag-of-Word Model,连续词袋模型)和Skip-gram模型。
- CBOW模型(左):CBOW是一个三层网络神经,该模型的特点是输入已知上下文,输出对当前单词的预测。
- Skip-gram模型(右):与CBOW模型相反,由当前词预测上下文词。
### 1.定义工具类
import re
def text_clear(text):
text = text.lower() #将文本转化成小写
text = re.sub(r'[^a-z0-9]',' ',text) #用空格替换非标准字符,^为求反操作
text = re.sub(r' +',' ',text) # 替换多重空格为单空格
text = text.strip() #去除首尾空格
text = text.split(' ') # 对句子按照空格进行划分
return text
### 2.处理数据
import csv
import numpy as np
agnews_label = []
agnews_title = []
agnews_text = []
# 便于处理数据
agnews_train = csv.reader(open('./ag_news_csv/train.csv','r'))
for line in agnews_train:
## 对于数字,得数字化转换;对于文字,得格式处理
#print(line)
agnews_label.append(np.float32(line[0]))
agnews_title.append(text_clear(line[1]))
agnews_text.append(text_clear(line[2]))
### 3.建立模型并保存
from gensim.models import word2vec
model = word2vec.Word2Vec(agnews_text,vector_size = 64,min_count = 0,window = 5, epochs = 128)
model_name = './corpusWord2Vec.bin'
model.save(model_name)
### 4.获取模型并进行训练
print("开始训练模型...")
from gensim.models import word2vec
model = word2vec.Word2Vec.load('./corpusWord2Vec.bin')
model.train(agnews_title,epochs = model.epochs,total_examples = model.corpus_count)
## out: (97931815, 110252672)
4. 文本主体的提取
4.1 文本主体的提取:基于TF-IDF 4.1.1 TF-IDF的原理(1)文本的提取关键字主要涉及两种算法:基于TF-IDF 和 基于TextRank。
(2)目标文本经过文本清洗和停用词的去除后,一般可以认为剩下的均有着目标含义的词。如果需要对其特征进行进一步的提取,提取能够代表文章的元素,包括词、短语、句子、标点以及其他信息的词。从词的角度来看,需要提取对文章表达贡献度大的词。
TF-IDF的介绍:
(1)是一种用于信息检索与信息勘测的常用加权技术。
(2)是一种统计方法,用来衡量一个词对一个文件及的重要程度。字词的重要性与其在文件中出现的次数成正比,而与其在文件集中出现的次数成反比。
------------------------------------------------------------分割线-------------------------------------------------------------------------
TF-IDF的主要思想:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为该词或者该短语具有很好的类别区分能力,适合用来分类。
- TF(Term Frequency):表示词条在文章中出现的频率。
- IDF(Inverter Document Frequency)的主要思想:包含某个词Word的文档越少,这个词的区分度越大,也就是IDF越大。
- TF-IDF = 词频 * 逆文档频率 = TF * IDF
此处将TF-IDF单独定义成一个类,便于后续使用。
## 1.定义TF-IDF类
class TFIDF_score:
def __init__(self,corpus,model = None):
self.corpus = corpus ##文集
self.model = model ##模型
self.idfs = self.__idf() ##IDF
## 计算每个单词的IDF值,并存储在init中
def __idf(self):
idfs = {}
d = 0.0
## 统计词出现次数
for doc in self.corpus:
d += 1
counted = []
for word in doc:
if not word in counted:
counted.append(word)
if word in idfs:
idfs[word] += 1
else:
idfs[word] = 1
## 计算每个词逆文档的值
for word in idfs:
idfs[word] = math.log(d/float(idfs[word]))
return idfs
## 计算IDF,并计算TF-IDF的值
def __get_TFIDF_score(self,text):
word_tfidf = {}
for word in text: ## 依次获得每个文档中的每个词
if word in word_tfidf: ## 计算每个词的词频
word_tfidf[word] += 1
else:
word_tfidf[word] = 1
for word in word_tfidf:
word_tfidf[word] *= self.idfs[word] ## 计算每个词的TF-IDF值
values_list = sorted(word_tfidf.items(),key = lambda word_tfidf:word_tfidf[1],reverse=True) ## 数据按重要程度从大到小排序
return values_list
def get_TFIDF_result(self,text):
values_list = self.__get_TFIDF_score(text)
value_list = []
for value in values_list:
value_list.append(value[0])
return (value_list)
## 2.获取目标数据
### 2.1 数据清洗类
import re
def text_clear(text):
text = text.lower() #将文本转化成小写
text = re.sub(r'[^a-z0-9]',' ',text) #用空格替换非标准字符,^为求反操作
text = re.sub(r' +',' ',text) # 替换多重空格为单空格
text = text.strip() #去除首尾空格
text = text.split(' ') # 对句子按照空格进行划分
return text
### 2.2 结合工具类text_clear获取目标数据
import csv
import numpy as np
agnews_label = []
agnews_title = []
agnews_text = []
# 便于处理数据
agnews_train = csv.reader(open('./ag_news_csv/train.csv','r'))
for line in agnews_train:
## 对于数字,得数字化转换;对于文字,得格式处理
#print(line)
agnews_label.append(np.float32(line[0]))
agnews_title.append(text_clear(line[1]))
agnews_text.append(text_clear(line[2]))
## 3. 载入程序7-5中的模型,对数据进行训练
## 主函数,使用
import math
from gensim.models import word2vec
model = word2vec.Word2Vec.load('./corpusWord2Vec.bin')
model.train(agnews_title,epochs = model.epochs,total_examples = model.corpus_count)
tfidf = TFIDF_score(agnews_text)
for line in agnews_text:
value_list = tfidf.get_TFIDF_result(line)
print(value_list)
print(model.wv[value_list])
## 结果为一个文本向量矩阵,每一个单词对应一个二维数组中的向量数组 ['cynics', 'dwindling', 'sellers', 'ultra', 'seeing', 'band', 'green', 'short', 'again', 'wall', 'street', 'are', 'reuters', 's', 'of'] [[ 1.17348909e+00 1.02108687e-01 -2.14409783e-01 5.70180178e-01 5.92369318e-01 -2.27488980e-01 8.21133733e-01 -1.15657197e-02 -1.33338773e+00 8.64599049e-01 6.07247353e-02 1.21579468e-01 -2.61938065e-01 -2.27355242e+00 9.15813267e-01 -1.07883906e+00 -1.14634979e+00 1.12520278e+00 -4.91948947e-02 -1.16895348e-01 7.24857509e-01 1.39616776e+00 1.17800856e+00 -1.72829461e+00 -5.66338658e-01 2.23885298e-01 1.25472039e-01 6.62063241e-01 -7.65496254e-01 1.92389220e-01 1.52555954e+00 5.19824445e-01 2.86635458e-01 -9.66206968e-01 -1.14739060e+00 -9.22317505e-01 -4.35026914e-01 -1.09736383e+00 6.40903533e-01 1.33023655e+00 -5.85277438e-01 -1.80912471e+00 1.23930439e-01 -1.80330956e+00 1.17725062e+00 1.23168588e+00 2.40483686e-01 -6.05988549e-03 1.87227798e+00 1.09425902e+00 1.05933940e+00 8.33601654e-01 4.79003996e-01 1.70514488e+00 -4.15998369e-01 1.31858647e+00 -5.62793136e-01 -1.34071529e+00 -2.29905796e+00 2.67159432e-01 1.65977216e+00 -1.72118330e+00 7.79630840e-01 8.27822387e-01] [ 4.38506985e+00 -3.03661752e+00 -1.20291913e+00 -1.15402424e+00 -2.12292576e+00 -2.24369192e+00 -7.53752887e-01 8.61398220e-01 -2.31971651e-01 1.48535773e-01 -4.51363707e+00 5.16624546e+00 -3.11404705e-01 5.79778291e-03 7.70554245e-01 2.35288286e+00 -9.58390176e-01 3.30757678e-01 -2.34791994e+00 -2.03470540e+00 ...4.2 文本主体的提取:基于TextRank 4.2.1 TextRank算法的介绍
4.2.2 TextRank算法的实现(程序7-8)(1)核心思想:
- 来源于著名的网页排名算法PageRank(用于解决链接分析中网页排名的问题)。
- 其将文本彩纷呈最小组成单元(词汇)作为网络节点,组成词汇网络图模型。
-----------------------------------------------------------------分割线----------------------------------------------------------------------
(2)TextRank提取文本关键词的步骤:
- 把给定的文本T按照完整句子进行分割;
- 对于每个句子,进行分词和词性标注处理,并过滤掉停用词,只保留指定词性的单词,如名词、动词、形容词。
- 构建候选关键词图G=(V,E),其中V为节点集,由每个词之间的相似度作为连接的边值。
- 根据下面的公式迭代传播公式,直至收敛:
- 对接点权重进行倒序排序,作为按重要程度排列的关键词。
## 1.TextRank算法的构建
class TextRank_score:
def __init__(self,agnews_text):
self.agnews_text = agnews_text
self.filter_list = self.__get_agnews_text()
self.win = self.__get_win()
self.agnews_text_dict = self.__get_TextRank_score_dict()
def __get_agnews_text(self):
sentence = []
for text in self.agnews_text:
for word in text:
sentence.append(word)
return sentence
def __get_win(self):
win = {}
for i in range(len(self.filter_list)):
if self.filter_list[i] not in win.keys():
win[self.filter_list[i]] = set()
if i-5 < 0:
lindex = 0
else:
lindex = i-5
for j in self.filter_list[lindex:i+5]:
win[self.filter_list[i]].add(j)
return win
def __get_TextRank_score_dict(self):
time = 0
score = {w:1.0 for w in self.filter_list}
while (time<50):
for k,v in self.win.items():
s = score[k]/len(v)
score[k] = 0
for i in v:
score[i] += s
time += 1
agnews_text_dict = {}
for key in score:
agnews_text_dict[key] = score[key]
return agnews_text_dict
def __get_TextRank_score(self,text):
temp_dict = {}
for word in text:
if word in self.agnews_text_dict.keys():
temp_dict[word] = (self.agnews_text_dict[word])
values_list = sorted(temp_dict.items(),key = lambda word_tfidf:word_tfidf[1],reverse=False) ## 数据按重要程度从大到小排序
return values_list
def get_TextRank_result(self,text):
temp_dict = {}
for word in text:
if word in self.agnews_text_dict.keys():
temp_dict[word] = (self.agnews_text_dict[word])
values_list = sorted(temp_dict.items(),key = lambda word_tfidf:word_tfidf[1],reverse=False) ## 数据按重要程度从大到小排序
value_list = []
for value in values_list:
value_list.append(value[0])
return (value_list)
## 2.获取目标数据,该部分与程序7.7相同
### 2.1 数据清洗类
import re
def text_clear(text):
text = text.lower() #将文本转化成小写
text = re.sub(r'[^a-z0-9]',' ',text) #用空格替换非标准字符,^为求反操作
text = re.sub(r' +',' ',text) # 替换多重空格为单空格
text = text.strip() #去除首尾空格
text = text.split(' ') # 对句子按照空格进行划分
return text
### 2.2 结合工具类text_clear获取目标数据
import csv
import numpy as np
agnews_label = []
agnews_title = []
agnews_text = []
# 便于处理数据
agnews_train = csv.reader(open('./ag_news_csv/train.csv','r'))
for line in agnews_train:
## 对于数字,得数字化转换;对于文字,得格式处理
#print(line)
agnews_label.append(np.float32(line[0]))
agnews_title.append(text_clear(line[1]))
agnews_text.append(text_clear(line[2]))
## 3.导入模型,对数据进行训练获取其向量矩阵
## 主函数,使用
import math
from gensim.models import word2vec
model = word2vec.Word2Vec.load('./corpusWord2Vec.bin')
model.train(agnews_title,epochs = model.epochs,total_examples = model.corpus_count)
textRank = TextRank_score(agnews_text)
for line in agnews_text:
value_list = textRank.get_TextRank_result(line)
print(value_list)
print(model.wv[value_list])
## 结果为一个文本向量矩阵,每一个单词对应一个二维数组中的向量数组 ## 与TF-IDF算法得到的文本向量矩阵一致 ['cynics', 'dwindling', 'sellers', 'ultra', 'seeing', 'band', 'green', 'short', 'wall', 'street', 'again', 'are', 'reuters', 's', 'of'] [[ 1.17348909e+00 1.02108687e-01 -2.14409783e-01 5.70180178e-01 5.92369318e-01 -2.27488980e-01 8.21133733e-01 -1.15657197e-02 -1.33338773e+00 8.64599049e-01 6.07247353e-02 1.21579468e-01 -2.61938065e-01 -2.27355242e+00 9.15813267e-01 -1.07883906e+00 -1.14634979e+00 1.12520278e+00 -4.91948947e-02 -1.16895348e-01 7.24857509e-01 1.39616776e+00 1.17800856e+00 -1.72829461e+00 -5.66338658e-01 2.23885298e-01 1.25472039e-01 6.62063241e-01 -7.65496254e-01 1.92389220e-01 1.52555954e+00 5.19824445e-01 2.86635458e-01 -9.66206968e-01 -1.14739060e+00 -9.22317505e-01 -4.35026914e-01 -1.09736383e+00 6.40903533e-01 1.33023655e+00 -5.85277438e-01 -1.80912471e+00 1.23930439e-01 -1.80330956e+00 1.17725062e+00 1.23168588e+00 2.40483686e-01 -6.05988549e-03 1.87227798e+00 1.09425902e+00 1.05933940e+00 8.33601654e-01 4.79003996e-01 1.70514488e+00 -4.15998369e-01 1.31858647e+00 -5.62793136e-01 -1.34071529e+00 -2.29905796e+00 2.67159432e-01 1.65977216e+00 -1.72118330e+00 7.79630840e-01 8.27822387e-01] [ 4.25027561e+00 -2.85347676e+00 -1.37562180e+00 -5.55923402e-01 -1.86602366e+00 -2.47801828e+00 -7.06179380e-01 1.77989691e-01 -3.90829116e-01 -1.60654616e-02 -4.09186506e+00 5.16973114e+00 -2.94205189e-01 1.05223686e-01 4.93972570e-01 1.74947226e+00 -7.62385488e-01 4.78628069e-01 -2.49241114e+00 -1.89942157e+00 5.75124562e-01 -6.23579323e-01 1.25777984e+00 -2.65328214e-02 -2.61453342e+00 1.17088020e+00 1.76670197e-02 2.22019523e-01 ...



