这篇文章要带来一个“重磅”消息,如标题所示,居然连大名鼎鼎的深度学习词向量工具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://www.kexue.fm/archives/4233

更详细的转载事宜请参考:《科学空间FAQ》

如果您还有什么疑惑或建议,欢迎在下方评论区继续讨论。

如果您觉得本文还不错,欢迎分享/打赏本文。打赏并非要从中获得收益,而是希望知道科学空间获得了多少读者的真心关注。当然,如果你无视它,也不会影响你的阅读。再次表示欢迎和感谢!

如果您需要引用本文,请参考:

苏剑林. (Feb. 23, 2017). 《SVD分解(三):连Word2Vec都只不过是个SVD? 》[Blog post]. Retrieved from https://www.kexue.fm/archives/4233

@online{kexuefm-4233,
        title={SVD分解(三):连Word2Vec都只不过是个SVD?},
        author={苏剑林},
        year={2017},
        month={Feb},
        url={\url{https://www.kexue.fm/archives/4233}},
}