主题模型
机器学习
常见使用场景
在机器学习和自然语言处理中,主题模型是最近比较热门的一个话题,它能够从一个给定文档集合中发现在这些文档中隐藏的“主题”。当给定某个主题的文档,则在这篇文档中,和该主题相关的词语会更加频繁出现。例如,关于体育的新闻中,像“棒球”,“赛点”这些词语相比于“火锅”,“川菜”更加容易出现。而且通常一个文档不仅仅含有一个主题,它更有可能同时包含多个主题。例如,常见的武侠小说中,可能80%的文字在描写打斗,剩下的15%和5%的文字分别描述了爱情或者政治等主题。主题模型会通过训练集学习到组成每篇文章的主题分布和每个词语代表着各个主题的概率,即主题-词项分布和文章-主题分布,这样当遇到一篇新的文档时,我们就可以通过主题-词项分布确定新文档的主题分布。
LSA算法
LSA的目的是要从文本中发现隐含的语义维度,即主题。我们知道,在文档的空间向量模型(VSM)中,文档被表示成由特征词出现概率组成的多维向量,这种方法的好处是可以将查询和文档转化成同一空间下的向量计算相似度,可以对不同词项赋予不同的权重,在文本检索、分类、聚类问题中都得到了广泛应用。然而,向量空间模型没有能力处理一词多义和一义多词问题,因此会造成计算文档间相似度的不准确性。LSA一定程度上解决上述所描述的问题。具体说来就是对一个大型的文档集合使用一个合理的维度建模,并将词项和文档都表示到该空间中。比如有2000个文档,包含7000个索引词,LSA使用一个维度为100的向量空间将文档和词项表示到该空间,进而在该空间进行信息检索。而将文档表示到此空间的过程就是SVD奇异值分解和降维的过程。降维是LSA分析中最重要的一步,通过降维,去除了文档中的“噪音”,也就是无关信息(比如词的误用或不相关的词偶尔出现在一起),语义结构逐渐呈现。相比传统向量空间,潜在语义空间的维度更小,语义关系更明确。因此将文档和词语都在潜在语义空间表示,我们就能计算Document-Document,Document-Term,Term-Term的相似度。
LSA的步骤如下:
1. 分析文档集合,建立Term-Document矩阵。
2. 对Term-Document矩阵进行奇异值分解。
3. 对SVD分解后的矩阵进行降维,保留前k个特征值,后面r−k个置零,也就是低阶近似。
4. 使用降维后的矩阵构建潜在语义空间,或重建Term-Document矩阵。新得到的Term-Document矩阵就是我们经过LSA模型提取低维隐含语义空间。该空间中,每个奇异值对应的是每个“语义”维度的权重,我们刚才将不太重要的权重置为零,只保留最重要的维度信息,因而可以得到文档的一种更优表达形式。
假设我们有五篇文档和一个查询:
d1 = Romeo and Juliet.
d2 = Juliet: O happy dagger!
d3 = Romeo died by dagger.
d4 = "Live free or die", that’s the New-Hampshire’s motto.
d5 = Did you know, New-Hampshire is in New-England.
q = dies, dagger.
很明显当我们查询dies, dagger的时候,d3应该是最相关的,因为在d3中同时出现dies, dagger,d2和d4各自包含一个单词紧随其后。但是d1和d5该怎么排列?我们都知道d1应该在d5之前,但是机器怎么识别呢?解决方法正是LSA,在这个例子中,d1中的Romeo和Juliet分别在d2和d3和单词dagger有关联,而单词dagger也是同理,对于d1和d5分别通过Romeo和New-Hampshire与dagger相联系。下面我们会通过更正式的方式来表达上述过程。
假设A是Term-Document矩阵,那么A的每列对应一篇文章,每行是一个单词。则A矩阵看上去是如下的样子:
romeojuliethappydaggerlivediefreenew hampshired111000000d201110000d310010100d400001111d500000001
很显然
B=ATA是Document-Document矩阵,如果文档i和j有b个相同的单词,则
B[i,j]=b。另一方面
C=AAT是Term-Term矩阵,如果单词i和j同时出现在一篇文档的频数是c,则
C[i,j]=c。很明显,矩阵B和C都是对称矩阵。我们对A做SVD分解。
A=UΣVT
其中U是矩阵B的特征向量,V是矩阵C的特征向量,
Σ是矩阵B的特征值的平法根。
Σ=⎡⎣⎢⎢⎢⎢2.285000002.201000001.361000001.187000000.797⎤⎦⎥⎥⎥⎥
我们只保留
Σ前
K个特征值,其余替换成0形成新的矩阵
Σk。对矩阵
U和
V也只保留对于
K项。然后计算“去噪”后的矩阵
Ak。
Ak=UkΣkVTk
因此,Term-Term与Document-Document在潜在语义空间的相关性矩阵可以表示为:
AkATk=(UkΣkVTk)(UkΣkVTk)T=UkΣkVTkVkΣTkUTk=UkΣkΣTkUTkATkAk=(UkΣkVTk)T(UkΣkVTk)=VkΣTkUTkUkΣkVTk=VkΣTkΣkVTk
因此我们可以把
UkΣk矩阵的行看作是term在潜在语义空间的坐标。同理我们认为
VkΣTk的行表示了文档的坐标。
回到之前例子中,我们只取前k=2个特征值,则:
Σ2=[2.285002.201]
U2=⎡⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢0.3960.3140.1780.4380.2640.5240.2640.3260.2800.4500.2690.3690.3460.2460.3460.460⎤⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥
VT2=[0.3110.3630.4070.5410.5940.2000.6030.6950.1430.229]
我们知道
U2Σ2的行代表单词在潜在语义空间的坐标,同理
V2ΣT2表示文档的坐标。则:
romeo=[0.9050.563],juliet=[0.7170.905],happy=[0.4070.541],dagger=[1.1970.494],live=[0.6030.695],die=[1.0010.742],free=[0.6030.695],new hampshire=[0.7450.925],
和
d1=[0.7110.730],d2=[0.9301.087],d3=[1.3570.402],d4=[1.3781.397],d5=[0.3270.460]
因此查询die, dagger也可以表示成两个 质心:
q=[1.0010.742]+[1.1970.494]2=[1.0990.124]
然后我们可以计算查询词和每片文档的距离:
diq|di||q|
下图就是所有文档、词语和查询在潜在语义空间的坐标:
对于新文档,如何计算它在潜在语义空间的坐标呢?事实上,不需要重新进行SVD分解,由:
A=UΣVT⇒UTA=UTUΣVT⇒Σ−1UTA=VT⇒V=ATUΣ−1(1)
对于新的文档仅需在
A矩阵加一列再代入(1)式重新计算出新文档的
V然后再乘以
Σ即可。
pLSA算法
我们了解到通过SVD可以进行LSA,把给定文档投影到语义空间,但其缺乏严谨的数理统计基础并且SVD分解非常耗时。pLSA则是从概率分布的角度建模的一种方法,它假设在词和文档之间有一层主题隐语义,而主题符合多项分布,一个主题中的词项也符合多项分布,由这两层分布的模型,生成各种文档。想象某个人要写N篇文档,他需要确定每篇文档里每个位置上的词。假定他一共有K个可选的主题,有V个可选的词项,所以,他制作了K个V面的“主题-词项”骰子,每个骰子对应一个主题,骰子每一面对应要选择的词项。然后,每写一篇文档会再制作一颗K面的“文档-主题”骰子;每写一个词,先扔该骰子选择主题;得到主题的结果后,使用和主题结果对应的那颗“主题-词项”骰子,扔该骰子选择要写的词。他不停的重复如上两个扔骰子步骤,最终完成了这篇文档。重复该方法N次,则写完所有的文档。在这个过程中,我们并未关注词和词之间的出现顺序,所以pLSA也是一种词袋方法。PLSA的概率图模型如下:
实心的节点d和w表示我们能观察到的文档和单词,空心的z表示我们观察不到的隐藏变量,用来表示隐含的主题。图中用了所谓的“盘子记法”,即用方框表示随机变量的重复。这里方框右下角的字母M和N分别表示有M篇文档,第j篇文档有N个单词。每条有向边表示随机变量间的依赖关系。也就是说,pLSA 假设每对(d,w)都是由下面的过程产生的:
1. 以p(d)的先验概率选择一篇文档
2. 选定d后,以p(z|d)的概率选中主题
3. 选中主题z后,以p(w|z)的概率选中单词
而我们感兴趣的正是其中的p(z|d)和p(w|z),利用前者我们可以知道每篇文章中各主题所占的比重,利用后者我们则能知道各单词在各主题中出现的概率,从而进一步找出各主题的“关键词”。记θ=(p(z|d),p(w|z)), 表示我们希望估计的模型参数。当然θ不仅仅代表两个数,而是对于每对(zk,di)和(zk,wj), 我们都要希望知道p(zk|di)和p(wj|zk)的值。也就是说,模型中共有|Z|∗|D|+|Z|∗|W|个参数。我们还知道:
p(d,w)=p(d)p(w|d)p(w|d)=∑zp(w|z)p(z|d)
于是,可以很容易写出样本分布的对数似然函数:
L(θ)=log∏d,wp(d,w)n(d,w)=∑d,wn(d,w)log∑zp(d)p(w|z)p(z|d)=∑d,wn(d,w)log∑zp(w|z)p(z|d)
因为p(d)和参数θ无关,所以第三步略掉,这里出现log套∑的形式,导致很难直接拿它做最大似然。但假如能观察到z,问题就很简单了。于是对于这种含有隐变量的最大似然估计,我们还是需要使用EM方法。
EM算法的步骤是:
1. E步骤:求隐含变量在给定当前估计的参数条件下的后验概率。
2. M步骤:最大化complete data对数似然函数的期望,此时我们使用E步骤里计算的隐含变量的后验概率,得到新的参数值,两步迭代进行直到收敛。
先解释一下什么是incomplete data和complete data。当原始数据的似然函数很复杂时,我们通过增加一些隐含变量来增强我们的数据,得到complete data,而complete data的似然函数更加简单,方便求极大值。于是,原始的数据就成了incomplete data。我们将会看到,我们可以通过最大化complete data似然函数的期望来最大化incomplete data的似然函数,以便得到求似然函数最大值更为简单的计算途径。
针对我们pLSA参数估计问题,在E步骤中,直接使用贝叶斯公式计算隐含变量在当前参数取值条件下的后验概率,有:
P(zk|di,wj;θt)=Pt(zk|di)Pt(wj|zk)∑zPt(z|di)Pt(wj|z)
而
Pt(zk|di)和
Pt(wj|zk)就是上轮迭代求出的,这样就完成了E-step。接下来M-step就是带入隐变量的后验概率,最大化样本分布的对数似然函数,更新参数
Pt(zk|di)和
Pt(wj|zk)。
Q(θ,θold)=E[log p(w,z,d)]=∑d,wn(d,w)∑kp(zk|di,wj;θt)log p(w,z,d)=∑d,wn(d,w)∑kp(zk|di,wj;θt)log p(z|d)p(w|z)
注意这里
p(zk|di,wj;θt)是已知的,取的是前面E步骤里面的估计值。下面我们来最大化期望,这又是一个带约束条件求极值的问题,可以用拉格朗日乘数法。拉格朗日乘数法可以把条件极值问题转化为无条件极值问题,在pLSA中目标函数就是,约束条件是:
∑kp(zk|di)∑jp(wj|zk)=1=1
这里我们引入两个乘子
λ和
u,可以写出拉格朗日函数,如下:
H=E[log p(w,z,d)]+λ∑i(1−∑kp(zk|di))+u∑k(1−∑jp(wj|zk))
这是一个关于
θ=(p(z|d),p(w|z))的函数,分别对其求偏导数,我们可以得到:
Pt+1(w(j)|z(k))Pt+1(z(k)|d(i))=∑dn(d,w(j))P(z(k)|d,w(j);θt)∑d,wn(d,w)P(z(k)|d,w;θt)=∑wn(d(i),w)P(z(k)|d(i),w;θt)∑w,zn(d,w)P(z|d(i),w;θt)
然后使用更新后的参数值
θ=(pt+1(z|d),pt+1(w|z)),我们又进入E步骤,计算隐含变量给出当前估计的参数条件下的后验概率。如此不断迭代,直到满足终止条件。
LDA算法
在原始的pLSA模型中,我们求解出两个参数:“主题-词项”p(w|z)和“文档-主题”p(z|d),但是我们并未考虑参数的先验知识;而LDA的改进之处,是对这俩参数之上分别增加了先验分布,相应参数称作超参数(hyperparamter)。概率图表示如下:
和pLSA模型类似,其中,单圆圈表示隐变量,双圆圈表示观察到的变量。对应到上图,只有wm,n是观察到的变量,其他都是隐变量或者参数,其中α和β是超参数。方框中Φ={φ⃗ k}Kk=1表示有K种“主题-词项”分布,Θ={ϑ⃗ m}Mm=1有M种“文档-主题”分布,即对每篇文档都会产生一个ϑ⃗ m分布。每篇文档m中有n个词,每个词wm,n都有一个主题zm,n,该词实际是由φ⃗ zm,n产生。具体过程下面再说。
贝叶斯估计
在pLSA原参数之上增加先验分布,其实就是用贝叶斯估计取代最大似然估计,具体要了解各种参数估计方法可以参考Heinrich论文的第二部分。简单说,最大似然估计(MLE)和最大后验估计(MAP)都是把待估计的参数看作一个拥有固定值的变量,只是取值未知。通常估计的方法都是找使得相应的函数最大时的参数,都是典型的点估计;由于MAP相比于MLE会考虑先验分布的影响,所以MAP也会有超参数,它的超参数代表的是一种信念(belief),会影响推断(inference)的结果。比如说抛硬币,如果我先假设是公平的硬币,这也是一种归纳偏置(bias),那么最终推断的结果会受我们预先假设的影响。贝叶斯估计是对MAP的扩展,但它不再对参数做直接的估计,而是把待估计的参数看作服从某种分布的随机变量。根据贝叶斯法则:
posterior=likelihood⋅priorevidence
即
p(X|θ)=p(θ|X)⋅p(θ)p(X)
在MLE和MAP中,由于是要求函数最大值时的参数,所以都不会考虑evidence。但在贝叶斯估计中,不再直接取极值,所以还会考虑evidence,下面的这个积分也是通常贝叶斯估计中最难处理的部分:
p(X)=∫p(θ|X)⋅p(θ)dθ
共轭先验
由于有积分的存在,贝叶斯估计常常会很难推算,这里我们就需要利用一种共轭先验(Conjugate Prior)的数学知识。在贝叶斯统计理论中,如果某个随机变量ϑ的先验分布p(ϑ)和后验分布p(ϑ|X)属于统一分布簇(简单说就是有同样的函数形式),则称先验分布p(ϑ)和后验分布p(ϑ|X)为共轭分布,先验分布p(ϑ)是似然函数p(X|ϑ)的共轭先验。
由于pLSA中参数“主题-词项”p(w|z)和“文档-主题”p(z|d)都服从多项分布,因此选择Dirichlet分布作为他们的共轭先验。在pLSA中,假设这俩多项分布是确定的,我们在已经假设确定的分布下,选择具体的主题和词项;但在LDA中,这俩多项分布的参数是被当作随机变量,服从另一层先验分布,所以,Dirichlet分布也称作分布的分布,其定义如下:
Dir(p⃗ |α⃗ )≜Γ(∑Kk=1αk)∏Kk=1Γ(αk)∏k=1Kpαk−1k≜1Δ(α⃗ )∏k=1Kpαk−1k(1)
其中,
p⃗ 是要猜测的随机向量,
α⃗ 是超参数,
Δ(α⃗ )称作Delta函数,是Dirichlet分布的归一化系数。
多项分布定义:
Mult(n⃗ |p⃗ ,N)≜(Nn⃗ )∏k=1Kpnkk(2)
其中,
p⃗ 和
n⃗ 服从约束
∑kpk=1和
∑knk=N。而
Γ(x+1)=x!就是阶乘在实数集上的扩展。因此,公式(1)和(2)有相同的形式,所以,这俩分布也称作Dirichlet-Multinomail共轭。
接着我们再来看看,对于非负实数α和β,我们有如下关系:
Beta(p|α,β)+BioCount(m1,m2)=Beta(α+m1,β+m2)
其中
BioCount(m1,m2)对应的是二项分布
B(m1+m2,p)的计数。从以上我们可以看出,Beta分布中的超参数
α和
β可以理解为物理计数,也被称为伪计数(pseudo-count)。同理推广到多项式分布有:
Dir(p⃗ |α⃗ )+MultCount(m⃗ )=Dir(p⃗ |α⃗ +m⃗ )
其中
MultCount(m⃗ )对应的是多项分布
Mult(m⃗ ,p⃗ )的计数。同理,Dir分布中的超参数
α⃗ 也可以理解为伪计数(pseudo-count)
现在考虑Dirichlet分布的特殊情况,超参数α⃗ 中的值相等,即α⃗ =αI⃗ ,变量α也称为聚集参数。下图就是α取不同值时候对称Dirichlet分布的图形:
很明显可以看到,当α=1时,Dirichlet分布退化为均匀分布。当α>1时,先验概率会更倾向于p1=p2=...=pk的情况。当α<1时,先验概率会更倾向于pi=1,pother=0的情况。换句话说,当聚合参数α=1时,先验退化为均匀分布。当大于1时,LDA就聚合在更多的主题,相反小于1,则聚合在少数几个主题。
生成过程
在LDA中,“文档-主题”向量ϑ⃗ m由超参数为α⃗ 的Dirichlet分布生成,“主题-词项”向量φ⃗ k由超参数为β⃗ 的Dirichlet分布生成。
符号解释:
- M文档数(固定值)
- K主题(component)数(固定值)
- V词项数(固定值)
- α⃗ “文档-主题”分布的超参数(K维向量,如果对称(symmetric)参数,则是一个标量)
- β⃗ “主题-词项”分布的超参数(V维向量,如果对称参数,则是一个标量)
- Θ是所有文档的“文档-主题”分布(M×K维矩阵)
- Φ是所有主题的“主题-词项”分布(K×V维矩阵)
- ϑ⃗ m对于文档m的主题分布参数标记p(z|d=m),每篇文档均不同,Θ={ϑ⃗ m}Mm=1是一个M×K矩阵
- φ⃗ m对于主题k的词项分布参数标记p(t|z=k),每个主题均不同,Φ=φ⃗ kKk=1是一个K×V矩阵
- Nm文档m的长度,这里由Poisson分布决定
- zm,n文档m中第n个词所属的主题
- wm,n文档m中第n个词的词项
根据概率图,整个样本集合的生成过程如下:
- 对所有的主题k∈[1,K](即生成ΦK×N,K个主题,对应词表V共有N个词):
- 生成K个主题的“主题-词项”分布φ⃗ k∼Dir(β⃗ )(N维矩阵,对应词表V中的每个词项的概率)
- 对所有的文档m∈[1,M]:
- 生成当前文档m相应的“文档-主题”分布ϑ⃗ m∼Dir(α⃗ ) (K维向量,即第m篇文档对应的每个主题的概率)
- 生成当前文档m的长度Nm∼Poiss(ξ)
- 对当前文档m中的所有词n∈[1,Nm]:
- 生成当前位置的词的所属主题zm,n∼Mult(ϑ⃗ m)
- 根据之前生成的主题分布ΦK×N,生成当前位置的词的相应词项wm,n∼Mult(φ⃗ zm,n)
上述过程可以分解为
- α⃗ →θ⃗ m→zm,n, 这个过程表示在生成第m篇文档的时候,先从“文档-主题”分布ϑ⃗ m中选出第n个词的topic编号zm,n;
- β⃗ →φ⃗ k→wm,n|k=zm,n, 这个过程表示用如下动作生成语料中第m篇文档的第n个词:在上帝手头的K个“主题-词项”分布ΦK×N中,挑选主题为k=zm,n的那个φ⃗ zm,n分布生成 wm,n;
理解 LDA最重要的就是理解这两个物理过程。 LDA 模型在基于K个 topic 生成语料中的M篇文档的过程中, 由于是 bag-of-words模型,有一些物理过程是相互独立可交换的。由此, LDA 生成模型中,M篇文档会对应于M个独立的 Dirichlet-Multinomial 共轭结构;K个 topic 会对应于 K 个独立的Dirichlet-Multinomial共轭结构。所以理解LDA所需要的所有数学就是理解Dirichlet-Multiomail共轭,其它都就是理解物理过程。现在我们进入细节, 来看看 LDA 模型是如何被分解为 M+K 个Dirichlet-Multinomial 共轭结构的。
由第一个物理过程,我们知道 α⃗ →θ⃗ m→zm,n 表示生成第 m 篇文档中的所有词对应的topics,显然 α⃗ →θ⃗ m 对应于 Dirichlet 分布, θ⃗ m→zm,n 对应于 Multinomial 分布, 所以整体是一个 Dirichlet-Multinomial 共轭结构;
p(z⃗ m|α⃗ )=∫p(z⃗ m|θ⃗ m)p(θ⃗ m|α⃗ )dθ⃗ m=∫∏k=1VpnkkDir(θ⃗ m|α⃗ )dθ⃗ m=∫∏k=1Vpnkk1Δ(α⃗ )∏k=1Vpαk−1kdp⃗ =1Δ(α⃗ )∫∏k=1Vpnk+αk−1kdp⃗ =Δ(n⃗ m+α⃗ )Δ(α⃗ )
其中
n⃗ m=(n(1)m,⋯,n(K)m) 表示第
m 篇文档中第
k 个topic 产生的词的个数。由于语料中
M 篇文档的 topics 生成过程相互独立,所以我们得到
M 个相互独立的 Dirichlet-Multinomial 共轭结构,从而我们可以得到整个语料中 topics 生成概率
p(z⃗ |α⃗ )=∏m=1Mp(z⃗ m|α⃗ )=∏m=1MΔ(n⃗ m+α⃗ )Δ(α⃗ )
目前为止,我们由 M 篇文档得到了 M 个 Dirichlet-Multinomial 共轭结构,还有额外 K 个 Dirichlet-Multinomial共轭结构在哪儿呢?为了形象话说明LDA生成文档的过程,我们认为假设文档是通过抛骰子生成的。在上帝按照之前的规则玩 LDA 游戏的时候,上帝是先完全处理完成一篇文档,再处理下一篇文档。文档中每个词的生成都要抛两次骰子,第一次抛一个doc-topic骰子得到 topic, 第二次抛一个topic-word骰子得到 word,每次生成每篇文档中的一个词的时候这两次抛骰子的动作是紧邻轮换进行的。如果语料中一共有 N 个词,则上帝一共要抛 2N次骰子,轮换的抛doc-topic骰子和 topic-word骰子。但实际上有一些抛骰子的顺序是可以交换的,我们可以等价的调整2N次抛骰子的次序:前N次只抛doc-topic骰子得到语料中所有词的 topics,然后基于得到的每个词的 topic 编号,后N次只抛topic-word骰子生成 N 个word。于是上帝在玩 LDA 游戏的时候,可以等价的按照如下过程进行:
- 上帝有两个大坛子的骰子,第一个坛子装的是doc-topic骰子,第二个坛子装的是topic-word骰子。
- 上帝随机从第二坛子中独立选取 K 个topic-word骰子,编号1到K。
- 每次生成一篇新文档前,上帝先从第一个坛子中随机抽取一个doc-topic骰子, 然后重复投掷这个doc-topic骰子,为每个词生成一个topic编号z。重复如上过程处理每篇文档,为每篇文档每个词生成topic编号,但是词还未生成。
- 从头到尾,对语聊中每篇文档的每个topic编号z,选择 K 个topic-word骰子中编号为z的那个,投掷这个骰子,于是生成对应的词语,直到生成完所有词语。
以上游戏是先生成了语料中所有词的 topic, 然后对每个词在给定 topic 的条件下生成 word。在语料中所有词的 topic 已经生成的条件下,任何两个 word 的生成动作都是可交换的。于是我们把语料中的词进行交换,把具有相同 topic 的词放在一起
w⃗ ′z⃗ ′=(w⃗ (1),⋯,w⃗ (K))=(z⃗ (1),⋯,z⃗ (K))
其中,
w⃗ (k) 表示这些词都是由第 k 个 topic 生成的,
z⃗ (k) 对应于这些词的 topic 编号,所以
z⃗ (k)中的分量都是k。
对应于概率图中的第二个物理过程 β⃗ →φ⃗ k→wm,n|k=zm,n,在 k=zm,n 的限制下,语料中任何两个由 topic k 生成的词都是可交换的,即便他们不再同一个文档中,所以我们此处不再考虑文档的概念,转而考虑由同一个 topic 生成的词。考虑如下过程 β⃗ →φ⃗ k→w(k) ,容易看出, 此时 β⃗ →φ⃗ k 对应于 Dirichlet 分布, φ⃗ k→w(k) 对应于 Multinomial 分布, 所以整体也还是一个 Dirichlet-Multinomial 共轭结构;
同样的,我们可以得到
p(w⃗ (k)|β⃗ )=Δ(n⃗ k+β⃗ )Δ(β⃗ )
其中
n⃗ k=(n(1)k,⋯,n(V)k) 表示中第
k 个topic 产生的词中 word
t的个数。而语料中
K 个 topics 生成words 的过程相互独立,所以我们得到
K 个相互独立的 Dirichlet-Multinomial 共轭结构,从而我们可以得到整个语料中词生成概率
p(w⃗ |z⃗ ,β⃗ )=p(w⃗ ′|z⃗ ′,β⃗ )=∏k=1Kp(w⃗ (k)|z⃗ (k),β⃗ )=∏k=1KΔ(n⃗ k+β⃗ )Δ(β⃗ )
因此我们可以得到联合概率分布p(w⃗ ,z⃗ ):
p(w⃗ ,z⃗ |α⃗ ,β⃗ )=p(w⃗ |z⃗ ,β⃗ )p(z⃗ |α⃗ )=∏k=1KΔ(n⃗ k+β⃗ )Δ(β⃗ )∏m=1MΔ(n⃗ m+α⃗ )Δ(α⃗ )
因此,由该生成过程可知,第 m 篇文档中第 n 个词 t 的生成概率:
p(wm,n=t|ϑ⃗ m,Φ)=∑k=1Kp(wm,n=t|φ⃗ k)p(zm,n=k|ϑ⃗ m)
LDA Gibbs Sampler
有了联合分布p(w⃗ ,z⃗ ), 万能的 MCMC 算法就可以发挥作用了!于是我们可以考虑使用 Gibbs Sampling 算法对这个分布进行采样。通常均匀分布Uniform(0,1)的样本,即我们熟悉的类rand()函数,可以由线性同余发生器生成;而其他的随机分布都可以在均匀分布的基础上,通过某种函数变换得到,比如,正态分布可以通过Box-Muller变换得到。然而,这种变换依赖于计算目标分布的积分的反函数,当目标分布的形式很复杂,或者是高维分布时,很难简单变换得到,而随机模拟(MCMC)就是求解近似解的一种强有力的方法。随机模拟的核心就是对一个分布进行抽样(Sampling),更多关于随机抽样可以参考这篇博客。
当然由于 w⃗ 是观测到的已知数据,只有 z⃗ 是隐含的变量,所以我们真正需要采样的是分布 p(z⃗ |w⃗ )。语料库 w⃗ 中的第i个词我们记为wi, 其中i=(m,n)是一个二维下标,对应于第m篇文档的第 n个词,我们用 ¬i 表示去除下标为i的词。那么按照 Gibbs Sampling 算法的要求,我们要求得任一个坐标轴 i 对应的条件分布 p(zi=k|z⃗ ¬i,w⃗ ) 。假设已经观测到的词 wi=t, 则由贝叶斯法则,我们容易得到
p(zi=k|z⃗ ¬i,w⃗ )∝p(zi=k,wi=t|z⃗ ¬i,w⃗ ¬i)
由于
zi=k,wi=t 只涉及到第 m 篇文档和第 k 个 topic,所以上式的条件概率计算中, 实际上也只会涉及到如下两个Dirichlet-Multinomial 共轭结构
1.
α⃗ →θ⃗ m→zm,n,
2.
β⃗ →φ⃗ k→wm,n|k=zm,n,
其它的 M+K-2 个 Dirichlet-Multinomial 共轭结构和
zi=k,wi=t是独立的。因此语料去掉第 i 个词对应的
(zi,wi),并不改变我们之前讨论的 M+K 个 Dirichlet-Multinomial 共轭结构,只是某些地方的计数会减少。所以
θ⃗ m,φ⃗ k 的后验分布都是 Dirichlet:
p(θ⃗ m|z⃗ ¬i,w⃗ ¬i)p(φ⃗ k|z⃗ ¬i,w⃗ ¬i)=Dir(θ⃗ m|n⃗ m,¬i+α⃗ )=Dir(φ⃗ k|n⃗ k,¬i+β⃗ )
使用上面两个式子,把以上想法综合一下,我们就得到了如下的 Gibbs Sampling 公式的推导
p(zi=k|z⃗ ¬i,w⃗ )∝p(zi=k,wi=t|z⃗ ¬i,w⃗ ¬i)=∫p(zi=k,wi=t,θ⃗ m,φ⃗ k|z⃗ ¬i,w⃗ ¬i)dθ⃗ mdφ⃗ k=∫p(zi=k,θ⃗ m|z⃗ ¬i,w⃗ ¬i)⋅p(wi=t,φ⃗ k|z⃗ ¬i,w⃗ ¬i)dθ⃗ mdφ⃗ k=∫p(zi=k|θ⃗ m)p(θ⃗ m|z⃗ ¬i,w⃗ ¬i)⋅p(wi=t|φ⃗ k)p(φ⃗ k|z⃗ ¬i,w⃗ ¬i)dθ⃗ mdφ⃗ k=∫p(zi=k|θ⃗ m)Dir(θ⃗ m|n⃗ m,¬i+α⃗ )dθ⃗ m⋅∫p(wi=t|φ⃗ k)Dir(φ⃗ k|n⃗ k,¬i+β⃗ )dφ⃗ k=∫θmkDir(θ⃗ m|n⃗ m,¬i+α⃗ )dθ⃗ m⋅∫φktDir(φ⃗ k|n⃗ k,¬i+β⃗ )dφ⃗ k=E(θmk)⋅E(φkt)=θ^mk⋅φ^kt
zi=k,wi=t的概率只和两个 Dirichlet-Multinomial 共轭结构关联。而最终得到的 θ^mk, φ^kt 就是对应的两个 Dirichlet 后验分布在贝叶斯框架下的参数估计。借助于前面介绍的Dirichlet 参数估计的公式 ,我们有
θ^mkφ^kt=n(k)m,¬i+αk∑Kk=1(n(k)m,¬i+αk)=n(t)k,¬i+βt∑Vt=1(n(t)k,¬i+βt)(1)(2)
于是,我们最终得到了 LDA 模型的 Gibbs Sampling 公式
p(zi=k|z⃗ ¬i,w⃗ )∝n(k)m,¬i+αk∑Kk=1(n(k)m,¬i+αk)⋅n(t)k,¬i+βt∑Vt=1(n(t)k,¬i+βt)(3)
Training
有了 LDA 模型,当然我们的目标有两个
- 估计模型中的参数 φ⃗ 1,⋯,φ⃗ K 和 θ⃗ 1,⋯,θ⃗ K
- 对于新来的一篇文档 docnew,我们能够计算这篇文档的 topic 分布 θ⃗ new。
有了 Gibbs Sampling 公式, 我们就可以基于语料训练 LDA 模型,并应用训练得到的模型对新的文档进行 topic 语义分析。训练的过程就是获取语料中的 (z,w) 的样本,而模型中的所有的参数都可以基于最终采样得到的样本进行估计。统计量n(z)m和n(t)z分别是M×K和K×V矩阵,它们每行的和分别是M维向量nm(文档长度)和K维向量nk。Gibbs sampling算法有三个阶段:初始化、burn-in和sampling。具体算法如下:
- 算法:LdaGibbs(w⃗ ,α,β,K)
- 输入:单词向量w⃗ ,超参数α和β,主题数K
- 全局变量:统计量n(k)m、n(t)k,以及它们的总数nm、nk,全部条件概率数组p(zi|⋅)
- 输出:主题向量z⃗ ,多项分布参数Φ和Θ,超参数估计量α和β
[随机初始化]
- 设置全局变量n(k)m、n(t)k、nm、nk为零
- 对所有文档 m∈[1,M]:
- 对文档 m 中的所有单词 n∈[1,Nm]:
- 随机初始化每个单词对应的主题zm,n=k∼Mult(1/K)
- 增加“文档-主题”计数:n(k)m+=1
- 增加“文档-主题”总数:nm+=1
- 增加“主题-词项”计数:n(t)k+=1
- 增加“主题-词项”总数:nk+=1
[迭代下面的步骤,直到Markov链收敛]
- 对所有文档 m∈[1,M]:
- 对文档 m 中的所有单词 m∈[1,M]:
- 删除该单词的主题计数:n(k)m−=1;nm−=1;n(t)k−=1;nk−=1;
- 根据公式(3)采样出该单词的新主题:k~∼p(zi|z⃗ ¬i,w⃗ )
- 增加该单词的新主题计数:n(k)m+=1;nm+=1;n(t)k+=1;nk+=1;
- 如果Markov链收敛:
- 根据公式(1)生成主题-词项分布 Φ
- 根据公式(2)生成文档-主题分布 Θ
由这个topic-word 频率矩阵我们可以计算每一个p(word|topic)概率,从而算出模型参数φ⃗ 1,⋯,φ⃗ K, 这就是上帝用的 K 个 topic-word 骰子。当然,语料中的文档对应的骰子参数 θ⃗ 1,⋯,θ⃗ M, 在以上训练过程中也是可以计算出来的,只要在 Gibbs Sampling 收敛之后,统计每篇文档中的 topic 的频率分布,我们就可以计算每一个 p(topic|doc) 概率,于是就可以计算出每一个θ⃗ m。由于参数θ⃗ m 是和训练语料中的每篇文档相关的,对于我们理解新的文档并无用处,所以工程上最终存储 LDA 模型时候一般没有必要保留。通常,在 LDA 模型训练的过程中,我们是取 Gibbs Sampling 收敛之后的 n 个迭代的结果进行平均来做参数估计,这样模型质量更高。
Inference
有了 LDA 的模型,对于新来的文档 docnew, 我们如何做该文档的 topic 语义分布的计算呢?基本上 inference 的过程和 training 的过程完全类似。对于新的文档, 我们只要认为 Gibbs Sampling 公式中的 φ^kt 部分是稳定不变的,是由训练语料得到的模型提供的,所以采样过程中我们只要估计该文档的 topic 分布 θ⃗ new 就好了
[随机初始化]
- 设置全局变量n(k)m、nm为零
- 对所有文档 m∈[1,M]:
- 对文档 m 中的所有单词 n∈[1,Nm]:
- 随机初始化每个单词对应的主题zm,n=k∼Mult(1/K)
- 增加“文档-主题”计数:n(k)m+=1
- 增加“文档-主题”总数:nm+=1
[迭代下面的步骤,直到Markov链收敛]
- 对所有文档 m∈[1,M]:
- 对文档 m 中的所有单词 m∈[1,M]:
- 删除该文档的主题计数:n(k)m−=1;nm−=1;
- 通过Training得到的φ^kt和迭代得到的φ^kt,带入公式(3)采样出该文档的新主题:k~∼p(zi|z⃗ ¬i,w⃗ )
- 增加该文档的新主题计数:n(k)m+=1;nm+=1;
- 如果Markov链收敛:
参考资料
- http://www.engr.uvic.ca/~seng474/svd.pdf
- http://blog.jqian.net/post/plsa.html
- http://blog.tomtung.com/2011/10/plsa/
- http://blog.jqian.net/post/lda.html#toc_0