Features measured in unrelated units can pull a scale-sensitive estimator toward the columns with the largest numeric ranges. StandardScaler in scikit-learn centers each numeric feature around zero and scales it to unit variance so magnitude reflects the data rather than its original unit.
The scaler learns one mean and scale per feature during fit(). Fit those statistics from training rows only, then reuse transform() for held-out and future rows so information outside the training set cannot influence preprocessing.
Standardization does not reduce the influence of outliers, and centering is unsuitable for sparse matrices unless densifying them is acceptable. Mixed numeric and categorical columns normally belong in a ColumnTransformer, while a Pipeline keeps the fitted preprocessing attached to the estimator during cross-validation and prediction.
Steps to standardize features with scikit-learn:
- Create standardize_features.py with named numeric training features and a held-out row.
- standardize_features.py
import numpy as np from sklearn.preprocessing import StandardScaler feature_names = ["age_years", "annual_income", "monthly_visits"] X_train = np.array( [ [22, 38000, 4], [25, 42000, 5], [47, 88000, 7], [52, 92000, 8], [31, 58000, 6], [45, 76000, 7], [28, 54000, 5], [39, 69000, 6], ], dtype=float, ) X_holdout = np.array([[34, 62000, 6]], dtype=float)
Every array uses the same column order. Each row represents one sample, and each column represents one feature.
- Append the scaler fit and transform block to standardize_features.py.
- standardize_features.py
scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) fitted_mean = scaler.mean_.copy() X_holdout_scaled = scaler.transform(X_holdout)
fit_transform() learns from X_train and scales those rows. transform() applies the stored statistics to X_holdout without fitting again.
- Append fail-capable scaling checks and readable output to standardize_features.py.
- standardize_features.py
np.testing.assert_allclose(X_train_scaled.mean(axis=0), 0.0, atol=1e-12) np.testing.assert_allclose(X_train_scaled.std(axis=0), 1.0, atol=1e-12) np.testing.assert_array_equal(scaler.mean_, fitted_mean) def format_values(values): return "[" + ", ".join(f"{value:.3f}" for value in values) + "]" print(f"training rows: {scaler.n_samples_seen_}") print(f"learned means: {format_values(scaler.mean_)}") print(f"learned scales: {format_values(scaler.scale_)}") print(f"scaled training means: {format_values(X_train_scaled.mean(axis=0))}") print(f"scaled training standard deviations: {format_values(X_train_scaled.std(axis=0))}") print(f"scaled holdout row: {format_values(X_holdout_scaled[0])}") print("training statistics unchanged after holdout transform: yes")
The assertions stop the program if the training features are not centered and scaled or if transforming the held-out row changes the fitted means.
- Run standardize_features.py to verify the standardized training and held-out values.
$ python standardize_features.py training rows: 8.0 learned means: [36.125, 64625.000, 6.000] learned scales: [10.446, 18781.224, 1.225] scaled training means: [-0.000, -0.000, 0.000] scaled training standard deviations: [1.000, 1.000, 1.000] scaled holdout row: [-0.203, -0.140, 0.000] training statistics unchanged after holdout transform: yes
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.