Search
🤖

ML 08. 차원 축소

Created at
2021/01/27
Updated at
2021/01/28
Tags
Keywords
ML
3 more properties
차원 축소를 통해 머신러닝 문제에서 차원의 저주를 해결하고 훈련의 속도를 높이거나, 일부 경우 모델 성능 향상을 도모할 수도 있다. 또한 차원을 축소함으로써 데이터 시각화를 통해 데이터에서 인사이트를 얻는 데에도 도움이 될 수 있다.
목차

1. 차원의 저주

차원의 저주
고차원 공간에서는 (저차원 공간에는 없는) 많은 문제가 일어난다는 사실을 뜻함
고차원 data set은 매우 희박할 위험, 즉 대부분 train data가 서로 멀리 떨어져 있음
고차원일수록 저차원일 때보다 예측이 불안정, 즉 train set의 차원이 클수록 과적합 위험이 커짐
해결 방법
훈련 샘플의 밀도가 충분히 높아질 때까지 훈련 세트의 크기를 키우기
근본적인 해결 방법이나, 실제로는 일정 밀도에 도달하기 위해 필요한 훈련 샘플 수는 차원 수가 커짐에 따라 기하급수적으로 늘어나기 때문에 어려운 일
차원 축소
모델 훈련 전에 train set의 차원을 감소시키면 훈련 속도는 빨라지지만 항상 더 낫거나 간단한 솔루션이 되는 것은 아니며 이는 전적으로 data set에 달려 있음

2. 차원 축소를 위한 접근 방법

2.1 투영(projection)

대부분 훈련 샘플은 고차원 공간 안의 저차원 부분 공간(subspace)에 (또는 가까이) 놓여 있음
이 경우 투영을 통해 데이터셋의 차원을 줄일 수 있음
부분 공간이 뒤틀리거나 휘어있는 경우에는 최선의 방법이 아님
투영 전 3차원 데이터셋
투영 후 2차원 데이터셋

2.2 매니폴드 학습(manifold learning)

dd 차원 매니폴드: 국부적으로 dd차원 초평면으로 보일 수 있는 nn차원 공간의 일부 (d<n)(d < n)
예시: 스위스 롤(Swiss roll)은 2D 매니폴드 (d=2,n=3)(d=2, n=3)
스위스롤 데이터셋
매니폴드 학습
많은 차원 축소 알고리즘은 훈련 샘플이 놓여 있는 매니폴드를 모델링하는 식으로 작동
대부분 실체 고차원 데이터셋이 더 낮은 저차원 매니폴드에 가깝게 놓여 있다는 매니폴드 가정(가설)에 근거
종종 암묵적으로 분류/회귀 등 작업이 저차원의 매니폴드 공간에 표현되면 더 간단해질 것이란 가정과 병행됨 but 항상 유효하지 않음!
모델 훈련 전에 차원 감소시 훈련 속도는 빨라지지만 항상 더 나은 솔루션이 되지는 않으며 이는 전적으로 데이터셋에 달려있음

3. PCA(principal component analysis)

- 가장 인기있는 차원 축소 알고리즘 - 데이터에 가장 가까운 초평면(hyperplane)을 정의 후 데이터를 이 평면에 투영시킴

3.1 PCA 방법

분산 보존
분산을 최대로 보존하는 올바른 초평면을 선택 (정보가 가장 적게 손실됨)
원본 데이터셋과 투영된 것 사이의 평균제곱거리를 최소화하는 축 선택
주성분
PCA 작동 방식: train set에서 분산이 최대인 축을 찾기 → 첫번째 축에 직교하고 남은 분산을 최대한 보존하는 두번째 축을 찾기 → 이전 두 축에 직교하는 세번째 축 찾기 → ...
이 과정에서 ii번째 축을 이 데이터의 ii번째 주성분(principal component, PC)라고 함
특잇값 분해(singular value decomposition, SVD)라는 표준 행렬 분해 기술 이용
train set 행렬 XX를 세 개 행렬의 행렬 곱셈인 UVTU\sum V^T로 분해
X=UVTX = U \sum V^T (VV: 주성분 행렬)
d차원으로 투영
추출한 주성분 중 처음 d개 주성분으로 정의한 초평면에 투영하여 데이터셋의 차원을 d차원으로 축소
d차원으로 축소된 데이터셋 계산식
Xdproj=XWdX_{d-proj} = XW_d (WdW_d 는 행렬 VV의 첫 dd열로 구성된 행렬)

3.2 PCA 실행 (사이킷런)

사이킷런 패키지를 이용하면 PCA를 간단하게 실행가능 (데이터셋 - 평균 작업까지 처리)
components_ 속성: 주성분 행렬 WdW^d의 전치
첫 번째 주성분 단위 벡터: pca.components_.T[:, 0]

3.3 적절한 차원 수 선택

explained_variance_ratio_ 변수: 설명된 분산의 비율
각 주성분의 축을 따라 놓여 있는 데이터셋의 분산 비율
충분한 분산이 될 때까지 더해야 할 차원수를 선택하는 것이 간단
train set의 분산을 95%로 유지하는데 필요한 최소한의 차원 수 d 계산 가능
pca = PCA() # 차원 축소없이 PCA 계산 pca.fit(X_train) cumsum = np.cumsum(pca.explained_variance_ratio_) d = np.argmax(cumsum >= 0.95) + 1
Python
복사
n_components를 보존하려는 분산의 비율로 지정(0~1)하여 PCA 실행
# n_components에 위에서 계산한 주성분 수 d를 직접 넣기보다는 분산 비율로 넣는 것이 나음 pca = PCA(n_components=0.95) X_reduced = pca.fit_transform(X_train)
Python
복사
분산을 차원 수에 대한 함수로 나타내어 적절한 지점 선택 (변곡점 이후로는 정보의 손실이 크지 않음)

3.4 압축을 위한 PCA

PCA 실행시 훈련세트 크기가 감소
PCA 투영 변환을 반대로 적용하면 원래 차원의 개수로 되돌릴 수 있음
투영에서 유실된 일정량의 정보는 살아나지 않으므로 원본과 같진 않음
재구성 오차(reconstruction error): 원본 데이터와 재구성된 데이터 사이의 평균 제곱 거리
PCA 역변환 공식: Xrecovered=XdprojWdTX_{recovered} = X_{d-proj}W_d^T
역변환 코드
pca = PCA(n_components = d) X_reduced = pca.fit_transform(X_train) X_recovered = pca.inverse_transform(X_reduced)
Python
복사

3.5 랜덤 PCA

svd_solver 매개변수
"ramdonized": 랜덤 PCA(ramdomized PCA)라는 확률적 알고리즘을 사용해 처음 dd개 주성분에 대한 근삿값을 빠르게 찾음. ddnn보다 많이 작으면 완전 SVD보다 훨씬 빠름
"auto": svd_solver의 기본값. mm이나 nn이 500보다 크고 ddmm이나 nn의 80% 미만일 때 자동으로 랜덤 PCA 알고리즘 사용
"full": 완전 SVD 방식을 강제함

3.6 점진적 PCA

점진적 PCA(incremental PCA, IPCA): 전체 훈련 세트를 메모리에 올리지 않는 알고리즘
훈련 세트를 미니배치로 나눈 뒤 IPCA 알고리즘에 하나씩 주입
훈련 세트 크기가 클 때 유용하고 온라인으로 PCA 적용 가능
from sklearn.decomposition import IncrementalPCA n_batches = 100 inc_pca = IncrementalPCA(n_components=154) for X_batch in np.array_split(X_train, n_batches): inc_pca.partial_fit(X_batch) # fit이 아닌 partial_fit 메서드 사용! X_reduced = inc_pca.transform(X_train)
Python
복사
넘파이 memmap 클래스를 사용해서 이진 파일에 저장된 매우 큰 배열을 메모리에 들어 있는 것처럼 다룰 수 있음

4. 커널 PCA

커널 PCA(kPCA): 커널 트릭을 PCA에 적용해 차원 축소를 위한 복잡한 비선형 투영을 수행
투영 후 샘플의 군집을 유지하거나 꼬인 매니폴드에 가까운 데이터셋을 펼칠 때에도 유용
사이킷런 KernelPCA 활용
from sklearn.decomposition import KernelPCA rbf_pca = KernelPCA(n_components = 2, kernel="rbf", gamma=0.04) X_reduced = rbf_pca.fit_transform(X)
Python
복사
커널 선택과 하이퍼파라미터 튜닝
kPCA는 비지도 학습이지만 종종 지도학습의 전처리 단계로 활용되므로, 그리드 탐색을 사용하여 주어진 문제에서 성능이 가장 좋은 커널과 하이퍼파라미터를 선택할 수 있음
비지도 학습 방법으로는, 가장 낮은 재구성 오차를 만드는 커널과 하이퍼파라미터를 선택하는 방식이 있으나 재구성이 선형 PCA만큼 쉽지 않음

5. 지역 선형 임베딩(locally linear embedding, LLE)

강력한 비선형 차원 축소(nonlinear dimensionality reduction, NLDR) 기술
투영에 의존하지 않는 매니폴드 학습
각 훈련 샘플이 가장 가까운 이웃(closest neighbor, cn)에 얼마나 선형적으로 연관되어있는지 측정하고 국부적인 관계가 가장 잘 보존되는 훈련 세트의 저차원 표현을 찾음
사이킷런 LocallyLinearEmbedding 사용
# 스위스 롤 데이터셋 생성 from sklearn.datasets import make_swiss_roll X, t = make_swiss_roll(n_samples=1000, noise=0.2, random_state=42) # LLE from sklearn.manifold import LocallyLinearEmbedding lle = LocallyLinearEmbedding(n_components=2, n_neighbors=10, random_state=42) X_reduced = lle.fit_transform(X)
Python
복사
계산복잡도 때문에 대량의 데이터셋에 적용하기는 어려움
PCA로 불필요한 차원을 대폭 제거한 후 LLE 같이 느린 알고맂므을 적용하면 비슷한 성능을 내지만 속도가 훨씬 빨라짐

6. 다른 차원 축소 기법

랜덤 투영(random projection)
랜덤한 선형 투영을 사용해 데이터를 저차원 공간으로 투영
sklearn.random_projection
다차원 스케일링(multidimensional scaling, MDS)
샘플 간의 거리를 보존하면서 차원을 축소
Isomap
각 샘플을 가장 가까운 이웃과 연결하는 식으로 그래프를 만듦 → 샘플간의 지오데식 거리(geodesic distance)를 유지하면서 차원 축소
t-SNE(t-distribued stochastic neighbor embedding)
비슷한 샘플은 가까이, 비슷하지 않은 샘플은 멀리 떨어지도록 하면서 차원을 축소
시각화에 많이 사용되며 특히 고차원 공간에 있는 샘플의 군집을 시각화할 때 사용
선형 판별 분석(linear discriminant analysis, LDA)
분류 알고리즘이지만 훈련 과정에서 클래스 사이를 가장 잘 구분하는 축을 학습
데이터가 투영되는 초평면을 정의하는 데 사용 가능
투영을 통해 클래스를 멀리 떨어지게 유지시키므로 SVM 분류기 같은 다른 분류 알고리즘을 적용하기 전에 차원을 축소시키는 데 좋음
참고자료
오렐리앙 제롬 지음, 박해선 옮김, ⟪핸즈온 머신러닝 2/E⟫