facebook / prophet

Tool for producing high quality forecasts for time series data that has multiple seasonality with linear or non-linear growth.
https://facebook.github.io/prophet
MIT License
18.32k stars 4.52k forks source link

[Bug] Error when updating fitted model using ``stan_init`` #2236

Open jelc53 opened 2 years ago

jelc53 commented 2 years ago

Bug description

When trying to update my model fit with new data using updated fitted model section here (https://facebook.github.io/prophet/docs/additional_topics.html), I get the following error

Traceback (most recent call last): File "<string>", line 1, in <module> File "/virtualenvs/smartshift-load-forecasting-9TtSrW0h-py3.9/lib/python3.9/site-packages/prophet/forecaster.py", line 1171, in fit self.params = self.stan_backend.fit(stan_init, dat, **kwargs) File "/virtualenvs/smartshift-load-forecasting-9TtSrW0h-py3.9/lib/python3.9/site-packages/prophet/models.py", line 90, in fit kwargs['inits'] = self.prepare_data(kwargs['init'], stan_data)[0] File "/virtualenvs/smartshift-load-forecasting-9TtSrW0h-py3.9/lib/python3.9/site-packages/prophet/models.py", line 164, in prepare_data 'y': data['y'].tolist(), AttributeError: 'list' object has no attribute 'tolist'

Note: Potentially a similar issue mentioned here: https://issuemode.com/issues/facebook/prophet/104552814.

Reproducible example

def stan_init(m):
        res = {}
        for pname in ['k', 'm', 'sigma_obs']:
            res[pname] = m.params[pname][0][0]
        for pname in ['delta', 'beta']:
            res[pname] = m.params[pname][0]
        return res

def update_model_state(input_data, fitted_model, intervals_per_day=None):
        """Update model state of fitted model without updating parameters"""

        old_data = fitted_model.history[['ds', 'y']]
        updated_data = pd.concat([old_data, input_data], axis=0).reset_index(drop=True)

        updated_model = Prophet(
            seasonality_mode='multiplicative',
            yearly_seasonality=False,
            weekly_seasonality=False,
            daily_seasonality=True,
        ).fit(
            updated_data,
            init=AutoArimaProphet.stan_init(fitted_model)  # warm fit
        )
        return updated_model

if __name__ == '__main__':

read in fb_input_data ...

estimator = Prophet(
                seasonality_mode='multiplicative',
                yearly_seasonality=False,
                weekly_seasonality=True,
                daily_seasonality=True,
            )
fitted_model = estimator.fit(fb_train_data)

fitted_model = update_model_state(
                input_data=fb_input_data,
                fitted_model=fitted_model
            )

Unable to provide data since sensitive, but here is a santiized excert.

               ds         y

0 2022-03-01 00:00:00 7.677567 1 2022-03-01 00:30:00 7.840946 2 2022-03-01 01:00:00 7.888173 3 2022-03-01 01:30:00 7.870759 4 2022-03-01 02:00:00 7.714092

jelc53 commented 2 years ago

Solved (I think). Needed to pass inits rather than init to match cmdstanpy kwargs interface. Suggest the documentation needs updating https://facebook.github.io/prophet/docs/additional_topics.html#updating-fitted-models

o1martinez commented 2 years ago

Your solution works thank you sir! Documentation indeed needs updating