在讲基于Negative Sampling的word2vec模型前,我们先看看Hierarchical Softmax的的缺点。的确,使用霍夫曼树来代替传统的神经网络,可以提高模型训练的效率。但是如果我们的训练样本里的中心词w是一个很生僻的词,那么就得在霍夫曼树中辛苦的向下走很久了。能不能不用搞这么复杂的一颗霍夫曼树,将模型变的更加简单呢?
Negative Sampling就是这么一种求解word2vec模型的方法,它摒弃了霍夫曼树,采用了Negative Sampling(负采样)的方法来求解。
负采样算法
在CBOW模型中,已知词w的上下文context(w)需要预测w。因此,对于给定的context(w),词w就是一个正样本,其它词就是负样本了。在Skip-gram中同样也存在正负样本问题。负样本那么多,该如何选取呢?这就是Negative Sampling(负采样)问题。也就是对于给定的词,如何生成其负样本子集NEG(w)?
采用的基本要求是:词典D中的词在语料C中出现的次数有高有低,对于那些高频词,被选为负样本的概率就应该比较大,反之,对于那些低频词,其被选中的概率就应该比较小。本质上就是一个带权采样问题。
word2vec采用的负采样方法如下:
(1)首先将一段长度为1的线段分成长度不相等的V份(V是词汇表的大小),每份对应词汇表的一个词。高频词对应长线段,低频词对应短线段。每个词的线段长度由下式决定:
len(w)=u∈D∑count(u)count(w)
在word2vec中,分子和分母都取了3/4次幂如下:
len(w)=u∈D∑count(u)3/4count(w)3/4
(2)在引入一个长度为1的线段进行等距划分成M份,其中M>>N,如下图所示:

如图所示,M份中的每一份都会落在某一个词对应的线段上。
(3)采样时,先从M个位置中采出neg个位置,再匹配到这neg个位置对应的词就是负词。如假设我们先采出m3,对应I2,I2对应的词就是负词。
注:在word2vec中,M取值默认为108。
CBOW模型
假设已经采样一个关于w的负样本子集NEG(w)=∅ ,且对于 w~∈D,定义:
Lw(w~)={1,w~=w0,w~=w
表示词w~的标签。即正样本的标签为1,负样本的标签为0。
对于一个给定的正样本(context(w),w),希望最大化:
g(w)=u∈w∪NEG(w)∏P(u∣context(w))
其中:
P(u∣context(w))={σ(xwTθu)Lw(u)=11−σ(xwTθu)Lw(u)=0
写成整体表达式:
P(u∣context(w))=[σ(xwTθu)]Lw(u)⋅[1−σ(xwTθu)]1−Lw(u)
这里的xw是各词向量之和。θu表示词对应的一个向量,是个待训练参数。
所以,最终g(w)的表达式如下:
g(w)=σ(xwTθw)u∈NEG(w)∏[1−σ(xwTθu)]
其中σ(xwTθw) 表示当上下文为contecxt(w) 时,预测中心词为w的概率;而σ(xwTθu)u∈NEG(w),预测中心词为u的概率。从形式上看,最大化g(w), 相当于:增大正样本的概率同时降低负样本的概率。所以,给定预料库C,函数:
G=w∈C∏g(w)
可以作为整体的优化目标。为了计算方便可以对G 取对数。所以:
L=logG=logw∈C∏g(w)=w∈C∑logg(w)=w∈C∑logu∈w∪NEG(w)∏{[σ(xwTθu)]Lw(u)⋅[1−σ(xwTθu)]1−Lw(u)}=w∈C∑u∈w∪NEG(w)∑{Lw(u)log[σ(xwTθu)]+(1−Lw(u))log[1−σ(xwTθu)]}=w∈C∑u∈w∪NEG(w)∑L(w,u)
接下来利用随机梯度上升对参数进行优化。
(1)更新θu:
因为:
∂θu∂L(w,u)=∂θu∂{Lw(u)log[σ(xwTθu)]+[1−Lw(u)]log[1−σ(xwTθu)]}=Lw(u)[1−σ(xwTθu)]xw−[1−Lw(u)]σ(xwTθu)xw=[Lw(u)−σ(xwTθu)]xw
所以 θu 更新公式为:
θu:=θu+η[Lw(u)−σ(xwTθu)]xw
其中η为学习率。
(2)更新xw
因为L(w,u) 关于变量xw和θw 是对称的。所以:
∂xw∂L(w,u)=[Lw(u)−σ(xwTθu)]θu
所以:
v(w~):=v(w~)+ηu∈w∪NEG(w)∑∂x(w)∂L(w,u),w~∈context(w)
以下是伪代码:

Skip-gram模型
Skip-gram模型与CBOW模型的负采样模型推到过程相似。具体过程可以参考word2vec中的数学原理详解
下面简单的给出随机梯度上升更新参数的伪代码:
