Skip to content
HotelMind AI

ML

Restaurant Demand Model

Source: hotelmind-ml/docs/models/restaurant.md

Model Card: Restaurant Demand Forecasting

Purpose

Forecast per-meal (breakfast/lunch/dinner) revenue and estimated order quantity for a branch/date, to support F&B staffing and inventory decisions.

⚠️ Trained entirely on synthetic data — see Known Assumptions below before using this model's output for any real decision.

Input Features

FEATURE_COLS (src/pipelines/restaurant_pipeline.py):

FeatureSource
month, quarter, day_of_week, is_weekend, is_holiday, is_eventsrc/features/calendar_features.py
total_orders_lag_1, total_orders_lag_7src/features/time_series_features.py
total_orders_rolling_mean_7same module

Target Variable

Three independent targets, one per meal: breakfast_revenue, lunch_revenue, dinner_revenue (float) — all synthetic (see below).

Algorithm

3 independent XGBoost models (RestaurantDemandModel, one per meal period; XGBRegressor, n_estimators=250, max_depth=4, learning_rate=0.05, subsample=0.8, colsample_bytree=0.8, random_state=42). One model per meal rather than one shared model, since meal-period demand patterns are treated as independent (per the model's own docstring).

Training Dataset

data/features/restaurant_features.parquet — 1,605 rows, generated by src/pipelines/synthetic_data.py::generate_restaurant_daily from data/raw/restaurant_daily_synthetic.csv. Chronological 80/20 train/test split per meal.

Evaluation Metrics

MealMAERMSEMAPE
Breakfast112.79150.9161.4%
Lunch88.47116.5065.2%
Dinner161.14212.8660.8%

Source: reports/latest_restaurant.json. These metrics measure how well each model fits the synthetic generator's own occupancy-driven signal plus injected noise — not real-world predictive accuracy.

Strengths

  • Demonstrates a complete, working per-meal demand-forecasting pipeline (feature engineering → training → evaluation → API) that would function identically against real restaurant order data if it ever becomes available — only load_data() would need to change.
  • Quantity estimation includes an internal cross-check (derive_meal_quantities) between two independent formulas, logging divergence >20% — a real-data-quality safeguard, not just a synthetic artifact.

Limitations

  • No real restaurant order data exists anywhere in this project — not in the raw Kaggle CSVs, not in the Phase 3 warehouse. Every value this model was trained on is fabricated.
  • expected_quantity in the API response is a simple derived ratio (predicted_revenue / avg_item_value), not a separately-trained quantity model.

Known Assumptions

  • Synthetic generation formula: `revenue = base_rate[meal] * occupied_rooms
    • day_of_week_multiplier * (1 + seeded_noise), deterministic via np.random.default_rng(seed=42)— reproducible, not pure random noise, but still fabricated data (seereports/final_phase4/known_limitations.md` items 1 and 9).
  • avg_item_value per meal is a fixed constant in the generator, not a measured value.

Future Improvements

  • Replace the synthetic seed with real F&B transaction data if a POS/ restaurant-ordering data source is ever integrated into the warehouse.
  • Consider a single multi-output model across meals if real data reveals shared demand drivers, rather than 3 fully independent models.