『파이썬 머신러닝 완벽 가이드』 도서를 공부하며 정리한 글입니다.
코드 결과는 직접 실행해보면서 결과를 보시면 좋을 것이라 생각하여 생략하였습니다.
이번 글에서는 피처 스케일링(feature scaling)의 대표적인 방법인 표준화(Standardization)와 정규화(Normalization)에 대해 소개하겠다.
피처 스케일링은 서로 다른 변수(feature)의 값 범위를 일정한 수준으로 맞추는 작업이다.
예를 들어서, 어떤 feature는 -1부터 1 사이의 값으로 구성되어 있고, 다른 feature는 0부터 100 사이의 값으로 구성되어 있는 경우이다.
- 서로 다른 범위의 변수들을 평균이 0이고 분산이 1인 (가우시안) 정규 분포를 가진 값으로 변환하는 것이 표준화이다.
- 서로 다른 범위의 변수들의 크기를 통일하기위해 크기를 (일반적으로 [0,1]로) 변환하는 것이 정규화이다.
1. 표준화
Xi_new = ( Xi - mean(X) ) / stdev(X)
공식은 원래의 값 Xi에서 피처 X의 평균을 뺀 값을 피처 X의 표준편차로 나누는 것이다.
2. 정규화
표준화는 평균이 0이고 분산이 1인 정규분포를 가지는 값으로 변환해주는 반면,
정규화는 실제 값의 범위를 표준 값 범위(일반적으로 [-1,+1] 또는 [0,1])로 변환하는 것을 의미한다.
즉, (후자일 경우) 최솟값이 0, 최댓값이 1인 셈으로, 개별 데이터의 크기가 모두 같은 단위로 변경된 것이다.
Xi_new = ( Xi - min(X) ) / ( max(X) - min(X) )
그런데, 정규화에는 선형대수 개념의 정규화와 일반적인 정규화(위의 공식) 간의 약간의 차이가 있다.
- 선형대수 개념의 정규화 : 개별 벡터를 모든 피처 벡터 크기의 합으로 나눠주는 것.
Xi_new = Xi / (Xi^2 + Yi^2 + Zi^2)
해당 선형대수 개념의 정규화는 사이킷런의 Normalizer 모듈에 적용된 것이다. (개별 벡터의 크기를 맞추고자 변환하는 것!)
헷갈림을 방지하고자 일반적인 의미의 표준화와 정규화를 피처 스케일링이라 하고,
선형대수 개념의 정규화를 벡터 정규화로 지칭하겠다.
3. 사이킷런의 피처 스케일링 클래스
이제 사이킷런에서 제공하는 대표적인 피처 스케일링 클래스 StandardScaler와 MinMaxScaler에 대해 알아보겠다.
StandardScaler는 표준화를 쉽게 지원하는 클래스 (평균 0, 분산 1) 이고,
MinMaxScaler는 정규화를 지원하는 클래스 (데이터 값을 0과 1사이의 범위값으로 변환) 이다.
(1) StandardScaler
- 가우시안 정규 분포를 가질 수 있도록 데이터를 변환하는 것은 몇몇 알고리즘에서 매우 중요하다.
- 아래의 알고리즘은 데이터가 가우시안 분포를 가지고 있다고 가정하고 구현되었기 때문에 표준화가 예측 성능 향상에 중요한 요소가 된다.
- 사이킷런에서 구현한 RBF 커널을 이용하는 서포트 벡터 머신 (Support Vector Machine)
- 선형 회귀 (Linear Regression)
- 로지스틱 회귀 (Logistic Regression)
- StandardScaler를 이용해서 한번에 표준화해 변환할 수 있다.
1. StandardScaler 객체 생성
2. fit()과 transform() 메서드 이용하여 변환
- fit() : 데이터 변환을 위한 기준 정보 설정. ex) 데이터셋의 최댓값/최솟값 설정 등..
- transform() : fit()을 통해 설정된 정보를 이용해서 데이터를 변환.
from sklearn.preprocessing import StandardScaler
## 1.
scaler = StandardScaler()
## 2.
scaler.fit(df)
df_sclaed = scaler.transform(df)
모든 칼럼 값의 평균이 0에 아주 가까운 값으로, 분산은 1에 아주 가까운 값으로 변환된다.
(2) MinMaxScaler
- 데이터의 분포가 가우시안 분포가 아닐 경우에는 Min, Max Scale을 적용해 볼 수 있다.
- 일반적으로 데이터값을 0과 1사이의 범위 값으로 변환하는데, 원본 데이터값에 음수가 있을 경우 -1에서 1값으로 변환한다.
- MinMaxScaler 를 이용해서 정규화한다.
from sklearn.preprocessing import MinMaxScaler
## 1.
# MinmaxScaler 객체에 별도의 feature_range 파라미터 값을 지정하지 않으면 0~1 값으로 변환된다.
scaler = MinMaxScaler()
## 2.
scaler.fit(df)
df_scaled = scaler.transoform(df)
2번에서 fit과 transform을 합쳐 한번에 적용할 수 있는 메서드로, fit_transform()이 있다.
유의할 점은 test set에 대해서 스케일링을 할 때에는 transform() 만 해주면 된다는 것이다. 즉, train set에 대해서 fit()한 Scaler 객체를 이용해서 test set을 변환해주면 된다는 것이다.
이유는?
학습데이터로 fit()이 적용된 스케일링 기준 정보를 그대로 test data에 적용해야하며,
그렇지 않고 (fit()을 이용하여) test data로 다시 새로운 스케일링 기준 정보를 만들게 되면
train data와 test data의 스케일링 기준 정보가 서로 달라지기 때문에 올바른 예측 결과를 도출하지 못할 수 있다.
예를 들자면,
train data가 0부터 10까지의 데이터이고, test data가 0부터 5까지의 데이터일 때
만약 각각, fit()과 transform() 메서드를 적용하여 변환시킨다면
train data에는 최솟값 0, 최댓값 10이 설정되어 1/10 Scale이 적용되기 때문에
1은 0.1로, 2는 0.2, 그리고 5는 0.5, 10은 1로 변환.
test data에는 최솟값 0, 최댓값 5가 설정되어
1은 0.2로, 2는 0.4, 그리고 5는 1로 변환.
train data에서는 2가 0.2로 변환됐고, 10이 1로 변환됐기 때문에 이렇게 되면, train data와 test data의 서로 다른 원본값이 동일한 값으로 변환되는 결과를 초래한다.
그렇기 때문에, test data에 다시 fit()을 적용해서는 안되며, train data로 이미 fit()이 적용된 Scaler 객체를 이용해 transform()으로 변환해야 한다.
이러한 주의사항이 있으므로, 차라리 처음부터 train과 test data set으로 분리하기 전에, 먼저 전체 데이터 세트에 스케일링을 적용한 뒤, train과 test data set으로 분리하는 것을 추천한다.
* 해당 유의사항은 앞으로 나올 (사이킷런 기반의) PCA와 같은 차원 축소 변환이나 텍스트의 피처 벡터화 변환 작업 시에도 동일하게 적용된다.
'지식 > Machine Learning' 카테고리의 다른 글
단순회귀, 다중회귀, 다항회귀 (0) | 2021.05.23 |
---|---|
데이터 전처리 (1) (0) | 2021.04.09 |
교차 검증 (0) | 2021.04.08 |
ndarray, 리스트, 딕셔너리와 DataFrame 상호 변환하기 (0) | 2021.03.28 |
K-NN 알고리즘의 쉬운 예제 (0) | 2021.03.16 |