Gridlock Hackathon 2.0 — Theme 2 (Event-Driven Congestion) · Target: Bengaluru Traffic Police (BTP) & Flipkart
This system forecasts the congestion impact of event-driven disruptions and recommends proportional officer deployment. Built on 8,173 real-world BTP incident records — no synthetic data.
See METHODOLOGY.md and FEATURE_AVAILABILITY.md for the full data audit, scoring logic, and statistical disclosures.
🌐 Live App · 📹 Demo Video · 💻 GitHub
| Feature | Description |
|---|---|
| Live Disruption Map | Stratified sample of historical incidents across Bengaluru, color-coded by severity |
| Response Recommendation Engine | Rule-based prediction using only report-time data (Priority + Corridor Frequency) — no post-resolution leakage |
| Post-Event Learning Replay | Chronological calibration replay showing predicted vs. resolved severity gap over time |
| Explainability Panel | Per-prediction breakdown of score components; flags corridor fallback inline if lookup misses |
| Data Limitations Drawer | Full-screen disclosure of model constraints, logging gaps, and ML confidence |
The system produces three independent severity reads per incident, never blended:
- Historical Baseline (
display_severity_bucket) — retrospective, based on actual median clearance time for the cause+corridor combination. - Report-Time Predictive Score — deterministic rule engine (Priority 57.14% + Corridor Frequency 42.86%), computable at the moment of logging.
- ML Directional Read (
ml_severity_bucket) — LightGBM classifier on 6 report-time features; labeled low-confidence and secondary.
- Coarse Bucket Resolution: 4-bucket output (Low/Medium/High/Critical) built on 2 input signals only, to strictly avoid label leakage.
- Low ML Confidence: Macro-F1 of 0.477 on held-out test split. Kept explicitly secondary to the rule engine.
- Chronic Logging Gaps: ~61% of records lack completion timestamps — only ~39% of events have a resolvable duration for ground-truth labeling.
See METHODOLOGY.md for full statistical detail.
Dataset: data/astram_event_data.csv — 8,173 real-world BTP incident records. No synthetic or simulated rows in the training or calibration pipeline.
To run the pipeline from scratch:
cd project/data-pipeline
uv run python clean.py
uv run python severity_score.py
uv run python predictive_score.py
uv run python calibration_ledger.py
uv run python train_model.py
uv run python validate.pyKey artifacts generated:
cleaned_data.parquet— standardized historical ledgerpredictive_cutoffs.json— corridor frequencies and rule-engine thresholdsmodel.pkl— trained LightGBM modelcalibration_ledger.json&calibration_summary.json— Timeline Replay data
cd project
uv sync # install all Python dependencies
uv run uvicorn backend.main:app --port 8000cd project/frontend
pnpm install
pnpm run devThe Next.js frontend proxies /api to http://127.0.0.1:8000 by default. To point at a remote backend:
# .env.local
BACKEND_URL=https://your-backend-url.comThe backend is fully containerized.
# 1. Authenticate and set your project
gcloud auth login
gcloud config set project YOUR_PROJECT_ID
# 2. Build and deploy in one step (Cloud Build handles the Docker build)
gcloud run deploy gridlock-backend \
--source . \
--region asia-south1 \
--platform managed \
--allow-unauthenticated \
--port 8080 \
--memory 1Gi \
--cpu 1
# 3. Copy the deployed URL and set it in frontend/.env.local
echo "BACKEND_URL=https://<your-service-url>.run.app" > frontend/.env.localNote
The image is ~500MB — lightgbm and pandas are the heavy dependencies. --memory 1Gi is the minimum safe value for loading the model and parquet artifacts at startup.





