奇异值分解

有一个矩阵M,可以分解为3个矩阵U、S、V,使得U x S x V等于M。U与V都是正交矩阵(乘以自身的转置矩阵结果为单位矩阵)。那么S矩阵主对角线上的元素称为矩阵M的奇异值,其它元素均为0。

"""
奇异值分解
"""

import numpy as np
M = 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 np
import scipy.misc as sm
import 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)*V
mp.subplot(224)
mp.imshow(img3.real,cmap='gray')
mp.xticks([])
mp.yticks([])

mp.tight_layout()
mp.show()

 

posted @ 2019-09-09 10:10  maplethefox  阅读(545)  评论(0编辑  收藏  举报