PMPredictor - Rezumat Complet Proiect
🎯Descriere Generală
PMPredictor este un sistem complet de monitorizare și predicție a calității aerului (PM2.5) care combină:
- 7 senzori activi cu date în timp real
- 5 modele de predicție (IDW, Ordinary Kriging, Universal Kriging, Random Forest, XGBoost)
- Dashboard interactiv cu hărți și grafice
- API REST complet documentat
- Sistem de alertare prin email
- Training automat pentru modele ML
📂 Structura Proiectului
/opt/pm25/
├── backend/ # Backend Python (FastAPI)
│ ├── main.py # API REST principal
│ ├── kriging.py # Modele Kriging (Ordinary + Universal)
│ ├── ml_models.py # Random Forest + XGBoost
│ ├── train_models.py # Script training modele ML
│ ├── evaluate_models.py # Evaluare și comparație modele
│ ├── generate_measurements.py # Generator date realiste
│ └── alert_system.py # Sistema alertare email
│
├── html/ # Frontend
│ ├── index.html # Dashboard principal
│ └── assets/ # CSS, JS, imagini (local)
│ ├── css/
│ ├── js/
│ └── fonts/
│
├── database/ # SQL
│ └── schema.sql # Schema PostgreSQL + PostGIS
│
├── models_storage/ # Modele ML trained
│ ├── random_forest_model.pkl
│ ├── xgboost_model.pkl
│ └── evaluation_report.json
│
├── logs/ # Loguri aplicație
│ ├── gunicorn-access.log
│ ├── gunicorn-error.log
│ ├── data-generator.log
│ ├── alerts.log
│ ├── training.log
│ └── evaluation.log
│
├── data/ # Date auxiliare
│ └── alert_state.json # Tracking alerte trimise
│
├── venv/ # Python virtual environment
├── gunicorn.conf.py # Config Gunicorn
└── requirements.txt # Dependențe Python
🔧Descriere Fișiere
Principale
Backend (Python + FastAPI)
1. backend/main.py ⭐ CORE API
Rol:API REST principal pentru întreg sistemul
-
Endpoints:
- GET / - Health check
- GET /sensors - Lista senzori
- GET /sensors/{id} - Detalii senzor
- GET /measurements/latest - Ultimele măsurători
- GET /measurements - Istoric măsurători (cu filtre)
- POST /predict - Predicție PM2.5(suportă 5 modele)
- GET /sensors/{id}/stats - Statistici senzor
- GET /predictions - Istoric predicții
-
Modele suportate:
- IDW (Inverse Distance Weighting)
- Ordinary Kriging
- Universal Kriging
- Random Forest
- XGBoost
-
Funcții principale:
- predict_pm25_idw() - Algoritm IDW
- haversine_distance() - Calcul distanțe geografice
- get_db() - Context manager pentru PostgreSQL
-
Dependințe:
FastAPI, psycopg2, numpy, math
2. backend/kriging.py 🗺️ GEOSTATISTICS
Rol:
Implementare Kriging (Ordinary + Universal) pentru interpolare spațială avansată
-
Clase:
- KrigingPredictor - Predictor principal
- fit() - Antrenare model cu senzori
- predict() - Predicție la coordonate țintă
- predict_grid() - Predicție pe grid (pentru vizualizări)
- calculate_confidence() - Calcul scor încredere
-
Funcții:
- predict_pm25_kriging() - Funcție wrapper pentru API
-
Features:
- Variograme automate (spherical, exponential, gaussian, linear, power)
- Universal Kriging cu drift polynomial
- Kriging variance pentru uncertainty quantification
- Confidence scoring bazat pe variogramă și număr senzori
-
Dependințe:
pykrige, numpy
3. backend/ml_models.py 🤖 MACHINE LEARNING
Rol:
Modele ML (Random Forest + XGBoost) pentru predicții avansate
-
Clase:
- MLPredictor - Predictor ML principal
- _create_features() - Feature engineering (23 features)
- train() - Antrenare model
- predict() - Predicție
- save() / load() - Persistență modele
-
Features (23 total):
-
Temporale:
hour, day_of_week, month, is_weekend, is_rush_hour
-
Spațiale:
distanțe (min, mean, max, std), sensor density
-
Statistice PM2.5:
mean, median, std, min, max, range, IDW baseline
-
Meteo:
mean/std temperature, mean/std humidity
-
Coordonate:
target_lat, target_lon
-
Funcții:
- predict_pm25_ml() - Wrapper pentru API
- train_ml_model_from_history() - Training din DB (placeholder)
-
Dependințe:
scikit-learn, xgboost, pandas, joblib
4. backend/train_models.py 🎓 TRAINING PIPELINE
Rol:
Script pentru antrenarea modelelor ML din date istorice
-
Funcții principale:
- create_training_data() - Creează dataset din măsurători istorice
- Strategy: Leave-one-out (folosește alți senzori pentru a prezice un senzor)
- Generează ~2500+ samples din 30 zile de date
- create_features_from_sensors() - Feature engineering
- train_model() - Antrenează un model (RF sau XGBoost)
- evaluate_model() - Calculează metrici (RMSE, MAE, R²)
- compare_with_baseline() - Comparație cu IDW baseline
-
Metrici calculate:
- RMSE (Root Mean Square Error)
- MAE (Mean Absolute Error)
- R² (Coefficient of Determination)
- Cross-validation RMSE
-
Usage:
python3 train_models.py --days 30 --models random_forest xgboost --compare
-
Output:
Modele salvate în /opt/pm25/models_storage/
5. backend/evaluate_models.py 📊 EVALUATION
Rol:
Evaluare și comparație a tuturor modelelor pe date live
-
Funcții:
- test_model_on_live_data() - Test pe date recente (leave-one-out)
- generate_comparison_report() - Raport complet comparativ
- check_model_drift() - Detectează dacă modelele necesită re-training
-
Output:
- Tabel comparativ sortate după RMSE
- Identifică cel mai bun model
- Calculează improvement față de baseline
- Salvează raport JSON
-
Usage:
- python3 evaluate_models.py - Evaluare completă
- python3 evaluate_models.py --drift - Check drift
6. backend/generate_measurements.py 📡 DATA GENERATOR
Rol:
Generează date realiste de la senzori pentru simulare și testing
-
Clasa:
- RealisticDataGenerator
- Patternuri realiste bazate pe:
-
Ora zilei:
rush hour (7-9, 17-20), noapte (0-6)
-
Sezon:
iarnă (+30% PM2.5), vară (-20%)
-
Locație:
Unirii (35), Victoriei (28), Băneasa (22), etc.
- Tranziții smooth între valori consecutive
- Spike-uri aleatorii (5% șansă)
-
Features generate:
- PM2.5, PM10
- Temperatură, umiditate, presiune
- Viteză vânt, direcție vânt
- Quality flag (valid/suspicious/invalid)
-
Usage:
Rulează din cron la 10 minute
-
Cleanup:
Șterge automat date >30 zile
7. backend/alert_system.py 📧 EMAIL ALERTS
Rol:
Monitorizare și alertare automată prin email
-
Clasa:
- AlertManager
- check_pm25_levels() - Verifică praguri PM2.5
- check_sensor_status() - Detectează senzori offline
- send_email_alerts() - Trimite email-uri HTML
-
Praguri alertare:
- PM2.5 >55: Unhealthy
- PM2.5 >150: Very Unhealthy
- PM2.5 >250: Hazardous
- Senzor offline >30 min
-
Features:
- Rate limiting (1 alert/60 min per senzor)
- State tracking în alert_state.json
- Email-uri HTML frumoase cu culori
-
Config:
.env pentru SMTP credentials
-
Usage:
Rulează din cron la 5 minute
Frontend (HTML + JavaScript)
8. html/index.html 🎨 DASHBOARD
Rol:
Dashboard interactiv web pentru utilizatori
-
Componente:
-
Header:
Titlu + Last Update
-
Stats Cards:
4 card-uri (senzori activi, avg PM2.5, predicții, AQI)
-
Hartă Leaflet:
Interactivă cu markeri pentru senzori și predicții
-
Lista Senzori:
Clickable pentru grafice
-
Formular Predicție:
- Selector model (5 opțiuni)
- Parametri specifici (IDW power, variogram type)
- Coordonate + rază
-
Modal Grafic:
Chart.js cu 3 datasets (PM2.5, Temp, Humidity)
-
Legendă AQI:
Categorii calitate aer
-
Funcții JavaScript:
- initMap() - Inițializare Leaflet
- loadSensors() - Încărcare senzori de la API
- loadLatestMeasurements() - Update date live
- showSensorChart() - Afișare grafic în modal
- displayPrediction() - Afișare rezultat predicție
-
Features:
- Click pe hartă → predicție automată
- Auto-refresh la 5 minute
- Responsive design (Tailwind CSS)
- Toate assets sunt locale (nu CDN)
Database
9. database/schema.sql 🗄️ DATABASE SCHEMA
Rol:
Schema completă PostgreSQL cu PostGIS
-
Tabele principale:
-
sensors
- Senzori fizici (id, name, lat/lon, location geography, status)
-
measurements
- Măsurători RAW (sensor_id, pm25, pm10, temp, humidity, timestamp)
-
predictions
- Predicții calculate (lat/lon, predicted_pm25, method, confidence)
-
prediction_sensors
- Many-to-many (ce senzori au contribuit la predicție)
-
air_quality_categories
- Categorii AQI (Good, Moderate, Unhealthy, etc.)
-
alerts
- Istoric alerte
-
Indexuri:
- GiST pentru location (căutări geografice rapide)
- B-tree pentru timestamp (time-series queries)
-
Views:
- latest_measurements - Ultimele valori de la fiecare senzor
- valid_predictions - Predicții valide și actuale
-
Funcții PostgreSQL:
- find_sensors_within_radius() - Găsește senzori într-o rază
- get_average_pm25() - Calculează media într-un interval
-
Sample data:
4 senzori în București + 24h de măsurători
Configurare
10. gunicorn.conf.py ⚙️ GUNICORN CONFIG
Rol:
Configurație Gunicorn pentru producție
- Workers, bind address, logging, etc.
11. requirements.txt 📦 DEPENDENCIES
Rol:
Lista dependențe Python
- fastapi
- uvicorn
- psycopg2-binary
- scikit-learn
- xgboost
- pykrige
- geopandas
- numpy, pandas, scipy
- matplotlib, seaborn
- joblib
12. .env 🔐 ENVIRONMENT VARIABLES
Rol:
Configurație sensibilă (nu în git)
- Database credentials
- SMTP settings pentru email
- API keys (dacă există)
🔄 Workflow Complet
┌─────────────────────────────────────────────────────┐
│ 1. GENERARE DATE (cron: la 10 min) │
│ generate_measurements.py → PostgreSQL │
└─────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ 2. TRAINING ML (cron: săptămânal) │
│ train_models.py → models_storage/*.pkl │
└─────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ 3. EVALUARE (cron: zilnic) │
│ evaluate_models.py → evaluation_report.json │
└─────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ 4. MONITORIZARE (cron: la 5 min) │
│ alert_system.py → Email alerts │
└─────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ 5. UTILIZARE (on-demand) │
│ User → index.html → API → Models → Response │
└─────────────────────────────────────────────────────┘
📊 Metrici Actuale
|
Model
|
RMSE (μg/m³)
|
MAE
|
R²
|
Status
|
|
XGBoost
|
~4.9 |
~3.5 |
0.88 |
✅ Best |
|
Random Forest
|
~5.2 |
~3.9 |
0.87 |
✅ Very Good |
|
Universal Kriging
|
~6.1 |
~4.5 |
0.82 |
✅ Good |
|
Ordinary Kriging
|
~6.8 |
~4.9 |
0.79 |
✅ Good |
|
IDW
|
~8.5 |
~6.1 |
0.71 |
✅ Baseline |
🎯 Ce Poate Face Sistemul
-
✅ Monitorizare real-time
- 7 senzori activi
-
✅ Predicții avansate
- 5 modele diferite
-
✅ Dashboard interactiv
- Hărți + grafice
-
✅ API REST complet
- Swagger docs
-
✅ Training automat
- Weekly retraining
-
✅ Alerting
- Email când PM2.5 >praguri
-
✅ Evaluare continuă
- Model performance tracking
-
✅ Istoric complet
- 30 zile de date păstrate
🔑 Comenzi Esențiale
# Start/Stop
sudo systemctl start|stop|restart pmpredictor
sudo systemctl start|stop|restart nginx
# Training
cd /opt/pm25/backend &&source ../venv/bin/activate
python3 train_models.py --days 30 --models random_forest xgboost
# Evaluare
python3 evaluate_models.py
# Generare date manual
python3 generate_measurements.py
# Alerte manual
python3 alert_system.py
# Logs
tail -f /opt/pm25/logs/*.log
🏆Aditionale
In venv
# Rulează training
./train_models.py --days 30 --models random_forest xgboost --compare
# Evaluare completă a tuturor modelelor
./evaluate_models.py
# Check model drift (verifică dacă trebuie retrained)
./evaluate_models.py --drift
- 1. ⏳ Extrage date din ultimele 30 zile din PostgreSQL
- 2. 🔧 Creează training samples (leave-one-out strategy)
- 3. 🧮 Feature engineering (23 features per sample)
- 4. 🌲 Antrenează Random Forest (100 trees)
- 5. 🚀 Antrenează XGBoost (gradient boosting)
- 6. 📊 Calculează metrici (RMSE, MAE, R²)
- 7. 🔄 Cross-validation (5-fold)
- 8. 💾 Salvează modele în folderul models_storage/
- 9. 📈 Compară cu IDW baseline
# Retrain ML models săptămânal (Luni la 3 AM, dupa un weekend fumigen)
0 3 * * 1 cd /opt/pm25/backend &&source ../venv/bin/activate &&python3 train_models.py --days 30 --models random_forest xgboost >>/opt/pm25/logs/training.log 2 >&1
# Evaluare modele zilnic (la 4 AM, daca are timp sa termine trainuirea, fara GPU)
0 4 * * * cd /opt/pm25/backend &&source ../venv/bin/activate && python3 evaluate_models.py >> /opt/pm25/logs/evaluation.log 2 >& 1
# Check drift săptămânal (Duminică la 23:00)
0 23 * * 0 cd /opt/pm25/backend &&source ../venv/bin/activate &&python3 evaluate_models.py --drift >>/opt/pm25/logs/drift-check.log 2 >&1