# Tanzania Water Pump Failures — Predicting & Prioritizing Repairs
Tanzania has ~59,000 rural water points, and **46% of them are broken or
failing**. Repair crews are limited, so the real question is not "which pumps
are broken?" but **"which pumps should we drive to first?"**
This project answers that end-to-end: a leak-free ML pipeline that predicts pump
status, plus a decision layer that turns those predictions into an inspection
schedule a water authority could actually run.
Data: the DrivenData "Pump it Up"
competition — 59,400 labeled pumps, 40 features, 3 classes.
---
## The result that matters
A model that reports 80% accuracy sounds good and tells you nothing about
whether it is *useful*. Two questions decide that.
### 1. If crews can only inspect k pumps, how well is that budget spent?
Ranking pumps by predicted risk — `P(non functional) + P(needs repair)` — and
sending crews down that list:
| Inspections (k) | Genuinely need a crew | Share of all broken pumps found | Lift vs. random |
|---:|:---:|:---:|:---:|
| 500 | **99.4%** | 9.2% | 2.18× |
| 1,000 | **99.3%** | 18.3% | 2.17× |
| 2,500 | 97.3% | 44.8% | 2.13× |
| 5,000 | 83.2% | 76.7% | 1.82× |
**Read this as:** send crews to the top 1,000 ranked pumps and **993 of them
genuinely need work**. Inspect 1,000 pumps at random and you find ~457. The
ranking more than doubles the return on every crew-day.
### 2. Are we optimizing for the right mistake?
`argmax P(class)` silently assumes every error costs the same. It doesn't:
leaving a broken pump unvisited strands a village for months, while a wasted
inspection costs one crew-day. Pricing that asymmetry (10:1 for a missed
failure, documented in `src/decision.py`) and choosing the
**minimum-expected-cost** action instead:
| Decision rule | Accuracy | Missed broken pumps | Wasted visits | Total cost |
|---|:---:|:---:|:---:|:---:|
| `argmax P(class)` | **0.80** | 1,078 | 1,040 | 10,619 |
| min expected cost | 0.50 | **47** | 4,884 | **5, …