Lesson 2 - Seasonal AR and MA Terms

Welcome to Seasonal AR and MA Terms

Lesson 1 said the seasonal orders mirror the non-seasonal ones at the seasonal lag. This lesson makes that concrete. A seasonal AR(1) term does for the seasonal lag exactly what a non-seasonal AR(1) does for lag 1: it says today’s value is a fraction of a value a fixed distance back — except the distance is a full season (12 months) instead of one step. Once you see a seasonal AR term recover a known coefficient and produce its distinctive autocorrelation fingerprint, the seasonal MA term and seasonal differencing fall into place by analogy.

By the end of this lesson, you will be able to:

  • Write the seasonal AR(1) relationship and explain what its coefficient means
  • Recover a known seasonal AR coefficient from synthetic data
  • Recognize the seasonal AR fingerprint: ACF spikes at multiples of the season length
  • Explain seasonal MA and seasonal differencing by analogy to their non-seasonal twins

Let’s build a seasonal AR process.


The Seasonal AR(1) Relationship

A seasonal AR(1) term, P = 1 with period s, writes each value as a fraction of the value one full season earlier:

y_t = Phi * y_{t-s} + e_t

For monthly data with s = 12, that’s y_t = Phi * y_{t-12} + e_t — this January is Phi times last January, this July is Phi times last July, plus a shock. It’s the identical form as the non-seasonal AR(1) from Module 5 (y_t = phi * y_{t-1} + e_t), with y_{t-1} swapped for y_{t-12} and phi (lowercase, non-seasonal) swapped for Phi (uppercase, seasonal). Build one with a known Phi = 0.6 and recover it, the same discipline you used for the non-seasonal models:

import numpy as np, pandas as pd
from statsmodels.tsa.statespace.sarimax import SARIMAX

rng = np.random.default_rng(7)
n, s, Phi = 300, 12, 0.6
e = rng.normal(0, 1, n)
y = np.zeros(n)
for t in range(n):
    y[t] = (Phi * y[t - s] if t >= s else 0) + e[t]
y = pd.Series(y)

res = SARIMAX(y, order=(0, 0, 0), seasonal_order=(1, 0, 0, 12), trend="n").fit(disp=False)
print(round(res.params.iloc[0], 3))    # 0.598  <- ar.S.L12

The fitted seasonal AR coefficient, labeled ar.S.L12 (seasonal AR at lag 12), is 0.598 — recovering the true 0.6 almost exactly. The S in the name marks it as seasonal, and the L12 marks the lag it operates at. The seasonal_order=(1, 0, 0, 12) says: one seasonal AR term, no seasonal differencing, no seasonal MA, period 12 — with order=(0, 0, 0) meaning no non-seasonal structure at all, so this is a pure seasonal AR(1).


The Seasonal AR Fingerprint

Just as a non-seasonal AR(1) has a distinctive ACF that tails off geometrically (Module 4), a seasonal AR(1) has its own fingerprint — the same geometric decay, but only at multiples of the season length:

from statsmodels.tsa.stattools import acf

a = acf(y, nlags=24, fft=True)
print(round(a[1], 3))     # -0.084   <- short lags near zero
print(round(a[12], 3))    #  0.552   <- spike at the season
print(round(a[24], 3))    #  0.280   <- decays (~0.552^2)

The pattern is unmistakable: near-zero at short lags (lag 1 is -0.084 — no month-to-month structure), a strong spike at lag 12 (0.552 — the seasonal relationship), and geometric decay at further seasonal multiples (lag 24 is 0.280, roughly 0.552², exactly as an AR(1) decays). It’s Module 4’s AR signature transposed to the seasonal scale: where a non-seasonal AR(1) tails off across lags 1, 2, 3, a seasonal AR(1) tails off across lags 12, 24, 36. Reading this fingerprint on a real series’ ACF is how you’d spot the need for a seasonal AR term — a spike at the seasonal lag with little in between.

An ACF bar chart over lags 1 to 30. Most bars near the short lags (1 through 11) are tiny, sitting near zero inside a shaded significance band. A tall bar rises at lag 12 (about 0.55), a shorter bar at lag 24 (about 0.28), and a hint of one at lag 36 would continue the pattern. The bars at seasonal multiples decay geometrically while the non-seasonal lags stay flat. The chart is annotated 'spikes at multiples of s=12, decaying like an AR(1) — the seasonal fingerprint'.
The seasonal AR(1) fingerprint: near-zero autocorrelation at short lags, a strong spike at the season length (12), and geometric decay at further seasonal multiples (24, 36...). It's the non-seasonal AR signature from Module 4, transposed to the seasonal lag.

Seasonal MA and Seasonal Differencing by Analogy

With the seasonal AR term understood, the other two seasonal orders follow directly from their Module 5 and Module 3 twins:

  • Seasonal MA(1) (Q = 1): y_t = e_t + Theta * e_{t-s} — today’s value carries an echo of the shock from one season ago, exactly as a non-seasonal MA(1) echoes the shock from one step ago. Its fingerprint (by analogy to Module 4) is a single ACF spike at lag s that then cuts off, rather than the AR term’s decaying series of seasonal spikes.
  • Seasonal differencing (D = 1): subtract the value one season ago, y_t - y_{t-s} — which is exactly y.diff(12), the transformation you used in Module 3 to stationarize Cyclepath. In SARIMA notation, the seasonal differencing you did by hand back then is simply D = 1.

So a model like SARIMA(0,0,0)(1,1,0)[12] — Module 4’s preview — reads as: seasonally difference once (D=1, remove the yearly level shifts), then fit a seasonal AR(1) (P=1) on the result. Every seasonal order is a familiar operation, just applied a cycle apart.

Reading the coefficient names in a summary

When you fit a SARIMA and read its summary (Lesson 3), the coefficient names tell you exactly which term is which: ar.L1 is non-seasonal AR at lag 1, ma.L1 is non-seasonal MA at lag 1, ar.S.L12 is seasonal AR at lag 12, and ma.S.L12 is seasonal MA at lag 12. The .S. and the lag number (L12) are how you tell a seasonal term from its non-seasonal cousin at a glance — useful when a model has both, like the SARIMA(1,1,0)(1,1,0)[12] this module builds, which will show both an ar.L1 and an ar.S.L12.


Practice Exercises

Exercise 1: Interpret a seasonal coefficient

A fitted SARIMA reports ar.S.L12 = 0.7. In plain terms, what relationship does that describe for monthly data?

Hint

It means each month’s value is about 0.7 times the same month one year earlier (plus shorter-term effects and noise) — this July is roughly 70% of last July, this December roughly 70% of last December, and so on, measured on whatever scale the seasonal terms operate (often after differencing). A high seasonal AR coefficient like 0.7 indicates a strong, persistent year-over-year seasonal relationship: the seasonal pattern carries forward reliably from one cycle to the next, which is exactly what makes the series seasonally predictable.

Exercise 2: Identify the fingerprint

You plot a series’ ACF and see near-zero bars at lags 1 through 6, a single strong spike at lag 7, and then near-zero bars again at 8 through 13 with no spike at lag 14. Seasonal AR or seasonal MA, and what period?

Hint

A seasonal MA(1) with period 7 (daily data, weekly cycle). The tell is that there’s a single spike at the seasonal lag (7) that then cuts off — no decaying series of spikes at 14, 21, etc. A seasonal AR would show spikes at 7, 14, 21 decaying geometrically (like this lesson’s 12, 24 pattern); a single seasonal spike that cuts off is the MA signature, transposed to the seasonal scale. This is the exact seasonal analogue of Module 4’s “ACF cuts off after q = MA” rule.

Exercise 3: Translate a hand operation into an order

In Module 3 you computed y.diff(12) to stationarize Cyclepath. Which SARIMA order does that correspond to, and what would y.diff(12).diff(12) correspond to?

Hint

y.diff(12) is a single seasonal difference — D = 1 with s = 12. Applying it twice, y.diff(12).diff(12), would be D = 2 — seasonal differencing of order 2. Just as d = 2 is rarely needed for non-seasonal trends (Module 5), D = 2 is rarely needed for seasonal patterns; D = 1 almost always suffices to remove a stable seasonal cycle, and going further risks the same overdifferencing problems Module 3 warned about, now at the seasonal scale.


Summary

A seasonal AR(1) term writes each value as a fraction of the value one full season earlier: y_t = Phi * y_{t-s} + e_t — the non-seasonal AR(1) form with lag s in place of lag 1. Fitting seasonal_order=(1,0,0,12) to a synthetic process with known Phi = 0.6 recovered it as 0.598 (coefficient ar.S.L12). Its fingerprint is Module 4’s AR signature at the seasonal scale: near-zero short lags, a spike at lag 12 (0.552), and geometric decay at seasonal multiples (lag 24 at 0.280 ≈ 0.552²). The seasonal MA term echoes a shock one season ago (a single seasonal ACF spike that cuts off), and seasonal differencing D = 1 is exactly Module 3’s y.diff(12). In a summary, seasonal terms are labeled with .S. and their lag (ar.S.L12), distinguishing them from non-seasonal twins.

Key Concepts

  • Seasonal AR(1)y_t = Phi * y_{t-s} + e_t; this period as a fraction of the same period one cycle ago.
  • Coefficient recovery — fitting (1,0,0,s) to known-Phi data returns that Phi, confirming the term works.
  • Seasonal AR fingerprint — ACF spikes at multiples of s, decaying geometrically, with short lags near zero.
  • Seasonal MA and differencing — the MA-echo and the y.diff(s) operations, applied at the seasonal lag.

Why This Matters

Seasonal terms are the beating heart of SARIMA — the piece that gives it the power a non-seasonal ARIMA lacked. Recognizing a seasonal AR fingerprint on an ACF plot tells you a seasonal term is needed; understanding that ar.S.L12 = 0.6 means “60% of the same month last year” lets you interpret a fitted model rather than treat it as a black box. And knowing that seasonal differencing is just y.diff(12) in disguise connects this module directly back to the stationarity work you already did. Next, you’ll fit a full SARIMA to Cyclepath with both seasonal and non-seasonal terms, read its summary, and produce a forecast.


Next Steps

Continue to Lesson 3 - Fitting SARIMA with statsmodels

Fit a full SARIMA to Cyclepath with SARIMAX, read the summary with both seasonal and non-seasonal terms, and forecast.

Back to Module Overview

Return to the Seasonality: SARIMA module overview


Continue Building Your Skills

You’ve built the seasonal AR term, recovered its coefficient, and learned to read its ACF fingerprint — plus the seasonal MA and differencing terms by analogy. Next you’ll assemble a complete SARIMA with both seasonal and non-seasonal terms, fit it to Cyclepath with statsmodels, and read a summary where ar.L1 and ar.S.L12 sit side by side.