← Statistics

Regression analysis

Overfitting and Underfitting

Imagine you want to predict net revenue per customer. One model barely improves on a simple guess. Another fits its training data almost perfectly—but performs poorly on new customers. Both models are unreliable, but for opposite reasons.

In Evaluating and Interpreting a Regression Model, we looked at how well a model fits the data it was given. Now we take the next step: will it still work on customers it has never seen?

This is the problem of generalization. A model that is too simple may miss important patterns (underfitting). A model that learns the training data too closely may fail to generalize (overfitting). Throughout this post, we use customer revenue as an illustrative example. All data is illustrative.

Training Data and Test Data

Before building a machine learning model, data scientists typically split their dataset into training and test data. This is a standard step in the machine learning workflow: the model needs data to learn from, but we also need separate data to check whether it can make reliable predictions on new observations.

We divide the data into two parts:

A practical example

Imagine we have data from 100 customers and want to predict their net revenue. We randomly assign 80 customers to the training set and reserve the other 20 for the test set.

The model learns from the 80 training customers. It then predicts revenue for the 20 test customers without having used their actual revenue values during training. We compare those predictions with the actual values to see how well the model performs on unseen data.

This matters because a model can perform very well on its training data but poorly on new customers. Comparing its performance on both datasets helps us identify potential overfitting and assess whether the model has learned patterns that generalize beyond the data it was trained on.

Splitting the Data with Python

from sklearn.model_selection import train_test_split

# Separate predictors from the target
X = df.drop(columns="net_revenue")
y = df["net_revenue"]

# Split the data: 80% training, 20% testing
X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.2,
    random_state=42
)

print("Training customers:", len(X_train))
print("Test customers:", len(X_test))
Training customers: 80
Test customers: 20

What the code does:

The result is 80 training observations and 20 test observations, assuming the dataset contains 100 rows. The code assumes df is your prepared pandas DataFrame and that net_revenue is your target column.

A grid of 100 dots, 80 blue for training data and 20 red for test data, scattered at random.
Chart 1 The model learns from the training data (80 customers). The test data (20 customers) remains unseen until evaluation, giving us a way to assess performance on new customers. Illustrative data.

Comparing performance on both datasets shows why we need both:

Model behaviorTraining performanceTest performance
UnderfittingPoorPoor
Good generalizationGoodGood
OverfittingVery goodMuch worse

This is the central lesson: training performance alone cannot tell us whether a model will generalize well.

A random split is not always the right split

A random split is appropriate for many independent customer records, but not every dataset. Time-dependent data may require a chronological split, and repeated observations from the same customer may require a customer-level split to avoid data leakage.

Two Ways a Model Can Fail

Underfitting

An underfitting model is too simple to capture the underlying pattern in the data. It performs poorly even on the data it was trained on, often resulting in a low R².

Imagine predicting net revenue per customer using only the weekday of their first order. Monday and Saturday customers may spend very different amounts, but the weekday alone might explain very little of that variation. The model ends up predicting roughly the same revenue for everyone.

In this example, the model has not learned enough about what drives customer spending. Its R² is 0.03, meaning it explains only 3% of the variation in revenue in the data used to fit the model.

Scatter plot of actual against predicted net revenue per customer. Actual revenue ranges from about 40 to 190 euros, but predictions stay in a narrow band around 113 euros, shown by a dashed horizontal line, far from the diagonal line of perfect predictions.
Chart 2 The model predicts almost the same revenue for every customer, so it cannot tell high-value customers from low-value ones. Illustrative data.

Typical causes of underfitting:

Because the model fails to capture the pattern in its training data, it is also unlikely to make reliable predictions for new customers.

Overfitting

Overfitting is the opposite problem. An overfitting model learns the training data too closely. It performs very well on the data it was trained on, but its predictions become less reliable when it encounters new data.

Imagine predicting net revenue per customer using 40 predictors but having data from only 60 customers. The model has many variables to work with relative to the number of observations. It may start treating random quirks as meaningful patterns. For example, one customer who happened to make a large purchase during a flash sale might disproportionately influence what the model learns. That pattern may not hold for other customers.

To understand why this happens, we need to distinguish between two things in the data:

An overfitting model learns both the signal and some of the noise. As a result, it fits its training data closely but struggles to generalize to the wider population.

Two scatter plots with identical axes. Left: a smooth blue curve shows the signal, gray vertical lines show each customer's distance from it as noise, and one flash-sale customer far above the curve is circled in red. Right: a red curve passes through every training customer, including a sharp spike at the flash-sale customer, while hollow dots for new customers sit close to the smooth dashed signal curve instead.
Chart 3 Each customer’s revenue is the smooth signal plus random noise. The overfitting model passes through every training customer, noise included, so it spikes at the flash-sale customer. New customers follow the smooth signal, not the spikes. Illustrative data.

How to Spot Underfitting and Overfitting

Comparing the error on the training data with the error on the test data tells the three situations apart.

Chart 4 shows the same 24 customers fitted three ways: a straight line (degree 1), a smooth curve (degree 2) and a very flexible curve (degree 12).

Three scatter plots of the same 24 customers with identical axes. The first has a nearly flat straight line, the second a smooth hump-shaped curve following the points, and the third a wildly oscillating curve that passes close to the points and shoots off the chart at the right edge.
Chart 4 The wiggly curve is close to every past customer, but between and beyond those points it swings wildly. One new customer would be badly mispredicted. Illustrative data.

The errors behind these three fits, measured on the 24 training customers and on 200 new customers, tell the same story in numbers:

ModelTraining errorTest error
Degree 1 (underfitting)€26€31
Degree 2 (good fit)€13€17
Degree 12 (overfitting)€12€54

Underfitting shows up as a high error on both sets. Overfitting shows up as a low training error but a much higher test error. Errors are RMSE (root mean squared error) in euros per customer.

Adding predictors can reduce training error even when the new variables contribute little useful information. For predictive modeling, cross-validation helps compare models on data not used to fit them. Adjusted R² is another useful measure when comparing linear regression models, but it does not replace evaluating predictive performance on unseen data. See Evaluating and Interpreting a Regression Model for adjusted R².

Bias and Variance

Underfitting and overfitting describe what goes wrong with a model. Bias and variance help explain why.

The Bias–Variance Trade-off

A very simple model may miss important relationships, even when trained on different samples. A very complex model may fit one training sample extremely well but produce very different results when trained on another.

The goal is to find a balance: a model complex enough to capture meaningful patterns, but not so complex that it starts learning random noise.

The chart below shows how the two errors trade off as the model becomes more complex.

Conceptual chart of error against model complexity. Bias squared falls as complexity grows, variance rises, and total error forms a U shape whose lowest point, marked by a dashed line, is the optimal model complexity.
Chart 5 As complexity grows, bias² falls and variance rises, so total error is lowest in between. Total error also includes irreducible noise, and the exact curve shapes depend on the problem and the model. Conceptual sketch.

Strategies to Reduce Underfitting and Overfitting

If the model underfits

If the model overfits

Several of these strategies come down to the same question: which predictors belong in the model? Too few useful predictors can leave important patterns unexplained, while unnecessary predictors can increase overfitting risk. The right choice depends on the data, model complexity, and how the model is evaluated. Deciding which ones to keep is called variable selection, and it is covered in Multiple Linear Regression.

How do we know if the changes work?

Evaluate the selected model on a separate test set that was not used for model selection. This provides an estimate of how well the model predicts unseen observations.

The goal is not to build the most complicated model or the model with the smallest training error. It is to find a model that captures meaningful patterns and performs reliably on new data.

How to explain it to stakeholders

“We compared three regression models to predict revenue per customer. The most complex model made predictions that were typically close to the actual values in its training data. However, when tested on new customers, its prediction errors became much larger.”

“The simpler model performed slightly worse on the training data but made much more reliable predictions for new customers.”

“This suggests that the complex model may have learned details specific to its training data rather than general patterns that apply to other customers.”

“Based on these results, we would prefer the simpler model, provided its predictions are sufficiently accurate for the business.”

Key takeaway

Underfitting occurs when a model fails to capture important patterns, resulting in poor training performance. Overfitting occurs when a model fits the training data too closely and performs substantially worse on unseen data.

To assess generalization, compare training performance with validation performance during model development. Once you have selected your model, evaluate it on a separate test set.

The goal is not to build the most complicated model or achieve the lowest training error. It is to find a model that captures meaningful patterns and makes reliable predictions on new data.

Related posts