作者: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 是正交的
另外一种思路就是通过每个词在语料文本中的分布相似性来代表某个单词,可以通过生成一个稠密向量表示单词来预测这个词在语料库中的上下文。通过神经网络获得词嵌入向量的具体做法是通过定义一个模型,通过最大化给定中心词的条件下出现语料中上下文的概率或者最小化损失函数:
损失函数可以表示:
其中 w−t w − t 表示中心词所有的上下文。对于概率分不到额损失函数一般会问到 交叉熵损失(为什么用交叉熵?常见的损失函数有哪些?有什么优缺点? )
2、word2vec
两个算法:
- Skip-grams :给定目标中心词预测上下文
- CBOW(连续词袋模型) : 通过上下文预测目标中心词
两种训练方式:
- Hierarchical softmax
- Negative sampling
详细的算法数学原理可以参考这个博客:点我
Skip-gram:
通过中心词来预测上下文
具体的算法细节:
对于词汇表中的每个单词 t=1...T t = 1... T ,预测窗口大小为m的每个上下文单词,目标函数我们可以定义为最大化在给定中心词的情况下上下文出现的概率:
取负的对数似然:
对于 p(wt+j|wt) p ( w t + j | w t ) :
其中:
o o 和分别代表词汇表的下标位置,分母中的 V V 代表词汇表的大小,最开始训练模型的时候都会将嵌入矩阵进行随机初始化,和 uo u o 表示中心词和外围词的向量表示,这样最终训练出来每个单词有两个不同的向量表示,这样会让训练更简单一些。
下图是skipgram 训练流程:
- 通过输入one-hot向量
- 在最开始随机初始化输入嵌入矩阵中look up 找到对应的词向量
- 将词向量与外围嵌入矩阵 W′ W ′ 相乘得到一个 V×1 V × 1 的向量
- 经过一个 softmax层
- 通过与实际语料的上下文one-hot 结果偏差优化
其中模型的所有的参数集
θ
θ
,每个单词都有两个词向量,通过优化损失函数去获得最终的词向量表示:
通过梯度下降最小化损失函数,不断去优化更新词向量:
通过对
vc
v
c
求偏导后发现,上式中的第2项通过计算上下文中可能出现的每一个单词的概率来得到一个期望向量,它是所有可能的上下文向量的平均,用它们出现的似然值来加权,通过不断调节模型中的向量值来使它们相等。对其他上下文向量也通过同样的方式来优化。
为了最小化损失函数,在语料中的所有窗口计算一次梯度进行更新:
while True:
theta_grad = evaluate_gradient(J,corpus,theta)
theta = theta - alpha * theta_grad
在实际应用中,一样数据量会很大,所以不会每次处理完所有的语料之后进行一次梯度下降,而是会采用随机梯度下降的方式,在对没个窗口进行一次计算后来更新参数:
while True:
theta_grad = evaluate_gradient(J,window,theta)
theta = theta - alpha * theta_grad