word2vec 入门(三)模型介绍
两种模型,两种方法
- 模型:CBOW和Skip-Gram
- 方法:Hierarchical Softmax和Negative Sampling
CBOW模型Hierarchical Softmax方法
CBOW 是 Continuous Bag-of-Words Model 的缩写,是预测 \(
P({W_t}|W_{t-k},W_{t-(k-1)},W_{t-(k-2)}...,W_{t-1},W_{t+1},W_{t+2}...,W_{t+k})\)
- INPUT:输入层,输入的是若干个词的词向量
- PROJECTION:投影层,是输入的若干个词向量的累加和,注意是向量的累加和,结果是一个向量。
- OUTPUT:输出层,其实是个二叉树,隐层的那个节点要跟输出层的那个二叉树的所有非叶节点链接的,第三层的这个二叉树是一个霍夫曼树,每个非叶节点也是一个向量,但是这个向量不代表某个词,代表某一类别的词;每个叶子节点代表一个词向量,为了简单只用一个w表示,没有下标。输入的几个词向量其实跟这个霍夫曼树中的某几个叶子节点是一样的,当然输入的那几个词跟它们最终输出的到的那个词未必是同一个词,而且基本不会是同一个词,只是这几个词跟输出的那个词往往有语义上的关系。
还有要注意的是,这个霍夫曼树的所有叶子节点就代表了语料库里面的所有词,而且是每个叶子节点对应一个词,不重复。 - w(t):当前词语(向量)
- w(t-2),w(t-1),w(t+1),w(t+2):当前词语的上下文
- SUM:上下文的累加和
这个网络结构的功能是为了完成一个的事情——判断一句话是否是自然语言。怎么判断呢?使用的是概率,就是计算一下这句话的“一列词的组合”的概率的连乘(联合概率)是多少,如果比较低,那么就可以认为不是一句自然语言,如果概率高,就是一句正常的话。这个也是语言模型的目标。
对于上面的那个网络结构来说,网络训练完成后,假如给定一句话s,这句话由词w1,w2,w3,…,wT组成,就可以利用计算这句话是自然语言的概率了,计算的公式是下面的公式
其中的Context表示的是该词的上下文,也就是这个词的前面和后面各若干个词,这个“若干”(后面简称c)一般是随机的,也就是一般会从1到5之间的一个随机数;每个\( p({w_i}|Contex{t_i})\)代表的意义是前后的c个词分别是那几个的情况下,出现该词的概率。举个例子就是:“大家 喜欢 吃 好吃 的 苹果”这句话总共6个词,假设对“吃”这个词来说c随机抽到2,则“吃”这个词的context是“大家”、“喜欢”、“好吃”和“的”,总共四个词,这四个词的顺序可以乱,这是word2vec的一个特点。
计算\({p({w_i}|Context_i)}\)的时候都要用到上面的那个网络,具体计算的方法用例子说明,假设就是计算“吃”这个词的在“大家”、“喜欢”、“好吃”和“的”这四个词作为上下文的条件概率,又假设“吃”这个词在霍夫曼树中是的最右边那一个叶子节点,那么从根节点到到达它就有两个非叶节点,根节点对应的词向量命名为A,根节点的右孩子节点对应的词向量命名为B,另外再假设“大家”、“喜欢”、“好吃”和“的”这四个词的词向量的和为C,则
其中
其中V表示语料库里面的的词的个数,这个定义的意思是在上下文C出现的情况下,中间这个词是A的概率。为了计算这个概率,需要把语料库里所有的词的能量都算一次,然后根据A的能量,得到的比值就是出现A的概率。
例子说明
例子:句子:我,喜欢,观看,巴西,足球,世界杯
w=足球
正类概率:$${\rm{\sigma(X_w^T\theta)} = \frac{1}{1+e{-X_wT\theta}}}$$
负类概率:$$1-\rm{\sigma(X_w^T\theta)}$$
"足球" 叶子节点经过4次二分类,每次分类结果对应的概率为
由Context("足球")预测"足球"出现的概率
- 对于词典中的每个词w有,\(l^w\) 结点个数
\(p(w|Context(w))= \sum_{j=2}{l_w}p(d_jw|{X_w,\theta_{j-1}^w})\)
- 对于由S个句子组成的语料库C有
- 取对数似然函数:
- 梯度下降法进行求解
对于语料库中的某个词\(w_t\),对应着二叉树的某个叶子节点,因此它必然有一个二进制编码,如"010011"。在训练阶段,当给定上下文,要预测后面的词\(w_t\)的时候,我们就从二叉树的根节点开始遍历,这里的目标就是预测这个词的二进制编号的每一位。即对于给定的上下文,我们的目标是使得预测词的二进制编码概率最大。形象地说,我们希望在根节点,词向量和与根节点相连经过logistic计算得到bit=1的概率尽量接近0,在第二层,希望其bit=1的概率尽量接近1,这么一直下去,我们把一路上计算得到的概率相乘,即得到目标词\(w_t\)在当前网络下的概率\(P(w_t)\),那么对于当前这个sample的残差就是\(1-P(w_t)\),于是就可以使用梯度下降法训练这个网络得到所有的参数值了。显而易见,按照目标词的二进制编码计算到最后的概率值就是归一化的。
Hierarchical Softmax用Huffman编码构造二叉树,其实借助了分类问题中,使用一连串二分类近似多分类的思想。例如我们是把所有的词都作为输出,那么“桔子”、“汽车”都是混在一起。给定w_t的上下文,先让模型判断\(w_t\)是不是名词,再判断是不是食物名,再判断是不是水果,再判断是不是“桔子”。
但是在训练过程中,模型会赋予这些抽象的中间结点一个合适的向量,这个向量代表了它对应的所有子结点。因为真正的单词公用了这些抽象结点的向量,所以Hierarchical Softmax方法和原始问题并不是等价的,但是这种近似并不会显著带来性能上的损失同时又使得模型的求解规模显著上升。
没有使用这种二叉树,而是直接从隐层直接计算每一个输出的概率——即传统的Softmax,就需要对|V|中的每一个词都算一遍,这个过程时间复杂度是O(|V|)的。而使用了二叉树(如Word2vec中的Huffman树),其时间复杂度就降到了O(log2(|V|)),速度大大地加快了。
Skip-gram
网络结构如下:
计算p(大家│吃)这么一个概率,这里的计算方法就简单多了,就是随机从语料库里面抽取c个词,这里假设c=3,抽中了D,E,F这三个词,又假设“吃”这个词的词向量是A,那么就计算“吃”这个词的概率就用下面的公式
所有词的概率计算出来再连乘就是整句话是自然语言的概率了。剩下的同上。
解法跟上面相同。
为什么要使用 Hierarchical Softmax 或 Negative Sampling
前面提到到 skip-gram 中的条件概率为:
\(p(w_o|w_I) = \frac{e{v_{w_o}T{V_{W_I}}}} {\sum_{w=1}W{e{v_w^T {V_{W_I}}}}}\)
这其实是一个多分类的 logistic regression, 即 softmax 模型,对应的 label 是One-hot representation,只有当前词对应的位置为 1,其他为 0。普通的方法是 p(wo|wi) 的分母要对所有词汇表里的单词求和,这使得计算梯度很耗时。
Hierarchical Softmax 则是介于两者之间的一种方法,使用的办法其实是借助了分类的概念。 假设我们是把所有的词都作为输出,那么“桔子”、“汽车”都是混在一起。而 Hierarchical Softmax 则是把这些词按照类别进行区分的。对于二叉树来说,则是使用二分类近似原来的多分类。例如给定 wi,先让模型判断 wo是不是名词,再判断是不是食物名,再判断是不是水果,再判断是不是“桔子”。虽然 word2vec 论文里,作者是使用哈夫曼编码构造的一连串两分类。但是在训练过程中,模型会赋予这些抽象的中间结点一个合适的向量, 这个向量代表了它对应的所有子结点。因为真正的单词公用了这些抽象结点的向量,所以Hierarchical Softmax 方法和原始问题并不是等价的,但是这种近似并不会显著带来性能上的损失同时又使得模型的求解规模显著上升。
Negative Sampling 也是用二分类近似多分类,区别在于使用的是one-versus-one 的方式近似,即采样一些负例,调整模型参数使得模型可以区分正例和负例。 换一个角度来看,就是 Negative Sampling 有点懒,他不想把分母中的所有词都算一次,就稍微选几个算算,选多少,就是模型中负例的个数,怎么选,一般就需要按照词频对应的概率分布来随机抽样了。