概述
Word2vec是一个基于神经网络的语言模型,设计目标是用来计算概率P(w|context),即词w在其上下文context下的条件概率。这里的context是一个句子中词w周围紧连着的n个词。有了P(w|context),就可以用类似n-gram模型的方法计算出一个句子的概率。语言模型在NLP领域有着广泛的应用,比如智能拼音输入法、语音识别和机器翻译等领域都需要使用语言模型。尽管如此,word2vec模型真正强大的地方在于其不仅仅是一个比n-gram等传统语言模型精准度更高的工具,而在于其训练过程所产生的附属品(词向量)有着更加广泛的应用。
那究竟什么是词向量呢?在NLP任务中,我们将自然语言交给机器学习算法来处理,但机器无法直接理解人类的语言。因此,首先要做的事情就是将语言数学化,词向量就是对自然语言数学化的一种很好的方式。
一种最简单的词向量是one-hot representation,就是用一个很长的向量来表示一个词,向量的长度是词典D的大小N,向量的分量只有一个为1,其他全为0,1的位置对应该词在词典中的索引。这种词向量表示有一些缺点:容易受维数灾难的困扰,尤其是应用于Deep Learning场景时;同时,也不能很好地刻画词与词之间的相似性。
另一种词向量是Distributed Representation,它最早是Hinton于1986年提出来的,可以克服one-hot representation的上述缺点。其基本想法是:通过训练将某种语言中的每个词映射成一个固定长度的短向量。所有这些向量构成一个词向量空间,每个向量是该空间中的一个点,在这个空间上引入“距离”,就可以根据词之间的距离来判断它们之间的(词法、语义上的)相似性了。Word2vec模型所产生的副产品就是这种Distributed Representation的词向量。
如何获取Distributed Representation的词向量呢?有很多不同的模型可以用来估计词向量,包括LSA矩阵分解模型、 PLSA 潜在语义分析概率模型、LDA 文档生成模型。此外,利用神经网络算法也是一种常用的方法,word2vec就是很好的一个例子。
词向量在信息检索中有着广泛的应用,比如可以基于词向量做相关词挖掘。注意,词向量只是针对“词”来提的,事实上,我们也可以针对更细粒度或更粗粒度来进行推广,如字向量,句子向量和文档向量,它们能够为字、句子、文档等单元提供更好的表示。大粒度的文本向量表示有着更加实际和广泛的应用。
对于神经网络,机器是很笨的,它理解不了我们人自己组建的更高层的自然语言,必须先把词处理成它可以理解的数学形式,就是将词映射成词向量。
对于图像来说,图像本身就是一种原生态的数据,人肉眼看到的就是这样一种数据,它没有经过任何的变幻和总结,所以人脑是怎么处理图片的,就可以用神经网络让机器去模仿人脑的处理方式,来完成这么一件事件。但文本不一样,文本是人有智慧后自己定义的一些符号组织起来的数据,不是原生态的数据,所以你必须把文本还原成计算机可以理解的形式,也就是这里要讲的词向量编码。
词编码需要保证词的相似性
向量空间分布的相似性
不同文明构建的语言之间具有相似性
我们希望从一个语系(英语)到另一个语系(西班牙语),映射到向量空间中后能够保持住他们的分布,比如说下图中左边的two,对应西班牙语向量空间中dos,他们的位置是差不多的。
向量空间子结构
一会会看到word2vec使得我们能够学习到这样一种关系,很多地方喜欢把他叫近义词,但其实他只是一种关联,所以我们希望我们能够获取词和词之间更底层的一些关联,比如说国王和女王之间的关系,与男人和女人之间的关系,其实非常非常相近的。所以我希望Vking减去Vqueen 与 Vman减去Vwomen,所能达到的结果应该是差不多的,国王和女王,与男人和女人,本质上是差不多的一件事。在进行此编码之后,能很好的保证原始文本的一些信息。人在这么多背景知识的情况下,理解到的这样一些信息,我们希望做完词编码后,依据能保持背景知识里头所理解的这些东西。
在计算机中表示一个词
传统方式是构建一个词典(Dict)
离散表示:One-hot表示(独热编码)
离散表示:Bag of Words(词袋)
离散表示:Bi-gram和N-gram
前面的词袋模型只关心词出没出现,不关心的出现顺序,比如:Mike love you; you love mike. 他们是两个不同的句子。
我们希望捕捉到这中顺序,那么通过2-gram将句子的顺序保留下来。
有些n-gram的term出现的频次是非常非常低的,但是你硬要开辟一些空间来存储它,它只要露了一次面,你就要给它开一个位置,所以这个向量会非常非常的长,非常非常的sparse(稀疏)。
语言模型
language model经常看那些词会接在那些词的后面。如何找出来错误的表达比如:you love I; you love me.
离散表示的问题
分布式表示(Distributed representation)
Distributed representation解析:你要让我自己去承担这个东西很难,所以我把它分发下去,我它丢到各个子节点或者classed上面,然后再把这些东西汇总回来。
用一个词附近的其他词来分布式的表示这个词。
共现矩阵(Cocurrence matrix)
窗口大小:如果要了解你的经济状况,应该了解你周围的几个朋友合适。
共现的频率:一次或多次。
靠它多近的这些人是都会被考虑到的,这就是局域窗的问题。
用当前词周围的词来定义当前词。
上面表示存在的问题
维度太高了,而且非常稀疏,那怎么在保留原的信息基础上把维度降下来呢?
SVD降维
从坐标中可以看出i和like与enjoy的距离是差不多的。
SVD降维的问题
神经网络最怕的东西就是维度太高,维度太高的话和后面的神经元连接时计算量会非常大,所以我希望这些稀疏的向量能够嵌入到一个稠密的向量,将向量做一个压缩,SVD似乎可以解决这样一个问题,但SVD和神经网络差异有点大,带来的问题是,你会看到很多地方word2vec并不是提前训练好,像FM做一个embedding,其中有这么一个环节 它们会把FM嵌入到deeplearning这样一个大框架当中,嵌入的条件一定是它本身的模式或者方式是类似的,但SVD它不是这样一套逻辑,所以它不合适。为了解决这个问题提出了NNLM,是word2vec的前身。
NNLM
NNLM(Neural Network Language model)是word2vec的前身,起初是为了解决语言模型这个问题,当你的语言模型上升到bi-gram,有很多稀疏性的问题,统计也不好统计,做平滑效果也不是很好,所以用统计的方式非常好时间,得把全部的语料都过一遍,最后还要一个很大的存储空间,因为需要把所有词的出现概率全都存下来。
目标函数就是一个最大似然,参数t(窗口)是可以滑动的,将窗口往前移。严格来说是个乘法的关系,但由于工程的关系,把转成求和的log形式。滑动窗口会遍历整个语料库去求和,所以他的计算量和语料库大小成正比
NNLM:结构
输入层的下一层叫projection layer(投影层),矩阵是C是你这10w个词的词向量,词的列向量一个一个组合起来的这么一个矩阵,假设现在你需要映射到300维的稠密向量,那么矩阵C就是300*10W的矩阵,这个C的权重是随机初始化的,因为我也不知道最终的权重是多少。
为什么叫投影层,因为one-hot编码的向量只有一个位置是1,其它位置都是0,与矩阵C做运算,就相当于取出其中C矩阵的对应一列。
拿到了w1,w2,w3这3个词各自的300位稠密向量后,它(投影层)会做一件事情,它把这3个词向量做一个拼接,得到一个900维的一个向量,假设投影层的下一个hidden层是500维,那么900会和这500做一个全连接。
最后一层是一个softmax的线性分类器,最后一层的维度和你词表的维度是一致的也是10W维,我最后要得到的结果是词表中10w个词向量的概率中最大的那个。
NNLM的计算复杂度
word2vec:CBOW(词袋模型)
word2vec中涉及到的两个模型,CBOW模型(Continuous Bag-Of-Words Model)和Skip-gram模型(Continuous Skip-gram Model)。CBOW是已知当前词的上下文,来预测当前词,而Skip-gram则相反,是在已知当前词的情况下,预测其上下文。
依据要预测的是这10w个词当中的哪一个词。
CBOW: Hierarchical Softmax
我 喜欢 观看 巴西 足球 世界杯,按之前的方式,我需要将转成6维长度的向量,如果觉得6维长度的向量平铺开来很麻烦,可以利用huffman tree来处理,在树中做决策只有往左走和往右走(0和1)。如何是上面的模型最后一层的权重会是300*10w这个多个θ(权重),因为你要保证做完乘法之后得1*10w的向量,这个计算量实在太大了。这里他做了一件事情,他把这些词都编码成一个Huffman tree之后,把θ放到了树上,在做决策的树节点上都留了一个权重,每到一个节点都是计算一次往哪边走,因为走了4词,最后要使得这四个决策乘积最大,每一次决策都看成是LR模型。
针对足球这个词,我们可以得到如下的结果:
CBOW:负例采样
那问题是为什么就可以选一部分负样本,他做法是: