Who Are You? Bayesian Prediction of Racial Category Using Surname and Geolocation
Project description
wru (Python)
Python implementation of wru (Who aRe yoU), the R package for Bayesian prediction of racial category using surname, first name, middle name, and geolocation.
Based on the methodology from Imai & Khanna (2016) and Imai, Khanna & McConnaughy (2022). Produces identical results to R wru v3.0.3 — validated on the exact 10-voter dataset from the R package README across surname-only, tract, and place geography levels (max |Δ| < 1e-6).
Installation
pip install .
For first/middle name support (BIFSG), also install pyreadr:
pip install ".[names]"
For faster fBISG Gibbs sampling with numba:
pip install ".[fast]"
Quick start
import pandas as pd
import wru
voters = pd.DataFrame({
"surname": ["Khanna", "Imai", "Rivera", "Johnson"],
"state": ["NJ", "NJ", "NY", "NY"],
"county": ["021", "021", "061", "061"],
"tract": ["004000", "004501", "004800", "014900"],
})
# Surname only
result = wru.predict_race(voters, surname_only=True)
# BISG with tract-level geography
result = wru.predict_race(voters, census_geo="tract")
Output columns pred_whi, pred_bla, pred_his, pred_asi, pred_oth contain posterior P(race | data) probabilities that sum to 1.
Features
Geography levels
Pass census_geo to condition on location. Supported levels: "county", "tract", "block_group", "block", "place", "zcta".
result = wru.predict_race(voters, census_geo="tract")
result = wru.predict_race(voters, census_geo="place")
The voter file must contain a state column (2-letter abbreviation) plus the relevant geography columns (county, tract, place, zcta, etc.).
BIFSG (first and middle names)
When first or middle name columns are available, BIFSG multiplies in additional name likelihoods:
voters["first"] = ["Kabir", "Kosuke", "Carlos", "Frank"]
result = wru.predict_race(voters, census_geo="tract", first_name_col="first")
Age and sex conditioning
Condition on age and/or sex using 2020 DHC P12 tables:
voters["age"] = [29, 40, 33, 25]
voters["sex"] = [0, 0, 0, 0] # 0=male, 1=female
result = wru.predict_race(voters, census_geo="county", age_col="age", sex_col="sex")
Party conditioning
Multiply in P(party | race) priors:
voters["PID"] = [0, 1, 2, 1] # 0=other, 1=Dem, 2=Rep
result = wru.predict_race(voters, census_geo="tract", party_col="PID")
Note: R wru v3.0.3 accepts but silently ignores the party parameter. This Python version actually applies party conditioning.
fBISG (measurement-error model)
The Gibbs sampler accounts for measurement error in Census counts:
result = wru.predict_race(voters, census_geo="tract", method="fbisg", n_samples=1000, burnin=200)
Census API key
For geographic conditioning, wru fetches data from the Census API. Requests work without a key (limited to 500/day). For heavier use, get a free key at https://api.census.gov/data/key_signup.html and set:
export CENSUS_API_KEY=your_key_here
Or pass it directly:
result = wru.predict_race(voters, census_geo="tract", census_key="your_key")
Census data is cached locally in ~/.cache/wru/ after the first download.
API reference
predict_race(voter_file, ...)
Main entry point. Key parameters:
| Parameter | Default | Description |
|---|---|---|
surname_col |
"surname" |
Column with last names |
first_name_col |
None |
Column with first names (enables BIFSG) |
middle_name_col |
None |
Column with middle names |
census_geo |
None |
Geography level for conditioning |
surname_only |
False |
Skip geographic conditioning |
age_col |
None |
Column with ages (integer) |
sex_col |
None |
Column with sex (0=male, 1=female) |
party_col |
None |
Column with party codes (0, 1, 2) |
method |
"bisg" |
"bisg" or "fbisg" |
census_year |
2020 |
Census data year (2010 or 2020) |
use_wru_names |
True |
Use wru's augmented name dictionaries |
cache |
True |
Cache downloaded Census data locally |
Helper functions
get_census_data(states, geo, year, ...)— pre-download Census data for multiple statesget_surnames(year)— load the Census surname listget_name_dict(name_type)— load wru name dictionaries ("last","first","middle")merge_names(voter_file, ...)— merge name-based race likelihoods onto a voter file
References
- Imai, K. and Khanna, K. (2016). "Improving Ecological Inference by Predicting Individual Ethnicity from Voter Registration Records." Political Analysis, 24(2), 263-272.
- Imai, K., Khanna, K. and McConnaughy, C.M. (2022). "Addressing Census Data Problems in Race Imputation via Fully Bayesian Improved Surname Geocoding and Name Supplements." Science Advances, 8(49). https://doi.org/10.1126/sciadv.adc9824
- R package: https://github.com/kosukeimai/wru
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 wru-0.2.1.tar.gz.
File metadata
- Download URL: wru-0.2.1.tar.gz
- Upload date:
- Size: 20.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.18
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6be7f0f7908a7c827d9de325dcf5bdb3eee107e85cf74b5b12d8d21684cddcc7
|
|
| MD5 |
bfc92adc9eb511868a77981ad86ca978
|
|
| BLAKE2b-256 |
f835b8e32115be1bc2265d00cf0252ac8c760308e7e6fb9673e35d9ad2135ebb
|
File details
Details for the file wru-0.2.1-py3-none-any.whl.
File metadata
- Download URL: wru-0.2.1-py3-none-any.whl
- Upload date:
- Size: 20.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.18
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3b4f612b8e9b3d30107412ec45e95dfb7cedd350ebc0cb8c4905ddc0bc9a222c
|
|
| MD5 |
994ee6e07ac1326c5da117ab137295f6
|
|
| BLAKE2b-256 |
baf2461bbb272788f544ea30e090ec10fa05ab597c8892f76ac9f2ef0fc0d127
|