【归纳总结】如何利用t-SNE可视化高维数据样本?附Python代码

一、t-SNE是什么?

t-SNE(t-Distributed Stochastic Neighbor Embedding)是一种非线性降维和可视化技术,用于将高维数据映射到低维空间,以便更好地理解和分析数据,在机器学习和数据可视化领域被广泛使用。t-SNE的主要思想是在高维空间中保持样本之间的局部关系,即相似的样本在低维空间中也应该保持相似。它通过学习一个映射函数,将样本从高维空间映射到低维空间,使得在低维空间中的样本间的距离尽可能地反映在高维空间中的相似性。这样,通过将高维数据映射到二维或三维空间,我们可以可视化数据并发现其中的结构、聚类和异常值等特征。

t-SNE的优点包括能够保留数据中的局部结构,并且在可视化复杂数据时表现良好。然而,它也有一些注意事项。t-SNE是一个计算密集型算法,对于大规模数据集可能需要较长的计算时间。此外,t-SNE的结果可能受到不同的超参数选择的影响,因此需要根据具体情况进行调整和解释。总之,t-SNE是一种有力的工具,可用于将高维数据降维到可视化友好的低维空间,帮助我们理解数据的结构和关系。

二、使用步骤

要使用Python绘制多类样本的t-SNE(t-Distributed Stochastic Neighbor Embedding)可视化图,可以使用scikit-learn库中的TSNE类。以下是一个简单的示例代码,演示了如何使用t-SNE对多类样本进行降维和可视化:

代码如下(示例):

import numpy as np
import matplotlib.pyplot as plt
from sklearn.manifold import TSNE

# 加载自己的数据集和标签
# X = np.load('your_data.npy')  # 替换为你的数据集路径
# labels = np.load('your_labels.npy')  # 替换为你的标签路径

# 定义三个类别的均值和协方差矩阵
mean1 = [0, 1]
cov1 = [[1, 0.3], [0.3, 1]]
mean2 = [3, 3]
cov2 = [[1, -0.2], [-0.2, 3]]
mean3 = [-10, 10]
cov3 = [[1, 0], [0, 0.5]]
mean4 = [-4, 2]
cov4 = [[0.5, 0.2], [0.2, 2]]

# 生成三个类别的样本数据
data1 = np.random.multivariate_normal(mean1, cov1, 100)
data2 = np.random.multivariate_normal(mean2, cov2, 100)
data3 = np.random.multivariate_normal(mean3, cov3, 100)
data4 = np.random.multivariate_normal(mean4, cov4, 100)

# 生成三个类别的样本数据的标签
label1 = np.zeros(data1.shape[0]) + 0
label2 = np.zeros(data1.shape[0]) + 1
label3 = np.zeros(data1.shape[0]) + 2
label4 = np.zeros(data1.shape[0]) + 3

# 将三个类别的数据合并
data = np.concatenate((data1, data2, data3, data4))
labels = np.concatenate((label1, label2, label3, label4))
print(data.shape, labels.shape)

# 使用t-SNE进行降维
tsne = TSNE(n_components=2, random_state=42)
X_tsne = tsne.fit_transform(data)

# 归一化
x_min, x_max = X_tsne.min(0), X_tsne.max(0)
X_norm = (X_tsne - x_min) / (x_max - x_min)

# 绘制t-SNE可视化图
plt.figure(figsize=(10, 8))
plt.rcParams['font.sans-serif'] = ['Times New Roman']  # 图中文字体设置为Times New Roman

shape_list = ['o', 'D', '^', 'P']  # 设置不同类别的形状
color_list = ['r', 'g', 'b', 'm']  # 设置不同类别的颜色
label_list = ['Class 1', 'Class 2', 'Class 3', 'Class 4']
# 遍历所有标签种类
for i in range(len(np.unique(labels))):
    plt.scatter(X_norm[labels == i, 0], X_norm[labels == i, 1], color=color_list[i],
                marker=shape_list[i], s=150, label=label_list[i], alpha=0.5)   # 绘制散点图,s=150表示形状大小, alpha=0.5表示图形透明度(越小越透明)

# # 遍历所有样本
# color_map = {0:'r', 1:'g', 2:'b', 3:'m'}   # 定义类别颜色映射关系
# shape_map = {0:'o', 1:'D', 2:'^', 3:'P'}
# label_map = {0:'Class 1', 1:'Class 2', 2:'Class 3', 3:'Class 4'}
# for data, label in zip(X_norm, labels):  # 遍历样本数据和标签,根据类别选择颜色并绘制散点图
#     # print(data, label)
#     plt.scatter(data[0], data[1], color=color_map[label], marker=shape_map[label])
#     # plt.text(data[0], data[1], label, ha='center', va='bottom')  # 所有样本都对应写上标签

# 添加图例,并设置字体大小
plt.legend(fontsize=20)

ax = plt.gca()  # gca:get current axis得到当前轴
# ax.spines['right'].set_visible(False)  # 取消右边界
# ax.spines['top'].set_visible(False)    # 取消上边界
ax.spines['right'].set_linewidth('2.0')  # 设置边框线宽为2.0
ax.spines['top'].set_linewidth('2.0')  # 设置边框线宽为2.0
ax.spines['bottom'].set_linewidth('2.0')  # 设置边框线宽为2.0
ax.spines['left'].set_linewidth('2.0')  # 设置边框线宽为2.0

plt.xticks(fontsize=20)  # 定义坐标轴刻度
plt.yticks(fontsize=20)

plt.xlabel('t-SNE Dimension 1', fontsize=20)  # 定义坐标轴标题
plt.ylabel('t-SNE Dimension 2', fontsize=20)
plt.title('t-SNE Visualization', fontsize=24)  # 定义图题

plt.show()  # 显示图形
plt.savefig('./visualization.png', dpi=600)  # 保存图为png格式
# plt.savefig('./visualization.svg', format='svg')  # 保存图为svg格式

可视化效果如下图所示:
在这里插入图片描述

上述代码中,X_tsne[labels == i, 0]是一个索引操作,用于从t-SNE降维后的数据X_tsne中选择特定类别的样本在第一个维度上的值。其中,labels == i是一个布尔数组,它的长度与数据集样本数量相同,该数组中的元素为True或False,表示对应的样本是否属于类别i。X_tsne[labels == i]表示从t-SNE降维后的数据集X_tsne中选择属于类别i的所有样本,这将返回一个新的数组,其形状为(属于类别i的样本数量, 降维后的特征数量)。X_tsne[labels == i, 0]则进一步选择了上述数组中的第一个特征维度的值。这将返回一个一维数组,包含属于类别i的样本在第一个维度上的数值。在绘制t-SNE可视化图时,这个表达式的作用是选择每个类别的样本在第一个维度上的值,以便将它们绘制在散点图中的水平方向上。同样,你可以使用X_tsne[labels == i, 1]选择每个类别的样本在第二个维度上的值,以将它们绘制在散点图的垂直方向上。这样,不同类别的样本将以不同的颜色在二维平面上进行可视化。

  • 8
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坊间小木匠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值