LDA vs PCA: 클래스를 분리하는 투영은 분산이 가장 큰 방향인 경우가 드뭅니다
요약
PCA와 LDA의 차이점을 비교하며, 클래스 분리가 목적일 때 PCA가 왜 부적절할 수 있는지 설명합니다. LDA가 클래스 간 산포와 클래스 내 산포의 비율을 최대화하는 Fisher 기준을 통해 어떻게 최적의 투영 축을 찾는지 다룹니다.
핵심 포인트
- PCA는 레이블을 고려하지 않고 전체 분산을 최대화하는 방향을 찾음
- LDA는 클래스 간 산포를 클래스 내 산포로 나눈 비율을 최대화함
- LDA는 지도 학습 기반의 차원 축소 및 분류 도구로 활용 가능
- 최적의 축은 Sw⁻¹ Sb의 고유벡터를 통해 계산됨
PCA는 누군가 "차원 축소 (reduce the dimensions)"라고 말할 때 반사적으로 떠오르는 방법입니다. 하지만 PCA는 레이블 (labels)을 전혀 고려하지 않으며, 이러한 맹목성 때문에 정확히 잘못된 방향을 가리키게 되는 매우 흔한 상황이 존재합니다. 저는 두 개의 점 구름 (clouds of points)을 드래그하면 두 가지 투영 축 — PCA와 LDA의 축 — 이 실시간으로 재계산되는 것을 볼 수 있는 대화형 데모를 제작했습니다. 이를 통해 실패 사례와 해결책을 놓치지 않고 확인할 수 있습니다.
PCA를 망가뜨리는 설정
길쭉한 두 개의 클래스가 각각 긴 시가 (cigar) 모양으로 늘어나 나란히 놓여 있다고 상상해 보세요. 가장 큰 전체 확산 (biggest total spread) 방향은 이 시가들의 길이를 따라 흐르며, 이 방향은 클래스를 구분하는 것과는 아무런 관련이 없습니다. 분산 (variance)을 최대화하는 PCA는 기쁘게 이 방향을 선택합니다. 점들을 해당 축으로 붕괴시키면 두 클래스는 하나의 흐릿한 언덕처럼 겹쳐지게 됩니다.
LDA (Linear Discriminant Analysis, 선형 판별 분석)는 레이블을 사용합니다. LDA는 각 클래스 내부의 확산에 상대적으로 클래스 평균들이 멀리 떨어져 있는 축을 찾습니다. 이 경우, 그 방향은 시가를 가로지르는 방향이며, PCA가 선택한 방향과 거의 수직입니다.
Fisher 기준 (The Fisher criterion)
LDA는 두 가지 "산포 (scatters)"의 비율을 최대화합니다:
J(w) = (wᵀ S_b w) / (wᵀ S_w w)
클래스 간 산포 (between-class scatter) / 클래스 내 산포 (within-class scatter)
S_b는 신호 (signal)로, 클래스 평균들이 전체 평균으로부터 얼마나 떨어져 있는지를 나타냅니다. S_w는 노이즈 (noise)로, 각 클래스가 자체 평균 주변으로 얼마나 퍼져 있는지를 나타냅니다. 신호 대 노이즈 (signal-over-noise)를 최대화하는 것이 핵심 아이디어입니다. 두 산포 행렬은 이 과정의 근간이 됩니다:
Sw = np.zeros((d, d)) # 클래스 내 산포 (within-class scatter)
for c in classes:
Xc = X[y == c] - means[c]
...
축을 구하는 방법
Fisher 기준을 최대화하는 것은 일반화된 고유값 문제 (generalized eigenvalue problem)입니다. 즉, 최적의 축은 S_w⁻¹ S_b의 상위 고유벡터 (eigenvectors)입니다. 두 개의 클래스인 경우 이는 깔끔한 폐쇄형 (closed form)으로 수렴하며, 데모에서 실시간으로 실행되는 한 줄의 코드는 바로 이것입니다:
# 두 클래스 폐쇄형 (페이지에서 그리는 방식)
w = np.linalg.inv(Sw) @ (means[1] - means[0])
w /= np.linalg.norm(w)
...
새로운 데이터 포인트를 투영(projecting)한 뒤, 투영된 클래스 평균들의 중간값과 비교하여 분류합니다. 이것이 데모에서 보여준 결정 임계값(decision threshold)입니다.
LDA는 분류기이자 차원 축소 도구입니다
scikit-learn에서 LDA는 빠르고 폐쇄형(closed-form)인 분류기(classifier)이자 지도 학습 기반의 차원 축소(dimensionality reducer) 도구입니다. 차원 축소 도구로서 LDA는 PCA의 지도 학습 버전(supervised cousin)이라고 할 수 있습니다. "몇 개의 축을 유지한다"는 아이디어는 동일하지만, 단순히 분산(variance)이 가장 큰 축이 아니라 클래스를 가장 잘 구별(discriminate)하는 축을 유지합니다.
X_lda = LinearDiscriminantAnalysis(n_components=1).fit_transform(X, y) # y를 사용함
X_pca = PCA(n_components=1).fit_transform(X) # y를 무시함
# 길게 늘어진 클래스 형태에서 X_lda는 레이블을 분리하지만, X_pca는 종종 그러지 못합니다.
한 가지 기억해야 할 점은, transform은 C개의 클래스에 대해 최대 C - 1개의 축만을 제공한다는 것입니다. 클래스 간 산포(between-class scatter)가 가질 수 있는 범위가 그만큼이기 때문입니다.
가정을 이해하세요
LDA는 각 클래스가 공유된 공분산(shared covariance)을 가진 가우시안(Gaussian) 분포를 따른다고 가정하며, 이것이 결정 경계(decision boundary)가 선형(linear)인 이유입니다. 이 가정은 조건이 충족될 때는 장점이 되지만, 그렇지 않을 때는 함정이 됩니다.
- LDA — 가우시안 클래스, 공유된 공분산 → 선형 경계, 지도 학습(supervised).
- QDA — 클래스별 공분산 → 클래스 형태가 실제로 다를 때 곡선 경계(curved boundary).
- PCA — 레이블 없음, 분산 유지 → 비지도 학습(unsupervised) 압축.
또한 샘플 수가 적어 S_w가 거의 특이 행렬(near-singular)에 가까워질 경우, 이를 그대로 역행렬로 계산하지 마세요. 수축(shrinkage) 기법(solver="lsqr", shrinkage="auto")을 사용해야 합니다.
핵심은 두 방식의 정확도 차이에 있습니다. 클래스 내부의 신장(within-class elongation)이 클래스 간 분리보다 훨씬 클 때, PCA는 늘어진 방향을 따라 휘어져 버려 1차원 투영 성능이 저하되지만, LDA는 그 신장 방향을 나누어 제거하고 분리 축(separating axis)에 안착합니다. 설령 해결이 불가능해 보이는 중첩된 문제라 할지라도, LDA는 여전히 "가장 덜 나쁜" 방향을 찾아내며, 이는 분산만으로는 보장할 수 없는 결과입니다.
클래스 분리 (class separation) 및 신장 (elongation) 슬라이더를 드래그하여 두 축, 투영 (projections), 그리고 정확도 (accuracies)가 실시간으로 재계산되는 것을 확인해 보세요:
https://dev48v.infy.uk/ml/day35-lda.html
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기