코딩초보 김씨

[ML] 데이터 전처리 - 선형 차원 축소 본문

Python/Machine Learning

[ML] 데이터 전처리 - 선형 차원 축소

초보김씨 2021. 6. 14. 20:59

[ 차원 축소란? ]

많은 피처로 구성된 다차원의 데이터 셋의 차원을 축소하여 새로원 차원의 데이터 세트를 생성하는 것

 

 

아래 이미지가 가장 직관적이고 이해가 쉬워서 가져왔다.

각 차원 공간의 25%에 해당하는 데이터가 위치하는 비율이 42%, 14% ..., 3%로 점차 줄어드는 것을 볼 수 있다.

 

출처 : https://blog.mathpresso.com/

 

 

 

[ 차원이 너무 클 때의 문제점 ]

1. 차원의 저주에 빠지기 쉽다.

2. 다중 공산성 문제

    많은 feature 중 몇 feature들끼리는 강한 상관관계를 보이는 경우가 있을 것이다.

    이처럼 상관관계가 높은 feature들을 함께 학습 시키면, 모델의 과적합이 발생하여 학습 성능 저하 가능성이 있음.   

 

 

 

" 따라서 모델에 데이터 셋을 적용하기 전에 어떤 feature가 모델의 성능에 큰 영향을 줄지 파악하고, 

feature를 선택/가공 하는 과정이 필요하다. "

 

 


 

[ 차원 축소의 종류 ]

 

1. 피처 선택(feature selection) : 불필요한 feature는 아예 제거하고, 데이터의 특징을 잘 나타내는 주요 feature만 선택

2. 피처 추출(feature selection) : 기존 feature를 저차원이 중요 feature로 압축해서 추출.

                                          이렇게 추출된 중요 feature는 기존과 완전히 다른 값이 된다.

 

 


 

 

[ PCA (Princial Component Analysis) 주성분분석 ]

PCA는 고차원의 데이터를 저차원으로 압축하는 대표적인 차원 축소 방법이며,

데이터를 가장 잘 표현하는 방향으로 축을 생성하고, 새롭게 생성된 축으로 데이터를 투영시킨다.

 

데이터들이 겹치면 정보의 유실이 발생할 수 있기 때문에

축을 설정할 때 데이터가 가장 넓게 펼쳐지는 축, 즉 가장 큰 분산(=공분산)을 가지는 축을 설정해야한다.

바로 이 축을 주성분 (Principal Component) 이라고 한다.

PC는 2차원에서는 2개, 3차원에서는 3개, 300차원에서는 300개가 있다.

 

분산을 크게 하려면 Eigen Value가 큰 지점을 찾아야 하는데,

Convariance Matrix 중 Eigen Value가 큰 값의 Eigen Vector를 찾고, 그를 기준으로 차원축소한다.

↑ 무슨 말인지 잘 모르겠으면, 아래 예시를 보고 이해하도록 하자!

 

 


 

[ PCA 방법 ]

방법 1. 어려움 (내 기준)
예시 출처 : github.com/minsuk-heo/python_tutorial/blob/master/data_science/pca/PCA.ipynb

# 데이터 생성
import pandas as pd

df = pd.DataFrame(columns=['calory', 'breakfast', 'lunch', 'dinner', 'exercise', 'body_shape'])
df.loc[0] = [1200, 1, 0, 0, 2, 'Skinny']
df.loc[1] = [2800, 1, 1, 1, 1, 'Normal']
df.loc[2] = [3500, 2, 2, 1, 0, 'Fat']
df.loc[3] = [1400, 0, 1, 0, 3, 'Skinny']
df.loc[4] = [5000, 2, 2, 2, 0, 'Fat']
df.loc[5] = [1300, 0, 0, 1, 2, 'Skinny']
df.loc[6] = [3000, 1, 0, 1, 1, 'Normal']
df.loc[7] = [4000, 2, 2, 2, 0, 'Fat']
df.loc[8] = [2600, 0, 2, 0, 0, 'Normal']
df.loc[9] = [3000, 1, 2, 1, 1, 'Fat']

# feature vectors 설정
X = df[['calory', 'breakfast', 'lunch', 'dinner', 'exercise']]

# 타겟값 설정
Y = df[['body_shape']]

 

0. 전처리 : StandardScaler로 데이터 Normalization (평균을 0, 표준편차를 1로 변환)

# 표준정규화
from sklearn.preprocessing import StandardScaler
x_std = StandardScaler().fit_transform(X)

 

1. 입력 데이터 세트의 공분산 행렬을 생성

import numpy as np

# 전처리한 x_std의 Transpose (column에 있는 feature들을 row로 변경)
features = x_std.T

# 공분산 행렬 생성
covariance_matrix = np.cov(features)
print(covariance_matrix)

공분산 행렬 (Covariance matrix) 생성

 

2. 공분산 행렬의 고유벡터와 고유값을 계산

# np.linalg.eig 함수는 Eigenvalue와 Eigenvector 반환
eig_vals, eig_vecs = np.linalg.eig(covariance_matrix)
print('Eigenvectors \n%s' %eig_vecs)
print('\nEigenvalues \n%s' %eig_vals)

 

3. 고유값이 가장 큰 순으로 K개(PCA 변환 차수만큼)만큼 고유벡터를 추출

# 고유벡터 1개로도 73%의 충분한 분산을 갖기 때문에 데이터를 1차원으로 축소
eig_vals[0] / sum(eig_vals)

 


4. 고유값이 가장 큰 순으로 추출된 고유벡터를 이용해 새롭게 입력 데이터를 변환

# eigen vector 위에 projection(투영) -> eigen vector 위에 데이터를 올려놓겠다
projected_X = x_std.dot(eig_vecs.T[0])

result = pd.DataFrame(projected_X, columns=['PC1'])
result['y-axis'] = 0.0
result['label'] = Y


5. 시각화

import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

sns.lmplot('PC1', 'y-axis', data=result, fit_reg=False,  # x-axis, y-axis, data, no line
           scatter_kws={"s": 50}, # marker size
           hue="label") # color

plt.title('PCA result')

 

방법 2. 매우 간단
from sklearn import decomposition

# n_components : 차원수
pca = decomposition.PCA(n_components=1)

# fit_transform을 통해 차원축소
sklearn_pca_x = pca.fit_transform(x_std)

sklearn_result = pd.DataFrame(sklearn_pca_x, columns=['PC1'])
sklearn_result['y-axis'] = 0.0
sklearn_result['label'] = Y

 

 

'Python > Machine Learning' 카테고리의 다른 글

[ML] 지도학습  (0) 2021.06.13
[ML] 비지도학습 - Clustering (군집화) 중 k-Means  (0) 2021.06.09
Comments