CS224n 深度学习自然语言处理 2019 版 Lecture-1 学习笔记。
这次的课程相比以往没有那么多的介绍,而是简短的介绍了人类语言的作用和特殊之外就开始讲主要课程。所以这里也不说多余的废话,直接进入主题。
Human language and word meaning
How do we represent the meaning of a word?
词是自然语言组成的基本单位(汉语体系是以字为基本单位),它表达了最基本的意思,通过不同词的不同排列组合才形成了我们丰富的语言世界。所以想让机器了解自然语言,首先要解决最基本的问题就是要让机器明白词的含义meaning of a word。
WordNet
WordNet是由Princeton 大学的心理学家,语言学家和计算机工程师联合设计的一种基于认知语言学的英语词典。它不是光把单词以字母顺序排列,而且按照单词的意义组成一个“单词的网络”。– 百度百科
说白了$WordNet$是一个网络词典,包含同义词集和上位词(“is a”关系) synonym sets and hypernyms。在$WordNet$中,用一个词的同义词和上位词来表示这个词的意思。
我们可以通过Python库来访问WordNet,看看它具体是什么样子的。
让jupter-notebook使用conda的虚拟环境:conda install nb_conda
通过nltk访问wordnet之前,需要执行nltk.download(‘wordnet’)去下载对应的数据。
from nltk.corpus import wordnet as wn
poses = { 'n':'noun', 'v':'verb', 's':'adj (s)', 'a':'adj', 'r':'adv'}
for synset in wn.synsets("good"):
print("{}: {}".format(poses[synset.pos()],
", ".join([l.name() for l in synset.lemmas()])))
同义词集效果如下:
from nltk.corpus import wordnet as wn
panda = wn.synset("panda.n.01")
hyper = lambda s: s.hypernyms()
list(panda.closure(hyper))
上位词效果如下:
NLTK:Natural Language Toolkit,自然语言处理工具包,在NLP领域中,最常使用的一个Python库。
$WordNet$作为资源库很好,但是有一些缺点:
- 缺少语义差别,如上面实验的”proficient”被列为“good”的同义词,只是在某些场景下是可行的。
- 缺少新词或者词的新含义,需要不断的去更新。
- 主观的,是通过建立者的主观意识创建的。
- 需要人类劳动来创造和调整。
- 无法计算单词相似度。
独热编码(one-hot)
在传统的自然语言处理中,我们把词语看作离散的符号: hotel, conference, motel - a localist representation。单词可以通过独热向量(one-hot vectors,只有一个1,其余均为0的稀疏向量)。
- 当语料库也就是词库的单词个数过大时,one-hot 编码的词向量的维度也会很大。
- 由于one-hot 编码都是由0-1组成,并且只有表示该词的位置是1,其余位置都是0,所以过于稀疏。
- 并且用one-hot 编码的词之间都是正交的(两个词向量的内积为0),所以无法表示两个词的相关性。
通过上下文表示词
分布式语义:一个单词的意思是由经常出现在它附近的单词给出的。
这个很容易理解,一个词实际所表达的意思往往取决于它所在的句子。有点物以类聚,人以群分的感觉。这个概念被称为现代统计$NLP$最成功的理念之一,所以才有了后来的$Word2Vec$词嵌入框架。
当一个单词$w$出现在文本中时,它的上下文$context$是出现在其附近的一组单词(在一个固定大小的窗口$Window$中)。在大量的语料库中,词$w$会出现在不同的语句中,所以也就有了许多不同的上下文$context$。我们可以通过这些$context$去得到该词的有效表示。
词向量(Word Vector)
词向量也叫词的表示(word representations)或者词嵌入(word embeddings),它是一种分布式表示。上文说的独热和通过上下文表示都属于分布式表示,但是独热编码的方式是稀疏的高纬的,而通过上下文表示得到的向量是低纬度的稠密的(dense)。我们希望在相似的$context$下的$word vector$也较为相似。
词向量在NLP中非常重要,一个训练好的词向量模型,可以很好的表达出词与词之间的关系。使得可以很好的进行下游任务的处理,有助于提高模型的性能和准确率。
Word2Vec
Word2vec introduction
$Word2Vec(Mikolov et al. 2013)$是一个学习词向量的框架,通过模型将自然语言的单词映射到n维空间中,这个n就是词向量的维度。在该空间中,语义相近的词向量位置相对比较接近。
它的主要思路是:
- 我们有大量的语料文本 (corpus means ‘body’ in Latin. 复数为corpora)。
- 固定词汇表中的每个单词都由一个向量表示。
- 文本中的每个位置$t$,其中有一个中心词$c$和上下文$context$单词$o$。
- 使用$c$和$o$的词向量的相似性来计算给定$c$的$o$的概率$P(o|c)$(反之亦然)。
- 不断调整词向量来最大化这个概率。
下图为窗口大小$j=2$时的$P(w_t+j|w_t)$计算过程,center word分别为$into$和$banking$。
当我们扫到下一个位置时,banking就成为center word。
Word2vec objective function
对于每个位置$t=1,\dots,T$,其中$T$为一句话中单词的个数。在大小为$m$的固定窗口$Window$内预测上下文单词,给定中心词$w_j$。
目标函数$J(\theta)$也叫代价函数或者损失函数。上述公式中求乘的方式最后得到一个非常小的值,因为每个概率$P$都是小于1大于0的小数,通过不断相乘(我们知道小于1的小数乘以一个小于1的小数会比这两个小数值更小)最后得到一个非常小的小数。所以我们通常会转为求对数,也就是在上述公式的两边加上$Log$,其中右边就可以转化为对数求和的形式。同时根据凸优化理论,我们将求最大化转为求最小化,变形后的目标函数为(平均)负对数似然:
Softmax
在这里对于每个单词$w$使用两个向量:
- $v_w$当$w$是中心词的时候。
- $u_w$当$w$是上下文词的时候。
然后对于一个中心词$c$和一个上下文词$o$的概率$P$:
两个向量内积的几何含义是什么
定义:两个向量a与b的内积为 a·b = |a||b|cos∠(a, b),特别地,0·a =a·0 = 0;若a,b是非零向量,则a与b正交的充要条件是a·b = 0。
分子中加上$exp$指数,一是为了防止内积为负数,二是为了使得内积大的概率值更大,内积小的概率值更小。
分母中对整个词汇进行归一化以给出概率分布,其中$V$是整个词汇表中单词的个数。
上述的内容就是一个$softmax$函数的应用例子。
- max :因为放大了最大的概率。
- soft :因为仍然为较小的$x_i$赋予了一定概率。
- $softmax$通常用于深度学习中。
Training a model by optimizing parameters
有了目标函数,我们就可以通过梯度下降法来优化参数$\theta$,在这里$\theta$就是我们的词向量,也就是模型中所有的参数。比如,我们有$V$个单词,每个单词取$d$维度。那么$\theta$可以表示为:
要记住的是这里每个单词都有两个向量作为中心词时的$v_w$和作为上下文词时的$u_w$。在训练时首先要随机初始化两个向量,通过梯度下降法不断更新向量,最后取平均值来表示该词的词向量。
Word2vec objective function gradients
储备知识
现在我们来求解目标函数的梯度,这需要用到一些高等数学和线性代数的知识。
- 求偏导数
- 对数的导数求法
- 指数的导数求法
- 链式求导法则
Calculating all gradients
根据求导法则偏导数可以移进求和中:
先求中心词$v_c$的偏导:
这里的$word2vec$算法又被叫做Skip-Gram model,还有另一种$word2vec$算法是Continuous Bag of Words,简称$CBOW$,它们的原理区别是Skip-Gram是求context word相对于center word的条件概率,也就是知道通过中心词求上下文词。而$CBOW$是求center相对于context word的条件概率,也就是通过上下文词求中心词。其他方面基本类似。
加快训练的$trick$有负采样(Negative sampling)和层次$Softmax$。
推荐阅读
论文阅读《Efficient Estimation of Word Representations in Vector Space》
论文阅读《Distributed Representations of Words and Phrases and their Compositionality》