当前位置:   article > 正文

LDA主题模型分析_lda主题分析

lda主题分析

CSDN话题挑战赛第2期
参赛话题:学习笔记

LDA主题模型分析

基于潜在语义分析的文本挖掘方法主要包括:
LSA(Latent Semantic Analysis)
PLSA(Probabilistic Latent Semantic Analysis)
LDA(Latent Dirichlet Allocation)

这里为什么是潜在语义呢?
顾名思义是通过分析文章(documents )来挖掘文章的潜在意思或语义(concepts )。如果每个单词都仅以着一个语义,同时每个语义仅仅由一个单词来表示,那么简单地将进行语义和单词间的映射。不幸的是,不同的单词可以表示同一个语义,或一个单词同时具有多个不同的意思,这些的模糊歧义使语义的准确识别变得十分困难。

一、导入第三方库

import os
import pandas as pd 
import re
import jieba
import jieba.posseg as psg
  • 1
  • 2
  • 3
  • 4
  • 5
# 自定义文件路径
os.chdir("E:/jupyterCode/LDA/result") # chdir方法用于改变当前工作目录到指定的路径
output_path = "E:/jupyterCode/LDA/result" # 存放结果
file_path = "E:/jupyterCode/LDA/data" # 存放数据
os.chdir(file_path)
data = pd.read_excel("data.xlsx") # excel文件中存放数据,content列名
dic_file = "E:/jupyterCode/LDA/stop_dic/dic.txt" # 存放用户自定义词汇,例如网络热词,在分词时不能拆开
stop_file = "E:/jupyterCode/LDA/stop_dic/stopwords.txt" # 存放停用词
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

二、中文分词

def chinese_word_cut(mytext):
    jieba.load_userdict(dic_file)
    jieba.initlize()
    try:
        stopword_list = open(stop_file,encoding = 'utf-8')
    except:
        stopword_list = []
        print('error in stop_file')
    stop_list = []
    flag_list = ['n','nz','vn'] # 标注词性 选取自定义的三种词性 名词,专有名词,动名词
    for line in stopword_list:
        line = re.sub(u'\n|\\r','',line)
        stop_list.append(line)
    word_list = []
    
    # jieba分词
    seg_list = psg.cut(mytext)
    for seg_word in seg_list :
        word = re.sub(u'[^\\u4e00-\\u9fa5]','',seg_word.word)
        find = 0
        for stop_word in stop_list :
            if stop_word == word or len(word) < 2 : # 如果这个词是停用词
                find = 1
                break
        if find == 0 and seg_word.flag in flag_list :
            word_list.append(word)
    return (" ").join(word_list)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
data["content_cutted"] = data.content.apply(chinese_word_cut)
  • 1

三、LDA分析

from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn.decomposition import LatentDirichletAllocation
def print_top_words(model, feature_names, n_top_words):
    tword = []
    for topic_idx, topic in enumerate(model.components_):
        print("Topic #%d:" % topic_idx)
        topic_w = " ".join([feature_names[i] for i in topic.argsort()[:-n_top_words - 1:-1]])
        tword.append(topic_w)
        print(topic_w)
    return tword    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
# 将数据转换为LDA所需要的数据格式
n_features = 1000 #提取1000个特征词语
tf_vectorizer = CountVectorizer(strip_accents = 'unicode',
                                max_features=n_features,
                                stop_words='english',
                                max_df = 0.5,
                                min_df = 10)
tf = tf_vectorizer.fit_transform(data.content_cutted)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
# 正式进行LDA模型的定义
n_topics = 8 # 自定义主题数量
lda = LatentDirichletAllocation(n_components=n_topics, max_iter=50, # 迭代数量50
                                learning_method='batch', # 学习方法batch
                                learning_offset=50, 
                                # 两个参数也可省略 模型的默认值 α=β=1/n
                                doc_topic_prior=0.1, # 参数α
                                topic_word_prior=0.01, # 参数β 
                                random_state=0)
lda.fit(tf)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述

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

在这里插入图片描述
这里的主题数为啥是自定义为8(0~7),并不是凭空想象的,接下来可以通过可视化数据以及主题困惑度的方法得到最优的主题数。
四、可视化

import pyLDAvis
import pyLDAvis.sklearn
pyLDAvis.enable_notebook()
pic = pyLDAvis.sklearn.prepare(lda, tf, tf_vectorizer)
pyLDAvis.save_html(pic, 'lda_pass'+str(n_topics)+'.html')
pyLDAvis.show(pic)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述
五、主题困惑度

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

在这里插入图片描述

六、导出生成的主题号与原始主题进行对比

import numpy as np
topics = lda.transform(tf)
topic = []
for t in topics:
    topic.append(list(t).index(np.max(t)))
data['topic'] = topic
data.to_excel("data_topic.xlsx",index = False)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述

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

闽ICP备14008679号