diff --git a/ads/opctl/operator/lowcode/common/utils.py b/ads/opctl/operator/lowcode/common/utils.py index dc32a7f8e..0c024cb05 100644 --- a/ads/opctl/operator/lowcode/common/utils.py +++ b/ads/opctl/operator/lowcode/common/utils.py @@ -218,17 +218,12 @@ def _write_file(local_filename, remote_filename, storage_options, **kwargs): def load_pkl(filepath): - return _safe_write(fn=_load_pkl, filepath=filepath) - - -def _load_pkl(filepath): storage_options = {} if ObjectStorageDetails.is_oci_path(filepath): storage_options = default_signer() with fsspec.open(filepath, "rb", **storage_options) as f: return cloudpickle.load(f) - return None def write_pkl(obj, filename, output_dir, storage_options): diff --git a/ads/opctl/operator/lowcode/forecast/model/arima.py b/ads/opctl/operator/lowcode/forecast/model/arima.py index cd7271fec..3158e704a 100644 --- a/ads/opctl/operator/lowcode/forecast/model/arima.py +++ b/ads/opctl/operator/lowcode/forecast/model/arima.py @@ -85,7 +85,11 @@ def _train_model(self, i, s_id, df, model_kwargs): X_pred = self.get_horizon(data).drop(target, axis=1) if self.loaded_models is not None and s_id in self.loaded_models: - model = self.loaded_models[s_id] + model = self.loaded_models[s_id]["model"] + order = model.order + seasonal_order = model.seasonal_order + model = pm.ARIMA(order=order, seasonal_order=seasonal_order) + model.fit(y=y, X=X_in) else: # Build and fit model model = pm.auto_arima(y=y, X=X_in, **model_kwargs) diff --git a/ads/opctl/operator/lowcode/forecast/model/automlx.py b/ads/opctl/operator/lowcode/forecast/model/automlx.py index e1730ac0a..2545112aa 100644 --- a/ads/opctl/operator/lowcode/forecast/model/automlx.py +++ b/ads/opctl/operator/lowcode/forecast/model/automlx.py @@ -142,17 +142,20 @@ def _build_model(self) -> pd.DataFrame: ) if self.loaded_models is not None and s_id in self.loaded_models: - model = self.loaded_models[s_id] - else: - model = Pipeline( - task="forecasting", - **model_kwargs, - ) - model.fit( - X=data_i.drop(target, axis=1), - y=data_i[[target]], - time_budget=time_budget, - ) + model = self.loaded_models[s_id]["model"] + model_kwargs["model_list"] = [model.selected_model_] + model_kwargs["search_space"]={} + model_kwargs["search_space"][model.selected_model_] = model.selected_model_params_ + + model = Pipeline( + task="forecasting", + **model_kwargs, + ) + model.fit( + X=data_i.drop(target, axis=1), + y=data_i[[target]], + time_budget=time_budget, + ) logger.debug(f"Selected model: {model.selected_model_}") logger.debug(f"Selected model params: {model.selected_model_params_}") summary_frame = model.forecast( diff --git a/ads/opctl/operator/lowcode/forecast/model/prophet.py b/ads/opctl/operator/lowcode/forecast/model/prophet.py index c77d1e78f..306768ded 100644 --- a/ads/opctl/operator/lowcode/forecast/model/prophet.py +++ b/ads/opctl/operator/lowcode/forecast/model/prophet.py @@ -9,6 +9,7 @@ import matplotlib as mpl import numpy as np import optuna +import inspect import pandas as pd from joblib import Parallel, delayed @@ -39,6 +40,22 @@ def _add_unit(num, unit): return f"{num} {unit}" +def _extract_parameter(model): + """ + extract Prophet initialization parameters + """ + from prophet import Prophet + sig = inspect.signature(Prophet.__init__) + param_names = list(sig.parameters.keys()) + params = {} + for name in param_names: + if hasattr(model, name): + value = getattr(model, name) + if isinstance(value, (int, float, str, bool, type(None), dict, list)): + params[name] = value + return params + + def _fit_model(data, params, additional_regressors): from prophet import Prophet @@ -96,16 +113,17 @@ def _train_model(self, i, series_id, df, model_kwargs): data = self.preprocess(df, series_id) data_i = self.drop_horizon(data) if self.loaded_models is not None and series_id in self.loaded_models: - model = self.loaded_models[series_id] + previous_model = self.loaded_models[series_id]["model"] + model_kwargs.update(_extract_parameter(previous_model)) else: if self.perform_tuning: model_kwargs = self.run_tuning(data_i, model_kwargs) - model = _fit_model( - data=data, - params=model_kwargs, - additional_regressors=self.additional_regressors, - ) + model = _fit_model( + data=data, + params=model_kwargs, + additional_regressors=self.additional_regressors, + ) # Get future df for prediction future = data.drop("y", axis=1)