当前位置: 首页 > news >正文

当散点图不够用时:用 t-SNE 可视化多维数据

从散点图的局限说起

在数据分析的工作中,我们经常会遇到这样一个问题:如何把数据的“样子”展示给别人看?

如果数据只有两个维度,事情很简单——画一张散点图就好了。

横轴一个变量,纵轴一个变量,每个点代表一条数据,分布一目了然。

如果数据有三个维度呢?也还行——散点图加上颜色,用不同颜色代表第三个维度的取值。

比如用散点图展示城市的人口、GDP和面积,点的颜色深浅表示面积大小。

如果数据有四个维度呢?可以再加一个点的大小(半径),用点的大小表示第四个维度。

比如散点图展示学生的学习时间、考试成绩、出勤率和作业完成度——横轴是学习时间,纵轴是考试成绩,颜色表示出勤率,点的大小表示作业完成度。

那五个维度呢?六个呢?十个呢?

散点图到此为止了。当数据的维度超过4个,传统的散点图就再也无能为力了。我们无法在二维平面上用有限的视觉通道(位置、颜色、大小、形状)去表达十几个甚至上百个维度的信息。

但现实世界中的数据,往往就是高维的。一份用户画像可能有几十个特征,一篇文档的向量表示可能有几百维,一张图片经过神经网络提取特征后可能有上千维。这些数据里藏着丰富的结构和模式,但我们看不见。

直到我看到了t-SNE

什么是 t-SNE?

t-SNEt-Distributed Stochastic Neighbor Embeddingt-分布随机邻域嵌入)是一种非线性降维技术,它的目标是把高维空间中的数据点映射到二维或三维空间,同时尽可能保留高维空间中数据点之间的局部邻域关系

说人话就是:在高维空间中离得近的点,在 t-SNE 图上也会离得近;在高维空间中离得远的点,在 t-SNE 图上也会离得远。

t-SNE的核心思想是概率的——它把数据点之间的相似度转化为概率分布,然后在低维空间中寻找一个分布,使得这两个分布尽可能接近。

它不需要预先指定簇的数量,能够自动揭示数据中潜在的聚类结构。

t-SNE 的优点

  • 擅长展示聚类效果:t-SNE 能够很好地将数据中的自然分组在二维平面上呈现出来。
  • 保留局部结构:在高维空间中相近的数据点在低维空间中仍然会靠在一起。
  • 无需预先定义簇数量:不像 K-Means 等聚类算法需要指定分成几类。

t-SNE 的缺点(⚠️ 重要!)

  • 计算成本高:尤其是在处理大型数据集时,t-SNE 的运行时间可能很长。
  • 结果不稳定:不同次运行可能得到不同的结果。
  • 坐标轴不可解释:t-SNE 的两个轴不代表任何原始特征的逻辑组合,不像 PCA 的主成分那样可以解释含义。
  • 参数敏感:困惑度(perplexity)等参数的选择会显著影响结果。
  • 可能产生误导:t-SNE 有时会夸大簇的大小差异,或者把本不相关的点凑到一起。

尤其需要注意的是,t-SNE 的全局距离(不同簇之间的距离)是没有意义的。

它擅长展示“谁和谁是一伙的”,但不擅长展示“这两个群体之间到底有多远”。

什么时候用 t-SNE?

t-SNE最适合的场景是:你想探索高维数据中是否存在自然的聚类结构

典型的使用场景包括:

  • 文本数据的可视化:将文档的向量表示(Embedding)降维到二维,观察不同主题的文档是否自然聚在一起。
  • 图像数据的可视化:将图片的特征向量降维,观察不同类别的图片在空间中的分布。
  • 用户行为分析:将用户的多维行为特征降维,识别不同的用户群体。
  • 模型输出的解释:可视化深度学习模型中间层的特征表示,帮助理解模型学到了什么。

动手实践:两个生活案例

光说不练假把式。接下来我们用两个贴近生活的例子,看看t-SNE到底怎么用。

案例一:葡萄酒品鉴数据可视化

假设你是一个葡萄酒爱好者,收集了 200 款红葡萄酒的 13 个特征数据(酒精含量、苹果酸含量、灰分含量、镁含量、总酚含量等)。

你想看看这些葡萄酒是否可以按照产地自然地分成几类。

这个数据集是scikit-learn这个机器学习库中自带的。

import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.datasets import load_wine from sklearn.manifold import TSNE from sklearn.preprocessing import StandardScaler # 加载葡萄酒数据集(13个特征,3个产地类别) wine = load_wine() X = wine.data # 13个特征 y = wine.target # 产地标签(0, 1, 2) # 标准化数据(t-SNE 对尺度敏感) X_scaled = StandardScaler().fit_transform(X) # 使用 t-SNE 降维到 2 维 tsne = TSNE(n_components=2, perplexity=30, random_state=42, max_iter=1000) X_tsne = tsne.fit_transform(X_scaled) # 可视化 plt.figure(figsize=(10, 8)) colors = ['red', 'green', 'blue'] for i, label in enumerate(np.unique(y)): mask = y == label plt.scatter(X_tsne[mask, 0], X_tsne[mask, 1], c=colors[i], label=f'产地 {i}', alpha=0.7, s=60) plt.title('t-SNE 可视化:葡萄酒按产地聚类', fontsize=14) plt.xlabel('t-SNE 维度 1') plt.ylabel('t-SNE 维度 2') plt.legend() plt.show()

运行这段代码,你会看到不同产地的葡萄酒在二维平面上自然地分成了几个簇。

原本 13 个维度的数据,现在可以直观地看到聚类结构——这就是t-SNE的魔力。

案例二:电影推荐系统中的用户画像

假设你有一个电影推荐系统,收集了 500 个用户的观影偏好数据。每个用户有 20 个特征:对不同类型电影(动作、喜剧、科幻、爱情、恐怖、纪录片等)的偏好程度。

你想看看这些用户是否可以自然地分成不同的“观影人群”,以便做更精准的推荐。

import numpy as np import matplotlib.pyplot as plt from sklearn.manifold import TSNE from sklearn.cluster import KMeans from sklearn.preprocessing import StandardScaler # 模拟数据:500个用户,20个电影类型偏好特征 np.random.seed(42) n_users = 500 n_features = 20 # 生成模拟数据:假设存在4种不同的用户类型 X = np.random.randn(n_users, n_features) # 为不同用户类型添加不同的偏好模式 # 类型0:喜欢动作和科幻 X[:125, 0:5] += 2.0 # 类型1:喜欢爱情和喜剧 X[125:250, 5:10] += 2.0 # 类型2:喜欢恐怖和悬疑 X[250:375, 10:15] += 2.0 # 类型3:喜欢纪录片和历史 X[375:500, 15:20] += 2.0 # 标准化 X_scaled = StandardScaler().fit_transform(X) # 先用 K-Means 聚类(这里只是为了给点打标签做可视化) kmeans = KMeans(n_clusters=4, random_state=42) labels = kmeans.fit_predict(X_scaled) # t-SNE 降维 tsne = TSNE(n_components=2, perplexity=30, random_state=42, max_iter=1000) X_tsne = tsne.fit_transform(X_scaled) # 可视化 plt.figure(figsize=(10, 8)) scatter = plt.scatter(X_tsne[:, 0], X_tsne[:, 1], c=labels, cmap='viridis', alpha=0.6, s=50) plt.colorbar(scatter, label='用户类型') plt.title('t-SNE 可视化:电影用户聚类', fontsize=14) plt.xlabel('t-SNE 维度 1') plt.ylabel('t-SNE 维度 2') plt.show()

在这个例子中,t-SNE 帮助我们直观地看到了 500 个用户在偏好空间中的分布——哪些用户是“动作片爱好者”,哪些是“爱情片爱好者”,一目了然。

一个完整的代码模板

如果你想把 t-SNE 应用到自己的数据上,下面这个模板可以直接套用:

import numpy as np import matplotlib.pyplot as plt from sklearn.manifold import TSNE from sklearn.preprocessing import StandardScaler # 1. 准备数据 # X 是你的高维数据,形状为 (n_samples, n_features) # labels 是每个样本的类别标签(可选,用于着色) # X = ... # 2. 标准化(重要!) X_scaled = StandardScaler().fit_transform(X) # 3. t-SNE 降维 tsne = TSNE( n_components=2, # 降维到2维 perplexity=30, # 困惑度,通常 5-50 random_state=42, # 固定随机种子,保证结果可复现 max_iter=1000 # 迭代次数,确保收敛 ) X_tsne = tsne.fit_transform(X_scaled) # 4. 可视化 plt.figure(figsize=(10, 8)) if labels is not None: scatter = plt.scatter(X_tsne[:, 0], X_tsne[:, 1], c=labels, cmap='tab10', alpha=0.6, s=50) plt.colorbar(scatter) else: plt.scatter(X_tsne[:, 0], X_tsne[:, 1], alpha=0.6, s=50) plt.title('t-SNE Visualization') plt.xlabel('t-SNE dimension 1') plt.ylabel('t-SNE dimension 2') plt.show()

http://www.jsqmd.com/news/1237496/

相关文章:

  • 51单片机串口通信
  • 异构联盟链跨链互通的工程实现:从中继架构到接入连接器
  • 企业知识库RAG实战:用向量数据库构建精准语义检索系统
  • XXL-JOB分布式任务调度平台核心原理与实践指南
  • MCP Server:AI Agent安全高效调用业务API的标准化方案
  • Java面试突击:从八股文背诵到构建最小知识体系与问题拆解框架
  • 跨系统查数据要2天?企业AI落地的核心病根,藏在看不见的语义
  • 广州电商公司税务合规怎么做?2026电商行业合规管理与机构选型攻略 - 米諾
  • Qt的概述
  • YOLOv13涨点改进| CVPR 2026 | 独家Conv与频域改进篇| 引入SSFModule选择性空间频率模块,助力无人机航拍、遥感影像、小目标检测、语义分割、实例分割、目标跟踪任务,有效涨点
  • 郴州甲醛检测公司怎么选:只做检测不除醛的专业CMA资质实验室——国慷测研CMA甲醛检测及公共卫生检测 - CMA甲醛检测中心
  • 2026山西企业获客复盘:为什么传统SEO失效,GEO优化成主流? - 米諾
  • ElevenLabs语音合成API实战踩坑与优化指南
  • SpringBoot进阶实战:从原理到生产级应用与面试突破
  • SlowHTTPTest终极指南:如何用免费工具发现并防御慢速HTTP攻击漏洞
  • Claude Code与DeepSeek API一键安装配置指南
  • 石家庄平山县亨得利官方名表服务中心电话公示(2026年7月最新) - 亨得利官方
  • AI伦理三脚架:原则、流程与工具的落地断层解析
  • 双轴晶体的圆锥折射
  • 宁波GEO找哪家比较好?2026本地靠谱推荐与服务商分级选型指南 - 小随科技
  • Kimi K3大模型集成实战:从API接入到生产环境部署
  • LED显示屏驱动技术解析与工程实践
  • 宣城GEO找哪家比较好?2026本地靠谱推荐与服务商分级选型实战指南 - 企业新闻快传
  • 2026仲夏桐梓黄金回收全维度拆解|老牌三十年连锁盘价结算全县乡镇免费上门卖金防坑实操手册 - 华金汇黄金回收
  • 2026苏州房屋漏水维修靠谱机构TOP4:精准治漏长效保障 专业防水公司排名推荐(2026年7月防水补漏最新TOP权威排名) - 鼎万建筑修缮
  • AI 电动加热围巾智能温控功率 MOSFET 完整选型方案
  • GESP四级C++客观题实战解析:从指针内存到STL容器的解题思维
  • 3个简单步骤,用Qwerty Learner打造你的英语打字肌肉记忆训练系统
  • HarmonyOS 6.1 实战:Swiper 轮播图与页面滑动详解
  • HarmonyOS API 23 ArkTS 实战:实现一个轻量级滤镜图片预览工具