Public Sector · Advanced

Water Pump Functionality Prediction

Classify 59,400 Tanzanian waterpoints as functional, needing repair or broken, and serve the model from a Flask form.

The scenario

Access to clean, working water is a critical challenge across much of Tanzania. Thousands of waterpoints, from wells and boreholes to communal standpipes, have been installed across the country, but many are non-functional or need repair, leaving communities without reliable water. You are a data scientist supporting the Ministry of Water and its NGO partners. They want a model that predicts the operational condition of a waterpoint from its location, management, water source and technical setup, so maintenance crews and budgets can be pointed where they will do the most good. The features and labels arrive in two files that must be joined on id before anything else.

Your role

Data Scientist, Ministry of Water and NGO maintenance partners, Tanzania

The business problem

Maintenance teams have no way to prioritise tens of thousands of waterpoints. Records exist for each point, but nobody can predict which ones are likely broken or about to fail, so repairs are reactive and resources are spread thin. A reliable three-class prediction (functional, functional needs repair, non functional) would let the ministry rank sites for inspection.

Objectives

  • 1Load both files and merge them on the shared id column before any exploration.
  • 2Investigate missing values, placeholder zeros and invalid GPS coordinates, and handle each deliberately.
  • 3Reduce redundant column groups and high-cardinality categoricals with justification.
  • 4Engineer features such as pump age from construction year and the recorded date.
  • 5Explore numeric and categorical features against the target, using Cramér's V for categorical associations.
  • 6Build ColumnTransformer preprocessing inside scikit-learn Pipelines and train at least four model families with cross-validation.
  • 7Evaluate with accuracy, weighted F1 and per-class confusion matrices on a held-out test set, then save the best pipeline.
  • 8Deploy the saved model in a single-page Flask app with a form and a prediction result.

Tasks and business questions

  1. 1

    Step 1 · Load and explore

    Set up a virtual environment and the folder structure. Load both CSV files and merge them on id. Inspect shape, columns and types, preview rows, check the target distribution, find missing values, spot suspicious zeros in coordinates, year and population, and measure the cardinality of every categorical column.

    • How many rows and columns do you have after the merge, and did every id match?
    • What is the class balance of status_group, and what does it mean for accuracy as a metric?
    • Which columns have missing values, which have suspicious zeros, and which have more than 100 unique values?
  2. 2

    Step 2 · Clean and engineer features

    Decide per column whether to drop, fill or flag missing values. Treat zeros in construction year, population and GPS as placeholders where appropriate, and handle the 0,0 coordinates. Investigate the column groups that describe the same thing at three levels of detail and keep one with justification. Reduce high-cardinality columns such as funder, installer and subvillage. Parse date_recorded into year and month, derive pump age, encode the target and save data/processed/train_clean.csv.

    • Which zeros did you treat as missing, and how did you fill or flag them?
    • Within each duplicated column group, which column did you keep and why?
    • How did you reduce the cardinality of funder, installer and subvillage?
    • How did you compute pump age, and how did you handle unknown construction years?
  3. 3

    Step 3 · EDA and correlation analysis

    Univariate distributions of key numeric and categorical features; bivariate views of each feature against the target with stacked bars and grouped box or violin plots; a numeric correlation heatmap for multicollinearity; Cramér's V for every categorical feature against status_group, ranked; and optionally a latitude-longitude scatter coloured by class.

    • Which categorical features have the highest Cramér's V with the target?
    • Which numeric features are collinear, and which will you drop?
    • Do quantity, water quality or extraction type separate the classes clearly?
    • Is there a spatial pattern in functionality?
  4. 4

    Step 4 · Pipelines and modelling

    Separate X and y, split into training and test sets (there is no external test file), define numeric and categorical feature groups from the EDA, build a ColumnTransformer for imputation, scaling and encoding, wrap it with each classifier in a Pipeline, and train logistic regression, decision tree, random forest and a gradient-boosting model with cross-validation. Optionally tune the best one.

    • How is your ColumnTransformer configured for numeric and categorical columns?
    • What were the cross-validated scores for each of the four models?
    • Which hyperparameters did you tune, and did it help?
  5. 5

    Step 5 · Evaluate and save

    Evaluate every model on the held-out test set with accuracy, weighted F1 and the full classification report, plot a confusion matrix for each, select the best model with a written justification, and save the pipeline and target encoder with joblib.

    • Which class is hardest to predict, and where do the errors concentrate?
    • Which model did you choose, and why?
  6. 6

    Deploy with Flask

    Build app/app.py to load the saved model, render a form at GET / and return a prediction at POST /predict. Use one index.html with Jinja2 logic so the result shows after a prediction. Keep the form to the most impactful features from the EDA rather than all 40 columns. Run it locally, then finish the README and push to GitHub.

    • Which features did you expose in the form, and why those?
    • How does the app map form inputs into the shape the pipeline expects?
    • What would you tell a maintenance planner about the model's limits?

Dataset and data dictionary

Two files sharing an id column. The features file has 59,400 waterpoints and 40 columns: static head, date recorded, funder, installer, GPS height, longitude and latitude, waterpoint name, basin, subvillage, region, district, local government area and ward, population, public meeting flag, recording group, scheme management and name, permit flag, construction year, and grouped columns for extraction type, management, payment, water quality, quantity, source and waterpoint type. The labels file holds the status_group target with three classes. Several numeric columns use 0 as a placeholder for missing data, some coordinates sit at 0,0 in the ocean, funder, installer and subvillage have thousands of unique values, and the three classes are imbalanced.

Waterpoint featureswater_pump_features

59,400 waterpoints with 40 location, management, technical and water-source columns. Join to the labels on id. · 59,400 rows

Sign in to download
Data dictionary for Waterpoint features
ColumnTypeDescriptionExample
idintegerWaterpoint identifier shared with the labels file.69572
amount_tshdecimalTotal static head: amount of water available to the waterpoint. Often 0.6000.0
date_recordeddateDate the row was entered into the system.2011-03-14
fundertextWho funded the well. Very high cardinality.Roman
gps_heightintegerAltitude of the well. 0 may be a placeholder.1390
installertextOrganisation that installed the well. Very high cardinality.Roman
longitudedecimalGPS longitude. 0 marks an invalid location.34.938
latitudedecimalGPS latitude. Near 0 marks an invalid location.-9.856
wpt_nametextName of the waterpoint if available.none
num_privateintegerUsage unspecified; explore during EDA.0
basintextGeographic water basin.Lake Nyasa
subvillagetextSub-village location. Very high cardinality.Mnyusi B
regiontextRegion name.Iringa
region_codeintegerRegion as a numeric code.11
district_codeintegerDistrict as a numeric code.5
lgatextLocal Government Area.Ludewa
wardtextAdministrative ward.Mundindi
populationintegerPopulation around the well. 0 may be a placeholder.109
public_meetingbooleanWhether a public meeting was held. Has missing values.True
recorded_bytextGroup that entered the row. Check whether it varies at all.GeoData Consultants Ltd
scheme_managementtextWho operates the waterpoint.VWC
scheme_nametextName of the operating scheme. Many missing values.Roman
permitbooleanWhether the waterpoint is permitted. Has missing values.False
construction_yearintegerYear built. 0 means unknown.1999
extraction_typetextExtraction mechanism, most detailed level of a three-column group.gravity
extraction_type_grouptextGrouped extraction type.gravity
extraction_type_classtextExtraction type class, coarsest level.gravity
managementtextHow the waterpoint is managed.vwc
management_grouptextGrouped management type.user-group
paymenttextWhat the water costs.pay annually
payment_typetextType of payment; overlaps with payment.annually
water_qualitytextQuality of the water.soft
quality_grouptextGrouped water quality.good
quantitytextQuantity of water available.enough
quantity_grouptextGrouped quantity; nearly identical to quantity.enough
sourcetextSource of the water.spring
source_typetextType of water source.spring
source_classtextClass of water source.groundwater
waterpoint_typetextKind of waterpoint.communal standpipe
waterpoint_type_grouptextGrouped waterpoint type.communal standpipe

Waterpoint labelswater_pump_labels

The status_group target for each waterpoint id: functional, functional needs repair, or non functional. · 59,400 rows

Sign in to download
Data dictionary for Waterpoint labels
ColumnTypeDescriptionExample
idintegerWaterpoint identifier shared with the features file.69572
status_grouptextTarget class: functional, functional needs repair, or non functional.functional

Required deliverables

  • Notebook (water_pump_analysis.ipynb) with clearly labelled markdown sections for each of the five steps: loading and exploration, cleaning and feature engineering, EDA and correlation, pipelines and modelling, evaluation and saving
  • Cleaned dataset saved to data/processed/train_clean.csv
  • Saved best pipeline at models/best_model.pkl with any target encoder alongside it
  • Flask app (app/app.py and app/templates/index.html) serving a single-page form and prediction result at http://127.0.0.1:5000/
  • reports/figures with the saved EDA plots, requirements.txt, .gitignore and README.md, all pushed to GitHub

How it is marked

  • Data loading and cleaning15%
  • Exploratory and correlation analysis15%
  • Feature engineering15%
  • Pipelines and modelling20%
  • Evaluation and model selection15%
  • Deployment10%
  • Documentation and reproducibility10%
  • Pass mark60%

Marked with the machine-learning rubric. Expect the two files merged on id first; zeros in construction year, population and coordinates investigated rather than trusted; the duplicated column groups (extraction, management, payment, quality, quantity, source, waterpoint type) reduced with justification; Cramér's V used to rank categorical features; four model families trained through Pipelines with cross-validation; weighted F1 and confusion matrices reported on a held-out set; and a running Flask form that returns one of the three classes.