LDA(Latent Dirichlet Allocation)主题模型

LDA(Latent Dirichlet Allocation)主题模型LDA 于 2003 年由 DavidBlei AndrewNg 和 MichaelI Jordan 提出 因为模型的简单和有效 掀起了主题模型研究的波浪 虽然说 LDA 模型简单 但是它的数学推导却不是那么平易近人 一般初学者会深陷数学细节推导中不能自拔 于是牛人们看不下去了 纷纷站出来发表了各种教程 国内方面 rickjin 有著名的 LDA 数学八卦 国外的 GregorHeinri 有著名的 P

LDA于2003年由 David Blei, Andrew Ng和 Michael I. Jordan提出,因为模型的简单和有效,掀起了主题模型研究的波浪。虽然说LDA模型简单,但是它的数学推导却不是那么平易近人,一般初学者会深陷数学细节推导中不能自拔。于是牛人们看不下去了,纷纷站出来发表了各种教程。国内方面rickjin有著名的《LDA数学八卦》,国外的Gregor Heinrich有著名的《Parameter estimation for text analysis》。其实有了这两篇互补的通俗教程,大家沉住心看个4、5遍,基本就可以明白LDA为什么是简单的了。那么其实也没我什么事了,然而心中总有一种被大牛点播的豁然开朗的快感,实在是不吐不快啊。

什么是主题

因为LDA是一种主题模型,那么首先必须明确知道LDA是怎么看待主题的。对于一篇新闻报道,我们看到里面讲了昨天NBA篮球比赛,那么用大腿想都知道它的主题是关于体育的。为什么我们大腿会那么聪明呢?这时大腿会回答因为里面出现了“科比”、“湖人”等等关键词。那么好了,我们可以定义主题是一种关键词集合,如果另外一篇文章出现这些关键词,我们可以直接判断他属于某种主题。但是,亲爱的读者请你想想,这样定义主题有什么弊端呢?按照这种定义,我们会很容易给出这样的条件:一旦文章出现了一个球星的名字,那么那篇文章的主题就是体育。可能你马上会骂我在瞎说,然后反驳说不一定,文章确实有球星的名字,但是里面全部在讲球星的性丑闻,和篮球没半毛钱关系,此时主题是娱乐还差不多。所以一个词不能硬性地扣一个主题的帽子,如果说一篇文章出现了某个球星的名字,我们只能说有很大概率他属于体育的主题,但也有小概率属于娱乐的主题。于是就会有这种现象:同一个词,在不同的主题背景下,它出现的概率是不同的。并且我们都可以基本确定,一个词不能代表一种主题,那么到底什么才是主题呢?耐不住性子的同学会说,既然一个词代表不了一种主题,那我就把所有词都用来代表一种主题,然后你自己去慢慢意会。没错,这样确实是一种完全的方式,主题本来就蕴含在所有词之中,这样确实是最保险的做法,但是你会发现这样等于什么都没做。老奸巨猾的LDA也是这么想的,但他狡猾之处在于它用非常圆滑手段地将主题用所有词汇表达出来。怎么个圆滑法呢?手段便是概率。LDA认为天下所有文章都是用基本的词汇组合而成,此时假设有词库 V={
v1,v2,....,vn}
V = { v 1 , v 2 , . . . . , v n }
,那么如何表达主题 k k 呢?LDA说通过词汇的概率分布来反映主题!多么狡猾的家伙。我们举个例子来说明LDA的观点。假设有词库

{ } ” role=”presentation”> { }

假设有两个主题

{
}
{ 体 育 , 政 治 }

LDA说体育这个主题就是:

{
:0.3:0.3:0.3:0.03:0.03:0.04}
{ 科 比 : 0.3 , 篮 球 : 0.3 , 足 球 : 0.3 , 奥 巴 马 : 0.03 , 希 拉 里 : 0.03 , 克 林 顿 : 0.04 }

(数字代表某个词的出现概率),而政治这个主题就是:

{
:0.03:0.03:0.04:0.3:0.3:0.3}
{ 科 比 : 0.03 , 篮 球 : 0.03 , 足 球 : 0.04 , 奥 巴 马 : 0.3 , 希 拉 里 : 0.3 , 克 林 顿 : 0.3 }

LDA就是这样说明什么是主题的,竟说得我无言以对,细思之下也是非常合理。

文章在讲什么

给你一篇文章读,然后请你简要概括文章在讲什么,你可能会这样回答:80%在讲政治的话题,剩下15%在讲娱乐,其余都是废话。这里大概可以提炼出三种主题:政治,娱乐,废话。也就是说,对于某一篇文章,很有可能里面不止在讲一种主题,而是几种主题混在一起的。读者可能会问,LDA是一种可以从文档中提炼主题模型,那他在建模的时候有没有考虑这种情形啊,他会不会忘记考虑了。那您就大可放心了,深谋远虑的LDA早就注意到这些了。LDA认为,文章和主题之间并不一定是一一对应的,也就是说,文章可以有多个主题,一个主题可以在多篇文章之中。这种说法,相信读者只能点头称是。假设现在有 K K 个主题,有 M ” role=”presentation” style=”position: relative;”> M 篇文章,那么每篇文章里面不同主题的组成比例应该是怎样的呢?由于上一小节我们知道不能硬性的将某个词套上某个主题,那么这里我们当然不能讲某个主题套在某个文章中,也就是有这样的现象:同一个主题,在不同的文章中,他出现的比例(概率)是不同的,看到这里,读者可能已经发现,文档和主题之间的关系和主题和词汇的关系是多么惊人的类似!LDA先人一步地将这一发现说出来,它说,上一节我们巧妙地用词汇的分布来表达主题,那么这一次也不例外,我们巧妙地用主题的分布来表达文章!同样,我们举个例子来说明一下,假设现在有两篇文章:

《 体 育 快 讯 》 , 《 娱 乐 周 报 》

有三个主题

体 育 , 娱 乐 , 废 话

那么

:[,,,,,....,,] 《 体 育 快 讯 》 是 这 样 的 : [ 废 话 , 体 育 , 体 育 , 体 育 , 体 育 , . . . . , 娱 乐 , 娱 乐 ]


:[,,,,,....,,] 《 娱 乐 周 报 》 是 这 样 的 : [ 废 话 , 废 话 , 娱 乐 , 娱 乐 , 娱 乐 , . . . . , 娱 乐 , 体 育 ]

也就是说,一篇文章在讲什么,通过不同的主题比例就可以概括得出。

文章是如何生成的

在前面两小节中,LDA认为,每个主题会对应一个词汇分布,而每个文档会对应一个主题分布,那么一篇文章是如何被写出来的呢?读者可能会说靠灵感+词汇。LDA脸一沉,感觉完蛋,灵感是什么玩意?LDA苦思冥想,最后没办法,想了个馊主意,它说

= 灵 感 = 随 机

这也是没办法中的办法。因此对于某一篇文章的生产过程是这样的:

  1. 确定主题和词汇的分布
  2. 确定文章和主题的分布
  3. 随机确定该文章的词汇个数 N N
  4. 如果当前生成的词汇个数小于 N ” role=”presentation” style=”position: relative;”> N 执行第5步,否则执行第6步
  5. 由文档和主题分布随机生成一个主题,通过该主题由主题和词汇分布随机生成一个词,继续执行第4步
  6. 文章生成结束

只要确定好两个分布(主题与词汇分布,文章与主题分布),然后随机生成文章各个主题比例,再根据各个主题随机生成词,词与词之间的顺序关系被彻底忽略了,这就是LDA眼中世间所有文章的生成过程!聪明的读者肯定觉得LDA完全就是一个骗子,这样认为文章的生成未免也太过天真了吧。然而事实就是如此,这也是为什么说LDA是一个很简单的模型。幸好我们这是用LDA来做主题分析,而不是用来生成文章,而从上上节的分析我们知道,主题其实就是一种词汇分布,这里并不涉及到词与词的顺序关系,所以LDA这种BOW(bag of words)的模型也是有它的简便和实用之处的。

LDA数学分析

上一小节,我们忽略了一个问题,就是如何确定主题和词汇分布,还有文档与词汇的分布,但是要搞明白这个问题,就避免不了一些数学分析了。再次强烈推荐rickjin的《LDA数学八卦》还有Gregor Heinrich有著名的《Parameter estimation for text analysis》。此处我只做一些关键扼要的理论推导 :-)

多项式分布

回忆一下概率论学的东西,假设一个罐子里有红黄两种球,随机抽取抽到红球的概率是 p p ,如果有放回重复抽 n ” role=”presentation” style=”position: relative;”> n 次球,抽到红球的次数为 k k 的概率分布就是二项分布,也就是

C n k p k ( 1 p ) n k ” role=”presentation”> C n k p k ( 1 p ) n k

如果罐子里有

k k
种不同颜色的球,那么进行抽取

n ” role=”presentation” style=”position: relative;”> n
次球的实验,假设抽到各种颜色球的概率分别是

p1,p2,....,pk p 1 , p 2 , . . . . , p k
,那么抽取

n n
次之后,各种颜色球被抽中的次数

n 1 , n 2 , . . . . , n k ” role=”presentation” style=”position: relative;”> n 1 , n 2 , . . . . , n k
的概率分布就是多项式分布了,记为

n!n1!n2!,....,nk!p1n1p2n2....pknk n ! n 1 ! n 2 ! , . . . . , n k ! p 1 n 1 p 2 n 2 . . . . p k n k

LDA出来说话了:
主题和词汇的分布就是多项式分布!因为一个主题里面不同词汇出现的概率不同,如果只有1个词汇,那么它就是二项分布,但是词汇不可能只有1个,所以它理所当然就是符合多项式分布。这是挺合理的假设,反正我们现在研究的内容是为词汇按主题给出不同的概率分布,其实也就是给出不同词汇在不同主题下的出现比例,我们并不关系词汇之间的顺序关系,所以多项式分布已经很好地刻画出这种关系了。LDA又说:
文章和主题之间的分布也是符合多项式分布!因为一篇文章要确定不同主题的出现概率,和主题要确定每个词汇的出现概率是完全可以类比的!思考一下我们也接受了LDA的说法,接下来我们介绍一些记号:

  • V V 代表我们字典的词汇个数
  • K ” role=”presentation” style=”position: relative;”> K 代表主题的个数
  • M M 代表文章的个数
  • ϕ k ” role=”presentation” style=”position: relative;”> ϕ k 代表第k个主题的多项式分布参数,长度为 V V ,因此 Φ ” role=”presentation” style=”position: relative;”> Φ 是一个 KV K ∗ V 的矩阵,每一行代表一个主题的多项式分布参数
  • θm θ m → 代表第 m m 篇文章的多项式分布参数,长度为 K ” role=”presentation” style=”position: relative;”> K ,因此 Θ Θ 是一个 MK M ∗ K 的矩阵,没一行代表一篇文章的多项式分布参数
  • Nm N m 代表第 m m 篇文章的长度
  • z m , n ” role=”presentation” style=”position: relative;”> z m , n 代表第 m m 篇文章第 n ” role=”presentation” style=”position: relative;”> n 个词由哪个主题产生的
  • wm,n w m , n 代表第 m m 篇文章第 n ” role=”presentation” style=”position: relative;”> n 个词

对于第 m m 篇文章,令 z ” role=”presentation” style=”position: relative;”> z 代表一次实验产生的主题随机变量,那么它就服从:

zMulti(z|θm) z ∼ M u l t i ( z | θ m → )



那么对于第 k k 个主题,令 w ” role=”presentation” style=”position: relative;”> w 代表一次实验产生的词随机变量,那么它就服从:

wMulti(w|ϕk) w ∼ M u l t i ( w | ϕ k → )

然后为了产生第 m m 篇文章,只要简单的按顺序利用 M u l t i ( z | θ m ) ” role=”presentation” style=”position: relative;”> M u l t i ( z | θ m ) 随机生成 zm,1,zm,2,zm,3,...,zm,Nm z m , 1 , z m , 2 , z m , 3 , . . . , z m , N m ,然后对号入座,再利用 Multi(w|ϕzm,n) M u l t i ( w | ϕ z m , n → ) ,生成 wm,1,wm,2,wm,3,...,wm,Nm w m , 1 , w m , 2 , w m , 3 , . . . , w m , N m 即可。

Dirichlet分布

忘记告诉大家,LDA属于江湖中的贝叶斯学派,在贝叶斯学派眼中,像上面提到的 ϕk ϕ k → θm θ m → 都是随机变量,随机变量怎么可以没有先验概率分布呢?这岂不是贻笑大方吗?所以LDA整理了一下衣领,马上提出了他们的先验概率分布:

ϕ⃗ Dirichlet(α⃗ ) ϕ → ∼ D i r i c h l e t ( α → )

θ⃗ Dirichlet(β⃗ ) θ → ∼ D i r i c h l e t ( β → )

为什么LDA要说它的先验分布是Dirichlet分布呢?其中最大的原因是因为多项式分布和Dirichlet分布是一对共轭分布,共轭分布有什么好处呢?好处在于计算后验概率有极大的便利!说到底是LDA看中它计算方便。增加了先验概率分布,那么在确定文章与主题分布还有主题与词汇分布的时候,就由先验概率分布先随机生成确定多项式分布的参数。用一个联合概率分布来描述第 m m 篇文章生成过程:

p ( z m , w m , θ m , Φ | α , β ) = n N m p ( w m , n | ϕ z m , n ) p ( z m , n | θ m ) p ( θ m | α ) p ( Φ | β ) ” role=”presentation”> p ( z m , w m , θ m , Φ | α , β ) = n N m p ( w m , n | ϕ z m , n ) p ( z m , n | θ m ) p ( θ m | α ) p ( Φ | β )


对于习惯了使用极大似然法的同学,为了使用极大似然法,我们必须将隐含变量消除,那么对于第 m m 篇文章其生成的边缘概率为:

p ( w m | α , β ) = θ m Φ z m n N m p ( w m , n | ϕ z m , n ) p ( z m , n | θ m ) p ( θ m | α ) p ( Φ | β ) = θ m Φ z m n N m p ( w m , n | ϕ z m , n ) p ( z m , n | θ m ) p ( θ m | α ) p ( Φ | β ) = θ m Φ z m 1 z m 2 . . . z m N m n N m p ( w m , n | ϕ z m , n ) p ( z m , n | θ m ) p ( θ m | α ) p ( Φ | β ) = θ m Φ n N m z m n p ( w m , n | ϕ z m , n ) p ( z m , n | θ m ) p ( θ m | α ) p ( Φ | β ) ” role=”presentation”> p ( w m | α , β ) = θ m Φ z m n N m p ( w m , n | ϕ z m , n ) p ( z m , n | θ m ) p ( θ m | α ) p ( Φ | β ) = θ m Φ z m n N m p ( w m , n | ϕ z m , n ) p ( z m , n | θ m ) p ( θ m | α ) p ( Φ | β ) = θ m Φ z m 1 z m 2 . . . z m N m n N m p ( w m , n | ϕ z m , n ) p ( z m , n | θ m ) p ( θ m | α ) p ( Φ | β ) = θ m Φ n N m z m n p ( w m , n | ϕ z m , n ) p ( z m , n | θ m ) p ( θ m | α ) p ( Φ | β )


以上可以看到,边缘概率分布实在是太复杂了,靠普通极大似然法来求解基本无望。不过这并不能难倒我们聪明的计算机科学家,下面我们来介绍一种近似求解法。

Gibbs 采样算法

采样算法的思想

对于一个概率分布 p(x⃗ ) p ( x → ) ,我们想得到它得概率分布,无奈有些概率分布形式实在复杂,我们无法直接求解,那么怎么办呢?假设我们的随机变量为:

x⃗ =[x1,x2,x3,...,xi,...,xn] x → = [ x 1 , x 2 , x 3 , . . . , x i , . . . , x n ]


其中 xi{
0,1}
x i ∈ { 0 , 1 }
,假设我们知道 p(x⃗ ) p ( x → ) 的概率分布,那么我们可以通过采样的方式得到每一次的样本值:

x⃗ (1)=[0,0,0,0,....0]x⃗ (2)=[1,1,0,0,....0]x⃗ (3)=[1,0,0,0,....0]x⃗ (4)=[1,1,0,0,....0].......x⃗ (N)=[1,1,0,0,....0] x → ( 1 ) = [ 0 , 0 , 0 , 0 , . . . .0 ] x → ( 2 ) = [ 1 , 1 , 0 , 0 , . . . .0 ] x → ( 3 ) = [ 1 , 0 , 0 , 0 , . . . .0 ] x → ( 4 ) = [ 1 , 1 , 0 , 0 , . . . .0 ] . . . . . . . x → ( N ) = [ 1 , 1 , 0 , 0 , . . . .0 ]


那么我们可以统计每个样本出现的次数,然后除以总的采样次数 N N 来得到相应概率分布。比如我们观察样本值 [ 1 , 1 , 0 , 0 , . . . . ] ” role=”presentation” style=”position: relative;”> [ 1 , 1 , 0 , 0 , . . . . ] 出现了 K K 次,那么样本出现的概率就可以如下求得:

p ( x 1 = 1 , x 2 = 1 , x 3 = 0 , . . . . , x n = 0 ) = K N ” role=”presentation”> p ( x 1 = 1 , x 2 = 1 , x 3 = 0 , . . . . , x n = 0 ) = K N


这是采样的基本思想,但是这里有令人匪夷所思的地方,首先我们不知道概率分布想得到概率分布我们必须通过采样方法来求得,但是采样方法又依赖于我们知道对应的概率分布才能得到相应的采样值,这是一个“鸡生蛋,蛋生鸡“的矛盾,足以令人百思不得其解,此时神奇的Gibbs采样更加令人充满敬畏。

神奇的Gibbs采样

实际应用中,我们通常是有一堆文章,然后要我们去自动提取主题,或者通过现有的文章训练出LDA模型,然后预测新的文章所属主题分类。也就是我们的兴趣点在于求出 Θ Θ Φ Φ 的后验概率分布。虽然LDA的模型思想很简单,但是要精确求出参数的后验概率分布却是不可行的,只能通过近似的方式求解。幸好前人已经发现了很多近似求解方法,其中比较简单的就是Gibbs采样,Gibbs的采样精神很简单,对于一个很复杂的高维概率分布:

p(x⃗ ) p ( x → )


我们想获得 p(x⃗ ) p ( x → ) 的样本,从而确定 p(x⃗ ) p ( x → ) 的参数值,也就是我们无法直接求取概率分布的参数,但是我们可以通过神奇的Gibbs采样,获得需要求解的概率分布的样本值,从而反过来确定概率分布。Gibbs采样很简单,它说如果你能很容易求解(通常都是很容易求解,因为此时的分布是一个一维的条件分布)

p(xi|x¬i) p ( x i | x ¬ i → )


这样的条件分布,那么想获得联合分布的样本,只需执行如下过程:

  • 随机初始化 x⃗ 0={
    x01,x02,...,x0N}
    x → 0 = { x 1 0 , x 2 0 , . . . , x N 0 }
  • 对于 t=1,2,3,4,….T:
    • xt1p(x1|xt1¬1) x 1 t ∼ p ( x 1 | x ¬ 1 t − 1 → )
    • xt2p(x2|xt1¬2) x 2 t ∼ p ( x 2 | x ¬ 2 t − 1 → )
    • xt3p(x3|xt1¬3) x 3 t ∼ p ( x 3 | x ¬ 3 t − 1 → )
    • ….
    • xtNp(xN|xt1¬N) x N t ∼ p ( x N | x ¬ N t − 1 → )
    • 得到一个样本值 x⃗ (t)=[xt1,xt2,xt3,....,xtN] x → ( t ) = [ x 1 t , x 2 t , x 3 t , . . . . , x N t ]


当采样过程收敛之后,通过以上采样得到的样本就是真实的 p(x⃗ ) p ( x → ) 样本。为什么可以如此神奇地操作,再次推荐rickjin的《LDA数学八卦》!

Collapsed Gibbs Sampler

p(zm,wm,θm,Φ|α⃗ ,β⃗ ) p ( z m → , w m → , θ m → , Φ | α → , β → )


为了采样方便,对于参数 θm θ m → Φ Φ ,它们本身就是关联 z⃗  z → w⃗  w → 的,也就是我们如果得到 z⃗  z → w⃗  w → 的采样,参数 θm θ m → Φ Φ 自然可以得知。那么可以积分化简,得到最终要采样的模型:

p(z⃗ ,w⃗ |α⃗ ,β⃗ ) p ( z → , w → | α → , β → )


有了联合分布,Gibbs万能算法就可以套用了,首先它必须先解决一个问题(为了表达方便,超参数 α⃗ ,β⃗  α → , β → 省略):

p(zm,i|zm,¬i,wm) p ( z m , i | z m , ¬ i , w m → )

其中 zm={
zm,ik,zm,¬i}
z m → = { z m , i = k , z m , ¬ i }
zm,¬i z m , ¬ i 代表第 m m 篇文章里面去除主题 z m , i ” role=”presentation” style=”position: relative;”> z m , i 的其他所有主题。其具体推导一开始推荐的文章都有详尽严格的过程,这里实在没有必要在赘述,直接给出结果(为了表达方便,这里去除下标m):

p(zi=k|z¬i,w⃗ )=p(w⃗ ,z⃗ )p(w⃗ ,z¬i)=p(w⃗ |z⃗ )p(w¬i|z¬i)p(wi)p(z⃗ )p(z¬i)p(w⃗ |z⃗ )p(w¬i|z¬i)p(z⃗ )p(z¬i)n(t)k,¬i+βtVt=1n(t)k,¬i+βtn(k)m,¬i+αkKk=1n(k)m,¬i+αkn(t)k,¬i+βtVt=1n(t)k,¬i+βt(n(k)m,¬i+αk) p ( z i = k | z ¬ i , w → ) = p ( w → , z → ) p ( w → , z ¬ i → ) = p ( w → | z → ) p ( w ¬ i | z ¬ i → ) p ( w i ) p ( z → ) p ( z ¬ i ) → ∝ p ( w → | z → ) p ( w ¬ i | z ¬ i → ) p ( z → ) p ( z ¬ i ) → ∝ n k , ¬ i ( t ) + β t ∑ t = 1 V n k , ¬ i ( t ) + β t n m , ¬ i ( k ) + α k ∑ k = 1 K n m , ¬ i ( k ) + α k ∝ n k , ¬ i ( t ) + β t ∑ t = 1 V n k , ¬ i ( t ) + β t ( n m , ¬ i ( k ) + α k )

其中 n(t)k n k ( t ) 代表第 m m 篇文章中词汇 t ” role=”presentation” style=”position: relative;”> t 属于主题 k k 出现的次数, n k , ¬ i ( t ) ” role=”presentation” style=”position: relative;”> n k , ¬ i ( t ) 代表除去其中 zi z i 的剩余个数,也就是说

n(t)k,¬i=n(t)k1 n k , ¬ i ( t ) = n k ( t ) − 1

类似的, n(k)m n m ( k ) 代表第 m m 篇文章中主题 k ” role=”presentation” style=”position: relative;”> k 出现的次数, n(k)m,¬i n m , ¬ i ( k ) 代表除去其中 zi z i 的剩余个数,也就是说

n(k)m,¬i=n(k)m1 n m , ¬ i ( k ) = n m ( k ) − 1

所以计算 p(zi|z¬i,w⃗ ) p ( z i | z ¬ i , w → ) 变成简单地在计数的问题。通过Gibbs采样算法后,最后的模型参数可以这样得出:

ϕk,t=n(t)k+βtVt=1n(t)k+βt ϕ k , t = n k ( t ) + β t ∑ t = 1 V n k ( t ) + β t

θm,k=n(k)m+αkKk=1n(k)m+αk θ m , k = n m ( k ) + α k ∑ k = 1 K n m ( k ) + α k

判断新文章的主题分布

由上一小节,我们可以通过大量文章求解出LDA这个模型,那么对于一篇新的文章,如何计算它的主题分布呢?一个方式是将文章加入到原来的训练集合里面 {
z̃ ⃗ ,z⃗ ;w̃ ⃗ ,w⃗ }
{ z ~ → , z → ; w ~ → , w → }
,然后得到它的采样条件概率为:

p(zi~=k|z̃ ⃗ ¬i,z⃗ ,w⃗ ,w̃ ⃗ )n(t)k+ñ (t)k,¬i+βtVt=1n(t)k+ñ (t)k,¬i+βtn(k)m̃ ,¬i+αkKk=1n(k)m̃ ,¬i+αk p ( z i ~ = k | z ~ → ¬ i , z → , w → , w ~ → ) ∝ n k ( t ) + n ~ k , ¬ i ( t ) + β t ∑ t = 1 V n k ( t ) + n ~ k , ¬ i ( t ) + β t n m ~ , ¬ i ( k ) + α k ∑ k = 1 K n m ~ , ¬ i ( k ) + α k

再重新跑一次Gibbs采样,然后得到它的分布。实际上这种做法确实是最优的,但是太慢了,怎么办呢?因为新来的文章,它的词汇是固定的,我们上节已经求出 ϕk,t ϕ k , t ,也就是词汇和主题的分布已经是确定的,我们没必要再浪费计算力了,也就是我们认为对一篇新文章,它已经难以撼动之前成千上万文章的统计结果了,也就是说:

n(t)k+ñ (t)k,¬i+βtVt=1n(t)k+ñ (t)k,¬i+βtn(t)k+βtVt=1n(t)k+βt n k ( t ) + n ~ k , ¬ i ( t ) + β t ∑ t = 1 V n k ( t ) + n ~ k , ¬ i ( t ) + β t ≈ n k ( t ) + β t ∑ t = 1 V n k ( t ) + β t

所以我们新的条件采样概率变成了:

p(zi~=k|w̃ i=t,z̃ ⃗ ¬i,z⃗ ,w⃗ ,w̃ ¬i)ϕk,t(n(k)m̃ ,¬i+αk) p ( z i ~ = k | w ~ i = t , z ~ → ¬ i , z → , w → , w ~ ¬ i → ) ∝ ϕ k , t ∗ ( n m ~ , ¬ i ( k ) + α k )

然后我们又可以开动Gibbs采样发动机,得到最终的分布结果:

θm̃ ,k=n(k)m̃ +αkKk=1n(k)m̃ +αk θ m ~ , k = n m ~ ( k ) + α k ∑ k = 1 K n m ~ ( k ) + α k

LDA的Gibbs采样实现

对于程序员来说,看惯代码,没有代码有点无所适从,有没有简单LDA的实现漂亮代码呢?答案是有的,LingPipe里面的LatentDirichletAllocation这个类,完整地按照Gregor Heinrich有著名的《Parameter estimation for text analysis》介绍的算法实现了,代码非常简单,并且可读性极高,建议抓来一看,必然大有毗益。此处我们贴出Gregor中提供的伪代码,以供查看:

  • 初始化阶段,出乎意料的简单,只要初始化4个统计量,分别是:
    • 文档 m m 对应主题 k ” role=”presentation” style=”position: relative;”> k 的计数: nkm n m k
    • 文档 m m 的词汇数: n m ” role=”presentation” style=”position: relative;”> n m
    • 主题 k k 对应的词汇为 t ” role=”presentation” style=”position: relative;”> t 的计数: ntk n k t
    • 主题 k k 的词汇数: n k ” role=”presentation” style=”position: relative;”> n k


  • nkm,nm,ntk,nk n m k , n m , n k t , n k 内存清0,然后根据以下程序随机初始化值:
    • 遍历每一个文档 m[1,M] m ∈ [ 1 , M ]
      • 遍历每个词汇 n[1,Nm] n ∈ [ 1 , N m ]
        • 从多项式分布 Mult(1/K) M u l t ( 1 / K ) 得到一个采样值: zmn=k z m n = k
        • nkm=nkm+1 n m k = n m k + 1
        • nm=nm+1 n m = n m + 1
        • ntk=ntk+1 n k t = n k t + 1
        • nk=nk+1 n k = n k + 1




  • Gibbs采样过程,以下是一个采样周期的执行过程:
    • 遍历每一个文档 m[1,M] m ∈ [ 1 , M ]
      • 遍历每个词汇 n[1,Nm] n ∈ [ 1 , N m ]
        • 对于当前的 wm,n w m , n 的主题 k k 对应的词汇 t ” role=”presentation” style=”position: relative;”> t 执行:

          • nkm=nkm1 n m k = n m k − 1
          • nm=nm1 n m = n m − 1
          • ntk=ntk1 n k t = n k t − 1
          • nk=nk1 n k = n k − 1
          • 根据 p(zi=k|z¬i,w⃗ ) p ( z i = k | z ¬ i , w → ) 获得一个采样值: k̂ =zm,n k ^ = z m , n 并执行:
            • nk̂ m=nk̂ m+1 n m k ^ = n m k ^ + 1
            • nm=nm+1 n m = n m + 1
            • ntk̂ =ntk̂ +1 n k ^ t = n k ^ t + 1
            • nk̂ =nk̂ +1 n k ^ = n k ^ + 1






难以置信的简单,一般在收敛之前,需要跑一定数量的采样次数让采样程序大致收敛,这个次数一般称为:burnin period。我们希望从采样程序中获得独立的样本,但是显然以上的采样过程明显依赖上一个采样结果,那么我们可以在上一次采样后,先抛弃一定数量的采样结果,再获得一个采样结果,这样可以大致做到样本独立,这样真正采样的时候,总有一定的滞后次数,这样的样本与样本的间隔称为:SampleLag。

LDA为什么能work

p(z|w,θ)p(w,z,θ|α)=mp(θm|α)np(zmn|θm)p(wmn|zmn,Φ) p ( z | w , θ ) ∝ p ( w , z , θ | α ) = ∏ m p ( θ m | α ) ∏ n p ( z m n | θ m ) p ( w m n | z m n , Φ )


首先需要明确的是 隐变量的后验概率分布是正比于联合概率分布的。在极大似然法中, 我们会希望模型越接近实际越好,也就是模型在数据上的概率越大越好。我们先只考虑上面表达式的数据似然项 p(wmn|zmn,Φ) p ( w m n | z m n , Φ ) ,为了使这一似然项越大越好,我们会希望某个 主题下对应的词的概率越大越好,由于主题-词汇分布由 Φ Φ 决定,理想情况下,我们希望 Φ Φ 矩阵应该是长下面这个样子:
这里写图片描述
横向代表主题,总共有 K K 行,列向代表词汇,总共有 V ” role=”presentation” style=”position: relative;”> V 列。

我们希望每个主题的词汇概率质量如上图蓝色方块所示(方块的概率和为1),也就是词汇按照主题个数不重叠地切割,这样可以保证词汇在所属主题下概率值最大,因为每一行概率和为1,我们希望概率密度集中在某些词上面,而不是分散地落在每个词上面(请读者思考一下为什么这样会使最终的概率值增大,这里比较难以用文字表达清楚,可以设想一下,假如每个主题的概率密度均匀分配到每个词上面,那么最终每一项 p(wmn|zmn,Φ) p ( w m n | z m n , Φ ) 会很小,这与我们的愿望是违背的)。为了使模型在数据上的概率最大,算法会倾向于将主题词汇分布按照上图的形式拟合,也就是“主题-词汇”分布会倾向于成为一个稀疏的分布。

有了上面的讨论,我们再来想想,每个主题会选哪些词汇作为自己的主题词呢? 也就是主题应该选哪些词来将自己的概率质量散落在他们身上。答案是那些经常出现在一起的词。假设主题A下面有主题词: a1,a2,...,an a 1 , a 2 , . . . , a n ,为了使概率值变大,那么这些词一定是同时出现在很多个文档里面,并且在多个文档中,这些词大部分都同时出现。可以想想为什么要这样,假设不是这样,比如在文档1种主题A的词汇是 a1,a2,a3,a4 a 1 , a 2 , a 3 , a 4 ,在文档2中主题A的词汇是 a5,a6,a7,a8 a 5 , a 6 , a 7 , a 8 ,在文档3中主题A的词汇是 a9,a10,a11,a12 a 9 , a 10 , a 11 , a 12 ,以此类推,如果主题A的词汇真的是这个样子——文档中同一主题都没有在另一个文档中出现,那么主题A下面的词会很多,但是我们上面分析了,为了使模型概率值大,每个主题下面的词必须越少越好,所以这也是有违背愿望的。因此主题下面的词都会倾向于同时出现在多个文档中,到这里为止,读者应该可以大概明白为什么LDA可以产生那么符合直觉的词汇分布了,因为在我们人类自己的概念中,主题词汇就是这样的东西,他们会经常一起出现,比如“银行”,“存款”这些金融主题词汇会很频繁同时出现在多个场合中,所以我们会将他们归为一个主题,而LDA恰恰能捕获这种特性。

Edwin Chen的博客《Introduction to Latent Dirichlet Allocation》也比较直观地介绍了LDA的直觉特性。至于怎么从理论上来说明为什么具有稀疏性质, Quora上面有一个相对直观的解释,我大概总结一下,由于LDA用Dirichlet作为Prior分布,而作为Prior的Dirichlet在其分布参数 α⃗  α → 取很小的时候(一般 α α K/50 K / 50 , β β 取值0.01),可以使得其采样的多项式参数变得稀疏。LDA有两对稀疏对抗,主题与文档的稀疏性和主题与词汇的稀疏性之间的对抗,而LDA会从数据中学习到一个权衡结果。为什么Dirichlet会有稀疏性质呢?可以参照以这篇:
《Notes on Multinomial sparsity and the Dirichlet concentration parameter α》
这篇note提到的Dirichlet其实可以看成几个Gamma分布变换而来,具体变换证明可以参照Quora另一个解答:Construction of Dirichlet distribution with Gamma distribution。另一个好处是,多了先验分布的模型比pLSA更加健壮,不容易导致overfiting,如果看回上面推导Gibbs Sampling的公式,Dirichlet其实起到一种Smooth的效果。可以再参考Kevin Gimpel写的《Modeling Topics》,对于几种常见基础的主题模型的对比,也可以解除不少困惑。

参考文献

  • 《LDA数学八卦》
  • 《Parameter estimation for text analysis》
  • 《gibbs sampling for the uninitiated》
  • 《text mining and topic models》
  • 《A Theoretical and Practical Implementation Tutorial on Topic Modeling and Gibbs Sampling》
  • 《Probabilistic Latent Semantic Analysis》
  • LingPipe
  • 《Modeling Topics》
  • 《Notes on Multinomial sparsity and the Dirichlet concentration parameter α》
  • Why does LDA works?
  • Construction of Dirichlet distribution with Gamma distribution
  • Dave Blei’s video lecture on topic models: http://videolectures.net/mlss09uk_blei_tm




















版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/223230.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午2:34
下一篇 2026年3月17日 下午2:34


相关推荐

  • SVN使用教程图文教程

    SVN使用教程图文教程2 安装 SVN2 1 安装完成后 比如我想把代码放在我的电脑其中一个位置比如 我的项目在 F 盘的目录下中 我右键就可以看到如下 说明 snv 已经安装成功了 2 2 使用 checkout 下载项目 先说下几个基本的命令 Checkout 把 SVN 仓库的代码下载到本地 比如你现在参与一个团队的项目 在你参与之前项目可能已经在运行或者技术主管也已经搭建好代码仓库 你可以通过 checkout

    2026年3月20日
    2
  • DrawImage方法详解(转载)

    DrawImage方法详解(转载)Image和Bitmap类概述GDI+的Image类封装了对BMP、GIF、JPEG、PNG、TIFF、WMF(Windows元文件)和EMF(增强WMF)图像文件的调入、格式转换以及简单处理的功能。

    2022年7月1日
    25
  • clipper库使用的一些心得

    clipper库使用的一些心得多边形处理库 clipper 的使用心得总结

    2026年3月17日
    1
  • JVM运行原理详解

    JVM运行原理详解1 JVM 简析 作为一名 Java 使用者 掌握 JVM 的体系结构也是很有必要的 说起 Java 我们首先想到的是 Java 编程语言 然而事实上 Java 是一种技术 它由四方面组成 Java 编程语言 Java 类文件格式 Java 虚拟机和 Java 应用程序接口 JavaAPI 它们的关系如下图所示 运行期环境代表着 Java 平台 开发人员编写 Ja

    2026年3月18日
    1
  • Python day2 知识回顾

    Python day2 知识回顾标准库一般放在 lib site packages 放自己下载的 起的 py 文件名称不要和模块名字相同 importsys print sys path 打印去哪里寻找这些模块的路径 print sys argv 当前路径打印 importoscmd res os system dir 只是打印目录输出在屏幕 但不保存 cmd res os popen dir read

    2026年3月16日
    2
  • 矿机价格又双叕暴跌!个人挖不到收益,区块已经垄断

    矿机价格又双叕暴跌!个人挖不到收益,区块已经垄断






从去年高峰时期的2万元抢不到,跌到现在7000元竟然无人问津。有这样一个故事在行业里流传:曾经有一位…

    2022年6月3日
    47

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号