看了几篇关于奇异值分解(Singular Value Decomposition,SVD)的博客,大部分都是从坐标变换(线性变换)的角度来阐述,讲了一堆坐标变换的东西,整了一大堆图,试图“通俗易懂”地向读者解释清楚这个矩阵分解方法。然而这个“通俗易懂”到我这就变成了“似懂非懂”,这些漂亮的图可把我整懵了。
就像《没想到吧》里王祖蓝对一个碎碎念的观众说的,“我问你的问题是,你是很熟悉邓紫棋的歌吗,我只问了你一个问题,你回我这么多干嘛”(上B站忍不住又看了邓紫棋3个视频,差点回不来)。我就想知道这个奇异值分解的数学公式是什么,然后明白它是怎么一步步推导出来的,以及怎么推导出奇异值分解和主成分分析法的关系,咋就要整这么多图呢?
如果你也有这种感觉,那这篇博客就带着你,以数学推导为主,一步步搞清楚奇异值分解是什么。这篇博客反其道而行之,全是数学推导,没有一个图,就是这么任性。当然相信我,这些推导并不难。
这篇博客整理如下的内容:
1、奇异值分解的数学公式;
2、奇异值分解的流程总结和案例;
3、用奇异值分解进行降维;
4、特征分解、奇异值分解和主成分分析法的关系;
5、奇异值分解在词向量降维中的应用。
一、奇异值分解的数学公式
我们直接抛出相关结论,不推导也不证明。
一个n×m的矩阵X的奇异值分解定义为:
其中U称为左奇异矩阵,是一个n×n的正交矩阵,即满足UU=E,U=U;而V称为右奇异矩阵,是一个m×m的正交矩阵。Σ为n×m的对角矩阵,对角线上的非零元素是奇异值(Singular Value)。
1、求奇异值
首先看Σ或者说奇异值是什么。如果矩阵X的秩rank(A)=r,那么实对称矩阵XX与X的秩相等,XX有r个非零的特征值和m-r个零特征值:λ≥λ≥ λ...≥λ>λ=...=λ=0。奇异值σ为:
矩阵Σ可以表示为:
2、求右奇异矩阵V
然后看右奇异矩阵V是什么。将V写成列向量的形式(v, v, ...v,.. v),那么V的列向量是实对称矩阵XX的单位特征向量,也就是有:
3、求左奇异矩阵U
(1)第一种做法
第一种做法更多是为了与右奇异矩阵V的求法相对应,实际计算时会采用另外的方法。前面说了实对称矩阵XX与X的秩相等,有r个非零特征值,那么另一个实对称矩阵XX与XX的秩相等,同样有r个非零特征值,且这两个矩阵的非零特征值相等。将U也写成列向量的形式(u, u, ...u,.. u),那么U的列向量是实对称矩阵XX的单位特征向量,也就是有:
看到这里,虽然不知道这是怎么推导过来的,但是感受到了一种强烈的数学之美,有没有!
(2)第二种做法
在第二种做法中,我们会充分利用实对称矩阵XX与右奇异矩阵V,来求得左奇异矩阵U,而不用另外去求XX的单位特征向量。我们首先把XX的特征值分为两组:特征值大于零的一组(r个),特征值等于零的一组(m-r个),相应的把右奇异矩阵的列向量分为两组:前r个非零特征值对应的单位特征向量为V=(v, v, ...v),而零特征值对应的单位特征向量为V=(v,.. v)。再把左奇异矩阵U的列向量也分为两组,尽管我们还不知道具体的元素值,但是我们知道它有n个列向量:前r个列向量U=(u, u, ...u),后n-r个列向量U=(u, u, ...u)。那么我们可以用X、V和奇异值构成的对角阵方阵S来求出U。
由第一种做法我们已知U是XX非零特征值的单位特征向量,那么U就是零特征值的单位特征向量了。我们不用去求U,只要构造n-r个列向量,每一个列向量满足:与其他n-1个列向量正交,且是单位向量——这通常是比较容易构造的。于是我们就得到了左奇异矩阵U=(U, U)。
我们还可以证明一下,由XVS所得到的U的确满足:列向量相互正交且为单位向量。这个证明很有用,并不复杂。
二、奇异值分解的流程和案例
好,有了第一部分的内容,那尽管我们不知道怎么推导出来的,我们也已经知道如何进行奇异值分解了。
1、奇异值分解的计算过程
如果有一个n×m的矩阵X,秩为r,那么对X进行奇异值分解的一种做法是:
X的m个特征值λ(其中非零的有r个)和m个单位特征向量v,
(2)把m个特征值λ从大到小排序,求出奇异值σ=√λ(i=1,...,r),并得到S=diag(σ,σ,...,σ);
(3)相应地把m个特征向量v进行排列,就可以得到右奇异矩阵V=(v, v, ...v,.. v),同时得到非零特征值的特征向量矩阵V=(v, v, ...v);
(4)由XVS求出n×r的矩阵U,写成U=(u, u, ...u);
(5)构造n-r个列向量u,每个都满足与其他n-1个列向量正交且是单位向量的条件,写成U=(u, u, ...u),于是得到左奇异矩阵U=(U, U)=(u, u, ... u, ..., u);
(6)得到X的奇异值分解:
接下来我们就举一个简单的例子,按这个流程走一遍。
2、奇异值分解的小案例
问题:
对以下的矩阵X进行奇异值分解。
求解:
三、用奇异值分解做降维
用奇异值分解做降维,主要用到了线性代数里的分块矩阵理论。
1、简化奇异值分解
我们可以看到矩阵Σ由奇异值和很多0元素构成,这些0看着很多余很难受对不对?尤其是对角线上的!所幸我们可以用分块矩阵的理论,把Σ中为0的对角元素抛弃掉。
和之前一样,X是n×m的矩阵,右奇异矩阵V中的前r个列向量为V=(v, v, ...v),左奇异矩阵U中的前r个列向量为U=(u, u, ...u),S=diag(σ,σ,...,σ)是奇异值构成的对角矩阵。则可以将奇异值分解的形式化简为X=USV。
2、用奇异值分解降维
我们是用分块矩阵对原来的奇异值分解形式进行化简的,现在让我们分块到底!
我们知道U中有r个列向量,我们再将其分块,比如我们想把维度降到d维(d<r),那么把U分块为两个子矩阵U=[U, U],有U=[u,u,...,u],U=[u,u,...,u]。
同样把V进行分块,得到V=[V, V],V=[v,v,...,v],V=[v,v,...,v]。
于是我们可以把X=USV也分块成:
因此如果我们想把维度降到d维,那么就让X≈USV。这样我们就舍弃了r-d维的信息USV,那不免让人担心,信息是否会损失太多。那如何计算损失的信息量呢?
3、度量降维后的信息量
在主成分分析法的文章中,提到了可以用数据集的方差来衡量数据所包含的信息量,方差越大,包含的信息越多。而方差又和特征值密切相关,在某些特殊情况下方差就等于特征值。于是我们隐约感觉到可以用我们求出来的奇异值或者特征值来度量矩阵的信息量。
是的,矩阵X的信息量就定义为所有奇异值的平方和,也就是XX的特征值之和:F=λ+λ+…+λ。
那么降维后的矩阵USV的信息量为:F=λ+λ+…+λ,而损失的信息为矩阵USV的信息量:F=λ+λ+…+λ
于是损失的信息量占总信息量的比例为:
这样我们就可以清晰地看到降到d维后,信息量是否损失太大,是否让我们无法承受。不过好在S中的奇异值是从大到小进行排列的,而且一般下降得特别快,前面少数几个奇异值的平方占总信息量的比例一般就已经很大了,剩下的舍弃了影响也不会很大。
好,到这里我们就明白了怎么度量降维后的矩阵所包含的信息量了。
然后,作为好奇宝宝的你也许会问,为什么矩阵X的信息量就是所有奇异值的平方和呢?好的,邓紫棋已经听到你的呼唤了,返场唱最后一首歌。这里是用矩阵X的F范数的平方来度量信息量。
什么是矩阵的F范数呢?矩阵的F范数定义为矩阵中每个元素平方之和的平方根,那么F范数的平方就是每个元素的平方和。
因为矩阵X每个元素的平方和(F范数的平方)是方阵XX的对角线元素之和(迹),于是我们进行证明:
其实不证明我们也知道方阵XX的对角线元素之和(迹)就是其特征值之和,哈哈哈,被我带偏了。
四、特征分解、奇异值值分解与主成分分析法
1、由特征分解到奇异值分解
(1)什么是特征分解
一个n×n的方阵A的特征分解(Eigenvalue Decomposition )定义为:
其中V是n×n的方阵,其中每一列都是A的特征向量,∧是对角阵,其中每一个元素是A的特征值。
如果A是对称矩阵,那么A的特征分解就变成了:
其中V是正交矩阵,即V=V。注意是方阵才可以进行特征分解哦。
(2)推导奇异值分解
如果有一个n×m的矩阵X,我们是没法对X进行特征分解的,那么怎么由特征分解推导出奇异值分解呢?
我们注意到XX是m×m实对称矩阵,于是先对XX进行特征分解:
V的列向量是单位特征向量,对角阵∧中的对角元素是特征值,且我们对特征值进行降序排列。假设X的秩为r,那么非零的特征值有r个。
V中的列向量(v, v, ...v,.. v)可以看成是m维空间中的m个标准正交基。XX特征分解就相当于一个线性变换,用标准正交基构成的矩阵V对对角矩阵进行线性变换,得到XX。
那么n×m的矩阵X应该也可以由一个n维空间中的n个标准正交基和一个m维空间中的m个标准正交基,对某个矩阵进行线性变换得到。我们想办法来找到这些标准正交基。
我们就让XX的单位特征向量V=(v, v, ...v,.. v)作为m个标准正交基,再找另外n个标准正交基。瞎折腾了一阵后,突然发现Xv与Xv是正交的!
太好了!这意味着只要我们把(Xv,Xv,..., Xv)中的非零列向量进行标准化,就可以得到另一组标准正交基了!如果X的秩为r,那么非零列向量是(Xv,Xv,..., Xv)(我不知道这怎么来的,装逼失败),且满足:
于是我们对Xv进行标准化:
得到了r个标准正交基(u, u, ... u),可是我们需要n个,还少了n-r个。没关系,我们直接找任意n-r个列向量,填补上去,使得U=(u, u, ... u, ..., u)是一组标准正交基。σ是奇异值,我们用σ作为对角元素来构造一个n×m维的矩阵Σ,那么X就可以用U和V这两个标准正交基组对Σ进行线性变换得到,也就是奇异值分解:X=UΣV。
2、奇异值分解与主成分分析法
奇异值分解是主成分分析法的一种常用的解决方案。如果数据集X是一个n×m的矩阵,n是变量的个数,m是样本的数量,那么进行主成分分析,也就是用奇异值分解的左奇异矩阵或者右奇异矩阵的装置作为主成分分析法中的转换矩阵,去乘以数据集X,从而得到主成分矩阵Y。
(1)为什么用奇异值分解
可是在《降维之主成分分析法(PCA)》中,我们明白了,可以求出X的协方差矩阵的单位特征向量矩阵E,用E的转置E作为转换矩阵P,然后由PX=Y得到主成分矩阵,再挑出前k主成分就可以做到降维。那我们直接去求E不就好了吗?干嘛还要把奇异值分解拉扯进来?
这是因为求解n维矩阵XX的特征值和特征向量的算法复杂度为O(n),因此如果X是高维的数据,也就是n非常大时,进行主成分分析就要计算超大矩阵的特征值。这就出现了算法复杂度过高,计算效率太低的问题。
可是奇异值分解也要对矩阵XX进行特征分解来求右奇异矩阵V啊,算法复杂度不也是O(n)?是这样的,不过对高维矩阵进行奇异值分解时,有一些更高效的算法,不用采取暴力特征分解的方式。
(2)奇异值分解与主成分分析法等价
我们先按照主成分分析法的步骤,对XX进行特征分解,得到:
然后对X进行奇异值分解,沿用前面的符号体系,得到X=UΣV,把X的奇异值分解代入到上面的特征分解式中:
由于在主成分分析法中我们用E作为转换矩阵P,那么从上面的推导可知,可以用X的左奇异矩阵U的转置U作为转换矩阵P,来求出主成分矩阵Y,UX=Y。
(3)用奇异值分解做主成分降维
X的奇异值分解还可以简化地写成X=USV,同样代入XX的特征分解中,得到:XX=USSU。U=(u, u, ...u)是n×r的矩阵,那么U是一个r×n的矩阵,UX就把X的特征从n维降至了r维。
进一步,我们在前面用分块矩阵的思想,把U分块为U=[U, U],U是一个d×n维的矩阵,那么用U作为转换矩阵,就可以把X的特征进一步压缩至d维。
(4)其他补充
如果你看了其他博主写的博客,会发现有些是用右奇异矩阵V的转置V来作为特征压缩的转换矩阵,和本文不一样。这是因为那些博客把有m个样本,n维特征的数据集写成了m×n的矩阵X,而本文把数据集写成n×m的矩阵,所以那些博客是用右奇异矩阵V,而本文是用左奇异矩阵U。
五、奇异值分解与词向量降维
我们来看怎么把奇异值分解用在词向量降维上。如果我们手头有一份文本数据集,里头有m篇文档,总共有n个不重复的词,那么我们可以通过统计文档中所有词出现的次数,整理成一个矩阵X,来构造词向量。
一般有两种方法来构造词向量矩阵:一是TF-IDF,词向量矩阵是n×m维的,行向量是每个词的词向量;二是基于窗口的共现矩阵,如果窗口是1,那么词向量矩阵是n×n维的,行向量是每个词的词向量。这两种词向量的表示方法存在很大的问题,那就是数据稀疏和词表维度过高。想象一下,如果文档有10万篇,词有5万个,那会是多么恐怖的一个场景。
因此我们非常有必要运用奇异值分解,对词向量矩阵进行降维。
1、对TF-IDF词向量矩阵进行降维
TF-IDF不用多解释了,由每个词的词频和逆文档频率两部分计算得到每个词的TF-IDF,然后所有词的TF-IDF构成词向量矩阵X。这个矩阵太大了,我们对这个矩阵X进行奇异值分解得到USV,U是n×r的矩阵,我们用U的行向量作为n个词的词向量,就实现了对文档数量维度的压缩。
如果还嫌词表维度太高,那么我们可以继续降维,从U中拿出前d个列向量,组成新的n×d维的词向量矩阵U,行向量作为降到d维后每个词的词向量。
d取多少合适呢?我们可以用奇异值的平方和计算降到d维后的剩余的信息量。如果我们希望保留85%的信息,那么就取以下公式大于或等于85%时的d值,作为降维后的维度。
2、对基于窗口的共现矩阵进行降维
这种方法是用一个相关性矩阵来构造词向量矩阵,叫做共现矩阵。 假设有3个句子(看成三篇文档也没毛病),一共8个不重复的词(把标点也算上),窗口设定为1,也就是把句子拆成一个个的词。
- I enjoy flying.
- I like NLP.
- I like deep learning
那么共现矩阵就是一个8维的方阵X:
同样用奇异值分解,把X分解为X=USV,然后用U的行向量作为每次词的词向量,就把词向量的维度从n维降到了r维。如果觉得还太高了,那么可以按照TF-IDF中的做法,继续进行降维。
参考资料:
1、《A Tutorial on Principal Component Analysis. Derivation, Discussion and Singular Value Decomposition》
2、《A Singularly Valuable Decomposition: The SVD of a Matrix 》