Spaces:
Sleeping
Sleeping
| from pathlib import Path | |
| from typing import Dict, Any, Optional | |
| import pandas as pd | |
| from pycaret.classification import setup as classification_setup, compare_models as classification_compare, finalize_model as classification_finalize, save_model as classification_save, load_model as classification_load | |
| from pycaret.regression import setup as regression_setup, compare_models as regression_compare, finalize_model as regression_finalize, save_model as regression_save, load_model as regression_load | |
| from mlpipeline.logging.logger import get_logger | |
| logger = get_logger(__name__) | |
| class PyCaretTrainer: | |
| def __init__(self, config: Dict[str, Any]): | |
| self.config = config | |
| self.model: Optional[Any] = None | |
| self.is_classification = None | |
| def train(self, train_data: pd.DataFrame, target_column: str, model_path: Path) -> Dict[str, float]: | |
| logger.info("Starting PyCaret training") | |
| if train_data[target_column].dtype == 'object' or train_data[target_column].nunique() < 20: | |
| self.is_classification = True | |
| setup_fn = classification_setup | |
| compare_fn = classification_compare | |
| finalize_fn = classification_finalize | |
| save_fn = classification_save | |
| else: | |
| self.is_classification = False | |
| setup_fn = regression_setup | |
| compare_fn = regression_compare | |
| finalize_fn = regression_finalize | |
| save_fn = regression_save | |
| exp = setup_fn( | |
| data=train_data, | |
| target=target_column, | |
| session_id=self.config.get('session_id', 42), | |
| fold=self.config.get('fold', 5), | |
| verbose=self.config.get('verbose', False), | |
| use_gpu=self.config.get('use_gpu', False), | |
| ) | |
| best_model = compare_fn( | |
| n_select=self.config.get('n_select', 5), | |
| verbose=self.config.get('verbose', False), | |
| ) | |
| if self.config.get('tuning', {}).get('enabled', True): | |
| from pycaret.classification import tune_model as classification_tune | |
| from pycaret.regression import tune_model as regression_tune | |
| tune_fn = classification_tune if self.is_classification else regression_tune | |
| best_model = tune_fn( | |
| best_model, | |
| n_iter=self.config.get('tuning', {}).get('n_iter', 10), | |
| optimize=self.config.get('tuning', {}).get('optimize', 'Accuracy'), | |
| ) | |
| self.model = finalize_fn(best_model) | |
| save_fn(self.model, str(model_path / 'model')) | |
| from pycaret.classification import pull as classification_pull | |
| from pycaret.regression import pull as regression_pull | |
| pull_fn = classification_pull if self.is_classification else regression_pull | |
| results = pull_fn() | |
| metrics = { | |
| 'score': float(results.iloc[0]['Mean']) if not results.empty else 0.0, | |
| } | |
| logger.info(f"PyCaret training completed. Score: {metrics['score']}") | |
| return metrics | |
| def predict(self, data: pd.DataFrame) -> pd.Series: | |
| if self.model is None: | |
| raise ValueError("Model not trained. Call train() first.") | |
| from pycaret.classification import predict_model as classification_predict | |
| from pycaret.regression import predict_model as regression_predict | |
| predict_fn = classification_predict if self.is_classification else regression_predict | |
| predictions = predict_fn(self.model, data=data) | |
| return predictions.iloc[:, -1] | |
| def load(self, model_path: Path): | |
| logger.info(f"Loading PyCaret model from {model_path}") | |
| load_fn = classification_load if self.is_classification else regression_load | |
| self.model = load_fn(str(model_path / 'model')) | |
| return self |