Building Inputs From Earlier Days
A prediction row needs information available before its target. We will turn one ordered record into rows of earlier readings without accidentally including the answer.
12 sections · 4 questions · 3 coding challenges
The arrow keys move between sections too.
Turning Delayed Effects Into Predictors
BOTIE
Our first example uses earlier demand to predict later demand. This constructs a supervised table from a time record; it does not establish that an earlier reading causes the next one.
Sources for this history
Which Readings Could Botie Have Used That Morning?
A regression model expects rows of inputs and corresponding answers. Botie's demand log is just one sequence. We need to decide which earlier entries belong beside each future target before we can fit anything.
For each target day, take the two preceding days in chronological order. Then slide that window forward by one position. Keeping the dates aligned is the first part of building a forecasting model.
The illustrative demand record is ordered from earliest to latest.
Step 1 of 3
Keep a target aside
The third value is the first target with two preceding observations.
Recorded history → prediction time → future
- Recorded
Day 1
4litres
- Recorded
Day 2
6litres
- Predict this day
Day 3
?not observed yet
Keep out of the inputs
- Later
Day 4
?not observed yet
Step 2 of 3
Move the window one position
The former target becomes a known input only after its observation time.
Recorded history → prediction time → future
- Recorded
Day 2
6litres
- Recorded
Day 3
5litres
- Predict this day
Day 4
?not observed yet
Keep out of the inputs
Step 3 of 3
Keep column meanings fixed
The first column is older and the second is more recent in every row.
| Predicting | Older input | Recent input | Later target |
|---|---|---|---|
| Day 3 | Day 1: 4 | Day 2: 6 | 5 |
| Day 4 | Day 2: 6 | Day 3: 5 | 9 |
Day 3
- Older input
- Day 1: 4
- Recent input
- Day 2: 6
- Later target
- 5
Day 4
- Older input
- Day 2: 6
- Recent input
- Day 3: 5
- Later target
- 9
The feature row has to stop before its target
Each row ends before its target. Averaging keeps target dates separate while summarising their available history.
What history belongs beside each target day?
Increase the history window and notice which early days no longer have enough preceding readings. Each surviving row must end before the day it predicts.
BOTIE
Trailing-mean predictions in target-date order
- 05
- 15.5
Follow the operations
1. Demand in chronological order
- 04
- 16
- 25
- 39
2. Number of preceding readings
2
3. Build earlier-value windows
4 6 6 5 4. Mean within each row
- 05
- 15.5
5. Result
- 05
- 15.5
Inputs must be evenly spaced and already audited for availability. This tool does not fill missing dates.
1. Define What One Row Represents
Each row will represent one forecast: the readings available when we make it, paired with the later value we want to predict. With two lags here, the older reading goes in column zero and the newer one in column one. We must use that order when predicting too.
The first two dates do not have enough preceding readings for complete rows. We omit them. Filling that unavailable history with zeros would tell the model that measurements existed when they did not.
Series = [4,6,5,9]
X = [[4,6], [6,5]]
y = [5,9]The target is the entry immediately after each input window.
2. Use a Trailing Summary When Individual Lags Are Unnecessary
A trailing mean summarises only the past window. It can reduce sensitivity to a single noisy reading, at the cost of discarding the order within that window.
A centred moving average is different: it can include observations after the position being summarised. That can help retrospective smoothing but can leak future information if used carelessly as a forecasting feature.
First trailing mean = (4 + 6) / 2 = 5
Second trailing mean = (6 + 5) / 2 = 5.5We calculate each summary from its input row before examining the target.
3. Keep Real Availability Separate From the Timestamp
A weather forecast issued yesterday might be available now, while tomorrow's measured rainfall is not. A record's measurement date alone does not prove it was available when a prediction was made.
Historical backtests should reproduce publication delays, late corrections, and missing readings where they matter. Replacing an old forecast with today's revised record can create an unrealistically easy problem.
Lagging a column is necessary in some tasks, but it is not a complete availability audit.
Build the row for one target day
The first prediction with two lags needs two earlier readings. Separate those inputs from the next value before building a whole table.
import numpy as np
readings = np.array([10, 12, 11, 15])
target_position = 2
features = readings[target_position - 2:target_position]
target = readings[target_position]
print(features.tolist())
print(int(target))[10, 12]
11The feature slice stops before the target position. Practice will repeat this alignment across every eligible target date.
4. Construct and Inspect Before Fitting
Print a few input rows with their target dates. Check the first and last rows manually, including the oldest and newest entries. This often reveals an off-by-one error more clearly than a model score does.
Botie's workshop constructs the past-only rows and averages each row. It is a moving-mean predictor, not an autoregressive model with fitted coefficients.
The next lessons decide what structure to model once the table is aligned.
5. Choose the Target Horizon before Building Rows
For a one-day forecast, the label follows the newest feature immediately. For a two-day forecast, an extra day lies between the newest available observation and the target. Shifting the feature window without shifting the target accordingly changes the task.
Print the first and last training rows with their time positions before fitting. This catches off-by-one errors more clearly than inspecting a final model score.
Build two-day targets from two known lags
The forecast origin is the index of the newest known reading. The target is two positions later.
import numpy as np
y = np.array([10.,12.,14.,16.,18.,20.])
rows, targets = [], []
for origin in range(1, len(y)-2):
rows.append(y[origin-1:origin+1])
targets.append(y[origin+2])
print(np.array(rows).tolist())
print([float(value) for value in targets])[[10.0, 12.0], [12.0, 14.0], [14.0, 16.0]]
[16.0, 18.0, 20.0]The intervening reading is not a feature. It would be unavailable at the stated origin.
6. A Future Calendar Entry and a Future Temperature Are Different Inputs
Tomorrow's weekday or a scheduled watering event may already be known today. Tomorrow's actual temperature is not. A forecast can use a weather forecast issued today, but training must use comparable historical forecasts rather than the later observed weather.
Record issue times for external inputs. Revised forecasts and backfilled measurements can leak later information into a retrospective feature table even when the target column is shifted correctly.
Check yourself
Questions on Parts 1 to 6
Question 1 of 4
Which row predicts 9?
Use the information below.
Series: [4,6,5,9]. Each target uses its two immediately preceding readings, older first.Try it with Botie
Build with Botie
Write and run Python