E.C.4 线性判别分析

LDA 会寻找一个投影方向,让同类样本更靠近、不同类样本更分开。它既可以做分类,也可以做有监督降维。
- Python 3.10+
- 当前稳定版
scikit-learn和numpy
python -m pip install -U scikit-learn numpy- 类内方差:同一个类别内部有多分散。
- 类间分离:不同类别中心之间有多远。
- 投影:把特征映射到更低维空间。
- 有监督降维:降维时使用标签信息。
- 这里的 LDA:Linear Discriminant Analysis,不是 Latent Dirichlet Allocation。
运行 LDA 分类和投影
Section titled “运行 LDA 分类和投影”创建 lda_projection.py:
import numpy as npfrom sklearn.discriminant_analysis import LinearDiscriminantAnalysis
X = np.array([ [1.0, 2.0], [1.5, 1.8], [2.0, 1.5], [4.0, 5.0], [4.5, 4.8], [5.0, 4.5],])y = np.array([0, 0, 0, 1, 1, 1])
model = LinearDiscriminantAnalysis(n_components=1)model.fit(X, y)
pred = model.predict([[1.4, 1.9], [4.8, 4.6]])projection = model.transform(X)
print("predictions:", pred.tolist())print("projection_shape:", projection.shape)运行:
python lda_projection.py预期输出:
predictions: [0, 1]projection_shape: (6, 1)同一个模型既完成了新点分类,也把训练数据投影到一个有判别力的一维方向。
和 PCA 对比
Section titled “和 PCA 对比”PCA 寻找整体方差大的方向,不看标签。LDA 使用标签,寻找最能分开类别的方向。当类别分离比通用压缩更重要时,LDA 更有意义。
适合尝试 LDA:
- 已有标签。
- 类别内部比较紧凑。
- 想做轻量线性 baseline。
- 想为可视化或下游模型得到低维表示。
如果类别边界明显高度非线性,就不要优先用它。
Baseline 复盘
Section titled “Baseline 复盘”复盘 LDA 时,检查投影后类别是否真的更容易分开。一个小图、类别均值表,或者投影前后的分数对比,都可以作为这页的证据。
不要默认“降维后一定更好”。如果投影后类别仍然重叠,就把这个结论写下来,并和 SVM、KNN 或其他 baseline 对比。LDA 的价值是解释分离方向,而不是制造一个新矩阵。
交付检查时,记录投影后的形状和每个类别的投影均值。若均值靠得很近,说明 LDA 找到的方向不够区分类别。这个结论本身也有价值,因为它告诉你需要更好的特征或非线性模型。
学完这一页,至少保留这张证据卡:
- 模型家族
- SVM、KNN、朴素贝叶斯、LDA 或其他传统基线
- 数据视图
- 特征缩放、类别平衡、决策边界和训练/测试划分
- 指标
- 准确率/F1、混淆矩阵、边距、邻近行为或投影质量
- 失败检查
- 缩放、高维度、假设薄弱、泄漏或基线拟合差
- 期望产出
- 经典机器学习基线结果,以及一条局限性说明
- 把这里的 LDA 和主题模型 LDA 混淆。
- 以为 LDA 用标签,所以一定比 PCA 好。
- 忘记两个类别时,LDA 最多只能投影到一个分量。
添加第三个类别,并设置 n_components=2。打印新的投影形状,并解释为什么最大分量数变了。
项目交付参考与讲解
有三个类别时,LDA 最多可以投影到 类别数 - 1 = 2 个判别分量,前提是特征维度也允许。如果你给类别 2 增加三个样本,并设置 n_components=2,变换后的数据应该有两列;如果现在共有九行,形状会类似 (9, 2)。
关键解释是:LDA 的方向用于分开类别。两个类别最多只需要一个分离方向;三个类别可能需要两个方向。