奇异值SVD分解的应用探究

  奇异值分解(Singular Value Decomposition,简称SVD)是在机器学习领域广泛应用的算法,它可以用于降维算法中的特征分解,使用SVD对矩阵进行分解, 能得到代表矩阵最明显变化的矩阵元素,是很多机器学习算法的基石。本文就对SVD的原理进行总结归纳,并举例说明其在图像处理中的应用。

一、特征值分解(EVD)

  在介绍SVD分解之前,要先了解一下特征值分解,即EVD分解。关于特征值和特征向量的含义及理解,可以参考这篇文章

1.特征值

  如果说一个向量 v v v是方阵 A n × n A_{n \times n} An×n的特征向量,将一定可以表示成下面的形式:
A v = λ v Av=\lambda v Av=λv
写成矩阵的形式为:
A P = [ λ 1 λ 2 ⋱ λ n ] P AP= \begin{bmatrix} \lambda _1 \\ & \lambda _2 \\ & & \ddots \\ & & & \lambda _n \\ \end{bmatrix} P AP= λ1λ2λn P

其中, P n × n P_{n\times n} Pn×n为特征向量 v i n × 1 {v_i}_{n\times 1} vin×1组成的矩阵:
P = [ v 1 v 2 ⋯ v n ] P=\begin{bmatrix} v_1 &v_2 & \cdots &v_n \end{bmatrix} P=[v1v2vn]

2.特征值分解过程

  如果矩阵 A A A是一个 m × m m\times m m×m的实对称矩阵(即 A = A T A=A^T A=AT ),那么它可以被分解成如下的形式:
A = Q Σ Q T = Q [ λ 1 λ 2 ⋱ λ m ] Q T A=Q\Sigma Q^T=Q \begin{bmatrix} \lambda _1 \\ & \lambda _2 \\ & & \ddots \\ & & & \lambda _m \\ \end{bmatrix} Q^T A=QΣQT=Q λ1λ2λm QT
其中 Q m × m Q_{m\times m} Qm×m为标准正交阵,即有 Q Q T = I , Q T Q = I QQ^T=I,Q^TQ=I QQT=I,QTQ=I, Σ \Sigma Σ为对角矩阵,维度为 m × m m\times m m×m λ i \lambda _i λi为特征值。

二、奇异值分解(SVD)

1.奇异值分解的形式

  特征值分解(EVD)是一个提取方阵特征很的方法,但是它只适用于方阵。而在机器学习的数据中,绝大部分的数据组成的矩阵都不是方阵,如一组数据有 m m m个样本,每个样本有 n n n个特征,往往这样的数据是样本的 m m m数量非常大,特征的 n n n数量有限,这样的数据组成的 矩阵 m × n m\times n m×n是无法进行特征值分解的。奇异值分解就是用来分解这种任意矩阵的分解方法。
  奇异值分解是将一个非零的实数矩阵 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

2.奇异值分解的方法

  为求解上述 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σ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=[u1u2um ] σ1 σ2 m×n v1v2vn
进一步化简得到
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

3.奇异值分解的价值

  这种近似的应用就是SVD分解的主要价值,可以用来数据的降维或者减少数据的存储空间。例如原先矩阵 A ∈ R m × n A\in R^{m\times n} ARm×n需要存储的数据为 m × n m\times n m×n个,而将其按照特征值分解后,假如只取第一个分量近似其矩阵的话,则存储的数据为 m + n + 1 m+n+1 m+n+1个,为保证其尽可能的近似于原矩阵,特征值可以选取前 k k k个,则其存储的数据为 k × ( m + n + 1 ) k\times (m+n+1) k×(m+n+1)个,显然大大减少了存储空间。

三、SVD分解在图像处理中的应用

3.1图像处理分析

  在图像处理中,往往要面对数据量比较大的图像。然而在实际的问题处理中,只需要提取图像的主要特征即可,不需要对其所有的数据进行处理,此时便需要提取主要的特征。例如下方的一张 700 × 500 × 3 700{\times}500{\times}3 700×500×3的图片,其数据量为 700 × 500 × 3 = 1050000 700{\times}500{\times}3=1050000 700×500×3=1050000个。对于这样的一张图片,其需要的存储空间为1050000个字节。运用SVD分解可以合理的减少其存储空间,从而大大简化后续的图像的其他操作的运算空间。下面介绍如何对一幅图像进行SVD分解,并得到其主要特征。
在这里插入图片描述

3.2SVD分解python代码

参考

import numpy as np
import matplotlib.image as mping
import matplotlib.pyplot as plt
import matplotlib as mpl


def image_svd(n, pic):
    a, b, c = np.linalg.svd(pic)#a,b,c= U,sigma,VT
    svd = np.zeros((a.shape[0], c.shape[1]))
    for i in range(0, n):
        svd[i, i] = b[i]
    img = np.matmul(a, svd)
    img = np.matmul(img, c)
    img[img >= 255] = 255
    img[0 >= img] = 0
    img = img.astype(np.uint8)
    return img


if __name__ == '__main__':
    mpl.rcParams['font.sans-serif'] = ['SimHei']
    mpl.rcParams['axes.unicode_minus'] = False

    path = './cat.jpg'
    img = mping.imread(path)
    print(img.shape)

    r = img[:, :, 0]
    g = img[:, :, 1]
    b = img[:, :, 2]
    plt.figure(figsize=(50, 100))
    for i in range(1, 31):
        r_img = image_svd(i, r)
        g_img = image_svd(i, g)
        b_img = image_svd(i, b)
        pic = np.stack([r_img, g_img, b_img], axis=2)
        print(i)
        plt.subplot(5, 6, i)
        plt.title("图像的SVD分解,使用前 %d 个特征值" % (i))
        plt.axis('off')
        plt.imshow(pic)
    plt.suptitle("图像的SVD分解")
    plt.subplots_adjust()
    plt.show()

3.3输出结果

在这里插入图片描述

  通过分析结果图可以发现,不同数量的奇异值返回的图像效果不同。如果只取前5个奇异值,返回的图像较模糊,返回前15个奇异值的图像,则能较好的表现原图像,而返回30个奇异值生成的图像,则几乎与原图像误差,根据不同的应用场合,可以合理的选取奇异值,这样的大大简化了原先700个奇异值的运算。

四、用Eigen库实现SVD分解

用Eigen库实现SVD分解

五、SVD分解的优点

1.内存少
  奇异值分解矩阵中 Σ \Sigma Σ里面的奇异值按从大到小的顺序排列,奇异值从大到小的顺序减小的特别快。在大多数情况下,前10%甚至1%的奇异值的和就占了全部的奇异值之和的99%以上。也就是说,剩下的90%甚至99%的奇异值几乎没有什么作用。因此,可以用前面 个大的奇异值来近似描述矩阵,于是奇异值分解公式可以写成如下:
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
其中 k k k是一个远远小于 m m m n n n 的数,右边的三个矩阵相乘的结果将会使一个接近 A A A的矩阵。如果 k k k越接近于 n n n ,则相乘的结果越接近于 A A A 。如果 k k k 的取值远远小于 n n n ,从计算机内存的角度来说,右边三个矩阵的存储内存要远远小于矩阵 A A A
2.SVD可以获取两个方向的主成分
  左奇异矩阵 U U U可以用于对行数的压缩;右奇异矩阵 V V V可以用于对列(即特征维度)的压缩。
3.滤波作用
  由于SVD分解最终是取得了多个权重较大的奇异值,因此其余较小的奇异值会被舍去。往往这些小的奇异值表征的是一些杂波,即不相关的干扰数据,运用SVD分解取得重要特征之后,恰好可以滤掉这些干扰数据,从而起到滤波的作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI Chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值