1.什么是word2vector?
我们先来看一个问题,假如有一个句子 " the dog bark at the mailman"。
假如用向量来表示每个单词,我们最先想到的是用one hot 编码的方式来表达每个单词,具体来说。
the 可以表示为 [1,0,0,0,0]
dog 可以表示为 [0,1,0,0,0]
bark 可以表示为 [0,0,1,0,0]
at 可以表示为[0,0,0,1,0]
mailman可以表示为[0,0,0,0,1]
我们可以看到每个单词其实就用一个向量来表示。我们发现几个问题:
第一,每个向量之间相互正交的(内积为0)。也就是说词与词之间是没有任何关系的。
第二,每个词的向量维度和不同词的个数有关。比方说,在上面的这个句子里,有5个不同的词,所以向量的维度是5。然而往往现实中,一篇文章的中不同的词的个数是很多的。这样,向量的维度会非常的高。
这种对词的向量表示方法存在着以上的问题,忽略了词与词之间的关系(比如说,dog和cat都是动物,并非完全无关系)。维度太高的向量作为模型输入会导致模型变的复杂(模型复杂需要更多的训练样本才能够收敛)
那么是否存在一种更加合理的对词的用向量的表达方式呢?有的,其实就是word embedding。
word embedding说的简单一点其实就是将高维稀疏的向量降维成稠密的低维向量。(一种高维到低维的映射)
那么如和实现word embedding?
w2v其实就是一种高效实现word embedding的工具。
所以,如果用一句话来描述word2vector的话你会怎么描述?简单的说,我觉得可以这么说w2v其实是一种将单词转化向量的工具。这一种向量的其实是对单词更有效的表达。
2.word2vector怎么做?
上面提到为了得到表达能力更强的词向量,我们可以进行word embedding。那么w2v是如何实现word embedding的呢?
下面我总结一下主要的思想,详细的原理可以参考以上给的三篇文章。
2.1 Skip-Gram& CBOW
在介绍w2v模型之前,先介绍两个模型。一个是Skip-Gram和CBOW(Continuous Bag-of-Words)。
首先看CBOW,它的做法是,将一个词所在的上下文中的词作为输入,而那个词本身作为输出。
再来看Skip-Gram,它的做法和CBOW相反,将一个词所在的上下文中的词作为输出,而词本身作为输入。(下面有例子说明)
另外,我们介绍这两个模型都会涉及到的一个重要参数。
window_size:窗口大小。
举一个例子,还是上面那句话:" the dog bark at the mailman"
假设window_size取1时,利用CBOW模型可以得到:
([the,bark],dog)
([dog,at],bark)
([bark,the],at)
([at,mailman],the)
一共4组数据。
同样滴,假设window_size还是1,利用Skip-Gram模型可以得到:
(dog,[the,bark])
(bark,[dog,at])
(at,[bark,the])
(the,[at,mailman])
对于每组数据会稍微做一下处理。比如对于第一组 (dog,[the,bark])一般处理成
(dog,the),(dog,bark)。类似有:
(bark,dog),(bark,at),(at,bark),(at,the),(the,at),(the,mailman)共8组数据。
2.2 word2vector
下面就可以直接介绍如何进行w2v,上面提到w2v可以看作是一个将高维空间映射到低维空间的过程,用一个单层神经网络就可以实现这种功能(和自编码器有点类似其实)。
对于CBOW,假如还是上面的句子,训练数据是([the,brak],dog)那么网络的输入输出如下图所示:
这里有几个细节:
1.上面介绍CBOW模型的时有一个模型的结构图,其中的SUM意思其实就是把各个上下文的词one-hot后的向量相加。
比如对于the的向量是[1,0,0,0,0]。bark向量是[0,0,1,0,0],SUM之后就是[1,0,1,0,0]这就是网络的输入。
输出就是[0,1,0,0,0]-dog
2.我们所谓的embedding vetcor其实就第二个红框里的线,每一根线其实就是一个权值。
3.第二个框里的红线其实就是dog这个单词的embedding结果(由5维变成3维)
4.这个单层NN训练完毕之后有用的部分就是embedding martrix这部分,其大小为 输入个数(词汇表长度)×embedding后的维度。类似对于Skip-Gram模型有:
当取训练数据(dog,bark)时,网络结构如上图,对比上面的CBOW最大的不同其实就是在于输入数据。
2.3 其他问题
上面只是关于w2v一个非常浅显方面的介绍,其实还有比如 负采样(negative sampling),层级SoftMax以及代码解读等,自己尝试写了几次,但是感觉都并没有太多的新东西,也没有什么犀利的见解。所以就没贴上来,下面只是简单概括一下负采样。
1.为什么需要负采样?
其实理由很简单,比如对于CBOW模型,已经知道词w的上下文Context(w)。如果希望预测词w,因此,当给定Context(w)时,词w就是一个正样本,其他词就是负样本。在上面的网络里面我们可以容易地看出输出有多少个就是词汇表里有多少个词。通常来说,我们的词汇表是非常庞大的,对于某一个词w,每个负样本逐个去算一次计算的代价是很大的。
-------------------------------------------------------------------------------------------------------------------------------------------------------------
网上已经有许多对w2v的介绍了,这里只是做一个简单的概括。下面这篇文章我认为是关于W2V写的比较好的文章:
另外一篇是关于Skip-Gram和CBow的介绍。
逻辑比较清晰的综述文章:
数学原理很清晰很短的一篇文章(也有关于负采样的简单说明)
---------------------------------------------------------------------------------------------------------------------------------------------------------------
仅为学习记录之用,侵删。
参考:https://blog.csdn.net/qq_22238533/article/details/78534743
https://www.leiphone.com/news/201706/PamWKpfRFEI42McI.html