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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4b32ff3ccea1dce9051e3e661ac61ed6c84e7f0f64189f169e11974033163f7e
4
- data.tar.gz: 5dfb93a8cfea394e235fd6597b80e192e3e22a7bf7965d5e13e00e2d8ccc0ed8
3
+ metadata.gz: 756e42a4e2c39e114610d2f41e2403d9b160e77da02c0483e43b4bf460dd828b
4
+ data.tar.gz: e7bce55f47410227131afcba9d2f90c9812dab093efd1c17465383b3a5e6dc73
5
5
  SHA512:
6
- metadata.gz: 47b944a25d3fa34e67d75ccd1cc558ab6777eef0f04c21e5af94328b4e5f03137e3ab29d005fef48cec064e0aeffea58e53997f851e6eee10a2b368c213807da
7
- data.tar.gz: fb27bf59a2d69f5b5444f0b28836a8c6edf0a528199c56ae757cfaee87e69b2caa4f4ef15f703813994b35a6ce74b086895c71fb6737930e482fa7148ad1ca29
6
+ metadata.gz: ec014f32ff39abd49195d7e9a7f38b3b297bc7f6fc28da3d1be6fb19b6edbe816a681c4fbb35d5ea79fc2ced0aa948b0468cff9f6d9d8293590761711944b71b
7
+ data.tar.gz: 87ecc8706c73e7f1063c8d75cc5c687ebc3fddb92d89e60bb115d21c90a60fbb6172648a0d414baeb11f04572b37e06777d4100acb07b8559dea8e8a711741fb
@@ -1,3 +1,7 @@
1
+ ## 0.2.3 (2020-10-14)
2
+
3
+ - Added support for times to `forecast` method
4
+
1
5
  ## 0.2.2 (2020-07-26)
2
6
 
3
7
  - Fixed error with constant series
@@ -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-a9d43195b8ad23703eda7bb8b52b8a758efb4699e2313f32d7bbdfaa2f4275f6.png)
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-b9e31bfcf77e57bbd503c0bcff5e5544e66085b90709b06dd96c5f622a87d84f.png)
129
+ ![Components](https://blazer.dokkuapp.com/assets/prophet/components-2cdd260e23bc89824ecca25f6bfe394deb5821d60b7e0e551469c90d204acd67.png)
130
130
 
131
131
  ## Saturating Forecasts
132
132
 
@@ -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
- bad_key = keys.find { |k| !k.is_a?(Date) }
31
- raise ArgumentError, "Expected Date, got #{bad_key.class.name}" if bad_key
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
- 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 }
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
- else
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.map { |v| [v["ds"].to_date, v["yhat"]] }.to_h
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
@@ -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 }
@@ -1,3 +1,3 @@
1
1
  module Prophet
2
- VERSION = "0.2.2"
2
+ VERSION = "0.2.3"
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.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-07-26 00:00:00.000000000 Z
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: []