def test_forecast_errors(data): res = ThetaModel(data, period=12).fit() with pytest.raises(ValueError, match="steps must be a positive integer"): res.forecast(-1) with pytest.raises(ValueError, match="theta must be a float"): res.forecast(7, theta=0.99) with pytest.raises(ValueError, match="steps must be a positive integer"): res.forecast_components(0)
def test_alt_index(indexed_data): idx = indexed_data.index date_like = not hasattr(idx, "freq") or getattr(idx, "freq", None) is None period = 12 if date_like else None res = ThetaModel(indexed_data, period=period).fit() if hasattr(idx, "freq") and idx.freq is None: with pytest.warns(UserWarning): res.forecast_components(37) with pytest.warns(UserWarning): res.forecast(23) else: res.forecast_components(37) res.forecast(23)
def test_smoke(data, period, use_mle, deseasonalize, use_test, diff, model): if period is None and isinstance(data, np.ndarray): return res = ThetaModel( data, period=period, deseasonalize=deseasonalize, use_test=use_test, difference=diff, method=model, ).fit(use_mle=use_mle) assert "b0" in str(res.summary()) res.forecast(36) res.forecast_components(47) assert res.model.use_test is (use_test and res.model.deseasonalize) assert res.model.difference is diff
def test_forecast_seasonal_alignment(data, period): res = ThetaModel( data, period=period, deseasonalize=True, use_test=False, difference=False, ).fit(use_mle=False) seasonal = res._seasonal comp = res.forecast_components(32) index = np.arange(data.shape[0], data.shape[0] + comp.shape[0]) expected = seasonal[index % period] np.testing.assert_allclose(comp.seasonal, expected)
res = tm.fit(use_mle=True) print(res.summary()) # The forecast only depends on the forecast trend component, # $$ # \hat{b}_0 # \left[h - 1 + \frac{1}{\hat{\alpha}} # - \frac{(1-\hat{\alpha})^T}{\hat{\alpha}} \right], # $$ # # the forecast from the SES (which does not change with the horizon), and # the seasonal. These three components are available using the # `forecast_components`. This allows forecasts to be constructed using # multiple choices of $\theta$ using the weight expression above. res.forecast_components(12) # ## Personal Consumption Expenditure # # We next look at personal consumption expenditure. This series has a # clear seasonal component and a drift. reader = pdr.fred.FredReader(["NA000349Q"], start="1980-01-01", end="2020-04-01") pce = reader.read() pce.columns = ["PCE"] pce.index.freq = "QS-OCT" _ = pce.plot() # Since this series is always positive, we model the $\ln$.