当前位置:   article > 正文

Eigen 矩阵的SVD分解_eigen svd

eigen svd

一、SVD分解原理

  奇异值分解是将一个非零的实数矩阵 A m × n A_{m \times n} Am×n分解成由三个是矩阵乘积形式的运算,即进行矩阵的因子分解:
A = U Σ V T A=U\Sigma V^T A=UΣVT
其中, U U U m × m m\times m m×m的单位正交阵, V V V n × n n\times n n×n的单位正交阵,即有 U U T = I , V V T = I UU^T=I,VV^T=I UUT=I,VVT=I Σ \Sigma Σ m × n m\times n m×n维的对角矩阵其对角线上的数值即为奇异值,并且按照降序排列,如:
Σ = [ σ 1 σ 2 ⋱ ⋱ ] m × n \Sigma= [σ1σ2]

_{m\times n} Σ=σ1 σ2 m×n
   U Σ V T U\Sigma V^T UΣVT为矩阵 A A A的奇异值分解, σ i \sqrt{\sigma _i} σi 为矩阵的奇异值, U U U称为左奇异矩阵, V V V称为右奇异矩阵。各矩阵的维度分别为 U ∈ R m × m U\in R^{m\times m} URm×m, Σ ∈ R m × n \Sigma \in R^{m\times n} ΣRm×n, V ∈ R n × n V\in R^{n\times n} VRn×n
  为求解上述 U U U, Σ \Sigma Σ, V V V,我们可以利用如下性质:
A A T = U Σ V T ( U Σ V T ) T = U Σ V T V Σ T U T = U Σ Σ T U T A T A = ( U Σ V T ) T U Σ V T = V Σ T U T U Σ V T = V Σ T Σ V T AA^T=U\Sigma V^T(U\Sigma V^T)^T=U\Sigma V^TV\Sigma ^TU^T=U\Sigma \Sigma^TU^T\\ A^TA=(U\Sigma V^T)^TU\Sigma V^T=V\Sigma ^TU^TU\Sigma V^T=V\Sigma ^T\Sigma V^T AAT=UΣVT(UΣVT)T=UΣVTVΣTUT=UΣΣTUTATA=(UΣVT)TUΣVT=VΣTUTUΣVT=VΣTΣVT
其中 Σ Σ T ∈ R m × m \Sigma \Sigma^T\in R^{m\times m} ΣΣTRm×m, Σ T Σ ∈ R n × n \Sigma^T \Sigma \in R^{n\times n} ΣTΣRn×n,即:

Σ Σ T = [ σ 1 σ 2 ⋱ ⋱ ] m × m \Sigma \Sigma^T= [σ1σ2]

_{m\times m} ΣΣT=σ1σ2m×m

Σ T Σ = [ σ 1 σ 2 ⋱ ⋱ ] n × n \Sigma^T\Sigma= [σ1σ2]

_{n\times n} ΣTΣ=σ1σ2n×n
可以看到 Σ Σ T \Sigma \Sigma^T ΣΣT Σ T Σ \Sigma^T \Sigma ΣTΣ的形式非常接近,进一步分析,我们可以发现 A A T AA^T AAT A T A A^TA ATA也是对称矩阵,那么就可以做特征值分解(EVD)。对 A A T AA^T AAT特征值分解,得到的特征矩阵即为 U U U 。对 A T A A^TA ATA特征值分解,得到的特征矩阵即为 V V V 。对 A A T AA^T AAT A T A A^TA ATA中的特征值开方,可以得到所有的奇异值。
由此可求得特征值为 σ 1 \sqrt{ \sigma _1} σ1 σ 2 \sqrt{ \sigma _2} σ2 、…、 σ k \sqrt{ \sigma _k} σk 。所以矩阵 A A A
A = U Σ V T = [ u 1 u 2 ⋯ u m   ] [ σ 1 σ 2 ⋱ ⋱ ] m × n [ v 1 v 2 ⋮ v n ] A=U\Sigma V^T= [u1u2um ]
[σ1σ2]
_{m\times n} [v1v2vn]
A=UΣVT=[u1u2um ]σ1 σ2 m×nv1v2vn

进一步化简得到
A = σ 1 u 1 v 1 T + σ 2 u 2 v 2 T + ⋯ + σ k u k v k T A=\sqrt{\sigma _1} u_1v_1^T+\sqrt{\sigma _2} u_2v_2^T+\cdots+\sqrt{\sigma _k} u_kv_k^T A=σ1 u1v1T+σ2 u2v2T++σk ukvkT
即:
A = λ 1 u 1 v 1 T + λ 2 u 2 v 2 T + ⋯ + λ k u k v k T A=\lambda _1 u_1v_1^T+\lambda_2 u_2v_2^T+\cdots+\lambda _k u_kv_k^T A=λ1u1v1T+λ2u2v2T++λkukvkT
矩阵 A A A被分解为 k k k个小矩阵,每个矩阵都是 λ \lambda λ乘以 u i v i T u_iv_i^T uiviT。此时可以看到,若 λ \lambda λ取值较大,其对应的矩阵在矩阵 A A A的占比也大,所以取以去前面主要的 λ \lambda λ来近似代表系统,近似的系统可以表示为:
A m × n = U m × m Σ m × n V n × n T ≈ U m × k Σ k × k V k × n T A_{m\times n}=U_{m\times m}\Sigma _{m\times n}V^T_{n\times n} \approx U_{m\times k}\Sigma _{k\times k}V^T_{k\times n} Am×n=Um×mΣm×nVn×nTUm×kΣk×kVk×nT

二、SVD分解举例

A = [ 0 1 1 1 1 0 ] A= [011110]

A=011110
求解 A T A A^TA ATA A T A A^TA ATA:
A T A = [ 0 1 1 1 1 0 ] [ 0 1 1 1 1 0 ] = [ 2 1 1 2 ] A^TA= [011110]
[011110]
= [2112]
ATA=[011110]011110=[2112]

A A T = [ 0 1 1 1 1 0 ] [ 0 1 1 1 1 0 ] = [ 1 1 0 1 2 1 0 1 1 ] AA^T= [011110]

[011110]
= [110121011]
AAT=011110[011110]=110121011
进而求 A T A A^TA ATA的特征值和特征向量:
λ 1 = 3 ; v 1 = [ 1 / 2 1 / 2 ]   λ 2 = 1 ; v 2 = [ 1 / 2 − 1 / 2 ] \lambda _1=3;v_1=[1/21/2]
\\ \ \\ \lambda _2=1;v_2=[1/21/2]
λ1=3;v1=[1/2 1/2 ] λ2=1;v2=[1/2 1/2 ]

A T A A^TA ATA的特征值和特征向量
λ 1 = 3 ; v 1 = [ 1 / 6 2 / 6 1 / 6 ]   λ 2 = 1 ; v 2 = [ − 1 / 2 0 1 / 2 ]   λ 3 = 0 ; v 3 = [ 1 / 3 − 1 / 3 1 / 3 ] \lambda _1=3;v_1=[1/62/61/6]
\\ \ \\ \lambda _2=1;v_2=[1/201/2]
\\ \ \\ \lambda _3=0;v_3=[1/31/31/3]
λ1=3;v1=1/6 2/6 1/6  λ2=1;v2=1/2 01/2  λ3=0;v3=1/3 1/3 1/3

利用 σ i = λ i \sigma _i=\sqrt {\lambda _i} σi=λi ,可得奇异值为 3 \sqrt 3 3 1 1 1。最终得 A A A的奇异值分解为:
A = U Σ V T = [ 1 / 6 − 1 / 2 1 / 3 2 / 6 0 − 1 / 3 1 / 6 1 / 2 1 / 3 ] [ 3 0 0 1 0 0 ] [ 1 / 2 1 / 2 1 / 2 − 1 / 2 ] A=U\Sigma V^T=[1/61/21/32/601/31/61/21/3]
[300100]
[1/21/21/21/2]
A=UΣVT=1/6 2/6 1/6 1/2 01/2 1/3 1/3 1/3 3 00010[1/2 1/2 1/2 1/2 ]

三、用Eigen库实现SVD分解

1.C++代码

#include <iostream>
#include <Eigen/Dense>

using namespace std;
using namespace Eigen;

int main()
{
	MatrixXf m = MatrixXf::Zero(3, 2);
	m << 0,1,1,1,1,0;
	cout << "Here is the matrix m:" << endl << m << endl;
	JacobiSVD<MatrixXf> svd(m, ComputeFullU | ComputeFullV);
	cout << "Its singular values are:" << endl << svd.singularValues() << endl;
	cout << "Its left singular vectors are the columns of the thin U matrix:" << endl << endl << svd.matrixU() << endl;
	cout << "Its right singular vectors are the columns of the thin V matrix:" << endl << endl << svd.matrixV() << endl;
	system("pause");
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

2.输出结果

Here is the matrix m:
0 1
1 1
1 0
Its singular values are:
1.73205
      1
Its left singular vectors are the columns of the thin U matrix:

   0.408248   -0.707107     0.57735
   0.816496 5.96046e-08    -0.57735
   0.408248    0.707107     0.57735
Its right singular vectors are the columns of the thin V matrix:

 0.707107  0.707107
 0.707107 -0.707107
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/78177
推荐阅读
相关标签
  

闽ICP备14008679号