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

时间:2011-01-27 23:35:36

标签: python math numpy pca

Picking up from where we left...

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

通过应用于Iris数据集的PCA查看here或任何其他教程,我会发现特征值为[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()返回的值(这是所有教程中使用的值),我可以从每个维度获得正确的变异百分比,但我想知道为什么{{1}返回的值}不能这样使用。

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

对不起,写了很长的btw。这是迄今为止的eig。假设你没有读过这一行。

4 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

我知道有三种方法可以做PCA:从相关矩阵的特征值分解,协方差矩阵或未缩放和未中心数据得出。听起来你正在传递linalg.eig正在处理未缩放的数据。无论如何,这只是猜测。问题的最佳位置是stats.stackexchange.com。 math.stackexchange.com上的人不使用实际数字。 :)

答案 3 :(得分:0)

我建议使用SVD,奇异值分解,用于PCA,因为
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]

你看到SVD的对角矩阵d,平方, 给出PC 0,PC 1 ...

的总方差比例

这有帮助吗?