Tomorrow's forecast
National demand in MW, by half hour (UK time). The shaded band is the model's 80% range.
How good is it? The model against NESO
Average error (MAPE) by month on data the model never saw in training. Lower is better. Both forecasts are scored against NESO's own published outturn, half hour by half hour.
One week, half hour by half hour
The last week of the test period: what happened, the model, and NESO.
What drives the forecast
Share of the model's learning that each input explains.
Live track record
Every forecast published by this page is saved before the day starts and scored when the actual demand comes in. No backtest, no hindsight.
How it works
- CollectHalf-hourly national demand since 2018 and NESO's day-ahead forecast (NESO open data), the newest days from Elexon, hourly weather from Open-Meteo for 32 places (cities weighted by population, solar regions and wind regions), and bank holidays (GOV.UK).
- Estimate hidden generationRooftop solar and small wind farms lower the demand the grid sees. Two models learn their output from sunshine over the solar regions and wind at turbine height, so the main model can work with the smoother underlying demand.
- Build featuresTime of day, day of week, holidays, season, temperature and how it compares with recent days, and underlying demand from 2, 7 and 14 days before, all relative to its recent level. Full days are at least two days old, because the forecast is made the morning before. Only last night's demand is newer.
- TrainThree LightGBM models with a quantile loss give the 10th, 50th and 90th percentiles. Early stopping on the newest part of the training data picks the number of trees, and conformal calibration widens the range. Every run is logged with MLflow.
- Test honestlyThe backtest trains only on data before the test period and is compared with a seasonal naive forecast (same half hour last week) and with NESO's real forecast.
- ServeA daily GitHub Actions job fetches the new data, retrains, forecasts tomorrow, saves the forecast to a history branch and publishes this page. A FastAPI service in Docker serves the same forecasts.
docker build -t energyforecast . docker run -p 8000:8000 -v "$PWD/artifacts:/app/artifacts" -v "$PWD/data/clean:/app/data/clean" energyforecast curl localhost:8000/forecast/latest