Testing a Forecast as Time Moves Forward
One convenient cutoff can hide a forecasting failure. We will replay several prediction dates, preserving what was known at each one, and compare methods on matching targets.
14 sections · 5 questions · 2 coding challenges
The arrow keys move between sections too.
Replaying Earlier Forecast Origins
BOTIE
Let's replay the decision at several earlier dates. At each date we expose only the observations that would have been available then, fit the procedure, and record its forecast before checking the later result. The small arrays let us inspect these time boundaries directly.
Would This Rule Have Helped Before We Knew the Answer?
Botie's forecast looks convincing on a plot of the whole record. But the model was fitted after all those observations existed. We need to reconstruct the decisions he could have made at earlier dates.
Move a cutoff through the record. At each cutoff, fit or update using only the available past, save the requested forecast, and score it against the later target. This makes the evaluation follow the intended use.
The forecast comparison uses an invented sequence of daily water totals.
Step 1 of 3
Make the first split
Imagine stopping the record at the end of day 3. Botie has three measurements and needs a prediction for day 4. Copying the latest reading gives us a simple rule to test. Keep tomorrow's answer covered until tomorrow arrives.
Recorded history → prediction time → future
- Recorded
Day 1
5litres
- Recorded
Day 2
7litres
- Recorded
Day 3
6litres
- Predict this day
Day 4
?not observed yet
Keep out of the inputs
- Later
Day 5
?not observed yet
Day 4 prediction: copy day 3
6 litres
Step 2 of 3
Move the origin
Now let one day pass. We can check the earlier prediction against day 4's reading, add that reading to the history, and make a new prediction for day 5. The boundary moves; information never travels backwards through it.
Recorded history → prediction time → future
- Recorded
Day 1
5litres
- Recorded
Day 2
7litres
- Recorded
Day 3
6litres
- Recorded
Day 4
9litres
- Predict this day
Day 5
?not observed yet
Keep out of the inputs
Day 5 prediction: copy day 4
9 litres
Step 3 of 3
Score matching targets
We have now waited for both target days. Put each prediction beside the observation it was meant to predict. A trailing-two mean is another possible rule: it averages the two latest readings available at each boundary.
| Target day | Later observation | Copy latest | Mean of last two | Absolute errors: latest / mean |
|---|---|---|---|---|
| Day 4 | 9 litres | 6 litres | 6.5 litres | 3 / 2.5 litres |
| Day 5 | 8 litres | 9 litres | 7.5 litres | 1 / 0.5 litres |
Day 4
- Later observation
- 9 litres
- Copy latest
- 6 litres
- Mean of last two
- 6.5 litres
- Absolute errors: latest / mean
- 3 / 2.5 litres
Day 5
- Later observation
- 8 litres
- Copy latest
- 9 litres
- Mean of last two
- 7.5 litres
- Absolute errors: latest / mean
- 1 / 0.5 litres
Evaluation has to replay the information available at each date
Comparing every method against the same target dates makes their error summaries comparable.
Which forecast would have helped on these dates?
Both methods made their predictions before the same target days. Compare their errors date by date before reducing each method to one average.
BOTIE
Mean absolute error for each method
- 02
- 11.5
Follow the operations
1. One row per forecasting method
6 9 6.5 7.5 2. Shared target observations
- 09
- 18
3. Subtract a shared reference row
-3 1 -2.5 -0.5 4. Absolute value
3 1 2.5 0.5 5. Mean within each row
- 02
- 11.5
6. Result
- 02
- 11.5
The provided forecasts must already respect their historical origins. This reducer cannot detect leakage in how they were created.
1. Choose Origins and Horizons Before Scoring
An expanding window retains all earlier training observations. A sliding window keeps a fixed recent span. The first can estimate from more data; the second can respond to a changed process by discarding older conditions.
Specify the forecast horizon, minimum history, update frequency, and training window before comparing scores. Different choices represent different deployment tasks.
Origin 3: history positions [0,1,2], target position 3
Origin 4: history positions [0,1,2,3], target position 4Array indices here identify chronological positions, not shuffled rows.
2. Refit the Whole Procedure Within Each Origin
Any learned scaling, imputation, feature selection, or model coefficients must be learned using that origin's training data. Fitting preprocessing once on the complete sequence still leaks future information even if the model's rows are split correctly.
When labels or measurements arrive late, move the usable cutoff back accordingly. The replay should match actual availability rather than an idealised instant report.
A backtest evaluates the complete prediction procedure, including how often it is allowed to update.
3. Compare Errors at Matching Dates and Horizons
Calculate an error for each saved forecast and its target. Report overall summaries and inspect errors across time. Overlapping forecasts and shared training histories can make those errors dependent.
If a method predicts several horizons, report performance by horizon as well as any chosen aggregate. A good next-day forecast need not be a good next-month forecast.
Targets = [9,8]
Persistence errors = [3,1]; MAE = 2
Trailing-two errors = [2.5,0.5]; MAE = 1.5This tiny comparison illustrates bookkeeping. It is far too small to establish reliable superiority.
Score two rules at one prediction date
Only the three history values are available when the prediction is made. We save both rules' answers and reveal the target afterwards.
import numpy as np
history = np.array([4., 6., 8.])
predictions = np.array([history[-1], history[-2:].mean()])
target = 10.0
print(predictions.tolist())
print(np.abs(target - predictions).tolist())[8.0, 7.0]
[2.0, 3.0]Persistence does better at this one origin. That does not settle the comparison across a whole period; the challenge repeats the process at several dates.
4. Keep a Final Period Outside Model Selection
Use rolling validation to select settings, then evaluate the chosen procedure on a final untouched period. Repeatedly adjusting a model after inspecting that period turns it into another validation set.
Botie's workshop compares aligned absolute errors. The coding task creates those predictions from the historical record itself, then a second task checks performance separately by horizon.
A deployment project later adds monitoring because the process can change after even a careful backtest.
5. A Forecast Origin Is Not Always the Latest Row in an Export
If daily demand is finalised the following afternoon, tomorrow morning's forecast cannot use yesterday's final total yet. Replaying the task requires both event dates and reporting dates.
At each origin, build the available history from records that had arrived by that time. A later corrected reading can be useful for scoring, but should not replace the version actually available to the historical predictor.
Check yourself
Questions on Delayed Forecast Inputs
Question 1 of 1
Can the 08:00 forecast use Monday’s final demand?
Use this setup.
A forecast is issued at 08:00 Tuesday. Monday’s final demand is only published at 14:00 Tuesday. A retrospective export labels it Monday.6. Compare an Expanding History with a Recent Window
An expanding window retains all past observations. A fixed recent window forgets older regimes. Neither is universally preferable: the first reduces estimation noise under stability, while the second can respond faster to change.
Choose the window rule using validation origins. Compare predictions on the same targets, including dates after a plausible operating change.
Two historical means after a level change
The record shifts from a low-demand period to a high-demand period. Targets begin at position three.
import numpy as np
y = np.array([5.,5.,5.,10.,10.,10.])
for origin in [3,4,5]:
expanding = y[:origin].mean()
recent = y[origin-2:origin].mean()
print(origin, round(float(expanding), 2), round(float(recent), 2), float(y[origin]))3 5.0 5.0 10.0
4 6.25 7.5 10.0
5 7.0 10.0 10.0Both methods miss the first unannounced change. The recent window then adapts faster because it discards older conditions.
7. Preserve the Paired Errors before Averaging
Keep each method's error beside the same origin and horizon. The difference between their errors tells us on which decisions one helped. An overall mean can hide a method that improves ordinary days but fails on the peak days Botie most cares about.
Origins and horizons can overlap, so errors are not generally independent. A simple standard error treating every cell as an unrelated observation can be misleading. Report the evaluation design and use an uncertainty method compatible with its dependence.
Check yourself
Questions on Parts 1 to 7
Question 1 of 4
Which slice can supply the training history?
Use the information below.
At origin index 3, observations at indices 0,1,2 are available. The target is at index 3.Try it with Botie
Build with Botie
Write and run Python