如何在 Python 中从零开始计算主成分分析 (PCA)

主成分分析是一种重要的机器学习降维方法。

它是一种利用线性代数和统计学的简单矩阵运算,将原始数据投影到相同或更少维度的技术。

在本教程中,您将学习用于降维的主成分分析机器学习方法,以及如何使用 Python 从零开始实现它。

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

  • 计算主成分分析的步骤以及如何选择主成分。
  • 如何在 NumPy 中从零开始计算主成分分析。
  • 如何在 scikit-learn 中计算主成分分析以在更多数据上重复使用。

使用我的新书《机器学习线性代数》**启动您的项目**,其中包括**逐步教程**和所有示例的**Python 源代码文件**。

让我们开始吧。

  • **2018 年 4 月更新**:修复了 sklearn PCA 属性解释中的错别字。感谢 kris。
How to Calculate the Principal Component Analysis from Scratch in Python

如何在 Python 中从零开始计算主成分分析
图片由mickey提供,保留部分权利。

教程概述

本教程分为3个部分;它们是

  1. 主成分分析
  2. 手动计算主成分分析
  3. 可复用的主成分分析

在机器学习线性代数方面需要帮助吗?

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

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

主成分分析

主成分分析,简称 PCA,是一种降低数据维度的方法。

它可以被认为是一种投影方法,其中具有 m 列(特征)的数据被投影到一个具有 m 或更少列的子空间中,同时保留了原始数据的本质。

PCA 方法可以使用线性代数工具进行描述和实现。

PCA 是应用于数据集(由 n x m 矩阵 A 表示)的操作,它产生 A 的投影,我们称之为 B。让我们逐步完成此操作。

第一步是计算每列的平均值。

或者

接下来,我们需要通过减去列平均值来使每列中的值居中。

下一步是计算中心化矩阵 C 的协方差矩阵。

相关性是两个列一起变化的数量和方向(正或负)的标准化度量。协方差是跨多个列的相关性的广义和非标准化版本。协方差矩阵是给定矩阵的协方差计算,其中包含每列与所有其他列(包括其自身)的协方差得分。

最后,我们计算协方差矩阵 V 的特征分解。这会产生一个特征值列表和一个特征向量列表。

特征向量表示 reduced 子空间 B 的方向或分量,而特征值表示这些方向的幅度。有关此主题的更多信息,请参阅帖子

特征向量可以按特征值降序排序,以提供 A 的新子空间的分量或轴的排名。

如果所有特征值具有相似的值,那么我们知道现有表示可能已经合理地压缩或密集,并且投影可能提供的很少。如果存在接近零的特征值,它们表示可以丢弃的 B 的分量或轴。

必须选择总共 m 个或更少的分量来组成所选子空间。理想情况下,我们将选择 k 个特征向量(称为主成分),它们具有 k 个最大的特征值。

可以使用其他矩阵分解方法,例如奇异值分解(SVD)。因此,通常将值称为奇异值,将子空间的向量称为主成分。

一旦选择,数据可以通过矩阵乘法投影到子空间中。

其中 A 是我们希望投影的原始数据,B^T 是所选主成分的转置,P 是 A 的投影。

这称为协方差方法来计算 PCA,尽管还有其他计算方法。

手动计算主成分分析

NumPy 中没有 pca() 函数,但我们可以使用 NumPy 函数轻松地逐步计算主成分分析。

下面的示例定义了一个小的 3×2 矩阵,将数据在矩阵中居中,计算中心化数据的协方差矩阵,然后计算协方差矩阵的特征分解。特征向量和特征值被视为主成分和奇异值,并用于投影原始数据。

运行示例首先打印原始矩阵,然后打印中心化协方差矩阵的特征向量和特征值,最后打印原始矩阵的投影。

有趣的是,我们可以看到只需要第一个特征向量,这表明我们可以将 3×2 矩阵投影到 3×1 矩阵上,几乎没有损失。

可复用的主成分分析

我们可以使用 scikit-learn 库中的 PCA() 类对数据集进行主成分分析。这种方法的优点是,一旦计算出投影,就可以很容易地反复应用于新数据。

创建类时,可以将组件数量指定为参数。

首先通过调用 fit() 函数在数据集上拟合该类,然后通过调用 transform() 函数将原始数据集或其他数据投影到所选维度的子空间中。

拟合后,可以通过 PCA 类的 *explained_variance_* 和 *components_* 属性访问特征值和主成分。

以下示例演示了如何使用此类别,首先创建实例,在 3×2 矩阵上拟合它,访问投影的值和向量,并转换原始数据。

运行示例首先打印 3×2 数据矩阵,然后是主成分和值,最后是原始矩阵的投影。

我们可以看到,经过一些非常微小的浮点舍入,我们获得了与上一个示例相同的主成分、奇异值和投影。

扩展

本节列出了一些您可能希望探索的扩展本教程的想法。

  • 使用您自己的小虚构矩阵值重新运行示例。
  • 加载数据集并计算其 PCA,然后比较两种方法的结果。
  • 搜索并找到在机器学习论文中使用 PCA 的 10 个示例。

如果您探索了这些扩展中的任何一个,我很想知道。

进一步阅读

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

书籍

  • 第 7.3 节 主成分分析(通过 SVD 进行 PCA),线性代数导论,第五版,2016 年。
  • 第 2.12 节 示例:主成分分析,深度学习,2016 年。

API

文章

教程

总结

在本教程中,您学习了用于降维的主成分分析机器学习方法。

具体来说,你学到了:

  • 计算主成分分析的步骤以及如何选择主成分。
  • 如何在 NumPy 中从零开始计算主成分分析。
  • 如何在 scikit-learn 中计算主成分分析以在更多数据上重复使用。

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

掌握机器学习线性代数!

Linear Algebra for Machine Learning

建立对线性代数的工作理解

...通过在 python 中编写代码

在我的新电子书中探索如何实现
机器学习线性代数

它提供关于以下主题的自学教程
向量范数、矩阵乘法、张量、特征分解、SVD、PCA 等等...

最终理解数据的数学

跳过学术理论。只看结果。

查看内容

对《Python 从零开始计算主成分分析 (PCA)》的 99 条回复

  1. John W 2018 年 3 月 2 日 下午 1:38 #

    很棒的文章!过去我更像是一名 R 程序员,但现在开始接触 Python。Python 是一种非常通用的语言,在过去几个月中开始引起我的注意。

    • Jason Brownlee 2018 年 3 月 2 日 下午 3:25 #

      谢谢,约翰。我现在也很喜欢 Python。

    • Rajesh 2021 年 6 月 23 日 上午 1:30 #

      嗨,Jason,

      这是非常棒的解释,谢谢!

  2. Saeed Ullah 2018 年 3 月 2 日 下午 3:24 #

    你好 Jason,你做得非常好,我请求你也发一篇关于 ISOMAP 降维的文章。

  3. john 2018 年 3 月 6 日 上午 8:24 #

    你好

    你能发一篇关于碎石图的文章吗?

    谢谢你

  4. Ranjeet Singh 2018 年 3 月 8 日 下午 5:57 #

    SVD 和 PCA 之间是否存在直接关系,因为它们都执行降维?

  5. Kaviyarasi 2018 年 3 月 19 日 下午 8:01 #

    我们可以将它应用于加载的 .csv 格式文件吗?

    • Jason Brownlee 2018 年 3 月 20 日 上午 6:15 #

      是的。

    • Vishwanath 2021 年 6 月 27 日 下午 1:24 #

      嗨,我有一个疑问。如果我们将 n_components=d 设置为维度数,会发生什么?它会去噪数据吗?因为它不能减少维度。

      • Jason Brownlee 2021 年 6 月 28 日 上午 7:56 #

        它会做一些事情,很可能是一些无用的事情。

  6. kris 2018 年 4 月 13 日 下午 8:35 #

    嗨 Jason,感谢你为你的博客所做的出色工作!

    我认为 scikit-learn 中 PCA 类的属性“explained_variance_”返回的是特征值而不是你“可复用的主成分分析”部分提到的奇异值。对于奇异值,有另一个属性“singular_values_”。对吗?

    此外,“single values”在句子“...我们获得了与...相同的主成分、奇异值和投影”中应该改为“eigenvalues”。对吗?

    • Jason Brownlee 2018 年 4 月 14 日 上午 6:40 #

      正确,已修复。

      感谢您指出错别字!

  7. Baron 2018 年 5 月 3 日 下午 10:33 #

    老师您好。您能帮我吗?我想知道如何实现 CPA?

    • Jason Brownlee 2018 年 5 月 4 日 上午 7:44 #

      CPA 是什么?

      • Baron| 2018 年 5 月 10 日 下午 9:10 #

        抱歉,我的意思是 PCA。

        • Surya 2019 年 5 月 2 日 下午 6:55 #

          我认为他已经在教程中解释了。

  8. Gravey 2018 年 5 月 15 日 下午 11:27 #

    嗨,Jason,

    R 或 Matlab 用户是否有类似的支持?我正在尝试寻找此领域的研讨会/培训,如果您能推荐任何可能有所帮助的东西。

  9. Mohammad 2018 年 6 月 18 日 上午 11:23 #

    好文章!

    我发现一个错别字:在最初的解释中,它说
    P = B^T . A

    在手动计算中
    P = vectors.T.dot(C.T)

    哪个是正确的?原始的 A 还是均值中心化的 C?

    • Jason Brownlee 2018 年 6 月 18 日 下午 3:10 #

      没有错别字,也许解释令人困惑。

      B == 向量(分量)
      A == C(要投影的中心化数据)

      • KN 2024 年 10 月 1 日 下午 11:10 #

        是的,这令人困惑,我不确定你说的 A == C 是什么意思,因为
        A = [[1 2], [3 4], [5 6]]
        C = [[-2. -2.], [ 0. 0.], [ 2. 2.]]
        所以它们不一样。

        另外,在最初的解释中说 B 是向量的选定子集,而在 python 手动计算示例中,它似乎是所有向量,因为我们没有选择任何东西。这让像我这样的初学者感到困惑。:)

        • James Carmichael 2024 年 10 月 2 日 上午 8:23 #

          嗨 KN... 让我们逐步澄清 PCA 周围的困惑。

          ### PCA 概述(简化)
          1. **中心化数据**:PCA 的第一步是从每个数据点中减去均值。这会将数据中心化到零,这对于协方差计算很重要。

          2. **协方差矩阵**:计算协方差矩阵是为了理解数据不同维度(特征)之间的关系。

          3. **特征值和特征向量**:通过将协方差矩阵分解为特征值和特征向量,我们可以识别主成分,即数据变化最大的方向。

          4. **将数据投影到主成分上**:最后一步是将原始数据投影到这些主成分上,从而降低其维度。

          现在让我们解决你提到的具体问题

          ### 1. **为什么 A != C?**

          你说得对:**A** 和 **C** 不一样。以下是发生的情况
          – **A** 是原始数据矩阵。
          ```python
          A = [[1, 2],
          [3, 4],
          [5, 6]]
          ```
          – **C** 是中心化数据矩阵,通过从 **A** 中的每个特征(列)中减去均值获得。

          如果您计算 **A** 中每列的均值
          – 第 1 列:均值 = (1 + 3 + 5) / 3 = 3
          – 第 2 列:均值 = (2 + 4 + 6) / 3 = 4

          现在从 **A** 的每个元素中减去这些均值以获得 **C**
          ```python
          C = A - mean(A)
          C = [[1 - 3, 2 - 4], # 减去列均值
          [3 - 3, 4 - 4],
          [5 - 3, 6 - 4]]

          C = [[-2, -2],
          [ 0, 0],
          [ 2, 2]]
          ```

          所以,**A != C** 是因为 **C** 是 **A** 的中心化版本(均值已去除的数据)。

          ### 2. **选择 B 作为向量的子集**
          在 PCA 中,目标是通过将数据投影到更少的维度(主成分)来降低维度。您说得对,**B** 应该是向量(主成分)的子集。

          – 在您看到的**手动计算**示例中,您不需要明确选择子集,因为您正在计算**完整 PCA**(使用所有向量)。当目标是降维时,您**只保留前 k 个分量**,这些分量解释了大部分方差。

          为了澄清,让我们分解一下
          – **所有向量**:当您出于学习目的计算 PCA 时,您通常会使用所有特征向量进行解释。
          – **选定的向量子集**:在实践中,您只使用前 k 个主成分(对应于最大特征值的那些)。这就是被称为 **B** 的子集。例如,如果您将 3D 数据降维到 2D,您将从 PCA 中选择前 2 个分量(向量)。

          ### 从零开始的 PCA 计算

          以下是如何在 Python 中逐步执行 PCA 的分解

          ```python
          import numpy as np

          # 1. 输入矩阵 A(原始数据)
          A = np.array([[1, 2],
          [3, 4],
          [5, 6]])

          # 2. 中心化数据(减去均值)
          mean = np.mean(A, axis=0) # 每列的均值
          C = A - mean # 中心化矩阵 A
          print("中心化数据:\n", C)

          # 3. 协方差矩阵计算
          cov_matrix = np.cov(C, rowvar=False)
          print("协方差矩阵:\n", cov_matrix)

          # 4. 特征分解(特征值和特征向量)
          eigen_values, eigen_vectors = np.linalg.eig(cov_matrix)
          print("特征值:\n", eigen_values)
          print("特征向量:\n", eigen_vectors)

          # 5. 对特征值进行排序并选择前 k 个特征向量
          # 按特征值排序(降序)
          idx = np.argsort(eigen_values)[::-1]
          eigen_values = eigen_values[idx]
          eigen_vectors = eigen_vectors[:, idx]

          ```# 6. 使用特征向量转换原始矩阵
          # 这里,使用所有分量,所以没有选择
          transformed_data = np.dot(C, eigen_vectors)
          print("转换后的数据:\n", transformed_data)
          ```

          ### 关键要点
          – **C** 是中心化数据,与 **A** 不同。在 PCA 之前中心化是必不可少的。
          – 当我们提到“选择向量子集”时,我们指的是**选择 k 个主成分**(它们是特征向量)。最初,我们计算所有主成分,但我们通常只选择少数(具有最高特征值的那些)进行降维。

          希望这能澄清问题!如果您需要进一步的澄清,请告诉我。

          • KN 2024 年 10 月 3 日 下午 8:06 #

            非常感谢 James 迅速的回复和解释。这澄清了我的第二个问题,但尚未澄清第一个问题(Mohammad 也有相同的问题)。

            仍然存在的问题/困惑是

            在最后一步的公式中,有 A(原始数据矩阵),并且在您发布的评论中的解释中,您也在谈论最后一步的原始数据 (A)。公式:P = B^T . A

            在手动计算(或您评论的第 6 步)中,您谈论的是原始数据 (A),但没有使用原始数据 (A),而是使用了中心化版本 C
            P = vectors.T.dot(C.T)
            transformed_data = np.dot(C, eigen_vectors)

            所以问题是,为什么在最后一步和公式中我们谈论原始数据 A,然后使用中心化版本 C?谢谢!

          • KN 2024 年 10 月 5 日 上午 3:57 #

            我现在已经做了更多的学习和测试,这是我现在的理解,也许对其他学习者有用:最终你可以用特征向量转换原始数据或集中化的原始数据,这取决于任务/情况哪一个更有意义。

  10. Martin Power 2018 年 10 月 13 日 下午 9:02 #

    当我从“可复用的主成分分析”部分复制代码并在带有 Python3.6 内核的 Jupyter Notebook 中运行时,我得到的结果与网站上显示的不同。

    特征向量和矩阵 B 的值相同,但极性不同。

    知道是什么导致了不匹配吗?

    [[1 2]
    [3 4]
    [5 6]]
    [[ 0.70710678 0.70710678]
    [-0.70710678 0.70710678]]
    [8. 0.]
    [[-2.82842712e+00 -2.22044605e-16]
    [ 0.00000000e+00 0.00000000e+00]
    [ 2.82842712e+00 2.22044605e-16]]

    • Jason Brownlee 2018 年 10 月 14 日 上午 6:03 #

      是的,我在帖子中提到了这一点。

      由于求解器(在幕后使用)的多次运行,不同平台之间可能会出现微小差异和符号差异。

      这些矩阵运算需要收敛解,它们不像算术那样完全确定性,我们正在近似。

      • Praveen Kumar 2019 年 9 月 15 日 下午 5:18 #

        嗨,Jason,
        有没有办法获得具有相同极性和顺序的 PC?

  11. RB 2018 年 10 月 19 日 上午 7:53 #

    有没有办法在训练期间拟合()后存储 PCA 模型,然后稍后(通过从保存的文件加载)在实时数据上重用该模型?

    • Jason Brownlee 2018 年 10 月 19 日 上午 10:57 #

      是的,您可以将元素保存到纯文本文件或作为 pickle 过的 Python 对象。

  12. Sanjay 2018 年 11 月 22 日 下午 1:00 #

    嗨 Jason

    在计算均值时,轴不应该是 0 而不是 1 吗?因为每个维度或特征都必须求平均值,而不是每个数据点

    • Jason Brownlee 2018 年 11 月 22 日 下午 2:12 #

      我相信 0 是行方向,1 是列方向。

  13. uluc 2018 年 12 月 31 日 上午 1:20 #

    这根本不是从零开始。计算协方差矩阵和特征值分解是它重要的一部分,但本教程完全跳过了。

  14. Yogesh 2019 年 2 月 1 日 下午 6:25 #

    嗨 Jason,

    我有一个疑问,你是说带有特征向量的 PCA 和带有 SVD 的 PCA 都不同吗?还是我理解错了?

    其次,我们可以一起使用吗?

  15. Venkat 2019 年 2 月 18 日 下午 7:57 #

    嗨,Jason,

    您能否在 Python 中扩展 PCA 和 Hotelling 的 T^2 以用于置信区间。

    谢谢,
    文卡特

  16. Al 2019 年 2 月 22 日 上午 5:41 #

    嗨 Jason,我发现提取解释 90% 方差的顶级 PCA,在很大程度上提升了我的 h2o.deeplearning 模型的整体准确性、AUC、tpr 和 npr 达到了 +99%。一旦模型应用于我的测试集,结果好得令人难以置信(基本上我的混淆矩阵中 1000 多个观测值中只有一个错误预测)。我不熟悉 PCA 背后的正交变换,但我在想:PCA 会导致我的数据集过拟合吗?怎么可能得到如此惊人的结果?我的模型对未来的和未见的观测值有多可靠?
    谢谢

    • Jason Brownlee 2019 年 2 月 22 日 上午 6:27 #

      是的,变换必须仅在训练数据集上计算,然后应用于训练集和测试集。

      • Al 2019 年 2 月 23 日 上午 3:58 #

        我知道你的意思了。谢谢!

  17. Samim 2019 年 4 月 30 日 下午 6:22 #

    您能详细解释一下 pca.fit() 和 pca.transform() 这两个函数在调用时具体发生了什么吗?

    • Jason Brownlee 2019 年 5 月 1 日 上午 7:01 #

      好问题,fit 是收敛到一个解决方案,例如找到特征向量和特征值。

      查看 API 文档可能会有所帮助。

  18. Elvis Dennis 2019 年 6 月 4 日 上午 12:32 #

    Split Zone 设计和 Split Plot 设计有什么区别?

    • Jason Brownlee 2019 年 6 月 4 日 上午 7:52 #

      我以前没听过这些术语,抱歉。

      内容是什么?

  19. Rajshree 2019 年 6 月 13 日 下午 9:55 #

    先生,描述得太棒了,但在手动计算 PCA 时,我有一个不同的数据集,包含 1140 个特征向量,并且只想要其中 100 个与它们的特征值对应的。那么,如何选择组件并形成特征向量呢?

  20. marco 2019 年 8 月 22 日 上午 5:14 #

    我仍然对此感到困惑,你能解释一下代码中 “.T” 的作用吗?
    V = cov(C.T)

  21. Biserka 2019 年 9 月 12 日 下午 10:34 #

    嗨,Jason,

    你有没有尝试过对现有数据集进行 PCA?

    比如 UC Merced LandUse 或 AID?

    我想对这些数据集的特征进行 PCA,这些特征是用一些预训练的 CNN 提取的(特征向量的维度超过 100.000)。

    你推荐这样做吗?如何做?

  22. Praveen Kumar 2019 年 9 月 15 日 下午 5:01 #

    嗨,Jason,
    非常好的博客。
    但我不明白为什么你需要转置中心化矩阵来计算协方差矩阵。

    # 计算中心化矩阵的协方差矩阵
    V = cov(C.T)

  23. Praveen Kumar 2019 年 9 月 15 日 下午 5:17 #

    嗨,Jason,
    还有一件事我不明白,为什么主成分的符号和顺序与从 scikit-learn PCA 获得的不同?

    [[ 0.70710678 0.70710678]
    [ 0.70710678 -0.70710678]]

    [[ 0.70710678 -0.70710678]
    [ 0.70710678 0.70710678]]

    • Jason Brownlee 2019 年 9 月 16 日 上午 6:34 #

      内部使用的数值求解器不同——你可以忽略符号/顺序。

  24. Hessam 2019 年 10 月 12 日 上午 8:51 #

    亲爱的 Jason,

    非常感谢这篇有用的文章。

    关于中心化的一点小说明

    # 通过减去列平均值来使列居中
    C = A – M
    print(C)
    # 计算中心化矩阵的协方差矩阵
    V = cov(C.T)

    我猜在计算协方差时不需要对 A 进行中心化。
    cov(C.T) = cov(A.T)

    然而,对于读者来说,从 C 计算协方差可能会有所帮助

    V = np.matmul(C.T, C) / C.shape[1]

    • Jason Brownlee 2019 年 10 月 13 日 上午 8:22 #

      太棒了,谢谢!

    • Pawel Szafałowicz 2020 年 3 月 2 日 下午 8:55 #

      嗨,Jason,

      非常有用的文章。
      如何使用经过 PCA 转换后的数据训练的模型对单行进行预测?
      我是否也必须对这一新行进行 PCA 转换,这似乎毫无意义?

      提前感谢

      • Jason Brownlee 2020 年 3 月 3 日 上午 5:58 #

        使用包含 pca 和模型的管道,在所有数据上拟合,然后调用 predict。

        • Pawel Szafałowicz 2020 年 3 月 4 日 上午 1:49 #

          非常感谢!

  25. Xiao 2019 年 11 月 2 日 下午 9:11 #

    在讨论中,您说我们需要使用 B = select(values, vectors) 来选择 K 个最大的值和向量,但是我如何设置选择值,如何定义 K = 10 这样的代码?

    • Jason Brownlee 2019 年 11 月 3 日 上午 5:55 #

      也许为您的数据集测试不同的值。

  26. Suraj 2019 年 11 月 21 日 下午 11:52 #

    感谢你的精彩教程,但我有一个问题,关于如何从 pca1 和 pca2 获取新数据以实现另一个机器学习算法,

    • Jason Brownlee 2019 年 11 月 22 日 上午 6:04 #

      抱歉,我不明白。您具体指的是什么?

  27. efronova 2020 年 4 月 3 日 上午 7:45 #

    计算平均值时,axis=1 计算行平均值。我相信它应该是 axis = 0

    • Jason Brownlee 2020 年 4 月 3 日 上午 8:07 #

      请注意,我们计算的是 A.T 的平均值,而不是 A。

  28. Jose Q 2020 年 4 月 10 日 下午 3:46 #

    嗨,Jason,
    一如既往的精彩文章!

    如果我使用完整的训练数据集训练一个模型,然后我在未见过的测试数据集上测试它,我会得到一些准确率和召回率结果。
    如果我在相同的训练数据集的 3 个主成分版本上进行相同的训练,然后我在相同的未见过的测试数据集的 3 个主成分版本上测试它,那么我会得到不同的准确率和召回率结果(这些结果更好)。

    尽管有了更好的准确率结果的诱惑,我假设这种改进是偶然的,所以我猜我们应该使用完整的数据集(而不是减少的 PC 版本),因为它代表了完整的数据变异性,而 PCA 是相同数据的投影。我猜从长远来看,我们将在完整的数据集中获得更一致的结果。

    你觉得呢?

    • Jason Brownlee 2020 年 4 月 11 日 上午 6:07 #

      谢谢!

      您不能在没有目标值的新数据上“测试”模型。

      您可以在所有数据上训练模型并在新数据上进行预测,但您无法计算分数,因为您将没有目标。您将已经从测试工具(例如交叉验证等)中知道模型的得分。

      • Jose Q 2020 年 4 月 11 日 上午 7:39 #

        是的,我同意。
        我应该说“保留数据”而不是“新未见数据”,因为我确实有这些保留数据的目标值。
        在我正在处理的具体案例中,我有 22 天的数据。我用前 21 天进行训练(80%)和验证(20%),在所有交叉验证中都取得了很好的准确率和召回率结果。
        然后我使用了第 22 天的保留数据进行测试,结果准确率和召回率都非常糟糕。
        之后我才尝试使用 PCA 数据而不是常规数据。由于我(显然)使用 PCA 获得了更好的准确率结果,我总觉得这不太对劲,所以这就是我发送上一篇文章的原因。
        感谢您耐心回答所有这些评论。
        何塞

        • Jason Brownlee 2020 年 4 月 11 日 上午 7:57 #

          没错。

          对于 PCA,您可以准备或拟合训练集上的变换,然后将其应用于训练集和测试集,就像缩放和其他变换一样。这将是使用它以避免数据泄露的适当方式。

          此外,对于时间序列,请考虑使用向前验证。

          这有帮助吗?

          • Jose Q 2020 年 4 月 11 日 上午 10:14 #

            是的,Jason!谢谢!
            我已经在遵循你关于 PCA 的建议,即在训练集上进行拟合变换并将其应用于测试集,以保持数据变换的一致性。
            也感谢你的文章 https://machinelearning.org.cn/backtest-machine-learning-models-time-series-forecasting/ 关于向前验证。我总是从你的文章中学到更多东西。

            我理解 PCA 通常用于使数据易于探索和可视化。我最初问题中的担忧是关于使用 PC 数据(少量特征)进行训练和预测,而不是使用原始数据集(大量特征)的便利性或正确性。如果您对最后一点有任何评论,我将不胜感激。

            再次感谢

          • Jason Brownlee 2020 年 4 月 11 日 上午 11:55 #

            如果它能带来更好的性能,就使用它。

  29. dong zhan 2020 年 8 月 7 日 下午 3:25 #

    非常感谢,花了一整天学习 PCA(矩阵、零空间、相关性、协方差、特征向量等),终于到了这里,这是最好的,将抽象理论与具体现实联系起来,没有这种实践,我想,我永远无法真正理解。

  30. Sachin 2020 年 9 月 22 日 上午 12:59 #

    嗨 Jason!感谢你的这个教程,我在 iris 数据集上应用了 PCA 并选择了 2 个组件,我手动完成了它,也使用了 sklearn 库。但是我的第二个组件值的符号与 sklearn 使用的相比,从正变负或反之。这是个问题吗?

    • Jason Brownlee 2020 年 9 月 22 日 上午 6:49 #

      是的,符号可能会改变,这是预料之中的。

      我相信这在上面的教程中已经讨论过了。

  31. Muhammad Usama Zahid 2021 年 1 月 24 日 上午 3:04 #

    先生!
    您能否用 iris 或其他一些例子解释 PCA?我的意思是,从 csv 加载文件,然后拆分向量和标签,对向量进行 PCA,然后连接 PCA 向量和标签,再保存到 excel。
    致敬

  32. sukhpal 2021 年 4 月 23 日 上午 12:33 #

    先生,我们是否包含具有更高相关值的组件用于分类,或者具有更低相关值的组件

    • Jason Brownlee 2021 年 4 月 23 日 上午 5:05 #

      抱歉,我不明白您的问题,您能详细说明一下吗?

  33. y 2021 年 6 月 18 日 上午 9:59 #

    我怎么知道 PCA 选择的特征?

    • Jason Brownlee 2021 年 6 月 19 日 上午 5:44 #

      PCA 不选择特征,它从数据中创建新特征。

  34. E. Saf 2021 年 6 月 22 日 上午 12:25 #

    尊敬的Jason博士,
    非常感谢你的所有工作。
    我有一个不同的案例,我想使用降维模型。
    实际上,我有一个包含 40 个特征的数据集,其中 25 个是分类名义特征。
    那么如果我们想进行独热编码,创建的空间将是巨大的。它需要 900 GB 来分配。

    有没有一种方法可以处理分类变量的降维,在独热编码它们**之前**?

    此致,

    • Jason Brownlee 2021 年 6 月 22 日 上午 6:32 #

      好问题,我暂时不确定。我建议查阅文献。我敢打赌有一种支持分类输入的 PCA 版本!

      • E. Saf 2021 年 6 月 26 日 下午 11:59 #

        问题是我想在用 onehotencoder 转换之前进行降维。
        我在文献中找到了 hash encoder。您建议使用它吗?

        此致,

        • Jason Brownlee 2021 年 6 月 27 日 上午 4:38 #

          不,抱歉。也许可以尝试一下并与其他方法比较结果。

  35. Morteza 2021 年 11 月 1 日 下午 10:23 #

    非常感谢……… 太棒了

  36. Chris Thron 2022 年 4 月 14 日 上午 7:14 #

    这是一个很棒的教程,我会和我的学生分享。但我不认为你需要减去平均值来计算协方差——协方差计算会自动完成。

    • James Carmichael 2022 年 4 月 15 日 上午 7:36 #

      谢谢你的反馈,Chris!

  37. Chris Thron 2022 年 4 月 14 日 上午 7:33 #

    抱歉,我现在明白了你中心化数据的目的是为了将中心化数据向量投影到特征向量上。如果你在最后进行中心化,可能会更清晰,这样就不会给人留下中心化是计算 PCA 所必需的印象。

    • James Carmichael 2022 年 4 月 15 日 上午 7:36 #

      谢谢你的反馈,Chris!

发表回复

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