Keep Training and Inference Identical

Preprocessing is part of the model

A preprocessing pipeline packages cleaning and transformation steps so the same learned medians, category vocabulary, scaling, and column order apply during both training and inference. Hand-copying preparation code into a production service invites training-serving skew - a difference between how examples were prepared while learning and how real inputs are prepared later.

from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder

prep = ColumnTransformer([
  ('num', SimpleImputer(strategy='median'), ['age', 'income']),
  ('cat', OneHotEncoder(handle_unknown='ignore'), ['plan']),
])
pipe = Pipeline([('prep', prep), ('model', model)])

Calling pipe.fit(X_train, y_train) fits every learned preprocessing step only on training rows. Calling pipe.predict(X_new) then applies those exact stored transformations before prediction. Saving the pipeline preserves the full inference contract rather than only the final estimator.

Analogy: If a recipe's training kitchen weighs flour in grams, the production kitchen cannot quietly switch to cups and expect identical bread. Package the measuring process with the recipe.
Goal: The existing ml-data-hygiene lab reinforces explicit coercion, defensible imputation, and aligned features rather than a blanket fillna(0) repair.