机器学习实验报告:PCA降维实战
机器学习实验报告:PCA降维实战
PCA(主成分分析)是一种常用的降维技术,在处理高维数据时能够有效减少数据维度,同时保留数据的主要特征。本文通过一个完整的实验报告,详细介绍了如何使用PCA对MNIST手写数字数据集进行降维处理,并通过随机森林和KNN分类器评估降维效果。
实验要求
实验名称:PCA降维
实验目的:
- 学习数据预处理和特征工程方法。
- 掌握PCA降维算法的基本原理和实现。
- 理解PCA的降维过程及其在高维数据中的应用。
- 使用不同的评价指标对降维效果进行评估。
- 通过数据可视化展示PCA的效果。
实验步骤与要求:
- 数据集预处理与特征工程
- 数据集导入:选择一个适合降维任务的数据集(如Iris数据集、手写数字识别数据集等)。
- 数据预处理:处理缺失值、去除异常值等,确保数据质量。
- 特征工程:对数据进行特征选择、特征缩放等操作,确保各特征具有相同的尺度。
- PCA算法实现
- 算法原理:简要说明PCA算法的原理,包括协方差矩阵的计算、特征值和特征向量的分解、以及主成分的选取过程。
- 实现过程:使用编程语言(如Python)实现PCA算法,可以使用现有库如scikit-learn。
- 降维过程:将数据投影到前几个主成分上,减少数据的维度。
- 降维效果分析
- 结果展示:展示PCA降维后的数据分布情况,可以使用散点图等方法进行可视化。
- 评价指标:使用累积方差贡献率等指标评估PCA的降维效果。
- 主成分分析:分析各个主成分对原始特征的贡献程度。
- 数据可视化
- 特征分布可视化:使用散点图、直方图等方法展示原始数据和降维后的数据分布情况。
- 降维效果展示:通过可视化展示PCA降维后的数据点分布,直观比较降维前后的差异。
- 主成分可视化:在二维或三维空间中可视化前几个主成分,展示数据在主成分空间中的分布。
- 实验总结
- 结果分析:总结实验结果,分析PCA算法的优缺点以及适用场景。
- 模型改进:探讨可能的改进方法,如结合其他降维方法或者使用非线性PCA等。
这份实验报告要求涵盖了PCA降维的基本步骤和分析方法。你可以根据具体的实验数据和任务进行适当的调整和补充。
实验目的(举例)
(1)图像处理与人脸识别:
在图像处理中,特别是人脸识别领域,PCA被广泛用于降低图像数据的维度。通过PCA,可以提取最具代表性的特征,例如人脸的轮廓和关键特征点,从而减少数据处理和存储的复杂性,加快识别速度。
(2)金融领域中的投资组合优化:
在金融领域,投资组合优化涉及大量资产和变量。PCA可以帮助分析市场变动中的主要模式,并提取关键的市场风险因素。通过降维,可以减少投资组合优化模型的复杂性和过拟合风险。
(3)基因组学:
在基因组学研究中,基因数据往往包含大量的特征,如基因表达数据。PCA可以帮助识别哪些基因在数据中具有显著的变异模式,从而帮助研究人员理解基因之间的关系和影响。
(4)自然语言处理:
在文本数据分析中,比如情感分析或主题建模,PCA可以用于降低文本特征的维度,提取最具信息量的语义特征。这有助于提高文本分类和聚类的精度。
(5)工业生产过程的质量控制:
在生产领域,如制造业,PCA可以用来监测生产过程中的各种变量和参数。通过降维,可以发现对产品质量影响最大的因素,从而及时调整生产过程,提高产品质量和稳定性。
实验步骤
导入必要的库和数据集
导入所需的Python库,包括用于数据处理和机器学习模型的库。然后,从OpenML获取手写数字识别数据集MNIST。数据集包括x(特征)和y(标签),并打印出特征数据的形状。画累计方差贡献率曲线,确定最佳的降维后特征数目范围
利用PCA(主成分分析)拟合数据集,计算每个主成分解释的方差比例。通过绘制累计方差贡献率曲线,可以观察到在多少主成分时累计方差贡献率开始趋于稳定。这帮助确定一个合适的降维后特征数目范围。初步选择特征数量为 1-100,绘制降维后的学习曲线
在初步选择中,以10为步长,从1到100选择主成分数量进行PCA降维。对每个选择的降维后特征数目,使用随机森林分类器进行交叉验证,并计算平均分数。这些分数帮助我们理解降维后特征数量对分类器性能的影响。进一步缩小特征数的范围到 10-25,找到最佳降维维度
根据初步选择的结果,进一步缩小特征数量的范围,以更细的间隔进行选择。在这里,我们选择特征数量从10到25之间进行评估,以找到在这个范围内表现最好的PCA降维维度。根据上图结果选择 22 维度进行降维
根据第4步的评估结果,选择了一个表现较好的PCA降维后特征数量,这里选择了22维。使用随机森林进行评估
使用随机森林分类器进行交叉验证评估。在这一步中,我们尝试了两种不同的随机森林模型:一个有10个决策树,另一个有100个决策树。我们计算并打印出每个模型的交叉验证平均分数,以评估其在降维后数据上的表现。使用 KNN 进行评估并尝试不同的 K 值,找到最佳 K 值
使用K近邻(KNN)分类器进行交叉验证评估。首先尝试了默认的KNN模型,然后测试了不同的K值(从1到10),以找到在降维后数据上表现最好的K值。绘制了K值与交叉验证分数的关系图,帮助我们理解K值选择对模型性能的影响。最佳 K 值为 3 时,计算模型性能和运行时间
根据第7步的评估结果,确定了在降维后数据上表现最好的K值。最后,使用该K值重新评估KNN模型,并计算模型的交叉验证平均分数以及模型运行的时间。这些结果提供了模型在不同K值下的性能比较,并展示了KNN模型的运行效率。
实验结果分析
- 结果展示
(2)PCA效果分析:
从累计方差贡献率曲线可以看出,前面几个主成分可以解释大部分的数据方差,随后的主成分贡献率逐渐变小。通过交叉验证,选择了降维到22维,这保留了足够的信息量同时减少了特征维度。
随机森林和KNN模型表现:
在降维后的数据上,随机森林和KNN都展现出不错的性能。随机森林的交叉验证平均精度约为0.9435,而最佳KNN(K=3)的平均精度约为0.9697。
模型应用:
在实际应用中,PCA可以用于减少高维数据的复杂性,提高模型的训练速度和泛化能力。例如,在人脸识别系统中,PCA常用于降维处理,以提高识别速度和降低计算成本。
实验源代码
from sklearn.decomposition import PCA # 导入PCA算法
from sklearn.model_selection import cross_val_score # 导入交叉验证函数
from sklearn.ensemble import RandomForestClassifier as RFC # 导入随机森林分类器
from sklearn.neighbors import KNeighborsClassifier as KNN # 导入K近邻分类器
from sklearn.datasets import fetch_openml # 导入数据集获取函数
import numpy as np # 导入数值计算库
import pandas as pd # 导入数据处理库
import matplotlib.pyplot as plt # 导入绘图库
import time # 导入时间库
# 导入数据
mnist = fetch_openml('mnist_784', version=1, as_frame=False)
x = mnist.data # 特征数据
y = mnist.target.astype(int) # 目标数据(转换为整数类型)
print(x.shape) # 打印特征数据形状 (70000, 784)
# 画累计方差贡献率曲线,找最佳降维后维度的范围
pca = PCA().fit(x)
plt.figure(figsize=(20, 5))
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文字体以显示中文
plt.plot(np.cumsum(pca.explained_variance_ratio_)) # 绘制累计方差贡献率曲线
plt.xlabel('降维后的特征数目')
plt.ylabel('累计可解释性方差比例之和')
plt.show()
# 初步选择特征数量为 1-100,绘制降维后的学习曲线
score = []
for i in range(1, 101, 10):
x_dr = PCA(n_components=i).fit_transform(x) # PCA降维
once = cross_val_score(RFC(n_estimators=10, random_state=42), x_dr, y, cv=5).mean() # 交叉验证随机森林分类器性能
score.append(once)
plt.figure(figsize=[20, 5])
plt.plot(range(1, 101, 10), score)
plt.xlabel('特征数')
plt.ylabel('随机森林交叉验证分数')
plt.show()
# 进一步缩小特征数的范围到 10-25,找到最佳降维维度
score = []
for i in range(10, 25):
x_dr = PCA(n_components=i).fit_transform(x) # PCA降维
once = cross_val_score(RFC(n_estimators=10, random_state=42), x_dr, y, cv=5).mean() # 交叉验证随机森林分类器性能
score.append(once)
plt.figure(figsize=[20, 5])
plt.plot(range(10, 25), score)
plt.xlabel('特征数')
plt.ylabel('随机森林交叉验证分数')
plt.show()
# 根据上图结果选择 22 维度
x_dr = PCA(n_components=22).fit_transform(x) # 选取22维度进行PCA降维
# 使用随机森林进行评估
once = cross_val_score(RFC(n_estimators=10, random_state=42), x_dr, y, cv=5).mean()
print("Random Forest (10 estimators):", once)
once1 = cross_val_score(RFC(n_estimators=100, random_state=42), x_dr, y, cv=5).mean()
print("Random Forest (100 estimators):", once1)
# 使用 KNN 进行评估
score_knn = cross_val_score(KNN(), x_dr, y, cv=5).mean()
print("KNN:", score_knn)
# 尝试不同的 K 值,找到最佳 K 值
score = []
for i in range(1, 11):
once = cross_val_score(KNN(n_neighbors=i), x_dr, y, cv=5).mean() # 交叉验证K近邻分类器性能
score.append(once)
plt.figure(figsize=[20, 5])
plt.plot(range(1, 11), score)
plt.xlabel('K 值')
plt.ylabel('KNN 交叉验证分数')
plt.show()
# 最佳 K 值为 3 时,计算模型性能
start = time.time()
sc = cross_val_score(KNN(n_neighbors=3), x_dr, y, cv=5).mean() # 计算K=3时K近邻分类器能
end = time.time()
print("KNN (k=3):", sc)
print("运行时间:", end - start)