01 — ContextThe Problem Worth Solving
India's disaster response machinery is reactive by design. Cyclones strike the Odisha coast on a near-cyclical basis — and yet every time, command centers operate on delayed data, cross-agency coordination stalls, and resource deployment is decided manually under pressure. The predictive models exist. The logistics tools exist. An integrated platform that brings them into a single operator view does not.
CRISP — Command & Response Intelligence System for Prediction — was my attempt to prototype what that platform could look like. The target user: a district-level emergency coordinator managing an active event, not a data scientist analyzing it after the fact.
XGBoost and LSTM risk prediction, OR-Tools vehicle routing for resource deployment, TimescaleDB for time-series event data, a live cyclone tracker, and a timeline scrubber for event replay — all unified in a single command dashboard.
02 — ArchitectureHow the ML Pipeline Worked
The prediction layer used a two-stage ensemble. An XGBoost classifier operated on structured tabular features — rainfall accumulation, wind speed deltas, population density, historical flood records — generating hourly district-level risk scores. An LSTM sequence model processed 10-day rolling windows of meteorological readings to project risk trajectories 48–72 hours out.
Risk Scoring Ensemble
# Two-stage risk ensemble: XGBoost (short-term) + LSTM (trajectory)
def compute_risk_score(district_id, timestamp):
features = fetch_realtime_features(district_id, timestamp)
xgb_score = xgb_model.predict_proba(features)[0][1]
seq = build_sequence_window(district_id, timestamp, window=10)
lstm_traj = lstm_model.predict(seq.reshape(1, 10, -1))
# Recency-bias toward LSTM for 48hr+ prediction horizon
return 0.55 * xgb_score + 0.45 * lstm_traj[0][0]
On the logistics side, OR-Tools solved a constrained vehicle routing problem — given shelter capacity, post-event road accessibility scores, and available relief vehicles, it generated optimized dispatch plans per active event. TimescaleDB handled time-series ingestion, powering the timeline scrubber that let operators replay any 6-hour window.
03 — FailureWhere the Product Thinking Broke Down
The architecture held. The product thinking didn't. My first version had seven live-updating panels, a flashing risk heatmap, real-time cyclone track animation, and an AI suggestion panel re-rendering every 30 seconds. It was technically complete and operationally unusable.
I designed the dashboard for tech reviewers, not emergency coordinators. Everything screamed urgency simultaneously — which meant nothing actually did.
Disaster command centers are cognitively overloaded environments by nature. Operators managing an active event cannot process seven competing visual signals. The correct principle — which I arrived at too late — is that every element must help the operator make a faster or more accurate decision. Anything else is noise.
No information hierarchy. Color was decorative, not functional. The AI panel was persistent instead of opt-in. Alert severity had no clear visual grammar. All of this should have been established before a single line of UI code was written.
The second iteration applied a strict three-tier alert hierarchy — critical, watch, informational — with functional color assignment. The AI panel became opt-in. The timeline scrubber moved to a secondary post-event mode. The cognitive load dropped significantly. That version should have been version one.
04 — The TrapVisual Polish as Avoidance
About 30% of total project time went to iterating on visual design — theme colors, animation timing, grid density, icon weight. CRISP cycled through a dark navy theme, a pure black theme, and a deep space-blue before locking. Each iteration felt like productive work. Most of it wasn't.
The visual language was correct after the second iteration. Hours three through six added nothing and took time from user flow testing and the OR-Tools fallback logic that never got built. Time-boxing design work with a hard deadline is a discipline I had to learn the hard way here.
05 — The SignalWhat the Prototype Actually Proved
Despite the missteps, CRISP proved something that mattered: the integration gap is real. No existing tool in India's disaster response stack combines predictive ML, real-time geospatial data, and logistics optimization in a unified operator view. During active events, coordinators context-switch across five or six systems. That switching has a measurable cost in response time.
The prototype also surfaced a non-obvious finding: training data quality is the actual bottleneck, not modeling sophistication. Historical disaster records in India are fragmented across state agencies, inconsistently formatted, and systematically missing for the high-impact events you most need. A clean model on clean data outperforms a complex model on noisy data, every time.
The two-stage ML ensemble, the TimescaleDB time-series layer, and the timeline scrubber UX were technically sound and genuinely useful ideas. The architecture in plan.md would serve as a real engineering blueprint — not just a portfolio artifact.
06 — RetrospectiveFive Things I'd Do Differently
Two hours sketching user flows by hand would have caught the cognitive overload problem before I'd touched a component. I arrived at this lesson too late.
The XGBoost model was clean. The data feeding it came from three inconsistent sources with manual transforms. Automate ingestion first — everything downstream depends on it.
Set a deadline and freeze the theme. The design was correct after iteration two. Everything after that was displacement activity masquerading as refinement.
VRP optimization can time out under certain constraint combinations. A greedy heuristic fallback is not optional in a system where the alternative is no dispatch plan during an active event.
One conversation with an actual NDRF or SDRF officer would have reoriented the entire product direction. Domain expertise is not a finishing step — it's the starting point.
CRISP is the project where I stopped treating ML as a feature to bolt on and started treating it as a system-level concern — one where every decision, from UI to data model to alert logic, has to account for model latency, prediction confidence, and graceful degradation. That shift is the most durable thing this project gave me.