데이터 변환으로 모델 입력 분포를 다루는 방법

스케일링, 로그 변환, Box-Cox 변환의 선택 기준과 데이터 누수 방지, 역변환, 분포 시프트 운영 방식을 정리합니다.

2026-08-14 · 최초 발행 2024-04-29

모델 입력 분포를 먼저 다뤄야 하는 이유

데이터 변환은 모델의 학습 안정성, 수렴 속도, 해석 가능성에 직접 영향을 주는 전처리 단계다. 입력 변수의 범위와 분포가 제각각이면 거리 계산이나 규제 항의 영향이 왜곡될 수 있고, 예측 결과를 원래 단위로 해석하기도 어려워진다.

스케일링은 값의 척도를 맞추는 데 초점을 둔다. 로그 변환과 Box-Cox 변환은 치우친 분포와 곱셈적 스케일을 다루는 데 사용한다. 어떤 변환을 선택하든 변환기를 학습 데이터에서만 fit하고, 검증·테스트 데이터에는 동일한 파라미터로 transform해야 한다. 예측값은 필요할 때 inverse_transform으로 원 단위로 되돌려 해석한다.

범위를 맞추거나 분포를 바꾸는 선택지

정규화(Min-Max)는 값을 [0, 1] 또는 원하는 구간으로 선형 변환한다. 범위가 직관적이라는 장점이 있지만 이상치에 민감하다. 표준화(Z-score)는 평균을 0, 표준편차를 1로 맞춰 변수 간 분산 규모를 통일한다. 이상치 영향은 완화할 수 있으나 비정규 분포의 꼬리값을 관리하는 데는 한계가 있다.

거리 기반 모델인 KNN, KMeans, SVM RBF와 규제 회귀인 Lasso, Ridge에서는 스케일링이 중요한 입력 조건이 된다. 트리 기반 모델은 상대적인 영향이 적지만, 학습 안정성이나 조기 종료 기준을 통일하는 데 긍정적인 효과가 있을 수 있다. 운영 환경에서는 훈련 구간에서 얻은 min/max 또는 mean/std를 고정해 관리하고, 데이터 분포 시프트가 생기면 주기적인 리핏과 모니터링을 검토한다.

로그 변환은 양수 값의 왜도를 완화하고 곱셈적 스케일을 덧셈적 스케일로 바꾼다. 비율, 매출, 체류시간처럼 곱셈적 잡음이 있는 값의 분산을 안정화하는 데 활용할 수 있다. 0을 포함하는 변수에는 log1p(x)를 적용하거나 상수 시프트를 고려한다. 첨도와 왜도를 줄이고 선형 적합성을 높일 수 있지만, 0 또는 음수 처리와 0 근처의 민감도는 별도로 관리해야 한다. 예측값은 expm1으로 복원할 수 있으며, 변환 뒤 단위 해석이 달라진다는 점도 비즈니스 측과 공유할 필요가 있다.

Box-Cox 변환은 λ 파라미터를 이용하는 지수형 단조 변환이다. 최대우도(MLE)로 λ를 추정해 정규성 근사를 높이며, λ=0일 때는 로그 변환과 일치한다. 입력은 양수여야 하므로 0이나 음수가 있다면 Yeo-Johnson 변환을 대안으로 쓴다. 이상치에 민감할 수 있어 윈저라이징이나 IQR 클리핑 같은 로버스트 전처리를 함께 고려할 수 있다. PowerTransformer를 사용하면 Box-Cox와 Yeo-Johnson의 fit, transform, 역변환을 일관된 방식으로 관리할 수 있다.

변환기는 검증 경계 안에서 학습한다

변환 로직은 ColumnTransformerPipeline에 묶어 모델 학습 과정에 포함하는 편이 안전하다. 교차검증에서는 각 학습 폴드 안에서만 fit이 수행되어야 하며, 그렇지 않으면 검증 데이터의 분포 정보가 전처리에 섞이는 데이터 누수가 발생한다.

배포 뒤에는 훈련 데이터와 실제 입력 데이터의 차이를 PSI, KS 통계 등으로 감지하고 재적합 기준을 마련한다. 역변환 중 발생할 수 있는 오류와 오버플로우도 예외 처리 대상이다.

입력 도메인에 따른 처리 흐름

음수/0 포함양수만예측치 해석오류/에지 케이스입력 데이터도메인 점검처리 선택: Yeo-Johnson 또는상수 시프트처리 선택: Log 또는 Box-Cox스케일링 선택: Min-Max /Z-score훈련 세트에서 fit검증/테스트에 transform모델 학습/평가역변환(inverse_transform)예외 처리: 오버플로우, NaN,범위로그/메트릭 기록 재시도정책

변환별 운영 특성

변환 성능(선형/거리기반) 확장성(대용량/스트림) 일관성(재현성/역변환) 안정성(이상치/수치) 운영 편의
정규화(Min-Max) 거리기반 효과 큼, 선형 회귀 가중치 안정화 보조 O(1) 업데이트 어려움, 윈도우링 필요 재현성 높음, 역변환 용이 이상치에 매우 민감 간단, 범위 해석 용이
표준화(Z-score) 선형/규제 모델 수렴 속도 개선 온라인 평균/분산 업데이트 용이 재현성 높음, 역변환 용이 이상치 영향 중간 일반적 기본값 역할
로그 변환 왜도 완화로 선형 적합성 개선 값 범위 축소로 수치 안정 역변환 간단, 0 처리 주의 0/음수 취급 필요 비즈니스 해석 주의 필요
Box-Cox 변환 정규성 근사로 회귀/ANOVA 성능 향상 λ 추정 비용 존재 역변환 가능, λ 관리 필요 양수 제약, 이상치 민감 PowerTransformer로 일원화 가능

금융·제조·수요 예측에서의 적용

금융 신용평가에서는 소득, 자산, 부채비율의 양의 왜도를 완화하기 위해 로그 또는 Box-Cox 변환을 적용할 수 있다. 카드 사용액과 거래 빈도는 표준화한 뒤 규제 회귀나 SVM에 입력하고, 파이프라인 기반 배포로 재현성과 모형검증 체계를 확보한다.

제조 설비 이상 탐지에서는 서로 다른 단위와 범위를 가진 센서값을 표준화해 스케일을 정렬한다. 진동 RMS, 전류 피크치처럼 heavy-tail 특성을 보이는 지표에는 로그 또는 Box-Cox 변환을 적용하고, KNN이나 KMeans 기반 이상치 탐지의 성능을 개선할 수 있다.

마케팅 LTV와 수익 예측에서는 구매금액과 세션 길이를 로그 변환해 선형 회귀의 적합성을 높인다. 사용자 속성은 표준화하고 카테고리 원-핫 인코딩 결과와 결합해 ElasticNet을 학습한다. 예측값을 역변환하면 원 단위 KPI 보고 체계를 유지할 수 있다.

시계열 수요 예측에서 변동성이 규모에 비례한다면 로그 변환으로 분산을 안정화한다. 회귀 기반 피처 엔지니어링과 Box-Cox를 결합해 정규성 근사를 시도할 수 있으며, 예측 구간의 역변환과 신뢰구간 변환 로직도 함께 둔다.

실행 가능한 전처리 코드

전제조건:

  • Python 3.10+, numpy, pandas, scikit-learn>=1.2, scipy>=1.8
  • 설치: pip install numpy pandas scikit-learn scipy

스케일링과 로그·Box-Cox 변환

import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler, StandardScaler, PowerTransformer, FunctionTransformer

# 샘플 데이터 생성
rng = np.random.default_rng(42)
df = pd.DataFrame({
    "amount": np.exp(rng.normal(3, 1, 1000)),   # 양의 왜도
    "age": rng.normal(40, 12, 1000),            # 대략 정규
    "clicks": rng.poisson(3, 1000)              # 0 포함 카운트
})

# 정규화/표준화
minmax = MinMaxScaler()
zscaler = StandardScaler()
df["age_minmax"] = minmax.fit_transform(df[["age"]])
df["age_z"] = zscaler.fit_transform(df[["age"]])

# 로그 변환: 0 포함 가능 변수에는 log1p
log1p = FunctionTransformer(np.log1p, validate=True, feature_names_out="one-to-one")
df["clicks_log1p"] = log1p.fit_transform(df[["clicks"]])

# Box-Cox: 양수 제약
pt_boxcox = PowerTransformer(method="box-cox", standardize=False)
df["amount_boxcox"] = pt_boxcox.fit_transform(df[["amount"]])
# λ 확인
lmbda = pt_boxcox.lambdas_[0]
print("Box-Cox lambda:", lmbda)

# 음수/0 가능 변수에는 Yeo-Johnson
pt_yj = PowerTransformer(method="yeo-johnson", standardize=False)
df["clicks_yj"] = pt_yj.fit_transform(df[["clicks"]])

교차검증에서 데이터 누수를 막는 구성

from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.linear_model import Ridge
from sklearn.model_selection import cross_val_score, KFold

num_features_log = ["amount"]
num_features_std = ["age"]
count_features = ["clicks"]

preprocess = ColumnTransformer(
    transformers=[
        ("log1p", FunctionTransformer(np.log1p), count_features),
        ("boxcox", PowerTransformer(method="box-cox"), num_features_log),
        ("zscore", StandardScaler(), num_features_std),
    ],
    remainder="drop"
)

model = Pipeline(steps=[
    ("prep", preprocess),
    ("reg", Ridge(alpha=1.0))
])

X = df[["amount", "age", "clicks"]]
y = np.log1p(df["amount"])  # 예시: 목표의 로그 변환 학습

cv = KFold(n_splits=5, shuffle=True, random_state=42)
scores = cross_val_score(model, X, y, cv=cv, scoring="neg_root_mean_squared_error")
print("CV RMSE(mean):", -scores.mean())

로그 타깃 예측값을 원 단위로 복원하기

# 타깃을 로그로 학습한 경우 예측 후 역변환
model.fit(X, y)
y_pred_log = model.predict(X[:5])
y_pred = np.expm1(y_pred_log)  # 원 단위 복원
print(y_pred)

음수와 0을 포함한 값의 처리

def safe_log1p(x: np.ndarray, eps: float = 0.0) -> np.ndarray:
    # 음수 발생 시 상수 시프트 적용
    shift = 0.0
    min_x = np.min(x)
    if min_x <= -eps:
        shift = -min_x + eps
    return np.log1p(x + shift), shift

vals = np.array([-2.0, 0.0, 3.0])
logged, shift = safe_log1p(vals, eps=1e-6)

성능 개선과 해석 체계의 변화

데이터와 분포에 따라 선형·규제 모델의 RMSE, MAE가 520% 개선된 사례가 관찰된다. KNN, KMeans 같은 거리 기반 모델에서는 실루엣 스코어와 탐지 정밀도가 1030%p 개선된 사례도 있다. 수치 안정성이 높아지면 최적화 수렴 에폭 수가 줄고 학습 시간이 단축될 수 있다.

변환은 계수 해석을 안정화하고 공선성을 완화하는 데도 기여한다. 비즈니스 지표의 척도를 일관되게 유지하고 보고 체계를 단순화할 수 있으며, 배포 환경에서는 재현성과 역변환을 통한 결과 신뢰성을 높인다.

데이터 전처리스케일링로그 변환Box-Cox 변환머신러닝