LDA主题聚类

LDA(Latent Dirichlet Allocation)学习笔记

最近在看LDA算法,经过了几天挣扎,总算大致了解了这个算法的整体框架和流程。

示例

LDA要干的事情简单来说就是为一堆文档进行聚类(所以是非监督学习),一种topic就是一类,要聚成的topic数目是事先指定的。聚类的结果是一个概率,而不是布尔型的100%属于某个类。国外有个博客[1]上有一个清晰的例子,直接引用:

Suppose you have the following set of sentences:

  • I like to eat broccoli and bananas.
  • I ate a banana and spinach smoothie for breakfast.
  • Chinchillas and kittens are cute.
  • My sister adopted a kitten yesterday.
  • Look at this cute hamster munching on a piece of broccoli.

What is latent Dirichlet allocation? It’s a way of automatically discovering topics that these sentences contain. For example, given these sentences and asked for 2 topics, LDA might produce something like

  • Sentences 1 and 2: 100% Topic A
  • Sentences 3 and 4: 100% Topic B
  • Sentence 5: 60% Topic A, 40% Topic B
  • Topic A: 30% broccoli, 15% bananas, 10% breakfast, 10% munching, … (at which point, you could interpret topic A to be about food)
  • Topic B: 20% chinchillas, 20% kittens, 20% cute, 15% hamster, … (at which point, you could interpret topic B to be about cute animals)

上面关于sentence 5的结果,可以看出来是一个明显的概率类型的聚类结果(sentence 1和2正好都是100%的确定性结果)。

再看例子里的结果,除了为每句话得出了一个概率的聚类结果,而且对每个Topic,都有代表性的词以及一个比例。以Topic A为例,就是说所有对应到Topic A的词里面,有30%的词是broccoli。在LDA算法中,会把每一个文档中的每一个词对应到一个Topic,所以能算出上面这个比例。这些词为描述这个Topic起了一个很好的指导意义,我想这就是LDA区别于传统文本聚类的优势吧。

LDA整体流程

先定义一些字母的含义:

  • 文档集合D,topic集合T
  • D中每个文档d看作一个单词序列< w1,w2,...,wn >,wi表示第i个单词,设d有n个单词。(LDA里面称之为word bag,实际上每个单词的出现位置对LDA算法无影响)
  • D中涉及的所有不同单词组成一个大集合VOCABULARY(简称VOC)

LDA以文档集合D作为输入(会有切词,去停用词,取词干等常见的预处理,略去不表),希望训练出的两个结果向量(设聚成k个Topic,VOC中共包含m个词):

  • 对每个D中的文档d,对应到不同topic的概率θd < pt1,..., ptk >,其中,pti表示d对应T中第i个topic的概率。计算方法是直观的,pti=nti/n,其中nti表示d中对应第i个topic的词的数目,n是d中所有词的总数。
  • 对每个T中的topic t,生成不同单词的概率φt < pw1,..., pwm >,其中,pwi表示t生成VOC中第i个单词的概率。计算方法同样很直观,pwi=Nwi/N,其中Nwi表示对应到topic t的VOC中第i个单词的数目,N表示所有对应到topic t的单词总数。

LDA的核心公式如下:

p(w|d) = p(w|t)*p(t|d)

扫描二维码关注公众号,回复: 2182073 查看本文章

直观的看这个公式,就是以Topic作为中间层,可以通过当前的θd和φt给出了文档d中出现单词w的概率。其中p(t|d)利用θd计算得到,p(w|t)利用φt计算得到。

实际上,利用当前的θd和φt,我们可以为一个文档中的一个单词计算它对应任意一个Topic时的p(w|d),然后根据这些结果来更新这个词应该对应的topic。然后,如果这个更新改变了这个单词所对应的Topic,就会反过来影响θd和φt

LDA算法开始时,先随机地给θd和φt赋值(对所有的d和t)。然后上述过程不断重复,最终收敛到的结果就是LDA的输出。



训练过程:GibbsSampling

(1)图示:


初始时,随机给文本中的每个单词w分配主题z;然后统计每个主题z下出现term t的数量分布以及每个文档m下主题z 的数量分布;然后排除当前词的主题分配,根据其他所有词的主题分配估计当前词的主题;用同样的方法不断更新下一个词的主题,直至每个文档下主题的分布以及每个主题下词的分布收敛,算法停止;这里的核心是如何根据其他所有词的主题分配估计当前词的主题,也就是gibbs 采样公式;

(2)gibbs采样公式:


其中zi=k表示第i个词的主题为k,i的形式为(m,n),表示第m篇第n个;¬i 表示去除下标为i的词;

(3)理解

        1)概率计算:

对每个D中的文档d,对应到不同Topic的概率θd<pt1,...,ptk>,其中,pti表示d对应T中第i个topic的概率。计算方法是直观的,pti=nti/n,其中nti表示d中对应第i个topic的词的数目,n是d中所有词的总数;

对每个T中的topict,生成不同单词的概率φt<pw1,...,pwm>,其中,pwi表示t生成VOC中第i个单词的概率。计算方法同样很直观,pwi=Nwi/N,其中Nwi表示对应到topic  t的VOC中第i个单词的数目,N表示所有对应到topic  t的单词总数。

       2)训练过程:

步骤1:先随机地给θd和φt赋值(对所有的d和t)

步骤2:pj(wi|ds)=p(wi|tj)*p(tj|ds)

枚举T中的topic,得到所有的pj(wi|ds),其中j取值1~k;然后可以根据这些概率值结果为ds中的第i个单词wi选择一个topic;最简单的想法是取令pj(wi|ds)最大的tj(注意,这个式子里只有j是变量),即argmax[j]pj(wi|ds);

步骤3:然后,如果ds中的第i个单词wi在这里选择了一个与原先不同的topic,就会对θd和φt有影响了(根据前面提到过的这两个向量的计算公式可以很容易知道)。它们的影响又会反过来影响对上面提到的p(w|d)的计算;对D中所有的d中的所有w进行一次p(w|d)的计算并重新选择topic看作一次迭代;这样进行n次循环迭代之后,就会收敛到LDA所需要的结果了;

4.推理过程:训练与推理的步骤几乎一样,都需要gibbs采样,但是由于推理时,已知topic下word的分布,因此每次迭代只更新文档下topic的分布,迭代速度是比训练快很多的;

5.效果评估(越小越好)

https://blog.csdn.net/zhazhiqiang/article/details/21186353

https://blog.csdn.net/dream_catcher_10/article/details/50812371



猜你喜欢

转载自blog.csdn.net/hlang8160/article/details/80957049
今日推荐