PCA 降维
主成分分析(PCA)是最经典的线性降维算法,将高维数据投影到低维空间,同时保留尽可能多的信息。
核心思想
找到数据方差最大的方向(主成分),将数据投影到这些方向上。
- 第一主成分:方差最大的方向
- 第二主成分:与第一主成分正交的前提下,方差最大的方向
- 依此类推...
数学推导
- 中心化数据(减均值)
- 计算协方差矩阵
- 对 C 做特征值分解
- 取前 k 个最大特征值对应的特征向量 → 投影矩阵
import numpy as np
class SimplePCA:
def __init__(self, n_components=2):
self.n_components = n_components
def fit(self, X):
# 中心化
self.mean_ = X.mean(axis=0)
X_centered = X - self.mean_
# 协方差矩阵
cov = np.cov(X_centered.T)
# 特征值分解
eigenvalues, eigenvectors = np.linalg.eigh(cov)
# 取最大的 n_components 个
idx = np.argsort(eigenvalues)[::-1]
self.components_ = eigenvectors[:, idx[:self.n_components]]
self.explained_variance_ = eigenvalues[idx[:self.n_components]]
return self
def transform(self, X):
X_centered = X - self.mean_
return X_centered @ self.components_
def fit_transform(self, X):
self.fit(X)
return self.transform(X)
Scikit-learn 实现
from sklearn.decomposition import PCA
from sklearn.datasets import load_digits
import matplotlib.pyplot as plt
digits = load_digits()
X, y = digits.data, digits.target
# 64 维 → 2 维可视化
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
plt.scatter(X_pca[:, 0], X_pca[:, 1], c=y, cmap='tab10', alpha=0.6)
plt.colorbar()
# 查看保留的方差比例
print(f"每个主成分解释的方差: {pca.explained_variance_ratio_}")
print(f"累计方差: {pca.explained_variance_ratio_.cumsum()}")
如何选择主成分数量
pca = PCA().fit(X)
# 累计方差图
plt.plot(np.cumsum(pca.explained_variance_ratio_))
plt.axhline(y=0.95, color='r', linestyle='--')
plt.xlabel('Number of Components')
plt.ylabel('Cumulative Explained Variance')
# 取保留 95% 方差的组件数
k = np.argmax(np.cumsum(pca.explained_variance_ratio_) >= 0.95) + 1
print(f"保留 95% 方差需要 {k} 个主成分")
也可以用 PCA(n_components=0.95) 直接指定保留的方差比例。
应用场景
1. 降维可视化
高维数据降到 2D/3D 观察分布:
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
X_vis = pca.fit_transform(X)
2. 去噪
pca = PCA(n_components=0.95).fit(X) # 保留 95% 方差
X_denoised = pca.inverse_transform(pca.transform(X))
丢弃小方差的维度往往对应噪声。
3. 加速训练
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
pipe = Pipeline([
('pca', PCA(n_components=50)),
('lr', LogisticRegression()),
])
pipe.fit(X_train, y_train)
PCA vs t-SNE vs UMAP
| 方法 | 特点 | 适用场景 |
|---|---|---|
| PCA | 线性、快速、可逆、可解释 | 降维后做 ML、去噪 |
| t-SNE | 保留局部结构、慢 | 可视化探索 |
| UMAP | 保留局部+部分全局、比 t-SNE 快 | 可视化 + 后续 ML |
注意:t-SNE 和 UMAP 适合可视化探索,但降维后的特征不适合直接用于下游 ML 任务(距离含义已改变)。
总结
| 特性 | 说明 |
|---|---|
| 优点 | 简单快速、去噪、消除特征共线性、可逆 |
| 缺点 | 只捕捉线性关系、主成分难解释、假设方差=信息 |
| 适用场景 | 数据预处理(降维)、去噪、高维数据可视化 |