SVD奇异值分解原理及应用

 --------------------------------------------------------------------------------------------------------------------------------

首先说明:本文的内容来自百家号“人工智能遇见磐创”大佬的整理,感谢原作者(本文在原作者的基础上按照自己的理解进行了修改,整合。如有不妥,请联系删除)。

原文地址:百度安全验证https://baijiahao.baidu.com/s?id=1643076332887222975&wfr=spider&for=pcicon-default.png?t=N7T8https://baijiahao.baidu.com/s?id=1643076332887222975&wfr=spider&for=pc

--------------------------------------------------------------------------------------------------------------------------------

大家发现没有?我们大学学过的线性代数在现实世界中基本没用。

好吧,但我可以向你保证,并不是这样的。特别是如果你想开启数据科学的职业生涯,那我们就开始吧,保证不让您失望。

线性代数弥合了理论与概念实际实施之间的差距。对线性代数的掌握理解打开了我们认为无法理解的机器学习算法的大门。

线性代数的一种这样的用途是奇异值分解(SVD)用于降维

你在数据科学中一定很多次遇到SVD。它无处不在,特别是当我们处理降维时。但它是什么?它是如何工作的?SVD应用有什么?

事实上,SVD是推荐系统的基础,而推荐系统是谷歌,YouTube,亚马逊,Facebook等大公司的核心。

接下来,我们一起看看这个奇怪而陌生的东西:SVD。

1、SVD分解原理

通过关于SVD及其应用的所有文献,你将非常频繁地遇到术语“矩阵的秩”。那么让我们从了解这是什么开始。

1.1 矩阵的秩

矩阵的秩是矩阵中线性无关的行(或列)向量的最大数量。如果向量r不能表示为r1和r2的线性组合,则称向量r与向量r1和r2线性无关

考虑下面的三个矩阵:

(1)在矩阵A中,行向量r2是r1的倍数,r2 = 2 r1,因此它只有一个无关的行向量。Rank(A)= 1

(2)在矩阵B中,行向量r3是r1和r2之和,r3 = r1 + r2,但r1和r2是无关的,Rank(B)= 2

(3)在矩阵C中,所有3行彼此无关。Rank(C)= 3

矩阵的秩可以被认为是由矩阵表示的独特信息量(也就是不相关的信息量)多少的代表。秩越高,信息越高

1.2 SVD

SVD将矩阵分解为3个矩阵的乘积,如下所示:

如果A是m x n矩阵:

  • U是左奇异向量的m×m矩阵
  • S是以递减顺序排列的奇异值的m×n对角矩阵
  • V是右奇异向量的n×n矩阵

1.3 为什么SVD用于降维?

你可能想知道我们为什么要经历这种看似辛苦的分解。可以通过分解的替代表示来理解原因。见下图:

分解允许我们将原始矩阵表示为低秩矩阵的线性组合(也就是说,复杂的矩阵A可以用\sigma_1\sigma_2两个参数表示,是不是就降低维度了?从2维数组降低到1维向量了?)。

在实际应用中,你将观察到的只有前几个(比如k)奇异值很大,其余的奇异值接近于零。因此,可以忽略除前几个之外而不会丢失大量信息。请参见下图中的矩阵截断方式:

也就是说A可以由前k个参数的线性组合近似表示,近似程度能达到90%。

总结以下3点:

  • 使用SVD,我们能够用3个较小的矩阵U,S和V表示我们的大矩阵A
  • 这在大型计算中很有用,如一张超像素照片4560*2780,这张照片可能有20M,但是我们可以仅使用100个\sigma表示即可,100个\sigma的存储空间也就是几K。
  • 我们可以得到A的k-秩近似。为此,选择前k个奇异值并相应地截断3个矩阵。

2、SVD分解应用

SVD是将矩阵A分解为3个矩阵(U,S和V)。S是奇异值的对角矩阵。将奇异值视为矩阵中不同特征的重要性值矩阵的秩是对存储在矩阵中的独特信息的度量。秩越高,信息越多矩阵的特征向量是数据的最大扩展或方差的方向在大多数应用中,我们希望将高秩矩阵缩减为低秩矩阵,同时保留重要信息。

我们将在此处遵循自上而下的方法并首先讨论SVD应用。现在你只需要知道四点来理解这些应用:

  • 图片压缩:在图像处理中,SVD分解常被用于图像压缩。通过对图像矩阵进行SVD分解,可以得到较低秩的近似矩阵,从而减少存储空间和传输带宽。这种方法在JPEG2000等图像压缩算法中得到广泛应用。
  • SLAM: 对极几何分解本质矩阵求R,t
  • 推荐系统:SVD分解在推荐系统中也有重要的应用。通过对用户评分矩阵进行SVD分解,可以将用户和物品映射到一个隐空间中,并预测用户对未评分物品的喜好程度。基于SVD的协同过滤算法在Netflix Prize竞赛中取得了很大成功。
  • 数据降维:SVD分解可以将高维数据降维到低维,保留数据的主要特征。这在机器学习和数据挖掘任务中非常有用,可以提高计算效率并减少存储需求。例如,在主成分分析(PCA)中,SVD分解被广泛用于实现数据降维。

2.1 SVD用于图像压缩

# 下载图片 "https://cdn.pixabay.com/photo/2017/03/27/16/50/beach-2179624_960_720.jpg"
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import cv2
# 灰度化读取图片
img = cv2.imread('beach-2179624_960_720.jpg', 0)

plt.imshow(img)
plt.axis('off')  # 关闭坐标轴
plt.show()

# 得到svd
U, S, V = np.linalg.svd(img)
# 得到矩阵的形状
print(U.shape, S.shape, V.shape)
# 以不同component数绘制图像
comps = [638, 500, 400, 300, 200, 100]
plt.figure(figsize = (16, 8))
for i in range(6):
    low_rank = U[:, :comps[i]] @ np.diag(S[:comps[i]]) @ V[:comps[i], :]
    if(i == 0):
        plt.subplot(2, 3, i+1), plt.imshow(low_rank, cmap = 'gray'), plt.axis('off'), plt.title("Original Image with n_components =" + str(comps[i]))

    else:
        plt.subplot(2, 3, i+1), plt.imshow(low_rank, cmap = 'gray'), plt.axis('off'), plt.title("n_components =" + str(comps[i]))

plt.show()

2.2 SVD用于图像恢复

图像恢复其实就是通过矩阵填充来实现。

矩阵填充是在部分观察的矩阵中填充缺失元素的过程。Netflix问题就是一个常见的例子。

给定一个评级矩阵,其中每个元素(i,j)表示客户i对电影j的评级,即客户i观看了电影j,否则该值为缺失值,我们想要预测剩余的元素以便对客户于提出好的建议。

在图像矩阵中!由于图像是连续的,大多数像素的值取决于它们周围的像素。因此,低秩矩阵可以是这些图像的良好近似。

图片来自:Chen, Zihan. “Singular Value Decomposition and its Applications in Image Processing.” ACM, 2018

2.3 SVD用于特征脸

论文“Eigenfaces for Recognition”于1991年发表。在此之前,大多数面部识别方法都涉及识别个体特征,如眼睛或鼻子,并根据这些特征之间的位置,大小和关系来开发模型。

特征脸方法试图在面部图像中提取相关信息,尽可能有效地对其进行编码,并将一个面部编码与数据库中的模型编码进行比较。

通过将每个面部表达为新面部空间中所选择的特征脸的线性组合来获得编码。

把这个方法分解为五个步骤:

  1. 收集面部训练集
  2. 通过找到最大方差的方向-特征向量或特征脸来找到最重要的特征
  3. 选择对应于最高特征值的M个特征脸(这些特征脸现在定义了一个新的面部空间)
  4. 将所有数据投影到此面部空间中
  5. 对于新面部,将其投影到新面部空间中,找到空间中最近的面部,并将面部分类为已知或未知面部

可以使用PCA和SVD找到这些特征脸。这是我在Labeled Faces in the Wild数据集中上执行SVD后获得的几个特征脸中的第一个:

我们可以看到,只有前几行中的图像看起来像实际的面部。其他看起来很糟糕,因此我放弃了它们。我保留了总共120个特征脸,并将数据转换为新的面部空间。然后我使用k近邻分类器来预测基于面部的姓名。

你可以在下面看到分类报告。显然,还有改进的余地。你可以尝试调整特征脸的数量或使用不同的分类器进行试验:

看看一些预测值及其真实标签:

2.4 SVD用于谱聚类

聚类是将类似对象划分在一起的任务。这是一种无监督的机器学习技术。对于我们大多数人来说,聚类是K-Means聚类(一种简单但功能强大的算法)的代名词,但是,这并不是准确的说法。

考虑以下情况:

显然,同心圆中有2个簇。但是,n_clusters = 2的KMeans给出了以下簇:

K-Means绝对不是这里使用的合适算法。谱聚类是一种可以解决这个问题的技术,它源于图论。以下是基本步骤:

  1. 从数据Affnity matrix(A)或Adjacent matrix开始。这表示一个对象与另一个对象的相似程度。在图中,这将表示点之间是否存在边缘
  2. 找到每个对象的 Degree matrix (D) 。这是一个对角矩阵,其元素(i,i)等于对象i相似的对象数
  3. 找到Affnity matrix的 Laplacian matrix(L) (L):L = A - D
  4. 根据它们的特征值找到Laplacian matrix的最高k个特征向量
  5. 在这些特征向量上运行k-means,将对象聚类为k类

你可以通过下面的链接阅读完整的算法及其数学原理^2,而scikit-learn中谱聚类的实现类似于KMeans:

from sklearn.datasets import make_circles
from sklearn.neighbors import kneighbors_graph
from sklearn.cluster import SpectralClustering
import numpy as np
import matplotlib.pyplot as plt
# s生成数据
X, labels = make_circles(n_samples=500, noise=0.1, factor=.2)
# 可视化数据
plt.scatter(X[:, 0], X[:, 1])
plt.show()
# 训练和预测
s_cluster = SpectralClustering(n_clusters = 2, eigen_solver='arpack',
affinity="nearest_neighbors").fit_predict(X)
# 可视化结果
plt.scatter(X[:, 0], X[:, 1], c = s_cluster)
plt.show()

你将从上面的代码中得到以下不错的聚类结果:

2.5 SVD用于从视频中删除背景

想一想如何区分视频背景和前景。视频的背景基本上是静态的 - 它看不到很多变化。所有的变化都在前景中看到。这是我们用来将背景与前景分开的属性。

以下是我们可以采用的步骤来实现此方法:

从视频创建矩阵M -- 这是通过定期从视频中采样图像快照,将这些图像矩阵展平为数组,并将它们存储为矩阵M的列。我们得到以下矩阵M的图:

你认为这些水平和波浪线代表什么?花一点时间考虑一下。

水平线表示在整个视频中不改变的像素值。基本上,这些代表了视频中的背景。波浪线显示变化并代表前景。

  • 因此,我们可以将M视为两个矩阵的总和 - 一个表示背景,另一个表示前景
  • 背景矩阵没有看到像素的变化,因此是多余的,即它没有很多独特的信息。所以,它是一个低秩矩阵
  • 因此,M的低秩近似是背景矩阵。我们在此步骤中使用SVD
  • 我们可以通过简单地从矩阵M中减去背景矩阵来获得前景矩阵
  • 这是视频一个删除背景后的帧:

3. 3种在Python中使用SVD的方法

我们知道什么是SVD,它是如何工作的,以及它在现实世界中的用途。但是我们如何自己实现SVD呢?

SVD的概念听起来很复杂。你可能想知道如何找到3个矩阵U,S和V。如果我们手动计算这些矩阵,这是一个漫长的过程。

幸运的是,我们不需要手动执行这些计算。我们可以用三种简单的方式在Python中实现SVD。

3.1 numpy中的SVD

NumPy是Python中科学计算的基础包。它具有有用的线性代数功能以及其他应用。

你可以使用numpy.linalg中的SVD获取完整的矩阵U,S和V。注意,S是对角矩阵,这意味着它的大多数元素都是0。这称为稀疏矩阵。为了节省空间,S作为奇异值的一维数组而不是完整的二维矩阵返回。

import numpy as np
from numpy.linalg import svd
# 定义二维矩阵
A = np.array([[4, 0], [3, -5]])
U, S, VT = svd(A)
print("Left Singular Vectors:")
print(U)
print("Singular Values:")
print(np.diag(S))
print("Right Singular Vectors:")
print(VT)
# 检查分解是否正确
# @ 表示矩阵乘法
print(U @ np.diag(S) @ VT)

3.2 scikit-learn中的Truncated SVD

在大多数常见的应用中,我们不希望找到完整的矩阵U,S和V。我们在降维和潜在语义分析中看到了这一点,还记得吗?

我们最终会修剪矩阵,所以为什么要首先找到完整的矩阵?

在这种情况下,最好使用sklearn.decomposition中的TruncatedSVD。你可以通过n_components参数指定所需的特征数量输出。n_components应严格小于输入矩阵中的特征数:

import numpy as np
from sklearn.decomposition import TruncatedSVD
A = np.array([[-1, 2, 0], [2, 0, -2], [0, -2, 1]])
print("Original Matrix:")
print(A)
svd = TruncatedSVD(n_components = 2)
A_transf = svd.fit_transform(A)
print("Singular values:")
print(svd.singular_values_)
print("Transformed Matrix after reducing to 2 features:")
print(A_transf)

3.3 scikit-learn中的Randomized SVD

Randomized SVD提供与Truncated SVD相同的结果,并且具有更快的计算时间。Truncated SVD使用ARPACK精确求解,但随机SVD使用了近似技术。

import numpy as np
from sklearn.utils.extmath import randomized_svd
A = np.array([[-1, 2, 0], [2, 0, -2], [0, -2, 1]])
u, s, vt = randomized_svd(A, n_components = 2)
print("Left Singular Vectors:")
print(u)
print("Singular Values:")
print(np.diag(s))
print("Right Singular Vectors:")
print(vt)

参考文献:

百度安全验证https://baijiahao.baidu.com/s?id=1643076332887222975&wfr=spider&for=pc

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

找不到msvcp140dll,无法继续执行代码的详细解决方法

在我们日常使用计算机进行各类工作任务的过程中,时常会遭遇一些突发的技术问题。比如,有时在运行某个重要程序或应用软件时,系统会突然弹出一个令人困扰的错误提示:“电脑提示找不到msvcp140.dll文件,因此无法继续执行…

Mysql基础(二)数据类型和约束

一 数据类型 讲解主要的数据类型,不面面俱到,后续遇到具体问题再查询补充扩展: 知识点的深度和广度以工作为导向 ① int float M : 表示显示宽度,M的取值范围是(0, 255)例如: int(5),当数据宽度小于5位的时候在数字前面需要用字符填满宽度说明&…

双击复制elementui表格某个单元格的数据

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、代码前言 在使用elementui的表格将数据展示出来时,我们想复制该表格区域对应的内容,但因为想复制的列不想太宽而数据太长导致数据省略,无法使用鼠标选择来全部复制到,所以想能不能实现一个双击该内容达到复制效果;…

VSCode 配置 C/C++ 环境

1 安装 VSCode 直接去官网(https://code.visualstudio.com/)下载并安装即可。 2 配置C/C编译环境 方案一 如果是在Windows,需要安装 MingW,可以去官网(https://sourceforge.net/projects/mingw-w64/)下载安装包。 注意安装路径不要出现中文。 打开 w…

声明式事务

文章目录 1.事务分类1.传统方式解决事务2.声明式事务 2.声明式事务案例1.需求分析2.解决方案分析3.数据表创建4.编写GoodsDao.java1.编写配置文件JdbcTemplate_ioc.xml2.单元测试 5.编写GoodsService.java6.配置事务管理器JdbcTemplate_ioc.xml7.进行测试 3.debug事务管理器Dat…

HubSpot流量转化:从访客到客户的转化策略

在当今数字化时代,企业营销获客的关键在于如何将网站访客转化为实际客户。作为HubSpot的合作伙伴,我们深知HubSpot软件在流量转化方面的强大功能。今天运营坛将带领大家深入探讨HubSpot流量转化的核心原理,并介绍如何利用个性化营销策略、构建…

实验2 NFS部署和配置

一、实训目的 1.了解NFS基本概念 2.实现NFS的配置和部署 二、实训准备 1.准备一台能够安装OpenStack的实验用计算机,建议使用VMware虚拟机。 2.该计算机应安装CentOS 7,建议采用CentOS 7.8版本。 3.准备两台虚拟机机(客户机和服务器机&…

在React Router 6中使用useRouteLoaderData钩子获取自定义路由信息

在 React Router 6 中怎么像vueRouter一样,可以在配置路由的时候,定义路由的元信息(附加信息)?答案是可以的。稍有些复杂。核心是通过为每个路由定义了一个 loader 函数,用于返回自定义的路由信息,然后通过useRouteLoaderData 钩子…

机器人实验室LAAS-CNRS介绍

一、LAAS-CNRS介绍 1、缩写介绍 同样的,给出英文缩写的全称,以便理解。这里的LAAS(Laboratory for Analysis and Architecture of Systems)指法国的系统分析与架构实验室,CNRS(Centre National de la Rec…

docker容器内ping外网能通,curl不通

排查原因是因为,在服务器上查看ifconfig,显示docker0的mtu是1500,网卡的mtu是1450。 mtu是指在网络通信中能够承载的最大数据包大小。一般情况下,docker的mtu默认为1500字节。 然而,不同的网络设备和网络配置可能会导…

Web3安全性:保护去中心化应用和用户的最佳实践

引言 随着Web3和去中心化应用(DApps)的迅速发展,我们进入了一个充满无限可能性的新世界。然而,这个数字天堂也伴随着一系列复杂的安全挑战。本文将深入探讨这些挑战,并提供一系列实用的安全建议,帮助你在W…

C++初阶学习第二弹——C++入门(下)

C入门(上):C初阶学习第一弹——C入门(上)-CSDN博客 目录 一、引用 1.1 引用的实质 1.2 引用的用法 二、函数重载 三、内敛函数 四、auto关键字 五、总结 前言: 在上面一章我们已经讲解了C的一些基本…

深度剖析图像处理—边缘检测

什么是边缘检测 边缘检测(Edge Detection)就是提取图像中的边缘点(Edge Point)。边缘点是与周围像素相比灰度值有阶跃变化或屋顶状变化的像素。边缘常存在于目标与背景之间、目标与目标之间、目标与其影子之间。 ​ 在图像处理和图像分析中,经常要用到边缘(Edge)、边…

【学习】对于加密接口、签名接口如何进行性能测试

随着科技的飞速发展,加密接口和签名接口在我们的日常生活中扮演着越来越重要的角色。从在线支付到信息安全,它们始终默默地守护着我们的数字世界。然而,随着应用场景的不断扩展,性能测试变得尤为重要。今天,让我们一起…

单例模式与反射创建对象

单例模式 饿汉式单例模式 单例模式,就是自己先把自己创建了,整个程序都只有这一个实例,别人都没有办法创建实例,因为他的构造方法是private的 一次性把全部都创建了 public class HungryMan {private static int [][] s new …

[lesson48]同名覆盖引发的问题

同名覆盖引发的问题 父子间的赋值兼容 子类对象可以当做父类对象使用(兼容性) 子类对象可以直接赋值给父类对象(<font color>兼容性)子类对象可以直接初始化父类对象父类指针可以直接指向子类对象父类引用可以直接引用子类对象 当使用父类指针(引用)指向子类对象时 子类…

安装zabbix server

目录 1、实验环境 2、yum 安装zabbix server 2.1 解决权限问题和放行流量 2.2 安装zabbix-server 1、实验环境 操作系统rhel8zabbix6.0TLS数据库mysql8.0.30IP地址192.168.81.131时间配置NTP时间服务器同步 2、yum 安装zabbix server 如果通过yum源安装&#xff0c;操作系…

《ElementUI 基础知识》png 图片扩展 icon用法

前言 UI 设计给的切图是 .png 格式。但想与 Element UI icon 用法类似&#xff0c;方案如下。 实现 步骤一 准备图片 步骤二 新建文件&#xff0c;可使用 CSS 预处理语言 styl 或 scss。 stylus 方式 文件 icon.styl /* 定义一个混合 */ cfgIcon(w, h) {display: inlin…

滑动窗口做题思路

什么是滑动窗口&#xff1f;就是一个队列,然后通过在这个队列中的各种移除和添加满足题目需求 题目: 209. 长度最小的子数组 - 力扣&#xff08;LeetCode&#xff09; class Solution {public int minSubArrayLen(int target, int[] nums) {int left 0;int sum 0;int n nu…

面向对象设计与分析40讲(25)中介模式、代理模式、门面模式、桥接模式、适配器模式

文章目录 门面模式代理模式中介模式 之所以把这几个模式放到一起写&#xff0c;是因为它们的界限比较模糊&#xff0c;结构上没有明显的差别&#xff0c;差别只是语义上。 这几种模式在结构上都类似&#xff1a; 代理将原本A–>C的直接调用变成&#xff1a; A–>B–>…