기록하는삶

[파이썬/python] 데이터 전처리(원핫인코딩_One-hot Encoding, 정규화, 표준화) 본문

AI/파이썬(Python)

[파이썬/python] 데이터 전처리(원핫인코딩_One-hot Encoding, 정규화, 표준화)

mingchin 2021. 9. 22. 00:22
728x90
반응형

정말 많은 데이터 전처리의 방법 중에서, scaling과 관련된 몇 가지를 살펴보도록 한다.

1) 원핫인코딩(One-hot Encoding)

데이터를 다루다보면 때로 필요에 의해 카테고리형 변수를 숫자로 변환하기도 한다. 예를 들어,

강아지, 고양이, 돼지, 토끼 → [1, 2, 3, 4]

와 같은 식이다. 이를 Label-Encoding이라 한다. 다만 이렇게 레이블링 하는 경우, 회귀분석 등 숫자의 크기가 가중치 결정에 있어 역할을 하는 경우 왜곡이 일어날 수 있다. (구분하기 위함일 뿐, 숫자의 크기는 아무런 의미가 없는데 머신러닝 과정에서 의미가 발생될 수 있음) 이를 방지하기 위한 Encoding 방식이 원핫인코딩이다. 같은 예에서 다음과 같다.

강아지 → 1000

고양이 → 0100

돼지 → 0010

토끼 → 0001

위와 같이 데이터의 차원만큼(위의 경우 4차원) 0,1 로만 구성된 벡터로 표현함으로써 그 크기를 모두 동일하게 하는 방법이다.

[참고] 숫자 크기가 주요한 역할을 하는 Linear Regressor 등에서는 중요하지만, 트리 계열 모델에서는 Label-Encoding으로 충분하다.

X_features_ohe = pd.get_dummies(DataFrame, columns=['year', 'month', 
'weather','weekend', 'season', "hour", 'holiday', 'workingday'])

위와 같이 pd.get_dummies(데이터프레임, columns = [원핫 인코딩을 원하는 column명])을 통해 할 수 있다.

2) 정규화(Normalization)

비슷한 맥락에서, 숫자형 데이터들의 크기가 불필요하게 영향을 미쳐 학습 성능이 떨어지거나 과적합이 발생할 가능성이 있다. 이를 방지하기 위한 두 가지 방법이 정규화와 표준화다.

정규화는 sklearn.preprocessing 안의 MinMaxScaler를 통해 수행할 수 있다.

MinMaxScaler의 변환 방법은 다음과 같다.

최대, 최소값을 이용해 모든 데이터를 0과 1사이의 값으로 변경한다. 간단한 예시는 아래와 같다.

from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import StandardScaler
import numpy as np

train = np.array([[1,2,3,4,5],[2,4,6,7,10]])
test = np.array([[-1,21,32,55,89],[11,18,29,37,39]])

scaler = MinMaxScaler()
scaler.fit(train)
scaler.transform(test)

train 데이터로 학습한 것을 바탕으로 test 데이터를 scaling한 결과다. 학습데이터와 테스트데이터를 원본데이터에서 나누어 사용하는 상황이라면, 가급적 나누기 이전에 scaling 한 뒤에 나누는 것이 좋다. 학습데이터와 테스트데이터가 본래 나누어져 있다면, 학습데이터에서 fit한 scaler를 그대로 테스트 데이터에 적용해야 한다.(테스트 데이터에서 별도로 scaling을 진행하면 안됨)

보통의 경우 위의 train/test 자리에 DataFrame 혹은 그 일부를 직접 넣어주게 된다.

3) 표준화(Normalization)

정규화는 sklearn.preprocessing 안의 StandardScaler를 통해 수행할 수 있다.

StandardScaler의 변환 방법은 다음과 같다.

데이터를 평균이 0, 분산이 1인 가우시안 정규분포를 가지도록 변환한다. 가우시안 정규분포를 가정하는 모델인 서포트벡터머신(SVM), 선형회귀(Linear Regressor), 로지스틱회귀(Logistic Regressor) 등에서 반드시 수행해야 하는 과정이다.

절차는 위와 거의 동일하다.

from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import StandardScaler
import numpy as np

train = np.array([[1,2,3,4,5],[2,4,6,7,10]])
test = np.array([[-1,21,32,55,89],[11,18,29,37,39]])

scaler = StandardScaler()
scaler.fit(train)
scaler.transform(test)

[참고]

MinMaxScaler는 내부적으로 활용한 샘플의 수, 데이터의 최대/최소의 값, 변환한 값의 범위 등을 반환한다. 이를 다음과 같이 확인할 수 있다.

print("샘플 수(row의 개수):", scaler.n_samples_seen_, "\n", 
"data의 최댓값(각 column의 최댓값):", scaler.data_max_, "\n",
"data의 최솟값(각 column의 최솟값):",scaler.data_min_, "\n", 
"변환된 값의 범위:", scaler.feature_range)

한 번 학습시킨 scaler에 대해, 다른 데이터로 추가 학습시키고 싶은 경우 partial_fit()을 이용할 수 있다. 아래와 같이 달라진 결과를 확인할 수 있다.

scaler.partial_fit(test)
scaler.transform(test)

print("샘플 수(row의 개수):", scaler.n_samples_seen_, "\n", 
"data의 최댓값(각 column의 최댓값):", scaler.data_max_, "\n",
"data의 최솟값(각 column의 최솟값):",scaler.data_min_, "\n", 
"변환된 값의 범위:", scaler.feature_range)

728x90
반응형