首页
/ Neuromatch Academy教程:使用PCA进行MNIST数据降维与重建

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进行数据重建的步骤如下:

  1. 选择保留的主成分数量K
  2. 使用前K个特征向量构建投影矩阵
  3. 将数据投影到低维空间
  4. 从低维表示重建原始数据
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也可以用于图像去噪。基本思路是:

  1. 对含噪图像执行PCA
  2. 保留主要成分,舍弃噪声主导的成分
  3. 重建图像
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是一种强大的无监督学习技术,能够有效降低数据维度,同时保留数据的主要特征。在实际应用中,选择合适的主成分数量是关键,需要在降维效果和信息保留之间取得平衡。