关于 umap-learn
umap-learn 是用于可视化和非线性降维的 Python 技能,面向数据分析与机器学习工作流。它支持监督式嵌入、聚类预处理以及新数据投影。
主要功能
- 01可视化与非线性降维
- 02监督式与半监督式嵌入
- 03聚类预处理
- 04将新数据投影至嵌入空间
- 05逆变换与对齐嵌入
适用场景
- 01将高维数据映射到低维空间以便可视化
- 02为密度聚类准备嵌入数据
- 03利用标签引导类别分离
- 04将训练好的嵌入用于新样本
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ ovachiever/ droid-tings --skill umap-learn安装后在 Claude Code 中输入/umap-learn确认已加载。
附带文件references/api_reference.md
详细介绍
UMAP-Learn
概述
UMAP(Uniform Manifold Approximation and Projection,统一流形近似与投影)是一种用于可视化和通用非线性降维的降维技术。使用此技能可快速生成可扩展的嵌入,同时保留局部和全局结构,并用于监督学习和聚类预处理。
快速开始
安装
uv pip install umap-learn
基本用法
UMAP 遵循 scikit-learn 约定,可直接替代 t-SNE 或 PCA。
import umap
from sklearn.preprocessing import StandardScaler
# Prepare data (standardization is essential)
scaled_data = StandardScaler().fit_transform(data)
# Method 1: Single step (fit and transform)
embedding = umap.UMAP().fit_transform(scaled_data)
# Method 2: Separate steps (for reusing trained model)
reducer = umap.UMAP(random_state=42)
reducer.fit(scaled_data)
embedding = reducer.embedding_ # Access the trained embedding
**关键预处理要求:**应用 UMAP 前,务必将特征标准化到相近的尺度,以确保各维度的权重相同。
典型工作流
import umap
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
# 1. Preprocess data
scaler = StandardScaler()
scaled_data = scaler.fit_transform(raw_data)
# 2. Create and fit UMAP
reducer = umap.UMAP(
n_neighbors=15,
min_dist=0.1,
n_components=2,
metric='euclidean',
random_state=42
)
embedding = reducer.fit_transform(scaled_data)
# 3. Visualize
plt.scatter(embedding[:, 0], embedding[:, 1], c=labels, cmap='Spectral', s=5)
plt.colorbar()
plt.title('UMAP Embedding')
plt.show()
参数调优指南
UMAP 有四个主要参数用于控制嵌入行为。了解这些参数对于有效使用至关重要。
n_neighbors(默认值:15)
**用途:**平衡嵌入中的局部结构与全局结构。
**工作原理:**控制 UMAP 学习流形结构时考察的局部邻域大小。
不同取值的影响:
- **低值(2-5):**突出精细的局部细节,但可能使数据碎片化为互不连通的部分
- **中值(15-20):**平衡呈现局部结构和全局关系(建议的起始值)
- **高值(50-200):**优先保留广泛的拓扑结构,但会牺牲精细细节
**建议:**从 15 开始,并根据结果进行调整。要增强全局结构就增大取值,要呈现更多局部细节就减小取值。
min_dist(默认值:0.1)
**用途:**控制点在低维空间中的聚集紧密程度。
**工作原理:**设置输出表示中各点之间允许的最小距离。
不同取值的影响:
- **低值(0.0-0.1):**生成适用于聚类的紧凑嵌入,并揭示精细的拓扑细节
- **高值(0.5-0.99):**避免点过于紧密地排列;优先保留广泛的拓扑结构,而非局部结构
**建议:**聚类应用使用 0.0,可视化使用 0.1-0.3,松散结构使用 0.5 以上。
n_components(默认值:2)
**用途:**确定嵌入输出空间的维度。
**主要特点:**与 t-SNE 不同,UMAP 能够良好地扩展到更高的嵌入维度,因此用途不限于可视化。
常见用途:
- **2-3 维:**可视化
- **5-10 维:**聚类预处理(比 2D 更好地保留密度)
- **10-50 维:**为下游 ML 模型进行特征工程
**建议:**可视化使用 2,聚类使用 5-10,ML 工作流使用更高维度。
metric(默认值:'euclidean')
**用途:**指定如何计算输入数据点之间的距离。
支持的度量方式:
- **Minkowski 变体:**euclidean、manhattan、chebyshev
- **空间度量:**canberra、braycurtis、haversine
- **相关性度量:**cosine、correlation(适用于文本/文档嵌入)
- **二元数据度量:**hamming、jaccard、dice、russellrao、kulsinski、rogerstanimoto、sokalmichener、sokalsneath、yule
- **自定义度量:**通过 Numba 定义的距离函数
**建议:**数值数据使用 euclidean,文本/文档向量使用 cosine,二元数据使用 hamming。
参数调优示例
# For visualization with emphasis on local structure
umap.UMAP(n_neighbors=15, min_dist=0.1, n_components=2, metric='euclidean')
# For clustering preprocessing
umap.UMAP(n_neighbors=30, min_dist=0.0, n_components=10, metric='euclidean')
# For document embeddings
umap.UMAP(n_neighbors=15, min_dist=0.1, n_components=2, metric='cosine')
# For preserving global structure
umap.UMAP(n_neighbors=100, min_dist=0.5, n_components=2, metric='euclidean')
监督和半监督降维
UMAP 支持将标签信息纳入嵌入过程,从而在保留内部结构的同时实现类别分离。
监督式 UMAP
拟合时通过 y 参数传入目标标签:
# Supervised dimension reduction
embedding = umap.UMAP().fit_transform(data, y=labels)
主要优势:
- 实现清晰的类别分离
- 保留每个类别的内部结构
- 维持类别之间的全局关系
**适用场景:**当你有带标签的数据,并希望分离已知类别,同时保留有意义的点嵌入时。
半监督 UMAP
对于部分有标签的数据,按照 scikit-learn 的惯例,将无标签点标记为 -1:
# Create semi-supervised labels
semi_labels = labels.copy()
semi_labels[unlabeled_indices] = -1
# Fit with partial labels
embedding = umap.UMAP().fit_transform(data, y=semi_labels)
适用场景: 标注成本高昂,或数据量超过可用标签数量时。
使用 UMAP 进行度量学习
在有标签的数据上训练监督式嵌入,然后应用于新的无标签数据:
# Train on labeled data
mapper = umap.UMAP().fit(train_data, train_labels)
# Transform unlabeled test data
test_embedding = mapper.transform(test_data)
# Use as feature engineering for downstream classifier
from sklearn.svm import SVC
clf = SVC().fit(mapper.embedding_, train_labels)
predictions = clf.predict(test_embedding)
适用场景: 在机器学习流水线中进行监督式特征工程。
使用 UMAP 进行聚类
UMAP 可作为基于密度的聚类算法(如 HDBSCAN)的有效预处理方法,克服维度灾难。
聚类最佳实践
核心原则: 聚类和可视化应采用不同的 UMAP 配置。
推荐参数:
- n_neighbors: 增至约 30(默认值 15 的局部性太强,可能产生人为的细粒度簇)
- min_dist: 设为 0.0(让簇内的点密集排列,以便更清晰地划分边界)
- n_components: 使用 5–10 个维度(在保持性能的同时,相较于 2D 可更好地保留密度)
聚类工作流
import umap
import hdbscan
from sklearn.preprocessing import StandardScaler
# 1. Preprocess data
scaled_data = StandardScaler().fit_transform(data)
# 2. UMAP with clustering-optimized parameters
reducer = umap.UMAP(
n_neighbors=30,
min_dist=0.0,
n_components=10, # Higher than 2 for better density preservation
metric='euclidean',
random_state=42
)
embedding = reducer.fit_transform(scaled_data)
# 3. Apply HDBSCAN clustering
clusterer = hdbscan.HDBSCAN(
min_cluster_size=15,
min_samples=5,
metric='euclidean'
)
labels = clusterer.fit_predict(embedding)
# 4. Evaluate
from sklearn.metrics import adjusted_rand_score
score = adjusted_rand_score(true_labels, labels)
print(f"Adjusted Rand Score: {score:.3f}")
print(f"Number of clusters: {len(set(labels)) - (1 if -1 in labels else 0)}")
print(f"Noise points: {sum(labels == -1)}")
聚类后的可视化
# Create 2D embedding for visualization (separate from clustering)
vis_reducer = umap.UMAP(n_neighbors=15, min_dist=0.1, n_components=2, random_state=42)
vis_embedding = vis_reducer.fit_transform(scaled_data)
# Plot with cluster labels
import matplotlib.pyplot as plt
plt.scatter(vis_embedding[:, 0], vis_embedding[:, 1], c=labels, cmap='Spectral', s=5)
plt.colorbar()
plt.title('UMAP Visualization with HDBSCAN Clusters')
plt.show()
重要注意事项: UMAP 无法完全保留密度,也可能产生人为的簇划分。请务必验证并探索生成的簇。
转换新数据
UMAP 可通过 transform() 方法对新数据进行预处理,使训练后的模型能够将未见过的数据投影到学习到的嵌入空间中。
基本转换用法
# Train on training data
trans = umap.UMAP(n_neighbors=15, random_state=42).fit(X_train)
# Transform test data
test_embedding = trans.transform(X_test)
与机器学习流水线集成
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import umap
# Split data
X_train, X_test, y_train, y_test = train_test_split(data, labels, test_size=0.2)
# Preprocess
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# Train UMAP
reducer = umap.UMAP(n_components=10, random_state=42)
X_train_embedded = reducer.fit_transform(X_train_scaled)
X_test_embedded = reducer.transform(X_test_scaled)
# Train classifier on embeddings
clf = SVC()
clf.fit(X_train_embedded, y_train)
accuracy = clf.score(X_test_embedded, y_test)
print(f"Test accuracy: {accuracy:.3f}")
重要注意事项
数据一致性: transform 方法假设训练数据和测试数据在高维空间中的整体分布一致。如果这一假设不成立,可考虑改用 Parametric UMAP。
性能: 转换操作效率很高(通常不到 1 秒),不过首次调用可能因 Numba JIT 编译而较慢。
Scikit-learn 兼容性: UMAP 遵循标准 sklearn 约定,可在流水线中无缝使用:
from sklearn.pipeline import Pipeline
pipeline = Pipeline([
('scaler', StandardScaler()),
('umap', umap.UMAP(n_components=10)),
('classifier', SVC())
])
pipeline.fit(X_train, y_train)
predictions = pipeline.predict(X_test)
高级功能
Parametric UMAP
Parametric UMAP 以学习得到的神经网络映射函数取代直接优化嵌入。
与标准 UMAP 的主要区别:
- 使用 TensorFlow/Keras 训练编码器网络
- 可高效转换新数据
- 支持通过解码器网络进行重构(逆变换)
- 支持自定义架构(用于图像的 CNN、用于序列的 RNN)
安装:
uv pip install umap-learn[parametric_umap]
# Requires TensorFlow 2.x
基本用法:
from umap.parametric_umap import ParametricUMAP
# Default architecture (3-layer 100-neuron fully-connected network)
embedder = ParametricUMAP()
embedding = embedder.fit_transform(data)
# Transform new data efficiently
new_embedding = embedder.transform(new_data)
自定义架构:
import tensorflow as tf
# Define custom encoder
encoder = tf.keras.Sequential([
tf.keras.layers.InputLayer(input_shape=(input_dim,)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.Dense(2) # Output dimension
])
embedder = ParametricUMAP(encoder=encoder, dims=(input_dim,))
embedding = embedder.fit_transform(data)
适用 Parametric UMAP 的场景:
- 需要在训练后高效转换新数据
- 需要重构功能(逆变换)
- 希望将 UMAP 与自编码器结合使用
- 处理可从专用架构中受益的复杂数据类型(图像、序列)
适用标准 UMAP 的场景:
- 需要简单易用并快速进行原型开发
- 数据集较小,且计算效率并非关键
- 不需要为未来数据学习转换方式
逆变换
逆变换可根据低维嵌入重构高维数据。
基本用法:
reducer = umap.UMAP()
embedding = reducer.fit_transform(data)
# Reconstruct high-dimensional data from embedding coordinates
reconstructed = reducer.inverse_transform(embedding)
重要限制:
- 计算成本高
- 在嵌入的凸包之外效果不佳
- 在簇间存在间隙的区域,准确度会下降
适用场景:
- 理解嵌入数据的结构
- 可视化簇之间的平滑过渡
- 探索数据点之间的插值
- 在嵌入空间中生成合成样本
示例:探索嵌入空间:
import numpy as np
# Create grid of points in embedding space
x = np.linspace(embedding[:, 0].min(), embedding[:, 0].max(), 10)
y = np.linspace(embedding[:, 1].min(), embedding[:, 1].max(), 10)
xx, yy = np.meshgrid(x, y)
grid_points = np.c_[xx.ravel(), yy.ravel()]
# Reconstruct samples from grid
reconstructed_samples = reducer.inverse_transform(grid_points)
AlignedUMAP
用于分析时间序列或相关数据集(例如,时间序列实验、批次数据):
from umap import AlignedUMAP
# List of related datasets
datasets = [day1_data, day2_data, day3_data]
# Create aligned embeddings
mapper = AlignedUMAP().fit(datasets)
aligned_embeddings = mapper.embeddings_ # List of embeddings
适用场景: 在保持坐标系一致的同时,比较相关数据集的嵌入。
可复现性
为确保结果可复现,请始终设置 random_state 参数:
reducer = umap.UMAP(random_state=42)
UMAP 使用随机优化,因此如果不固定随机状态,每次运行的结果都会略有差异。
常见问题和解决方案
问题: 连通分量断开或聚类分散
- 解决方案: 增大
n_neighbors,以强调更多全局结构
问题: 聚类过于分散或分离度不足
- 解决方案: 减小
min_dist,使点能够更紧密地排列
问题: 聚类效果不佳
- 解决方案: 使用针对聚类的参数(n_neighbors=30,min_dist=0.0,n_components=5-10)
问题: 转换结果与训练结果差异显著
- 解决方案: 确保测试数据的分布与训练数据一致,或使用 Parametric UMAP
问题: 大型数据集上的性能较慢
- 解决方案: 设置
low_memory=True(默认值),或考虑先使用 PCA 降维
问题: 所有点都塌缩到单个聚类中
- 解决方案: 检查数据预处理(确保缩放正确),增大
min_dist
资源
references/
包含详细的 API 文档:
api_reference.md:完整的 UMAP 类参数和方法
需要详细的参数信息或高级方法用法时,请加载这些参考资料。