Word2vec

word2vec是一种将word转为向量的方法,其包含两种算法,分别是skip-gramCBOW,它们的最大区别是skip-gram是通过中心词去预测中心词周围的词,而CBOW是通过周围的词去预测中心词

这个word2vec的方法是在2013年的论文《Efficient Estimation of Word Representations in Vector Space》中提出的,作者来自google,文章下载链接:https://arxiv.org/pdf/1301.3781.pdf

文章提出了这两种方法如下图所示:

在处理自然语言时,通常将词语或者字做向量化,例如独热编码,例如我们有一句话为:“我爱中国北京”,我们分词后对其进行独热编码,结果可以是:

“我”: 【1,0,0,0】

“爱”:【0,1,0,0】

“中国”: 【0,0,1,0】

“北京”: 【0,0,0,1】

但是独热编码在大量数据的情况下会出现维度灾难,通过观察我们可以知道上面的独热编码例子中,如果不同的词语不是4个而是n个,则独热编码的向量维度为1*n,也就是说,任何一个词的独热编码中,有一位为1,其他n-1位为0,这会导致数据非常稀疏(0特别多,1很少),存储开销也很大(n很大的情况下)

那有什么办法可以解决这个问题呢?

于是,分布式表示被提出来了。什么是分布式表示?

它的思路是通过训练,将每个词都映射到一个较短的词向量上来。这个较短的词向量维度是多大呢?这个一般需要我们在训练时自己来指定。现在很常见的例如300维。

例如下面图展示了四个不同的单词,可以用一个可变化的维度长度表示(图中只画出了前4维),其实可以是多少维由你指定。假设为4维。

大家如果细心,会发现在展示的这些维度中的数字已经不是1和0了,而是一些其他的浮点数。

这种将高维度的词表示转换为低维度的词表示的方法,我们称之为词嵌入(word embedding)。

上图是将一个3维词向量表示转为2维词向量表示。

有个有意思的发现是,当我们使用词嵌入后,词之间可以存在一些关系,例如:

king的词向量减去man的词向量,再加上woman的词向量会等于queen的词向量!

出现这种神奇现象的原因是,我们使用的分布式表示的词向量包含有词语上下文信息。

怎么理解上下文信息呢?

其实很简单,我们在上学时,做阅读理解经常会提到联系上下文,所谓的上下文信息无非是当前内容在文本中前后的其他内容信息。

如下图所示,learning这个词的上下文信息可以是它左右两边的content标记的内容。

试想一下,如果这里的learning换成studying,是不是这句话仍然很合适呢?毕竟这两个单词都是学习的意思。

再转换一下思维,由于在当前上下文信息中,learning和studying都可以出现,是不是learning和studying是近义词了呢?没错,在当前的CBOW下确实是这样,甚至man和woman,cat和dog都可能是近义词

其实就是拥有相似或者相同的上下文的多个词可能是近义词或者同义词。

CBOW

这里慢慢将CBOW的算法思想透露出来了,因为CBOW就是通过当前中心词的上下文单词信息预测当前中心词。

首先我们需要训练CBOW模型,该模型的结构如下图:

这张图略微复杂,我们需要从最左边开始看,最左边的一列是当前词的上下文词语,例如当前词的前两个词和后两个词,一共4个上下文词。

这些上下文词即为图中的x1k、x2k。。。xck。

这些词是独热编码表示,维度为1*V(虽然图上画得像列向量V*1,这图画的容易理解错误,其中V为词空间的大小,也就是有多少个不同的词,则独热编码的维度为多少,也就是V个不同的词)。

然后刚说的每个上下文的词向量都需要乘以一个共享的矩阵W,由于整个模型是一个神经网络结构,我们将这个存在于输入层和隐藏层之间的矩阵称为W1,该矩阵的维度为V*N,其中V如前所述,N为我们自己定义的一个维度。

学过线性代数的矩阵乘法我们知道,这里的独热编码向量1*V乘上维度为V*N的矩阵W1,结果是1*N的向量。

这里因为一个中心词会有多个上下文词,而每个上下文词都会计算得到一个1*N向量,我们将这些上下文词的1*N向量相加取平均,得到中间层(隐藏层)的向量,这个向量也为1*N,之后,这个向量需要乘以一个N*V的矩阵W2,最终得到的输出层维度为1*V。

然后将1*V的向量softmax归一化处理得到新的1*V向量,在V个取值中概率值最大的数字对应的位置所表示的词就是预测结果。如果对softmax的概念陌生,可以搜索学习一下。

而这个输出的结果1*V就是预测出的中心词的分布式表示。

别急,我们只是讲通了这个CBOW模型的前向计算过程。

我们接下来说说模型的训练过程。

(1)当前词的上下文词语的独热编码输入到输入层。

(2)这些词分别乘以同一个矩阵W1后分别得到各自的1*N向量。(这里的隐藏层相当于embedding)

(3)将这些1*N向量取平均为一个1*N向量。(这里其实相当于使用了GlobalAveragePooling1D)

(4)将这个1*N向量乘矩阵W2,变成一个1*V向量。

(5)将1*V向量softmax归一化后输出取每个词的概率向量1*V。

(6)将概率值最大的数对应的词作为预测词。

(7)将预测的结果1*V向量和真实标签1*V向量(真实标签中的V个值中有一个是1,其他是0)计算误差,一般是交叉熵

(8)在每次前向传播之后反向传播误差,不断调整W1和W2矩阵的值。

预测的时候,做一次前向传播即可得到预测的中心词结果。

你可能会想,word2vec不是要将词转为分布式表示的词嵌入么?怎么变成预测中心词了?

这个问题问得好!其实我们在做CBOW时,最终要的是W1这个V*N矩阵,想想这是为什么呢?

因为我们是要将词转换为分布式表示的词嵌入,我们先将词进行独热编码,每个词的向量表示是1*V的,经过乘以W1后,根据矩阵乘法的理解,假设1*V向量中第n位是1,其他是0,则矩阵乘法结果是得到了W1矩阵中的第n行结果,也就是将词表示为了一个1*N的向量,一般N远小于V,这也就将长度为V的独热编码稀疏词向量表示转为了稠密的长度为N的词向量表示。

如果还没啥感觉,看下面这张图帮助你理解:

所以,当我们下次要查某个词的词向量时,只需要和矩阵W1相乘就能得到结果。常用的词向量长度有300,大家想想300是不是远小于我们词表里所有不重复词的数量呢?

Skip-gram

Skip-gram用于预测与给定中心词相对应的上下文词。它和连续词袋模型(CBOW)算法相反。在Skip-gram中,中心词是输入词(input word),上下文词是输出词(output word)。因为要预测多个上下文词,所以这一过程比较困难。

给定 “sat” 一词后,鉴于sat位于0位,我们会尝试在 -1 位上预测单词 “cat” ,在3位上预测单词 “mat” 。我们不预测常用词和停用词,比如 “the”。

  1. 架构

上图中,w(t)就是中心词,也叫给定输入词。其中有一个隐藏层,它执行权重矩阵和输入向量w(t)之间的点积运算。隐藏层中不使用激活函数。现在,隐藏层中的点积运算结果被传递到输出层。输出层计算隐藏层输出向量和输出层权重矩阵之间的点积。然后用softmax激活函数来计算在给定上下文位置中,单词出现在w(t)上下文中的概率。

  1. 使用到的变量

1.在数据库或文本中出现的特殊单词的汇总词典。这个词典就叫做词汇量,是系统的已知词。词汇量用字母“v”来表示。

2.“N”代表隐藏层中神经元的数量

3.窗口大小就是预测单词的最大的上下文位置。“c” 代表窗口大小。比如,在给定的架构图中窗口大小为2,因此,我们会在 (t-2), (t-1), (t+1) 和 (t+2) 的上下文位置中预测单词。

4.上下文窗口是指会在给定词的范围内出现的、要预测的单词数量。上下文窗口值窗口大小的两倍。给定图像的上下文窗口值是4。

5.输入向量的维度等于|V|。每个单词都要进行one-hot编码。

6.隐藏层的权重矩阵(W)的维度是[|V|, N]。“||” 是把数组值还原的模函数。

7.隐藏层的输出向量是H[N]。

8.隐藏层和输出层之间的权重矩阵 (W’) 维度是[N,|V|]。

9.W’和H之间的点积生成输出向量U[|v|]。

  1. 工作步骤

1. 利用one-hot编码将单词转换为向量,这些向量的维度是 [1,|v|]。

2. 单词w(t)从|V|神经元被传递到隐藏层。

3. 隐藏层执行权重向量W[|v|, N] 和输入向量w(t)之间的点积运算。这里,我们可以总结出:第(t)行的W[|v|, N] 会输出(H[1, N])。

4. 谨记:隐藏层不使用激活函数,所以H[1,k] 会直接传递到输出层。

5. 输出层会执行H[1, N]和W’[N, |v|]之间的点积运算,并给出向量U。

6. 现在,要得出每个向量的概率,我们要使用softmax函数,因为每次迭代都得出输出向量U,这是一种one-hot编码模式。

7. 概率最大的那个单词就是最终结果。如果在指定上下文位置中预测的单词是错误的,我们会使用反向传播算法来修正权重向量W和W’。

以上步骤对字典中的每个单词w(t) 都要执行。而且,每个单词w(t) 会被传递2c次。所以我们可以得知,正向传播算法在每段时间内会执行 |v|*2c次。

如何做一对多的训练?
a.使用softmax多分类

我们将通过“喂养”在训练文档中找到的“单词对”(word pair)来训练神经网络。下面的例子显示了一些训练样本(单词对),句子为“The quick brown fox jumps over the lazy dog.”,窗口大小为2,蓝色突出显示的是输入单词。输入输出都是one-hot向量

b.优化——将softmax改进成n个二分类的逻辑回归分类器

:该方法在原作者的第二篇论文中提出:Distributed Representations of Words and Phrases and their Compositionality

可以将softmax改进成n个二分类的逻辑回归分类器,即把词匹配的方法改进。

若like和apple是来自第一个句子的滑动窗口里面的,称为正样本(有效配对) 。当第一个句子中eat和I配对时,为负样本,因为skip-window=1,即滑动窗口大小为1。负样本是随机的,是采样才出来的,一般为1个正样本配上5个负样本。(①表示单词来自第一个句子,②表示单词来自第二个句子)

模型如何放进网络里面训练,又如何产生结果?

①将eat的one-hot编码放入input(这里假设eat是1000个词里的第256个,apple是第200个,banana是第400个)

②隐藏层简记为e(嵌入向量),将每一行记为

③使用sigmoid函数

④一般是1个正样本+5个负样本组成一对X,Y

⑤只更新这个6个即可

  1. 概率函数

w(c, j) 是在第c个上下文位置上预测的第j个单词;w(O, c)是在第c个上下文位置上出现的实际单词;w(I)是唯一的输入词;u(c, j)是在第c个上下文位置上预测单词时,U向量的第j个值。

  1. 损失函数

由于我们想在第c个上下文位置预测w(c, j) 时实现概率最大化,可以使用损失函数L。

  1. 优势

1.Skip-gram是一种无监督学习技术,因此它可以用于任何原始文本。

2.相比于其他单词转向量表达法,Skip-gram需要的记忆更少。

3.它只需要两个维度为[N, |v|]而不是[|v|, |v|]的权重矩阵。而且通常情况下,N约为300,|v| 则约为数百万。

  1. 劣势

1.找到N和c的最佳值很困难。

2.Softmax函数计算耗费的时间很长。

3.训练这个算法耗时较长。

算法耗时的原因

经过ŷ的softmax计算得到ŷ',ŷ'与y相减(左图)进行反向传播的计算,在隐藏层时,隐藏层数为300,需要乘以一个普通的权重矩阵,还原回1000层,在这期间,计算量很大,隐藏层的每一层都需要和权重矩阵的每一行进行乘积并相加(右图红框部分),得到ŷ一个神经元的输出。

计算次数:

①右图中权重矩阵每一行乘以隐藏层每一列,权重矩阵共1000行,所以需要进行1000次计算。

②左图中ŷ转化为ŷ'需要进行1000次计算。

简单来看,总共需要2000次计算,这是一个输入和输出的组合,如下图,若有4个输入输出组合,则需要进行4X2000次计算,导致计算量过大。

注:https://www.cnblogs.com/jfdwd/p/11082536.html可以参考如何负采样

  1. 改进

作者在第二篇论文中对skip-gram进行了改进

  1. Hierarchical Softmax: 使用二叉树来记录词表中所有的词,避免softmax时需要遍历词表中所有的词,时间复杂度由O(V)变为O(log2(V))。具体做法是将所有词放在树的叶子节点上,每个非叶子结点节点也有自己的词向量表示不同层上的类别,每个叶子节点的概率是从根节点到该叶子节点的路径上记录的概率之积。这样softmax变成了二分类问题,假设用用平衡二叉树来进行分类,则条件概率估计可以转换为log2∣V∣个二分类问题。由于词的出现频率不同,使出现频率高的离根节点更近,出现频率低的离根节点越远,能有效的降低计算开销,这样便形成了哈夫曼树

  1. Negative Sampling:负采样也是为了降低softmax计算的复杂度,和原来通过所有单词计算softmax不同,现在只计算窗口内单词(正例)和随机抽的k个窗口外单词(负例)。本质上也是把softmax变成了sigmoid分类问题,将多分类转化为二分类问题。

  1. Subsampling of frequent words:对于有些频繁出现的单词比如the等实际对前后词的影响非常小,对训练帮助也非常小,所以在训练中随机抛弃一些高频词,不仅能增加训练的速度,还能提升模型的效果

  1. Learning Phrases:将单词组合成的phrase当成一个token(一个word)来看。这里基于共现统计发现phrase:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值