假设公司年会要拍一张合影,HR 希望摄影师能一眼分清市场部和研发部。新来的摄影助理只知道把所有人尽量铺满画面,于是他把队伍排得很开,结果两个部门的人还是混在一起。老摄影师却不急着按快门,他先看了一眼工牌,再调整镜头方向,让研发部整体偏左、市场部整体偏右,而且每个部门内部不要拉得太散。LDA 就是这位老摄影师。 LDA 是线性判别分析(Linear Discriminant Analysis)的简称,一种有监督降维方法:先把高维样本投影到一条线或一个低维空间,让不同类别彼此远离、同类尽量聚拢。PCA 不看标签,看重“整张照片的信息量”;LDA 看标签,看重“能不能把两类人分开”。本文会用这个合影故事贯穿始终,带你从散度矩阵讲到 Fisher 准则,最后用代码亲手实现它。
掌握 LDA,你就拥有了在标签引导下做特征提取的经典武器;在人脸识别、文本分类等任务中,它能显著提升分类器效率和可解释性。
可视化演示
本节配有交互动效(进入视口后自动加载,约 3KB)。
背景与动机
年会合影时,新来的摄影助理只顾着“把画面撑满”,于是把所有人都散开,结果照片里红蓝工牌依然交叠,HR 完全分不清谁属于哪个部门。问题出在助理只关注“人有没有铺满画面”,却忽略了每个人胸前的工牌。真实场景中的高维数据也一样:动辄几十、几百甚至上万维的特征,直接送入分类器既慢又容易过拟合,这被称为“维度灾难”。
降维因此成为机器学习里很常见的前置步骤。最经典的无监督方法是 PCA,它只让投影后所有样本的总方差尽可能大。可是“总方差大”不等于“类别分得开”。如果投影方向选得不好,两个部门的人在投影线上依然混在一起,照片再满也没有意义。
LDA 的思路完全不同:它是一个有监督降维方法,输入不仅是样本,还包括每个样本的类别标签。它先把标签当成“工牌”,再计算两个关键指标——类内散度和类间散度,最后寻找一个让“类间尽量远、类内尽量聚”的方向。这正是老摄影师看工牌选机位的数学版本。
核心思想
老摄影师选机位,本质上是在把三维空间里的所有人压缩到一条“排列线”上。只要这条线选得好,研发部自然落在左边,市场部自然落在右边。数学上,这条线的方向用一个向量 \(w\) 表示,每个样本 \(x_i\) 在线上留下的位置是 \(z_i\),这就是投影。
一个好的 \(w\),会让红色工牌对应的 \(z_i\) 整体落在左边,绿色工牌整体落在右边,同时红色内部不要拉得太宽、绿色内部也不要拉得太宽。接下来两节,就是用两个“散度矩阵”把这两个要求写成数学公式。
- 投影向量\(w\) 是 d 维空间里的一个方向向量,相当于摄影师选择的镜头朝向。
- 内积运算把样本 \(x_i\) 与方向 \(w\) 做内积,得到一个标量 \(z_i\)。
- 几何含义所有样本点被压到以 \(w\) 为方向的一维直线上,\(z_i\) 就是它在直线上的位置。
类内散度矩阵
摄影师的第一个要求是“每个部门内部别散开”。研发部如果有人站在会场最左,有人站在会场最右,就算部门均值在中点,拍出来依然和市场部混在一起。于是我们需要一个量,衡量同一类样本围绕自己类中心的聚集程度,这就是类内散度矩阵 \(S_W\),其中 W 代表 Within(内部)。
\(S_W\) 聚合了所有类别内部的离散程度。投影之后,类内散度变成 \(w^{\top} S_W w\),也就是“每个部门内部在照片线上的分散程度之和”。这个值越小,说明同部门的人站得越紧凑。
- 类内均值先算出第 \(i\) 类样本的中心位置,就像圈出红组成员后找到红队的“队形中心”。
- 离差向量每个样本减去本类中心,得到“离队距离”。
- 外积求和把离差向量与它的转置做外积,再对同类所有样本求和,得到矩阵。
类间散度矩阵
第二个要求是“不同部门之间离得越远越好”。拍照时,如果两个部门中心的连线太短,即使内部都很紧凑,照片上仍会挤在一起。类间散度矩阵 \(S_B\) 衡量的是各类中心与全局中心之间的差异,其中 B 代表 Between(之间)。
投影之后,类间散度变成 \(w^{\top} S_B w\),它度量的是“各投影类中心离整体中心有多远”。这个值越大,说明不同部门在照片线上的位置分得越开。
- 全局均值先计算所有人的整体中心。
- 类中心偏差每个部门的中心减去全局中心,得到“部门相对于整体偏了多少”。
- 加权外积用该类的样本数 \(n_i\) 加权,再做外积求和;部门人越多,权重越大。
目标函数与求解
现在老摄影师手里有两把尺子:一把量“部内纪律”,越小越好;一把量“部间距离”,越大越好。能不能把它们合成一个分数,用来比较不同拍摄角度?Fisher 给出了答案:直接用比值。
这个方程的解就是 \(S_W^{-1}S_B\) 的特征向量。由于 \(S_B\) 的秩最多是类别数减一,所以 LDA 真正有判别力的方向最多只有 \(c-1\) 个;二分类时只能得到一条投影线。实际使用中,取最大特征值对应的特征向量,组成投影矩阵。
- 分子\(w^{\top} S_B w\) 是投影后的类间散度,越大代表异类分得越开。
- 分母\(w^{\top} S_W w\) 是投影后的类内散度,越小代表同类聚得越紧。
- 目标找到使比值最大的 \(w\),这就是 Fisher 准则。
- 求导令 \(J(w)\) 对 \(w\) 的导数为零,得到广义特征方程。
LDA降维流程
老摄影师不会只凭感觉按快门,他有一套完整流程:先看清工牌分组,再量内部纪律、量部间距离,最后选机位。机器执行 LDA 时也遵循同样的步骤:计算均值、构造散度矩阵、做特征分解、投影变换。
整个流程可以概括为:先用标签构造 \(S_W\) 和 \(S_B\),再求解广义特征方程,最后用最大特征向量做投影。工程实践中,如果 \(S_W\) 不可逆或样本量太少,通常会加入正则项或先做 PCA 再执行 LDA。
- 组成投影矩阵把前 \(k\) 个最大特征值对应的特征向量按列排成 \(W\)。
- 矩阵乘法原始数据 \(X\) 是 \(N \times d\),乘上 \(W\) 得到降维后的 \(Z\)。
- 维度约束\(k \le c-1\),所以二分类最多降到 1 维,三分类最多降到 2 维。
PCA与LDA对比
摄影助理用的是 PCA 机位:不管工牌,只求画面整体铺得开;老摄影师用的是 LDA 机位:先看工牌,再求部门之间分得开、内部不散架。两者都做线性降维,但目标和输入完全不同。
因此,当任务是探索无标签数据、可视化整体结构时,PCA 更合适;当任务是人脸识别、文本分类等有监督场景时,LDA 往往能提供更强的判别特征。若数据分布复杂或标签噪声较大,LDA 可能会过拟合,此时可以结合 PCA 先降噪,再用 LDA 提取判别方向。
- PCA 的分子\(\Sigma\) 是所有样本共享的协方差矩阵,不出现任何标签。
- PCA 的分母只约束 \(w\) 的长度,本质是“找一个方向让总方差最大”。
- LDA 的分子分母分子用 \(S_B\)、分母用 \(S_W\),每一步都依赖类别标签。
AI 应用场景
人脸识别特征提取
阶段:特征工程 / 特征提取
解决的问题:人脸图像原始像素维度极高,直接做分类计算量大,且光照、角度会引入大量与身份无关的噪声。传统 PCA 只能保留整体像素方差,无法保证同一个人的照片在低维空间靠近。
具体案例:在经典“Fisherfaces”方案中,先用 PCA 把人脸图像压缩到中间维度,再用 LDA 提取判别方向。系统对十几个人的人脸库做特征提取后,每个人的照片都聚成一个“工牌区域”,新样本落在谁的区域就识别为谁。
文本分类前的降维
阶段:数据预处理 / 向量化后处理
解决的问题:文本经过 TF-IDF 或词袋向量化后,特征维度常达到数万维,且大量维度对分类没有贡献。LDA 利用文档类别标签,把高维词向量投影到类别可分性最好的低维空间。
具体案例:在新闻分类系统中,先对训练文档做 TF-IDF,再用 LDA 将 2 万维特征降到类别数减一维,最后交给 SVM 分类。实验显示,特征维度下降几十倍,分类准确率和训练速度都有提升。
Python 演示
import numpy as np class LDA: def __init__(self, n_components=1): self.n_components = n_components self.components_ = None def fit(self, X, y): n_features = X.shape[1] classes = np.unique(y) mean_all = np.mean(X, axis=0) sw = np.zeros((n_features, n_features)) sb = np.zeros((n_features, n_features)) for c in classes: Xc = X[y == c] mean_c = np.mean(Xc, axis=0) sw += (Xc - mean_c).T @ (Xc - mean_c) n_c = Xc.shape[0] diff = (mean_c - mean_all).reshape(-1, 1) sb += n_c * (diff @ diff.T) eig_vals, eig_vecs = np.linalg.eig(np.linalg.pinv(sw) @ sb) idx = np.argsort(eig_vals.real)[::-1] self.components_ = eig_vecs[:, idx[:self.n_components]].real return self def transform(self, X): return X @ self.components_ if __name__ == "__main__": rng = np.random.RandomState(0) mean0 = np.array([0.0, 0.0]) mean1 = np.array([3.0, 1.0]) mean2 = np.array([1.5, 4.0]) cov = np.array([[0.8, 0.1], [0.1, 0.8]]) X0 = rng.multivariate_normal(mean0, cov, 50) X1 = rng.multivariate_normal(mean1, cov, 50) X2 = rng.multivariate_normal(mean2, cov, 50) X = np.vstack([X0, X1, X2]) y = np.array([0] * 50 + [1] * 50 + [2] * 50) lda = LDA(n_components=2).fit(X, y) Z = lda.transform(X) print("LDA transformed shape:", Z.shape) print("Projection matrix shape:", lda.components_.shape)
mean_all = np.mean(X, axis=0)先算出所有样本的全局中心,相当于合影时先找到整个会场的中点。sw += (Xc - mean_c).T @ (Xc - mean_c)把每个类内部离差累加,得到类内散度矩阵。diff = (mean_c - mean_all).reshape(-1, 1)把类中心与全局中心的偏差整理成列向量。sb += n_c * (diff @ diff.T)用样本数加权的外积累加,得到类间散度矩阵。eig_vals, eig_vecs = np.linalg.eig(np.linalg.pinv(sw) @ sb)用伪逆处理可能奇异的 \(S_W\),再求广义特征方程。self.components_ = eig_vecs[:, idx[:self.n_components]].real按特征值从大到小取前 \(k\) 个特征向量,作为投影矩阵。return X @ self.components_把原始数据投到判别方向,得到低维表示。
常见误区
误区反正 LDA 用了标签信息,只要数据有标签,LDA 就一定比 PCA 好。
正解LDA 优化的是类别可分性,不是数据保真度。如果类别分布严重重叠、非高斯或标签噪声很大,LDA 反而可能丢掉 PCA 能保留的有用结构。另外 LDA 最多降到 \(c-1\) 维,想保留更多维度时 PCA 更灵活。
为何常见:因为两者都是线性投影,看起来“带标签的版本”似乎天然更强,忽略了优化目标不同。
误区只要两类样本投影后的均值距离很大,就一定能把两类分开。
正解均值距离只衡量“中心差”,没有看类内宽度。如果每个类内部都摊得很宽,投影后照样大面积重叠。LDA 的比值同时惩罚类内散度,所以“中心远”和“内部紧”缺一不可。
为何常见:人们直觉上容易只盯住“两类代表点”,忽略了群体内部的分布宽度。
误区LDA 只是一个降维函数,任何数据扔进去都能得到合理结果。
正解LDA 依赖均值和协方差结构,理论上假设各类近似服从正态分布且协方差相近。如果数据高度偏斜、存在明显非线性边界,线性 LDA 的投影效果会明显下降。
为何常见:在工具库里调用 LDA 只需一两行代码,导致使用者忽视了方法背后的分布假设。
误区类内散度矩阵能求逆,所以求解一定稳定可靠。
正解高维小样本下,即使 \(S_W\) 形式上可逆,也可能病态严重,特征向量对噪声极其敏感。工程上常用正则项、伪逆或先 PCA 后 LDA 提高稳定性。
为何常见:教材里写着 \(S_W^{-1}S_B\),大家便以为求逆成功就万事大吉,忽略了数值稳定性问题。
面试题
Q1. LDA 在寻找投影方向时,核心目标是什么?
- A.最大化投影后样本的总方差
- B.最大化类间散度与类内散度之比← 正确答案
- C.最小化所有样本到原点距离
- D.最大化每个类内部聚集程度
答案:B。LDA 通过 Fisher 准则最大化类间散度与类内散度的比值,既要求异类远,又要求同类紧。A 是 PCA 的目标,C 和 D 都只描述了一个侧面。
Q2. LDA 中 \(S_W\) 通常被称为?
- A.类间散度矩阵
- B.类内散度矩阵← 正确答案
- C.全局协方差矩阵
- D.单位特征矩阵
答案:B。\(S_W\) 中的 W 代表 Within,衡量每个类别内部的离散程度。类间散度矩阵是 \(S_B\),全局协方差矩阵是 PCA 使用的概念。
Q3. 求解 LDA 投影方向时,需要求解的核心方程是?
- A.S_B w = λ S_W w← 正确答案
- B.S_W w = λ S_B w
- C.S_W^{-1} w = λ S_B
- D.S_B^{-1} S_W = λ I
答案:A。对 Fisher 准则求导后得到广义特征方程 \(S_B w = \lambda S_W w\),等价于 \(S_W^{-1}S_B w = \lambda w\)。其他选项混淆了 \(S_B\) 与 \(S_W\) 的位置。
Q4. 二分类场景下,LDA 最多可以得到几个有判别力的投影方向?
- A.0 个方向
- B.1 个方向← 正确答案
- C.2 个方向
- D.标签数量无关
答案:B。\(S_B\) 的秩最多是类别数减一,二分类时 \(c=2\),所以最多只有一个非零特征值,对应一个有效投影方向。
Q5. 当 \(S_W\) 奇异时,工程上通常如何处理?
- A.直接丢弃 S_W
- B.改用正则化或伪逆← 正确答案
- C.换成随机投影
- D.增加学习率
答案:B。高维小样本下类内散度矩阵可能不可逆或病态,常见做法是加入正则项、使用伪逆,或先 PCA 降维再 LDA。丢弃 \(S_W\) 会破坏目标函数。
Q6. 关于 PCA 与 LDA 的区别,下列说法正确的是?
- A.PCA 关注总方差,LDA 关注类别可分性← 正确答案
- B.PCA 关注类别可分性,LDA 关注总方差
- C.两者都只关注总方差
- D.两者都只关注类别可分性
答案:A。PCA 是无监督的,最大化投影后总方差;LDA 是有监督的,最大化类间散度与类内散度之比。其他选项把两者的目标弄反了。
Q7. 假设有 5 个类别、100 维数据,LDA 降维最多能保留几维有判别力?
- A.1 维
- B.3 维
- C.4 维← 正确答案
- D.100 维
答案:C。\(S_B\) 是由 \(c\) 个类中心构造的矩阵,秩最多为 \(c-1\),所以有判别力的维度数上限为 \(5-1=4\)。
Q8. 下列哪些是执行 LDA 降维的必要步骤?
- A.计算各类样本均值← 正确答案
- B.构造类内与类间散度矩阵← 正确答案
- C.求解广义特征方程← 正确答案
- D.使用梯度下降拟合树模型
答案:ABC。LDA 需要先算类均值,再构造 \(S_W\) 和 \(S_B\),最后做广义特征分解取特征向量。树模型和梯度下降不属于 LDA 的步骤。
Q9. 关于 LDA 的适用前提,下列说法正确的有?
- A.各类近似服从正态分布← 正确答案
- B.各类协方差结构相近← 正确答案
- C.样本类别标签已知← 正确答案
- D.数据必须服从均匀分布
答案:ABC。LDA 是基于均值与协方差的线性方法,通常假设条件分布近似正态、协方差相近,且必须有标签。均匀分布不是 LDA 的前提。
Q10. 下列哪些是 LDA 的典型应用场景?
- A.人脸识别特征提取← 正确答案
- B.文本分类前的降维← 正确答案
- C.无标签异常检测
- D.有监督分类前处理← 正确答案
答案:ABD。LDA 被广泛用于人脸识别和文本分类等有监督任务,作为特征提取或分类前处理步骤。无标签异常检测没有类别标签,不适合 LDA。