Skip to content

Commit 3b3d0b0

Browse files
committed
0.6.10
1 parent 6e726be commit 3b3d0b0

35 files changed

+155
-85
lines changed

TODO.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111
* Series will largely be consistent in period, or at least up-sampled to regular intervals
1212
* The most recent data will generally be the most important
1313
* Forecasts are desired for the future immediately following the most recent data.
14+
* trimmed_mean to AverageValueNaive
1415

15-
# 0.6.9 🇺🇦 🇺🇦 🇺🇦
16-
* expanded regressor options for MultivariateRegression, NeuralForecast (currently only available directly, not from AutoTS class)
17-
* matse bug fix on all 0 history
16+
# 0.6.10 🇺🇦 🇺🇦 🇺🇦
17+
* assorted minor bug fixes
18+
* bug in mosaic model selection fixed
19+
* added crosshair_lite mosaic
1820

1921
### Unstable Upstream Pacakges (those that are frequently broken by maintainers)
2022
* Pytorch-Forecasting

autots/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from autots.models.cassandra import Cassandra
2727

2828

29-
__version__ = '0.6.9'
29+
__version__ = '0.6.10'
3030

3131
TransformTS = GeneralTransformer
3232

autots/evaluator/auto_model.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1549,14 +1549,12 @@ def virtual_memory():
15491549
template_result.model_count += 1
15501550
if verbose > 0:
15511551
if validation_round >= 1:
1552-
base_print = (
1553-
"Model Number: {} of {} with model {} for Validation {}{}".format(
1554-
str(template_result.model_count),
1555-
template.shape[0],
1556-
model_str,
1557-
str(validation_round),
1558-
str(additional_msg),
1559-
)
1552+
base_print = "Model Number: {} of {} with model {} for Validation {}{}".format(
1553+
str(template_result.model_count),
1554+
template.shape[0],
1555+
model_str,
1556+
str(validation_round),
1557+
str(additional_msg),
15601558
)
15611559
else:
15621560
base_print = (

autots/evaluator/auto_ts.py

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -505,16 +505,26 @@ def get_new_params(method='random'):
505505
'smape_weighting': random.choices([0, 1, 5, 10], [0.3, 0.2, 0.3, 0.1])[
506506
0
507507
],
508-
'mae_weighting': random.choices([0, 1, 3, 5, 0.1], [0.1, 0.3, 0.3, 0.3, 0.1])[0],
509-
'rmse_weighting': random.choices([0, 1, 3, 5, 0.1], [0.1, 0.3, 0.3, 0.3, 0.1])[0],
508+
'mae_weighting': random.choices(
509+
[0, 1, 3, 5, 0.1], [0.1, 0.3, 0.3, 0.3, 0.1]
510+
)[0],
511+
'rmse_weighting': random.choices(
512+
[0, 1, 3, 5, 0.1], [0.1, 0.3, 0.3, 0.3, 0.1]
513+
)[0],
510514
'made_weighting': random.choices([0, 1, 3, 5], [0.7, 0.3, 0.1, 0.05])[
511515
0
512516
],
513-
'mage_weighting': random.choices([0, 1, 3, 5, 0.01], [0.8, 0.1, 0.1, 0.0, 0.2])[0],
517+
'mage_weighting': random.choices(
518+
[0, 1, 3, 5, 0.01], [0.8, 0.1, 0.1, 0.0, 0.2]
519+
)[0],
514520
'mle_weighting': random.choices([0, 1, 3, 5], [0.8, 0.1, 0.1, 0.0])[0],
515521
'imle_weighting': random.choices([0, 1, 3, 5], [0.8, 0.1, 0.1, 0.0])[0],
516-
'spl_weighting': random.choices([0, 1, 3, 5, 0.1], [0.1, 0.3, 0.3, 0.3, 0.1])[0],
517-
'oda_weighting': random.choices([0, 1, 3, 5, 0.1], [0.8, 0.1, 0.1, 0.0, 0.1])[0],
522+
'spl_weighting': random.choices(
523+
[0, 1, 3, 5, 0.1], [0.1, 0.3, 0.3, 0.3, 0.1]
524+
)[0],
525+
'oda_weighting': random.choices(
526+
[0, 1, 3, 5, 0.1], [0.8, 0.1, 0.1, 0.0, 0.1]
527+
)[0],
518528
'mqae_weighting': random.choices([0, 1, 3, 5], [0.4, 0.2, 0.1, 0.0])[0],
519529
'dwae_weighting': random.choices([0, 1, 3, 5], [0.8, 0.1, 0.1, 0.0])[0],
520530
'maxe_weighting': random.choices([0, 1, 3, 5], [0.8, 0.1, 0.1, 0.0])[0],
@@ -1544,7 +1554,9 @@ def validation_agg(self):
15441554
)
15451555
return self
15461556

1547-
def _return_best_model(self, metric_weighting=None, allow_horizontal=True, n=1, template_cols=None):
1557+
def _return_best_model(
1558+
self, metric_weighting=None, allow_horizontal=True, n=1, template_cols=None
1559+
):
15481560
"""Sets best model based on validation results.
15491561
15501562
Args:
@@ -1614,7 +1626,9 @@ def _set_best_model(self, metric_weighting=None, allow_horizontal=True, n=1):
16141626
self.parse_best_model()
16151627
return self
16161628

1617-
def _best_non_horizontal(self, metric_weighting=None, series=None, n=1, template_cols=None):
1629+
def _best_non_horizontal(
1630+
self, metric_weighting=None, series=None, n=1, template_cols=None
1631+
):
16181632
if self.validation_results is None:
16191633
if not self.initial_results.model_results.empty:
16201634
self = self.validation_agg()
@@ -2177,10 +2191,14 @@ def export_template(
21772191
extra_mods = []
21782192
if min_metrics is not None:
21792193
for metric in min_metrics:
2180-
extra_mods.append(export_template.nsmallest(1, columns=metric).copy())
2194+
extra_mods.append(
2195+
export_template.nsmallest(1, columns=metric).copy()
2196+
)
21812197
if max_metrics is not None:
21822198
for metric in max_metrics:
2183-
extra_mods.append(export_template.nlargest(1, columns=metric).copy())
2199+
extra_mods.append(
2200+
export_template.nlargest(1, columns=metric).copy()
2201+
)
21842202
if str(max_per_model_class).isdigit():
21852203
export_template = (
21862204
export_template.sort_values('Score', ascending=True)
@@ -2191,7 +2209,9 @@ def export_template(
21912209
export_template = export_template.nsmallest(n, columns=['Score'])
21922210
if extra_mods:
21932211
extra_mods = pd.concat(extra_mods)
2194-
export_template = pd.concat([export_template, extra_mods]).drop_duplicates()
2212+
export_template = pd.concat(
2213+
[export_template, extra_mods]
2214+
).drop_duplicates()
21952215
if self.best_model_id not in export_template['ID']:
21962216
export_template = pd.concat(
21972217
[
@@ -2469,12 +2489,22 @@ def _generate_mosaic_template(
24692489
)
24702490
runtime_weighting = self.metric_weighting.get("runtime_weighting", 0)
24712491
if runtime_weighting != 0:
2472-
local_results = initial_results.model_results.copy().groupby("ID")["TotalRuntimeSeconds"].mean()
2473-
runtimes = local_results.loc[initial_results.full_mae_ids].to_numpy()[:, np.newaxis, np.newaxis]
2492+
local_results = (
2493+
initial_results.model_results.copy()
2494+
.groupby("ID")["TotalRuntimeSeconds"]
2495+
.mean()
2496+
)
2497+
runtimes = local_results.loc[initial_results.full_mae_ids].to_numpy()[
2498+
:, np.newaxis, np.newaxis
2499+
]
24742500
# not fully confident in this scaler, trying to put runtime loosely in reference to mae scale
2475-
mae_min = initial_results.per_series_mae.loc[initial_results.model_results.set_index("ID")['mae'].idxmin()]
2501+
mae_min = initial_results.per_series_mae.loc[
2502+
initial_results.model_results.set_index("ID")['mae'].idxmin()
2503+
]
24762504
mae_min = np.min(mae_min[mae_min > 0])
2477-
basic_scaler = initial_results.model_results['TotalRuntimeSeconds'].mean() / mae_min
2505+
basic_scaler = (
2506+
initial_results.model_results['TotalRuntimeSeconds'].mean() / mae_min
2507+
)
24782508
# making runtime weighting even smaller because generally want this to be a very small component
24792509
weight_per_value + (runtimes / basic_scaler) * (runtime_weighting / 10)
24802510

@@ -2496,7 +2526,9 @@ def _generate_mosaic_template(
24962526
# process for crosshair
24972527
crs_hr = mosaic_config.get("crosshair")
24982528
if crs_hr:
2499-
full_mae_err = [generate_crosshair_score(x, method=crs_hr) for x in errs]
2529+
full_mae_err = [
2530+
generate_crosshair_score(x, method=crs_hr) for x in errs
2531+
]
25002532
else:
25012533
full_mae_err = errs
25022534
# refine to n_models if necessary

autots/models/ensemble.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,12 +1578,12 @@ def generate_crosshair_score(error_matrix, method=None):
15781578
arr_size = error_matrix.size
15791579
base_weight = 0.001 / arr_size
15801580
sum_error = np.sum(error_matrix) * base_weight
1581-
1581+
15821582
cross_base = error_matrix * (base_weight * 50)
15831583
row_sums = cross_base.sum(axis=1)
15841584
col_sums = cross_base.sum(axis=0)
15851585
outer_sum = np.add.outer(row_sums, col_sums)
1586-
1586+
15871587
return error_matrix + sum_error + outer_sum
15881588

15891589

autots/models/neural_forecast.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,13 @@ def __init__(
7272
self.df_train = None
7373
self.static_regressor = None
7474

75-
def fit(self, df, future_regressor=None, static_regressor=None, regressor_per_series=None):
75+
def fit(
76+
self,
77+
df,
78+
future_regressor=None,
79+
static_regressor=None,
80+
regressor_per_series=None,
81+
):
7682
"""Train algorithm given data supplied.
7783
7884
Args:
@@ -242,7 +248,9 @@ def fit(self, df, future_regressor=None, static_regressor=None, regressor_per_se
242248
local_copy = local_copy.reset_index()
243249
local_copy['unique_id'] = str(key)
244250
full_df.append(local_copy)
245-
silly_format = silly_format.merge(pd.concat(full_df), on=['unique_id', 'ds'], how='left').fillna(0)
251+
silly_format = silly_format.merge(
252+
pd.concat(full_df), on=['unique_id', 'ds'], how='left'
253+
).fillna(0)
246254
self.nf = NeuralForecast(models=models, freq=freq)
247255
if self.static_regressor is None:
248256
self.nf.fit(df=silly_format)
@@ -256,7 +264,11 @@ def fit(self, df, future_regressor=None, static_regressor=None, regressor_per_se
256264
return self
257265

258266
def predict(
259-
self, forecast_length=None, future_regressor=None, just_point_forecast=False, regressor_per_series=None
267+
self,
268+
forecast_length=None,
269+
future_regressor=None,
270+
just_point_forecast=False,
271+
regressor_per_series=None,
260272
):
261273
predictStartTime = datetime.datetime.now()
262274
if self.regression_type in ['User', 'user', True]:
@@ -279,7 +291,9 @@ def predict(
279291
local_copy = local_copy.reset_index()
280292
local_copy['unique_id'] = str(key)
281293
full_df.append(local_copy)
282-
futr_df = futr_df.merge(pd.concat(full_df), on=['unique_id', 'ds'], how='left').fillna(0)
294+
futr_df = futr_df.merge(
295+
pd.concat(full_df), on=['unique_id', 'ds'], how='left'
296+
).fillna(0)
283297
self.futr_df = futr_df
284298
long_forecast = self.nf.predict(futr_df=futr_df)
285299
else:
@@ -378,7 +392,9 @@ def get_new_params(self, method: str = 'random'):
378392
)[0]
379393
point_quantile = None
380394
if loss == "MQLoss":
381-
point_quantile = random.choices([None, 0.35, 0.45, 0.55, 0.65, 0.7], [0.5, 0.1, 0.1, 0.1, 0.1, 0.1])[0]
395+
point_quantile = random.choices(
396+
[None, 0.35, 0.45, 0.55, 0.65, 0.7], [0.5, 0.1, 0.1, 0.1, 0.1, 0.1]
397+
)[0]
382398
if models == "TFT":
383399
model_args = {
384400
"n_head": random.choice([2, 4]),

autots/models/sklearn.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,9 @@ def rolling_x_regressor_regressor(
254254
X = pd.concat([X, future_regressor], axis=1)
255255
if regressor_per_series is not None:
256256
# this is actually wrong, merging on an index value that is off by one
257-
X = X.merge(regressor_per_series, left_index=True, right_index=True, how='left').bfill()
257+
X = X.merge(
258+
regressor_per_series, left_index=True, right_index=True, how='left'
259+
).bfill()
258260
if static_regressor is not None:
259261
X['series_id'] = df.columns[0]
260262
X = X.merge(static_regressor, left_on="series_id", right_index=True, how='left')
@@ -1287,7 +1289,9 @@ def generate_regressor_params(
12871289
param_dict = {
12881290
'C': random.choices([1.0, 0.5, 2.0, 0.25], [0.6, 0.1, 0.1, 0.1])[0],
12891291
'tol': random.choices([1e-4, 1e-3, 1e-5], [0.6, 0.1, 0.1])[0],
1290-
"loss": random.choice(['epsilon_insensitive', 'squared_epsilon_insensitive']),
1292+
"loss": random.choice(
1293+
['epsilon_insensitive', 'squared_epsilon_insensitive']
1294+
),
12911295
"max_iter": random.choice([500, 1000]),
12921296
}
12931297
else:
@@ -3421,7 +3425,9 @@ def get_new_params(self, method: str = 'random'):
34213425
regression_choice = random.choices([None, 'User'], [0.7, 0.3])[0]
34223426
coint_lag = 1
34233427
if "deep" in method:
3424-
coint_choice = random.choices([None, "BTCD", "Johansen"], [0.8, 0.1, 0.1])[0]
3428+
coint_choice = random.choices([None, "BTCD", "Johansen"], [0.8, 0.1, 0.1])[
3429+
0
3430+
]
34253431
else:
34263432
coint_choice = None
34273433
if coint_choice is not None:

autots/tools/percentile.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,11 @@ def nan_quantile(arr, q, method="linear", axis=0, errors="raise"):
111111
"""
112112
return nan_percentile(arr, q * 100, method=method, axis=axis, errors=errors)
113113

114+
114115
def trimmed_mean(data, percent, axis=0):
115116
limit = int(np.ceil(percent * data.shape[axis]))
116117
sorted_data = np.sort(data, axis=axis)
117-
trimmed = sorted_data.take(indices=range(limit, data.shape[axis] - limit), axis=axis)
118+
trimmed = sorted_data.take(
119+
indices=range(limit, data.shape[axis] - limit), axis=axis
120+
)
118121
return np.mean(trimmed, axis=axis)
22.1 KB
Binary file not shown.
4.6 KB
Binary file not shown.

0 commit comments

Comments
 (0)