美文网首页
Word2Vec详解

Word2Vec详解

作者: 小幸运Q | 来源:发表于2020-08-06 10:35 被阅读0次

    https://www.jianshu.com/p/8ac51e0b70cf
    http://super1peng.xyz/2018/04/22/Hierarchical-Softmax-CBOW/
    https://shomy.top/2017/07/28/word2vec-all/
    https://zhuanlan.zhihu.com/p/56139075
    https://zhuanlan.zhihu.com/p/53194407


    "就"的word2vec

    假定每个词w_t都跟其相邻的词w_{t+j}的关系最密切,换句话说每个词都是由相邻的词决定的p(w_{中心词}|w_{周边})(CBOW模型的动机),或者每个词都决定了相邻的词p(w_{周边}|w_{中心词})(Skip-gram模型的动机)

    那么为了产生模型的正样本,我们选一个长度为2c+1(目标词前后各选c个词)的滑动窗口,从句子左边滑倒右边,每滑一次,窗口中的词就形成了我们的一个正样本。


    • 以下以skip-gram为例

    目标函数

    基于极大似然概率,我们希望所有样本的条件概率p(w_{t+j}|w_t)之积最大,使用log probability(变和为积),可得目标函数:

    \frac{1}{T}\sum_{t=1}^T\sum_{-c \leq j \leq c,j \ne 0}log (p(w_{t+j}|w_t))

    怎么定义p(w_{t+j}|w_t)

    p(w_o|w_I)=\frac{p(w_ow_I)}{p(w_I)}=\frac{e^{v_{wo}'^Tv_{wI}}}{\sum_{w=1}^W e^{v_w'^T v_{wI}}}

    p(w_I)=\sum_{i=1}^{W(词汇表大小)}p(w_i)p(w_I),w_I是对预测的估计

    分子是e的周边某个词向量*当前中心词向量,分母是所有词向量*当前中心词向量

    V_{wo}是词w的输出output向量表示(如下图W_{V*N}),V_{wI}是输入input向量表示(如下图W'_{N*V}),wI代表输入的中心位置词向量,wo代表输入中心位置周边词向量,V_w表示词w的词向量vector。

    输入向量表示即input layer到hidden layer的权重矩阵W_{V*N}(即词向量),输出向量表达就是hidden layer到output layer的权重矩阵W'_{N*V}

    采样的输出格式:

    image.png

    One-Word Model

    V词汇表长度,N隐向量长度,Input只有一个词输入

    输入x,隐向量h=xW_{V*N}=v_{WI}^T,输出u=W'^Th

    思路:作为一个多分类问题,最简单最直接的方法当然是直接用softmax函数输出概率,但是我们又希望用向量v_w表示每个词w,用词之间的距离v_iv_j表示语义的接近程度。

    • word2vec的隐层并没有激活函数,softmax在输出层,这跟神经网络不一样。

    流程:

    输入词向量x,经过输入层到隐层的矩阵W_{V*N}得到词向量h,再乘以隐藏层到输出层的矩阵W_{N*V}得到向量u,将向量u与周边词的预估\hat{u}计算p,求p的最大值,然后反向传播更新矩阵。

    • 输入层到隐层比较稀疏,只要更新1对应的那行即可(CBOW更新V*1行,Skip只要1行),但是隐层到输出层比较稠密,需要更新的是N*V的矩阵,计算量比较大(CBOW和Skip都是V*N级别)。

    Word2Vec的两种形式

    CBOW利用上下文预测wt的值,Skip-gram利用wt预测上下文的值

    CBOW(上下文生成词向量)

    跟上一个模型不同,输入的是多个词,W_{V*N}参数大家都共享。只是求h的公式改成了求平均。需要学习W_{V*N}W'_{N*V}

    image.png
    1. h=\frac{1}{C} W_{V*N}^T(x_1+...+x_C)=\frac{1}{C}(v_{w1}+...v_{wC})^T,C=2c

    W_{V*N}的列向量代表某个单词作为上下文出现的时候的词向量
    W'_{N*V}的行向量代表某个单词作为中心词出现的时候的词向量

    1. u=hW'_{N*V},u的维度等于词汇量的大小,每一维代表该单词作为中心词的得分。

    2. 既然有了每个单词的得分,那么直接把这个得分转化成0-1之间的概率就行了,用softmax函数就能实现\hat{y}=softmax(u)

    3. 怎么衡量\hat{y},y的差异?选择信息论中的交叉熵即可

    H(y,\hat{y})=-\sum_{j=1}^{|V|}y_jlog(\hat{y_j}),因为只有第i点为1,其他全0,所以H=-y_ilog(\hat{y_i})

    现在有了模型预测出的中心词是每个单词的概率\hat{y}=[0.1,0.2,...,0.4,...,0]和真实的one-hot-vector概率y=[0,.,1,.,0]

    最好的情况就是预测的值与真实值完全一样,这时候可以计算出交叉熵的值为-1log(1)=0;当预测值与真实值越接近时,损失越小,模型的预测效果也就越好。这就要求模型的输出向量y在正确单词(下标为c)处值要接近1,根据概率分布的特征,也就是在其他位置处的值接近0。

    右边的log要接近于u_c^T\hat{v}

    \hat{v}为预估的输出词\hat{y}


    Skip-gram(单词预测上下文,输出概率最高的2c个词)

    image.png image.png

    注:W'_{V*N}参数大家都共享,理论上输出的是词表中各个词的概率,在各个位置上的运算输出应该一样。

    按词core-词A的pair来训练,使得:Max \text{ } p(A|core),Min \text{ } p(otherwords|core)

    argmax \prod_{(w,c)\in D}\frac{1}{1+e^{-u_c*v_w}}+\prod_{(i,c) \in \hat{D}}[1-\frac{1}{1+e^{-u_c*v_i}}]

    c = core , i = otherwords, w = RelativeWords

    argmax \sum_{(w,c)\in D}log( \frac{1}{1+e^{-u_c*v_w}})+\sum_{(i,c) \in \hat{D}}log [1-\frac{1}{1+e^{-u_c*v_i}}]

    简化可得:argmax \sum_{(w,c)\in D} log( \sigma (u_c*v_w))+\sum_{(i,c) \in \hat{D}} log(\sigma (-u_c*v_i))

    image.png

    如果已知中心词,那么出现中心词的周围词的概率是独立的

    image.png 没有uc,因为输出没有中心词,用初始输入 vc [0,..,1,..,0]替代
    • 输出层时所乘的词表中每个词的权值向量组成的矩阵非常庞大,所以word2vec的实现里用了负采样或者哈夫曼树做多层二分类做优化

    Word2Vec优化

    训练词汇表需要开销特别大,隐层到输出层的softmax计算量也很大。针对后者,我们提出了以下两种优化方法:

    1. Hierarchical Softmax(最大似然估计+HaffmanTree)

    加速softmax计算,根节点是隐藏层输入词向量\frac{1}{C}W_{V*N}^T(x_1+...+x_c)

    • 目的:
    1. 使用二叉树,复杂度从|V|降到了log_2|V|
    2. 由于使用霍夫曼树是高频的词靠近树根,这样高频词需要更少的时间会被找到,这符合我们的贪心优化思想。
    叶节点权重是单词出现的次数

    P(+类)= {\sigma}(x^{T}_{w}\theta) = \frac{1}{1+e^{ x^T_w \theta }}

    我们需要训练的参数是每个节点的 \theta

    在word2vec中,我们采用了二元逻辑回归的方法,即规定沿着左子树走,那么就是负类(编码为1),沿着右子树走,那么就是正类(编码为0)。判别正类和负类的方法是使用sigmoid函数,即:

    被划分为左子树而成为负类的概率为P(-)=1-P(+)(决定往左还是往右走)

    image.png

    其中图中白色的叶子节点表示词汇表中所有的|V|个词, 黑色节点表示非叶子节点, 每个叶子节点代表语料库中的一个词,于是每个词语都可以被01唯一的编码,并且其编码序列对应一个事件序列。而我们的目的是使的w=w_O这条路径的概率最大,即: P(w=wO|wI) 最大。


    • 具体的公式表达:
    image.png image.png

    经过l^w-1个节点,编码从下标2开始(根节点无编码),对应的参数向量下标从1开始(根节点为1)。

    其中,每一项(二进制的每一位|x_w)是一个逻辑斯谛回归

    image.png

    考虑到d只有0和1两种取值,我们可以用指数形式方便地将其写到一起

    image.png

    我们的目标函数取对数似然:

    image.png
    1. 负采样(跟Hierarchical效果差不多,而且更简单)

    负采样NS仅仅更新一小部分向量,一般是5-20个,可以手工设定,而非全部V个(一般来说V都是几万到几百万的量级)。

    负采样的思想便是每次训练只随机取一小部分的负例使他们的概率最小,以及对应的正例概率最大。

    具体的目标函数:v_{w_0}'是输入正例onehotw_0乘以矩阵得到的词向量,v_{w_i}相当于h则是在CBOW时等于h=\frac{1}{C}(\sum^{C}_{j=1}v_{wj}),在Skip时等于h=v_{w_i},乘以即输入和隐藏之间的矩阵。v_{WI}则是隐层到输出层的矩阵。

    image.png
    • 什么是负样本?(降低输出假词的概率)

    比如我们有一个训练样本,中心词是w,它周围上下文共有2c个词,记为context(w)。由于这个中心词w,的确和context(w)相关存在,因此它是一个真实的正例。通过Negative Sampling采样,我们对输出词用假词进行替换,这样context(w)和wi就组成了neg个并不真实存在的负例。利用这一个正例和neg个负例,我们进行二元逻辑回归,得到负采样对应每个词wi对应的模型参数θi,和每个词的词向量。(在论文中,作者指出指出对于小规模数据集,选择5-20个neg words会比较好,对于大规模数据集可以仅选择2-5个neg words)

    1个正例和一堆负例的极大似然估计:

    \prod_{i=0}^{neg}P(context(w_0), w_i) = \sigma(x_{w_0}^T\theta^{w_0})\prod_{i=1}^{neg}(1- \sigma(x_{w_0}^T\theta^{w_i})),其中x_{w0}是正例

    对应的对数极大似然:L = \sum\limits_{i=0}^{neg}y_i log(\sigma(x_{w_0}^T\theta^{w_i})) + (1-y_i) log(1- \sigma(x_{w_0}^T\theta^{w_i}))

    \begin{align} \frac{\partial L}{\partial \theta^{w_i} } &= y_i(1- \sigma(x_{w_0}^T\theta^{w_i}))x_{w_0}-(1-y_i)\sigma(x_{w_0}^T\theta^{w_i})x_{w_0} \\ & = (y_i -\sigma(x_{w_0}^T\theta^{w_i})) x_{w_0} \end{align}

    \frac{\partial L}{\partial x^{w_0} } = \sum\limits_{i=0}^{neg}(y_i -\sigma(x_{w_0}^T\theta^{w_i}))\theta^{w_i}

    根据以上的式子利用梯度上升法(求极大不是极小)可以解出\theta^{w_i}x_{w_0}

    • 如何进行负采样?
    image.png

    如果词汇表的大小为V,那么我们就将一段长度为1的线段分成V份,每份对应词汇表中的一个词。当然每个词对应的线段长度是不一样的,高频词对应的线段长,低频词对应的线段短。每个词w的线段长度由下式决定:

    p(w) = \frac{coun(w)^{0.75}}{\sum _{u}count(w)^{0.75}}

    相比于直接使用频次作为权重, 取0.75幂的好处可以减弱不同频次差异过大带来的影响,使得小频次的单词被采样的概率变大。

    在采样前,我们将这段长度为1的线段划分成M等份(在word2vec中,M取值默认为10^8),这里M>>V,这样可以保证每个词对应的线段都会划分成对应的小块。而M份中的每一份都会落在某一个词对应的线段上。在采样的时候,我们只需要从M个位置中采样出neg个位置就行,此时采样到的每一个位置对应到的线段所属的词就是我们的负例词。

    • 另外还有随机删除高频词汇的操作:主要思想是少训练没有区分度的高频term

    Facebook的双塔模型(item2vec)

    image.png

    Item2Vec只能利用序列型数据,这就需要上Graph Embedding了。广告侧的模型结构对物品embedding,也算一种Item2Vec。


    • item2vec 和 传统的word2vec 两者的区别:item2vec为什么抛弃了序列关系和空间性?

    优化版的Word2Vec用了negative sampling,首先全局计算词频,按照词频选定中心词all,再按照词频负采样生成上下文,直接训练。这时已经没有什么序列性了。

    至于item2vec,很多商品数据是离散的,没有什么序列性,这时直接使用负采样就行。在句子中序列性都没那么重要,更别说离散的CTR数据了。


    问答环节

    为什么说深度学习的特点不适合处理特征过于稀疏的样本?

    深入梯度下降的过程会发现如果特征过于稀疏会导致整个网络收敛过慢,因为每次更新只有极少数的权重会得到更新。这在样本有限的情况下几乎会导致模型不收敛。

    我们能把输出矩阵中的权重向量当作词向量吗?

    可以,两者都可以。输入输出矩阵都可以用作embedding,官方采用了输入矩阵,但只是做embedding的话,不直接优化效果,采用输入或者输出矩阵没有本质的差别。

    知道了user对item的播放序列使用item2vec可以生成item的向量表示,但是如何得到user的向量表示呢?

    最naive的方法就是平均一下,改进一下的话可以用attention机制生成user embedding。

    相关文章

      网友评论

          本文标题:Word2Vec详解

          本文链接:https://www.haomeiwen.com/subject/bnsmrktx.html