SVD是计算时代最为重要的矩阵分解方式之一,其提供了一种数值稳定的矩阵分解结果,可用于多种应用目的并保证矩阵分解的存在性。
一、问题
高维是在处理复杂系统中的数据时经常遇到的挑战,这些系统可能涉及大型测量数据集,包括音频、图像或视频数据。数据也可以从物理系统生成,例如来自大脑的神经记录、来自仿真或实验的流体速度测量值等。
SVD提供了一种系统的方法,可以根据主导模式确定高维数据的低维近似值。SVD在数值上是稳定的,并根据由数据内主要相关性定义的新坐标系提供数据的层次表示。此外,与特征分解不同,SVD可以保证对于任何矩阵都是存在的。
二、应用
(1)降低高维数据的维数。
(2)计算非方阵的伪逆。
(3)为欠定或超定矩阵方程组Ax = b提供解。
(4)对数据集去噪。
(5)对于刻画向量空间之间的线性映射的输入和输出几何关系也很重要。
三、基础
1、拉伸
比如,此刻我们手里有一个2×3的数据矩阵,设
(只有对角线上有元素),那么
。
我们可以看到这个S矩阵对D数据矩阵的轴方向做了个拉伸。
2、旋转
同样设,还是对2×3的数据矩阵
左乘,那么
。
R的作用是对D在坐标轴上按逆时针旋转角度。
四、定义
对于我们要分析的大型数据集,SVD存在唯一矩阵分解:
其中,和
是带有标准正交列的酉矩阵,
是一个对角元素为非负实数、非对角元素都为零的矩阵。
表示复共轭转置,对实值矩阵来说,这与常规转置
相同。
的对角线元素被称为奇异值,X矩阵的秩等于非零奇异值的个数。
由于和
是带有标准正交列的酉矩阵,结合上述基础知识,
,对数据集
进行线性变换,分解为旋转、拉伸、旋转。其中,
代表旋转,
(对角阵)代表拉伸,
代表旋转。在线性变换之前我们可以找到一对基,在线性变换之后还可以找到一对垂直的基。此处V为原始数据集的标准正交基,U为经过线性变换后的标准正交基。
如何求解SVD?
令,其实
是一个对角阵,其转置等于它本身。如果
是一个2×2的矩阵,则
。
言归正传,
同理,我们可以推导出
讨论的特征向量,我们写为以下形式
由上式,类比
我们可以将看作是
的特征向量,
则是
的特征值对角阵,那么
是
的特征是开方构成的对角阵。同理,
是
的特征向量。
求解流程:
--->
求的特征向量得到
,求
的特征向量得到
;--->
求或
的特征值,然后开方得到奇异值。--->
构成对角矩阵(以二阶为例)
五、代码
在matlab中,SVD的计算很简单:
X = randn(5,3);
[U,S,V] = svd(X);
对于非方阵X,经济SVD效率更高:
[Uhat,Shat,V]=svd(X,'econ'); %economy sized SVD
在Python中
import numpy as np
X = np.random.rand(5,3) %创建任意数据矩阵
U,S,V = np.linalg,svd(X,full_matrices = True) %满SVD
Uhat,Shat,Vhat = np.linalg.svd(X,full_matrices = False)%经济型SVD
在R中:
X <- replicate(3,rnoem(5))
s <- svd(X)
U <- s$u
S <- diag(s$d)
V <- s$v