Data fundamentals
One-Hot Encoding: How to Make Categories Readable for Machine Learning
Imagine you want to predict product revenue. Your dataset contains a column called Product Category, with values such as Lighting, Furniture, and Home Decor.
A machine-learning model can work with numbers, but it cannot directly interpret these category names as numerical features. Simply assigning Lighting = 1, Furniture = 2, and Home Decor = 3 would introduce an artificial order that doesn't exist.
One-hot encoding solves this problem by turning each category into its own binary column. Each row receives a 1 for the category it belongs to and a 0 for all other categories. Let's see how this works — and why the way we encode categorical data matters for our model.
Why assigning numbers to categories can mislead a model
Consider a small order dataset from a home-goods retailer:
| Order | Category | Revenue (€) |
|---|---|---|
| 1 | Furniture | 240 |
| 2 | Lighting | 85 |
| 3 | Home Decor | 60 |
| 4 | Furniture | 310 |
Suppose we want to predict revenue using product category as one of our features. The challenge is that a machine-learning model cannot directly use category names such as Furniture, Lighting, and Home Decor as numerical inputs.
One simple approach is to assign each category a number:
- Furniture = 1
- Lighting = 2
- Home Decor = 3
This is called label encoding. Although the transformation looks harmless, it introduces numerical relationships that do not exist in the original data.
- It creates an artificial order. Home Decor (3) is numerically greater than Furniture (1). However, product categories have no natural ranking. Neither category is inherently greater than another.
- It creates artificial distances. The numerical distance between Furniture (1) and Lighting (2) is the same as the distance between Lighting (2) and Home Decor (3). These numbers suggest a relationship between categories that has no real meaning.
For linear regression, representing a nominal category with a single numerical code forces the model to estimate one coefficient for that code. This imposes a particular numerical relationship between the categories instead of allowing each category to have its own effect. Distance-based algorithms, such as k-nearest neighbors, can also interpret the arbitrary distances as meaningful.
The solution: One-hot encoding
Instead of assigning each category a single number, we create a separate binary column for each category. A value of 1 indicates that an observation belongs to that category; 0 indicates that it does not.
Let's apply this to our retail example:
| Category | Category_Furniture | Category_Lighting | Category_Home Decor | Revenue (€) |
|---|---|---|---|---|
| Furniture | 1 | 0 | 0 | 240 |
| Lighting | 0 | 1 | 0 | 85 |
| Home Decor | 0 | 0 | 1 | 60 |
| Furniture | 1 | 0 | 0 | 310 |
Each row has exactly one active category, represented by a value of 1, while the remaining category columns contain 0. This is where the name one-hot encoding comes from. Unlike assigning arbitrary numerical labels, this representation does not impose an order or distance between categories.
What does this mean for a regression model?
The model can now learn a separate coefficient for each category, rather than treating category codes as a single numerical variable.
For example, a regression model can estimate how revenue differs between Furniture, Lighting, and Home Decor. If we include an intercept, we typically leave one category out as the reference category to avoid perfect multicollinearity.
One-hot encoding does not guarantee better predictions. It simply gives the model a more appropriate representation of nominal categorical data.
How to do it in Python
Option 1: pandas (quick and good for exploration)
import pandas as pd
df = pd.DataFrame({
"order_id": [1, 2, 3, 4],
"category": ["Furniture", "Lighting", "Home Decor", "Furniture"],
"revenue": [240, 85, 60, 310],
})
df_encoded = pd.get_dummies(df, columns=["category"], dtype=int)
print(df_encoded)
Option 2: scikit-learn (better for real ML pipelines)
from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder(handle_unknown="ignore", sparse_output=False)
encoded = encoder.fit_transform(df[["category"]])
print(encoder.get_feature_names_out())
# ['category_Furniture' 'category_Home Decor' 'category_Lighting']
Why prefer scikit-learn for modeling? The encoder remembers which categories it saw during training. When new data arrives with a category the model has never seen, handle_unknown="ignore" encodes it as all zeros instead of crashing. With pd.get_dummies, train and test data can end up with different columns, which is a classic source of confusing errors.
Three things that can go wrong
- The dummy variable trap. With three categories, two dummy columns are sufficient when a regression model includes an intercept. Keeping all three creates perfect multicollinearity. Use
drop_first=Truein pandas ordrop="first"in scikit-learn to leave one category as the reference. - High cardinality. Variables such as postal codes or product IDs can contain thousands of unique values. One-hot encoding would create thousands of columns. Consider grouping rare categories into "Other" or using frequency encoding instead.
- Data leakage. Split your data before fitting the encoder. Fit it on the training set, then transform the test set using the same encoder. This keeps preprocessing consistent and avoids information leaking from the test set.
When should you use it?
| Situation | Recommendation |
|---|---|
| Categories without a natural order | One-hot encoding |
| Categories with a meaningful order | Ordinal encoding |
| Thousands of unique categories | Consider alternative encoding methods |
| Tree-based models with few categories | One-hot encoding is often suitable |
Rule of thumb: One-hot encoding is a strong default for nominal categorical variables, but the best method depends on your data and model.
Key takeaway
One-hot encoding is a small step in data preparation, but it shows a bigger principle: how you represent your data decides what your model can learn. Turning text into numbers is easy. Turning it into numbers that don't lie is the actual skill.
Related posts
- Exploratory Data Analysis Look at your categories and distributions before you encode and model them.
- Multiple Linear Regression Where one-hot encoded categories become predictors in a model.
- Generalized Linear Models How regression extends to yes/no and count outcomes.