-목차-
구현 코드 : Feature_Scaling
1. 표준화(Standardization), 정규화(Normalization)란?
머신러닝은 데이터를 가지고 학습한다. 그런데 데이터의 각 피처는 단위도 다르고 각 피처간 값의 범위도 꽤 차이가 있다. 각 피처의 단위가 다르고 범위가 다르면 제대로 값을 비교할 수 없다. 특히 선형 회귀 문제애서 매우 큰 값을 가지는 피처는 모델의 가중치가 편향 되거나 학습시간이 오래 걸리는 문제를 야기한다. 이러한 문제를 해결하기 위해 서로 다른 변수의 값 범위를 일정한 수준으로 맞추는 작업을 피처 스케일링(feature scaling)이라고 한다. 대표적인 방법으로는 표준화(Standardization)와 정규화(Normalization)이 있다.
표준화와 정규화의 개념과 사이킷런(scikit-learn)에서 제공하는 표준화 정규화 모듈을 알아보자.
1.1 표준화
표준화는 데이터의 피처 각각이 평균이 0이고 분산이 1인 가우시안 정규 분포를 가진 값으로 변환하는 것을 의미한다.
표중화를 통해 변환될 피처 \(x\)의 새로운 \(i\)번째 데이터를 \(x_i\underline{\,}new \)라고 할때 표준화 식은 아래와 같다.
\[x_i\underline{\,}new = \frac{x_i-mean(x)}{stdev(x)}\]
1.2 정규화
일반적으로 정규화는 서로 다른 피처의 크기를 통일하기 위해 크기를 변환해주는 개념이다.
예를 들어 피처 A는 거리를 나타내는 변수로서 값이 0 ~ 100KM로 주어지고 피처 B는 금액을 나타내는 속성으로 값이 0 ~ 100,000,000,000원으로 주어진다면 이 변수를 모두 동일한 크기 단위로 비교하기 위해 값을 모두 최소 0~최대 1의 값으로 변환하는 것이다.
새로운 데이터 \(x_i\underline{\,}new \)는 아래 식으로 변환된다.
\[x_i\underline{\,}new = \frac{x_i-min(x)}{max(x)-min(x)}\]
여기서 주의해야 할 점이 있다. Python의 사이킷런의 전처리에서 제공하는 Normalizer모듈은 위에서 설명한 일반적인 정규화 와는 약간의 차이가 있다. 사이킷런의 Normalizer 모듈은 선형대수에서의 정규화 개념이 적용되었으며 개별 벡터의 크기를 정규화 하는것을 의미한다. 예를 들어 세 개의 피처 \(x\), \(y\), \(z\)가 있고 새로운 데이터를 \(x_i\underline{\,}new \)라고 할때 수식으로 표현 하면 아래와 같다.
\[x_i\underline{\,}new = \frac{x_i}{\sqrt{x_i^2+y_i^2+z_i^2}}\]
2. StandardScaler
사이킷런에서 제공되는 StandardScaler는 앞서 설명한 표준화를 쉽게 지원하기 위한 클래스이다. 즉, 개별 피처를 평균이 0, 분산이 1인 값으로 변환한다.
이렇게 사우시안 정규 분포를 가질 수 있도록 데이터를 변환 하는 것은 몇몇 알고리즘에서 매우 중요하다.
특히 사이킷런에서 구현한 RBF 커널을 이용하는 서포트 벡터 머신(Support Vector Machine) 이나 선형 회귀(Linear Regression), 로지스틱 회귀(Logistic Regression)는 데이터가 가우시안 분포를 가지고 있다고 가정하고 구현 됐기 때문에 사전에 표준화를 적용하는 것을 예측 성능 향상에 중요한 요소가 될 수 있다.
예제 코드
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_iris
import pandas as pd
# 붓꽃 데이터 셋을 로딩하고 DataFrame으로 변환합니다.
iris = load_iris()
iris_data = iris.data
iris_df = pd.DataFrame(data=iris_data, columns=iris.feature_names)
# StandardScaler객체 생성
scaler = StandardScaler()
# StandardScaler 로 데이터 셋 변환. fit( ) 과 transform( ) 호출.
scaler.fit(iris_df)
iris_scaled = scaler.transform(iris_df)
#transform( )시 scale 변환된 데이터 셋이 numpy ndarry로 반환되어 이를 DataFrame으로 변환
iris_df_scaled = pd.DataFrame(data=iris_scaled, columns=iris.feature_names)
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
모든 피처의 값이 평군이 0에 아주 가까운 값으로, 그리고 분산은 1에 아주 가까운 값으로 변환됐음을 알 수 있다.
3. MinMaxScaler
다음으로 사이킷런 에서 제공하는 MinMaxScaler에 대해 알아보자. MinMaxScaler는 데이터값을 0과 1사이의 범위 값으로 변환한다. 만약 음수 값이 있으면 -1 에서 1사이의 값으로 변환한다. 예제를 통해 어떻게 동작하는지 알아보자.
예제 코드
from sklearn.preprocessing import MinMaxScaler
# MinMaxScaler객체 생성
scaler = MinMaxScaler()
# MinMaxScaler 로 데이터 셋 변환. fit() 과 transform() 호출.
scaler.fit(iris_df)
iris_scaled = scaler.transform(iris_df)
# transform()시 scale 변환된 데이터 셋이 numpy ndarry로 반환되어 이를 DataFrame으로 변환
iris_df_scaled = pd.DataFrame(data=iris_scaled, columns=iris.feature_names)
print('feature들의 최소 값')
print(iris_df_scaled.min())
print('\nfeature들의 최대 값')
print(iris_df_scaled.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
모든 피처에 0에서 1사이의 값으로 변환되는 스케일링이 적용됐음을 알 수 있다.
참고 자료
'머신러닝, 딥러닝' 카테고리의 다른 글
고유값 분해(Eigen-Value Decomposition) (1) | 2022.02.28 |
---|---|
[ML] 평가 지표(Evaluation Metric) (0) | 2022.02.23 |
[ML] 교차 검증 (CV, Cross Validation) (0) | 2022.02.21 |
[DL] Cost Function (0) | 2022.02.15 |
[DL] 경사 하강법(Gradient Descent) (0) | 2022.02.04 |
댓글