Spark, .../mlib/feature/PCA.scala 코드를 분석한 글이다. PCA의 원리에 대해 이해를 하기 위해 소스를 분석했는데 조금은 원리를 알게 되었지만, 수학으로 인한 장벽은 여전했다.
SPARK's PCA.sala
1. 'pc'로 명칭된 값과 Explained Variance을 구한다.
val mat = new RowMatrix(sources)
val (pc, explainedVariance) = mat.computePrincipalComponentsAndExplainedVariance(k)
변수 pc : K값으로 보정된 SVD의 U행렬
변수 explainedVariance : Explained Variance
2. 입력된 벡터들을 차례대로 pc에 곱한 결과를 구한다.
pc.transpose.multiply(입력벡터)
변수명 pc로 정의된 값은 변환하고자 하는 차원값 K값이 반영되었기 때문에 입력된 벡터를 곱하면 원했던 차원의 변환된 벡터를 구할 수 있다. 여기서 사소한 배열 형식의 변경 코드등의 설명은 배제했다. 내용을 보면 아주 간단하다. 실재로는 PCA.scala에는 중요한 것은 없고, RowMatrix객체의 computePrincipalComponentsAndExplainedVariance함수를 호출하는 것이 전부이다.
RowMatix#computePrincipalComponentsAndExplainedVariance
// 1. 공분산(Covariance)를 구한다.
val Cov = computeCovariance().asBreeze.asInstanceOf[BDM[Double]]
// 2. 공분산의 SVD의 u, s를 구한다. v는 처리안함.
val brzSvd.SVD(u: BDM[Double], s: BDV[Double], _) = brzSvd(Cov)
// 3. s 벡터의 각항목별 전체대비 비중을 구하고, 이를 explained variance로 한다.
val eigenSum = s.data.sum
val explainedVariance = s.data.map(_ / eigenSum)
// u벡터를 k열만큼 추린 배열과 explained variance를 반환한다.
if (k == n) {
(Matrices.dense(n, k, u.data), Vectors.dense(explainedVariance))
} else {
(Matrices.dense(n, k, Arrays.copyOfRange(u.data, 0, n * k)),
Vectors.dense(Arrays.copyOfRange(explainedVariance, 0, k)))
}
초보적인 실험
파란점은 입력 벡터이고 빨간점은 설명을 위한 가상의 변환된 벡터이다. 이 실험을 한 이유는 어떤 벡터가 변환이 될 때, 그림-1 처럼 회전하는 것인지, 그림-2처럼 투영되는 것인지 알고 싶었다. 그림-1을 보면 회전하는 것처럼 보이지만 그림-2처럼 투영된다. 즉 변환된 값은 A+까지의 길이값이 아니라, A*이다.
마치며
'Data Analysis' 카테고리의 다른 글
기계학습 - Spark(8) - PCA 코드분석1 (0) | 2017.07.02 |
---|---|
기계학습 - Spark(7) - Word2Vec 코드분석 완결 (0) | 2017.06.18 |
기계학습 - Spark(6) - Word2Vec, 학습하는 부분 코드 분석2 (0) | 2017.06.15 |
기계학습 - Spark(5) - Word2Vec, 학습하는 부분 코드 분석 (0) | 2017.06.11 |
기계학습 - Spark(4) - Word2Vec (0) | 2017.05.21 |