📜  奇异值分解 (SVD)

📅  最后修改于: 2022-05-13 01:54:41.932000             🧑  作者: Mango

奇异值分解 (SVD)

矩阵的奇异值分解 (SVD) 是将该矩阵分解为三个矩阵。它具有一些有趣的代数性质,并传达了有关线性变换的重要几何和理论见解。它在数据科学中也有一些重要的应用。在本文中,我将尝试解释 SVD 背后的数学直觉及其几何意义。

SVD背后的数学

mxn 矩阵 A 的 SVD 由以下公式给出:

A = UWV^{T}



在哪里:

  • U: mxn矩阵的正交特征向量AA^{T}           .
  • V T :包含 A^{T}A 的正交特征向量的nxn矩阵的转置。
  • W:奇异值的 nxn对角矩阵,奇异值是特征值的平方根A^{T}A       .

例子

  • 求矩阵 A = 的 SVD \begin{bmatrix} 3& 3 & 2 \\ 2&  3& -2 \end{bmatrix}
  • 要计算 SVD,首先,我们需要通过找到 AA^{T} 的特征值来计算奇异值。

A \cdot A^{T} =\begin{bmatrix} 3& 3 & 2 \\ 2&  3& -2 \end{bmatrix} \cdot \begin{bmatrix} 3 & 2 \\ 3 & 3 \\ 2 & -2 \end{bmatrix} = \begin{bmatrix} 17 & 8\\ 8 & 17 \end{bmatrix}

  • 上述矩阵的特征方程为:

W - \lambda I =0 \\ A A^{T} - \lambda I =0

\lambda^{2} - 34 \lambda + 225 =0



= (\lambda-25)(\lambda -9)

所以我们的奇异值是: \sigma_1 = 5 \, ; \sigma_2 = 3

  • 现在,我们找到合适的奇异向量,即正交组为T A的特征向量的T A的特征值是25,9和0,因为A T A是对称的,我们知道,特征向量将是正交的。

为了\lambda =25,

AA^{T} - 25 \cdot I  = \begin{bmatrix} -12 &  12& 2\\ 12 &  -12 & -2\\ 2&  -2 & -17 \end{bmatrix}

这可以是行减少到:

\begin{bmatrix} 1&  -1& 0 \\ 0&  0&  1\\ 0&  0& 0 \end{bmatrix}



在它的方向上的单位向量是:

v_1 = \begin{bmatrix} \frac{1}{\sqrt{2}}\\ \frac{1}{\sqrt{2}}\\ 0 \end{bmatrix}

类似地,对于 λ = 9,特征向量为:

v_2 =\begin{bmatrix} \frac{1}{\sqrt{18}}\\ \frac{-1}{\sqrt{18}}\\ \frac{4}{\sqrt{18}}\\ \end{bmatrix}

对于第三个特征向量,我们可以使用它垂直于 v1 和 v2 的性质,使得:



v_1^{T} v_3 =0 \\ v_2^{T} v_3 =0

求解上述方程以生成第三个特征向量

v_3 = \begin{bmatrix} a\\ b\\ c \end{bmatrix} = \begin{bmatrix} a\\ -a \\ -a/2 \end{bmatrix} = \begin{bmatrix} \frac{2}{3}\\ \frac{-2}{3}\\ \frac{-1}{3} \end{bmatrix}

现在,我们使用公式 u_i = \frac{1}{\sigma} A v_i 计算 U,这给出了 U = \begin{bmatrix} \frac{1}{\sqrt{2}} &\frac{1}{\sqrt{2}} \\ \frac{1}{\sqrt{2}}& \frac{-1}{\sqrt{2}} \end{bmatrix}     .因此,我们最终的 SVD 方程变为:

A =A = \begin{bmatrix} \frac{1}{\sqrt{2}} &\frac{1}{\sqrt{2}} \\ \frac{1}{\sqrt{2}}& \frac{-1}{\sqrt{2}} \end{bmatrix} \begin{bmatrix} 5 &  0& 0 \\ 0 &  3& 0 \end{bmatrix} \begin{bmatrix} \frac{1}{\sqrt{2}}& \frac{1}{\sqrt{2}} &0 \\ \frac{1}{\sqrt{18}}& \frac{-1}{\sqrt{18}} & \frac{4}{\sqrt{18}}\\ \frac{2}{3}&\frac{-2}{3}  &\frac{1}{3} \end{bmatrix}



应用

  • Pseudo-inverse的计算: Psuedo inverse或Moore-Penrose inverse是对可能不可逆的矩阵逆(如低秩矩阵)的推广。如果矩阵是可逆的,那么它的逆将等于伪逆,但对于不可逆的矩阵存在伪逆。它由 A +表示。

假设,我们需要计算矩阵 M 的伪逆:

然后,M 的 SVD 可以表示为:

M = U W V^{T}

两边乘以 M^{-1}。

M^{-1} M = M^{-1} U W V^{T}

I= M^{-1} U W V^{T}

两边乘以V:

V = M^{-1} U W V^{T}V

V = M^{-1} U W



乘以 W^{-1}。由于 W 是奇异矩阵,W 的逆矩阵 = diag(a_1, a_2, a_3, ... a_n)^{-1}            = diag(1/a_1, 1/a_2, 1/a_3, ... 1/a_n)

V W^{-1} =  M^{-1} U W W^{-1}

V W^{-1} = M^{-1} U

乘以U^T

V W^{-1} U^{T} = M^{-1} U U^{T}

V W^{-1} U^{T} = M^{-1} = M^{+}

上面的方程给出了伪逆。

  • 求解一组齐次线性方程 (Mx =b):如果 b=0,则计算 SVD 并取与奇异值(在W 中)等于 0相关联的 V T 的任何列。

如果b \neq 0           , Mx =b

乘以M^{-1}

M^{-1} M x = M^{-1} b



x = M^{-1} b

从伪逆,我们知道M^{-1} = V W^{-1} U^{T}

因此,

x = V W^{-1} U^{T} b

  • 秩、范围和空空间:
    • 矩阵 M 的秩可以通过非零奇异值的数量从 SVD 计算出来。
    • 矩阵 M 的范围是 U 的左奇异向量对应于非零奇异值。
    • 矩阵 M 的零空间是对应于归零奇异值的 V 的右奇异向量。

M = U W V^{T}

  • 曲线拟合问题:奇异值分解可用于最小化最小二乘误差。它使用伪逆来近似它。
  • 除上述应用外,奇异值分解和伪逆也可用于数字信号处理和图像处理

执行

  • 在这段代码中,我们将尝试使用 Numpy 和 Scipy 计算奇异值分解。我们将计算 SVD,并执行伪逆。最后,我们可以应用 SVD 来压缩图像
Python3
# Imports
  
import numpy as np
from scipy.linalg import svd
  
"""
Singular Value Decomposition
"""
# define a matrix
X = np.array([[3, 3, 2], [2,3,-2]])
print(X)
# perform SVD
U, singular, V_transpose = svd(X)
# print different components
print("U: ",U)
print("Singular array",s)
print("V^{T}",V_transpose)
  
"""
Calculate Pseudo inverse
"""
# Onverse of singular matrix is just the reciprocal of each element
singular_inv = 1.0 / singular
# create m x n matrix of zeroes and put singular values in it
s_inv = np.zeros(A.shape)
s_inv[0][0]= singular_inv[0]
s_inv[1][1] =singular_inv[1]
# calculate pseudoinverse
M = np.dot(np.dot(V_transpose.T,s_inv.T),U.T)
print(M)
  
"""
SVD on image compression
"""
  
import numpy as np
import matplotlib.pyplot as plt
from skimage import data
from skimage.color import rgb2gray
  
cat = data.chelsea()
plt.imshow(cat)
# convert to grayscale
gray_cat = rgb2gray(cat)
  
# calculate the SVD and plot the image
U,S,V_T = svd(gray_cat, full_matrices=False)
S = np.diag(S)
fig, ax = plt.subplots(5, 2, figsize=(8, 20))
  
curr_fig=0
for r in [5, 10, 70, 100, 200]:
  cat_approx =U[:, :r] @  S[0:r, :r] @ V_T[:r, :]
  ax[curr_fig][0].imshow(256-cat_approx)
  ax[curr_fig][0].set_title("k = "+str(r))
  ax[curr_fig,0].axis('off')
  ax[curr_fig][1].set_title("Original Image")
  ax[curr_fig][1].imshow(gray_cat)
  ax[curr_fig,1].axis('off')
  curr_fig +=1
plt.show()


输出:

[[ 3  3  2]
 [ 2  3 -2]]
---------------------------
U:  [[-0.7815437 -0.6238505]
 [-0.6238505  0.7815437]]
---------------------------
Singular array [5.54801894 2.86696457]
---------------------------
V^{T} [[-0.64749817 -0.7599438  -0.05684667]
 [-0.10759258  0.16501062 -0.9804057 ]
 [-0.75443354  0.62869461  0.18860838]]
--------------------------
# Inverse 
array([[ 0.11462451,  0.04347826],
       [ 0.07114625,  0.13043478],
       [ 0.22134387, -0.26086957]])
---------------------------

原始与 SVD k 图像

参考:

  • SVD 示例