Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
883f296
Add conformal prediction intervals support for Hyper-Tree models
StatMixedML Jun 3, 2026
16acbc1
Exclude macOS + Python 3.14 from CI (numpy upstream incompatibility)
StatMixedML Jun 3, 2026
772ab3e
Pin macOS CI runner to macos-13 (macos-latest numpy incompatibility)
StatMixedML Jun 3, 2026
faf46be
Update CI configuration to use macos-latest and adjust torch installa…
StatMixedML Jun 3, 2026
437e9b5
Fix CI torch install: install project first, swap to CPU torch with -…
StatMixedML Jun 3, 2026
684602e
Fix CI: uninstall PyPI torch before installing CPU-only build
StatMixedML Jun 3, 2026
c35f572
Fix CI: install CPU torch via --index-url before project to avoid CUD…
StatMixedML Jun 3, 2026
4a90f68
Fix CI: swap torch install order to avoid numpy ABI collision
StatMixedML Jun 3, 2026
1ccc880
Fix: Revert the CI workflow
StatMixedML Jun 3, 2026
237410b
Fix refit=False conformal calibration by re-anchoring forecast seed p…
StatMixedML Jun 3, 2026
a552542
Update to reflect code changes
StatMixedML Jun 3, 2026
695dcc7
Update to reflect code changes
StatMixedML Jun 3, 2026
321c906
Fix CI: stop --cov from double-importing numpy (fatal on numpy ≥2.4)
StatMixedML Jun 3, 2026
75ca441
Fix Run coverage in dedicated job with pytrace tracer to restore Code…
StatMixedML Jun 3, 2026
2deef5e
Refactor coverage configuration and enhance tests for _align_scores a…
StatMixedML Jun 3, 2026
f0682a8
Update claude configuration to use new model and increase max turns
StatMixedML Jun 3, 2026
38aabd9
Add NOTICE file for third-party attributions and update README with N…
StatMixedML Jun 3, 2026
412ab1f
Rename NOTICE to THIRD_PARTY_NOTICES and update README with new link …
StatMixedML Jun 3, 2026
bf646c8
Update README to reference THIRD_PARTY_NOTICES instead of NOTICE for …
StatMixedML Jun 3, 2026
b2924a0
Refactor README to enhance layout and improve visibility of project i…
StatMixedML Jun 8, 2026
d8bc8f0
Update README to drop 'value' column from test dataset preparation
StatMixedML Jun 8, 2026
8c186ed
Fix training-state bugs; add analytic AR Hessian and ETS init options
StatMixedML Jun 10, 2026
a0ab407
Add VAR and TSB models
StatMixedML Jun 11, 2026
352ec75
Add VAR and TSB models
StatMixedML Jun 11, 2026
cf78e5f
Add VAR and TSB models
StatMixedML Jun 11, 2026
a1947a9
Add ARMA models and additional fixes and improvements
StatMixedML Jun 12, 2026
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
9 changes: 7 additions & 2 deletions .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ jobs:
- New or changed logic that lacks corresponding test coverage

Do NOT flag minor style or formatting issues that a linter or formatter would catch.

Ignore Jupyter notebooks entirely: do NOT read, review, or comment on any
`*.ipynb` files. When inspecting the diff, exclude them, e.g.
`gh pr diff ${{ github.event.pull_request.number }} -- ':!*.ipynb'`.

If no substantive issues are found, post a short approval comment.

The PR branch is already checked out.
Expand All @@ -45,6 +50,6 @@ jobs:
Only post GitHub comments, do not submit review text as messages.

claude_args: |
--model claude-sonnet-4-6
--max-turns 10
--model claude-opus-4-6
--max-turns 20
--allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)"
6 changes: 3 additions & 3 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ jobs:
actions: read

claude_args: |
--model claude-sonnet-4-6
--max-turns 10
--allowedTools "Edit,Read,Write,Bash(uv run pytest:*),Bash(uv run ruff check:*),Bash(gh:*),Bash(git:*)"
--model claude-opus-4-6
--max-turns 20
--allowedTools "Edit,Read,Write,Bash(python -m pip install:*),Bash(pytest:*),Bash(flake8:*),Bash(gh:*),Bash(git:*)"
16 changes: 11 additions & 5 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,23 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
# Install project with test extras (pytest, pytest-cov, etc.)
python -m pip install -e ".[test]"
# Force CPU-only torch to avoid pulling CUDA wheels in CI
python -m pip install --force-reinstall --no-deps torch --extra-index-url https://download.pytorch.org/whl/cpu

- name: Run tests with coverage
- name: Run tests
run: |
pytest tests/ -vv --tb=long --cov-report=xml
pytest tests/ -vv --tb=long

- name: Generate coverage for Codecov
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11'
continue-on-error: true
env:
COVERAGE_CORE: pytrace
run: |
pytest tests/ --cov=hypertrees --cov-report=xml

- name: Upload coverage reports to Codecov
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11'
uses: codecov/codecov-action@v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
83 changes: 66 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,51 @@
<h4 align="center">

| | **[Release Notes](https://github.com/StatMixedML/Hyper-Trees/releases)** |
|----------------------|---|
| **Open&#160;Source** | [![License: Apache 2.0 + Commons Clause](https://img.shields.io/badge/License-Apache_2.0_with_Commons_Clause-yellow.svg)](LICENSE) |
| **CI/CD** | [![github-actions](https://img.shields.io/github/actions/workflow/status/StatMixedML/Hyper-Trees/unit-tests.yml?logo=github)](https://github.com/StatMixedML/Hyper-Trees/actions/workflows/unit-tests.yml) <img src="https://codecov.io/gh/StatMixedML/Hyper-Trees/branch/main/graph/badge.svg" alt="Code coverage status badge"> |
| **Package** | [![!pypi](https://img.shields.io/pypi/v/hypertrees-forecasting?color=orange)](https://pypi.org/project/hypertrees-forecasting/) [![!python-versions](https://img.shields.io/pypi/pyversions/hypertrees-forecasting)](https://www.python.org/) |
| **Downloads** | ![Pepy Total Downloads](https://img.shields.io/pepy/dt/hypertrees-forecasting?label=PyPI%20Downloads&color=green) |
| **Paper** | [![Arxiv link](https://img.shields.io/badge/arXiv-Forecasting%20with%20Hyper--Trees-color=brightgreen)](https://arxiv.org/pdf/2405.07836) |

</h4>
<table align="center" width="100%" style="border: none; border-collapse: collapse;">
<tr>
<td align="center" valign="middle" style="border: none;">
<h1>Hyper-Trees</h1>
<p><strong>GBDTs as Hyper-Models for Classical Forecasting Models</strong></p>
<table align="center" style="border: none; border-collapse: collapse;">
<tr style="border: none;">
<td align="left" style="border: none;"><strong>Open&nbsp;Source</strong></td>
<td align="center" style="border: none;">
<a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache_2.0_with_Commons_Clause-yellow?logo=opensourceinitiative&logoColor=white" alt="License: Apache 2.0 with Commons Clause"/></a>
</td>
</tr>
<tr style="border: none;">
<td align="left" style="border: none;"><strong>CI/CD</strong></td>
<td align="center" style="border: none;">
<a href="https://github.com/StatMixedML/Hyper-Trees/actions/workflows/unit-tests.yml"><img src="https://img.shields.io/github/actions/workflow/status/StatMixedML/Hyper-Trees/unit-tests.yml?logo=github&logoColor=white&label=Build" alt="Unit Tests"/></a>
<a href="https://codecov.io/gh/StatMixedML/Hyper-Trees"><img src="https://img.shields.io/codecov/c/github/StatMixedML/Hyper-Trees?logo=codecov&logoColor=white&label=Coverage" alt="Code Coverage"/></a>
</td>
</tr>
<tr style="border: none;">
<td align="left" style="border: none;"><strong>Package</strong></td>
<td align="center" style="border: none;">
<a href="https://pypi.org/project/hypertrees-forecasting/"><img src="https://img.shields.io/pypi/v/hypertrees-forecasting?color=orange&logo=pypi&logoColor=white&label=PyPI" alt="PyPI Version"/></a>
<a href="https://www.python.org/"><img src="https://img.shields.io/pypi/pyversions/hypertrees-forecasting?logo=python&logoColor=white&label=Python" alt="Python Versions"/></a>
</td>
</tr>
<tr style="border: none;">
<td align="left" style="border: none;"><strong>Downloads</strong></td>
<td align="center" style="border: none;">
<a href="https://pepy.tech/project/hypertrees-forecasting"><img src="https://img.shields.io/pepy/dt/hypertrees-forecasting?label=PyPI%20Downloads&color=green&logo=pypi&logoColor=white" alt="PyPI Downloads"/></a>
</td>
</tr>
<tr style="border: none;">
<td align="left" style="border: none;"><strong>Paper</strong></td>
<td align="center" style="border: none;">
<a href="https://arxiv.org/abs/2405.07836"><img src="https://img.shields.io/badge/arXiv-2405.07836-b31b1b?logo=arxiv&logoColor=white&label=Paper" alt="arXiv"/></a>
</td>
</tr>
<tr style="border: none;">
<td align="left" style="border: none;"><strong>Release</strong></td>
<td align="center" style="border: none;">
<a href="https://github.com/StatMixedML/Hyper-Trees/releases"><img src="https://img.shields.io/github/v/release/StatMixedML/Hyper-Trees?logo=github&logoColor=white&label=Release%20Notes" alt="Release Notes"/></a>
</td>
</tr>
</table>
</td>
</tr>
</table>


---
Expand All @@ -34,6 +71,7 @@ Hyper-Trees offer several advantages:
---

# News
[2026-06-03] v0.2.0 adds support for forecast intervals via conformal prediction.<br>
[2026-06-01] v0.1.0 released on [PyPI](https://pypi.org/project/hypertrees-forecasting/).<br>
[2024-05-01] Create repository and initial commits.

Expand All @@ -45,11 +83,16 @@ Hyper-Trees offer several advantages:
| :--- | :--- | :---: |
| **`Hyper-Tree-AR`** | Autoregressive model with tree-learned, time-varying AR(p) parameters. | ![](https://img.shields.io/badge/Global-blue) ![](https://img.shields.io/badge/Local-green) |
| **`Hyper-TreeNet-AR`** | Hybrid model combining tree embeddings with a neural network to learn AR(p) parameters. | ![](https://img.shields.io/badge/Global-blue) ![](https://img.shields.io/badge/Local-green) |
| **`Hyper-Tree-ARMA`** | Autoregressive moving-average model with tree-learned, time-varying AR(p) and MA(q) parameters, fitted recursion-free via the two-stage Hannan-Rissanen procedure. | ![](https://img.shields.io/badge/Global-blue) ![](https://img.shields.io/badge/Local-green) |
| **`Hyper-TreeNet-ARMA`** | Hybrid model combining tree embeddings with a neural network to learn the ARMA(p, q) parameters. | ![](https://img.shields.io/badge/Global-blue) ![](https://img.shields.io/badge/Local-green) |
| **`Hyper-Tree-ETS`** | Exponential smoothing model where ETS parameters are estimated by trees. | ![](https://img.shields.io/badge/Global-blue) ![](https://img.shields.io/badge/Local-green) |
| **`Hyper-Tree-STL`** | STL decomposition with tree-learned parameters for trend and seasonality. | ![](https://img.shields.io/badge/Local-green) |
| **`Hyper-Tree-VAR`** | Vector autoregression with tree-learned, time-varying VAR(p) coefficient matrices, capturing cross-series lead/lag dependence. Intended for small aligned panels. | ![](https://img.shields.io/badge/Global-blue) |
| **`Hyper-TreeNet-VAR`** | Hybrid model combining tree embeddings with a neural network to learn the VAR(p) coefficient matrices; recommended VAR variant, since its runtime is independent of the number of coefficients. | ![](https://img.shields.io/badge/Global-blue) |
| **`Hyper-Tree-TSB`** | Intermittent demand model (Teunter-Syntetos-Babai) with tree-learned, time-varying smoothing rates for demand probability and demand size. | ![](https://img.shields.io/badge/Global-blue) ![](https://img.shields.io/badge/Local-green) |

`Global` means a single model is trained across multiple time series; `Local` means a separate model is trained for each individual series.
All models currently provide point forecasts only. Probabilistic forecasting is planned for future releases. Note on `Hyper-Tree-STL`: it is designed to decompose time series into trend and seasonal components and is not intended for forecasting. However, the STL-parameters can still be used to generate forecasts.
All models produce point forecasts and support conformal prediction intervals via `ForecastIntervals` (see [Getting Started](#getting-started)). Full distributional (probabilistic) forecasting is planned for future releases. Note on `Hyper-Tree-STL`: it is designed to decompose time series into trend and seasonal components and is not intended for forecasting. However, the STL-parameters can still be used to generate forecasts.

---

Expand All @@ -59,6 +102,7 @@ The example below trains a `Hyper-Tree-AR` model on the classic AirPassengers se

```python
from hypertrees.models import HyperTreeAR
from hypertrees import ForecastIntervals
from examples.utils import (load_air_passengers, plot_example_forecast)

# Load data and add 'month' as a feature
Expand All @@ -67,13 +111,18 @@ dta["month"] = dta["date"].dt.month

# Split the data into training and testing sets, reserving the last 12 months for testing
fcst_h = 12
test = dta.tail(fcst_h)
test = dta.tail(fcst_h).drop(columns="value")
train = dta.drop(test.index)

# Initialize an AR-12 model for monthly data, train, and forecast
# Initialize an AR-12 model for monthly data, calibrate conformal intervals, and forecast
ci_levels = [80, 90]
ht_model = HyperTreeAR(p=12, freq="M", fcst_h=fcst_h)
ht_model.train(lgb_params={"learning_rate": 0.1}, num_iterations=100, train_data=train)
forecasts = ht_model.forecast(test_data=test)
ht_model.train(
lgb_params={"learning_rate": 0.1},
train_data=train,
forecast_intervals=ForecastIntervals(n_windows=5), # calibrate intervals
)
forecasts = ht_model.forecast(test_data=test, level=ci_levels)

# Plot actuals vs. forecast
plot_example_forecast(dta, forecasts)
Expand Down Expand Up @@ -157,7 +206,7 @@ This work draws on and integrates methods and implementations from the following

- [**<u>LightGBM</u>**](https://github.com/microsoft/LightGBM) – Gradient boosting framework for efficient tree-based learning.
- [**<u>PyTorch</u>**](https://github.com/pytorch/pytorch) – Deep learning framework for tensor computation and neural network modeling.
- [**<u>Nixtla</u>**](https://github.com/Nixtla) – Open Source Time Series Ecosystem.
- [**<u>Nixtla</u>**](https://github.com/Nixtla) – Open Source Time Series Ecosystem. The conformal prediction intervals in `hypertrees/conformal.py` are adapted from Nixtla's [statsforecast](https://github.com/Nixtla/statsforecast), [mlforecast](https://github.com/Nixtla/mlforecast), and [neuralforecast](https://github.com/Nixtla/neuralforecast) (Apache-2.0); see [`THIRD_PARTY_NOTICES`](THIRD_PARTY_NOTICES).
- [**<u>sktime</u>**](https://github.com/sktime/sktime) – A unified framework for machine learning with time series.
- [**<u>GluonTS</u>**](https://github.com/awslabs/gluonts) – Probabilistic time series modeling and forecasting with deep learning.

Expand Down
43 changes: 43 additions & 0 deletions THIRD_PARTY_NOTICES
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
Hyper-Trees
Copyright 2026 Alexander März

Licensed under the Apache License, Version 2.0, with the Commons Clause License
Condition v1.0. See the LICENSE file for the full terms.

------------------------------------------------------------------------------
Third-party attributions
------------------------------------------------------------------------------

This product includes software adapted from the Nixtla open-source forecasting
libraries, each licensed under the Apache License, Version 2.0:

- statsforecast https://github.com/Nixtla/statsforecast
- mlforecast https://github.com/Nixtla/mlforecast
- neuralforecast https://github.com/Nixtla/neuralforecast

The following components are adapted from these libraries and have been
modified from the originals:

- Conformal prediction intervals (hypertrees/conformal.py): the
rolling-origin calibration, the two interval-construction methods
("conformal_distribution" and "conformal_error"), the per-horizon-step
quantile logic, and the "<model>-lo-<level>" / "<model>-hi-<level>"
output column naming convention follow Nixtla's design.

- Exponential smoothing state initialization
(hypertrees/models/HyperTreeETS.py): the classical and additive
seasonal/level/trend initialization (centered 2 x m moving-average
detrending, per-slot seasonal indices, the OLS level/trend seed, and the
initial-seasonal clipping) follows the statsforecast / R forecast::ets
heuristic.

- TSB intermittent-demand method (hypertrees/models/HyperTreeTSB.py): the
probability/size smoothing recursion and the state initialization follow
the statsforecast TSB implementation.

- Time series preprocessing (hypertrees/utils.py): the frequency-alias
conversion and the lag-column ordering follow the mlforecast conventions.

A copy of the Apache License, Version 2.0, is available at:

http://www.apache.org/licenses/LICENSE-2.0
Loading
Loading