svd分解:
中间的矩阵为对角矩阵
python实现:
from numpy import mat, linalg
def main():
data = mat([[1, 1, 1, 0, 0],
[2, 2, 2, 0, 0],
[1, 1, 1, 0, 0],
[5, 5, 5, 0, 0],
[1, 1, 0, 2, 2],
[0, 0, 0, 3, 3],
[0, 0, 0, 1, 1]])
u, sigma, v_t = linalg.svd(data)
print(u)
print()
print(sigma)
print()
print(v_t)
sigma_mat = mat([[sigma[0], 0, 0], [0, sigma[1], 0], [0, 0, sigma[2]]])
new_data = u[:, :3] * sigma_mat * v_t[:3, :]
print()
print(new_data)
if __name__ == '__main__':
main()
输出:
[[-1.77939726e-01 -1.64228493e-02 1.80501685e-02 9.27047702e-01
3.74969832e-02 -3.11055905e-01 -1.00810187e-01]
[-3.55879451e-01 -3.28456986e-02 3.61003369e-02 3.29089057e-02
-9.11915822e-01 1.95688838e-01 -3.96847175e-04]
[-1.77939726e-01 -1.64228493e-02 1.80501685e-02 2.74228495e-01
2.65720721e-01 8.63025454e-01 2.77705297e-01]
[-8.89698628e-01 -8.21142464e-02 9.02508423e-02 -2.53418802e-01
3.04122788e-01 -1.88669445e-01 -3.52202831e-02]
[-1.33954753e-01 5.33527340e-01 -8.35107599e-01 5.55111512e-16
-1.58727198e-16 -9.22872889e-16 -3.34801631e-16]
[-2.15749771e-02 7.97677135e-01 5.13074760e-01 -2.77858188e-03
1.97619258e-02 9.19461850e-02 -3.01906682e-01]
[-7.19165903e-03 2.65892378e-01 1.71024920e-01 8.33574565e-03
-5.92857774e-02 -2.75838555e-01 9.05720047e-01]]
[9.72140007e+00 5.29397912e+00 6.84226362e-01 1.33460130e-15
2.63935250e-31]
[[-5.81200877e-01 -5.81200877e-01 -5.67421508e-01 -3.49564973e-02
-3.49564973e-02]
[ 4.61260083e-03 4.61260083e-03 -9.61674228e-02 7.03814349e-01
7.03814349e-01]
[-4.02721076e-01 -4.02721076e-01 8.17792552e-01 5.85098794e-02
5.85098794e-02]
[-7.07106781e-01 7.07106781e-01 1.66533454e-16 3.46944695e-17
6.93889390e-18]
[ 0.00000000e+00 2.60253608e-17 -2.36845203e-17 -7.07106781e-01
7.07106781e-01]]
[[ 1.00000000e+00 1.00000000e+00 1.00000000e+00 1.94093903e-16
1.74795104e-16]
[ 2.00000000e+00 2.00000000e+00 2.00000000e+00 6.25868351e-17
2.39892377e-17]
[ 1.00000000e+00 1.00000000e+00 1.00000000e+00 -6.28062537e-16
-6.47361335e-16]
[ 5.00000000e+00 5.00000000e+00 5.00000000e+00 1.14233797e-16
1.75229637e-17]
[ 1.00000000e+00 1.00000000e+00 -1.80048454e-16 2.00000000e+00
2.00000000e+00]
[-5.06382306e-17 3.15500161e-16 -4.14592885e-16 3.00000000e+00
3.00000000e+00]
[-1.01278813e-18 1.18720378e-16 -1.89063042e-16 1.00000000e+00
1.00000000e+00]]
发现第二个矩阵(奇异值)中前3比较大,后2都是极小值,因此可以使用前三进行重构,得到接近原矩阵的矩阵