Look before you model
Last session we built the Lumen series, split it by time, and shipped one baseline. Tonight we earn the right to model. Decomposition pulls the observed line into its trend, its repeating seasonal shape, and the residual left over - so you stop guessing what is in the data and start seeing it. Then we build the full baseline family: naive, drift, and seasonal-naive. These are not throwaway models - they are the scoreboard. Anything you build later has to beat them on a backtest, or it does not ship.
STL splits a series into three readable parts 7 min live
STL - Seasonal-Trend decomposition using Loess - takes the observed line and separates it into a smooth trend, a repeating seasonal component (here on a weekly period, m=7), and a residual - whatever is left. Read together, the three panels tell you which method on the ladder to reach for: strong seasonal shape says a seasonal method, a wandering trend says smoothing, and a fat residual says do not over-promise.
LiveReading the three components3 min▶
Each panel answers a different modelling question:
- Trend - is the level drifting up or down, and is it straight or curved? A clear trend rules out a flat naive forecast.
- Seasonal - how big and how stable is the repeating shape? A strong, steady weekly pattern is a gift: seasonal-naive alone will already be hard to beat.
- Residual - what is left after trend and seasonal are removed? If it is small and patternless, you have captured the signal. If it still has structure, there is more to model.
STL is additive by default, and robust. Lumen's weekend dips are a fixed weekly shape, so an additive STL fits cleanly. If the seasonal swings grew with the level (bigger sales, bigger weekend dip), you would log-transform first or use a multiplicative view. STL's robust=True option also down-weights one-off spikes like a launch day, so they do not distort the trend.
Self-studySTL vs classical decomposition2 min read▶
FPP3 favours STL over the older classical decomposition for three reasons:
- The seasonal component is allowed to change slowly over time, not frozen for the whole series.
- It is robust to outliers - a bad day does not bend the trend.
- You control the smoothness of trend and season directly via the Loess windows.
The tradeoff: STL handles only additive decomposition and one seasonal period at a time. For our weekly Lumen series that is exactly right.
The baseline family - the lines to beat 6 min live
Three baselines cover almost every simple case, and each is one idea. Naive: tomorrow equals today's last value, held flat. Drift: naive plus the average slope of the history, so the forecast keeps rising or falling. Seasonal-naive: tomorrow equals the same period one cycle ago. On a weekly series like Lumen, seasonal-naive usually wins - and that is the whole point of measuring against it.
LiveWhich baseline fits which series3 min▶
Match the baseline to the shape you saw in the decomposition:
- No trend, no season - naive is the right bar. A random-walk-like series is genuinely hard to beat.
- Clear trend, weak season - drift, so the forecast keeps moving in the trend's direction.
- Strong season (our case) - seasonal-naive, which carries the weekly shape forward for free.
Decompose the Lumen series with STL ★ 12 min · everyone builds
Fit STL on the daily series, pull out the three components, and score how seasonal the series really is.
Rebuild the Lumen daily series from b1 so this notebook runs standalone.
Fit STL(s, period=7) and unpack trend, seasonal, and residual.
Print the seven-day seasonal shape and compute the strength-of-seasonality score.
Plot res.plot() and read the three panels before moving on.
Score the baseline family on the holdout ★ 10 min · build your own
Build naive, drift, and seasonal-naive for the horizon H, score each with MAPE on the same holdout, and print the table. On this weekly series, seasonal-naive should come out on top.
Reuse the time split from b1: last H=14 days as test, the rest as train.
Build all three baselines as pandas Series aligned to the test index.
Score each with MAPE and sort the table - the winner is your bar for the rest of the course.
This table is your scoreboard for the whole course. In b3 you will watch Holt-Winters try to beat the seasonal-naive line; in b4 SARIMA; in b6 gradient boosting. The M-competitions - the field's largest empirical bake-offs - found that simple methods and their combinations are remarkably hard to beat, so a complex model only earns its keep if it clears this bar on a proper backtest (b8). If it cannot, the baseline ships, and it is also your fallback when a fancy model fails in production.
Try it yourself - this week ◐ 30-45 min total
- Run STL on your own daily series (or the Lumen one). Print the seven-day seasonal shape and the strength-of-seasonality score.
- Look hard at the residual panel. Write one sentence: does anything structured remain, or is it noise?
- Build all three baselines - naive, drift, seasonal-naive - and score them with MAPE on your holdout. Which wins, and does it match the decomposition?
- Set that winning MAPE aside as your bar. Every model from b3 onward has to beat it.
- Optional: skim FPP3 chapters 3 (decomposition) and 5.2 (simple forecasting methods) - the open textbook this track follows.
Sources covered (cited)
Taught from the forecasting canon and the published empirical evidence. This session covers:
Three questions before you go 🎯 ◐ 90 seconds
1 · What three parts does STL split a series into?
STL - Seasonal-Trend decomposition using Loess - separates the observed line into a smooth trend, a repeating seasonal component, and the residual left over. Reading the three tells you which method to reach for.
2 · How does the drift baseline differ from the naive baseline?
Naive holds the last value flat. Drift extends the line by the average slope between the first and last points, so a trending series keeps moving in that direction.
3 · Why score all three baselines before building a real model?
The winning baseline is your scoreboard. The M-competitions show simple methods are hard to beat, so a complex model only earns its complexity if it clears that bar - and the baseline is your production fallback.
Builder session 2 cheat sheet · pin this
STL(s, period=7).