Numpy.eig与PCA中的方差百分比

3 投票
4 回答
7126 浏览
提问于 2025-04-16 10:45

接着上次的内容继续...

我可以用linalg.eig或者linalg.svd来计算主成分分析(PCA)。这两种方法在处理同样的数据时(我现在用的是鸢尾花数据集),返回的主成分(特征向量)和特征值是不同的。

这里或者其他任何关于鸢尾花数据集的PCA教程中,我发现特征值是[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]另一篇文章提到(“一个成分解释的变异比例就是它的特征值除以特征值的总和。”)

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

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

抱歉写了这么长的内容。给自己一个(::),因为能看到这里。假设你没有只读这一行。

4 个回答

0

你确定这两种情况的数据是一样的吗?还有,维度的顺序正确吗?(你不是在发送旋转过的数组吧?)我敢打赌,如果你用对了方法,它们的结果会是一样的;)

0

我知道有三种方法可以做主成分分析(PCA):一种是通过相关矩阵的特征值分解,另一种是通过协方差矩阵,最后一种是在未缩放和未中心化的数据上进行。听起来你是在用 linalg.eig 处理未缩放的数据。总之,这只是我的猜测。你可以把这个问题放在 stats.stackexchange.com 上问,那里的朋友们会更合适。math.stackexchange.com 的人不太用实际数字。:)

4

根据Doug对你之前问题的回答,我实现了下面这两个函数,得到了如下的输出:

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]]

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

撰写回答