Metadata-Version: 2.4
Name: twiga
Version: 0.1.2
Summary: Point and probabilistic time series forecasting — one interface, every model.
Project-URL: Homepage, https://github.com/sambaiga/twiga-forecast
Project-URL: Repository, https://github.com/sambaiga/twiga-forecast
Project-URL: Documentation, https://sambaiga.github.io/twiga-docs
Project-URL: Bug Tracker, https://github.com/sambaiga/twiga-forecast/issues
Project-URL: Changelog, https://github.com/sambaiga/twiga-forecast/blob/main/CHANGELOG.md
Author-email: sambaiga <sambaiga@gmail.com>, apina <fred.apina@gmail.com>
License: Apache-2.0
License-File: LICENSE
Keywords: forecasting,machine-learning,neural-networks,probabilistic,time-series
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Scientific/Engineering :: Mathematics
Classifier: Typing :: Typed
Requires-Python: >=3.12
Requires-Dist: antropy>=0.2.2
Requires-Dist: astral>=3.2
Requires-Dist: catboost>=1.2.10
Requires-Dist: great-tables>=0.21.0
Requires-Dist: hurst>=0.0.5
Requires-Dist: lets-plot>=4.9.0
Requires-Dist: lightgbm>=4.6.0
Requires-Dist: ngboost>=0.5.9
Requires-Dist: numpy>=2.4.4
Requires-Dist: optuna-integration>=4.8.0
Requires-Dist: optuna>=4.8.0
Requires-Dist: pandas>=2.3.3
Requires-Dist: pyarrow>=23.0.0
Requires-Dist: pydantic>=2.13.0
Requires-Dist: quantile-forest>=1.4.1
Requires-Dist: rich>=15.0.0
Requires-Dist: scikit-learn>=1.8.0
Requires-Dist: statsmodels>=0.14.6
Requires-Dist: tqdm>=4.67.3
Requires-Dist: xgboost>=3.2.0
Provides-Extra: all
Requires-Dist: anyio>=4.0.0; extra == 'all'
Requires-Dist: evidently>=0.7.21; extra == 'all'
Requires-Dist: fastapi>=0.136.1; extra == 'all'
Requires-Dist: lightning>=2.6.1; extra == 'all'
Requires-Dist: matplotlib-inline>=0.2.1; extra == 'all'
Requires-Dist: matplotlib>=3.10.8; extra == 'all'
Requires-Dist: mlflow>=3.11.1; extra == 'all'
Requires-Dist: optuna-dashboard>=0.20.0; extra == 'all'
Requires-Dist: plotly>=5.24.1; extra == 'all'
Requires-Dist: prefect>=3.6.28; extra == 'all'
Requires-Dist: pydantic-settings>=2.14.0; extra == 'all'
Requires-Dist: scienceplots>=2.2.1; extra == 'all'
Requires-Dist: shap>=0.46.0; extra == 'all'
Requires-Dist: tensorboard>=2.19.0; extra == 'all'
Requires-Dist: torch<2.11.0,>=2.10.0; extra == 'all'
Requires-Dist: torchmetrics>=1.9.0; extra == 'all'
Requires-Dist: uvicorn[standard]>=0.34.0; extra == 'all'
Provides-Extra: dev
Requires-Dist: aiohttp>=3.11.18; extra == 'dev'
Requires-Dist: commitizen>=4.3.0; extra == 'dev'
Requires-Dist: ipykernel>=7.2.0; extra == 'dev'
Requires-Dist: ipython>=9.13.0; extra == 'dev'
Requires-Dist: ipywidgets>=8.1.8; extra == 'dev'
Requires-Dist: myst-parser>=5.0.0; extra == 'dev'
Requires-Dist: nbdime>=4.0.4; extra == 'dev'
Requires-Dist: nbsphinx>=0.9.8; extra == 'dev'
Requires-Dist: nbstripout>=0.9.1; extra == 'dev'
Requires-Dist: notebook>=7.5.5; extra == 'dev'
Requires-Dist: numpydoc>=1.10.0; extra == 'dev'
Requires-Dist: pre-commit>=4.5.1; extra == 'dev'
Requires-Dist: pycln>=2.6.0; extra == 'dev'
Requires-Dist: pydata-sphinx-theme>=0.17.0; extra == 'dev'
Requires-Dist: pytest-cov>=7.1.0; extra == 'dev'
Requires-Dist: pytest-mpl>=0.19.0; extra == 'dev'
Requires-Dist: pytest-xdist>=3.8.0; extra == 'dev'
Requires-Dist: pytest>=9.0.3; extra == 'dev'
Requires-Dist: ruff>=0.14.14; extra == 'dev'
Requires-Dist: safety>=3.2.0; extra == 'dev'
Requires-Dist: sphinx-autobuild>=2025.8.25; extra == 'dev'
Requires-Dist: sphinx-autodoc-typehints>=3.10.1; extra == 'dev'
Requires-Dist: sphinx-copybutton>=0.5.2; extra == 'dev'
Requires-Dist: sphinx-design>=0.7.0; extra == 'dev'
Requires-Dist: sphinx-prompt>=1.10.2; extra == 'dev'
Requires-Dist: sphinx-tabs>=3.5.0; extra == 'dev'
Requires-Dist: sphinx-togglebutton>=0.4.5; extra == 'dev'
Requires-Dist: sphinx>=9.1.0; extra == 'dev'
Requires-Dist: sphinxcontrib-mermaid>=2.0.1; extra == 'dev'
Requires-Dist: ty>=0.0.28; extra == 'dev'
Provides-Extra: explain
Requires-Dist: shap>=0.46.0; extra == 'explain'
Provides-Extra: lightning
Requires-Dist: lightning>=2.6.1; extra == 'lightning'
Requires-Dist: tensorboard>=2.19.0; extra == 'lightning'
Requires-Dist: torch<2.11.0,>=2.10.0; extra == 'lightning'
Requires-Dist: torchmetrics>=1.9.0; extra == 'lightning'
Provides-Extra: mlops
Requires-Dist: anyio>=4.0.0; extra == 'mlops'
Requires-Dist: evidently>=0.7.21; extra == 'mlops'
Requires-Dist: fastapi>=0.136.1; extra == 'mlops'
Requires-Dist: mlflow>=3.11.1; extra == 'mlops'
Requires-Dist: prefect>=3.6.28; extra == 'mlops'
Requires-Dist: pydantic-settings>=2.14.0; extra == 'mlops'
Requires-Dist: uvicorn[standard]>=0.34.0; extra == 'mlops'
Provides-Extra: nn
Requires-Dist: lightning>=2.6.1; extra == 'nn'
Requires-Dist: tensorboard>=2.19.0; extra == 'nn'
Requires-Dist: torch<2.11.0,>=2.10.0; extra == 'nn'
Requires-Dist: torchmetrics>=1.9.0; extra == 'nn'
Provides-Extra: plots
Requires-Dist: matplotlib-inline>=0.2.1; extra == 'plots'
Requires-Dist: matplotlib>=3.10.8; extra == 'plots'
Requires-Dist: plotly>=5.24.1; extra == 'plots'
Requires-Dist: scienceplots>=2.2.1; extra == 'plots'
Provides-Extra: torch
Requires-Dist: lightning>=2.6.1; extra == 'torch'
Requires-Dist: tensorboard>=2.19.0; extra == 'torch'
Requires-Dist: torch<2.11.0,>=2.10.0; extra == 'torch'
Requires-Dist: torchmetrics>=1.9.0; extra == 'torch'
Provides-Extra: tracking
Requires-Dist: tensorboard>=2.19.0; extra == 'tracking'
Provides-Extra: tuning
Requires-Dist: optuna-dashboard>=0.20.0; extra == 'tuning'
Description-Content-Type: text/markdown

# Twiga Forecast

**Point & probabilistic time series forecasting — one interface, every model.**

*"Twiga" means giraffe in Swahili 🦒*

[![Python](https://img.shields.io/badge/python-3.12|3.13-3776ab?style=flat-square&logo=python&logoColor=white)](https://www.python.org/downloads/)
[![PyPI](https://img.shields.io/pypi/v/twiga?style=flat-square&color=0f718e)](https://pypi.org/project/twiga/)
[![License](https://img.shields.io/badge/license-Apache--2.0-green?style=flat-square)](LICENSE)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json&style=flat-square)](https://github.com/astral-sh/ruff)
[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json&style=flat-square)](https://github.com/astral-sh/uv)

[Documentation](https://sambaiga.github.io/twiga-docs) · [Tutorials](https://sambaiga.github.io/twiga-docs/tutorials/index.html) · [API Reference](https://sambaiga.github.io/twiga-docs/api/index.html) · [PyPI](https://pypi.org/project/twiga/)

---

Most forecasting libraries force a choice — ML **or** deep learning, point forecasts **or** probabilistic ones, flexibility **or** production readiness. **Twiga removes that trade-off.**

A single `TwigaForecaster` trains, tunes, evaluates and backtests gradient-boosted trees, neural networks, quantile regression, parametric distributions and conformal prediction through one consistent, config-driven API.

---

## Installation

```bash
# Core (tree models + lets-plot + great-tables)
pip install twiga

# + Matplotlib, Plotly, SciencePlots
pip install "twiga[plots]"

# + Neural networks (PyTorch Lightning)
pip install "twiga[nn]"

# Everything
pip install "twiga[all]"
```

> **Batteries included** — XGBoost, LightGBM, CatBoost, NGBoost, lets-plot and Great Tables ship with the base install.

| Extra | What it adds |
| --- | --- |
| `plots` | Matplotlib, Plotly, SciencePlots (publication-quality & interactive charts) |
| `nn` | PyTorch, Lightning, TorchMetrics, TensorBoard |
| `explain` | SHAP feature attribution |
| `mlops` | MLflow, FastAPI, Evidently, Prefect |
| `all` | Everything above |

---

## What Twiga offers

| Feature | Description |
| --- | --- |
| 🔀 **One interface, every model** | Swap a gradient-boosted tree for a neural network by changing one config object, not rewriting code |
| 📊 **Probabilistic forecasting** | Quantile regression, parametric distributions (Normal, Laplace, LogNormal, Gamma, Beta, Student-t) and conformal prediction, all composable with any backbone |
| 🎯 **Calibrated uncertainty** | Conformal prediction wraps any trained model with finite-sample coverage guarantees, no retraining required |
| ⚙️ **Experiment-ready** | Pydantic configs wired directly to Optuna search spaces; time-based backtesting and checkpoint-based resume are first-class features |
| 🔍 **Feature intelligence** | Eight association measures fused with Borda-count rank aggregation; stationarity tests, entropy and residual diagnostics in one call |
| 🚀 **Production MLOps** | Optional stack with experiment tracking, versioned checkpoints, drift monitoring, REST API and automated retraining |

---

## Quick start

```python
import pandas as pd
from twiga.forecaster.core import TwigaForecaster
from twiga.core.config import DataPipelineConfig, ForecasterConfig
from twiga.models.ml.lightgbm_model import LIGHTGBMConfig

# train_df / test_df are pandas DataFrames with a DatetimeIndex
forecaster = TwigaForecaster(
    data_params=DataPipelineConfig(target_feature="load_mw", forecast_horizon=48),
    model_params=[LIGHTGBMConfig()],
    train_params=ForecasterConfig(split_freq="days", train_size=14, test_size=7),
)
forecaster.fit(train_df=train_df)
predictions_df, metrics_df = forecaster.evaluate_point_forecast(test_df=test_df)
```

Switch to a neural network by swapping one config:

```python
from twiga.models.nn.mlpgam_model import MLPGAMConfig

forecaster = TwigaForecaster(
    data_params=DataPipelineConfig(target_feature="load_mw", forecast_horizon=48),
    model_params=[MLPGAMConfig()],
    train_params=ForecasterConfig(split_freq="days", train_size=14, test_size=7),
)
```

See the [tutorials](https://sambaiga.github.io/twiga-docs/tutorials/index.html) for probabilistic forecasting, conformal prediction, backtesting, HPO, and MLOps examples.

---

## Documentation

| Section | Description |
| --- | --- |
| [Get Started](https://sambaiga.github.io/twiga-docs/getting-started/index.html) | Install, key concepts, and your first forecast |
| [User Guide](https://sambaiga.github.io/twiga-docs/core/index.html) | Forecaster API, data pipeline, metrics, backtesting |
| [Models](https://sambaiga.github.io/twiga-docs/models/index.html) | ML tree models, neural networks, HPO |
| [Probabilistic](https://sambaiga.github.io/twiga-docs/probabilistic/index.html) | Distributions, quantile regression, conformal prediction |
| [Tutorials](https://sambaiga.github.io/twiga-docs/tutorials/index.html) | End-to-end Jupyter notebooks |
| [MLOps](https://sambaiga.github.io/twiga-docs/mlops/index.html) | Tracking, serving, monitoring, orchestration |
| [API Reference](https://sambaiga.github.io/twiga-docs/api/index.html) | Full API reference |

---

## Contributing

Bug reports and feature requests are welcome — please [open an issue](https://github.com/sambaiga/twiga-forecast/issues). Pull requests should target the `main` branch and pass the pre-commit checks (`uv run pre-commit run --all-files`).

---

## Contributors

Thanks goes to these wonderful people:

<table>
  <tbody>
    <tr>
      <td align="center" valign="top" width="14.28%">
        <a href="https://github.com/sambaiga">
          <img src="https://avatars.githubusercontent.com/u/338440?v=4" width="100px;" alt="Anthony Faustine"/><br/>
          <sub><b>Anthony Faustine</b></sub>
        </a>
      </td>
      <td align="center" valign="top" width="14.28%">
        <a href="https://github.com/fred-apina">
          <img src="https://avatars.githubusercontent.com/u/39369908?v=4" width="100px;" alt="Frederick Apina"/><br/>
          <sub><b>Frederick Apina</b></sub>
        </a>
      </td>
      <td align="center" valign="top" width="14.28%">
        <a href="https://github.com/alspereira">
          <img src="https://avatars.githubusercontent.com/u/7491890?v=4" width="100px;" alt="Lucas Pereira"/><br/>
          <sub><b>Lucas Pereira</b></sub>
        </a>
      </td>
    </tr>
  </tbody>
</table>

---

## References

1. A. Faustine, N. J. Nunes and L. Pereira, "Efficiency through Simplicity: MLP-based Approach for Net-Load Forecasting with Uncertainty Estimates," *IEEE Transactions on Power Systems*, doi: [10.1109/TPWRS.2024.3400123](https://ieeexplore.ieee.org/document/10529636).
2. A. Faustine and L. Pereira, "FPSeq2Q: Fully Parameterized Sequence to Quantile Regression for Net-Load Forecasting With Uncertainty Estimates," *IEEE Transactions on Smart Grid*, vol. 13, no. 3, pp. 2440-2451, May 2022, doi: [10.1109/TSG.2022.3148699](https://ieeexplore.ieee.org/document/9701598).
3. A. Faustine and L. Pereira, "Conformal Multilayer Perceptron-Based Probabilistic Net-Load Forecasting for Low-Voltage Distribution Systems with Photovoltaic Generation," *2024 IEEE International Conference on Communications, Control, and Computing Technologies for Smart Grids (SmartGridComm)*, Oslo, Norway, 2024, pp. 59-64, doi: [10.1109/SmartGridComm60555.2024.10738106](https://ieeexplore.ieee.org/document/10738106).
4. A. Faustine and L. Pereira, "Enhancing LV System Resilience through Probabilistic Forecasting of Interdependent Variables: Voltage, Reactive and Active Power," *CIRED Chicago Workshop 2024: Resilience of Electric Distribution Systems*, Chicago, USA, 2025, pp. 27-31, doi: [10.1049/icp.2024.2555](https://doi.org/10.1049/icp.2024.2555).

---

Apache 2.0 License · Built with ❤️ for energy & power systems forecasting
