【CS224n笔记 (2) 】词向量表示word2vec

1、Word Meanning

1.1我们怎样表述一个单词的意思

对于英语中的meaning这个单词,韦伯词典中的解释如下:

  • the idea that is represented by a word, phrase, etc.
  • the idea that a person wants to express by using words, signs, etc.
  • the idea that is expressed in a work of writing, art, etc

这也就是上一节中讲的NLP难的问题之一,歧义。一个单词往往有很多个意思,在合适的语境下有合适的意思。

1.2 在计算机中我们如何处理意思?

使用分类词典(WordNet)来表示计算机中的词语。

from nltk.corpus import wordnet as wd
panda = wd.synset('panda.n.01')
hyper = lambda s : s.hypernyms()
list(panda.closure(hyper)

结果是:

[Synset('procyonid.n.01'),
 Synset('carnivore.n.01'),
 Synset('placental.n.01'),
 Synset('mammal.n.01'),
 Synset('vertebrate.n.01'),
 Synset('chordate.n.01'),
 Synset('animal.n.01'),
 Synset('organism.n.01'),
 Synset('living_thing.n.01'),
 Synset('whole.n.02'),
 Synset('object.n.01'),
 Synset('physical_entity.n.01'),
 Synset('entity.n.01')]

可以看到我们是采用一种离散的形式来进行表示的。那么这种离散表示存在什么问题呢?

  • 使用语言学的资源虽然很好,但是还是不够细致。比如一些同义词:
    adept, expert, good, practiced, proficient, skillful

  • 缺少新词

  • 太过主观

  • 需要人自己去创建和更新

  • 很难去计算单词之间的相似性

无论是在任何学科,研究语言处理都是将词语作为最小的单位,那么在这其中有一种最简单的给词语编码的方式就是one-hot编码。比如现在单词表有5个单词,分别是【我,喜欢,跑步,运动,喝水】,那么我们想表示运动这个词语就是:[0, 0, 0, 1, 0],同样的表示喝水就是[0, 0, 0, 0, 1]。可见实际上表示的就是单词的位置。但是这样表示有一些问题:

维度爆炸问题,课程中提出了谷歌发布的1TB语料词汇量是1300万,这样完全维度爆炸了。

相关性问题,比如上例中运动的向量是[0, 0, 0, 1, 0],而跑步的向量是[0, 0, 1, 0, 0]两向量的内积为0,也就是完全不相关。但实际中我们知道,运动和跑步并不是毫无关系的,所以这种表示方式表达不出来这种关系。

ps:为什么向量内积可以得到相关性?
请参考余弦定理。

1.3 从符号表示到分布式表示

正因为 ont-hot 编码无法表示相关性,所以新提出了一种分布式表示,也就是分布式表示。语言学家J. R. Firth提出,通过一个单词的上下文可以得到它的意思,这是现代基于统计的自然语言处理成功的主要原因。比如下面这个例子,你只有把banking放到句子中,你才能真正确定它的意思。
在这里插入图片描述
通过向量去表示单词的意思

将为每个单词类型构建一个密集向量,以便它能够很好地预测上下文中出现的其他单词,而这个密集向量一般在300-500维左右,有的甚至超过1000维,但是和ont-hot相比,已经是降维了。它用一些上下文中出现的单词来表示一个中心词,比如下面这个例子,当然维度要更高。
在这里插入图片描述
横坐标表示我想表示出来的中心词,纵坐标表示用一些上下文中出现的词来表示他们。我们可以很明确的看到MAN的性别是-1,Woman的性别是1,其他的都差不多,而Apple和Orange都是食物,所以基本Food的占比很高。

可以看的出来,这种表示的方法贼好,但是有个问题就是,我们怎么能成功的用计算机实现这种表示方法,其中的一种方法就是后面要提到的word2vec模型。

1.4 学习神经网络词嵌入的基本思想

我们首先定义一个预测某个单词的上下文的模型,
p ( c o n t e x t w t ) = . . . p(context|w_t)=...
其中 c o n t e x t context 为需要预测的上下文, w t w_t 为给定的词

再定义一个损失函数:
J = 1 p ( w t w t ) J = 1-p(w_{-t}|w_t)
这里的 w t w_{-t} 表示除了的上下文 w t w_t (负号通常表示除了某某之外,比如下面的例子中表示除了苹果以外的其他任何单词),如果完美预测,损失函数为零。然后在一个大型语料库中的不同位置得到训练实例,调整词向量,最小化损失函数。

比如下面这句话:我想吃苹果,也想吃梨子
根据上面的例子,当苹果出现了,预测下面梨子出现的可能性。所以概率模型也就是:
p ( ) = . . . p(梨子|苹果)=...
那么损失函数也就是:
J = 1 p ( w ) J = 1-p(w|苹果)
如果w = 梨子,那么概率为1,损失函数为0。

1.5 直接学习低维词向量

  • Learning representations by back-propagating errors (Rumelhart et al., 1986)
  • A neural probabilistic language model (Bengio et al., 2003)
  • NLP (almost) from Scratch (Collobert & Weston, 2008)
  • A recent, even simpler and faster model: word2vec (Mikolov et al. 2013)

2. Word2vec

首先word2vec有两种算法:

  • skip-gram:通过中心词去预测周边的词
  • Continuous Bag of Words(CBOW):通过上下文的单词,去预测中心词。

两种有效的训练方法:

  • Hierarchical softmax
  • Negative sampling

在本课中只会讲Naïve softmax
按步骤,我们首先来讲Skip-gram

2.1 Skip-gram

在这里插入图片描述
我们Skip-gram模型的任务就是要通过into去预测周围的一些词。先定义一个半径m,我们需要预测的就是以into为原点,m为半径范围内的词注意这里虽然有四条线,但模型中只有一个条件分布。学习就是要最大化这些词在into的假设下的条件概率。

2.1.1 损失函数

对上面的模型,我们的损失函数定义为所有位置的预测结果的乘积:
J ( θ ) = t = 1 T m j m , j 0 p ( w t + j w t ; θ ) J'(\theta) = \prod_{t=1}^T \prod_{--m\leq j \leq m,j\neq 0}p(w_{t+j}|w_t;\theta)
其中T为文本的总长度,m为上下文的长度,然后取对数似然的相反数方便计算,得到:
J ( θ ) = 1 T t = 1 T m j m , j 0 l o g p ( w t + j w t ) J(\theta) = -\frac{1}{T}\sum_{t=1}^T \sum_{--m\leq j \leq m,j\neq 0}log p(w_{t+j}|w_t)

其中的 p ( w t + j w t ) p(w_{t+j}|w_t) 可以使用softmax函数进行计算,softmax函数主要是将数值转化成概率。
p ( o c ) = e x p ( u o T v c ) w = 1 v e x p ( u w T v c ) p(o|c) = \frac{exp(u_o^T v_c)}{\sum_{w=1}^v exp(u_w^T v_c)}

其中o是输出的中间词上下文中的确切某一个,c是中间词。u是对应的上下文词向量,v是词向量。

这里举一个栗子:
我想吃苹果,也想吃__.
现在我有这样一个需求在这,需要根据苹果取预测后面那句话空白处的结果,此时 o o 表示空白处的需要预测的词,比如梨子 c c 表示中间词苹果 u u v v 表示的都是词向量, u o u_o 表示的是梨子(假设空白处的正确答案是梨子)的向量, v c v_c 表示的是中间词苹果的词向量, u w u_w 表示所有上下文的词的词向量。

上述式子中 u o T v c = u v = i u i v i u_o^T v_c = u\cdot v = \sum_{i} u_i v_i 为向量 u u v v 的内积,其可以刻画两个向量的相关性,两个向量的相似度越大,其内积也越大。Softmax即从实数空间到概率分布的标准映射方法。所以 p ( o c ) p(o|c) 其实衡量了预测的答案梨子与中间词苹果的相关性,并且将这个相关性的大小转化为概率。

2.1.2 skip-gram的详细过程

在这里插入图片描述
首先左边输入的是一个某个单词one-hot变量,我们知道skip-gram是通过一个中心词去预测周围的词的,然后 V × 1 V\times 1 维的输入向量和一个 d × V d\times V 维的嵌入矩阵 W W 相乘,得到一个压缩后 d × 1 d\times 1 词向量,再和一个 V × d V\times d 嵌入矩阵 W W' 相乘得到输出向量,然后输出向量经过softmax函数,变成一个概率,然后我们可以找到对应位置概率最大的判断为预测单词,根据位置去写出对应的ont-hot变量,进而确定是哪个单词。三个 W W' 矩阵具有相同的参数,因此每次训练的时候分别用中心词上下文所有的目标单词去计算loss,目的是最小化所有条件分布的乘积。其中矩阵 W W W W' 都可以作为词嵌入的矩阵。

2.1.3 训练模型:计算向量的的梯度

我们把所有的需要参数放进一个向量当作,向量如下:
在这里插入图片描述
其实这就是两个矩阵 W W W W' 的所有权重。然后求这个向量的梯度,再使用梯度下降法进行训练即可。

2.2 梯度下降

对于损失函数
J ( θ ) = 1 T t = 1 T m j m , j 0 l o g p ( w t + j w t ) J(\theta) = -\frac{1}{T}\sum_{t=1}^T \sum_{--m\leq j \leq m,j\neq 0}log p(w_{t+j}|w_t)
其中 p ( o c ) = e x p ( u o T v c ) w = 1 v e x p ( u w T v c ) p(o|c) = \frac{exp(u_o^T v_c)}{\sum_{w=1}^v exp(u_w^T v_c)} o和c为context和中心词。训练中每次都已 c e n t e r , c o n t e x t (center, context) 的格式送入数据

V c l o g e x p ( u o T v c ) w = 1 v e x p ( u w T v c ) = V c l o g e x p ( u o T v c ) V c l o g w = 1 v e x p ( u w T v c ) \frac{\partial}{\partial V_c}log \frac{exp(u_o^T v_c)}{\sum_{w=1}^v exp(u_w^T v_c)} = \frac{\partial}{\partial V_c}log exp(u_o^T v_c)- \frac{\partial}{\partial V_c}log \sum_{w=1}^v exp(u_w^T v_c)
由上式可以看出,损失函数可以分为两部分
V c l o g e x p ( u o T v c ) \frac{\partial}{\partial V_c}log exp(u_o^T v_c) V c l o g w = 1 v e x p ( u w T v c ) \frac{\partial}{\partial V_c}log \sum_{w=1}^v exp(u_w^T v_c)

左边部分由于 l o g log e x p exp 可以抵消,故
V c l o g e x p ( u o T v c ) = V c u o T v c = u o \frac{\partial}{\partial V_c}log exp(u_o^T v_c) = \frac{\partial}{\partial V_c}u_o^T v_c= u_o
右边部分则利用链式法则进行求解
V c l o g w = 1 v e x p ( u w T v c ) = 1 w = 1 v e x p ( u w T v c ) x = 1 v e x p ( u x T v c ) u x \frac{\partial}{\partial V_c}log \sum_{w=1}^v exp(u_w^T v_c) = \frac{1}{\sum_{w=1}^v exp(u_w^T v_c)} \sum_{x=1}^v exp(u_x^T v_c)u_x
注意在链式法则中求和随着链式延展要更换索引(w到x)。

所以最后损失函数的梯度
V c l o g ( p ( o c ) ) = u 0 x = 1 v e x p ( u x T v c ) u x w = 1 v e x p ( u w T v c ) = u 0 x = 1 v p ( x c ) u x \frac{\partial}{\partial V_c}log (p(o|c) ) = u_0 - \sum_{x=1}^v\frac{ exp(u_x^T v_c)u_x}{\sum_{w=1}^v exp(u_w^T v_c)} = u_0-\sum_{x=1}^v p(x|c) u_x

再用刚刚的例子解释一遍这个结果:
我想吃苹果,也想吃__.
假设这句话的中心词是苹果抽到的周边词答案是梨子 u 0 u_0 梨子的向量表述 p ( x c ) p(x|c) p ( ) p(输出的词|苹果) 的概率, v v 所有可能的结果 u x u_x 代表输出的词的向量表述 x = 1 v p ( x c ) u x \sum_{x=1}^v p(x|c) u_x 即代表对所有可能的输出的结果的加权求和,即期望。损失函数可以解释为正确答案与输出答案的期望的差距

最后使用随机梯度下降SGD进行更新,每次梯度下降只更新 W W 矩阵中的周边词对应的列向量(例如梨子、想、吃等), W W' 矩阵只更新中心词的列向量(苹果)。
在这里插入图片描述
在这里插入图片描述

END

猜你喜欢

转载自blog.csdn.net/weixin_39373480/article/details/88651868