Lecture 2 PCA
학교 수업 복습 칸입니다. 25년 Fall, Pattern Recognition and Machine Learning
들어가면서.
이 수업은 패턴인식론과 생성형 알고리즘을 다루는 수업이다. 강의 순서는 다음과 같다.
- Information
- PCA, LDA –> 오늘
- Bayesian Decision
- Bayesian Network
- Parametric Estimation
- Non-parametric Estimation
- Variational Inference
- Deep Generative model
데이터분포를 어떻게 근사할 것인가. 그것이 핵심이다. 지금은 데이터 전처리에서 가장 대표적으로 쓰인다.
데이터있다고 가정해보자.
PCA와 LDA의 목적
우선 위의 그래프는 아래의 코드를 통해 작성되었다.
우선, 두개의 데이터군은 다음과 같다. Class0 은 -1,1을 평균으로 하여, 공분산값 cov0를 가지고, Class1 은 2,-0.5를 평균으로 공분산 cov1를 가진다.
# 클래스 0: 왼쪽 위쪽
mean0 = np.array([-1.0, 1.0])
cov0 = np.array([[0.4, 0.2],
[0.2, 0.3]])
X0 = np.random.multivariate_normal(mean0, cov0, size=100)
# 클래스 1: 오른쪽 아래쪽
mean1 = np.array([2.0, -0.5])
cov1 = np.array([[0.3, -0.1],
[-0.1, 0.2]])
X1 = np.random.multivariate_normal(mean1, cov1, size=100)
그럴때 PCA는 Class 0 + Class 1 이 가지는 전체 데이터 분포의 데이터 특성을 보여주고, LDA 는 Class0과 Class1과의 데이터를 구분하는 방향을 시각적으로 보여주고있다.
이제 PCA와 LDA의 정의와 특성에 대해 곰곰히 뜯어보자.
PCA
PCA의 정의
PCA는 고차원 데이터의 분산을 가장 잘 보존하는 방향을 찾아,
저차원 공간으로 선형투영하는 차원 축소기법이다.
우선, 앞서 그래프에서 PCA 벡터를 그리는 코드를 가져와보자.
mean = X.mean(axis=0)
X_centered = X - mean
cov = np.cov(X_centered.T) # (2,2)
eigvals, eigvecs = np.linalg.eigh(cov) # 작은 고유값부터
order = np.argsort(eigvals)[::-1] # 내림차순 정렬
eigvals = eigvals[order]
eigvecs = eigvecs[:, order]
pc1 = eigvecs[:, 0]
pc2 = eigvecs[:, 1]
max_components = min(6, eigvals.shape[0]) # 최대 6개까지, 차원 수를 넘지 않게
lines = ["PCA Eigenvalues & Eigenvectors:"]
for i in range(max_components):
vec = eigvecs[:, i]
lines.append(
f"PC{i+1}: eigenvalue = {eigvals[i]:.4f}, "
f"vector = [{vec[0]:.4f}, {vec[1]:.4f}]"
)
display("\n".join(lines))
코드에서 쉽게 보면, 데이터에서 PCA 분해는 Eigen-vector, 즉 고유값임을 알수 있다. -> eigvecs[:,order] 여기서 데이터는 2차원이므로 고유값이 2개이지만, 만약 차원이 늘어난다면 고유값은 차원의 개수많큼 존재한다.
알아야 할 주요내용은 다음과 같다.
-
데이터 평균(mean)
\[m = \frac{1}{n}\sum_{k=1}^{n} x_k\] -
선형 투영 모델 데이터를 단위벡터 (e) 방향으로 투영
\[x_k \approx m + a_k e\]투영 계수
\[a_k = e^T(x_k - m)\] -
Scatter Matrix
\[S = \sum_{k=1}^{n} (x_k - m)(x_k - m)^T\]
산포 행렬공분산 행렬과 같은 형태 (스케일만 다름)
-
PCA 최적화 문제 → 고유값 문제
\[\max_{e} \quad e^T S e\]
분산을 최대로 하는 방향 (e) 를 찾는 문제이는 고유값 문제로 된다
\[S e = \lambda e\] -
주성분(Principal Components)
\[e_1, e_2, \dots, e_d\]
가장 큰 고유값에 대응하는 고유벡터가 1st PC상위 (d’)개 축만 선택하여 투영
\[a_i^{(k)} = e_i^T(x_k - m), \qquad i = 1,\dots,d'\] -
차원 축소 오차 (버린 정보량) (d’)차까지 사용했을 때 남는(버려지는) 정보량
\[J_{d'} = \sum_{i=d'+1}^{d} \lambda_i\]
PCA의 특징
이렇게 해서 가지는 PCA의 결과(고유값)은 다음과 같은 특징들을 가진다.
1) 비지도학습기반의 차원 축소 : 데이터 분포만 보고 축을 결정할 수 있다. 2) 최대 분산의 보존 : 투영 후, 분산이 최대가 되도록 방향을 선택 -> 가장 많은 정보가 담긴 축을 찾는다. 3) 직교축의 생성 : 고유벡터들간에는 서로 직교한다. 4) 최소제곱오차를 가진다.(MSE) : 원본데이터를 투영선으로 근사했을때, 재구성 오차가 최소다. 5) 낮은 고유값은 버려지는 축이다 : 작은 고유값은 기여도가 작은 방향, 차원 축소시 우선 제거된다.
왜 PCA?
고차원의 데이터는
- 중복된 정보가 많고
- 축 간 상관성이 존재하는 경우가 많으며
- 계산비용과 저장 비용이 커지는 문제가 있다.
따라서, 정보는 최대한 유지하면서 차원을 줄이는 방법 이 된다. 차원을 몇까지 줄일 것인가는 데이터의 특성을 보고, 잘 판단해야 하는 문제가 남아있다마는. 그래도 한차원 줄일때마다 연산량을 극적으로 낮출수 있다는 장점을 눈여겨봐야 한다.
Scatter Matrix를 보면, {(데이터) - (평균)} 을 제곱한 것들의 합인 것을 알수 있다.
죽, PCA는 오차의 제곱이 작아지는 방향을 찾는 문제로 설명할 수 있으며,
이 수식을 전개해보면, 결국 고유값을 찾는 문제로 귀결될 수 있음을 알 수 있다.
(유도할 줄 알면 좋다. 근데, 유도식을 어디에서 쓰긴 할까….???)
그렇게 얻은 고유값을 각각의 축으로 하여 데이터를 투영시키면 그것을 이 데이터의 “주성분(Principle Components)”이라고 이야기 한다.
PCA가 잘될때와 안될때
- 잘 되는 경우
- 데이터가 타원형 분포일때
- 축 사이의 강한 상관관계가 있을때
- 노이즈의 방향이 작은 고유값에 몰릴때 (노이즈를 날리면 되니까)
- 저차원구조가 선형적으로 존재할때 이런 경우 상위 몇개 축만으로도 대부분의 분산(variance)를 설명가능하다.
- 잘 안되는 경우
- 클래스 정보가 중요하지만 분산이 작을때
- 테이터 구조가 비선형 다양체(Manifold)
- 이상치(Outlier)가 크고 분산을 강하게 왜곡할때
- 스케일이 다른 feature가 섞여있을때 이런 경우 전처리(정규화, 표준화)를 통해 다시 PCA 해석을 수행해볼 수 있겠다.
LDA (Linear Discriminant Analysis)
PCA가 차원의 축소를 위해 수행하는 알고리즘이라면, LDA는 클래스를 구분하기 위해 사용하는 위한 방법이다.
Linear Discriminant Analysis is a supervised machine learning and statistical technique used for classification and dimensionality reduction.
즉 클래스간 분리가 가장 잘되는 방향을 찾는 지도학습 기반 차원축소라는 것. 이를 통해 클래스간 평균은 서로 멀어지게 하고, 같은 클래스 내부는 조밀하게 뭉쳐지게 하는 투영의 축을 찾는다.
두 클래스의 평균 $m_0$, $m_1$ 이 있을때, LDA는
1) 투영방향 $w$에서 클래스간의 평균간 거리를 높이고,
2) 클래스간의 분산을 낮추도록 최적화하는 과정을 거친다.
그러면, 우선 투영 후 클래스간의 평균거리를 정의해야 한다. 그러기 위해선 클래스들의 평균, 분산값들을 알 필요가 있다.
클래스 평균
앞서서 PCA에서는 전체 데이터의 평균을 잡았다고 하면,
이번에는 클래스들의 평균을 봐야 한다.
- $C_i$ : $i$번째 클래스
- $n_i$ : 클래스 내 샘플 수
Within-Class scatter (클래스의 분산)
예전에 회사서 통계를 배울때, 군간비교, 군내비교 라는 말을 한다.
보통 군이라고 하면 Group을 이야기하곤 했는데, 비슷한 개념으로 클래스 내부의 분산을 본다.
즉 이 클래스의 데이터가 얼마나 퍼져있는가를 본다.
Between-class scatter (클래스간의 분산)
클래스 내부의 분산을 알았다면, 이제 클래스들 사이의 분산을 알아야 한다.
\[S_b = (m_1 - m_0)(m_1 - m_0)^T\]Fisher Discrimination Ratio
그러면 이제, LDA를통해 얻고자 하는 방향 $w$ 에 대한 식을 얻을 수 있다.
\[J(w) = \frac{(w^T(m_1-m_0))^2}{w^T S_w w}\]- 분자 = 클래스 평균 간 거리 (between-class)
- 분모 = 클래스 내부 분산 (within-class)
LDA 최적화 해석
최적화 문제:
\[\max_w\; \frac{w^T S_b w}{w^T S_w w}\]일반화된 고유값 문제:
\[S_b w = \lambda S_w w\]2-class 해:
\[w \propto S_w^{-1}(m_1 - m_0)\]해석:
- $(m_1 - m_0)$ = 평균 차 벡터
- $S_w^{-1}$ = 내부 분산 보정
→ 분산이 큰 축은 덜 강조되고
→ 분산이 작은 축은 더 강조됨
다중 클래스에서의 LDA
클래스가 2개 이상인 경우, 각 클래스 평균이 전체 평균으로부터 얼마나 떨어져 있는가를 기반으로 정의된다.
클래스’들’의 평균.
\[m = \frac{1}{N}\sum_{k=1}^{N} x_k\]클래스의 평균
\[m_i = \frac{1}{n_i}\sum_{x\in C_i} x\]다중 클래스들사이의 분산 (Between-class Scatter Matrix)
\[S_b = \sum_{i=1}^{C} n_i (m_i - m)(m_i - m)^T\]- $n_i$ : 클래스 $i$의 샘플 개수
- $(m_i - m)$ : 전체 평균 대비 클래스 중심 이동량
-
$\Sigma$ : 모든 클래스 기여 합산
- 클래스 평균들이 서로 멀리 떨어질수록 $S_b$ 가 커진다
- 샘플 수가 많은 클래스는 더 크게 반영된다
- $S_b$ 는 “클래스 간 분리도”를 표현하는 척도이다
Fisher Discriminant Objective (Multi-class)
\[\max_W \quad \frac{|W^T S_b W|}{|W^T S_w W|}\]- $S_b$ : between-class scatter
- $S_w$ : within-class scatter
- $W$ : 투영 행렬 (여러 개의 판별축을 동시에 찾음)
-
$ \cdot $ : 행렬식 (determinant)
Generalized Eigenvalue Problem
방금의 Fisher disciriminant 목적함수는 다음 식으로 변환된다.
\[S_b W = S_w W \Lambda\]- $W$ : 일반화된 고유벡터 행렬
- $\Lambda$ : 고유값 대각 행렬
즉,
$S_w^{-1} S_b$ 의 고유벡터를 구하면
LDA 판별축을 얻을 수 있다.
LDA 투영 차원의 제한
다중 클래스 LDA에서 찾을 수 있는 최대 판별 차원은
\[\text{dim}(W) \le C - 1\]그 이유는:
- $S_b$ 의 랭크(rank)가 최대 $C-1$
- 즉, 클래스 평균은 서로 독립하게 움직일 수 있는 방향이 $C-1$개뿐
따라서,
클래스가 많아질수록
LDA는 “클래스 구조를 유지하는 최소 차원 공간”으로 압축된다.
요약
- PCA → 분산을 최대화하는 방향
- LDA → 분리도가 최대가 되는 판별 방향
LDA는
“클래스 간 거리 / 클래스 내부 분산” 비율을 극대화하는
지도학습 기반 차원 축소 방법이다.
댓글남기기