10 · Moving averages
Averaging a sliding window of recent points smooths noise and gives the simplest possible forecaster. The window size trades smoothness against lag — the central tension of every smoother.
One idea, one try. At your own pace.
LEARN BY DOINGPut your intuition to work3 steps
10 · Moving averages
Use the lesson’s examples and explanation to check your idea.
Personal reflection. Nothing is sent to an AI service.A moving average replaces each point with the mean of its window. As a smoother it removes noise; as a forecaster it predicts the next steps as the average of the last k points. A bigger window smooths more but lags more — there is no free lunch.
Without this:
Without a baseline smoother you have no cheap noise filter and no naive forecast to beat — and a model that can't beat a moving average isn't earning its complexity.
The moving average (MA) is the most basic time-series tool there is, and it wears two hats.
As a smoother, it replaces each point with the mean of a sliding window of width k: the point at time t becomes the average of t-k+1 … t. Noise (which averages toward zero) gets damped while the underlying level and slow trend survive. In pandas this is one line: ts.rolling(window=k).mean().
As a naive forecaster, the MA says: my best guess for the next step is the average of the last k observations. Repeat that average for every step in the horizon and you have a flat forecast — crude, but it's the baseline every fancier model must beat.
The choice of k is the whole game, and it's a tradeoff with no escape:
- Small
k(e.g. 3) — barely smooths, follows the data closely, reacts fast, but lets noise through. - Large
k(e.g. 14) — very smooth, kills noise, but introduces lag: the smoothed line trails turns in the series by roughly(k-1)/2steps. On an upward trend a wide MA systematically reads low.
A weighted moving average (WMA) softens this by giving recent points more weight (a triangular or exponential weighting) so the average reacts faster than its window width suggests — the idea exponential smoothing pushes to its logical end in the next lesson.
Below we smooth a noisy trending series with two window sizes, quantify how much noise each removes versus how much lag it adds, and build a naive MA forecast for the next steps.
Python (in browser)
rolling().mean() smooths a noisy series. A wider window lowers the roughness (more noise averaged away) but trails turning points by more steps — and the naive MA forecast is just a flat average of the last k points.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Let's make the lag-versus-smoothness tradeoff visible. We plot the noisy series with both moving averages overlaid: the short window (3) hugs the data and stays jittery, while the long window (14) is glassy-smooth but visibly drags behind every rise and fall. There is no setting that gives you both — picking k is choosing where on that spectrum you want to live.
Python (in browser)
The same series under a narrow (3) and wide (14) moving average. The wide one is smoother but visibly trails turning points — smoothness and responsiveness pull in opposite directions.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
You widen a moving-average window from 3 to 21 days. What happens?
- A moving average smooths by replacing each point with the mean of a sliding window (ts.rolling(k).mean()).
- As a forecaster it's a flat naive baseline: the next steps equal the average of the last k points — the bar every model must clear.
- Window size trades smoothness against lag: bigger k removes more noise but trails turns by ~(k-1)/2 steps. There is no free lunch.
Rolling means power dashboards (7-day averages), feature engineering (rolling stats as model inputs), and the baseline forecasts you benchmark ARIMA and ML models against.
If you remove it: Without a moving-average baseline you can't tell whether a complex model is actually adding value or just dressing up the recent average.