星座图:把高维数据画成星空的那点事

那天深夜,我在翻一个基因表达的数据集,密密麻麻 2000 多个特征,盯得眼睛发酸。随手跑了个聚类,想着画个 PCA 交差——出来的散点图糊成一团,什么都没说清楚。然后同事扔给我一句:“试试星座图吧。” 我愣了一下。星座图?那玩意儿,不就是小时候天文馆里发的星座盘吗?

结果一打开文档,整个人醒了过来。

星座图(Constellation Plot)是一种将高维空间中的点投射到二维平面上,并根据邻近关系连线、构造出类似星座形状的可视化方法。 它不是新东西,90 年代就有人提了,可是在动不动就谈 t-SNE、UMAP 的今天,它像个被遗忘的老抽屉——偶然拉开,却翻出意外好用的工具。

说穿了,它就是给每个数据点找一个“最近的邻居”,画一条边,再用某种力导向或优化算法把点甩到平面上。那些连起来的枝枝桠桠,真的,一眼看过去,就像猎户座的腰带,或者大熊的尾巴——难怪叫星座图。

第一次跑出来的图,我看了十分钟

第一次跑出来的图,我看了十分钟
第一次跑出来的图,我看了十分钟

不是开玩笑。那张图上有几条清晰的“触须”,还有几个孤岛一样的小团簇。我的样本是不同病人的细胞,那些触须恰好对应了疾病进展的几个阶段。原本用热图看,根本分不出这种渐变的路子。

这就是星座图最诡异也最迷人的地方:它能保留高维流形的局部结构,而且是以一种几乎直觉的方式呈现。 PCA 只抓全局方差,很多时候把局部关系抹平了。t-SNE 倒是局部好,可那个调参过程——说实话,比哄女朋友还难。星座图却不一样。你只要选好距离度量和权重,它就把“邻居”关系老老实实画出来。那些连线不是随便画的,它们代表数据点之间真实的高维邻近。有时候你会看到一条长长的“悬臂”,那其实是一串渐变的数据,像光谱一样过渡。

不过,别高兴太早。这张图也容易骗人。

调参三小时,只为一个满意的图形

我用的 R,包是 cluster 里自带的 clara.plot,后来又翻到一个叫 Constellation 的小众包。画第一张图只花了 5 分钟,可后来为了让图“能看”,我调了整整一个下午。核心就两个参数:距离度量(Euclidean、Manhattan 还是 Cosine)邻居数量阈值(k 值)。k 太小,图会碎成一地鸡毛;k 太大,所有点都连在一起,像个毛线团。还有那个权重衰减函数——高斯核还是 t-分布?选错一个,得到的图形能让你怀疑人生。

有一回我忘了做特征标准化,图出来活像个八爪鱼炸了。这才发现,星座图对尺度极度敏感。说到底,它只是一个可视化工具,不能帮你做特征工程。得先把数据收拾干净:离群值剔除、缺失值填补、无信息变量过滤……这些脏活一样不少。

数据可视化星座图聚类分析案例
数据可视化星座图聚类分析案例

上图是我后来调好的一个版本,展示了某个电商用户分群的数据。你能看到几个明显的消费群体被不同的“星座”包裹,而那些边缘的用户像流星一样散在外面——市场部门看了直呼过瘾。

别把它当万能钥匙

有段时间我见人就推星座图,直到在一个时序数据上栽了跟头。数据是连续的时间点,星座图非但没展示出周期性,反而把因果律搅得稀烂。我琢磨了好久才明白:星座图的连线只反映相似度,不反映方向或因果。 它适合横截面、适合探索静态聚类,可一涉及到动态变化、演变轨迹,就显得力不从心了。

另外,密度高的区域,星座图会变成一坨巨大的星云,让你根本看不清内部结构。这时候也许需要交互式的工具,允许用户缩放、拖拽,或者结合其他降维方法做一个双向视图。可交互式的星座图——市面上几乎没有成品。只能用 D3.js 自己撸,那个学习曲线,啧啧。

用R语言绘制星座图代码示例
用R语言绘制星座图代码示例

如果你打算动手,我建议从 R 入手。上面这张是代码片段的截图,展示了如何加载数据、计算距离矩阵、调用 plot.constella 的过程。注意那个 linkage 参数,它决定了点是按单链接还是全链接来连边。这个小小的选择,能彻底改变图形的解读。

结尾扯个闲篇

结尾扯个闲篇
结尾扯个闲篇

前阵子我跟一个做天文数据的朋友聊天,他居然也在用星座图——不是看星星,而是给星系分类。他说,“这东西看着亲切,跟我们的星图天然像。” 我听完笑了。也许工具和人之间,是有缘分这种东西的。有些图给人冷冰冰的感觉,比如箱线图、相关系数矩阵;而星座图,不管你用它分析的是股票还是病毒,最后都变成一片可以凝视的夜空。

有空的话,翻出你手边最乱的一个数据集试试。别管什么统计显著,先画一张星座图出来。说不定,数据里藏着一个你从未注意到的星座形状。

免责声明:市场有风险,选择需谨慎!此文仅供参考,不作买卖依据。如有侵权请联系删除。
文章名称:星座图:把高维数据画成星空的那点事
文章链接:https://www.yinweisuoyi.com/a/1115.html