LDA的代码实现:http://blog.csdn.net/u010551621/article/details/45258573
文本建模
我们日常生活中总是产生大量的文本,如果每个文本存储为一篇文章,那么每篇文档从人的观察来说就是有序的词的序列d=(w1,w1,...,wn)
包含m篇文章的语料库
统计文本建模的目的就是追问这些观察到预料库的词序列是如何生成的,统计学被人们描述为猜测上帝的游戏,人类产生的所有语料文本我们都可以看成是上帝抛掷骰子生成的,我们观察到的只是上帝玩这个游戏的结果--词序列构成的语料,而上帝玩游戏的过程对我们是个黑盒子。所以在文本建模中我们希望可以猜测出上帝是如何玩这个游戏的,具体一点,核心的两个问题是:
1.上帝都有什么样的骰子
2.上帝是如何抛掷这些骰子的
第一个问题就是表示模型中都有哪些参数,骰子的每一个面的概率都对应的模型的参数;第二个问题就是游戏规则是什么,上帝可能有各种不同类型的骰子,上帝可能按照一定的规则抛掷这些骰子产生词序列
1.Unigram Model
假设我们的词典中一共有V个词v1,v2,...,vV,那么最简单的Unigram Model就是认为上帝是按照如下的游戏规则产生文本的
(1)上帝只有一个骰子,这个骰子有V个面,每个面对应一个词,各个面的概率不一;
(2)每抛出一次骰子,抛出的面就对应的产生于一个词;如果一篇文档中有n个词,那么上帝就是独立的抛掷n词骰子产生这n个词
上帝的唯一的骰子的各个面的概率是记为:
所以每次投掷骰子类似于一个抛硬币时的贝努利实验,只是贝努利实验中我们抛掷的是两面的骰子,而此处抛掷的是V面的骰子,我们把抛这个V面的骰子的实验记为
对于一篇文档:
该文档被生成的概率:
而文档和文档之间被认为是独立的,所以如果语料中有多篇文档:
该语料的概率是:
在Unigram Model中,我们假设了文档之间是独立可交换的,而文档中的词也是独立可交换的,所以一篇文档相当于一个袋子,里面装了一些词,而词的顺序信息就无关重要了,这样的模型也称为词袋模型
假设语料中总的词频是N,在所有的N个词中如果我们关注每个词vi的发生次数ni,那么:
多项分布的概率
此时语料的概率是:
当然我们很重要的一个任务是估计模型的参数P,也就是问上帝拥有的这个骰子的各个面的概率有多大,按照频率派的观点,使用最大似然估计最大化语料的概率,于是参数pi的估计值就是:
对于以上模型,贝叶斯学派的统计学家会有不同意见,他们会很挑剔的批评只假设上帝拥有一个唯一固定的骰子是不合理的,在贝叶斯学派看来,一切参数都是随机变量,以上模型的骰子的P不是唯一固定的,它也是一个随机变量。所以按照贝叶斯学派的观点,上帝是按照以下的过程在玩游戏的:
贝叶斯Unigram Model假设
1.上帝有一个装有无穷多骰子的坛子,里面有各式各样的骰子,每个骰子有V个面;
2.上帝从坛子里面抽了一个骰子出来,然后用这个骰子不断地抛,然后产生了语料库中的所有的词
上帝的这个坛子里,骰子可以是无穷多个,有些类型的骰子数量多,有些类型的骰子数量少,所以从概率分布的角度来看,坛子里面的骰子P服从一个概况分布p(P),这个分布称为参数P的先验分布
以上贝叶斯学派的假设之下,语料的概率该如何计算呢?
由于我们并不知道上帝使用了哪个骰子,每一个骰子都是可以被用到的,只是使用的概率被概率分布
决定,对每个具体的骰子P,由该骰子产生的数据的概率是
所以最终数据产生的概率就是对每个骰子产生的数据概率进行积分累加求和
在贝叶斯分析框架下,此处先验分布
就有很多种选择了,注意到:
实际上是在计算一个多项分布的概率,所以对先验分布的一个好的选择就是多项分布对应的共轭分布,即Dirichlet分布:
此处,
回归前一小节介绍Dirichlet分布的知识:其中很重要的一点就是:Dirichlet先验+多项分布的数据=后验分布为Dirichlet分布
于是在给定参数
的先验分布
各个词出现的频次的数据是
为多项分布,所以无需计算,我们就可推出后验分布:
在贝叶斯框架下,参数
该如何估计呢,由于我们已经有了参数的后验分布,所以合理的方式是使用后验分布的极大值点,或者是参数在后验分布下的平均值,在该文档中,我们取平均值作为参数的估计值,使用Dirichlet分布的结论可得:
也就是对每个参数,我们用下式作为估计值:
考虑到
在Dirichlet分布中的物理意义是事件的先验伪计数,这个估计式子的含义是很直观的:每个参数的估计值是其对应事件的先验的伪计数和数据中的计数的和在整体计数中的比例
进一步我们可以计算出文本语料的产生概率是:
2.Topic Model和PLSA
以上的Unigram Mode是一个很简单的模型,模型中的假设过于简单,和人类写文章产生每一个词的差距过大,有没有更好的模型呢?
我们可以看看日常生活中人们是如何构思文章的,如果我们要写一篇文章,首先是要确定结果主题,譬如构思一篇自然语言处理的文章,可能40%会谈论语言学,30%谈论概率统计,20%谈论计算机,还有10%谈论其他的主题,每个主题下我们又会想到对应的词,我们之所以会想到对应的词是因为这些词在这些主题下出现的概率很高,我们可以很自然的看到,一篇文章通常是由多个主题构成的,一个主题又是由多个与该主题关系比较大的词构成的
以上这种直观的想法由Hoffmn给出的PLSA模型中首先进行了明确的数学化,他认为一篇文章可以由多个主题(topic)构成,每个topic都是词汇上的概率分布,文章中的每一词都是由一个固定的topic生成的
所有人类思考和写文章的行为都可以认为是上帝的行为,我们可以继续回到上帝的假设中,那么在PLSA模型中,Hoffman认为上帝是按照如下的游戏规则来生成文本的。
PLSA Topic Model
1.上帝有两种类型的骰子,一类是doc-topic骰子,每个doc-topic骰子有K个面,每一个面是一个topic的编号;一类是topic-word骰子,每个topic-word骰子有V个面,每个面对应一个词;
2.上帝一共有K个topic-word骰子,每个骰子有一个编号,编号从1到K
3.生成每篇文档之前,上帝都先为这篇文章制造一个特定的doc-topic骰子,然后重复如下过程生成文档中的词
投掷这个doc-topic骰子,得到一个topic编号z
选择K个topic-word骰子中编号为z的那个,投掷这个骰子,于是得到一个词
以上PLSA模型的文档生成过程可以图形化的表示为:
我们可以发现在以上的游戏规则下,文档和文档之间是独立可交换的,同一个文档里的词也是独立可交换的,还是一个bag of words模型。游戏中的K个topic-word骰子,我们可以记为
对于包含M篇文档的语料
中的每一篇文档
都会有一个特定的doc-topic骰子
所有对应的骰子记为:
为了方便,我们假设每个词w都是一个编号,对应到topic-word骰子的面,于是在PLSA模型中,第m篇文档的每个词的生成概率为:
所以整篇文档的生成概率为:
由于文档之间相互独立,我们也容易写出整个语料的生成概率。求解PLSA这个Topic Model的过程汇总,模型参数求解可以使用著名的EM算法进行求得局部最优解
3.LDA文本建模
(1)游戏规则
对于上述的PLSA模型,贝叶斯学派显然是有意见的,doc-topic骰子
和topic-word骰子
都是模型中的参数,参数都是随机变量,怎么能没有先验分布呢?于是,类似于对Unigram Model的贝叶斯改造,我们也可以如下在两个骰子参数前加上先验分布从而把PLSA的游戏过程改造为一个贝叶斯的游戏过程。由于doc-topic骰子和topic-word骰子都应到多项分布,所以先验分布的一个好的选择就是Dirichlet分布,于是我们就得到了LDA(Latent Dirichlet Allocation)模型
在LDA模型中,上帝是按照如下的规则玩文档生成的游戏的:
LDA Topic Model
1.上帝有两大坛骰子,都一个坛子装的是doc-topic骰子,第二个坛子装的是topic-word骰子;
2.上帝随机的从第二坛骰子中独立的抽取了K个topic-word骰子,编号为1到K;
3.每次生成一篇新的文档前,上帝先从第一个坛子里随机抽取一个doc-topic骰子。然后重复以下过程生成文档中的词
投掷这个topic-word骰子,得到一个topic编号z
选择K个topic-word骰子中编号为z的那个,投掷这个骰子,于是得到一个词
假设语料库中有M篇文档,所有的word和对应的topic如下表示
其中
表示第m篇文档中的词
表示这些词对应的topic编号
(2)物理过程分解
使用概率图模型表示,LDA模型的游戏过程如图所示:
这个概率图可以分为两个主要的物理过程:
1.
这个过程表示在生成第m篇文档时,先从第一个坛子中抽取一个doc-topic骰子
然后投掷这个骰子生成文档中第n个词的topic编号
2.
这个过程用如下动作生成语料中的第m篇文档的第n个词:在上帝手头的K个topic-word骰子
中,挑选编号为
的那个骰子进行投掷,然后生成word
理解LDA最重要的就是理解这两个物理过程。LDA模型在基于K个topic生成语料的M篇文章的过程中,由于是bag of words 模型,有一些物理过程是相互独立可交换的。由此,LDA生成模型中,M篇文档会对应M个独立的Dirichlet-Multinomial共轭结构,K个topic会对应于K个独立的Dirichlet-Multinomial共轭结构。所以理解LDA所需要的所有数学就是理解Dirichlet-Multinomial共轭结构,其他就都是理解物理过程。现在让我们进入细节,来看看LDA模型是如何被分解为M+K个Dirichlet-Multinomial共轭结构的
由第一个物理过程,我们知道
是表示生产第m篇文档中的所有词对应的topics,显然,
对应于Dirichlet分布,
对应于Multnomial分布,所以整体是一个Dirichlet-Multinomial共轭结构
前文介绍bayes Unigram Model时对Dirichlet-Multinomial共轭结构做了一些计算,我们在这里可以得到:
进一步,利用Dirichlet-Multinomial共轭结构,可以得到参数
的后验分布是
由于语料中M篇文档的topics的生成过程相互独立,所以我们得到M个相互独立的Dirichlet-Multinomial共轭结构,从而我们得到整个语料中topics的生成概率是
目前我们由M篇文档生成了M个Dirichlet-Multinomial共轭结构,还有K个Dirichlet-Multinomial共轭结构在哪里呢?在上帝按照LDA规则玩游戏的时候,上帝是完全处理完一篇文档再处理下一篇文档,文档中生成的每一个词都要抛掷两次骰子,第一次抛一个doc-topic骰子得到topic,第二次抛一个topic-word骰子得到word,每次生成每篇文档中的一个词的时候,这两次抛骰子的动作是紧邻轮换进行的,如果预料中有N个词,那么要抛掷2N次骰子,轮换的抛掷doc-word骰子和topic-word骰子。但实际上有一些抛骰子的动作是可以交换的,我们可以等价的调整2N次抛骰子的顺序,前N次只抛doc-topic骰子,得到语料中所有词的topics,然后基于得到的每个词的topics编号,后N次只抛topic-word骰子生成N个word,于是上帝在玩LDA游戏的时候可以等价的按照如下过程进行:
1.上帝有两大坛骰子,第一个坛子装的是doc-topic骰子,第二个坛子装的是topic-word骰子;
2.上帝随机的从第二坛里面独立的抽取K个topic-word骰子,编号从1到K;
3.每次生成一篇新的文档前,上帝先从第一个坛子里面随机抽取doc-topic骰子,然后重复投掷这个doc-word骰子为每个词都生成一个topic编号z,重复以上过程处理每篇文档,生成语料中每个词的topic编号,但是词尚未生成‘
4.从头到尾,对语料中的每篇文档中的每个topic编号z,选择K个topic-word骰子中编号为z的那个,投掷这个骰子,于是生成对应的word;
以上游戏先是生成了语料中所有词的topics,然后对每个词在给定topic下生成生成word,在语料中所有词的topic已经生成的条件下,任何两个word的生成动作都是可交换的,于是我们把语料中的词进行交换,把具有相同topic的词放到一起
其中
表示这些词都是由第k个topic生成
对应于词的topic编号,所以这个向量的各个分量都是k
对应于概率图中的第二个物理过程,
在
的限制下,语料中任何两个由topic k生成的词都是可交换的,即使他们不在同一个文档中,所以此处不再考虑文档的概念,转而考虑由同一个topic生成的词,考虑如下过程·
容易看出
对应于Dirichlet分布
对应于Multinomial分布,所以整体也还是对应与一个Dirichlet-Multinomial共轭结构
同样借助于前面的推导我们可以得到:
其中
进一步,利用Dirichlet-Multinomial共轭结构,我们得到参数
的后验分布恰好是
而语料中K个topics生成词的过程相互独,所以我们得到K个相互独立的Dirichlet-Multinomial共轭结构,从而我们得到整个语料库中词生成的概率
结合前面的topic的生成概率,可以得到语料中词和topic的联合生成概率
(3)Gibbs Sampling
有了联合分布
万能的MCMC算法就可以发挥作用了,于是我们可以考虑用Gibbs Sampling抽样对这个分布进行采样了,当然由于
是已经观测到的已知的数据,只有
是隐含的变量,所以我们真正需要采样的是分布
在Gregor Heinrich那篇很有名的LDA模型科普文章Parameter estimation for text analysis中,是基于上式即联合分布来推导Gibbs Sampling公式的,此小节我们使用不同的方式,主要是基于Dirichlet-Multinomial共轭来推导Gibbs Sampling公式的,这样对于理解采样中的概率物理过程有帮助
语料
第i个词对应的topic我们记为
其中i=(m,n)是个二维下标,对应于第m篇文档的第n个词,我们用-i表示去除下标为i的词,那么按照Gibbs Sampling算法的要求,我们要求得任一个坐标轴i对应的条件分布
假设已经观察到的词
则由贝叶斯法则,我们容易得到:
由于
只涉及第m篇文档和第k个topic,所以上式的条件概率计算中,实际上也只会涉及到如下两个Dirichlet-Multinomial共轭结构
其他M+K-2个Dirichlet-Multinomial共轭结构和
是独立的,由于语料在去掉第i个词对应的
并不改变我们之前所说的M+K个Dirichlet-Multinomial共轭结构,只是某些地方的计数会变少,因此
的后验分布都是Dirichelt分布:
使用上面两个式子,把以上想法综合一下,我们就得到了如下的Gibbs Sampling 公式的推导:
对于上面数学式子化简的的解析:
第一行是根据贝叶斯公式推导而来的;
第二行是对zi和wi的可能发生的背景做了一个积分求和,即生成topic和生成word都是由
决定的;
第三行是因为生成topic的过程和生成word的过程是独立的,因此可以化简为相乘的形式;
第四行化简是根据条件概率公式:p(AB)=p(A)P(B|A)得到的;
第五行和第六行是将对应的分布代入,具体是在去掉语料库中第i个词的条件下的第m个doc-topic骰子的各个面的概率后验分布和第k个topic-word骰子的各个面的概率后验分布,都是Dirichlet分布;
第七行是给定第m个doc-topic骰子的各个面的概率后验分布和第k个topic-word骰子的各个面的概率后验分布情况下,将生成第m篇文档的第n个词的topic zi的概率和第m篇文档的第n个词wi的概率进行了简洁记法,其实这个后验概率分布基于的数据并不包括第m篇文档的第n个词对应的topic以及第m篇文档的第n个词;
第八行可以这么理解:对于第m篇文档的第n个词的topic zi来说,它出现某个值(1到K)的概率是取决于第m篇文档的doc-topic骰子的各个面的后验概率分布的,不同的后验概率分布,生成对应的topic的概率也是不同的,这其中只涉及了第m篇文档的topic生成的过程,是一个Dirichlet-Multinomial共轭结构,也就是说将第m篇文档的第n个词的topic的生成概率乘以决定其取值的那个Dirichlet后验概率分布的结果,可以看作为这个topic的生成概率的期望,同样的,对于第m篇文档的第n个词也是同样的分析,这其中我们能看出来只涉及了两个Dirichlet-Multinomial共轭结构
下面我们就要计算
那么这两个变量怎么计算呢,我们上面已经说了他们分别表示第m篇文档的第n个词的topic的生成概率的期望,我们再想一下,这个生成的概率是不是就对应这个第m篇文档的doc-topic的骰子的各个面的概率,因为这各个面的概率就是说每个topic取值的概率,那么就是说我们需要求这各个面概率的期望即可,我们知道这各个面概率
的后验概率就是服从Dirichlet分布的,但是这里是记住是语料库中去掉第m篇文档的第n个词的情况下,上面我们也给出了分布形式,这里我们只需计算m篇文档的doc-topic的各个面概率的每个分量的期望即可,根据之前学习Dirichlet分布的结论可知:
于是我们最终得到了LDA模型的Gibbs Sampling的公式
这个公式的右边就是p(topic|doc).p(word|topic),这个概率其实就是doc->topic->word的路径概率,由于topic有K个,所以Gibbs Sampling 公式的物理意义就是在这K条路径中进行采样
对于这里需要说明一下,因为后面我们需要实现这个Gibbs Sampling 算法下的LDA模型
大家应该知道Gibbs Sampling 算法是用来随机模型采样的,对于我们的语料库而言,我们得到的是语料库中的词,要想得到每篇文档的主题分布,首先得知道每篇文档的每个词的主题;
我们通过模拟文章的生成过程,用数学上表述为M+K个Dirichlet-Mutinomial共轭结构,我们的目标是要得到每个词的topic,因为每个词的topic都可能有K个取值,那么整个语料的词有很多个,这个语料的词的topic分布是个高维分布,我们想要得到这个高维分布平稳以后的样本就可以作为我们最终语料的词的topic,也就可以得到语料中的文档的主题分布;
对高维的分布采样我们可以使用Gibbs Sampling 算法,大家在这里或许有个疑问,就是前面我们在介绍Gibbs Sampling 算法时,是通过构造马氏链转移矩阵,使其满足细致平稳条件,每一轮对样本的所有的维度进行采样,在达到平稳分布后,我们取平稳分布后的样本就是我们的目标样本,并且有一个好处就是我们不用知道原来的样本的分布情况,只需要构造马氏链转移矩阵,使其收敛到最后的平稳分布。那么这里我们虽然同样是要得到所有的词的topic的样本,但是这里存在着马氏链里的关系吗?也就是说每一个词的topic会被所有其他词的topic来决定吗?大家都知道,LDA模型是建立在上帝玩游戏的规则之上,每一个词的topic是在服从Dirichlet先验概率分布的概率向量基础上按照多项分布产生的,我们可以认为当已知所有其他词的topic时,我们会得到所有doc-topic骰子和topic-word骰子的各个面概率的后验分布,这样我们就可以得到当前词的topic的分布;
这样,我们可以在所有其他的词的topic已知的条件下沿着每一个词的topic进行轮换的采样,当然前提是构造前面所说的马氏链转移矩阵,即当所有其他词的topic已知时,当前词的topic的分布。每一轮采样都得到了所有的词的topic样本,经过多次迭代采样后,会收敛到topic的平稳分布,可以取这些平稳分布后的样本的平均值,也可以取某一次的值
(4)Training and Inference
有了LDA模型,当然我们的目标有两个:
估计模型中的参数
对于新来的一篇文章
我们能够计算这篇文章的topic分布
有了Gibbs Sampling公式,我们就可以基于语料训练LDA模型,并应用训练得到的模型对新的文档进行topic语义分析。训练的过程就是通过Gibbs Sampling获取语料中的(z,w)的样本,而模型中的所有的参数都可以基于最终采样得到的样本进行估计。训练的流程很简单:
1随机初始化,对语料库中每一个词w,随机的赋一个topic编号z
2.重新扫描语料库,对每一个词w,按照Gibbs Sampling 公式重新采样它的topic,在语料中进行更新;
3.重复以上语料库的重新采样过程直到Gibbs Sampling收敛;
4.统计语料中的topic-word共现频率矩阵,该矩阵就是LDA的模型
由这个topic-word矩阵我们可以计算每一个p(word|topic)的概率,从而计算出模型参数
这就是上帝用的K个topic-word骰子。当然语料中的文档对应的骰子参数
在以上训练过程中也是可以计算出来的,只要在Gibbs Sampling收敛以后,统计每篇文档中的topic的频率分布,我们就可以计算每一个p(topic|doc)概率,于是就可以计算出每一个
但是这个参数是和训练语料中的每篇文档相关的,对于我们理解新的文档无用处,所以工程上存储LDA模型的时候一般不保留,通常在训练LDA模型的过程中,我们是取Gibbs Sampling收敛之后的n个迭代结果进行平均来做参数估计,这样模型质量更高
有了LDA的模型,我们对于新来的文档,该如何做该文档的topic语义分布的计算呢?基本上,inference的过程和trainning的过程完全类似,对于新的文档,我们只要认为Gibbs Sampling公式中的
是稳定不变的,所以采样过程中,我们只要估计该文档的topic分布
就好了