0
$\begingroup$

TL;DR: Are there one-sided decomposition alternatives to the naive seasonal_decompose from statsmodels? Are there approaches to adapt intrinsically two-sided algorithms (like STL from statsmodels) to forecasting applications?

I'm attempting to perform time-series forecasting. For this I want to decompose a time-series into trend and seasonal parts. I picked STL implementation from statsmodels to handle this. I gravitated towards STL instead of seasonal_decompose, since even the docs down the bottom encourage more sophisticated approaches: Notes section of seasonal_decompose documentation I noticed, however, that the decomposition is two-sided, i.e., the trend and seasonal computation uses data from both before and after a given point in time. Below is an illustration of this using Civilian Labor Force Level from FRED and the onset of COVID.

import matplotlib.pyplot as plt
import pandas as pd
from pandas_datareader.fred import FredReader
from statsmodels.tsa.seasonal import STL


# Load data.
indicator = 'CLF16OV'
data = FredReader(indicator, start=2000).read()

# Execute decomposition.
stl = STL(endog=data, period=12)
decomp = stl.fit()

# Split results into separate series.
data_t = pd.Series(
    data=decomp.trend,
    index=data.index,
    name=f'{indicator}_t',
)
data_s = pd.Series(
    data=decomp.seasonal,
    index=data.index,
    name=f'{indicator}_s',
)
data_r = pd.Series(
    data=decomp.resid,
    index=data.index,
    name=f'{indicator}_r',
)

# Plot results.
fig, axes = plt.subplots(nrows=5, ncols=1, sharex=True, figsize=(11, 10))
axes = axes.flatten()

data.plot(ax=axes[0])
axes[0].set_title('Observed')
axes[0].axvline('02-2020', color='red')
axes[0].annotate('Start of COVID', xy=(0.8, 0.2), xycoords='axes fraction')

data_t.plot(ax=axes[1])
axes[1].set_title('Trend')
axes[1].axvline('02-2020', color='red')
axes[1].axvspan('07-2019', '02-2020', color='red', alpha=0.3)

data_s.plot(ax=axes[2])
axes[2].set_title('Seasonal')
axes[2].axvline('02-2020', color='red')
axes[2].axvspan('03-2018', '02-2020', color='red', alpha=0.3)

data_s.rolling(24).var().plot(ax=axes[3])
axes[3].set_title('Seasonal 2-year rolling variance')
axes[3].axvline('02-2020', color='red')
axes[3].axvspan('03-2018', '02-2020', color='red', alpha=0.3)

data_r.plot(ax=axes[4])
axes[4].set_title('Residua')
axes[4].axvline('02-2020', color='red')

fig.tight_layout()

The resulting figure: Trend-season decomposition of US Labor Force data.

You'll notice that the trend turns down a couple months before the start of COVID and the variance of the seasonal part picks up even earlier "in anticipation" of the COVID crash.

I don't see a two_sided argument for STL such as there is for seasonal_decompose, which I could set to False in order for the algorithm to only "see" past data. I believe this is dictated by some theoretical limitations which I'm ignorant of. The problem with developing a forecasting model using such a centered method is that future states affect the decomposition (and consequently the forecast) at a given point in time and hence I can't use it to form an actionable prediction today.

Are there other options for one-sided decomposition besides the naive seasonal_decompose?

Are there approaches to adapt these intrinsically two-sided algorithms to forecasting applications?

$\endgroup$

1 Answer 1

1
$\begingroup$

It sounds like you need an ETS model which has trend and seasonal components which are estimated in a one-sided manner, and is a common forecasting model.

They are implemented in the statsmodels package for python.

$\endgroup$
1
  • $\begingroup$ Thanks Rob, I'll look into them! $\endgroup$ Jun 2, 2022 at 19:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.