def fit(df, args): m = Prophet(changepoint_prior_scale=args.changepoint_prior_scale, interval_width=args.interval_width, mcmc_samples=args.mcmc_samples) m.add_country_holidays(country_name='US') # m.add_regressor('low', prior_scale=0.5, mode='multiplicative') ? print(f'Model is trained on {len(df)} data') m.fit(df) return m
def run_prophet_train(df): m = Prophet(daily_seasonality=True, weekly_seasonality=True) m.add_country_holidays(country_name='CN') m.add_seasonality(name='weekly', period=7, fourier_order=3, prior_scale=0.1) m.fit(df) pass
def get_model_forecast(info): ds = ast.literal_eval(info['train_ds']) y = ast.literal_eval(info['train_y']) avg_prc = ast.literal_eval(info['train_avg_prc']) test_y = ast.literal_eval(info['test_y']) test_avg_prc = ast.literal_eval(info['test_avg_prc']) dic = {'ds': ds, 'y': y, 'avg_prc': avg_prc} data = pd.DataFrame(dic) holidays = pd.read_json(info['holidays']) ## feature engineering if data['avg_prc'].max() > 0: data['avg_prc'] = data['avg_prc'] / data['avg_prc'].max() * 100 else: data['avg_prc'] = data['avg_prc'] / (data['avg_prc'].max() + 1) * 100 data['cap'] = 100.0 data['floor'] = 0.0 ## run prophet model = Prophet(growth='logistic', holidays=holidays) model.add_country_holidays(country_name='KR') model.add_seasonality(name='monthly', period=30.5, fourier_order=5) if data['avg_prc'].isna().sum() == 0: model.add_regressor('avg_prc') model.fit(data) ## get estimation future = model.make_future_dataframe(periods=PRED_DAYS) if data['avg_prc'].isna().sum() == 0: future['avg_prc'] = pd.concat( [pd.Series(avg_prc), pd.Series(test_avg_prc)], ignore_index=True) future['cap'] = 100 future['floor'] = 0.0 forecast = model.predict(future) return model, forecast
def get_model_forecast_pred(self): train, test = self.data[:-self.PRED_DAYS], self.data[-self.PRED_DAYS:] model = Prophet(growth='logistic', holidays=self.holidays, holidays_prior_scale=self.holiday_weight, seasonality_prior_scale=self.seasonality_weight, changepoint_prior_scale=self.changepoint_weight, changepoint_range=self.changepoint_range, changepoints=self.changepoints if self.changepoints else None, ) if self.ADD_COUNTRY_HOLIDAY: model.add_country_holidays(country_name='KR') if self.ADD_MONTHLY_SEASONALITY: model.add_seasonality(name='montly_seasonality', period=30.5, fourier_order=5) if self.PRC: model.add_regressor('avg_prc', prior_scale=self.price_weight, standardize=False) model.fit(train) future = model.make_future_dataframe(periods=self.PRED_DAYS) future = pd.merge(future, train, left_on='ds', right_on='ds', how='left') future = future[['ds', 'floor', 'cap', 'avg_prc']] future['avg_prc'] = self.data.avg_prc.values future_fill_missing = {'cap' : 100, 'floor' : 0.0} future.fillna(future_fill_missing, inplace=True) else: model.fit(train) future = model.make_future_dataframe(periods=self.PRED_DAYS) future['cap'] = 100 future['floor'] = 0.0 forecast = model.predict(future) pred = forecast[['ds', 'yhat']][-self.PRED_DAYS:] pred['yhat'] = np.where(pred['yhat'] < 0, 0, pred['yhat']) return model, forecast, pred
def test_fit_predict_with_country_holidays(self): holidays = pd.DataFrame({ 'ds': pd.to_datetime(['2012-06-06', '2013-06-06']), 'holiday': ['seans-bday'] * 2, 'lower_window': [0] * 2, 'upper_window': [1] * 2, }) # Test with holidays and country_holidays model = Prophet(holidays=holidays, uncertainty_samples=0) model.add_country_holidays(country_name='US') model.fit(DATA).predict() # There are training holidays missing in the test set train = DATA.head(154) future = DATA.tail(355) model = Prophet(uncertainty_samples=0) model.add_country_holidays(country_name='US') model.fit(train).predict(future) # There are test holidays missing in the training set train = DATA.tail(355) future = DATA2 model = Prophet(uncertainty_samples=0) model.add_country_holidays(country_name='US') model.fit(train).predict(future)
import pandas as pd from prophet import Prophet # float_precision='high' required for pd.read_csv to match precision of Rover.read_csv df = pd.read_csv('examples/example_wp_log_peyton_manning.csv', float_precision='high') m = Prophet() m.add_country_holidays(country_name='US') m.fit(df, seed=123) future = m.make_future_dataframe(periods=365) forecast = m.predict(future) print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail()) m.plot(forecast).savefig('/tmp/py_country_holidays.png') m.plot_components(forecast).savefig('/tmp/py_country_holidays2.png')
class FBProphetModel(PredictionModel): """Facebook's Prophet prediction model.""" def __init__(self, params: dict, transformation: str = "none"): super().__init__(params, name="FBProphet", transformation=transformation) # Stuff needed to make Prophet shut up during training. self.suppress_stdout_stderr = suppress_stdout_stderr self.fbmodel = Prophet() try: self.fbprophet_parameters = params["model_parameters"]["fbprophet_parameters"] except KeyError: self.fbprophet_parameters = None def train(self, input_data: DataFrame, extra_regressors: DataFrame = None): """Overrides PredictionModel.train()""" if self.fbprophet_parameters is not None: try: timeseries_name = input_data.columns[0] date_format = self.fbprophet_parameters["holidays_dataframes"]["date_format"] holidays = pd.read_csv(self.fbprophet_parameters["holidays_dataframes"][timeseries_name]) holidays.loc[:, "ds"].apply(lambda x: pd.to_datetime(x, format=date_format)) self.fbmodel = Prophet(holidays=holidays) log.debug(f"Using a dataframe for holidays...") except KeyError: self.fbmodel = Prophet() try: holiday_country = self.fbprophet_parameters["holiday_country"] self.fbmodel.add_country_holidays(country_name=holiday_country) log.debug(f"Set {holiday_country} as country for holiday calendar...") except KeyError: pass else: self.fbmodel = Prophet() if extra_regressors is not None: # We could apply self.transformation also on the extra regressors. # From tests, it looks like it doesn't change much/it worsens the forecasts. input_data = input_data.join(extra_regressors) input_data.reset_index(inplace=True) column_indices = [0, 1] new_names = ['ds', 'y'] old_names = input_data.columns[column_indices] input_data.rename(columns=dict(zip(old_names, new_names)), inplace=True) [self.fbmodel.add_regressor(col) for col in extra_regressors.columns] else: input_data.reset_index(inplace=True) input_data.columns = ['ds', 'y'] with self.suppress_stdout_stderr(): self.fbmodel.fit(input_data) ####################### # param_grid = { # 'changepoint_prior_scale': [0.001, 0.01, 0.1, 0.5], # 'seasonality_prior_scale': [0.01, 0.1, 1.0, 10.0], # } # param_grid = { # 'changepoint_prior_scale': [0.001, 0.01], # 'seasonality_prior_scale': [0.01, 0.1], # } # # if extra_regressors is not None: # input_data = input_data.join(extra_regressors) # input_data.reset_index(inplace=True) # column_indices = [0, 1] # new_names = ['ds', 'y'] # old_names = input_data.columns[column_indices] # input_data.rename(columns=dict(zip(old_names, new_names)), inplace=True) # # else: # input_data.reset_index(inplace=True) # input_data.columns = ['ds', 'y'] # # # Generate all combinations of parameters # all_params = [dict(zip(param_grid.keys(), v)) for v in itertools.product(*param_grid.values())] # rmses = [] # Store the RMSEs for each params here # # # Use cross validation to evaluate all parameters # for params in all_params: # m = Prophet(**params) # [m.add_regressor(col) for col in extra_regressors.columns] if extra_regressors is not None else None # with self.suppress_stdout_stderr(): # m.fit(input_data) # Fit model with given params # df_cv = cross_validation(m, horizon=self.prediction_lags, parallel="processes") # df_p = performance_metrics(df_cv, rolling_window=1) # rmses.append(df_p['rmse'].values[0]) # # # Find the best parameters # tuning_results = pd.DataFrame(all_params) # tuning_results['rmse'] = rmses # # best_params = all_params[np.argmin(rmses)] # print(best_params) # # self.fbmodel = Prophet(**best_params) # [self.fbmodel.add_regressor(col) for col in extra_regressors.columns] if extra_regressors is not None else None # with self.suppress_stdout_stderr(): # self.fbmodel.fit(input_data) def predict(self, future_dataframe: DataFrame, extra_regressors: DataFrame = None) -> DataFrame: """Overrides PredictionModel.predict()""" future = future_dataframe.reset_index() future.rename(columns={'index': 'ds'}, inplace=True) if extra_regressors is not None: future.set_index('ds', inplace=True) future = future.join(extra_regressors.copy()) future.reset_index(inplace=True) forecast = self.fbmodel.predict(future) forecast.set_index('ds', inplace=True) return forecast