使用SVD(奇异值分解)进行降维的奇妙之旅
在数据分析和机器学习的广阔天地中,降维技术占据着举足轻重的地位。当我们面对高维数据时,不仅计算成本高昂,而且容易遭遇“维度灾难”,即随着维度的增加,数据的稀疏性和距离度量失效等问题愈发严重。为了克服这些挑战,各种降维技术应运而生,其中奇异值分解(Singular Value Decomposition, SVD)便是一种强大而优雅的工具。本文将带您踏上一段使用SVD进行降维的奇妙之旅。
什么是SVD?
SVD是一种在信号处理、统计学、机器学习等多个领域广泛应用的数学方法。它将一个任意形状的矩阵分解为三个特定形状的矩阵的乘积:一个正交矩阵、一个对角矩阵(其元素称为奇异值)和另一个正交矩阵的转置。这种分解方式不仅揭示了矩阵的内部结构,还为我们提供了一种有效的降维手段。
公式表示
对于任意m×n矩阵A,其SVD可以表示为:
A=UΣVT
其中,U是m×m的正交矩阵,Σ是m×n的矩形对角矩阵(非零元素为奇异值,按从大到小排列),V是n×n的正交矩阵。
SVD在降维中的应用
在降维场景下,SVD通过保留矩阵A中最重要的特征(即最大的奇异值对应的特征向量)来减少数据的维度。具体来说,我们可以通过选择Σ中最大的k个奇异值(k<min(m,n))以及它们对应的U和V中的列来近似原矩阵A,从而实现降维。
步骤概览
- 计算SVD:首先,对原始数据矩阵A进行SVD分解。
- 选择奇异值:根据实际需求选择前k个最大的奇异值。
- 构建降维矩阵:利用选定的奇异值及其对应的U和V中的列,构建降维后的矩阵。
- 解释与应用:分析降维后的数据,应用于后续的数据分析或机器学习任务中。
import numpy as np
from scipy.linalg import svd # 假设A是你的原始数据矩阵
A = np.random.rand(m, n) # 示例:生成一个m行n列的随机矩阵 # 计算SVD
U, s, VT = svd(A, full_matrices=False) # full_matrices=False表示不计算完整的U和VT
Sigma = np.diag(s) # 将奇异值向量s转换为对角矩阵Sigma
奇异点:
k = 5 # 假设我们想要降维到5维
s_k = s[:k] # 选择前k个最大的奇异值
U_k = U[:, :k] # 选择U中与这k个奇异值对应的列
VT_k = VT[:k, :] # 注意:这里实际上应该选择VT的前k行,因为VT是V的转置
# 但由于我们通常与U一起工作来重建降维后的数据,所以VT_k在直接降维中可能不直接使用
优点与局限
- 优点:
- 高效性:SVD提供了一种快速且有效的降维方法。
- 保留关键信息:通过保留最大的奇异值,能够较好地保留数据的主要特征。
- 广泛适用性:适用于各种类型的数据,无需对数据分布做过多假设。
- 局限:
- 计算复杂度:对于非常大的矩阵,SVD的计算可能相对耗时。
- 解释性:降维后的数据维度可能不如原始数据直观,解释起来需要一定的背景知识。
实践案例
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt def pic_compress(k, pic_array): # 计算SVD u, sigma, vt = np.linalg.svd(pic_array, full_matrices=False) # 构建压缩后的Sigma矩阵 sig = np.diag(sigma[:k]) # 重构压缩后的图像 # 注意:这里使用vt[:k, :]的转置来与u[:, :k]相乘 new_pic = np.dot(u[:, :k], np.dot(sig, vt[:k, :].T)) # 计算压缩后的图像大小(这里只是示例,实际节省取决于数据类型和存储方式) # 假设每个元素是float64类型,每个元素占用8字节 original_size = pic_array.nbytes compressed_size = u[:, :k].nbytes + sig.nbytes + vt[:k, :].nbytes return new_pic, original_size, compressed_size # 加载图像并转换为灰度图
img = Image.open('lufei.jpg').convert('L')
ori_img = np.array(img) # 进行图像压缩
k = 100
new_img, original_size, compressed_size = pic_compress(k, ori_img) # 显示结果
print(f"Original size: {original_size} bytes")
print(f"Compressed size: {compressed_size} bytes")
print(f"Compression ratio: {original_size / compressed_size:.2f}") fig, ax = plt.subplots(1, 2, figsize=(12, 6))
ax[0].imshow(ori_img, cmap='gray')
ax[0].set_title("Before Compression")
ax[0].axis('off') ax[1].imshow(new_img, cmap='gray')
ax[1].set_title("After Compression")
ax[1].axis('off') plt.show()
注意
- 在实际应用中,选择
k的值是一个重要的步骤,它需要根据数据的特性和任务的需求来确定。 - SVD降维特别适用于那些可以表示为矩阵形式的数据,如文本数据的TF-IDF矩阵、图像数据的像素矩阵等。
- 除了SVD之外,还有其他降维技术,如PCA(主成分分析),它在某些情况下与SVD密切相关(特别是在数据已经中心化的情况下)。PCA是SVD在数据协方差矩阵上的应用,但它通常更直接地关注于数据的方差最大化。
相关文章:
使用SVD(奇异值分解)进行降维的奇妙之旅
在数据分析和机器学习的广阔天地中,降维技术占据着举足轻重的地位。当我们面对高维数据时,不仅计算成本高昂,而且容易遭遇“维度灾难”,即随着维度的增加,数据的稀疏性和距离度量失效等问题愈发严重。为了克服这些挑战…...
【C++ 第二十一章】特殊类的设计(学习思路)
1.请设计一个类,不能被拷贝 设计思路 拷贝只会使用在两个场景中:拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。 C98 的做法 将拷贝构造函数与赋值运算符…...
Java设计模式【命令模式】-行为型
1. 介绍 命令模式(Command Pattern) 是一种行为型设计模式,它将一个请求封装为一个对象,从而使我们可以用不同的请求对客户端进行参数化,并且支持请求的排队、记录日志以及撤销、重做等功能。命令模式将请求的发送者与…...
【HarmonyOS】一键扫码功能
【HarmonyOS】一键扫码功能 前言 鸿蒙在api10之后,对系统api的基础上,封装了较为复杂功能的开发工具包,统一称之为Kit。这些Kit根据功能定义的不同,划分为不同的种类Kit。如下图所示: 其实可以理解为集成在系统中的…...
Spring Boot应用中集成与使用多数据源
Spring Boot应用中集成与使用多数据源 1. 前言 通过定义和使用多个数据源,能在Spring Boot应用中实现更复杂的数据管理场景,比如读写分离、数据冗余等。 2. 准备工作 环境准备:确保已经准备好Spring Boot的开发环境。数据库准备ÿ…...
探索 JavaScript 中的 instanceof 关键字
在 JavaScript 这门灵活而强大的编程语言中,instanceof 是一个非常重要的操作符,它用于检测一个对象是否在其原型链的原型构造函数的 prototype 属性中出现。简而言之,instanceof 用于测试一个对象是否是其父类或者其原型链上某个构造函数的实…...
Python爬虫02
xml 和html 区别 jsonpath模块 场景 多层嵌套的复杂字典直接提取数据 安装 pip install jsonpath使用 from jsonpath import jsonpathret jsonpath(dict, jaonpath语法规则字符串)语法规则 eg: lxml模块&xpath语法 谷歌浏览器 xpath helper 插件 作用对当前页面…...
HTTP/3
http相关知识点 HTTP/3是超文本传输协议(HTTP)的最新版本,旨在进一步提高Web性能和安全性。HTTP/3的显著变化是它基于QUIC(Quick UDP Internet Connections)协议,而不是之前版本中使用的TCP协议。QUIC是由…...
MySQL 字符串操作详解和案例示范
MySQL 字符串操作详解 MySQL 提供了丰富的字符串操作函数,能够对这些字符串进行截取、定位、替换等操作。本文将详细讲解 MySQL 中的字符串操作函数,包括 SUBSTRING()、SUBSTR()、LEFT()、RIGHT()、LOCATE()、POSITION()、FIND_IN_SET()、ELT()、INSERT…...
全双工语音交互
文章目录 微软小冰全双工字节大模型语音交互[Language Model Can Listen While Speaking](https://arxiv.org/html/2408.02622v1) 微软小冰全双工 全双工的定义:一路持续的听,upload audio;一路持续的输出,download audio…...
nginx中如何设置gzip
前言 Nginx通过配置gzip压缩可以提升网站整体速度 Nginx的gzip功能是用于压缩HTTP响应内容的功能。当启用gzip时,在发送给客户端之前,Nginx会将响应内容压缩以减小其大小。这样可以减少数据传输的带宽消耗和响应时间,提高网站的性能和速度。…...
借老系统重构机会我写了个groovy规则引擎
公司老系统的重构计划早就有了,为了对Java硬编码的各种校验规则进行重构,特地参考了相关技术,最终选择了groovy进行了系统的学习,并编写了一个即插即用的轻量级规则引擎。 文章目录 项目背景技术选型groovy的性能groovy脚本执行线…...
C#利用ffmpeg借助NVIDIA GPU实现实时RTSP硬解码+硬编码录制MP4
目录 说明 效果 项目 代码 下载 说明 利用周杰的开源项目 Sdcb.FFmpeg 项目地址:https://github.com/sdcb/Sdcb.FFmpeg/ 代码实现参考:https://github.com/sdcb/ffmpeg-muxing-video-demo 效果 C#利用ffmpeg借助NVIDIA GPU实现实时RTSP硬解码硬…...
第4章 汇编语言和汇编软件
第4章 汇编语言和汇编软件 该章主要介绍了汇编语言和汇编语言编译器的安装和使用。 汇编语言程序 该小节主要介绍了为什么要有汇编语言和汇编语言程序的一些基础写法。 书中有提到CPU有不同的架构,汇编语言有不同的风格,那么不同的CPU架构和不同的汇…...
网络安全在2024好入行吗?
前言 024年的今天,慎重进入网安行业吧,目前来说信息安全方向的就业对于学历的容忍度比软件开发要大得多,还有很多高中被挖过来的大佬。 理由很简单,目前来说,信息安全的圈子人少,985、211院校很多都才建立…...
C++练习
要求 1. 函数命名清晰 使用描述性的命名,准确反映函数的功能。例如,使用 CalculateSum() 而不是 sum()。避免使用缩写或模糊不清的名字,确保变量和函数名有明确的含义。 2. 参数传递 根据需要选择按值传递、按引用传递或按指针传递。如果…...
3. GIS后端工程师岗位职责、技术要求和常见面试题
本系列文章目录: 1. GIS开发工程师岗位职责、技术要求和常见面试题 2. GIS数据工程师岗位职责、技术要求和常见面试题 3. GIS后端工程师岗位职责、技术要求和常见面试题 4. GIS前端工程师岗位职责、技术要求和常见面试题 5. GIS工程师岗位职责、技术要求和常见面试…...
Linux学习笔记(4)----Debian压力测试方法
使用命令行终端压力测试需要两个实用工具:s-tui和stress sudo apt install s-tui stress 安装完成后,在终端中启动 s-tui实用工具: s-tui 执行后如下图: 你可以使用鼠标或键盘箭头键浏览菜单,然后点击“压力选项(Str…...
xml详解
一、XML是什么 XML(可扩展标记语言)是一种非常常用的数据存储和交换格式。 二、XML 的基本结构 声明 XML 文件通常以 XML 声明开始,例如:<?xml version"1.0" encoding"UTF-8"?>。它指定了 XML 的版…...
C140 杨辉三角
C140 杨辉三角 题目题解(94)讨论(102)排行面经 new 简单 通过率:29.57% 时间限制:1秒 空间限制:256M 知识点C工程师牛客 校招时部分企业笔试将禁止编程题跳出页面,为提前适应,练习时请使用在线自测,…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
QT开发技术【ffmpeg + QAudioOutput】音乐播放器
一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下,音视频内容犹如璀璨繁星,点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频,到在线课堂中知识渊博的专家授课,再到影视平台上扣人心弦的高清大片,音…...
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...
Python异步编程:深入理解协程的原理与实践指南
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 持续学习,不断…...
自定义线程池1.2
自定义线程池 1.2 1. 简介 上次我们实现了 1.1 版本,将线程池中的线程数量交给使用者决定,并且将线程的创建延迟到任务提交的时候,在本文中我们将对这个版本进行如下的优化: 在新建线程时交给线程一个任务。让线程在某种情况下…...
