차원 축소를 통해 머신러닝 문제에서 차원의 저주를 해결하고 훈련의 속도를 높이거나, 일부 경우 모델 성능 향상을 도모할 수도 있다. 또한 차원을 축소함으로써 데이터 시각화를 통해 데이터에서 인사이트를 얻는 데에도 도움이 될 수 있다.
목차
1. 차원의 저주
차원의 저주
•
고차원 공간에서는 (저차원 공간에는 없는) 많은 문제가 일어난다는 사실을 뜻함
•
고차원 data set은 매우 희박할 위험, 즉 대부분 train data가 서로 멀리 떨어져 있음
•
고차원일수록 저차원일 때보다 예측이 불안정, 즉 train set의 차원이 클수록 과적합 위험이 커짐
해결 방법
•
훈련 샘플의 밀도가 충분히 높아질 때까지 훈련 세트의 크기를 키우기
◦
근본적인 해결 방법이나, 실제로는 일정 밀도에 도달하기 위해 필요한 훈련 샘플 수는 차원 수가 커짐에 따라 기하급수적으로 늘어나기 때문에 어려운 일
•
차원 축소
◦
모델 훈련 전에 train set의 차원을 감소시키면 훈련 속도는 빨라지지만 항상 더 낫거나 간단한 솔루션이 되는 것은 아니며 이는 전적으로 data set에 달려 있음
2. 차원 축소를 위한 접근 방법
2.1 투영(projection)
•
대부분 훈련 샘플은 고차원 공간 안의 저차원 부분 공간(subspace)에 (또는 가까이) 놓여 있음
•
이 경우 투영을 통해 데이터셋의 차원을 줄일 수 있음
•
부분 공간이 뒤틀리거나 휘어있는 경우에는 최선의 방법이 아님
투영 전 3차원 데이터셋
투영 후 2차원 데이터셋
2.2 매니폴드 학습(manifold learning)
•
차원 매니폴드: 국부적으로 차원 초평면으로 보일 수 있는 차원 공간의 일부
◦
예시: 스위스 롤(Swiss roll)은 2D 매니폴드
스위스롤 데이터셋
•
매니폴드 학습
◦
많은 차원 축소 알고리즘은 훈련 샘플이 놓여 있는 매니폴드를 모델링하는 식으로 작동
◦
대부분 실체 고차원 데이터셋이 더 낮은 저차원 매니폴드에 가깝게 놓여 있다는 매니폴드 가정(가설)에 근거
◦
종종 암묵적으로 분류/회귀 등 작업이 저차원의 매니폴드 공간에 표현되면 더 간단해질 것이란 가정과 병행됨 but 항상 유효하지 않음!
◦
모델 훈련 전에 차원 감소시 훈련 속도는 빨라지지만 항상 더 나은 솔루션이 되지는 않으며 이는 전적으로 데이터셋에 달려있음
3. PCA(principal component analysis)
- 가장 인기있는 차원 축소 알고리즘
- 데이터에 가장 가까운 초평면(hyperplane)을 정의 후 데이터를 이 평면에 투영시킴
3.1 PCA 방법
분산 보존
•
분산을 최대로 보존하는 올바른 초평면을 선택 (정보가 가장 적게 손실됨)
◦
원본 데이터셋과 투영된 것 사이의 평균제곱거리를 최소화하는 축 선택
주성분
•
PCA 작동 방식: train set에서 분산이 최대인 축을 찾기 → 첫번째 축에 직교하고 남은 분산을 최대한 보존하는 두번째 축을 찾기 → 이전 두 축에 직교하는 세번째 축 찾기 → ...
•
이 과정에서 번째 축을 이 데이터의 번째 주성분(principal component, PC)라고 함
•
특잇값 분해(singular value decomposition, SVD)라는 표준 행렬 분해 기술 이용
◦
train set 행렬 를 세 개 행렬의 행렬 곱셈인 로 분해
(: 주성분 행렬)
d차원으로 투영
•
추출한 주성분 중 처음 d개 주성분으로 정의한 초평면에 투영하여 데이터셋의 차원을 d차원으로 축소
•
d차원으로 축소된 데이터셋 계산식
( 는 행렬 의 첫 열로 구성된 행렬)
3.2 PCA 실행 (사이킷런)
•
사이킷런 패키지를 이용하면 PCA를 간단하게 실행가능 (데이터셋 - 평균 작업까지 처리)
•
components_ 속성: 주성분 행렬 의 전치
◦
첫 번째 주성분 단위 벡터: 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 역변환 공식:
•
역변환 코드
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)라는 확률적 알고리즘을 사용해 처음 개 주성분에 대한 근삿값을 빠르게 찾음. 가 보다 많이 작으면 완전 SVD보다 훨씬 빠름
◦
"auto": svd_solver의 기본값. 이나 이 500보다 크고 가 이나 의 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⟫