LDA主题模型简介及Python实现_lda主题模型

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

一、LDA主题模型简介

        LDA主题模型主要用于推测文档的主题分布可以将文档集中每篇文档的主题以概率分布的形式给出根据主题进行主题聚类或文本分类。

        LDA主题模型不关心文档中单词的顺序通常使用词袋特征bag-of-word feature来代表文档。词袋模型介绍可以参考这篇文章文本向量化表示——词袋模型 - 知乎

        了解LDA模型我们需要先了解LDA的生成模型LDA认为一篇文章是怎么形成的呢

        LDA模型认为主题可以由一个词汇分布来表示而文章可以由主题分布来表示

        比如有两个主题美食美妆。LDA说两个主题可以由词汇分布表示他们分别是

{面包0.4火锅0.5眉笔0.03腮红0.07}
{眉笔0.4腮红0.5面包0.03火锅0.07}

        同样对于两篇文章LDA认为文章可以由主题分布这么表示

《美妆日记》{美妆0.8美食0.1其他0.1}

《美食探索》{美食0.8美妆0.1其他0.1}

        所以想要生成一篇文章可以先以一定的概率选取上述某个主题再以一定的概率选取那个主题下的某个单词不断重复这两步就可以生成最终文章。

        在LDA模型中一篇文档生成的方式如下

 

        其中类似Beta分布是二项式分布的共轭先验概率分布而狄利克雷分布Dirichlet分布是多项式分布的共轭先验概率分布。

        如果我们要生成一篇文档它里面的每个词语出现的概率为

         更详细的数学推导可以见通俗理解LDA主题模型_结构之法 算法之道-CSDN博客_lda模型

        看到文章推断其隐藏的主题分布就是建模的目的。换言之人类根据文档生成模型写成了各类文章然后丢给了计算机相当于计算机看到的是一篇篇已经写好的文章。现在计算机需要根据一篇篇文章中看到的一系列词归纳出当篇文章的主题进而得出各个主题各自不同的出现概率主题分布。

        至于LDA主题模型在计算机中具体是怎么实现的我们也可以不必细究现在有很多可以直接用来进行LDA主题分析的包我们直接用就行。没错我就是调包侠

二、Python实现

        在用Python进行LDA主题模型分析之前我先对文档进行了分词和去停用词处理详情可以看我之前的文章用python对单一微博文档进行分词——jieba分词加保留词和停用词_阿丢是丢心心的博客-CSDN博客_jieba 停用词

        我下面的输入文件也是已经分好词的文件

1.导入算法包

import gensim
from gensim import corpora
import matplotlib.pyplot as plt
import matplotlib
import numpy as np
import warnings
warnings.filterwarnings('ignore')  # To ignore all warnings that arise here to enhance clarity

from gensim.models.coherencemodel import CoherenceModel
from gensim.models.ldamodel import LdaModel

2.加载数据

        先将文档转化为一个二元列表其中每个子列表代表一条微博

PATH = "E:/data/output.csv"

file_object2=open(PATH,encoding = 'utf-8',errors = 'ignore').read().split('\n')  #一行行的读取内容
data_set=[]  #建立存储分词的列表
for i in range(len(file_object2)):
    result=[]
    seg_list = file_object2[i].split()
    for w in seg_list :  #读取每一行分词
        result.append(w)
    data_set.append(result)
print(data_set)

        构建词典语料向量化表示

dictionary = corpora.Dictionary(data_set)  # 构建词典
corpus = [dictionary.doc2bow(text) for text in data_set]  #表示为第几个单词出现了几次

3.构建LDA模型

ldamodel = LdaModel(corpus, num_topics=10, id2word = dictionary, passes=30,random_state = 1)   #分为10个主题
print(ldamodel.print_topics(num_topics=num_topics, num_words=15))  #每个主题输出15个单词

        这是确定主题数时LDA模型的构建方法一般我们可以用指标来评估模型好坏也可以用这些指标来确定最优主题数。一般用来评价LDA主题模型的指标有困惑度perplexity和主题一致性coherence困惑度越低或者一致性越高说明模型越好。一些研究表明perplexity并不是一个好的指标所以一般我用coherence来评价模型并选择最优主题但下面代码两种方法我都用了。

#计算困惑度
def perplexity(num_topics):
    ldamodel = LdaModel(corpus, num_topics=num_topics, id2word = dictionary, passes=30)
    print(ldamodel.print_topics(num_topics=num_topics, num_words=15))
    print(ldamodel.log_perplexity(corpus))
    return ldamodel.log_perplexity(corpus)
#计算coherence
def coherence(num_topics):
    ldamodel = LdaModel(corpus, num_topics=num_topics, id2word = dictionary, passes=30,random_state = 1)
    print(ldamodel.print_topics(num_topics=num_topics, num_words=10))
    ldacm = CoherenceModel(model=ldamodel, texts=data_set, dictionary=dictionary, coherence='c_v')
    print(ldacm.get_coherence())
    return ldacm.get_coherence()

4.绘制主题-coherence曲线选择最佳主题数

x = range(1,15)
# z = [perplexity(i) for i in x]  #如果想用困惑度就选这个
y = [coherence(i) for i in x]
plt.plot(x, y)
plt.xlabel('主题数目')
plt.ylabel('coherence大小')
plt.rcParams['font.sans-serif']=['SimHei']
matplotlib.rcParams['axes.unicode_minus']=False
plt.title('主题-coherence变化情况')
plt.show()

        最终能得到各主题的词语分布和这样的图形

 5.结果输出与可视化

        通过上述主题评估我们发现可以选择5作为主题个数接下来我们可以再跑一次模型设定主题数为5并输出每个文档最有可能对应的主题

from gensim.models import LdaModel
import pandas as pd
from gensim.corpora import Dictionary
from gensim import corpora, models
import csv

# 准备数据
PATH = "E:/data/output1.csv"

file_object2=open(PATH,encoding = 'utf-8',errors = 'ignore').read().split('\n')  #一行行的读取内容
data_set=[] #建立存储分词的列表
for i in range(len(file_object2)):
    result=[]
    seg_list = file_object2[i].split()
    for w in seg_list :#读取每一行分词
        result.append(w)
    data_set.append(result)

dictionary = corpora.Dictionary(data_set)  # 构建词典
corpus = [dictionary.doc2bow(text) for text in data_set]

lda = LdaModel(corpus=corpus, id2word=dictionary, num_topics=5, passes = 30,random_state=1)
topic_list=lda.print_topics()
print(topic_list)

for i in lda.get_document_topics(corpus)[:]:
    listj=[]
    for j in i:
        listj.append(j[1])
    bz=listj.index(max(listj))
    print(i[bz][0])

        同时我们可以用pyLDAvis对LDA模型结果进行可视化

import pyLDAvis.gensim
pyLDAvis.enable_notebook()
data = pyLDAvis.gensim.prepare(lda, corpus, dictionary)
pyLDAvis.save_html(data, 'E:/data/3topic.html')

        大概能得到这样的结果

 左侧圆圈表示主题右侧表示各个词语对主题的贡献度。

所有代码如下

import gensim
from gensim import corpora
import matplotlib.pyplot as plt
import matplotlib
import numpy as np
import warnings
warnings.filterwarnings('ignore')  # To ignore all warnings that arise here to enhance clarity

from gensim.models.coherencemodel import CoherenceModel
from gensim.models.ldamodel import LdaModel



 # 准备数据
PATH = "E:/data/output.csv"

file_object2=open(PATH,encoding = 'utf-8',errors = 'ignore').read().split('\n')  #一行行的读取内容
data_set=[] #建立存储分词的列表
for i in range(len(file_object2)):
    result=[]
    seg_list = file_object2[i].split()
    for w in seg_list :#读取每一行分词
        result.append(w)
    data_set.append(result)
print(data_set)


dictionary = corpora.Dictionary(data_set)  # 构建 document-term matrix
corpus = [dictionary.doc2bow(text) for text in data_set]
#Lda = gensim.models.ldamodel.LdaModel  # 创建LDA对象

#计算困惑度
def perplexity(num_topics):
    ldamodel = LdaModel(corpus, num_topics=num_topics, id2word = dictionary, passes=30)
    print(ldamodel.print_topics(num_topics=num_topics, num_words=15))
    print(ldamodel.log_perplexity(corpus))
    return ldamodel.log_perplexity(corpus)

#计算coherence
def coherence(num_topics):
    ldamodel = LdaModel(corpus, num_topics=num_topics, id2word = dictionary, passes=30,random_state = 1)
    print(ldamodel.print_topics(num_topics=num_topics, num_words=10))
    ldacm = CoherenceModel(model=ldamodel, texts=data_set, dictionary=dictionary, coherence='c_v')
    print(ldacm.get_coherence())
    return ldacm.get_coherence()

# 绘制困惑度折线图
x = range(1,15)
# z = [perplexity(i) for i in x]
y = [coherence(i) for i in x]
plt.plot(x, y)
plt.xlabel('主题数目')
plt.ylabel('coherence大小')
plt.rcParams['font.sans-serif']=['SimHei']
matplotlib.rcParams['axes.unicode_minus']=False
plt.title('主题-coherence变化情况')
plt.show()
from gensim.models import LdaModel
import pandas as pd
from gensim.corpora import Dictionary
from gensim import corpora, models
import csv

# 准备数据
PATH = "E:/data/output1.csv"

file_object2=open(PATH,encoding = 'utf-8',errors = 'ignore').read().split('\n')  #一行行的读取内容
data_set=[] #建立存储分词的列表
for i in range(len(file_object2)):
    result=[]
    seg_list = file_object2[i].split()
    for w in seg_list :#读取每一行分词
        result.append(w)
    data_set.append(result)

dictionary = corpora.Dictionary(data_set)  # 构建 document-term matrix
corpus = [dictionary.doc2bow(text) for text in data_set]

lda = LdaModel(corpus=corpus, id2word=dictionary, num_topics=5, passes = 30,random_state=1)
topic_list=lda.print_topics()
print(topic_list)

result_list =[]
for i in lda.get_document_topics(corpus)[:]:
    listj=[]
    for j in i:
        listj.append(j[1])
    bz=listj.index(max(listj))
    result_list.append(i[bz][0])
print(result_list)
import pyLDAvis.gensim
pyLDAvis.enable_notebook()
data = pyLDAvis.gensim.prepare(lda, corpus, dictionary)
pyLDAvis.save_html(data, 'E:/data/topic.html')

有需要自取~

还可以关注我之后我还会发更多关于数据分析的干货文章~

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: python