TSNE-t-SNE
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 列为样本 ID,后续列为数值特征;
- 支持
none、standard、minmax三种特征预处理; - 支持
pca与random两种初始化; - 支持
euclidean与cosine两种距离度量; - 支持
learning_rate="auto"或手动数值; - 输出低维嵌入、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.py、indicators_widget.py、data_validator.py 与 core/tsne_calculator.py 的实现,模块对输入数据的真实要求如下:
- 数据不能为空;
- 至少包含两列,即第 1 列对象名称和至少 1 列特征;
- 第 1 列对象名称不能重复;
- 第 2 列及以后必须是数值型列;
- 特征列不能含空值;
- 特征列不能是常数列;
- 至少选择 1 个特征列;
perplexity必须大于 0 且小于样本数;angle必须在(0,1)内;n_components必须满足1 <= n_components <= 3;- 当
init="pca"时,还要求n_components <= 特征数; - 若
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
当前代码允许两种输入形式:
auto- 正数值
若输入 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 模型对象中读取
kl_divergence_
并记为
$$ \mathrm{KL}=D_{\mathrm{KL}} \tag{13} $$
该数值对应程序字段 kl_divergence_。
该值越小,通常表示低维嵌入对高维邻近结构的保持越好。
5.2 实际迭代轮数
项目还会读取
n_iter_
并将其记录到 Stats 表和 Parameters 表中。它表示模型实际执行的迭代次数,可用于辅助判断优化是否充分。
5.3 统计表字段
当前 Stats 工作表固定包含:
kl_divergencen_iter_perplexitylearning_rateearly_exaggerationangle
6. 代码实现细节
6.1 使用的是 sklearn.manifold.TSNE
当前模块没有自写梯度下降、动量更新或概率矩阵构造,而是直接实例化:
TSNE(n_components=..., perplexity=..., learning_rate=..., max_iter=..., init=..., metric=..., early_exaggeration=..., angle=..., random_state=...)
需要注意,界面里显示的是 n_iter,但底层传参给的是 max_iter。
6.2 Features 工作表不是预处理后的矩阵
导出的 Features 工作表保存的是
- 用户选中的原始特征列
而不是标准化或 Min-Max 之后的矩阵。真正输入 t-SNE 的预处理数据只在内存中使用,没有单独导出。
6.3 图表目录与生成条件
当前图表路径固定为结果目录下的
plots/embedding_scatter.png
但代码中的绘图逻辑默认会读取嵌入结果的第 1、2 个低维坐标,因此它在实践上假定:
- 嵌入维度至少为 2。
虽然参数校验允许 n_components=1,但当前保存图表的实现对 1 维嵌入并不稳健,报告撰写与实际使用时更建议选择 2 维或 3 维。
7. 算法流程
结合当前项目代码,TSNE-t-SNE 的实际执行流程如下:
- 读取
.xlsx、.xls或.csv文件,并校验首列样本 ID 与后续数值特征。 - 在“特征选择”页勾选参与 t-SNE 的特征列。
- 在“方法与参数”页设置
n_components、perplexity、learning_rate、n_iter、metric、init、early_exaggeration、angle、normalization与random_state。 - 对选中特征按
none、standard或minmax进行预处理。 - 调用
sklearn.manifold.TSNE.fit_transform()生成低维嵌入。 - 读取
kl_divergence_和n_iter_作为结果指标。 - 当图表保存成功时,生成
plots/embedding_scatter.png。 - 导出
tsne_results_<时间戳>.xlsx,并保存在results/TSNE-t-SNE分析结果_<时间戳>/目录下。
8. 关键参数说明
8.1 n_components
目标嵌入维度,当前界面范围为 1 到 3,默认值为 2。从当前实现稳定性和可视化用途来看,更推荐使用 2 维。
8.2 perplexity
困惑度参数,必须大于 0 且小于样本数。它控制局部邻域规模,值越大越偏向保留更大范围的邻近结构。
8.3 learning_rate
可填写 auto 或正数值。若填写 auto,底层行为完全由 sklearn 决定。
8.4 n_iter
界面中的迭代次数参数,底层会作为 max_iter 传给 TSNE。该值越大,通常越有机会降低最终 KL 散度,但计算耗时也会增加。
8.5 metric
当前支持:
euclideancosine
不同距离度量会直接影响高维邻近概率的构造。
8.6 init
当前支持:
pcarandom
若使用 pca,还要求嵌入维度不大于特征数。
8.7 early_exaggeration
早期夸大系数,代码直接传给 TSNE。该参数会影响优化前期簇间分离程度。
8.8 angle
Barnes-Hut 近似角度参数,必须位于 (0,1)。值越大通常近似越强、速度越快,但精度可能下降。
8.9 normalization
当前支持:
nonestandardminmax
由于 t-SNE 的邻近关系直接依赖预处理后的特征距离,不同预处理方式会显著影响最终可视化结构。
9. 输出结果与导出说明
9.1 Excel 工作表
根据 save_to_excel() 的实现,导出的 Excel 文件包含:
RawDataFeaturesEmbeddedStatsParametersCharts
其中 Charts 只有在散点图成功保存时才会出现。
9.2 结果文件与图表目录
当前结果目录固定形如:
results/TSNE-t-SNE分析结果_<时间戳>/
导出文件名为:
tsne_results_<时间戳>.xlsx
图表目录为:
plots/embedding_scatter.png
与部分其他模块不同,这里的图表目录名固定为 plots/,而不是带时间戳的单独文件夹名。
10. 论文写作建议
10.1 方法描述模板
“本文采用 t-SNE 方法对高维样本进行非线性降维可视化。该方法首先基于高维空间中样本间的相似性构造联合概率分布,再在低维空间中使用 Student t 分布定义样本间相似性,并通过最小化两者之间的 KL 散度获得低维嵌入。本文使用最终 KL 散度和嵌入散点图分析样本的局部结构。”
10.2 结果解释模板
结果部分可写为:Embedded 表中的 Dim1、Dim2、Dim3 是最终低维坐标。若 kl_divergence 越小,通常说明高维局部邻近结构在低维中保留得越好。需要注意的是,t-SNE 更适合解释局部邻近关系和簇分离趋势,不应过度解释全局距离和绝对坐标大小;若使用了 standard 或 minmax,则应在论文中说明 t-SNE 是基于预处理后的特征距离运行的。
10.3 图表题注模板
- 图 1 t-SNE 二维嵌入散点图。
- 表 1 t-SNE 低维嵌入结果。
- 表 2 t-SNE 参数设置与 KL 散度结果。
11. 实现说明与注意事项
- 当前模块只支持“首列样本名,后续列为数值特征”的数据格式。
perplexity必须严格小于样本数,程序不会自动调整。Features工作表保存的是原始选中特征,不是预处理后的输入矩阵。- 当前图表导出逻辑更适合
n_components>=2的情形。 - t-SNE 的坐标轴本身通常没有直接业务含义,重点应放在样本相对位置和局部聚集结构上。
12. 单篇终审补充
12.1 图题与表题对齐建议
当前 t-SNE 模块的真实工作簿包含:
RawDataFeaturesEmbeddedStatsParametersCharts(散点图成功生成时存在)
其中 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,实测工作表为:
RawDataFeaturesEmbeddedStatsParametersCharts
这里应继续区分 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。 - 正文应围绕
RawData、Features、Embedded、Stats、Parameters、Charts来写。 - 图证应对应
embedding_scatter.png,并把嵌入散点图和原始特征表分开说明。 - 复现脚本应按
repro_tsne_t_sne.py + repro_inputs/tsne_ui_input.csv的口径说明。