word2vec原理

首先声明,本文源自于刘建平老师的博客,原文写的非常好,在此结合鄙人的项目经验和大家分享。

word2vec原理(一) CBOW与Skip-Gram模型基础

一:词向量基础
word2vec是谷歌于2013年提出的一个nlp工具,他的特点就是将词向量化,这样,词与词之间就可以定量的去度量他们之间的相互关系,发掘词之间的联系,用词向量来表示词并不是word2vec的首创,很早之前就出现了,最早的词向量是很冗长的,它使用词向量的维度来表示词汇表的大小,对于词汇表中的某个具体词,他的对应位置为1,比如我们有下面的5个词组成的词汇表,词"Queen"的序号为2, 那么它的词向量就是(0,1,0,0,0)。同样的道理,词"Woman"的词向量就是(0,0,0,1,0)。这种方式我们一般叫做one-hot representation 。
在这里插入图片描述
但是这种编码方式存在一个巨大的问题,我们在实际的工业生产中,我们的词汇表一般非常大,达到百万级别,这样每个词都用百万维的向量来表示简直就是内存灾难,除了一个是1,其余全是0,这样表达效率严重不足。我们可以用distributed representation 可以解决one-hot-representation 问题,他的训练方式是将词映射到较短的词向量上从而用这些较短的词向量组成词向量空间,进而用普通的统计学方法来研究词与词之间的关系。
比如下图我们将词汇表里的词用"Royalty",“Masculinity”, “Femininity"和"Age"4个维度来表示,King这个词对应的词向量可能是(0.99,0.99,0.05,0.7)。当然在实际情况中,我们并不能对词向量的每个维度做一个很好的解释。
 在这里插入图片描述
有了用Distributed Representation表示的较短的词向量,我们就可以较容易的分析词之间的关系了,比如我们将词的维度降维到2维,有一个有趣的研究表明,用下图的词向量表示我们的词时,我们可以发现:
在这里插入图片描述
在这里插入图片描述
可见,只要得到了词汇表里所有词对应的词向量,我们就可以做很多事情了
二. CBOW与Skip-Gram用于神经网络语言模型
在word2vec之前,就已经有用神经网络DNN来训练词向量进而处理词与词之间的关系了 ,一般都是采用三层神经网络,即输入层,隐藏层,输出层(softmax层) 。一般我们用CBOW模型和skip-gram模型来定义模型的数据的输入和输出.
CBOW模型的输入就是与一个特定词上下文相关的词所对应的词向量,而输出就是这个特定词的词向量。比如下面这段话,我们的上下文大小取值为4,特定的这个词是"Learning”,也就是我们需要的输出词向量,上下文对应的词有8个,前后各4个,这8个词是我们模型的输入。由于CBOW使用的是词袋模型,因此这8个词都是平等的,也就是不考虑他们和我们关注的词之间的距离大小,只要在我们上下文之内即可。

在这里插入图片描述
在上面的例子中,我们的输入是八个词向量,输出是词汇表中所有词的softmax概率(训练的目标是期望训练样本也就是那八个词对应的softmax概率最大)。对应到神经网络中,网络输入为八个神经元,输出为词汇表大小个神经元,隐层神经元个数可以由我们自己指定。训练过程大致如下:通过DNN的反向传播找到模型参数和每个词的词向量,当有新的需求,例如求某几个词相关的特定词时候,我们可以通过DNN前向传播并通过softmax计算出词汇表中概率最大的词向量对应的神经元,也就是我们需要的特定词。
skip-gram模型与CBOW模型完全相反,还是对应上面的例子,输入为一个特定词的词向量,输出为与这个特定词上下文相关的概率最大的八个字的词向量。对应到神经网络中,输入为一个神经元,输出为八个神经元,隐层个数可由我们自己指定,通过dnn反向传播训练,求出词汇表中每个次对应的词向量以及模型参数。面对新需求时,通过前向传播计算出词汇表中与输入相关的概率最大的词向量,也就是我们需要的与特定次相关的词向量。

以上就是神经网络语言模型如何用cbow和skip-gram来训练得到词向量的大致过程,但是,我们的词汇表一般是百万级别,输出层在做softmax时,需要计算百万个词向量的概率,这个过程极为耗时。

三. word2vec基础之霍夫曼树
word2vec也使用了cbow和skip-gram模型来训练模型得到词向量,但是没有使用dnn模型,最早的优化结构是使用霍夫曼树来替代隐藏层和输出层的神经元,霍夫曼书的叶子结点就是模型的神经元输出,叶子节点的个数就是词汇表的大小,内部节点的个数就是隐藏层神经元的个数。
叶子节点:树的每一个叶子节点都代表一个单词,所以通常词频越高离根节点越近;

内部节点:每一个内部节点都代表一次逻辑回归的过程,可以规定沿着左子树走是负类(霍夫曼编码 1),沿着右子树走是正类(霍夫曼编码 0)。假设 xw 是当前内部节点的词向量,而 θ 则是需要学习的模型参数。对于 CBOW 模型,xw 初始化(根节点)为输入的词向量加和求平均后的向量,对于 Skip-gram 来说,就是 xw 的词向量。判别正类和负类的方法是使用 Sigmoid 函数:
在这里插入图片描述
最终输出哪个单词是由 logN 次逻辑回归过程决定的,回到基于 Hierarchical Softmax 的 word2vec 本身,我们的目标就是找到合适的所有节点的词向量和所有内部节点 θ, 使训练样本达到最大似然。如此经过一系列推导便可得到目标函数:
在这里插入图片描述

霍夫曼树的建立过程如下:
输入:权值为(w1,w2,w3…wn)的n 个节点
输出:对应的霍夫曼树。
1,将(w1,w2,w3…wn)看作是有n颗树的森林,每个树只有一个节点(也就是根节点)。
2,在森林中选择根节点权值最小的两棵树进行权值相加形成一颗新树,这两颗新树分别作为新树的左右子树。
3,将新树加入森林,并从森林中删除掉两颗子树。
4,重复步奏2和步奏3,直到森林中只剩一棵树为止
 下面我们用一个具体的例子来说明霍夫曼树建立的过程,我们有(a,b,c,d,e,f)共6个节点,节点的权值分布是(20,4,8,6,16,3)。

首先是最小的b和f合并,得到的新树根节点权重是7.此时森林里5棵树,根节点权重分别是20,8,6,16,7。此时根节点权重最小的6,7合并,得到新子树,依次类推,最终得到下面的霍夫曼树。
在这里插入图片描述
那么霍夫曼树有什么好处呢,一般在得到霍夫曼树后我们会对叶子结点进行霍夫曼编码,由于权重越高的节点越靠近根节点,而低权重的节点会相对远离根节点,所以我们的高权重节点的霍夫曼编码值会就较短,而低权重节点的霍夫曼编码值较长,这样就保证了树的带权路径最短,也符合我们的信息论,即我们希望我们常用的词拥有更短的编码。霍夫曼树约定一般左子树的编码为0,右子树的编码为1,所以我们看到c的编码为00。而在word2vec中相反,左子树为1,右子树为0,同时约定左子树的权重不得小于右子树。

word2vec原理(二) 基于Hierarchical Softmax的模型

一:
由于神经网络训练语言模型的缺点,word2vec并没有采用传统的DNN模型,而是进行了改进,一种是分层softmax(Hierarchical Softmax),另一种就是负采样(negative sampling).本章我们先讲word2vec基于分层sorfmax对语言训练模型的改进。
首先我们回顾传统dnn词向量语言模型,里面有三层,输入层,输出层(softmax),隐藏层。该模型最大的缺点就是隐层到输出的softmax层之间的计算会计算词汇表的维度,非常大,所以被摒弃。如下图:
在这里插入图片描述
word2vec在传统的dnn基础之上做了两点改进,
第一,在输入层到隐层,word2vec并没有像传统的dnn那样采用线性变换和激活函数,而是直接对所有的输入词向量进行了求和平均。比如输入的是三个4维词向量:(1,2,3,4),(9,6,11,8),(5,10,7,12),那么我们word2vec映射后的词向量就是(5,6,7,8)。由于这里是从多个词向量变成了一个词向量。
第二,在隐藏层到输出的softmax层,为了避免softmax计算词汇表所有词的词向量,word2vec采用了霍夫曼树来代替从隐藏层到输出层的映射,如何映射呢?

由于把我们之前所有的输出softmax概率计算替换成了一颗二叉霍夫曼树,那么我们的softmax概率计算只需要沿着树形结构进行就可以了,也就是从霍夫曼书的根节点走到叶子结点。和之前的神经网络语言模型相比,我们的霍夫曼树的所有内部节点就类似之前神经网络隐藏层的神经元,其中,根节点的词向量对应我们的投影后的词向量,而所有叶子节点就类似于之前神经网络softmax输出层的神经元,叶子节点的个数就是词汇表的大小。在霍夫曼树中,隐藏层到输出层的softmax映射不是一下子完成的,而是沿着霍夫曼树一步步完成的,因此这种softmax取名为"Hierarchical Softmax"。例如下图的W2:
在这里插入图片描述

在word2vec中我们采用二元逻辑回归(区别于二分类)的方法,即规定沿着左子树走就是负类(霍夫曼树编码为1),沿着右子树走即为正类(霍夫曼书编码为0)。同时规定左子树的权重不得低于右子树。判别正类和负类的方法是使用sigmoid函数,即:
在这里插入图片描述
 其中xw是当前内部节点的词向量,而θ则是我们需要从训练样本求出的逻辑回归的模型参数。
使用霍夫曼树的优点有两个:
1,由于是二叉树,之前的计算量为v,现在变成了log2v,
2,由于使用霍夫曼树使得高频词更靠近根节点,这样高频词就可以更快的找到,符合我们的贪心优化算法。
 容易理解,被划分为左子树而成为负类的概率为P(−)=1−P(+)。在某一个内部节点,要判断是沿左子树还是右子树走的标准就是看P(−),P(+)谁的概率值大。而控制P(−),P(+)谁的概率值大的因素一个是当前节点的词向量,另一个是当前节点的模型参数θ。

对于上图中的w2,如果它是一个训练样本的输出,那么我们期望对于里面的隐藏节点n(w2,1)的P(−)概率大,n(w2,2)的P(−)概率大,n(w2,3)的P(+)概率大。
回到基于分层softmax本身,我们的目标是找到适合的,所有节点的词向量和内部节点参数θ,使得训练样本达到最大似然。
二: 基于Hierarchical Softmax的模型梯度计算
我们使用最大似然法来寻找所有节点的词向量和所有内部节点的 θ ,我们的期望是最大化所有训练样本的似然函数乘积。
为了方便计算,我们定义输入词为w,定义经过输入层到隐层求和平均后的霍夫曼树根节点为Xw,定义从根节点到叶子结点的节点总数为Lw,w从根节点开始经过第i个节点表示piw,对应的霍夫曼编码为diw,而该节点对应的模型参数为 θ iw,其中i最大为Lw-1,因为训练只针对内部节点,不包括根节点。
定义w经过霍夫曼树第i个节点的逻辑回归概率为如下:
在这里插入图片描述
对一个样本去最大似然:
在这里插入图片描述
在word2vec中我们使用的是随机梯度上升法,并没有将所有样本的似然函数乘起来得到真正的训练集最大似然。每次仅仅用一个样本来更新梯度,从而降低梯度计算,这样我们可以得到对数似然函数L如下
在这里插入图片描述

要得到模型中w词向量和内部节点的模型参数θ, 我们使用梯度上升法即可。首先我们求模型参数θ的梯度
在这里插入图片描述
 同样的方法,可以求出xw的梯度表达式如下:
 在这里插入图片描述

三:基于Hierarchical Softmax的CBOW模型
首先我们要定义词向量的维度大小M,以及CBOW的上下文大小2c,这样我们对于训练样本中的每一个词,其前面的c个词和后面的c个词作为了CBOW模型的输入,该词本身作为样本的输出,期望softmax概率最大。
在做CBOW模型前,我们需要先将词汇表建立成一颗霍夫曼树。
对于从输入层到隐藏层(投影层),这一步比较简单,就是对w周围的2c个词向量求和取平均即可,即:
在这里插入图片描述
第二步,通过梯度上升法来更新我们的θwj−1和xw,注意这里的xw是由2c个词向量相加而成,我们做梯度更新完毕后会用梯度项直接更新原始的各个xi(i=1,2,2c),即:
在这里插入图片描述
其中η为梯度上升法的步长。

这里总结下基于Hierarchical Softmax的CBOW模型算法流程,梯度迭代使用了随机梯度上升法:
输入:基于cbow的预料训练样本,词向量的维度M,cbow的上下文2c,步长为η
输出:霍夫曼树的内部节点参数θ ,所有的词向量w
1,基于语料库建立霍夫曼树
2,随机初始化所有的模型参数θ ,所有的词向量w
3,机型梯度上升迭代,对于训练集中的每个样本做如下处理
在这里插入图片描述

四:基于Hierarchical Softmax的Skip-Gram模型
我们对于训练样本中的每一个词,该词本身作为样本的输入, 其前面的c个词和后面的c个词作为了Skip-Gram模型的输出,,期望这些词的softmax概率比其他的词大。

Skip-Gram模型和CBOW模型其实是反过来的,在上一篇已经讲过。

在做CBOW模型前,我们需要先将词汇表建立成一颗霍夫曼树。

对于从输入层到隐藏层(投影层),这一步比CBOW简单,由于只有一个词,所以,即xw就是词w对应的词向量。
 第二步,通过梯度上升法来更新我们的θwj−1和xw,注意这里的xw周围有2c个词向量,此时如果我们期望P(xi|xw),i=1,2…2c最大。此时我们注意到由于上下文是相互的,在期望P(xi|xw),i=1,2…2c最大化的同时,反过来我们也期望P(xw|xi),i=1,2…2c最大。那么是使用P(xi|xw)好还是P(xw|xi)好呢,word2vec使用了后者,这样做的好处就是在一个迭代窗口内,我们不是只更新xw一个词,而是xi,i=1,2…2c共2c个词。这样整体的迭代会更加的均衡。因为这个原因,Skip-Gram模型并没有和CBOW模型一样对输入进行迭代更新,而是对2c个输出进行迭代更新。
 输入:基于Skip-Gram的语料训练样本,词向量的维度大小M,Skip-Gram的上下文大小2c,步长η
 输出:霍夫曼树的内部节点模型参数θ,所有的词向量w

  1. 基于语料训练样本建立霍夫曼树。

2. 随机初始化所有的模型参数θ,所有的词向量w,

3. 进行梯度上升迭代过程,对于训练集中的每一个样本(w,context(w))做如下处理:
 在这里插入图片描述

word2vec原理(三) 基于Negative Sampling的模型

1. Hierarchical Softmax的缺点与改进
虽然分层softmax采用霍夫曼书代替了神经网络隐藏层到softmax层的映射从而提高了模型的训练效率,但存在一个问题,就是当我们的训练样本中目标词是一个生僻词的时候,霍夫曼书就会往下走很久,整个树就会变得非常复杂。 Negative Sampling就是这么一种求解word2vec模型的方法,它摒弃了霍夫曼树,采用了Negative Sampling(负采样)的方法来求解,下面我们就来看看Negative Sampling的求解思路。
2基于Negative Sampling的模型概述
比如我们有一个训练样本,中心词为w,上下词共有2c个词,记为context(w),由于这个中心词w,的确和context(w)相关存在,因此它是一个真实的正例。通过Negative Sampling采样,我们得到neg个和w不同的中心词wi,i=1,2,…neg,这样context(w)和wi就组成了neg个并不真实存在的负例。利用这一个正例和neg个负例,我们进行二元逻辑回归,得到负采样对应每个词wi对应的模型参数θi,和每个词的词向量。 从上面的描述可以看出,Negative Sampling由于没有采用霍夫曼树,每次只是通过采样neg个不同的中心词做负例,就可以训练模型,因此整个过程要比Hierarchical Softmax简单。
3:Negative Sampling负采样方法
负例采样不再使用复杂的霍夫曼树,而是利用相对简单的随机负采样来大幅提高性能,并且在经过论证后发现,负例采样不但可以提高训练速度,还可以改善所得词向量的质量,因此,负例采样比层次 Softmax 使用率更高。

负例采样的思想其实和层次 Softmax 很类似,也是将 Softmax 多分类问题转化成多次二分类问题,使用二元逻辑回归可以让一个训练样本每次仅仅更新一小部分的权重,不同于原本每个训练样本更新所有的权重,这样大大减少了梯度下降过程中的计算量。
当然,负例采样的具体过程和层次 Softmax 有很大区别。 它的技术点会涉及两个关键的地方,一个是如何进行负例采样,另外一个是如何进行二元逻辑回归
Word2Vec 论文中给出的采样方式其实并不复杂,首先采样的数量根据数据集的大小而定,一个经验是对于小数据集,选择 5~20 个负例,而对于较大的数据集,则只需要 2~5 个负例就可以。另外,采样会遵循一定的分布,这里用的是一元模型分布 (unigram distribution),它的特点是词频更高的词更有可能被选为负例,是一个加权采样。假设我们要将整个语料库的单词作为单词表,并且从单词表中进行随机负例采样,则选取某个词的概率等于该词出现在语料库次数(词频)除以语料库出现的单词总数,用公式表示为:
 在这里插入图片描述

其中,f(⋅) 可以理解为计数,即得到词频。
论文中指出,作者在这个公式上尝试了很多变化,最后表现比较好的是将单词词频提高到 3/4 次幂。如下:
在这里插入图片描述
这个改变后的公式会产生一个效果,就是稍微增加低频词的采样概率,降低高频词的采样概率。
 在采样前,我们将这段长度为1的线段划分成M等份,这里M>>V,这样可以保证每个词对应的线段都会划分成对应的小块。而M份中的每一份都会落在某一个词对应的线段上。在采样的时候,我们只需要从M个位置中采样出neg个位置就行,此时采样到的每一个位置对应到的线段所属的词就是我们的负例词。
 在这里插入图片描述
然后再来看二元逻辑回归的目标函数,论文中给出了 Skip-gram 模型负采样的优化目标函数为:
在这里插入图片描述
其中 Pn(w) 就是采样用的概率分布。
原论文中并没有给出负例采样的推导过程,2014 年,Yoav Goldberg 在论文《word2vec Explained: Deriving Mikolov et al.’s Negative-Sampling Word-Embedding Method》里对上述目标函数给出了推导。
从本文前面的内容我们已知 Skip-gram 的最初的目标函数:
在这里插入图片描述
如果对上述目标函数进行优化,第二项需要对词典里的所有词进行优化,所以计算量比较大。如果换个角度考虑,如果我们将合理的上下文样本对看成是 1,不合理的上下文样本对看成是 0,那么问题转换为二分类问题,那么我们目标就是最大化下面的目标函数:
在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值