Gestion des notebooks d’apprentissage automatique en temps réel (Alpha)

IMPORTANT

L’apprentissage automatique en temps réel n’est pas encore disponible pour tous les utilisateurs. Cette fonctionnalité est en version alpha et est encore en cours de test. Ce document peut faire l’objet de modifications.

Le guide suivant décrit les étapes nécessaires à la création d’une application d’apprentissage automatique en temps réel. En utilisant l’Adobe Modèle de notebook Python ML en temps réel, ce guide couvre la formation d’un modèle, la création d’un DSL, la publication de DSL sur Edge et la notation de la requête. Au fur et à mesure que vous passez à la mise en oeuvre de votre modèle d’apprentissage automatique en temps réel, vous devez modifier le modèle en fonction des besoins de votre jeu de données.

Création d’un notebook d’apprentissage automatique en temps réel

Dans l’interface utilisateur de Adobe Experience Platform, sélectionnez Notebooks dans Data Science. Ensuite, sélectionnez JupyterLab et laissez un certain temps à l’environnement pour le chargement.

Ouvrez JupyterLab.

Le lanceur JupyterLab s’affiche. Faites défiler l’écran jusqu’à Apprentissage automatique en temps réel et sélectionnez le notebook ML en temps réel. Un modèle s’ouvre, contenant des exemples de cellules de notebook avec un exemple de jeu de données.

python vide

Importation et découverte de noeuds

Commencez par importer tous les packages requis pour votre modèle. Assurez-vous que tout module que vous prévoyez d’utiliser pour la création de noeuds est importé.

REMARQUE

La liste des imports peut différer en fonction du modèle que vous souhaitez faire. Cette liste va changer à mesure que de nouveaux noeuds seront ajoutés au fil du temps. Reportez-vous au guide de référence des noeuds pour obtenir la liste complète des noeuds disponibles.

from pprint import pprint
import pandas as pd
import numpy as np
import json
import uuid
from shutil import copyfile
from pathlib import Path
from datetime import date, datetime, timedelta
from platform_sdk.dataset_reader import DatasetReader

from rtml_nodelibs.nodes.standard.preprocessing.json_to_df import JsonToDataframe
from rtml_sdk.edge.utils import EdgeUtils
from rtml_sdk.graph.utils import GraphBuilder
from rtml_nodelibs.nodes.standard.ml.onnx import ONNXNode
from rtml_nodelibs.core.nodefactory import NodeFactory as nf
from rtml_nodelibs.nodes.standard.preprocessing.pandasnode import Pandas
from rtml_nodelibs.nodes.standard.preprocessing.one_hot_encoder import OneHotEncoder
from rtml_nodelibs.nodes.standard.ml.artifact_utils import ModelUpload
from rtml_nodelibs.core.nodefactory import NodeFactory as nf
from rtml_nodelibs.core.datamsg import DataMsg

La cellule de code suivante imprime une liste de noeuds disponibles.

# Discover Nodes
pprint(nf.discover_nodes())

liste des notes

Formation à un modèle d’apprentissage automatique en temps réel

À l’aide de l’une des options suivantes, vous allez écrire du code Python pour lire, prétraiter et analyser les données. Ensuite, vous devez entraîner votre propre modèle ML, le sérialiser au format ONNX, puis le charger dans la boutique de modèles d’apprentissage automatique en temps réel.

Formation de votre propre modèle

Commencez par charger vos données d’apprentissage.

REMARQUE

Dans le modèle ML en temps réel, le jeu de données CSV d’assurance automobile est récupéré à partir de Github.

Chargement des données d’entraînement

Si vous souhaitez utiliser un jeu de données dans Adobe Experience Platform, annulez la mise en commentaire de la cellule ci-dessous. Ensuite, vous devez remplacer DATASET_ID par la valeur appropriée.

jeu de données rtml

Pour accéder à un jeu de données dans votre notebook JupyterLab, sélectionnez l’onglet Données dans le volet de navigation de gauche de JupyterLab. Les répertoires Jeux de données et Schémas s’affichent. Sélectionnez Jeux de données et cliquez avec le bouton droit, puis sélectionnez l’option Explorer les données dans Notebook dans le menu déroulant du jeu de données que vous souhaitez utiliser. Une entrée de code exécutable s’affiche au bas du notebook. Cette cellule contient votre dataset_id.

accès aux jeux de données

Une fois l’opération terminée, cliquez avec le bouton droit de la souris et supprimez la cellule que vous avez générée au bas du notebook.

Propriétés de formation

En utilisant le modèle fourni, modifiez l’une des propriétés d’entraînement dans config_properties.

config_properties = {
    "train_records_limit":1000000,
    "n_estimators": "80",
    "max_depth": "5",
    "ten_id": "_experienceplatform"  
}

Préparation de votre modèle

À l’aide du modèle ML en temps réel , vous devez analyser, pré-traiter, former et évaluer votre modèle ML. Pour ce faire, appliquez des transformations de données et créez un pipeline de formation.

Conversion des données

La cellule ML en temps réel modèles Transformations de données doit être modifiée pour fonctionner avec votre propre jeu de données. Cela implique généralement de renommer les colonnes, le cumul des données et la préparation des données/conception des fonctionnalités.

REMARQUE

L’exemple suivant a été condensé à des fins de lisibilité à l’aide de [ ... ]. Consultez et développez la section de transformation des données de modèles ML en temps réel pour la cellule de code complète.

df1.rename(columns = {config_properties['ten_id']+'.identification.ecid' : 'ecid',
                     [ ... ]}, inplace=True)
df1 = df1[['ecid', 'km', 'cartype', 'age', 'gender', 'carbrand', 'leasing', 'city', 
       'country', 'nationality', 'primaryuser', 'purchase', 'pricequote', 'timestamp']]
print("df1 shape 1", df1.shape)
#########################################
# Data Rollup
######################################### 
df1['timestamp'] = pd.to_datetime(df1.timestamp)
df1['hour'] = df1['timestamp'].dt.hour.astype(int)
df1['dayofweek'] = df1['timestamp'].dt.dayofweek

df1.loc[(df1['purchase'] == 'yes'), 'purchase'] = 1
df1.purchase.fillna(0, inplace=True)
df1['purchase'] = df1['purchase'].astype(int)

[ ... ]

print("df1 shape 2", df1.shape)

#########################################
# Data Preparation/Feature Engineering
#########################################      

df1['carbrand'] = df1['carbrand'].str.lower()
df1['country'] = df1['country'].str.lower()
df1.loc[(df1['carbrand'] == 'vw'), 'carbrand'] = 'volkswagen'

[ ... ]

df1['age'].fillna(df1['age'].median(), inplace=True)
df1['gender'].fillna('notgiven', inplace=True)

[ ... ]

df1['city'] = df1.groupby('country')['city'].transform(lambda x : x.fillna(x.mode()))
df1.dropna(subset = ['pricequote'], inplace=True)
print("df1 shape 3", df1.shape)
print(df1)

#grouping
grouping_cols = ['carbrand', 'cartype', 'city', 'country']

for col in grouping_cols:
    df_idx = pd.DataFrame(df1[col].value_counts().head(6))

    def grouping(x):
        if x in df_idx.index:
            return x
        else:
            return "Others"
    df1[col] = df1[col].apply(lambda x: grouping(x))

def age(x):
    if x < 20:
        return "u20"
    elif x > 19 and x < 29:
    [ ... ]
    else: 
        return "Others"

df1['age'] = df1['age'].astype(int)
df1['age_bucket'] = df1['age'].apply(lambda x: age(x))

df_final = df1[['hour', 'dayofweek','age_bucket', 'gender', 'city',  
   'country', 'carbrand', 'cartype', 'leasing', 'pricequote', 'purchase']]
print("df final", df_final.shape)

cat_cols = ['age_bucket', 'gender', 'city', 'dayofweek', 'country', 'carbrand', 'cartype', 'leasing']
df_final = pd.get_dummies(df_final, columns = cat_cols)

Exécutez la cellule fournie pour afficher un exemple de résultat. La table de sortie renvoyée par le jeu de données carinsurancedataset.csv renvoie les modifications que vous avez définies.

Exemple de transformations de données

Pipeline de formation

Vous devez ensuite créer le pipeline d’entraînement. Cela ressemblera à tout autre fichier de pipeline d’entraînement, sauf que vous devez convertir et générer un fichier ONNX.

Modifiez le modèle à l’aide des transformations de données définies dans votre cellule précédente. Le code ci-dessous est utilisé pour générer un fichier ONNX dans votre pipeline de fonctionnalités. Consultez le modèle ML en temps réel pour la cellule de code de pipeline complète.

#for generating onnx
def generate_onnx_resources(self):        
    install_dir = os.path.expanduser('~/my-workspace')
    print("Generating Onnx")
        
    from skl2onnx import convert_sklearn
    from skl2onnx.common.data_types import FloatTensorType
        
    # ONNX-ification
    initial_type = [('float_input', FloatTensorType([None, self.feature_len]))]

    print("Converting Model to Onnx")
    onx = convert_sklearn(self.model, initial_types=initial_type)
             
    with open("model.onnx", "wb") as f:
        f.write(onx.SerializeToString())
            
    print("Model onnx created")

Une fois que vous avez terminé votre pipeline de formation et modifié vos données par le biais de transformations de données, utilisez la cellule suivante pour exécuter la formation.

model = train(config_properties, df_final)

Génération et chargement d’un modèle ONNX

Une fois que vous avez terminé une opération de formation réussie, vous devez générer un modèle ONNX et charger le modèle formé dans la boutique de modèles d’apprentissage automatique en temps réel. Après avoir exécuté les cellules suivantes, votre modèle ONNX apparaît dans le rail de gauche à côté de tous les autres notebooks.

import os
import skl2onnx, subprocess

model.generate_onnx_resources()
REMARQUE

Modifiez la valeur de chaîne model_path (model.onnx) pour modifier le nom de votre modèle.

model_path = "model.onnx"
REMARQUE

La cellule suivante n’est ni modifiable, ni modifiable. Elle est également nécessaire au fonctionnement de votre application d’apprentissage automatique en temps réel.

model = ModelUpload(params={'model_path': model_path})
msg_model = model.process(None, 1)
model_id = msg_model.model['model_id']
 
print("Model ID : ", model_id)

Modèle ONNX

Téléchargement de votre propre modèle ONNX préentraîné

À l’aide du bouton Télécharger situé dans les notebooks JupyterLab, chargez votre modèle ONNX préentraîné dans l’environnement des notebooks Data Science Workspace.

icône de chargement

Ensuite, modifiez la valeur de chaîne model_path dans le notebook ML en temps réel pour qu’elle corresponde à votre nom de modèle ONNX. Une fois l’opération terminée, exécutez la cellule Définir le chemin d’accès au modèle, puis exécutez la cellule Télécharger votre modèle vers le magasin de modèles RTML. L’emplacement de votre modèle et l’identifiant du modèle sont tous deux renvoyés dans la réponse en cas de réussite.

charger son propre modèle

Création d’un langage spécifique au domaine (DSL)

Cette section décrit la création d’un DSL. Vous allez créer les noeuds qui incluent tout prétraitement des données avec le noeud ONNX. Ensuite, un graphique DSL est créé à l’aide des noeuds et des bords. Contour des noeuds de connexion à l’aide du format basé sur un tuple (node_1, node_2). Le graphique ne doit pas comporter de cycles.

IMPORTANT

L’utilisation du noeud ONNX est obligatoire. Sans le noeud ONNX, l’application échoue.

Création de noeuds

REMARQUE

Il est probable que vous ayez plusieurs noeuds en fonction du type de données utilisé. L’exemple suivant illustre un seul noeud dans le modèle ML en temps réel. Consultez la section Modèles ML en temps réel Création de noeuds pour la cellule de code complète.

Le noeud Pandas ci-dessous utilise "import": "map" pour importer le nom de la méthode sous la forme d’une chaîne dans les paramètres, suivie de la saisie des paramètres sous la forme d’une fonction de carte. L’exemple ci-dessous utilise {'arg': {'dataLayerNull': 'notgiven', 'no': 'no', 'yes': 'yes', 'notgiven': 'notgiven'}}. Une fois la carte en place, vous avez la possibilité de définir inplace sur True ou False. Définissez inplace sur True ou False selon que vous souhaitez appliquer ou non la transformation. Par défaut, "inplace": False crée une nouvelle colonne. La prise en charge d’un nouveau nom de colonne doit être ajoutée dans une version ultérieure. La dernière ligne cols peut être un nom de colonne unique ou une liste de colonnes. Indiquez les colonnes sur lesquelles vous souhaitez appliquer la transformation. Dans cet exemple, leasing est spécifié. Pour plus d’informations sur les noeuds disponibles et sur leur utilisation, consultez le guide de référence sur les noeuds.

# Renaming leasing column using Pandas Node
leasing_mapper_node = Pandas(params={'import': 'map',
                                'kwargs': {'arg': {
                                    'dataLayerNull': 'notgiven', 
                                    'no': 'no', 
                                    'yes': 'yes', 
                                    'notgiven': 'notgiven'}},
                                'inplace': True,
                                'cols': 'leasing'})

Création du graphique DSL

Une fois les noeuds créés, l’étape suivante consiste à les associer pour créer un graphique.

Commencez par répertorier tous les noeuds qui font partie du graphique en créant un tableau.

nodes = [json_df_node, 
        to_datetime_node,
        hour_node,
        dayofweek_node,
        age_fillna_node,
        carbrand_fillna_node,
        country_fillna_node,
        cartype_primary_nationality_km_fillna_node,
        carbrand_mapper_node,
        cartype_mapper_node,
        country_mapper_node,
        gender_mapper_node,
        leasing_mapper_node,
        age_to_int_node,
        age_bins_node,
        dummies_node, 
        onnx_node]

Ensuite, connectez les noeuds aux bords. Chaque tuple est une connexion Edge.

CONSEIL

Comme les noeuds dépendent les uns des autres (chaque noeud dépend de la sortie du noeud précédent), vous pouvez créer des liens à l’aide d’une simple compréhension de liste Python. Ajoutez vos propres connexions si un noeud dépend de plusieurs entrées.

edges = [(nodes[i], nodes[i+1]) for i in range(len(nodes)-1)]

Une fois vos noeuds connectés, créez le graphique. La cellule ci-dessous est obligatoire et ne peut pas être modifiée ni supprimée.

dsl = GraphBuilder.generate_dsl(nodes=nodes, edges=edges)
pprint(json.loads(dsl))

Une fois l’opération terminée, un objet edge est renvoyé contenant chacun des noeuds et les paramètres qui leur ont été associés.

edge return

Publication sur Edge (Hub)

REMARQUE

L’apprentissage automatique en temps réel est temporairement déployé sur et géré par Adobe Experience Platform Hub. Pour plus d’informations, consultez la section de présentation de Architecture d’apprentissage automatique en temps réel.

Maintenant que vous avez créé un graphique DSL, vous pouvez déployer le graphique sur Edge.

IMPORTANT

Ne publiez pas sur Edge souvent, cela peut surcharger les noeuds Edge. Il n’est pas recommandé de publier le même modèle plusieurs fois.

edge_utils = EdgeUtils()
(edge_location, service_id) = edge_utils.publish_to_edge(dsl=dsl)
print(f'Edge Location: {edge_location}')
print(f'Service ID: {service_id}')

Mise à jour de votre DSL et republication sur Edge (facultatif)

Si vous n’avez pas besoin de mettre à jour votre DSL, vous pouvez passer à notation.

REMARQUE

Les cellules suivantes ne sont nécessaires que si vous souhaitez mettre à jour un DSL existant qui a été publié sur Edge.

Vos modèles vont probablement continuer à se développer. Au lieu de créer un nouveau service, il est possible de mettre à jour un service existant avec votre nouveau modèle. Vous pouvez définir un noeud que vous souhaitez mettre à jour, lui attribuer un nouvel ID, puis charger à nouveau le nouveau DSL sur la balise Edge.

Dans l’exemple ci-dessous, le noeud 0 est mis à jour avec un nouvel ID.

# Update the id of Node 0 with a random uuid.

dsl_dict = json.loads(dsl)
print(f"ID of Node 0 in current DSL: {dsl_dict['edge']['applicationDsl']['nodes'][0]['id']}")

new_node_id = str(uuid.uuid4())
print(f'Updated Node ID: {new_node_id}')

dsl_dict['edge']['applicationDsl']['nodes'][0]['id'] = new_node_id

Noeud mis à jour

Après la mise à jour de l’ID de noeud, vous pouvez republier un DSL mis à jour sur Edge.

# Republish the updated DSL to Edge
(edge_location_ret, service_id, updated_dsl) = edge_utils.update_deployment(dsl=json.dumps(dsl_dict), service_id=service_id)
print(f'Updated dsl: {updated_dsl}')

Vous recevez le DSL mis à jour.

Mise à jour du DSL

Notation

Après la publication sur Edge, la notation est effectuée par une requête de POST d’un client. En règle générale, cela peut être effectué à partir d’une application cliente qui a besoin de scores ML. Vous pouvez également le faire à partir de Postman. Le modèle ML en temps réel utilise EdgeUtils pour démontrer ce processus.

REMARQUE

Un petit temps de traitement est nécessaire avant le début de la notation.

# Wait for the app to come up
import time
time.sleep(20)

En utilisant le même schéma que celui utilisé dans la formation, des exemples de données de notation sont générés. Ces données sont utilisées pour créer un cadre de données de notation, puis converties en dictionnaire de notation. Consultez le modèle ML en temps réel pour la cellule de code complète.

Données de notation

Score par rapport au point d’entrée Edge

Utilisez la cellule suivante dans le modèle ML en temps réel pour obtenir une note par rapport à votre service Edge.

Score par rapport au bord

Une fois la notation terminée, l’URL Edge, la charge utile et la sortie notée de Edge sont renvoyées.

Liste de vos applications déployées à partir de la balise Edge

Pour générer une liste de vos applications actuellement déployées sur Edge, exécutez la cellule de code suivante. Cette cellule ne peut pas être modifiée ni supprimée.

services = edge_utils.list_deployed_services()
print(services)

La réponse renvoyée est un tableau de vos services déployés.

[
    {
        "created": "2020-05-25T19:18:52.731Z",
        "deprecated": false,
        "id": "40eq76c0-1c6f-427a-8f8f-54y9cdf041b7",
        "type": "edge",
        "updated": "2020-05-25T19:18:52.731Z"
    }
]

Supprimer un ID d’application ou de service déployé de Edge (facultatif)

ATTENTION

Cette cellule est utilisée pour supprimer votre application Edge déployée. N’utilisez pas la cellule suivante, sauf si vous devez supprimer une application Edge déployée.

if edge_utils.delete_from_edge(service_id=service_id):
    print(f"Deleted service id {service_id} successfully")
else:
    print(f"Failed to delete service id {service_id}")

Étapes suivantes

En suivant le tutoriel ci-dessus, vous avez correctement formé et téléchargé un modèle ONNX vers la boutique de modèles d’apprentissage automatique en temps réel. En outre, vous avez noté et déployé votre modèle d’apprentissage automatique en temps réel. Si vous souhaitez en savoir plus sur les noeuds disponibles pour la création de modèles, consultez le guide de référence sur les noeuds.

Sur cette page