Lz的研究方向大概定了下来,应该会涉及到评论文本分析,所以最近导师让我看看文本数据预处理这块,然后我上Github上找到了这个项目,跟着做了一下。然后通过自己爬取的某多多平台评论数据进行了实际操作,最后也是能够出结果。(这个出结果的意思是能够把文本数据转化成词向量,并且可以得出某词的余弦相似度,随后的主题提取,情感分析我还在看)。话不多说,直接进入正题。
这个维基百科中文语料库在网上有很多资源,我就不提供渠道了,我就把我的这个文本放到下面百度网盘链接里了,需要的自取。
链接:https://pan.baidu.com/s/1bax33-wAbxyUokah9YhaeA
提取码:zxt1
这个语料库有点大,但是还是有的词他不存在,所以中华文化真的是博大精深。
我将整个过程分为以下步骤:
1、语料库格式转换
下载的维基百科语料库是xml格式,需要转换成txt格式;且部分语料是繁体,所以需要转换成简体。但是我这份代码直接一步搞定,直接从xml格式转换成txt简体中文,不需要opencc什么的软件,虽然我也费劲巴拉的下载了这个opencc,但最后还是看不懂网上的教程,最后好在发现了这份代码,但是作者找不到了,如果有小伙伴发现的话,希望能偶提醒我一下。
2、分词
本文采用的是jieba分词,效果很好,很容易调用。
3、使用word2vec来训练文本词向量模型
注意这个word2vec是针对这个维基百科文本数据进行的训练,所以只有这份数据里出现过得词才会有对应的词向量,如果你有新的词,最后可以通过增量训练的方式加入进去,我昨天也是搞了很久这个增量训练,但是没成功。
强烈建议这三步分为三个子文件分别执行,不然每进行一次就要转换很久格式,第一步的语料库格式转换我是花费了80分钟才整完,所以把这几步单独整,可以避免很多麻烦事。
步骤就先这三步吧,下面看看代码吧。
1、语料库格式转换(这个是在网上找的一份代码,如有知道出处的可以提醒我一下,谢谢啦~)
其中,extract_pages函数后面是需要放入你自己语料库的文件位置,别弄错了哦,虽然网上很多教程已经很详细了,但是针对我们初学者,很多细节是我们注意不到的,但是这些细节在网上那些大佬看来是不用提起的操作,但是对于我们来说可能需要想半天,找很久的教程,这个我真的深有感触。
# -*- coding: utf-8 -*-
import imp
import sys
imp.reload(sys)
# sys.setdefaultencoding('utf8')
from gensim.corpora.wikicorpus import extract_pages, filter_wiki
import bz2file ####记得安装呀!!!
import re
from opencc import OpenCC ####修改过
from tqdm import tqdm
import codecs
wiki = extract_pages(bz2file.open(r"C:\Users\28493\Downloads\zhwiki-latest-pages-articles.xml.bz2"))
cc = OpenCC('t2s') ###修改过
def wiki_replace(d):
s = d[1]
s = re.sub(':*{\|[\s\S]*?\|}', '', s)
s = re.sub('[\s\S]*? ', '', s)
s = re.sub('(.){{([^{}\n]*?\|[^{}\n]*?)}}', '\\1[[\\2]]', s)
s = filter_wiki(s)
s = re.sub('\* *\n|\'{2,}', '', s)
s = re.sub('\n+', '\n', s)
s = re.sub('\n[:;]|\n +', '\n', s)
s = re.sub('\n==', '\n\n==', s)
s = u'【' + d[0] + u'】\n' + s
return cc.convert(s).strip() ####修改过
i = 0
f = codecs.open('00000wiki.txt', 'w', encoding='utf-8') ####自己改名字就好了!叫狗蛋都行
w = tqdm(wiki, desc=u'已获取0篇文章')
for d in w:
if not re.findall('^[a-zA-Z]+:', d[0]) and d[0] and not re.findall(u'^#', d[1]):
s = wiki_replace(d)
f.write(s + '\n\n\n')
i += 1
if i % 100 == 0:
w.set_description(u'已获取%s篇文章' % i)
f.close()
这个整完后会在你的pycharm左边文件界面出现一个 txt 文件,本文的是“00000wiki.txt”,当然这个名字可以随便改。
2、分词
jieba分词真的好用,名字起的也是很形象。代码如下
其中jieba在使用时会用到两个文件,一个是停用词文件,一个是jieba的词典库。这两个是公用的,应该用到jieba这个包就一定会用到这两个文件,文件放到下面百度网盘链接里了。在代码中对应的是“jieba.set_dictionary”和“stopword_set”下面的文件。
链接:https://pan.baidu.com/s/1yxdC_aK10K859QDW7Ke_Dw
提取码:zxt1
import jieba
import logging
def main():
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
# jieba custom setting.
jieba.set_dictionary(r"C:\Users\28493\OneDrive\桌面\word2vec实战教学\jieba_dict\dict.txt.big")
# load stopwords set
stopword_set = set()
with open(r"C:\Users\28493\OneDrive\桌面\word2vec实战教学\jieba_dict\stopwords.txt", 'r', encoding='utf-8') as stopwords:
for stopword in stopwords:
stopword_set.add(stopword.strip('\n'))
output = open('wiki_seg.txt', 'w', encoding='utf-8')# 最后输出的文件名称
with open('00000wiki.txt', 'r', encoding='utf-8') as content:
for texts_num, line in enumerate(content):
line = line.strip('\n')
words = jieba.cut(line, cut_all=False)
for word in words:
if word not in stopword_set:
output.write(word + ' ')
output.write('\n')
if (texts_num + 1) % 10000 == 0:
logging.info("已完成前 %d 行的斷詞" % (texts_num + 1))
output.close()
if __name__ == '__main__':
main()
最后会得到一个分词完成后的文件,本文中是“wiki_seg.txt”。同样也会出现在你的pycharm界面左方。
3、词向量模型训练
这一步,只要把分词后的“wiki_seg.txt”放进去就行,代码中的“wiki_seg.txt”是个地址,应该不是词,所以还是在左边右击这个文件,最后复制文件地址。
import logging
from gensim.models import word2vec, Word2Vec
def main():
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
sentences = word2vec.LineSentence("wiki_seg.txt")
model = word2vec.Word2Vec(sentences, vector_size=250)
# 保存模型,供日後使用
model.save("word2vec.bin")
# 模型讀取方式
# model = word2vec.Word2Vec.load("your_model_name")
if __name__ == '__main__':
main()
word2vec_model = Word2Vec.load("word2vec.bin")
# word2vec_model = word2vec.Word2Vec.load('word2vec.bin')
word2vec_model.wv.save_word2vec_format('word2vec.txt', binary=False)
# 查看词向量
print('北京:', word2vec_model.wv['北京'])
A = word2vec_model.wv['北京']
sim_words = word2vec_model.wv.most_similar(u'北京')
for w in sim_words:
print(w)
sim_words1 = word2vec_model.wv.similarity(u'北京', u'天津')
print(sim_words1)
训练完成后模型可以保存为很多形式,本文保存成“word2vec.bin”这个是模型名称,应该是打不开的;所以把它的格式进行转换,转换成下面的“word2vec.txt”或者“word2vec.vector”这俩是可以直接打开,可以看到对应的词向量,文件最终都会出现在pycharm界面的左边。
然后,你就可以输入随意的词来输出它的词向量矩阵,以及输出与这个词在本文档中相似度最高的词,以及探究随意给定的两个词之间相似度是多少。这里都用的是余弦相似度。
至于在词向量设置好之后怎么应用我现在也不太清楚。老师让我把销售数据整理成矩阵形式,文本数据要么转换成词向量形式进行词嵌入,要么通过词典方法进行分词,主题提取、情感分析。这些我现在都是一头雾水。
下面我用我自己爬取的某多多平台商品数据进行实验,数据大概是200条,爬去下来时excel形式,需要手动把它复制贴到文本文档中,所以对于我们做中文的评论分析,什么xml转换成txt,然后再繁转简其实都是不需要的,即本文的第一步其实是不经常用到的。最后贴到文本文档中的数据格式如下图所示
将这个文本先进行分词,带入到第二步的代码中,如下所示,最终输出的格式名称是Pdd.txt
import jieba
import logging
def main():
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
# jieba custom setting.
jieba.set_dictionary(r"C:\Users\28493\OneDrive\桌面\word2vec实战教学\jieba_dict\dict.txt.big")
# load stopwords set
stopword_set = set()
with open(r"C:\Users\28493\OneDrive\桌面\word2vec实战教学\jieba_dict\stopwords.txt", 'r', encoding='utf-8') as stopwords:
for stopword in stopwords:
stopword_set.add(stopword.strip('\n'))
output = open('Pdd.txt', 'w', encoding='utf-8')
with open(r"C:\Users\28493\OneDrive\桌面\拼多多批发数据\评论.txt", 'r', encoding='utf-8') as content:
for texts_num, line in enumerate(content):
line = line.strip('\n')
words = jieba.cut(line, cut_all=False)
for word in words:
if word not in stopword_set:
output.write(word + ' ')
output.write('\n')
if (texts_num + 1) % 10000 == 0:
logging.info("已完成前 %d 行的斷詞" % (texts_num + 1))
output.close()
if __name__ == '__main__':
main()
分词后的结果如下图所示
此时再进行第三步,将分好词的文本放入到word2vec中训练,代码如下
import logging
from gensim.models import word2vec
def main():
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
sentences = word2vec.LineSentence("Pdd.txt")
model = word2vec.Word2Vec(sentences, vector_size=250)
# 保存模型,供日後使用
model.save("Pdd.model")
model.wv.save_word2vec_format('Pdd.vector')
# 模型讀取方式
# model = word2vec.Word2Vec.load("your_model_name")
if __name__ == '__main__':
main()
word2vec_model = word2vec.Word2Vec.load('Pdd.model')
# 查看词向量
print('价格:', word2vec_model.wv['儿子'])
A = word2vec_model.wv['儿子']
sim_words = word2vec_model.wv.most_similar(u'儿子') # 这是探究与‘北京这个词相似度最高的几个词’
for w in sim_words:
print(w)
sim_words1 = word2vec_model.wv.similarity(u'儿子', u'舒服') # 这是探究两个词之间的相似度
print(sim_words1)
最终保存为Pdd.model,然后就可以查看不同词的相关数据了。
以上就是我的所有分享,有很多都是在网上找的代码,如果有冒犯到作者或者其他人的,还望海涵,通知我我会及时改正。
不说了,干饭去了,希望大家赏个小心心,谢谢同志们~