Move copy test to test_diagnostics

This commit is contained in:
Ben Letham 2018-05-04 16:15:43 -07:00
parent 55d7d1e62d
commit 8e8e04858a
5 changed files with 142 additions and 199 deletions

View file

@ -4,8 +4,9 @@ context("Prophet diagnostics tests")
## Makes R CMD CHECK happy due to dplyr syntax below
globalVariables(c("y", "yhat"))
DATA <- head(read.csv('data.csv'), 100)
DATA$ds <- as.Date(DATA$ds)
DATA_all <- read.csv('data.csv')
DATA_all$ds <- as.Date(DATA_all$ds)
DATA <- head(DATA_all, 100)
test_that("simulated_historical_forecasts", {
skip_if_not(Sys.getenv('R_ARCH') != '/i386')
@ -132,3 +133,72 @@ test_that("performance_metrics", {
sort(colnames(df_horizon)) == sort(c('coverage', 'mse', 'horizon'))
))
})
test_that("copy", {
skip_if_not(Sys.getenv('R_ARCH') != '/i386')
df <- DATA_all
df$cap <- 200.
df$binary_feature <- c(rep(0, 255), rep(1, 255))
inputs <- list(
growth = c('linear', 'logistic'),
yearly.seasonality = c(TRUE, FALSE),
weekly.seasonality = c(TRUE, FALSE),
daily.seasonality = c(TRUE, FALSE),
holidays = c('null', 'insert_dataframe')
)
products <- expand.grid(inputs)
for (i in 1:length(products)) {
if (products$holidays[i] == 'insert_dataframe') {
holidays <- data.frame(ds=c('2016-12-25'), holiday=c('x'))
} else {
holidays <- NULL
}
m1 <- prophet(
growth = as.character(products$growth[i]),
changepoints = NULL,
n.changepoints = 3,
yearly.seasonality = products$yearly.seasonality[i],
weekly.seasonality = products$weekly.seasonality[i],
daily.seasonality = products$daily.seasonality[i],
holidays = holidays,
seasonality.prior.scale = 1.1,
holidays.prior.scale = 1.1,
changepoints.prior.scale = 0.1,
mcmc.samples = 100,
interval.width = 0.9,
uncertainty.samples = 200,
fit = FALSE
)
out <- prophet:::setup_dataframe(m1, df, initialize_scales = TRUE)
m1 <- out$m
m1$history <- out$df
m1 <- prophet:::set_auto_seasonalities(m1)
m2 <- prophet:::prophet_copy(m1)
# Values should be copied correctly
args <- c('growth', 'changepoints', 'n.changepoints', 'holidays',
'seasonality.prior.scale', 'holidays.prior.scale',
'changepoints.prior.scale', 'mcmc.samples', 'interval.width',
'uncertainty.samples')
for (arg in args) {
expect_equal(m1[[arg]], m2[[arg]])
}
expect_equal(FALSE, m2$yearly.seasonality)
expect_equal(FALSE, m2$weekly.seasonality)
expect_equal(FALSE, m2$daily.seasonality)
expect_equal(m1$yearly.seasonality, 'yearly' %in% names(m2$seasonalities))
expect_equal(m1$weekly.seasonality, 'weekly' %in% names(m2$seasonalities))
expect_equal(m1$daily.seasonality, 'daily' %in% names(m2$seasonalities))
}
# Check for cutoff and custom seasonality and extra regressors
changepoints <- seq.Date(as.Date('2012-06-15'), as.Date('2012-09-15'), by='d')
cutoff <- as.Date('2012-07-25')
m1 <- prophet(changepoints = changepoints)
m1 <- add_seasonality(m1, 'custom', 10, 5)
m1 <- add_regressor(m1, 'binary_feature')
m1 <- fit.prophet(m1, df)
m2 <- prophet:::prophet_copy(m1, cutoff)
changepoints <- changepoints[changepoints <= cutoff]
expect_equal(prophet:::set_date(changepoints), m2$changepoints)
expect_true('custom' %in% names(m2$seasonalities))
expect_true('binary_feature' %in% names(m2$extra_regressors))
})

View file

@ -1,60 +0,0 @@
library(prophet)
context("Prophet metrics tests")
## Makes R CMD CHECK happy due to dplyr syntax below
globalVariables(c("y", "yhat"))
DATA <- head(read.csv('data.csv'), 100)
DATA$ds <- as.Date(DATA$ds)
test_that("metrics_tests_using_model", {
# Create dummy model
m <- prophet(DATA)
# Create metric data
forecast <- predict(m, NULL)
df <- na.omit(dplyr::inner_join(m$history, forecast, by="ds"))
# Check all metrics wether it is equal to its definition
y <- df$y
yhat <- df$yhat
expect_equal(me(m), mean(y-yhat))
expect_equal(mse(m), mean((y-yhat)^2))
expect_equal(rmse(m), sqrt(mean((y-yhat)^2)))
expect_equal(mae(m), mean(abs(y-yhat)))
expect_equal(mpe(m), 100*mean((y-yhat)/y))
expect_equal(mape(m), 100*mean(abs((y-yhat)/y)))
answer <- data.frame(
me=me(m),
mse=mse(m),
rmse=rmse(m),
mae=mae(m),
mpe=mpe(m),
mape=mape(m)
)
expect_equal(all_metrics(m), answer)
})
test_that("metrics_tests_using_simulated_historical_forecast", {
#skip_if_not(Sys.getenv('R_ARCH') != '/i386')
# Create dummy model
m <- prophet(DATA)
# Run simulated historical forecast
df <- simulated_historical_forecasts(m, horizon = 3, units = 'days', k = 2, period = 3)
# Check all metrics wether it is equal to its definition
y <- df$y
yhat <- df$yhat
expect_equal(me(df=df), mean(y-yhat))
expect_equal(mse(df=df), mean((y-yhat)^2))
expect_equal(rmse(df=df), sqrt(mean((y-yhat)^2)))
expect_equal(mae(df=df), mean(abs(y-yhat)))
expect_equal(mpe(df=df), 100*mean((y-yhat)/y))
expect_equal(mape(df=df), 100*mean(abs((y-yhat)/y)))
answer <- data.frame(
me=me(df=df),
mse=mse(df=df),
rmse=rmse(df=df),
mae=mae(df=df),
mpe=mpe(df=df),
mape=mape(df=df)
)
expect_equal(all_metrics(df=df), answer)
})

View file

@ -509,72 +509,3 @@ test_that("added_regressors", {
m <- add_regressor(m, 'constant_feature')
expect_error(fit.prophet(m, df))
})
test_that("copy", {
skip_if_not(Sys.getenv('R_ARCH') != '/i386')
df <- DATA
df$cap <- 200.
df$binary_feature <- c(rep(0, 255), rep(1, 255))
inputs <- list(
growth = c('linear', 'logistic'),
yearly.seasonality = c(TRUE, FALSE),
weekly.seasonality = c(TRUE, FALSE),
daily.seasonality = c(TRUE, FALSE),
holidays = c('null', 'insert_dataframe')
)
products <- expand.grid(inputs)
for (i in 1:length(products)) {
if (products$holidays[i] == 'insert_dataframe') {
holidays <- data.frame(ds=c('2016-12-25'), holiday=c('x'))
} else {
holidays <- NULL
}
m1 <- prophet(
growth = as.character(products$growth[i]),
changepoints = NULL,
n.changepoints = 3,
yearly.seasonality = products$yearly.seasonality[i],
weekly.seasonality = products$weekly.seasonality[i],
daily.seasonality = products$daily.seasonality[i],
holidays = holidays,
seasonality.prior.scale = 1.1,
holidays.prior.scale = 1.1,
changepoints.prior.scale = 0.1,
mcmc.samples = 100,
interval.width = 0.9,
uncertainty.samples = 200,
fit = FALSE
)
out <- prophet:::setup_dataframe(m1, df, initialize_scales = TRUE)
m1 <- out$m
m1$history <- out$df
m1 <- prophet:::set_auto_seasonalities(m1)
m2 <- prophet:::prophet_copy(m1)
# Values should be copied correctly
args <- c('growth', 'changepoints', 'n.changepoints', 'holidays',
'seasonality.prior.scale', 'holidays.prior.scale',
'changepoints.prior.scale', 'mcmc.samples', 'interval.width',
'uncertainty.samples')
for (arg in args) {
expect_equal(m1[[arg]], m2[[arg]])
}
expect_equal(FALSE, m2$yearly.seasonality)
expect_equal(FALSE, m2$weekly.seasonality)
expect_equal(FALSE, m2$daily.seasonality)
expect_equal(m1$yearly.seasonality, 'yearly' %in% names(m2$seasonalities))
expect_equal(m1$weekly.seasonality, 'weekly' %in% names(m2$seasonalities))
expect_equal(m1$daily.seasonality, 'daily' %in% names(m2$seasonalities))
}
# Check for cutoff and custom seasonality and extra regressors
changepoints <- seq.Date(as.Date('2012-06-15'), as.Date('2012-09-15'), by='d')
cutoff <- as.Date('2012-07-25')
m1 <- prophet(changepoints = changepoints)
m1 <- add_seasonality(m1, 'custom', 10, 5)
m1 <- add_regressor(m1, 'binary_feature')
m1 <- fit.prophet(m1, df)
m2 <- prophet:::prophet_copy(m1, cutoff)
changepoints <- changepoints[changepoints <= cutoff]
expect_equal(prophet:::set_date(changepoints), m2$changepoints)
expect_true('custom' %in% names(m2$seasonalities))
expect_true('binary_feature' %in% names(m2$extra_regressors))
})

View file

@ -10,6 +10,8 @@ from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import itertools
import numpy as np
import pandas as pd
@ -19,9 +21,10 @@ from unittest import TestCase
from fbprophet import Prophet
from fbprophet import diagnostics
DATA = pd.read_csv(
DATA_all = pd.read_csv(
os.path.join(os.path.dirname(__file__), 'data.csv'), parse_dates=['ds']
).head(100)
)
DATA = DATA_all.head(100)
# fb-block 1 end
# fb-block 2
@ -165,3 +168,68 @@ class TestDiagnostics(TestCase):
set(df_horizon.columns),
{'coverage', 'mse', 'horizon'},
)
def test_copy(self):
df = DATA_all.copy()
df['cap'] = 200.
df['binary_feature'] = [0] * 255 + [1] * 255
# These values are created except for its default values
holiday = pd.DataFrame(
{'ds': pd.to_datetime(['2016-12-25']), 'holiday': ['x']})
products = itertools.product(
['linear', 'logistic'], # growth
[None, pd.to_datetime(['2016-12-25'])], # changepoints
[3], # n_changepoints
[True, False], # yearly_seasonality
[True, False], # weekly_seasonality
[True, False], # daily_seasonality
[None, holiday], # holidays
[1.1], # seasonality_prior_scale
[1.1], # holidays_prior_scale
[0.1], # changepoint_prior_scale
[100], # mcmc_samples
[0.9], # interval_width
[200] # uncertainty_samples
)
# Values should be copied correctly
for product in products:
m1 = Prophet(*product)
m1.history = m1.setup_dataframe(
df.copy(), initialize_scales=True)
m1.set_auto_seasonalities()
m2 = diagnostics.prophet_copy(m1)
self.assertEqual(m1.growth, m2.growth)
self.assertEqual(m1.n_changepoints, m2.n_changepoints)
self.assertEqual(m1.changepoints, m2.changepoints)
self.assertEqual(False, m2.yearly_seasonality)
self.assertEqual(False, m2.weekly_seasonality)
self.assertEqual(False, m2.daily_seasonality)
self.assertEqual(
m1.yearly_seasonality, 'yearly' in m2.seasonalities)
self.assertEqual(
m1.weekly_seasonality, 'weekly' in m2.seasonalities)
self.assertEqual(
m1.daily_seasonality, 'daily' in m2.seasonalities)
if m1.holidays is None:
self.assertEqual(m1.holidays, m2.holidays)
else:
self.assertTrue((m1.holidays == m2.holidays).values.all())
self.assertEqual(m1.seasonality_prior_scale, m2.seasonality_prior_scale)
self.assertEqual(m1.changepoint_prior_scale, m2.changepoint_prior_scale)
self.assertEqual(m1.holidays_prior_scale, m2.holidays_prior_scale)
self.assertEqual(m1.mcmc_samples, m2.mcmc_samples)
self.assertEqual(m1.interval_width, m2.interval_width)
self.assertEqual(m1.uncertainty_samples, m2.uncertainty_samples)
# Check for cutoff and custom seasonality and extra regressors
changepoints = pd.date_range('2012-06-15', '2012-09-15')
cutoff = pd.Timestamp('2012-07-25')
m1 = Prophet(changepoints=changepoints)
m1.add_seasonality('custom', 10, 5)
m1.add_regressor('binary_feature')
m1.fit(df)
m2 = diagnostics.prophet_copy(m1, cutoff=cutoff)
changepoints = changepoints[changepoints <= cutoff]
self.assertTrue((changepoints == m2.changepoints).all())
self.assertTrue('custom' in m2.seasonalities)
self.assertTrue('binary_feature' in m2.extra_regressors)

View file

@ -10,7 +10,6 @@ from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import itertools
import numpy as np
import pandas as pd
@ -545,68 +544,3 @@ class TestProphet(TestCase):
m.add_regressor('constant_feature')
with self.assertRaises(ValueError):
m.fit(df.copy())
def test_copy(self):
df = DATA.copy()
df['cap'] = 200.
df['binary_feature'] = [0] * 255 + [1] * 255
# These values are created except for its default values
holiday = pd.DataFrame(
{'ds': pd.to_datetime(['2016-12-25']), 'holiday': ['x']})
products = itertools.product(
['linear', 'logistic'], # growth
[None, pd.to_datetime(['2016-12-25'])], # changepoints
[3], # n_changepoints
[True, False], # yearly_seasonality
[True, False], # weekly_seasonality
[True, False], # daily_seasonality
[None, holiday], # holidays
[1.1], # seasonality_prior_scale
[1.1], # holidays_prior_scale
[0.1], # changepoint_prior_scale
[100], # mcmc_samples
[0.9], # interval_width
[200] # uncertainty_samples
)
# Values should be copied correctly
for product in products:
m1 = Prophet(*product)
m1.history = m1.setup_dataframe(
df.copy(), initialize_scales=True)
m1.set_auto_seasonalities()
m2 = m1.copy()
self.assertEqual(m1.growth, m2.growth)
self.assertEqual(m1.n_changepoints, m2.n_changepoints)
self.assertEqual(m1.changepoints, m2.changepoints)
self.assertEqual(False, m2.yearly_seasonality)
self.assertEqual(False, m2.weekly_seasonality)
self.assertEqual(False, m2.daily_seasonality)
self.assertEqual(
m1.yearly_seasonality, 'yearly' in m2.seasonalities)
self.assertEqual(
m1.weekly_seasonality, 'weekly' in m2.seasonalities)
self.assertEqual(
m1.daily_seasonality, 'daily' in m2.seasonalities)
if m1.holidays is None:
self.assertEqual(m1.holidays, m2.holidays)
else:
self.assertTrue((m1.holidays == m2.holidays).values.all())
self.assertEqual(m1.seasonality_prior_scale, m2.seasonality_prior_scale)
self.assertEqual(m1.changepoint_prior_scale, m2.changepoint_prior_scale)
self.assertEqual(m1.holidays_prior_scale, m2.holidays_prior_scale)
self.assertEqual(m1.mcmc_samples, m2.mcmc_samples)
self.assertEqual(m1.interval_width, m2.interval_width)
self.assertEqual(m1.uncertainty_samples, m2.uncertainty_samples)
# Check for cutoff and custom seasonality and extra regressors
changepoints = pd.date_range('2012-06-15', '2012-09-15')
cutoff = pd.Timestamp('2012-07-25')
m1 = Prophet(changepoints=changepoints)
m1.add_seasonality('custom', 10, 5)
m1.add_regressor('binary_feature')
m1.fit(df)
m2 = m1.copy(cutoff=cutoff)
changepoints = changepoints[changepoints <= cutoff]
self.assertTrue((changepoints == m2.changepoints).all())
self.assertTrue('custom' in m2.seasonalities)
self.assertTrue('binary_feature' in m2.extra_regressors)