prophet-rb 0.4.1 → 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.
- 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
|