word2vec培训程序澄清

时间:2017-09-06 00:00:34

标签: gensim word2vec

我正在尝试学习word2vec中的skip-gram模型,但是我对一些基本概念感到困惑。首先,这是我目前对模型动机的理解。我正在使用Python gensim

这里我有三个句子的语料库。

sentences = [
    ['i', 'like', 'cats', 'and', 'dogs'],
    ['i', 'like', 'dogs'],
    ['dogs', 'like', 'dogs']
]

由此,我可以确定我的词汇V = ['and', 'cats', 'dogs', 'i', 'like']

跟随Tomas Mikolov(及其他人)this paper

  

基本的Skip-gram公式使用softmax定义p(w_t + j | w_t)   功能:

skipgram

  

其中v_w和v'_w是“输入”和“输出”矢量表示   w是W,W是词汇中的单词数。

根据我的理解,skip-gram模型涉及两个矩阵(我将它们称为 I O ),它们是“输入/中心”的向量表示单词和“输出/上下文”单词的向量表示。假设d = 2(向量维度或'大小',因为它在genism中被称为), I 应该是2x5矩阵, O 应该是5x2矩阵。在训练过程开始时,这些矩阵充满了随机值(是吗?)。所以我们可能有

import numpy as np
np.random.seed(2017)

I = np.random.rand(5,2).round(2)  # 5 rows by 2 cols
[[ 0.02  0.77] # and
 [ 0.45  0.12] # cats
 [ 0.93  0.65] # dogs
 [ 0.14  0.23] # i
 [ 0.23  0.26]] # like

O = np.random.rand(2,5).round(2)  # 2 rows by 5 cols
  #and  #cats #dogs  #i   #like 
[[ 0.11  0.63  0.39  0.32  0.63]
 [ 0.29  0.94  0.15  0.08  0.7 ]]

现在,如果我想计算“狗”这个词出现在“猫”语境中的可能性我应该做

exp([0.39,0.15] * [0.45 0.12])/(...)=(0.1125)/(...)

关于这个问题:

  1. 到目前为止,我对算法的理解是否正确?
  2. 使用genism,我可以使用
  3. 训练这个数据的模型

    import gensim
    model = gensim.models.Word2Vec(sentences, sg = 1, size=2, window=1, min_count=1)
    model.wv['dogs']  # array([ 0.06249372,  0.22618999], dtype=float32)
    

    对于给定的数组,是输入矩阵或输出矩阵中“dog”的向量?有没有办法在最终模型中查看两个矩阵?

    1. 为什么model.wv.similarity('cats','cats') = 1?我认为这应该接近于0,因为数据表明单词“cats”不太可能出现在“猫”这个词的上下文中。

1 个答案:

答案 0 :(得分:1)

(1)一般来说,是的,但是:

O 输出矩阵 - 更准确地理解为从神经网络的隐藏层到多个输出节点的权重 - 无论是否使用“否定”都会有不同的解释采样' (' NS')或'分层softmax' (' HS')培训。

在实践中, I O 都是 len(词汇)行和矢量大小列。 (Word2Vec model实例的model.wv.syn0数组; O 是其model.syn1neg数组NS或HS中的model.syn1。)

我发现NS更容易思考:每个可预测的单词对应一个输出节点。对于训练数据,其中(上下文) - 指示 - >(单词),训练试图将该单词的节点值驱动为1.0,并将其他随机选择的单词节点值指向0.0。

在HS中,每个单词由输出节点的一小部分的霍夫曼代码表示 - 那些'点'被驱动到1.0或0.0以使网络在(上下文) - 指示 - >(单词)示例之后更多地指示单个单词。

只有 I 矩阵(初始字值)在开始时被随机化为低幅度矢量。 (隐藏到输出的权重 O 保留为零。)

(2)是的,那将训练一些东西 - 只需要注意,小玩具大小的例子不一定能产生从word2vec估价的有用的矢量坐标星座。

(3)注意,model.similarity('cats', 'cats')实际上是检查这两个词的(输入)向量之间的余弦相似性。那些是相同的词,因此它们在定义上具有相同的向量,并且相同向量之间的相似性是1.0。

也就是说,similarity() 向模型询问预测,它通过密钥检索学习的单词并比较这些向量。 (gensim的最新版本确实具有predict_output_word()功能,但它仅适用于NS模式,并且预测并不是word2vec的重点,并且许多实现都没有提供任何预测API相反,重点是在训练期间使用那些尝试的预测来诱导对任何其他任务都有用的单词向量。)

但即使你正在阅读预测,“猫”也是如此。在“猫”的背景下,该模型可能仍然是一个合理的,虽然不好的预测。强迫大词汇量进入“密集”的较小维度的本质。嵌入是压缩 - 模型别无选择,只能将相关的单词聚集在一起,因为没有足够的内部复杂性(可学习的参数)来简单地记住输入的所有细节。 (在大多数情况下,这是一件好事,因为它会产生一般化的模式,而不仅仅是训练语料库的过度拟合特征。)

“猫”这个词。将会近距离接近狗狗。和宠物' - 因为它们都是用相似的词或彼此共同出现的。因此,模型将被迫对每个模型进行类似的输出预测,因为它们的输入向量变化不大。并且可以制作一些在逻辑语言使用中无意义的预测 - 如重复单词 - 但仅仅因为与其他加权替代方案相比,在整个训练集中采用更大的误差仍然会产生更少的误差。