cs224n 第二课:词向量表示 word2vec

作者:deta 
时间:2018/07/26 

1、计算机中怎样表达每个词的含义了?

在英文中,一般用WordNet等分类资源来处理词义,啥意思了?就像我们查中华字典一样,查熊猫的解释是:有胎盘的、活的、哺乳类动物, 通过这样一种 is-a 的关系来处理词义,自己可以装上nltk包跑下课程上的代码:

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

这种离散的表征方式存在一些问题,会遗漏一些词之间的信息,大量的基于规则和统计型NLP的工作都是将单词作为原子(最小)符号,用向量空间表示的话就是一个 one-hot 向量,命中某个单词的得向量位置为1,其他为都是0,但是这种方法有很多缺点:

  • 词汇表一般维度都很高
  • 不能体现 相似词语之间的相关性,就比如通过one-hot 表示的 hotel h o t e l motel m o t e l 是正交的

这里写图片描述


另外一种思路就是通过每个词在语料文本中的分布相似性来代表某个单词,可以通过生成一个稠密向量表示单词来预测这个词在语料库中的上下文。通过神经网络获得词嵌入向量的具体做法是通过定义一个模型,通过最大化给定中心词的条件下出现语料中上下文的概率或者最小化损失函数:

p(context|wt)=... p ( c o n t e x t | w t ) = . . .

损失函数可以表示:

J=1p(wt|wt) J = 1 − p ( w − t | w t )

其中 wt w − t 表示中心词所有的上下文。对于概率分不到额损失函数一般会问到 交叉熵损失(为什么用交叉熵?常见的损失函数有哪些?有什么优缺点? )

2、word2vec

两个算法:

  • Skip-grams :给定目标中心词预测上下文
  • CBOW(连续词袋模型) : 通过上下文预测目标中心词

两种训练方式:

  • Hierarchical softmax
  • Negative sampling

详细的算法数学原理可以参考这个博客:点我

Skip-gram:

通过中心词来预测上下文

这里写图片描述

具体的算法细节:

对于词汇表中的每个单词 t=1...T t = 1... T ,预测窗口大小为m的每个上下文单词,目标函数我们可以定义为最大化在给定中心词的情况下上下文出现的概率:

J(θ)=t=1Tmjmj0P(wt+j|wt;θ) J ′ ( θ ) = ∏ t = 1 T ∏ − m ≤ j ≤ m j ≠ 0 P ( w t + j | w t ; θ )

取负的对数似然:

J(θ)=1Tt=1Tmjmj0logP(wt+j|wt;θ) J ( θ ) = − 1 T ∑ t = 1 T ∑ − m ≤ j ≤ m j ≠ 0 l o g P ( w t + j | w t ; θ )

对于 p(wt+j|wt) p ( w t + j | w t )

p(o|c)=exp(uTovc)Vw=1exp(uTwvc) p ( o | c ) = e x p ( u o T v c ) ∑ w = 1 V e x p ( u w T v c )

其中:

uTv=u.v=i=1muivi u T v = u . v = ∑ i = 1 m u i v i

o o c分别代表词汇表的下标位置,分母中的 V V 代表词汇表的大小,最开始训练模型的时候都会将嵌入矩阵进行随机初始化,vc uo u o 表示中心词和外围词的向量表示,这样最终训练出来每个单词有两个不同的向量表示,这样会让训练更简单一些。


下图是skipgram 训练流程:

  • 通过输入one-hot向量
  • 在最开始随机初始化输入嵌入矩阵中look up 找到对应的词向量
  • 将词向量与外围嵌入矩阵 W W ′ 相乘得到一个 V×1 V × 1 的向量
  • 经过一个 softmax
  • 通过与实际语料的上下文one-hot 结果偏差优化

这里写图片描述
其中模型的所有的参数集 θ θ ,每个单词都有两个词向量,通过优化损失函数去获得最终的词向量表示:

这里写图片描述

通过梯度下降最小化损失函数,不断去优化更新词向量:

这里写图片描述
通过对 vc v c 求偏导后发现,上式中的第2项通过计算上下文中可能出现的每一个单词的概率来得到一个期望向量,它是所有可能的上下文向量的平均,用它们出现的似然值来加权,通过不断调节模型中的向量值来使它们相等。对其他上下文向量也通过同样的方式来优化。


为了最小化损失函数,在语料中的所有窗口计算一次梯度进行更新:

θnew=θoldαθJ(θ) θ n e w = θ o l d − α ▽ θ J ( θ )

while True:
    theta_grad = evaluate_gradient(J,corpus,theta)
    theta = theta - alpha * theta_grad

在实际应用中,一样数据量会很大,所以不会每次处理完所有的语料之后进行一次梯度下降,而是会采用随机梯度下降的方式,在对没个窗口进行一次计算后来更新参数:

θnew=θoldαθJt(θ) θ n e w = θ o l d − α ▽ θ J t ( θ )

while True:
    theta_grad = evaluate_gradient(J,window,theta)
    theta = theta - alpha * theta_grad
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值