![31185b7f2f4c39373b29adba989b38a8.png](https://i-blog.csdnimg.cn/blog_migrate/ea08cc76e28f232d0d212f9680cd4851.jpeg)
word2vec模型的原理
注:本篇笔记来源于对某学院NLP视频课程的梳理。
0.背景
对于一个词语,如果可以用向量的方式来表述,在数学上进行优化就会非常方便,这种方式就叫做词向量的方式。传统的词向量方法是one-hot encoding(独热编码)。
假设有一个词库
那么,基于这个词库
相应地,对于句子
这样的表述方式,虽然可以进行数学处理,但是仍有不少非常明显的缺点:
- 这是一种Sparse Representation,向量空间太稀疏,太多的零向量,十分占用内存
- 这种表示方法难以衡量词与词之间的距离和相似性,无法表达词语的含义
- 词库的大小即是词向量的维度大小,无法用低维度表达更多的词语,表达能力差
由于one-hot方法缺点太多,distributed representation(分布式表达)就应运而生了。这里先不讲分布式表达具体是什么个样子,先讲一下分布式是怎么来的。分布式表达的核心思路是克服one-hot的缺点,所以相对one-hot来说,我们希望分布式表达是稠密的(Dense),具有语义的(Semantic),且表达能力高(即维度不高也能表达多个不同的词语)。
one-hot的方法之所以缺点多,是因为它把单词的意义用1来表示,且仅仅只着落在一个单独的维度上。而分布式的表达则不然,它会把单词的意义分布在不同的维度上。从语言学的角度来说,一个词的含义其实就是用其他词来表示的。所以分布式的表达也更加符合语言学的逻辑。
另外,就如何生成词向量来说,one-hot方法是从词库出发,直接把一个词映射成由0和1组成的向量,每一个词只考虑自己在词库的位置,所在位置为1,其他位置为0,也就是说,这个词语的生成仅仅考虑了自己的局部情况,完全没有考虑自己与其他词语的关系,我们把这个生成的模式叫做local generalization(局部泛化)。而分布式的方式则是global generalization(全局泛化),什么叫全局泛化呢?意思就是说,每一个词的生成都考虑了与其他词的关系。举个例子,用一大堆的积木可以搭建成不同的玩具,如小猫小狗这样的,如果说我们的语料库是木头,那么我们就要把木头处理成积木,这个积木就是中间参数,然后每一个词的词向量就像是用积木搭建的玩具,也就是参数的不同表达,这些玩具虽然不同,但是都是积木搭建的,也就是说,虽然每个词的词向量是不一样的,但是他们都是用相同的参数表达出来的,这就叫parameter sharing。
综上来说,one-hot和distributed representation存在4个最大的区别:
| --------- | one-hot | distributed representation |
| 向量空间 | sparse | dense |
| 语言意义 | 无语义 | 有语义 |
| 表达能力 | 有限 | 无限 |
| 生成方式 | local generalization | global generalization |
1.word2vec的思路
我们已经知道了分布式表达的概念,那么如何才能从语句从得到一个词的分布式词向量呢?我们需要做的,首先是找到词语之间的数学上的关系。我们可以先思考一下,对于一句话中的单词,一般来说,离得近的单词,它们的相似度会大一些,而离得远一点的单词,它们的相似度会低一点。基于这个假设,我们可以用两种不同的思路来进行具体的表达。第一个思路是,用一个句子中的某一个单词,去预测它前后有可能出现的单词;第二个思路是把第一个思路反过来,即是用中心单词附近的单词,来预测中心单词。
学习词向量的两种模式就是基于上述两个思路来的。用中心词预测上下文词语,叫做skip-gram模型,而用上下文词语预测中心词,叫做cbow模型。直观来看,用中心词预测上下文词语的难度会更大一点,因为一个词预测多个词比起多个词预测一个词而言,缺失的信息会更多一些。所以,如果skip-gram模型一旦训练成功,这个模型效果通常是好于cbow的,因为这个模型完成了更艰难的任务。从某种意义来说,是由于这个模型内部挖掘到了更多的隐藏信息。
2.构造目标函数
在有了具体思路以后,我们就要着手于构建目标函数了。以skip-gram模型为例,对于一句话而言,假设
对于这个条件概率
由于存在累乘,很自然的可以想到将其取对数化变成累加,所以有:
显然,我们只要找到能够使得目标函数最大化的$theta$,就能得到想要的词向量。
3.条件概率的具体形式
目标函数构建好之后,我们需要找到
在
我们知道目标函数
未知的地方在于
我们可以考虑用同样的形式来表示
然后,又考虑到两个点,第一是希望当
综合以上考虑,可以把条件概率表述为:
所以目标函数可以写成:
进一步化简:
得出这个无法再化简的目标函数后,很自然地可以想到用随机梯度下降的优化方向去找到最优的
一般有两种方法可以进行优化求解:
- Negative Sampling,不必遍历整个词库,只需要随机采用一些负样本即可
- Hierarchical Softmax,构建二叉树遍历,间接避免遍历整个词库
4.构建条件概率条件的另一种思路
可以看出,其实
我们的思路是,给定词
4.1 Sigmoid二分类
所以用sigmoid函数来进行表述,即
那么相应地,我们的目标函数可以写成:
这里
所以目标函数可以写为:
再取对数,可得:
这里要注意的是:
当词库变大时,非上下文词对会变得非常大,为了降低计算量,需要对负样本
4.2 新目标函数及其最优化
所以目标函数可以更新为:
其中
有个这个目标函数以后,我们可以尝试着用梯度下降的方法去寻找最优参数
可以设
将
总结一下
当目标函数收敛或者是迭代到一定阈值范围时,停止参数更新,即可得到最后的词向量~
5.简略评估词向量是否可用
基于给定的一个词库,当我们用word2vec模型将词向量训练出来以后,我们还需要检查一下词向量是否可用。所谓是否可以用,其实就是想看一下词向量能否把词语的意义在数学的角度上表述完备。一般来说,有以下三种方法:
- 将词向量的维度降低到二维进行可视化,观察词与词之间的距离与意义是否匹配。
- 查看两个词语之间的相似性,或者查看某个词相似度最高的词。(可以与人工标记的相似度做对比)
- 同类比较,观察同义词之间的距离是否合理。比如women和man的距离与girl和boy的距离差距是否大。
6. Word2vec实战
https://github.com/QuantumDriver/NLP-4th-Assignment/blob/master/Lesson-04/Assignment.ipynbgithub.com文本建模后,用词向量进行可视化,效果如下:
![735e88b029ec24e2044c1215a6ba37e5.png](https://i-blog.csdnimg.cn/blog_migrate/b1218eff7c4c8c6d8e76eb9720191dab.jpeg)
![aaadc54bbad73c0c2ca02a26c3331702.png](https://i-blog.csdnimg.cn/blog_migrate/5f09691c82285bda67e7ac1bfa5fceeb.jpeg)
![1e8ebc461e2d8956793b4b9cff301a07.png](https://i-blog.csdnimg.cn/blog_migrate/799f74f1210118fc59befb46c271f917.jpeg)