一.奇异值分解定义
将一个非零的实矩阵,表示为如下三个实矩阵的乘积形式的运算,即进行矩阵的因子分解:
其中,是阶正交矩阵,是阶正交矩阵,是由降序排列的非负对角元素组成的矩形对角矩阵,用符号描述如下:
二.奇异值分解定理
任意的实矩阵都可以进行奇异值分解,这便是奇异值分解定理,下面构造性的证明
2.1求
由于是阶的矩阵,所以是一个实对称矩阵,故可以对其做正交分解使得:
其中,为n阶正交实矩阵,为阶对角阵,其对角线元素由的特征值构成,且这些特征值非负,下面简单说明,假设是的一个特征值,是对应的特征向量,那么
所以:
我们可以通过调整正交矩阵的排列损失使得对应的特征值形成降序排列:
接着计算奇异值:
假设的秩为,则的秩也为r,所以有:
相应的,我们令:
则:
同样地,我们令:
对其余部分填充0,使得:
2.2 求
接下来构造阶正交实对称矩阵,我们令:
令:
那么,如下关系就可以成立了:
接下来,再为扩充个标准正交向量,令为的一组正交基,并令:
所以:
三.紧奇异值分解与截断奇异值分解
3.1紧奇异值分解
上面第二节的分解方式称为完全奇异分解,大家可以发现,如果,我们完全没有必要对以及进行扩充,因为通过就可以无损还原,即:
这便是紧奇异分解
3.2截断奇异值分解
另外,我们也可以只取最大的个奇异值()对应的部分去近似,这便是截断奇异值分解,即:
这里,是一个的矩阵,由的前列得到,是矩阵,由的前列得到,是阶对角矩阵,由的前行列得到,下面通过对图像的SVD分解不同截断来加深理解,参考自>>>
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
plt.figure(figsize = (18,4))
im = plt.imread('./source/19_降维_svd_demo.jpg')
ks=[800,500,200,100,50,10]#分别截取不同的k
for idx,k in enumerate(ks):
svd_image = []
for ch in range(3):#注意,有RGB三个维度,每个维度对应一个矩阵做SVD分解
im_ch = im[:,:,ch]
U,D,VT = np.linalg.svd(im_ch)
imx = np.matmul(np.matmul(U[:,:k],np.diag(D[:k])),VT[:k,:])
# 将像素值约束到合理范围
imx = np.where(imx<0,0,imx)
imx = np.where(imx>255,255,imx)
svd_image.append(imx.astype('uint8'))
img = np.stack((svd_image[0], svd_image[1], svd_image[2]), 2)
plt.subplot(1,len(ks),idx+1)
plt.imshow(img)
plt.axis('off')
plt.title("k="+str(k))
显然,越小图片越模糊...,另外我们可以发现与的画质差距并不大,间接反映出奇异值从大到小,其实衰减很快,所以仅保留少许的即可还原一个不错的图片效果