前言:对于第一个版本 的基于LDA的文本关键词提取 实现了给定文本,提取其关键的功能。后来有需求变动,需要给出所提取的关键词的重要程度排名。便有一个问题:如何判断文本自身的词语的重要性几何,其打分的依据是什么。这也是所有关键词提取方法中最重要的一步。
思路:1. LDA模型训练得到 topic_word 。由此可以知道每个topic 由哪些单词所代表,以及每个单词在这个topic的重要性得分。
2. 对于测试集文本,经过LDA模型之后,得到该文本对应的topic(通常一个文本会有多个topic,舍弃概率小的,保留大概率的topic)。由1得到的每个topic包含的单词,将其赋值给测试集文本,作为候选关键词。而对于每个候选关键词,其得分 score= 每个topic的概率*每个单词属于该topic的概率。
实现算法:在LDA模型完成之后的后续代码。
a = lda.print_topics(num_topics=6)
topic_word_dict = {}
for k in range(num_topics):
b = lda.print_topic(k)
b = b.split(' + ')
word_score_list = []
for i in b:
temp1 = i.split('*')
#print(temp1)
temp1[1] = eval(temp1[1])
word_score_list.append(temp1)
topic_word_dict[k] = word_score_list
#print(topic_word_dict)
doc_topic_dict = {} # key: 第i篇文章 value: 第i篇文章的主题分布
doc_word_dict = {} # key: 第i篇文章 value: 第i篇文章的主题所包含的词语+得分。
for i in range(M):
templist2 = [] #临时变量,存储topici包含的词语
test_doc=train[i]#查看训练集中第i个样本
doc_bow = dictionary.doc2bow(test_doc) #文档转换成bow
num_show_topic = 2 # 每个文档取其前2个主题
doc_topics = lda.get_document_topics(doc_bow) # 某文档的主题分布
doc_topic_dict[i] = doc_topics[:num_show_topic]
for topic in doc_topic_dict[i]:
temp_word = topic_word_dict[topic[0]]
for k in range(len(temp_word)):
temp_word[i][0] = float(temp_word[i][0]) * float(topic[1])
#print(temp_word)
templist2 += temp_word
# 找出templist2所有关键词
a = set()
for word in templist2:
a.add(word[1])
b = len(templist2)
c = {}
for word in a:
c[word] = 0
for m in range(b):
if templist2[m][1] == word :
c[word] += float(templist2[m][0])
doc_word_dict[i] = c
#print(doc_word_dict)
for i in range(M):
keyword = {}
print('文档%s的关键词:' %filelist[i])
for word in train[i]:
if word in doc_word_dict[i].keys():
keyword[word] = doc_word_dict[i][word]
keyword = sorted(keyword.items(), key=lambda x: x[1], reverse=True)
print(keyword)
问题:如何遍历一个列表,如何合并其元素里相同的项。
由于列表的每个元素又是一个列表,这个子列表包含两个子元素。子元素有一项是单词,故先用一个集合保存单词,用一个字典保存结果。再遍历整个列表,判断每个元素的子元素的单词 ==word, 将其概率值赋值给字典。