[머신러닝] 피처 스케일링 (Feature Scaling) - 표준화 (standardization) , 정규화 (normalization)

김죠·2023년 5월 8일
0

머신러닝

목록 보기
6/9
  • ✔ Feature Scaling 이란?

    • 서로 다른 변수의 값 범위를 일정한 수준으로 맞추는 작업

    • 표준화 , 정규화 방법 존재

    • 2차원 이상 데이터만 가능


  • ✔ 왜 Feature Scaling 이 필요할까?

    데이터를 평가하는 기준을 설정하고, 그 기준 내에서 데이터를 평가하여 비교가 편하게 하기 위함이다.
    예를 들어, 온도, 습도, 날씨 등은 °\degreeC, °\degreeF 등으로 나타낸다. 이는 단위도 다르고 범위도 달라서 직접적인 비교가 불가능하다. 나의 영어 성적이 95점 (100점 만점), 친구의 성적이 500점 (990점 만점) 일 때, 내가 공부를 더 잘 한다고 말할 수 없는 것과 유사하다.
    따라서, 각 특성들의 단위를 무시하고, 단순 값으로 비교할 수 있게 만들어 주어야 한다. 이것이 우리가 Feature Scaling (표준화/정규화)를 하는 이유이다.
    또 하나의 중요한 이유는, scale의 범위가 너무 크면 노이즈 데이터가 생성되거나 overfitting이 일어날 가능성이 높아지기 때문이다.


  • 표준화

    • 데이터의 feature 각각 평균이 0, 분산이 1인 정규분포를 가진 값으로 변환한다. 즉, 피처가 표준정규분포의 속성을 갖도록 조정되는 것이다.

      표준화를 식으로 나타내면 다음과 같다.

      SVM, Linear Regression, Logistic Regression은 데이터가 정규 분포를 이룬다 가정하고 구현되었기 때문에, 사전에 표준화를 적용하는 것은 성능 향상에 중요한 요소가 될 수 있다. 왜냐하면, 표준화는 피처가 정규분포인 경우 유용하기 때문이다.

      transform( ) 시, 스케일 변환된 데이터가 ndarray로 변환되기에, 이를 DataFrame으로 변환이 필요하다.

      표준화를 사용하기 위한 코드는 StandardScaler( )를 사용하는데, 다음과 같다.

from sklearn.datasets import load_iris
import pandas as pd

#붓꽃 데이터 세트를 로딩하고 DataFrame을 변환
iris = load_iris()
iris_data = iris.data
iris_df = pd.DataFrame(iris_data, columns = iris.feature_names)

from sklearn.preprocessing import StandardScaler

# StandardScaler 객체 생성
scaler = StandardScaler()

# StandardScaler로 데이터 세트 변환 -> fit(), transform()
scaler.fit(iris_data)
iris_scaled = scaler.transform(iris_data)

# transform()시 스케일 변환된 데이터 세트가 numpy ndarray로 반환돼 
# 이를 DataFrame으로 변환 필요
iris_df_scaled = pd.DataFrame(iris_scaled, columns = iris.feature_names)

print('feature들의 평균:\n', iris_df_scaled.mean())
print('\nfeature들의 분산:\n', iris_df_scaled.var())

feature들의 평균:
sepal length (cm) -1.690315e-15
sepal width (cm) -1.842970e-15
petal length (cm) -1.698641e-15
petal width (cm) -1.409243e-15
dtype: float64 \\
feature들의 분산:
sepal length (cm) 1.006711
sepal width (cm) 1.006711
petal length (cm) 1.006711
petal width (cm) 1.006711
dtype: float64

각 feature 의 평균이 0, 분산이 1에 가까운 모습이다.


  • 정규화

    • 데이터의 크기를 모두 똑같은 단위로 변경해준다. 모든 값을 0 ~ 1 사이의 값으로 변환한다. (음수가 있을 경우 -1 ~ 1 사이로 변환)
      머신러닝에서 scale 이 큰 피처의 영향이 비대해지는 것을 방지해준다. 정규화 중 제일 많이 쓰이는 Min-Max Scaling 을 식으로 나타내면 다음과 같다.


      표준화와 마찬가지로, transform( ) 시, 스케일 변환된 데이터가 ndarray로 변환되기 때문에, 이를 DataFrame으로 변환시켜줘야 한다.
      정규화를 사용하기 위한 코드는 MinMaxScaler( )를 사용하는데, 다음과 같다.

from sklearn.preprocessing import MinMaxScaler

# MinMaxScaler 객체 생성
scaler = MinMaxScaler()

# MinMaxScaler로 데이터 세트 변환 -> fit(), transform()
scaler.fit(iris_data)
iris_scaled = scaler.transform(iris_data)

# transfrom() 시 스케일 변환된 데이터 세트가 numpy ndarray로 반환돼
# 이를 DataFrame으로 변환 필요
iris_df_scaled = pd.DataFrame(iris_scaled, columns = iris.feature_names)

print('feature들의 최솟값 :\n', iris_df_scaled.min())
print('\nfeature들의 최댓값 :\n', iris_df_scaled.max())

feature들의 최솟값 :
sepal length (cm) 0.0
sepal width (cm) 0.0
petal length (cm) 0.0
petal width (cm) 0.0
dtype: float64 \\
feature들의 최댓값 :
sepal length (cm) 1.0
sepal width (cm) 1.0
petal length (cm) 1.0
petal width (cm) 1.0
dtype: float64

  • ✔ Feature Scaling 시 유의점

    train data로 fit & transform 적용 시, test data로 fit을 적용하지 않고 train data로 fit 한 결과를 이용하여 test data를 transform 해야한다.
    그렇지 않을 시, train, test data의 scaling 기준 정보다 서로 달라지기 때문에 올바른 예측이 불가능하다. (e.g. train에서 (0, 1, 2, 3, 4, 5) \rightarrow (0.0, 0.2, 0.4, 0.6, 0.8, 1.0) 으로 변환하였는데, test를 (0, 2, 4) \rightarrow (0.0, 0.5, 1.0) 으로 잘못 변환될 수 있음)

    따라서, 가능하다면 전체 데이터를 scaling 후, train/test 로 분리하는 것이 좋다. 만약 이것이 여의치 않다면, test 데이터 변환 시 fit 을 적용하지 않고, train 으로 fit 된 scaler 객체를 이용하여 test 를 transform 하여야 한다.

  • ✔ 그렇다면, 언제 표준화를 하고 언제 정규화를 해야 하는지?

    일반적으로, scaling 은 개별 피처에서 비대칭 되었거나, 서로 다른 피처간에 단위가 극명하게 차이날 때 적용한다.
    보통, 정규화는 데이터가 정규 분포를 따르지 않을 때 사용하는 것이 유용하며, 표준화는 데이터가 정규 분포를 따를 때 사용하는 것이 유용하다.

    그러나, tree 기반 모델에서는 scaling 효과가 거의 미미하다. tree 기반 모델은 변수의 크기에 민감하지 않기 때문이다. 따라서, 선형 계열 (Linear Regression, Logistic Regression, SVM 등), 딥러닝 등을 적용할 때 scaling 을 고려하는 것이 좋다. (딥러닝 시에는 비교적 큰 값을 가지면 상대적으로 최적화하기 어렵기 때문이다.)

    하지만, ML 알고리즘이 개선되면서, scaling 효과가 생각보다 크지 않은 경우가 많다. 게다가, 선형 계열에서 조차 scaling 을 적용했을 때 성능이 향상되지 못할 수도 있다.
    따라서, scaling 적용 전 후 결과로 판단해야 한다. (어떤 분포에 어떤 scaling 을 적용하면 좋다는 공식은 존재하지 않는다.)

    이에 대한 내용은 다음 글을 참고하였다.

    https://www.inflearn.com/questions/65387/%EC%A0%95%EA%B7%9C%ED%99%94-%ED%91%9C%EC%A4%80%ED%99%94-%EC%A7%88%EB%AC%B8%EB%93%9C%EB%A6%BD%EB%8B%88%EB%8B%A4

0개의 댓글