Skip to main content

AI Model & Forecasting

Ensemble Model

Three models combined with dynamic Inverse-MAE weighting:

ModelFeaturesMin Weight
Random ForestLag + rolling + weather + cyclical30% (floor)
ARIMAAuto-order via AIC grid p∈[0,3] q∈[0,2]Dynamic
XGBoost LiteLag 1/2/3/6/12h — trained at runtimeDynamic

Weighting Formula

w_i = (1 / MAE_i) / Σ(1 / MAE_j)   with   w_RF ≥ 0.30

PM2.5_final = w_RF × pred_RF + w_ARIMA × pred_ARIMA + w_XGB × pred_XGB

Weights recompute every 60-minute cycle based on one-step-ahead MAE against the last 6 hours of actual observations.

Delta clamping: MAX_HOURLY_DELTA = 12.0 µg/m³ prevents implausible step-wise jumps in multi-step iterative forecasts.


Feature Engineering

GroupFeatures
Cyclical timesin/cos(hour), sin/cos(day_of_week), sin/cos(month)
Lag featurespm25_lag_1h, _2h, _3h, _6h, _12h, _24h
Rolling statspm25_roll_mean_3h, _6h, _24h
Diff featurespm25_diff_1h, _3h
Weathertemperature, humidity, wind_speed, wind_direction, pressure, CO, NO₂

Total: 157 features


Training Results

Training data: 01/01/2024 → 02/04/2026 (19,752 hourly points, TPHCM)

Cross-Validation (TimeSeriesSplit — 5 folds)

ModelCV MAECV RMSECV R²
ExtraTrees1.1672.2100.9693
XGBoost1.5032.7710.9533
Random Forest1.7772.9570.9397
Baseline (last hour)2.8954.5520.8809

Test Set (3,951 points — unseen)

ModelMAE (µg/m³)RMSE (µg/m³)
ExtraTrees0.2920.5640.9982
XGBoost0.2650.5090.9985
Random Forest0.2830.6210.9978

All AI models outperform the naive baseline by 6–7× on RMSE.


Adding / Updating a Model

  1. Train in Google Colab (see src/airsafenet_ai/notebooks/)
  2. Export model.pkl + metadata.json
  3. Place in src/airsafenet_ai/models/
  4. Restart the AI server or call POST /admin/compute
  5. Verify via GET /health and GET /model/info

See MODEL_VERSIONING.md for naming conventions.


Anomaly Detection

ParameterValue
Spike threshold+20 µg/m³ within 6-hour lookback
Cooldown2 hours between alerts
XAI methodFeature importance × delta → top 3 factors
Storagedata/anomaly_log.json
Alert triggerPOST to .NET /api/notification/check-and-alert