Python实现QR分解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python实现QR分解相关的知识,希望对你有一定的参考价值。
参考技术A 使用Gram-Schmidt正交化,Householder变换,Given旋转三种方法实现了QR分解,但是感觉好像并无卵用,貌似实际生产有更好的改进方法?矩阵分析或者矩阵论的课都有介绍,网上资料也很多,在此不贴了。
机器学习中的矩阵分解LU分解QR分解SVD分解
学习总结
文章目录
一、三角分解(LU分解)
1.1 高斯消元
1.2 LU分解原理
1.3 LU分解python代码
1.4 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[\\beginarrayll3 & 0 \\\\ 0 & 1\\endarray\\right]
M=[3001]
对角矩阵M是将二维平面上的点(x,y)经过线性变换到另一个点的变换矩阵(变换效果:平面沿着x水平方向进行3倍拉伸,垂直方向没变化): [ 3 0 0 1 ] [ x y ] = [ 3 x y ] \\left[\\beginarrayll 3 & 0 \\\\ 0 & 1 \\endarray\\right]\\left[\\beginarrayl x \\\\ y \\endarray\\right]=\\left[\\beginarrayc 3 x \\\\ y \\endarray\\right] [3001][xy]=[3xy]
(2)SVD推导(略)
从几何角度理解二维SVD:借助SVD可将一个相互垂直的网络(orthogonal grid)变换到另一个互相垂直的网络。
实际应用中,我们仅需保留着三个比较小的矩阵,就能表示A,不仅节省存储量,在计算的时候更是减少了计算量。SVD在信息检索(隐性语义索引)、图像压缩、推荐系统、金融等领域都有应用。
(3)SVD栗子
其中正交矩阵的特征值和特征向量的求解可以复习线性代数。
四、SVD图像压缩
(1)下载cv2
:pip 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实现(原理清晰)
以上是关于Python实现QR分解的主要内容,如果未能解决你的问题,请参考以下文章
急求matlab复数矩阵QR分解代码我知道matlab本身有qr函数 但是我想知道利用householder变换递归实现的原理。
数学推导+纯Python实现机器学习算法28:奇异值分解SVD