Skip to main content

Scikit-learn Pipeline

scikit-learn의 Pipeline은 전처리 단계와 모델 학습을 하나의 객체로 묶어, 데이터 누수를 방지하고 코드를 깔끔하게 유지합니다.

학습 목표

  • Pipeline으로 전처리와 모델을 연결할 수 있습니다.
  • ColumnTransformer로 수치형/범주형 변수를 각각 다르게 처리할 수 있습니다.
  • 파이프라인과 교차검증, GridSearchCV를 결합할 수 있습니다.

파이프라인 구축 실습

1
기본 Pipeline
2
from sklearn.pipeline import Pipeline, make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression

# 방법 1: Pipeline (이름 지정)
pipe = Pipeline([
    ("scaler", StandardScaler()),
    ("classifier", LogisticRegression(max_iter=1000))
])

# 방법 2: make_pipeline (자동 이름)
pipe = make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000))

# fit → 내부적으로 scaler.fit_transform → classifier.fit 순서로 실행
pipe.fit(X_train, y_train)

# predict → scaler.transform → classifier.predict 순서로 실행
y_pred = pipe.predict(X_test)
score = pipe.score(X_test, y_test)
print(f"파이프라인 정확도: {score:.4f}")
3
ColumnTransformer: 열별 전처리
4
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.impute import SimpleImputer

# 수치형 / 범주형 열 구분
numeric_features = ["age", "income", "score"]
categorical_features = ["city", "gender"]

# 수치형 전처리: 결측치 대체 → 스케일링
numeric_transformer = Pipeline([
    ("imputer", SimpleImputer(strategy="median")),
    ("scaler", StandardScaler())
])

# 범주형 전처리: 결측치 대체 → 원-핫 인코딩
categorical_transformer = Pipeline([
    ("imputer", SimpleImputer(strategy="most_frequent")),
    ("encoder", OneHotEncoder(handle_unknown="ignore"))
])

# ColumnTransformer로 통합
preprocessor = ColumnTransformer(
    transformers=[
        ("num", numeric_transformer, numeric_features),
        ("cat", categorical_transformer, categorical_features)
    ]
)

# 전처리 + 모델 통합 파이프라인
full_pipeline = Pipeline([
    ("preprocessor", preprocessor),
    ("classifier", LogisticRegression(max_iter=1000))
])

full_pipeline.fit(X_train, y_train)
print(f"전체 파이프라인 정확도: {full_pipeline.score(X_test, y_test):.4f}")
5
파이프라인 + GridSearchCV
6
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier

# 파이프라인 내부 파라미터는 "단계이름__파라미터" 형식으로 접근
param_grid = {
    "preprocessor__num__imputer__strategy": ["mean", "median"],
    "classifier__n_estimators": [100, 200],
    "classifier__max_depth": [5, 10, None],
}

# 모델을 랜덤 포레스트로 교체
full_pipeline.set_params(classifier=RandomForestClassifier(random_state=42))

grid = GridSearchCV(full_pipeline, param_grid, cv=5,
                    scoring="accuracy", n_jobs=-1)
grid.fit(X_train, y_train)

print(f"최적 파라미터: {grid.best_params_}")
print(f"최적 점수: {grid.best_score_:.4f}")
7
불균형 데이터 파이프라인
8
from imblearn.pipeline import Pipeline as ImbPipeline
from imblearn.over_sampling import SMOTE

# imbalanced-learn의 Pipeline은 샘플링 단계를 포함할 수 있음
imb_pipeline = ImbPipeline([
    ("preprocessor", preprocessor),
    ("smote", SMOTE(random_state=42)),
    ("classifier", RandomForestClassifier(random_state=42))
])

# SMOTE는 fit 시에만 적용, predict 시에는 건너뜀
imb_pipeline.fit(X_train, y_train)
print(f"불균형 처리 파이프라인: {imb_pipeline.score(X_test, y_test):.4f}")
  1. 데이터 누수 방지: fit/transform 순서를 자동 관리합니다. 2) 코드 간결: 전처리+모델이 하나의 객체입니다. 3) 재현성: 동일한 파이프라인으로 새 데이터에 적용 가능합니다. 4) GridSearchCV 통합: 전처리 파라미터도 함께 탐색할 수 있습니다.
네. BaseEstimatorTransformerMixin을 상속하여 fittransform 메서드를 구현하면 파이프라인에 추가할 수 있습니다. FunctionTransformer를 사용하면 더 간단하게 커스텀 변환을 추가할 수 있습니다.

체크리스트

  • Pipeline으로 전처리와 모델을 연결할 수 있다
  • ColumnTransformer로 열별 전처리를 구성할 수 있다
  • 파이프라인과 GridSearchCV를 결합할 수 있다
  • 불균형 데이터용 파이프라인을 구성할 수 있다

다음 문서