def test_error_action_validation(): est = ARIMA(order=(1, 1, 2), seasonal_order=(0, 1, 1, 12)) with pytest.raises(ValueError) as ve: cross_validate( est, y, error_score=None, scoring='mean_squared_error', cv=SlidingWindowForecastCV(window_size=100, step=24, h=1)) assert 'error_score should be' in pytest_error_str(ve)
def test_issue_286(): mod = ARIMA(order=(1, 1, 2)) mod.fit(wineind) with pytest.raises(ValueError) as ve: mod.predict_in_sample(start=0) assert "In-sample predictions undefined for" in pytest_error_str(ve)
def test_valid_metrics(metric, expected_error, expected_error_msg): if not expected_error: assert callable(val.get_scoring_metric(metric)) else: with pytest.raises(expected_error) as err: val.get_scoring_metric(metric) assert expected_error_msg in pytest_error_str(err)
def test_issue_341(): y = [ 0, 132, 163, 238, 29, 0, 150, 320, 249, 224, 197, 31, 0, 154, 143, 132, 135, 158, 21, 0, 126, 100, 137, 105, 104, 8, 0, 165, 191, 234, 253, 155, 25, 0, 228, 234, 265, 205, 191, 19, 0, 188, 156, 172, 173, 166, 28, 0, 209, 160, 159, 129, 124, 18, 0, 155 ] with pytest.raises(ValueError) as ve: auto.auto_arima(y, start_p=1, start_q=1, test='adf', max_p=3, max_q=3, m=52, start_P=0, seasonal=True, d=None, D=1, trace=True, error_action='ignore', suppress_warnings=True, stepwise=True) # assert that we catch the np LinAlg error and reraise with a more # meaningful message assert "Encountered exception in stationarity test" in pytest_error_str(ve)
def test_names_double_underscore(self): # Will fail since the "__" is reserved for parameter names with pytest.raises(ValueError) as ve: Pipeline([("stage__1", BoxCoxEndogTransformer()), ("stage", ARIMA(order=(0, 0, 0)))]) assert "must not contain __" in pytest_error_str(ve)
def test_names_in_params(self): # Will fail because 'steps' is a param of Pipeline with pytest.raises(ValueError) as ve: Pipeline([("steps", BoxCoxEndogTransformer()), ("stage", ARIMA(order=(0, 0, 0)))]) assert "names conflict" in pytest_error_str(ve)
def test_non_unique_names(self): # Will fail since the same name repeated twice with pytest.raises(ValueError) as ve: Pipeline([("stage", BoxCoxEndogTransformer()), ("stage", ARIMA(order=(0, 0, 0)))]) assert "not unique" in pytest_error_str(ve)
def test_pipeline_behavior(): wineind = load_wineind() train, test = wineind[:125], wineind[125:] pipeline = Pipeline([ ("fourier", FourierFeaturizer(m=12)), ("arima", AutoARIMA(seasonal=False, stepwise=True, suppress_warnings=True, maxiter=3, error_action='ignore')) ]) # Quick assertions on indexing assert len(pipeline) == 2 pipeline.fit(train) preds = pipeline.predict(5) assert preds.shape[0] == 5 assert pipeline._final_estimator.model_.fit_with_exog_ # Assert that when the n_periods kwarg is set manually and incorrectly for # the fourier transformer, we get a ValueError kwargs = { "fourier__n_periods": 10 } with pytest.raises(ValueError) as ve: pipeline.predict(3, **kwargs) assert "'n_periods'" in pytest_error_str(ve) # Assert that we can update the model pipeline.update(test, maxiter=5) # And that the fourier transformer was updated properly... assert pipeline.steps_[0][1].n_ == wineind.shape[0]
def test_issue_341(): seas_diffed = np.array([124., -114., -163., -83.]) with pytest.raises(ValueError) as ve: arima_utils.ndiffs(seas_diffed, test='adf') assert "raised from LinAlgError" in pytest_error_str(ve)
def test_except_and_reraise_no_reraise(): with pytest.raises(KeyError) as ke: with ctx.except_and_reraise(ValueError, raise_err=TypeError, raise_msg="bar message"): raise KeyError("foo message") assert "foo message" in pytest_error_str(ke)
def test_check_start_max_values(st, mx, argname, exp_vals, exp_err_msg): if exp_err_msg: with pytest.raises(ValueError) as ve: val.check_start_max_values(st, mx, argname) assert exp_err_msg in pytest_error_str(ve) else: res = val.check_start_max_values(st, mx, argname) assert exp_vals == res
def test_illegal_column_fails(): X_prime = X.copy() X_prime["date2"] = X_prime["date"].astype(str) feat = DateFeaturizer(column_name="date2") with pytest.raises(ValueError) as ve: feat.fit_transform(y, X_prime) assert "pd.Timestamp type" in pytest_error_str(ve)
def test_non_transformer_in_steps(self): # Will fail since the first stage is not a transformer with pytest.raises(TypeError) as ve: Pipeline([ ("stage1", (lambda *args, **kwargs: None)), # Fail ("stage2", AutoARIMA()) ]) assert "instances of BaseTransformer" in pytest_error_str(ve)
def test_force_polynomial_error(): x = np.array([1, 2, 3, 4, 5, 6, 7, 8]) d = 3 xreg = None with pytest.raises(ValueError) as ve: pm.auto_arima(x, d=d, D=0, seasonal=False, X=xreg, trace=2) err_msg = pytest_error_str(ve) assert 'simple polynomial' in err_msg, err_msg
def test_except_and_reraise_do_reraise(): with pytest.raises(KeyError) as ke: with ctx.except_and_reraise(ValueError, raise_err=KeyError, raise_msg="bar message"): raise ValueError("contains foo message") msg = pytest_error_str(ke) assert "bar message" in msg assert "raised from ValueError" in msg
def test_m_too_large(): train = lynx[:90] with pytest.raises(ValueError) as v: auto_arima(train, start_p=1, start_q=1, start_P=1, start_Q=1, max_p=5, max_q=5, max_P=5, max_Q=5, seasonal=True, stepwise=True, suppress_warnings=True, D=10, max_D=10, error_action='ignore', m=20) msg = pytest_error_str(v) assert 'The seasonal differencing order' in msg
def test_failing_ocsb(): # TODO: should this pass? # This passes in R, but statsmodels can't compute the regression... with pytest.raises(ValueError): OCSBTest(m=4, max_lag=0).estimate_seasonal_differencing_term(austres) # Fail for bad method with pytest.raises(ValueError) as v: OCSBTest(m=4, max_lag=3, lag_method="bad_method")\ .estimate_seasonal_differencing_term(austres) assert "invalid method" in pytest_error_str(v)
def test_force_polynomial_error(): x = np.array([1, 2, 3, 4, 5, 6, 7, 8]) d = 3 xreg = None with pytest.raises(ValueError) as ve, \ pytest.warns(ModelFitWarning) as mfw: pm.auto_arima(x, d=d, D=0, seasonal=False, X=xreg, trace=2) err_msg = pytest_error_str(ve) assert 'simple polynomial' in err_msg, err_msg warning_msgs = pytest_warning_messages(mfw) assert any('more differencing operation' in w for w in warning_msgs)
def test_force_polynomial_error(): x = np.array([1, 2, 3, 4, 5, 6]) d = 2 xreg = None with pytest.raises(ValueError) as ve: auto_arima(x, d=d, D=0, seasonal=False, exogenous=xreg) err_msg = pytest_error_str(ve) assert 'simple polynomial' in err_msg, err_msg # but it should pass when xreg is not none xreg = rs.rand(x.shape[0], 2) _ = auto_arima(x, d=d, D=0, seasonal=False, # noqa: F841 exogenous=xreg, error_action='ignore', suppress_warnings=True)
def test_multiple(err): class FooError(BaseException): pass with pytest.raises(FooError) as fe: with ctx.except_and_reraise( ValueError, KeyError, TypeError, raise_err=FooError, raise_msg="gotcha, fam", ): raise err("Boo!") assert "gotcha, fam" in pytest_error_str(fe)
def test_check_m(m, seasonal, expect_error, expect_warning, expected_val): if expect_error: with pytest.raises(ValueError) as ve: val.check_m(m, seasonal) assert 'must be a positive integer' in pytest_error_str(ve) else: if expect_warning: with pytest.warns(UserWarning) as w: res = val.check_m(m, seasonal) assert any('set for non-seasonal fit' in s for s in pytest_warning_messages(w)) else: with pytest.warns(None) as w: res = val.check_m(m, seasonal) assert not w assert expected_val == res
def test_oob_for_issue_29(): dta = sm.datasets.sunspots.load_pandas().data dta.index = pd.Index(sm.tsa.datetools.dates_from_range('1700', '2008')) del dta["YEAR"] xreg = np.random.RandomState(1).rand(dta.shape[0], 3) # Try for cv on/off, various D levels, and various Xregs for d in (0, 1): for cv in (0, 3): for exog in (xreg, None): # surround with try/except so we can log the failing combo try: model = ARIMA(order=(2, d, 0), out_of_sample_size=cv).fit(dta, exogenous=exog) # If exogenous is defined, we need to pass n_periods of # exogenous rows to the predict function. Otherwise we'll # just leave it at None if exog is not None: xr = exog[:3, :] else: xr = None _, _ = model.predict(n_periods=3, return_conf_int=True, exogenous=xr) # Statsmodels can be fragile with ARMA coefficient # computation. If we encounter that, pass: # ValueError: The computed initial MA coefficients are # not invertible. You should induce invertibility, # choose a different model order, or ... except Exception as ex: # print("Failing combo: d=%i, cv=%i, exog=%r" # % (d, cv, exog)) if "invertibility" in pytest_error_str(ex): pass else: raise
def test_check_information_criterion(ic, ooss, expect_error, expect_warning, expected_val): if expect_error: with pytest.raises(ValueError) as ve: val.check_information_criterion(ic, ooss) assert 'not defined for information_criteria' in pytest_error_str(ve) else: if expect_warning: with pytest.warns(UserWarning) as w: res = val.check_information_criterion(ic, ooss) assert any('information_criterion cannot be' in s for s in pytest_warning_messages(w)) else: with pytest.warns(None) as w: res = val.check_information_criterion(ic, ooss) assert not w assert expected_val == res
def test_new_serialization(): arima = ARIMA(order=(0, 0, 0), suppress_warnings=True).fit(y) # Serialize it, show there is no tmp_loc_ pkl_file = "file.pkl" new_loc = "ts_wrapper.pkl" try: joblib.dump(arima, pkl_file) # Assert it does NOT use the old-style pickling assert not _uses_legacy_pickling(arima) loaded = joblib.load(pkl_file) assert not _uses_legacy_pickling(loaded) preds = loaded.predict() os.unlink(pkl_file) # Now save out the arima_res_ piece separately, and show we can load # it from the legacy method arima.summary() arima.arima_res_.save(fname=new_loc) arima.tmp_pkl_ = new_loc assert _uses_legacy_pickling(arima) # Save/load it and show it works joblib.dump(arima, pkl_file) loaded2 = joblib.load(pkl_file) assert_array_almost_equal(loaded2.predict(), preds) # De-cache arima._clear_cached_state() assert not os.path.exists(new_loc) # Show we get an OSError now with pytest.raises(OSError) as ose: joblib.load(pkl_file) assert "Does it still" in pytest_error_str(ose), ose finally: _unlink_if_exists(pkl_file) _unlink_if_exists(new_loc)
def test_value_error_on_neg_lambda(): trans = BoxCoxEndogTransformer(lmbda2=-4.) with pytest.raises(ValueError) as ve: trans.fit_transform([1, 2, 3]) assert 'lmbda2 must be a non-negative' in pytest_error_str(ve)
def test_bad_last_stage(self, stages): # Will fail since the last stage is not an estimator with pytest.raises(TypeError) as ve: Pipeline(stages) assert "Last step of Pipeline should be" in pytest_error_str(ve)
def test_bad_window_size(): cv = SlidingWindowForecastCV(window_size=2, step=1, h=4) with pytest.raises(ValueError) as ve: list(cv.split(y)) assert "> 2" in pytest_error_str(ve)
def test_value_error_on_update_check(): with pytest.raises(ValueError) as ve: base.UpdatableMixin()._check_endog(None) assert 'cannot be None' in pytest_error_str(ve)
def test_value_error_on_fit(): feat = FourierFeaturizer(m=12, k=8) with pytest.raises(ValueError) as ve: feat.fit_transform(wineind) assert 'k must be' in pytest_error_str(ve)
def test_value_error_check(): feat = FourierFeaturizer(m=12) with pytest.raises(ValueError) as ve: feat._check_y_X(wineind, None, null_allowed=False) assert 'non-None' in pytest_error_str(ve)