import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import numpy.testing as testing
from darts import TimeSeries
from darts.datasets import AirPassengersDataset
Darts
= AirPassengersDataset().load()
series series.plot()
= series.split_before(0.75)
series1, series2
series1.plot() series2.plot()
= series[:-36], series[-36:]
series1, series2
series1.plot() series2.plot()
= TimeSeries.from_times_and_values(
series_noise len(series))
series.time_index, np.random.randn(
)/ 2 + 20 * series_noise - 10).plot() (series
/ 50).stack(series_noise).plot() (series
map(np.log).plot() series.
map(lambda ts, x: x / ts.days_in_month).plot() series.
/ 20).add_datetime_attribute("month").plot() (series
/ 200).add_holidays("US").plot() (series
series.diff().plot()
from darts.utils.missing_values import fill_missing_values
= np.arange(50, step=0.5)
values 10:30] = np.nan
values[60:95] = np.nan
values[= TimeSeries.from_values(values)
series_
- 10).plot(label="with missing values (shifted below)")
(series_ ="without missing values") fill_missing_values(series_).plot(label
= series.split_before(pd.Timestamp("19580101"))
train, val ="training")
train.plot(label="validation") val.plot(label
Training forecasting models and making predictions
from darts.models import NaiveSeasonal
/home/thekkel/mambaforge/envs/cfast/lib/python3.11/site-packages/neptune/internal/backends/hosted_client.py:51: NeptuneDeprecationWarning: The 'neptune-client' package has been deprecated and will be removed in the future. Install the 'neptune' package instead. For more, see https://docs.neptune.ai/setup/upgrading/
from neptune.version import version as neptune_client_version
/home/thekkel/mambaforge/envs/cfast/lib/python3.11/site-packages/pytorch_lightning/loggers/neptune.py:51: NeptuneDeprecationWarning: You're importing the Neptune client library via the deprecated `neptune.new` module, which will be removed in a future release. Import directly from `neptune` instead.
import neptune.new as neptune
= NaiveSeasonal(K=1)
naive_model
naive_model.fit(train)= naive_model.predict(36)
naive_forecast
="actual")
series.plot(label="naive forecast (K=1)") naive_forecast.plot(label
Inspect Seasonality
from darts.utils.statistics import plot_acf, check_seasonality
=12, alpha=0.05) plot_acf(train, m
for m in range(2, 25):
= check_seasonality(train, m=m, alpha=0.05)
is_seasonal, period if is_seasonal:
print("There is seasonality of order {}.".format(period))
There is seasonality of order 12.
= NaiveSeasonal(K=12)
seasonal_model
seasonal_model.fit(train)= seasonal_model.predict(36)
seasonal_forecast
="actual")
series.plot(label="naive forecast (K=12)") seasonal_forecast.plot(label
from darts.models import NaiveDrift
= NaiveDrift()
drift_model
drift_model.fit(train)= drift_model.predict(36)
drift_forecast
= drift_forecast + seasonal_forecast - train.last_value()
combined_forecast
series.plot()="combined")
combined_forecast.plot(label="drift") drift_forecast.plot(label
from darts.metrics import mape
print(
"Mean absolute percentage error for the combined naive drift + seasonal: {:.2f}%.".format(
mape(series, combined_forecast)
) )
Mean absolute percentage error for the combined naive drift + seasonal: 5.66%.
from darts.models import ExponentialSmoothing, TBATS, AutoARIMA, Theta
def eval_model(model):
model.fit(train)= model.predict(len(val))
forecast print("model {} obtains MAPE: {:.2f}%".format(model, mape(val, forecast)))
= str(model))
forecast.plot(label
-40:].plot(label="Orginal")
series[
eval_model(ExponentialSmoothing())
eval_model(TBATS())
eval_model(AutoARIMA()) eval_model(Theta())
model ExponentialSmoothing() obtains MAPE: 5.11%
model TBATS() obtains MAPE: 5.87%
model AutoARIMA() obtains MAPE: 11.65%
model Theta() obtains MAPE: 8.15%
Searching for hyper-parameters with the Theta method¶
# Search for the best theta parameter, by trying 50 different values
= 2 - np.linspace(-10, 10, 50)
thetas
= float("inf")
best_mape = 0
best_theta
for theta in thetas:
= Theta(theta)
model
model.fit(train)= model.predict(len(val))
pred_theta = mape(val, pred_theta)
res
if res < best_mape:
= res
best_mape = theta best_theta
= Theta(best_theta)
best_theta_model
best_theta_model.fit(train)= best_theta_model.predict(len(val))
pred_best_theta
print(
"The MAPE is: {:.2f}, with theta = {}.".format(
mape(val, pred_best_theta), best_theta
) )
The MAPE is: 4.40, with theta = -3.5102040816326543.
="train")
train.plot(label="true")
val.plot(label="prediction") pred_best_theta.plot(label
Backtesting: simulate historical forecasting
= best_theta_model.historical_forecasts(
historical_fcast_theta =0.6, forecast_horizon=3, verbose=True
series, start
)
="data")
series.plot(label="backtest 3-months ahead forecast (Theta)")
historical_fcast_theta.plot(labelprint("MAPE = {:.2f}%".format(mape(historical_fcast_theta, series)))
MAPE = 7.70%
= Theta(best_theta)
best_theta_model
= best_theta_model.backtest(
raw_errors =0.6, forecast_horizon=3, metric=mape, reduction=None, verbose=True
series, start
)
from darts.utils.statistics import plot_hist
plot_hist(
raw_errors,=np.arange(0, max(raw_errors), 1),
bins="Individual backtest error scores (histogram)",
title )
= best_theta_model.backtest(
average_error
series,=0.6,
start=3,
forecast_horizon=mape,
metric=np.mean, # this is actually the default
reduction=True,
verbose
)
print("Average error (MAPE) over all historical forecasts: %.2f" % average_error)
Average error (MAPE) over all historical forecasts: 6.36
from darts.utils.statistics import plot_residuals_analysis
plot_residuals_analysis(best_theta_model.residuals(series))
= ExponentialSmoothing(seasonal_periods=12)
model_es = model_es.historical_forecasts(
historical_fcast_es =0.6, forecast_horizon=3, verbose=True
series, start
)
="data")
series.plot(label="backtest 3-months ahead forecast (Exp. Smoothing)")
historical_fcast_es.plot(labelprint("MAPE = {:.2f}%".format(mape(historical_fcast_es, series)))
MAPE = 4.45%
plot_residuals_analysis(model_es.residuals(series))
Machine learning and global models
RegressionModel can wrap around any sklearn-compatible regression model to produce forecasts (it has its own section below).
RNNModel is a flexible RNN implementation, which can be used like DeepAR.
NBEATSModel implements the N-BEATS model.
TFTModel implements the Temporal Fusion Transformer model.
TCNModel implements temporal convolutional networks.
from darts.datasets import AirPassengersDataset, MonthlyMilkDataset
= AirPassengersDataset().load().astype(np.float32)
series_air = MonthlyMilkDataset().load().astype(np.float32)
series_milk
# set aside last 36 months of each series as validation set:
= series_air[:-36], series_air[-36:]
train_air, val_air = series_milk[:-36], series_milk[-36:]
train_milk, val_milk
train_air.plot()
val_air.plot()
train_milk.plot() val_milk.plot()
from darts.dataprocessing.transformers import Scaler
= Scaler()
scaler = scaler.fit_transform([train_air, train_milk])
train_air_scaled, train_milk_scaled
train_air_scaled.plot() train_milk_scaled.plot()
Using deep learning: example with N-BEATS
from darts.models import NBEATSModel
= NBEATSModel(input_chunk_length=24, output_chunk_length=12, random_state=42)
model
=50, verbose=True); model.fit([train_air_scaled, train_milk_scaled], epochs
GPU available: True (cuda), used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
HPU available: False, using: 0 HPUs
You are using a CUDA device ('NVIDIA GeForce RTX 3060') that has Tensor Cores. To properly utilize them, you should set `torch.set_float32_matmul_precision('medium' | 'high')` which will trade-off precision for performance. For more details, read https://pytorch.org/docs/stable/generated/torch.set_float32_matmul_precision.html#torch.set_float32_matmul_precision
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]
| Name | Type | Params
---------------------------------------------------
0 | criterion | MSELoss | 0
1 | train_metrics | MetricCollection | 0
2 | val_metrics | MetricCollection | 0
3 | stacks | ModuleList | 6.2 M
---------------------------------------------------
6.2 M Trainable params
1.4 K Non-trainable params
6.2 M Total params
24.787 Total estimated model params size (MB)
`Trainer.fit` stopped: `max_epochs=50` reached.
= model.predict(series=train_air_scaled, n=36)
pred_air = model.predict(series=train_milk_scaled, n=36)
pred_milk
# scale back:
= scaler.inverse_transform([pred_air, pred_milk])
pred_air, pred_milk
=(10, 6))
plt.figure(figsize="actual (air)")
series_air.plot(label="actual (milk)")
series_milk.plot(label="forecast (air)")
pred_air.plot(label="forecast (milk)") pred_milk.plot(label
GPU available: True (cuda), used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
HPU available: False, using: 0 HPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]
GPU available: True (cuda), used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
HPU available: False, using: 0 HPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]
Covariates: using external data
past_covariates are series not necessarily known ahead of the forecast time. Those can for instance represent things that have to be measured and are not known upfront. Models do not use the future values of past_covariates when making forecasts.
future_covariates are series which are known in advance, up to the forecast horizon. This can represent things such as calendar information, holidays, weather forecasts, etc. Models that accept future_covariates will look at the future values (up to the forecast horizon) when making forecasts.
from darts import concatenate
from darts.utils.timeseries_generation import datetime_attribute_timeseries as dt_attr
= concatenate(
air_covs
["month", dtype=np.float32) / 12,
dt_attr(series_air.time_index, "year", dtype=np.float32) - 1948) / 12,
(dt_attr(series_air.time_index,
],="component",
axis
)
= concatenate(
milk_covs
["month", dtype=np.float32) / 12,
dt_attr(series_milk.time_index, "year", dtype=np.float32) - 1962) / 13,
(dt_attr(series_milk.time_index,
],="component",
axis
)
air_covs.plot()
plt.title("one multivariate time series of 2 dimensions, containing covariates for the air series:"
; )
= NBEATSModel(input_chunk_length=24, output_chunk_length=12, random_state=42)
model
model.fit(
[train_air_scaled, train_milk_scaled],=[air_covs, milk_covs],
past_covariates=50,
epochs=True,
verbose; )
GPU available: True (cuda), used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
HPU available: False, using: 0 HPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]
| Name | Type | Params
---------------------------------------------------
0 | criterion | MSELoss | 0
1 | train_metrics | MetricCollection | 0
2 | val_metrics | MetricCollection | 0
3 | stacks | ModuleList | 6.6 M
---------------------------------------------------
6.6 M Trainable params
1.7 K Non-trainable params
6.6 M Total params
26.314 Total estimated model params size (MB)
`Trainer.fit` stopped: `max_epochs=50` reached.
= model.predict(series=train_air_scaled, past_covariates=air_covs, n=36)
pred_air = model.predict(series=train_milk_scaled, past_covariates=milk_covs, n=36)
pred_milk
# scale back:
= scaler.inverse_transform([pred_air, pred_milk])
pred_air, pred_milk
=(10, 6))
plt.figure(figsize="actual (air)")
series_air.plot(label="actual (milk)")
series_milk.plot(label="forecast (air)")
pred_air.plot(label="forecast (milk)") pred_milk.plot(label
`predict()` was called with `n > output_chunk_length`: using auto-regression to forecast the values after `output_chunk_length` points. The model will access `(n - output_chunk_length)` future values of your `past_covariates` (relative to the first predicted time step). To hide this warning, set `show_warnings=False`.
GPU available: True (cuda), used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
HPU available: False, using: 0 HPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]
`predict()` was called with `n > output_chunk_length`: using auto-regression to forecast the values after `output_chunk_length` points. The model will access `(n - output_chunk_length)` future values of your `past_covariates` (relative to the first predicted time step). To hide this warning, set `show_warnings=False`.
GPU available: True (cuda), used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
HPU available: False, using: 0 HPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]
Encoders: using covariates for free
def extract_year(idx):
"""Extract the year each time index entry and normalized it."""
return (idx.year - 1950) / 50
= {
encoders "cyclic": {"future": ["month"]},
"datetime_attribute": {"future": ["hour", "dayofweek"]},
"position": {"past": ["absolute"], "future": ["relative"]},
"custom": {"past": [extract_year]},
"transformer": Scaler(),
}
= {"datetime_attribute": {"past": ["month", "year"]}, "transformer": Scaler()} encoders
= NBEATSModel(
model =24,
input_chunk_length=12,
output_chunk_length=encoders,
add_encoders=42,
random_state
)
=50, verbose=True); model.fit([train_air_scaled, train_milk_scaled], epochs
GPU available: True (cuda), used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
HPU available: False, using: 0 HPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]
| Name | Type | Params
---------------------------------------------------
0 | criterion | MSELoss | 0
1 | train_metrics | MetricCollection | 0
2 | val_metrics | MetricCollection | 0
3 | stacks | ModuleList | 6.6 M
---------------------------------------------------
6.6 M Trainable params
1.7 K Non-trainable params
6.6 M Total params
26.314 Total estimated model params size (MB)
`Trainer.fit` stopped: `max_epochs=50` reached.
= model.predict(series=train_air_scaled, n=36)
pred_air
# scale back:
= scaler.inverse_transform(pred_air)
pred_air
=(10, 6))
plt.figure(figsize="actual (air)")
series_air.plot(label="forecast (air)") pred_air.plot(label
`predict()` was called with `n > output_chunk_length`: using auto-regression to forecast the values after `output_chunk_length` points. The model will access `(n - output_chunk_length)` future values of your `past_covariates` (relative to the first predicted time step). To hide this warning, set `show_warnings=False`.
GPU available: True (cuda), used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
HPU available: False, using: 0 HPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]
Regression forecasting models
from darts.models import RegressionModel
from sklearn.linear_model import BayesianRidge
= RegressionModel(lags=72, lags_future_covariates=[-6, 0], model=BayesianRidge())
model
model.fit(=[air_covs, milk_covs]
[train_air_scaled, train_milk_scaled], future_covariates; )
= model.predict(
pred_air, pred_milk =[train_air_scaled, train_milk_scaled],
series=[air_covs, milk_covs],
future_covariates=36,
n
)
# scale back:
= scaler.inverse_transform([pred_air, pred_milk])
pred_air, pred_milk
=(10, 6))
plt.figure(figsize="actual (air)")
series_air.plot(label="actual (milk)")
series_milk.plot(label="forecast (air)")
pred_air.plot(label="forecast (milk)") pred_milk.plot(label
mape([series_air, series_milk], [pred_air, pred_milk])
[3.417016565799713, 5.283146351575851]
=np.mean) mape([series_air, series_milk], [pred_air, pred_milk], inter_reduction
4.350081458687782
= RegressionModel(
bayes_ridge_model =72, lags_future_covariates=[0], model=BayesianRidge()
lags
)
= bayes_ridge_model.historical_forecasts(
backtest =air_covs, start=0.6, forecast_horizon=3, verbose=True
series_air, future_covariates
)
print("MAPE = %.2f" % (mape(backtest, series_air)))
series_air.plot() backtest.plot()
`enable_optimization=True` is ignored because `retrain` is not `False` or `0`.To hide this warning, set `show_warnings=False` or `enable_optimization=False`.
`enable_optimization=True` is ignored because `forecast_horizon > model.output_chunk_length`.To hide this warning, set `show_warnings=False` or `enable_optimization=False`.
MAPE = 3.66
Probabilistic forecasts
= ExponentialSmoothing()
model_es
model_es.fit(train)= model_es.predict(len(val), num_samples=500)
probabilistic_forecast
="actual")
series.plot(label="probabilistic forecast")
probabilistic_forecast.plot(label
plt.legend() plt.show()
With neural networks
from darts.models import TCNModel
from darts.utils.likelihood_models import LaplaceLikelihood
= TCNModel(
model =24,
input_chunk_length=12,
output_chunk_length=42,
random_state=LaplaceLikelihood(),
likelihood
)
=400, verbose=True); model.fit(train_air_scaled, epochs
GPU available: True (cuda), used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
HPU available: False, using: 0 HPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]
| Name | Type | Params
----------------------------------------------------
0 | criterion | MSELoss | 0
1 | train_metrics | MetricCollection | 0
2 | val_metrics | MetricCollection | 0
3 | dropout | MonteCarloDropout | 0
4 | res_blocks | ModuleList | 166
----------------------------------------------------
166 Trainable params
0 Non-trainable params
166 Total params
0.001 Total estimated model params size (MB)
`Trainer.fit` stopped: `max_epochs=400` reached.
= model.predict(n=36, num_samples=500)
pred
# scale back:
= scaler.inverse_transform(pred)
pred
series_air.plot() pred.plot()
GPU available: True (cuda), used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
HPU available: False, using: 0 HPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]
= TCNModel(
model =24,
input_chunk_length=12,
output_chunk_length=42,
random_state=LaplaceLikelihood(prior_b=0.1),
likelihood
)
=400, verbose=True); model.fit(train_air_scaled, epochs
GPU available: True (cuda), used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
HPU available: False, using: 0 HPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]
| Name | Type | Params
----------------------------------------------------
0 | criterion | MSELoss | 0
1 | train_metrics | MetricCollection | 0
2 | val_metrics | MetricCollection | 0
3 | dropout | MonteCarloDropout | 0
4 | res_blocks | ModuleList | 166
----------------------------------------------------
166 Trainable params
0 Non-trainable params
166 Total params
0.001 Total estimated model params size (MB)
`Trainer.fit` stopped: `max_epochs=400` reached.
= model.predict(n=36, num_samples=500)
pred
# scale back:
= scaler.inverse_transform(pred)
pred
series_air.plot() pred.plot()
GPU available: True (cuda), used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
HPU available: False, using: 0 HPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]
=0.01, high_quantile=0.99, label="1-99th percentiles")
pred.plot(low_quantile=0.2, high_quantile=0.8, label="20-80th percentiles") pred.plot(low_quantile
Types of distributions
The likelihood has to be compatible with the domain of your time series’ values. For instance PoissonLikelihood can be used on discrete positive values, ExponentialLikelihood can be used on real positive values, and BetaLikelihood on real values in (0,1)
It is also possible to use QuantileRegression to apply a quantile loss and fit some desired quantiles directly.
Evaluating Probabilistic Forecasts
from darts.metrics import rho_risk
print("MAPE of median forecast: %.2f" % mape(series_air, pred))
for rho in [0.05, 0.1, 0.5, 0.9, 0.95]:
= rho_risk(series_air, pred, rho=rho)
rr print("rho-risk at quantile %.2f: %.2f" % (rho, rr))
MAPE of median forecast: 11.67
rho-risk at quantile 0.05: 0.14
rho-risk at quantile 0.10: 0.14
rho-risk at quantile 0.50: 0.12
rho-risk at quantile 0.90: 0.03
rho-risk at quantile 0.95: 0.02
Using Quantile Loss
from darts.utils.likelihood_models import QuantileRegression
= TCNModel(
model =24,
input_chunk_length=12,
output_chunk_length=42,
random_state=QuantileRegression([0.05, 0.1, 0.5, 0.9, 0.95]),
likelihood
)
=400, verbose=True); model.fit(train_air_scaled, epochs
GPU available: True (cuda), used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
HPU available: False, using: 0 HPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]
| Name | Type | Params
----------------------------------------------------
0 | criterion | MSELoss | 0
1 | train_metrics | MetricCollection | 0
2 | val_metrics | MetricCollection | 0
3 | dropout | MonteCarloDropout | 0
4 | res_blocks | ModuleList | 208
----------------------------------------------------
208 Trainable params
0 Non-trainable params
208 Total params
0.001 Total estimated model params size (MB)
`Trainer.fit` stopped: `max_epochs=400` reached.
= model.predict(n=36, num_samples=500)
pred
# scale back:
= scaler.inverse_transform(pred)
pred
series_air.plot()
pred.plot()
print("MAPE of median forecast: %.2f" % mape(series_air, pred))
for rho in [0.05, 0.1, 0.5, 0.9, 0.95]:
= rho_risk(series_air, pred, rho=rho)
rr print("rho-risk at quantile %.2f: %.2f" % (rho, rr))
GPU available: True (cuda), used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
HPU available: False, using: 0 HPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]
MAPE of median forecast: 5.11
rho-risk at quantile 0.05: 0.00
rho-risk at quantile 0.10: 0.00
rho-risk at quantile 0.50: 0.02
rho-risk at quantile 0.90: 0.01
rho-risk at quantile 0.95: 0.01
Ensembling models
Ensembling is about combining the forecasts produced by several models, in order to obtain a final - and hopefully better forecast.
For instance, in our example of a less naive model above, we manually combined a naive seasonal model with a naive drift model. Here, we will show how models forecasts can be automatically combined, naively using a NaiveEnsembleModel, or learned using RegressionEnsembleModel.
It is of course also possible to use past and/or future_covariates with ensemble model but they will be passed only to the models supporting them when calling fit() and predict().
Naive Ensembling
from darts.models import NaiveEnsembleModel
= [NaiveDrift(), NaiveSeasonal(12)]
models
= NaiveEnsembleModel(forecasting_models=models)
ensemble_model
= ensemble_model.historical_forecasts(
backtest =0.6, forecast_horizon=3, verbose=True
series_air, start
)
print("MAPE = %.2f" % (mape(backtest, series_air)))
series_air.plot() backtest.plot()
MAPE = 11.88
Learned Ensembling
As expected in this case, the naive ensemble doesn’t give great results (although in some cases it could!)
We can sometimes do better if we see the ensembling as a supervised regression problem: given a set of forecasts (features), find a model that combines them in order to minimise errors on the target. This is what the RegressionEnsembleModel does. It accepts three parameters:
forecasting_models is a list of forecasting models whose predictions we want to ensemble.
regression_train_n_points is the number of time steps to use for fitting the “ensemble regression” model (i.e., the inner model that combines the forecasts).
regression_model is, optionally, a sklearn-compatible regression model or a Darts RegressionModel to be used for the ensemble regression. If not specified, a linear regression is used. Using a sklearn model is easy out-of-the-box, but using a RegressionModel allows to potentially take arbitrary lags of the individual forecasts as inputs of the regression model.
Once these elements are in place, a RegressionEnsembleModel can be used like a regular forecasting model:
from darts.models import RegressionEnsembleModel
= [NaiveDrift(), NaiveSeasonal(12)]
models
= RegressionEnsembleModel(
ensemble_model =models, regression_train_n_points=12
forecasting_models
)
= ensemble_model.historical_forecasts(
backtest =0.6, forecast_horizon=3, verbose=True
series_air, start
)
print("MAPE = %.2f" % (mape(backtest, series_air)))
series_air.plot() backtest.plot()
MAPE = 4.85
ensemble_model.fit(series_air)#|eval: false ensemble_model.regression_model.model.coef_
array([0.0136882, 1.0980103], dtype=float32)
from darts.models import LinearRegressionModel
= [0.25, 0.5, 0.75]
quantiles
= [NaiveDrift(), NaiveSeasonal(12)]
models
= LinearRegressionModel(
regression_model =quantiles,
quantiles=[0],
lags_future_covariates="quantile",
likelihood=False,
fit_intercept
)
= RegressionEnsembleModel(
ensemble_model =models,
forecasting_models=12,
regression_train_n_points=regression_model,
regression_model
)
= ensemble_model.historical_forecasts(
backtest =0.6, forecast_horizon=3, num_samples=500, verbose=True
series_air, start
)
print("MAPE = %.2f" % (mape(backtest, series_air)))
series_air.plot() backtest.plot()
MAPE = 4.79
Fitting a Kalman Filter
from darts.models import KalmanFilter
= KalmanFilter(dim_x=3)
kf
kf.fit(train_air_scaled)= kf.filter(train_air_scaled, num_samples=100)
filtered_series
train_air_scaled.plot()#|eval: false
filtered_series.plot( )
Inferring missing values with Gaussian Processes
from darts.models import GaussianProcessFilter
from sklearn.gaussian_process.kernels import RBF
# create a series with holes:
= train_air_scaled.values()
values 20:22] = np.nan
values[28:32] = np.nan
values[55:59] = np.nan
values[72:80] = np.nan
values[= TimeSeries.from_times_and_values(train_air_scaled.time_index, values)
series_holes
series_holes.plot()
= RBF()
kernel
= GaussianProcessFilter(kernel=kernel, alpha=0.1, normalize_y=True)
gpf = gpf.filter(series_holes, num_samples=100)
filtered_series
filtered_series.plot()