-
1 # 哥廷根數學學派
-
2 # 機器之心Pro
矩陣分解在機器學習應用中的重要性無需多言。本文對適用範圍很廣的奇異值分解方法進行了介紹,並透過程式碼演示說明了其工作方式、計算方法及其常見的幾種基礎應用。
矩陣分解也叫矩陣因子分解,涉及到用給定矩陣的組成元素描述該矩陣。
奇異值分解(SVD)可能是最著名和使用最廣泛的矩陣分解方法。所有矩陣都有一種 SVD 方法,這使得其比特徵分解(eigendecomposition)等其它方法更加穩定。因此,這種方法在很多應用中都有應用,包括壓縮、去噪、資料壓縮。
在這份教程中,你將瞭解用於將矩陣分解成其組成元素的奇異值分解方法。
在完成本教程後,你將瞭解:
·奇異值分解是什麼以及涉及什麼
·如何計算 SVD 以及如何根據 SVD 元素重建矩形和方形矩陣
·如何使用 SVD 計算偽逆和執行降維
那就開始吧!
教程概覽
本教程分為 5 部分,依次為:
1. 奇異值分解
2. 計算奇異值分解
3. 根據 SVD 重建矩陣
4. 用於偽逆的 SVD
5. 用於降維的 SVD
奇異值分解
奇異值分解(SVD)是一種用於將矩陣歸約成其組成部分的矩陣分解方法,以使後面的某些矩陣計算更簡單。
為了說明簡單,我們將關注用於實數值矩陣的 SVD,而會忽略複數矩陣的情況。
其中 A 是我們希望分解的 n×m 的實矩陣,U 是一個 m×m 矩陣,Sigma(通常用大寫的希臘字母 ∑表示)是一個 m×n 的對角矩陣,V^T 是一個 n×n 矩陣的轉置,其中 T 是上標。
奇異值分解是線性代數的一個亮點。
——《__Introduction to Linear Algebra__ (http://amzn.to/2AZ7R8j)》第五版,2016 年,第 371 頁
Sigma 矩陣中的對角值被稱為原始矩陣 A 的奇異值。U 矩陣的列被稱為 A 的左奇異向量,V 的列被稱為 A 的右奇異向量。
SVD 是透過迭代式的數值方法計算的。我不會詳細深入這些方法的細節。每一個矩形矩陣都有一個奇異值分解,儘管所得到的矩陣可能包含複數值以及浮點算術的侷限性可能會導致某些矩陣無法簡單利落地完成分解。
奇異值分解(SVD)提供了另一種將矩陣分解成奇異向量和奇異值的方式。SVD 讓我們可以發現某些與特徵分解同種型別的資訊。但是,SVD 有更廣的適用性。
——《Deep Learning》,2016 年,第 44-45
SVD 在矩陣求逆等其它矩陣運算的計算有廣泛的應用,但也可用作機器學習中的資料歸約方法。SVD 也可用在最小二乘線性迴歸、影象壓縮和資料去噪中。
奇異值分解(SVD)在統計學、機器學習和計算機科學領域有很多應用。將 SVD 應用於矩陣就像是使用 X 射線進行透視……
——《No Bullshit Guide To Linear Algebra》,2017 年,第 297 頁
計算奇異值分解
SVD 可以透過呼叫 svd() 函式進行計算。
該函式在處理矩陣後會返回 U、Sigma 和 V^T 元素。Sigma 對角矩陣是按奇異值向量的形式返回的。V 矩陣是以轉置後的形式返回的,比如 V.T.
下面的示例定義了一個 3×2 矩陣並計算了奇異值分解。
執行這個示例,首先會顯示定義的 3×2 矩陣,然後會顯示分解計算得到的 3×3 的 U 矩陣、2 個元素的 Sigma 向量和 2×3 的 V^T 矩陣元素。
根據 SVD 重建矩陣
原始矩陣可以根據 U、Sigma 和 V^T 元素重建出來。
svd() 返回的 U、s 和 V 元素不能直接相乘。
s 向量必須使用 diag() 函式轉換成對角矩陣。預設情況下,這個函式將建立一個相對於原來矩陣的 m×m 的方形矩陣。這是有問題的,因為該矩陣的尺寸並不符合矩陣乘法的規則,即一個矩陣的列數必須等於後一個矩陣的行數。
在建立了方形的 Sigma 對角矩陣之後,各個矩陣的大小與我們分解的原始 n×m 矩陣是相關的,如下:
而事實上我們需要:
我們可以透過建立一個全是 0 值的 m×n 的新 Sigma 矩陣(比如:更多行)並使用透過 diag() 計算得到的方形對角矩陣來填充矩陣的前 n×n 部分。
執行這個示例,首先會顯示原始矩陣,然後會顯示根據 SVD 元素重建的矩陣。
上面使用 Sigma 對角矩陣的複雜之處僅存在於 m 和 n 不相等的情況中。當重建一個方形矩陣時,其對角矩陣可以直接使用,如下。
執行這個示例會顯示原來的 3×3 矩陣和根據 SVD 元素直接重建的版本。
用於偽逆的 SVD
偽逆(pseudoinverse)是將方形矩陣的矩陣求逆泛化應用到行數和列數不相等的矩形矩陣上。
這也被稱為廣義逆(Generalized Inverse)或摩爾-彭若斯逆(Moore-Penrose Inverse)——得名於兩位獨立發現該方法的研究者。
矩陣求逆不是為非方形矩陣定義的。[...] 當 A 的列數大於行數時,那麼使用偽逆求解線性方程是眾多解決方案中的一種。
——《Deep Learning》,2016 年,第 46 頁
偽逆表示為 A^+,其中 A 是被求逆的矩陣,+ 是上標。
偽逆是使用 A 的奇異值分解計算的:
或者,沒有點符號:
其中 A^+ 是 A 的偽逆,D^+ 是對角矩陣 Sigma 的偽逆,U^T 是 U 的轉置。
我們可以根據 SVD 運算得到 U 和 V。
根據 Sigma 建立一個對角矩陣,計算 Sigma 中每個非零元素的倒數,然後如果原始矩陣是矩形的就取其轉置,就可以計算得到 D^+。
偽逆提供了一種求解線性迴歸方程的方法,尤其是當行數多於列數時,而這也是很常見的情況。
NumPy 提供了函式 pinv() 來計算矩形矩陣的偽逆。
下面的示例定義了一個 4×2 的矩陣並計算了其偽逆。
執行這個示例,首先顯示定義的矩陣,然後顯示計算出的偽逆。
我們可以透過 SVD 採用人工的方式計算偽逆,並將結果與 pinv() 函式的結果進行比較。
首先我們必須計算 SVD。然後我們必須計算 s 陣列中每個值的倒數。然後將這個 s 陣列轉換成一個對角矩陣,它額外增加了一行 0 以使其變成矩形形式。最後,我們可以根據這些元素計算偽逆。
具體實現方式為:
下面列出了完整的示例。
執行這個示例,首先顯示定義的矩形矩陣,然後顯示其偽逆,結果與上面 pinv() 函式的結果一致。
用於降維的 SVD
SVD 的一大常見應用是降維。
具有大量特徵的資料(比如特徵數(列數)多於觀察數(行數))也許可以被歸約成與所涉預測問題最相關的更小特徵子集。
其結果是一個秩更低的矩陣,據說接近原始矩陣。
為了做到這一點,我們可以在原來的資料上執行一次 SVD 操作並選擇 Sigma 中前 k 個最大的奇異值。這些列可以從 Sigma 中選擇得到,行可以從 V^T 中選擇得到。
然後可以重建原始向量 A 的近似 B。
在自然語言處理中,這種方法可以被用在文件中詞出現情況或詞頻的矩陣上,並被稱為隱含語義分析(Latent Semantic Analysis)或隱含語義索引(Latent Semantic Indexing)。
在實踐中,我們可以保留和使用被稱為 T 的描述性資料子集。這是矩陣的密集總結或投射。
此外,這種變換既可以在原來的矩陣 A 上計算和應用,也可以在其它類似的矩陣上計算和應用。
下面的示例是使用 SVD 的資料歸約。
首先定義一個 3×10 的矩陣,其列數多於行數。然後計算 SVD 並且只選取其前兩個特徵。這些元素再重新結合起來,得到原始矩陣的準確再現。最後計算轉換的方式有兩種。
執行這個示例,首先顯示定義的矩陣,然後是重建的近似矩陣,然後是原始矩陣的兩個同樣的變換結果。
scikit-learn 提供了直接實現這種功能的 TruncatedSVD 類。
TruncatedSVD 的建立必須指定所需的特徵數或所要選擇的成分數,比如 2。一旦建立完成,你就可以透過呼叫 fit() 函式來擬合該變換(比如:計算 V^Tk),然後再透過呼叫 transform() 函式將其應用於原始矩陣。結果得到上面被稱為 T 的 A 的變換。
下面的示例演示了 TruncatedSVD 類。
執行這個示例,首先顯示定義的矩陣,然後是該矩陣變換後的版本。
可以看到,結果得到的值與上面人工計算的結果一致,但某些值的符號不一樣。由於所涉及的計算的性質以及所用的基礎庫和方法的差異,可以預見在符號方面會存在一些不穩定性。只要對該變換進行訓練以便複用,這種不穩定性在實踐中應該不成問題。
回覆列表
奇異值分解是一個有著很明顯的物理意義的一種方法,它可以將一個比較複雜的矩陣用更小更簡單的幾個子矩陣的相乘來表示,這些小矩陣描述的是矩陣的重要的特性。
在機器學習領域,有相當多的應用與奇異值都可以扯上關係,比如做feature reduction的PCA,做資料壓縮(以影象壓縮為代表)的演算法,還有做搜尋引擎語義層次檢索的LSI(Latent Semantic Indexing)。