Word2Vec
2021-10-16

 

 

背景知识

Log-linear Model

定义(Log Linear Models):将语言模型的建立看成是一个多分类问题,相当于线性分类器加上softmax操作。

(1)Y=softmax(wx+b)

 

符号定义

  1. 单词:w
  2. 词典:D={w1,w2,,wN},其中,N为单词个数。由单词组成的集合。
  3. 语料库:C,由单词组成的文本序列。
  4. 上下文:Context(wt)是单词wt在语料库中前c个单词和后c个单词组成的文本序列,wt称为中心词,c为窗口长度
  5. 词向量:v(w)表示单词w对应的词向量

 

两种模型

Word2Vec简介

架构

语言模型基本思想:句子中下一个词的出现和前面的词是有关系的,所以可以使用前面的词预测下一个词

Word2Vec基本思想:句子中相近的词之间是有联系的,比如今天后面经常出现上午、下午。所以Word2Vec的基本思想就是用词来预测词,CBOW使用周围词预测中心词,Skip-gram使用中心词预测周围词。

单个词到单个词

为了便于理解CBOW和Skip-gram模型,先介绍一个词到一个词的简单模型。

假设输入为:我喜欢观看巴西足球世界杯。经过分词,得到词表:['我','喜欢','观看','巴西','足球','世界杯']。为了构建一个词到一个词的模型,将单词两两分组,得到数据集:[['我','喜欢'],['喜欢','观看'],['观看','巴西'],['巴西','足球'],['足球','世界杯']]。使用one-hot对单词进行表示如下图所示:

巴西onehot

接下来,输入数据:['我', '喜欢'],在输出中,期望'喜欢'的概率最大。

巴西世界杯

扩展到一般的网络结构:

标准网络结构

定义如下符号:

  1. V:词表大小(或语料库中不同单词的数目)
  2. N:词向量维度
  3. XN×1:输入单词,使用one-hot编码表示
  4. w:原始单词
  5. Context(wi)c:单词wi的第c个周围词,其中,1cC
  6. WV×N:输入层与隐藏层之间的权重
  7. WN×V:隐藏层与输出层之间的权重
  8. uV×1:每个单词的预测值,通过softmax计算可得到概率
  9. yV×1:每个单词的概率

 

前向计算:

  1. hN×1=WTX

    hi=k=1Vwkixk

  2. uV×1=WTh

    uj=i=1Nwijhi,注意,hi出现在每一个uj当中,如果对hi求导,需要遍历每一个uj

  3. y=softmax(u)

 

损失函数:

  1. 给定中心词wi,预测词wj的概率

    (2)p(wjwi)=yj=eujk=1Veuk
  2. 损失函数

    假设a是正确的单词对应的索引,我们期望p(wawi)最大,等价地,可以导出如下损失函数:

    (3)E=log{euak=1Veuk}=ua+log(k=1Veuk)

     

    反向传播:

(4)(1)WEuj=t(j,a)+yj:=ejEwij=Eujujwij=ejhiEW=i=1Nj=1Vhiej=heT(2)WEhi=j=1VEujujhi=j=1Vejwij:=EHiEwki=Ehihiwki=(j=1Vejwij)xk=EHixkEW=k=1Vi=1NEHixk=XEHTV×NX1010EHTt(j,a)={1,j=a0,ja

参数更新:

  1. W更新:需要更新整个矩阵

  2. W更新:只需要更新a对应的行。梯度更新如下图所示:(注:wt应为XW2应为W

    W更新示意

 

CBOW

CBOW1

首先,需要定义window,即选取多少个周围词,上图中window=2。通过周围词预测中心词,该问题为多分类问题。

词向量:v

输入:周围词,wi1,wi2,wi+1,wi+2,将其词向量相加得到周围词词向量vo

标签:中心词,wiM为语料库C中的中心词个数

使用向量内积表示词向量的相似度,那么,中心词的预测概率为:

(5)p(wiwi2,wi1,wi+1,wi+2)=exp(voTvwi)j=1Nexp(voTvj)vwivj

损失函数(使中心词的概率最大):

(6)J(θ)=1Mi=1Mlogp(wiwo)=1Mi=1Mexp(voTvwi)j=1Mexp(voTvj)Mwiwowivovj

 

Skip-gram

skip-gram1

首先,需要定义window,即选取多少个周围词,上图中window=2。通过中心词预测周围词,该问题为多分类问题。

词向量:v

输入:中心词,wi

标签:周围词,wi1,wi2,wi+1,wi+2M为周围词个数

使用向量内积表示词向量的相似度,那么,周围词的预测概率为:

(7)p(wi1wi)=exp(vwi1Tvwi)j=1Mexp(vjTvwi)vj

损失函数(使周围词的概率最大):

(8)J(θ)=1Mm=1Mcjc,j0logp(wm+jwm)c

 

计算优化

为了解决上述模型中softmax计算量太大的问题,使用以下两种方法进行优化。

Hierarchical softmax

核心思想:将多分类问题转化为多个二分类问题。

方法:将词表中的单词,按照频率构建一颗哈夫曼树,这样,对每一个单词,便有了唯一正确的一个搜索路径。如果将搜索路径视为输入X,将单词视为真实标签y,那么,从根结点到目标单词(叶子结点),便是若干个二分类过程。至此,完成了问题的转化。

CBOW

HS1

针对上述哈夫曼树,各层解释如下:

  1. 输入层

    v(Context(w)1)v(Context(w)2)v(Context(w)2c)Rm,其中,v()为单词的向量化表示

  2. 投影层

    (9)xw=i=12cv(Context(w)i)Rm
  3. 输出层

    给定w的周围词,单词w出现的概率,即p(wContext(w))

为方便计算损失函数,定义如下变量:

  1. 路径pw=(p1w,p2w,,plww)

    从根结点出发,到达w对应的叶子结点的路径。其中,lw为路径长度,即路径中结点数目;piw为路径中的结点,p1w为根结点,plwww对应的叶子结点。

  2. 编码dw=(d1w,d2w,,dlww)

    w的Huffman编码。其中,diw{0,1}为路径pw中第i个结点对应的编码(根结点不对应编码)。

  3. 权值θw=(θ1w,θ2w,,θlw1w)

    路径pw中非叶子结点对应的参数向量。其中,θiRm为路径pw中第i个非叶子结点对应的参数向量。

 

那么,在已知周围词Context(w)的条件下,中心词w的概率为:

(10)p(wContext(w))=j=2lwp(djwxw,θj1w)

其中,

(11)p(djwxw,θj1w)={σ(xwTθj1w),djw=01σ(xwTθj1w),djw=1

该概率也可以写成如下形式:

(12)p(djwxw,θj1w)=[σ(xwTθj1w)]1djw[1σ(xwTθj1w)]djw

那么,似然函数为:

(13)=wCp(w Context (w))=wCj=2lwp(djwxw,θj1w)

对数似然函数为:

(14)L=logwCj=2lwp(djwxw,θj1w)=wClogj=2lwp(djwxw,θj1w)=wCj=2lw{(1djw)log[σ(xwTθj1w)]+djwlog[1σ(xwTθj1w)]}

对数似然函数L关于θj1w求偏导为:

(15)Lθj1w=θj1w{wCj=2lw{(1djw)log[σ(xwTθj1w)]+djwlog[1σ(xwTθj1w)]}}=(1djw)[1σ(xwTθj1w)]xwdjwσ(xwTθj1w)xw=[1djwσ(xwTθj1w)]xw

所以,θj1w的更新公式为:

(16)θj1w=θj1w+η[1djwσ(xwθj1w)]xwη

对数似然函数L关于xw求偏导为:

(17)Lxw=j=2lw[1djwσ(xwθj1w)]θj1w

v(w~)的更新公式为:

(18)v(w~)=v(w~)+ηLxww~Context(w)

Skip-gram

HS2

 

针对上述哈夫曼树,各层解释如下:

  1. 输入层

    当前样本的中心词w对应的词向量v(w)Rm

  2. 映射层

    恒等映射,多余,为了和CBOW模型的网络结构进行对比。

  3. 输出层

 

那么,给定中心词w的条件下,其周围词Context(w)的条件概率为:

(19)p(Context(w)w)=uContext(w)p(uw)

其中,

(20)p(uw)=j=2lup(djuv(w),θj1u)

并且:

(21)p(djuv(w),θj1u)=[σ(v(w)Tθj1u)]1dju[1σ(v(w)Tθj1u)]dju

所以,似然函数为:

(22)=wCp(Context(w)w)=wCuContext(w)j=2lup(djuv(w),θj1u)

对数似然函数为:

(23)L=wCloguContext(w)j=2lu{[σ(v(w)Tθj1u)]1dju[1σ(v(w)Tθj1u)]dju}=wCuContext(w)j=2lu{(1dju)log[σ(v(w)Tθj1u)]+djulog[1σ(v(w)Tθj1u)]}

对数似然函数L关于θj1u的偏导为:

(24)Lθj1u=θj1u{wCuContext(w)j=2lu{(1dju)log[σ(v(w)Tθj1u)]+djulog[1σ(v(w)Tθj1u)]}}=wC{(1dju)[1σ(v(w)Tθj1u)]v(w)djuσ(v(w)Tθj1u)v(w)}=wC[1djuσ(v(w)Tθj1u)]v(w)

θj1u的更新公式为:

(25)θj1u=θj1u+ηwC[1djuσ(v(w)Tθj1u)]v(w)η

对数似然函数L关于v(w)的偏导为:

(26)Lv(w)=uContext(w)j=2lu[1djuσ(v(w)Tθj1u)]θj1u

v(w)的更新为:

(27)v(w)=v(w)+ηuContext(w)j=2lu[1djuσ(v(w)Tθj1u)]θj1u

Negative Sampling

CBOW

Context(w)的负样本子集(非w的周围词)为:

NEG(w)

对于w~D,定义Lw(w~)表示词w~的标签,即w~是否是中心词w的周围词,正样本标签为1,负样本标签为0:

(28)Lw(w~)={1,w~=w0,w~w

在给定周围词Context(w)的条件下,中心词与负样本数据集,即{w}NEG(w),其似然函数为:

(29)g(w)=u{w}NEG(w)p(uContext(w))=σ(xwTθw)uNEG(w)[1σ(xwTθw)]

其中,

(30)p(uContext(w))={σ(xwTθu),Lw(u)=11σ(xwTθu),Lw(u)=0xwContext(w)θuRm

上式也可以写为:

(31)p(uContext(w))=[σ(xwTθu)]Lw(u)[1σ(xwTθu)]1Lw(u)

关于词表C的对数似然函数为:

(32)L=logwCg(w)=wClogg(w)=wClogu{w}NEG(w){[σ(xwTθu)]Lw(u)[1σ(xwTθu)]1Lw(u)}=wCu{w}NEG(w){Lw(u)log[σ(xwTθu)]+[1Lw(u)]log[1σ(xwTθu)]}

对数似然函数L关于θu的偏导为:

(33)Lθu=θu{wCu{w}NEG(w){Lw(u)log[σ(xwTθu)]+[1Lw(u)]log[1σ(xwTθu)]}}=Lw(u)[1σ(xwTθu)]xw[1Lw(u)]σ(xwTθu)xw=[Lw(u)σ(xwTθu)]xw

参数θu的更新公式为:

(34)θu=θu+η[Lw(u)σ(xwTθu)]xw

对数似然函数L关于xw的偏导为:

(35)Lxw=u{w}NEG(w)[Lw(u)σ(xwTθu)]θu

参数v(w~)的更新公式为:

(36)v(w~)=v(w~)+ηLxww~Context(w)

Skip-gram

给定中心词w,对应多个周围词w~NEGw~(w)表示相对于(w,w~)的负样本。

给定周围词w~{w}NEGw~(w)的似然函数为:

(37)g(w)=w~ Context (w)u{w}NEGw~(w)p(uw~)NEGw~(w)w~

其中,

(38)p(uw~)={σ(v(w~)Tθu),Lw(u)=11σ(v(w~)Tθu),Lw(u)=0

上式又可以写为:

(39)p(uw~)=[σ(v(w~)Tθu)]Lw(u)[1σ(v(w~)Tθu)]1Lw(u)

关于词表C的对数似然函数为:

(40)L=logwCg(w)=wClogg(w)=wClogw~ Context(w) u{w}NEGw~(w){[σ(v(w~)Tθu)]Lw(u)[1σ(v(w~)Tθu)]1Lw(u)}=wCw~Context(w)u{w}NEGw~(w){Lw(u)log[σ(v(w~)Tθu)]+[1Lw(u)]log[1σ(v(w~)Tθu)]}

对数似然函数L关于θu的偏导为:

(41)Lθu=θu{wCw~Context(w)u{w}NEGw~(w){Lw(u)log[σ(v(w~)Tθu)]+[1Lw(u)]log[1σ(v(w~)Tθu)]}}=Lw(u)[1σ(v(w~)Tθu)]v(w~)[1Lw(u)]σ(v(w~)Tθu)v(w~)=[Lw(u)σ(v(w~)Tθu)]v(w~)

参数θu的更新公式为:

(42)θu=θu+η[Lw(u)σ(v(w~)Tθu)]v(w~)

对数似然函数L关于v(w~)的偏导为:

(43)Lv(w~)=u{w}NEGw~(w)[Lw(u)σ(v(w~)Tθu)]θu

参数v(w~)的更新公式为:

(44)v(w~)=v(w~)+ηLv(w~)

采样

负采样

负采样

非等距剖分:

设词典D中单词wi对应的线段为l(wi),其长度为:

(45)len(wi)=counter(wi)uDcounter(u)counter()C

可将线段l(w1),,l(wN)拼接为长度为1的单位线段。记:

(46)l0=0lk=j=1klen(wj),k=1,2,,N

则以lj,j{0,1,,N}为剖分点可得到区间[0,1]上的一个非等距剖分:

(47)Ii=(li1,li],i=1,2,,N

等距剖分:

在区间[0,1]上以剖分点mj,j{0,1,,M}做等距剖分,其中MN

等距与非等距映射:

将等距剖分的内部点{mj}j=1M1投影到非等距剖分,则可建立{mj}j=1M1与区间{Ij}j=1N的映射,进一步建立与词{wj}j=1N之间的映射。

(48)Table(i)=wk, where miIk,i=1,2,,M1

重采样

重采样的目的:提高低频次出现的频率,降低高频词出现的概率。

训练集中的词wi会以P(wi)的概率被删除,概率P(wi)计算公式为:

(49)P(wi)=1tf(wi)f(wi)wit105

复杂度分析

使用模型参数量表征模型复杂度。

定义符号:

  1. O:训练复杂度

  2. E:迭代次数

  3. T:数据集大小

  4. Q:参与本次计算的参数的数目

    那么:O=E×T×Q

NNLM(前馈神经网络)

NNLM_model

模型:使用前N个词预测下一个词

(50)y=Utanh(WX+d)p(xixi1,,xiN)=eyij=1VeyjX=[x(1),x(2),,x(N)],y=[y1,y2,,yV]

符号定义:

  1. N:上文词(训练数据)个数
  2. D:词向量维度
  3. V:词表的大小
  4. H:隐藏层大小
  5. xN×D
  6. WN×D×H
  7. UV×H

 

参数个数:

  1. 输入层:N×D

  2. 隐藏层:N×D×H

  3. 输出层:V×H。如果使用HS对输出进行优化,则需要进行log2V次二分类,参数θ的长度为H,故参数量为Hlog2V

     

    总参数量:Q=N×D+N×D×H+V×H

 

RNNLM(循环神经网络语言模型)

RNNLM_model

(51)s(t)=Uw(t)+Ws(t1)+dy(t)=Vs(t)w(t)ts(t1)

符号定义:

  1. w(t):维度为D×1
  2. UH×D
  3. WH×H
  4. s(t):维度为H×1
  5. VV×H
  6. y(t):维度为V×1

 

复杂度计算:

  1. 输入层:1×D

  2. 隐藏层:D×H+H×H

  3. 输出层:H×V

  4. 总复杂度:假设DH

    1×D+D×H+H×H+H×V1×H+H×H×2+V×HH×H+V×H

     

Skip-gram

符号定义:

  1. C:中心词个数
  2. D:词向量维度
  3. V:单词个数

 

原始复杂度:

  1. 输入:1×D
  2. 输出:通过矩阵WD×V进行计算得到u,再通过softmax操作得到最终结果y。因此,本次参与计算的参数个数为D×V
  3. 总复杂度:C(1×D+D×V)

 

Hierarchical softmax复杂度:

  1. log2V次二分类,参数θ的长度为D,故复杂度为C(1×D+D×log2V)

 

Negative Sampling复杂度:

  1. 正样本个数为1,负样本个数为K,词向量维度为D,故总的复杂度为C(1×D+D×(K+1))

 

CBOW

周围词个数为N,每个词的向量维度为D,所以输入的参数量为N×D。经过sum操作,得到汇总的词向量,维度为1×D,再经过权重矩阵WD×V计算,得到最终预测结果。所以输出层的参数量为N×D

原始复杂度:N×D+D×V

HS复杂度:N×D+D×log2V

NEG复杂度:N×D+D×(K+1)

 

复杂度总结

如下对各模型复杂度进行总结:

  1. NNLM:Q=N×D+N×D×H+H×log2V
  2. RNNLM:Q=H×H+H×log2V
  3. Skip_gram+HS:Q=C(1×D+D×log2V)
  4. Skip_gram+NEG:Q=C(1×D+D×(K+1))
  5. CBOW+HS:Q=N×D+D×log2V
  6. CBOW+NEG:Q=N×D+D×(K+1)

 

问题

  1. 为什么可以使用向量内积度量相似度?

    ab=|a||b|cosθ,其中,θ为两向量的夹角。如果向量已被单位化,那么向量内积等于cosθ,此时,两向量越接近,夹角越小,内积越大。

  2. 对比Skip-gram和CBOW。训练速度上CBOW更快;对低频词,Skip-gram效果更好,因为Skip-gram是用当前词预测上下文,当前词是低频还是高频没有区别,但是CBOW相当于是完形填空,更倾向于选择常见的词而不是低频词。总体上讲,Skip-gram模型的效果更好。

 

参考链接

  1. https://spaces.ac.cn/archives/4122

  2. 源码 GitHub - tmikolov/word2vec: Automatically exported from code.google.com/p/word2vec

  3. Embedding从入门到专家必读的十篇论文 - 知乎 (zhihu.com)

  4. 词向量模型word2vector详解 - 空空如也_stephen - 博客园 (cnblogs.com)

  5. word2vec公式推导及python简单实现 - Kayden_Cheung - 博客园 (cnblogs.com)

  6. Python implementation of Word2Vec | Marginalia (claudiobellei.com)

  7. The backpropagation algorithm for Word2Vec | Marginalia (claudiobellei.com)

  8. word2vec公式推导及python简单实现 - Kayden_Cheung - 博客园 (cnblogs.com)

  9. 深度之眼:NLP-baseline 体验课 (deepshare.net)

  10. 七月在线:补充视频:陈博士带你从头到尾通透word2vec (julyedu.com)

  11. 【机器学习】白板推导系列(三十六) ~ 词向量(Word Vector)哔哩哔哩bilibili

  12. 【双语字幕】斯坦福CS224n《深度学习自然语言处理》课程(2019) by Chris Manning哔哩哔哩bilibili