特征分解
若方阵
A∈R n×n
,存在
v∈R n
、
λ∈R
,使得:
Av=λv
,则
v
称为
将所有的特征向量按列排成一个矩阵
特别地,若
奇异值分解(SVD)
若
奇异值分解可以用特征分解来解释,设
A=UΣV T
,则有:
-
AA T =UΣV T VΣU T =UΣ 2 U T
。可见,
A
的奇异值分解中的
-
A T A=VΣU T UΣV T =VΣ 2 V T
。可见,
A
的奇异值分解中的
SVD分解能用于数据压缩:
- 通过
A m×n =U m×m Σ m×n V T n×n
,求解
U
、
- 将
- 取前
k
个奇异值对应的
此时所需的存储量为 mk+k+nk=k(m+n+1) ,若 k<mnm+n+1 ,就能起到压缩的作用。实际上,对于图像这样的数据,当 k<mnm+n+1 时,也能保留视觉上的大部分信息。
import math
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
# 读取图片
X = np.array(Image.open(".\_data\son.jpg").convert('L'), 'f') # M*N
M = X.shape[0]
N = X.shape[1]
U, s, V = np.linalg.svd(X) # 奇异值分解(均已按 s 中的奇异值降序排列)
S = np.zeros((M, N))
S[0:M, 0:M] = np.diag(s)
plt.subplots(figsize=(20,10))
r, c, i = (5, 6, 1)
for k in range(M, 0, -math.ceil(M/(r*c))):
Uk = U[:, 0:k] # M*k
Sk = S[0:k, 0:k] # k*k
Vk = V[0:k, :] # k*N
X_ = Uk.dot(Sk).dot(Vk) # M*N
ratio = 1.0*k*(M+N+1)/(M*N)
plt.subplot(r, c, i, title='↓k=%d, ratio=%.1f' % (k, ratio)).axis('off')
plt.imshow(Image.fromarray(X_))
i+=1
plt.axis('off')
plt.show()