facebookresearch / Kats

Kats, a kit to analyze time series data, a lightweight, easy-to-use, generalizable, and extendable framework to perform time series analysis, from understanding the key statistics and characteristics, detecting change points and anomalies, to forecasting future trends.
MIT License
4.88k stars 534 forks source link

Save serialized prophet model #242

Closed rosalinesway closed 2 years ago

rosalinesway commented 2 years ago

Hi,

I tried using the kats package with the default prophet functions to serialize the prophet model using the below code:

from kats.models.prophet import ProphetModel, ProphetParams
import json
from prophet.serialize import model_to_json, model_from_json
# create a model param instance
params = ProphetParams(seasonality_mode=args.seasonality_mode)  # additive mode gives worse results
m = ProphetModel(DATA_DF, params)
m.fit()
save_model(m, 'serialized_model.json')

def save_model(model, file_name):
    with open(file_name, 'w') as file:
        json.dump(model_to_json(model), file)

Currently, it is throwing this error:

Traceback (most recent call last):
  File "kats_example.py", line 67, in save_model
    json.dump(model_to_json(model), file)
  File "/home/ubuntu/anaconda3/lib/python3.7/site-packages/prophet/serialize.py", line 56, in model_to_json
    if model.history is None:
AttributeError: 'ProphetModel' object has no attribute 'history'
neelabalan commented 2 years ago

@rosalinesway

from kats.models.prophet import ProphetModel, ProphetParams
from fbprophet.serialize import model_to_json

m = ProphetModel(TimeSeriesData(df),  ProphetParams(seasonality_mode='multiplicative'))
m.fit()

with open('serialized_model.json', 'w') as file:
    file.write(model_to_json(m.model))
rosalinesway commented 2 years ago

@neelabalan I ran the same command as you showed, and the same error occurred AttributeError: 'ProphetModel' object has no attribute 'history'

neelabalan commented 2 years ago

@rosalinesway

screenshot_kats json_kats

rosalinesway commented 2 years ago

ok, I think what breaks is using the ProphetModel from the result of the backtester.


ALL_ERRORS = ["mape", "smape", "mae", "mase", "mse", "rmse"]
backtester_prophet = CrossValidation(
        error_methods=ALL_ERRORS,
        data=DATA_TS,
        params=params,
        train_percentage=50,
        test_percentage=20,
        model_class=ProphetModel,
        num_folds=10,
)
backtester_prophet.run_cv()

backtester_errors["prophet"] = {}
for error, value in backtester_prophet.errors.items():
    backtester_errors["prophet"][error] = value

# results: List of tuples
# (training_data, testing_data, trained_model, forecast_predictions)
(
        train_data,
        test_data,
        trained_model,
        forecast_predictions,
) = backtester_prophet.results[0]
neelabalan commented 2 years ago

did you use trained_model.model? The difference is

type(trained_model)
# kats.models.prophet.ProphetModel

type(trained_model.model)
# fbprophet.forecaster.Prophet

The above backtester example works fine for me

from kats.utils import backtesters

ALL_ERRORS = ["mape", "smape", "mae", "mase", "mse", "rmse"]
backtester_prophet = backtesters.CrossValidation(
        error_methods=ALL_ERRORS,
        data=tsd,
        params=ProphetParams(seasonality_mode='multiplicative'),
        train_percentage=50,
        test_percentage=20,
        model_class=ProphetModel,
        num_folds=10,
)
backtester_prophet.run_cv()

(
        train_data,
        test_data,
        trained_model,
        forecast_predictions,
) = backtester_prophet.results[0]

with open('serialized_model.json', 'w') as file:
    file.write(model_to_json(trained_model.model))
rosalinesway commented 2 years ago

@neelabalan that did work, thanks!