15.3 Operacionalize seu modelo usando uma Receita

Neste exercício, você pegará seu modelo e o operacionalizará no Adobe Experience Platform criando uma receita.

O notebook do construtor de receitas modela seu modelo para empacotá-lo e operacionalizá-lo automaticamente. O notebook tem várias células modelo nas quais você ajusta o código do modelo:

  • Os requisitos e as células de configuração permitem que você adicione bibliotecas adicionais e configure conjuntos de dados e parâmetros de ajuste para seu modelo
  • A célula do avaliador permite que você divida seus dados e avalie o desempenho do modelo
  • As células do carregador de dados de treinamento e pontuação permitem carregar os dados necessários para treinamento e pontuação
  • Finalmente, a célula de pipeline contém a lógica necessária para treinamento e pontuação do modelo.

Nós simplificamos as etapas necessárias para operacionalizar um modelo, dando a você a capacidade de treiná-lo, avaliá-lo e marcá-lo em escala e, em seguida, colocá-lo em um fluxo contínuo no Adobe Experience Platform. O empacotamento para uma Receita também permite que você use o mesmo código com conjuntos de dados diferentes para potencializar casos de uso diferentes em suas organizações. Nosso caso de uso específico envolve o uso do código do modelo de recomendações para usuários que procuram produtos para comprar no site.

Faça logon na Adobe Experience Platform acessando este URL: https://experience.adobe.com/platform.

Depois de fazer logon, você chegará na página inicial do Adobe Experience Platform.

Assimilação de dados

Antes de continuar, tem de selecionar uma caixa de proteção. O nome da caixa de proteção a ser selecionada é --aepSandboxId--. Para fazer isso, clique no texto Production Prod (Produto de produção) na linha azul na parte superior da tela.

Assimilação de dados

Depois de selecionar a caixa de proteção apropriada, você verá a tela mudar e agora está na sua caixa de proteção dedicada.

Assimilação de dados

No Adobe Experience Platform, clique em Notebooks no menu no lado esquerdo da tela e vá para JupyterLab.

Assimilação de dados

Em Notebooks de Júpiter, abra a página Iniciador clicando no ícone + na barra de tarefas.

DSW

Você verá isso:

DSW

Abra um bloco de anotações em branco do Construtor de receitas clicando no botão Construtor de receitas no Iniciador.

DSW

Você terá um novo notebook vazio e vazio do Recipe Builder. Antes de continuar, dê um nome descritivo ao seu bloco de anotações. Clique com o botão direito do mouse no arquivo [Python 3] Recipe Builder.ipynb e clique em Renomear.

DSW

Digite exchange365-Insurance-sales-propensity.ipynb como o nome do seu notebook e pressione Enter. Você terá isto:

DSW

Neste notebook, você fará o seguinte:

  • Treinar um modelo
  • Pontuar um modelo
  • Criar uma fórmula a partir do modelo

Vamos configurar todas as etapas em detalhes.

Arquivos de configuração

Role para baixo no notebook Construtor de receita até ver Arquivos ​de configuração.

DSW

Agora é necessário atualizar as células para Configuração de treinamento e Configuração de pontuação.

Configuração de treinamento

Clique na célula de Configuração de treinamento.

Antes de fazer qualquer coisa, por favor, prestem atenção! Seja o que for que você fizer, não exclua ou substitua a linha que start com %%write. Esta linha é exigida pelo notebook Construtor de receita.

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

DSW

Você também verá um código semelhante na mesma célula:

{
   "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"
}

Substitua esse código por este código:

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

As variáveis de ambiente aepCarInsuranceInteractionsDatasetId e aepCarInsuranceInteractionsSchemaRef referem-se a uma ID de conjunto de dados que foi criada em sua instância do Adobe Experience Platform e a uma ID de referência de schema de um schema que foi criado em sua instância do Adobe Experience Platform.

aepCarInsuranceInteractionsDatasetId refere-se à ID do conjunto de dados do Sistema de demonstração do conjunto de dados - Conjunto de dados do Evento para o site (Global v1.1), aepCarInsuranceInteractionsSchemaRef refere-se à ID de referência do Schema do Sistema de demonstração do schema - Schema para o site (Web) Global v1.1). Substitua as variáveis de ambiente pela ID do conjunto de dados e pela ID de referência do Schema ao colar o código na célula Configuração de treinamento do seu notebook.

Agora você deve ter algo semelhante na célula Configuração de treinamento:

DSW

Configuração de Pontuação

Clique na célula para Configuração de Pontuação.

Antes de fazer qualquer coisa, por favor, prestem atenção! Seja o que for que você fizer, não exclua ou substitua a linha que start com %%write. Esta linha é exigida pelo notebook Construtor de receita.

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

DSW

Você também verá um código semelhante na mesma célula:

{
   "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>"
}

Substitua esse código por este código:

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

As variáveis de ambiente aepCarInsuranceInteractionsDatasetId, aepMlPredictionsDatasetId e aepMlPredictionsSchemaRef referem-se às IDs do conjunto de dados de conjuntos de dados e ID de Ref do Schema de schemas criados na sua instância Adobe Experience Platform.

aepCarInsuranceInteractionsDatasetId refere-se à ID do conjunto de dados do sistema de demonstração do conjunto de dados - Conjunto de dados do Evento para o site (Global v1.1), aepMlPredictionsDatasetId refere-se à ID do conjunto de dados do sistema de demonstração do conjunto de dados - Conjunto de dados do Perfil para Prefixo ML dictions (Global v1.1), aepMlPredictionsSchemaRef refere-se à ID de Ref. do Schema do Sistema de ​Demonstração de schemas - Schema do Perfil para Previsões ML (Global v1.1). Substitua as variáveis do ambiente pela ID do conjunto de dados e pela ID de referência do Schema ao colar o código na célula Configuração de pontuação no seu notebook.

Agora você deve ter algo semelhante na célula Configuração de Pontuação:

DSW

Arquivo de Carregador de Dados de Treinamento

Role para baixo no notebook Construtor de receitas até ver o Arquivo do carregador de dados de treinamento.

DSW

Agora é necessário atualizar o código do Arquivo do carregador de dados de treinamento.

Antes de fazer qualquer coisa, por favor, prestem atenção! Seja o que for que você fizer, não exclua ou substitua a linha que start com %%write. Esta linha é exigida pelo notebook Construtor de receita.

DSW

Nessa célula, você encontrará um código semelhante a este:

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

Substitua esse código (sem substituir a linha %%write efile) por este código:

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

Agora você deve ter algo semelhante na célula Arquivo do carregador de dados de treinamento:

DSW

Arquivo de Carregador de Dados de Pontuação

Role para baixo no bloco de anotações do Recipe Builder até ver Arquivo do carregador de dados de pontuação.

DSW

Agora é necessário atualizar o código para o Arquivo do Carregador de Dados de Pontuação.

Antes de fazer qualquer coisa, por favor, prestem atenção! Seja o que for que você fizer, não exclua ou substitua a linha que start com %%write. Esta linha é exigida pelo notebook Construtor de receita.

DSW

Nessa célula, você encontrará um código semelhante a este:

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

Substitua esse código (sem substituir a linha %%write efile) por este código:

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

Agora você deve ter algo semelhante na célula Arquivo do Carregador de Dados de Pontuação:

DSW

Arquivo Pipeline

Role para baixo no notebook do Recipe Builder até ver Arquivo Pipeline.

DSW

Agora é necessário atualizar o código do Arquivo Pipeline.

Antes de fazer qualquer coisa, por favor, prestem atenção! Seja o que for que você fizer, não exclua ou substitua a linha que start com %%write. Esta linha é exigida pelo notebook Construtor de receita.

DSW

Nessa célula, você encontrará um código semelhante a este:

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

Substitua esse código (sem substituir a linha %%write efile) por este código:

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

Agora você deve ter algo semelhante na célula Arquivo ​Pipeline:

DSW

Arquivo do avaliador

Role para baixo no bloco de anotações do Construtor de receitas até ver Arquivo do avaliador.

DSW

Agora é necessário atualizar o código do Arquivo do Avaliador.

Antes de fazer qualquer coisa, por favor, prestem atenção! Seja o que for que você fizer, não exclua ou substitua a linha que start com %%write. Esta linha é exigida pelo notebook Construtor de receita.

DSW

Nessa célula, você encontrará um código semelhante a este:

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

Substitua esse código (sem substituir a linha %%write efile) por este código:

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

Agora você deve ter algo semelhante na célula Arquivo do Avaliador:

DSW

Arquivo de economia de dados

Role para baixo no bloco de anotações do Construtor de receitas até ver o Arquivo de economia de dados.

DSW

Agora é necessário atualizar o código para o Arquivo do Data Saver.

Antes de fazer qualquer coisa, por favor, prestem atenção! Seja o que for que você fizer, não exclua ou substitua a linha que start com %%write. Esta linha é exigida pelo notebook Construtor de receita.

DSW

Nessa célula, você encontrará um código semelhante a este:

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)

Substitua esse código (sem substituir a linha %%write efile) por este código:

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)

Agora, você deve ter algo semelhante na célula Arquivo do Data Saver:

DSW

Agora você configurou todo o código necessário para executar seu notebook.

Treinar um modelo

Para treinar um modelo, clique no botão Treinar .

DSW

Clique em Treinar na barra de ferramentas superior para criar uma execução de treinamento no notebook. Isso executa as células do carregador de dados de treinamento, pipeline e avaliador e gera métricas de avaliação para medir o desempenho do modelo. Um registro de comandos e saídas do script de treinamento será exibido no bloco de anotações (sob a célula Avaliador -).

Depois de clicar em Treinar, a Execução de treinamento será start e precisará de alguns minutos para ser concluída.

DSW
DSW
DSW

Quando você clica em Treinamento, as seguintes células são executadas:

  • Arquivo de requisitos
  • Arquivos de configuração - Treinamento
  • Arquivo de Carregador de Dados de Treinamento
  • Arquivo Pipeline
  • Arquivo do avaliador

Pontuar um modelo

A pontuação de um modelo é feita clicando no botão Pontuação .

DSW

Clique em Pontuação na barra de ferramentas superior para criar uma execução de treinamento na célula. Isso executa o carregador de dados de pontuação, o pipeline e as células avaliadoras e gera métricas de avaliação para medir o desempenho do modelo. Um registro de comandos e saídas do script de treinamento será exibido no bloco de anotações (sob a célula pipeline.py ).

Depois de clicar em Pontuação, a Execução de treinamento será start e precisará de alguns minutos para ser concluída.

DSW
DSW
DSW

Quando você clica em Pontuação, as seguintes células são executadas:

  • Arquivo de requisitos
  • Arquivos de configuração - Pontuação
  • Arquivo de Carregador de Dados de Pontuação
  • Arquivo Pipeline
  • Arquivo do avaliador

Além disso, no final da Execução de Pontuação, a saída com pontuações de propensão é armazenada no Adobe Experience Platform, no Conjunto de Dados Sistema de Demonstração - Conjunto de Dados de Perfis para Previsões ML (Global v1.1) .

Você pode verificar isso aqui.

DSW

Criar uma fórmula a partir do modelo

A criação de uma receita é feita clicando no botão Criar receita .

DSW

Quando estiver satisfeito com os resultados do treinamento e da pontuação, você poderá criar uma fórmula. Clique no botão Criar receita para start do processo.

Criar uma receita permite testar seu modelo em escala.

Depois de clicar no botão Criar receita , é necessário digitar um nome para a receita.

DSW

Como convenção de nomenclatura, use:

  • ​ldapCarInsurancePropensity

Substitua ldap pelo ldap.

Exemplo: para ldap vangeluw, o nome da sua receita deve ser: vangeluwCarInsurancePropensity.

DSW

Depois de inserir um Nome de receita, clique em OK.

Um segundo pop-up é exibido, informando que a Receita está sendo criada. Isso pode levar até 5 minutos, aguarde até que o processo termine.

DSW

Você pode visualização o progresso do processo de criação da receita no canto superior direito dos notebooks de Júpiter.

DSW

Não faça mais nada, você precisa manter essa janela do navegador aberta no Bloco de notas com o processo de criação de receita em andamento.

Após alguns minutos, a criação da receita está concluída.

Clique em Fórmulas de Visualização na janela pop-up.

DSW

Você verá todas as Receitas disponíveis, que agora incluem sua Receita também.

DSW

Agora que você criou sua receita, vamos continuar com o próximo exercício no qual você vai start treinamento e experimentação escaláveis.

Próxima etapa: 15.4 Preparar e marcar a receita

Voltar ao módulo 15

Voltar para todos os módulos

Nesta página