概述
降维(Dimensionality Reduction)是机器学习和数据科学中的核心技术,用于将高维数据映射到低维空间,同时尽可能保留原始数据的重要结构。1
本文全面对比主流降维技术,帮助读者根据具体场景选择合适的方法。
1. 降维技术分类
1.1 按保留结构分类
| 类型 | 代表方法 | 核心思想 |
|---|---|---|
| 保留全局结构 | PCA, SVD | 保留最大方差方向 |
| 保留局部结构 | t-SNE, UMAP, LLE | 保持邻居关系 |
| 保留测地距离 | ISOMAP, MDS | 保留流形上的距离 |
1.2 按线性/非线性分类
降维方法
├── 线性方法
│ ├── PCA(主成分分析)
│ ├── LDA(线性判别分析)
│ └── SVD(奇异值分解)
│
└── 非线性方法(流形学习)
├── 全局方法
│ ├── ISOMAP
│ └── MDS(多维缩放)
│
├── 局部方法
│ ├── t-SNE
│ ├── UMAP
│ └── LLE(局部线性嵌入)
│
└── 基于图的
└── Laplacian Eigenmaps
1.3 按监督/非监督分类
| 类别 | 方法 | 说明 |
|---|---|---|
| 非监督 | PCA, t-SNE, UMAP, ISOMAP, LLE | 不使用标签信息 |
| 监督 | LDA, 监督UMAP | 利用标签信息 |
| 半监督 | 标签传播 + 降维 | 部分标签信息 |
2. 方法详细对比
2.1 核心算法对比表
| 方法 | 线性/非线性 | 时间复杂度 | 空间复杂度 | 保留结构 | 可逆性 | Out-of-sample |
|---|---|---|---|---|---|---|
| PCA | 线性 | 全局方差 | 是 | 是(闭式) | ||
| t-SNE | 非线性 | 局部邻居 | 否 | 否 | ||
| UMAP | 非线性 | 局部+部分全局 | 近似 | 是 | ||
| LLE | 非线性 | 局部线性 | 否 | 否 | ||
| ISOMAP | 非线性 | 测地距离 | 否 | 否 | ||
| LDA | 线性 | 类间可分性 | 是 | 是 |
2.2 理论特性对比
| 方法 | 理论基础 | 全局结构 | 局部结构 | 距离保持 | 连续性 | 可解释性 |
|---|---|---|---|---|---|---|
| PCA | 方差最大化 | ✓✓✓ | ○ | 部分 | ✓ | ✓✓✓ |
| t-SNE | KL散度 | ○ | ✓✓✓ | 不保证 | ✓ | ○ |
| UMAP | 拓扑数据分析 | ✓ | ✓✓✓ | 部分 | ✓ | ○ |
| LLE | 局部线性重构 | ○ | ✓✓✓ | 部分 | ✓ | ○ |
| ISOMAP | 测地距离 | ✓✓ | ✓ | ✓✓ | ✓ | ○ |
注:✓✓✓ = 完全支持,✓✓ = 较好支持,✓ = 支持,○ = 不支持或有限
2.3 适用场景对比
| 场景 | 推荐方法 | 理由 |
|---|---|---|
| 数据预处理 | PCA | 保留信息、计算高效、可逆 |
| 聚类可视化 | UMAP / t-SNE | 分离聚类效果好 |
| 连续结构可视化 | UMAP / ISOMAP | 保持全局趋势 |
| 分类可视化 | LDA / 监督UMAP | 利用类别信息 |
| 大规模数据(>100K) | UMAP / PCA | 效率高 |
| 流形学习 | ISOMAP / UMAP | 理论基础强 |
| 需要可逆 | PCA / 自编码器 | 保留重构能力 |
3. 理论联系
3.1 流形学习视角
流形学习假设高维数据实际上分布在一个低维流形上。
流形的数学定义:
是一个 维流形,如果对于每一点 ,存在一个邻域同胚于 。
核心假设:
- 数据 是从某个低维流形 采样
- 流形上可以定义局部度量
- 目标是恢复流形的几何结构
3.2 图拉普拉斯视角
许多降维方法可以统一到图拉普拉斯框架:
构图:根据数据构建加权图
拉普拉斯矩阵:
其中 是度矩阵, 是权重矩阵。
谱方法:最小化
这统一了Laplacian Eigenmaps、LLE和谱聚类。
3.3 信息论视角
| 方法 | 信息论基础 |
|---|---|
| PCA | 最大化保留的方差(香农熵相关) |
| t-SNE | 最小化KL散度(互信息相关) |
| UMAP | 最小化交叉熵(信息论度量) |
4. 数学公式对比
4.1 目标函数总结
PCA:
t-SNE:
UMAP:
LLE:
ISOMAP:
4.2 计算特性对比
| 方法 | 收敛性 | 唯一性 | 迭代次数 |
|---|---|---|---|
| PCA | 闭式解 | 全局唯一 | 0 |
| t-SNE | 梯度下降 | 可能不唯一 | 1000-5000 |
| UMAP | 梯度下降 | 可能不唯一 | 200-500 |
| LLE | 特征分解 | 缩放不确定 | 0 |
| ISOMAP | 特征分解 | 缩放不确定 | 0 |
5. 深度学习中的降维
5.1 自编码器降维
自编码器提供了一种数据驱动的降维方法:
import torch
import torch.nn as nn
class Autoencoder(nn.Module):
def __init__(self, input_dim, latent_dim):
super().__init__()
# 编码器
self.encoder = nn.Sequential(
nn.Linear(input_dim, 256),
nn.ReLU(),
nn.Linear(256, latent_dim) # 潜在空间
)
# 解码器
self.decoder = nn.Sequential(
nn.Linear(latent_dim, 256),
nn.ReLU(),
nn.Linear(256, input_dim)
)
def forward(self, x):
z = self.encoder(x)
return self.decoder(z)与线性方法的对比:
| 特性 | PCA | 自编码器 |
|---|---|---|
| 线性/非线性 | 线性 | 非线性 |
| 可逆性 | 精确 | 近似 |
| 学习方式 | 无监督 | 无监督 |
| 可解释性 | 高 | 低 |
5.2 对比学习表示
对比学习方法学习到的表示可以直接用于降维可视化:
from sklearn.manifold import TSNE
import umap
import numpy as np
# 假设 features 是对比学习模型提取的特征
features = contrastive_model(images)
# t-SNE可视化
tsne = TSNE(n_components=2, perplexity=30)
features_tsne = tsne.fit_transform(features)
# UMAP可视化
reducer = umap.UMAP(n_components=2, n_neighbors=15, min_dist=0.1)
features_umap = reducer.fit_transform(features)5.3 预训练模型特征
预训练CNN/ViT的特征可以先用PCA降维再用t-SNE/UMAP可视化:
# 1. 提取特征
features = pretrained_model(images) # (N, 2048)
# 2. PCA降维(可选,加速)
from sklearn.decomposition import PCA
pca = PCA(n_components=50)
features_pca = pca.fit_transform(features)
# 3. 非线性降维
reducer = umap.UMAP(n_components=2)
features_2d = reducer.fit_transform(features_pca)6. 实践选择指南
6.1 决策流程图
开始
↓
数据规模?
├─ 大规模(>100K)→ UMAP 或 PCA+UMAP
│
└─ 小规模(<100K)→ 继续判断
↓
目标是什么?
├─ 可视化聚类 → t-SNE 或 UMAP
├─ 可视化连续结构 → UMAP 或 ISOMAP
├─ 预处理/降噪 → PCA
├─ 分类增强 → LDA
└─ 保留重构能力 → PCA 或 自编码器
6.2 参数调优建议
PCA:
- 通常不需要调参
- 选择保留的方差比例(通常95-99%)
t-SNE:
- perplexity: 5-50(默认30)
- learning_rate: 200-1000
- n_iter: 1000-5000
UMAP:
- n_neighbors: 10-50(默认15)
- min_dist: 0-0.5(默认0.1)
- metric: 根据数据选择
6.3 代码模板
from sklearn.decomposition import PCA
from sklearn.manifold import TSNE
import umap
import numpy as np
def reduce_dimensions(X, method='umap', **kwargs):
"""
统一的降维接口
Parameters:
-----------
X : array of shape (n_samples, n_features)
输入数据
method : str
降维方法:'pca', 'tsne', 'umap'
**kwargs : dict
方法特定的参数
"""
if method == 'pca':
n_components = kwargs.get('n_components', 2)
pca = PCA(n_components=n_components)
return pca.fit_transform(X)
elif method == 'tsne':
n_components = kwargs.get('n_components', 2)
perplexity = kwargs.get('perplexity', 30)
tsne = TSNE(n_components=n_components, perplexity=perplexity)
return tsne.fit_transform(X)
elif method == 'umap':
n_components = kwargs.get('n_components', 2)
n_neighbors = kwargs.get('n_neighbors', 15)
min_dist = kwargs.get('min_dist', 0.1)
reducer = umap.UMAP(n_components=n_components,
n_neighbors=n_neighbors,
min_dist=min_dist)
return reducer.fit_transform(X)
else:
raise ValueError(f"Unknown method: {method}")7. 综合对比可视化
7.1 保留结构对比
| 方法 | 全局距离 | 局部邻居 | 聚类结构 | 连续流形 |
|---|---|---|---|---|
| PCA | ✓✓✓ | ○ | ○ | ○ |
| Kernel PCA | ✓✓ | ✓ | ✓ | ✓ |
| t-SNE | ○ | ✓✓✓ | ✓✓✓ | ✓ |
| UMAP | ✓ | ✓✓✓ | ✓✓✓ | ✓✓ |
| LLE | ○ | ✓✓✓ | ✓ | ✓✓ |
| ISOMAP | ✓✓ | ✓✓ | ✓ | ✓✓✓ |
7.2 计算效率对比
效率排名(从高到低):
1. PCA (闭式解)
2. UMAP (O(n log n))
3. LLE (O(dn²))
4. ISOMAP (O(dn²))
5. t-SNE (O(n²) 或 O(n log n) with Barnes-Hut)
7.3 内存需求对比
| 方法 | 内存复杂度 | 大数据处理 |
|---|---|---|
| PCA | ✓✓✓ | |
| UMAP | ✓✓✓ | |
| t-SNE | 需要采样 | |
| ISOMAP | 需要采样 |
8. 总结与建议
8.1 选择原则
-
预处理阶段:使用PCA
- 计算高效
- 保留最多信息
- 可逆
-
聚类可视化:使用UMAP或t-SNE
- 分离聚类效果好
- UMAP更快且保留更多全局结构
-
流形学习:使用UMAP或ISOMAP
- 理论基础强
- 适合非欧几里得数据
-
分类任务:使用LDA或监督UMAP
- 利用标签信息
- 最大化类别可分性
-
需要重构:使用PCA或自编码器
- 可逆
- 适合作为其他任务的输入
8.2 组合使用
实践中经常组合使用多种降维方法:
# Pipeline: PCA → UMAP
pca = PCA(n_components=50) # 先降维到50维
X_pca = pca.fit_transform(X)
# 再UMAP降维到2D
reducer = umap.UMAP(n_components=2)
X_umap = reducer.fit_transform(X_pca)8.3 最新进展
- parametric t-SNE:使用神经网络实现可学习的t-SNE
- parametric UMAP:支持监督学习和自定义损失
- scRNA-seq专用:SCANVI、scVI等针对单细胞数据的专用方法
参考资料
相关阅读
Footnotes
-
van der Maaten, L., Postma, E., & van den Herik, J. (2009). Dimensionality Reduction: A Comparative Review. TiCC, Tilburg University. ↩