prophet-rb 0.2.0 → 0.2.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2b37dc1a6be57b67cd740727e0bf4ac0b3a4cf2e27ed19647b631094696787da
4
- data.tar.gz: 892af24ebdd897d7dba904ed7b11a83390533666de13bb3f57172e26839ade3a
3
+ metadata.gz: 6469e3c9b0f7d026678845025284f37f7c72f875e19a5f245d9bbc745d348a38
4
+ data.tar.gz: f3be6a4488cf07a9b2b36f2ce8dd20e9c42aa4297b36b7c56d0ac16bbd6a28f2
5
5
  SHA512:
6
- metadata.gz: 53bc289290cf1a7861419634a057253f3727994c2e911247af0adf7e39688a15c019e180274cb8dd1e2a140e94dafc90ef7ff996319446b535c5f08a9090a990
7
- data.tar.gz: 6b4ecdfcfb03f3e9da68f244fd8d25f5f9bee9a854bdc4d9f68d4907f59260a485df323eb70cc60cdc68e1c1e0d5e9b5431313785bd22da72758fd90fbda7bd2
6
+ metadata.gz: 6476dc943d7a23bf74e84a8fec345009b4587e1e514e9b8e22b32fdd02e44a0f60870eb918b5cb097cd47f1da3e9ad8481098f6800736eadc31fffd7db266f75
7
+ data.tar.gz: e831ae81325d98e12a3b53bf3e68f87fdc953ad8cba1f22daca5cd375c822a9d39e5f192a4c40eeaf5c62c852955fce3b300680538988a7449069fc3de25fefb
@@ -1,3 +1,7 @@
1
+ ## 0.2.1 (2020-07-15)
2
+
3
+ - Added `forecast` method
4
+
1
5
  ## 0.2.0 (2020-05-13)
2
6
 
3
7
  - Switched from Daru to Rover
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
- ## Documentation
23
+ ## Simple API
24
24
 
25
- Check out the [Prophet documentation](https://facebook.github.io/prophet/docs/quick_start.html) for a great explanation of all of the features. The Ruby API follows the Python API and supports the same features.
25
+ Get future predictions for a time series
26
26
 
27
- ## Quick Start
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(5)
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(5)
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(5)
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" => ["playoff"] * 14,
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" => [0] * 14,
157
- "upper_window" => [1] * 14
184
+ "lower_window" => 0,
185
+ "upper_window" => 1
158
186
  )
159
187
  superbowls = Rover::DataFrame.new(
160
- "holiday" => ["superbowl"] * 3,
188
+ "holiday" => "superbowl",
161
189
  "ds" => ["2010-02-07", "2014-02-02", "2016-02-07"],
162
- "lower_window" => [0] * 3,
163
- "upper_window" => [1] * 3
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.
@@ -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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Prophet
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
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.0
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-05-14 00:00:00.000000000 Z
11
+ date: 2020-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cmdstan