为什么词嵌入实际上是向量?

Why are word embedding actually vectors?

对不起我的天真,但我不明白为什么作为 NN 训练过程 (word2vec) 结果的词嵌入实际上是向量。

Embedding是降维的过程,在训练过程中NN将单词的1/0数组缩减为更小的数组,这个过程没有应用向量算法。

因此我们得到的只是数组而不是向量。为什么我应该将这些数组视为向量?

虽然我们得到了向量,但为什么每个人都将它们描述为来自原点 (0,0) 的向量?

再次抱歉,如果我的问题看起来很愚蠢。

the process does nothing that applies vector arithmetic

训练过程与向量运算无关,但是当数组产生时,结果发现它们具有很好的性质,所以可以想到"word linear space".

例如,在此 space 中哪些词的嵌入最接近给定词?

换句话说,意思相近的词就是云。这是二维 t-SNE 表示:

再举个例子,"man"和"woman"的距离和"uncle"和"aunt"的距离很接近:

因此,您的算术相当合理:

W("woman") − W("man") ≃ W("aunt") − W("uncle")
W("woman") − W("man") ≃ W("queen") − W("king")

所以称它们为向量并不牵强。所有图片均来自this wonderful post,非常推荐阅读

每个单词映射到 d-dimension space 中的一个点(d 通常为 300 或 600,但不是必需的),因此它被称为向量(d-dim space 中的每个点只不过是 d-dim space 中的一个向量。

这些点有一些很好的属性(具有相似含义的词往往彼此靠近)[使用 2 词向量之间的余弦距离来测量接近度]

什么是嵌入?

Word embedding is the collective name for a set of language modeling and feature learning techniques in natural language processing (NLP) where words or phrases from the vocabulary are mapped to vectors of real numbers.

Conceptually it involves a mathematical embedding from a space with one dimension per word to a continuous vector space with much lower dimension.

(来源:https://en.wikipedia.org/wiki/Word_embedding

什么是 Word2Vec?

Word2vec is a group of related models that are used to produce word embeddings. These models are shallow, two-layer neural networks that are trained to reconstruct linguistic contexts of words.

Word2vec takes as its input a large corpus of text and produces a vector space, typically of several hundred dimensions, with each unique word in the corpus being assigned a corresponding vector in the space.

Word vectors are positioned in the vector space such that words that share common contexts in the corpus are located in close proximity to one another in the space.

(来源:https://en.wikipedia.org/wiki/Word2vec

什么是数组?

In computer science, an array data structure, or simply an array, is a data structure consisting of a collection of elements (values or variables), each identified by at least one array index or key.

An array is stored so that the position of each element can be computed from its index tuple by a mathematical formula.

The simplest type of data structure is a linear array, also called one-dimensional array.

什么是向量/矢量space?

A vector space (also called a linear space) is a collection of objects called vectors, which may be added together and multiplied ("scaled") by numbers, called scalars.

Scalars are often taken to be real numbers, but there are also vector spaces with scalar multiplication by complex numbers, rational numbers, or generally any field.

The operations of vector addition and scalar multiplication must satisfy certain requirements, called axioms, listed below.

(来源:https://en.wikipedia.org/wiki/Vector_space

向量和数组有什么区别?

首先,词嵌入中的向量不完全是编程语言的数据结构(所以它不是Arrays vs Vectors: Introductory Similarities and Differences)。

在编程上,词嵌入向量某种实数数组(数据结构)(即标量)

从数学上讲,任何一维或多维填充实数的元素都是 tensor。矢量是标量的单一维度。


回答 OP 问题:

为什么词嵌入实际上是向量?

By definition, word embeddings are vectors (see above)

为什么我们将单词表示为实数向量?

To learn the differences between words, we have to quantify the difference in some manner.

想象一下,如果我们将这些“智能”数字分配给单词:

>>> semnum = semantic_numbers = {'car': 5, 'vehicle': 2, 'apple': 232, 'orange': 300, 'fruit': 211, 'samsung': 1080, 'iphone': 1200}
>>> abs(semnum['fruit'] - semnum['apple'])
21
>>> abs(semnum['samsung'] - semnum['apple'])
848

我们看到 fruitapple 之间的距离很近,但 samsungapple 不是。在这种情况下,单词的单个数字“特征”能够捕获有关单词含义的一些信息,但并不完全。

想象一下,我们对每个单词(即向量)有两个实数值:

>>> import numpy as np
>>> semnum = semantic_numbers = {'car': [5, -20], 'vehicle': [2, -18], 'apple': [232, 1010], 'orange': [300, 250], 'fruit': [211, 250], 'samsung': [1080, 1002], 'iphone': [1200, 1100]}

要计算差异,我们可以这样做:

>>> np.array(semnum['apple']) - np.array(semnum['orange'])
array([-68, 761])

>>> np.array(semnum['apple']) - np.array(semnum['samsung'])
array([-848,    8])

这不是很有用,它 returns 是一个向量,我们无法确定单词之间的距离,因此我们可以尝试一些向量技巧并计算向量之间的距离,例如euclidean distance:

>>> import numpy as np
>>> orange = np.array(semnum['orange'])
>>> apple = np.array(semnum['apple'])
>>> samsung = np.array(semnum['samsung'])

>>> np.linalg.norm(apple-orange)
763.03604108849277

>>> np.linalg.norm(apple-samsung)
848.03773500947466

>>> np.linalg.norm(orange-samsung)
1083.4685043876448

现在,我们可以看到更多 appleorange 更接近 samsung 的“信息”。可能那是因为 apple 在语料库中与 samsungorange.

更频繁地同时出现

大问题来了,“我们如何得到这些实数来表示单词的向量?”。这就是 Word2Vec / 嵌入训练算法 (originally conceived by Bengio 2003) 的用武之地。


走弯路

既然向表示单词的向量添加更多实数可以提供更多信息,那么我们为什么不添加更多维度(即每个单词向量中的列数)?

传统上,我们通过计算 distributional semantics/distributed lexical semantics 字段中的逐字矩阵来计算单词之间的差异,但如果单词不合并,矩阵会变得非常稀疏,有许多零值与另一个发生。

因此dimensionality reduction after computing the word co-occurrence matrix付出了很多努力。恕我直言,这就像从上到下查看单词之间的全局关系,然后压缩矩阵以获得更小的向量来表示每个单词。

所以“深度学习”词嵌入的创建来自另一个思想流派,它从随机(有时不是那么随机)初始化每个词的向量层开始,并学习 parameters/weights这些向量并通过根据某些定义的属性最小化某些损失函数来优化这些 parameters/weights。

听起来有点模糊,但具体来说,如果我们看一下 Word2Vec 学习技术,就会更清楚,参见

这里有更多关于词嵌入的资源:https://github.com/keon/awesome-nlp#word-vectors

著名的 Word2Vec 实现是 CBOW + Skip-Gram

您对 CBOW 的输入是您的输入词向量(每个都是一个长度为 N 的向量;N = 词汇量)。所有这些输入词向量一起是一个大小为 M x N 的数组; M=单词长度)。

现在下图中有趣的是投影步骤,我们强制神经网络学习输入的低维表示 space 以正确预测输出。所需的输出是我们的原始输入。

这个低维表示 P 由描述单词的抽象特征组成,例如位置、形容词等(实际上这些学到的特征并不是很清楚)。现在,这些特征代表了对这些词的一种看法。

和所有特征一样,我们可以将它们视为高维向量。 如果需要,您可以使用降维技术以 2 维或 3 维 space 显示它们。

更多细节和图片来源:https://arxiv.org/pdf/1301.3781.pdf