【机器学习中的矩阵分解】LU分解、QR分解、SVD分解

本文介绍了矩阵分解中的LU、QR和SVD三种方法。LU分解用于求解线性方程组、计算矩阵逆和行列式;QR分解在数值线性代数中有广泛应用;SVD则在图像压缩和手写体识别中展示出强大能力。通过Python代码示例展示了如何进行LU分解,并探讨了SVD在图像压缩中的应用,包括图像的复原和压缩率计算。
摘要由CSDN通过智能技术生成

学习总结

一、三角分解(LU分解)

1.1 高斯消元和LU分解

三角分解 (LU分解) 是一种矩阵分解的方法, 它将一个矩阵分解为一个下三角矩阵(L)和一个上三角矩阵 (U) 的乘积。这种分解对于解决线性方程组、求矩阵的逆以及计算矩阵的行列式等问题非常有用。

LU分解的定义
给定一个 n × n n \times n n×n 的矩阵 A A A, 如果存在一个下三角矩阵 L L L 和一个上三角矩阵 U U U, 使得 A = L U A=L U A=LU, 则称矩阵 A A A 可以被 LU分解。

  • 下三角矩阵 L L L : 主对角线上的元素都是 1 , 即 L i i = 1 L_{i i}=1 Lii=1, 且 L L L 的所有元素都满足 L i j = 0 L_{i j}=0 Lij=0 对于所有 i < j i<j i<j
  • 上三角矩阵 U U U : 主对角线以下的元素都是 0 , 即 U i j = 0 U_{i j}=0 Uij=0 对于所有 i > j i>j i>j

1.2 LU分解的用途

  1. 求解线性方程组:如果有线性方程组 A x = b A x=b Ax=b, 通过 LU分解可以将其转化为两个三角方程组, 先解 L y = b L y=b Ly=b, 再解 U x = y U x=y Ux=y, 这样的分解使得计算更简单。
  2. 计算矩阵的逆: 如果需要计算矩阵 A A A 的逆, 可以先对 A A A 进行LU分解, 然后利用三角矩阵的逆的性质来计算。
  3. 计算行列式: 矩阵的行列式可以通过其 LU分解的三角矩阵的行列式来计算。

1.3 LU分解python代码

下面是一个使用Python和NumPy库进行LU分解的例子。NumPy库提供了一个名为lu的函数,它可以用来计算矩阵的LU分解。
用Python代码来进行LU分解:

import numpy as np
from scipy.linalg import lu

# 定义一个需要进行LU分解的矩阵A
A = np.array([[2, 3], [1, 4]])

# 使用scipy的lu函数进行LU分解
P, L, U = lu(A)

print("P (置换矩阵):")
print(P)
print("L (下三角矩阵):")
print(L)
print("U (上三角矩阵):")
print(U)

# 验证LU分解:PA = LU
PA = np.dot(P, A)
LU = np.dot(L, U)

print("\n验证LU分解:")
print("PA:\n", PA)
print("LU:\n", LU)

二、QR分解

2.1 Schmid 正交化

2.2 使用 Schmid 施密特正交化过程求 QR 分解

2.3 QR分解的栗子

三、SVD分解

3.1 SVD定义

Singular Value Decomposition。
SVD是一种基于矩阵分解的,提取信息的强大工具,能够发现数据中的潜在模式。应用领域比如:

  • 隐性语义分析 (Latent Semantic Analysis, LSA) 或隐性语义索引 (Latent Semantic Indexing, LSI);
  • 推荐系统 (Recommender system),可以说是最有价值的应用点(不过现在推荐系统很多都是基于深度学习模型);
  • 矩阵形式数据(主要是图像数据)的压缩。

3.2 SVD基本理论

(1)线性变换

以2×2的线性变换矩阵为例,现在有一个对角矩阵
M = [ 3 0 0 1 ] M=\left[\begin{array}{ll}3 & 0 \\ 0 & 1\end{array}\right] M=[3001]

对角矩阵M是将二维平面上的点(x,y)经过线性变换到另一个点的变换矩阵(变换效果:平面沿着x水平方向进行3倍拉伸,垂直方向没变化): [ 3 0 0 1 ] [ x y ] = [ 3 x y ] \left[\begin{array}{ll} 3 & 0 \\ 0 & 1 \end{array}\right]\left[\begin{array}{l} x \\ y \end{array}\right]=\left[\begin{array}{c} 3 x \\ y \end{array}\right] [3001][xy]=[3xy]

(2)SVD推导(略)

从几何角度理解二维SVD:借助SVD可将一个相互垂直的网络(orthogonal grid)变换到另一个互相垂直的网络。
在这里插入图片描述
实际应用中,我们仅需保留着三个比较小的矩阵,就能表示A,不仅节省存储量,在计算的时候更是减少了计算量。SVD在信息检索(隐性语义索引)、图像压缩、推荐系统、金融等领域都有应用。

(3)SVD栗子

其中正交矩阵的特征值和特征向量的求解可以复习线性代数。
在这里插入图片描述
在这里插入图片描述

四、SVD图像压缩

(1)下载cv2pip install opencv-python

(2)其中np.linalg.svd(a, full_matrices=1, compute_uv=1)函数:

  • input参数:

    • a是一个形如(M,N)矩阵
    • full_matrices的取值是为0或者1,默认值为1,这时u的大小为(M,M),v的大小为(N,N) 。否则u的大小为(M,K),v的大小为(K,N) ,K=min(M,N)。
    • compute_uv的取值是为0或者1,默认值为1,表示计算u,s,v。为0的时候只计算s。
  • output参数(三个):

    • u大小为(M,M),s大小为(M,N),v大小为(N,N)。
    • A = usv
    • 其中s是对矩阵a的奇异值分解。s除了对角元素不为0,其他元素都为0,并且对角元素从大到小排列。s中有n个奇异值,一般排在后面的比较接近0,所以仅保留比较大的r个奇异值。

(3)numpy.stack函数:将多个数组进行堆叠,按照指定的维度,可参考博客

# -*- coding: utf-8 -*-
"""
Created on Sat Dec 11 23:14:35 2021

@author: 86493
"""
import cv2
import matplotlib as mpl
import numpy as np
import matplotlib.pyplot as plt

#转为u8类型
def restore1(u, sigma, v, k):
    
    m = len(u)
    n = len(v)
    a = np.zeros((m, n))
    a = np.dot(u[:, :k], np.diag(sigma[:k])).dot(v[:k, :])
    # s1 =  np.size(u[:, :k])
    # s1+= np.size(np.diag(sigma[:k]))
    # s1+= np.size(np.diag(v[:k, :]))
    # s2 = np.size(a)
    # print("压缩率:",s1/s2)
    a[a < 0] = 0
    a[a > 255] = 255
    return np.rint(a).astype('uint8')

def SVD(frame,K=10):
    a = np.array(frame)
    #由于是彩色图像,所以3通道。a的最内层数组为三个数,分别表示RGB,用来表示一个像素
    u_r, sigma_r, v_r = np.linalg.svd(a[:, :, 0])
    u_g, sigma_g, v_g = np.linalg.svd(a[:, :, 1])
    u_b, sigma_b, v_b = np.linalg.svd(a[:, :, 2])

    
    R = restore1(u_r, sigma_r, v_r, K)
    G = restore1(u_g, sigma_g, v_g, K)
    B = restore1(u_b, sigma_b, v_b, K)
    I = np.stack((R, G, B), axis = 2)
    return I
      

if __name__ == "__main__":
    mpl.rcParams['font.sans-serif'] = [u'simHei']
    mpl.rcParams['axes.unicode_minus'] = False
    # frame = cv2.imread("./liuyifei.bmp",-1)
    frame = cv2.imread("pig.jpg",-1)
    I = SVD(frame,40)
    plt.imshow(I)
    cv2.imwrite("out.bmp",I)

原图为:
在这里插入图片描述
图像压缩后的图为:
在这里插入图片描述

五、SVD手写体识别


Reference

(1)SVD-矩阵奇异值分解 —— 原理与几何意义
(2)SVD应用于图像压缩 Python代码测试
(3)https://www.zhihu.com/question/277311874
(4)矩阵的SVD分解(应用之一:手写数字识别)
(5)浅谈SVD原理以及python实现小demo
(6)SVD(奇异值分解)Python实现(原理清晰)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山顶夕景

小哥哥给我买个零食可好

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值