浏览代码

Merge bugfixes from master into v0.3 (#393)

* Update memory requirement description per #326

* Fix R warning with extra regressor; disallow constant extra regressors.

* Fix unit test broken in new pandas

* Fix diagnostics unit tests for new pandas

* Fix copy with extra seasonalities / regressors Py

* Fix copy with extra seasonalities / regressors R

* Fix weekly_start and yearly_start in R plot_components

* Fix plotting in pandas 0.21 by using pydatetime instead of numpy

* Version bump

* Update README for new version

* Fix missing columns in SHF with extra regressor
Ben Letham 7 年之前
父节点
当前提交
014b3b5919

+ 2 - 2
R/DESCRIPTION

@@ -1,7 +1,7 @@
 Package: prophet
 Title: Automatic Forecasting Procedure
-Version: 0.2.0.9000
-Date: 2017-09-02
+Version: 0.2.1.9000
+Date: 2017-11-08
 Authors@R: c(
   person("Sean", "Taylor", email = "sjt@fb.com", role = c("cre", "aut")),
   person("Ben", "Letham", email = "bletham@fb.com", role = "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 <- '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)

+ 4 - 0
README.md

@@ -62,6 +62,10 @@ Use `conda install gcc` to set up gcc. The easiest way to install Prophet is thr
 
 ## Changelog
 
+### Version 0.2.1 (2017.11.08)
+
+- Bugfixes
+
 ### Version 0.2 (2017.09.02)
 
 - Forecasting with sub-daily data

+ 1 - 1
python/fbprophet/__init__.py

@@ -7,4 +7,4 @@
 
 from fbprophet.forecaster import Prophet
 
-__version__ = '0.2.dev'
+__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)

+ 1 - 1
python/setup.py

@@ -97,7 +97,7 @@ class TestCommand(test_command):
 
 setup(
     name='fbprophet',
-    version='0.2',
+    version='0.2.1',
     description='Automatic Forecasting Procedure',
     url='https://facebook.github.io/prophet/',
     author='Sean J. Taylor <sjt@fb.com>, Ben Letham <bletham@fb.com>',