前言
最近又系统的学习了一遍词向量的一些基础知识,巩固了基础知识的同时又有了一些新的收货,在此想记录下学习过程中的笔记,写的不好的地方请见谅,如有错误欢迎指正
一 语言模型
首先我们回顾一些基础的知识与概念,什么是语言模型呢?语言模型就是用来预测句子在语言中出现的概率(比如机器翻译),假设一门语言中所有的可能的句子都服从某个概率分布,每个句子出现的概率加起来为1,语言模型的任务预测每个句子在语言中的概率。传统的语言模型只会预测句子出现的概率而不会理解句子的含义,没法告诉我们两句话的意思是否相似。
语言模型的计算:
eg: 我 今天 下午 打 羽毛球
如果使用语言模型计算这句话的概率
其中S为句子,W表示其中的单词,P(S)被称为语言模型,用来计算一个句子是句子的概率的模型,简单的看就是一个联合概率的计算。
如果直接对上式计算有2个缺点,一是数据过于稀疏;二是参数空间大(由数据稀疏导致);为了解决这两个问题我们使用N-gram模型。
二 N-gram模型
为了解决上文中提到了数据稀疏以及参数空间大的问题,我们基于马尔科夫的假设(类似齐次马尔可夫假设):下一个词的出现依赖于它前面的一个或几个词(通常我们说话的过程中的词只与前几个词相关),减少参数空间。
假设下一个词的出现依赖它前面的一个词,则有:
假设下一个词的出现依赖它前面的两个词,则有:
n-gram模型:假设当前词的出现的概率只与它前面的N-1个词有关,n=1是我们称为unigram,n=2时叫做bigram,n=3时叫做trigram。
如何选择n:
更大的n:对下一个词出现的约束信息更多,具有更大的辨别力。
更小的n:在训练语料库出现的次数更多,具有更可靠的统计信息,具有更高的可靠性。
构造语言模型:最大似然估计
Count(X)在训练语料库单词序列X在训练语料中出现的次数。有些序列在实际训练中不会出现,我们使用平滑处理防止概率相乘为0。
三 词向量简介
One-hot representation: 独热向量编码,对应词位置为1,其它为0,比较简单就不多介绍了。
one-hot向量的缺点:1.语义鸿沟的问题,意思相近的词计算相似度(比如余弦相似度)为0;
2.维数灾难、稀疏,向量中大多数列为0,消耗计算资源;
3.无法表示未出现的词汇;
分布式表示:通过训练将每个词(one-hot形式)映射成K维的实数向量,通过余弦相似度、欧式判断他们之间的相似度。词向量的表示的核心,利用上下文信息进行词的表示,与语言的表现形式无关。
如何训练词向量:并没有直接的模型可以训练得到分布式表示的词向量,可以通过训练语言模型的同时得到词向量,为了选择摸个某个模型刻画目标词汇与上下文的关系,我们需要在词向量中抓取到一个词的上下文信息,所以构建上下文与目标词汇的关系,最自然的方式就是使用语言模型。
如何使用语言模型训练得到词向量呢?
我们可以使用NNLM、RNNLM、CBOW和Skip-gram,下面我们来分别介绍一下这几个模型。
四 训练词向量使用的语言模型
1.NNLM(神经网络语言模型)
我们使用N-gram模型时,当N取值大时,参数会比较稀疏,参数空间大,计算成本昂贵。我们采用新思路使用模型参数化的方式构造语言模型去完成这个事情,我们不在记住所有的概率,而是用一组参数去描述这个事情,这样真正需要计算概率的时候只需要把所有的词喂给模型,过一遍神经网络就能拿到这样一个概率,所以2003年提出了NNLM神经网络语言模型(w2v的前身),从语言模型触发将模型最优化问题转化为词向量求解的过程。
目标函数:
根据前n-1个单词,预测第t个位置单词的概率
使用了非对称的前向窗函数,窗的长度为n-1
滑动窗口便利整个语料库求和,计算量正比于语料库的大小
概率P满足归一化(一般使用softmax)条件,这样不同位置t处的概率才能相加及即:
模型结构图:
我们来简单介绍一下模型的结构,上述模型其中模型的输入在训练的过程中使用词的ont-hot向量(假设维度为V,V为词表大小)与我们随机初始化的一个投影矩阵C(在训练过程中会不断更新,假设维度为D)相乘,假设输入为3个词经过映射得到3个词向量维度为D,然后NNLM会将它们拼接成一个3D维的向量然后经过一个hidden layer(隐层)做全连接(神经元的数量由用户自己定义在这里我们假设为H),再接上一个输出层(神经元的数量等于V,词表的大小),再做softmax归一化处理。从结构上来看还是很简单的,模型的每个训练样本的计算复杂Q:
其中N为输入的单词数
2 RNNLM(循环神经网络语言模型)
基于循环神经网络的语言模型,所以具有RNN的特性,我们可以充分使用上下文的信息预测单词
结构图
结构简介:w(t)表示第t个时刻的当前输入单词,维度假设为V,V是词典大小,one-hot表示。
s(t-1)代表隐层的前一次输出
y(t)表示模型输出
计算复杂度:
H为隐层的神经元数
缺点:RNNLM在形式上看起来不错,但是因为使用了RNN实际难以优化(梯度消失、梯度爆炸等),优化不好导致会丢失长距离的信息,只能记住短距离的信息,效果可能不如其他模型。
接下来我们介绍一下CBOW与Skip-gram看它们解决了一些什么问题
3 CBOW连续词袋模型
Continuous Bag of Words,连续词袋模型,即利用中心词(Wt)的上下文(context)来预测中心词(Wt)
结构图:
目标函数:
特点:
没有隐层
训练过程中使用双向上下文窗口
上下文词序无关(BOW)
输入层直接使用低纬稠密向量表示
投影层简化为求和平均
模型结构介绍:
CBOW可以描述为简化版的神经网络语言模型,计算流程,输入上下文单词one-hot表示,然后经过投影矩阵映射为词向量加起来求平均,再经过一个全连接层维度为词表大小,在再通过softmax输出每个词的概率;计算复杂度:, D为投影矩阵维度, N为输入单词数,其中V我们可以通过分层softmax方法优化到对数级别为
可以看出来计算复杂度以及参数数量相较于神经网络语言模型减少的很多
4 Skip-gram
跳字模型,是根据中心词(Wt)来预测周围的词,即预测上下文(context)。
结构图:
目标函数
输出层:只含当前样本的中心词w的词向量
投影层:恒等投影,为了和CBOW模型对比
输出层: 和CBOW模型一样
相比于NNLM,CBOW和Skip-gram使用较少的计算代价就可以获得质量更高的词向量;
但是CBOW和Skip-gram也有自己的缺点:
一是对每个局部上下文窗口单独训练,没有利用包含在全局的共现矩阵中的统计信息;而是对多义词无法很好的表示和处理,因为使用了唯一的词向量; 解决方案Glove:利用全局信息编码词向量,这个我们本文不做讨论。接下来我们来研究一下2个常用的优化计算的方法层次softmax以及负采样。
五 计算优化方法
1. hierarchical-softmax(层次softmax)
一般输出层计算单词的概率的计算复杂度为O(V),V为词表的大小,我们可以使用二叉树结构来减少计算量。我们可以把常规的softmax当做一个深度只有1,叶子节点为V的树, 计算每一个单词softmax的概率, 需要标准化所有的V个叶子节点,如果我们使用二叉树来代替这个结构(叶子节点为单词),我们只需要随着路径来找到相应的单词,不需要考虑其他的叶子节点;又因为一个标准的二叉树的深度为所以我们最多只需要计算个节点的来得到最后的单词的概率,需要注意的是这里的概率已经被标准化过了,所有叶子节点的概率相加为1, 因为在二叉树分裂到最后没有概率丢失,所以相加为1。更具体一点来说就是我们穿过树时,我们需要计算出每个节点向左或者向右时的概率,因此我们为每个节点分配一个向量分布表示,相较于普通的softmax我们不再有为每一个单词的输出embadding ,反而我们为每一个节点生成一个唯一的向量分布表示,层次softmax的参数数量与普通的softmax差不多。
我们定义给定节点n,以及上下文c的条件下节点向左(或向右)的概率为:
这里的计算与常规softmax中的计算相同;相比于普通softmax上下文向量与整个输出词汇向量做点积输出所有词的概率,现在计算的是h与每个节点之间的点积,最后只会输出一个概率,其中h为输入上下文的向量,相反的节点王座的概率为:
图例:
cat词的概率为节点1向左的概率、节点2向右的概率以及节点5向右的概率乘积。
显然,树的结构很重要,实际上我们可以使用符号来索引每个几点,假设0为向左转,1为向右转,比如上图中的cat可以用011来表示,balanced 二叉树的路径长度为,假设V=10000,则平均路径长度为13.3。在信息论中,我们可以用13.3来表示每个字的位数。
这里引入信息内容函数, 为概率的负对数
熵 H为语料库里所有单词的信息增益:
假设一棵平衡二叉树,V =10000, 所有叶子节点的概率都相同
我们可以使用熵来作为每个单词的平均编码位数
树的结构很重要,我们可以根据所有单词的信息增益来编码我们的树结构,我们可以将信息量较少的单词采用较短的路径。也可以使用单词的概率,由于某些单词比其他单词更有可能出现(比如“the”),因此也可以采用较短的路径来加快计算。
简单总结一下层次softmax与常规softmax的不同点:
1.输出层节点采用二叉树结构,减少了计算的次数;
2.只输出一个概率,常规softmax输出所有概率;
3.常规softmax是将上下文向量与V个(V为词表大小)输出词向量相乘,层次softmax是将上下文向量与V-1个节点连接相乘
2.负采样
Negative Sampling也是一种生成词向量的高效方法,我们使用Skip-gram模型举例,它优化的是另一个不同的目标函数;
我们假设是一对单词还有上下文,
是这对数据属于训练数据里的正确的样本的概率,
相反的 是这对数据为负样本(即不属于这个训练数据里的)的概率
我们假设有个参数控制着他们的概率分布:
我们的目标是找到参数 最大化所有训练样本属于训练集的概率:
的概率我们可以使用sigmoid函数这样定义:
其中为上下文对应的输入词向量(在skip-gram中就是中心词通过one-hot映射得到的低纬词向量),为输出层该词对应的输出词向量
得到最终公式为:
这个公式有一个小问题就是,我们可以通过设置参数使得.这个是很容易实现的我们可以设置对于所有的,当K足够大时概率就接近1了,事实上当K约等于40时,概率就已经接近1了。
所以我们需要一种技巧来防止所有的向量的值相同,比如可以禁止一些(w,c)的组合出现。有一种方法就是给模型提供一些(w,c)组合它们的非常小,比如提供一些(w,c)组合没有在训练数据里面出现的,把它们全部假设为负样本(negative sampling的名字来源于此,给模型提供一个负样本数据集通过随机采样获取)所以我们的目标函数变为以下形式:
其中数据D'为负样本样本集合,D为正样本集合
假设我们让 可以得到:
我们需要通过调整参数来最大化这个概率
我们采样一个正样本,一般会采样K个负样本有,negative sampling最关键的地方在于反向传播时它更新的过程,相比于常规的更新所有词汇集,负采样只会更新,这个集合上的词对应的参数,词汇量的大小变小了。所以大大减少了计算量。
参考文章
1.EfficientEstimationofWordRepresentationsin VectorSpace CBOW和Skip-gram经典论文
2.word2vec Explained: Deriving Mikolov et al.’s Negative-Sampling Word-Embedding Method 这篇论文详细讲了negative sampling