Skip to content
Time series forecasting for Ruby
Ruby Stan Python Makefile
Branch: master
Clone or download

Latest commit

Latest commit 5f062a3 May 14, 2020

Files

Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
data-raw First commit Apr 9, 2020
examples First commit Apr 9, 2020
ext/prophet First commit Apr 9, 2020
lib Version bump to 0.2.0 [skip ci] May 14, 2020
stan First commit Apr 9, 2020
test Switched from Daru to Rover May 14, 2020
.gitignore First commit Apr 9, 2020
.travis.yml
CHANGELOG.md Version bump to 0.2.0 [skip ci] May 14, 2020
Gemfile New version of Numo is out May 5, 2020
LICENSE.txt First commit Apr 9, 2020
README.md Fixed example [skip ci] May 14, 2020
Rakefile First commit Apr 9, 2020
appveyor.yml Added AppVeyor Apr 10, 2020
prophet-rb.gemspec Switched from Daru to Rover May 14, 2020

README.md

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 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 = Rover.read_csv("example_wp_log_peyton_manning.csv")
df.head
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
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
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 = Rover.read_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 = Rover::DataFrame.new(
  "holiday" => "playoff",
  "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,
  "upper_window" => 1
)
superbowls = Rover::DataFrame.new(
  "holiday" => "superbowl",
  "ds" => ["2010-02-07", "2014-02-02", "2016-02-07"],
  "lower_window" => 0,
  "upper_window" => 1
)
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 = Rover.read_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 = Rover.read_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

Upgrading

0.2.0

Prophet now uses Rover instead of Daru. Two changes you may need to make are:

  • Rover.read_csv instead of Daru::DataFrame.from_csv
  • df[["ds", "yhat"]] instead of df["ds", "yhat"]

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
You can’t perform that action at this time.