最近博客开的分支有点多,PRML、RL、TensorFlow,现在又开一个NLP,有点忙不过来了。主要是组内最近开了RL和NLP两个方向,而我都需要跟进,当然NLP不是我的主要方向,因此写博客我也就写得简略一些。
学习的主要的参考材料是Stanford的公开课程。
Cooccurrence Matrix
Word vectors的主要思想,是用在文档中某个词附近出现的词来表示这个词(也就是说,如果两个词,它们在语料中附近出现的词都差不多,那么它们的语义应该也差不多)。
我们设置一个window size,然后就可以用cooccurrence matrix来用一个词周围出现的词来表示它。所谓的window size,即对于当前这个词,前后多少个词属于在它的周围。
给定一个较小的语料库:
I like deep learning.
I like NLP.
I enjoy flying.
设定window size为1,即只考虑前后一个单词。
可以得到cooccurrence matrix:
counts I like enjoy deep learning NLP flying . I 0 2 1 0 0 0 0 0 like 2 0 0 1 0 1 0 0 enjoy 1 0 0 0 0 0 1 0 deep 0 1 0 0 1 0 0 0 learning 0 0 0 1 0 0 0 1 NLP 0 1 0 0 0 0 0 1 flying 0 0 1 0 0 0 0 1 . 0 0 0 0 1 1 1 0
Singular Value Decomposition (SVD)
得到了cooccurrence matrix其实我们就已经得到了最初的vector,每一个单词都可以用cooccurrence matrix中的一行向量来表示。但是,cooccurrence matrix是一个稀疏矩阵,不仅占用的空间大,而且所表示的特征不明显。因此我们考虑降维,直接可以想到的是奇异值分解SVD(关于SVD的计算过程不在这里细讲,可以参考相关书籍,我可能会在之后写一个博客讲吧)。
图1 SVD
如图1,SVD将一个n*m的矩阵分解为三个矩阵相乘,其中S只有在对角线上的元素非0,如果调整行列顺序,将S中的元素从大到小排序,然后保留前k个,就保留了原矩阵的主要特征,同时将秩从r压缩到了k,起到了降维的作用。
我们用 U^ 中的每一行来表示一个词。对于上一节的例子,我们取k=2,并将单词的vector可视化表示,如图2。
图2 word vectors可视化
可以看出,已经初步有一些效果,NLP与deep靠得很近。当然这个语料库太小了,效果还不明显:(
Word2Vec
当然,前面两节得到的vector还不是我们真正要讲的。这一节才真正开始讲我们的word2vec。SVD方法很好,但主要的问题是,每当我们新增一个词,或者有新的语料,SVD都需要重新跑一遍,而对于一个n*m的矩阵,跑一遍SVD的时间复杂度是O(mn2)的(n<m)。
于是,我们的想法是,能不能直接从语料中学习得到vector。
这里就直接给出我们的目标方程,给定一个中心词,我们希望最大化它上下文中出现的词的概率:
其中 θ 表示我们需要优化的所有变量,T表示整个文档单词个数,m表示window size, wt+j 即上下文中的词, wt 是中心词。
这里最关键的就是,怎么定义上下文出现的词的概率,最简单的一种表示:
其中,o是外部词,c是中心词,每个词用两个向量表示,当它作为中心词时使用v,作为外部词时使用u。(实际上,这就成了一个动态逻辑回归问题。)最终我们得到的向量,可以是v和u的平均值。
Some Math
在求解这个问题之前,我们先了解一下涉及到的一些简单的数学。
gradient descent
对于最小化问题,我们可以使用梯度下降的方式求极值,得到一个局部最优解,如果最小化的目标函数是凸的,那得到的局部最优解就是全局最优解。
我们以一元的函数为例,一元函数的梯度就是导数。设
f(x)=x4−3x3+2
,它的导数为
f′(x)=4x3−9x2
。我们用伪代码来表明梯度下降的计算过程。
x0=0,x1=6,θ=0.00001,ε=0.01
while(|x1−x0|>θ)
x0=x1
x1=x0−ε×f′(x0)
printx1,f(x1)
其中, θ 是求解的精度, ε 是每一步调整的大小。梯度下降就是先任意取一个初始的x,然后沿着梯度方向调整,直到最终取到极值(因为极值的地方函数值变化小,所以可以用 θ 来判断)。为什么采用梯度方向,是因为梯度方向函数的变化最大,越容易接近极值点。
Useful basics
∂xTa∂x=∂aTx∂x=∂∑ixiai∂x=[d∑ixiaidxj]=[a1a2⋯ad]=a
dydx=dydududx
optimal vc
给定window size和外部词对应的向量u,我们来推导一下一个中心词 vc 的梯度下降,由于是对window size内的外部词求和,因此主要就是求 logp(o∣c) 的偏导:
∂J(θ)∂vc=∂∂vc⎛⎝1T∑t=1T∑−m≤j≤m,j≠0logp(wt+j∣wt)⎞⎠=1T∑t=1T∑−m≤j≤m,j≠0∂∂vclogp(wt+j∣wt)
∂logp(o∣c)∂vc=∂∂vc(uoTvc−log∑w=1Wexp(uwTvc))=uo−∂∂vclog∑w=1Wexp(uwTvc)=uo−1∑Ww=1exp(uwTvc)∂∂vc∑x=1Wexp(uxTvc)=uo−1∑Ww=1exp(uwTvc)∑x=1W∂∂vcexp(uxTvc)=uo−1∑Ww=1exp(uwTvc)∑x=1Wexp(uxTvc)∂∂vcuxTvc=uo−1∑Ww=1exp(uwTvc)∑x=1Wexp(uxTvc)ux=uo−∑x=1Wexp(uxTvc)∑Ww=1exp(uwTvc)ux=uo−∑x=1Wp(x∣c)ux
Next Blog
当然,word2vec到这里还没有完,我的博客主要按照课程的进度写,下一篇将继续讲word2vec。