Beispiel #1
0
    def __init__(
        self,
        freq: str,
        prediction_length: int,
        method_name: str = "ets",
        period: int = None,
        trunc_length: Optional[int] = None,
        params: Optional[Dict] = None,
    ) -> None:
        super().__init__(freq=freq, prediction_length=prediction_length)

        try:
            from rpy2 import robjects, rinterface
            import rpy2.robjects.packages as rpackages
            from rpy2.rinterface import RRuntimeError
        except ImportError as e:
            raise ImportError(str(e) + USAGE_MESSAGE) from e

        self._robjects = robjects
        self._rinterface = rinterface
        self._rinterface.initr()
        self._rpackages = rpackages

        this_dir = os.path.dirname(os.path.realpath(__file__))
        this_dir = this_dir.replace("\\", "/")  # for windows
        r_files = [
            n[:-2] for n in os.listdir(f"{this_dir}/R/") if n[-2:] == ".R"
        ]

        for n in r_files:
            try:
                path = Path(this_dir, "R", f"{n}.R")
                robjects.r(f'source("{path}")'.replace("\\", "\\\\"))
            except RRuntimeError as er:
                raise RRuntimeError(str(er) + USAGE_MESSAGE) from er

        supported_methods = ["ets", "arima", "tbats", "croston", "mlp"]
        assert (
            method_name in supported_methods
        ), f"method {method_name} is not supported please use one of {supported_methods}"

        self.method_name = method_name

        self._stats_pkg = rpackages.importr("stats")
        self._r_method = robjects.r[method_name]

        self.prediction_length = prediction_length
        self.freq = freq
        self.period = period if period is not None else get_seasonality(freq)
        self.trunc_length = trunc_length

        self.params = {
            "prediction_length": self.prediction_length,
            "output_types": ["samples"],
            "frequency": self.period,
        }
        if params is not None:
            self.params.update(params)
Beispiel #2
0
    def __init__(
        self,
        freq: str,
        prediction_length: int,
        method_name: str = "ets",
        period: int = None,
        num_eval_samples: int = 100,
        trunc_length: Optional[int] = None,
        params: Optional[Dict] = None,
    ) -> None:
        try:
            from rpy2 import robjects, rinterface
            import rpy2.robjects.packages as rpackages
            from rpy2.rinterface import RRuntimeError
        except ImportError as e:
            raise ImportError(str(e) + USAGE_MESSAGE) from e

        self._robjects = robjects
        self._rinterface = rinterface
        self._rinterface.initr()
        self._rpackages = rpackages

        this_dir = os.path.dirname(os.path.realpath(__file__))
        r_files = [
            n[:-2] for n in os.listdir(f"{this_dir}/R/") if n[-2:] == ".R"
        ]

        for n in r_files:
            try:
                robjects.r(f'source("{this_dir}/R/{n}.R")')
            except RRuntimeError as er:
                raise RRuntimeError(str(er) + USAGE_MESSAGE) from er

        supported_methods = ["ets", "arima", "tbats", "croston", "mlp"]
        assert (
            method_name in supported_methods
        ), f"method {method_name} is not supported please use one of {supported_methods}"

        self.method_name = method_name

        self._stats_pkg = rpackages.importr('stats')
        self._r_method = robjects.r[method_name]

        self.prediction_length = prediction_length
        self.freq = freq
        self.period = period if period is not None else get_seasonality(freq)
        self.num_samples = num_eval_samples
        self.trunc_length = trunc_length

        self.params = {
            'prediction_length': self.prediction_length,
            'output_types': ['samples'],
            'num_samples': self.num_samples,
            'frequency': self.period,
        }
        if params is not None:
            self.params.update(params)
Beispiel #3
0
def naive_2(
    past_ts_data: np.ndarray,
    prediction_length: int,
    freq: Optional[str] = None,
    season_length: Optional[int] = None,
) -> np.ndarray:
    """
    Make seasonality adjusted time series prediction.

    If specified, `season_length` takes precedence.

    As described here: https://www.m4.unic.ac.cy/wp-content/uploads/2018/03/M4-Competitors-Guide.pdf
    Code based on: https://github.com/Mcompetitions/M4-methods/blob/master/Benchmarks%20and%20Evaluation.R
    """
    assert freq is not None or season_length is not None, (
        "Either the frequency or season length of the time series "
        "has to be specified. "
    )
    season_length = (
        season_length if season_length is not None else get_seasonality(freq)
    )
    has_seasonality = False

    if season_length > 1:
        has_seasonality = seasonality_test(past_ts_data, season_length)

    # it has seasonality, then calculate the multiplicative seasonal component
    if has_seasonality:
        # TODO: think about maybe only using past_ts_data[- max(5*season_length, 2*prediction_length):] for speedup
        seasonal_decomposition = sm.tsa.seasonal_decompose(
            x=past_ts_data, period=season_length, model="multiplicative"
        ).seasonal
        seasonality_normed_context = past_ts_data / seasonal_decomposition

        last_period = seasonal_decomposition[-season_length:]
        num_required_periods = (prediction_length // len(last_period)) + 1

        multiplicative_seasonal_component = np.tile(
            last_period, num_required_periods
        )[:prediction_length]
    else:
        seasonality_normed_context = past_ts_data
        multiplicative_seasonal_component = np.ones(
            prediction_length
        )  # i.e. no seasonality component

    # calculate naive forecast: (last value prediction_length times)
    naive_forecast = (
        np.ones(prediction_length) * seasonality_normed_context[-1]
    )

    forecast = np.mean(naive_forecast) * multiplicative_seasonal_component

    return forecast
Beispiel #4
0
    def __init__(self, loss_function: str, freq: str, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)
        self.loss_function = loss_function
        self.freq = freq

        # Covert frequency string like "2H" to whats called the periodicity m.
        # E.g. 12 in case of "2H" because of 12 times two hours in a day.
        self.periodicity = get_seasonality(self.freq)

        if self.loss_function == "MASE":
            assert (
                self.periodicity < self.context_length + self.prediction_length
            ), ("If the 'periodicity' of your data is less than 'context_length' + 'prediction_length' "
                "the seasonal_error cannot be calculated and thus 'MASE' cannot be used for optimization."
                )
Beispiel #5
0
    def __init__(
        self,
        freq: str,
        prediction_length: int,
        season_length: Optional[int] = None,
    ) -> None:
        super().__init__(prediction_length, freq)

        assert (
            season_length is None
            or season_length > 0), "The value of `season_length` should be > 0"

        self.freq = freq
        self.prediction_length = prediction_length
        self.season_length = (season_length if season_length is not None else
                              get_seasonality(freq))
Beispiel #6
0
def test_get_seasonality(freq, expected_seasonality):
    assert get_seasonality(freq) == expected_seasonality