42
42
TORCH_AVAILABLE = False
43
43
44
44
45
+ def get_dummy_series (
46
+ ts_length : int , lt_end_value : int = 10 , st_value_offset : int = 10
47
+ ) -> TimeSeries :
48
+ return (
49
+ lt (length = ts_length , end_value = lt_end_value )
50
+ + st (length = ts_length , value_y_offset = st_value_offset )
51
+ + rt (length = ts_length )
52
+ )
53
+
54
+
45
55
def compare_best_against_random (model_class , params , series , stride = 1 ):
46
56
47
57
# instantiate best model in expanding window mode
48
58
np .random .seed (1 )
49
- best_model_1 , _ = model_class .gridsearch (
59
+ best_model_1 , _ , _ = model_class .gridsearch (
50
60
params ,
51
61
series ,
52
62
forecast_horizon = 10 ,
@@ -57,7 +67,9 @@ def compare_best_against_random(model_class, params, series, stride=1):
57
67
58
68
# instantiate best model in split mode
59
69
train , val = series .split_before (series .time_index [- 10 ])
60
- best_model_2 , _ = model_class .gridsearch (params , train , val_series = val , metric = mape )
70
+ best_model_2 , _ , _ = model_class .gridsearch (
71
+ params , train , val_series = val , metric = mape
72
+ )
61
73
62
74
# intantiate model with random parameters from 'params'
63
75
random .seed (1 )
@@ -297,12 +309,7 @@ def test_backtest_regression(self):
297
309
def test_gridsearch (self ):
298
310
np .random .seed (1 )
299
311
300
- ts_length = 50
301
- dummy_series = (
302
- lt (length = ts_length , end_value = 10 )
303
- + st (length = ts_length , value_y_offset = 10 )
304
- + rt (length = ts_length )
305
- )
312
+ dummy_series = get_dummy_series (ts_length = 50 )
306
313
dummy_series_int_index = TimeSeries .from_values (dummy_series .values ())
307
314
308
315
theta_params = {"theta" : list (range (3 , 10 ))}
@@ -322,16 +329,34 @@ def test_gridsearch(self):
322
329
compare_best_against_random (ExponentialSmoothing , es_params , dummy_series )
323
330
)
324
331
332
+ def test_gridsearch_metric_score (self ):
333
+ np .random .seed (1 )
334
+
335
+ model_class = Theta
336
+ params = {"theta" : list (range (3 , 6 ))}
337
+ dummy_series = get_dummy_series (ts_length = 50 )
338
+
339
+ best_model , _ , score = model_class .gridsearch (
340
+ params ,
341
+ series = dummy_series ,
342
+ forecast_horizon = 10 ,
343
+ stride = 1 ,
344
+ start = dummy_series .time_index [- 21 ],
345
+ )
346
+ recalculated_score = best_model .backtest (
347
+ series = dummy_series ,
348
+ start = dummy_series .time_index [- 21 ],
349
+ forecast_horizon = 10 ,
350
+ stride = 1 ,
351
+ )
352
+
353
+ self .assertEqual (score , recalculated_score , "The metric scores should match" )
354
+
325
355
@unittest .skipUnless (TORCH_AVAILABLE , "requires torch" )
326
356
def test_gridsearch_random_search (self ):
327
357
np .random .seed (1 )
328
358
329
- ts_length = 50
330
- dummy_series = (
331
- lt (length = ts_length , end_value = 10 )
332
- + st (length = ts_length , value_y_offset = 10 )
333
- + rt (length = ts_length )
334
- )
359
+ dummy_series = get_dummy_series (ts_length = 50 )
335
360
336
361
param_range = list (range (10 , 20 ))
337
362
params = {"lags" : param_range }
@@ -343,16 +368,12 @@ def test_gridsearch_random_search(self):
343
368
344
369
self .assertEqual (type (result [0 ]), RandomForest )
345
370
self .assertEqual (type (result [1 ]["lags" ]), int )
371
+ self .assertEqual (type (result [2 ]), float )
346
372
self .assertTrue (min (param_range ) <= result [1 ]["lags" ] <= max (param_range ))
347
373
348
374
@unittest .skipUnless (TORCH_AVAILABLE , "requires torch" )
349
375
def test_gridsearch_n_random_samples_bad_arguments (self ):
350
- ts_length = 50
351
- dummy_series = (
352
- lt (length = ts_length , end_value = 10 )
353
- + st (length = ts_length , value_y_offset = 10 )
354
- + rt (length = ts_length )
355
- )
376
+ dummy_series = get_dummy_series (ts_length = 50 )
356
377
357
378
params = {"lags" : list (range (1 , 11 )), "past_covariates" : list (range (1 , 11 ))}
358
379
@@ -398,16 +419,11 @@ def test_gridsearch_n_jobs(self):
398
419
"""
399
420
400
421
np .random .seed (1 )
401
- ts_length = 100
402
422
403
- dummy_series = (
404
- lt (length = ts_length , end_value = 1 )
405
- + st (length = ts_length , value_y_offset = 0 )
406
- + rt (length = ts_length )
423
+ dummy_series = get_dummy_series (
424
+ ts_length = 100 , lt_end_value = 1 , st_value_offset = 0
407
425
).astype (np .float32 )
408
-
409
- ts_train = dummy_series [: round (ts_length * 0.8 )]
410
- ts_val = dummy_series [round (ts_length * 0.8 ) :]
426
+ ts_train , ts_val = dummy_series .split_before (split_point = 0.8 )
411
427
412
428
test_cases = [
413
429
{
@@ -433,12 +449,12 @@ def test_gridsearch_n_jobs(self):
433
449
parameters = test ["parameters" ]
434
450
435
451
np .random .seed (1 )
436
- _ , best_params1 = model .gridsearch (
452
+ _ , best_params1 , _ = model .gridsearch (
437
453
parameters = parameters , series = ts_train , val_series = ts_val , n_jobs = 1
438
454
)
439
455
440
456
np .random .seed (1 )
441
- _ , best_params2 = model .gridsearch (
457
+ _ , best_params2 , _ = model .gridsearch (
442
458
parameters = parameters , series = ts_train , val_series = ts_val , n_jobs = - 1
443
459
)
444
460
0 commit comments