15.3 Operationalisieren Sie Ihr Modell mit einem Rezept

In dieser Übung nehmen Sie Ihr Modell und operalisieren es in Adobe Experience Platform, indem Sie ein Rezept erstellen.

Das Rezept-Builder-Notebook stellt Ihr Modell vor, um es automatisch zu verpacken und zu operieren. Das Notebook verfügt über mehrere Vorlagenzellen, in die Sie Ihren Modellcode einpassen:

  • Mithilfe der Anforderungen und Konfigurationszellen können Sie zusätzliche Bibliotheken hinzufügen sowie Datasets und Tuning-Parameter für Ihr Modell konfigurieren.
  • Mithilfe der Bewertungszelle können Sie Ihre Daten aufteilen und die Leistung Ihres Modells bewerten.
  • Mithilfe der Laderzellen für Schulungs- und Bewertungsdaten können Sie die Daten laden, die Sie für die Schulung und Bewertung benötigen
  • Schließlich enthält die Pipeline-Zelle eine Logik, die sowohl für die Schulung als auch für die Bewertung Ihres Modells erforderlich ist.

Wir haben die für die Operationalisierung eines Modells erforderlichen Schritte gestrafft, indem wir Ihnen die Möglichkeit geben, das Modell im Maßstab zu trainieren, auszuwerten und zu bewerten und es dann in einem nahtlosen Fluss auf Adobe Experience Platform zu verpacken. Die Verpackung in ein Rezept ermöglicht Ihnen auch, denselben Code mit verschiedenen Datensätzen zu verwenden, um verschiedene Anwendungsfälle in Ihrem Unternehmen zu ermöglichen. Unser spezifischer Anwendungsfall dreht sich um die Verwendung des Empfehlungsmodellcodes für Benutzer, die Produkte auf der Website suchen, die sie kaufen möchten.

Melden Sie sich unter folgender URL bei Adobe Experience Platform an: https://experience.adobe.com/platform.

Nach dem Anmelden landen Sie auf der Homepage von Adobe Experience Platform.

Datenaufnahme

Bevor Sie fortfahren, müssen Sie eine Sandbox auswählen. Die auszuwählende Sandbox hat den Namen --aepSandboxId--. Klicken Sie dazu auf den Text Produktions-Prod in der blauen Zeile oben auf Ihrem Bildschirm.

Datenaufnahme

Nachdem Sie die entsprechende Sandbox ausgewählt haben, sehen Sie die Änderung des Bildschirms, und jetzt befinden Sie sich in Ihrer eigenen Sandbox.

Datenaufnahme

Klicken Sie in Adobe Experience Platform auf Notebooks im Menü links auf Ihrem Bildschirm und gehen Sie dann zu JupyterLab.

Datenaufnahme

Öffnen Sie in Jupyter-Notebooks die Seite Starter , indem Sie in der Taskleiste auf das Symbol + klicken.

DSW

Dann sehen Sie Folgendes:

DSW

Öffnen Sie ein leeres Rezept Builder -Notebook, indem Sie im Starter auf die Schaltfläche Rezepturaufbau klicken.

DSW

Dann haben Sie ein leeres neues Rezept Builder-Notebook. Bevor Sie fortfahren, geben Sie Ihrem Notebook einen beschreibenden Namen. Klicken Sie mit der rechten Maustaste auf die Datei [Python 3] Recipe Builder.ipynb und klicken Sie auf Umbenennen.

DSW

Geben Sie als Namen für Ihr Notebook den Eintrag gegenseitige365-Versicherung-sales-neisity.ipynb ein und drücken Sie die Eingabetaste. Dann haben Sie Folgendes:

DSW

In diesem Notebook führen Sie die folgenden Schritte aus:

  • Modell trainieren
  • Modellbewertung
  • Erstellen eines Rezepts aus dem Modell

Konfigurieren wir alle Schritte im Detail.

Konfigurationsdateien

Blättern Sie im Rezept Builder-Notebook nach unten, bis Sie die Konfigurationsdateien sehen.

DSW

Sie müssen jetzt die Zellen für die Schulungskonfiguration und Bewertungskonfiguration aktualisieren.

Schulungskonfiguration

Klicken Sie in die Zelle für die Schulungskonfiguration.

Bevor du etwas machst, achte bitte auf!! Was auch immer Sie tun, löschen oder überschreiben Sie nicht die Zeile, die Beginn mit %%writeFile. Diese Linie ist für das Rezept Builder-Notebook erforderlich.

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

DSW

Sie sehen auch ähnlichen Code in derselben Zelle:

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

Ersetzen Sie diesen Code durch folgenden Code:

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

Die Umgebung-Variablen aepCarInsuranceInteractionsDataSetId und aepCarInsuranceInteractionsSchemaRef beziehen sich auf eine Dataset-ID des Datensatzes, der in Ihrer Adobe Experience Platform-Instanz erstellt wurde, und auf eine Schema-ref-ID eines Schemas, das in Ihrer Adobe Experience Platform-Instanz erstellt wurde.

aepCarInsuranceInteractionsDatasetId bezieht sich auf die Dataset-ID des Dataset Demo Systems - Ereignis DataSet for Website (Global v1.1), aepCarInsuranceInteractionsSchemaRef bezieht sich auf die Schema-Ref-ID des Schema Demo Systems - Ereignis Schema for Website (Global v1 1). Ersetzen Sie die Umgebung durch die Datensatzkennungen-ID und Schema-Ref-ID, wenn Sie den Code in die Schulungskonfigurationszelle Ihres Notebooks einfügen.

Sie sollten jetzt eine ähnliche Funktion in der Zelle Schulungskonfiguration haben:

DSW

Bewertungskonfiguration

Klicken Sie in die Zelle für die Scoring-Konfiguration.

Bevor du etwas machst, achte bitte auf!! Was auch immer Sie tun, löschen oder überschreiben Sie nicht die Zeile, die Beginn mit %%writeFile. Diese Linie ist für das Rezept Builder-Notebook erforderlich.

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

DSW

Sie sehen auch ähnlichen Code in derselben Zelle:

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

Ersetzen Sie diesen Code durch folgenden Code:

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

Die Umgebung-Variablen aepCarInsuranceInteractionsDataSetId, aepMlPredictionsDatasetId und aepMlPredictionsSchemaRef beziehen sich auf die DataSet-IDs von Datensätzen und die Schema-Ref-ID von Schemas, die in Ihrer Adobe Experience Platform-Instanz erstellt wurden.

aepCarInsuranceInteractionsDatasetId bezieht sich auf die Dataset-ID des Dataset Demo Systems - Ereignis DataSet for Website (Global v1.1), aepMlPredictionsDataSetId bezieht sich auf die Dataset-ID des Dataset Demo Systems - Profil DataSet for ML Predictions (Global v1.1), aepMlPredictionsSchemaRef bezieht sich auf die Schema-Ref-ID des Schema ​Demo System - Profil Schemas for ML Predictions (Global v1.1) Schemas. Ersetzen Sie die Umgebung durch die Datensatzkennungen-ID und Schema-Ref-ID, wenn Sie den Code in die Bewertungskonfigurationszelle Ihres Notebooks einfügen.

Sie sollten jetzt eine ähnliche Funktion in der Zelle Scoring Configuration haben:

DSW

Schulungsdatenladedatei

Blättern Sie im Rezept Builder-Notebook nach unten, bis die Schulungsdatenladedatei angezeigt wird.

DSW

Sie müssen jetzt den Code für die Schulungsdatenladedatei aktualisieren.

Bevor du etwas machst, achte bitte auf!! Was auch immer Sie tun, löschen oder überschreiben Sie nicht die Zeile, die Beginn mit %%writeFile. Diese Linie ist für das Rezept Builder-Notebook erforderlich.

DSW

In dieser Zelle finden Sie Code wie folgt:

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

Ersetzen Sie diesen Code (ohne die Zeile %%writeFile zu überschreiben) durch folgenden Code:

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

Sie sollten jetzt in der Zelle "Datenladedatei für Schulungsdaten"etwas Ähnliches haben:

DSW

Datenladedatei auswerten

Blättern Sie im Rezept-Builder-Notebook nach unten, bis die Datei Scoring Data Loader angezeigt wird.

DSW

Sie müssen jetzt den Code für die Datenladedatei"Scoring"aktualisieren.

Bevor du etwas machst, achte bitte auf!! Was auch immer Sie tun, löschen oder überschreiben Sie nicht die Zeile, die Beginn mit %%writeFile. Diese Linie ist für das Rezept Builder-Notebook erforderlich.

DSW

In dieser Zelle finden Sie Code wie folgt:

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

Ersetzen Sie diesen Code (ohne die Zeile %%writeFile zu überschreiben) durch folgenden Code:

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

Sie sollten jetzt in der Zelle "Datenladedatei auswerten"etwas Ähnliches haben:

DSW

Pipeline-Datei

Blättern Sie im Rezept Builder-Notebook nach unten, bis die Pipeline-Datei angezeigt wird.

DSW

Sie müssen jetzt den Code für die Pipeline-Datei aktualisieren.

Bevor du etwas machst, achte bitte auf!! Was auch immer Sie tun, löschen oder überschreiben Sie nicht die Zeile, die Beginn mit %%writeFile. Diese Linie ist für das Rezept Builder-Notebook erforderlich.

DSW

In dieser Zelle finden Sie Code wie folgt:

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

Ersetzen Sie diesen Code (ohne die Zeile %%writeFile zu überschreiben) durch folgenden Code:

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

Sie sollten jetzt in der Zelle "Pipeline-Datei "etwas Ähnliches haben:

DSW

Bewertungsdatei

Blättern Sie im Rezept-Builder-Notebook nach unten, bis die Bewertungsdatei angezeigt wird.

DSW

Sie müssen jetzt den Code für die Bewertungsdatei aktualisieren.

Bevor du etwas machst, achte bitte auf!! Was auch immer Sie tun, löschen oder überschreiben Sie nicht die Zeile, die Beginn mit %%writeFile. Diese Linie ist für das Rezept Builder-Notebook erforderlich.

DSW

In dieser Zelle finden Sie Code wie folgt:

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

Ersetzen Sie diesen Code (ohne die Zeile %%writeFile zu überschreiben) durch folgenden Code:

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

Sie sollten jetzt in der Zelle Bewertungsdatei etwas Ähnliches haben:

DSW

Datenspeicherdatei

Blättern Sie im Rezept Builder-Notebook nach unten, bis die Datenspeicherdatei angezeigt wird.

DSW

Sie müssen jetzt den Code für die Datenspeicherdatei aktualisieren.

Bevor du etwas machst, achte bitte auf!! Was auch immer Sie tun, löschen oder überschreiben Sie nicht die Zeile, die Beginn mit %%writeFile. Diese Linie ist für das Rezept Builder-Notebook erforderlich.

DSW

In dieser Zelle finden Sie Code wie folgt:

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)

Ersetzen Sie diesen Code (ohne die Zeile %%writeFile zu überschreiben) durch folgenden Code:

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)

Sie sollten nun in der Zelle "Datenspeicherdatei "etwas Ähnliches haben:

DSW

Sie haben jetzt den gesamten Code konfiguriert, den Sie zum Ausführen Ihres Notebooks benötigen.

Modell trainieren

Die Schulung eines Modells erfolgt durch Klicken auf die Schaltfläche Zug .

DSW

Klicken Sie in der oberen Symbolleiste auf Zug , um einen Schulungslauf im Notebook zu erstellen. Dadurch werden die Zellen für Schulungsdatenlader, Pipeline- und Bewertungszellen ausgeführt und Bewertungsmetriken zur Messung der Modellleistung generiert. Ein Protokoll mit Befehlen und Ausgängen aus dem Schulungsskript wird im Notebook angezeigt (unter der Zelle "Bewerter -").

Nachdem Sie auf Zug geklickt haben, wird der Schulungslauf Beginn und dauert einige Minuten.

DSW
DSW
DSW

Wenn Sie auf Train klicken, werden die folgenden Zellen ausgeführt:

  • Anforderungsdatei
  • Konfigurationsdateien - Schulung
  • Schulungsdatenladedatei
  • Pipeline-Datei
  • Bewertungsdatei

Modellbewertung

Die Bewertung eines Modells erfolgt durch Klicken auf die Schaltfläche Ergebnis .

DSW

Klicken Sie in der oberen Symbolleiste auf Ergebnis , um eine Schulungsausführung in der Zelle zu erstellen. Dadurch werden die Zellen für die Datenladefunktion, die Pipeline- und die Bewertungszelle ausgeführt und Bewertungsmetriken zur Messung der Modellleistung generiert. A log of commands and outputs from the training script will appear in the notebook (under the pipeline.py cell).

Nachdem Sie auf Ergebnis geklickt haben, wird der Schulungslauf Beginn und dauert einige Minuten.

DSW
DSW
DSW

Wenn Sie auf Ergebnis klicken, werden die folgenden Zellen ausgeführt:

  • Anforderungsdatei
  • Konfigurationsdateien - Bewertung
  • Datenladedatei auswerten
  • Pipeline-Datei
  • Bewertungsdatei

Zusätzlich wird am Ende des Scoring-Run die Ausgabe mit Tendenzwerten in Adobe Experience Platform gespeichert, im Demo System - Profil DataSet für ML Predictions (Global v1.1) DataSet.

Sie können dies hierüberprüfen.

DSW

Erstellen eines Rezepts aus dem Modell

Das Erstellen eines Rezepts erfolgt durch Klicken auf die Schaltfläche Rezept erstellen .

DSW

Wenn Sie mit den Ergebnissen von Schulungen und Bewertungen zufrieden sind, können Sie ein Rezept erstellen. Klicken Sie auf die Schaltfläche "Rezept erstellen ", um den Prozess Beginn.

Wenn Sie ein Rezept erstellen, können Sie Ihr Modell im Maßstab testen.

Nachdem Sie auf die Schaltfläche Rezept erstellen geklickt haben, müssen Sie einen Namen für Ihr Rezept eingeben.

DSW

Als Benennungskonvention verwenden Sie bitte:

  • ​ldapCarInsurancePropensity

Ersetzen Sie ldap durch Ihren ldap.

Beispiel: für ldap vangeluw sollte der Name Ihres Rezepts wie folgt lauten: vangeluwCarInsurancePropensity.

DSW

Klicken Sie nach Eingabe des Rezeptnamen auf OK.

Es wird ein zweites Popup mit einer Meldung angezeigt, dass Ihr Rezept erstellt wurde. Dies kann bis zu 5 Minuten dauern. Warten Sie, bis der Prozess abgeschlossen ist.

DSW

Sie können den Fortschritt des Rezepterstellungsprozesses in der oberen rechten Ecke von Jupyter-Notebooks Ansicht leisten.

DSW

Tun Sie nichts anderes, Sie müssen dieses Browserfenster auf dem Notebook geöffnet lassen, während der Prozess der Rezepterstellung läuft.

Nach einigen Minuten ist die Rezepterstellung abgeschlossen.

Klicken Sie im Popup-Fenster auf Ansicht Rezepte .

DSW

Dann sehen Sie alle verfügbaren Rezepte, die jetzt auch Ihre Rezepte enthalten.

DSW

Nachdem Sie Ihr Rezept erstellt haben, fahren wir mit der nächsten Übung fort, in der Sie skalierbare Schulungen und Experimente Beginn geben.

Nächster Schritt: 15.4 Ausbildung und Bewertung des Rezepts

Zurück zu Modul 15

Zurück zu allen Modulen

Auf dieser Seite