0. 들어가기전에
[머신러닝] 차원의 저주와 차원 축소에서 이어집니다.
1. PCA (Principal Component Analysis)
PCA는 가장 대표적인 차원 축소 기법으로 여러 변수 간에 존재하는 상관관계를 이용해 이를 대표하는 주성분(Principal Component)을 추출해 차원을 축소하는 기법이다.
목적
1. 고차원의 데이터를 저차원으로 줄인다.
2. 공통된 (상관관계가 높은) 변수들을 줄여서 주성분을 찾는다.
1-1. 방법
1. 기존 데이터의 정보 유실을 최소화하기 위하여 가장 높은 분산을 가지는 데이터의 축을 찾아 해당 축으로 차원을 축소한다. (분산이 데이터의 특성을 가장 잘 나타내는 것으로 간주)
2. 첫 번째 축에서 직교하는 축을 선정하여 해당 축으로 차원을 축소한다. (직교하는 축을 쓰는 이유는 첫 번째 주성분이 담아내지 못한 특성을 최대한 담아낼 수 있는 방향이기 때문)
3. 1번과 2번을 축소시키려는 차원의 수에 맞게 반복한다.
1-2. 선형대수
선형대수 관점에서 생각하면, 입력 데이터의 공분산 행렬(Covariance Matric)를 고유값 분해하고 이렇게 구한 고유벡터에 입력 데이터를 선형 변환하는 것이다. 이렇게 들으면, 이해가 안가므로 각각 단어의 의미를 알아보면서 이해해보자.
- 선형 변환: 특정 벡터에 행렬 A를 곱해 새로운 벡터로 변환하는 것
- 공분산: 두 변수 간의 선형 관계를 나타내는 값
- 공분산 행렬: 여러 변수와 관련된 공분산을 포함하는 정방형 행렬
- 고유 벡터: 행렬 A를 곱하더라도 방향이 변하지 않고 그 크기만 변하는 벡터
PCA에서는 높은 분산을 가지도록 한다. 따라서, 공분산 행렬의 특성을 보존해야 한다. 그리고 고유값 분해로 고유벡터를 구하면, 고유벡터는 방향이 변하지 않으므로 특성을 보존한다고 생각할 수 있고 해당 방향으로 선형 변환(사영)을 시켜서 차원을 축소한다는 것이다.
1-3. 사용법
sklearn에서 기본으로 제공해주는 iris 데이터셋을 통해 사용법을 알아보자.
# 라이브러리 임포트
from sklearn.datasets import load_iris
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
# 데이터 프레임으로 만들기
iris = load_iris()
columns = ['sepal_length', 'wepal_width', 'petal_length', 'petal_width']
irisDF = pd.DataFrame(iris.data, columns = columns)
irisDF['target'] = iris.target
print(irisDF.head())
print(irisDF.drop('target', axis=1).shape)
sepal_length wepal_width petal_length petal_width target
0 5.1 3.5 1.4 0.2 0
1 4.9 3.0 1.4 0.2 0
2 4.7 3.2 1.3 0.2 0
3 4.6 3.1 1.5 0.2 0
4 5.0 3.6 1.4 0.2 0
(150, 4)
# 전처리
from sklearn.preprocessing import StandardScaler
iris_scaled = StandardScaler().fit_transform(irisDF.drop('target', axis=1))
# PCA 수행
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
pca.fit(iris_scaled)
iris_pca = pca.transform(iris_scaled)
print(iris_pca.shape)
(150, 2)
차원의 수가 줄어들었음을 확인할 수 있다.
# 칼럼 변경
pca_columns = ['pca_1', 'pca_2']
irisDF_pca = pd.DataFrame(iris_pca, columns = pca_columns)
irisDF_pca['target'] = iris.target
irisDF_pca['target'] = irisDF_pca['target'].map({0: iris.target_names[0], 1: iris.target_names[1], 2: iris.target_names[2]})
irisDF_pca.head()
pca_1 | pca_2 | target | |
---|---|---|---|
0 | -2.264703 | 0.480027 | setosa |
1 | -2.080961 | -0.674134 | setosa |
2 | -2.364229 | -0.341908 | setosa |
3 | -2.299384 | -0.597395 | setosa |
4 | -2.389842 | 0.646835 | setosa |
# 시각화
sns.scatterplot(data=irisDF_pca, x="pca_1", y="pca_2", hue="target")
plt.legend()
plt.show()
# 데이터 반영 비율 확인
print(pca.explained_variance_ratio_, sum(pca.explained_variance_ratio_))
[0.72962445 0.22850762] 0.9581320720000164
pca_1는 기존 데이터의 73%를 반영하고 pca_2는 23%정도 반영한다는 의미이다. 그리고 합쳐서 96%정도 반영하므로 정보의 손실이 거의 없다고 생각할 수 있다.
1-4. 요약
- PCA는 고차원의 데이터를 저차원의 데이터로 차원 축소하는 알고리즘이다.
- 분산이 큰 벡터부터 투영하므로 노이즈 제거 효과도 있다.
- PCA 수행 전 스케일링 잊지 말것!
2. Reference
'머신러닝' 카테고리의 다른 글
[머신러닝] 차원의 저주와 차원 축소 (0) | 2022.07.28 |
---|