prophet-rb 0.2.0 → 0.2.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 +4 -0
- data/README.md +49 -12
- data/lib/prophet.rb +38 -0
- data/lib/prophet/forecaster.rb +13 -0
- data/lib/prophet/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6469e3c9b0f7d026678845025284f37f7c72f875e19a5f245d9bbc745d348a38
|
4
|
+
data.tar.gz: f3be6a4488cf07a9b2b36f2ce8dd20e9c42aa4297b36b7c56d0ac16bbd6a28f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6476dc943d7a23bf74e84a8fec345009b4587e1e514e9b8e22b32fdd02e44a0f60870eb918b5cb097cd47f1da3e9ad8481098f6800736eadc31fffd7db266f75
|
7
|
+
data.tar.gz: e831ae81325d98e12a3b53bf3e68f87fdc953ad8cba1f22daca5cd375c822a9d39e5f192a4c40eeaf5c62c852955fce3b300680538988a7449069fc3de25fefb
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -20,11 +20,39 @@ Add this line to your application’s Gemfile:
|
|
20
20
|
gem 'prophet-rb'
|
21
21
|
```
|
22
22
|
|
23
|
-
##
|
23
|
+
## Simple API
|
24
24
|
|
25
|
-
|
25
|
+
Get future predictions for a time series
|
26
26
|
|
27
|
-
|
27
|
+
```ruby
|
28
|
+
series = {
|
29
|
+
Date.parse("2020-01-01") => 100,
|
30
|
+
Date.parse("2020-01-02") => 150,
|
31
|
+
Date.parse("2020-01-03") => 136,
|
32
|
+
# ...
|
33
|
+
}
|
34
|
+
|
35
|
+
Prophet.forecast(series)
|
36
|
+
```
|
37
|
+
|
38
|
+
Specify the number of predictions to return
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
Prophet.forecast(series, count: 3)
|
42
|
+
```
|
43
|
+
|
44
|
+
Works great with [Groupdate](https://github.com/ankane/groupdate)
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
series = User.group_by_day(:created_at).count
|
48
|
+
Prophet.forecast(series)
|
49
|
+
```
|
50
|
+
|
51
|
+
## Advanced API
|
52
|
+
|
53
|
+
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.
|
54
|
+
|
55
|
+
## Advanced Quick Start
|
28
56
|
|
29
57
|
[Explanation](https://facebook.github.io/prophet/docs/quick_start.html)
|
30
58
|
|
@@ -32,7 +60,7 @@ Create a data frame with `ds` and `y` columns - here’s [an example](examples/e
|
|
32
60
|
|
33
61
|
```ruby
|
34
62
|
df = Rover.read_csv("example_wp_log_peyton_manning.csv")
|
35
|
-
df.head
|
63
|
+
df.head
|
36
64
|
```
|
37
65
|
|
38
66
|
ds | y
|
@@ -54,7 +82,7 @@ Make a data frame with a `ds` column for future predictions
|
|
54
82
|
|
55
83
|
```ruby
|
56
84
|
future = m.make_future_dataframe(periods: 365)
|
57
|
-
future.tail
|
85
|
+
future.tail
|
58
86
|
```
|
59
87
|
|
60
88
|
ds |
|
@@ -69,7 +97,7 @@ Make predictions
|
|
69
97
|
|
70
98
|
```ruby
|
71
99
|
forecast = m.predict(future)
|
72
|
-
forecast["ds", "yhat", "yhat_lower", "yhat_upper"].tail
|
100
|
+
forecast[["ds", "yhat", "yhat_lower", "yhat_upper"]].tail
|
73
101
|
```
|
74
102
|
|
75
103
|
ds | yhat | yhat_lower | yhat_upper
|
@@ -147,20 +175,20 @@ Create a data frame with `holiday` and `ds` columns. Include all occurrences in
|
|
147
175
|
|
148
176
|
```ruby
|
149
177
|
playoffs = Rover::DataFrame.new(
|
150
|
-
"holiday" =>
|
178
|
+
"holiday" => "playoff",
|
151
179
|
"ds" => ["2008-01-13", "2009-01-03", "2010-01-16",
|
152
180
|
"2010-01-24", "2010-02-07", "2011-01-08",
|
153
181
|
"2013-01-12", "2014-01-12", "2014-01-19",
|
154
182
|
"2014-02-02", "2015-01-11", "2016-01-17",
|
155
183
|
"2016-01-24", "2016-02-07"],
|
156
|
-
"lower_window" =>
|
157
|
-
"upper_window" =>
|
184
|
+
"lower_window" => 0,
|
185
|
+
"upper_window" => 1
|
158
186
|
)
|
159
187
|
superbowls = Rover::DataFrame.new(
|
160
|
-
"holiday" =>
|
188
|
+
"holiday" => "superbowl",
|
161
189
|
"ds" => ["2010-02-07", "2014-02-02", "2016-02-07"],
|
162
|
-
"lower_window" =>
|
163
|
-
"upper_window" =>
|
190
|
+
"lower_window" => 0,
|
191
|
+
"upper_window" => 1
|
164
192
|
)
|
165
193
|
holidays = playoffs.concat(superbowls)
|
166
194
|
|
@@ -246,6 +274,15 @@ forecast = m.predict(future)
|
|
246
274
|
|
247
275
|
- [Forecasting at Scale](https://peerj.com/preprints/3190.pdf)
|
248
276
|
|
277
|
+
## Upgrading
|
278
|
+
|
279
|
+
### 0.2.0
|
280
|
+
|
281
|
+
Prophet now uses [Rover](https://github.com/ankane/rover) instead of Daru. Two changes you may need to make are:
|
282
|
+
|
283
|
+
- `Rover.read_csv` instead of `Daru::DataFrame.from_csv`
|
284
|
+
- `df[["ds", "yhat"]]` instead of `df["ds", "yhat"]`
|
285
|
+
|
249
286
|
## Credits
|
250
287
|
|
251
288
|
This library was ported from the [Prophet Python library](https://github.com/facebook/prophet) and is available under the same license.
|
data/lib/prophet.rb
CHANGED
@@ -20,4 +20,42 @@ module Prophet
|
|
20
20
|
def self.new(**kwargs)
|
21
21
|
Forecaster.new(**kwargs)
|
22
22
|
end
|
23
|
+
|
24
|
+
# to add time support in future, see
|
25
|
+
# https://github.com/ankane/prophet/commit/06e3562835cbcf06b8431f3a91fe2618d4703eb7
|
26
|
+
def self.forecast(series, count: 10)
|
27
|
+
raise ArgumentError, "Series must have at least 10 data points" if series.size < 10
|
28
|
+
|
29
|
+
keys = series.keys
|
30
|
+
bad_key = keys.find { |k| !k.is_a?(Date) }
|
31
|
+
raise ArgumentError, "Expected Date, got #{bad_key.class.name}" if bad_key
|
32
|
+
|
33
|
+
week = keys.map { |k| k.wday }.uniq.size == 1
|
34
|
+
month = keys.all? { |k| k.day == 1 }
|
35
|
+
quarter = month && keys.all? { |k| k.month % 3 == 1 }
|
36
|
+
year = quarter && keys.all? { |k| k.month == 1 }
|
37
|
+
|
38
|
+
freq =
|
39
|
+
if year
|
40
|
+
"YS"
|
41
|
+
elsif quarter
|
42
|
+
"QS"
|
43
|
+
elsif month
|
44
|
+
"MS"
|
45
|
+
elsif week
|
46
|
+
"W"
|
47
|
+
else
|
48
|
+
"D"
|
49
|
+
end
|
50
|
+
|
51
|
+
df = Rover::DataFrame.new({"ds" => series.keys, "y" => series.values})
|
52
|
+
|
53
|
+
m = Prophet.new
|
54
|
+
m.logger.level = ::Logger::FATAL # no logging
|
55
|
+
m.fit(df)
|
56
|
+
|
57
|
+
future = m.make_future_dataframe(periods: count, include_history: false, freq: freq)
|
58
|
+
forecast = m.predict(future)
|
59
|
+
forecast[["ds", "yhat"]].to_a.map { |v| [v["ds"].to_date, v["yhat"]] }.to_h
|
60
|
+
end
|
23
61
|
end
|
data/lib/prophet/forecaster.rb
CHANGED
@@ -911,9 +911,22 @@ module Prophet
|
|
911
911
|
dates = (periods + 1).times.map { |i| last_date + i * week }
|
912
912
|
when "MS"
|
913
913
|
dates = [last_date]
|
914
|
+
# TODO reset day from last date, but keep time
|
914
915
|
periods.times do
|
915
916
|
dates << dates.last.to_datetime.next_month.to_time.utc
|
916
917
|
end
|
918
|
+
when "QS"
|
919
|
+
dates = [last_date]
|
920
|
+
# TODO reset day and month from last date, but keep time
|
921
|
+
periods.times do
|
922
|
+
dates << dates.last.to_datetime.next_month.next_month.next_month.to_time.utc
|
923
|
+
end
|
924
|
+
when "YS"
|
925
|
+
dates = [last_date]
|
926
|
+
# TODO reset day and month from last date, but keep time
|
927
|
+
periods.times do
|
928
|
+
dates << dates.last.to_datetime.next_year.to_time.utc
|
929
|
+
end
|
917
930
|
else
|
918
931
|
raise ArgumentError, "Unknown freq: #{freq}"
|
919
932
|
end
|
data/lib/prophet/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prophet-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cmdstan
|