010 setup() 전처리 옵션 - 스케일링
키워드: 스케일링, 정규화
개요
수치형 특성들은 서로 다른 범위와 단위를 가집니다. 예를 들어 나이는 0100 범위지만, 소득은 0수억 원 범위입니다. 이런 차이는 일부 알고리즘의 성능에 영향을 미칩니다. **스케일링(Scaling)**은 특성들의 범위를 맞춰주는 전처리 기법입니다. 이 글에서는 PyCaret의 스케일링 옵션을 알아보겠습니다.
실습 환경
- Python 버전: 3.11 권장
- Python 3.11은 2027년 말까지 지원되며, PyCaret 호환 최신 버전입니다.
- 필요 패키지:
pycaret[full]>=3.0, pandas, matplotlib
pip install pycaret[full]>=3.0 pandas matplotlib
Google Colab 사용 불가 Google Colab은 2025년 8월부터 Python 3.12만 지원하여 PyCaret(3.8~3.11) 실습이 불가능합니다. 로컬 환경이나 Docker를 사용해 주세요.
스케일링이 필요한 이유
스케일링 미적용 시 문제
from pycaret.datasets import get_data
import pandas as pd
data = get_data('insurance')
print(data[['age', 'bmi', 'charges']].describe())
출력:
age bmi charges
count 1338.0000 1338.0000 1338.000000
mean 39.2070 30.6634 13270.422265
std 14.0500 6.0981 12110.011237
min 18.0000 15.9600 1121.873900
max 64.0000 53.1300 63770.428010
age: 18 ~ 64 범위bmi: 15.96 ~ 53.13 범위charges: 1,121 ~ 63,770 범위
이 상태로 KNN, SVM, 신경망을 학습하면 charges가 거리 계산을 지배합니다.
스케일링이 중요한 알고리즘
| 알고리즘 | 스케일링 필요 | 이유 |
|---|---|---|
| KNN | ✅ 필수 | 거리 기반 |
| SVM | ✅ 필수 | 거리 기반 |
| 신경망 (MLP) | ✅ 필수 | 경사하강법 |
| 로지스틱 회귀 | ⚠️ 권장 | 수렴 속도 |
| Ridge/Lasso | ⚠️ 권장 | 정규화 영향 |
| 결정 트리 | ❌ 불필요 | 분할 기반 |
| 랜덤 포레스트 | ❌ 불필요 | 트리 앙상블 |
| XGBoost/LightGBM | ❌ 불필요 | 트리 기반 |
PyCaret 스케일링 옵션
normalize 파라미터
from pycaret.regression import *
clf = setup(
data=data,
target='charges',
normalize=True, # 스케일링 활성화
normalize_method='zscore', # 스케일링 방법
session_id=42
)
스케일링 방법 비교
| 방법 | 파라미터 | 수식 | 범위 |
|---|---|---|---|
| Z-score (표준화) | 'zscore' | (x - mean) / std | 대부분 -3 ~ 3 |
| Min-Max | 'minmax' | (x - min) / (max - min) | 0 ~ 1 |
| Max Absolute | 'maxabs' | x / max(abs(x)) | -1 ~ 1 |
| Robust | 'robust' | (x - median) / IQR | 이상치에 강건 |
스케일링 방법 상세
1. Z-score 표준화 (기본값)
평균 0, 표준편차 1로 변환
clf = setup(
data=data,
target='charges',
normalize=True,
normalize_method='zscore',
session_id=42
)
변환 공식:
z = (x - μ) / σ
적합한 경우:
- 정규분포에 가까운 데이터
- 대부분의 경우 권장
2. Min-Max 스케일링
0~1 범위로 변환
clf = setup(
data=data,
target='charges',
normalize=True,
normalize_method='minmax',
session_id=42
)
변환 공식:
x_scaled = (x - x_min) / (x_max - x_min)
적합한 경우:
- 특정 범위가 필요할 때
- 신경망 입력
- 이미지 데이터
3. Max Absolute 스케일링
최대 절대값으로 나눔
clf = setup(
data=data,
target='charges',
normalize=True,
normalize_method='maxabs',
session_id=42
)
적합한 경우:
- 희소 행렬 (0이 많은 데이터)
- 0을 유지해야 할 때
4. Robust 스케일링
중앙값과 IQR 사용 (이상치에 강건)
clf = setup(
data=data,
target='charges',
normalize=True,
normalize_method='robust',
session_id=42
)
변환 공식:
x_scaled = (x - median) / IQR
IQR = Q3 - Q1 (사분위수 범위)
적합한 경우:
- 이상치가 많은 데이터
- 비대칭 분포
실전 예제: 스케일링 효과 비교
from pycaret.regression import *
from pycaret.datasets import get_data
data = get_data('insurance')
# 010 스케일링 없이
print("=" * 50)
print("스케일링 없음")
print("=" * 50)
reg1 = setup(
data=data,
target='charges',
normalize=False,
session_id=42,
verbose=False
)
# 010 SVM 모델 (스케일링 민감)
svm1 = create_model('svm', verbose=False)
results1 = pull()
print(f"SVM R2: {results1['R2'].mean():.4f}")
# 010 Z-score 스케일링
print("\n" + "=" * 50)
print("Z-score 스케일링")
print("=" * 50)
reg2 = setup(
data=data,
target='charges',
normalize=True,
normalize_method='zscore',
session_id=42,
verbose=False
)
svm2 = create_model('svm', verbose=False)
results2 = pull()
print(f"SVM R2: {results2['R2'].mean():.4f}")
# 010 Min-Max 스케일링
print("\n" + "=" * 50)
print("Min-Max 스케일링")
print("=" * 50)
reg3 = setup(
data=data,
target='charges',
normalize=True,
normalize_method='minmax',
session_id=42,
verbose=False
)
svm3 = create_model('svm', verbose=False)
results3 = pull()
print(f"SVM R2: {results3['R2'].mean():.4f}")
출력 예시:
==================================================
스케일링 없음
==================================================
SVM R2: -0.0821
==================================================
Z-score 스케일링
==================================================
SVM R2: 0.7423
==================================================
Min-Max 스케일링
==================================================
SVM R2: 0.7156
스케일링 없이는 SVM이 전혀 학습하지 못하지만, 스케일링 후 성능이 크게 향상됩니다!
트리 기반 모델에서의 스케일링
트리 기반 모델은 스케일링이 불필요합니다:
from pycaret.regression import *
from pycaret.datasets import get_data
data = get_data('insurance')
# 010 스케일링 없이
reg1 = setup(data, target='charges', normalize=False, session_id=42, verbose=False)
rf1 = create_model('rf', verbose=False)
results1 = pull()
print(f"RF (스케일링 X): R2 = {results1['R2'].mean():.4f}")
# 010 스케일링 적용
reg2 = setup(data, target='charges', normalize=True, session_id=42, verbose=False)
rf2 = create_model('rf', verbose=False)
results2 = pull()
print(f"RF (스케일링 O): R2 = {results2['R2'].mean():.4f}")
출력:
RF (스케일링 X): R2 = 0.8521
RF (스케일링 O): R2 = 0.8519
랜덤 포레스트는 스케일링 여부에 거의 영향받지 않습니다.
스케일링 시각화
import matplotlib.pyplot as plt
import numpy as np
from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler
# 010 샘플 데이터
np.random.seed(42)
data_sample = np.concatenate([
np.random.normal(50, 10, 100),
np.array([150, 200]) # 이상치
])
# 010 스케일링
scalers = {
'Original': data_sample,
'Z-score': StandardScaler().fit_transform(data_sample.reshape(-1, 1)).flatten(),
'Min-Max': MinMaxScaler().fit_transform(data_sample.reshape(-1, 1)).flatten(),
'Robust': RobustScaler().fit_transform(data_sample.reshape(-1, 1)).flatten()
}
# 010 시각화
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
axes = axes.flatten()
for ax, (name, values) in zip(axes, scalers.items()):
ax.hist(values, bins=20, edgecolor='black', alpha=0.7)
ax.set_title(f'{name}')
ax.set_xlabel('Value')
ax.set_ylabel('Frequency')
plt.tight_layout()
plt.savefig('scaling_comparison.png')
스케일링 선택 가이드
| 상황 | 권장 스케일링 |
|---|---|
| 일반적인 경우 | Z-score ('zscore') |
| 신경망 입력 | Min-Max ('minmax') |
| 이상치가 많음 | Robust ('robust') |
| 희소 데이터 | Max Absolute ('maxabs') |
| 트리 기반 모델만 사용 | 불필요 (normalize=False) |
타겟 변수 변환
회귀 문제에서 타겟 변수도 변환할 수 있습니다:
clf = setup(
data=data,
target='charges',
transform_target=True, # 타겟 변환 활성화
transform_target_method='yeo-johnson', # 변환 방법
session_id=42
)
타겟 변환 방법:
'yeo-johnson': 음수 포함 가능'box-cox': 양수만 가능'quantile': 균등 분포로 변환
적합한 경우:
- 타겟이 비대칭 분포일 때
- 타겟에 이상치가 있을 때
정리
- 스케일링은 특성들의 범위를 맞춰주는 전처리입니다.
- KNN, SVM, 신경망 등 거리 기반 알고리즘에는 필수입니다.
- 트리 기반 모델(RF, XGBoost 등)에는 불필요합니다.
normalize=True로 활성화하고,normalize_method로 방법을 선택합니다.- 이상치가 많으면
'robust'스케일링을 사용하세요. - PyCaret의
compare_models()는 여러 알고리즘을 테스트하므로 스케일링을 적용하는 것이 좋습니다.
다음 글 예고
다음 글에서는 setup() 전처리 옵션 - 특성 선택에 대해 알아보겠습니다. 불필요한 특성을 제거하고 중요한 특성만 선택하여 모델 성능을 향상시키는 방법을 다룹니다.
PyCaret 머신러닝 마스터 시리즈 #010