mcpField
U
umap-learn

umap-learn

github.com/jaechang-hits数据与数据库38467 次安装1 周前更新
代码仓库

关于 umap-learn

UMAP-Learn 是用于非线性降维的 Python 库,供数据科学和机器学习工作中进行可视化与预处理。它支持监督式嵌入、新数据转换、保留密度的 DensMAP,以及用于对齐数据集和神经网络嵌入的变体。

主要功能

  1. 01非线性降维
  2. 02监督式与半监督式嵌入
  3. 03将新数据映射到已拟合空间
  4. 04保留密度的 DensMAP
  5. 05对齐多个数据集的嵌入
  6. 06基于神经网络的 Parametric UMAP

适用场景

  1. 01将高维数据投影到 2D 或 3D
  2. 02为基于密度的聚类准备嵌入
  3. 03为机器学习工作流构造特征
  4. 04比较不同时间点或批次的嵌入

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jaechang-hits/sciagent-skills --skill umap-learn

安装后在 Claude Code 中输入/umap-learn确认已加载。

附带文件references/api_reference.md

详细介绍

UMAP-Learn

概述

UMAP(统一流形逼近与投影)是一种用于可视化和通用非线性降维的降维算法。它比 t-SNE 更快,可扩展到更大的数据集,同时保留局部和全局结构,并支持监督学习以及新数据点的嵌入。

适用场景

  • 将高维数据降至 2D/3D,以便可视化
  • 用于基于密度的聚类(HDBSCAN、DBSCAN)的预处理
  • 在 ML 工作流中进行特征工程(将新数据转换为已学习的嵌入)
  • 使用部分标签进行监督式/半监督式嵌入
  • 跟踪不同时间点或批次间的嵌入(AlignedUMAP)
  • 保持密度的嵌入(DensMAP)
  • 使用自定义架构进行基于神经网络的嵌入(Parametric UMAP)
  • 线性降维请使用 PCA(scikit-learn)
  • 不进行嵌入、仅构建邻域图时,请使用 scikit-learn NearestNeighbors

前置条件

pip install umap-learn

# For Parametric UMAP (neural network variant)
pip install umap-learn[parametric_umap]  # requires TensorFlow 2.x

重要:应用 UMAP 前务必对特征进行标准化,以确保各维度的权重相同。

快速入门

import umap
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_digits

# Load and scale data
X, y = load_digits(return_X_y=True)
X_scaled = StandardScaler().fit_transform(X)

# Fit and transform
embedding = umap.UMAP(random_state=42).fit_transform(X_scaled)
print(f"Input: {X_scaled.shape}, Output: {embedding.shape}")
# Input: (1797, 64), Output: (1797, 2)

核心 API

1. 标准 UMAP

遵循 scikit-learn 约定的基础降维。

import umap
from sklearn.preprocessing import StandardScaler

X_scaled = StandardScaler().fit_transform(data)

# Method 1: fit_transform (single step)
embedding = umap.UMAP(
    n_neighbors=15,     # local neighborhood size (2-200)
    min_dist=0.1,       # min distance between embedded points (0.0-0.99)
    n_components=2,     # output dimensions
    metric='euclidean', # distance metric
    random_state=42,    # reproducibility
).fit_transform(X_scaled)
print(f"Embedding shape: {embedding.shape}")

# Method 2: fit + access (for reuse)
reducer = umap.UMAP(random_state=42)
reducer.fit(X_scaled)
embedding = reducer.embedding_  # trained embedding
graph = reducer.graph_          # fuzzy simplicial set (sparse matrix)
# Visualization
import matplotlib.pyplot as plt

plt.figure(figsize=(8, 6))
plt.scatter(embedding[:, 0], embedding[:, 1], c=labels, cmap='Spectral', s=5)
plt.colorbar()
plt.title('UMAP Embedding')
plt.tight_layout()
plt.savefig('umap_embedding.png', dpi=150)
2. 监督式与半监督式 UMAP

通过 y 参数纳入标签信息,以引导嵌入。

import umap

# Supervised — all labels known
embedding = umap.UMAP(random_state=42).fit_transform(X_scaled, y=labels)

# Semi-supervised — partial labels (mark unlabeled as -1)
semi_labels = labels.copy()
semi_labels[unlabeled_indices] = -1
embedding = umap.UMAP(random_state=42).fit_transform(X_scaled, y=semi_labels)

# Control label influence with target_weight (0.0=unsupervised, 1.0=fully supervised)
reducer = umap.UMAP(
    target_weight=0.7,               # emphasize labels
    target_metric='categorical',     # for classification; use distance metric for regression
    random_state=42
)
embedding = reducer.fit_transform(X_scaled, y=labels)
print(f"Supervised embedding: {embedding.shape}")
3. 转换新数据

将未见过的数据投影到训练得到的嵌入空间中。

import umap
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# Fit on training data
reducer = umap.UMAP(n_components=10, random_state=42)
X_train_emb = reducer.fit_transform(X_train_scaled)

# Transform test data
X_test_emb = reducer.transform(X_test_scaled)
print(f"Train: {X_train_emb.shape}, Test: {X_test_emb.shape}")

# Works in sklearn Pipelines
from sklearn.pipeline import Pipeline
from sklearn.svm import SVC

pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('umap', umap.UMAP(n_components=10, random_state=42)),
    ('classifier', SVC())
])
pipeline.fit(X_train, y_train)
accuracy = pipeline.score(X_test, y_test)
print(f"Pipeline accuracy: {accuracy:.3f}")
4. Parametric UMAP

通过 TensorFlow/Keras 实现基于神经网络的嵌入。支持高效转换、重构和自定义架构。

from umap.parametric_umap import ParametricUMAP

# Default architecture (3-layer, 100-neuron FC network)
embedder = ParametricUMAP(n_components=2, random_state=42)
embedding = embedder.fit_transform(X_scaled)
new_emb = embedder.transform(new_data)  # fast neural network inference
print(f"Parametric embedding: {embedding.shape}")
import tensorflow as tf
from umap.parametric_umap import ParametricUMAP

# Custom encoder/decoder for autoencoder mode
input_dim = X_scaled.shape[1]
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),
])
decoder = tf.keras.Sequential([
    tf.keras.layers.InputLayer(input_shape=(2,)),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(input_dim),
])

embedder = ParametricUMAP(
    encoder=encoder, decoder=decoder, dims=(input_dim,),
    parametric_reconstruction=True, autoencoder_loss=True,
    n_training_epochs=10, batch_size=128,
    n_neighbors=15, min_dist=0.1, random_state=42
)
embedding = embedder.fit_transform(X_scaled)
reconstructed = embedder.inverse_transform(embedding)
print(f"Reconstruction error: {np.mean((X_scaled - reconstructed)**2):.4f}")
5. DensMAP

一种在嵌入中保留局部密度信息的变体。

import umap

reducer = umap.UMAP(
    densmap=True,          # enable DensMAP
    dens_lambda=2.0,       # density preservation weight
    dens_frac=0.3,         # fraction for density estimation
    output_dens=True,      # output density estimates
    n_neighbors=15,
    min_dist=0.1,
    random_state=42
)
embedding = reducer.fit_transform(X_scaled)

# Access density estimates
original_density = reducer.rad_orig_  # density in original space
embedded_density = reducer.rad_emb_   # density in embedded space
print(f"DensMAP embedding: {embedding.shape}")
print(f"Density correlation: {np.corrcoef(original_density, embedded_density)[0,1]:.3f}")
6. AlignedUMAP

对齐多个相关数据集(时间点、批次)之间的嵌入。

from umap import AlignedUMAP

# Multiple related datasets
datasets = [day1_data, day2_data, day3_data]

mapper = AlignedUMAP(
    n_neighbors=15,
    alignment_regularisation=1e-2,  # alignment strength
    alignment_window_size=2,        # align with N adjacent datasets
    n_components=2,
    random_state=42
)
mapper.fit(datasets)

aligned_embeddings = mapper.embeddings_  # list of aligned embedding arrays
print(f"Aligned {len(aligned_embeddings)} datasets")
for i, emb in enumerate(aligned_embeddings):
    print(f"  Dataset {i}: {emb.shape}")

核心概念

参数调优指南
参数低中(默认)高效果
n_neighbors2-51550-200局部细节与全局结构之间的权衡
min_dist0.00.10.5-0.99紧密聚类与分散分布之间的权衡
n_components225-50可视化与 ML/聚类之间的权衡
spread0.51.02.0嵌入尺度(与 min_dist 配合)
按使用场景配置
使用场景n_neighborsmin_distn_componentsmetric
可视化150.12euclidean
聚类(HDBSCAN)300.05-10euclidean
文本/文档嵌入150.12cosine
全局结构1000.52euclidean
ML 特征工程15-300.110-50euclidean
二元/集合数据150.12hamming/jaccard
支持的度量

闵可夫斯基族:euclidean、manhattan、chebyshev、minkowski。空间度量:canberra、braycurtis、haversine。相关性度量:cosine、correlation。二元度量:hamming、jaccard、dice、russellrao、rogerstanimoto、sokalmichener、sokalsneath、yule。特殊选项:precomputed(距离矩阵)、自定义的 Numba 编译可调用对象。

标准 UMAP 与 Parametric UMAP 对比
特性标准版参数化版
后端直接优化TensorFlow 神经网络
转换速度中等快(神经网络推理)
逆变换近似,耗时解码器网络,速度快
自定义架构否是(CNN、RNN 等)
依赖要求umap-learnumap-learn + TensorFlow 2.x
适用场景快速探索生产工作流、重构

常见工作流

工作流 1:UMAP + HDBSCAN 聚类流程
import umap
import hdbscan
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import adjusted_rand_score

# Step 1: Preprocess
X_scaled = StandardScaler().fit_transform(data)
print(f"Input shape: {X_scaled.shape}")

# Step 2: UMAP for clustering (NOT visualization parameters)
reducer = umap.UMAP(
    n_neighbors=30,     # more global structure for clustering
    min_dist=0.0,       # allow tight packing
    n_components=10,    # higher dims preserve density better than 2D
    metric='euclidean',
    random_state=42
)
embedding = reducer.fit_transform(X_scaled)

# Step 3: HDBSCAN clustering
clusterer = hdbscan.HDBSCAN(min_cluster_size=15, min_samples=5)
cluster_labels = clusterer.fit_predict(embedding)

n_clusters = len(set(cluster_labels)) - (1 if -1 in cluster_labels else 0)
noise = sum(cluster_labels == -1)
print(f"Clusters: {n_clusters}, Noise: {noise}")

# Step 4: Separate 2D embedding for visualization
vis_emb = umap.UMAP(n_neighbors=15, min_dist=0.1, random_state=42).fit_transform(X_scaled)
plt.scatter(vis_emb[:, 0], vis_emb[:, 1], c=cluster_labels, cmap='Spectral', s=5)
plt.colorbar()
plt.title(f'HDBSCAN Clusters (n={n_clusters})')
plt.tight_layout()
plt.savefig('umap_clusters.png', dpi=150)
工作流 2:用于分类的监督式嵌入
import umap
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.metrics import classification_report

# Split and scale
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
scaler = StandardScaler()
X_train_s = scaler.fit_transform(X_train)
X_test_s = scaler.transform(X_test)

# Supervised UMAP for feature engineering
reducer = umap.UMAP(n_components=10, random_state=42)
X_train_emb = reducer.fit_transform(X_train_s, y=y_train)
X_test_emb = reducer.transform(X_test_s)

# Downstream classifier
clf = SVC(kernel='rbf')
clf.fit(X_train_emb, y_train)
y_pred = clf.predict(X_test_emb)

print(classification_report(y_test, y_pred))
工作流 3:通过逆变换探索嵌入空间

仅限文本——组合核心 API 模块 1 和 3(对标准 UMAP 使用 inverse_transform):

  1. 在数据上拟合标准 UMAP(核心 API:标准 UMAP)
  2. 创建覆盖整个嵌入空间的网格点
  3. 应用 reducer.inverse_transform(grid_points) 重建高维数据
  4. 可视化重建的样本,以了解嵌入区域

注意:逆变换是近似的;在训练嵌入的凸包之外效果较差。

关键参数

参数模块默认值范围效果
n_neighborsUMAP152-200局部与全局结构的平衡
min_distUMAP0.10.0-0.99簇的紧密程度
n_componentsUMAP22-100输出维度
metricUMAP'euclidean'参见指标列表距离计算方法
spreadUMAP1.0>0嵌入尺度(与 min_dist 配合使用)
n_epochsUMAPNone (自动)50-500+训练迭代次数
learning_rateUMAP1.0>0SGD 步长
initUMAP'spectral'spectral/random/pca嵌入初始化方式
random_stateUMAPNoneint可复现性随机种子
target_weightUMAP0.50.0-1.0标签影响程度(监督式)
densmapUMAPFalsebool启用 DensMAP
dens_lambdaUMAP2.0>0DensMAP 密度权重
low_memoryUMAPTruebool节省内存模式
encoderParametricUMAPNoneKeras 模型自定义编码器网络
decoderParametricUMAPNoneKeras 模型自定义解码器网络
n_training_epochsParametricUMAP11-100神经网络训练轮数
alignment_regularisationAlignedUMAP0.01>0对齐强度
alignment_window_sizeAlignedUMAP31-N要对齐的相邻数据集数量

最佳实践

  1. 始终标准化特征:在 UMAP 前使用 StandardScaler——范围不同且未缩放的特征会主导嵌入结果。

  2. 设置 random_state 以确保可复现性:UMAP 使用随机优化;如果不固定随机种子,每次运行的结果都会不同。

  3. 针对聚类和可视化使用不同参数:聚类需要 n_neighbors=30, min_dist=0.0, n_components=5-10。可视化需要 n_neighbors=15, min_dist=0.1, n_components=2。

  4. 反模式——按字面意义解读距离:UMAP 保留的是拓扑结构,而非精确距离。嵌入中的簇间隔和点间距离与原始距离并不成正比。

  5. 反模式——使用 2D 嵌入进行聚类:2D 投影会丢失密度信息。为 HDBSCAN 输入使用 5-10 个分量。

  6. 对于超高维数据,考虑先进行 PCA 预处理:对于特征数超过 1000 的数据,先降至 50-100 个 PCA 分量,可在不损失质量的情况下加快 UMAP 运行速度。

  7. 在生产环境中使用 Parametric UMAP:如果需要快速转换新数据或具备重建能力,Parametric UMAP 的神经网络可提供稳定、快速的推理。

常用方案

方案:自定义 Numba 距离指标
from numba import njit
import umap

@njit()
def weighted_euclidean(x, y):
    """Custom distance with feature weights."""
    result = 0.0
    for i in range(x.shape[0]):
        result += (x[i] - y[i]) ** 2 * (1.0 + i * 0.01)  # increasing weight
    return np.sqrt(result)

embedding = umap.UMAP(metric=weighted_euclidean, random_state=42).fit_transform(data)
方案:预计算距离矩阵
import umap
from scipy.spatial.distance import pdist, squareform

# Compute custom distance matrix
dist_matrix = squareform(pdist(data, metric='correlation'))

# Use precomputed distances
embedding = umap.UMAP(
    metric='precomputed', random_state=42
).fit_transform(dist_matrix)
print(f"Embedding from precomputed: {embedding.shape}")
方案:度量学习流水线
import umap
from sklearn.svm import SVC

# Train supervised embedding on labeled data
mapper = umap.UMAP(n_components=10, random_state=42)
train_emb = mapper.fit_transform(X_train, y=y_train)

# Transform unlabeled test data using learned metric
test_emb = mapper.transform(X_test)

# Downstream classifier
clf = SVC().fit(train_emb, y_train)
predictions = clf.predict(test_emb)
print(f"Accuracy: {(predictions == y_test).mean():.3f}")

故障排查

问题原因解决方案
簇断开或碎片化n_neighbors 过低增大 n_neighbors(尝试 30-50)
簇过于分散min_dist 过高减小 min_dist(尝试 0.0-0.05)
所有点都挤在一起预处理不当或 min_dist 过低检查 StandardScaler;增大 min_dist
聚类效果不佳使用了可视化参数进行聚类设置 n_neighbors=30, min_dist=0.0, n_components=5-10
转换结果与训练结果不同分布偏移确保测试数据与训练数据的分布一致;使用 Parametric UMAP
大型数据集(>100k)运行缓慢默认设置设置 low_memory=True;先用 PCA 将数据预处理为 50-100 维
首次运行非常缓慢Numba JIT 编译这是预期现象——后续运行会很快(已编译并缓存)
ImportError: umap与 umap 包名称冲突pip install umap-learn(而非 pip install umap)
Parametric UMAP 导入错误缺少 TensorFlowpip install umap-learn[parametric_umap]
结果不可复现未设置 random_state始终设置 random_state=42(或任意整数)

捆绑资源

references/api_reference.md

完整的 UMAP 构造函数参数参考(60 多个参数,按类别组织:核心、训练、高级结构、监督式、转换、性能、DensMAP)、所有方法和属性、带有自动编码器参数的 ParametricUMAP 类、AlignedUMAP 类、实用函数(nearest_neighbors、fuzzy_simplicial_set)。核心参数调优指南已移至 SKILL.md 的 Key Concepts 和 Core API 模块。省略了与 SKILL.md 工作流重复的用法示例。

相关技能

  • scikit-learn-machine-learning — 用于下游任务的 ML 分类器、预处理和流水线
  • matplotlib-scientific-plotting — UMAP 嵌入的可视化
  • scikit-bio — 可通过 metric='precomputed' 输入 UMAP 的生物学距离矩阵

参考资料

  • McInnes L、Healy J、Melville J。《UMAP:用于降维的统一流形近似与投影》。arXiv:1802.03426
  • Sainburg T、McInnes L、Gentner TQ。《用于表征与半监督学习的参数化 UMAP 嵌入》。Neural Computation(2021)
  • Narayan A、Berger B、Cho H。《通过保留密度的数据可视化评估单细胞转录组变异性》。Nature Biotechnology(2021)——DensMAP
  • 官方文档:https://umap-learn.readthedocs.io/
  • GitHub:https://github.com/lmcinnes/umap

评论

支持 Markdown