基于gensim实现word2vec模型(附案例实战)
什么是word2vec?
Word2Vec是google在2013年推出的一个NLP工具,它的特点是能够将单词转化为向量来表示,这样词与词之间就可以定量的去度量他们之间的关系,挖掘词之间的联系。用词向量来表示词并不是Word2Vec的首创,在很久之前就出现了。最早的词向量采用OneHot编码,又称为一位有效编码,每个词向量维度大小为整个词汇表的大小,对于每个具体的词汇表中的词,将对应的位置置为1。比如我们有下面的5个词组成的词汇表:
采用OneHot编码方式来表示词向量非常简单,但缺点也是显而易见的,一方面我们实际使用的词汇表很大,经常是百万级以上,这么高维的数据处理起来会消耗大量的计算资源与时间。另一方面,OneHot编码中所有词向量之间彼此正交,没有体现词与词之间的相似关系。
Distributedrepresentation可以解决OneHot编码存在的问题,它的思路是通过训练,将原来OneHot编码的每个词都映射到一个较短的词向量上来,而这个较短的词向量的维度可以由我们自己在训练时根据任务需要来自己指定。
下图是采用Distributedrepresentation的一个例子,我们将词汇表里的词用Royalty,Masculinity,Femininity和Age4个维度来表示,King这个词对应的词向量可能是(0。99,0。99,0。05,0。7)。当然在实际情况中,我们并不能对词向量的每个维度做一个很好的解释。
Word2Vec的原理
Word2Vec的训练模型本质上是只具有一个隐含层的神经元网络(如下图)。
它的输入是采用OneHot编码的词汇表向量,它的输出也是OneHot编码的词汇表向量。使用所有的样本,训练这个神经元网络,等到收敛之后,从输入层到隐含层的那些权重,便是每一个词的采用DistributedRepresentation的词向量。比如,上图中单词的Wordembedding后的向量便是矩阵WvxN的第i行的转置。这样我们就把原本维数为V的词向量变成了维数为N的词向量(N远小于V),并且词向量间保留了一定的相关关系。
gensim实现word2vec模型(实战)
本次实战案例选取的数据集是四大名著中的三国演义。
首先使用jieba进行中文分词,
分词之后使用gensim库中的word2vec构建模
从结果中我们看出,与孔明相关性最高的是玄德、云长、孟获,也符合小说中的角色关系。
接着我们将模型可视化,
importnumpyasnp
fromsklearn。decompositionimportPCA
将词向量投影到二维空间
rawWordVec〔〕
word2ind{}
fori,winenumerate(model。wv。indextokey):
rawWordVec。append(model。wv〔w〕)词向量
word2ind〔w〕i{词语:序号}
rawWordVecnp。array(rawWordVec)
XreducedPCA(ncomponents2)。fittransform(rawWordVec)PCA降2维
importmatplotlib。pyplotasplt
plt。rcParams〔font。sansserif〕〔SimHei〕解决中文显示
plt。rcParams〔axes。unicodeminus〕False解决符号无法显示
绘制星空图
绘制所有单词向量的二维空间投影
figplt。figure(figsize(15,10))
axfig。gca()
ax。setfacecolor(white)
ax。plot(Xreduced〔:,0〕,Xreduced〔:,1〕,。,markersize1,alpha0。3,colorblack)
绘制几个特殊单词的向量
words〔孙权,刘备,曹操,周瑜,诸葛亮,司马懿,汉献帝〕
forwinwords:
ifwinword2ind:
indword2ind〔w〕
xyXreduced〔ind〕
plt。plot(xy〔0〕,xy〔1〕,。,alpha1,colororange,markersize10)
plt。text(xy〔0〕,xy〔1〕,w,alpha1,colorred)
最后,我们还可以做个类比关系实验,
比如,孔明是玄德的军师,那么曹操的军师是谁呢?