Beijing · air quality forecast
A model trained on twelve years of the city's own PM2.5 readings against the weather that produced them, run in your browser on the current forecast. Below it: how good the forecast is, and what the model learned about wind, rain and season along the way.
Likely range and confidence. Each day's range is where the measured daily mean landed 80% of the time when the forecast said this, at this many days out, over 2024 – September 2026 against the forecasts actually issued — a factor of about ×0.64 to ×1.67 one day ahead, widening to ×0.5 to ×2.7 at seven. "Sure" is the share of that error distribution that keeps the day inside the forecast's own AQI category: a forecast sitting mid-band is surer than one near an edge, and every day is less sure the further out it is. The shaded band on the chart is the same idea hour by hour — the 10th to 90th percentile of where the measured hour landed at that lead: ×0.86–1.14 one hour out, ×0.6–1.6 at twelve, ×0.5–1.9 at two days, ×0.4–2.8 at seven.
The forecast run is Open-Meteo's best-match model for central Beijing; the readings are the CNEMC city mean via its mirror; the upwind cities are the same publication. Everything is fetched fresh, so the page is never more than about ten minutes behind the network.
The model has two parts. A weather model maps the hour's weather and its previous 72 hours — wind at the surface, at 100 m and at 925/850/700 hPa, boundary-layer height, humidity, rain, the inversion, the season and the city's emissions baseline over the trailing year — to PM2.5. A residual model then learns how far the city's latest reading sits from what the weather alone would give, and how quickly that gap decays with lead time, with the upwind cities' latest readings as a hint of what is coming.
It was fitted on December 2013 – 2022 and judged on 2024 – September 2026, years it never saw and whose air was half as dirty as the years it learned from. The honest test uses the weather forecasts that were actually issued one to seven days earlier over that period: the same model run on reanalysis instead — a perfect forecast — separates its own error from the weather forecast's.
The model's own ceiling is flat at about 0.7 whatever the lead. Beyond two days almost all of the growing error is the weather forecast's: the 100 m northerly wind, the model's most important input, agrees with what happened at 0.85 one day out and 0.40 at seven.
| Lead | R² | MAE µg/m³ | "over 35" right |
|---|
MAE against a mean of 29 µg/m³. The last column is whether the day was correctly called above or below China's 24-hour standard.
| Model or inputs | R² log | R² | MAE |
|---|
Gradient boosting and a recurrent net land in the same place, so the ceiling is the inputs, not the model. Upwind readings are worth a great deal for six hours and nothing after two days, which is why the forecast leans on them early and on the weather later.
Wind history carries half of the model's explanatory power, and its single most important input is the northerly component of the 100 m wind averaged over the past 24 hours — not the wind now, and not its speed. A steady wind at 6 m/s leaves 13 µg/m³ if it comes from the north-west and 57 if it comes from the south, and a stronger southerly is worse: it is importing the Hebei plain's air. Above the rooftops the signal is cleaner still: the northerly wind at 925 hPa, from the radiosonde, is the strongest single correlate of PM2.5 in the whole dataset.
Everything else held at its observed value, averaged over 20,000 hours. Calm is bad in every direction; the north-west is clean at any speed; the south gets dirtier as it blows harder.
The air clears within six hours, bottoms out at +6 to +12 h at about a third of the level before the front, and takes two days to climb back. Spring is the exception when the wind brings dust: in those 29 onsets PM2.5 rose first.
Washout is real and scales with amount. Take every hour with rain in the past 24 h, ask the model to predict it, then zero every precipitation input with wind, humidity, boundary layer and season left exactly as they were: the prediction drops 17% for a trace-to-2 mm day, 24% at 2–5 mm, 46% at 20–50 mm, 60% above 50 mm. A model-free comparison of wet and dry hours in the same month, wind sector, wind speed and time of day agrees: −25%.
But rain arrives wet. Humidity is the strongest non-wind lever the model has — 31 µg/m³ at 10% RH, 60 at 100% — because particles swell in humid air and a saturated, stagnant airmass is the recipe for haze. Compared with a genuinely dry day at that month's typical humidity, light rain is net-neutral; the day comes out cleaner only past about 20 mm. In winter it flips outright: snowy and drizzly days are stagnant, humid, southerly days, so January's wet hours run far dirtier than its dry ones.
≥ 2 mm in the past 24 h against none in the past 48 h, within month × wind sector × wind-speed tercile × 6 h block × era. January rests on few wet hours: read it as "large and positive".
Still −18% two days later. Beijing's air takes about as long to re-load after rain as after a north wind.
Each panel varies one input across its range for the same 20,000 sampled hours, holding everything else fixed. Season keeps its shape even after wind, humidity and boundary layer are accounted for. Below a 100 m boundary layer the model reads 56 µg/m³, above 800 m about 35, and then it saturates. Wind speed on its own is non-monotonic — calm is bad, 4 m/s is the clean point, and 8–10 m/s is worse again because at those speeds the model is seeing strong southerlies and dust. Hour of day goes nearly flat once the boundary layer is an input; weekday is exactly flat — Beijing has no weekend effect.
Hold the emissions baseline at 2014's and give the model each later year's actual weather: it predicts 78–87 µg/m³ every year. The fall from 87 to 27 is emissions, with the weather of 2017 and 2025 somewhat kinder and 2023–24 somewhat harsher than average.
| Inputs removed | R² loss |
|---|
Small numbers for humidity, boundary layer and hour of day mean they are interchangeable — a night hour, high humidity and a shallow lid all say "stagnant" — not that they don't matter.
Target: hourly city-mean PM2.5 as log1p. Inputs: Capital Airport METARs,
ERA5 reanalysis for central Beijing, the Nanjiao radiosonde, twenty surrounding cities' PM2.5 and PM10, and the
calendar as sine/cosine pairs. Gradient-boosted trees; the year is not an input — networks extrapolated the
2013–22 decline as a line — the trailing-year mean stands in for it.
Left out on purpose because they are what PM2.5 looks like, not what causes it: visibility, the haze and
mist codes, and whether the METAR carried a cloud group at all (a report is CAVOK only when visibility is
10 km or more — it was the third most important feature until it was caught).
Sources: CNEMC via quotsoft.net · IEM METAR · Open-Meteo ERA5 (pinned to models=era5) and forecast
archive · NOAA IGRA v2. Code and every number on this page: ml/ in the repository.