跳到主要内容

交互式、可视化地理解 SVD 分解

欢迎来到交互式理解奇异值分解!这篇文章和你看到的其它文章可能有所不同,当你双击下面的大部分动画的时候,它将变成可交互的,你将在亲自探索中建立关于问题的直觉。

现在让我们来试一试。我们知道,一个矩阵代表了对空间网格的拉伸和旋转。具体来说是将正交基放到矩阵的列向量所指示的位置。下面这个动画演示了这一点,双击它,你可以亲自拖动两个基底,看到空间的变换。

更直观一点,我们来看看这样的一个空间线性变换对不同图形产生了什么样的影响。双击它,可以看到不同图形在这个变换下相应的变化。

一个直观的感受是,圆变成了椭圆,而原来摆的板板正正的三角形和正方形则变得不那么规则了。圆变成椭圆,说明空间的变化等于两个垂直的方向上拉长了。边垂直于原来的 x 轴和 y 轴的正方形则变得不那么规整,这说明两个拉长的方向不再是原来基向量的两个方向。

你能找到一个这样的十字,恰好是椭圆的长轴和短轴吗?在下面的交互里拖动单位圆上的点试一试。当你找到这样一个方向时,会弹出通过。在右下角有两个滑块,你可拖动它们,让图形在你找到的两个方向上缩放。多试几个变换,观察一下,你发现了什么?

在长短轴上缩放,可以看见圆、正方形、三角形同时变回了原来的样子。这说明,虽然这个线性变换把等边三角形和正方形变得不那么规律,但是只要我们转一个视角看,就只是普普通通的横竖两个方向上的拉伸。

也就是说,任意一个线性变换,都等于在某几个正交的方向上拉伸,再进行旋转。在下面的动画中,你可以双击指定任何你喜欢的线性变换,然后按空格或者右下角下一步按钮,看看它是怎么通过一个方向上的拉伸和旋转得到的。

这样“找到一个方向进行拉伸,然后旋转”其实就是奇异值分解,我们可以把任何一个矩阵分解成这样的形式。那么,这样一些操作如何用线性代数的语言来表示呢?又应该如何找到旋转的角度和拉伸的大小?

先来复习一下如何用矩阵来表示拉伸和旋转操作。首先是对角矩阵对应了沿基底方向的拉伸/收缩。老规矩,双击可以拖动数字,看看球如何变化。

旋转操作则是矩阵 $[v_1, v_2]$ 中 $v_1$ 和 $v_2$ 两个向量都在单位圆上,而且保持正交。在下面的演示中,你可以看见一个代表旋转的矩阵,和它的转置分别造成了怎样的效果。双击可以亲自拖动旋转。

你可能已经看出来,转置的转动方向和原始的矩阵转动方向相反,也就是说,单位正交矩阵的转置就是它的逆。这很好证明,因为两列相乘是 0,而一列自己乘自己是 1.。

万事具备,现在可以用线性代数的语言来表现我们所学到的“找到一个方向,拉伸,然后再旋转到正确方向”了。由于前面所说的拉伸是在坐标轴方向上,因此,我们需要把“找到一个方向建立坐标系”变成,转和那个方向相反的角度,把要进行拉伸的轴对齐坐标轴。然后进行相应操作。

让我们用线性代数的语言重新表述一下在之前的动画里看到的。

这就是我们在教科书上看到的奇异值分解的形式。奇异值,就是中间拉伸的那一步所对应的系数。

接下来的问题是,我们怎么求出式子中的三个部分?其实只要算算 $A^T A$ 就可以得到一个特征值分解的形式。这样,我们就可以的对 $A^T A$ 进行特征值分解,特征向量就是 V,特征值开根号就是 $\Sigma$ 对角线上的数字,称为奇异值。

那奇异值究竟是什么呢?看看下面的动画,双击自由拖动,看看线性变换和奇异值有什么直观的联系。

仔细观察,可以注意到,奇异值就是椭圆的长轴和短轴相对于原来的圆直径拉伸的比例,即变化最大的一些方向拉伸了多少倍。

我们把奇异值分解以后的式子展开可以发现,其实就是一些秩为 $1$ 的矩阵,表达了这个线性变换在每个方向上引起的变化。

在下面这个示例中,演示了在最后一个奇异值很小的时候,按照奇异值分解展开只取前两项的变换和三项的变换的不同。双击你可以自己选择只保留哪些项,拖动视角看看线性变换变成了什么样。

可以看出,去掉最后一项,变换后的图形其实差不多,因为虽然矩阵满秩,但是那一层几乎拍扁了。也就是矩阵中几乎有两列是线性相关的。工业界中得到的矩阵,很难有两列严格线性相关,只能是几乎线性相关,通过这种方法,我们可以对奇异值设置一个阈值,看看矩阵实际上有意义的秩是多少。由于去掉影响小的方向对矩阵几乎没有影响,这种方法也可以被用于压缩、特征提取等领域。


本文是使用 Wanim 制作的,你喜欢这样的讲义吗?