1. SVD
1.1 分解
如下图,一个矩阵可以分解为两个方阵和一个对角矩阵的乘积:
C = m * n;u = m * m;sigma = m * n;v' = n * n
1.2 奇异值
sigma是一个对角矩阵,但通常不是方阵。sigma的对角元素被称为奇异值,与特征值类似。因此与PCA类似,我们可以取sigma中最大的k个,来简化数据:
u' = m * k;sigma' = k * k;v'' = k * v
1.3 重构C矩阵
利用新的三个矩阵u',sigma',v''相乘仍然得到一个m * n的矩阵。如果你选择的k个奇异值所占的所有奇异值比例足够大,那么新得到的m * n的矩阵将与C非常接近。
2. SVD实践 - 矩阵压缩
# -*- coding: utf-8 -*-
"""
arr =
[[0, 0, 0, 2, 2],
[0, 0, 0, 3, 3],
[0, 0, 0, 1, 1],
[1, 1, 1, 0, 0],
[2, 2, 2, 0, 0],
[5, 5, 5, 0, 0],
[1, 1, 1, 0, 0]]
u = 7 * 7
sigma = 7 * 5, 只返回了对角元素, 其余0元素被省略
V = 5 * 5
"""
import numpy as np
arr = np.array([[0, 0, 0, 2, 2], [0, 0, 0, 3, 3], [0, 0, 0, 1, 1],
[1, 1, 1, 0, 0], [2, 2, 2, 0, 0], [5, 5, 5, 0, 0], [1, 1, 1, 0, 0]])
# 1. 分解
u, sigma, v = np.linalg.svd(arr)
# 2. 重构
new_arr = np.mat(u[:, 0:2]) * np.mat(np.diag(sigma[0:2])) * np.mat(v[0:2, :])
new_arr与arr非常接近,几乎相等。这其实是类似于图像压缩,只保留图像分解后的两个方阵和一个对角阵的对角元素,就可以恢复原图像。