5 · Label encoding and ordinal encoding
Use Label Encoder for the target y; use Ordinal Encoder for feature columns with a natural order.
Use Label Encoder for the TARGET y; use Ordinal Encoder for FEATURE columns with a natural order.
Without this:
Without the distinction, you'll either inject false order into nominal features (the classic newbie mistake) or use the wrong tool for the target.
The previous lesson covered nominal features — categories with no meaningful order. This lesson covers two related but distinct tools:
-
LabelEncoder— designed specifically for the target variabley. It maps each class label to an integer 0, 1, 2, ... in alphabetical/sorted order. It is a 1-D transformer that operates on a vector, not a DataFrame column. -
OrdinalEncoder— designed for feature columns that have a real ordinal relationship: sizes (S < M < L < XL), education levels (HighSchool < Bachelor < Masters < PhD), satisfaction ratings (bad < ok < good < excellent).
The key difference from one-hot encoding: ordinal encoding preserves the ordering signal with a single integer column instead of expanding to N columns. This is valid ONLY when the ordering is meaningful — do not use it on nominal features.
Critical rule: LabelEncoder is for y only. Calling it on a DataFrame feature column technically works (it returns integers) but it applies alphabetical ordering with no way to override the order — which is wrong for most ordinal features.
Python (in browser)
`LabelEncoder` maps class labels to 0..N-1 in alphabetical order. `.classes_` stores the mapping; `.inverse_transform()` decodes predictions back to labels.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
Without the `categories` argument, `OrdinalEncoder` sorts alphabetically — L=0, M=1, S=2, XL=3 — placing S above L, which is backwards. Always pass `categories=[[ordered_list]]` explicitly.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
`df['col'].map({'S': 0, 'M': 1, 'L': 2, 'XL': 3})` is the cleanest approach for small fixed ordinals in pure pandas — self-documenting and NaN on typos.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Decision table: LabelEncoder for y; OrdinalEncoder (with explicit categories) for ordered features; OneHotEncoder for unordered features. Never mix them up.
You have a feature `education_level` with values 'PhD', 'Masters', 'Bachelor', 'HighSchool'. Which encoder and setup is correct?
- `LabelEncoder` is for the **target `y`** only — maps class labels to 0..N-1 alphabetically; use `.classes_` to see the mapping and `.inverse_transform()` to decode predictions.
- `OrdinalEncoder` is for **feature columns with a real ordinal order** — always pass `categories=[[ordered_list]]` explicitly; never rely on alphabetical default order.
- For small fixed ordinals, `df['col'].map({'S': 0, 'M': 1, 'L': 2, 'XL': 3})` is the cleanest pandas-only approach — self-documenting and returns NaN on unknown values.
- When in doubt whether categories are ordinal, prefer `OneHotEncoder` — injecting a false order is the more dangerous mistake than the efficiency loss.
Tree models (`RandomForestClassifier`, `XGBoost`) handle ordinal features natively — the model decides at each split whether the order matters. Linear models need the explicit ordinal-vs-OHE choice upfront because they compute global weights for each column.
If you remove it: You'd accidentally tell a regression model that 'S' is half of 'M' (because 1 / 2 = 0.5), which is nonsense for a clothing size — or that 'Masters' is equidistant from 'HighSchool' and 'PhD', which loses the graduation signal entirely.