聚类算法之LDA
程序员文章站
2022-05-19 13:16:43
...
因工作需要,对2000多篇文件进行聚类,由于文本长度较短,所以聚类效果不好,随着主题数量的增加,困惑度一直增加,并未出现困惑度减少的现象,让我一直怀疑自己的做法是否正确。后来通过对通过标题+文本的拼接,才出现较好的收敛;
perplexity(困惑度)
在对文本的主题特征进行研究时,要指定LDA生成的主题的数目,而一般的解决方法是使用perplexity来计算其中z是主题,w是文档,gamma是训练集学出来的文本-主题分布,所以perplexity的上半部分就是生成整个文档的似然估计(表示训练集训练出的参数的生成能力)的负值,由于概率取值范围为【0,1】,按照对数函数的定义,分子值是一个大数,而分母是整个测试集的单词数目。
也就是说模型生成能力越强,perplexity值越小。
perplexity=exp^{ - (∑log(p(w))) / (N) }
其中,P(W)是指的测试集中出现的每一个词的概率,具体到LDA的模型中就是P(w)=∑z p(z|d)*p(w|z)【z,d分别指训练过的主题和测试集的各篇文档】。p(z|d)表示的是一个文档中每个主题出现的概率,p(w|z)表示的是词典中的每一个单词在某个主题下出现的概率。分母的N是测试集中出现的所有词,或者说是测试集的总长度,不排重。
sklearn中关于perplexity的计算:
Perplexity is defined as exp(-1. * log-likelihood per word)
if sub_sampling:
word_cnt = X.sum() * (float(self.total_samples) / current_samples)
else:
word_cnt = X.sum()
perword_bound = bound / word_cnt
return np.exp(-1.0 * perword_bound)
相关代码:
lda_cv = LatentDirichletAllocation(n_components=i, max_iter=200, learning_offset=50., learning_method='online',
random_state=0).fit(cv_features)
print('--------------Lda-cv_features 主题--------------------------------')
result_list = display_topics(lda_cv, cv_feature_names, no_top_words)
perplexity = lda_cv.perplexity(cv_features)
print(perplexity)
topic_dist = lda_cv.transform(cv_features)
topic_dist = topic_dist.tolist()
print(topic_dist[:3])
old_df["聚类类别"] = [num_list.index(max(num_list)) for num_list in topic_dist]
上一篇: 到底什么是反射