Post

2.3 데이터 정규화

2.3 데이터 정규화


1. Feature Scaling

feature scaling 이란 서로 다른 피처 값의 범위 (최댓값 - 최소값)가 일치하도록 조정하는 작업을 말한다. 값의 범위가 데이터마다 다르면 모델 훈련이 제대로 안될 수 있기 때문이다.

[!] 단, 트리 기반 모델(랜덤 포레스트, XGBoost, LightGBM 등)은 피처 스케일링이 필요 없다. 트리 기반 모델은 데이터의 크기 보다는 대소 관계에 영향을 받기 때문이다. 피처 스케일링을 하더라도 대소 관계에는 변함이 없다.

이름키(m)몸무게(kg)옷 사이즈
광일1.775L
혜성1.555S
덕수1.860< ? >

직관적으로 보면 덕수의 옷 사이즈는 L일 것이다. 머신러닝 모델을 이를 어떻게 예측할까?

간단하게 키와 몸무게를 더하는 방법이 있다. 더한 값이 광일이와 가까우면 L, 혜성이와 가까우면 S로 예측할 것이다.

  • 광일 : 1.7 + 75 = 76.7
  • 혜성 : 1.5 + 55 = 56.5
  • 덕수 : 1.8 + 60 = 61.8

즉 덕수의 키와 몸무게의 합(61.8)은 광일(76.7)보다 혜성(56.5)에 가깝기 때문에 머신러닝 모델은 덕수의 옷 사이즈를 S로 예측할 것이다. 잘못 예측한 결과이다. 이는 키와 몸무게의 범위가 서로 다르기 때문이다. 키의 최댓값(1.8)과 최솟값(1.5)차이는 0.3 이지만 몸무게의 최댓값(75)과 최솟값(55) 차이는 20이다.

따라서 오류를 개선하기 위해서는 키와 몸무게 값의 범위를 같은 수준으로 맞춰야 한다. 이때 필요한 기법이 피처 스케일링이다.



1.1 min-max 정규화

min-max 정규화 는 feature 값의 범위를 0 ~ 1로 조정하는 기법이다. 조정 후 최솟값은 0, 최댓값은 1이 된다.


\[x_{scaled} = {x - x_{min} \over x_{max} - x_{min}}\]


이름min-max 정규화한 키min-max 정규화한 몸무게키 + 몸무게
광일(1.7 - 1.5) / (1.8 - 1.5) = 0.67(75 - 55) / (75 - 55) = 11.67
혜성(1.5 - 1.5) / (1.8 - 1.5) = 0(55 - 55) / (75 - 55) = 00
덕수(1.8 - 1.5) / (1.8 - 1.5) = 1(60 - 55) / (75 - 55) = 0.251.25

덕수의 키와 몸무게 합은 1.25이다. 혜성보다 광일이에 가까워졌으므로 덕수의 옷 사이즈는 L이라고 예측할 수 있다.

[!] 이상치(대부분의 값과 동떨어진 값) 가 너무 크거나 작을 때는 min-max 정규화가 좋지 않은 결과를 낼 수 있다. min-max 정규화 후에 이상치는 0 또는 1이 되겠지만 나머지 값들은 아주 미세한 차이로 좁은 구간에 몰려있게 된다. 따라서 이상치가 너무 크거나 작을 땐 표준화(standardization) 이 더 바람직하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
import pandas as pd 

height_weight_dict = {'':[1.7, 1.5, 1.8], '몸무게':[75, 55, 60]}
df = pd.DataFrame(height_weight_dict, index = ['광일', '혜성', '덕수'])

print(df)

'''
      키  몸무게
광일  1.7   75
혜성  1.5   55
덕수  1.8   60
'''
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()

scaler.fit(df)
df_scaler = scaler.transform(df)

print(df_scaler)

'''
[[0.66666667 1.        ]
 [0.         0.        ]
 [1.         0.25      ]]
'''


fit() 과 transform() vs fit_transform()

fit() 과 transform()은 fit_transform()으로 한번에 실행할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
scaler = MinMaxScaler()

df_scaler = scaler.fit_transform(df)

print(df_scaler)

'''
[[0.66666667 1.        ]
 [0.         0.        ]
 [1.         0.25      ]]
'''

두 함수를 나눠놓은 이유는 데이터 하나에만 min-max 정규화를 적용할 때는 fit_transform()을 쓰는데 더 편리하지만 한 데이터에 맞춰 놓은 스케일링 범위를 다른 데이터에도 적용하려면 fit()과 transform()을 따로 써야 한다.

1
2
3
4
5
6
scaler = MinMaxScaler()

scaler.fit(df)
df_scaled = scaler.transform(df)
df2_scaled = scaler.transform(df2)
df3_scaled = scaler.transform(df3)



1.2 표준화

표준화 (standardization)는 평균이 0, 분산이 1이 되도록 feature 값을 조정하는 기법이다. min-max 정규화와 다르게 표준화는 상한과 하한이 없다. 상한, 하한을 따로 정해야 하는 경우가 아니라면 표준화를 적용할 수 있다.

[!] 정규분포를 따르는 데이터는 표준화 스케일링을 적용하는 것이 좋다.

\(x_{scaled} = {x - \hat{x} \over \sigma}\) $\hat{x}$ 는 평균 , $\sigma$ 는 표준편차를 의미한다.

1
2
3
4
5
6
7
8
9
10
11
12
from sklearn import StandardScaler

scaler = StandardScaler()

df_scaled = scaler.fit_transform(df)
print(df_scaled)

'''
[[ 0.26726124  1.37281295]
 [-1.33630621 -0.98058068]
 [ 1.06904497 -0.39223227]]
'''
This post is licensed under CC BY 4.0 by the author.