基于KPCA的手写数字降维与分类识别
1.作者介绍
李至屹,男,西安工程大学电子信息学院,2025级研究生
研究方向:FPGA嵌入式系统设计
电子邮件:2274511087@qq.com
郭政,男,西安工程大学电子信息学院,2025级研究生,张宏伟人工智能课题组
研究方向:机器视觉与人工智能
电子邮件:1225301905@qq.com
2.算法介绍
2.1 KPCA算法介绍
KPCA(Kernel Principal Component Analysis,核主成分分析),是一种非线性降维方法,通过核函数将原始数据映射到高维特征空间,实现非线性主成分提取。
它也是PCA的非线性扩展,核心是用核技巧把数据隐式映射到高维空间,再在该空间做线性PCA,从而处理PCA无法解决的非线性降维问题。
以本实验为例,KPCA可用于手写数字数据降维,保留主要特征,降低噪声影响,降维之后结合分类器(本项目使用SVM)实现数字分类识别。
2.2 KPCA算法原理分析
原理图(从784个像素点到二维降维空间):
说明:本实验使用MNIST手写数字数据集,MNIST图像大小为28×28,每张图像由784个像素点组成。每个像素点可以看作原始空间中的一个维度,因此每张图像可以看作是一个784维的向量,不是784个样本。我们将所有样本在784维空间中进行KPCA非线性映射,并降维到二维空间进行可视化演示。
关键点:
1.原始空间维度是 784 维(每个像素点一个维度)。
2.每张图像是一个 784 维向量,不是 784 个样本。
3.KPCA 通过核映射捕捉非线性结构,将数据映射到高维特征空间,再进行线性降维。
4.最终在2维空间中可视化展示。
该原理图中通过非线性核函数映射后,数据被压缩到二维空间,不同数字类别开始分离,这样就便于可视化和分类。
核函数示意图(RBF核将数据映射到高维):
该图中显示二维数据经过RBF核映射到曲面高维空间,数据点可以通过线性超平面分开,使线性不可分的问题在高维空间中变得线性可分。
KPCA的工作流程主要包括数据准备,核矩阵构建,中心化,特征值分解,选择主成分,投影降维,模型训练和预测评估,下面是其工作流程图:
3.数据集介绍与实验环境
3.1 数据集介绍
前面提到,本实验使用MNIST手写数字数据集,该数据集是计算机视觉领域中最经典、最常用的基准数据集之一,由美国国家标准与技术研究院(NIST)改进整理而成。该数据集由60000个训练样本和10000个测试样本组成,每个样本为28×28像素的灰度图像,像素取值范围为 0~255。
数据集特点:
共包含 10 个数字类别(0-9)。
图像为灰度图像,单通道,无彩色信息。
数字书写风格多样,包含不同书写人、不同笔画粗细和倾斜程度。
数据集用途:
广泛用于数字识别、降维、分类等机器学习与深度学习任务。
适合作为降维方法(如 KPCA)效果评估与方法对比的基准数据集。
对应数据集下载地址:https://www.openml.org/d/554?utm_source=chatgpt.com,下面是该数据集的部分样本展示:
注:每行代表一个数字类别(0-9),展示该类别的部分样本示例
3.2 实验环境
本实验采用的软件环境:
Windows 11操作系统
Python 3.10
VSCode 开发环境
Anaconda 虚拟环境管理
本实验需要安装的依赖库:
PyTorch(模型训练)
NumPy(数值计算)
Matplotlib(数据可视化)
Scikit-learn(机器学习)
Pandas(数据处理)
其中,NumPy用于矩阵与数值运算,Matplotlib用于数据可视化,Scikit-learn主要用于KPCA与SVM实现,Pandas用于数据读取与处理。
4.代码实现
本实验完整代码及流程注释如下所示:
# 1. 导入相关库
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import KernelPCA
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
from sklearn.metrics import confusion_matrix
from sklearn.metrics import ConfusionMatrixDisplay
# 2. 加载MNIST数据集
mnist = fetch_openml(
'mnist_784',
version=1,
parser='auto'
)
# 3. 只取部分数据(优化)
# 只取前5000个样本
X = mnist.data[:5000]
y = mnist.target[:5000].astype(int)
print("数据加载完成")
print("数据维度:", X.shape)
print("标签维度:", y.shape)
# 4. 数据归一化
# 像素归一化
X = X / 255.0
# 标准化
scaler = StandardScaler()
X = scaler.fit_transform(X)
print("归一化完成")
# 5. 展示部分手写数字样本
fig, axes = plt.subplots(2, 5, figsize=(10, 5))
for i, ax in enumerate(axes.flat):
image = X[i].reshape(28, 28)
ax.imshow(image, cmap='gray')
ax.set_title(f"Label: {y[i]}")
ax.axis('off')
plt.suptitle("MNIST Handwritten Digits")
plt.tight_layout()
plt.show()
# 6. 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42
)
print("训练集大小:", X_train.shape)
print("测试集大小:", X_test.shape)
# 7. KPCA降维
kpca = KernelPCA(
n_components=50, # 主成分数量
kernel='rbf', # RBF核
gamma=0.003, # 核参数
eigen_solver='randomized' # 随机SVD
)
# 训练集降维
X_train_kpca = kpca.fit_transform(X_train)
# 测试集降维
X_test_kpca = kpca.transform(X_test)
print("KPCA降维完成")
print("降维后训练集维度:", X_train_kpca.shape)
# 8. KPCA结果可视化
plt.figure(figsize=(10, 8))
scatter = plt.scatter(
X_train_kpca[:, 0],
X_train_kpca[:, 1],
c=y_train,
cmap='tab10',
s=10
)
plt.colorbar(scatter)
plt.title("KPCA Dimensionality Reduction Visualization")
plt.xlabel("Principal Component 1")
plt.ylabel("Principal Component 2")
plt.grid(True)
plt.show()
# 9. SVM分类器训练
svm = SVC(
kernel='rbf',
C=5
)
svm.fit(X_train_kpca, y_train)
print("SVM训练完成")
# 10. 模型预测
y_pred = svm.predict(X_test_kpca)
# 11. 分类准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"分类准确率: {accuracy * 100:.2f}%")
# 12. 混淆矩阵
print("\n绘制混淆矩阵...")
cm = confusion_matrix(y_test, y_pred)
disp = ConfusionMatrixDisplay(
confusion_matrix=cm
)
fig, ax = plt.subplots(figsize=(10, 10))
disp.plot(ax=ax)
plt.title("MNIST Classification Confusion Matrix")
plt.show()
# 13. 程序结束
print("程序运行结束")
运行结果:
1.在终端会输出最终的分类准确率,用于衡量算法的分类识别性能。对应代码及运行结果如下图所示:
2.生成手写数字样本图,用于展示MNIST数据集数字图片。
3.生成KPCA降维可视化图,该图片为二维散点图,用于展示不同数字类别在二维空间中的分布。
4.最后绘制混淆矩阵,并生成混淆矩阵图,用于展示各数字分类识别情况。
