无监督学习 · 06

潜在语义分析与非负矩阵分解

词袋模型太稀疏、太表面。LSA 用截断 SVD 从共现统计里「压」出话题;NMF 加一条非负约束,让话题变得可解释。两种矩阵分解,两种看文本的方式。

14 min read

从词袋到话题

文本分析的第一步通常是把文档变成向量。最朴素的做法是词袋模型(Bag of Words):建一张词表,大小为 mm;有 nn 篇文档;构造一个 m×nm \times n词-文档矩阵 XX,其中 XijX_{ij} 表示第 ii 个词在第 jj 篇文档中出现的频次(或 TF-IDF 权重)。

这个矩阵有两个致命问题:

  1. 极度稀疏。词表通常几万甚至几十万,但一篇文档只用几百个词。XX 里绝大多数元素是零。
  2. 语义缺失。"汽车"和"轿车"是不同的行,在 XX 里完全正交——但它们语义几乎相同。反过来,"苹果"一个词对应水果和公司两种含义,在 XX 里却只有一行。

问题的根源在于:词袋模型工作在单词向量空间mm 维),维度太高,每个维度只对应一个具体的词,没有抽象出「话题」这个概念。

我们需要一种降维方法:把 mm 维的单词空间压到 kk 维的话题向量空间kmk \ll m),使得语义相近的词被映射到相近的方向。这恰好是矩阵分解擅长的事情。

如果你已经读过 SVD 篇,你知道截断 SVD 是最优低秩近似。如果你读过 PCA 篇,你知道降维的关键是保留方差最大的方向。LSA 和 NMF 就是把这些工具用到词-文档矩阵上。

潜在语义分析 (LSA)

潜在语义分析(Latent Semantic Analysis,也叫 LSI——Latent Semantic Indexing)的核心思路极其简单:对词-文档矩阵 XX截断 SVD,用低秩近似来发现隐藏的话题结构。

截断 SVD 回顾

SVD 篇详细介绍了:任意 m×nm \times n 矩阵 XX 都可以精确分解为

X=UΣVX = U \Sigma V^\top

其中 URm×mU \in \mathbb{R}^{m \times m} 正交,Σ\Sigma 是奇异值对角矩阵(σ1σ2\sigma_1 \geq \sigma_2 \geq \cdots),VRn×nV \in \mathbb{R}^{n \times n} 正交。

截断 SVD 只保留前 kk 个最大的奇异值:

XXk=UkΣkVkX \approx X_k = U_k \Sigma_k V_k^\top

其中 UkRm×kU_k \in \mathbb{R}^{m \times k}ΣkRk×k\Sigma_k \in \mathbb{R}^{k \times k}VkRn×kV_k \in \mathbb{R}^{n \times k}。根据 Eckart-Young 定理,这是 Frobenius 范数下最优的秩-kk 近似

LSA 的语义解读

把截断 SVD 的三个矩阵放到文本语境下:

  • UkU_km×km \times k):每一行是一个词的 kk 维话题表示。语义相近的词(如"机器"和"算法")在这个空间里方向接近。
  • VkV_kn×kn \times k):每一行是一个文档的 kk 维话题表示。内容相似的文档被映射到相近的位置。
  • Σk\Sigma_kk×kk \times k):对角线上的奇异值表示每个话题的「强度」。σ1\sigma_1 最大,对应最主要的话题维度。

几何意义很清楚:原来 mm 维的单词空间里,每个词是一个极度稀疏的 one-hot 向量;经过 LSA 之后,每个词变成了一个稠密的 kk 维向量,坐标的含义是「这个词在各个话题上的参与度」。

LSA 的计算流程

  1. 构造词-文档矩阵 XX(通常用 TF-IDF 加权而非原始频次)
  2. XX 做截断 SVD,取前 kk 个奇异值(kk 通常取 100~300)
  3. UkΣkU_k \Sigma_k 的行向量作为词的表示,用 VkΣkV_k \Sigma_k 的行向量作为文档的表示
  4. 在低维空间里用余弦相似度做检索、分类、聚类

LSA 的局限

  • 分解结果可以是负数UkU_kVkV_k 的元素可正可负。说一个词在某个话题上的参与度是 0.3-0.3——负的参与度很难解释。
  • 话题不可叠加解读。一篇文档不能被理解为"30% 话题A + 70% 话题B",因为有负值搅局。
  • 不能处理多义词。每个词只有一个向量,无法区分"苹果(水果)"和"苹果(公司)"。

第一个问题催生了 NMF;第三个问题后来被 Word2Vec 和 BERT 解决。

非负矩阵分解 (NMF)

非负矩阵分解(Non-negative Matrix Factorization,NMF)只加了一条看似简单的约束——所有元素都不能是负数——但这一条约束带来了质的变化。

基本形式

给定非负矩阵 XR0m×nX \in \mathbb{R}_{\geq 0}^{m \times n},NMF 寻找两个非负矩阵 WR0m×kW \in \mathbb{R}_{\geq 0}^{m \times k}HR0k×nH \in \mathbb{R}_{\geq 0}^{k \times n},使得:

XWHX \approx W H

其中 kk 是话题数,通常 kmin(m,n)k \ll \min(m, n)

和 SVD 的关键区别:WWHH 的所有元素都 0\geq 0

非负约束的意义

这条约束为什么重要?因为它让分解结果有了直觉上的「可加性」解读:

Xijt=1kWitHtjX_{ij} \approx \sum_{t=1}^{k} W_{it} \cdot H_{tj}

每个文档是几个话题的加法叠加(没有减法)。WitW_{it} 是第 ii 个词对第 tt 个话题的贡献强度(非负 = "有多大关系"),HtjH_{tj} 是第 tt 个话题在第 jj 篇文档中的激活程度(非负 = "有多强")。

这就像调鸡尾酒:每杯酒是几种基酒的正比例混合,不存在"减去50ml伏特加"这种操作。你可以直接说:这篇文档 = 40% 体育话题 + 60% 科技话题。LSA 做不到这一点。

直觉总结:

SVD / LSANMF
元素取值可正可负非负
解读话题方向(可以"反向参与")话题强度(纯粹的"有多少")
类比正交坐标系鸡尾酒配方

目标函数

NMF 最常见的两种损失函数:

平方损失(Frobenius 范数)

minW0,  H0XWHF2=i,j(Xij(WH)ij)2\min_{W \geq 0,\; H \geq 0} \|X - WH\|_F^2 = \sum_{i,j} (X_{ij} - (WH)_{ij})^2

KL 散度损失(也叫广义 KL 散度):

minW0,  H0D(XWH)=i,j[XijlogXij(WH)ijXij+(WH)ij]\min_{W \geq 0,\; H \geq 0} D(X \| WH) = \sum_{i,j} \left[ X_{ij} \log \frac{X_{ij}}{(WH)_{ij}} - X_{ij} + (WH)_{ij} \right]

两种损失对应不同的噪声模型:平方损失假设高斯噪声,KL 散度假设泊松噪声。实际中平方损失用得更多。

乘法更新规则

NMF 的优化不是凸问题(WWHH 耦合),没有全局最优的闭式解。Lee & Seung (1999, 2001) 提出了经典的乘法更新规则,简洁优雅:

对于平方损失,更新公式是:

HtjHtj(WX)tj(WWH)tjH_{tj} \leftarrow H_{tj} \cdot \frac{(W^\top X)_{tj}}{(W^\top W H)_{tj}} WitWit(XH)it(WHH)itW_{it} \leftarrow W_{it} \cdot \frac{(X H^\top)_{it}}{(W H H^\top)_{it}}

关键性质:

  • 自动保非负。只要初始值非负,乘法更新(乘一个非负因子)的结果永远非负。不需要额外做投影或裁剪。
  • 单调递减。每一步更新都保证目标函数不增。这个可以严格证明——分子分母的比值恰好对应梯度下降的步长。
  • 收敛到局部最优。由于问题非凸,不同的初始化可能得到不同的结果。

和梯度下降的关系:乘法更新其实是一种缩放梯度下降——用当前值除以分母来自适应调整步长,同时保证非负性。这比普通梯度下降 + ReLU 裁剪更稳定。

交互演示

下面的演示展示了两种分解方式的对比。切换 LSA / NMF 模式,调整话题数 kk,观察分解矩阵和重建误差的变化。注意 NMF 模式下所有矩阵格子都是暖色调(非负),而 LSA 模式可能出现蓝色(负值)。

话题数 k =
X (词-文档)
d1d2d3d4d5机器学习神经网络2.001.003.003.002.01.01.002.002.002.003.00
U_2 (词-话题)
t1t2机器学习神经网络0.4-0.70.70.30.3-0.50.60.4
×
Σ_2
t1t2t1t25.2004.6
×
V_2ᵀ (话题-文档)
d1d2d3d4d5t1t20.20.60.20.60.5-0.40.4-0.40.4-0.6
重建 X̂
d1d2d3d4d5机器学习神经网络1.70.11.6-0.12.90.22.50.22.50.81.30.01.2-0.12.2-0.22.5-0.22.50.2
重建误差 ||X - X̂||_F = 1.54奇异值 [5.2, 4.6, 1.2, 1.0]
LSA 用截断 SVD 提取话题。拖动 k 观察:k 越大,重建误差越小,但小的奇异值贡献有限。

LSA vs NMF 对比

把两种方法放在一起看:

维度LSA(截断 SVD)NMF
数学基础奇异值分解,Eckart-Young 最优性非负矩阵分解,乘法更新
约束正交性(UU=IU^\top U = IVV=IV^\top V = I非负性(W0W \geq 0H0H \geq 0
元素取值实数(可正可负)非负
全局最优是(SVD 是闭式解)否(非凸,局部最优)
可解释性弱——话题方向难以命名强——话题是词的「正叠加」
稀疏性不稀疏(UkU_k, VkV_k 通常稠密)自然稀疏(很多元素接近零)
唯一性唯一(奇异值排序固定)不唯一(依赖初始化)
计算效率高效(有成熟的稀疏 SVD 算法)需迭代,较慢
典型用途信息检索、文档相似度话题建模、文本挖掘、推荐系统

怎么选?

  • 如果你要做检索或降维,关心的是相似度计算的质量,LSA 更合适——它有最优性保证,且计算快。
  • 如果你要做话题发现,想看到"话题1 = 机器 + 学习 + 模型"这样可读的结果,NMF 更合适——非负约束让每个话题自然呈现为一组相关词的组合。
  • 在实际管线中,两者经常和 TF-IDF 加权配合使用。sklearn.decomposition.TruncatedSVDsklearn.decomposition.NMF 都只需要几行代码。

这个想法在前沿里