1 为什么要做PCA降维
1.1.维度灾难
维度灾难,简单来说就是变量的个数多。如果变量个数增加,随之需要估计的参数个数也在增加,在训练集保持不变的情况下待估参数的方差也会随之增加,导致参数估计质量下降。
1.2 变量之间存在相关关系
变量彼此之间常常存在一定程度的、有时甚至是相当高的相关性,这说明数据是有冗余的,或者说观测数据中的信息是有重叠的,这是我们利用主成分进行降维的前提条件
降维之后相当于对某个方向做投影,选择投射下来点分散的那些方向(也就是方差相对比较大的)表明了原来的数据的损失比较小,对称矩阵都可以U对角化
#生成数据
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
from sklearn.decomposition import PCA
import seaborn as sns
sns.set()
rng=np.random.RandomState(1)
#rand 0-1的随机数,randn:服从正态分布的的随机值
x=np.dot(rng.rand(2,2),rng.randn(2,200)).T
plt.scatter(x[:,0],x[:,1])
plt.axis('equal')
画出特征向量的方向
def draw_vector(v0,v1,ax=None):
ax=ax or plt.gca()
arrowprops=dict(arrowstyle='->',
linewidth=2,
shrinkA=0,shrinkB=0)
ax.annotate('',v1,v0,arrowprops=arrowprops)
plt.scatter(x[:,0],x[:,1],alpha=0.3)
for length,vector in zip(pca.explained_variance_,pca.components_):
v=vector*3*np.sqrt(length)
draw_vector(pca.mean_,pca.mean_+v)
plt.axis('equal')
pca的实现步骤:
1:0均值化
2:计算协方差阵,并求其特征值和特征向量
3:保留最大的N个特征值
4 构造相应的特征向量,形成新的特征空间
5 将数据转换到新特征空间
def zeromean(data):
#行代表样本,列代表特征
mean_value=np.mean(data,axis=0)
new_data=data-mean_value
return new_data,mean_value
def pca(data,n):
newdata,meanval=zeromean(data)
cov=np.cov(newdata,rowvar=0)
eigvalindice=np.argsort(eigval)
n_eigvalindice=eigvalindice[-1:-(n+1):-1]
n_eigvec=eigvec[:,n_eigvalindice]
#形成低维数据
new_datamat=newdata*n_eigvec
#重构数据
recover_data=(new_datamat*n_eigvec.T)+meanval
return new_datamat,recover_data
from sklearn.datasets import load_iris
iris=load_iris()
iris_data,iris_target=iris.data,iris.target
new_data,recon=pca(iris_data,2)
#pca对图片进行数据去噪声的一个实例
#人脸压缩和重构的实例
from sklearn.datasets import fetch_olivetti_faces
oliv=fetch_olivetti_faces()
fig=plt.figure(figsize=(6,6))
#定义每个子图的空间的差异
fig.subplots_adjust(left=0,right=1,bottom=0,top=1,hspace=0.05,wspace=0.05)
for i in range(64):
ax=fig.add_subplot(8,8,i+1,xticks=[],yticks=[])
X,y=oliv.data,oliv.target
pca_oliv=PCA(64)
X_proj=pca_oliv.fit_transform(X)
fig=plt.figure(figsize=(8,8))
fig.subplots_adjust(left=0,right=1,bottom=0,top=1,hspace=0.05,wspace=0.05)
for i in range(10):
ax=fig.add_subplot(5,5,i+1,xticks=[],yticks=[])
降维之后的结果
pca重构
x_inv_proj=pca_oliv.inverse_transform(X_proj)
x_proj_img=np.reshape(x_inv_proj,(400,64,64))
fig=plt.figure(figsize=(6,6))
fig.subplots_adjust(left=0,right=1,bottom=0,top=1,hspace=0.05,wspace=0.05)
for i in range(64):
ax=fig.add_subplot(8,8,i+1,xticks=[],yticks=[])
领取专属 10元无门槛券
私享最新 技术干货