矩阵的奇异值分解

奇异值分解(Singular Value Decomposition)简称SVD,主要作用是简化数据,提取信息。

SVD的公式: A m × n = U m × m Σ m × n V n × n T A_{m\times n}=U_{m\times m} \Sigma_{m\times n} V_{n\times n}^T Am×n=Um×mΣm×nVn×nT

这个公式中, U 和 V 都是正交矩阵,即:
U U T = U T U = E m × m V V T = V T V = E n × n UU^T=U^TU=E_{m\times m} \qquad VV^T=V^TV=E_{n\times n} UUT=UTU=Em×mVVT=VTV=En×n

原矩阵A是一个m行n列的矩阵,它被分解成了三个矩阵,分别是:

矩阵 别称 维度 计算方法
U U U 矩阵 A的左奇异向量 m行n列 列由 A A T AA^T AAT的特征向量构成,且特征向量为单位列向量
Σ \Sigma Σ 矩阵 A的奇异值 m行n列 对角元素来源于 A A T AA^T AAT A T A A^TA ATA的特征值的平方根,并且是按从大到小的顺序排列的
V V V 矩阵 A的右奇异向量 n行n列 列由 A T A A^TA ATA的特征向量构成,且特征向量为单位列向量

矩阵的奇异值分解_第1张图片

对矩阵进行SVD分解

import numpy as np
from numpy import linalg as la
from numpy import *

M = [[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]]

# 7x5
Data = mat(M)

U, Sigma, VT = linalg.svd(Data)

# 构建Sig矩阵,上面的Sigma只是Sig的对角元素
Signn = mat(np.diag(Sigma))   # 以Sigma为主对角线创建矩阵(5x5)
Sigmn = mat([[Sigma[0], 0, 0, 0, 0], [0, Sigma[1], 0, 0, 0], [0, 0, Sigma[2], 0, 0], [0, 0, 0, Sigma[3], 0], [0, 0, 0, 0, Sigma[4]], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]])


print(U[:, :Data.shape[1]] * Signn * VT)

print(U * Sigmn * VT)


'''
最后一个是公式的原始样式,但构建Sigmm没有Signn来得来得快
而且Sigmn的倒数x (x=Data.shape[0]-len(Sigma))行都是由0组成的,与U的最后x列相乘的结果也是0,所以截掉不影响最后结果
U[:, :Data.shape[1]] * Signn * VT 等于 U * Sigmn * VT
'''


创建矩阵的一些语法

import numpy as np


# 从0开始 取30个数 两两之间相差1
n = np.arange(0, 30, 1)
nn = n.reshape(6, 5)

# 相当于形成一个等差数列, 首项是0,尾项是4,一共9个
o = np.linspace(0, 4, 9)
o.resize(3, 3)

# reshape有返回值,不改变内存   resize无返回值,改变内存



a = np.ones((3, 4))  # 3行4列全是1
b = np.zeros((2, 4)) # 2行3列全是0
e = np.eye(3)        # 3维单位矩阵
x = [4, 5, 6]
y = np.diag(x)       # 以x为主对角线创建矩阵(3x3)
c = np.random.randint(0, 10, (4,3))  # 在0到10之间随机出数,创建4x3矩阵

# 水平拼接行数要相同,竖直拼接列数要相同
p = np.ones([2, 3], int)
pp = np.hstack([p, 2*p])  # 水平拼接
sp = np.vstack([a, b])    # 竖直拼接

你可能感兴趣的:(数学,线性代数,python,机器学习)