Research & methodology / October 2026

How we built
HeatAhead.

From public housing records to an inspection priority list. This is the data we prepared, the models we trained, the tests we ran, and the evidence behind the estimates you see.

Daily-model inputs
36 features from records and weather
Original training set
622,362 building-day examples
2025–26 ranking tests
71 days plus eight cold-spell evaluations
Follow the training process

01 / Introduction

Why we built HeatAhead.

New York City law requires landlords to keep apartments at 68°F during the day and 62°F overnight from October 1 to May 31. Every winter, thousands of buildings fail to do so. When the heat goes out, tenants call 311, and the Department of Housing Preservation and Development (HPD) sends an inspector. The city largely works through these complaints in the order they arrive, so by the time an inspector reaches a building, the people inside may already have been cold for days. Since July 2017 alone, New Yorkers have filed more than 1.8 million heat complaints.

Using several open data sets and machine learning models, we set out to answer one primary question: on the evening before a freezing day, can a building’s complaint, violation and property history, combined with the weather, tell us which buildings are most likely to lose heat in the next few days? In particular, we wanted to know whether a ranked list built this way would put inspectors in front of failing buildings sooner than the approaches the city can use today, such as answering complaints in the order they arrive or looking at last winter’s complaint counts.

We expected a building’s own recent complaint history to be the strongest signal, because a heating system that has failed recently is likely to fail again. We also expected that how a building responds to cold weather, its size and age, the record of its owner’s other buildings and the condition of its boiler would each add information. This page explains the data we used, how we prepared it, and the methods we used to test those expectations. The website itself presents the results: each building’s estimated risk, the citywide map and the inspection priority list.

02 / The data

Where our data comes from and how we prepared it.

The data for this analysis describes New York City’s residential buildings, the heat complaints their tenants filed, the violations that inspectors recorded, the owners and boilers behind each building, and the weather on every day of the heating season. All of it is public and free to access. We downloaded every file on October 16, 2026, and the complaint and violation records run through October 14, 2026.

The table below lists each source, the agency that publishes it and what we took from it. Each name links to the original data set.

What goes into the analysis
Data set and publisherWhat it contains and how we use it
HPD complaints ↗
HPD, NYC Open Data
Every heat and hot water complaint filed through 311: 2,219,844 records from July 1, 2017 to October 14, 2026. This is the source of our outcome and of most of our strongest inputs.
HPD violations ↗
HPD, NYC Open Data
Violations that an inspector confirmed in person: 223,430 heat violations (orders 666, 966 and 674) and hot water violations (orders 670 and 970). We use them as history and as an independent check on our outcome.
PLUTO properties ↗
Department of City Planning
Version 26v2 of the city’s property file, limited to the 172,485 tax lots with three or more residential units. It gives each building’s units, floors, floor area, year built, alterations, community district and location.
HPD owner registrations ↗
HPD, NYC Open Data
The registered owner and managing agent of each building. We matched 136,589 owners, which lets us count how many buildings an owner holds and how their other buildings performed last winter.
DOB boiler inspections ↗ & DEP boiler permits ↗
Departments of Buildings and Environmental Protection
892,914 boiler inspection reports, which record defects, and 91,370 boiler permits, which record the fuel each boiler burns.
NOAA Central Park ↗ & Open-Meteo ↗
NOAA and Open-Meteo
Daily minimum and maximum temperature, snow and wind for every day since January 1, 2017 (3,572 days, with none missing), plus the seven day forecast we use to detect an approaching cold spell.

How the sources fit together

Because these records come from four city agencies and one federal agency, they do not share a single identifier. Complaints, violations and PLUTO identify a property by its BBL, the ten digit borough, block and lot number of the tax lot. Boiler records identify a building by its BIN, the Department of Buildings’ building number, and owner registrations use HPD’s own building ID. We joined each source only on the identifier it was published with, and then summarized everything at the level of the BBL. We also stored every identifier as a whole number before joining, because some files store the BBL as a decimal number, and a decimal BBL silently fails to match its whole number twin.

Cleaning the complaint records

The complaint file required the most preparation. Its 2,219,844 rows describe 2,196,887 distinct complaints, because one complaint can list several problems, each on its own row. We kept the two problem types that describe a heating failure, “NO HEAT” and “NO HEAT AND NO HOT WATER,” which left 1,853,073 rows. We then removed 6,650 rows that had no BBL and could not be placed on a property, and kept only complaints at lots in our building table, which left 1,703,315 rows describing 1,694,922 distinct complaints at 62,451 lots. Finally, we counted each complaint once per building per day, so that a complaint repeated across rows never counts twice. The result is 1,148,420 building days with at least one heat complaint.

For the violation records, we kept only the five heat and hot water order numbers and removed 23,607 records dated before 2010, which include inspection dates as early as 1968 that are either entry errors or too old to describe a building today. For the boiler records, we count only reports dated before the winter being studied, so that a later inspection can never inform an earlier prediction. The weather record needed no repair.

These steps mean our study covers buildings with three or more apartments that have some heat complaint or violation history. A building enters a ranking only if it has at least one heat complaint or violation on record, because a building with no history gives a model nothing to learn from, and no method we tested could find the failures in those buildings. The winter outlook, which estimates each building’s chance of losing heat at least once this winter, covers 63,727 buildings. The cold-day ranking, which estimates the chance of a heat failure within 48 hours of a freezing day, covers 67,125 buildings. The cold-day ranking is slightly larger because it also counts buildings whose only record is a hot water violation, while the winter outlook counts heat violations only. One more detail matters for reading the results: a BBL describes a tax lot rather than a single building, so a large complex with several buildings on one lot appears in our data as a single record.

The outcome we predict

Public records do not say when a boiler stops working, so we had to define a heat failure from what is recorded. We say a building has a heat failure when it receives two or more distinct heat complaints across two consecutive days. We require two complaints rather than one because a single complaint often describes one cold apartment or a call that leads nowhere. We checked this choice against inspectors’ records: a single isolated complaint was followed by a confirmed heat violation within seven days 4.78% of the time, while a cluster of two or more was followed by one 8.93% of the time, 1.87 times as often. Confirmed violations are rare even for real failures because inspectors cannot reach every complaint in time, so we train on the complaint based outcome and keep the confirmed violation, within seven days, as a separate check.

Privacy and ethics

The complaint and violation files include apartment numbers. Our modeling pipeline never loads that column, and our separate complaint analysis replaced every apartment number with a secure one way code before building any table, so no apartment number appears in any table, model input or page on this site. Every estimate describes a whole building. We also recognize that complaints depend on people choosing to report a problem, and that some communities report less often than others. A building with a quiet record is not necessarily a building without problems, and we discuss what that means for the results in the limitations section below.

03 / Modeling

How we built and trained the models.

Our modeling uses supervised machine learning: we show a model many past examples of buildings together with what happened next, and it learns which patterns came before a heat failure. This section explains how we turned the cleaned records into model inputs, how we built the training data, which methods we used and why, and how we tested them.

Turning records into model inputs

Each training example is one building on one heating season day, described by 36 inputs calculated from the records above. The inputs fall into seven families. Previous winters count the building’s complaints and violations over the last one and two seasons, flag buildings with five or more complaints in each of the last two seasons, and count last season’s whole building complaints, which usually mean the boiler itself failed rather than one apartment. Recent activity counts the building’s complaints in the previous 2, 7, 14 and 30 days and measures how many days have passed since its last complaint and last violation. Cold response measures, over the previous two winters, the share of frigid days (below 20°F), freezing days (20°F to below 32°F) and cold days (32°F to below 45°F) on which the building had a complaint. This separates a building with constant problems from one that mainly struggles when the temperature drops. Property inputs come from PLUTO, and owner and boiler inputs describe the owner’s portfolio and the boiler’s recorded defects and fuel. Nearby reports count complaints at other buildings on the same tax block in the previous two days, because buildings that share an owner or a heating plant tend to fail together. Finally, weather and calendar inputs describe the day’s temperature, snow and wind and how far into the cold season the day falls.

The 36 daily-model inputs, grouped by what they describe
Input familyInputsWhat we calculate
Previous winters6One and two season complaints and violations, a chronic complaint flag and last season’s whole building complaints.
Recent activity7Complaints in the last 2, 7, 14 and 30 days, days since the last complaint and violation, and whole building complaints in the last 14 days.
Cold response3Complaint rates on frigid, freezing and cold days over the prior two winters.
Property6Units, year built, alteration flag, floors, floor area and community district.
Owner and boiler4Owner portfolio size, complaints at the owner’s other buildings, boiler defects and oil fuel.
Nearby reports1Complaints at other buildings on the same tax block over the previous two days.
Weather and calendar9Minimum and maximum temperature, the previous day’s minimum, the three day rolling minimum, the change from the previous day, snow, wind, weekday and days into the cold season.

The time rule

A model can look far better than it really is if its inputs accidentally contain information from the future. To prevent this, every input for a building on a given day uses only records dated before that day. Season level history uses only earlier seasons, recent activity windows end on the evening before, and fields that are only known after the fact, such as a complaint’s final status or closing date, are never used. We wrote automated tests that fail if any of these rules is broken.

Building the training data

Using every building on every day would produce tens of millions of examples, nearly all of them days without a failure. Instead, we kept every heat failure from the 2018 to 2019 winter through the 2024 to 2025 winter and added twice as many randomly chosen days without one. After removing buildings with no prior history, the training set contains 622,362 building days. Because this sample contains far more failures than real life does, the model’s raw scores overstate the true chance of a failure, which is why every probability we show passes through a separate calibration step, described below.

The machine learning methods we use

Our main models are gradient boosted decision trees. A decision tree sorts buildings into groups by asking a series of yes or no questions about their inputs, such as whether a building had more than three complaints in the last 14 days. Gradient boosting builds hundreds of small trees one after another, with each new tree correcting the errors left by the trees before it. We chose this family because it is the most consistently accurate method for tables of counts, dates and measurements like ours, it handles missing values and very different scales without extra preparation, and it lets us explain which inputs a model relies on.

The original model averages two implementations of the same idea, XGBoost and scikit-learn’s HistGradientBoosting, each built from 400 trees with a maximum depth of 6 and a learning rate of 0.08. Averaging two models smooths out the quirks of either one. Its scores then pass through isotonic regression, a calibration method that learns how raw scores map to the share of buildings that actually failed, using every eligible building rather than the sampled training data. Calibration changes the numbers we display but never the order of the ranking.

We built two more models for the two other questions the site answers. The winter outlook uses one example per building per season, with 21 inputs measured on October 1 and the outcome “lost heat at least once that winter.” It is a HistGradientBoosting model trained on 305,413 building seasons, with its own isotonic calibration. The cold spell model is trained directly on the task inspectors face: on the evening before a cold spell, which buildings will fail during it? We chose its settings with a twelve trial search scored only on the 2024 to 2025 winter, then trained it five times with different random seeds and averaged the five, which removes most of the variation between individual training runs.

We also tested methods that work differently, to make sure the gradient boosted trees were not simply the first idea we tried. These include a model trained to rank buildings directly, a graph neural network that learns from links between buildings that share an owner or a block, a survival model that predicts when a building will first fail, a model trained on confirmed violations instead of complaints, and a statistical method called conformal risk control that sets alert thresholds with a guaranteed maximum miss rate. Finally, we used backward feature elimination, which removes the least useful input one at a time across three model types, to learn which inputs actually carry the signal. The development record below lists what each of these changed.

How we test the models

We split the data by time, never at random, so that a model is always tested on a winter it has never seen. Models learn from the 2018 to 2019 through 2023 to 2024 winters, the 2024 to 2025 winter is used to choose between versions and settings, and the 2025 to 2026 winter is held out and scored once at the end. On each test day, the model ranks every eligible building in the city, and we measure precision at k: of the k buildings ranked highest, the share that actually had a heat failure. We use this measure because an inspection team can only visit a limited number of buildings, so what matters is whether the top of the list is right. We compare every model with simple rules the city could use without any model, such as ranking by complaints in the last 14 days. To check that the results were not one lucky winter, we repeated the test six times, each time training only on earlier winters and testing on the next one, and we measured uncertainty by resampling whole days and whole cold spells rather than individual buildings.

  1. Winters 2018 to 2024Train candidate models.
  2. Winter 2024 to 2025Choose between versions and settings, then refit.
  3. Winter 2025 to 2026Test once on the held out winter.
Which model supplies each part of the website?
M1 / Evaluation

The original daily ensemble

Supplies the fixed submission benchmarks. Its training stops before the 2025 to 2026 winter.

M2 + M3 / Cold-day queue

Deployment refit and calibration

The same recipe refit with the latest completed winter included, with its scores passed through the daily calibrator. Because it has seen the test winter, it is never used to report test performance.

M4 / Winter outlook

The season level model

HistGradientBoosting with 21 start of season inputs, trained on 305,413 building seasons. Its calibrated output supplies the winter estimate and the map colors.

M13 / Cold spells

The tuned five seed spell model

Supplies the cold spell benchmark and the dispatch simulation. It is reported separately from the M2 and M4 files behind the public website.

04 / Evaluation

How useful is the top of the list?

An inspection team can only visit so many buildings. We measure precision at k: among the first k buildings in the ranking, how many later meet the complaint-cluster label? This is more useful for prioritization than a single “accuracy” number for every building.

Original model · top 100 per spell

86.1%

About 86 of the first 100 buildings met the complaint-cluster label during a spell, averaged across eight test spells.

Approx. 95% bootstrap range: 81–92%.*

Checks across earlier winters

6 of 6

The model beat the 14-day complaint-count rule in all six forward-moving winter tests.

Past performance; future winters can differ.

Spell precision: original model, later spell model and a simple baseline
First buildings in listM1 originalM13 later spell model14-day complaints
10086.1%90.1%77.1%
50064.6%65.4%59.9%
1,00051.4%51.4%47.8%
2,50034.8%35.2%31.9%

*The range comes from the saved follow-up statistical analysis, which resamples whole cold spells. Its rerun varies slightly from the original model run; the original submission figure above stays fixed. Eight spells are a small sample.

How the four prediction windows differ
Fixed M1 submission benchmarks · precision at the top 100
EvaluationResultWhat we watch for
Daily / 48 hours69.1%Complaint clusters across day d and d+1, averaged over 71 freezing days.
Cold spell86.1%A cluster during the spell plus one grace day, averaged over eight spells.
Daily / 30 days96.6%An outcome within 30 days of a daily ranking.
First-spell watchlist99%Rank once at the first spell; follow the top 100 through the rest of winter.

A daily freezing day has minimum temperature below 32°F. A test cold spell has at least two consecutive days with mean temperature below 32°F. We rank once on the spell’s eve, then observe its outcome window.

The 30-day result is an outcome-follow-up window, not a 30-day weather forecast. The 99% watchlist result is not the separate M4 season model’s calibration. These tests cannot be read as one universal accuracy percentage.

For the daily 48-hour estimate, the approximate 95% interval widens to 66–71% when consecutive cold-day blocks are resampled together. The saved inference run varies slightly from the frozen point result, as noted above.

Six-winter backtest and statistical checks
Each fold tests the next winter’s 10 coldest days · daily precision at 100
Test winterModel14-day baseline
2020–2155.8%54.0%
2021–2265.0%62.9%
2022–2366.5%60.4%
2023–2469.1%64.4%
2024–2574.4%68.5%
2025–2672.8%70.3%

These are separate forward-moving tests, not the 71-day headline evaluation. Each model sees only winters before its test winter, with the same settings used across folds.

For uncertainty, the saved analysis uses 2,000 bootstrap resamples of whole days or spells. A second check resamples 16 blocks of consecutive cold days together, because days in one cold snap are related. We do not treat thousands of buildings in the same spell as thousands of independent weather events.

The follow-up daily run beats the 14-day baseline on 67 of 71 days at the top 100, with one tie and three losses. A paired sign-flip test using 100,000 draws gives p ≈ 0.00001. On the eight spell comparisons, the original model beats the baseline in all eight (exact one-sided p = 1/256). These describe this test set, not certainty about future winters.

How much of the whole problem does the final ranking find?

Precision measures how many picks were right. Recall and cumulative gain ask how many of all the complaint-cluster outcomes the ranking finds.

  • For M13, the top 1% of the ranked list captures 25.7% of spell outcomes on average.
  • The top 10% captures 75.3%. Random selection would capture about 10%.
  • At 2,500 buildings, mean recall is 54.3% across the eight spells.
  • Mean precision-recall AUC is 0.434, compared with a mean outcome rate of 3.1%. AUC summarizes the ranking over many possible list lengths.

These are M13 research results over the eligible population. They are not calibration results for every building, and they do not measure outcomes in properties outside the ranking.

What our inspection simulation suggests

We replayed 183,384 building-day complaint cases from 2025–26, comparing first-come-first-served dispatch with a model-prioritized queue. At an assumed capacity of 700 inspections a day and a 14-day case expiry, the simulation estimated 7.8% more confirmed violations and a mean wait of 2.03 days instead of 3.12 for complaint-cluster cases.

These are simulated results, not an observed city deployment or proof that outages were prevented. Prioritizing also left some lower-ranked cases unvisited: 5,546 complaint-cluster cases expired in that scenario. That trade-off matters alongside the average improvement.

05 / Development record

What improved the model, and what did not.

We kept the original submission results fixed and gave later models their own names. A more complicated method had to improve the ranking at useful list lengths, not just produce an impressive score at one cutoff.

The five feature rounds that led to the original model
Recorded development runs · daily precision at 100, 48-hour outcome
ChangeResult
14-day complaint rule61.7% · the baseline to beat
Initial planned features65.7%
Cold response, recency & history eligibility67.8%
Building-wide reports67.7% · 96.3% at the separate 30-day horizon
Portfolio, boiler & ensemble work68.7%
Short-term velocity, neighbors & season clock69.1% · fixed original submission figure

These are development runs, not independent estimates of each feature’s causal effect. Small changes can be training noise. In a separate feature-addition study, we also found boiler defect counts that included later records and tested replacements dated before each season; performance changed by only about 0.15 percentage points.

Alternative models, results and decisions
Later experiments · results use different targets where stated
ExperimentFinding & decision
M7 · learning to rank87.9% spell precision at 100, but 33.7% at 2,500 versus M1’s 34.8%. Not adopted.
M8 · confirmed violations30.2% at 100 versus a 16.5% baseline on the separate seven-day violation target. Kept as an enforcement experiment.
M9 · GraphSAGETwo-layer graph network over owner/block connections, trained on LinuxONE. 84.9% spell precision at 100. Not adopted.
M11 → M13 · spell trainingTrain directly on the spell outcome, tune settings, average five seeds. M13 reaches 90.1% at 100; reported separately.
M12 · tuned daily model20 validation-winter trials; 89.2% spell precision at 100. Retained as a later daily configuration.
M10 / M10b · failure timingStrong timing order, but absolute dates and probabilities missed the calibration bar. Not shipped.
M14 · complaint categories89.0% versus 89.0% for an identically trained control. The extract has categories, not narrative text. Not adopted.
Season watchlist trendsYear-over-year trend inputs did not meaningfully improve M4. Not adopted.
T8 · alert thresholdsOn the test winter, broad/strict thresholds missed 7.4% / 21.1% of daily outcomes. This is a separate alert-coverage experiment, not inspection precision.
Feature removal studyStill in progress in the supplied October 18 report. Validation findings are not presented as final test results.
How the alert thresholds were tested

The threshold experiment fixes a model trained on 2018–19 through 2022–23, then uses 102 freezing days across the next two winters to choose broad and strict alert levels. It checks those levels on the 71 freezing days of 2025–26.

The broad level missed 7.4% of daily complaint-cluster outcomes, but would alert about 13,107 buildings per cold day on average. The strict level missed 21.1% and would alert about 5,220. Coverage comes with a larger notification volume.

These results do not guarantee the same miss rate in a different future winter. The email worker uses the tested threshold file when it is present; otherwise it has a documented fallback. An alert threshold and a top-50 inspection queue serve different purposes.

06 / Reading the estimates

A good ranking and a useful percentage are different tests.

The top-100 results describe the quality of a list. A building’s percentage needs another check: calibration. We group similar predictions and compare them with the share of buildings that actually had complaint clusters. A group estimated near 60% should have an observed rate near 60%.

Winter risk

Estimates whether a building will have at least one complaint cluster over the season, using information available at its start. This is the estimate used to color the risk map.

Cold-day risk

Estimates the shorter 48-hour outcome around freezing weather, with recent complaints and weather included. It answers a different question, so its percentage can differ.

For season risk, we fit the calibration adjustment on half the 2025–26 building records and checked it on the other half. Daily calibration uses a sample from the full ranking population, because sampling training examples changes the apparent complaint rate. Calibration checks are separate from the ranking tests.

See the calibration table used by this website

The daily calibrator uses 142,000 score/outcome pairs: 2,000 buildings sampled on each of the 71 test days. Those 2025–26 outcomes help fit the calibration adjustment, so the ranking holdout and the calibration protocol have different roles. A raw training score is not a calibrated probability.

This table comes from the same published data as the building page’s reliability table. It is not a copied table from an older model report. The observed share counts the complaint-cluster outcome, not a confirmed violation.

Published season-risk calibration · data build 2026-10-17
Risk groupBuildingsMean predictionObserved share
0–5% 12,3072.4% 2.3%
5–10% 4,3707.5% 7.4%
10–20% 3,66014.5% 13.7%
20–35% 2,78824.9% 23.7%
35–50% 2,97840.7% 39.6%
50–65% 1,30458.9% 55.6%
65–80% 1,13573.8% 73.5%
80–100% 1,32691.2% 91.3%

Group averages can differ by several percentage points. Calibration is a measured check, not proof that any one building’s outcome is known.

07 / Engineering

What we ran on IBM Z.

The data pipeline, model training, alternative-model experiments and inspection simulation ran on the team’s IBM LinuxONE environment. We also benchmarked IBM Snap ML on the same s390x machine to measure how quickly a model could score buildings.

Snap ML batch-scoring benchmark · 3-core guest

481,356 building predictions per second

A separate benchmark model, not a website load-time measurement. This result uses Snap ML’s CPU tree engine; it does not demonstrate Telum accelerator offload.

Benchmark comparison, hardware checks and publication steps
Measured on the same 3-core s390x guest
EngineBuilding scores / secondp99 single-row latency
XGBoost358,6290.71 ms
Snap ML benchmark twin481,3560.51 ms

Snap ML’s benchmark twin was trained natively with 200 rounds and depth 6. Missing values were imputed to −1 for that engine. This tests serving speed; it is not a new accuracy result for the XGBoost deployment model.

The team also benchmarked hardware-assisted compression on the 361 MB complaint extract: 2,077 MB/s versus 33 MB/s with that acceleration disabled. The AES-256 file benchmark measured 728 MB/s versus 106 MB/s without the relevant CPU instructions. These are separate hardware measurements, not evidence of tree-model accelerator offload.

After evaluation, we refit the deployment model, export calibrated building scores, and run the asset builder to produce the small public files the site reads. Model exchange uses portable JSON rather than moving Python pickles between laptop and mainframe.

  1. Prepare labels and features: 01_build_panel.py.
  2. Fit and evaluate: 02_train.py, 03_evaluate.py, 05_backtest.py and 07_spell_eval.py.
  3. Generate deployment and winter scores: 06_final_scores.py and 09_season_risk.py.
  4. Package the website’s public data: web/build_assets.py.

Heavy processing stays on LinuxONE. The public Vercel site serves precomputed building estimates and maps, while account and monitoring features connect to backend services. The replay lets us demonstrate how incoming complaints can update a building’s priority.

08 / The help assistant

How the models and the chat fit together.

The prediction training above uses structured records and boosted trees. The help assistant uses a different process. Our complaint extract contains categories and flags, not narrative text; we did not fine-tune a language model on complaint stories.

  1. Match common wording locally

    The browser searches our 29 written help topics using keywords, related words and typo handling. This works without a language-model connection.

  2. Use an existing LLM for an unfamiliar question, if configured

    The optional server connection asks a pretrained model to classify the question into a known topic. It receives the current question and, when relevant, the previous topic ID; it does not receive the whole chat or account records.

  3. Offer choices when the meaning is unclear

    The assistant can show several “Did you mean…” options. A provider suggestion is offered for the visitor to choose, rather than being presented as a new factual answer.

  4. Show the written answer and its page links

    The selected topic loads an answer from the help library. Building risk still comes from the prediction pipeline; the LLM does not generate a building score or perform account actions.

The LLM response contract and fallback

The prompt asks for a topic identifier, not a free-form answer. Its JSON schema permits only known topic IDs or “unknown.” For example:

{ "topic": "inspector" }

Building IDs are removed before an optional provider call, and common private-input patterns are rejected. If the provider is unavailable or returns an invalid topic, the chat falls back to the local help library. The site does not store the conversation.

09 / Limits & next steps

What this work cannot tell us yet.

In addition to explaining our methods, it is important to discuss the limits of our data and of our analysis. The first and largest limit is that our outcome is built from complaints. A complaint depends on a tenant choosing to call 311, and some buildings and communities report problems less often than others. A quiet record therefore does not establish that a building is safe, and a model trained on complaints can only learn the failures that people reported. We use confirmed violations as a second check, but those are limited by how many inspectors are available.

Our coverage is also incomplete. We study buildings with three or more apartments, and we rank only buildings with some complaint or violation history, so a building that is missing from the map or not individually ranked should not be read as having zero risk. Some property facts are current snapshots rather than historical records: ownership comes from today’s registrations, so our tests on past winters inherit today’s owners. Because a BBL describes a tax lot, a large complex can appear as one record and rank highly partly because its many units generate many complaints.

There are limits to the analysis as well. Our tests use the weather that actually occurred as a stand in for a forecast. We measured archived 24 to 48 hour forecasts at about two degrees Fahrenheit of error, so live performance should be close, but it is not identical. Our final test covers a single held out winter with eight cold spells, which is a small sample, and a citywide result can hide differences between boroughs, building types and neighborhoods. We also built a model that estimates when a building will first fail, but its estimates were not reliable enough to show on this site.

Our next steps are to test the models on another winter, to audit how well they work across communities, and to try the tool with the people who would use it. Those checks matter before anyone uses these rankings to allocate public resources.

10 / The team & the record

Built by NYU Tingineers.

We built HeatAhead during the IBM Z Datathon in October 2026. The work spans data cleaning, weather and building analysis, model training, evaluation, backend services and the website.

This page draws on the team’s October 18 complete model report, checked against the training code and published website data. That report also covers the feature removal and tuning experiments, which finished on October 18.

Our project record includes the feature pipeline, training scripts, model comparisons, statistical checks and deployment instructions. Model artifacts use portable JSON for exchange between machines. Raw extracts, credentials and resident-level records are excluded from the website package. Source is available on request while the team finalizes the license.

Questions about the method, a possible mistake, or working together? Email heataheadnyc@gmail.com.

HeatAhead is an independent datathon project, not an NYC311 or HPD service. Method notes updated October 18, 2026.