autohybts 1.0.0rc1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- autohybts-1.0.0rc1/.gitignore +36 -0
- autohybts-1.0.0rc1/LICENSE +21 -0
- autohybts-1.0.0rc1/PKG-INFO +267 -0
- autohybts-1.0.0rc1/README.md +200 -0
- autohybts-1.0.0rc1/notebooks/README.md +67 -0
- autohybts-1.0.0rc1/notebooks/en/README.md +31 -0
- autohybts-1.0.0rc1/pyproject.toml +145 -0
- autohybts-1.0.0rc1/src/autohybts/__init__.py +21 -0
- autohybts-1.0.0rc1/src/autohybts/adapters/__init__.py +1 -0
- autohybts-1.0.0rc1/src/autohybts/adapters/base.py +180 -0
- autohybts-1.0.0rc1/src/autohybts/adapters/harmonic.py +110 -0
- autohybts-1.0.0rc1/src/autohybts/adapters/intermittent.py +175 -0
- autohybts-1.0.0rc1/src/autohybts/adapters/naive.py +140 -0
- autohybts-1.0.0rc1/src/autohybts/adapters/sklearn_regression.py +322 -0
- autohybts-1.0.0rc1/src/autohybts/adapters/statsforecast_models.py +83 -0
- autohybts-1.0.0rc1/src/autohybts/adapters/statsmodels_arima.py +219 -0
- autohybts-1.0.0rc1/src/autohybts/adapters/statsmodels_ets.py +112 -0
- autohybts-1.0.0rc1/src/autohybts/api.py +64 -0
- autohybts-1.0.0rc1/src/autohybts/benchmarks/__init__.py +27 -0
- autohybts-1.0.0rc1/src/autohybts/benchmarks/ablation.py +485 -0
- autohybts-1.0.0rc1/src/autohybts/benchmarks/calibration.py +310 -0
- autohybts-1.0.0rc1/src/autohybts/data/__init__.py +1 -0
- autohybts-1.0.0rc1/src/autohybts/data/ingest.py +39 -0
- autohybts-1.0.0rc1/src/autohybts/data/panel.py +222 -0
- autohybts-1.0.0rc1/src/autohybts/data/preprocessing.py +87 -0
- autohybts-1.0.0rc1/src/autohybts/data/profiling.py +51 -0
- autohybts-1.0.0rc1/src/autohybts/data/schema.py +190 -0
- autohybts-1.0.0rc1/src/autohybts/data/splitter.py +629 -0
- autohybts-1.0.0rc1/src/autohybts/data/validation.py +136 -0
- autohybts-1.0.0rc1/src/autohybts/data/windows.py +67 -0
- autohybts-1.0.0rc1/src/autohybts/datasets/__init__.py +33 -0
- autohybts-1.0.0rc1/src/autohybts/datasets/cache.py +295 -0
- autohybts-1.0.0rc1/src/autohybts/datasets/catalog.py +209 -0
- autohybts-1.0.0rc1/src/autohybts/datasets/descriptor.py +144 -0
- autohybts-1.0.0rc1/src/autohybts/datasets/named.py +53 -0
- autohybts-1.0.0rc1/src/autohybts/datasets/providers.py +588 -0
- autohybts-1.0.0rc1/src/autohybts/datasets/synthetic.py +114 -0
- autohybts-1.0.0rc1/src/autohybts/domain/__init__.py +1 -0
- autohybts-1.0.0rc1/src/autohybts/domain/context.py +79 -0
- autohybts-1.0.0rc1/src/autohybts/domain/fit_count.py +50 -0
- autohybts-1.0.0rc1/src/autohybts/domain/identity.py +89 -0
- autohybts-1.0.0rc1/src/autohybts/domain/results.py +211 -0
- autohybts-1.0.0rc1/src/autohybts/domain/specs.py +593 -0
- autohybts-1.0.0rc1/src/autohybts/evaluation/__init__.py +1 -0
- autohybts-1.0.0rc1/src/autohybts/evaluation/coverage.py +32 -0
- autohybts-1.0.0rc1/src/autohybts/evaluation/metrics.py +177 -0
- autohybts-1.0.0rc1/src/autohybts/evaluation/temporal.py +312 -0
- autohybts-1.0.0rc1/src/autohybts/exceptions.py +82 -0
- autohybts-1.0.0rc1/src/autohybts/experiment.py +1660 -0
- autohybts-1.0.0rc1/src/autohybts/forecasting/__init__.py +1 -0
- autohybts-1.0.0rc1/src/autohybts/forecasting/finalized.py +278 -0
- autohybts-1.0.0rc1/src/autohybts/forecasting/forecast_frame.py +87 -0
- autohybts-1.0.0rc1/src/autohybts/forecasting/multi_step_a.py +47 -0
- autohybts-1.0.0rc1/src/autohybts/forecasting/rolling_one_step_b.py +55 -0
- autohybts-1.0.0rc1/src/autohybts/models/__init__.py +45 -0
- autohybts-1.0.0rc1/src/autohybts/models/custom.py +106 -0
- autohybts-1.0.0rc1/src/autohybts/models/keras_models.py +270 -0
- autohybts-1.0.0rc1/src/autohybts/models/keras_zoo.py +63 -0
- autohybts-1.0.0rc1/src/autohybts/models/lagged.py +286 -0
- autohybts-1.0.0rc1/src/autohybts/models/requirements.py +134 -0
- autohybts-1.0.0rc1/src/autohybts/models/torch_models.py +323 -0
- autohybts-1.0.0rc1/src/autohybts/models/torch_zoo.py +155 -0
- autohybts-1.0.0rc1/src/autohybts/persistence/__init__.py +1 -0
- autohybts-1.0.0rc1/src/autohybts/persistence/manifest.py +89 -0
- autohybts-1.0.0rc1/src/autohybts/persistence/model_store.py +151 -0
- autohybts-1.0.0rc1/src/autohybts/py.typed +0 -0
- autohybts-1.0.0rc1/src/autohybts/registry/__init__.py +6 -0
- autohybts-1.0.0rc1/src/autohybts/registry/capabilities.py +83 -0
- autohybts-1.0.0rc1/src/autohybts/registry/registry.py +512 -0
- autohybts-1.0.0rc1/src/autohybts/reporting/__init__.py +1 -0
- autohybts-1.0.0rc1/src/autohybts/reporting/comparison.py +262 -0
- autohybts-1.0.0rc1/src/autohybts/reporting/diagnostics.py +107 -0
- autohybts-1.0.0rc1/src/autohybts/reporting/evidence.py +67 -0
- autohybts-1.0.0rc1/src/autohybts/reporting/leaderboard.py +76 -0
- autohybts-1.0.0rc1/src/autohybts/reporting/plots.py +559 -0
- autohybts-1.0.0rc1/src/autohybts/reporting/strategies.py +192 -0
- autohybts-1.0.0rc1/src/autohybts/residuals/__init__.py +1 -0
- autohybts-1.0.0rc1/src/autohybts/residuals/correctors.py +145 -0
- autohybts-1.0.0rc1/src/autohybts/residuals/features.py +71 -0
- autohybts-1.0.0rc1/src/autohybts/residuals/generation.py +202 -0
- autohybts-1.0.0rc1/src/autohybts/residuals/provenance.py +109 -0
- autohybts-1.0.0rc1/src/autohybts/residuals/recursive.py +38 -0
- autohybts-1.0.0rc1/src/autohybts/residuals/sequence.py +137 -0
- autohybts-1.0.0rc1/src/autohybts/results.py +186 -0
- autohybts-1.0.0rc1/src/autohybts/search/__init__.py +1 -0
- autohybts-1.0.0rc1/src/autohybts/search/budgets.py +110 -0
- autohybts-1.0.0rc1/src/autohybts/search/cache.py +51 -0
- autohybts-1.0.0rc1/src/autohybts/search/ledger.py +104 -0
- autohybts-1.0.0rc1/src/autohybts/search/pruning.py +61 -0
- autohybts-1.0.0rc1/src/autohybts/search/runner.py +315 -0
- autohybts-1.0.0rc1/src/autohybts/search/spaces.py +611 -0
- autohybts-1.0.0rc1/src/autohybts/search/tuning.py +357 -0
- autohybts-1.0.0rc1/src/autohybts/selection/__init__.py +1 -0
- autohybts-1.0.0rc1/src/autohybts/selection/incremental.py +401 -0
- autohybts-1.0.0rc1/src/autohybts/selection/policy.py +253 -0
- autohybts-1.0.0rc1/src/autohybts/selection/rank.py +184 -0
- autohybts-1.0.0rc1/src/autohybts/strategies/__init__.py +1 -0
- autohybts-1.0.0rc1/src/autohybts/strategies/additive_residual.py +207 -0
- autohybts-1.0.0rc1/src/autohybts/strategies/base.py +227 -0
- autohybts-1.0.0rc1/src/autohybts/strategies/combination.py +164 -0
- autohybts-1.0.0rc1/src/autohybts/strategies/decomposition.py +198 -0
- autohybts-1.0.0rc1/src/autohybts/strategies/dynamic.py +230 -0
- autohybts-1.0.0rc1/src/autohybts/strategies/ensemble.py +140 -0
- autohybts-1.0.0rc1/src/autohybts/strategies/multistage.py +66 -0
- autohybts-1.0.0rc1/src/autohybts/types.py +31 -0
- autohybts-1.0.0rc1/tests/conftest.py +35 -0
- autohybts-1.0.0rc1/tests/contracts/test_base_forecaster.py +190 -0
- autohybts-1.0.0rc1/tests/contracts/test_docs_tables.py +48 -0
- autohybts-1.0.0rc1/tests/contracts/test_docs_translation.py +81 -0
- autohybts-1.0.0rc1/tests/contracts/test_exceptions.py +50 -0
- autohybts-1.0.0rc1/tests/contracts/test_import_minimal.py +44 -0
- autohybts-1.0.0rc1/tests/contracts/test_notebook_metadata.py +103 -0
- autohybts-1.0.0rc1/tests/contracts/test_notebook_outputs.py +40 -0
- autohybts-1.0.0rc1/tests/fixtures/datasets/README.txt +2 -0
- autohybts-1.0.0rc1/tests/fixtures/datasets/m4/Daily-test.csv +3 -0
- autohybts-1.0.0rc1/tests/fixtures/datasets/m4/Daily-train.csv +3 -0
- autohybts-1.0.0rc1/tests/fixtures/datasets/m4/M4-info.csv +4 -0
- autohybts-1.0.0rc1/tests/fixtures/datasets/rdatasets/AirPassengers.csv +7 -0
- autohybts-1.0.0rc1/tests/fixtures/datasets/rdatasets/datasets.csv +4 -0
- autohybts-1.0.0rc1/tests/fixtures/datasets/rdatasets/iris.csv +4 -0
- autohybts-1.0.0rc1/tests/fixtures/datasets/rdatasets/ozone.csv +5 -0
- autohybts-1.0.0rc1/tests/integration/test_ablation_script.py +68 -0
- autohybts-1.0.0rc1/tests/integration/test_advanced_families.py +250 -0
- autohybts-1.0.0rc1/tests/integration/test_comparison.py +373 -0
- autohybts-1.0.0rc1/tests/integration/test_ensembles.py +115 -0
- autohybts-1.0.0rc1/tests/integration/test_experiment.py +310 -0
- autohybts-1.0.0rc1/tests/integration/test_incremental_selection.py +130 -0
- autohybts-1.0.0rc1/tests/integration/test_notebooks.py +168 -0
- autohybts-1.0.0rc1/tests/integration/test_panel_experiment.py +317 -0
- autohybts-1.0.0rc1/tests/integration/test_reporting.py +223 -0
- autohybts-1.0.0rc1/tests/integration/test_residual_pipeline.py +204 -0
- autohybts-1.0.0rc1/tests/integration/test_search_engine.py +384 -0
- autohybts-1.0.0rc1/tests/integration/test_temporal_evaluator.py +353 -0
- autohybts-1.0.0rc1/tests/leakage/test_advanced_causality.py +144 -0
- autohybts-1.0.0rc1/tests/leakage/test_base_causality.py +81 -0
- autohybts-1.0.0rc1/tests/leakage/test_context.py +61 -0
- autohybts-1.0.0rc1/tests/leakage/test_ensemble_causality.py +90 -0
- autohybts-1.0.0rc1/tests/leakage/test_external_frameworks.py +355 -0
- autohybts-1.0.0rc1/tests/leakage/test_hybrid_causality.py +140 -0
- autohybts-1.0.0rc1/tests/leakage/test_residual_windows.py +74 -0
- autohybts-1.0.0rc1/tests/leakage/test_temporal_plan.py +235 -0
- autohybts-1.0.0rc1/tests/leakage/test_variant_b.py +253 -0
- autohybts-1.0.0rc1/tests/regression/capture_legacy.py +107 -0
- autohybts-1.0.0rc1/tests/regression/capture_legacy_hybrids.py +276 -0
- autohybts-1.0.0rc1/tests/regression/fixtures/legacy_composed.json +468 -0
- autohybts-1.0.0rc1/tests/regression/fixtures/legacy_hybrids.json +768 -0
- autohybts-1.0.0rc1/tests/regression/test_legacy_parity.py +230 -0
- autohybts-1.0.0rc1/tests/unit/test_ablation_report.py +102 -0
- autohybts-1.0.0rc1/tests/unit/test_adapters.py +235 -0
- autohybts-1.0.0rc1/tests/unit/test_advanced_strategies.py +440 -0
- autohybts-1.0.0rc1/tests/unit/test_arima_cache.py +58 -0
- autohybts-1.0.0rc1/tests/unit/test_baselines.py +115 -0
- autohybts-1.0.0rc1/tests/unit/test_boosting.py +127 -0
- autohybts-1.0.0rc1/tests/unit/test_calibration.py +116 -0
- autohybts-1.0.0rc1/tests/unit/test_compositions.py +323 -0
- autohybts-1.0.0rc1/tests/unit/test_correctors.py +90 -0
- autohybts-1.0.0rc1/tests/unit/test_datasets.py +505 -0
- autohybts-1.0.0rc1/tests/unit/test_default_rule.py +77 -0
- autohybts-1.0.0rc1/tests/unit/test_dynamic_selection.py +175 -0
- autohybts-1.0.0rc1/tests/unit/test_external_models.py +401 -0
- autohybts-1.0.0rc1/tests/unit/test_forecast_frame.py +64 -0
- autohybts-1.0.0rc1/tests/unit/test_harmonic.py +90 -0
- autohybts-1.0.0rc1/tests/unit/test_identity.py +144 -0
- autohybts-1.0.0rc1/tests/unit/test_ingest.py +40 -0
- autohybts-1.0.0rc1/tests/unit/test_intermittent.py +136 -0
- autohybts-1.0.0rc1/tests/unit/test_manifest.py +78 -0
- autohybts-1.0.0rc1/tests/unit/test_metrics.py +90 -0
- autohybts-1.0.0rc1/tests/unit/test_panel.py +87 -0
- autohybts-1.0.0rc1/tests/unit/test_preprocessing.py +54 -0
- autohybts-1.0.0rc1/tests/unit/test_registry.py +224 -0
- autohybts-1.0.0rc1/tests/unit/test_release.py +73 -0
- autohybts-1.0.0rc1/tests/unit/test_residual_sequence.py +121 -0
- autohybts-1.0.0rc1/tests/unit/test_residuals.py +175 -0
- autohybts-1.0.0rc1/tests/unit/test_scaling.py +90 -0
- autohybts-1.0.0rc1/tests/unit/test_schema.py +129 -0
- autohybts-1.0.0rc1/tests/unit/test_search_components.py +278 -0
- autohybts-1.0.0rc1/tests/unit/test_selection_rules.py +428 -0
- autohybts-1.0.0rc1/tests/unit/test_specs.py +113 -0
- autohybts-1.0.0rc1/tests/unit/test_splitter.py +181 -0
- autohybts-1.0.0rc1/tests/unit/test_statsforecast.py +93 -0
- autohybts-1.0.0rc1/tests/unit/test_strategy_report.py +122 -0
- autohybts-1.0.0rc1/tests/unit/test_tuning.py +95 -0
- autohybts-1.0.0rc1/tests/unit/test_types.py +21 -0
- autohybts-1.0.0rc1/tests/unit/test_validation.py +120 -0
- autohybts-1.0.0rc1/tests/unit/test_windows.py +55 -0
- autohybts-1.0.0rc1/tools/check_release.py +96 -0
- autohybts-1.0.0rc1/tools/smoke_wheel.py +47 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
*.md
|
|
2
|
+
!README.md
|
|
3
|
+
!.github/SECURITY.md
|
|
4
|
+
docs/
|
|
5
|
+
|
|
6
|
+
.venv/
|
|
7
|
+
.venv-*/
|
|
8
|
+
__pycache__/
|
|
9
|
+
.ipynb_checkpoints/
|
|
10
|
+
|
|
11
|
+
data/raw/
|
|
12
|
+
artifacts/
|
|
13
|
+
.claude/
|
|
14
|
+
.agents/
|
|
15
|
+
lightning_logs/
|
|
16
|
+
|
|
17
|
+
# Tooling and build outputs
|
|
18
|
+
.pytest_cache/
|
|
19
|
+
.mypy_cache/
|
|
20
|
+
.ruff_cache/
|
|
21
|
+
.hypothesis/
|
|
22
|
+
.coverage
|
|
23
|
+
.coverage.*
|
|
24
|
+
coverage.xml
|
|
25
|
+
htmlcov/
|
|
26
|
+
build/
|
|
27
|
+
dist/
|
|
28
|
+
*.egg-info/
|
|
29
|
+
runs/
|
|
30
|
+
|
|
31
|
+
# Documentation build and notebooks copied at build time
|
|
32
|
+
documentation/_build/
|
|
33
|
+
documentation/tutorials/notebooks/
|
|
34
|
+
documentation/user_guide/_generated/
|
|
35
|
+
documentation/en/tutorials/notebooks/
|
|
36
|
+
documentation/en/user_guide/_generated/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 João Ataíde
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: autohybts
|
|
3
|
+
Version: 1.0.0rc1
|
|
4
|
+
Summary: Automated Hybrid Time Series Forecasting: guarded search and incremental selection of standalone and hybrid forecasters.
|
|
5
|
+
Project-URL: Homepage, https://github.com/jvataidee/AutoHybTS
|
|
6
|
+
Project-URL: Documentation, https://autohybts.readthedocs.io/
|
|
7
|
+
Project-URL: Source, https://github.com/jvataidee/AutoHybTS
|
|
8
|
+
Project-URL: Issues, https://github.com/jvataidee/AutoHybTS/issues
|
|
9
|
+
Author: João Ataíde
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: automl,forecasting,hybrid models,residual correction,time series
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Requires-Dist: numpy>=1.26
|
|
23
|
+
Requires-Dist: pandas>=2.1
|
|
24
|
+
Requires-Dist: scikit-learn>=1.4
|
|
25
|
+
Provides-Extra: boosting
|
|
26
|
+
Requires-Dist: catboost>=1.2; extra == 'boosting'
|
|
27
|
+
Requires-Dist: lightgbm>=4; extra == 'boosting'
|
|
28
|
+
Requires-Dist: xgboost>=2; extra == 'boosting'
|
|
29
|
+
Provides-Extra: datasets
|
|
30
|
+
Requires-Dist: rdata>=0.11; extra == 'datasets'
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
33
|
+
Requires-Dist: hypothesis>=6.100; extra == 'dev'
|
|
34
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
35
|
+
Requires-Dist: packaging>=22; extra == 'dev'
|
|
36
|
+
Requires-Dist: pandas-stubs>=2.1; extra == 'dev'
|
|
37
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
40
|
+
Provides-Extra: docs
|
|
41
|
+
Requires-Dist: furo>=2024.5.6; extra == 'docs'
|
|
42
|
+
Requires-Dist: myst-nb>=1.1; extra == 'docs'
|
|
43
|
+
Requires-Dist: sphinx-copybutton>=0.5; extra == 'docs'
|
|
44
|
+
Requires-Dist: sphinx>=7.3; extra == 'docs'
|
|
45
|
+
Provides-Extra: nixtla-stats
|
|
46
|
+
Requires-Dist: statsforecast>=2; extra == 'nixtla-stats'
|
|
47
|
+
Provides-Extra: notebook
|
|
48
|
+
Requires-Dist: ipykernel>=6.29; extra == 'notebook'
|
|
49
|
+
Requires-Dist: matplotlib>=3.10; extra == 'notebook'
|
|
50
|
+
Requires-Dist: nbclient>=0.10; extra == 'notebook'
|
|
51
|
+
Requires-Dist: nbformat>=5.10; extra == 'notebook'
|
|
52
|
+
Provides-Extra: optuna
|
|
53
|
+
Requires-Dist: optuna>=3.5; extra == 'optuna'
|
|
54
|
+
Provides-Extra: plot
|
|
55
|
+
Requires-Dist: matplotlib>=3.10; extra == 'plot'
|
|
56
|
+
Provides-Extra: stats
|
|
57
|
+
Requires-Dist: statsmodels>=0.14; extra == 'stats'
|
|
58
|
+
Provides-Extra: tensorflow
|
|
59
|
+
Requires-Dist: packaging>=22; extra == 'tensorflow'
|
|
60
|
+
Requires-Dist: tensorflow>=2.16; extra == 'tensorflow'
|
|
61
|
+
Provides-Extra: torch
|
|
62
|
+
Requires-Dist: packaging>=22; extra == 'torch'
|
|
63
|
+
Requires-Dist: torch>=2.2; extra == 'torch'
|
|
64
|
+
Provides-Extra: yaml
|
|
65
|
+
Requires-Dist: pyyaml>=6.0; extra == 'yaml'
|
|
66
|
+
Description-Content-Type: text/markdown
|
|
67
|
+
|
|
68
|
+
<p align="center">
|
|
69
|
+
<img src="https://raw.githubusercontent.com/jvataidee/AutoHybTS/main/figures/AutoHybTS.png" alt="AutoHybTS" width="260">
|
|
70
|
+
</p>
|
|
71
|
+
|
|
72
|
+
<p align="center">
|
|
73
|
+
<img src="https://img.shields.io/badge/python-3.11%2B-blue.svg" alt="Python 3.11+">
|
|
74
|
+
<a href="https://autohybts.readthedocs.io/"><img src="https://readthedocs.org/projects/autohybts/badge/?version=latest" alt="Documentação"></a>
|
|
75
|
+
<a href="https://github.com/jvataidee/AutoHybTS/actions/workflows/ci.yml"><img src="https://github.com/jvataidee/AutoHybTS/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
|
|
76
|
+
<a href="https://github.com/jvataidee/AutoHybTS/blob/main/LICENSE"><img src="https://img.shields.io/badge/licen%C3%A7a-MIT-green.svg" alt="Licença MIT"></a>
|
|
77
|
+
</p>
|
|
78
|
+
|
|
79
|
+
# AutoHybTS
|
|
80
|
+
|
|
81
|
+
**Automated Hybrid Time Series Forecasting.** Biblioteca Python que automatiza a comparação de modelos individuais de previsão e a descoberta de **sistemas híbridos residuais** (modelo-base + corretor do erro), aceitando complexidade adicional só quando critérios de validação temporal definidos pelo usuário são satisfeitos.
|
|
82
|
+
|
|
83
|
+
A interface é inspirada no [PyCaret](https://pycaret.org) — um experimento, métodos curtos, resultados prontos para tabela e gráfico —, mas o foco é outro: reunir num só fluxo, com validação sem vazamento, os modelos híbridos residuais para previsão de séries temporais e as estratégias de montá-los (correção aditiva, vários estágios, decomposição, combinação).
|
|
84
|
+
|
|
85
|
+
> **Status: candidata à v1 (`1.0.0rc1`).** A API funciona para uma série ou um painel de séries, nas variantes A (multipasso) e B (rolling de um passo com parâmetros congelados). Esta é uma pré-versão para validação; a `1.0.0` estável depende da conferência final e do estudo em séries reais. Veja as [notas e a política de compatibilidade](documentation/releasing.rst).
|
|
86
|
+
|
|
87
|
+
## Instalação
|
|
88
|
+
|
|
89
|
+
Requer Python 3.11 ou mais novo.
|
|
90
|
+
|
|
91
|
+
Para testar o código antes da publicação da candidata, instale direto do repositório:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
pip install "autohybts[stats,plot] @ git+https://github.com/jvataidee/AutoHybTS.git"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
A publicação de `v1.0.0rc1` será feita primeiro no TestPyPI. As instruções para instalar
|
|
98
|
+
a candidata pelo índice de testes estão nas [notas de release](documentation/releasing.rst).
|
|
99
|
+
|
|
100
|
+
Para usar modelos próprios em PyTorch ou TensorFlow, acrescente os extras `torch` e/ou `tensorflow` (ex.: `autohybts[stats,plot,torch]`).
|
|
101
|
+
|
|
102
|
+
## Início rápido
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
from autohybts import AutoHybridExperiment, load_model, save_model
|
|
106
|
+
from autohybts.datasets import get_data
|
|
107
|
+
|
|
108
|
+
y = get_data("synthetic_daily") # pd.Series diária
|
|
109
|
+
exp = AutoHybridExperiment(fh=14, session_id=42).fit(y) # sela os últimos 14 pontos
|
|
110
|
+
|
|
111
|
+
result = exp.compare_models() # busca em V_search + seleção incremental em V_select
|
|
112
|
+
result.leaderboard # todas as candidatas avaliadas na busca
|
|
113
|
+
result.decisions # cada desafiante (ex.: arima-mlp): aceito ou não, e por quê
|
|
114
|
+
|
|
115
|
+
final = exp.finalize_model(result.best) # reajuste no histórico anterior ao teste
|
|
116
|
+
exp.predict_model(final).predictions # previsões indexadas por data
|
|
117
|
+
exp.evaluate_external(final).metrics # teste selado, uma única vez
|
|
118
|
+
|
|
119
|
+
path = save_model(final, "artifacts/champion")
|
|
120
|
+
model = load_model(path, trusted=True) # trusted=True: só para arquivos de confiança
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Carregar um modelo executa código (pickle). Para artefatos que passam por outras mãos,
|
|
124
|
+
assine com `save_model(..., signing_key=chave)` e confira com
|
|
125
|
+
`load_model(..., signing_key=chave)`, ou fixe o hash com `load_model(..., sha256=...)`.
|
|
126
|
+
|
|
127
|
+
### Estratégias de montar o sistema híbrido
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
result = exp.compare_models(
|
|
131
|
+
include=("standalone", "residual", "multistage", "decomposition", "combination")
|
|
132
|
+
)
|
|
133
|
+
result.strategies # melhor e mediana de cada estratégia
|
|
134
|
+
result.plot("pareto") # erro × custo; também x="complexity" e "strategies"
|
|
135
|
+
|
|
136
|
+
exp.create_hybrid("arima", "mlp") # ŷ = b + α·r̂
|
|
137
|
+
exp.create_hybrid("arima", "mlp", extra_stages=["linear"]) # correção da correção
|
|
138
|
+
exp.create_decomposition("linear", "mlp", method="ma") # suave + volátil
|
|
139
|
+
exp.create_combination(["arima", "knn"], weights="inverse_mse")
|
|
140
|
+
exp.tune_model("knn", n_trials=20) # só em V_search; Optuna se instalado
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Comparação e validação cruzada temporal
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
cv = exp.cross_validate(folds=8, step=7) # mesmas origens para todos os modelos
|
|
147
|
+
cv.summary # média, desvio, posto médio
|
|
148
|
+
cv.tests() # Wilcoxon e Diebold-Mariano com Holm (relatório)
|
|
149
|
+
cv.plot("critical_difference") # também: leaderboard, boxplot, win_rate, forecasts
|
|
150
|
+
exp.nested_cross_validate(outer_folds=3) # o procedimento inteiro, dobra a dobra
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Modelos próprios (PyTorch, TensorFlow, qualquer biblioteca)
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
from autohybts.models import keras_model, keras_zoo, torch_model
|
|
157
|
+
from autohybts.models.torch_zoo import LSTMNet, MambaNet
|
|
158
|
+
|
|
159
|
+
exp.register_model(
|
|
160
|
+
"lstm",
|
|
161
|
+
torch_model(LSTMNet, hidden=32, lags=28, differencing=1),
|
|
162
|
+
family="deep",
|
|
163
|
+
requires={"torch": ">=2.2"},
|
|
164
|
+
version="1",
|
|
165
|
+
)
|
|
166
|
+
exp.register_model(
|
|
167
|
+
"mamba",
|
|
168
|
+
torch_model(MambaNet, d_model=32, lags=28, differencing=1),
|
|
169
|
+
family="deep",
|
|
170
|
+
requires={"torch": ">=2.2"},
|
|
171
|
+
version="1",
|
|
172
|
+
)
|
|
173
|
+
exp.register_model(
|
|
174
|
+
"keras_lstm",
|
|
175
|
+
keras_model(keras_zoo.lstm, units=32, lags=28),
|
|
176
|
+
family="deep",
|
|
177
|
+
requires={"tensorflow": ">=2.16"},
|
|
178
|
+
version="1",
|
|
179
|
+
)
|
|
180
|
+
# depois, os nomes valem em base_models, correctors, create_hybrid, tune_model ...
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Várias séries
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
exp = AutoHybridExperiment(fh=14).fit({"loja_a": y_a, "loja_b": y_b})
|
|
187
|
+
result = exp.compare_models() # ranking pela média dos postos entre séries
|
|
188
|
+
model = exp.finalize_model(result.best) # PanelForecaster: um modelo por série
|
|
189
|
+
exp.evaluate_external(model).metrics # uma linha por série + média
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Datasets
|
|
193
|
+
|
|
194
|
+
Copie o nome e passe para `get_data`; o resultado é uma `pd.Series` pronta para o `fit`.
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
from autohybts.datasets import get_data
|
|
198
|
+
|
|
199
|
+
y = get_data("ozone")
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
| Nome | O que é | Frequência | Pontos |
|
|
203
|
+
|---|---|---|---|
|
|
204
|
+
| `synthetic_daily` | sintética: tendência, sazonalidade semanal e ruído AR(1) (offline) | diária | 730 |
|
|
205
|
+
| `white_noise_daily` | sintética: nível + ruído branco, controle negativo (offline) | diária | 730 |
|
|
206
|
+
| `air_passengers` | passageiros aéreos, 1949–1960 | mensal | 144 |
|
|
207
|
+
| `nottem` | temperatura em Nottingham, 1920–1939 | mensal | 240 |
|
|
208
|
+
| `us_acc_deaths` | mortes acidentais nos EUA, 1973–1978 | mensal | 72 |
|
|
209
|
+
| `sunspots_monthly` | manchas solares, 1749–1983 | mensal | 2820 |
|
|
210
|
+
| `uk_gas` | consumo de gás no Reino Unido, 1960–1986 | trimestral | 108 |
|
|
211
|
+
| `johnson_johnson` | lucro por ação da Johnson & Johnson, 1960–1980 | trimestral | 84 |
|
|
212
|
+
| `ozone` | ozônio total em Halley Bay (Antártida), 1956–2000 | anual | 45 |
|
|
213
|
+
| `nile` | vazão do rio Nilo, 1871–1970 | anual | 100 |
|
|
214
|
+
| `lynx` | linces capturados no Canadá, 1821–1934 | anual | 114 |
|
|
215
|
+
| `lake_huron` | nível do lago Huron, 1875–1972 | anual | 98 |
|
|
216
|
+
| `sunspots` | manchas solares, 1700–1988 | anual | 289 |
|
|
217
|
+
| `m4:D1` | M4: troque `D1` por `Y…`, `Q…`, `M…`, `W…`, `D…` ou `H…` (100 mil séries) | várias | — |
|
|
218
|
+
| `m3:N1402` | M3: 3.003 séries; exige o extra `datasets` | várias | — |
|
|
219
|
+
|
|
220
|
+
As sintéticas são geradas na hora. As outras são baixadas na primeira vez e ficam em cache
|
|
221
|
+
(`~/.cache/autohybts/datasets`); as reais vêm do [Rdatasets](https://vincentarelbundock.github.io/Rdatasets/).
|
|
222
|
+
|
|
223
|
+
Nas séries do M4 e do M3 o teste oficial da competição vem no fim; sele-o com `test_size`:
|
|
224
|
+
|
|
225
|
+
```python
|
|
226
|
+
from autohybts.datasets import load_benchmark
|
|
227
|
+
|
|
228
|
+
series = load_benchmark("m4", subset="daily", series_id="D1")
|
|
229
|
+
exp = AutoHybridExperiment(fh=series.descriptor.horizon, test_size=len(series.test)).fit(
|
|
230
|
+
series.full()
|
|
231
|
+
)
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Qualquer outra série do Rdatasets entra por `load_dataset`, dizendo qual coluna é o tempo,
|
|
235
|
+
qual é o alvo e a frequência (veja a documentação, *Datasets*). A biblioteca não preenche
|
|
236
|
+
valores ausentes: trate-os antes do `fit`.
|
|
237
|
+
|
|
238
|
+
## Documentação e tutoriais
|
|
239
|
+
|
|
240
|
+
- Documentação: <https://autohybts.readthedocs.io/>
|
|
241
|
+
- Tutoriais em notebook, salvos com as saídas: [`notebooks/`](https://github.com/jvataidee/AutoHybTS/tree/main/notebooks)
|
|
242
|
+
|
|
243
|
+
Para configurar a publicação no Read the Docs, veja
|
|
244
|
+
[`Publicação no Read the Docs`](documentation/contributing.rst).
|
|
245
|
+
O projeto em português (`/pt-br/latest/`) deve usar **Language: Portuguese (Brazil)**
|
|
246
|
+
e **Build configuration file: `documentation/.readthedocs.yaml`**. O YAML da raiz
|
|
247
|
+
(`.readthedocs.yaml`) compila a versão em inglês.
|
|
248
|
+
|
|
249
|
+
## Princípios
|
|
250
|
+
|
|
251
|
+
- Validade temporal antes de automação: nenhuma informação posterior à origem de previsão entra como feature, e o teste selado nunca alimenta busca ou seleção.
|
|
252
|
+
- Seleção incremental guardada: um desafiante só substitui o campeão atual se superar critérios pareados de ganho e vitórias; caso contrário, a estrutura anterior (inclusive um modelo individual) é mantida.
|
|
253
|
+
- Rastreabilidade: candidatas, tentativas e decisões têm identidade estável e ficam registradas, inclusive rejeições e falhas.
|
|
254
|
+
|
|
255
|
+
## Limitações atuais
|
|
256
|
+
|
|
257
|
+
- Decomposição, combinação fixa e estágios múltiplos só entram na busca quando pedidos em `compare_models(include=...)`; a CV aninhada é só para uma série; a seleção dinâmica (`dynamic`) só existe na variante B.
|
|
258
|
+
- `compare_models` com o orçamento padrão (`small`), o espaço completo e 7 origens por camada leva alguns minutos numa série de ~700 pontos, sobretudo por causa do ARIMA com ordem automática; use `budget="smoke"`, `fold=3` ou `base_models=[...]` para explorar.
|
|
259
|
+
- A regra de aceite (ganho mediano ≥ 5 %, vitórias ≥ 60 %, variabilidade ≥ 0,05, com 7 origens por camada quando a série comporta) foi calibrada em controles sintéticos: aceitou estruturas espúrias em 2–4 % das séries de ruído branco e ganhos reais em 54–56 % das séries com resíduo previsível. Não é controle de erro estatístico; em séries curtas, com menos origens, a taxa de falso aceite é maior (veja o guia de seleção).
|
|
260
|
+
|
|
261
|
+
## Créditos
|
|
262
|
+
|
|
263
|
+
Inspirada na ergonomia do [PyCaret](https://pycaret.org); o PyCaret não é dependência.
|
|
264
|
+
|
|
265
|
+
## Licença
|
|
266
|
+
|
|
267
|
+
[MIT](https://github.com/jvataidee/AutoHybTS/blob/main/LICENSE) © João Ataíde.
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/jvataidee/AutoHybTS/main/figures/AutoHybTS.png" alt="AutoHybTS" width="260">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img src="https://img.shields.io/badge/python-3.11%2B-blue.svg" alt="Python 3.11+">
|
|
7
|
+
<a href="https://autohybts.readthedocs.io/"><img src="https://readthedocs.org/projects/autohybts/badge/?version=latest" alt="Documentação"></a>
|
|
8
|
+
<a href="https://github.com/jvataidee/AutoHybTS/actions/workflows/ci.yml"><img src="https://github.com/jvataidee/AutoHybTS/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
|
|
9
|
+
<a href="https://github.com/jvataidee/AutoHybTS/blob/main/LICENSE"><img src="https://img.shields.io/badge/licen%C3%A7a-MIT-green.svg" alt="Licença MIT"></a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
# AutoHybTS
|
|
13
|
+
|
|
14
|
+
**Automated Hybrid Time Series Forecasting.** Biblioteca Python que automatiza a comparação de modelos individuais de previsão e a descoberta de **sistemas híbridos residuais** (modelo-base + corretor do erro), aceitando complexidade adicional só quando critérios de validação temporal definidos pelo usuário são satisfeitos.
|
|
15
|
+
|
|
16
|
+
A interface é inspirada no [PyCaret](https://pycaret.org) — um experimento, métodos curtos, resultados prontos para tabela e gráfico —, mas o foco é outro: reunir num só fluxo, com validação sem vazamento, os modelos híbridos residuais para previsão de séries temporais e as estratégias de montá-los (correção aditiva, vários estágios, decomposição, combinação).
|
|
17
|
+
|
|
18
|
+
> **Status: candidata à v1 (`1.0.0rc1`).** A API funciona para uma série ou um painel de séries, nas variantes A (multipasso) e B (rolling de um passo com parâmetros congelados). Esta é uma pré-versão para validação; a `1.0.0` estável depende da conferência final e do estudo em séries reais. Veja as [notas e a política de compatibilidade](documentation/releasing.rst).
|
|
19
|
+
|
|
20
|
+
## Instalação
|
|
21
|
+
|
|
22
|
+
Requer Python 3.11 ou mais novo.
|
|
23
|
+
|
|
24
|
+
Para testar o código antes da publicação da candidata, instale direto do repositório:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install "autohybts[stats,plot] @ git+https://github.com/jvataidee/AutoHybTS.git"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
A publicação de `v1.0.0rc1` será feita primeiro no TestPyPI. As instruções para instalar
|
|
31
|
+
a candidata pelo índice de testes estão nas [notas de release](documentation/releasing.rst).
|
|
32
|
+
|
|
33
|
+
Para usar modelos próprios em PyTorch ou TensorFlow, acrescente os extras `torch` e/ou `tensorflow` (ex.: `autohybts[stats,plot,torch]`).
|
|
34
|
+
|
|
35
|
+
## Início rápido
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from autohybts import AutoHybridExperiment, load_model, save_model
|
|
39
|
+
from autohybts.datasets import get_data
|
|
40
|
+
|
|
41
|
+
y = get_data("synthetic_daily") # pd.Series diária
|
|
42
|
+
exp = AutoHybridExperiment(fh=14, session_id=42).fit(y) # sela os últimos 14 pontos
|
|
43
|
+
|
|
44
|
+
result = exp.compare_models() # busca em V_search + seleção incremental em V_select
|
|
45
|
+
result.leaderboard # todas as candidatas avaliadas na busca
|
|
46
|
+
result.decisions # cada desafiante (ex.: arima-mlp): aceito ou não, e por quê
|
|
47
|
+
|
|
48
|
+
final = exp.finalize_model(result.best) # reajuste no histórico anterior ao teste
|
|
49
|
+
exp.predict_model(final).predictions # previsões indexadas por data
|
|
50
|
+
exp.evaluate_external(final).metrics # teste selado, uma única vez
|
|
51
|
+
|
|
52
|
+
path = save_model(final, "artifacts/champion")
|
|
53
|
+
model = load_model(path, trusted=True) # trusted=True: só para arquivos de confiança
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Carregar um modelo executa código (pickle). Para artefatos que passam por outras mãos,
|
|
57
|
+
assine com `save_model(..., signing_key=chave)` e confira com
|
|
58
|
+
`load_model(..., signing_key=chave)`, ou fixe o hash com `load_model(..., sha256=...)`.
|
|
59
|
+
|
|
60
|
+
### Estratégias de montar o sistema híbrido
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
result = exp.compare_models(
|
|
64
|
+
include=("standalone", "residual", "multistage", "decomposition", "combination")
|
|
65
|
+
)
|
|
66
|
+
result.strategies # melhor e mediana de cada estratégia
|
|
67
|
+
result.plot("pareto") # erro × custo; também x="complexity" e "strategies"
|
|
68
|
+
|
|
69
|
+
exp.create_hybrid("arima", "mlp") # ŷ = b + α·r̂
|
|
70
|
+
exp.create_hybrid("arima", "mlp", extra_stages=["linear"]) # correção da correção
|
|
71
|
+
exp.create_decomposition("linear", "mlp", method="ma") # suave + volátil
|
|
72
|
+
exp.create_combination(["arima", "knn"], weights="inverse_mse")
|
|
73
|
+
exp.tune_model("knn", n_trials=20) # só em V_search; Optuna se instalado
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Comparação e validação cruzada temporal
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
cv = exp.cross_validate(folds=8, step=7) # mesmas origens para todos os modelos
|
|
80
|
+
cv.summary # média, desvio, posto médio
|
|
81
|
+
cv.tests() # Wilcoxon e Diebold-Mariano com Holm (relatório)
|
|
82
|
+
cv.plot("critical_difference") # também: leaderboard, boxplot, win_rate, forecasts
|
|
83
|
+
exp.nested_cross_validate(outer_folds=3) # o procedimento inteiro, dobra a dobra
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Modelos próprios (PyTorch, TensorFlow, qualquer biblioteca)
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
from autohybts.models import keras_model, keras_zoo, torch_model
|
|
90
|
+
from autohybts.models.torch_zoo import LSTMNet, MambaNet
|
|
91
|
+
|
|
92
|
+
exp.register_model(
|
|
93
|
+
"lstm",
|
|
94
|
+
torch_model(LSTMNet, hidden=32, lags=28, differencing=1),
|
|
95
|
+
family="deep",
|
|
96
|
+
requires={"torch": ">=2.2"},
|
|
97
|
+
version="1",
|
|
98
|
+
)
|
|
99
|
+
exp.register_model(
|
|
100
|
+
"mamba",
|
|
101
|
+
torch_model(MambaNet, d_model=32, lags=28, differencing=1),
|
|
102
|
+
family="deep",
|
|
103
|
+
requires={"torch": ">=2.2"},
|
|
104
|
+
version="1",
|
|
105
|
+
)
|
|
106
|
+
exp.register_model(
|
|
107
|
+
"keras_lstm",
|
|
108
|
+
keras_model(keras_zoo.lstm, units=32, lags=28),
|
|
109
|
+
family="deep",
|
|
110
|
+
requires={"tensorflow": ">=2.16"},
|
|
111
|
+
version="1",
|
|
112
|
+
)
|
|
113
|
+
# depois, os nomes valem em base_models, correctors, create_hybrid, tune_model ...
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Várias séries
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
exp = AutoHybridExperiment(fh=14).fit({"loja_a": y_a, "loja_b": y_b})
|
|
120
|
+
result = exp.compare_models() # ranking pela média dos postos entre séries
|
|
121
|
+
model = exp.finalize_model(result.best) # PanelForecaster: um modelo por série
|
|
122
|
+
exp.evaluate_external(model).metrics # uma linha por série + média
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Datasets
|
|
126
|
+
|
|
127
|
+
Copie o nome e passe para `get_data`; o resultado é uma `pd.Series` pronta para o `fit`.
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
from autohybts.datasets import get_data
|
|
131
|
+
|
|
132
|
+
y = get_data("ozone")
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
| Nome | O que é | Frequência | Pontos |
|
|
136
|
+
|---|---|---|---|
|
|
137
|
+
| `synthetic_daily` | sintética: tendência, sazonalidade semanal e ruído AR(1) (offline) | diária | 730 |
|
|
138
|
+
| `white_noise_daily` | sintética: nível + ruído branco, controle negativo (offline) | diária | 730 |
|
|
139
|
+
| `air_passengers` | passageiros aéreos, 1949–1960 | mensal | 144 |
|
|
140
|
+
| `nottem` | temperatura em Nottingham, 1920–1939 | mensal | 240 |
|
|
141
|
+
| `us_acc_deaths` | mortes acidentais nos EUA, 1973–1978 | mensal | 72 |
|
|
142
|
+
| `sunspots_monthly` | manchas solares, 1749–1983 | mensal | 2820 |
|
|
143
|
+
| `uk_gas` | consumo de gás no Reino Unido, 1960–1986 | trimestral | 108 |
|
|
144
|
+
| `johnson_johnson` | lucro por ação da Johnson & Johnson, 1960–1980 | trimestral | 84 |
|
|
145
|
+
| `ozone` | ozônio total em Halley Bay (Antártida), 1956–2000 | anual | 45 |
|
|
146
|
+
| `nile` | vazão do rio Nilo, 1871–1970 | anual | 100 |
|
|
147
|
+
| `lynx` | linces capturados no Canadá, 1821–1934 | anual | 114 |
|
|
148
|
+
| `lake_huron` | nível do lago Huron, 1875–1972 | anual | 98 |
|
|
149
|
+
| `sunspots` | manchas solares, 1700–1988 | anual | 289 |
|
|
150
|
+
| `m4:D1` | M4: troque `D1` por `Y…`, `Q…`, `M…`, `W…`, `D…` ou `H…` (100 mil séries) | várias | — |
|
|
151
|
+
| `m3:N1402` | M3: 3.003 séries; exige o extra `datasets` | várias | — |
|
|
152
|
+
|
|
153
|
+
As sintéticas são geradas na hora. As outras são baixadas na primeira vez e ficam em cache
|
|
154
|
+
(`~/.cache/autohybts/datasets`); as reais vêm do [Rdatasets](https://vincentarelbundock.github.io/Rdatasets/).
|
|
155
|
+
|
|
156
|
+
Nas séries do M4 e do M3 o teste oficial da competição vem no fim; sele-o com `test_size`:
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
from autohybts.datasets import load_benchmark
|
|
160
|
+
|
|
161
|
+
series = load_benchmark("m4", subset="daily", series_id="D1")
|
|
162
|
+
exp = AutoHybridExperiment(fh=series.descriptor.horizon, test_size=len(series.test)).fit(
|
|
163
|
+
series.full()
|
|
164
|
+
)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Qualquer outra série do Rdatasets entra por `load_dataset`, dizendo qual coluna é o tempo,
|
|
168
|
+
qual é o alvo e a frequência (veja a documentação, *Datasets*). A biblioteca não preenche
|
|
169
|
+
valores ausentes: trate-os antes do `fit`.
|
|
170
|
+
|
|
171
|
+
## Documentação e tutoriais
|
|
172
|
+
|
|
173
|
+
- Documentação: <https://autohybts.readthedocs.io/>
|
|
174
|
+
- Tutoriais em notebook, salvos com as saídas: [`notebooks/`](https://github.com/jvataidee/AutoHybTS/tree/main/notebooks)
|
|
175
|
+
|
|
176
|
+
Para configurar a publicação no Read the Docs, veja
|
|
177
|
+
[`Publicação no Read the Docs`](documentation/contributing.rst).
|
|
178
|
+
O projeto em português (`/pt-br/latest/`) deve usar **Language: Portuguese (Brazil)**
|
|
179
|
+
e **Build configuration file: `documentation/.readthedocs.yaml`**. O YAML da raiz
|
|
180
|
+
(`.readthedocs.yaml`) compila a versão em inglês.
|
|
181
|
+
|
|
182
|
+
## Princípios
|
|
183
|
+
|
|
184
|
+
- Validade temporal antes de automação: nenhuma informação posterior à origem de previsão entra como feature, e o teste selado nunca alimenta busca ou seleção.
|
|
185
|
+
- Seleção incremental guardada: um desafiante só substitui o campeão atual se superar critérios pareados de ganho e vitórias; caso contrário, a estrutura anterior (inclusive um modelo individual) é mantida.
|
|
186
|
+
- Rastreabilidade: candidatas, tentativas e decisões têm identidade estável e ficam registradas, inclusive rejeições e falhas.
|
|
187
|
+
|
|
188
|
+
## Limitações atuais
|
|
189
|
+
|
|
190
|
+
- Decomposição, combinação fixa e estágios múltiplos só entram na busca quando pedidos em `compare_models(include=...)`; a CV aninhada é só para uma série; a seleção dinâmica (`dynamic`) só existe na variante B.
|
|
191
|
+
- `compare_models` com o orçamento padrão (`small`), o espaço completo e 7 origens por camada leva alguns minutos numa série de ~700 pontos, sobretudo por causa do ARIMA com ordem automática; use `budget="smoke"`, `fold=3` ou `base_models=[...]` para explorar.
|
|
192
|
+
- A regra de aceite (ganho mediano ≥ 5 %, vitórias ≥ 60 %, variabilidade ≥ 0,05, com 7 origens por camada quando a série comporta) foi calibrada em controles sintéticos: aceitou estruturas espúrias em 2–4 % das séries de ruído branco e ganhos reais em 54–56 % das séries com resíduo previsível. Não é controle de erro estatístico; em séries curtas, com menos origens, a taxa de falso aceite é maior (veja o guia de seleção).
|
|
193
|
+
|
|
194
|
+
## Créditos
|
|
195
|
+
|
|
196
|
+
Inspirada na ergonomia do [PyCaret](https://pycaret.org); o PyCaret não é dependência.
|
|
197
|
+
|
|
198
|
+
## Licença
|
|
199
|
+
|
|
200
|
+
[MIT](https://github.com/jvataidee/AutoHybTS/blob/main/LICENSE) © João Ataíde.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Tutoriais da AutoHybTS
|
|
2
|
+
|
|
3
|
+
Notebooks no estilo dos tutoriais do PyCaret 4: curtos, numerados, um tema por notebook, usando a API orientada a objetos (`AutoHybridExperiment`). As cópias em inglês, célula a célula, estão em [`en/`](en/README.md); uma mudança num tutorial entra nos dois idiomas.
|
|
4
|
+
|
|
5
|
+
| Notebook | Conteúdo | Requer |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| [01_quickstart](01_quickstart.ipynb) | Carregar uma série, comparar modelos, prever e avaliar no teste selado | etapa I8 |
|
|
8
|
+
| [02_hybrid_selection](02_hybrid_selection.ipynb) | Busca em estágios, híbrido montado à mão, decisões de seleção, auditoria de tentativas, diagnósticos e eventos | etapas I8 e I11 |
|
|
9
|
+
| [03_finalize_and_persist](03_finalize_and_persist.ipynb) | Finalizar, avaliar uma vez, salvar e carregar com manifesto, previsão operacional sem teste selado | etapa I8 |
|
|
10
|
+
| [04_rolling_one_step](04_rolling_one_step.ipynb) | Variante B: previsão de um passo com parâmetros congelados e streaming de observações | etapa I10 |
|
|
11
|
+
| [06_compare_and_cross_validate](06_compare_and_cross_validate.ipynb) | Ranking das finalistas, validação cruzada temporal, gráficos de comparação, testes estatísticos, comparação no teste selado e CV aninhada | — |
|
|
12
|
+
| [07_panel](07_panel.ipynb) | Várias séries no mesmo experimento: ranking entre séries, seleção sobre o conjunto, um modelo por série e avaliação externa por série | — |
|
|
13
|
+
| [08_advanced_families_and_tuning](08_advanced_families_and_tuning.ipynb) | Estágios extras, decomposição, combinação fixa, busca com todas as famílias e `tune_model` | — |
|
|
14
|
+
| [09_ablation](09_ablation.ipynb) | Ablação do procedimento de seleção (§30.5): 4 procedimentos, mesmo orçamento e mesmos testes externos, em 12 séries sintéticas × 3 sementes, orçamento `small` | pesado (≈55 min) |
|
|
15
|
+
| [10_external_models](10_external_models.ipynb) | Modelos próprios: PyTorch (LSTM, Transformer, Mamba, GRU escrito na hora), TensorFlow/Keras (LSTM, Transformer, convolução), Holt-Winters do statsmodels e gradient boosting, como bases, corretores, na busca, no ajuste e na persistência | extras `torch` e `tensorflow`; pesado |
|
|
16
|
+
| [11_calibration](11_calibration.ipynb) | Calibração da regra de aceite em controles com resposta conhecida (ruído branco e resíduo previsível): falsos aceites, ganhos recusados, efeito do número de origens e do teste de Wilcoxon, conjunto de confirmação | — |
|
|
17
|
+
| [12_baselines_and_boosting](12_baselines_and_boosting.ipynb) | Baselines (média histórica, média em janela, média sazonal em janela, passeio aleatório com drift), boosting sobre lags (HistGradientBoosting, AdaBoost.R2, LightGBM) como bases e corretores, RMAE e contagem de ajustes | LightGBM no extra `boosting` |
|
|
18
|
+
| [13_ensembles](13_ensembles.ipynb) | Ensembles de candidatas completas (média, mediana, média aparada, inverso do MSE, NNLS com encolhimento), ensemble de híbridos, ensemble corrigido e ensembles na busca com a regra de aceite | — |
|
|
19
|
+
| [14_intermittent_demand](14_intermittent_demand.ipynb) | Demanda intermitente: Croston-SBA, TSB, ADIDA e IMAPA contra médias simples, por que a RMSSE em vez da MASE, mudança de taxa, demanda que para e a família `intermittent` na busca | — |
|
|
20
|
+
| [15_statsforecast](15_statsforecast.ipynb) | AutoARIMA, AutoETS, AutoTheta e AutoCES do StatsForecast contra statsmodels e baselines, parâmetros congelados (`forward`), os híbridos estatístico-ANN da replicação e a busca com esses modelos | extra `nixtla-stats` (traz pandas 2.x) |
|
|
21
|
+
| [05_benchmark_m4](05_benchmark_m4.ipynb) | M4 com o teste oficial selado, painel do M3 e Rdatasets (baixa os dados na primeira execução) | rede na 1ª vez; extra `datasets` para o M3 |
|
|
22
|
+
|
|
23
|
+
## Como executar
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
.venv/Scripts/python -m pip install -e ".[dev,stats,notebook]"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
No VS Code, abra o notebook e selecione o kernel do `.venv`.
|
|
30
|
+
|
|
31
|
+
## Estado
|
|
32
|
+
|
|
33
|
+
| Notebook | Situação |
|
|
34
|
+
|---|---|
|
|
35
|
+
| 01_quickstart | roda (≈1–2 min com o orçamento padrão) |
|
|
36
|
+
| 03_finalize_and_persist | roda (≈3–6 min: dois `compare_models`) |
|
|
37
|
+
| 02_hybrid_selection | roda (≈1,5 min) |
|
|
38
|
+
| 04_rolling_one_step | roda (≈2,5–4,5 min) |
|
|
39
|
+
| 07_panel | roda |
|
|
40
|
+
| 08_advanced_families_and_tuning | roda (≈1 min) |
|
|
41
|
+
| 09_ablation | roda (≈55 min com o orçamento `small`); nos testes só com `AUTOHYBTS_RUN_HEAVY=1` |
|
|
42
|
+
| 05_benchmark_m4 | roda (≈25 s com cache; o primeiro download do M4 diário tem ~100 MB) |
|
|
43
|
+
| 06_compare_and_cross_validate | roda (≈50 s) |
|
|
44
|
+
| 10_external_models | roda (≈6 min); nos testes só com `AUTOHYBTS_RUN_HEAVY=1` |
|
|
45
|
+
| 11_calibration | roda (≈8 min) |
|
|
46
|
+
| 12_baselines_and_boosting | roda (≈1,5 min) |
|
|
47
|
+
| 13_ensembles | roda (≈4–5 min) |
|
|
48
|
+
| 14_intermittent_demand | roda (≈15 s) |
|
|
49
|
+
| 15_statsforecast | roda no ambiente com o extra `nixtla-stats` (pandas 2.x) |
|
|
50
|
+
|
|
51
|
+
O teste `tests/integration/test_notebooks.py` executa cada notebook assim que todos os nomes listados em `metadata.autohybts.requires` existem no pacote:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
.venv/Scripts/python -m pytest tests/integration/test_notebooks.py -m slow -rs
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Notebooks marcados `heavy` só rodam com `AUTOHYBTS_RUN_HEAVY=1`; um notebook cujos `extras` (declarados nos metadados) não estão instalados é pulado com o nome do que falta.
|
|
58
|
+
|
|
59
|
+
## Novo tutorial
|
|
60
|
+
|
|
61
|
+
O esqueleto no modelo de aula, com os metadados já no esquema, sai de:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
.venv/Scripts/python notebooks/new_notebook.py 15_temporal_bagging "Bagging temporal" --guide user_guide/ensembles --requires autohybts.AutoHybridExperiment.compare_models
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
As regras (seções, metadados, execução e saídas) estão em `documentation/contributing.rst`.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# AutoHybTS tutorials (English)
|
|
2
|
+
|
|
3
|
+
English copies of the tutorials in `notebooks/` (Portuguese), cell by cell, with the same code, metadata and outputs. Each notebook is PyCaret-4 style: short, numbered, one topic per notebook, using the object-oriented API (`AutoHybridExperiment`).
|
|
4
|
+
|
|
5
|
+
| Notebook | Content | Requires |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| [01_quickstart](01_quickstart.ipynb) | Load a series, compare models, forecast and evaluate on the sealed test | — |
|
|
8
|
+
| [02_hybrid_selection](02_hybrid_selection.ipynb) | Staged search, a hand-built hybrid, selection decisions, trial audit, diagnostics and events | — |
|
|
9
|
+
| [03_finalize_and_persist](03_finalize_and_persist.ipynb) | Finalize, evaluate once, save and load with a manifest, operational forecasting without a sealed test | — |
|
|
10
|
+
| [04_rolling_one_step](04_rolling_one_step.ipynb) | Variant B: one-step forecasting with frozen parameters and streaming observations | — |
|
|
11
|
+
| [05_benchmark_m4](05_benchmark_m4.ipynb) | M4 with the official test sealed, an M3 panel and Rdatasets (downloads the data on the first run) | network the first time; `datasets` extra for M3 |
|
|
12
|
+
| [06_compare_and_cross_validate](06_compare_and_cross_validate.ipynb) | Ranking of the finalists, temporal cross-validation, comparison plots, statistical tests, comparison on the sealed test and nested CV | — |
|
|
13
|
+
| [07_panel](07_panel.ipynb) | Several series in the same experiment: ranking across series, selection over the whole set, one model per series and external evaluation per series | — |
|
|
14
|
+
| [08_advanced_families_and_tuning](08_advanced_families_and_tuning.ipynb) | Extra stages, decomposition, fixed combination, search with every family and `tune_model` | — |
|
|
15
|
+
| [09_ablation](09_ablation.ipynb) | Ablation of the selection procedure (§30.5): 4 procedures, same budget and same external tests, on 12 synthetic series × 3 seeds, `small` budget | heavy (≈55 min) |
|
|
16
|
+
| [10_external_models](10_external_models.ipynb) | Your own models: PyTorch (LSTM, Transformer, Mamba, a GRU written on the spot), TensorFlow/Keras (LSTM, Transformer, convolution), statsmodels' Holt-Winters and gradient boosting, as bases, correctors, in the search, in tuning and in persistence | `torch` and `tensorflow` extras; heavy |
|
|
17
|
+
| [11_calibration](11_calibration.ipynb) | Calibration of the acceptance rule on controls with a known answer (white noise and predictable residual): false acceptances, rejected gains, effect of the number of origins and of the Wilcoxon test, confirmation set | — |
|
|
18
|
+
| [12_baselines_and_boosting](12_baselines_and_boosting.ipynb) | Baselines, boosting on lags (HistGradientBoosting, AdaBoost.R2, LightGBM, XGBoost, CatBoost) as bases and correctors, RMAE and fit counts | `boosting` extra |
|
|
19
|
+
| [13_ensembles](13_ensembles.ipynb) | Ensembles of complete candidates (mean, median, trimmed mean, inverse MSE, NNLS with shrinkage), ensemble of hybrids, corrected ensemble and ensembles in the search with the acceptance rule | — |
|
|
20
|
+
| [14_intermittent_demand](14_intermittent_demand.ipynb) | Intermittent demand: Croston-SBA, TSB, ADIDA and IMAPA against simple means, why RMSSE instead of MASE, rate changes, demand that stops and the `intermittent` family in the search | — |
|
|
21
|
+
| [15_statsforecast](15_statsforecast.ipynb) | StatsForecast's AutoARIMA, AutoETS, AutoTheta and AutoCES against statsmodels and baselines, frozen parameters (`forward`), the statistical-ANN hybrids of the replication and the search with these models | `nixtla-stats` extra (brings pandas 2.x) |
|
|
22
|
+
|
|
23
|
+
## How to run
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
.venv/Scripts/python -m pip install -e ".[dev,stats,notebook]"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
In VS Code, open the notebook and select the `.venv` kernel. Run the notebooks from this folder (`notebooks/en`); notebook 15 needs the environment with the `nixtla-stats` extra.
|
|
30
|
+
|
|
31
|
+
A change to a tutorial goes into both languages; `tests/contracts/test_docs_translation.py` checks that every Portuguese notebook has an English copy with the same metadata. The rules (sections, metadata, execution and outputs) are in `documentation/en/contributing.rst`.
|