pLSA 浅析

刚读博的时候,就读到过pLSA的文章,当时对里面的概率,分布什么的,一头雾水。三年过去了,整理以往paper又发现当初打印的文章,竟然一下子看懂了。特意整理下,希望为以后看到这个东西的人,有点参考的作用。

PLSA是个从文档中发现topic的算法,它认为文本可以分三个层次来理解。1,文档(d);2,主题(z);3,单词(w),既一个文档包含若干主题,每个主题包含若干单词。从概率层面来讲,这里的包含其实是某种分布。也就是说,一个文档可以看做在一些主题上面的分布(P(z|d),而每个主题看做在单词上面的某种分布(P(w|z))。 pLSA就是对这些分布进行建模。


相信大部分人都可能理解之前的这些内容,关键难点在于求解。其实呢,一切古典概率都是纸老虎,概率,在文本处理里面,本质就是词频。
pLSA模型的目标函数就是使得所有文档单词组合的似然函数最大:

这里就是单词w_i在文档d_j中出现的次数。
问题的解可以用EM算法实现。
首先,对变量初始化。
在E step里面,计算

这里就是求一个文档中的某个单词在某主题下面的分布,一个简单的概率计算,下标省略,注意一致。
在M step,计算

这里求得是在所有文档中一个单词在某个主题下面的概率。
另外一个更新是

这里求的是某文档在主题上面的分布。

关于示例代码,网上很多,比如<a "https:="" blob="" github.com="" href="https://github.com/nokuno/nokuno/blob/master/python/ml/plsa.py" master="" ml="" nokuno="" plsa.py"="" python="">

#!/usr/bin/env python
from random import random
from math import log, exp

def normalize(P):
    return [p / sum(P) for p in P]

# test data
D = [[2,10,0],[1,5,0],[0,0,8],[0,1,9]]
N = len(D)
W = len(D[0])
print 'D = ', D

#initialize
K = 5
Q = [normalize([random() for n in range(N)]) for k in range(K)]
R = [normalize([random() for w in range(W)]) for k in range(K)]
P = normalize([random() for k in range(K)])

print 'Q = ', Q
print 'R = ', R

#iteration
for loop in range(10):
    # e-step
    C = [[normalize([Q[k][w] * R[k][w] * P[k] for k in range(K)]) for w in range(W)] for n in range(N)]

    # m-step
    for k in range(K):
        Q[k] = normalize([sum([C[n][w][k] * D[n][w] for w in range(W)]) for n in range(N)])
        R[k] = normalize([sum([C[n][w][k] * D[n][w] for n in range(N)]) for w in range(W)])
    P = normalize([sum(D[n][w] * C[n][w][k] for w in range(W) for n in range(N)) for k in range(K)])

    # log likelihood
    L = sum(D[n][w] * log(sum(Q[k][n] * R[k][w] for k in range(K))) for n in range(N) for w in range(W))
    print 'L = ', L

 

 

posted on 2012-08-01 02:28  xueliangliu  阅读(1799)  评论(0编辑  收藏  举报

导航