From fc8fa49aac68d0a81f79acb6ee3550992cedd8df Mon Sep 17 00:00:00 2001 From: loulo1 <78915009+loulo1@users.noreply.github.com> Date: Mon, 8 Mar 2021 12:36:38 +0100 Subject: [PATCH 1/3] Fix the issue #1814 I did as PyStanBackend. And now when we use the method fit of Prophet, we can do like in the documentation: https://facebook.github.io/prophet/docs/additional_topics.html#updating-fitted-models def stan_init(m): """Retrieve parameters from a trained model. Retrieve parameters from a trained model in the format used to initialize a new Stan model. Parameters ---------- m: A trained model of the Prophet class. Returns ------- A Dictionary containing retrieved parameters of 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 df = pd.read_csv('../examples/example_wp_log_peyton_manning.csv') df1 = df.loc[df['ds'] < '2016-01-19', :] # All data except the last day m1 = Prophet().fit(df1) # A model fit to all data except the last day %timeit m2 = Prophet().fit(df) # Adding the last day, fitting from scratch %timeit m2 = Prophet().fit(df, init=stan_init(m1)) # Adding the last day, warm-starting from m1 Update models.py Update models.py Update models.py Update models.py Update models.py Update models.py Update models.py Test Test2 Test4 Test4 Test are fixed --- python/fbprophet/models.py | 54 ++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/python/fbprophet/models.py b/python/fbprophet/models.py index 8b62275..c75bc93 100644 --- a/python/fbprophet/models.py +++ b/python/fbprophet/models.py @@ -87,25 +87,30 @@ class CmdStanPyBackend(IStanBackend): def fit(self, stan_init, stan_data, **kwargs): (stan_init, stan_data) = self.prepare_data(stan_init, stan_data) - if 'algorithm' not in kwargs: - kwargs['algorithm'] = 'Newton' if stan_data['T'] < 100 else 'LBFGS' - iterations = int(1e4) + if 'init' in kwargs: + kwargs['init'] = self.prepare_data(kwargs['init'], stan_data)[0] + + args = dict( + data=stan_data, + init=stan_init, + algorithm='Newton' if stan_data['T'] < 100 else 'LBFGS', + iter=int(1e4), + ) + args.update(kwargs) + + args['inits'] = args['init'] + del args['init'] + try: - self.stan_fit = self.model.optimize(data=stan_data, - inits=stan_init, - iter=iterations, - **kwargs) + self.stan_fit = self.model.optimize(**args) except RuntimeError as e: # Fall back on Newton - if self.newton_fallback and kwargs['algorithm'] != 'Newton': + if self.newton_fallback and args['algorithm'] != 'Newton': logger.warning( 'Optimization terminated abnormally. Falling back to Newton.' ) - kwargs['algorithm'] = 'Newton' - self.stan_fit = self.model.optimize(data=stan_data, - inits=stan_init, - iter=iterations, - **kwargs) + args['algorithm'] = 'Newton' + self.stan_fit = self.model.optimize(**args) else: raise e @@ -117,17 +122,28 @@ class CmdStanPyBackend(IStanBackend): def sampling(self, stan_init, stan_data, samples, **kwargs) -> dict: (stan_init, stan_data) = self.prepare_data(stan_init, stan_data) + if 'init' in kwargs: + kwargs['init'] = self.prepare_data(kwargs['init'], stan_data)[0] + + args = dict( + data=stan_data, + init=stan_init, + algorithm='Newton' if stan_data['T'] < 100 else 'LBFGS', + ) if 'chains' not in kwargs: kwargs['chains'] = 4 iter_half = samples // 2 + kwargs['iter_sampling'] = iter_half if 'iter_warmup' not in kwargs: kwargs['iter_warmup'] = iter_half + + args.update(kwargs) - self.stan_fit = self.model.sample(data=stan_data, - inits=stan_init, - iter_sampling=iter_half, - **kwargs) + args['inits'] = args['init'] + del args['init'] + + self.stan_fit = self.model.sample(**args) res = self.stan_fit.sample (samples, c, columns) = res.shape res = res.reshape((samples * c, columns)) @@ -166,10 +182,10 @@ class CmdStanPyBackend(IStanBackend): 'm': init['m'], 'delta': init['delta'].tolist(), 'beta': init['beta'].tolist(), - 'sigma_obs': 1 + 'sigma_obs': init['sigma_obs'] } return (cmdstanpy_init, cmdstanpy_data) - + @staticmethod def stan_to_dict_numpy(column_names: Tuple[str, ...], data: 'np.array'): import numpy as np From 3a0061e8e19fc2a297bed7ec0d54dec5601baa91 Mon Sep 17 00:00:00 2001 From: loulo1 <78915009+loulo1@users.noreply.github.com> Date: Wed, 14 Apr 2021 15:39:02 +0200 Subject: [PATCH 2/3] change init into inits for CmdStanPyBackend --- python/fbprophet/models.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/python/fbprophet/models.py b/python/fbprophet/models.py index c75bc93..59a741a 100644 --- a/python/fbprophet/models.py +++ b/python/fbprophet/models.py @@ -87,20 +87,18 @@ class CmdStanPyBackend(IStanBackend): def fit(self, stan_init, stan_data, **kwargs): (stan_init, stan_data) = self.prepare_data(stan_init, stan_data) - if 'init' in kwargs: - kwargs['init'] = self.prepare_data(kwargs['init'], stan_data)[0] + + if 'inits' not in kwargs and 'init' in kwargs: + kwargs['inits'] = self.prepare_data(kwargs['init'], stan_data)[0] args = dict( data=stan_data, - init=stan_init, + inits=stan_init, algorithm='Newton' if stan_data['T'] < 100 else 'LBFGS', iter=int(1e4), ) args.update(kwargs) - args['inits'] = args['init'] - del args['init'] - try: self.stan_fit = self.model.optimize(**args) except RuntimeError as e: @@ -122,12 +120,13 @@ class CmdStanPyBackend(IStanBackend): def sampling(self, stan_init, stan_data, samples, **kwargs) -> dict: (stan_init, stan_data) = self.prepare_data(stan_init, stan_data) - if 'init' in kwargs: - kwargs['init'] = self.prepare_data(kwargs['init'], stan_data)[0] + + if 'inits' not in kwargs and 'init' in kwargs: + kwargs['inits'] = self.prepare_data(kwargs['init'], stan_data)[0] args = dict( data=stan_data, - init=stan_init, + inits=stan_init, algorithm='Newton' if stan_data['T'] < 100 else 'LBFGS', ) @@ -140,9 +139,6 @@ class CmdStanPyBackend(IStanBackend): args.update(kwargs) - args['inits'] = args['init'] - del args['init'] - self.stan_fit = self.model.sample(**args) res = self.stan_fit.sample (samples, c, columns) = res.shape From 847ecee03341123a1afafd9d7048c57fd60646c9 Mon Sep 17 00:00:00 2001 From: Ben Letham Date: Tue, 20 Apr 2021 17:43:10 -0700 Subject: [PATCH 3/3] Merge --- python/fbprophet/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/fbprophet/models.py b/python/fbprophet/models.py index 59a741a..ca81631 100644 --- a/python/fbprophet/models.py +++ b/python/fbprophet/models.py @@ -140,7 +140,7 @@ class CmdStanPyBackend(IStanBackend): args.update(kwargs) self.stan_fit = self.model.sample(**args) - res = self.stan_fit.sample + res = self.stan_fit.draws() (samples, c, columns) = res.shape res = res.reshape((samples * c, columns)) params = self.stan_to_dict_numpy(self.stan_fit.column_names, res)