当前位置:   article > 正文

LDA主题模型的原理和建模_lda平均主题余弦相似度原理公式

lda平均主题余弦相似度原理公式

什么是LDA主题模型

首先说明一下什么是主题模型。这里的主题模型是把一份份不同的文本内容通过某种方式来找到这些文本对应的主题。打个比方:我有一堆新闻类文档,但我想将这对文档进行主题分类。到底是娱乐?军事?政治?等主题。这时候就使用到主题模型。
而这里的LDA和特征工程的LDA不一样。全名Latent Dirichlet Allocation,是一款基于Dirichlet分布的概率主题模型。他属于非监督学习,当中运用到了概率论以及词袋模型等知识。

背景知识

为了更容易的了解LDA的工作原理,请原谅我的啰嗦。先简单的科普一下背景知识。当然已经熟悉的朋友,可以选择忽略这个酌情下一步

贝叶斯理论

这个应该很多人都认识的。这里面先验概率等知识我就不说了。这里先列出贝叶斯公式:
P ( θ , y ) = P ( θ ) P ( y ∣ θ ) P(\theta,y) = P(\theta)P(y|\theta) P(θ,y)=P(θ)P(yθ)
然后就演变出
P ( θ ∣ y ) = P ( θ , y ) P ( θ ) = P ( θ ) P ( y ∣ θ ) P ( θ ) P(\theta|y) = \frac{P(\theta,y)}{ P(\theta)}=\frac{P(\theta)P(y|\theta)}{P(\theta)} P(θy)=P(θ)P(θ,y)=P(θ)P(θ)P(yθ)
这个公式的伟大之处就是实现了概率统计上的“交换律”。本来我们要求y下发现的概率,变成了theta下的概率。这为后面LDA模型提供了基础

gamma函数

gamma是阶乘函数在实数的推广。先回顾一下实数的阶乘公式
Γ ( n ) = ( n − 1 ) ! \Gamma(n) = (n-1)! Γ(n)=(n1)!
相对于实数界的有
Γ ( x ) = ∫ 0 ∞ t x − 1 e − t d t \Gamma(x) = \int_0^\infty{t^{x-1}}e^{-t}dt Γ(x)=0tx1etdt

多个分布

博鲁尼分布

博鲁尼就是只有两种出现的情况。比如要么0,要么1。我制作一次实现得到的分布结果。

二项分布

二项分布就是某一种概率事件,他只可能出现两种情况,要么正要么负{+,-}。他是博鲁尼分布执行N此以后的结果。这种分布就是二项分布。比如最常见的就是抛硬币,出现字和出现图案的概率就是二项分布。二项分布的密度函数有
P ( K = k ) = ( k n ) p k ( 1 − p ) n − k P(K=k)=(^n_k)p^k(1-p)^{n-k} P(K=k)=(kn)pk(1p)nk

多项分布

多项分布就是二项分布的多维度展开式。也就是说我的概率事件不在是{+,-}。而是存在很多种情况。比如掷骰子,概率事件有{1,2,3,4,5,6}。在执行N此实验以后,就会出现k=6的多项分布。相关密度函数有
P ( x 1 , x 2 , ⋅ ⋅ ⋅ , x k ; n , p 1 , p 2 , ⋅ ⋅ ⋅ , p k ) = n ! x 1 ! ⋅ ⋅ ⋅ x n ! P 1 X 1 ⋅ ⋅ ⋅ P n X n P(x_1,x_2,···,x_k;n,p_1,p_2,···,p_k)=\frac{n!}{x_1!···x_n!}P_1^{X_1}···P_n^{X_n} P(x1,x2,,xk;n,p1,p2,,pk)=x1!xn!n!P1X1PnXn

beta分布

beta分布式二项分布的共轭先验分布。说白了他就是二项分布+gamma函数。
给定参数a他的函数公式有:
B e t a ( x ∣ α , β ) = Γ ( a + β ) Γ ( a ) Γ ( β ) p α − 1 ( 1 − x ) β − 1 Beta(x|\alpha,\beta)=\frac{\Gamma(a+\beta)}{\Gamma(a)\Gamma(\beta)}p^{\alpha-1}(1-x)^{\beta-1} Beta(xα,β)=Γ(a)Γ(β)Γ(a+β)pα1(1x)β1

Dirichlet 分布

最后Dirichlet分布其实就是beta分布的多维度推广。他们的关系可以理解为二项分布与多项分布的关系。所以,他的函数公式为:
D i r i c h l e t ( x 1 , x 2 , ⋅ ⋅ ⋅ , x n ; α 1 , α 2 , ⋅ ⋅ ⋅ , α n ) = Γ ( α 1 + α 2 + ⋅ ⋅ ⋅ + α n ) Γ ( α 1 ) Γ ( α 2 ) ⋅ ⋅ ⋅ Γ ( α n ) x 1 α 1 − 1 x 2 α 2 − 1 ⋅ ⋅ ⋅ x n α n − 1 Dirichlet(x_1,x_2,···,x_n;\alpha_1,\alpha_2,···,\alpha_n)=\frac{\Gamma(\alpha_1+\alpha_2+···+\alpha_n)}{\Gamma(\alpha_1)\Gamma(\alpha_2)···\Gamma(\alpha_n)}x_1^{\alpha_1-1}x_2^{\alpha_2-1}···x_n^{\alpha_n-1} Dirichlet(x1,x2,,xn;α1,α2,,αn)=Γ(α1)Γ(α2)Γ(αn)Γ(α1+α2++αn)x1α11x2α21xnαn1
这里细看一下,是不是感觉和多项式分布的公式有点像

开始了解LDA

上面讲了那么多东西,那么到底什么才是LDA模型呢?我们先拟定一个命题:现在我们有很多篇新闻稿件,我们要针对这些稿件进行主题分类。大概如图下面的意思(图片来源于网络)
在这里插入图片描述

也就是我们需要求概率P(主题|文档)。然后从P的最大值获取该稿件的最可能概率。这里利用贝叶斯概率公式的链条化简,可以得到这么一条公式
P ( 单 词 ∣ 文 档 ) = P ( 单 词 ∣ 主 题 ) P ( 主 题 ∣ 文 档 ) P(单词|文档)=P(单词|主题)P(主题|文档) P()=P()P()
具体推导我这里就不列出来了,大家可以自行对照上面的贝叶斯进行化简。
从这里我们可以看出,LDA对主题分类做了一件什么事呢?他其实就是求P(单词|文档)P(单词|主题) 这两个概率分布,然后结合着两个概率分布来求出P(主题|文档)的最大值。最后得到该文档的主题。所以LDA的具体流程如下:
在这里插入图片描述
他的具体步骤如下:

  1. 首先假设稿件主题的先验分布服从Dirichlet分布。既对某个文档d,其主题的分布有:
    θ d = D i r i c h l e t ( α ) \theta_{d}=Dirichlet(\alpha) θd=Dirichlet(α)
    这里对应的是流程图中左边的两个圈圈的步骤。

  2. 假设主题中的词的先验分布服从Dirichlet分布。既对任意一个主题k有:
    β k = D i r i c h l e t ( μ ) \beta_{k}=Dirichlet(\mu) βk=Dirichlet(μ)
    这里对应流程图中右边的两个圈圈。

  3. 最后结合两边的分布最后得到最后的词分布,从而达到预测主题的想过。

Python建模

理论知识就到此为止,接下来我们进行python的建模。采用往上面比较多用的希拉里邮件数据:https://wx.jdcloud.com/market/packet/10487
然后下面是我的代码和注释

# 导包
import numpy as np
import pandas as pd
import re
from gensim import corpora, models, similarities
import gensim

# 文本预处理
def clean_email_text(text):
    text = text.replace('\n'," ") #新行,我们是不需要的
    text = re.sub(r"-", " ", text) #把 "-" 的两个单词,分开。(比如:july-edu ==> july edu)
    text = re.sub(r"\d+/\d+/\d+", "", text) #日期,对主体模型没什么意义
    text = re.sub(r"[0-2]?[0-9]:[0-6][0-9]", "", text) #时间,没意义
    text = re.sub(r"[\w]+@[\.\w]+", "", text) #邮件地址,没意义
    text = re.sub(r"/[a-zA-Z]*[:\//\]*[A-Za-z0-9\-_]+\.+[A-Za-z0-9\.\/%&=\?\-_]+/i", "", text) #网址,没意义
    pure_text = ''
    # 以防还有其他特殊字符(数字)等等,我们直接把他们loop一遍,过滤掉
    for letter in text:
        # 只留下字母和空格
        if letter.isalpha() or letter==' ':
            pure_text += letter
    # 再把那些去除特殊字符后落单的单词,直接排除。
    # 我们就只剩下有意义的单词了。
    text = ' '.join(word for word in pure_text.split() if len(word)>1)
    return text
# 数据读取
df = pd.read_csv('Emails.csv')
# 简单处理一下,去掉空
df = df[['Id','ExtractedBodyText']].dropna()
# 清除无用内容,只保留单词
docs = df['ExtractedBodyText'].apply(lambda x: clean_email_text(x))
doclist = docs.values
# 手动列出停用词列表,中文的话可稍微百度一下虚词列表
stoplist = ['very', 'ourselves', 'am', 'doesn', 'through', 'me', 'against', 'up', 'just', 'her', 'ours', 
            'couldn', 'because', 'is', 'isn', 'it', 'only', 'in', 'such', 'too', 'mustn', 'under', 'their', 
            'if', 'to', 'my', 'himself', 'after', 'why', 'while', 'can', 'each', 'itself', 'his', 'all', 'once', 
            'herself', 'more', 'our', 'they', 'hasn', 'on', 'ma', 'them', 'its', 'where', 'did', 'll', 'you', 
            'didn', 'nor', 'as', 'now', 'before', 'those', 'yours', 'from', 'who', 'was', 'm', 'been', 'will', 
            'into', 'same', 'how', 'some', 'of', 'out', 'with', 's', 'being', 't', 'mightn', 'she', 'again', 'be', 
            'by', 'shan', 'have', 'yourselves', 'needn', 'and', 'are', 'o', 'these', 'further', 'most', 'yourself', 
            'having', 'aren', 'here', 'he', 'were', 'but', 'this', 'myself', 'own', 'we', 'so', 'i', 'does', 'both', 
            'when', 'between', 'd', 'had', 'the', 'y', 'has', 'down', 'off', 'than', 'haven', 'whom', 'wouldn', 
            'should', 've', 'over', 'themselves', 'few', 'then', 'hadn', 'what', 'until', 'won', 'no', 'about', 
            'any', 'that', 'for', 'shouldn', 'don', 'do', 'there', 'doing', 'an', 'or', 'ain', 'hers', 'wasn', 
            'weren', 'above', 'a', 'at', 'your', 'theirs', 'below', 'other', 'not', 're', 'him', 'during', 'which','am','pm']
# 去除停用词
texts = [[word.lower() for word in doc.lower().split() if word not in stoplist] for doc in doclist]
# 创建语料库,把每一个单词转化成元祖模式展示[(15, 1), (17, 1)]
dictionary = corpora.Dictionary(texts)
corpus = [dictionary.doc2bow(text) for text in texts]
# 训练模型
lda = gensim.models.ldamodel.LdaModel(corpus=corpus,id2word=dictionary,num_topics=20)
# 打印主题各单词结果
print(lda.print_topics(num_topics=20,num_words=10))
# 保存语料库与模型
lda.save('hillary_classify_model.model')
dictionary.save('hillary_classify_dictionary.model')
# 模型的加载和预测
model = gensim.models.ldamodel.LdaModel.load('hillary_classify_model.model')
dic = corpora.Dictionary.load('hillary_classify_dictionary.model')
# 这里假设我有一篇关于奥巴马与民主党的新闻稿件
s = 'The news of Obama or Republican Party'
text = s.lower().split(' ')
# 预测主题
bow = dic.doc2bow(text)
model.get_document_topics(bow)

  • 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
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/607638
推荐阅读
相关标签
  

闽ICP备14008679号