지난 여러 포스트에서 다루었던 특성 선택 (feature selection)은 원본 데이터의 feature를 유지하면서 덜 중요한 feature를 제거하는 방법이었습니다. 하지만 학습 알고리즘의 효율성을 높이기 위한 특성 줄이기의 방법으로는 새로운 특성 공간으로 데이터를 투영하여 원본 데이터의 정보를 최대한 유지하면서 특성 차원을 압축하는 차원 축소 (dimension reduction) 방법도 있습니다. 이번 포스트에서는 차원 축소에서 가장 대표적인 알고리즘, PCA (Principle Component Algorithm)을 다루어보도록 하겠습니다.
차원 축소는 변수 선택에 비해 어떤 장점을 지닐까요? 변수 선택은 손쉽게 덜 중요한 feature를 제거하지만 데이터 특성의 일부분을 완전히 제거하는 것이므로 데이터 자체를 표현한다고 보기는 어렵습니다. 하지만 차원 축소는 원본 데이터 정보를 최대한 유지한 채 2/3 차원으로 축소하면 시각화가 가능하며 중요한 정보를 추출하기 때문에 데이터 상의 노이즈를 제거하는 효과가 있습니다.
Principle Component Analysis
Background
고차원 데이터를 어떠한 벡터 $v$를 통해 저차원으로 투영시킬 때 저차원 상에서 데이터의 분산이 가장 큰 방향이 데이터의 정보를 가장 많이 가지고 있습니다. 즉, 차원을 효과적으로 축소하기 위해서는 원본 데이터의 정보를 최대한 많이 함유하고 있어야 하고 PCA는 저차원으로 데이터를 투영했을 때 분산이 가장 크게 되는 벡터를 찾는 알고리즘입니다.
PCA는 이를 위해 투영 이후의 차원이 직교가 되도록 하는 선형 변환을 수행합니다. 먼저, $d$차원의 $n$개의 데이터 $x_1, ..., x_n$이 존재할 때, 각 특성 별 크기 영향력을 일정하게 하기 위해 평균이 0, 분산이 1이 되도록 표준화 과정을 진행합니다. 정규화된 데이터 $n\times d$ 행렬 $X$에 대해 $v=(v_1, ..., v_d)$ 벡터를 이용해 선형 변환하고 변환된 벡터 $t_i$가 최대 분산을 가지도록 합니다.
$t_i=x_i \cdot v, i=1,...,n$
데이터를 feature 별로 정규화했으므로 $t_i$의 분산이 최대가 되도록 하는 벡터 $v$는 다음과 같습니다.
$v = arg max_{\Vert v\Vert=1} {\sum_i (x_i\cdot v)^2}$
$= arg max_{\Vert v\Vert=1} (\Vert Xw\Vert)^2 = arg max_{\Vert v\Vert=1} v^T X^T Xv$
이를 라그랑지안 기법을 이용해 풀면 최대가 되는 $v$는 데이터 행렬 $X$의 covariance 행렬 $X^TX$의 고유값이 가장 큰 고유값에 (eigenvalue) 해당하는 고유벡터 (eigenvector)가 됩니다. 이 방법으로 분산이 가장 큰 첫 번째 principle component를 찾았습니다. 두 번째 principle component를 어떻게 찾을까요?
첫 번쨰 principle component를 $v_1$이라 했을 때 원래 차원에서의 해당 벡터는 $(X\cdot v_1)v_1$이며 전체 데이터 행렬 $X$에서 이부분을 빼준 이후에 $X_2$ 똑같은 방법으로 분산을 최대화하는 principle component를 찾습니다.
$X_2 = X - Xv_1 v_1^T$
$v_2 = arg max_{\Vert v\Vert=1} (\Vert X_2 w\Vert)^2 = arg max_{\Vert v\Vert=1}$ $v^T X_2^T X_2v$
이도 마찬가지로 라그랑지안 기법을 이용해 풀면 최대가 되는 $v_2$는 $X^TX$의 남은 eigenvalue 중 최대인 두 번쨰 최대 고유값의 고유벡터가 됩니다. 즉, 이를 일반화하면 PCA는 covariance 행렬 $X^TX$의 큰 고유값들과 대응되는 고유벡터들을 찾아서 투영시키는 방법으로 정리할 수 있습니다. 특히, $X^TX$는 대칭행렬이므로 서로 다른 고유벡터들은 서로 직교하는 성질을 가지고 있습니다. 정리하면 PCA는 원본 데이터에서 투영 후 분산이 크게 되는 벡터들이 서로 직교하도록 선형 변환하는 알고리즘이라 할 수 있습니다.
In python
파이썬에서는 역시 scikit-learn 패키지가 PCA를 지원합니다. sklearn.decomposition 모듈의 PCA 함수를 이용해 쉽게 차원 축소를 수행할 수 있습니다.
타이타닉 데이터에 대해 전처리를 수행하고 sklearn.preprocessing 모듈의 StandardScaler 함수를 이용해 표준화를 수행합니다. PCA 함수의 "n_components" 파라미터를 통해 축소할 차원을 정할 수 있고 fit 함수를 이용해 PCA를 계산하여 "explaiend_variance_ratio_" 속성을 통해 각 principle component가 데이터의 분산을 얼마만큼 표현하는 지 알 수 있습니다.
# 설명 변수 데이터를 정규화(normalization)
from sklearn import preprocessing
X = preprocessing.StandardScaler().fit(X).transform(X)
# train data 와 test data로 구분(7:3 비율)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=10)
from sklearn.decomposition import PCA
# 성분을 3개로 만들기
pca = PCA(n_components=3)
pca.fit(X_train)
# 각 성분의 explained_variance_ratio_ 구하기
# explained_variance_ratio_: 각 성분에 포함된 데이터의 분산의 크기
print('explained variance ratio :', pca.explained_variance_ratio_)
특히, fit_transform 함수를 이용해 PCA 계산/데이터 차원 축소를 동시에 수행할 수 있습니다. (이는 scikit-learn 패키지에서 지원하는 대부분의 함수가 가진 공통적인 api입니다)
# 주성분분석을 수행한 데이터 만들기
pca = PCA(n_components=1)
X_train_pca = pca.fit_transform(X_train)
X_test_pca = pca.fit_transform(X_test)
print('Before PCA: {}'.format(X_train.shape))
print('After PCA: {}'.format(X_train_pca.shape))
'Machine Learning Models > Classic' 카테고리의 다른 글
XGBOOST 동작 원리 (0) | 2021.05.15 |
---|---|
Dimension Reduction - t-SNE (1) (0) | 2021.04.20 |
Classification - Metrics (2) (1) | 2021.04.19 |
Classification - Metrics (1) (0) | 2021.04.19 |
Feature Selection - XGBoost (0) | 2021.04.17 |