一、LDA线性判别法讲解
PCA 来降维属于无监督学习,其没有将样本类别标签考虑进去。LDA是一种有监督学习的降维技术,也就是说它将样本类别标签考虑了进去。LDA的思想为:给定样本训练集,将样本投影到一条直线上,使得同类样本的投影点尽可能近、不同类样本的投影点中心尽可能远。简单的概括一句话:投影后类内方差最小,类间方差最大。

假设有个二分类问题,训练集xi为N个不同维度的样本,那么样本点x在向量w的投影为:

该式子中,x为样本集合;y为转置后的特征空间;w是转置矩阵,通过w可以将两类x转换成N个一维的样本,分为y1和y2两个子集。设各类样本均值向量为��i,那么:

样本的协方差矩阵为:

目标函数:
(1)投影后的两类样本中心点尽可能远
该目标为找到一个最佳的w使投影后的两类样本中心点尽量远的直线是好的直线,该目标函数如下:

这里我们把f(w)当作目标函数,期望其值越大越好。
(2)投影后类内方差尽可能小

在这里我们引入另一个度量指标:散列值来表示同类数据样本点的离散程度,如下所示:

上述式子表示其值越大,表示越分散;其值越小,表示越集中。
(3)对于上述两个目标的求解
要使不同类别之间的中心距离尽量大,那么将其作为分子;要使相同类别样本之间距离尽可能小,那将其作为分母,求整体的最大值即可:


对于矩阵SB和SW,只要有数据和标签即可求解。如果对分子和分母同时求解,就会有无穷多解,常用的方法是先固定分母,经过缩放变换后,将其值限制为1,如下所示:

Python实现:
import numpy as np #导入numpy库
x1 = [ 1, 2, 3, 1, 2 ]
x2 = [ 3, 2 ,1, 3, 1 ]
y = [ 1, 1, 1, 2, 2 ]
X =np.c_[x1, x2] #两列合并
X
#导入LDA模块
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
#设置LDA降,并将降维后的维度设为1
lda = LinearDiscriminantAnalysis(n_components=1)
lda.fit(X,y) #进行降维训练
print (“每个类别的均值: “,lda. means_)
print (“整体样本的均值: “,lda. xbar_)
X_LDA = lda.transform(X) #生成的降维后的新变量X
print (“降维后变量:”, X_LDA)
print (“截距: “, lda.intercept_)
print (“权重W: “, lda.coef_)
二、LDA线性判别法的应用场景
LDA(Linear Discriminant Analysis)是一种有监督的降维和分类方法,其核心目标是:
【1】最大化类间距离:使不同类别投影后的均值差异最大
【2】最小化类内距离:使同类样本的投影点尽可能集中
数学目标函数:

其中 Sb 是类间散度矩阵,Sw 是类内散度矩阵。
(1) 模式识别与分类
场景:小样本高维数据的分类
案例:
人脸识别(Eigenfaces vs. Fisherfaces)
医学诊断(癌症亚型分类)
优势:在类别可分性强时,效果优于PCA
(2) 生物信息学
基因表达数据分析:
将数万个基因特征降至2-3维
可视化不同癌症类型的分离情况
效果对比:

(3) 金融风控
客户信用评分:
输入:收入、负债、交易记录等30+特征
输出:高风险/低风险客户的二维投影
优势:明确显示决策边界
(4) 多分类任务
手写数字识别:
MNIST数据(784维→9维,因为类别数10-1)
计算效率比SVM更高
数学约束:
LDA最大降维维度 = 类别数 – 1
(5) 语音识别
声学特征降维:将MFCC(梅尔频率倒谱系数)从39维降至5-10维;保留最具判别力的频率特征
LDA与PCA的对比:

选择LDA的决策条件:
【1】当以下条件满足时优先使用LDA:
数据维度 < 样本量(p<np<n)
类别数较少(<10)
各类近似正态分布
需要明确的可解释性投影方向
【2】避免使用LDA的情况:
特征间存在高度非线性关系
类别数 > 特征数
数据标签噪声较大
三、LDA 线性判别法的优缺点
LDA 作为经典的线性分类与降维方法,在标签充足、样本分布近似高斯且线性可分的场景中表现优异,尤其适合需要兼顾降维与分类的任务。但在面对高维小样本、类别不平衡或非线性数据时,需结合预处理或改进方法(如核 LDA、正则化 LDA)以提升效果。实际应用中,可根据数据特性与任务目标,灵活选择 LDA 或与其他算法(如 PCA、SVM)结合使用。
(一)LDA 的核心优点
(1) 明确的分类导向性
LDA 以最大化类别区分度为目标(通过类间散度与类内散度的比值优化),降维结果直接服务于分类任务,相比无监督降维(如 PCA)更具针对性。
案例:在文本分类中,LDA 可将高维词向量投影到最能区分不同主题的低维空间,提升分类准确率。
(2) 线性模型的高效性与可解释性
基于线性变换,计算复杂度低(时间复杂度为 O (n³),n 为特征数),适合处理大规模数据。
投影方向(权重向量)可直接反映各特征对分类的贡献度,例如在人脸识别中,权重高的像素点对应关键面部特征。
(3) 天然的降维上限约束
降维后的维度上限为类别数-1,避免了维度冗余。例如,3 类数据最多降为 2 维,保证降维后仍保留足够分类信息。
(4) 对样本分布的假设兼容性
假设各分类样本服从高斯分布且协方差矩阵相同,这一假设在许多实际场景(如生物特征识别、金融数据分箱)中近似成立,保证了模型有效性。
(5) 可扩展为非线性版本
通过与核函数结合(如核 LDA),可处理非线性分类问题,将原始特征映射到高维空间后再进行线性判别。
(二)LDA 的主要缺点
(1) 对类别不平衡的敏感性
目标函数基于类间散度,若某类样本数量过少,其类间散度贡献小,易被忽略。
实例:医疗数据中疾病类样本远少于正常类时,LDA 可能过度偏向正常类,导致疾病检测率下降。
(2) 依赖样本的线性可分假设
当类别间存在非线性边界时(如环形分布数据),线性投影无法有效区分,需依赖核方法或非线性变换。
(3) 高维小样本场景下的奇异性问题
当特征维度 d 大于样本数 n 时,类内散度矩阵可能不可逆(病态矩阵),导致无法求解最优投影方向(需通过正则化或 PCA 降维预处理)。
(4) 缺乏对特征独立性的考量
LDA 仅已关注特征对分类的整体贡献,不处理特征间的相关性,可能存在冗余特征干扰。例如,在房价预测中,面积与总价高度相关,LDA 可能重复计算其权重。
(5) 对噪声和离群点的鲁棒性不足
类内散度计算受离群点影响大,若样本中存在异常值,可能导致最优投影方向偏移。
解决方案:可先通过聚类或异常检测过滤离群点,或使用加权 LDA 降低异常值权重。
(6) 无监督场景下的适用性局限
依赖标签信息,无法直接用于无标签数据降维(而 PCA 可直接处理无监督数据)。
(三)LDA 与 PCA 的对比总结

(四)实际应用中的优化策略
【1】针对类别不平衡
使用加权 LDA(为少数类赋予更高权重)或过采样(如 SMOTE)扩充少数类样本。
【2】处理高维小样本
先通过 PCA 降维至n-1维(n 为样本数),再应用 LDA(即 PCA+LDA 组合方法)。
【3】提升鲁棒性
结合正则化项(如 L2 正则)约束权重向量,或使用核 LDA 处理非线性问题。
四、线性判别法LDA的例子
以下是一个完整的医疗领域LDA实现案例,包含数据生成、模型构建、训练评估和可视化全流程,这个实现完整展示了LDA在医疗数据分析中的典型应用流程,所有代码都有详细注释,避免使用复杂语法,确保可读性。可视化部分已处理中文乱码问题,并去除了警告信息。
注意事项:
【1】实际医疗应用中需要更多样本(建议>100条)
【2】分类效果严重依赖数据是否符合LDA的高斯分布假设
【3】对于非线性可分数据,需考虑改用QDA或其他非线性方法
主要步骤:
【1】数据准备:
创建10条模拟医疗数据,包含3个临床指标和诊断类别
【2】数据标准化:
使用StandardScaler对特征进行Z-score标准化
输出标准化后的数值范围(均值≈0,方差=1)
【3】LDA降维
将3维特征降至2维(因为3个类别)
输出投影矩阵,显示每个原始特征对判别分量的贡献
【4】可视化
绘制降维后的二维散点图,不同类别用不同颜色标记
图形显示各类别的分离情况
【5】分类器应用
使用LDA作为分类器预测新样本
输出测试集的预测结果与真实标签对比
【6】模型评估
计算准确率和混淆矩阵
【7】决策边界
绘制基于前两个判别分量的决策区域
直观展示分类器的判断逻辑
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.metrics import accuracy_score, confusion_matrix
import warnings
warnings.filterwarnings(“ignore”) # 去除警告
plt.rcParams['font.sans-serif'] = ['SimHei'] # 解决中文乱码
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# ==================== 1. 准备医疗数据集 ====================
# 模拟10条患者数据,3个特征+1个类别标签(0-健康,1-糖尿病,2-高血压)
# 特征:年龄,血糖水平(mmol/L),血压(mmHg)
medical_data = np.array([
[35, 5.2, 120, 0], # 健康
[48, 6.8, 135, 1], # 糖尿病
[62, 7.5, 148, 2], # 高血压
[29, 5.1, 118, 0],
[53, 9.1, 142, 1],
[58, 8.3, 155, 2],
[41, 5.8, 126, 0],
[50, 10.2, 140, 1],
[65, 7.9, 160, 2],
[45, 6.1, 130, 0]
])
# 分离特征和标签
X = medical_data[:, :3] # 前3列是特征
y = medical_data[:, 3] # 最后1列是标签
print(“医疗数据示例:”)
print(“年龄 | 血糖 | 血压 | 类别”)
print(“—————————-“)
for row in medical_data:
print(f”{int(row[0])}岁 | {row[1]} | {int(row[2])} | {int(row[3])}”)
# ==================== 2. 数据标准化 ====================
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
print(”
标准化后的数据(前3个样本):”)
print(X_scaled[:3])
# ==================== 3. 执行LDA降维 ====================
lda = LinearDiscriminantAnalysis(n_components=2)
X_lda = lda.fit_transform(X_scaled, y) # 注意LDA需要标签!
print(”
LDA投影矩阵:”)
print(lda.scalings_) # 显示投影方向
print(”
降维结果:”)
for i, (original, reduced) in enumerate(zip(X_scaled[:3], X_lda[:3])):
print(f”样本{i}: {original} → {reduced}”)
# ==================== 4. 可视化降维结果 ====================
plt.figure(figsize=(10, 6))
colors = ['green', 'orange', 'red']
labels = ['健康', '糖尿病', '高血压']
for color, target, label in zip(colors, [0, 1, 2], labels):
plt.scatter(
X_lda[y == target, 0], # 第一判别分量
X_lda[y == target, 1], # 第二判别分量
color=color,
label=label,
alpha=0.7
)
plt.title('LDA: 患者数据降维可视化')
plt.xlabel('第一判别分量 (解释方差: %.1f%%)' % (lda.explained_variance_ratio_[0]*100))
plt.ylabel('第二判别分量 (解释方差: %.1f%%)' % (lda.explained_variance_ratio_[1]*100))
plt.legend()
plt.grid()
plt.show()
# ==================== 5. 作为分类器使用 ====================
# 划分训练集和测试集(简单示例,实际应用需交叉验证)
X_train, X_test = X_scaled[:7], X_scaled[7:]
y_train, y_test = y[:7], y[7:]
# 训练LDA分类器
lda_classifier = LinearDiscriminantAnalysis()
lda_classifier.fit(X_train, y_train)
# 预测
y_pred = lda_classifier.predict(X_test)
print(”
测试集真实标签:”, y_test)
print(“测试集预测标签:”, y_pred)
# ==================== 6. 模型评估 ====================
accuracy = accuracy_score(y_test, y_pred)
conf_mat = confusion_matrix(y_test, y_pred)
print(”
模型评估:”)
print(f”准确率: {accuracy:.2f}”)
print(“混淆矩阵:”)
print(conf_mat)
# ==================== 7. 修正后的决策边界可视化 ====================
# 创建一个新的LDA模型专门用于2D可视化
lda_vis = LinearDiscriminantAnalysis(n_components=2)
X_lda_vis = lda_vis.fit_transform(X_scaled, y)
lda_classifier_vis = LinearDiscriminantAnalysis()
lda_classifier_vis.fit(X_lda_vis, y) # 在降维后的数据上训练
plt.figure(figsize=(10, 6))
# 生成网格点
x_min, x_max = X_lda_vis[:, 0].min() – 1, X_lda_vis[:, 0].max() + 1
y_min, y_max = X_lda_vis[:, 1].min() – 1, X_lda_vis[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02),
np.arange(y_min, y_max, 0.02))
# 预测网格点类别
Z = lda_classifier_vis.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
# 绘制决策区域
plt.contourf(xx, yy, Z, alpha=0.3, levels=[-0.5, 0.5, 1.5, 2.5], colors=colors)
# 绘制数据点
for color, target, label in zip(colors, [0, 1, 2], labels):
plt.scatter(
X_lda_vis[y == target, 0],
X_lda_vis[y == target, 1],
color=color,
label=label,
edgecolors='black'
)
plt.title('LDA决策边界可视化(基于降维数据)')
plt.xlabel('第一判别分量')
plt.ylabel('第二判别分量')
plt.legend()
plt.show()
输出结果:
医疗数据示例: 年龄 | 血糖 | 血压 | 类别 ---------------------------- 35岁 | 5.2 | 120 | 0 48岁 | 6.8 | 135 | 1 62岁 | 7.5 | 148 | 2 29岁 | 5.1 | 118 | 0 53岁 | 9.1 | 142 | 1 58岁 | 8.3 | 155 | 2 41岁 | 5.8 | 126 | 0 50岁 | 10.2 | 140 | 1 65岁 | 7.9 | 160 | 2 45岁 | 6.1 | 130 | 0 标准化后的数据(前3个样本): [[-1.24233296 -1.23702137 -1.28610446] [-0.05480881 -0.24740427 -0.17739372] [ 1.22406336 0.18555321 0.78348892]] LDA投影矩阵: [[ 0.00378016 -0.82540646] [-0.43341907 -1.94087296] [ 2.93348092 2.02065929]] 降维结果: 样本0: [-1.24233296 -1.23702137 -1.28610446] → [-3.24131046 0.82755206] 样本1: [-0.05480881 -0.24740427 -0.17739372] → [-0.41335855 0.16696754] 样本2: [1.22406336 0.18555321 0.78348892] → [2.22255467 0.21267917]

测试集真实标签: [1. 2. 0.] 测试集预测标签: [1. 2. 1.] 模型评估: 准确率: 0.67 混淆矩阵: [[0 1 0] [0 1 0] [0 0 1]]
















暂无评论内容