Skip to content
Machine Learning
Regression 8 min read

Feature Scaling & Transforms

Put features on a common scale with StandardScaler, MinMaxScaler, and RobustScaler, and tame skewed distributions with log and power transforms.

Download notebook Open Google ColabIn Colab: File → Upload notebook → pick the downloaded file.

A dataset rarely arrives ready for modeling: one column measures age (20–70), another income (thousands to millions), a third is skewed so hard that 95% of values huddle near zero. Many algorithms quietly assume features live on comparable scales — and misbehave when they don't. This lesson covers why scaling matters, which scaler to use when, and how power transforms fix skewed distributions — plus the one mistake (fitting scalers on test data) that silently invalidates your results.

Why scale at all?

Three concrete reasons:

  1. Gradient descent converges better. Remember in the linear-regression lesson how b learned slower than w? With features of wildly different magnitudes, the loss surface becomes a long, narrow valley: the gradient is steep in one direction and nearly flat in another, so a learning rate that's safe for one weight is glacial for another. Scaling rounds the valley into a bowl, and the same steps reach the bottom far faster.
  2. Distance-based models need it. KNN, K-Means, and SVMs compare points by distance. If income ranges over millions and age over decades, distance is effectively just income — age becomes invisible.
  3. Regularization must be fair. The next lesson penalizes large weights. But a feature measured in millimeters needs a coefficient 1000× larger than the same feature in meters — penalizing raw coefficient size across unscaled features punishes features for their units, not their usefulness.

(Tree-based models are the notable exception — they split on thresholds and don't care about scale.)

Three scalers, one outlier

scikit-learn's big three:

  • StandardScaler — subtract the mean, divide by the standard deviation. Result: mean 0, std 1. The default choice, best when data is roughly bell-shaped.
  • MinMaxScaler — shift the minimum to 0, stretch the maximum to 1. Intuitive bounded range, but one outlier squeezes everyone else into a tiny sliver.
  • RobustScaler — subtract the median, divide by the interquartile range (IQR). Quantiles barely move when an outlier appears, so it's the scaler of choice for contaminated data.

Watch how a single outlier affects each:

Python — runs in your browser

Look at the MinMax row in the dirty block: the outlier grabbed max = 1.0 for itself and crushed all 200 real points below ~0.1 — most of the scale is wasted on one bad value. StandardScaler suffered too (the outlier inflated the std, shrinking everyone). RobustScaler's output is nearly identical in both blocks — the median and IQR barely noticed.

Skewed data: transform before (or instead of) scaling

Scaling shifts and stretches, but it can't change a distribution's shape. Income, prices, trip distances — many real features are right-skewed: a heavy pile near zero and a long tail. Linear models and standardization both work better when values are roughly symmetric. The fix is a nonlinear transform:

  • log — the classic for positive right-skewed data (np.log1p handles zeros).
  • Box-Cox — a family of power transforms that learns the best exponent; requires strictly positive data.
  • Yeo-Johnson — Box-Cox's sibling that also accepts zero and negative values. scikit-learn's PowerTransformer default.
Python — runs in your browser

The raw histogram slumps against zero with a long tail; all three transforms produce a much more symmetric bell. PowerTransformer even standardizes the output for you (mean 0, std 1) by default, so it often replaces the scaler entirely for skewed columns. This works on targets too — if y is skewed (like the taxi fares in this module's exercises), modeling log(y) often fixes the funnel-shaped residual plots you learned to spot in lesson 1.

QuantileTransformer, briefly: it maps values to their quantiles, forcing any distribution into a uniform (or normal) shape. It's a blunt but effective instrument for very messy features — just know it's non-linear and rank-based, so it distorts distances within the tails.

Fit on train, transform everywhere

Scalers are learned from data — the mean, the min/max, the quantiles are statistics. If you compute them on the full dataset before splitting, information about the test set bleeds into training. That's data leakage, and it makes your evaluation optimistic.

Never fit a scaler on test data

Always: scaler.fit_transform(X_train) then scaler.transform(X_test) — fit on train only, reuse those statistics for the test set. The test set must be processed exactly as truly-new data would be: with statistics it had no part in computing.

The foolproof way to obey this rule is to put the scaler inside a Pipeline. Then fit only ever sees training data, cross-validation re-fits the scaler per fold automatically, and you can't leak even if you try:

Python — runs in your browser

From now on in this course, preprocessing always lives inside the pipeline — it's not just tidier, it's the only leak-proof way to work.

Choosing quickly

Data looks likeUse
Roughly bell-shapedStandardScaler
Need a bounded 0–1 range, no outliers (e.g., pixel values)MinMaxScaler
Contains outliers you can't removeRobustScaler
Right-skewed, strictly positivelog / Box-Cox
Skewed with zeros or negativesYeo-Johnson (PowerTransformer)
Bizarre multi-modal messQuantileTransformer

Check your understanding

4 questions · free
  1. Q1.Why does feature scaling speed up gradient descent?

  2. Q2.Your feature has a few extreme outliers you can't remove. Which scaler distorts the non-outlier points the least?

  3. Q3.You want to power-transform a feature containing negative values. Which method works?

  4. Q4.A colleague fits StandardScaler on the full dataset, then splits into train/test. What's wrong?

Exercise: Does scaling rescue KNN?

Load load_diabetes and deliberately sabotage it: multiply one feature column by 1000 so it dominates all distances. Split into train/test, then fit a KNeighborsRegressor twice — once on the raw sabotaged data, once inside a Pipeline with StandardScaler. Compare test R². Explain in a comment why the unscaled version suffers.

With features on a fair, common scale, we can finally penalize model weights fairly too — next: regularization with Ridge, Lasso, and ElasticNet.