提起 PCA,也就是主成分分析,很多教程一上来就甩一堆矩阵公式。其实它的想法很朴素:我们手里一堆特征,彼此可能还有关联,能不能用更少的几个新特征,把原本数据里的'骨干信息'保留下来?
PCA 就是一个线性变换,把原始特征重新组合成一组互不相关的新变量——主成分。第一个主成分指向数据方差最大的方向,接下来每个主成分都选在跟前一个正交的方向上,依次按方差大小排列。这样做的好处是,扔掉末尾那些主成分,丢掉的信息最少。
因为是线性方法,所以对表格数据特别管用。它自身无监督,不用标签,在很多领域里都能插一手:
- 图像里做人脸特征提取、压缩
- 金融里做因子分析、降维后可视化成份
- 基因数据里挑出最'活跃'的几个方向
- 问卷调查里把一堆相关问题浓缩成几个主因子
下面来说说它到底怎么算。
计算路数
- 标准化——这一步偷懒不得。比如身高(取值 150-200)和收入(可能几千-几万)直接放进去,方差大的特征会主导主成分,结果根本说明不了问题。必须先让每个特征均值为 0、标准差为 1。
- 协方差矩阵——算一下特征两两之间的相关性,协方差大的就说明它们容易往一个方向变。
- 特征分解——从协方差矩阵里解出特征值和特征向量。特征向量就是主成分的方向,特征值就是它在这个方向上对应的方差。
- 选成分——把特征值从大到小排,取前 k 个特征向量组成投影矩阵。
- 数据映射——把原始标准化数据乘上投影矩阵,维度就从原来的 m 降到了 k。
我喜欢它什么
- 降维之后计算量小了,但信息保留得不错。
- 揭示变量背后的结构,有时还能顺带可视化。
- 无监督,有数据就能跑。
- 末尾成分常常是噪声,丢掉反而干净。
但别忽视它的脾气
- 只抓线性关系。数据如果弯成流形,PCA 直接抓瞎——这种情况换 Kernel PCA 或 t-SNE 更合适。
- 方差大不代表就一定重要。有时候小方差里躲着强判别信息,PCA 会直接扔掉。
- 异常值很烦,一个离群点就能把主成分方向扯歪。
- 解释性会变差。主成分是原始特征的线性组合,不像'性别''年龄'那么直观。
上手代码
聊原理容易困,跑段代码就清楚了。用 scikit-learn 的 PCA,几行就能搞定。
入门:鸢尾花
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
# 加载数据
iris = load_iris()
X = iris.data
y = iris.target
# 先标准化,别忘
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 降到 2 维,方便画图
pca = PCA(n_components=2, random_state=42)
X_pca = pca.fit_transform(X_scaled)
()
()
pca_df = pd.DataFrame(data=X_pca, columns=[, ])
pca_df[] = y
(pca_df.head())


