第09周:吴恩达机器学习课后编程题ex7下PCA——Python

2 主成分分析

 

2.1 Example Dataset

先从一个二维数据集开始,将其压缩为一维。

PCA就是一种降维算法,将n维的特征映射到k维上,这k维是全新的正交特征也被称为主成分,是在原有n维特征的基础上重新构造出来的k维特征。

步骤:①数据预处理(均值归一化/特征缩放);②计算协方差矩阵;③取U矩阵(特征向量矩阵)种前k个向量得到一个n*k维的矩阵U_{reduce},用他的转置乘以数据x就可以得到降维后的数据z = U_{reduce}^Tx

先导入数据并且可视化数据:

import numpy as np
import matplotlib.pyplot as plt
import scipy.io as sio

data = sio.loadmat('ex7data1.mat')
print(data.keys())

X = data['X']
print(X.shape)  # (50, 2)
# 可视化
plt.scatter(X[:,0],X[:,1])
plt.show()

 2.2 Implementing PCA用PCA开始压缩

数据归一化:

# 对数据x归一化
def meanx(X):
    mean = X.mean(axis=0) # 求每列的均值
    sigma = X.std(axis=0, ddof=1) # 求方差
    X = (X-mean)/sigma
    return X, mean, sigma

Mean_x,mean,sigma = meanx(X)

plt.scatter(Mean_x[:,0],Mean_x[:,1])
plt.show()

 计算协方差和特征向量:

\Sigma =\frac{1}{m}\sum_{i=1}^{m}(x^{(i)})(x^{(i)})^T

# 计算协方差和特征向量U
def pca(X):
    m = len(X)
    Sigma = (X.T @ X)/m
    U,S,V = np.linalg.svd(Sigma) # SVD奇异值分解计算特征向量U
    return U,S

U, S = pca(Mean_x)

# 画出最后的特征向量
plt.figure(figsize=(6,6))
plt.scatter(X[:,0],X[:,1],marker='o',facecolors = 'orange', edgecolors='blue')
plt.plot([mean[0],mean[0]+1.5*S[0]*U[0,0]],[mean[1],mean[1]+1.5*S[0]*U[1,0]],'k')# 两个点之间的连线
plt.plot([mean[0],mean[0]+1.5*S[1]*U[0,1]],[mean[1],mean[1]+1.5*S[1]*U[1,1]],'k')# 1.5和S表示特征向量的长度
plt.title('Computed eigenbectors of the dataset')
plt.show()

 2.3 用PCA实现降维

将归一化后的数据投影到特征向量上

# 降维,将归一化候得数据投影到特征向量上
def X_reduction(x, U, K):
    U_reduce = U[:, 0:K] # 选择特征向量矩阵的前K列
    return X@U_reduce
# 降维后的数据
z = X_reduction(Mean_x, U, 1) # 让K=1
print(z.shape) # (50, 1)

此时降维后的数据变成了一维

PCA可以降维,也可以恢复数据维度

#重现数据
def restoreData(z, U, K):
    U_reduce = U[:, 0:K]
    return z@U_reduce.T

#重建后的数据如下
Restore_x = restoreData(z, U, 1)

可视化归一化后的数据和重现数据:

#可视化投影,并且画出归一化数据和降维后又重现的数据对应点用虚线链接
plt.scatter(Mean_x[:,0],Mean_x[:,1], marker = 'o',facecolors = 'orange',edgecolors='blue')
plt.scatter(Restore_x[:,0],Restore_x[:,1],marker='o',facecolor='blue',edgecolors='red')
for i in range(len(X)):
    plt.plot([Mean_x[i,0],Restore_x[i,0]],[Mean_x[i,1],Restore_x[i,1]],'k--')
plt.title('The normalized and projuected data after PCA')
plt.show()

 计算一下降维后的数据保留了原始数据多少差异性:86.78%

#计算保留差异性
def retained_variance(S, K):
    rv = np.sum(S[:K])/np.sum(S)
    return print('{:.2f}%'.format(rv*100))

retained_variance(S, 1) # 86.78%

2.4 用PCA进行图像降维压缩

先导入图像然后可视化其中100张图,此时的图片很清晰。

# 导入图像数据
facedata = sio.loadmat('ex7faces.mat')
print(facedata.keys())
A = facedata['X']
print(A.shape)  # (5000, 1024)

# 打印100个图像
def plot_100_images(A):
    fig,axs = plt.subplots(ncols=10,nrows=10,figsize = (10,10)) # 定义n*n的画布
    for c in range(10):
        for r in range(10):
            axs[c,r].imshow(A[10*c+r].reshape(32,32).T,cmap = 'Greys_r') #显示单通道的灰图
            axs[c,r].set_xticks([])
            axs[c,r].set_yticks([])
    plt.show()

plot_100_images(A)

 对图片集开始降为还是调用之前的方法,降维后的图片变得模糊。

# 对A降维
A_reduction = meanA@U1
print(A_reduction.shape) # (5000, 36)

A_recover = A_reduction @ U1.T + np.mean(A, axis=0)

plot_100_images(A_recover),plot_100_images(A)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值