機器學習 | SVD矩陣分解算法,對矩陣做拆分,然后呢?


本文始發於個人公眾號:TechFlow,原創不易,求個關注


今天是機器學習專題第28篇文章,我們來聊聊SVD算法。

SVD的英文全稱是Singular Value Decomposition,翻譯過來是奇異值分解。這其實是一種線性代數算法,用來對矩陣進行拆分。拆分之后可以提取出關鍵信息,從而降低原數據的規模。因此廣泛利用在各個領域當中,例如信號處理、金融領域、統計領域。在機器學習當中也有很多領域用到了這個算法,比如推薦系統、搜索引擎以及數據壓縮等等。

SVD簡介

我們假設原始數據集矩陣D是一個mxn的矩陣,那么利用SVD算法,我們可以將它分解成三個部分:

這三個矩陣當中U是一個m x n的矩陣,是一個m x n的對角矩陣,除了對角元素全為0,對角元素為該矩陣的奇異值。V是一個n x n的矩陣。U和V都是酉矩陣,即滿足。也就是它乘上它的轉置等於單位對角矩陣。

我們可以看下下圖,從直觀上感知一下這三個矩陣。

下面我們來簡單推導一下SVD的求解過程,看起來很復雜,概念也不少,但是真正求解起來卻並不難。會需要用到矩陣特征值分解的相關概念,如果不熟悉的同學可以先看下線性代數專題相關內容做個回顧:

線性代數精華——矩陣的特征值與特征向量

首先,如果我們計算可以得到一個n x n的方陣。對於方陣我們可以對它進行特征分解,假設得到特征值是,特征向量是,代入特征值的性質可以得到:

這樣的特征值和特征向量一共會有n個,我們把它所有的特征向量組合在一起,可以得到一個n x n的矩陣V。它也就是我們SVD分解結果之后的V,所以有些書上會把它叫做右奇異向量。

同理,我們計算可以得到一個m x m的方陣,我們同樣可以對他進行特征值分解,得到一個特征矩陣U。U應該是一個m x m的矩陣,也就是SVD公式中的U,我們可以將它稱為A的左奇異向量。

U和V都有了,我們只剩下還沒求出來了。由於它是一個對角矩陣,除了對角元素全為0,所以我們只需要求出它當中的每一個對角元素,也就是奇異值就可以了,我們假設奇異值是,我們對SVD的式子進行變形:

這個推導當中利用了V是酉矩陣的性質,所以我們乘上了V將它消除,就推導得到了奇異值的公式,矩陣也就不難求了。

整個推導的過程不難,但是有一個問題沒解決,為什么的特征矩陣就是SVD中的U矩陣了,原理是什么?這一步是怎么推導來的?說實話我也不知道天才數學家們這一步是怎么推導得到的,我實在腦補不出來當時經過了怎樣的思考才得到了這個結果,但是想要證明它是正確的倒不難。

這里也同樣利用了酉矩陣的性質,還有對角矩陣乘法的性質。我們可以看出來,U的確是特征向量組成的矩陣,同樣也可以證明V。其實如果眼尖一點還可以發現特征值矩陣等於奇異值矩陣的平方,所以

所以,我們求解矩陣可以不用很麻煩地通過矩陣去計算,而是可以通過的特征值取平方根來求了。

SVD的用途

我們推導了這么多公式,那么這個SVD算法究竟有什么用呢?

看來看去好像看不出什么用途,因為我們把一個矩陣變成了三個,這三個矩陣的規模也並沒有降低,反而增加了。但是如果去研究一下分解出來的奇異值,會發現奇異值降低的特別快。只要10%甚至是1%的奇異值就占據了全部奇異值之和的99%以上的比例。

換句話說,我們並不需要完整的SVD分解結果,而是只需要篩選出其中很少的k個奇異值,和對應的左右奇異向量就可以近似描述原矩陣了。

我們看下下圖,相當於我們從分解出來的矩陣當中篩選一小部分來代替整體,並且保留和整體近似的信息。

我們把式子寫出來:

這里的k遠小於n,所以我們可以大大降低SVD分解之后得到的矩陣參數的數量。

也就是說,我們通過SVD分解,將一個m x n的大矩陣,分解成了三個小得多的小矩陣。並且通過這三個小矩陣,我們可以還原出原矩陣大部分的信息。不知道大家有沒有想到什么?是了,這個和我們之前介紹的PCA算法如出一轍。不僅思路相似,就連計算的過程也重合度非常高,實際上PCA算法的求解方法之一就是通過SVD矩陣分解。

SVD與PCA

我們來簡單看看SVD和PCA之間的關聯。

首先復習一下PCA算法,我們首先計算出原始數據的協方差矩陣X,再對進行矩陣分解,找到最大的K個特征值。然后用這K個特征值對應的特征向量組成的矩陣來對原始數據做矩陣變換。

在這個過程當中,我們需要計算,當X的規模很大的時候,這個計算開銷也是很大的。注意到我們在計算SVD中V矩陣的時候,也用到了矩陣的特征值分解。然而關鍵是一些計算SVD的算法可以不先求出協方差矩陣也能得到V,就繞開了這個開銷很大的步驟。

所以目前流行的PCA幾乎都是以SVD為底層機制實現的,比如sklearn庫中的PCA工具就是用的SVD。

代碼實現

關於SVD算法我們並不需要自己實現,因為numpy當中封裝了現成的SVD分解方法

我們直接調用np.linalg.svd接口即能完成矩陣的分解:

這里的Sigma返回的是一個向量,代替了對角矩陣,節省了存儲開銷。我們可以通過找出最小的K,使得K個奇異值占據整體奇異值95%以上的和。這里可以看到,我們選出了5個奇異值就占據所有奇異值和的99%以上:

總結

我們今天和大家分享了SVD算法的原理,以及一種常規的計算方法。SVD和PCA一樣底層都是基於矩陣的線性操作完成的,通過SVD的性質,我們可以對原數據進行壓縮和轉化。基於這一點,衍生出了許多的算法和應用場景,其中最經典的要屬推薦系統中的協同過濾了。由於篇幅限制,我們將會在下一篇文章當中和大家分享這一點,實際了解一下SVD的應用,加深一下理解。

由於SVD可以實現並行化計算,使得在實際當中它更受歡迎。但SVD也不是萬能的,它一個很大的缺點就是和PCA一樣解釋性很差,我們無法得知某些值或者是某些現象的原因。關於這一點,我們也會在下一篇文章當中加以體現。

今天的文章到這里就結束了,如果喜歡本文的話,請來一波素質三連,給我一點支持吧(關注、轉發、點贊)。

本文使用 mdnice 排版


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM