무효 클릭 IP 추적 중...
머신러닝,딥러닝/딥러닝

[scikit-learn]데이터를 scaling할때 왜 train 데이터의 값만 fit 하는걸까?

꼬예 2021. 12. 1.

많은 분들이 데이터 컬럼간 단위 차이가 클때 스케일링을 하시는데요.

 

아마 아래 코드와 같이 train데이터만 fit을 하고 나머지 데이터(validation, test data)는 그냥 transform만 하는 걸 많이들 보셨을 겁니다. 

왜 이렇게 해야할까요?

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
scaler.fit(train_data) 

train_data = scaler.transform(train_data)
val_data = scaler.transform(val_data)
test_data = scaler.transform(test_data)

 

 

간단하게 fit 과 transform 의 역할을 말씀 드리자면, fit은 데이터의 컬럼별로 평균과, 표준편차 값을 구하고 그 값을 저장했다가 transform에서 저장했던 값을 아래 공식과 같이 적용 해주신다고 보면 됩니다. 

다시 말해, train data에만 fit을 했다는것은 train data의 해당되는 평균값과 표준편차 를 이용해 다른 데이터에 적용한다는 말이 되겠죠?

 

valid 데이터는 valid 데이터의 평균과 표준편차를, test데이터는 test 데이터의 평균과 표준편차를 이용하면 왜 문제가 될까요?

아래 예시를 통해 문제가 되는 예시를 보여드리겠습니다.

 

 

[10, 20, 30] 으로 구성된 a의 평균과 표준편차를 구하고 이 값들을 가지고 스케일링을 해보았을때 아래와 같은 값이 출력이 됩니다.

import numpy as np

a = [10, 20, 30]
mean_a = np.mean(a) # a의 평균
std_a = np.std(a) # a의 표준편차
standard_a = np.round((a-mean_a)/std_a, 2)  #소수점을 줄이기위해 둘째자리에서 반올림
print(standard_a)

output :

스케일링 된 값의 평균과 표준편차를 확인해보면 우리가 원하는대로 평균은 0 , 표준편차는 1로 변경된것을 알 수 있습니다. 

 

우리의 머신러닝이 0.5 이하의 값들은 class 1로 분류하고, 그 이상의 값들은 class 2로 분류하는 모델이라고 가정해볼게요. 

그렇다면 [-1.22, 0. , 1.22] ==> [class 1, class1, class2]로 y값을 뱉어내겠죠?

 

또다른 예시를 볼게요.

아래 b는 a보다 훨씬 작은 5, 6, 7임에도 불구하고  스케일링을 적용했을때 값이 a의 스케일된 값과 같습니다.

import numpy as np

b = [5, 6, 7]
mean_b = np.mean(b) # b의 평균
std_b = np.std(b) # b의 표준편차
standard_b = np.round((b-mean_b)/std_b, 2)  #소수점을 줄이기위해 둘째자리에서 반올림
print(standard_b)

우리 모델은 스케일된 값을 기준으로 연산을 하기 때문에 마찬가지로, [class 1, class1, class2] 라는 답을 내놓게 되는거죠.

 

스케일 전 원래값이 이렇게나 차이가 나는데, 스케일된 값이 같다고 값은 값으로 분류한다.. 뭔가 이상한거 느끼셨나요?

output :

 

 

 

많은 초보분들이 위와 같은 실수를 많이 하니 주의 하시기 바랍니다.:)

  • 트위터 공유하기
  • 페이스북 공유하기
  • 카카오톡 공유하기
이 컨텐츠가 마음에 드셨다면 커피 한잔(후원) ☕

댓글