Word2Vec算法
Word2Vec算法可以说是
机器学习在文本分析中最重要的应用,它既是一种引人入胜又非常有用的工具。顾名思义,它根据我们使用的语料库创建单词的向量表示。但是Word2Vec的魔力在于它如何捕获矢量中单词的语义表示。论文对向量空间中单词表示的有效估计[1] [Mikolov等。[2013],单词和短语及其组合的分布式表示... [2] [Mikolov等。2013],以及连续空间字表示法中的语言规律
[3] [Mikolov等。2013]为Word2Vec奠定了基础并描述了它们的用途。
我们已经提到,这些单词向量有助于表示单词的语义-这到底是什么意思?对于初学者来说,这意味着我们可以对这些单词使用矢量推理-最著名的例子之一是米科洛夫的论文,其中我们看到如果我们使用单词vector并执行(此处,我们使用V(word)表示单词V(King)– V(Man)+ V(Woman)的向量表示形式,所得向量最接近V(Queen)。很容易看出为什么这是显着的-我们对这些单词的直观理解反映在单词的学习向量表示中!
这使我们能够在文本分析管道中添加更多的功能-具有向量的直观语义表示形式(并扩展为文档-但我们稍后会谈到)将不止一次地派上用场。
查找单词对关系是这样一种有趣的用法-如果我们定义两个单词之间的关系,例如法国:巴黎,则使用适当的向量差可以确定其他类似的关系-意大利:罗马,日本:东京是两个这样的示例,分别是使用Word2Vec找到。我们可以像使用任何其他矢量一样继续使用这些矢量-通过添加两个矢量,我们可以尝试获得我们认为两个单词相加的结果。例如,V(越南)+ V(首都)最接近V(河内)的向量表示。
这种技术究竟如何导致对单词的这种理解?Word2Vec通过理解上下文来工作-特别是,某些单词中倾向于出现哪些单词?我们选择一个滑动窗口大小,并基于此窗口大小尝试根据周围的单词来确定观察输出单词的条件概率。例如,如果句子为:文本数据的个人性质总是会增加一些动机,这也有可能意味着我们知道数据的性质以及预期的结果。并且我们的目标词是粗体字,动机,我们尝试找出找到动机一词的几率如果上下文总是在窗口的左侧添加额外的,并且也可能在右侧添加。当然,这只是一个说明性示例-确切的培训过程要求我们在其他细节中选择窗口大小和尺寸数。
有两种主要的方法来执行Word2Vec训练,分别是连续词袋模型(CBOW)和Skip Gram模型。这些模型的基础架构在原始研究论文中进行了描述,但是这两种方法都涉及理解我们之前讨论的上下文。Mikolov等人撰写的论文。提供培训过程的更多详细信息,并且由于该代码是公开的,因此这意味着我们实际上知道实际情况。
该 博客文章[4](Word2Vec教程-将跳过-gram模型)的克里斯·麦考密克解释了一些跳跃克word2vec模型背后的数学直觉,而 这个岗位[5](词矢量惊人的力量)的阿德里安Colyer讨论了我们可以使用word2vec进行的一些操作。如果您想更深入地了解Word2Vec的数学细节,这些链接将很有用。此资源页面[6]包含Word2Vec的理论和代码资源,如果您希望查找原始资料或其他实现细节,该页面也很有用。
虽然Word2Vec仍然是最受欢迎的单词向量实现,但这并不是第一次尝试,当然也不是最后一次-我们将在本章的最后部分中讨论其他一些单词嵌入技术。现在,让我们跳入使用这些单词向量的过程。
Gensim再次向我们提供帮助,可以说是该算法最可靠的开源实现,我们将探索如何使用它。
在Gensim中使用Word2Vec
Google发行的原始C代码[7]表现出色,但gensims的实现是开源实现比原始实现更高效的情况。
gensim实现在2013年原始算法发布时进行了编码-Radim?eh??ek[8]的博客文章记录了为gensim实现相同功能时遇到的一些想法和问题,如果您愿意,值得阅读知道在python中编码word2vec的过程。涉及word2vec的交互式Web教程[9]非常有趣,并说明了我们之前讨论过的word2vec的一些示例。值得一看的是,您是否对在线运行gensim word2vec代码感兴趣,还可以作为在gensim中使用word2vec的快速教程。
现在,我们将开始实际训练自己的Word2Vec模型。与我们使用的所有其他gensim模型一样,第一步涉及导入适当的模型。
从gensim.models导入word2vec
在这一点上,重要的是仔细阅读word2vec类以及KeyedVector类的文档,我们都会大量使用它们。在文档页面上,我们列出了word2vec.Word2Vec类的参数。
sg:定义训练算法。默认情况下(sg = 0),使用CBOW。否则(sg = 1),将使用skip-gram。
size:这是特征向量的维数。
窗口:这是句子中当前词和预测词之间的最大距离。
alpha:这是初始学习率(随着训练的进行,线性下降到min_alpha)。
种子:用于随机数生成器。每个单词的初始向量都以单词+ str(seed)的串联哈希值作为种子。请注意,对于完全确定性可重现的运行,还必须将模型限制为单个工作线程,以消除OS线程调度中的排序抖动。(在Python 3中,解释程序启动之间的可重复性还要求使用PYTHONHASHSEED环境变量来控制哈希随机化。)
min_count:忽略所有总频率低于此频率的单词。
max_vocab_size:限制词汇量期间的RAM;如果有比这更多的独特词,则修剪不常用的词。每1000万个字类型需要大约1GB的RAM。设置为无无限制(默认)。
sample:用于配置随机采样哪些高频词的阈值;默认值为1e-3,有用范围为(0,1e-5)。
worker:使用这么多的worker线程来训练模型(=使用多核机器进行更快的训练)。
hs:如果为1,则将等级softmax用于模型训练。如果设置为0(默认值),并且负数为非零,则将使用负数采样。
负数:如果> 0,将使用负数采样,负数的int指定应绘制多少个噪声词(通常在5到20之间)。默认值为5。如果设置为0,则不使用负采样。
cbow_mean:如果为0,则使用上下文词向量的总和。如果为1(默认),请使用均值。仅在使用cbow时适用。
hashfxn:哈希函数,用于随机初始化权重,以提高训练的可重复性。默认值为Python的基本内置哈希函数。
iter:语料库上的迭代次数(时期)。预设值为5。
trim_rule:词汇修剪规则指定某些单词应保留在词汇中,被修剪掉还是使用默认值处理(如果单词计数<min_count,则丢弃)。可以为None(将使用min_count),也可以是接受参数(word,count,min_count)并返回RULE_DISCARD,utils.RULE_KEEP或utils.RULE_DEFAULT的可调用对象。注意:如果给出规则,则该规则仅用于在build_vocab()期间修剪词汇,而不会存储为模型的一部分。
sorted_vocab:如果为1(默认值),则在分配单词索引之前,按降序对词汇表进行排序。
batch_words:传递给工作线程(以及cython例程)的示例批次的目标大小(以字为单位)。默认值为10000。(如果单个文本的长度超过10000个单词,则将通过较大的批处理,但是标准cython代码将截断为该最大值。)。
在示例中,我们不会使用或探索所有这些参数,但是它们对于保持想法仍然很重要-微调模型将严重依赖于此。在训练模型时,我们可以使用我们自己的语料库,也可以使用更通用的语料库-因为我们不想训练特定的主题或领域,因此我们将使用Text8 语料库[10],该语料库包含从Wikipedia中提取的文本数据。请务必先下载数据-我们通过在“实验程序”部分下找到链接text8.zip来进行此操作。
我们或多或少会遵循本章末尾附带的Jupyter笔记本,也可以在以下链接[11]中找到它。
句子= word2vec.Text8Corpus('text8')
模型= word2vec.Word2Vec(句子,大小= 200,hs = 1)
我们的模型将使用分层softmax进行训练,并将具有200个功能。这意味着它具有分层输出,并在其最终层中使用softmax函数。softmax函数是对逻辑函数的概括,该逻辑函数将任意实数值的K维向量z压缩为实数值的K维向量,其中每个条目的范围为(0,1),并且所有条目相加最多1个。我们此时不需要了解数学基础,但是如果感兴趣,链接1-3会提供更多有关此的详细信息。
打印我们的模型可以告诉我们:
打印(型号)
-> Word2Vec(vocab = 71290,size = 200,alpha = 0.025)
现在我们有了训练有素的模型,让我们尝试一下著名的King-Man + Woman示例:
model.wv.most_like(positive = ['woman','king'],negative = ['man'],topn = 1)[0]
在这里,我们将国王和女人(它们是正参数)相加,将男人(它是负参数)相减,然后仅选择元组中的第一个值。
->(u'queen')
瞧!不出所料,当我们搜索与女人和国王最相似但与男人相距甚远的单词时,Queen是最接近的单词向量。请注意,由于这是一个概率训练过程,因此您可能会得到一个不同的单词的可能性很小,但仍然与单词的上下文相关。例如,可能会出现宝座或帝国之类的词。
我们也可以使用most_similar_cosmul方法-gensim文档[12]将其描述为与传统相似性函数略有不同,而是使用Omer Levy和Yoav Goldberg在其论文中描述的实现[13]稀疏和显式单词中的语言规律性制图表达。正面的话
仍然对相似度有正面贡献,负面词则有负面影响,但对较大距离主导计算的敏感性较低。例如:
model.wv.most_like_cosmul(positive = ['woman','king'],negative = ['man'])
-> [(u'queen',0.8473771810531616),
(u'matilda',0.8126628994941711),
(u'throne',0.8048466444015503),
(u'prince',0.8044915795326233),
(u'empress',0.803791880607605),
(u'consort',0.8026778697967529),
(u'dowager',0.7984940409660339),
(u'princess',0.7976254224777222),
(u'heir',0.7949869632720947),
(u'monarch',0.7940317392349243)]
如果我们希望查找单词的向量表示形式,则需要做的是:
model.wv ['computer']
model.save(“ text8_model”)
我们不会在此处显示输出,但是可以期望看到200维数组,这就是我们指定的大小。
如果我们希望将模型保存到磁盘上并再次使用,则可以使用保存和加载功能来做到这一点。这特别有用-我们可以保存和重新训练模型,或者进一步训练适合特定领域的模型。
model.save(“ text8_model”)
模型= word2vec.Word2Vec.load(“ text8_model”)
gensim的神奇之处还在于,它不仅使我们能够训练模型-就像我们到目前为止所看到的那样,它是API,这意味着我们不必担心数学运算,而是可以专注于利用这些词向量的全部潜力。让我们看看word2vec模型提供的其他一些漂亮功能:
使用单词向量,我们可以识别列表中的哪个单词距离其他单词最远。Gensim使用dont_match方法实现了此功能,我们将举例说明:
model.wv.doesnt_match(“早餐谷物晚餐午餐” .split())
->“谷物”
不出所料,一个与列表中其他单词不匹配的单词被选中-这里是谷物。我们还可以使用该模型来了解语料库中相似或不同的词-
model.wv.similarity('woman','man')
-> 0.6416034158543054
model.wv.similarity('woman','cereal')
-> 0.04408454181286298
model.wv.distance('man','woman')
-> 0.35839658414569464
在这种情况下,结果是不言自明的,并且正如预期的那样,女人和谷物这两个词并不相似。在这里,距离仅仅是1 -相似性。
我们可以继续使用train方法训练Word2Vec模型-只需记住显式传递一个历元参数,因为这是一种避免模型自身进行多次训练的能力上常见错误的建议方法。该Gensim笔记本教程[14]逐步介绍了如何使用word2vec进行在线培训。简要地说,它需要执行以下任务-建立新的词汇表,然后再次运行火车功能。
训练完模型后,建议仅开始使用模型的键控向量。到目前为止,您可能已经注意到,我们一直在使用键控向量(这只是用于存储向量的Gensim类)来执行大多数任务-model.wv代表了这一点。要释放一些RAM空间,我们可以运行:
word_vectors = model.wv
德尔模型
现在,我们可以执行我们在使用单词向量之前所做的所有任务。请记住,这不仅适用于Word2Vec,而且适用于所有单词嵌入。
为了评估我们的模型做得如何,我们可以在安装gensim时加载的数据集上对其进行测试。
model.wv.evaluate_word_pairs(os.path.join(module_path,'test_data','wordsim353.tsv'))
- >(((0.6230957719715976,3.90029813472169e-39),
SpearmanrResult(相关性= 0.645315618985209,pvalue = 1.0038208415351643e-42),0.56657223796034)
在这里,为了确保找到文件,我们必须指定模块路径-这是gensim / test文件夹的路径,这是文件所在的位置。我们还可以通过运行以下代码来测试我们的模型,以查找单词对和关联。
model.wv.accuracy(os.path.join(module_path,'test_data','questions-words.txt'))
到目前为止,在我们的示例中,我们使用了一个经过自我训练的模型-有时这可能是一个非常耗时的练习,并且知道如何加载预先训练的矢量模型非常方便。例如,Gensim提供了一个简单的界面来加载经过Google新闻培训的原始word2vec模型(您可以从链接[9]下载此文件)。
从gensim.models导入KeyedVectors
#加载Google word2vec模型
filename ='GoogleNews-vectors-negative300.bin'
模型= KeyedVectors.load_word2vec_format(文件名,二进制=真)
我们的模型现在使用300维单词向量模型,并且我们可以再次运行之前运行的所有先前代码示例-结果不会有太大区别,但是我们可以期望使用更复杂的模型。
1