PCA求解思路

来源:互联网 发布:linux终端装中文输入法 编辑:程序博客网 时间:2024/05/01 12:20

学习完了NG的PCA和《机器学习实战》的PCA


有一点很疑惑不解,对矩阵A,

NG是先用A - Amean,然后求协方差矩阵 covA = 1/m * AT * A 然后进行SVD分解,得到 U

因为 1/m*( AT * A) = V * (lambda**2/m) * VT  ,所以其实就是求出对A进行SVD分解的V


《实战》是用A - Amean, 然后求协方差矩阵 covA = 1/m * AT *A 然后求特征值和特征向量

也就是对A进行 SVD分解之后得到的V


那么问题就来了,为什么一定要求协方差矩阵,而不是直接对A进行SVD分解得到V呢?

想太多也没有用,直接来实践吧,直接修改《实战》中的代码


原代码:

def pca(dataMat, topNfeat = 9999999):
    meanVals = mean(dataMat, axis = 0)
    meanRemoved = dataMat - meanVals
    #covariance matrix, x.T * x
    #If rowvar is True (default), then each row represents a variable, with observations in the columns
   
covMat = cov(meanRemoved, rowvar = False)
    #Compute the eigenvalues and right eigenvectors of a square array.
    eigVals,eigVects = linalg.eig(mat(covMat))
    #Returns the indices that would sort an array.

    eigValInd = argsort(eigVals)
    eigValInd = eigValInd[:-(topNfeat + 1):-1]
    redEigVects = eigVects[:,eigValInd]
    lowDDataMat = meanRemoved * redEigVects
    reconMat = (lowDDataMat * redEigVects.T) + meanVals
    return lowDDataMat, reconMat


修改后的代码:

def pca(dataMat, topNfeat = 9999999):
    meanVals = mean(dataMat, axis = 0)
    meanRemoved = dataMat - meanVals
    #covariance matrix, x.T * x
    #If rowvar is True (default), then each row represents a variable, with observations in the columns
    #covMat = cov(meanRemoved, rowvar = False)
    #Compute the eigenvalues and right eigenvectors of a square array.
    #eigVals,eigVects = linalg.eig(mat(covMat))
    #Returns the indices that would sort an array.
    s,eigVals,d = linalg.svd(meanRemoved)
    eigVects = d.T

    
    eigValInd = argsort(eigVals)
    eigValInd = eigValInd[:-(topNfeat + 1):-1]
    redEigVects = eigVects[:,eigValInd]
    lowDDataMat = meanRemoved * redEigVects
    reconMat = (lowDDataMat * redEigVects.T) + meanVals
    return lowDDataMat, reconMat



只有一点点小改动,就是不求协方差矩阵,而是直接对减去平均值之后的矩阵进行SVD分解,然后求出V


然后得出的结果,一模一样


然后更改《实战》里查看特征值的代码

不求协方差矩阵,而是直接对减去平均值之后的矩阵进行SVD分解,然后查看lambda

记住协方差矩阵的特征值为lambda**2/m

所以我们对求得的lambda先平方,再除以样本的数目,得出的结果。。仍然是一模一样


也就是说,按照我的推论,不求协方差矩阵,而是直接对减去平均值之后的矩阵进行SVD分解,然后求出V,这样的推论是合理的。


如果有不对的地方,请大家回复一下帮我改正,感谢。



**************************************************************************分割线********************************************************************************

因为尝试了可以直接减去平均值之后的矩阵进行SVD分解,然后求出V

又因为不理解PCA的本质,所以尝试了不减去平均值,直接对原矩阵进行SVD分解,

得出的结果如下


查了资料,这样的效果并不好,因为PCA寻找的是“保留更多信息的维度”,也就是说在这个维度的投影尽量分散,如果不先求均值的话,就达不到分散的效果。。这样求的是过原点的尽量分散的维度。这并不符合我们的目的

更详细的理解:
http://www.360doc.com/content/13/1124/02/9482_331688889.shtml

看完我知道了,我的计算方法虽然没有什么数学上的错误。。可是不方便理解。GG



TruncatedSVD is very similar to PCA, but differs in that it works on sample matrices X directly instead of their covariance matrices. When the columnwise (per-feature) means of X are subtracted from the feature values, truncated SVD on the resulting matrix is equivalent to PCA.
0 0