unit8co / darts

A python library for user-friendly forecasting and anomaly detection on time series.
https://unit8co.github.io/darts/
Apache License 2.0
7.95k stars 866 forks source link

How to return standard deviation of posterior distribution from Bayesian Ridge Regression #2299

Closed ettan10 closed 1 month ago

ettan10 commented 6 months ago

I initialized a RegressionModel which is wrapped around the Bayesian Ridge Regression Model from sklearn.

As Bayesian Ridge Regression returns a distribution per point, I am looking to plot the confidence interval of each point that is predicted. The original method in sklearn gives the option to return both the mean and standard deviation of the distribution if necessary. From the standard deviation, I can then compute the confidence interval of each point. image

How do I call this parameter in darts? This is how I initialized my model:

br_model = RegressionModel(
    lags=target_lags,
    lags_past_covariates=past_cov_lags, 
    lags_future_covariates=future_cov_lags,
    output_chunk_length=forecast_horizon,
    multi_models=True,
    model=BayesianRidge()
)

This is how I do my historical forecast. I tried including return_std in the predict_kwargs but got an error:

br_model.fit(
            series = target_fit,
            past_covariates= past_cov_fit,
            future_covariates= future_cov_fit'
        )

br_model.historical_forecasts(
                series=target_hf, 
                past_covariates= past_cov_hf,
                future_covariates= future_cov_hf,
                start=start' 
                retrain=retrain,
                forecast_horizon=forecast_horizon,
                stride=stride,
                train_length = train_length
                verbose=True,
                last_points_only=False,
                predict_kwargs = {'return_std':True}
) 

image

madtoinou commented 6 months ago

Hi @ettan10,

Darts does not support the kwargs of the predict() method for the Bayesian Ridge Regression, as it will change the shape of the output and break a considerable amount of the logic in methods such as historical_forecasts() for example. Also, depending on output_chunk_length and the number of dimension in your target series, the model might be wrapper in the MultiOutputRegressor class...

In order to extract it, you need to modify a considerable amount of code, starting with _predict_and_sample() in order to store/return y_std and propagate this change to all the methods relying on it (notably predict() and historical_forecasts()).

ettan10 commented 6 months ago

@madtoinou thanks for the clarification. is there another way you can suggest that I can compute the confidence interval of the predictions based on the respective underlying distribution?

madtoinou commented 5 months ago

If you really want to use this model, you could probably compute it manually from the forecasted values and the sigma_ and alpha_ attributes of the model (that you will need to store after each call to fit()), using the same logic as sklearn source. Make sure to use the right parameters when applying them to some forecasts (or directly modify historical_forecasts() for-loop).

If you can use another model, you can make them probabilistic (see example) and generate forecasts with num_samples > 1.