서로 다른 변수의 값 범위를 일정한 수준으로 맞추는 작업을 피처 스케일(feature scaling)이라고 한다. 대표적인 방법으로 표준화(Standardization)와 정규화(Normalization)가 있다.
표준화는 데이터의 피처 각각이 평균이 0이고 분산이 1인 가우시안 정규분포를 가진 값으로 변환하는것을 의미한다.
정규화는 서로 다른 피처의 크기를 통일하기 위해 크기를 변환해주는 개념이다. 예를들어 초등학교의 개수는 1개, 2개, 3개 의 단위이지만 초등학교 거리는 400m, 600m, 1km 으로 구성되어있따. 이 변수를 모두 동일한 크기 단위로 비교하기 위해 값을 모두 0과 1사이(음수가 있을경우 -1과 1사이)의 값으로 변환하는 것이다.
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으로 변환해 확인 할 수 있다.
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()만 시켜주는것이 올바른 형태이다.
데이터를 회귀 분석에 사용하기 위해서는 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)
...
데이터를 회귀 분석에 사용하기 위해서는 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)
...