word2vec 训练程序说明

word2vec training procedure clarification

我正在尝试学习 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

The basic Skip-gram formulation defines p(w_t+j |w_t) using the softmax function:

where v_w and v′_w are the “input” and “output” vector representations of w, and W is the number of words in the vocabulary.

据我了解,skip-gram 模型涉及两个矩阵(我称它们为 IO),它们是"input/center" 个词的向量表示和 "output/context" 个词的向量表示。假设 d = 2(向量维度或 'size' 作为它在 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 ]]

现在,如果我想计算 "dogs" 这个词出现在 "cats" 的上下文中的概率,我应该这样做

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)

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

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

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

O 输出矩阵——更恰当地理解为神经网络隐藏层到多个输出节点的权重——在使用 'negative sampling' ('NS') 或 'hierarchical softmax' ('HS') 训练。

实际上 IO 都是 len(vocab) 行和 向量大小 列。 (IWord2Vec model 实例的 model.wv.syn0 数组;O 是它的 model.syn1neg NS 中的数组或 HS 中的 model.syn1。)

我发现 NS 更容易思考:每个可预测的词对应一个输出节点。对于 (context)-indicates->(word) 的训练数据,训练会尝试将该词的节点值推向 1.0,并将其他随机选择的词节点值推向 0.0。

在 HS 中,每个单词都由输出节点的一小部分的霍夫曼代码表示——那些 'points' 被驱动为 1.0 或 0.0 以使网络在(context)-indicates->(word) 示例。

只有 I 矩阵,初始单词值,在开始时被随机分配到低幅度向量。 (隐藏到输出的权重 O 为零。)

(2) 是的,这会训练一些东西 - 请注意,微型玩具大小的示例不一定会生成从 word2vec 中赋值的有用的矢量坐标星座。

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

也就是说,similarity() 而不是 要求模型进行预测,它是按键检索学习的单词并比较这些向量。 (最新版本的 gensim 确实有一个 predict_output_word() 函数,但它只能在 NS 模式下工作,并且进行预测并不是 word2vec 的真正意义,许多实现不提供任何预测 API全部。相反,重点是在训练期间使用那些尝试的预测来归纳出对各种其他任务有用的词向量。)

但即使您正在阅读预测,在 'cats' 的上下文中,'cats' 可能仍然是来自模型的合理但糟糕的预测。将大词汇表强制到 'dense' 嵌入的较小维度的本质是压缩——模型别无选择,只能将相关词聚集在一起,因为没有足够的内部复杂性(可学习参数)来简单地记住输入的所有细节. (在大多数情况下,这是一件好事,因为它会产生可泛化的模式,而不仅仅是训练语料库的过度拟合特性。)

单词 'cats' 将接近 'dogs' 和 'pets' – 因为它们都与相似的单词或彼此同时出现。因此,模型将被迫为每个模型做出类似的输出预测,因为它们的输入向量变化不大。并且可能会做出一些在逻辑语言使用中毫无意义的预测——比如重复的单词——但这只是因为与其他加权替代方案相比,在整个训练集中采用更大的误差仍然会产生更小的误差。