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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -1
- data/LICENSE.txt +1 -1
- data/README.md +51 -1
- data/data-raw/LICENSE-holidays.txt +20 -0
- data/data-raw/README.md +3 -0
- data/data-raw/generated_holidays.csv +29302 -61443
- data/lib/prophet/forecaster.rb +200 -0
- data/lib/prophet/holidays.rb +6 -10
- data/lib/prophet/stan_backend.rb +5 -5
- data/lib/prophet/version.rb +1 -1
- data/lib/prophet.rb +22 -7
- data/stan/{unix/prophet.stan → prophet.stan} +8 -7
- data/vendor/aarch64-linux/bin/prophet +0 -0
- data/vendor/{prophet-linux-arm → aarch64-linux}/lib/libtbb.so +0 -0
- data/vendor/{prophet-linux-arm → aarch64-linux}/lib/libtbb.so.2 +0 -0
- data/vendor/{prophet-linux-arm → aarch64-linux}/lib/libtbbmalloc.so +0 -0
- data/vendor/{prophet-linux-arm → aarch64-linux}/lib/libtbbmalloc.so.2 +0 -0
- data/vendor/{prophet-linux-arm → aarch64-linux}/lib/libtbbmalloc_proxy.so +0 -0
- data/vendor/{prophet-linux-arm → aarch64-linux}/lib/libtbbmalloc_proxy.so.2 +0 -0
- data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/boost-license.txt +0 -0
- data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/cli11-license.txt +0 -0
- data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/cmdstan-license.txt +0 -0
- data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/eigen-bsd-license.txt +0 -0
- data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/eigen-mpl2-license.txt +0 -0
- data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/prophet-license.txt +0 -0
- data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/rapidjson-license.txt +0 -0
- data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/stan-license.txt +0 -0
- data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/stan-math-license.txt +0 -0
- data/vendor/aarch64-linux/licenses/sundials-license.txt +29 -0
- data/vendor/aarch64-linux/licenses/sundials-notice.txt +21 -0
- data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/tbb-license.txt +0 -0
- data/vendor/{prophet-linux-arm → aarch64-linux}/licenses/tbb-third-party-programs.txt +0 -0
- data/vendor/arm64-darwin/bin/prophet +0 -0
- data/vendor/arm64-darwin/lib/libtbb.dylib +0 -0
- data/vendor/{prophet-mac-arm → arm64-darwin}/lib/libtbbmalloc.dylib +0 -0
- data/vendor/{prophet-mac-arm → arm64-darwin}/lib/libtbbmalloc_proxy.dylib +0 -0
- data/vendor/{prophet-linux → arm64-darwin}/licenses/boost-license.txt +0 -0
- data/vendor/{prophet-linux → arm64-darwin}/licenses/cli11-license.txt +0 -0
- data/vendor/{prophet-linux → arm64-darwin}/licenses/cmdstan-license.txt +0 -0
- data/vendor/{prophet-linux → arm64-darwin}/licenses/eigen-bsd-license.txt +0 -0
- data/vendor/{prophet-linux → arm64-darwin}/licenses/eigen-mpl2-license.txt +0 -0
- data/vendor/{prophet-linux → arm64-darwin}/licenses/prophet-license.txt +0 -0
- data/vendor/{prophet-linux → arm64-darwin}/licenses/rapidjson-license.txt +0 -0
- data/vendor/{prophet-linux → arm64-darwin}/licenses/stan-license.txt +0 -0
- data/vendor/{prophet-linux → arm64-darwin}/licenses/stan-math-license.txt +0 -0
- data/vendor/arm64-darwin/licenses/sundials-license.txt +29 -0
- data/vendor/arm64-darwin/licenses/sundials-notice.txt +21 -0
- data/vendor/{prophet-linux → arm64-darwin}/licenses/tbb-license.txt +0 -0
- data/vendor/{prophet-linux → arm64-darwin}/licenses/tbb-third-party-programs.txt +0 -0
- data/vendor/x86_64-darwin/bin/prophet +0 -0
- data/vendor/x86_64-darwin/lib/libtbb.dylib +0 -0
- data/vendor/{prophet-mac → x86_64-darwin}/lib/libtbbmalloc.dylib +0 -0
- data/vendor/{prophet-mac → x86_64-darwin}/lib/libtbbmalloc_proxy.dylib +0 -0
- data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/boost-license.txt +0 -0
- data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/cli11-license.txt +0 -0
- data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/cmdstan-license.txt +0 -0
- data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/eigen-bsd-license.txt +0 -0
- data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/eigen-mpl2-license.txt +0 -0
- data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/prophet-license.txt +0 -0
- data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/rapidjson-license.txt +0 -0
- data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/stan-license.txt +0 -0
- data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/stan-math-license.txt +0 -0
- data/vendor/x86_64-darwin/licenses/sundials-license.txt +29 -0
- data/vendor/x86_64-darwin/licenses/sundials-notice.txt +21 -0
- data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/tbb-license.txt +0 -0
- data/vendor/{prophet-mac-arm → x86_64-darwin}/licenses/tbb-third-party-programs.txt +0 -0
- data/vendor/x86_64-linux/bin/prophet +0 -0
- data/vendor/{prophet-linux → x86_64-linux}/lib/libtbb.so +0 -0
- data/vendor/x86_64-linux/lib/libtbb.so.2 +0 -0
- data/vendor/{prophet-linux → x86_64-linux}/lib/libtbbmalloc.so +0 -0
- data/vendor/x86_64-linux/lib/libtbbmalloc.so.2 +0 -0
- data/vendor/{prophet-linux → x86_64-linux}/lib/libtbbmalloc_proxy.so +0 -0
- data/vendor/{prophet-linux → x86_64-linux}/lib/libtbbmalloc_proxy.so.2 +0 -0
- data/vendor/{prophet-mac → x86_64-linux}/licenses/boost-license.txt +0 -0
- data/vendor/{prophet-mac → x86_64-linux}/licenses/cli11-license.txt +0 -0
- data/vendor/{prophet-mac → x86_64-linux}/licenses/cmdstan-license.txt +0 -0
- data/vendor/{prophet-mac → x86_64-linux}/licenses/eigen-bsd-license.txt +0 -0
- data/vendor/{prophet-mac → x86_64-linux}/licenses/eigen-mpl2-license.txt +0 -0
- data/vendor/{prophet-mac → x86_64-linux}/licenses/prophet-license.txt +0 -0
- data/vendor/{prophet-mac → x86_64-linux}/licenses/rapidjson-license.txt +0 -0
- data/vendor/{prophet-mac → x86_64-linux}/licenses/stan-license.txt +0 -0
- data/vendor/{prophet-mac → x86_64-linux}/licenses/stan-math-license.txt +0 -0
- data/vendor/x86_64-linux/licenses/sundials-license.txt +29 -0
- data/vendor/x86_64-linux/licenses/sundials-notice.txt +21 -0
- data/vendor/{prophet-mac → x86_64-linux}/licenses/tbb-license.txt +0 -0
- data/vendor/{prophet-mac → x86_64-linux}/licenses/tbb-third-party-programs.txt +0 -0
- metadata +79 -74
- data/stan/win/prophet.stan +0 -175
- data/vendor/prophet-linux/bin/prophet +0 -0
- data/vendor/prophet-linux/lib/libtbb.so.2 +0 -0
- data/vendor/prophet-linux/lib/libtbbmalloc.so.2 +0 -0
- data/vendor/prophet-linux/licenses/sundials-license.txt +0 -67
- data/vendor/prophet-linux-arm/bin/prophet +0 -0
- data/vendor/prophet-linux-arm/licenses/sundials-license.txt +0 -67
- data/vendor/prophet-mac/bin/prophet +0 -0
- data/vendor/prophet-mac/lib/libtbb.dylib +0 -0
- data/vendor/prophet-mac/licenses/sundials-license.txt +0 -67
- data/vendor/prophet-mac-arm/bin/prophet +0 -0
- data/vendor/prophet-mac-arm/lib/libtbb.dylib +0 -0
- data/vendor/prophet-mac-arm/licenses/sundials-license.txt +0 -67
data/lib/prophet/forecaster.rb
CHANGED
@@ -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
|
data/lib/prophet/holidays.rb
CHANGED
@@ -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
|
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
|
-
|
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
|
data/lib/prophet/stan_backend.rb
CHANGED
@@ -6,7 +6,7 @@ module Prophet
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def load_model
|
9
|
-
model_file = File.expand_path("../../vendor
|
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
|
-
"
|
142
|
+
"arm64-darwin"
|
143
143
|
else
|
144
|
-
"
|
144
|
+
"x86_64-darwin"
|
145
145
|
end
|
146
146
|
else
|
147
147
|
if RbConfig::CONFIG["host_cpu"] =~ /arm|aarch64/i
|
148
|
-
"linux
|
148
|
+
"aarch64-linux"
|
149
149
|
else
|
150
|
-
"linux"
|
150
|
+
"x86_64-linux"
|
151
151
|
end
|
152
152
|
end
|
153
153
|
end
|
data/lib/prophet/version.rb
CHANGED
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 =
|
67
|
-
m.
|
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
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
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
|
-
|
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 ~
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
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
|
File without changes
|
Binary file
|
File without changes
|
Binary file
|
File without changes
|
Binary file
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -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.
|
File without changes
|
File without changes
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -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.
|
File without changes
|
File without changes
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -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.
|