1. 程式人生 > >PCA與SVD簡潔解析(參考CS231n)

PCA與SVD簡潔解析(參考CS231n)

PCA演算法

PCA的演算法步驟:

設有m條n維資料。

1)將原始資料按列組成n行m列矩陣X

2)將X的每一行(代表一個屬性欄位)進行零均值化,即減去這一行的均值

3)求出協方差矩陣C=1mXXTC=1mXXT

4)求出協方差矩陣的特徵值及對應的特徵向量

5)將特徵向量按對應特徵值大小從上到下按行排列成矩陣,取前k行組成矩陣P

6)Y=PXY=PX即為降維到k維後的資料

PCA的全部工作簡單點說,就是對原始的空間中順序地找一組相互正交的座標軸,第一個軸是使得方差最大的,第二個軸是在與第一個軸正交的平面中使得方差最大的,第三個軸是在與第1、2個軸正交的平面中方差最大的,這樣假設在N維空間中,我們可以找到N個這樣的座標軸,我們取前r個去近似這個空間,這樣就從一個N維的空間壓縮到r維的空間了,但是我們選擇的r個座標軸能夠使得空間的壓縮使得資料的損失最小

PCA和白化(Whitening)是一種預處理形式。在這種處理中,先對資料進行零中心化處理,然後計算協方差矩陣,它展示了資料中的相關性結構。

# 假設輸入資料矩陣X的尺寸為[N x D]
X -= np.mean(X, axis = 0) # 對資料進行零中心化(重要)
cov = np.dot(X.T, X) / X.shape[0] # 得到資料的協方差矩陣

資料協方差矩陣的第(i, j)個元素是資料第i個和第j個維度的協方差。具體來說,該矩陣的對角線上的元素是方差。還有,協方差矩陣是對稱和半正定的。我們可以對資料協方差矩陣進行SVD(奇異值分解)運算。

U,S,V = np.linalg
.svd(cov)

U的列是特徵向量,S是裝有奇異值的1維陣列(因為cov是對稱且半正定的,所以S中元素是特徵值的平方)。為了去除資料相關性,將已經零中心化處理過的原始資料投影到特徵基準上:

Xrot = np.dot(X,U) # 對資料去相關性

注意U的列是標準正交向量的集合(正規化為1,列之間標準正交),所以可以把它們看做標準正交基向量。因此,投影對應x中的資料的一個旋轉,旋轉產生的結果就是新的特徵向量。如果計算Xrot的協方差矩陣,將會看到它是對角對稱的。np.linalg.svd的一個良好性質是在它的返回值U中,特徵向量是按照特徵值的大小排列的。我們可以利用這個性質來對資料降維,只要使用前面的小部分特徵向量,丟棄掉那些包含的資料沒有方差

的維度。 這個操作也被稱為主成分分析( Principal Component Analysis 簡稱PCA)降維:

Xrot_reduced = np.dot(X, U[:,:100]) # Xrot_reduced 變成 [N x 100]

經過上面的操作,將原始的資料集的大小由[N x D]降到了[N x 100],留下了資料中包含最大方差的100個維度。通常使用PCA降維過的資料訓練線性分類器和神經網路會達到非常好的效能效果,同時還能節省時間和儲存器空間。

最後一個在實踐中會看見的變換是白化(whitening)。白化操作的輸入是特徵基準上的資料,然後對每個維度除以其特徵值來對數值範圍進行歸一化。該變換的幾何解釋是:如果資料服從多變數的高斯分佈,那麼經過白化後,資料的分佈將會是一個均值為零,且協方差相等的矩陣。該操作的程式碼如下:

# 對資料進行白化操作:
# 除以特徵值 
Xwhite = Xrot / np.sqrt(S + 1e-5)

警告:誇大的噪聲。注意分母中添加了1e-5(或一個更小的常量)來防止分母為0。該變換的一個缺陷是在變換的過程中可能會誇大資料中的噪聲,這是因為它將所有維度都拉伸到相同的數值範圍,這些維度中也包含了那些只有極少差異性(方差小)而大多是噪聲的維度。在實際操作中,這個問題可以用更強的平滑來解決(例如:採用比1e-5更大的值)。

奇異值分解

特徵值分解是一個提取矩陣特徵很不錯的方法,但是它只是對方陣而言的,在現實的世界中,我們看到的大部分矩陣都不是方陣,比如說有N個學生,每個學生有M科成績,這樣形成的一個N * M的矩陣就不可能是方陣,我們怎樣才能描述這樣普通的矩陣呢的重要特徵呢?奇異值分解可以用來幹這個事情,奇異值分解是一個能適用於任意的矩陣的一種分解的方法:

假設A是一個N * M的矩陣,那麼得到的U是一個N * N的方陣(裡面的向量是正交的,U裡面的向量稱為左奇異向量),Σ是一個N * M的矩陣(除了對角線的元素都是0,對角線上的元素稱為奇異值),V’(V的轉置)是一個N * N的矩陣,裡面的向量也是正交的,V裡面的向量稱為右奇異向量),從圖片來反映幾個相乘的矩陣的大小可得下面的圖片:

三個矩陣有非常清楚的物理含義。

第一個矩陣X中的每一行表示意思相關的一類詞,其中的每個非零元素表示這類詞中每個詞的重要性(或者說相關性),數值越大越相關。最後一個矩陣Y中的每一列表示同一主題一類文章,其中每個元素表示這類文章中每篇文章的相關性。中間的矩陣則表示類詞和文章雷之間的相關性。因此,我們只要對關聯矩陣A進行一次奇異值分解,w 我們就可以同時完成了近義詞分類和文章的分類。(同時得到每類文章和每類詞的相關性)。

參考:

https://zhuanlan.zhihu.com/p/25801478

https://zhuanlan.zhihu.com/p/21560667?refer=intelligentunit