Predictive Analytics / Data Science
Forecasting & Decision Intelligence
Evaluation-Driven Demand Forecasting and Uncertainty-Aware Planning
An evaluation-driven forecasting workflow that transforms reservation transactions into daily room-night demand, compares forecasting strategies through rolling-origin backtesting, and generates channel-level predictions with uncertainty-aware planning scenarios.
Project Overview
Reservation transactions are not daily demand. The workflow validates 18,067 completed reservation records, expands stays into 51,696 room-night observations, and aggregates them by channel into complete daily time series.
Transactional data engineering meets forecasting experiments: temporal validation guides channel-specific model selection, then a 365-day demand forecast supports uncertainty-aware scenario planning.
Key Results
- Forecast Room Nights
- 31.6K
- 365-day base forecast estimate
- Lower Direct-Channel MAE
- 24%
- Versus a common 3-month baseline across model-selection backtests
- Historical Backtest Origins
- 4
- Rolling-origin temporal evaluation
51,696 historical room-night observations1,460 channel-level daily predictions
System Architecture
Forecasting / Analytical architecture
Every forecast starts with a boundary.
Historical room-night demand
Evaluation before extrapolation
Turn reservation intervals into daily demand. Test forecasting choices against time. Carry the selected channel models into an explicit planning horizon.
Completed, positive-length stays
Parse dates · retain checked-out stays
18,067 valid reservation records
Illustrative stay · departure date excluded
51,696 room nights
One row per occupied night.
Aggregate into daily channel counts.
Transformation check / expanded rows = sum of valid lengths of stay
One daily series per channel
Select a channel to trace its verified history window and forecast output.
Symbolic date × channel grid · yₜ denotes a daily count. No historical observations are plotted.
Mon → Sun
Compare weekday demand summaries
Calendar-month means
Inspect changes through time
Zero-fill date-channel gaps only within the accepted observation period, starting 2022-10-01.
Establish baselines
Seven-day seasonal-naive
Three-month recent mean
Test extensions & history
- Recent means · 1, 3, 6 months
- Channel × weekday means
- Linear-trend extrapolation
Channel-specific recent mean
Forecast = mean daily demand
over the selected channel history.
ŷ(c, t) = mean(Hc)
Weekday and trend experiments are not components of the final constant-mean forecast.
Rolling origins / Booking.com
6-month selected history · 2-calendar-month evaluationthrough
through
Each row advances the information cutoff. History stops before its origin; future observations are used only to measure errors. Compact layouts show each row on its own relative time axis.
MAE · RMSE · channel diagnostics
Compare average errors and variation between historical simulations.
Booking.com / 6 months
The same four origins informed selection. These are model-selection comparisons, not an independent final test.
6-month historical mean
→
18,200 room nights
Same daily mean projected across 365 dates
31,622 room nights
365 days × 4 channels
1,460 channel-level daily predictions
Branch into planning assumptions
Base: The aggregated point forecast, before scenario stress. All values are reported room-night totals.
Scenarios are planning assumptions, not calibrated prediction intervals. Two-month backtests do not validate a 365-day horizon. Revenue intelligence and broader decision-support functionality remain planned.
Text architecture & evidence scope
Foundation. Completed reservations with positive lengths of stay expand to occupied nights, including arrival and excluding departure. Expanded row counts are checked against total stay lengths. Daily counts are grouped by date and channel, with zero-fill limited to the accepted history window.
Development and evaluation. The initial April–May 2024 split tests seasonal-naive and recent-mean baselines. Rolling-origin experiments compare recent-mean history windows, weekday means, and linear trends at 2023-07-01, 2023-10-01, 2024-01-01, and 2024-04-01. Each origin uses only preceding history and evaluates the following two calendar months. MAE and RMSE inform channel-specific history-window selection.
Forecast and planning. The retained recent means use six months for Booking.com, three for Channel Manager, one for Direct, and three for IBE. History ends on 2024-05-31, before the 365-day forecast starts. Channel forecasts aggregate to the reported 31,622 room-night base. Downside and upside totals reflect ±8% stress applied to the unrounded base; reported totals are rounded independently.
Limits. The same backtests informed model selection and do not establish independent or year-ahead performance. Scenarios are assumptions, not probability intervals. Symbols and the example reservation illustrate data structure rather than raw observations. The source workbook is private; the existing processing totals are preserved rather than recomputed here. No deployed pricing engine, automated retraining, or revenue-optimization result is claimed.
365-Day Demand Forecast
Forecast period: –
Forecast room nights · annual channel mix
31,622
365 days · 4 channels
| Channel | Forecast | Share |
|---|---|---|
| BookingCom | 18,200 | 57.6% |
| ChannelManager | 4,297 | 13.6% |
| Direct | 754 | 2.4% |
| Ibe | 8,371 | 26.5% |
Evaluation-Driven Model Selection
Each origin simulates a historical forecasting decision using only information available at that time.
Origin 01
Origin 02
Origin 03
Origin 04
Available historyFollowing ≈2 months evaluated
Model-selection MAE
Room nights / day · lower is better- Common 3-month window
- Channel-specific window
BookingCom
6-month history5.3% lower MAE
Common 3-month window MAE: 6.01
Channel-specific window MAE: 5.69
ChannelManager
3-month history
Common 3-month window MAE: 2.61
Channel-specific window MAE: 2.61
Direct
1-month history24% lower MAE
Common 3-month window MAE: 4.73
Channel-specific window MAE: 3.60
Ibe
3-month history
Common 3-month window MAE: 4.67
Channel-specific window MAE: 4.67
Complexity was tested. Linear-trend extrapolation worsened average MAE for all four channels.
Engineered Through Evaluation
Channel-Specific Forecasting
- Problem
- Booking channels exhibit different levels of demand stability.
- Decision
- Select a history window for each channel through rolling-origin evaluation.
Complexity Must Earn Its Place
- Problem
- Weekday patterns and linear trends appeared useful in historical data.
- Decision
- Reject extensions that failed to improve out-of-sample performance consistently.
Leakage-Free Validation
- Problem
- Future information can accidentally enter historical experiments.
- Decision
- Enforce chronological information boundaries at every forecast origin.
Technology Stack
Data Engineering
- Python
- Pandas
- NumPy
Forecasting
- Recent-Mean Models
- Seasonal Baselines
- Linear Trends
- Channel-Specific Models
Evaluation
- Rolling-Origin Backtesting
- MAE
- RMSE
- Error Analysis
Visualization
- Matplotlib
Development
- Git
- GitHub
- Markdown
Explore the Full Implementation
Explore the forecasting experiments, temporal validation, Python implementations, visualizations, and documented engineering decisions.