想学SVD(奇异值分解)算法?看这篇就够了


想学SVD(奇异值分解)算法?看这篇就够了

仅用于站内搜索,没有排版格式,具体信息请跳转上方微信公众号内链接

线性代数是机器学习领域的基础,其中一个最重要的概念是奇异值分解(SVD),本文尽可能简洁的介绍SVD(奇异值分解)算法的基础理解,以及它在现实世界中的应用。
SVD是最广泛使用的无监督学习算法之一,它在许多推荐系统和降维系统中居于核心位置,这些系统是全球公司如谷歌、Netflix、Facebook、YouTube等的核心技术。
简单来说,SVD是将一个任意矩阵分解为三个矩阵。所以如果我们有一个矩阵A,那么它的SVD可以表示为:
A是矩阵,U是的正交矩阵,是的非负对角矩阵,是的正交矩阵。
U也被称为左奇异向量,S为奇异值,V为右奇异向量。
带维度的奇异值分解:
用矩阵表示奇异值分解:
我们通常将具有较大特征值的向量排列在前,而较小特征值的向量则排在后面。
特征值与向量的对应关系:
与特征值分解相比,奇异值分解可以应用于非方阵。在SVD中,U和V对于任何矩阵都是可逆的,并且它们是正交归一的,这是我们所喜爱的特性。虽然这里不进行证明,但我们可以告诉你,奇异值比特征值在数值上更稳定。
为了更好地理解,我们通过一个例子演示SVD
假设我们有非方阵A:
我们计算矩阵与转置矩阵的乘积,有:
求解的特征值和特征向量:
求解的特征值和特征向量:
奇异值是正特征值的平方根,即5和3。因此非方阵A的SVD分解为:
为了得到矩阵A的SVD分解:
我们需要求解正交矩阵U和V
其中I是单位矩阵。
上面3个方程有3个未知数,因此是可以求解这3个未知数的。
矩阵A的转置是:
由于正交矩阵V和U满足:
我们计算:
最后一个方程等价于求矩阵的特征向量,我们只需将所有特征向量放入一个矩阵中,矩阵S则是包含特征值的对角矩阵。
即,有:
其中是的特征值。
计算矩阵的表达式:
其中矩阵V包含了的所有特征向量,矩阵S包含了的所有特征值的平方根。我们可以对重复相同的工程,并得到一个类似的方程。
现在我们知道了通过和分别得到了矩阵U和V,其中U和V包含了各自的特征向量,S的特征值是矩阵或特征值的平方根。因此3个未知量都求解了,即可得到矩阵A的SVD分解:
由于矩阵V是正交的,等于单位矩阵I。我们可以将SVD方程重新写为:
矩阵V:
其中:
矩阵U:
其中:
矩阵S:
我们取第1个特征向量:
得:
可以通用化上式:
因此A的SVD分解可以看做是和的一系列外积:
若我们取前k个奇异值,根据上式得到新的矩阵。
矩阵是降维后的数值。若大家还有疑问,欢迎留言。
我们可以将图像存储在一个矩阵中。每个图像由一组像素组成,这些像素是构成该图像的基本单元。每个像素表示图像中某个特定位置的颜色或光强度。在PNG格式的灰度图像中,每个像素的值在0和1之间,其中0对应黑色,1对应白色。因此一个具有像素的灰度图像可以存储在一个矩阵或NumPy数组中。在这里,我们使用imread()函数加载一张爱因斯坦的灰度图像,其分辨率为480×423像素,并将其存储为一个二维数组。然后,我们使用SVD来分解该矩阵,并使用前30个奇异值来重建图像。
左图是原始图像,右图是取前30个奇异值重建的图像。
原始矩阵是480×423的,因此我们需要存储480×423=203040个值。经过SVD后,每个具有480个元素,每个具有423个元素。为了使用前30个奇异值重建图像,我们只需要保留前30个、和,这意味着只需要存储30×(1+480+423)=27120个值。这大约是原始图像所需值数量的13%。因此,通过使用SVD,我们可以得到原始图像的良好近似,并节省大量内存。
下图计算了前6个奇异值对应的矩阵。每个矩阵的秩为1,并且具有与原始矩阵相同的行数和列数。
请注意,与原始灰度图像不同,这些秩为1的矩阵的元素值可以大于1或小于0,它们不应被解释为灰度图像。因此,我没有使用cmap=’gray’也没有将它们显示为灰度图像。在绘制这些矩阵时,我们不关心像素的绝对值,而是关注它们之间的相对值。
为了理解每个矩阵中如何存储图像信息,我们可以研究一个更简单的图像。下面的代码读取了一个包含五个简单形状的二进制图像(一个矩形和4个圆形),并取前2个、前4个和前6个奇异值重建图像。
现在我们绘制前6个奇异值对应的矩阵:
从每个奇异值的图像可以看出,前两个奇异值构建的矩阵大致捕捉了四个圆形作为四个矩形,而最后四个奇异值构建的矩阵则添加了更多细节。
如下图,图像中有6根柱子,第一个奇异值对应的矩阵可以捕捉到原始图像中的柱子数量。
在这个示例中,我们将使用Scikit-learn库中的Olivettifaces数据集。该数据集包含400张图像,图像展示了40位不同受试者的面部特征。对于一些受试者,图像是在不同时间拍摄的,具有不同的光照、面部表情和面部细节。这些图像为灰度图像,每张图像具有64×64像素。每个像素的强度值在区间[0,1]上。首先,我们加载数据集:
我们调用它来读取数据,并将图像存储在imgs数组中。这是一个形状为(400,64,64)的数组,包含400张64×64的灰度图像。我们可以在这里展示其中的一些作为示例:
在前一个示例中,我们将原始图像存储在一个矩阵中,然后使用SVD对其进行分解。在这里,我们采用另一种方法。我们有400张图像并给每张图像分配一个从1到400的标签。现在我们使用独热编码来表示这些标签,使用一个包含400个元素的列向量。对于每个标签k,除了第k个元素,所有元素都是零。因此,标签k将由以下向量表示:
现在我们将每张图像存储在一个列向量中。每张图像有64×64=4096个像素。因此,我们可以将每张图像展平并将像素值放入一个具有4096个元素的列向量中,如下图所示:
因此,每张标签为k的图像将存储在向量中,我们需要400个向量来保存所有图像。现在我们定义一个变换矩阵,它将标签向量转换为其对应的图像向量。这些向量将作为矩阵的列:
这个矩阵有4096行和400列。我们可以简单地使用来找到每个标签对应的图像(可以是任何向量,而将是对应的)。例如,对于这个数据集中的第三张图像,标签是3,的所有元素都是零,除了第三个元素是1。现在记住分块矩阵的乘法,当我们用乘以时,除了第三列之外,的所有列都被乘以零,所以:
现在我们对矩阵进行SVD分解。
我们计算并显示前8个奇异值对应的U向量:
上图就是我们要介绍的特征脸,每个特征脸捕捉了图像向量的一些信息。例如特征脸主要反映了眼睛信息,特征脸捕捉了鼻子信息。
上述代码的数组s具有400个元素,因此我们有400个非零的奇异值,矩阵的矩为400。因此我们需要前400个向量来完全重建矩阵,使用这些基向量轻松重建其中一张图像。
这里我们使用不同个数的奇异值去重建第160号图像(k表示使用前k个奇异值重建图像)。
上图反映的信息与特征脸步骤的细节基本一致,如最高奇异值(k=1)重建的图像反映了眼睛信息,同样地,第一个特征脸反映的也是眼睛信息。
SVD可以用于降低图像中的噪声。
首先,我们加载图像并添加一些噪声。然后使用前20、55和200个奇异值重建图像。如上图所示,随着重建矩阵的秩增加,噪声的量也随之增加。因此如果我们使用较低的秩,比如20,可以显著减少图像中的噪声。
我真的觉得奇异值分解(SVD)被低估了。它是线性代数中一个非常重要的基础概念,而且它的应用非常酷!相信我,我们看到的只是SVD众多用途中的一小部分。有什么问题,欢迎讨论!
欢迎扫码关注:


文章作者: ZejunCao
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 ZejunCao !
  目录