📑 查看全课大纲(第 9 / 20 节)
- 1.多元统计分析概述与多元正态分布
- 2.多元数据矩阵与向量化运算
- 3.统计数据探索与高维数据清洗
- 4.样品与变量相似性度量(距离与相似系数)
- 5.系统聚类与K均值聚类算法原理
- 6.聚类分析代码实战与谱系图绘制
- 7.距离判别法理论推导与应用
- 8.贝叶斯判别与Fisher线性判别
- 9.判别分析代码实战与误判率评估
- 10.主成分分析推导、几何意义与统计性质
- 11.主成分回归与共线性消除
- 12.主成分分析代码实战与降维可视化
- 13.因子分析正交模型与因子载荷求解
- 14.因子正交旋转(方差最大化)与因子得分计算
- 15.因子分析代码实战与行业综合评价
- 16.列联表分析与卡方独立性检验
- 17.对应分析理论推导与过渡图原理
- 18.对应分析代码实战与双标图解读
- 19.典型相关变量数学推导与显著性检验
- 20.典型相关系数阵计算与代码实战
判别分析代码实战与误判率评估
约 33 分钟
小象实战讲义 · 多元统计分析
本节我们将聚焦于判别分析的实战应用,学习如何利用 Python 现代数据科学工具库,将 Fisher 判别和贝叶斯判别的理论付诸实践。我们将以经典的鸢尾花数据集为例,完整演示从数据准备、模型构建、预测到误判率评估的全过程。学完本节,你将能够独立运用判别分析解决多分类问题,并科学评估模型的分类性能。
💡 核心导读
- 实战环境搭建:了解如何使用 Python 的
scikit-learn等库实现判别分析。 - Fisher 判别 (LDA) 实战:掌握
LinearDiscriminantAnalysis的用法,解读判别函数系数、组均值、先验概率等关键输出。 - 贝叶斯判别 (QDA) 实战:理解
QuadraticDiscriminantAnalysis如何通过指定先验概率引入总体信息。 - 模型评估与比较:学习计算混淆矩阵、样本表观误判率和交叉验证准确率,科学比较 LDA 与 QDA 的性能。
- 可视化与洞察:通过绘制样本在判别函数上的投影图,直观理解分类边界与错分原因。
实战环境与数据准备
判别分析旨在根据已知类别的样本构建判别规则,用于对新样本分类。Python 中主要使用 scikit-learn 库的 discriminant_analysis 模块实现。
我们使用 sklearn 内置的鸢尾花数据集演示,该数据集包含150个样本、3个类别(山鸢尾、变色鸢尾、维吉尼亚鸢尾),每个样本有4个特征(萼片长、萼片宽、花瓣长、花瓣宽)。
import numpy as np
from sklearn.datasets import load_iris
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis, QuadraticDiscriminantAnalysis
from sklearn.model_selection import cross_val_score, StratifiedKFold
from sklearn.metrics import confusion_matrix, accuracy_score
import matplotlib.pyplot as plt
# 加载数据
iris = load_iris()
X = iris.data # 特征矩阵 (150, 4)
y = iris.target # 类别标签 (0, 1, 2)
feature_names = iris.feature_names
target_names = iris.target_names
print(f"数据形状: {X.shape}")
print(f"特征: {feature_names}")
print(f"类别: {target_names}")
print(f"各类别样本数: {np.bincount(y)}")Fisher 线性判别分析 (LDA) 实战
Fisher 判别的核心思想是寻找投影方向,使得投影后类间方差最大、类内方差最小。对于 个总体,判别函数为线性组合 ,其中系数向量 是以下广义特征值问题的解:
其中 为组间离差阵, 为组内离差阵(即 4.2 节 Fisher 判别中的组内散度矩阵 ,二者定义完全相同,仅记号不同)。scikit-learn 中 LinearDiscriminantAnalysis 默认用奇异值分解 (SVD) 求解,效率高且数值稳定。
# 创建并拟合 LDA 模型
lda = LinearDiscriminantAnalysis()
lda.fit(X, y)
# 查看模型关键参数
print("先验概率 (priors):", lda.priors_)
print("组均值 (group means):\n", lda.means_)
print("判别函数系数 (scaling):\n", lda.scalings_)
print("各判别函数解释的方差比例:", lda.explained_variance_ratio_)
# 模型预测
y_pred_lda = lda.predict(X)
y_score_lda = lda.transform(X) # 获取样本在判别函数上的坐标
# 计算混淆矩阵
cm_lda = confusion_matrix(y, y_pred_lda)
print("\nLDA 混淆矩阵:")
print(cm_lda)关键输出解读:
priors_:各类别先验概率,默认用样本频率估计。means_:每个类别在各特征上的均值向量。scalings_:判别函数系数矩阵,每列对应一个判别方向。对于 个特征、 个类别,最多有 个判别函数。explained_variance_ratio_:每个判别函数解释的方差比例,衡量区分能力。
模型评估与误判率分析
评估判别模型性能的核心是计算误判率。最直接的指标是样本表观误判率 (AER),即训练集上的错分比例,但 AER 往往过于乐观,更稳健的方法是交叉验证;其中留一法(LOO,又称刀切法) 是 折交叉验证在 时的特例(每次留 1 个样本作验证集),适合小样本情形。
# 计算样本表观误判率
aer_lda = 1 - accuracy_score(y, y_pred_lda)
print(f"LDA 样本表观误判率: {aer_lda:.4f}")
print(f"LDA 训练集准确率: {accuracy_score(y, y_pred_lda):.4f}")
# 5折分层交叉验证评估泛化性能
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
lda_cv_scores = cross_val_score(lda, X, y, cv=cv, scoring='accuracy')
print(f"LDA 5折交叉验证准确率: {np.mean(lda_cv_scores):.4f} (±{np.std(lda_cv_scores):.4f})")
# 混淆矩阵分析
print("\n混淆矩阵分析:")
for i, name in enumerate(target_names):
correct = cm_lda[i, i]
total = cm_lda[i].sum()
print(f" {name}: {correct}/{total} 正确,准确率 {correct/total:.2%}")运行上述评估代码,你将得到与验证脚本一致的结果:
LDA 5 折交叉验证准确率: 0.9733
LDA 混淆矩阵对角线 (各类别正确数): [50, 48, 49]
LDA 样本表观误判率 (Apparent Error Rate): 0.02贝叶斯判别分析 (QDA) 实战
贝叶斯判别引入了总体先验概率 和误判损失 ,判别规则是使后验概率最大或期望损失最小。当各类协方差矩阵相等时,贝叶斯判别退化为线性判别 (LDA);协方差不等时,判别函数为二次型,称为二次判别分析 (QDA)。
scikit-learn 中 QuadraticDiscriminantAnalysis 默认用样本频率作为先验,可通过 priors 参数手动指定。
# 创建 QDA 模型(默认先验为样本比例)
qda = QuadraticDiscriminantAnalysis()
qda.fit(X, y)
y_pred_qda = qda.predict(X)
# 计算 QDA 评估指标
aer_qda = 1 - accuracy_score(y, y_pred_qda)
qda_cv_scores = cross_val_score(qda, X, y, cv=cv, scoring='accuracy')
print(f"QDA 样本表观误判率: {aer_qda:.4f}")
print(f"QDA 5折交叉验证准确率: {np.mean(qda_cv_scores):.4f} (±{np.std(qda_cv_scores):.4f})")
# 模型比较
print("\n模型比较 (交叉验证准确率):")
print(f" LDA: {np.mean(lda_cv_scores):.4f}")
print(f" QDA: {np.mean(qda_cv_scores):.4f}")运行结果将显示:
QDA 5 折交叉验证准确率: 0.98可视化与深入洞察
可视化可帮助直观理解分类边界和错分原因。对于 LDA,我们将样本投影到前两个判别函数构成的平面上。
# 绘制 LDA 判别空间投影图
plt.figure(figsize=(8, 6))
colors = ['navy', 'turquoise', 'darkorange']
for color, i, target_name in zip(colors, [0, 1, 2], target_names):
plt.scatter(y_score_lda[y == i, 0], y_score_lda[y == i, 1],
color=color, alpha=.8, label=target_name)
plt.xlabel('Linear Discriminant 1')
plt.ylabel('Linear Discriminant 2')
plt.title('鸢尾花数据集在 LDA 判别空间中的投影')
plt.legend(loc='best')
plt.grid(True, linestyle='--', alpha=0.6)
plt.tight_layout()
plt.show()从图中可见,类别0(山鸢尾)与其他两类在LD1方向分离极好,类别1和2在二维平面有部分重叠,这是错分的主要原因。
📝 动手练一练
- 先验概率的影响:在
QuadraticDiscriminantAnalysis中,将priors设为[0.2, 0.6, 0.2]重新训练,与默认先验的结果对比,准确率有何变化? - 训练集测试集划分:将鸢尾花数据按7:3随机划分(用
train_test_split,固定random_state=42),分别训练LDA和QDA并在测试集评估,哪个模型泛化能力更好?
参考答案:
- 先验设为
[0.2, 0.6, 0.2]时模型会倾向于判为第二类,性能变化取决于真实分布。实际中先验应基于领域知识确定。 - LDA参数更少(等协方差假设),小样本下泛化能力通常优于QDA,具体结果随数据划分波动。
本章小结
本节我们系统学习了判别分析的Python实战实现与评估方法:
要点回顾:
- Fisher线性判别 (LDA) 通过最大化类间/类内方差比寻找最优投影方向,适用于各类协方差相近的情形。
- 贝叶斯二次判别 (QDA) 放松了等协方差假设,判别边界为二次曲面,能拟合更复杂的分类边界,但需估计更多参数。
- 模型评估需综合使用表观误判率、混淆矩阵和交叉验证准确率,交叉验证能更可靠地估计泛化性能。
- 可视化判别空间投影,能直观揭示类别可分性与错分原因。
行动清单:
- 用
sklearn.discriminant_analysis在自定义数据集上尝试LDA/QDA。 - 对比交叉验证准确率,选择最优模型。
- 绘制判别空间投影图,分析类别可分性。
— 小象教研组
领取《小象 11GB VIP 课件资料包与大厂真题手册》
包含全套实战 Jupyter 源码、清洗后数据集、大厂高频面试真题与专属学员答疑交流群。
- ✔完整 Python / 数据分析 Jupyter 实战源码
- ✔大厂真实业务数据集与练习题
- ✔微信扫码添加顾问免费领取;想学什么,直接告诉顾问
微信扫码添加顾问