特征降维实战五步跑通主成分分析

文章配图

数据集几十上百个维度,训练慢还容易过拟合,心里清楚不是所有特征都有用,又说不清砍哪些——这是做机器学习最常见的处境。主成分分析的思路是换一个方向解决:不在原始特征里挑挑拣拣,把数据投影到几个按方差排序的新方向上,取前几个就够。这篇不推导数学,直接用 Scikit-Learn 五步跑通,并补上源教程没展开的选型边界。

五步流程

第一步加载数据。用自带的红酒数据集演示,13 个化学成分特征、178 条样本:

from sklearn import datasets
wine_data = datasets.load_wine(as_frame=True)
df = wine_data.data
print(df.shape)   # (178, 13)

第二步标准化,这步是整个流程的成败关键。特征的量纲差异大——酒精含量十几、镁含量上百,直接进 PCA 会让大方差特征主导主成分方向,结果失真。StandardScaler 把每个特征拉成零均值单位方差:

文章配图

from sklearn.preprocessing import StandardScaler
scaled_df = StandardScaler().fit_transform(df)

第三步执行降维,拟合和变换一个方法完成,底层用 SVD 而非特征值分解,数值上更稳:

from sklearn.decomposition import PCA
pca = PCA(n_components=3)
transformed = pca.fit_transform(scaled_df)

第四步读关键属性。components_ 存主成分方向,explained_variance_ratio_ 给每个主成分捕获的方差比例,求和就是保留的信息量占比:

print(sum(pca.explained_variance_ratio_))  # 0.6653

13 维压到 3 维剩约 66.5%,丢了三分之一方差——够不够取决于下游任务。

文章配图

第五步选主成分数量。把 n_components 从 1 遍历到最大值,画累积方差解释比曲线找拐点:

import numpy as np, matplotlib.pyplot as plt
var_ratio = []
for num in range(14):
    p = PCA(n_components=num).fit(scaled_df)
    var_ratio.append(np.sum(p.explained_variance_ratio_))
plt.plot(range(14), var_ratio, marker='o')
plt.grid(True)

红酒数据集在第 6 个主成分附近累积超过 80%——不到一半的维度保住八成信息。工程上 80% 到 90% 是合理区间。

两个被教程略过的实用细节

一是 n_components 可以传浮点数:PCA(n_components=0.95) 会自动选保留 95% 方差的最少主成分数,省掉手调。二是验收别只看方差比,加一道重构校验——用 inverse_transform 把降维数据还原,算与原始数据的均方误差,误差分布异常说明主成分方向被离群样本带偏了。

适用边界与失效场景

PCA 是线性方法,假设主成分是原始特征的线性组合。数据有明显非线性结构(卷曲流形)时效果平庸,换 t-SNE 或 UMAP。类别型特征多的话先 One-Hot 再标准化,维度反而膨胀,这时降维价值更明显;但高维稀疏的文本 TF-IDF 矩阵不建议直接 PCA——稠密化成本高,适合走截断 SVD。还有一条常被误解:主成分本身没有物理含义,第一主成分可能是一堆特征的混合,需要可解释特征选择时应换 Lasso 或树模型的重要性排序,两者是不同目标。标准化永远不省、浮点阈值先试、线性假设先想清楚——这三条比五步流程本身更决定 PCA 在你的数据上好不好用。

0

评论0

请先
显示验证码
没有账号?注册  忘记密码?