본문 바로가기

Data Analysis

기계학습 - Spark(8) - PCA 코드분석1

Spark의 기계학습 교육사이트의 나머지 부분은 평이한 내용들이지만, 그중에 ngram과 PCA는 흥미로웠다. ngram은 개요만 읽어도 이해하는데 충분했다. PCA는 N차원의 벡터를 N보다 같거나 작은 차원의 벡터로 변한하는 것인데, 어떻게 구현이 되는지가 궁금했고, word2vec을 이해할 때와 만찬가지로 직접 구현 소스 코드를 분석해보기로 했다.


먼저 spark사이트에 나온 샘플예제는 최신버전에서 약간 문법오류가 있어보여 수정한 코드를 아래에 적는다.

import org.apache.spark.ml.feature.PCA

import org.apache.spark.ml.linalg.Vectors


val data = Array(

        Vectors.sparse(5, Seq((1, 1.0), (3, 7.0))),

        Vectors.dense(2.0, 0.0, 3.0, 4.0, 5.0),

        Vectors.dense(4.0, 0.0, 0.0, 6.0, 7.0)

    )


val df = spark.createDataFrame(data.map(Tuple1.apply)).toDF("features")

val pca = new PCA()

              .setInputCol("features")

              .setOutputCol("pcaFeatures")

              .setK(3)


/* transform함수를 호출하기 위해서는 .fit호출시 모델을 받아...*/

val mdl = pca.fit(df)

val result = mdl.transform(df).select("pcaFeatures")


result.show()




개요


PCA는 Principal Component Analysis의 약자이다. 다음은 위키피디아 설명이다.  "Principal component analysis (PCA) is a statistical procedure that uses an orthogonal transformation to convert a set of observations of possibly correlated variables into a set of values of linearly uncorrelated variables called principal components (or sometimes, principal modes of variation)" [출처:위키피디아



  • correlated value : 위의 그림에서 파란색 점들은 2개의 축 (X, Y)의 값으로 이루어졌다. 그리고 X값이 증가하면 Y값도 증가하는 경향을 갖는다. 회귀분석처럼 한쪽의 값의 추이에 따라 다른쪽의 값의 추이가 서로 상관이 있는 그림상의 푸른점들의 값 같은 것을 말했다고 본다.
  • statistical : 앞서 상관성(correlation) 정도를 측정하려면 분산이 사용된다. 위의 그림의 빨간선은 직관적으로 그렸을 뿐이다. 이 선은 다양하게 그려질 수 있는데, 바로 통계값을 이용 연관성이 가장 높은 선을 그릴 수 있게 된다.  
  • principal : 왜 principal이라는 단어를 썼을까? 다음 단어의 뜻을 바탕으로 유추해봤다. "principal axis"는 타원의 중심축을 말한다. 2차원에서 흩어져 있는 값들이 상관성이 있을 때, 타원의 모양처럼 분포된다면 최대한 중심축을 구하는게 관건이지 않을까 한다.
위의 그림처럼 2차원의 값을 빨간색 선상에 놓으면 1차원의 값들이 된다. 벡터의 차수를 낮추는데, 정보의 유실을 최소화하는 방법으로 보인다.

단순히 2차원만을 생각한다면, 간단하지만 N-차원으로 확대가 되면 상상조차 하기 힘들다. 수학적인 설명은 이해가 갈듯 말듯한데다 구체적으로 손에 잡히는게 없으니, 이 역시 PCA를 구현한 소스코드를 보고 거꾸로 이론을 이해해보려 한다.