Supervised Forecasting

Scope

The forecasting pipeline replaces a pure historical weekday/slot average with supervised zone-level demand and fare models. It is an optional strategy input; it does not replace the default Two-Step recommender because the fixed rollout benchmark does not show a downstream gain.

Data and temporal boundary

build_demand_panel constructs a complete 30-minute by 263-zone grid. Missing zone-slots have zero observed arrivals and missing conditional mean fare. Features start only after 336 historical slots are available.

The reported split is:

  • training: 2023-01-08 00:00 through 2023-01-20 23:30;

  • validation: 2023-01-21 00:00 through 2023-01-24 23:30;

  • recursive forecast: 2023-01-25 through the public holdout week.

Every lag, rolling statistic, and neighborhood statistic is computed from slots strictly earlier than its target. Model selection and blending use only the internal validation interval. The later public query/rollout interval is used as a separate downstream diagnostic.

Features

The LightGBM and XGBoost baselines share these inputs:

  • zone ID, weekday, hour, half-hour bucket, and time slot;

  • demand lags at 1, 2, 48, and 336 half-hour slots;

  • trailing demand means over 3, 48, and 336 slots;

  • mean, standard deviation, and maximum one-slot-lag demand among the five nearest reachable zones;

  • mean travel time to those reachable neighbors.

Unreachable OD entries are masked. They are never converted into artificial graph edges.

Outputs

For each zone and target slot the model produces:

  • predicted_demand_count, a non-negative Poisson intensity;

  • predicted_demand_probability = 1 - exp(-count), the probability of at least one passenger arrival;

  • predicted_expected_fare, the conditional mean fare estimate.

The probability is not a driver’s pickup-success probability. That event also depends on competing supply, demand depletion, queues, and driver behavior, which the current data and single-driver simulator do not identify.

Results and ablation

Model

Demand MAE

Demand RMSE

Fare MAE

Fare RMSE

Historical average

1.7273

5.9237

7.0103

12.8339

LightGBM

1.5114

5.0707

5.9526

10.6708

XGBoost

1.4956

5.0020

5.9633

10.7277

Selected LightGBM/historical ensemble

1.4868

4.9810

5.9188

10.6106

The ensemble demand MAE improvement has timestamp-block bootstrap 95% CI [0.1960, 0.2820]. Feature ablation demand MAE is 1.5344 without direct lags, 1.5632 without rolling features, and 1.5366 without neighborhood features, versus 1.5114 for the full LightGBM model.

Reproduction

python -m pip install -e ".[dev,forecasting]"
python -m scripts.train_forecaster
python -m scripts.run_forecasting_benchmark --runs 100

The forecast artifact covers the extra 2023-02-01 00:00 slot because a query exactly at 2023-01-31 23:30 is mapped to the next half-hour boundary.

Limitations

The deployed forecast is recursive over the entire week because the strategy interface cannot ingest newly observed arrivals online. Error therefore compounds. The current score also combines predicted count and fare with a hand-designed travel-time denominator; it was not optimized for the simulator reward. The paired rollout difference against historical Single-Step is -\(17.88/day with 95% CI [-\)38.15, $3.03], so no downstream improvement is claimed.