prophet-rb 0.2.2 → 0.2.3
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/LICENSE.txt +1 -1
- data/README.md +2 -2
- data/lib/prophet.rb +35 -10
- data/lib/prophet/forecaster.rb +3 -0
- data/lib/prophet/version.rb +1 -1
- metadata +30 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 756e42a4e2c39e114610d2f41e2403d9b160e77da02c0483e43b4bf460dd828b
|
4
|
+
data.tar.gz: e7bce55f47410227131afcba9d2f90c9812dab093efd1c17465383b3a5e6dc73
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec014f32ff39abd49195d7e9a7f38b3b297bc7f6fc28da3d1be6fb19b6edbe816a681c4fbb35d5ea79fc2ced0aa948b0468cff9f6d9d8293590761711944b71b
|
7
|
+
data.tar.gz: 87ecc8706c73e7f1063c8d75cc5c687ebc3fddb92d89e60bb115d21c90a60fbb6172648a0d414baeb11f04572b37e06777d4100acb07b8559dea8e8a711741fb
|
data/CHANGELOG.md
CHANGED
data/LICENSE.txt
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
MIT License
|
2
2
|
|
3
|
-
Copyright (c) 2020 Andrew Kane
|
4
3
|
Copyright (c) Facebook, Inc. and its affiliates.
|
4
|
+
Copyright (c) 2020 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
@@ -118,7 +118,7 @@ Plot the forecast
|
|
118
118
|
m.plot(forecast).savefig("forecast.png")
|
119
119
|
```
|
120
120
|
|
121
|
-
![Forecast](https://blazer.dokkuapp.com/assets/prophet/forecast-
|
121
|
+
![Forecast](https://blazer.dokkuapp.com/assets/prophet/forecast-77cf453fda67d1b462c6c22aee3a02572203b71c4517fedecc1f438cd374a876.png)
|
122
122
|
|
123
123
|
Plot components
|
124
124
|
|
@@ -126,7 +126,7 @@ Plot components
|
|
126
126
|
m.plot_components(forecast).savefig("components.png")
|
127
127
|
```
|
128
128
|
|
129
|
-
![Components](https://blazer.dokkuapp.com/assets/prophet/components-
|
129
|
+
![Components](https://blazer.dokkuapp.com/assets/prophet/components-2cdd260e23bc89824ecca25f6bfe394deb5821d60b7e0e551469c90d204acd67.png)
|
130
130
|
|
131
131
|
## Saturating Forecasts
|
132
132
|
|
data/lib/prophet.rb
CHANGED
@@ -21,19 +21,22 @@ module Prophet
|
|
21
21
|
Forecaster.new(**kwargs)
|
22
22
|
end
|
23
23
|
|
24
|
-
# to add time support in future, see
|
25
|
-
# https://github.com/ankane/prophet/commit/06e3562835cbcf06b8431f3a91fe2618d4703eb7
|
26
24
|
def self.forecast(series, count: 10)
|
27
25
|
raise ArgumentError, "Series must have at least 10 data points" if series.size < 10
|
28
26
|
|
27
|
+
# check type to determine output format
|
28
|
+
# check for before converting to time
|
29
29
|
keys = series.keys
|
30
|
-
|
31
|
-
|
30
|
+
dates = keys.all? { |k| k.is_a?(Date) }
|
31
|
+
time_zone = keys.first.time_zone if keys.first.respond_to?(:time_zone)
|
32
|
+
utc = keys.first.utc? if keys.first.respond_to?(:utc?)
|
33
|
+
times = keys.map(&:to_time)
|
32
34
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
day = times.all? { |t| t.hour == 0 && t.min == 0 && t.sec == 0 && t.nsec == 0 }
|
36
|
+
week = day && times.map { |k| k.wday }.uniq.size == 1
|
37
|
+
month = day && times.all? { |k| k.day == 1 }
|
38
|
+
quarter = month && times.all? { |k| k.month % 3 == 1 }
|
39
|
+
year = quarter && times.all? { |k| k.month == 1 }
|
37
40
|
|
38
41
|
freq =
|
39
42
|
if year
|
@@ -44,10 +47,20 @@ module Prophet
|
|
44
47
|
"MS"
|
45
48
|
elsif week
|
46
49
|
"W"
|
47
|
-
|
50
|
+
elsif day
|
48
51
|
"D"
|
52
|
+
else
|
53
|
+
diff = Rover::Vector.new(times).sort.diff.to_numo[1..-1]
|
54
|
+
min_diff = diff.min.to_i
|
55
|
+
|
56
|
+
# could be another common divisor
|
57
|
+
# but keep it simple for now
|
58
|
+
raise "Unknown frequency" unless (diff % min_diff).eq(0).all?
|
59
|
+
|
60
|
+
"#{min_diff}S"
|
49
61
|
end
|
50
62
|
|
63
|
+
# use series, not times, so dates are handled correctly
|
51
64
|
df = Rover::DataFrame.new({"ds" => series.keys, "y" => series.values})
|
52
65
|
|
53
66
|
m = Prophet.new
|
@@ -56,6 +69,18 @@ module Prophet
|
|
56
69
|
|
57
70
|
future = m.make_future_dataframe(periods: count, include_history: false, freq: freq)
|
58
71
|
forecast = m.predict(future)
|
59
|
-
forecast[["ds", "yhat"]].to_a
|
72
|
+
result = forecast[["ds", "yhat"]].to_a
|
73
|
+
|
74
|
+
# use the same format as input
|
75
|
+
if dates
|
76
|
+
result.each { |v| v["ds"] = v["ds"].to_date }
|
77
|
+
elsif time_zone
|
78
|
+
result.each { |v| v["ds"] = v["ds"].in_time_zone(time_zone) }
|
79
|
+
elsif utc
|
80
|
+
result.each { |v| v["ds"] = v["ds"].utc }
|
81
|
+
else
|
82
|
+
result.each { |v| v["ds"] = v["ds"].localtime }
|
83
|
+
end
|
84
|
+
result.map { |v| [v["ds"], v["yhat"]] }.to_h
|
60
85
|
end
|
61
86
|
end
|
data/lib/prophet/forecaster.rb
CHANGED
@@ -901,6 +901,9 @@ module Prophet
|
|
901
901
|
# TODO add more freq
|
902
902
|
# https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#timeseries-offset-aliases
|
903
903
|
case freq
|
904
|
+
when /\A\d+S\z/
|
905
|
+
secs = freq.to_i
|
906
|
+
dates = (periods + 1).times.map { |i| last_date + i * secs }
|
904
907
|
when "H"
|
905
908
|
hour = 3600
|
906
909
|
dates = (periods + 1).times.map { |i| last_date + i * hour }
|
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.3
|
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-10-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cmdstan
|
@@ -122,6 +122,34 @@ dependencies:
|
|
122
122
|
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: activesupport
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: tzinfo-data
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
125
153
|
description:
|
126
154
|
email: andrew@chartkick.com
|
127
155
|
executables: []
|