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中分解是协方差矩阵,根据定义总是平方(即,这些列是原始矩阵的各个数据点对于行,每个单元格是这两个点的协方差,这是证明的由主对角线下降 – 给定的数据点与本身具有完美的协方差).