PCA主成分分析:从数学原理到Python实战的降维指南

📅 2026/8/22 6:12:45
PCA主成分分析:从数学原理到Python实战的降维指南
1. 项目概述从数据冗余到信息精华如果你处理过一堆变量多到让人眼花缭乱的数据比如几十个经济指标、上百个基因表达量或者几百个传感器读数那你肯定遇到过两个头疼的问题一是维度太高数据点稀疏得像撒在广场上的芝麻难以直观分析和可视化二是变量之间往往“勾肩搭背”存在多重共线性这会让很多后续的统计模型“消化不良”结果不稳定。主成分分析也就是我们常说的PCA就是专门用来对付这两个问题的“降维神器”。简单来说PCA干的事就是在一堆可能存在相关性的原始变量里找到几个全新的、互不相关的“综合变量”我们管它们叫主成分。这些主成分是按重要性排队的第一个主成分携带了原始数据里最多的变异信息第二个次之以此类推。通过只保留前几个最重要的主成分我们就能用少得多的变量抓住原始数据最核心的结构和特征实现降维。这就像给一本厚厚的书写摘要我们保留了最关键的故事情节但大大压缩了篇幅。在数学建模竞赛里PCA的应用场景多到数不过来。无论是国赛、美赛还是亚太杯只要题目涉及高维数据处理、特征提取、数据可视化或者去除噪声PCA几乎都是工具箱里的标配。比如在社会科学题目中分析影响城市发展的众多因素在环境科学题目中处理多源遥感数据在生物信息题目中分析基因表达谱。掌握PCA就等于掌握了一把打开高维数据大门的钥匙。2. PCA的核心思想与数学原理拆解2.1 直观理解从“拧麻花”到“摆正位置”想象一下你有一组关于学生成绩的二维数据数学成绩X轴和物理成绩Y轴。通常这两门课成绩好的学生另一门也不会太差所以数据点在坐标系里大概会呈现一个斜向上的椭圆形“云团”。这个云团的长轴方向就是数学和物理成绩共同变化的主要趋势——我们可以理解为“理科综合能力”。短轴方向则代表了某个学生数学和物理成绩的差异程度。PCA要做的第一步就是把这个斜着的椭圆“摆正”。具体操作是将坐标原点移到数据的中心即减去每个变量的均值称为“中心化”然后旋转坐标系使得新坐标轴的方向沿着数据点分布最“散”的方向。这个旋转后的新坐标系其坐标轴就是主成分。第一主成分PC1对应最长轴方差最大方向第二主成分PC2对应与PC1垂直的次长轴。这样我们就把原来用“数学分”和“物理分”描述一个学生变成了用“理科综合能力”PC1和“文理偏科程度”PC2来描述。后者通常包含的信息量方差远小于前者如果我们只关心学生的整体理科水平那么完全可以忽略PC2只用PC1这一个维度来近似表示所有学生这就实现了从2维到1维的降维。2.2 数学本质特征值分解与协方差矩阵上面“旋转”和“找方向”的直观操作在数学上对应着矩阵的特征值分解。其核心步骤如下数据标准化通常建议进行将每个原始变量减去其均值再除以其标准差。这一步至关重要它消除了不同变量量纲和数量级的影响让所有变量在计算中处于平等地位。否则数值大的变量如GDP单位是万亿会完全主导主成分的方向淹没了数值小但可能重要的变量如失业率单位是百分比。注意是否标准化取决于数据特性和分析目标。如果变量单位一致且你希望保留原始方差贡献可以只中心化而不标准化。但在绝大多数建模场景尤其是变量单位混杂时标准化是标准操作。计算协方差矩阵或相关矩阵如果我们对标准化后的数据做PCA实际上计算的是变量的相关矩阵如果只中心化计算的是协方差矩阵。这个矩阵的第(i, j)个元素表示第i个变量和第j个变量之间的协方差或相关系数。它刻画了所有变量两两之间的线性关系强度。特征值分解对协方差矩阵或相关矩阵进行特征值分解。你会得到特征向量每一个特征向量就是一个主成分的方向即我们旋转后的新坐标轴方向。向量中的每个数值代表原始变量对该主成分的“贡献权重”称为载荷。特征值每个特征值的大小等于其对应的主成分所携带的方差。特征值越大说明这个主成分方向上的数据波动越大包含的信息越多。选择主成分将特征值从大到小排序其对应的特征向量主成分也按重要性排列。通常我们根据以下准则决定保留前k个主成分累积方差贡献率最常见的方法。计算前k个主成分的方差之和占总方差所有特征值之和的比例。通常要求这个比例达到80%-95%具体阈值根据问题灵活设定。碎石图绘制特征值随主成分序号下降的折线图。图形通常在前几个成分处陡峭下降之后变得平缓。我们保留“拐点”之前的主成分。特征值大于1准则适用于相关矩阵PCA只保留特征值大于1的主成分。计算主成分得分这是降维后的新数据。将标准化后的原始数据矩阵乘以由前k个主成分方向特征向量构成的矩阵就得到了每个样本在k个新维度上的坐标即主成分得分。这个得分矩阵的行是样本列是主成分就是我们后续建模分析所用的低维数据。2.3 一个超简单的计算示例假设我们有两个中心化后的变量X1和X2有3个样本 样本1: (1, 1) 样本2: (2, 2) 样本3: (3, 3) 这显然是完全共线的数据X1X2协方差矩阵S [[1, 1], [1, 1]] 因为X1和X2的方差都是1协方差也是1求S的特征值和特征向量解方程 |S - λI| 0得到特征值 λ12 λ20。对应λ12的特征向量是 [√2/2 √2/2]^T即[0.707 0.707]这就是第一主成分方向。它的载荷表示PC1是由X1和X2各贡献0.707构成的新综合变量。对应λ20的特征向量是[-√2/2 √2/2]^T方差为0没有信息。第一主成分的方差贡献率 2 / (20) 100%。这意味着用一个主成分就能100%还原原始数据的所有信息因为原始数据本就分布在一条直线上。计算主成分得分用原始数据点乘第一主成分方向向量。样本1得分 [1 1] · [0.707 0.707] 1.414样本2得分 [2 2] · [0.707 0.707] 2.828样本3得分 [3 3] · [0.707 0.707] 4.243 这样我们就把二维数据(1,1) (2,2) (3,3)压缩成了一维数据1.414 2.828 4.243并且完全没有信息损失。3. PCA在数学建模中的典型应用场景与实操要点3.1 场景一数据降维与特征提取这是PCA最经典的应用。当你的模型自变量特征数量庞大远超样本量或者特征间高度相关时直接扔进回归或分类模型很容易导致过拟合或计算困难。建模实操步骤数据预处理清洗缺失值、异常值。然后务必进行标准化(x - mean)/std。在Python的sklearn中使用StandardScaler。拟合PCA模型使用sklearn.decomposition.PCA。关键参数是n_components你可以直接指定整数k如n_components5。指定一个0-1之间的浮点数如n_components0.95代表保留95%的方差。初始不指定先拟合全部成分再通过分析碎石图和累积贡献率来决定k。分析与解释查看pca.explained_variance_ratio_这是各主成分的方差贡献率。查看pca.components_这是主成分的载荷矩阵。解读载荷是理解主成分含义的关键。例如如果PC1在“人均GDP”、“科研投入”、“高校数量”上都有很高的正载荷那么PC1可以解释为“城市综合发展水平”因子。获取新特征使用pca.transform(X_scaled)得到降维后的新数据集X_pca用于后续的回归、分类或聚类分析。注意事项与心得信息损失是必然的PCA是一种有损压缩。保留95%的方差意味着你主动丢弃了5%的信息这部分可能是噪声也可能是某些细微但重要的模式。在关乎预测精度的比赛中需要权衡降维带来的稳定性提升和潜在的信息损失。主成分的可解释性有时主成分的载荷分布很平均难以赋予清晰的业务含义。这时不必强行解释可以将其视为纯粹的“数学特征”。在建模报告中应展示前几个主成分的载荷矩阵并尝试解释。不要对标签y做PCAPCA只应用于特征X数据。永远不要将需要预测的因变量也放入PCA中一起降维。3.2 场景二多维数据可视化人眼最多能舒服地观察三维数据。PCA可以将成百上千维的数据降到2维或3维从而让我们能够直观地在散点图上观察样本的分布、聚集和异常情况。实操要点通常将数据降至2维PC1 vs PC2或3维。绘制散点图后可以结合样本的原始标签如果有的话进行着色观察在主成分空间中不同类别的样本是否能够被区分开。这常用于探索性数据分析为后续选择分类模型提供直觉。可以在散点图旁绘制双标图。双标图同时展示了样本点在主成分空间的位置和原始变量以向量的形式。变量的向量方向表示该变量与主成分的关系夹角越小相关性越强长度表示该变量在该二维视图中的代表性强度。这有助于直观理解哪些原始变量对前两个主成分的贡献大。一个常见误区用2D PCA图展示的聚类效果很好不代表用原始数据或更多主成分做聚类效果也一样好。2D视图可能丢失了在更高主成分上的区分信息。它主要是一个强大的可视化探索工具而非最终的结论证明。3.3 场景三消除多重共线性与数据去噪在多元线性回归中如果自变量之间高度相关多重共线性会导致回归系数估计不稳定、方差膨胀、甚至模型无法求解。PCA生成的主成分是正交不相关的用它们作为新的自变量进行回归就彻底避免了共线性问题。这种回归称为主成分回归。此外PCA假设数据变异的主要部分由前几个主成分承载而方差很小的后几个主成分往往被认为是随机噪声。因此如果我们只保留前k个主成分并反向转换回原始变量空间使用pca.inverse_transform就可以得到一份“去噪”后的数据。这在图像处理、信号处理中很常见。实操心得主成分回归的陷阱PCR虽然解决了共线性但主成分是数学构造可能失去业务含义。更重要的是用于预测的第一主成分未必是与因变量y最相关的那一个。有时一个方差很小的主成分可能与y高度相关。因此更推荐使用偏最小二乘法它在寻找成分时同时考虑了最大化解释X的方差和最大化与y的相关性。去噪的代价PCA去噪是一种线性滤波。对于非线性结构的数据可能会滤掉重要特征。在建模中除非有明确证据表明后部主成分是噪声否则谨慎使用。4. 基于Python的PCA完整实战流程与代码解析我们将使用经典的鸢尾花数据集进行全流程演示这个数据集有4个特征花萼和花瓣的长宽3个类别。我们将完成从数据探索、PCA降维、可视化到结果解读的全过程。4.1 环境准备与数据加载# 导入必要的库 import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns from sklearn.datasets import load_iris from sklearn.preprocessing import StandardScaler from sklearn.decomposition import PCA # 设置中文显示和图形样式如果环境支持 plt.rcParams[font.sans-serif] [SimHei] # 用来正常显示中文标签 plt.rcParams[axes.unicode_minus] False # 用来正常显示负号 sns.set(stylewhitegrid) # 加载鸢尾花数据集 iris load_iris() X iris.data # 特征数据形状 (150 4) y iris.target # 目标标签 0: setosa 1: versicolor 2: virginica feature_names iris.feature_names target_names iris.target_names # 查看数据基本信息 print(f数据形状: {X.shape}) # (150 4) print(f特征名称: {feature_names}) print(f目标类别: {target_names})4.2 数据标准化与PCA拟合# 1. 数据标准化 - PCA前至关重要的一步 scaler StandardScaler() X_scaled scaler.fit_transform(X) # 均值为0标准差为1 print(标准化后前5个样本:\n X_scaled[:5]) # 2. 初始拟合PCA查看所有成分的方差解释情况 pca_full PCA() X_pca_full pca_full.fit_transform(X_scaled) # 计算累积方差贡献率 explained_variance_ratio pca_full.explained_variance_ratio_ cumulative_variance_ratio np.cumsum(explained_variance_ratio) print(\n各主成分方差贡献率:, explained_variance_ratio) print(累积方差贡献率:, cumulative_variance_ratio)运行后你可能会看到类似输出各主成分方差贡献率: [0.72962445 0.22850762 0.03668922 0.00517871] 累积方差贡献率: [0.72962445 0.95813207 0.99482129 1. ]解读第一个主成分PC1就解释了约73%的总方差前两个主成分PC1PC2一起解释了约95.8%的方差。这意味着我们只用两个新变量就能保留原始4个变量中95.8%的信息降维效果非常显著。4.3 可视化分析碎石图与累积贡献率图# 绘制碎石图与累积贡献率图双Y轴 fig ax1 plt.subplots(figsize(10 6)) # 碎石图条形图折线 components range(1 len(explained_variance_ratio)1) ax1.bar(components explained_variance_ratio alpha0.6 colorb label单个贡献率) ax1.plot(components explained_variance_ratio ro-, linewidth2) ax1.set_xlabel(主成分序号) ax1.set_ylabel(方差贡献率单个 colorb) ax1.tick_params(axisy labelcolorb) ax1.set_xticks(components) ax1.set_title(PCA方差解释分析图) # 累积贡献率图折线次Y轴 ax2 ax1.twinx() ax2.plot(components cumulative_variance_ratio gs-, linewidth2 label累积贡献率) ax2.set_ylabel(累积方差贡献率 colorg) ax2.tick_params(axisy labelcolorg) ax2.axhline(y0.95 colorr linestyle-- alpha0.5 label95%阈值) # 添加图例 lines_1 labels_1 ax1.get_legend_handles_labels() lines_2 labels_2 ax2.get_legend_handles_labels() ax2.legend(lines_1 lines_2 labels_1 labels_2 loccenter right) plt.tight_layout() plt.show()通过这个图我们可以清晰地看到“拐点”出现在第2或第3个成分之后。结合累积贡献率保留2个主成分达到95.8%是一个合理的选择。4.4 降维至2维并进行可视化# 3. 根据分析选择保留2个主成分重新拟合PCA pca PCA(n_components2) X_pca pca.fit_transform(X_scaled) # 得到降维后的新数据 (150 2) print(降维后数据形状:, X_pca.shape) # 4. 创建降维后的数据DataFrame方便分析 df_pca pd.DataFrame(dataX_pca columns[主成分1 (PC1) 主成分2 (PC2)]) df_pca[鸢尾花类别] [target_names[label] for label in y] # 添加类别标签 print(\n降维后数据前5行:) print(df_pca.head()) # 5. 可视化2D PCA结果 plt.figure(figsize(10 8)) scatter plt.scatter(X_pca[: 0] X_pca[: 1] cy cmapviridis edgecolork s70 alpha0.8) plt.xlabel(第一主成分 (PC1 解释方差{:.2%}).format(explained_variance_ratio[0])) plt.ylabel(第二主成分 (PC2 解释方差{:.2%}).format(explained_variance_ratio[1])) plt.title(鸢尾花数据集PCA降维可视化 (2D)) plt.colorbar(scatter label鸢尾花类别) # 为每个类别添加文本标注取类中心点 for target name in enumerate(target_names): center X_pca[y target].mean(axis0) plt.text(center[0] center[1] name fontsize12 fontweightbold bboxdict(boxstyleroundpad0.3 facecolorwhite alpha0.8)) plt.grid(True alpha0.3) plt.tight_layout() plt.show()从生成的散点图可以清晰看到三个类别的鸢尾花在PC1-PC2平面上被很好地分开了。Setosa类标签0与其他两类完全分离而Versicolor和Virginica在PC2方向上有所重叠但在PC1方向上仍有区分度。这直观地证明了原始4个特征中蕴含的类别区分信息主要集中在前两个主成分里。4.5 深入解读载荷分析与双标图理解主成分的含义需要看载荷矩阵。# 查看前两个主成分的载荷特征向量 loadings pca.components_.T # 转置一下使得每行对应一个原始特征 df_loadings pd.DataFrame(loadings columns[PC1 载荷 PC2 载荷] indexfeature_names) print(主成分载荷矩阵原始特征对主成分的贡献:) print(df_loadings) # 绘制载荷热图 plt.figure(figsize(8 4)) sns.heatmap(df_loadings annotTrue cmapRdBu_r center0 fmt.3f linewidths0.5) plt.title(主成分载荷热图) plt.tight_layout() plt.show()假设载荷矩阵如下PC1 载荷 PC2 载荷 sepal length (cm) 0.521 -0.377 sepal width (cm) -0.269 -0.923 petal length (cm) 0.580 -0.024 petal width (cm) 0.565 -0.066解读PC1在所有特征除了花萼宽上都有较高的正载荷。这意味着PC1是一个反映花朵整体尺寸大小的综合指标。PC1得分高的花其花萼长、花瓣长、花瓣宽都比较大。PC2在“花萼宽”上有非常大的负载荷-0.923在“花萼长”上有中等负载荷-0.377而在花瓣尺寸上载荷很小。这意味着PC2主要代表了花萼的“宽长比”或形态与整体尺寸关系不大。PC2得分低更负的花具有相对更宽的花萼。结合之前的散点图Setosa花在PC1上得分低整体尺寸小在PC2上得分高花萼相对较窄长这里需要结合具体数值符号看而Virginica在PC1上得分高整体尺寸大。这样的解读就让主成分有了明确的植物形态学意义。绘制双标图Biplot可以一次性展示样本点和变量向量的关系# 简易版双标图绘制函数 def biplot(score loadings labelsNone feature_namesNone): 绘制PCA双标图 xs score[: 0] # 第一主成分得分 ys score[: 1] # 第二主成分得分 scalex 1.0 / (xs.max() - xs.min()) scaley 1.0 / (ys.max() - ys.min()) score_scaled np.column_stack([xs * scalex ys * scaley]) # 缩放得分以便与向量同图显示 plt.figure(figsize(10 8)) # 绘制样本点按类别着色 scatter plt.scatter(score_scaled[: 0] score_scaled[: 1] cy cmapviridis alpha0.6 edgecolorsk s50) # 绘制特征向量箭头 for i feature in enumerate(feature_names): plt.arrow(0 0 loadings[i 0] loadings[i 1] colorr alpha0.8 head_width0.02 head_length0.02) plt.text(loadings[i 0] * 1.15 loadings[i 1] * 1.15 feature colordarkred hacenter vacenter fontsize11 fontweightbold) plt.xlabel(fPC1 ({explained_variance_ratio[0]:.2%})) plt.ylabel(fPC2 ({explained_variance_ratio[1]:.2%})) plt.title(PCA双标图 (Biplot)) plt.grid(True alpha0.3) # 设置坐标轴范围使箭头清晰可见 plt.xlim(min(score_scaled[: 0].min() loadings[: 0].min())-0.1 max(score_scaled[: 0].max() loadings[: 0].max())0.1) plt.ylim(min(score_scaled[: 1].min() loadings[: 1].min())-0.1 max(score_scaled[: 1].max() loadings[: 1].max())0.1) plt.axhline(y0 colork linestyle-- alpha0.3) plt.axvline(x0 colork linestyle-- alpha0.3) plt.colorbar(scatter label鸢尾花类别) plt.tight_layout() plt.show() # 调用函数绘制双标图 biplot(X_pca loadings labelsy feature_namesfeature_names)在双标图中箭头指向表示该原始变量与主成分的关系方向。例如“petal length”箭头指向右上方说明花瓣长的花其PC1和PC2得分都倾向于更高。箭头长度大致代表该变量在该二维视图中的重要性。可以清晰看到“petal length”和“petal width”的箭头方向与PC1高度一致印证了PC1是“整体尺寸”因子。5. 数学建模中应用PCA的常见问题与避坑指南5.1 问题一标准化到底做不做什么时候做这是新手最容易困惑的点。必须做标准化的场景原始变量量纲不同如身高cm vs 体重kg或数量级差异巨大如GDP万亿 vs 失业率百分比。不做标准化PCA的结果会被大尺度变量完全主导。可以考虑不做标准化仅中心化的场景所有变量单位一致且你希望保留原始变量的方差信息。例如所有特征都是同一类传感器的读数单位都是mV且你认为读数波动大的传感器本身就更重要。建模竞赛中的建议除非有非常明确的理由否则默认进行标准化。在论文中必须明确写明“在进行PCA前我们对所有特征进行了Z-score标准化处理以消除量纲影响。”5.2 问题二主成分个数k到底怎么选没有绝对的金标准需要结合多种方法并服务于建模目标。累积贡献率阈值法最常用。在建模中85%-95%是常见区间。追求高保真可选95%追求极致降维可选85%。碎石图拐点法观察碎石图选择斜率明显变缓的“肘部”之前的成分。比较主观但直观。特征值大于1准则适用于基于相关矩阵的PCA。保留特征值1的成分。在Python中pca PCA(n_components‘mle’)可以使用一种基于最大似然估计的自动选择方法效果也不错。交叉验证法如果你的最终目标是构建预测模型如回归、分类可以将k的选择纳入交叉验证流程。尝试不同的k值进行降维然后用降维后的数据训练模型选择在验证集上性能最好的k。这是最严谨但计算量较大的方法。实操心得在数学建模论文中建议同时展示碎石图和累积贡献率表并明确陈述你选择k值的理由。例如“由图X的碎石图可见前两个主成分后曲线趋于平缓。且前两个主成分的累积方差贡献率达到95.8%足以代表原始数据的大部分信息因此我们选择保留两个主成分进行后续分析。”5.3 问题三PCA处理过的数据还能回到原始变量吗可以但这是有损的。使用pca.inverse_transform(X_pca)可以将降维后的数据X_pca假设保留了k个成分转换回原始特征空间但维度是原始的p维。这个重构的数据X_reconstructed是使用k个主成分所能做到的、对原始数据X的最佳线性逼近。两者的差异重构误差就是你丢弃的那部分信息。这个功能在数据去噪和压缩中很有用。但在特征提取用于建模的场景下我们通常直接使用主成分得分X_pca不需要回退。5.4 问题四PCA是万能的吗有哪些局限和替代方案绝对不是。PCA的局限性包括线性假设PCA只能捕捉线性关系。如果变量间存在复杂的非线性关系如环形、流形结构PCA效果会很差。此时应考虑核PCA或t-SNE、UMAP等非线性降维方法。方差最大化不等于信息最大化PCA以保留最大方差为目标但方差最大的方向不一定是对下游任务如分类最重要的方向。如果目标是预测线性判别分析或偏最小二乘法可能更合适。对异常值敏感由于基于方差和协方差异常值会极大地扭曲主成分的方向。在应用PCA前务必做好异常值检测和处理。主成分的可解释性挑战有时主成分是多个原始变量的复杂混合难以赋予清晰的实际意义。在数学建模中的策略PCA通常是高维数据探索和预处理的第一步。你可以先用PCA可视化数据、观察结构、去除明显共线性。然后根据后续模型的需求决定是使用PCA降维后的特征还是结合领域知识筛选原始特征或者尝试其他非线性方法。在论文中清晰展示PCA的分析过程碎石图、载荷矩阵、可视化结果本身就是一份出色的探索性数据分析内容。5.5 一个完整的建模代码模板框架这里提供一个在数学建模中可直接套用的PCA分析模板框架 数学建模PCA分析通用模板 import pandas as pd import numpy as np from sklearn.preprocessing import StandardScaler from sklearn.decomposition import PCA import matplotlib.pyplot as plt import seaborn as sns # 1. 加载和探索数据 df pd.read_csv(your_data.csv) X df.drop(columns[target_column]) # 假设最后一列是目标变量y y df[target_column] print(数据形状:, X.shape) print(\n数据描述前5行:\n X.head()) print(\n特征基本信息:\n X.describe()) # 2. 数据预处理处理缺失值、异常值此处略 # X handle_missing_values(X) # X remove_outliers(X) # 3. 特征标准化 scaler StandardScaler() X_scaled scaler.fit_transform(X) # 4. 初步PCA分析决定成分数 pca_full PCA() X_pca_full pca_full.fit_transform(X_scaled) # 计算方差解释 explained_variance pca_full.explained_variance_ratio_ cumulative_variance np.cumsum(explained_variance) # 绘制决策图 fig axes plt.subplots(1 2 figsize(14 5)) axes[0].plot(range(1 len(explained_variance)1) explained_variance bo-) axes[0].set_title(碎石图) axes[0].set_xlabel(主成分序号) axes[0].set_ylabel(方差贡献率) axes[0].grid(True) axes[1].plot(range(1 len(cumulative_variance)1) cumulative_variance ro-) axes[1].axhline(y0.95 colorg linestyle-- label95%阈值) axes[1].set_title(累积方差贡献率图) axes[1].set_xlabel(主成分序号) axes[1].set_ylabel(累积方差贡献率) axes[1].legend() axes[1].grid(True) plt.tight_layout() plt.show() # 打印表格方便写入论文 variance_df pd.DataFrame({ 主成分: [fPC{i1} for i in range(len(explained_variance))] 方差贡献率: explained_variance 累积贡献率: cumulative_variance }) print(variance_df.round(4)) # 5. 根据图表决定保留k个成分例如k2 k 2 print(f\n决定保留前{k}个主成分累积解释方差{cumulative_variance[k-1]:.2%}) # 6. 使用选定的k重新拟合PCA并获取降维后数据 pca PCA(n_componentsk) X_pca pca.fit_transform(X_scaled) print(f降维后数据形状: {X_pca.shape}) # 7. 可选分析主成分载荷尝试解释 loadings pca.components_.T df_loadings pd.DataFrame(loadings columns[fPC{i1} for i in range(k)] indexX.columns) print(\n主成分载荷矩阵:) print(df_loadings) # 8. 可视化2D或3D if k 2: plt.figure(figsize(8 6)) if y is not None: # 如果有类别标签按类别着色 scatter plt.scatter(X_pca[: 0] X_pca[: 1] cy cmaptab10 alpha0.7 edgecolorsk) plt.colorbar(scatter) else: plt.scatter(X_pca[: 0] X_pca[: 1] alpha0.7) plt.xlabel(fPC1 ({explained_variance[0]:.2%})) plt.ylabel(fPC2 ({explained_variance[1]:.2%})) plt.title(PCA降维可视化) plt.grid(True alpha0.3) plt.tight_layout() plt.show() # 9. 将降维后的数据保存用于后续建模 df_pca_result pd.DataFrame(X_pca columns[fPC{i1} for i in range(k)]) if y is not None: df_pca_result[target] y.values df_pca_result.to_csv(pca_reduced_data.csv indexFalse) print(降维后数据已保存至 pca_reduced_data.csv)掌握这个模板你就能在数学建模中快速、规范地完成PCA分析并将清晰的结果和图表呈现在论文中。记住PCA不仅是一个技术工具更是你理解高维数据、讲述数据故事的有力武器。在应用时多想一步“这个主成分意味着什么”你的模型和论文会因此增色不少。