Data Science Categorical Data

Categorical data needs to be converted into numbers before most machine learning models can use it, and the right encoding depends on whether the categories have a natural order.

Why Categories Can't Be Used As-Is

Most scikit-learn models only accept numeric input. A column like 'city' with values Chicago, Paris, and Tokyo, or 'size' with values Small, Medium, and Large, has to be transformed into numbers first. How you do that transformation matters a lot: pick the wrong encoding and you can accidentally tell the model that categories have a mathematical relationship that doesn't exist.

Nominal vs Ordinal Categories

Nominal categories have no inherent order: colors, cities, and payment methods are all nominal, since 'red' isn't mathematically greater or less than 'blue'. Ordinal categories do have a meaningful order: a satisfaction rating of Low, Medium, High, or a shirt size of Small, Medium, Large, XL clearly rank from lower to higher. This distinction decides which encoding to use.

  • Nominal data (no order) -> one-hot / dummy encoding, e.g. pandas.get_dummies() or OneHotEncoder.
  • Ordinal data (has order) -> ordinal encoding, e.g. OrdinalEncoder or a manual mapping, preserving rank order as integers.

Example: One-hot encoding nominal data with pandas

import pandas as pd

df = pd.DataFrame({
    'city': ['Chicago', 'Paris', 'Tokyo', 'Paris'],
    'sales': [200, 150, 300, 180]
})

# get_dummies creates one binary column per category
encoded = pd.get_dummies(df, columns=['city'])
print(encoded)
#    sales  city_Chicago  city_Paris  city_Tokyo
# 0    200          True       False       False
# 1    150         False        True       False
# 2    300         False       False        True
# 3    180         False        True       False
Note: Never assign arbitrary integers (Chicago=0, Paris=1, Tokyo=2) to nominal categories and feed them to a linear or logistic model. The model will interpret Tokyo as 'twice' Paris, a relationship that doesn't exist and will distort the fitted coefficients.

Ordinal Encoding When Order Matters

When categories do have a real ranking, encoding them as ordered integers is not only safe, it's useful: it lets the model learn a single coefficient that captures the increasing (or decreasing) effect of moving up a level, instead of learning a separate, unrelated coefficient per category as one-hot encoding would.

Example: Ordinal encoding with scikit-learn

import pandas as pd
from sklearn.preprocessing import OrdinalEncoder

df = pd.DataFrame({
    'satisfaction': ['Low', 'High', 'Medium', 'Medium', 'Low']
})

# Explicitly list the true rank order, lowest to highest
encoder = OrdinalEncoder(categories=[['Low', 'Medium', 'High']])
df['satisfaction_encoded'] = encoder.fit_transform(df[['satisfaction']])
print(df)
#   satisfaction  satisfaction_encoded
# 0          Low                   0.0
# 1         High                   2.0
# 2       Medium                   1.0
# 3       Medium                   1.0
# 4          Low                   0.0
EncodingUse caseRisk if used incorrectly
One-hot / dummyNominal categories: city, color, payment typeAdds many columns; can cause collinearity if not dropped one column
OrdinalOrdered categories: rating, size, education levelImplies a false order/spacing if categories are actually nominal
Note: When one-hot encoding, pass drop_first=True to pd.get_dummies() (or drop='first' to OneHotEncoder) for linear models. This avoids the 'dummy variable trap', where one column is a perfect linear combination of the others.

As a quick rule of thumb: if you can't answer 'is category A definitively more or less than category B?', treat the feature as nominal and one-hot encode it. If you can rank every category confidently, ordinal encoding usually produces a simpler and more effective model.

Exercise: Data Science Categorical Data

What is categorical data?