Hybrid time series forecasting library combining Prophet with gradient boosting models
Project description
HybridTS
Hybrid Time Series Forecasting for Python
Combines Prophet's trend and seasonality detection with gradient boosting (XGBoost / LightGBM) to correct residuals — delivering more accurate forecasts than either model alone.
How It Works
- Prophet fits trend, seasonality, and holiday effects
- XGBoost / LightGBM learns from the residuals using engineered features
- Final forecast = Prophet baseline + ML residual correction
Installation
pip install hybridts
Quick Start
from hybridts import HybridForecaster, ProphetModel, XGBoostTuner
import pandas as pd
prophet = ProphetModel()
xgb = XGBoostTuner()
forecaster = HybridForecaster(primary_model=prophet, secondary_model=xgb)
df = pd.read_csv("data.csv", parse_dates=["ds"]) # columns: ds, y
forecaster.fit(df)
forecast = forecaster.predict(horizon=30)
print(forecast)
Data Format
A pandas DataFrame with exactly two columns:
| Column | Type | Description |
|---|---|---|
ds |
datetime | Date of observation |
y |
float | Value to forecast |
Core API
HybridForecaster
HybridForecaster(
primary_model, # ProphetModel instance
secondary_model, # XGBoostTuner or LightGBMTuner instance
test_size=30, # holdout size for validate()
paydays_set=None, # set of payday Timestamps (auto-generated if None)
holidays_country="BR", # country code for auto-generated holidays
holidays_state=None, # state/subdivision code
)
fit(df, holidays=<auto>, features=<auto>)
Trains both models. By default, holidays and features are auto-generated from the data.
forecaster.fit(df) # auto holidays + auto features
forecaster.fit(df, holidays=None) # no holidays passed to Prophet
forecaster.fit(df, holidays=my_holidays) # custom holidays DataFrame
forecaster.fit(df, features=None) # secondary model trains without exogenous features
predict(horizon, features=<auto>)
Returns a DataFrame with horizon rows:
| Column | Description |
|---|---|
data |
Forecast date |
forecast_primary_base |
Prophet baseline |
residual_correction |
ML adjustment |
forecast_final |
Final hybrid forecast |
validate(df, test_size=None)
Evaluates on a holdout set without data leakage. Returns (metrics, y_true, y_pred).
metrics, y_true, y_pred = forecaster.validate(df)
# metrics: {"mape", "rmse", "mae", "mdape"}
validate_and_fit(df, test_size=None)
Validates on holdout, then retrains on the full dataset.
forecaster, metrics = forecaster.validate_and_fit(df)
Models
ProphetModel
Wraps Prophet with automated hyperparameter tuning via cross-validation.
ProphetModel(
param_grid={"changepoint_prior_scale": [0.05, 0.1], ...}, # grid search params
cv_params={"initial": "300 days", "period": "30 days", "horizon": "30 days"},
yearly_seasonality=True,
weekly_seasonality=True,
daily_seasonality=False,
static_params={...}, # used by fit_static() — skips CV
)
| Method | Description |
|---|---|
fit(df, holidays) |
Tunes hyperparameters via CV, then fits on full data |
fit_static(df, holidays) |
Fits with static_params, no CV |
predict(df) |
Returns Prophet forecast DataFrame |
XGBoostTuner
Wraps XGBoost via sktime's make_reduction with grid search and expanding window CV.
XGBoostTuner(
test_size=30,
param_grid={"window_length": [21], "estimator__max_depth": [5, 7], ...},
static_params={"n_estimators": 200, "max_depth": 5, ...},
cv_initial_window=270,
cv_step_length=30,
window_length=21,
fh=30,
strategy="recursive",
regressor_params={"random_state": 42},
)
LightGBMTuner
Same interface as XGBoostTuner, using LightGBM as the estimator.
LightGBMTuner(
lgbm_regressor_params={"strategy": "recursive", "n_estimators": 200, ...},
test_size=30,
initial_window=270,
step_length=30,
window_length=21,
param_grid={"window_length": [21, 28], ...},
)
Both models expose fit(), fit_static(), and predict().
Feature Engineering
from hybridts import create_features, get_brazilian_paydays, create_holidays_prophet
# Generate Brazilian payday dates
paydays = get_brazilian_paydays(start_year=2022, end_year=2025)
# Create exogenous features
features = create_features(
df_dates=df[["ds"]],
paydays_set=paydays, # optional — all payday features zeroed if None
min_year=2022,
max_year=2025,
holidays_country="BR",
holidays_state="SP",
)
Generated features:
| Feature | Description |
|---|---|
is_weekend |
1 if Saturday or Sunday |
is_month_start |
1 if day <= 9 |
is_month_end |
1 if last day of month |
day_of_week |
0 (Mon) to 6 (Sun) |
day_of_month |
1-31 |
is_payday |
1 if date is a payday |
is_adiantamento |
1 if salary advance day |
sextou_com_dinheiro |
1 if Friday and payday |
dias_desde_pagamento |
Days since last payday |
is_holiday |
1 if public holiday |
is_holiday_eve |
1 if day before holiday |
is_post_holiday |
1 if day after holiday |
Logging
HybridTS uses loguru with logging disabled by default (library-safe). To enable:
from loguru import logger
logger.enable("hybridts")
Project Structure
hybridts/
├── __init__.py # public API
└── src/
├── features/
│ ├── data_processor.py # TimeSeriesProcessor
│ ├── engineering.py # create_features
│ └── holidays.py # create_holidays_prophet, get_brazilian_paydays
├── models/
│ ├── primary/
│ │ └── prophet.py # ProphetModel
│ └── secondary/
│ ├── xgboost.py # XGBoostTuner
│ └── lightgbm.py # LightGBMTuner
├── pipeline/
│ └── pipeline.py # HybridForecaster
└── exception/
├── model_exception.py # ModelTrainingException, ModelPredictionException
└── dataframe_exception.py
License
MIT — see LICENSE
Davi Franco — GitHub
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hybridts-0.2.0.tar.gz.
File metadata
- Download URL: hybridts-0.2.0.tar.gz
- Upload date:
- Size: 41.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd878aabb0e1b9e123837c3eee6be137635e6f7010f92ae4b890d953d0152d27
|
|
| MD5 |
a10730e3a8be234241b62700e89ce9da
|
|
| BLAKE2b-256 |
6311eef6c151210b87c7e192d16a87ea794b5cd810db5a7dd92f362288c93fc8
|
File details
Details for the file hybridts-0.2.0-py3-none-any.whl.
File metadata
- Download URL: hybridts-0.2.0-py3-none-any.whl
- Upload date:
- Size: 21.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9143a7ff4ccc253be7dade71c12d4e29df3ac751068fefc667bf7bd470040b29
|
|
| MD5 |
9a77b52f8b6a08a87e87667034da859e
|
|
| BLAKE2b-256 |
5dac399f5668b69bda34930bfd50ec971a7fcdda0af7c797993b13d2ab8ebe35
|