Towards AI Can Help your Team Adopt AI: Corporate Training, Consulting, and Talent Solutions.


Let’s Do: Time Series Decomposition
Latest   Machine Learning

Let’s Do: Time Series Decomposition

Last Updated on June 28, 2023 by Editorial Team

Author(s): Bradley Stephen Shaw

Originally published on Towards AI.

What makes your time series tick? There’s only one way to find out — by taking it apart.

Photo by Sean Whelan on Unsplash

Time series are quite possibly the most ubiquitous collections of data available today. In fact, you’ve probably observed many yourself without even knowing — doing your grocery shopping, watching a sports match, and even just walking around.

Put simply, a time series is a series of data points that are indexed, listed, or graphed in time order¹.

Time series approaches generally fall into two buckets: extracting meaningful information from past data (time series analysis) and modeling past data in order to predict future values (time series forecasting). In this article, we’ll be focussing on the former, exploring:

  1. Model form
  2. Location and trend
  3. Seasonality
  4. Residual and noise
  5. A useful example

First up, some theory.

The building blocks of a time series

It’s useful to consider a generic time series as some combination of underlying drivers: location and trend, seasonality, and residual.

Location and trend

Often bundled together into a single “trend” term, location specifies the starting point of the series, and trend relates to long-term changes over time.

Usually, we think of trends as being movements in time series unrelated to regular seasonal effects and random shocks.


Seasonal effects are regular, systematic variations in the time series.

The drivers of these effects vary depending on the context of the analysis but are commonly related to calendar dates or physical conditions — e.g., summer holidays or the frequency at which a traffic light turns red.


Sometimes called noise, the residual is the catch-all bucket containing variation which is unrelated to long-term and/or predictable changes — i.e., this component is whatever remains after trend and seasonality have been removed from the time series.

As an example, a volcano eruption or a large sports event could cause shocks in a time series of airline passengers; all of this would get bundled into the residual.

Now that we’ve got a basic understanding of the elements of a time series let’s put them together in a model.

Model form

We can combine trend, seasonality, and residual into a decomposition model. These models are usually additive or multiplicative depending on the characteristics of the time series in question. Mathematically, this becomes:

Image by author

The determining factor of the decomposition model type is whether the amplitude of the seasonal and residual elements change as the trend changes²: if the size of the seasonal and residual elements are consistent regardless of the trend, then an additive model is most appropriate.

Enough theory for now — let’s see a practical example of decomposition!

The classic example

This set of airline data³ is commonly used in demonstrations of time series analysis, and for a good reason: it demonstrates the key components of a time series extremely well.

After some manipulation, we have monthly counts of airline passengers dating back to 1949:

Image by author

Plotting this data, we see the following:

Image by author
  1. A clear and consistent upward trend over time.
  2. Strong seasonality, becoming more evident over time. The seasonality element becomes more pronounced as the trend increases.
  3. Some evidence of a residual, as we can see what looks like random variation in the series.

As we’ve seen the magnitude of the seasonality element move in line with the magnitude of the trend element, we can be fairly certain that a multiplicative model is appropriate here.

Let’s go ahead and decompose the time series using the seasonal_decompose function in Python’s statsmodels ⁴. This decomposition first determines trend, and then calculates seasonality. The difference between the time series and the derived trend and seasonality falls into the residual.

This is a “naive” decomposition approach as it relies on the use of moving averages to calculate trend — more on that below.

Code-wise, the decomposition is quite simple:

# decompose
result = seasonal_decompose(
model = 'multiplicative',
period = 12,
extrapolate_trend = 6

# get each element
trend = pd.Series(result.trend)
season = pd.Series(result.seasonal)
res = pd.Series(result.resid)

Let’s take a look at the parameters used:

  • model specifies the decomposition model type. In this case, we’ve explicitly stated that we’re using the multiplicative model.
  • period specifies the period after which the seasonal behavior of the time series can be expected to repeat. Since we’re using monthly data, we would expect the seasonal element to repeat itself every 1 year, or 12 months. If we were using daily data, we would set period to be 7, reflecting the number of days in a week.
  • extrapolate_trend relates to the moving average used to derive the trend. The default approach is to calculate a “two-sided” moving average which reflects the period provided, and return Nan for points for which the moving average cannot be calculated. seasonal_decompose provides the option to replace the Nan with extrapolated values using the nearest extrapolate_trend points. So in our case, the two-sided moving average returns Nan for the first and last 6 points (since period = 12); we use the nearest 6 points to create an extrapolation to replace these missing values.

Let’s plot each component of the decomposition and remove each from the series in turn:

Image by author

The trend component is clearly upward and consistent over time. No surprises here, as we saw in the Raw series. Note how regular the start and finish of the trend are — this is caused by the extrapolation we covered above.

Once we remove the trend from the series — or “detrend” it — we see a mostly-regular pattern (top right above). Note how the de-trended series appears most consistent from about 1954 to 1958, with data points on either side of that interval appearing fairly noisy.

Seasonality is shown in the middle left chart above. Since seasonality is calculated such that it is a consistent pattern across the entire time series, we show only one period of the seasonal effects. Notice how seasonality peaks around the July and August summer holidays and drops around the start of the academic year in September and October — fairly sensible and in line with expectations.

Removing both trend and seasonality from the series leaves just the residual — we see this as the middle right and bottom left charts are the same. We can see how there is a noticeable change in the amplitude if the residual from 1954 to 1958, coinciding with changes in the raw series.

Finally, removing the residual from the de-trended, de-seasonalised series delivers a constant series of value 1.

Pro tip #1: under the multiplicative model, we remove an element of the time series by dividing the (raw) series by the element in question. As an example, if we were to remove seasonality from the equation, we would divide the raw series by the seasonality values. Under the additive model, we would subtract the component rather than divide by it.

Pro tip #2: under the multiplicative model, removing all of the constituent parts of a time series leaves a constant series of 1. If we were using an additive model, this “remainder” would be 0. This is a good check to ensure that all the elements of the time series have been captured appropriately.

Practical applications

Now that we’re familiar with decomposition, let’s take a look at how we can use it in our analysis.

Removing seasonality highlights trends and unexpected events

High levels of seasonality can mask trends and events, especially if the event takes place during a period of strong seasonality.

For example, consider the number of daily walkers in a park; during the colder winter months, we would expect a drop in these numbers — no big deal. But what if a short cold snap kept even more people away? Would it be easy to see that in a series without seasonality removed? Probably not!

Image by author

If we remove the derived seasonality from the airline data, we get the chart above (orange for de-seasoned data, grey for original series). Note how a downward spike around March 1960 appears to be masked, and only becomes noticeable once we strip out seasonality.

Removing noise creates a more regular time series.

By definition, the residual component is noisy and contains unexpected events and changes. It’s quite often useful to ask “what if?” questions, like “what if that random thing didn’t happen?”. We can get to a quick answer by simply removing the residual from a time series.

Image by author

Consider the airline series above. The original series is plotted in grey, and the denoised series is in red. Notice how removing random events creates a more regular time series that’s better suited to analysis and forecasting.

Recap and ramble

The recap

We covered the constituent components of a time series, and how we can put them together. We discussed how long-term changes in a time series are captured as trend, how the seasonality component represents regular and periodic variation, and how random fluctuations and shocks are captured in the residual component.

We also saw how we could formulate an additive and multiplicative time series model, the choice of which to use depending on how the amplitude of the seasonality and residual interacts with the trend.

We used statsmodels decompose an example time series and explore the various components and their effects on the original time series. Lastly, we discussed some practical use cases: the motivation for removing seasonality and for removing residual from the time series.

The ramble

Implicit in this analysis is the use of a univariate time series — i.e., we concentrated on measurements of a single quantity over time. Things don’t tend to operate in isolation in the real world, so it may make sense to analyze multiple time series in conjunction. Luckily for us, multivariate time series is a well-formed branch of statistics!

I mentioned that the time series decomposition approach we used was “naive”; naive in the sense that the decomposition relies on moving averages. While moving averages are great (and simple) tools, they can be sensitive to the choice of window size. There are other decomposition approaches available — like the STL⁶ — which may provide a more nuanced and robust result.

Finally, we need to talk about change points: depending on the size and treatment of the change, the decomposition can be distorted. COVID is a great example where not accounting for the effect of lockdown periods properly can create a distorted seasonality result, which in turn can distort conclusions drawn from an analysis.

That’s it from me — I hope you’ve enjoyed reading as much as I’ve enjoyed writing. Keep an eye out for more articles as I delve into time series analysis and forecasting.

References and resources

  1. Time series — Wikipedia
  2. Time Series Analysis: The Basics (
  3. yao, wei (2016), “international-airline-passengers”, Mendeley Data, V1, doi: 10.17632/vcwrx2rwtg.1, downloaded and used under the CC BY 4.0 license.
  4. statsmodels 0.14.0
  5. statsmodels.tsa.seasonal.seasonal_decompose — statsmodels 0.15.0 (+8)
  6. 6.6 STL decomposition U+007C Forecasting: Principles and Practice (2nd ed) (

Join thousands of data leaders on the AI newsletter. Join over 80,000 subscribers and keep up to date with the latest developments in AI. From research to projects and ideas. If you are building an AI startup, an AI-related product, or a service, we invite you to consider becoming a sponsor.

Published via Towards AI

Feedback ↓