news 2026/9/26 21:09:42

UMAP 结果可视化与诊断:umap.plot 完整实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UMAP 结果可视化与诊断:umap.plot 完整实战指南
  • 机器学习
  • 数据可视化

【免费下载链接】umap

Uniform Manifold Approximation and Projection

项目地址:https://gitcode.com/gh_mirrors/um/umap
点击查看免费下载

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背景
firefirerainbowblack
viridisviridisSpectralblack
infernoinfernoSpectralblack
blueBluestab20white
redRedstab20bwhite
greenGreenstab20cwhite
darkbluedarkbluerainbowblack
darkreddarkredrainbowblack
darkgreendarkgreenrainbowblack

这些主题的实际定义可以在 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

项目地址:https://gitcode.com/gh_mirrors/um/umap
点击查看免费下载

相关推荐

上一篇:告别装备焦虑:TQVaultAE 让你的泰坦之旅仓库无限扩展 🎮
下一篇:终极指南:如何免费解锁Grammarly Premium高级版完整功能

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/26 21:07:52

深入了解Vibe Coding:从自然语言到可运行项目的AI编程实践

1. vibe coding 到底是什么:从一个周末原型说起大概每个程序员都有过这样的周六:早起泡了杯咖啡,脑子里突然冒出一个工具需求——把同事们散落在飞书文档里的周报自动汇总成一份 Markdown 报表,省得每周五下午手动复制黏贴。放到两…

作者头像 李华
网站建设 2026/9/26 21:06:41

百度网盘下载慢?从链路瓶颈到客户端设置,五种实测提速方法

百度网盘下载速度慢这件事,几乎成了国内互联网用户共同的“默契痛点”。很多人第一反应就是“百度在限速”,但我在实际排查中发现问题往往没那么简单——宽带、路由器、网线、客户端设置、甚至你要下载的文件本身,都可能成为真正的短板。这篇…

作者头像 李华
网站建设 2026/9/26 21:01:23

Java并发锁优化:从synchronized到CAS的演进与实战

先从一个我上个月在客户现场遇到的故障说起。一个订单接口在并发峰值时频繁超时,一堆线程卡在synchronized代码块上,CPU 飙到 90% 以上,日志里全是线程阻塞的告警。那个方法其实只做了库存校验和扣减,逻辑不长,但锁全压…

作者头像 李华
网站建设 2026/9/26 21:00:45

代码评审效率提升指南:从流程设计到自动化工具落地

聊到代码评审,我猜很多人的第一反应不是“质量保障”,而是“又来了”“拖了三天终于有人 review 了”“这评论到底在说啥”。我做过几年的研发管理和平台工具建设,也长期在一线写代码、提 MR、被 review 也 review 别人,open-code…

作者头像 李华
网站建设 2026/9/26 20:58:03

Java+uni-app音乐论坛APP源码解析:从部署到二次开发

简介:这是一份基于Android技术的音乐论坛APP完整源码项目,采用Java后端支撑,前端涵盖Vue页面与微信小程序端,适合计算机相关专业学生用于毕业设计、课程设计或课外项目实战。压缩包内共2000个文件,以vue、java、js文件…

作者头像 李华
网站建设 2026/9/26 20:55:50

垃圾分类小程序+SpringBoot后端:从功能拆解到部署上线的完整实践

垃圾分类小程序加 SpringBoot 后端,这个组合在毕业设计选题里出现的频率真的高。我见过太多人拿到这类项目之后只是把代码跑起来,复制粘贴了一篇文档,结果答辩或者面试的时候被问两句就卡壳——因为他们根本不清楚每个模块为什么这么设计&…

作者头像 李华