word2vec原理和难点介绍

前言

本文仅作一个备忘录,不详细说明word2vec的两种词袋模型(skip-gram和CBOW),后面的记录默认是在skip-gram的基础下完成,即是利用中心词来预测上下文;同时也不涉及数学的推导计算,仅是做一些我认为比较重要的知识纪要。

word2vec是什么?

word2vec通常是一种进行文本的向量提取的技术,利用单词的共现(共同出现,后续会有详细记录)思想,通过对文本语料库进行训练,得到的每个单词的向量,最后可以通过向量来计算单词的相似性,或者说是共现概率。

是有监督还是无监督?

word2vec可以说是无监督,因为他全程并不需要我们去标定label,label是内部自己生成和判定的(那这个label如何产生呢?这就是下一个问题会介绍)

输入的数据是什么、是以什么形式输入?

对模型进行训练,当然要有训练的data,那data是什么?或者说输入的特征数据是什么?以下面这句话为例
The cat is very cute.
word2vec是直接一次将这句话输入到模型中吗?显然不是,倘若我们指定的滑窗大小是1,则产生的语料是:

当以cat为中心词:the cat is
当以is 为中心词:cat is very
当以very为中心词:is very cute
注:以上并为考虑去除停用词,只是做一个简单的举例

当以cat为中心词时,得到了语料是‘the cat is’,但是要留意,并不是就是把这个都一次性输入到模型中,最开始我们提到了word2vec是利用了单词的共现思想,这个共现其实就是在这里得以体现,模型输入的是:
the cat 1
cat is 1
这里的the cat表示,他们一起在滑窗中出现,这就是共现,后面的1就是label,表示一起出现的概率,这就是在无监督学习中label的产生方式,当然label为1的是正样本。

那负样本是什么呢,负样本就是以cat为中心词时,未出现在滑窗中的所有词和中心词的组合,比如 cat very 就是负样本,label应该为0,cat cute也是负样本。
当然这里有个问题:就是,语料库是非常大的,当我们进行样本获取的时候,如果语料库是10w,这时候,滑窗内的词是正样本,滑窗外的都是负样本,那每一次滑窗移动,负样本都会非常大。这显然是效率很低,甚至不利于训练,该怎么处理
这就是后续word2vec优化中的其中一步。

word2vec的参数是什么?

在模型训练中,word2vec是一个神经网络,那它最终的参数是代表着什么呢,它是什么样子的形式呢?
在word2vec训练过程中,它的参数其实最终就是两个矩阵,这里将这两个矩阵分别叫做A,B。每一行就是一个单词的向量表示,那这里有个疑问:为啥是两个参数矩阵,这里做一个朴素的理解
这里面的A、B矩阵都有所有词的向量,但是他们又不太相同,比如cat在A矩阵中有个对应的向量参数(也就是矩阵的一行),同样在B中也有一行,为什么会这样,可以理解为,A矩阵里的cat对应的那一行向量(也就是参数)
当cat作为中心词时会对其进行更新的和学习的,B矩阵里的cat对应的那一行向量(也就是参数)当cat作为非中心词时会对其进行更新的和学习的。这是不一样的。
当然又会有疑问:最终训练出的模型中,我们要采用哪一个矩阵里的参数作为单词的embedding向量呢?
其实这是个开放的问题,你可以是其中任意一个矩阵,也可以两个相加的平局,或者在平均时给每一个矩阵附加一个权值。

word2vec的整个计算过程

结合上面的介绍对整个流程做一个介绍,首先依旧是以:the cat is very cute做为例子。
1.以滑窗移动获得语料(滑窗大小我们定义为1)
the cat is
cat is very
is very cute

当以cat为中心词时,获得正样本
the cat label为1
cat is label为1
cat very label为0

假如举例the cat ,首先将the和cat的one-hot输入到模型中,然后会分别取到A矩阵下对应的一行向量(就是矩阵的一行参数),表示着这俩单词的向量,然后将这两行向量进行相乘,得到一个数,最后对相乘得到的数进行softmax,得到的概率,就是以cat为中心词时,预测the的概率,
这时候如果预测的概率是0.42,那这里的真实的label是1,所以就可以设定loss = y-y^ = 1.0.42,然后依据sgd等优化方法,更新A矩阵里的对应的cat的向量,那the的向量需要更新吗?需要的啦,只是它是在B矩阵里更新了,为啥会这样呢?
其实理解的时候可以先不用管the,我们看cat,这时候的cat更新的是A矩阵,那何时更新B矩阵呢?是在cat不作为中心词的时候进行更新,也就好比这里的the,这里的the就更新的是B矩阵,但是当the作为中心词时,它就会来更新A矩阵,这样两个都训练到了。

优化篇

问题提出

回顾以上的步骤讲解,有两个地方明显的会让我们的训练模型的时候有阻碍

问题1:负样本太多

问题描述:
当以cat为中心词时,the cat is 是滑窗内的正样本,但是如果此时语料库中有10w个单词,那除了the和is之外,其他的单词和cat的组合全部都为负样本,你想这才只是仅以cat为中心词时的负样本就这么多,全部滑窗循环下来,负样本将无比巨大

问题后果:
负样本太多,会导致训练样本失衡,同时负样本太多会导致数据量太大难以训练、以及训练模型有偏。

问题解决:
既然负样本太多,最直观的减少负样本的解决方法不就是少取一点嘛,这里提出的一个负采样,其实就是抽样的取负样本,不全部取,而是取部分,这很好理解。

问题2:softmax计算量太大

问题描述,每进行一次单词的共现预测时,都会涉及到一个问题:就是softmax计算, 可以回顾一下softmax的公式,你会发现每进行一次softmax计算,我们的分母上都要对
全部单词的预测输出值进行计算,然后加和,显然这样的复杂度是n。
问题后果:
每一次要对某一个单词做预测时,都要对全量的单词的概率做计算,其实这是一个很复杂的事情,效率会极低。
问题解决:
这里引入了霍夫曼树的原理,首先要知道霍夫曼树的原理是什么,霍夫曼数的原理就是,将权重越大的节点,越靠近根节点。下面做个例子来例句霍夫曼树的原理。
1 1 3 12 34 9 4 30 87

在构建霍夫曼树之前要对其进行排序
1 1 3 4 9 12 30 34 87
先将最小的分配到叶子节点上。
在这里插入图片描述

分配之后,将分配出去的节点(1,1)剔除出队列,将他们的加和(2)放入队列,然后将最小的两个拿出,进行重新排序
2 3 4 9 12 30 34 87
在这里插入图片描述

依次进行第二步的操作,将分配出去的节点(2,3)剔除出队列,将他们的加和(5)放入队列,然后重新排序,然后将最小的两个拿出
4 5 9 12 30 34 87
在这里插入图片描述

依次进行第二步的操作,将分配出去的节点(4,5)剔除出队列,将他们的加和(9)放入队列,然后重新排序,然后将最小的两个拿出
9 9 12 30 34 87
在这里插入图片描述

依次进行第二步的操作,将分配出去的节点(9,9)剔除出队列,将他们的加和(18)放入队列,然后重新排序,然后将最小的两个拿出
12 18 30 34 87
在这里插入图片描述

依次进行第二步的操作,将分配出去的节点(12,18)剔除出队列,将他们的加和(30)放入队列,然后重新排序,然后将最小的两个拿出
30 30 34 87
在这里插入图片描述

依次进行第二步的操作,将分配出去的节点(30,30)剔除出队列,将他们的加和(60)放入队列,然后重新排序,然后将最小的两个拿出
34 60 87
在这里插入图片描述

依次进行第二步的操作,将分配出去的节点(34,60)剔除出队列,将他们的加和(94)放入队列,然后重新排序,然后将最小的两个拿出
87 94
在这里插入图片描述

至此这棵树就构建完毕,可以发现数字最大的就会很靠近根节点(红色的),数字最小的会很原理根节点(黑色)

那为什么就可以引入这个霍夫曼树来优化我们的softmax呢?
其实就是根据每个单词出现的概率进行霍夫曼编码,首先会统计整个语料库中单词出现的次数,然后依据单词出现的次数进行霍夫曼编码(也就是将刚刚距离中的那些数字替换为具体单词出现的次数),将出现次数比较多的单词
优先放到根节点附近,这样当我们进行单词概率预测的时候,出现次数最多的当然要让他最快找到了,这就是优化本质。

首先上面关于word2vec的整个执行流程中讲到,最终我们会查到两个单词的向量,然后相乘,这里的分母上要进行所有单词
的概率计算统计,这里先不要softmax,
你想想,他们进行相乘以后,假设相乘的结果就是一个进入了一个霍夫曼树编码的根节点上,那这时候你如果是计算the出现的概率,你就只需要依据一条线去找到the,然后这条线上是有权重是需要学习的,将这些权重相乘就得到了
the的概率,显然复杂度大大降低,同时如果the在整篇文章中出现的次数很多,它就会被编码到根节点附件,这是效率会更高,因为只需要走一两步就找到the
的概率。
在这里插入图片描述

这就是对softmax的改进:层次softmax。
至此关于优化的也记录完毕。

おすすめ

転載: blog.csdn.net/weixin_41885239/article/details/121387608