15.3 Operazionalizzare il modello utilizzando una ricetta

In questo esercizio, prenderà il modello e lo renderà operativo in Adobe Experience Platform creando una ricetta.

Il notebook per la generazione di ricette funge da modello per creare automaticamente un pacchetto e renderlo operativo. Il notebook dispone di più celle modellate che consentono di adattare il codice del modello in:

  • I requisiti e le celle di configurazione consentono di aggiungere librerie aggiuntive e configurare set di dati e parametri di ottimizzazione per il modello
  • La cella valutatore consente di suddividere i dati e valutare le prestazioni del modello
  • Le celle del caricatore dati di formazione e punteggio consentono di caricare i dati necessari per la formazione e il punteggio
  • Infine, la cella della pipeline contiene la logica necessaria sia per la formazione che per il punteggio del modello.

Abbiamo semplificato i passaggi necessari per rendere operativo un modello, consentendo di formare, valutare e valutare il modello in scala e quindi di inserirlo in un unico flusso su Adobe Experience Platform. La creazione di pacchetti in una ricetta consente inoltre di utilizzare lo stesso codice con set di dati diversi per alimentare diversi casi di utilizzo nelle organizzazioni. Il nostro caso di utilizzo specifico ruota intorno all'utilizzo del codice del modello di raccomandazioni per gli utenti che cercano prodotti da acquistare sul sito Web.

Accedete ad Adobe Experience Platform con il seguente URL: https://experience.adobe.com/platform.

Dopo aver effettuato l'accesso, si arriva sulla homepage di Adobe Experience Platform.

Acquisizione dei dati

Prima di continuare, dovete selezionare una sandbox. La sandbox da selezionare è denominata --aepSandboxId--. Per farlo, fai clic sul testo Produzione Prod nella linea blu sopra lo schermo.

Acquisizione dei dati

Dopo aver selezionato la sandbox appropriata, verrà visualizzato il cambio dello schermo e ora siete nella sandbox dedicata.

Acquisizione dei dati

In Adobe Experience Platform, fate clic su Notebook nel menu a sinistra dello schermo, quindi andate a JupyterLab.

Acquisizione dei dati

In Jupyter Notebooks, aprire la pagina Launcher facendo clic sull'icona + nella barra delle applicazioni.

DSW

Vedrete questo:

DSW

Aprite un blocco appunti Recipe Builder vuoto facendo clic sul pulsante Recipe Builder nel modulo di avvio.

DSW

A questo punto, il nuovo blocco appunti Recipe Builder vuoto. Prima di continuare, assegnare al blocco appunti un nome descrittivo. Fate clic con il pulsante destro del mouse sul file [Python 3] Recipe Builder.ipynb e fate clic su Rinomina.

DSW

Inserire Mutuo365-Insurance-sales-propensity.ipynb come nome per il notebook e premere Invio. Avrete quindi questo:

DSW

In questo blocco appunti, effettuerai le seguenti operazioni:

  • Train a model
  • Punteggio di un modello
  • Creare una ricetta dal modello

Configuriamo tutti i passaggi in dettaglio.

File di configurazione

Scorrete verso il basso nel blocco appunti di Recipe Builder fino a visualizzare i file di configurazione.

DSW

È ora necessario aggiornare le celle per Configurazione ​formazione e Configurazione ​punteggio.

Configurazione formazione

Fate clic nella cella Configurazione ​formazione.

Prima di fare qualsiasi cosa, prestate attenzione!! Qualunque cosa si faccia, non eliminare o sovrascrivere la riga che inizia con %%writefile. Questa riga è necessaria per il notebook Recipe Builder.

%%writefile ~/my-workspace/.recipes/recipe-tFgHWnuH5/training.conf

DSW

Vedrai anche un codice simile nella stessa cella:

{
   "trainingDataSetId": "<replace with training dataset id>",
   "ACP_DSW_TRAINING_XDM_SCHEMA": "<replace with training xdm schema id>",
   "tenantId": "_<tenant_id>", 
   "learning_rate": "0.1",
   "n_estimators": "100",
   "max_depth": "3"
}

Sostituire il codice con il codice seguente:

{
    "trainingDataSetId": "--aepCarInsuranceInteractionsDatasetId--",
    "ACP_DSW_TRAINING_XDM_SCHEMA": "https://ns.adobe.com/--aepTenantIdSchema--/schemas/--aepCarInsuranceInteractionsSchemaRef--",
    "train_records_limit":1000000,
    "n_estimators": "80",
    "max_depth": "5",
    "ten_id": "--aepTenantId--"
}
IMPORTANTE

Le variabili di ambiente aepCarInsuranceInteractionsDatasetId e aepCarInsuranceInteractionsSchemaRef fanno riferimento a un ID di set di dati creato nell’istanza di Adobe Experience Platform e a un ID di riferimento dello schema creato nell’istanza di Adobe Experience Platform.

aepCarInsuranceInteractionsDatasetId fa riferimento all'ID del set di dati Demo System - Event Dataset for Website (Global v1.1), aepCarInsuranceInteractionsSchemaRef fa riferimento all'ID dello schema Ref del sistema Demo - Event Schema for Website (Global v1.1). Sostituite le variabili di ambiente con l’ID del set di dati e lo ID di riferimento dello schema quando incollate il codice nella cella Configurazione ​formazione del notebook.

Nella cella Configurazione ​formazione dovrebbe ora essere presente qualcosa di simile:

DSW

Configurazione punteggio

Fare clic nella cella per la configurazione del punteggio.

Prima di fare qualsiasi cosa, prestate attenzione!! Qualunque cosa si faccia, non eliminare o sovrascrivere la riga che inizia con %%writefile. Questa riga è necessaria per il notebook Recipe Builder.

%%writefile ~/my-workspace/.recipes/recipe-tFgHWnuH5/scoring.conf

DSW

Vedrai anche un codice simile nella stessa cella:

{
   "scoringDataSetId": "<replace with scoring input dataset id>",
   "scoringResultsDataSetId": "<replace with scoring results dataset id>",
   "ACP_DSW_SCORING_RESULTS_XDM_SCHEMA": "<replace with scoring results xdm schema id>",
   "tenantId": "_<tenant_id>"
}

Sostituire il codice con il codice seguente:

{
   "scoringDataSetId": "--aepCarInsuranceInteractionsDatasetId--",
   "scoringResultsDataSetId": "--aepMlPredictionsDatasetId--",
   "ACP_DSW_SCORING_RESULTS_XDM_SCHEMA": "https://ns.adobe.com/--aepTenantIdSchema--/schemas/--aepMlPredictionsSchemaRef--",
   "ten_id": "--aepTenantId--"
}
IMPORTANTE

Le variabili di ambiente aepCarInsuranceInteractionsDatasetId, aepMlPredictionsDatasetId e aepMlPredictionsSchemaRef fanno riferimento agli ID di set di dati e all'ID di rif dello schema degli schemi creati nell'istanza di Adobe Experience Platform.

aepCarInsuranceInteractionsDatasetId si riferisce all'ID del set di dati del Demo System - DataSet evento per il sito Web (Global v1.1), aepMlPredictionsDatasetId fa riferimento all'ID del set di dati del DataSet Demo System - DataSet di profili per le previsioni ML (Global v1.1), aep MlPredictionsSchemaRef fa riferimento all'ID di riferimento dello schema del sistema ​demo dello schema - Schema del profilo per lo schema ML Predictions (Global v1.1). Sostituire le variabili di ambiente con l'ID del set di dati e lo ID di riferimento dello schema quando si incolla il codice nella cella Configurazione punteggio del blocco appunti.

Nella cella Configurazione ​punteggio è ora necessario disporre di qualcosa di simile:

DSW

File di caricamento dati formazione

Scorrete verso il basso nel blocco appunti di Recipe Builder fino a visualizzare il file di caricamento dati formazione.

DSW

È ora necessario aggiornare il codice per il file di caricamento dati formazione.

Prima di fare qualsiasi cosa, prestate attenzione!! Qualunque cosa si faccia, non eliminare o sovrascrivere la riga che inizia con %%writefile. Questa riga è necessaria per il notebook Recipe Builder.

DSW

In quella cella troverai un codice simile al seguente:

import pandas as pd
from datetime import datetime, timedelta
from platform_sdk.dataset_reader import DatasetReader
from .utils import get_client_context

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")
    
    if (timeframe is not None):
        date_before = datetime.utcnow().date()
        date_after = date_before - timedelta(minutes=int(timeframe))
        dataframe = dataset_reader.where(dataset_reader[tenant_id + '.date'].gt(str(date_after)).And(dataset_reader[tenant_id + '.date'].lt(str(date_before)))).read()
    else:
        dataframe = dataset_reader.read()

    if '_id' in dataframe.columns:
        #Rename columns to strip tenantId
        dataframe = dataframe.rename(columns = lambda x : str(x)[str(x).find('.')+1:])
        #Drop id and timestamp
        dataframe.drop(['_id', 'timestamp'], axis=1, inplace=True)
    
    #########################################
    # 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)

    print("Training Data Load Finish")
    return dataframe

Sostituire il codice (senza sovrascrivere la riga %%writefile ) con il codice seguente:

import numpy as np
import pandas as pd
from datetime import datetime, timedelta
from platform_sdk.dataset_reader import DatasetReader
from .utils import get_client_context

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

    #########################################
    # Load Data
    #########################################    
    client_context = get_client_context(config_properties)
    train_records_limit = config_properties['train_records_limit']
    
    dataset_reader = DatasetReader(client_context, config_properties['trainingDataSetId'])
    
    #timeframe = config_properties.get("timeframe")
    #tenant_id = config_properties.get("tenant_id")
    print('Reading Training Data')
    df1 = dataset_reader.limit(train_records_limit).read()
    df1.rename(columns = {config_properties['ten_id']+'.identification.core.ecid' : 'ecid',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.numberKm': 'km',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.type': 'cartype',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.customerAge': 'age',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.customerGender' : 'gender',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.brand' : 'carbrand',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.leasing' : 'leasing',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.customerCity' : 'city',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.customerCountry' : 'country',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.customerNationality' : 'nationality',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.isCustomerPrimaryDriver' : 'primaryuser',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.hasCustomerPurchased' : 'purchase',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.priceBasic' : 'pricequote'}, inplace=True)
    df1 = df1[['ecid', 'km', 'cartype', 'age', 'gender', 'carbrand', 'leasing', 'city', 
           'country', 'nationality', 'primaryuser', 'purchase', 'pricequote', 'timestamp']]
    df1 = df1.loc[df1['age'] != 0]
    
    #########################################
    # 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'] == 'true'), 'purchase'] = 1
    df1.loc[(df1['purchase'] == 'false'), 'purchase'] = 0
    df1.loc[(df1['purchase'] == ''), 'purchase'] = 0
    df1.purchase.fillna(0, inplace=True)
    df1['purchase'] = df1['purchase'].astype(int)
    
    df1.dropna(subset = ['ecid'], inplace=True)
    df1['ecid'] = df1['ecid'].astype(str)
    df_conv_dict = df1.groupby('ecid').max()[['purchase']]
    df_conv_dict = df_conv_dict.to_dict()
    
    idx = df1.groupby('ecid')['timestamp'].transform(max) == df1['timestamp']
    df1 = df1[idx]
    df1 = df1.drop_duplicates(subset = 'ecid', keep = 'last', inplace = False)
    #df1['purchase'] = df1['ecid'].map(df_conv_dict['purchase'])

    #########################################
    # Data Preparation/Feature Engineering
    #########################################      
    
    df1['carbrand'] = df1['carbrand'].str.lower()
    df1['country'] = df1['country'].str.lower()
    df1.loc[(df1['carbrand'] == 'vw'), 'carbrand'] = 'volkswagen'
    df1.loc[(df1['carbrand'] == 'citroen'), 'carbrand'] = 'cadillac'
    df1.loc[(df1['carbrand'] == 'opel'), 'carbrand'] = 'bmw'
    df1.loc[(df1['carbrand'] == 'mini'), 'carbrand'] = 'volkswagen'
    
    df1.loc[(df1['cartype'] == 'SUV / Geländewagen') | (df1['cartype'] == 'SUV / Tout terrain'), 'cartype'] = 'suv'
    df1.loc[(df1['cartype'] == 'Kleinwagen') | (df1['cartype'] == 'Untere Mittelklasse') | (df1['cartype'] == 'Mikroklasse'), 'cartype'] = 'hatchback'
    df1.loc[(df1['cartype'] == 'Mittelklasse') | (df1['cartype'] == 'Obere Mittelklasse'), 'cartype'] = 'sedan'
    df1.loc[(df1['cartype'] == 'Kompaktvan / Minivan'), 'cartype'] = 'minivan'
    df1.loc[(df1['cartype'] == 'Cabriolet / Roadster'), 'cartype'] = 'convertible'
    df1.loc[(df1['cartype'] == 'Coupé / Sportwagen'), 'cartype'] = 'coupe'
    df1.loc[(df1['cartype'] == 'dataLayerNull'), 'cartype'] = pd.np.nan
    df1.loc[(df1['cartype'] == 'Luxusklasse'), 'cartype'] = 'luxury'
    df1.loc[(df1['cartype'] == 'Strasse'), 'cartype'] = 'mpv'
    
    df1.loc[(df1['leasing'] == 'false'), 'leasing'] = 'no'
    df1.loc[df1['country'] == 'at', 'country'] = 'austria'
    df1.loc[(df1['leasing'] == 'dataLayerNull'), 'leasing'] = pd.np.nan
    df1.loc[(df1['gender'] == 'dataLayerNull'), 'gender'] = pd.np.nan
    df1.loc[(df1['carbrand'] == 'dataLayerNull'), 'carbrand'] = pd.np.nan

    df1['age'].fillna(df1['age'].median(), inplace=True)
    df1['gender'].fillna('notgiven', inplace=True)
    df1['leasing'].fillna('notgiven', inplace=True)
    df1['carbrand'].fillna('bmw', inplace=True)
    df1['country'].fillna('germany', inplace=True)
    df1['cartype'].fillna('na', inplace=True)
    df1['primaryuser'].fillna('na', inplace=True)
    df1['nationality'].fillna('na', inplace=True)
    df1['km'].fillna('na', inplace=True)
    
    df1['city'] = df1.groupby('country')['city'].transform(lambda x : x.fillna(x.mode()))
    #df1.dropna(subset = ['pricequote'], inplace=True)
    
    #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:
            return "20-28"
        elif x > 28 and x < 43:
            return "29-42"
        elif x > 42 and x < 55:
            return "43-54"
        elif x > 54 and x < 65:
            return "55-64"
        elif x >= 65: 
            return "65+"
        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']]
    
    cat_cols = ['age_bucket', 'gender', 'city', 'dayofweek', 'country', 'carbrand', 'cartype', 'leasing']
    df_final = pd.get_dummies(df_final, columns = cat_cols)
    
    dataframe = df_final.copy()
    
    df_final.head(20)
 
    print("Training Data Load Finish")
    return dataframe

Nella cella del file del caricatore dati formazione deve ora essere presente qualcosa di simile:

DSW

Punteggio file di caricamento dati

Scorri verso il basso nel blocco appunti di Generatore di ricette fino a visualizzare il file di caricamento dati punteggio.

DSW

È ora necessario aggiornare il codice per il file di caricamento dati punteggio.

Prima di fare qualsiasi cosa, prestate attenzione!! Qualunque cosa si faccia, non eliminare o sovrascrivere la riga che inizia con %%writefile. Questa riga è necessaria per il notebook Recipe Builder.

DSW

In quella cella troverai un codice simile al seguente:

import pandas as pd
from datetime import datetime, timedelta
from .utils import get_client_context
from platform_sdk.dataset_reader import DatasetReader

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")

    if (timeframe is not None):
        date_before = datetime.utcnow().date()
        date_after = date_before - timedelta(minutes=int(timeframe))
        dataframe = dataset_reader.where(dataset_reader[tenant_id + '.date'].gt(str(date_after)).And(dataset_reader[tenant_id + '.date'].lt(str(date_before)))).read()
    else:
        dataframe = dataset_reader.read()
        print(dataframe)

    #########################################
    # 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 and timestamp
        dataframe.drop(['_id', '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

Sostituire il codice (senza sovrascrivere la riga %%writefile ) con il codice seguente:

import pandas as pd
from datetime import datetime, timedelta
from .utils import get_client_context
from platform_sdk.dataset_reader import DatasetReader

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")
    df1 = dataset_reader.read()
    df1.rename(columns = {config_properties['ten_id']+'.identification.core.ecid' : 'ecid',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.numberKm': 'km',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.type': 'cartype',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.customerAge': 'age',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.customerGender' : 'gender',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.brand' : 'carbrand',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.leasing' : 'leasing',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.customerCity' : 'city',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.customerCountry' : 'country',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.customerNationality' : 'nationality',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.isCustomerPrimaryDriver' : 'primaryuser',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.hasCustomerPurchased' : 'purchase',
                     config_properties['ten_id']+'.interactionDetails.insurance.car.priceBasic' : 'pricequote'}, inplace=True)
    df1 = df1[['ecid', 'km', 'cartype', 'age', 'gender', 'carbrand', 'leasing', 'city', 
           'country', 'nationality', 'primaryuser', 'purchase', 'pricequote', 'timestamp']]
    df1 = df1.loc[df1['age'] != 0]
    
    #########################################
    # 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'] == 'true'), 'purchase'] = 1
    df1.loc[(df1['purchase'] == 'false'), 'purchase'] = 0
    df1.loc[(df1['purchase'] == ''), 'purchase'] = 0
    df1.purchase.fillna(0, inplace=True)
    df1['purchase'] = df1['purchase'].astype(int)
    
    df1.dropna(subset = ['ecid'], inplace=True)
    df1['ecid'] = df1['ecid'].astype(str)
    df_conv_dict = df1.groupby('ecid').max()[['purchase']]
    df_conv_dict = df_conv_dict.to_dict()
    
    idx = df1.groupby('ecid')['timestamp'].transform(max) == df1['timestamp']
    df1 = df1[idx]
    df1 = df1.drop_duplicates(subset = 'ecid', keep = 'last', inplace = False)
    df1['purchase'] = df1['ecid'].map(df_conv_dict['purchase'])
    
    #########################################
    # Data Preparation/Feature Engineering
    #########################################      
    
    df1['carbrand'] = df1['carbrand'].str.lower()
    df1['country'] = df1['country'].str.lower()
    df1.loc[(df1['carbrand'] == 'vw'), 'carbrand'] = 'volkswagen'
    df1.loc[(df1['carbrand'] == 'citroen'), 'carbrand'] = 'cadillac'
    df1.loc[(df1['carbrand'] == 'opel'), 'carbrand'] = 'bmw'
    df1.loc[(df1['carbrand'] == 'mini'), 'carbrand'] = 'volkswagen'
    
    df1.loc[(df1['cartype'] == 'SUV / Geländewagen') | (df1['cartype'] == 'SUV / Tout terrain'), 'cartype'] = 'suv'
    df1.loc[(df1['cartype'] == 'Kleinwagen') | (df1['cartype'] == 'Untere Mittelklasse') | (df1['cartype'] == 'Mikroklasse'), 'cartype'] = 'hatchback'
    df1.loc[(df1['cartype'] == 'Mittelklasse') | (df1['cartype'] == 'Obere Mittelklasse'), 'cartype'] = 'sedan'
    df1.loc[(df1['cartype'] == 'Kompaktvan / Minivan'), 'cartype'] = 'minivan'
    df1.loc[(df1['cartype'] == 'Cabriolet / Roadster'), 'cartype'] = 'convertible'
    df1.loc[(df1['cartype'] == 'Coupé / Sportwagen'), 'cartype'] = 'coupe'
    df1.loc[(df1['cartype'] == 'dataLayerNull'), 'cartype'] = pd.np.nan
    df1.loc[(df1['cartype'] == 'Luxusklasse'), 'cartype'] = 'luxury'
    df1.loc[(df1['cartype'] == 'Strasse'), 'cartype'] = 'mpv'
    
    df1.loc[(df1['leasing'] == 'false'), 'leasing'] = 'no'
    df1.loc[df1['country'] == 'at', 'country'] = 'austria'
    df1.loc[(df1['leasing'] == 'dataLayerNull'), 'leasing'] = pd.np.nan
    df1.loc[(df1['gender'] == 'dataLayerNull'), 'gender'] = pd.np.nan
    df1.loc[(df1['carbrand'] == 'dataLayerNull'), 'carbrand'] = pd.np.nan

    df1['age'].fillna(df1['age'].median(), inplace=True)
    df1['gender'].fillna('notgiven', inplace=True)
    df1['leasing'].fillna('notgiven', inplace=True)
    df1['carbrand'].fillna('bmw', inplace=True)
    df1['country'].fillna('germany', inplace=True)
    df1['cartype'].fillna('na', inplace=True)
    df1['primaryuser'].fillna('na', inplace=True)
    df1['nationality'].fillna('na', inplace=True)
    df1['km'].fillna('na', inplace=True)
    
    df1['city'] = df1.groupby('country')['city'].transform(lambda x : x.fillna(x.mode()))
    df1.dropna(subset = ['pricequote'], inplace=True)
    
    #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:
            return "20-28"
        elif x > 28 and x < 43:
            return "29-42"
        elif x > 42 and x < 55:
            return "43-54"
        elif x > 54 and x < 65:
            return "55-64"
        elif x >= 65: 
            return "65+"
        else: 
            return "Others"
        
    df1['age'] = df1['age'].astype(int)
    df1['age_bucket'] = df1['age'].apply(lambda x: age(x))
    
    df_final = df1[['ecid', 'hour', 'dayofweek','age_bucket', 'gender', 'city',  
       'country', 'carbrand', 'cartype', 'leasing', 'pricequote']]
    
    #cat_cols = ['age_bucket', 'gender', 'city', 'dayofweek', 'country', 'carbrand', 'cartype', 'leasing']
    #df_final = pd.get_dummies(df_final, columns = cat_cols)
    
    dataframe = df_final.copy()

    print("Scoring Data Load Finish")

    return dataframe

Nella cella del file del caricatore dati punteggio è ora necessario disporre di qualcosa di simile:

DSW

File pipeline

Scorrete verso il basso nel blocco appunti di Generatore di ricette fino a visualizzare il file della tubazione.

DSW

È ora necessario aggiornare il codice per il file ​pipeline.

Prima di fare qualsiasi cosa, prestate attenzione!! Qualunque cosa si faccia, non eliminare o sovrascrivere la riga che inizia con %%writefile. Questa riga è necessaria per il notebook Recipe Builder.

DSW

In quella cella troverai un codice simile al seguente:

from sklearn.ensemble import GradientBoostingRegressor

def train(config_properties, data):

    print("Train Start")

    #########################################
    # Extract fields from configProperties
    #########################################
    learning_rate = float(config_properties['learning_rate'])
    n_estimators = int(config_properties['n_estimators'])
    max_depth = int(config_properties['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

def score(config_properties, 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

Sostituire il codice (senza sovrascrivere la riga %%writefile ) con il codice seguente:

import pandas as pd
import numpy as np
from sklearn import metrics
from sklearn.metrics import roc_curve, auc, mean_squared_error
from sklearn.ensemble import RandomForestClassifier
import os

def underSample(data):
    conv = data[data['purchase'] > 0]
    non_conv = data[data['purchase'] == 0]
    sample_size = len(conv)
    non_sample = non_conv.sample(n = sample_size)
    frames = [conv, non_sample]
    result = pd.concat(frames)
    return result

class RandomForest():
    def __init__(self, config_properties, X, y):
        print("initiating model")
        self.n_estimators = int(config_properties['n_estimators'])
        self.max_depth = int(config_properties['max_depth'])
        self.X = X
        self.y = y
        self.features = X.columns.values.tolist()
        self.model = RandomForestClassifier(n_estimators=self.n_estimators, max_depth=self.max_depth, random_state=32)
        self.trained_model = self.model.fit(self.X,self.y)
    def train_model(self):
        print('fitting model')
        return self.model.fit(self.X,self.y)
    
    def make_tarfile(self, output_filename, source_dir):
        with tarfile.open(output_filename, "w:gz") as tar:
            tar.add(source_dir, arcname=os.path.basename(source_dir))
    
    #for generating onnx
    def generate_onnx_resources(self):        
        install_dir = os.path.expanduser('~/my-workspace')
        print("Generating Onnx")
        try:
            subprocess.check_call(["conda", "uninstall", "-y", "protobuf"])
        except:
            print("protobuf not installed via conda")
        
        subprocess.check_call(["python", '-m', 'pip', 'install', 'skl2onnx'])
        
        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_new.onnx", "wb") as f:
            f.write(onx.SerializeToString())
            
        self.make_tarfile('model_new.tar.gz', 'model.onnx')
        print("Model onnx created")

def train(config_properties, data):

    print("Train Start")  
    y_train = data['purchase']
    X_train = data.drop('purchase', axis=1)
    # Fit model
    lead_score = RandomForest(config_properties, X_train, y_train)
    lead_score.train_model()

    print("Train Complete")
    
    return lead_score

def score(config_properties, data, model):

    print("Score Start")
    cat_cols = ['age_bucket', 'gender', 'city', 'dayofweek', 'country', 'carbrand', 'cartype', 'leasing']
    data = pd.get_dummies(data, columns = cat_cols)
    
    X_score = data.drop('ecid', axis=1)
    train_feats = model.features
    print(train_feats)
    
    trained_model = model.trained_model
    score_feats = X_score.columns.values.tolist()
    missing_feats = list(set(train_feats) - set(score_feats))
    extra_feats = list(set(score_feats) - set(train_feats))
    for c in extra_feats:
        X_score.drop(c, axis=1, inplace=True)
    for c in missing_feats:
        X_score[c] = 0
    X_score = X_score[train_feats]
    print(X_score.columns.values.tolist())
    y_preds = trained_model.predict_proba(X_score)[:,1]
    
    data.rename(columns = {'ecid' : config_properties['ten_id']+'.identification.core.ecid'}, inplace=True)
    
    data[config_properties['ten_id']+'.individualScoring.insurance.carInsuranceSalesPrediction'] = y_preds
    data = data[[config_properties['ten_id']+'.identification.core.ecid', config_properties['ten_id']+'.individualScoring.insurance.carInsuranceSalesPrediction']]

    print("Score Complete")
    return data

Nella cella File ​tubazione deve ora essere presente qualcosa di simile:

DSW

File di valutazione

Scorrete verso il basso nel blocco appunti di Generatore di ricette fino a visualizzare il file ​valutatore.

DSW

È ora necessario aggiornare il codice per il file ​valutatore.

Prima di fare qualsiasi cosa, prestate attenzione!! Qualunque cosa si faccia, non eliminare o sovrascrivere la riga che inizia con %%writefile. Questa riga è necessaria per il notebook Recipe Builder.

DSW

In quella cella troverai un codice simile al seguente:

from ml.runtime.python.core.regressionEvaluator import RegressionEvaluator
import numpy as np

class Evaluator(RegressionEvaluator):
    def __init__(self):
        print ("Initiate")

    def split(self, config={}, 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

    def evaluate(self, data=[], model={}, config={}):
        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"}]
        
        print(metric)
        return metric

Sostituire il codice (senza sovrascrivere la riga %%writefile ) con il codice seguente:

from ml.runtime.python.core.regressionEvaluator import RegressionEvaluator
import numpy as np
from sklearn import metrics
from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import train_test_split

class Evaluator(RegressionEvaluator):
    def __init__(self):
        print ("Initiate")

    def split(self, config={}, dataframe=None):
        
        train, val = train_test_split(dataframe, test_size = 0.2, random_state = 32)

        return train, val

    def evaluate(self, data=[], model={}, config={}):
        model = model.trained_model
        print ("Evaluation evaluate triggered")
        val = data.drop('purchase', axis=1)
        y_pred = model.predict(val)
        y_actual = data['purchase']
        
        y_pred_proba = model.predict_proba(val)[:,1]
       
        accuracy = metrics.accuracy_score(y_actual, y_pred, normalize=True, sample_weight=None)
        recall = metrics.recall_score(y_actual, y_pred, labels=None, pos_label=1, average='binary', sample_weight=None)
        precision = metrics.precision_score(y_actual, y_pred, labels=None, pos_label=1, average='binary', sample_weight=None)
        
        val_fpr, val_tpr, _ = roc_curve(y_actual, y_pred_proba)
        roc_auc = auc(val_fpr, val_tpr)

        metric = [{"name": "Accuracy", "value": accuracy, "valueType": "double"},
                  {"name": "Recall", "value": recall, "valueType": "double"},
                  {"name": "Precision", "value": precision, "valueType": "double"}]
        
        print(metric)
        return metric

Nella cella File ​valutatore deve ora essere presente qualcosa di simile:

DSW

File di salvataggio dati

Scorri verso il basso nel blocco appunti di Recipe Builder fino a visualizzare il file ​Data Saver.

DSW

È ora necessario aggiornare il codice per il file ​Data Saver.

Prima di fare qualsiasi cosa, prestate attenzione!! Qualunque cosa si faccia, non eliminare o sovrascrivere la riga che inizia con %%writefile. Questa riga è necessaria per il notebook Recipe Builder.

DSW

In quella cella troverai un codice simile al seguente:

import pandas as pd
from .utils import get_client_context
from platform_sdk.models import Dataset
from platform_sdk.dataset_writer import DatasetWriter

def save(config_properties, prediction):
  print("Datasaver Start")

  client_context = get_client_context(config_properties)
  tenant_id = config_properties.get("tenantId")
  prediction = prediction.add_prefix(tenant_id+".")

  prediction = prediction.join(pd.DataFrame(
      {
          '_id': "",
          'timestamp': '2019-01-01T00:00:00',
          'eventType': ""
      }, index=prediction.index))

  dataset = Dataset(client_context).get_by_id(config_properties['scoringResultsDataSetId'])
  dataset_writer = DatasetWriter(client_context, dataset)
  dataset_writer.write(prediction, file_format='json')

  print("Datasaver Finish")
  print(prediction)

Sostituire il codice (senza sovrascrivere la riga %%writefile ) con il codice seguente:

from .utils import get_client_context
from platform_sdk.models import Dataset
from platform_sdk.dataset_writer import DatasetWriter

def save(config_properties, prediction):
  print("Datasaver Start")

  client_context = get_client_context(config_properties)
  dataset = Dataset(client_context).get_by_id(config_properties['scoringResultsDataSetId'])
  dataset_writer = DatasetWriter(client_context, dataset)
  dataset_writer.write(prediction, file_format='json')

  print("Datasaver Finish")
  print(prediction)

Nella cella File di Data Saver ora si deve avere qualcosa di simile:

DSW

Ora hai configurato tutto il codice necessario per eseguire il blocco appunti.

Train a model

La formazione di un modello viene effettuata facendo clic sul pulsante Treno .

DSW

Fate clic su Treno nella barra degli strumenti superiore per creare un'esecuzione di formazione nel blocco appunti. In questo modo vengono eseguite le celle del caricatore dei dati di formazione, della pipeline e del valutatore e vengono generate metriche di valutazione per misurare le prestazioni del modello. Nel blocco appunti (sotto la cella Valutatore) viene visualizzato un registro di comandi e output dello script di formazione.

Dopo aver fatto clic sul treno, la procedura di formazione inizierà e avrà bisogno di un paio di minuti per completare.

DSW
DSW
DSW

Quando si fa clic su Treno, vengono eseguite le celle seguenti:

  • File di requisiti
  • File di configurazione - Formazione
  • File di caricamento dati formazione
  • File pipeline
  • File di valutazione

Punteggio di un modello

Per eseguire il punteggio di un modello, fare clic sul pulsante Valutazione .

DSW

Fate clic su Punteggio nella barra degli strumenti superiore per creare un'esecuzione di formazione nella cella. In questo modo vengono eseguite le celle del caricatore dei dati di punteggio, della pipeline e del valutatore e vengono generate metriche di valutazione per misurare le prestazioni del modello. Nel blocco appunti (sotto la cella pipeline.py ) viene visualizzato un registro di comandi e output dello script di formazione.

Dopo aver fatto clic su Punteggio, l'esecuzione della formazione inizierà e saranno necessari un paio di minuti per completare.

DSW
DSW
DSW

Quando si fa clic su Punteggio, vengono eseguite le celle seguenti:

  • File di requisiti
  • File di configurazione - Punteggio
  • Punteggio file di caricamento dati
  • File pipeline
  • File di valutazione

Inoltre, alla fine dell'esecuzione del punteggio, l'output con punteggi di propensione è memorizzato in Adobe Experience Platform, nel Demo System - Profile Dataset for ML Predictions (Global v1.1) Dataset.

Potete verificarlo qui.

DSW

Creare una ricetta dal modello

Per creare una ricetta, fate clic sul pulsante Crea ricetta .

DSW

Una volta soddisfatti i risultati della formazione e del punteggio, potete creare una ricetta. Fate clic sul pulsante Crea ricetta per avviare il processo.

La creazione di una ricetta consente di verificare il modello in scala.

Dopo aver fatto clic sul pulsante Crea ricetta , dovete immettere un nome per la ricetta.

DSW

Come convenzione di denominazione, utilizzate:

  • ​ldapCarInsurancePropensity

Sostituire ldap con il ldap.

Esempio: per ldap vangeluw, il nome della ricetta dovrebbe essere: vangeluwCarInsurancePropensity.

DSW

Dopo aver immesso un nome per la ricetta, fate clic su OK.

Viene visualizzata una seconda finestra a comparsa in cui viene indicato che è in corso la creazione della Ricetta. L'operazione potrebbe richiedere fino a 5 minuti. Attendere il termine del processo.

DSW

È possibile visualizzare l'avanzamento del processo di creazione delle ricette nell'angolo superiore destro di Jupyter Notebooks.

DSW

Non fare altro, è necessario tenere aperta questa finestra del browser sul notebook con il processo di creazione delle ricette in corso.

Dopo un paio di minuti, la creazione della ricetta è finita.

Fate clic su Visualizza ricette nella finestra a comparsa.

DSW

Vedrete tutte le ricette disponibili, che ora include anche la vostra Ricetta.

DSW

Ora che hai creato la tua ricetta, continuiamo con il prossimo esercizio in cui inizierai formazione e sperimentazione scalabili.

Passaggio successivo: 15.4 Treno e punteggio della tua ricetta

Torna al modulo 15

Torna a tutti i moduli

In questa pagina