t-distributed Stochastic Neighbor Embedding (t-SNE)
t-SNE 将高维数据映射到 2D 或 3D 空间,同时尽量让邻近点仍保持邻近,从而显现聚类。了解其工作原理、困惑度、注意事项和代码。
t 分布随机邻域嵌入(t-SNE)是一种非线性降维方法,可将高维数据点放置在二维或三维图上,使原始空间中互为邻居的点在图上仍然彼此相邻。Laurens van der Maaten 和 Geoffrey Hinton 在《机器学习研究杂志》2008 年发表的论文中首次提出了这种方法。它是对嵌入向量、图像特征和单细胞基因表达数据进行数据可视化的标准工具;在这些数据中,数百个维度会掩盖群组,而二维散点图能将群组显示出来。
t-SNE 的工作原理#
t-SNE 会将两个空间中的距离转换为概率,然后移动图上的点,直到两组概率相匹配:
- 高维相似度:对于每个点,t-SNE 会根据该点与所有其他点的距离建立一个高斯分布,并将距离转换为选取各点作为邻居的概率。它会调整每个高斯分布的宽度,使分布的困惑度(大致相当于有效邻居数量)符合用户设定的值,因此密集区域会使用较窄的高斯分布,稀疏区域则会使用较宽的分布。
- 低维相似度:在图上,相似度由自由度为 1 的 Student t 分布决定;其厚尾使中等距离的点也能相隔较远。这缓解了拥挤问题:二维图的空间太小,无法容纳高维空间中某个点所有中等距离的邻居。
- 优化:梯度下降会移动图上的点,以最小化两个分布之间的 Kullback-Leibler 散度。早期夸大阶段会放大高维相似度;在 scikit-learn 中,放大倍数为 12,因此自然形成的簇会在早期聚集为紧密且彼此分离的群组。
精确 t-SNE 会比较每一对点,因此其计算成本会随数据集规模呈二次增长。scikit-learn 默认使用的 Barnes-Hut 近似算法,可将二维和三维图的计算复杂度降至 O(N log N);而 openTSNE 等采用 FFT 加速的实现则可处理数百万个点。
困惑度与 t-SNE 图的解读#
困惑度是最主要的设置。通常使用 5 到 50 之间的值,scikit-learn 的默认值是 30,且该值必须小于点的数量。较低的困惑度会聚焦于非常局部的结构,可能将一个群组拆成若干碎片;较高的困惑度则会融合相邻群组,并展示更多全局布局。由于优化问题是非凸的,不同随机种子可能生成不同的图。
有三个特点让 t-SNE 图很容易被误读。图上的簇大小无法说明原始簇的分布范围,因为 t-SNE 会扩展密集群组并压缩稀疏群组。簇间距离也不可靠;在较低困惑度下,随机噪声甚至可能看起来像是形成了簇。scikit-learn 的 TSNE 也没有 transform 方法,因此拟合后的图无法放入新点,除非重新计算;而 t-SNE 坐标很少被用作其他模型的输入特征。
t-SNE、PCA 与 UMAP 的比较#
主成分分析(PCA)是一种线性且确定性的方法,可保留全局方差最大的方向,并立即投影新点。t-SNE 则是非线性且随机的方法,可保留局部邻域。二者经常结合使用:运行 t-SNE 前先用 PCA 将超高维数据降至约 50 维,可以抑制噪声并加快计算;而 scikit-learn 的 t-SNE 默认从 PCA 初始化图,从而保留更多全局布局。UMAP 于 2018 年推出,同样会构建邻居图,通常在大型数据集上运行更快,往往能保留更多全局结构,还能将新点嵌入现有图中。
此示例使用两种方法将 scikit-learn 附带的 64 像素手写数字投影到二维,并测量可信度:衡量图上每个点的最近邻是否也是其在 64 维空间中的邻居。
from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
from sklearn.manifold import TSNE, trustworthiness
# 1,797 handwritten digits, each an 8x8 image flattened to 64 features
X, y = load_digits(return_X_y=True)
# Project to 2D with a linear method and with t-SNE
X_pca = PCA(n_components=2).fit_transform(X)
X_tsne = TSNE(n_components=2, perplexity=30, random_state=0).fit_transform(X)
# Trustworthiness near 1.0 means a point's 2D neighbors were also its 64D neighbors
print(f"PCA trustworthiness: {trustworthiness(X, X_pca, n_neighbors=10):.3f}")
print(f"t-SNE trustworthiness: {trustworthiness(X, X_tsne, n_neighbors=10):.3f}")脚本输出的 PCA 可信度为 0.830,t-SNE 为 0.993。将 64 个维度压缩到两个线性方向,会让许多点落在那些在 64 维空间中与它们相距很远的数字旁边;而 t-SNE 图则保留了几乎所有原有的 10 近邻关系。
实际应用#
- 检查学到的特征:投影网络特征提取的输出,可以查看视觉上相似的类别是否形成彼此分离的群组。YOLO26 模型通过
model.embed()为每张图像返回一个特征向量,默认取自倒数第二层;这些向量的 t-SNE 图能显示自定义训练模型如何区分类别。 - 数据集整理:落在其他类别图像岛中的图像通常标注有误,而聚集紧密、彼此几乎相同的点则可能是重复样本。Ultralytics Platform 中的聚类面板会将数据集的图像嵌入投影到类似的 2D 散点图中,方便进行这些检查。
- 词语和文档嵌入:词向量图会将相关词语(例如国家名称或数字)放在相邻群组中。
- 单细胞基因组学:研究人员会将每个细胞中数千个基因的表达量降至二维,以识别细胞类型。t-SNE 曾长期是这类分析的标准方法,后来许多团队转而使用 UMAP。










