有一个矩阵M,可以分解为3个矩阵U、S、V,使得U x S x V等于M。U与V都是正交矩阵(乘以自身的转置矩阵结果为单位矩阵)。那么S矩阵主对角线上的元素称为矩阵M的奇异值,其它元素均为0。
"""奇异值分解"""import numpy as npM = np.mat('4 11 14; 8 7 -2')print(M)"""[[ 4 11 14] [ 8 7 -2]]"""U, sv, V = np.linalg.svd(M, full_matrices=False)print(U,U.shape)"""[[-0.9486833 -0.31622777] [-0.31622777 0.9486833 ]] (2, 2)"""print(sv,sv.shape)#[18.97366596 9.48683298] (2,)print(V,V.shape)"""[[-0.33333333 -0.66666667 -0.66666667] [ 0.66666667 0.33333333 -0.66666667]] (2, 3)"""print(U * U.T)"""[[ 1.00000000e+00 -7.27396709e-17] [-7.27396709e-17 1.00000000e+00]]"""print(V * V.T)"""[[1.00000000e+00 3.08395285e-16] [3.08395285e-16 1.00000000e+00]]"""S = np.diag(sv)print(S)"""[[18.97366596 0. ] [ 0. 9.48683298]]"""#生成原矩阵print(U * S * V)"""[[ 4. 11. 14.] [ 8. 7. -2.]]"""
案例:读取图片的亮度矩阵,提取奇异值与两个正交矩阵,保留部分奇异值,重新生成新的亮度矩阵,绘制图片。
import numpy as npimport scipy.misc as smimport matplotlib.pyplot as mp# 读取图片数据,True提取项目矩阵img = sm.imread('lily.jpg', True)print(img, img.shape)"""[[36.742 35.97 34.97 ... 54.102 54.33 51.042] [37.742 37.742 37.97 ... 54.102 53.33 51.042] [40.34 41.112 40.34 ... 51.732 51.846 50.857] ... [ 5.228 6.228 5.929 ... 71.666 68.954 68.242] [ 6.228 6.228 4.929 ... 73.182 72.182 71.242] [ 6.228 6.228 4.929 ... 69.709 71.709 74.242]] (512, 512)"""# 提取特征值eigvals, eigvecs = np.linalg.eig(np.mat(img))#逆向推到原矩阵eigvals[50:] = 0 #保留50个特征值img2 = eigvecs*np.diag(eigvals)*eigvecs.I# 绘制图片mp.figure('Lily', facecolor='lightgray')mp.subplot(221)mp.imshow(img,cmap='gray')mp.xticks([])mp.yticks([])mp.subplot(222)mp.imshow(img2.real,cmap='gray')mp.xticks([])mp.yticks([])#奇异值分解U,sv,V = np.linalg.svd(np.mat(img))sv[50:] = 0 #保留50个奇异值print(type(U),type(V))img3 = U*np.diag(sv)*Vmp.subplot(224)mp.imshow(img3.real,cmap='gray')mp.xticks([])mp.yticks([])mp.tight_layout()mp.show()