Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Groundwork — Construction Risk Intelligence

Upload any construction dataset and get instant, explainable predictions of project risk — schedule duration, delay likelihood, and the factors driving each outcome. Groundwork maps unfamiliar columns automatically, trains a model on the spot, and turns the results into plain-English reports through Claude.

Why this exists. Construction data lives in silos — schedules in one system, costs in another, permits in a third — and most tools require a fixed schema. Groundwork ingests any construction CSV, figures out what the columns mean, and produces usable risk intelligence without a data-science team in the loop.


What it does

  • Schema-agnostic ingestion. Drop in a CSV with unknown columns. Claude reads the headers and a sample of rows and maps each column to a role (target, numeric feature, categorical feature, date, or drop).
  • Automatic target resolution. If no numeric outcome exists, Groundwork derives one — e.g. permit duration from issuance_date − filing_date — instead of failing.
  • On-the-fly modelling. A Random Forest regressor trains on the uploaded data and reports MAE and R² on a held-out split.
  • Explainability. SHAP values decompose every prediction; Claude translates them into a readable narrative ("borough workload is the biggest driver, adding ~4 days").
  • Cold-start comparison. Each prediction is shown against a no-history baseline, so users can see how much the historical signal actually helps.
  • Risk analytics. Group-level deviation-from-average views highlight which categories run slower or faster than the norm, with weak/meaningful-driver flags.
  • Conversational analysis. A data-aware chat answers questions grounded in the uploaded dataset.

Architecture

Groundwork is a full-stack application with a clean frontend/backend separation — the Python ML logic is served through an API rather than embedded in the UI.

┌─────────────────────┐     HTTP/JSON      ┌─────────────────────┐
│   React (Vite)      │  ───────────────►  │   FastAPI backend   │
│   frontend          │  ◄───────────────  │   (Python)          │
│  · upload & forms   │                    │  · column mapping   │
│  · charts / SHAP    │                    │  · model training   │
│  · risk analytics   │                    │  · SHAP + reports   │
└─────────────────────┘                    └──────────┬──────────┘
                                                       │
                                    ┌──────────────────┴──────────────────┐
                                    │  Random Forest + SHAP   │   Claude   │
                                    │  (scikit-learn)         │   API      │
                                    └─────────────────────────┴────────────┘

Backend endpoints

Method Route Purpose
GET / Health check
POST /upload Parse CSV → Claude maps columns → train model → return stats
POST /predict Run prediction + SHAP + Claude risk report for given inputs
POST /chat Answer questions grounded in the loaded dataset

Tech stack

Frontend — React 18, Vite, plain CSS design system (light/dark themes), Lucide icons Backend — FastAPI, Uvicorn ML — scikit-learn (Random Forest), SHAP for explainability, pandas / NumPy AI — Anthropic Claude (Sonnet) for column mapping, SHAP interpretation, and reports


Running locally

Two processes: a Python backend and a React frontend.

Prerequisites

  • Python 3.12 with the packages in backend/requirements.txt
  • Node.js 18+ and npm
  • An Anthropic API key (entered in the app at runtime — never stored)

Backend

cd backend
pip install -r requirements.txt
python -m uvicorn main:app --reload --port 8000

The API runs at http://localhost:8000.

Note on dependencies. SHAP is pinned to 0.46.0 and NumPy to <2.0; newer SHAP requires NumPy 2.x, which conflicts with the pandas/pyarrow build in many environments. Installing from requirements.txt handles this.

Frontend

cd frontend
npm install
npm run dev

The app runs at http://localhost:5173.

Using it

  1. Enter your Anthropic API key via the header badge.
  2. Upload a construction CSV (NYC / Chicago permits, project logs, contractor records…).
  3. Review the mapped columns, run a prediction, and explore the risk analytics.

Engineering notes

A few decisions worth calling out, since they reflect how the app handles real, messy data rather than a clean demo set:

  • Robust type coercion. Columns an LLM labels "numeric" often contain codes like 96-15. Each is validated; columns that don't convert are rerouted to categorical or dropped, so a single dirty column can't crash training.
  • Target leakage guard. When the target is derived from two dates, features built from the end date are removed — otherwise the model would "cheat" and report a meaningless near-perfect score.
  • Identifier filtering. Grouping columns that are near-unique per row (addresses, BINs) are excluded from analytics, since averaging by an ID conveys nothing.
  • Keys never touch the codebase. The API key is supplied at runtime and passed per-request to the local backend; it is never written to disk or committed. This keeps the repository safe to make public.

Roadmap

  • User-selectable prediction target (choose the outcome, or a derived duration)
  • Sample dataset / demo mode for evaluation without an API key
  • Geospatial risk view for datasets with coordinates
  • Deployment (backend → Render/Railway, frontend → Vercel/Netlify)

Background

Groundwork began as an investigation into the cold-start problem in construction analytics: new projects have no history, so early risk prediction is hard. The app demonstrates one practical answer — borrow signal from similar historical projects, map heterogeneous data automatically, and keep every prediction explainable.

About

Schema-agnostic construction risk intelligence — React + FastAPI + Random Forest + SHAP

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages