피처 스케일링(StandardScaler,MinMaxScaler)

생각하는 마리오네트·2021년 6월 26일
0
post-custom-banner

피처 스케일링(표준화, 정규화)

  • 서로 다른 변수의 값 범위를 일정한 수준으로 맞추는 작업을 피처 스케일(feature scaling)이라고 한다. 대표적인 방법으로 표준화(Standardization)와 정규화(Normalization)가 있다.

  • 표준화는 데이터의 피처 각각이 평균이 0이고 분산이 1인 가우시안 정규분포를 가진 값으로 변환하는것을 의미한다.

  • 정규화는 서로 다른 피처의 크기를 통일하기 위해 크기를 변환해주는 개념이다. 예를들어 초등학교의 개수는 1개, 2개, 3개 의 단위이지만 초등학교 거리는 400m, 600m, 1km 으로 구성되어있따. 이 변수를 모두 동일한 크기 단위로 비교하기 위해 값을 모두 0과 1사이(음수가 있을경우 -1과 1사이)의 값으로 변환하는 것이다.

예외)

  • 사이킷런의 전처리에서 제공하는 Normalizer모듈과 차이가 있다.
  • 큰 개념은 같지만, 사이킷런의 경우 개별 벡터의 크기를 맞추기 위해 변환하는 것을 의미한다.

StandardScaler

  • StandardScaler는 앞에서 설명한 표준화를 쉽게 지원하기 위한 클래스이다. 즉, 개별 피처를 평균이 0이고, 분산이 1인 값으로 변환해 준다.

  • 이렇게 정규분포를 가질수 있게 데이터를 변환하는것은 특정 알고리즘에서는 매우 중요하다.

  • 서포트 벡터 머신(Support Vector Machine), 선형회귀(Linear Regression), 로지스틱 회귀(Logistic Regression)는 데이터가 정규분포를 가지고 있다고 가정하고 구현이 되기 때문에 사전 표준화는 예측 성능 향상에 중요한 요소가 될 수 있다.

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
df_scaled = scaler.fit_transform(df)
df_scaled_df = pd.DataFrame(df_scaled)

표준화를 하게 되면 데이터 세트가 넘파이의 ndarray이므로 DataFrame으로 변환해 확인 할 수 있다.

MinMaxScaler

  • 데이터를 0과 1사이의 범위값으로 변환하고 (만약 음수가 포함되어 있다면 -1,1 혹은 -1,0사이로 변환한다.)
  • 데이터의 분포가 정규분포를 따르지 않을 때 min,max scale을 적용해 볼 수 있다.
from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()
df_scaled = scaler.fit_transform(df)
df_sclaed_df = pd.DataFrame(df)

언제 어떤것을 사용해야할까??

  • 정규화의 경우 특이 치(극단 값)의 영향을 크게 받기 때문에 이럴경우 표준화를 시키는 것이 더좋다.

  • 정규분포가 아닐경우 표준화는 좋지 않다.

  • 표준화와 정규화중 어느것이 좋냐고 묻는다면 써봐야 안다라고 답할 수 있을것 같다. 위의 두문장의 경우는 경우에 맞게 사용하면되지만, 대부분 둘을 다 사용해 보고 더 좋은 성능을 가지는 것을 사용하는것이 좋다.

🙅‍♂️ 학습 데이터와 테스트 데이터 스케일링 변환 시 유의점

  • StandardScaler나 MinMaxScaler와 같은 Scaler객체를 이용해 데이터 스케일링 변환 시 fit(), transform(), fit_transform() 이 세가지 메소드를 이용하는데 매우 주의 해야할 점이 있다.

  • fit_transform()은 fit()과 transform()을 합친 메소드인데 train과 test데이터 둘다 fit_transform을 사용해서는 안된다.

  • 처음으로 돌아가서 fit()을 통해 입력하게 되면 인자로 준 데이터를 기준으로 스케일링 기준 정보가 입력이 된다.

  • 따라서 이후에 transform()을 하게되면 fit()에서 전달해준 기준 정보를 기반으로 변형을 시켜주는 원리이다.

  • 이를 한꺼번에 진행하는것이 fit_transform()인데 train데이터에 fit_transform()을 사용하고 test데이터에 fit_transform을 사용하게 되면 문제가 발생한다.

  • 첫번째 fit_transform에서 인자로 넣어준 train데이터를 통해 기준 정보를 입력하고 변형을 시켜주었는데 test데이터로 다시 fit_transform을 하게되면 해당 데이터로 다시 기준 정보를 입력받고 변형을 가해준다.

  • 우리가 알고있듯 train과 test는 데이터가 다르다!! 그렇기 때문에 각각의 데이터 기준정보로 변형해주면 의미가 없어진다... 서로 다른 기준에 따라서 각각의 데이터가 스케일링 되었기 때문이다.

  • 따라서 train데이터를 fit_transform()을 해주었으면, 이때 적용된 데이터 기반으로 test데이터를 transform()만 시켜주는것이 올바른 형태이다.

정리)

  • 가장좋은것은 데이터가 합쳐져있을때 스케일링하는것이고 분리가 되었다면 아래와같이 실행한다.
  • 테스트 데이터를 변환할 때 fit()이나 fit_transform()을 적용하지않고 학습데이터로 이미fit()된 scaler객체를 이용해서 transform()으로 변환만 한다.
profile
문제를해결하는도구로서의"데이터"
post-custom-banner

2개의 댓글

comment-user-thumbnail
2021년 7월 1일

데이터를 회귀 분석에 사용하기 위해서는 standardization을 거쳐야 하는데 만약 데이터 전체에 standardization을 거친 뒤 이를 train, test set으로 나눠주게 되면 standardization 과정에서 hold-out test set의 정보가 train set에 흘러 들어가 즉 data leakage가 발생하여 test set으로 모델의 performance를 제대로 확인할 수 없습니다. 이를 위해 standardization을 거치기 전에 데이터를 train/test으로 나누어 standardize를 train data와 test data에 따로 실행해줘야 합니다.
올바른 예시) scaler = MinMaxScaler()
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)
...

답글 달기
comment-user-thumbnail
2021년 7월 1일

데이터를 회귀 분석에 사용하기 위해서는 standardization을 거쳐야 하는데 만약 데이터 전체에 standardization을 거친 뒤 이를 train, test set으로 나눠주게 되면 standardization 과정에서 hold-out test set의 정보가 train set에 흘러 들어가 즉 data leakage가 발생하여 test set으로 모델의 performance를 제대로 확인할 수 없습니다. 이를 위해 standardization을 거치기 전에 데이터를 train/test으로 나누어 standardize를 train data와 test data에 따로 실행해줘야 합니다.
올바른 예시) scaler = MinMaxScaler()
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)
...

답글 달기