flowchart LR
A["Training set<br/>t = 1 … T"] -->|forecast origin| B["Test set<br/>t = T+1 … T+H"]
ECON 8310: Business Forecasting — Lecture 1
University of Nebraska at Omaha
Every business decision made today depends on expectations about tomorrow.
| Domain | The question someone is actually asking |
|---|---|
| Operations & supply chain | How much inventory should Walmart order for Black Friday? How many nurses does a hospital need next Tuesday night? |
| Finance & risk | Will credit card defaults rise next quarter? What will the Fed Funds rate be in six months? |
| Marketing & strategy | How many units will this new product sell in year one? What is the lifetime value of this customer cohort? |
| Macro & public policy | Will GDP grow by 2% or 3% next year? What will unemployment be in Q4? |
Every one of these is a decision waiting on a number. A decision is only as good as the forecast it rests on.
Time Series
A time series is an ordered sequence of observations \(\{y_1, y_2, \ldots, y_T\}\) where \(t\) indexes time.
Notation for the whole course:
Under squared-error loss the best forecast is the conditional expectation, \(\hat{y}_{t+h|t} = \mathbb{E}[y_{t+h} \mid \mathcal{F}_t]\), where \(\mathcal{F}_t\) is everything known at time \(t\).
Any series can be decomposed into four parts (additive form): \(y_t = T_t + S_t + C_t + I_t\).
Which parts matter depends on the series: retail sales are trend + seasonality, quarterly GDP is trend + cycle, daily stock returns are mostly irregular.
Ignoring seasonality causes large, systematic errors. A non-seasonal model on monthly retail data will consistently under-forecast December and over-forecast January — every single year.
Before presenting any model, check that it beats a naive benchmark: a model that cannot beat the baseline has zero value. Each forecast (red) is built from a line (blue):
CA_1 FOODS; RMSE over the 52 shaded test weeks. In the M4 Competition many machine learning models failed to beat simple exponential smoothing (Makridakis et al. 2020).
Recent observations should carry more weight than old ones.
Most classical methods weight every observation equally — but what if the world changes? After a store renovation, equal weights keep forecasting the old store for months.
Exponential weighting: an observation \(k\) weeks old gets weight \(\alpha(1-\alpha)^k\). High \(\alpha\) = short memory; low \(\alpha\) = long memory:
Fitted \(\alpha\) on two aisles of one store. Log scale: each week back is the same step down, \(\times(1-\alpha)\).
SES Update Equation
The level \(\ell_t\) closes the fraction \(\alpha\) of each week’s gap (\(0 < \alpha \leq 1\)); the forecast is flat.
\[ \ell_t = \alpha\, y_t + (1-\alpha)\,\ell_{t-1} = \ell_{t-1} + \alpha\,(y_t - \ell_{t-1}), \qquad \hat{y}_{T+h|T} = \ell_T \]
Large \(\alpha\) chases every wiggle; small \(\alpha\) is smooth but slow. SES nests both benchmarks: \(\alpha = 1\) is naïve, \(\alpha \to 0\) the historical mean. CA_1 FOODS. No trend, no season.
SES is flat. For a trending series, track the level \(\ell_t\) and the slope \(b_t\):
Holt’s Linear Exponential Smoothing (Holt 2004)
Level: \(\ell_t = \alpha\, y_t + (1-\alpha)\,(\ell_{t-1} + b_{t-1})\)
Trend: \(b_t = \beta^*(\ell_t - \ell_{t-1}) + (1-\beta^*)\,b_{t-1}\)
Forecast: \(\hat{y}_{T+h|T} = \ell_T + h\,b_T\)
Straight lines get unrealistic far out. For \(h > 6\), the damped trend multiplies each week’s rise by \(\phi\) (\(0 < \phi < 1\)), so the forecast levels off under \(\ell_T + b_T\,\phi/(1-\phi)\).
Holt-Winters Additive Method (Winters 1960)
\[ \begin{aligned} \ell_t &= \alpha(y_t - s_{t-m}) + (1-\alpha)(\ell_{t-1}+b_{t-1}) \\ b_t &= \beta^*(\ell_t - \ell_{t-1}) + (1-\beta^*)\,b_{t-1} \\ s_t &= \gamma(y_t - \ell_{t-1} - b_{t-1}) + (1-\gamma)\,s_{t-m} \\ \hat{y}_{T+h|T} &= \ell_T + h\,b_T + s_{T+h-m} \qquad (m = \text{seasonal period};\ h \le m) \end{aligned} \]
Additive seasonality:
Multiplicative seasonality:
US retail’s December spike grows as overall sales grow: multiplicative.
Needs at least \(2m\) observations to initialize (\(m=12\) for monthly data).
Hyndman and Athanasopoulos (2021) unify every exponential smoothing method as a state space model: Error × Trend × Seasonal. Trend and season set the forecast’s shape:
The error, A or M, changes the intervals, not the shape. Additive error with a multiplicative season is unstable, so 9 × 2 − 3 = 15 models. Automatic selection: fit all 15, keep the minimum AIC (ETSModel in statsmodels). Schematic shapes, not data.
Forecasting without evaluation is not science — it is storytelling.
Draw each out-of-sample error \(e_{T+h} = y_{T+h} - \hat{y}_{T+h|T}\) as a square. CA_1 FOODS, the 52 test weeks:
\[\text{MAE} = \tfrac{1}{H}\sum_{h=1}^{H} |e_{T+h}|\]
\[\text{RMSE} = \sqrt{\tfrac{1}{H}\sum_{h=1}^{H} e_{T+h}^2}\]
MAE is the average side (dashed). RMSE is the side of the average square (filled), so \(\text{RMSE} \geq \text{MAE}\).
A tie on MAE, not on RMSE: five big misses carry 40% of SES’s squared error. When big misses are costly — a stockout — prefer RMSE.
RMSE and MAE come in the units of \(y_t\), so they compare models on the same series. To compare across series, scale the errors:
\[ \text{MAPE} = \frac{100\%}{H}\sum_{h=1}^{H}\left|\frac{e_{T+h}}{y_{T+h}}\right| \qquad\qquad \text{MASE} = \frac{\text{MAE}}{\displaystyle\frac{1}{T-m}\sum_{t=m+1}^{T} |y_t - y_{t-m}|} \]
The MASE denominator is seasonal naïve’s average miss on the training data. \(\text{MASE} < 1\): smaller errors than that; \(\text{MASE} > 1\): worse. It is one of the M4 Competition’s two accuracy measures (Makridakis et al. 2020).
MAPE breaks down when \(y_t\) is near zero; MASE does not. MASE \(< 1\) is no win over seasonal naïve on the test weeks: on CA_1 FOODS both score 0.59.
Never evaluate a forecast model on the data used to fit it. In-sample fit measures how well the model memorized the past, not how well it predicts the future.
flowchart LR
A["Training set<br/>t = 1 … T"] -->|forecast origin| B["Test set<br/>t = T+1 … T+H"]
Never randomly shuffle time-series observations. Use TimeSeriesSplit in scikit-learn, never KFold: shuffled or not, KFold lets future data train the model — data leakage that makes results look excellent and forecast badly.
What we will cover, and how it fits together.
| Part | Lectures |
|---|---|
| I. Time series | 1. Intro, ETS & evaluation (today) 2. ARIMA & VAR 3. Generalized additive models |
| II. Tree-based | 4. Decision trees 5. Tree ensembles: random forests & boosted trees 6. Regularization & model selection |
| III. Deep learning | 7. Neural networks (PyTorch) 8. CNN architectures 9. RNNs, LSTMs & Transformers |
| IV. Bayesian | 10. Foundations 11. Time series & hierarchical models 12. Bayesian linear regression |
Lecture 13 closes the course with a synthesis of all four parts. Python throughout: statsmodels, scikit-learn, XGBoost, PyTorch, Prophet, pyGAM, PyMC.
The Python stack: statsmodels (ETS, ARIMA, VAR) · scikit-learn (models, pipelines, cross-validation) · xgboost (gradient boosting) · torch (neural networks) · prophet and pygam (GAMs) · pymc (Bayesian models).
By the end of the semester you will be able to:
Under squared loss the best forecast is the conditional expectation.
Always beat a benchmark first: naïve, seasonal naïve, mean, drift.
Exponential smoothing weights the past geometrically; \(\alpha\) sets how fast it forgets.
SES → Holt (+ trend) → Holt-Winters (+ season): all ETS models, chosen by AIC.
Evaluate out-of-sample, never shuffled. RMSE punishes big misses; MASE compares across series.
Next: ARIMA & VAR — a regression-based approach to time series with rich autocorrelation structure.
ECON 8310 | University of Nebraska at Omaha