写在开头:个人认为还是理论最重要!还是理论最重要!还是理论最重要!重要事情说三遍!
本人最近用到了PCA相关知识,借此进行一定的记录。
同时本文是基于周志华《机器学习》来学习的!相当于也是个读书笔记!
(能力有限,如有不当,敬请谅解)
一、目的
1、降低维数(主要目的)
主成分分析 (Principal Component Analysis,简称 PCA)是最常用的一种降维方法。(具体可见西瓜书,也可以参考下面引用)
2、去噪
PCA也可以用作噪音的过滤,因为任何一个成分的变化影响都远远大于随机噪声的影响的,所以针对于噪声,各种的成分相对不受影响。即可以用主成分来重构原始数据。
3、原理
- 空间中有 个点 (这些点即可以理解为我们数据的特征,如图片的像素),首先对 数据进行归一化(保证其均值为0)。其中 空间中的坐标基向量均是两两正交的,坐标系基向量为 。
- 对 进行降维压缩得到 , 。其中 和 分别是样本 和 在 和 空间下的坐标。
- 由 得到 的过程可以如下表示: ;基于 重构 可以表示为: (基变换,坐标变换)。
所以 与 之间的距离表述如下,其中 :
最小化上式得到
。
二、代码
1、本文代码是通过加载原始的matlab 中的一个数组文件作为数据集的(数据集可以是任意的数据,但注意最后用plt库绘图时,注意下标的匹配)
2、其中有些地方代码已经注释的很清楚了。
3、若进行降噪即最后重构(restore)即可,若进行降维,那么经过转换后(transform)的即是新的维度下的结果。
4、代码引用了部分搜索到的,不过有些确实找不到了而没有引用!
1、sklearn库方式
# -*- coding: utf-8 -*-
"""
Created on Tue Jan 8 10:39:09 2019
@author: QSY
"""
import matplotlib.pyplot as plt
import scipy.io as sci
from sklearn.decomposition import PCA
import numpy as np
"""Read data from *.mat including two kinds"""
data_tarin = sci.loadmat('data_train.mat')
# data_test = sci.loadmat('data_test.mat')
data_train_noisy = data_tarin['noiseSignal']
data_train_theory = data_tarin['clearSignal']
#选取数据进行操作
X=data_train_noisy[0:1,:]
#进行行列转换
X=list(map(list, zip(*X)))
#创建横坐标
p=[]
for i in range(434):
j=i
p.append(j)
def ReadReductionofcomponents(X):
pca=PCA(n_components=1)
pca.fit(X)
#进行操作转换后的结果
x_reduction =pca.transform(X)
#进行复原恢复后的结果
x_restore=pca.inverse_transform(x_reduction)
x_restore=x_restore[:,0:1]
#X仅选择某一列的数据进行操作
X=np.array(X)
X=X[:,0:1]
#进行线绘制
plt.plot(p, x_restore, color='r', linewidth=0.3, alpha=0.6,label="PCA")
plt.plot(p, X, color='b', linewidth=0.2, alpha=0.6,label="init")
plt.legend()#显示图例名字
#pdf保存
plt.savefig('1.png')
plt.show()
ReadReductionofcomponents(X)
2、数学方式
# -*- coding: utf-8 -*-
"""
Created on Tue Jan 8 16:24:57 2019
@author: QSY
"""
import numpy as np
import scipy.io as sci
import matplotlib.pyplot as plt
"""Read data from *.mat including two kinds"""
data_tarin = sci.loadmat('data_train.mat')
other_data=sci.loadmat('pca.mat')
# data_test = sci.loadmat('data_test.mat')
data_train_noisy = data_tarin['noiseSignal']
data_train_theory = data_tarin['clearSignal']
perfect_data=other_data['U']
#选取数据进行操作
X=data_train_noisy[0:3,:]
X=list(map(list, zip(*X)))
X=perfect_data
#零均值化
def zeroMean(dataMat):
#按列求均值,即求各个特征的均值
meanVal=np.mean(dataMat,axis=0)
newData=dataMat-meanVal
return newData,meanVal
def pca(dataMat,n):
newData,meanVal=zeroMean(dataMat)
covMat=np.cov(newData,rowvar=0) #求协方差矩阵
eigVals,eigVects=np.linalg.eig(np.mat(covMat))#求特征值和特征向量,特征向量是按列放的,即一列代表一个特征向量
eigValIndice=np.argsort(eigVals) #对特征值从小到大排序
n_eigValIndice=eigValIndice[-1:-(n+1):-1] #最大的n个特征值的下标
n_eigVect=eigVects[:,n_eigValIndice] #最大的n个特征值对应的特征向量
lowDDataMat=newData*n_eigVect #低维特征空间的数据
reconMat=(lowDDataMat*n_eigVect.T)+meanVal #重构数据
return lowDDataMat,reconMat
#newData,meanVal=zeroMean(X)
lowDDataMat,reconMat=pca(X,n=1)
p=[]
for i in range(24):
j=i#np.log10(i)
p.append(j)
plt.plot(p, lowDDataMat, color='r', linewidth=0.2, alpha=0.6,label="after PCA")
#plt.plot(p, X, color='b', linewidth=0.2, alpha=0.6,label="init")
plt.legend()#显示图例名字
#pdf保存
plt.savefig('1.pdf')
plt.show()
引用
https://www.cnblogs.com/sweetyu/p/5085798.html
https://www.cnblogs.com/pinard/p/6243025.html