Skip to content

Commit

Permalink
Merge branch 'master' into feat/user-defined-fn-name-window-trans
Browse files Browse the repository at this point in the history
  • Loading branch information
JQGoh committed Mar 27, 2023
2 parents 952c7e2 + 28d3e2a commit 9993323
Show file tree
Hide file tree
Showing 25 changed files with 108 additions and 110 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ on bringing more models and features.
Model | Univariate | Multivariate | Probabilistic | Multiple series (global) | Past-observed covariates | Future-known covariates | Static covariates | Reference
--- | --- | --- | --- | --- | --- | --- | --- | ---
`ARIMA` | ✅ | | ✅ | | | ✅ | |
`VARIMA` | | ✅ | | | | ✅ | |
`VARIMA` | | ✅ | | | | ✅ | |
`AutoARIMA` | ✅ | | | | | ✅ | |
`StatsForecastAutoARIMA` (faster AutoARIMA) | ✅ | | ✅ | | | ✅ | | [Nixtla's statsforecast](https://github.com/Nixtla/statsforecast)
`ExponentialSmoothing` | ✅ | | ✅ | | | | |
Expand Down
5 changes: 0 additions & 5 deletions darts/models/forecasting/arima.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,6 @@ def __init__(
self.model = None
np.random.seed(random_state)

def __str__(self):
if self.seasonal_order == (0, 0, 0, 0):
return f"ARIMA{self.order}"
return f"SARIMA{self.order}x{self.seasonal_order}"

def _fit(self, series: TimeSeries, future_covariates: Optional[TimeSeries] = None):
super()._fit(series, future_covariates)

Expand Down
3 changes: 0 additions & 3 deletions darts/models/forecasting/auto_arima.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,6 @@ def __init__(
self.model = PmdAutoARIMA(*autoarima_args, **autoarima_kwargs)
self.trend = self.model.trend

def __str__(self):
return "Auto-ARIMA"

def _fit(self, series: TimeSeries, future_covariates: Optional[TimeSeries] = None):
super()._fit(series, future_covariates)
self._assert_univariate(series)
Expand Down
27 changes: 7 additions & 20 deletions darts/models/forecasting/baselines.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ def __init__(self):
super().__init__()
self.mean_val = None

def __str__(self):
return "Naive mean predictor model"

def fit(self, series: TimeSeries):
super().fit(series)

Expand Down Expand Up @@ -66,9 +63,6 @@ def __init__(self, K: int = 1):
def min_train_series_length(self):
return max(self.K, 3)

def __str__(self):
return f"Naive seasonal model, with K={self.K}"

def fit(self, series: TimeSeries):
super().fit(series)

Expand Down Expand Up @@ -101,9 +95,6 @@ def __init__(self):
"""
super().__init__()

def __str__(self):
return "Naive drift model"

def fit(self, series: TimeSeries):
super().fit(series)
assert series.n_samples == 1, "This model expects deterministic time series"
Expand Down Expand Up @@ -215,16 +206,12 @@ def ensemble(
predictions: Union[TimeSeries, Sequence[TimeSeries]],
series: Optional[Sequence[TimeSeries]] = None,
) -> Union[TimeSeries, Sequence[TimeSeries]]:
def take_average(prediction: TimeSeries) -> TimeSeries:
series = prediction.pd_dataframe(copy=False).sum(axis=1) / len(self.models)
series.name = prediction.components[0]
return TimeSeries.from_series(series)

if isinstance(predictions, Sequence):
return [
TimeSeries.from_series(
p.pd_dataframe(copy=False).sum(axis=1) / len(self.models),
static_covariates=p.static_covariates,
)
for p in predictions
]
return [take_average(p) for p in predictions]
else:
return TimeSeries.from_series(
predictions.pd_dataframe(copy=False).sum(axis=1) / len(self.models),
static_covariates=predictions.static_covariates,
)
return take_average(predictions)
3 changes: 0 additions & 3 deletions darts/models/forecasting/catboost_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,6 @@ def __init__(
model=CatBoostRegressor(**kwargs),
)

def __str__(self):
return f"CatBoostModel(lags={self.lags})"

def fit(
self,
series: Union[TimeSeries, Sequence[TimeSeries]],
Expand Down
3 changes: 0 additions & 3 deletions darts/models/forecasting/croston.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,6 @@ def __init__(

self.version = version

def __str__(self):
return "Croston"

def _fit(self, series: TimeSeries, future_covariates: Optional[TimeSeries] = None):
super()._fit(series, future_covariates)
self._assert_univariate(series)
Expand Down
6 changes: 0 additions & 6 deletions darts/models/forecasting/exponential_smoothing.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,6 @@ def __init__(
self.model = None
np.random.seed(random_state)

def __str__(self):
return (
f"ExponentialSmoothing(trend={self.trend}, damped={self.damped}, "
f"seasonal={self.seasonal}, seasonal_periods={self.seasonal_periods}"
)

def fit(self, series: TimeSeries):
super().fit(series)
self._assert_univariate(series)
Expand Down
9 changes: 0 additions & 9 deletions darts/models/forecasting/fft.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,15 +260,6 @@ def __init__(
self.trend = trend
self.trend_poly_degree = trend_poly_degree

def __str__(self):
return (
"FFT(nr_freqs_to_keep="
+ str(self.nr_freqs_to_keep)
+ ", trend="
+ str(self.trend)
+ ")"
)

def _exp_trend(self, x) -> Callable:
"""Helper function, used to make FFT model pickable."""
return np.exp(self.trend_coefficients[1]) * np.exp(
Expand Down
62 changes: 61 additions & 1 deletion darts/models/forecasting/forecasting_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -1623,9 +1623,69 @@ def load(path: Union[str, BinaryIO]) -> "ForecastingModel":
def _assert_univariate(self, series: TimeSeries):
if not series.is_univariate:
raise_log(
ValueError("This model only supports univariate TimeSeries instances")
ValueError(
f"Model `{self.__class__.__name__}` only supports univariate TimeSeries instances"
),
logger=logger,
)

def _assert_multivariate(self, series: TimeSeries):
if series.is_univariate:
raise_log(
ValueError(
f"Model `{self.__class__.__name__}` only supports multivariate TimeSeries instances"
),
logger=logger,
)

def __repr__(self):
"""
Get full description for this estimator (includes all params).
"""
return self._get_model_description_string(True)

def __str__(self):
"""
Get short description for this estimator (only includes params with non-default values).
"""
return self._get_model_description_string(False)

def _get_model_description_string(self, include_default_params):
"""
Get model description string of structure `model_name`(`model_param_key_value_pairs`).
Parameters
----------
include_default_params : bool,
If True, will include params with default values in the description.
Returns
-------
description : String
Model description.
"""
default_model_params = self._get_default_model_params()
changed_model_params = [
(k, v)
for k, v in self.model_params.items()
if include_default_params or v != default_model_params.get(k, None)
]

model_name = self.__class__.__name__
params_string = ", ".join([f"{k}={str(v)}" for k, v in changed_model_params])
return f"{model_name}({params_string})"

@classmethod
def _get_default_model_params(cls):
"""Get parameter key : default_value pairs for the estimator"""
init_signature = inspect.signature(cls.__init__)
# Consider the constructor parameters excluding 'self'
return {
p.name: p.default
for p in init_signature.parameters.values()
if p.name != "self"
}


class LocalForecastingModel(ForecastingModel, ABC):
"""The base class for "local" forecasting models, handling only single univariate time series.
Expand Down
3 changes: 0 additions & 3 deletions darts/models/forecasting/kalman_forecaster.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,6 @@ def __init__(
self.kf = kf
self.darts_kf = KalmanFilter(dim_x, kf)

def __str__(self):
return f"Kalman Filter Forecaster (dim_x={self.dim_x})"

def _fit(self, series: TimeSeries, future_covariates: Optional[TimeSeries] = None):

super()._fit(series, future_covariates)
Expand Down
5 changes: 0 additions & 5 deletions darts/models/forecasting/lgbm.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,6 @@ def __init__(
model=lgb.LGBMRegressor(**self.kwargs),
)

def __str__(self):
if self.likelihood:
return f"LGBModel(lags={self.lags}, likelihood={self.likelihood})"
return f"LGBModel(lags={self.lags})"

def fit(
self,
series: Union[TimeSeries, Sequence[TimeSeries]],
Expand Down
5 changes: 0 additions & 5 deletions darts/models/forecasting/linear_regression_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,6 @@ def __init__(
multi_models=multi_models,
)

def __str__(self):
if self.likelihood:
return f"LinearRegression(lags={self.lags}, likelihood={self.likelihood})"
return f"LinearRegression(lags={self.lags})"

def fit(
self,
series: Union[TimeSeries, Sequence[TimeSeries]],
Expand Down
3 changes: 0 additions & 3 deletions darts/models/forecasting/prophet_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,6 @@ def __init__(
# Use 0 as default value
self._floor = 0

def __str__(self):
return "Prophet"

def _fit(self, series: TimeSeries, future_covariates: Optional[TimeSeries] = None):

super()._fit(series, future_covariates)
Expand Down
6 changes: 0 additions & 6 deletions darts/models/forecasting/random_forest.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,3 @@ def __init__(
multi_models=multi_models,
model=RandomForestRegressor(**kwargs),
)

def __str__(self):
return (
f"RandomForest(lags={self.lags}, "
f"n_estimators={self.n_estimators}, max_depth={self.max_depth})"
)
3 changes: 0 additions & 3 deletions darts/models/forecasting/regression_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,3 @@ def _quantile_sampling(self, model_output: np.ndarray) -> np.ndarray:
class _QuantileModelContainer(OrderedDict):
def __init__(self):
super().__init__()

def __str__(self):
return f"_QuantileModelContainer(quantiles={list(self.keys())})"
3 changes: 0 additions & 3 deletions darts/models/forecasting/sf_auto_arima.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,6 @@ def __init__(
super().__init__(add_encoders=add_encoders)
self.model = SFAutoARIMA(*autoarima_args, **autoarima_kwargs)

def __str__(self):
return "Auto-ARIMA-Statsforecasts"

def _fit(self, series: TimeSeries, future_covariates: Optional[TimeSeries] = None):
super()._fit(series, future_covariates)
self._assert_univariate(series)
Expand Down
3 changes: 0 additions & 3 deletions darts/models/forecasting/sf_auto_ces.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ def __init__(self, *autoces_args, **autoces_kwargs):
super().__init__()
self.model = SFAutoCES(*autoces_args, **autoces_kwargs)

def __str__(self):
return "Auto-CES-Statsforecasts"

def fit(self, series: TimeSeries):
super().fit(series)
self._assert_univariate(series)
Expand Down
3 changes: 0 additions & 3 deletions darts/models/forecasting/sf_auto_ets.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,6 @@ def __init__(self, *ets_args, add_encoders: Optional[dict] = None, **ets_kwargs)
self.model = SFAutoETS(*ets_args, **ets_kwargs)
self._linreg = None

def __str__(self):
return "ETS-Statsforecasts"

def _fit(self, series: TimeSeries, future_covariates: Optional[TimeSeries] = None):
super()._fit(series, future_covariates)
self._assert_univariate(series)
Expand Down
3 changes: 0 additions & 3 deletions darts/models/forecasting/sf_auto_theta.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ def __init__(self, *autotheta_args, **autotheta_kwargs):
super().__init__()
self.model = SFAutoTheta(*autotheta_args, **autotheta_kwargs)

def __str__(self):
return "Auto-Theta-Statsforecasts"

def fit(self, series: TimeSeries):
super().fit(series)
self._assert_univariate(series)
Expand Down
3 changes: 0 additions & 3 deletions darts/models/forecasting/tbats.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,6 @@ def __init__(
self.model = None
np.random.seed(random_state)

def __str__(self):
return "(T)BATS"

@abstractmethod
def _create_model(self):
pass
Expand Down
8 changes: 0 additions & 8 deletions darts/models/forecasting/theta.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,6 @@ def predict(

return self._build_forecast_series(forecast)

def __str__(self):
return f"Theta({self.theta})"

@property
def min_train_series_length(self) -> int:
if (
Expand Down Expand Up @@ -469,11 +466,6 @@ def select_best_model(
)
return theta

def __str__(self):
return "4Theta(theta:{}, curve:{}, model:{}, seasonality:{})".format(
self.theta, self.trend_mode, self.model_mode, self.season_mode
)

@property
def min_train_series_length(self) -> int:
if (
Expand Down
7 changes: 2 additions & 5 deletions darts/models/forecasting/varima.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,6 @@ def __init__(

assert d <= 1, "d > 1 not supported."

def __str__(self):
if self.d == 0:
return f"VARMA({self.p},{self.q})"
return f"VARIMA({self.p},{self.d},{self.q})"

def _differentiate_series(self, series: TimeSeries) -> TimeSeries:
"""Differentiate the series self.d times"""
for _ in range(self.d):
Expand Down Expand Up @@ -114,6 +109,8 @@ def _fit(
) -> None:
super()._fit(series, future_covariates)

self._assert_multivariate(series)

# storing to restore the statsmodels model results object
self.training_historic_future_covariates = future_covariates

Expand Down
5 changes: 0 additions & 5 deletions darts/models/forecasting/xgboost.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,6 @@ def __init__(
model=xgb.XGBRegressor(**self.kwargs),
)

def __str__(self):
if self.likelihood:
return f"XGBModel(lags={self.lags}, likelihood={self.likelihood})"
return f"XGBModel(lags={self.lags})"

def fit(
self,
series: Union[TimeSeries, Sequence[TimeSeries]],
Expand Down
3 changes: 2 additions & 1 deletion darts/tests/models/forecasting/test_ensemble_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ def test_call_predict_local_models(self):
with self.assertRaises(Exception):
naive_ensemble.predict(5)
naive_ensemble.fit(self.series1)
naive_ensemble.predict(5)
pred1 = naive_ensemble.predict(5)
assert self.series1.components == pred1.components

def test_predict_ensemble_local_models(self):
naive = NaiveSeasonal(K=5)
Expand Down

0 comments on commit 9993323

Please sign in to comment.