在本堂课中,其基础技能需要懂得并应用:Ipython,numpy和Pytorch。其他的关于自然语言处理和深度学习,上了这堂课,你就会了解。
语言,语言是传递信息的声音和文字,是人类沟通的主要方式(其他方式包括图像、触感等)。它作为人类文明的载体,距今已有5000多年的历史。如此古老的本领,在历史的长河之中,没有出现质的改变(功能没有改变,方式没有改变)。
在信息和信息传播活动,人类历史中共有五次巨大变革:
第一次:语言的诞生,是历史上最伟大的信息技术革命,语言使人类描述信息、交流信息的方式得到了大大的改进.
第二次:文字的诞生,为了便于交流和长期存储信息,就要创造一些符号代表语言,这些符号经过相当长的一段时间后逐渐演变成文字,并固定下来.
第三次:印刷术的诞生,使得知识可以大量生产、存储和流通,进一步扩大了信息交流的范围.
第四次:电磁波的应用,电磁波的应用使得信息传递的速度大大提高.
第五次:计算机技术的应用,使人们对信息的处理能力、处理速度产生了飞跃.
然而,当今自然语言(人类使用的语言,包含以上第一次、第二次革命的结果),相较于当今5G的网络传播速度(第五次革命),是相当的缓慢,但是仍然被我们人类广泛使用,那这是为什么?这是因为语言虽然说的东西少,但是听的内容多。这其中的信息增益,来源于对于世界的认知。
所谓的意思(Meaning)指两个方面,一方面是单词本身的意思(Representation for words),另一方面是使用单词想要表达的意思(Express by using words)。例如,我渴了。句子本身是说我缺少水分,而另一个含义是,你需要给我倒杯水。这是使用这句话想要表达的意思。
从语言学角度来说,文字等价于符号(signifier),也就是符号化所要表示的意思(signified the idea thing)。从这个角度讲,符号学派的理论就自然站得住脚。
基于符号理论,一个比较著名的应用是WordNet,NLTK工具包中包含这个应用,它将单词之间的关系描述为同义词和上位词(synonym set and hypernyms), 也就是什么是什么的关系。这样就能够很好的解决不同符号所表示的不同含义及其之间的关系。在中文中,也存在同样的工具(知网,即HowNet),不是大家所熟知的论文检索网站。
这样,WordNet就可以获得层次化的单词间的关系,但是同样存在以下几个问题:
在文本表示上,如上所讲,已经有一定的方法,接下来需要解决的是如何进行语言间的运算(计算机要做的事)。
传统的自然语言处理(NLP)方式中,将单词看作为离散的符号(discrete symbols),就像一个词典一样,一个词对应一个编号,更一般的,使用独热(One-Hot)编码的形式。这样,符号就可以转换为数值进行运算。
同样的,该种方法同样存在一些问题,例如,词汇表太大,英文词汇超过50万个。不能够计算相似度(一种方法是使用wordnet,另一种方法就想去学习一种基于向量的表示方式)
那么,如何去基于单词向量本身学习呢?在1957年,一种理论提出:词汇的含义来源于其上下文(word’s means is given by it’s context)。跟随着这个思路,从神经语言模型(2003)到Word2Vec(2013)的道路就都说的通了。
神经网络模型的目的是,将单词进行分布式表示,即把词映射到一个向量空间中,使得相似的词拥有相似的位置。Word2Vec模型具有以下特点:
下面就是“硬核”Word2Vec的推导过程。
我们使用Skip-Gram模型举例说明,
首先,Word2Vec同样使用极大似然估计,就像我们上面所说,它需要使得给定中心词,使得上下文词出现概率最大,即:
L ( θ ) = ∏ P ( w t + i ∣ w t ; θ ) L(\theta)=\prod P(w_{t+i}|w_t;\theta) L(θ)=∏P(wt+i∣wt;θ)
为了更容易计算,我们设计的目标函数如下:
J ( θ ) = − 1 T l o g L ( θ ) = − 1 T ∑ t = 1 T ∑ − m ≤ j ≤ m l o g P ( w t + i ∣ w t ; θ ) J(\theta)=-\frac{1}{T}logL(\theta)=-\frac{1}{T}\sum^{T}_{t=1}\sum_{-m\le j\le m }logP(w_{t+i}|w_t;\theta) J(θ)=−T1logL(θ)=−T1t=1∑T−m≤j≤m∑logP(wt+i∣wt;θ)
最小化目标函数就是最大化似然函数,自然就是最大化准确率。
这就自然而然的就引出计算问题,如何计算 P ( w t + i ∣ w t ; θ ) P(w_{t+i}|w_t;\theta) P(wt+i∣wt;θ)?
我们曾经遇到的极大似然估计,大部分都是用频率来近似概率获得其P,这里并不能这样。
我们定义 v w v_w vw是中心词的词向量, u w u_w uw是上下文的词向量,也就是说,其实同一个词,即有作为中心词的时候的词向量,也有作为上下文时的词向量。这样做只是为了后面更好的计算和操作,使用单个向量也是能够解决这个问题。
于是,我们的概率计算公式就为:
P ( o ∣ c ) = e x p ( u o T v c ) ∑ w ∈ V e x p ( u w T v c ) P(o|c)=\frac{exp(u_o^Tv_c)}{\sum_{w \in V}exp(u_w^Tv_c)} P(o∣c)=∑w∈Vexp(uwTvc)exp(uoTvc)
其中o表示目标词,V表示词表。其含义为,上面为两个词的矩阵的乘积最大,下面为正则项。这就有点像softmax函数一样。此处,我们先穿插一点,可以看到,其实这种计算方法就是使得越共现的词,向量乘积越大,乘积越大,则概率越大。最终会实现和某一个词的相关词和其都相似,就使得这些相关词向量更加相似。
另一个问题是,我们这里所谓的 θ \theta θ是谁?答案是 v c v_c vc,即我们是对其求 v c v_c vc的偏导,首先我们先写出我们目标函数:
∂ ∂ v c l o g P ( o ∣ c ) = ∂ ∂ v c l o g e x p ( u o T v c ) ∑ w ∈ V e x p ( u w T v c ) \frac{\partial }{\partial v_c}logP(o|c)=\frac{\partial }{\partial v_c}log\frac{exp(u_o^Tv_c)}{\sum_{w \in V}exp(u_w^Tv_c)} ∂vc∂logP(o∣c)=∂vc∂log∑w∈Vexp(uwTvc)exp(uoTvc)
= ∂ ∂ v c l o g e x p ( u o T v c ) − ∂ ∂ v c l o g ∑ w ∈ V e x p ( u w T v c ) =\frac{\partial }{\partial v_c}logexp(u_o^Tv_c)-\frac{\partial }{\partial v_c}log{\sum_{w \in V}exp(u_w^Tv_c)} =∂vc∂logexp(uoTvc)−∂vc∂logw∈V∑exp(uwTvc)
此时我们可以分开计算被减数和减数的偏导
∂ ∂ v c l o g e x p ( u o T v c ) = u o \frac{\partial }{\partial v_c}logexp(u_o^Tv_c)=u_o ∂vc∂logexp(uoTvc)=uo
∂ ∂ v c l o g ∑ w ∈ V e x p ( u w T v c ) = ∑ x ∈ V e x p ( u x T v c ) u x ∑ w ∈ V e x p ( u w T v c ) \frac{\partial }{\partial v_c}log{\sum_{w \in V}exp(u_w^Tv_c)}=\frac{\sum_{x \in V}exp(u_x^Tv_c) u_x}{\sum_{w \in V}exp(u_w^Tv_c)} ∂vc∂logw∈V∑exp(uwTvc)=∑w∈Vexp(uwTvc)∑x∈Vexp(uxTvc)ux
因此最终的目标函数为:
∂ ∂ v c l o g P ( o ∣ c ) = u o − ∑ x ∈ V e x p ( u x T v c ) u x ∑ w ∈ V e x p ( u w T v c ) \frac{\partial }{\partial v_c}logP(o|c)=u_o-\frac{\sum_{x \in V}exp(u_x^Tv_c) u_x}{\sum_{w \in V}exp(u_w^Tv_c)} ∂vc∂logP(o∣c)=uo−∑w∈Vexp(uwTvc)∑x∈Vexp(uxTvc)ux
= u o − ∑ x ∈ V e x p ( u x T v c ) u x ∑ w ∈ V e x p ( u w T v c ) =u_o-\sum_{x \in V}\frac{exp(u_x^Tv_c) u_x}{\sum_{w \in V}exp(u_w^Tv_c)} =uo−x∈V∑∑w∈Vexp(uwTvc)exp(uxTvc)ux
= u o − ∑ x ∈ V P ( x ∣ c ) u x =u_o-\sum_{x \in V}P(x|c)u_x =uo−x∈V∑P(x∣c)ux
这样就是可以计算的了,更新 θ \theta θ时的方法如下,但是所有的参数很多,想直接更新会计算非常复杂。
θ n e w = θ o l d − α ▽ θ J ( θ ) \theta^{new}=\theta^{old}-\alpha \bigtriangledown_{\theta}J(\theta) θnew=θold−α▽θJ(θ)
解决方法是,我们采样一个窗口内的单词来更新,并不更新所有的单词。
在SG模型中的负采样方法则如下:
J n e g − s a m p l e = − l o g ( σ ( u o T v c ) ) − ∑ k − 1 K l o g ( σ ( − u k T v c ) ) J_{neg-sample}=-log(\sigma(u_o^{T}v_c))-\sum_{k-1}^{K}log(\sigma(-u_k^Tv_c)) Jneg−sample=−log(σ(uoTvc))−k−1∑Klog(σ(−ukTvc))
其中K为我们采样的单词,根据单词采样概率获得,其单词采样概率计算方法如下,这样可以使得概率更小的单词更会被采样:
P ( w ) = U ( w ) 3 4 Z P(w)=\frac{U(w)^{\frac{3}{4}}}{Z} P(w)=ZU(w)43
至此我们的SG模型就已经讲述完毕了。
从以上我们可以看出,为什么不直接使用词共现矩阵来做这个事情呢?这个下节课会讲到。