
终于有契机来先容我在线性代数中最心爱的时间——奇异值领悟 (SVD),从某种进程上来说,这可能是线性代数中最具有表面道理和实用价值的时间了,天然很缺憾我在本科毕业后随机两年才清醒到这小数,这种时间不错对任何矩阵适用,不单是是方阵,对一般的矩形矩阵亦然适用的,仅以我的学问层面而言,SVD的垄断就包括,举例保举系统中的协同滤波和图像处罚领域的图像压缩。咱们在这期推送中,有契机向公共先容这种时间,好了,让咱们开动吧。
奇异值领悟 (SVD)最初,什么是SVD,你怎样暗示它?在数学中,咱们不错将任何一个矩阵A作念奇异值领悟,用数学标志暗示如下。
图片
这里:
U 是一个 n x n 正交矩阵,其列叫作念A 的左奇异向量。
V 是一个 d x d 正交矩阵,其列叫作念 A 的右奇异向量。
S 是一个 n x d 对角矩阵,对角线上具有非负数字,咱们时常将这些数字从大到小排序,东谈主们给这些数字一个称号叫作念 A 的奇异值。
为了更明晰地先容上头的名词,咱们说淌若存在得志底下公式的向量 u 和 v,则向量 u 和 v 称为奇异向量。σ叫作念 是一个奇异值。
图片
咱们要仔细不雅察一下方程(1)和方程(2),事实上他们抒发的是吞并个敬爱,咱们瞩目到因为υ是正交矩阵,是以它的逆矩阵便是其转置矩阵,瞩目到这小数,咱们就知谈了方程(1)事实便是(2)的紧凑的矩阵神色,因此,每个奇异向量齐有一个对应的奇异值。底下咱们来进行可视化,颜料疏导的列暗示对应的奇异值和向量,如下图所示。
图片
SVD和正交对角化的分袂
到咫尺收尾,咱们有了SVD的初步想法,那么,鄙人一步,一个很天然的问题便是咱们怎样筹划SVD?在久了斟酌这个问题之前,我思浮现另外一个问题即 SVD 和公共熟知正交对角化之间的分袂,因为它们瑕瑜常相似的想法。淌若你照旧忘了什么是正交对角化,那么咱们如故最初回顾一下它的界说:
图片
P 是 A 的正交矩阵和正交特征向量
D 是一个对角矩阵,其对角线上是 A 的特征值。
SVD 和正交对角化之间的要害分袂在于正交对角化仅适用于方阵。此外,天然 SVD 在公式中有两个不同的矩阵(U 和 V),但正交对角化唯有一个矩阵 (P)。这些公式究竟是什么敬爱?咱们不妨作念一些可视化的展示,匡助你清醒这些矩阵。
图片
正交矩阵 — 旋转空间
图片
对角矩阵 — 缩放空间
从上头两张动画中咱们了解到了正交矩阵和对角矩阵的遑急含义。正交矩阵老是使空间旋转或反射,而对角矩阵老是使空间缩放。我驯服公共从动图中明晰地看到了这小数,为了败北你健忘这小数,咱们鄙人面的图片中作念了总结。
图片
图片
图片
图片
上图描述了正交对角化。底下那张图则暗示SVD领悟
怎样筹划 SVD在推行算法中,咱们不错筹划 A 的 SVD,如下所示(* 暗示转置共轭或者奉陪)由于大大宗的垄断齐是实矩阵,是以共轭就变得无可不成,因而在实矩阵的道理下,这个标志便是转置的敬爱。
筹划左奇异向量(U)。它等于 AA* 的特征向量。
筹划右奇异向量(V)。它等于 A*A 的特征向量。
筹划 AA* 或 A*A(D) 的特征值的肤浅根。
然后,咱们就会取得 SVD 的悉数信息。让咱们考证此历程是否正确。举例,我将使用底下的矩阵:
图片
第一步,您需要筹划 AA* 的特征向量。
# 筹划 AA*left = np.dot(A, A.T)print(left)# 筹划上述矩阵的特征向量 left_eigen_val, left_eigen_vec = np.linalg.eig(left)print(left_eigen_val, left_eigen_vec)# 你会取得以下成果# print(left)# array([[20, 14, 0, 0],# [14, 10, 0, 0],# [ 0, 0, 0, 0],# [ 0, 0, 0, 0]])## print(left_eigen_val, left_eigen_vec)# array([29.86606875, 0.13393125, 0. , 0. ])# array([[ 0.81741556, -0.57604844, 0. , 0. ],# [ 0.57604844, 0.81741556, 0. , 0. ],# [ 0. , 0. , 1. , 0. ],# [ 0. , 0. , 0. , 1. ]])
下一步,您需要筹划 A*A 的特征向量。你不错用相通的格式解释它。
p.dot(A.T, A)print(right)# 筹划上述矩阵的特征向量 right_eigen_val, right_eigen_vec = np.linalg.eig(right)print(right_eigen_val, right_eigen_vec)# 你会取得以下成果# print(right)# array([[ 5, 11],#[11, 25]])## print(right_eigen_val, right_eigen_vec)# array([ 0.13393125, 29.86606875])# array([[-0.9145143 , -0.40455358],# [ 0.40455358, -0.9145143 ]])关于临了一步,你必须筹划来自 AA* 或 A*A 的特征值的肤浅根。而这两个具有疏导的特征值!
图片
天然咱们经验了 SVD 的数学历程,但推行上Python 里不错快速筹划它,因为东谈主们照旧把相应的数学历程压缩到包里了,从而你不错圣洁的调用它们。
# 通过numpy筹划SVD U, S, V = np.linalg.svd(A)# U# array([[-0.81741556, -0.57604844, 0. , 0. ],# [-0.57604844, 0.81741556, 0. , 0. ],# [ 0. , 0. , 1. , 0. ],# [ 0. , 0. , 0. , 0. , 1. ]])# S# 数组([5.4649857 , 0.36596619])# V# 数组([[-0.40455358, -0.9145143 ],# [-0.9145143 , 0.40455358]]))
你天然不错查验成果是否与咱们手动筹划的成果疏导。好了今天就到这里吧感谢你的阅读,不错的话请多多援手公众号,感谢!
援用
[1] https://docs.manim.community/en/stable/installation.html
[2] https://web.stanford.edu/class/cs168/l/l9.pdf
[3] https://www.cs.princeton.edu/courses/archive/spring20/cos302/files/COS_302_Precept_4.pdf
[4] https://web.mit.edu/be.400/www/SVD/Singular_Value_Decomposition.htm
本站仅提供存储奇迹,悉数内容均由用户发布,如发现存害或侵权内容,请点击举报。