一、基于Negative Sampling的CBOW
1、模型讲解
NS_CBOW不像H_CBOW那样可以画出网络结构图,这更多是一个公式推导的模型;其中最重要的是负样本集的采样,并且对于每个样本扩充成1个样本集。
具体做法是:对于给定的语料库T,取$POS(w)=\left \{ (context(w),w) \right \}$作为正样本,在词典中用“负例采样算法”采样$neg$个词,取$NEG(w)=\left \{ (context(w), u_{i}),~~i\in 1,2...neg \right \}$作为负样本集;因此1个样本,可以扩充为1个样本集,$ALL(w)=POS(w) \cup NEG(w) $。
2、参数求解
2.1、目标函数的推导
定义下式,表示正样本的标签为1,负样本的标签为0
$\displaystyle H^{w}(u)=\left\{\begin{matrix} 1, & u=w \\ 0, & u\neq w \end{matrix}\right.$
在一个样本集中,每个样本的预测概率可以表示为下式;其中$\theta ^{u}$是词$u$对应的一个辅助向量,属于模型参数;直观地理解是:假设一个样本集有n个样本,对每个样本都训练一个逻辑回归模型,这n个模型对应n个输出概率。
$\displaystyle P(u|context(w))=[\sigma (\theta ^{u}\cdot x_{w})]^{H^{w}(u)}\cdot [1-\sigma (\theta ^{u}\cdot x_{w})]^{1-H^{w}(u)}$
在一个样本集中,采用极大似然估计的思想,我们希望最大化下式;也即:希望1个样本集中,这n个模型输出概率的连乘最大。
$\displaystyle g(w)=\prod_{u\in ALL(w)}P(u|context(w))$
对于给定的语料库T,我们希望极大化:
$\displaystyle G(w)=\prod_{w\in T}g(w)$
对上式取对数,得到最终的对数似然函数:
$\displaystyle L(w)=logG(w)=\sum_{w \in T}log~g(w)=\sum_{w \in T}\sum_{u \in ALL(w)}P(u|context(w))$
$\displaystyle =\sum_{w \in T}\sum_{u \in ALL(w)} \left \{ H^{w}(u)\cdot log[\sigma (\theta ^{u}\cdot x_{w})] + (1-H^{w}(u)) log [1-\sigma (\theta ^{u}\cdot x_{w})] \right \}$
$\displaystyle =\sum_{w \in T}\sum_{u \in ALL(w)} L(w, u)$
2.2、随机梯度上升法求解参数
采用随机梯度上升法进行优化,也即每次对“1个样本集”进行优化,1个样本集有n个样本,将这n个样本分别输入这n个二分类器,然后同时刷新所有的分类器参数,并且优化$\displaystyle \sum_{u \in ALL(w)} L(w, u)$ 的方法是:独立地优化“1个样本集”中每个二分类器的$L(w, u)$,让每个$L(w,j)$同时往梯度上升的方向更新一小步,来逐步逼近整体的最大化。
1、更新模型参数:1个样本集中有n个二分类器;每个二分类器都有正确的类别输出(有1个预测为正的分类器,$n-1$个预测为负的分类器),用梯度上升法更新每个二分类器的参数便可
$\displaystyle \frac{\partial L(w,u)}{\partial \theta ^{u}}=\frac{\partial }{\partial \theta ^{u}}\left \{ H^{w}(u)\cdot log[\sigma (\theta ^{u}\cdot x_{w})] + (1-H^{w}(u)) log [1-\sigma (\theta ^{u}\cdot x_{w})] \right \}$
$\displaystyle = \left \{ H^{w}(u) [1-\sigma (\theta ^{u}\cdot x_{w})] - [1-H^{w}(u)] \sigma (\theta ^{u}\cdot x_{w}) \right \}x_{w}$
$\displaystyle = [H^{w}(u) - \sigma (\theta ^{u}\cdot x_{w})] x_{w}$
于是权重的更新公式为:$\displaystyle \theta ^{u} = \theta ^{u} + \eta [H^{w}(u) - \sigma (\theta ^{u}\cdot x_{w})] x_{w}$
2、更新词向量参数:更新窗口每个词的词向量
$\displaystyle \frac{\partial L(w,u)}{\partial x_{w}}=[H^{w}(u) - \sigma (\theta ^{u}\cdot x_{w})] \theta ^{u}$
于是词向量的更新公式为:$\displaystyle v(w_{i}) = v(w_{i}) + \eta \sum_{u \in ALL(w)} \frac{\partial L(w,u)}{\partial x_{w}},~~i\in2C$
3、伪代码
1. $e=0$ 2. $\displaystyle x_{w}=\sum_{w\in context(w)}v(w)$ 3. $FOR~u=ALL(w) ~DO:$ $\displaystyle g = \eta [H^{w}(u) - \sigma (\theta ^{u}\cdot x_{w})]$ $e = e + g\theta ^{u}$ $\theta ^{u} = \theta ^{u}+ gx_{w}$ 4. $FOR~i \in 2C~DO:$ $v(w_{i})=v(w_{i})+e$ |
二、基于Negative Sampling的skip-gram
三、Negative Sampling算法
上文提到的,对于一个目标单词$w$,需要采样对应的负样本集,这个“负样本集”就是用负例采样算法得到的,其方法非常简单,就像我们转轮盘抽奖一样,有些区域的面积大,对应的奖品比较容易抽中,有些区域的面积小,这些奖品就不好抽到。
负例采样算法使用一个长度为1的线段模拟轮盘,线段一共有N段(词典的大小为N),每一段表示词典中的一个单词,高频词对应的长度长,低频词对应的长度短,每个词的长度的计算公式为:
$\displaystyle len(w)=\frac{count(w)}{\sum_{u\in D}count(u)}$
在W2V里,做了一点小小的处理:
$\displaystyle len(w)=\frac{count(w)^{0.75}}{\left ( \sum_{u\in D}count(u) \right )^{0.75}}$
采样前,将这段长为1的线段划分为M等分(M>>N,W2V中$M=10^{8}$),则一共有M-1个位置(对应图中的红色虚线),每个位置对应一个单词;
采样时,每次生成一个[1, M-1]的随机数r,看看r对应哪个单词,就将那个单词采样出来;如果碰巧采样到了目标单词$w$,直接跳过便可。