Atul Iwale · Project 15 · Real data · Survival analysis

NYC Permit Approval Forecast

How long will the NYC Department of Buildings take to approve a major job's plans? Trained and tested on real DOB NOW plan-examination filings (New Buildings, alterations with a new certificate of occupancy, demolitions), March 2021 to September 2026. A quarter of them are still waiting, so the model uses survival analysis rather than ordinary regression.

Real public data: NYC Open Data, DOB NOW: BuildXGBoost accelerated failure time (in this app)Compared with Kaplan-Meier, Cox, random survival forestTime split: train 2021–23, test Jul 2024 – Jun 2025

Notebook 1: cleaning and exploration · Notebook 2: survival models · Source code · README

Forecast a filing

Describe the job as it would be filed. The model runs in your browser; nothing is sent anywhere.

Work included

Why open filings matter

The shortcut "average the filings that got approved" ignores the slow ones still waiting. Kaplan-Meier counts every filing, open ones included, for as long as they have been open.

Median days to approval, by filing year

Recent years look fast to the naive method only because their slow filings aren't approved yet.

Share approved, by days since filing (Kaplan-Meier)

How the models compare

Scored on 5,708 filings from July 2024 to June 2025, which no model saw during training or tuning. The C-index is the share of comparable pairs of filings put in the right order; AUC at 90 days is how well the model separates filings approved within 90 days from the rest; the integrated Brier score (IBS) measures probability error, lower is better.

Are the probabilities right? Approval within 180 days

Test filings in ten groups by predicted chance; observed shares use Kaplan-Meier. The naive model, trained only on approved filings, is over-optimistic.

How it works

  • 131,515 filing records reduced to one initial filing per job; 128 duplicate records, 180 undated filings and 21 impossible dates handled.
  • Open filings are "censored": they count as "not approved after this many days", never as a made-up end date.
  • XGBoost AFT models log(days) with boosted trees; open filings enter the training loss as "at least this long". Distribution and spread were chosen on the first half of 2024.
  • Only filing-day information is used. The job description and DOB's workload were tested and added little, so the app doesn't need them.
  • The browser runs the same trees as Python and checks itself against Python's predictions on load.

Honest limits