NLP 笔记:Skip-gram
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,当它为中心词时向量表示为 ,而为背景词时向量表示为。
设中心词在词典中索引为c,背景在词典中索引为o,给定中心词生成一个背景词的条件概率可以通过对向量内积做softmax运算而得到:
可以想成是以c为中心词,o为背景词的概率权重;
分母相当于以c为中心词,生成其他各个词的概率权重。
所以二者一除就是给定中心词生成某一个背景词的条件概率
由上面那个式子,我们可以得到:每一个中心词,推断两边分别m个位置的背景词的概率:
其中,t表示窗口中心词的位置;m表示推断窗口的大小
我们为了求出“最好”的word embedding,可以最大化上面那个概率。
基于此,我们可以使用最大似然估计的方法。
但是一个函数的最大值往往不容易计算,因此,我们可以通过对函数进行变换,从而改变函数的增减性,以便优化。
其中,我们把带到上式中,可以得到
通过上面一段的操作,我们把一个求最大值的问题转换成了一个求最小值的问题。
求最小值,我们可以使用梯度下降法。
在优化之前,我们要搞清楚我们优化的目标是那个,哪些是参数。
我们要做一个假设,在对中心词权重更新时,背景词的权重是固定的,然后在以同样的方式来更新背景词的权重。
接下来我们求导计算梯度
这里就计算出来了中心词的梯度,可以根据这个梯度进行迭代更新。
对于背景词的更新是同样的方法。(就是上式不是对的偏导数,而是每个的偏导数了。
但是要注意背景词的个数不是唯一的,所以更新的时候要逐个更新。
训练结束后,对于词典中的任一索引为i ii的词,我们均得到该词作为中心词和背景词的两组词向量和
还有一个小问题要说明一下:
在词典中所有的词都有机会被当做是中心词和背景词。在更新的时候,都会被更新一遍,这种时候该怎么确定一个词的向量到底该怎么选择呢?
——在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的每一行对应的是单词作为中心词时的向量。
这里初始化的矩阵W'的每一列则对应的是单词作为背景词时的向量。
每个词都有机会成为中心词,同时也会成为其他中心词的背景词,因为窗口一直再变动。
4)取出一个词作为中心词。该词的词向量(它的形状为d维的向量1∗d),与背景词权重矩阵W‘中的其他词做内积。
此时会得到一个背景词的计算结果,即: (假设背景词的索引为o)。
重复计算,我们可以得到作为中心词的时候,字典中每一个词作为背景词的概率权重。(字典中有V个词,我们就可以得到V个概率权重)
5)softmax层的映射。
在上一步中得到了V个背景词的概率权重,那么此时我们需要做的就是计算某一个词作为背景词的条件概率,即
6)概率最大化。
skip-gram的学习相当于监督学习,我们是有明确的背景词输入的。(就是知道这个地方的背景词应该是哪个)
我们期望窗口内的词的输出概率最大。因此我们的目标变为极大化概率。
在不影响函数单调性的前提下我们变为极大化函数: l(对数似然)。
但是,计算一个函数的最大值不如计算一个函数的最小值来的方便,因此这里给这个函数进行单调性变换:
7)极小化目标函数。
通过上面的变换,此时已经变为一个数学优化问题,梯度下降法更新参数。
8)更新中心词的向量
后面减去的即为梯度:
9) 8对应的梯度里面,相比于5,又多了一层对于j的求和,这个下标代表的背景词,m是窗口的大小。这么做才能与我们最初的设定相对应:一个中心词,推断多个背景词。
10).根据同样的原理,在窗口进行移动了之后,可以进行同样的更新。
11.在词汇表中所有的词都被训练之后。我们得到了每个词的两个词向量分别为。是作为中心词时的向量,我们一般用这个作为最终的选择。对应的就是作为背景词时的向量了。
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相关推荐
- pytorch笔记: 搭建Skip—gram
skip-gram 理论部分见:NLP 笔记:Skip-gram_刘文巾的博客-CSDN博客 1 导入库 import numpy as np import torch from torch impo ...
- NLP笔记:word2vec简单考察
NLP笔记:word2vec简单考察 1. 简介 2. word2vec原理介绍 3. gensim实现 4. tensorflow实现 1. cbow方式 2. skip gram方式 3. 直接生 ...
- 《自然语言处理学习之路》02 词向量模型Word2Vec,CBOW,Skip Gram
本文主要是学习参考莫烦老师的教学,对老师课程的学习,记忆笔记. 原文链接 文章目录 书山有路勤为径,学海无涯苦作舟. 零.吃水不忘挖井人 一.计算机如何实现对于词语的理解 1.1 万物数字化 1.2 ...
- NLP笔记:常用激活函数考察整理
NLP笔记:常用激活函数考察整理 0. 引言 1. 常用激活函数 1. sigmoid 2. softmax 3. relu系列 1. relu 2. leaky relu 3. elu 4. sel ...
- 《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 笔记 这本书 本 ...
- 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个字符预测第 ...
- 【NLP笔记】文本生成?还不快上知识库
来自 | 知乎 地址 | https://zhuanlan.zhihu.com/p/163343976 作者 | 三和厂妹 编辑 | 机器学习算法与自然语言处理公众号 本文已获得作者授权,未经许可禁止 ...
- Coursera NLP 笔记02
找到一个很好的英语笔记,等有空了再整理第二章http://files.asimihsan.com/courses/nlp-coursera-2013/notes/nlp.html#the-trigra ...
- NLP 笔记: 序列标注与BIO标注
1 序列标注 序列标注(Sequence labeling)NLP问题中的基本问题.在序列标注中,我们想对一个序列的每一个元素标注一个标签.一般来说,一个序列指的是一个句子,而一个元素指的是句子中的一 ...
最新文章
- An internal error occurred during: Launching MVC on Tomcat 6.x.
- HDU 2955 Robberies
- CentOS 初体验十六:阿里云安装Nexus搭建Maven私有仓库
- 经典C语言程序100例之四六
- 华为鸿蒙os系统有哪些黑科技,华为首款搭载鸿蒙os智慧产品除了鸿蒙系统还有这黑科技...
- 410. Split Array Largest Sum 分割数组的最大值
- SVN更新的时候报断言失败解决办法
- This dependency was not found: * !!vue-style-loader!css-loader?……解决方案
- linux tick 函数,Linux上的GetTickCount函数
- django + mysql 支持表情包
- PostgreSQL 字典表设计
- FTP、FTPS 与 SFTP 简介
- gg修改器修改数值没有用怎么办_gg修改器怎么用教学 gg修改器修改游戏方法介绍...
- c语言中fprintf的作用,C语言中fprintf函数介绍
- 计算机可以谭音乐吗,谭晶怎么被叫谭哈哈 《歌手》谭晶演唱什么歌曲
- 程序员5种编程入门方法,如何快速学会一门编程语言?
- chromium的下载和编译(流程详解)
- 手机上该怎么合并PDF?这个方法可不要错过
- 消除Mac Word文档生成目录中的灰色底纹
- 【每天一个 Linux 命令】网络相关命令(ifconfig、route、ping、traceroute、netstat、ss、telnet、rcp、scp)
热门文章
- Memcache 安装与使用
- SQL Server 问题之 排序规则(collation)冲突
- Oracle的悲观锁和乐观锁
- build/envsetup.sh脚本分析
- 静态数组的声明与例子练习
- RHCE课程-RH253Linux服务器架设笔记五-DNS服务器配置(2)
- who killed my time?
- CSP认证201412-4	最优灌溉[C++题解]:最小生成树裸题、Kruskal算法求最小生成树
- InnoDB MySQL 全文索引 学习笔记
- linux内核模块编译出现找不到include/generated/asm/unistd_32.h” 问题解决