SVD奇异值分解

无论是特征值分解还是奇异值分解,都是为了让人们对矩阵(或者线性变换)的作用有一个直观的认识。这是因为我们拿过来一个矩阵,很多情况下只能看到一堆排列有序的数字,而看不到这些数字背后的真实含义,特征值分解和奇异值分解告诉了我们这些数字背后的真实含义,换句话说,它告诉了我们关于矩阵作用的本质信息。


SVD提供了一种非常便捷的矩阵分解方式,能够发现数据中十分有意思的潜在模式。在这篇文章中,我们将会提供对SVD几何上的理解和一些简单的应用实例。首先从几何层面上去理解二维的SVD。
SVD奇异值分解

这就表明任意的矩阵 A 是可以分解成三个矩阵相乘的形式。
V表示了原始域的标准正交基,U表示经过A 变换后的co-domain的标准正交基,Σ表示了V中的向量与U中相对应向量之间的关系。我们仔细观察上图发现,线性变换A可以分解为旋转缩放旋转这三种基本线性变换。
SVD奇异值分解SVD奇异值分解是对角阵,表示奇异值,A矩阵的作用是将一个向量在V这组正交基向量的空间旋转,并对每个方向进行了一定的缩放,缩放因子就是各个奇异值。然后在U这组正交基向量的空间再次旋转。可以说奇异值分解将一个矩阵原本混合在一起的三种作用效果,分解出来了。
接下来我们从分解的角度重新理解前面的表达式,我们把原来的矩阵A表达成了n个矩阵的和:
SVD奇异值分解

这个式子有什么用呢?注意到,我们假定SVD奇异值分解是按降序排列的,它在某种程度上反映了对应项MiA中的“贡献”。SVD奇异值分解越大,说明对应的MiA的分解中占据的比重也越大。所以一个很自然的想法是,我们是不是可以提取出Mi中那些对A贡献最大的项,把它们的和作为对A的近似?

答案是肯定的,不过等一下,这个想法好像似曾相识?对了,多元统计分析中经典的主成分分析就是这样做的。在主成分分析中,我们把数据整体的变异分解成若干个主成分之和,然后保留方差最大的若干个主成分,而舍弃那些方差较小的。事实上,主成分分析就是对数据的协方差矩阵进行了类似的分解(特征值分解),但这种分解只适用于对称的矩阵,而 SVD 则是对任意大小和形状的矩阵都成立。(SVD 和特征值分解有着非常紧密的联系,此为后话)

我们再回顾一下,主成分分析有什么作用?答曰,降维。换言之,就是用几组低维的主成分来记录原始数据的大部分信息,这也可以认为是一种信息的(有损)压缩。一个矩阵越“奇异”,其越少的奇异值蕴含了更多的矩阵信息,矩阵的信息熵越小(这也符合我们的认知,矩阵越“奇异”,其行(或列)向量彼此越线性相关,越能彼此互相解释,矩阵所携带的信息自然也越少)。

我们用一个图像压缩的例子来说明。我们知道,电脑上的图像(特指位图)都是由像素点组成的,所以存储一张1000×622 大小的图片,实际上就是存储一个1000×622 的矩阵,共622000个元素。这个矩阵用SVD可以分解为622个矩阵之和,如果我们选取其中的前100个之和作为对图像数据的近似,那么只需要存储100个奇异值SVD奇异值分解,100个SVD奇异值分解向量和 100个SVD奇异值分解向量,共计100×(1+1000+622)=162300个元素,大约只有原始的26% 大小.

奇异值分解除了以上提到的应用以外,还有很多应用。这里在介绍两个:

1.潜在语义索引(Latent Semantic Indexing)

与PCA不太一样,至少不是实现了SVD就可以直接用的,不过LSI也是一个严重依赖于SVD的算法,之前吴军老师在矩阵计算与文本处理中的分类问题中谈到:

“三个矩阵有非常清楚的物理含义。第一个矩阵X中的每一行表示意思相关的一类词,其中的每个非零元素表示这类词中每个词的重要性(或者说相关性),数值越大越相关。最后一个矩阵Y中的每一列表示同一主题一类文章,其中每个元素表示这类文章中每篇文章的相关性。中间的矩阵则表示类词和文章类之间的相关性。因此,我们只要对关联矩阵A进行一次奇异值分解,w 我们就可以同时完成了近义词分类和文章的分类。(同时得到每类文章和每类词的相关性)。”


上面这段话可能不太容易理解,不过这就是LSI的精髓内容,我下面举一个例子来说明一下,下面的例子来自LSA tutorial,具体的网址我将在最后的引用中给出:
SVD奇异值分解

这就是一个矩阵,不过不太一样的是,这里的一行表示一个词在哪些title中出现了(一行就是之前说的一维feature),一列表示一个title中有哪些词,(这个矩阵其实是我们之前说的那种一行是一个sample的形式的一种转置,这个会使得我们的左右奇异向量的意义产生变化,但是不会影响我们计算的过程)。比如说T1这个title中就有guide、investing、market、stock四个词,各出现了一次,我们将这个矩阵进行SVD,得到下面的矩阵:
SVD奇异值分解

左奇异向量表示词的一些特性,右奇异向量表示文档的一些特性,中间的奇异值矩阵表示左奇异向量的一行与右奇异向量的一列的重要程序,数字越大越重要。

继续看这个矩阵还可以发现一些有意思的东西,首先,左奇异向量的第一列表示每一个词的出现频繁程度,虽然不是线性的,但是可以认为是一个大概的描述,比如book是0.15对应文档中出现的2次,investing是0.74对应了文档中出现了9次,rich是0.36对应文档中出现了3次;

其次,右奇异向量中的第一行表示每一篇文档中的出现词的个数的近似,比如说,T6是0.49,出现了5个词,T2是0.22,出现了2个词。

然后我们反过头来看,我们可以将左奇异向量和右奇异向量都取后2维(之前是3维的矩阵),投影到一个平面上,可以得到:

SVD奇异值分解

在图上,每一个红色的点,都表示一个词,每一个蓝色的点,都表示一篇文档,这样我们可以对这些词和文档进行聚类,比如说stock 和 market可以放在一类,因为他们老是出现在一起,real和estate可以放在一类,dads,guide这种词就看起来有点孤立了,我们就不对他们进行合并了。按这样聚类出现的效果,可以提取文档集合中的近义词,这样当用户检索文档的时候,是用语义级别(近义词集合)去检索了,而不是之前的词的级别。这样一减少我们的检索、存储量,因为这样压缩的文档集合和PCA是异曲同工的,二可以提高我们的用户体验,用户输入一个词,我们可以在这个词的近义词的集合中去找,这是传统的索引无法做到的。


2.数据分析(dataanalysis)


我们搜集的数据中总是存在噪声:无论采用的设备多精密,方法有多好,总是会存在一些误差的。如果你们还记得上文提到的,大的奇异值对应了矩阵中的主要信息的话,运用SVD进行数据分析,提取其中的主要部分的话,还是相当合理的。作为例子,假如我们搜集的数据如下所示:

<img src="https://pic3.zhimg.com/50/71f0e50096fa09c6496b6c662643d07e_hd.png" data-rawwidth="211" data-rawheight="211" class="content_image" width="211">SVD奇异值分解

我们将数据用矩阵的形式表示:

<img src="https://pic2.zhimg.com/50/70e555bad872479bcb5a79dc8e7f76b5_hd.png" data-rawwidth="415" data-rawheight="46" class="content_image" width="415">SVD奇异值分解

经过奇异值分解后,得到

σ1 = 6.04
σ2 = 0.22

由于第一个奇异值远比第二个要大,数据中有包含一些噪声,第二个奇异值在原始矩阵分解相对应的部分可以忽略。经过SVD分解后,保留了主要样本点如图所示

SVD奇异值分解

就保留主要样本数据来看,该过程跟PCA( principal componentanalysis)技术有一些联系,PCA也使用了SVD去检测数据间依赖和冗余信息.。