使用Jupyter Notebooks创建菜谱

本教程将分两个主要部分。 首先,您将使用JupyterLab Notebook中的模板创建机器学习模型。 接下来,您将练习笔记本到JupyterLab中的菜谱工作流,以在Data Science Workspace中创建菜谱。

引入的概念:

  • 菜谱: 菜谱是模型规范的Adobe术语,是表示特定机器学习、AI算法或集成算法、处理逻辑和配置的顶级容器,构建和执行经过培训的模型时需要这些功能,因此有助于解决特定的业务问题。
  • 模型: 模型是机器学习方法的实例,该方法使用历史数据和配置进行培训,以便针对业务用例进行解决。
  • 培训: 培训是从标记数据中学习模式和洞察的过程。
  • 评分: 评分是使用经过培训的模型从数据生成洞察的过程。

开始使用JupyterLab笔记本环境

可以在Data Science Workspace中从头开始创建菜谱。 要进行开始,请导航到Adobe Experience Platform并单击左侧的​Notebooks​选项卡。 从JupyterLab Launcher中选择Recipe Builder模板,创建新笔记本。

Recipe Builder笔记本可以在笔记本内运行培训和评分。 这使您能够灵活地在对培训和评分数据运行实验之间更改其train()score()方法。 一旦您对培训和评分的输出感到满意,您就可以创建一个菜谱,在Data Science Workspace中使用笔记本创建菜谱功能,该功能内置于菜谱生成器笔记本中。

注意

Recipe Builder笔记本支持使用所有文件格式,但当前“创建菜谱”功能仅支持Python。

单击启动程序中的Recipe Builder笔记本时,将在选项卡中打开该笔记本。 笔记本中使用的模板是Python Retail Sales Forecasing Recipe,也可以在此公共存储库中找到

您会注意到,工具栏中还有三个其他操作,即​TrainScore​和​Create Recipe。 这些图标仅显示在Recipe Builder笔记本中。 在笔记本中构建菜谱后,将在培训和评分部分🔗中讨论有关这些操作的更多信息。

编辑菜谱文件

要编辑菜谱文件,请导航到Jupyter中与文件路径对应的单元格。 例如,如果要对evaluator.py进行更改,请查找%%writefile demo-recipe/evaluator.py

开始对单元格进行必要的更改,完成后,只需运行单元格。 %%writefile filename.py命令将单元格的内容写入filename.py。 您必须手动为每个包含更改的文件运行单元格。

注意

如果适用,您应手动运行单元格。

Recipe Builder笔记本入门

现在,您已了解JupyterLab笔记本环境的基础知识,可开始查看构成机器学习模型菜谱的文件。 下面显示了我们将讨论的文件:

要求文件

要求文件用于声明您希望在菜谱中使用的其他库。 如果存在依赖关系,则可以指定版本号。 要查找其他库,请访问anaconda.org。 要了解如何设置要求文件的格式,请访问Conda。 已在使用的主库的列表包括:

python=3.6.7
scikit-learn
pandas
numpy
data_access_sdk_python
注意

您添加的库或特定版本可能与上述库不兼容。 此外,如果选择手动创建环境文件,则不允许覆盖name字段。

配置文件

配置文件training.confscoring.conf用于指定要用于培训和评分以及添加超参数的数据集。 培训和评分有不同的配置。

用户在运行培训和评分之前必须填写以下变量:

  • trainingDataSetId
  • ACP_DSW_TRAINING_XDM_SCHEMA
  • scoringDataSetId
  • ACP_DSW_SCORING_RESULTS_XDM_SCHEMA
  • scoringResultsDataSetId

要查找数据集和模式ID,请转到左侧导航栏(文件夹图标下)笔记本内的“数据”选项卡“数据”选项卡

在​模式​和​数据集​选项卡下的Adobe Experience Platform上可以找到相同的信息。

默认情况下,在访问数据时会为您设置以下配置参数:

  • ML_FRAMEWORK_IMS_USER_CLIENT_ID
  • ML_FRAMEWORK_IMS_TOKEN
  • ML_FRAMEWORK_IMS_ML_TOKEN
  • ML_FRAMEWORK_IMS_TENANT_ID

培训数据加载器

培训数据加载器的目的是实例化用于创建机器学习模型的数据。 通常,培训数据加载器将完成以下两个任务:

  • 从Platform加载数据
  • 数据准备和功能工程

以下两节将重新介绍加载数据和数据准备。

正在加载数据

此步骤使用dataframe。 可以使用Platform SDK(platform_sdk)从Adobe Experience Platform中的文件加载数据,或使用熊猫' read_csv()read_json()函数从外部源加载数据。

注意

在Recipe Builder笔记本中,数据通过platform_sdk数据加载器加载。

Platform SDK

有关使用platform_sdk数据加载器的详细教程,请访问平台SDK指南。 本教程提供有关构建身份验证、基本读取数据和基本写入数据的信息。

外部源

本节将向您介绍如何将JSON或CSV文件导入到pacantis对象。 熊猫图书馆的官方文件可在以下网址找到:

首先,下面是导入CSV文件的示例。 data参数是CSV文件的路径。 此变量是从上一节中的configProperties导入的。

df = pd.read_csv(data)

您还可以从JSON文件导入。 data参数是CSV文件的路径。 此变量是从上一节中的configProperties导入的。

df = pd.read_json(data)

现在,您的数据位于数据帧对象中,可在下一节中分析和处理数据。

从Platform SDK

您可以使用平台SDK加载数据。 可通过包含以下行,在页面顶部导入库:

from platform_sdk.dataset_reader import DatasetReader

然后,我们使用load()方法从trainingDataSetId中按配置(recipe.conf)文件中的设置获取培训数据集。

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

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

配置文件部分中所述,当您使用client_context从Experience Platform访问数据时,将为您设置以下配置参数:

  • ML_FRAMEWORK_IMS_USER_CLIENT_ID
  • ML_FRAMEWORK_IMS_TOKEN
  • ML_FRAMEWORK_IMS_ML_TOKEN
  • ML_FRAMEWORK_IMS_TENANT_ID

现在您掌握了数据,您可以从数据准备和功能工程开始。

数据准备和功能工程

加载数据后,将准备数据,然后将其拆分到trainval数据集。 示例代码如下所示:

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

在此示例中,对原始数据集有五项操作:

  • 添加weekyear
  • storeType转换为指示符变量
  • isHoliday转换为数字变量
  • 偏移weeklySales以获得未来和过去的销售值
  • 按日期将数据拆分为trainval数据集

首先,创建weekyear列,并将原始date列转换为Python datetime。 周值和年值从日期时间对象中提取。

接下来,将storeType转换为表示三种不同存储类型(ABC)的三列。 每个值都将包含一个布尔值,其状态storeType为true。 将删除storeType列。

同样,weeklySalesisHoliday布尔值更改为数字表示形式,1或0。

此数据在trainval数据集之间拆分。

load()函数应以trainval数据集作为输出。

评分数据加载器

加载评分数据的过程与split()函数中加载培训数据的过程类似。 我们使用Data Access SDK从recipe.conf文件中的scoringDataSetId加载数据。

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

在加载数据后,进行数据准备和特征工程。

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

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

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

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

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

    print("Scoring Data Load Finish")

    return dataframe

由于我们模型的目的是预测未来的每周销售,因此您需要创建一个评分数据集来评估模型的预测效果。

此Recipe Builder笔记本通过向前7天抵销我们的每周销售额来实现此目的。 请注意,每周有45个存储区的测量值,这样您就可以将45个数据集的weeklySales值转发到名为weeklySalesAhead的新列。

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

同样,您也可以通过向后移动45来创建列weeklySalesLag。 使用此选项,您还可以计算每周销售额的差值,并将它们存储在列weeklySalesDiff中。

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

由于您正在向前偏移weeklySales数据点45个数据集,向后偏移45个数据集以创建新列,因此前45个数据点将具有NaN值。 您可以使用df.dropna()函数从数据集中删除这些点,该函数会删除所有具有NaN值的行。

df.dropna(0, inplace=True)

您的评分数据加载器中的load()函数应以评分数据集作为输出完成。

管道文件

pipeline.py文件包含培训和评分逻辑。

培训

培训的目的是使用培训数据集中的功能和标签创建模型。

注意

特征是指机器学习模型用来预测标签的输入变量。

train()函数应包括培训模型并返回培训模型。 不同型号的一些示例可在scikit-learn用户指南文档中找到。

选择培训模型后,您会将x和y培训数据集拟合到该模型,该函数将返回培训的模型。 说明此问题的示例如下:

def train(configProperties, data):

    print("Train Start")

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


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

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

    model.fit(X_train, y_train)

    print("Train Complete")

    return model

请注意,根据您的应用程序,您的GradientBoostingRegressor()函数中将包含参数。 xTrainingDataset 应包含用于培训的功能,而 yTrainingDataset 应包含标签。

评分

score()函数应包含评分算法并返回一个度量,以指示模型执行的成功程度。 score()函数使用评分数据集标签和训练的模型来生成一组预测特征。 然后,将这些预测值与评分数据集中的实际特征进行比较。 在此示例中,score()函数使用经过训练的模型来使用评分数据集中的标签来预测特征。 返回预测特征。

def score(configProperties, data, model):

    print("Score Start")

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

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

    print("Score Complete")

    return data

求值器文件

evaluator.py文件包含如何评估培训菜谱以及如何拆分培训数据的逻辑。 在零售销售示例中,将包含加载和准备培训数据的逻辑。 我们将浏览以下两节。

拆分数据集

培训的数据准备阶段需要拆分要用于培训和测试的数据集。 此val数据将隐式用于在模型训练后评估模型。 此过程与评分分开。

本节将显示split()函数,该函数将首先将数据加载到笔记本中,然后通过删除数据集中的不相关列来清理数据。 从那里,您将能够执行功能工程,即根据数据中的现有原始功能创建其他相关功能的过程。 下面显示了此过程的示例和说明。

split()函数如下所示。 参数中提供的数据帧将拆分为要返回的trainval变量。

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

    return train, val

评估已训练的模型

evaluate()函数在模型训练后执行,并将返回一个度量来指示模型执行的成功程度。 evaluate()函数使用测试数据集标签和“训练”模型来预测一组特征。 然后将这些预测值与测试数据集中的实际特征进行比较。 常见评分算法包括:

零售销售示例中的evaluate()函数如下所示:

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

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

    return metric

请注意,该函数返回一个metric对象,其中包含一个评估量度数组。 这些量度将用于评估训练模型的效果。

数据保护程序文件

datasaver.py文件包含save()函数,用于在测试评分时保存您的预测。 save()函数将进行预测,并使用Experience Platform Catalog API将数据写入您在scoring.conf文件中指定的scoringResultsDataSetId

在零售销售示例菜谱中使用的示例在此处可见。 请注意使用DataSetWriter库将数据写入平台:

from data_access_sdk_python.writer import DataSetWriter

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

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

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

    print("Writer Configured")

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

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

培训和评分

在对笔记本进行更改并要培训菜谱后,您可以单击栏顶部的关联按钮在单元格中创建培训运行。 单击该按钮后,培训脚本的命令和输出日志将显示在笔记本(evaluator.py单元格下)中。 首先安装所有依赖项,然后启动培训。

请注意,必须至少运行一次培训,然后才能运行评分。 单击​Run Scoring​按钮将对培训期间生成的培训模型得分。 评分脚本将显示在datasaver.py下。

出于调试目的,如果要查看隐藏输出,请将debug添加到输出单元格的末尾,然后重新运行它。

创建菜谱

编辑菜谱并满足培训/评分输出后,可以按右上方导航中的​Create Recipe​从笔记本创建菜谱。

按下按钮后,系统会提示您输入菜谱名称。 此名称表示在Platform上创建的实际处方。

按​Ok​后,您将能够导航到Adobe Experience Platform上的新菜谱。 单击​View Recipes​按钮可转到​ML Models​下的​Recipes​选项卡

一旦流程完成,菜谱将显示如下内容:

注意
  • 请勿删除任何文件单元格
  • 请勿编辑文件单元格顶部的%%writefile
  • 请勿同时在不同笔记本中创建菜谱

后续步骤

完成本教程后,您学会了如何在Recipe Builder笔记本中创建机器学习模型。 您还学习了如何在笔记本中练习笔记本至菜谱工作流,以在Data Science Workspace中创建菜谱。

要继续学习如何使用Data Science Workspace中的资源,请访问Data Science Workspace菜谱和模型下拉列表。

其他资源

以下视频旨在帮助您理解构建和部署模型。

在此页面上