Representing Categorical Data for Machine Learning
To test a column, ask two questions. Do the values come from a fixed list of possibilities? Do they name a quality rather than an amount? If both answers are yes, the column is categorical.
A Dataset Whose Values Are Not All Numbers
A machine learning algorithm does not look at a spreadsheet the way a person does. It works with numbers arranged in a consistent layout, and the way those numbers are arranged can decide whether the algorithm learns anything useful. Real datasets often contain columns whose entries are words rather than numbers, and those columns need special handling before a model can use them.
A concrete case makes this easier to see. The adult income dataset is built from the 1994 census database in the United States. Its task is to predict whether a worker earns more than $50K per year or at most $50K per year. Each row describes one worker, and each column is a feature describing that worker: age, how they are employed, their education, their sex, their weekly working hours, their occupation, and more. The column we want to predict is income. The task is framed as a classification problem with two classes.
Read down the columns and notice a pattern. Some columns hold values that look like measurements, such as 39, 50, or 40. Other columns hold values that look like labels, such as Male, Bachelors, or Private. That difference in appearance is the starting point for the idea of a categorical variable.
Two Ideas That Define a Categorical Feature
A categorical variable comes from a fixed list of possible values and describes a qualitative property, not a quantity. The set of possible values is limited and known in advance, and the values name a quality such as which kind of education someone completed or which kind of job they hold.
The definition has two parts, and both matter. The first part is about where the values come from: a fixed list. The second part is about what the values mean: a quality rather than an amount. A categorical feature answers the question which one of these, not how much.
To test a column, ask two questions. Do the values come from a fixed list of possibilities? Do they name a quality rather than an amount? If both answers are yes, the column is categorical.
Tracing Which Columns Are Categorical
Apply the two questions to the adult dataset, one feature at a time. Workclass, education, sex, and occupation are the categorical features: their values come from a fixed set of labels and describe a quality of the worker. Age and hours-per-week are continuous features. They are numerical and their values fall along a range, so one value can be larger or smaller than another, and values can lie between two others.
The two groups look different on the page for a reason. Continuous values can be compared by size and can sit between two other values. Categorical values can only be matched or not matched against the list of labels. This difference will matter when we try to feed the columns to a model.
Why a Weighted Sum Breaks on Words
The reason categorical variables need attention appears once we train a model. Consider a logistic regression classifier on this data. A logistic regression makes its prediction by combining the input features with coefficients that are learned from the training set. The prediction is written as $\hat{y}$, and it depends on the coefficients $w_{i}$ and $b$ together with the input features $x_{i}$. The coefficients are fixed numbers learned during training, and the features are the values supplied for each example.
This weighted sum only works when the inputs are numbers. If $x_{2}$ is 39, multiplying it by a weight produces a meaningful quantity. If $x_{2}$ is the word Masters or Bachelors, there is no multiplication to perform. The formula makes sense when the input features are numbers, but not when a feature is a word, so the categorical values must be represented in some different way before logistic regression can be applied.
Turning Red, Green, and Blue into Vectors
The standard way to convert categories into numbers is one-hot encoding. The idea is to give each possible category its own position in a vector. For a given data point, the position that belongs to its category is set to 1, and every other position is set to 0. Only one position is hot at a time, which is where the name comes from.
Suppose a dataset has a color column with three possible categories: red, green, and blue. First we fix the order of the categories, because the position of each 1 depends on that order. Then we write a small function that builds the vector for any single value. The function needs no library. It only compares the value against each category in turn.
[0, 1, 0]
[0, 0, 1]- categories fixes the order, so position 0 is red, position 1 is green, position 2 is blue
- the loop compares the value with each category in turn
- exactly one position receives a 1; every other position receives a 0
What do you think happens?
Before running it, what vector do you expect one_hot("red") to return with the order red, green, blue?
Reveal answer
[1, 0, 0]
Red is the first category, so position 0 is set to 1 and the other two positions are 0.
Now apply the same function to every row of a small column. The same category always produces the same vector, so the two rows that say red come out identical. The single text column is replaced by a block of numeric columns, and each row becomes a vector.
red [1, 0, 0]
green [0, 1, 0]
blue [0, 0, 1]
red [1, 0, 0]- the list comprehension applies
one_hotto every row - the first and last rows are both red, so their vectors match
Read the diagram by position. The slot labeled green is the only one set to 1, because green is the category of this data point. The vector length equals the number of categories, so the encoding grows wider as the number of categories grows.
Why One-Hot Encoding Avoids a False Order
Notice what this encoding avoids. If we simply assigned the numbers 0, 1, and 2 to red, green, and blue, a model could read those numbers as an ordering or as distances, even though the colors have no such order. A model that multiplies by a weight would treat green as lying halfway between red and blue.
Mistakes When Encoding Categories
Common mistake Assigning 0, 1, 2 to categories and feeding them as ordinary numbers
What it looks likered = 0, green = 1, blue = 2 treated as a numeric columnWhy it failsThe model can read the numbers as an ordering or as distances that do not exist in the data.
Do this insteadGive each category its own position with one-hot encoding.
Common mistake Changing the category order between runs
What it looks likeUsing red, green, blue on Monday and blue, green, red on Tuesday
Why it failsThe position of each 1 depends on the order, so the same category would produce different vectors.
Do this insteadFix the order of the categories once and reuse it for every row.
Common mistake Expecting the vector for a value to contain more than one 1
What it looks likeExpecting red to produce [1, 1, 0]
Why it failsOnly one position is hot at a time, the one belonging to the value's own category.
Do this insteadSet exactly one position to 1 and all others to 0.
Common mistake Leaving a categorical column as raw text when fitting logistic regression
Creating New Features from Existing Columns
Encoding changes the form of a feature, but feature engineering can also create new features from existing data. The chapter names three techniques: binning, adding polynomial terms, and adding interactions. Each reshapes a raw measurement into a form that gives a model more to work with. Expert knowledge of the problem usually guides which new features to create.
| Technique | What it creates | Illustrative example with age and hours-per-week |
|---|---|---|
| Binning | One new column per range of values | Age 39 falls in a bin such as 30 to 44, so that bin column is 1 |
| Polynomial term | A column that is the feature raised to a power | $\text{age}^{2}$ for age 39 is 1521 |
| Interaction | A column that is the product of two features | $\text{age} \times \text{hours}$ for age 39 and 40 hours is 1560 |
Three ways to build new columns from existing ones. The bin boundaries are chosen only for illustration.
Building one feature of each kind from a single worker
A worker has age 39 and works 40 hours per week. Build a binned age feature, a squared age term, and an age-by-hours interaction.
- 1Choose bin boundaries
Use the illustrative bins 0 to 29, 30 to 44, 45 to 59, and 60 and over. In a real project these would come from knowledge of the problem.
- 2Create the binned feature
39 falls in the 30 to 44 bin, so that bin column is 1 and the others are 0.
- 3Create the polynomial term
Squaring age gives 39 times 39, which is 1521.
- 4Create the interaction
Multiplying age by hours-per-week gives 39 times 40, which is 1560.
The worker now has the original age and hours columns plus three new columns: the bin indicator, the squared age, and the age-by-hours product.
The engineered features do not replace the originals. They are added alongside them, and the combined set is what the model receives. The new columns are built from the same raw measurements, so the model sees both the plain values and the reshaped versions.
Matching Features to the Model
The right feature set depends on the model. A straight-line model cannot bend a relationship on its own, so linear models gain from binning and from adding polynomial and interaction terms. Those additions give a linear model the nonlinear structure it cannot produce by itself. More complex nonlinear models, such as random forests and SVMs, may learn complex tasks without the feature space being expanded explicitly.
Practice Encoding a Small Column
A column holds the values small, medium, large, medium. Using the order small, medium, large, write the one-hot vector for each row and check that the two medium rows match. Then state why the vectors should not be replaced with 0, 1, 2.
Hints
- Fix the category order first and write it down.
- Exactly one position in each vector should be 1.
- Treating small, medium, and large as 0, 1, and 2 would suggest a false order and distances between sizes.
Key Takeaways
- A categorical variable comes from a fixed list of possible values and describes a qualitative property, not a quantity. Workclass, education, sex, and occupation are categorical in the adult dataset, while age and hours-per-week are continuous.
- Logistic regression combines inputs with learned coefficients, so categorical words must be converted to numbers before the model can use them.
- One-hot encoding gives each category its own position in a vector, sets exactly one position to 1, and avoids implying a false ordering among categories.
- Binning, polynomial terms, and interactions create new features from existing columns, and linear models tend to benefit most from them.
- The right features depend on the model, and matching features to the method is often the most important factor in success.