⚠️ Alpha内测版本警告:此为早期内部构建版本,尚不完整且可能存在错误,欢迎大家提Issue反馈问题或建议。
Skip to content

第18章 概率潜在语义分析

习题18.1

  证明生成模型与共现模型是等价的。

解答:

解答思路:

  1. 生成模型的定义
  2. 共现模型的定义
  3. 证明生成模型与共现模型是等价的

解答步骤:

第1步:生成模型

  根据书中第18.1.2节的生成模型的定义:

  假设有单词集合W={w1,w2,,wM},其中M是单词个数;文本(指标)集合D={d1,d2,,dN},其中N是文本个数;话题集合Z={z1,z2,,zK},其中K是预先设定的话题个数。随机变量w取值于单词集合;随机变量d取值于文本集合,随机变量z取值于话题集合。概率分布P(d)、条件概率分布P(z|d)、条件概率分布P(w|z)皆属于多项分布,其中P(d)表示生成文本d的概率,P(z|d)表示文本d生成话题z的概率,P(w|z)表示话题z生成单词w的概率。

  每个单词-文本对(w,d)的生成概率由以下公式决定:

(1)P(w,d)=P(d)P(w|d)=P(d)zP(w,z|d)=P(d)zP(z|d)P(w|z)

即生成模型的定义。
  生成模型假设在话题z给定条件下,单词w与文本d条件独立,即

P(w,z|d)=P(z|d)P(w|z)

第2步:共现模型

  根据书中第18.1.3节的共现模型的定义:

  每个单词-文本对(w,d)的概率由以下公式决定:

(2)P(w,d)=zZP(z)P(w|z)P(d|z)

即共现模型的定义。
  共现模型假设在话题z给定条件下,单词w与文本d是条件独立的,即

P(w,d|z)=P(w|z)P(d|z)

第3步:证明生成模型与共现模型是等价的

  结合公式(1)和公式(2),可得:

P(w,d)=P(d)zP(z|d)P(w|z)=zP(w|z)P(z|d)P(d)=zP(w,z|d)P(d)=zP(w,d,z)=zP(z)P(w,d|z)=zP(z)P(w|z)P(d|z)

  可知生成模型与共现模型的概率公式是等价的,故证得生成模型与共现模型是等价的。

习题18.2

  推导共现模型的EM算法。

解答:

解答思路:

  1. EM算法的一般步骤
  2. 推导共现模型的Q函数
  3. 推导共现模型的E步
  4. 推导共现模型的M步
  5. 写出共现模型的EM算法

解答步骤:

第1步:EM算法

  根据书中第18.2节的EM算法介绍:

  EM算法是一种迭代算法,每次迭代包括交替的两步:E步,求期望;M步,求极大。E步是计算Q函数,即完全数据的对数似然函数对不完全数据的条件分布的期望。M步是对Q函数极大化,更新模型参数。详细介绍见第9章。

第2步:推导共现模型的Q函数推导

  设单词集合为W={w1,w2,,wM},文本集合为D={d1,d2,,dN},话题集合为Z={z1,z2,,zK}。给定单词-文本共现数据T={n(wi,dj)},i=1,2,,M, j=1,2,,N,目标是估计概率潜在语义模型(共现模型)的参数。

  根据书中第18.1.3节的共现模型定义:

  文本-单词共现数据T的生成概率为所有单词-文本对(w,d)的生成概率的乘积:

(1)P(T)=(w,d)P(w,d)n(w,d)

每个单词-文本对(w,d)的概率由以下公式决定:

(2)P(w,d)=zZP(z)P(w|z)P(d|z)

即共现模型的定义。

  对公式(1)使用极大似然估计,结合公式(2),对数似然函数是

logP(T)=i=1Mj=1Nn(wi,dj)logP(wi,dj)=i=1Mj=1Nn(wi,dj)log[k=1KP(zk)P(wi|zk)P(dj|zk)]

  由于log函数是上凸函数,可以基于Jessen不等式,得:

i=1Mj=1Nn(wi,dj)log[k=1KP(zk)P(wi|zk)P(dj|zk)]i=1Mj=1Nn(wi,dj)k=1Klog[P(zk)P(wi|zk)P(dj|zk)]

  可以得到Q函数:

Q=EZ[logP(T)|z]=EZ{i=1Mj=1Nn(wi,dj)k=1Klog[P(zk)P(wi|zk)P(dj|zk)]}=i=1Mj=1Nn(wi,dj)EZ{k=1Klog[P(zk)P(wi|zk)P(dj|zk)]}=i=1Mj=1Nn(wi,dj)k=1KP(zk|wi,dj)log[P(zk)P(wi|zk)P(dj|zk)]

第3步:推导共现模型的E步

  根据贝叶斯公式计算

P(zk|wi,dj)=P(zk)P(wi|zk)P(dj|zk)k=1KP(zk)P(wi|zk)P(dj|zk)

第4步:推导共现模型的M步

  通过约束最优化求解Q函数的极大值,这时P(zk)P(wi|zk)P(dj|zk)是变量。因为变量P(zk)P(wi|zk)P(dj|zk)形成概率分布,满足约束条件

k=1KP(zk)=1i=1MP(wi|zk)=1,k=1,2,,Kj=1NP(dj|zk)=1,k=1,2,,K

使用拉格朗日法,引入拉格朗日乘子α,β,γ,定义拉格朗日函数Λ

Λ=Q+α(1k=1KP(zk))+k=1Kβk(1i=1MP(wi|zk))+k=1Kγk(1j=1NP(dj|zk))

将拉格朗日函数Λ分别对P(zk)P(wi|zk)P(dj|zk)求偏导数,并令其等于0,得到下面的方程组

i=1Mj=1Nn(wi,dj)P(zk|wi,dj)αP(zk)=0,k=1,2,,Kj=1Nn(wi,dj)P(zk|wi,dj)βkP(wi|zk)=0,i=1,2,,M;k=1,2,,Ki=1Mn(wi,dj)P(zk|wi,dj)γkP(dj|zk)=0,j=1,2,,N;k=1,2,,K

解方程组得M步的参数估计公式:

p(zk)=i=1Mj=1Nn(wi,dj)P(zk|wi,dj)j=1Nn(dj)p(wi|zk)=j=1Nn(wi,dj)P(zk|wi,dj)m=1Mj=1Nn(wm,dj)P(zk|wm,dj)p(dj|zk)=i=1Mn(wi,dj)P(zk|wi,dj)i=1Ml=1Nn(wi,dl)P(zk|wi,dl)

第5步:共现模型的EM算法

输入:设单词集合为W={w1,w2,,wM},文本集合为D={d1,d2,,dN},话题集合为Z={z1,z2,,zK},共现数据{n(wi,dj)},i=1,2,,M, j=1,2,,N
输出:P(zk)P(wi|zk)P(dj|zk)
(1)设置参数P(zk)P(wi|zk)P(dj|zk)的初始值。
(2)迭代执行以下E步、M步,直到收敛为止。
    E步:

P(zk|wi,dj)=P(zk)P(wi|zk)P(dj|zk)k=1KP(zk)P(wi|zk)P(dj|zk)

    M步:

p(zk)=i=1Mj=1Nn(wi,dj)P(zk|wi,dj)j=1Nn(dj)p(wi|zk)=j=1Nn(wi,dj)P(zk|wi,dj)i=1Mj=1Nn(wi,dj)P(zk|wi,dj)p(dj|zk)=i=1Mn(wi,dj)P(zk|wi,dj)i=1Mj=1Nn(wi,dj)P(zk|wi,dj)

习题18.3

  对以下文本数据集进行概率潜在语义分析。 18-3-Text-Dataset.png

解答:

解答思路:

  1. 给出概率潜在语义模型参数估计的EM算法
  2. 自编程实现概率潜在语义模型参数估计的EM算法
  3. 对文本数据集进行概率潜在语义分析

解答步骤:

第1步:概率潜在语义模型参数估计的EM算法

  根据书中第18章的算法18.1的概率潜在语义模型参数估计的EM算法:

算法18.1(概率潜在语义模型参数估计的EM算法)
输入:设单词集合为W={w1,w2,,wM},文本集合为D={d1,d2,,dN},话题集合为Z={z1,z2,,zK},共现数据{n(wi,dj)},i=1,2,,M, j=1,2,,N
输出:P(wi|zk)P(zk|dj)
(1)设置参数P(wi|zk)P(zk|dj)的初始值。
(2)迭代执行以下E步、M步,直到收敛为止。
    E步:

P(zk|wi,dj)=P(wi|zk)P(zk|dj)k=1KP(wi|zk)P(zk|dj)

    M步:

p(wi|zk)=j=1Nn(wi,dj)P(zk|wi,dj)m=1Mj=1Nn(wm,dj)P(zk|wm,dj)p(dj|zk)=i=1Mn(wi,dj)P(zk|wi,dj)n(dj)

第2步:自编程实现概率潜在语义模型参数估计的EM算法

python
import numpy as np


class EMPlsa:
    def __init__(self, max_iter=100, random_state=2022):
        """
        基于生成模型的EM算法的概率潜在语义模型
        :param max_iter: 最大迭代次数
        :param random_state: 随机种子
        """
        self.max_iter = max_iter
        self.random_state = random_state

    def fit(self, X, K):
        """
        :param X: 单词-文本矩阵
        :param K: 话题个数
        :return: P(w_i|z_k) 和 P(z_k|d_j)
        """
        # M, N分别为单词个数和文本个数
        M, N = X.shape

        # 计算n(d_j)
        n_d = [np.sum(X[:, j]) for j in range(N)]

        # (1)设置参数P(w_i|z_k)和P(z_k|d_j)的初始值
        np.random.seed(self.random_state)
        p_wz = np.random.random((M, K))
        p_zd = np.random.random((K, N))

        # (2)迭代执行E步和M步,直至收敛为止
        for _ in range(self.max_iter):
            # E步
            P = np.zeros((M, N, K))
            for i in range(M):
                for j in range(N):
                    for k in range(K):
                        P[i][j][k] = p_wz[i][k] * p_zd[k][j]
                    P[i][j] /= np.sum(P[i][j])

            # M步
            for k in range(K):
                for i in range(M):
                    p_wz[i][k] = np.sum([X[i][j] * P[i][j][k] for j in range(N)])
                p_wz[:, k] /= np.sum(p_wz[:, k])

            for k in range(K):
                for j in range(N):
                    p_zd[k][j] = np.sum([X[i][j] * P[i][j][k] for i in range(M)]) / n_d[j]

        return p_wz, p_zd

第3步:对文本数据集进行概率潜在语义分析

python
# 输入文本-单词矩阵,共有9个文本,11个单词
X = np.array([[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]])

# 设置精度为3
np.set_printoptions(precision=3, suppress=True)

# 假设话题的个数是3个
k = 3

em_plsa = EMPlsa(max_iter=100)

p_wz, p_zd = em_plsa.fit(X, 3)

print("参数P(w_i|z_k):")
print(p_wz)
print("参数P(z_k|d_j):")
print(p_zd)
参数P(w_i|z_k):
[[0.    0.162 0.   ]
 [0.    0.    0.2  ]
 [0.116 0.081 0.   ]
 [0.115 0.    0.1  ]
 [0.    0.081 0.1  ]
 [0.423 0.271 0.2  ]
 [0.    0.162 0.   ]
 [0.115 0.    0.1  ]
 [0.    0.    0.3  ]
 [0.    0.243 0.   ]
 [0.231 0.    0.   ]]
参数P(z_k|d_j):
[[0.    1.    0.    0.553 1.    0.    1.    0.    0.   ]
 [1.    0.    1.    0.447 0.    0.    0.    1.    0.   ]
 [0.    0.    0.    0.    0.    1.    0.    0.    1.   ]]