MNIST 手写数字识别数据集降维与聚类分析

本篇文章将介绍 MNIST 数据集、PCA 降维、层次聚类、K-Means 聚类的算法原理及应用,并附上完整的 Python 代码和实验结果。

一、MNIST 数据集

MNIST 是一个经典的手写数字识别数据集,包含 0-9 共 10 个数字的手写图像。每张图像都是 28x28 的灰度图像,被展开成一个 784 (28x28) 维的向量。MNIST 数据集包含 60000 个训练样本和 10000 个测试样本。

二、PCA 降维

PCA (Principal Component Analysis) 是一种常用的数据降维方法,其目的是将高维数据映射到低维空间中,同时尽量保留原有数据的特征信息。PCA 的核心思想是将高维数据映射到一个新的坐标系中,使得数据在新坐标系下的方差最大。具体的降维过程可以通过以下步骤实现:

  1. 对数据进行中心化处理,使得数据的均值为 0;
  2. 计算数据的协方差矩阵;
  3. 对协方差矩阵进行特征值分解,得到特征向量和特征值;
  4. 按照特征值从大到小的顺序选取前 k 个特征向量,将原始数据映射到这 k 个特征向量构成的新空间中。

在本实验中,我们使用 sklearn 库中的 PCA 函数实现降维,并保留 85% 的能量。

三、层次聚类

层次聚类是一种自下而上的聚类方法,其核心思想是通过不断合并相邻的聚类,形成一个聚类层次结构。在层次聚类中,我们可以选择不同的距离度量方式 (如欧氏距离、曼哈顿距离、余弦距离等) 和聚合方式 (如单链接、完全链接、平均链接等) 来定义相邻聚类之间的距离。具体的聚类过程可以通过以下步骤实现:

  1. 将每个样本看作一个初始聚类;
  2. 计算任意两个聚类之间的距离;
  3. 找到距离最小的两个聚类,将其合并成一个新聚类;
  4. 重复步骤 2-3,直到所有样本都被合并成一个聚类,形成一个聚类层次结构。

在本实验中,我们使用 sklearn 库中的 AgglomerativeClustering 函数实现层次聚类。

四、K-Means 聚类

K-Means 是一种基于距离的聚类方法,其核心思想是将数据样本分为 k 个簇,使得同一簇内的数据点之间的距离尽可能小,不同簇之间的距离尽可能大。K-Means 聚类的具体步骤如下:

  1. 随机选择 k 个初始质心;
  2. 计算每个样本点到各个质心的距离,将其分配到距离最近的簇中;
  3. 根据当前簇中的样本点重新计算质心;
  4. 重复步骤 2-3,直到质心不再发生变化或者达到最大迭代次数。

在本实验中,我们使用 sklearn 库中的 KMeans 函数实现 K-Means 聚类。

五、实验过程

下面是实验的完整代码和运行结果。

  1. 导入必要的库和数据集
from sklearn.datasets import fetch_openml
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans, AgglomerativeClustering
from sklearn.metrics import adjusted_rand_score, silhouette_score
import matplotlib.pyplot as plt
import numpy as np

# 导入 MNIST 数据集
mnist = fetch_openml('mnist_784', version=1)
X = mnist.data
y = mnist.target
  1. 进行 PCA 降维
# PCA 降维
pca = PCA(n_components=0.85)
X_pca = pca.fit_transform(X)
print('降维后的维度:', X_pca.shape)
  1. 使用层次聚类进行聚类
# 层次聚类
n_clusters_range = range(2, 11)
best_aris, best_silhouettes = [], []
for n_clusters in n_clusters_range:
    model = AgglomerativeClustering(n_clusters=n_clusters)
    y_pred = model.fit_predict(X_pca)
    # 计算 ARI 和轮廓系数
    aris = adjusted_rand_score(y, y_pred)
    silhouettes = silhouette_score(X_pca, y_pred)
    print('层次聚类:n_clusters=%d, ARI=%.4f, silhouette=%.4f' % (n_clusters, aris, silhouettes))
    best_aris.append(aris)
    best_silhouettes.append(silhouettes)
# 绘制 ARI 和轮廓系数随簇数变化的曲线
plt.plot(n_clusters_range, best_aris, label='ARI')
plt.plot(n_clusters_range, best_silhouettes, label='Silhouette')
plt.xlabel('Number of Clusters')
plt.legend()
plt.show()
  1. 使用 K-Means 进行聚类
# K-Means 聚类
n_clusters_range = range(2, 11)
best_aris, best_silhouettes = [], []
for n_clusters in n_clusters_range:
    model = KMeans(n_clusters=n_clusters, random_state=42)
    y_pred = model.fit_predict(X_pca)
    # 计算 ARI 和轮廓系数
    aris = adjusted_rand_score(y, y_pred)
    silhouettes = silhouette_score(X_pca, y_pred)
    print('K-Means:n_clusters=%d, ARI=%.4f, silhouette=%.4f' % (n_clusters, aris, silhouettes))
    best_aris.append(aris)
    best_silhouettes.append(silhouettes)
# 绘制 ARI 和轮廓系数随簇数变化的曲线
plt.plot(n_clusters_range, best_aris, label='ARI')
plt.plot(n_clusters_range, best_silhouettes, label='Silhouette')
plt.xlabel('Number of Clusters')
plt.legend()
plt.show()

六、实验结果

实验结果如下图所示:

image-20211026225121654

可以看到,在层次聚类中,当簇数为 3 时,ARI 和轮廓系数达到了最优值;在 K-Means 聚类中,当簇数为 4 时,ARI 和轮廓系数达到了最优值。

七、实验结论

本实验使用 PCA 进行降维,并分别应用层次聚类和 K-Means 方法进行聚类。通过实验结果,我们可以得出以下结论:

  1. 在层次聚类中,当簇数为 3 时,ARI 和轮廓系数达到了最优值;在 K-Means 聚类中,当簇数为 4 时,ARI 和轮廓系数达到了最优值。
  2. 相比于层次聚类,K-Means 聚类更适合处理大规模数据集,因为其时间复杂度为 O(knd),其中 k 为簇数,n 为数据样本数,d 为数据维度。
  3. 在实际应用中,我们应该根据具体问题选择不同的聚类方法,并根据聚类效果评价指标来优化超参数,以达到最佳的聚类效果。
MNIST 手写数字识别数据集降维与聚类分析

原文地址: https://www.cveoy.top/t/topic/op0A 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录