prophet-rb 0.4.1 → 0.4.2
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 +32 -5
- data/lib/prophet/diagnostics.rb +1 -1
- data/lib/prophet/forecaster.rb +11 -11
- data/lib/prophet/holidays.rb +5 -2
- data/lib/prophet/plot.rb +4 -4
- 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: b7d18b97220bb11a0d836b1d272728ed9211aa85fb687032c6451d26b70c6755
|
4
|
+
data.tar.gz: c0de54e1a1f66785fe7a61f22c187376c43f9746f9cefa9f6d46834c742f15fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b7d79d1b6c2fd8335ce417c653ecca5b7e15b9092dcba76f0062e38a775a0af6f88bb92334b2a24871745b2d64fb8822c3898617d9c391268cc7c7299e99e31
|
7
|
+
data.tar.gz: 0c094fe16a216ed0f19e566c5c5af896a878b3086f4ac0e550e58e9945c213aae9d12259a08c628b0f02662f7e7c25dcf10313ac65b311f9024a8b60f2b84331
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -87,6 +87,7 @@ Check out the [Prophet documentation](https://facebook.github.io/prophet/docs/qu
|
|
87
87
|
- [Holidays and Special Events](#holidays-and-special-events)
|
88
88
|
- [Multiplicative Seasonality](#multiplicative-seasonality)
|
89
89
|
- [Uncertainty Intervals](#uncertainty-intervals)
|
90
|
+
- [Outliers](#outliers)
|
90
91
|
- [Non-Daily Data](#non-daily-data)
|
91
92
|
- [Diagnostics](#diagnostics)
|
92
93
|
- [Additional Topics](#additional-topics)
|
@@ -228,11 +229,13 @@ Create a data frame with `holiday` and `ds` columns. Include all occurrences in
|
|
228
229
|
```ruby
|
229
230
|
playoffs = Rover::DataFrame.new(
|
230
231
|
"holiday" => "playoff",
|
231
|
-
"ds" => [
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
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
|
+
],
|
236
239
|
"lower_window" => 0,
|
237
240
|
"upper_window" => 1
|
238
241
|
)
|
@@ -287,6 +290,8 @@ forecast = m.predict(future)
|
|
287
290
|
|
288
291
|
[Explanation](https://facebook.github.io/prophet/docs/multiplicative_seasonality.html)
|
289
292
|
|
293
|
+
Specify multiplicative seasonality
|
294
|
+
|
290
295
|
```ruby
|
291
296
|
df = Rover.read_csv("example_air_passengers.csv")
|
292
297
|
m = Prophet.new(seasonality_mode: "multiplicative")
|
@@ -295,8 +300,18 @@ future = m.make_future_dataframe(periods: 50, freq: "MS")
|
|
295
300
|
forecast = m.predict(future)
|
296
301
|
```
|
297
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
|
+
|
298
311
|
## Uncertainty Intervals
|
299
312
|
|
313
|
+
[Explanation](https://facebook.github.io/prophet/docs/uncertainty_intervals.html)
|
314
|
+
|
300
315
|
Specify the width of uncertainty intervals (80% by default)
|
301
316
|
|
302
317
|
```ruby
|
@@ -309,6 +324,18 @@ Get uncertainty in seasonality
|
|
309
324
|
Prophet.new(mcmc_samples: 300)
|
310
325
|
```
|
311
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
|
+
|
312
339
|
## Non-Daily Data
|
313
340
|
|
314
341
|
[Explanation](https://facebook.github.io/prophet/docs/non-daily_data.html)
|
data/lib/prophet/diagnostics.rb
CHANGED
@@ -179,7 +179,7 @@ module Prophet
|
|
179
179
|
if metrics.nil?
|
180
180
|
metrics = valid_metrics
|
181
181
|
end
|
182
|
-
if (df
|
182
|
+
if (!df.include?("yhat_lower") || !df.include?("yhat_upper")) && metrics.include?("coverage")
|
183
183
|
metrics.delete("coverage")
|
184
184
|
end
|
185
185
|
if metrics.uniq.length != metrics.length
|
data/lib/prophet/forecaster.rb
CHANGED
@@ -89,7 +89,7 @@ module Prophet
|
|
89
89
|
raise ArgumentError, "Parameter \"changepoint_range\" must be in [0, 1]"
|
90
90
|
end
|
91
91
|
if @holidays
|
92
|
-
if
|
92
|
+
if !(@holidays.is_a?(Rover::DataFrame) && @holidays.include?("ds") && @holidays.include?("holiday"))
|
93
93
|
raise ArgumentError, "holidays must be a DataFrame with \"ds\" and \"holiday\" columns."
|
94
94
|
end
|
95
95
|
@holidays["ds"] = to_datetime(@holidays["ds"])
|
@@ -125,8 +125,8 @@ module Prophet
|
|
125
125
|
"holidays", "zeros", "extra_regressors_additive", "yhat",
|
126
126
|
"extra_regressors_multiplicative", "multiplicative_terms",
|
127
127
|
]
|
128
|
-
rn_l = reserved_names.map { |n| n
|
129
|
-
rn_u = reserved_names.map { |n| n
|
128
|
+
rn_l = reserved_names.map { |n| "#{n}_lower" }
|
129
|
+
rn_u = reserved_names.map { |n| "#{n}_upper" }
|
130
130
|
reserved_names.concat(rn_l)
|
131
131
|
reserved_names.concat(rn_u)
|
132
132
|
reserved_names.concat(["ds", "y", "cap", "floor", "y_scaled", "cap_scaled"])
|
@@ -142,7 +142,7 @@ module Prophet
|
|
142
142
|
if check_seasonalities && @seasonalities[name]
|
143
143
|
raise ArgumentError, "Name #{name.inspect} already used for a seasonality."
|
144
144
|
end
|
145
|
-
if check_regressors
|
145
|
+
if check_regressors && @extra_regressors[name]
|
146
146
|
raise ArgumentError, "Name #{name.inspect} already used for an added regressor."
|
147
147
|
end
|
148
148
|
end
|
@@ -167,7 +167,7 @@ module Prophet
|
|
167
167
|
raise ArgumentError, "Found NaN in column #{name.inspect}"
|
168
168
|
end
|
169
169
|
end
|
170
|
-
@seasonalities.
|
170
|
+
@seasonalities.each_value do |props|
|
171
171
|
condition_name = props[:condition_name]
|
172
172
|
if condition_name
|
173
173
|
if !df.include?(condition_name)
|
@@ -481,14 +481,14 @@ module Prophet
|
|
481
481
|
end
|
482
482
|
# Add totals additive and multiplicative components, and regressors
|
483
483
|
["additive", "multiplicative"].each do |mode|
|
484
|
-
components = add_group_component(components, mode
|
484
|
+
components = add_group_component(components, "#{mode}_terms", modes[mode])
|
485
485
|
regressors_by_mode = @extra_regressors.select { |r, props| props[:mode] == mode }
|
486
486
|
.map { |r, props| r }
|
487
|
-
components = add_group_component(components, "extra_regressors_"
|
487
|
+
components = add_group_component(components, "extra_regressors_#{mode}", regressors_by_mode)
|
488
488
|
|
489
489
|
# Add combination components to modes
|
490
|
-
modes[mode] << mode
|
491
|
-
modes[mode] << "extra_regressors_"
|
490
|
+
modes[mode] << "#{mode}_terms"
|
491
|
+
modes[mode] << "extra_regressors_#{mode}"
|
492
492
|
end
|
493
493
|
# After all of the additive/multiplicative groups have been added,
|
494
494
|
modes[@seasonality_mode] << "holidays"
|
@@ -817,8 +817,8 @@ module Prophet
|
|
817
817
|
end
|
818
818
|
data[component] = comp.mean(axis: 1, nan: true)
|
819
819
|
if @uncertainty_samples
|
820
|
-
data[component
|
821
|
-
data[component
|
820
|
+
data["#{component}_lower"] = comp.percentile(lower_p, axis: 1)
|
821
|
+
data["#{component}_upper"] = comp.percentile(upper_p, axis: 1)
|
822
822
|
end
|
823
823
|
end
|
824
824
|
Rover::DataFrame.new(data)
|
data/lib/prophet/holidays.rb
CHANGED
@@ -3,8 +3,11 @@ module Prophet
|
|
3
3
|
def get_holiday_names(country)
|
4
4
|
years = (1995..2045).to_a
|
5
5
|
holiday_names = make_holidays_df(years, country)["holiday"].uniq
|
6
|
-
|
7
|
-
|
6
|
+
if holiday_names.size == 0
|
7
|
+
# TODO raise error in 0.5.0
|
8
|
+
# raise ArgumentError, "Holidays in #{country} are not currently supported"
|
9
|
+
logger.warn "Holidays in #{country} are not currently supported"
|
10
|
+
end
|
8
11
|
holiday_names
|
9
12
|
end
|
10
13
|
|
data/lib/prophet/plot.rb
CHANGED
@@ -183,7 +183,7 @@ module Prophet
|
|
183
183
|
ax.plot(fcst_t, fcst["floor"].to_a, ls: "--", c: "k")
|
184
184
|
end
|
185
185
|
if uncertainty && @uncertainty_samples
|
186
|
-
artists += [ax.fill_between(fcst_t, fcst[name
|
186
|
+
artists += [ax.fill_between(fcst_t, fcst["#{name}_lower"].to_a, fcst["#{name}_upper"].to_a, color: "#0072B2", alpha: 0.2)]
|
187
187
|
end
|
188
188
|
# Specify formatting to workaround matplotlib issue #12925
|
189
189
|
locator = dates.AutoDateLocator.new(interval_multiples: false)
|
@@ -229,7 +229,7 @@ module Prophet
|
|
229
229
|
days = days.map { |v| v.strftime("%A") }
|
230
230
|
artists += ax.plot(days.size.times.to_a, seas[name].to_a, ls: "-", c: "#0072B2")
|
231
231
|
if uncertainty && @uncertainty_samples
|
232
|
-
artists += [ax.fill_between(days.size.times.to_a, seas[name
|
232
|
+
artists += [ax.fill_between(days.size.times.to_a, seas["#{name}_lower"].to_a, seas["#{name}_upper"].to_a, color: "#0072B2", alpha: 0.2)]
|
233
233
|
end
|
234
234
|
ax.grid(true, which: "major", c: "gray", ls: "-", lw: 1, alpha: 0.2)
|
235
235
|
ax.set_xticks(days.size.times.to_a)
|
@@ -255,7 +255,7 @@ module Prophet
|
|
255
255
|
seas = predict_seasonal_components(df_y)
|
256
256
|
artists += ax.plot(to_pydatetime(df_y["ds"]), seas[name].to_a, ls: "-", c: "#0072B2")
|
257
257
|
if uncertainty && @uncertainty_samples
|
258
|
-
artists += [ax.fill_between(to_pydatetime(df_y["ds"]), seas[name
|
258
|
+
artists += [ax.fill_between(to_pydatetime(df_y["ds"]), seas["#{name}_lower"].to_a, seas["#{name}_upper"].to_a, color: "#0072B2", alpha: 0.2)]
|
259
259
|
end
|
260
260
|
ax.grid(true, which: "major", c: "gray", ls: "-", lw: 1, alpha: 0.2)
|
261
261
|
months = dates.MonthLocator.new((1..12).to_a, bymonthday: 1, interval: 2)
|
@@ -288,7 +288,7 @@ module Prophet
|
|
288
288
|
seas = predict_seasonal_components(df_y)
|
289
289
|
artists += ax.plot(to_pydatetime(df_y["ds"]), seas[name].to_a, ls: "-", c: "#0072B2")
|
290
290
|
if uncertainty && @uncertainty_samples
|
291
|
-
artists += [ax.fill_between(to_pydatetime(df_y["ds"]), seas[name
|
291
|
+
artists += [ax.fill_between(to_pydatetime(df_y["ds"]), seas["#{name}_lower"].to_a, seas["#{name}_upper"].to_a, color: "#0072B2", alpha: 0.2)]
|
292
292
|
end
|
293
293
|
ax.grid(true, which: "major", c: "gray", ls: "-", lw: 1, alpha: 0.2)
|
294
294
|
step = (finish - start) / (7 - 1).to_f
|
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.4.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-07-
|
11
|
+
date: 2022-07-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cmdstan
|