python – 我的PCA有什么问题?

前端之家收集整理的这篇文章主要介绍了python – 我的PCA有什么问题?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我的代码
from numpy import *

def pca(orig_data):
    data = array(orig_data)
    data = (data - data.mean(axis=0)) / data.std(axis=0)
    u,s,v = linalg.svd(data)
    print s #should be s**2 instead!
    print v

def load_iris(path):
    lines = []
    with open(path) as input_file:
        lines = input_file.readlines()
    data = []
    for line in lines:
        cur_line = line.rstrip().split(',')
        cur_line = cur_line[:-1]
        cur_line = [float(elem) for elem in cur_line]
        data.append(array(cur_line))
    return array(data)

if __name__ == '__main__':
    data = load_iris('iris.data')
    pca(data)

虹膜数据集:http://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data

输出

[ 20.89551896  11.75513248   4.7013819    1.75816839]
[[ 0.52237162 -0.26335492  0.58125401  0.56561105]
 [-0.37231836 -0.92555649 -0.02109478 -0.06541577]
 [ 0.72101681 -0.24203288 -0.14089226 -0.6338014 ]
 [ 0.26199559 -0.12413481 -0.80115427  0.52354627]]

所需输出
特征值 – [2.9108 0.9212 0.1474 0.0206]
主要组件 – 与我相同,但转置好,我猜

另外,linalg.eig函数输出是什么?根据PCA对维基百科的描述,我应该这样:

cov_mat = cov(orig_data)
val,vec = linalg.eig(cov_mat)
print val

但是在我在线上发现的教程中,输出结果并不完全匹配.另外,如果我有四个维度,我以为我应该有4个特征值,而不是像eig给我的150个.我做错了吗?

编辑:我注意到,值不同于150,这是数据集中元素的数量.此外,特征值应该等于维数,在这种情况下,4.我不明白是为什么这种差异正在发生.如果我简单地将特征值分为len(数据),我可以得到我想要的结果,但是我不明白为什么.无论哪种方式,特征值的比例都没有改变,但对我来说很重要,所以我想了解发生了什么.

解决方法

你分解了错误的矩阵.

主成分分析需要操纵特征向量/特征值
的协方差矩阵,而不是数据本身.从m×n数据矩阵创建的协方差矩阵将是一个m×m矩阵,其中沿着主对角线的矩阵.

您确实可以使用cov功能,但是您需要进一步操纵数据.使用类似的函数corrcoef可能更容易一些:

import numpy as NP
import numpy.linalg as LA

# a simulated data set with 8 data points,each point having five features
data = NP.random.randint(0,10,40).reshape(8,5)

# usually a good idea to mean center your data first:
data -= NP.mean(data,axis=0)

# calculate the covariance matrix 
C = NP.corrcoef(data,rowvar=0)
# returns an m x m matrix,or here a 5 x 5 matrix)

# now get the eigenvalues/eigenvectors of C:
eval,evec = LA.eig(C)

为了获得特征向量/特征值,我没有使用SVD分解协方差矩阵,
虽然,你当然可以.我喜欢用NumPy(或SciPy’s)中的eig来计算它们,
LA模块 – 它比svd更容易使用,返回值是特征向量
和特征值本身,没有别的.相反,如你所知,svd不直接返回这些.

授予SVD函数将分解任何矩阵,而不仅仅是方形(eig函数被限制);然而,当做PCA时,你总是会有一个方阵来分解,无论您的数据的形式如何.这显然是因为您的矩阵在PCA中分解是协方差矩阵,根据定义总是平方(即,这些列是原始矩阵的各个数据点对于行,每个单元格是这两个点的协方差,这是证明的由主对角线下降 – 给定的数据点与本身具有完美的协方差).

猜你在找的Python相关文章