prophet-rb 0.3.1 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -2
- data/LICENSE.txt +1 -1
- data/README.md +149 -2
- data/data-raw/LICENSE-holidays.txt +20 -0
- data/data-raw/README.md +3 -0
- data/data-raw/generated_holidays.csv +29302 -61443
- data/lib/prophet/diagnostics.rb +349 -0
- data/lib/prophet/forecaster.rb +214 -4
- data/lib/prophet/holidays.rb +6 -10
- data/lib/prophet/plot.rb +56 -6
- data/lib/prophet/stan_backend.rb +10 -1
- data/lib/prophet/version.rb +1 -1
- data/lib/prophet.rb +23 -7
- data/stan/{unix/prophet.stan → prophet.stan} +8 -7
- data/vendor/aarch64-linux/bin/prophet +0 -0
- data/vendor/aarch64-linux/lib/libtbb.so.2 +0 -0
- data/vendor/aarch64-linux/lib/libtbbmalloc.so.2 +0 -0
- data/vendor/aarch64-linux/lib/libtbbmalloc_proxy.so.2 +0 -0
- data/vendor/aarch64-linux/licenses/sundials-license.txt +25 -63
- data/vendor/aarch64-linux/licenses/sundials-notice.txt +21 -0
- data/vendor/arm64-darwin/bin/prophet +0 -0
- data/vendor/arm64-darwin/lib/libtbb.dylib +0 -0
- data/vendor/arm64-darwin/lib/libtbbmalloc.dylib +0 -0
- data/vendor/arm64-darwin/licenses/sundials-license.txt +25 -63
- data/vendor/arm64-darwin/licenses/sundials-notice.txt +21 -0
- data/vendor/x86_64-darwin/bin/prophet +0 -0
- data/vendor/x86_64-darwin/lib/libtbb.dylib +0 -0
- data/vendor/x86_64-darwin/lib/libtbbmalloc.dylib +0 -0
- data/vendor/x86_64-darwin/licenses/sundials-license.txt +25 -63
- data/vendor/x86_64-darwin/licenses/sundials-notice.txt +21 -0
- data/vendor/x86_64-linux/bin/prophet +0 -0
- data/vendor/x86_64-linux/lib/libtbb.so.2 +0 -0
- data/vendor/x86_64-linux/lib/libtbbmalloc.so.2 +0 -0
- data/vendor/x86_64-linux/lib/libtbbmalloc_proxy.so.2 +0 -0
- data/vendor/x86_64-linux/licenses/sundials-license.txt +25 -63
- data/vendor/x86_64-linux/licenses/sundials-notice.txt +21 -0
- metadata +10 -4
- data/stan/win/prophet.stan +0 -175
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 69d58f060a9bda44b1ab8666ded81b3e61ff1b95b08ae40727fa7a2dfee57ee0
|
4
|
+
data.tar.gz: dc76685a8b45ca7cad79561f986af9c66e5e49bd45dd5e10c72f91088d9b470a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 34d2fd0587110c6de9db334c44a4859a5de92d1cc124efb5f865c845d504816f3d3cd34d63776a709de396af8f9b2cf82a390cfb9f3e49e685ef8be4f469fb3e
|
7
|
+
data.tar.gz: '0587986407bb68a9ca97928ad65bcbb42fe101bd9d2e50a44b2126df38d67c04544932ec39009c6f1d6467736aa0a8404ac4aad04187dcb953285d4d5ee80a77'
|
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,23 @@
|
|
1
|
-
## 0.
|
1
|
+
## 0.4.1 (2022-07-10)
|
2
|
+
|
3
|
+
- Added support for cross validation and performance metrics
|
4
|
+
- Added support for updating fitted models
|
5
|
+
- Added support for saturating minimum forecasts
|
6
|
+
|
7
|
+
## 0.4.0 (2022-07-07)
|
8
|
+
|
9
|
+
- Added support for saving and loading models
|
10
|
+
- Updated holidays
|
11
|
+
|
12
|
+
## 0.3.2 (2022-05-15)
|
13
|
+
|
14
|
+
- Added advanced API options to `forecast` and `anomalies` methods
|
15
|
+
|
16
|
+
## 0.3.1 (2022-04-28)
|
2
17
|
|
3
18
|
- Improved error message for missing columns
|
4
19
|
|
5
|
-
## 0.3.0 (
|
20
|
+
## 0.3.0 (2022-04-24)
|
6
21
|
|
7
22
|
- Switched to precompiled models
|
8
23
|
- Dropped support for Ruby < 2.7
|
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
@@ -22,6 +22,8 @@ gem "prophet-rb"
|
|
22
22
|
|
23
23
|
## Simple API
|
24
24
|
|
25
|
+
### Forecasting
|
26
|
+
|
25
27
|
Get future predictions for a time series
|
26
28
|
|
27
29
|
```ruby
|
@@ -48,16 +50,47 @@ series = User.group_by_day(:created_at).count
|
|
48
50
|
Prophet.forecast(series)
|
49
51
|
```
|
50
52
|
|
53
|
+
And supports [advanced API](#advanced-api) options
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
Prophet.forecast(series, growth: "logistic", weekly_seasonality: false)
|
57
|
+
```
|
58
|
+
|
59
|
+
### Anomaly Detection
|
60
|
+
|
51
61
|
Detect anomalies in a time series
|
52
62
|
|
53
63
|
```ruby
|
54
64
|
Prophet.anomalies(series)
|
55
65
|
```
|
56
66
|
|
67
|
+
Specify the width of uncertainty intervals (decrease for more anomalies)
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
Prophet.anomalies(series, interval_width: 0.99)
|
71
|
+
```
|
72
|
+
|
73
|
+
Also supports [advanced API](#advanced-api) options
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
Prophet.anomalies(series, growth: "logistic", weekly_seasonality: false)
|
77
|
+
```
|
78
|
+
|
57
79
|
## Advanced API
|
58
80
|
|
59
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.
|
60
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
|
+
- [Non-Daily Data](#non-daily-data)
|
91
|
+
- [Diagnostics](#diagnostics)
|
92
|
+
- [Additional Topics](#additional-topics)
|
93
|
+
|
61
94
|
## Advanced Quick Start
|
62
95
|
|
63
96
|
[Explanation](https://facebook.github.io/prophet/docs/quick_start.html)
|
@@ -145,11 +178,24 @@ df = Rover.read_csv("example_wp_log_R.csv")
|
|
145
178
|
df["cap"] = 8.5
|
146
179
|
m = Prophet.new(growth: "logistic")
|
147
180
|
m.fit(df)
|
148
|
-
future = m.make_future_dataframe(periods:
|
181
|
+
future = m.make_future_dataframe(periods: 1826)
|
149
182
|
future["cap"] = 8.5
|
150
183
|
forecast = m.predict(future)
|
151
184
|
```
|
152
185
|
|
186
|
+
Saturating minimum
|
187
|
+
|
188
|
+
```ruby
|
189
|
+
df["y"] = 10 - df["y"]
|
190
|
+
df["cap"] = 6
|
191
|
+
df["floor"] = 1.5
|
192
|
+
future["cap"] = 6
|
193
|
+
future["floor"] = 1.5
|
194
|
+
m = Prophet.new(growth: "logistic")
|
195
|
+
m.fit(df)
|
196
|
+
forecast = m.predict(future)
|
197
|
+
```
|
198
|
+
|
153
199
|
## Trend Changepoints
|
154
200
|
|
155
201
|
[Explanation](https://facebook.github.io/prophet/docs/trend_changepoints.html)
|
@@ -206,7 +252,7 @@ Add country-specific holidays
|
|
206
252
|
|
207
253
|
```ruby
|
208
254
|
m = Prophet.new
|
209
|
-
m.add_country_holidays(
|
255
|
+
m.add_country_holidays("US")
|
210
256
|
m.fit(df)
|
211
257
|
```
|
212
258
|
|
@@ -276,6 +322,107 @@ future = m.make_future_dataframe(periods: 300, freq: "H")
|
|
276
322
|
forecast = m.predict(future)
|
277
323
|
```
|
278
324
|
|
325
|
+
## Diagnostics
|
326
|
+
|
327
|
+
[Explanation](http://facebook.github.io/prophet/docs/diagnostics.html)
|
328
|
+
|
329
|
+
Cross validation
|
330
|
+
|
331
|
+
```ruby
|
332
|
+
df_cv = Prophet::Diagnostics.cross_validation(m, initial: "730 days", period: "180 days", horizon: "365 days")
|
333
|
+
```
|
334
|
+
|
335
|
+
Custom cutoffs
|
336
|
+
|
337
|
+
```ruby
|
338
|
+
cutoffs = ["2013-02-15", "2013-08-15", "2014-02-15"].map { |v| Time.parse("#{v} 00:00:00 UTC") }
|
339
|
+
df_cv2 = Prophet::Diagnostics.cross_validation(m, cutoffs: cutoffs, horizon: "365 days")
|
340
|
+
```
|
341
|
+
|
342
|
+
Get performance metrics
|
343
|
+
|
344
|
+
```ruby
|
345
|
+
df_p = Prophet::Diagnostics.performance_metrics(df_cv)
|
346
|
+
```
|
347
|
+
|
348
|
+
Plot cross validation metrics
|
349
|
+
|
350
|
+
```ruby
|
351
|
+
Prophet::Plot.plot_cross_validation_metric(df_cv, metric: "mape")
|
352
|
+
```
|
353
|
+
|
354
|
+
Hyperparameter tuning
|
355
|
+
|
356
|
+
```ruby
|
357
|
+
param_grid = {
|
358
|
+
changepoint_prior_scale: [0.001, 0.01, 0.1, 0.5],
|
359
|
+
seasonality_prior_scale: [0.01, 0.1, 1.0, 10.0]
|
360
|
+
}
|
361
|
+
|
362
|
+
# Generate all combinations of parameters
|
363
|
+
all_params = param_grid.values[0].product(*param_grid.values[1..-1]).map { |v| param_grid.keys.zip(v).to_h }
|
364
|
+
rmses = [] # Store the RMSEs for each params here
|
365
|
+
|
366
|
+
# Use cross validation to evaluate all parameters
|
367
|
+
all_params.each do |params|
|
368
|
+
m = Prophet.new(**params).fit(df) # Fit model with given params
|
369
|
+
df_cv = Prophet::Diagnostics.cross_validation(m, cutoffs: cutoffs, horizon: "30 days")
|
370
|
+
df_p = Prophet::Diagnostics.performance_metrics(df_cv, rolling_window: 1)
|
371
|
+
rmses << df_p["rmse"][0]
|
372
|
+
end
|
373
|
+
|
374
|
+
# Find the best parameters
|
375
|
+
tuning_results = Rover::DataFrame.new(all_params)
|
376
|
+
tuning_results["rmse"] = rmses
|
377
|
+
p tuning_results
|
378
|
+
```
|
379
|
+
|
380
|
+
## Additional Topics
|
381
|
+
|
382
|
+
[Explanation](https://facebook.github.io/prophet/docs/additional_topics.html)
|
383
|
+
|
384
|
+
Save a model
|
385
|
+
|
386
|
+
```ruby
|
387
|
+
File.write("model.json", m.to_json)
|
388
|
+
```
|
389
|
+
|
390
|
+
Load a model
|
391
|
+
|
392
|
+
```ruby
|
393
|
+
m = Prophet.from_json(File.read("model.json"))
|
394
|
+
```
|
395
|
+
|
396
|
+
Uses the same format as Python, so models can be saved and loaded in either language
|
397
|
+
|
398
|
+
Flat trend
|
399
|
+
|
400
|
+
```ruby
|
401
|
+
m = Prophet.new(growth: "flat")
|
402
|
+
```
|
403
|
+
|
404
|
+
Updating fitted models
|
405
|
+
|
406
|
+
```ruby
|
407
|
+
def stan_init(m)
|
408
|
+
res = {}
|
409
|
+
["k", "m", "sigma_obs"].each do |pname|
|
410
|
+
res[pname] = m.params[pname][0, true][0]
|
411
|
+
end
|
412
|
+
["delta", "beta"].each do |pname|
|
413
|
+
res[pname] = m.params[pname][0, true]
|
414
|
+
end
|
415
|
+
res
|
416
|
+
end
|
417
|
+
|
418
|
+
df = Rover.read_csv("example_wp_log_peyton_manning.csv")
|
419
|
+
df1 = df[df["ds"] <= "2016-01-19"] # All data except the last day
|
420
|
+
m1 = Prophet.new.fit(df1) # A model fit to all data except the last day
|
421
|
+
|
422
|
+
m2 = Prophet.new.fit(df) # Adding the last day, fitting from scratch
|
423
|
+
m2 = Prophet.new.fit(df, init: stan_init(m1)) # Adding the last day, warm-starting from m1
|
424
|
+
```
|
425
|
+
|
279
426
|
## Resources
|
280
427
|
|
281
428
|
- [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.
|
data/data-raw/README.md
ADDED