概述
统一流形逼近与投影(Uniform Manifold Approximation and Projection, UMAP)是一种用于降维和可视化的非线性技术,由McInnes、Healy和Melnick于2018年提出。1
UMAP的核心优势在于:
- 相比t-SNE,保留了更多的全局结构
- 计算速度更快,可扩展性更好
- 理论基础基于拓扑数据分析
1. 理论基础
1.1 拓扑数据分析基础
UMAP的理论基础建立在拓扑数据分析(Topological Data Analysis, TDA)之上。核心假设是:数据分布在一个流形上。
流形假设:
- 高维数据实际上是低维流形的采样
- 流形具有局部欧几里得性质
- 关键是恢复流形的拓扑结构
模糊单纯复形:
UMAP使用模糊单纯复形(Fuzzy Simplicial Complex)来近似数据的拓扑结构:
- 单纯形:点是0-单纯形,线段是1-单纯形,三角形是2-单纯形
- 单纯复形:单纯形的集合,对交集闭合
- 模糊化:每条边有一个隶属度值,表示两点在同一簇的程度
1.2 局部度量结构
UMAP假设在流形的每个局部区域,数据的度量结构是已知的。具体来说:
对于每个点 ,定义局部距离函数 ,这可以是欧氏距离、马氏距离或其他度量。
局部连通性约束:
UMAP通过 -最近邻图来确保局部连通性:
1.3 跨局部结构的连接
UMAP不仅考虑局部结构,还考虑如何跨局部区域连接。这通过模糊单纯复形的交集来实现。
局部模糊单纯集的交集:
两个模糊单纯集 和 的交集定义为:
其中 表示边, 和 是隶属度值。
2. UMAP核心算法
2.1 构造模糊单纯复形
第一步:构建k-邻域图
- 对于每个点 ,找到其 个最近邻
- 确定局部度量缩放因子 (类似t-SNE的困惑度)
- 构建带权重的k-近邻图
局部距离缩放:
UMAP使用基于熵的方法确定 :
其中 是到最近邻的距离。
第二步:定义边权重
对于边 ,定义权重:
2.2 优化目标
UMAP通过最小化模糊单纯复形之间的交叉熵来找到低维嵌入:
其中 是低维空间的隶属度:
参数 和 通过曲线拟合得到,通常 ,。
2.3 交叉熵分解
交叉熵可以分解为两部分:
吸引项:鼓励高维空间中相似的点在低维空间中也接近
排斥项:鼓励高维空间中不相似的点在低维空间中远离
这使得UMAP能够同时保留局部和全局结构。
2.4 算法流程
输入:高维数据 X,邻居数 k,最小距离 d_min,目标维度 n_components
1. 构造模糊单纯复形 C:
a. 计算k-近邻图
b. 确定局部度量 σ_i
c. 计算边权重 w_c(i,j)
2. 初始化低维嵌入 Y(通常使用SVD或随机初始化)
3. 优化交叉熵:
a. 使用类似t-SNE的梯度下降
b. 吸引梯度 + 排斥梯度
c. 使用采样技术加速
4. 返回低维嵌入 Y
3. 关键参数
3.1 n_neighbors(邻居数)
控制考虑多少个最近邻来构建局部结构。
| 值 | 效果 |
|---|---|
| 小(2-10) | 保留更多局部细节,可能丢失全局结构 |
| 中等(15-50) | 平衡局部和全局结构 |
| 大(100+) | 保留更多全局结构 |
3.2 min_dist(最小距离)
控制低维嵌入中点之间的最小距离。
| 值 | 效果 |
|---|---|
| 小(0-0.1) | 点更密集聚在一起 |
| 大(0.5-1.0) | 点更均匀分布,保留更多全局距离 |
3.3 距离度量
UMAP支持多种距离度量:
import umap
# 欧氏距离(默认)
reducer = umap.UMAP(metric='euclidean')
# 余弦距离
reducer = umap.UMAP(metric='cosine')
# 曼哈顿距离
reducer = umap.UMAP(metric='manhattan')
# 自定义距离
reducer = umap.UMAP(metric='precomputed', transform_metric='precomputed')3.4 其他重要参数
| 参数 | 默认值 | 说明 |
|---|---|---|
| n_components | 2 | 目标维度 |
| spread | 1.0 | 与min_dist配合使用 |
| set_op_mix_ratio | 1.0 | 模糊并集运算的参数 |
| local_connectivity | 1.0 | 局部连通性参数 |
4. 与t-SNE的对比
4.1 理论对比
| 特性 | t-SNE | UMAP |
|---|---|---|
| 理论基础 | 概率分布(KL散度) | 拓扑数据分析(模糊单纯复形) |
| 优化目标 | 仅吸引(KL散度) | 吸引+排斥(交叉熵) |
| 全局结构 | 主要保留局部 | 同时保留局部和全局 |
| 距离保留 | 不保证 | 不完全保证,但较好 |
| 计算复杂度 | 或 (Barnes-Hut) |
4.2 实际效果对比
import numpy as np
import matplotlib.pyplot as plt
from sklearn.manifold import TSNE
import umap
# 假设 X 是高维数据
n_samples = 5000
# t-SNE
tsne = TSNE(n_components=2, perplexity=30, random_state=42)
X_tsne = tsne.fit_transform(X)
# UMAP
reducer = umap.UMAP(n_components=2, n_neighbors=15, min_dist=0.1, random_state=42)
X_umap = reducer.fit_transform(X)经验对比:
| 场景 | 推荐方法 | 原因 |
|---|---|---|
| 大数据集(>10000) | UMAP | 速度更快 |
| 聚类可视化 | 两者皆可 | UMAP全局结构更好 |
| 连续结构可视化 | t-SNE | 可能更平滑 |
| 需要out-of-sample | UMAP | 内置支持 |
| 参数调优困难 | UMAP | 对参数不那么敏感 |
4.3 UMAP的独特优势
- Out-of-sample扩展:UMAP可以对新数据进行transform,无需重新训练
- 更高的速度:基于PyTorch和Numba优化
- 监督降维:支持通过标签信息指导降维
- 度量学习:可以用于学习数据的度量结构
5. 实践应用
5.1 基本用法
import umap
import numpy as np
# 生成示例数据
np.random.seed(42)
X = np.random.randn(1000, 10)
# 基本降维
reducer = umap.UMAP(n_components=2, n_neighbors=15, min_dist=0.1)
embedding = reducer.fit_transform(X)
# 查看参数
print(f"Embedding shape: {embedding.shape}")
print(f"Number of components: {reducer.n_components_}")5.2 大规模数据
# 使用UMAP处理大规模数据
reducer = umap.UMAP(
n_components=2,
n_neighbors=30,
min_dist=0.0,
metric='euclidean',
low_memory=True, # 减少内存使用
n_epochs=200 # 增加迭代次数
)5.3 监督降维
UMAP可以接受标签信息来指导降维:
# 监督UMAP
reducer = umap.UMAP(
n_components=2,
n_neighbors=15,
min_dist=0.1,
target=X_labels, # 标签数组
target_weight=0.5 # 监督损失的权重
)5.4 Out-of-sample扩展
# 先拟合
reducer = umap.UMAP(n_components=2)
reducer.fit(X_train)
# 再转换新数据
X_test_embedded = reducer.transform(X_test)5.5 定制距离函数
from scipy.spatial.distance import correlation
def custom_distance(a, b):
return correlation(a, b)
reducer = umap.UMAP(
n_components=2,
metric=custom_distance
)6. 深度学习中的应用
6.1 表示学习可视化
import torch
from torchvision import models
# 提取特征
model = models.resnet50(pretrained=True)
model.fc = torch.nn.Identity() # 移除分类头
# 提取特征
with torch.no_grad():
features = model(images)
# UMAP降维
reducer = umap.UMAP(n_components=2, n_neighbors=15, min_dist=0.1)
features_2d = reducer.fit_transform(features.numpy())6.2 对比学习表示分析
UMAP可以用于分析对比学习(如SimCLR、MoCo)学到的表示:
- 可视化特征空间的结构
- 分析正负样本的关系
- 评估表示的质量
6.3 嵌入空间分析
# 分析语言模型的嵌入空间
from transformers import AutoModel
model = AutoModel.from_pretrained('bert-base-uncased')
embeddings = model.embeddings.word_embeddings.weight.detach().numpy()
reducer = umap.UMAP(n_components=2, n_neighbors=30, min_dist=0.0)
embeddings_2d = reducer.fit_transform(embeddings)7. 理论局限与注意事项
7.1 理论基础局限
- 模糊单纯复形的构建依赖局部度量假设
- 缺乏像PCA那样的解析解
- 对超参数选择仍然敏感
7.2 实践注意事项
- 随机种子:UMAP对初始化敏感,建议固定随机种子
- 数据标准化:强烈建议先对数据进行标准化/归一化
- 距离度量选择:根据数据特点选择合适的距离度量
- 参数调优:通过实验确定最优参数
7.3 与其他方法的结合
from sklearn.decomposition import PCA
# 先PCA降维到合理维度
pca = PCA(n_components=50)
X_pca = pca.fit_transform(X)
# 再UMAP降维到2D
reducer = umap.UMAP(n_components=2, n_neighbors=15, min_dist=0.1)
X_embedded = reducer.fit_transform(X_pca)8. 参考资料
相关阅读
Footnotes
-
McInnes, L., Healy, J., & Melville, J. (2018). UMAP: Uniform Manifold Approximation and Projection for Dimension Reduction. arXiv:1802.03426. ↩