word2vec是google的一个开源工具,能够根据输入的词的集合计算出词与词之间的距离。它将term转换成向量形式,可以把对文本内容的处理简化为向量空间中的向量运算,计算出向量空间上的相似度,来表示文本语义上的相似度。
需要注意的是,word2vec计算的是余弦值,距离范围为0-1之间,值越大代表两个词关联度越高。
下面通过一个完整的实例来看看word2vec是如何使用的。
一、jieba分词
由于是对中文语料进行处理,所以要先对中文语料进行分词。
from gensim.corpora import Dictionary
import jieba
import pandas as pd
import os
from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator
import PIL.Image as image
from imageio import imread
# 创建输出结果目录
output_dir = u'output_word2vec'
if not os.path.exists(output_dir):
os.mkdir(output_dir)
"""
通过jieba进行分词并保存分词后的结果。
步骤如下:
1.导入txt
2.去掉所有的标点符号换行符以及停用词
3.load特定的词库
4.分词
5.保存分词结果
"""
# 导入txt并去掉多余的换行和空格
sao = open('sao_dg.txt',encoding='utf-8').read().replace('\n','').replace(' ','')
# 导入停用词库
stopwords = pd.read_table('stop_words.txt',names=['words'],encoding='utf-8')
# stopwords.head()
# 导入特定的词库
jieba.load_userdict('刀剑词库.txt')
# 分词
new_sao = [word for word in jieba.lcut(sao) if word not in list(stopwords['words'])]
# new_sao
# 分词结果保存为seg_sao.txt
seg_word_file = os.path.join(output_dir, 'seg_sao.txt')
with open(seg_word_file, 'wb') as outfile:
for words in new_sao:
outfile.write(u''.join(words).encode('utf-8') + b'\n')
print (u'分词结果路径:{}'.format(seg_word_file))
二、wordcloud词云图
对txt文件分词完后,可以通过wordcloud绘制词云看看有哪几个词出现的频率最高
import numpy as np
from PIL import Image
sentence = open(r'output_word2vec\seg_sao.txt',encoding='utf-8').read().replace('\n',' ')
#获取词云轮廓形状图
shape_image=np.array(Image.open('tr_outline.jpg'))
#生成词云图,此处默认为随机染色,当文本数量较少(看处理效果)时,将repeat设置为True
word_cloud=WordCloud(background_color='white',font_path='msyh.ttc', mask=shape_image,min_font_size=1)
word_cloud.generate(sentence)
word_cloud.to_file('sao_wc.png')
效果如图:
由于我所使用的停用词库并不是很完整,所以wordcloud中还是会看到一些停用词。
三、word2vec参数详解以及训练和使用
使用Gensim训练word2vec相对来说十分方便,也非常简单。
具体步骤大致分三步:
1.通过LineSentence将分词后的预料转换成一个迭代器
2.用Word2Vec训练模型
3.保存模型
4.使用模型
from gensim.models import Word2Vec
from gensim.models.word2vec import LineSentence
# 创建一个句子迭代器,一行为一个句子,词和词之间用空格分开
# 这里我们把一篇文章当作一个句子
sentences = LineSentence(seg_word_file)
# 训练模型
model = Word2Vec(sentences=sentences, size=100, iter=10, min_count=20)
# 保存模型
model_file = os.path.join(output_dir, 'model.w2v')
model.save(model_file)
在这里需要注意下Word2Vec的一些参数设置
语法:
Word2Vec(sentences=None, corpus_file=None, size=100, alpha=0.025,
window=5, min_count=5, max_vocab_size=None, sample=0.001,
seed=1, workers=3, min_alpha=0.0001, sg=0, hs=0, negative=5,
ns_exponent=0.75, cbow_mean=1, hashfxn=<built-in function hash>,
iter=5, null_word=0, trim_rule=None, sorted_vocab=1, batch_words=10000,
compute_loss=False, callbacks=(), max_final_vocab=None)
参数:
- size:
是指特征向量的维度,默认为100。 - alpha:
是初始的学习速率,在训练过程中会线性地递减到min_alpha。 - window:
窗口大小,表示当前词与预测词在一个句子中的最大距离是多少。 - min_count:
可以对字典做截断. 词频少于min_count次数的单词会被丢弃掉, 默认值为5。 - max_vocab_size:
设置词向量构建期间的RAM限制,设置成None则没有限制。 - sample:
高频词汇的随机降采样的配置阈值,默认为1e-3,范围是(0,1e-5)。 - seed:
用于随机数发生器。与初始化词向量有关。 - workers:
用于控制训练的并行数。 - min_alpha:
学习率的最小值。 - sg:
用于设置训练算法,默认为0,对应CBOW算法;sg=1则采用skip-gram算法。 - hs:
如果为1则会采用hierarchica·softmax技巧。如果设置为0(默认),则使用negative sampling。 - negative:
如果>0,则会采用negativesampling,用于设置多少个noise words(一般是5-20)。 - cbow_mean:
如果为0,则采用上下文词向量的和,如果为1(default)则采用均值,只有使用CBOW的时候才起作用。 - hashfxn:
hash函数来初始化权重,默认使用python的hash函数。 - iter:
迭代次数,默认为5。 - trim_rule:
用于设置词汇表的整理规则,指定那些单词要留下,哪些要被删除。可以设置为None(min_count会被使用)。 - sorted_vocab:
如果为1(默认),则在分配word index 的时候会先对单词基于频率降序排序。 - batch_words:
每一批的传递给线程的单词的数量,默认为10000。
训练好模型后,就可以使用该模型了
# 导入模型
model_sao = Word2Vec.load(model_file)
# 计算两个词的相似度
model_sao.similarity(u'狙击',u'武器')
# 计算与武器最相关的20个词
model.most_similar(u'武器',topn=20)
其实和本人所预想的还是有很大的出入的,但大致的流程还是蛮通俗易懂的。不过该语料也只是该小说的一个小章节,后续会对该实例进行完善和修正的