【转】奇异值分解
奇異值分解(Singular Value Decomposition,以下簡稱SVD)是在機器學習領域廣泛應用的算法,它不光可以用于降維算法中的特征分解,還可以用于推薦系統,以及自然語言處理等領域。是很多機器學習算法的基石。本文就對SVD的原理做一個總結,并討論在在PCA降維算法中是如何運用運用SVD的。
1. 回顧特征值和特征向量
首先回顧下特征值和特征向量的定義如下:
Ax=λxAx = \lambda x Ax=λx
其中AAA是一個n×nn \times nn×n矩陣,xxx是一個nnn維向量,則λ\lambdaλ是矩陣AAA的一個特征值,而xxx是矩陣AAA的特征值λ\lambdaλ所對應的特征向量。
求出特征值和特征向量有什么好處呢? 就是我們可以將矩陣A特征分解。如果我們求出了矩陣A的n個特征值λ1≤λ2≤...≤λn\lambda_1 \leq \lambda_2 \leq ... \leq \lambda_nλ1?≤λ2?≤...≤λn? ,以及這nnn個特征值所對應的特征向量w1,w2,...,wnw_1, w_2, ...,w_nw1?,w2?,...,wn?,
那么矩陣A就可以用下式的特征分解表示:
A=WΣW?1A=W \Sigma W^{-1} A=WΣW?1
其中WWW是這nnn個特征向量所張成的n×nn \times nn×n維矩陣,而Σ\SigmaΣ為這nnn個特征值為主對角線的n×nn \times nn×n維矩陣。
一般我們會把WWW的這nnn個特征向量標準化,即滿足∥wi∥2=1\left \| w_i \right \|_2=1∥wi?∥2?=1,或者∥wiTwi∥=1\left \| w_i^Tw_i\right \|=1∥∥?wiT?wi?∥∥?=1,此時W的nnn個特征向量為標準正交基,滿足WTW=IW^TW=IWTW=I,即WT=W?1W^T=W^{-1}WT=W?1,也就是說W為酉矩陣。
這樣我們的特征分解表達式可以寫成
A=WΣWTA=W \Sigma W^T A=WΣWT
注意到要進行特征分解,矩陣A必須為方陣。
那么如果A不是方陣,即行和列不相同時,我們還可以對矩陣進行分解嗎?答案是可以,此時我們的SVD登場了。
SVD的定義
SVD也是對矩陣進行分解,但是和特征分解不同,SVD并不要求要分解的矩陣為方陣。假設我們的矩陣A是一個m×n的矩陣,那么我們定義矩陣A的SVD為:
A=UΣVTA = U \Sigma V^T A=UΣVT
其中UUU是一個m×mm \times mm×m的矩陣, Σ\SigmaΣ是一個n×nn \times nn×n的矩陣,除了主對角線上的元素以外全為0,主對角線上的每個元素都稱為奇異值, VVV是一個n×nn \times nn×n的矩陣。UUU和VVV都是酉矩陣,即滿足
UTU=I,VTV=IU^TU=I,V^TV=I UTU=I,VTV=I
下圖可以很形象的看出上面SVD的定義:
那么我們如何求出SVD分解后的UUU,Σ\SigmaΣ,VVV這三個矩陣呢?
如果我們將AAA的轉置和AAA做矩陣乘法,那么會得到n×nn \times nn×n的一個方陣ATAA^TAATA。既然ATAA^TAATA是方陣,那么我們就可以進行特征分解,得到的特征值和特征向量滿足下式:
(ATA)vi=λivi(A^TA)v_i = \lambda_iv_i (ATA)vi?=λi?vi?
這樣我們就可以得到矩陣ATAA^TAATA的nnn個特征值和對應的nnn個特征向量vvv了。將ATAA^TAATA的所有特征向量張成一個n×nn \times nn×n的矩陣VVV,就是我們SVD公式里面的VVV矩陣了。一般我們將VVV中的每個特征向量叫做AAA的右奇異向量。
如果我們將AAA和AAA的轉置做矩陣乘法,那么會得到m×mm \times mm×m的一個方陣AATAA^TAAT。既然AATAA^TAAT是方陣,那么我們就可以進行特征分解,得到的特征值和特征向量滿足下式:
(AAT)ui=λiui(AA^T)u_i=\lambda_iu_i (AAT)ui?=λi?ui?
這樣我們就可以得到矩陣AATAA^TAAT的mmm個特征值和對應的mmm個特征向量uuu了。將AATAA^TAAT的所有特征向量張成一個m×mm \times mm×m的矩陣UUU,就是我們SVD公式里面的UUU矩陣了。一般我們將UUU中的每個特征向量叫做A的左奇異向量。
UUU和VVV我們都求出來了,現在就剩下奇異值矩陣Σ\SigmaΣ沒有求出了.
由于Σ\SigmaΣ除了對角線上是奇異值其他位置都是0,那我們只需要求出每個奇異值σ\sigmaσ就可以了。
我們注意到:
A=UΣVT?AV=UΣVTV?AV=UΣ?Avi=σi?σi=Avi/uiA = U\Sigma V^T \Rightarrow AV = U\Sigma V^T V \Rightarrow AV = U\Sigma \Rightarrow Av_i=\sigma_i \Rightarrow \sigma_i=Av_i/u_i A=UΣVT?AV=UΣVTV?AV=UΣ?Avi?=σi??σi?=Avi?/ui?
這樣我們可以求出我們的每個奇異值,進而求出奇異值矩陣Σ\SigmaΣ。
上面還有一個問題沒有講,就是我們說ATAA^TAATA的特征向量組成的就是我們SVD中的VVV矩陣,而AATAA^TAAT的特征向量組成的就是我們SVD中的UUU矩陣,這有什么根據嗎?這個其實很容易證明,我們以VVV矩陣的證明為例。
A=UΣVT?AT=VΣUT?ATA=VΣUTUΣVT=VΣ2VTA=U\Sigma V^T \Rightarrow A^T=V\Sigma U^T \Rightarrow A^TA=V\Sigma U^TU\Sigma V^T = V \Sigma^2V^T A=UΣVT?AT=VΣUT?ATA=VΣUTUΣVT=VΣ2VT
上式證明使用了UTU=I,ΣT=ΣU^TU=I,\Sigma^T=\SigmaUTU=I,ΣT=Σ。可以看出ATAA^TAATA的特征向量組成的的確就是我們SVD中的VVV矩陣。類似的方法可以得到AATAA^TAAT的特征向量組成的就是我們SVD中的UUU矩陣。
進一步我們還可以看出我們的特征值矩陣等于奇異值矩陣的平方,也就是說特征值和奇異值滿足如下關系:
σi=λi\sigma_i=\sqrt{\lambda_i} σi?=λi??
這樣也就是說,我們可以不用σi=AViui\sigma_i=\frac{AV_i}{u_i}σi?=ui?AVi??來計算奇異值,也可以通過求出ATAA^TAATA的特征值取平方根來求奇異值。
3. SVD計算舉例
這里我們用一個簡單的例子來說明矩陣是如何進行奇異值分解的。我們的矩陣A定義為:
data=np.array(([0, 1],[1, 1],[1, 0])) #array([[0, 1], # [1, 1], # [1, 0]])求出ATAA^TAATA和AATAA^TAAT
進而求出ATAA^TAATA的特征值和特征向量:
接著求出AATAA^TAAT的特征值和特征向量:
利用Avi=σiui,i=1,2Av_i=\sigma_iu_i,i=1,2Avi?=σi?ui?,i=1,2求奇異值:
也可以用σi=λi\sigma_i=\sqrt{\lambda _i}σi?=λi??直接求出奇異值為3\sqrt{3}3?和111.
最終得到A的奇異值分解為:
4. SVD的一些性質
對于奇異值,它跟我們特征分解中的特征值類似,在奇異值矩陣中也是按照從大到小排列,而且奇異值的減少特別的快,在很多情況下,前10%甚至1%的奇異值的和就占了全部的奇異值之和的99%以上的比例。
也就是說,我們也可以用最大的k個的奇異值和對應的左右奇異向量來近似描述矩陣。
也就是說:
Am×n=Um×mΣm×nVn×nT≈Um×kΣk×kVk×nTA_{m \times n} = U_{m \times m} \Sigma_{m \times n} V^T_{n \times n} \approx U_{m \times k} \Sigma_{k \times k} V^T_{k \times n} Am×n?=Um×m?Σm×n?Vn×nT?≈Um×k?Σk×k?Vk×nT?
其中kkk要比nnn小很多,也就是一個大的矩陣AAA可以用三個小的矩陣Um×k,Σk×k,Vk×nU_{m \times k},\Sigma_{k \times k},V_{k \times n}Um×k?,Σk×k?,Vk×n?來表示。如下圖所示,現在我們的矩陣A只需要灰色的部分的三個小矩陣就可以近似描述了。
由于這個重要的性質,SVD可以用于PCA降維,來做數據壓縮和去噪。也可以用于推薦算法,將用戶和喜好對應的矩陣做特征分解,進而得到隱含的用戶需求來做推薦。同時也可以用于NLP中的算法,比如潛在語義索引(LSI)。
下面我們就對SVD用于PCA降維做一個介紹。
5. SVD用于PCA
PCA降維,需要找到樣本協方差矩陣XXTXX^TXXT的最大的ddd個特征向量,然后用這最大的ddd個特征向量張成的矩陣來做低維投影降維。可以看出,在這個過程中需要先求出協方差矩陣XTXX^TXXTX,當樣本數多樣本特征數也多的時候,這個計算量是很大的。
注意到我們的SVD也可以得到協方差矩陣XTXX^TXXTX最大的ddd個特征向量張成的矩陣,但是SVD有個好處,有一些SVD的實現算法可以不求先求出協方差矩陣XTXX^TXXTX,也能求出我們的右奇異矩陣VVV。也就是說,我們的PCA算法可以不用做特征分解,而是做SVD來完成。這個方法在樣本量很大的時候很有效。實際上,scikit-learn的PCA算法的背后真正的實現就是用的SVD,而不是我們我們認為的暴力特征分解。
另一方面,注意到PCA僅僅使用了我們SVD的右奇異矩陣,沒有使用左奇異矩陣,那么左奇異矩陣有什么用呢?
假設我們的樣本是m×nm \times nm×n的矩陣X,如果我們通過SVD找到了矩陣XXTXX^TXXT最大的ddd個特征向量張成的m×dm \times dm×d維矩陣UUU,則我們如果進行如下處理:
xd×n′=Ud×mTXm×nx^\prime_{d \times n} = U^T_{d \times m} X_{m \times n} xd×n′?=Ud×mT?Xm×n?
可以得到一個d×nd \times nd×n的矩陣X′X^\primeX′,這個矩陣和我們原來的m×nm \times nm×n維樣本矩陣XXX相比,行數從mmm減到了kkk,可見對行數進行了壓縮。
左奇異矩陣可以用于行數的壓縮。
右奇異矩陣可以用于列數即特征維度的壓縮,也就是我們的PCA降維。
6. SVD小結
SVD作為一個很基本的算法,在很多機器學習算法中都有它的身影,特別是在現在的大數據時代,由于SVD可以實現并行化,因此更是大展身手。
SVD的缺點是分解出的矩陣解釋性往往不強,有點黑盒子的味道,不過這不影響它的使用。
總結
- 上一篇: 种植牙会生长吗
- 下一篇: 小米电视4怎样外接音响