From 114cae699fb660b610e9a0e85fd24151b87ff247 Mon Sep 17 00:00:00 2001 From: DRMPN Date: Fri, 23 Aug 2024 14:00:11 +0300 Subject: [PATCH 1/8] fix: do not launch composition for atomized model --- fedot/api/api_utils/predefined_model.py | 4 +++- fedot/api/main.py | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/fedot/api/api_utils/predefined_model.py b/fedot/api/api_utils/predefined_model.py index 1b50bd8d90..4a8e96d5dc 100644 --- a/fedot/api/api_utils/predefined_model.py +++ b/fedot/api/api_utils/predefined_model.py @@ -31,7 +31,9 @@ def _get_pipeline(self, use_input_preprocessing: bool = True) -> Pipeline: else: raise ValueError(f'{type(self.predefined_model)} is not supported as Fedot model') - verify_pipeline(pipelines, task_type=self.data.task.task_type, raise_on_failure=True) + # ISSUE #1317 Quick Fix: Skip pipeline verification for Atomized Model + if not "atomized" in pipelines.descriptive_id: + verify_pipeline(pipelines, task_type=self.data.task.task_type, raise_on_failure=True) return pipelines diff --git a/fedot/api/main.py b/fedot/api/main.py index f389489acc..80d6d6b216 100644 --- a/fedot/api/main.py +++ b/fedot/api/main.py @@ -166,6 +166,11 @@ def fit(self, with fedot_composer_timer.launch_preprocessing(): self.train_data = self.data_processor.fit_transform(self.train_data) + # ISSUE #1317 Quick Fix: Do not launch composition for Atomized Model + if init_asm := self.params.data.get('initial_assumption'): + if predefined_model is None and "atomized" in init_asm.descriptive_id: + predefined_model = init_asm + with fedot_composer_timer.launch_fitting(): if predefined_model is not None: # Fit predefined model and return it without composing From 360260c560b21f9c2dcf620fab01775a6d6c6d05 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 23 Aug 2024 11:07:02 +0000 Subject: [PATCH 2/8] Automated autopep8 fixes --- fedot/api/api_utils/predefined_model.py | 2 +- fedot/api/main.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fedot/api/api_utils/predefined_model.py b/fedot/api/api_utils/predefined_model.py index 4a8e96d5dc..5ead4df499 100644 --- a/fedot/api/api_utils/predefined_model.py +++ b/fedot/api/api_utils/predefined_model.py @@ -32,7 +32,7 @@ def _get_pipeline(self, use_input_preprocessing: bool = True) -> Pipeline: raise ValueError(f'{type(self.predefined_model)} is not supported as Fedot model') # ISSUE #1317 Quick Fix: Skip pipeline verification for Atomized Model - if not "atomized" in pipelines.descriptive_id: + if "atomized" not in pipelines.descriptive_id: verify_pipeline(pipelines, task_type=self.data.task.task_type, raise_on_failure=True) return pipelines diff --git a/fedot/api/main.py b/fedot/api/main.py index 80d6d6b216..b698e8f600 100644 --- a/fedot/api/main.py +++ b/fedot/api/main.py @@ -168,7 +168,7 @@ def fit(self, # ISSUE #1317 Quick Fix: Do not launch composition for Atomized Model if init_asm := self.params.data.get('initial_assumption'): - if predefined_model is None and "atomized" in init_asm.descriptive_id: + if predefined_model is None and "atomized" in init_asm.descriptive_id: predefined_model = init_asm with fedot_composer_timer.launch_fitting(): From 1bca8ff62d27f34247636419dae7b0f1c7614604 Mon Sep 17 00:00:00 2001 From: DRMPN Date: Sat, 24 Aug 2024 23:06:26 +0300 Subject: [PATCH 3/8] fix: remove comments --- fedot/api/api_utils/predefined_model.py | 3 +-- fedot/api/main.py | 7 +++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/fedot/api/api_utils/predefined_model.py b/fedot/api/api_utils/predefined_model.py index 5ead4df499..e920812072 100644 --- a/fedot/api/api_utils/predefined_model.py +++ b/fedot/api/api_utils/predefined_model.py @@ -31,8 +31,7 @@ def _get_pipeline(self, use_input_preprocessing: bool = True) -> Pipeline: else: raise ValueError(f'{type(self.predefined_model)} is not supported as Fedot model') - # ISSUE #1317 Quick Fix: Skip pipeline verification for Atomized Model - if "atomized" not in pipelines.descriptive_id: + if not "atomized" in pipelines.descriptive_id: verify_pipeline(pipelines, task_type=self.data.task.task_type, raise_on_failure=True) return pipelines diff --git a/fedot/api/main.py b/fedot/api/main.py index b698e8f600..94036fab49 100644 --- a/fedot/api/main.py +++ b/fedot/api/main.py @@ -166,10 +166,9 @@ def fit(self, with fedot_composer_timer.launch_preprocessing(): self.train_data = self.data_processor.fit_transform(self.train_data) - # ISSUE #1317 Quick Fix: Do not launch composition for Atomized Model - if init_asm := self.params.data.get('initial_assumption'): - if predefined_model is None and "atomized" in init_asm.descriptive_id: - predefined_model = init_asm + init_asm = self.params.data.get('initial_assumption') + if (predefined_model is None) and init_asm and ("atomized" in init_asm.descriptive_id): + predefined_model = init_asm with fedot_composer_timer.launch_fitting(): if predefined_model is not None: From e6dda1ad0ce14379ed835b1479eb58ec946251eb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 24 Aug 2024 20:12:15 +0000 Subject: [PATCH 4/8] Automated autopep8 fixes --- fedot/api/api_utils/predefined_model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fedot/api/api_utils/predefined_model.py b/fedot/api/api_utils/predefined_model.py index e920812072..9ad2904b95 100644 --- a/fedot/api/api_utils/predefined_model.py +++ b/fedot/api/api_utils/predefined_model.py @@ -31,7 +31,7 @@ def _get_pipeline(self, use_input_preprocessing: bool = True) -> Pipeline: else: raise ValueError(f'{type(self.predefined_model)} is not supported as Fedot model') - if not "atomized" in pipelines.descriptive_id: + if "atomized" not in pipelines.descriptive_id: verify_pipeline(pipelines, task_type=self.data.task.task_type, raise_on_failure=True) return pipelines From b956d5953555e706503553a97fd8d23c005d8c69 Mon Sep 17 00:00:00 2001 From: DRMPN Date: Mon, 26 Aug 2024 00:42:17 +0300 Subject: [PATCH 5/8] test: add integration test for atomized model --- test/integration/api/test_main_api.py | 38 +++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/test/integration/api/test_main_api.py b/test/integration/api/test_main_api.py index 01700842e1..f750b16bc9 100644 --- a/test/integration/api/test_main_api.py +++ b/test/integration/api/test_main_api.py @@ -11,8 +11,10 @@ from examples.simple.time_series_forecasting.ts_pipelines import ts_complex_ridge_smoothing_pipeline from fedot import Fedot +from fedot.core.operations.atomized_model import AtomizedModel from fedot.core.pipelines.node import PipelineNode from fedot.core.pipelines.pipeline import Pipeline +from fedot.core.pipelines.pipeline_builder import PipelineBuilder from fedot.core.repository.tasks import TsForecastingParams from test.data.datasets import get_dataset, get_multimodal_ts_data, load_categorical_unimodal, \ load_categorical_multidata @@ -84,6 +86,42 @@ def test_api_tune_correct(task_type, metric_name, pred_model): assert len(test_data.target) == len(pred_before) == len(pred_after) +@pytest.mark.parametrize( + "task_type, metric_name, pred_model", + [ + ("classification", "f1", "dt"), + ("regression", "rmse", "dtreg"), + ], +) +def test_api_fit_atomized_model(task_type, metric_name, pred_model): + train_data, test_data, _ = get_dataset(task_type, n_samples=100, n_features=5, iris_dataset=False) + + auto_model = Fedot( + problem=task_type, + metric=metric_name, + **TESTS_MAIN_API_DEFAULT_PARAMS, + initial_assumption=PipelineBuilder().add_node("scaling").add_node(pred_model).build() + ) + + auto_model.fit(features=train_data) + pred_auto_model = auto_model.predict(features=test_data) + + prev_model = auto_model.current_pipeline + prev_model.unfit() + + atomized_model = Pipeline( + PipelineNode(operation_type=AtomizedModel(prev_model), nodes_from=[PipelineNode("normalization")]) + ) + + auto_model_from_atomized = Fedot( + problem=task_type, metric=metric_name, **TESTS_MAIN_API_DEFAULT_PARAMS, initial_assumption=atomized_model + ) + auto_model_from_atomized.fit(features=train_data) + pred_auto_model_from_atomized = auto_model_from_atomized.predict(features=test_data) + + assert len(test_data.target) == len(pred_auto_model) == len(pred_auto_model_from_atomized) + + def test_api_simple_ts_predict_correct(task_type: str = 'ts_forecasting'): # The forecast length must be equal to 5 forecast_length = 5 From b7466e088a3cb614db327f1d9909bd571c2356e5 Mon Sep 17 00:00:00 2001 From: DRMPN Date: Mon, 26 Aug 2024 03:29:40 +0300 Subject: [PATCH 6/8] test: fix integration test --- fedot/api/main.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fedot/api/main.py b/fedot/api/main.py index 94036fab49..6cb6901e4a 100644 --- a/fedot/api/main.py +++ b/fedot/api/main.py @@ -167,8 +167,9 @@ def fit(self, self.train_data = self.data_processor.fit_transform(self.train_data) init_asm = self.params.data.get('initial_assumption') - if (predefined_model is None) and init_asm and ("atomized" in init_asm.descriptive_id): - predefined_model = init_asm + if (predefined_model is None): + if isinstance(init_asm, Pipeline) and ("atomized" in init_asm.descriptive_id): + predefined_model = init_asm with fedot_composer_timer.launch_fitting(): if predefined_model is not None: From 8d6a1fc323646be93442ca290890f1573cb28c62 Mon Sep 17 00:00:00 2001 From: DRMPN Date: Mon, 26 Aug 2024 23:34:41 +0300 Subject: [PATCH 7/8] chore: remove parenthesis --- fedot/api/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fedot/api/main.py b/fedot/api/main.py index 6cb6901e4a..78c0572a08 100644 --- a/fedot/api/main.py +++ b/fedot/api/main.py @@ -167,7 +167,7 @@ def fit(self, self.train_data = self.data_processor.fit_transform(self.train_data) init_asm = self.params.data.get('initial_assumption') - if (predefined_model is None): + if predefined_model is None: if isinstance(init_asm, Pipeline) and ("atomized" in init_asm.descriptive_id): predefined_model = init_asm From d6555da0fa8f6d68edce0e74ec322d3c871c333d Mon Sep 17 00:00:00 2001 From: DRMPN Date: Tue, 27 Aug 2024 00:06:19 +0300 Subject: [PATCH 8/8] refactor: add log messages and TODO comments --- fedot/api/api_utils/predefined_model.py | 5 ++++- fedot/api/main.py | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/fedot/api/api_utils/predefined_model.py b/fedot/api/api_utils/predefined_model.py index 9ad2904b95..1c40b4444e 100644 --- a/fedot/api/api_utils/predefined_model.py +++ b/fedot/api/api_utils/predefined_model.py @@ -31,7 +31,10 @@ def _get_pipeline(self, use_input_preprocessing: bool = True) -> Pipeline: else: raise ValueError(f'{type(self.predefined_model)} is not supported as Fedot model') - if "atomized" not in pipelines.descriptive_id: + # TODO: Workaround for AtomizedModel + if "atomized" in pipelines.descriptive_id: + self.log.message("Pipeline verification for AtomizedModel currently unavailable") + else: verify_pipeline(pipelines, task_type=self.data.task.task_type, raise_on_failure=True) return pipelines diff --git a/fedot/api/main.py b/fedot/api/main.py index 78c0572a08..1fbcf02ca8 100644 --- a/fedot/api/main.py +++ b/fedot/api/main.py @@ -166,9 +166,11 @@ def fit(self, with fedot_composer_timer.launch_preprocessing(): self.train_data = self.data_processor.fit_transform(self.train_data) + # TODO: Workaround for AtomizedModel init_asm = self.params.data.get('initial_assumption') if predefined_model is None: if isinstance(init_asm, Pipeline) and ("atomized" in init_asm.descriptive_id): + self.log.message('Composition for AtomizedModel currently unavailable') predefined_model = init_asm with fedot_composer_timer.launch_fitting():