def test_predictions_with_additional_regressors(sample_data): ''' TODO: update ''' my_chronos = Chronos(n_changepoints=0, max_iter=100) my_chronos.add_regressors("reg1", "mul") my_chronos.add_regressors("reg2", "mul") # Check not including the regressor throws an error with pytest.raises(KeyError): my_chronos.fit(sample_data) # Now check with the regressor sample_data['reg1'] = [1] * sample_data.shape[0] sample_data['reg2'] = [1] * sample_data.shape[0] my_chronos.fit(sample_data) future_df = my_chronos.make_future_dataframe(include_history=False) # Check not including the regressor throws an error with pytest.raises(KeyError): predictions = my_chronos.predict(future_df) # Now check with the regressor future_df['reg1'] = [1] * future_df.shape[0] future_df['reg2'] = [1] * future_df.shape[0] predictions = my_chronos.predict(future_df) predictions.drop('y', axis=1, inplace=True) assert (predictions.isna().sum().sum() == 0)
def test_plotting_no_history(capsys, monkeypatch, sample_data): ''' Test the plotting of data when no history is provided. This was an issue raised in issue #2. ''' for distribution in chronos_utils.SUPPORTED_DISTRIBUTIONS: my_chronos = Chronos(n_changepoints=0, max_iter=100, distribution=distribution) my_chronos.fit(sample_data) future_df = my_chronos.make_future_dataframe(include_history=False) predictions = my_chronos.predict(future_df) fig = plt.figure(figsize=(15,5)) gs = gridspec.GridSpec(1,1, figure=fig) gs_section = gs[0,0] ax = fig.add_subplot(gs_section) #chronos_plotting.plot_predictions(predictions, my_chronos, fig=fig, gs_section=gs_section) chronos_plotting.plot_predictions(predictions, my_chronos, axs=ax) plt.savefig("test_prediction_no_history.png") std_error = capsys.readouterr().err assert(std_error == "") os.remove("test_prediction_no_history.png")
def test_error_for_nan_values(sample_data): ''' Tests that Chronos complains when given nan values to fit on, but not to predict on ''' def add_dummy_regressors(data): z = data.index.values y = 0.01 * z + np.sin(z / 30) data['y'] = y # should be easy since the target is just dummy1 + dummy2 dummy1 = 0.01 * z dummy2 = np.sin(z / 30) data['dummy1'] = dummy1 data['dummy2'] = dummy2 return data sample_data = add_dummy_regressors(sample_data) my_chronos = Chronos(max_iter=200) # add dummies my_chronos.add_regressors("dummy1") my_chronos.add_regressors("dummy2") # check nan values fail for all columns for col in ['ds', 'y', 'dummy1', 'dummy2']: sample_data_with_nans = sample_data.copy() sample_data_with_nans.loc[0, col] = np.nan with pytest.raises(ValueError): my_chronos.fit(sample_data_with_nans) # check original data works my_chronos.fit(sample_data) future_df = my_chronos.make_future_dataframe() future_df = add_dummy_regressors(future_df) # check nan values fail for all columns EXCEPT # the target column when making predictions for col in ['ds', 'y', 'dummy1', 'dummy2']: future_df_with_nans = future_df.copy() future_df_with_nans.loc[0, col] = np.nan if (col == 'y'): predictions = my_chronos.predict(future_df_with_nans) else: with pytest.raises(ValueError): predictions = my_chronos.predict(future_df_with_nans)
def test_prediction_with_easy_extra_regressors(sample_data): ''' Test that when the size of the data is too small, the number of changepoints gets adjusted ''' z = sample_data.index.values y = 0.01 * z + np.sin(z / 30) sample_data['y'] = y # should be easy since the target is just dummy1 + dummy2 dummy1 = 0.01 * z dummy2 = np.sin(z / 30) sample_data['dummy1'] = dummy1 sample_data['dummy2'] = dummy2 for distribution in chronos_utils.SUPPORTED_DISTRIBUTIONS: # Student t distribution has issues with the long tails if (distribution != chronos_utils.StudentT_dist_code): my_chronos = Chronos(max_iter=200, distribution=distribution) # add dummies my_chronos.add_regressors("dummy1") my_chronos.add_regressors("dummy2") my_chronos.fit(sample_data) future_df = my_chronos.make_future_dataframe() # Add dummies to future df z = future_df.index.values y = 0.01 * z + np.sin(z / 30) future_df['y'] = y dummy1 = 0.01 * z dummy2 = np.sin(z / 30) future_df['dummy1'] = dummy1 future_df['dummy2'] = dummy2 # Make predictions predictions = my_chronos.predict(future_df) # The predictions should be almost the same as the target assert (np.mean(np.abs(predictions['y'] - predictions['yhat'])) < 0.1)
def test_predictions_not_nan(sample_data): ''' Make sure no nans are returned during the prediction process ''' for method in ["MAP", "MLE"]: for distribution in chronos_utils.SUPPORTED_DISTRIBUTIONS: my_chronos = Chronos(n_changepoints=0, max_iter=100, distribution=distribution, method=method) my_chronos.fit(sample_data) future_df = my_chronos.make_future_dataframe(include_history=False) predictions = my_chronos.predict(future_df) predictions.drop('y', axis=1, inplace=True) #print(predictions) assert (predictions.isna().sum().sum() == 0)
def test_prediction_too_small_for_default_changepoints(sample_data): ''' Test that when the size of the data is too small, the number of changepoints gets adjusted ''' for distribution in chronos_utils.SUPPORTED_DISTRIBUTIONS: my_chronos = Chronos(max_iter=100, n_changepoints=20, distribution=distribution) # This should raise a warning about the size of the data and changepoint number with pytest.warns(RuntimeWarning): my_chronos.fit(sample_data.iloc[:10]) future_df = my_chronos.make_future_dataframe() predictions = my_chronos.predict(future_df) assert (my_chronos._Chronos__number_of_changepoints < sample_data.shape[0])
def test_plotting(capsys, monkeypatch, sample_data): ''' Test the plotting of data when no history is provided. This was an issue raised in issue #2. ''' for distribution in chronos_utils.SUPPORTED_DISTRIBUTIONS: my_chronos = Chronos(n_changepoints=0, max_iter=100, distribution=distribution) my_chronos.fit(sample_data) future_df = my_chronos.make_future_dataframe(include_history=True) predictions = my_chronos.predict(future_df) with pytest.warns(UserWarning): chronos_plotting.plot_components(predictions, my_chronos, figure_name="test_prediction.png") std_error = capsys.readouterr().err assert(std_error == "") os.remove("test_prediction.png")