PCA主要应用于降维度、可视化,以此来加快学习算法的运行速度。
PCA实现
首先,你将用一个二维的样本集来实验,从而对PCA如何运行的有一个直观的感受,然后再在一个更大的由5000个人脸图像组成的数据集上实现PCA。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.io import loadmat
mat=loadmat('ex7data1.mat')
X=mat['X']
x=pd.DataFrame(mat['X'],columns=['x1','x2'])
fig,ax=plt.subplots(figsize=(12,8))
ax.scatter(x['x1'],x['x2'])
ax.set_xlabel('x1')
ax.set_ylabel('x2')
plt.show()
正式开始进行PCA,首先需要对数据集进行归一化和特征缩放。
X_norm=(x-x.mean(axis=0))/x.std(axis=0)
然后计算协方差矩阵,用奇异值分解得出U,U是一个具有与数据之间最小投射误差的方向向量构成的矩阵,将数据从n维降至k维,选取U[:,:k],最后计算新的特征向量z=X_norm*U,这里需要注意的是x应该是归一化之后的x,不然结果会出错!!!
def pca(x):
x=np.matrix(x)
sigma=(x.T*x)/len(x)
U,S,V=np.linalg.svd(sigma)
return U,S,V
def project_data(x,k,u):
u_reduce=u[:,:k]
return x*u_reduce
z=project_data(X_norm,U,1)
重建压缩数据
x=u_reduce*z
def recover_data(u,z,k):
u_reduce=u[:,:k]
return z*u_reduce.T
x_recover=recover_data(U,z,1)
画图观察数据映射结果
x_recover=np.array(x_recover)
plt.figure(figsize=(20,12))
plt.scatter(X_norm[:,0], X_norm[:,1], marker='o', facecolors='none', edgecolors='b')
plt.scatter(x_recover[:,0], x_recover[:,1], marker='o', facecolors='none', edgecolors='r')
for i in range(len(X_norm)):
plt.plot([X_norm[i,0], x_recover[i,0]], [X_norm[i,1], x_recover[i,1]], 'k--')
plt.title('The normalized and projected data after PCA')
人脸数据集
face_mat=loadmat('ex7faces.mat')
X=face_mat['X'] #(5000,1024)
显示100张图像
def plot_100_image(x):
idx=np.random.choice(5000,100)
fig,ax=plt.subplots(ncols=10,nrows=10,figsize=(8,8))
images=x[idx] #(100,1024)
for i in range(10):
for j in range(10):
ax[i][j].imshow(images[i*10+j].reshape(32,32).T,cmap='gray_r')
ax[i][j].set_xticks([])
ax[i][j].set_yticks([])
#降低维度-1024-36
#首先归一化
means = X.mean(axis=0)
stds = X.std(axis=0)
X_norm = (X - means) / stds
X_norm
U,S,V=pca(X_norm)
z=project_data(X_norm,U,36)
x_recover=recover_data(z,U,36)
plot_100_image(x_recover)