Hierarchical polling unit intelligence for Nigeria (ML-ready)
Project description
Nigerian Polling Units
ngpu is a Python and R programming library that provides hierarchical intelligence over Nigeria’s polling unit administrative structure, designed specifically for machine learning, analytics, and research workflows.
Features
- Programmatic access to States, LGAs, Wards, and Polling Units
- ML-ready DataFrame export
- Hierarchical categorical encoders
- Coverage and bias diagnostics
- Fuzzy search for noisy text inputs
Installation
For Python Users: Run in notebook or IDE
pip install ngpu
For R Users: Run in terminal or Anaconda Prompt
conda create -n ngpu-r -c conda-forge python=3.10 ngpu r-base r-reticulate pandas scikit-learn
This installs:
Python
ngpu
R
reticulate
ML dependencies
Quick Start
from ngpu import Index, to_dataframe
states = Index.states()
lgas = Index.lgas("Anambra")
df = to_dataframe()
Connecting R to ngpu
Open R or RStudio.
library(reticulate)
use_condaenv("ngpu-r", required = TRUE)
ngpu <- import("ngpu")
Machine Learning Usgae
from ngpu.ml.encoder import PollingUnitEncoder
encoder = PollingUnitEncoder(level="ward")
X = encoder.fit_transform(df)
Coverage Diagnostics
from ngpu.ml.diagnostics import CoverageReport
report = CoverageReport(df)
report.coverage_by_state()
Use Cases
Regional ML feature engineering
Bias and coverage analysis
Socio-economic modeling
Civic tech and policy research
Any domain requiring stable Nigerian administrative anchors
In Python
List all states:
from ngpu import Index
states = Index.states()
print(states)
⬆ Validate categorical values in incoming datasets.
Get LGAs for a state:
lgas = Index.lgas("Enugu")
print(lgas)
⬆ Fill missing LGA values during data cleaning.
Get wards and polling units
wards = Index.wards("Enugu", "Awgu")
pus = Index.polling_units("Enugu", "Awgu", "Ward 1")
⬆ Hierarchical drill-down analysis.
Converting to a DataFrame:
df = ngpu.to_dataframe()
df.head()
Join with survey data
Join with transaction data
Feature engineering pipelines
Problem
Dataset contains:
state Missing lga, ward, polling_unit
Solution
import pandas as pd
data = pd.DataFrame({
"state": ["Lagos", "Kano"]
})
ngpu_df = ngpu.to_dataframe()
enriched = data.merge(ngpu_df, on="state", how="left")
Result:
All valid LGAs, wards, and polling units are added
No manual mapping required
Machine Learning
Hierarchical Encoding
from ngpu.ml import PollingUnitEncoder
encoder = PollingUnitEncoder()
encoded = encoder.fit_transform(
state="Lagos",
lga="Ikeja",
ward="Ward 1",
polling_unit="PU 001"
)
print(encoded)
Use Case
Converts hierarchy into numeric features
Compatible with scikit-learn models
ML Pipeline
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
X = ngpu_df[["state", "lga", "ward"]]
y = ngpu_df["polling_unit"]
encoder = PollingUnitEncoder()
X_encoded = encoder.fit_transform_df(X)
X_train, X_test, y_train, y_test = train_test_split(
X_encoded, y, test_size=0.2
)
model = RandomForestClassifier()
model.fit(X_train, y_train)
Data Validation & Diagnostics
from ngpu.ml import HierarchyDiagnostics
diag = HierarchyDiagnostics()
diag.validate(
state="Lagos",
lga="Gwale"
)
Returns:
True → valid
False → invalid
Use Case:
Detect bad records before training
Prevent invalid inference
In R
states <- ngpu$Index$states()
print(states)
⬆ Validate state names in a dataset before analysis.
lgas <- ngpu$Index$lgas("Lagos")
print(lgas)
⬆ Fill missing LGAs when only state information exists.
df <- ngpu$to_dataframe()
df_r <- py_to_r(df)
head(df_r)
⬆ Join ngpu data with survey, transaction, or demographic datasets.
Problem:
You have a dataset with: state missing lga, ward, polling_unit
Solution:
library(dplyr)
data <- data.frame(
state = c("Lagos", "Kano")
)
ngpu_df <- py_to_r(ngpu$to_dataframe())
enriched <- data %>%
left_join(ngpu_df, by = "state")
head(enriched)
Dataset is automatically expanded with valid LGAs, wards, and polling units.
Machine Learning Usage
encoder <- ngpu$PollingUnitEncoder()
encoded <- encoder$fit_transform(
state = "Taraba",
lga = "Jalingo",
ward = "Ward 7",
polling_unit = "PU 007"
)
print(encoded)
Convert categorical hierarchy into numeric ML-ready features
Used in regression, classification, and clustering.
Use with caret/tidymodels
library(caret)
ml_df <- ngpu_df %>%
select(state, lga, ward) %>%
mutate(across(everything(), as.factor))
model <- train(
ward ~ .,
data = ml_df,
method = "rf"
)
Predict missing administrative attributes Learn regional patterns
Data Validation & Diagnotstics
diag <- ngpu$HierarchyDiagnostics()
diag$validate(
state = "Lagos",
lga = "Gwale"
)
Returns:
TRUE → valid
FALSE → impossible combination
Use case:
Catch data errors before modeling Prevent garbage-in-garbage-out ML
Common Errors & Fixes
Error: ModuleNotFoundError
use_condaenv("ngpu-r", required = TRUE)
Error: Wrong Python
py_config()
Ensure it points to ngpu-r.
Authors:
MaryBlessing Umeh, Software Engineer
Chidiebere V. Christopher, Data Scientist
LICENSE
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ngpu-0.1.0.tar.gz.
File metadata
- Download URL: ngpu-0.1.0.tar.gz
- Upload date:
- Size: 907.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c778a1473d3f880ca5e5884b9e771f2d2f70c261c6b60485d13a3fea6144193b
|
|
| MD5 |
af996607dc64d20692f2296a3d7325c8
|
|
| BLAKE2b-256 |
fb1e823fb10cd7bd379813e278b210e57af93555f4091de0e152105ddfd0078a
|
File details
Details for the file ngpu-0.1.0-py3-none-any.whl.
File metadata
- Download URL: ngpu-0.1.0-py3-none-any.whl
- Upload date:
- Size: 911.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8498959711afd3cf091bc20dc2b89cf47100c5103b3addfe940467db22d95ba5
|
|
| MD5 |
f9b8be3df2f5610573053f171b05e5d5
|
|
| BLAKE2b-256 |
2a4415f7755f925308efb3dbd72c0e7bc53a93127cf3af03a7dd7aae2f0ec0e6
|