コード例 #1
0
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)
コード例 #2
0
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)
コード例 #3
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")
コード例 #4
0
def test_prediction_no_seasonality(sample_data):
    '''
        Test that predictions without seasonality
        can be done, and that the trend is close to
        predictions since without seasonality
        only the distribution parameters should
        modify the predictions
    '''
    for distribution in chronos_utils.SUPPORTED_DISTRIBUTIONS:
        if (distribution not in [
                chronos_utils.Poisson_dist_code,
                chronos_utils.HalfNormal_dist_code
        ]):
            # Poisson and half-normal produes very strange results here
            my_chronos = Chronos(n_changepoints=6,
                                 max_iter=100,
                                 distribution=distribution,
                                 year_seasonality_order=0,
                                 month_seasonality_order=0,
                                 weekly_seasonality_order=0)
            my_chronos.fit(sample_data)

            predictions = my_chronos.predict(sample_number=2000,
                                             period=30,
                                             frequency='D')

            assert (np.mean(np.abs(predictions['yhat'] - predictions['trend']))
                    <= 0.1)
コード例 #5
0
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)
コード例 #6
0
def test_prediction_no_changepoints(sample_data):
    '''
        Test that predictions work without
        changepoints and that fitting can 
        still be done
    '''
    for distribution in chronos_utils.SUPPORTED_DISTRIBUTIONS:
        my_chronos = Chronos(n_changepoints=0,
                             distribution=distribution,
                             max_iter=100)
        my_chronos.fit(sample_data)

        predictions = my_chronos.predict(sample_number=2000,
                                         period=30,
                                         frequency='D')

        assert (my_chronos._Chronos__number_of_changepoints == 0)
コード例 #7
0
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)
コード例 #8
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])
コード例 #9
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")