主题文本分析:
首先读取txt文本,并删除stop_list中存放的停止词汇
f = open('..\\LDA_test.txt')
texts = [[word for word in line.strip().lower().split() if word not in stop_list] for line in f]
print('Text = ')
pprint(texts) #输出格式处理好的文本内容
然后计算生成文本内容的词典
dictionary = corpora.Dictionary(texts)
print('corpora.Dictionary:')
print(dictionary)
然后将每个文档或者文档中的每个句子(一行)向量化
corpus = [dictionary.doc2bow(text) for text in texts]
print('corpus')
print(corpus)
然后计算词频
corpus_tfidf = models.TfidfModel(corpus)[corpus]
print('corpus_tfidf:')
print(corpus_tfidf)
然后可以条用LSI模型做文本分析
lsi = models.LsiModel(corpus_tfidf, num_topics=2, id2word=dictionary)
topic_result = [a for a in lsi[corpus_tfidf]]
pprint(topic_result) #输出每个文档或者每行句子的主题
或者输出每个主题的词汇构成
print('LSI Topics:')
pprint(lsi.print_topics(num_topics=2, num_words=5))
计算文档两两之间的相似度
similarity = similarities.MatrixSimilarity(lsi[corpus_tfidf]) # similarities.Similarity()
print('Similarity:')
pprint(list(similarity))
也可以用LDA模型来做主题分析
num_topics = 2
lda = models.LdaModel(corpus_tfidf, num_topics=num_topics, id2word=dictionary,
alpha='auto', eta='auto', minimum_probability=0.001, passes=10)
输出每个文档的主题分布:
doc_topic = [doc_t for doc_t in lda[corpus_tfidf]]
print('Document-Topic:\n')
pprint(doc_topic)
或者:
for doc_topic in lda.get_document_topics(corpus_tfidf):
print(doc_topic)
然后输出每个主题的词分布:
for topic_id in range(num_topics):
print('Topic', topic_id)
# pprint(lda.get_topic_terms(topicid=topic_id))
pprint(lda.show_topic(topic_id))
计算文档之间的相似度
similarity = similarities.MatrixSimilarity(lda[corpus_tfidf])
print('Similarity:')
pprint(list(similarity))
基于lda第三方库实现的主题分析
需要先安装这个第三方库lda( pip install lda)
首先要把每个文档的格式转换为向量来表示
所以多个文档就形成了一个矩阵,维度为k*n,k为每个文档向量的长度,n为文档个数
例如:矩阵中的每个元素可以用tf—idf词频来表示
利用LDA模型进行建模
topic_num = 20
model = lda.LDA(n_topics=topic_num, n_iter=800, random_state=1)
model.fit(X)
输出各个主题的词分布
topic_word = model.topic_word_
print(("type(topic_word): {}".format(type(topic_word))))
print(("shape: {}".format(topic_word.shape)))
print((topic_word[:, :5])) #由于词分布太长了,所以只用输出部分
可以输出每个主题topK个词汇:
n = 7
for i, topic_dist in enumerate(topic_word):
topic_words = np.array(vocab)[np.argsort(topic_dist)][:-(n + 1):-1]
print(('*Topic {}\n- {}'.format(i, ' '.join(topic_words))))
其中vocab为所有文档的词汇元组,就是对应词向量的词汇元组
长度等于每个文档词向量的长度
最终输出我们想要知道的每个文档对应的最有可能的主题:
doc_topic = model.doc_topic_
print(("type(doc_topic): {}".format(type(doc_topic))))
print(("shape: {}".format(doc_topic.shape)))
for i in range(10):
topic_most_pr = doc_topic[i].argmax()
print(("文档: {} 主题: {} value: {}".format(i, topic_most_pr, doc_topic[i][topic_most_pr])))
最后是可视化:
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
# Topic - word
plt.figure(figsize=(7, 6))
# f, ax = plt.subplots(5, 1, sharex=True)
for i, k in enumerate([0, 5, 9, 14, 19]):
ax = plt.subplot(5, 1, i+1)
ax.plot(topic_word[k, :], 'r-')
ax.set_xlim(-50, 4350) # [0,4258]
ax.set_ylim(0, 0.08)
ax.set_ylabel("概率")
ax.set_title("主题 {}".format(k))
plt.xlabel("词", fontsize=13)
plt.tight_layout()
plt.suptitle('主题的词分布', fontsize=15)
plt.subplots_adjust(top=0.9)
plt.show()
# Document - Topic
plt.figure(figsize=(7, 6))
# f, ax= plt.subplots(5, 1, figsize=(8, 6), sharex=True)
for i, k in enumerate([1, 3, 4, 8, 9]):
ax = plt.subplot(5, 1, i+1)
ax.stem(doc_topic[k, :], linefmt='g-', markerfmt='ro')
ax.set_xlim(-1, topic_num+1)
ax.set_ylim(0, 1)
ax.set_ylabel("概率")
ax.set_title("文档 {}".format(k))
plt.xlabel("主题", fontsize=13)
plt.suptitle('文档的主题分布', fontsize=15)
plt.tight_layout()
plt.subplots_adjust(top=0.9)
plt.show()