Python:使用SVD实现PCA

Python:使用SVD实现PCA,python,data-science,pca,svd,Python,Data Science,Pca,Svd,我试图找出使用奇异值分解的PCA与使用特征向量分解的PCA之间的区别 绘制以下矩阵: B = np.array([ [1, 2], [3, 4], [5, 6] ]) 当使用特征向量分解计算该矩阵B的PCA时,我们遵循以下步骤: 通过从每列中减去列平均值,将数据(B项)居中 计算协方差矩阵C=Cov(B)=B^T*B/(m-1),其中m=#行B 求C的特征向量 PCs=X*特

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

绘制以下矩阵:

 B = np.array([          [1, 2],
                         [3, 4],
                         [5, 6] ])
当使用特征向量分解计算该矩阵B的PCA时,我们遵循以下步骤:

  • 通过从每列中减去列平均值,将数据(B项)居中
  • 计算协方差矩阵
    C=Cov(B)=B^T*B/(m-1)
    ,其中m=#行B
  • 求C的特征向量
  • PCs=X*特征向量
  • 使用SVD计算矩阵B的PCA时,我们遵循以下步骤:

  • 计算B的奇异值分解:
    B=U*Sigma*V.T
  • PCs=U*Sigma
  • 对于给定的矩阵,我已经完成了这两个步骤

    通过特征向量分解,我得到以下结果:

    [[-2.82842712  0.        ]
     [ 0.          0.        ]
     [ 2.82842712  0.        ]]
    
    通过SVD,我获得了以下结果:

    [[-2.18941839  0.45436451]
     [-4.99846626  0.12383458]
     [-7.80751414 -0.20669536]]
    
    通过特征向量分解得到的结果是作为解给出的结果。那么,为什么SVD得到的结果不同呢


    我知道:
    C=Cov(B)=V*(Sigma^2)/(m-1))*V.T
    ,我觉得这可能与为什么这两个结果不同有关。还是。有人能帮我更好地理解吗?

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

    sklearn.decomposition.PCA的代码:

    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))
    
    PCA的输出:

    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:

    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的输出:

    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.]]
    

    非常感谢。我还计算:如果我将矩阵B居中,然后执行SVD,结果等于特征向量分解。我不知道我还得把矩阵居中