MLFlow-机器学习工程-一-

68 阅读1小时+

MLFlow 机器学习工程(一)

原文:annas-archive.org/md5/e98213c48352ec428afb655035096e6f

译者:飞龙

协议:CC BY-NC-SA 4.0

前言

基于机器学习的产品实施可能是一项费力的任务。普遍需要减少机器学习开发生命周期不同步骤之间的摩擦,以及参与过程中的数据科学家和工程师团队之间的摩擦。

机器学习从业者,如数据科学家和机器学习工程师,使用不同的系统、标准和工具。虽然数据科学家大部分时间在 Jupyter Notebook 等工具中开发模型,但在生产运行时,模型是在一个对规模和可靠性要求更高的软件应用环境中部署的。

在本书中,您将了解 MLflow 以及有助于您机器学习生命周期的机器学习工程实践,包括数据获取、准备、训练和部署。本书的内容基于开放接口设计,将与任何语言或平台兼容。在可扩展性和可重复性方面,您也将从中受益。

在本书结束时,您将能够轻松地使用 MLflow 设置模型开发环境,构建您的机器学习问题,并使用标准化框架来设置您自己的机器学习系统。如果您正在实施您的第一个生产级机器学习项目,本书也将特别有用。

本书面向对象

本书面向软件、机器学习以及数据科学专业人士或爱好者,他们希望探索生产中机器学习系统的工程方面。机器学习从业者将能够通过这本实用的 MLflow 指南将他们的知识付诸实践。本书采用动手实践的方法来实施相关方法,让您能够迅速上手 MLflow。本书的基本要求是具备 Python 编程经验以及了解 Bash 终端和命令。

本书涵盖内容

第一章介绍 MLflow,将概述 MLflow 的不同功能,指导您安装和探索平台的核心功能。阅读本章后,您将能够在本地上安装和操作您的 MLflow 环境。

第二章您的机器学习项目,将介绍本书的重点。本书的方法是通过一个实际业务案例,即股票市场预测,来探索 MLflow 的所有不同功能。将使用问题框架框架让您深入了解书中使用的示例。本书的其余部分将创建一个示例管道供使用。

第三章, 您的数据科学工作台,帮助您了解如何使用 MLflow 创建本地环境,以便您可以在本地使用 MLflow 提供的一切不同功能来开发机器学习项目。

第四章, MLflow 中的实验管理,您将通过创建不同的模型并在 MLflow 中比较不同运行的指标来获得股票预测的实际经验。您将得到指导,了解如何部署跟踪服务器,以便许多机器学习从业者可以共享指标并改进模型。

第五章, 使用 MLflow 管理模型,探讨了 MLflow 中模型创建的不同功能。将涵盖内置模型,如 PyTorch 和 TensorFlow 模型,以及 MLflow 中不可用的自定义模型。将介绍模型生命周期,以及 MLflow 的模型注册功能。

第六章, 介绍 ML 系统架构,讨论了正确架构机器学习系统的必要性以及 MLflow 如何融入端到端机器学习系统的画面中。

第七章, 数据和特征管理,介绍了数据和特征管理。将阐明特征生成的重要性,以及如何使用特征流通过 MLflow 记录模型结果。

第八章, 使用 MLflow 训练模型,将描述并开发针对当前问题的完整训练管道基础设施,并使用 MLflow 特定的功能。

第九章, 使用 MLflow 进行部署和推理,将使用 MLflow 的 API 和批量功能暴露我们的机器学习系统的端到端部署基础设施,包括推理组件。还将描述 MLflow 的云启用功能。

第十章, 扩展您的机器学习工作流程,涵盖了与高性能/大数据库的集成,这些库允许 MLflow 系统扩展以处理大量数据。

第十一章, 性能监控,探讨了机器学习操作的重要领域以及如何使用最佳实践和操作模式确保书中开发的生成系统平稳运行。

第十二章, MLFlow 的高级主题,展示了包含完整 MLflow 管道的高级案例研究。这些案例研究使用了与本书其他部分所讨论的不同类型的模型,以确保对 MLflow 的特征覆盖范围广泛。

为了充分利用本书

理想情况下,在开始阅读本书之前,您应该对 Python 编程语言有很好的掌握,并且已经创建了基本的机器学习模型。一门机器学习入门课程将有助于将本书中讨论的概念置于上下文中。

图片

如果您正在使用本书的数字版,我们建议您亲自输入代码或从本书的 GitHub 仓库(下一节中有一个链接)获取代码。这样做将帮助您避免与代码复制和粘贴相关的任何潜在错误。

下载示例代码文件

您可以从 GitHub 下载本书的示例代码文件github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow。如果代码有更新,它将在 GitHub 仓库中更新。

我们还有其他来自我们丰富的图书和视频目录的代码包可供选择,请访问github.com/PacktPublishing/。查看它们!

下载彩色图像

我们还提供了一份包含本书中使用的截图和图表彩色图像的 PDF 文件。您可以从这里下载:static.packt-cdn.com/downloads/9781800560796_ColorImages.pdf

使用的约定

本书使用了多种文本约定。

文本中的代码:表示文本中的代码单词、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 昵称。以下是一个示例:“model.pkl文件包含模型的序列化版本”

代码块按以下方式设置:

import mlflow
from sklearn.linear_model import LogisticRegression
mlflow.sklearn.autolog()
with mlflow.start_run():
    clf = LogisticRegression()
    clf.fit(X_train, y_train)

任何命令行输入或输出都按以下方式编写:

docker build -t stockpred -f dockerfile

粗体: 表示新术语、重要单词或您在屏幕上看到的单词。例如,菜单或对话框中的单词以粗体显示。以下是一个示例:“MLflow是一个开源平台,用于**机器学习(ML)**生命周期”

小贴士或重要提示

看起来像这样。

联系我们

读者的反馈总是受欢迎的。

一般反馈: 如果您对本书的任何方面有疑问,请通过 customercare@packtpub.com 给我们发邮件,并在邮件主题中提及书名。

勘误表: 尽管我们已经尽最大努力确保内容的准确性,但错误仍然可能发生。如果您在这本书中发现了错误,如果您能向我们报告,我们将不胜感激。请访问www.packtpub.com/support/err…并填写表格。

盗版: 如果您在互联网上以任何形式发现我们作品的非法副本,如果您能向我们提供位置地址或网站名称,我们将不胜感激。请通过版权@packt.com 与我们联系,并提供材料的链接。

如果您有兴趣成为作者: 如果您在某个领域有专业知识,并且您有兴趣撰写或为书籍做出贡献,请访问authors.packtpub.com

分享您的想法

一旦您阅读了《使用 MLflow 的机器学习工程》,我们非常期待听到您的想法!扫描下面的二维码直接进入此书的亚马逊评论页面并分享您的反馈。

二维码图片

packt.link/r/1-800-56079-6

您的评论对我们和科技社区都非常重要,它将帮助我们确保我们提供的是高质量的内容。

第一部分:问题界定与介绍

本节将向您介绍使用 MLflow 以简洁明了的方式陈述机器学习问题的框架。

本节涵盖了以下章节:

  • 第一章, 介绍 MLflow

  • 第二章, 您的机器学习项目

第一章:介绍 MLflow

MLflow是一个专注于机器学习ML)生命周期、可重复性训练部署的开源平台。它基于开放的接口设计,能够与任何语言或平台协同工作,拥有 Python 和 Java 客户端,并通过 REST API 提供访问。可扩展性也是 ML 开发者可以利用的 MLflow 的一个重要优势。

在本书的这一章中,我们将通过示例和示例代码来查看 MLflow 的工作原理。这将建立使用该概念来构建端到端 ML 项目的必要基础。

具体来说,我们将在本章中查看以下部分:

  • 什么是 MLflow?

  • 开始使用 MLflow

  • 探索 MLflow 模块

技术要求

对于本章,你需要以下先决条件:

  • 在您的机器上安装了最新版本的 Docker。如果您没有最新版本,请按照以下 URL 的说明操作:docs.docker.com/get-docker/

  • 访问 bash 终端(Linux 或 Windows)。

  • 访问浏览器。

  • 已安装 Python 3.5+。

  • 已安装 PIP。

什么是 MLflow?

基于 ML 的产品实施可能是一项费力的任务。普遍需要减少 ML 开发生命周期不同步骤之间的摩擦,以及参与过程的数据科学家和工程师团队之间的摩擦。

机器学习从业者,如数据科学家和机器学习工程师,使用不同的系统、标准和工具进行操作。虽然数据科学家大部分时间在 Jupyter Notebooks 等工具中开发模型,但在生产环境中运行时,模型是在一个对规模和可靠性要求更高的软件应用环境中部署的。

在 ML 项目中,一个常见的情况是工程团队重新实现模型,创建一个定制的系统来提供特定的模型。对于遵循定制方法的模型开发团队,以下是一些常见的挑战:

  • 由于需要创建定制的软件基础设施来开发和提供模型,导致超出预算的 ML 项目

  • 在重新实现数据科学家产生的模型时出现的翻译错误

  • 在提供预测时遇到的可扩展性问题

  • 由于缺乏标准环境,数据科学家在重现训练过程中出现的摩擦

利用机器学习的公司往往创建自己的(通常是极其费力的)内部系统,以确保机器学习开发过程的顺畅和结构化。广泛记录的机器学习平台包括来自 Uber 和 Facebook 的 Michelangelo 和 FBLearner 等系统。

在机器学习(ML)日益普及的背景下,MLflow 最初在 Databricks 创建,并作为一个平台开源,旨在帮助实现机器学习系统的实施。

MLflow 允许一个日常实践者在单一平台上管理机器学习生命周期,从模型开发的迭代到在兼容现代软件系统要求的可靠和可扩展环境中部署。

开始使用 MLflow

接下来,我们将在您的机器上安装 MLflow 并为其在本章中使用做准备。安装 MLflow 时,您有两个选择。第一个选择是通过书中提供的基于 Docker 容器的配方在存储库中:github.com/PacktPublishing/Machine-Learning-Engineering-with-Mlflow.git

要安装它,请按照以下说明操作:

  1. 使用以下命令安装软件:

    $ git clone https://github.com/PacktPublishing/Machine-Learning-Engineering-with-Mlflow.git
    $ cd Machine-Learning-Engineering-with-Mlflow
    $ cd Chapter01
    
  2. 在这个阶段,Docker 镜像非常简单:它仅包含 MLflow 和 sklearn,这是本书这一章节中要使用的主要工具。为了说明目的,您可以查看 Dockerfile 的内容:

    FROM jupyter/scipy-notebook
    RUN pip install mlflow
    RUN pip install sklearn
    
  3. 要构建镜像,您现在应该运行以下命令:

    docker build -t chapter_1_homlflow
    
  4. 在构建镜像后,您可以运行 ./run.sh 命令:

    ./run.sh
    

    重要提示

    确保您的机器上安装了最新版本的 Docker 非常重要。

  5. 打开您的浏览器,访问 localhost:888,您应该能够导航到 Chapter01 文件夹。

在接下来的部分,我们将使用之前步骤中创建的 Jupyter 环境使用 MLflow 开发我们的第一个模型。

使用 MLflow 开发您的第一个模型

从简单性的角度来看,在本节中,我们将使用 sklearn 内置的样本数据集,这是我们最初用来探索 MLflow 功能的机器学习库。对于本节,我们将选择著名的 Iris 数据集,使用 MLflow 训练一个多类分类器。

Iris 数据集(sklearn 内置数据集之一,可通过 scikit-learn.org/stable/datasets/toy_dataset.html 获取)包含以下作为特征的元素:花瓣长度、花瓣宽度、花萼长度和花萼宽度。目标变量是鸢尾花的类别:Iris Setosa、Iris Versicolor 或 Iris Virginica:

  1. 加载样本数据集:

    from sklearn import datasets
    from sklearn.model_selection import train_test_split
    dataset = datasets.load_iris()
    X_train, X_test, y_train, y_test = train_test_split(dataset.data, dataset.target, test_size=0.4)
    
  2. 接下来,让我们训练您的模型。

    使用 scikit-learn 等框架训练简单的机器学习模型涉及实例化一个估算器,如 LogisticRegression,并调用 fit 命令在 scikit-learn 内置的 Iris 数据集上执行训练:

    from sklearn.linear_model import LogisticRegression
    clf = LogisticRegression()
    clf.fit(X_train, y_train)
    

    上述代码行只是 ML 工程 流程的一小部分。正如将要展示的,为了将前面的训练代码投入生产并确保其可用性和可靠性,需要创建大量的代码。MLflow 的一个主要目标就是帮助设置 ML 系统和项目的过程。在接下来的章节中,我们将展示如何使用 MLflow 使您的解决方案更加健壮和可靠。

  3. 然后,我们将添加 MLflow。

    通过几行额外的代码,你应该能够开始你的第一个 MLflow 交互。在以下代码列表中,我们首先导入 mlflow 模块,然后是 scikit-learn 中的 LogisticRegression 类。你可以使用附带的 Jupyter 笔记本来运行下一部分:

    import mlflow
    from sklearn.linear_model import LogisticRegression
    mlflow.sklearn.autolog()
    with mlflow.start_run():
        clf = LogisticRegression()
        clf.fit(X_train, y_train)
    

    mlflow.sklearn.autolog() 指令允许您在本地目录中自动记录实验。它捕获了使用的底层机器学习库产生的指标。MLflow Tracking 是负责处理指标和日志的模块。默认情况下,MLflow 运行的元数据存储在本地文件系统中。

  4. 如果你在一个附带的笔记本的根文档上运行以下摘录,你应该现在在你的主目录中有以下文件,这是运行以下命令的结果:

    $ ls -l 
    total 24
    -rw-r--r-- 1 jovyan users 12970 Oct 14 16:30 chapther_01_introducing_ml_flow.ipynb
    -rw-r--r-- 1 jovyan users    53 Sep 30 20:41 Dockerfile
    drwxr-xr-x 4 jovyan users   128 Oct 14 16:32 mlruns
    -rwxr-xr-x 1 jovyan users    97 Oct 14 13:20 run.sh
    

    mlruns 文件夹与你的笔记本文件夹同时生成,包含当前上下文中由你的代码执行的所有实验。

    mlruns 文件夹将包含一个带有顺序编号的文件夹来标识你的实验。文件夹的结构如下所示:

    ├── 46dc6db17fb5471a9a23d45407da680f
    │   ├── artifacts
    │   │   └── model
    │   │       ├── MLmodel
    │   │       ├── conda.yaml
    │   │       ├── input_example.json
    │   │       └── model.pkl
    │   ├── meta.yaml
    │   ├── metrics
    │   │   └── training_score
    │   ├── params
    │   │   ├── C
    │   │   …..
    │   └── tags
    │       ├── mlflow.source.type
    │       └── mlflow.user
    └── meta.yaml
    

    因此,我们几乎不需要付出太多努力,就有很多可追溯性可用,并且有一个很好的基础来改进。

你的实验在先前的样本中被识别为 UUID,由 46dc6db17fb5471a9a23d45407da680f。在目录的根目录下,有一个名为 meta.yamlyaml 文件,其中包含以下内容:

artifact_uri: file:///home/jovyan/mlruns/0/518d3162be7347298abe4c88567ca3e7/artifacts
end_time: 1602693152677
entry_point_name: ''
experiment_id: '0'
lifecycle_stage: active
name: ''
run_id: 518d3162be7347298abe4c88567ca3e7
run_uuid: 518d3162be7347298abe4c88567ca3e7
source_name: ''
source_type: 4
source_version: ''
start_time: 1602693152313
status: 3
tags: []
user_id: jovyan

这是你实验的基本元数据,包括开始时间、结束时间、运行识别(run_idrun_uuid)、生命周期阶段的假设以及执行实验的用户。设置基本上基于默认运行,但提供了关于你实验的有价值和可读的信息:

├── 46dc6db17fb5471a9a23d45407da680f
│   ├── artifacts
│   │   └── model
│   │       ├── MLmodel
│   │  ^   ├── conda.yaml
│   │       ├── input_example.json
│   │       └── model.pkl

model.pkl 文件包含模型的序列化版本。对于 scikit-learn 模型,有一个模型的 Python 代码的二进制版本。在自动记录时,利用了底层机器库的指标。默认的打包策略基于一个 conda.yaml 文件,其中包含正确的依赖关系,以便能够序列化模型。

MLmodel 文件是从 MLflow 项目中关于如何运行当前模型进行推理的主要定义。

metrics 文件夹包含训练过程的这次特定运行的训练分数值,可以用来与后续模型改进进行基准测试。

在文件夹列表的第一项中,params 文件夹包含了逻辑回归模型的默认参数,不同的默认可能性被透明地列出并自动存储。

探索 MLflow 模块

MLflow 模块是软件组件,它们提供了辅助不同机器生命周期阶段的核心理念。MLflow 功能通过模块提供,这些模块是可扩展的组件,它们在平台上组织相关的功能。

以下是在 MLflow 中内置的模块:

  • MLflow 跟踪:提供了一种机制和用户界面来处理由 ML 执行(训练和推理)生成的指标和工件

  • MLflow 项目:一种用于标准化 ML 项目的包格式

  • MLflow 模型:一种机制,可以部署到不同类型的本地和云环境

  • MLflow 模型注册表:一个模块,用于管理 MLflow 中的模型及其生命周期,包括状态

为了探索不同的模块,我们将使用以下命令在您的本地环境中安装 MLflow:

pip install mlflow

重要提示

确保在您的本地机器上正确安装了技术要求,以便您能够跟随操作。您也可以使用具有所需权限的pip命令。

探索 MLflow 项目

MLflow 项目代表 ML 项目的组织基本单位。MLflow 项目支持三种不同的环境:Conda 环境、Docker 和本地系统。

重要提示

可以在官方文档中查看 MLProject 文件上可用的不同参数的模型详细信息,该文档可在www.mlflow.org/docs/latest/projects.html#running-projects找到。

以下是一个conda环境MLproject文件的示例:

name: condapred
conda_env:
  image: conda.yaml
entry_points:
  main:
    command: "python mljob.py"

conda选项中,假设存在一个包含所需依赖项的conda.yaml文件。当 MLflow 被要求运行项目时,它将使用指定的依赖项启动环境。

基于系统的环境将如下所示;实际上相当简单:

name: syspred
entry_points:
  main:
    command: "python mljob.py"

上述系统变体将基本上依赖于本地环境依赖项,假设底层操作系统包含所有依赖项。这种方法特别容易与底层操作系统发生库冲突;在已经存在适合项目的操作系统环境的情况下,这可能是有价值的。

以下是基于 Docker 环境的MLproject文件:

name: syspred
docker_env:
  image: stockpred-docker
entry_points:
  main:
    command: "python mljob.py"

一旦您有了环境,定义您的项目外观的主要文件是MLProject文件。此文件由 MLflow 用于了解它应该如何运行您的项目。

在 MLflow 中开发您的第一个端到端管道

我们将在本节中使用 MLflow 和本地安装的 Docker 原型化一个简单的股票预测项目,并将记录解决方案的不同文件和阶段。您将使用本地系统上安装的 MLflow 和 Docker 来开发它。

重要提示

在本节中,我们假设 MLflow 和 Docker 已在本地安装,因为本节中的步骤将在您的本地环境中执行。

在本示例项目中,任务是创建一个基本的 MLflow 项目,并生成一个可工作的基线 ML 模型,根据一定数量的市场信号预测股市是上涨还是下跌。

在本节中,我们将使用 Yahoo Finance 提供的 BTC-USD 对 3 个月期间的报价数据集。我们将训练一个模型来预测在给定的一天内报价是否会上涨。将通过 MLflow 提供一个 REST API 进行预测。

我们将逐步说明创建一个 MLflow 项目,用于在股票数据上训练分类器,使用 Yahoo API 通过包的 pandas 数据读取器检索金融信息:

  1. 添加你的 MLProject 文件:

    name: stockpred
    docker_env:
      image: stockpred-docker
    entry_points:
      main:
        command: "python train.py"
    

    前面的 MLProject 文件指定依赖项将使用特定的镜像名称在 Docker 中管理。MLflow 将尝试使用您系统上安装的 Docker 版本来拉取镜像。如果找不到,它将尝试从 Docker Hub 获取。对于本章的目标,MLflow 在您的本地机器上运行是完全可行的。

    我们添加到项目中的第二个配置是主入口点命令。要执行的命令将在 Docker 环境中调用我们的项目代码的 train.py Python 文件。

  2. 将 Docker 文件添加到项目中。

    此外,您还可以指定您镜像的 Docker 注册表 URL。运行 Docker 的优势是您的项目不受 Python 语言的限制,正如我们将在本书的高级部分中看到的那样。MLflow API 在 Rest 接口以及官方客户端(Python、Java 和 R)中可用:

    FROM continuumio/miniconda:4.5.4
    RUN pip install mlflow==1.11.0 \
        && pip install numpy==1.14.3 \
        && pip install scipy \
        && pip install pandas==0.22.0 \
        && pip install scikit-learn==0.20.4 \
        && pip install cloudpickle \
        && pip install pandas_datareader>=0.8.0
    

    前面的 Docker 镜像文件基于开源软件包 Miniconda,这是一个免费的、包含数据科学所需的最小包集的最小安装程序,它允许我们控制环境中所需包的详细信息。

    我们将指定 MLflow(我们的 ML 平台)的版本、numpyscipy 用于数值计算。Cloudpickle 允许我们轻松序列化对象。我们将使用 pandas 来管理数据框,并使用 pandas_datareader 来允许我们轻松从公共来源检索数据。

  3. 导入项目所需的所有包。

    在下面的列表中,我们明确导入了在执行训练脚本期间将使用的所有库:读取数据的库,以及与所选初始 ML 模型相关的不同 sklearn 模块:

    import numpy as np
    import datetime
    import pandas_datareader.data as web
    from sklearn.model_selection import train_test_split
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.metrics import classification_report
    from sklearn.metrics import precision_score
    from sklearn.metrics import recall_score
    from sklearn.metrics import f1_score
    import mlflow.sklearn
    

    我们明确选择了 RandomForestClassifier 作为股票市场运动检测问题的模型,因为它是一个非常灵活且广泛接受的分类问题基线模型。

  4. 获取您的训练数据。

    代码中获取 Yahoo Finance 股票数据集的部分故意很小,因此我们选择一个 3 个月的特定间隔来训练我们的分类器。

    acquire_training_data 方法返回一个包含相关数据集的 pandas 数据框:

    def acquire_training_data():
        start = datetime.datetime(2019, 7, 1)
        end = datetime.datetime(2019, 9, 30)
        df = web.DataReader("BTC-USD", 'yahoo', start, end)
        return df
    

    获取数据的格式是交易所 API 中金融证券的经典格式。对于期间每一天,我们检索以下数据:股票的最高价、最低价、开盘价和收盘价,以及成交量。最后一列代表调整后的收盘价,即除息和拆股后的价值:

    ![图 1.1 – 获取数据的摘录 img/image001.jpg

    图 1.1 – 获取数据的摘录

    图 1.2 说明了我们希望通过当前数据准备过程实现的目标变量:

    ![图 1.2 – 带有预测列的获取数据摘录 img/image002.jpg

    图 1.2 – 获取数据中带有预测列的摘录

  5. 使数据可由 scikit-learn 使用。

    在先前的步骤中获取的数据显然不能直接由RandomForestAlgorithm使用,因为它依赖于分类特征。为了便于执行此操作,我们将使用滚动窗口技术将原始数据转换为特征向量。

    基本上,每一天的特征向量成为当前窗口日和前一个窗口日之间的差值。在这种情况下,我们使用前一天的股市走势(股票上涨为 1,否则为 0):

    def digitize(n):
        if n > 0:
            return 1
        return 0
    def rolling_window(a, window):
        """
            Takes np.array 'a' and size 'window' as parameters
            Outputs an np.array with all the ordered sequences of values of 'a' of size 'window'
            e.g. Input: ( np.array([1, 2, 3, 4, 5, 6]), 4 )
                 Output:
                         array([[1, 2, 3, 4],
                               [2, 3, 4, 5],
                               [3, 4, 5, 6]])
        """
        shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
        strides = a.strides + (a.strides[-1],)
        return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)
    def prepare_training_data(data):
        data['Delta'] = data['Close'] - data['Open']
        data['to_predict'] = data['Delta'].apply(lambda d: digitize(d))
        return data
    

    以下示例说明了使用前一天的二值化涨跌产生的数据框输出:

    ![图 1.3 – 二值化市场涨跌的特征向量 img/image003.jpg

    图 1.3 – 二值化市场涨跌的特征向量

  6. 在 MLflow 中训练和存储您的模型。

    以下代码列表的这一部分调用了先前声明的数据准备方法并执行了预测过程。

    主要执行还明确地将当前执行中在 MLflow 环境中训练的 ML 模型记录下来。

    if __name__ == "__main__":
        with mlflow.start_run():
        training_data = acquire_training_data()
        prepared_training_data_df = prepare_training_data(training_data)
        btc_mat = prepared_training_data_df.as_matrix()
        WINDOW_SIZE = 14
        X = rolling_window(btc_mat[:, 7], WINDOW_SIZE)[:-1, :]
        Y = prepared_training_data_df['to_predict'].as_matrix()[WINDOW_SIZE:]
        X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.25, random_state=4284, stratify=Y)
        clf = RandomForestClassifier(bootstrap=True, criterion='gini', min_samples_split=2, min_weight_fraction_leaf=0.0, n_estimators=50, random_state=4284, verbose=0)
        clf.fit(X_train, y_train)
        predicted = clf.predict(X_test)
        mlflow.sklearn.log_model(clf, "model_random_forest")
        mlflow.log_metric("precision_label_0", precision_score(y_test, predicted, pos_label=0))
        mlflow.log_metric("recall_label_0", recall_score(y_test, predicted, pos_label=0))
        mlflow.log_metric("f1score_label_0", f1_score(y_test, predicted, pos_label=0))
        mlflow.log_metric("precision_label_1", precision_score(y_test, predicted, pos_label=1))
        mlflow.log_metric("recall_label_1", recall_score(y_test, predicted, pos_label=1))
        mlflow.log_metric("f1score_label_1", f1_score(y_test, predicted, pos_label=1))
    

    mlflow.sklearn.log_model(clf, "model_random_forest") 方法负责在训练后持久化模型。与先前的示例相比,我们明确要求 MLflow 记录我们认为相关的模型和指标。这种对记录项的灵活性允许一个程序将多个模型记录到 MLflow 中。

    最后,根据先前创建的文件,您的项目布局应如下所示:

    ├── Dockerfile
    ├── MLproject
    ├── README.md
    └── train.py
    
  7. 构建您项目的 Docker 镜像。

    为了构建您的 Docker 镜像,您应该运行以下命令:

    stockpred tag. This image will be usable in MLflow in the subsequent steps as the model is now logged into your local registry. Following execution of this command, you should expect a successful Docker build:
    
    

    ---> 268cb080fed2

    成功构建 268cb080fed2

    成功标记 stockpred:latest

  8. 运行您的项目。

    为了运行您的项目,您现在可以运行 MLflow 项目:

    mlflow run .
    

    您的输出应类似于此处提供的摘录:

    MLFLOW_EXPERIMENT_ID=0 stockpred:3451a1f python train.py' in run with ID '442275f18d354564b6259a0188a12575' ===
                  precision    recall  f1-score   support
               0       0.61      1.00      0.76        11
               1       1.00      0.22      0.36         9
        accuracy                           0.65        20
       macro avg       0.81      0.61      0.56        20
    weighted avg       0.79      0.65      0.58        20
    2020/10/15 19:19:39 INFO mlflow.projects: === Run (ID '442275f18d354564b6259a0188a12575') succeeded ===
    

    这包含了对您的模型的打印输出、实验 ID 以及当前运行期间捕获的指标。

在这个阶段,您有一个使用 MLflow 的简单、可复制的股票预测管道的基线,您可以在此基础上进行改进并轻松与他人分享。

重新运行实验

MLflow 的另一个极其有用的功能是能够以与最初运行时相同的参数重新运行特定的实验。

例如,您应该能够通过指定项目的 GitHub URL 来运行您之前的项目:

mlflow run https://github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/tree/master/Chapter01/stockpred

基本上,上一个命令执行的操作是 MLflow 将仓库克隆到临时目录,并按照 MLProject 上的配方执行它。

实验的 ID(或名称)允许您使用原始参数运行项目,从而实现项目的完全可重复性。

MLflow 项目功能允许您的项目在高级云环境中运行,如 Kubernetes 和 Databricks。无缝扩展您的机器学习作业是像 MLflow 这样的平台的主要卖点之一。

如您从当前章节所见,MLflow 项目模块允许执行一个可重复的机器学习作业,该作业被视为一个自包含的项目。

探索 MLflow 跟踪

MLflow 跟踪组件负责可观察性。此模块的主要功能是记录 MLflow 执行的指标、工件和参数。它提供可视化和工件管理功能。

在生产环境中,它被用作一个用 Python 实现的集中式跟踪服务器,可以由组织中的一组机器学习从业者共享。这使得组织内部可以共享机器学习模型的改进。

图 1.4中,您可以看到一个记录了您模型所有运行的界面,并允许您记录您实验的可观察量(指标、文件、模型和工件)。对于每次运行,您都可以查看和比较您模块的不同指标和参数。

它解决了模型开发者比较不同参数和设置下模型不同迭代时的常见痛点。

以下截图展示了我们上一个模型最后一次运行的指标:

![Figure 1.4 – MLFlow 界面/UI 的示例img/image004.jpg

图 1.4 – MLFlow 界面/UI 的示例

MLflow 允许检查与每个模型及其相关元数据相关的任意工件,允许比较不同运行的指标。您可以看到 RUN ID 和生成特定实验运行的代码的 Git 哈希:

Figure 1.5 – 检查记录的模型工件

Figure 1.5 – 检查记录的模型工件

在您的stockpred当前目录中,您可以运行以下命令以访问您运行的结果:

mlflow ui

在本地运行 MLflow UI 将使其在以下 URL 下可用:127.0.0.1:5000/

在以下截图所示的特定情况下,我们有一个命名实验,其中调整了前一个示例中窗口大小的参数。在 F1 分数方面,可以清楚地看到算法性能的差异:

![图 1.6 – MLflow 运行的列表图片

图 1.6 – MLflow 运行的列表

MLFlow 跟踪的另一个非常有用的功能是能够在不同作业运行之间进行比较:

![图 1.7 – 任务运行 F1 指标的对比图片

图 1.7 – 任务运行 F1 指标的对比

此前的可视化允许从业者决定在生产中使用哪种模型,或者是否进一步迭代。

探索 MLflow 模型

MLflow 模型是处理 MLflow 中支持的不同模型风味以及将部署到不同执行环境的中介的核心组件。

我们现在将深入探讨 MLflow 最新版本中支持的不同模型。

MLflow 入门部分所示,MLflow 模型在模型以内部格式持久化时具有特定的序列化方法。例如,stockpred项目上实现的模型的序列化文件夹看起来如下:

├── MLmodel
├── conda.yaml
└── model.pkl

内部,MLflow sklearn 模型在运行时使用conda文件及其依赖项持久化,并使用源代码记录的 pickle 模型:

artifact_path: model_random_forest
flavors:
  python_function:
    env: conda.yaml
    loader_module: mlflow.sklearn
    model_path: model.pkl
    python_version: 3.7.6
  sklearn:
    pickled_model: model.pkl
    serialization_format: cloudpickle
    sklearn_version: 0.23.2
run_id: 22c91480dc2641b88131c50209073113
utc_time_created: '2020-10-15 20:16:26.619071'
~

默认情况下,MLflow 支持以两种风味提供模型服务,即作为python_functionsklearn格式。这些风味基本上是用于工具或环境的模型格式。

使用前面的一个很好的例子是能够通过执行以下命令来提供服务而无需任何额外代码:

mlflow models serve -m ./mlruns/0/b9ee36e80a934cef9cac3a0513db515c/artifacts/model_random_forest/

您可以访问一个非常简单的 Web 服务器,可以运行您的模型。您可以通过运行以下命令来执行模型预测接口:

curl http://127.0.0.1:5000/invocations -H 'Content-Type: application/json' -d '{"data":[[1,1,1,1,0,1,1,1,0,1,1,1,0,0]]}' [1]%

对我们模型 API 调用的响应是1;根据我们的预测变量定义,这意味着在下次读取时,股票将上涨。

最后几个步骤概述了 MLflow 作为端到端模型开发工具的强大之处,包括为 ML 服务原型设计基于 REST 的 API。

MLflow 模型组件允许创建具有与内置模型相同优势的自定义 Python 模块,只要遵循预测接口即可。

在接下来的章节中,我们将探讨一些值得注意的模型类型,包括以下内容:

  • XGBoost 模型格式

  • R 函数

  • H2O 模型

  • Keras

  • PyTorch

  • Sklearn

  • Spark MLib

  • TensorFlow

  • Fastai

支持最普遍的 ML 模型类型,结合其内置的本地和云部署能力,是 MLflow 模型的最强功能之一。我们将在与部署相关的章节中更详细地探讨这一点。

探索 MLflow 模型注册

MLflow 中的模型注册组件为 ML 开发者提供了模型生命周期管理的抽象。它是一个集中存储库,允许组织或功能中的模型可以协作地共享、创建和归档。

可以使用 MLflow 的不同 API 和 UI 来管理模型。图 1.7 展示了跟踪服务器中的 Artifacts UI,可用于注册模型:

图 1.8 – 将模型注册为工件

图 1.8 – 将模型注册为工件

在注册模型后,您可以使用相关元数据注释已注册的模型,并管理其生命周期。一个例子是将模型放在预生产环境中的测试阶段,并通过将模型发送到生产来管理生命周期:

图 1.9 – 管理不同的模型版本和阶段

图 1.9 – 管理不同的模型版本和阶段

本书将进一步探讨模型注册模块,详细介绍了如何设置集中式服务器以及管理机器学习模型的生命周期,从构思到逐步淘汰模型的过程。

摘要

在本章中,我们介绍了 MLflow,并探讨了采用机器学习平台以减少机器学习开发中从模型开发到生产的时间的动机。通过本章获得的知识和经验,您可以开始改进并使您的机器学习开发工作流程可重复和可追踪。

我们深入探讨了平台中的每个重要模块:项目、模型、跟踪器和模型注册。特别强调了实际示例,以说明每个核心功能,让您能够以动手的方式接触平台。MLflow 提供了多种开箱即用的功能,这些功能将最小化代码和配置,以减少机器学习开发生命周期的摩擦。MLflow 提供了开箱即用的指标管理、模型管理和可重复性。

我们将在本章节的入门知识基础上,扩展我们在构建实际机器学习平台方面的技能和知识。

在本章中,我们简要介绍了股票市场预测的用例,该用例将在本书的其余部分中使用。在下一章中,我们将专注于严格定义股票市场预测的机器学习问题。

进一步阅读

为了增强您的知识,您可以查阅以下链接中提供的文档:

第二章:您的机器学习项目

本书的方法是通过迭代一个实际商业项目——即股票市场预测——并利用这个用例,通过不同的章节探索 MLflow 的不同功能。我们将使用结构化方法来构建机器学习问题和项目。本书剩余部分将创建并使用一个示例管道来迭代和演进项目。

使用结构化框架描述机器学习问题有助于从业者更有效地推理机器学习管道的不同需求。我们将展示一个使用在构建阶段收集到的需求的实际管道。

具体来说,在本章中,我们将涵盖以下内容:

  • 探索机器学习过程

  • 构建机器学习问题

  • 介绍股票市场预测问题

  • 开发您的机器学习基线管道

技术要求

对于本章,您需要以下先决条件:

  • 在您的机器上安装了最新版本的 Docker。如果您还没有安装,请按照docs.docker.com/get-docker/上的说明进行操作。

  • 访问 Bash 终端(Linux 或 Windows)。

  • 访问浏览器。

  • 已安装 Python 3.5 以上版本。

  • 第一章,“介绍 MLflow”中所述,在本地安装 MLflow。

探索机器学习过程

在本章中,我们将首先描述我们将贯穿整本书解决的问题。我们的目标是关注股票交易背景下的机器学习。

机器学习可以被定义为训练一个软件实体的过程——在本例中,是一个模型,用于在问题中做出相关预测。预测被用于驱动业务决策,例如,应该购买或出售哪只股票,或者图片中是否包含猫。

对于一个成功的项目来说,拥有标准的机器学习项目方法是至关重要的。机器学习生命周期的典型迭代在图 2.1中展示:

图 2.1 – 获取数据的摘录及预测列

图 2.1 – 获取数据的摘录及预测列

让我们详细检查每个阶段:

  • 构思:这一阶段涉及识别一个使用机器学习的机会并制定问题。

  • 原型设计:这涉及到验证现有数据集的可行性和适用性,以实现计划中的想法。

  • 试点:这涉及到评估和迭代机器学习算法,以便决定是否进入下一阶段。

  • 生产部署:在成功试点后,我们应该能够在生产中运行机器学习项目,并允许它开始接收生产流量。

图 2.1中定义的这些高级阶段肯定不是静态的,通常是迭代的,各阶段之间有动态移动以精炼和改进。

应该注意的是,机器学习并不是解决所有问题的方案。在决定使用机器学习之前,需要对当前的问题或项目进行深入评估,以决定是否应用机器学习。

有一些简单场景,机器学习解决方案是一个很好的候选者,例如以下情况:

  • 当简单的规则和启发式方法不足以解决当前的问题时。

  • 使用当前最先进的方法解决问题非常昂贵。

  • 当解决问题的规则和代码非常复杂且难以维护时。

机器学习的出现给各个领域带来了变化;其中之一是金融领域。在计算机出现之前,金融是基于小办公室中的交易纸张,交易数量较少。有了计算机,情况发生了变化;现在每天有数百万笔交易。数百万人相互交易,无需亲自见面或进行任何其他形式的物理接触。

在金融和股票交易领域,机器学习可以在以下环境中使用:

  • 数据挖掘:使用高级预测分析来识别数据集中的模式。高级数据分析师通常将机器学习模型作为其分析过程的一部分,并用于驱动业务决策。

  • 对冲交易:一种使用两对市场方向相反的股票的技术。基本上,这是通过在每只股票与其正常行为不同步时卖出或买入来实现的,因为市场在一段时间后会趋于收敛。

  • 股票预测:基于当前时间序列对特定股票在未来的某个时间点将被交易的简单预测。

  • 异常检测:在市场中检测异常情况,发现对防止自动交易系统在市场异常的日子里运行非常重要。

  • 情感分析:众所周知,股市主要是由公司和企业参与者的情绪驱动的。这种技术使用社交媒体或其它媒介上的消息,利用自然语言处理技术来衡量情绪(例如,正面、负面或中性)。

接下来,我们将探讨为机器学习构建问题框架。

构建机器学习问题框架

本节中定义的机器学习问题框架是一种技术和方法,旨在帮助明确和具体化机器学习问题,以便可以实施工程解决方案。如果没有一个稳固的方法来处理机器学习问题,提取这项工作的真正价值可能会变得非常困难。

我们将借鉴亚马逊和谷歌等公司的方法,这些公司已经成功应用了机器学习问题框架的技术。

机器学习开发过程高度基于科学方法。我们经过不同的阶段,包括陈述目标、数据收集、假设检验和结论。预期我们将循环通过工作流程的不同阶段,直到确定一个好的模型或明显无法开发模型。

以下小节描述了本书其余部分将使用的框架,以激发机器学习问题解决框架。

问题陈述

在尝试其他任何事情之前,理解我们正在解决的问题非常重要。为当前问题定义问题陈述是定义问题的明确方式。以下是一些合理的机器学习问题陈述示例:

  • 预测特定股票的股票市场明天是否会上涨。

  • 预测图片中是否有猫。

在这个流程的部分,我们指定我们旨在解决的特定类型的学习问题。以下是一些常见的问题类型:

  • 分类:这类问题要求你预测模型的输出标签或类别,例如,分类电子邮件文本是否为垃圾邮件。它可以是二分类或多分类。一个多分类变体的好例子是根据手写数字进行分类。

  • 回归:这指的是你需要,例如,从训练数据集中预测一个数值。好的例子包括根据大气特征预测温度和预测给定股票的美元价值。

  • 聚类:当你没有标签来训练模型时,它包括发现数据的自然分组。它使用距离度量将相似数据点分组到同一组中。聚类可以用来识别欺诈交易,因为它们不会属于现有的分组。

  • 生成模型:这是一种新型的机器学习,它根据现有数据生成新的数据,并且与输入数据在统计上相似。它在现代语言模型中广泛使用,例如 OpenAI 的 GPT-3。

  • 强化学习:这是一种机器学习类型,其中代理/模型与环境交互以学习最优行为以最大化奖励。一个著名的应用是谷歌 DeepMind 的 AlphaGo 代理,它能够在围棋棋盘游戏中击败最佳人类玩家。一个非常重要的应用是使用盈利作为奖励来训练自动交易股票代理。

    重要提示

    机器学习问题有多种分类法;本节中的列表绝对不是详尽的。此列表与书中的示例相关。

成功与失败的定义

从业务中获得成功定义对于将您的问题置于正确的视角非常重要。例如,对于股市案例,以下可以概述为一个期望的结果:“使用本项目的模型,我们希望将我们目前 50%的日常交易盈利的盈利能力提高至 56%。”

因此,如果我们只有 30%的交易是成功的,那么这个模型显然是失败的。它通常将依赖于业务标准。

将业务指标作为成功定义,而不是像准确性、精确度或召回率这样的技术指标,有助于使解决方案与组织的具体目标保持一致。

模型输出

在机器学习问题框架的背景下,模型输出取决于您要解决的问题类型。例如,回归模型输出将是一个特定的数字(例如,作为股票预测的 10.5)和分类将返回一个标签(例如,检测到猫时返回true)以及一个概率阈值。

您的模型输出应该肯定与您的结果定义相关。

输出用途

说明您的预测将如何被使用有助于揭示模型开发的理由,帮助开发者了解问题和拥有感,例如,决定您是否将预测直接用于用户界面或用于喂养上游系统。

启发式方法

使用机器学习解决的问题可以通过规则和启发式方法来近似。将启发式方法作为机器学习管道的起点通常是一个推荐的项目启动方法。

例如,对于股票交易预测问题的一个有效启发式方法是使用最后一天的预测作为第一个基线生产启发式。模型开发者的目标就是通过更好的模型来超越基线。

数据层定义

在您的模型背景下精确定义输入和输出有助于澄清并指导您的机器学习问题开发。

数据源

本节关于问题框架的内容包括在问题框架过程中识别原始数据源并对其进行记录。原始数据源的例子包括公共或专有数据集及其定义和数据字典。

在这个阶段,识别数据是否已标记以及标记数据所需付出的努力是很重要的。

模型输入/输出

模型开发涉及定义模型中要使用的精确输入。考虑到所有可用的数据源,指定模型输入或特征集对于执行您的管道变得至关重要。与您的输入一起,应定义期望的目标。

模型输入/输出最好以表格形式呈现,如图 2.2所示,以便于推理和模型实现。为了清晰起见,增加了一行示例数据:

![图 2.2 – 记录模型输入/输出的示例图片

图 2.2 – 模型输入/输出的文档示例

接下来,我们将探讨在本书中我们将要工作的股票交易场景中,使用机器学习问题界定技术。

介绍股票市场预测问题

本书剩余章节将涵盖假设公司PsyStock LLC的情景,该公司为业余交易者提供平台,提供 API 和 UI 以解决股票预测背景下的不同预测问题。

作为机器学习实践者和开发者,我们应该能够构建一个平台,使数据科学家团队能够快速开发、测试并将机器学习项目投入生产。

我们将首先应用和界定问题,以便我们可以在问题的定义基础上构建我们的平台。需要注意的是,随着我们对问题的了解更多,问题界定将不断发展:初始界定将为我们提供解决问题空间的指导。

以下是我们将在本书的其余部分作为机器学习开发在 MLflow 中参考的核心项目。

股票走势预测器

这是公司 PsyStock LLC 将为客户提供的第一个 API 项目。如果给定的股票代码在股市中上涨,则该 API 将返回true,如果不上涨,则返回false

问题陈述

问题陈述是通过机器学习分类器预测市场在单日是否会上涨。

成功与失败定义

在这种情况下,成功定义为系统中预测市场方向正确的天数占一个月天数的百分比。成功基本上是指系统在市场方向上准确率超过 60% – 基本上,是优于随机基线的期望值。

模型输出

模型输出为1表示股票代码价值增加,为0表示未增加。

输出用途

模型的输出将用于向 Rest API 提供基于分类准确度定义阈值的truefalse值。

此问题的预期延迟低于 1,000 毫秒。

启发式方法

解决此问题的最简单启发式方法是使用随机预测器对每个输入进行预测,市场上涨或下跌的概率相等。

数据层定义

让我们定义我们数据层的每个部分。

数据源

由 Yahoo Finance 公共 API 提供的历史股票市场数据集。

模型输入/输出

让我们看看输入和输出,接下来:

  • 输入:过去 10 天给定股票代码的每日收盘价。

  • 1表示下一期增加,0表示不增加。

下表显示了模型的输入/输出数据:

图 2.3 – 模型输入/输出的文档示例

图片

图 2.3 – 记录模型输入/输出的示例

市场影响者的情绪分析

情绪机器学习管道将预测社交媒体上股票代码的情绪是正面还是负面,并将其作为 API 提供给我们在本书中开发的机器学习平台的用户。

问题陈述

为了预测 PsyStock LLC 选定的相关市场影响者在 Twitter 上对给定股票代码在当天是否具有正面情绪。

成功与失败的定义

在这种情况下,成功定义起来有点困难,因为情绪是正面的这一事实不能精确地追踪到市场指标。对于这个特定的预测问题,成功的定义应该是用户重复使用 API 次数的代理。

模型输出

模型输出基本上是一个数字,匹配股票代码的推文的极性——正面、负面或中性情绪。

输出用途

该系统的输出将用于一个 Rest API,该 API 将在请求时提供,包括给定股票代码的正面、中性和负面极性的数量。

启发式方法

作为此问题的基线,一个非常简单的启发式方法是计算单词updown出现的次数。对于股票代码,哪个单词更频繁,就使用哪个单词的值作为极性。如果两个单词之间的频率百分比小于 10%,我们将假设该股票代码的情绪是中性的。

数据层定义

对于这个问题,最 readily available 的原始数据是社交媒体。Twitter 提供了一个易于消费和搜索的 API,我们可以通过股票代码和影响者用户名进行搜索。

数据来源

源数据将通过 Twitter API 获取,以搜索给定可更新市场影响者列表的股票代码。

模型输入/输出

将为模型提供服务的系统将接收一条推文并返回分类的情绪(正面、负面或中性):

图 2.4 – 记录模型输入/输出的示例

图 2.4 – 记录模型输入/输出的示例

在本节中,我们仅定义了我们将从头到尾在整个书中解决的问题。我们将根据需要改进问题框架的定义,并在必要时对其进行更新。

在下一节中,我们将探讨在问题框架中定义启发式方法,以创建我们将要改进的第一个基础管道。

开发您的机器学习基线管道

对于我们的机器学习平台,我们将从一个非常简单、基于启发式方法的管道开始,以确保您的端到端系统的基础设施运行正确,并为机器学习模型提供一个可以迭代的 环境。

重要提示

确保在本地机器上正确安装技术要求对于跟随教程至关重要。本节假设您已按照技术要求部分安装了 MLflow 和 Docker。

到本节结束时,您将能够创建我们的基线流程。基线流程的价值在于能够快速迭代模型开发。因此,基本上,一个端到端的基础设施将提供给开发团队,其中包含用于训练和模型服务的占位符。由于所有这些都实现在了 MLflow 中,因此可以轻松实现不同类型团队在机器学习项目中的专业化和专注。工程团队将专注于改进流程,而数据科学导向的团队将有一种快速测试和评估其模型的方法:

  1. 在 MLflow 中实现启发式模型。

    在以下代码块中,我们创建了RandomPredictor类,这是一个从mlflow.pyfunc.PythonModel类派生的定制预测器。主要的predict方法返回 0 到 1 之间的随机数:

    import mlflow
    class RandomPredictor(mlflow.pyfunc.PythonModel):
      def __init__(self):
        pass
      def predict(self, context, model_input):
        return model_input.apply(lambda column: random.randint(0,1))
    

    我们使用 MLflow 中创建自定义模型的特定功能;有关自定义模型的更多详细信息,请参阅mlflow.org/docs/latest/python_api/mlflow.pyfunc.html#pyfunc-create-custom

  2. 在 MLflow 中保存模型。

    以下代码块以random_model的名称保存模型,以便以后检索。它在本地文件系统中的 MLflow 注册表中注册:

    model_path = "random_model"
    baseline_model = RandomPredictor()
    mlflow.pyfunc.save_model(path=model_path, python_model=random_model)
    

    在这个阶段,我们基本上实例化了模型,并按照本地环境配置将其存储在模型注册表中。

  3. 运行您的mlflow作业:

    mlflow run . 
    
  4. 启动服务 API:

    mlflow models serve -m ./mlruns/0/b9ee36e80a934cef9cac3a0513db515c/artifacts/random_model/
    
  5. 测试您模型的 API。

    您可以访问一个非常简单的 Flask 服务器,可以运行您的模型。您可以通过在服务器上运行curl命令来测试执行:

    curl http://127.0.0.1:5000/invocations -H 'Content-Type: application/json' -d '{"data":[[1,1,1,1,0,1,1,1,0,1,1,1,0,0]]}' [1]%
    

在这个阶段,我们有一个基线虚拟模型,模型开发团队的目标现在是要改进这个模型。这个相同的流程将在下一章中用于构建一个数据科学开发环境,该平台在本书中构建的初始算法。

摘要

在本章中,我们介绍了机器学习问题框架方法,并探讨了采用此框架的一些动机。

我们介绍了股票市场预测机器学习平台以及我们使用 ML 问题框架方法定义的初始预测问题集。

在本章中,我们简要介绍了将在本书其余部分使用的股票市场预测基本流程的用例。

在下一章中,我们将专注于使用本章中定义的问题创建一个数据科学开发环境,使用 MLflow。

进一步阅读

为了进一步扩展您的知识,您可以查阅以下链接中的文档:

第二部分:模型开发和实验

本节涵盖了使用 MLflow 进行端到端模型开发的过程,包括通过 MLflow 进行实验管理,针对机器学习中的算法开发阶段。您将学习如何使用 MLflow 逐步开发您的机器学习模型,并使用 MLflow 进行管理。

本节包含以下章节:

  • 第三章, 您的数据科学工作台

  • 第四章, MLflow 中的实验管理

  • 第五章, 使用 MLflow 管理模型

第三章:您的数据科学工作台

在本章中,您将了解在创建本地环境的情况下 MLflow 的应用,以便您可以使用 MLflow 提供的不同功能在本地开发机器学习项目。本章专注于机器学习工程,机器学习工程师最重要的角色之一是建立一个环境,让模型开发者和从业者可以高效工作。我们还将演示如何使用工作台完成特定任务的动手示例。

特别地,在本章中,我们将探讨以下主题:

  • 理解数据科学工作台的价值

  • 创建您自己的数据科学工作台

  • 使用工作台进行股票预测

技术要求

对于本章,您需要以下先决条件:

  • 在您的机器上安装的 Docker 最新版本。如果您尚未安装,请按照 docs.docker.com/get-docker/ 上的说明进行操作。

    已安装 Docker Compose 的最新版本。如果您尚未安装,请按照 docs.docker.com/compose/ins… 上的说明进行操作。

  • 命令行中访问 Git,并按照本 统一资源定位符URLgit-scm.com/book/en/v2/Getting-Started-Installing-Git 中的说明进行安装。

  • 访问 bash 终端(Linux 或 Windows)。

  • 访问浏览器。

  • 已安装 Python 3.5+。

  • 如在 第一章 中所述,本地安装 MLflow。

理解数据科学工作台的价值

数据科学工作台是一个环境,用于标准化组织的机器学习工具和实践,允许快速上线和开发模型和分析。机器学习工程的一个关键功能是支持数据科学从业者使用能够赋予他们力量并加速他们日常活动的工具。

在数据科学团队中,快速测试多种方法和技术的能力至关重要。每天都有新的库和开源工具被创建。一个项目可能需要超过十个库来测试一种新的模型。这些众多的库,如果未能正确整理,可能会在模型中引起错误或不兼容。

数据是数据科学工作流程的核心。拥有干净的数据集用于开发和评估模型至关重要。随着大量大型数据集的出现,需要专门的大数据工具来处理数据。数据可以以多种格式和速度进行分析或实验,并且可以以多种格式和介质提供。它可以通过文件、云或 REpresentational State TransferREST应用程序编程接口API)提供。

数据科学主要是一种协作工艺;它是团队成员之间共享模型和流程的工作流程的一部分。不可避免地,从这个活动中出现的一个痛点是模型开发作业在从业者之间的跨可重复性。数据科学家 A 分享了一个假设库版本 2.6 的模型训练脚本,但数据科学家 B 使用的是版本 2.8 的环境。在某些情况下,追踪和修复这个问题可能需要数小时。如果这个问题出现在生产环境中,它可能会对公司造成极大的成本。

在迭代——例如——模型时,每次运行都包含多个可以调整以改进模型的参数。如果我们不以结构化的方式存储实验的详细信息,那么维护哪个参数产生了特定的性能指标(例如准确性)的可追溯性可能会成为问题。如果在模型开发阶段只保留最新设置,那么回到产生更好模型的特定批次设置可能是不可能的。

迭代速度的需求在将原型代码翻译到可靠执行的生产环境时,可能会引起许多挫败感。例如,如果你在一个可以轻松访问图形处理单元GPUs)进行推理的 Windows 机器上开发新的交易模型,你的工程团队成员可能会决定重用现有的无 GPU 访问的 Linux 基础设施。这导致你的生产算法最终需要 5 小时才能完成,而在本地运行只需 30 秒,影响了项目的最终结果。

很明显,如果不对环境和工具相关的问题进行前期处理,数据科学部门会面临系统性的技术痛点。总结来说,我们可以列出本节中描述的以下主要点:

  • 可重复性摩擦

  • 处理大型和多样化数据集的复杂性

  • 实验设置管理不善

  • 本地和生产环境之间的漂移

数据科学工作台通过创建一个结构化环境来解决本节中描述的痛点,在这个环境中,机器学习从业者可以授权可靠地开发和部署他们的模型,减少摩擦。无摩擦的环境将允许高度昂贵的模型开发时间专注于开发和迭代模型,而不是解决工具和数据技术问题。

在深入研究为机器学习团队构建数据科学工作台的动机之后,我们接下来将根据已知的痛点开始设计数据科学工作台。

创建自己的数据科学工作台

为了解决前述章节中描述的数据科学模型开发中的常见摩擦,我们需要为数据科学家和从业者提供一个标准化的环境,让他们可以在其中开发和管理工作。数据科学工作台应允许您快速启动项目,并且一套起始工具和框架的可用性允许数据科学家快速启动项目。

数据科学家和机器学习从业者处于工作台的中心:他们应该有一个可靠的平台,允许他们开发并为其组织增加价值,同时他们的模型触手可及。

以下图表展示了数据科学工作台的核心功能:

![Figure 3.1 – 数据科学工作台的核心功能

![img/B16783_03_001.jpg]

图 3.1 – 数据科学工作台的核心功能

为了思考我们数据科学工作台的设计,并基于图 3.1中的图表,我们需要在我们的数据科学工作台中具备以下核心功能:

  • 依赖管理:在本地环境中集成依赖管理有助于处理可重复性问题,并防止不同环境之间的库冲突。这通常是通过使用环境管理器,如 Docker,或者在您的编程语言中提供环境管理框架来实现的。MLflow 通过支持基于 Docker 或 Conda 的环境来提供这一功能。

  • 数据管理:如果您必须处理大量数据集,则在本地环境中管理数据可能会变得复杂且令人畏惧。在您的本地项目中有一个标准化的数据处理定义,允许他人自由协作并理解可用的结构。

  • 模型管理:将不同的模型组织并妥善存储提供了一个易于工作的结构,能够同时处理许多想法并持久化那些有潜力的想法。MLflow 通过模型格式抽象和模型注册组件来支持这一点,以管理模型。

  • 部署:在本地环境中与模型将提供服务的生产环境保持一致需要深思熟虑。生产环境需要准备好接收模型开发者的模型,以尽可能少的摩擦。这种平稳的部署工作流程只有在本地环境正确设计的情况下才可能实现。

  • 实验管理:调整参数是机器学习从业者最常见的事情。能够跟上不同版本和特定参数可能会迅速变得繁琐,对模型开发者来说。

    重要提示

    在本节中,我们将从头开始使用 MLflow 实现数据科学工作台的基础,主要支持本地开发。云提供商如亚马逊网络服务AWS)Sagemaker、谷歌 AIAzure 机器学习Azure ML)提供了一些非常具有意见和功能丰富的选项。

机器学习工程团队在所服务的团队使用的用例和技术方面有自由度。

以下步骤展示了使用数据科学工作台进行开发的良好工作流程:

  • 模型开发者通过安装程序或克隆仓库来安装公司工作台包。

  • 模型开发者运行一个命令以启动项目。

  • 模型开发者根据配置或提示选择一组选项。

  • 基本框架生成时,会为以下项目创建特定文件夹:

    a) Data:这将包含当前项目的所有数据资产

    b) Notebooks:用于存放所有迭代开发笔记本,包括生成模型所需的所有步骤

    c) Model:包含二进制模型或模型引用的文件夹,可能以二进制格式

    d) Source Code:用于存储代码的结构化组件和可重用库

    e) Output:用于存放项目特定输出的文件夹——例如,可视化、报告或预测

  • 使用标准化的包、依赖管理和工具组织创建项目文件夹。

  • 模型开发者可以自由迭代并使用组织级别的支持工具创建模型。

建立数据科学工作台为组织中的机器学习加速和民主化提供了一个工具,这是由于标准化和高效采用机器学习最佳实践的结果。

我们将在本章中开始我们的工作台实现,使用业界广泛使用的合理组件。

构建我们的工作台

我们将在开发环境架构中拥有以下组件:

  • Docker/Docker Compose:将使用 Docker 来处理架构中每个主要组件的依赖关系,Docker Compose 将用作不同软件组件容器之间的协调器。工作台架构的每个组件都在 Docker 中,其优势是元素库之间不会相互冲突。

  • JupyterLab:在机器学习环境中开发数据科学代码和进行数据分析的事实上环境。

  • MLflow:MLflow 是工作台的核心,提供实验跟踪、模型管理、注册和部署接口的功能。

  • PostgreSQL 数据库:PostgreSQL 数据库作为 MLflow 后端元数据的存储层,是当前架构的一部分。其他关系型数据库也可以用作 MLflow 后端元数据,但我们将使用 PostgreSQL。

我们的数据科学工作台设计可以在以下图表中看到:

图 3.2 – 我们的数据科学工作台设计

图 3.2 – 我们的数据科学工作台设计

图 3.2 展示了我们将支持的数据科学工作台组件布局。

一旦环境启动并运行,实践者的常规工作流程是在 Jupyter 中开发他们的代码,并使用 MLflow 支持运行他们的实验。环境将自动路由到正确配置到正确后端的 MLflow 安装,如图 3.2 所示。

重要提示

根据本章定义,我们的数据科学工作台是一个完整的地方环境。随着本书的进展,我们将介绍基于云的环境,并将我们的工作台与共享资源链接。

以下 GitHub 文件夹中提供了一个项目布局的示例:

github.com/PacktPublis…

您可以在此处看到工作台文件布局的一般表示:

├── Makefile
├── README.md
├── data
├── docker
├── docker-compose.yml
├── docs
├── notebooks
├── requirements.txt
├── setup.py
├── src
├── tests
└── tox.ini

此文件夹结构的主要元素在此概述:

  • Makefile:这允许您控制工作台。通过发出命令,您可以要求工作台设置一个新的环境笔记本以以不同格式启动 MLflow。

  • README.md:一个包含项目示例描述及其如何运行的文件。

  • data文件夹:一个文件夹,用于存储开发期间使用的数据集,并在本地运行时挂载数据库的数据目录。

  • docker:一个包含我们环境所包含的不同子系统 Docker 镜像的文件夹。

  • docker-compose.yml:一个包含我们工作台环境中的不同服务编排的文件——即:Jupyter 笔记本、MLflow 和用于支持 MLflow 的 PostgreSQL。

  • docs:包含我们希望持久化的相关项目文档。

  • notebooks:一个包含笔记本信息的文件夹。

  • requirements.txt:一个要求文件,用于向项目添加库。

  • src:一个包含项目源代码的文件夹,将在项目的后续阶段进行更新。

  • tests:一个包含项目代码端到端测试的文件夹。

  • tox.ini:一个模板文件,用于控制单元测试的执行。

现在,我们将继续使用我们自己的开发环境来解决股票预测问题,基于我们刚刚构建的框架。

使用工作台进行股票预测

在本节中,我们将逐步使用工作台来设置新项目。按照步骤说明启动您的环境并使用工作台进行股票预测项目。

重要提示

在“技术要求”部分列出的所有软件包/库都必须正确安装在您的本地机器上,这对于您跟随教程至关重要。

启动你的环境

我们将接着探索您自己的开发环境,基于本节中所示的开发环境。请执行以下步骤:

  1. 复制位于 github.com/PacktPublis… 的项目内容。

  2. 通过运行以下命令启动您的本地环境:

    make
    
  3. 检查创建的环境,如下所示:

    $ docker ps 
    

    以下截图展示了三个 Docker 镜像:第一个用于 Jupyter,第二个用于 MLflow,第三个用于 PostgreSQL 数据库。状态应显示为 Up x minutes

图 3.3 – 运行 Docker 镜像

图 3.3 – 运行 Docker 镜像

您工作台通常使用的端口如下所示:Jupyter 在端口 8888 上运行,MLflow 在端口 5000 上运行,PostgreSQL 在端口 5432 上运行。

如果任何容器失败,您可能需要检查端口是否被不同的服务使用。如果是这种情况,您将需要关闭所有其他服务。

检查您的 Jupyter Notebooks 环境 localhost:8888,如下面的截图所示:

图 3.4 – 运行 Jupyter 环境

图 3.4 – 运行 Jupyter 环境

您应该有一个可用的环境,允许您在指定的文件夹中创建新的 notebooks 文件。

http://localhost:5000 上检查您的 MLflow 环境,如下面的截图所示:

图 3.5 – 运行 MLflow 环境

图 3.5 – 运行 MLflow 环境

图 3.5 展示了您将在 MLflow 中使用的实验跟踪环境。

通过运行 /notebooks/mlflow_sample.ipynb 中的 notebook 文件在 MLflow 中运行一个示例实验,如下面的截图所示:

图 3.6 – mlflow_sample 代码摘录

图 3.6 – mlflow_sample 代码摘录

图 3.6 中的代码导入 MLflow 并手动创建一个实验,在第二行使用 mlflow.set_experiment('mlflow_experiment')

with mlflow.start_run() 行负责在 MLflow 中启动和拆除实验。

在接下来的三行中,我们使用 mlflow.log_param 函数记录几个字符串类型的测试参数。要记录数值,我们将使用 mlflow.log_metric 函数。

最后,我们还将使用 mlflow.log_artifact("mlflow_example.ipynb") 函数记录执行函数的整个文件,以确保模型及其源代码的可追溯性。

检查示例运行情况,以确认环境是否正常工作。您应该回到位于 http://localhost:5000 的 MLflow 用户界面UI)并检查是否创建了新的实验,如下面的截图所示:

图 3.7 – MLflow 测试实验

图 3.7 – MLflow 测试实验

图 3.7 显示了我们特定实验中使用的附加参数以及 指标 列中可见的特定指标 i

接下来,您应该点击创建的实验以访问我们迄今为止执行的运行的详细信息。以下是一个截图示例:

图 3.8 – MLflow 实验细节

图 3.8 – MLflow 实验细节

除了指标细节之外,您还可以访问特定时间点的 mlflow_example 笔记本文件。

在此阶段,您已经拥有一个按预期运行和工作的环境。接下来,我们将使用我们自己的算法来更新它;我们将使用我们在 第二章您的机器学习项目 中创建的算法。

使用您自己的算法进行更新

让我们更新我们在 第二章ML 问题框架 中创建的笔记本文件,并将其添加到您本地工作台上的笔记本文件夹中。代码摘录如下:

import mlflow
class RandomPredictor(mlflow.pyfunc.PythonModel):
  def __init__(self):
    pass
  def predict(self, context, model_input):
    return model_input.apply(lambda column: random.randint(0,1))

notebooks/stockpred_randomizer.ipynb 文件中的 notebook 文件夹下,您可以跟随我们最近创建的数据科学工作台中前面代码摘录的集成。我们将按以下步骤进行:

  1. 我们将首先导入所有需要的依赖项并运行笔记本的第一个单元,如下所示:图 3.9 – MLflow 实验细节

    图 3.9 – MLflow 实验细节

  2. 让我们声明并执行 图 3.9 中概述的类,该类在笔记本的第二单元中表示,如下所示:图 3.10 – 包含 RandomPredictor 类声明的笔记本单元

    图 3.10 – 包含 RandomPredictor 类声明的笔记本单元

  3. 我们现在可以在 MLflow 基础设施中保存我们的模型,以便我们可以测试模型的加载。model_path 包含模型将保存的文件夹名称。您需要在 r 变量中实例化模型,并使用 mlflow.pyfunc.save_model 将模型本地保存,如下面的代码片段所示:图 3.11 – 展示保存模型的笔记本

    图 3.11 – 展示保存模型的笔记本

    您可以在笔记本环境左侧的窗格中看到,在您的文件旁边创建了一个新文件夹来存储您的模型。此文件夹将存储 Conda 环境以及您的模型的可 pickled/binarized Python 函数,如下面的截图所示:

    图 3.12 – 展示保存模型文件夹的笔记本

    图 3.12 – 展示保存模型文件夹的笔记本

  4. 接下来,我们可以加载并使用模型来检查保存的模型是否可用,如下所示:

图 3.13 – 展示保存模型文件夹的笔记本

图 3.13 – 展示保存模型文件夹的笔记本

图 3.14 展示了创建一个随机输入 loaded_model 来预测输入向量的过程。我们将以 stockpred_experiment_days_up 为名运行实验,将每个模型在市场上涨的天数作为指标进行记录,如下所示:

图 3.14 – 展示加载模型使用的笔记本单元格

图 3.14 – 展示加载模型使用的笔记本单元格

要检查实验的最后运行,你可以查看 http://localhost:5000 并确认新实验已被创建,如下面的屏幕截图所示:

图 3.15 – 我们 stockpred 实验的 MLflow 初始用户界面

图 3.15 – 我们 stockpred 实验的 MLflow 初始用户界面

你现在可以比较我们算法的多次运行,并查看天数上升指标的变化,如下面的屏幕截图所示。你可以相应地选择深入了解你想要更多详细信息的运行:

图 3.16 – 保存的工件日志细节

图 3.16 – 保存的工件日志细节

图 3.16中,你可以清楚地看到我们运行的日志细节——即,工件模型和天数上升指标。

为了正确地拆除环境,你必须在同一文件夹中运行以下命令:

make down

摘要

在本章中,我们介绍了数据科学工作台的概念,并探讨了采用此工具作为加速我们的机器学习工程实践的一些动机。

我们根据需求设计了一个数据科学工作台,使用 MLflow 和基于相邻技术的技术。我们详细说明了使用 MLflow 设置你的开发环境的步骤,并说明了如何使用现有代码。在后面的章节中,我们探讨了工作台,并添加了我们上一章开发的股票交易算法。

在下一章中,我们将专注于使用 MLflow 进行实验,以改进我们的模型,使用本章开发的工作台。

进一步阅读

为了进一步扩展你的知识,你可以查阅以下链接中的文档:

第四章:MLflow 中的实验管理

在本章中,我们将通过创建不同的模型并比较 MLflow 中不同运行的指标来为您提供股票预测的实际经验。您将指导如何使用 MLflow 实验方法,以便不同的机器学习从业者可以共享指标并改进同一模型。

在本章中,我们将具体探讨以下主题:

  • 开始使用实验模块

  • 定义实验

  • 添加实验

  • 比较不同的模型

  • 使用超参数优化调整您的模型

在这个阶段,我们目前有一个基于朴素启发式的基线管道。在本章中,我们将通过 MLflow 添加我们的技能集,以便能够对多个模型进行实验,并调整一个特定模型。

我们将深入研究第二章中介绍的“您的机器学习项目”中的Psystock公司案例,这是一个股票交易机器学习平台。在本章中,我们将向我们的平台添加比较多个模型和运行基准实验的功能,以便能够为特定的股票和股票代码创建预测器。

在数据科学函数中,一种常见的方法是为特定模型开发一个模型,涉及以下三个步骤:创建不同模型类型的基线模型,确定表现最佳的模型,并使用最佳模型进行预测。

技术要求

对于本章,您需要以下先决条件:

  • 在您的机器上安装了最新版本的 Docker。如果您还没有安装,请按照docs.docker.com/get-docker/中的说明进行操作。

  • 安装了最新版本的 Docker Compose。请按照docs.docker.com/compose/install/中的说明进行操作。

  • 在命令行中访问 Git,并按照git-scm.com/book/en/v2/Getting-Started-Installing-Git中的说明安装。

  • 访问 bash 终端(Linux 或 Windows)。

  • 访问浏览器。

  • 安装了 Python 3.5+。

  • 您本地安装的最新机器学习版本,并在第三章,“您的数据科学工作台”中描述。

开始使用实验模块

要开始使用技术模块,您需要开始使用以下文件夹中为本章准备的环境:github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/tree/master/Chapter04

在这个阶段,您应该能够执行 make 命令来构建工作台,以便跟随本章的内容。接下来,您需要输入以下命令以移动到正确的目录:

$ cd Chapter04/gradflow/

要启动环境,您需要运行以下命令:

$ make

开始管理 MLflow 中的实验的入口是 图 4.1 中所示的实验界面:

2

1

![图片 4.1 – MLflow 中的实验界面

![图片 B16783_04_01.jpg]

图 4.1 – MLflow 中的实验界面

在左侧面板(1)中,您可以管理和创建实验,在右侧(2)中,您可以查询特定实验的详细信息。

要创建一个新实验,您需要在左侧面板上点击 + 按钮,并添加您实验的详细信息,如图 图 4.2 所示:

![图片 4.2 – 创建新实验

![图片 B16783_04_02.jpg]

图 4.2 – 创建新实验

在简要介绍了跟踪服务器和实验管理功能之后,我们现在将使用工作台上的功能来应对本章的挑战。

定义实验

使用机器学习问题框架方法,我们现在将定义本章中股票价格预测问题的主要组件:

![图片 B16783_04_Table_(1).jpg]![表 4.1 – 机器学习问题框架回顾

![图片 B16783_04_Table_(2).jpg]

表 4.1 – 机器学习问题框架回顾

机器学习中的 F-score 指标是二元分类器的准确度度量,提供了在误分类(假阳性或假阴性)之间的良好平衡和权衡。更多详细信息可以在维基百科页面找到:en.wikipedia.org/wiki/F-score

探索数据集

根据我们的机器学习问题框架,我们将使用 2020 年 1 月至 12 月的市场观察数据作为输入数据,这些数据由 Yahoo 数据 API 提供。

以下代码片段,使用了我们工作台中的 pandas_datareader 模块,使我们能够轻松检索我们想要的数据。完整的笔记本可以在github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/blob/master/Chapter04/gradflow/notebooks/retrieve_training_data.ipynb找到:

import pandas as pd
import numpy as np
import datetime
import pandas_datareader.data as web
from pandas import Series, DataFrame
start = datetime.datetime(2014, 1, 1)
end = datetime.datetime(2020, 12, 31)
btc_df = web.DataReader("BTC-USD", 'yahoo', start, end)

对于这个特定问题,我们将从 2014 年检索数据,直到 2020 年底,如图 图 4.3 中提供的表格所示。该表格提供了交易部分 BTC 股票的高、低、开盘价和收盘价的价值信息。这些数据将用于本章中模型的训练:

![图片 B16783_04_03.jpg]

图 4.3 – 列出从源(Yahoo Finance)检索的数据

可以通过绘制其中一个变量来轻松绘制这些数据,以说明数据的连续性:

btc_df['Open'].plot()

为了更详细地说明数据的性质,我们可以绘制数据的摘录:

![图 4.4 – 从源(雅虎财经)检索到的 BTC Open 变量的绘图]

![img/B16783_04_04.jpg]

图 4.4 – 从源(雅虎财经)检索到的 BTC Open 变量的绘图

在本节中明确定义我们将要实验的内容后,我们将添加新的模型,以便我们能够运行实验并在它们之间进行比较。

所需范围的数据方便地保存在 Chapter04/gradflow/notebooks/training_data.csv 文件中,时间范围从 2014 年到 2020 年(含),因此可以在建模阶段轻松检索。

添加实验

因此,在本节中,我们将使用 MLflow 的实验模块来跟踪不同模型的运行,并将它们发布到我们的工作台数据库中,以便可以并排比较性能结果。

实验实际上可以由不同的模型开发者进行,只要他们都指向共享的 MLflow 基础设施。

为了创建我们的第一个模型,我们将选择一组模型家族,并在每个案例上评估我们的问题。从更广泛的角度来看,分类的主要家族可以是基于树的模型、线性模型和神经网络。通过查看在每个案例上表现更好的指标,我们然后可以将调整引导到最佳模型,并将其用作我们的初始生产模型。

我们在本节中的选择包括以下内容:

  • 逻辑分类器:线性模型家族的一部分,并且是常用的基线。

  • Xgboost:这属于树提升算法家族,其中许多弱树分类器被组装成一个更强的模型。

  • Keras:这类模型属于神经网络家族,通常用于数据量很大且特征之间关系非线性的情况。

设置新模型的步骤相当常见,每个模型都会有重叠和重复的代码。接下来,我们将从基于逻辑回归的分类器开始。

设置基于逻辑分类器的步骤

在本子节中,我们将使用 scikit-learn 实现逻辑回归分类器,并使用我们的输入数据训练模型。

该模型的完整笔记本可在本书的存储库中找到,并可用于在 Chapter04/gradflow/notebooks/mlflow_run_logistic_regression.ipynb 文件中跟随:

  1. SKLearn 模型、LogisticRegressionf1_score 指标功能,这将使我们能够计算性能:

    import pandas
    import numpy as np
    import mlflow
    import tensorflow
    from tensorflow import keras
    import mlflow.keras
    from sklearn.metrics import f1_score,confusion_matrix
    from sklearn.model_selection import train_test_split
    
  2. training_data.csv 文件:

    pandas_df = pandas.read_csv("training_data.csv")
    X=pandas_df.iloc[:,:-1]
    Y=pandas_df.iloc[:,-1]
    X_train, X_test, y_train, y_test = \
    train_test_split(X, Y, test_size=0.33, 
                     random_state=4284, stratify=Y)
    

    使用 train_test_split 函数将数据分为训练集和测试集,其中三分之一的用于测试,其余用于训练。

  3. mlflow.set_experiment 方法。这将创建一个实验(如果不存在)或将当前运行与一个实验关联。我们使用 mlflow.sklearn.autolog() 启用 MLflow 的自动功能来捕获实验的指标:

    mlflow.set_experiment("Baseline_Predictions")
    mlflow.sklearn.autolog()
    
  4. withmlflow.start_run 函数用于处理将运行与特定的 run_name 注册,以便它可以被识别,并包含 fit 模型,以及用于计算 f1_score 实验性能指标的评估代码:

    with mlflow.start_run(run_name='logistic_regression_model_baseline') as run:
        model = LogisticRegression()
        model.fit(X_train, y_train)
        preds = model.predict(X_test)
        y_pred = np.where(preds>0.5,1,0)
        f1 = f1_score(y_test, y_pred)
        mlflow.log_metric(key="f1_experiment_score", 
                          value=f1)
    

    此外,我们需要使用 mlflow.log_metric 函数记录我们特定的指标 f1_experiment_score。添加我们特定方法的主要原因是为每个模型,MLflow 中的自动记录功能使用每个底层框架默认的指标,通常这些指标并不匹配。

执行所有与模型开发相关的步骤后,我们现在可以导航到我们的运行并可视化实验的日志。在 图 4.5 中,你可以看到与逻辑回归、持续时间以及你在运行中使用的所有参数相关的特定参数:

![Figure 4.5 – 逻辑回归模型细节img/B16783_04_05.jpg

图 4.5 – 逻辑回归模型细节

对于 SKLearn 模型,MLflow 自动记录混淆矩阵和精确率和召回率曲线,这对于检测模型在训练数据上的表现非常有用。例如,图 4.6 报告将存储在运行的艺术品中:

![Figure 4.6 – 混淆矩阵指标img/B16783_04_06.jpg

图 4.6 – 混淆矩阵指标

MLflow 为 Sklearn 提供了内置的指标,这为训练过程中产生的模型提供了更好的可见性,而无需开发者编写额外的代码。

设置基于 XGBoost 的分类器的步骤

我们现在将使用 XGBoost 库实现基于梯度树的算法。

该模型的完整笔记本可在本书的存储库中找到,并可用于在 Chapter04/gradflow/notebooks/mlflow_run_xgboost.ipynb 文件中跟随:

导入依赖项:XGBoost 库与指标函数一起导入:

import pandas
import mlflow
import xgboost as xgb
from sklearn.metrics import f1_score
from sklearn.model_selection import train_test_split
  1. training_data.csv 文件。

  2. Baseline_Predictions,我们需要给 MLflow 指示通过 mlflow.xgboost.autolog 自动记录模型:

    mlflow.set_experiment("Baseline_Predictions")
    mlflow.xgboost.autolog()
    
  3. f1_score:

    with mlflow.start_run(
      run_name='xgboost_model_baseline') as run:
        model=xgb.train(dtrain=dtrain,params={})
        preds = model.predict(dtest)
        y_bin = [1\. if y_cont > threshold else 0\. for y_cont in preds]
        f1= f1_score(y_test,y_bin)
        mlflow.log_metric(key="f1_experiment_score", 
                          value=f1)
    

执行所有与模型开发相关的步骤后,我们现在可以导航到我们的运行并可视化实验的日志。在 图 4.7 中,你可以看到与 xgboost_model_baseline、持续时间以及你在运行中使用的所有参数相关的特定参数:

![Figure 4.7 – MLflow 中的 XGBoost 分类器细节img/B16783_04_07.jpg

图 4.7 – MLflow 中的 XGBoost 分类器细节

对于 XGBoost 模型,MLflow 自动记录特征信息和重要性。我们可以在 图 4.8 中看到模型存储在工作台 艺术品 部分的特征排名:

![图 4.8 – XGBoost 在 MLflow 上的特征重要性img/B16783_04_08.jpg

图 4.8 – XGBoost 在 MLflow 上的特征重要性

图 4.8 中的特征重要性图允许开发者从数据中了解模型的内部结构。在这种情况下,似乎输入向量的第 14 天的第 2 天和第 7 天是前两个有意义的特征。接下来,我们将实现一个基于深度学习的模型。

基于深度学习的分类器设置步骤

在本节中,我们将实现一个神经网络算法来解决我们的分类问题。

该模型的完整笔记本位于本书的仓库中,可以在 Chapter04/gradflow/notebooks/mlflow_run_keras.ipynb 文件中找到以进行跟随:

  1. tensorflow,因为我们将其用作 keras 的后端:

    import pandas
    import numpy as np
    import mlflow
    import tensorflow
    from tensorflow import keras
    import mlflow.keras
    from sklearn.metrics import f1_score,confusion_matrix
    from sklearn.model_selection import train_test_split
    
  2. 获取数据:请参考 设置基于 XGBoost 的分类器步骤 部分的第 2 步。

  3. Baseline_Predictions,我们需要给 MLflow 指令,通过 mlflow.tensorflow.autolog 自动记录模型:

     mlflow.set_experiment("Baseline_Predictions")
     mlflow.tensorflow.autolog()
    

    Sklearn 或 XGBoost 分类器,因此我们需要定义网络的层和架构。在这种情况下,需要按照 Tensorflow 的要求编译 Sequential 架构和模型:

    model = keras.Sequential([
      keras.layers.Dense(
        units=36,
        activation='relu',
        input_shape=(X_train.shape[-1],)
      ),
      keras.layers.BatchNormalization(),
      keras.layers.Dense(units=1, activation='sigmoid'),
    ])
    model.compile(
      optimizer=keras.optimizers.Adam(lr=0.001),
      loss="binary_crossentropy",
      metrics="Accuracy"
    )
    
  4. run_name、拟合模型以及计算 f1_score 指标:

    with mlflow.start_run(
      run_name='keras_model_baseline') as run:
        model.fit(
            X_train,
            y_train,
            epochs=20,
            validation_split=0.05,
            shuffle=True,
            verbose=0
        )
        preds = model.predict(X_test)
        y_pred = np.where(preds>0.5,1,0)
        f1 = f1_score(y_test, y_pred)
        mlflow.log_metric(key="f1_experiment_score", 
                          value=f1)
    

    对于 keras 模型,MLflow 会自动记录大量的神经网络相关数据,包括优化器、epoch 和批大小,以及其他在 图 4.9 中可以看到的相关信息:

![图 4.9 – Keras 分类器模型细节img/B16783_04_09.jpg

图 4.9 – Keras 分类器模型细节

此外,TensorFlow 日志可以连接到 TensorBoard。这是一个 TensorFlow 内置工具,用于提供机器学习工作流程的可视化和指标。创建了接口,以便模型开发者可以利用本地的 TensorFlow 仪器和专业的可视化工具。

在我们的平台上设置好分类器后,在下一节中,我们将准备好比较使用 MLflow 开发的不同分类器的性能。

比较不同模型

我们在本节中为每个覆盖的模型运行了实验,并验证了所有不同的工件。只需查看我们的基线实验表,并选择共同的定制指标 f1_experiment_score,我们就可以看到表现最好的模型是基于逻辑回归的模型,F 分数为 0.66:

图 4.10 – 从目标指标的角度比较不同模型性能

指标也可以并排比较,如图 图 4.11 所示。在左侧,我们有 SKlearn 模型,在右侧是 XGBoost 模型,带有自定义的 f1_experiment_score 指标。我们可以看到,两者提供的指标是不同的,因此当我们有不同模型时,自定义指标的原因:

![图 4.11 – Sklearn 模型的指标图片

图 4.11 – Sklearn 模型的指标

比较指标后,很明显最佳模型是逻辑回归。为了改进模型,在下一节中,我们将使用最先进的技术来优化其参数,并使用 MLflow 实验功能来实现这一点。

使用超参数优化调整模型

机器学习模型有许多参数,允许开发者提高性能并控制他们所使用的模型,提供更好的数据拟合和生产用例的杠杆。超参数优化是系统地、自动地识别机器学习模型最佳参数的过程,对于此类系统的成功部署至关重要。

在上一节中,我们确定了针对我们问题的最佳模型族(换句话说,LogisticRegression),因此现在我们需要使用 MLflow 来确定我们模型的正确参数。您可以在项目仓库中的以下笔记本中跟随操作,位于 Chapter04/gradflow/notebooks/hyperopt_optimization_logistic_regression_mlflow.ipynb:

  1. hyperopt 库,其中包含多个算法帮助我们进行模型调优:

    from hyperopt import tpe
    from hyperopt import STATUS_OK
    from hyperopt import Trials
    from hyperopt import hp
    from hyperopt import fmin
    from sklearn.linear_model import LogisticRegression
    from sklearn.model_selection import cross_val_score
    from sklearn.model_selection import train_test_split
    
  2. 我们模型中的 f1_score 指标。在 hyperopt 中,优化是通过最小化来实现的,但在这个案例中,我们希望得到最大的 f1_score 指标。因此,我们定义损失(最小化的函数)的方式是 f1_score 指标的倒数,即 loss = 1-fscore,这样这个函数的最小化将代表最佳的 f1_score 指标。对于模型参数的每一次运行,我们将它包裹在 mlflow.start_run(nested=True) 中,这样每次优化迭代都会作为主任务的子运行被记录,从而在比较运行间的指标时提供多项优势:

    N_FOLDS = 3
    MAX_EVALS = 10
    def objective(params, n_folds = N_FOLDS):
        # Perform n_fold cross validation with 
        #hyperparameters
        # Use early stopping and evaluate based on ROC AUC
        mlflow.sklearn.autolog()
        with mlflow.start_run(nested=True):
            clf = LogisticRegression(**params,
                                     random_state=0,
                                     verbose =0)
            scores = cross_val_score(clf, X_train, 
                                     y_train, cv=5, 
                                     scoring='f1_macro')
            # Extract the best score
            best_score = max(scores)
            # Loss must be minimized
            loss = 1 - best_score
            # Dictionary with information for evaluation
            return {'loss': loss, 'params': params, 
                    'status': STATUS_OK}
    
  3. best 变量。核心功能是最小化,由 fmin(fn = objective, space = space, algo = tpe.suggest, max_evals = MAX_EVALS, trials = bayes_trials) 表示,其中我们提供了之前定义的参数空间和目标函数:

    # Algorithm
    tpe_algorithm = tpe.suggest
    # Trials object to track progress
    bayes_trials = Trials()
    mlflow.set_experiment("Bayesian_param_tuning")
    with mlflow.start_run():
        best = fmin(fn = objective, space = space, 
                    algo = tpe.suggest, 
                    max_evals = MAX_EVALS, 
                    trials = bayes_trials)
    
  4. 运行实验几分钟之后,我们现在可以回顾 Hyperopt_Optimization 实验中的实验:![图 4.12 – 列出超参数调优的所有嵌套运行 图片

    图 4.12 – 列出超参数调优的所有嵌套运行

  5. 通过点击 training_f1_score 和求解器:图片

    图 4.13 – 列出超参数调优的所有嵌套运行

  6. 我们可以轻松地在同一界面中比较不同的求解器和对我们性能指标的影响,从而进一步了解我们的建模阶段:

![图 4.14 – 列出超参数调优的所有嵌套运行img/B16783_04_14.jpg

图 4.14 – 列出超参数调优的所有嵌套运行

我们通过优化当前问题的最有效模型的参数来结束本节。在本书的下一章中,我们将使用最佳模型提供的信息,深入探讨MLflow中模型管理的生命周期。

摘要

在本章中,我们介绍了 MLflow 的实验组件。我们了解了 MLflow 中的日志指标和工件。我们详细说明了在 MLflow 中跟踪实验的步骤。

在最后几节中,我们探讨了使用本章学到的概念进行超参数优化的用例。

在下一章中,我们将专注于使用本章开发的模型,利用 MLflow 来管理模型。

进一步阅读

为了进一步巩固你的知识,你可以查阅以下链接中的文档:

第五章:使用 MLflow 管理模型

在本章中,您将了解 MLflow 中模型管理的不同功能。您将了解 MLflow 中的模型生命周期,我们将解释如何将其与您的常规开发工作流程集成以及如何创建 MLflow 中不可用的自定义模型。模型生命周期将与 MLflow 的模型注册表功能一起介绍。

具体来说,在本章中,我们将查看以下部分:

  • 理解 MLflow 中的模型

  • 探索 MLflow 中的模型风味

  • 管理模型和签名模式

  • 使用模型注册表管理生命周期

从工作台的角度来看,我们希望使用 MLflow 来管理我们的模型并实施一个清晰的模型生命周期。通过将管理模型功能添加到我们的基准测试中,利用 MLflow 将提高我们机器学习工程解决方案的质量和运营。

技术要求

对于本章,您需要以下内容:

  • 在您的机器上安装了最新版本的 Docker。如果您还没有安装,请按照docs.docker.com/get-docker/中的说明进行操作。

  • 最新版本的 docker-compose 已安装。请按照 docs.docker.com/compose/ins… 中的说明进行操作。

  • 在命令行中访问 Git 并按照git-scm.com/book/en/v2/Getting-Started-Installing-Git中描述的方式进行安装。

  • 访问 Bash 终端(Linux 或 Windows)。

  • 访问浏览器。

  • 安装了 Python 3.5+。

  • 本地安装了您机器学习工作台的最新版本,如第三章中所述,您的数据科学工作台

理解 MLflow 中的模型

在 MLflow 平台上,您有两个主要组件可用于管理模型:

  • 模型:此模块管理平台上的格式、库和标准执行模块。它支持最常用的多种机器学习模型:sklearn、XGBoost、TensorFlow、H20、fastai 等。它具有管理模型输出和输入模式的功能,并便于部署。

  • 模型注册表:此模块处理模型生命周期,从注册和标记模型元数据以便相关系统检索。它支持不同状态的模型,例如,实时开发、测试和生产。

MLflow 模型在本质上是一种模型打包格式。MLflow 模型打包的主要目标是使模型类型与其执行环境解耦。MLflow 模型的类比有点像模型的 Dockerfile,其中您描述模型的元数据,并且上游的部署工具能够根据规范与模型交互。

如图 5.1 中的图所示,在一侧您有您的模型库,例如 TensorFlow 或 sklearn。在 MLflow 的核心,您有 MLflow 模型格式,它能够以多种风味(模型格式)提供,以满足本地和云上不同类型的推理工具:

图片

图 5.1 – MLflow 模型图

图 5.1是从 URL www.infoq.com/presentations/mlflow-databricks/# 提取的。

MLflow 模型定义的核心部分是 MLflow 模型文件,如图中下一个屏幕截图所示:

图片

图 5.2 – MLmodel 文件的示例

一个 MLmodel 示例可以在图 5.2 中看到,并提供以下信息:

  • 运行 ID:这是对项目模型运行的引用,该运行允许创建模型。

  • 创建时间:模型创建的时间戳。

  • MLflow 提供的pyfunc模型。

  • 签名:这是 MLmodel 中定义模型签名并允许您以某种方式类型化模型推理过程的组件。它允许验证需要与模型签名匹配的输入数据。

pyfunc。此函数在支持 Python 的任何环境中都受支持,为模型的部署者提供了在 MLflow 中记录模型后如何最佳运行模型的灵活性:

  1. 在项目的 GitHub 仓库中,请转到Gradflow文件夹,并按照以下命令启动本章的环境:

    make 
    
  2. 您可以运行包括图 5.3 中显示的模型单元格在内的所有单元格:图片

    图 5.3 – MLmodel 文件的示例

    图 5.3 中的模型应该与第四章中使用的模型非常相似,即 MLflow 中的实验管理。使用mlflow.start_run,您可以在 MLflow 中开始记录模型,并利用平台固有的功能来捕获正在开发的模型的相关细节。

  3. 您现在可以探索 MLflow 中的MLmodel文件!图片

    图 5.4 – MLmodel 文件的示例

  4. 在 MLflow 中探索conda文件!图片

    图 5.5 – MLmodel 文件的示例

  5. 将模型以MLflow Pyfunc格式加载进行预测:

    import mlflow
    logged_model = ‘/data/artifacts/1/132e6fa332f2412d85f3cb9e6d6bc933/artifacts/model’
    # Load model as a PyFuncModel.
    loaded_model = mlflow.pyfunc.load_model(logged_model)
    # Predict on a Pandas DataFrame.
    import pandas as pd
    loaded_model.predict(pd.DataFrame(X_test))
    

    或者,模型可以以原生 H5 Keras 格式加载,并加载到完全不同的应用程序中,如图 5.4 所示,使用/data/model/model.h5文件。

在本节介绍了 MLflow 中的模型概念之后,我们将进一步深入探讨 MLflow 中不同类型的模型。

探索 MLflow 中的模型风味

MLflow 中的模型风味基本上是 MLflow 支持的不同库的不同模型。此功能允许 MLflow 使用每个特定模型的本地库处理模型类型,并支持一些模型的本地功能。以下列表展示了代表模型的选取,以描述和说明 MLflow 中可用的支持:

  • mlflow.tensorflow: TensorFlow 是迄今为止最常用的库之一,特别适合深度学习。MLflow 通过以 TensorBoard 格式保存日志,与模型格式和监控能力进行原生集成。MLflow 支持 TensorFlow 模型的自动记录。

  • mlflow.h2o: H2O 是一个面向模型自动化的完整机器学习平台,与 MLflow 有一些重叠的功能。MLflow 提供了在 H2O 原生格式中加载(load_model)和记录模型(log_model)的能力,允许工具之间的互操作性。不幸的是,截至当前 MLflow 版本,你无法在h2o模型上使用自动记录:

    mlflow.h2o.load_model(...)
    mlflow.h2o.log_model(...)
    
  • mlflow.spark: MLflow 通过两个主要接口与 Apache Spark 库进行原生集成:Spark MLlib 用于机器学习,以及 MLeap 平台(combust.github.io/mleap-docs/… 更像是一个部署平台,而 MLlib 则更像是一个你可以添加到项目中的库。

MLflow 支持非常全面的口味/格式列表,它们的用法和支持可以在这里阅读:www.mlflow.org/docs/latest/python_api/index.html.

)

自定义模型

我们可以深入探讨下一段代码和自定义的RandomPredictor模型。只要提供一个具有fitpredict方法接口的类,你就可以拥有自己的自定义 MLflow 模型:

class RandomPredictor(mlflow.pyfunc.PythonModel):
  def __init__(self):
    pass
  def fit(self):
    pass
  def predict(self, context, model_input):
    return model_input.apply(
        lambda column: random.randint(0,1))

在前面的class中,我们基本上使用随机概率,它可以作为一个样本模型,用于确保你的模型比随机模型更好。

在本节中,我们介绍了不同类型的模型风味和自定义模式的创建。接下来,我们将探讨 MLflow 的一些模式和签名特征。

管理模型签名和模式

MLflow 的一个重要特性是提供模型输入和输出模式的抽象,以及在预测和训练期间验证模型数据的能力。

如果你的输入在预测期间不匹配模型的模式和签名,MLflow 会抛出一个错误:

  1. 接下来,我们将查看一个简单的数字分类模型(数据集的详细信息可在以下链接找到:archive.ics.uci.edu/ml/datasets/Optical+Recognition+of+Handwritten+Digits)的代码示例。以下代码将图像展平为 pandas DataFrame,并将模型拟合到数据集:

    from sklearn import datasets, svm, metrics
    from sklearn.model_selection import train_test_split
    import mlflow
    digits = datasets.load_digits()
    n_samples = len(digits.images)
    data = digits.images.reshape((n_samples, -1))
    clf = svm.SVC(gamma=0.001)
    X_train, X_test, y_train, y_test = train_test_split(
        data, digits.target, test_size=0.5, shuffle=False)
    mlflow.sklearn.autolog()
    with mlflow.start_run():
        clf.fit(X_train, y_train)
    
  2. 我们将查看之前的代码列表,您可以在新的笔记本中运行它,并通过 MLflow UI 深入调查 图 5.6 中生成的 MLmodel:

    图 5.6 – MLmodel 文件示例

  3. MLmodel 文件包含输入和输出文件的 JSON 签名。对于一些自动记录的变体,我们可能无法自动推断签名,因此您可以在记录模型时提供签名:

    # flatten the images
    from mlflow.models.signature import infer_signature
    with mlflow.start_run(run_name=’untuned_random_forest’):
        …
        signature = infer_signature(X_train, 
            wrappedModel.predict(None, X_train))
        mlflow.pyfunc.log_model(“random_forest_model”, 
                                python_model=wrappedModel, 
                                signature=signature)
    

在之前的代码块中,模型的签名由 infer_signature 方法提供。当模型通过 log_model 记录时,签名被提供。签名与模型一起记录的一个重要优点是它们可以作为模型的文档和元数据。第三方系统可以消费元数据并通过验证数据或为模型生成文档与模型交互。

在本节中,我们介绍了 MLflow 模型的模式化和签名功能。现在我们将继续探讨这个空间中的另一个关键模块,即模型注册表。

介绍模型注册表

MLflow 模型注册表是 MLflow 中的一个模块,它包含一个用于存储模型的集中存储库,一个允许在注册表中管理模型生命周期的 API。

对于机器学习模型开发者来说,一个典型的流程是获取训练数据;清理、处理和训练模型;然后将其交给负责部署模型的人员或系统。在非常小的环境中,如果您有一个人负责这个功能,这相当简单。当团队中模型的种类和数量开始扩展时,挑战和摩擦开始出现。以下是一些机器学习开发者提出的关于存储和检索模型的常见摩擦点:

  • 在大型团队中的协作

  • 生产中淘汰过时的模型

  • 模型的来源

  • 模型缺乏文档

  • 识别模型的正确版本

  • 如何将模型与部署工具集成

MLflow 模型注册表背后的主要思想是在组织中提供一个中央存储模型的地方,所有相关模型都存储在此,并且可以被人类和系统访问。一个很好的类比就是具有相关元数据和模型集中状态管理的模型 Git 仓库。

在 MLflow UI(可在您的本地环境中使用)中,您应单击 实验 标签右侧带有 模型 标签的选项卡,如箭头所示:

  1. 通过此模块,您能够列出所有已注册的模型,按名称搜索或按名称创建。对于每个模型,您可以看到最新版本的标签以及处于预发布或生产中的特定版本!

    图 5.7 – 模型注册表 UI

  2. 可以通过点击 创建模型 按钮创建一个新模型,并为特定模型指定一个相关名称,如图 5.8 所示:

    5.8 – 模型注册库 UI – 创建模型

  3. 你也可以通过进入 实验 模型并选择你的一个模型来在 MLflow 中创建模型,然后,具体决定注册该模型。你将必须将你的运行与现有模型关联或创建一个新模型名称,以关联此特定类型的模型:

5.9 – 模型跟踪 UI – 创建新模型

当你添加一个新模型时,MLflow 会自动增加版本号,并将此版本标记为最新版本,组织中的每个人都可以查询给定问题的模型的最新版本。

将你的最佳模型添加到模型注册库

在 MLflow 的 UI 中可以执行的所有操作也可以通过 MLflow API 实现。

我们可以快速回到我们的股票市场预测用例,并将我们的第一个基线模型添加到模型注册库,并运行本章仓库中可用的 hyperopt_optimization_logistic_regression_mlflow.ipynb 笔记本,并根据图 5.10 所示的 F1 分数指标按降序排序运行:

5.10 – 选择最佳模型

从那里,你应该能够注册名为 BTC StockPrediction 的最佳模型,如图 5.11 所示:

5.11 – 命名你的模型

通过返回模型模块,你将注意到,如图 5.12 所示,你的新创建的模型位于 版本 1 下:

5.12 – 已注册模型

在介绍了模型注册库的功能后,在下一节中,我们将描述一个模型开发生命周期,以帮助组织你的模型管理。

管理模型开发生命周期

在一个由多个模型开发者组成的团队中工作,管理模型生命周期非常重要。在同一个项目中尝试不同模型是相当常见的,让审阅者决定最终进入生产的模型非常重要:

5.13 – 模型开发生命周期的示例

如果使用与图 5.13 所示类似的生命周期,模型在其生命周期中可以经历以下阶段:

  • 开发:模型开发者仍在探索和尝试不同的方法,仍在尝试找到解决他们的机器学习问题的合理解决方案。

  • 预发布:模型可以与生产类型流量自动测试的状态。

  • 生产:当模型准备好处理现实生活中的生产流量时。

  • 存档:当模型不再服务于其最初开发时的业务目的时,它将被存档,其元数据将存储以供将来参考或合规性使用。

例如,如图 5.14所示,审稿人或主管可以将模型从开发状态移动到预发布状态,以便在测试环境中进一步部署,如果经审稿人批准,模型可以过渡到生产状态:

图 5.14 – 模型开发生命周期的示例

在从 MLflow 中的状态转换时,你有选择将处于现有状态的模型发送到下一个状态:

图 5.15 – MLflow 中的阶段转换

在成熟环境中,从预发布阶段到生产阶段的转换旨在自动进行,正如我们将在本书的后续章节中展示的那样。

通过本节,我们完成了与 MLflow 中模型相关特性的描述。

摘要

在本章中,我们首先介绍了 MLflow 中的模型模块及其对不同算法的支持,从基于树的到线性的再到神经网络的。我们了解了模型日志和指标的支持以及自定义指标的创作。

在前两节中,我们介绍了模型注册模型及其如何使用它来实现模型生命周期来管理我们的模型。

在本书的下一章和章节中,我们将专注于将到目前为止学到的概念应用于现实系统,并将为生产环境设计一个机器学习系统。

进一步阅读

为了巩固你的知识并深入了解本章中介绍的概念,你应该查看以下链接:

第三部分:生产环境中的机器学习

本节将介绍 MLflow 中可用于将模型从开发阶段无缝过渡到生产环境的各种功能。

本节涵盖了以下章节:

  • 第六章, 介绍机器学习系统架构

  • 第七章*,* 数据和特征管理

  • 第八章*,* 使用 MLflow 训练模型

  • 第九章*,* 使用 MLflow 进行部署和推理

第六章:介绍机器学习系统架构

在本章中,你将了解在更广泛的软件工程(SWE)背景下机器学习(ML)系统架构的一般原则,以及以可靠方式在生产中部署模型时常见的常见问题。你还将有机会跟随我们构建我们的机器学习系统。我们将简要探讨如何使用 MLflow 以及其他相关工具构建可靠和可扩展的机器学习平台。

具体来说,在本章中,我们将探讨以下部分:

  • 理解机器学习系统和项目中的挑战

  • 调查最先进的机器学习平台

  • 构建 PsyStock 机器学习平台

你将遵循一个理解问题、研究行业领先公司提供的不同解决方案,然后开发你自己的相关架构的过程。这种三步法可以转移到你想要开发的任何未来的机器学习系统中。

技术要求

对于本章,你需要满足以下先决条件:

  • 在你的机器上安装了最新版本的 Docker。如果你还没有安装,请按照docs.docker.com/get-docker/中的说明操作。

  • 已安装docker-compose的最新版本。请按照docs.docker.com/compose/install/中的说明操作。

  • 在命令行中访问 Git,并按照git-scm.com/book/en/v2/Getting-Started-Installing-Git中的说明进行安装。

  • 访问 Bash 终端(Linux 或 Windows)。

  • 访问浏览器。

  • 已安装 Python 3.5+。

  • 第三章中所述,在本地安装了与你的机器学习平台最新版本兼容的版本,你的数据科学工作台

理解机器学习系统和项目中的挑战

利用机器学习实现产品可能是一项费力的任务,因为需要在书中介绍一些关于机器学习系统架构最佳实践的新概念。

到目前为止,在这本书中,我们已经展示了 MLflow 如何使日常模型开发者拥有一个平台来管理从模型开发迭代到在模型注册表中存储模型整个机器学习生命周期。

总结来说,到目前为止,我们已经为模型开发者创建了一个平台,让他们可以构建模型并在中央仓库中发布模型。这是开始挖掘创建的模型商业价值理想阶段。在机器学习系统中,要从模型开发跃迁到生产中的模型,需要转变思维方式和采取不同的方法。在解锁价值和构建模型之后,利用阶段开始,这时拥有机器学习系统架构可以为你的模型部署和运营定下基调。

机器学习系统是传统软件开发(SWE)领域的专业化分支,因此我们可以也应该利用 SWE 领域的知识体系来构建我们的系统。与我们相关联的 SWE 概念如下:

  • 关注点分离:一个完整的系统应该被分割成不同的组件。系统的每个组件都应该是独立的,并且专注于做好一件事。例如,一个训练组件应该专注于训练,而不是同时进行评分。

  • 自主性:系统的每个组件都应该作为一个独立的自主单元存在,并且可以独立部署。例如,您的 API 系统的部署应该独立于训练系统的部署。

  • 弹性:关注点分离和模块化的一个后果是我们必须确保如果更广泛系统的一个组件出现故障,这不会影响独立组件。如果一个机器平台的批量评分机制出现故障,它不应该影响实时系统。

  • 可扩展性:我们应该能够独立并根据其工作负载独立扩展系统的不同组件。

  • 可测试性:这代表系统被测试的能力以及其功能与一组代表性输入进行验证的能力。在机器学习系统中,由于模型的非确定性,这一点尤其困难。

  • 持续部署/交付:这代表在几乎没有任何摩擦的情况下,在代码、配置、模型或数据发生变化时部署系统的能力,在机器学习的情况下,以便有新版本的系统。

  • 可组合性:我们应该能够将系统的组件在未来项目中重复使用,以提高投资回报率。因此,机器学习工程师需要确保正在开发的代码和组件易于重复使用和/或与其他系统互操作。

  • 可维护性:这是系统被修改、修复和改进以适应不断变化的环境需求的容易程度。

在这个阶段,我们可以简要介绍并细化我们的用例,即股票预测,以在 PsyStock 公司开发我们的机器学习平台。

基于迄今为止在原型设计模型以预测比特币价格方面所做的工作,公司的业务发展部门决定将其第一个产品作为加密货币预测 API来启动,因为它们正在成为企业界的一种流行技术。一个团队被组建起来,决定调查挑战和最先进的平台,然后构建公司的自有平台。

一个机器学习项目通常涉及公司中的许多部门。以 PsyStock 为例,一个典型的机器学习项目团队包括以下利益相关者:

  • 数据科学团队:负责构建和发展模型,目标是实现最高准确率,预测加密货币价格和市场走势。

  • 机器学习/数据工程团队:负责工程组件,包括数据采集、准备、训练和部署,并关注系统在生产中正确部署并按规格运行。

  • 基础设施团队:负责提供计算和基础设施资源。期望系统不会给团队带来运营负担。

  • 产品团队:提供与公司网络平台和整体软件的集成,推动功能创建,确保快速推理速度。

  • 业务发展/市场营销团队:打包和营销产品,并监控产品的业务表现。

在下一节中,我们将了解机器学习系统和项目的一般挑战。

机器学习(ML)是技术的一个重要应用,旨在帮助组织利用数据释放价值。在商业世界中应用机器学习时,尚未定义标准实践,许多组织都难以将基于机器学习的产品投入生产。

在现实世界中,将模型投入生产的简单方法可能包括以下步骤:

  1. 数据科学家在笔记本环境中创建模型,并在 R 语言中实现代码。

  2. 数据科学家与工程团队分享笔记本,表示他们已准备好将他们的模型投入生产。

  3. 工程团队使用他们能理解的语言重新实现了训练过程,在这种情况下,是 Python 语言。

  4. 经过长时间的试错过程,直到数据科学团队和工程团队达成一致,认为定制化训练系统产生的模型与原始模型产生等效的输出。

  5. 创建并开发了一个新的系统来评分系统,工程团队注意到高延迟。由于当前状态无法重新开发,模型被发送回重新开发。

上一段描述的情况比你想象的更常见。这在 D. Sculley 等人于 2015 年发表的论文《机器学习系统中隐藏的技术债务》中有详细描述。谷歌的一个团队识别了以下与天真地实施机器学习平台相关的风险因素和技术债务:

  • 边界侵蚀:由于机器学习系统的本质是混合不同逻辑域的信号,因此在 SWE 中尽可能保持业务域的清晰逻辑具有挑战性。另一个自然问题是将模型输出作为第三个模型A的输入的诱惑,这可能会在模型B中产生意外的效果。

  • 昂贵的依赖数据:新鲜、准确和可靠的数据是机器学习系统最重要的组成部分。例如,在加密货币案例中,为了能够预测,可能会结合使用外部 API 和社会网络情绪信号。在某个时刻,其中一个数据信号可能不可用,使得其中一个组件不可用。现实世界中的数据分布可能会改变,导致模型在现实世界中的推理变得不相关。

  • 反馈循环:在某些情况下,模型会影响用于训练的数据选择。信用评分就是一个很好的例子。决定谁将获得模型下一次重新训练的信用的人将选择受模型影响的人群中的训练数据。在开发模型时,分析模型对地面数据的影响是很重要的。

  • 系统级反模式:机器学习系统因其包含不同包和缺乏适当抽象的粘合代码而臭名昭著。在某些情况下,由于在笔记本中编写代码的迭代性质,可能会使用多种语言来实现库。

  • 配置管理:通常在机器学习系统中被忽视,但特定结果产生的配置信息对于模型的后分析和部署至关重要。不使用既定的配置管理实践可能会在机器学习管道中引入错误。

  • 监控和测试:集成测试和单元测试是 SWE 项目中的常见模式,但由于机器学习项目的随机性质,它们更难实施。

解决机器学习系统挑战的一个重要实践是在模型训练期间以及系统运行时,对过程的临界部分、代码进行广泛的测试,如图 6.1 所示:

图片

图 6.1 – 从 research.google/pubs/pub465…

图 6.1 所展示的是通过标准软件实践测试系统的不同部分,并添加专门的数据预测监控来应对技术债务的一种方法。重要的新增加是数据测试和模型测试,因此测试传入数据和训练数据,同时能够监控这些测试并决定系统是否通过相关标准是至关重要的。

作为平台,MLflow 解决了本节中提到的机器学习系统的一些问题。MLflow 专注于机器学习技术债务的特定维度,是创建机器学习平台的一个很好的支柱组件。

在下一节中,我们将探讨一些最先进的鲁棒机器学习工程系统的例子,以指导我们的开发。

调查最先进的机器学习平台

从高层次来看,一个成熟的机器学习系统具有图 6.2中概述的组件。这些组件理想上是独立的,并负责系统的特定功能:

图片

图 6.2 – 机器学习平台组件

遵循 SWE 模块化的先例,这些通用组件使我们能够比较不同的机器学习平台,并指定我们对 PsyStock 每个组件的要求。我们选择用作架构比较参考的组件如下:

  • 数据和特征管理:数据和特征管理组件负责数据采集、特征生成、存储以及向上游模块提供服务。

  • 训练基础设施:处理模型训练过程、调度、消耗特征以及生成最终模型的组件。

  • 部署和推理:该单元的职责是模型的部署推理和批处理评分。它是系统的外部面孔,对外部系统是可访问的。

  • 性能和监控:一个处理可观察性、不同系统发布的指标以及生产中的监控系统的组件。

  • 模型管理:管理模型工件版本和模型的生命周期。

  • 工作流管理:负责编排批处理工作流和处理管道的组件。

在描述了机器学习平台的不同组件之后,我们将查看一些示例,从 Uber 的 Michelangelo 开始。

了解 Michelangelo

Uber 是首批广泛记录其认识到机器学习平台对于释放数据价值至关重要的公司之一。

Uber 构建平台内部动机如下:

  • 由于将本地模型转换为生产所需的大量资源,机器学习的影响有限。

  • 不可靠的机器学习和数据管道。

  • 工程团队必须为现有系统创建定制的服务容器和系统。

  • 无法扩展机器学习项目。

以下图 6.3(来自eng.uber.com/michelangelo-machine-learning-platform)展示了 Michelangelo 的不同组件。一个显著组件是 Uber 基础设施中的数据组件,它将实时数据基础设施与流系统(如 Kafka)解耦,以从外部获取数据,这些数据流向训练过程,然后到实时和离线模式下的评分。独特的特征包括批处理世界和实时世界的分离,以及为 API 和批处理系统提供通用预测服务:

图片

图.6.3 – Michelangelo 架构

我们选择用作架构比较参考的组件如下:

  • 数据和特征管理:它包含一个集中式数据存储,其中包含为服务模型和训练模型所需的所有特征。特征数据存储可以实时和批量访问。对于批量场景,他们使用名为 Hive 的数据库系统,对于实时,他们使用 Cassandra。

  • 训练基础设施:使用名为Horovodgithub.com/horovod/horovod)的工具提供的分布式训练基础设施,具有专门和定制的组件以及增强的报告功能。它为每种类型的模型(深度学习、模型、特征重要性等)提供自定义指标。训练作业的输出是使用 Cassandra 数据库作为后端的模型存储库。

  • 部署和推理:通过标准的 SWE 实践(CI/CD、基于指标监控的回滚等)部署的系统,通常作为工件在 Uber 数据中心提供。一个预测服务接收请求,并根据头部信息预先加载正确的模型,并使用内部 DSL 在特征存储的服务层查询进一步的数据增强,从而提供预测向量。

  • 性能和监控:它利用公司通用的集中式日志系统。对于监控预测,会生成预测和现实世界值的相关指标,并将差异记录下来。通过这种方式,可以分析和监控模型的错误。

  • 模型管理:模型作为工件编译并存储在 Cassandra 数据存储中。

  • 工作流管理:提供用于连接管道的 API。它包含一个管理平面,其中包含一个 UI,允许管理模型和部署。工作流管理是 API 驱动的,可以从外部使用 Python 或 Java 进行管理。

对于像 Uber 这样的公司来说,建立自己的系统的一个明显优势是灵活性和满足他们非常具体用例的能力。

了解 Kubeflow

Kubeflow 在某种程度上是一个针对Kubernetes环境的开源平台,用于机器学习生命周期。它基本上是一个工具生态系统,这些工具协同工作以提供机器学习平台的主要组件。Kubeflow 最初是在谷歌开发的,目前是一个非常活跃的开源项目。

Kubernetes是领先的开放源代码计算环境之一,它允许在容器化工作负载中灵活分配计算和存储资源。它最初是在谷歌创建的。为了理解 Kubeflow,需要基本了解 Kubernetes。以下官方文档链接包含了理解基础所需的前提条件:kubernetes.io/docs/concepts/overview/

图 6.4 所示,它使用 Kubernetes 的基础,提供了一套机器学习工作流的应用程序,其中可以聚合与 Kubeflow 标准兼容的不同工具,以提供一套连贯的服务:

图片

图 6.4 – 来自 www.kubeflow.org/docs/starte…

我们选择用作架构比较参考的组件如下:

  • 数据和特征管理:Kubeflow 提供与 Spark 等大数据工具的集成。用于数据和特征管理的一个生态系统组件称为 Feast,是一个开源的机器学习特征。

  • 训练基础设施:Kubeflow 为常见的模型如 TensorFlow、PyTorch 和定制模型提供特定的 Kubeflow 运算符。训练作业基本上是特定的 Kubernetes 作业。

  • 部署和推理:Kubeflow 提供与 TensorFlow Serving、Seldon Core 和 KFServing 等第三方工具的多个集成,具有不同的权衡和成熟度水平。

  • 性能和监控:Prometheus 是一种在 Kubernetes 环境中使用的通用监控工具,可以在此环境中利用。

  • 模型管理:不是专门用于管理模型的工具,但可以添加如 MLflow 这样的工具来覆盖模型管理生命周期。

  • 工作流管理:通过一个名为 Kubeflow Pipelines 的特定工具进行工作流管理,该工具建立在 Kubernetes 上的通用管道工具 Argo Workflows 之上。它允许通过代码构建多步骤管道。

在查看参考架构后,我们现在将花时间构建自己的架构,凭借行业中最先进的知识。

架构 PsyStock 机器学习平台

我们可以根据对最佳实践和示例参考架构的研究提炼出的原则,为我们的机器学习平台定义一组期望的原则。我们希望在平台中保持的主要原则如下:

  • 利用 开放系统和标准:使用如 MLflow 提供的开放系统允许长期性和灵活性,以利用开源社区的进步和力量,以较低的成本扩展公司的机器学习平台。

  • 优先考虑 可扩展的解决方案:公司需要为未来增长激增做好准备;尽管这是第一个版本,但根据需求和视角进行激增的能力需要到位。

  • 集成 可靠的数据生命周期:数据是机器学习平台的重心,应该以可靠和可追踪的方式在规模上进行管理。

  • 遵循 软件开发最佳实践:例如,关注点分离、可测试性、CI/CD、可观察性和模块化。

  • 维护 供应商和云独立性:PsyStock 作为一个初创公司,在一个非常动态的环境中运营,在不同的地理区域,可以访问不同的云,在某些情况下,还需要遵守不将数据从给定地理区域移动的要求。因此,保持云无关性并能够在不同的环境中拥有工作负载是一个竞争优势。

这些原则将使我们能够在公司内部构建一个开放且成本低的系统架构,并允许在不同的系统上运行,无论是在本地、云中还是本地。

我们之前已经定义了预测用例的业务需求,即加密货币运动的检测和价值预测。为了利用这一点和其他用例,创建一个机器学习平台对公司来说至关重要。

现在,凭借对最先进系统的研究和描述的知识,我们将接下来定义激发我们机器学习平台特性的方法。

描述机器学习平台的功能

制定特性规范对于保持开发工作专注于一小套能够为平台用户解锁价值的特性至关重要。在本节中,我们将激发能够实现机器学习平台最佳价值的特性。

在我们的系统中,我们希望能够具备以下功能:

  • 特性:安排训练作业:数据科学家需要能够使用配置或等效代码为他们的模型安排训练作业。

  • 特性:无缝部署从数据科学工作台开发的不同模型:公司在第三章“你的数据科学工作台”中已经开发了一个数据科学工作台。我们希望能够利用之前所做的所有工作,以便在平台上开发的模型可以部署到生产环境中。

  • 特性:允许在出现新数据的情况下重新校准模型:当特定位置出现新数据时,需要自动生成一个新模型并将其存储在平台系统和人类可访问的模型注册表中。

  • 特性:提交和配置批量评分作业:平台应允许相关用户在出现新数据的情况下配置和安排批量作业。

  • 特性:基于高效推理 API 的以下 API 评分:给定一个模型,平台应该具有使用模型模式创建匹配 API 的功能。

在讨论了机器学习系统的理想特性之后,我们将在下一节中开始从高层次构建系统。

高层次系统架构

我们现在将专注于定义我们架构的构建块以及不同组件之间的不同数据流。

根据上一节中指定的特性和原则,我们的机器学习平台和解决方案应包含以下组件,如图 6.5中的架构图所述。

图片

图 6.5 – ML 平台架构图

此图对技术选择具有特定的不确定性,因为这将在即将到来的章节中完成,届时将全面探索每个组件的工程。

  1. 数据和特征管理:这是通过特征/数据层执行的,该层从工作台接收特征注册,并允许从工作台注册数据集。数据层为训练环境提供数据。

  2. 训练基础设施:训练基础设施组件允许根据数据科学工作台的请求安排作业的训练。

  3. 部署和推理:部署环境消耗模型以执行批量或实时操作,由数据层中的数据或通过生产系统发出的请求触发。

  4. 性能和监控:这是通过监控和指标的中心组件来实现的,所有围绕该组件的系统都会将指标发布到其中。

  5. 模型管理:由模型注册表组件封装,其中包含存储和相关生命周期项目。输入主要来自训练作业和数据科学工作台。

  6. 工作流管理:这是一个允许协调不同系统的组件。例如,它允许安排作业和依赖关系管理,强制执行执行顺序。例如,推理批处理作业只能在训练作业之后执行。这可以通过操作系统使用 Cron 系统或通过更复杂的流程工具(如 Airflow)来实现。

我们接下来将简要介绍我们将如何使用MLflow实现本节概述的想法。

MLflow 和其他生态系统工具

MLflow 是由开源社区创建的一个工具,旨在解决开放系统中 ML 系统的一个空白,专注于可重复性、模型管理和部署。MLflow 绝对不是一个完整的工具;它需要其他组件,当其优势得到利用时,它是 ML 解决方案的一个核心部分。

近年来,在 Kubernetes 世界中出现了如Kubeflow之类的系统,旨在帮助管理 ML 系统的基础设施方面,并作为实际的部署环境。

Minio是 Kubeflow 附带的一个存储系统,它将用作元数据和数据集的无差别存储机制,并为云和本地环境上的存储提供抽象。

在确定了关于 ML 平台行业的最佳实践、概述了我们的需求,并在本节中设计了我们的 ML 平台架构后,我们将用本书的接下来的四章来构建我们平台的所有组件。

摘要

在本章中,我们介绍了构建机器学习系统所涉及的概念,映射了利益相关者,确定了常见问题和最佳实践,并概述了初始架构。我们在数据层和建模与推理层上确定了机器学习系统架构的关键构建块。强调了组件之间的互连,并概述了功能规格。

我们还讨论了如何在您的机器学习平台上利用 MLflow 以及其他参考工具可以补充的不足之处。

在本书的下一章节和部分中,我们将专注于将到目前为止学到的概念应用于实际系统,并通过实现 PsyStock 机器学习平台的架构来实践。我们将为每个组件设立一个章节,从规格说明开始,直到包含实际示例的组件实现。

进一步阅读

为了进一步扩展您的知识,您可以查阅以下链接中的文档: