prophet-rb 0.5.0 → 0.5.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 +10 -0
- data/LICENSE.txt +1 -1
- data/README.md +1 -10
- data/lib/prophet/forecaster.rb +35 -9
- data/lib/prophet/plot.rb +3 -2
- data/lib/prophet/stan_backend.rb +3 -3
- data/lib/prophet/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 455967bcdd71332715b83a6095dd9068fdcfbe5c29064315458faa31ef9f37bb
|
4
|
+
data.tar.gz: 7492995c53307c1c37eb8b169e32fdaac474e91e8398e41c8c7d2c9e40ea5cfb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2627962cf86a8eaa3b7018aa82157b6b53837817ab642782078372368199e8a80417ec93dc7e0bb8f44a5b8f32a9ba3492e18433579c13e24215dea84f9aa961
|
7
|
+
data.tar.gz: 118b13c8aefe85854f64d84a4bbcd0b72bf5fd77e46bc0c99902c0651c7530ca413c1a388820a894c4ed08f779db7cf4027bc5682dbe9dcb6081ad1d6ce1ee97
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
## 0.5.2 (2024-10-26)
|
2
|
+
|
3
|
+
- Fixed warning with `plot` method
|
4
|
+
|
5
|
+
## 0.5.1 (2024-05-06)
|
6
|
+
|
7
|
+
- Added `scaling` option
|
8
|
+
- Fixed issue with yearly seasonality being enabled without enough data
|
9
|
+
- Fixed issue with internal columns in `predict` output (`col`, `col_lower`, and `col_upper`)
|
10
|
+
|
1
11
|
## 0.5.0 (2023-09-05)
|
2
12
|
|
3
13
|
- Added support for Polars
|
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-
|
4
|
+
Copyright (c) 2020-2024 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
@@ -10,7 +10,7 @@ Supports:
|
|
10
10
|
|
11
11
|
And gracefully handles missing data
|
12
12
|
|
13
|
-
[](https://github.com/ankane/prophet-ruby/actions)
|
14
14
|
|
15
15
|
## Installation
|
16
16
|
|
@@ -454,15 +454,6 @@ m2 = Prophet.new.fit(df, init: stan_init(m1)) # Adding the last day, warm-starti
|
|
454
454
|
|
455
455
|
- [Forecasting at Scale](https://peerj.com/preprints/3190.pdf)
|
456
456
|
|
457
|
-
## Upgrading
|
458
|
-
|
459
|
-
### 0.2.0
|
460
|
-
|
461
|
-
Prophet now uses [Rover](https://github.com/ankane/rover) instead of Daru. Two changes you may need to make are:
|
462
|
-
|
463
|
-
- `Rover.read_csv` instead of `Daru::DataFrame.from_csv`
|
464
|
-
- `df[["ds", "yhat"]]` instead of `df["ds", "yhat"]`
|
465
|
-
|
466
457
|
## Credits
|
467
458
|
|
468
459
|
This library was ported from the [Prophet Python library](https://github.com/facebook/prophet) and is available under the same license.
|
data/lib/prophet/forecaster.rb
CHANGED
@@ -27,7 +27,8 @@ module Prophet
|
|
27
27
|
changepoint_prior_scale: 0.05,
|
28
28
|
mcmc_samples: 0,
|
29
29
|
interval_width: 0.80,
|
30
|
-
uncertainty_samples: 1000
|
30
|
+
uncertainty_samples: 1000,
|
31
|
+
scaling: "absmax"
|
31
32
|
)
|
32
33
|
@growth = growth
|
33
34
|
|
@@ -54,6 +55,10 @@ module Prophet
|
|
54
55
|
@mcmc_samples = mcmc_samples
|
55
56
|
@interval_width = interval_width
|
56
57
|
@uncertainty_samples = uncertainty_samples
|
58
|
+
if !["absmax", "minmax"].include?(scaling)
|
59
|
+
raise ArgumentError, "scaling must be one of \"absmax\" or \"minmax\""
|
60
|
+
end
|
61
|
+
@scaling = scaling
|
57
62
|
|
58
63
|
# Set during fitting or by other methods
|
59
64
|
@start = nil
|
@@ -124,7 +129,7 @@ module Prophet
|
|
124
129
|
reserved_names = [
|
125
130
|
"trend", "additive_terms", "daily", "weekly", "yearly",
|
126
131
|
"holidays", "zeros", "extra_regressors_additive", "yhat",
|
127
|
-
"extra_regressors_multiplicative", "multiplicative_terms"
|
132
|
+
"extra_regressors_multiplicative", "multiplicative_terms"
|
128
133
|
]
|
129
134
|
rn_l = reserved_names.map { |n| "#{n}_lower" }
|
130
135
|
rn_u = reserved_names.map { |n| "#{n}_upper" }
|
@@ -189,7 +194,11 @@ module Prophet
|
|
189
194
|
raise ArgumentError, "Expected column \"floor\"."
|
190
195
|
end
|
191
196
|
else
|
192
|
-
|
197
|
+
if @scaling == "absmax"
|
198
|
+
df["floor"] = 0
|
199
|
+
elsif @scaling == "minmax"
|
200
|
+
df["floor"] = @y_min
|
201
|
+
end
|
193
202
|
end
|
194
203
|
|
195
204
|
if @growth == "logistic"
|
@@ -219,11 +228,22 @@ module Prophet
|
|
219
228
|
|
220
229
|
if @growth == "logistic" && df.include?("floor")
|
221
230
|
@logistic_floor = true
|
222
|
-
|
231
|
+
if @scaling == "absmax"
|
232
|
+
@y_min = (df["y"] - df["floor"]).abs.min.to_f
|
233
|
+
@y_scale = (df["y"] - df["floor"]).abs.max.to_f
|
234
|
+
elsif @scaling == "minmax"
|
235
|
+
@y_min = df["floor"].min
|
236
|
+
@y_scale = (df["cap"].max - @y_min).to_f
|
237
|
+
end
|
223
238
|
else
|
224
|
-
|
239
|
+
if @scaling == "absmax"
|
240
|
+
@y_min = 0.0
|
241
|
+
@y_scale = df["y"].abs.max.to_f
|
242
|
+
elsif @scaling == "minmax"
|
243
|
+
@y_min = df["y"].min
|
244
|
+
@y_scale = (df["y"].max - @y_min).to_f
|
245
|
+
end
|
225
246
|
end
|
226
|
-
@y_scale = (df["y"] - floor).abs.max
|
227
247
|
@y_scale = 1 if @y_scale == 0
|
228
248
|
@start = df["ds"].min
|
229
249
|
@t_scale = df["ds"].max - @start
|
@@ -547,7 +567,7 @@ module Prophet
|
|
547
567
|
days = 86400
|
548
568
|
|
549
569
|
# Yearly seasonality
|
550
|
-
yearly_disable = last - first <
|
570
|
+
yearly_disable = last - first < 730 * days
|
551
571
|
fourier_order = parse_seasonality_args("yearly", @yearly_seasonality, yearly_disable, 10)
|
552
572
|
if fourier_order > 0
|
553
573
|
@seasonalities["yearly"] = {
|
@@ -807,7 +827,7 @@ module Prophet
|
|
807
827
|
|
808
828
|
x = seasonal_features.to_numo
|
809
829
|
data = {}
|
810
|
-
component_cols.vector_names.each do |component|
|
830
|
+
(component_cols.vector_names - ["col"]).each do |component|
|
811
831
|
beta_c = @params["beta"] * component_cols[component].to_numo
|
812
832
|
|
813
833
|
comp = x.dot(beta_c.transpose)
|
@@ -1052,7 +1072,7 @@ module Prophet
|
|
1052
1072
|
"yearly_seasonality", "weekly_seasonality", "daily_seasonality",
|
1053
1073
|
"seasonality_mode", "seasonality_prior_scale", "changepoint_prior_scale",
|
1054
1074
|
"holidays_prior_scale", "mcmc_samples", "interval_width", "uncertainty_samples",
|
1055
|
-
"y_scale", "logistic_floor", "country_holidays", "component_modes"
|
1075
|
+
"y_scale", "y_min", "scaling", "logistic_floor", "country_holidays", "component_modes"
|
1056
1076
|
]
|
1057
1077
|
|
1058
1078
|
PD_SERIES = ["changepoints", "history_dates", "train_holiday_names"]
|
@@ -1169,6 +1189,12 @@ module Prophet
|
|
1169
1189
|
|
1170
1190
|
model_dict = JSON.parse(model_json)
|
1171
1191
|
|
1192
|
+
# handle_simple_attributes_backwards_compat
|
1193
|
+
if !model_dict["scaling"]
|
1194
|
+
model_dict["scaling"] = "absmax"
|
1195
|
+
model_dict["y_min"] = 0.0
|
1196
|
+
end
|
1197
|
+
|
1172
1198
|
# We will overwrite all attributes set in init anyway
|
1173
1199
|
model = Prophet.new
|
1174
1200
|
# Simple types
|
data/lib/prophet/plot.rb
CHANGED
@@ -259,7 +259,7 @@ module Prophet
|
|
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)
|
262
|
-
ax.xaxis.set_major_formatter(ticker.FuncFormatter.new(lambda { |x, pos=nil| dates.num2date(x).strftime("%B %-e") }))
|
262
|
+
ax.xaxis.set_major_formatter(ticker.FuncFormatter.new(lambda { |x, pos = nil| dates.num2date(x).strftime("%B %-e") }))
|
263
263
|
ax.xaxis.set_major_locator(months)
|
264
264
|
ax.set_xlabel("Day of year")
|
265
265
|
ax.set_ylabel(name)
|
@@ -301,7 +301,7 @@ module Prophet
|
|
301
301
|
else
|
302
302
|
fmt_str = "%m/%d"
|
303
303
|
end
|
304
|
-
ax.xaxis.set_major_formatter(ticker.FuncFormatter.new(lambda { |x, pos=nil| dates.num2date(x).strftime(fmt_str) }))
|
304
|
+
ax.xaxis.set_major_formatter(ticker.FuncFormatter.new(lambda { |x, pos = nil| dates.num2date(x).strftime(fmt_str) }))
|
305
305
|
ax.set_xlabel("ds")
|
306
306
|
ax.set_ylabel(name)
|
307
307
|
if @seasonalities[name][:mode] == "multiplicative"
|
@@ -313,6 +313,7 @@ module Prophet
|
|
313
313
|
def set_y_as_percent(ax)
|
314
314
|
yticks = 100 * ax.get_yticks
|
315
315
|
yticklabels = yticks.tolist.map { |y| "%.4g%%" % y }
|
316
|
+
ax.set_yticks(ax.get_yticks.tolist)
|
316
317
|
ax.set_yticklabels(yticklabels)
|
317
318
|
ax
|
318
319
|
end
|
data/lib/prophet/stan_backend.rb
CHANGED
@@ -148,14 +148,14 @@ module Prophet
|
|
148
148
|
def platform
|
149
149
|
if Gem.win_platform?
|
150
150
|
"windows"
|
151
|
-
elsif RbConfig::CONFIG["host_os"]
|
152
|
-
if RbConfig::CONFIG["host_cpu"]
|
151
|
+
elsif RbConfig::CONFIG["host_os"].match?(/darwin/i)
|
152
|
+
if RbConfig::CONFIG["host_cpu"].match?(/arm|aarch64/i)
|
153
153
|
"arm64-darwin"
|
154
154
|
else
|
155
155
|
"x86_64-darwin"
|
156
156
|
end
|
157
157
|
else
|
158
|
-
if RbConfig::CONFIG["host_cpu"]
|
158
|
+
if RbConfig::CONFIG["host_cpu"].match?(/arm|aarch64/i)
|
159
159
|
"aarch64-linux"
|
160
160
|
else
|
161
161
|
"x86_64-linux"
|
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.5.
|
4
|
+
version: 0.5.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:
|
11
|
+
date: 2024-10-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cmdstan
|
@@ -166,7 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
166
166
|
- !ruby/object:Gem::Version
|
167
167
|
version: '0'
|
168
168
|
requirements: []
|
169
|
-
rubygems_version: 3.
|
169
|
+
rubygems_version: 3.5.16
|
170
170
|
signing_key:
|
171
171
|
specification_version: 4
|
172
172
|
summary: Time series forecasting for Ruby
|