From 6e51130f28092099b4bc3b1c7c6349359c60be22 Mon Sep 17 00:00:00 2001 From: Ben Letham Date: Mon, 3 Feb 2020 17:02:23 -0800 Subject: [PATCH] Use fit kwargs in cross validation (#1040) --- R/R/diagnostics.R | 3 ++- R/R/prophet.R | 4 +++- R/tests/testthat/test_prophet.R | 1 + python/fbprophet/diagnostics.py | 2 +- python/fbprophet/forecaster.py | 3 +++ python/fbprophet/tests/test_diagnostics.py | 2 +- python/fbprophet/tests/test_prophet.py | 1 + 7 files changed, 12 insertions(+), 4 deletions(-) diff --git a/R/R/diagnostics.R b/R/R/diagnostics.R index 51b46ac..2a52f52 100644 --- a/R/R/diagnostics.R +++ b/R/R/diagnostics.R @@ -117,7 +117,8 @@ cross_validation <- function( if (nrow(history.c) < 2) { stop('Less than two datapoints before cutoff. Increase initial window.') } - m <- fit.prophet(m, history.c) + fit.args <- c(list(m=m, df=history.c), model$fit.kwargs) + m <- do.call(fit.prophet, fit.args) # Calculate yhat df.predict <- dplyr::filter(df, ds > cutoff, ds <= cutoff + horizon.dt) # Get the columns for the future dataframe diff --git a/R/R/prophet.R b/R/R/prophet.R index c8c8948..da9174b 100644 --- a/R/R/prophet.R +++ b/R/R/prophet.R @@ -134,7 +134,8 @@ prophet <- function(df = NULL, history.dates = NULL, train.holiday.names = NULL, train.component.cols = NULL, - component.modes = NULL + component.modes = NULL, + fit.kwargs = list() ) m <- validate_inputs(m) class(m) <- append("prophet", class(m)) @@ -1208,6 +1209,7 @@ fit.prophet <- function(m, df, ...) { component.cols <- out2$component.cols m$train.component.cols <- component.cols m$component.modes <- out2$modes + m$fit.kwargs <- list(...) m <- set_changepoints(m) diff --git a/R/tests/testthat/test_prophet.R b/R/tests/testthat/test_prophet.R index c1f895f..8dd6288 100644 --- a/R/tests/testthat/test_prophet.R +++ b/R/tests/testthat/test_prophet.R @@ -114,6 +114,7 @@ test_that("logistic_floor", { expect_true(m$logistic.floor) expect_true('floor' %in% colnames(m$history)) expect_equal(m$history$y_scaled[1], 1., tolerance = 1e-6) + expect_equal(m$fit.kwargs, list(algorithm = 'Newton')) fcst1 <- predict(m, future1) m2 <- prophet(growth = 'logistic') diff --git a/python/fbprophet/diagnostics.py b/python/fbprophet/diagnostics.py index dcbe927..3f37198 100644 --- a/python/fbprophet/diagnostics.py +++ b/python/fbprophet/diagnostics.py @@ -117,7 +117,7 @@ def cross_validation(model, horizon, period=None, initial=None): 'Less than two datapoints before cutoff. ' 'Increase initial window.' ) - m.fit(history_c) + m.fit(history_c, **model.fit_kwargs) # Calculate yhat index_predicted = (df['ds'] > cutoff) & (df['ds'] <= cutoff + horizon) # Get the columns for the future dataframe diff --git a/python/fbprophet/forecaster.py b/python/fbprophet/forecaster.py index ac33bf9..354a28c 100644 --- a/python/fbprophet/forecaster.py +++ b/python/fbprophet/forecaster.py @@ -8,6 +8,7 @@ from __future__ import absolute_import, division, print_function import logging from collections import OrderedDict, defaultdict +from copy import deepcopy from datetime import timedelta import numpy as np @@ -137,6 +138,7 @@ class Prophet(object): self.train_component_cols = None self.component_modes = None self.train_holiday_names = None + self.fit_kwargs = {} self.validate_inputs() def validate_inputs(self): @@ -1080,6 +1082,7 @@ class Prophet(object): self.make_all_seasonality_features(history)) self.train_component_cols = component_cols self.component_modes = modes + self.fit_kwargs = deepcopy(kwargs) self.set_changepoints() diff --git a/python/fbprophet/tests/test_diagnostics.py b/python/fbprophet/tests/test_diagnostics.py index 148252a..07402c8 100644 --- a/python/fbprophet/tests/test_diagnostics.py +++ b/python/fbprophet/tests/test_diagnostics.py @@ -109,7 +109,7 @@ class TestDiagnostics(TestCase): df = self.__df.copy() for uncertainty in [0, False]: m = Prophet(uncertainty_samples=uncertainty) - m.fit(df) + m.fit(df, algorithm='Newton') df_cv = diagnostics.cross_validation( m, horizon='4 days', period='4 days', initial='115 days') expected_cols = ['ds', 'yhat', 'y', 'cutoff'] diff --git a/python/fbprophet/tests/test_prophet.py b/python/fbprophet/tests/test_prophet.py index 7b13dcb..df62131 100644 --- a/python/fbprophet/tests/test_prophet.py +++ b/python/fbprophet/tests/test_prophet.py @@ -142,6 +142,7 @@ class TestProphet(TestCase): self.assertTrue(m.logistic_floor) self.assertTrue('floor' in m.history) self.assertAlmostEqual(m.history['y_scaled'][0], 1.) + self.assertEqual(m.fit_kwargs, {'algorithm': 'Newton'}) fcst1 = m.predict(future) m2 = Prophet(growth='logistic')