首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python:使用SVD实现PCA

Python:使用SVD实现PCA
EN

Stack Overflow用户
提问于 2020-03-03 13:22:36
回答 1查看 12K关注 0票数 4

我试图找出采用奇异值分解的PCA与使用特征向量分解的PCA的区别。

如下图所示:

代码语言:javascript
复制
 B = np.array([          [1, 2],
                         [3, 4],
                         [5, 6] ])

当使用特征向量分解计算此矩阵B的PCA时,我们遵循以下步骤:

C

  • PCs = X * eigen_vecs

  1. 通过从列
  2. 中减去列平均值来对数据(B的条目)进行中心化,计算协方差矩阵C = Cov(B) = B^T * B / (m -1),其中m=#行B
  3. 找到了
  4. 的特征向量。

当使用SVD计算矩阵B的PCA时,我们遵循以下步骤:

B:B = U * Sigma * V.T

  • PCs = U * Sigma

  1. 计算奇异值

对于给定的矩阵,我两者都做了。

利用特征向量分解,得到了如下结果:

代码语言:javascript
复制
[[-2.82842712  0.        ]
 [ 0.          0.        ]
 [ 2.82842712  0.        ]]

通过SVD,我得到了以下结果:

代码语言:javascript
复制
[[-2.18941839  0.45436451]
 [-4.99846626  0.12383458]
 [-7.80751414 -0.20669536]]

用特征向量分解得到的结果是作为解的结果。那么,为什么SVD的结果是不同的呢?

我知道:C = Cov(B) = V * (Sigma^2)/(m-1)) * V.T和我有一种感觉,这可能与这两种结果不同的原因有关。还是这样。有人能帮我更好地理解吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-06 17:19:18

请参阅下面的矩阵与sklearn.decomposition.PCA和numpy.linalg.svd的比较。您能否比较或发布如何导出SVD结果。

Sklearn.decomposition.PCA代码:

代码语言:javascript
复制
from sklearn.decomposition import PCA
import numpy as np 
np.set_printoptions(precision=3)

B = np.array([[1.0,2], [3,4], [5,6]])

B1 = B.copy() 
B1 -= np.mean(B1, axis=0) 
n_samples = B1.shape[0]
print("B1 is B after centering:")
print(B1)

cov_mat = np.cov(B1.T)
pca = PCA(n_components=2) 
X = pca.fit_transform(B1)
print("X")
print(X)

eigenvecmat =   []
print("Eigenvectors:")
for eigenvector in pca.components_:
   if eigenvecmat == []:
        eigenvecmat = eigenvector
   else:
        eigenvecmat = np.vstack((eigenvecmat, eigenvector))
   print(eigenvector)
print("eigenvector-matrix")
print(eigenvecmat)

print("CHECK FOR PCA:")
print("X * eigenvector-matrix (=B1)")
print(np.dot(PCs, eigenvecmat))

常设仲裁院的产出:

代码语言:javascript
复制
B1 is B after centering:
[[-2. -2.]
 [ 0.  0.]
 [ 2.  2.]]
X
[[-2.828  0.   ]
 [ 0.     0.   ]
 [ 2.828  0.   ]]
Eigenvectors:
[0.707 0.707]
[-0.707  0.707]
eigenvector-matrix
[[ 0.707  0.707]
 [-0.707  0.707]]
CHECK FOR PCA:
X * eigenvector-matrix (=B1)
[[-2. -2.]
 [ 0.  0.]
 [ 2.  2.]]

numpy.linalg.svd:

代码语言:javascript
复制
print("B1 is B after centering:")
print(B1)

from numpy.linalg import svd 
U, S, Vt = svd(X1, full_matrices=True)

print("U:")
print(U)
print("S used for building Sigma:")
print(S)
Sigma = np.zeros((3, 2), dtype=float)
Sigma[:2, :2] = np.diag(S)
print("Sigma:")
print(Sigma)
print("V already transposed:")
print(Vt)
print("CHECK FOR SVD:")
print("U * Sigma * Vt (=B1)")
print(np.dot(U, np.dot(Sigma, Vt)))

SVD的产出:

代码语言:javascript
复制
B1 is B after centering:
[[-2. -2.]
 [ 0.  0.]
 [ 2.  2.]]
U:
[[-0.707  0.     0.707]
 [ 0.     1.     0.   ]
 [ 0.707  0.     0.707]]
S used for building Sigma:
[4. 0.]
Sigma:
[[4. 0.]
 [0. 0.]
 [0. 0.]]
V already transposed:
[[ 0.707  0.707]
 [-0.707  0.707]]
CHECK FOR SVD:
U * Sigma * Vt (=B1)
[[-2. -2.]
 [ 0.  0.]
 [ 2.  2.]]
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60508233

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档