Before starting, make sure you understand these terms. They appear throughout all code blocks in this course.
| Term | Full Name | What it means in simple words |
|---|---|---|
| RSV | Relative Search Volume | A normalized query metric provided by Google Trends representing search interest for a specific term relative to total searches. |
| Digital Epidemiology | Digital Epidemiology | The science that utilizes digital data sources, such as internet queries and social media, to study disease patterns and public health behaviors. |
| Syndromic Surveillance | Syndromic Surveillance | An epidemiological method monitoring real-time health data, including symptom queries, to provide early warnings of disease outbreaks. |
| ERA5-Land | ECMWF ERA5-Land Reanalysis | A global climate dataset offering hourly and daily atmospheric and land surface variables at high spatial resolution. |
| Spatial Autocorrelation | Spatial Autocorrelation | The degree to which health or environmental variables in neighboring spatial units are correlated with one another. |
| MAUP | Modifiable Areal Unit Problem | A statistical bias where spatial analysis outcomes change when point data are aggregated into different boundary shapes or sizes. |
| Digital Divide | Digital Divide | The socioeconomic gap between populations with consistent internet access and those without, impacting query representativeness. |
| Random Forest Regression | Random Forest Regression | An ensemble machine learning technique that trains multiple decision trees to predict continuous numerical targets. |
| Environmental Determinants | Environmental Determinants of Health | External ecological and climate parameters, such as temperature and humidity, that influence human health outcomes. |
| Confounding Variable | Confounding Variable | An extraneous factor that correlates with both the exposure and outcome, potentially masking true epidemiological relationships. |
| Feature Importance | Feature Importance | A metric in machine learning models that quantifies the relative contribution of each predictor variable. |
| Representativeness Bias | Representativeness Bias | A systemic sampling error where online digital search activity does not accurately reflect the demographics of the broader population. |
Digital epidemiology leverages global web search behavior to monitor public health trends, bridging the gap between delayed clinical surveillance and real-time early warnings. This course explores how to harmonize spatial Google Trends search volume signals with global Earth observation datasets using Google Earth Engine. By combining atmospheric covariates from ERA5-Land, surface temperature from MODIS, and population density from WorldPop, participants will build robust machine learning models to predict spatial disease proxies while explicitly accounting for spatial bias and digital infrastructure disparities.
ECMWF/ERA5_LAND/DAILY_AGGRYou need two browser tabs open side by side throughout this course.
Course25_Global Digital Epidemiology: Integrating Search Signals with GeoAI and Earth Observation
The prompt is the core skill of this course. A good prompt includes the exact dataset ID, band names, study area coordinates, dates, preprocessing steps, and desired outputs.
Paste the following code into your GEE code editor and click Run. Read the beginner notes below to understand what each line does.
// Load global administrative boundaries
var countries = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017');
// Define temporal range for environmental reduction
var startDate = '2023-01-01';
var endDate = '2023-12-31';
// Load air temperature from ERA5-Land Daily (Convert Kelvin to Celsius)
var era5 = ee.ImageCollection('ECMWF/ERA5_LAND/DAILY_AGGR')
.filterDate(startDate, endDate)
.select('temperature_2m')
.mean()
.subtract(273.15)
.rename('mean_air_temp');
// Load Land Surface Temperature from MODIS
var modisLST = ee.ImageCollection('MODIS/061/MOD11A1')
.filterDate(startDate, endDate)
.select('LST_Day_1km')
.mean()
.multiply(0.02)
.subtract(273.15)
.rename('mean_lst');
// Load Population Density from WorldPop
var population = ee.Image('WorldPop/GP/100m/pop')
.rename('pop_density');
// Combine environmental layers into a single multi-band image
var predictors = era5.addBands(modisLST).addBands(population);
// Aggregate environmental mean values across each country boundary
var countryFeatures = predictors.reduceRegions({
collection: countries,
reducer: ee.Reducer.mean(),
scale: 10000
});
// Attach synthetic Google Trends Relative Search Volume (RSV) health proxy
// (Simulating search interest correlated with climate exposure for demonstration)
var healthDataset = countryFeatures.map(function(f) {
var temp = ee.Number(f.get('mean_air_temp'));
var pop = ee.Number(f.get('pop_density'));
// Synthetic expression representing fever/influenza search volume proxy
var rsvProxy = temp.multiply(-0.8).add(pop.log().multiply(2.5)).add(50);
return f.set('RSV_Proxy', rsvProxy);
}).filter(ee.Filter.notNull(['mean_air_temp', 'mean_lst', 'pop_density', 'RSV_Proxy']));
// Print feature sample to Console
print('Processed Global Health Features:', healthDataset.limit(5));
// Visualization setup
Map.setCenter(0, 20, 2);
Map.addLayer(era5, {min: -10, max: 35, palette: ['blue', 'yellow', 'red']}, 'Mean Air Temp (C)');
Map.addLayer(countries, {color: '888888'}, 'Global Boundaries', false);
Add this block after the previous code. It continues the analysis with additional processing and visualization.
// Prepare Machine Learning training attributes
var predictorNames = ['mean_air_temp', 'mean_lst', 'pop_density'];
var targetProperty = 'RSV_Proxy';
// Train a Random Forest Regressor inside Earth Engine
var rfRegressor = ee.Classifier.smileRandomForest(100)
.setOutputMode('REGRESSION')
.train({
features: healthDataset,
classProperty: targetProperty,
inputProperties: predictorNames
});
// Evaluate model resubstitution error
var trainedModel = healthDataset.classify(rfRegressor, 'Predicted_RSV');
print('Model Training Diagnostics:', rfRegressor.explain());
// Predict spatial health query risk raster continuously across global land masses
var spatialRiskMap = predictors.select(predictorNames).classify(rfRegressor);
// Apply population mask to exclude uninhabited zones
var maskedRiskMap = spatialRiskMap.updateMask(population.gt(1));
// Display predicted digital epidemiological risk map
var riskVis = {
min: 20,
max: 80,
palette: ['#2b83ba', '#abdda4', '#ffffbf', '#fdae61', '#d7191c']
};
Map.addLayer(maskedRiskMap, riskVis, 'Predicted Health Search Risk Index');
// Export predicted spatial risk map as geotiff
Export.image.toDrive({
image: maskedRiskMap,
description: 'Global_Digital_Epidemiology_Risk_Map',
scale: 10000,
region: ee.Geometry.BBox(-180, -60, 180, 85),
maxPixels: 1e13
});
Add this block at the end of your script to export the final map as a GeoTIFF to your Google Drive. After clicking Run, go to the Tasks tab in GEE and click Run next to each export task.
// Export summarized country-level table including actual and predicted search proxies
Export.table.toDrive({
collection: trainedModel,
description: 'Global_Digital_Epidemiology_Country_Metrics',
fileFormat: 'CSV',
selectors: ['COUNTRY_NA', 'mean_air_temp', 'mean_lst', 'pop_density', 'RSV_Proxy', 'Predicted_RSV']
});
Use DeepSeek to extend the script for each exercise below. Write a follow-up prompt describing what you want to add, then copy the generated code and paste it into your GEE script.
To get the best results from DeepSeek for GEE tasks, always include these elements in your prompts:
| Element | Example |
|---|---|
| Exact dataset ID | ECMWF/ERA5_LAND/DAILY_AGGR |
| Band names | "select band 'B4' for red, 'B8' for NIR" |
| Study area | "rectangle [-6.5, 33.0, -1.5, 36.0] North Morocco" |
| Date range | "filter from 2020-01-01 to 2023-12-31" |
| Output format | "print area in hectares, add a legend, export to Drive" |
| Error fixing | "The code gives error X. Please fix it." |
| Iteration | "Add a time series chart for each year 2018-2023" |