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_tFor 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.L12The 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.
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 lagsthat 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 exactlyy.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 simplyD = 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.