Observed since 21 Oct, 10:32 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Unsupervised machine learning for humanitarian needs assessment and visualization
Unsupervised machine learning for humanitarian needs assessment at ANY geographic level
AidMind is a production-ready Python tool that enables humanitarian data analysts to quickly identify areas with the highest need for aid using unsupervised machine learning. Works with provinces, districts, villages, refugee camps, neighborhoods, or any custom geographic units. It automatically clusters geographic units, ranks them by need level, and generates interactive choropleth maps with discrete color-coded need levels.
Fully generalized: Works with any CSV structure and any GeoJSON boundaries.
pip install aidmind
git clone https://github.com/yourorg/aidmind.git
cd aidmind
pip install -r requirements.txt
pip install -e .
from aidmind import analyze_needs
# Analyze provinces
output = analyze_needs("provinces.csv", "Afghanistan", admin_level="ADM1")
print(f"Map saved to: {output}")
# Analyze districts
output = analyze_needs(
"districts.csv",
"Afghanistan",
admin_level="ADM2",
admin_col="district"
)
# Analyze villages using your own GeoJSON
output = analyze_needs(
"villages.csv",
local_geojson="village_boundaries.geojson",
admin_col="village_name"
)
# Works with refugee camps, neighborhoods, health zones, etc.
output = analyze_needs(
"refugee_camps.csv",
local_geojson="camp_boundaries.geojson",
admin_col="camp_name",
fixed_thresholds=(0.25, 0.50, 0.75) # Optional: fixed thresholds
)
# Province-level
python -m aidmind provinces.csv "Afghanistan" --admin-level ADM1
# District-level
python -m aidmind districts.csv "Kenya" --admin-level ADM2 --admin-col district
# Village-level with custom boundaries
python -m aidmind villages.csv --geojson villages.geojson --admin-col village_name
See USAGE_EXAMPLES.md for complete documentation with 10+ examples.
province,health_index,education_index,income_index,food_security,water_access
Kabul,0.75,0.80,0.70,0.85,0.78
Kandahar,0.45,0.40,0.50,0.35,0.44
Herat,0.60,0.65,0.55,0.60,0.63
village_name,health_access,school_access,water_quality,food_availability
Qala-e-Fatullah,0.30,0.25,0.40,0.35
Deh-e-Bagh,0.45,0.40,0.55,0.50
Karez-e-Mir,0.25,0.20,0.35,0.30
camp_name,shelter,water,sanitation,food,health
Camp Dadaab 1,0.40,0.35,0.30,0.45,0.50
Camp Kakuma,0.55,0.50,0.45,0.60,0.65
Camp Nyarugusu,0.30,0.25,0.20,0.35,0.40
If you have multiple records per unit (e.g., Kabul_1, Kabul_2), the tool automatically:
admin_coloutput/needs_map_<ISO3>.htmloutput/needs_scores_<ISO3>.csvExample needs_scores_AFG.csv:
admin1,need_score,need_rank,cluster,need_level
Kabul,0.142,3,2,lowest
Kandahar,0.856,0,0,high
Herat,0.487,2,1,medium
# Use consistent cutoffs across all countries
output = analyze_needs(
"country1.csv",
"Afghanistan",
fixed_thresholds=(0.25, 0.50, 0.75)
)
# No internet required after initial download
output = analyze_needs(
"data.csv",
"Kenya",
local_geojson="boundaries/kenya_adm1.geojson"
)
output = analyze_needs(
"district_data.csv",
"Ethiopia",
admin_level="ADM2",
admin_col="district"
)
Problem: WARNING: Low admin name match rate: 45%
Solution:
Problem: ValueError: No numeric feature columns found
Solution:
Problem: ValueError: Could not detect an admin name column
Solution:
province, admin1, region, or stateadmin_col="your_column_name"Problem: WARNING: Dataset has only 2 rows
Solution:
analyze_needs()def analyze_needs(
dataset_path: str,
country_name: Optional[str] = None,
output_html_path: Optional[str] = None,
*,
admin_level: Optional[str] = None,
admin_col: Optional[str] = None,
local_geojson: Optional[str] = None,
fixed_thresholds: Optional[Tuple[float, float, float]] = None,
) -> str
Parameters:
dataset_path (str): Path to CSV file with geographic units and indicatorscountry_name (str, optional): Country name (e.g., "Afghanistan", "Kenya"). Required only if using GeoBoundaries. Can be None if providing local_geojsonoutput_html_path (str, optional): Custom output path for HTMLadmin_level (str, optional): Admin level ("ADM1", "ADM2", "ADM3", or any custom). Only used with GeoBoundariesadmin_col (str, optional): Name of geographic unit column (auto-detected if None)local_geojson (str, optional): Path to local GeoJSON boundaries. Use this for villages or custom unitsfixed_thresholds (tuple, optional): (q25, q50, q75) for color levelsReturns:
str: Path to generated HTML fileRaises:
FileNotFoundError: If dataset or local_geojson not foundValueError: If invalid inputs, empty dataset, or both country_name and local_geojson missingExamples:
# Province-level with GeoBoundaries
analyze_needs("provinces.csv", "Afghanistan", admin_level="ADM1")
# District-level with GeoBoundaries
analyze_needs("districts.csv", "Kenya", admin_level="ADM2")
# Village-level with custom boundaries
analyze_needs("villages.csv", local_geojson="villages.geojson")
# Custom zones
analyze_needs("camps.csv", local_geojson="camps.geojson", admin_col="camp_name")
See examples/ directory for:
basic_usage.ipynb: Step-by-step tutorialmulti_country.py: Batch processing multiple countriescustom_config.py: Advanced configuration optionsWe welcome contributions! Please:
See CONTRIBUTING.md for detailed guidelines.
MIT License - see LICENSE file for details.
If you use AidMind in your research or reports, please cite:
AidMind: Unsupervised Machine Learning for Humanitarian Needs Assessment
Version 1.0.0
https://github.com/yourorg/aidmind
See CHANGELOG.md for version history and updates.
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 1.0.1 | 2 Nov 2025 | 15 |
This describes our collected data; it is not a security assessment.
Observed since 21 Oct, 10:32 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:73e7c3c1c34c191d69ac5f1bd158bbd7be87d932d7ea0bbe4cea755963127413