1.将corpus转化为ndarray
from gensim import matutils
numpy_matrix =
matutils.corpus2dense(corpus_tfidf,len(dictionary))
2.接下来我需要根据指定行号,抽出两个向量出来
实际上numpy_matrix[1,:]就抽取出第二行了
3.计算两个向量的cosine值
from nltk.cluster import
util
util.cosine_distance(numpy_matrix[2,:], numpy_matrix[5,:])
4.然而,对于超过3000篇以上的文本,如果每个文本都不大的话,很可能一篇文本只和几篇十几篇其他文本有相同词汇,而与其他文档都没有相同词汇,换句话说,大多数文档与目标文档的cosine数值是0,显然,这种情况并不适合对文本进行聚类,因而需要降维,降维的目的在于使用主题空间替代词汇空间,来容纳文档集合,从而压缩文档之间的距离,使基于文本相似度的聚类成为可能。
这里可以使用LSI建立主题空间,也可以使用LDA建立主题空间,LSI模型无论道理还是操作都很容易,LDA虽然对数学功底有要求,不过从操作层面上讲,Gensim已经提供了所有需要的基本功能,现在我需要对一个语料库建立主题空间,然后比较这个语料库中指定的两两文档之间的相似度。
(1) from gensim import corpora,models,similarities
model
=
models.ldamodel.LdaModel(corpus,num_topics=100,id2word=corpus.id2word)
(2) 将每个文档中的主题都列出来
topics =[model[c] for c in corpus]
print topics[0]
result:
[(topic_index,topic_weight),......]
(3)
实际上,我更想要权重TOP10或者100主题中,权重为TOP10的词汇,这个怎么获得?
说到这里,有两个很有用的函数
show_topic(topicid,
topn=10)
show_topics(num_topics=10,
num_words=10, log=False,
formatted=True
lda = LdaModel(corpus, num_topics=10)
(4) 如何在主题空间比较两两文档之间的相似度
topics =[model[c] for c in
corpus]
dense =
np.zeros((len(topics),100),float)
for ti,t in
enumerate(topics):
for tj,v in t:
dense[ti,tj] = v
# 得到的是dense[文档id,主题id]=某文档在某主题的权重
#接下来计算文档相似度--得到矩阵中文档间距离的方阵
from
scipy.spatial import distance
pairwise
= distance.squareform(distance.pdist(dense))
largest =
pairwise.max()
for ti in
range(len(topics)): #将对角线元素全部置为比矩阵中最大值还要大,little trick,原因?
pairewise[ti,tj] = largest + 1
#distance.squareform:用于将v向量(长度为d*(d-1)/2)转化为对角线全为零的方阵
#distance.pdist:pdist(X):计算两两行向量之间的欧几里得距离
#然后我们就可以对给定文档,找出与其最相似文档
def closest_to(doc_id):
return pairwise[doc_id].argmin()
#darray.argmin(axis=None,
out=None)
#Return indices of the
minimum values along the given axis of a.
#Refer to numpy.argmin for detailed documentation.
5.主题数目的选择
前述主题数目的选择都相当随意,如果我们仅仅把主题抽取作为处理的中间环节,那么对大多数用户来说,主题数量对最终结果并无影响,也就是说,只要你抽取了足够多的主题,最终结果并区别。
不过即使这样,你有时候仍然需要去确定需要抽取多少主题,有一种叫做垂直狄利克莱过程的方法,它在Gensim中有所实现。
hdp =
gensim.models.hdpmodel.HdpModel(mm,id2word)
剩余流程和使用LDA一样,不过使用这种方法花费的时间更长一些。
(待完成)