Econometric Approach to Time Series Analysis — Seasonal ARIMA in Python
By: Jahangir Mammadov
Tags: Towards Data Science, Seasonal, Time Series Analysis, Sarimax, Data Science

If we look at the time series plot of the data we can observe an increasing trend in 2000–2006, a decreasing trend in home sales starting from 2007 till 2012 due to big financial crisis and increasing trend again till 2018. We can also observe seasonality in the data as usually the housing market is not active at the beginning of a year and sales usually go high in mid-year and again sales getting lower by the end of the year. Seems like warmer seasons, especially summer is the good season for the American housing market.

3. Seasonal decomposition and Time series components: Trend, Seasonality, Cycles, Residuals

Time series data Y is composed of a combination of Trend, Cycles, Seasonality and Residuals. Obviously, you may come across with time series where it doesn’t have a Trend, Cycles or Seasonality. So, it is your task to identify the components of time series data. Definition of the terms are given below:

Trend — long-term upward or downward movement.

Cycle — periodic variation due to economic movements. It is different from seasonal variation. The cycle is the variation of autoregressive component of time series data. Cycles occur within longer time intervals such as every 6–10 years, whereas seasonal variation occurs in shorter time intervals.

Seasonality — variation in data caused by seasonal effects. Ice cream sales are high in summer, heating oil sales are high in winter but low in summer.

Residuals — a component that is left after other components have been calculated and removed from time series data. It is randomly, identiclly and independently distributed (i.i.d). Residuals, R~ N(0,1).

Statsmodels library has a function called seasonal_decompose, which decomposes time series Y into Trend, Seasonality and Residuals. Although, it is a naive decomposition algorithm, in practice it is very intuitive and works well for time series data where T, S and R are obvious. Before explaining the below graphs I would like to talk about the interaction among these components.

Time series data Y can take either an additive or a multiplicative form. In additive form, time series Y is formed by the sum of time series components, namely, T, S, C, R:

Y = T + C + S + R

In multiplicative form time series Y is formed by the product of time series components:

Y = T * C * S * R

So, is home sales index is multiplicative or additive? If you carefully look at the time series plot of Housing index you may notice that the seasonal variation (seasonality) gets smaller when the trend decreases (years 2008–2013) and gets bigger when the trend increases (years 2014–2019). This happens in multiplicative time series, where small value for trend T results in small S because we multiply S by T. You don’t experience this phenomenon in additive time series.

We decompose time series data into Trend, Seasonal component and Residuals using seasonal_decompose(original_data, ‘multiplicative’) function from statsmodels. Don’t be surprised if the function returns all 3 components even though you assume that they do not exist for a particular time series data. In reality, these components are generated by a simple algorithm, that’s why the decomposition function cannot say a component doesn’t exist, despite the calculated value is not significant. So, you will see these three components for any time series data. You have to know how to read the results and decide which model (ARIMA or SARIMA) to fit the data.

Plot of seasonal decomposition from statsmodels library

We will try to decompose the data into components ourselves to better understand their derivation and usage. The trend can be calculated taking moving average with window size= 12. The below plot is very similar to the Trend generated by stats model library.

Moving average with window size=12

Plot of Moving average window size=12

Remember the multiplicative model, Y = T *C* S* R ? Dividing Y by T may give you Y/T=C*S*R and we assume that Residuals are too small for this data as the time series plot looks smooth. We have a very small data, thus we cannot detect an economic cycle. We get a seasonal component when we divide time series by trend, S=Y/T.

Code snippet for seasonality decomposition

Graph of seasonality is a little bit harder to understand, however, the explanation given here is sufficient. y=1.2(red marker) means there were 20% more sales in July-2000. In other words, June has a seasonal effect of +20% or 1.2 *T. On the other hand, y=0.8(green marker) in Feb-2003 shows a 20% decrease in sales. So, for some time series data not at this particular case, you may see the seasonal effect is very small i.e y=0.0001. It shows a very small seasonal effect, which shouldn’t even be considered significant.

Seasonal Component

Residuals can be computed as R = Y/(S*T)

Code snippet for residuals decomposition

Resiudals component

There are some other ways to detect seasonality. In the below graph, monthly home sales for each year is plotted and as you can see every year follows pretty much the same pattern with a slight difference. House sales are high in summer, lower in winter months.

Code snippet for the monthly home sales graph

Monthly sales per year

4. Stationarity in time series data and why it is important

When we have trend and/or seasonality in a time series data we call it non-staionary.

Stationarity means the statistical properties of data, such as mean, variance and standard deviation remain constant over time.

Why do we want the statistical properties to remain the same over time? Well, because we make statistical assumptions (a good example could be OLS assumptions) about the sample data in due course of model building and the model will only be capable of performing under those assumptions. When the statistical properties of the data changes, the model is no longer capable of representing the true nature of the data.

That’s why our forecasting/prediction results will no longer be valid. Changing mean/variance will require us to fit another model and this model may be valid for a short period of time and we have to abandon it again and fit a new model. See, how inefficient and unreliable this process looks like. We have to make time series data stationary before fitting a model. We can make time series stationary by transforming the data. Usually, differencing is used to make the data stationary. We will talk about it in Section 6, below.

So, how can we test whether a time series data is stationary or not? The first is just eyeballing the time series plot and identify trend or seasonality. If at least one of them exists, then the time series data is not stationary. Secondly, you may divide the data into 3 different sets and calculate mean and variance for each set and confirm whether mean and variance for each set is substantially different or not. The third option is to use one of the statistical tests provided in statsmodels library.

Augmented Dickey-Fuller test is the most popular amongst others, where the null hypothesis, H_0 = data is not stationary. ADF test result provides test statistic and P value. P value >= 0.05 means the data is not stationary, otherwise, we reject the null hypothesis and say data is stationary.

We assume you know what hypothesis testing is and what P value means. If you are not quite familiar with these terms, then look at the p-value and if it is smaller than 0.05 (p-value < 0.05) then data is stationary if p-value >= 0.05 data is not stationary. ADF test confirms that the original time series data is not stationary with p-value ~ 0.08

Code snippet for ADF test

Time series data is not stationary. Adfuller test pvalue=0.0803366374517756

5. Autocorrelation and partial autocorrelation

We have to take a look at ACF and PACF plots, before model building as we will use these plots a lot from now on.

Autocorrelation plot shows the correlation of time series data with its own lagged values. For example, autocorrelation at lag=1 shows the correlation between y_t and y_t-1. At lag=2, corr(y_t, y_t-2). At lag=12 corr(y_t, y_t-12). Every data point at time t having a high correlation with a data point at time t-12, t-24, etc denotes seasonality at this particular example.

Autocorrelation plot of original home sales index data

The below code snippet and scatter plots may help you to better understand the correlation between lagged values, namely, autocorrelation.

Code snippet for correlation of lags

Correlation between lag values — highly correlated

Back to ACF plot, blue shaded area at the autocorrelation plot shows significance level. So, correlation coefficients within the shaded area show weak correlation at those lags and we don’t consider them significant in the analysis.

The partial autocorrelation function (PACF) gives the partial correlation of a stationary time series with its own lagged values.

Partial autocorrelation plot of original home sales index data

PACF removes the correlation contribution of other lags and gives the pure correlation between two lags without the effect of others.