NeuroNomixer
  • Home
  • Blog
  • Visual Guides
  • Authors
  • Contact
Sign InSign Up
HomeBlogAuthorsContactPrivacy Policy

© 2026 NeuroNomixer — Built with Next.js & Tailwind CSS

Visual Guides/Turning Categories into Numbers
Data & Analysis

Turning Categories into Numbers

Models and math need numbers, but "Riverside" is not one. Every way of fixing that smuggles in an assumption, and the wrong one quietly invents an order that does not exist or leaks the answer into the features.

Try all four encodings (1/4)
Explode the one-hot columns
Run the fit comparison

Sign in to save progress

An encoding is a modeling assumption in disguise

A linear model cannot multiply a coefficient by "Old Town", and neither can a distance metric or a gradient. So categorical columns must become numeric ones. The catch: numbers carry structure that names never had. Numbers have an order, magnitudes, and distances, and your model will happily use all three even when they are artifacts of the encoding rather than facts about the world.

How this playground stays honest: everything is computed live in your browser from the literal 12-row table below (4 neighborhoods) and, in the last section, a 60-value sample from a seeded generator (seed 20260708). Both least-squares fits are solved exactly with the normal equations. Nothing is precomputed or faked.

The encoding lab

12 houses · 4 neighborhoods · rebuilt live

Same twelve houses, four different numeric matrices. Click through every encoding and watch the columns it hands to the model. Each one answers the same question, "what number is a neighborhood?", with a different assumption.

One-hot: One binary column per category. No fake structure, but the width grows with the number of categories.
NeighborhoodPrice ($k)is_Docklandsis_Hillcrestis_Old_Townis_Riverside
Riverside3720001
Old Town3000010
Docklands2401000
Hillcrest4050100
Old Town3220010
Riverside3880001
Docklands2621000
Old Town2910010
Hillcrest4300100
Riverside4010001
Old Town3150010
Hillcrest4180100

Four categories became four columns, and every row is a single 1 among 0s. No category is claimed to be bigger, closer, or better than another. That neutrality is exactly what the width buys you.

The one-hot column explosion

One-hot is the safest default at low cardinality, but its cost is width: k categories means k columns (k minus 1 if you drop a reference level). Drag the slider from 4 neighborhoods toward zip-code territory and watch the matrix widen while the rows available to estimate each column shrink. Push it past 20 columns to see it tip.

4

One-hot columns

4

one per category

Ordinal / freq / target columns

1

always, at any k

Rows per column (n = 200)

50.0

200 / 4

Status

Manageable

threshold: more than 20 columns

This is one face of the curse of dimensionality: parameters grow with k while the data does not. High-cardinality columns are exactly where the compact encodings, and eventually dimensionality reduction, earn their keep.

The fit lab: what a fake order costs

Ordinal encoding is perfect when the order is real (small, medium, large). Here the order is alphabetical, so a linear model on the code is forced to draw one straight line through neighborhoods whose mean prices are not monotone in that order. One-hot gives the model a free mean per neighborhood instead.

Two least-squares fits on the same 12 rows, solved exactly with the normal equations. One regresses price on the single ordinal code. The other regresses price on the four one-hot columns. Before running it, note that the category mean prices go up, down, then up again along the alphabetical codes.

When the encoding borrows the answer: target encoding on tiny categories

Target encoding replaces each category with the mean of the label inside it. With plenty of rows per category that mean is signal. With one or two rows per category the mean IS the label, so the feature memorizes noise. Below, the prices are pure noise with zero real category effect: slide k up and watch the train fit climb while the held-out slice, split deterministically, gets worse.

6
-1.0-0.50.00.51.051015202530Number of categories (k)R² (display clamped to [-1, 1])
Train R² (memorization)Held-out R² (the truth)Current k

Train R² at k = 6

0.071

Held-out R² at k = 6

-0.076

Avg train rows per category

6.7

Smallest category (train rows)

6

How this stays honest: the 60 prices are 350 plus uniform noise of ±40, drawn once from a seeded generator (seed 20260708), and the category has zero real effect on price. Rows with index mod 3 equal to 2 are held out (20 of 60). Each category is encoded with its train-only mean price, a line is fit by exact least squares on the train slice, and both R² values are recomputed live for every k.

This gap is a leakage signature: the feature knows things about the training labels that no honest feature could know at prediction time. Practitioners blunt it with out-of-fold means and smoothing toward the global mean. The full story, including nastier variants, lives in the data leakage guide.

Choosing in practice

EncodingAssumption it injectsReach for it when
One-hotNone (categories independent)Low cardinality, linear models
OrdinalA real, meaningful orderGenuinely ordered levels only
FrequencyPrevalence predicts the targetHigh cardinality, quick baseline
TargetCategory means generalizeHigh cardinality, with out-of-fold means and smoothing
← All GuidesNext Guide →