gensim使⽤⽅法以及例⼦
gensim是⼀个python的⾃然语⾔处理库,能够将⽂档根据TF-IDF, LDA, LSI 等模型转化成向量模式,以便进⾏进⼀步的处理。此
外,gensim还实现了word2vec功能,能够将单词转化为词向量。关于词向量的知识可以看我之前的
关于gensim的使⽤⽅法,我是根据官⽹的资料来看的,思路也是跟着官⽹tutorial⾛的,英⽂好的或者感觉我写的不全⾯的可以去看
1. corpora 和 dictionary
1.1 基本概念和⽤法
corpora是gensim中的⼀个基本概念,是⽂档集的表现形式,也是后续进⼀步处理的基础。从本质上来说,corpora其实是⼀种格式或者说约定,其实就是⼀个⼆维矩阵。举个例⼦,现在有⼀个⽂档集,⾥⾯有两篇⽂档
hurry up
rise up
这两篇⽂档⾥总共出现了3个词,hurry, rise, up。如果将这3个词映射到数字,⽐如说hurry, rise, up 分别对应1,2,3, 那么上述的⽂档集的⼀种表现形式可以是
1,0,1
0,1,1
这种⽅法只考虑了词频,且不考虑词语间的位置关系。因为第⼀个⽂档中的两个词分别编号1,3且都只出现了⼀次,所以第1个和第3个为1,第2个数为0。
当然了,在实际运⾏中,因为单词数量极多(上万甚⾄10万级别),⽽⼀篇⽂档的单词数是有限的,所以如果还是采⽤密集矩阵来表⽰的话,会造成极⼤的内存浪费,所以gensim内部是⽤稀疏矩阵的形式来表⽰的。
那么,如何将字符串形式的⽂档转化成上述形式呢?这⾥就要提到词典的概念(dictionary)。词典是所有⽂档中所有单词的集合,⽽且记录了各词的出现次数等信息。
在实际的操作中,对于字符串形式的⽂档,⾸先要将字符串分割成词语列表。⽐如”hurry up”要分割成[“hurry”,”up”]。 对于中⽂来讲,分词就是⼀个很关键的问题,不过可以去⼀些分词库来实现。我⼀般⽤的是jieba. ⽽对于英⽂来说,虽然分词⽅便,但是要注意词⼲提取和词形还原。
在将⽂档分割成词语之后,使⽤dictionary = corpora.Dictionary(texts)⽣成词典,并可以使⽤save函数将词典持久化。⽣成词典以后 corpus = [dictionary.doc2bow(text) for text in texts]档转化为向量形式。⽰例代码如下
from gensim import corpora
from collections import defaultdict
documents = ["Human machine interface for lab abc computer applications",
"A survey of user opinion of computer system response time",
"The EPS user interface management system",
"System and human system engineering testing of EPS",
"Relation of user perceived response time to error measurement",
"The generation of random binary unordered trees",
"The intersection graph of paths in trees",
"Graph minors IV Widths of trees and well quasi ordering",
"Graph minors A survey"]
# 去掉停⽤词
stoplist = set('for a of the and to in'.split())
texts = [[word for word in document.lower().split() if word not in stoplist]
for document in documents]
# 去掉只出现⼀次的单词
frequency = defaultdict(int)
for text in texts:
for token in text:
frequency[token] += 1
texts = [[token for token in text if frequency[token] > 1]
for text in texts]
dictionary = corpora.Dictionary(texts)  # ⽣成词典
# 将⽂档存⼊字典,字典有很多功能,⽐如
# ken2id 存放的是单词-id key-value对
# diction.dfs 存放的是单词的出现频率
dictionary.save('/tmp/deerwester.dict')  # store the dictionary, for future reference
corpus = [dictionary.doc2bow(text) for text in texts]
corpora.MmCorpus.serialize('/', corpus)  # store to disk, for later use
注意最后的corpora.MmCorpus.serialize 将corpus持久化到磁盘中。相反,可以⽤
corpus = corpora.MmCorpus('/')
来从磁盘中读取corpus。
除了MmCorpus以外,还有其他的格式,例如SvmLightCorpus, BleiCorpus, LowCorpus等等,⽤法类似。
1.2 dictionary的其他⼀些⽤法
dictionary还有其他的⼀些⽤法,现罗列⼀部分
dictionary.filter_n_most_frequent(N)
过滤掉出现频率最⾼的N个单词
dictionary.filter_extremes(no_below=5, no_above=0.5, keep_n=100000)
1.去掉出现次数低于no_below的
2.去掉出现次数⾼于no_above的。注意这个⼩数指的是百分数
3.在1和2的基础上,保留出现频率前keep_n的单词
dictionary.filter_tokens(bad_ids=None, good_ids=None)
有两种⽤法,⼀种是去掉bad_id对应的词,另⼀种是保留good_id对应的词⽽去掉其他词。注意这⾥bad_ids和good_ids都是列表形式
dictionarypacity()
在执⾏完前⾯的过滤操作以后,可能会造成单词的序号之间有空隙,这时就可以使⽤该函数来对词典来进⾏重新排序,去掉这些空隙。
1.3 分批处理和分布式计算结果的汇总
dictionary和corpora的基本⽤法在上⼀节已经提过,但是当⽂本的规模很⼤时,也许会造成内存不⾜以容纳⽂本的情况,这就需要将所有⽂本分批处理,最后再将各批次计算得到的结果进⾏汇总。分布式计算时也有类似的需求。
这⾥假设在两个批次中,分别⽣成了dict1,corpus1以及dict2,corpus2.
第⼀步,⾸先将两个词典合并。当然,如果是先统⼀⽣成词典再分批⽣成词向量的话,可以跳过这⼀步,因为词典是⼀样的。
合并词典很简单
dict2_to_dict1 = _with(dict2)
要注意的是,得到的dict2_to_dict1并不是⽣成后的词典,⽽是dict2中的单词序号到这些词在合并后词典新序号的映射表。⽽dict1本⾝成为合并后的新词典。
第⼆部,合并corpus
如果之前跳过了第⼀步,即dict1就是dict2的话,可以直接进⾏合并。合并有两种⽅式,⼀种是
merged_corpus = [x for x in corpus1] + [x for x in corpus2]
另外⼀种,则需使⽤内置的itertools类
merged_corpus = itertools.chain(corpus1, corpus2)
merged_corpus = [x for x in merged_corpus]
如果之前的词典也是分批⽣成的话,则需要对corpus2进⾏⼀定的处理
new_corpus2 = dict2_to_dict1[corpus2]
merged_corpus = itertools.chain(corpus1, new_corpus2)
merged_corpus = [x for x in merged_corpus]
这样,就把分批处理得到的dict和corpus都合并起来了。
2. models
在models中,可以对corpus进⾏进⼀步的处理,⽐如使⽤tf-idf模型,lsi模型,lda模型等,⾮常强⼤。
在按照之前的⽅法⽣成了corpus和dictionary以后,就可以⽣成模型了
tfidf_model = models.TfidfModel(corpus)
注意,⽬前只是⽣成了⼀个模型,但这是类似于⽣成器,并不是将对应的corpus转化后的结果。对tf-idf模型⽽⾔,⾥⾯存储有各个单词的词频,⽂频等信息。想要将⽂档转化成tf-idf模式表⽰的向量,还要使⽤如下命令
corpus_tfidf = tfidf_model[corpus]
对于lda和lsi模型,⽤法有所不同
可以看到,这⾥除了corpus以外,还多了num_topic的选项。这是指的潜在主题(topic)的数⽬,也等于
转成lsi模型以后每个⽂档对应的向量长度。转化以后的向量在各项的值,即为该⽂档在该潜在主题的权重。因此lsi和lda的结果也可以看做该⽂档的⽂档向量,⽤于后续的分类,聚类等算法。值得注意的是,id2word是所有模型都有的选项,可以指定使⽤的词典。
由于这⾥num_topics=2 ,所以可以⽤作图的⽅式直观的显现出来
可以很清楚的看到,9个⽂档可以看成两类,分别是前5⾏和后4⾏。这⼀部分的代码如下
lsi_model = models.LsiModel(corpus_tfidf, id2word=dictionary, num_topics=2)corpus_lsi = lsi_model[corpus_tfidf]
import  os
from  gensim import  corpora, models, similarities
from  pprint import  pprint
from  matplotlib import  pyplot as  plt
import  logging
# logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
def  PrintDictionary (dictionary):
token2id = ken2id
dfs = dictionary.dfs
token_info = {}
for  word in  token2id:
token_info[word] = dict(
word = word,
id = token2id[word],
freq = dfs[token2id[word]]
)
token_items = token_info.values()
token_items = sorted(token_items, key = lambda  x:x['id'])
print('The info of dictionary: ')
pprint(token_items)
exists的用法
print('--------------------------')
def  Show2dCorpora (corpus):
nodes = list(corpus)
ax0 = [x[0][1] for  x in  nodes] # 绘制各个doc 代表的点
ax1 = [x[1][1] for  x in  nodes]
# print(ax0)
# print(ax0)
# print(ax1)
plt.plot(ax0,ax1,'o')
plt.show()
if (ists("/tmp/deerwester.dict")):
dictionary = corpora.Dictionary.load('/tmp/deerwester.dict')
corpus = corpora.MmCorpus('/')
print("Used files generated from first tutorial")
else:
print("Please run first tutorial to generate data set")
PrintDictionary(dictionary)
# 尝试将corpus(bow形式) 转化成tf-idf形式
tfidf_model = models.TfidfModel(corpus) # step 1 -- initialize a model 将⽂档由按照词频表⽰转变为按照tf-idf格式表⽰
doc_bow = [(0, 1), (1, 1),[4,3]]
doc_tfidf = tfidf_model[doc_bow]
# 将整个corpus转为tf-idf格式
corpus_tfidf = tfidf_model[corpus]
# pprint(list(corpus_tfidf))
# pprint(list(corpus))
## LSI模型 **************************************************
# 转化为lsi模型, 可⽤作聚类或分类
lsi_model = models.LsiModel(corpus_tfidf, id2word=dictionary, num_topics=2)
corpus_lsi = lsi_model[corpus_tfidf]
nodes = list(corpus_lsi)
# pprint(nodes)
lsi_model.print_topics(2) # 打印各topic的含义
# ax0 = [x[0][1] for x in nodes] # 绘制各个doc代表的点
# ax1 = [x[1][1] for x in nodes]
# print(ax0)
# print(ax1)
# plt.plot(ax0,ax1,'o')
# plt.show()
lsi_model.save('/tmp/model.lsi') # same for tfidf, lda, ...
lsi_model = models.LsiModel.load('/tmp/model.lsi')
#  *********************************************************
## LDA模型 **************************************************
lda_model = models.LdaModel(corpus_tfidf, id2word=dictionary, num_topics=2)
corpus_lda = lda_model[corpus_tfidf]
Show2dCorpora(corpus_lsi)
# nodes = list(corpus_lda)
# pprint(list(corpus_lda))
# 此外,还有Random Projections, Hierarchical Dirichlet Process等模型
3. similarities
这⼀部分主要负责计算⽂档间的相似度。与向量的相似度计算⽅式⼀样,采⽤余弦⽅法计算得到。⼀般来讲,使⽤lsi模型得到的向量进⾏计算效果⽐较好。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。