首页 >> 知识 >> 奇异值分解(SVD)及其应用

奇异值分解(SVD)及其应用

奇异值分解的定义

SVD(Singular Value Decomposition)可以理解为:将一个比较复杂的矩阵用更小更简单的3个子矩阵的相乘来表示,这3个小矩阵描述了大矩阵重要的特性。

定义:矩阵的奇异值分解是指将一个秩为 r r r的实矩阵 A m × n A_{m imes n} Am×n​分解为三个实矩阵乘积的形式:

A m × n = U m × m Σ m × n V n × n T ≈ U m × k Σ k × k V k × n T A_{m imes n} = U_{m imes m} Sigma_{m imes n} V ^ { T }_{n imes n} approx U_{m imes k} Sigma_{k imes k} V ^ { T }_{k imes n} Am×n​=Um×m​Σm×n​Vn×nT​≈Um×k​Σk×k​Vk×nT​

其中 U U U是 m m m阶正交矩阵( U U U的列向量称为左奇异向量), V V V是 n n n阶正交矩阵( V V V的列向量称为右奇异向量), Σ Sigma Σ是 m × n m imes n m×n矩形对角矩阵,称为奇异值矩阵,对角线上的元素称为奇异值。

Σ = [ D r × r 0 0 0 ] m × n Sigma = egin{bmatrix} D_{r imes r}&0\ 0&0\ end{bmatrix}_{m imes n} Σ=[Dr×r​0​00​]m×n​

D D D是一个 r × r r imes r r×r的对角阵, D D D的对角线元素是 A A A的前 r r r个奇异值 σ 1 ≥ σ 2 ≥ ⋯ ≥ σ r > 0 sigma _ { 1 } geq sigma _ { 2 } geq cdots geq sigma _ { r } > 0 σ1​≥σ2​≥⋯≥σr​>0(非负,降序)。

知识点:任意一个实矩阵 A A A可以由其外积展开式表示

A = σ 1 u 1 v 1 T + σ 2 u 2 v 2 T + ⋯ + σ r u r v r T A = sigma _ { 1 } u _ { 1 } v _ { 1 } ^ { T } + sigma _ { 2 } u _ { 2 } v _ { 2 } ^ { T } + cdots + sigma _ { r } u _ { r } v _ { r } ^ { T } A=σ1​u1​v1T​+σ2​u2​v2T​+⋯+σr​ur​vrT​

其中 u k v k T u _ { k } v _ { k } ^ { T } uk​vkT​为 m × n m imes n m×n矩阵,是列向量 u k u _ { k } uk​和行向量 v k T v _ { k } ^ { T } vkT​的外积, σ k sigma _ { k } σk​为奇异值, u k , v k T , σ k u _ { k } , v _ { k } ^ { T } , sigma _ { k } uk​,vkT​,σk​通过矩阵 A A A的奇异值分解得到。

知识点:奇异值在矩阵中按照从大到小排列,在很多情况下,前10%甚至1%的奇异值的和就占了全部的奇异值之和的99%以上的比例。蜜桃成人网站入口可以用最大的 k k k个奇异值的矩阵和 U V T UV^T UVT相乘来近似描述矩阵,从而实现了降维、减少数据存储、提升计算性能等效果。

奇异值分解的计算

设矩阵 A A A的奇异值分解为 A = U Σ V T A = U Sigma V ^ { T } A=UΣVT,则有

A T A = V ( Σ T Σ ) V T A A T = U ( Σ Σ T ) U T egin{array} { l } { A ^ { T } A = V ( Sigma ^ { T } Sigma ) V ^ { T } } \ { A A ^ { T } = U ( Sigma Sigma ^ { T } ) U ^ { T } } end{array} ATA=V(ΣTΣ)VTAAT=U(ΣΣT)UT​

即对称矩阵 A T A A^TA ATA和 A A T AA^T AAT的特征分解可以由矩阵 A A A的奇异值分解矩阵表示。

证明: A T A A^TA ATA的特征值非负。

令 A A A是 m × n m imes n m×n矩阵,那么 A T A A^TA ATA是对称矩阵且可以正交对角化,让 { v 1 , … , v n } {v_1,dots,v_n} {v1​,…,vn​}是 R n R^n Rn的单位正交基且构成 A T A A^TA ATA的特征向量, λ 1 , … , λ n lambda_1,dots,lambda_n λ1​,…,λn​是 A T A A^TA ATA对应的特征值,那么对 1 ≤ i ≤ n 1le{i}le{n} 1≤i≤n,

∥ A v i ∥ 2 = ( A v i ) T ( A v i ) = v i T A T A v i = v i T λ i v i = λ i | Av_i |^2 = (Av_i)^T(Av_i)=v_i^TA^TAv_i =v_i^Tlambda_iv_i=lambda_i ∥Avi​∥2=(Avi​)T(Avi​)=viT​ATAvi​=viT​λi​vi​=λi​

所以 A T A A^TA ATA的所有特征值都非负,如果必要,通过重新编号蜜桃成人网站入口可以假设特征值的重新排列满足

λ 1 ≥ λ 2 ≥ ⋯ ≥ λ n ≥ 0 lambda_ { 1 } geq lambda_ { 2 } geq cdots geq lambda_ { n } geq 0 λ1​≥λ2​≥⋯≥λn​≥0

A A A的奇异值是 A T A A^TA ATA的特征值的平方根,记为 σ 1 , σ 2 , … , σ n sigma_1,sigma_2,dots,sigma_n σ1​,σ2​,…,σn​,且它们递减顺序排列。

σ j = ∥ A v j ∥ = λ j , j = 1 , 2 , ⋯   , n sigma _ { j } = |Av_j | = sqrt { lambda _ { j } }, quad j = 1,2 , cdots , n σj​=∥Avj​∥=λj​ ​,j=1,2,⋯,n

可见,对 A A A进行奇异值分解需要求矩阵 A T A A^TA ATA的特征值及其对应的标准正交的特征向量来构成正交矩阵 V V V的列,特征值 λ j lambda _ { j } λj​的平方根得到奇异值$sigma _ { i } 也 即 得 到 奇 异 值 矩 阵 也即得到奇异值矩阵 也即得到奇异值矩阵Sigma$。

证明:假设 { v 1 , v 2 , … , v n } {v_1,v_2,dots,v_n} {v1​,v2​,…,vn​}是包含 A T A A^TA ATA特征向量的 R n R^n Rn上的标准正交基,重新整理使得对应 A T A A^TA ATA的特征值满足 λ 1 ≥ λ 2 ≥ ⋯ ≥ λ n lambda_1 ge lambda_2 ge dots ge lambda_n λ1​≥λ2​≥⋯≥λn​。若 A A A有 r r r个非零奇异值,则 { A v 1 , A v 2 , … , A v r } {Av_1,Av_2,dots,Av_r} {Av1​,Av2​,…,Avr​}是 C o l A ColA ColA的一个正交基,且 r a n k A = r rank A = r rankA=r。

当 i i i不等于 j j j时, v i T v j = 0 v_i^Tv_j=0 viT​vj​=0。

( A v i ) T A v j = v i T A T A v j = λ j v i T v j = 0 (Av_i)^TAv_j = v_i^TA^TAv_j = lambda_jv_i^Tv_j = 0 (Avi​)TAvj​=viT​ATAvj​=λj​viT​vj​=0

所以, { A v 1 , A v 2 , … , A v n } {Av_1,Av_2,dots,Av_n} {Av1​,Av2​,…,Avn​}是一个正交基。由于向量 A v 1 , A v 2 , … , A v n Av_1,Av_2,dots,Av_n Av1​,Av2​,…,Avn​的长度是 A A A的奇异值,且因为有 r r r个非零奇异值, A v i ( r ≥ i ≥ 1 ) Av_i (rge ige 1) Avi​(r≥i≥1)为非零向量。所以 A v 1 , A v 2 , … , A v r Av_1,Av_2,dots,Av_r Av1​,Av2​,…,Avr​线性无关,且属于 C o l A ColA ColA。

对任意属于 C o l A ColA ColA的 y y y,如 y = A x y=Ax y=Ax,蜜桃成人网站入口可以写出 x = c 1 v 1 + ⋯ + c n v n x=c_1v_1+dots+c_nv_n x=c1​v1​+⋯+cn​vn​,且

y = A x = c 1 A v 1 + ⋯ + c r A r v r y = Ax = c_1Av_1+dots+c_rA_rv_r y=Ax=c1​Av1​+⋯+cr​Ar​vr​

这样, y y y在 S p a n { A v 1 , … , A v r } Span{Av_1,dots,Av_r} Span{Av1​,…,Avr​}中,这说明 { A v 1 , A v 2 , … , A v r } {Av_1,Av_2,dots,Av_r} {Av1​,Av2​,…,Avr​}是 C o l A ColA ColA的一个正交基,因此 r a n k A = d i m ( C o l A ) = r rank A = dim(ColA)=r rankA=dim(ColA)=r。

由于 { A v 1 , A v 2 , … , A v r } {Av_1,Av_2,dots,Av_r} {Av1​,Av2​,…,Avr​}是 C o l A ColA ColA的一个正交基,将每一个 A v i Av_i Avi​单位化得到一个标准正交基 { u 1 , u 2 … u r } {u_1,u_2dots u_r} {u1​,u2​…ur​},此处

u i = 1 ∥ A v i ∥ A v i = 1 σ i A v i ( r ≥ i ≥ 1 ) u_i = frac{1}{|Av_i|}Av_i = frac{1}{sigma_i}Av_i(rge ige1) ui​=∥Avi​∥1​Avi​=σi​1​Avi​(r≥i≥1)

将 { u 1 , u 2 … u r } {u_1,u_2dots u_r} {u1​,u2​…ur​}扩充为 R m R^m Rm的单位正交基 { u 1 , u 2 … u m } {u_1,u_2dots u_m} {u1​,u2​…um​}。

U = ( u 1 , u 2 , … , u m ) , V = ( v 1 , v 2 , … , v n ) U=(u_1,u_2,dots,u_m),V=(v_1,v_2,dots,v_n) U=(u1​,u2​,…,um​),V=(v1​,v2​,…,vn​)

由构造可知, U U U和 V V V是正交矩阵,

A V = ( A v 1 , … , A v r , 0 , … , 0 ) = ( σ 1 u 1 , … , σ r u r , 0 … , 0 ) = U Σ AV=(Av_1,dots,Av_r,0,dots,0)=(sigma_1u_1,dots,sigma_ru_r,0dots,0)=USigma AV=(Av1​,…,Avr​,0,…,0)=(σ1​u1​,…,σr​ur​,0…,0)=UΣ

即: A = U Σ V T A=U Sigma V^T A=UΣVT,从而得到 U U U。

知识点:任意给定一个实矩阵,其奇异值分解一定存在,但并不唯一。

奇异值分解的实现

1. 手动实现

# 实现奇异值分解, 输入一个numpy矩阵,输出 U, sigma, Vimport numpy as np# 基于矩阵分解的结果,复原矩阵def rebuildMatrix(U, sigma, V): a = np.dot(U, sigma) a = np.dot(a, np.transpose(V)) return a# 基于特征值的大小,对特征值以及特征向量进行倒序排列。def sortByEigenValue(Eigenvalues, EigenVectors): index = np.argsort(-1 * Eigenvalues) Eigenvalues = Eigenvalues[index] EigenVectors = EigenVectors[:, index] return Eigenvalues, EigenVectors# 对一个矩阵进行奇异值分解def SVD(matrixA, NumOfLeft=None): # NumOfLeft是要保留的奇异值的个数,也就是中间那个方阵的宽度 # 首先求transpose(A)*A matrixAT_matrixA = np.dot(np.transpose(matrixA), matrixA) # 然后求右奇异向量 lambda_V, X_V = np.linalg.eig(matrixAT_matrixA) lambda_V, X_V = sortByEigenValue(lambda_V, X_V) # 求奇异值 sigmas = lambda_V # python里很小的数有时候是负数 sigmas = list(map(lambda x: np.sqrt(x) if x > 0 else 0, sigmas)) sigmas = np.array(sigmas) sigmasMatrix = np.diag(sigmas) if NumOfLeft is None: # 大于0的特征值的个数 rankOfSigmasMatrix = len(list(filter(lambda x: x > 0, sigmas))) else: rankOfSigmasMatrix = NumOfLeft # 特征值为0的奇异值就不要了 sigmasMatrix = sigmasMatrix[0:rankOfSigmasMatrix, :] # 计算左奇异向量 # 初始化一个左奇异向量矩阵,这里直接进行裁剪 X_U = np.zeros((matrixA.shape[0], rankOfSigmasMatrix)) for i in range(rankOfSigmasMatrix): X_U[:, i] = np.transpose(np.dot(matrixA, X_V[:, i]) / sigmas[i]) # 对右奇异向量和奇异值矩阵进行裁剪 X_V = X_V[:, 0:rankOfSigmasMatrix] sigmasMatrix = sigmasMatrix[0:rankOfSigmasMatrix, 0:rankOfSigmasMatrix] return X_U, sigmasMatrix, X_VA = np.array([[4, 11, 14], [8, 7, -2]])X_U, sigmasMatrix, X_V = SVD(A)print(A)# [[ 4 11 14]# [ 8 7 -2]]print(X_U.shape) # (2, 2)print(sigmasMatrix.shape) # (2, 2)print(X_V.shape) # (3, 2)print(rebuildMatrix(X_U, sigmasMatrix, X_V))# [[ 4. 11. 14.]# [ 8. 7. -2.]]

2. 使用numpy.linalg.svd函数

import numpy as npA = np.array([[4, 11, 14], [8, 7, -2]])print(A)# [[ 4 11 14]# [ 8 7 -2]]u, s, vh = np.linalg.svd(A, full_matrices=False)print(u.shape) # (2, 2)print(s.shape) # (2,)print(vh.shape) # (2, 3)a = np.dot(u, np.diag(s))a = np.dot(a, vh)print(a)# [[ 4. 11. 14.]# [ 8. 7. -2.]] 奇异值分解的应用

1. 数据压缩

奇异值分解可以有效地表示数据。例如,假设蜜桃成人网站入口希望传输下面的图像,它由一个 25 × 15 25 imes 15 25×15个黑色或白色像素组成的数组。

由于此图像中只有三种类型的列,如下图所示,因此可以用更紧凑的形式表示数据。

蜜桃成人网站入口将图像表示为一个 25 × 15 25 imes 15 25×15矩阵,矩阵的元素对应着图像的不同像素,如果像素是白色的话,就取 1,黑色的就取 0。 蜜桃成人网站入口得到了一个具有375个元素的矩阵,如下图所示

如果对 M M M进行奇异值分解,蜜桃成人网站入口会发现只有三个非零奇异值 σ 1 = 14.72 , σ 2 = 5.22 , σ 3 = 3.31 sigma_1=14.72,sigma_2=5.22,sigma_3=3.31 σ1​=14.72,σ2​=5.22,σ3​=3.31(非零奇异值的数目等于矩阵的秩,在这个例子中,蜜桃成人网站入口看到矩阵中有三个线性无关的列,这意味着秩将是3)。

M = σ 1 u 1 v 1 T + σ 2 u 2 v 2 T + σ 3 u 3 v 3 T M = sigma _ { 1 } u _ { 1 } v _ { 1 } ^ { T } + sigma _ { 2 } u _ { 2 } v _ { 2 } ^ { T } + sigma _ { 3 } u _ { 3 } v _ { 3 } ^ { T } M=σ1​u1​v1T​+σ2​u2​v2T​+σ3​u3​v3T​

v i v_i vi​具有15个元素, u i u_i ui​ 具有25个元素, σ i sigma_i σi​ 对应不同的奇异值。蜜桃成人网站入口就可以用123个元素来表示具有375个元素的图像数据了。通过这种方式,奇异值分解可以发现矩阵中的冗余,并提供消除冗余的格式。

2. 去噪

前面的例子展示了如何利用许多奇异值为零的情况。一般来说,大的奇异值对应的部分会包含

网站地图