6种使用Python实现的降维算法

降维是一种无监督学习技术。

然而,它可以作为机器学习算法在分类和回归预测建模数据集上的数据转换预处理步骤,用于监督学习算法。

有许多降维算法可供选择,没有一种算法适用于所有情况。相反,探索一系列降维算法和每种算法的不同配置是一个好主意。

在本教程中,您将了解如何在 Python 中拟合和评估顶级降维算法。

完成本教程后,您将了解:

  • 降维旨在找到数值输入数据的低维表示,同时保留数据中的重要关系。
  • 有许多不同的降维算法,没有一种方法适用于所有数据集。
  • 如何在 Python 中使用 scikit-learn 机器学习库实现、拟合和评估顶级降维。

立即开始您的项目,阅读我的新书《机器学习数据准备》,其中包含分步教程和所有示例的Python源代码文件。

让我们开始吧。

Dimensionality Reduction Algorithms With Python

Python 降维算法
照片来源:Bernard Spragg. NZ,部分权利保留。

教程概述

本教程分为三个部分;它们是:

  1. 降维
  2. 降维算法
  3. 降维示例
    1. Scikit-Learn 库安装
    2. 分类数据集
    3. 主成分分析
    4. 奇异值分解
    5. 线性判别分析
    6. Isomap 嵌入
    7. 局部线性嵌入
    8. 改进型局部线性嵌入

降维

降维是指在训练数据中减少输入变量数量的技术。

在处理高维数据时,通过将数据投影到捕获数据“本质”的低维子空间来降低维度通常很有用。这被称为降维。

— 第 11 页,《机器学习:概率视角》,2012 年。

高维度可能意味着有数百、数千甚至数百万个输入变量。

更少的输入维度通常意味着更少的参数或更简单的机器学习模型结构,这被称为自由度。具有过多自由度的模型很可能过拟合训练数据集,并且在新数据上的表现可能不佳。

理想的模型应具有泛化能力强且简洁的特点,反过来,输入数据应具有较少的输入变量。这对于线性模型尤其重要,因为输入数量和模型自由度通常密切相关。

降维是在建模之前对数据执行的数据准备技术。它可能在数据清理和数据缩放之后,在训练预测模型之前执行。

……降维技术能够产生更紧凑、更易于解释的目标概念表示,并将用户的注意力集中在最相关的变量上。

— 第 289 页,《数据挖掘:实用机器学习工具和技术》,第 4 版,2016 年。

因此,在训练数据上进行的任何降维操作也必须在新数据上进行,例如测试数据集、验证数据集以及使用最终模型进行预测时的数据。

想开始学习数据准备吗?

立即参加我为期7天的免费电子邮件速成课程(附示例代码)。

点击注册,同时获得该课程的免费PDF电子书版本。

降维算法

有许多可用于降维的算法。

主要的两类方法是那些源于线性代数的方法和那些源于流形学习的方法。

线性代数方法

源自线性代数领域的矩阵分解方法可用于降维。

有关矩阵分解的更多信息,请参阅教程

一些更流行的方法包括

  • 主成分分析
  • 奇异值分解
  • 非负矩阵分解

流形学习方法

流形学习方法旨在找到高维输入的低维投影,这些投影能够捕捉输入数据的关键特性。

一些更流行的方法包括

  • Isomap 嵌入
  • 局部线性嵌入
  • 多维尺度分析
  • 谱嵌入
  • t-分布随机邻域嵌入

每种算法都提供了一种不同的方法来应对在低维度下发现数据自然关系这一挑战。

没有最佳的降维算法,也没有简单的方法可以在不进行受控实验的情况下找到适合您数据的最佳算法。

在本教程中,我们将回顾如何使用 scikit-learn 库中的这些流行降维算法的每个子集。

这些示例将为您提供复制粘贴示例并在您自己的数据上测试这些方法的基础。

我们不会深入探讨算法工作原理的理论,也不会直接比较它们。有关此主题的良好起点,请参阅

让我们开始吧。

降维示例

在本节中,我们将回顾如何在 scikit-learn 中使用流行的降维算法。

这包括一个将降维技术用作建模管道中的数据转换的示例,以及评估在数据上拟合的模型。

这些示例旨在供您复制粘贴到您自己的项目中并应用于您自己的数据。scikit-learn 库中提供了一些算法,但由于算法本身的性质无法直接用作数据转换,因此并未在此展示。

因此,我们将在每个示例中使用合成分类数据集。

Scikit-Learn 库安装

首先,让我们安装库。

不要跳过此步骤,您需要确保安装了最新版本。

您可以使用 pip Python 安装程序安装 scikit-learn 库,如下所示:

有关特定于您平台的其他安装说明,请参阅:

接下来,让我们确认已安装该库并正在使用现代版本。

运行以下脚本打印库版本号。

运行该示例,您应该会看到以下版本号或更高版本。

分类数据集

我们将使用 make_classification() 函数来创建测试二分类数据集。

该数据集将包含 1,000 个样本,其中有 20 个输入特征,10 个是信息性的,10 个是冗余的。这为每种技术提供了识别和删除冗余输入特征的机会。

伪随机数生成器的固定随机种子确保我们每次运行代码时都会生成相同的合成数据集。

下面列出了创建和总结合成分类数据集的示例。

运行示例创建数据集并报告行数和列数,这与我们的预期相符。

这是一项二元分类任务,我们将在每次降维转换后评估一个逻辑回归模型。

模型将使用重复分层 10 折交叉验证的黄金标准进行评估。将报告所有折和重复之间的平均和标准差分类准确率。

以下示例将模型在原始数据集上的评估作为比较基准。

运行示例,使用所有 20 列对原始数据集上的逻辑回归进行评估,准确率约为 82.4%。

成功的降维转换应该能让模型获得比此基线更好的准确率,尽管并非所有技术都能实现这一点。

注意:我们不尝试“解决”这个数据集,只是提供可用的示例,您可以将其用作起点。

接下来,我们可以开始查看降维算法在此数据集上的应用示例。

我已经对每种方法进行了最小的调整。每种降维方法都将被配置为将 20 个输入列减少到 10 个(如果可能)。

我们将使用管道 (Pipeline) 将数据转换和模型组合成一个原子单元,可以使用交叉验证程序对其进行评估;例如:

让我们开始吧。

您能为其中一种算法获得更好的结果吗?
在下面的评论中告诉我。

主成分分析

主成分分析(PCA)可能是稠密数据(零值很少)降维最常用的技术。

有关 PCA 工作原理的更多信息,请参阅教程

scikit-learn 库提供了PCA 类,这是主成分分析的实现,可用作降维数据转换。“n_components”参数可以设置为配置转换输出所需的维度数。

下面列出了使用 PCA 降维评估模型的完整示例。

运行示例将评估包含降维和逻辑回归预测模型的建模管道。

注意:由于算法的随机性或评估程序的随机性,或数值精度的差异,您的结果可能有所不同。考虑运行示例几次并比较平均结果。

在这种情况下,我们没有看到使用 PCA 转换对模型性能有任何提升。

奇异值分解

奇异值分解(SVD)是降维技术中最常用的技术之一,特别适用于稀疏数据(许多值为零的数据)。

有关 SVD 工作原理的更多信息,请参阅教程

scikit-learn 库提供了TruncatedSVD 类,这是奇异值分解的实现,可用作降维数据转换。“n_components”参数可以设置为配置转换输出所需的维度数。

下面列出了使用 SVD 降维评估模型的完整示例。

运行示例将评估包含降维和逻辑回归预测模型的建模管道。

注意:由于算法的随机性或评估程序的随机性,或数值精度的差异,您的结果可能有所不同。考虑运行示例几次并比较平均结果。

在这种情况下,我们没有看到使用 SVD 转换对模型性能有任何提升。

线性判别分析

线性判别分析(LDA)是一种多类别分类算法,可用于降维。

投影的维度数量限制为 1 和 C-1,其中 C 是类别的数量。在这种情况下,我们的数据集是二元分类问题(两个类别),将维度数量限制为 1。

有关 LDA 用于降维的更多信息,请参阅教程

scikit-learn 库提供了LinearDiscriminantAnalysis 类,这是线性判别分析的实现,可用作降维数据转换。“n_components”参数可以设置为配置转换输出所需的维度数。

下面列出了使用 LDA 降维评估模型的完整示例。

运行示例将评估包含降维和逻辑回归预测模型的建模管道。

注意:由于算法的随机性或评估程序的随机性,或数值精度的差异,您的结果可能有所不同。考虑运行示例几次并比较平均结果。

在这种情况下,与在原始数据上拟合的基线相比,我们可以看到性能有轻微提升。

Isomap 嵌入

Isomap 嵌入,或 Isomap,创建数据集的嵌入,并尝试保留数据中的关系。

scikit-learn 库提供了Isomap 类,这是 Isomap 嵌入的实现,可用作降维数据转换。“n_components”参数可以设置为配置转换输出所需的维度数。

下面列出了使用 SVD 降维评估模型的完整示例。

运行示例将评估包含降维和逻辑回归预测模型的建模管道。

注意:由于算法的随机性或评估程序的随机性,或数值精度的差异,您的结果可能有所不同。考虑运行示例几次并比较平均结果。

在这种情况下,与在原始数据上拟合的基线相比,我们可以看到 Isomap 数据转换的性能有所提升。

局部线性嵌入

局部线性嵌入(LLE)创建数据集的嵌入,并尝试保留数据中邻域之间的关系。

scikit-learn 库提供了LocallyLinearEmbedding 类,这是局部线性嵌入的实现,可用作降维数据转换。“n_components”参数可以设置为配置转换输出所需的维度数。

下面列出了使用 LLE 降维评估模型的完整示例。

运行示例将评估包含降维和逻辑回归预测模型的建模管道。

注意:由于算法的随机性或评估程序的随机性,或数值精度的差异,您的结果可能有所不同。考虑运行示例几次并比较平均结果。

在这种情况下,与在原始数据上拟合的基线相比,我们可以看到 LLE 数据转换的性能有所提升。

改进型局部线性嵌入

改进型局部线性嵌入(Modified LLE)是局部线性嵌入的扩展,它为每个邻域创建多个加权向量。

scikit-learn 库提供了LocallyLinearEmbedding 类,这是改进型局部线性嵌入的实现,可用作降维数据转换。“method”参数必须设置为‘modified’,而“n_components”参数可以设置为配置转换输出所需的维度数,该维度数必须小于“n_neighbors”参数。

下面列出了使用改进型 LLE 降维评估模型的完整示例。

运行示例将评估包含降维和逻辑回归预测模型的建模管道。

注意:由于算法的随机性或评估程序的随机性,或数值精度的差异,您的结果可能有所不同。考虑运行示例几次并比较平均结果。

在这种情况下,与在原始数据上拟合的基线相比,我们可以看到改进型 LLE 数据转换的性能有所提升。

进一步阅读

如果您想深入了解,本节提供了更多关于该主题的资源。

教程

API

总结

在本教程中,您了解了如何在 Python 中拟合和评估顶级降维算法。

具体来说,你学到了:

  • 降维旨在找到数值输入数据的低维表示,同时保留数据中的重要关系。
  • 有许多不同的降维算法,没有一种方法适用于所有数据集。
  • 如何在 Python 中使用 scikit-learn 机器学习库实现、拟合和评估顶级降维。

你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。

掌握现代数据准备!

Data Preparation for Machine Learning

在几分钟内准备好您的机器学习数据

...只需几行python代码

在我的新电子书中探索如何实现
机器学习数据准备

它提供**自学教程**,并附有关于以下内容的**完整工作代码**:
*特征选择*、*RFE*、*数据清洗*、*数据转换*、*缩放*、*降维*,以及更多...

将现代数据准备技术引入
您的机器学习项目


查看内容

对《Python 降维算法》的 20 条回复

  1. Abc 2020年7月10日上午9:40 #

    如何选择维度数量

    • Jason Brownlee 2020年7月10日下午1:48 #

      一些方法会提供关于组件/维度数量有用的信息,例如 PCA。

      通常,将其视为建模管道的超参数。

  2. Alanzinho 2020年7月11日晚上9:24 #

    文章没有提到哪些输入被丢弃,哪些可以被认为是“强”的。在实际场景中,有必要了解这些信息来证明降维的合理性。

    • Jason Brownlee 2020年7月12日早上5:51 #

      我根据结果来指导我。例如,使用能产生最佳模型性能的维度数量。

  3. Sangram 2020年8月4日晚上10:16 #

    UMAP也是一种很棒的降维算法。

    • Jason Brownlee 2020年8月5日早上6:12 #

      谢谢!

    • Alexandra 2023年8月10日早上3:09 #

      我尝试过使用 UMAP 来可视化我的数据。您能否提供一些关于如何将其用作降维算法的见解?

  4. Samuel 2020年8月13日早上6:06 #

    你好 Jason。流形方法中的任何一种都可以用于时间序列数据吗?

    • Jason Brownlee 2020年8月13日早上6:24 #

      也许吧,我对时间序列聚类不太了解,抱歉。

  5. Ancy Sherin Jose 2021年8月15日凌晨12:06 #

    嗨,Jason,

    在进行 K-Means 聚类之前,使用线性判别分析降维技术来减少维度数量是否有任何问题?

    我尝试了 PCA + K-Means 和 LDA + K-Means。我为 LDA + K-Means 获得了良好的结果。但我找不到任何使用 LDA + K-Means 的工作。由于我正在处理一个标记数据集,我可以采用 LDA 技术,但在实际情况中,可能没有标记数据集。所以我的问题是,如果我使用 LDA + K-Means 是否有意义?我没有找到任何使用这种技术进行聚类的作品。

    谢谢您

  6. collins 2021年8月21日早上5:58 #

    Jason,我在这里有点迷茫,关于降维,我们是否先使用 PCA + 逻辑回归来找到降维的准确性,然后再使用另一个模型来训练和测试数据?

    • Adrian Tam
      Adrian Tam 2021年8月23日早上4:42 #

      PCA 是一种降维技术。但任何降维都会丢失一些信息,只是信息量多少的问题。例如,应用逻辑回归可以帮助您找到一种方法来衡量降维是否能保留您在特定问题所需的信息。

  7. Ancy Sherin Jose 2021年8月28日晚上2:33 #

    谢谢。

  8. Med 2022年7月21日早上9:07 #

    大家好,

    是否有与 PLA(分段线性近似)相关的技术可用于降维?我遇到的问题是:我的数据集是一个矩阵,其中包含时间序列,每一行代表一个时间序列。我需要一个使用 PLA 来减少列数的算法。

    谢谢并致以最诚挚的问候

    Med

  9. Sarka 2022 年 10 月 22 日晚上 10:58 #

    您好,我尝试使用谱嵌入来查看交叉验证分数,但它返回了 nan 值。您能帮我看看哪里出错了 G 吗?谢谢,Sarka

    # 谱嵌入
    from sklearn import metrics
    from sklearn.datasets import load_digits
    from sklearn.manifold import SpectralEmbedding
    from sklearn.metrics import accuracy_score

    # 定义数据集
    X, y = make_classification(n_samples=1000, n_features=20, n_informative=10, n_redundant=10, random_state=7)

    # 定义管道
    model = SpectralEmbedding(n_components=2)
    X_transformed = model.fit_transform(X)

    # 评估模型
    cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
    n_scores = cross_val_score(model, X, y, scoring=’accuracy’, cv=cv, n_jobs=-1)

    # 报告表现
    print(‘Accuracy: %.3f (%.3f)’ % (mean(n_scores), std(n_scores)))

    • James Carmichael 2022 年 10 月 23 日上午 8:21 #

      Sarka,您好……我没有看到您定义 `make_classification` 的地方。

  10. Bryam Blas 2023 年 8 月 19 日上午 5:17 #

    我有一个问题,如果我的数据集中包含分类变量和数值变量,您推荐使用哪种技术,或者在这些情况下我应该怎么做?谢谢。

留下回复

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。