iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

scikit-learn API

A clean end-to-end scikit-learn pipeline with column transformers, model selection, calibration, and a saved estimator. The way pros assemble ML pipelines.

scikit-learn — pipeline patterns

EXAMPLE
# ===== Imports =====
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split, StratifiedKFold, GridSearchCV
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import HistGradientBoostingClassifier
from sklearn.calibration import CalibratedClassifierCV
from sklearn.metrics import roc_auc_score, classification_report
import joblib

# ===== Data =====
df = pd.read_csv('churn.csv')
y = df.pop('churned').astype(int).values
X = df

num_cols = X.select_dtypes('number').columns.tolist()
cat_cols = X.select_dtypes('object').columns.tolist()

X_train, X_test, y_train, y_test = train_test_split(
    X, y, stratify=y, test_size=0.2, random_state=42
)

# ===== Pre-processing =====
num_pipe = Pipeline([
    ('imp', SimpleImputer(strategy='median')),
    ('scale', StandardScaler()),
])
cat_pipe = Pipeline([
    ('imp', SimpleImputer(strategy='most_frequent')),
    ('ohe', OneHotEncoder(handle_unknown='ignore', sparse_output=False)),
])
prep = ColumnTransformer([
    ('num', num_pipe, num_cols),
    ('cat', cat_pipe, cat_cols),
])

# ===== Model selection =====
candidates = {
    'logreg': Pipeline([('prep', prep), ('clf', LogisticRegression(max_iter=2000))]),
    'hgb':    Pipeline([('prep', prep), ('clf', HistGradientBoostingClassifier())]),
}

cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)

grid_hgb = GridSearchCV(
    candidates['hgb'],
    param_grid={
        'clf__learning_rate': [0.05, 0.1],
        'clf__max_depth': [None, 6, 8],
        'clf__min_samples_leaf': [20, 50],
    },
    scoring='roc_auc', cv=cv, n_jobs=-1, refit=True,
)
grid_hgb.fit(X_train, y_train)
print('best HGB AUC:', grid_hgb.best_score_, grid_hgb.best_params_)

# ===== Calibration =====
# Tree-ensemble probabilities are over-confident at the edges; calibrate.
best = grid_hgb.best_estimator_
cal = CalibratedClassifierCV(best, method='isotonic', cv=cv)
cal.fit(X_train, y_train)

# ===== Evaluation =====
proba = cal.predict_proba(X_test)[:, 1]
pred  = (proba >= 0.5).astype(int)
print('AUC test:', roc_auc_score(y_test, proba))
print(classification_report(y_test, pred, digits=3))

# ===== Save + load =====
joblib.dump(cal, 'churn.joblib')
loaded = joblib.load('churn.joblib')
# loaded.predict_proba(new_X)[:, 1]

# ===== Patterns to internalise =====
# - One Pipeline end-to-end so prep + model travel together
# - ColumnTransformer over hand-rolled prep loops
# - Stratify on classification splits
# - Score with the metric you optimise for (AUC for ranking, logloss for probabilities)
# - Calibrate probabilities if downstream decisions use the threshold
# - Persist the fitted Pipeline, not just the model

# ===== Pitfalls =====
# - Fitting scaler on the whole dataset before split  -> leakage
# - Using accuracy on imbalanced data  -> misleading
# - GridSearchCV without StratifiedKFold on classification
# - Re-running OneHotEncoder with different categories at predict time
# - Saving the bare model and re-implementing prep at inference

Why it matters

Pipeline + ColumnTransformer + StratifiedKFold + Calibration is the reflex stack. The dataset changes weekly; the shape of this scaffold should not. Once it is muscle memory you spend brainpower on features and labels, not glue code.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
# Everything follows the same API:
model = Estimator(**hyperparams)
model.fit(Xtr, ytr)
model.predict(Xte)
model.score(Xte, yte)
# Transformers expose fit/transform/fit_transform.
Try it Yourself »

Test yourself

Q1. Every estimator implements…
Q2. A Pipeline lets you…
Q3. Hyperparameter search is supported by…

Discussion

Loading…