2.1.5 · D2Data Preprocessing & Feature Engineering

Visual walkthrough — Min-max scaling and z-score normalization

2,340 words11 min readBack to topic

You have a bunch of numbers — heights, prices, ages. They live wherever their units put them: prices in the thousands, ages in the tens. Machine learning algorithms hate that. This page builds, picture by picture, the two transformations that fix it: min-max scaling and z-score normalization. We start from a blank number line and earn every symbol before we use it.


Step 1 — Put the raw numbers on a line

WHAT. Before any formula, just drop our example data onto a number line. We will use two datasets throughout: ages [20, 25, 30, 35, 40] and test scores [60, 70, 80, 90, 100].

WHY. You cannot scale what you cannot see. Every transformation below is just sliding and stretching this line. Seeing the raw spread first makes "slide" and "stretch" concrete instead of abstract.

PICTURE. Each dot is one data value. Notice the two things a ruler needs to know: where the leftmost dot sits and where the rightmost dot sits — call them (the smallest value) and (the largest value).

Figure — Min-max scaling and z-score normalization

Step 2 — What kind of transformation are we even allowed?

WHAT. We restrict ourselves to a linear transformation: a rule of the form

Here is one raw value, is a number that stretches or shrinks the whole line, and is a number that slides the whole line left or right.

WHY this shape and not something curvy? Because we want to rescale the data without distorting it — the middle dot must stay in the middle, equal gaps must stay equal gaps. Only "multiply then add" keeps the spacing evenly proportional. A curvy function (like squaring) would bunch some dots and spread others, changing the shape of the data. We do not want that yet.

PICTURE. controls how wide the dots spread; controls where the whole pattern sits. Two knobs, that's it.

Figure — Min-max scaling and z-score normalization

Step 3 — Min-max: choose the two goals, solve for the knobs

WHAT. For min-max scaling we demand exactly two things:

  • the smallest value should land on 0:
  • the largest value should land on 1:

WHY these two? Two goals is exactly enough to pin down two unknowns ( and ). Any more would be over-constrained; any fewer leaves the ruler undecided. And [0, 1] is a friendly target: bounded, interpretable, plays well with sigmoid outputs.

Plug each goal into :

Solve the second line for , then feed it back:

Combine:

PICTURE. Read the final form as a two-move dance: subtract slides the left dot onto 0; divide by the range squeezes the right dot onto 1.

Figure — Min-max scaling and z-score normalization

Step 4 — Watch it work on the ages (numbers, then picture)

WHAT. Apply Step 3's formula to [20, 25, 30, 35, 40]. Here , , range .

WHY it reads this way. The scaled value literally answers "what fraction of the way from min to max am I?" 25 is a quarter of the way → 0.25. 30 is exactly halfway → 0.50. That interpretability is the headline feature of min-max.

PICTURE. Same dots as Step 1, now with the new ruler underneath. The dots didn't move relative to each other — only the labels changed.

Figure — Min-max scaling and z-score normalization

Step 5 — Z-score: swap the goals for "average" and "wobble"

WHAT. Now pick different goals for the same machine. Instead of anchoring to min and max, anchor to two statistics of the whole cloud:

  • the mean — the balance point of the dots (add them up, divide by count ),
  • the standard deviation — the "typical distance a dot sits from ".

We demand:

  • after transforming, the mean should be 0,
  • after transforming, the standard deviation should be 1.

WHY switch anchors? Min and max are set by just two dots — the extremes. If one dot is a freak outlier, it hijacks the whole ruler (we'll see this in Step 7). Mean and standard deviation listen to every dot, so a single outlier moves them only a little. That robustness is the reason z-score exists.

PICTURE. The balance point is where the line would balance on a fingertip; is the half-width of the "typical" band around it.

Figure — Min-max scaling and z-score normalization

Step 6 — Solve for the z-score knobs

WHAT. We are still using the same machine from Step 2, . When we feed it the mean-and-spread goals, the scaled output earns its own traditional name: we write it instead of . So throughout this step, is — same variable, new letter, just the standardized value of one data point.

Mean goal. The average of a transformed line is the transform of the average, so:

Spread goal. Multiplying every value by multiplies the standard deviation by (sliding by doesn't change spread at all). So:

We take the positive root so the order of the dots is preserved (bigger raw value → bigger z). Combine:

WHY divide by specifically? Because has the same units as (dollars, years...). Dividing by cancels the units — the result is a pure count of "how many typical wobbles away from average." That is what makes z comparable across features with different units.

PICTURE. Center the cloud on 0 (subtract ), then use as your new unit ruler-tick.

Figure — Min-max scaling and z-score normalization

Step 7 — The edge case that decides which to use: an outlier

WHAT. Salaries [30000, 35000, 40000, 45000, 200000] — four ordinary values and one giant.

Min-max. , , range .

The four normal salaries are crushed into [0, 0.088] — the outlier stole almost the entire [0,1] budget because it single-handedly sets .

Z-score. , .

The normal salaries keep a visible spread; the outlier is flagged as " std-devs out" rather than swallowing everything.

WHY the difference? Min-max's ruler is nailed to the two extreme dots, so one freak dot warps it entirely. Z-score's ruler is nailed to and , which every dot votes on — one freak dot barely nudges them.

PICTURE. Same salaries under both rulers, so you can see the crushing versus the graceful flagging. (For truly heavy outliers, the next step up is robust scaling.)

Figure — Min-max scaling and z-score normalization

The one-picture summary

WHAT. One figure, both methods, side by side: the raw line at top, and the two rulers it produces below. Left column = min-max (anchors: the extreme dots). Right column = z-score (anchors: mean and spread). Both are the same slide-and-stretch — they just chose different goals.

Figure — Min-max scaling and z-score normalization

This scaling step feeds directly into gradient descent, PCA, and (inside networks) batch normalization — all of which assume features live on comparable scales. It sits alongside data cleaning and encoding in the preprocessing pipeline.

Recall Feynman retelling — say it back in plain words

We had numbers scattered on a line, but their units made them incomparable. We decided we're only allowed to slide and stretch the line — multiply by , add — because that rescales without bending the data's shape. Two knobs need two goals to pin them down. Min-max says "make the smallest 0 and the biggest 1," which forces and gives — a fraction telling you how far along you are (and test values outside the training range spill past 0 or 1). Z-score says instead "make the average 0 and the typical wobble 1," which forces and gives — a count of standard deviations from the mean, units cancelled; here is just the scaled variable under a traditional name. Min-max is nailed to the two extreme dots, so one outlier wrecks it; z-score is nailed to statistics every dot votes on, so it shrugs outliers off. If all values are equal, both blow up (divide by zero) — that feature is dead weight anyway. And always learn your ruler on training data, then reuse it — never re-measure on the test set.

Recall

What does the numerator do in min-max scaling? ::: Slides the line so the minimum lands on 0. Why divide by in z-score? ::: It cancels the units, turning the value into a pure count of standard deviations. In z-score, what is the relationship between and ? ::: They are the same thing — is just the traditional name for the scaled (standardized) value. Do we divide by or for in feature scaling? ::: By (population form, matching StandardScaler); the choice barely matters as long as you stay consistent. What happens to a test value that lies outside the training range under min-max? ::: It maps outside [0, 1] — below 0 if under , above 1 if over . Why does an outlier break min-max but not z-score? ::: Min-max is anchored to the two extreme dots (one outlier sets ); z-score is anchored to which every dot influences only slightly. What goes wrong if all values are identical? ::: and , so both formulas divide by zero.