笔记 | SVD | 奇异值分解

SVD原理

SVD分解或者说极大协方差分析方法,主要针对于一般实矩阵的SVD运算。其中,一般实矩阵指行数和列数可以不等的实元素矩阵。

如下所示,假设 C C C m × n m \times n m×n阶矩阵,则存在一个 m × m m \times m m×m阶的列正交矩阵 U U U n × n n \times n n×n阶的列正交矩阵 V V V,使得:

C = U ( Σ 0 0 0 ) V T \mathbf{C}=\mathbf{U} \begin{pmatrix} \mathbf{\Sigma} & \mathbf{0} \\ \mathbf{0} & \mathbf{0} \end{pmatrix}\mathbf{V}^\mathbf{T} C=U(Σ000)VT

成立。其中, Σ \Sigma Σ
r r r 阶对角矩阵或者可以写成 Σ = d i a g ( σ 1 , σ 2 , σ 3 , . . . , σ r ) \Sigma=diag(\sigma_1,\sigma_2,\sigma_3,...,\sigma_r) Σ=diag(σ1,σ2,σ3,...,σr), ( r ⩽ min ⁡ { m , n } ) (r\leqslant\min\{m,n\}) (rmin{m,n}),且 σ 1 ⩾ σ 2 ⩾ ⋯ ⩾ σ r > 0 \sigma_1\geqslant\sigma_2\geqslant\cdots\geqslant\sigma_r>0 σ1σ2σr>0

以上称为实一般矩阵 C C C的奇异值分解, σ i ( i = 1 , 2 , 3 , . . . , r ) \sigma_i(i=1,2,3,...,r) σi(i=1,2,3,...,r)称为 C C C的奇异值, U U U的列向量称为左奇异向量, V V V的列向量称为右奇异向量。

对于正交矩阵,总是使空间旋转或反射,而对角矩阵总是使空间缩放。

本质上,对于一个矩阵 C C C的奇异值分解,实际转换为求取以上两个方阵 U U U V V V的特征值和特征向量的问题,特征值的正的平方根就是奇异值(对角矩阵 Σ \Sigma Σ的对角线元素),特征值对应的特征向量分别是左奇向量和右奇向量,下面会介绍相关的计算。

下面是SVD的一个分解示意图:

计算步骤

以下 C T C^T CT表示 C C C的转置

1、计算左奇异向量( U U U)。它等于 C C T CC^T CCT 的特征向量。

2、计算右奇异向量( V V V)。它等于 $C^TC $的特征向量。

3、计算 C C T CC^T CCT C T C C^TC CTC 的特征值的平方根。

以上计算过程可以在numpy函数中封装,可以直接进行调用:numpy.linalg.svd(a, full_matrices=True, compute_uv=True, hermitian=False)

当 a 是一个 2D 数组时, 且 full_matrices=False,然后将其分解为 u @ np.diag(s) @ vh = (u * s) @ vh ,其中 u vh 的 Hermitian 转置是具有正交列的二维数组,s 是 a 的奇异值的一维数组。

np.diag()表示提取对角线或构建对角数组。其中,返回的 U U U是左奇异向量, V h Vh Vh是右奇异向量, s s s是奇异值

GitHub上有博主提供了一个计算演示代码:

  • https://github.com/longhongc/SVD-python-implementation/blob/main/my_SVD.ipynb

SVD与EOF的关系

EOF实际上是SVD的特殊情况,对于SVD针对的是两个物理时空场,而EOF是一个物理时空场,如m表示空间点,n表示时间点,那么

利用计算得到的奇异向量和对应的时间系数可以恢复原来的数据,这里 X X X表示原始数据,即

X = U T X = UT X=UT
那么,同样的道理,根据原始数据和奇异向量也可以用来得到对应的时间序列,即

T = U T X T=U^TX T=UTX

SVD在气象海洋中的应用

在实际使用SVD分解在气象海洋数据时,步骤相对上述的计算有完善一点,具体为:

1、数据的预处理,需要输入两个距平变量场或者标准化变量场的交叉协方差矩阵A

2、计算A矩阵的左奇异向量U,即主成分模态,列向量对应EOF空间模态

3、计算A矩阵的右奇异向量V

4、根据左变量场及左奇异向量计算时间系数矩阵,即 P C = U X PC=U^X PC=UX,这里 X X X表示原始场

5、计算每对奇异向量的方程贡献和累计方差贡献

6、显著性检验

SVD的物理意义

SVD在气象、海洋实际应用中往往是对两个物理量场做分解的。其原理是要求两个场的展开系数的协方差最大。比如对某海域的海表温度(SST)和海表气压(SLP)做SVD分析,是为了提取出这两个变量之间相互耦合(协方差矩阵)的最重要的空间模态和时间演变信息。

其中的空间模态就是SVD得到的奇异向量(左右奇异向量分别对应SST和SLP),它们有各自的时间系数表征了时间演变特征。注意SVD方法输入的两个变量场的空间点数可以不相同(m1, m2),但是两个变量的时间长度必须相同(n)

python中的svd分解

在python中,不仅numpy提供了svd函数,scipy也提供了可调用的函数:scipy.linalg.svdscipy.sparse.linalg.svds.

以上scipy提高的函数中,当输入矩阵是密集矩阵且需要所有奇异值时,第一种方法通常更有效。而当输入矩阵 X 是稀疏矩阵或只需要最大奇异值时,第二种方法通常非常有效。

scipy.linalg.svd快速的原因是以分配大量内存用于临时计算为代价,随维数的增加而变化。

应用个例

对于热带垂直速度 ω \omega ω,可以通过svd将其它被分解为经验垂直结构函数(EOF)及其相关的主成分(PC),代表空间和时间变率。

其中,第一模态和第二模态分别可以表示第一斜压和第二斜压模,第一斜压模态与深对流云有关,第二斜压模态与层状云有关。

参考

  • https://mp.weixin.qq.com/s/SBwRI1vg3h-wqjphMsHbGA

  • https://numpy.org/doc/2.2/reference/generated/numpy.linalg.svd.html

  • https://fa.bianp.net/blog/2012/singular-value-decomposition-in-scipy/

  • https://github.com/longhongc/SVD-python-implementation

  • https://pyoceans.github.io/sea-py/

  • https://github.com/mathildejutras/mtm-svd-python/tree/master

  • 上课课件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简朴-ocean

继续进步

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值