Création d’une recette à l’aide de notebooks Jupyter

Ce tutoriel se déroulera en deux temps. Tout d’abord, vous créerez un modèle d’apprentissage automatique à l’aide d’un modèle dans JupyterLab Notebook. Next, you will exercise the notebook to recipe workflow within JupyterLab to create a recipe within Data Science Workspace.

Concepts présentés :

  • Recettes : une recette est le terme utilisé par Adobe pour désigner une spécification de modèle. Il s’agit d’un conteneur de niveau supérieur qui représente un apprentissage automatique spécifique, un algorithme d’intelligence artificielle ou un ensemble d’algorithmes, une logique de traitement et la configuration nécessaires pour créer et exécuter un modèle formé et ainsi aider à résoudre des problèmes d’entreprise spécifiques.
  • Modèle : un modèle est une instance d’une recette d’apprentissage automatique formée à l’aide de données historiques et de configurations dans le but de résoudre un cas d’usage commercial.
  • Formation : la formation est le processus de formation de modèles et de connaissances à partir de données étiquetées.
  • Notation : la notation est le processus de génération d’informations à partir de données en utilisant un modèle formé.

Get started with the JupyterLab notebook environment

Creating a recipe from scratch can be done within Data Science Workspace. Pour début, accédez à Adobe Experience Platform et cliquez sur l'onglet Ordinateurs portables à gauche. Créez un bloc-notes en sélectionnant le modèle Créateur de recettes dans le JupyterLab Launcher.

The Recipe Builder notebook allows you to run training and scoring runs inside the notebook. Vous avez ainsi la possibilité d’apporter des modifications à leurs méthodes de train() et de score() entre deux expériences en cours d’exécution sur les données de formation et de notation. Once you are happy with the outputs of the training and scoring, you can create a recipe to be used in Data Science Workspace using the notebook to recipe functionality built in to the Recipe Builder notebook.

NOTE

Le notebook Recipe Builder prend en charge l’utilisation de tous les formats de fichier, mais la fonctionnalité Create Recipe ne prend actuellement en charge que Python.

Lorsque vous cliquez sur le bloc-notes du Générateur de recettes depuis le lanceur, le bloc-notes s'ouvre dans l'onglet. Le modèle utilisé dans le notebook est la recette Python de prévision des ventes au détail, qui se trouve également dans ce référentiel public.

You will notice that in the toolbar there are three additional actions namely – Train, Score, and Create Recipe. These icons only appear in the Recipe Builder notebook. Vous trouverez plus d’informations sur ces actions dans la section Formation et notation après avoir créé votre recette dans le notebook.

Modification des fichiers de recette

Pour apporter des modifications aux fichiers de recette, accédez dans Jupyter à la cellule correspondant au chemin du fichier. Par exemple, si vous souhaitez apporter des modifications à evaluator.py, recherchez %%writefile demo-recipe/evaluator.py.

Effectuez les modifications nécessaires dans la cellule. Lorsque vous avez terminé, exécutez simplement la cellule. La commande %%writefile filename.py écrira le contenu de la cellule dans filename.py. Vous devrez exécuter manuellement la cellule pour chaque fichier avec modifications.

NOTE

Vous devriez exécuter les cellules manuellement lorsque cela est nécessaire.

Prise en main du notebook Recipe Builder

Now that you know the basics for the JupyterLab notebook environment, you can begin looking at the files that make up a machine learning model recipe. Les fichiers concernés sont présentés ici :

Fichier des exigences

Le fichier des exigences sert à définir les bibliothèques supplémentaires que vous souhaitez utiliser dans la recette. En cas de dépendance, vous pouvez spécifier le numéro de version. To look for additional libraries, visit anaconda.org. Pour savoir comment formater le fichier de configuration requise, visitez Conda. Voici une liste non exhaustive des principales bibliothèques déjà utilisées :

python=3.6.7
scikit-learn
pandas
numpy
data_access_sdk_python
NOTE

Les bibliothèques ou versions spécifiques que vous ajoutez peuvent être incompatibles avec les bibliothèques mentionnées ci-dessus. De plus, si vous choisissez de créer manuellement un fichier d’environnement, le champ name n’est pas autorisé à être remplacé.

Fichiers de configuration

Les fichiers de configuration, training.conf et scoring.conf, servent à spécifier les jeux de données que vous souhaitez utiliser pour la formation et la notation, et à ajouter des hyperparamètres. Les configurations pour la formation et la notation sont distinctes.

Les utilisateurs doivent renseigner les variables suivantes avant d’exécuter la formation et la notation :

  • trainingDataSetId
  • ACP_DSW_TRAINING_XDM_SCHEMA
  • scoringDataSetId
  • ACP_DSW_SCORING_RESULTS_XDM_SCHEMA
  • scoringResultsDataSetId

Pour rechercher les identifiants du jeu de données et du schéma, accédez dans les notebooks à l’onglet Données de la barre de navigation de gauche (sous l’icône de dossier).

Vous trouverez les mêmes informations sur Adobe Experience Platform sous les onglets Schéma et Jeu de données.

Les paramètres de configuration suivants sont définis par défaut lorsque vous accédez aux données :

  • ML_FRAMEWORK_IMS_USER_CLIENT_ID
  • ML_FRAMEWORK_IMS_TOKEN
  • ML_FRAMEWORK_IMS_ML_TOKEN
  • ML_FRAMEWORK_IMS_TENANT_ID

Chargeur de données d’apprentissage

Le chargeur de données d’apprentissage est destiné à instancier les données utilisées pour créer le modèle d’apprentissage automatique. En règle générale, le chargeur de données d’apprentissage accomplit deux tâches :

  • Load data from Platform
  • Préparation des données et ingénierie des fonctionnalités

Les deux prochaines sections traiteront du chargement et de la préparation des données.

Chargement des données

Cette étape utilise le cadre de données pandas. Data can be loaded from files in Adobe Experience Platform using either the Platform SDK (platform_sdk), or from external sources using pandas' read_csv() or read_json() functions.

NOTE

Dans le notebook Recipe Builder, les données sont chargées via le chargeur de données platform_sdk.

Platform SDK

Pour un tutoriel détaillé sur l’utilisation du chargeur de données platform_sdk, consultez le guide SDK Platform. Ce tutoriel fournit des informations sur l’authentification de création, la lecture et l’écriture basiques de données.

Sources externes

Cette section vous explique comment importer un fichier JSON ou CSV dans un objet pandas. La documentation officielle de la bibliothèque pandas se trouve ici :

Tout d’abord, voici un exemple d’importation d’un fichier CSV. L’argument data est le chemin d’accès au fichier CSV. Cette variable a été importée à partir de configProperties de la section précédente.

df = pd.read_csv(data)

Vous pouvez également réaliser l’importation à partir d’un fichier JSON. L’argument data est le chemin d’accès au fichier CSV. Cette variable a été importée à partir de configProperties de la section précédente.

df = pd.read_json(data)

Vos données se trouvent maintenant dans l’objet « cadre de données » et peuvent être analysées et manipulées dans la section suivante.

A partir du SDK de plate-forme

Vous pouvez charger des données à l’aide du SDK de plate-forme. La bibliothèque peut être importée en haut de la page en incluant la ligne :

from platform_sdk.dataset_reader import DatasetReader

Nous utilisons ensuite la méthode load() pour récupérer le jeu de données d’apprentissage à partir de trainingDataSetId comme précisé dans notre fichier de configuration (recipe.conf).

def load(config_properties):
    print("Training Data Load Start")

    #########################################
    # Load Data
    #########################################    
    client_context = get_client_context(config_properties)
    
    dataset_reader = DatasetReader(client_context, config_properties['trainingDataSetId'])
    
    timeframe = config_properties.get("timeframe")
    tenant_id = config_properties.get("tenant_id")
NOTE

As mentioned in the Configuration File section, the following configuration parameters are set for you when you access data from Experience Platform using client_context:

  • ML_FRAMEWORK_IMS_USER_CLIENT_ID
  • ML_FRAMEWORK_IMS_TOKEN
  • ML_FRAMEWORK_IMS_ML_TOKEN
  • ML_FRAMEWORK_IMS_TENANT_ID

Maintenant que vous disposez de vos données, vous pouvez commencer leur préparation ainsi que la conception des fonctionnalités.

Préparation des données et ingénierie des fonctionnalités

Une fois les données chargées, elles sont préparées puis partagées entre les jeux de données train et val. Voici un échantillon de code :

#########################################
# Data Preparation/Feature Engineering
#########################################
dataframe.date = pd.to_datetime(dataframe.date)
dataframe['week'] = dataframe.date.dt.week
dataframe['year'] = dataframe.date.dt.year

dataframe = pd.concat([dataframe, pd.get_dummies(dataframe['storeType'])], axis=1)
dataframe.drop('storeType', axis=1, inplace=True)
dataframe['isHoliday'] = dataframe['isHoliday'].astype(int)

dataframe['weeklySalesAhead'] = dataframe.shift(-45)['weeklySales']
dataframe['weeklySalesLag'] = dataframe.shift(45)['weeklySales']
dataframe['weeklySalesDiff'] = (dataframe['weeklySales'] - dataframe['weeklySalesLag']) / dataframe['weeklySalesLag']
dataframe.dropna(0, inplace=True)

dataframe = dataframe.set_index(dataframe.date)
dataframe.drop('date', axis=1, inplace=True) 

Dans cet exemple, le jeu de données d’origine a subi cinq opérations :

  • L’ajout de colonnes weeket year
  • La conversion de storeType en variable indicatrice
  • La conversion de isHoliday en variable numérique
  • Le décalage de weeklySales pour obtenir la valeur des ventes futures et antérieures
  • Le partage des données par date entre les jeux de données train et val

First, week and year columns are created and the original date column converted to Python datetime. Les valeurs Semaine et Année sont extraites de l’objet de datetime.

Ensuite, storeType est transformé en trois colonnes représentant les trois types de magasin différents, (A, B et C). Chacune contient une valeur booléenne qui indique quel storeType est vrai. La colonne storeType sera supprimée.

De même, weeklySales change la valeur booléenne isHoliday en une représentation numérique (un ou zéro).

Ces données sont partagées entre les jeux de données train et val.

La fonction load() doit être complétée avec les jeux de données train et val en tant que sortie.

Chargeur de données de notation

La procédure de chargement des données pour notation est similaire à celle de chargement des données d’apprentissage de la fonction split(). Nous utilisons le SDK Data Access pour charger les données à partir de scoringDataSetId dans notre fichier recipe.conf.

def load(config_properties):

    print("Scoring Data Load Start")

    #########################################
    # Load Data
    #########################################
    client_context = get_client_context(config_properties)

    dataset_reader = DatasetReader(client_context, config_properties['scoringDataSetId'])
    timeframe = config_properties.get("timeframe")
    tenant_id = config_properties.get("tenant_id")

Une fois les données chargées, la préparation des données et la conception des fonctionnalités sont effectuées.

    #########################################
    # Data Preparation/Feature Engineering
    #########################################
    if '_id' in dataframe.columns:
        #Rename columns to strip tenantId
        dataframe = dataframe.rename(columns = lambda x : str(x)[str(x).find('.')+1:])
        #Drop id, eventType and timestamp
        dataframe.drop(['_id', 'eventType', 'timestamp'], axis=1, inplace=True)

    dataframe.date = pd.to_datetime(dataframe.date)
    dataframe['week'] = dataframe.date.dt.week
    dataframe['year'] = dataframe.date.dt.year

    dataframe = pd.concat([dataframe, pd.get_dummies(dataframe['storeType'])], axis=1)
    dataframe.drop('storeType', axis=1, inplace=True)
    dataframe['isHoliday'] = dataframe['isHoliday'].astype(int)

    dataframe['weeklySalesAhead'] = dataframe.shift(-45)['weeklySales']
    dataframe['weeklySalesLag'] = dataframe.shift(45)['weeklySales']
    dataframe['weeklySalesDiff'] = (dataframe['weeklySales'] - dataframe['weeklySalesLag']) / dataframe['weeklySalesLag']
    dataframe.dropna(0, inplace=True)

    dataframe = dataframe.set_index(dataframe.date)
    dataframe.drop('date', axis=1, inplace=True)

    print("Scoring Data Load Finish")

    return dataframe

Puisque le but de notre modèle est de prédire les futures ventes hebdomadaires, vous devrez créer un jeu de données de notation servant à évaluer les performances de prédiction du modèle.

Ce notebook Recipe Builder le fait en décalant nos ventes hebdomadaires de sept jours vers l’avant. Vous remarquerez qu’il existe des mesures pour 45 magasins par semaine : vous pouvez donc déplacer les valeurs weeklySales de 45 jeux de données vers l’avant dans une nouvelle colonne intitulée weeklySalesAhead.

df['weeklySalesAhead'] = df.shift(-45)['weeklySales']

De même, vous pouvez créer une colonne weeklySalesLag en reculant de 45. Grâce à cela, vous pouvez également calculer la différence entre les ventes hebdomadaires et les stocker dans la colonne weeklySalesDiff.

df['weeklySalesLag'] = df.shift(45)['weeklySales']
df['weeklySalesDiff'] = (df['weeklySales'] - df['weeklySalesLag']) / df['weeklySalesLag']

Puisque vous décalez les points de données weeklySales de 45 jeux de données vers l’avant et de 45 jeux de données vers l’arrière pour créer de nouvelles colonnes, les 45 premiers et derniers points de données auront des valeurs NaN. Vous pouvez supprimer ces points de notre jeu de données en utilisant la fonction df.dropna() qui supprime toutes les lignes comportant des valeurs NaN.

df.dropna(0, inplace=True)

La fonction load() de votre chargeur de données de notation doit comprendre le jeu de données de notation comme sortie.

Fichier Pipeline

Le fichier pipeline.py inclut la logique de formation et de notation.

Formation

L’objectif de la formation est de créer un modèle à l’aide des fonctionnalités et des étiquettes présentes dans votre jeu de données d’apprentissage.

NOTE

Les Fonctionnalités font référence à la variable d’entrée utilisée par le modèle d’apprentissage automatique pour prédire les étiquettes.

La fonction train() doit inclure le modèle de formation et renvoyer le modèle formé. Vous trouverez quelques exemples de différents modèles dans la documentation du guide d’utilisation de scikit-learn.

Après avoir choisi votre modèle de formation, vous ajusterez votre jeu de données d’apprentissage x et y au modèle, et la fonction renverra le modèle formé. En voici un exemple :

def train(configProperties, data):

    print("Train Start")

    #########################################
    # Extract fields from configProperties
    #########################################
    learning_rate = float(configProperties['learning_rate'])
    n_estimators = int(configProperties['n_estimators'])
    max_depth = int(configProperties['max_depth'])


    #########################################
    # Fit model
    #########################################
    X_train = data.drop('weeklySalesAhead', axis=1).values
    y_train = data['weeklySalesAhead'].values

    seed = 1234
    model = GradientBoostingRegressor(learning_rate=learning_rate,
                                      n_estimators=n_estimators,
                                      max_depth=max_depth,
                                      random_state=seed)

    model.fit(X_train, y_train)

    print("Train Complete")

    return model

Il faut souligner que selon votre application, vous aurez des arguments dans votre fonction GradientBoostingRegressor(). xTrainingDataset devrait contenir vos fonctionnalités utilisées pour la formation, tandis que yTrainingDataset devrait contenir vos étiquettes.

Notation

La fonction score() doit contenir l’algorithme de notation et renvoyer une mesure pour indiquer le degré de réussite du modèle. La fonction score() utilise les étiquettes des jeux de données de notation et le modèle formé pour générer un ensemble de fonctionnalités prédites. Ces valeurs prédites sont ensuite comparées aux fonctionnalités réelles du jeu de données de notation. Dans cet exemple, la fonction score() utilise le modèle formé pour prédire les fonctionnalités à l’aide des étiquettes du jeu de données de notation. Les fonctionnalités prédites sont renvoyées.

def score(configProperties, data, model):

    print("Score Start")

    X_test = data.drop('weeklySalesAhead', axis=1).values
    y_test = data['weeklySalesAhead'].values
    y_pred = model.predict(X_test)

    data['prediction'] = y_pred
    data = data[['store', 'prediction']].reset_index()
    data['date'] = data['date'].astype(str)

    print("Score Complete")

    return data

Fichier Evaluator

Le fichier evaluator.py contient la logique de la manière dont vous souhaitez évaluer votre recette formée ainsi que la manière dont vos données d’apprentissage doivent être fractionnées. Dans l’exemple de ventes au détail, la logique de chargement et de préparation des données d’apprentissage sera incluse. Nous allons passer en revue les deux sections ci-dessous.

Fractionnement du jeu de données

La phase de préparation des données pour la formation nécessite de fractionner le jeu de données à utiliser pour la formation et les tests. Ces données val seront utilisées implicitement pour évaluer le modèle après sa formation. Il s’agit d’un processus distinct de celui de notation.

Cette section montre la fonction split() qui chargera d’abord les données dans le notebook, puis les nettoiera en supprimant les colonnes inutiles dans le jeu de données. A partir de là, vous pourrez concevoir les fonctionnalités, ce qui consiste à créer des fonctionnalités utiles supplémentaires à partir des fonctionnalités brutes existantes dans les données. Vous trouverez ci-dessous un exemple commenté de ce processus.

La fonction split() est illustrée ci-dessous. La base de données fournie dans l’argument sera partagée entre les variables train et val à renvoyer.

def split(self, configProperties={}, dataframe=None):
    train_start = '2010-02-12'
    train_end = '2012-01-27'
    val_start = '2012-02-03'
    train = dataframe[train_start:train_end]
    val = dataframe[val_start:]

    return train, val

Évaluation du modèle formé

La fonction evaluate() est exécutée après la formation du modèle et renvoie une mesure pour indiquer le degré de réussite du modèle. La fonction evaluate() utilise les étiquettes des jeux de données de test et le modèle formé pour prédire un ensemble de fonctionnalités. Ces valeurs prédites sont ensuite comparées aux fonctionnalités réelles du jeu de données de test. Voici quelques-uns des algorithmes de notation courants :

La fonction evaluate() de l’échantillon de ventes au détail est illustrée ci-dessous :

def evaluate(self, data=[], model={}, configProperties={}):
    print ("Evaluation evaluate triggered")
    val = data.drop('weeklySalesAhead', axis=1)
    y_pred = model.predict(val)
    y_actual = data['weeklySalesAhead'].values
    mape = np.mean(np.abs((y_actual - y_pred) / y_actual))
    mae = np.mean(np.abs(y_actual - y_pred))
    rmse = np.sqrt(np.mean((y_actual - y_pred) ** 2))

    metric = [{"name": "MAPE", "value": mape, "valueType": "double"},
                {"name": "MAE", "value": mae, "valueType": "double"},
                {"name": "RMSE", "value": rmse, "valueType": "double"}]

    return metric

Vous remarquerez que la fonction renvoie un objet metric contenant un tableau de mesures d’évaluation. Ces mesures serviront à évaluer les performances du modèle formé.

Fichier Data Saver

Le fichier datasaver.py contient la fonction save() qui enregistre votre prédiction lors du test de notation. The save() function will take your prediction and using Experience Platform Catalog APIs, write the data to the scoringResultsDataSetId you specified in your scoring.conf file.

L’exemple utilisé dans l’échantillon de recette des ventes au détail est illustré ici. Vous remarquez l’utilisation de la bibliothèque DataSetWriter pour écrire des données vers Platform :

from data_access_sdk_python.writer import DataSetWriter

def save(configProperties, prediction):
    print("Datasaver Start")
    print("Setting up Writer")

    catalog_url = "https://platform.adobe.io/data/foundation/catalog"
    ingestion_url = "https://platform.adobe.io/data/foundation/import"

    writer = DataSetWriter(catalog_url=catalog_url,
                           ingestion_url=ingestion_url,
                           client_id=configProperties['ML_FRAMEWORK_IMS_USER_CLIENT_ID'],
                           user_token=configProperties['ML_FRAMEWORK_IMS_TOKEN'],
                           service_token=configProperties['ML_FRAMEWORK_IMS_ML_TOKEN'])

    print("Writer Configured")

    writer.write(data_set_id=configProperties['scoringResultsDataSetId'],
                 dataframe=prediction,
                 ims_org=configProperties['ML_FRAMEWORK_IMS_TENANT_ID'])

    print("Write Done")
    print("Datasaver Finish")
    print(prediction)

Formation et notation

Lorsque vous avez terminé de modifier votre notebook et que vous souhaitez former votre recette, vous pouvez cliquer sur les boutons associés en haut de la barre pour créer une session de formation dans la cellule. Lorsque vous cliquez sur le bouton, un journal des commandes et des sorties issues du script de formation s’affichera dans le notebook (sous la cellule evaluator.py). Conda installe d’abord toutes les dépendances, puis la formation commence.

Remarque : vous devez exécuter la formation au moins une fois avant de pouvoir exécuter la notation. En cliquant sur le bouton Exécuter la notation, vous obtiendrez la notation du modèle formé généré pendant la formation. Le script de notation apparaîtra sous datasaver.py.

À des fins de débogage, si vous souhaitez afficher la sortie masquée, ajoutez debug à la fin de la cellule de sortie et exécutez-la de nouveau.

Création d’une recette

When you are done editing the recipe and satisfied with the training/scoring output, you can create a recipe from the notebook by pressing Create Recipe in the top-right navigation.

Après avoir appuyé sur le bouton, vous êtes invité à saisir un nom de recette. Ce nom représente la recette réelle créée sur Platform.

Une fois que vous avez appuyé sur OK, vous pourrez accéder à la nouvelle recette dans Adobe Experience Platform. Vous pouvez cliquer sur le bouton Voir les recettes pour accéder à l’onglet Recettes sous Modèles ML.

Voici l’aspect de la recette une fois le processus terminé :

CAUTION
  • Ne supprimer aucune cellule de fichier
  • Ne pas modifier la ligne %%writefile en haut des cellules de fichier
  • Ne pas créer plusieurs recettes dans différents cahiers simultanément

Étapes suivantes

En terminant ce tutoriel, vous avez appris à créer un modèle d’apprentissage automatique dans le notebook Recipe Builder. Vous avez également appris à utiliser le notebook pour recevoir le workflow dans le notebook afin de créer une recette dans Data Science Workspace.

To continue learning how to work with resources within Data Science Workspace, please visit the Data Science Workspace recipes and models dropdown.

Ressources supplémentaires

La vidéo suivante est conçue pour vous aider à comprendre comment créer et déployer des modèles.

Sur cette page