1. 普通方阵的矩阵分解(EVD)

我们知道如果一个矩阵 A 是方阵,即行列维度相同(mxm),一般来说可以对 A 进行特征分解:

其中,U 的列向量是 A 的特征向量,Λ 是对角矩阵,Λ 对角元素是对应特征向量的特征值。

举个简单的例子,例如方阵 A 为:

那么对其进行特征分解,相应的 Python 代码为:

import numpy as np

A = np.array([[2,2],[1,2]])

lamda,U=np.linalg.eig(A)

print('方阵 A: ',A)

print('特征值 lamda: ',lamda)

print('特征向量 U: ',U)

运行输出:

方阵 A: [[2 2]

[1 2]]

特征值 lamda: [ 3.41421356 0.58578644]

特征向量 U: [[ 0.81649658 -0.81649658]

[ 0.57735027 0.57735027]]

特征分解就是把 A 拆分,如下所示:

其中,特征值 λ1=3.41421356,对应的特征向量 u1=[0.81649658 0.57735027];特征值 λ2=0.58578644,对应的特征向量 u2=[-0.81649658 0.57735027],特征向量均为列向量。

值得注意的是,特征向量都是单位矩阵,相互之间是线性无关的,但是并不正交。得出的结论是对于任意方阵,不同特征值对应的特征向量必然线性无关,但是不一定正交。

2.对称矩阵的矩阵分解(EVD)

如果方阵 A 是对称矩阵,例如:

对称矩阵特征分解满足以下公式:

那么对其进行特征分解,相应的 Python 代码为:

A = np.array([[2,1],[1,1]])

lamda,U=np.linalg.eig(A)

print('方阵 A: ',A)

print('特征值 lamda: ',lamda)

print('特征向量 U: ',U)

运行输出:

方阵 A: [[2 1]

[1 1]]

特征值 lamda: [ 2.61803399 0.38196601]

特征向量 U: [[ 0.85065081 -0.52573111]

[ 0.52573111 0.85065081]]

特征分解就是把 A 拆分,如下所示:

其中,特征值 λ1=2.61803399,对应的特征向量 u1=[0.85065081 0.52573111];特征值 λ2=0.38196601,对应的特征向量 u2=[-0.52573111 0.85065081],特征向量均为列向量。

注意,我们发现对阵矩阵的分解和非对称矩阵的分解除了公式不同之外,特征向量也有不同的特性。对称矩阵的不同特征值对应的特征向量不仅线性无关,而且是相互正交的。什么是正交呢?就是特征向量内积为零。验证如下:

00.85065081∗−0.52573111+0.52573111∗0.85065081=0

重点来了,对称矩阵 A 经过矩阵分解之后,可以写成以下形式:

对上式进行验证:

3. 奇异值分解(SVD)

我们发现,在矩阵分解里的 A 是方阵或者是对称矩阵,行列维度都是相同的。但是实际应用中,很多矩阵都是非方阵、非对称的。那么如何对这类矩阵进行分解呢?因此,我们就引入了针对维度为 mxn 矩阵的分解方法,称之为奇异值分解(Singular Value Decomposition)。

假设矩阵 A 的维度为 mxn,虽然 A 不是方阵,但是下面的矩阵却是方阵,且维度分别为 mxm、nxn。

因此,我们就可以分别对上面的方阵进行分解:

其中,Λ1 和 Λ2 是对焦矩阵,且对角线上非零元素均相同,即两个方阵具有相同的非零特征值,特征值令为 σ1, σ2, … , σk。值得注意的是,k<=m 且 k<=n。

根据 σ1, σ2, … , σk 就可以得到矩阵 A 的特征值为:

接下来,我们就能够得到奇异值分解的公式:

其中,P 称为左奇异矩阵,维度是 mxm,Q 称为右奇异矩阵,维度是 nxn。Λ 并不是方阵,其维度为 mxn,Λ 对角线上的非零元素就是 A 的特征值 λ1, λ2, … , λk。图形化表示奇异值分解如下图所示:

举个简单的例子来说明,令 A 为 3×2 的矩阵:

则有:

计算得到特征向量 P 和对应的特征值 σ 为:

然后,有:

计算得到特征向量 Q 和对应的特征值 σ 为:

则我们看可以得到 A 的特征值为:

最后,整合矩阵相乘结果,满足奇异值分解公式。

奇异值分解可以写成以下和的形式:

其中,p1 和 q1 分别为左奇异矩阵和右奇异矩阵的特征向量。

4. 如何形象化理解 SVD

奇异值分解到底有什么用呢?如何形象化地理解奇异值?我们一起来看下面的例子。

首先放上男神的照片:

我们对该图片进行奇异值分解,则该图片可写成以下和的形式:

上式中,λ1, λ2, … , λk 是按照从大到小的顺序的。

首先,若我们只保留最大的奇异值 λ1,舍去其它奇异值,即 A=λ1p1q1T,然后作图:

结果完全看不清楚,再多加几个奇异值,取前 5 个最大的奇异值,然后作图:

现在貌似有点轮廓了,继续增加奇异值,取前 10 个最大的奇异值,然后作图:

又清晰了一些,继续将奇异值增加到 20 个,然后作图:

现在已经比较清晰了,继续将奇异值增加到 50 个,然后作图:

可见,取前 50 个最大奇异值来重构图像时,已经非常清晰了。我们得到和原图差别不大的图像。也就是说,随着选择的奇异值的增加,重构的图像越来越接近原图像。

基于这个原理,奇异值分解可以用来进行图片压缩。例如在本例中,原始图片的维度是 870×870,总共需要保存的像素值是:870×870=756900。若使用 SVD,取前 50 个最大的奇异值即可,则总共需要存储的元素个数为:

(870+1+870)∗50=87050

显然,所需存储量大大减小了。在需要存储许多高清图片,而存储空间有限的情况下,就可以利用 SVD,保留奇异值最大的若干项,舍去奇异值较小的项即可。

值得一提的是,奇异值从大到小衰减得特别快,在很多情况下,前 10% 甚至 1% 的奇异值的和就占了全部的奇异值之和的 99% 以上了。这对于数据压缩来说是个好事。下面这张图展示了本例中奇异值和奇异值累加的分布:

SVD 数据压缩的算法图示如下:

SVD 数据压缩的示例代码为:

from skimage import io

import matplotlib.pyplot as plt

from PIL import Image

import numpy as np

img=io.imread(r'D:\workspace\python\AiTrainingCamp\holidays\zoubo\ng33.jpg')

m,n = img.shape

io.imshow(img)

plt.show()

P, L, Q = np.linalg.svd(img)

tmp = np.diag(L)

if m < n:

d = np.hstack((tmp,np.zeros((m,n-m))))

else:

d = np.vstack((tmp,np.zeros((m-n,n))))

k = 5

img2 = P[:,:k].dot(d[:k,:k]).dot(Q[:k,:])

io.imshow(np.uint8(img2))

plt.show()

tmp = np.uint8(img2)

im = Image.fromarray(tmp)

im.save("out.jpg")

整数分解为若干项之和python_SVD奇异值分解及Python实例相关推荐

  1. 7-37 整数分解为若干项之和(20 分)

    7-37 7-37 整数分解为若干项之和(20 分) 将一个正整数N分解成几个正整数相加,可以有多种分解方法,例如7=6+1,7=5+2,7=5+1+1,-.编程求出正整数N的所有整数分解式子. 输入 ...

  2. 7-37 整数分解为若干项之和 (20 分)(dfs)

    7-37 整数分解为若干项之和 (20 分) 将一个正整数N分解成几个正整数相加,可以有多种分解方法,例如7=6+1,7=5+2,7=5+1+1,-.编程求出正整数N的所有整数分解式子. 输入格式: ...

  3. 整数分解为若干项之和

    7-37 整数分解为若干项之和 (20 分) 将一个正整数N分解成几个正整数相加,可以有多种分解方法,例如7=6+1,7=5+2,7=5+1+1,-.编程求出正整数N的所有整数分解式子. 输入格式: ...

  4. 整数分解成若干项之和(DFS)拓展延伸

    在深度优先搜索的例题中,有一种题型是整数分解成若干项之和. 例如将一个正整数N分解成几个正整数相加,可以有多种分解方法,例如7=1+6,7=2+5,7=1+1+5,-.编程求出正整数N的所有整数分解式 ...

  5. 7-14 整数分解为若干项之和 (15分)(附详细讲解(不用递归的高效算法))

    将一个正整数N分解成几个正整数相加,可以有多种分解方法,例如7=6+1,7=5+2,7=5+1+1,-.编程求出正整数N的所有整数分解式子. 输入格式: 每个输入包含一个测试用例,即正整数N (0&l ...

  6. 分解连续自然数的和_将整数分解为连续自然数之和

    将一个正整数,拆分成连续的自然数之和,输出所有可能的情况 例如: 3 = 1+2 10 = 1+2+3+4 18 = 5+6+7 偶然见到这个问题,这里写下自己的解法. 分析: 对给定整数x以及一组满 ...

  7. 形如:1/a 的分数称为单位分数。可以把1分解为若干个互不相同的单位分数之和。

    形如:1/a 的分数称为单位分数.可以把1分解为若干个互不相同的单位分数之和. 例如: 1 = 1/2 + 1/3 + 1/9 + 1/18 1 = 1/2 + 1/3 + 1/10 + 1/15 1 ...

  8. 形如:1/a 的分数称为单位分数。 可以把1分解为若干个互不相同的单位分数之和。 例如: 1 = 1/2 + 1/3 + 1/9 + 1/18 1 = 1/2 + 1/3 + 1/10 + 1/1

    形如:1/a 的分数称为单位分数. 可以把1分解为若干个互不相同的单位分数之和. 例如: 1 = 1/2 + 1/3 + 1/9 + 1/18 1 = 1/2 + 1/3 + 1/10 + 1/15 ...

  9. 形如:1/a 的分数称为单位分数。 可以把1分解为若干个互不相同的单位分数之和。

    形如:1/a 的分数称为单位分数. 可以把1分解为若干个互不相同的单位分数之和. 例如: 1 = 1/2 + 1/3 + 1/9 + 1/18 1 = 1/2 + 1/3 + 1/10 + 1/15 ...

最新文章

  1. Go 语言编程 — gormigrate GORM 的数据库迁移助手
  2. linux查看oracle的sga设置,Oracle基础教程之设置系统全局区SGA命令
  3. 在Windows C程序中使用Unicode编码
  4. php 数组处理函数,PHP数组处理函数举例
  5. 2.python中的矩阵、多维数组----numpy
  6. 【分类汇总】110 天以来的题解分类汇总
  7. html5 graphics with svg css3,HTML5 Canvas and CSS3 Graphics Primer
  8. 使用allegro画PCB的基本流程:
  9. compileflow 淘宝工作流引擎
  10. webpack之基础篇(四):webpack-dev-server介绍
  11. 10.3注意力的评价函数
  12. Spring ClassPathResource详解
  13. 7-2 哥尼斯堡的“七桥问题” (25分)
  14. 微信小程序取本地数据库数据(实测有图)
  15. JAVA8用哪个版本的MYSQL_MySQL用哪个版本,5.7还是8.0?
  16. 如何破解excel密码
  17. 为什么要有无参构造方法,无参构造的运行原理
  18. Git操作失败提示fatal: Unable to create 'E:/GitDemos/todolist/.git/index.lock': File exists...
  19. ‘Tensor‘ object has no attribute ‘_keras_history‘——keras和tensorflow版本不兼容
  20. DNS与Bind基本配置实现

热门文章

  1. 【Clickhouse】Clickhouse 普通视图
  2. Spring : @Value注解
  3. Hadoop常用参数整理(HDFS/Yarn/MapReduce/GC)
  4. python 如何匹配一撇字符_python,yaml如何解析包含撇号的字符串
  5. deepin中自定义安装的软件如何加入到启动器
  6. 划分子网后的三级结构
  7. leetcode题解5-最长回文子串
  8. Spring框架----Spring的环绕通知
  9. vue 组件 全局组件和局部组件component
  10. 2019.7.22JS初始内容的整理以及4道题目