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
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)*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
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
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参与运算。
可以看出两者的输出是相同的。因此所谓的np.cov(X)其实就是把np.cov(x,y)中两个变量所有的维度纵向拼接在一起作为X参与运算。
作者:你的雷哥
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。