Gensim的简介

简介

Gensim是一款开源的第三方Python工具包,用于从原始的非结构化的文本中,无监督地学习到文本隐层的主题向量表达。
它支持包括TF-IDF,LSA,LDA,和word2vec在内的多种主题模型算法,
支持流式训练,并提供了诸如相似度计算,信息检索等一些常用任务的API接口。

基本概念

  • 语料Corpus: 一组原始文本的集合,用于无监督地训练文本主题的隐层结构,语料中不需要人工标注的附加信息。在Gensim中,Corpus通常是一个可迭代的对象(比如列表)。每次迭代返回一个可用于表达文本对象的稀疏向量。
  • 向量Vector: 由一组文本特征构成的列表,是一段文本在Gensim中的内容部表达。
  • 稀疏向量SparseVector: 通常 我们可以略去向量中多余的0元素,此时向量中的每一个元素是一个(key,value)的tuple.
  • 模型Model: 是一个抽象的术语,定义了两个向量空间的变换(即从文本的一种向量表达变换为另一种向量表达)

Step1 训练语料的预处理

训练语料的预处理是指将文档中原始的字符文本转换充Gensim模型所能理解的稀疏向量的过程。
通常,我们要处理的原生语料是一堆文档集合,每一篇文档又是一些原生字符的集合。在交给Gensim的模型训练之前,我们需要将这些原生字符解析成Gensim能处理的稀疏向量格式。
由于语言和应用的多样性,Gensim没有对预处理的接口做出任何强制性的限定,通常,我们徐对原始的文本进行分词、去除停用词等操作,得到每一篇文档的特征列表。例如在词袋模型中,文档的特征就是其包含的word:

texts = [['human', 'interface', 'computer'],
 ['survey', 'user', 'computer', 'system', 'response', 'time'],
 ['eps', 'user', 'interface', 'system'],
 ['system', 'human', 'system', 'eps'],
 ['user', 'response', 'time'],
 ['trees'],
 ['graph', 'trees'],
 ['graph', 'minors', 'trees'],
 ['graph', 'minors', 'survey']]

其中,corpus的每一个元素对应一篇文档。
接下来,我们可以调用Gensim提供的API建立语料特征(此处是word)的索引字典,并将文本特征的原始表达转化成词袋模型对应的稀疏向量的表达。依然以词袋模型为例:

from gensim import corpora
dictionary = corpora.Dictionary(texts)
corpus = [dictionary.doc2bow(text) for text in texts]
print(corpus[0]) # [(0,1), (1, 1), (2, 1)] # (word index, freq) 没有出现的vocab 就不会在这里显示

到这里,训练语料的预处理工作就完成了。我们得到了语料中每一篇文档对应的稀疏向量(这里是bow向量);向量的每一个元素代表了一个word在这篇文档中出现的次数。值得注意的是,虽然词袋模型是很多主题模型的基本假设,这里介绍的doc2bow函数并不是将文本转化成稀疏向量的唯一途径。在下一小节里我们将介绍更多的向量变换函数。
最后,出于内存优化的考虑,Gensim支持文档的流式处理。我们需要做的,只是将上面的列表封装成一个Python 迭代器; 每次迭代都返回一个稀疏向量即可。

class MyCorpus(object):
	def __iter__(self):
		for line in open("mycorpus.txt"):
			yield dictionary.doc2bow(line.lower().split()) # 每次迭代 都返回一个稀疏向量

Step2 主题向量的变换

对文本向量的变换是Gensim的核心,通过挖掘语料中隐藏的语义结构特征,我们最终可以变换出一个简洁高效的文本向量。
在Gensim中,每一个向量变换的操作都对应一个主题模型,例如上一小节提到的对应着词袋模型的doc2bow变换。每一个模型又都是一个标准的python对象。下面以TF-IDF模型为例,介绍Gensim模型的一般使用方法。
首先是模型对象的初始化,通常,Gensim模型都接受一段训练语料(注意Gensim中,语料对应着一个稀疏向量的迭代器)作为初始化的参数。显然越是复杂的模型 需要配置的参数越多。

from gensim import models
tfidf = models.TfidfModel(corpus)

其中,corpus是一个返回bow向量的迭代器,这两行代码将完成对corpus中出现的每一个特征的IDF值得统计工作。
接下来,我们可以调用这个模型将任意一段语料(依然是bow向量的迭代器)转换成TFIDF向量(的迭代器)。需要注意的是,这里的bow向量必须与训练语料的bow向量共享同一个特征字典(即共享同一个向量空间)。

doc_bow = [(0,1), (1,1)]
print(tfidf[doc_bow]) # [(0, 0.7071678), (1, 0.70710678)]

注意,同样是出于内存的考虑,model[corpus]方法返回的是一个迭代器,如果要多次访问model[corpus] 的返回结果,可以先将结果向量序列化到磁盘上。

我们也可以将训练好的模型持久化到磁盘上,以便下一次使用:

tfidf.save("./model.tfidf")
tfidf = models.TfidfModel.load('./model.tfidf')

Gensim内置了多种主题模型的向量变换,包括LDA,LSI, RP, HDP等。这些模型通常以bow向量或tfidf向量的语料为输入,生成相应的主题向量。所有的模型都支持流式计算。关于Gensim模型更多的介绍,可以参考api reference

Step3 文档相似度的计算

在得到每一篇文档对应的主题向量后,我们就可以计算文档之间的相似度,进而完成如文本聚类、信息检索之类的任务。在Gensim中,也提供了这一类接口。
以信息检索为例。对于一篇待检索的query,我们的目标是从文本集合中检索出主题相似度最高的文档。
首先,我们需要将待检所的query和文本放在同一个向量空间里进行表达(以LSI向量空间为例):

#构造LSI模型并将待检索的query和文本转化为LSI主题向量
# 转换之前的corpus和query 均是BOW向量
lsi_model = models.LsiModel(corpus, id2word = dictionary, num_topics=2)
documents = lsi_model[corpus]
query_vec = lsi_model[query]

接下来,我们用待检索的文档向量初始化一个相似度计算的对象:

index = similarities.MatrixSimilarity(documents)

我们也可以通过save() 和load()方法持久化这个相似度矩阵:

index.save("./tmp/deerwester.index")
index = similarities.MatrixSimilarity.load('./tmp/deerwester.index')

注意,如果待索引的目标文档过多,使用similarites.MatrixSimilarity类往往会带来内存不够用的问题。此时 可以改用similarites.Similarity类。二者的接口接本保持一致。
最后我们借助index对象计算任意一段query和所有文档的余弦相似度:

sims = index[query_vec] # return: an iterator of tuple (idx, sim)

参考:gensim的入门教程

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值