矩阵奇异值分解——信息压缩与降噪(open_cv)
博主今天上数学建模课,老师讲了矩阵的奇异值分解可以用来进行图片压缩。博主学线性代数的时候没有想到奇异值分解可以这么用,今天我们就来讨论一下矩阵的奇异值分解,来探索一下线性代数的本质。(博主太菜了,当初学线代没学到真东西)。
1、前言
如果要谈矩阵的奇异值分解,我们首先得搞清楚矩阵是什么。如果你不是很清楚的话可以先看一下这个视频:
https://www.bilibili.com/video/BV1ys411472E/?spm_id_from=333.999.0.0
如果你对矩阵的理解比较深刻,那我们就尝试回顾一下。
首先任何一个矩阵我们都可以把他们看作一个线性变换,他的作用就是将空间拉伸或压缩。我们不妨假设存在一个矩阵 A A A,它就代表了一个线性变换。我们进一步深入的讨论, A − 1 A^{-1} A−1就是这个线性变换的逆变换,即将拉伸或压缩的空间重新压缩或拉伸回去。
其次, A A A的列向量我们可以看作一组新基,注意这一组新基是在我们原来的坐标系下描述的。对一个向量 x x x,如果我对他进行线性变换,得到新向量 y = A x y=Ax y=Ax(注意线性变换是左乘)。 y y y是我们原来空间里向量经过空间的线性变换得到的同一个向量,此刻y的坐标依旧是有我们原来的坐标系描述的(即我们最初的空间的坐标系)。这个向量在新基下的表示,即用新空间的坐标系下表示这个向量,就是我们原来的向量 x x x,因为空间变化了。
OK,如果我们有一个新的线性变换 P P P,将我们原来的空间变化为新的空间。如果我们要在新的空间衡量我们之前提到线性变换,即用我们经过 P P P变换得到的新的视角来衡量我们在原来视角下看待的 A A A变换,我们把它取名为 B B B。首先我们给出结论 B = P − 1 A P B=P^{-1}AP B=P−1AP,然后我们尝试理解这个线性变换 B B B。从右向左看,首先我们对原来的空间进行 P P P变换得到新的空间,此时新空间里的向量依旧以我们原来的空间的坐标系衡量。然后我们进行 A A A变换,因为新空间依旧以原空间的坐标描述,所以 A A A变换依旧用原空间的坐标描述,不过这次变换的是新空间中的向量。最后我们做逆变换 P − 1 P^{-1} P−1,你可以理解为现在 A A A变换已经让新空间里的向量发生了变化,但是还是用我们原来空间的坐标系描述的,所以我们需要做逆变换转化为新的视角。
这里博主讲的可能不是很清楚,不过你只需记住 B = P − 1 A P B=P^{-1}AP B=P−1AP的具体含义,就可以方便接下来的阅读。
2、首先谈一谈特征值分解
我们谈矩阵的奇异值分解之前,先来简单的谈一谈特征值分解。首先给出公式,具体来说,给定一个方阵(n x n矩阵)A,特征值分解将其分解为以下形式:
A
=
P
Λ
P
−
1
A = PΛP⁻¹
A=PΛP−1
其中:
- A 是原始的方阵。
- P 是一个可逆矩阵,其列向量是特征向量。这些特征向量描述了线性变换A的不同方向。
- Λ(Lambda)是一个对角矩阵,其对角线上的元素是特征值。特征值表示了每个特征向量的重要性或缩放因子。
在理解上面这个公式之前,我们先回顾一下特征值和特征向量求法 A x = λ x Ax = \lambda x Ax=λx。这个求法说明,对向量 x x x进行线性变换 A A A后,向量 x x x的只改变了它的尺度,没有改变它的方向。向量 x x x就是线性变换 A A A的特征向量, λ \lambda λ就是线性变换 A A A的特征值。
有了以上的信息,就可以更方便的理解特征值分解的公式了。我们先将公式化为以下形式: P − A P = Λ P⁻AP = Λ P−AP=Λ。由我们在第一部分提到的知识可以知道, Λ Λ Λ是经过 P P P变换得到的新的视角来衡量我们在原来视角下看待的 A A A变换。因为 P P P是由 A A A的特征向量作为列向量得到的方阵,所以经过 P P P变换得到得到的新空间是以特征向量作为基。因为向量 x x x进行线性变换 A A A后,向量 x x x的只改变了它的尺度,没有改变它的方向,所以在新的坐标系下观察就是对基向量的尺度变换。所以最后我们在新视角下看到的线性变换是一个由对应特征值组成的对角阵 Λ Λ Λ。
总结以下,你可以把特征值分解理解为寻找线性变换的方向和在每一个方向上的变换尺度。
3、什么是矩阵的奇异值分解?
我们已经讲过了矩阵的特征值分解,这有利于我们更好的理解矩阵的奇异值分解。首先我们给出矩阵的奇异值分解的公式:
A
=
U
Σ
V
T
A = UΣV^T
A=UΣVT
以上的计算步骤为:
- 给定一个矩阵 A A A(m x n),其中 m 表示行数,n 表示列数。
- 计算 A A A 的转置矩阵 A T A^T AT。
- 计算 A A A 和 A T A^T AT 的乘积 A T A A^TA ATA,得到一个方阵(n x n)。
- 对方阵 A T A A^TA ATA进行特征值分解,得到特征值和特征向量。
- 特征值分解后,特征值的平方根即为矩阵 A A A 的奇异值(Singular Values)。通常按照从大到小的顺序排列奇异值。
- 根据奇异值,可以得到三个矩阵
U
U
U、
Σ
Σ
Σ(sigma)、
V
T
V^T
VT(V 的转置),使得
A
=
U
Σ
V
T
A = UΣV^T
A=UΣVT。
- U U U 是一个 m x m 的正交矩阵,其列向量是 A A T AA^T AAT 特征向量的归一化版本。
- Σ Σ Σ 是一个 m x n 的对角矩阵,对角线上的元素是按照奇异值降序排列的,其他元素为零。
- V T V^T VT 是一个 n x n 的正交矩阵,其列向量是 A T A A^TA ATA 特征向量的归一化版本。
所以我们可以这么理解,**矩阵的奇异值分解是当矩阵为非方阵时的特征值分解(因为特征值分解只能用于方阵)。本质上讲,奇异值分解是先将矩阵转化为方阵,在进行特征值分解。转化为方阵的方法就是计算 A A A 和 A T A^T AT 的乘积 A T A A^TA ATA。**我们之前讲过,矩阵 A A A可以看作线性变换。那么 A T A^T AT表示什么?博主比较菜,只能浅浅的解释一下,可能也不太对。**每一个空间都有一个对偶空间,A的转置就表示其在对偶空间下表示的线性变换。**那么 A A T AA^T AAT能表示什么特征呢?**我只能这么理解,一个行向量乘以它转置后得到的列向量表示它的模,这个模是一个一维的实数,比较好处理。那么一个非方阵乘以它转置后得到的非方阵得到的是一个新矩阵。这个矩阵是一个方阵,比较好处理,同时也反应了原来非方阵的特征。**说实话从单纯的从计算的角度更好理解。
由于 A A T AA^T AAT和 A T A A^TA ATA是实对称矩阵,所以它们的特征向量之间构成正交向量。我们把它们的特征向量归一化组成的矩阵为正交矩阵,依然能使得 A A T AA^T AAT分解成原来的对角矩阵矩阵。
由于博主水平不够,这里有两个问题无法从向量空间的形式解释,恳请巨佬解释:
- 为什么实对称矩阵的特征向量正交?
- 为什么可以使矩阵A化为对角阵的矩阵P,经过正交单位化变成Q后,仍能使A化为同样的对角阵?
我可以用计算的方式证明,但是难以用抽象的方式解释。
由于正交矩阵的列向量两两垂直,并且为单位向量,**说明 U U U和 V T V^T VT对应的线性变换为旋转,既不会改变空间尺度也不会拉伸和压缩空间,只是改变了方向,**根据前面的知识是可以理解的。
所以我们放上经典老图,奇异值分解可以看作旋转拉伸再旋转。
4、使用python模拟图片压缩的过程
①原理
由于 A = U Σ V T A = UΣV^T A=UΣVT,我们只需要将 Σ Σ Σ对角线保留前几个最大的奇异值,其余都置为0,就可以实现图像的压缩。
②代码
from PIL import Image
import numpy as np
# 打开图像
image = Image.open('output_gray.bmp')
# 将图像转换为NumPy数组
pixel_matrix = np.array(image)
# 进行奇异值分解
U, S, VT = np.linalg.svd(pixel_matrix)
# 初建全为0的528*532的初始矩阵
new_matrix = np.zeros((528, 532))
n = int(input("输入取前多少项:"))
# 相加前n个项
for i in range(n):
u = U[:,i].reshape(-1,1)
v = VT[i].reshape(1,-1)
new_matrix = S[i]*u*v + new_matrix
# 将像素矩阵转换为图像
image = Image.fromarray(new_matrix)
# 保存图像
if image.mode == "F":
image = image.convert('L')
image.save("output100.bmp")
# 显示图像
image.show()
③成果
原图:
取前5项:、
取前10项:
取前20项:
取前50项: