ECON 8310: Business Forecasting — Lecture 12
University of Nebraska at Omaha
The same regression you already know — returning a distribution for every coefficient.
OLS, which you have fitted since Lecture 2, solves for one best coefficient vector:
\[\hat{\boldsymbol{\beta}} = (\mathbf{X}^{\top}\mathbf{X})^{-1}\mathbf{X}^{\top}\mathbf{y}\]
The Bayesian version uses Lecture 10’s update rule instead:
\[p(\boldsymbol{\beta} \mid \mathbf{y}) \;\propto\; p(\mathbf{y} \mid \boldsymbol{\beta}) \cdot p(\boldsymbol{\beta})\]
Every coefficient comes back as a distribution: not an estimate plus an asymptotic error bar, but a full posterior you can ask questions of.
And Lecture 6 reappears: regularization is a prior. The posterior mode under a Normal prior is the Ridge estimate; under a Laplace prior, it is the LASSO estimate.
Log units on log price, SNAP, events, series and trend
with pm.Model() as model:
a = pm.Normal("a", y.mean(), 1, shape=J) # one per series
b_price = pm.Normal("b_price", 0, 1) # weakly informative
b_snap = pm.Normal("b_snap", 0, 1)
b_event = pm.Normal("b_event", 0, 1)
b_trend = pm.Normal("b_trend", 0, 1)
sigma = pm.Exponential("sigma", 1.0)
mu = a[idx] + b_price*lpc + b_snap*snap + b_event*event + b_trend*yr
pm.Normal("obs", mu=mu, sigma=sigma, observed=y)
idata = pm.sample(1000, tune=1500, chains=4)Do not standardize log price — with both in logs b_price is an elasticity, percent change in demand per percent change in price. lpc is log price centered within series, which fixed ESS 184 \(\rightarrow\) 3,097. J is the number of series (30), idx maps each row to its series, and yr counts years since the first week.
Three questions you can ask a distribution that you cannot ask a point estimate.
Fitted on the weekly panel, controlling for series and trend:
| Coefficient | Mean | 94% HDI | Reading |
|---|---|---|---|
b_price |
\(-0.493\) | \([-0.596,\ -0.387]\) | Inelastic: all of it above \(-1\) |
b_trend |
\(0.110\) | \([0.107,\ 0.113]\) | About 11% growth per year |
b_snap |
\(0.036\) | \([0.027,\ 0.046]\) | About a 3.7% SNAP-week lift |
b_event |
\(-0.003\) | \([-0.011,\ 0.004]\) | Spans zero |
The HDI — highest density interval — is the shortest interval holding 94% of the posterior, and it means what everyone wants: a 94% probability the coefficient is inside.
The last row is the useful one. b_event’s interval spans zero, so the data do not establish a direction. Two slides on, we ask whether it is also too small to matter.
Any question about \(\beta\) is a count of samples: one line each
Each answer is the share of the area past a line. Demand is inelastic in every draw; the half-percent question stays open. The usual p-value, against zero, gives only the direction.
b_event’s HDI spans zero: no direction. A ROPE — region of practical equivalence — asks a different question: is the effect too small to act on?
The width is a business choice, not a statistic. We use Homework 7’s \(|\beta| < 0.05\), about \(\pm 5\%\) a week; even at \(\pm 1\%\), 95% is inside.
Spans zero and inside the ROPE: negligible, stop looking. Spans zero and wide: still open, get more data. “Not significant” cannot tell them apart.
Which coefficients mean what you think they mean.
A DAG is a picture of what you believe causes what, drawn from domain knowledge before the model. It decides which variables belong in the regression.
Confounder: causes both predictor and outcome. Must be controlled, or it leaks into your coefficient.
Collider: caused by both. Controlling for it creates a spurious association (McElreath 2020).
So “add every control you have” is bad advice, and no model fit settles it.
Whether a DAG is right is a business question, not a statistical one.
Two confounders move price and units together: the category and time.
Food is cheap and sells in volume; prices and volumes both rose, 2011–2016. Removing the series means alone flips the sign. With both removed: \(-0.493\), HDI \([-0.596, -0.387]\). The naive \(-2.805\), HDI \([-2.856, -2.756]\), is nearly six times too large, at half the width.
Confidently, precisely wrong: a tight interval says the model is sure, not that it answers your question. Only the DAG protects you from an omitted confounder.
Push a scenario through the draws to get a distribution of outcomes, not one number.
What if we raise price 5%?
With an elasticity near \(-0.493\), a 5% price rise implies roughly a 2.4% fall in units, 94% of the posterior between \(-2.9\%\) and \(-1.9\%\).
The decision follows. Revenue changes by a factor \(1.05^{\,1+b}\), which rises exactly when \(b > -1\). Every draw is above \(-1\), so \(P(\text{revenue rises}) = 1.00\): about \(+2.5\%\) on average.
Valid only to the extent the DAG is — this is a causal claim about intervening on price.
From classical time series to Bayesian hierarchical models: a complete forecasting toolkit.
| Method | Data | Uncertainty | Interpretable | Strengths |
|---|---|---|---|---|
| ETS / ARIMA (L01–02) | Univariate TS | CI | High | Fast, automatic |
| GAM / Prophet (L03) | TS + predictors | Limited | High | Nonlinear + interpretable |
| Decision Tree (L04) | Tabular | No | High | Rule-based explanation |
| Random Forest (L05) | Tabular | OOB error only | Medium | Robust, minimal tuning |
| XGBoost (L05) | Tabular | No | Low | Interactions; 781 on our board |
| Ridge / LASSO (L06) | Tabular | No | High | Best on our board: 744 |
| FFN / 1D CNN (L07–08) | Tabular / TS | No | Low | Flexible nonlinear fits |
| LSTM / Transformer (L09) | Sequences | No | Very low | Long-range dependencies |
| Bayesian (L10–12) | Any | Full posterior | High | Uncertainty, small samples |
XGBoost’s 781 is from an earlier xgboost; the pinned 3.4.1 gives 792.
No single method dominates. Choose based on: (1) data type and size, (2) need for uncertainty quantification, (3) need for interpretability, (4) time to deploy. In practice, combine: your scoreboard’s winner for the point forecast (here, LASSO) and a Bayesian model for the intervals.
Bayesian regression: a posterior per \(\beta\), whose mode is Ridge (Normal) or LASSO (Laplace).
Ask the posterior directly: mean, HDI, \(P(\beta_j\) past a threshold\()\), mass in a ROPE.
Draw the DAG first: control confounders (here, series and time), never colliders.
Scenarios: push a counterfactual through the draws to get a distribution of outcomes.
No single method is best: pair an accurate point forecast with Bayesian intervals.
ECON 8310 | University of Nebraska at Omaha