주성분 분석(Principal Component Analysis, 이하 PCA)는 데이터에 대한 정보 손실을 최소화하면서 데이터에 내재된 유의미한 기저변수를 발견해내는 과정에 사용되는 기법이다. PCA는 1. 데이터 차원을 줄이는 과정 2. 데이터의 특징 추출 방법 등에 활용된다.

PCA는 기존 데이터 \(\mathbf{X}\)가 \(D\)차원이라고 했을 때, 이 데이터를 최대한 잘 설명해줄 수 있는 \(M\)차원의 주성분(principal component)을 만들어내는 과정이다. 당연히 \(M \leq D\) 이다. 즉 기존 \(D\)차원의 데이터를 \(M\)차원으로 줄이는 것이다.

조금 더 구체적으로 말하자면, PCA는 기존 데이터셋을 principal subspace라고 불리는 더 낮은 차원의 공간으로 데이터를 orthogonal projection을 시킴으로써 이루어진다. 이러한 orthogonal projection 과정은 데이터 분산이 최대가 되는 방향으로 진행되어야 한다.

PCA

그런데 보통 우리는 분산이 작은 것이 좋다고 꾸준하게 이야기를 들어왔다. 그런데 왜 PCA에서는 분산이 최대화되는 것이 좋은 것일까? 위의 그림과 같이 데이터가 분포해있다고 가정해자. 데이터의 차원을 줄인다는 것은 데이터를 요약하는 과정이라고 받아들일 수 있다. 어느 위치에서 데이터를 바라보아야 가장 데이터를 잘 요약할 수 있는가를 생각해보면, 그 위치는 바로 데이터의 분산이 최대가 되는 위치일 수 밖에 없다. 위의 그림이라면, 1st Principal Component라고 적혀있는 방향으로 데이터를 바라보아야 이 데이터를 가장 잘 요약할 수 있다.

데이터셋 \(\mathbf{X}=(X_{1},...,X_{D})\)가 다음과 같은 평균과 공분산 행렬을 갖는다고 하자.

\[\mathbb{E}(\mathbf{X})=\mu \quad \text{Cov}(\mathbf{X})=\Sigma\]

이 공분산행렬 \(\Sigma\)는 \(D \times D\) 크기의 symmetric matrix이기 때문에 다음과 같이 spectral decomposition을 수행할 수 있다.

\[\Sigma = \Gamma\Lambda\Gamma^{T} = \sum_{i=1}^{D}\lambda_{i}\gamma_{i}\gamma_{i}^{T}\]

여기서 \(\Lambda\)는 \(\Sigma\)의 eigenvalue인 \((\lambda_{1},...,\lambda_{D})\)들로 이루어진 대각행렬(diagonal matrix)이며, \(\Gamma = (\gamma_{1},...,\gamma_{D})\)는 각 컬럼이 standardized eigenvector인 orthogonal matrix이다.여기서 공분산행렬의 eigenvalues는 다음과 같이 값이 큰 순서대로 정렬되어 있다고 하자. \(\lambda_{1} \geq \lambda_{2} \geq ... \geq \lambda_{D} \geq 0\). 모든 eigenvalues가 0이상인 것은 공분산행렬이 positive semi definite 행렬이기 때문이다.

Principal Component 생성

Principal Component는 \(\mathbf{X}\)의 linear combination을 통해 생성된다. 데이터셋 \(\mathbf{X}\)를 principal component \(\mathbf{Y}\)로 변환시키는 과정은 아래의 수식과 같다.

\[\mathbf{X} \to \mathbf{Y} = \Gamma^{T}(\mathbf{X}-\mu)\]

따라서 \(\mathbf{X}\)의 \(i\)번째 principal component는 다음과 같이 표현된다. 여기서 \(\gamma_{i}\)는 \(\Gamma\)의 \(i\)번째 컬럼을 의미하며 이를 principal component loading이라 부른다.

\[y_{i} = \gamma_{i}^{T}(\mathbf{X}-\mu)\]

이를 통해 생성된 principal component \(\mathbf{Y}\)에 대해서는 다음의 특징들이 성립한다.

\[\begin{align} \text{1.} & E(y_{i}) = 0 \nonumber \\ \text{2.} & \text{Var}(y_{i})= \lambda_{i} \nonumber \\ \text{3.} & \text{Cov}(y_{i},y_{j}) = 0 \quad i \neq j \nonumber \\ \text{4.} & \text{Var}(y_{1}) \geq \text{Var}(y_{2}) \geq .... \geq Var(y_{D}) \geq 0 \nonumber \\ \text{5.} & \sum_{i=1}^{D}\text{Var}(y_{i}) = \text{tr}(\Sigma) \nonumber \\ \text{6.} & \prod_{i=1}^{D}\text{Var}(y_{i}) = \vert \Sigma \vert \nonumber \end{align}\]

여기서 2번 항목이 성립하는 이유는 다음과 같으며 이 수식이 성립함에 따라 3번,4번에 대해서도 자연스럽게 받아들일 수 있다.

\[\text{Cov}(\mathbf{Y}) = \Gamma^{T}\text{Cov}(\mathbf{X})\Gamma = \Gamma^{T}\Gamma\Lambda\Gamma^{T}\Gamma = \Lambda\]

특히 3번 사항 \(\text{Cov}(y_{i},y_{j}) = 0 \quad i \neq j\)은 PCA를 통해 새롭게 생성된 principal component간의 상호 독립성(uncorrleated)을 확인할 수 있는 특징이다.

왜 가장 큰 eigenvalue일 때, 분산을 최대화 하는가?

데이터셋 \(\mathbf{X}\)에 대해 선형결합을 하여 새로운 principal component를 생성한다. 그래서 새로운 principal component를 만들기 위해서 우리는 \(\mathbf{a}^{T}\mathbf{X}\) 의 분산이 최대화되는 경우를 찾아야 한다. 여기서 다음과 같이 \(\mathbf{a}\)를 정의한다.

\[\begin{align} \mathbf{a} &= c_{1}\gamma_{1}+c_{2}\gamma_{2}+...+c_{D}\gamma_{D} \nonumber \\ \mathbf{a} &= \Gamma C \nonumber \\ \text{where} \quad \mathbf{a}^{T}\mathbf{a} &= 1 \nonumber \end{align}\]

여기서 eigenvector인 \((\gamma_{1},...,\gamma_{D})\)는 \(\Sigma\) 를 구성하는 basis 이다. 더불어 \(\mathbf{a}^{T}\mathbf{a}=1\)임을 통해 우리는 \(C^{T}C = \sum_{i=1}^{D}c_{i}^{2} =1\) 임을 알 수 있다.

그렇다면, 데이터셋 \(\mathbf{X}\)의 선형결합 \(\mathbf{a}^{T}\mathbf{X}\)의 분산은 다음과 같이 계산될 것이다.

\[\begin{align} \text{Var}(\mathbf{a}^{T}\mathbf{X}) &= \mathbf{a}^{T}\Sigma\mathbf{a} = C^{T}\Gamma^{T}(\Gamma\Lambda\Gamma^{T})\Gamma C \nonumber \\ &= C^{T}\Lambda C = \sum_{i=1}^{D}\lambda_{i}c_{i}^{2} \end{align}\]

제약조건 \(\sum_{i=1}^{D}c_{i}^{2}=1\) 조건에서 \(\sum_{i=1}^{D}\lambda_{i}c_{i}^{2}\)를 최대화시킬 수 있는건 \(\lambda_{1} \geq \lambda_{2} \geq .... \geq \lambda_{D} \geq 0\)이기 때문에 \(c_{1}=1, c_{2}=0,... c_{D}=0\) 일 때이다.

따라서 선형결합 \(\mathbf{a}^{T}\mathbf{X}\)의 분산을 최대화할 수 있는 것은 공분산행렬 \(\Sigma\)의 가장 큰 eigenvalue에 매칭되는 eigenvector가 \(\mathbf{a}\)일 때이다.

이와 같은 논리로 계속 진행한다면 첫번째 principal component는 \(\gamma_{1}^{T}\mathbf{X}\)가 될 것이고 2번째 principal component는 \(\gamma_{2}^{T}\mathbf{X}\)가 될 것이다. \(k\)번째 principal component는 \(\gamma_{k}^{T}\mathbf{X}\)가 될 것이다.

이 알고리즘은 1번째 principal component와 서로 orthogonal한 방향들 중에서 데이터에 대해 가장 많은 정보를 포함하는(그 다음으로 분산이 큰)방향을 찾는다. 위의 그림과 같이 2차원에서는 가능한 orthogonal 방향이 1개 뿐이지만 고차원에서는 orthogonal한 방향이 수없이 많을 것이다.

새로운 principal component는 기존 데이터를 얼마나 설명해주는가?

앞서 우리는 PCA를 통해 더 적은 차원의 데이터로 기존 데이터를 일정부분 손실을 보지만 적은 차원의 데이터로 표현할 수 있다고 하였다. 그렇다면, PCA를 통해 얻은 새로운 변수는 기존 데이터셋이 가지고 있는 내용의 몇 %를 설명해줄 수 있는지를 알아야 한다.

이는 앞서 우리의 주된 논의대상이었던 eigenvalue를 통해 확인할 수 있다. 기존 데이터셋의 공분산행렬 \(\Sigma\)는 다음과 같은 성질을 갖는다.

\[\text{tr}(\Sigma) = \sum_{i=1}^{D}\lambda_{i} = \sum_{i=1}^{D}\text{Var}(y_{i})\]

따라서 k번째 principal component가 전체 분산 중 몇%를 차지하는가에 대해서는 다음의 수식을 통해 확인할 수 있다.

\[\frac{\lambda_{k}}{\sum_{i=1}^{D}\lambda_{i}}\]

선형결합한 데이터의 분산을 최대화하는 방향으로 진행해야 하므로 당연히 \(k\)번째 principal component가 \(k+1\)번째 principal component보다 전체 분산을 설명하는 비율이 더 높을 것이다. 대부분의 경우 1~3번째 principal component로 전체 분산의 80% 가까이를 커버한다. 따라서 우리는 극히 적은 수의 principal component로 정보를 많이 손실보지 않으면서 기존 \(D\)차원의 데이터셋을 대체할 수 있다.

기존 데이터셋의 몇 %까지의 손실을 감수할 것인가를 결정하는건 사람의 분석자의 몫이다. 전체 분산을 설명하는 비율을 기준으로 principal component 개수를 설정할 수 있고, 분산 비율을 지켜보기 이전에 principal component의 개수를 설정하기도 한다. 일반적으로는 프로그램을 통해 Scree Plot을 그려 기울기가 급격하게 완만하게 변화하는 곳에서 최적의 principal component 개수를 결정한다. Scree Plot에 대해서는 별도 코드 내용을 첨부하여 살펴볼 것이다.

상기 내용에 관련한 코드는 다음의 Python코드링크 에서 확인할 수 있습니다.

참조 문헌

  1. PRML

  2. 단단한 머신러닝

  3. The Elements of Statistical Learning