Neuromatch Academy教程:使用PCA进行MNIST数据降维与重建
2025-07-10 07:13:55作者:江焘钦
引言
本教程将介绍如何使用主成分分析(PCA)对经典的MNIST手写数字数据集进行降维处理。MNIST数据集包含70,000张28×28像素的灰度手写数字图像,是机器学习领域的基准数据集之一。
教程目标
通过本教程,您将学习:
- 在MNIST数据集上应用PCA进行降维
- 计算并分析解释方差
- 使用不同数量的主成分重建数据
- (选学)使用PCA进行图像去噪
准备工作
首先导入必要的Python库:
import numpy as np
import matplotlib.pyplot as plt
MNIST数据集简介
MNIST数据集中的每张图像都被展平为一个784维的向量(28×28像素),整个数据集可以表示为70,000×784的矩阵:
- 每行代表一张不同的图像
- 每列代表一个不同的像素值
让我们先加载并可视化数据集中的前9张图像:
# 加载MNIST数据集
# 可视化前9张图像
def plot_MNIST_sample(X):
fig, ax = plt.subplots()
k = 0
for k1 in range(3):
for k2 in range(3):
k = k + 1
plt.imshow(np.reshape(X[k, :], (28, 28),
extent=[(k1 + 1) * 28, k1 * 28, (k2+1) * 28, k2 * 28],
vmin=0, vmax=255)
plt.xlim((3 * 28, 0))
plt.ylim((3 * 28, 0))
plt.tick_params(axis='both', which='both', bottom=False, top=False,
labelbottom=False)
plt.clim([0, 250])
ax.set_xticks([])
ax.set_yticks([])
plt.show()
PCA实现步骤
1. 数据预处理
在执行PCA前,我们需要对数据进行中心化处理:
def pca(X):
# 中心化数据
X = X - np.mean(X, 0)
# 计算协方差矩阵
cov_matrix = get_sample_cov_matrix(X)
# 计算特征值和特征向量
evals, evectors = np.linalg.eigh(cov_matrix)
# 按特征值降序排序
evals, evectors = sort_evals_descending(evals, evectors)
# 将数据投影到新基上
score = change_of_basis(X, evectors)
return score, evectors, evals
2. 计算协方差矩阵
协方差矩阵的计算公式为:
def get_sample_cov_matrix(X):
X = X - np.mean(X, 0)
cov_matrix = 1 / X.shape[0] * np.matmul(X.T, X)
return cov_matrix
3. 特征值分解与排序
对协方差矩阵进行特征值分解后,我们需要按特征值大小降序排列:
def sort_evals_descending(evals, evectors):
index = np.flip(np.argsort(evals))
evals = evals[index]
evectors = evectors[:, index]
return evals, evectors
解释方差分析
执行PCA后,我们可以计算每个主成分解释的方差比例:
def plot_variance_explained(variance_explained):
plt.figure()
plt.plot(np.arange(1, len(variance_explained) + 1), variance_explained, '--k')
plt.xlabel('Number of components')
plt.ylabel('Variance explained')
plt.show()
通常我们会观察到前几个主成分解释了大部分方差,而后面的主成分贡献较小。
数据重建
使用PCA进行数据重建的步骤如下:
- 选择保留的主成分数量K
- 使用前K个特征向量构建投影矩阵
- 将数据投影到低维空间
- 从低维表示重建原始数据
def plot_MNIST_reconstruction(X, X_reconstructed, keep_dims):
# 绘制原始图像和重建图像对比
plt.figure()
ax = plt.subplot(121)
# 绘制原始图像
# ...
ax = plt.subplot(122)
# 绘制重建图像
# ...
plt.title(f'Reconstructed K: {keep_dims}')
plt.tight_layout()
plt.show()
PCA去噪应用(选学)
PCA也可以用于图像去噪。基本思路是:
- 对含噪图像执行PCA
- 保留主要成分,舍弃噪声主导的成分
- 重建图像
def add_noise(X, frac_noisy_pixels):
# 添加随机噪声
X_noisy = np.reshape(X, (X.shape[0] * X.shape[1]))
N_noise_ixs = int(X_noisy.shape[0] * frac_noisy_pixels)
noise_ixs = np.random.choice(X_noisy.shape[0], size=N_noise_ixs, replace=False)
X_noisy[noise_ixs] = np.random.uniform(0, 255, noise_ixs.shape)
return np.reshape(X_noisy, (X.shape[0], X.shape[1]))
结论
本教程介绍了PCA在MNIST数据集上的应用,包括:
- 数据降维与可视化
- 解释方差分析
- 数据重建
- 图像去噪
PCA是一种强大的无监督学习技术,能够有效降低数据维度,同时保留数据的主要特征。在实际应用中,选择合适的主成分数量是关键,需要在降维效果和信息保留之间取得平衡。