Concepts / Tree-Based Models and Feature Interactions

Tree-Based Models and Feature Interactions

Linear models can struggle with skewed features that have many small values and a few very large ones, and transforming such features often improves the fit.

  • Programming

When a Few Huge Values Get in the Way

Many real datasets contain a feature whose values are mostly small, with a handful of extremely large values sitting far to the right. Counts, prices, and durations often look like this. The feature may carry useful information about the target, yet a linear model can still struggle with it. This article follows one feature from its raw form through a transformation and a feature-selection step, and shows how to check each change with a score on unseen data.

Before reading on, make a prediction. Suppose you fit a ridge regression on raw columns where most values are small but a few are enormous. Will the model fit well, or will the large values get in the way? Keep your answer in mind, because the rest of the article explains what happens and why.

Reading a Skewed Feature

Picture a feature whose values cluster near zero, while a few values sit far above the rest. Plotted on a number line, the feature shows a long tail stretching to the right. Statisticians call this a skewed distribution. The source describes this pattern as many small values together with a few very large ones, and notes that it is very common in practice.

A linear model fits a straight-line relationship between each feature and the target. When a few values are enormous, they dominate that fit. The many small values are squeezed into a tiny region of the scale, where the model cannot distinguish them well. The diagram below contrasts the raw feature with the same feature after a logarithm is applied.

Many small valuesclustered near zeroSmall valuesspread across a widerstretchA few very largevaluesfar to the rightLarge valuesmoved closer to the bulkStraight line fitpulled toward the largevaluesStraight line fitdescribes the spread moreevenlysame featuredominatessame featureusable
Why does a single straight line fit poorly when most points cluster near zero and a few points sit far out? The large values set the scale, so the small values are crowded into a narrow band.

The problem is not that the large values are wrong. They are valid observations, but on a linear scale they carry so much weight that the model's line is set mostly by them. A transformation that compresses large values makes the feature easier for a linear relationship to describe.

How log(x + 1) Reshapes the Values

The source uses the form log(x + 1) when it transforms a feature or a target that counts things. The logarithm compresses large values, so very large numbers move much closer to the bulk of the data. Meanwhile, the small values, which were crowded together, occupy a wider stretch of the scale. The feature becomes more evenly spread. The transformation changes the scale of the feature rather than discarding any of its values.

Formula, step by step
  1. 1
    x is the original, non-negative value of the feature or target.
  2. 2
    Adding 1 moves x = 0 to 1, where the logarithm is defined.
  3. 3
    The logarithm compresses large values, so the spread of the transformed values is more even.
  4. 4
    In Python, NumPy computes the same quantity directly with np.log1p(x).

Adding 1 matters because many count values are zero, and the logarithm of zero is undefined. Adding 1 moves every value of zero or more into a range where the logarithm is defined. This is why the form log(x + 1), and the NumPy function np.log1p that computes it, is the usual choice for counts and for regression targets.

Worked example

Applying log(x + 1) to a skewed count feature

A count feature holds the values 0, 1, 10, 100, and 1000. Apply log(x + 1) to each value and describe how the spread changes.

  1. 1
    Handle the zero

    For x = 0, log(0 + 1) = log(1) = 0. Without the plus one, the logarithm of zero would be undefined.

  2. 2
    Transform the small values

    For x = 1, log(2) is about 0.693. For x = 10, log(11) is about 2.398.

  3. 3
    Transform the large values

    For x = 100, log(101) is about 4.615. For x = 1000, log(1001) is about 6.909.

  4. 4
    Compare the spread

    The raw gap between 100 and 1000 is 900 units, while the gap between their transformed values is about 2.29. The very large values have moved much closer to the rest of the data.

Result

The transformed values 0, 0.69, 2.40, 4.62, and 6.91 are spread more evenly than the raw values 0, 1, 10, 100, and 1000.

0010.69102.401004.6210006.91log(x + 1)log(x + 1)log(x + 1)log(x + 1)log(x + 1)
How does log(x + 1) pull a few very large values closer to the many small values on the number line? Each raw value on the left maps to a transformed value on the right.
python
Output (expected)
[0.         0.69314718 2.39789527 4.61512052 6.90875478]
Notes on the code
  • np.log1p computes log(x + 1) directly, so the zero in the input is handled safely.
  • The output is the same feature after transformation; the number of values is unchanged.

Deciding What to Transform

There is no single transformation that always works. The source notes that finding the best transformation for each combination of dataset and model is somewhat of an art. Which features to transform is an empirical choice. In the source's example every feature happened to share the same properties, which is rarely true in practice. Usually only a subset of the features should be transformed, and sometimes each feature needs its own transformation.

The choice depends on the model family. Tree-based models are generally unaffected by these transforms, while linear models often depend on them. The source also says that binning, polynomials, and interactions can have a large influence on less complex models such as linear models and naive Bayes models. Other models, including SVMs, nearest neighbors, and neural networks, may sometimes benefit, but the effect is usually less predictable.

A tree splits the feature at thresholds, so it separates small values from large ones without needing the values to lie on a straight-line relationship. Because of that, the compression a logarithm provides usually gives a tree little benefit. This is the reason tree-based models usually skip this step, while a linear model often needs it.

Feature Selection with SelectPercentile

Transformations change the values of existing features. A second lever is to change how many features the model sees. The source warns that it is tempting to create many new features, but adding features makes all models more complex and raises the chance of overfitting. When the feature count is high, it can be wise to keep only the most useful features and discard the rest. This can produce simpler models that generalize better.

The source describes three basic strategies: univariate statistics, model-based selection, and iterative selection. This article focuses on the first. Univariate selection scores each feature on its own against the target, then keeps the top-scoring features. SelectPercentile keeps a chosen percentage of the features with the highest scores.

All featuresfull training matrixScore each featureunivariate statisticagainst targetRank by scorehighest scores firstKeep top percentilediscard the restReduced feature setfewer columns for the modelfit on training datapercentile
What happens to the feature set at each step, from scoring every feature to keeping only the top percentile? Each stage narrows the set that the model will see.
python
Notes on the code
  • fit_transform learns the scores from the training data only and keeps the top 50 percent of features.
  • transform applies the same chosen columns to the test data without re-scoring it.
  • f_regression is one univariate score function for a numeric target; the choice of score function depends on the problem.

Checking the Reduced Model on Held-Out Data

Feature selection is supervised: it uses the target to decide which features to keep. For that reason the selection must be fitted only on the training portion of the data, and the test set must remain untouched. The data flows in one direction. The full dataset is split into a training set and a test set. The selector and the model are fitted on the training set. The test set is then transformed using the already-fitted selector and scored once.

Full datasetfeatures and targetTraining setused to fit selector andmodelReduced featurescolumns chosen on trainingdataTest scoremeasured on unseen dataTest setheld back until scoringsplitsplitfit selectorscore modeltransform then score
How does the data split into training and test sets so the reduced feature model can be scored on unseen data? Only the training set is used to choose features.

Mistakes When Transforming and Selecting

  • Common mistake

    Using np.log on a feature that contains zeros

    What it looks like

    np.log(counts) where counts includes 0 produces negative infinity for those entries.

    Why it fails

    The logarithm of zero is undefined, so the transformed feature is no longer usable.

    Do this instead

    Use np.log1p(counts), which computes log(x + 1) and handles zeros safely.

  • Common mistake

    Transforming every feature by default

    Why it fails

    The source notes that only a subset of features usually needs transforming, and the right choice is empirical.

    Do this instead

    Inspect each feature's distribution and compare test scores with and without the transformation.

  • Common mistake

    Expecting tree-based models to benefit from the same transform

    Why it fails

    Tree-based models are generally unaffected by these transforms, while linear models often depend on them.

    Do this instead

    Apply the step when the model is linear, and skip it for tree-based models unless testing shows a benefit.

  • Common mistake

    Fitting SelectPercentile on the full dataset before splitting

    Why it fails

    Feature selection is supervised, so it uses the target, and fitting it on the test rows leaks information.

    Do this instead

    Split first, fit the selector on the training data only, and apply transform to the test data.

  • Common mistake

    Adding many new features and assuming more features always helps

Practice: Choosing a Transformation and a Percentile

MEDIUM

A dataset has a count feature with values 0, 2, 5, 40, 900, and a target that is also a count. You will fit a linear model on it. Which of these columns would you transform, using log(x + 1) or np.log1p, and why? Then describe the order of steps you would use to choose a SelectPercentile value and confirm it on a held-out test set.

Hints
  • Look for a feature with many small values and a few very large ones, and check whether the target is a count.
  • Remember that the selector must be fitted on the training split only, and the test score is measured once on unseen rows.
  • A tree-based model would usually skip the transform, so consider which model you are fitting before deciding.

Key Takeaways

  • A skewed feature, with many small values and a few very large ones, can limit a linear model because the large values dominate the straight-line fit.
  • The transformation log(x + 1), written as np.log1p in Python, compresses large values and handles zeros safely, so it is commonly applied to counts and regression targets.
  • Which features to transform is an empirical choice; tree-based models are generally unaffected by these transforms, while linear models often depend on them.
  • SelectPercentile reduces the feature count by scoring each feature against the target and keeping the top percentile, and it must be fitted on training data only.
  • Confirm any reduction with a single test score on held-out data that the selection step never saw.

Related concepts

More concepts starting with T