【问题标题】:Python Sklearn Covariance Matrix diagonal entries incorrect?Python Sklearn协方差矩阵对角线条目不正确?
【发布时间】:2017-03-02 21:36:06
【问题描述】:

我正在尝试对某些数据执行 PCA。据我所知,相关矩阵应该在主对角线上有 1 的条目。这不是我在 sklearn PCA 中看到的 .get_covariance()。我想知道为什么会这样?
出于我自己的目的,我可以对矩阵进行缩放以获得对角元素为1 的矩阵,但我只是想知道,既然我的数据已经标准化,为什么对角线条目仍然不是1

In [1]: import pandas as pd

In [2]: import numpy as np                                                                                                                      

In [3]: from sklearn.decomposition import PCA                                                                                                   

In [4]: df = pd.read_csv('myTable.csv')                                                                                                         

In [5]: df                                                                                                                                      
Out[5]:                                                                                                                                         
         a1        a2        a3        a4        a5                                                                                             
0 -0.559104  0.185914 -2.331367  0.231150  0.357008                                                                                             
1  0.769835 -0.408685  0.375754  0.051397 -0.075885                                                                                             
2 -1.376530 -0.764808 -2.383611 -0.327153  1.746765                                                                                             
3 -0.830105 -0.197574  1.835807 -0.695089  0.881297                                                                                             
4 -0.991861  1.089319 -0.164139 -0.335003  0.795937                                                                                             
5 -1.132968 -2.240598 -0.101935  0.680038 -0.033921                                                                                             
6 -1.205631 -1.492009 -0.602400 -0.065256 -0.494267                                                                                             
7 -1.210978 -1.220986 -0.017062  0.024422 -0.224585                                                                                             
8 -0.332957  2.114870  0.818108  0.612831 -1.879758                                                                                             
9 -0.350612 -0.563872  0.869303 -0.325626 -0.372874                                                                                             

In [6]: df = (df-df.mean())/df.std()                                                                                                            

In [7]: pca = PCA()                                                                                                                             

In [8]: pca.fit(df)                                                                                                                             
Out[8]: PCA(copy=True, n_components=None, whiten=False)  

In [10]: pca.explained_variance_, pca.components_, pca.get_covariance()                                                                         
Out[10]:                                                                                                                                        
(array([ 1.8780651 ,  1.1526052 ,  0.78052872,  0.55167761,  0.13712337]),                                                                      
 array([[-0.47790108, -0.36036503, -0.38619941, -0.35716396,  0.60417838],                                                                      
        [ 0.25426743,  0.32305024,  0.47784502, -0.72831952,  0.26870322],                                                                      
        [-0.17613902, -0.7303121 ,  0.6250759 , -0.05118019, -0.20562097],                                                                      
        [ 0.82132736, -0.45982165, -0.21938834,  0.03274499,  0.25452296],                                                                      
        [ 0.03681087, -0.14485808, -0.42855924, -0.58162955, -0.67505936]]),                                                                    
 array([[ 0.9       ,  0.30943895,  0.29916112,  0.12605405, -0.32333097],                                                                      
        [ 0.30943895,  0.9       ,  0.14715469,  0.00295615, -0.24279645],                                                                      
        [ 0.29916112,  0.14715469,  0.9       , -0.13683409, -0.38167791],                                                                      
        [ 0.12605405,  0.00295615, -0.13683409,  0.9       , -0.56418468],                                                                      
        [-0.32333097, -0.24279645, -0.38167791, -0.56418468,  0.9       ]]))   

关闭
问题在于我的标准化。我应该按照Tonechas 的建议使用df.std(ddof=0)

【问题讨论】:

    标签: python scikit-learn correlation covariance pca


    【解决方案1】:

    您需要将标准偏差标准化为 N 而不是 N-1(这是默认值)。这可以在对pandas.DataFrame.std() 的调用中使用ddof 参数进行更改,如下所示:

    In [146]: from sklearn.decomposition import PCA
    
    In [147]: df
    Out[147]: 
             a1        a2        a3        a4        a5
    0 -0.559104  0.185914 -2.331367  0.231150 -0.559104
    1  0.769835 -0.408685  0.375754  0.051397  0.769835
    2 -1.376530 -0.764808 -2.383611 -0.327153 -1.376530
    3 -0.830105 -0.197574  1.835807 -0.695089 -0.830105
    4 -0.991861  1.089319 -0.164139 -0.335003 -0.991861
    5 -1.132968 -2.240598 -0.101935  0.680038 -1.132968
    6 -1.205631 -1.492009 -0.602400 -0.065256 -1.205631
    7 -1.210978 -1.220986 -0.017062  0.024422 -1.210978
    8 -0.332957  2.114870  0.818108  0.612831 -0.332957
    9 -0.350612 -0.563872  0.869303 -0.325626 -0.350612
    
    In [148]: df = (df-df.mean())/df.std(ddof=0)
    
    In [149]: pca = PCA()
    
    In [150]: pca.fit(df)
    Out[150]: 
    PCA(copy=True, iterated_power='auto', n_components=None, random_state=None,
      svd_solver='auto', tol=0.0, whiten=False)
    
    In [151]: pca.get_covariance()
    Out[151]: 
    array([[ 1.  ,  0.34,  0.33,  0.14,  1.  ],
           [ 0.34,  1.  ,  0.16,  0.  ,  0.34],
           [ 0.33,  0.16,  1.  , -0.15,  0.33],
           [ 0.14,  0.  , -0.15,  1.  ,  0.14],
           [ 1.  ,  0.34,  0.33,  0.14,  1.  ]])
    

    【讨论】:

    • 所以我没有正确缩放/标准化我的数据?
    • 如果我理解正确,不一定是因为 pca.get_covariance() 返回一个估计值?
    • 为什么不一样?数据还是一样的,只是表示方式不同。
    • 我已经缩放了每一列? df.mean()df.std() 返回数组——列的均值和标准差。
    • 这可能就是原因。我不敢相信我忘记了这一点。谢谢:)
    【解决方案2】:

    PCA 和相关矩阵是不同的东西。如果具有转置的居中和归一化数据(在野外可能存在略微不同的定义)PCA 是与特征分解没有不同的分解,则相关矩阵只是乘积。特别是,PC 是除正交外的简并,因此没有相关性。

    当然,这两者是相关的,例如,如果你所有的向量都是相关的,你会期望对应的 PC 具有高权重。

    【讨论】:

    • 可以,但是PCA不是基于相关矩阵吗?
    • @AsheKetchum 我认为它的原始形式不会标准化输入的长度,所以它是协方差矩阵。但是你是对的,在实践中很多人选择正常化。尽管如此,这只是计算 PCA 的一种方法使用该矩阵作为中间体。它们不相同,也不具有相同的对角线元素。
    • 是的,我明白了。我的问题是为什么我的矩阵在我已经标准化之后不是相关矩阵。另一方面,我从来没有说过PCA,一种分析,与相关矩阵,一个矩阵是一样的。
    • @AsheKetchum 好的,我想我误解了你的问题。对此感到抱歉。
    • 没问题 :) 感谢您的帮助!
    猜你喜欢
    • 2017-02-26
    • 2017-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-13
    相关资源
    最近更新 更多