Notice
Recent Posts
Recent Comments
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Archives
Today
Total
관리 메뉴

AI기록장

[ML] 데이터 스케일링(Data Scaling) 본문

ML/개념정리

[ML] 데이터 스케일링(Data Scaling)

SanL 2023. 9. 11. 00:06

❖ Data Scaling

: Data Scaling은 데이터 전처리 과정 중의 하나이다.
피처(feature)들마다 데이터값의 범위가 다 제각각이기 때문에 범위 차이가 클 경우 데이터를 갖고 모델을
학습할 때 0으로 수렴하거나 무한으로 발산할 수 있다.

즉, 이러한 머신러닝을 Data Scaling 방법을 이용하여 모든 피처들의 데이터 분포나 범위를 동일하게 조정할 수 있다.

표준화

데이터의 피처 각각이 평균이 0 이고, 분산이 1인 가우시안 정규 분포를 가진 값으로 변환하는 것

→ x값이 최소일 떄 분자가 최소가 되어 x'은 0이되고, x값이 최대일 때 분자와 분모가 같으므로 x'은 1

정규화

서로 다른 피처의 크기를 통일하기 위해 데이터의 크기를 0~1사이로 변환해주는 개념이다.

→ 에타는 평균, 알바는 표준편차를 의미


왜?

예를 들어, 날씨에 대한 부분을 이야기 할때 온도, 습도, 바람 등을 이야기할 수 있는데

이것들의 값을 절대적으로 비교하기에는 불가하다.

이처럼 서로 다른 기준의 값들을 같은 기준으로 변환해주는 것을 말한다.

★ 피처 스케일링이 중요할 경우

몇몇 머신러닝 알고리즘들은 피처 스케일링에 민감하다.


1. Gradient Descent Based Algorithms
→ 최적화 기법을 위해 Gradient Descent(경사하강법) Algorithms을 사용하는 ML 알고리즘들
(Linear Regression, Logistic Regression, Neural Network 등) 은 피처 스케일링이 중요
→ 경사하강법에서 x값은 경사하강법의 단계의 크기에 큰 영향을 미쳐, 경사하강이 최솟값으로 부드럽게 이동하고,
하강 단계가 모든 특징에 대해 동일한 속도로 업데이트를 위해서는 피처 스케일링이 중요!


2. Distance-Based Algorithms
→ Distance Alogrithms(KNN, K-means,SVM)은 데이터 점들간의 거리로 유사성을 판단하기 때문에 피처의 크기에 영향을 받는다.
즉, 스케일링 전과 후의 데이터의 유클리드 거리가 변하는 값을 생각하면 된다.
변화의 데이터 분포 값이 크다면 유클리드의 값이 크게 나오겠지만, 스케일링을 한 후에는 좀 더 안정된 거리의 값이 나올 것이다.


3. Tree-Based Alogrithms
→ 위의 알고리즘들은 모두 피처의 값에 예민했지만, Tree Alogrithms들은 피처 스케일링에 민감하게 반응하지않는다.
결정 트리와 같은 경우 데이터의 특징을 기반으로 노드를 분류해나아가기 때문에이다.

sklearn - Data Scaling 방법 다섯가지

  • StandardScaler() : 모든 피처들을 평균이 0 , 분산이 1인 정규분포를 갖도록 만들어준다.

  • MinMaxscaler() : 모든 피처들이 0과 1 사이의 데이터값을 갖도록 만들어준다.

  • MaxAbsScaler() : 모든 피처들의 절대값이 0과 1사이에 놓이도록 만드러준다.

  • RobustScaler() : 중간값(median)과 사분위값을 사용하여 StandardScaler보다 데이터가 더 넓게 분포되도록 만들어준다.

  • Normalizer() : 각 행(row)마다 정규화를 진행하여, 한 행의 모든 피처들 사이의 유클리드 거리가 1이 되도록 데이터값을 만들어준다.

  • StandardScaler

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())
feature 들의 평균 값
sepal length (cm)    5.843333
sepal width (cm)     3.057333
petal length (cm)    3.758000
petal width (cm)     1.199333
dtype: float64

feature 들의 분산 값
sepal length (cm)    0.685694
sepal width (cm)     0.189979
petal length (cm)    3.116278
petal width (cm)     0.581006
dtype: float64
from sklearn.preprocessing import StandardScaler

# StandardScaler객체 생성
scaler = StandardScaler()
# StandardScaler 로 데이터 셋 변환. fit( ) 과 transform( ) 호출.  
scaler.fit(iris_df)
iris_scaled = scaler.transform(iris_df)

#transform( )시 scale 변환된 데이터 셋이 numpy ndarry로 반환되어 이를 DataFrame으로 변환
iris_df_scaled = pd.DataFrame(data=iris_scaled, columns=iris.feature_names)
print('feature 들의 평균 값')
print(iris_df_scaled.mean())
print('\nfeature 들의 분산 값')
print(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
  • MinMaxScaler
from sklearn.preprocessing import MinMaxScaler

# MinMaxScaler객체 생성
scaler = MinMaxScaler()
# MinMaxScaler 로 데이터 셋 변환. fit() 과 transform() 호출.  
scaler.fit(iris_df)
iris_scaled = scaler.transform(iris_df)

# transform()시 scale 변환된 데이터 셋이 numpy ndarry로 반환되어 이를 DataFrame으로 변환
iris_df_scaled = pd.DataFrame(data=iris_scaled, columns=iris.feature_names)
print('feature들의 최소 값')
print(iris_df_scaled.min())
print('\nfeature들의 최대 값')
print(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

☑︎주의 (중요)

학습 데이터세트와 테스트 세트에 fit(), transform()을 적용할 때, 주의가 필요하다.
→ Scaler 객체를 이용해서 train 세트를 fit을 수행했다면, test 세트 또한, train 세트가 scaler된 객체를 이용하여
transform을 진행해야한다.
그 이유는 train 데이터 세트와 test 데이터 세트의 기준 척도가 서로 달라지면 안된다.

from sklearn.preprocessing import MinMaxScaler
import numpy as np

# 학습 데이터는 0 부터 10까지, 테스트 데이터는 0 부터 5까지 값을 가지는 데이터 세트로 생성
# Scaler클래스의 fit(), transform()은 2차원 이상 데이터만 가능하므로 reshape(-1, 1)로 차원 변경
train_array = np.arange(0, 11).reshape(-1, 1)
test_array =  np.arange(0, 6).reshape(-1, 1)
# 최소값 0, 최대값 1로 변환하는 MinMaxScaler객체 생성
scaler = MinMaxScaler()
# fit()하게 되면 train_array 데이터의 최소값이 0, 최대값이 10으로 설정.  
scaler.fit(train_array)
# 1/10 scale로 train_array 데이터 변환함. 원본 10-> 1로 변환됨.
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))
원본 train_array 데이터: [ 0  1  2  3  4  5  6  7  8  9 10]
Scale된 train_array 데이터: [0.  0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. ]
# 앞에서 생성한 MinMaxScaler에 test_array를 fit()하게 되면 원본 데이터의 최소값이 0, 최대값이 5으로 설정됨 
scaler.fit(test_array)
# 1/5 scale로 test_array 데이터 변환함. 원본 5->1로 변환.  
test_scaled = scaler.transform(test_array)
# test_array 변환 출력
print('원본 test_array 데이터:', np.round(test_array.reshape(-1), 2))
print('Scale된 test_array 데이터:', np.round(test_scaled.reshape(-1), 2))
원본 test_array 데이터: [0 1 2 3 4 5]
Scale된 test_array 데이터: [0.  0.2 0.4 0.6 0.8 1. ]

→ 이 처럼 train 데이터 세트에서 scaler가 되었지만, test 데이터 세트에서 다시 fit()을 진행하여 transform을 한다면,
train 데이터 세트에서 가르키는 2와 test에서 가르키는 2는 다른 기준으로 데이터 분포를 재형성 하게된다.

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))
원본 train_array 데이터: [ 0  1  2  3  4  5  6  7  8  9 10]
Scale된 train_array 데이터: [0.  0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. ]

원본 test_array 데이터: [0 1 2 3 4 5]
Scale된 test_array 데이터: [0.  0.1 0.2 0.3 0.4 0.5]

→ 이렇게 train data set에서 만들어진 scaler 객체를 가지고 test data set에도 동일하게 scaler을 적용시켜주어야
동일한 기준으로 스케일링이 적용됨


[참고] Dacon (yun99), 파이썬 머신러닝 완벽가이드