Skip to main content

스케일링과 정규화

피처의 스케일(범위, 단위)이 다르면 일부 ML 모델은 스케일이 큰 피처에 편향됩니다. 스케일링(Scaling)은 피처들을 비슷한 범위로 변환하여 모델이 모든 피처를 공정하게 학습할 수 있게 합니다.

학습 목표

  • StandardScaler, MinMaxScaler, RobustScaler의 차이를 이해한다
  • 데이터 특성에 맞는 스케일러를 선택할 수 있다
  • 로그 변환과 Box-Cox 변환으로 분포를 정규화할 수 있다
  • 스케일링이 필요한 모델과 불필요한 모델을 구분할 수 있다

왜 중요한가

경력(120년)과 연봉(200010000만원)을 동시에 사용하면, 연봉의 수치가 훨씬 크므로 거리 기반 모델(KNN, SVM)은 연봉에 지배됩니다. 스케일링으로 이 문제를 해결합니다.

StandardScaler — 표준화

평균을 0, 표준편차를 1로 변환합니다.
import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler
import matplotlib.pyplot as plt

np.random.seed(42)
df = pd.DataFrame({
    'salary': np.random.normal(4500, 800, 200),
    'experience': np.random.uniform(1, 20, 200),
    'performance': np.random.normal(75, 10, 200)
})

# StandardScaler
scaler = StandardScaler()
df_standard = pd.DataFrame(
    scaler.fit_transform(df),
    columns=df.columns
)

print("StandardScaler 결과:")
print(df_standard.describe().round(2))
# mean ≈ 0, std ≈ 1

MinMaxScaler — 최소-최대 정규화

모든 값을 0~1 범위로 변환합니다.
# MinMaxScaler
minmax = MinMaxScaler()
df_minmax = pd.DataFrame(
    minmax.fit_transform(df),
    columns=df.columns
)

print("MinMaxScaler 결과:")
print(df_minmax.describe().round(2))
# min = 0, max = 1

# 특정 범위로 스케일링
minmax_custom = MinMaxScaler(feature_range=(-1, 1))
df_custom = pd.DataFrame(
    minmax_custom.fit_transform(df),
    columns=df.columns
)

RobustScaler — 이상치에 강건한 스케일링

중앙값과 IQR을 사용하여 이상치의 영향을 줄입니다.
# 이상치가 포함된 데이터
df_outlier = df.copy()
df_outlier.loc[0, 'salary'] = 50000   # 극단적 이상치

# 세 스케일러 비교
scalers = {
    'Standard': StandardScaler(),
    'MinMax': MinMaxScaler(),
    'Robust': RobustScaler()
}

fig, axes = plt.subplots(1, 3, figsize=(15, 4))
for ax, (name, scaler) in zip(axes, scalers.items()):
    scaled = scaler.fit_transform(df_outlier[['salary']])
    ax.hist(scaled, bins=30, color='#4a9eca', alpha=0.7, edgecolor='white')
    ax.set_title(f'{name}Scaler')
    ax.set_xlabel('스케일링된 값')

plt.suptitle('이상치가 있을 때 스케일러 비교')
plt.tight_layout()
plt.show()

스케일러 비교

스케일러수식이상치 영향적합한 상황
Standard(x - mean) / std높음정규분포, 이상치 없음
MinMax(x - min) / (max - min)매우 높음범위가 정해진 데이터
Robust(x - median) / IQR낮음이상치가 있는 데이터

분포 변환 — 편향 보정

from scipy import stats
from sklearn.preprocessing import PowerTransformer

# 편향된 데이터
np.random.seed(42)
skewed_data = np.random.exponential(5, 500)

fig, axes = plt.subplots(1, 4, figsize=(16, 4))

# 원본
axes[0].hist(skewed_data, bins=30, color='#e6a23c', alpha=0.7)
axes[0].set_title(f'원본 (왜도: {stats.skew(skewed_data):.2f})')

# 로그 변환
log_data = np.log1p(skewed_data)  # log(1+x): 0 포함 가능
axes[1].hist(log_data, bins=30, color='#4a9eca', alpha=0.7)
axes[1].set_title(f'로그 변환 (왜도: {stats.skew(log_data):.2f})')

# 제곱근 변환
sqrt_data = np.sqrt(skewed_data)
axes[2].hist(sqrt_data, bins=30, color='#4a9e4a', alpha=0.7)
axes[2].set_title(f'제곱근 변환 (왜도: {stats.skew(sqrt_data):.2f})')

# Box-Cox 변환 (양수 데이터만)
pt = PowerTransformer(method='yeo-johnson')
boxcox_data = pt.fit_transform(skewed_data.reshape(-1, 1)).flatten()
axes[3].hist(boxcox_data, bins=30, color='#9b59b6', alpha=0.7)
axes[3].set_title(f'Yeo-Johnson (왜도: {stats.skew(boxcox_data):.2f})')

plt.tight_layout()
plt.show()
변환적합한 상황제약
로그 (log1p)오른쪽 치우침, 양수 데이터0 이하 값 불가 (log1p로 해결)
제곱근 (sqrt)약한 오른쪽 치우침음수 값 불가
Box-Cox양수 데이터양수만 가능
Yeo-Johnson모든 데이터제약 없음 (Box-Cox의 일반화)

스케일링이 필요한 모델

모델스케일링 필요이유
선형회귀, 로지스틱회귀필수계수 크기가 스케일에 의존
SVM필수거리 기반 최적화
KNN필수거리 계산에 스케일 영향
PCA필수분산 기반 차원 축소
결정 트리, Random Forest불필요분할 기준이 스케일 무관
XGBoost, LightGBM불필요트리 기반 모델
신경망필수경사하강법 수렴 속도
확실하지 않으면 StandardScaler를 기본으로 사용하세요. 이상치가 있으면 RobustScaler, 신경망에서는 MinMaxScaler(0~1)가 자주 사용됩니다.

AI/ML에서의 활용

  • 모델 성능: 스케일링만으로 KNN, SVM의 성능이 크게 향상됩니다
  • 수렴 속도: 신경망의 경사하강법 수렴이 빨라집니다
  • 해석 가능성: StandardScaler 후 회귀 계수를 비교하면 피처의 상대적 중요도를 파악할 수 있습니다
  • 파이프라인 통합: 반드시 Pipeline 내에서 스케일링하여 데이터 누수를 방지합니다
fit_transform()은 학습 데이터에서 통계값(평균, 표준편차 등)을 계산하고 변환합니다. transform()은 이미 계산된 통계값으로 새 데이터를 변환합니다. 테스트 데이터에는 반드시 transform()만 사용해야 합니다.

체크리스트

  • StandardScaler, MinMaxScaler, RobustScaler의 차이를 설명할 수 있다
  • 이상치 유무에 따라 적절한 스케일러를 선택할 수 있다
  • 편향된 분포를 로그/Box-Cox 변환으로 정규화할 수 있다
  • 스케일링이 필요한 모델과 불필요한 모델을 구분할 수 있다
  • fit_transform과 transform의 차이를 이해한다

다음 문서