发布于2026-07-17 阅读(0)
扫一扫,手机访问
PCA降维这事,说起来简单,但实际用起来,坑还真不少。先说几个核心判断:你得先理解PCA的“脾气”,知道它什么时候该“fit”,什么时候该“transform”;主成分个数选多少,不能光看心情;画图的时候,坐标轴传对了没?还有,数据本身合不合适,心里得有个数。下面咱们把这些关键点掰开揉碎了说。

fit_transform 和 transform 混用导致报错最让人头疼的坑,就是训练和预测阶段把fit_transform和transform搞混了。比如,训练时用fit_transform跑了一遍,结果新数据来了,又顺手调了个fit_transform,系统立马就给你看脸色:ValueError: X has 5 features, but PCA is expecting 10。这其实是个原则性问题。PCA的逻辑是,先通过fit(或者fit_transform)从训练数据里“学习”出一套主成分方向,然后,之后所有新数据,都只能老老实实地用这套方向去transform,不能重新“学习”。
pca.fit_transform(X_train),得到降维后的数据,同时把模型保存下来。pca 实例,调用 pca.transform(X_test),千万不能重新 fit。StandardScaler 做预处理,道理一样,只对训练集 fit 一次,然后拿这个标准去 transform 测试集。n_components 设成整数还是小数很关键那么,到底选多少个主成分才合适?n_components这个参数,直接决定了你保留了多少信息,以及后续模型的效果。设成整数,比如5,意思就是固定保留前5个主成分;设成0到1之间的小数,比如0.95,那就灵活多了——它会自动帮你保留能解释95%方差的最少成分数量。在原始特征维度高、相关性又不明确的时候,用小数是更稳妥的做法。
n_components=0.95,记得跑完后检查一下 pca.n_components_,看看实际取了多少个主成分,别被意外压缩过度给坑了。n_components 大于了样本数和特征数中较小的那个,系统会直接报错 ValueError: n_components must be <= min(n_samples, n_features)。plt.scatter 坐标传错列名就白忙活这点看起来简单,但出错率极高。PCA跑出来的结果是一个numpy.ndarray,没有列名。你想画前两个主成分的散点图,必须明确地取第0列和第1列:plt.scatter(X_pca[:, 0], X_pca[:, 1], c=y)。如果写成X_pca['PC1'],或者误用了原始特征的名字,那系统就会毫不客气地给你报KeyError或IndexError。
pd.DataFrame(X_pca) 自动命名列,手动加列名更可控,比如:pd.DataFrame(X_pca, columns=[f'PC{i+1}' for i in range(X_pca.shape[1])])。y 是字符串(比如类别名),直接用 c=y 会报错,得先映射成数字:from sklearn.preprocessing import LabelEncoder; y_num = LabelEncoder().fit_transform(y)。plt.colorbar() 配合 c 参数时,确保 y 是数值型,否则颜色条会显示异常,看着怪别扭的。话说回来,PCA确实不是万能药。它本质上是一个线性、基于均方误差最优的正交投影,碰到三类数据,基本就歇菜了:一是含有强离群点的数据,它们会严重拉偏协方差;二是文本类稀疏矩阵(比如scipy.sparse),sklearn.PCA 根本不支持;三是本质呈流形结构的数据,比如环形、S形,线性投影会把原本不同类别的数据点压到一起,导致分类完全失败。
RobustScaler 处理,或者干脆删掉离群点再做PCA,别指望PCA自带鲁棒性。TruncatedSVD,接口跟PCA几乎一样,但它能支持稀疏矩阵。TSNE 或 UMAP。不过要注意,它们不可逆,也不支持 transform 新样本。真正麻烦的是,你往往很难一开始就判断数据到底适不适合PCA。直到你画完图,发现所有类别都糊在一起,这时候才回过头去检查原始变量的相关性,画协方差热力图,甚至跑个 KernelPCA 做个对比——而不是硬着头皮调 n_components 这个参数。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8