A deployed machine-learning weather app that trains and serves a custom Keras sequence model for 7-day city-level forecasting.
AI Weather Predictor is a full ML engineering project for forecasting the next 7 days of weather for a user-selected city. The current production version uses a custom trained TensorFlow/Keras model, not a third-party forecast endpoint, to generate future weather values from recent historical observations.
The app collects recent weather history for a city, applies the same v2 preprocessing pipeline used during training, scales the input features, runs the trained Keras model, inverse-transforms the predictions, and presents a structured forecast with confidence labels, risk signals, model diagnostics, and an OpenAI-generated natural-language explanation grounded in the model output.
This project is designed to demonstrate practical ML engineering: data collection, feature engineering, supervised sequence creation, model training, model evaluation, inference serving, API deployment, and user-facing AI interpretation.
flowchart LR
A[City Input] --> B[FastAPI Web App]
B --> C[Geocode City]
C --> D[Historical Weather Archive]
D --> E[v2 Feature Engineering]
E --> F[60-Day Scaled Input Window]
F --> G[Custom Keras Sequence Model]
G --> H[7-Day Multi-Target Forecast]
H --> I[Risk and Confidence Layer]
H --> J[OpenAI Explanation Layer]
I --> K[Forecast API and Web UI]
J --> K
L[Training Script] --> M[Multi-City Historical Dataset]
M --> N[Time-Based Train/Validation/Test Split]
N --> O[v2 Model Artifacts]
O --> B
The model predicts 7 daily steps for 6 target variables:
| Target | Meaning |
|---|---|
tavg |
Average daily temperature |
tmin |
Minimum daily temperature |
tmax |
Maximum daily temperature |
wspd |
Maximum daily wind speed |
prcp |
Daily precipitation amount |
snow |
Daily snowfall amount |
The app derives rain/snow signals, risk indicators, and confidence labels from these model-generated values. Rain signal is model-derived from predicted precipitation amount; it is not presented as an official calibrated meteorological probability.
The current deployed model is model_v2, trained from historical daily weather data between 2020-01-01 and 2026-07-02.
| Metric | Value |
|---|---|
| Training sequences | 61,845 |
| Validation sequences | 12,775 |
| Test sequences | 6,195 |
| Average temperature MAE | 2.403 C |
| Minimum temperature MAE | 2.396 C |
| Maximum temperature MAE | 2.949 C |
| Mean temperature MAE | 2.583 C |
| Wind speed MAE | 4.513 km/h |
| Precipitation MAE | 2.850 mm |
| Snow MAE | 0.112 cm |
The test set is time-based rather than random-only, which makes the evaluation more realistic for forecasting. The model is strongest as a portfolio-quality applied ML system; it is not intended to claim superiority over professional numerical weather prediction systems.
The v2 model was trained on a curated set of 35 Italian and nearby European cities, including:
Padova, Venice, Verona, Vicenza, Treviso, Bologna, Ferrara, Ravenna, Milan, Turin, Genoa, Florence, Rome, Naples, Bari, Palermo, Trieste, Trento, Bolzano, Udine, Ljubljana, Zagreb, Vienna, Munich, Zurich, Innsbruck, Nice, Lyon, Paris, Barcelona, Madrid, Berlin, Amsterdam, Prague, and Budapest.
This geographic selection gives the model stronger regional relevance for northern Italy and surrounding European climate patterns.
The v2 preprocessing pipeline is shared by training and inference through webapp/ml_pipeline.py. It builds a 60-day input sequence using:
- Raw weather variables: temperature, wind, precipitation, snow.
- Temperature range features.
- Lag features for temperature, wind, and precipitation.
- Rolling temperature averages over 3, 7, and 14 days.
- Rolling precipitation and snow history.
- Rain-day counts over the previous week.
- Wind rolling averages.
- Day-of-year, month, and weekday cyclical encodings.
- Latitude and longitude normalized features.
- Learned feature and target scaling saved in
streamlit/model_v2/scalers_v2.npz.
Using the same pipeline for training and serving reduces training/inference mismatch.
The v2 model is a supervised multi-output sequence model:
| Component | Description |
|---|---|
| Input | 60 days x engineered features |
| Output | 7 days x 6 weather targets |
| Architecture | Causal Conv1D layers, GRU encoder, dense forecast head |
| Loss | Huber loss |
| Optimizer | Adam |
| Callbacks | Early stopping, learning-rate reduction, best-model checkpoint |
The trained model artifact is stored at:
streamlit/model_v2/weather_model_v2.keras
Supporting artifacts:
streamlit/model_v2/scalers_v2.npz
streamlit/model_v2/metrics_v2.json
streamlit/model_v2/training_cities_v2.csv
AI-weather-predictor/
|-- assets/
| `-- ai-weather-predictor-cover.png
|-- infrastructure/ # Terraform configuration for cloud resources
|-- mlflow/ # Historical experiment artifacts
|-- models/ # Legacy model artifact
|-- notebooks/ # Original exploration and training notebooks
|-- scripts/
| |-- train_weather_model_v2.py # Reproducible v2 training pipeline
| |-- data_collector.py # Legacy collection script
| |-- preprocessing.py # Legacy preprocessing script
| `-- test.py # Legacy inference test script
|-- streamlit/
| |-- model_v2/ # Current deployed model/scalers/metrics
| |-- app.py # Legacy Streamlit app
| |-- data_collector.py # Legacy app-side data retrieval
| |-- preprocessing.py # Legacy app-side preprocessing
| `-- weather_model.keras # Legacy model artifact
|-- webapp/
| |-- main.py # Current FastAPI production app
| |-- ml_pipeline.py # Shared v2 training/inference pipeline
| `-- requirements.txt # Web deployment dependencies
|-- requirements.txt
|-- LICENSE
`-- README.md
git clone https://github.com/sntk-76/AI-weather-predictor.git
cd AI-weather-predictor
python -m venv .venv
source .venv/bin/activate
pip install -r webapp/requirements.txt
uvicorn webapp.main:app --host 127.0.0.1 --port 8601On Windows PowerShell:
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install -r webapp\requirements.txt
uvicorn webapp.main:app --host 127.0.0.1 --port 8601Then open:
http://127.0.0.1:8601/weather/
curl -X POST http://127.0.0.1:8601/weather/api/forecast \
-H "Content-Type: application/json" \
-d '{"city":"Padova"}'The response includes:
forecast: 7 model-generated daily predictions.insights: warmest/coolest/wettest day and trend.risks: model-derived weather risk signals.summary: OpenAI-generated explanation grounded in model output.model: model version, target variables, and holdout metrics.diagnostics: input data window and rows used for inference.source: historical data source and notes about model-derived signals.
Run the v2 training script:
python scripts/train_weather_model_v2.py --start-date 2020-01-01 --epochs 22 --batch-size 128The script:
- Downloads historical daily weather for the configured training cities.
- Builds the shared v2 features.
- Creates 60-day input and 7-day target sequences.
- Splits data by time into train, validation, and test sets.
- Trains the Keras model.
- Saves the model, scalers, metrics, and training-city metadata to
streamlit/model_v2/.
The live deployment runs FastAPI behind a reverse proxy:
https://botverio.com/weather/
The previous Streamlit implementation remains in the repository as a legacy interface, but the current deployed runtime is FastAPI.
This app intentionally demonstrates a custom trained ML model. It uses historical observations as input and predicts the next 7 days from learned patterns. Professional weather providers usually use physics-based numerical weather prediction systems with real-time atmospheric fields, so they can outperform a pure historical ML model.
The value of this project is the end-to-end ML engineering workflow: training, validation, feature design, model serving, inference diagnostics, and transparent model communication.
- Add direct comparison against persistence, climatology, and Open-Meteo forecast baselines.
- Add per-city backtesting dashboards.
- Add model drift monitoring and scheduled retraining.
- Add quantile forecasts or prediction intervals.
- Add a stronger precipitation-specific classifier/regressor head.
- Add CI checks for preprocessing compatibility and model artifact loading.
This project is licensed under the MIT License.
