图解word2vec(原文翻译)


自2013年以来,word2vec一直是一种有效的词嵌入的方法,本文把word2vec用图解的方式进行,全篇没有数学公式,很是通俗易懂,推荐初学者阅读。python

(原文做者:jalammar,翻译:黄海广)。git


备注:这个是另外一个版本的翻译,网上也有其它版本的翻译,都是独立完成的。github

原文连接:算法

https://jalammar.github.io/illustrated-word2vec/api

这篇文章的代码传到了本站的github:网络

https://github.com/fengdu78/machine_learning_beginner/tree/master/word2vec架构

正文开始

我发现嵌入的概念是机器学习中最迷人的想法之一。若是您曾经使用Siri,Google智能助理,Alexa,谷歌翻译,甚至智能手机键盘进行下一词预测,那么您颇有可能从这个已经成为天然语言处理模型核心的想法中受益。在过去的几十年中,使用嵌入技术进行神经模型已有至关大的发展(最近的发展包括BERT和GPT2 等尖端模型的语境化嵌入)。dom

自2013年以来,Word2vec一直是一种有效建立单词嵌入的方法。除了词嵌入字的方法以外,它的一些概念已经被证实能够在非语言任务中有效地建立推荐引擎和理解顺序数据。好比Airbnb,阿里巴巴,Spotify和Anghami这样的公司都从NLP世界中创造出这一优秀的工具并将其用于生产中,从而为新型推荐引擎提供支持。机器学习

咱们将讨论嵌入的概念,以及使用word2vec生成嵌入的机制。ide

让咱们从一个例子开始,了解使用向量来表示事物。

您是否知道五个数字(向量)的列表能够表明您的个性?

个性嵌入:你的个性怎么样?

使用0到100的范围表示你的个性(其中0是最内向的,100是最外向的)。

五大人格特质测试,这些测试会问你一个问题列表,而后在不少方面给你打分,内向/外向就是其中之一。

图解word2vec(原文翻译)

图:测试结果示例。它能够真正告诉你不少关于你本身的事情,而且在学术、我的和职业成功方面都具备预测能力。

假设个人测试得分为38/100。咱们能够用这种方式绘制:

图解word2vec(原文翻译)
让咱们将范围切换到从-1到1:

图解word2vec(原文翻译)

了解一我的,一个维度的信息不够,因此让咱们添加另外一个维度 - 测试中另外一个特征的得分。

图解word2vec(原文翻译)

你可能不知道每一个维度表明什么,但仍然能够从一我的的个性的向量表示中得到了不少有用的信息。

咱们如今能够说这个向量部分表明了个人个性。当你想要将另外两我的与我进行比较时,向量化表示的有用性就出现了。在下图中,两我的中哪个更像我?

图解word2vec(原文翻译)

处理向量时,计算类似度得分的经常使用方法是余弦类似度:

图解word2vec(原文翻译)
一号人物与个人余弦类似度得分高,因此咱们的性格比较类似。

然而,两个方面还不足以捕获有关不一样人群的足够信息。几十年的心理学研究已经研究了五个主要特征(以及大量的子特征)。因此咱们在比较中使用全部五个维度:

图解word2vec(原文翻译)

咱们无法在二维上绘制出来五个维度,这是机器学习中的常见挑战,咱们常常须要在更高维度的空间中思考。但好处是余弦类似度仍然有效。它适用于任意数量的维度:

图解word2vec(原文翻译)

嵌入的两个中心思想:

  • 咱们能够将人(事物)表示为数字的向量。

  • 咱们能够很容易地计算出类似的向量彼此之间的关系。

图解word2vec(原文翻译)

词嵌入

咱们导入在维基百科上训练的GloVe向量:

import gensim
import gensim.downloader as api
model = api.load('glove-wiki-gigaword-50')

model["king"]
#查看“king”最类似的单词

[('prince', 0.8236179351806641),
 ('queen', 0.7839042544364929),
 ('ii', 0.7746230363845825),
 ('emperor', 0.7736247181892395),
 ('son', 0.766719400882721),
 ('uncle', 0.7627150416374207),
 ('kingdom', 0.7542160749435425),
 ('throne', 0.7539913654327393),
 ('brother', 0.7492411136627197),
 ('ruler', 0.7434253096580505)]

这是一个包含50个数字的列表,咱们没法说清楚里面的值表明什么。咱们把全部这些数字放在一行,以便咱们能够比较其余单词向量。让咱们根据它们的值对单元格进行颜色编码(若是它们接近2则为红色,若是它们接近0则为白色,若是它们接近-2则为蓝色)

import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
plt.figure(figsize=(15, 1))
sns.heatmap([model["king"]],
            xticklabels=False,
            yticklabels=False,
            cbar=False,
            vmin=-2,
            vmax=2,
            linewidths=0.7)
plt.show()

图解word2vec(原文翻译)

咱们将忽略数字并仅查看颜色以指示单元格的值,咱们将“King”与其余词语进行对比:

plt.figure(figsize=(15, 4))
sns.heatmap([
    model["king"],
    model["man"],
    model["woman"],
    model["king"] - model["man"] + model["woman"],
    model["queen"],
],
            cbar=True,
            xticklabels=False,
            yticklabels=False,
            linewidths=1)
plt.show()

图解word2vec(原文翻译)
看看“man”和“woman”是如何彼此更类似的,他们中的任何一个都是“king”?这告诉你一些事情。这些向量表示捕获了这些单词的信息/含义/关联。

这是另外一个示例列表(经过垂直扫描列来查找具备类似颜色的列):

图解word2vec(原文翻译)

有几点须要指出:

  • 全部这些不一样的单词都有一个直的红色列。它们在这个维度上是类似的(咱们不知道每一个维度代码是什么)

  • 你能够看到“woman”和“girl”在不少地方是如何类似的。与“man”和“boy”同样

  • “boy”和“girl”也有彼此类似的地方,但与“woman”或“man”不一样。这些是否能够编写一个模糊的青年概念?可能。

  • 除了最后一个字以外的全部字都表明着人。我添加了一个对象“water”来显示类别之间的差别。例如,您能够看到蓝色列一直向下并在嵌入“water”以前中止。

  • 有一个明显的地方,“king”和“queen”彼此类似,并与全部其余人不一样。类比

咱们能够添加和减去单词嵌入并得到有趣的结果,最有名的例子是公式:“king” - “man” + “woman”:

model.most_similar(positive=["king","woman"],negative=["man"])

[('queen', 0.8523603677749634),
 ('throne', 0.7664334177970886),
 ('prince', 0.759214460849762),
 ('daughter', 0.7473883032798767),
 ('elizabeth', 0.7460220456123352),
 ('princess', 0.7424569725990295),
 ('kingdom', 0.7337411642074585),
 ('monarch', 0.7214490175247192),
 ('eldest', 0.7184861898422241),
 ('widow', 0.7099430561065674)]

咱们能够像之前同样想象这个类比:

图解word2vec(原文翻译)

语言建模

若是想要给出NLP应用程序的示例,最好的示例之一将是智能手机键盘的下一个字(词)预测功能。这是数十亿人天天使用数百次的功能。

图解word2vec(原文翻译)

下一个字(词)预测是一项能够经过语言模型解决的任务。语言模型能够采用单词列表(比方说两个单词),并尝试预测它们以后的单词。

在上面的屏幕截图中,咱们能够将模型视为接受这两个绿色单词(thou shalt)并返回建议列表(“not”是具备最高几率的那个字)的模型:

图解word2vec(原文翻译)

咱们能够把模型想象成这个黑盒子:

图解word2vec(原文翻译)

但实际上,该模型不会只输出一个单词。它实际上输出了它所知道的全部单词的几率分数(模型的“词汇表”,其范围能够从几千到一百多万个字(词))。而后应用程序必须找到分数最高的单词,并将其呈现给用户。

图解word2vec(原文翻译)

图:神经语言模型的输出是模型知道的全部单词的几率分数。咱们在这里将几率称为百分比,好比几率40%将在输出向量中表示为
0.4

通过训练,早期的神经语言模型(Bengio 2003)将分三步计算预测:

图解word2vec(原文翻译)

在讨论嵌入时,第一步对咱们来讲最相关。训练过程的结果之一是这个矩阵包含咱们词汇表中每一个单词的嵌入。在预测时间内,咱们只查找输入字的嵌入,并使用它们来计算预测:

图解word2vec(原文翻译)

如今让咱们转到训练过程,以了解嵌入矩阵是如何工做的。

语言模型的训练

与大多数其余机器学习模型相比,语言模型具备巨大优点。即:咱们全部的书籍,文章,维基百科内容和其余形式的大量文本数据能够做为训练数据。与此相比,许多其余机器学习模型须要手动设计特征和专门收集的数据。
单词经过咱们查看它们每每会出如今旁边的其余单词来嵌入。其机制就是这样

  1. 咱们得到了大量文本数据(例如,全部维基百科文章)。而后

  2. 咱们有一个窗口(好比说三个单词),咱们会对全部文本进行滑动。

  3. 滑动窗口为咱们的模型生成训练样本

图解word2vec(原文翻译)

当这个窗口滑动文本时,咱们(虚拟地)生成一个用于训练模型的数据集。为了准确看看它是如何完成的,让咱们看看滑动窗口如何处理这个短语:

当咱们开始时,窗口在句子的前三个单词上:
图解word2vec(原文翻译)

咱们将前两个单词做为特征,将第三个单词做为标签:
图解word2vec(原文翻译)
咱们如今已经在数据集中生成了第一个样本,咱们稍后可使用它来训练语言模型。

而后咱们将窗口滑动到下一个位置并建立第二个样本:

图解word2vec(原文翻译)
如今生成第二个示例。

很快咱们就会有一个更大的数据集,在不一样的单词对以后,这些数据集会出现:

图解word2vec(原文翻译)

在实践中,模型每每在咱们滑动窗口时进行训练。但我发现逻辑上将“数据集生成”阶段与训练阶段分开是更清楚的。除了基于神经网络的语言建模方法以外,一种称为N-gram的技术一般用于训练语言模型。

要了解这种从N-gram到神经模型的转换如何反映现实世界的产品,建议看这篇2015年博客文章,介绍他们的神经语言模型并将其与以前的N-gram模型进行比较。

两边看

给了你句子前面的内容,进行填空:
图解word2vec(原文翻译)
我在这里给你的背景是空格以前的五个字(以及以前提到的“bus”)。我相信大多数人都会猜到空格里的这个词会是“bus”。可是,若是我再给你一条信息:空格以后的一句话,那会改变你的答案吗?

图解word2vec(原文翻译)

这彻底改变了应该留在空格中的内容。“red”这个词如今最可能填到空格中。咱们从中学到的是特定词语以前和以后的词语都具备信息价值。事实证实,考虑两个方向(咱们猜想的单词左侧和右侧的单词)会让词嵌入作得更好。

让咱们看看咱们如何调整咱们训练模型的方式来解决这个问题。

Skipgram

咱们不只能够查看在目标词以前的两个单词,还能够查看其后的两个单词。

图解word2vec(原文翻译)

若是咱们这样作,咱们实际构建和训练模型的数据集将以下所示:
这被称为连续词袋结构,并在word2vec论文 one of the word2vec papers 中进行过描述。

图解word2vec(原文翻译)
另外一种结构与连续词袋结构略有不一样,但也能够也显示出良好结果。这个结构试图使用当前词来猜想相邻词,而不是根据其上下文(它以前和以后的词)猜想一个词。咱们能够想到它在训练文本上滑动的窗口以下所示:

图解word2vec(原文翻译)

绿色框中的字将是输入字,每一个粉色框将是可能的输出。粉色框具备不一样的阴影,由于此滑动窗口实际上在咱们的训练数据集中建立了四个单独的样本:
图解word2vec(原文翻译)
此方法称为skipgram架构。咱们能够执行如下操做将滑动窗口可视化:
图解word2vec(原文翻译)
这会将这四个样本添加到咱们的训练数据集中:
图解word2vec(原文翻译)
而后咱们将窗口滑动到下一个位置:
图解word2vec(原文翻译)
这将产生咱们的下四个样本:
图解word2vec(原文翻译)
接着滑动几个位置以后,咱们有更多的样本:
图解word2vec(原文翻译)

从新审视训练过程

如今咱们已经从现有的运行文本中提取了咱们的skipgram训练数据集,让咱们看看咱们如何使用它来训练预测相邻单词的基本神经语言模型。

图解word2vec(原文翻译)

咱们从数据集中的第一个样本开始。咱们把特征提供给未经训练的模型,要求它预测一个合适的相邻单词。

图解word2vec(原文翻译)

该模型进行三个步骤并输出预测向量(几率分配给其词汇表中的每一个单词)。因为该模型未通过训练,所以在此阶段的预测确定是错误的。但那不要紧。咱们知道应该它将猜到哪一个词:咱们目前用于训练模型的行中的标签/输出单元格:

图解word2vec(原文翻译)

“目标向量”的词(字)几率为1,其余词(字)的几率都是0。咱们减去两个向量,获得一个偏差向量:
图解word2vec(原文翻译)

如今可使用此偏差向量来更新模型,以便下次当“not”做为输入时,模型更有可能猜想“thou”。

图解word2vec(原文翻译)

这就是训练的第一步。咱们继续使用数据集中的下一个样本进行相同的处理,而后是下一个样本,直到咱们覆盖了数据集中的全部样本。这就结束了一个epcho的训练。咱们继续训练多个epcho,而后咱们就有了训练好的模型,咱们能够从中提取嵌入矩阵并将其用于任何其余应用。

虽然这加深了咱们对该过程的理解,但仍然不是word2vec实际上的训练过程。

负采样

回想一下这个神经语言模型如何计算其预测的三个步骤:

图解word2vec(原文翻译)

从计算的角度来看,第三步很是消耗资源:尤为是咱们将在数据集中为每一个训练样本作一次(极可能数千万次)。咱们须要作一些事情来提升效率。
一种方法是将目标分红两个步骤:

  1. 生成高质量的单词嵌入(不要担忧下一个单词预测)。

  2. 使用这些高质量的嵌入来训练语言模型(进行下一个单词预测)。

咱们将专一于第1步,由于咱们专一于嵌入。要使用高性能模型生成高质量嵌入,咱们能够从预测相邻单词切换模型的任务:

图解word2vec(原文翻译)

并将其切换到一个取输入和输出字的模型,并输出一个分数,代表它们是不是邻居(0表示“不是邻居”,1表示“邻居”)。

图解word2vec(原文翻译)

这个简单的改变,将咱们须要的模型从神经网络改成逻辑回归模型:所以它变得更简单,计算速度更快。

这个改变要求咱们切换数据集的结构 - 标签如今是一个值为0或1的新列。它们将所有为1,由于咱们添加的全部单词都是邻居。

图解word2vec(原文翻译)

如今能够以极快的速度计算 - 在几分钟内处理数百万个示例。可是咱们须要关闭一个漏洞。若是咱们全部的例子都是正面的(目标:1),咱们打开本身的智能模型的可能性老是返回1 - 达到100%的准确性,但什么都不学习并生成垃圾嵌入。

图解word2vec(原文翻译)

为了解决这个问题,咱们须要在数据集中引入负样本 - 不是邻居的单词样本。咱们的模型须要为这些样本返回0。如今这是一个挑战,模型必须努力解决,并且速度还要快。

图解word2vec(原文翻译)

图:对于咱们数据集中的每一个样本,咱们添加了负样本。它们具备相同的输入词和0标签。可是咱们填写什么做为输出词?咱们从词汇表中随机抽取单词

图解word2vec(原文翻译)

这个想法的灵感来自Noise-contrastive estimation。咱们将实际信号(相邻单词的正例)与噪声(随机选择的不是邻居的单词)进行对比。这是计算量和统计效率的巨大折衷。

带负采样的skipgram(SGNS)

咱们如今已经介绍了word2vec中的两个核心思想:
负采样和skipgram。

图解word2vec(原文翻译)

Word2vec训练流程

如今咱们已经创建了skipgram和负采样的两个中心思想,咱们能够继续仔细研究实际的word2vec训练过程。
在训练过程开始以前,咱们预先处理咱们正在训练模型的文本。在这一步中,咱们肯定词汇量的大小(咱们称之为vocab_size,好比说,将其视为10,000)以及哪些词属于它。在训练阶段的开始,咱们建立两个矩阵 - Embedding矩阵和Context矩阵。这两个矩阵在咱们的词汇表中嵌入了每一个单词(这vocab_size是他们的维度之一)。第二个维度是咱们但愿每次嵌入的时间长度(embedding_size- 300是一个常见值,但咱们在本文前面的例子是50。)。

图解word2vec(原文翻译)

在训练过程开始时,咱们用随机值初始化这些矩阵。而后咱们开始训练过程。在每一个训练步骤中,咱们采起一个正样本及其相关的负样本。咱们来看看咱们的第一组:

图解word2vec(原文翻译)

如今咱们有四个单词:输入单词not和输出/上下文单词:( thou实际邻居),aaron,和taco(负样本)。咱们继续查找它们的嵌入 - 对于输入词,咱们查看Embedding矩阵。对于上下文单词,咱们查看Context矩阵(即便两个矩阵都在咱们的词汇表中嵌入了每一个单词)。

图解word2vec(原文翻译)
而后,咱们计算输入嵌入与每一个上下文嵌入的点积。。在每种状况下,会产生一个数字,该数字表示输入和上下文嵌入的类似性。

图解word2vec(原文翻译)

如今咱们须要一种方法将这些分数转化为看起来像几率的东西 :使用sigmoid函数把几率转换为0和1。

图解word2vec(原文翻译)

如今咱们能够将sigmoid操做的输出视为这些样本的模型输出。您能够看到taco得分最高aaron,而且在sigmoid操做以前和以后仍然具备最低分。既然未经训练的模型已作出预测,而且看到咱们有一个实际的目标标签要比较,那么让咱们计算模型预测中的偏差。为此,咱们只从目标标签中减去sigmoid分数。

图解word2vec(原文翻译)

error=target−sigmoid

这是“机器学习”的“学习”部分。如今,咱们能够利用这个错误分数调整not,thou,aaron和taco的嵌入,使下一次咱们作出这一计算,结果会更接近目标分数。
图解word2vec(原文翻译)

训练步骤到此结束。咱们从这一步骤中获得稍微好一点的嵌入(not,thou,aaron和taco)。咱们如今进行下一步(下一个正样本及其相关的负样本),并再次执行相同的过程。

图解word2vec(原文翻译)
当咱们循环遍历整个数据集屡次时,嵌入继续获得改进。而后咱们能够中止训练过程,丢弃Context矩阵,并使用Embeddings矩阵做为下一个任务的预训练嵌入。

窗口大小和负样本数量

word2vec训练过程当中的两个关键超参数是窗口大小和负样本的数量。

图解word2vec(原文翻译)

不一样的窗口大小能够更好地提供不一样的任务。
一种启发式方法是较小的窗口嵌入(2-15),其中两个嵌入之间的高类似性得分代表这些单词是可互换的(注意,若是咱们只查看周围的单词,反义词一般能够互换 - 例如,好的和坏的常常出如今相似的情境中)。
使用较大的窗口嵌入(15-50,甚至更多)会获得类似性更能指示单词相关性的嵌入。实际上,您一般须要对嵌入过程提供注释指导,为您的任务带来有用的类似感。
Gensim默认窗口大小为5(输入字自己加上输入字以前的两个字和输入字以后的两个字)。

图解word2vec(原文翻译)

负样本的数量是训练过程的另外一个因素。原始论文里负样本数量为5-20。它还指出,当你拥有足够大的数据集时,2-5彷佛已经足够了。Gensim默认为5个负样本。

结论

我但愿你如今对词嵌入和word2vec算法有所了解。我也但愿如今当你读到一篇提到“skip gram with negative sampling”(SGNS)的论文时,你会对这些概念有了更好的认识。
本文做者:jalammar。

参考文献和进一步阅读材料

  • Distributed Representations of Words and Phrases and their Compositionality [pdf]

  • Efficient Estimation of Word Representations in Vector Space [pdf]

  • A Neural Probabilistic Language Model [pdf]

  • Speech and Language Processing by Dan Jurafsky and James H. Martin is a leading resource for NLP. Word2vec is tackled in Chapter 6.

    • Neural Network Methods in Natural Language Processing by Yoav Goldberg is a great read for neural NLP topics.
  • Chris McCormick has written some great blog posts about Word2vec. He also just released The Inner Workings of word2vec, an E-book focused on the internals of word2vec.

  • Want to read the code? Here are two options:

    • Gensim’s python implementation of word2vec
  • Mikolov’s original implementation in C – better yet, this version with detailed comments from Chris McCormick.

  • Evaluating distributional models of compositional semantics

  • On word embeddings, part 2

  • Dune
相关文章
相关标签/搜索