02. Busca de híbridos e seleção incremental¶
A busca roda em estágios, sempre na validação temporal:
Bases individuais de várias famílias (estatística, linear, kernel, árvore, neural).
Retenção: as duas melhores de cada família, o ARIMA e a melhor base geral.
Híbridos residuais:
ŷ = base + α · corretor(resíduos), com corretores Linear, KNN e MLP, janelas de 7 ou 28 resíduos eα ∈ {0,5; 1}.Refinamento das duas melhores estruturas residuais.
Seleção incremental: cada família desafia o campeão atual e só o substitui com ganho mediano ≥ 5% e vitórias em ≥ 60% das origens (regra calibrada, ADR-0008).
Perfil quickstart: o critério de variabilidade do protocolo fica desligado, e isso aparece no relatório. O perfil research_strict exige esse critério definido.
import autohybts
print("AutoHybTS", autohybts.__version__)
AutoHybTS 1.0.0rc4
1. Dados e experimento¶
O ARIMA com ordem automática é o modelo mais caro; aqui ele aparece só nos exemplos manuais da seção 3, e a busca automática fica com os demais modelos.
budget limita o número de candidatas (total, por família e por etapa; max_trials substitui o total), então a mesma série e a mesma semente dão a mesma busca em qualquer máquina. Um prazo de relógio é opcional (max_wall_time_s=...): nenhuma candidata começa depois dele, e as que ficarem de fora aparecem no ledger como STOPPED.
progress=True mostra uma barra do tqdm por etapa da busca e outra para as finalistas em V_select (extra progress). É só relatório: as candidatas avaliadas e o campeão não mudam.
from autohybts import AutoHybridExperiment
from autohybts.datasets import get_data
y = get_data("synthetic_daily")
exp = AutoHybridExperiment(
fh=14,
session_id=42,
progress=True,
fold=3,
fold_strategy="expanding",
seasonal_period=7,
profile="quickstart",
base_models=["naive", "seasonal_naive", "linear", "knn", "mlp"],
correctors=["linear", "knn", "mlp"],
residual_windows=[7, 28],
residual_sources=["historical_oof_1step"],
alphas=[0.5, 1.0],
budget="small",
max_trials=40,
).fit(y)
exp.splits
| layer | train_start | origin | first_target | last_target | n_train | horizon | |
|---|---|---|---|---|---|---|---|
| fold_id | |||||||
| search-0 | search | 2024-01-01 | 2025-09-23 | 2025-09-24 | 2025-10-07 | 632 | 14 |
| search-1 | search | 2024-01-01 | 2025-10-07 | 2025-10-08 | 2025-10-21 | 646 | 14 |
| search-2 | search | 2024-01-01 | 2025-10-21 | 2025-10-22 | 2025-11-04 | 660 | 14 |
| select-0 | select | 2024-01-01 | 2025-11-04 | 2025-11-05 | 2025-11-18 | 674 | 14 |
| select-1 | select | 2024-01-01 | 2025-11-18 | 2025-11-19 | 2025-12-02 | 688 | 14 |
| select-2 | select | 2024-01-01 | 2025-12-02 | 2025-12-03 | 2025-12-16 | 702 | 14 |
2. Catálogo de modelos¶
exp.models()
| family | multi_step | online_state_update | in_sample_fitted | deterministic | requires_extra | training_scope | output_type | horizon_strategy | max_horizon | target_mode | accepts_exog | requires | version | description | ||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| kind | name | |||||||||||||||
| base | adaboost_r2 | tree | True | True | False | False | NaN | local | point | recursive | None | univariate | True | None | None | AdaBoost.R2 (scikit-learn) sobre lags. |
| adida | intermittent | True | True | False | True | NaN | local | point | recursive | None | univariate | False | None | None | ADIDA: suavização em blocos de k períodos. | |
| arima | statistical | True | True | True | True | stats | local | point | recursive | None | univariate | True | None | None | ARIMA (statsmodels); ordem automática por KPSS... | |
| catboost_regressor | tree | True | True | False | False | boosting | local | point | recursive | None | univariate | True | None | None | CatBoost sobre lags (extra boosting). | |
| croston_sba | intermittent | True | True | False | True | NaN | local | point | recursive | None | univariate | False | None | None | Croston-SBA: tamanho / intervalo entre demandas. | |
| elastic_net_regression | linear | True | True | False | True | NaN | local | point | recursive | None | univariate | True | None | None | Elastic Net sobre lags. | |
| exponential_smoothing | statistical | True | True | False | True | stats | local | point | recursive | None | univariate | False | None | None | Suavização exponencial aditiva (Holt, Holt-Win... | |
| extra_trees_regressor | tree | True | True | False | False | NaN | local | point | recursive | None | univariate | True | None | None | Árvores extremamente aleatórias sobre lags. | |
| harmonic_regression | statistical | True | True | False | True | NaN | local | point | recursive | None | univariate | False | None | None | Regressão harmônica dinâmica: tendência + Four... | |
| hist_gradient_boosting | tree | True | True | False | False | NaN | local | point | recursive | None | univariate | True | None | None | HistGradientBoosting (scikit-learn) sobre lags. | |
| historic_average | statistical | True | True | False | True | NaN | local | point | recursive | None | univariate | False | None | None | Média do treino (parâmetro congelado). | |
| imapa | intermittent | True | True | False | True | NaN | local | point | recursive | None | univariate | False | None | None | IMAPA: média do ADIDA nos níveis 1..k. | |
| knn | kernel | True | True | False | True | NaN | local | point | recursive | None | univariate | True | None | None | k vizinhos mais próximos sobre lags. | |
| lasso_regression | linear | True | True | False | True | NaN | local | point | recursive | None | univariate | True | None | None | Regressão Lasso sobre lags. | |
| lightgbm_regressor | tree | True | True | False | False | boosting | local | point | recursive | None | univariate | True | None | None | LightGBM sobre lags (extra boosting). | |
| linear | linear | True | True | False | True | NaN | local | point | recursive | None | univariate | True | None | None | Regressão linear sobre lags. | |
| mlp | neural | True | True | False | False | NaN | local | point | recursive | None | univariate | True | None | None | Perceptron multicamadas sobre lags. | |
| naive | statistical | True | True | False | True | NaN | local | point | recursive | None | univariate | False | None | None | Repete o último valor observado. | |
| random_forest | tree | True | True | False | False | NaN | local | point | recursive | None | univariate | True | None | None | Floresta aleatória sobre lags. | |
| random_walk_drift | statistical | True | True | False | True | NaN | local | point | recursive | None | univariate | False | None | None | Passeio aleatório com drift: último valor + h ... | |
| ridge_regression | linear | True | True | False | True | NaN | local | point | recursive | None | univariate | True | None | None | Regressão Ridge sobre lags. | |
| sarima | statistical | True | True | True | True | stats | local | point | recursive | None | univariate | True | None | None | ARIMA sazonal (statsmodels); D pela força sazo... | |
| seasonal_naive | statistical | True | True | False | True | NaN | local | point | recursive | None | univariate | False | None | None | Repete a última temporada (season_length). | |
| seasonal_window_average | statistical | True | True | False | True | NaN | local | point | recursive | None | univariate | False | None | None | Média de cada posição sazonal nas últimas wind... | |
| sf_auto_arima | statistical | True | True | False | True | nixtla-stats | local | point | recursive | None | univariate | False | None | None | AutoARIMA do StatsForecast (ordem automática, ... | |
| sf_auto_ces | statistical | True | True | False | True | nixtla-stats | local | point | recursive | None | univariate | False | None | None | AutoCES do StatsForecast (suavização exponenci... | |
| sf_auto_ets | statistical | True | True | False | True | nixtla-stats | local | point | recursive | None | univariate | False | None | None | AutoETS do StatsForecast (erro, tendência e sa... | |
| sf_auto_theta | statistical | True | True | False | True | nixtla-stats | local | point | recursive | None | univariate | False | None | None | AutoTheta do StatsForecast (variantes do métod... | |
| svm | kernel | True | True | False | True | NaN | local | point | recursive | None | univariate | True | None | None | SVR sobre lags. | |
| tree | tree | True | True | False | True | NaN | local | point | recursive | None | univariate | True | None | None | Árvore de decisão sobre lags. | |
| tsb | intermittent | True | True | False | True | NaN | local | point | recursive | None | univariate | False | None | None | TSB: probabilidade de demanda × tamanho. | |
| window_average | statistical | True | True | False | True | NaN | local | point | recursive | None | univariate | False | None | None | Média das últimas window observações. | |
| xgboost_regressor | tree | True | True | False | False | boosting | local | point | recursive | None | univariate | True | None | None | XGBoost sobre lags (extra boosting). | |
| corrector | adaboost_r2 | corrector | False | False | False | False | NaN | local | point | recursive | None | univariate | False | None | None | AdaBoost.R2 sobre janelas de resíduos. |
| arima_sequence | corrector | True | True | False | True | stats | local | point | recursive | None | univariate | False | None | None | ARIMA sobre a série de resíduos (horizonte int... | |
| catboost_regressor | corrector | False | False | False | False | boosting | local | point | recursive | None | univariate | False | None | None | CatBoost sobre janelas de resíduos (extra boos... | |
| exponential_smoothing_sequence | corrector | True | True | False | True | stats | local | point | recursive | None | univariate | False | None | None | Suavização exponencial sobre a série de resídu... | |
| hist_gradient_boosting | corrector | False | False | False | False | NaN | local | point | recursive | None | univariate | False | None | None | HistGradientBoosting sobre janelas de resíduos. | |
| knn | corrector | False | False | False | True | NaN | local | point | recursive | None | univariate | False | None | None | k vizinhos mais próximos sobre janelas de resí... | |
| lightgbm_regressor | corrector | False | False | False | False | boosting | local | point | recursive | None | univariate | False | None | None | LightGBM sobre janelas de resíduos (extra boos... | |
| linear | corrector | False | False | False | True | NaN | local | point | recursive | None | univariate | False | None | None | Regressão linear sobre janelas de resíduos. | |
| mlp | corrector | False | False | False | False | NaN | local | point | recursive | None | univariate | False | None | None | Perceptron multicamadas sobre janelas de resíd... | |
| random_forest | corrector | False | False | False | False | NaN | local | point | recursive | None | univariate | False | None | None | Floresta aleatória sobre janelas de resíduos. | |
| svm | corrector | False | False | False | True | NaN | local | point | recursive | None | univariate | False | None | None | SVR sobre janelas de resíduos. | |
| tree | corrector | False | False | False | True | NaN | local | point | recursive | None | univariate | False | None | None | Árvore de decisão sobre janelas de resíduos. | |
| xgboost_regressor | corrector | False | False | False | False | boosting | local | point | recursive | None | univariate | False | None | None | XGBoost sobre janelas de resíduos (extra boost... |
3. Um modelo individual e um híbrido montado à mão¶
Útil para entender as peças antes da busca automática. Os resíduos do corretor são erros de previsão fora da amostra (historical_oof_1step), nunca valores ajustados no próprio treino.
arima = exp.create_model("arima")
arima.cv_results
| layer | status | MASE | MAE | RMSE | sMAPE | |
|---|---|---|---|---|---|---|
| search-0 | search | SUCCEEDED | 1.846794 | 2.865174 | 3.100497 | 0.040837 |
| search-1 | search | SUCCEEDED | 0.554999 | 0.861073 | 1.100535 | 0.012383 |
| search-2 | search | SUCCEEDED | 1.668095 | 2.569822 | 2.698243 | 0.037090 |
| select-0 | select | SUCCEEDED | 2.174782 | 3.346846 | 3.488244 | 0.047806 |
| select-1 | select | SUCCEEDED | 2.195924 | 3.418777 | 3.807198 | 0.048332 |
| select-2 | select | SUCCEEDED | 0.387069 | 0.607182 | 0.739234 | 0.008558 |
| Mean | NaN | NaN | 1.471277 | 2.278146 | 2.488992 | 0.032501 |
| Std | NaN | NaN | 0.801855 | 1.238794 | 1.276195 | 0.017626 |
hybrid = exp.create_hybrid(
base="arima",
corrector="mlp",
window=7,
alpha=1.0,
residual_source="historical_oof_1step",
)
hybrid.cv_results
| layer | status | MASE | MAE | RMSE | sMAPE | |
|---|---|---|---|---|---|---|
| search-0 | search | SUCCEEDED | 1.866445 | 2.895661 | 3.093652 | 0.041158 |
| search-1 | search | SUCCEEDED | 0.555764 | 0.862260 | 1.086767 | 0.012409 |
| search-2 | search | SUCCEEDED | 1.668606 | 2.570609 | 2.692855 | 0.037114 |
| select-0 | select | SUCCEEDED | 2.083504 | 3.206376 | 3.343848 | 0.045730 |
| select-1 | select | SUCCEEDED | 2.161925 | 3.365846 | 3.776502 | 0.047617 |
| select-2 | select | SUCCEEDED | 0.365805 | 0.573826 | 0.722414 | 0.008059 |
| Mean | NaN | NaN | 1.450342 | 2.245763 | 2.452673 | 0.032015 |
| Std | NaN | NaN | 0.787974 | 1.217761 | 1.254970 | 0.017317 |
4. Busca automática¶
result = exp.compare_models(include=["standalone", "residual"], sort="MASE")
result.leaderboard
busca S0 bases: 0%| | 0/5 [00:00<?, ?cand/s]
busca S0 bases: 80%|████████ | 4/5 [00:00<00:00, 25.08cand/s]
busca S0 bases: 100%|██████████| 5/5 [00:00<00:00, 5.07cand/s]
busca S2 resíduos: 0%| | 0/11 [00:00<?, ?cand/s]
busca S2 resíduos: 9%|▉ | 1/11 [00:02<00:20, 2.08s/cand]
busca S2 resíduos: 18%|█▊ | 2/11 [00:03<00:13, 1.52s/cand]
busca S2 resíduos: 27%|██▋ | 3/11 [00:03<00:07, 1.11cand/s]
busca S2 resíduos: 36%|███▋ | 4/11 [00:03<00:05, 1.35cand/s]
busca S2 resíduos: 45%|████▌ | 5/11 [00:04<00:03, 1.85cand/s]
busca S2 resíduos: 55%|█████▍ | 6/11 [00:05<00:04, 1.21cand/s]
busca S2 resíduos: 64%|██████▎ | 7/11 [00:06<00:03, 1.15cand/s]
busca S2 resíduos: 73%|███████▎ | 8/11 [00:06<00:01, 1.54cand/s]
busca S2 resíduos: 82%|████████▏ | 9/11 [00:07<00:01, 1.64cand/s]
busca S2 resíduos: 91%|█████████ | 10/11 [00:07<00:00, 2.04cand/s]
busca S2 resíduos: 100%|██████████| 11/11 [00:08<00:00, 1.23cand/s]
busca S2 resíduos: 100%|██████████| 11/11 [00:08<00:00, 1.24cand/s]
busca S3 refino: 0%| | 0/2 [00:00<?, ?cand/s]
busca S3 refino: 50%|█████ | 1/2 [00:02<00:02, 2.08s/cand]
busca S3 refino: 100%|██████████| 2/2 [00:02<00:00, 1.05cand/s]
busca S3 refino: 100%|██████████| 2/2 [00:02<00:00, 1.12s/cand]
seleção V_select: 0%| | 0/5 [00:00<?, ?cand/s]
seleção V_select: 20%|██ | 1/5 [00:00<00:01, 2.12cand/s]
seleção V_select: 40%|████ | 2/5 [00:01<00:02, 1.07cand/s]
seleção V_select: 100%|██████████| 5/5 [00:01<00:00, 2.80cand/s]
| name | model | family | strategy | base | corrector | residual_source | window | alpha | mean_rank | ... | MAE | RMSE | sMAPE | coverage | n_units | n_failed | n_skipped | fit_seconds | predict_seconds | is_champion | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| candidate_id | |||||||||||||||||||||
| 7dd1082a4ee4fe9df20683376c5688b4a23322240929c4c44a8140e266a10ae2 | mlp | mlp(lags=7) | neural | standalone | mlp | NaN | NaN | NaN | NaN | 1.0 | ... | 1.329098 | 1.590181 | 0.019224 | 1.0 | 3 | 0 | 0 | 0.807899 | 0.017187 | False |
| 9fd962cca51322c0e3697027ac96d1fa8d35c2672647b0030737ef663dde6df6 | mlp-linear | mlp(lags=7) + linear [w=7, alpha=0.5, historic... | residual | residual_additive | mlp | linear | historical_oof_1step | 7.0 | 0.5 | 2.0 | ... | 1.335050 | 1.622713 | 0.019335 | 1.0 | 3 | 0 | 0 | 2.061273 | 0.012969 | True |
| 459af2c77fe43d1936669c337e695b972b6de79264cfa329ed349dfc20dc5172 | mlp-linear | mlp(lags=7) + linear [w=28, alpha=0.5, histori... | residual | residual_additive | mlp | linear | historical_oof_1step | 28.0 | 0.5 | 3.0 | ... | 1.536977 | 1.800618 | 0.022398 | 1.0 | 3 | 0 | 0 | 1.533249 | 0.012512 | False |
| 70ad174e1cc49eb256646399fb3e4b7d9df82f14f2978d09d35dac0019c7ef37 | knn | knn(lags=7) | kernel | standalone | knn | NaN | NaN | NaN | NaN | 4.0 | ... | 1.563061 | 1.966950 | 0.022621 | 1.0 | 3 | 0 | 0 | 0.050587 | 0.036638 | False |
| d90528888825a4459816afbcf249ff909747924f0a2bbaa6e09d027e31342238 | seasonal_naive | seasonal_naive(season_length=7) | statistical | standalone | seasonal_naive | NaN | NaN | NaN | NaN | 5.0 | ... | 1.614291 | 1.909265 | 0.023346 | 1.0 | 3 | 0 | 0 | 0.000080 | 0.000144 | False |
| e9e747a9648ad8d377f20122dce611a43dd3bf85a64c950a8e1ef246ebc032b4 | linear | linear(lags=7) | linear | standalone | linear | NaN | NaN | NaN | NaN | 6.0 | ... | 1.649719 | 1.852607 | 0.023763 | 1.0 | 3 | 0 | 0 | 0.057596 | 0.008549 | False |
| 773d3b8c8d625571d4d4b4f4aa234d9f88b9b7fc0ceb3101c126e49e100378fc | seasonal_naive-linear | seasonal_naive(season_length=7) + linear [w=7,... | residual | residual_additive | seasonal_naive | linear | historical_oof_1step | 7.0 | 0.5 | 7.0 | ... | 1.673298 | 1.998234 | 0.024205 | 1.0 | 3 | 0 | 0 | 0.164522 | 0.005550 | False |
| c4821c0a39e39a26ca17be31d8298f1ebcaed90d98e0a1fd3722f7c6ed592f9b | linear-linear | linear(lags=7) + linear [w=7, alpha=0.5, histo... | residual | residual_additive | linear | linear | historical_oof_1step | 7.0 | 0.5 | 8.0 | ... | 1.698826 | 1.914754 | 0.024472 | 1.0 | 3 | 0 | 0 | 0.481665 | 0.012821 | False |
| 972a9d57c62d5265bf431a410bf8ccd45ae226f2e6bb124bc9d763258cbdbae4 | mlp-linear | mlp(lags=7) + linear [w=7, alpha=1.0, historic... | residual | residual_additive | mlp | linear | historical_oof_1step | 7.0 | 1.0 | 9.0 | ... | 1.725096 | 2.009527 | 0.024833 | 1.0 | 3 | 0 | 0 | 1.366397 | 0.012967 | False |
| b678627c69f0bc5eb419617a2119103a8a5340ac96c0551898c62a1d76dc0179 | linear-linear | linear(lags=7) + linear [w=7, alpha=1.0, histo... | residual | residual_additive | linear | linear | historical_oof_1step | 7.0 | 1.0 | 10.0 | ... | 1.748087 | 1.988548 | 0.025178 | 1.0 | 3 | 0 | 0 | 0.504137 | 0.018069 | False |
| 507265ea41efe47e82119ba51bc162c1cd983e9fd72f0a1b25e7ca1c8d95b229 | seasonal_naive-linear | seasonal_naive(season_length=7) + linear [w=7,... | residual | residual_additive | seasonal_naive | linear | historical_oof_1step | 7.0 | 1.0 | 11.0 | ... | 1.768259 | 2.152438 | 0.025573 | 1.0 | 3 | 0 | 0 | 0.159355 | 0.005538 | False |
| bbd8aa955229e78f79ee95ec40b350010922f578702fd6a464ea2ea729023f34 | seasonal_naive-linear | seasonal_naive(season_length=7) + linear [w=7,... | residual | residual_additive | seasonal_naive | linear | historical_oof_multistep | 7.0 | 0.5 | 12.0 | ... | 2.617302 | 2.887196 | 0.037349 | 1.0 | 3 | 0 | 0 | 0.148647 | 0.006292 | False |
| 60fa40d778d88419b30bab18cd7f1fd7cad8e46e100cfe53d3a7b3f2fcc845b4 | naive-linear | naive + linear [w=7, alpha=1.0, historical_oof... | residual | residual_additive | naive | linear | historical_oof_1step | 7.0 | 1.0 | 13.0 | ... | 3.903393 | 4.441350 | 0.055259 | 1.0 | 3 | 0 | 0 | 0.210182 | 0.009204 | False |
| b78538dee2cc85795a8cc90439de94a964e7a02a28eff7a3f960c947a2e9e699 | naive-linear | naive + linear [w=7, alpha=0.5, historical_oof... | residual | residual_additive | naive | linear | historical_oof_1step | 7.0 | 0.5 | 14.0 | ... | 3.916747 | 4.375241 | 0.055684 | 1.0 | 3 | 0 | 0 | 0.174942 | 0.005655 | False |
| 2117d1027abc8c33b855cff511914a6917df041e30dd98281ad26a716bae3b78 | naive | naive | statistical | standalone | naive | NaN | NaN | NaN | NaN | 15.0 | ... | 3.961290 | 4.498781 | 0.056375 | 1.0 | 3 | 0 | 0 | 0.000119 | 0.000137 | False |
| bf5bff5cb0bc3a6ce953ea9188dae5a44f9f780d655ab31857957fa89a1f2250 | knn-linear | knn(lags=7) + linear [w=7, alpha=0.5, historic... | residual | residual_additive | knn | linear | historical_oof_1step | 7.0 | 0.5 | 16.0 | ... | 4.072110 | 4.339678 | 0.057173 | 1.0 | 3 | 0 | 0 | 1.077592 | 0.042116 | False |
| 747968575a6cd0d95bbee95e83321806fed5a85e1007f47989c2adf289a7f495 | mlp-linear | mlp(lags=7) + linear [w=7, alpha=0.5, historic... | residual | residual_additive | mlp | linear | historical_oof_multistep | 7.0 | 0.5 | 17.0 | ... | 4.429702 | 4.649585 | 0.061832 | 1.0 | 3 | 0 | 0 | 2.063942 | 0.014461 | False |
| df3ec82ac4a2623a390d9a7ee621e53fda49f4f8b54f4d411b38c569f7b2af05 | knn-linear | knn(lags=7) + linear [w=7, alpha=1.0, historic... | residual | residual_additive | knn | linear | historical_oof_1step | 7.0 | 1.0 | 18.0 | ... | 8.484694 | 8.671081 | 0.115437 | 1.0 | 3 | 0 | 0 | 0.925168 | 0.036879 | False |
18 rows × 21 columns
5. Por que o campeão venceu¶
decisions lista cada desafiante, se foi aceito, o ganho mediano, a taxa de vitórias e os motivos. Rejeições também ficam registradas. audit conta todas as tentativas, inclusive as podadas e as que falharam.
Este notebook usa fold=3 para rodar rápido: são 3 unidades em V_select, e 60% de vitórias exige vencer 2 das 3. Com tão poucas unidades a regra é um protocolo, não um teste estatístico. O padrão fold="auto" usa 7 origens quando a série comporta, o número em que a regra foi calibrada; o notebook 11 mede quantas vezes cada configuração aceita um híbrido espúrio.
result.decisions
| family | champion_before | challenger | accepted | reason_codes | median_gain | win_rate | variability_status | variability_value | p_value | challenger_coverage | challenger_label | champion_before_id | challenger_id | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | statistical | mlp | seasonal_naive | False | (median_gain_below_threshold,) | 0.034103 | 0.666667 | disabled | None | None | 1.0 | seasonal_naive(season_length=7) | 7dd1082a4ee4fe9df20683376c5688b4a23322240929c4... | d90528888825a4459816afbcf249ff909747924f0a2bba... |
| 1 | linear | mlp | linear | False | (median_gain_below_threshold, win_rate_below_t... | -0.026810 | 0.333333 | disabled | None | None | 1.0 | linear(lags=7) | 7dd1082a4ee4fe9df20683376c5688b4a23322240929c4... | e9e747a9648ad8d377f20122dce611a43dd3bf85a64c95... |
| 2 | kernel | mlp | knn | False | (median_gain_below_threshold, win_rate_below_t... | -0.109042 | 0.333333 | disabled | None | None | 1.0 | knn(lags=7) | 7dd1082a4ee4fe9df20683376c5688b4a23322240929c4... | 70ad174e1cc49eb256646399fb3e4b7d9df82f14f2978d... |
| 3 | residual | mlp | mlp-linear | True | (accepted,) | 0.142037 | 0.666667 | disabled | None | None | 1.0 | mlp(lags=7) + linear [w=7, alpha=0.5, historic... | 7dd1082a4ee4fe9df20683376c5688b4a23322240929c4... | 9fd962cca51322c0e3697027ac96d1fa8d35c2672647b0... |
Tudo o que cada decisão usou, unidade por unidade: os dois erros, o ganho e se houve vitória (empate não conta). Dá para recalcular o ganho mediano e a taxa de vitórias, ou reamostrar, fora da biblioteca.
units = result.selection.decision_units_frame()
units[units["family"] == "residual"].round(4)
| family | challenger_id | accepted | unit_id | series_id | champion_error | challenger_error | gain | win | |
|---|---|---|---|---|---|---|---|---|---|
| 9 | residual | 9fd962cca51322c0e3697027ac96d1fa8d35c2672647b0... | True | select-0 | None | 2.3449 | 2.0119 | 0.1420 | True |
| 10 | residual | 9fd962cca51322c0e3697027ac96d1fa8d35c2672647b0... | True | select-1 | None | 1.2018 | 1.6898 | -0.4061 | False |
| 11 | residual | 9fd962cca51322c0e3697027ac96d1fa8d35c2672647b0... | True | select-2 | None | 1.5715 | 1.1243 | 0.2846 | True |
result.audit
SelectionAudit(protocol_hash='aa88c5a5ada48e7970d42ca6d46bace46c42668c9f6b3ad47986044ed0787f56', search_protocol_hash='dd40456eb2da818cf575c202bb45b3c9f8473119d8df55ac0ae006dbd977e0d3', total_trials=18, tried_by_family={'statistical': 2, 'linear': 1, 'kernel': 1, 'neural': 1, 'residual': 13}, pruned_trials=49, failed_trials=0, finalist_ids=('7dd1082a4ee4fe9df20683376c5688b4a23322240929c4c44a8140e266a10ae2', '9fd962cca51322c0e3697027ac96d1fa8d35c2672647b0030737ef663dde6df6', '70ad174e1cc49eb256646399fb3e4b7d9df82f14f2978d09d35dac0019c7ef37', 'd90528888825a4459816afbcf249ff909747924f0a2bbaa6e09d027e31342238', 'e9e747a9648ad8d377f20122dce611a43dd3bf85a64c950a8e1ef246ebc032b4'), winner_id='9fd962cca51322c0e3697027ac96d1fa8d35c2672647b0030737ef663dde6df6', comparison_origin_ids=('select-0', 'select-1', 'select-2'), decision_reasons=('statistical: median_gain_below_threshold', 'linear: median_gain_below_threshold+win_rate_below_threshold', 'kernel: median_gain_below_threshold+win_rate_below_threshold', 'residual: accepted'), exploratory=False, search_best_score=0.8585660174722802, winner_search_score=0.8628987716271869, winner_select_score=1.6086533406757795)
6. Diagnósticos da validação¶
Todos os gráficos usam previsões fora da amostra nas origens de validação, nunca o teste selado.
exp.plot_model(result.best, plot="cv_forecasts")
exp.plot_model(result.best, plot="residuals")
exp.plot_model(result.best, plot="selection_trace")
7. Eventos do experimento¶
for event in exp.events:
duration = f"{event.duration_ms:9.1f} ms" if event.duration_ms else " " * 12
print(f"{event.kind:32s} {duration} {event.message}")
experiment.fitted 38.7 ms 1 série(s), 716 pontos de desenvolvimento, teste selado de 14 por série, 6 origens
model.created 30679.7 ms arima
hybrid.created 21592.0 ms arima + mlp [w=7, alpha=1.0, historical_oof_1step]
search.finished 12167.0 ms 18 tentativas (budget_limited)
selection.finished 1817.0 ms campeão: mlp(lags=7) + linear [w=7, alpha=0.5, historical_oof_1step]