# How to Decompose Time Series Data into Trend and Seasonality?

253 views (last 30 days)
carolina on 22 Mar 2021
Commented: Michel Koll on 17 Nov 2022 at 10:58
I have a time series with predictive temperature and real temperature. I need to decompose a time series into components. Some components from time series are level, trend,seasonality and one component called noise.
Where the components are added together as follows:
Time series = Level + Trend + Seasonality + Noise
Noise=Time series- seasonality –trend
The purpose of decomposing the time series is to easily analyze the behavior of the results over time
This is the original predicted temperature time series which shows a nonlinear trend
I tried to remove the trend, this is the result it provided
Here is the code I have used
clear
close all
%Señal de Temperatura Predicha
x=1:1:100
ptemp=cell2mat(matriz_results(88277:88376,3:3))'
ordsignal=6
coeficient=polyfit(x,ptemp,6)
[p,s,mu]=polyfit(x,ptemp,ordsignal)
f_y=polyval(p,x,[],mu)
rtrend=ptemp-f_y
subplot(2,1,1)
plot(x,ptemp),grid
title('Tiempo de Predicción adelante: 60 minutos'),ylabel('Temperatura en °C')
subplot(2,1,2)
plot(x,rtrend),grid
xlabel('Muestras de Tiempo'),ylabel('Temperatura en °C')
title('Tiempo de Predicción adelante: 60 minutos-Sin Tendencia')
The ordsignalis the orden a function.
Remove trends from Data
https://www.mathworks.com/help/signal/ug/remove-trends-from-data.html
I need to show a similar result or if maybe there is a tool to decompose a time series into
components. I have not been able to estimate noise or residual components and seasonality. Thanks in advance for your help.
Michel Koll on 17 Nov 2022 at 10:58
I think I have somewhat of a rookie question. Why do I have to use a centered moving average in order to evaluate the trend? This creates a half a period length lag and thus is not real time applicable. Why can't I use the last "period length" values in order to evaluate the most recent trend value?
Hope this question fits here, I am desperatly trying to find an asnwer to that.
Thank you.

Michelle Hirsch on 24 Sep 2021
This just got way easier, with the new trenddecomp function introduced in R2021b.
Abhishek Chakraborty on 12 Nov 2022 at 11:54
Hi. I have MATLAB2020b. Any idea how I can use this function on my MATLAB2020b? Is there a way to use this function on MATLAB2020b too?

Kaiguang on 2 Apr 2022
Edited: Kaiguang on 5 Oct 2022
Numerous time series decomposition algorithms are possible and the results are sensitive to the algorithim choices. (An excerpt from here: The notional of seasonal variation is always intrinsically ambiguous: whether the temporal variation should be considered Seasonal, Trend, or Remainder is, to a degree, a matter of opinion and determined by choice of model and model parameters. This is true in STL as well as any seasonal variational approach).
In case that somebody is looking for an alternative, one choice is a Bayesian method called BEAST (Bayesian Estimator of Abrupt Change, Seasonality, and Trend) available from this FileExchange entry or https://github.com/zhaokg/Rbeast. It can be instantly installed by running eval(webread('http://b.link/rbeast',weboptions('cert',''))). BEAST actually does time series decomposition and changepoint detection at the same time. Below is a quick illustration using a monthly Google Search Trend time series on the keyword 'beach' in the US:
o = beast( beach ) % Apply BEAST to the 'beach time series: beach is a data vector only; the time
% info can be supplied using the start and deltat
% keywords, as in the next commented line
%o = beast( beach,'start',[2004,1],'deltat',1/12 )
printbeast(o) % print the changepoints detected
plotbeast(o) % plot the results: o.season.Y and o.trend.Y are the seasonal and trend compoents
Below is the plotted result. The decomposed seasonal signal and trend are in the 'seasona' and 'trend' subplots, respectively. In the fitted seasonality and trend, seasonal changepoints (scp) and trend changepoints (tcp) are detected seperately. As a Bayesian method, it not just tells when there are some changepoints but also quanitifies the probablity of changepoint occurrence over time (the Pr(scp) and Pr(tcp) subplots where the peaks indicate the times when the changepoints most likely occur).
Some possible Interpretations of the results: There was a sudden jump (or structural break) in the summer of 2011 ( The summer of 2011 was the hottest one on record for the US: the time series 'beach' again refers to the US online search popularity for 'beach'). There is also an abrupt rise at the start of 2016, again possibly attribute to the abormal high temperature (January 2016 Was the Most Abnormally Warm Month Ever Recorded: https://weather.com/news/climate/news/record-warmest-january-global-2016). There is a sharp drop in the search popularity around April 2020 (attributed apparently to the covid outbreak).
BEAST can also handle trend-only time series. Below is also an example to explain the meaining of tOrder and sOrder (e.g., the y labels in the figure above)..
y = [zeros(1,100) 1:100 99:-1:50 50*ones(1,250)] + 10*rand(1,500); % a trend-only time series without perodic/seasonal variation
o = beast(y, 'season','none') % season='none': y has no periodic/season component
plotbeast(o)
printbeast(o)
The trend is fitted using a piecewise polynomial model. Again, as a Bayesian method, BEAST assumes the order of the polynomial as uknowns. The orders of the polynomial needed to adequately fit the trend are estimated over time, as depicted iin the tOrder subplot. The 1st and 4th segments are flat lines, so their estimated poly orders are close to zeros.
uninstallbeast % Uninstall BEAST

Shashank Gupta on 25 Mar 2021
Hi Carolina,
MATLAB as of now does not have an explicite function for decomposition of time series data. But there are workaround to get these components. Check out this resource material. The trend can be estimated easily through moving average filter, look at this doc page. Similarly, seasonal component can also be estimated by parameteric estimated model, this link should help you. the remaining component you can find out by simply substracting each one of them by original signal (assuming the model is additive in nature).
I hope this helps you.
Cheers.