RNN虽然可以解决长期记忆问题,但是还有一个问题没有解决.自然语言不仅和前后语境相关,单词本身也后很多含义.比如说下面几个词:
苹果 香蕉 科学家 农民
我们可以很容易发现苹果和香蕉是一类,因为他们都是水果.而科学家和农民是一类,因为他们都是人.
但是在RNN不能发现这些关系,RNN训练时单词是以one-hot编码的形式输入的,无法计算两个单词的距离,所以,无法从one-hot编码中找出哪些词是相似的.
为了解决这个问题就出现了单词嵌入,英文为Word Embeddings.Embedding在数学上表示一个maping, 也就是一个function,该函数能将单词映射到另一个空间,映射后保留原有的结构,比如在X所属的空间上X1 < X2,那么映射后在Y所属空间上同理 Y1 < Y2,在新的空间中我们可以计算两个单词向量直接的距离,从而明确单词之间的关系.
举个例子,我们会把单词映射到一个新的空间,这个空间有年龄,甜度,口感,教育程度,平均工资这几个纬度:
苹果 | 香蕉 | 科学家 | 农民 | |
---|---|---|---|---|
年龄 | -1 | -2 | 43 | 30 |
甜度 | 5 | 6 | 0.1 | 0.2 |
口感 | 10 | 15 | -1.2 | -2 |
教育程度 | 2 | 3 | 150 | 50 |
平均工资 | -0.2 | -0.1 | 50000 | 20000 |
于是,Embedding后单词的向量为:
现在,我们就通过向量间的距离找出相关关系.
单词嵌入就是用一个向量代表一个词,这个向量会包含这个词的所代表的信息。
我们要建立一个语言模型,这个模型的目的是预测一段话中下一个词出现的概率:
I want a glass of orange ____.
首先通过矩阵E与单词One-hot编码相乘计算出每个单词的单词嵌入向量:
接下来把这些单词嵌入向量输入到一个神经网络中,最后通过softmax输入下一个单词的概率.
接下来迭代模型:
模型的中E为模型的参数,是所有单词的单词嵌入所组成的矩阵.事实证明这种方法能学习到非常合理的单词嵌入,因为当数据量非常大时,通常会得到非常类似的话,比如说下面两句:
单词预测的结果都是juice,但前面一个词是orange,另一个词为apple.这就会促使模型调整orange与apple的单词嵌入非常相近,最终达到在单词嵌入空间中物以类聚的效果.
还可以从另一个角度来理解单词嵌入,训练的过程一直用一个向量去代替一个词,这么做久了,这个向量当然能很好的代替这个词了。
后来人们发现,我们不需要整个句子来训练模型,仅适用目标词附近的词就可以取得不错的效果,这就是Word2Vec算法.
Word2Vec是目前最常用的词嵌入模型之一,它2013年google提出来的.Word2Vec是一种浅层神经网络模型,有两种网络结构,分别是CBOW与Skip-gram.
CBOW的目标是根据上下文出现的词语来预测当前词的生成概率;而Skip-gram是根据当前词来预测上下文中各词的生成概率.他们的网络结构都是一样的:
CBOW的输入层输入附近的词,每个词用N维One-hot表示,输出为N个词出现的概率;Skip-gram输入的是N个词出现的概率,来预测附近的词.所以他们正好是相反的,互为镜像.
在第一层网络会生出一个维的参数,在第二层网络会生成一个维的参数.可以选择其中一个作为N个单词的K维词向量.
单词嵌入的另一个好处就是,它可以使每个单词的词向量变短,如果是词袋模型,每个词向量的长度为,既单词的总个数,这样向量太长了.使用单词嵌入可以把维的词向量映射到维,这样可以大大减小词向量的维度.
Word2Vec有一个缺点,当单词数量K非常大时Softmax的计算非常慢:
负采用法采用多个二分类代替Softmax,这样每次预测只需计算一个二分类即可.还是以juice为目标词为例,对juice附近的词,标记为正样本,然后从词典里随机抽取几个与juice完全不相关的词作为负样本,如下:
x1 | x2 | y |
---|---|---|
orange | juice | 1 |
king | juice | 0 |
sky | juice | 0 |
使用上述数据训练逻辑回归二分类,可以得:
使用K个逻辑回归可以代替逻辑回归代替Softma计算P(t|c).重要的是每次迭代只需更新一个逻辑回归就可以了,效率很快.
GloVe是一个更为简洁的单词嵌入算法,全称为global vectors for word representation .
通过上面的算法可以看出来,单词嵌入向量与其在目标词附近出现的频率直接相关,GloVe算法直接将词向量与词频建立关系:
其中为单词i在单词j附近出现的频率., 是主词和上下文词的常数偏倚.通俗点讲,假设单词a与单词b在单词c附近出现的频率相近,那么单词a与单词b的单词嵌入就相近,反之假设单词a与单词b在单词c附近出现的频率相差很远,那么这两个单词的单词嵌入差距也很大.
因为与是相等的,所以公式相当于:
于是定义损失函数:
是权重,为了处理停用词,以及为0的情况.
参考:
https://www.coursera.org/learn/nlp-sequence-models
https://cndocr.github.io/text2vec-doc-cn/glove.html