跑完一次单细胞测序,或者把一万条用户行为压成向量,你会得到一张几百列的表。这类表在 AI 项目里随处可见,人眼却只能看两维,于是有人把它画成散点图:几团颜色分开的点,中间隔着空白。这张图很可能是 t-SNE 画的,而它最容易被读错的地方,恰好就是那些空白。
高维的距离,本来就搬不到纸上
维度一高,点与点之间的距离会趋于接近:随机取两个点,它们的欧氏距离几乎一样大。这意味着「谁离谁近」这个信息在高维里被稀释了,直接取前两个维度画图,看到的多半是一团糊。降维要解决的就是这件事——在低维里重新安排位置,让原本的关系尽量留下来。
难点在于二维装不下全部关系。一千个点之间的距离有几十万对,两个坐标只有两个自由度,必然要丢东西。各种降维方法的差别,本质上就是选择丢什么、保什么。
三种方法,保的东西不一样
| 方法 | 保什么结构 | 代价 | 什么时候会骗你 |
|---|---|---|---|
| PCA | 全局方差,投影后各方向上的分散程度最大 | 只做线性变换,弯曲的流形展不开,通常要先标准化 | 数据落在弯曲流形上时,两类会被压在一起 |
| t-SNE | 局部邻域,原本相近的点在图上仍然相近 | 计算慢、内存高、每次结果不同、新样本无法直接定位 | 把簇间距离、簇大小当结论时 |
| UMAP | 局部邻域为主,兼顾一部分全局拓扑 | 超参数敏感,不同参数下图形差异大 | 用它推断连续变化的方向或簇的先后顺序时 |
三种方法的共同点是都在保「近邻」,区别在对远处关系的处理:PCA 用一组直线概括全局,t-SNE 几乎放弃远处,UMAP 折中。看懂这一点,就知道为什么它们的图形不能互相印证——一张图上的两团分开,换一种方法可能就贴在一起,两种结果都不算错。
局部优先,是它的设计前提
t-SNE 的做法分两步。先在原始高维空间里,把每个点与其它点的相似度算成一个概率分布,近的点概率高;再在二维平面上随机撒点,同样算一遍相似度,然后不断挪动位置,让两个分布尽量接近。优化的目标是最小化两个分布之间的KL 散度——高维用高斯分布描述,低维用 t 分布描述,后者的长尾让中等距离的点不至于被硬拉开。
因为目标函数对「近的点被拉远」惩罚重,对「远的点被拉近」惩罚轻,结果就是局部结构保得住、全局结构随它去。这是明确的取舍:它优先回答「谁和谁是邻居」,不回答「这两群隔多远」。
簇之间的距离为什么不能读
图上两团点隔得很开,很多人会直接说「这两类差异很大」。这句话没有依据。位置是在优化过程中被推出来的,簇与簇之间的斥力只让它们不重叠,不编码原始空间里的实际距离。同一份数据换一个随机种子,两团可能挨得更近,甚至左右互换。
簇的大小同样不可读。t-SNE 倾向于把密集的区域摊开、把稀疏的区域压缩,视觉面积和样本量、密度都没有稳定对应关系。看起来最大的一团,可能只是原本分布得比较散。簇的形状、有没有明显边界,也会随参数变化,不能当成「天然分界」的证据。
困惑度一改,图就换一张
困惑度(perplexity)可以粗略理解为「每个点关心多少个邻居」,常用范围在 5 到 50 之间。设得小,图会碎成很多小块,局部细节多但整体散;设得大,块会合并,看起来结构清晰,实际上可能把不同的群揉在一起。它没有唯一正确值,只有和你数据规模匹配的值。
还有几个参数会改变观感:迭代次数不够,图还没收敛,点会挤成一团;学习率过高,会出现看起来像「岛」的假结构。所以一张图好看不等于结论可靠,判断标准是同一份数据在多组参数下是否稳定出现同样的分组。
能看结构,不能当特征
最常见的误用是把 t-SNE 的输出当成新特征,喂给下游的分类或聚类模型。它的坐标没有可重复的含义:换一次运行,同一个点的坐标就变了,模型学到的是一组随机数。需要降维后建模,PCA 或自编码器这类有确定映射的方法更合适。
它也不能给新样本定位。t-SNE 没有学到一个从高维到低维的函数,新来的点只能把全量数据重跑一遍,图会整体变形,和历史结果无法对齐。这一点在需要持续更新的场景里是硬伤,UMAP 在这方面稍好,但也不是严格的可增量映射。
别在 t-SNE 图上直接跑K-means,得到的簇看起来漂亮,实际是在二维投影上分的,和原始空间的簇不是一回事。要聚类就在原始特征上做,图只用来观察。
怎么用它才不算白看
把它放在探索阶段,位置在「形成假设」而不是「验证假设」。先看有没有明显的分群,再用原始特征做统计检验或聚类,确认这个分群是真的。分组如果对应某个已知标签,把标签上色叠上去看是否吻合,比盯着图猜有用。
跑的时候至少做三件事:换三个随机种子,看分组是否稳定;换两三个困惑度,看结构是否还在;先用 PCA 降到 50 维左右再喂给 t-SNE,既降噪也提速。三步都过,图上的结构才值得往下追。
速查:t-SNE 的读图规则
- 只看有没有分群,不看簇间距离
- 簇的大小、形状、边界都不代表原始密度
- 换种子、换困惑度各跑几遍,结构稳定才算数
- 不要拿降维结果当特征喂模型
- 聚类回原始空间做,图上不下结论


