一、说明
降维在数据分析和机器学习中发挥着关键作用,为高维数据集带来的挑战提供了战略解决方案。随着数据集规模和复杂性的增长,特征或维度的数量通常变得难以处理,导致计算需求增加、潜在的过度拟合和模型可解释性降低。降维技术通过捕获数据中的基本信息同时丢弃冗余或信息量较少的特征来提供补救措施。这一过程不仅简化了计算任务,还有助于可视化数据趋势,减轻维数灾难的风险,并提高机器学习模型的泛化性能。降维在从图像和语音处理到金融和生物信息学等各个领域都有应用,其中从大量数据集中提取有意义的模式对于做出明智的决策和构建有效的预测模型至关重要。
在本博客中,我们将深入研究三种强大的降维技术——主成分分析(PCA)、线性判别分析(LDA)和奇异值分解(SVD)。我们的探索不仅会阐明这些方法的底层算法,还会提供它们各自的优缺点。我们将结合理论讨论和 Python 的实际实现,提供将 PCA、LDA 和 SVD 应用到现实世界数据集的实践指导。无论您是寻求降维介绍的新手,还是希望增强理解的经验丰富的从业者,这个博客都是为了满足各个级别的专业知识而精心设计的。
二、主成分分析(PCA)
主成分分析(PCA)是一种广泛应用于数据分析和机器学习的降维技术。其主要目标是将高维数据转换为低维表示,捕获最重要的信息。
2.1 以下是 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 : (k*m)(m*n) = (k*n)
因此,我们新的变换矩阵有 n具有 k 维的数据点。
2.2 优点:
1.降维:
PCA有效地减少了特征数量,这对于遭受维数灾难的模型是有利的。
2. 特征独立性:
主成分是正交的(不相关的),这意味着它们捕获独立的信息,简化了对简化特征的解释。
3. 降噪:
PCA 可以通过关注解释数据中最显着方差的成分来帮助降低噪声。
4. 可视化:
降维数据可以可视化,有助于理解底层结构和模式。
2.3 缺点:
1. 可解释性的损失:
原始特征的可解释性可能会在变换后的空间中丢失,因为主成分是原始特征的线性组合。
2. 线性假设:
PCA 假设变量之间的关系是线性的,但并非在所有情况下都是如此。
3.对尺度敏感:
PCA对特征的尺度敏感,因此通常需要标准化。
4. 异常值影响结果:
异常值可以显着影响 PCA 的结果,因为它侧重于捕获最大方差,这可能会受到极值的影响。
2.4 何时使用:
1. 高维数据:
PCA 在处理具有大量特征的数据集以减轻维数灾难时特别有用。
2.共线特征:
当特征高度相关时,PCA可以有效地捕获共享信息并用更少的组件来表示它。
3. 可视化:
当高维数据可视化具有挑战性时,PCA 很有用。它将数据投影到可以轻松可视化的低维空间中。
5.线性关系:
当变量之间的关系大部分是线性时,PCA是一种合适的技术。
2.5 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 计算“线性判别式”,确定作为轴的方向,以最大化多个类之间的分离。为了深入研究 LDA 的工作原理,让我们使用UCI 机器学习存储库中著名的“Iris”数据集的示例来了解如何计算 LDA 。它包含来自三个不同品种的 150 朵鸢尾花的测量值。
Iris 数据集中共有三个类:
- 山鸢尾 (n=50)
- 杂色鸢尾 (n=50)
- 弗吉尼亚鸢尾 (n=50)
Iris 数据集中有四个特征:
- 萼片长度(厘米)
- 萼片宽度(厘米)
- 花瓣长度(厘米)
- 花瓣宽度(厘米)
3.1 LDA的步骤:
- 我们将从计算 3 个不同花类的平均向量 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),它表示不同类之间的分布:
在我们的示例中,它将如下所示:
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-1Sb 的特征值和特征向量(类似于 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 X 2 矩阵)通过以下方程将样本转换到新的子空间:Y = X*W,其中 X 是矩阵格式的原始数据帧(在我们的例子中为 150 X 4 矩阵)并且Y 是转换后的数据集(150 X 2 矩阵)。请参阅此博客了解更多详细信息。
3.2 优点:
1.最大化类分离:
LDA旨在最大化不同类之间的分离,使其对分类任务有效。
2.降维:
与PCA一样,LDA可以用于降维,但具有考虑类信息的优点。
3.3 缺点:
1.对异常值的敏感性:
LDA对异常值敏感,异常值的存在会影响方法的性能。
2. 正态性假设:
LDA 假设每个类内的特征呈正态分布,如果违反此假设,LDA 可能表现不佳。
3. 需要足够的样本:当
每类样本数量较少时,LDA 可能表现不佳。拥有更多样本可以改善类参数的估计。
3.4 何时使用:
1. 分类任务
当目标是将数据分类到预定义的类别时,LDA 很有用。
2. 保留类别信息:
当目标是降低维度同时保留与区分类别相关的信息时。
3. 正态性假设成立:
当每个类内正态分布的假设有效时,LDA 表现良好。
4.有监督降维:
当任务需要在类标签的指导下进行降维时,LDA是一个合适的选择。
3.5 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}")
# Now, X_train_lda_selected and X_test_lda_selected can be used for further analysis or modeling
此示例使用make_classification
scikit-learn 中的函数生成合成数据集,然后将数据拆分为训练集和测试集。它标准化特征,初始化LDA模型,并将其拟合到训练数据中。最后,它根据解释的所需方差选择组件数量,并相应地转换训练和测试数据。
四、奇异值分解 (SVD)
奇异值分解是一种矩阵分解技术,广泛应用于各种应用,包括线性代数、信号处理和机器学习。它将一个矩阵分解为另外三个矩阵,允许以简化形式表示原始矩阵。这里解释了分解技术和证明。
4.1 SVD 的步骤:
1. 矩阵的分解
给定一个大小为 mxn 的矩阵 M(或 m 行 n 列的数据框),SVD 将其分解为三个矩阵:
M = U *Σ *Vᵗ,
其中 U 是 mxm 正交矩阵,Σ 是mxr 对角矩阵,V 是 rxn 正交矩阵。r是矩阵M的秩。Σ的
对角线元素是原始矩阵M的奇异值,并且它们按降序排列。U 的列是 M 的左奇异向量。这些向量形成 M 的列空间的正交基。V 的列是 M 的右奇异向量。这些向量形成 M 的行空间的正交基。请阅读本文以深入了解其背后的数学原理。
2. 简化形式(截断SVD)
对于降维,通常使用截断版本的SVD。选择 Σ 中前 k 个最大奇异值。这些列可以从 Σ 中选择,行可以从 Vᵗ 中选择。可以使用以下公式从原始矩阵 M 重建新矩阵 B:
B = U * Σ
B = Vᵗ * A,其中 Σ 仅包含原始 Σ 中基于奇异值的前 k 列,Vᵗ 包含原始 Vᵗ 中与奇异值对应的前 k 行。欲了解更多详情,您可以参考这里。
4.2 优点:
1. 降维
SVD 允许通过仅保留最重要的奇异值和向量来降维。
2.数据压缩
SVD用于数据压缩任务,减少矩阵的存储要求。
3. 降噪
通过仅使用最重要的奇异值,SVD 可以帮助减少数据中噪声的影响。
4. 数值稳定性
SVD 具有数值稳定性,非常适合求解病态系统中的线性方程。
5.正交性
SVD分解中的矩阵U和V是正交的,保留了原始矩阵的行和列之间的关系。
6.在推荐系统中的应用
SVD广泛应用于推荐系统的协同过滤中。
4.3 缺点:
1. 计算复杂性:
计算大型矩阵的完整 SVD 的计算成本可能很高。
2. 内存要求:
存储完整的矩阵 U、Σ 和 V 可能会占用大量内存,尤其是对于大型矩阵。
3. 对缺失值的敏感性:
SVD 对数据中的缺失值很敏感,处理缺失值需要专门的技术。
4.4 何时使用 SVD:
1. 降维:
当目标是降低数据的维度同时保留其基本结构时。
2. 推荐系统:
在基于协同过滤的推荐系统中,SVD 用于识别捕获用户-项目交互的潜在因素。
3.数据压缩:
在需要对大数据集进行压缩或近似的场景中。
4. 数值稳定性:
在求解病态系统中的线性方程时,SVD 提供数值稳定性。
5.信号处理:
在信号处理中,SVD用于降噪和特征提取。
6. 主题建模:
SVD 用于主题建模技术,例如潜在语义分析(LSA)。
4.5 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}")
# Now, X_train_svd_selected and X_test_svd_selected can be used for further analysis or modeling
此示例使用该make_classification
函数生成合成数据集,将数据拆分为训练集和测试集,并对特征进行标准化。然后,它初始化TruncatedSVD
模型,将其拟合到训练数据上,并根据所解释的所需方差选择组件的数量。最后,它相应地转换训练和测试数据。
五、结论
主成分分析 (PCA)、线性判别分析 (LDA) 和奇异值分解 (SVD) 之间的选择取决于数据的具体目标和特征。以下是有关何时使用每种技术的一般准则:
1. PCA(主成分分析)
用例:
1. 当目标是降低数据集的维度时。
2. 在捕获数据中的全局模式和关系至关重要的场景中。
3. 用于探索性数据分析和可视化。
2. LDA(线性判别分析)
用例:
1. 在分类问题中,增强类之间的分离很重要。
2. 当存在标记数据集时,目标是找到最大化类别区分度的投影。
3. 当类正态分布和协方差矩阵相等的假设成立时,LDA 特别有效。
3. SVD(奇异值分解)
用例:
1. 处理稀疏数据或缺失值时。
2. 在推荐系统的协同过滤中。
3. SVD也适用于数据压缩和去噪。
我们应该考虑以下因素:
无监督与监督学习:PCA 是无监督的,而 LDA 是有监督的。根据标记数据的可用性进行选择。
类可分离性:如果目标是提高类可分离性,则首选 LDA。PCA 和 SVD 关注整体方差。
数据特征:数据的特征(例如线性、类别分布和异常值的存在)会影响选择。
应用程序特定要求:考虑应用程序的特定要求,例如可解释性、计算效率或丢失数据的处理。
总之,PCA 适用于无监督降维,LDA 对于关注类可分离性的监督问题有效,而 SVD 用途广泛,适合各种应用,包括协同过滤和矩阵分解。选择取决于数据的性质和分析的目标。
您对此博客有任何疑问或建议吗?请随时留言。