데이터 전처리
Data Preprocessing
원시 데이터를 분석 가능한 형태로 정제하는 과정. 결측값 처리, 정규화, 인코딩 등 포함.
Data Preprocessing
원시 데이터를 분석 가능한 형태로 정제하는 과정. 결측값 처리, 정규화, 인코딩 등 포함.
데이터 전처리(Data Preprocessing)는 원시 데이터를 머신러닝 모델이나 분석에 적합한 형태로 정제하고 변환하는 과정입니다. 실제 데이터 과학 프로젝트에서 전체 시간의 60-80%가 데이터 전처리에 소요될 만큼 핵심적인 단계입니다. "Garbage In, Garbage Out"이라는 격언처럼, 전처리 품질이 모델 성능에 직접적인 영향을 미칩니다.
전처리의 주요 작업은 결측값 처리, 이상치 탐지 및 제거, 데이터 정규화/표준화, 범주형 변수 인코딩, 특성 선택 및 변환 등이 있습니다. 결측값은 삭제, 평균/중앙값 대체, KNN 대체, 다중 대체(MICE) 등 다양한 전략으로 처리하며, 이상치는 IQR, Z-score, Isolation Forest 등으로 탐지합니다. 스케일링은 알고리즘에 따라 적절한 방법을 선택해야 합니다.
수치형 데이터의 스케일링에는 Min-Max 정규화(0-1 범위), StandardScaler(Z-score 표준화), RobustScaler(중앙값 기반으로 이상치에 강건) 등이 있습니다. 범주형 데이터는 One-Hot Encoding(명목형), Label Encoding(순서형), Target Encoding(고카디널리티 범주) 등으로 수치화합니다. 텍스트나 날짜 데이터도 적절한 변환이 필요합니다.
scikit-learn의 Pipeline과 ColumnTransformer를 활용하면 전처리 과정을 재현 가능하고 모듈화된 형태로 구성할 수 있습니다. 대용량 데이터는 Spark나 Dask로 분산 처리하며, 전처리 로직을 Feature Store에 등록하면 학습과 추론에서 일관성을 유지할 수 있습니다. 전처리는 단순 작업이 아닌 도메인 지식을 반영하는 핵심 역량입니다.
# 종합적인 데이터 전처리 파이프라인 예시
import pandas as pd
import numpy as np
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import (
StandardScaler, MinMaxScaler, OneHotEncoder,
OrdinalEncoder, PowerTransformer
)
from sklearn.impute import SimpleImputer, KNNImputer
from sklearn.feature_selection import SelectKBest, mutual_info_classif
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
# 1. 데이터 로드 및 탐색
df = pd.read_csv('customer_data.csv')
print(f"Shape: {df.shape}")
print(f"결측값:\n{df.isnull().sum()}")
print(f"데이터 타입:\n{df.dtypes}")
# 2. 컬럼 타입별 분류
numeric_features = ['age', 'income', 'credit_score', 'account_balance']
categorical_features = ['gender', 'region', 'membership_type']
ordinal_features = ['education'] # 순서 있는 범주
# 3. 이상치 탐지 및 처리 (IQR 방식)
def remove_outliers_iqr(df, column, threshold=1.5):
"""IQR 기반 이상치 제거"""
Q1 = df[column].quantile(0.25)
Q3 = df[column].quantile(0.75)
IQR = Q3 - Q1
lower = Q1 - threshold * IQR
upper = Q3 + threshold * IQR
return df[(df[column] >= lower) & (df[column] <= upper)]
# 수치형 컬럼에 이상치 처리 적용
for col in numeric_features:
df = remove_outliers_iqr(df, col)
# 4. 전처리 파이프라인 구성
# 수치형: KNN 대체 -> Z-score 정규화 -> 정규분포화
numeric_transformer = Pipeline(steps=[
('imputer', KNNImputer(n_neighbors=5)),
('scaler', StandardScaler()),
('power', PowerTransformer(method='yeo-johnson'))
])
# 범주형: 최빈값 대체 -> One-Hot 인코딩
categorical_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='most_frequent')),
('encoder', OneHotEncoder(handle_unknown='ignore', sparse_output=False))
])
# 순서형: 최빈값 대체 -> Ordinal 인코딩
ordinal_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='most_frequent')),
('encoder', OrdinalEncoder(categories=[
['고졸', '전문대졸', '대졸', '석사', '박사']
]))
])
# 5. ColumnTransformer로 통합
preprocessor = ColumnTransformer(
transformers=[
('num', numeric_transformer, numeric_features),
('cat', categorical_transformer, categorical_features),
('ord', ordinal_transformer, ordinal_features)
],
remainder='drop'
)
# 6. 전체 ML 파이프라인 (전처리 + 특성 선택 + 모델)
full_pipeline = Pipeline(steps=[
('preprocessor', preprocessor),
('feature_selection', SelectKBest(mutual_info_classif, k=15)),
('classifier', RandomForestClassifier(n_estimators=100, random_state=42))
])
# 7. 학습 및 평가
X = df.drop('target', axis=1)
y = df['target']
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# 전체 파이프라인 학습
full_pipeline.fit(X_train, y_train)
predictions = full_pipeline.predict(X_test)
# 8. 전처리된 데이터 확인
X_preprocessed = preprocessor.fit_transform(X_train)
feature_names = preprocessor.get_feature_names_out()
print(f"전처리 후 특성 수: {len(feature_names)}")
print(f"특성 이름: {feature_names[:10]}...")
# 9. 파이프라인 저장 (재사용)
import joblib
joblib.dump(full_pipeline, 'preprocessing_pipeline.pkl')
# 추론 시 동일한 파이프라인 사용
loaded_pipeline = joblib.load('preprocessing_pipeline.pkl')
new_predictions = loaded_pipeline.predict(new_data)