概率潜在语义分析 Probabilistic Latent Semantic Analysis

1.概率潜在语义分析是利用概率生成模型对文本集合进行话题分析的方法。概率潜在语义分析受潜在语义分析的启发提出两者可以通过矩阵分解关联起来。

给定一个文本集合,通过概率潜在语义分析,可以得到各个文本生成话题的条件概率分布,以及各个话题生成单词的条件概率分布。

概率潜在语义分析的模型有生成模型,以及等价的共现模型。其学习策略是观测数据的极大似然估计,其学习算法是EM算法。

2.生成模型表示文本生成话题,话题生成单词从而得到单词文本共现数据的过程;假设每个文本由一个话题分布决定,每个话题由一个单词分布决定。单词变量www与文本变量ddd是观测变量话题变量zzz是隐变量。生成模型的定义如下:
P(T)=∏(w,d)P(w,d)n(w,d)P ( T ) = \prod _ { ( w , d ) } P ( w , d ) ^ { n ( w , d ) }P(T)=(w,d)P(w,d)n(w,d)
P(w,d)=P(d)P(w∣d)=P(d)∑αP(z∣d)P(w∣z)P ( w , d ) = P ( d ) P ( w | d ) = P ( d ) \sum _ { \alpha } P ( z | d ) P ( w | z )P(w,d)=P(d)P(wd)=P(d)αP(zd)P(wz)
3.共现模型描述文本单词共现数据拥有的模式。共现模型的定义如下:
P(T)=∏(w,d)P(w,d)n(w,d)P ( T ) = \prod _ { ( w , d ) } P ( w , d ) ^ { n ( w , d ) }P(T)=(w,d)P(w,d)n(w,d)
P(w,d)=∑z∈ZP(z)P(w∣z)P(d∣z)P ( w , d ) = \sum _ { z \in Z } P ( z ) P ( w | z ) P ( d | z )P(w,d)=zZP(z)P(wz)P(dz)

4.概率潜在语义分析的模型的参数个数是O(M⋅K+N⋅K)O ( M \cdot K + N \cdot K )O(MK+NK)。现实中K≪MK \ll MKM,所以概率潜在语义分析通过话题对数据进行了更简洁地表示,实现了数据压缩。

5.模型中的概率分布P(w∣d)P ( w | d )P(wd)可以由参数空间中的单纯形表示。MMM维参数空间中,单词单纯形表示所有可能的文本的分布,在其中的话题单纯形表示在KKK个话题定义下的所有可能的文本的分布。话题单纯形是单词单纯形的子集,表示潜在语义空间。

6.概率潜在语义分析的学习通常采用EM算法通过迭代学习模型的参数,P(w∣z)P ( w | z )P(wz)
P(z∣d)P ( z| d )P(zd),而P(d)P(d)Pd可直接统计得出。

import numpy as np
X = [[0,0,1,1,0,0,0,0,0], 
     [0,0,0,0,0,1,0,0,1], 
     [0,1,0,0,0,0,0,1,0], 
     [0,0,0,0,0,0,1,0,1], 
     [1,0,0,0,0,1,0,0,0], 
     [1,1,1,1,1,1,1,1,1], 
     [1,0,1,0,0,0,0,0,0], 
     [0,0,0,0,0,0,1,0,1], 
     [0,0,0,0,0,2,0,0,1], 
     [1,0,1,0,0,0,0,1,0], 
     [0,0,0,1,1,0,0,0,0]]

X = np.asarray(X)
print(X.shape)
X = X.T
print(X.shape)
X
(11, 9)
(9, 11)





array([[0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0],
       [0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0],
       [1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0],
       [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
       [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
       [0, 1, 0, 0, 1, 1, 0, 0, 2, 0, 0],
       [0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0],
       [0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0],
       [0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0]])
class PLSA:
  def __init__(self, K, max_iter):
    self.K = K
    self.max_iter = max_iter

  def fit(self, X):
    n_d, n_w = X.shape
    # P(z|w,d)
    p_z_dw = np.zeros((n_d, n_w, self.K))
    # P(z|d)
    p_z_d = np.random.rand(n_d, self.K)
    # P(w|z)
    p_w_z = np.random.rand(self.K, n_w)
    for i_iter in range(self.max_iter):
      # E step
      for di in range(n_d):
        for wi in range(n_w):
          sum_zk = np.zeros((self.K))
          for zi in range(self.K):
            sum_zk[zi] = p_z_d[di, zi] * p_w_z[zi, wi]
          sum1 = np.sum(sum_zk)
          if sum1 == 0:
            sum1 = 1
          for zi in range(self.K):
            p_z_dw[di, wi, zi] = sum_zk[zi] / sum1
      # M step
      # update P(z|d)
      for di in range(n_d):
        for zi in range(self.K):
          sum1 = 0.
          sum2 = 0.
          for wi in range(n_w):
            sum1 = sum1 + X[di, wi] * p_z_dw[di, wi, zi]
            sum2 = sum2 + X[di, wi]
          if sum2 == 0:
            sum2 = 1
          p_z_d[di, zi] = sum1 / sum2

      # update P(w|z)
      for zi in range(self.K):
        sum2 = np.zeros((n_w))
        for wi in range(n_w):
          for di in range(n_d):
            sum2[wi] = sum2[wi] + X[di, wi] * p_z_dw[di, wi, zi]
        sum1 = np.sum(sum2)
        if sum1 == 0:
          sum1 = 1
          for wi in range(n_w):
            p_w_z[zi, wi] = sum2[wi] / sum1
    return p_w_z, p_z_d
  
# -------------------------------
# TEST
model = PLSA(2, 100)
p_w_z, p_z_d = model.fit(X)
print(p_w_z)
print("------------------------------------")
print(p_z_d)
[[0.83983869 0.71250701 0.45183393 0.33794936 0.19372614 0.57970474
  0.34416528 0.2215177  0.36514242 0.65338927 0.86118584]
 [0.71095039 0.10896351 0.6963845  0.58948003 0.50499094 0.62095904
  0.5042079  0.32303399 0.89803475 0.20741103 0.34065561]]
------------------------------------
[[3.57062081e-01 6.42937919e-01]
 [1.41847888e-10 1.00000000e+00]
 [9.99901702e-01 9.82982252e-05]
 [1.00000000e+00 6.23592304e-12]
 [1.00000000e+00 2.28213037e-14]
 [2.69885196e-01 7.30114804e-01]
 [9.56664699e-15 1.00000000e+00]
 [9.91792827e-01 8.20717330e-03]
 [4.00565093e-01 5.99434907e-01]]

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐