Artificial Intelligence (AI)

MLOps With Prefect & CometML: Predict Bulldozer Sales Prices

Written by smirow

Introduction

Si vous êtes débutant et que vous commencez tout juste à apprendre le MLOps, vous vous posez peut-être une question : que sont les MLOps ?

En termes simples, MLOps (Machine Learning Operations) est un ensemble de pratiques de collaboration et de communication entre les data scientists et les professionnels des opérations. L'application de ces pratiques augmente la qualité, simplifie le processus de gestion et automatise le déploiement de modèles de Machine Learning et de Deep Learning dans des environnements de production à grande échelle. Il est plus facile d'aligner les modèles sur les besoins de l'entreprise et les exigences réglementaires. Dans cet article, nous mettrons en œuvre notre projet en utilisant Prefect et CometML.

Dans ce projet MLOps, nous allons construire le meilleur modèle de Machine Learning possible en utilisant des hyperparamètres optimaux pour prédire le prix de vente d'un Bulldozer. Comme vous le savez peut-être, un bulldozer est un véhicule puissant pour creuser et creuser des fossés peu profonds.

MLOPS

Objectifs d'apprentissage

  • Découvrez les concepts MLOps et le flux de travail ML de bout en bout.
  • Implémentez le pipeline MLOps avec Prefect et CometML.
  • Créez des flux de travail ML reproductibles et automatisés.
  • Évaluez et surveillez les modèles ML.
  • Expérience MLOps de bout en bout.

Cet article a été publié dans le cadre du Blogathon sur la science des données.

Qu'est-ce que Prefect et CometML ?

Préfet

Prefect est une bibliothèque Python open source qui vous aide à bien définir, planifier et gérer les flux de données. Il simplifie l'orchestration et l'automatisation des flux de données complexes, facilitant ainsi les tâches. Les exemples sont l’extraction de données, la transformation et la formation de modèles. Vous pouvez les faire de manière systématique et reproductible.

pip install prefect

Une autre chose que je devrais mentionner est Prefect Cloud. Prefect Cloud est une plate-forme cloud fournie par Prefect pour gérer, orchestrer et surveiller les flux de données dans MLOps.

ComèteML

CometML est une plateforme de gestion et de suivi des expériences d'apprentissage automatique dans MLOps. Il fournit des outils de gestion des versions, de collaboration et de visualisation des résultats. Il permet de rationaliser le développement et la surveillance des modèles d'apprentissage automatique.

pip install comet_ml

Le projet MLOps : commençons.

Exploration des données

Au fur et à mesure que nous construisons un modèle d'apprentissage automatique de bout en bout, nous nous concentrerons davantage sur le cycle de vie du ML que sur la création de modèles.

Projet MLOps

Si vous observez l'ensemble de données, vous verrez qu'il y a 53 colonnes. Nous utiliserons les 52 colonnes pour les entités en entrée ou X, et puisque notre variable cible est Prix ​​de vente, ce sera le y. Dans la partie exploration des données, nous avons effectué toutes sortes d'explorations, de df.info() au tracé des valeurs manquantes à l'aide d'un nuage de points. Vous retrouverez toutes les étapes dans mon notebook sur le dépôt GitHub. Vous pouvez également télécharger l'ensemble de données à partir de là. Maintenant, commençons à travailler sur le projet.

Configurer un environnement virtuel

Qu’est-ce que l’environnement virtuel et pourquoi en avons-nous besoin ?

Un environnement virtuel est un espace de travail Python autonome permettant d'isoler les dépendances d'un projet.
Vous installez de nombreuses bibliothèques sur votre ordinateur pour plusieurs projets. Vous avez peut-être installé Python3.11, mais parfois, vous avez besoin de Python3.9 pour un autre projet. Pour éviter les conflits, vous devez configurer un environnement virtuel.

Création d'un environnement virtuel

python -m venv myenv
#then for activation
myenv\Scripts\activate
python3 -m venv myenv
#then for activation
source myenv/bin/activate

Structure du fichier

Projet MLOps

Configurer CometML et Prefect

Pour configurer CometML, vous devez créer un fichier nommé .comet.config dans le répertoire de votre projet et définir ses paramètres de configuration. Voici un exemple de la façon dont vous pouvez structurer un fichier .comet.config de base :

[comet]
api_key = your_api_key
workspace = your_workspace
project_name = your_project_name

Vous devez vous inscrire à Comet pour une api_key, un espace de travail et un nom_projet. Voyons comment créer un compte Comet.

Créer un compte Comet

  • Veuillez créer un nouveau compte. C'est facile et gratuit.
Projet MLOps

Clé API

  • Lorsque votre compte est créé dans le coin supérieur droit, cliquez sur votre avatar, puis sélectionnez Paramètres du compte.
Projet MLOps
  • Pour obtenir la clé API, cliquez sur l'onglet Clés API. Votre clé API actuelle y est affichée. Cliquez sur Copier pour copier la clé API.
Projet MLOps
  • Vous pouvez voir le nom de votre espace de travail et le nom de votre projet dans l'onglet Espaces de travail.

Alors maintenant, configurons Prefect.

Mettre en place le préfet

Prefect fournit une plate-forme cloud et une API pour gérer et surveiller les flux de travail. En nous inscrivant, nous pouvons utiliser Prefect Cloud. Il dispose d'un tableau de bord pour suivre les flux de travail. Il peut définir des notifications, analyser les journaux et bien plus encore. La partie intéressante est que nous pouvons déployer notre modèle d'apprentissage automatique.

pip install -U prefect

Consultez le guide d'installation pour plus de détails.

  • Étape 2 : Connectez-vous à l'API du préfet

La fonctionnalité de Prefect repose sur une API cloud backend. L'API gère l'exécution des workflows et des pipelines de données. Nous devons connecter l'installation de Prefect à cette API. Cela débloque des fonctionnalités utiles. Par exemple, un tableau de bord central peut être utilisé pour surveiller les exécutions du flux de travail. Il vous permet également de définir des notifications. Vous pouvez les obtenir lorsque des tâches échouent, analyser les journaux et suivre l'historique des tâches. Enfin, il vous permet de faire évoluer les charges de travail sur un cluster. Nous pouvons créer des flux de travail localement sans l'API. Mais nous ne pouvons pas les rendre opérationnels ou prêts pour la production. Le Prefect Cloud gère la planification et les tentatives. Il suit les limites fixées via l'API. Ainsi, utiliser Prefect avec son service API offre une plateforme sans serveur. Il permet de gérer des flux de travail complexes sans avoir besoin d'héberger vos propres coordinateurs.

  1. Créez un nouveau compte ou connectez-vous à
  2. Utilisez la commande CLI de connexion parfaite au cloud pour

Connexion parfaite au cloud

Choisissez Se connecter avec un navigateur Web et cliquez sur le bouton Autoriser dans la fenêtre ouverte du navigateur.

Instance de serveur Prefect auto-hébergée

Vous pouvez également l'exécuter sur votre ordinateur local. Consultez le didacticiel pour obtenir de l'aide. Notez que vous devez héberger votre propre serveur et exécuter vos flux sur votre propre infrastructure.

  • Étape 3 : Transformez votre fonction en flux Préfet

Voir le flux.py fichier où j'ai ajouté le décorateur @flow. C’est le moyen le plus rapide de démarrer avec Prefect. Un « flux » est un graphique acyclique dirigé (DAG) représentant un flux de travail. Dans Prefect, une tâche est une unité de travail fondamentale dans le flux de travail. Nous discuterons des tâches plus tard dans ce didacticiel.

5 étapes pour mettre en œuvre ce projet MLOps à l'aide de Prefect et CometML

Voici les 5 étapes pour mettre en œuvre le projet MLops à l'aide de Prefect et CometML

Étape 1 – Ingérer des données

Dans cette étape, nous ingérons nos données de notre dossier de données. Jetons un coup d'œil à notre fichier ingest_data.py dans le dossier steps

class IngestData:
    """Ingests data from a CSV file."""

    def __init__(self, data_path: str):
        self.data_path = data_path

    def get_data(self):
        logging.info(f"Ingest data from {self.data_path}")
        return pd.read_csv(self.data_path)

@task(cache_key_fn=task_input_hash, cache_expiration=timedelta(hours=1))
def ingest_df(data_path: str) -> pd.DataFrame:
    """
    Ingest data from the specified path and return a DataFrame.

    Args:
        data_path (str): The path to the data file.

    Returns:
        pd.DataFrame: A pandas DataFrame containing the ingested data.
    """
    try:
        ingest_obj = IngestData(data_path)
        df = ingest_obj.get_data()
        print(f"Ingesting data from {data_path}")
        experiment.log_metric("data_ingestion_status", 1)
        return df
    except Exception as e:
        logging.error(f"Error while ingesting data: {e}")
        raise e
    finally:
        # Ensure that the experiment is ended to log all data
        experiment.end()

Dans Prefect, une tâche est une unité de travail fondamentale dans un workflow. Il représente une unité de calcul individuelle ou une opération qui doit être effectuée. Ainsi, dans ce cas, notre première tâche consiste à ingérer les données.

@task(cache_key_fn=task_input_hash, cache_expiration=timedelta(hours=1))

Ce décorateur de tâches Prefect spécifie les paramètres de mise en cache, en utilisant task_input_hash comme fonction de clé de cache et en définissant une expiration du cache d'une heure. Vous pouvez en savoir plus à ce sujet dans le doc du préfet.

Étape 2 – Nettoyer les données

Dans cette étape, nous nettoierons nos données et le code ci-dessous renverra X_train, X_test, y_train, y_test, pour entraîner et tester notre modèle ML. Regardons

@task(cache_key_fn=task_input_hash, cache_expiration=timedelta(hours=1))
def clean_df(data: pd.DataFrame) -> Tuple[
    Annotated[pd.DataFrame, 'X_train'],
    Annotated[pd.DataFrame, 'X_test'],
    Annotated[pd.Series, 'y_train'],
    Annotated[pd.Series, 'y_test'],
]:
    """
    Data cleaning class which preprocesses the data and divides it into train and test data.

    Args:
        data: pd.DataFrame
    """
    try:
        preprocess_strategy = DataPreprocessStrategy()
        data_cleaning = DataCleaning(data, preprocess_strategy)
        preprocessed_data = data_cleaning.handle_data()

        divide_strategy = DataDivideStrategy()
        data_cleaning = DataCleaning(preprocessed_data, divide_strategy)
        X_train, X_test, y_train, y_test = data_cleaning.handle_data()
        logging.info(f"Data Cleaning Complete")
        experiment.log_metric("data_cleaning_status", 1)
        return X_train, X_test, y_train, y_test 
    except Exception as e: 
        logging.error(e)
        raise e
    finally:
        # Ensure that the experiment is ended to log all data
        experiment.end()

Jusqu'à présent, si vous observez attentivement le code ci-dessus, vous vous demandez peut-être où sont DataPreprocessStrategy() et DataDivideStrategy() définis dans le dossier modèle, nous définissons ces méthodes ; regardons

class DataPreprocessStrategy(DataStrategy):
    """
    Data preprocessing strategy which preprocesses the data.
    """

    def handle_data(self, data: pd.DataFrame) -> pd.DataFrame:
        try:
            """
            Performs transformations on df and returns transformaed df.
            """
            # Convert 'saledate' column to datetime
            data['saledate'] = pd.to_datetime(data['saledate'])
            data["saleYear"] = data.saledate.dt.year
            data["saleMonth"] = data.saledate.dt.month
            data["saleDay"] =data.saledate.dt.day
            data["saleDayOfWeek"] = data.saledate.dt.dayofweek
            data["saleDayOfYear"] = data.saledate.dt.dayofyear

            data.drop("saledate", axis=1, inplace=True)


            # Fill the numeric row with median
            for label, content in data.items():
                    if pd.api.types.is_numeric_dtype(content):
                        if pd.isnull(content).sum():
                            # Add a binary column which tells us if the data was missing 
                            # or not
                            data[label+"is_missing"] = pd.isnull(content)
                            # Fill missing numeric values with median
                            data[label] = content.fillna(content.median())

                    # Filled categorical missing data and turn categories into numbers
                    if not pd.api.types.is_numeric_dtype(content):
                        data[label+"is_missing"] = pd.isnull(content)
                        # We add +1 to the category code because pandas encodes
                        # missing categories as -1
                        data[label] = pd.Categorical(content).codes+1
                
        
        
            return data
        except Exception as e:
            logging.error("Error in Data handling: {}".format(e))
            raise e

Dans mon référentiel GitHub, vous pouvez trouver toutes les méthodes.

Étape 3 – Former le modèle

Nous allons former un modèle de régression linéaire simple à l'aide de la bibliothèque Scikit learn.

# Create a CometML experiment
experiment = Experiment()
@task(cache_key_fn=task_input_hash, cache_expiration=timedelta(hours=1))
def train_model(
    X_train: pd.DataFrame,
    X_test: pd.DataFrame,
    y_train: pd.Series,
    y_test: pd.Series,
    config: ModelNameConfig = ModelNameConfig(),
) -> RegressorMixin:
    """
    Train a regression model based on the specified configuration.

    Args:
        X_train (pd.DataFrame): Training data features.
        X_test (pd.DataFrame): Testing data features.
        y_train (pd.Series): Training data target.
        y_test (pd.Series): Testing data target.
        config (ModelNameConfig): Model configuration.

    Returns:
        RegressorMixin: Trained regression model.
    """
    try:
        model = None
        if config.model_name == "random_forest_regressor":
            model = RandomForestRegressor(n_estimators=40,
                                                min_samples_leaf=1,
                                                min_samples_split=14,
                                                max_features=0.5,
                                                n_jobs=-1,
                                                max_samples=None,
                                                random_state=42)
            trained_model = model.fit(X_train, y_train)
             # Save the trained model to a file
            model_filename = "trained_model.pkl"
            with open(model_filename, 'wb') as model_file:
                pickle.dump(trained_model, model_file)
            print("train model finished")
            experiment.log_metric("model_training_status", 1)
            return trained_model
        else:
            raise ValueError("Model name not supported")
    except Exception as e:
        logging.error(f"Error in train model: {e}")
        raise e
    finally:
    # Ensure that the experiment is ended to log all data
        experiment.end()

Étape 4 – Évaluer le modèle

# Create a CometML experiment
experiment = Experiment()
@task(cache_key_fn=task_input_hash, cache_expiration=timedelta(hours=1))
def evaluate_model(
    model: RegressorMixin, X_test: pd.DataFrame, y_test: pd.Series
) -> Tuple[Annotated[float, "r2"], 
           Annotated[float, "rmse"],
]:
    """
    Args:
        model: RegressorMixin
        x_test: pd.DataFrame
        y_test: pd.Series
    Returns:
        r2_score: float
        rmse: float
    """
    try:
        prediction = model.predict(X_test)

        # Using the MSE class for mean squared error calculation
        mse_class = MSE()
        mse = mse_class.calculate_score(y_test, prediction)
        experiment.log_metric("MSE", mse)
        # Using the R2Score class for R2 score calculation
        r2_class = R2Score()
        r2 = r2_class.calculate_score(y_test, prediction)
        experiment.log_metric("R2Score", r2)
        # Using the RMSE class for root mean squared error calculation
        rmse_class = RMSE()
        rmse = rmse_class.calculate_score(y_test, prediction)
        experiment.log_metric("RMSE", rmse)
       # Log metrics to CometML
        
        experiment.log_metric("model_evaluation_status", 1)
        print("Evaluate model finished")

        return r2, rmse
    except Exception as e:
        logging.error(f"Error in evaluation: {e}")
        raise e
    finally:
        # Ensure that the experiment is ended to log all data
        experiment.end()

Nous avons enregistré toutes ces mesures, comme le score r2, mse et rmse. Vous pouvez voir le code ci-dessus. Nous pouvons visualiser ces matrices sur le tableau de bord CometML. Cependant, lorsque vous exécutez le flux, vous pouvez voir le tableau de bord. Dans l'étape suivante, nous en discutons.

Projet MLOps

Étape 5 – Exécuter le flux (la dernière étape)

Nous devons gérer le flux.

Nous importons toutes les tâches et flux dans le fichier flow.py et exécutons notre flux à partir de là.

python3 flow.py
from prefect import flow

from steps. ingest_data import ingest_df
from steps.clean_data import clean_df
from steps.train_model import train_model
from steps.evaluation import evaluate_model
## import comet_ml at the top of your file
from comet_ml import Experiment

## Create an experiment with your api key
@flow(retries=3, retry_delay_seconds=5, log_prints=True)
def my_flow():
    data_path="/home/dhrubaubuntu/gigs_projects/Bulldozer-price-prediction/data/TrainAndValid.csv"
    df = ingest_df(data_path)
    X_train, X_test, y_train, y_test = clean_df(df)
    model = train_model(X_train, X_test, y_train, y_test)
    r2_score, rmse = evaluate_model(model, X_test, y_test)

# Run the Prefect Flow
if __name__ == "__main__":
    my_flow()
Projet MLOps

Ici, vous pouvez voir tous les tableaux de bord de flux de rodage dans Prefect

Projet MLOps

Conclusion

La mise en œuvre de MLOps de bout en bout permet aux organisations de faire évoluer de manière fiable les solutions d'apprentissage automatique en production. Ce didacticiel a démontré un flux de travail automatisé pour prédire l'autonomie des véhicules électriques à l'aide de bibliothèques open source telles que Prefect et CometML.

Les principaux points forts du projet comprennent :

  • L'orchestration d'un pipeline ML avec Prefect implique de gérer des étapes allant de l'ingestion de données, au prétraitement, au développement de modèles, à l'évaluation et à la surveillance.
  • Suivi des expériences dans CometML pour visualiser les métriques du modèle telles que les scores RMSE et R2 au fil du temps à des fins de comparaison.
  • Surveillance des exécutions de flux de travail dans Prefect Cloud affichant la durée des tâches.

Dans l'ensemble, cette vitrine met en œuvre les meilleures pratiques de la science des données en matière d'automatisation, de reproductibilité et de surveillance dans un flux de travail structuré essentiel pour les systèmes ML du monde réel. L'extension et l'opérationnalisation en production peuvent tirer davantage parti de l'évolutivité de Prefect dans la gestion des flux à grande échelle sur une infrastructure distribuée.

Points clés à retenir

Voici quelques points clés à retenir de ce didacticiel MLOps de bout en bout :

  • La mise en œuvre de MLOps améliore la collaboration entre les data scientists et l'informatique grâce aux pratiques d'automatisation et de DevOps.
  • Prefect permet la création de pipelines de données et de flux de travail robustes pour ingérer, traiter, former et évaluer des modèles.
  • CometML fournit un moyen simple de suivre les expériences de ML avec journalisation et visualisation.
  • L'orchestration du cycle de vie du ML de bout en bout garantit que les modèles restent pertinents à mesure que de nouvelles données arrivent.
  • La surveillance des exécutions de flux de travail permet d'identifier et de résoudre rapidement les pannes.
  • MLOps permet une expérimentation plus rapide en simplifiant le recyclage et le déploiement de modèles mis à jour.

Questions fréquemment posées

T1. Qu’est-ce que MLOps ?

Rép. MLOps pour l'apprentissage automatique est un ensemble de pratiques qui visent à rationaliser et automatiser le cycle de vie de l'apprentissage automatique de bout en bout, y compris le développement, le déploiement et la maintenance de modèles, afin d'améliorer la collaboration et l'efficacité des équipes de science des données et d'exploitation.

Q2. Qu'est-ce que Préfet ?

Rép. Prefect est une bibliothèque Python open source pour la gestion des flux de travail. Il permet la création, la planification et l'orchestration de flux de travail et de tâches de données couramment utilisés dans les pipelines de science des données et d'automatisation. Il simplifie les flux de travail complexes, en mettant l'accent sur la flexibilité, la fiabilité et la surveillance.

Q3. Qu’est-ce que CometML ?

Rép. CometML est une plateforme d'expérimentation et de collaboration en matière d'apprentissage automatique. Il fournit des outils pour suivre, comparer et optimiser les expériences d'apprentissage automatique, permettant aux équipes d'enregistrer et de partager les détails, les mesures et les visualisations des expériences afin d'améliorer le développement de modèles et la collaboration.

Q4. A quoi sert Préfet ?

Rép. Prefect est utilisé pour la gestion des flux de travail dans la science des données et l'automatisation. Il permet de rationaliser et d'orchestrer des flux de données complexes, facilitant ainsi la conception, la planification et la surveillance cohérente des tâches. Prefect est couramment utilisé pour le traitement des données, la formation de modèles d'apprentissage automatique et d'autres opérations centrées sur les données, fournissant un cadre pour créer, exécuter et gérer efficacement les flux de travail.

Q5. Quelle est la différence entre MLflow et Comet ?

Rép. MLflow est une plate-forme open source permettant de gérer le cycle de vie de l'apprentissage automatique de bout en bout, y compris le suivi des expériences, le conditionnement du code en exécutions reproductibles, ainsi que le partage et le déploiement de modèles. Comet est une plate-forme d'expérimentation et de collaboration en matière d'apprentissage automatique, axée sur le suivi des expériences, les visualisations et les fonctionnalités de collaboration. Il fournit une plateforme centralisée permettant aux équipes d'analyser et de partager les résultats. Bien que les deux prennent en charge le suivi des expériences, MLflow offre des fonctionnalités supplémentaires de packaging de modèles et de déploiement, tandis que Comet met l'accent sur les capacités de collaboration et de visualisation.

Les médias présentés dans cet article n'appartiennent pas à Analytics Vidhya et sont utilisés à la discrétion de l'auteur.

About the author

smirow

Leave a Comment