1 skip-gram举例

假设在我们的文本序列中有5个词,[“the”,“man”,“loves”,“his”,“son”]。

假设我们的窗口大小skip-window=2,中心词为“loves”,那么上下文的词即为:“the”、“man”、“his”、“son”。这里的上下文词又被称作“背景词”,对应的窗口称作“背景窗口”。

跳字模型能帮我们做的就是,通过中心词“loves”,生成与它距离不超过2的背景词“the”、“man”、“his”、“son”的条件概率,用公式表示即:

进一步,假设给定中心词的情况下,背景词之间是相互独立的,公式可以进一步得到

用概率图表示为:

可以看得出来,这里是一个一对多的情景,根据一个词来推测2m个词,(m表示背景窗口的大小)。

2 skip-gram 逐步解析

2.1  one-hot word symbol(编码)

在NLP学习笔记:word2vec_刘文巾的博客-CSDN博客 中我们说过 one-hot编码有很多的弊端(需要的空间很冗余,且无法反映单词之间的相似程度)。

但是计算机没办法识别“字符”,所有的数据必须转化成二进制的编码形式,one-hot编码就是最便捷的一种表达方式了。(这里的one-hot只是一种过渡)

2.2 词嵌入(word embedding)

但是,one-hot表达的向量过于稀疏。我们需要用一个稠密的向量来表示单词空间。(这个向量是可以在空间中表征一定单词的含义)

我们必须先初始化一些这样的表示单词的稠密向量,然后通过学习的方式来更新向量的值(权重),然后得到我们最终想要的向量。

2.1中得到的每一个单词的one-hot编码,都需要映射到一个稠密的向量编码中。

这个映射过程,就被称作是嵌入(embedding),因为是单词的映射,所以被叫做词嵌入(word embedding)。

假设我们要把一个单词映射到一个300维(这个300维是经过大量的实验得出的,一般的映射范围是200-500维)的向量中,那么我们直观的做法就是:矩阵运算。

因为我们每个单词现在的情况是N维的一个向量(N是字典中单词的数量),如果映射到300维,需要的权重矩阵就是N ∗ 300,这样得到的矩阵就是一个1 ∗ 300的矩阵(向量)。

2.2.1 词嵌入举例

假设我们字典中有5个单词(即N=5),那么word embedding如下图所示:

通过上图,我们可以发现一个规律:

计算出来的这个“稠密的”向量,和我们单词在one-hot编码表的位置是有关系的。

如果单词的one-hot编码中,第i维是1,那么生成的稠密词向量就是编码表的第i行。

所以我们word embedding生成稠密词向量的过程,就是一个查找编码表的过程。而这个编码表,我们可以想成是一个神经网络的隐藏层(这个隐藏层没有激活函数)。通过这个隐藏层,我们把one-hot编码映射到一个低维度的空间里面。

3 skip-gram 数学原理

在skip-gram中,每个词被表示成两个d维向量,用来计算条件概率。

假设这个词在词典中索引为i,当它为中心词时向量表示为 \boldsymbol{v}_i\in\mathbb{R}^d,而为背景词时向量表示为\boldsymbol{u}_i\in\mathbb{R}^d

设中心词w_c在词典中索引为c,背景w_o在词典中索引为o,给定中心词生成一个背景词的条件概率可以通过对向量内积做softmax运算而得到:

exp(u_o^Tv_c)可以想成是以c为中心词,o为背景词的概率权重;

分母相当于以c为中心词,生成其他各个词的概率权重。

所以二者一除就是给定中心词生成某一个背景词的条件概率

由上面那个式子,我们可以得到:每一个中心词,推断两边分别m个位置的背景词的概率:

其中,t表示窗口中心词的位置;m表示推断窗口的大小

我们为了求出“最好”的word embedding,可以最大化上面那个概率。

基于此,我们可以使用最大似然估计的方法。

但是一个函数的最大值往往不容易计算,因此,我们可以通过对函数进行变换,从而改变函数的增减性,以便优化。

其中,我们把带到上式中,可以得到

通过上面一段的操作,我们把一个求最大值的问题转换成了一个求最小值的问题。

求最小值,我们可以使用梯度下降法。

在优化之前,我们要搞清楚我们优化的目标是那个,哪些是参数。

我们要做一个假设,在对中心词权重更新时,背景词的权重是固定的,然后在以同样的方式来更新背景词的权重。

接下来我们求导计算梯度

这里就计算出来了中心词的梯度,可以根据这个梯度进行迭代更新。

对于背景词的更新是同样的方法。(就是上式不是对v_c的偏导数,而是每个w_o的偏导数了。

但是要注意背景词的个数不是唯一的,所以更新的时候要逐个更新。

训练结束后,对于词典中的任一索引为i ii的词,我们均得到该词作为中心词和背景词的两组词向量v_iu_i

还有一个小问题要说明一下:

在词典中所有的词都有机会被当做是中心词和背景词。在更新的时候,都会被更新一遍,这种时候该怎么确定一个词的向量到底该怎么选择呢?

——在NLP应用中,一般使用中心词向量作为词的表征向量。

4 skip-gram流程总结

1)one-hot编码。

每个单词形成V∗1的向量;对于整个词汇表就是V∗V的矩阵。

2)word embedding 词嵌入。

根据索引映射,将每个单词映射到d维空间。

通过这样的方式就可以将所有的单词映射到矩阵W上(矩阵W的形状为V∗d),并且每个单词与矩阵中的某列一一对应。

3)skip-gram模型训练。

初始化一个d维空间的矩阵作为权重矩阵W ′ ,该矩阵的形状为V ∗ d 。

值得注意的是,目前我们已经有了两个d维空间的矩阵,要清楚这两个矩阵都是干什么的。

矩阵W的每一行对应的是单词作为中心词时的向量v_i

这里初始化的矩阵W'的每一列则对应的是单词作为背景词时的向量u_i

每个词都有机会成为中心词,同时也会成为其他中心词的背景词,因为窗口一直再变动。

4)取出一个词作为中心词。该词的词向量v_c(它的形状为d维的向量1∗d),与背景词权重矩阵W‘中的其他词做内积。

此时会得到一个背景词的计算结果,即: v_c*u_o^T(假设背景词的索引为o)。

重复计算,我们可以得到v_c作为中心词的时候,字典中每一个词作为背景词的概率权重。(字典中有V个词,我们就可以得到V个概率权重)

5)softmax层的映射。

在上一步中得到了V个背景词的概率权重,那么此时我们需要做的就是计算某一个词作为背景词的条件概率,即

6)概率最大化。

skip-gram的学习相当于监督学习,我们是有明确的背景词输入的。(就是知道这个地方的背景词应该是哪个)

我们期望窗口内的词的输出概率最大。因此我们的目标变为极大化概率P(w_o \mid w_c)

在不影响函数单调性的前提下我们变为极大化函数: \log P(w_o \mid w_c)l(对数似然)。

但是,计算一个函数的最大值不如计算一个函数的最小值来的方便,因此这里给这个函数进行单调性变换:-\log P(w_o \mid w_c)

7)极小化目标函数。

通过上面的变换,此时已经变为一个数学优化问题,梯度下降法更新参数。

8)更新中心词的向量v_c

v_c := v_c - \alpha * \nabla P(w_o \mid w_c)

后面减去的即为梯度:\nabla P(w_o \mid w_c)=\boldsymbol{u}_o - \sum_{j \in (c-m,0) \cup (0,c+m) } \left(\frac{\text{exp}(\boldsymbol{u}_j^\top \boldsymbol{v}_c)}{ \sum_{i \in \mathcal{V}} \text{exp}(\boldsymbol{u}_i^\top \boldsymbol{v}_c)}\right) \boldsymbol{u}_j

9) 8对应的梯度里面,相比于5,又多了一层对于j的求和,这个下标代表的背景词,m是窗口的大小。这么做才能与我们最初的设定相对应:一个中心词,推断多个背景词。

10).根据同样的原理,在窗口进行移动了之后,可以进行同样的更新。

11.在词汇表中所有的词都被训练之后。我们得到了每个词的两个词向量分别为v_i,u_iv_i是作为中心词时的向量,我们一般用这个作为最终的选择。u_i对应的就是作为背景词时的向量了。

 5 skip-gram 优化

我们现在有一个包含10000个单词的词汇表,向量特征为300维。

那么对于这个词汇量的skip-gram,将会有两个weights矩阵----一个隐藏层和一个输出层。

这两层都会有一个300x10000=3000000的权重矩阵。

在如此大的神经网络上进行梯度下降是非常慢的,更加严重的是,我们需要大量训练数据去调整权重,以及避免过拟合。

在论文“Distributed Representations of Words and Phrases and their Compositionality”中,主要有三种方式来优化skip-gram:

5.1 在模型中将共同出现的单词对或者短语当做单个“词”

比如像“Boston Globe”(“波士顿环球报”,一种报纸)这样的单词对,在作为单独的“Boston”和“Globe”来进行看待的时候有着非常不同的含义。

所以在将它作为一整个“Boston Globe”来说是非常有意义的,不论它出现在文中哪里,都将一整个当成一个单词来看待,并且有它自己的词向量。

论文中使用了1千亿个来自谷歌新闻数据集的单词来进行训练。额外增加的短语使得这个模型的单词尺寸缩减到了3百万个单词!

5.2 二次采样

在一个很大的语料库中,有一些很高频率的一些词(比如冠词 a,the ;介词 in,on等)。

这些词相比于一些出现的次数较少的词,提供的信息不多。同时这些词会导致我们很多的训练是没有什么作用的。

为了缓解这个问题,论文中提出了二次采样的思路:每一个单词都有一定概率被丢弃。这个概率为:

f(wi)是单词出现的次数与总单词个数的比值。(例如“peanut”在1 billion 单词语料中出现了1000次,那么z('peanut')=1E-6)

t是一个选定的阈值,一般在1E-5左右。

5.3 负采样

在训练skip-gram时,每接受一个训练样本,就需要调整所有神经单元权重参数,来使神经网络预测更加准确。

换句话说,每个训练样本都将会调整所有神经网络中的参数。

词汇表的大小决定了我们skip-gram 神经网络将会有一个非常大的权重参数,并且所有的权重参数会随着数十亿训练样本不断调整。

负采样的思路是:每次让一个训练样本仅仅更新一小部分的权重参数,从而降低梯度下降过程中的计算量。

如果词汇表的大小为1万, 当输入样本 ( "fox", "quick") 到神经网络时,在输出层我们期望对应 “quick” 单词的那个神经元结点输出 1,其余 9999 个都应该输出 0。在这里,这9999个我们期望输出为0的神经元结点所对应的单词我们称之为 negative word。

负采样的想法也很直接 ,将随机选择一小部分的 negative words,比如选 10个 negative words 来更新对应的权重参数。

在论文中作者指出指出对于小规模数据集,建议选择 5-20 个 negative words,对于大规模数据集选择 2-5个 negative words.

如果使用了负采样,那么 仅仅需要去更新positive word- “quick” 和选择的其他 10 个negative words 的结点对应的权重,共计 11 个输出神经元,相当于每次只更新 300 x 11 = 3300 个权重参数。对于 3百万 的权重来说,相当于只计算了千分之一的权重,这样计算效率就大幅度提高。

这里指的权重是前面说的W'的权重,也就是背景词矩阵的权重

5.3.1 负样本(negative words)的选择

论文中使用 一元模型分布 (unigram distribution) 来选择 negative words。

一个单词被选作 负样本 的概率跟它出现的频次有关,出现频次越高的单词越容易被选作负样本,经验公式为:

其中:

f(w) 代表 每个单词被赋予的一个权重,即 它单词出现的词频。

分母 代表所有单词的权重和。

公式中指数3/4完全是基于经验的,论文中提到这个公式的效果要比其它公式更加出色。

5.3.2 正样本的概率

对于正样本,Skig-Gram 模型的输出是

引入负样本之后,我们计算概率的函数不像之前是softmax了,而是sigmoid函数。

5.3.3 负样本的概率

对于负样本,Skig-Gram 模型的输出是

5.3.4 总样本

参考文献

NLP之---word2vec算法skip-gram原理详解_Ricky-CSDN博客_skipgram

Word2Vec教程-Skip-Gram模型 - 简书 (jianshu.com)

Word2Vec教程-Negative Sampling 负采样 - 简书 (jianshu.com)

countries.capitals.projections.eps (arxiv.org)

Word2Vec导学第二部分 - 负采样_陈诚的博客-CSDN博客_负采样

Word2vec, Skip-Gram, CBOW, NEG, 负采样 - 知乎 (zhihu.com)

NLP 笔记:Skip-gram相关推荐

  1. pytorch笔记: 搭建Skip—gram

    skip-gram 理论部分见:NLP 笔记:Skip-gram_刘文巾的博客-CSDN博客 1 导入库 import numpy as np import torch from torch impo ...

  2. NLP笔记:word2vec简单考察

    NLP笔记:word2vec简单考察 1. 简介 2. word2vec原理介绍 3. gensim实现 4. tensorflow实现 1. cbow方式 2. skip gram方式 3. 直接生 ...

  3. 《自然语言处理学习之路》02 词向量模型Word2Vec,CBOW,Skip Gram

    本文主要是学习参考莫烦老师的教学,对老师课程的学习,记忆笔记. 原文链接 文章目录 书山有路勤为径,学海无涯苦作舟. 零.吃水不忘挖井人 一.计算机如何实现对于词语的理解 1.1 万物数字化 1.2 ...

  4. NLP笔记:常用激活函数考察整理

    NLP笔记:常用激活函数考察整理 0. 引言 1. 常用激活函数 1. sigmoid 2. softmax 3. relu系列 1. relu 2. leaky relu 3. elu 4. sel ...

  5. 《Natural Language Processing with PyTorch》 Chapter 2: A Quick Tour of Traditional NLP 笔记

    <Natural Language Processing with PyTorch> Chapter 2: A Quick Tour of Traditional NLP 笔记 这本书 本 ...

  6. Rasa课程、Rasa培训、Rasa面试、Rasa实战系列之Understanding Word Embeddings CBOW and Skip Gram

    Rasa课程.Rasa培训.Rasa面试.Rasa实战系列之Understanding Word Embeddings CBOW and Skip Gram 字嵌入 从第i个字符,第i+1个字符预测第 ...

  7. 【NLP笔记】文本生成?还不快上知识库

    来自 | 知乎 地址 | https://zhuanlan.zhihu.com/p/163343976 作者 | 三和厂妹 编辑 | 机器学习算法与自然语言处理公众号 本文已获得作者授权,未经许可禁止 ...

  8. Coursera NLP 笔记02

    找到一个很好的英语笔记,等有空了再整理第二章http://files.asimihsan.com/courses/nlp-coursera-2013/notes/nlp.html#the-trigra ...

  9. NLP 笔记: 序列标注与BIO标注

    1 序列标注 序列标注(Sequence labeling)NLP问题中的基本问题.在序列标注中,我们想对一个序列的每一个元素标注一个标签.一般来说,一个序列指的是一个句子,而一个元素指的是句子中的一 ...

最新文章

  1. An internal error occurred during: Launching MVC on Tomcat 6.x.
  2. HDU 2955 Robberies
  3. CentOS 初体验十六:阿里云安装Nexus搭建Maven私有仓库
  4. 经典C语言程序100例之四六
  5. 华为鸿蒙os系统有哪些黑科技,华为首款搭载鸿蒙os智慧产品除了鸿蒙系统还有这黑科技...
  6. 410. Split Array Largest Sum 分割数组的最大值
  7. SVN更新的时候报断言失败解决办法
  8. This dependency was not found: * !!vue-style-loader!css-loader?……解决方案
  9. linux tick 函数,Linux上的GetTickCount函数
  10. django + mysql 支持表情包
  11. PostgreSQL 字典表设计
  12. FTP、FTPS 与 SFTP 简介
  13. gg修改器修改数值没有用怎么办_gg修改器怎么用教学 gg修改器修改游戏方法介绍...
  14. c语言中fprintf的作用,C语言中fprintf函数介绍
  15. 计算机可以谭音乐吗,谭晶怎么被叫谭哈哈 《歌手》谭晶演唱什么歌曲
  16. 程序员5种编程入门方法,如何快速学会一门编程语言?
  17. chromium的下载和编译(流程详解)
  18. 手机上该怎么合并PDF?这个方法可不要错过
  19. 消除Mac Word文档生成目录中的灰色底纹
  20. 【每天一个 Linux 命令】网络相关命令(ifconfig、route、ping、traceroute、netstat、ss、telnet、rcp、scp)

热门文章

  1. Memcache 安装与使用
  2. SQL Server 问题之 排序规则(collation)冲突
  3. Oracle的悲观锁和乐观锁
  4. build/envsetup.sh脚本分析
  5. 静态数组的声明与例子练习
  6. RHCE课程-RH253Linux服务器架设笔记五-DNS服务器配置(2)
  7. who killed my time?
  8. CSP认证201412-4 最优灌溉[C++题解]:最小生成树裸题、Kruskal算法求最小生成树
  9. InnoDB MySQL 全文索引 学习笔记
  10. linux内核模块编译出现找不到include/generated/asm/unistd_32.h” 问题解决