Word2vec简单整理

参考:https://zhuanlan.zhihu.com/p/22477976

http://yobobobo001.github.io/2016/05/26/%E6%88%91%E6%89%80%E7%90%86%E8%A7%A3%E7%9A%84word2vec/

http://x-algo.cn/index.php/2016/03/12/281/#i

https://www.zhihu.com/question/25269336

http://mp.weixin.qq.com/s?__biz=MzA3MDg0MjgxNQ==&mid=208116963&idx=3&sn=2a4c2eb8fbd27cad2293d8acabce52e9&mpshare=1&scene=1&srcid=0327HXI7DLeR7UUMDXHlb7H3#rd

http://www.flyml.net/2016/11/07/word2vec-basic-understanding/

简介

word2vec就是用一个一层的神经网络(CBOW的本质)把one-hot形式的词向量映射为分布式形式的词向量,为了加快训练速度,用了Hierarchical softmax,negative sampling 等trick。训练的主要目标是获得分布式词向量,而不是神经网络的预测模型。word2vec的训练过程是有监督的神经网络学习,但是得到的结果居然是无监督的clustering的效果,就是获取词向量。分布式词向量隐含了词语的信息,分布式词向量之间的夹角可以表示词语之间的相关性,因此用作特征值比直接用词本身更方便。word2vec还规避了两大问题:词语的次序和热门词语的降权处理。与潜在语义分析(Latent Semantic Index, LSI)、潜在狄立克雷分配(Latent Dirichlet Allocation,LDA)的经典过程相比,Word2vec利用了词的上下文,语义信息更加地丰富。

word2vec涉及到很多自然语言处理的名词。首先是词向量(word vector),图像和音频等信号都可以用一个矩阵或者向量表示,所以我们也希望用一个数学方法来表达单词,这样可以方便的用于各种后续计算,这就是词向量。

1. one-hot方式。从很大的词库corpus里选V个频率最高的词(忽略其他的),V一般比较大,比如V=10W,固定这些词的顺序,然后每个词就可以用一个V维的稀疏向量表示了,这个向量只有一个位置的元素是1,其他位置的元素都是0。One hot方式其实就是简单的直接映射,所以缺点也很明显,维数很大,也没啥计算上的意义。

2. 分布式词向量(distributed word representation), 分布式词向量是一个固定大小的实数向量,事前确定它的大小比如N=300维或者N=1000维,每个元素都是一个实数,实数的具体值是词库里面每个词通过不同的贡献得来的,所以叫分布式的。而word2vec就是一种学习这个分布式词向量的算法。向量的余弦夹角可以代表词语之间的相似度。种方法相较于One-hot方式另一个区别是维数下降极多,对于一个10W的词表,我们可以用10维的实数向量来表示一个词,而One-hot得要10W维。



分布式词向量并不是word2vec的作者发明的,他只是提出了一种更快更好的方式来训练也就是:连续词袋模型Continous Bag of Words Model(CBOW)和Skip-Gram Model。这两种都是训练词向量的方法,可以选择其一,不过据论文说CBOW要更快一些(1天vs.3天的区别)。统计语言模型statistical language model就是给你几个词,在这几个词出现的前提下来计算某个词出现的(事后)概率。CBOW也是统计语言模型的一种,顾名思义就是根据某个词前面的C个词或者前后C个连续的词,来计算某个词出现的概率。Skip-Gram Model相反,是根据某个词,然后分别计算它前后出现某几个词的各个概率。
以“我爱北京天安门”这句话为例。假设我们现在关注的词是“爱”,C=2时它的上下文分别是“我”,“北京天安门”。CBOW模型就是把“我” “北京天安门” 的one hot表示方式作为输入,也就是C个1xV的向量,分别跟同一个VxN的大小的系数矩阵W1相乘得到C个1xN的隐藏层hidden layer,然后C个取平均所以只算一个隐藏层。这个过程也被称为线性激活函数(这也算激活函数?分明就是没有激活函数了)。然后再跟另一个NxV大小的系数矩阵W2相乘得到1xV的输出层,这个输出层每个元素代表的就是词库里每个词的事后概率。输出层需要跟ground truth也就是“爱”的one hot形式做比较计算loss。这里需要注意的就是V通常是一个很大的数比如几百万,计算起来相当费时间,除了“爱”那个位置的元素肯定要算在loss里面,word2vec就用基于huffman编码的Hierarchical softmax筛选掉了一部分不可能的词,然后又用nagetive samping再去掉了一些负样本的词所以时间复杂度就从O(V)变成了O(logV)。Skip gram训练过程类似,只不过输入输出刚好相反。
训练完成后对于某个词就可以拿出它的1xN的隐藏层作为词向量,就可以w2v(中国)-w2v(北京)=w2v(法国)-w2v(巴黎)了。

如何训练词向量

一般而言,一篇文章都会有个主题,比如海贼王的文章里面可能通篇都出现海贼王相关的词语,如路飞,索隆等,这些词的语义肯定比不同文章的更相近,所以作者提出了以下两种模型,把相近的单词放进模型里面训练。

  • cbow

    把中间的词单独拎出来,让周围的词去预测这个词的概率。

    1. 每个单词先映射到公用词表中(大矩阵)一列对应的向量
    2. 把向量相加
    3. 把这个向量经过一个softmax得出预测相应单词的概率。
  • skip-gram

    skip-gram则是输入一个单词,把词周围的其他词作为要预测的单词。

训练的细节

  • softmax层加速

    两种网络结构的最后一层都是一个大的softmax,起到对于每个词的预测概率归一化作用,可是在实际训练过程中每次迭代都要通过softmax计算每个词的概率是相当耗费时间的,能否优化这个呢?这个问题早在03年Bengio提出的语言模型[2]也遇到,后来他们提出了Hierarchical Softmax[3]来加速。

    • 为什么要归一化

      在每次迭代中把要预测的词相关权重增加,通过归一化,同时把其他的词相关权重减少。这个不难理解,总的预测概率和是1,把其中某一个词的概率增加就意味着把其他词的预测概率打压。能不能只增加其中某个词的概率呢?可以,但是收敛很慢。

    • Hierarchical Softmax 是如何提速的?

      Hierarchical Softmax 相对于原来的softmax是把一个多分类问题转换成了多个二分类问题。通俗地说,现在仓管人员要去仓库找一个配件,按照softmax策略是把仓库里面的配件一个个的过一遍,最后确定下来是哪个,Hierarchical Softmax则是根据预先记录的表知道了要找的配件在第二个房间的第一个货架第二行第一个直接去取的。在上面提到,归一化的作用是把其他词的概率打压,那么能不能把词分好类别直接打压呢?这样就是每次打压一个类别(多个单词),而不用一个个地打压每个单词的相关权重了。原来的softmax是这样的:

      现在我们构建一颗二叉树把所有单词放在叶子节点上:

      现在我们要更新12号节点,沿着二叉树的路径可以看到判断是这样的:是否在1号节点的左儿子里,是否在2号节点的左儿子里,是否在5号节点的左儿子里,是否在9号儿子的左节点里。这就变成了多个二分类问题,作者采用哈弗曼树编码更是把每个单词在树中路径的长度减少到极致,并且等价于原来的softmax,因为整棵树的叶子节点和是归一化的。所以,最终的更新只需要更新一部分的权重即可。注意:最终的节点已经不是表示单词了,而是二叉树上的非叶子节点。

      这样,由原来的O(N)次运算下降到了O(logN)级别,搞过ACM的同学可以意识到这个做法类似线段树的段更新。

  • negative sampling

    不做归一化可是又想降低其他单词的预测概率,该怎么做呢?这就是negative sampling的由来。作者对其他的单词进行负采样以降低其他单词的相关权重,作者认为负采样中单词作为负样本的概率应该和其词频正相关,所以词频越高的越大概率被抽到。这种方案我认为只是一种近似方案,和Hierarchical Softmax 这种等价于原来的softmax是有明显区别的。不过这种方案在低频词上的学习会好一些,主要原因在于负采样更容易抽到其中的高频词。

  • 训练数据的窗口选取策略

    从cbow的网络结构可以看出,模型输入的单词数量是不定长的,那在构造训练样本的时候应该如何选取预测单词附近的多少个单词作为输入呢?Mikolov认为离预测单词近的词语比那些远的单词更相关,所以采用了随机窗口大小的方式来选取,每次在区间[1, window]随机一个数值K,然后在预测单词的前后各选取k个单词作为输入。

    window是可选参数大小,window增大可以使向量学习更充分,但同时也增加了训练的复杂度。

  • exp运算打表

    计算softmax的时候需要求e的x次方,一轮迭代中指数运算至少需要上亿级别的指数运算,由于sigmod函数是个长“S”型的函数,可以通过对中间部分的x查表来取代多次指数运算。

  • 降采样

    对于语料中的高频词,Mikolov选择对它们进行降采样(sub-samplig),我认为高频词在语料中的出现次数比较多,而且高频词一般而言都不是决定附近词语的词,比如“的”这种停用词。所以对高频词进行降采样既不影响模型效果,又能提升收敛速度,何乐而不为呢?

  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值