머신러닝

[머신러닝] 피처스케일링 - StandardScaler, MinMaxScaler

GinaKim 2024. 2. 19. 17:49
728x90

피처 스케일링(Feature scaling)

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

SVM, KNN, 베이지안, 회귀 등 다양한 알고리즘 사용 (수치에 대한 영향이 큼)

트리 계열 알고리즘에서는 정규화와 표준화가 분할 기준에 영향을 끼치지 않기 때문에 사용하지 않는다!!

 

대표적 방법

  • 표준화 : 데이터의 피처 각각이 평균이 0이고 분산이 1인 가우시안 정규분포를 가진 값으로 변환하는 것
  • 정규화 : 서로 다른 피처의 크기를 동일하기 위해 크기를 변환해주는 개념 (피처들의 단위를 모두 동일한 크기 단위로 비교하기 위해 모두 0~1의 값으로 변환하는 것)

StandardScaler

표준화를 지원해주는 클래스

개별 피처를 표준정규분포로 변환해 줌

 

1. feature들의 평균값과 분산값 확인

from sklearn.datasets import load_iris
import pandas as pd
# 붓꽃 데이터 셋을 로딩하고 DataFrame으로 변환합니다. 
iris = load_iris()
iris_data = iris.data
iris_df = pd.DataFrame(data=iris_data, columns=iris.feature_names)

print('feature 들의 평균 값')
print(iris_df.mean())
print('\nfeature 들의 분산 값')
print(iris_df.var())

 

2. StandardScaler를 이용해 각 피처를 한번에 표준화

from sklearn.preprocessing import StandardScaler

# 객체 생성
scaler = StandardScaler()

#StandardScaler로 데이터 세트 변환. fit()과 transform() 호출
scaler.fit(iris_df)
iris_scaled = scaler.transform(iris_df)

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

#iris_df_scaled
print("feature들의 평균 값")
print(iris_df_scaled.mean())
print('\nfeature 들의 분산 값')
print(iris_df_scaled.var())

 

모든 칼럼이 평균은 0에 아주 가깝게, 분산은 1에 가까운 값으로 변환되었음을 확인

 

MinMaxScaler

정규화 기법

수치 데이터를 0과 1 사이의 범위 값으로 변환
만약 음수가 존재하면 -1에서 1값으로 변환

 

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()

scaler.fit(iris_df)
iris_scaled = scaler.transform(iris_df)
iris_df_scaled = pd.DataFrame(data=iris_scaled, columns=iris.feature_names)

#iris_df_scaled
print("feature들의 평균 값")
print(iris_df_scaled.mean())
print('\nfeature 들의 분산 값')
print(iris_df_scaled.var())

 

모든 피처에 0에서 1사이의 값으로 변환되는 스케일링이 적용되었음을 알 수 있다.

 

MinMaxScaler 사용할 때, test데이터와 train 데이터를 합친 상태에서 fit과 transform 해야 함

test과 train을 각각 MinMaxScaler 하면,  test과 train의 최대 최소 값이 달라지기 때문에 test과 train의 값이 달라지게 됨 

(ex. test데이터에선 10을 1로 스케일링 되었지만, train데이터에서는 8이 1로 스케일링이 됨)

 

그렇기 때문에 test데이터와 train 데이터를 합친 상태에서 fit과 transform 하거나

test로 fit한 scaler로 train에 transform 해야 함

scaler = MinMaxScaler()
scaler.fit(train_array)
train_scaled = scaler.transform(train_array)
print('원본 train_array 데이터:', np.round(train_array.reshape(-1), 2))
print('Scale된 train_array 데이터:', np.round(train_scaled.reshape(-1), 2))

# test_array에 Scale 변환을 할 때는 반드시 fit()을 호출하지 않고 transform() 만으로 변환해야 함. 
test_scaled = scaler.transform(test_array)
print('\n원본 test_array 데이터:', np.round(test_array.reshape(-1), 2))
print('Scale된 test_array 데이터:', np.round(test_scaled.reshape(-1), 2))

728x90