当前位置:   article > 正文

主题模型分析_主题分析

主题分析

链接入口:【python-sklearn】中文文本 | 主题模型分析-LDA(Latent Dirichlet Allocation)_哔哩哔哩_bilibili

详细版代码入口:如何用Python从海量文本抽取主题?

概念

主题:自动将文本语料库编码为一组具有实质性意义的类别

主题分析的典型代表:隐含狄利克雷分布(LDA

LDA

最明显的特征:能够将若干文档自动编码分类为一定数量的主题。

主题数量需要人为确定主题数量

原理

通过对比新旧文档来判断模型的好坏,然后在不同参数的很多模型找到最优模型。

 

 

代码

导入sklearn模块:

  1. from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
  2. from sklearn.decomposition import LatentDirichletAllocation

 定义函数print_top_words:

  1. def print_top_words(model, feature_names, n_top_words):
  2. tword = []
  3. for topic_idx, topic in enumerate(model.components_):
  4. print("Topic #%d:" % topic_idx)
  5. topic_w = " ".join([feature_names[i] for i in topic.argsort()[:-n_top_words - 1:-1]])
  6. tword.append(topic_w)
  7. print(topic_w)
  8. return tword

 将数据进行转化:

CountVectorizer统计词频,文中代码限定term出现次数必须大于10。

  1. n_features = 1000 #提取1000个特征词语
  2. tf_vectorizer = CountVectorizer(strip_accents = 'unicode',
  3. max_features=n_features,
  4. stop_words='english',
  5. max_df = 0.5,
  6. min_df = 10)
  7. tf = tf_vectorizer.fit_transform(data.content_cutted)

主题模型训练 

  1. n_topics = 8#人为定义主题数量
  2. lda = LatentDirichletAllocation(n_components=n_topics, max_iter=50,
  3. learning_method='batch',
  4. learning_offset=50,
  5. # doc_topic_prior=0.1,
  6. # topic_word_prior=0.01,
  7. random_state=0)
  8. lda.fit(tf)

 LatentDirichletAllocation函数:

n_components=n_topics     表示隐含主题数K

max_iter=50     表示EM算法的最大迭代次数为10
learning_method='batch'      表示LDA的求解算法为 ‘batch’,变分推断EM算法
learning_offset=50      表示仅仅在算法使用”online”时有意义。用来减小前面训练样本批次对最终模型的影响。

α相当于 doc_topic_prior,β相当于topic_word_prior,前者我们一般定义为0.1,后者为0.01。

α,β如果不设置,则都默认为1/n_topics

方法:

fit(X[, y]):利用训练数据训练模型,输入的X为文本词频统计矩阵。

  1. n_top_words = 25#打印每个主题下面的前25个词语
  2. tf_feature_names = tf_vectorizer.get_feature_names()
  3. topic_word = print_top_words(lda, tf_feature_names, n_top_words)

运行结果:(主题的名字需要自定义) 

 

确定最优的主题数量

主题数量不能过多,不然会导致过分分类

可视化

  1. import pyLDAvis
  2. import pyLDAvis.sklearn
  3. pyLDAvis.enable_notebook()
  4. pic = pyLDAvis.sklearn.prepare(lda, tf, tf_vectorizer)
  5. pyLDAvis.display(pic)
  6. pyLDAvis.save_html(pic, 'lda_pass'+str(n_topics)+'.html')
  7. pyLDAvis.display(pic)
  8. #去工作路径下找保存好的html文件
  9. #和视频里讲的不一样,目前这个代码不需要手动中断运行,可以快速出结果

结果显示:

每个圈代表一个主题,主题之间相距越远,表示主题之间相似度越小,分化效果越好。

 

主题困惑度(更严谨)

一般来说,最低的主题困惑度对应的主题数是最优的。

  1. import matplotlib.pyplot as plt
  2. plexs = []
  3. scores = []
  4. n_max_topics = 16
  5. for i in range(1,n_max_topics):
  6. print(i)
  7. lda = LatentDirichletAllocation(n_components=i, max_iter=50,
  8. learning_method='batch',
  9. learning_offset=50,random_state=0)
  10. lda.fit(tf)
  11. plexs.append(lda.perplexity(tf))
  12. scores.append(lda.score(tf))
  13. n_t=15#区间最右侧的值。注意:不能大于n_max_topics
  14. x=list(range(1,n_t+1))
  15. plt.plot(x,plexs[0:n_t])
  16. plt.xlabel("number of topics")
  17. plt.ylabel("perplexity")
  18. plt.show()

结果显示:

根据手肘法,缩减横向坐标的取值范围,可以发现x=8时,有一个低谷,我觉得是相当于极小值。

 关于困惑度可参考:折肘法+困惑度确定LDA主题模型的主题数_巴基海贼王的博客-CSDN博客_lda主题数

输出结果

  1. import numpy as np
  2. topics=lda.transform(tf)
  3. topic = []
  4. for t in topics:
  5. topic.append("Topic #"+str(list(t).index(np.max(t))))
  6. data['概率最大的主题序号']=topic
  7. data['每个主题对应概率']=list(topics)
  8. data.to_excel("data_topic.xlsx",index=False)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/937388
推荐阅读
相关标签
  

闽ICP备14008679号