mllib提供了兩種進行pca變換的方法,第一種與上文提到的svd分解類似,位於org.apache.spark.mllib.linalg
包下的rowmatrix
中,這裡,我們同樣讀入上文中提到的a.mat
檔案,對其進行pca變換:
scala> import org.apache.spark.mllib.linalg.vectors
scala> import org.apache.spark.mllib.linalg.distributed.rowmatrix
scala> val data = sc.textfile("a.mat").map(_.split(" ").map(_.todouble)).map(line => vectors.dense(line))
//通過rdd[vectors]建立行矩陣
scala> val rm = new rowmatrix(data)
rm: org.apache.spark.mllib.linalg.distributed.rowmatrix = org.apache.spark.mllib.linalg.distributed.rowmatrix@4397952a
//保留前3個主成分
scala> val pc = rm.computeprincipalcomponents(3)
pc: org.apache.spark.mllib.linalg.matrix =
-0.41267731212833847 -0.3096216957951525 0.1822187433607524
0.22357946922702987 -0.08150768817940773 0.5905947537762997
-0.08813803143909382 -0.5339474873283436 -0.2258410886711858
0.07580492185074224 -0.56869017430423 -0.28981327663106565
0.4399389896865264 -0.23105821586820194 0.3185548657550075
-0.08276152212493619 0.3798283369681188 -0.4216195003799105
0.3952116027336311 -0.19598446496556066 -0.17237034054712738
0.43580231831608096 -0.023441639969444372 -0.4151661847170216
0.468703853681766 0.2288352748369381 0.04103087747663084
可以看到,主成分矩陣是乙個尺寸為(9,3)的矩陣,其中每一列代表乙個主成分(新座標軸),每一行代表原有的乙個特徵,而a.mat
矩陣可以看成是乙個有4個樣本,9個特徵的資料集,那麼,主成分矩陣相當於把原有的9維特徵空間投影到乙個3維的空間中,從而達到降維的效果。
可以通過矩陣乘法來完成對原矩陣的pca變換,可以看到原有的(4,9)矩陣被變換成新的(4,3)矩陣。
scala> val projected = rm.multiply(pc)
projected: org.apache.spark.mllib.linalg.distributed.rowmatrix = org.apache.spark.mllib.linalg.distributed.rowmatrix@2a805829
scala> projected.rows.foreach(println)
[12.247647483894383,-2.725468189870252,-5.568954759405281]
[2.8762985358626505,-2.2654415718974685,1.428630138613534]
[12.284448024169402,-12.510510992280857,-0.16048149283293078]
[-1.2537294080109986,-10.15675264890709,-4.8697886049036025]
需要注意的是,mllib提供的pca變換方法最多只能處理65535維的資料。
除了矩陣類內建的pca變換外,mllib還提供了一種「模型式」的pca變換實現,它位於org.apache.spark.mllib.feature
包下的pca
類,它可以接受rdd[vectors]
作為引數,進行pca變換。
該方法特別適用於原始資料是labeledpoint
型別的情況,只需取出labeledpoint
的feature
成員(它是rdd[vector]
型別),對其做pca操作後再放回,即可在不影響原有標籤情況下進行pca變換。
首先引入需要使用到的類:
import org.apache.spark.mllib.feature.pca
import org.apache.spark.mllib.regression.labeledpoint
依然使用前文的a.mat
矩陣,為了創造出labeledpoint
,我們為第乙個樣本標註標籤為0.0
,其他為1.0
。
scala> val data = sc.textfile("a.mat").map(_.split(" ").map(_.todouble)).map(line => )
scala> data.foreach(println)
(0.0,[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0])
(1.0,[6.0,4.0,2.0,1.0,3.0,4.0,2.0,1.0,5.0])
(1.0,[5.0,6.0,7.0,8.0,9.0,0.0,8.0,6.0,7.0])
(1.0,[9.0,0.0,8.0,7.0,1.0,4.0,3.0,2.0,1.0])
隨後,建立乙個pca
類的物件,在構造器中給定主成分個數為3,並呼叫其fit
方法來生成乙個pcamodel
類的物件pca
,該物件儲存了對應的主成分矩陣:
scala> val pca = new pca(3).fit(data.map(_.features))
pca: org.apache.spark.mllib.feature.pcamodel = org.apache.spark.mllib.feature.pcamodel@68602c26
對於labeledpoint
型的資料來說,可使用map
運算元對每一條資料進行處理,將features
成員替換成pca變換後的特徵即可:
scala> val projected = data.map(p => p.copy(features = pca.transform(p.features)))
scala> projected.foreach(println)
(0.0,[12.247647483894383,-2.725468189870252,-5.568954759405281])
(1.0,[2.8762985358626505,-2.2654415718974685,1.428630138613534])
(1.0,[12.284448024169402,-12.510510992280857,-0.16048149283293078])
(1.0,[-1.2537294080109986,-10.15675264890709,-4.8697886049036025])
pca主成分分析 PCA主成分分析(中)
矩陣 matrix,很容易讓人們想到那部著名的科幻電影 駭客帝國 事實上,我們又何嘗不是真的生活在matrix中。機器學習處理的大多數資料,都是以 矩陣 形式儲存的。矩陣是向量的組合,而乙個向量代表一組資料,資料又是多維度的。比如每個人的都具有身高 體重 長相 性情等多個維度的資訊資料,而這些多維度...
主成分分析PCA
主要參考這篇文章 個人總結 pca是一種對取樣資料提取主要成分,從而達到降維的目的。相比於上篇文章介紹到的svd降維不同,svd降維是指減少資料的儲存空間,資料的實際資訊沒有缺少。個人感覺pca更類似與svd的去噪的過程。pca求解過程中,涉及到了svd的使用。針對資料集d 假設di 的維度為 w ...
PCA 主成分分析
在進行影象的特徵提取的過程中,提取的特徵維數太多經常會導致特徵匹配時過於複雜,消耗系統資源,不得不採用特徵降維的方法。所謂特徵降維,即採用乙個低緯度的特徵來表示高緯度。將高緯度的特徵經過某個函式對映至低緯度作為新的特徵。pca和lda區別 pca是從特徵的角度協方差角度 求出協方差矩陣的特徵值和特徵...