com*_*com 4 nlp machine-learning embedding neural-network word2vec
我为我的幼稚而感到抱歉,但我不明白为什么NN训练过程(word2vec)产生的词嵌入实际上是向量。
嵌入是降维的过程,在训练过程中,NN将词的1/0数组缩小为较小的数组,该过程不执行任何应用矢量算法的过程。
因此,结果是我们只有数组而不是向量。为什么将这些数组视为向量?
即使我们得到矢量,为什么每个人都将它们描述为来自原点(0,0)的矢量?
再次,对不起,如果我的问题看起来很愚蠢。
该过程不执行任何应用向量算术的操作
训练过程与向量运算无关,但是当生成数组时,发现它们具有非常好的属性,因此可以想到“词线性空间”。
例如,在这个空间中,哪些词的嵌入最接近给定的词?
换句话说,意思相近的词形成一片云。这是一个二维 t-SNE 表示:
再比如,“男人”和“女人”之间的距离非常接近“叔叔”和“阿姨”之间的距离:
结果,你有非常合理的算术:
W("woman") ? W("man") ? W("aunt") ? W("uncle")
W("woman") ? W("man") ? W("queen") ? W("king")
Run Code Online (Sandbox Code Playgroud)
所以称它们为vector并不牵强。所有图片都来自这篇精彩的帖子,我非常推荐阅读。
什么是嵌入物?
单词嵌入是自然语言处理(NLP)中一组语言建模和功能学习技术的总称,其中词汇表中的单词或短语被映射到实数向量。
从概念上讲,它涉及从每个单词一维的空间到具有低维的连续向量空间的数学嵌入。
(来源:https : //en.wikipedia.org/wiki/Word_embedding)
什么是Word2Vec?
Word2vec是一组用于产生单词嵌入的相关模型。这些模型是浅的两层神经网络,经过训练可以重建单词的语言环境。
Word2vec将一个大型文本语料库作为输入,并产生一个通常具有几百个维度的向量空间,该语料库中的每个唯一单词都在该空间中分配了一个对应的向量。
词向量位于向量空间中,以便在语料库中共享公共上下文的词在空间中彼此紧邻。
(来源:https : //en.wikipedia.org/wiki/Word2vec)
什么是数组?
在计算机科学中,数组数据结构(或简称为数组)是由元素(值或变量)的集合组成的数据结构,每个元素均由至少一个数组索引或键标识。
存储一个数组,以便可以通过数学公式从其索引元组计算每个元素的位置。
数据结构的最简单类型是线性数组,也称为一维数组。
什么是向量/向量空间?
向量空间(也称为线性空间)是称为向量的对象的集合,可以将这些对象加在一起并乘以(称为“标量”)数字。
标量通常被视为实数,但是也有矢量空间,其标量乘以复数,有理数或通常任何字段。
向量加法和标量乘法的运算必须满足下面列出的称为公理的某些要求。
(来源:https : //en.wikipedia.org/wiki/Vector_space)
向量和数组有什么区别?
首先,词嵌入中的向量并不完全是编程语言的数据结构(因此它不是数组与向量:简介相似性和差异性)。
通过编程,单词嵌入向量是某种实数(即标量)数组(数据结构)
从数学上讲,任何一维或多维填充实数的元素都是张量。向量是标量的一维。
要回答OP问题:
为什么词嵌入实际上是向量?
根据定义,词嵌入是向量(请参见上文)
为什么我们将单词表示为实数向量?
要了解单词之间的差异,我们必须以某种方式量化差异。
想象一下,如果我们将这些“智能”数字分配给以下单词:
>>> 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
Run Code Online (Sandbox Code Playgroud)
我们看到,之间的距离fruit和apple接近,但samsung并apple没有。在这种情况下,单词的单个数字“功能”能够捕获有关单词含义的一些信息,但不能完全捕获。
想象一下,每个单词(即向量)有两个实数值:
>>> 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]}
Run Code Online (Sandbox Code Playgroud)
要计算差异,我们可以这样做:
>>> np.array(semnum['apple']) - np.array(semnum['orange'])
array([-68, 761])
>>> np.array(semnum['apple']) - np.array(semnum['samsung'])
array([-848, 8])
Run Code Online (Sandbox Code Playgroud)
这不是非常有用的信息,它返回一个向量,并且我们无法确切地确定单词之间的距离,因此我们可以尝试一些矢量技巧,并计算出向量之间的距离,例如欧氏距离:
>>> 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
Run Code Online (Sandbox Code Playgroud)
现在,我们可以看到更多的“信息” apple可能更接近samsung比orange对samsung。可能是因为apple与samsung相比,在语料库中出现的频率更高orange。
一个大问题来了:“我们如何获得这些实数来表示单词的向量?” 。这就是Word2Vec /嵌入训练算法(最初由Bengio 2003构思)的地方。
由于将更多的实数添加到表示单词的向量中会提供更多信息,那么为什么不增加更多的维数(即每个单词向量中的列数)呢?
传统上,我们通过计算分布语义/分布式词法语义领域中的逐词矩阵来计算词之间的差异,但是如果这些词彼此之间不共存,则矩阵实际上会变得稀疏,具有许多零值。
因此,在计算单词共现矩阵之后,在降维上付出了很多努力。恕我直言,这就像是单词之间全局关系的自顶向下视图,然后压缩矩阵以得到一个较小的向量来表示每个单词。
因此,“深度学习”词嵌入的创建来自另一种流派,并从随机(有时不是那么随机)初始化每个词的向量层,并学习这些向量的参数/权重并优化这些参数/通过基于某些定义的属性最小化某些损失函数来加权。
听起来有些模糊,但具体来说,如果我们看一下Word2Vec学习技术,它将更加清晰,请参阅
这是更多有关单词嵌入的资源:https : //github.com/keon/awesome-nlp#word-vectors