只说人话,不砌公式,让非数学专业读者能看明白的Word2Vec。
1. Word2Vec的作用
顾名思义,Word2Vec就是把单词转换成向量。它本质上是一种单词聚类的方法,是实现单词语义推测、句子情感分析等目的一种手段。
选取训练后的单词向量的其中任意3个维度,放到坐标系中展示,会发现语义相似的词汇在空间坐标中的位置会十分接近,而语义无关的词之间则相距较远。这种性质可以用来对单词和句子进行更加泛化的分析。
词向量在空间的表示一些研究还发现,计算有相似关系的单词之间的位移向量也会十分相似,例如从“Man”到“Wonman”的向量,与从“King”到“Queen”之间的向量几乎相同。这对语言和语义学的研究提供一种新的途径。
词向量与词意的关联关于更多Word2Vec的应用场景,请看:
知乎:word2vec有什么应用?
CSDN:深度学习word2vec笔记之应用篇
2. 传统方法
单词变向量其实可以不通过神经网络直接得到。假设我们有一个足够大的语料库(其中包含各种各样的句子,比如维基百科词库就是很好的语料来源),通常语义比较接近的词周边经常出现的词也应该差不多,所以判断一个词和哪些词比较像,就是找到这个词周围的词和哪些词周围的词比较像。那么最笨(但很管用)的办法莫过于将语料库里的所有句子扫描一遍,挨个数出每个单词周围出现其它单词的次数,做成下面这样的表格就可以了。
词频表做这个表格时候,语料库里的单词量可能多大几十万种,做这么大的表格实在太费劲。实际的做法是只选出其中一部分词汇(比如统计出在语料库里词频最高的一部分词汇),其余(出现频率很低)的词都用一个特殊符号代替掉。比如选5万个词,把这个表格保存成矩阵,就是5万x5万的矩阵,矩阵的每行就是相应词的一个5万维向量表示。有了空间向量,两个词的关系就可以用数学关系表示了,比如向量的距离和相对空间关系。
但是这个向量实在太大,并且过于稀疏,且不说矩阵中的绝大多数数据都是0,光是计算两个词的距离就需要5万次减法、5万次乘法、49999次加法以及1次开方。所以在真正用的时候,还需要对向量进行降维(主成分分析)处理。方形矩阵的主成分分析可以使用特征值分解或者奇异值分解实现,比如保留特征最大的50个分量,最终得到5万x50的矩阵,每个词的向量就只有50维,并且最大化的保留了各矩阵之间的位置关系。这个矩阵被称为“嵌入(Embedding)矩阵”。
关于主成分分析以后另起一篇文章介绍,先推荐两篇网络上写得比较好的:
主成分分析降维(MNIST数据集)
强大的矩阵奇异值分解(SVD)及其应用
看起来不错,不过计算这样的一个原始矩阵需要多少内存呢?假设矩阵的每个数字都用标准32位Int表示,那么完整保存一个5万x5万维的矩阵,大约需要10,000,000,000个byte,也就是10GB的内存(且随着词汇量增加程平方倍增长,汉语常用词汇大约有20万个)。虽然还有一些优化的空间,比如说使用稀疏矩阵来保存这些数据,即便如此,在性能和内存开销上依然差强人意。从最终结果来看,我们其实想要的那个降维后的嵌入矩阵,有没办法不要生成这个原始矩阵,直接得到嵌入矩阵呢?使用传统的方法是办不到了。
3. 神经网络
既然传统方法做不了,只能另辟蹊径。这个时候Google发表的一篇论文祭出了神经网络大法,论文原文见这个链接:
Exploiting Similarities among Languages for Machine Translation
这个论文里的模型后来被人们称为“Word2Vec”,其实是因为Google论文开源的Git代码仓库名字就叫叫“Word2Vec”。在论文里的计算模型包括两种:Continuous Bag of Words(CBOW)和Skip-Gram,别看这两个模型名字相差这么大,在论文的附图里看起来也差别那么大,其实两者在实现上的差别仅仅是调换一下训练词和目标词的位置。除去代码和模型里面的一些算法优化部分,Word2Vec的最简单版本,可以认为是逻辑回归网络的一种变形。
两种基于神经网络的词向量生成模型以CBOW为例,还是每次挨个把语料库的词取出来,作为该次训练的目标,然后把这个词所在位置的前后N个词(N通常用1或者2,数字越大学习到的模型信息量越丰富,但需要的训练时间越长)依次作为训练的输入。比如N值为2,每取出一个词(作为中心词),就要使用该词的前后各2个词(作为环境词),分别放到网络训练一次,一共要取4个环境词。还是以识别5万个词的向量为例,具体训练过程如下:
- 首先预处理数据,把所有需要进行训练的词汇编上序号,比如1-50000
- 随机初始化一个维度为50000x50的矩阵,作为待训练的嵌入矩阵
- 每次取出一个中心词和它的其中一个环境词
- 以环境词编号作行数,从词向量矩阵里取出这一行数据(50维向量)
- 将这个50维向量作为逻辑回归网络的输入,训练目标是中心词编号相应的One-Hot向量
- 在训练的反向传播时计算,不但更新逻辑回归网络的权重矩阵,还要往前多传递一级,把取出的50维向量的值也根据目标梯度进行更新
- 将更新过的50维向量重新更新到嵌入矩阵相应的行
- 重复以上过程,直到所有的中心词都已经被遍历一遍,此时嵌入矩阵值的计算就完成了
你没看错,那个50000x50维的向量就是嵌入矩阵,整个训练过程就是直接对这个矩阵进行更新。Skip-Gram的算法就是把第3步的输入词和第4步的目标词对调一下。虽然对于生成嵌入矩阵而言,两种方法效果基本相同(统计数据表明,Skip-gram在训练数据量较大时得到的词向量效果比CBOW略佳),需要指出的是两种模型本身所蕴含的意义是不太一样的。CBOW用环境词预测中心词,得到逻辑回归网络可以用来预测类似“一句话中缺少了一个单词,这个单词最可能是什么”这样的问题。而Skip-Gram使用中心词来预测环境词,因此它可以用来预测类似“给定一个单词,它周边最可能出现哪些单词”的问题。
由于神经网络计算过程的模糊性,对Work2Vec和其他同类实现的效果曾经有过一些争议,但随后就有些第三方机构提供了测试数据来支撑Word2Vec理论的可靠性。其中比较有意思的是2014在美国计算机语言学协会年度会议上提出的论文《Don’t count, predict!》
4. 真实的Word2Vec
前面部分介绍的简化版Word2Vec过程实际上是为了便于大家理解而概括出来的。这个理想的模型当中存在一些无法回避的问题,比如输出的部分是一个50000维的One-Hot向量,因此数据经过网络后应该得到的也是一个50000维的向量,对这个输出向量进行Softmax计算所需的工作量将是一个天文数字。
Google论文里真实实现的Word2Vec对模型提出了两种改进思路,即Hierarchical Softmax模型和Negative Sampling模型。
Hierarchical Softmax是用输出值的霍夫曼编码代替原本的One-Hot向量,用霍夫曼树替代Softmax的计算过程。
Negative Sampling(简称NEG)使用随机采用替代Softmax计算概率,它是另一种更严谨的抽样模型NCE的简化版本。
关于Hierarchical Softmax和Negative Sampling的原理细节(包含太多数学公式,白话不出来了,谁要能帮我把这部分讲清楚,我请吃饭_)可参看以下文章:
word2vec 代码实现(1) – Skip gram
word2vec 代码实现(2) – CBOW
word2vec原理篇
深度学习word2vec笔记之算法篇
将这两种算法与前面的两个模型组合,在Google的论文里一共包含了4种Word2Vec的实现。
- Hierarchical Softmax CBOW 模型
- Hierarchical Softmax Skip-Gram 模型
- Negative Sampling CBOW 模型
- Negative Sampling Skip-Gram 模型
在Tensorflow里最常见的实现例子是Negative Sampling Skip-Gram,比如:
其中的抽样算法封装在了tf.nn.nce_loss
方法里面。
最后附上网络上一个对Word2Vec讲解比较具有系统性的系列博客“word2vec中的数学原理详解”:
前言
预备知识
背景知识
基于 Hierarchical Softmax 的模型
基于 Negative Sampling 的模型
若干源码细节
网友评论