pca算法实现

pca基础知识不了解的可以先看下一这篇博客:https://www.cnblogs.com/lliuye/p/9156763.html

 

 

 

 

 

 

 

 

 具体算法实现如下:

 1 import numpy as np
 2 import matplotlib.pyplot as plt
 3 # 载入数据
 4 data = np.genfromtxt("data.csv", delimiter=",")
 5 x_data = data[:,0]
 6 y_data = data[:,1]
 7 plt.scatter(x_data,y_data)
 8 plt.show()
 9 print(x_data.shape)
10 # 数据中心化
11 def zeroMean(dataMat):
12     # 按列求平均,即各个特征的平均
13     meanVal = np.mean(dataMat, axis=0)
14     newData = dataMat - meanVal
15     return newData, meanVal
16 newData,meanVal=zeroMean(data)
17 print(newData.shape)
18 # np.cov用于求协方差矩阵,参数rowvar=0说明数据一行代表一个样本,若非0,说明传入的数据一列代表一个样本。
19 covMat = np.cov(newData, rowvar=0)#因为是行作为样本,所以列作为特征,得到的协方差是2*2
20 # 协方差矩阵
21 print(covMat)
22 # np.linalg.eig求矩阵的特征值和特征向量
23 eigVals, eigVects = np.linalg.eig(np.mat(covMat))
24 # 特征值
25 print(eigVals)
26 # 特征向量
27 print(eigVects.shape)
28 # 对特征值从小到大排序
29 eigValIndice = np.argsort(eigVals)
30 eigValIndice
31 top = 1
32 # 最大的n个特征值的下标
33 n_eigValIndice = eigValIndice[-1:-(top+1):-1]
34 print(n_eigValIndice)
35 # 最大的n个特征值对应的特征向量
36 n_eigVect = eigVects[:,n_eigValIndice]
37 print(n_eigVect.shape)
38 # 低维特征空间的数据
39 lowDDataMat = newData*n_eigVect#原始数据投射到选取的特征向量上
40 print(lowDDataMat.shape)#低纬数据
41 # 利用低纬度数据来重构数据
42 reconMat = (lowDDataMat*n_eigVect.T) + meanVal#降维的逆操作
43 reconMat
44 # 载入数据
45 data = np.genfromtxt("data.csv", delimiter=",")
46 x_data = data[:,0]
47 y_data = data[:,1]
48 plt.scatter(x_data,y_data)
49 
50 # 重构的数据
51 x_data = np.array(reconMat)[:,0]
52 y_data = np.array(reconMat)[:,1]
53 plt.scatter(x_data,y_data,c='r')
54 plt.show()
55 
56 plt.show()

 

 关于np.cov的用法详细如下:

1. np.cov(x)
 
x=[1,2,3,4]
np.cov(x)12
输出为 array(1.6666666666666665),一开始我以为当x为一个行向量时,cov(x)计算的就是x的方差。但是通过观察发现
 
np.var(x)*4     #output:5
np.cov(x)*3     #output:512
np.cov(x)这种情况计算的是x方差的无偏估计,即s2=∑ni=1(x−x^)n−1s2=∑i=1n(x−x^)n−1,而np.var(x)计算的则是s2=∑ni=1(x−x^)ns2=∑i=1n(x−x^)n
接着我们再假设x为一个4*3的矩阵
 
X=np.array([[1 ,5 ,6] ,[4 ,3 ,9 ],[ 4 ,2 ,9],[ 4 ,7 ,2]])
np.cov(x)12
首先不同于matlab。在numpy中,将x的每一列视作一个独立的变量,因此这里一共有4个3维的变量,因此将会输出一个4*4的协方差矩阵
 
其中对角线元素是每个维度的方差,非对角线上的元素则是不同维度间的协方差。
2. np.cov(x,y)
在学习的过程中还有一点比较困惑的是np.cov(x)和np.cov(x,y)的区别,以下用代码来进行说明:
 
X=np.array([[1 ,5 ,6] ,[4 ,3 ,9 ],[ 4 ,2 ,9],[ 4 ,7 ,2]])
x=X[0:2]
y=X[2:4]
print(np.cov(X))
print(np.cov(x,y))12345
输出为
 
可以看出两者的输出是相同的。因此所谓的np.cov(X)其实就是把np.cov(x,y)中两个变量所有的维度纵向拼接在一起作为X参与运算。

 

posted @ 2019-11-12 22:50  你的雷哥  阅读(354)  评论(0编辑  收藏  举报