Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Doc/Adding basic usage example in each model docstring #1956

Merged
merged 16 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ but cannot always guarantee backwards compatibility. Changes that may **break co
- `TimeSeries` with a `RangeIndex` starting in the negative start are now supported by `historical_forecasts`. [#1866](https://github.com/unit8co/darts/pull/1866) by [Antoine Madrona](https://github.com/madtoinou).
- Added a new argument `start_format` to `historical_forecasts()`, `backtest()` and `gridsearch` that allows to use an integer `start` either as the index position or index value/label for `series` indexed with a `pd.RangeIndex`. [#1866](https://github.com/unit8co/darts/pull/1866) by [Antoine Madrona](https://github.com/madtoinou).
- Added `RINorm` (Reversible Instance Norm) as an input normalization option for all `TorchForecastingModel` except `RNNModel`. Activate it with model creation parameter `use_reversible_instance_norm`. [#1969](https://github.com/unit8co/darts/pull/1969) by [Dennis Bader](https://github.com/dennisbader).
- Reduced the size of the Darts docker image `unit8/darts:latest`, and included all optional models as well as dev requirements. [#1878](https://github.com/unit8co/darts/pull/1878) by [Alex Colpitts](https://github.com/alexcolpitts96).
- Reduced the size of the Darts docker image `unit8/darts:latest`, and included all optional models as well as dev requirements. [#1878](https://github.com/unit8co/darts/pull/1878) by [Alex Colpitts](https://github.com/alexcolpitts96).
- Added short examples in the docstring of all the models, including covariates usage and some model-specific parameters. [#1956](https://github.com/unit8co/darts/pull/1956) by [Antoine Madrona](https://github.com/madtoinou).

**Fixed**
- Fixed a bug in `TimeSeries.from_dataframe()` when using a pandas.DataFrame with `df.columns.name != None`. [#1938](https://github.com/unit8co/darts/pull/1938) by [Antoine Madrona](https://github.com/madtoinou).
Expand Down
25 changes: 24 additions & 1 deletion darts/models/forecasting/arima.py
madtoinou marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some more points (this time with N for New ;) ):

  • N1: I'd try to make it more obvious that the usage of future covariates is optional, not the encoding itselve (here and everywhere else when covariates are used). E.g.
>>> # optionally, encode the holidays as a future covariates
to 
>>> # optionally, use some future covariates; e.g. the value of the month encoded as a sine and cosine series
  • N2: the air passengers series has a monthly frequency. Adding holidays as covariates is not the best choice for this frequency (here and in the other examples).
    Maybe we could use the value of the month or something? E.g.
from darts.utils.timeseries_generation import datetime_attribute_timeseries
future_cov = datetime_attribute_timeseries(series, "month", cyclic=True, add_length=6)
  • N3 The indentation should 4 whitespaces and the last ")" should be at 0 indentation
    E.g.
# right now it looks like this:
>>> model = BlockRNNModel(
>>>   input_chunk_length=12,
>>>   output_chunk_length= 6,
>>>   n_rnn_layers=2,
>>>   n_epochs=50,
>>>   )

# it should look like this
>>> model = BlockRNNModel(
>>>     input_chunk_length=12,
>>>     output_chunk_length=6,
>>>     n_rnn_layers=2,
>>>     n_epochs=50,
>>> )
  • N4 the predicted values of the torch models are mostly really bad. We should explain that those are simple usage examples and for better performance user should transform the input data, more epochs, validation set, etc.. Ideally we could reference some notebook or something

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have missing models:

sf_auto_arima.py
sf_auto_ces.py
sf_auto_ets.py
sf_auto_theta.py

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was already simple example for these models, I did not change them but I could so that everything is homogeneous.

Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,37 @@ def __init__(
.. highlight:: python
.. code-block:: python

def encode_year(idx):
return (idx.year - 1950) / 50

add_encoders={
'cyclic': {'future': ['month']},
'datetime_attribute': {'future': ['hour', 'dayofweek']},
'position': {'future': ['relative']},
'custom': {'future': [lambda idx: (idx.year - 1950) / 50]},
'custom': {'future': [encode_year]},
'transformer': Scaler()
}
..

Examples
madtoinou marked this conversation as resolved.
Show resolved Hide resolved
--------
>>> from darts.datasets import AirPassengersDataset
madtoinou marked this conversation as resolved.
Show resolved Hide resolved
>>> from darts.models import ARIMA
>>> from darts.utils.timeseries_generation import datetime_attribute_timeseries
>>> series = AirPassengersDataset().load()
>>> # optionally, use some future covariates; e.g. the value of the month encoded as a sine and cosine series
>>> future_cov = datetime_attribute_timeseries(series, "month", cyclic=True, add_length=6)
>>> # define ARIMA parameters
>>> model = ARIMA(p=12, d=1, q=2)
>>> model.fit(series, future_covariates=future_cov)
>>> pred = model.predict(6, future_covariates=future_cov)
>>> pred.values()
array([[451.36489334],
[416.88972829],
[443.10520391],
[481.07892911],
[502.11286509],
[555.50153984]])
"""
super().__init__(add_encoders=add_encoders)
self.order = p, d, q
Expand Down
25 changes: 24 additions & 1 deletion darts/models/forecasting/auto_arima.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,37 @@ def __init__(
.. highlight:: python
.. code-block:: python

def encode_year(idx):
return (idx.year - 1950) / 50

add_encoders={
'cyclic': {'future': ['month']},
'datetime_attribute': {'future': ['hour', 'dayofweek']},
'position': {'future': ['relative']},
'custom': {'future': [lambda idx: (idx.year - 1950) / 50]},
'custom': {'future': [encode_year]},
'transformer': Scaler()
}
..

Examples
--------
>>> from darts.datasets import AirPassengersDataset
madtoinou marked this conversation as resolved.
Show resolved Hide resolved
>>> from darts.models import AutoARIMA
madtoinou marked this conversation as resolved.
Show resolved Hide resolved
>>> from darts.utils.timeseries_generation import holidays_timeseries
>>> series = AirPassengersDataset().load()
>>> # optionally, use some future covariates; e.g. the value of the month encoded as a sine and cosine series
>>> future_cov = datetime_attribute_timeseries(series, "month", cyclic=True, add_length=6)
>>> # define some boundaries for the parameters
>>> model = AutoARIMA(start_p=8, max_p=12, start_q=1)
>>> model.fit(series, future_covariates=future_cov)
>>> pred = model.predict(6, future_covariates=future_cov)
>>> pred.values()
array([[449.79716178],
[416.31180633],
[445.28005229],
[485.27121314],
[507.61787454],
[561.26993332]])
"""
super().__init__(add_encoders=add_encoders)
self.model = PmdAutoARIMA(*autoarima_args, **autoarima_kwargs)
Expand Down
82 changes: 82 additions & 0 deletions darts/models/forecasting/baselines.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,22 @@ def __init__(self):

This model has no parameter, and always predicts the
mean value of the training series.

Examples
--------
>>> from darts.datasets import AirPassengersDataset
>>> from darts.models import NaiveMean
>>> series = AirPassengersDataset().load()
>>> model = NaiveMean()
>>> model.fit(series)
>>> pred = model.predict(6)
>>> pred.values()
array([[280.29861111],
[280.29861111],
[280.29861111],
[280.29861111],
[280.29861111],
[280.29861111]])
"""
super().__init__()
self.mean_val = None
Expand Down Expand Up @@ -63,6 +79,23 @@ def __init__(self, K: int = 1):
----------
K
the number of last time steps of the training set to repeat

Examples
--------
>>> from darts.datasets import AirPassengersDataset
>>> from darts.models import NaiveSeasonal
>>> series = AirPassengersDataset().load()
# prior analysis suggested seasonality of 12
>>> model = NaiveSeasonal(K=12)
>>> model.fit(series)
>>> pred = model.predict(6)
>>> pred.values()
array([[417.],
[391.],
[419.],
[461.],
[472.],
[535.]])
"""
super().__init__()
self.last_k_vals = None
Expand Down Expand Up @@ -106,6 +139,22 @@ def __init__(self):
and extends it in the future. For a training series of length :math:`T`, we have:

.. math:: \\hat{y}_{T+h} = y_T + h\\left( \\frac{y_T - y_1}{T - 1} \\right)

Examples
--------
>>> from darts.datasets import AirPassengersDataset
>>> from darts.models import NaiveDrift
>>> series = AirPassengersDataset().load()
>>> model = NaiveDrift()
>>> model.fit(series)
>>> pred = model.predict(6)
>>> pred.values()
array([[434.23776224],
[436.47552448],
[438.71328671],
[440.95104895],
[443.18881119],
[445.42657343]])
"""
super().__init__()

Expand Down Expand Up @@ -147,6 +196,22 @@ def __init__(self, input_chunk_length: int = 1):
----------
input_chunk_length
The size of the sliding window used to calculate the moving average

Examples
--------
>>> from darts.datasets import AirPassengersDataset
>>> from darts.models import NaiveMovingAverage
>>> series = AirPassengersDataset().load()
# using the average of the last 6 months
>>> model = NaiveMovingAverage(input_chunk_length=6)
>>> pred = model.predict(6)
>>> pred.values()
array([[503.16666667],
[483.36111111],
[462.9212963 ],
[455.40817901],
[454.47620885],
[465.22224366]])
"""
super().__init__()
self.input_chunk_length = input_chunk_length
Expand Down Expand Up @@ -217,6 +282,23 @@ def __init__(
List of forecasting models whose predictions to ensemble
show_warnings
Whether to show warnings related to models covariates support.

Examples
--------
>>> from darts.datasets import AirPassengersDataset
>>> from darts.models import NaiveEnsembleModel, NaiveSeasonal, LinearRegressionModel
>>> series = AirPassengersDataset().load()
>>> # defining the ensemble
>>> model = NaiveEnsembleModel([NaiveSeasonal(K=12), LinearRegressionModel(lags=4)])
>>> model.fit(series)
>>> pred = model.predict(6)
>>> pred.values()
array([[439.23152974],
[431.41161602],
[439.72888401],
[453.70180806],
[454.96757177],
[485.16604194]])
"""
super().__init__(
models=models,
Expand Down
30 changes: 30 additions & 0 deletions darts/models/forecasting/block_rnn_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,36 @@ def encode_year(idx):
----------
.. [1] T. Kim et al. "Reversible Instance Normalization for Accurate Time-Series Forecasting against
Distribution Shift", https://openreview.net/forum?id=cGDAkQo1C0p

Examples
--------
>>> from darts.datasets import WeatherDataset
>>> from darts.models import BlockRNNModel
>>> series = WeatherDataset().load()
>>> # predicting atmospheric pressure
>>> target = series['p (mbar)'][:100]
>>> # optionally, use past observed rainfall (pretending to be unknown beyond index 100)
>>> past_cov = series['rain (mm)'][:100]
>>> # predict 6 pressure values using the 12 past values of pressure and rainfall, as well as the 6 temperature
>>> model = BlockRNNModel(
>>> input_chunk_length=12,
>>> output_chunk_length=6,
>>> n_rnn_layers=2,
>>> n_epochs=50,
>>> )
>>> model.fit(target, past_covariates=past_cov)
>>> pred = model.predict(6)
>>> pred.values()
array([[4.97979827],
[3.9707572 ],
[5.27869295],
[5.19697244],
[5.28424783],
[5.22497681]])

.. note::
`RNN example notebook <https://unit8co.github.io/darts/examples/04-RNN-examples.html>`_ presents techniques
that can be used to improve the forecasts quality compared to this simple usage example.
"""
super().__init__(**self._extract_torch_model_params(**self.model_params))

Expand Down
29 changes: 29 additions & 0 deletions darts/models/forecasting/catboost_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,35 @@ def encode_year(idx):
that all target `series` have the same static covariate dimensionality in ``fit()`` and ``predict()``.
**kwargs
Additional keyword arguments passed to `catboost.CatBoostRegressor`.

Examples
madtoinou marked this conversation as resolved.
Show resolved Hide resolved
--------
>>> from darts.datasets import WeatherDataset
madtoinou marked this conversation as resolved.
Show resolved Hide resolved
>>> from darts.models import CatBoostModel
>>> series = WeatherDataset().load()
>>> # predicting atmospheric pressure
>>> target = series['p (mbar)'][:100]
>>> # optionally, use past observed rainfall (pretending to be unknown beyond index 100)
>>> past_cov = series['rain (mm)'][:100]
>>> # optionally, use future temperatures (pretending this component is a forecast)
>>> future_cov = series['T (degC)'][:106]
>>> # predict 6 pressure values using the 12 past values of pressure and rainfall, as well as the 6 temperature
>>> # values corresponding to the forecasted period
>>> model = CatBoostModel(
>>> lags=12,
>>> lags_past_covariates=12,
>>> lags_future_covariates=[0,1,2,3,4,5],
>>> output_chunk_length=6
>>> )
>>> model.fit(target, past_covariates=past_cov, future_covariates=future_cov)
>>> pred = model.predict(6)
>>> pred.values()
array([[1006.4153701 ],
[1006.41907237],
[1006.30872957],
[1006.28614154],
[1006.22355514],
[1006.21607546]])
"""
kwargs["random_state"] = random_state # seed for tree learner
self.kwargs = kwargs
Expand Down
22 changes: 21 additions & 1 deletion darts/models/forecasting/croston.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,14 @@ def __init__(
.. highlight:: python
.. code-block:: python

def encode_year(idx):
return (idx.year - 1950) / 50

add_encoders={
'cyclic': {'future': ['month']},
'datetime_attribute': {'future': ['hour', 'dayofweek']},
'position': {'future': ['relative']},
'custom': {'future': [lambda idx: (idx.year - 1950) / 50]},
'custom': {'future': [encode_year]},
'transformer': Scaler()
}
..
Expand All @@ -74,6 +77,23 @@ def __init__(
.. [2] Ruud H. Teunter, Aris A. Syntetos, and M. Zied Babai.
Intermittent demand: Linking forecasting to inventory obsolescence.
European Journal of Operational Research, 214(3):606 – 615, 2011.

Examples
--------
>>> from darts.datasets import AirPassengersDataset
>>> from darts.models import Croston
>>> series = AirPassengersDataset().load()
>>> # use the optimized version to automatically select best alpha parameter
>>> model = Croston(version="optimized")
>>> model.fit(series)
>>> pred = model.predict(6)
>>> pred.values()
array([[461.7666],
[461.7666],
[461.7666],
[461.7666],
[461.7666],
[461.7666]])
"""
super().__init__(add_encoders=add_encoders)
raise_if_not(
Expand Down
33 changes: 33 additions & 0 deletions darts/models/forecasting/dlinear.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,39 @@ def encode_year(idx):
Are Transformers Effective for Time Series Forecasting?. arXiv preprint arXiv:2205.13504.
.. [2] T. Kim et al. "Reversible Instance Normalization for Accurate Time-Series Forecasting against
Distribution Shift", https://openreview.net/forum?id=cGDAkQo1C0p

Examples
madtoinou marked this conversation as resolved.
Show resolved Hide resolved
--------
>>> from darts.datasets import WeatherDataset
madtoinou marked this conversation as resolved.
Show resolved Hide resolved
>>> from darts.models import DLinearModel
>>> series = WeatherDataset().load()
>>> # predicting atmospheric pressure
>>> target = series['p (mbar)'][:100]
>>> # optionally, use past observed rainfall (pretending to be unknown beyond index 100)
>>> past_cov = series['rain (mm)'][:100]
>>> # optionally, use future temperatures (pretending this component is a forecast)
>>> future_cov = series['T (degC)'][:106]
>>> # predict 6 pressure values using the 12 past values of pressure and rainfall, as well as the 6 temperature
>>> # values corresponding to the forecasted period
>>> model = DLinearModel(
>>> input_chunk_length=6,
>>> output_chunk_length=6,
>>> n_epochs=20,
>>> )
>>> model.fit(target, past_covariates=past_cov, future_covariates=future_cov)
>>> pred = model.predict(6)
>>> pred.values()
array([[667.20957388],
[666.76986848],
[666.67733306],
[666.06625381],
[665.8529289 ],
[665.75320573]])

.. note::
This simple usage example produces poor forecasts. In order to obtain better performance, user should
transform the input data, increase the number of epochs, use a validation set, optimize the hyper-
parameters, ...
"""
super().__init__(**self._extract_torch_model_params(**self.model_params))

Expand Down
18 changes: 18 additions & 0 deletions darts/models/forecasting/exponential_smoothing.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,24 @@ def __init__(
:func:`statsmodels.tsa.holtwinters.ExponentialSmoothing.fit()`.
See `the documentation
<https://www.statsmodels.org/stable/generated/statsmodels.tsa.holtwinters.ExponentialSmoothing.fit.html>`_.

Examples
--------
>>> from darts.datasets import AirPassengersDataset
>>> from darts.models import ExponentialSmoothing
>>> from darts.utils.utils import ModelMode, SeasonalityMode
>>> series = AirPassengersDataset().load()
>>> # using Holt's exponential smoothing
>>> model = ExponentialSmoothing(trend=ModelMode.ADDITIVE, seasonal=SeasonalityMode.MULTIPLICATIVE)
>>> model.fit(series)
>>> pred = model.predict(6)
>>> pred.values()
array([[445.24283838],
[418.22618932],
[465.31305075],
[494.95129261],
[505.4770514 ],
[573.31519186]])
"""
super().__init__()
self.trend = trend
Expand Down
Loading
Loading