解释Gensim中的Word2Vec,用于创建单词嵌入模型(预训练和自定义)。

732 阅读11分钟

简介

在这篇文章中,我们将看到用Gensim库中的word2vec模型进行词嵌入的教程。我们将首先了解什么是词嵌入和什么是word2vec模型。然后我们将看到它的两种架构,即连续词袋(CBOW)模型和Skip Gram模型。最后,我们将解释如何使用预训练的word2vec模型,以及如何在Gensim中用你自己的文本语料库训练一个自定义的word2vec模型。作为奖励,我们还将介绍我们的自定义word2vec模型的可视化情况。

什么是词嵌入?

机器学习和深度学习算法不能直接处理文本数据,因此需要将它们转换为数字表示。 在NLP中,有像Bag of Words、Term Frequency、TF-IDF这样的技术来将文本转换成数字向量。然而,这些经典的技术并不能以数字形式代表文本之间的语义关系。

这就是词嵌入发挥作用的地方。词嵌入是文本的数字向量表示,它也保持了文本语料库中单词的语义和上下文关系。

在这样的表示中,具有更强语义关系的词在向量空间中彼此更接近。正如你在下面的例子中所看到的,苹果和芒果这两个词是相互接近的,因为它们都有许多相似的特征,都是水果。同样,国王和王后这两个词也是相互接近的,因为它们在皇家范围内是相似的。

Word Embeddings

什么是Word2Vec模型?

word2vec

Word2vec是一种流行的技术,通过使用神经网络创建单词嵌入模型。word2vec架构是由谷歌公司的托马斯-米科洛夫领导的研究团队在2013年提出的。

word2vec模型可以从训练文本语料库中创建保持语义和句法关系的数字向量表示。word2vec保留语义的一个非常著名的例子是,当你从King中减去Man这个词,再加上Woman,就会得到Queen这个最接近的结果之一。

国王-男人+女人≈女王

你可能会想我们是如何用单词做加减法的,但请记住,这些单词在word2vec中是用数字向量表示的,所以当你应用减法和加法时,结果向量更接近于Queen的向量表示。

在向量空间中,国王和王后这对词与男人和女人这对词之间有相似的距离。这是word2vec的另一种说法,即如果男人是女人,那么Kind就是Queen!

Word2Vec Word Embedding Example of King Man Woman Queen

谷歌公开发布的word2vec模型由300个特征组成,该模型是在谷歌新闻数据集中训练的。该模型的词汇量约为16亿字。然而,这可能需要花费大量的时间来训练模型,但他们应用了一种简单的子采样方法来优化时间。

Word2Vec架构

word2vec architecture

(来源)

该论文提出了两种word2vec架构来创建单词嵌入模型--i)连续词袋(CBOW)和ii)跳格。

i) 连续词袋(CBOW)模型

在连续词袋架构中,该模型从周围的上下文词中预测出当前的词。周围上下文词的长度是窗口大小,是一个可调整的超参数。该模型可以由一个单隐层神经网络来训练。

一旦神经网络被训练,它就会产生训练语料库中的单词的向量表示。矢量的大小也是一个超参数,我们可以相应地选择,以产生最佳的结果。

二)跳格模型

在skip-gram模型中,神经网络被训练来预测周围的上下文单词,给定当前单词作为输入。在这里,周围语境词的窗口大小也是一个可调整的参数。

当神经网络被训练时,它会产生训练语料库中的词的向量表示。矢量的大小也是一个超参数,可以通过实验来产生最佳结果。

CBOW vs Skip-Gram Word2Vec模型

  1. CBOW模型的训练是通过给周围的上下文单词作为输入来预测当前单词。而Skip-Gram模型是通过提供中心词作为输入来预测周围的语境词来训练的。
  2. 与Skip-Gram模型相比,CBOW模型的训练速度更快。
  3. CBOW模型在表示更频繁出现的单词时效果很好,而Skip-Gram在表示不太频繁的稀有单词时效果更好。

有关细节和信息,你可以参考word2vec原始论文。

使用Gensim库的Word2Vec

Gensim是一个用于自然语言处理的开源python库。在Gensim中使用Word2Vec是初学者最简单的选择,因为它有高水平的API,可以训练你自己的CBOW和SKip-Gram模型或运行预先训练好的word2vec模型。

安装Gensim库

让我们安装Gensim库和其支持库python-Levenshtein。

在[1]。

pip install gensim
pip install python-Levenshtein

在下面的章节中,我们将告诉你如何在Gensim中运行预训练的word2vec模型,然后告诉你如何训练你的CBOW和SKip-Gram。

(所有的例子都是在Genism 4.0中显示的,可能在Genism 3.x版本中不适用)。

在Gensim中使用预训练的Word2Vec模型

i) 下载预训练的权重

我们将使用word2vec的预训练权重,它是在包含30亿个词的Google New语料库上训练的。这个模型由300个维度的向量组成,包括300万个单词和短语。

该权重可以从这个链接下载。它是一个1.5GB的文件,所以要确保你有足够的空间来保存它。

二)加载库

我们加载所需的Gensim库和模块,如下所示 -

在[2]中。

import gensim
from gensim.models import Word2Vec,KeyedVectors

iii) 加载预训练的权重

接下来,我们通过使用Gensim的KeyedVectors.load_word2vec_format()模块加载我们预训练的权重。请确保在第一个参数中给出预训练权重的正确路径。(在我们的例子中,它被保存在当前工作目录中)

在[3]中。

model = KeyedVectors.load_word2vec_format('GoogleNews-vectors-negative300.bin.gz',binary=True,limit=100000)

iv) 检查词的矢量

我们可以检查数字向量的表示,就像下面的例子一样,我们对单词man进行了展示。

In[4]:

vec = model['man']
print(vec)

Out[4]:

[ 0.32617188  0.13085938  0.03466797 -0.08300781  0.08984375 -0.04125977 -0.19824219  0.00689697  0.14355469  0.0019455   0.02880859 -0.25 -0.08398438 -0.15136719 -0.10205078  0.04077148 -0.09765625  0.05932617  0.02978516 -0.10058594 -0.13085938  0.001297    0.02612305 -0.27148438  0.06396484 -0.19140625 -0.078125    0.25976562  0.375      -0.04541016  0.16210938  0.13671875 -0.06396484 -0.02062988 -0.09667969  0.25390625  0.24804688 -0.12695312  0.07177734  0.3203125   0.03149414 -0.03857422  0.21191406 -0.00811768  0.22265625 -0.13476562 -0.07617188  0.01049805 -0.05175781  0.03808594 -0.13378906  0.125       0.0559082  -0.18261719  0.08154297 -0.08447266 -0.07763672 -0.04345703  0.08105469 -0.01092529  0.17480469  0.30664062 -0.04321289 -0.01416016  0.09082031 -0.00927734 -0.03442383 -0.11523438  0.12451172 -0.0246582   0.08544922  0.14355469 -0.27734375  0.03662109 -0.11035156  0.13085938 -0.01721191 -0.08056641 -0.00708008 -0.02954102  0.30078125 -0.09033203  0.03149414 -0.18652344 -0.11181641  0.10253906 -0.25976562 -0.02209473  0.16796875 -0.05322266 -0.14550781 -0.01049805 -0.03039551 -0.03857422  0.11523438 -0.0062561 -0.13964844  0.08007812  0.06103516 -0.15332031 -0.11132812 -0.14160156  0.19824219 -0.06933594  0.29296875 -0.16015625  0.20898438  0.00041771  0.01831055 -0.20214844  0.04760742  0.05810547 -0.0123291  -0.01989746 -0.00364685 -0.0135498  -0.08251953 -0.03149414  0.00717163  0.20117188  0.08300781 -0.0480957  -0.26367188 -0.09667969 -0.22558594 -0.09667969  0.06494141 -0.02502441  0.08496094  0.03198242 -0.07568359 -0.25390625 -0.11669922 -0.01446533 -0.16015625 -0.00701904 -0.05712891  0.02807617 -0.09179688  0.25195312  0.24121094  0.06640625  0.12988281  0.17089844 -0.13671875  0.1875     -0.10009766 -0.04199219 -0.12011719  0.00524902  0.15625    -0.203125   -0.07128906 -0.06103516  0.01635742  0.18261719  0.03588867 -0.04248047  0.16796875 -0.15039062 -0.16992188  0.01831055  0.27734375 -0.01269531 -0.0390625  -0.15429688  0.18457031 -0.07910156  0.09033203 -0.02709961  0.08251953  0.06738281 -0.16113281 -0.19628906 -0.15234375 -0.04711914  0.04760742  0.05908203 -0.16894531 -0.14941406  0.12988281  0.04321289  0.02624512 -0.1796875  -0.19628906  0.06445312  0.08935547  0.1640625  -0.03808594 -0.09814453 -0.01483154  0.1875  0.12792969  0.22753906  0.01818848 -0.07958984 -0.11376953 -0.06933594 -0.15527344 -0.08105469 -0.09277344 -0.11328125 -0.15136719 -0.08007812 -0.05126953 -0.15332031  0.11669922  0.06835938  0.0324707  -0.33984375 -0.08154297 -0.08349609  0.04003906  0.04907227 -0.24121094 -0.13476562 -0.05932617  0.12158203 -0.34179688  0.16503906  0.06176758 -0.18164062  0.20117188 -0.07714844  0.1640625   0.00402832  0.30273438 -0.10009766 -0.13671875 -0.05957031  0.0625     -0.21289062 -0.06542969  0.1796875 -0.07763672 -0.01928711 -0.15039062 -0.00106049  0.03417969  0.03344727  0.19335938  0.01965332 -0.19921875 -0.10644531  0.01525879  0.00927734  0.01416016 -0.02392578  0.05883789  0.02368164  0.125       0.04760742 -0.05566406  0.11572266  0.14746094  0.1015625  -0.07128906 -0.07714844 -0.12597656  0.0291748   0.09521484 -0.12402344 -0.109375   -0.12890625  0.16308594  0.28320312 -0.03149414  0.12304688 -0.23242188 -0.09375 -0.12988281  0.0135498  -0.03881836 -0.08251953  0.00897217  0.16308594  0.10546875 -0.13867188 -0.16503906 -0.03857422  0.10839844 -0.10498047  0.06396484  0.38867188 -0.05981445 -0.0612793  -0.10449219 -0.16796875  0.07177734  0.13964844  0.15527344 -0.03125    -0.20214844 -0.12988281 -0.10058594 -0.06396484 -0.08349609 -0.30273438 -0.08007812  0.02099609]

iv) 最相似的词

我们可以通过使用Gensim的most_similar()API获得与给定单词相似的单词列表。

In[5]:

model.most_similar('man')

Out[5]:

[('女人', 0.7664012908935547),
('男孩', 0.6824871301651001),
('少年', 0.6586930155754089),
('teenage_girl', 0.6147903203964233),
('girl', 0.5921714305877686),
('强盗',0.5585119128227234),
('teen_ager',0.5549196600914001),
('男人',0。5489763021469116),
('家伙',0.5420035123825073),
('人',0.5342026352882385)]

In[6]:

model.most_similar('PHP')

Out[6]:

[('ASP.NET', 0.7275794744491577),
('Visual_Basic', 0.6807329654693604),
('J2EE', 0.6805503368377686),
('Drupal', 0.6674476265907288),
('NET_Framework', 0.6344218254089355),
('Perl', 0.6339991688728333),
('MySQL', 0.6315538883209229),
('AJAX', 0.6286270618438721),
('插件', 0.6174636483192444),
('SQL', 0.6123985052108765)]

五)文字类比

现在让我们在下面的例子中看到word2vec的King-Man+Woman的真实工作例子。做完这个操作后,我们使用most_similar()API,可以看到Queen在相似度列表的顶部。

In[7]:

vec = model['king'] - model['man'] + model['women']
model.most_similar([vec])

Out[7]:

[('国王', 0.6478992700576782),
('皇后', 0.535493791103363),
('女人', 0.5233659148216248),
('国王',0.5162314772605896),
('皇后',0.4995364248752594),
('王子',0.46233269572257996),
('君主',0.45280295610427856),
('君主制',0.4293173849582672),
('crown_prince', 0.42302510142326355),
('womens', 0.41756653785705566)]

让我们看看另一个例子,这次我们做的是INR - India + England,令人惊讶的是,模型在最相似的结果中返回了货币GBP

In[8]:

vec = model['INR'] - model ['India'] + model['England']
model.most_similar([vec])

Out[8]:

[('INR', 0.6442341208457947),
( 'GBP', 0.5040826797485352),
( 'England', 0.44649264216423035),
('£', 0.43340998888015747),
('â_£', 0.4307197630405426),
('£_#.##m', 0.42561301589012146),
('GBP##', 0.42464491724967957),
('stg', 0.42324796319007874),
('EUR', 0.418365478515625),
('€', 0.4151178002357483)

在Gensim中训练自定义Word2Vec模型

i) 了解Word2Vec()的语法

通过使用gensim.models的*Word2Vec()*模块,在Gensim中用你自己的文本语料库训练自定义的wor2vec模型是非常容易的,只需提供以下参数即可

  • 句子。它是一个可迭代的标记化句子列表,将作为训练模型的语料库。
  • **min_count。**如果任何单词的频率低于这个值,它将被忽略。
  • **workers。**用于训练模型的CPU工作线程的数量。
  • **window。**是指在训练过程中考虑到的句子中的当前词和预测词的最大距离。
  • **sg:**这表示训练算法。如果sg=1,则使用skip-gram进行训练,如果sg=0,则使用CBOW进行训练。
  • **epochs:**训练用的epochs数量。

这些只是我们正在使用的几个参数,但还有许多其他的参数可以使用,以获得更多的灵活性。关于完整的语法,请查看这里的Gensim文档。

ii) 自定义训练的数据集

为了训练的目的,我们将使用《哈利-波特》系列的第一本书--《魔法师之石》。文本文件版本可以从这个链接下载。

三)加载库

我们将加载以下库。加载TSNE和matplotlib是为了将我们自定义的word2vec模型的词嵌入可视化。

在[9]中。

# For Data Preprocessing

iii) 数据集的加载

接下来,我们通过使用pandas read_csv函数加载数据集。

In[10]:

df = pd.read_csv('HarryPotter.txt', delimiter = "\n",header=None)
df.columns = ['Line']
df

输出[10]。

0/
1那个活着的男孩
2杜斯利先生和夫人,住在普利维特大街四号...
3骄傲地说,他们是完全不...
4非常感谢你。他们是最后的人...
......
6757"哦,我会的,"哈利说,他们很惊讶......
6758他脸上洋溢着的笑容。" T...
6759我知道我们不允许在家里使用魔法。我是
6760将会和杜德利有很多的乐趣,这个星期天...
6761页码348

6762行×1列

iv) 文本预处理

对于预处理,我们将使用gensim.utils.simple_preprocess进行基本的预处理,将文本语料库标记为一个句子列表,并删除一些停顿词和标点符号。

gensim.utils.simple_preprocess模块对于基本的目的是好的,但如果你要创建一个严肃的模型,我们建议使用其他标准选项和技术来进行强大的文本清理和预处理。

In[11]:

preprocessed_text = df['Line'].apply(gensim.utils.simple_preprocess)
preprocessed_text

Out[11]:

0                                                      []
1                                  [the, boy, who, lived]
2       [mr, and, mrs, dursley, of, number, four, priv...
3       [were, proud, to, say, that, they, were, perfe...
4       [thank, you, very, much, they, were, the, last...
                              ...                        
6757    [oh, will, said, harry, and, they, were, surpr...
6758    [the, grin, that, was, spreading, over, his, f...
6759    [know, we, re, not, allowed, to, use, magic, a...
6760    [going, to, have, lot, of, fun, with, dudley, ...
6761                                               [page]
Name: Line, Length: 6762, dtype: object

v) 训练CBOW Word2Vec模型

在这里,我们用CBOW技术训练自定义的word2vec模型。为此,我们将sg=0的值与其他参数一起传递,如下所示。

其他参数的值是通过实验得出的,可能不会产生一个好的模型,因为我们的目标是解释训练你自己的自定义CBOW模型的步骤。你可能需要调整这些超参数以产生好的结果。

在[12]中。

model_cbow = Word2Vec(sentences=preprocessed_text, sg=0, min_count=10, workers=4, window =3, epochs = 20)

一旦训练完成,我们可以快速检查一个寻找与 "harry "最相似的词的例子。实际上,它很好地列出了与哈利-波特关系密切的其他角色的名字。这是不是很酷!?

In[13]:

model_cbow.wv.most_similar("harry")

Out[13]:

[('Ron', 0.8734568953514099),
('Neville', 0.8471445441246033),
('hermione', 0.7981335520744324),
('Hagrid', 0.7969962954521179),
('Malfoy', 0.7925101518630981),
('她',0.772059977054596),
('seamus',0.6930352449417114),
('迅速',0.692932665348053),
('他',0.691251814365387),
('突然',0.6806278228759766)]

v) 训练跳格的Word2Vec模型

为了用跳格技术训练word2vec,我们将sg=1的值与其他参数一起传递,如下所示。同样,这些超参数只是用于实验,你可能想调整它们以获得更好的结果。

在[14]中。

model_skipgram = Word2Vec(sentences =preprocessed_text, sg=1, min_count=10, workers=4, window =10, epochs = 20)

同样,一旦训练完成,我们可以通过寻找与 "harry "最相似的词来检查这个模型的工作情况。但是这一次我们看到的结果并不像使用CBOW的结果那样令人印象深刻。

In[15]:

model_skipgram.wv.most_similar("harry")

Out[15]:

[('小妖精', 0.5757830142974854),
('一起', 0.5725131630897522),
('摇晃', 0.5482161641120911),
('他',0.5105234980583191),
('工作',0.5037856698036194),
('the', 0.5015968084335327),
('page', 0.4912668466567993),
('story', 0.4897386431694031),
('furiously', 0.4880291223526001),
('then', 0.47639384865760803)]

v) 词嵌入的可视化

wor2vec创建的词嵌入模型可以通过使用Matplotlib和Sklearn的TNSE模块进行可视化。下面的代码参考了Jeff Delaney的Kaggle代码,我们只是修改了代码,使其与Gensim 4.0版本兼容。

在[16]。

def

a) 将CBOW的词嵌入可视化

让我们通过使用上面的自定义函数来可视化我们自定义的CBOW模型的词嵌入。

In[17]:

tsne_plot(model_cbow)

Out[17]:

Word2Vec Gensim CBOW Word Embedding Visualization

b) 可视化跳格的词嵌入

让我们通过使用上述自定义函数来可视化我们的自定义跳格模型的词嵌入。

In[18]:

tsne_plot(model_skipgram)

Out[18]:

Word2Vec Gensim Skip-Gram Word Embedding Visualization

The postWord2Vec in Gensim Explained for Creating Word Embedding Models (Prestrained and Custom)appeared first onMLK - Machine Learning Knowledge.