奇異值分解(Singular Value Decomposition,如下簡稱SVD)是在機器學習領域普遍應用的算法,它不光能夠用於降維算法中的特徵分解,還能夠用於推薦系統,以及天然語言處理等領域。是不少機器學習算法的基石。本文就對SVD的原理作一個總結,並討論在在PCA降維算法中是如何運用運用SVD的。html
咱們首先回顧下特徵值和特徵向量的定義以下:
\[ Ax=\lambda x \]算法
其中A是一個\(n \times n\)的實對稱矩陣,\(x\)是一個\(n\)維向量,則咱們說\(\lambda\)是矩陣A的一個特徵值,而\(x\)是矩陣A的特徵值\(\lambda\)所對應的特徵向量。微信
求出特徵值和特徵向量有什麼好處呢? 就是咱們能夠將矩陣A特徵分解。若是咱們求出了矩陣A的\(n\)個特徵值\(\lambda_1 \leq \lambda_2 \leq ... \leq \lambda_n\),以及這\(n\)個特徵值所對應的特徵向量\(\{w_1,w_2,...w_n\}\),,若是這\(n\)個特徵向量線性無關,那麼矩陣A就能夠用下式的特徵分解表示:
\[ A=W\Sigma W^{-1} \]app
其中W是這\(n\)個特徵向量所張成的\(n \times n\)維矩陣,而\(\Sigma\)爲這n個特徵值爲主對角線的\(n \times n\)維矩陣。機器學習
通常咱們會把W的這\(n\)個特徵向量標準化,即知足\(||w_i||_2 =1\), 或者說\(w_i^Tw_i =1\),此時W的\(n\)個特徵向量爲標準正交基,知足\(W^TW=I\),即\(W^T=W^{-1}\), 也就是說W爲酉矩陣。post
這樣咱們的特徵分解表達式能夠寫成
\[ A=W\Sigma W^T \]學習
注意到要進行特徵分解,矩陣A必須爲方陣。那麼若是A不是方陣,即行和列不相同時,咱們還能夠對矩陣進行分解嗎?答案是能夠,此時咱們的SVD登場了。大數據
SVD也是對矩陣進行分解,可是和特徵分解不一樣,SVD並不要求要分解的矩陣爲方陣。假設咱們的矩陣A是一個\(m \times n\)的矩陣,那麼咱們定義矩陣A的SVD爲:
\[ A = U\Sigma V^T \]spa
其中U是一個\(m \times m\)的矩陣,\(\Sigma\)是一個\(m \times n\)的矩陣,除了主對角線上的元素之外全爲0,主對角線上的每一個元素都稱爲奇異值,V是一個\(n \times n\)的矩陣。U和V都是酉矩陣,即知足\(U^TU=I, V^TV=I\)。下圖能夠很形象的看出上面SVD的定義:3d
那麼咱們如何求出SVD分解後的\(U, \Sigma, V\)這三個矩陣呢?
若是咱們將A的轉置和A作矩陣乘法,那麼會獲得\(n \times n\)的一個方陣\(A^TA\)。既然\(A^TA\)是方陣,那麼咱們就能夠進行特徵分解,獲得的特徵值和特徵向量知足下式:
\[ (A^TA)v_i = \lambda_i v_i \]
這樣咱們就能夠獲得矩陣\(A^TA\)的n個特徵值和對應的n個特徵向量\(v\)了。將\(A^TA\)的全部特徵向量張成一個\(n \times n\)的矩陣V,就是咱們SVD公式裏面的V矩陣了。通常咱們將V中的每一個特徵向量叫作A的右奇異向量。
若是咱們將A和A的轉置作矩陣乘法,那麼會獲得\(m \times m\)的一個方陣\(AA^T\)。既然\(AA^T\)是方陣,那麼咱們就能夠進行特徵分解,獲得的特徵值和特徵向量知足下式:
\[ (AA^T)u_i = \lambda_i u_i \]
這樣咱們就能夠獲得矩陣\(AA^T\)的m個特徵值和對應的m個特徵向量\(u\)了。將\(AA^T\)的全部特徵向量張成一個\(m \times m\)的矩陣U,就是咱們SVD公式裏面的U矩陣了。通常咱們將U中的每一個特徵向量叫作A的左奇異向量。
U和V咱們都求出來了,如今就剩下奇異值矩陣\(\Sigma\)沒有求出了。因爲\(\Sigma\)除了對角線上是奇異值其餘位置都是0,那咱們只須要求出每一個奇異值\(\sigma\)就能夠了。
咱們注意到:
\[ A=U\Sigma V^T \Rightarrow AV=U\Sigma V^TV \Rightarrow AV=U\Sigma \Rightarrow Av_i = \sigma_i u_i \Rightarrow \sigma_i = Av_i / u_i \]
這樣咱們能夠求出咱們的每一個奇異值,進而求出奇異值矩陣\(\Sigma\)。
上面還有一個問題沒有講,就是咱們說\(A^TA\)的特徵向量組成的就是咱們SVD中的V矩陣,而\(AA^T\)的特徵向量組成的就是咱們SVD中的U矩陣,這有什麼根據嗎?這個其實很容易證實,咱們以V矩陣的證實爲例。
\[ A=U\Sigma V^T \Rightarrow A^T=V\Sigma^T U^T \Rightarrow A^TA = V\Sigma^T U^TU\Sigma V^T = V\Sigma^2V^T \]
上式證實使用了:\(U^TU=I, \Sigma^T\Sigma=\Sigma^2。\)能夠看出\(A^TA\)的特徵向量組成的的確就是咱們SVD中的V矩陣。相似的方法能夠獲得\(AA^T\)的特徵向量組成的就是咱們SVD中的U矩陣。
進一步咱們還能夠看出咱們的特徵值矩陣等於奇異值矩陣的平方,也就是說特徵值和奇異值知足以下關係:
\[ \sigma_i = \sqrt{\lambda_i} \]
這樣也就是說,咱們能夠不用$ \sigma_i = Av_i / u_i\(來計算奇異值,也能夠經過求出\)A^TA$的特徵值取平方根來求奇異值。
這裏咱們用一個簡單的例子來講明矩陣是如何進行奇異值分解的。咱們的矩陣A定義爲:
\[ \mathbf{A} = \left( \begin{array}{ccc} 0& 1\\ 1& 1\\ 1& 0 \end{array} \right) \]
咱們首先求出\(A^TA\)和\(AA^T\)
\[ \mathbf{A^TA} = \left( \begin{array}{ccc} 0& 1 &1\\ 1&1& 0 \end{array} \right) \left( \begin{array}{ccc} 0& 1\\ 1& 1\\ 1& 0 \end{array} \right) = \left( \begin{array}{ccc} 2& 1 \\ 1& 2 \end{array} \right) \]
\[ \mathbf{AA^T} = \left( \begin{array}{ccc} 0& 1\\ 1& 1\\ 1& 0 \end{array} \right) \left( \begin{array}{ccc} 0& 1 &1\\ 1&1& 0 \end{array} \right) = \left( \begin{array}{ccc} 1& 1 & 0\\ 1& 2 & 1\\ 0& 1& 1 \end{array} \right) \]
進而求出\(A^TA\)的特徵值和特徵向量:
\[ \lambda_1= 3; v_1 = \left( \begin{array}{ccc} 1/\sqrt{2} \\ 1/\sqrt{2} \end{array} \right); \lambda_2= 1; v_2 = \left( \begin{array}{ccc} -1/\sqrt{2} \\ 1/\sqrt{2} \end{array} \right) \]
接着求\(AA^T\)的特徵值和特徵向量:
\[ \lambda_1= 3; u_1 = \left( \begin{array}{ccc} 1/\sqrt{6} \\ 2/\sqrt{6} \\ 1/\sqrt{6} \end{array} \right); \lambda_2= 1; u_2 = \left( \begin{array}{ccc} 1/\sqrt{2} \\ 0 \\ -1/\sqrt{2} \end{array} \right); \lambda_3= 0; u_3 = \left( \begin{array}{ccc} 1/\sqrt{3} \\ -1/\sqrt{3} \\ 1/\sqrt{3} \end{array} \right) \]
利用\(Av_i = \sigma_i u_i, i=1,2\)求奇異值:
\[ \left( \begin{array}{ccc} 0& 1\\ 1& 1\\ 1& 0 \end{array} \right) \left( \begin{array}{ccc} 1/\sqrt{2} \\ 1/\sqrt{2} \end{array} \right) = \sigma_1 \left( \begin{array}{ccc} 1/\sqrt{6} \\ 2/\sqrt{6} \\ 1/\sqrt{6} \end{array} \right) \Rightarrow \sigma_1=\sqrt{3} \]
\[ \left( \begin{array}{ccc} 0& 1\\ 1& 1\\ 1& 0 \end{array} \right) \left( \begin{array}{ccc} -1/\sqrt{2} \\ 1/\sqrt{2} \end{array} \right) = \sigma_2 \left( \begin{array}{ccc} 1/\sqrt{2} \\ 0 \\ -1/\sqrt{2} \end{array} \right) \Rightarrow \sigma_2=1 \]
固然,咱們也能夠用\(\sigma_i = \sqrt{\lambda_i}\)直接求出奇異值爲\(\sqrt{3}\)和1.
最終獲得A的奇異值分解爲:
\[ A=U\Sigma V^T = \left( \begin{array}{ccc} 1/\sqrt{6} & 1/\sqrt{2} & 1/\sqrt{3} \\ 2/\sqrt{6} & 0 & -1/\sqrt{3}\\ 1/\sqrt{6} & -1/\sqrt{2} & 1/\sqrt{3} \end{array} \right) \left( \begin{array}{ccc} \sqrt{3} & 0 \\ 0 & 1\\ 0 & 0 \end{array} \right) \left( \begin{array}{ccc} 1/\sqrt{2} & 1/\sqrt{2} \\ -1/\sqrt{2} & 1/\sqrt{2} \end{array} \right) \]
上面幾節咱們對SVD的定義和計算作了詳細的描述,彷佛看不出咱們費這麼大的力氣作SVD有什麼好處。那麼SVD有什麼重要的性質值得咱們注意呢?
對於奇異值,它跟咱們特徵分解中的特徵值相似,在奇異值矩陣中也是按照從大到小排列,並且奇異值的減小特別的快,在不少狀況下,前10%甚至1%的奇異值的和就佔了所有的奇異值之和的99%以上的比例。也就是說,咱們也能夠用最大的k個的奇異值和對應的左右奇異向量來近似描述矩陣。也就是說:
\[ A_{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} \]
其中k要比n小不少,也就是一個大的矩陣A能夠用三個小的矩陣\(U_{m \times k},\Sigma_{k \times k} ,V^T_{k \times n}\)來表示。以下圖所示,如今咱們的矩陣A只須要灰色的部分的三個小矩陣就能夠近似描述了。
因爲這個重要的性質,SVD能夠用於PCA降維,來作數據壓縮和去噪。也能夠用於推薦算法,將用戶和喜愛對應的矩陣作特徵分解,進而獲得隱含的用戶需求來作推薦。同時也能夠用於NLP中的算法,好比潛在語義索引(LSI)。下面咱們就對SVD用於PCA降維作一個介紹。
在主成分分析(PCA)原理總結中,咱們講到要用PCA降維,須要找到樣本協方差矩陣\(X^TX\)的最大的d個特徵向量,而後用這最大的d個特徵向量張成的矩陣來作低維投影降維。能夠看出,在這個過程當中須要先求出協方差矩陣\(X^TX\),當樣本數多樣本特徵數也多的時候,這個計算量是很大的。
注意到咱們的SVD也能夠獲得協方差矩陣\(X^TX\)最大的d個特徵向量張成的矩陣,可是SVD有個好處,有一些SVD的實現算法能夠不求先求出協方差矩陣\(X^TX\),也能求出咱們的右奇異矩陣\(V\)。也就是說,咱們的PCA算法能夠不用作特徵分解,而是作SVD來完成。這個方法在樣本量很大的時候頗有效。實際上,scikit-learn的PCA算法的背後真正的實現就是用的SVD,而不是咱們咱們認爲的暴力特徵分解。
另外一方面,注意到PCA僅僅使用了咱們SVD的右奇異矩陣,沒有使用左奇異矩陣,那麼左奇異矩陣有什麼用呢?
假設咱們的樣本是\(m \times n\)的矩陣X,若是咱們經過SVD找到了矩陣\(XX^T\)最大的d個特徵向量張成的\(m \times d\)維矩陣U,則咱們若是進行以下處理:
\[ X'_{d \times n} = U_{d \times m}^TX_{m \times n} \]
能夠獲得一個\(d \times n\)的矩陣X‘,這個矩陣和咱們原來的\(m \times n\)維樣本矩陣X相比,行數從m減到了d,可見對行數進行了壓縮。也就是說,左奇異矩陣能夠用於行數的壓縮。相對的,右奇異矩陣能夠用於列數即特徵維度的壓縮,也就是咱們的PCA降維。
SVD做爲一個很基本的算法,在不少機器學習算法中都有它的身影,特別是在如今的大數據時代,因爲SVD能夠實現並行化,所以更是大展身手。SVD的原理不難,只要有基本的線性代數知識就能夠理解,實現也很簡單所以值得仔細的研究。固然,SVD的缺點是分解出的矩陣解釋性每每不強,有點黑盒子的味道,不過這不影響它的使用。
(歡迎轉載,轉載請註明出處。歡迎溝通交流: 微信:nickchen121)
```