Search
Duplicate

Machine Learning/ PCA

주의) 이 페이지에서는 공식의 유도 과정 같은 것은 정리하지 않는다. 공식의 유도 과정은 <코세라 강의> 참조.

PCA (Principal Component Analysis)

데이터의 차원 수를 낮춰서 데이터를 압축하는 알고리즘.
2차원 데이터를 1차원 선으로 줄이는 것, 3차원 데이터를 2차원 면으로 줄이는 것과 같은 것이 기본이며, 같은 개념으로 1000차원 데이터를 100차원으로 줄인다. 당연히 차원을 많이 축소할 수록 손실이 많이 발생하기 때문에 적당한 정도를 찾는 것이 중요하다.
여기까지만 보면 고차원 데이터를 저차원에 투영하는 것 같지만 사실 투영은 아니다. 자세한 내용은 아래 참조.
선형회귀와 PCA가 다른 점은 선형회귀는 Y 값이 존재하여 주어진 선과 Y 값의 차이가 비용이 되지만, PCA는 차원을 줄인 선과 원본 데이터의 거리가 오차가 된다.
데이터의 차원을 줄이는 이유는 프로세스의 성능상 이유와 데이터 시각화 등의 이유가 있음.

PCA의 절차

PCA를 수행하기 전에 전처리 작업으로 Feature Scaling과 Mean Normalization을 수행한다.
feature Scaling은 feature 간의 단위의 차이가 클 때 보정하는 방법으로 각 feature의 데이터를 평균값으로 뺀 후 max-min 값 혹은 표준편차로 나눈 것이고
Mean Normalization은 데이터 분포가 원점을 중심으로 그려지도록 데이터를 평균값으로 뺀 값을 사용하는 것이다.
전처리를 수행한 데이터는 2가지 단계를 통해 데이터 압축을 하는데, 첫 번째는 공분산 행렬(Covariance Matrix) –두 변수의 상관관계를 나타내는 것– 을 구하는 것이고 그 다음으로는 고유벡터(Eigen Vector) –0이 아닌 값으로서 선형 변환 후에도 변하지 않는 벡터– 를 사용하는 것이다.
공분산 행렬은 Σ\Sigma로 표기하며 다음의 식을 통해 구할 수 있다.
Σ=1mi=1n(xi)(xi)T\Sigma = \frac{1}{m} \sum_{i=1}^n (x^i) (x^i)^T
xix^{i}는 데이터들을 차원수만큼 나열한 벡터이다. 그 벡터 xix^{i} 와 xix^{i} 의 전치행렬을 곱하면 n×nn \times n 행렬이 된다.
위 공식을 통해 구해진 공분산 행렬 Σ\Sigma는 옥타브의 svd 함수 –Singular Value Decomposition의 약자로서 eigenvector 보다 안정적인 수학적 방식이라고 한다– 에 넣으면 U, S, V 3가지 값이 나오는데, 그 중 U 값 행렬 중 줄이고자 하는 차원수 만큼의 열(column)을 취하여 Ureduce 행렬을 만든 후에,
Ureduce 행렬을 전치 시킨 후 축소하고자 하는 원본 데이터 x와 곱하면 최종적으로 차원 축소된 데이터 z를 얻을 수 있다.
z=UreduceTxz = Ureduce^{T} x
요약하자면 n×1n \times 1 의 데이터 xxk×1k \times 1의 데이터 zz로 축소 시키는 절차는 아래와 같다.
1.
데이터를 전처리 한다 (feature scaling, mean normalization)
2.
공분산 행렬을 구한다.
3.
SVD 를 이용하여 U, S, V 값을 구한다.
4.
U 값을 k 열만큼만 취하여 Ureduce 행렬을 만든다.
5.
Ureduce 행렬을 전치시킨 후 최초의 n×1n \times 1xx 벡터와 곱하여 k×1k \times 1 으로 축소된 zz 벡터를 구한다.

압축한 데이터 되돌리기

압축한 데이터를 원래대로 돌리려면 거꾸로 계산하면 된다. Ureduce 행렬을 전치시킨 후 xx를 곱한 것이 축소된 데이터인 zz가 되었으므로, zz에다 전치시키지 않은 Ureduce을 곱하면 된다.
Ureduce×Z=XapproxUreduce \times Z = Xapprox
다만 이때의 XX는 원래의 XX와는 완전히 같지 않은데, 위 이미지의 녹색선에 해당하는 수준으로만 복원이 될 뿐 완전히 XX로 복원되지는 못한다. 이래서 이 XXXapproxXapprox라고 한다.

축소할 차원 수 K 구하기

축소한 후 복원한 데이터를 바탕으로 축소한 데이터의 오차를 계산할 수 있다. XXXapproxXapprox의 차이를 계산하는 후 그것을 다시 XX로 나누면 오차율이 계산되는데, 그 오차율을 바탕으로 적합한 차원수 KK를 계산해 낼 수 있다.
1mi=1mxixapproxi21mi=1mxi20.01\frac{ \frac{1}{m} \sum_{i=1}^m || x^i - xapprox^i ||^2 }{ \frac{1}{m} \sum_{i=1}^m || x^i ||^2 } \leq 0.01
KK를 계산해 낼 수 있는 방법은 2가지인데,
첫 번째는 KK를 1부터 시작하여 KK 값을 늘려가면서 오차가 1% 이하가 되는 값을 찾는 것이 있고 –다소 노가다
차원 수가 원본에 가까워질 수록 오차율은 줄어드므로 1에서 시작하면 오차율이 점점 줄어든다.
두 번째는 위에서 사용한 SVD 함수를 이용하는 것.
SVD 함수의 결과값인 U, S, V 중에서 S 값을 사용한다.
SS는 위 이미지와 같이 대각선으로 S11,S22,...,SnnS_{11}, S_{22}, ... , S_{nn}의 값을 갖고 그 외는 모두 0인 행렬인데, 해당 행렬의 kk번째까지 합한 후, nn까지의 합으로 나눈 값이 0.99 보다 커지는 kk값을 찾으면 된다. –원래는 1에서 뺀 값이 0.01 보다 작은 값을 찾는 것인데, 1을 넘기고 부등호를 바꿔서 0.99보다 커지는 값을 찾는다.
i=1kSiii=1nSii0.99\frac { \sum_{i=1}^k S_{ii} } { \sum_{i=1}^n S_{ii} } \geq 0.99