Python Sklearn协方差矩阵对角线条目不正确?
我正在尝试对一些数据执行PCA。据我所知,相关矩阵的主对角线上应该有Python Sklearn协方差矩阵对角线条目不正确?,python,scikit-learn,correlation,covariance,pca,Python,Scikit Learn,Correlation,Covariance,Pca,我正在尝试对一些数据执行PCA。据我所知,相关矩阵的主对角线上应该有1的条目。这不是我在sklearn PCA中看到的。获取协方差()。我想知道为什么会这样? 出于我自己的目的,我可以对矩阵进行缩放以获得对角线条目为1的矩阵,但我只是想知道,既然我已经标准化了我的数据,为什么对角线条目仍然不是1 In [1]: import pandas as pd In [2]: import numpy as np
1
的条目。这不是我在sklearn PCA中看到的。获取协方差()。我想知道为什么会这样?
出于我自己的目的,我可以对矩阵进行缩放以获得对角线条目为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 ]]))
关闭
问题在于我的标准化。我应该使用df.std(ddof=0)
,正如Tonechas
所建议的,主成分分析和相关矩阵是不同的东西。如果中心化和标准化数据及其转置(在野外可能有稍微不同的定义)PCA是与特征分解相似的分解,则相关矩阵就是乘积。特别是,除正交外,PCs是简并的,因此没有相关性
当然,这两者是相关的,例如,如果所有向量都是相关的,那么您会期望相应的PC具有高权重。您需要将标准偏差标准化为N,而不是N-1(默认值)。这可以使用调用中的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_convariance()返回一个估计值?为什么不同?数据还是一样的,只是表示方式不同。但我已经缩放了每一列了吗df.mean()
和df.std()
返回数组——列的平均值和std。这可能就是原因。真不敢相信我竟然忘了。谢谢:)当然可以,但PCA不是基于相关矩阵吗?@AsheKetchum我认为在其原始形式中,它不会使输入的长度正常化,因此它将是协方差矩阵。但你是对的,在实践中许多人选择正常化。尽管如此,计算主成分分析的唯一方法是将该矩阵用作中间矩阵。它们不一样,也没有相同的对角线元素。是的,我理解。我的问题是,在我已经归一化之后,为什么我的矩阵不是相关矩阵。另一方面,我从来没有说过PCA,一种分析,和相关矩阵,一种矩阵是一样的。@AsheKetchum好吧,我想我误解了你的问题。很抱歉。没问题:)谢谢你的帮助!