Prophet.rb

Time series forecasting for Ruby, ported from Prophet

Supports:

  • Multiple seasonalities
  • Linear and non-linear growth
  • Holidays and special events

And gracefully handles missing data

Build Status

Installation

Add this line to your application’s Gemfile:

gem 'prophet-rb'

Documentation

Check out the Prophet documentation for a great explanation of all of the features. The Ruby API follows the Python API and supports the same features.

Quick Start

Explanation

Create a data frame with ds and y columns - here’s an example you can use

df = Daru::DataFrame.from_csv("example_wp_log_peyton_manning.csv")
df.head(5)
ds y
2007-12-10 9.59076113
2007-12-11 8.51959031
2007-12-12 8.18367658
2007-12-13 8.07246736
2007-12-14 7.89357207

Fit a model

m = Prophet.new
m.fit(df)

Make a data frame with a ds column for future predictions

future = m.make_future_dataframe(periods: 365)
future.tail(5)
ds
2017-01-15
2017-01-16
2017-01-17
2017-01-18
2017-01-19

Make predictions

forecast = m.predict(future)
forecast["ds", "yhat", "yhat_lower", "yhat_upper"].tail(5)
ds yhat yhat_lower yhat_upper
2017-01-15 8.21192840 7.52526442 8.92389960
2017-01-16 8.53696359 7.79124970 9.22620028
2017-01-17 8.32439891 7.62482699 9.04719328
2017-01-18 8.15702395 7.40079968 8.91301650
2017-01-19 8.16900433 7.45673678 8.83486188

Plots

For plots, install the matplotlib gem.

Plot the forecast

m.plot(forecast).savefig("forecast.png")

Forecast

Plot components

m.plot_components(forecast).savefig("components.png")

Components

Saturating Forecasts

Explanation

Forecast logistic growth instead of linear

df = Daru::DataFrame.from_csv("example_wp_log_R.csv")
df["cap"] = 8.5
m = Prophet.new(growth: "logistic")
m.fit(df)
future = m.make_future_dataframe(periods: 365)
future["cap"] = 8.5
forecast = m.predict(future)

Trend Changepoints

Explanation

Plot changepoints

fig = m.plot(forecast)
m.add_changepoints_to_plot(fig.gca, forecast)

Adjust trend flexibility

m = Prophet.new(changepoint_prior_scale: 0.5)

Specify the location of changepoints

m = Prophet.new(changepoints: ["2014-01-01"])

Holidays and Special Events

Explanation

Create a data frame with holiday and ds columns. Include all occurrences in your past data and future occurrences you’d like to forecast.

playoffs = Daru::DataFrame.new(
  "holiday" => ["playoff"] * 14,
  "ds" => ["2008-01-13", "2009-01-03", "2010-01-16",
           "2010-01-24", "2010-02-07", "2011-01-08",
           "2013-01-12", "2014-01-12", "2014-01-19",
           "2014-02-02", "2015-01-11", "2016-01-17",
           "2016-01-24", "2016-02-07"],
  "lower_window" => [0] * 14,
  "upper_window" => [1] * 14
)
superbowls = Daru::DataFrame.new(
  "holiday" => ["superbowl"] * 3,
  "ds" => ["2010-02-07", "2014-02-02", "2016-02-07"],
  "lower_window" => [0] * 3,
  "upper_window" => [1] * 3
)
holidays = playoffs.concat(superbowls)

m = Prophet.new(holidays: holidays)
m.fit(df)

Add country-specific holidays

m = Prophet.new
m.add_country_holidays(country_name: "US")
m.fit(df)

Specify custom seasonalities

m = Prophet.new(weekly_seasonality: false)
m.add_seasonality(name: "monthly", period: 30.5, fourier_order: 5)
forecast = m.fit(df).predict(future)

Specify additional regressors

nfl_sunday = lambda do |ds|
  date = ds.respond_to?(:to_date) ? ds.to_date : Date.parse(ds)
  date.wday == 0 && (date.month > 8 || date.month < 2) ? 1 : 0
end

df["nfl_sunday"] = df["ds"].map(&nfl_sunday)

m = Prophet.new
m.add_regressor("nfl_sunday")
m.fit(df)

future["nfl_sunday"] = future["ds"].map(&nfl_sunday)

forecast = m.predict(future)

Multiplicative Seasonality

Explanation

df = Daru::DataFrame.from_csv("example_air_passengers.csv")
m = Prophet.new(seasonality_mode: "multiplicative")
m.fit(df)
future = m.make_future_dataframe(periods: 50, freq: "MS")
forecast = m.predict(future)

Uncertainty Intervals

Specify the width of uncertainty intervals (80% by default)

Prophet.new(interval_width: 0.95)

Get uncertainty in seasonality

Prophet.new(mcmc_samples: 300)

Non-Daily Data

Explanation

Sub-daily data

df = Daru::DataFrame.from_csv("example_yosemite_temps.csv")
m = Prophet.new(changepoint_prior_scale: 0.01).fit(df)
future = m.make_future_dataframe(periods: 300, freq: "H")
forecast = m.predict(future)

Resources

Credits

This library was ported from the Prophet Python library and is available under the same license.

History

View the changelog

Contributing

Everyone is encouraged to help improve this project. Here are a few ways you can help:

To get started with development:

git clone https://github.com/ankane/prophet.git
cd prophet
bundle install
bundle exec ruby ext/prophet/extconf.rb
bundle exec rake test