LDA主题模型

LDA文档主题生成模型

LDA是一种文档主题生成模型,包含词、主题和文档三层结构。

所谓生成模型,就是说,我们认为一篇文章的每个词都是通过“以一定概率选择了某个主题,并从这个主题中以一定概率选择某个词语”这样一个过程得到。文档到主题服从多项式分布,主题到词服从多项式分布。

LDA是一种非监督机器学习技术,可以用来识别大规模文档集或语料库中潜藏的主题信息。它采用了词袋的方法,这种方法将每一篇文档视为一个词频向量,从而将文本信息转化为了易于建模的数字信息。

但是词袋方法没有考虑词与词之间的顺序,这简化了问题的复杂性,同时也为模型的改进提供了契机。每一篇文档代表了一些主题所构成的一个概率分布,而每一个主题又代表了很多单词所构成的一个概率分布。

理解LDA的五个步骤:

         一个函数:gamma函数

         四个分布:二项分布、多项分布、beta分布、Dirichlet分布

         一个概念和一个理念:共轭先验、贝叶斯框架

         两个模型:pLSA、LDA

         一个采样:Gibbs采样

LDA的贝叶斯模型

         LDA是基于贝叶斯模型的,涉及到贝叶斯模型离不开“先验分布”,“数据(似然)”和"后验分布"三块。

先验分布数据(似然)后验分布

例如:P(好工程师)P(简历|好工程师)= P(好工程师|简历)

二项分布与Beta分布

         二项分布:

         其中:p我们可以理解为好的工程师概率,k为好工程师的个数,n为工程师的总数

         我们希望这个先验分布和数据(似然)对应的二项分布集合后,得到的后验分布在后面还可以作为先验分布。也即是说,我们希望先验分布和后验分布的形式应该是一样的,这样的分布我们一般叫共轭分布。在我们的例子里,我们希望找到和二项分布共轭的分布。

         和二项分布共轭的分布其实就是Beta分布。Beta分布的表达式为:

其中Γ是Gamma函数,满足Γx=x-1!

多项分布与Dirichlet 分布

         假如数据有三维,由于二维我们使用了Beta分布和二项分布来表达这个模型,则在三维时,以此类推,我们可以用三维的Beta分布来表达先验后验分布,三项的多项分布来表达数据(似然)。(超过二维的Beta分布我们一般称之为狄利克雷(以下称为Dirichlet )分布)

         假设是三维,则多项式分布为:

         三维的Dirichlet分布:

         一般意义上的K维Dirichlet 分布表达式为:

LDA主题模型

LDA假设文档主题的先验分布是Dirichlet分布,即对于任一文档d,其主题分布θd 为:

其中,α 为分布的超参数,是一个K维向量,K表示主题数目

LDA假设主题中词的先验分布是Dirichlet分布,即对于任一主题k, 其词分布βk为:

其中,η为分布的超参数,是一个V维向量。V代表词汇表里所有词的个数。

对于数据中任一一篇文档d中的第n个词,我们可以从主题分布θd中得到它的主题编号zdn的分布为:

而对于该主题编号,得到我们看到的词wdn的概率分布为: 

基于这个LDA模型的求解方法:

  1. 基于Gibbs采样算法求解
  2. 基于变分推断EM算法求解

LDA主题模型的python实现

  • 导入文档
  • 清洗文档
  1. 分词
  2. 停用词处理
  3. 词干提取
  • 构建描述文档词频的矩阵
  • 应用LDA模型
  • 检查结果

 

from stop_words import get_stop_words
from nltk.stem.porter import PorterStemmer
from nltk.tokenize import RegexpTokenizer
from gensim import corpora,models
import gensim

tokenizer=RegexpTokenizer(r'\w+')
texts=[]

doc_a = "Brocolli is good to eat. My brother likes to eat good brocolli, but not my mother."
doc_b = "My mother spends a lot of time driving my brother around to baseball practice."
doc_c = "Some health experts suggest that driving may cause increased tension and blood pressure."
doc_d = "I often feel pressure to perform well at school, but my mother never seems to drive my brother to do better."
doc_e = "Health professionals say that brocolli is good for your health."
doc_set = [doc_a, doc_b, doc_c, doc_d, doc_e]
en_stop=get_stop_words('en')
# compile sample documents into a list
#分词
for i in doc_set:
    raw=i.lower()
    tokens=tokenizer.tokenize(raw)
    print(tokens)

    #创建停用词列表

    stopped_tokens=[i for i in tokens if i not in en_stop]
    print(stopped_tokens)

    #词干提取(将相似的单词去除词缀得到词根)
    p_stemmer=PorterStemmer()#p_stemmer 要求所有单词的类型都是 str。p_stemmer 以词干的形式返回字符串参数
    stemmed_tokens=[p_stemmer.stem(i) for i in stopped_tokens]
    texts.append(stemmed_tokens)

dictionary=corpora.Dictionary(texts)#Dictionary() 方法遍历所有的文本,为每个不重复的单词分配一个单独的整数ID
corpus=[dictionary.doc2bow(text)for text in texts]#doc2bow() 方法将 dictionary 转化为一个词袋。
# 得到的结果 corpus 是一个向量的列表,向量的个数就是文档数。在每个文档向量中都包含一系列元组。
ldamodel=gensim.models.ldamodel.LdaModel(corpus,num_topics=2,id2word=dictionary,passes=20)
    #num_topics: 必须。LDA 模型要求用户决定应该生成多少个主题。由于我们的文档集很小,所以我们只生成三个主题。
    #id2word:必须。LdaModel 类要求我们之前的 dictionary 把 id 都映射成为字符串。
    #passes:可选。模型遍历语料库的次数。遍历的次数越多,模型越精确。但是对于非常大的语料库,遍历太多次会花费很长的时间。

#检查结果
print(ldamodel.print_topics(num_topics=2,num_words=4))
#每一个生成的主题都用逗号分隔开。每个主题当中有三个该主题当中最可能出现的单词

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值