Scikit-Learn Pipeline 2026: Panduan Feature Engineering dan Pertanyaan Interview

Kuasai scikit-learn pipeline dengan ColumnTransformer untuk feature engineering. Pelajari praktik terbaik preprocessing, hindari data leakage, dan persiapkan interview machine learning dengan contoh kode praktis.

Scikit-Learn Pipeline 2026: Panduan Feature Engineering dan Pertanyaan Interview

Scikit-learn pipeline mengubah kode preprocessing yang berantakan menjadi workflow yang reproducible dan siap produksi. Dengan versi 1.9 yang dirilis pada Juni 2026, Pipeline dan ColumnTransformer tetap menjadi fondasi setiap proyek machine learning serius, kini dengan callback monitoring, visualisasi HTML yang ditingkatkan, dan dukungan Array API.

Interview Insight

Pewawancara sering bertanya: "Bagaimana cara mencegah data leakage selama cross-validation?" Jawabannya adalah pipeline. Melakukan fitting preprocessing steps di dalam CV loop memastikan data test tidak pernah mempengaruhi keputusan scaling atau encoding.

Mengapa Pipeline Menghilangkan Data Leakage

Data leakage terjadi ketika informasi dari test set mempengaruhi preprocessing. Kesalahan umum: melakukan fitting StandardScaler pada seluruh dataset sebelum splitting. Scaler mempelajari mean dan variance dari sampel test, sehingga menggelembungkan skor cross-validation.

Pipeline memperbaiki masalah ini dengan merangkai transformer dan estimator menjadi satu objek yang melakukan fit semua langkah secara bersamaan:

python
# pipeline_basics.py
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score

# Create a pipeline that scales features and trains a classifier
pipeline = Pipeline([
    ('scaler', StandardScaler()),  # Step 1: Normalize features
    ('classifier', LogisticRegression(max_iter=1000))  # Step 2: Train model
])

# cross_val_score fits the scaler separately for each fold
# No data leakage: test fold is never seen during scaler.fit()
scores = cross_val_score(pipeline, X, y, cv=5, scoring='accuracy')
print(f"Mean accuracy: {scores.mean():.3f} (+/- {scores.std():.3f})")

Objek Pipeline mengimplementasikan fit, predict, dan score, membuatnya dapat dipertukarkan dengan estimator scikit-learn mana pun. Ini berarti GridSearchCV, RandomizedSearchCV, dan semua utilitas cross-validation bekerja tanpa modifikasi.

ColumnTransformer untuk Tipe Data Campuran

Dataset nyata berisi kolom numerik (usia, gaji) dan kolom kategorikal (negara, tipe_produk). ColumnTransformer menerapkan preprocessing berbeda ke subset kolom yang berbeda, kemudian menggabungkan hasilnya:

python
# column_transformer_example.py
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline
import pandas as pd

# Sample dataset with mixed types
df = pd.DataFrame({
    'age': [25, 30, None, 45],
    'salary': [50000, 60000, 75000, None],
    'country': ['US', 'UK', 'DE', 'US'],
    'education': ['Bachelor', 'Master', 'PhD', 'Bachelor']
})

# Define numeric preprocessing: impute missing values, then scale
numeric_transformer = Pipeline([
    ('imputer', SimpleImputer(strategy='median')),
    ('scaler', StandardScaler())
])

# Define categorical preprocessing: impute with mode, then one-hot encode
categorical_transformer = Pipeline([
    ('imputer', SimpleImputer(strategy='most_frequent')),
    ('encoder', OneHotEncoder(handle_unknown='ignore', sparse_output=False))
])

# Combine transformers with ColumnTransformer
preprocessor = ColumnTransformer(
    transformers=[
        ('num', numeric_transformer, ['age', 'salary']),
        ('cat', categorical_transformer, ['country', 'education'])
    ],
    verbose_feature_names_out=True  # Prefix output names with transformer name
)

# Fit and inspect output shape
X_transformed = preprocessor.fit_transform(df)
print(f"Transformed shape: {X_transformed.shape}")
print(f"Feature names: {preprocessor.get_feature_names_out()}")

Parameter verbose_feature_names_out (yang ditingkatkan pada versi 1.6 untuk menerima string dan callable) mengontrol penamaan output feature. Mengaturnya ke True akan menambahkan prefix nama transformer pada setiap feature, mencegah tabrakan nama ketika beberapa transformer menghasilkan nama kolom yang serupa.

Mengotomatisasi Pemilihan Kolom dengan make_column_selector

Menuliskan nama kolom secara hardcode akan rusak ketika dataset berubah. make_column_selector memilih kolom berdasarkan dtype secara otomatis:

python
# automatic_column_selection.py
from sklearn.compose import ColumnTransformer, make_column_selector
from sklearn.preprocessing import StandardScaler, OneHotEncoder

# Select columns by dtype: no hardcoded column names
preprocessor = ColumnTransformer(
    transformers=[
        ('num', StandardScaler(), make_column_selector(dtype_include='number')),
        ('cat', OneHotEncoder(handle_unknown='ignore'),
         make_column_selector(dtype_include='object'))
    ],
    remainder='passthrough'  # Keep unprocessed columns as-is
)

# Works with any DataFrame that has numeric and object columns
X_processed = preprocessor.fit_transform(df)

Parameter remainder mengontrol apa yang terjadi pada kolom yang tidak cocok dengan transformer mana pun. Pilihannya termasuk 'drop' (default), 'passthrough' (simpan tanpa perubahan), atau transformer untuk diterapkan pada kolom yang tersisa.

Siap menguasai wawancara Data Science & ML Anda?

Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.

Feature Engineering di Dalam Pipeline

Pipeline melampaui preprocessing untuk mencakup langkah-langkah feature engineering. Transformer kustom mewarisi dari BaseEstimator dan TransformerMixin:

python
# custom_transformer.py
from sklearn.base import BaseEstimator, TransformerMixin
import numpy as np

class DateFeatureExtractor(BaseEstimator, TransformerMixin):
    """Extract year, month, day, and weekday from datetime columns."""
    
    def __init__(self, date_column='date'):
        self.date_column = date_column
    
    def fit(self, X, y=None):
        # No fitting required for date extraction
        return self
    
    def transform(self, X):
        X = X.copy()
        dates = pd.to_datetime(X[self.date_column])
        
        # Extract temporal features
        X['year'] = dates.dt.year
        X['month'] = dates.dt.month
        X['day'] = dates.dt.day
        X['weekday'] = dates.dt.weekday
        X['is_weekend'] = (dates.dt.weekday >= 5).astype(int)
        
        # Drop original date column
        return X.drop(columns=[self.date_column])
    
    def get_feature_names_out(self, input_features=None):
        # Required for Pipeline.get_feature_names_out() to work
        return ['year', 'month', 'day', 'weekday', 'is_weekend']

# Integrate into a full pipeline
full_pipeline = Pipeline([
    ('date_features', DateFeatureExtractor(date_column='signup_date')),
    ('preprocessor', preprocessor),
    ('model', LogisticRegression())
])

Mengimplementasikan get_feature_names_out memungkinkan representasi HTML baru di scikit-learn 1.9 untuk menampilkan nama output feature, membuat debugging dan dokumentasi lebih mudah.

Hyperparameter Tuning di Seluruh Langkah Pipeline

GridSearchCV melakukan tuning parameter di semua langkah pipeline menggunakan konvensi penamaan step__parameter:

python
# pipeline_gridsearch.py
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier

# Build pipeline with tunable components
pipeline = Pipeline([
    ('preprocessor', preprocessor),
    ('classifier', RandomForestClassifier(random_state=42))
])

# Define parameter grid: note the double underscore syntax
param_grid = {
    'preprocessor__num__imputer__strategy': ['mean', 'median'],
    'classifier__n_estimators': [100, 200],
    'classifier__max_depth': [10, 20, None]
}

# GridSearchCV handles all combinations automatically
grid_search = GridSearchCV(
    pipeline,
    param_grid,
    cv=5,
    scoring='f1_weighted',
    n_jobs=-1
)

grid_search.fit(X_train, y_train)
print(f"Best params: {grid_search.best_params_}")
print(f"Best score: {grid_search.best_score_:.3f}")

Double underscore (__) mengakses parameter bersarang. Untuk ColumnTransformer, path menyertakan nama transformer: preprocessor__num__imputer__strategy menjangkau parameter strategy imputer di dalam numeric transformer.

Caching Transformer dengan Parameter memory

Preprocessing kompleks pada dataset besar bisa lambat. Parameter memory meng-cache fitted transformer ke disk:

python
# cached_pipeline.py
from sklearn.pipeline import Pipeline
from tempfile import mkdtemp
import joblib

# Create a cache directory
cachedir = mkdtemp()

# Pipeline caches intermediate steps
cached_pipeline = Pipeline(
    [
        ('preprocessor', preprocessor),  # Cached after first fit
        ('classifier', RandomForestClassifier())
    ],
    memory=cachedir  # Or use joblib.Memory for more control
)

# First fit: slow (computes all transformations)
cached_pipeline.fit(X_train, y_train)

# Second fit with same X_train: fast (loads cached transformers)
cached_pipeline.fit(X_train, y_train)  # Skips preprocessor fitting

Caching sangat berguna selama hyperparameter search, di mana preprocessing yang sama diterapkan ke beberapa konfigurasi model. Estimator akhir (classifier atau regressor) tidak pernah di-cache, hanya transformer intermediate.

Monitoring Training dengan Callback (scikit-learn 1.9)

Callback API di versi 1.9 menambahkan progress monitoring ke pipeline:

python
# callback_monitoring.py
from sklearn.callback import ProgressBar, ScoringMonitor
from sklearn.linear_model import LogisticRegression

# Display progress during GridSearchCV
with ProgressBar():
    grid_search = GridSearchCV(
        pipeline,
        param_grid,
        cv=5,
        n_jobs=1  # Progress bars require single-threaded execution
    )
    grid_search.fit(X_train, y_train)

# Monitor scoring metrics per iteration
with ScoringMonitor(X_val, y_val, scoring='accuracy') as monitor:
    logreg = LogisticRegression(solver='lbfgs', max_iter=500)
    logreg.fit(X_train, y_train)
    print(f"Scores per iteration: {monitor.scores_}")

Callback bekerja dengan Pipeline, StandardScaler, LogisticRegression (solver LBFGS), dan semua kelas search CV. Fitur eksperimental ini memberikan visibilitas ke dalam fit yang berjalan lama tanpa kode logging kustom.

FeatureUnion untuk Ekstraksi Fitur Paralel

FeatureUnion menjalankan beberapa transformer secara paralel dan menggabungkan output-nya secara horizontal:

python
# feature_union_example.py
from sklearn.pipeline import FeatureUnion, Pipeline
from sklearn.decomposition import PCA
from sklearn.feature_selection import SelectKBest, f_classif

# Combine PCA and univariate selection
feature_union = FeatureUnion([
    ('pca', PCA(n_components=5)),
    ('select', SelectKBest(f_classif, k=10))
])

# Pipeline: preprocess, combine features, classify
pipeline = Pipeline([
    ('preprocessor', preprocessor),
    ('features', feature_union),
    ('classifier', LogisticRegression())
])

# Output contains 5 PCA components + 10 selected features = 15 features
pipeline.fit(X_train, y_train)

Versi 1.7.2 menambahkan validasi yang memastikan semua transformer mengembalikan output 2D. Ini menangkap error lebih awal ketika transformer kustom secara tidak sengaja mengembalikan array 1D.

Serialisasi dan Deployment

Pipeline melakukan serialisasi dengan joblib, menyimpan semua parameter yang telah di-fit:

python
# model_deployment.py
import joblib

# Save the entire pipeline (preprocessing + model)
joblib.dump(pipeline, 'churn_predictor.pkl')

# Load in production
loaded_pipeline = joblib.load('churn_predictor.pkl')

# Predict on new data (same preprocessing automatically applied)
new_data = pd.DataFrame({'age': [32], 'salary': [65000], ...})
predictions = loaded_pipeline.predict(new_data)

File yang diserialisasi berisi segalanya: logika column selector, mean dan variance scaler yang telah di-fit, kategori encoder, dan bobot model. Deployment hanya memerlukan scikit-learn dan joblib, tanpa kode preprocessing kustom.

Kompatibilitas Versi

Pipeline yang diserialisasi dengan scikit-learn 1.8 mungkin tidak dapat dimuat dengan benar pada 1.9 jika menggunakan parameter yang deprecated. Selalu pin versi scikit-learn di production dan uji upgrade sebelum melakukan deploy.

Pertanyaan Interview tentang Scikit-Learn Pipeline

Q: Apa itu data leakage dan bagaimana pipeline mencegahnya?

Data leakage terjadi ketika informasi dari validation atau test set mempengaruhi training model. Contoh klasik: melakukan fitting StandardScaler pada seluruh dataset sebelum splitting. Mean dan standard deviation scaler menyertakan sampel test, membuat skor cross-validation menjadi tinggi secara artifisial.

Pipeline mencegah ini dengan mengenkapsulasi preprocessing di dalam loop cross-validation. Ketika cross_val_score memanggil pipeline.fit(), setiap fold melakukan fit scaler hanya pada data training. Statistik test fold tidak pernah bocor ke preprocessing.

Q: Bagaimana cara mengakses dan memodifikasi parameter dari nested pipeline steps?

Gunakan sintaks double underscore: pipeline.set_params(classifier__n_estimators=200). Untuk ColumnTransformer, sertakan nama transformer: pipeline.set_params(preprocessor__num__scaler__with_mean=False). Method get_params() mengembalikan semua parameter bersarang sebagai dictionary flat, berguna untuk inspeksi dan logging.

Q: Kapan sebaiknya menggunakan FeatureUnion vs ColumnTransformer?

ColumnTransformer menerapkan transformer berbeda ke kolom berbeda dari input yang sama. FeatureUnion menerapkan transformer berbeda ke seluruh input dan menggabungkan secara horizontal. Gunakan ColumnTransformer untuk preprocessing kolom heterogen (numerik vs kategorikal). Gunakan FeatureUnion untuk feature augmentation, di mana beberapa metode ekstraksi (PCA, polynomial features, domain-specific extractors) menghasilkan fitur komplementer dari data yang sama.

Q: Bagaimana cara debug pipeline yang gagal?

Atur verbose=True pada pipeline untuk melihat timing langkah. Akses hasil intermediate dengan pipeline.named_steps['step_name'].transform(X) untuk pipeline yang sudah di-fit. Di scikit-learn 1.9, representasi HTML menampilkan atribut yang telah di-fit dan nama output feature, menyederhanakan debugging di Jupyter notebook. Untuk inspeksi lebih dalam, gunakan pipeline[:-1].fit_transform(X, y) untuk mendapatkan output tepat sebelum estimator akhir.

Checklist Production untuk ML Pipeline

  • Pin versi scikit-learn di requirements untuk menghindari masalah serialisasi
  • Gunakan make_column_selector daripada nama kolom hardcoded ketika dataset mungkin berubah
  • Set handle_unknown='ignore' pada OneHotEncoder untuk menangani kategori baru di production
  • Cache preprocessing yang mahal dengan parameter memory selama development
  • Validasi output shape dan nama feature pipeline dalam test sebelum deployment
  • Simpan get_feature_names_out() bersama model untuk analisis feature importance
  • Gunakan Pipeline di dalam GridSearchCV, jangan sebaliknya, untuk memastikan perilaku CV yang benar

Mulai berlatih!

Uji pengetahuan Anda dengan simulator wawancara dan tes teknis kami.

Tantangan harian

Bisakah kamu menemukan bug di Data Science & ML?

Satu potongan kode nyata, satu bug tersembunyi, satu percobaan per hari. Tanpa akun untuk mencoba.

Anthony Fillion-Maillet

Ditulis oleh

Anthony Fillion-Maillet

Pendiri SharpSkill

Developer fullstack selama lebih dari 10 tahun. Ia menjalankan SharpSkill dan bertanggung jawab atas semua yang diterbitkan di sini.

Diperbarui 2 September 2026

Bagikan

Artikel terkait