prophet_logistic_growth.stan 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. # Copyright (c) 2017-present, Facebook, Inc.
  2. # All rights reserved.
  3. #
  4. # This source code is licensed under the BSD-style license found in the
  5. # LICENSE file in the root directory of this source tree. An additional grant
  6. # of patent rights can be found in the PATENTS file in the same directory.
  7. data {
  8. int T; // Sample size
  9. int<lower=1> K; // Number of seasonal vectors
  10. vector[T] t; // Day
  11. vector[T] cap; // Capacities
  12. vector[T] y; // Time-series
  13. int S; // Number of split points
  14. matrix[T, S] A; // Split indicators
  15. int s_indx[S]; // Index of split points
  16. matrix[T,K] X; // season vectors
  17. real<lower=0> sigma; // scale on seasonality prior
  18. real<lower=0> tau; // scale on changepoints prior
  19. }
  20. transformed data {
  21. int s_ext[S + 1]; // Segment endpoints
  22. for (j in 1:S) {
  23. s_ext[j] = s_indx[j];
  24. }
  25. s_ext[S + 1] = T + 1; // Used for the m_adj loop below.
  26. }
  27. parameters {
  28. real k; // Base growth rate
  29. real m; // offset
  30. vector[S] delta; // Rate adjustments
  31. real<lower=0> sigma_obs; // Observation noise (incl. seasonal variation)
  32. vector[K] beta; // seasonal vector
  33. }
  34. transformed parameters {
  35. vector[S] gamma; // adjusted offsets, for piecewise continuity
  36. vector[S + 1] k_s; // actual rate in each segment
  37. real m_pr;
  38. // Compute the rate in each segment
  39. k_s[1] = k;
  40. for (i in 1:S) {
  41. k_s[i + 1] = k_s[i] + delta[i];
  42. }
  43. // Piecewise offsets
  44. m_pr = m; // The offset in the previous segment
  45. for (i in 1:S) {
  46. gamma[i] = (t[s_indx[i]] - m_pr) * (1 - k_s[i] / k_s[i + 1]);
  47. m_pr = m_pr + gamma[i]; // update for the next segment
  48. }
  49. }
  50. model {
  51. //priors
  52. k ~ normal(0, 5);
  53. m ~ normal(0, 5);
  54. delta ~ double_exponential(0, tau);
  55. sigma_obs ~ normal(0, 0.1);
  56. beta ~ normal(0, sigma);
  57. // Likelihood
  58. y ~ normal(cap ./ (1 + exp(-(k + A * delta) .* (t - (m + A * gamma)))) + X * beta, sigma_obs);
  59. }