三个主要降维技术对比介绍:PCA, LCA,SVD

news2024/12/23 22:58:20

随着数据集的规模和复杂性的增长,特征或维度的数量往往变得难以处理,导致计算需求增加,潜在的过拟合和模型可解释性降低。降维技术提供了一种补救方法,它捕获数据中的基本信息,同时丢弃冗余或信息较少的特征。这个过程不仅简化了计算任务,还有助于可视化数据趋势,减轻维度诅咒的风险,并提高机器学习模型的泛化性能。降维在各个领域都有应用,从图像和语音处理到金融和生物信息学,在这些领域,从大量数据集中提取有意义的模式对于做出明智的决策和建立有效的预测模型至关重要。

本文将深入研究三种强大的降维技术——主成分分析(PCA)、线性判别分析(LDA)和奇异值分解(SVD)。我们不仅介绍这些方法的基本算法,而且提供各自的优点和缺点。

主成分分析(PCA)

主成分分析(PCA)是一种广泛应用于数据分析和机器学习的降维技术。它的主要目标是将高维数据转换为低维表示,捕获最重要的信息。

我们的目标是识别数据集中的模式,所以希望数据分布在每个维度上,并且在这些维度之间是有独立性的。方差作为可变性的度量标准,本质上量化了数据集分散的程度。用数学术语来说,它表示与平均的平均平方偏差。计算方差的公式用var(x)表示如下:

协方差量化了两组有序数据中对应元素相似的程度。用cov(x, y)表示变量x和y之间的协方差。xi表示第i维中x的值,而x柱和y柱表示它们各自的平均值。如果我们有一个维数为m*n的矩阵X,其中包含n个数据点,每个数据点有m维,那么协方差矩阵可以计算如下:

协方差矩阵包括

  1. 以尺寸方差为主要对角线元素
  2. 维度的协方差作为非对角线元素

我们的目标是确保数据广泛分散,表明其维度之间的高方差,另外一个目标是消除相关维度,这意味着维度之间的协方差应为零(表明它们的线性无关)。所以对数据进行变换的目的是使其协方差矩阵具有以下特征:

  1. 作为主要对角线元素的显著值。
  2. 零值作为非对角线元素。

所以必须对原始数据点进行变换获得类似于对角矩阵的协方差矩阵。将矩阵转换成对角矩阵的过程称为对角化,它构成了主成分分析(PCA)背后的主要动机。

PCA的工作原理

1、标准化

当特征以不同的单位度量时,对数据进行标准化。这需要减去平均值,然后除以每个特征的标准差。对具有不同尺度特征的数据进行标准化的失败可能导致误导性的成分。

2、计算协方差矩阵

如前面讨论的那样计算协方差矩阵

3、计算特征向量和特征值

确定协方差矩阵的特征向量和特征值。

特征向量表示方向(主成分),特征值表示这些方向上的方差大小。

4、特征值排序

对特征值按降序排序。与最高特征值相对应的特征向量是捕获数据中最大方差的主成分。

5、选择主成分

根据需要解释的方差选择前k个特征向量(主成分)。一般情况下会设定阈值,保留总方差的很大一部分,例如85%。

6、转换数据

我们可以用特征向量变换原始数据:

如果我们有m维的n个数据点X: m*n

P: k*m

Y = PX: (km)(mn) = (k*n)

新变换矩阵有n个数据点,有k维。

优点

降维:PCA有效地减少了特征的数量,这对遭受维数诅咒的模型是有益的。

特征独立性:主成分是正交的(不相关的),这意味着它们捕获独立的信息,简化了对约简特征的解释。

降噪:PCA可以通过专注于解释数据中最显著方差的成分来帮助减少噪声。

可视化:降维数据可以可视化,有助于理解底层结构和模式。

缺点

原始特征的可解释性可能在变换后的空间中丢失,因为主成分是原始特征的线性组合。

PCA假设变量之间的关系是线性的,但并非在所有情况下都是如此。

PCA对特征的尺度比较敏感,因此常常需要标准化。

异常值可以显著影响PCA的结果,因为它侧重于捕获最大方差,这可能受到极值的影响。

何时使用

高维数据:PCA在处理具有大量特征的数据集以减轻维度诅咒时特别有用。

共线的特点:当特征高度相关时,PCA可以有效地捕获共享信息并用更少的组件表示它。

可视化:它将数据投射到一个较低维度的空间,可以很容易地可视化。

线性关系:当变量之间的关系大多是线性的,主成分分析是一个合适的技术。

Python代码示例

 import numpy as np
 from sklearn.decomposition import PCA
 from sklearn.preprocessing import StandardScaler
 from sklearn.model_selection import train_test_split
 from sklearn.datasets import load_iris
 
 # Load iris dataset as an example
 iris = load_iris()
 X = iris.data
 y = iris.target
 
 # Split the dataset into training and testing sets
 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
 
 # Standardize the data (important for PCA)
 scaler = StandardScaler()
 X_train_std = scaler.fit_transform(X_train)
 X_test_std = scaler.transform(X_test)
 
 # Apply PCA
 pca = PCA()
 X_train_pca = pca.fit_transform(X_train_std)
 
 # Calculate the cumulative explained variance
 cumulative_variance_ratio = np.cumsum(pca.explained_variance_ratio_)
 
 # Determine the number of components to keep for 85% variance explained
 n_components = np.argmax(cumulative_variance_ratio >= 0.85) + 1
 
 # Apply PCA with the selected number of components
 pca = PCA(n_components=n_components)
 X_train_pca = pca.fit_transform(X_train_std)
 X_test_pca = pca.transform(X_test_std)
 
 # Display the results
 print("Original Training Data Shape:", X_train.shape)
 print("Reduced Training Data Shape (PCA):", X_train_pca.shape)
 print("Number of Components Selected:", n_components)

上面代码在最初应用PCA()时没有指定组件的数量,这意味着它将保留所有组件。然后使用np.cumsum(pca.explained_variance_ratio_)计算累计解释方差。确定解释至少85%方差所需的分量数,并使用选定的分量数再次应用PCA。请注意PCA只应用于训练数据,然后在测试数据应用转换方法即可。

线性判别分析(LDA)

线性判别分析(LDA)作为一种降维和分类技术,目标是优化数据集中不同类别之间的区别。LDA在预先确定数据点类别的监督学习场景中特别流行。PCA被认为是一种“无监督”算法,它忽略了类标签,专注于寻找主成分以最大化数据集方差,而LDA则采用“监督”方法。LDA计算“线性判别器”,确定作为轴的方向,以最大限度地分离多个类。我们这里使用“Iris”数据集的示例来了解LDA是如何计算的。它包含了来自三个不同物种的150朵鸢尾花的尺寸。

Iris数据集中有三个类:

  • Iris-setosa (n=50)
  • Iris-versicolor (n=50)
  • Iris-virginica (n=50)

有四个特征:

  • sepal length in cm
  • sepal width in cm
  • petal length in cm
  • petal width in cm

LDA的工作步骤

1、计算三种不同花类的平均向量mi, (i=1,2,3):

 Mean Vector class 1: [ 5.006  3.418  1.464  0.244]
 
 Mean Vector class 2: [ 5.936  2.77   4.26   1.326]
 
 Mean Vector class 3: [ 6.588  2.974  5.552  2.026]

每个向量包含特定类的数据集中4个特征的平均值。

2、计算类内散点矩阵(Sw),它表示每个类内数据的分布

结果如下:

 within-class Scatter Matrix:
  [[ 38.9562  13.683   24.614    5.6556]
  [ 13.683   17.035    8.12     4.9132]
  [ 24.614    8.12    27.22     6.2536]
  [  5.6556   4.9132   6.2536   6.1756]]

3、计算类间散点矩阵(Sb), Sb表示不同类之间的分布,公式如下:

结果如下:

 between-class Scatter Matrix:
  [[  63.2121  -19.534   165.1647   71.3631]
  [ -19.534    10.9776  -56.0552  -22.4924]
  [ 165.1647  -56.0552  436.6437  186.9081]
  [  71.3631  -22.4924  186.9081   80.6041]]

4、计算Sw-¹Sb的特征值和特征向量(类似于PCA)。在我们的例子中,有4个特征值和特征向量

 Eigenvector 1:
 [[-0.2049]
  [-0.3871]
  [ 0.5465]
  [ 0.7138]]
 Eigenvalue 1: 3.23e+01
 
 Eigenvector 2:
 [[-0.009 ]
  [-0.589 ]
  [ 0.2543]
  [-0.767 ]]
 Eigenvalue 2: 2.78e-01
 
 Eigenvector 3:
 [[ 0.179 ]
  [-0.3178]
  [-0.3658]
  [ 0.6011]]
 Eigenvalue 3: -4.02e-17
 
 Eigenvector 4:
 [[ 0.179 ]
  [-0.3178]
  [-0.3658]
  [ 0.6011]]
 Eigenvalue 4: -4.02e-17

5、通过减少特征值对特征向量进行排序,并选择最上面的k。

通过减少特征值对特征对进行排序后,基于2个信息量最大的特征对构建d×k维度特征向量矩阵(称之为W)。在下面的例子中,得到了下面的矩阵:

 Matrix W:
  [[-0.2049 -0.009 ]
  [-0.3871 -0.589 ]
  [ 0.5465  0.2543]
  [ 0.7138 -0.767 ]]

6、使用矩阵W (4 × 2矩阵)通过方程将样本转换到新的子空间:Y = X*W,其中X是矩阵格式的原始数据(150 × 4矩阵),Y是转换后的数据集(150 × 2矩阵)。

优点

最大化类分离:LDA的目的是最大限度地分离不同的类,使其有效的分类任务。

降维:与PCA一样,LDA也可用于降维,其优点是考虑了类信息。

缺点

对异常值的敏感性:LDA对异常值非常敏感,异常值的存在会影响方法的性能。

正态性假设:LDA假设每个类中的特征是正态分布的,如果违反了这个假设,它可能无法很好地执行。

需要足够的数据:LDA在每个类只有少量样本的情况下可能表现不佳。拥有更多的样本可以改善类参数的估计。

何时使用

分类任务:当目标是将数据分类到预定义的类中时,LDA是有益的。

保存类信息:当目标是在降低维数的同时保留与区分类相关的信息时,LDA非常有用

正态性假设成立:当类别内的正态分布假设成立时,LDA表现良好。

监督降维:当任务需要在类标签的指导下进行降维时,LDA是一个合适的选择。

Python代码示例

 import numpy as np
 import pandas as pd
 from sklearn.model_selection import train_test_split
 from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
 from sklearn.datasets import make_classification
 from sklearn.preprocessing import StandardScaler
 
 # Generate a sample dataset
 X, y = make_classification(n_samples=1000, n_features=20, n_classes=2, random_state=42)
 
 # Split the data into training and test sets
 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
 
 # Standardize the features (important for LDA)
 scaler = StandardScaler()
 X_train = scaler.fit_transform(X_train)
 X_test = scaler.transform(X_test)
 
 # Initialize LDA and fit on the training data
 lda = LinearDiscriminantAnalysis()
 X_train_lda = lda.fit_transform(X_train, y_train)
 
 # Calculate explained variance ratio for each component
 explained_variance_ratio = lda.explained_variance_ratio_
 
 # Calculate the cumulative explained variance
 cumulative_explained_variance = np.cumsum(explained_variance_ratio)
 
 # Find the number of components that explain at least 75% of the variance
 n_components = np.argmax(cumulative_explained_variance >= 0.75) + 1
 
 # Transform both the training and test data to the selected number of components
 X_train_lda_selected = lda.transform(X_train)[:, :n_components]
 X_test_lda_selected = lda.transform(X_test)[:, :n_components]
 
 # Print the number of components selected
 print(f"Number of components selected: {n_components}")
 

奇异值分解(SVD)

奇异值分解是一种矩阵分解技术,广泛应用于线性代数、信号处理和机器学习等领域。它将一个矩阵分解成另外三个矩阵,原始矩阵以简化形式表示。

SVD的工作步骤

1、矩阵分解

给定大小为M × n的矩阵M(或有M行n列的数据),奇异值分解将其分解为三个矩阵:M = u *Σ * v *

其中U是一个m × m正交矩阵,Σ是一个m × r对角矩阵,V是一个r × n正交矩阵。r是矩阵M的秩。

Σ的对角线元素为原矩阵M的奇异值,按降序排列。U的列是m的左奇异向量,这些向量构成了m的列空间的正交基,V的列是m的右奇异向量,这些向量构成了m的行空间的正交基。

2、简化形式(Truncated SVD)

对于降维,通常使用截断版本的奇异值分解。选择Σ中前k个最大的奇异值。这些列可以从Σ中选择,行可以从V * *中选择。由原矩阵M重构出一个新的矩阵B,公式如下:

B = u * Σ,B = V * A

其中Σ只包含原始Σ中奇异值的前k列,V包含原始V中奇异值对应的前k行。

优点

降维:SVD允许通过只保留最重要的奇异值和向量来降低维数。

数据压缩:SVD用于数据压缩任务,减少了矩阵的存储需求。

降噪:通过只使用最显著的奇异值,奇异值分解可以帮助减少数据中噪声的影响。

数值稳定性:奇异值分解在数值上是稳定的,适合于求解病态系统中的线性方程。

正交性:SVD分解中的矩阵U和V是正交的,保留了原矩阵的行与列之间的关系。

推荐系统中的应用:奇异值分解广泛应用于推荐系统的协同过滤。

缺点

计算复杂度:计算大型矩阵的完整SVD在计算上是非常昂贵的。

内存需求:存储完整的矩阵U、Σ和V可能会占用大量内存,特别是对于大型矩阵。

对缺失值的敏感性:SVD对数据中的缺失值很敏感,处理缺失值需要专门的技术。

何时使用

降维:当目标是在保留数据基本结构的同时降低数据的维数时。

推荐系统:在基于协同过滤的推荐系统中,SVD用于识别捕获用户-物品交互的潜在因素。

数据压缩:在需要压缩或近似大型数据集的场景中。

信号处理:在信号处理中,采用奇异值分解进行降噪和特征提取。

主题建模:SVD被用于主题建模技术,如潜在语义分析(LSA)。

Python代码示例

 import numpy as np
 from sklearn.model_selection import train_test_split
 from sklearn.decomposition import TruncatedSVD
 from sklearn.datasets import make_classification
 from sklearn.preprocessing import StandardScaler
 
 # Generate a sample dataset
 X, y = make_classification(n_samples=1000, n_features=20, n_classes=2, random_state=42)
 
 # Split the data into training and test sets
 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
 
 # Standardize the features (important for SVD)
 scaler = StandardScaler()
 X_train = scaler.fit_transform(X_train)
 X_test = scaler.transform(X_test)
 
 # Initialize SVD and fit on the training data
 svd = TruncatedSVD(n_components=X_train.shape[1] - 1)  # Use one less component than the feature count
 X_train_svd = svd.fit_transform(X_train)
 
 # Calculate explained variance ratio for each component
 explained_variance_ratio = svd.explained_variance_ratio_
 
 # Calculate the cumulative explained variance
 cumulative_explained_variance = np.cumsum(explained_variance_ratio)
 
 # Find the number of components that explain at least 75% of the variance
 n_components = np.argmax(cumulative_explained_variance >= 0.75) + 1
 
 # Transform both the training and test data to the selected number of components
 X_train_svd_selected = svd.transform(X_train)[:, :n_components]
 X_test_svd_selected = svd.transform(X_test)[:, :n_components]
 
 # Print the number of components selected
 print(f"Number of components selected: {n_components}")

总结

在主成分分析(PCA)、线性判别分析(LDA)和奇异值分解(SVD)之间的选择取决于数据的具体目标和特征。以下是关于何时使用每种技术的一般指导原则:

主成分分析:

  1. 当目标是降低数据集的维数时。
  2. 在捕获数据中的全局模式和关系至关重要的场景中。
  3. 用于探索性数据分析和可视化。

线性判别分析:

  1. 在分类问题中,增强类之间的分离。
  2. 当有一个标记的数据集时,目标是找到一个最大化阶级歧视的投影。
  3. 当正态分布类和等协方差矩阵的假设成立时,LDA特别有效。

奇异值分解:

  1. 当处理稀疏数据或缺失值时。
  2. 推荐系统的协同过滤。
  3. 奇异值分解也适用于数据压缩和去噪。

三个技术的对比:

无监督vs有监督学习:PCA是无监督的,而LDA是有监督的。根据标记数据的可用性进行选择。

类可分离性:如果目标是改进类可分离性,那么首选LDA。PCA和SVD关注的是总体方差。

数据特征:数据的特征,如线性、类别分布和异常值的存在,会影响选择。

特定于应用程序的需求:考虑应用程序的特定需求,例如可解释性、计算效率或对丢失数据的处理。

综上所述,PCA适用于无监督降维,LDA适用于关注类可分性的监督问题,而SVD具有通用性,可用于包括协同过滤和矩阵分解在内的各种应用。

https://avoid.overfit.cn/post/271ccd73554a40309d4539b2d5c568b6

作者:Indraneel Dutta Baruah

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1073871.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

11-Webpack模块打包工具

01.什么是 Webpack 目标 了解 Webpack 的概念和作用,以及使用 讲解 Webpack 是一个静态模块打包工具,从入口构建依赖图,打包有关的模块,最后用于展示你的内容 静态模块:编写代码过程中的,html&#xf…

Git分支教程:详解分支创建、合并、删除等操作

GIT分支是Git中用于开发和管理代码的重要概念之一。每个分支都是一个独立的代码版本,可以在分支上进行修改和提交,而不影响主线(通常是master分支)上的开发工作。 分支的作用: 并行开发:多个开发人员可以…

vue3学习(一)---新特性

文章目录 vue3和vue2的区别重写双向数据绑定优化Vdom性能瓶颈patch flag 优化静态树 FragmentTree shaking组合式API写法 vue3和vue2的区别 重写双向数据绑定 vue2 基于Object.defineProperty()实现vue3 基于Proxy proxy与Object.defineProperty(obj, prop, desc)方式相比有以…

bootstrapjs开发环境搭建

Bootstrapjs是一个web前端页面应用开发框架,其提供功能丰富的JavaScript工具集以及用户界面元素或组件的样式集,本文主要描述bootstrapjs的开发环境搭建。 如上所示,使用nodejs运行时环境、使用npm包管理工具、使用npm初始化一个项目工程test…

直流无刷电机简介

一、 简介 直流无刷电机(简称BLDC)是随着半导体电子技术发展而出现的机电一体化电机,是永磁式同步电机的一种。 直流无刷电机与直流有刷电机的区别:直流有刷电机利用电枢绕组旋转换向;直流无刷电机是采用半导体开关器…

全局变量报错:\Output\STM32.axf: Error: L6218E: Undefined symbol

全局变量报错: .\Output\STM32.axf: Error: L6218E: Undefined symbol key_num (referred from main.o). 这里只说全局变量哦,这是因为你在调用的.c文件里 把定义写在了函数里面,写函数外面就没事了 改为: .h的声明文件根本不用写…

openGauss学习笔记-94 openGauss 数据库管理-访问外部数据库-mysql_fdw

文章目录 openGauss学习笔记-94 openGauss 数据库管理-访问外部数据库-mysql_fdw94.1 编译mysql_fdw94.2 使用mysql_fdw94.3 常见问题94.4 注意事项 openGauss学习笔记-94 openGauss 数据库管理-访问外部数据库-mysql_fdw openGauss的fdw实现的功能是各个openGauss数据库及远程…

vue3中的父子组件传递slot的方式

缘起 目前的 vue3 工程,有处相似的地方,上面是一个 a-step 组件,下面是一个 vxetable 的组件,目前有好几处都是各自复制这两个组件,进行各自的处理。所以就要把这处,改成一个组件,供小伙伴们使用…

什么是列间空调?

列间空调(Chilled Beam Air Conditioning System)是一种先进的空调系统,用于办公室和商业建筑等高要求的室内空间。这种系统采用创新的工作原理,结合空气对流和辐射的方式,提供高效的舒适空调效果。 列间空调系统的工作…

从零开始读懂相对论:探索爱因斯坦的科学奇迹

💂 个人网站:【工具大全】【游戏大全】【神级源码资源网】🤟 前端学习课程:👉【28个案例趣学前端】【400个JS面试题】💅 寻找学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】 引言 阿尔伯特爱因斯坦…

STM32 Cube项目实战开发过程中--调用Freemodbus通信出现异常问题原因分析--ADC DMA初始化顺序导致串口数据异常问题解决办法

文章目录 1.ADC与DMA初始化顺序导致使用Freemodbus串口通信异常:2.通信异常时串口初始化的顺序为:3.重新调整初始化位置后,通信问题解决:5.重新调整初始化位置后,通信正常:总结:Cube开发库系统默…

利用KerasCV YOLOv8轻松实现目标精确检测

本文中将实现基于KerasCV YOLOv8的交通灯信号检测,并附录完整代码。。 自从You Only Look Once(简称 YOLO)的诞生以来,目标检测问题主要通过深度学习来解决。大多数深度学习架构通过巧妙地将目标检测问题构建为多个小分类问题和回归问题的组合来实现。具体而言,它是通过在…

手动快速批量修改文件名

方法一 1.选中需要批量修改的文件,如图1 图1 2.按F2键,输入文件名。如图2. 图2 3.Enter,效果如图3. 图3 方法二 1.新建记事本文档,输入如下代码。如图4. DIR . /B>文件名列表.csv 含义是:提取出带有“.”的文…

06-Zookeeper选举Leader源码剖析(一)

上一篇:05-Zookeeper典型使用场景实战 一、为什么要看源码 提升技术功底:学习源码里的优秀设计思想,比如一些疑难问题的解决思路,还有一些优秀的设计模式,整体提升自己的技术功底深度掌握技术框架:源码看…

完美解决Android adb install 安装提示 INSTALL_FAILED_TEST_ONLY

完美解决Android adb install 安装提示 INSTALL_FAILED_TEST_ONLY 目录 所遇问题 有些时候我们用命令进行安装apk如下: adb install xxx.apk但是会安装不成功,报如下错误: 错误现象:提示:Failed to install app-d…

【Go】Fyne跨平台图形界面框架使用

😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍Fyne跨平台图形界面框架使用。 学其所用,用其所学。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,下次更新…

文本编辑器去除PDF水印

用文本编辑器打开pdf,搜索水印的特殊文字,全部替换。 另外一个水印字母间有空格。 替换完后保存。 重新打开pdf:

国产麒麟V10桌面操作系统上运行WinForm程序

将需要运行的程序拷贝到系统中,如图: 选择exe后点击鼠标右键,选择打开方式,然后选择CrossOver(安装),如图: 打开CrossOver 软件安装程序后,点击选择容器,然后选择Windows 10 容器…

交互式ICP

以下程序演示如何编写交互式ICP查看器。该程序将加载点云并对其进行刚性变换。之后&#xff0c;使用ICP算法将变换后的点云与原来的点云对齐。每次用户按下“空格”&#xff0c;进行ICP迭代&#xff0c;刷新可视化界面。 代码实现 资源准备 monkey.ply #include <string&…

用Python简单的实现一下六大主流小说平台小说下载(附源码)

很多小伙伴学习Python的初衷就是为了爬取小说&#xff0c;方便又快捷~ 辣么今天咱们来分享6个主流小说平台的爬取教程~ 一、流程步骤 流程基本都差不多&#xff0c;只是看网站具体加密反爬&#xff0c;咱们再进行解密。 实现爬虫的第一步? 1、去抓包分析&#xff0c;分析数…