Skip to content

AI Agents · Guide

Build a Scikit-learn Training Pipeline

Connect train-only imputation, scaling and a simple classifier in one reproducible pipeline, with a stable feature contract and a baseline.

Metarix Editorial · Nov 8, 2026 · 4 min read

Share

Documentation-based research

On this page

A model is more than its estimator. The transformations that fill missing values, scale inputs or encode categories are part of the system. If training and prediction apply different transformations, a perfectly saved estimator can still produce incorrect results.

In this lesson of the Machine Learning Engineer learning path, you build a small pipeline whose learned steps stay inside the training boundary. The example uses numeric inputs and logistic regression; the same discipline applies when the estimator becomes more complex.

Separate fixed rules from learned transformations

A unit conversion chosen from a specification is a fixed rule. A median estimated from a dataset is learned information. The latter must be fit on training data, then applied unchanged to validation, test and prediction inputs.

Our four features have different units. The pipeline first fills missing measurements with training medians, then standardizes using training statistics, then fits a classifier. Validation and test rows pass through the fitted steps; they do not refit them.

If you perform cross-validation, fit the entire pipeline inside each fold. Fitting a scaler once on all rows before cross-validation lets the validation folds influence preprocessing. The scikit-learn common-pitfalls guide gives examples of this leakage pattern.

Understand the baseline before adding complexity

Logistic regression calculates a weighted combination of features and maps it to a binary-class probability estimate. Despite its name, it is commonly used for classification. Its linear decision structure is a useful starting point, not evidence that every relationship in your problem is linear.

The capstone fixes the model family and regularization setting before evaluating the test data. It also trains a DummyClassifier that returns the training class prior. That baseline helps distinguish learning useful relationships from benefiting from class frequency alone.

Tree-based methods and gradient boosting can be appropriate next candidates. You do not need to learn XGBoost, LightGBM and CatBoost simultaneously before completing one valid project. Choose alternatives for a reason, compare them under the same development protocol, and keep the final test set out of that selection process.

Read the pipeline you are running

The downloaded project trains this structure:

python
model = Pipeline([
    ("imputer", SimpleImputer(strategy="median")),
    ("scale", StandardScaler()),
    ("classifier", LogisticRegression(C=1.0, random_state=17, max_iter=1000)),
])
model.fit(x_train, y_train)

This is an excerpt from ml_capstone.py, not a standalone script: the imports and training arrays are defined there. The pipeline learns medians, scaling statistics and model weights using training rows only. Random seeds help make the example repeatable, while dependency versions and numerical environment also matter.

For mixed numeric and categorical data, a ColumnTransformer can apply different preprocessing to each group. It is worth learning when your dataset needs it. Adding one to this all-numeric fixture would add machinery without teaching a necessary behavior.

Preserve the feature contract

Feature order is part of the interface. A model expecting temperature, vibration, load and pressure cannot safely accept the same values in a different order. The project records feature_order in its exported artifact and validates the names before converting a request into a numeric vector.

Missing values also need a policy. The example permits an individual measurement to be null and imputes it using the training median. It rejects a request where every measurement is missing. In a real system, missingness could itself be informative or require rejecting a request; decide that from the problem, not a library default.

Exercise: inspect what training learned

From the extracted capstone directory, run:

sh
python ml_capstone.py train --out artifacts
python - <<'PY'
import json
from pathlib import Path
model = json.loads(Path("artifacts/model.json").read_text())
print(model["feature_order"])
print(len(model["imputer_medians"]), len(model["coefficients"]))
PY
python -m unittest -v

Expect the four feature names and the pair 4, 4. The tests include checks that imputation and scaling statistics match training rows and that the exported prediction agrees with the fitted scikit-learn pipeline. Passing those checks establishes a property of this implementation, not that the model is useful outside the synthetic fixture.

Explain why the scaler is fit once per training run and why a more complex estimator would not justify fitting preprocessing on all data. You are ready for evaluation when you can identify every step that learns from data and the partition it is allowed to use.

Sources and method

The capstone pipeline and commands were tested locally on Python 3.12.14 and scikit-learn 1.8.0. No third-party dataset or production training service was used.

Share

Keep Reading