Urban Energy Demand
URP 530 Final Project Prototype
What am I trying to do?
Cities are often described as “systems,” but that word hides how messy and human they really are. Energy demand is shaped not only by weather and time, but by routines, institutions, calendars, habits, and unexpected disruptions. A weekday in January does not behave like a football Saturday in September. A heat wave does not just raise demand, it literally changes how people live through the day, when buildings cool, and when systems get stressed.
This project started with a simple question:
Can I build a lightweight AI system that forecasts urban energy demand and communicates the results in a usable way?
More specifically, I wanted to build a prototype to predict Ann Arbor energy demand through a forecasting and dashboard system that predicts likely demand patterns, identifies peak usage windows, and presents both live-style forecasts and historical validation in a way that is legible to non-specialists.
Staying within the limits of this class, my goal was not to build a utility-grade control room or a perfect digital twin. Rather, it is meant to be a realistic prototype that has both technical forecasting and urban decision-making; a model strong enough to generate useful signals, and a dashboard simple enough to communicate those signals clearly.
1. Project Contexts / Goals
At its core, this project attempts to create an AI that can help people better understand and anticipate stress in urban infrastructure systems.
I focused on electricity demand because it is one of the clearest examples of a city system that is both technical and social. Demand rises and falls according to weather, work schedules, weekends, holidays, and recurring institutional patterns. That makes it a strong candidate for forecasting, as well as a good reminder that prediction is never just about “the grid.”
The specific goal of the project was to build a prototype that could:
Forecast hourly electricity demand
Identify likely peak-demand hours
Evaluate how well the model performs on held-out historical data
Present forecast outputs and validation results through an interactive dashboard
Why does this matter?
Urban infrastructure systems are under increasing stress. Heat waves, electrification, EV adoption, and population growth all intensify pressure on electricity systems. Even a simple forecasting tool can help frame where and when strain is likely to occur.
As discussed in our course, there is now an increasingly popular discourse about smart cities, digital twins, and urban intelligence, but much less attention to how these systems are actually built from constrained data, imperfect proxies, and tradeoffs between sophistication and interpretability. This prototype is an attempt at highlighting some of these limitations and looked over roadblocks.
Finally, I wanted this project to be grounded in urban technology based logic, not just machine learning logic. A technically strong model is not enough if it cannot answer the kinds of questions cities actually ask:
When is risk highest?
How trustworthy is the model?
What kinds of days does it fail on?
What hidden assumptions are baked into the data?
The goal, then, is having a working model as well as a thorough understanding of what it means to apply AI in urban systems responsibly.
2. Methods
This project used a relatively simple workflow:
Build a master hourly dataset from public data
Engineer features relevant to demand forecasting
Train the XGBoost regression model
Evaluate the model using time-based validation
Build a dashboard showing forecast and validation outputs
The overall project architecture is as follows:
Data and training setup
Because utility-grade city demand data is usually private, I used public proxy data to construct the training dataset. The master table was built by combining:
Hourly electricity demand data
Hourly weather data
Calendar-based indicators such as holidays
The unit of analysis was one row per hour. In other words, the model was not consuming raw sequences in the way a language model does. It was consuming a structured hourly feature table.
The training setup looks like this:
Y variable (target): hourly electricity demand (
demand_mw)X variables (features): weather, calendar, lagged demand, and rolling demand statistics
The most important feature groups are as follows:
Calendar / time features
These help the model learn recurring patterns
hour of day
day of week
month
day of year
week of year
weekend flag
holiday flag
Weather features
These help the model respond to environmental conditions
temperature
dew point
relative humidity
wind speed
nonlinear temperature terms
heat/cold indicator flags
temperature-humidity interaction
Lag features
These give the model explicit memory of recent and recurring load behavior
previous hour demand
previous 24-hour demand
previous 48-hour demand
previous 72-hour demand
previous 168-hour demand (same hour last week)
Rolling features
These help summarize recent trends
rolling 6-hour mean
rolling 12-hour mean
rolling 24-hour mean
rolling 24-hour standard deviation
rolling 168-hour mean
This was, the model doesn’t have to “discover” all temporal structure from scratch, as I am already explicitly encoding the most relevant temporal relationships into the feature table.
Why XGBoost instead of GRU, LSTM, or another deep learning model?
This was one of the most important methodological choices in the project.
At first glance, it might seem like energy demand forecasting should use a sequential deep learning model such as an LSTM or GRU. Those models are often associated with time-series prediction. But for this project, I believe XGBoost was the better fit.
The main reason is that this was not a massive, high-frequency, multi-sensor dataset. It was a moderately sized hourly tabular dataset with strong structured features. With one row per hour, the training table was on the order of tens of thousands of observations, not millions. For example:
1 year of hourly data ≈ 8,760 rows
2 years ≈ 17,520 rows (current training dataset)
3 years ≈ 26,280 rows
5 years ≈ 43,800 rows
After lag and rolling feature creation, the usable modeling table becomes slightly smaller because the earliest rows are dropped.
That is enough data for a strong machine learning model, but not necessarily enough to justify a more complex recurrent architecture. In this setting, XGBoost has several advantages:
It performs well on structured tabular data
It handles nonlinear threshold effects well
It trains quickly and is easier to debug
It supports clearer interpretability
In an urban systems context, it is not enough to predict well. It is also useful, if not more so, to understand why the model thinks demand will peak. A tree-based model works very well when the main logic of the problem can be represented as interactions like:
high temperature + weekday + late afternoon
recent high demand + recurring daily cycle
summer pattern + humidity surge
In other words, XGBoost is especially strong when you already know which kinds of features are meaningful and can encode them directly.
It is important to note, however, that GRU or LSTM might become more attractive if the project was scaled up in any capacity, like longer time horizons, finer-grained data, or looking at multiple cities and data touchpoints at once.
Training and validation
The model was trained using a time-based train/test split, essential for forecasting. The training data needs to come earlier in time, and the test data later in time, so that validation mimics a real forecasting setting.
Performance was evaluated using:
MAE (Mean Absolute Error)
RMSE (Root Mean Squared Error)
MAPE (Mean Absolute Percentage Error)
Daily peak-hour accuracy
That last metric is especially important because one of the main product goals was not only to estimate demand generally, but to correctly identify the highest-demand hour of the day.
3. Outcomes
The outcome of the project is a working prototype with two major components:
1. A trained hourly demand forecasting model
The model predicts electricity demand based on recent demand history, weather, and calendar effects.
2. A lightweight Streamlit dashboard
The dashboard presents:
Forecast metrics
Hourly forecast charts
Forecast tables
Historical actual vs predicted performance
Worst-error-day analysis
A simple explanation panel
The dashboard is structured into two views:
Live Forecast
Historical Validation
This helps the user immediately know the difference between what the model is predicting now and how well the model has performed on past held-out data.
That distinction matters because many AI demos blur prediction and proof. A model can look impressive if it is only showing its forecasts, but without validation you do not know how much to trust it. On the other hand, a validation-only dashboard can feel backward-looking and disconnected from operational use. Putting both in the same interface made the system more legible.
Training validation results
The validation metrics were strong:
MAE: 984.83
RMSE: 1487.47
MAPE: 1.21%
Daily peak-hour accuracy: 1.00
Interpreting those in plain language:
The model’s average hourly error was around 985 MW.
It occasionally made larger misses, reflected in the higher RMSE.
The average percentage error was only about 1.2%, which is very strong for this kind of prototype.
Most strikingly, the model correctly identified the exact daily peak hour across the test set.
That does not mean the model is perfect, and those results should still be stress-tested against more unusual days. But they do suggest that the model captures the broad structure of demand very well.
Interactive output
The dashboard includes several useful components:
actual vs predicted charts for the test period,
a next-24-hour or live-today forecast chart,
a forecast table showing hourly expected demand,
a worst-day analysis table and selectable error-day plot,
and a simple explanation panel describing the forecast and what likely drives it.
4. Reflections
This project, and overall course, have pushed me to think critically about AI not as a magical layer added to cities, but as a process of translating urban complexity into data, features, assumptions, and interfaces.
One thing I learned early on is that the hardest part of applied AI is often not the model, and in this case, it was actually the data pipeline, feature logic and validation design. Building the master dataset required much more care than simply fitting a model. That alone was a useful reminder that real AI systems are built on data engineering decisions that often disappear from the final interface.
It also sharpened my understanding of what “smart” urban infrastructure actually means. A model that predicts demand well is useful, but it is not neutral. It depends on what data is available, what proxy is used, what is excluded, and what counts as success.
For example, in this prototype:
The demand signal is a proxy, not direct utility telemetry
The weather inputs are public and limited
The model is built to forecast patterns, not explain power-system physics
This means the system is best understood as a decision-support prototype, not a full operational grid-management platform.
More importantly, this project reinforced for me that urban planning and urban tech domain expertise matters. Someone approaching this only as a machine learning problem might focus on squeezing out another fraction of a percent in predictive performance. But domain expertise changes the questions you ask. It shifts, or perhaps expands, the focus of the project from just the accuracy of the model to the kinds of urban behavior it may highlight, what decisions this forecast may influence, who benefits from its existence and who inevitably suffers a loss.
Urban planning knowledge also changes how we interpret infrastructure. Energy demand isn’t just a technical time series. It is connected to housing form, mobility, climate adaptation, institutional schedules, and neighborhood vulnerability. This means that a peak-demand forecast is also a heat-risk question, a load spike can be related to building systems and land use, and a model failure on holidays or event days can reveal something about how urban rhythms are organized.
This project also made me more cautious about the rhetoric around AI in cities. It is easy to imagine systems like this as steps toward a seamless smart-city future. But even a small prototype shows how much these systems depend on simplification. Forecasting can be useful, but if it is framed carelessly, it can create a false sense of objectivity. Overall, this assignment advanced my understanding of AI by making me work through the entire chain; from raw public data, to feature engineering, to model selection, to validation, to interface design, to critical reflection about how such a system would actually function in an urban setting.







