[NLP]高级词向量表达之Word2vec详解(知识点全覆盖)

1、词表征(Word Representation)

首先明确句子是 序列化 ,里面携带了大量大信息。在NLP发展的进程里面, 采用了one-hot vector的形式来表示一个句子里面的词是一种方式。表示这个句子的方式如下:
1、首先是创建一张词汇表(Vocabulary),然后每个词都有对应的位置,假设现在我们有10000个单词。本例子来自于吴恩达的Deep learning ai。图中所示的词汇表大小就是10000。一般规模的商业应用来说,词汇表大小为30000到50000词。大型互联网是百万级别的词汇表。

在这里插入图片描述
2、将句子里面的每个单词转换为one-hot vector。one-hot vector从字面上来理解就是向量里面只有1个1,也就是找到这个词在词汇表里面的位置处填上1,然后其他的位置都是0。可以看出one-hot vector的模长为1。
one-hot vector表示向量的缺陷:
(1)这种表示把每个词都孤立出来了,使得算法对相关词的泛化能力弱。两个不同人名的one-hot vector的内积为0,这样来表示就不能体现出词汇在某些方面的相关性
(2)这样得到的向量是稀疏的,而且维度非常的大。

那么现在提个问题:我们怎么来表示词汇,能够将一些相关词汇之间的一些共通特征给表现出来呢?

2、词嵌入(Word Embedding)

embedding是数学领域的有名词,是指某个对象 X 被嵌入到另外一个对象 Y 中,映射 f : X → Y ,例如有理数嵌入实数。word embedding,就是找到一个映射或者函数,生成在一个新的空间上的表达,该表达就是word representation。推广开来,还有image embedding, video embedding, 都是一种将源数据映射到另外一个空间.
Word Embedding 是NLP中一组语言模型和特征学习技术的总称,把词汇表中的单词或者短语映射成由实数构成的向量上(映射)在这里插入图片描述
在这里插入图片描述
文本表示的方法有很多种,下面只介绍 3 类方式:

独热编码 | one-hot representation
整数编码
词嵌入 | word embedding

word embedding 是文本表示的一类方法。跟 one-hot 编码和整数编码的目的一样,不过?他有更多的优点。

词嵌入并不特指某个具体的算法,跟上面2种方式相比,这种方法有几个明显的优势:

他可以将文本通过一个低维向量来表达,不像 one-hot 那么长。
语意相似的词在向量空间上也会比较相近。
通用性很强,可以用在不同的任务中。
在这里插入图片描述
在这里插入图片描述
Word2vec
这是一种基于统计方法来获得词向量的方法,他是 2013 年由谷歌的 Mikolov 提出了一套新的词嵌入方法。

这种算法有2种训练模式:

通过上下文来预测当前词
通过当前词来预测上下文
GloVe 可以移步我的另一篇
GloVe 是对 Word2vec 方法的扩展,它将全局统计和 Word2vec 的基于上下文的学习结合了起来
One-Hots 就是最简单的Word Embedding,是指将所有词排成一列,对于词A,只有在它的位置置1,其他位置置0,维度就是所有词的数目。
N-Gram是基于一个假设:第n个词出现与前n-1个词相关,而与其他任何词不相关(这也是隐马尔可夫当中的假设)。指给定的一段文本或语音中N个项目(item)的序列
两个重要应用场景:
(1)基于一定的语料库,利用N-Gram预计或者评估一个句子是否合理。
(2)评估两个字符串之间的差异程度。这是模糊匹配中常用的一种手段。

N=1时称为unigram,N=2称为bigram,N=3称为trigram,以此类推。例:将“informationretrieval”视为一段文本,它的5-grams的items依次为:infor, nform, forma, ormat, rmati, matio, ation, tionr, ionre, onret, nretr, retri, etrie, triev, rieva, ieval

字符串间模糊匹配

(1)N-gram距离

两个字符串s,t分别利用N-Gram语言模型来表示时,则对应N-gram子串中公共部分的长度就称之为N-Gram距离。例如:假设有字符串s,那么按照N-Gram方法得到N个分词组成的子字符串,其中相同的子字符串个数作为N-Gram距离计算的方式。具体如下所示:

字符串:s=“ABC”,对字符串进行分词,考虑字符串首尾的字符begin和end,得到begin,A,B,C,end。这里采用二元语言模型,则有:(begin,A)、(A,B)、(B,C)、(C,end)。

字符串:t=“AB”,对字符串进行分词,考虑字符串首尾的字符begin和end,得到begin,A,B,end。这里采用二元语言模型,则有:(begin,A)、(A,B)、(B,end)。

假设有一个字符串s=“ABC”,对应的BI-Gram的结果如下:(begin,A)、(A,B)、(B,C)、(C,end)。出现字符串s的概率为:
P(ABC)=P(A|begin)P(B|A)P(C|B)*P(end|C)。

在处理文本特征时,通常一个关键词作为一个特征。在一些场景可能不够,需要进一步提取更多的特征,可以考虑N-Gram,思路如下:

以Bi-Gram为例,在原始文本中,以每个关键词作为一个特征,通过将关键词两两组合,得到一个Bi-Gram组合,再根据N-Gram语言模型,计算各个Bi-Gram组合的概率,作为新的特征。

Cocurrence matrix定义

共现矩阵Cocurrence matrix:一定程度上解决没有考虑单词之间相对位置的关系的问题

实现方法:某个词的意思跟它临近的单词是紧密相关的。可以设定一个窗口(大小一般是5~10),利用这种共现关系生成词向量(得到一个对称矩阵——共现矩阵,该矩阵统计当前词与其他词在同一窗口中的次数,如果词数是n,那么矩阵是nXn)。

例子:
I like deep learning.
I like NLP.
I enjoy flying.
共现矩阵:
在这里插入图片描述
缺点:仍然面对维度灾难。这SVD或者PCA等一些常用的降维方法也会带来其他的一些问题,例如,我们的词汇表中有新词加入,很难为他分配一个新的向量。

分布式表示Dristributed representation

Dristributed representation可以解决One hot representation的问题,它的思路是通过训练,将每个词都映射到一个较短的词向量上来。所有的这些词向量就构成了向量空间,进而可以用普通的统计学的方法来研究词与词之间的关系。这个较短的词向量维度是多大呢?这个一般需要我们在训练时自己来指定。

Dristributed representation:低维实数向量,它的思路是通过训练,将每个词都映射到一个较短的词向量上来,可以解决One hot representation的问题,。在word2vec出现之前,已经有用神经网络DNN来用训练词向量进而处理词与词之间的关系了。采用的方法一般是一个三层的神经网络结构(当然也可以多层),分为输入层,隐藏层和输出层(softmax层)

相关或者相似的词,在距离上更接近
自动实现:1)单词语义相似性的度量;2)词汇的语义的类比
在这里插入图片描述

Word2Vec训练词向量

Word2Vec:CBOW、Skip-Gram
前面我们看到了one-hot vector表示一个词,只有一个维度有意义。那么我们可以想想,能不能把一些相似词汇的一些特征抽取出来,给词不同的维度赋予一些意思呢?结果就出现了词嵌入的方式来表示句子里面的词。

(1)词嵌入:顾名思义,就是将一些特征给嵌入到词汇里面,让它能表现出更多的信息。

Dristributed representation可以解决One hot representation的问题,它的思路是通过训练,将每个词都映射到一个较短的词向量上来。所有的这些词向量就构成了向量空间,进而可以用普通的统计学的方法来研究词与词之间的关系。这个较短的词向量维度是多大呢?这个一般需要我们在训练时自己来指定。
在这里插入图片描述
经过我们一系列的降维神操作,有了用Dristributed representation表示的较短的词向量,我们就可以较容易的分析词之间的关系了,比如我们将词的维度降维到2维,有一个有趣的研究表明,用下图的词向量表示我们的词时,我们可以发现:
在这里插入图片描述在这里插入图片描述
出现这种现象的原因是,我们得到最后的词向量的训练过程中引入了词的上下文。你想到得到"learning"的词向量,但训练过程中,你同时考虑了它左右的上下文,那么就可以使"learning"带有语义信息了。通过这种操作,我们可以得到近义词,甚至cat和它的复数cats的向量极其相近。

现在举个例子:
1)性别特征:我们可以看出一些词如Man, Woman, King, Queen是有关系的,那么我们就在gender这一栏给填上相关性的权重,然后词如Apple, Orange这些就与gender,没有关系,那么就是赋予趋近于0的权重。
2)年龄特征:可以看出King, Queen和age还是很想关的,但是Man, Woman, Apple, Orange与此就没有多大关系了。
采用相同的策略,我们可以从很多特征(Food、size、cost、alive等)来考察一个词在这些特征上面是否有关系。在这里例子里面选取了300个特征,那么我们就可以将一个词表示为300维的一个向量,那么这些向量里面很多维度上都不是0。而且我们也可以看出向量之间再做内积就能体现出词汇的相似度了。然后另外一个重要的特性就做类比推理,但是这种推理的准确度在30%到75%区间范围内。
在这里插入图片描述
到这里了,你会想,我们如何来得到一个词嵌入的特征矩阵呢?

(2)学习词嵌入

在介绍学习词嵌入之前,把相关的符号在这里标注下:
其中10000表示词汇表次数,300表示嵌入向量里面的特征数。所以我们有个词汇表和嵌入矩阵之后,我们就能得到对应单词的词向量了。
下面我们就开始对词向量进行一个学习:
学习嵌入矩阵E的一个好方法就是2003年Bengio等人提出的神经语言模型 ,关于语言模型的介绍可以参考我的前一篇博客。
这里我们以一句话为例,来说明使用语言模型来学习词嵌入。这句话:I want a glass of orange juice。
上下文(context):把预测词前面的几个词作文上下文,这个例子中为a glass of orange
目标词(target):把要预测的单词作为目标词,这个例子中的目标词就是juice
注意:这里是为了学习词嵌入,不是为了构建一个语言模型。
在这里插入图片描述
那么现在我们就有训练集样本了:content(w):维度((n-1)m,1),n-1指的是窗口里面的单词数,也就是例子中的4,m指的是词向量的维度,例子中为300。那么例子中显示的是(1200,1)。
w:要预测的下一个词,例子中为juice,然后它的维度是(D, 1),D指的就是词汇表的大小,也就是例子中所示的10000。
在softmax层,会计算10000个条件概率。然后可以通过反向传播的方式,经过梯度下降法,得到我们想获得的嵌入矩阵E。
与n-gram模型相比,好处在于:
1、可以进行词语之间的相似度计算了,而且还能够做类比。
2、不需要再考虑平滑操作了,因为p(w|context)在0到1之间。

二、Word2Vec

百度百科:Word2vec,是一群用来产生词向量的相关模型。这些模型为浅而双层的神经网络,用来训练以重新建构语言学之词文本。网络以词表现,并且需猜测相邻位置的输入词,在word2vec中词袋模型假设下,词的顺序是不重要的。训练完成之后,word2vec模型可用来映射每个词到一个向量,可用来表示词对词之间的关系,该向量为神经网络之隐藏层。
Word2vec 可以根据给定的语料库,通过优化后的训练模型快速有效地将一个词语表达成向量形式,为自然语言处理领域的应用研究提供了新的工具。Word2vec依赖skip-grams或连续词袋(CBOW)来建立神经词嵌入。

word2vec模型其实就是简单化的神经网络。在这里插入图片描述
输入是One-Hot Vector,Hidden Layer没有激活函数,也就是线性的单元。Output Layer维度跟Input Layer的维度一样,用的是Softmax回归。当这个模型训练好以后,我们并不会用这个训练好的模型处理新的任务,我们真正需要的是这个模型通过训练数据所学得的参数,例如隐层的权重矩阵。

这个模型是如何定义数据的输入和输出呢?一般分为CBOW(Continuous Bag-of-Words 与Skip-Gram两种模型。CBOW模型的训练输入是某一个特征词的上下文相关的词对应的词向量,而输出就是这特定的一个词的词向量。 Skip-Gram模型和CBOW的思路是反着来的,即输入是特定的一个词的词向量,而输出是特定词对应的上下文词向量。CBOW对小型数据库比较合适,而Skip-Gram在大型语料中表现更好。

看完了前面的神经语言模型之后,我们看转入了Word2Vec的两个重要的模型CBOW(Continues bags of words)和Skip-gram模型。这两个模型的示意图如下:
在这里插入图片描述
这里可以明显看出下面的的预测的方法:在这里插入图片描述

1、Skip-Gram

定义:给定input word来预测上下文
在这里插入图片描述

1
2
3
4
5
6
训练数据获取:假如有一个句子“The quick brown fox jumps over lazy dog”。
选句子中间的一个词作为我们的输入词,例如我们选取“quick”作为input word;
定义skip_window的参数,代表从当前input word的一侧(左边或右边)选取词的数量。如果我们设置skip_window=2,那么我们最终获得窗口中的词(包括input word在内)就是['The', 'quick','brown', 'fox']。skip_window=2代表着选取左input word左侧2个词和右侧2个词进入我们的窗口,所以整个窗口大小span=2x2=4。
参数num_skips,代表从整个窗口中选取多少个不同的词作为output word,当skip_window=2,num_skips=2时,会得到两组 (input word, output word) 形式的训练数据,即 ('quick', 'brown'),('quick', 'the')。
训练时,剔除高频的停用词来减少模型的噪音,并加速训练,如'the'、'a'等,它们对其他词的贡献不大。
input word和output word都是one-hot编码的向量。最终模型的输出是一个概率分布。

在这里插入图片描述
模型输入:

输入的每一个词都是一个One-Hot表示形式,(“the”, “quick”, “brown”, “fox”, “jumps”,“over”,“lazy”,“dog”),我们对这个词汇表的单词进行编号0-7。那么”dog“就可以被表示为一个8维向量[0, 0, 0, 0, 0, 0, 0, 1]。
通常词汇表比较大,如果词汇表有10000个词,模型的输入就是一个10000维的向量,那么输出也是一个10000维度(词汇表的大小)的向量,它包含了10000个概率,每一个概率代表着当前词是输入样本中output word的概率大小。在这里插入图片描述

隐含层:

网络的隐层没有使用任何激活函数,但是输出层使用了sotfmax

隐含层节点的个数就是词向量的维数,由One-Hot映射为Dristributed representation

上图网络中隐层的权重矩阵应该为10000行,300列(隐层有300个结点)。最终每个单词可以被编码为300维的词向量

Google在最新发布的基于Google news数据集训练的模型中使用的是300个特征的词向量,在Python的gensim包中封装的Word2Vec接口默认的词向量大小为100, window_size为5
下图中,左右两张图分别从不同角度代表了输入层-隐层的权重矩阵。左图中每一列代表一个10000维的词向量和隐层单个神经元连接的权重向量。右图中,每一行实际上代表了每个单词的词向量。
在这里插入图片描述
最终的目标就是学习这个隐层的权重矩阵

我们现在回来接着通过模型的定义来训练我们的这个模型。

input word和output word都会被我们进行one-hot编码。输入被one-hot编码后大多数维度上都是0(实际上仅有一个位置为1),所以向量稀疏,如果我们将一个1 x 10000的向量和10000 x 300的矩阵相乘,它会消耗相当大的计算资源,为了高效计算,隐层权重矩阵看成了一个”查找表“(lookup table),进行矩阵计算时,直接去查输入向量中取值为1的维度下对应的那些权重值。隐层的输出就是每个输入单词的“嵌入词向量”。

在这里插入图片描述

输出层

经过神经网络隐层的计算,词从一个1 x 10000的向量变成1 x 300的向量,再被输入到输出层。输出层是一个softmax回归分类器,它的每个结点将会输出一个0-1之间的值(概率),这些所有输出层神经元结点的概率之和为1。

下面是一个例子,训练样本为 (input word: “ants”, output word: “car”) 的计算示意图。
在这里插入图片描述

在这里插入图片描述在这里插入图片描述
到这里来了之后,我们就得到了Skip-Gram模型的目标函数,但是这里有计算上的问题,就是我们这里上下文取的是词库,那么计算的时间复杂度很高。解决上面的问题,目前使用了两种手段:一个是负采样,另外一个是层次化的softmax。

在这里插入图片描述
到目前为止的话,可能出现的问题就是正样本的数量非常少,然后负样本的数量非常多,这个就是样本数量极度不均衡的状态,所以我们需要从负样本里面抽选一部分出来,这样的话,我们计算的时候就更快。
下面就是对负采样的一个说明:
I want a glass of orange juice
由上面的text,我们就知道了Vocab = {I, want, a, glass, of, orange, juice} 总共7个单词,然后按照窗口是1的情况,进行一个负采样:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1
2
3
4
5
负采样算法流程
for each (w, c) in 正样本集合:
    负采样得到集合N(w):中心词是w,负采样。超参数为负样本个数
    进行梯度计算
    更新参数

在for循环里面,我们需要去进行负采样的操作。这里负采样的个数就是一个训练时候的超参数了。一般选择是5或者是10。另外为了进行加速的处理,我们源代码里面是用到了哈夫曼树的方式去进行一个提速的采样。

2、CBOW

定义:给定上下文,来预测input word(与Skip-Gram相反)

在这里插入图片描述
输入数据:输入有多个单词,每个单词与隐含层矩阵相乘后得到多个词向量,此时对多个词向量平均,再输出到输出层。在这里插入图片描述

模型加速

DNN模型最大的问题在于从隐藏层到输出的softmax层的计算量很大,因为要计算所有词的softmax概率,再去找概率最大的值==>Hierarchical Softmax
Hierarchical Softmax(霍夫曼树)提高模型训练的效率(时间复杂度O(n)>O(logn))。但是如果训练样本里的中心词w是一个很生僻的词,那么霍夫曼树向下走很久>Negative Sampling
Negative Sampling:neg个负例,每次网络更新不对所有负样本更新

(1)Hierarchical Softmax

定义:Hierarchical Softmax是一种对输出层进行优化的策略,输出层从原始模型的利用softmax计算概率值改为了利用Huffman树计算概率值。

哈夫曼树怎么来的? 将语料库中词以及词出现的频率构造一颗哈夫曼树,默认左边(编码为0)是负类,右边(编码为1)是正类,哈夫曼树的叶子节点就是语料库中的所有的词 ,词频越高的词,距离根节点就越近。

从根节点出发,到达指定叶子节点的路径是唯一的。softmax概率计算只需要沿着树形结构进行就可以。如下图所示,可以沿着霍夫曼树从根节点一直走到叶子节点的词w2

在这里插入图片描述
和之前的神经网络语言模型相比,霍夫曼树的所有内部节点就类似之前神经网络隐藏层的神经元,其中,根节点的词向量对应我们的投影后的词向量(即隐含层词向量),而所有叶子节点就类似于之前神经网络softmax输出层的神经元,叶子节点的个数就是词汇表的大小。在霍夫曼树中,隐藏层到输出层的softmax映射是沿着霍夫曼树一步步完成的,因此这种softmax取名为"Hierarchical Softmax"。

实现:在word2vec中,采用二元逻辑回归的方法,即规定沿着左子树走是负类(霍夫曼树编码1),沿着右子树走是正类(霍夫曼树编码0)。判别正类和负类的方法是使用sigmoid函数
在这里插入图片描述
优势:第一,二叉树,将计算量为V降为log2V。第二,由于使用霍夫曼树是高频的词靠近树根,高频词需要更少的时间会被找到,这符合贪心优化思想。
被划分为左子树而成为负类的概率为P(?)=1?P(+)。在某一个内部节点,要判断是沿左子树还是右子树走的标准就是看P(?)、P(+)谁的概率值大。而控制P(?)、P(+)谁的概率值大的因素一个是当前节点的词向量,另一个是当前节点的模型参数θ(需要训练)。

对于上图中的w2,如果它是一个训练样本的输出,那么我们期望对于里面的隐藏节点n(w2,1)的P(?)概率大,n(w2,2)的P(?)概率大,n(w2,3)的P(+)概率大。

回到基于Hierarchical Softmax的word2vec本身,我们的目标就是找到合适的所有节点的词向量和所有内部节点θ, 使训练样本达到最大似然。
在这里插入图片描述

(2)Negative Sampling

Word2Vec 的作者在它的第二篇论文中强调了三个创新:

将常见的单词组合(word pairs)或者词组作为单个“words”来处理。
对高频次单词进行抽样来减少训练样本的个数。
对优化目标采用“negative sampling”方法,这样每个训练样本的训练只会更新一小部分的模型权重,从而降低计算负担。
创新一:Word pairs and “phases”

作者指出,一些单词组合(或者词组)的含义和拆开以后具有完全不同的意义。比如“Boston Globe”是一种报刊的名字,而单独的“Boston”和“Globe”这样单个的单词却表达不出这样的含义。因此,在文章中只要出现“Boston Globe”,我们就应该把它作为一个单独的词来生成其词向量,而不是将其拆开。同样的例子还有“New York”,“United Stated”等。

在Google发布的模型中,它本身的训练样本中有来自Google News数据集中的1000亿的单词,但是除了单个单词以外,单词组合(或词组)又有3百万之多。

创新二:高频词抽样
在这里插入图片描述
对于“the”这种常用高频单词,存在两个问题:

当我们得到成对的单词训练样本时,(“fox”, “the”) 这样的训练样本并不会给我们提供关于“fox”更多的语义信息,因为“the”在每个单词的上下文中几乎都会出现。

由于在文本中“the”这样的常用词出现概率很大,因此我们将会有大量的(”the“,…)这样的训练样本,而这些样本数量远远超过了我们学习“the”这个词向量所需的训练样本数。

Word2Vec通过“抽样”模式来解决这种高频词问题。

基本思想:对于训练原始文本中遇到的每一个单词,它们都有一定概率被我们从文本中删掉,而这个被删除的概率与单词的频率有关。

抽样率

ωi 是一个单词,Z(ωi) 是 ωi 这个单词在所有语料中出现的频次。如果单词“peanut”在10亿规模大小的语料中出现了1000次,那么 Z(peanut) = 1000/1000000000 = 1e - 6。

有一个参数叫“sample”,这个参数代表一个阈值,默认值为0.001(在gensim包中的Word2Vec类说明中,这个参数默认为0.001,文档中对这个参数的解释为“ threshold for configuring which higher-frequency words are randomly downsampled”)。这个值越小意味着这个单词被保留下来的概率越小(即有越大的概率被我们删除)。

P(ωi) 代表着保留某个单词的概率:
在这里插入图片描述
在这里插入图片描述
图中x轴代表着 Z(ωi) ,即单词 ωi 在语料中出现频率,y轴代表某个单词被保留的概率。对于一个庞大的语料来说,单个单词的出现频率不会很大,即使是常用词,也不可能特别大。

从这个图中,我们可以看到,随着单词出现频率的增高,它被采样保留的概率越来越小,我们还可以看到一些有趣的结论:

● 当 Z(ωi) <= 0.0026 时,P(ωi) = 1.0 。当单词在语料中出现的频率小于 0.0026 时,它是 100% 被保留的,这意味着只有那些在语料中出现频率超过 0.26% 的单词才会被采样。

● 当时 Z(ωi) = 0.00746 时,P(ωi) = 0.5,意味着这一部分的单词有 50% 的概率被保留。

● 当 Z(ωi) = 1.0 时,P(ωi) = 0.033,意味着这部分单词以 3.3% 的概率被保留。

创新三:负采样(negative sampling)

训练一个神经网络意味着要输入训练样本并且不断调整神经元的权重,从而不断提高对目标的准确预测。每当神经网络经过一个训练样本的训练,它的权重就会进行一次调整。

vocabulary的大小决定了我们的Skip-Gram神经网络将会拥有大规模的权重矩阵,所有的这些权重需要通过我们数以亿计的训练样本来进行调整,这是非常消耗计算资源的,并且实际中训练起来会非常慢。

negative sampling解决了这个问题,它是用来提高训练速度并且改善所得到词向量的质量的一种方法。不同于原本每个训练样本更新所有的权重,负采样每次让一个训练样本仅仅更新一小部分的权重,这样就会降低梯度下降过程中的计算量。

当我们用训练样本 ( input word: “fox”,output word: “quick”) 来训练我们的神经网络时,“ fox”和“quick”都是经过one-hot编码的。如果我们的vocabulary大小为10000时,在输出层,我们期望对应“quick”单词的那个神经元结点输出1,其余9999个都应该输出0。在这里,这9999个我们期望输出为0的神经元结点所对应的单词我们称为“negative” word。

当使用负采样时,我们将随机选择一小部分的negative words(比如选5个negative words)来更新对应的权重。我们也会对我们的“positive” word进行权重更新(在我们上面的例子中,这个单词指的是”quick“)。

在论文中,作者指出指出对于小规模数据集,选择5-20个negative words会比较好,对于大规模数据集可以仅选择2-5个negative words。

隐层-输出层拥有300 x 10000的权重矩阵。如果使用了负采样的方法我们仅仅去更新我们的positive word-“quick”的和我们选择的其他5个negative words的结点对应的权重,共计6个输出神经元,相当于每次只更新 300 x 6 = 1800 个权重。对于3百万的权重来说,相当于只计算了0.06%的权重,这样计算效率就大幅度提高。

选择negative words

使用“一元模型分布(unigram distribution)”来选择“negative words”。

一个单词被选作negative sample的概率跟它出现的频次有关,出现频次越高的单词越容易被选作negative words。

代码中的公式实现如下:
在这里插入图片描述

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

公式中开3/4的根号完全是基于经验的,论文中提到这个公式的效果要比其它公式更加出色。你可以在google的搜索栏中输入“plot y = x^(3/4) and y = x”,然后看到这两幅图(如下图),仔细观察x在[0,1]区间内时y的取值,x^(3/4) 有一小段弧形,取值在 y = x 函数之上。
在这里插入图片描述

3、词向量的评估方式

训练得到词向量之后,我们可以采用三种方法去进行词向量的好坏的评估:
1、可视化的方式评估:我们将我们学习到的100/200/300维的词向量通过降维算法TSNE降到2为空间里面。然后通过可视化的方式看出词向量的好坏。
在这里插入图片描述
2、计算词向量的相似度或者相关性去评估。这种评估的方式就需要用到人工去标记相似度。
3、通过类比来评估。
在这里插入图片描述

4. 弊端

虽然word2vec思想非常的牛逼,但是也存在了很多的缺点和问题:
1、学习出来的词向量是固定的。这就导致了在任何的语境里面它表达的意思都是固定的了。实际上我们希望得到的是在不同语境下面得到不同的词向量。所以后来就有了ELMo和BERT模型了。
2、窗口的长度是有限的。解决的方式就通过language model了。
3、无法有效的学习低频词汇和未登陆词。解决的方法就是subword embedding了。
4、预测不具备uncertainty。因为我们的词向量都是固定住了的。但是不同语境下面的词语的意义不同。解决的方式就是采用高斯embedding了。
5、可解释性不够。这个就是深度学习的一个通病了。

大家可能会觉得很乱,其实是我搜刮了许多资源然后整合在一起的,目的是为了更好更深入的理解这方面的知识,而不是浅尝辄止,这也是为了便于后期进行不断复习,这样就不用搜来搜去了,恳请读者谅解啦!喜欢的可以收藏关注我,我会陆陆续续发布机器学习/推荐系统/自然语言处理方面的知识,争取知识全覆盖!全是为今年9月的面试做准备!大家共勉,一起加油!