本博客仅为作者记录笔记之用,不免有很多细节不对之处。还望各位看官能够见谅,欢迎批评指正。


  word2vector顾名思义就是要把单词转化为向量来表示。我们可以通过模型的训练将文本内容转化为K维向量空间中的向量,这样我们在向量空间中可以使用相似度来代表词与词之间的相似度。正是因为这样,word2vector的方法被广泛的运用在NLP领域,例如文本分类,语义分析,文本聚类等。

1.Huffman树

1.1 Huffman树的定义

  在介绍word2Vector之前,我们需要了解一种数据结构Huffman树,这种结构被广泛的应用在NLP领域中。它是二叉树的一种,在Huffman树中,每个节点都有一个非负的权值。下面给出Huffman树的一些基本定义

  • 节点的路径长度:若规定根节点的层数为1,那么根节点到第L层的节点的路径长度为L-1;
  • 节点的带权路径长度:指从根节点到该节点的路径长度与该节点的权值的乘积;
  • 树的带权路径长度:指所有叶子结点的带权路径长度之和

  若给定n个权值作为n个叶子结点,我们去构造一棵二叉树,使得二叉树的带权路径长度达到最小,那么我们称这种二叉树为最优二叉树,也就是Huffman树。

1.2 Huffman树的构造

  Huffman树的构造主要可以分成4步:

  1. 将{$w_1,w_2,w_3…w_n$}n个权值看成是n棵树的森林;
  2. 从森林中挑选出两个权值最小的组成一棵新的树,组成新的树的权值为左右子树的权值之和;
  3. 从森林中删除选取的两棵树,并将组成的新树添加到森林中;
  4. 重复第2、3步,直到森林中只有一棵树为止,最后那棵树即为Huffman树;

注意:一般在第二步将两棵树合并时,我们习惯于将权值较大的那棵树作为左子树,而将权值较小的那棵树作为右子树。

1.3 Huffman编码

  Huffman编码最早是使用于报文的传送,目的是在传送同样一段报文里,让报文编码总长度达到最短。因为我们再构造Huffman树时,出现频率较高的词,它所在的叶子结点离根节点近;而出现频次较低的词,它所在的叶节点就离根节点较远。

  Huffman的编码规则:将构造好的Huffman树的所有左子树编码为1,右子树编码为0,根节点不用编码。任意一个词的Huffman编码为从根节点起,到该词所对应的位置所经历的节点的编码。

2.词向量

  在word2vector之前,一种常见的将word转化为向量的方法就是one-hot。One-hot主要是维护一个单词字典,对单词进行顺序编号。假设字典里有K个单词,那么我们每一个单词对应一个K维向量,而在向量里,只有这个单词对应编号的行为1,其余行均为0。这种方法虽然简单易行,但是会有几个明显的缺点:

  • 这种表达方式无法定义词与词之间的相似度,因为任意的两个向量的距离都是相同的;
  • 当我们要维护的词的数目很多时,这会使每一个单词的词向量维数很大,这会造成维灾难;

  而另外一种方法就是Hinton在很早前提出的distribution representation。它主要是想通过模型的训练,将每个单词映射到一个K维向量中(其中K为模型的超参数),这样我们就可以通过不同向量之间的距离来定义词与词之间的语义相似度。

3.语言模型

3.1 n-gram模型

  如果我们需要计算一个句子的概率模型,通常会基于一个语料库来对其进行计算。我们如何去定义一个句子的概率呢?假设 $W=(w_1,w_2…w_T)$ 代表由T个词按照顺序组成的一个句子,那么它的联合概率可以定义为:

$p(W)=p(w\_1^T)=p(w\_1,w\_2...w\_n)$

其中 $w_1^T$ 代表从 $w_1$ 到 $w_T$。根据贝叶斯公式,我们可以有如下表达:

$p(w\_1,w\_2...w\_n)=p(w\_1^{T-1})*p(w\_T|w\_1^{T-1})$

而 $p(w_1^{T-1})$ 又可以写成

$p(w\_1^{T-1})=p(w\_1^{T-2})*p(w\_{T-1}|w\_1^{T-2})$

因此,进行类推,我们可以得到

$p(w\_1,w\_2...w\_n)=p(w\_1)\*p(w\_2|w\_1)\*p(w\_3|w\_1^2)\*...p(w\_T|w\_1^{T-1})$

其中的条件概率$p(w_2|w_1), p(w_3|w_1^2)…p(w_T|w_1^{T-1})$ 就是模型的参数,如果这些参数全部已知,那么给定一个句子,那么我们就可以求出这个句子的概率了。

  对于公式 $p(w_1,w_2…w_n)=p(w_1^{T-1})*p(w_T|w_1^{T-1})$ ,我们对其进行变形可以得到:

$$p(w_k|w_1^{k-1})={p(w_1^k)\over {p(w_1^{k-1})}}$$

根据大数定律,当我们的语料库足够大时,条件概率可以由下面公式来近似表示:

$$p(w_k|w_1^{k-1}) \approx {count(w_1^k)\over {count(w_1^{k-1})}}$$

其中$count(w_1^k)$和$count(w_1^{k-1})$代表词组$w_1^k$和$w_1^{k-1}$的出现次数。

  上述定义的条件概率里,一个词出现的概率是和其前面所有词的概率都有关。如果假设,一个词出现的概率只与其前面的n个单词有关,那么就是n-gram的思想了。它做了一个n-1阶的Markov假设,即认为一个词出现的概率至于其前面的n个单词有关,那么有:

$$p(w_k|w_1^{k-1}) = p(w_k|w_{k-n+1}^{k-1})$$

那么根据贝叶斯公式可以得到

$$p(w_k|w_{k-1}^{k-1}) = {p(w_{k-n+1}^k)\over {p(w_{k-n+1}^{k-1})}}$$

当k=2时,上述公式就可以写成

$$p(w_k|w_{k-1}^{k-1}) = {p(w_{k-1}^k)\over {p(w_{k-1}^{k-1})}}$$

$$p(w_k|w_{k-1}^{k-1}) \approx {count(w_{k-1},w_k)\over {count(w_{k-1})}}$$

下面给出一个简单的例子来简单说明如何去计算。假设我们的语料库有三句话:1.小明喜欢吃西瓜。2.小红不喜欢吃苹果。3.小明不喜欢吃苹果。那么我们如何去计算“小红不喜欢吃西瓜”这句话的概率呢?

3.2