ML Categorical Data

Most machine learning models only understand numbers, so categorical columns like color or city need to be converted into numeric form before they can be used as features.

#Jobseeker

Find matching jobs & Auto apply with AI

Hyring
Jobseeker using Hyring to search, apply, and prepare with AI

Why Categories Need Encoding

A column like car_color with values Red, Blue, and Green looks perfectly reasonable to a human, but scikit-learn's estimators expect numeric arrays. Simply mapping Red to 0, Blue to 1, and Green to 2 is dangerous because it implies an order and a distance between categories that does not exist, the model might learn that green is greater than red, which is meaningless for an unordered category.

One-Hot Encoding

One-hot encoding solves this by creating one new binary column per category. Each row gets a 1 in the column matching its category and 0 in all the others. Because no category is represented by a bigger or smaller number than another, the model can no longer invent a false ordering between them.

Example

import pandas as pd

df = pd.DataFrame({
    'car_color': ['Red', 'Blue', 'Green', 'Blue', 'Red'],
    'price': [22000, 25000, 21000, 24000, 23000]
})

encoded = pd.get_dummies(df, columns=['car_color'])
print(encoded)

get_dummies vs OneHotEncoder

pandas.get_dummies() is the fastest way to one-hot encode a DataFrame during exploration, but it has a drawback, it only creates columns for the categories it has already seen. sklearn.preprocessing.OneHotEncoder is the safer choice inside a production pipeline because it can be fit on training data and then applied consistently to new data, even when a category is missing or new categories should raise an error instead of being silently dropped.

Example

import numpy as np
from sklearn.preprocessing import OneHotEncoder

colors = np.array([['Red'], ['Blue'], ['Green'], ['Blue']])

encoder = OneHotEncoder(sparse_output=False, handle_unknown='ignore')
encoded_colors = encoder.fit_transform(colors)

print(encoder.get_feature_names_out())
print(encoded_colors)
  • Use drop_first=True with get_dummies, or drop='first' with OneHotEncoder, to avoid the dummy variable trap where encoded columns are linearly dependent.
  • Set handle_unknown='ignore' on OneHotEncoder so categories missing from training data do not crash predictions later.
  • get_dummies works directly on a DataFrame and returns column names automatically; OneHotEncoder needs get_feature_names_out() to recover them.
  • Wrap OneHotEncoder in a ColumnTransformer to encode categorical columns while leaving or scaling numeric columns separately.

Example

from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LinearRegression

numeric_features = ['mileage']
categorical_features = ['car_color']

preprocessor = ColumnTransformer([
    ('num', StandardScaler(), numeric_features),
    ('cat', OneHotEncoder(handle_unknown='ignore'), categorical_features)
])

model = Pipeline([
    ('preprocess', preprocessor),
    ('regressor', LinearRegression())
])

# model.fit(X_train, y_train) applies scaling and encoding automatically
print(preprocessor)
Aspectpandas.get_dummiessklearn.OneHotEncoder
Fits on training data onlyNo, re-encodes whatever it seesYes, fit then transform consistently
Handles unseen categoriesSilently produces different columnsCan raise or ignore, your choice
Fits inside a PipelineNoYes
Best forQuick exploration in a notebookProduction and reusable pipelines
Note: When a linear or logistic regression model sits downstream, drop one dummy column per categorical feature with drop_first=True, keeping all of them creates perfectly correlated columns that make the coefficients unstable.

Exercise: ML Categorical Data

Why must categorical data typically be converted before use in most ML algorithms?