Article / Forecasting

Forecasting with mathematical intuition

Understand exponential smoothing, ARIMA, supervised forecasting, rolling backtests, and prediction intervals through equations and practical examples.

Aayush Raj Regmi9 min read
In this article · 9 sections

Forecasting asks a deceptively simple question: what can we say about a future observation using only information available now? The final clause is the difficult part. A model can look excellent if its features, validation split, or data cleaning accidentally contain knowledge from the future.

Imagine managing stock for a small chain of stores. You need next week’s demand to decide how much to order. A forecast that is slightly more accurate on average may still be less useful if it badly underestimates festival demand or provides no indication of uncertainty. The right method depends on the decision, the forecast horizon, and the information available at ordering time.

Define the prediction before choosing the model

Let yty_t be demand at time tt. A forecast made at time tt for hh periods ahead is written y^t+h∣t\hat y_{t+h\mid t}. The vertical bar reminds us that the prediction must use information available at tt, not information discovered later.

Specify the unit, frequency, horizon, update schedule, and decision. “Forecast sales” is underspecified. “Every Sunday evening, predict daily unit demand for each store-product pair over the next seven days” defines a testable task. Also record whether the target is demand or observed sales: when an item is out of stock, sales can understate demand.

Distinguish three kinds of features. Historical demand is observed at forecast time. Calendar information, such as a scheduled holiday, may be known in advance. Future weather or an unannounced promotion may be unknown. A backtest using realized future weather answers an easier question than a deployed system using a weather forecast.

Separate patterns and build honest baselines

An additive mental model is:

yt=ℓt+st+et,y_t = \ell_t+s_t+e_t,

where ℓt\ell_t captures level and possibly trend, sts_t describes a repeating seasonal pattern, and ete_t is the unexplained remainder. This is a way to reason about structure, not a claim that every series truly decomposes into three independent parts.

If seasonal variation grows with the level, a multiplicative description may fit better. A logarithm can turn multiplicative effects into additive ones for strictly positive observations, but zeros require a deliberate treatment. Exponentiating a predicted log value generally does not give the conditional mean on the original scale; account for the target statistic and transformation bias.

Start with naive forecasts. A last-value forecast uses y^t+h∣t=yt\hat y_{t+h\mid t}=y_t. A seasonal naive forecast repeats the last observed season. For weekly seasonality in daily data, next Monday resembles the last observed Monday. These methods are cheap, interpretable, and surprisingly hard to beat on some series.

A model that cannot reliably beat an appropriate baseline has not earned its operational complexity. Compare improvements by horizon and business segment, not only through one aggregate score.

Exponential smoothing is controlled adaptation

Simple exponential smoothing updates a level estimate:

ℓt=αyt+(1−α)ℓt−1,0≤α≤1.\ell_t=\alpha y_t+(1-\alpha)\ell_{t-1},\qquad 0\le\alpha\le1.

Think of α\alpha as a response knob. If the previous level was 100100, the new observation is 110110, and α=0.3\alpha=0.3, the updated level is 103103. A large value reacts quickly; a small one smooths over short-lived noise.

Repeated substitution shows why the method is called exponential: older observations receive weights proportional to α(1−α)j\alpha(1-\alpha)^j. Under this simple model, future point forecasts are flat at the estimated level. A persistent trend needs more structure.

Holt’s linear method maintains a level and slope:

ℓt=αyt+(1−α)(ℓt−1+bt−1),bt=β(ℓt−ℓt−1)+(1−β)bt−1,y^t+h∣t=ℓt+hbt.\begin{aligned} \ell_t &= \alpha y_t+(1-\alpha)(\ell_{t-1}+b_{t-1}),\\ b_t &= \beta(\ell_t-\ell_{t-1})+(1-\beta)b_{t-1},\\ \hat y_{t+h\mid t} &= \ell_t+h b_t. \end{aligned}

The level update compares the latest observation with where the previous trend expected the series to be. The slope update smooths the newest estimated change. Straight-line extrapolation can become implausible far ahead, so a damped trend can reduce the contribution of distant future increments.

Seasonal exponential-smoothing models add a seasonal state, with additive or multiplicative choices. The exponential-smoothing chapter of Forecasting: Principles and Practice develops these variants and their state-space interpretation. The practical question is which combination matches the series, not which acronym is newest.

ARIMA models dependence in a different way

An autoregressive model relates a value to earlier values. For a stationary AR(1) process:

yt−μ=ϕ(yt−1−μ)+εt,∣ϕ∣<1.y_t-\mu=\phi(y_{t-1}-\mu)+\varepsilon_t,\qquad |\phi|<1.

If ϕ=0.8\phi=0.8, a deviation of ten units above the long-run mean contributes eight units to the next conditional expectation, then 6.46.4 two steps ahead. The effect decays rather than becoming a permanent linear trend. The formula assumes a stable process with innovations whose conditional mean is zero.

A moving-average term models dependence on past innovations, not a moving average of observations. Differencing handles some forms of nonstationarity: Δyt=yt−yt−1\Delta y_t=y_t-y_{t-1} describes changes, while seasonal differencing uses yt−yt−my_t-y_{t-m} for seasonal period mm.

ARIMA combines autoregressive terms, differencing, and moving-average terms. Differencing is not a universal preprocessing step. Too much differencing can add unnecessary noise, and a structural break does not automatically become predictable after subtraction. Examine the series and residuals, and compare out-of-sample forecasts. The ARIMA chapter provides the detailed model family and diagnostics.

Turn forecasting into supervised learning carefully

Tree models and neural networks can use lags, rolling summaries, product attributes, and known future variables. A training row might include demand at lags one, seven, and fourteen; a trailing seven-day mean; day of week; and a promotion already scheduled at the forecast origin.

The rolling mean must stop before the target. If predicting demand on day tt, a trailing mean containing yty_t leaks the answer. Fitting a scaler or imputer on the full dataset also leaks information about the future distribution, even if it does not directly reveal the target value. Fit preprocessing inside each training window.

Multi-step forecasting creates another choice. A recursive strategy predicts one step, feeds that prediction back as a lag, and repeats. It is economical but can accumulate errors. A direct strategy learns a separate prediction function for each horizon. A multi-output strategy predicts the entire horizon together. Compare all strategies under the actual horizon you need; a one-step leaderboard cannot settle a seven-day planning problem.

Global models share information across many related series. This can help when individual products have little history. But product identifiers alone do not solve cold starts: a new product needs transferable information such as category, price, or planned distribution. Large pretrained time-series models are another candidate, not an exemption from leakage control, baseline comparison, or domain evaluation.

Backtest from the point of view of the past

A random split usually lets the model train on observations that occur after its validation examples. Instead, choose several forecast origins. At each origin, fit using only the earlier data and predict the same horizon that deployment requires. This is time-series cross-validation.

Here is a self-contained seasonal-naive backtest for a regularly spaced numeric sequence. It evaluates every horizon separately and never reads future observations to construct the prediction.

from statistics import mean


def seasonal_naive(history, horizon, season=7):
    if len(history) < season:
        raise ValueError("Need at least one full season")
    last_season = history[-season:]
    return [last_season[h % season] for h in range(horizon)]


def rolling_mae(values, initial=56, horizon=7, step=7):
    by_horizon = [[] for _ in range(horizon)]
    for cutoff in range(initial, len(values) - horizon + 1, step):
        forecast = seasonal_naive(values[:cutoff], horizon)
        actual = values[cutoff:cutoff + horizon]
        for h, (prediction, observation) in enumerate(zip(forecast, actual)):
            by_horizon[h].append(abs(observation - prediction))
    if not all(by_horizon):
        raise ValueError("Not enough observations for a complete backtest")
    return [mean(errors) for errors in by_horizon]

Validate dates, missing periods, and units before using this function. In a real pipeline, materialize what was known at each origin, including data revisions and reporting delays. An expanding window uses all available history; a sliding window deliberately forgets older observations. Choose between them based on whether older regimes remain relevant.

Use validation origins for tuning and reserve a later untouched period for the final comparison. Repeatedly changing a model after inspecting the final test set turns that set into another tuning set.

Choose a metric that matches the decision

Mean absolute error is:

MAE⁡=1n∑i∣yi−y^i∣.\operatorname{MAE}=\frac1n\sum_i|y_i-\hat y_i|.

It expresses a typical absolute miss in the target’s units. RMSE squares errors before averaging and then takes the square root, so large misses receive more weight. Neither metric accounts for different costs of overprediction and underprediction unless you explicitly modify the objective.

A scaled metric can compare series with different magnitudes. For seasonal period mm, one common training-based scale is:

MASE⁡=mean absolute forecast error1T−m∑t=m+1T∣yt−yt−m∣.\operatorname{MASE}=\frac{\text{mean absolute forecast error}}{\frac{1}{T-m}\sum_{t=m+1}^{T}|y_t-y_{t-m}|}.

The denominator is computed from the training data, not the future evaluation period. If it is zero, the ratio is undefined and needs a documented handling rule. Percentage errors have their own difficulties when actual demand is zero or near zero. Report both a comparable aggregate and segment-level results in meaningful units.

Forecast a distribution when the decision needs one

A point forecast cannot describe risk on its own. A prediction interval aims to cover a future observation with a stated frequency under the model’s assumptions. It is different from a confidence interval for an estimated mean. See the forecasting text’s discussion of prediction intervals.

For illustration, if a forecast error is approximately normal with known standard deviation σh\sigma_h, a central 95% interval is approximately y^±1.96σh\hat y\pm1.96\sigma_h. The standard deviation is horizon-specific. In a random walk with independent innovations of variance σ2\sigma^2, the hh-step forecast error variance is hσ2h\sigma^2, so uncertainty grows with the square root of the horizon in standard-deviation units. Other processes need different calculations.

When understocking and overstocking have different costs, predict the relevant quantile. If the underage cost is CuC_u and the overage cost is CoC_o, the simple single-period newsvendor decision uses quantile Cu/(Cu+Co)C_u/(C_u+C_o) under its assumptions. With costs nine and one, the relevant quantile is 0.90.9, not the median. This is a decision rule for an illustrative inventory model, not a universal ordering policy.

Quantile forecasts can be trained with pinball loss:

ρτ(u)=u(τ−1{u<0}),u=y−q^τ.\rho_\tau(u)=u\bigl(\tau-\mathbf1\{u<0\}\bigr),\qquad u=y-\hat q_\tau.

A 90% interval that covers only 60% of observations is overconfident. Check coverage by horizon and segment, as well as interval width. Very wide intervals can achieve coverage while being operationally useless. Calibration methods also have assumptions; ordinary exchangeability-based guarantees do not automatically apply to a changing time series.

Practice: a forecast that survives deployment

Choose one regularly spaced demand series and document when each feature becomes available. Compare seasonal naive, exponential smoothing, and a lag-based supervised model across at least six forecast origins. Report errors separately for each horizon and for high-demand periods.

Then introduce an artificial reporting delay. Remove the most recent observation from the information available at each origin and rerun the comparison. This exercise often reveals more about a forecasting system than swapping one sophisticated model for another.

The best forecasting workflow makes its information boundary, assumptions, and uncertainty visible. A complicated model can be useful, but only after the evaluation problem is honest enough to recognize the improvement.

Sources & further reading

The explanations and worked examples in this article are original. These papers and official references support the technical background and provide further detail.

  1. exponential-smoothing chapter of Forecasting: Principles and Practice ↗
  2. ARIMA chapter ↗
  3. time-series cross-validation ↗
  4. prediction intervals ↗
Back to all writing