Keras自然语言处理(十二)

第九章 如何在Gensim开发词嵌入

词嵌入是一种在自然语言处理中表示文本的现代方法。像Word2Vec和Glove这样的嵌入算法是神经网络模型用于机器翻译等自然语言处理问题所取得的最新成果关键。在本教程中,你将了解在Python中如何使用Gensim为自然语言处理应用程序训练和加载自嵌入模型。接下来你将了解:
-如何在文本数据上训练自己的Word2Vec单词嵌入模型
-如何使用主成分分析可视化训练的单词嵌入模型
-如何从谷歌和斯坦福加载预先训练好的Word2Vec和Glove自嵌入模型

9.1 概述

下面分为以下几块内容:

  1. 词嵌入
  2. Gensim库
  3. 开发Word2Vec词嵌入模型
  4. 可视化词嵌入模型
  5. 加载谷歌的Word2Vec词嵌入模型
  6. 加载斯坦福的Glove嵌入模型

9.2 词嵌入

词嵌入是一种提供单词的密集向量表示的方法,可以捕捉单词的含义。词嵌入是对简单词袋模型编码方案的改进,任何一个文档在词袋模型方案的编码下最终得到一个稀疏的向量,得到的是文档的内容,而不是词的内容。词嵌入模型是在大规模文本语料库上通过使用一定的算法训练一组固定长度密集和连续值向量获得的。每个单词由嵌入空间的一个点表示,这些点是根据围绕目标单词的单词学习和移动的。单词本身由自己的伴生词(文本两侧的词)的含义来定义的,同意通过嵌入来学习单词的意思。单词向量空间表示提供一个映射,其中具有相似含义的单词在空间内局部聚类。
在文本表示中,使用词嵌入模型是深度神经网络在处理机器翻译等问题上具有突破性表现的关键方法之一,下面我们将使用Glove和Word2Vec两种不同的词嵌入方法

9.3 Gensim

Gensim是一个用于自然语言处理的来源Python库,主要关注主题建模。Gensim是一个成熟,专注,高效的NLP工具套件,它和NLTK不一样。值得注意的是它支持Word2Vec词嵌入的实现,可以从文本中学习新的词向量。
它还提供了加载几种不同格式的预训练词嵌入模型,以及使用和查询加载词嵌入模型工具。我们本章教程中使用Gensim库。

9.4 开发Word2Vec嵌入

Word2Vec是一种用于从文本语料库中学习词嵌入模型的算法。有两种主要的训练算法可用于从文本学习词嵌入模型:连续的词袋(CBOW)和Skip-Gram。我们不会深入讨论这些算法,只会简单介绍一下如何选择目标单词的窗口,提供上下文,确定单词含义。该方法由Tomas Mikolov开发,他以前就职与Google现在在Facebook。
word2Vec模型需要大量文本,例如整个维基百科语料库。但是我们不会用这类语料库,仅仅使用 一个小文本例子来演示训练词嵌入模型的原理。Gensim提供了使用Word2Vec模型的Word2Vec类,从文本学习单词嵌入模型涉及文本加载、将文本分割成句子并将它作为参数传递给Word2Vec实例的构造函数。例如:

sentences = ......
model = Word2Vec(sentences)

具体而言,每个句子必须被标记化,意味着分成单词并准备好(例如,可能预先过滤并且可能转换为优选情况)句子可以说加载到内存中的文本,也可以是逐步加载文本的迭代器,这是大规模文本语料库的加载的方法,Word2Vec构造函数有很多参数;下面是一些值得注意的参数:
-size:(默认是100)嵌入的维数,例如表示每个标记(单词)的密集向量长度
-window:(默认是5)目标字和目标字周围的字之间的最大距离
-min_count:(默认是5)训练模型时要考虑的最小字数,小于此计数的单词将被忽略
-workers:(默认值3)训练时使用的线程数
-sg:(默认为0或CBOW)训练算法CBOW(0)或Skip-gram(1)
刚开始时,默认值已经能满足要求完成任务了,如果你使用的是多核cpu或者是使用GPU运算,那么我建议将workers设置成多核值,在训练结束之后,我们可以通过wv属性来访问它。这是可以进行查询的实际单词矢量模型,例如需要打印所学习的单词词汇:

words = list(model.wv.vocab)
print(words)

也可以查看特定标记的嵌入向量:

print(model['word'])

最后,通过调用单词矢量模型上的save_word2vec_format函数,可以将训练过的模型保存到文件中。默认情况下,模型以二进制格式保存以节省空间。例如:

modle.wv.save_word2vec_format('modle.bin')

入门时,可以将学习的模型保存为ASCII格式并查看内容,可以调用save_word2vec_format函数时设置binary = False来执行此操作,例如:

modle.wv.save_word2vec_format('modle.bin',binary= False)

然后通过Word2Vec.load()函数再次加载保存的模型。例如:

model= Word2Vec.load('model.bin')

我们可以将所有这些与一个有效的例子结合起来。我们不会从文件中加载大型文本文档或语料库,而是使用预先标记化的小型内存列表。训练模型并将单词的最小计数设置为1,以便不忽略任何单词。在学习模型之后,我们总结,打印词汇表,然后为单词“sentence”打印单个向量。最后,模型以二进制格式保存到文件中,加载,然后进行汇总。

from gensim.models import Word2Vec
sentences = [
    ['this','is','the','first','sentence','for','word2vec'],
    ['this','is','secound','sentence'],
    ['yet','another','sentence'],
    ['one','more','sentence'],
    ['and','the','final','sentence']
]
model = Word2Vec(sentences,min_count=1)
print(model)
words = list(model.wv.vocab)
print(words)
print(model['sentence'])
model.save('model.bin')
new_model = Word2Vec.load('model.bin')
print(new_model)

其示例结果如下:

print(model):Word2Vec(vocab=14, size=100, alpha=0.025)
print(words)['this', 'is', 'the', 'first', 'sentence', 'for', 'word2vec', 'secound', 'yet', 'another', 'one', 'more', 'and', 'final']
print(model['sentence'])[-4.3932153e-03  4.9996446e-03  3.8395536e-03  3.4331253e-03
  2.8051641e-03 -3.6040121e-03 -4.9631945e-03  1.8730393e-03
 -3.7610305e-03 -3.4772451e-03  1.5897923e-03  8.5464312e-04
 -3.0013123e-03 -9.1531379e-05 -1.6883557e-03  4.8735086e-04
 -4.2694937e-03  4.7233817e-04  8.9689100e-04 -4.3538711e-03
 -2.7600485e-03 -4.7514704e-03  1.5844182e-03  1.7203739e-03
 -3.3354606e-03  4.3395036e-03 -3.0304438e-03 -2.2012368e-03
 -4.0195184e-03 -4.8476099e-03 -4.1649412e-04 -4.0635904e-03
 -4.2859437e-03  4.4143326e-03  2.4464633e-04  2.7554093e-03
 -7.0612517e-04  4.2472943e-03  2.9121286e-06 -5.2874831e-05
 -1.8779160e-03 -8.5741433e-04  9.8144508e-04  4.5734751e-03
 -4.1618403e-03 -1.2491726e-03  1.3678202e-03  4.2464891e-03
  4.4794790e-03  3.8795243e-03  2.9247612e-04 -4.3525486e-03
 -1.4561928e-04  1.5029532e-03  2.1376288e-03  1.3452580e-03
  3.2858453e-03  1.4102793e-03  1.8084480e-03 -2.6794816e-03
  7.2724809e-04 -2.3574515e-03 -4.6865623e-03  2.9165768e-03
 -3.9128996e-03  1.7019726e-03 -2.0510012e-03  4.8277859e-04
  1.6498364e-03 -2.1685581e-03  3.8715275e-03 -3.2213230e-03
  3.5351126e-03  2.6879262e-03 -4.0457365e-03  3.2360591e-03
 -4.7725253e-04 -7.3874288e-04  3.0384883e-03  2.7823308e-03
  3.8524491e-03 -4.3807635e-03  3.8701240e-03 -1.8334254e-03
  2.9018181e-03 -3.7440876e-03  4.1242205e-03  4.1260049e-03
  2.5114042e-03  2.8071564e-03 -2.9098536e-03  2.1740727e-03
 -2.1272530e-03 -4.8005837e-03  3.4703570e-03  2.8520336e-04
 -5.3913059e-04 -1.8387977e-03 -1.8933687e-03  2.3157052e-03]
 print(new_model):Word2Vec(vocab=14, size=100, alpha=0.025)

可以看到 ,通过一些准备文本文档的工作,你可以使用Gensim轻松创建自己的单词嵌入模型。

9.5 可视化词嵌入

在获得文本数据的词嵌入模型之后,可以通过图形化的方式来观看其详细信息。你可以使用经典投影方法将高维单词向量降维到二维并绘制他们的。可视化可以帮助你的学习模型提供定性诊断,我们可以从训练好的模型中检索所有向量:

x = model[model.wv.vocab]

然后我们在矢量上使用投影方法将其降维,例如scikit-learn中提供的那些方法,然后使用matplotlib将投影绘制为散点图。让我们栏一下使用Principal Component Analysis的示例:

9.5.1 使用PCA绘制单词向量

我们可以使用scikit-learn PCA类创建单词向量的二维PCA模型

pca =PCA(n_components = 2)
result = pca.fit_transform(x)

使用matplotlib绘制得到的投影,将两个维度分别赋给x和y

pyplot.scatter(result[:,0],result[:,1])

我们可以更近一步,用图标本身注释图表上的点。不作修饰的话:

words = list(model.wv.vocab)
for i ,word in enumerate(words):
	pyplot.annotate(word,xy = (result[i,0],result[i,1]))

综合成一个示例:

from gensim.models import Word2Vec
from sklearn.decomposition import PCA
from matplotlib import pyplot as plt
sentences = [
    ['this','is','the','first','sentence','for','word2vec'],
    ['this','is','secound','sentence'],
    ['yet','another','sentence'],
    ['one','more','sentence'],
    ['and','the','final','sentence']
]
model = Word2Vec(sentences,min_count=1)
print(model)
words = list(model.wv.vocab)
print(words)
print(model['sentence'])
model.save('model.bin')
new_model = Word2Vec.load('model.bin')
print(new_model)
def fenge():
    print('*'*50)
x = model[model.wv.vocab]
pca = PCA(n_components=2)
result = pca.fit_transform(x)
plt.scatter(result[:,0],result[:,1])
words = list(model.wv.vocab)
for i,word in enumerate(words):
    plt.annotate(word,xy = (result[i,0],result[i,1]))
plt.show()

其结果:

Word2Vec(vocab=14, size=100, alpha=0.025)
['this', 'is', 'the', 'first', 'sentence', 'for', 'word2vec', 'secound', 'yet', 'another', 'one', 'more', 'and', 'final']
[ 3.3506027e-03 -1.6004874e-03 -6.4718688e-04 -2.8005145e-03
  2.6984653e-03 -4.1073075e-04  4.5237346e-03  3.8454030e-03
  1.4062473e-03  4.6560308e-03  4.0897452e-03  5.8226334e-04
 -1.4448334e-03 -3.1216252e-03 -1.8161410e-03  4.1753220e-04
 -3.1535662e-04 -1.3939689e-04  3.2697176e-03 -1.9169830e-03
  4.1367258e-03  1.0472808e-03 -2.3012497e-03  3.7769089e-03
 -3.8995568e-03 -4.7919550e-04 -2.0453355e-03 -3.4917442e-03
 -4.9620285e-03 -3.6054165e-03 -1.7354928e-03 -3.5315619e-03
 -4.1427873e-03  8.1388443e-04 -2.6569921e-03 -2.1104726e-03
  4.2457418e-03  3.9423853e-03  2.6940859e-05  5.8246637e-04
 -4.3433676e-03  8.6449023e-04  2.8639981e-03 -3.4095587e-03
  2.5706205e-03 -3.6734345e-03 -3.6135738e-04  4.7329073e-03
 -4.3543526e-03  3.6185124e-04 -4.2222873e-03  3.7503163e-03
  5.1588292e-04  3.9372565e-03 -1.1500549e-03  4.9018525e-03
 -1.3552298e-03  3.5837407e-03  2.4763085e-03  1.7844236e-03
  3.9862697e-03 -2.1506688e-03 -1.6671336e-03  1.0172591e-04
 -3.1412023e-03  2.1293384e-03 -1.0608727e-03  1.9958001e-03
 -4.1934028e-03  9.0571394e-04  7.2922633e-04  3.5267135e-03
  1.4308650e-03 -3.7091819e-03 -2.6802516e-03  8.8346562e-05
 -3.8006500e-04  3.9145043e-03 -2.6740420e-03 -1.6246972e-03
 -4.4981339e-03 -3.1348004e-03 -3.4086327e-03 -4.9283262e-03
 -4.2164624e-03  2.6724439e-03  4.0915576e-03 -4.8876693e-03
  1.5391955e-03 -1.3365324e-03  1.0122207e-03 -2.5467831e-03
  2.8405993e-03 -8.2647835e-04  7.9470698e-04 -3.6461521e-03
  4.7350195e-03 -8.1437052e-04  1.8990251e-03  1.7882443e-04]
Word2Vec(vocab=14, size=100, alpha=0.025)

plt.show():
在这里插入图片描述

9.6 加载Google的Word2Vec嵌入

训练自己的单词向量可能是给定NLP问题的最佳方法。但是我们不仅需要大量的时间来训练,还需要一台性能优越的计算机来帮助我们计算,以及在输入数据和训练算法方面需要一些专业的知识。为了解决这些问题,我们使用预训练模型来实现我们的目标而节约大量的时间和计算。下面我们来介绍一下Google的Word2Vec模型。Google除了在Word2Vec Google Code Project上发布了预训练模型还发布了论文和代码。
预先训练的模型只不过是包含分词及其相关向量的文件。Google的Word2Vec模型是咋其新闻数据(约1000亿字)上训练得到的,它包含300万个单词和短语,词向量是300维的,这是一个1.53G的文件(因为这个文件过大,而我的计算机性能有所欠缺,故本节不提供下载源以及后续的演示过程,仅展示其方法和使用结果),解压后是一个名为“GoogleNews-vectors-negative300.bin”的二进制文件(和前面我们保存的’model.bin’类似,前面我们提到模型在保存的时候是以二进制保存的)。这里还是使用Gensim库提供的工具来加载这个文件,调用KeyedVectors.load_word2vec_format()函数将模型保存到内存中:

from gensim.models import KeyedVectors
filename = 'GoogleNews-vectors-negtive300.bin'
model= KeyedVectors.load_word2vec_format(filename,binary = True)

这里做一个简单的有趣的线性代数算法:

queen = (king - man) + woman

上面的加减法表示queen单词的向量等于King向量减去man向量再加上woman向量。King里的man-ness被woman-ness取代成了queen。
Gensim提供了一个接口most_similar函数,用于训练或加载的模型中执行下面这种操作:

result = model.most_similar(positive = ['woman','king'],negative = ['man'],topn = 1)
print(result)

我们将上面的综合在一起:

from gensim.models import KeyedVectors
filename = 'GoogleNews-vectors-negtive300.bin'
model= KeyedVectors.load_word2vec_format(filename,binary = True)
result = model.most_similar(positive = ['woman','king'],negative = ['man'],topn = 1)
print(result)

运行加载Google预训练的Word2Vec模型示例,然后计算(King-man)+woman=?单词的操作变成了向量进行操作。正如预料的一样答案是queen

[('queen',0.711819)]

9.7 加载斯坦福的Glove嵌入

斯坦福大学的研究人员业开发出一套想Word2Vec一样的词嵌入模型训练算法,称为全局向量词表示(Global Vectors for Word Pepresentation)法,简称Glove,这里不会介绍Word2Vec和Glove之间的区别,一般来说对于NLP人员来说大家更喜欢Glove。
与Word2Vec一样,Glove研究人员也提供预训练单词向量,可供选择,你可以下载Glove预训练模型,可以很容易加载它与Gensim一起使用:第一步,将Glove文件格式转化为Word2Vec文件格式,唯一的区别是多了一个小标题行,转换可以通过调用glove2word2vec函数完成。

from gensim.scripts.glove2word2vec import glove2word2vec
glove_input_file = 'glove.txt'
word2_output_file = 'word2vec.txt'
glove2word2vec(glove_input_file,word2_output_file)

转化后文件可以像上面的Word2Vec文件一样加载。首先让我们来看看Glove文件:Glove的下载地址为:
http://nlp.stanford.edu/data/glove.6B.zip
现在文件的名称为:glove.6B.zip是一个压缩包,它有822MB,有4种不同的模型(50,100,200,300维)是在维基百科60亿个单词上训练所得和涵盖了400000个单词词汇。
使用模型的100维版本,我们可以将文件转换为Word2Vec格式

from gensim.scripts.glove2word2vec import glove2word2vec
glove_input_file = 'glove/glove.6B.100d.txt'
word2_output_file = 'glove.6B.100d.txt.word2vec'
glove2word2vec(glove_input_file,word2_output_file)

现在你拥有Word2Vec格式的Glove模型副本,其名称为:glove.6B.100d.txt.word2vec,现在我们加载它并执行相同的(King-man)+woman = ?的示例按照上一小节进行测试。完整的过程如下:

from gensim.models import KeyedVectors
filename = 'glove.6B.100d.txt.word2vec'
#转换后的文件是ASCII格式,故在读取的时候 binary = False
model= KeyedVectors.load_word2vec_format(filename,binary = False)
result = model.most_similar(positive = ['woman','king'],negative = ['man'],topn = 1)
print(result)

其结果为:

[('queen', 0.7698541283607483)]

完整的示例:

from gensim.scripts.glove2word2vec import glove2word2vec
glove_input_file = r'F:\5-model and data\Glove\glove.6B.100d.txt'
word2_output_file = 'glove.6B.100d.txt.word2vec'
glove2word2vec(glove_input_file,word2_output_file)
from gensim.models import KeyedVectors
filename = 'glove.6B.100d.txt.word2vec'
#转换后的文件是ASCII格式,故在读取的时候 binary = False
model= KeyedVectors.load_word2vec_format(filename,binary = False)
result = model.most_similar(positive = ['woman','king'],negative = ['man'],topn = 1)
print(result)

9.8 摘要

本节你了解了如何使用Gensim在Python中开发和加载字嵌入层。具体来说,你了解了:

  1. 如何在文本数据上训练自己的Word2Vec单词嵌入模型
  2. 如何使用主成分分析可视化训练单词嵌入模型
  3. 如何从Google和斯坦福加载预训练好的Word2Vec和Glove字嵌入模型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值