Need help with prophet?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

ankane
173 Stars 2 Forks MIT License 89 Commits 1 Opened issues

Description

Time series forecasting for Ruby

Services available

!
?

Need anything else?

Contributors list

# 3,320
Ruby
Rails
elastic...
chartjs
86 commits
# 86,317
CSS
Shell
pelican
Rust
2 commits

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'

Simple API

Get future predictions for a time series

series = {
  Date.parse("2020-01-01") => 100,
  Date.parse("2020-01-02") => 150,
  Date.parse("2020-01-03") => 136,
  # ...
}

Prophet.forecast(series)

Specify the number of predictions to return

Prophet.forecast(series, count: 3)

Works great with Groupdate

series = User.group_by_day(:created_at).count
Prophet.forecast(series)

Advanced API

Check out the Prophet documentation for a great explanation of all of the features. The advanced API follows the Python API and supports the same features. It uses Rover for data frames.

Advanced 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 | yhatlower | yhatupper --- | --- | --- | --- 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

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.