【小技巧】机器学习中可视化高维向量的两种方法PCA和t-SNE,以及其原理介绍和代码示例(附代码)

使用情景:比如说现在我有一批numpy的多维向量,比如说都是256维度的,X.shape(n, 256), 已知它们都是经过训练能够在256dim的超球面上实现分类或聚类的,现在我想把它们可视化出来看看各个簇在超球面上的分布是怎样的?
在这里插入图片描述

1. 可视化方法介绍(附代码)

为了可视化高维数据(比如你的256维向量)在低维空间(通常是2D或3D)的分布,常用的方法包括主成分分析(PCA)和t-SNE。这两种方法可以帮助我们理解数据在高维空间中的内在结构。

下面,我会展示如何使用Python的scikit-learn库和matplotlib来可视化这些向量。我将使用PCA和t-SNE两种方法来降维,并在3D平面上展示结果。如果你有标签数据,这将有助于我们看到不同簇的分布。

首先,确保你已经安装了必要的库:

pip install numpy matplotlib scikit-learn plotly

下面是一个示例脚本,展示如何将你的高维数据可视化:

# -*- coding: utf8 -*-
import os
import numpy as np
import matplotlib.pyplot as plt
plt.switch_backend('agg')
from sklearn.decomposition import PCA
from sklearn.manifold import TSNE
import plotly.graph_objects as godef visualize_data_3d_interactive_v0(X, save_path, labels=None):"""X: shape(num, dim)"""save_path = os.path.splitext(save_path)[0]# 使用PCA将数据降到3维print('PCA is processing ...')pca = PCA(n_components=3)X_pca = pca.fit_transform(X)# 使用t-SNE将数据降到3维print('t-SNE is processing ...')tsne = TSNE(n_components=3, perplexity=30, learning_rate=200)X_tsne = tsne.fit_transform(X)# 为PCA结果创建一个3D散点图fig_pca = go.Figure(data=[go.Scatter3d(x=X_pca[:, 0], y=X_pca[:, 1], z=X_pca[:, 2],mode='markers',marker=dict(size=5,color=labels,                # 设置颜色为标签opacity=0.8))])fig_pca.update_layout(title='PCA Results', scene=dict(xaxis_title='Component 1',yaxis_title='Component 2',zaxis_title='Component 3'))fig_pca.write_html(save_path + '_pca.html')# 为t-SNE结果创建一个3D散点图fig_tsne = go.Figure(data=[go.Scatter3d(x=X_tsne[:, 0], y=X_tsne[:, 1], z=X_tsne[:, 2],mode='markers',marker=dict(size=5,color=labels,                # 设置颜色为标签opacity=0.8))])fig_tsne.update_layout(title='t-SNE Results', scene=dict(xaxis_title='Component 1',yaxis_title='Component 2',zaxis_title='Component 3'))fig_tsne.write_html(save_path + '_tsne.html')def visualize_data_3d_interactive_v1(data_dict, save_path):"""版本不同:1.输入不同,data_dict是一个{cls: features};2.可视化功能差异,这个版本加入了对于不同cls显示不同颜色,并打上标签;"""save_path = os.path.splitext(save_path)[0]# 准备空列表来存储所有数据点和颜色all_data = []colors = []pid_index = 0  # 用于为每个pid分配不同的颜色texts = []  # 用于存储文本标签# 提取颜色映射color_palette = plt.cm.get_cmap('tab10', len(data_dict))# 将每个pid的数据点收集到一起,并为第一个特征添加标签for pid, features in data_dict.items():all_data.append(features)colors.extend([color_palette(pid_index)] * features.shape[0])# 初始化所有文本为空,除了第一个特征texts.extend([""] * features.shape[0])texts[len(texts) - features.shape[0]] = pid  # 为第一个特征设置pid标签pid_index += 1# 将所有数据合并成一个大矩阵all_data = np.vstack(all_data)# 使用PCA将数据降到3维print('PCA is processing ...')pca = PCA(n_components=3)X_pca = pca.fit_transform(all_data)# 使用t-SNE将数据降到3维print('t-SNE is processing ...')tsne = TSNE(n_components=3, perplexity=30, learning_rate=200)X_tsne = tsne.fit_transform(all_data)# 创建一个3D散点图显示PCA结果fig_pca = go.Figure(data=[go.Scatter3d(x=X_pca[:, 0], y=X_pca[:, 1], z=X_pca[:, 2],mode='markers+text',text=texts,marker=dict(size=5,color=['rgb({}, {}, {})'.format(c[0]*255, c[1]*255, c[2]*255) for c in colors],  # 将颜色转换为plotly格式opacity=0.8))])fig_pca.update_layout(title='PCA Results', scene=dict(xaxis_title='Component 1',yaxis_title='Component 2',zaxis_title='Component 3'))fig_pca.write_html(save_path + '_pca.html')# 创建一个3D散点图显示t-SNE结果fig_tsne = go.Figure(data=[go.Scatter3d(x=X_tsne[:, 0], y=X_tsne[:, 1], z=X_tsne[:, 2],mode='markers+text',text=texts,marker=dict(size=5,color=['rgb({}, {}, {})'.format(c[0]*255, c[1]*255, c[2]*255) for c in colors],  # 将颜色转换为plotly格式opacity=0.8))])fig_tsne.update_layout(title='t-SNE Results', scene=dict(xaxis_title='Component 1',yaxis_title='Component 2',zaxis_title='Component 3'))fig_tsne.write_html(save_path + '_tsne.html')if __name__ == '__main__':# test v0data_np = np.random.rand(100, 256)visualize_data_3d_interactive_v0(data_np, 'outputs/vis_hdim_vector_interactive_v0.html')# test v1data_dict = {'class1': np.random.randn(100, 50),   # 100个50维的样本'class2': np.random.randn(100, 50),   # 另外100个50维的样本'class3': np.random.randn(100, 50),   # 另外100个50维的样本'class4': np.random.randn(100, 50),   # 另外100个50维的样本'class5': np.random.randn(100, 50),   # 另外100个50维的样本'class6': np.random.randn(100, 50),   # 另外100个50维的样本'class7': np.random.randn(100, 50),   # 另外100个50维的样本'class8': np.random.randn(100, 50),   # 另外100个50维的样本'class9': np.random.randn(100, 50),   # 另外100个50维的样本'class10': np.random.randn(100, 50)   # 另外100个50维的样本}visualize_data_3d_interactive_v1(data_dict, 'outputs/vis_hdim_vector_interactive_v1.html')

在这个脚本中,你需要替换X为你实际的数据。

PCA通常用于获取数据的主要方向,而t-SNE更擅长在保持局部结构的同时展示数据的簇状分布。视觉效果上,t-SNE可能更适合展示复杂的簇结构,但它的计算成本通常也更高。

2. t-SNE 原理

t-SNE(t-Distributed Stochastic Neighbor Embedding)是一种非常流行的机器学习算法,主要用于高维数据的可视化。它由Laurens van der Maaten和Geoffrey Hinton在2008年提出。t-SNE的核心优势在于它能够有效地在二维或三维空间中展示高维数据的局部结构,使得类似的数据点在低维空间中彼此靠近,而不相似的数据点则远离。这使t-SNE特别适用于高维数据的聚类分析和可视化。

t-SNE的工作原理

t-SNE的工作过程可以分为以下几个关键步骤:

  1. 计算高维空间中的相似性
    t-SNE首先在高维空间中计算每对数据点间的条件概率,这种概率反映了一个点选择另一个点作为其邻居的可能性。这个概率由高斯分布(正态分布)的相似性函数决定,其中中心点是数据点本身。

  2. 计算低维空间中的相似性
    对于映射到低维空间中的数据点,t-SNE使用了一个长尾分布——具体来说是t分布(自由度为1的学生t分布,形状类似柯西分布),来计算低维空间中点之间的相似性。使用长尾分布是为了解决所谓的“拥挤问题”(crowding problem),即在低维空间中很难准确地表示原高维空间中的距离关系。

  3. 最小化Kullback-Leibler散度
    t-SNE的目标是使得两个空间(高维和低维)中的概率分布尽可能相似。为此,它通过最小化高维空间与低维空间中定义的概率分布之间的Kullback-Leibler散度来调整低维空间中的点。Kullback-Leibler散度是一种衡量两个概率分布差异的方法。

  4. 梯度下降
    t-SNE使用梯度下降法来找到低维空间的最优配置,以最小化Kullback-Leibler散度。这一步通常需要多次迭代,且对初始值和超参数(如学习率和困惑度)比较敏感。

t-SNE的使用注意事项

  • 困惑度(Perplexity)
    困惑度是t-SNE中的一个重要参数,反映了考虑的邻居的数量,并且对结果有显著影响。一般需要通过试验来选择最合适的困惑度值。

  • 随机性
    由于梯度下降的初始点是随机选择的,t-SNE的结果可能每次都略有不同。为了得到可重复的结果,需要固定随机种子。

  • 计算成本
    t-SNE的计算成本随着数据量的增加而显著增加,特别是对于非常大的数据集,可能需要较长的计算时间。

t-SNE是一个非常强大的工具,特别是在探索性数据分析和数据可视化方面。然而,正确地使用t-SNE需要对其参数和数据特性有一定的理解。

3. PCA 原理

主成分分析(PCA,Principal Component Analysis)是一种广泛使用的统计技术,用于数据降维和探索性数据分析。通过PCA,可以从多维数据集中提取出关键信息,并且以维数更少的数据集形式呈现,这种转换是通过保留数据的最大方差来实现的。

PCA的工作原理

  1. 标准化数据
    首先,通常需要将数据进行标准化处理,即对每个特征维度进行中心化(减去均值)和缩放(除以标准差),以使各特征具有相同的重要性。

  2. 计算协方差矩阵
    然后,计算数据的协方差矩阵。协方差矩阵描述了数据中各个变量之间的相关性;在这个矩阵中,每个元素是对应两个变量的协方差,它反映了两个变量变化时是如何相互影响的。

  3. 求解特征值和特征向量
    对协方差矩阵进行特征值分解,求得的特征值和对应的特征向量指示了数据的主要变化方向。特征值越大,对应的特征向量在数据集中的重要性就越高,这个特征向量定义了一个主成分。

  4. 选择主成分
    选择最大的几个特征值及其对应的特征向量。通常,这些特征向量被称为“主成分”,它们是新的、较少的、互相正交的坐标轴,这些坐标轴是按照它们能够捕捉的数据方差的重要性排序的。

  5. 构造新的特征空间
    将原始数据投影到这些选定的主成分上,得到的就是降维后的数据。这一步通常涉及到一个矩阵乘法运算,原始数据矩阵乘以选定的主成分矩阵。

PCA的应用

  • 数据压缩:通过减少数据集的维数,PCA有助于减少存储空间和提高算法效率。
  • 去噪:PCA可以帮助识别并去除数据中的噪声,特别是当噪声较小且数据的主要结构在高方差的方向时。
  • 可视化:在多维数据集中,通过PCA可以将数据降到两维或三维,使得数据可通过图形化方式展示。

注意事项

虽然PCA是一个强大的工具,但它也有局限性。由于PCA是基于线性假设的,它可能无法有效识别基于非线性结构的复杂模式。此外,如果所有变量的方差都差不多,PCA的效果可能就不明显。在这些情况下,可能需要考虑使用其他的降维技术,如t-SNE、LDA(线性判别分析)或者基于核的PCA方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/129.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

陈胜许诺‘苟富贵,勿相忘’的那些工友们,后来都怎么样了?

记得初三语文上册的课文中,有一篇叫《陈涉世家》文章,节选自《史记》,讲述的是秦末农民起义军领袖陈胜吴广的故事。其中陈胜有三句话让人记忆犹新,其中有两句是他在地主家当农民工时,和一起做事的工友说的。第一句话就…

Vue项目实现懒加载——自用笔记

熟悉指令语法&#xff1a; <template><HomePanel title"人气推荐" sub-title"人气爆款 不容错过"><ul class"goods-list"><li v-for"item in hotList" :key"item.id"><RouterLink to"/&qu…

免费学习简单实操,轻松拿下微软生成式AI认证

在这个AI风暴席卷全球的时代&#xff0c;我们都处在一个充满机遇和挑战的交叉点上。无论你是正在寻找新的职业道路&#xff0c;还是希望在现有的职业生涯中取得突破&#xff0c;掌握AI技能都将成为你开启新篇章的关键。 为了帮助更多的人在这个AI时代中实现跨越&#xff0c;微…

v-deep 打破作用域隔离的原理

vue 中使用 scoped 样式隔离 使用 ::v-deep 和 >>> &#xff0c;穿透作用域样式&#xff0c;以便在父组件中修改子组件的样式&#xff0c;即打破样式隔离。 vue 使用了一种叫做 scoped css 的技术来隔离组件的样式&#xff0c;确保他们不会泄漏到其他组件中&#xf…

spring-core:注解合成(AnnotationUtils.synthesizeAnnotation)的使用示例

spring-core提供的AnnotationUtils工具功能很强大&#xff0c;也很灵活&#xff0c;其中的synthesizeAnnotation方法我一起没搞明白它的使用场景&#xff0c;直到今天我的工作用上了它&#xff0c;学会它的使用。 synthesizeAnnotation方法说明&#xff1a; 通过将包含了注解字…

网工内推 | 14薪!安全服务工程师,上市公司,CISP认证优先

01 远江盛邦 招聘岗位&#xff1a;安全服务工程师 职责描述&#xff1a; 1、负责对客户网络、系统进行渗透测试&#xff0c;漏洞验证、安全评估和安全加固&#xff1b; 2、负责对监督单位的系统安全问题进行监督&#xff0c;并督察改进&#xff1b; 3、对监管单位的安全告警、…

力扣136. 只出现一次的数字

Problem: 136. 只出现一次的数字 文章目录 题目描述思路复杂度Code 题目描述 思路 由于题目要求使用线性时间复杂度和常量级的空间复杂度&#xff0c;再加上找重复元素这个特性&#xff0c;我们可以想到使用位运算来求解&#xff1a; 1.任何数与其本身异或得0&#xff0c;任何…

我的创作纪念日20240418

机缘 我的技术博客起源于对编程的深深热爱和对知识的渴望。从一开始&#xff0c;我就被编程世界的无限可能所吸引&#xff0c;而这种热情也推动我开始了技术创作之旅。我创建博客的初衷有以下几点&#xff1a; 分享实战经验&#xff1a;在工作中&#xff0c;我遇到了许多技术…

HackMyVM-BaseME

目录 信息收集 arp nmap WEB web信息收集 gobuster hydra 目录检索 ssh 提权 get user sudo base64提权 get root 信息收集 arp ┌─[rootparrot]─[~/HackMyVM] └──╼ #arp-scan -l Interface: enp0s3, type: EN10MB, MAC: 08:00:27:16:3d:f8, IPv4: 192.168…

go语言context

context在服务端编程基本都贯穿所有&#xff0c; Context 是请求的上下文信息。对于RPC Server来说&#xff0c;一般每接收一个新的请求&#xff0c;会产生一个新的Context&#xff0c;在进行内部的函数调用的时候&#xff0c;通过传递Context&#xff0c;可以让不同的函数、协…

Flowable工作流引擎:Spring Boot集成指南

Flowable工作流引擎&#xff1a;Spring Boot集成指南 前言开始集成相关配置文件pom文件 前言 在快速变化的软件开发世界中&#xff0c;工作流管理成为了企业应用不可或缺的组成部分。无论是简化复杂业务流程、提升操作效率还是确保流程的一致性和透明性&#xff0c;一个强大的…

python二级题目-仅使用 Python 基本语法,即不使用任何模块,编写 Python 程序计算下列数学表达式的结果并输出,小数点后保留 3 位。

x(((3**4)5*(6**7))/8)**0.5 .format 用法一&#xff1a; print({}.format(1)) 1 print(这个是format的用法{}。。。.format(3)) 这个是format的用法3 ’大括号1:{},大括号2:{},大括号3:{}‘.format(3,4,5) print(’大括号1:{},大括号2:{},大括号3:{}‘.form…

牛客小白月赛90(A,B,C,D,E,F)

比赛链接 官方题解&#xff08;视频&#xff09; 这场偏思维&#xff0c;感觉好像没啥算法。E需要动态维护前 k k k 小&#xff0c;F是个离散化加dp&#xff0c;状态和递推方程比较 非常规&#xff0c;建议还是看一下涨涨姿势。 A 小A的文化节 思路&#xff1a; 签到 cod…

hive使用sqoop与oracle传输数据

下载地址 http://archive.apache.org/dist/sqoop 两个版本sqoop1&#xff08;1.4.x&#xff09;和sqoop2&#xff08;1.99.x&#xff09;&#xff0c;两种不同的架构。 本文使用sqoop1。 sqoop是apache旗下一款“hadoop与关系数据库之间传送数据”的工具。 导入数据&#xf…

5374: 【数学】最后一击

题目描述 小爱和小艾两人组队打一只怪兽。一开始怪兽有 n 点生命值&#xff0c;当 n 变成 0 或更低时&#xff0c;怪兽就被消灭了。他们两人是同时开始攻击的&#xff0c;小爱每分钟可以攻击 a 下&#xff0c;小艾每分钟可以攻击 b 下。若 a2&#xff0c;b4&#xff0c;则小爱…

深圳市第六批专精特新“小巨人”企业申报和第三批专精特新“小巨人”企业申报开始了

各区&#xff08;新区、特别合作区&#xff09;相关工作部门&#xff0c;各企业&#xff1a; 根据《工业和信息化部办公厅关于开展第六批专精特新“小巨人”企业培育和第三批专精特新“小巨人”企业复核工作的通知》&#xff08;工信厅企业函〔2024〕142号&#xff09;要求&…

中仕公考:2024年广东省高校毕业生‘三支一扶‘公告

2024年广东省三支一扶共计划招募3000名左右高校毕业生&#xff0c;服务期限为两年&#xff0c;具体招募岗位和条件可通过广东人事考试网查询。 招考条件&#xff1a; 年龄不超过30周岁(1993年4月22日后出生); 支教岗位须是已取得教师资格证的高校毕业生&#xff0c;支医专业…

Phpstorm环境配置与应用

PhpStorm是一款功能强大的PHP集成开发环境&#xff0c;配置与应用涉及以下步骤&#xff1a; 下载与安装&#xff1a; 访问 PhpStorm 官网下载地址&#xff0c;选择合适的版本进行下载。双击下载的安装包文件进行安装&#xff0c;过程类似于其他IntelliJ IDEA产品。 个性化设…

C++ | Leetcode C++题解之第23题合并K个升序链表

题目: 题解&#xff1a; class Solution {// 21. 合并两个有序链表ListNode *mergeTwoLists(ListNode *list1, ListNode *list2) {auto dummy new ListNode(); // 用哨兵节点简化代码逻辑auto cur dummy; // cur 指向新链表的末尾while (list1 && list2) {if (list1…

秋招嵌入式面经

24秋招-汇川嵌入式面经--超详细&#xff01; 一面 8月24日投递 9月3日一面&#xff08;30min&#xff09; 自我介绍&#xff1a; 介绍一下你的第一个项目吧 对于MCU的选型为什么使用F4的STM32&#xff1f; 项目里面用到了SPI进行两块MCU之间的通信&#xff0c;介绍一下SPI…