spark 主成分分析(PCA)

2021-08-28 12:43:08 字數 3973 閱讀 6420

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型別的情況,只需取出labeledpointfeature成員(它是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是從特徵的角度協方差角度 求出協方差矩陣的特徵值和特徵...