mcpField
A
alterlab-umap

alterlab-umap

github.com/alterlab-ieu数据与数据库7867 次安装5 周前更新
代码仓库

关于 alterlab-umap

alterlab-umap 是介绍 UMAP 降维方法的技能,面向需要处理高维特征或嵌入数据的研究者和机器学习从业者。它涵盖可视化、聚类预处理、监督式嵌入、参数选择及新数据转换。

主要功能

  1. 01将高维数据投影到低维空间
  2. 02支持监督与半监督嵌入
  3. 03调整邻居数、距离等参数
  4. 04转换新数据并集成机器学习流水线
  5. 05支持参数化 UMAP 与逆变换

适用场景

  1. 01将特征或嵌入可视化为 2D/3D
  2. 02为 HDBSCAN 聚类降低维度
  3. 03用标签引导类别分离
  4. 04将已拟合模型用于测试数据

安装

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

$npx skills add https://github.com/alterlab-ieu/alterlab-academic-skills --skill alterlab-umap

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

附带文件evals/evals.jsonreferences/api_reference.md

详细介绍

UMAP-Learn

概述

UMAP(Uniform Manifold Approximation and Projection,统一流形近似与投影)是一种用于可视化和一般非线性降维的技术。需要快速、可扩展且能保留局部和全局结构的嵌入、监督学习和聚类预处理时,请使用此技能。

何时使用此技能

用户希望进行以下操作时,请使用此技能:

  • 将高维特征或嵌入投影到 2-D/3-D,以便可视化。
  • 在基于密度的聚类(HDBSCAN)之前进行降维。
  • 拟合监督式、半监督式、参数化或对齐的 UMAP 模型,或使用已拟合的模型转换新数据。
  • 调整 n_neighbors、min_dist、n_components 和 metric,或使嵌入具有可复现性。
不适用的场景
场景改用
单细胞工作流(在 AnnData 上执行 sc.pp.neighbors → sc.tl.umap)alterlab-scanpy
线性降维(PCA/TruncatedSVD)或通用 ML 管道及模型选择alterlab-scikit-learn
将 BERTopic 用于文档主题建模(其内部使用 UMAP)作为测量设计alterlab-text-as-data

快速入门

安装
uv pip install "umap-learn>=0.5,<0.6"   # examples target the 0.5.x API
基本用法

UMAP 遵循 scikit-learn 惯例,可直接替代 t-SNE 或 PCA。

import umap
from sklearn.preprocessing import StandardScaler

# Prepare data (put features on comparable scales)
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 之前,请对单位不同的特征进行标准化,否则距离度量会按各维度的原始尺度进行加权。若所选度量适用于原始尺度(例如,对文本或模型嵌入使用余弦距离,对二元数据使用 Jaccard 距离),则可跳过此步骤。

典型工作流
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 有四个主要参数控制嵌入行为。理解这些参数对于有效使用 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 个维度(在保持性能的同时,相比二维提升密度保留效果)
聚类工作流
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 (standalone `hdbscan` package; scikit-learn >= 1.3
#    also ships sklearn.cluster.HDBSCAN with a similar interface)
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; import as `from umap.parametric_umap import ParametricUMAP`
# (also re-exported as `umap.ParametricUMAP`)

基本用法:

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

适用场景: 在保持坐标系一致的同时,比较相关数据集之间的嵌入。

可复现性

UMAP 使用随机优化,因此每次运行的结果可能不同,除非固定随机状态:

reducer = umap.UMAP(random_state=42)

注意事项(已验证,umap-learn 0.5.x): 设置 random_state 会强制运行使用单线程——UMAP 会将 n_jobs 覆盖为 1,并发出 "n_jobs value ... overridden to 1 by setting random_state. Use no seed for parallelism."。因此,这确实需要权衡:固定随机种子可以确保结果完全可复现,但会失去默认的多核并行能力(n_jobs=-1)。处理大型数据集时,探索阶段将 random_state=None(速度快,支持并行),仅在最终归档运行时设置随机种子。若要完全复现,还应记录 umap-learn 版本,因为无法保证嵌入结果在不同版本间保持稳定。

常见问题及解决方案

问题: 连通分量断开或簇发生碎片化

  • 解决方案: 增大 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 类参数和方法

需要详细的参数信息或高级方法用法时,请加载这些参考资料。

属于 AlterLab Academic Skills 套件的一部分。

评论

支持 Markdown