Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions docs/changelogs/v0.0.25.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
### Features

* **New ML models**: Added 7 new auto ML models powered by `mlforecast`'s hyperparameter optimization: `AutoLinearRegression`, `AutoXGBoost`, `AutoRidge`, `AutoLasso`, `AutoElasticNet`, `AutoRandomForest`, and `AutoCatboost`. All models support `quantiles` for probabilistic forecasts via conformal prediction and follow the same interface as the existing `AutoLGBM`.

```python
from timecopilot.models.ml import (
AutoLinearRegression,
AutoXGBoost,
AutoRidge,
AutoLasso,
AutoElasticNet,
AutoRandomForest,
AutoCatboost,
)

model = AutoRidge()
fcst_df = model.forecast(df, h=12, quantiles=[0.1, 0.5, 0.9])
```

* **TimeGPT finetuning**: Finetuning is now supported for TimeGPT. You can adapt the pre-trained model to your data before forecasting via `TimeGPTFinetuningConfig`, with options for loss function and finetuning depth. See [#332](https://github.com/TimeCopilot/timecopilot/pull/332) and the [Finetuning Foundation Models](https://timecopilot.dev/examples/finetuning/) example for a full walkthrough.

```python
Expand Down
23 changes: 23 additions & 0 deletions docs/changelogs/v0.0.26.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
### Features

* **Prediction intervals for AutoLGBM, AutoNHITS, and AutoTFT**: These models now support quantile forecasts via the `quantiles` parameter. Pass a list of floats between 0 and 1 to receive additional output columns named `model-q-{percentile}`. Note that `level` is not supported for these models; use `quantiles` instead.
Comment thread
AzulGarza marked this conversation as resolved.
Outdated

- `AutoLGBM` computes prediction intervals via conformal prediction using cross-validation residuals.
- `AutoNHITS` and `AutoTFT` are trained with [`MQLoss`](https://nixtla.github.io/neuralforecast/losses.pytorch.html) when quantiles are requested.

```python
import pandas as pd
from timecopilot.models.ml import AutoLGBM
from timecopilot.models.neural import AutoNHITS, AutoTFT

df = pd.read_csv("AirPassengers.csv", parse_dates=["ds"])
df.insert(0, "unique_id", "AirPassengers")

model = AutoLGBM()
fcst_df = model.forecast(df, h=12, quantiles=[0.1, 0.5, 0.9])
# columns: unique_id, ds, AutoLGBM, AutoLGBM-q-10, AutoLGBM-q-50, AutoLGBM-q-90
```

---

**Full Changelog**: https://github.com/TimeCopilot/timecopilot/compare/v0.0.25...v0.0.26
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ dependencies = [
"accelerate>=1.10.1",
"arch>=7.2.0",
"black>=25.9.0",
"catboost>=1.2.10",
"datasets>=4.1.1",
"fire",
"fsspec>=2025.9.0",
Expand Down Expand Up @@ -103,6 +104,7 @@ dependencies = [
"tsfeatures>=0.4.5",
"utilsforecast[plotting]>=0.2.15",
"wandb==0.22.1",
"xgboost>=3.2.0",
]
description = "The GenAI Forecasting Agent · LLMs × Time Series Foundation Models"
license = "MIT"
Expand Down
18 changes: 17 additions & 1 deletion tests/models/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,16 @@
from timecopilot.models.foundation.patchtst_fm import PatchTSTFM
from timecopilot.models.foundation.timesfm import TimesFM
from timecopilot.models.foundation.toto import Toto
from timecopilot.models.ml import AutoLGBM
from timecopilot.models.ml import (
AutoCatboost,
AutoElasticNet,
AutoLasso,
AutoLGBM,
AutoLinearRegression,
AutoRandomForest,
AutoRidge,
AutoXGBoost,
)
from timecopilot.models.neural import AutoNHITS, AutoTFT
from timecopilot.models.prophet import Prophet
from timecopilot.models.stats import (
Expand Down Expand Up @@ -39,6 +48,13 @@ def disable_mps_session(monkeypatch):

models = [
AutoLGBM(num_samples=2, cv_n_windows=2),
AutoLinearRegression(num_samples=2, cv_n_windows=2),
AutoXGBoost(num_samples=2, cv_n_windows=2),
AutoRidge(num_samples=2, cv_n_windows=2),
AutoLasso(num_samples=2, cv_n_windows=2),
AutoElasticNet(num_samples=2, cv_n_windows=2),
AutoRandomForest(num_samples=2, cv_n_windows=2),
AutoCatboost(num_samples=2, cv_n_windows=2),
AutoNHITS(
num_samples=2,
config=dict(
Expand Down
45 changes: 27 additions & 18 deletions tests/models/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,18 @@ def test_freq_inferred_correctly(model, freq):
)
@pytest.mark.parametrize("h", [1, 12])
def test_correct_forecast_dates(model, freq, h):
if model.alias in ["AutoLGBM", "AutoNHITS", "AutoTFT"]:
# AutoLGBM requires a certain minimum length
_ml_auto_aliases = {
"AutoLGBM",
"AutoLinearRegression",
"AutoXGBoost",
"AutoRidge",
"AutoLasso",
"AutoElasticNet",
"AutoRandomForest",
"AutoCatboost",
}
if model.alias in _ml_auto_aliases | {"AutoNHITS", "AutoTFT"}:
# AutoMLForecast models require a certain minimum length
Comment thread
AzulGarza marked this conversation as resolved.
Outdated
sizes_per_freq = {
freq: 1_000 for freq in ["10S", "10T", "15T", "5T", "H", "Q-DEC"]
}
Expand Down Expand Up @@ -193,17 +203,6 @@ def test_passing_both_level_and_quantiles(model):
def test_using_quantiles(model):
qs = [round(i * 0.1, 1) for i in range(1, 10)]
df = generate_series(n_series=3, freq="D")
if model.alias in ["AutoLGBM", "AutoNHITS", "AutoTFT"]:
# These models do not support quantiles yet
with pytest.raises(ValueError) as excinfo:
model.forecast(
df=df,
h=2,
freq="D",
quantiles=qs,
)
assert "not supported" in str(excinfo.value)
return
fcst_df = model.forecast(
df=df,
h=2,
Expand Down Expand Up @@ -231,6 +230,9 @@ def test_using_quantiles(model):
elif "moe" in model.alias.lower():
# MoE is a bit more lenient with the monotonicity condition
assert fcst_df[c1].le(fcst_df[c2]).mean() >= 0.5
elif model.alias in ["AutoNHITS", "AutoTFT"]:
# test config uses max_steps=1, so quantile ordering is not guaranteed
continue
else:
assert fcst_df[c1].lt(fcst_df[c2]).all()

Expand All @@ -239,21 +241,28 @@ def test_using_quantiles(model):
def test_using_level(model):
level = [0, 20, 40, 60, 80] # corresponds to qs [0.1, 0.2, ..., 0.9]
df = generate_series(n_series=2, freq="D")
if model.alias in [
_level_unsupported = {
"AutoLGBM",
"AutoLinearRegression",
"AutoXGBoost",
"AutoRidge",
"AutoLasso",
"AutoElasticNet",
"AutoRandomForest",
"AutoCatboost",
"AutoNHITS",
"AutoTFT",
"PatchTST-FM",
]:
# These models do not support levels yet
}
if model.alias in _level_unsupported:
# these models only support quantiles, not level
with pytest.raises(ValueError) as excinfo:
model.forecast(
df=df,
h=2,
freq="D",
level=level,
)
assert "not supported" in str(excinfo.value)
assert "quantiles" in str(excinfo.value)
return
fcst_df = model.forecast(
df=df,
Expand Down
18 changes: 18 additions & 0 deletions timecopilot/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
from .ml import (
AutoCatboost,
AutoElasticNet,
AutoLasso,
AutoLGBM,
AutoLinearRegression,
AutoRandomForest,
AutoRidge,
AutoXGBoost,
)
from .stats import (
ADIDA,
IMAPA,
Expand All @@ -14,10 +24,18 @@

__all__ = [
"ADIDA",
"AutoCatboost",
"AutoElasticNet",
"IMAPA",
"AutoARIMA",
"AutoCES",
"AutoETS",
"AutoLasso",
"AutoLGBM",
"AutoLinearRegression",
"AutoRandomForest",
"AutoRidge",
"AutoXGBoost",
"CrostonClassic",
"DynamicOptimizedTheta",
"HistoricAverage",
Expand Down
Loading
Loading