Why does Spark's OneHotEncoder drop the last category by default?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Spark drops the last one-hot category by default to avoid a redundant feature column. In linear models, keeping every category column plus an intercept creates perfect multicollinearity, so Spark uses a reference category representation unless you tell it otherwise.
What Dropping The Last Category Actually Means
Suppose a categorical feature has three indexed values:
- '
0for red' - '
1for green' - '
2for blue'
If you keep all three one-hot columns, the vectors look like this:
- red becomes
[1, 0, 0] - green becomes
[0, 1, 0] - blue becomes
[0, 0, 1]
With dropLast=True, Spark uses only two columns:
- red becomes
[1, 0] - green becomes
[0, 1] - blue becomes
[0, 0]
The missing category is still represented. It is simply encoded as the all-zero baseline vector.
Why Spark Does This By Default
For linear regression, logistic regression, and other linear models, full one-hot encoding plus an intercept creates a dependency between columns. One category can always be derived from the others, so the design matrix is not full rank.
That redundancy is often called the dummy-variable trap. Dropping one category solves it cleanly because the omitted category becomes the reference level against which the other categories are measured.
This is why Spark's default is sensible for many modeling pipelines. It reduces dimensionality slightly and avoids a common source of unstable coefficients in linear models.
Example In Spark
In PySpark, the usual pipeline is StringIndexer followed by OneHotEncoder:
If you set dropLast=False, Spark keeps the full set of indicator positions:
That can be useful when you explicitly want a full indicator vector, for example when exporting features to another system or working with models that do not care about collinearity in the same way.
When You Might Want dropLast=False
Tree-based models are generally less sensitive to the same linear-algebra issue that affects linear models. In those cases, keeping all categories is often acceptable.
You may also prefer dropLast=False when:
- interpretability requires every category to have its own explicit bit
- downstream consumers expect a full one-hot vector
- you are not fitting a linear model with an intercept term
The important point is that Spark's default is a modeling convenience, not a universal mathematical law.
Do Not Confuse Indexing Order With Category Importance
OneHotEncoder works on indexed values, usually produced by StringIndexer. The category that gets dropped is the last indexed category, which depends on how indexing was assigned.
That means the reference category is not chosen semantically unless you control the indexing behavior yourself. If the baseline category matters for interpretation, inspect the indexer model and verify which label maps to which index.
Common Pitfalls
- Thinking the dropped category disappears entirely instead of becoming the all-zero reference vector.
- Forgetting that the dropped category depends on the index order produced earlier in the pipeline.
- Using full one-hot encoding with linear models and then being surprised by redundant columns.
- Assuming tree models and linear models react to encoded features in the same way.
- Changing
dropLastwithout considering how downstream feature consumers interpret the vector size.
Summary
- Spark drops the last category by default to avoid redundant one-hot columns.
- The omitted category is still represented as the all-zero baseline vector.
- This default is especially helpful for linear models, where full one-hot encoding can cause multicollinearity.
- If you need every category explicitly, set
dropLast=Falseand make that choice deliberately.

