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

Improve description for ARIMA parameters (p, q, seasonal_orders and trend) #2142

Merged
merged 15 commits into from
Feb 16, 2024
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ but cannot always guarantee backwards compatibility. Changes that may **break co

### For users of the library:
**Improved**
- Improvements to `ARIMA` documentation: Specified possible `p`, `d`, `P`, `D`, `trend` advanced options that are available in statsmodels. More explanations on the behaviour of the parameters were added. [#2142](https://github.com/unit8co/darts/pull/2142) by [MarcBresson](https://github.com/MarcBresson)
- Improvements to `TimeSeries`: [#2196](https://github.com/unit8co/darts/pull/2196) by [Dennis Bader](https://github.com/dennisbader).
- 🚀🚀🚀 Significant performance boosts for several `TimeSeries` methods resulting increased efficiency across the entire `Darts` library. Up to 2x faster creation times for series indexed with "regular" frequencies (e.g. Daily, hourly, ...), and >100x for series indexed with "special" frequencies (e.g. "W-MON", ...). Affects:
- All `TimeSeries` creation methods
Expand Down
54 changes: 40 additions & 14 deletions darts/models/forecasting/arima.py
MarcBresson marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@
.. [1] https://wikipedia.org/wiki/Autoregressive_integrated_moving_average
"""

from typing import Optional, Tuple
from typing import List, Literal, Optional, Sequence, Tuple, Union

try:
from typing import TypeAlias
except ImportError:
from typing_extensions import TypeAlias

import numpy as np
from statsmodels import __version_tuple__ as statsmodels_version
Expand All @@ -28,14 +33,22 @@
statsmodels_above_0135 = statsmodels_version > (0, 13, 5)


IntOrIntSequence: TypeAlias = Union[int, Sequence[int]]
dennisbader marked this conversation as resolved.
Show resolved Hide resolved


class ARIMA(TransferableFutureCovariatesLocalForecastingModel):
def __init__(
self,
p: int = 12,
p: IntOrIntSequence = 12,
d: int = 1,
q: int = 0,
seasonal_order: Tuple[int, int, int, int] = (0, 0, 0, 0),
trend: Optional[str] = None,
q: IntOrIntSequence = 0,
seasonal_order: Tuple[int, IntOrIntSequence, IntOrIntSequence, int] = (
0,
0,
0,
0,
),
trend: Optional[Union[Literal["n", "c", "t", "ct"], List[int]]] = None,
random_state: Optional[int] = None,
add_encoders: Optional[dict] = None,
):
Expand All @@ -45,20 +58,29 @@ def __init__(

Parameters
----------
p : int
p : int | Sequence[int]
Order (number of time lags) of the autoregressive model (AR).
If a sequence of integers, specifies the exact lags to include.
d : int
The order of differentiation; i.e., the number of times the data
have had past values subtracted (I).
q : int
q : int | Sequence[int]
The size of the moving average window (MA).
seasonal_order: Tuple[int, int, int, int]
The (P,D,Q,s) order of the seasonal component for the AR parameters,
differences, MA parameters and periodicity.
trend: str
Parameter controlling the deterministic trend. 'n' indicates no trend,
'c' a constant term, 't' linear trend in time, and 'ct' includes both.
Default is 'c' for models without integration, and no trend for models with integration.
If a sequence of integers, specifies the exact lags to include in the window.
seasonal_order: Tuple[int | Sequence[int], int, int | Sequence[int], int]
MarcBresson marked this conversation as resolved.
Show resolved Hide resolved
The (P,D,Q,s) order of the seasonal component for the AR parameters (P),
differences (D), MA parameters (Q) and periodicity (s). D and s are always integers,
while P and Q may either be integers or sequence of positive integers
specifying exactly which lag orders are included.
trend: Literal['n', 'c', 't', 'ct'] | list[int], optional
Parameter controlling the deterministic trend. Either a string or list of integers.
If a string, can be 'n' for no trend, 'c' for a constant term, 't' for a linear trend in time,
and 'ct' for a constant term and linear trend.
If a list of integers, defines a polynomial according to `numpy.poly1d` [1]_. E.g., `[1,1,0,1]` would
translate to :math:`a + bt + ct^3`.
Trend term of lower order than `d + D` cannot be as they would be eliminated due to the differencing
operation.
Default is 'c' for models without integration, and 'n' for models with integration.
add_encoders
dennisbader marked this conversation as resolved.
Show resolved Hide resolved
A large number of future covariates can be automatically generated with `add_encoders`.
This can be done by adding multiple pre-defined index encoders and/or custom user-made functions that
Expand Down Expand Up @@ -103,6 +125,10 @@ def encode_year(idx):
[481.07892911],
[502.11286509],
[555.50153984]])

References
----------
.. [1] https://numpy.org/doc/stable/reference/generated/numpy.poly1d.html
"""
super().__init__(add_encoders=add_encoders)
self.order = p, d, q
Expand Down
18 changes: 16 additions & 2 deletions darts/tests/models/forecasting/test_historical_forecasts.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,8 +357,22 @@ def create_model(ocl, use_ll=True, model_type="regression"):
**tfm_kwargs,
)

def test_historical_forecasts_transferrable_future_cov_local_models(self):
model = ARIMA()
@pytest.mark.parametrize(
"arima_args",
[
{},
{
"p": np.array([1, 2, 3, 4]),
"q": (2, 3),
"seasonal_order": ([1, 5], 1, (1, 2, 3), 6),
"trend": [0, 0, 2, 1],
},
],
)
def test_historical_forecasts_transferrable_future_cov_local_models(
self, arima_args: dict
):
model = ARIMA(**arima_args)
assert model.min_train_series_length == 30
series = tg.sine_timeseries(length=31)
res = model.historical_forecasts(
Expand Down
Loading