# Scikit-Learn Pipeline 완벽 가이드 2026: 특성 엔지니어링과 면접 대비 > Scikit-Learn Pipeline을 활용한 특성 엔지니어링 실전 가이드입니다. ColumnTransformer, 커스텀 Transformer, GridSearchCV를 통한 하이퍼파라미터 튜닝, 프로덕션 배포 모범 사례를 다룹니다. - Published: 2026-09-02 - Updated: 2026-09-02 - Author: Anthony Fillion-Maillet - Reading time: 5 min --- 머신러닝 프로젝트에서 특성 엔지니어링과 모델 학습 워크플로우를 효율적으로 관리하는 것은 재현성과 프로덕션 배포 관점에서 매우 중요합니다. Scikit-Learn 1.5에서는 Pipeline 클래스가 강화되어 더욱 유연한 전처리와 모델 통합이 가능해졌습니다. 본 글에서는 sklearn Pipeline의 기초부터 고급 활용법, 그리고 2026년 머신러닝 엔지니어 면접에서 자주 출제되는 질문에 대해 설명합니다. > **Pipeline이란 무엇인가** > > Scikit-Learn의 Pipeline은 데이터 전처리와 모델 학습을 단일 객체로 연결하는 메커니즘입니다. 이를 통해 데이터 누수(Data Leakage) 방지, 코드 재사용성 향상, 하이퍼파라미터 일괄 최적화가 가능합니다. Pipeline을 사용하지 않으면 훈련 데이터와 테스트 데이터에 개별적으로 전처리를 적용해야 하며, 오류가 발생하기 쉽습니다. ## Pipeline의 기본: 전처리와 모델의 통합 Pipeline의 기본 구조는 여러 "단계(step)"를 순서대로 실행하는 시퀀스입니다. 각 단계는 변환기(Transformer) 또는 추정기(Estimator)로 구성됩니다. 변환기는 `fit`과 `transform` 메서드를 가지며, 추정기는 `fit`과 `predict` 메서드를 가집니다. 다음은 결측값 대체, 표준화, 로지스틱 회귀를 결합한 기본적인 Pipeline 예시입니다. ```python from sklearn.pipeline import Pipeline from sklearn.impute import SimpleImputer from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split import pandas as pd import numpy as np # Sample data X = pd.DataFrame({ 'age': [25, 30, np.nan, 45, 50], 'income': [50000, 60000, 75000, np.nan, 90000], 'score': [0.8, 0.6, 0.9, 0.7, 0.85] }) y = np.array([0, 0, 1, 1, 1]) # Create pipeline pipeline = Pipeline([ ('imputer', SimpleImputer(strategy='median')), ('scaler', StandardScaler()), ('classifier', LogisticRegression(random_state=42)) ]) # Fit and predict X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) pipeline.fit(X_train, y_train) predictions = pipeline.predict(X_test) print(f"Predictions: {predictions}") ``` 이 Pipeline에서 `fit` 메서드를 호출하면 각 단계가 순서대로 훈련 데이터에 적합됩니다. `predict`를 호출하면 데이터가 각 변환기를 통과하고 최종적으로 분류기에서 예측이 수행됩니다. 중요한 점은 `fit`은 훈련 데이터에서만 호출되고, 테스트 데이터에는 `transform`만 적용된다는 것입니다. 이를 통해 데이터 누수가 자동으로 방지됩니다. ## ColumnTransformer: 서로 다른 데이터 타입 처리 실제 데이터셋에서는 수치형 특성과 범주형 특성이 혼재하는 것이 일반적입니다. `ColumnTransformer`를 사용하면 서로 다른 열에 대해 서로 다른 전처리를 적용할 수 있습니다. ```python from sklearn.compose import ColumnTransformer from sklearn.preprocessing import OneHotEncoder, StandardScaler from sklearn.impute import SimpleImputer from sklearn.pipeline import Pipeline from sklearn.ensemble import RandomForestClassifier import pandas as pd import numpy as np # Mixed data types X = pd.DataFrame({ 'age': [25, 30, 35, 40, np.nan], 'income': [50000, 60000, np.nan, 80000, 90000], 'education': ['bachelor', 'master', 'phd', 'bachelor', 'master'], 'city': ['tokyo', 'osaka', 'tokyo', np.nan, 'osaka'] }) y = np.array([0, 0, 1, 1, 1]) # Define transformers for each column type numeric_features = ['age', 'income'] numeric_transformer = Pipeline([ ('imputer', SimpleImputer(strategy='median')), ('scaler', StandardScaler()) ]) categorical_features = ['education', 'city'] categorical_transformer = Pipeline([ ('imputer', SimpleImputer(strategy='most_frequent')), ('encoder', OneHotEncoder(handle_unknown='ignore', sparse_output=False)) ]) # Combine with ColumnTransformer preprocessor = ColumnTransformer( transformers=[ ('num', numeric_transformer, numeric_features), ('cat', categorical_transformer, categorical_features) ], remainder='drop' # Drop columns not specified ) # Full pipeline with model full_pipeline = Pipeline([ ('preprocessor', preprocessor), ('classifier', RandomForestClassifier(n_estimators=100, random_state=42)) ]) full_pipeline.fit(X, y) print(f"Feature names: {full_pipeline.named_steps['preprocessor'].get_feature_names_out()}") ``` `ColumnTransformer`의 `remainder` 파라미터는 중요합니다. `'drop'`은 지정되지 않은 열을 삭제하고, `'passthrough'`는 변환 없이 유지합니다. 프로덕션 환경에서는 명시적으로 처리할 열을 지정하고, 예상치 못한 열이 포함될 경우 오류를 발생시키는 것이 권장됩니다. ## 커스텀 Transformer 생성 Scikit-Learn의 내장 변환기로는 대응할 수 없는 전처리 로직이 필요한 경우, 커스텀 Transformer를 생성합니다. `BaseEstimator`와 `TransformerMixin`을 상속하여 Pipeline 호환 클래스를 만들 수 있습니다. ```python from sklearn.base import BaseEstimator, TransformerMixin import numpy as np import pandas as pd class OutlierClipper(BaseEstimator, TransformerMixin): """Clip outliers using IQR method.""" def __init__(self, factor=1.5): self.factor = factor self.lower_bounds_ = None self.upper_bounds_ = None def fit(self, X, y=None): X_array = np.asarray(X) q1 = np.percentile(X_array, 25, axis=0) q3 = np.percentile(X_array, 75, axis=0) iqr = q3 - q1 self.lower_bounds_ = q1 - self.factor * iqr self.upper_bounds_ = q3 + self.factor * iqr return self def transform(self, X): X_array = np.asarray(X).copy() X_clipped = np.clip(X_array, self.lower_bounds_, self.upper_bounds_) return X_clipped # Usage in pipeline from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler from sklearn.linear_model import Ridge X = np.array([[1, 100], [2, 200], [3, 150], [100, 180], [5, 170]]) # 100 is outlier y = np.array([10, 20, 15, 18, 17]) pipeline = Pipeline([ ('outlier_clipper', OutlierClipper(factor=1.5)), ('scaler', StandardScaler()), ('regressor', Ridge()) ]) pipeline.fit(X, y) print(f"Coefficients: {pipeline.named_steps['regressor'].coef_}") ``` 커스텀 Transformer를 생성할 때 중요한 점은 `fit` 메서드에서 학습한 파라미터(이 예시에서는 `lower_bounds_`와 `upper_bounds_`)를 인스턴스 변수로 저장하는 것입니다. 이를 통해 훈련 데이터에서 학습한 통계량이 테스트 데이터에도 적용됩니다. ## 하이퍼파라미터 튜닝과 GridSearchCV Pipeline의 큰 장점 중 하나는 전처리 파라미터와 모델의 하이퍼파라미터를 동시에 최적화할 수 있다는 것입니다. `GridSearchCV`나 `RandomizedSearchCV`와 결합하여 최적의 설정을 효율적으로 탐색할 수 있습니다. ```python from sklearn.model_selection import GridSearchCV from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler from sklearn.decomposition import PCA from sklearn.svm import SVC from sklearn.datasets import make_classification # Generate sample data X, y = make_classification(n_samples=1000, n_features=20, n_informative=10, n_redundant=5, random_state=42) # Pipeline with PCA and SVM pipeline = Pipeline([ ('scaler', StandardScaler()), ('pca', PCA()), ('svm', SVC()) ]) # Parameter grid using step__parameter notation param_grid = { 'pca__n_components': [5, 10, 15], 'svm__C': [0.1, 1, 10], 'svm__kernel': ['rbf', 'linear'], 'svm__gamma': ['scale', 'auto'] } # Grid search with cross-validation grid_search = GridSearchCV( pipeline, param_grid, cv=5, scoring='accuracy', n_jobs=-1, verbose=1 ) grid_search.fit(X, y) print(f"Best parameters: {grid_search.best_params_}") print(f"Best cross-validation score: {grid_search.best_score_:.4f}") ``` 파라미터 이름은 `단계명__파라미터명` 형식으로 지정합니다. 이 예시에서 `pca__n_components`는 PCA 단계의 `n_components` 파라미터를 가리킵니다. 중첩된 Pipeline(ColumnTransformer 내의 Pipeline 등)에서는 `preprocessor__num__imputer__strategy`처럼 여러 언더스코어로 경로를 지정합니다. ## 특성 선택과 Pipeline 특성 선택은 모델 성능 향상과 해석성 개선에 중요합니다. Scikit-Learn은 여러 특성 선택 기법을 제공하며, Pipeline에 포함시킴으로써 교차 검증 중 데이터 누수를 방지할 수 있습니다. ```python from sklearn.feature_selection import SelectKBest, f_classif, RFE from sklearn.ensemble import RandomForestClassifier from sklearn.pipeline import Pipeline from sklearn.model_selection import cross_val_score from sklearn.datasets import make_classification # Generate data with informative and noise features X, y = make_classification(n_samples=500, n_features=30, n_informative=10, n_redundant=5, n_classes=2, random_state=42) # Method 1: Filter-based selection (SelectKBest) filter_pipeline = Pipeline([ ('selector', SelectKBest(score_func=f_classif, k=10)), ('classifier', RandomForestClassifier(n_estimators=100, random_state=42)) ]) # Method 2: Wrapper-based selection (RFE) rfe_pipeline = Pipeline([ ('selector', RFE(estimator=RandomForestClassifier(n_estimators=50, random_state=42), n_features_to_select=10, step=5)), ('classifier', RandomForestClassifier(n_estimators=100, random_state=42)) ]) # Compare methods for name, pipeline in [('Filter', filter_pipeline), ('RFE', rfe_pipeline)]: scores = cross_val_score(pipeline, X, y, cv=5, scoring='accuracy') print(f"{name}: {scores.mean():.4f} (+/- {scores.std() * 2:.4f})") ``` 특성 선택을 Pipeline 외부에서 수행하면 테스트 데이터의 정보가 훈련 과정에 누수될 수 있습니다. Pipeline 내에 포함시킴으로써 각 교차 검증 폴드에서 독립적으로 특성 선택이 수행되어 일반화 성능의 정확한 추정이 가능해집니다. ## 면접에서 자주 출제되는 질문과 답변 2026년 머신러닝 엔지니어 면접에서는 Pipeline에 관한 실무적 지식이 평가됩니다. 다음은 자주 출제되는 질문과 답변입니다. **Q1: Pipeline을 사용하는 주요 장점은 무엇입니까? 사용하지 않는 경우와 비교해 설명하십시오.** Pipeline의 주요 장점은 세 가지입니다. 첫째, **데이터 누수 방지**입니다. 전처리 파라미터(예: 표준화의 평균과 표준편차)가 훈련 데이터에서만 학습되고, 테스트 데이터에는 적용만 된다는 것이 보장됩니다. Pipeline 없이는 개발자가 수동으로 이를 관리해야 하며, 실수로 테스트 데이터에서 `fit_transform`을 호출하는 오류가 발생하기 쉽습니다. 둘째, **코드의 간결성과 재사용성**입니다. 전처리와 모델이 단일 객체로 캡슐화되어 프로덕션 배포가 간소화됩니다. 셋째, **하이퍼파라미터의 일괄 최적화**입니다. `GridSearchCV`와 결합하여 전처리 파라미터와 모델 파라미터를 동시에 최적화할 수 있습니다. **Q2: `fit_transform`과 `fit`+`transform`의 차이점은 무엇입니까? 언제 구분해서 사용합니까?** `fit_transform`은 `fit`과 `transform`을 연속으로 실행하는 편의 메서드로, 일부 Transformer에서는 계산 효율을 위해 최적화되어 있습니다. 예를 들어, PCA에서는 `fit_transform`이 `fit`과 `transform`을 별도로 호출하는 것보다 빠릅니다. 구분해서 사용하는 기준으로는, 훈련 데이터에는 `fit_transform`을 사용하고, 테스트 데이터에는 `transform`만 사용합니다. Pipeline을 사용하는 경우 이 구분은 자동으로 처리되므로 수동으로 관리할 필요가 없습니다. 면접에서는 "테스트 데이터에 `fit_transform`을 사용하면 어떻게 되는가"라는 질문이 자주 나옵니다. 답변은, 테스트 데이터의 통계량이 전처리에 사용되어 훈련 데이터와 테스트 데이터에 서로 다른 변환이 적용되므로 모델의 일반화 성능을 올바르게 평가할 수 없게 됩니다. **Q3: ColumnTransformer에서 `remainder='passthrough'`와 `remainder='drop'`의 차이점은 무엇입니까? 프로덕션 환경에서는 어느 것을 권장합니까?** `remainder='passthrough'`는 명시적으로 지정되지 않은 열을 변환 없이 그대로 출력에 포함시킵니다. `remainder='drop'`은 지정되지 않은 열을 삭제합니다. 프로덕션 환경에서는 `remainder='drop'`을 권장합니다. 이유는 데이터 스키마가 변경된 경우(예: 새로운 열이 추가된 경우) `passthrough`에서는 예상치 못한 열이 모델에 입력되어 예측 결과에 영향을 미칠 수 있기 때문입니다. `drop`을 사용하면 예상 외의 열은 자동으로 무시되어 모델의 동작이 안정됩니다. 다만 개발 단계에서는 `passthrough`를 사용하여 모든 특성의 영향을 평가하는 것이 유용할 수 있습니다. **Q4: 커스텀 Transformer를 생성할 때 상속해야 할 클래스는 무엇입니까? 각 클래스의 역할을 설명하십시오.** 커스텀 Transformer는 `BaseEstimator`와 `TransformerMixin` 모두를 상속합니다. `BaseEstimator`는 `get_params`와 `set_params` 메서드를 제공하며, 이를 통해 하이퍼파라미터의 조회와 설정이 가능해집니다. `GridSearchCV` 등의 메타 추정기는 이러한 메서드를 사용하여 파라미터를 조작합니다. `TransformerMixin`은 `fit_transform` 메서드를 제공하며, 이는 `fit`과 `transform`을 연속으로 호출하는 편의 메서드입니다. 개발자는 `fit`과 `transform` 메서드만 구현하면 `fit_transform`은 자동으로 사용 가능해집니다. 또한 `__init__` 메서드에서는 모든 파라미터를 동일한 이름의 인스턴스 변수로 저장해야 합니다. 이는 `get_params`가 올바르게 동작하기 위해 필요합니다. **Q5: Pipeline에서 메모리 캐시를 사용하는 방법과 장점을 설명하십시오.** Pipeline의 `memory` 파라미터에 캐시 디렉토리를 지정하여 변환 결과를 캐시할 수 있습니다. ```python from sklearn.pipeline import Pipeline from tempfile import mkdtemp cachedir = mkdtemp() pipeline = Pipeline([ ('expensive_transform', SomeExpensiveTransformer()), ('model', SomeModel()) ], memory=cachedir) ``` 이를 통해 동일한 데이터와 동일한 파라미터로 `fit`이 호출된 경우 캐시된 결과가 재사용됩니다. 주요 장점은 하이퍼파라미터 튜닝 중 계산 시간 단축입니다. 예를 들어 모델 파라미터만 변경하는 경우 전처리 단계의 결과는 캐시에서 읽어옵니다. 주의할 점으로, 캐시는 디스크 용량을 소비하므로 대규모 데이터셋에서는 적절한 정리가 필요합니다. ## 프로덕션 환경에서의 Pipeline 배포 프로덕션 환경에서는 학습된 Pipeline을 직렬화하여 저장하고 추론 시 불러와야 합니다. `joblib`은 NumPy 배열을 포함한 객체의 효율적인 직렬화를 제공합니다. ```python import joblib from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler from sklearn.ensemble import GradientBoostingClassifier import numpy as np # Train pipeline X_train = np.random.randn(1000, 10) y_train = np.random.randint(0, 2, 1000) pipeline = Pipeline([ ('scaler', StandardScaler()), ('classifier', GradientBoostingClassifier(n_estimators=100, random_state=42)) ]) pipeline.fit(X_train, y_train) # Save trained pipeline joblib.dump(pipeline, 'model_pipeline.joblib') # Load and predict (in production) loaded_pipeline = joblib.load('model_pipeline.joblib') X_new = np.random.randn(5, 10) predictions = loaded_pipeline.predict(X_new) print(f"Predictions: {predictions}") ``` 프로덕션 환경에서는 모델의 버전 관리도 중요합니다. 파일 이름에 버전 번호나 타임스탬프를 포함시켜 롤백이 가능하도록 합니다. 또한 [머신러닝](/technologies/machine-learning) 모범 사례로서 모델의 메타데이터(학습 일시, 사용한 데이터셋, 평가 지표 등)를 별도 파일에 저장하는 것이 권장됩니다. [Python](/technologies/python)에서의 데이터 처리 기술은 효과적인 Pipeline 구축에 필수적입니다. [데이터 사이언스](/technologies/data-science) 실무에서는 Pipeline을 사용하여 재현 가능한 실험을 수행하고 프로덕션 환경으로의 전환을 원활하게 진행하는 것이 요구됩니다. ## 요약: Pipeline으로 머신러닝 워크플로우 최적화 Scikit-Learn Pipeline은 머신러닝 워크플로우를 효율화하고 재현성을 확보하기 위한 중요한 도구입니다. 2026년 머신러닝 엔지니어 면접에서는 Pipeline에 대한 실무 지식이 자주 평가됩니다. 본 글에서 학습한 주요 포인트: - **기본 구조**: Pipeline은 변환기와 추정기를 순서대로 연결하여 데이터 누수를 자동으로 방지합니다 - **ColumnTransformer**: 서로 다른 데이터 타입에 대해 서로 다른 전처리를 적용하여 복잡한 데이터셋을 효율적으로 처리합니다 - **커스텀 Transformer**: `BaseEstimator`와 `TransformerMixin`을 상속하여 도메인 특화 전처리 로직을 구현합니다 - **하이퍼파라미터 튜닝**: `GridSearchCV`와 결합하여 전처리와 모델 파라미터를 동시에 최적화합니다 - **프로덕션 배포**: `joblib`으로 Pipeline을 직렬화하여 추론 환경에서 재사용합니다 Pipeline을 효과적으로 활용함으로써 머신러닝 프로젝트의 품질과 유지보수성이 크게 향상됩니다. 면접 대비로서도 Pipeline의 개념과 모범 사례를 깊이 이해하는 것이 2026년 머신러닝 엔지니어 직군에서 중요한 차별화 요소가 됩니다. --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/ko/blog/data-science/scikit-learn-pipelines-feature-engineering-interview-2026