Choosing Transformations for Linear Models
Count features are often skewed and contain large outliers, which can make a linear model fit poorly.
When a Count Feature Breaks a Linear Model
Count data shows up whenever you record how many times something happened: visits to a page, items bought in a store, or appearances of a word. Features like these tend to share a recognizable pattern. Most values are small, a few values are very large, and the bulk of the data sits on one side of the range.
A linear model fitted directly to a feature like this can struggle. A handful of extreme values pulls the fitted line toward themselves, so the model captures the main relationship poorly. In the example this article follows, a Ridge regression model achieved only a relatively low R squared score on the data, meaning it could not capture the relationship between the feature and the target well.
One way to address this is a logarithmic transformation of the feature. The rest of this article follows that transformation step by step: what it is, why it has a shift built into it, what it does to the shape of the data, and how to find the exact point where a pipeline starts producing a wrong result.
Tracing the Zero Problem
The transformation is a single line of NumPy applied to the training and test feature matrices. Before tracing it, make a prediction. Suppose one of the feature values in X_train is 0. What does the expression X_train + 1 produce for that entry, and why might that matter for the logarithm that follows? Write down your guess before reading on.
What do you think happens?
If a feature value in X_train is 0, what does X_train + 1 produce for that entry, and why does that matter for the logarithm?
Reveal answer
The entry becomes 1, because 0 + 1 = 1. Since log(1) = 0 is a valid, finite result, the logarithm can then be applied to that entry.
The logarithm is not defined at 0, so applying it to a raw 0 has no valid result. Adding 1 first moves that zero to 1, which is a valid input.
Compare your guess with the reveal. The point to hold onto is this: the problem is not the logarithm by itself. The problem is that a count of 0 is a legitimate value in count data, and the logarithm has no defined output for it. The shift is what resolves that conflict.
Why the Shift Comes Before the Log
The source explains the reason for the shift directly. The value 0 appears in the data, and the logarithm is not defined at 0. So applying the logarithm to the raw values is not an option. Instead, the transformation is written as $\log(X + 1)$, which first adds 1 to each value and then takes the logarithm.
The shift guarantees that the argument of the logarithm is never zero for a count of zero, since 0 + 1 is 1. The original count of 0 is therefore mapped to a valid input rather than an undefined one. The shift also keeps every non-negative count within the domain of the logarithm, which is why the same expression works across the whole column.
Following One Column Through the Pipeline
Follow a single count column from raw input to the fitted model. The pipeline below has five stages. Trace where a bad value would first show up if the shift were left out.
Read the pipeline as a sequence of checkpoints. The raw counts still contain a 0, which is valid data. The unexpected result first appears at the logarithm stage if the shift is missing, because the logarithm of 0 has no valid value. Adding 1 at the second stage removes that problem before the logarithm sees it.
[0. 0.69314718 1.38629436 2.30258509 4.60517019 6.90775528]- X_train is a single-column feature matrix of count values, including a 0.
- X_shifted = X_train + 1 applies the shift to every entry first.
np.log(X_shifted)takes the logarithm only after the shift, so every input is at least 1.ravel()flattens the column so the transformed values print on one line.
This example is a generated illustration that follows the pattern described in the source: one NumPy line applied to the feature matrix, with the shift applied before the logarithm. The zero in the first row maps to 0, and every other count maps to a finite value.
Transforming a single count value
Apply log(X + 1) to the count 9.
- 1Start with the raw count
The raw value is X = 9.
- 2Apply the shift
Compute X + 1 = 9 + 1 = 10.
- 3Apply the logarithm
Compute log(10), which is approximately 2.30259 in natural logarithm terms.
The count 9 maps to approximately 2.30259.
Reading How Big Counts Get Compressed
The mapping below shows how each raw count lands after the transformation. Look at the gap between neighboring values on each side. The raw counts jump by large amounts at the top of the range, while the transformed values move in much smaller steps.
The values in the map follow directly from the shift and the logarithm. Counts 0, 1, and 3 map to 0, about 0.693, and about 1.386. Counts 99 and 999 map to about 4.605 and about 6.908. Each step up by a factor of ten in the raw count adds the same amount, about 2.303, to the transformed value. That is why very large counts stop stretching the range the way they did before.
This is the compression the source describes: a logarithm compresses large values much more than small ones, so a long tail of big counts ends up closer to the bulk of the data.
Comparing the Distribution Before and After
A histogram shows how many values fall into each range, so it is a natural way to check whether the transformation reduced skew. The source plots the feature after the transformation, with a label on each axis and 25 bins. Compare that plot with a histogram of the raw column to judge whether the asymmetry and outliers have been reduced.
The source describes the effect in two parts. First, the distribution becomes less asymmetrical: the lopsided pile of small values and the long tail of large values become more balanced. Second, the very large outliers that stretched the range are no longer present in the same form. Both changes make it easier for a linear model to follow the main relationship, rather than being pulled by a few extreme points.
Mistakes With the Shifted Transformation
Common mistake Applying the logarithm to the raw column without the shift
What it looks likenp.log(X_train) when X_train contains a 0Why it failsThe logarithm is not defined at 0, so the entry for a count of 0 has no valid transformed value.
Do this insteadWrite the transformation as log(X + 1): shift first, then take the logarithm.
Common mistake Reversing the order of the shift and the logarithm
What it looks likeTaking the logarithm of X_train, then adding 1 to the result
Why it failsThe shift is what removes the zero problem. Reversing the order brings back the undefined case.
Do this insteadKeep the shift on the input, before the logarithm is applied.
Common mistake Transforming the training data but not the test data
Why it failsThe model learns from one scale and then receives values on a different scale at prediction time.
Do this insteadApply the same transformation to both the training and test feature matrices.
Common mistake Reading a transformed column as if it were raw counts
Why it failsA plot of an already transformed column shows log-scale values, so the numbers no longer represent counts.
Do this insteadLabel the axis as transformed and keep the transformation in mind when interpreting the plot.
Practice Tracing a Count Column
A feature column contains the counts [0, 2, 7, 99]. Without running the code, compute log(X + 1) for each value, and identify the first stage of the pipeline at which a wrong result would appear if the shift were left out.
Hints
- Start by adding 1 to each count before taking any logarithm.
- The count 0 is the one that causes trouble if no shift is applied.
- The first stage where a wrong result appears is the logarithm stage, since that is where the undefined input would be used.
Check your answer by comparing it with the mapping from earlier. Counts 2 and 7 become log(3) and log(8), and 99 becomes log(100). If you are unsure about a value, return to the pipeline diagram and trace one count through each stage.
Key Takeaways
- Count features are often skewed and contain large outliers, which can pull a linear model's fitted line away from the bulk of the data.
- The logarithm is undefined at 0, so the transformation is written as log(X + 1), with the shift applied before the logarithm.
- After the transformation, the distribution is less asymmetrical and very large outliers are reduced, because a logarithm compresses large values much more than small ones.
- Apply the same transformation to training and test data, and be careful when interpreting or plotting a column that has already been transformed.