word2vec原理(一) CBOW与Skip-Gram模型基础

 word2vec是google在2013年推出的一个NLP工具,它的特色是将全部的词向量化,这样词与词之间就能够定量的去度量他们之间的关系,挖掘词之间的联系。虽然源码是开源的,可是谷歌的代码库国内没法访问,所以本文的讲解word2vec原理以Github上的word2vec代码为准。本文关注于word2vec的基础知识。git

1. 词向量基础

    用词向量来表示词并非word2vec的独创,在好久以前就出现了。最先的词向量是很冗长的,它使用是词向量维度大小为整个词汇表的大小,对于每一个具体的词汇表中的词,将对应的位置置为1。好比咱们有下面的5个词组成的词汇表,词"Queen"的序号为2, 那么它的词向量就是(0,1,0,0,0)(0,1,0,0,0)。一样的道理,词"Woman"的词向量就是(0,0,0,1,0)(0,0,0,1,0)。这种词向量的编码方式咱们通常叫作1-of-N representation或者one hot representation.github

     One hot representation用来表示词向量很是简单,可是却有不少问题。最大的问题是咱们的词汇表通常都很是大,好比达到百万级别,这样每一个词都用百万维的向量来表示简直是内存的灾难。这样的向量其实除了一个位置是1,其他的位置所有都是0,表达的效率不高,能不能把词向量的维度变小呢?算法

    Dristributed representation能够解决One hot representation的问题,它的思路是经过训练,将每一个词都映射到一个较短的词向量上来。全部的这些词向量就构成了向量空间,进而能够用普通的统计学的方法来研究词与词之间的关系。这个较短的词向量维度是多大呢?这个通常须要咱们在训练时本身来指定。网络

    好比下图咱们将词汇表里的词用"Royalty","Masculinity", "Femininity"和"Age"4个维度来表示,King这个词对应的词向量多是(0.99,0.99,0.05,0.7)(0.99,0.99,0.05,0.7)。固然在实际状况中,咱们并不能对词向量的每一个维度作一个很好的解释。数据结构

 

    有了用Dristributed representation表示的较短的词向量,咱们就能够较容易的分析词之间的关系了,好比咱们将词的维度降维到2维,有一个有趣的研究代表,用下图的词向量表示咱们的词时,咱们能够发现:函数

King→−Man→+Woman→=Queen→King→−Man→+Woman→=Queen→工具

     可见咱们只要获得了词汇表里全部词对应的词向量,那么咱们就能够作不少有趣的事情了。不过,怎么训练获得合适的词向量呢?一个很常见的方法是使用神经网络语言模型。优化

2. CBOW与Skip-Gram用于神经网络语言模型

    在word2vec出现以前,已经有用神经网络DNN来用训练词向量进而处理词与词之间的关系了。采用的方法通常是一个三层的神经网络结构(固然也能够多层),分为输入层,隐藏层和输出层(softmax层)。google

    这个模型是如何定义数据的输入和输出呢?通常分为CBOW(Continuous Bag-of-Words 与Skip-Gram两种模型。编码

    CBOW模型的训练输入是某一个特征词的上下文相关的词对应的词向量,而输出就是这特定的一个词的词向量。好比下面这段话,咱们的上下文大小取值为4,特定的这个词是"Learning",也就是咱们须要的输出词向量,上下文对应的词有8个,先后各4个,这8个词是咱们模型的输入。因为CBOW使用的是词袋模型,所以这8个词都是平等的,也就是不考虑他们和咱们关注的词之间的距离大小,只要在咱们上下文以内便可。

    这样咱们这个CBOW的例子里,咱们的输入是8个词向量,输出是全部词的softmax几率(训练的目标是指望训练样本特定词对应的softmax几率最大),对应的CBOW神经网络模型输入层有8个神经元,输出层有词汇表大小个神经元。隐藏层的神经元个数咱们能够本身指定。经过DNN的反向传播算法,咱们能够求出DNN模型的参数,同时获得全部的词对应的词向量。这样当咱们有新的需求,要求出某8个词对应的最可能的输出中心词时,咱们能够经过一次DNN前向传播算法并经过softmax激活函数找到几率最大的词对应的神经元便可。

    
    Skip-Gram模型和CBOW的思路是反着来的,即输入是特定的一个词的词向量,而输出是特定词对应的上下文词向量。仍是上面的例子,咱们的上下文大小取值为4, 特定的这个词"Learning"是咱们的输入,而这8个上下文词是咱们的输出。

    这样咱们这个Skip-Gram的例子里,咱们的输入是特定词, 输出是softmax几率排前8的8个词,对应的Skip-Gram神经网络模型输入层有1个神经元,输出层有词汇表大小个神经元。隐藏层的神经元个数咱们能够本身指定。经过DNN的反向传播算法,咱们能够求出DNN模型的参数,同时获得全部的词对应的词向量。这样当咱们有新的需求,要求出某1个词对应的最可能的8个上下文词时,咱们能够经过一次DNN前向传播算法获得几率大小排前8的softmax几率对应的神经元所对应的词便可。

    以上就是神经网络语言模型中如何用CBOW与Skip-Gram来训练模型与获得词向量的大概过程。可是这和word2vec中用CBOW与Skip-Gram来训练模型与获得词向量的过程有不少的不一样。

    word2vec为何 不用现成的DNN模型,要继续优化出新方法呢?最主要的问题是DNN模型的这个处理过程很是耗时。咱们的词汇表通常在百万级别以上,这意味着咱们DNN的输出层须要进行softmax计算各个词的输出几率的的计算量很大。有没有简化一点点的方法呢?

3. word2vec基础之霍夫曼树

    word2vec也使用了CBOW与Skip-Gram来训练模型与获得词向量,可是并无使用传统的DNN模型。最早优化使用的数据结构是用霍夫曼树来代替隐藏层和输出层的神经元,霍夫曼树的叶子节点起到输出层神经元的做用,叶子节点的个数即为词汇表的小大。 而内部节点则起到隐藏层神经元的做用。

    具体如何用霍夫曼树来进行CBOW和Skip-Gram的训练咱们在下一节讲,这里咱们先复习下霍夫曼树。

    霍夫曼树的创建其实并不难,过程以下:

    输入:权值为(w1,w2,...wn)(w1,w2,...wn)的nn个节点

    输出:对应的霍夫曼树

    1)将(w1,w2,...wn)(w1,w2,...wn)看作是有nn棵树的森林,每一个树仅有一个节点。

    2)在森林中选择根节点权值最小的两棵树进行合并,获得一个新的树,这两颗树分布做为新树的左右子树。新树的根节点权重为左右子树的根节点权重之和。

    3) 将以前的根节点权值最小的两棵树从森林删除,并把新树加入森林。

    4)重复步骤2)和3)直到森林里只有一棵树为止。

    下面咱们用一个具体的例子来讲明霍夫曼树创建的过程,咱们有(a,b,c,d,e,f)共6个节点,节点的权值分布是(16,4,8,6,20,3)。

    首先是最小的b和f合并,获得的新树根节点权重是7.此时森林里5棵树,根节点权重分别是16,8,6,20,7。此时根节点权重最小的6,7合并,获得新子树,依次类推,最终获得下面的霍夫曼树。

    那么霍夫曼树有什么好处呢?通常获得霍夫曼树后咱们会对叶子节点进行霍夫曼编码,因为权重高的叶子节点越靠近根节点,而权重低的叶子节点会远离根节点,这样咱们的高权重节点编码值较短,而低权重值编码值较长。这保证的树的带权路径最短,也符合咱们的信息论,即咱们但愿越经常使用的词拥有更短的编码。如何编码呢?通常对于一个霍夫曼树的节点(根节点除外),能够约定左子树编码为0,右子树编码为1.如上图,则能够获得c的编码是00。

    在word2vec中,约定编码方式和上面的例子相反,即约定左子树编码为1,右子树编码为0,同时约定左子树的权重不小于右子树的权重。

    咱们在下一节的Hierarchical Softmax中再继续讲使用霍夫曼树和DNN语言模型相比的好处以及如何训练CBOW&Skip-Gram模型。

相关文章
相关标签/搜索