一、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}
U∈Rm×m,
Σ
∈
R
m
×
n
\Sigma \in R^{m\times n}
Σ∈Rm×n,
V
∈
R
n
×
n
V\in R^{n\times n}
V∈Rn×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}
ΣΣT∈Rm×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σ2⋱⋱⎦⎥⎥⎤m×m
Σ
T
Σ
=
[
σ
1
σ
2
⋱
⋱
]
n
×
n
\Sigma^T\Sigma= \begin{bmatrix} \sigma _1 \\ & \sigma _2 \\ & & \ddots \\ & & &\ddots \\ \end{bmatrix}_{n\times n}
ΣTΣ=⎣⎢⎢⎡σ1σ2⋱⋱⎦⎥⎥⎤n×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=[u1u2⋯um ]⎣⎢⎢⎡σ1σ2⋱⋱⎦⎥⎥⎤m×n⎣⎢⎢⎢⎡v1v2⋮vn⎦⎥⎥⎥⎤
进一步化简得到
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=σ1u1v1T+σ2u2v2T+⋯+σkukvkT
即:
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×nT≈Um×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/21/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/62/61/6⎦⎤ λ2=1;v2=⎣⎡−1/201/2⎦⎤ λ3=0;v3=⎣⎡1/3−1/31/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/62/61/6−1/201/21/3−1/31/3⎦⎤⎣⎡300010⎦⎤[1/21/21/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;
}
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