prophet-rb 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -1
  3. data/LICENSE.txt +1 -1
  4. data/README.md +51 -1
  5. data/data-raw/LICENSE-holidays.txt +20 -0
  6. data/data-raw/README.md +3 -0
  7. data/data-raw/generated_holidays.csv +29302 -61443
  8. data/lib/prophet/forecaster.rb +200 -0
  9. data/lib/prophet/holidays.rb +6 -10
  10. data/lib/prophet/stan_backend.rb +5 -5
  11. data/lib/prophet/version.rb +1 -1
  12. data/lib/prophet.rb +22 -7
  13. data/stan/{unix/prophet.stan → prophet.stan} +8 -7
  14. data/vendor/aarch64-linux/bin/prophet +0 -0
  15. data/vendor/{prophet-linux-arm → aarch64-linux}/lib/libtbb.so +0 -0
  16. data/vendor/{prophet-linux-arm → aarch64-linux}/lib/libtbb.so.2 +0 -0
  17. data/vendor/{prophet-linux-arm → aarch64-linux}/lib/libtbbmalloc.so +0 -0
  18. data/vendor/{prophet-linux-arm → aarch64-linux}/lib/libtbbmalloc.so.2 +0 -0
  19. data/vendor/{prophet-linux-arm → aarch64-linux}/lib/libtbbmalloc_proxy.so +0 -0
  20. data/vendor/{prophet-linux-arm → aarch64-linux}/lib/libtbbmalloc_proxy.so.2 +0 -0
  21. data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/boost-license.txt +0 -0
  22. data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/cli11-license.txt +0 -0
  23. data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/cmdstan-license.txt +0 -0
  24. data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/eigen-bsd-license.txt +0 -0
  25. data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/eigen-mpl2-license.txt +0 -0
  26. data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/prophet-license.txt +0 -0
  27. data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/rapidjson-license.txt +0 -0
  28. data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/stan-license.txt +0 -0
  29. data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/stan-math-license.txt +0 -0
  30. data/vendor/aarch64-linux/licenses/sundials-license.txt +29 -0
  31. data/vendor/aarch64-linux/licenses/sundials-notice.txt +21 -0
  32. data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/tbb-license.txt +0 -0
  33. data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/tbb-third-party-programs.txt +0 -0
  34. data/vendor/arm64-darwin/bin/prophet +0 -0
  35. data/vendor/arm64-darwin/lib/libtbb.dylib +0 -0
  36. data/vendor/{prophet-mac-arm → arm64-darwin}/lib/libtbbmalloc.dylib +0 -0
  37. data/vendor/{prophet-mac-arm → arm64-darwin}/lib/libtbbmalloc_proxy.dylib +0 -0
  38. data/vendor/{prophet-linux → arm64-darwin}/licenses/boost-license.txt +0 -0
  39. data/vendor/{prophet-linux → arm64-darwin}/licenses/cli11-license.txt +0 -0
  40. data/vendor/{prophet-linux → arm64-darwin}/licenses/cmdstan-license.txt +0 -0
  41. data/vendor/{prophet-linux → arm64-darwin}/licenses/eigen-bsd-license.txt +0 -0
  42. data/vendor/{prophet-linux → arm64-darwin}/licenses/eigen-mpl2-license.txt +0 -0
  43. data/vendor/{prophet-linux → arm64-darwin}/licenses/prophet-license.txt +0 -0
  44. data/vendor/{prophet-linux → arm64-darwin}/licenses/rapidjson-license.txt +0 -0
  45. data/vendor/{prophet-linux → arm64-darwin}/licenses/stan-license.txt +0 -0
  46. data/vendor/{prophet-linux → arm64-darwin}/licenses/stan-math-license.txt +0 -0
  47. data/vendor/arm64-darwin/licenses/sundials-license.txt +29 -0
  48. data/vendor/arm64-darwin/licenses/sundials-notice.txt +21 -0
  49. data/vendor/{prophet-linux → arm64-darwin}/licenses/tbb-license.txt +0 -0
  50. data/vendor/{prophet-linux → arm64-darwin}/licenses/tbb-third-party-programs.txt +0 -0
  51. data/vendor/x86_64-darwin/bin/prophet +0 -0
  52. data/vendor/x86_64-darwin/lib/libtbb.dylib +0 -0
  53. data/vendor/{prophet-mac → x86_64-darwin}/lib/libtbbmalloc.dylib +0 -0
  54. data/vendor/{prophet-mac → x86_64-darwin}/lib/libtbbmalloc_proxy.dylib +0 -0
  55. data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/boost-license.txt +0 -0
  56. data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/cli11-license.txt +0 -0
  57. data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/cmdstan-license.txt +0 -0
  58. data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/eigen-bsd-license.txt +0 -0
  59. data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/eigen-mpl2-license.txt +0 -0
  60. data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/prophet-license.txt +0 -0
  61. data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/rapidjson-license.txt +0 -0
  62. data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/stan-license.txt +0 -0
  63. data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/stan-math-license.txt +0 -0
  64. data/vendor/x86_64-darwin/licenses/sundials-license.txt +29 -0
  65. data/vendor/x86_64-darwin/licenses/sundials-notice.txt +21 -0
  66. data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/tbb-license.txt +0 -0
  67. data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/tbb-third-party-programs.txt +0 -0
  68. data/vendor/x86_64-linux/bin/prophet +0 -0
  69. data/vendor/{prophet-linux → x86_64-linux}/lib/libtbb.so +0 -0
  70. data/vendor/x86_64-linux/lib/libtbb.so.2 +0 -0
  71. data/vendor/{prophet-linux → x86_64-linux}/lib/libtbbmalloc.so +0 -0
  72. data/vendor/x86_64-linux/lib/libtbbmalloc.so.2 +0 -0
  73. data/vendor/{prophet-linux → x86_64-linux}/lib/libtbbmalloc_proxy.so +0 -0
  74. data/vendor/{prophet-linux → x86_64-linux}/lib/libtbbmalloc_proxy.so.2 +0 -0
  75. data/vendor/{prophet-mac → x86_64-linux}/licenses/boost-license.txt +0 -0
  76. data/vendor/{prophet-mac → x86_64-linux}/licenses/cli11-license.txt +0 -0
  77. data/vendor/{prophet-mac → x86_64-linux}/licenses/cmdstan-license.txt +0 -0
  78. data/vendor/{prophet-mac → x86_64-linux}/licenses/eigen-bsd-license.txt +0 -0
  79. data/vendor/{prophet-mac → x86_64-linux}/licenses/eigen-mpl2-license.txt +0 -0
  80. data/vendor/{prophet-mac → x86_64-linux}/licenses/prophet-license.txt +0 -0
  81. data/vendor/{prophet-mac → x86_64-linux}/licenses/rapidjson-license.txt +0 -0
  82. data/vendor/{prophet-mac → x86_64-linux}/licenses/stan-license.txt +0 -0
  83. data/vendor/{prophet-mac → x86_64-linux}/licenses/stan-math-license.txt +0 -0
  84. data/vendor/x86_64-linux/licenses/sundials-license.txt +29 -0
  85. data/vendor/x86_64-linux/licenses/sundials-notice.txt +21 -0
  86. data/vendor/{prophet-mac → x86_64-linux}/licenses/tbb-license.txt +0 -0
  87. data/vendor/{prophet-mac → x86_64-linux}/licenses/tbb-third-party-programs.txt +0 -0
  88. metadata +79 -74
  89. data/stan/win/prophet.stan +0 -175
  90. data/vendor/prophet-linux/bin/prophet +0 -0
  91. data/vendor/prophet-linux/lib/libtbb.so.2 +0 -0
  92. data/vendor/prophet-linux/lib/libtbbmalloc.so.2 +0 -0
  93. data/vendor/prophet-linux/licenses/sundials-license.txt +0 -67
  94. data/vendor/prophet-linux-arm/bin/prophet +0 -0
  95. data/vendor/prophet-linux-arm/licenses/sundials-license.txt +0 -67
  96. data/vendor/prophet-mac/bin/prophet +0 -0
  97. data/vendor/prophet-mac/lib/libtbb.dylib +0 -0
  98. data/vendor/prophet-mac/licenses/sundials-license.txt +0 -67
  99. data/vendor/prophet-mac-arm/bin/prophet +0 -0
  100. data/vendor/prophet-mac-arm/lib/libtbb.dylib +0 -0
  101. data/vendor/prophet-mac-arm/licenses/sundials-license.txt +0 -67
@@ -386,6 +386,12 @@ module Prophet
386
386
 
387
387
  def add_country_holidays(country_name)
388
388
  raise Error, "Country holidays must be added prior to model fitting." if @history
389
+
390
+ # Fix for previously documented keyword argument
391
+ if country_name.is_a?(Hash) && country_name[:country_name]
392
+ country_name = country_name[:country_name]
393
+ end
394
+
389
395
  # Validate names.
390
396
  get_holiday_names(country_name).each do |name|
391
397
  # Allow merging with existing holidays
@@ -616,6 +622,10 @@ module Prophet
616
622
  end
617
623
  raise ArgumentError, "Must be a data frame" unless df.is_a?(Rover::DataFrame)
618
624
 
625
+ unless df.include?("ds") && df.include?("y")
626
+ raise ArgumentError, "Data frame must have ds and y columns"
627
+ end
628
+
619
629
  history = df[!df["y"].missing]
620
630
  raise Error, "Data has less than 2 non-nil rows" if history.size < 2
621
631
 
@@ -961,6 +971,12 @@ module Prophet
961
971
  Rover::DataFrame.new({"ds" => dates})
962
972
  end
963
973
 
974
+ def to_json
975
+ require "json"
976
+
977
+ JSON.generate(as_json)
978
+ end
979
+
964
980
  private
965
981
 
966
982
  # Time is preferred over DateTime in Ruby docs
@@ -1007,5 +1023,189 @@ module Prophet
1007
1023
  u = Numo::DFloat.new(size).rand(-0.5, 0.5)
1008
1024
  loc - scale * u.sign * Numo::NMath.log(1 - 2 * u.abs)
1009
1025
  end
1026
+
1027
+ SIMPLE_ATTRIBUTES = [
1028
+ "growth", "n_changepoints", "specified_changepoints", "changepoint_range",
1029
+ "yearly_seasonality", "weekly_seasonality", "daily_seasonality",
1030
+ "seasonality_mode", "seasonality_prior_scale", "changepoint_prior_scale",
1031
+ "holidays_prior_scale", "mcmc_samples", "interval_width", "uncertainty_samples",
1032
+ "y_scale", "logistic_floor", "country_holidays", "component_modes"
1033
+ ]
1034
+
1035
+ PD_SERIES = ["changepoints", "history_dates", "train_holiday_names"]
1036
+
1037
+ PD_TIMESTAMP = ["start"]
1038
+
1039
+ PD_TIMEDELTA = ["t_scale"]
1040
+
1041
+ PD_DATAFRAME = ["holidays", "history", "train_component_cols"]
1042
+
1043
+ NP_ARRAY = ["changepoints_t"]
1044
+
1045
+ ORDEREDDICT = ["seasonalities", "extra_regressors"]
1046
+
1047
+ def as_json
1048
+ if @history.nil?
1049
+ raise Error, "This can only be used to serialize models that have already been fit."
1050
+ end
1051
+
1052
+ model_dict =
1053
+ SIMPLE_ATTRIBUTES.to_h do |attribute|
1054
+ [attribute, instance_variable_get("@#{attribute}")]
1055
+ end
1056
+
1057
+ # Handle attributes of non-core types
1058
+ PD_SERIES.each do |attribute|
1059
+ if instance_variable_get("@#{attribute}").nil?
1060
+ model_dict[attribute] = nil
1061
+ else
1062
+ v = instance_variable_get("@#{attribute}")
1063
+ d = {
1064
+ "name" => "ds",
1065
+ "index" => v.size.times.to_a,
1066
+ "data" => v.to_a.map { |v| v.iso8601(3) }
1067
+ }
1068
+ model_dict[attribute] = JSON.generate(d)
1069
+ end
1070
+ end
1071
+ PD_TIMESTAMP.each do |attribute|
1072
+ model_dict[attribute] = instance_variable_get("@#{attribute}").to_f
1073
+ end
1074
+ PD_TIMEDELTA.each do |attribute|
1075
+ model_dict[attribute] = instance_variable_get("@#{attribute}").to_f
1076
+ end
1077
+ PD_DATAFRAME.each do |attribute|
1078
+ if instance_variable_get("@#{attribute}").nil?
1079
+ model_dict[attribute] = nil
1080
+ else
1081
+ # use same format as Pandas
1082
+ v = instance_variable_get("@#{attribute}")
1083
+
1084
+ v = v.dup
1085
+ v["ds"] = v["ds"].map { |v| v.iso8601(3) } if v["ds"]
1086
+ v.delete("col")
1087
+
1088
+ fields =
1089
+ v.types.map do |k, t|
1090
+ type =
1091
+ case t
1092
+ when :object
1093
+ "datetime"
1094
+ when :int64
1095
+ "integer"
1096
+ else
1097
+ "number"
1098
+ end
1099
+ {"name" => k, "type" => type}
1100
+ end
1101
+
1102
+ d = {
1103
+ "schema" => {
1104
+ "fields" => fields,
1105
+ "pandas_version" => "0.20.0"
1106
+ },
1107
+ "data" => v.to_a
1108
+ }
1109
+ model_dict[attribute] = JSON.generate(d)
1110
+ end
1111
+ end
1112
+ NP_ARRAY.each do |attribute|
1113
+ model_dict[attribute] = instance_variable_get("@#{attribute}").to_a
1114
+ end
1115
+ ORDEREDDICT.each do |attribute|
1116
+ model_dict[attribute] = [
1117
+ instance_variable_get("@#{attribute}").keys,
1118
+ instance_variable_get("@#{attribute}").transform_keys(&:to_s)
1119
+ ]
1120
+ end
1121
+ # Other attributes with special handling
1122
+ # fit_kwargs -> Transform any numpy types before serializing.
1123
+ # They do not need to be transformed back on deserializing.
1124
+ # TODO deep copy
1125
+ fit_kwargs = @fit_kwargs.to_h { |k, v| [k.to_s, v.dup] }
1126
+ if fit_kwargs.key?("init")
1127
+ fit_kwargs["init"].each do |k, v|
1128
+ if v.is_a?(Numo::NArray)
1129
+ fit_kwargs["init"][k] = v.to_a
1130
+ # elsif v.is_a?(Float)
1131
+ # fit_kwargs["init"][k] = v.to_f
1132
+ end
1133
+ end
1134
+ end
1135
+ model_dict["fit_kwargs"] = fit_kwargs
1136
+
1137
+ # Params (Dict[str, np.ndarray])
1138
+ model_dict["params"] = params.transform_values(&:to_a)
1139
+ # Attributes that are skipped: stan_fit, stan_backend
1140
+ # Returns 1.0 for Prophet 1.1
1141
+ model_dict["__prophet_version"] = "1.0"
1142
+ model_dict
1143
+ end
1144
+
1145
+ def self.from_json(model_json)
1146
+ require "json"
1147
+
1148
+ model_dict = JSON.parse(model_json)
1149
+
1150
+ # We will overwrite all attributes set in init anyway
1151
+ model = Prophet.new
1152
+ # Simple types
1153
+ SIMPLE_ATTRIBUTES.each do |attribute|
1154
+ model.instance_variable_set("@#{attribute}", model_dict.fetch(attribute))
1155
+ end
1156
+ PD_SERIES.each do |attribute|
1157
+ if model_dict[attribute].nil?
1158
+ model.instance_variable_set("@#{attribute}", nil)
1159
+ else
1160
+ d = JSON.parse(model_dict.fetch(attribute))
1161
+ s = Rover::Vector.new(d["data"])
1162
+ if d["name"] == "ds"
1163
+ s = s.map { |v| Time.parse(v).utc }
1164
+ end
1165
+ model.instance_variable_set("@#{attribute}", s)
1166
+ end
1167
+ end
1168
+ PD_TIMESTAMP.each do |attribute|
1169
+ model.instance_variable_set("@#{attribute}", Time.at(model_dict.fetch(attribute)))
1170
+ end
1171
+ PD_TIMEDELTA.each do |attribute|
1172
+ model.instance_variable_set("@#{attribute}", model_dict.fetch(attribute).to_f)
1173
+ end
1174
+ PD_DATAFRAME.each do |attribute|
1175
+ if model_dict[attribute].nil?
1176
+ model.instance_variable_set("@#{attribute}", nil)
1177
+ else
1178
+ d = JSON.parse(model_dict.fetch(attribute))
1179
+ df = Rover::DataFrame.new(d["data"])
1180
+ df["ds"] = df["ds"].map { |v| Time.parse(v).utc } if df["ds"]
1181
+ if attribute == "train_component_cols"
1182
+ # Special handling because of named index column
1183
+ # df.columns.name = 'component'
1184
+ # df.index.name = 'col'
1185
+ end
1186
+ model.instance_variable_set("@#{attribute}", df)
1187
+ end
1188
+ end
1189
+ NP_ARRAY.each do |attribute|
1190
+ model.instance_variable_set("@#{attribute}", Numo::NArray.cast(model_dict.fetch(attribute)))
1191
+ end
1192
+ ORDEREDDICT.each do |attribute|
1193
+ key_list, unordered_dict = model_dict.fetch(attribute)
1194
+ od = {}
1195
+ key_list.each do |key|
1196
+ od[key] = unordered_dict[key].transform_keys(&:to_sym)
1197
+ end
1198
+ model.instance_variable_set("@#{attribute}", od)
1199
+ end
1200
+ # Other attributes with special handling
1201
+ # fit_kwargs
1202
+ model.instance_variable_set(:@fit_kwargs, model_dict["fit_kwargs"].transform_keys(&:to_sym))
1203
+ # Params (Dict[str, np.ndarray])
1204
+ model.instance_variable_set(:@params, model_dict["params"].transform_values { |v| Numo::NArray.cast(v) })
1205
+ # Skipped attributes
1206
+ # model.stan_backend = nil
1207
+ model.instance_variable_set(:@stan_fit, nil)
1208
+ model
1209
+ end
1010
1210
  end
1011
1211
  end
@@ -2,25 +2,21 @@ module Prophet
2
2
  module Holidays
3
3
  def get_holiday_names(country)
4
4
  years = (1995..2045).to_a
5
- make_holidays_df(years, country)["holiday"].uniq
5
+ holiday_names = make_holidays_df(years, country)["holiday"].uniq
6
+ # TODO raise error in 0.4.0
7
+ logger.warn "Holidays in #{country} are not currently supported"
8
+ holiday_names
6
9
  end
7
10
 
8
11
  def make_holidays_df(year_list, country)
9
12
  holidays_df[(holidays_df["country"] == country) & (holidays_df["year"].in?(year_list))][["ds", "holiday"]]
10
13
  end
11
14
 
12
- # TODO marshal on installation
15
+ # TODO improve performance
13
16
  def holidays_df
14
17
  @holidays_df ||= begin
15
- holidays = {"ds" => [], "holiday" => [], "country" => [], "year" => []}
16
18
  holidays_file = File.expand_path("../../data-raw/generated_holidays.csv", __dir__)
17
- CSV.foreach(holidays_file, headers: true, converters: [:date, :numeric]) do |row|
18
- holidays["ds"] << row["ds"]
19
- holidays["holiday"] << row["holiday"]
20
- holidays["country"] << row["country"]
21
- holidays["year"] << row["year"]
22
- end
23
- Rover::DataFrame.new(holidays)
19
+ Rover.read_csv(holidays_file, converters: [:date, :numeric])
24
20
  end
25
21
  end
26
22
  end
@@ -6,7 +6,7 @@ module Prophet
6
6
  end
7
7
 
8
8
  def load_model
9
- model_file = File.expand_path("../../vendor/prophet-#{platform}/bin/prophet", __dir__)
9
+ model_file = File.expand_path("../../vendor/#{platform}/bin/prophet", __dir__)
10
10
  raise Error, "Platform not supported yet" unless File.exist?(model_file)
11
11
  CmdStan::Model.new(exe_file: model_file)
12
12
  end
@@ -139,15 +139,15 @@ module Prophet
139
139
  "windows"
140
140
  elsif RbConfig::CONFIG["host_os"] =~ /darwin/i
141
141
  if RbConfig::CONFIG["host_cpu"] =~ /arm|aarch64/i
142
- "mac-arm"
142
+ "arm64-darwin"
143
143
  else
144
- "mac"
144
+ "x86_64-darwin"
145
145
  end
146
146
  else
147
147
  if RbConfig::CONFIG["host_cpu"] =~ /arm|aarch64/i
148
- "linux-arm"
148
+ "aarch64-linux"
149
149
  else
150
- "linux"
150
+ "x86_64-linux"
151
151
  end
152
152
  end
153
153
  end
@@ -1,3 +1,3 @@
1
1
  module Prophet
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
data/lib/prophet.rb CHANGED
@@ -21,9 +21,12 @@ module Prophet
21
21
  Forecaster.new(**kwargs)
22
22
  end
23
23
 
24
- def self.forecast(series, count: 10)
24
+ def self.forecast(series, count: 10, country_holidays: nil, cap: nil, verbose: false, **options)
25
25
  raise ArgumentError, "Series must have at least 10 data points" if series.size < 10
26
26
 
27
+ # error early on unknown keywords
28
+ m = Prophet.new(**options)
29
+
27
30
  # check type to determine output format
28
31
  # check for before converting to time
29
32
  keys = series.keys
@@ -62,12 +65,14 @@ module Prophet
62
65
 
63
66
  # use series, not times, so dates are handled correctly
64
67
  df = Rover::DataFrame.new({"ds" => series.keys, "y" => series.values})
68
+ df["cap"] = cap if cap
65
69
 
66
- m = Prophet.new
67
- m.logger.level = ::Logger::FATAL # no logging
70
+ m.logger.level = ::Logger::FATAL unless verbose
71
+ m.add_country_holidays(country_holidays) if country_holidays
68
72
  m.fit(df)
69
73
 
70
74
  future = m.make_future_dataframe(periods: count, include_history: false, freq: freq)
75
+ future["cap"] = cap if cap
71
76
  forecast = m.predict(future)
72
77
  result = forecast[["ds", "yhat"]].to_a
73
78
 
@@ -84,13 +89,23 @@ module Prophet
84
89
  result.map { |v| [v["ds"], v["yhat"]] }.to_h
85
90
  end
86
91
 
87
- def self.anomalies(series)
88
- df = Rover::DataFrame.new(series.map { |k, v| {"ds" => k, "y" => v} })
89
- m = Prophet.new(interval_width: 0.99)
90
- m.logger.level = ::Logger::FATAL # no logging
92
+ # TODO better name for interval_width
93
+ # TODO DRY with forecast method
94
+ def self.anomalies(series, interval_width: 0.99, country_holidays: nil, cap: nil, verbose: false, **options)
95
+ df = Rover::DataFrame.new({"ds" => series.keys, "y" => series.values})
96
+ df["cap"] = cap if cap
97
+
98
+ m = Prophet.new(interval_width: interval_width, **options)
99
+ m.logger.level = ::Logger::FATAL unless verbose
100
+ m.add_country_holidays(country_holidays) if country_holidays
91
101
  m.fit(df)
102
+
92
103
  forecast = m.predict(df)
93
104
  # filter df["ds"] to ensure dates/times in same format as input
94
105
  df["ds"][(df["y"] < forecast["yhat_lower"]) | (df["y"] > forecast["yhat_upper"])].to_a
95
106
  end
107
+
108
+ def self.from_json(model_json)
109
+ Forecaster.from_json(model_json)
110
+ end
96
111
  end
@@ -101,8 +101,9 @@ data {
101
101
  }
102
102
 
103
103
  transformed data {
104
- matrix[T, S] A;
105
- A = get_changepoint_matrix(t, t_change, T, S);
104
+ matrix[T, S] A = get_changepoint_matrix(t, t_change, T, S);
105
+ matrix[T, K] X_sa = X .* rep_matrix(s_a', T);
106
+ matrix[T, K] X_sm = X .* rep_matrix(s_m', T);
106
107
  }
107
108
 
108
109
  parameters {
@@ -133,10 +134,10 @@ model {
133
134
  beta ~ normal(0, sigmas);
134
135
 
135
136
  // Likelihood
136
- y ~ normal(
137
- trend
138
- .* (1 + X * (beta .* s_m))
139
- + X * (beta .* s_a),
140
- sigma_obs
137
+ y ~ normal_id_glm(
138
+ X_sa,
139
+ trend .* (1 + X_sm * beta),
140
+ beta,
141
+ sigma_obs
141
142
  );
142
143
  }
Binary file
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2002-2022, Lawrence Livermore National Security and Southern Methodist University.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ * Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ * Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ * Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,21 @@
1
+ This work was produced under the auspices of the U.S. Department of
2
+ Energy by Lawrence Livermore National Laboratory under Contract
3
+ DE-AC52-07NA27344.
4
+
5
+ This work was prepared as an account of work sponsored by an agency of
6
+ the United States Government. Neither the United States Government nor
7
+ Lawrence Livermore National Security, LLC, nor any of their employees
8
+ makes any warranty, expressed or implied, or assumes any legal liability
9
+ or responsibility for the accuracy, completeness, or usefulness of any
10
+ information, apparatus, product, or process disclosed, or represents that
11
+ its use would not infringe privately owned rights.
12
+
13
+ Reference herein to any specific commercial product, process, or service
14
+ by trade name, trademark, manufacturer, or otherwise does not necessarily
15
+ constitute or imply its endorsement, recommendation, or favoring by the
16
+ United States Government or Lawrence Livermore National Security, LLC.
17
+
18
+ The views and opinions of authors expressed herein do not necessarily
19
+ state or reflect those of the United States Government or Lawrence
20
+ Livermore National Security, LLC, and shall not be used for advertising
21
+ or product endorsement purposes.
Binary file
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2002-2022, Lawrence Livermore National Security and Southern Methodist University.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ * Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ * Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ * Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,21 @@
1
+ This work was produced under the auspices of the U.S. Department of
2
+ Energy by Lawrence Livermore National Laboratory under Contract
3
+ DE-AC52-07NA27344.
4
+
5
+ This work was prepared as an account of work sponsored by an agency of
6
+ the United States Government. Neither the United States Government nor
7
+ Lawrence Livermore National Security, LLC, nor any of their employees
8
+ makes any warranty, expressed or implied, or assumes any legal liability
9
+ or responsibility for the accuracy, completeness, or usefulness of any
10
+ information, apparatus, product, or process disclosed, or represents that
11
+ its use would not infringe privately owned rights.
12
+
13
+ Reference herein to any specific commercial product, process, or service
14
+ by trade name, trademark, manufacturer, or otherwise does not necessarily
15
+ constitute or imply its endorsement, recommendation, or favoring by the
16
+ United States Government or Lawrence Livermore National Security, LLC.
17
+
18
+ The views and opinions of authors expressed herein do not necessarily
19
+ state or reflect those of the United States Government or Lawrence
20
+ Livermore National Security, LLC, and shall not be used for advertising
21
+ or product endorsement purposes.
Binary file
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2002-2022, Lawrence Livermore National Security and Southern Methodist University.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ * Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ * Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ * Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.