prophet-rb 0.3.2 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +158 -6
  5. data/data-raw/LICENSE-holidays.txt +20 -0
  6. data/data-raw/README.md +3 -0
  7. data/data-raw/generated_holidays.csv +29302 -61443
  8. data/lib/prophet/diagnostics.rb +349 -0
  9. data/lib/prophet/forecaster.rb +219 -15
  10. data/lib/prophet/holidays.rb +5 -2
  11. data/lib/prophet/plot.rb +60 -10
  12. data/lib/prophet/stan_backend.rb +10 -1
  13. data/lib/prophet/version.rb +1 -1
  14. data/lib/prophet.rb +5 -0
  15. data/stan/{unix/prophet.stan → prophet.stan} +8 -7
  16. data/vendor/aarch64-linux/bin/prophet +0 -0
  17. data/vendor/aarch64-linux/lib/libtbb.so.2 +0 -0
  18. data/vendor/aarch64-linux/lib/libtbbmalloc.so.2 +0 -0
  19. data/vendor/aarch64-linux/lib/libtbbmalloc_proxy.so.2 +0 -0
  20. data/vendor/aarch64-linux/licenses/sundials-license.txt +25 -63
  21. data/vendor/aarch64-linux/licenses/sundials-notice.txt +21 -0
  22. data/vendor/arm64-darwin/bin/prophet +0 -0
  23. data/vendor/arm64-darwin/lib/libtbb.dylib +0 -0
  24. data/vendor/arm64-darwin/lib/libtbbmalloc.dylib +0 -0
  25. data/vendor/arm64-darwin/licenses/sundials-license.txt +25 -63
  26. data/vendor/arm64-darwin/licenses/sundials-notice.txt +21 -0
  27. data/vendor/x86_64-darwin/bin/prophet +0 -0
  28. data/vendor/x86_64-darwin/lib/libtbb.dylib +0 -0
  29. data/vendor/x86_64-darwin/lib/libtbbmalloc.dylib +0 -0
  30. data/vendor/x86_64-darwin/licenses/sundials-license.txt +25 -63
  31. data/vendor/x86_64-darwin/licenses/sundials-notice.txt +21 -0
  32. data/vendor/x86_64-linux/bin/prophet +0 -0
  33. data/vendor/x86_64-linux/lib/libtbb.so.2 +0 -0
  34. data/vendor/x86_64-linux/lib/libtbbmalloc.so.2 +0 -0
  35. data/vendor/x86_64-linux/lib/libtbbmalloc_proxy.so.2 +0 -0
  36. data/vendor/x86_64-linux/licenses/sundials-license.txt +25 -63
  37. data/vendor/x86_64-linux/licenses/sundials-notice.txt +21 -0
  38. metadata +10 -4
  39. data/stan/win/prophet.stan +0 -175
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e24dad0631694318db703e420f657e964911071b73e03cd73a6fc4c2d6e16fc
4
- data.tar.gz: bcf2a53b3bcacf5461cd0b881bba0d026c7adee88200646f915074c9946711d3
3
+ metadata.gz: b7d18b97220bb11a0d836b1d272728ed9211aa85fb687032c6451d26b70c6755
4
+ data.tar.gz: c0de54e1a1f66785fe7a61f22c187376c43f9746f9cefa9f6d46834c742f15fb
5
5
  SHA512:
6
- metadata.gz: bdad3069aeaadaa9ac8d339fb6e877942470fd5c8e11652bce50029b0a6de13d0fe383f6a97a343e29138396dec4b1c159e5ee87d229073d2f3eb5c084aa5af2
7
- data.tar.gz: 1d54e502621ed4d34c818fe2e0e064578eae948957305300222892f4ee4750418e2471261596568d05795aea31bb4fe4639925da20a1f5db5bd20a0f0b35a66f
6
+ metadata.gz: 3b7d79d1b6c2fd8335ce417c653ecca5b7e15b9092dcba76f0062e38a775a0af6f88bb92334b2a24871745b2d64fb8822c3898617d9c391268cc7c7299e99e31
7
+ data.tar.gz: 0c094fe16a216ed0f19e566c5c5af896a878b3086f4ac0e550e58e9945c213aae9d12259a08c628b0f02662f7e7c25dcf10313ac65b311f9024a8b60f2b84331
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## 0.4.2 (2022-07-12)
2
+
3
+ - Fixed warning with `add_country_holidays` method
4
+
5
+ ## 0.4.1 (2022-07-10)
6
+
7
+ - Added support for cross validation and performance metrics
8
+ - Added support for updating fitted models
9
+ - Added support for saturating minimum forecasts
10
+
11
+ ## 0.4.0 (2022-07-07)
12
+
13
+ - Added support for saving and loading models
14
+ - Updated holidays
15
+
1
16
  ## 0.3.2 (2022-05-15)
2
17
 
3
18
  - Added advanced API options to `forecast` and `anomalies` methods
data/LICENSE.txt CHANGED
@@ -1,7 +1,7 @@
1
1
  MIT License
2
2
 
3
3
  Copyright (c) Facebook, Inc. and its affiliates.
4
- Copyright (c) 2020 Andrew Kane
4
+ Copyright (c) 2020-2022 Andrew Kane
5
5
 
6
6
  Permission is hereby granted, free of charge, to any person obtaining
7
7
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -80,6 +80,18 @@ Prophet.anomalies(series, growth: "logistic", weekly_seasonality: false)
80
80
 
81
81
  Check out the [Prophet documentation](https://facebook.github.io/prophet/docs/quick_start.html) for a great explanation of all of the features. The advanced API follows the Python API and supports the same features. It uses [Rover](https://github.com/ankane/rover) for data frames.
82
82
 
83
+ - [Quick Start](#advanced-quick-start)
84
+ - [Plots](#plots)
85
+ - [Saturating Forecasts](#saturating-forecasts)
86
+ - [Trend Changepoints](#trend-changepoints)
87
+ - [Holidays and Special Events](#holidays-and-special-events)
88
+ - [Multiplicative Seasonality](#multiplicative-seasonality)
89
+ - [Uncertainty Intervals](#uncertainty-intervals)
90
+ - [Outliers](#outliers)
91
+ - [Non-Daily Data](#non-daily-data)
92
+ - [Diagnostics](#diagnostics)
93
+ - [Additional Topics](#additional-topics)
94
+
83
95
  ## Advanced Quick Start
84
96
 
85
97
  [Explanation](https://facebook.github.io/prophet/docs/quick_start.html)
@@ -167,11 +179,24 @@ df = Rover.read_csv("example_wp_log_R.csv")
167
179
  df["cap"] = 8.5
168
180
  m = Prophet.new(growth: "logistic")
169
181
  m.fit(df)
170
- future = m.make_future_dataframe(periods: 365)
182
+ future = m.make_future_dataframe(periods: 1826)
171
183
  future["cap"] = 8.5
172
184
  forecast = m.predict(future)
173
185
  ```
174
186
 
187
+ Saturating minimum
188
+
189
+ ```ruby
190
+ df["y"] = 10 - df["y"]
191
+ df["cap"] = 6
192
+ df["floor"] = 1.5
193
+ future["cap"] = 6
194
+ future["floor"] = 1.5
195
+ m = Prophet.new(growth: "logistic")
196
+ m.fit(df)
197
+ forecast = m.predict(future)
198
+ ```
199
+
175
200
  ## Trend Changepoints
176
201
 
177
202
  [Explanation](https://facebook.github.io/prophet/docs/trend_changepoints.html)
@@ -204,11 +229,13 @@ Create a data frame with `holiday` and `ds` columns. Include all occurrences in
204
229
  ```ruby
205
230
  playoffs = Rover::DataFrame.new(
206
231
  "holiday" => "playoff",
207
- "ds" => ["2008-01-13", "2009-01-03", "2010-01-16",
208
- "2010-01-24", "2010-02-07", "2011-01-08",
209
- "2013-01-12", "2014-01-12", "2014-01-19",
210
- "2014-02-02", "2015-01-11", "2016-01-17",
211
- "2016-01-24", "2016-02-07"],
232
+ "ds" => [
233
+ "2008-01-13", "2009-01-03", "2010-01-16",
234
+ "2010-01-24", "2010-02-07", "2011-01-08",
235
+ "2013-01-12", "2014-01-12", "2014-01-19",
236
+ "2014-02-02", "2015-01-11", "2016-01-17",
237
+ "2016-01-24", "2016-02-07"
238
+ ],
212
239
  "lower_window" => 0,
213
240
  "upper_window" => 1
214
241
  )
@@ -263,6 +290,8 @@ forecast = m.predict(future)
263
290
 
264
291
  [Explanation](https://facebook.github.io/prophet/docs/multiplicative_seasonality.html)
265
292
 
293
+ Specify multiplicative seasonality
294
+
266
295
  ```ruby
267
296
  df = Rover.read_csv("example_air_passengers.csv")
268
297
  m = Prophet.new(seasonality_mode: "multiplicative")
@@ -271,8 +300,18 @@ future = m.make_future_dataframe(periods: 50, freq: "MS")
271
300
  forecast = m.predict(future)
272
301
  ```
273
302
 
303
+ Specify mode when adding seasonality and regressors
304
+
305
+ ```ruby
306
+ m = Prophet.new(seasonality_mode: "multiplicative")
307
+ m.add_seasonality(name: "quarterly", period: 91.25, fourier_order: 8, mode: "additive")
308
+ m.add_regressor("regressor", mode: "additive")
309
+ ```
310
+
274
311
  ## Uncertainty Intervals
275
312
 
313
+ [Explanation](https://facebook.github.io/prophet/docs/uncertainty_intervals.html)
314
+
276
315
  Specify the width of uncertainty intervals (80% by default)
277
316
 
278
317
  ```ruby
@@ -285,6 +324,18 @@ Get uncertainty in seasonality
285
324
  Prophet.new(mcmc_samples: 300)
286
325
  ```
287
326
 
327
+ ## Outliers
328
+
329
+ [Explanation](https://facebook.github.io/prophet/docs/outliers.html)
330
+
331
+ Remove outliers
332
+
333
+ ```ruby
334
+ df = Rover.read_csv("example_wp_log_R_outliers1.csv")
335
+ df["y"][(df["ds"] > "2010-01-01") & (df["ds"] < "2011-01-01")] = Float::NAN
336
+ m = Prophet.new.fit(df)
337
+ ```
338
+
288
339
  ## Non-Daily Data
289
340
 
290
341
  [Explanation](https://facebook.github.io/prophet/docs/non-daily_data.html)
@@ -298,6 +349,107 @@ future = m.make_future_dataframe(periods: 300, freq: "H")
298
349
  forecast = m.predict(future)
299
350
  ```
300
351
 
352
+ ## Diagnostics
353
+
354
+ [Explanation](http://facebook.github.io/prophet/docs/diagnostics.html)
355
+
356
+ Cross validation
357
+
358
+ ```ruby
359
+ df_cv = Prophet::Diagnostics.cross_validation(m, initial: "730 days", period: "180 days", horizon: "365 days")
360
+ ```
361
+
362
+ Custom cutoffs
363
+
364
+ ```ruby
365
+ cutoffs = ["2013-02-15", "2013-08-15", "2014-02-15"].map { |v| Time.parse("#{v} 00:00:00 UTC") }
366
+ df_cv2 = Prophet::Diagnostics.cross_validation(m, cutoffs: cutoffs, horizon: "365 days")
367
+ ```
368
+
369
+ Get performance metrics
370
+
371
+ ```ruby
372
+ df_p = Prophet::Diagnostics.performance_metrics(df_cv)
373
+ ```
374
+
375
+ Plot cross validation metrics
376
+
377
+ ```ruby
378
+ Prophet::Plot.plot_cross_validation_metric(df_cv, metric: "mape")
379
+ ```
380
+
381
+ Hyperparameter tuning
382
+
383
+ ```ruby
384
+ param_grid = {
385
+ changepoint_prior_scale: [0.001, 0.01, 0.1, 0.5],
386
+ seasonality_prior_scale: [0.01, 0.1, 1.0, 10.0]
387
+ }
388
+
389
+ # Generate all combinations of parameters
390
+ all_params = param_grid.values[0].product(*param_grid.values[1..-1]).map { |v| param_grid.keys.zip(v).to_h }
391
+ rmses = [] # Store the RMSEs for each params here
392
+
393
+ # Use cross validation to evaluate all parameters
394
+ all_params.each do |params|
395
+ m = Prophet.new(**params).fit(df) # Fit model with given params
396
+ df_cv = Prophet::Diagnostics.cross_validation(m, cutoffs: cutoffs, horizon: "30 days")
397
+ df_p = Prophet::Diagnostics.performance_metrics(df_cv, rolling_window: 1)
398
+ rmses << df_p["rmse"][0]
399
+ end
400
+
401
+ # Find the best parameters
402
+ tuning_results = Rover::DataFrame.new(all_params)
403
+ tuning_results["rmse"] = rmses
404
+ p tuning_results
405
+ ```
406
+
407
+ ## Additional Topics
408
+
409
+ [Explanation](https://facebook.github.io/prophet/docs/additional_topics.html)
410
+
411
+ Save a model
412
+
413
+ ```ruby
414
+ File.write("model.json", m.to_json)
415
+ ```
416
+
417
+ Load a model
418
+
419
+ ```ruby
420
+ m = Prophet.from_json(File.read("model.json"))
421
+ ```
422
+
423
+ Uses the same format as Python, so models can be saved and loaded in either language
424
+
425
+ Flat trend
426
+
427
+ ```ruby
428
+ m = Prophet.new(growth: "flat")
429
+ ```
430
+
431
+ Updating fitted models
432
+
433
+ ```ruby
434
+ def stan_init(m)
435
+ res = {}
436
+ ["k", "m", "sigma_obs"].each do |pname|
437
+ res[pname] = m.params[pname][0, true][0]
438
+ end
439
+ ["delta", "beta"].each do |pname|
440
+ res[pname] = m.params[pname][0, true]
441
+ end
442
+ res
443
+ end
444
+
445
+ df = Rover.read_csv("example_wp_log_peyton_manning.csv")
446
+ df1 = df[df["ds"] <= "2016-01-19"] # All data except the last day
447
+ m1 = Prophet.new.fit(df1) # A model fit to all data except the last day
448
+
449
+ m2 = Prophet.new.fit(df) # Adding the last day, fitting from scratch
450
+ m2 = Prophet.new.fit(df, init: stan_init(m1)) # Adding the last day, warm-starting from m1
451
+ ```
452
+
301
453
  ## Resources
302
454
 
303
455
  - [Forecasting at Scale](https://peerj.com/preprints/3190.pdf)
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2017-2022 <maurizio.montel@gmail.com>
2
+ Copyright (c) 2014-2017 <ryanssdev@icloud.com>
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
@@ -0,0 +1,3 @@
1
+ Holidays from 1995 through 2044 are generated from [this script](https://github.com/facebook/prophet/blob/main/python/scripts/generate_holidays_file.py).
2
+
3
+ The data is primarily based on the Python [holidays](https://pypi.org/project/holidays/) package.