SVD分解(三):连Word2Vec都只不过是个SVD?
By 苏剑林 | 2017-02-23 | 96507位读者 |这篇文章要带来一个“重磅”消息,如标题所示,居然连大名鼎鼎的深度学习词向量工具Word2Vec都只不过是个SVD!
当然,Word2Vec的超级忠实粉丝们,你们也不用太激动,这里只是说模型结构上是等价的,并非完全等价,Word2Vec还是有它的独特之处。只不过,经过我这样解释之后,估计很多问题就可以类似想通了。
词向量=one hot #
让我们先来回顾一下去年的一篇文章《词向量与Embedding究竟是怎么回事?》,这篇文章主要说的是:所谓Embedding层,就是一个one hot的全连接层罢了(再次强调,这里说的完全等价,而不是“相当于”),而词向量,就是这个全连接层的参数;至于Word2Vec,就通过大大简化的语言模型来训练Embedding层,从而得到词向量(它的优化技巧有很多,但模型结构就只是这么简单);词向量能够减少过拟合风险,是因为用Word2Vec之类的工具、通过大规模语料来无监督地预训练了这个Embedding层,而跟one hot还是Embedding还是词向量本身没啥关系。
有了这个观点后,马上可以解释我们以前的一个做法为什么可行了。在做情感分类问题时,如果有了词向量,想要得到句向量,最简单的一个方案就是直接对句子中的词语的词向量求和或者求平均,这约能达到85%的准确率。事实上这也是facebook出品的文本分类工具FastText的做法了(FastText还多引入了ngram特征,来缓解词序问题,但总的来说,依旧是把特征向量求平均来得到句向量)。为什么这么一个看上去毫不直观的、简单粗暴的方案也能达到这么不错的准确率?
回到我们用one hot的时代,我们是这样表示一个句子的。假如我们将“我”、“爱”、“科学”、“空间”、“不”、“错”六个词用下面的one hot编码:
$$\begin{array}{c|c}\hline\text{我} & [1, 0, 0, 0, 0, 0]\\
\text{爱} & [0, 1, 0, 0, 0, 0]\\
\text{科学} & [0, 0, 1, 0, 0, 0]\\
\text{空间} & [0, 0, 0, 1, 0, 0]\\
\text{不} & [0, 0, 0, 0, 1, 0]\\
\text{错} & [0, 0, 0, 0, 0, 1]\\
\hline
\end{array}$$
那么不考虑词序的话,“我爱空间科学”这个短语就可以用下面的向量(词袋)表示:
\begin{pmatrix}1 & 1 & 1 & 1 & 0 & 0\end{pmatrix}
有了这个向量之后,要用神经网络做分类,后面可以接一个全连接层,隐藏节点为3:
$$\begin{aligned}&\begin{pmatrix}1 & 1 & 1 & 1 & 0 & 0\end{pmatrix}\begin{pmatrix}w_{11} & w_{12} & w_{13}\\
w_{21} & w_{22} & w_{23}\\
w_{31} & w_{32} & w_{33}\\
w_{41} & w_{42} & w_{43}\\
w_{51} & w_{52} & w_{53}\\
w_{61} & w_{62} & w_{63}\end{pmatrix}\\
=&\begin{pmatrix}w_{11}+w_{21}+w_{31}+w_{41} & w_{12}+w_{22}+w_{32}+w_{42} & w_{13}+w_{23}+w_{33}+w_{43}\end{pmatrix}\end{aligned}$$
咦?这不就是将前4个向量拿出来相加吗?
这样情况就清晰了。如果我们用传统的词袋模型,不考虑词序,然后后面接一个全连接层。为了防止过拟合,这个全连接层的参数用预训练的词向量代替,那么结果就是等价于直接将对应的词向量取出,然后求和!也就是说,词向量求和得到句向量,实际上就是传统的词袋模型的等价物!
Word2Vec=SVD? #
自始至终,笔者谈及Word2Vec与SVD的等价性时,都会带一个问号。这是因为,它们两者的模型结构是等价的,但实现方式又不一样,这算不算等价,只能看读者心中对于“等价”的定义了。
事实上,词向量这个概念很早就有了,当时还不叫Word Embedding,是叫distributed representation,即分布式表示,其本意就是词的上下文能够帮助我们理解我们这个词。现在假设总词表有$N$个词,用one hot表示就是将每个词表示成一个$N$维的向量;而分布式表示,就是设想开一个窗口(前后若干个词加上当前词,作为一个窗口),然后统计当前词的前后若干个词的分布情况,就用这个分布情况来表示当前词,而这个分布也可以用相应的$N$维的向量来表示。由于是通过上下文分布来表示一个词,而不再是孤立地“独热”了,因此能够表示语义的相关性,但问题是它还是$N$维的,维度还是太大了,整个词向量表(共现矩阵)太稀疏。
怎么办呢?其实数学家早就有解决办法了,对于稀疏矩阵,一个既能够降维,又可以提高泛化能力的方案就是对矩阵SVD分解。而本系列的第一篇就说了,SVD分解等价于一个三层的自编码器,于是放到今天来看,这种方案就是说:原始的分布式表示的词向量是$N$维的,太大,我们可以用自编码器来降低维度嘛,自编码器的中间节点数记为$n$,把$n$设置为一个适当的值,训练完自编码器后,直接把中间层的$n$维结果就作为新的词向量就行了。所以说,这就是一个$N$维输入,中间节点为$n$个,$N$维输出的自编码器方案,也等价于一个SVD分解。
那么,还没有说到Word2Vec呢?Word2Vec的模型又要怎么看呢?Word2Vec的一个CBOW方案是,将前后若干个词的词向量求和,然后接一个$N$维的全连接层,并做一个softmax来预测当前词的概率。本文的前半部分说了,这种词向量求和,等价于原来的词袋模型接一个全连接层(这个全连接层的参数就是词向量表),这样来看,Word2Vec也只是一个$N$维输入,中间节点为$n$个,$N$维输出的三层神经网络罢了,所以从网络结构上来看,它跟自编码器等价,也就是跟SVD分解等价。
从实现上来看,区别也很明显:
1、Word2Vec的这种方案,可以看作是通过前后词来预测当前词,而自编码器或者SVD则是通过前后词来预测前后词;
2、Word2Vec最后接的是softmax来预测概率,也就是说实现了一个非线性变换,而自编码器或者SVD并没有。
这两个区别在多大程度上影响了词向量的质量,我没有严格的数学证明,但是从实际测试来看,相同的语料情况下,Word2Vec的词向量质量似乎更胜一筹。
不是总结的总结 #
本文通过一系列头脑风暴,来思考传统的分布式表示和Word2Vec的模型的练习,最后得到这样的结果。这样的思考的最主要的一个目的是把各个方面的东西联系起来,使我们的认识更加贴近本质,而这或许会对我们应用模型甚至构建模型都起到重要的指导作用。总的来说,这系列的几篇文章告诉我们,将很多运算或者模型写成矩阵形式后,能够看出很多东西的本质,并且有助于引导我们思考改进的方向,比如很多模型实际上可以写成矩阵乘法,然后矩阵乘法就相当于一层神经网络,既然神经网络,那是不是可以加多层?是不是可以加激活函数?是不是可以用SVD分解一下?因为根据本系列第二篇,SVD具有明确的聚类意义。诸如此类的思考,就可以帮助我们搭建模型甚至泛化模型了。
转载到请包括本文地址:https://kexue.fm/archives/4233
更详细的转载事宜请参考:《科学空间FAQ》
如果您还有什么疑惑或建议,欢迎在下方评论区继续讨论。
如果您觉得本文还不错,欢迎分享/打赏本文。打赏并非要从中获得收益,而是希望知道科学空间获得了多少读者的真心关注。当然,如果你无视它,也不会影响你的阅读。再次表示欢迎和感谢!
如果您需要引用本文,请参考:
苏剑林. (Feb. 23, 2017). 《SVD分解(三):连Word2Vec都只不过是个SVD? 》[Blog post]. Retrieved from https://kexue.fm/archives/4233
@online{kexuefm-4233,
title={SVD分解(三):连Word2Vec都只不过是个SVD?},
author={苏剑林},
year={2017},
month={Feb},
url={\url{https://kexue.fm/archives/4233}},
}
March 11th, 2017
博主你好,我最近在学习word2vec在推荐系统中的应用,keras中的Embedding层算法是怎么样的?如何求出词向量的?您可以推荐一些资料给我吗?
请看本博客文章《词向量与Embedding究竟是怎么回事?》,本文有链接。
March 23rd, 2017
博主你好,有个疑问。
“Word2Vec的这种方案,可以看作是通过前后词来预测当前词,而自编码器或者SVD则是通过前后词来预测前后词。”
SVD只是一个矩阵分解过程,又何来预测一说?还有“通过前后词来预测前后词”这个说法令人费解。
请看本系列第一篇,那里说了SVD等价于三层自编码器,自编码器是输入等于输出这样训练的,就相当于前后词来预测前后词了。
June 26th, 2017
不知道lz看过之前的那篇Neural Word Embedding as Implicit Matrix Factorization文章没有,上面就是说的word2vec相当于一个PMI矩阵的分解
May 22nd, 2018
一口气看完了3篇SVD,写的很精彩,但还是有疑惑。
1. SVD中间的矩阵一般是对角矩阵,而且元素从大到小排列,这相当于是该特征的重要性;PCA也是利用此性质来进行降维。而在你的文章中SVD的中间的矩阵并没有这样的特性了。
2. 你说SVD矩阵分解后是对词和文章的聚类,对此我不太理解。之前有个算法叫Latent Semantic Indexing(LSI),也是对文章-词矩阵进行分解,我理解的是分解之后的对应词向量和文章向量。而聚类给人的感觉是用k-means聚合成几个团簇才叫聚类。能否解释一下你的想法?
谢谢~
1、SVD是一个理论比较完备的算法,可以得到你说的那种形式和排列,而我这里只是做一个基本的介绍。这个基本的介绍仅仅将SVD理解为“一个大矩阵分解为两个小矩阵相乘”,也就是相当于将中间的那个矩阵合并了。这个嘛,抓住主要核心即可,毕竟只是科普。
2、聚类也是一种直观的理解,而且当初我还没有理解得很深入,所以就用聚类来表达这个意思。其实这种说法在《数学之美》中也出现了,我也只是借鉴。可能概率化的pLSA模型更有聚类意义。
September 18th, 2018
word2vec 是 X = softmax(UV),U 是嵌入。
自编码器是 X = softmax(XUV),XU 是嵌入。
SVD 是 X = U∑V,U∑ 是嵌入。
的确形式不一样,但是都是等效的。。
word2vec 的独到之处是(1)少了一次矩阵相乘,(2)在后续工作中引入了层叠 softmax。可以看出它就是为实际生产做准备的,用尽一切办法降低计算量。
不知道你的X是什么。如果X是one hot输入,那么word2vec就是X = softmax(XUV),就是自编码器。
请参考:https://kexue.fm/archives/4122
当然好像也不能完全叫自编码器,不是输入一个词预测这个词,而是输入一个词,预测临近词,但做法基本一样了。
如果X是one hot输入,X 就是单位矩阵,可以省略。实际上代码里面没必要进行这一步。
1、X不是单位矩阵,甚至X不需要是方阵;
2、可以省略是另一回事,但讨论数学本质的时候,它就是存在的。在word2vec之类的模型中,从来就不是以词向量为输入,它们的输入就是one hot;从来就不存在所谓的“输入(指的是词向量)也是需要训练出来的”这回事。
April 15th, 2019
有个有趣的区别,在于被分解的矩阵是共现矩阵还是训练数据
共现矩阵的维度:词表数*词表数,实际上不区分因果关系,关系是对称的,矩阵也是实对称的,可以被开方,即只能得到一组词向量;distributed representation是用的共现矩阵么?是不是glove用的也是共现矩阵?
训练数据(输入输出都是词表数*数据条数的矩阵),就是CBOW或者skip gram的那种,会区分出输入和输出,实际上假设词表数为N,训练语料的窗口数为W,那把word2vec改写为矩阵形式就是LABEL(N*W)=EO(N*K)*EI(K*N)*INPUT(N*W),K是隐藏层节点数,EI是输入到隐藏层的全连接参数,EO是隐藏层到输出的全连接参数,都可以拿来当作词向量;所以建模时是区分输入和输出的,得到的两组词向量EI和EO也是不同的,据说一些大牛会把两组词向量加起来用(好像是某公开课视频里说的,比较方便,效果也ok);是不是因为没有对称性,word2vec在某些任务上表现会好一些?但具体怎么利用这个不对称性呢...
你说的聚类的思想确实很有启发性!
共现矩阵可以不对称呀。比如“词-文档”共现矩阵就可以不对称,“词-词”共现矩阵自然也可以保持不对称性。相反地,word2vec或者glove的共现也可以对称化。
August 1st, 2020
一个错别字: 对于稀疏矩阵,一个既能够将【降】维,又可以提高泛化能力的方案就是对矩阵SVD分解
谢谢啦,已经修正。
April 5th, 2023
[...]没找到特别好的材料,欢迎留言,参考 SVD分解(三):连Word2Vec都只不过是个SVD?中的说法:[...]
April 5th, 2023
[...]没找到特别好的材料,欢迎留言,参考 SVD分解(三):连Word2Vec都只不过是个SVD?中的说法:[...]
April 5th, 2023
[...]没找到特别好的材料,欢迎留言,参考 SVD分解(三):连Word2Vec都只不过是个SVD?中的说法:[...]