umap-learn について
UMAP-Learn は、可視化や前処理に使う非線形次元削減の Python ライブラリです。教師あり埋め込み、新規データの変換、密度を保つ DensMAP のほか、データセット間の整列やニューラルネットワークを使う変種を備えています。
主な機能
- 01非線形次元削減
- 02教師あり・半教師あり埋め込み
- 03学習済み空間への新規データ変換
- 04密度を保つ DensMAP
- 05データセット間の埋め込み整列
- 06ニューラルネットワーク型 Parametric UMAP
活用シーン
- 01高次元データを 2D または 3D に投影
- 02密度ベースクラスタリング用の埋め込み作成
- 03機械学習ワークフロー向けの特徴量作成
- 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(Uniform Manifold Approximation and Projection)は、可視化や一般的な非線形次元削減のための次元削減アルゴリズムです。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_neighbors | 2-5 | 15 | 50-200 | 局所的な詳細と大域構造のバランス |
min_dist | 0.0 | 0.1 | 0.5-0.99 | 密集したクラスタと広がり |
n_components | 2 | 2 | 5-50 | 可視化と ML/クラスタリング |
spread | 0.5 | 1.0 | 2.0 | 埋め込みのスケール(min_dist と併用) |
ユースケース別の設定
| ユースケース | n_neighbors | min_dist | n_components | metric |
|---|---|---|---|---|
| 可視化 | 15 | 0.1 | 2 | euclidean |
| クラスタリング(HDBSCAN) | 30 | 0.0 | 5-10 | euclidean |
| テキスト/ドキュメントの埋め込み | 15 | 0.1 | 2 | cosine |
| 大域構造 | 100 | 0.5 | 2 | euclidean |
| ML の特徴量エンジニアリング | 15-30 | 0.1 | 10-50 | euclidean |
| バイナリ/集合データ | 15 | 0.1 | 2 | hamming/jaccard |
サポートされるメトリクス
ミンコフスキー系:euclidean、manhattan、chebyshev、minkowski。空間系:canberra、braycurtis、haversine。相関系:cosine、correlation。バイナリ系:hamming、jaccard、dice、russellrao、rogerstanimoto、sokalmichener、sokalsneath、yule。特殊なメトリクス:precomputed(距離行列)、Numba でコンパイルされたカスタム呼び出し可能オブジェクト。
標準 UMAP と Parametric UMAP の比較
| 特徴 | 標準 | Parametric |
|---|---|---|
| バックエンド | 直接最適化 | TensorFlow ニューラルネットワーク |
| 変換速度 | 中程度 | 高速(ニューラルネットワークの推論) |
| 逆変換 | 近似的で、計算コストが高い | デコーダーネットワークにより高速 |
| カスタムアーキテクチャ | なし | あり(CNN、RNN など) |
| 要件 | umap-learn | umap-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:逆変換による埋め込み空間の探索
テキストのみ — Core API モジュール 1 と 3(標準 UMAP での inverse_transform)を組み合わせます。
- データに標準 UMAP を適合させます(Core API:Standard UMAP)
- 埋め込み空間をカバーするグリッド状の点を作成します
reducer.inverse_transform(grid_points)を適用し、高次元データを再構成します- 再構成したサンプルを可視化して、埋め込み領域を把握します
注:逆変換は近似的なものです。学習時の埋め込みの凸包の外側では、うまく機能しません。
主なパラメーター
| パラメーター | モジュール | デフォルト | 範囲 | 効果 |
|---|---|---|---|---|
n_neighbors | UMAP | 15 | 2-200 | 局所構造と大域構造のバランス |
min_dist | UMAP | 0.1 | 0.0-0.99 | クラスターの密集度 |
n_components | UMAP | 2 | 2-100 | 出力の次元数 |
metric | UMAP | 'euclidean' | メトリクス一覧を参照 | 距離の計算方法 |
spread | UMAP | 1.0 | >0 | 埋め込みのスケール(min_dist と併用) |
n_epochs | UMAP | None (自動) | 50-500+ | 学習の反復回数 |
learning_rate | UMAP | 1.0 | >0 | SGD のステップサイズ |
init | UMAP | 'spectral' | spectral/random/pca | 埋め込みの初期化方法 |
random_state | UMAP | None | int | 再現性を確保するシード |
target_weight | UMAP | 0.5 | 0.0-1.0 | ラベルの影響度(教師あり) |
densmap | UMAP | False | bool | DensMAP を有効にする |
dens_lambda | UMAP | 2.0 | >0 | DensMAP の密度の重み |
low_memory | UMAP | True | bool | メモリ効率モード |
encoder | ParametricUMAP | None | Keras モデル | カスタムエンコーダーネットワーク |
decoder | ParametricUMAP | None | Keras モデル | カスタムデコーダーネットワーク |
n_training_epochs | ParametricUMAP | 1 | 1-100 | ニューラルネットワークの学習エポック数 |
alignment_regularisation | AlignedUMAP | 0.01 | >0 | アライメントの強さ |
alignment_window_size | AlignedUMAP | 3 | 1-N | アライメントする隣接データセット数 |
ベストプラクティス
-
特徴量は必ず標準化します:UMAP の前に
StandardScalerを使用します。スケールが異なる特徴量を標準化しないと、埋め込みがそれらに支配されます。 -
再現性のために
random_stateを設定します:UMAP は確率的最適化を使用するため、固定シードを指定しないと実行ごとに結果が変わります。 -
クラスタリングと可視化では異なるパラメーターを使用します:クラスタリングでは
n_neighbors=30, min_dist=0.0, n_components=5-10が必要です。可視化ではn_neighbors=15, min_dist=0.1, n_components=2が必要です。 -
アンチパターン — 距離を文字どおりに解釈する:UMAP が保持するのはトポロジーであり、正確な距離ではありません。埋め込み上のクラスター間の隔たりや点間の距離は、元の距離に比例しません。
-
アンチパターン — クラスタリングに 2D 埋め込みを使用する:2D 射影では密度情報が失われます。HDBSCAN への入力には 5~10 個の成分を使用します。
-
非常に高次元のデータでは PCA による前処理を検討します:1000 個を超える特徴量を持つデータでは、まず PCA 成分を 50~100 個に減らすことで、品質を損なわずに UMAP を高速化できます。
-
本番環境では 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 コンパイル | 想定どおりです。2 回目以降は高速です(コンパイル済みキャッシュを使用) |
ImportError: umap | umap パッケージとの名前の競合 | pip install umap-learn を実行します(pip install umap ではありません) |
| Parametric UMAP のインポートエラー | TensorFlow がありません | pip 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 の「主要な概念」と「コア 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. 表現学習と半教師あり学習のための Parametric 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