機器學習_用SVD奇異值分解給資料降維

xieyan0811發表於2017-11-22

 本想把PCA和SVD寫在一起,可上篇PCA還沒寫清楚就已經4頁word了。再把SVD和特徵工程的內容加上,實在是太長了,一下說太多也記不住,於是重開一篇。
 SVD用到的原理和 PCA非常相似,就不再此贅述了,如果對特徵值、特徵向量相關問題不清楚請參見前篇《機器學習_用PCA主成分分析給資料降維》

1. 原理

 先回憶一下特徵值分解:把向量x往特徵向量方向上分解,然後每個方向上做伸縮,最後再把結果加起來即可。也可以理解為將向量x轉到正交座標系,在各個座標軸的方向上縮放後,再轉換回原來的座標系。只有方陣才能做特徵值分解,因此我們在PCA中不是直接對資料做分解,而是對引數的協方差矩陣做分解。
 我們知道,任何矩陣都可以分解為三個矩陣的乘積 A=U * Sigma * VT,也就是奇異值分解.其中 U 和VT 均是酉陣(正交陣在複數域的推廣),而 Sigma 為增廣對角陣。從直觀上講,U 和 VT 可視為旋轉操作,Sigma 可視為縮放操作。因此奇異值分解的含義就是說,若將矩陣看做一個變換,那麼任何這樣的變換可以看做是兩個旋轉和一個縮放變換的複合,這點和特徵值分解基本一樣。它也可以通過對Sigma的調整實現降維,通過U和VT在高維和低維間轉換。相位元徵值分解,奇異值分解可處理的不只是協方差矩陣(方陣),還可以直接處理資料。


圖片引自百度百科

 但SVD也有一些問題,比如資料多的時候,奇異值分解的計算量會很大,不像PCA做特徵值分解時,矩陣的大小隻和屬性個數相關。

2. 例程

(1) 功能

對矩陣A做SVD分解;降維;原始資料轉到低維度;降維後的資料恢復到原來維度,看資料損失。

(2) 程式碼

from numpy import linalg
import array
import numpy as np

A=np.mat([[1,2,3],[4,5,6]])  
U,Sigma,VT=linalg.svd(A)  
print("U",U)
print("Sigma",Sigma)
print("VT",VT)
Sigma[1]=0 # 降維
print("Sigma",Sigma)

S = np.zeros((2,3))
S[:2, :2] = np.diag(Sigma)
print("A conv:", np.dot(np.dot(A.T, U), S)) # 原始資料轉到低維
print("A':", np.dot(np.dot(U, S), VT)) # 恢復原始維度

(3) 執行結果

('U', matrix([[-0.3863177 , -0.92236578],
        [-0.92236578,  0.3863177 ]]))
('Sigma', array([ 9.508032  ,  0.77286964]))
('VT', matrix([[-0.42866713, -0.56630692, -0.7039467 ],
        [ 0.80596391,  0.11238241, -0.58119908],
        [ 0.40824829, -0.81649658,  0.40824829]]))
('Sigma', array([ 9.508032,  0.      ]))
('A conv:', matrix([[-38.7526545 ,   0.        ,   0.        ],
        [-51.19565893,   0.        ,   0.        ],
        [-63.63866337,   0.        ,   0.        ]]))
("A':", matrix([[ 1.57454629,  2.08011388,  2.58568148],
        [ 3.75936076,  4.96644562,  6.17353048]]))

(4) 分析

 SVD分解矩陣A,A是一個2x3(mn,其中m是行數)的矩陣,把它分解成三個矩陣的乘積:A=U * Sigma * VT,其中U的大小是2x2(mm),VT為33(nn),Sigma為min(m,n),從矩陣乘法的角度上看,Sigma的大小應該是m*n,由於它是對角陣,為了簡化,這裡只取了對角線上元素。
 Sigma奇異值為(9.508032,0.77286964),兩值差異很大,說明轉換後特徵主要集中在一個維度上,於是降維,Sigma調整 為(9.508032,0)。將原始矩陣A轉置後乘U和調整後的Sigma,實現了對A的降維。最後,將調整後的Sigma與U,VT相乘,對映回原始維度,變為矩陣A’,對比之下,A’與A的也差不太多。不過把兩維降成一維還是挺誇張的,在此只為舉例,大家領會精神吧。
 這裡比較重的是:觀察Sigma,決定保留前幾項?svd()函式對求出的奇異值和奇異向量按大小做了排序,其中值明顯大的前N項,說明有N個“綜合引數”最重要,因此,可以將資料降成N維。可降維度的多少,主要還是看資料的相關性,相關性越大,越適合降維。

3. 具體應用

(1) 圖片壓縮

 把圖片的畫素放一個矩陣裡,做SVD分解,只保留Sigma中值大的前N項。則儲存時只需儲存三個矩陣,假設原圖大小100x100,N為5,則原圖要10000點儲存,而拆分後100x5+100x5+5=1005,影象大小變為原來的1/10。

(2) 資料降維

 矩陣中記20人試吃這5種套餐的評價(5x20),先對整體資料做SVD分解,假設保留Sigma的前3項,把原矩陣轉置並和U,Sigma相乘,矩陣就從520維變成了35維。再套用各種學習演算法時,資料就大大縮減了(從高維到低維投影)。不過20個維度變為3個維度後,屬性意義也不像之前那麼直觀了,我們可以使用VT矩陣把資料恢復到原來的維度。


技術文章定時推送
請關注公眾號:演算法學習分享

相關文章