正在加载中...

展开本页目录
算法教程TSNE-t-SNE

TSNE-t-SNE

No.135 · 在线教程

t-SNE(t-distributed Stochastic Neighbor Embedding)是一类经典的非线性降维与可视化方法。它的核心思想是:在高维空间中用概率分布刻画样本之间的邻近关系,再在低维空间中构造另一个概率分布,通过最小化两者之间的 KL 散度,使相近样本在…

TSNE-t-SNE

1. 方法概述

t-SNE(t-distributed Stochastic Neighbor Embedding)是一类经典的非线性降维与可视化方法。它的核心思想是:在高维空间中用概率分布刻画样本之间的邻近关系,再在低维空间中构造另一个概率分布,通过最小化两者之间的 KL 散度,使相近样本在低维中尽量靠近,同时缓解“拥挤问题”。

本项目中的 TSNE-t-SNE 模块并不是自写 t-SNE 梯度下降过程,而是对 sklearn.manifold.TSNE 的工程化封装。根据当前代码,它具有以下特点:

  1. 固定要求第 1 列为样本 ID,后续列为数值特征;
  2. 支持 nonestandardminmax 三种特征预处理;
  3. 支持 pcarandom 两种初始化;
  4. 支持 euclideancosine 两种距离度量;
  5. 支持 learning_rate="auto" 或手动数值;
  6. 输出低维嵌入、KL 散度、实际迭代轮数与散点图。

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

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

其中程序固定把第 1 列视为样本名称列,不参与 t-SNE 计算。

2. 数据要求与预处理

2.1 数据约束

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

  1. 数据不能为空;
  2. 至少包含两列,即第 1 列对象名称和至少 1 列特征;
  3. 第 1 列对象名称不能重复;
  4. 第 2 列及以后必须是数值型列;
  5. 特征列不能含空值;
  6. 特征列不能是常数列;
  7. 至少选择 1 个特征列;
  8. perplexity 必须大于 0 且小于样本数;
  9. angle 必须在 (0,1) 内;
  10. n_components 必须满足 1 <= n_components <= 3
  11. init="pca" 时,还要求 n_components <= 特征数
  12. learning_rate 为数值,则必须大于 0。

当前模块没有 label_col 选择逻辑,首列样本 ID 是固定结构的一部分。

2.2 Z-score 标准化

normalization="standard" 时,代码调用 StandardScaler() 执行

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

2.3 Min-Max 归一化

normalization="minmax" 时,代码调用 MinMaxScaler() 执行

$$ z_{ij}=\frac{x_{ij}-x_j^{\min}}{x_j^{\max}-x_j^{\min}} \tag{3} $$

normalization="none",则直接令

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

记进入 t-SNE 模型的矩阵为

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

2.4 符号说明

符号 含义
\(n\) 样本数量
\(p\) 特征维数
\(q\) 低维嵌入维数 n_components
\(z_i\) 第 \(i\) 个样本的预处理后特征向量
\(y_i\) 第 \(i\) 个样本的低维坐标
\(p_{ij}\) 高维空间邻近概率
\(q_{ij}\) 低维空间邻近概率
\(\mathrm{KL}(P\Vert Q)\) t-SNE 优化目标

3. 核心数学模型

3.1 高维邻近概率

t-SNE 会先在高维空间中基于样本间距离构造条件邻近概率。概念上可写为

$$ p_{j\mid i}= \frac{\exp\!\left(-\|z_i-z_j\|_2^2/2\sigma_i^2\right)} {\sum_{k\neq i}\exp\!\left(-\|z_i-z_k\|_2^2/2\sigma_i^2\right)} \tag{6} $$

其中 \(\sigma_i\) 由困惑度 perplexity 控制。

3.2 对称化概率

标准 t-SNE 通常把条件概率对称化为联合概率:

$$ p_{ij}=\frac{p_{j\mid i}+p_{i\mid j}}{2n} \tag{7} $$

3.3 低维学生 t 分布

在低维空间中,t-SNE 使用自由度为 1 的 Student t 分布构造相似性:

$$ q_{ij}= \frac{\left(1+\|y_i-y_j\|_2^2\right)^{-1}} {\sum_{k\neq \ell}\left(1+\|y_k-y_\ell\|_2^2\right)^{-1}} \tag{8} $$

3.4 优化目标

t-SNE 通过最小化高维概率分布与低维概率分布之间的 KL 散度完成嵌入:

$$ \mathrm{KL}(P\|Q)=\sum_{i\neq j}p_{ij}\log\frac{p_{ij}}{q_{ij}} \tag{9} $$

当前项目并不手写该优化过程,而是把参数直接传给 sklearn.manifold.TSNE 完成求解。

4. 项目中的参数口径

4.1 perplexity

代码要求

$$ 0<\texttt{perplexity}<n \tag{10} $$

其中 \(n\) 为样本数。程序不会自动修正过大的困惑度,而是直接报错。

4.2 learning_rate

当前代码允许两种输入形式:

  1. auto
  2. 正数值

若输入 auto,则原样传给 sklearn.manifold.TSNE;当前项目本身并不自行计算自动学习率公式。

4.3 n_components 与 Barnes-Hut 限制

代码明确限制

$$ 1\le q\le 3 \tag{11} $$

这是当前项目依据 t-SNE 的 Barnes-Hut 路线所做的限制。若用户输入超过 3,会直接报错。

4.4 init="pca" 的额外限制

init="pca" 时,代码还要求

$$ q\le p \tag{12} $$

否则直接报错,而不是自动退回到随机初始化。

5. 评价指标

5.1 KL 散度

拟合完成后,项目从 TSNE 模型对象中读取

  1. kl_divergence_

并记为

$$ \mathrm{KL}=D_{\mathrm{KL}} \tag{13} $$

该数值对应程序字段 kl_divergence_

该值越小,通常表示低维嵌入对高维邻近结构的保持越好。

5.2 实际迭代轮数

项目还会读取

  1. n_iter_

并将其记录到 Stats 表和 Parameters 表中。它表示模型实际执行的迭代次数,可用于辅助判断优化是否充分。

5.3 统计表字段

当前 Stats 工作表固定包含:

  1. kl_divergence
  2. n_iter_
  3. perplexity
  4. learning_rate
  5. early_exaggeration
  6. angle

6. 代码实现细节

6.1 使用的是 sklearn.manifold.TSNE

当前模块没有自写梯度下降、动量更新或概率矩阵构造,而是直接实例化:

  1. TSNE(n_components=..., perplexity=..., learning_rate=..., max_iter=..., init=..., metric=..., early_exaggeration=..., angle=..., random_state=...)

需要注意,界面里显示的是 n_iter,但底层传参给的是 max_iter

6.2 Features 工作表不是预处理后的矩阵

导出的 Features 工作表保存的是

  1. 用户选中的原始特征列

而不是标准化或 Min-Max 之后的矩阵。真正输入 t-SNE 的预处理数据只在内存中使用,没有单独导出。

6.3 图表目录与生成条件

当前图表路径固定为结果目录下的

  1. plots/embedding_scatter.png

但代码中的绘图逻辑默认会读取嵌入结果的第 1、2 个低维坐标,因此它在实践上假定:

  1. 嵌入维度至少为 2。

虽然参数校验允许 n_components=1,但当前保存图表的实现对 1 维嵌入并不稳健,报告撰写与实际使用时更建议选择 2 维或 3 维。

7. 算法流程

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

  1. 读取 .xlsx.xls.csv 文件,并校验首列样本 ID 与后续数值特征。
  2. 在“特征选择”页勾选参与 t-SNE 的特征列。
  3. 在“方法与参数”页设置 n_componentsperplexitylearning_raten_itermetricinitearly_exaggerationanglenormalizationrandom_state
  4. 对选中特征按 nonestandardminmax 进行预处理。
  5. 调用 sklearn.manifold.TSNE.fit_transform() 生成低维嵌入。
  6. 读取 kl_divergence_n_iter_ 作为结果指标。
  7. 当图表保存成功时,生成 plots/embedding_scatter.png
  8. 导出 tsne_results_<时间戳>.xlsx,并保存在 results/TSNE-t-SNE分析结果_<时间戳>/ 目录下。

8. 关键参数说明

8.1 n_components

目标嵌入维度,当前界面范围为 13,默认值为 2。从当前实现稳定性和可视化用途来看,更推荐使用 2 维。

8.2 perplexity

困惑度参数,必须大于 0 且小于样本数。它控制局部邻域规模,值越大越偏向保留更大范围的邻近结构。

8.3 learning_rate

可填写 auto 或正数值。若填写 auto,底层行为完全由 sklearn 决定。

8.4 n_iter

界面中的迭代次数参数,底层会作为 max_iter 传给 TSNE。该值越大,通常越有机会降低最终 KL 散度,但计算耗时也会增加。

8.5 metric

当前支持:

  1. euclidean
  2. cosine

不同距离度量会直接影响高维邻近概率的构造。

8.6 init

当前支持:

  1. pca
  2. random

若使用 pca,还要求嵌入维度不大于特征数。

8.7 early_exaggeration

早期夸大系数,代码直接传给 TSNE。该参数会影响优化前期簇间分离程度。

8.8 angle

Barnes-Hut 近似角度参数,必须位于 (0,1)。值越大通常近似越强、速度越快,但精度可能下降。

8.9 normalization

当前支持:

  1. none
  2. standard
  3. minmax

由于 t-SNE 的邻近关系直接依赖预处理后的特征距离,不同预处理方式会显著影响最终可视化结构。

9. 输出结果与导出说明

9.1 Excel 工作表

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

  1. RawData
  2. Features
  3. Embedded
  4. Stats
  5. Parameters
  6. Charts

其中 Charts 只有在散点图成功保存时才会出现。

9.2 结果文件与图表目录

当前结果目录固定形如:

  1. results/TSNE-t-SNE分析结果_<时间戳>/

导出文件名为:

  1. tsne_results_<时间戳>.xlsx

图表目录为:

  1. plots/embedding_scatter.png

与部分其他模块不同,这里的图表目录名固定为 plots/,而不是带时间戳的单独文件夹名。

10. 论文写作建议

10.1 方法描述模板

“本文采用 t-SNE 方法对高维样本进行非线性降维可视化。该方法首先基于高维空间中样本间的相似性构造联合概率分布,再在低维空间中使用 Student t 分布定义样本间相似性,并通过最小化两者之间的 KL 散度获得低维嵌入。本文使用最终 KL 散度和嵌入散点图分析样本的局部结构。”

10.2 结果解释模板

结果部分可写为:Embedded 表中的 Dim1Dim2Dim3 是最终低维坐标。若 kl_divergence 越小,通常说明高维局部邻近结构在低维中保留得越好。需要注意的是,t-SNE 更适合解释局部邻近关系和簇分离趋势,不应过度解释全局距离和绝对坐标大小;若使用了 standardminmax,则应在论文中说明 t-SNE 是基于预处理后的特征距离运行的。

10.3 图表题注模板

  • 图 1 t-SNE 二维嵌入散点图。
  • 表 1 t-SNE 低维嵌入结果。
  • 表 2 t-SNE 参数设置与 KL 散度结果。

11. 实现说明与注意事项

  1. 当前模块只支持“首列样本名,后续列为数值特征”的数据格式。
  2. perplexity 必须严格小于样本数,程序不会自动调整。
  3. Features 工作表保存的是原始选中特征,不是预处理后的输入矩阵。
  4. 当前图表导出逻辑更适合 n_components>=2 的情形。
  5. t-SNE 的坐标轴本身通常没有直接业务含义,重点应放在样本相对位置和局部聚集结构上。

12. 单篇终审补充

12.1 图题与表题对齐建议

当前 t-SNE 模块的真实工作簿包含:

  • RawData
  • Features
  • Embedded
  • Stats
  • Parameters
  • Charts(散点图成功生成时存在)

其中 Embedded 是正文最适合引用的核心结果表;Stats 则负责承接 kl_divergence 等结果指标。不要把 Features 误写成“预处理后矩阵”,因为当前程序内部会对特征做标准化或归一化,但 Excel 里导出的 Features 仍是原始选中特征。

图文件保存在结果目录下的 plots/ 子目录,当前真实图名为:

  • embedding_scatter.png

因此图题建议写成“t-SNE 二维嵌入散点图”。若本次运行维度大于 2,当前图仍只画前两维;若维度为 1,图表口径就不应再写成二维图。

12.2 终审说明

这篇文档最需要避免的误写,是把导出表与内部优化空间混为一谈。当前程序内部基于预处理后的矩阵拟合 t-SNE,但导出的 Features 并不是这个内部矩阵,因此论文里若讨论“预处理后距离对邻近概率的影响”,应在方法部分说明,而不要拿 Features 表直接当证据。

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

12.3 全量强化补充

本篇终审补充绑定的真实算法目录为 具体的算法3/聚类与降维/TSNE-t-SNE,本次采用的代表性结果目录为 具体的算法3/聚类与降维/TSNE-t-SNE/results/TSNE-t-SNE分析结果_20260329_171405。该目录是单轮结果目录,结构比较干净。

主结果工作簿为 具体的算法3/聚类与降维/TSNE-t-SNE/results/TSNE-t-SNE分析结果_20260329_171405/tsne_results_20260329_171405.xlsx,实测工作表为:

  • RawData
  • Features
  • Embedded
  • Stats
  • Parameters
  • Charts

这里应继续区分 Features 与内部拟合矩阵。当前工作簿里的 Features 是被选中的原始特征表,不等于内部标准化或归一化后的 t-SNE 输入空间;真正的低维结果在 Embedded 中,指标汇总在 Stats 中。

本轮真实图文件为 具体的算法3/聚类与降维/TSNE-t-SNE/results/TSNE-t-SNE分析结果_20260329_171405/plots/embedding_scatter.png。因此这一轮图证据只能写成“嵌入散点图”,不能扩写成困惑度调参曲线或 KL 历史曲线,因为程序没有导出这些图。

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

  • 具体的算法3/聚类与降维/TSNE-t-SNE/results/TSNE-t-SNE分析结果_20260329_171405/repro_tsne_t_sne.py
  • 具体的算法3/聚类与降维/TSNE-t-SNE/results/TSNE-t-SNE分析结果_20260329_171405/repro_inputs/tsne_ui_input.csv

脚本中明确写成 INPUT_FILE = 'repro_inputs/tsne_ui_input.csv',这说明该轮复现实验已切换到结果目录内部相对路径副本,而不是外部绝对路径上传文件。

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

  • 当前主结果目录应写作 具体的算法3/聚类与降维/TSNE-t-SNE/results/TSNE-t-SNE分析结果_20260329_171405
  • 正文应围绕 RawDataFeaturesEmbeddedStatsParametersCharts 来写。
  • 图证应对应 embedding_scatter.png,并把嵌入散点图和原始特征表分开说明。
  • 复现脚本应按 repro_tsne_t_sne.py + repro_inputs/tsne_ui_input.csv 的口径说明。