XGBoost hourly energy demand forecaster for PJM East - 145,366 observations across 16 years, with temporal feature engineering, hyperparameter tuning, and SHAP interpretability.
Watts next? This model knows.
| Metric | Validation | Test |
|---|---|---|
| MAPE | 0.77% | 0.84% |
| RMSE | 346 MW | 360 MW |
| MAE | 246 MW | 267 MW |
Sub-1% MAPE on an out-of-sample test year, with no weather data, no holiday calendars, and no external features. Just timestamps and lagged demand. The tight val/test gap (0.77% vs 0.84%) confirms the model generalizes across time periods without overfitting.
Takes 16 years of hourly electricity consumption data for the PJM East region, engineers 20+ temporal features (calendar, cyclical encoding, lag values, rolling statistics), and trains a hyperparameter-tuned XGBoost regressor to predict next-hour demand. The model is evaluated on a held-out test year (2017-2018) with detailed error analysis by hour and month, and explained with SHAP feature importance.
Hourly Energy Consumption - PJM East Interconnection hourly demand in megawatts (2002-2018). CC0 Public Domain license.
- Clone and install:
git clone https://github.com/lenamonj/the-power-hour.git
cd the-power-hour
pip install -r requirements.txt-
Download
PJME_hourly.csvfrom Kaggle and place it indata/. -
Run:
jupyter notebook the_power_hour.ipynb| Category | Features |
|---|---|
| Calendar | hour, dayofweek, month, dayofyear, weekofyear, quarter, is_weekend |
| Cyclical | hour_sin/cos, month_sin/cos, dow_sin/cos |
| Lag | 1h, 24h, 48h, 168h (1 week) |
| Rolling | 24h mean/std, 7-day mean/std |
| Trend | days_since_start |
- XGBoost over LSTM/Prophet. Gradient-boosted trees with engineered features consistently outperform deep learning and statistical models on tabular time series. Simpler, faster, more interpretable.
- Temporal splits only. Train on 2002-2016, validate on 2016-2017, test on 2017-2018. No random shuffling - that would leak future information into training.
- No external data. Weather, holidays, and economic indicators would improve accuracy but add dependencies. This notebook demonstrates what pure time series feature engineering can achieve.
- Low learning rate + early stopping. Tuned from [0.005, 0.01, 0.02] with up to 5,000 trees. The model finds its own stopping point on validation MAPE.
- SHAP over feature importance. XGBoost's built-in importance is biased toward high-cardinality features. SHAP values are theoretically grounded.
.
├── the_power_hour.ipynb # Full pipeline - one notebook
├── data/ # Kaggle data (not tracked in git)
├── requirements.txt # Python dependencies
├── LICENSE # MIT License
└── README.md # You are here
This project is licensed under the MIT License.
Built with Python, XGBoost, and public data. No proprietary tools required.