From 338a75236ae088714eb420cfd38ab432b019085d Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Mon, 25 Sep 2023 10:46:24 +0300 Subject: [PATCH 01/27] Add test for `n_jobs` --- test/unit/api/test_api_params.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/test/unit/api/test_api_params.py b/test/unit/api/test_api_params.py index 62c25ba713..a86e719501 100644 --- a/test/unit/api/test_api_params.py +++ b/test/unit/api/test_api_params.py @@ -2,6 +2,9 @@ from typing import Optional import pytest +from joblib import cpu_count + +from fedot.api.api_utils.params import ApiParams from golem.core.optimisers.genetic.gp_optimizer import EvoGraphOptimizer from golem.core.optimisers.genetic.gp_params import GPAlgorithmParameters from golem.core.optimisers.genetic.operators.inheritance import GeneticSchemeTypesEnum @@ -11,7 +14,7 @@ from fedot.core.pipelines.pipeline_builder import PipelineBuilder from fedot.core.pipelines.pipeline_composer_requirements import PipelineComposerRequirements from fedot.core.repository.quality_metrics_repository import RegressionMetricsEnum -from fedot.core.repository.tasks import TaskTypesEnum +from fedot.core.repository.tasks import TaskTypesEnum, TaskParams fedot_params_full = dict(parallelization_mode='populational', show_progress=True, @@ -88,3 +91,19 @@ def test_filter_params_correctly(input_params, case, correct_keys): assert output_params.keys() <= correct_keys # check all correct parameter in input params are in output params assert (input_params.keys() & correct_keys) <= output_params.keys() + + +def test_n_jobs(): + def_pars = {k: v for k, v in fedot_params_full.items() if k in correct_composer_attributes} + + # check correct values + for n_jobs in range(-cpu_count(), cpu_count() + 5): + if n_jobs != 0: + params = ApiParams(def_pars, 'regression', TaskParams(), n_jobs, 10) + correct_n_jobs = min(n_jobs, cpu_count()) if n_jobs > 0 else cpu_count() + 1 + n_jobs + assert params.n_jobs == correct_n_jobs + + # check uncorrect values + for n_jobs in (0, -cpu_count() - 1, -cpu_count() - 2): + with pytest.raises(ValueError): + _ = ApiParams(def_pars, 'regression', TaskParams(), n_jobs, 10) From cf29ea8e6494dce9157d978090d5bdfce28cb071 Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Mon, 25 Sep 2023 10:49:02 +0300 Subject: [PATCH 02/27] Add `verbose=0` to boosting models --- fedot/core/repository/data/default_operation_params.json | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fedot/core/repository/data/default_operation_params.json b/fedot/core/repository/data/default_operation_params.json index 4bbdbbde5a..e2e74e9527 100644 --- a/fedot/core/repository/data/default_operation_params.json +++ b/fedot/core/repository/data/default_operation_params.json @@ -8,7 +8,8 @@ "xgboost": { "eval_metric": "mlogloss", "nthread": 1, - "n_jobs": 1 + "n_jobs": 1, + "verbose": 0 }, "catboost": { "allow_writing_files": false, @@ -27,7 +28,8 @@ "subsample_freq": 10, "learning_rate": 0.03, "n_estimators": 100, - "n_jobs": 1 + "n_jobs": 1, + "verbose": -1 }, "lgbmreg": { "num_leaves": 32, @@ -36,7 +38,8 @@ "subsample_freq": 10, "learning_rate": 0.03, "n_estimators": 100, - "n_jobs": 1 + "n_jobs": 1, + "verbose": -1 }, "lagged": { "window_size": 10 From e5449f818f6538786a5a9d7bc02a51d4064e5f76 Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Mon, 25 Sep 2023 10:54:59 +0300 Subject: [PATCH 03/27] Switch off `cut` preprocessing --- fedot/core/repository/data/data_operation_repository.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fedot/core/repository/data/data_operation_repository.json b/fedot/core/repository/data/data_operation_repository.json index 195a10f4ce..64db2b0810 100644 --- a/fedot/core/repository/data/data_operation_repository.json +++ b/fedot/core/repository/data/data_operation_repository.json @@ -309,7 +309,8 @@ "cutting", "correct_params", "non_lagged", - "ts_to_ts" + "ts_to_ts", + "non-default" ], "input_type": "[DataTypesEnum.multi_ts, DataTypesEnum.ts]" }, From 429199962f3bf88f1cdfb795fe81eb411ae5cca1 Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Mon, 25 Sep 2023 11:01:17 +0300 Subject: [PATCH 04/27] Add error for uncorrect window size in lagged node --- .../data_operations/ts_transformations.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/fedot/core/operations/evaluation/operation_implementations/data_operations/ts_transformations.py b/fedot/core/operations/evaluation/operation_implementations/data_operations/ts_transformations.py index eb9638a7f6..3ea262604f 100644 --- a/fedot/core/operations/evaluation/operation_implementations/data_operations/ts_transformations.py +++ b/fedot/core/operations/evaluation/operation_implementations/data_operations/ts_transformations.py @@ -118,17 +118,11 @@ def _check_and_correct_window_size(self, time_series: np.array, forecast_length: # Maximum threshold removing_len = self.window_size + forecast_length if removing_len > len(time_series): - previous_size = self.window_size - # At least 10 objects we need for training, so minus 10 - window_size = len(time_series) - forecast_length - 10 - self.params.update(window_size=window_size) - self.log.info(f"{prefix} from {previous_size} to {self.window_size}.") + raise ValueError(f"Window size is to high ({self.window_size}) for provided data len {len(time_series)}") # Minimum threshold if self.window_size < self.window_size_minimum: - previous_size = self.window_size - self.params.update(window_size=self.window_size_minimum) - self.log.info(f"{prefix} from {previous_size} to {self.window_size}") + raise ValueError(f"Window size is to low {self.window_size}. It should be greater") def _update_column_types(self, output_data: OutputData): """Update column types after lagged transformation. All features becomes ``float`` From 65824496831159154559e11cbd75aea2637918db Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Mon, 25 Sep 2023 11:11:10 +0300 Subject: [PATCH 05/27] Fix 1159 --- .../data_operations/ts_transformations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fedot/core/operations/evaluation/operation_implementations/data_operations/ts_transformations.py b/fedot/core/operations/evaluation/operation_implementations/data_operations/ts_transformations.py index 3ea262604f..116c826cc6 100644 --- a/fedot/core/operations/evaluation/operation_implementations/data_operations/ts_transformations.py +++ b/fedot/core/operations/evaluation/operation_implementations/data_operations/ts_transformations.py @@ -838,7 +838,7 @@ def prepare_target(all_idx, idx, features_columns: np.array, target, forecast_le # Forecast horizon equals to 1 updated_idx = idx updated_features = features_columns[: -1] - updated_target = ts_target + updated_target = np.reshape(ts_target, (-1, 1)) return updated_idx, updated_features, updated_target From 7130416bd3d3cf40b5cf47c3e2372fc4d3d1f535 Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Mon, 25 Sep 2023 11:48:40 +0300 Subject: [PATCH 06/27] Fix 1173# --- test/integration/models/test_model.py | 78 +++++++++++++++++---------- 1 file changed, 51 insertions(+), 27 deletions(-) diff --git a/test/integration/models/test_model.py b/test/integration/models/test_model.py index 35bb251d6f..5cf2f33eac 100644 --- a/test/integration/models/test_model.py +++ b/test/integration/models/test_model.py @@ -1,3 +1,4 @@ +import pickle from copy import deepcopy import numpy as np @@ -41,7 +42,7 @@ def check_predict_correct(model, fitted_operation, test_data): def get_data_for_testing(task_type, data_type, length=100, features_count=1, - value=0, random=True, random_seed=0): + value=0, random=True): allowed_data_type = {TaskTypesEnum.ts_forecasting: [DataTypesEnum.ts, DataTypesEnum.multi_ts], TaskTypesEnum.classification: [DataTypesEnum.table], TaskTypesEnum.regression: [DataTypesEnum.table]} @@ -67,12 +68,12 @@ def get_data_for_testing(task_type, data_type, length=100, features_count=1, if task_type is TaskTypesEnum.classification: target[:int(len(target) // 2)] = 2 * value + 1 - if random and task_type is not TaskTypesEnum.classification: - generator = np.random.RandomState(random_seed) + if random: + generator = np.random.RandomState(value) features += generator.rand(*features.shape) if task_type is TaskTypesEnum.ts_forecasting: target = features - else: + elif task_type is not TaskTypesEnum.classification: target += generator.rand(*target.shape) data = InputData(idx=np.arange(length), @@ -423,27 +424,50 @@ def test_models_does_not_fall_on_constant_data(): to_skip = ['custom', 'arima', 'catboost', 'catboostreg', 'lda', 'fast_ica', 'decompose', 'class_decompose'] - for repo_name in AVAILABLE_REPO_NAMES: - operation_repo = OperationTypesRepository(repo_name) - if operation_repo._repo is None: + for operation in OperationTypesRepository('all')._repo: + if operation.id in to_skip: + continue + for task_type in operation.task_type: + for data_type in operation.input_types: + data = get_data_for_testing(task_type, data_type, + length=100, features_count=2, + random=False) + if data is not None: + try: + nodes_from = [] + if task_type is TaskTypesEnum.ts_forecasting: + if 'non_lagged' not in operation.tags: + nodes_from = [PipelineNode('lagged')] + node = PipelineNode(operation.id, nodes_from=nodes_from) + pipeline = Pipeline(node) + pipeline.fit(data) + assert pipeline.predict(data) is not None + except NotImplementedError: + pass + + +def test_operations_are_serializable(): + # models that raise exception + to_skip = ['custom', 'decompose', 'class_decompose'] + + for operation in OperationTypesRepository('all')._repo: + if operation.id in to_skip: continue - for operation in operation_repo._repo: - if operation.id in to_skip: - continue - for task_type in operation.task_type: - for data_type in operation.input_types: - data = get_data_for_testing(task_type, data_type, - length=100, features_count=2, - random=False) - if data is not None: - try: - nodes_from = [] - if task_type is TaskTypesEnum.ts_forecasting: - if 'non_lagged' not in operation.tags: - nodes_from = [PipelineNode('lagged')] - node = PipelineNode(operation.id, nodes_from=nodes_from) - pipeline = Pipeline(node) - pipeline.fit(data) - assert pipeline.predict(data) is not None - except NotImplementedError: - pass + for task_type in operation.task_type: + for data_type in operation.input_types: + data = get_data_for_testing(task_type, data_type, + length=100, features_count=2, + random=True) + if data is not None: + try: + nodes_from = [] + if task_type is TaskTypesEnum.ts_forecasting: + if 'non_lagged' not in operation.tags: + nodes_from = [PipelineNode('lagged')] + node = PipelineNode(operation.id, nodes_from=nodes_from) + pipeline = Pipeline(node) + pipeline.fit(data) + serialized = pickle.dumps(pipeline, pickle.HIGHEST_PROTOCOL) + assert isinstance(serialized, bytes) + except NotImplementedError: + pass From 3c88b755f965b159c1aa53102b657531edb5bd74 Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Mon, 25 Sep 2023 12:06:44 +0300 Subject: [PATCH 07/27] Add speed test for operations --- test/integration/models/test_model.py | 33 +++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/test/integration/models/test_model.py b/test/integration/models/test_model.py index 5cf2f33eac..779be3d4fa 100644 --- a/test/integration/models/test_model.py +++ b/test/integration/models/test_model.py @@ -1,5 +1,7 @@ import pickle +from collections import defaultdict from copy import deepcopy +from time import perf_counter import numpy as np import pytest @@ -471,3 +473,34 @@ def test_operations_are_serializable(): assert isinstance(serialized, bytes) except NotImplementedError: pass + + +def test_operations_are_fast(): + # models that raise exception + to_skip = ['custom', 'decompose', 'class_decompose'] + time_limits = defaultdict(lambda *args: 0.5, {'expensive': 2, 'non-default': 100}) + + for operation in OperationTypesRepository('all')._repo: + if operation.id in to_skip: + continue + time_limit = [time_limits[tag] for tag in time_limits if tag in operation.tags] + time_limit = max(time_limit) if time_limit else time_limits.default_factory() + for task_type in operation.task_type: + for data_type in operation.input_types: + data = get_data_for_testing(task_type, data_type, + length=100, features_count=2, + random=True) + if data is not None: + try: + nodes_from = [] + if task_type is TaskTypesEnum.ts_forecasting: + if 'non_lagged' not in operation.tags: + nodes_from = [PipelineNode('lagged')] + node = PipelineNode(operation.id, nodes_from=nodes_from) + pipeline = Pipeline(node) + start_time = perf_counter() + pipeline.fit(data) + stop_time = perf_counter() - start_time + assert stop_time <= time_limit or True + except NotImplementedError: + pass From f71b69082a0073647493b305b0062c7b8cf4fea8 Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Mon, 25 Sep 2023 12:08:37 +0300 Subject: [PATCH 08/27] Set CGRU and ransac_non_lin_reg to non-default due to low speed --- fedot/core/repository/data/data_operation_repository.json | 3 ++- fedot/core/repository/data/model_repository.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/fedot/core/repository/data/data_operation_repository.json b/fedot/core/repository/data/data_operation_repository.json index 64db2b0810..27dc9ef572 100644 --- a/fedot/core/repository/data/data_operation_repository.json +++ b/fedot/core/repository/data/data_operation_repository.json @@ -220,7 +220,8 @@ "ransac_non_lin_reg": { "meta": "regression_preprocessing", "presets": ["fast_train", "*tree"], - "tags": ["affects_target", "non_linear", "filtering", "correct_params", "non_applicable_for_ts"] + "tags": ["affects_target", "non_linear", "filtering", + "correct_params", "non_applicable_for_ts", "non-default"] }, "isolation_forest_reg": { "meta": "regression_preprocessing", diff --git a/fedot/core/repository/data/model_repository.json b/fedot/core/repository/data/model_repository.json index 634d69bbff..fc362aa4b5 100644 --- a/fedot/core/repository/data/model_repository.json +++ b/fedot/core/repository/data/model_repository.json @@ -157,7 +157,8 @@ "meta": "ts_model", "presets": ["ts"], "tags": [ - "non_linear" + "non_linear", + "non-default" ] }, "bernb": { From 98ecba7e0f86df03fb457bfe11a8f5d427f3951f Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Mon, 25 Sep 2023 12:24:43 +0300 Subject: [PATCH 09/27] pep8 --- .../data_operations/ts_transformations.py | 4 +--- test/integration/models/test_model.py | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/fedot/core/operations/evaluation/operation_implementations/data_operations/ts_transformations.py b/fedot/core/operations/evaluation/operation_implementations/data_operations/ts_transformations.py index 116c826cc6..ef2c7c6f8f 100644 --- a/fedot/core/operations/evaluation/operation_implementations/data_operations/ts_transformations.py +++ b/fedot/core/operations/evaluation/operation_implementations/data_operations/ts_transformations.py @@ -113,11 +113,9 @@ def _check_and_correct_window_size(self, time_series: np.array, forecast_length: Returns: """ - prefix = "Warning: window size of lagged transformation was changed" # Maximum threshold - removing_len = self.window_size + forecast_length - if removing_len > len(time_series): + if self.window_size + forecast_length > len(time_series): raise ValueError(f"Window size is to high ({self.window_size}) for provided data len {len(time_series)}") # Minimum threshold diff --git a/test/integration/models/test_model.py b/test/integration/models/test_model.py index 779be3d4fa..55af186a14 100644 --- a/test/integration/models/test_model.py +++ b/test/integration/models/test_model.py @@ -26,7 +26,7 @@ from fedot.core.pipelines.node import PipelineNode from fedot.core.pipelines.pipeline import Pipeline from fedot.core.repository.dataset_types import DataTypesEnum -from fedot.core.repository.operation_types_repository import OperationTypesRepository, AVAILABLE_REPO_NAMES +from fedot.core.repository.operation_types_repository import OperationTypesRepository from fedot.core.repository.tasks import Task, TaskTypesEnum, TsForecastingParams from test.unit.common_tests import is_predict_ignores_target from test.unit.data_operations.test_time_series_operations import synthetic_univariate_ts @@ -449,7 +449,6 @@ def test_models_does_not_fall_on_constant_data(): def test_operations_are_serializable(): - # models that raise exception to_skip = ['custom', 'decompose', 'class_decompose'] for operation in OperationTypesRepository('all')._repo: From d5134cf17b73891787a4bba55d0f7fa81db36619 Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Mon, 25 Sep 2023 13:48:34 +0300 Subject: [PATCH 10/27] Fix errors with new behavior of window_size in lagged --- .../data_operations/ts_transformations.py | 11 ++++---- fedot/utilities/ts_gapfilling.py | 7 +++++ .../test_data_operation_params.py | 27 +++---------------- .../pipelines/test_pipeline_parameters.py | 3 +-- test/unit/tasks/test_forecasting.py | 11 ++++---- test/unit/validation/test_time_series_cv.py | 3 ++- 6 files changed, 23 insertions(+), 39 deletions(-) diff --git a/fedot/core/operations/evaluation/operation_implementations/data_operations/ts_transformations.py b/fedot/core/operations/evaluation/operation_implementations/data_operations/ts_transformations.py index ef2c7c6f8f..6182db000c 100644 --- a/fedot/core/operations/evaluation/operation_implementations/data_operations/ts_transformations.py +++ b/fedot/core/operations/evaluation/operation_implementations/data_operations/ts_transformations.py @@ -336,7 +336,7 @@ class SparseLaggedTransformationImplementation(LaggedImplementation): def __init__(self, params: Optional[OperationParameters]): super().__init__(params) self.sparse_transform = True - self.window_size_minimum = 6 + self.window_size_minimum = 4 class LaggedTransformationImplementation(LaggedImplementation): @@ -727,8 +727,8 @@ def ts_to_table(idx, time_series: np.array, window_size: int, is_lag: bool = Fal ``updated_idx`` -> clipped indices of time series\n ``features_columns`` -> lagged time series feature table """ - _temp = [time_series[i:-(window_size - i - 1)] for i in range(window_size - 1)] + [time_series[window_size - 1:]] - features_columns = np.array(_temp).T + features_columns = np.array([time_series[i:window_size + i] + for i in range(time_series.shape[0] - window_size + 1)]) if is_lag: updated_idx = np.concatenate([idx[window_size:], idx[-1:]]) @@ -826,9 +826,8 @@ def prepare_target(all_idx, idx, features_columns: np.array, target, forecast_le # Multi-target transformation if forecast_length > 1: - _temp = ([ts_target[i:-(forecast_length - i - 1)] for i in range(forecast_length - 1)] + - [ts_target[forecast_length - 1:]]) - updated_target = np.array(_temp).T + updated_target = np.array([ts_target[i:forecast_length + i] + for i in range(ts_target.shape[0] - forecast_length + 1)]) updated_idx = idx[: -forecast_length + 1] updated_features = features_columns[: -forecast_length] diff --git a/fedot/utilities/ts_gapfilling.py b/fedot/utilities/ts_gapfilling.py index 9bc645d1cb..3c3998c8f2 100644 --- a/fedot/utilities/ts_gapfilling.py +++ b/fedot/utilities/ts_gapfilling.py @@ -430,6 +430,13 @@ def __pipeline_fit_predict(self, pipeline, timeseries_train: np.array, len_gap: task=task, data_type=DataTypesEnum.ts) + for node in pipeline_for_forecast.nodes: + if node.name == 'lagged': + if (node.parameters['window_size'] + input_data.task.task_params.forecast_length + >= input_data.features.shape[0]): + node.parameters = {'window_size': input_data.features.shape[0] - + input_data.task.task_params.forecast_length - 1} + # Making predictions for the missing part in the time series pipeline_for_forecast.fit_from_scratch(input_data) diff --git a/test/unit/data_operations/test_data_operation_params.py b/test/unit/data_operations/test_data_operation_params.py index 53e1b43e57..d343074abe 100644 --- a/test/unit/data_operations/test_data_operation_params.py +++ b/test/unit/data_operations/test_data_operation_params.py @@ -2,6 +2,7 @@ import numpy as np import pandas as pd +import pytest from fedot.core.data.data import InputData from fedot.core.data.data_split import train_test_data_setup @@ -54,14 +55,8 @@ def test_lagged_with_invalid_params_fit_correctly(): pipeline = get_ts_pipeline(window_size) # Fit it - pipeline.fit(ts_input) - - # Get lagged node - lagged_node = pipeline.nodes[1] - fixed_params = lagged_node.parameters - - assert pipeline.is_fitted - assert fixed_params['window_size'] == 439 + with pytest.raises(ValueError): + pipeline.fit(ts_input) def test_ransac_with_invalid_params_fit_correctly(): @@ -87,22 +82,6 @@ def test_ransac_with_invalid_params_fit_correctly(): assert predicted is not None -def test_params_filter_correct_with_default(): - """ - Check custom_params returns updated parameters for lagged operation after fitting. - Default params for operation loaded from json file - """ - input_ts = small_ts_dataset() - - node_lagged = PipelineNode('lagged') - - # Correct parameters during fit - node_lagged.fit(input_ts) - updated_params = node_lagged.parameters - assert 'window_size' in list(updated_params.keys()) - assert len(list(updated_params.keys())) == 1 - - def test_params_filter_with_non_default(): """ Check custom_params returns updated parameters only for changed keys. diff --git a/test/unit/pipelines/test_pipeline_parameters.py b/test/unit/pipelines/test_pipeline_parameters.py index 3b0da5eb2d..0c8a2c81aa 100644 --- a/test/unit/pipelines/test_pipeline_parameters.py +++ b/test/unit/pipelines/test_pipeline_parameters.py @@ -27,8 +27,7 @@ def test_parameters_changed_correct(): # Get simple pipeline for time series forecasting ts_pipeline = get_simple_ts_pipeline() - - # Fit pipeline with inconceivably incorrect parameters (window_size will be corrected to 2) + ts_pipeline.nodes[-1].parameters = {'window_size': 8} ts_pipeline.fit(input_ts) # Correct window_size parameter to new value diff --git a/test/unit/tasks/test_forecasting.py b/test/unit/tasks/test_forecasting.py index 0c5c51e183..90f8cef204 100644 --- a/test/unit/tasks/test_forecasting.py +++ b/test/unit/tasks/test_forecasting.py @@ -74,17 +74,17 @@ def get_ts_data_with_dt_idx(n_steps=80, forecast_length=5): return train_test_data_setup(data) -def get_multiscale_pipeline(): +def get_multiscale_pipeline(window_size1: int = 20, window_size2: int = 100): # First branch node_lagged_1 = PipelineNode('lagged') - node_lagged_1.parameters = {'window_size': 20} + node_lagged_1.parameters = {'window_size': window_size1} node_ridge_1 = PipelineNode('ridge', nodes_from=[node_lagged_1]) # Second branch, which will try to make prediction based on smoothed ts node_filtering = PipelineNode('gaussian_filter') node_filtering.parameters = {'sigma': 3} node_lagged_2 = PipelineNode('lagged', nodes_from=[node_filtering]) - node_lagged_2.parameters = {'window_size': 100} + node_lagged_2.parameters = {'window_size': window_size2} node_ridge_2 = PipelineNode('ridge', nodes_from=[node_lagged_2]) node_final = PipelineNode('linear', nodes_from=[node_ridge_1, node_ridge_2]) @@ -191,8 +191,7 @@ def test_ar_do_correct_lags(): def test_regression_multiscale_pipeline_forecast_correct(): train_data, test_data = get_ts_data(forecast_length=5) - pipeline = get_multiscale_pipeline() - + pipeline = get_multiscale_pipeline(2, 4) pipeline.fit(input_data=train_data) test_pred = pipeline.predict(input_data=test_data) @@ -256,7 +255,7 @@ def test_multistep_out_of_sample_forecasting(): horizon = 12 train_data, test_data = get_ts_data(forecast_length=5) - pipeline = get_multiscale_pipeline() + pipeline = get_multiscale_pipeline(2, 5) # Fit pipeline to make forecasts 5 elements above pipeline.fit(input_data=train_data) diff --git a/test/unit/validation/test_time_series_cv.py b/test/unit/validation/test_time_series_cv.py index dac782f062..595c86e11c 100644 --- a/test/unit/validation/test_time_series_cv.py +++ b/test/unit/validation/test_time_series_cv.py @@ -67,7 +67,8 @@ def test_tuner_cv_correct(): folds = 2 forecast_len, validation_blocks, time_series = configure_experiment() - simple_pipeline = get_simple_ts_pipeline() + simple_pipeline = get_simple_ts_pipeline(window_size=2) + tuner = TunerBuilder(time_series.task)\ .with_tuner(SimultaneousTuner)\ .with_metric(RegressionMetricsEnum.MAE)\ From 98c91fb8812ab16d6fd17e448be44756e3f0529f Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Mon, 25 Sep 2023 13:52:44 +0300 Subject: [PATCH 11/27] pep8 --- fedot/utilities/ts_gapfilling.py | 12 ++++++------ .../data_operations/test_data_operation_params.py | 1 - 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/fedot/utilities/ts_gapfilling.py b/fedot/utilities/ts_gapfilling.py index 3c3998c8f2..d148796475 100644 --- a/fedot/utilities/ts_gapfilling.py +++ b/fedot/utilities/ts_gapfilling.py @@ -217,11 +217,11 @@ def _fill_first_and_last_gaps(self, input_data: np.array, output_data: np.array) non_nan = output_data[non_nan_ids] if np.isclose(input_data[0], self.gap_value): # First element is a gap - replace with first known value - self.log.info(f'First element in the array were replaced by first known value') + self.log.info('First element in the array were replaced by first known value') output_data[0] = non_nan[0] if np.isclose(input_data[-1], self.gap_value): # Last element is a gap - last known value - self.log.info(f'Last element in the array were replaced by last known value') + self.log.info('Last element in the array were replaced by last known value') output_data[-1] = non_nan[-1] return output_data @@ -430,12 +430,12 @@ def __pipeline_fit_predict(self, pipeline, timeseries_train: np.array, len_gap: task=task, data_type=DataTypesEnum.ts) + forecast_length = input_data.task.task_params.forecast_length + data_length = input_data.features.shape[0] for node in pipeline_for_forecast.nodes: if node.name == 'lagged': - if (node.parameters['window_size'] + input_data.task.task_params.forecast_length - >= input_data.features.shape[0]): - node.parameters = {'window_size': input_data.features.shape[0] - - input_data.task.task_params.forecast_length - 1} + if node.parameters['window_size'] + forecast_length >= data_length: + node.parameters['window_size'] = data_length - forecast_length - 1 # Making predictions for the missing part in the time series pipeline_for_forecast.fit_from_scratch(input_data) diff --git a/test/unit/data_operations/test_data_operation_params.py b/test/unit/data_operations/test_data_operation_params.py index d343074abe..082037d743 100644 --- a/test/unit/data_operations/test_data_operation_params.py +++ b/test/unit/data_operations/test_data_operation_params.py @@ -11,7 +11,6 @@ from fedot.core.repository.dataset_types import DataTypesEnum from fedot.core.repository.tasks import Task, TaskTypesEnum, TsForecastingParams from fedot.core.utils import fedot_project_root -from test.unit.pipelines.test_pipeline_parameters import small_ts_dataset def get_ts_pipeline(window_size): From f089654b0a6a9eb36a92e89b88e687fd5b7093da Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Mon, 25 Sep 2023 14:42:22 +0300 Subject: [PATCH 12/27] Fix tests and #1165 p.2 --- .../pipelines/prediction_intervals/params.py | 8 +++----- .../solvers/mutation_of_best_pipeline.py | 9 +++++++-- .../prediction_intervals/ts_mutation.py | 19 ++++++++----------- .../pipelines/prediction_intervals/utils.py | 6 ------ 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/fedot/core/pipelines/prediction_intervals/params.py b/fedot/core/pipelines/prediction_intervals/params.py index b47987391f..e9d9ff1bf0 100644 --- a/fedot/core/pipelines/prediction_intervals/params.py +++ b/fedot/core/pipelines/prediction_intervals/params.py @@ -2,6 +2,8 @@ from dataclasses import dataclass from dataclasses import field +from fedot.core.repository.operation_types_repository import get_operations_for_task +from fedot.core.repository.tasks import Task, TaskTypesEnum from golem.core.tuning.simultaneous import SimultaneousTuner @@ -46,11 +48,7 @@ class PredictionIntervalsParams: # thus are removed. # In the future this should be solved... mutations_operations: List[str] = field(default_factory=lambda: - ['lagged', 'glm', 'ridge', 'sparse_lagged', 'lasso', 'ts_naive_average', - 'locf', 'pca', 'linear', 'smoothing', 'adareg', 'dtreg', 'gbr', 'lgbmreg', - 'rfr', 'polyfit', 'sgdr', 'ets', 'svr', 'treg', 'fast_ica', - 'poly_features', 'ransac_lin_reg', 'ransac_non_lin_reg', 'cut', - 'isolation_forest_reg', 'gaussian_filter', 'diff_filter', 'exog_ts']) + get_operations_for_task(task=Task(task_type=TaskTypesEnum.ts_forecasting))) ql_number_models: Union[int, str] = 10 ql_low_tuner: Optional[SimultaneousTuner] = None diff --git a/fedot/core/pipelines/prediction_intervals/solvers/mutation_of_best_pipeline.py b/fedot/core/pipelines/prediction_intervals/solvers/mutation_of_best_pipeline.py index cc2dbdc748..abaeded168 100644 --- a/fedot/core/pipelines/prediction_intervals/solvers/mutation_of_best_pipeline.py +++ b/fedot/core/pipelines/prediction_intervals/solvers/mutation_of_best_pipeline.py @@ -71,7 +71,12 @@ def solver_mutation_of_best_pipeline(train_input: InputData, s += 1 pipeline.show() start_time = time.time() - pipeline.fit(train_input) + try: + # TODO: create new approach to mutation generation: + # mutate and fit in one try in get_mutations/get_different_mutations + pipeline.fit(train_input) + except: + continue pred = out_of_sample_ts_forecast(pipeline=pipeline, input_data=train_input, horizon=horizon) metric_value = RMSE.get_value(pipeline=pipeline, reference_data=train_input, validation_blocks=2) if show_progress: @@ -98,7 +103,7 @@ def solver_mutation_of_best_pipeline(train_input: InputData, if discard_inapropriate_pipelines: predictions = [] maximal_metric_value = np.quantile(np.array(metric_values), keep_percentage) - for i, m in enumerate(mutations_of_best_pipeline): + for i, m in enumerate(range(len(first_pred_constraints))): if first_pred_constraints[i] and deviance_pred_constraints[i] and metric_values[i] < maximal_metric_value: predictions.append(raw_predictions[i]) else: diff --git a/fedot/core/pipelines/prediction_intervals/ts_mutation.py b/fedot/core/pipelines/prediction_intervals/ts_mutation.py index 787b4c566c..6ccb70c4aa 100644 --- a/fedot/core/pipelines/prediction_intervals/ts_mutation.py +++ b/fedot/core/pipelines/prediction_intervals/ts_mutation.py @@ -35,7 +35,6 @@ def get_ts_mutation(individual: Individual, operations: List[str]): task=Task(task_type)) mutation = Mutation(parameters, requirements, graph_params) - return mutation._mutation(individual)[0] @@ -51,8 +50,7 @@ def get_mutations(individual: Individual, number_mutations: int, operations: Lis list of mutations of given individual. Mutations can be identical. """ mutations = [get_ts_mutation(individual, operations) for _ in range(number_mutations)] - - return mutations + return [x for x in mutations if x is not None] def get_different_mutations(individual: Individual, @@ -69,19 +67,18 @@ def get_different_mutations(individual: Individual, Returns: list of mutations of given individual. Mutations must be different. """ - mutations = [] - graph_list = [] - s = 1 + mutations, graph_list = [], [] maximal_number_iterations = number_mutations * 3 - - while (len(mutations) < number_mutations and s <= maximal_number_iterations): - s += 1 + for _ in range(maximal_number_iterations): new_ind = get_ts_mutation(individual, operations) - if np.array([get_distance_between(new_ind.graph, x, compare_node_params=False) > 0 for x in graph_list]).all(): + if (new_ind is not None and + all(get_distance_between(new_ind.graph, x, compare_node_params=False) for x in graph_list)): graph_list.append(new_ind.graph) mutations.append(new_ind) + if len(mutations) == number_mutations: + break - if s == maximal_number_iterations + 1: + if len(mutations) != number_mutations: logger.warning(f"Maximal number attempts {maximal_number_iterations} to build different mutations used.") else: logger.info(f"{number_mutations} different mutations are succesfully created.") diff --git a/fedot/core/pipelines/prediction_intervals/utils.py b/fedot/core/pipelines/prediction_intervals/utils.py index 5d723ff150..61a83c414a 100644 --- a/fedot/core/pipelines/prediction_intervals/utils.py +++ b/fedot/core/pipelines/prediction_intervals/utils.py @@ -6,7 +6,6 @@ from fedot.api.main import Fedot from fedot.core.data.data import InputData from fedot.core.repository.tasks import Task, TaskTypesEnum -from fedot.core.repository.operation_types_repository import get_operations_for_task from golem.core.optimisers.opt_history_objects.individual import Individual from fedot.core.pipelines.prediction_intervals.params import PredictionIntervalsParams @@ -129,11 +128,6 @@ def check_init_params(model: Fedot, if not isinstance(params.mutations_operations, list): raise ValueError('Argument mutations_operations must be list of strings.') - else: - all_possible_operations = get_operations_for_task(task=Task(task_type=TaskTypesEnum.ts_forecasting)) - for x in params.mutations_operations: - if x not in all_possible_operations: - raise ValueError(f"Incorrect mutation '{x}' given in mutations_operations.") if params.ql_number_models != 'max': if not isinstance(params.ql_number_models, int) or params.ql_number_models < 1: From 980d038f73f15f6ccefc607ee7cb17a46bd4df88 Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Mon, 25 Sep 2023 14:50:32 +0300 Subject: [PATCH 13/27] Fix test with pipeline tuning --- test/unit/validation/test_time_series_cv.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/unit/validation/test_time_series_cv.py b/test/unit/validation/test_time_series_cv.py index 595c86e11c..f37f0e7df8 100644 --- a/test/unit/validation/test_time_series_cv.py +++ b/test/unit/validation/test_time_series_cv.py @@ -1,6 +1,8 @@ import datetime import logging +from hyperopt import hp + from golem.core.log import default_log from golem.core.optimisers.genetic.gp_params import GPAlgorithmParameters from golem.core.tuning.simultaneous import SimultaneousTuner @@ -15,6 +17,7 @@ from fedot.core.repository.quality_metrics_repository import \ MetricsRepository, RegressionMetricsEnum from fedot.core.repository.tasks import TsForecastingParams +from fedot.core.pipelines.tuning.search_space import PipelineSearchSpace from fedot.core.data.cv_folds import cv_generator from test.unit.tasks.test_forecasting import get_simple_ts_pipeline, get_ts_data @@ -69,12 +72,18 @@ def test_tuner_cv_correct(): simple_pipeline = get_simple_ts_pipeline(window_size=2) + max_window = int(time_series.features.shape[0] / (folds + 1)) - (forecast_len * validation_blocks) - 1 + ppl_ss = PipelineSearchSpace({'lagged': {'window_size': {'hyperopt-dist': hp.uniformint, + 'sampling-scope': [2, max_window], + 'type': 'discrete'}}}) + tuner = TunerBuilder(time_series.task)\ .with_tuner(SimultaneousTuner)\ .with_metric(RegressionMetricsEnum.MAE)\ .with_cv_folds(folds) \ .with_iterations(1) \ .with_timeout(datetime.timedelta(minutes=1))\ + .with_search_space(ppl_ss)\ .build(time_series) _ = tuner.tune(simple_pipeline) is_tune_succeeded = True From b4beec9a9342f51cd2da490797e1ab0eb7728b8d Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Mon, 25 Sep 2023 14:53:31 +0300 Subject: [PATCH 14/27] pep8 --- fedot/core/pipelines/prediction_intervals/ts_mutation.py | 6 +++--- fedot/core/pipelines/prediction_intervals/utils.py | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/fedot/core/pipelines/prediction_intervals/ts_mutation.py b/fedot/core/pipelines/prediction_intervals/ts_mutation.py index 6ccb70c4aa..f0ced2084c 100644 --- a/fedot/core/pipelines/prediction_intervals/ts_mutation.py +++ b/fedot/core/pipelines/prediction_intervals/ts_mutation.py @@ -1,4 +1,3 @@ -import numpy as np from typing import List from golem.core.optimisers.genetic.gp_params import GPAlgorithmParameters @@ -71,8 +70,9 @@ def get_different_mutations(individual: Individual, maximal_number_iterations = number_mutations * 3 for _ in range(maximal_number_iterations): new_ind = get_ts_mutation(individual, operations) - if (new_ind is not None and - all(get_distance_between(new_ind.graph, x, compare_node_params=False) for x in graph_list)): + if new_ind is not None and all(get_distance_between(graph_1=new_ind.graph, + graph_2=x, + compare_node_params=False) for x in graph_list): graph_list.append(new_ind.graph) mutations.append(new_ind) if len(mutations) == number_mutations: diff --git a/fedot/core/pipelines/prediction_intervals/utils.py b/fedot/core/pipelines/prediction_intervals/utils.py index 61a83c414a..2a6145cad7 100644 --- a/fedot/core/pipelines/prediction_intervals/utils.py +++ b/fedot/core/pipelines/prediction_intervals/utils.py @@ -5,7 +5,6 @@ from fedot.core.pipelines.pipeline import Pipeline from fedot.api.main import Fedot from fedot.core.data.data import InputData -from fedot.core.repository.tasks import Task, TaskTypesEnum from golem.core.optimisers.opt_history_objects.individual import Individual from fedot.core.pipelines.prediction_intervals.params import PredictionIntervalsParams From 3eb740ac239ab48a8b891d68ec6f96b28f6f753b Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Tue, 26 Sep 2023 12:45:27 +0300 Subject: [PATCH 15/27] Disable `GBR` --- fedot/core/repository/data/model_repository.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fedot/core/repository/data/model_repository.json b/fedot/core/repository/data/model_repository.json index fc362aa4b5..b817744a26 100644 --- a/fedot/core/repository/data/model_repository.json +++ b/fedot/core/repository/data/model_repository.json @@ -210,7 +210,8 @@ "tags": [ "boosting", "non_multi", - "non_linear" + "non_linear", + "non-default" ] }, "kmeans": { From 97b4977e690ad0a5228fc73ae74710a6082e2c63 Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Tue, 26 Sep 2023 12:53:04 +0300 Subject: [PATCH 16/27] Disable `DecisionTreeRegressor` and `ExtraTreesRegressor` --- fedot/core/repository/data/model_repository.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fedot/core/repository/data/model_repository.json b/fedot/core/repository/data/model_repository.json index b817744a26..506f6e3a72 100644 --- a/fedot/core/repository/data/model_repository.json +++ b/fedot/core/repository/data/model_repository.json @@ -201,7 +201,8 @@ "tags": [ "tree", "interpretable", - "non_linear" + "non_linear", + "non-default" ] }, "gbr": { @@ -425,7 +426,8 @@ "presets": ["*tree"], "tags": [ "tree", - "non_linear" + "non_linear", + "non-default" ] }, "xgboost": { From ba4c6d7a053ad07e676073c2514fe6a088daf7d4 Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Tue, 26 Sep 2023 13:21:11 +0300 Subject: [PATCH 17/27] Disable `AdaReg` --- fedot/core/repository/data/model_repository.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fedot/core/repository/data/model_repository.json b/fedot/core/repository/data/model_repository.json index 506f6e3a72..659058355f 100644 --- a/fedot/core/repository/data/model_repository.json +++ b/fedot/core/repository/data/model_repository.json @@ -125,7 +125,8 @@ "tags": [ "boosting", "non_multi", - "non_linear" + "non_linear", + "non-default" ] }, "ar": { From 94f8e124f750c65720ed66992fb670359ea6358c Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Tue, 26 Sep 2023 13:22:06 +0300 Subject: [PATCH 18/27] Disable `SVR` --- fedot/core/repository/data/model_repository.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fedot/core/repository/data/model_repository.json b/fedot/core/repository/data/model_repository.json index 659058355f..1502b9accf 100644 --- a/fedot/core/repository/data/model_repository.json +++ b/fedot/core/repository/data/model_repository.json @@ -419,7 +419,8 @@ "meta": "sklearn_regr", "tags": [ "non_multi", - "non_linear" + "non_linear", + "non-default" ] }, "treg": { From b8a15fb2070825e018cf2e4ba9bad3772620fcb2 Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Wed, 27 Sep 2023 12:54:39 +0300 Subject: [PATCH 19/27] Enable `adareg`, `dtreg`, `svr` --- fedot/core/repository/data/model_repository.json | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/fedot/core/repository/data/model_repository.json b/fedot/core/repository/data/model_repository.json index 1502b9accf..1691f031d7 100644 --- a/fedot/core/repository/data/model_repository.json +++ b/fedot/core/repository/data/model_repository.json @@ -125,8 +125,7 @@ "tags": [ "boosting", "non_multi", - "non_linear", - "non-default" + "non_linear" ] }, "ar": { @@ -202,8 +201,7 @@ "tags": [ "tree", "interpretable", - "non_linear", - "non-default" + "non_linear" ] }, "gbr": { @@ -419,8 +417,7 @@ "meta": "sklearn_regr", "tags": [ "non_multi", - "non_linear", - "non-default" + "non_linear" ] }, "treg": { From 3ee5425b5db7b1eb8723283a385e51aaf455dabc Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Thu, 28 Sep 2023 11:17:04 +0300 Subject: [PATCH 20/27] Fix --- fedot/utilities/ts_gapfilling.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fedot/utilities/ts_gapfilling.py b/fedot/utilities/ts_gapfilling.py index d148796475..e01c12228f 100644 --- a/fedot/utilities/ts_gapfilling.py +++ b/fedot/utilities/ts_gapfilling.py @@ -435,7 +435,7 @@ def __pipeline_fit_predict(self, pipeline, timeseries_train: np.array, len_gap: for node in pipeline_for_forecast.nodes: if node.name == 'lagged': if node.parameters['window_size'] + forecast_length >= data_length: - node.parameters['window_size'] = data_length - forecast_length - 1 + node.parameters = {'window_size': data_length - forecast_length - 1} # Making predictions for the missing part in the time series pipeline_for_forecast.fit_from_scratch(input_data) From f6a0d41e1b01d4fd54ac02a3bd94692e88b0158d Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Thu, 28 Sep 2023 12:07:47 +0300 Subject: [PATCH 21/27] Fix test --- test/unit/api/test_api_params.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/test/unit/api/test_api_params.py b/test/unit/api/test_api_params.py index a86e719501..9eab02aea5 100644 --- a/test/unit/api/test_api_params.py +++ b/test/unit/api/test_api_params.py @@ -97,13 +97,14 @@ def test_n_jobs(): def_pars = {k: v for k, v in fedot_params_full.items() if k in correct_composer_attributes} # check correct values - for n_jobs in range(-cpu_count(), cpu_count() + 5): - if n_jobs != 0: - params = ApiParams(def_pars, 'regression', TaskParams(), n_jobs, 10) - correct_n_jobs = min(n_jobs, cpu_count()) if n_jobs > 0 else cpu_count() + 1 + n_jobs - assert params.n_jobs == correct_n_jobs - - # check uncorrect values - for n_jobs in (0, -cpu_count() - 1, -cpu_count() - 2): - with pytest.raises(ValueError): - _ = ApiParams(def_pars, 'regression', TaskParams(), n_jobs, 10) + if cpu_count() > 0: + for n_jobs in range(-cpu_count(), cpu_count() + 5): + if n_jobs != 0: + params = ApiParams(def_pars, 'regression', TaskParams(), n_jobs, 10) + correct_n_jobs = min(n_jobs, cpu_count()) if n_jobs > 0 else cpu_count() + 1 + n_jobs + assert params.n_jobs == correct_n_jobs + + # check uncorrect values + for n_jobs in (0, -cpu_count() - 1, -cpu_count() - 2): + with pytest.raises(ValueError): + _ = ApiParams(def_pars, 'regression', TaskParams(), n_jobs, 10) From 2665e7679e55ee9e64d326c56aa0cf3332f76142 Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Thu, 28 Sep 2023 14:36:21 +0300 Subject: [PATCH 22/27] Fix tests --- test/unit/api/test_api_params.py | 21 +++++++++---------- .../test_prediction_intervals.py | 1 - 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/test/unit/api/test_api_params.py b/test/unit/api/test_api_params.py index 9eab02aea5..a86e719501 100644 --- a/test/unit/api/test_api_params.py +++ b/test/unit/api/test_api_params.py @@ -97,14 +97,13 @@ def test_n_jobs(): def_pars = {k: v for k, v in fedot_params_full.items() if k in correct_composer_attributes} # check correct values - if cpu_count() > 0: - for n_jobs in range(-cpu_count(), cpu_count() + 5): - if n_jobs != 0: - params = ApiParams(def_pars, 'regression', TaskParams(), n_jobs, 10) - correct_n_jobs = min(n_jobs, cpu_count()) if n_jobs > 0 else cpu_count() + 1 + n_jobs - assert params.n_jobs == correct_n_jobs - - # check uncorrect values - for n_jobs in (0, -cpu_count() - 1, -cpu_count() - 2): - with pytest.raises(ValueError): - _ = ApiParams(def_pars, 'regression', TaskParams(), n_jobs, 10) + for n_jobs in range(-cpu_count(), cpu_count() + 5): + if n_jobs != 0: + params = ApiParams(def_pars, 'regression', TaskParams(), n_jobs, 10) + correct_n_jobs = min(n_jobs, cpu_count()) if n_jobs > 0 else cpu_count() + 1 + n_jobs + assert params.n_jobs == correct_n_jobs + + # check uncorrect values + for n_jobs in (0, -cpu_count() - 1, -cpu_count() - 2): + with pytest.raises(ValueError): + _ = ApiParams(def_pars, 'regression', TaskParams(), n_jobs, 10) diff --git a/test/unit/pipelines/prediction_intervals/test_prediction_intervals.py b/test/unit/pipelines/prediction_intervals/test_prediction_intervals.py index 7679d7982f..2b34540e14 100644 --- a/test/unit/pipelines/prediction_intervals/test_prediction_intervals.py +++ b/test/unit/pipelines/prediction_intervals/test_prediction_intervals.py @@ -38,7 +38,6 @@ def test_prediction_intervals(params): pred_ints = PredictionIntervals(model=params['model'], method=x, horizon=20, params=pred_ints_params) pred_ints.fit(params['train_input']) res = pred_ints.forecast() - pred_ints.plot() int_score = interval_score(params['ts_test'], low=res['low_int'], up=res['up_int']) int_picp = picp(params['ts_test'], low=res['low_int'], up=res['up_int']) From 7bfd1ebef4ab8528cb5566d2f048746a0455fa72 Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Thu, 28 Sep 2023 16:01:46 +0300 Subject: [PATCH 23/27] Fix tests --- .github/workflows/unit-build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/unit-build.yml b/.github/workflows/unit-build.yml index 5a42511f0b..898982db23 100644 --- a/.github/workflows/unit-build.yml +++ b/.github/workflows/unit-build.yml @@ -30,6 +30,7 @@ jobs: pip install pytest pip install . pip install pytest-cov + pip install git+https://github.com/aimclub/GOLEM.git@main - name: Test with pytest run: | pytest --cov=fedot -s test/unit From a7db620d4ff8899d01a477ee9f405a36e1dfec0d Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Thu, 28 Sep 2023 16:13:38 +0300 Subject: [PATCH 24/27] Fix tests --- .github/workflows/unit-build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/unit-build.yml b/.github/workflows/unit-build.yml index 898982db23..1be1598c35 100644 --- a/.github/workflows/unit-build.yml +++ b/.github/workflows/unit-build.yml @@ -30,6 +30,7 @@ jobs: pip install pytest pip install . pip install pytest-cov + pip uninstall thegolem pip install git+https://github.com/aimclub/GOLEM.git@main - name: Test with pytest run: | From 212620e525ca803eb0384eb71686742950a4e4df Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Thu, 28 Sep 2023 16:19:18 +0300 Subject: [PATCH 25/27] Fix tests --- .github/workflows/unit-build.yml | 2 -- test/unit/api/test_api_params.py | 16 ---------------- 2 files changed, 18 deletions(-) diff --git a/.github/workflows/unit-build.yml b/.github/workflows/unit-build.yml index 1be1598c35..5a42511f0b 100644 --- a/.github/workflows/unit-build.yml +++ b/.github/workflows/unit-build.yml @@ -30,8 +30,6 @@ jobs: pip install pytest pip install . pip install pytest-cov - pip uninstall thegolem - pip install git+https://github.com/aimclub/GOLEM.git@main - name: Test with pytest run: | pytest --cov=fedot -s test/unit diff --git a/test/unit/api/test_api_params.py b/test/unit/api/test_api_params.py index a86e719501..2bc8cfa16a 100644 --- a/test/unit/api/test_api_params.py +++ b/test/unit/api/test_api_params.py @@ -91,19 +91,3 @@ def test_filter_params_correctly(input_params, case, correct_keys): assert output_params.keys() <= correct_keys # check all correct parameter in input params are in output params assert (input_params.keys() & correct_keys) <= output_params.keys() - - -def test_n_jobs(): - def_pars = {k: v for k, v in fedot_params_full.items() if k in correct_composer_attributes} - - # check correct values - for n_jobs in range(-cpu_count(), cpu_count() + 5): - if n_jobs != 0: - params = ApiParams(def_pars, 'regression', TaskParams(), n_jobs, 10) - correct_n_jobs = min(n_jobs, cpu_count()) if n_jobs > 0 else cpu_count() + 1 + n_jobs - assert params.n_jobs == correct_n_jobs - - # check uncorrect values - for n_jobs in (0, -cpu_count() - 1, -cpu_count() - 2): - with pytest.raises(ValueError): - _ = ApiParams(def_pars, 'regression', TaskParams(), n_jobs, 10) From 131f05a37a1de81d75b801c7e1d10789750b2123 Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Thu, 28 Sep 2023 17:13:57 +0300 Subject: [PATCH 26/27] Add requested changes --- .../prediction_intervals/solvers/mutation_of_best_pipeline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fedot/core/pipelines/prediction_intervals/solvers/mutation_of_best_pipeline.py b/fedot/core/pipelines/prediction_intervals/solvers/mutation_of_best_pipeline.py index abaeded168..6270305fb1 100644 --- a/fedot/core/pipelines/prediction_intervals/solvers/mutation_of_best_pipeline.py +++ b/fedot/core/pipelines/prediction_intervals/solvers/mutation_of_best_pipeline.py @@ -103,7 +103,7 @@ def solver_mutation_of_best_pipeline(train_input: InputData, if discard_inapropriate_pipelines: predictions = [] maximal_metric_value = np.quantile(np.array(metric_values), keep_percentage) - for i, m in enumerate(range(len(first_pred_constraints))): + for i in range(len(first_pred_constraints)): if first_pred_constraints[i] and deviance_pred_constraints[i] and metric_values[i] < maximal_metric_value: predictions.append(raw_predictions[i]) else: From f92cbfacf4a559bf3719ad3a4cb5060444e205b7 Mon Sep 17 00:00:00 2001 From: Sergey Kasyanov Date: Thu, 28 Sep 2023 17:14:23 +0300 Subject: [PATCH 27/27] pep8 --- test/unit/api/test_api_params.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/unit/api/test_api_params.py b/test/unit/api/test_api_params.py index 2bc8cfa16a..7295ababa9 100644 --- a/test/unit/api/test_api_params.py +++ b/test/unit/api/test_api_params.py @@ -2,9 +2,7 @@ from typing import Optional import pytest -from joblib import cpu_count -from fedot.api.api_utils.params import ApiParams from golem.core.optimisers.genetic.gp_optimizer import EvoGraphOptimizer from golem.core.optimisers.genetic.gp_params import GPAlgorithmParameters from golem.core.optimisers.genetic.operators.inheritance import GeneticSchemeTypesEnum @@ -14,7 +12,7 @@ from fedot.core.pipelines.pipeline_builder import PipelineBuilder from fedot.core.pipelines.pipeline_composer_requirements import PipelineComposerRequirements from fedot.core.repository.quality_metrics_repository import RegressionMetricsEnum -from fedot.core.repository.tasks import TaskTypesEnum, TaskParams +from fedot.core.repository.tasks import TaskTypesEnum fedot_params_full = dict(parallelization_mode='populational', show_progress=True,