← Index fig. 8

Satellite-Derived Wildfire Smoke Exposure

an XGBoost wildfire model that took F1 from 0.12 to 0.52, shown at ISES-ISEE and AGU

Year
2025
Kind
Research
Role
Machine learning researcher
With
Emory School of Public Health
Tools
Python, XGBoost, Wavelet Transforms, Remote Sensing
An hourly PM2.5 series with two smoothed curves overlaid, separating fast spikes from the slow background

A PM2.5 reading tells you how much fine particulate is in the air. It doesn’t tell you why. Traffic, a cold morning inversion and a wildfire plume 300 miles away can all push the number up. For health research you need to know which days were actually smoke days, and the existing labels for that disagree with each other a lot.

From May 2024 to August 2026 I worked on that problem with a group at Emory’s School of Public Health.

TLDR: I built the pipeline that breaks 10+ years of surface PM2.5 readings into time scales with a discrete wavelet transform, so slow background pollution and sharp smoke events end up in different bands. Those bands, plus satellite smoke maps, air-quality model output, fire counts and weather, feed an XGBoost classifier that flags smoke days. It reached an F1 of 0.52 under 10-fold cross-validation. For comparison, airport-based smoke labels agree with NOAA’s satellite smoke product at an F1 of just 0.12. The work went to ISES-ISEE 2025 and to the AGU Annual Meeting as a talk, where I’m one of nine authors.

The figures on this page are a recreation of the method on public data from one WRCC monitor, made for this write-up. The real pipeline, data and results stay on Emory’s servers.

Why wavelets

Look at a raw PM2.5 series and the smoke jumps out to a human: tall, sudden spikes that last a day or two. But a model sees one number per time step, with no idea which part is the slow drift and which part is the event.

Hourly PM2.5 from one smoke monitor over 16 days in October 2024, flat for days and then spiking above 200
Raw hourly PM2.5 from one temporary smoke monitor in Utah, October 2024. Long quiet stretches, then spikes.

A discrete wavelet transform splits the series into bands by time scale. The approximation band keeps the slow background. Each detail band keeps the wiggles at one scale (hours, half-days, days). Add the bands back together and you get the original signal exactly, so the transform sorts the signal without losing any of it.

Six stacked panels: the signal, the slow approximation band, and four detail bands from slowest to fastest
The same series split into five bands with a db4 wavelet. A4 is everything slower than about 32 hours; D1 is the 2–4 hour jitter.
Python source for loading the series, running pywt.wavedec and rebuilding each band in the time domain
The decomposition is about twenty lines with PyWavelets. The assert at the end checks the bands add back up to the signal.

What the bands give the model

Instead of one raw value per day, the classifier gets features that say “this much of today’s signal is slow background, this much is a fast spike”. A smoke event shows up as energy in the detail bands that the background can’t explain.

Bar chart of how much of the signal's energy is in each band, with the approximation band at about 53 percent
Share of energy per band for this one record. About half is slow background; the rest is spread across the faster bands where the events live.

The real pipeline did this on daily data from EPA monitors across many sites and more than a decade, which is where most of the engineering went: getting years of sensor and satellite data into one consistent shape.

The team

The AGU talk, “Developing Data-driven Wildfire Smoke Detection Using Wavelet-decomposed Surface Observations and Machine Learning”, lists Meng Qi as first author, with Zhihao Jin, Zhuohan Chi, Danlu Zhang, Ke Xu, Dimple Pruthi, me, Wenhao Wang and Yang Liu.