word2vec代码_怎样用Word2Vec创建反向词典?看这里看这里

全文共 8395字,预计学习时长 17分钟
bdb91a504219afbd0cbd4882bd6b616e.png

本文将介绍怎样用Word2Vec创建反向词典。除了Word2Vec之外,使用其他文字嵌入模型也会得到同样的结果。如果你不知道这意味着什么也不要紧,我们会解释清楚的。反向词典就是一种词典,需要先输入定义,然后找出与该定义相匹配的单词。

所需代码可以在companion repository中找到:https://github.com/unosviluppatore/reverse-dictionary

d45a6c213e6a4a6d3db26cf5fd623ca9.png

自然语言处理的应用

自然语言处理是一个很棒的领域。这个领域很有趣,客户也经常在应用程序中使用。因为自然语言处理是个很难进入的领域。你永远不知道,一个问题是能够在一天之内通过一个现成的库得以解决?还是需要一个研发团队研究两年才能获得不错的结果。简单点说:自然语言处理困难的地方不在于技术,而在于理解怎样成功运用。

基于机器学习解决上述问题时就更突出了,你需要了解一点机器学习的背景。有时即使解决方案行得通,仍需几个星期来调整参数和权重。

所以,本文中只列举一种技术,也就是一个简单的程序:反向词典。也就是说,怎么通过定义找到单词。这是一款简洁的程序,是买不到的,也无法用确定性算法来创建。

d45a6c213e6a4a6d3db26cf5fd623ca9.png

机器学习中的单词表征

机器学习的第一步是理解如何表达所处理的数据。最基本的方式就是使用one-hot编码,有以下几种方式:

· 收集所有的可能值(例如,10000个可能值)

· 每个可能值都用一个向量表示,这个向量包含尽可能多的分量(每个值由一个包含10000个组件的向量表示)

· 为了表达每个值,除了给一个组件赋值为1外,其他组件都赋值为0(即,每个组件都是0,除了一个组件是1)

将其应用于单词,就意味着:

· 需要10000个单词量

· 每个单词都用一个向量表示,这个向量包含10000个组件

· 单词 dog 表达为[1, 0, 0 …],单词 cat 表达为 [0, 1, 0 …],等等

这种方式可以表达所有单词,但还存在两大缺点:

· 每个向量都非常稀疏;大多数向量都是0

· 表达不具备任何语义;“father”和“mother”意思非常接近,但你永远不会看到这两个单词用one-hot编码

解决之道:单词嵌入

为了克服上面的两大缺点,单词嵌入应运而生。这种类型的单词表征的关键在于,具有相似含义的单词使用相似的表达。为了捕捉单词意思,或者与其他单词相关联,该表达允许有密集的向量。意思很简单,嵌入的单词并没有真正捕捉到father的意思,但是它的表达将与mother的表达类似。

这是一个强大的特点,可以应用于各种情况。例如,可以解决下面这个问题:

什么对于父亲相当于母亲对于女儿?

第一个单词嵌入模型是 Word2Vec ,我们将用它来创建反向词典。这一模型对该领域进行了革新,并催生了许多其他模型,例如FastText、GloVe这些模型之间有着细微差别——例如GloVe和Word2Vec是在单词层面上训练,而FastText则是在character n-grams上训练的。但是它们的原理、应用以及结果都非常相似。

d45a6c213e6a4a6d3db26cf5fd623ca9.png

Word2Vec的工作原理

Word2Vec的有效性得益于下面这个技巧:针对特定任务训练神经网络,然后将这个神经网络用于其他用途。这个技巧并不是Word2Vec所独有的,这是机器学习中最常用的一个技巧。基本上只需训练神经网络来得到一个特定的输出,然后去掉输出层,只保留神经网络隐藏层的权重。

训练过程和往常一样:给神经网络一个输入值以及一个与输入值相对应的输出。这样,神经网络可以慢慢学习如何生成正确的输出。

这个训练任务是为了计算在给定输入单词的情况下,在上下文中出现某个单词的概率。例如,如果有programmer这个单词,那么在上下文的短语中看到computer这个单词的概率是多少?

Word2Vec训练策略

Word2Vec有两种典型的策略:CBOW和skip-gram——这两个策略是可逆的。用CBOW输入单词的上下文,在输出中得到想要的单词。用skip-gram则相反:先输入单词,然后预测它所适用的上下文。

在最基本的层面上,“context (上下文)”这个术语仅仅是指目标单词周围的词,比如目标单词前后的词。但是,“上下文”也可用于表达句法意义(例如,指主语,如果目标词是动词)。这里只采用“上下文”最简单的含义。

例如这句话:

the gentle giant graciously spoke

在CBOW中, 需要输入[gentle, graciously]来得到输出giant。在skip-gram中,我们将输入“输入giant”,同时输入“输出[gentle, graciously]”。训练是用单个单词完成的,所以,在实践中,对CBOW来说:

· 第一次,输入gentle,期待结果输出giant。

· 第二次,输入 graciously ,期待结果输出 giant。

如果用skip-gram,就要把输入和输出颠倒过来。

d45a6c213e6a4a6d3db26cf5fd623ca9.png

神经网络会带来什么

就像前面所说,训练的最后会删除输出层,因为我们并不真正关心一个单词出现在目标单词附近的概率。例如,当输入单词flag时,我们并不真正关心 USA会有多大的概率出现在上下文中。然而,我们将保留神经网络隐藏层的权重,并用它来表达单词。这有什么用呢?

这是网络结构的特点所致。输入是单词的one-hot编码。例如,dog使用[1,0,0 …]来表达。在训练期间,输出也是单词的one-hot编码(例如,对于the dog barks,使用CBOW应输入dog,输出barks)。最终,输出层将会有一系列可能性。例如,给定输入单词cat,输出层将有可能在cat的上下文中出现单词dog。pet这个单词也会有出现的可能性,依此类推。

bf54344569c1efc6d413c2b585096a63.png

Word2Vec的神经网络

每个神经元对每个单词都有权重,所以在训练结束时,将有无数个神经元,每个神经元对每个单词都有权重。此外,要记住,表达单词的输入向量除了一个分量是1外,其他都是零。

因此,在矩阵乘法的数学规则中,如果用神经元矩阵乘以一个输入向量,输入向量为0,则神经元中的大多数权重无效,每个神经元中,将剩下一个与输入单词相关联的权重。每个神经元中的一系列非零权重将是Word2Vec中表达单词的权重。

上下文相似的单词会得到相似的输出,所以在特定单词的上下文中出现的概率也相似。换句话说,dog和cat会得到相似的输出。因此,它们也将具有相似的权重。这就是为什么意义相近的单词在Word2Vec中用相近的向量来表示。

Word2Vec的判断相当简单:相似的单词会出现在相似的短语中。然而,这一点也相当有效。当然,前提是有足够大的数据集用于训练。稍后会处理这个问题。

d45a6c213e6a4a6d3db26cf5fd623ca9.png

Word2Vec的意义

现在知道了Word2Vec的工作原理,下面来看看怎么用它创建反向词典。反向词典是通过输入定义来查找单词的词典。所以,理想情况下,输入group of relative(一群亲戚),程序会给出family(家族)。

从显而易见的开始:同义词词典使用的是单词嵌入法。如前所述,在这个系统中,相似的词有相似的表达。因此,如果想要系统找到与输入单词相近的单词,它会找到一个意思相似的单词。例如,如果输入happiness,可能会输出joy。

由此,你也许认为,做与上面相反的事情也行得通,比如找到输入单词的反义词。很不幸,这是不可能直接实现的,因为表达单词的向量不能理解单词之间那么精确的关系。基本上,sad这个单词的向量与 happy这个词的向量并不是镜像相反。

为什么可以用Word2Vec

请看下面单词向量的简化表示。

6fdecf6fa86ecf9e2df70390091e4ccd.png

单词关系的图形表达

系统可以找到由?表达的单词,仅仅因为它可以从father的向量中添加两个给定单词向量(mother 和 daughter)之间的差异。该系统确实能够捕捉到单词之间的关系,但是这种捕捉方式并不容易理解。换句话说:向量的位置是有意义的,但这也意味着这些位置的定义不是绝对的(例如,相反的),而是相对的(例如,一个看起来像是A-B的单词)。

这也解释了为什么无法直接找到反义词:在Word2Vec中没有可以用来描述这种关系的数学运算。

反向词典的工作原理

现在既然完全理解了单词向量的作用,那就可以来理解怎么用它们来创建一个反向词典了。反向词典基本可以用来查找到一个与输入内容(也就是定义)相似的单词。这是可以实现的,因为系统使用的是向量数学。

例如,如果输入 group of relatives,它就会找到 family。也可以在定义中使用否定的词来帮助识别一个词。例如,亲属团体决心组织起来。稍后将看到否定一个词的确切含义。也可以在定义中使用否定词来帮助识别单词。例如,将group of -relatives解析为organization。稍后将会解释否定一个单词有什么意义。

d45a6c213e6a4a6d3db26cf5fd623ca9.png

Word2Vec模型的数据

既然理论都清楚了,下面可以看看代码,然后创建反向词典。

第一步是创建字典。创建字典本身并不难,但是要花费很长时间。更重要的是,内容越多越好。对于普通用户来说,下载和存储大量数据并不轻松。仅英文维基百科的转储,提取时就可能需要超过50 GB(只包含文本)。通用爬网(可自由访问的已爬网页面)的数据可能会占用数千兆字节的存储空间。

出于实用考虑,最好使用谷歌共享的资料,例如谷歌新闻数据预先训练好的模型:GoogleNews-vectors-negative300.bin.gz。如果对这个文件进行搜索,很多地方都找得到。以前,谷歌代码项目是该文件的官方来源,但现在最好的来源似乎是谷歌硬盘。该文件是1.6GB的压缩版,不需要解压。

数据下载完成后,可以放在项目下的 models目录中。有许多针对Word2Vec的库,所以可以使用多种语言,但鉴于Python在机器学习中的流行度,本文会选择Python作为示例。本文将使用gensim库的Word2Vec,因为它是最优的。至于网络界面,则会使用Flask。

加载数据

首先,需要用3行简单的代码将Word2Vec加载至内存。

model = KeyedVectors.load_word2vec_format("./models/GoogleNews-vectors-negative300.bin.gz

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值