面经之word2vec
篇(一)
前篇
本来以为自己word2vec
掌握的很好,面试的时候回答的一团糟…借此机会,结合面试提问,再来复习一遍word2vec
吧,面试给自己上了一节很重要的课…
本篇文章主要是讲解CBOW
以及skip-gram
模型
1.为什么需要word embedding
首先使用one-hot
的时候,可能会导致维度爆炸,其次,使用one-hot
的时候,所有的词之间的距离相同,而实际上,相似的词更有可能出现在相同的上下文中。如使用one-hot
表示时,人和猫、狗之间的距离相等,这个在实际上是不符合要求的,那么word embedding
可以解释上面的问题,那么什么是word embedding
呢?其中可以理解的就是采用更加紧凑的方式来避免维度爆炸,如下面一张图:
经过这样的表示后,我们的dog
就可以表示为dog
=[w1
,w2
,w3
…]
其中基向量[w1
,w2
,w3
…]可以采用PCA
之类的方式进行获取.
word embedding
的优点:
(1)相对于one-hot
,能够产生稠密的向量,避免维度爆炸;
(2)词之间的距离可以表示出来(词之间的相似度)
(3)可以作为词的特征去帮助解决其他的问题,如文本分类,命名实体识别、语义分析等。
word embedding
的缺点:向量的可解释性不强,没有one-hot
那样明确的表示意义。
2. word2vec
首先大体的介绍一下word2vec
是什么东西:word2vec
不是一个算法,它仅仅是一个工具包,将词转换为稠密的向量,它主要是包括以下几个内容:
(1)两个模型
--CBOW
--skip-gram
(2)两种训练方式
--层次softmax
--负采样(negative sampling)
上面的内容就是word2vec
这个工具的全部面貌,下面分开来叙述:
2.1 CBOW
模型
首先是给出这个模型的网络图:
解释如下:
这个模型主要是根据上下文预测当前词
按照上面的图示,我们也将这个网络结构分为三层进行描述:
-
INPUT:文本中自己设定的窗口中包含的词向量,这个词向量是
one-hot
表示的(即对于每个输入的词,其表示方式是one-hot
), -
PROJECTION:可以理解为隐藏层,直接将输入的向量进行累加求和(先进行线性变换,然后求加和)
-
OUTPUT:输出层对应一个二叉树,它是以文本中出现过的词当做叶子结点,以各词出现的次数当做权值,来构建Huffman树,我们最终的w(t)实际也是一个
one-hot
表示,对于CBOW
模型,它是一个中心值。最终稠密的向量是如何得到的呢?---->不是其他的,就是隐藏层的权值!!
那么使用
Huffman
树有什么好处呢? 首先,由于是二叉树,之前计算量为O(n),现在变成了O(log(n))。第二,由于使用霍夫曼树是高频的词靠近树根,这样高频词需要更少的时间会被找到
2.1.1 基于层次softmax来训练模型
其实模型的输出也可以也可以是softmax
,但是对于类别较多时,softmax
会对所有的词进行排序,然后取最大值,这样来做是及其耗时的,为了提升效率,我们采用了层次softmax
来解决我们的问题,将复杂度有O(n)降为O(log(n))
好了,上面的细节问完了,那么继续问的就是层次softmax
如何进行操作,可能是一大波的数学公式+证明来了:
由于我们把之前所有都要计算的从输出softmax
层的概率计算变成了一颗二叉霍夫曼树,那么我们的softmax
概率计算只需要沿着树形结构进行就可以了。如下图所示,我们可以沿着霍夫曼树从根节点一直走到我们的叶子节点的词w2
。
如何“沿着霍夫曼树一步步完成”呢?在word2vec
中,我们采用了逻辑回归的方法:即规定沿着左子树走,那么就是负类(霍夫曼树编码1),沿着右子树走,那么就是正类(霍夫曼树编码0)。判别正类和负类的方法是使用sigmoid函数,即
P ( + ) = σ ( x T w θ ) = 1 1 + e − x T w θ P(+)=\sigma(x^T{_w}\theta)=\frac{1}{ {1+e^{-x^T{_w}\theta}}} P(+)=σ(xTwθ)=1+e−xTwθ1
其中xw
是当前内部节点的词向量,而θ
则是我们需要从训练样本求出的逻辑回归的模型参数。
那么被划分为负例的概率为P(−)=1−P(+),那么在结点的内部,需要看到的就是往左还是往右,那么就是判断P(+)、P(-)哪一个概率大,那么是如何确定哪一个概率值大呢?
回到基于层次softmax
的word2vec
本身,我们的目标就是找到合适的所有节点的词向量和所有内部节点θ
, 使训练样本达到最大似然。那么如何达到最大似然呢?
以上面的例子为例,假设我们希望最大化下面的函数:
∏ 1 3 P ( n ( w i ) , i ) = ( 1 − 1 1 + e − x T w θ ) ∗ ( 1 − 1 1 + e − x T w θ ) ∗ 1 1 + e − x T w θ \prod_1^3P(n(w_i),i)=(1-\frac{1}{ {1+e^{-x^T{_w}\theta}}})*(1-\frac{1}{ {1+e^{-x^T{_w}\theta}}})*\frac{1}{ {1+e^{-x^T{_w}\theta}}} ∏13P(n(wi),i)=(1−1+e−xTwθ1)∗(1−1+e−xTwθ1)∗1+e−xTwθ1
我们定义以下几个变量,有助于我们后期公式的计算:
- 定义输入的词为
w
(最终需要求得的词) - 输入层词向量求和平均后的霍夫曼树根节点词向量为 x w x_w xw,
- 从根节点到
w
所在的叶子节点,包含的节点总数为 l w l_w lw, - w在霍夫曼树中从根节点开始,经过的第i个节点表示为 p i w p_i^w piw,对应的霍夫曼编码为 d i w d_i^w diw∈{0,1},其中i=2,3,… l w l_w lw。
- 该节点对应的模型参数表示为 θ i w \theta_i^w θiw, 其中i=1,2,… l w − 1 l_w-1 l