README.md in prophet-rb-0.4.0 vs README.md in prophet-rb-0.4.1
- old
+ new
@@ -86,11 +86,12 @@
- [Trend Changepoints](#trend-changepoints)
- [Holidays and Special Events](#holidays-and-special-events)
- [Multiplicative Seasonality](#multiplicative-seasonality)
- [Uncertainty Intervals](#uncertainty-intervals)
- [Non-Daily Data](#non-daily-data)
-- [Saving Models](#saving-models)
+- [Diagnostics](#diagnostics)
+- [Additional Topics](#additional-topics)
## Advanced Quick Start
[Explanation](https://facebook.github.io/prophet/docs/quick_start.html)
@@ -175,15 +176,28 @@
```ruby
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 = m.make_future_dataframe(periods: 1826)
future["cap"] = 8.5
forecast = m.predict(future)
```
+Saturating minimum
+
+```ruby
+df["y"] = 10 - df["y"]
+df["cap"] = 6
+df["floor"] = 1.5
+future["cap"] = 6
+future["floor"] = 1.5
+m = Prophet.new(growth: "logistic")
+m.fit(df)
+forecast = m.predict(future)
+```
+
## Trend Changepoints
[Explanation](https://facebook.github.io/prophet/docs/trend_changepoints.html)
Plot changepoints
@@ -306,14 +320,69 @@
m = Prophet.new(changepoint_prior_scale: 0.01).fit(df)
future = m.make_future_dataframe(periods: 300, freq: "H")
forecast = m.predict(future)
```
-## Saving Models
+## Diagnostics
-[Explanation](https://facebook.github.io/prophet/docs/additional_topics.html#saving-models)
+[Explanation](http://facebook.github.io/prophet/docs/diagnostics.html)
+Cross validation
+
+```ruby
+df_cv = Prophet::Diagnostics.cross_validation(m, initial: "730 days", period: "180 days", horizon: "365 days")
+```
+
+Custom cutoffs
+
+```ruby
+cutoffs = ["2013-02-15", "2013-08-15", "2014-02-15"].map { |v| Time.parse("#{v} 00:00:00 UTC") }
+df_cv2 = Prophet::Diagnostics.cross_validation(m, cutoffs: cutoffs, horizon: "365 days")
+```
+
+Get performance metrics
+
+```ruby
+df_p = Prophet::Diagnostics.performance_metrics(df_cv)
+```
+
+Plot cross validation metrics
+
+```ruby
+Prophet::Plot.plot_cross_validation_metric(df_cv, metric: "mape")
+```
+
+Hyperparameter tuning
+
+```ruby
+param_grid = {
+ changepoint_prior_scale: [0.001, 0.01, 0.1, 0.5],
+ seasonality_prior_scale: [0.01, 0.1, 1.0, 10.0]
+}
+
+# Generate all combinations of parameters
+all_params = param_grid.values[0].product(*param_grid.values[1..-1]).map { |v| param_grid.keys.zip(v).to_h }
+rmses = [] # Store the RMSEs for each params here
+
+# Use cross validation to evaluate all parameters
+all_params.each do |params|
+ m = Prophet.new(**params).fit(df) # Fit model with given params
+ df_cv = Prophet::Diagnostics.cross_validation(m, cutoffs: cutoffs, horizon: "30 days")
+ df_p = Prophet::Diagnostics.performance_metrics(df_cv, rolling_window: 1)
+ rmses << df_p["rmse"][0]
+end
+
+# Find the best parameters
+tuning_results = Rover::DataFrame.new(all_params)
+tuning_results["rmse"] = rmses
+p tuning_results
+```
+
+## Additional Topics
+
+[Explanation](https://facebook.github.io/prophet/docs/additional_topics.html)
+
Save a model
```ruby
File.write("model.json", m.to_json)
```
@@ -323,9 +392,37 @@
```ruby
m = Prophet.from_json(File.read("model.json"))
```
Uses the same format as Python, so models can be saved and loaded in either language
+
+Flat trend
+
+```ruby
+m = Prophet.new(growth: "flat")
+```
+
+Updating fitted models
+
+```ruby
+def stan_init(m)
+ res = {}
+ ["k", "m", "sigma_obs"].each do |pname|
+ res[pname] = m.params[pname][0, true][0]
+ end
+ ["delta", "beta"].each do |pname|
+ res[pname] = m.params[pname][0, true]
+ end
+ res
+end
+
+df = Rover.read_csv("example_wp_log_peyton_manning.csv")
+df1 = df[df["ds"] <= "2016-01-19"] # All data except the last day
+m1 = Prophet.new.fit(df1) # A model fit to all data except the last day
+
+m2 = Prophet.new.fit(df) # Adding the last day, fitting from scratch
+m2 = Prophet.new.fit(df, init: stan_init(m1)) # Adding the last day, warm-starting from m1
+```
## Resources
- [Forecasting at Scale](https://peerj.com/preprints/3190.pdf)