在降维领域,线性判别分析(LDA)常常被更为流行的主成分分析(PCA)所掩盖。然而,LDA 提供了 PCA 无法做到的独特能力:它在降维的同时优化类别可分性。
本教程将向您介绍 LDA、其背后的数学直觉以及该技术的实际应用。我们还将把 LDA 应用于一个数据集,与 PCA 进行比较,分析其优劣势,旨在为您提供在下一个项目中开始使用 LDA 所需的一切。
线性判别分析(LDA)简介
在假设不同类别的数据分别来自不同的高斯分布 的前提下,LDA 是一种降维与分类技术。
LDA 的目标是找到能最好地区分这些类别的特征线性组合。它最大化类间散度与类内散度的比值。通俗地说,它试图在特征空间中找到使不同类别彼此相距更远(高类间散度)、同一类别内部点彼此更接近(低类内散度)的方向。
这种双重目标使 LDA 在降维与分类任务中都格外有效。
LDA 背后的数学
理解 LDA 的数学原理需要将算法分解为三个关键组成部分:
类内散度矩阵(Sw)
类内散度矩阵衡量每个类别内部数据点的分散程度。
对于每个类别i ,我们计算散度矩阵 Si 为:
Si = Σ(x - μi)(x - μi)T技术支持
其中 x 表示类别 i 中的每个数据点,μi 是类别 i 的均值。总的类内散度矩阵为:
Sw = Σ Si (sum over all classes)技术支持
类间散度矩阵(Sb)
类间散度矩阵衡量各类别均值与整体均值之间的距离。其计算方式为:
Sb = Σ Ni(μi - μ)(μi - μ)T 技术支持
其中 Ni 是类别 i 的样本数,μi 是类别 i 的均值,μ 是所有数据的整体均值。
优化目标
LDA 旨在找到使 Fisher 准则最大化的投影矩阵 W:
J(W) = |WT Sb W| / |WT Sw W|技术支持
本质上,这是在投影空间中最大化类间散度与类内散度之比。其解涉及求矩阵 Sw-1 Sb 的特征向量,即得到最佳区分类别的方向(线性判别向量)。
因此,LDA 将这一复杂的优化问题转化为特征值分解 ,从而在中等高维数据集上也具有计算效率。
在理解了 LDA 的概念与数学直觉后,接下来看看它的实际应用。
LDA 的真实世界应用
在需要分类与降维的多个领域,LDA 都有所应用:
医学诊断 :LDA 用于医学影像中对不同类型的肿瘤或异常进行分类。它可以分析 MRI 扫描,通过识别图像数据中最具判别性的特征来区分良性与恶性组织。
金融与银行 :信用评分系统使用 LDA 将贷款申请人划分为不同风险类别。通过分析收入、负债收入比、信用历史等财务指标,LDA 可帮助区分高风险与低风险借款人。
生物信息学 :基因表达分析使用 LDA 对不同疾病状态或治疗反应进行分类。它有助于识别在区分健康与患病组织样本中最重要的基因。
市场营销与客户细分 :企业使用 LDA 基于购买行为、人口统计数据与参与度指标对客户进行细分,这在目标营销活动和个性化产品推荐中非常有用。
图像识别 :人脸识别系统利用 LDA 在保留最有助于区分不同个体的特征的同时,降低人脸图像的维度。
质量控制 :制造业基于各种质量指标应用 LDA 将产品分类为次品或合格品,从而实现自动化质保流程。
语音识别 :LDA 通过识别最能区分不同语音音素的声学特征来辅助音素分类,从而提升语音转文本系统的准确率。
环境监测 :LDA 被用于基于传感器数据对环境状况进行分类,例如区分不同的污染水平或天气模式。
在 Python 中实现 LDA
让我们通过一个端到端示例,使用 Python 实现 LDA。
我们将使用 Seeds 数据集,可从UCI 库 以及Kaggle 下载。该数据集包含属于三种不同小麦品种的小麦籽粒测量值。
步骤 1:导入库并加载数据
首先,我们导入必要的库并加载数据集:
import numpy as np
import pandas as pd
import matplotlib. pyplot as plt
import seaborn as sns
from sklearn. model_selection import train_test_split
from sklearn. preprocessing import StandardScaler
from sklearn. discriminant_analysis import LinearDiscriminantAnalysis
from sklearn. metrics import classification_report, confusion_matrix, accuracy_score
file_path = "seeds_dataset.txt"
column_names = [ 'area' , 'perimeter' , 'compactness' , 'kernel_length' ,
'kernel_width' , 'asymmetry' , 'groove_length' , 'variety' ]
seeds_df = pd. read_csv( file_path, sep= '\s+' , header= None , names= column_names)
print ( f"Dataset shape: { seeds_df. shape} " )
seeds_df. head( ) 技术支持
我们将在下方查看已加载数据集的前 5 行:
Seeds 数据集概览。(作者供图)
步骤 2:数据预处理
探索数据结构并为 LDA 分析做准备:
print ( f"Missing values: { seeds_df. isnull( ) . sum ( ) . sum ( ) } " )
print ( "\nClass distribution:" )
print ( seeds_df[ 'variety' ] . value_counts( ) )
X = seeds_df. drop( 'variety' , axis= 1 )
y = seeds_df[ 'variety' ]
X_train, X_test, y_train, y_test = train_test_split( X, y, test_size= 0.3 ,
random_state= 42 , stratify= y)
scaler = StandardScaler( )
X_train_scaled = scaler. fit_transform( X_train)
X_test_scaled = scaler. transform( X_test) 技术支持
这里我们检查数据集中是否存在缺失值,并查看每个类别包含多少样本。随后通过将输入与标签分离、划分训练集与测试集,并对输入值进行标准化,使所有特征处于相近量纲,为后续建模做准备。
数据预处理。(作者供图)
可以看到不存在缺失值,且类别分布均衡。
步骤 3:应用 LDA 进行降维
现在我们将应用 LDA,在保留类别可分性的同时降低数据维度:
lda = LinearDiscriminantAnalysis( n_components= 2 )
X_train_lda = lda. fit_transform( X_train_scaled, y_train)
X_test_lda = lda. transform( X_test_scaled)
print ( "Explained variance ratio:" , lda. explained_variance_ratio_)
print ( "Cumulative explained variance:" , np. cumsum( lda. explained_variance_ratio_) ) 技术支持
我们创建一个模型来寻找最佳方向,以分离数据中的不同类别。由于有三个类别,将数据降至两个新特征,可以保留区分它们的最重要模式。
输出如下:
LDA 方差结果。(作者供图)
该输出展示了由 LDA 生成的两个新特征分别捕获了多少类别分离信息:
解释方差比: 这意味着第一个 LDA 分量捕获了约 67.7% 的类别区分信息,而第二个分量捕获了剩余的 32.3%。
累积解释方差: 两个分量合计捕获了原始数据中 100% 的类别分离信息。这是预期的,因为我们有 3 个类别,而 LDA 至多给出 2 个有用方向。
步骤 4:可视化 LDA 变换
让我们可视化 LDA 如何变换数据并分离各类别:
fig, ( ax1, ax2) = plt. subplots( 1 , 2 , figsize= ( 14 , 6 ) )
ax1. scatter( X_train_scaled[ : , 0 ] , X_train_scaled[ : , 1 ] ,
c= y_train, cmap= 'viridis' , alpha= 0.7 , edgecolor= 'k' )
ax1. set_xlabel( 'Area (standardized)' )
ax1. set_ylabel( 'Perimeter (standardized)' )
ax1. set_title( 'Original Feature Space (First Two Features)' )
ax1. grid( True , alpha= 0.3 )
scatter = ax2. scatter( X_train_lda[ : , 0 ] , X_train_lda[ : , 1 ] ,
c= y_train, cmap= 'viridis' , alpha= 0.7 , edgecolor= 'k' )
ax2. set_xlabel( 'First Linear Discriminant' )
ax2. set_ylabel( 'Second Linear Discriminant' )
ax2. set_title( 'LDA-Transformed Space' )
ax2. grid( True , alpha= 0.3 )
plt. colorbar( scatter, ax= ax2, label= 'Wheat Variety' )
plt. tight_layout( )
plt. show( ) 技术支持
上述代码创建了两个并排的图表,帮助我们对比应用降维技术前后数据的变化,如下所示:
LDA 可视化。(作者供图)
第一个图使用两项原始测量特征(面积与周长)展示数据,以观察类别在原空间中的天然分离程度。第二个图展示了将数据变换到最有利于类别分离的方向后的结果。我们添加了颜色条来指示不同颜色对应的小麦品种。
步骤 5:将 LDA 用于分类
LDA 也可以直接作为分类器使用。
让我们来实现它:
lda_classifier = LinearDiscriminantAnalysis( )
lda_classifier. fit( X_train_scaled, y_train)
y_pred = lda_classifier. predict( X_test_scaled)
accuracy = accuracy_score( y_test, y_pred)
print ( f"Classification Accuracy: { accuracy: .4f } " )
print ( "\nClassification Report:" )
print ( classification_report( y_test, y_pred) ) 技术支持
我们根据训练数据训练一个模型来识别不同的小麦类别。随后在新的、未见过的样本上测试其表现,通过总体准确率以及对各类别的预测情况来评估。
输出如下:
LDA 分类结果。(作者供图)
该模型对小麦类型的预测准确率约为 92%,可视为表现良好。
该示例表明,尽管 LDA 常用于降维,但它也可以通过对各类别的概率分布进行建模,并将新数据分配给似然最高的类别,从而充当分类器。
用代码与可视化对比 LDA 与 PCA
主成分分析是另一种流行的降维技术,旨在寻找数据中方差最大的方向。
让我们在前面示例的基础上比较 LDA 与 PCA:
from sklearn.decomposition import PCA
pca = PCA( n_components= 2 )
X_train_pca = pca. fit_transform( X_train_scaled)
X_test_pca = pca. transform( X_test_scaled)
fig, ( ax1, ax2) = plt. subplots( 1 , 2 , figsize= ( 14 , 6 ) )
scatter1 = ax1. scatter( X_train_pca[ : , 0 ] , X_train_pca[ : , 1 ] ,
c= y_train, cmap= 'viridis' , alpha= 0.7 , edgecolor= 'k' )
ax1. set_xlabel( 'First Principal Component' )
ax1. set_ylabel( 'Second Principal Component' )
ax1. set_title( f'PCA Transformation\nExplained Variance: { pca. explained_variance_ratio_. sum ( ) : .2% } ' )
ax1. grid( True , alpha= 0.3 )
scatter2 = ax2. scatter( X_train_lda[ : , 0 ] , X_train_lda[ : , 1 ] ,
c= y_train, cmap= 'viridis' , alpha= 0.7 , edgecolor= 'k' )
ax2. set_xlabel( 'First Linear Discriminant' )
ax2. set_ylabel( 'Second Linear Discriminant' )
ax2. set_title( f'LDA Transformation\nExplained Variance: { lda. explained_variance_ratio_. sum ( ) : .2% } ' )
ax2. grid( True , alpha= 0.3 )
plt. colorbar( scatter1, ax= ax1, label= 'Wheat Variety' )
plt. colorbar( scatter2, ax= ax2, label= 'Wheat Variety' )
plt. tight_layout( )
plt. show( ) 技术支持
我们得到如下图:
LDA 与 PCA 对比。(作者供图)
左图展示使用 PCA 后的数据,它寻找的是捕获数据整体方差最大的方向。右图展示使用 LDA 的结果,它寻找的是最能区分小麦类别的方向。
基于我们的实现结果与解释方差数值,可以得出结论:尽管两者表现都不错,但对这样的分类问题而言,LDA 通常能产生更清晰的群组分离。
LDA 与其他降维技术的显著区别在于其监督式特性。PCA 在不考虑类别标签的情况下仅关注数据方差,而 LDA 明确利用类别信息寻找最具判别力的方向。当处理高维数据且类别可分性比保留整体方差更重要时,这一点尤为理想。
因此,PCA 适用于以下情形:
需要无监督的降维
类别标签不可用或不相关
希望可视化高维数据
需要降低噪声与计算复杂度
类似地,LDA 适用于:
拥有带标签数据并希望最大化类别分离
每个类别的样本量充足(通常 > 30)
同时需要降维与分类
类别判别性比保留整体方差更重要
LDA 的优缺点
与任何算法一样,LDA 也有其优点与局限性,在项目中应用前需要加以权衡。
优点
监督学习优势 :不同于 PCA,LDA 使用类别标签信息来寻找最具判别性的特征,更适合分类任务。
降维与分类二合一 :既能降维,又提供内置分类器。
计算高效 :仅需进行特征值分解,对中等规模数据集也较为快速。
可解释性强 :线性判别向量可解释为原始特征的加权组合。
对高斯分布最优 :当各类别服从具有相同协方差矩阵的高斯分布时,提供最优线性分类器。
无需超参数调优 :与许多机器学习算法不同,基础实现的 LDA 无需调整超参数。
缺点
仅限线性边界 :无法捕捉特征与类别之间的非线性关系。
高斯与等协方差假设 :假设每个类别服从多元高斯分布,这在真实数据中未必成立;并假设所有类别具有相同的协方差矩阵,而实践中常被违背。
分量数受限 :至多可提取(n_classes — 1)个判别分量,对于多类别问题的可视化可能不足。
对离群点与多重共线性敏感 :均值与协方差的计算对离群点敏感;当特征高度相关时,算法表现可能不佳。
样本量要求 :需要每个类别有足够样本,才能可靠地估计协方差矩阵。
理解这些权衡能帮助我们判断 LDA 是否是手头问题的最佳选择。
结论
本文介绍了线性判别分析,这是一种通过最大化类间与类内散度之比,将降维与 分类相结合的监督式技术。
我们探讨了 LDA 的数学基础,使用 Python 实现了该方法,并与 PCA 进行了比较,以了解各自更适用的场景。我们还了解了 LDA 的实际应用,并讨论了它的优点与局限。
若想进一步加深对 LDA 及相关机器学习技术的理解,建议报名我们的Python 监督式机器学习 学习路径,系统掌握多种算法及其实现;或参加我们的Python 中的降维 课程,更深入学习监督与无监督的降维技术。
在降维领域,线性判别分析(LDA)常常被更为流行的主成分分析(PCA)所掩盖。然而,LDA 提供了 PCA 无法做到的独特能力:它在降维的同时优化类别可分性。
本教程将向您介绍 LDA、其背后的数学直觉以及该技术的实际应用。我们还将把 LDA 应用于一个数据集,与 PCA 进行比较,分析其优劣势,旨在为您提供在下一个项目中开始使用 LDA 所需的一切。
线性判别分析(LDA)简介
在假设不同类别的数据分别来自不同的高斯分布的前提下,LDA 是一种降维与分类技术。
LDA 的目标是找到能最好地区分这些类别的特征线性组合。它最大化类间散度与类内散度的比值。通俗地说,它试图在特征空间中找到使不同类别彼此相距更远(高类间散度)、同一类别内部点彼此更接近(低类内散度)的方向。
这种双重目标使 LDA 在降维与分类任务中都格外有效。
LDA 背后的数学
理解 LDA 的数学原理需要将算法分解为三个关键组成部分:
类内散度矩阵(Sw)
类内散度矩阵衡量每个类别内部数据点的分散程度。
对于每个类别i,我们计算散度矩阵 Si 为:
其中 x 表示类别 i 中的每个数据点,μi 是类别 i 的均值。总的类内散度矩阵为:
类间散度矩阵(Sb)
类间散度矩阵衡量各类别均值与整体均值之间的距离。其计算方式为:
其中 Ni 是类别 i 的样本数,μi 是类别 i 的均值,μ 是所有数据的整体均值。
优化目标
LDA 旨在找到使 Fisher 准则最大化的投影矩阵 W:
本质上,这是在投影空间中最大化类间散度与类内散度之比。其解涉及求矩阵 Sw-1Sb 的特征向量,即得到最佳区分类别的方向(线性判别向量)。
因此,LDA 将这一复杂的优化问题转化为特征值分解,从而在中等高维数据集上也具有计算效率。
在理解了 LDA 的概念与数学直觉后,接下来看看它的实际应用。
LDA 的真实世界应用
在需要分类与降维的多个领域,LDA 都有所应用:
在 Python 中实现 LDA
让我们通过一个端到端示例,使用 Python 实现 LDA。
我们将使用 Seeds 数据集,可从UCI 库以及Kaggle下载。该数据集包含属于三种不同小麦品种的小麦籽粒测量值。
步骤 1:导入库并加载数据
首先,我们导入必要的库并加载数据集:
我们将在下方查看已加载数据集的前 5 行:
步骤 2:数据预处理
探索数据结构并为 LDA 分析做准备:
这里我们检查数据集中是否存在缺失值,并查看每个类别包含多少样本。随后通过将输入与标签分离、划分训练集与测试集,并对输入值进行标准化,使所有特征处于相近量纲,为后续建模做准备。
数据预处理。(作者供图)
可以看到不存在缺失值,且类别分布均衡。
步骤 3:应用 LDA 进行降维
现在我们将应用 LDA,在保留类别可分性的同时降低数据维度:
我们创建一个模型来寻找最佳方向,以分离数据中的不同类别。由于有三个类别,将数据降至两个新特征,可以保留区分它们的最重要模式。
输出如下:
该输出展示了由 LDA 生成的两个新特征分别捕获了多少类别分离信息:
步骤 4:可视化 LDA 变换
让我们可视化 LDA 如何变换数据并分离各类别:
上述代码创建了两个并排的图表,帮助我们对比应用降维技术前后数据的变化,如下所示:
第一个图使用两项原始测量特征(面积与周长)展示数据,以观察类别在原空间中的天然分离程度。第二个图展示了将数据变换到最有利于类别分离的方向后的结果。我们添加了颜色条来指示不同颜色对应的小麦品种。
步骤 5:将 LDA 用于分类
LDA 也可以直接作为分类器使用。
让我们来实现它:
我们根据训练数据训练一个模型来识别不同的小麦类别。随后在新的、未见过的样本上测试其表现,通过总体准确率以及对各类别的预测情况来评估。
输出如下:
LDA 分类结果。(作者供图)
该模型对小麦类型的预测准确率约为 92%,可视为表现良好。
该示例表明,尽管 LDA 常用于降维,但它也可以通过对各类别的概率分布进行建模,并将新数据分配给似然最高的类别,从而充当分类器。
用代码与可视化对比 LDA 与 PCA
主成分分析是另一种流行的降维技术,旨在寻找数据中方差最大的方向。
让我们在前面示例的基础上比较 LDA 与 PCA:
from sklearn.decomposition import PCA
我们得到如下图:
左图展示使用 PCA 后的数据,它寻找的是捕获数据整体方差最大的方向。右图展示使用 LDA 的结果,它寻找的是最能区分小麦类别的方向。
基于我们的实现结果与解释方差数值,可以得出结论:尽管两者表现都不错,但对这样的分类问题而言,LDA 通常能产生更清晰的群组分离。
LDA 与其他降维技术的显著区别在于其监督式特性。PCA 在不考虑类别标签的情况下仅关注数据方差,而 LDA 明确利用类别信息寻找最具判别力的方向。当处理高维数据且类别可分性比保留整体方差更重要时,这一点尤为理想。
因此,PCA 适用于以下情形:
类似地,LDA 适用于:
LDA 的优缺点
与任何算法一样,LDA 也有其优点与局限性,在项目中应用前需要加以权衡。
优点
缺点
理解这些权衡能帮助我们判断 LDA 是否是手头问题的最佳选择。
结论
本文介绍了线性判别分析,这是一种通过最大化类间与类内散度之比,将降维与分类相结合的监督式技术。
我们探讨了 LDA 的数学基础,使用 Python 实现了该方法,并与 PCA 进行了比较,以了解各自更适用的场景。我们还了解了 LDA 的实际应用,并讨论了它的优点与局限。
若想进一步加深对 LDA 及相关机器学习技术的理解,建议报名我们的Python 监督式机器学习学习路径,系统掌握多种算法及其实现;或参加我们的Python 中的降维课程,更深入学习监督与无监督的降维技术。