Lecture 2 主要介绍了传统的共现矩阵生成词向量方法和迭代生成词向量的方法,例如word2vec和Glove。
文章目录
Word Vectors
人类对“词义”定义为通过一个词或者短语表示的意思,人想要通过词表达的意思,写作、艺术表达的意思。
计算机定义“词义”,通常是使用WordNet之类的分类方法,比如说,具有is-a关系、代名词集合。例如,“panda” is-a “animal”,“panda” is-a “vertebrate”,“good”的代名词集合有“full”,“expert”等。
首先,介绍一个可以说是最简单的词向量:
one-hot vector
one-hot向量就是将每个词表达为一个大小为|V|*1的向量,其中词所在的位置为1,其他位置全为0。|V|表示词典的大小。
这种表示方法存在的问题有:
- 丢失了词词之间的细小的差别
- 无法处理新词
- 带有主观性
- 需要人力实现
- 很难精确计算词之间的相似性
现在,一个很成功的统计NLP想法就是,通过邻域词(上下文)来表达词的信息。
怎样通过上下文表达词呢?答案是,共现矩阵。
共现矩阵
生成共现矩阵有两种方法:整篇文档和滑动窗口。
-
整篇文档
根据文档生成大小为|V|*M的共现矩阵,第 i 行第 j 列表示词 i 在文档 j 中出现的次数。这种方法会由主题引申到“潜语义分析”。很明显,随着文档数量M的增加,矩阵大小也在增加。
-
滑动窗口
使用滑动窗口能够同时捕获到句法(POS)和语义信息。
生成的共现矩阵是对称的,对角线上元素为0,矩阵大小为n*n,n表示词的个数。
共现矩阵存在的问题
在Google级别的公司处理NLP任务,词的个数会达到百万级别,这就导致了共现矩阵具有很高的维度,需要更大的存储空间。而在后续的分类等任务中,也会存在着矩阵稀疏的问题,导致模型的鲁棒性很差。
解决方法:使用低纬度的向量来存储词的大部分信息,也叫“密集向量”,通常大小为25~1000。怎样降低共现矩阵的维度呢?
接下来介绍两种方法:SVD-Based和 Iteration-Based。
SVD
对共现矩阵X应用SVD(Singular Value Decomposition)奇异值分解。奇异值分解适用于任意大小的矩阵。对于大小为n*m的矩阵X,奇异值分解为:
X = U S V T X=USV^T X=USVT
其中,U的大小n*n,每列向量是正交的,成为左奇异向量;S的大小n*m,对角线上为奇异值,按照从大到小排列,除对角线外其他元素都是0;V的大小为m*m,列向量也是正交的,成为右奇异向量。奇异值表征的是特征向量的重要性。
复习一下SVD的求解过程:
- ( X T X ) v i = λ i v i (X^TX)v_i = \lambda_iv_i (XTX)vi=λivi
- σ i = λ i \sigma_i = \sqrt{\lambda_i} σi=λi
- u i = 1 σ i X v i u_i = \frac{1}{\sigma_i}Xv_i ui=σi1Xvi
通常,前10%~1%的奇异值的和就占了全部的奇异值之和的99%以上,所以,经常用部分奇异值分类来近似矩阵X。得到的分解公式:
python可以通过调用numpy实现SVD:
import numpy as np
la = np.linalg
words = [“I”,”like”,”enjoy”,”deep”,”learning”,”NLP”,”flying”,”.”]
X = np.array([0,2,1,0,0,0,0,0],
[2,0,0,1,0,1,0,0],
[1,0,0,0,0,0,1,0],
[0,1,0,0,1,0,0,0],
[0,0,0,1,0,0,0,1],
[0,1,0,0,0,0,0,1],
[0,0,1,0,0,0,0,1],
[0,0,0,0,1,1,1,0])
U, s, vh = la.svd(X, full_matrices=False)
对于出现频率很高的词,例如“the”“she”“has”等,对X有很大的影响,所以经常采用几种补救方法:
- 设置词频阈值,高于阈值用阈值取代
- 忽略这些无意义的高频词
- 滑动窗口使用斜坡窗口,即越靠近中心词,计数越多,远离中心词的词计数减少
- 使用皮尔逊系数代替计数统计,将小于0的皮尔逊系数设置为0。
SVD存在的问题
- 计算复杂度高,当n*m大小的共现矩阵,耗费 O ( m n 2 ) O(mn^2) O(mn2)的复杂度
- 对新词或者新文档难处理
SVD缺点的解决办法存在很多,与本课程和深度学习相关的主要有以下:
- Learning representations by back-propagating errors.(Rumelhart et al., 1986)
- A neural probabilistic language model (Bengio et al ., 2003)
- NLP from scratch (Collobert & Weston, 2008)
- A recent and even simpler model: word2vec (Mikolov et al., 2013)
word2vec
word2vec就是接下来我们要介绍的重点。
word2vec的主要思想是:对每个词,预测周围可能出现的词,而不是计算共现矩阵。这样,对于新词、新出现的句子和文档,也可以快速及时处理。
对于大小为c的窗口,预测目标词的上下文可能出现的词,目标函数为:
J ( θ ) = 1 T ∑ t = 1 T ∑ − c ≤ j ≤ c , j ≠ 0 l o g p ( w t + j ∣ w t ) J(\theta) = \frac{1}{T}\sum_{t=1}^T\sum_{-c\leq{j}\leq{c},j \neq0}logp(w_{t+j}|w_t) J(θ)=T1t=1∑T−c≤j≤c,j̸=0∑logp(wt+j∣wt)
即,最大化给定中心词的任意上下文词的概率。对于 p ( w t + j ∣ w t ) p(w_{t+j}|w_t) p(wt+j∣wt)最简单的公式为:
p ( w O ∣ w I ) = e x p ( u O T v I ) ∑ w = 1 W e x p ( u w T v I ) p(w_O|w_I)=\frac{exp(u_{O}^Tv_{I})}{\sum_{w=1}^{W}exp(u_w^Tv_{I})} p(wO∣wI)=∑w=1Wexp(uwTvI)exp(uOTvI)
就是softmax函数形式,其中 u u u 和 v v v 分别表示词的输入向量和输出向量(每个词都有两个向量,这点很重要!)
想要优化目标函数,我们需要对公式求导求梯度,在推导的过程中,有两个知识点需要掌握:
- 矩阵求导 ∂ X T a ∂ X = ∂ a T X ∂ X = a \frac{\partial{X^Ta}}{\partial{X}} = \frac{\partial{a^TX}}{\partial{X}} = a ∂X∂XTa=∂X∂aTX=a
- 链式法则 d y d x = d y d u d u d x \frac{dy}{dx} = \frac{dy}{du}\frac{du}{dx} dxdy=dudydxdu
对概率p进行求导:
∂ p ( o ∣ c ) ∂ v c = ∂ ∂ v c l o g ( e x p ( u o T v c ) ∑ w = 1 W e x p ( u w T v c ) ) \frac{\partial{p(o|c)}}{\partial{v_c}} = \frac{\partial}{\partial{v_c}}log(\frac{exp(u_o^Tv_c)}{\sum_{w=1}^{W}exp(u_w^Tv_c)}) ∂vc∂p(o∣c)=∂vc∂log(∑w=1Wexp(uwTvc)exp(uoTvc