【问题标题】:Numpy.eig and the percentage of variance in PCANumpy.eig 和 PCA 中的方差百分比
【发布时间】:2011-01-27 23:35:35
【问题描述】:

Picking up from where we left...

所以我可以使用 linalg.eig 或 linalg.svd 来计算 PCA。当它们被输入相同的数据时,每一个都会返回不同的主成分/特征向量和特征值(我目前正在使用 Iris 数据集)。

查看 here 或任何其他将 PCA 应用于 Iris 数据集的教程,我会发现特征值是 [2.9108 0.9212 0.1474 0.0206]eig 方法为我提供了一组不同的特征值/向量,我不介意使用这些特征值/向量,除了这些特征值,一旦求和,就等于维数 (4),并且可用于查找每个组件的数量对总方差有贡献。

采用linalg.eig 返回的特征值我做不到。例如,返回的值为[9206.53059607 314.10307292 12.03601935 3.53031167]。在这种情况下,方差的比例为[0.96542969 0.03293797 0.00126214 0.0003702]This other page 说(“一个组件解释的变化比例就是它的特征值除以特征值之和。”)

由于每个维度解释的方差应该是恒定的(我认为),所以这些比例是错误的。所以,如果我使用 svd() 返回的值,这是所有教程中使用的值,我可以从每个维度获得正确的变化百分比,但我想知道为什么 eig 返回的值不能被这样使用。

我假设返回的结果仍然是投影变量的有效方法,那么有没有办法转换它们,以便我可以得到每个变量解释的正确比例的方差?换句话说,我可以使用eig 方法并且仍然有每个变量的方差比例吗?此外,这种映射是否只能在特征值中完成,以便我可以同时拥有真实的特征值和归一化的特征值?

抱歉,顺便提了这么长的文章。这是一个(::),因为已经走到了这一步。假设您不只是阅读了这一行。

【问题讨论】:

  • 你可能想在math.stackexchange.com上发帖
  • @S.Lott 我曾经尝试在那里发帖,他们说该网站仅用于真正的高级数学和其他东西,所以我宁愿不再去那里,除非我真的必须这样做。
  • 由于这不是编程(无代码),因此您不太可能在这里获得帮助。一个带有刻薄 cmets 的问题并没有多大意义。在在这里等待答案之前,我会在那里开始搜索相关问题。阅读大量问题以了解问题的提出方式非常重要,这样您才能更好地适应。例子。 “很抱歉写了这么长的文章”是蹩脚的。如果它很长,你可以把它修短并成为重点。
  • @S.Lott 我的问题有点特定于 python。我可以在那里问(我在另一个选项卡上输入问题),但我很有信心他们会告诉我他们因此无能为力。另外,我写了很多文字,因为如果我读到的其他问题有任何迹象,你经常会让人们要求澄清你的意思。我很确定你很生气,因为你刚刚读了最后一行,却没有得到 cookie
  • “我很确定你疯了”。那你就大错特错了。

标签: python math numpy pca


【解决方案1】:

Doug's answer to your previous question 并实现以下两个函数,我得到如下所示的输出:

def pca_eig(orig_data):
    data = array(orig_data)
    data = (data - data.mean(axis=0)) / data.std(axis=0)
    C = corrcoef(data, rowvar=0)
    w, v = linalg.eig(C)
    print "Using numpy.linalg.eig"
    print w
    print v

def pca_svd(orig_data):
    data = array(orig_data)
    data = (data - data.mean(axis=0)) / data.std(axis=0)
    C = corrcoef(data, rowvar=0)
    u, s, v = linalg.svd(C)
    print "Using numpy.linalg.svd"
    print u
    print s
    print v

输出:

Using numpy.linalg.eig
[ 2.91081808  0.92122093  0.14735328  0.02060771]
[[ 0.52237162 -0.37231836 -0.72101681  0.26199559]
 [-0.26335492 -0.92555649  0.24203288 -0.12413481]
 [ 0.58125401 -0.02109478  0.14089226 -0.80115427]
 [ 0.56561105 -0.06541577  0.6338014   0.52354627]]

Using numpy.linalg.svd
[[-0.52237162 -0.37231836  0.72101681  0.26199559]
 [ 0.26335492 -0.92555649 -0.24203288 -0.12413481]
 [-0.58125401 -0.02109478 -0.14089226 -0.80115427]
 [-0.56561105 -0.06541577 -0.6338014   0.52354627]]
[ 2.91081808  0.92122093  0.14735328  0.02060771]
[[-0.52237162  0.26335492 -0.58125401 -0.56561105]
 [-0.37231836 -0.92555649 -0.02109478 -0.06541577]
 [ 0.72101681 -0.24203288 -0.14089226 -0.6338014 ]
 [ 0.26199559 -0.12413481 -0.80115427  0.52354627]]

在这两种情况下,我都得到了所需的特征值。

【讨论】:

    【解决方案2】:

    您确定这两种情况的数据相同并且尺寸顺序正确(您不是在旋转数组中发​​送吗?)?我敢打赌,如果你正确使用它们,你会发现它们都会给出相同的结果;)

    【讨论】:

      【解决方案3】:

      我知道执行 PCA 的方法有 3 种:源自相关矩阵、协方差矩阵的特征值分解,或基于未缩放和未居中的数据。听起来您正在传递 linalg.eig 正在处理未缩放的数据。无论如何,这只是一个猜测。一个更好的地方是stats.stackexchange.com。 math.stackexchange.com 上的人不使用实际数字。 :)

      【讨论】:

      • 我同意stats.stackexchange.com 可能是解决这个问题的更好场所。
      • 非PhDs应该有algorithm.stackexchange吗?
      【解决方案4】:

      我建议对 PCA 使用 SVD(奇异值分解),因为
      1) 它直接为您提供所需的值和矩阵
      2) 它很强大。
      请参阅 SO 上的 principal-component-analysis-in-python 以获取(惊喜)虹膜数据的示例。 运行它给出了

      read iris.csv: (150, 4)
      Center -= A.mean: [ 5.84  3.05  3.76  1.2 ]
      Center /= A.std: [ 0.83  0.43  1.76  0.76]
      
      SVD: A (150, 4) -> U (150, 4)  x  d diagonal  x  Vt (4, 4)
      d^2: 437 138 22.1 3.09
      % variance: [  72.77   95.8    99.48  100.  ]
      PC 0 weights: [ 0.52 -0.26  0.58  0.57]
      PC 1 weights: [-0.37 -0.93 -0.02 -0.07]
      

      你看到对角矩阵 d 来自 SVD,平方, 给出从 PC 0 到 PC 1 的总方差的比例 ...

      这有帮助吗?

      【讨论】:

        猜你喜欢
        • 2017-10-02
        • 2016-02-04
        • 2019-12-09
        • 2020-11-19
        • 1970-01-01
        • 2011-10-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多