Skip to content

crojasu/audience-map

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Level Up UK — Geo-Targeting Intelligence Tool

Crossreferences your community database with free UK open data to identify where paid ads will have the highest impact.


What it does

  1. Pulls postcodes from your SQL database
  2. Maps each postcode to an LSOA and parliamentary constituency (via ONSPD)
  3. Enriches with:
    • ONS Census 2021: % women, % age 18–45, % degree-educated
    • 2024 General Election: progressive vote share (Labour + Green + LibDem + SNP + Plaid)
  4. Scores each area:
    • Density score — how many Level Up members already live there
    • Opportunity score — demographic/political signal, discounted for areas already well-covered
  5. Outputs:
    • scored_postcodes.csv — upload to Meta Ads or Google Ads
    • targeting_map.html — interactive map to explore visually

Setup

Requirements

pip install pandas numpy folium requests psycopg2-binary
# or for MySQL: pip install pymysql

Step 1 — Configure your database

Edit geo_targeting.py, find the DB_CONFIG block at the top:

DB_CONFIG = {
    "engine": "postgres",        # or "mysql" or "sqlite"
    "host": "your-db-host",
    "port": 5432,
    "database": "your-db-name",
    "user": "your-username",
    "password": "your-password",
}

POSTCODE_QUERY = """
    SELECT postcode FROM community_members
    WHERE postcode IS NOT NULL
"""

Also update POSTCODE_QUERY to match your actual table and column names.

Step 2 — Download the data

python download_data.py

This will auto-download Census 2021 and electoral data.

For ONSPD (the postcode directory), you need to download it manually because ONS changes the URL quarterly:

  1. Go to: https://geoportal.statistics.gov.uk/
  2. Search: ONS Postcode Directory
  3. Click the most recent version → CSV download (~800MB zip)
  4. Unzip and rename the main CSV file to data/ONSPD_raw.csv
  5. Re-run python download_data.py to slim it down

Step 3 — Run

python geo_targeting.py

Outputs:

  • scored_postcodes.csv
  • targeting_map.html

Data Sources

Dataset Source License
ONS Postcode Directory (ONSPD) geoportal.statistics.gov.uk Open Government Licence
Census 2021 (TS008, TS007, TS067) NOMIS / ONS Open Government Licence
2024 GE Results House of Commons Library Open Parliament Licence

All three are free, openly licensed, and do not require registration.


Scoring Formula

Density Score (0–100)

Members per 1,000 residents in that LSOA, normalised.

Opportunity Score (0–100)

Weighted demographic index:

  • % women aged 18–45 → 40% weight
  • % with degree-level education → 15% weight
  • % female population → 15% weight
  • Progressive vote share (Lab+Grn+LD+SNP+PC) → 30% weight

Then discounted (up to 50%) for areas already well-covered by existing members.

High tier = strong demographics, not yet well-reached → prioritise for ads Low tier = already well-covered OR weak signal → deprioritise


Using the CSV with Meta Ads / Google Ads

Meta Ads (Facebook/Instagram)

  1. In Ads Manager → Audiences → Create Audience → Custom Audience
  2. Or use Location Targeting: paste the postcodes from the "High" tier rows
  3. You can also upload the full CSV as a customer list to find lookalike audiences

Google Ads

  1. Campaigns → Locations → Bulk add locations
  2. Paste postcode list from the "High" tier

Extending the tool

Ideas for future iterations:

  • Add Indices of Multiple Deprivation to weight by class/income
  • Pull Twitter/X follower geodata (if available) to validate the model
  • Add ONS Subnational Population Projections for growth areas
  • Build a Flask/FastAPI endpoint to refresh scores automatically on a schedule

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages