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

【机器学习】基于t-SNE的MNIST数据集可视化探索

 一、前言

        在机器学习和数据科学领域,高维数据的可视化是一个极具挑战但又至关重要的问题。高维数据难以直观地理解和分析,而有效的可视化方法能够帮助我们发现数据中的潜在结构、模式和关系。本文以经典的MNIST手写数字数据集为例,探讨如何利用t-分布随机邻域嵌入(t-SNE)这一强大的降维技术,将高维的图像数据降维到二维空间,并进行可视化展示。通过本文,我们将深入了解t-SNE的原理、算法步骤,以及如何在Python中实现并应用它,从而更好地理解和探索高维数据的内在特性。


二、技术与原理简介

        在深入探讨t-SNE之前,我们首先需要区分机器学习中的两大主要范畴:监督学习和无监督学习。

        1. 监督学习

        监督学习是指在已知输入数据和对应标签的情况下,训练模型学习输入与输出之间的映射关系。模型通过学习大量的带标签数据,能够对新的、未见过的数据进行预测或分类。常见的监督学习算法包括:

  • 线性回归: 用于预测连续型变量。
  • 逻辑回归: 用于分类问题。
  • 支持向量机 (SVM): 用于分类和回归问题,尤其擅长处理高维数据。
  • 决策树: 基于树状结构进行决策,易于理解和解释。
  • 随机森林: 集成多个决策树,提高预测的准确性和鲁棒性。
  • 神经网络: 模拟人脑神经元结构,能够学习复杂的非线性关系。

        2. 无监督学习

        无监督学习是指在没有标签的情况下,训练模型发现数据中的潜在结构和模式。模型通过分析数据的内在特征,能够进行聚类、降维、关联规则挖掘等任务。常见的无监督学习算法包括:

  • 聚类: 将数据划分为不同的簇,使得同一簇内的数据相似度较高,不同簇之间的数据相似度较低。常见的聚类算法包括K-means、层次聚类、DBSCAN等。
  • 降维: 将高维数据降维到低维空间,同时尽可能保留数据的关键信息。常见的降维算法包括主成分分析 (PCA)、t-SNE、UMAP等。
  • 关联规则挖掘: 发现数据中不同项之间的关联关系,例如购物篮分析。

        3. 监督学习与无监督学习的区别

        4. MNIST数据集简介

        MNIST (Modified National Institute of Standards and Technology database) 是一个经典的手写数字数据集,广泛应用于机器学习和深度学习领域。它包含60,000个训练样本和10,000个测试样本,每个样本都是一个28x28像素的灰度图像,代表0到9之间的手写数字。

        4.1 数据格式

        MNIST数据集通常以两种格式提供:

  • 图像格式: 每个样本都是一个图像文件,例如PNG或JPEG格式。
  • 数值格式: 每个样本都被转换为一个784维的向量,其中每个元素代表一个像素的灰度值 (0到255)。

       4.2 数据集特点

  • 规模适中: MNIST数据集的规模适中,既可以用于快速原型验证,又可以用于训练复杂的模型。
  • 易于获取: MNIST数据集可以从多个来源免费获取,例如Scikit-learn、TensorFlow等。
  • 广泛应用: MNIST数据集被广泛应用于各种机器学习和深度学习算法的评估和比较。

        5. t-SNE算法原理与数学推导

        5.1 算法核心思想

        t-SNE(t-Distributed Stochastic Neighbor Embedding)是一种非线性降维技术,通过以下步骤实现高维数据到低维空间的映射:

  1. 计算高维相似度:在原始空间中,计算每对样本间的相似度
  2. 构建低维嵌入空间:在目标空间(如2D)中,通过优化使相似度分布匹配
  3. 梯度下降优化:最小化两空间分布的KL散度

        5.2 数学公式详解

        5.2.1 高维相似度计算

        对原始空间中的样本对(𝑥𝑖,𝑥𝑗) ,定义条件概率:

其中𝜎𝑖 ​为高斯核带宽,通过二分查找确定以满足** perplexity **参数(控制邻域大小)。

        5.2.2 低维相似度建模

        在目标空间中,定义联合概率:

        采用t-分布(自由度为1的Student分布)以增强对异常值的鲁棒性。

        5.2.3 目标函数优化

        通过最小化KL散度实现分布匹配:

其中

        优化过程使用梯度下降:

        5.3 算法步骤流程

  1. 参数初始化:设置降维维度(如2D)、perplexity(通常5-50)、学习率等
  2. 高维相似度计算:为每个样本计算条件概率矩阵𝑃P
  3. 低维初始化:随机生成初始嵌入坐标𝑌Y
  4. 梯度下降优化:迭代更新𝑌Y以最小化KL散度
  5. 结果输出:返回低维坐标矩阵

三、代码详解

        本文的代码主要分为以下几个部分:

        1. 导入库

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
from sklearn import datasets
from sklearn import manifold
%matplotlib inline

说明

  • import matplotlib.pyplot as plt: 导入matplotlib库,用于绘制图像。
  • import numpy as np: 导入numpy库,用于进行数值计算。
  • import pandas as pd: 导入pandas库,用于数据处理。
  • import seaborn as sns: 导入seaborn库,用于数据可视化。
  • from sklearn import datasets: 导入sklearn库中的datasets模块,用于加载数据集。
  • from sklearn import manifold: 导入sklearn库中的manifold模块,用于降维。
  • %matplotlib inline: 在Jupyter Notebook中显示图像。

        2. 加载数据

# 加载数据
data = datasets.fetch_openml('mnist_784', version=1, return_X_y=True)
pixel_values, targets = data
targets = targets.astype(int)

# 将DataFrame转换为numpy数组以便更容易操作
# 如果pixel_values已经是numpy数组,这一步可以跳过
if isinstance(pixel_values, pd.DataFrame):
    pixel_values_array = pixel_values.values
else:
    pixel_values_array = pixel_values

说明

  • data = datasets.fetch_openml('mnist_784', version=1, return_X_y=True): 使用datasets.fetch_openml函数加载MNIST数据集。'mnist_784'表示数据集的名称,version=1表示数据集的版本,return_X_y=True表示返回输入数据和标签。
  • pixel_values, targets = data: 将返回的数据解包为pixel_valuestargetspixel_values包含图像的像素值,targets包含图像的标签。
  • targets = targets.astype(int): 将标签转换为整数类型。
  • if isinstance(pixel_values, pd.DataFrame):: 检查pixel_values是否为pandas DataFrame类型。
  • pixel_values_array = pixel_values.values: 如果pixel_values为pandas DataFrame类型,则将其转换为numpy数组。
  • else: pixel_values_array = pixel_values: 否则,直接使用pixel_values

        3. 显示单个图像

# 显示单个图像
single_image = pixel_values_array[1].reshape(28, 28)
plt.imshow(single_image, cmap='gray')

说明

  • single_image = pixel_values_array[1].reshape(28, 28): 选择第一个图像,并将其reshape为28x28的矩阵。
  • plt.imshow(single_image, cmap='gray'): 使用plt.imshow函数显示图像,cmap='gray'表示使用灰度颜色映射。

        4. t-SNE降维

# t-SNE降维
tsne = manifold.TSNE(n_components=2, random_state=42)
transformed_data = tsne.fit_transform(pixel_values_array[:3000])

说明

  • tsne = manifold.TSNE(n_components=2, random_state=42): 创建一个t-SNE对象。n_components=2表示将数据降维到二维空间,random_state=42表示设置随机种子,保证结果的可重复性。
  • transformed_data = tsne.fit_transform(pixel_values_array[:3000]): 使用fit_transform函数对数据进行降维。这里只使用了前3000个样本,因为t-SNE的计算复杂度较高。

        5. 创建DataFrame用于可视化

# 创建DataFrame用于可视化
tsne_df = pd.DataFrame(
    np.column_stack((transformed_data, targets[:3000])),
    columns=["x", "y", "targets"]
)
tsne_df.loc[:, "targets"] = tsne_df.targets.astype(int)

说明

  • tsne_df = pd.DataFrame(...): 创建一个pandas DataFrame对象,用于存储降维后的数据和标签。
  • np.column_stack((transformed_data, targets[:3000])): 将降维后的数据和标签按列拼接在一起。
  • columns=["x", "y", "targets"]: 设置DataFrame的列名。
  • tsne_df.loc[:, "targets"] = tsne_df.targets.astype(int): 将DataFrame中的标签转换为整数类型。

        6. 可视化

# 可视化
# 注意:在新版本的seaborn中,size参数已更改为height
try:
    grid = sns.FacetGrid(tsne_df, hue="targets", size=8)
except TypeError:
    grid = sns.FacetGrid(tsne_df, hue="targets", height=8)
    
grid.map(plt.scatter, "x", "y").add_legend()

说明

  • grid = sns.FacetGrid(tsne_df, hue="targets", size=8): 创建一个seaborn FacetGrid对象,用于可视化降维后的数据。hue="targets"表示使用标签作为颜色编码,size=8表示设置图像的大小。
  • grid.map(plt.scatter, "x", "y").add_legend(): 使用plt.scatter函数绘制散点图,"x""y"表示散点图的横坐标和纵坐标,add_legend()表示添加图例。

        7. 完整代码

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
from sklearn import datasets
from sklearn import manifold
%matplotlib inline

# 加载数据
data = datasets.fetch_openml('mnist_784', version=1, return_X_y=True)
pixel_values, targets = data
targets = targets.astype(int)

# 将DataFrame转换为numpy数组以便更容易操作
# 如果pixel_values已经是numpy数组,这一步可以跳过
if isinstance(pixel_values, pd.DataFrame):
    pixel_values_array = pixel_values.values
else:
    pixel_values_array = pixel_values

# 显示单个图像
single_image = pixel_values_array[1].reshape(28, 28)
plt.imshow(single_image, cmap='gray')

# t-SNE降维
tsne = manifold.TSNE(n_components=2, random_state=42)
transformed_data = tsne.fit_transform(pixel_values_array[:3000])

# 创建DataFrame用于可视化
tsne_df = pd.DataFrame(
    np.column_stack((transformed_data, targets[:3000])),
    columns=["x", "y", "targets"]
)
tsne_df.loc[:, "targets"] = tsne_df.targets.astype(int)

# 可视化
# 注意:在新版本的seaborn中,size参数已更改为height
try:
    grid = sns.FacetGrid(tsne_df, hue="targets", size=8)
except TypeError:
    grid = sns.FacetGrid(tsne_df, hue="targets", height=8)
    
grid.map(plt.scatter, "x", "y").add_legend()


四、总结与思考

        本文以MNIST数据集为例,详细介绍了如何使用t-SNE进行高维数据可视化。通过t-SNE降维,我们可以将784维的图像数据降维到二维空间,并在散点图上清晰地看到不同数字之间的分布情况。

        t-SNE是一种强大的降维技术,但也有一些局限性:

  • 计算复杂度高: t-SNE的计算复杂度为O(n^2),对于大规模数据集,计算时间会非常长。
  • 参数敏感: t-SNE的性能受到参数的影响,例如困惑度 (perplexity) 和学习率 (learning_rate)。
  • 全局结构失真: t-SNE主要关注局部结构,可能会导致全局结构失真。

        在实际应用中,我们需要根据具体情况选择合适的降维技术。对于大规模数据集,可以考虑使用PCA或UMAP等更高效的算法。对于需要保留全局结构的场景,可以考虑使用Isomap或LLE等算法。


【作者声明】

        本文内容基于作者对基于t-SNE的MNIST数据集可视化探索实现过程的实验与总结,所有数据和代码均为原创。文章中的观点仅代表个人见解,供读者参考交流。若有任何问题或建议,欢迎在评论区留言讨论,共同促进技术进步。


 【关注我们】

        如果您对神经网络、群智能算法及人工智能技术感兴趣,欢迎点赞、收藏并转发,与更多朋友一起探讨与交流!


http://www.kler.cn/a/585171.html

相关文章:

  • MCP-Playwright:当自动化测试遇上「万能插座」,效率革命就此开启!
  • Linux 匿名管道实现进程池
  • 【webrtc debug tools】 rtc_event_log_to_text
  • 容器技术与Kubernetes概述
  • Ai文章改写出来的文章,怎么过Ai检测?控制指令,测试的一点心得,彻底疯了!
  • Python:面向对象,类和对象,实例方法与实例属性,构造函数
  • ARM:什么是满减栈?为何选择满减栈?
  • 【零基础入门unity游戏开发——unity3D篇】3D物理系统之 —— 3D刚体组件Rigidbody
  • 一些docker命令
  • 微服务全局ID方案汇总
  • LeetCode860☞柠檬水找零
  • 有关Java中的注解和反射
  • 详解数据库范式
  • 《Java对象“比武场“:Comparable与Comparator的巅峰对决》
  • app.config.globalProperties
  • 语言识别模型whisper学习笔记
  • Odoo Http鉴权+调用后端接口
  • 爱普生车规级晶振SG2520CAA智能汽车电子系统的应用
  • JavaScript 函数基础
  • 【区块链】btc