什么是SVD分解,为什么要进行SVD分解
SVD分解就是将一个矩阵A,分解为如下的形式
A
=
U
Σ
V
T
A=U \Sigma V^T
A=UΣVT
分解的动机一般是为了减少矩阵
A
A
A的存储空间,如
A
A
A原本是(100,10)的矩阵,且假设
A
A
A实际上有很多信息是冗余的(不妨假设
A
A
A分解后的奇异值降序排列分别为
3
,
2
,
0.000...
,
.
.
.
3,2,0.000...,...
3,2,0.000...,...)那么我们只需要保留前面两个奇异值,就可以大大减小所需的存储空间:
A
=
U
Σ
V
T
=
A=U\Sigma V^T=
A=UΣVT=
(
u
1
u
2
…
u
n
)
(
3
2
…
)
(
v
1
T
…
v
m
T
)
\left( {u_{1}~~u_{2}~\ldots~~u_{n}} \right)~\left( {\begin{matrix} 3 & & \\ & 2 & \\ & ~ & \ldots \\ \end{matrix}~~~~~~~~~~~~~~} \right)~\begin{pmatrix} v_{1}^{T} \\ \ldots \\ v_{m}^{T} \\ \end{pmatrix}
(u1 u2 … un) ⎝
⎛32 … ⎠
⎞ ⎝
⎛v1T…vmT⎠
⎞
由于分解之后原矩阵可以被以下公式重建:
M
=
u
1
σ
1
v
1
T
+
…
+
u
p
σ
p
v
p
T
M = u_{1}\sigma_{1}v_{1}^{T} + \ldots + u_{p}\sigma_{p}v_{p}^{T}
M=u1σ1v1T+…+upσpvpT
若忽略掉k≥3的分量,则变成:
M
≈
u
1
σ
1
v
1
T
+
u
1
σ
2
v
2
T
M \approx u_{1}\sigma_{1}v_{1}^{T} + u_{1}\sigma_{2}v_{2}^{T}
M≈u1σ1v1T+u1σ2v2T
此时需要的存储空间为(100+1+10)*2 = 222 < 1000,从而减少了矩阵的存储空间,同时使得信息的丢失较小。
用 matlab 进行 SVD 分解
用 matlab 自带的 SVD 分解
> A=[4 0
3 -5]
A =
4 0
3 -5
> [U,S,V]=svd(A)
U =
0.4472 -0.8944
0.8944 0.4472
S =
6.3246 0
0 3.1623
V =
0.7071 -0.7071
-0.7071 -0.7071
>
用特征值分解 eig 来进行 svd 分解
是对矩阵
A
T
A
A^T A
ATA 进行特征值分解,特征值就是
Σ
2
Σ^2
Σ2 特征向量就组成了
V
V
V
这是因为:
若
A
=
U
Σ
V
T
A = U\Sigma V^{T}
A=UΣVT,则
A
T
A
=
V
Σ
T
U
T
U
Σ
V
T
A^{T}A = V\Sigma^{T}U^{T}U\Sigma V^{T}
ATA=VΣTUTUΣVT
又因为U,V是正交矩阵(
U
T
U
=
I
,
V
T
V
=
I
U^{T}U = I~,~V^{T}V = I
UTU=I , VTV=I),所以
A
T
A
=
V
Σ
T
Σ
V
T
=
V
Σ
2
V
T
A^{T}A = V\Sigma^{T}\Sigma V^{T} = V\Sigma^{2}V^{T}
ATA=VΣTΣVT=VΣ2VT,(这里
Σ
2
Σ^2
Σ2变成了一个对角方阵)
> A=[4 0
3 -5]
A =
4 0
3 -5
> C=A'*A
C =
25 -15
-15 25
%%%%%%%%%% 用 eig 进行特征值分解
> [V,D]=eig(C)
V =
-0.7071 -0.7071
0.7071 -0.7071
D =
40.0000 0
0 10.0000
%%%%%%%%%% Sigma 矩阵就是分解得到的对角阵的开方
> S=sqrt(D)
S =
6.3246 0
0 3.1623
%%%%%%%%%% 利用公式 A = U*S*V' 得到 U=A*V*S^(-1) 求矩阵U
%%%%%%%%%% (注意V,U都是正交矩阵,即V^T=V^(-1),U^T=U^(-1))
> U=A*V*S^(-1)
U =
-0.4472 -0.8944
-0.8944 0.4472
%%%%%%%%%% 还原回原来的矩阵
> A=U*S*V'
A =
4.0000 -0.0000
3.0000 -5.0000
>