AI in Public Health
Public health operates at the population level — monitoring disease trends, identifying risk factors, designing interventions, and allocating resources across entire communities and nations. It deals fundamentally with aggregated, uncertain, and often incomplete data. AI is transforming this domain by enabling earlier detection of health threats, more accurate disease burden estimates, and more equitable allocation of public health resources.
Public health AI differs from clinical AI (which focuses on individual patient care) in working with aggregate surveillance data, ecological analyses, social determinants, and policy-level interventions — often with far fewer individual-level labels and far more confounding factors.
Epidemic Surveillance and Outbreak Detection
Traditional outbreak detection relies on passive reporting through health departments — a system with significant delays (days to weeks from symptom onset to reported case). AI-driven syndromic surveillance monitors proxy signals that appear earlier than confirmed diagnoses.
import pandas as pd
import numpy as np
from scipy import stats
def detect_anomaly_cusum(
time_series: pd.Series,
baseline_weeks: int = 52,
threshold: float = 3.0,
k: float = 0.5
) -> pd.DataFrame:
"""
CUSUM (Cumulative Sum) anomaly detection for disease surveillance.
Monitors a health indicator (e.g., emergency department visits for
influenza-like illness) for significant deviations above baseline.
k: allowance parameter (typically 0.5 * expected shift to detect)
threshold: alert threshold (standard deviations above baseline)
Used in CDC's Early Aberration Reporting System (EARS).
"""
results = []
for i in range(baseline_weeks, len(time_series)):
# Rolling baseline: mean and std over preceding baseline_weeks
baseline = time_series.iloc[i - baseline_weeks:i]
mu = baseline.mean()
sigma = baseline.std()
if sigma == 0:
results.append({"date": time_series.index[i], "cusum": 0,
"alert": False, "z_score": 0})
continue
# Standardized value
z = (time_series.iloc[i] - mu) / sigma
# One-sided upper CUSUM: accumulate excess above k
prev_cusum = results[-1]["cusum"] if results else 0
cusum = max(0, prev_cusum + z - k)
results.append({
"date": time_series.index[i],
"observed": time_series.iloc[i],
"expected": mu,
"z_score": z,
"cusum": cusum,
"alert": cusum > threshold
})
return pd.DataFrame(results)
def detect_aberration_ensemble(
ili_visits: pd.Series, # influenza-like illness ED visits
pharmacy_sales: pd.Series, # OTC cold/flu medication sales
search_trends: pd.Series # web search volume for flu symptoms
) -> pd.DataFrame:
"""
Multi-source syndromic surveillance combining:
- Emergency department ILI visits
- Over-the-counter pharmacy sales (fever reducers, antivirals)
- Internet search trends (Google Flu Trends successor approaches)
Ensemble alert: flag when ≥2 sources show simultaneous anomaly.
"""
sources = {
"ILI visits": ili_visits,
"Pharmacy sales": pharmacy_sales,
"Search trends": search_trends
}
alerts = {}
for name, series in sources.items():
cusum_df = detect_anomaly_cusum(series)
alerts[name] = cusum_df.set_index("date")["alert"]
alert_df = pd.DataFrame(alerts)
alert_df["sources_alerting"] = alert_df.sum(axis=1)
alert_df["ensemble_alert"] = alert_df["sources_alerting"] >= 2
return alert_df
HealthMap, ProMED, and WHO’s EIOS (Epidemic Intelligence from Open Sources) system use NLP to continuously scan news articles, social media, and official reports in multiple languages to detect early signals of novel outbreaks — providing days to weeks of advance warning over traditional surveillance systems.
Epidemic Forecasting
During the COVID-19 pandemic, dozens of ML models competed on forecasting hospitalization, case counts, and deaths. The CDC’s COVID-19 Forecast Hub aggregated these into ensemble forecasts:
import numpy as np
import pandas as pd
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.preprocessing import StandardScaler
def build_epidemic_forecaster(
epi_df: pd.DataFrame,
forecast_horizon: int = 4 # weeks
) -> dict:
"""
Forecasting weekly hospitalizations 1–4 weeks ahead.
Feature engineering captures:
- Recent trajectory (lagged values, trends)
- Seasonal patterns (week of year, year in pandemic)
- Vaccination coverage and pace
- Variant-specific reproduction number estimates
- Healthcare system strain indicators (ICU occupancy)
- Population immunity proxies (seroprevalence surveys)
"""
forecast_models = {}
for horizon in range(1, forecast_horizon + 1):
feature_cols = [
f"hosp_lag_{lag}" for lag in [1, 2, 3, 4, 7, 14]
] + [
"hosp_trend_7d", # 7-day slope
"hosp_trend_14d",
"rt_estimate", # effective reproduction number
"vax_coverage_2dose", # fully vaccinated %
"vax_pace_7d", # weekly vaccination rate
"icu_occupancy_pct",
"week_of_year_sin", # seasonal encoding
"week_of_year_cos",
"cases_lag_7d", # case counts lead hospitalizations
"test_positivity_rate"
]
# Target: hospitalizations `horizon` weeks ahead
target = f"hosp_ahead_{horizon}w"
# Build training examples with sliding window
df = epi_df.copy()
df[target] = df["hospitalizations"].shift(-horizon * 7)
df = df.dropna(subset=[target] + feature_cols)
X = df[feature_cols]
y = df[target]
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
model = GradientBoostingRegressor(
n_estimators=300,
learning_rate=0.05,
max_depth=4,
subsample=0.8,
random_state=42
)
model.fit(X_scaled, y)
forecast_models[horizon] = {"model": model, "scaler": scaler,
"features": feature_cols}
return forecast_models
Genomic Epidemiology
Pathogen whole-genome sequencing combined with ML enables real-time phylogenetic analysis — tracking transmission chains, identifying variants of concern, and attributing outbreak sources:
from sklearn.cluster import DBSCAN
import numpy as np
def cluster_genomic_sequences(
distance_matrix: np.ndarray,
sample_ids: list[str],
collection_dates: list[str],
eps_snps: float = 5.0 # sequences within 5 SNPs = same cluster
) -> dict:
"""
Cluster pathogen sequences by genetic distance to identify
transmission clusters. DBSCAN handles variable cluster sizes
and identifies outliers (unlinked cases, importations).
distance_matrix: pairwise SNP distances between genome sequences
eps_snps: maximum SNP distance to consider sequences linked
Used in COVID-19, TB, norovirus, and influenza outbreak investigations.
"""
clustering = DBSCAN(
eps=eps_snps,
min_samples=2,
metric="precomputed"
)
labels = clustering.fit_predict(distance_matrix)
cluster_assignments = {}
for sample_id, label in zip(sample_ids, labels):
if label == -1:
cluster_assignments[sample_id] = "unlinked"
else:
cluster_assignments[sample_id] = f"cluster_{label:03d}"
cluster_sizes = {}
for cluster in set(labels):
if cluster != -1:
size = (labels == cluster).sum()
cluster_sizes[f"cluster_{cluster:03d}"] = size
return {
"assignments": cluster_assignments,
"cluster_sizes": cluster_sizes,
"n_clusters": len(set(labels) - {-1}),
"n_unlinked": (labels == -1).sum()
}
During COVID-19, genomic sequencing platforms like Nextstrain and COG-UK used phylogenetic ML to track the emergence and spread of Alpha, Delta, and Omicron variants in near-real-time — directly informing travel policies and booster recommendations.
Disease Burden Estimation and Health Equity
Official statistics systematically undercount disease burden — not all cases are diagnosed, not all deaths are attributed correctly, and data quality varies dramatically across geographies. ML enables better estimation from sparse and heterogeneous data sources:
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestRegressor
def estimate_excess_mortality(
observed_deaths: pd.Series,
baseline_deaths_predicted: pd.Series
) -> pd.DataFrame:
"""
Excess mortality = observed deaths - expected deaths under counterfactual
(absence of the event of interest, e.g., pandemic or heat wave).
Expected deaths modeled as:
- Time series models fit to pre-event data
- Accounts for seasonality, long-term trends, aging
- Can incorporate temperature, flu burden as covariates
Used by The Economist, WHO, and academic groups to estimate
true COVID-19 death toll (2020–2023: ~15–20 million globally
vs. official confirmed count of ~7 million).
"""
excess = observed_deaths - baseline_deaths_predicted
return pd.DataFrame({
"date": observed_deaths.index,
"observed": observed_deaths.values,
"expected": baseline_deaths_predicted.values,
"excess": excess.values,
"excess_pct": (excess / baseline_deaths_predicted * 100).values
})
def analyze_health_disparities(population_df: pd.DataFrame,
outcome_col: str,
group_col: str) -> pd.DataFrame:
"""
Quantify health disparities across demographic groups.
Computes rate ratios and rate differences relative to reference group.
Used in health equity analyses for vaccine uptake, cancer screening,
chronic disease prevalence, and COVID-19 outcomes by race/ethnicity,
income, geography, and other social determinants of health.
"""
ref_group = population_df[group_col].value_counts().index[0]
ref_rate = (population_df[population_df[group_col] == ref_group][outcome_col].mean())
results = []
for group in population_df[group_col].unique():
group_data = population_df[population_df[group_col] == group]
group_rate = group_data[outcome_col].mean()
results.append({
"group": group,
"rate": group_rate,
"rate_ratio": group_rate / (ref_rate + 1e-9),
"rate_difference": group_rate - ref_rate,
"n": len(group_data)
})
return pd.DataFrame(results).sort_values("rate_ratio", ascending=False)
Environmental Health and Exposure Mapping
AI links environmental data (satellite imagery, air quality sensors, land use maps) to health outcomes at high spatial resolution — enabling exposure mapping where direct measurements don’t exist:
from sklearn.ensemble import GradientBoostingRegressor
import numpy as np
def predict_air_quality_exposure(
location_features: np.ndarray, # lat/lon, land use, road density, etc.
meteorological_features: np.ndarray, # wind, temperature, humidity
source_features: np.ndarray # nearby emission sources, traffic counts
) -> np.ndarray:
"""
Land Use Regression (LUR) model for PM2.5 exposure estimation.
Predicts fine particulate matter concentration at any location
by combining physical features with ML. Used to:
- Estimate exposure for epidemiological cohort studies
- Identify high-exposure communities for intervention
- Model health impact of policy interventions (e.g., emission rules)
Input features typically include:
- Satellite-derived aerosol optical depth (AOD)
- Distance to major roads, truck routes
- Land use classification (industrial, residential, green space)
- Population density, building density
- Local meteorology (wind speed/direction, mixing height)
"""
X = np.concatenate([location_features, meteorological_features,
source_features], axis=1)
# Model would be trained here with monitor observations as targets
return X # placeholder
Challenges in Public Health AI
Data quality and completeness: Health data is collected for administrative, not research, purposes. Case definitions change over time; reporting is inconsistent across jurisdictions; missing data is systematic, not random.
Ecological fallacy: Associations observed at the population level (e.g., areas with more fast food restaurants have higher obesity rates) do not necessarily hold at the individual level. Careful causal reasoning is required before making policy recommendations.
Health equity: ML models trained on data from well-resourced health systems may perform poorly on underserved populations with different patterns of care-seeking, diagnosis, and documentation. Models that optimize for aggregate performance can inadvertently worsen disparities.
Privacy: Individual-level health data is highly sensitive. Differential privacy, federated learning, and secure multi-party computation are increasingly required for public health AI that spans multiple health systems or jurisdictions.
AI in public health holds enormous potential — the COVID-19 pandemic accelerated adoption of real-time surveillance, genomic epidemiology, and forecasting capabilities that would have taken decades to develop otherwise. The challenge now is ensuring these capabilities are deployed equitably, transparently, and with appropriate human oversight.