t-SNE维度地图绘制笔记
文章目录示例1(一维)示例2(三维)为什么要降维如果1000维直接操作会怎样?标准定义t-SNE 是一种基于概率的流形学习技术。它通过在高维空间和低维空间中分别构建样本点的概率分布并利用梯度下降法最小化两个分布之间的 KL 散度Kullback-Leibler Divergence从而在低维空间中保留数据的局部结构特征。一句话t-SNE 是目前机器学习领域最强的高维数据可视化工具它能将复杂的数据“压扁”成一张清晰的散点图让你一眼看出数据是如何分类和聚类的。作用流程大概为1、关注“邻里关系”(1)t-SNE 并不关心所有数据点之间的绝对距离它只关心“谁是邻居”。(2)在高维空间中如果点 A 和点 B 离得很近是邻居t-SNE 会认为它们非常相似。2、计算“相似度”(1)高维空间使用高斯分布来计算两点之间的相似度概率。(2)低维空间使用t-分布自由度为1来计算两点之间的相似度概率。为什么要用 t-分布 这是一个巧妙的数学技巧。t-分布具有“长尾”特性能把高维空间中原本距离较远的点在低维空间中推得更远从而解决了“拥挤问题”让聚类结果分得更开。3、保持一致性算法的目标是让低维空间中的邻居关系尽可能与高维空间中的邻居关系一致。如果高维中 A 和 B 是好朋友但在低维图中离得很远算法就会受到“惩罚”Loss变大并不断调整位置直到两者关系匹配为止。示例1(一维)创建tsne_demo.py代码importmatplotlib.pyplotaspltfromsklearnimportdatasetsfromsklearn.manifoldimportTSNE# # 1. 加载数据 (无需联网)# print(正在加载本地手写数字数据集...)# 使用 sklearn 内置的 digits 数据集 (1797个样本, 8x8像素)digitsdatasets.load_digits()Xdigits.data ydigits.targetprint(f数据加载完成样本数量:{X.shape[0]}, 特征维度:{X.shape[1]})# # 2. t-SNE 降维# print(正在进行 t-SNE 降维 (通常只需几秒)...)# n_components2: 降到2维以便绘图# perplexity30: 困惑度控制邻域大小# initpca: 使用PCA初始化通常比随机初始化收敛更快、效果更好tsneTSNE(n_components2,perplexity30,random_state42,initpca)# fit_transform 执行降维操作X_tsnetsne.fit_transform(X)print(降维完成正在绘图...)# # 3. 可视化结果# plt.figure(figsize(10,8))# 绘制散点图# cy: 根据标签 y 的值自动分配颜色# cmaptab10: 使用包含10种颜色的色板 (对应数字0-9)scatterplt.scatter(X_tsne[:,0],X_tsne[:,1],cy,cmaptab10,s15,alpha0.6)plt.title(t-SNE Visualization of Sklearn Digits Dataset,fontsize14)plt.xlabel(Dimension 1)plt.ylabel(Dimension 2)# 添加图例显示每个颜色代表的数字plt.legend(*scatter.legend_elements(),titleDigits,locupper left)plt.colorbar(scatter,ticksrange(10))plt.tight_layout()plt.show()print(绘图完成请查看弹出的图表窗口。)运行结果如图示例2(三维)创建tsne_demo_3d.py代码importmatplotlib.pyplotaspltfrommpl_toolkits.mplot3dimportAxes3D# 必须导入这个包才能画3D图fromsklearnimportdatasetsfromsklearn.manifoldimportTSNE# # 1. 加载数据# print(正在加载数据...)digitsdatasets.load_digits()Xdigits.data ydigits.target# # 2. t-SNE 降维 (关键修改在这里)# print(正在进行 t-SNE 降维至 3D...)# 将 n_components 改为 3表示我们要得到 X, Y, Z 三个坐标tsneTSNE(n_components3,perplexity30,random_state42,initpca)X_tsnetsne.fit_transform(X)# # 3. 绘制 3D 散点图# figplt.figure(figsize(10,8))# 添加一个 3D 子图axfig.add_subplot(111,projection3d)# 绘制散点# cy: 根据标签上色# cmaptab10: 颜色映射# s20: 点的大小scatterax.scatter(X_tsne[:,0],X_tsne[:,1],X_tsne[:,2],cy,cmaptab10,s20,alpha0.6)ax.set_title(3D t-SNE Visualization of Digits,fontsize14)ax.set_xlabel(Dimension 1 (X))ax.set_ylabel(Dimension 2 (Y))ax.set_zlabel(Dimension 3 (Z))# 注意这里多了一个 Z轴标签# 添加图例plt.legend(*scatter.legend_elements(),titleDigits,locupper left)plt.show()print(绘图完成你可以用鼠标拖拽旋转查看不同角度。)运行结果如图为什么要降维如果1000维直接操作会怎样?1、速度特别慢。因为是两维两维的计算1000维需要很多次两两计算。2、在超高维空间如 1000 维中数据会变得极其稀疏。数学上有一个反直觉的现象在高维空间中任意两点之间的距离都会变得差不多最近邻和最远邻的距离差异微乎其微。后果t-SNE 依赖“距离”来判断相似度。如果所有点的距离都差不多t-SNE 就分不清谁是邻居、谁是路人。视觉效果你会得到一张杂乱无章的散点图要么是一团巨大的“毛球”要么是均匀分布的噪点完全看不出聚类结构。3、噪声干扰严重信噪比低**原因**1000 维的数据通常包含大量冗余信息或噪声比如在图像识别中背景像素可能就是噪声。**后果**t-SNE 会试图去拟合这些噪声。它可能会把一些仅仅是因为随机噪声而凑在一起的点强行聚成一类导致你看到很多虚假的聚类。你以为发现了新大陆其实只是数据的随机波动。