标签:1.3 文章 nal lov arch 上下文 php run 组成
这种方法把每个词表示为一个很长的向量。这个向量的维度是词表大小,其中绝大多数元素为 0,只有一个维度的值为 1,这个维度就代表了当前的词。
假如词表是:[气温、已经、开始、回升、了],那么词的词向量分别可以是[1,0,0,0,0],[0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1]。这样的表示方法简单容易理解,而且编程也很容易实现,只需要取对应的索引就能够完成,已经可以解决相当一部分NLP的问题,但是仍然存在不足,即词向量与词向量之间都是相互独立的;我们都知道,词与词之间是有一定的联系的,我们无法通过这种词向量得知两个词在语义上是否相似,并且如果词表非常大的情况下,每个词都是茫茫 0 海中的一个 1,这种高维稀疏的表示也有可能引发维度灾难。为了解决上述问题,就有了词向量的第二种表示方法。
word2vec就是通过这种方法将词表示为向量,即通过训练将词表示为限定维度K的实数向量,这种非稀疏表示的向量很容易求它们之间的距离(欧式、余弦等),从而判断词与词语义上的相似性,也就解决了上述one-hot方法表示两个词之间的相互独立的问题。
不过Distributed representation并不是word2vec诞生才有的, Distributed representation 最早是 Hinton 在 1986 年的论文《Learning distributed representations of concepts》中提出的。虽然这篇文章没有说要将词做 Distributed representation,但至少这种先进的思想在那个时候就在人们的心中埋下了火种,到 2000 年之后开始逐渐被人重视。 word2vec之所以会产生这么大的影响,是因为它采用了简化的模型,使得训练速度大为提升,让word embedding这项技术(也就是词的distributed representation)变得实用,能够应用在很多的任务上。
上图示CBOW
和Skip-Gram
的结构图,从图中能够看出,两个模型都包含三层结构,分别是输入层
,投影层
,输出层
;CBOW模型是在已知当前词上下文context的前提下预测当前词w(t),类似阅读理解中的完形填空;而Skip-Gram模型恰恰相反,是在已知当前词w(t)的前提下,预测上下文context。
对于CBOW
和Skip-Gram
两个模型,word2vec给出了两套框架,用于训练快而好的词向量,他们分别是Hierarchical Softmax
和 Negative Sampling
,下文将介绍这两种加速方法。
Negative Sampling(NEG)
是Tomas Mikolov在Distributed Representations of Words and Phrasesand their Compositionality中提出的,它是噪声对比损失函数NCE
(Noise Contrastive Estimation)的简化版本,用于提高训练速度和提升词向量质量。w
,它周围上下文共有2c个词,记为context(w)
。由于这个中心词w
,的确和context(w)
相关存在,因此它是一个真实的正例
。通过Negative Sampling
进行负采样,我们得到neg(负采样的个数)个和w不同的中心词wi
,i=1,2,..neg,这样context(w)和wi就组成了neg个并不真实存在的负例
。利用这一个正例和neg个负例,我们进行二元逻辑回归(可以理解成一个二分类问题
),得到负采样对应每个词wi对应的模型参数以及每个词的词向量。我们来看一下如何进行负采样,得到neg个负例。word2vec
采样的方法并不复杂,如果词汇表的大小为V,那么我们就将一段长度为1的线段分成V份,每份对应词汇表中的一个词。当然每个词对应的线段长度是不一样的,高频词对应的线段长,低频词对应的线段短(根据词频采样,出现的次数越多,负采样的概率越大)。每个词w的线段长度由下式决定:
-
在采样前,我们将这段长度为1的线段划分成M等份,这里M>>V,这样能够保证每个词对应的线段都会划分成对应的小块,而M份中每一份都会落在某一个词对应的线段上(如下图),采样的时候,我们只需要随机生成neg个数,对应的位置就是采样的负例词。
CBOW
模型来说,就是把上下文词向量加和,然而,对于Skip-Gram
模型来说就是简单的传值。一般得到哈夫曼树后我们会对叶子节点进行哈夫曼编码,由于权重高的叶子节点越靠近根节点,而权重低的叶子节点会远离根节点,这样我们的高权重节点编码值较短,而低权重值编码值较长。这保证的树的带权路径最短,也符合我们的信息论,即我们希望越常用的词(词频越高的词)拥有更短的编码,一般的编码规则是左0右1,但是这都是人为规定的,word2vec中正好采用了相反的编码规则,同时约定左子树的权重不小于右子树的权重。
在这里提供了几份代码,包括我实现的c++
,pytorch
版本,以及word2vec源码版本及其源码注释版。
pytorch-version: https://github.com/bamtercelboo/pytorch_word2vec
cpp-version: https://github.com/bamtercelboo/word2vec/tree/master/word2vec
word2vec-source-version:word2vec.googlecode.com/svn/trunk/
word2vec-annotation-version: https://github.com/tankle/word2vec
enwiki-20150112_text.txt
(12G)上进行了测试,测试采用的是根据这篇论文 Community Evaluation and Exchange of Word Vectors at wordvectors.org 提供的方法与site(http://www.wordvectors.org/index.php),计算词之间的相似度。结果如下图所示:由于 pytorch-version
训练速度慢并且demo还没有完善,所以仅在 Cpp-version
和 word2vec源码(C-version
)进行了测试对比。以上对比试验均是在相同的参数设置下完成的。
model: skip-gram
, loss: Negative Sampling
,neg: 10
dim: 100
, lr: 0.025
, windows size: 5
,minCount: 10
, iters: 5
Cpp-version
和C-version
训练出来的词向量都能达到一样的性能,甚至还比C-version
训练出来词向量稍高一点。enwiki-20150112_text.txt
上取出大约1G的文件,进行重新训练两份词向量,看一下训练时间,下图是实验结果。Cpp-version
和C-version
的训练时间相差不大。[1] Efficient Estimation of Word Representations in Vector Space
[2] Learning distributed representations of concepts
[3] Distributed Representations of Words and Phrasesand their Compositionality
[4] Community Evaluation and Exchange of Word Vectors at wordvectors.org
[5] https://blog.csdn.net/itplus/article/details/37998797(word2vec 中的数学原理详解)
[6] http://www.cnblogs.com/pinard/p/7249903.html(word2vec 原理)
标签:1.3 文章 nal lov arch 上下文 php run 组成
原文地址:https://www.cnblogs.com/bamtercelboo/p/8933367.html