How Restaurants Know What You’ll Crave Before You Do
The Future of Food Forecasting
Imagine walking into your favorite café, and the daily special is exactly what you were craving—even though you never said a word. That’s not magic; it’s predictive ordering, powered by AI. Restaurants are starting to harness the same algorithms used in e‑commerce and logistics to forecast customer demand before it’s voiced. This isn’t just shaping menus—it’s transforming supply chains, staffing, and kitchen prep.
The Data Behind Your Dinner
Predictive ordering begins with demand forecasting models that ingest:
- Historical sales (SKU × store × day)
- External factors (weather, holidays, sports/events)
- Menu & pricing (promotions, price elasticity)
- Availability (stock‑on‑hand, supplier lead times)
- Local signals (regional tastes, search trends)
Classical time‑series (ARIMA/SARIMAX) captures seasonality; tree‑boosting (LightGBM/quantile loss) and deep models (LSTM/Transformers) capture nonlinear shifts—like sudden surges in iced drinks during heat waves or wings on game days.
A Credible End‑to‑End Pipeline
Minimum viable schema
store_id, sku_id, date, units_sold, price, promo_flag, stock_on_hand, weather_*, event_flags, dow, month, social_index?, lead_time_days?
Feature engineering
- Calendar features: DOW/holiday one‑hots; seasonal Fourier terms
- Lags/rolls: lag_1, lag_7, lag_28; rolling mean/std (7/28 days)
- Interactions:
temp × iced_drink_flag
,game_day × wings_category
- Price/promo elasticity features
- Mask stockouts (don’t learn from truncated demand)
Hierarchical, probabilistic forecasting
- Forecast at SKU × store, optionally reconcile to store/chain totals (bottom‑up or MinT)
- Train models that output quantiles (P10/P50/P90) for safety‑stock planning
- Backtest with rolling origins; metrics: sMAPE/MASE (point), Pinball loss (quantiles)
Simple Math Sketch (Newsvendor Logic)
For a single SKU/day, choose order quantity q to balance waste vs. stockout costs:
Minimize: c_w · E[(q − D)_+] + c_s · E[(D − q)_+]
Where: D ~ random demand, c_w = waste cost, c_s = stockout cost
Optimal service level (single-period approximation):
q* = F_D^{-1}( c_s / (c_s + c_w) )
I.e., order to the demand quantile set by your relative costs.
For multi‑day horizons, apply per day or solve as a coupled LP/MILP with storage and budget constraints.
Realistic Pseudocode (Production‑ish)
# DATA PREP
data = load_sales_weather_events() # multi-store, multi-sku
data = mask_stockouts(data) # remove/flag truncated demand
data = add_calendar_features(data) # DOW, holidays, Fourier seasonality
data = add_lags_rolls(data, lags=[1,7,28], rolls=[7,28])
data = add_interactions(data, ["temp*iced", "game_day*wings"])
# TRAIN/VALIDATE by STORE × SKU (hierarchical)
models = {}
for store in STORES:
for sku in SKUS[store]:
ds = data.filter(store, sku)
folds = time_series_folds(ds, horizon=28, n_folds=4)
best_model, best_score = None, +inf
for candidate in [SARIMAX_X, LGBM_Quantile, TFT]:
scores = []
for train, valid in folds:
m = candidate.fit(train.X, train.y)
q_fore = m.predict(valid.X, quantiles=[0.1, 0.5, 0.9])
scores.append(pinball_loss(valid.y, q_fore))
if mean(scores) < best_score:
best_model, best_score = m, mean(scores)
models[(store, sku)] = best_model
# FORECAST (probabilistic)
forecasts = {}
for key, model in models.items():
X_future = build_future_features(key, horizon=28, latest_weather, events)
forecasts[key] = model.predict(X_future, quantiles=[0.1, 0.5, 0.9])
# OPTIONAL: RECONCILE HIERARCHY (e.g., MinT)
forecasts = reconcile_hierarchy(forecasts, levels=["sku_store","store","chain"])
# INVENTORY / MENU OPTIMIZATION (one store)
for store in STORES:
F = forecasts[store] # dict: sku → daily quantiles
# Decision: order_qty[sku] ≥ 0
minimize Σ_s [ waste_cost[s]·E[max(q_s − D_s, 0)] + stockout_cost[s]·E[max(D_s − q_s, 0)] ]
subject to:
Σ_s (q_s·unit_cost[s]) ≤ budget_store
Σ_s (q_s·storage_vol[s]) ≤ cold_storage_cap
0 ≤ q_s ≤ supplier_limit[s]
solve → order plan + menu highlights
Minimal, Realistic Code Fragment (Python‑style)
# LightGBM quantile models (per SKU/store) + simple newsvendor decision
import numpy as np, lightgbm as lgb
q_models = {q: lgb.LGBMRegressor(objective='quantile', alpha=q) for q in [0.1, 0.5, 0.9]}
for q, m in q_models.items():
m.fit(X_train, y_train)
q_preds = {q: q_models[q].predict(X_future) for q in q_models} # arrays over horizon
# Choose order quantity by cost-weighted service level
service = cs / (cs + cw) # cs=stockout cost, cw=waste cost
# Use quantile interpolation across predicted distributions
stacked = np.vstack([q_preds[0.1], q_preds[0.5], q_preds[0.9]]).T
order_qty = np.quantile(stacked, service, axis=1)
# If many SKUs/constraints: send to LP/MILP (e.g., OR-Tools) using piecewise expectation
from ortools.linear_solver import pywraplp
solver = pywraplp.Solver.CreateSolver('GLOP')
q = {s: solver.NumVar(0, supplier_limit[s], f"q_{s}") for s in SKUS}
solver.Add(sum(q[s]*unit_cost[s] for s in SKUS) <= budget)
solver.Add(sum(q[s]*storage_vol[s] for s in SKUS) <= cold_storage_cap)
# Objective: Σ_s approx_expected_cost(q[s], quantile_scenarios[s])
# (Implement with piecewise linearization or scenario expansion)
solver.Minimize(sum(approx_expected_cost(s, q[s], scenarios[s]) for s in SKUS))
solver.Solve()
Innovation in Action (Real‑World Examples)
Real examples, not endorsements: Starbucks has publicly discussed using its Deep Brew AI for inventory/personalization. Chains like Domino’s have reported demand forecasting to improve delivery and reduce waste. These cases show predictive systems are operational today; specifics vary by brand and are evolving.
What This Means for Your Kitchen
- Restaurants: Lower waste, fewer stockouts, better labor and prep planning.
- Home cooks: Meal‑planning apps increasingly use lightweight forecasting—try apps that learn your patterns and suggest “next best” recipes.
Looking Ahead
Next‑gen systems will fuse probabilistic forecasts with real‑time sensors (smart fridges, prep‑station scales), auto‑replenishment, and dynamic menus. The more connected kitchens become, the more predictive ordering will quietly run in the background—so the right dish appears at the right time.
Question for readers: If an algorithm suggested tomorrow’s special or your next home‑cooked meal, would you follow it—or trust your gut?
Comments