正在加载中...

展开本页目录
算法教程UMAP-UMAP

UMAP-UMAP

No.137 · 在线教程

UMAP(Uniform Manifold Approximation and Projection)是一类基于流形学习与模糊拓扑图思想的非线性降维方法。它通常先在高维空间中构造局部邻域图,再把这种局部邻域结构压缩到低维空间中,从而在保持局部邻近关系的同时获得较好的全局结构表达。

UMAP-UMAP

1. 方法概述

UMAP(Uniform Manifold Approximation and Projection)是一类基于流形学习与模糊拓扑图思想的非线性降维方法。它通常先在高维空间中构造局部邻域图,再把这种局部邻域结构压缩到低维空间中,从而在保持局部邻近关系的同时获得较好的全局结构表达。

本项目中的 UMAP-UMAP 模块并不是直接封装 umap-learn 库,而是根据 UMAP 的基本思想实现了一套简化版自写流程。根据当前代码,它具有以下特点:

  1. 固定要求第 1 列为样本 ID,后续列为数值特征;
  2. 仅支持是否执行 z-score 标准化,不支持 Min-Max 归一化选项;
  3. 通过 cKDTree 构建 k 近邻图;
  4. 自行计算平滑 kNN 距离参数 rhosigma
  5. 自行构造并对称化模糊图,再做低维随机梯度优化;
  6. 输出低维嵌入、RhoSigma、KNN 边、模糊图边、嵌入参数和图表。

设共有 \(n\) 个样本、\(p\) 个被选中的特征,记原始特征矩阵为

$$ X=(x_{ij})_{n\times p},\quad i=1,2,\ldots,n,\ j=1,2,\ldots,p \tag{1} $$

其中程序固定把第 1 列视为样本名称列,不参与降维。

2. 数据要求与预处理

2.1 数据约束

根据 upload_widget.pyindicators_widget.pydata_validator.pycore/umap_calculator.py 的实现,模块对输入数据的真实要求如下:

  1. 数据不能为空;
  2. 至少包含两列,即第 1 列对象名称和至少 1 列特征;
  3. 第 1 列对象名称不能重复;
  4. 第 2 列及以后必须可转为数值;
  5. 特征列不能含空值、NaN 或无穷值;
  6. 至少选择 1 个特征列;
  7. 样本数至少为 3;
  8. n_neighbors >= 2
  9. n_components >= 1
  10. min_dist > 0
  11. spread > 0
  12. n_epochs >= 10
  13. learning_rate > 0
  14. negative_sample_rate >= 0

与部分其他模块不同,这个 UMAP 实现没有单独的 label_col 选择逻辑,也没有显式屏蔽常数列。

2.2 标准化方式

standardize=True 时,代码执行 z-score 标准化:

$$ z_{ij}=\frac{x_{ij}-\mu_j}{\sigma_j} \tag{2} $$

其中 \(\sigma_j\) 按 ddof=0 计算;若某列标准差为 0,则会被替换为 1。

standardize=False,则直接令

$$ z_{ij}=x_{ij} \tag{3} $$

记进入 UMAP 流程的矩阵为

$$ Z=(z_{ij})_{n\times p} \tag{4} $$

2.3 符号说明

符号 含义
\(n\) 样本数量
\(p\) 特征维数
\(k\) 实际邻居数
\(q\) 低维嵌入维数
\(z_i\) 第 \(i\) 个样本的预处理后特征向量
\(\rho_i\) 第 \(i\) 个样本的局部距离偏移量
\(\sigma_i\) 第 \(i\) 个样本的平滑距离尺度
\(w_{ij}\) 从 \(i\) 指向 \(j\) 的模糊邻接权重
\(y_i\) 第 \(i\) 个样本的低维嵌入坐标
\(a,b\) 低维吸引曲线参数

3. 核心数学模型

3.1 k 近邻搜索

代码先基于预处理后的矩阵 \(Z\) 构建 cKDTree,再对每个样本查询最近的 \(k+1\) 个点,其中第一个点是样本自身,随后会被去掉。因此真正参与计算的近邻数为

$$ k=\min(\texttt{n\_neighbors},\, n-1) \tag{5} $$

3.2 平滑 kNN 距离

对每个样本 \(i\),代码先取最小的正邻居距离作为

$$ \rho_i=\min\{d_{ij}: d_{ij}>0\} \tag{6} $$

再通过二分搜索找到 \(\sigma_i\),使得

$$ \sum_{j=1}^{k}\exp\!\left(-\frac{\max(d_{ij}-\rho_i,\,0)}{\sigma_i}\right)\approx \log_2(k) \tag{7} $$

这一步正对应 _smooth_knn_dist() 中的目标方程。

3.3 定向模糊图权重

在得到 \(\rho_i\) 和 \(\sigma_i\) 后,代码对每个近邻边赋予权重

$$ w_{ij}=\exp\!\left(-\frac{\max(d_{ij}-\rho_i,\,0)}{\sigma_i}\right) \tag{8} $$

这构成了一个定向的局部模糊邻域图。

3.4 图对称化

当前实现通过

$$ \tilde w_{ij}=w_{ij}+w_{ji}-w_{ij}w_{ji} \tag{9} $$

把定向图对称化。这正对应代码里的

  1. graph = graph + graph.T - graph.multiply(graph.T)

3.5 低维吸引曲线参数

代码会根据 spreadmin_dist 拟合曲线

$$ f(x)=\frac{1}{1+a x^{2b}} \tag{10} $$

并通过 curve_fit() 求出参数 \(a,b\)。若拟合失败,则直接回退到

$$ a=1,\qquad b=1 \tag{11} $$

3.6 嵌入优化

设样本 \(i\) 与 \(j\) 的低维坐标差为 \(y_i-y_j\),代码在正样本边上使用吸引更新,在负采样点上使用排斥更新。对正边,其梯度系数近似为

$$ g_{ij}^{(+)}= \frac{2ab\|y_i-y_j\|^{2(b-1)}}{1+a\|y_i-y_j\|^{2b}} \tag{12} $$

对负采样边,其排斥系数近似为

$$ g_{ik}^{(-)}= \frac{2b}{(0.001+\|y_i-y_k\|^2)\big(1+a\|y_i-y_k\|^{2b}\big)} \tag{13} $$

当前学习率还会按 epoch 线性衰减:

$$ \eta_t=\eta_0\left(1-\frac{t}{T}\right) \tag{14} $$

其中 \(T=\texttt{n\_epochs}\)。

4. 项目中的初始化与实现口径

4.1 random 初始化

init_method="random" 时,代码用均值为 0、标准差为 1e-4 的随机正态分布初始化低维坐标。

4.2 pca 初始化

init_method="pca" 时,代码不会调用外部 PCA 类,而是对中心化后的矩阵做一次 numpy.linalg.svd,并取前若干个左奇异向量乘奇异值作为初始坐标。

若请求的维数超过当前可直接得到的列数,代码会继续用很小的随机噪声补足剩余维度,而不是报错。

4.3 n_neighbors 的实际值可能被下调

虽然界面允许设置较大的 n_neighbors,但底层实际会执行:

  1. n_neighbors = min(user_n_neighbors, n_samples - 1)

因此导出参数中的 n_neighbors 可能是自动下调后的实际值

5. 评价指标

当前项目并没有像 PCA、MDS 那样输出重构误差或残差方差,而是记录图结构层面的统计量,包括:

  1. n_samples
  2. n_edges
  3. mean_weight
  4. max_weight
  5. min_weight

其中:

$$ \texttt{mean\_weight}=\frac{1}{|E|}\sum_{(i,j)\in E}\tilde w_{ij} \tag{15} $$

这里 \(E\) 表示对称化后模糊图中的边集合。

6. 代码实现细节

6.1 这不是标准 umap-learn 输出口径

当前模块没有直接使用官方 umap-learnUMAP.fit_transform(),因此:

  1. 不会输出 embedding_graph_ 等官方对象属性;
  2. 也没有官方 UMAP 的完整交叉熵损失与优化调度;
  3. 文档应明确写成“基于 UMAP 思想的简化实现”,而不是“调用标准 UMAP 库”。

6.2 raw_data 不是完整原始表

当前导出的 原始数据 工作表只包含:

  1. 第 1 列样本 ID;
  2. 被选中的特征列

而不是上传文件的全部列。

6.3 图表生成条件

当前只会在

  1. embedding.shape[1] >= 2

时生成 embedding_2d.png,因此如果降维维度设置为 1,则不会有二维散点图。

7. 算法流程

结合当前项目代码,UMAP-UMAP 的实际执行流程如下:

  1. 读取 .xlsx.xls.csv 文件,并校验首列样本 ID 与后续数值特征。
  2. 在“特征选择”页从第 2 列及以后勾选参与降维的特征列。
  3. 在“方法设置”页设置 n_neighborsn_componentsmin_distspreadn_epochslearning_ratenegative_sample_rateinit_methodstandardizerandom_state
  4. 按需执行 z-score 标准化。
  5. 基于 cKDTree 构建 k 近邻关系,并计算每个样本的 rhosigma
  6. 构造定向模糊图权重并做对称化。
  7. 拟合低维吸引曲线参数 \(a,b\),初始化嵌入坐标。
  8. 通过正边吸引和负采样排斥进行低维优化。
  9. 生成低维嵌入、RhoSigma、KNN 边表、模糊图边表和指标表。
  10. 导出 UMAP_results_<时间戳>.xlsx,并在同目录下生成 UMAP_plots_<时间戳>/ 图表目录。

8. 关键参数说明

8.1 n_neighbors

邻居数,当前要求至少为 2。该值越大,越倾向于保留更宽范围的局部结构;越小则更强调局部细节。

8.2 n_components

目标降维维度,界面范围为 150。当前实现允许高于原始特征维数的值,因为 pca 初始化不足时会用随机噪声补齐。

8.3 min_dist

最小距离参数,必须大于 0。它影响低维空间中点与点之间的最小拥挤程度。

8.4 spread

分布尺度参数,必须大于 0。它与 min_dist 一起决定低维吸引曲线的形状。

8.5 n_epochs

优化轮数,当前要求至少为 10。值越大,嵌入有更多机会稳定,但计算时间也更长。

8.6 learning_rate

初始学习率,必须大于 0,并会在训练过程中按 epoch 线性衰减。

8.7 negative_sample_rate

负采样次数,必须不小于 0。该值越大,排斥力更新越频繁,通常会拉开不同区域间的距离。

8.8 init_method

当前支持:

  1. random
  2. pca

其中 pca 实际是代码内部基于 SVD 的简化 PCA 初始化,而不是直接调用 sklearn PCA。

8.9 standardize

是否执行 z-score 标准化。由于 UMAP 的近邻搜索直接依赖样本间距离,不同量纲下通常更建议开启标准化。

9. 输出结果与导出说明

9.1 Excel 工作表

根据 save_results() 的实现,导出的 Excel 文件包含:

  1. Parameters
  2. 原始数据
  3. 处理后数据
  4. 低维嵌入
  5. RhoSigma
  6. KNN边
  7. 模糊图边
  8. 评价指标
  9. 嵌入参数
  10. Charts

其中:

  1. RhoSigma 记录每个样本的 rhosigma
  2. KNN边 记录定向 k 近邻边及距离;
  3. 模糊图边 记录对称化后的边及权重;
  4. 嵌入参数 记录低维吸引曲线参数 ab

9.2 图表目录

当前图表会保存在结果目录下的:

  1. UMAP_plots_<时间戳>/embedding_2d.png

结果文件名为:

  1. UMAP_results_<时间戳>.xlsx

10. 论文写作建议

10.1 方法描述模板

“本文采用基于 UMAP 思想的非线性降维方法对样本进行低维表示。该方法首先在高维特征空间中构建 k 近邻图,并通过平滑 kNN 距离得到局部模糊邻域关系;随后将该邻域结构映射到低维空间,并利用带负采样的优化过程获得最终嵌入。本文进一步结合模糊图权重统计和低维散点图分析样本结构。”

10.2 结果解释模板

结果部分可写为:低维嵌入 表反映样本在 UMAP 低维空间中的坐标,RhoSigma 可辅助理解各样本局部邻域的尺度差异,KNN边模糊图边 可用于说明图结构是如何构建的;同时 mean_weightmax_weightmin_weight 有助于概括模糊图连接强弱。

10.3 图表题注模板

  • 图 1 UMAP 二维嵌入散点图。
  • 表 1 UMAP 低维嵌入结果。
  • 表 2 UMAP 局部邻域参数 rho/sigma 与图结构统计结果。

11. 实现说明与注意事项

  1. 当前模块是“基于 UMAP 思想的简化实现”,不是直接调用标准 umap-learn
  2. 该实现只提供 standardize 开关,不提供 Min-Max 归一化选项。
  3. n_neighbors 在样本较少时会被自动下调到 n_samples-1
  4. 原始数据 工作表只保存样本 ID 和选中特征,不一定包含上传文件中的全部列。
  5. 若降维维度为 1,则不会生成二维嵌入图。

12. 单篇终审补充

12.1 图题与表题对齐建议

当前 UMAP 模块的真实工作簿包含:

  • Parameters
  • 原始数据
  • 处理后数据
  • 低维嵌入
  • RhoSigma
  • KNN边
  • 模糊图边
  • 评价指标
  • 嵌入参数
  • Charts

这套输出里,RhoSigmaKNN边模糊图边 是最能体现当前“基于 UMAP 思想的简化实现”特征的结果页。若论文只保留 低维嵌入 而不说明图结构构造过程,会削弱这一模块与普通降维算法的区别。

图文件保存在结果目录下的 UMAP_plots_<时间戳>/ 子目录,当前真实图名为:

  • embedding_2d.png

因此图题建议写成“UMAP 二维嵌入散点图”。若本次运行维度只有 1,则这张图不会出现,正文不应保留二维图占位描述。

12.2 终审说明

这篇文档最需要强调的,是当前实现并不是直接调用标准 umap-learn,而是项目内自行实现的简化 UMAP 过程。因此论文方法部分可以借鉴 UMAP 思想描述,但结果部分必须以当前实际导出的 RhoSigmaKNN边模糊图边嵌入参数 为准。

另外,当前 repro 脚本已经采用 repro_inputs/... 相对路径,结果目录中可见如 repro_inputs/umap_ui_input.csv 的输入引用。这篇可以按新框架口径写可复现性。

12.3 全量强化补充

本篇终审补充绑定的真实算法目录为 具体的算法3/聚类与降维/UMAP-UMAP,本次采用的代表性结果目录为 具体的算法3/聚类与降维/UMAP-UMAP/results/UMAP-UMAP分析结果_20260329_171412。该目录里同时存在两份连续时间戳工作簿和两套图目录,因此文档必须区分主结果与 repro 再生产物。

该目录下实际存在:

  • UMAP_results_20260329_171412.xlsx
  • UMAP_results_20260329_171413.xlsx
  • UMAP_plots_20260329_171412/embedding_2d.png
  • UMAP_plots_20260329_171413/embedding_2d.png

复现脚本中明确写的是 OUTPUT_FILE = 'UMAP_results_20260329_171413.xlsx',因此本篇若要绑定“主 UI 结果”,应优先指向 UMAP_results_20260329_171412.xlsx;若要说明“同目录内由 repro 脚本再生产出的结果”,则对应 UMAP_results_20260329_171413.xlsx。两者不能混写成同一次静态导出。

两份工作簿实测工作表一致,均包含:

  • Parameters
  • 原始数据
  • 处理后数据
  • 低维嵌入
  • RhoSigma
  • KNN边
  • 模糊图边
  • 评价指标
  • 嵌入参数
  • Charts

这套页名表明当前实现的辨识度不只在 低维嵌入,还在 RhoSigmaKNN边模糊图边。论文若只留下嵌入散点图,会把该实现的图结构构造证据省掉。

复现实物方面,该目录实际包含:

  • 具体的算法3/聚类与降维/UMAP-UMAP/results/UMAP-UMAP分析结果_20260329_171412/repro_umap_umap.py
  • 具体的算法3/聚类与降维/UMAP-UMAP/results/UMAP-UMAP分析结果_20260329_171412/repro_inputs/umap_ui_input.csv

脚本中明确写成 INPUT_FILE = 'repro_inputs/umap_ui_input.csv'OUTPUT_FILE = 'UMAP_results_20260329_171413.xlsx'。因此这一轮的真实口径应写成“目录内同时保留主结果和脚本再生产物”,而不是把两份 xlsx 都当成初始主结果。

11. 软件实现核查补充(2026-07)

  • 当前主结果目录应写作 具体的算法3/聚类与降维/UMAP-UMAP/results/UMAP-UMAP分析结果_20260329_171412
  • 正文应围绕 原始数据处理后数据低维嵌入RhoSigmaKNN边模糊图边评价指标嵌入参数Charts 来写。
  • 图证应围绕嵌入散点图和图结构证据展开,不要只写成普通二维降维图。
  • 复现脚本应按 repro_umap_umap.py + repro_inputs/umap_ui_input.csv 的口径说明。