【NLP学习笔记】(二)gensim使用之Topics and Transformations

本文主要翻译自:https://radimrehurek.com/gensim/tut2.html

这个教程会向大家展示如何将代表文档的向量转换成另一种向量,做这件事的目的主要有两个:

  1. 发现语料中的隐藏结构,比如词与词之间的联系,然后用一种全新的方式、一种更能表现语义的方式(semantic way)来描述文档。

  2. 使文档的表示更加紧凑,这样可以提高效率和功效,因为新的表达方式消耗更少的资源,并且去除了噪音。

一、回顾

在之前的gensim基础使用中,我们介绍了如何将语料提取特征后转换为向量(基于词袋模型),上一章中的结果:

# 清洗后的语料库,只有九句话,代表九个文档
[['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']]
# 根据上面语料训练的词典,每个词都有一个id
{'computer': 0,
 'eps': 8,
 'graph': 10,
 'human': 1,
 'interface': 2,
 'minors': 11,
 'response': 3,
 'survey': 4,
 'system': 5,
 'time': 6,
 'trees': 9,
 'user': 7}
# 根据词典基于词袋模型,训练上面语料的结果,(0,1.0)的意思是id为0的单词,即“computer”在第一篇文章中出现了1次。其它类似。
[[(0, 1.0), (1, 1.0), (2, 1.0)],
 [(0, 1.0), (3, 1.0), (4, 1.0), (5, 1.0), (6, 1.0), (7, 1.0)],
 [(2, 1.0), (5, 1.0), (7, 1.0), (8, 1.0)],
 [(1, 1.0), (5, 2.0), (8, 1.0)],
 [(3, 1.0), (6, 1.0), (7, 1.0)],
 [(9, 1.0)],
 [(9, 1.0), (10, 1.0)],
 [(9, 1.0), (10, 1.0), (11, 1.0)],
 [(4, 1.0), (10, 1.0), (11, 1.0)]]

###二、加载上一章中结果(保存的字典和语料向量)

from gensim import corpora, models, similarities
import os
if(os.path.exists('./gensim_out/deerwester.dict')):
    dictionary = corpora.Dictionary.load('./gensim_out/deerwester.dict')
    corpus = corpora.MmCorpus('./gensim_out/deerwester.mm')
    print("使用之前已经存储的字典和语料向量")
else:
    print("请先通过上一章生成deerwester.dict和deerwester.mm")

#pprint(dictionary.tokenz`2id)
#pprint(corpus)

三、初始化一个转换模型(Creating a transformation)

转换模型是标准的python对象,通常需要传入一个语料库进行初始化。
我们使用教程1中的旧语料库来初始化(训练)转换模型。也就是上面加载的corpus, 不同的转换模型一般需要不同的初始化参数; 在TfIdf的情况下,“训练”仅包括通过提供的语料库一次并计算其所有词频和逆文档频率。 训练其他模型,例如潜在语义分析或潜在狄利克雷分析,涉及更多,因此也会消耗更多时间。

tfidf = models.TfidfModel(corpus) #初始化一个模型

doc_bow = [(0, 1), (1, 1)]

print(tfidf[doc_bow])#输出:[(0, 0.70710678), (1, 0.70710678)]

上面已经创建了tfidf模型,我们应该将其作为一个只读对象来看待,用它可以将旧的向量表示(上一节中的词袋模型)转换为新的向量表示(比如tf-idf权重)
假设新文本为:“Human computer interaction
doc_bow是新文本经过上一章的清洗、分词、基于词袋模型转换后的结果,(0, 1)表示id为0,即“computer”。1表示“computer”在新文本中出现了1次;(1, 1)表示id为1,即“human”也出现了1次。
tfidf模型将新文本从词袋向量模型([(0, 1), (1, 1)])转换为了词频-逆文档频率权重向量([(0, 0.70710678), (1, 0.70710678)]),即“computer”的权重为0 0.70710678,“human”的权重为0.70710678

四、序列化转换后的结果

调用model_name[corpus]仅在旧的语料库文档流周围创建一个包装器 ,实际转换在文档迭代期间即时完成。 我们无法在调用corpus_transformed = model [corpus]时转换整个语料库,因为这意味着将结果存储在内存中,这与gensim的内存独立的目标相矛盾。 如果您将多次迭代转换的corpus_transformed,并且转换成本很高,请先将生成的语料库序列化到磁盘然后再使用它。

#用tfidf转换语料库corpus
corpus_tfidf = tfidf[corpus]

 #initialize an LSI transformation(初始化LSI模型)
lsi = models.LsiModel(corpus_tfidf, id2word=dictionary, num_topics=2)

#create a double wrapper over the original corpus: bow->tfidf->fold-in-lsicorpus_lsi = lsi[corpus_tfidf] 
lsi.print_topics(2)
#输出:topic #0(1.594): -0.703*"trees" + -0.538*"graph" + -0.402*"minors" + -0.187*"survey" + -0.061*"system" + -0.060*"response" + -0.060*"time" + -0.058*"user" + -0.049*"computer" + -0.035*"interface"
topic #1(1.476): -0.460*"system" + -0.373*"user" + -0.332*"eps" + -0.328*"interface" + -0.320*"response" + -0.320*"time" + -0.293*"computer" + -0.280*"human" + -0.171*"survey" + 0.161*"trees"

根据上面结果可以看出“trees”, “graph” and “minors都是相关联的词汇,并且对第一个主题的贡献度最高,第二个主题,更多的是关注其他的词汇

for doc in corpus_lsi:
    print(doc)

#输出结果(可以看出前五个文档与第二个主题关联度更高):
[(0, -0.066), (1, 0.520)] # "Human machine interface for lab abc computer applications"
[(0, -0.197), (1, 0.761)] # "A survey of user opinion of computer system response time"
[(0, -0.090), (1, 0.724)] # "The EPS user interface management system"
[(0, -0.076), (1, 0.632)] # "System and human system engineering testing of EPS"
[(0, -0.102), (1, 0.574)] # "Relation of user perceived response time to error measurement"
[(0, -0.703), (1, -0.161)] # "The generation of random binary unordered trees"
[(0, -0.877), (1, -0.168)] # "The intersection graph of paths in trees"
[(0, -0.910), (1, -0.141)] # "Graph minors IV Widths of trees and well quasi ordering"
[(0, -0.617), (1, 0.054)] # "Graph minors A survey"

保存模型与加载模型

lsi.save('./gensim_out/model.lsi') #保存 same for tfidf, lda, ...

lsi = models.LsiModel.load('/tmp/model.lsi') #加载

gensim中可用的转换模型

1.Term Frequency * Inverse Document Frequency, Tf-Idf

model = models.TfidfModel(corpus, normalize=True)

2.Latent Semantic Indexing, LSI (or sometimes LSA)

model = models.LsiModel(tfidf_corpus, id2word=dictionary, num_topics=300)
model.add_documents(another_tfidf_corpus)  #now LSI has been trained on tfidf_corpus + another_tfidf_corpus
lsi_vec = model[tfidf_vec]  #convert some new document into the LSI space, without affecting the model
...
model.add_documents(more_documents)  #tfidf_corpus + another_tfidf_corpus + more_documents
lsi_vec = model[tfidf_vec]
...

3.Random Projections, RP

model = models.RpModel(tfidf_corpus, num_topics=500)

4.Latent Dirichlet Allocation, LDA

model = models.LdaModel(corpus, id2word=dictionary, num_topics=100)

5.Hierarchical Dirichlet Process, HDP

model = models.HdpModel(corpus, id2word=dictionary)

你可能感兴趣的:(自然语言处理)