查看全课大纲(第 30 / 69 节)
- 1.NLP 的研究领域、应用与学习路径
- 2.自然语言的基本术语
- 3.信息论基础:信息熵与交叉熵
- 4.语言的进化与语义变迁
- 5.主观概率、客观概率与条件概率
- 6.贝叶斯原理与推理
- 7.随机变量:二项式、期望方差与联合概率
- 8.常见概率分布
- 9.辛普森悖论与贝叶斯解题实例
- 10.语言模型:语言概率与词袋模型
- 11.n-gram 语言模型(二元 / 三元 / N-Gram)
- 12.语言模型评价:交叉熵、困惑度与插值
- 13.朴素贝叶斯文本分类:垃圾邮件
- 14.拼写检查
- 15.中文分词:构词法、最大匹配、最优路径与 Jieba
- 16.词表示问题与语义相似度
- 17.TF-IDF 权重处理
- 18.One-Hot 表达与词表示的局限
- 19.Word2Vec 核心思想
- 20.Word2Vec 训练过程
- 21.Skip-gram 模型详解
- 22.词性标注任务与标注方法(规则 + N-Gram)
- 23.EM 算法与混合模型
- 24.高斯混合模型 GMM
- 25.从混合模型到隐马尔可夫模型
- 26.隐马尔可夫模型(HMM)推导与维特比解码
- 27.线性链条件随机场 CRF
- 28.贝叶斯网络与图模型
- 29.隐马尔可夫链与 HMM 推导
- 30.PLSA 主题模型
- 31.LSI 与 SVD 向量表达
- 32.LDA 与狄利克雷分布
- 33.主题模型实验复现(困惑度 / 分类 / 相似度 / 延展)
- 34.上下文无关文法(CFG)与句法分析
- 35.概率上下文无关文法 PCFG
- 36.统计机器翻译:词对齐与翻译模型
- 37.统计机器翻译中的对齐模型与参数估计
- 38.从统计机器翻译到神经机器翻译
- 39.神经元与反向传播速览(指向深度学习课)
- 40.CNN 原理及其在 NLP 中的应用
- 41.循环神经网络的基本原理与 Elman / Jordan 网络
- 42.LSTM:长短期记忆网络的核心思想与分步实现
- 43.Encoder-Decoder 框架
- 44.Seq2Seq 与早期注意力机制
- 45.注意力机制的背景与动机
- 46.注意力模型实现原理与匹配函数
- 47.记忆网络:组成与计算
- 48.注意力机制的应用与历史延展
- 49.Transformer 结构:Encoder-Decoder 栈与 Self-Attention
- 50.Multi-Head Attention、FFNN 与位置编码
- 51.层归一化、损失函数与 Universal Transformer 延展
- 52.预训练范式:从 ELMo 到 BERT
- 53.BERT 与掩码语言模型
- 54.BERT 下游任务微调与 GLUE 口径
- 55.GPT 与自回归语言建模
- 56.GPT-1 到 GPT-4 的演进
- 57.指令微调与 RLHF
- 58.分词器:BPE、WordPiece 与中文词表
- 59.上下文窗口与长文本处理
- 60.能力边界、成本与适用场景
- 61.文本分类实战:从朴素贝叶斯到逻辑回归
- 62.命名实体识别实战
- 63.文本生成与摘要实战
- 64.语义检索与向量库实战
- 65.RAG 知识库问答
- 66.NLP 评估指标:BLEU / ROUGE / BERTScore 与人工评估
- 67.幻觉与事实性问题
- 68.文本与知识结合(知识图谱压缩)
- 69.跨媒体信息检索与未来展望
PLSA 主题模型
小象实战讲义 · 自然语言处理
在掌握了隐马尔可夫模型(HMM)和期望最大化(EM)算法等概率图模型基础后,我们正式进入主题模型(Topic Model)的世界。主题模型旨在从大量文本中自动发现其隐含的“主题”结构,是文本挖掘、信息检索和自然语言理解的核心技术之一。本节将首先回顾经典的潜在语义分析(LSA),然后深入其概率化版本——概率潜在语义分析(PLSA),理解其如何将矩阵分解转化为概率生成模型,为后续学习更强大的主题模型(如 LDA)奠定坚实基础。
💡 核心导读
- 从矩阵到概率:理解如何将文档-词矩阵的奇异值分解(SVD)转化为概率模型,引入“主题”作为隐含变量。
- PLSA 的生成过程:掌握 PLSA 的核心假设——文档由多个主题混合而成,而每个主题是词的概率分布。
- 模型表示与似然:学习 PLSA 的图模型表示(盘式记法)及其联合概率与似然函数的数学形式。
- 与 LSA 的关联:明确 PLSA 作为 LSA 的概率化扩展,其优势在于提供了清晰的概率解释。
- 通向现代模型:认识 PLSA 作为经典主题模型的承上启下作用,了解其局限性及后续发展。
从潜在语义分析(LSA)到概率模型
在深入 PLSA 之前,我们必须回顾其前身——潜在语义分析(Latent Semantic Analysis, LSA),有时也称为潜在语义索引(LSI)。其核心思想源于线性代数中的矩阵分解。
文档-词矩阵与 SVD
我们处理文本集合时,首先构建一个 文档-词矩阵(Term-Document Matrix)。假设我们有 M 篇文档和 N 个不同的词(词汇表大小)。这个矩阵 X 的维度是 N x M,其中元素 X[i, j] 表示词 i 在文档 j 中出现的次数(或经过 TF-IDF 加权的值)。
# 示例:一个极小的文档-词矩阵 (N=4个词, M=3篇文档)
import numpy as np
# 词汇表: ['计算机', '算法', '圣经', '祈祷']
# 文档: D1 (科技), D2 (科技), D3 (宗教)
term_doc_matrix = np.array([
[5, 4, 0], # '计算机'
[3, 6, 1], # '算法' (在D3中出现1次,可能是个例或歧义)
[0, 0, 7], # '圣经'
[0, 0, 5], # '祈祷'
], dtype=float)
print("文档-词矩阵 (词 x 文档):")
print(term_doc_matrix)
print(f"矩阵形状: {term_doc_matrix.shape} (N={term_doc_matrix.shape[0]}, M={term_doc_matrix.shape[1]})")文档-词矩阵 (词 x 文档):
[[5. 4. 0.]
[3. 6. 1.]
[0. 0. 7.]
[0. 0. 5.]]
矩阵形状: (4, 3) (N=4, M=3)LSA 的核心是对这个矩阵 X 进行 奇异值分解(Singular Value Decomposition, SVD): 其中:
- 是
N x K矩阵,每一列可以理解为与“词”相关的潜在语义维度(左奇异向量)。 - 是
K x K对角矩阵,对角线上的奇异值表示对应潜在维度的重要性。 - 是
K x M矩阵,每一行可以理解为与“文档”相关的潜在语义维度(右奇异向量的转置)。 - 是选取的潜在维度数(主题数),通常 。
# —— 重新构建上文用到的微型数据(本节各代码块相互独立,可单独运行)
import numpy as np
term_doc_matrix = np.array([
[5, 4, 0], # '计算机'
[3, 6, 1], # '算法' (在D3中出现1次,可能是个例或歧义)
[0, 0, 7], # '圣经'
[0, 0, 5], # '祈祷'
], dtype=float)
# 对上述矩阵进行 SVD 分解(仅作演示,实际中K=min(N,M))
U, S, Vt = np.linalg.svd(term_doc_matrix, full_matrices=False)
K = S.shape[0]
print(f"\nSVD 分解结果:")
print(f"U 形状: {U.shape}")
print(f"S (奇异值): {S}")
print(f"Vt 形状: {Vt.shape}")
print(f"潜在维度 K = {K}")
# 假设我们只保留前2个最重要的维度 (K' = 2)
K_prime = 2
U_reduced = U[:, :K_prime]
S_reduced = np.diag(S[:K_prime])
Vt_reduced = Vt[:K_prime, :]
print(f"\n保留前{K_prime}个主题后的压缩表示:")
print(f"U_k' 形状: {U_reduced.shape}")
print(f"S_k' 形状: {S_reduced.shape}")
print(f"Vt_k' 形状: {Vt_reduced.shape}")
# 重建近似矩阵
X_approx = U_reduced @ S_reduced @ Vt_reduced
print(f"\n原始矩阵 X:\n{term_doc_matrix}")
print(f"\n近似重建矩阵 X_approx:\n{X_approx}")
SVD 分解结果:
U 形状: (4, 3)
S (奇异值): [9.2728253 8.43163808 1.98045204]
Vt 形状: (3, 3)
潜在维度 K = 3
保留前2个主题后的压缩表示:
U_k' 形状: (4, 2)
S_k' 形状: (2, 2)
Vt_k' 形状: (2, 3)
原始矩阵 X:
[[5. 4. 0.]
[3. 6. 1.]
[0. 0. 7.]
[0. 0. 5.]]
近似重建矩阵 X_approx:
[[ 3.87984945 4.88881384 -0.02775031]
[ 4.06494177 5.15499306 1.02638258]
[-0.10637593 0.08440687 6.99736467]
[-0.07598281 0.06029062 4.99811762]]通过 SVD,我们将高维(N 维)的文档向量(矩阵的列)映射到了低维(K' 维)的潜在语义空间(由 的行表示)。在这个空间中,语义相似的文档(如 D1 和 D2)距离会更近,语义不同的文档(如 D1 和 D3)距离会更远。这解决了 词项匹配中的同义词和多义词问题,因为潜在维度捕获了词与词、文档与文档之间更深层的关联。
然而,LSA/SVD 是纯粹的线性代数方法,缺乏概率解释。我们无法将奇异向量直接解释为“文档属于某个主题的概率”或“主题下词的概率分布”。
概率潜在语义分析(PLSA)
为了给潜在语义分析提供一个稳固的概率基础,Hofmann 于 1999 年提出了 概率潜在语义分析(Probabilistic Latent Semantic Analysis, PLSA)。
基本思想与生成过程
PLSA 的核心是引入一个隐含的随机变量 ,表示 主题(Topic)。它假设每篇文档 是多个主题的混合,而每个主题 则是一个在词汇表上的多项分布,即定义了每个词 出现的概率。
PLSA 的生成过程可以想象如下:
- 以概率 选择一篇文档 。
- 对于文档 中的每一个词的位置: a. 根据条件分布 选择一个主题 。 b. 在给定主题 的条件下,根据分布 生成一个词 。
这一过程隐含一条条件独立假设:在给定主题 后,词 与文档 条件独立,即 ,等价于 。正是这条假设把 约简为 ,后面的边缘化求和似然才成立;它是建模假设,不是概率恒等式。
这个过程可以用下面的概率图模型(盘式记法)表示:
|‾‾‾‾‾|
| d | (文档,观察变量,M篇文档)
|_____|
|
| P(z|d)
v
|‾‾‾‾‾|
| z | (主题,隐含变量,K个主题)
|_____|
|
| P(w|z)
v
|‾‾‾‾‾|
| w | (词,观察变量,N个词)
|_____|
重复 N_d 次 (文档d的长度)图:PLSA 的图模型表示。方板(plate)表示重复。d 和 w 是观察到的,z 是隐含的。
联合概率与似然函数
根据上述生成过程,观察到一个词 出现在一篇特定文档 中的联合概率为: 在 PLSA 中, 不是直接统计得到的,而是通过主题 “解释”的: 因此,联合概率可以写为: 其中:
- 是选择文档 的先验概率。
- 是文档 属于主题 的概率(文档-主题分布)。
- 是主题 下生成词 的概率(主题-词分布)。
给定整个语料库,我们观察到的数据是 文档-词共现频率 ,即词 在文档 中出现的次数。PLSA 的模型参数是 。数据的对数似然函数为: 代入 得: 我们的目标是找到参数 以最大化这个对数似然 。
与 LSA 的对比
PLSA 为 LSA 提供了一个明确的概率生成框架:
- LSA:通过 SVD 进行确定性矩阵分解。潜在维度(奇异向量)有正有负,难以直接解释为概率。
- PLSA:通过引入隐含主题变量 ,将文档和词的联系建模为概率混合模型。所有参数 和 都是非负的概率值,具有清晰的解释性。
从模型能力上看,PLSA 可以看作是 LSA 的一种概率化扩展。两者都试图找到文档和词在低维潜在空间中的表示,但 PLSA 的统计基础更牢固,为使用 EM 算法进行参数估计铺平了道路。
LSA (SVD) 视角:
文档d -> 在潜在空间中的向量表示 (Vt中的列) -> 用于计算相似度。
PLSA 视角:
文档d -> 主题分布 P(z|d) (一个K维概率向量) -> 每个主题z -> 词分布 P(w|z)。
文档相似度可以通过比较它们的主题分布 (P(z|d)) 来计算,例如使用 KL 散度或余弦相似度。PLSA 的参数估计与 EM 算法
最大化 PLSA 的对数似然函数没有解析解,因为求和对数内部包含了隐含变量 的求和。这正是 期望最大化(EM)算法 的用武之地。
E步(期望步):在给定当前参数估计 下,计算隐含主题 的后验概率: 这个后验概率表示,对于观察到的 这对共现,其由主题 生成的责任(responsibility)有多大。
M步(最大化步):利用 E 步计算出的后验概率作为权重,更新模型参数以最大化完整数据的期望似然。
- 更新主题-词分布:
- 更新文档-主题分布: 其中 是文档 的总词数。
- 文档先验 通常简单地用文档的相对频率估计:。
重复执行 E 步和 M 步直到对数似然收敛,即可得到 PLSA 的模型参数。
# 注意:以下为 PLSA EM 算法的伪代码示意,用于说明流程。
# 实际应用中,可借助 numpy 等做向量化自行实现 PLSA 的 EM;若使用第三方主题模型库,需确认其明确提供 PLSA/PLSI,而不是 LSI 或 LDA。
print("PLSA EM 算法伪代码流程:")
print("1. 初始化参数:")
print(" - 随机初始化 P(z|d) 和 P(w|z),并确保每行和为1 (概率分布)。")
print("2. 迭代直至收敛:")
print(" 【E步】对每个 (d, w) 对,计算后验 P(z|d, w):")
print(" P(z|d,w) = P_old(w|z) * P_old(z|d) / sum_over_z( P_old(w|z') * P_old(z'|d) )")
print(" 【M步】用后验更新参数:")
print(" P_new(w|z) = sum_over_d[ n(d,w) * P(z|d,w) ] / sum_over_d,w'[ n(d,w') * P(z|d,w') ]")
print(" P_new(z|d) = sum_over_w[ n(d,w) * P(z|d,w) ] / n(d) (文档总词数)")
print("3. 输出: 文档-主题分布 P(z|d) 和 主题-词分布 P(w|z)。")PLSA EM 算法伪代码流程:
1. 初始化参数:
- 随机初始化 P(z|d) 和 P(w|z),并确保每行和为1 (概率分布)。
2. 迭代直至收敛:
【E步】对每个 (d, w) 对,计算后验 P(z|d, w):
P(z|d,w) = P_old(w|z) * P_old(z|d) / sum_over_z( P_old(w|z') * P_old(z'|d) )
【M步】用后验更新参数:
P_new(w|z) = sum_over_d[ n(d,w) * P(z|d,w) ] / sum_over_d,w'[ n(d,w') * P(z|d,w') ]
P_new(z|d) = sum_over_w[ n(d,w) * P(z|d,w) ] / n(d) (文档总词数)
3. 输出: 文档-主题分布 P(z|d) 和 主题-词分布 P(w|z)。📝 动手练一练
- 概念辨析:LSA 和 PLSA 都旨在发现文本的潜在语义结构。请简述它们最根本的区别是什么?PLSA 引入的概率框架带来了哪些优势?
👉 点击查看参考答案
根本区别: LSA 基于线性代数(SVD),是一种确定性的矩阵分解方法。PLSA 则基于统计学,是一种概率生成模型,引入了“主题”作为隐含随机变量。
PLSA 的优势:
- 概率解释:所有输出(文档-主题分布 、主题-词分布 )都是严格的概率值,意义清晰。例如, 可以直接解释为文档 有 70% 的内容关于主题 。
- 统计基础:基于似然最大化,可以自然地融入统计推断框架,并使用 EM 算法进行稳健的参数估计。
- 模型灵活性:为后续更复杂的概率主题模型(如 LDA)提供了直接的建模基础。LDA 可以看作是 PLSA 的贝叶斯版本,通过引入先验分布解决了 PLSA 的一些固有问题(如过拟合)。
- 手算理解:假设一个极简语料库只有 1 篇文档 ,词汇表只有 2 个词 ,且我们设定主题数 。观察到词频为 , 。在 PLSA 的某次 EM 迭代中,当前参数为: 请计算对于共现 ,主题 和 的后验概率 。
👉 点击查看参考答案
根据 E 步公式:
对于 :
- 分母 =
计算结果显示,对于词 ,模型认为它更可能(约 87.1% 的责任)是由主题 生成的,这与参数设定一致( 远高于 )。
本章小结
本节我们深入探讨了概率潜在语义分析(PLSA)模型。我们从其前身 LSA 出发,理解了通过 SVD 对文档-词矩阵进行降维以捕获潜在语义的思想。PLSA 的关键创新在于为这一过程赋予了概率解释,引入了“主题”作为连接文档和词的隐含变量,并定义了一个清晰的生成过程:文档生成主题,主题再生成词。
我们学习了 PLSA 的图模型表示、联合概率与似然函数形式,并了解了其参数如何通过 EM 算法进行估计。与 LSA 相比,PLSA 的优势在于其所有参数都具有概率意义,为文本分析提供了更丰富的解释性工具,例如得到文档的主题构成 和每个主题下的关键词分布 。
PLSA 是主题模型发展史上的重要里程碑,但它也存在局限性,最主要的是其参数 与训练文档直接绑定,导致模型参数数量随文档数量线性增长,容易过拟合,并且难以处理训练集之外的新文档。这直接催生了其贝叶斯扩展——潜在狄利克雷分配(LDA),我们将在下一节中学习。
📋 行动清单
- 在本地尝试用
numpy实现一个简化版的 PLSA EM 算法(例如,固定迭代次数),在小规模人造数据上运行,观察 和 的收敛情况。 - 思考:如果一篇文档明显只讨论一个主题(如“圣经”),PLSA 学出的 应该呈现什么特点?如果一篇文档混合了“科技”和“体育”主题,其 又会如何?
- 预习 LDA,对比其图模型与 PLSA 的差异,理解“狄利克雷先验”在模型中扮演的角色。
—— 小象教研组