导读
本文简单的介绍了Google 于 2013 年开源推出的一个用于获取 word vector 的工具包(word2vec),并且简单的介绍了其中的两个训练模型(Skip-gram,CBOW),以及两种加速的方法(Hierarchical Softmax,Negative Sampling)。
一 、word2vec
word2vec最初是由Tomas Mikolov 2013年在ICLR发表的一篇文章 Efficient Estimation of Word Representations in Vector Space [ https://arxiv.org/pdf/1301.3781.pdf ] , 并且开源了代码,作用是将所有词语投影到K维的向量空间,每个词语都可以用一个K维向量表示。由于它简洁,高效的特点,引起了人们的广泛关注,并应用在很多NLP任务中,用于训练相应的词向量。
二 、Skip-Gram model and CBOW model

CBOW和Skip-Gram的结构图,从图中能够看出,两个模型都包含三层结构,分别是输入层,投影层,输出层;CBOW模型是在已知当前词上下文context的前提下预测当前词w(t),类似阅读理解中的完形填空;而Skip-Gram模型恰恰相反,是在已知当前词w(t)的前提下,预测上下文context。CBOW和Skip-Gram两个模型,word2vec给出了两套框架,用于训练快而好的词向量,他们分别是Hierarchical Softmax 和 Negative Sampling,下文将介绍这两种加速方法。
三 、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对应的模型参数以及每个词的词向量。word2vec采样的方法并不复杂,如果词汇表的大小为V,那么我们就将一段长度为1的线段分成V份,每份对应词汇表中的一个词。当然每个词对应的线段长度是不一样的,高频词对应的线段长,低频词对应的线段短(根据词频采样,出现的次数越多,负采样的概率越大)。每个词w的线段长度由下式决定: 

四 、Hierarchical Softmax
CBOW模型来说,就是把上下文词向量加和,然而,对于Skip-Gram模型来说就是简单的传值。
五 、Demo
c++,pytorch版本,以及word2vec源码版本及其源码注释版。pytorch-version: https://github.com/bamtercelboo/pytorch_word2veccpp-version: https://github.com/bamtercelboo/word2vec/tree/master/word2vecword2vec-source-version:word2vec.googlecode.com/svn/trunk/word2vec-annotation-version: https://github.com/tankle/word2vec六 、Experiment Result
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: 10dim: 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 的训练时间相差不大。References
[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 原理)