主题模型-LDA浅析

一、原文:http://cos.name/2010/10/lda_topic_model/

LDA主题模型简介

    上个学期到现在陆陆续续研究了一下主题模型(topic model)这个东东。何谓“主题”呢?望文生义就知道是什么意思了,就是诸如一篇文章、一段话、一个句子所表达的中心思想。不过从统计模型的角度来说, 我们是用一个特定的词频分布来刻画主题的,并认为一篇文章、一段话、一个句子是从一个概率模型中生成的。

    D. M. Blei在2003年(准确地说应该是2002年)提出的LDA(Latent Dirichlet Allocation)模型(翻译成中文就是——潜在狄利克雷分配模型)让主题模型火了起来, 今年3月份我居然还发现了一个专门的LDA的R软件包(7月份有更新),可见主题模型方兴未艾呀。主题模型是一种语言模型,是对自然语言进行建模,这个在信息检索中很有用。

    LDA主题模型涉及到贝叶斯理论、Dirichlet分布多项分布、图模型、变分推断EM算法Gibbs抽样等知识,不是很好懂,LDA那篇30 页的文章我看了四、五遍才基本弄明白是咋回事。那篇文章其实有点老了,但是很经典,从它衍生出来的文章现在已经有n多n多了。主题模型其实也不只是LDA 了,LDA之前也有主题模型,它是之前的一个突破,它之后也有很多对它进行改进的主题模型。需要注意的是,LDA也是有名的Linear Discriminant Analysis(线性判别分析)的缩写。

    LDA是一种非监督机器学习技术,可以用来识别大规模文档集(document collection)或语料库(corpus)中潜藏的主题信息。它采用了词袋(bag of words)的方法,这种方法将每一篇文档视为一个词频向量,从而将文本信息转化为了易于建模的数字信息。但是词袋方法没有考虑词与词之间的顺序,这简化了问题的复杂性,同时也为模型的改进提供了契机。每一篇文档代表了一些主题所构成的一个概率分布,而每一个主题又代表了很多单词所构成的一个概率分布。由于 Dirichlet分布随机向量各分量间的弱相关性(之所以还有点“相关”,是因为各分量之和必须为1),使得我们假想的潜在主题之间也几乎是不相关的,这与很多实际问题并不相符,从而造成了LDA的又一个遗留问题。

    对于语料库中的每篇文档,LDA定义了如下生成过程(generative process):

    1. 对每一篇文档,从主题分布中抽取一个主题;

    2. 从上述被抽到的主题所对应的单词分布中抽取一个单词;

    3. 重复上述过程直至遍历文档中的每一个单词。

    更形式化一点说,语料库中的每一篇文档与 T(通过反复试验等方法事先给定)个主题的一个多项分布相对应,将该多项分布记为 \theta。每个主题又与词汇表(vocabulary)中的  V个单词的一个多项分布相对应,将这个多项分布记为 \phi。上述词汇表是由语料库中所有文档中的所有互异单词组成,但实际建模的时候要剔除一些停用词(stopword),还要进行一些词干化(stemming)处理等。\theta 和\phi分别有一个带有超参数(hyperparameter)\alpha\beta的Dirichlet先验分布。对于一篇文档d中的每一个单词,我们从该文档所对应的多项分布\theta中抽取一个主题z,然后我们再从主题z所对应的多项分布\phi中抽取一个单词w。将这个过程重复N_d次,就产生了文档d,这里的N_d是文档d的单词总数。这个生成过程可以用如下的图模型表示


    这个图模型表示法也称作“盘子表示法”(plate notation)。图中的阴影圆圈表示可观测变量(observed variable),非阴影圆圈表示潜在变量(latent variable),箭头表示两变量间的条件依赖性(conditional dependency),方框表示重复抽样,重复次数在方框的右下角。

    该模型有两个参数需要推断(infer):一个是“文档-主题”分布\theta,另外是T个“主题-单词”分布\phi。通过学习(learn)这两个参数,我们可以知道文档作者感兴趣的主题,以及每篇文档所涵盖的主题比例等。推断方法主要有LDA模型作者提出的变分-EM算法,还有现在常用的Gibbs抽样法。

    LDA模型现在已经成为了主题建模中的一个标准。如前所述,LDA模型自从诞生之后有了蓬勃的扩展,特别是在社会网络和社会媒体研究领域最为常见。

二、原文:http://blog.youkuaiyun.com/huagong_adu/article/details/7937616

(一)LDA作用

        传统判断两个文档相似性的方法是通过查看两个文档共同出现的单词的多少,如TF-IDF等,这种方法没有考虑到文字背后的语义关联,可能在两个文档共同出现的单词很少甚至没有,但两个文档是相似的。

        举个例子,有两个句子分别如下:

                “乔布斯离我们而去了。”

                “苹果价格会不会降?”

        可以看到上面这两个句子没有共同出现的单词,但这两个句子是相似的,如果按传统的方法判断这两个句子肯定不相似,所以在判断文档相关性的时候需要考虑到文档的语义,而语义挖掘的利器是主题模型,LDA就是其中一种比较有效的模型。

        在主题模型中,主题表示一个概念、一个方面,表现为一系列相关的单词,是这些单词的条件概率。形象来说,主题就是一个桶,里面装了出现概率较高的单词,这些单词与这个主题有很强的相关性。

        怎样才能生成主题?对文章的主题应该怎么分析?这是主题模型要解决的问题。

        首先,可以用生成模型来看文档和主题这两件事。所谓生成模型,就是说,我们认为一篇文章的每个词都是通过“以一定概率选择了某个主题,并从这个主题中以一定概率选择某个词语”这样一个过程得到的。那么,如果我们要生成一篇文档,它里面的每个词语出现的概率为:


        这个概率公式可以用矩阵表示:


        其中”文档-词语”矩阵表示每个文档中每个单词的词频,即出现的概率;”主题-词语”矩阵表示每个主题中每个单词的出现概率;”文档-主题”矩阵表示每个文档中每个主题出现的概率。

        给定一系列文档,通过对文档进行分词,计算各个文档中每个单词的词频就可以得到左边这边”文档-词语”矩阵。主题模型就是通过左边这个矩阵进行训练,学习出右边两个矩阵。

        主题模型有两种:pLSA(ProbabilisticLatent Semantic Analysis)和LDA(Latent Dirichlet Allocation),下面主要介绍LDA。

(二)LDA介绍

        如何生成M份包含N个单词的文档,LatentDirichlet Allocation这篇文章介绍了3方法:

        方法一:unigram model

        该模型使用下面方法生成1个文档:

        For each ofthe N words w_n: 
                Choose a word w_n ~ p(w); 

        其中N表示要生成的文档的单词的个数,w_n表示生成的第n个单词w,p(w)表示单词w的分布,可以通过语料进行统计学习得到,比如给一本书,统计各个单词在书中出现的概率。

        这种方法通过训练语料获得一个单词的概率分布函数,然后根据这个概率分布函数每次生成一个单词,使用这个方法M次生成M个文档。其图模型如下图所示:


        方法二:Mixture of unigram

        unigram模型的方法的缺点就是生成的文本没有主题,过于简单,mixture of unigram方法对其进行了改进,该模型使用下面方法生成1个文档:

        Choose a topicz ~ p(z); 

        For each ofthe N words w_n: 

                Choose a word w_n ~ p(w|z); 

        其中z表示一个主题,p(z)表示主题的概率分布,z通过p(z)按概率产生;N和w_n同上;p(w|z)表示给定z时w的分布,可以看成一个k×V的矩阵,k为主题的个数,V为单词的个数,每行表示这个主题对应的单词的概率分布,即主题z所包含的各个单词的概率,通过这个概率分布按一定概率生成每个单词。

        这种方法首先选选定一个主题z,主题z对应一个单词的概率分布p(w|z),每次按这个分布生成一个单词,使用M次这个方法生成M份不同的文档。其图模型如下图所示:


        从上图可以看出,z在w所在的长方形外面,表示z生成一份N个单词的文档时主题z只生成一次,即只允许一个文档只有一个主题,这不太符合常规情况,通常一个文档可能包含多个主题。

        方法三:LDA(Latent Dirichlet Allocation)

        LDA方法使生成的文档可以包含多个主题,该模型使用下面方法生成1个文档:

        Chooseparameter θ ~ p(θ); 

        For each ofthe N words w_n: 

                Choose a topic z_n ~ p(z|θ); 

                Choose a word w_n ~ p(w|z); 

        其中θ是一个主题向量,向量的每一列表示每个主题在文档出现的概率,该向量为非负归一化向量;p(θ)是θ的分布,具体为Dirichlet分布,即分布的分布;N和w_n同上;z_n表示选择的主题,p(z|θ)表示给定θ时主题z的概率分布,具体为θ的值,即p(z=i|θ)= θ_i;p(w|z)同上。

        这种方法首先选定一个主题向量θ,确定每个主题被选择的概率。然后在生成每个单词的时候,从主题分布向量θ中选择一个主题z,按主题z的单词概率分布生成一个单词。其图模型如下图所示:


        从上图可知LDA的联合概率为:


        把上面的式子对应到图上,可以大致按下图理解:


        从上图可以看出,LDA的三个表示层被三种颜色表示出来:

        1. corpus-level(红色):α和β表示语料级别的参数,也就是每个文档都一样,因此生成过程只采样一次。

        2.document-level(橙色):θ是文档级别的变量,每个文档对应一个θ,也就是每个文档产生各个主题z的概率是不同的,所有生成每个文档采样一次θ。

        3. word-level(绿色):z和w都是单词级别变量,z由θ生成,w由z和β共同生成,一个 单词w对应一个主题z。

        通过上面对LDA生成模型的讨论,可以知道LDA模型主要是从给定的输入语料中学习训练两个控制参数α和β,学习出了这两个控制参数就确定了模型,便可以用来生成文档。其中α和β分别对应以下各个信息:

        α:分布p(θ)需要一个向量参数,即Dirichlet分布的参数,用于生成一个主题θ向量;

        β:各个主题对应的单词概率分布矩阵p(w|z)。

        把w当做观察变量,θ和z当做隐藏变量,就可以通过EM算法学习出α和β,求解过程中遇到后验概率p(θ,z|w)无法直接求解,需要找一个似然函数下界来近似求解,原文使用基于分解(factorization)假设的变分法(varialtional inference)进行计算,用到了EM算法。每次E-step输入α和β,计算似然函数,M-step最大化这个似然函数,算出α和β,不断迭代直到收敛。

 

        参考文献:

David M. Blei, AndrewY. Ng, Michael I. Jordan, LatentDirichlet Allocation, Journal of Machine Learning Research 3, p993-1022,2003

【JMLR’03】Latent Dirichlet Allocation (LDA)- David M.Blei

搜索背后的奥秘——浅谈语义主题计算

http://bbs.byr.cn/#!article/PR_AI/2530?p=1


### BERT-LDA主题模型实现代码 以下是基于GitHub资源和现有技术的BERT-LDA主题模型实现方法。该部分涵盖了如何利用预训练的BERT模型提取文档嵌入向量,并将其作为输入传递给LDA模型以完成主题建模。 #### 使用BERT提取文本嵌入 为了将BERT与LDA结合,可以先使用BERT生成高质量的文本表示。以下是一个简单的示例代码用于获取BERT嵌入: ```python from transformers import BertTokenizer, BertModel import torch def get_bert_embeddings(texts, model_name='bert-base-uncased'): tokenizer = BertTokenizer.from_pretrained(model_name) model = BertModel.from_pretrained(model_name) embeddings = [] for text in texts: inputs = tokenizer(text, return_tensors="pt", truncation=True, padding=True, max_length=512) with torch.no_grad(): outputs = model(**inputs) embedding = outputs.last_hidden_state[:, 0, :].numpy() # 获取[CLS]标记的隐藏状态 embeddings.append(embedding) return embeddings ``` 此函数会返回每篇文档对应的BERT嵌入[^4]。 #### 结合LDA进行主题建模 一旦获得了BERT嵌入,就可以进一步处理这些嵌入并应用于传统的LDA框架。下面展示了一个简化版流程: ```python from sklearn.decomposition import LatentDirichletAllocation from sklearn.feature_extraction.text import CountVectorizer # 假设我们已经得到了一组经过BERT编码后的文本数据 texts = ["example sentence one", "another example sentence"] # 转化为词频矩阵 vectorizer = CountVectorizer() X = vectorizer.fit_transform(texts) # 初始化LDA模型 lda_model = LatentDirichletAllocation(n_components=5, random_state=42) lda_output = lda_model.fit_transform(X) print(lda_output) # 输出每个样本的主题分布概率 ``` 需要注意的是,在实际操作中可能还需要对BERT嵌入做降维或其他形式的数据转换以便更好地适配到标准LDA算法的要求之中[^5]。 #### GitHub上的相关项目推荐 目前有不少开源项目实现了类似的思路,比如`Bertopic`就是一个非常流行的库,它内部集成了BERT和其他先进的自然语言处理技术来提升传统主题模型的效果。可以在如下链接找到更多细节: https://github.com/MaartenGr/BERTopic 另外还有专门针对中文环境设计的一些解决方案可供参考,例如: https://github.com/ymcui/Chinese-BERT-wwm 以上两个仓库都提供了详尽的例子说明怎样把现代深度学习架构融入经典统计学方法当中去解决复杂的NLP任务问题[^6]。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值