- 机器学习
- 数据可视化
【免费下载链接】umap
Uniform Manifold Approximation and Projection
UMAP(Uniform Manifold Approximation and Projection)最常见的用途之一就是降维到 2 维后进行可视化。为此,umap包内置了umap.plot工具模块(实现位于 umap/plot.py),它以极简的 API 提供散点图、大数据集渲染、交互式图表、连通性图以及多种诊断图,让开发者无需掌握 matplotlib、datashader、bokeh 的复杂细节就能快速产出高质量图表。阅读本文后,你将掌握如何用umap.plot.points绘制带标签/连续值着色的嵌入散点图,如何自动切换 datashader 渲染大规模数据,如何用 bokeh 构建带 hover 提示的交互图,以及如何用umap.plot.diagnostic从 PCA 色彩、向量量化、局部维度、邻域保持度四个角度评估嵌入质量。
环境准备与依赖
umap.plot并不属于umap的默认依赖。核心包依赖仅包含 numpy、scipy、scikit-learn、numba、pynndescent、tqdm 等(见 pyproject.toml),而绘图模块额外需要:
matplotlib:静态散点图的渲染与坐标轴控制;pandas:构建 hover 数据、组织绘图数据;datashader:大数据集栅格化渲染与边捆绑(edge bundling);bokeh:交互式图表与 hover 工具;holoviews:大数据量交互图的 datashader 后端集成;- 另外源码还会用到
colorcet与scikit-image(见 umap/plot.py)。
这些库均可用 pip 或 conda 安装。通过 pip 可以一条命令装齐全部绘图依赖:
pip install umap-learn[plot]或使用 conda:
conda install pandas matplotlib datashader bokeh holoviews colorcet scikit-image在 pyproject.toml 中,plot可选依赖还额外包含了seaborn与dask。若缺少任一绘图依赖,导入umap.plot会抛出ImportError,并在警告信息中给出上述安装提示。安装完成后即可导入:
import umap.plot准备示例数据
本文沿用官方文档的演示流程,先加载三份经典数据集:手写数字 pendigits、完整 MNIST 与 Fashion-MNIST。
import sklearn.datasets import pandas as pd import numpy as np import umap pendigits = sklearn.datasets.load_digits() mnist = sklearn.datasets.fetch_openml('mnist_784') fmnist = sklearn.datasets.fetch_openml('Fashion-MNIST')首先在 pendigits 上拟合一个标准的 UMAP 模型:
mapper = umap.UMAP().fit(pendigits.data)umap.plot系列绘图函数的核心输入就是这个训练完毕的mapper对象——它们会从mapper.embedding_中读取嵌入坐标,从mapper.metric、mapper.n_neighbors、mapper.min_dist等属性读取参数信息(见 umap/plot.py),并在图中自动加水印标注。
基础散点图:umap.plot.points
最直接的用法是把训练好的 UMAP 模型直接传给umap.plot.points:
umap.plot.points(mapper)points函数会自动根据数据密度选择点的大小,并把本次训练使用的 UMAP 参数(n_neighbors、min_dist,若使用了非标准metric还会附带 metric 名称)以水印形式标注在图上。该函数返回 matplotlib 的 axes 对象,因此你可以继续调用任意 matplotlib 函数来添加标题、轴标签等。
按类别标签着色
数据常常带有标签(来自真值、聚类或其他途径),此时只需通过labels关键字传入标签数组,umap.plot.points会自动按类别选择分类色映射着色:
umap.plot.points(mapper, labels=pendigits.target)按连续值着色
如果附加数据是连续型变量,则应使用values关键字,数据会按连续色映射着色:
umap.plot.points(mapper, values=pendigits.data.mean(axis=1), theme='fire')注意labels与values互斥,同时传入会抛出ValueError(见 umap/plot.py)。
主题(theme)与精细控制
points内置了 9 种预定义主题,每种主题统一规定了连续色映射、分类色映射、背景色与边色:
| 主题 | 连续 cmap | 分类 color_key_cmap | 背景 |
|---|---|---|---|
| fire | fire | rainbow | black |
| viridis | viridis | Spectral | black |
| inferno | inferno | Spectral | black |
| blue | Blues | tab20 | white |
| red | Reds | tab20b | white |
| green | Greens | tab20c | white |
| darkblue | darkblue | rainbow | black |
| darkred | darkred | rainbow | black |
| darkgreen | darkgreen | rainbow | black |
这些主题的实际定义可以在 umap/plot.py 中查看,其中fire、darkblue、darkgreen、darkred、darkpurple等专用色映射由colorcet生成并注册进 matplotlib(见 umap/plot.py)。指定theme会覆盖对应的cmap、color_key_cmap、background参数。
若想完全自定义,可以同时指定color_key_cmap(分类色映射)与background(背景色),例如用黑色背景配合 'Paired' 分类色映射:
umap.plot.points(mapper, labels=pendigits.target, color_key_cmap='Paired', background='black')points还支持以下参数(完整签名见 umap/plot.py):
color_key:字典(标签 →'#RRGGBB'颜色字符串)或数组(为每个类别提供一个颜色),用于精确指定类别颜色;cmap:连续色映射名,默认'Blues',无标签/值时会用于按密度着色;width/height:输出图像像素尺寸,默认 800 × 800;show_legend:是否显示图例,默认True;subset_points:布尔数组,只绘制被选中的子集点;ax:传入 matplotlib axes 对象以在既有坐标系上绘制;alpha:透明度,取值 0~1,超出范围会抛错(见 umap/plot.py)。
需要说明的是,umap.plot的目标是"简单易用",并不追求对绘图细节的全面掌控;需要精细调优的读者,官方建议直接使用 matplotlib、datashader 与 bokeh 本身。
大数据集绘制:自动切换 datashader
当数据量很大时,普通散点图容易被"过度绘制"(overplotting)欺骗:密集簇的标记层层堆叠,会让人误以为其中只有少量点。调小点大小或增加 alpha 通道只能部分缓解,无法根治。
umap.plot.points内置了自动切换逻辑(见 umap/plot.py):当点数超过width * height // 10(即每 10 个像素超过 1 个点)时,自动改用 datashader 渲染,否则使用 matplotlib。以 Fashion-MNIST 为例:
mapper = umap.UMAP().fit(fmnist.data) umap.plot.points(mapper)渲染管线由_datashade_points实现(见 umap/plot.py):先把嵌入坐标包装为 pandas DataFrame,用ds.Canvas建画布,按ds.count(密度)、ds.count_cat(按类别计数,配合color_key或color_key_cmap)或按值分桶聚合,再经tf.shade着色并设置背景。datashader 路径下 alpha 被换算为 0~255 的整数范围(见 umap/plot.py)。
所有与points相同的选项(标签、主题、值着色等)在 datashader 路径下依然生效,用户无需感知后端差异:
umap.plot.points(mapper, labels=fmnist.target, theme='fire')交互式绘图与 hover 工具
静态图之外,umap.plot还提供基于 bokeh 的交互式绘图:支持平移、缩放,以及对数据点悬停查看详细信息。
先训练一个 Fashion-MNIST 前 30000 条子集的模型:
mapper = umap.UMAP().fit(fmnist.data[:30000])hover 提示信息通过一个 DataFrame 构造:每一行对应一个数据点(顺序与嵌入一致),每一列是要在提示框中展示的字段。这里构造包含索引、目标类别号以及类别名称的 hover 数据:
hover_data = pd.DataFrame({'index': np.arange(30000), 'label': fmnist.target[:30000]}) hover_data['item'] = hover_data.label.map( { '0': 'T-shirt/top', '1': 'Trouser', '2': 'Pullover', '3': 'Dress', '4': 'Coat', '5': 'Sandal', '6': 'Shirt', '7': 'Sneaker', '8': 'Bag', '9': 'Ankle Boot', } )在 notebook 中展示 bokeh 图需要先启用 notebook 输出模式:
umap.plot.output_notebook()然后调用umap.plot.interactive,其 API 与umap.plot.points高度一致,额外支持hover_data关键字;bokeh 有多个输出目标,在 notebook 内展示还需对结果调用show:
p = umap.plot.interactive(mapper, labels=fmnist.target[:30000], hover_data=hover_data, point_size=2) umap.plot.show(p)plotting_interactive_example.html 就是官方通过 doc/plotting_example_interactive.py 生成的交互示例页面,后者展示了用umap.plot.output_file(...)输出到独立 HTML 文件的等价做法。
interactive支持与points相同的全部美学参数(主题、按标签/值着色等),并额外提供:
tools:自定义 bokeh 工具列表,默认"pan,wheel_zoom,box_zoom,save,reset,help";若列表中包含HoverTool,则不会自动生成基于hover_data的提示框(见 umap/plot.py);point_size:固定点大小,默认按数据量估算;interactive_text_search:在图上添加文本搜索框,输入关键字可高亮匹配点(匹配点 alpha 为interactive_text_search_alpha_contrast,非匹配点为1 - alpha),搜索列默认取 hover_data 各列与标签列,可通过interactive_text_search_columns指定(实现见 umap/plot.py)。
值得注意的是,当点数量超过阈值时,interactive会切换到 holoviews + datashader 渲染(见 umap/plot.py),此时 hover 提示、文本搜索与 alpha 参数不可用,函数会发出警告并建议对数据做子采样。
绘制连通性(connectivity)
UMAP 内部先构造一个近似流形的拓扑表示,实践中可简化为带权图(即mapper.graph_)。把该图叠加到嵌入坐标上,可以直观理解嵌入结果与原始连通结构的关系,也常作为诊断视图。使用umap.plot.connectivity:
umap.plot.connectivity(mapper, show_points=True)其实现(见 umap/plot.py)将mapper.graph_.tocoo()转为(source, target, weight)边表,用 datashader 的ds.Canvas画布与tf.shade渲染边;show_points=True时叠加用_datashade_points绘制的点(通过tf.stack合成),否则仅显示边。相关参数:
edge_cmap:边的色映射,默认'gray_r',主题会覆盖它;edge_bundling:边捆绑方法,支持None或'hammer'。
connectivity与points共享标签/值着色、主题、背景、宽高等参数。若启用 hammer 边捆绑:
umap.plot.connectivity(mapper, edge_bundling='hammer')hammer 边捆绑能显著减少视觉杂乱,但对大图计算代价很高(源码会在执行前发出明确警告,见 umap/plot.py),大数据集需谨慎使用。
诊断绘图:umap.plot.diagnostic
umap.plot.diagnostic提供多种嵌入质量诊断视图(见 umap/plot.py),diagnostic_type支持'pca'、'ica'、'vq'、'local_dim'、'neighborhood'以及一次输出全部子图的'all'(完整类型列表定义于 umap/plot.py)。以下以完整 MNIST 数据为例:
mapper = umap.UMAP().fit(mnist.data)PCA 全局结构诊断
diagnostic_type='pca'先用保留全局结构的 PCA 把数据降到 3 维,将 3 维坐标归一化到 0~1 后映射为 RGB 颜色,再用这些颜色给嵌入点着色,从而观察大规模全局结构在嵌入中的表现:
umap.plot.diagnostic(mapper, diagnostic_type='pca')期望看到的是颜色整体平滑过渡、布局大体尊重颜色渐变。若相邻聚类之间存在颜色"翻转"(例如某个簇上下颠倒、与邻近簇色调不连续),通常意味着优化过程中该簇曾被垂直翻转且未被纠正,提示嵌入在该区域存在全局结构失真。
向量量化(VQ)诊断
diagnostic_type='vq'用 KMeans 找到 3 个代表中心,以每个点到这三个中心的距离(归一化)作为 RGB 颜色(实现见 umap/plot.py)。与 PCA 类似,它也刻画数据的宏观全局结构:
umap.plot.diagnostic(mapper, diagnostic_type='vq')通过对比 PCA 与 VQ 两种视图,可以更可靠地判断哪些簇发生了翻转、哪些区域嵌入较好。
局部维度诊断
diagnostic_type='local_dim'估计每个点周围的局部维度:对每个点的近邻做 PCA,取累计解释方差比首次超过local_variance_threshold(默认 0.8)的维数作为局部维度估计(见 umap/plot.py)。理想情况下局部维度应接近嵌入维度;局部维度高的区域,说明该处数据本身自由度大,UMAP 在二维下更难准确表示,因此嵌入在这些区域的可靠性较低。
local_dims = umap.plot.diagnostic(mapper, diagnostic_type='local_dim')MNIST 图中左下角"数字 1"簇局部维度最低(书写方式自由度小),而中间区域局部维度较高——高维数据压缩到二维必然有妥协,这些区域的嵌入要谨慎解读。上例中该函数返回的local_dims是局部维度数组本身:diagnostic支持return_diagnostics=True(返回(ax, 诊断数据))与plot_result=False(不绘图、直接返回诊断数据),便于你拿这些数值做进一步分析。
邻域保持度诊断
diagnostic_type='neighborhood'用 Jaccard 指数衡量高维空间中每个点的局部邻域在嵌入中被保留的程度:交集大小除以两个邻域(高维与嵌入空间)的并集大小。数值越高,表示该点局部邻域保持得越准确。实现上,高维邻域取自模型内部的 kNN 搜索(_nhood_search,见 umap/plot.py,小数据用成对距离矩阵、大数据用_knn_search_index),嵌入邻域用 KDTree 查询,二者通过 numba 加速的_nhood_compare计算 Jaccard 指数(见 umap/plot.py);nhood_size参数控制邻域大小,默认 15。
umap.plot.diagnostic(mapper, diagnostic_type='neighborhood')从图上可以看到:局部维度较低的点(与上一张图对照)通常邻域保持得更好;簇边缘(边界清晰)的保持度往往高于簇中心。这张图直观标出了哪些区域可以信赖、哪些区域在压缩到二维时不得不做出妥协。
一键输出全部诊断
diagnostic_type='all'会把pca、ica、vq、local_dim、neighborhood五个子图排成网格一次性输出(见 umap/plot.py),适合快速总览嵌入质量。
辅助工具:show 与近邻距离分布
umap.plot.show(plot_to_show)统一调度显示:matplotlib axes 走plt.show(),bokeh figure 走 bokeh 的show,holoviews DynamicMap 会被渲染为 bokeh 后端后显示,无法识别的类型会抛ValueError(见 umap/plot.py);umap.plot.nearest_neighbour_distribution(mapper, bins=25)绘制每个点到其最近邻的平均距离直方图(见 umap/plot.py),可用于观察数据密度分布与 kNN 结构是否合理。
测试与验证
仓库的绘图测试位于 umap/tests/test_plot.py:在 iris 数据上训练n_epochs=100的模型后,覆盖了points(含 labels/values/subset_points/theme)、diagnostic(all 与 neighborhood)、connectivity(含 theme 与 hammer 边捆绑)、interactive(含 labels/values/subset_points/theme)以及_datashade_points的直接调用。该测试在绘图依赖缺失时会自动跳过(plot_only标记),验证了本文所述所有 API 的可用性。
小结
umap.plot以"简单易用、自动合理"为设计宗旨,把 matplotlib、datashader、bokeh、holoviews 四套后端封装进统一、精简的 API:
- 静态查看嵌入:
umap.plot.points,自动处理点大小、密度着色、标签/值着色与主题; - 大数据集:自动切换 datashader,杜绝过度绘制误导;
- 交互探索:
umap.plot.interactive+hover_data,快速获得带提示框的可缩放图表; - 结构检查:
umap.plot.connectivity,观察流形图与嵌入的对应关系; - 质量诊断:
umap.plot.diagnostic提供 PCA / ICA / VQ / 局部维度 / 邻域保持度五类视图,交叉对比即可定位嵌入中的全局翻转、高维失真区域等隐患。
需要更深层美学控制时,官方建议直接使用底层库。想要复现本文全部示例,可参考官方文档 doc/plotting.rst 与交互示例脚本 doc/plotting_example_interactive.py。
- 机器学习
- 数据可视化
【免费下载链接】umap
Uniform Manifold Approximation and Projection
相关推荐
SuperKernel 结果目录诊断与可视化:graph-autofusion 中 sk-model-analysis 工具集实战指南
SuperKernel 结果目录诊断与可视化:graph autofusion 中 sk model analysis 工具集实战指南 SuperKernel(
人工智能模型编译AscendVentoy 混合 ISO 制作完整指南:三步做出 UEFI/BIOS 双启动多系统启动盘
Ventoy 混合 ISO 制作完整指南:三步做出 UEFI/BIOS 双启动多系统启动盘 测试机上要跑 WinPE,办公机上要装 Linux,家里还想备一张
操作系统固件开发工具StatsModels回归诊断可视化完全指南
StatsModels回归诊断可视化完全指南 前言 回归分析是统计学中最常用的方法之一,但如何评估回归模型的质量和假设是否满足却是一个复杂的问题。StatsMo
数据分析数据科学科研
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考