加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – 我的PCA有什么问题?

发布时间:2020-12-16 23:02:56 所属栏目:Python 来源:网络整理
导读:我的代码: 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 vdef load_iris(path): lines = [] with open(path)
我的代码:
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中分解是协方差矩阵,根据定义总是平方(即,这些列是原始矩阵的各个数据点对于行,每个单元格是这两个点的协方差,这是证明的由主对角线下降 – 给定的数据点与本身具有完美的协方差).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读