Updating a Forecast Without Starting Over
Botie needs to respond to new demand without letting one unusual day replace everything he knows. A weighted update lets him control how quickly his estimate changes.
12 sections · 4 questions · 2 coding challenges
The arrow keys move between sections too.
Maintaining a Level Estimate as Observations Arrive
BOTIE
Simple exponential smoothing maintains a level. More elaborate versions add trend and seasonal states. We begin with the level-only update so its response to a new observation is visible before adding those components.
Sources for this history
How Much Should One New Day Change the Estimate?
Yesterday's demand may be useful, but it can also be unusually high or low. Averaging the entire history has the opposite problem: old conditions may keep influencing the estimate after the greenhouse has changed.
We can retain a current estimate of demand and adjust it toward each new observation. The question becomes how much of the new discrepancy to use. That single choice produces a sequence of estimates we can inspect.
These illustrative water readings are used to show one update at a time.
Step 1 of 3
Keep the current estimate
Botie's current level is ten litres.
- Level
- 10
Step 2 of 3
Observe a different day
The new reading is fourteen litres. With an update fraction of one quarter, only part of that discrepancy moves the level.
Stored level: 10 New reading: 14 Fraction to use: 0.25 Change = 0.25 × (14 − 10) = 1
Step 3 of 3
Carry the updated state forward
The updated level is eleven litres and becomes the next one-step forecast.
Updated level = 10 + 1 = 11 Next forecast = 11
The state retains part of the past and part of the new evidence
The difference describes the surprise. Alpha controls how much of that surprise enters the retained state.
How much should one surprising day change the next forecast?
A new reading disagrees with the retained level. Try a small response rate and then a larger one, watching how much of that surprise enters the updated level.
Make the forecast before revealing the next day
BOTIE
Smoothing starts at the first observation, then moves its level halfway toward each newly revealed value. Changing the rule restarts the comparison on the same sequence.
Known days: 1 to 1
Forecast for day 2: 8
BOTIE
Updated demand level
11
Follow the operations
1. Previous level estimate
10
2. Update fraction
0.25
3. New observed demand
14
4. Subtract
4
5. Multiply
1
6. Add
11
7. Result
11
This is one level update with a supplied alpha in [0,1]. It does not fit alpha or model trend and seasonality.
1. Separate Observation, State, and Forecast
Before today's reading arrives, Botie has yesterday's retained level estimate. He uses that to forecast today. Once the actual demand is known, he can update the level for tomorrow.
Keep those two moments separate in the code. If we update first and then score the result against today's reading, we are using part of the answer in what we call a forecast.
Before observation: forecast[t] = level[t-1]
After observation: update level[t]The order of operations prevents tomorrow's information from changing yesterday's saved prediction.
2. Move Partway Toward the New Reading
The smoothing parameter alpha lies between zero and one. A small value changes the estimate slowly; a large value responds quickly. Alpha zero ignores new data and alpha one replaces the level with the latest observation.
The error-correction form and weighted-average form describe the same update.
level_new = level_old + alpha × (reading - level_old)
= 10 + 0.25 × (14 - 10)
= 11The two weights in the equivalent average sum to one.
3. Understand Why Older Readings Fade
Repeated substitution shows that each older contribution is multiplied by another factor of one minus alpha at every update. Its influence decreases geometrically. The initial state also retains some influence until enough updates have occurred.
This explains the name exponential smoothing. It does not mean that the data itself is assumed to grow exponentially.
Weight on latest reading: alpha
Weight on preceding reading: alpha × (1-alpha)
Weight one step earlier: alpha × (1-alpha)^2Choose an initial state and record it when reproducing a calculation.
Let one new day move the retained level
Botie predicted ten litres. The next day used fourteen, and we choose to absorb one quarter of that surprise into the level.
import numpy as np
level = 10.0
reading = 14.0
alpha = 0.25
forecast_before_reading = level
surprise = reading - level
level = level + alpha * surprise
print(f'{forecast_before_reading:.2f}')
print(f'{level:.2f}')10.00
11.00The saved forecast is still ten. Eleven is the updated state for a later prediction. Keeping those two moments separate is the main job of the loop in practice.
4. Match the State to the Structure in the Series
Simple exponential smoothing gives a flat forecast beyond the current level. A persistent trend or seasonal pattern calls for additional structure or a different method.
Choose alpha using a training and validation procedure that respects time. Do not select it on final test outcomes. In the workshop, build one update and inspect how the old estimate and new reading each contribute.
The Python loop repeats the same update over a record, saving predictions before each new reading.
5. Choose Alpha by Forecasting before Updating
A candidate alpha defines an entire sequence of states. For each candidate, reset to the same initial state, save a forecast, observe the target and only then update. Score all candidates on matching validation targets.
Updating before saving the prediction evaluates how well the smoother explains a value it has already seen. That produces an artificially favourable result, especially at a high alpha.
Compare two response rates on an ordered record
Both candidates start from a level of ten. These supplied observations illustrate validation bookkeeping.
import numpy as np
observed = np.array([12.,14.,13.])
for alpha in [.2,.8]:
level = 10.
errors = []
for value in observed:
errors.append(abs(value-level))
level += alpha*(value-level)
print(alpha, round(float(np.mean(errors)), 3))0.2 2.493
0.8 1.64The faster response wins on these three targets. Select a rate on a proper validation period and retain a later period for final assessment.
6. A Trend Needs Its Own State
A level-only smoother keeps one current estimate and predicts that level at every future horizon. A steadily rising process needs another quantity: the estimated change per interval. A trend model updates both level and trend, then extends the level using the trend.
The extra state adds flexibility and another estimation problem. A temporary jump can be mistaken for persistent growth. Compare with the level-only and seasonal baselines rather than assuming an extra state must improve forecasts.
Check yourself
Questions on Parts 1 to 6
Question 1 of 4
What is the updated level?
Use the information below.
Old level=10, new reading=14, alpha=0.25.Try it with Botie
Build with Botie
Write and run Python