prophet-rb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,162 @@
1
+ // Copyright (c) Facebook, Inc. and its affiliates.
2
+
3
+ // This source code is licensed under the MIT license found in the
4
+ // LICENSE file in the root directory of this source tree.
5
+
6
+ functions {
7
+ real[ , ] get_changepoint_matrix(real[] t, real[] t_change, int T, int S) {
8
+ // Assumes t and t_change are sorted.
9
+ real A[T, S];
10
+ real a_row[S];
11
+ int cp_idx;
12
+
13
+ // Start with an empty matrix.
14
+ A = rep_array(0, T, S);
15
+ a_row = rep_array(0, S);
16
+ cp_idx = 1;
17
+
18
+ // Fill in each row of A.
19
+ for (i in 1:T) {
20
+ while ((cp_idx <= S) && (t[i] >= t_change[cp_idx])) {
21
+ a_row[cp_idx] = 1;
22
+ cp_idx = cp_idx + 1;
23
+ }
24
+ A[i] = a_row;
25
+ }
26
+ return A;
27
+ }
28
+
29
+ // Logistic trend functions
30
+
31
+ real[] logistic_gamma(real k, real m, real[] delta, real[] t_change, int S) {
32
+ real gamma[S]; // adjusted offsets, for piecewise continuity
33
+ real k_s[S + 1]; // actual rate in each segment
34
+ real m_pr;
35
+
36
+ // Compute the rate in each segment
37
+ k_s[1] = k;
38
+ for (i in 1:S) {
39
+ k_s[i + 1] = k_s[i] + delta[i];
40
+ }
41
+
42
+ // Piecewise offsets
43
+ m_pr = m; // The offset in the previous segment
44
+ for (i in 1:S) {
45
+ gamma[i] = (t_change[i] - m_pr) * (1 - k_s[i] / k_s[i + 1]);
46
+ m_pr = m_pr + gamma[i]; // update for the next segment
47
+ }
48
+ return gamma;
49
+ }
50
+
51
+ real[] logistic_trend(
52
+ real k,
53
+ real m,
54
+ real[] delta,
55
+ real[] t,
56
+ real[] cap,
57
+ real[ , ] A,
58
+ real[] t_change,
59
+ int S,
60
+ int T
61
+ ) {
62
+ real gamma[S];
63
+ real Y[T];
64
+
65
+ gamma = logistic_gamma(k, m, delta, t_change, S);
66
+ for (i in 1:T) {
67
+ Y[i] = cap[i] / (1 + exp(-(k + dot_product(A[i], delta))
68
+ * (t[i] - (m + dot_product(A[i], gamma)))));
69
+ }
70
+ return Y;
71
+ }
72
+
73
+ // Linear trend function
74
+
75
+ real[] linear_trend(
76
+ real k,
77
+ real m,
78
+ real[] delta,
79
+ real[] t,
80
+ real[ , ] A,
81
+ real[] t_change,
82
+ int S,
83
+ int T
84
+ ) {
85
+ real gamma[S];
86
+ real Y[T];
87
+
88
+ for (i in 1:S) {
89
+ gamma[i] = -t_change[i] * delta[i];
90
+ }
91
+ for (i in 1:T) {
92
+ Y[i] = (k + dot_product(A[i], delta)) * t[i] + (
93
+ m + dot_product(A[i], gamma));
94
+ }
95
+ return Y;
96
+ }
97
+ }
98
+
99
+ data {
100
+ int T; // Number of time periods
101
+ int<lower=1> K; // Number of regressors
102
+ real t[T]; // Time
103
+ real cap[T]; // Capacities for logistic trend
104
+ real y[T]; // Time series
105
+ int S; // Number of changepoints
106
+ real t_change[S]; // Times of trend changepoints
107
+ real X[T,K]; // Regressors
108
+ vector[K] sigmas; // Scale on seasonality prior
109
+ real<lower=0> tau; // Scale on changepoints prior
110
+ int trend_indicator; // 0 for linear, 1 for logistic
111
+ real s_a[K]; // Indicator of additive features
112
+ real s_m[K]; // Indicator of multiplicative features
113
+ }
114
+
115
+ transformed data {
116
+ real A[T, S];
117
+ A = get_changepoint_matrix(t, t_change, T, S);
118
+ }
119
+
120
+ parameters {
121
+ real k; // Base trend growth rate
122
+ real m; // Trend offset
123
+ real delta[S]; // Trend rate adjustments
124
+ real<lower=0> sigma_obs; // Observation noise
125
+ real beta[K]; // Regressor coefficients
126
+ }
127
+
128
+ transformed parameters {
129
+ real trend[T];
130
+ real Y[T];
131
+ real beta_m[K];
132
+ real beta_a[K];
133
+
134
+ if (trend_indicator == 0) {
135
+ trend = linear_trend(k, m, delta, t, A, t_change, S, T);
136
+ } else if (trend_indicator == 1) {
137
+ trend = logistic_trend(k, m, delta, t, cap, A, t_change, S, T);
138
+ }
139
+
140
+ for (i in 1:K) {
141
+ beta_m[i] = beta[i] * s_m[i];
142
+ beta_a[i] = beta[i] * s_a[i];
143
+ }
144
+
145
+ for (i in 1:T) {
146
+ Y[i] = (
147
+ trend[i] * (1 + dot_product(X[i], beta_m)) + dot_product(X[i], beta_a)
148
+ );
149
+ }
150
+ }
151
+
152
+ model {
153
+ //priors
154
+ k ~ normal(0, 5);
155
+ m ~ normal(0, 5);
156
+ delta ~ double_exponential(0, tau);
157
+ sigma_obs ~ normal(0, 0.5);
158
+ beta ~ normal(0, sigmas);
159
+
160
+ // Likelihood
161
+ y ~ normal(Y, sigma_obs);
162
+ }
metadata ADDED
@@ -0,0 +1,170 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: prophet-rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Kane
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-04-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: cmdstan
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: daru
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: numo-narray
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '5'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '5'
97
+ - !ruby/object:Gem::Dependency
98
+ name: matplotlib
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: ruby-prof
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description:
126
+ email: andrew@chartkick.com
127
+ executables: []
128
+ extensions:
129
+ - ext/prophet/extconf.rb
130
+ extra_rdoc_files: []
131
+ files:
132
+ - CHANGELOG.md
133
+ - LICENSE.txt
134
+ - README.md
135
+ - data-raw/generated_holidays.csv
136
+ - ext/prophet/Makefile
137
+ - ext/prophet/extconf.rb
138
+ - lib/prophet-rb.rb
139
+ - lib/prophet.rb
140
+ - lib/prophet/forecaster.rb
141
+ - lib/prophet/holidays.rb
142
+ - lib/prophet/plot.rb
143
+ - lib/prophet/stan_backend.rb
144
+ - lib/prophet/version.rb
145
+ - stan/unix/prophet.stan
146
+ - stan/win/prophet.stan
147
+ homepage: https://github.com/ankane/prophet
148
+ licenses:
149
+ - MIT
150
+ metadata: {}
151
+ post_install_message:
152
+ rdoc_options: []
153
+ require_paths:
154
+ - lib
155
+ required_ruby_version: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '2.4'
160
+ required_rubygems_version: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ requirements: []
166
+ rubygems_version: 3.1.2
167
+ signing_key:
168
+ specification_version: 4
169
+ summary: Time series forecasting for Ruby
170
+ test_files: []