[사이킷런] 데이터 스케일링
07 Feb 2020
Reading time ~3 minutes
머신러닝, 딥러닝 모델 알고리즘에서 숫자형의 데이터도 변환을 통해 모델이 더 효과적으로 학습하도록 할 수 있습니다.
이번 포스팅에서는 사이킷런에서 이런 데이터 전처리 작업을 위해 제공하고 있는 스케일링에 대해 알아보겠습니다.
피처 스케일링
피처스케일링(Feature Scaling)
은 서로 다른 변수의 값 범위를 일정한 수준으로 맞추는 작업입니다. 대표적으로 표준화, 정규화가 있습니다. 데이터의 특정 값이 너무 크거나 작은 경우에는 모델이 학습과정에서 그 값(아웃라이어)에 대해 치우쳐 잘못 학습할 수 있습니다. 때문에 스케일링은 중요한 전처리 작업입니다.
(1) StandardScaler - 표준화
표준화는 데이터 피처의 각각의 평균이 0이고 분산이 1인 정규분포를 가진 값으로 변환하는 것입니다. 변수 값을 표준화시키는 식은 아래와 같습니다.
사이킷런에서는 StandardScaler()
클래스를 통해 개별 피처를 평균이 0, 분산은 1이 되도록 변환할 수 있습니다. 선형회귀, 로지스틱 회귀, RBF커널을 이용하는 서포트 벡터머신에서는 데이터가 정규분포(가우시안분포)를 가지고 있다고 가정하고 구현했기 때문에, 사전에 표준화를 적용하는 것은 성능 향상에 중요한 요소입니다.
사이킷런의 예제 붓꽃 데이터 세트를 사용하여 표준화를 적용해보겠습니다.
# 예제 붓꽃 데이터 세트 불러오기
from sklearn.datasets import load_iris
import pandas as pd
iris = load_iris()
iris_data = iris.data
iris_df = pd.DataFrame(data = iris_data, columns = iris.feature_names)
iris_df.head()
sepal length (cm) | sepal width (cm) | petal length (cm) | petal width (cm) | |
---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 |
1 | 4.9 | 3.0 | 1.4 | 0.2 |
2 | 4.7 | 3.2 | 1.3 | 0.2 |
3 | 4.6 | 3.1 | 1.5 | 0.2 |
4 | 5.0 | 3.6 | 1.4 | 0.2 |
print('feature들의 평균: ')
print(iris_df.mean())
print('\nfeature들의 분산: ')
print(iris_df.var())
# 출력:
feature들의 평균:
sepal length (cm) 5.843333
sepal width (cm) 3.057333
petal length (cm) 3.758000
petal width (cm) 1.199333
dtype: float64
feature들의 분산:
sepal length (cm) 0.685694
sepal width (cm) 0.189979
petal length (cm) 3.116278
petal width (cm) 0.581006
dtype: float64
# StandardScaler를 이용하여 피처 표준화
from sklearn.preprocessing import StandardScaler
# scaler 객체 생성
scaler = StandardScaler()
# 데이터 변환
scaler.fit(iris_df)
iris_scaled = scaler.transform(iris_df)
# transform()을 사용한 반환 값은 넘파이 어레이로 반환되기 때문에 데이터 프레임으로 형식 변환
iris_df_scaled = pd.DataFrame(data = iris_scaled, columns = iris.feature_names)
iris_df_scaled.head()
sepal length (cm) | sepal width (cm) | petal length (cm) | petal width (cm) | |
---|---|---|---|---|
0 | -0.900681 | 1.019004 | -1.340227 | -1.315444 |
1 | -1.143017 | -0.131979 | -1.340227 | -1.315444 |
2 | -1.385353 | 0.328414 | -1.397064 | -1.315444 |
3 | -1.506521 | 0.098217 | -1.283389 | -1.315444 |
4 | -1.021849 | 1.249201 | -1.340227 | -1.315444 |
print('feature들의 평균값: ')
print(iris_df_scaled.mean())
print('\nfeature들의 분산값: ')
print(iris_df_scaled.var())
# 출력:
변환된 feature들의 평균값:
sepal length (cm) -1.690315e-15
sepal width (cm) -1.842970e-15
petal length (cm) -1.698641e-15
petal width (cm) -1.409243e-15
dtype: float64
변환된 feature들의 분산값:
sepal length (cm) 1.006711
sepal width (cm) 1.006711
petal length (cm) 1.006711
petal width (cm) 1.006711
dtype: float64
StandardScaler를 사용하여 변환환 결과 모든 피처들이 평균은 0, 분산은 1에 가깝게 변환되었습니다.
(2) MinMaxScaler
피처 값을 0과 1 사이의 범위 값으로 변환합니다. 이 MinMaxScaler
는 의 분포가 가우시안 분포가 아닐 경우에 적용해 볼 수 있는 방법입니다. 변수를 스케일링하는 식은 아래와 같습니다.
역시 사이킷런의 예제 붓꽃 데이터 세트를 사용하여 표준화를 적용해보겠습니다.
from sklearn.preprocessing import MinMaxScaler
# MinMaxScaler 객체 생성
scaler = MinMaxScaler()
# MinMaxScaler로 데이터 세트 변환
scaler.fit(iris_df)
iris_scaled = scaler.transform(iris_df)
# transform() 변환시 스케일 변환된 데이터세트가 Numpy ndarray로 반환되 이를 데이터 프레임으로 변환
iris_df_minmax = pd.DataFrame(data=iris_scaled, columns = iris.feature_names)
iris_df_minmax.head()
sepal length (cm) | sepal width (cm) | petal length (cm) | petal width (cm) | |
---|---|---|---|---|
0 | 0.222222 | 0.625000 | 0.067797 | 0.041667 |
1 | 0.166667 | 0.416667 | 0.067797 | 0.041667 |
2 | 0.111111 | 0.500000 | 0.050847 | 0.041667 |
3 | 0.083333 | 0.458333 | 0.084746 | 0.041667 |
4 | 0.194444 | 0.666667 | 0.067797 | 0.041667`` |
print('변환된 feature들의 최소값: ')
print(iris_df_minmax.min())
print('\n변환된 feature들의 최대값: ')
print(iris_df_minmax.max())
# 출력:
변환된 feature들의 최소값:
sepal length (cm) 0.0
sepal width (cm) 0.0
petal length (cm) 0.0
petal width (cm) 0.0
dtype: float64
변환된 feature들의 최대값:
sepal length (cm) 1.0
sepal width (cm) 1.0
petal length (cm) 1.0
petal width (cm) 1.0
dtype: float64
MinMaxScaler를 사용하여 변환환 결과 모든 피처들이 평균은 0, 분산은 1에 가깝게 변환되었습니다.
Reference
- 파이썬 머신러닝 완벽가이드