CS224n-word2vec

简介

关于这门课的笔记整理的博客非常的多,但是看别人的整理总没有自己整理来的印象深刻。我是一个看到新的知识必须完全吃透的人,所以决定详细的理一理word2vec的相关内容。在整理内容的过程中,会好好吸收一下别的优秀博客的精华,力保整篇文章看起来清晰。

首先介绍一下CS224n这门课程,这门课程全称是 “Natural Language Processing With Deep Learning”,也就是主要讲的是目前是如何利用最热门的深度学习来进行自然语言处理的。该课程的第一节课主要讲的是自然语言处理有什么应用场景等。涉及到公式推导的话就要从第二节课开始,因此我也从第二节课的内容开始进行整理。

统计语言模型

在开始介绍word2vec之前,不得不介绍统计语言模型。统计语言模型即是用来描述词、语句乃至于整个文档这些不同的语法单元的概率分布的模型,能够用于衡量某句话或者词序列是否符合所处语言环境下人们日常的行文说话方式。简单来说,统计语言模型是用来计算一个句子的概率的概率模型

假设W=(w1,w2,...,wn)是一个由n个词组成的一个句子,那么这个句子的概率就是这n个词的联合概率。

p(W)=p(w1,w2,...,wn)
上面的式子就是W这个句子的概率,根据贝叶斯公式可以得到:
p(W)=p(w1)p(w2|w1)p(w3|w1,w2)...p(wn|w1,w2,...,wn1)
如果这些参数都已经求出来了就可以得到一个句子的概率了。下面介绍一个最简单的计算这些条件概率的方法,也是nlp中最简单的方法。

n-gram模型

上面提到需要计算条件概率。那么现在考虑 P= p(wk|w1,...,wk1)的近似计算。根据贝叶斯公式有:

P=p(w1,...,wk)p(w1,...,wk1)
当我们的语料足够多的时候,P可近似表示为
Pcount(w1,...,wk)count(w1,...,wk1)
从上面的公式可以看出wk和它前面的所有单词都相关,这在实际中并不合理。这里就涉及到了n-gram的基本思想:假定一个词出现的概率只与它前面固定数目的词语相关。假设一个词出现的概率就只与它前面的 n-1 个词相关。那么就有下面的等式:
p(wk|w1,...,wk1)=p(wk|wkn+1,...,wk1)
一般n会取4以内,当n取1的时候,一个词出现的概率和前一个词语相关。上面就是最简单的n-gram的模型,总的来说它的具体工作就是在语料中统计各种词串出现的次数,将概率值计算好之后就存储起来以便计算一个句子的概率。这个是最基本的统计语言模型,下面将介绍近几年来热门的语言模型——神经概率语言模型。

神经概率语言模型

该模型最先在Bengio的一篇论文中提出,模型中用到了一个重要的工具——词向量。现实生活中的语言其实是一系列符号的集合,而这样的集合是具有内容的,用英文来说就是meaning。然而机器不仅无法直接读取我们的语言(也就是一个句子甚至是一个单词),更无法识别到语言的内容以及含义。所以我们的首要任务是要将语言转换成机器能够识别的格式,然后再建模。那么所谓的机器能够识别的格式就是词向量,也就是包含一系列实数的一个向量,问题是这样的向量该怎么构建呢?

  1. one-hot编码
    在nlp(自然语言处理)中,普遍认为单词是最小的单位,所以我们怎么来表示一个单词呢?

    这里需要给出几个定义,我们有一个足够大的词典D并且词典大小为|V|,词典中每个单词都是不重复并且有自己唯一索引号的。所以我们可以使用一个R|V|x1 的向量来表示一个单词。具体的做法是假如 motel 是词典中的第11个词,hotel 是词典中的第8个词。
    CS224n-word2vec
    那么motel的词向量在11这一个索引取值为1,在其他索引的取值都为0。同理hotel的词向量在8索引取值为1,其他索引的取值为0。

    但这种词向量表示具有一些缺点,比如容易造成维数灾难(如果字典长度是万级的,一个向量就变的非常稀疏);不能很好刻画词和词之间的相似性(不同词语之间的欧式距离永远是2 )。

  2. 分布式词向量
    nlp中有一句很著名的话, “You shall know a word by the company it keeps”。也就是说某个词的含义可以通过它旁边的词得知。针对特定的训练预料,每一个单词都会映射成一个固定长度的短向量(这里的短意味着远小于常见的词典长度),这些短向量里面的值不是稀疏的,通过将词语的信息分布到不同维度上来表征这个词语。

    说到这里可能会有些迷糊,为什么这样的词向量就可以表示一个词语呢?这个词向量的可解释性的确不强,但是实用性却是相当的好,我目前还没有想明白这一点。值得注意的是,一个词的词向量并不惟一,取决于训练预料以及训练算法。

在我们的神经概率语言模型中就需要用到上面两种词向量。下面先好好说一说神经概率语言模型。在介绍之前需要再明确一下我们的目的,和n-gram中类似,现在我们是给定一个词的上下文,然后来预测这个词。用符号的形式表示就是 max p(w|context(w))。明确这一个目标非常重要噢。

首先说到神经,其实就是神经网络。下图给出一个简单的神经网络示意图。
CS224n-word2vec
上面的神经网络的数据流如下:

  • w的前n-1个词语都表示成one-hot向量从输入层传进网络。
  • 将这n-1个one-hot向量按照顺序拼接起来成一个(n-1)*|V|长度的向量 xw
  • 隐藏层的输入是xw和权值矩阵W的内积,也就是zw=g(Wxw+p),其中g是**函数。
  • 输出层的输出是zw和权值矩阵U的内积,也就是yw=Uzw+q
  • 由于最后我们需要得到的是一个概率值,也就是yw的各个分量之和要为1。在这里体现为一个多分类问题,所以最后的yw要扔进softmax里面转换成概率。

这样上面神经网络的大致工作流程已经说明白了。下面就详细介绍一下word2vec,一个流行的训练词向量的模型。

word2vec

word2vec其实只是一个称呼,意味着将word转换成vector,它里面其实包含了两个重要的模型:

  • CBOW (Continuous Bag of Words):通过一个固定窗口大小的上下文单词来预测一个目标单词。
  • SG(Skip-grams):通过一个中心单词来预测固定长度的上下文单词。

这两个模型的网络结构图如下:
CS224n-word2vec
其中目前又有两种高效的训练方法,也就是说总共有四种模型:

  • Hierarchical softmax
  • Negative sampling

Naive softmax

我们首先来讲最基本的训练方法,也就是朴素的softmax而不是上面两种方法。而这个方法就用SG来说明,SG和CBOW其实是想通的,只说明其中一个另一个也可以直接类推。

在一个语料库中,对于任意的词语t,要预测窗口大小为 m 的上下文,那么目标函数如下,目标函数的意义是所有预测结果的概率值相乘,也就是似然函数,目标函数中的θ代表了所有需要我们去优化的神经网络参数:

J(θ)=t=1Tmjmp(wt+j|wt)
在机器学习里面我们习惯将乘转换成和,将最大化似然函数转换成最小化代价函数,所以我们就使用负对数似然函数作为我们的目标函数:
J(θ)=1Tt=1Tmjmlog(p(wt+j|wt))
接下来我们需要知道怎么表示 p(wt+j|wt),这样我们才可以得到一个直接的表达式。我们上面说过最后要使用softmax函数来表示概率,下面的一个softmax类型的概率就能够表示 p(wt+j|wt)
p(o|c)=exp(uoTvc)w=1Vexp(uwvc)
这里面值得注意的是,分子使用上下文词语o的输出词向量和中心词v的输入词向量作点乘,如果点乘出来的值越大,说明两个词越相近。最后除以所有输出词向量和输入词向量的点乘的和转换成概率值。下面一幅图详细展示了实际程序中是怎么计算的。
CS224n-word2vec
输入是一个长度为7的one-hot向量,注意到这个向量在这里的作用就是选出来输入层和隐藏层中间的权值矩阵的第5列出来,然后隐藏层并没有**函数所以是一个线形层,然后隐藏层的输出和隐藏层到输出层的权值矩阵相乘得到一个长度为字典长度的向量,注意到图中没进入softmax的三个向量是一模一样的。最后再分别比较softmax层的输出向量和真实的要预测的词语的one-hot向量的损失,由于一般是使用交叉熵损失函数,又由于真实的向量是one-hot的,所以对于一个单词来说,它的损失就是对应索引位上的预测概率值。最后总的损失将所有单词的预测概率值相加就可以了。

知道了大致的流程以后就要知道怎么更新我们的神经网络参数了,就是利用梯度来更新啦~现在我们就要对J(θ)使用梯度下降让他取极小值。