Eigen 矩阵的SVD分解

矩阵的SVD分解

  • 一、SVD分解原理
  • 二、SVD分解举例
  • 三、用Eigen库实现SVD分解
    • 1.C++代码
    • 2.输出结果

一、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= \begin{bmatrix} \sqrt{ \sigma _1} \\ & \sqrt{\sigma _2} \\ & & \ddots \\ & & &\ddots \\ \end{bmatrix}_{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= \begin{bmatrix} \sigma _1 \\ & \sigma _2 \\ & & \ddots \\ & & &\ddots \\ \end{bmatrix}_{m\times m} ΣΣT=σ1σ2m×m

Σ T Σ = [ σ 1 σ 2 ⋱ ⋱ ] n × n \Sigma^T\Sigma= \begin{bmatrix} \sigma _1 \\ & \sigma _2 \\ & & \ddots \\ & & &\ddots \\ \end{bmatrix}_{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= \begin{bmatrix} u_1 &u_2&\cdots&u_m\ \end{bmatrix}\begin{bmatrix} \sqrt{\sigma _1} \\ &\sqrt{ \sigma _2} \\ & & \ddots \\ & & &\ddots \\ \end{bmatrix}_{m\times n} \begin{bmatrix} v_1 \\ v_2 \\ \vdots \\ v_n \\ \end{bmatrix} 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= \begin{bmatrix} 0 &1 \\ 1 & 1 \\ 1 & 0 \\ \end{bmatrix} 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= \begin{bmatrix} 0 &1&1 \\ 1 & 1&0 \\ \end{bmatrix} \begin{bmatrix} 0 &1 \\ 1 & 1 \\ 1 & 0 \\ \end{bmatrix}= \begin{bmatrix} 2 &1 \\ 1 & 2 \\ \end{bmatrix} 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= \begin{bmatrix} 0 &1 \\ 1 & 1 \\ 1 & 0 \\ \end{bmatrix}\begin{bmatrix} 0 &1&1 \\ 1 & 1&0 \\ \end{bmatrix}= \begin{bmatrix} 1 &1&0 \\ 1 &2&1 \\ 0 &1&1 \\ \end{bmatrix} 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=\begin{bmatrix} 1/\sqrt 2 \\ 1/\sqrt 2 \\ \end{bmatrix}\\ \ \\ \lambda _2=1;v_2=\begin{bmatrix} 1/\sqrt 2 \\ -1/\sqrt 2 \\ \end{bmatrix} λ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=\begin{bmatrix} 1/\sqrt 6\\ 2/\sqrt 6 \\ 1/\sqrt 6 \\ \end{bmatrix}\\ \ \\ \lambda _2=1;v_2=\begin{bmatrix} -1/\sqrt 2 \\ 0 \\ 1/\sqrt 2 \end{bmatrix}\\ \ \\ \lambda _3=0;v_3=\begin{bmatrix} 1/\sqrt 3 \\ -1/\sqrt 3 \\ 1/\sqrt 3 \end{bmatrix} λ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=\begin{bmatrix} 1/\sqrt 6&-1/\sqrt 2&1/\sqrt 3\\ 2/\sqrt 6&0&-1/\sqrt 3 \\ 1/\sqrt 6&1/\sqrt 2&1/\sqrt 3 \\ \end{bmatrix} \begin{bmatrix} \sqrt 3&0\\ 0&1 \\ 0&0 \\ \end{bmatrix} \begin{bmatrix} 1/\sqrt 2&1/\sqrt 2\\ 1/\sqrt 2&-1/\sqrt 2\\ \end{bmatrix} 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 
#include 

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;
}

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

你可能感兴趣的:(Eigen,SVD,Eigen)