Explorar o código

Fix missing columns in SHF with extra regressor

bletham %!s(int64=7) %!d(string=hai) anos
pai
achega
5d453c1d05

+ 1 - 1
R/DESCRIPTION

@@ -1,6 +1,6 @@
 Package: prophet
 Title: Automatic Forecasting Procedure
-Version: 0.2.1
+Version: 0.2.1.9000
 Date: 2017-11-08
 Authors@R: c(
   person("Sean", "Taylor", email = "sjt@fb.com", role = c("cre", "aut")),

+ 2 - 0
R/R/diagnostics.R

@@ -83,6 +83,7 @@ simulated_historical_forecasts <- function(model, horizon, units, k,
     m <- fit.prophet(m, history.c)
     # Calculate yhat
     df.predict <- dplyr::filter(df, ds > cutoff, ds <= cutoff + horizon)
+    # Get the columns for the future dataframe
     columns <- c('ds')
     if (m$growth == 'logistic') {
       columns <- c(columns, 'cap')
@@ -90,6 +91,7 @@ simulated_historical_forecasts <- function(model, horizon, units, k,
         columns <- c(columns, 'floor')
       }
     }
+    columns <- c(columns, names(m$extra_regressors))
     future <- df[columns]
     yhat <- stats::predict(m, future)
     # Merge yhat, y, and cutoff.

+ 19 - 0
R/tests/testthat/test_diagnostics.R

@@ -47,6 +47,25 @@ test_that("simulated_historical_forecasts_logistic", {
   expect_equal(sum((df.merged$y.x - df.merged$y.y) ** 2), 0)
 })
 
+test_that("simulated_historical_forecasts_extra_regressors", {
+  skip_if_not(Sys.getenv('R_ARCH') != '/i386')
+  df <- DATA
+  df$extra <- seq(0, nrow(df) - 1)
+  m <- prophet()
+  m <- add_seasonality(m, name = 'monthly', period = 30.5, fourier.order = 5)
+  m <- add_regressor(m, 'extra')
+  m <- fit.prophet(m, df)
+  df.shf <- simulated_historical_forecasts(
+    m, horizon = 3, units = 'days', k = 2, period = 3)
+  # All cutoff dates should be less than ds dates
+  expect_true(all(df.shf$cutoff < df.shf$ds))
+  # The unique size of output cutoff should be equal to 'k'
+  expect_equal(length(unique(df.shf$cutoff)), 2)
+  # Each y in df_shf and DATA with same ds should be equal
+  df.merged <- dplyr::left_join(df.shf, m$history, by="ds")
+  expect_equal(sum((df.merged$y.x - df.merged$y.y) ** 2), 0)
+})
+
 test_that("simulated_historical_forecasts_default_value_check", {
   skip_if_not(Sys.getenv('R_ARCH') != '/i386')
   m <- prophet(DATA)

+ 1 - 1
python/fbprophet/__init__.py

@@ -7,4 +7,4 @@
 
 from fbprophet.forecaster import Prophet
 
-__version__ = '0.2.1'
+__version__ = '0.2.1.dev'

+ 2 - 0
python/fbprophet/diagnostics.py

@@ -93,11 +93,13 @@ def simulated_historical_forecasts(model, horizon, k, period=None):
         m.fit(df[df['ds'] <= cutoff])
         # Calculate yhat
         index_predicted = (df['ds'] > cutoff) & (df['ds'] <= cutoff + horizon)
+        # Get the columns for the future dataframe
         columns = ['ds']
         if m.growth == 'logistic':
             columns.append('cap')
             if m.logistic_floor:
                 columns.append('floor')
+        columns.extend(m.extra_regressors.keys())
         yhat = m.predict(df[index_predicted][columns])
         # Merge yhat(predicts), y(df, original data) and cutoff
         predicts.append(pd.concat([

+ 19 - 0
python/fbprophet/tests/test_diagnostics.py

@@ -75,6 +75,25 @@ class TestDiagnostics(TestCase):
         self.assertAlmostEqual(
             np.sum((df_merged['y_x'] - df_merged['y_y']) ** 2), 0.0)
 
+    def test_simulated_historical_forecasts_extra_regressors(self):
+        m = Prophet()
+        m.add_seasonality(name='monthly', period=30.5, fourier_order=5)
+        m.add_regressor('extra')
+        df = self.__df.copy()
+        df['cap'] = 40
+        df['extra'] = range(df.shape[0])
+        m.fit(df)
+        df_shf = diagnostics.simulated_historical_forecasts(
+            m, horizon='3 days', k=2, period='3 days')
+        # All cutoff dates should be less than ds dates
+        self.assertTrue((df_shf['cutoff'] < df_shf['ds']).all())
+        # The unique size of output cutoff should be equal to 'k'
+        self.assertEqual(len(np.unique(df_shf['cutoff'])), 2)
+        # Each y in df_shf and self.__df with same ds should be equal
+        df_merged = pd.merge(df_shf, df, 'left', on='ds')
+        self.assertAlmostEqual(
+            np.sum((df_merged['y_x'] - df_merged['y_y']) ** 2), 0.0)
+
     def test_simulated_historical_forecasts_default_value_check(self):
         m = Prophet()
         m.fit(self.__df)