python 矩阵分析(求方差,协方差矩阵,特征值,特征向量......);PCA实现

1. 求均值

import numpy as np
X=np.array([1,2,3,4,5,6])
np.mean(X)
a = np.array([[1, 2], [3, 4]])
np.mean(a) # 将上面二维矩阵的每个元素相加除以元素个数(求平均数)
#输出:2.5
np.mean(a, axis=0) # axis=0,计算每一列的均值
#输出:array([ 2.,  3.])
np.mean(a, axis=1) # 计算每一行的均值
#输出:array([ 1.5,  3.5])

2. 求标准差和方差

import numpy as np
X=np.array([1,2,3,4,5,6])
np.std(X) #标准差
np.var(X) #方差

3. 协方差矩阵

两个特征X,Y(都是向量)的协方差公式:

cov(X,Y)=\frac{\sum_{i=1}^{n}(X_{i}-\bar{X})(Y_{i}-\bar{Y})}{n-1},    cov(X,Y)=cov(Y,X)

协方差具体的大小并不重要,但是它的正负是重要的。如果它的值是正的,这表明两个特征之间同时增加或减小;如果它的值是负的,这表明两个特征之间有一个增加而另一个减小。如果它的值为0,则表明两个特征之间是独立的。

如果有多个特征,可以计算协方差矩阵:

C=\begin{pmatrix} cov(1,1) cov(1,2) cov(1,3) \cdots cov(1,n) \\ cov(2,1) cov(2,2) cov(2,3) \cdots cov(2,n)\\ cov(3,1) cov(3,2) cov(3,3) \cdots cov(3,n)\\ \vdots \vdots \vdots \ddots \vdots \\ cov(n,1) cov(n,2) cov(n,3) \cdots cov(n,n) \end{pmatrix}

import numpy as np
T=np.array([9,15,25,14,10,18,0,16,5,19,16,20])
S=np.array([39,56,93,61,50,75,32,85,42,70,66,80])
T=T[:,np.newaxis]
S=S[:,np.newaxis]
X=np.hstack((T,S))
np.cov(X.T)

求出的协方差输出如下:

array([[  47.71969697,  122.9469697 ],
       [ 122.9469697 ,  370.08333333]])

4. 计算特征值和特征向量

import numpy as np
cov_mat = np.cov(X_train_std.T)
eigen_vals, eigen_vecs = np.linalg.eig(cov_mat)#特征值是eigen_vals,特征向量是eigen_vecs, 
                                                #特征向量是按列放的,即一列代表一个特征向量

PCA的原理,假如原始数据集X是N*M(N是样本数,M是特征数)先计算出协方差矩阵的特征值和特征向量(M维),然后挑出对应特征值最大的特征向量(2个)组成映射矩阵W(M*2),用X*W即可得到降维后的数据集(N*2)。

#调用sklearn库实现PCA
from sklearn import decomposition
pca = decomposition.PCA()
pca.fit(X_arr) #X_arr是原始数据集,一行表示一个样本,一列表示一个feature
pca.n_components = 2 #降为两维
X_reduced = pca.fit_transform(X_arr) #X_reduced是降维后的数据集

#基于numpy自己实现PCA
import numpy as np
meanval=np.mean(X_arr, axis=0) #计算原始数据中每一列的均值,axis=0按列取均值
newData=X_arr-meanval #去均值化,每个feature的均值为0
covMat=np.cov(newData,rowvar=0) #计算协方差矩阵,rowvar=0表示数据的每一列代表一个feature
featValue, featVec=np.linalg.eig(covMat) #计算协方差矩阵的特征值和特征向量
index=np.argsort(featValue) #将特征值按从大到小排序,index保留的是对应原featValue中的下标
n_index=index[-1:-3:-1] #取最大的两维特征值在原featValue中的下标
n_featVec=featVec[:, n_index] #取最大的两维特征值对应的特征向量组成变换矩阵
lowData=np.dot(newData,n_featVec) #lowData=newData*n_featVec
highData=np.dot(lowData,n_featVec.T)+meanval #highData=(lowData*n_featVec.T)+meanval

 

你可能感兴趣的:(python)