下麵是章節降維的內容(其他內容參見全文目錄)
降維 是減少變量數量的過程。它可以用來從含有噪聲的未加工特征中提取潛在特征,或者在維持原來結構的情況下壓縮數據。MLlib提供了類RowMatrix 上的降維支持。
奇異值分解 (SVD)
奇異值分解(SVD)將一個矩陣分解為三個矩陣:U, Σ, 和V ,三個矩陣滿足條件:
A = U Σ VT
- U是正交矩陣,該矩陣的列稱為左奇異向量。
- Σ 是對角矩陣,對角線上的元素降序排列,對角線上的每個值稱為奇異值。
- V是正交矩陣,該矩陣的列稱為右奇異向量。
對於大型舉證,我們通常不需要完全分解,而是求解最大的幾個奇異值以及對應的奇異向量即可。這樣做可以節省存儲空間、降噪以及恢複矩陣的低秩結構。
補充:
1. 奇異值的另外一種定義:A*A的非負特征值得平方根,其中A*是A的共軛轉置矩陣(當矩陣元素為實數,共軛轉置矩陣就是轉置矩陣)。
2.
如果我們保留top k 個奇異值,那麽結果中的低秩矩陣的維度如下:
- U: m×k,
- Σ: k×k,
- V: n×k.
性能
假設n小於m。奇異值和右奇異向量來自Gramian矩陣(ATA)的特征值和特征向量。存儲左奇異矩陣的向量是U,通過矩陣乘法U = A(VS-1)得到(指定ComputeU參數)。實際使用的方法基於計算開銷自動選擇。
- 如果n比較小(n < 100)或者k相對於n比較大(k > n/2),我們先計算Grimian矩陣,然後在本地驅動程序中計算最大的特征值和特征向量。這需要一趟遍曆,在執行器和驅動程序上的空間複雜度O(n2),在驅動程序上的時間複雜度O(n2k)。
- 否則,我們分布式計算 (ATA)v 並交給ARPACK(大規模特征值計算程序包)去計算最大的特征值以及特征向量。這需要O(k)次遍曆,執行器上O(n)的存儲空間以及驅動程序上O(nk)存儲空間。
SVD 示例(Scala)
MLlib針對行矩陣提供了SVD功能,提供支持的類是RowMatrix 。
import org.apache.spark.mllib.linalg.Matrix
import org.apache.spark.mllib.linalg.distributed.RowMatrix
import org.apache.spark.mllib.linalg.SingularValueDecomposition
val mat: RowMatrix = ...
// Compute the top 20 singular values and corresponding singular vectors.
val svd: SingularValueDecomposition[RowMatrix, Matrix] = mat.computeSVD(20, computeU = true)
val U: RowMatrix = svd.U // The U factor is a RowMatrix.
val s: Vector = svd.s // The singular values are stored in a local dense vector.
val V: Matrix = svd.V // The V factor is a local dense matrix.
主成分分析 (PCA)
主成分分析 (PCA)是尋找坐標旋轉的一種統計方法,該方法可以使得:樣本點在第一個坐標上擁有最大的方差,後續坐標依次擁有次大的方差。其中用到的旋轉矩陣的列稱為主成分。PCA在降維中有廣泛應用。
補充:
主成分分析的一般計算步驟:
1. 數據標準化:設樣本數為m,每個樣本特征維度為n, 在每個維度上計算均值u和方差δ2(。然後令歸一化特征值: x’ = (x – u)/δ
2. 求協方差矩陣(也有的地方計算相關係數矩陣)。
3. 求協方差矩陣的特征值和特征向量。
4. 將特征值從大到小排序,取最大的k個特征值,然後將對應的k個特征向量的作為列向量組成矩陣。k 值的確定參考當前累計特征值的和占特征值總和的比例,一般要求在85%以上。
5. 投影:將歸一化之後的樣本點投影到選取的特征向量上。ResultDataMatrix(m, k) = NormalizedDataMatrix(m, n) * EigenVectorsMatix(n * k)
MLlib中使用行矩陣來支持PCA。
下麵的代碼(Scala)說明了怎樣在RowMatrix上計算主成分並使用主成分將特征映射到低維空間。
import org.apache.spark.mllib.linalg.Matrix
import org.apache.spark.mllib.linalg.distributed.RowMatrixval mat: RowMatrix = ...
// Compute the top 10 principal components.
val pc: Matrix = mat.computePrincipalComponents(10) // Principal components are stored in a local dense matrix.// Project the rows to the linear space spanned by the top 10 principal components.
val projected: RowMatrix = mat.multiply(pc)
參考:
[1] http://www.cnblogs.com/jerrylead/archive/2011/04/18/2020209.html
[2] http://baike.baidu.com/picture/45376/45376/0/e850352ac65c1038ef0358deb0119313b07e89a9.html?fr=lemma&ct=single#aid=0&pic=e850352ac65c1038ef0358deb0119313b07e89a9