sklearn PCA的explained_variance_与scipy eigs特征值差异问题
为什么scipy的eigs和sklearn的PCA得到的特征值不一致?
你在开展主成分分析(PCA)工作时,发现两种获取特征值的方式结果存在差异:通过scipy.sparse.linalg.eigs方法,以及sklearn.decomposition.PCA的explained_variance_属性获取的特征值并不一致。你理解特征向量可能因标量倍数不同而有差异,但无法理解特征值为何也会不同。
示例代码:
import numpy as np import scipy.sparse.linalg as ll from sklearn.decomposition import PCA a = np.array([[0,0,0],[0,0,1],[0,1,0]]) w1, v1 = ll.eigs(a, k=3) w2 = PCA(n_components=3).fit(a).explained_variance_
运行结果:
w1.real array([ 1., -1., 0.]) w2 array([0.5 , 0.16666667, 0. ])
差异原因解析
这既不是代码问题,也不是你误解了线性代数概念,而是两者计算的根本不是同一个矩阵的特征值:
scipy.sparse.linalg.eigs:直接对原始输入矩阵
a求解特征值,得到的是矩阵a本身的特征值,对应你得到的[1., -1., 0.],这个结果是完全正确的。sklearn.decomposition.PCA.explained_variance_:PCA的核心流程是对数据做去中心化后计算协方差矩阵,再求解协方差矩阵的特征值,具体步骤如下:
- 去中心化:先计算输入数据每列的均值,然后用原始数据减去均值。你的矩阵
a每列均值为[0, 1/3, 1/3],去中心化后的矩阵为:[[0, -1/3, -1/3], [0, -1/3, 2/3], [0, 2/3, -1/3]] - 计算协方差矩阵:用去中心化后的矩阵计算样本协方差矩阵(除以样本数-1=2),得到的协方差矩阵为:
[[0, 0, 0], [0, 1/3, -1/18], [0, -1/18, 1/3]] - 求解特征值:这个协方差矩阵的特征值就是
[0.5, 0.16666667, 0.],和w2的结果完全匹配。
- 去中心化:先计算输入数据每列的均值,然后用原始数据减去均值。你的矩阵
简单来说,eigs求的是原始矩阵的特征值,而PCA的explained_variance_求的是去中心化后数据的协方差矩阵的特征值,两者计算对象不同,结果自然存在差异。
内容的提问来源于stack exchange,提问作者CharlieCCC
相关产品推荐
相关产品推荐

