An open forecaster that ranks the hours of tomorrow by how breathable the air is in Islamabad / Rawalpindi.
Built with PriorLabs-TabPFNTabPFN v2 needs roughly 1,000–2,500 training hours (about 6–15 weeks of hourly data) before it matches, and then edges, a one-line hour-of-day bias baseline on hour ranking. Below that it is worse and high-variance.
Mean gap in median within-day ranking ρ, TabPFN − B2: −0.12 at 100 h, −0.05 at 250 h, −0.12 at 500 h, +0.01 at 1,000 h, +0.07 at 2,500 h, +0.11 at 5,000 h. The edge is consistent across folds only at 5,000 h (4/4 folds; 3/5 at 1,000 and 2,500 h). Six rolling-origin folds, not the spent TEST month.
Clear Hour predicts the cleanest 2h window of 2026-10-11 is 15:00-17:00 at 49.2 ug/m3; the dirtiest is 22:00-00:00 at 78.4 ug/m3.
Late entry: the B0 and B2 curves were committed at 06:10:46 (69c7d9e). TabPFN was committed at 06:51 (802344a); hours before that time (shaded, up to 07:00) had already occurred and are not pre-registered. Inputs are live forecasts; ground truth is an uncalibrated low-cost sensor.
Lanes under the axis: solid bar = each model's cleanest 2 h window, outlined bar = its dirtiest. Shaded region = hours before the TabPFN commit.
| Model | Cleanest 2 h (µg/m³) | Dirtiest 2 h (µg/m³) |
|---|---|---|
| TabPFN v2 late entry | 15:00–17:00 (49.2) | 22:00–00:00 (78.4) |
| B2 hour-bias pre-registered | 15:00–17:00 (54.0) | 22:00–00:00 (81.8) |
| B0 raw CAMS pre-registered | 05:00–07:00 (34.9) | 22:00–00:00 (67.3) |
Measured hours: 24/24. Truth = OpenAQ sensor 4554236, uncalibrated low-cost, CC BY 4.0, The Urban Unit (AirGradient sensor, uncalibrated). One day is one sample.
| Model | View | MAE | Bias | Spearman ρ | Chosen cleanest 2 h | Actual PM2.5 in that window | Inside actual cleanest set? |
|---|---|---|---|---|---|---|---|
| TabPFN v2 | full day | 21.9 | +14.6 | -0.369 | 15:00-17:00 | 29.8 vs day mean 45.4 | no |
| TabPFN v2 | hours ≥ 07:00 (windows re-derived) | 25.6 | +25.6 | -0.483 | 15:00-17:00 | 29.8 vs day mean 35.7 | no |
| B2 hour-bias | full day | 25.3 | +18.8 | -0.409 | 15:00-17:00 | 29.8 vs day mean 45.4 | no |
| B2 hour-bias | hours ≥ 07:00 (windows re-derived) | 30.9 | +30.9 | -0.153 | 15:00-17:00 | 29.8 vs day mean 35.7 | no |
| B0 raw CAMS | full day | 21.9 | -3.5 | -0.512 | 05:00-07:00 | 73.7 vs day mean 45.4 | no |
| B0 raw CAMS | hours ≥ 07:00 (windows re-derived) | 18.1 | +7.8 | -0.701 | 09:00-11:00 | 47.8 vs day mean 35.7 | no |
| Hour | TabPFN v2 | B2 | B0 | Measured |
|---|---|---|---|---|
| 00:00 | 63.4 | 58.5 | 41.9 | 84.1 |
| 01:00 | 64.3 | 60.9 | 41.1 | 74.4 |
| 02:00 | 57.6 | 58.6 | 39.2 | 66.9 |
| 03:00 | 55.7 | 56.7 | 37.1 | 52.9 |
| 04:00 | 53.3 | 56.9 | 35.4 | 56.7 |
| 05:00 | 51.3 | 56.8 | 34.8 | 66.7 |
| 06:00 | 51.4 | 60.0 | 35.0 | 80.7 |
| 07:00 | 53.3 | 65.2 | 37.7 | 50.5 |
| 08:00 | 55.3 | 66.5 | 37.3 | 47.8 |
| 09:00 | 57.4 | 65.3 | 34.9 | 48.8 |
| 10:00 | 57.2 | 67.1 | 35.5 | 46.8 |
| 11:00 | 56.2 | 69.5 | 35.3 | 49.5 |
| 12:00 | 55.2 | 65.8 | 35.3 | 51.0 |
| 13:00 | 56.9 | 61.5 | 36.6 | 45.6 |
| 14:00 | 52.5 | 57.8 | 37.6 | 35.8 |
| 15:00 | 49.6 | 53.1 | 36.4 | 31.9 |
| 16:00 | 48.8 | 54.9 | 38.1 | 27.7 |
| 17:00 | 59.4 | 59.0 | 40.9 | 18.2 |
| 18:00 | 65.1 | 67.0 | 45.6 | 23.7 |
| 19:00 | 69.9 | 70.9 | 48.9 | 22.4 |
| 20:00 | 73.5 | 71.5 | 50.2 | 21.7 |
| 21:00 | 74.9 | 73.7 | 55.3 | 24.4 |
| 22:00 | 78.8 | 78.8 | 63.8 | 24.4 |
| 23:00 | 78.1 | 84.8 | 70.8 | 37.0 |
Rolling-origin test: for each of six 30-day windows, train on the N most recent valid hours before the window (recency, never random). Mean over the folds available at each N (4–6); TabPFN's whiskers are ±1 std across folds (large: fold spread is as big as most gaps between models). The shaded column marks 1,000–2,500 h.
Ridge is omitted from the error chart: it is off-scale at small N (MAE 321 at 100 h, 74 at 250 h, 52 at 500 h). N = 10,000 is not shown: TabPFN was not run there (one fold, baselines only). The F3 smog-season fold dominates every mean; differences under ~1–2 µg/m³ or ~0.05 in ρ are ties.
| Model (mean over folds) | N=100 | N=250 | N=500 | N=1,000 | N=2,500 | N=5,000 |
|---|---|---|---|---|---|---|
| TabPFN v2 | 0.317 MAE 19.7 | 0.447 MAE 18.4 | 0.431 MAE 17.9 | 0.544 MAE 17.2 | 0.616 MAE 16.0 | 0.590 MAE 16.9 |
| HistGBR | 0.350 MAE 18.3 | 0.402 MAE 18.8 | 0.442 MAE 17.5 | 0.441 MAE 17.2 | 0.457 MAE 16.8 | 0.541 MAE 31.9 |
| B2 hour-bias | 0.439 MAE 19.2 | 0.498 MAE 18.1 | 0.555 MAE 21.3 | 0.535 MAE 24.1 | 0.543 MAE 30.2 | 0.476 MAE 44.5 |
| Ridge | 0.309 MAE 320.9 | 0.470 MAE 74.1 | 0.529 MAE 52.5 | 0.469 MAE 50.5 | 0.453 MAE 19.1 | 0.547 MAE 22.4 |
| B0 raw CAMS | 0.439 MAE 24.9 | 0.439 MAE 24.9 | 0.479 MAE 27.2 | 0.479 MAE 27.2 | 0.479 MAE 27.2 | 0.431 MAE 30.1 |
| TabPFN − B2 (ρ) | -0.123 | -0.051 | -0.124 | +0.010 | +0.073 | +0.114 |
Trained on sensor 4554236 (2,500 most recent hours, no retraining), evaluated at sensor 4565419 over folds F2, F3, F4, F6. Both sensors share the same CAMS/weather inputs; F1 and F5 have no transfer cell.
| Model | MAE | median ρ | top-window hit | folds |
|---|---|---|---|---|
| B0 raw CAMS | 27.5 | 0.570 | 43% | 4 |
| B2 CAMS+hour bias | 32.5 | 0.604 | 47% | 4 |
| B4 Ridge | 18.2 | 0.568 | 47% | 4 |
| B5 HistGBR | 17.5 | 0.521 | 43% | 4 |
| M1 TabPFN v2 | 16.8 | 0.661 | 56% | 4 |
2026-09-10 → 2026-10-09, 30 days, models refit on TRAIN+DEV. TabPFN's MAE edge over B2 is clear; its ranking edge over B2 is not statistically significant, and HistGBR beat TabPFN on the DEV month.
| Model | MAE | RMSE | Bias | Within-day ρ median | Top-2h hit |
|---|---|---|---|---|---|
| B0 raw CAMS | 16.1 | 20.7 | -3.4 | 0.564 | 30% |
| B1 CAMS+const bias | 22.0 | 28.7 | +20.2 | 0.564 | 30% |
| B2 CAMS+hour bias | 22.1 | 28.7 | +20.2 | 0.544 | 43% |
| B3 CAMS+hour×season bias | 31.6 | 41.1 | +27.3 | 0.489 | 40% |
| B4 Ridge | 20.3 | 27.4 | +17.4 | 0.603 | 30% |
| B5 HistGBR | 10.8 | 15.2 | -4.1 | 0.644 | 40% |
| M1 TabPFN v2 | 10.3 | 14.6 | -4.2 | 0.675 | 37% |