DataBrick-机器学习实战-全-
DataBrick 机器学习实战(全)
原文:
annas-archive.org/md5/5cdf821417f3768adfda996e91e9305e译者:飞龙
前言
在这本书中,你将发现是什么让 Databricks 数据智能平台成为顶级机器学习解决方案的首选。Databricks ML in Action 通过在 Databricks 平台上执行数据科学、机器学习和生成式 AI 项目的端到端示例,展示了云无关的实践。你将在学习如何在实际工作流程中实际应用它们的过程中,掌握 Databricks 的托管 MLflow、向量搜索、AutoML、Unity 目录和模型服务方面的专业知识。这本书不仅提供了详细的代码解释,还促进了代码的无缝导入,以便实际使用。你会发现如何利用开源的 Databricks 平台,通过补充资源来增强你的学习,提高你的技能,并提高你的生产力。到本书结束时,你将精通使用 Databricks 进行数据科学、机器学习和生成式 AI,使你能够交付卓越的数据产品。
这本书面向谁
这本书面向寻求在实施和利用 Databricks 数据智能平台及其湖仓架构以创建数据产品的机器学习工程师、数据科学家和技术经理。
这本书涵盖的内容
第一章,使用本书和湖仓概念入门,涵盖了数据工程和机器学习的技术和方法。目标不是揭示以前从未见过的数据洞察。如果是那样的话,这将是一篇学术论文。相反,本章的目标是利用开放和免费的数据来展示高级技术和最佳实践。你将列出并描述书中出现的每个数据集。
第二章,设计 Databricks:第一天,涵盖了工作空间设计、模型生命周期实践、命名约定、不要放入 DBFS 中的内容以及其他准备性话题。Databricks 平台易于使用。然而,有许多选项可供选择,以满足不同组织的需求。在我的承包商生涯和我在 Databricks 的时间中,我看到了团队的成功与失败。我将与你分享成功的动态以及本章中伴随这些洞察的任何配置。
第三章,构建我们的青铜层,通过探索奖牌架构青铜层的基本原理,开始你在 Databricks DI 平台中的数据之旅。青铜层是转换你的数据以用于下游项目的第一步,本章将重点介绍你可用于必要转换的 Databricks 功能和技术。我们将首先向你介绍自动加载器,这是一个用于自动化数据摄入的工具,你可以使用或不需要Delta Live Tables(DLT)来插入和转换你的数据。
第四章,了解您的数据,探讨了 Databricks DI 平台内有助于提高和监控数据质量以及促进数据探索的功能。使用 Databricks 更好地了解数据有众多方法。首先,我们将介绍如何使用 DLT 来监督数据质量,以尽早发现质量问题并防止整个管道的污染。我们将首次深入了解 Lakehouse 监控,它帮助我们分析数据随时间的变化,并可以提醒我们关注的变化。
第五章,在 Databricks 上进行特征工程,从第四章开始,我们在那里利用 Databricks 的力量来探索和精炼我们的数据集,深入探讨 Databricks 的组件,这些组件使下一步的特征工程成为可能。我们将首先介绍在 Unity Catalog 中的Databricks 特征工程(DFE),向您展示您如何使用 Unity Catalog 高效地管理工程特征。了解如何在 UC 中利用 DFE 对于创建跨训练和推理的可重复和一致的特征至关重要。然后,您将学习如何利用 Structured Streaming 在流上计算特征,这允许您创建模型做出快速决策所需的状态化特征。
第六章,寻找信号,探讨了如何利用数据科学在数据的噪声中寻找隐藏的信号。我们将利用上一章在 Databricks 平台上创建的特征。我们将首先使用 AutoML 进行基本的建模方法,提供自动生成的代码,并快速使数据科学家能够建立基准模型以超越。在寻找信号时,我们尝试不同的特征、超参数和模型。从历史上看,跟踪这些配置及其相应的评估指标本身就是一项耗时的工作。MLflow 提供的一种低开销跟踪机制,如用于管理数据科学项目和支撑 MLOps 的开源平台 MLflow 提供的跟踪,将减轻手动捕获配置的负担。更具体地说,我们将介绍 MLflow 跟踪,这是一个显著提高跟踪每个排列众多输出的 MLflow 组件。然而,这仅仅是开始。
第七章,在 Databricks 上生产化机器学习,探讨了使用 Databricks 产品生产化机器学习模型,通过整合 Unity Catalog 注册、Databricks 工作流、Databricks 资产包和模型服务功能等功能,使这一旅程更加直接和连贯。本章将涵盖将您的模型从开发到生产的工具和实践。
第八章,监控、评估和更多,介绍了如何在新的 Lakeview 仪表板和标准的 DBSQL 仪表板中创建仪表板的可视化。部署的模型可以通过网络应用程序共享。因此,我们不仅将介绍 Hugging Face Spaces,还将使用 Gradio 应用程序部署 RAG 聊天机器人,以应用我们所学到的知识。
要充分利用本书
| 本书涵盖的软件/硬件 | 操作系统要求 |
|---|---|
| Databricks | Windows, macOS, 或 Linux |
| Python 及其相关库 | Windows, macOS, 或 Linux |
如果您正在使用本书的数字版,我们建议您亲自输入代码或从书的 GitHub 仓库(下一节中有一个链接)获取代码。这样做将帮助您避免与代码的复制和粘贴相关的任何潜在错误。
本书包含一些较长的截图,这些截图是为了展示工作流程的概览以及用户界面。因此,在 100% 缩放时,这些图像中的内容可能看起来很小。请查看随书提供的 PDF 复印件以放大以获得更清晰的图像。
下载示例代码文件
你可以从 GitHub 下载本书的示例代码文件 github.com/PacktPublishing/Databricks-ML-In-Action。如果代码有更新,它将在 GitHub 仓库中更新。
我们还有其他来自我们丰富的书籍和视频目录的代码包可供在 github.com/PacktPublishing/ 获取。查看它们吧!
使用的约定
本书中使用了多种文本约定。
文本中的代码:表示文本中的代码单词、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 昵称。以下是一个示例:“例如,你可以选择ml_in_action.favorita_forecasting.train_set表。”
粗体:表示新术语、重要单词或屏幕上看到的单词。例如,菜单或对话框中的单词以粗体显示。以下是一个示例:“一旦你有了数据集,请返回到画布选项卡。”
小贴士或重要注意事项
看起来像这样。
联系我们
读者反馈始终欢迎。
一般反馈:如果您对本书的任何方面有疑问,请通过电子邮件发送至 customercare@packtpub.com,并在邮件主题中提及书名。
勘误表:尽管我们已经尽一切努力确保内容的准确性,但错误仍然可能发生。如果您在这本书中发现了错误,我们将非常感激您能向我们报告。请访问 www.packtpub.com/support/errata 并填写表格。
盗版:如果您在互联网上以任何形式遇到我们作品的非法副本,如果您能提供位置地址或网站名称,我们将不胜感激。请通过版权@packtpub.com 与我们联系,并提供材料的链接。
如果您有兴趣成为作者:如果您在某个领域有专业知识,并且您有兴趣撰写或为本书做出贡献,请访问authors.packtpub.com。
分享您的想法
读完《Databricks ML in Action》后,我们非常乐意听到您的想法!请点击此处直接转到该书的亚马逊评论页面并分享您的反馈。
您的评论对我们和科技社区非常重要,并将帮助我们确保我们提供高质量的内容。
下载本书的免费 PDF 副本
感谢您购买本书!
您喜欢在路上阅读,但无法携带您的印刷书籍到处走?
您选择的设备是否与您的电子书购买不兼容?
不要担心,现在,每购买一本 Packt 书籍,您都可以免费获得该书的 DRM 免费 PDF 版本。
在任何地方、任何设备上阅读。直接从您最喜欢的技术书籍中搜索、复制和粘贴代码到您的应用程序中。
优惠不止于此,您还可以获得独家访问折扣、时事通讯和每日收件箱中的精彩免费内容。
按照以下简单步骤获取这些优惠:
- 扫描二维码或访问以下链接

packt.link/free-ebook/978-1-80056-489-3
-
提交您的购买证明
-
就这些!我们将直接将您的免费 PDF 和其他优惠发送到您的电子邮件中
第一部分:Databricks 统一湖仓平台概述
本部分的目标不是揭示以前从未见过的数据洞察。如果是那样,这将是一篇学术论文。相反,目标是使用开放和免费的数据来展示高级技术和最佳实践。本部分将列出并描述本书中存在的每个数据集。它还向您介绍本部分中洞察背后的成功动态以及任何配置。本部分涵盖工作空间设计、模型生命周期实践、命名约定、不要放入 DBFS 的内容以及其他准备性话题。
本部分包含以下章节:
-
第一章,本书和湖仓概念入门
-
第二章,设计 Databricks:第一天
-
第三章,构建我们的青铜层
第一章:开始使用本书和湖仓概念
“给我六个小时砍倒一棵树,我会花前四个小时磨斧头。”
– 亚伯拉罕·林肯
我们将从一个基本的概述开始,介绍 Databricks 的数据智能平台(DI)是一个基于湖仓架构的开放平台,以及这种架构在开发机器学习(ML)应用中的优势。为了简洁起见,本书中将交替使用“数据智能平台”和“Databricks”这两个术语。本章将介绍本书中我们将使用的不同项目和关联数据集。每个项目都有意突出 DI 平台的一个功能或组件。请将示例项目作为每个平台元素的实际操作课程。我们将在每个章节的最后部分通过这些项目进行学习——即应用我们的学习。
在本章中,您将学习以下内容:
-
数据智能平台组件
-
Databricks 平台的优势
-
应用我们的学习
数据智能平台组件
数据智能平台允许您的整个组织利用数据和 AI。它基于湖仓架构,为所有数据和管理层提供一个开放、统一的基石。它由一个数据智能引擎提供动力,该引擎理解您数据的环境。为了实际应用,让我们讨论 Databricks 数据智能平台的组件:

图 1.1 – Databricks 数据智能平台组件
让我们查看以下列表,其中包含图中的项目描述:
-
Delta Lake:数据智能平台内的数据布局会根据常见的数据使用模式自动优化
-
Unity Catalog:一个统一的管理模型,用于保护、管理和共享您的数据资产
-
数据智能引擎:该引擎使用 AI 来增强平台的功能
-
Databricks AI: 支持端到端机器学习解决方案和生成式 AI功能的机器学习工具,包括创建、调整和提供大型语言模型 (LLM)
-
Delta live tables:使自动数据摄取和数据质量成为可能
-
工作流:一个完全集成的编排服务,用于自动化、管理和监控多任务工作负载、查询和管道
-
Databricks SQL (DBSQL): 一种以 SQL 为首的界面,类似于您与数据仓库交互的方式,并具有文本到 SQL 等功能,允许您使用自然语言生成查询
现在我们已经定义了我们的元素,让我们讨论它们如何帮助我们实现我们的机器学习目标。
Databricks 平台的优势
Databricks 对湖屋架构的实施是独特的。Databricks 的基础建立在由 Unity Catalog 管理的 Delta 格式数据湖上。因此,它结合了数据湖的可扩展性和成本效益以及数据仓库的治理。这意味着不仅通过 访问控制列表(ACLs)管理表级权限,而且文件和对象级访问也得到了规范。这种从数据湖和/或数据仓库到统一平台的架构变化是理想的——湖屋促进了组织在分析、商业智能和数据分析项目中的各种新用例。有关湖屋优势的更多信息,请参阅 进一步阅读 部分的 数据湖简介 博客文章。
本节将讨论开源框架的重要性以及它们提供的两个关键优势——透明度和灵活性。
开源特性
开源特性与数据智能平台的关系是独特的。这种独特性体现在开放性和透明度的概念上,通常被称为 Databricks 的“玻璃盒”方法。这意味着当你使用该平台创建资产时,没有不可理解的黑盒迫使你依赖特定供应商进行使用、理解或存储。真正开放的湖屋架构使用开放数据文件格式,使访问、共享和删除数据变得简单。Databricks 对 Apache Spark 的托管版本进行了优化,以利用开放数据格式 Delta(我们将在稍后详细介绍)。这就是为什么 Delta 格式对于大多数用例来说都是理想的。然而,没有任何阻止你使用诸如 CSV 或 Parquet 格式的东西。此外,Databricks 引入了 Delta Lake 通用格式(Delta Lake UniForm),以便轻松集成其他文件格式,如 Iceberg 或 Hudi。有关更多详细信息,请参阅本章末尾的 进一步阅读 部分。
图 1**.2 展示了数据格式与 UniForm 的结合。

图 1.2 – Delta Lake UniForm 使消费 Hudi 和 Iceberg 文件格式与消费 Delta 一样简单
使用第三方和开源软件的能力推动了快速创新。数据处理和机器学习的新进展可以迅速测试并集成到您的流程中。相比之下,专有系统通常需要较长的等待时间,以便供应商整合更新。等待供应商利用开源创新似乎很少见,但这是常态而不是例外。这在数据科学领域尤其如此。软件和算法进步的速度令人难以置信。这种疯狂的创新步伐的证据可以在 Hugging Face 社区网站上每天看到。开发者们在 Hugging Face 上分享库和模型;仅该网站每天就有数百个库更新。
Delta、Spark、Spark 上的 Pandas API(见 图 1.3)和 MLflow 是一致创新的重要例子,这主要得益于它们作为开源项目的透明度。我们特别提到这些,因为它们最初都是由 Databricks 的创始人或公司成员在其成立后创建的。
ML 开发者从这种透明度中受益匪浅,因为它为他们提供了无与伦比的灵活性、易于集成以及来自开源社区的强大支持——所有这些都不需要维护开源全栈的开销。
与公司需要设置全新的开发环境相比,作为承包商使用 Databricks 进行开发速度极快。一些公司需要提交服务请求来安装 Python 库。这可能会成为数据科学家的生产力杀手。在 Databricks 中,许多您喜欢的库都是预先安装并可供使用的,当然,您也可以轻松地安装自己的库。
此外,Databricks 用户群体庞大且充满活力。Databricks 社区网站是一个极好的资源,可以询问和回答有关 Databricks 的任何问题。我们在本章末尾的 进一步阅读 部分包含了一个链接。

图 1.3 – Spark 上的 pandas API
Spark 上的 pandas API 几乎与标准的 pandas 语法相同,这使得对于在 Python 中编写过 pandas 代码的人来说,学习使用 Spark 进行分布式计算变得更加容易。
在继续关注透明度的同时,让我们转向 Databricks AutoML。
Databricks AutoML
Databricks 将其 AutoML 解决方案称为玻璃盒。这个术语突出了这样一个事实:对用户来说没有任何隐藏的东西。在数据智能平台中的这个特性利用了一个开源库 Hyperopt,结合 Spark 进行超参数调整。它不仅智能地探索不同的模型类型,而且在分布式方式中优化参数。Hyperopt 的使用使得 AutoML 实验中的每一次运行都能为下一次运行提供信息,与网格搜索相比,减少了达到最优解所需的运行次数。实验中的每一次运行都关联着一个包含模型代码的笔记本。这种方法提高了生产力,减少了不必要的计算,并让科学家能够进行实验而不是编写样板代码。一旦 AutoML 收敛到算法最优解,就会有“最佳笔记本”用于最佳评分的模型。本书的几个章节中我们将详细探讨 AutoML。
可重用性和可重现性
作为数据科学家,透明度尤为重要。我们不信任黑盒模型。在不理解它们的情况下如何使用它们呢?一个模型的好坏取决于输入的数据。除了不信任模型之外,黑盒还引发了我们对研究可重复性和模型驱动者可解释性的担忧。
当我们创建一个模型时,它属于谁?我们能访问它吗?我们能调整、测试,最重要的是,重用它吗?投入模型创建的时间是不可忽视的。Databricks AutoML 为你提供了解释、重现和重用它创建的模型所需的一切。实际上,你可以将模型代码或模型对象在笔记本电脑或任何地方运行。这种开源、玻璃盒、可重现和可重用的方法论正是我们所倡导的开放。
开放文件格式提供灵活性
灵活性也是 Databricks 平台的一个基本方面,因此让我们深入了解 Delta 文件格式,这是一个开源项目,它使得适应多种不同的用例变得容易。对于那些熟悉 Parquet 的人来说,可以将 Delta 视为 Parquet 的增强版——Delta 文件是带有事务日志的 Parquet 文件。事务日志是一个变革性的因素。可靠性的提高和优化使得 Delta 成为 Databricks 湖屋架构的基础。湖屋的数据湖部分对数据科学、流处理以及非结构化和半结构化数据格式至关重要。Delta 也使得仓库部分成为可能。关于 Delta 有整本书的讨论;在进一步阅读部分可以找到一些例子。我们关注的是它是一个开放文件格式,具有支持构建数据产品的关键特性。
集成和控制
拥有一个开放文件格式对于保持对您数据的所有权至关重要。您不仅希望能够读取、修改和打开您的数据文件,还希望将它们保留在您的云租户中。在 Databricks 数据智能平台上,您可以保持对数据的控制。没有必要将数据文件放入专有格式或将其锁在供应商的云中。查看图 1.4,了解 Delta 如何成为更大生态系统的一部分。

图 1.4 – Delta 内核连接生态系统
Delta 内核引入了一种全新的方法,提供简化的、专注的、可靠的 API,这些 API 抽象了 Delta 协议的复杂性。通过简单地更新内核版本,连接器开发者可以无缝访问最新的 Delta 功能,而无需修改任何代码。
Delta 中的时间旅行版本控制
开放文件格式的自由和灵活性使得它能够与新的和现有的外部工具集成。特别是 Delta Lake,凭借时间旅行版本控制、卓越的速度以及更新和合并更改的能力等特性,为创建数据产品提供了独特的支持。在此背景下,时间旅行指的是查询您数据表不同版本的能力,让您能够回顾在最近更改或转换之前表的状态(见图 1.5)。最明显的用途是在犯错后进行备份,而不是作为安全措施写出多个表的副本。时间旅行的一个可能不那么明显的用途是可重复研究。您可以在不创建数据副本的情况下访问模型在上一周训练时所使用的数据。在整个书中,我们将详细介绍您可以使用的数据智能平台的功能,以促进可重复研究。以下图示展示了如何查询相对于时间戳或版本号的表的前一个版本。

图 1.5 – 查询技术代码示例,用于查看表的前一个版本
Databricks 优化组合的速度
接下来,让我们讨论 Databricks 湖屋架构的速度。2021 年 11 月,Databricks 为数据仓库的黄金标准性能基准设定了新的世界纪录。巴塞罗那计算小组分享了支持这一发现的研究。这一创纪录的速度得益于 Databricks 的引擎(Spark 和 Photon)与 Delta 的结合(参见进一步阅读部分的Databricks Sets Official Data Warehousing Performance Record链接)。
Delta 的额外优势
Delta 的令人印象深刻的特性包括变更数据馈送(CDF)、变更数据捕获(CDC)和模式演变。每个都在支持机器学习的数据转换中扮演着特定的角色。
从 Delta 的 CDF(Change Data Feed,变更数据馈送)功能开始,它正是其名称所暗示的——变化数据的馈送。假设你有一个寻找欺诈行为的模型,该模型需要知道在过去 10 分钟内发生了多少交易请求。每次需要更新账户的值时,重写整个表是不切实际的。在这种情况下,特征值,即过去 10 分钟内发生的交易数量,只有在值发生变化时才需要更新。本例中 CDF 的使用使得更新可以传递给一个在线特征存储;详见第五章和第六章以获取更多详细信息。
最后,让我们谈谈变更数据捕获(CDC),它是数据管理领域的一个颠覆者。与传统的文件系统不同,Delta 中的 CDC 被有意设计来高效地处理数据更新。让我们更深入地了解 CDC,并通过两个实际场景来探索其功能:
-
场景 1 – 无需努力的记录更新:想象一个涉及你的客户拉米(Rami)的场景。他最初在威斯康星州购买商品,但后来搬到了科罗拉多州,并在那里继续购买。在你的记录中,反映拉米在科罗拉多州的新地址至关重要。这正是 Delta 的 CDC(Change Data Capture,变更数据捕获)大放异彩的地方。它无需将拉米视为新客户,就能轻松更新他的客户记录。CDC 擅长无缝地捕获和应用更新,确保数据完整性而无需任何麻烦。
-
场景 2 – 适应不断变化的数据源:现在,考虑一种情况,你的数据源经历意外变化,导致添加了一个包含客户信息的新列。假设这个新列提供了关于客户购买物品颜色的洞察。这是你不想丢失的有价值数据。Delta 的 CDC 结合其模式演变功能,正是解救之道。
在第三章中深入探讨了模式演变,它使 Delta 能够优雅地适应模式变化,而不会造成任何中断。当处理新的数据列时,Delta 能够顺利地整合这些信息,确保你的数据保持最新,同时保留其全部历史背景。这确保了你可以为现在和未来的分析利用有价值的见解。
应用我们的学习方法
这本书以项目为基础。每一章都从概述重要概念和数据智能平台功能开始,为你准备主要活动——应用我们的学习部分。每个应用我们的学习部分都有一个技术要求部分,这样你知道完成相应章节的项目工作需要哪些技术资源,除了你的 Databricks 工作空间和 GitHub 仓库。
技术要求
这里是需要开始使用本书中使用的动手示例所需的技术要求:
-
我们使用 Kaggle 的两个数据集。如果你还没有账户,你需要创建一个。
-
在整本书中,我们将参考 GitHub 中的代码。如果你还没有账户,请创建一个。
了解你的数据
书中包含四个主要项目,这些项目按顺序逐步展开。在每一章后续的章节中,代码将扩展前一章的代码。我们选择这些项目是为了突出不同机器学习项目中的各种数据智能平台功能。具体来说,我们包括将流数据引入你的湖仓架构、预测销售、构建用于计算机视觉的深度学习(DL)模型,以及使用检索增强生成(RAG)技术构建聊天机器人。阅读每个项目的描述,以了解它将涵盖的内容。如果一些概念和功能不熟悉,不要担心!我们将在接下来的章节中解释它们。
项目 – 流式交易
这个第一个项目是为我们将生成的流式交易数据集提供的数据解决方案。交易数据将包括客户 ID 和交易时间等信息,我们将使用这些信息来模拟实时流式交易;请参阅图 1.6中的示例数据。

图 1.6 – 合成流式交易数据的示例
我们希望通过这个项目展示数据智能平台与过去专有数据仓库相比的灵活性,后者在数据摄取方面更为僵化。此外,我们还想突出 Databricks 的重要功能,如Spark Structured Streaming、Auto Loader、模式演变、Delta Live Tables 和湖仓监控。
当我们生成交易时,我们也会根据统计分布生成一个标签(注意,标签是随机的,仅用于学习目的)。这是我们将会预测的标签。我们的旅程包括生成多行 JSON 文件的交易记录,将文件格式化为 Delta 表,为我们的机器学习模型创建流式特征,使用 pyfunc 包裹预处理步骤,并通过工作流部署模型包装器。通过查看 图 1.7 了解我们将如何推进这个项目。


图 1.7 – 流式事务项目的项目流程
这就完成了流式事务项目的解释。接下来,我们将查看预测项目。
项目 – Favorita 销售预测
这是一个典型的预测项目。我们的数据集托管在 Kaggle 网站上(参见 进一步阅读 部分)。我们将使用这些数据构建一个模型,以预测厄瓜多尔特定 Favorita 店面一家商品的总销售额。数据包括训练数据、测试数据和补充数据。本项目将使用 Databricks 的 AutoML 进行数据探索并创建基线模型。通过查看 图 1.8 了解我们将如何推进这个项目。店面销售数据集是一个丰富的时序数据集,我们鼓励您使用您喜欢的时序库在我们的项目框架上构建。


图 1.8 – Favorita 店面销售项目的项目流程
这就完成了预测项目的解释。接下来,我们将查看深度学习项目。
项目 – 多标签图像分类
这是一个使用另一个 Kaggle 数据集的深度学习数据解决方案。我们将使用这些数据集的图像微调一个深度学习模型,使用 PyTorch 和 Lightning 预测相应的标签。我们将实现 MLflow 代码进行实验和模型跟踪,使用 Spark 进行快速训练和 推理,以及使用 Delta 进行数据版本控制。我们将通过创建一个模型包装器来部署模型,类似于我们在流式事务项目中使用的包装器。通过查看 图 1.9 了解我们将如何推进这个项目。


图 1.9 – 多标签图像分类项目的项目流程
这就结束了图像分类项目的解释。接下来,我们将探讨聊天机器人项目。
项目 – 检索增强生成聊天机器人
这个项目是一个 RAG 聊天机器人。我们使用的数据集来自arXiv网站。我们选择了一些关于生成式人工智能对人类和劳动影响的研究文章。我们将下载并将它们存储在第二章中的一个卷中。下载 PDF 文档后,我们将通过分块和标记化过程提取和准备文本,为聊天机器人创建要引用的文档嵌入。我们将使用 Databricks 向量搜索来存储嵌入。然后,我们将使用新的基础模型 API 在检索文本时生成答案。最终的机器人将作为使用Databricks 模型服务的应用程序部署。这个示例允许你从头到尾构建一个聊天机器人!通过查看图 1.10中的项目流程来了解我们将如何进行这个项目。


图 1.10 – 聊天机器人项目的项目流程
四个项目是可以在 Databricks 上实施的动手示例。《Databricks 机器学习实战》基于我们的经验,从机器学习的角度提供了最佳实践和建议,并补充了在线文档。本书中展示的所有代码和解决方案都是在 Databricks 的全版本上开发和测试的。然而,我们理解可访问性很重要。Databricks 数据智能平台还有一个免费的社区版本,使每个人都能在考虑升级之前跟随示例进行到一定程度。
摘要
在本章中,我们向您介绍了《Databricks 机器学习实战》。我们强调,Databricks 数据智能平台的设计考虑了开放性、灵活性和工具自由度,这极大地提高了生产力。此外,我们还向您展示了本书中将占中心地位的项目和相关数据集。
现在你已经对数据智能平台有了基础的了解,是时候迈出下一步了。在接下来的章节中,我们将引导你设置环境,并提供下载项目数据的说明。这将为你准备在这个旅程中即将到来的实际、动手的机器学习体验。
问题
让我们通过以下问题来测试一下我们学到了什么:
-
你将如何使用这本书?你计划从头到尾阅读,还是挑选某些章节?你已经选择了感兴趣的章节吗?
-
我们讨论了为什么在建模中保持透明度对于成功至关重要。Databricks 的自动机器学习(AutoML)的玻璃盒方法是如何支持这一点的?
-
Databricks 开发了一种新的方式来统一开放数据格式,称为 UniForm。UniForm 统一了哪些数据格式?
-
Delta 是湖屋架构的基础。使用 Delta 的一个好处是什么?
-
在 Databricks 中,使用 Delta 文件格式进行大规模数据处理相比简单的 Parquet 文件有哪些主要优势?
答案
在思考了这些问题之后,比较一下您的答案和我们的答案:
-
我们无法回答这个问题,但我们希望您很快就能学到在工作中可以用到的东西!
-
玻璃盒方法通过提供实验中每次运行的代码和最佳运行,支持透明度,从而实现可重用性和可重复性。
-
Apache Iceberg、Apache Hudi 和 Linux Foundation Delta Lake(Delta 的开源/未管理版本)。
-
有几个。以下是一些:
-
开放协议(无供应商锁定)
-
速度
-
数据变更捕获
-
时间旅行
-
-
虽然 Parquet 也提供列式存储并具有高效的读写操作,但其缺乏 ACID 事务能力,这使得 Delta Lake 与之区分开来。
进一步阅读
在本章中,我们介绍了关键技术。查看这些资源深入了解您最感兴趣的领域:
-
YouTube 视频 - Databricks 数据智能平台入门:
youtu.be/E885Ld3N2As?si=1NPg85phVH8RhayO -
数据仓库之父比尔·英蒙(Bill Inmon)的5 步成功构建数据湖屋:
www.databricks.com/resources/ebook/building-the-data-lakehouse -
Delta Lake: Up & Running by O’Reilly:
www.databricks.com/resources/ebook/delta-lake-running-oreilly -
Delta Lake: The Definitive Guide:
www.oreilly.com/library/view/delta-lake-the/9781098151935/ -
比较 Apache Spark 和 Databricks:
www.databricks.com/spark/comparing-databricks-to-apache-spark -
Databricks MLflow:
www.databricks.com/product/managed-mlflow -
Databricks 社区版 FAQ:
www.databricks.com/product/faq/community-edition#:~:text=What%20is%20the%20difference%20between,ODBC%20integrations%20for%20BI%20analysis -
Delta 2.0 - 你的数据湖屋基础是 开放的:
delta.io/blog/2022-08-02-delta-2-0-the-foundation-of-your-data-lake-is-open/ -
Delta Lake 集成:
delta.io/integrations/ -
*Delta 与 Iceberg:
databeans-blogs.medium.com/delta-vs-iceberg-performance-as-a-decisive-criteria-add7bcdde03d -
UniForm:
www.databricks.com/blog/delta-uniform-universal-format-lakehouse-interoperability -
Delta 内核:简化为 Delta 构建连接器的:
www.databricks.com/dataaisummit/session/delta-kernel-simplifying-building-connectors-delta/ -
Databricks 社区 网站:
community.cloud.databricks.com -
播客:与 Denny Lee 的 Delta Lake 讨论:
open.spotify.com/show/6YvPDkILtWfnJNTzJ9HsmW?si=214eb7d808d84aa4 -
Databricks 创下官方数据仓库性能 记录:
www.databricks.com/blog/2021/11/02/databricks-sets-official-data-warehousing-performance-record.html -
LightGBM:
github.com/microsoft/LightGBMlightgbm.readthedocs.io/en/latest/ -
Kaggle | 商店 销售:
www.kaggle.com/competitions/store-sales-time-series-forecasting/overview -
Kaggle | 多标签图像 分类:
www.kaggle.com/datasets/meherunnesashraboni/multi-label-image-classification-dataset -
存储销售 - 时间序列 预测:Kaggle.com/competitions/store-sales-time-series-forecasting/overview
-
arXiv 网站:
arxiv.org
第二章:设计 Databricks:第一天
“设计不仅仅是看起来和感觉如何。设计是如何运作的。”
- 史蒂夫·乔布斯
本章将介绍工程师、数据科学家以及类似角色应该了解的概念和主题,以便在 Databricks 数据智能平台上取得成功。在设置数据和 AI 平台时,以我们为例,Databricks,总有最佳实践需要遵循。我们在本章中分享这些最佳实践,以便您更好地理解设置选项及其影响;这些可能是影响整个数据产品工作流程的战略决策,也可能是简单的偏好问题。我们首先解释 Databricks 的一般架构和关键术语,然后介绍平台设置期间需要做出的最重要的决策,并以代码示例和配置来下载示例项目的数据。我们还在本章中介绍了各种平台功能和组件,这些将在本书的其余部分进行更详细的介绍。以下是本章中将学习的内容:
这是本章中将学习的内容:
-
规划您的平台
-
定义工作区
-
选择元数据存储
-
讨论数据准备
-
计划创建特征
-
Databricks 中的建模
-
应用学习
规划您的平台
本节涵盖了在 DI 平台设置前后需要讨论的主题。数据团队的角色通常决定了平台设置。Databricks 的理想属性之一是其技术栈统一,这使得团队设置和协作更加直接。数据团队的报告结构通常决定了角色结束和开始的地方,而不是实际的数据产品工作流程。幸运的是,我们不必担心,因为 DI 平台服务于数据工程师、科学家和分析人员。
在图 2.1中,您可以查看端到端的湖屋架构以及 Databricks 中的组件。

图 2.1 – 湖屋架构概述以及 Databricks DI 平台如何适应这一范式
DI 平台由一个或多个 Databricks 账户组成。大多数情况下,公司只有一个账户。然而,在某些情况下,公司需要额外的环境隔离,并为开发、预生产和生产设置单独的账户是一个选择。关于多个账户用于隔离级别的讨论超出了本书的范围,但如果您有疑问或想了解更多信息,请查看进一步阅读中的资源。

图 2.2 – 环境隔离选项的视觉表示
我们使用不同的目录来分离我们的环境。本书的大部分项目工作都使用ml_in_action目录。对于某些模型的生成版本,我们使用ml_in_prod目录。设置多个工作区是另一种分离环境的方法。我们建议使用文档和您的公司政策来指导您的隔离设置。让我们继续讨论在 Databricks 环境中工作区究竟是什么。
定义工作区
重要的是要知道 Databricks 使用“工作区”一词来指代两个不同的组件:Databricks 的一个实例(意味着您通过唯一的 URL 地址访问的托管 Databricks 部署)以及访问您的工作成果(如笔记本、查询和仪表板)的文件夹环境。
让我们逐一了解这两个组件:
-
工作区作为一个实例:一个 Databricks 账户可以连接多个工作区,这意味着 DI 平台的实例已部署,通常可以通过浏览器访问,如前所述,但也可以通过 SDK 或 REST API 访问。
-
工作区文件夹用于存储他们的 MLFlow 实验或 Terraform 状态,以便进行管道部署。您还可以在您的个人和项目文件夹中创建和存储笔记本,而不在源代码控制之外。
我们现在对工作区有了更清晰的理解。现在让我们讨论为什么我们选择Unity Catalog(UC)作为我们首选的元数据存储。
选择元数据存储
元数据存储是一个存储数据平台元数据的系统,可以将其视为对象的顶层容器。它注册有关数据库、表、视图、用户定义函数(UDFs)和其他数据资产的各种信息。元数据包括诸如存储位置和每个资产访问权限的详细信息。
DI 平台中本机提供两种类型的元数据存储:Unity Catalog(UC)和Hive Metastore(HMS)。UC 由一个包含目录、数据库(也称为模式)和表名的三级命名空间组成。相比之下,HMS 只使用一个包含数据库和表名的两级命名空间。元数据存储对于您的 Databricks 工作区实例是必需的,因为这是组织和控制数据访问的组件。选择正确的元数据存储是您 DI 平台之旅的早期决策之一,我们建议使用 Unity Catalog。让我们谈谈为什么。
注意在图 2.3中,您可以拥有多个分配给同一元数据存储的工作区。访问控制和用户管理的范围是账户级别,如图所示。一个 UC 元数据存储,一组目录,范围在一个区域,每个区域恰好有一个元数据存储。在区域内,您可以轻松共享数据、特征、卷访问、函数和模型。

图 2.3 – 具有多个工作区的 Unity Catalog 设计
Unity Catalog 不仅仅是数据资产的一组。UC 还跟踪谁访问了资产,这使得审计变得简单。使用 UC 允许公司轻松管理权限和确保数据及对象的安全,同时能够在不同的工作区之间共享它们。在环境之间安全共享是为什么我们推荐使用 UC 元数据存储的原因之一。
HMS 设计比 UC 更少集中化。例如,从历史上看,工作区作为数据和代码隔离被创建,这意味着有单独的工作区用于不同的隔离级别。这种设计通常需要在开发、测试和生成工作区之外,还有一个集中的模型注册表工作区。如果不使用 UC,每个工作区都需要自己的 HMS 和用户组管理。相比之下,UC 在账户级别而不是单个工作区级别管理所有资产;参见图 2.3、图 2.4和进一步阅读。集中的治理模型提供了更无缝地集成多个工作区的能力。

图 2.4 – UC 管理目录下的所有资产,包括数据库、表、卷、函数和模型
在决定您的元数据存储时,不必是一个永久的决定。然而,稍后迁移可能会变得头疼。UC 持续改进并与新的 Databricks 功能集成。选择 UC 而不是 HMS 的原因列表持续增长,我们的建议是从 UC 开始并坚持使用 UC。
要确定 Unity Catalog 是否适合您和您的公司,您可以在进一步阅读中查看选择 UC 的限制列表。随着 UC 在功能上的持续扩展,它是未来的道路。特别是对于机器学习,它与特征工程客户端和新的模型注册表集成。使用 UC 模型注册表进行模型共享和管理更简单。我们将在第 5、6 和 7 章中详细介绍 Unity Catalog 中的模型注册表和 Databricks 特征工程客户端,但如果您现在就好奇并渴望了解更多,您可以在进一步阅读部分查看“在 Unity Catalog 中管理模型生命周期”。鉴于使用 UC 的理由不断增多,本书中的所有项目代码都将使用 UC。
定义数据存储的位置和云对象存储
所有数据产品都始于数据,因此我们如何使数据对数据团队可访问是另一个重要的早期设计选择。Databricks 是一个基于云的平台,可以连接到云对象存储 – Azure Data Lake Storage (ADLS), Amazon Simple Storage Service (S3), 或 Google Cloud Storage (GCS)。计算和存储是分离的。Databricks 负责计算;数据存储在云对象存储中。
最初,数据必须在 DI 平台被利用之前存储在云对象存储中。现在,查询联邦允许客户无论数据存储在哪里都可以查询他们的数据(请参阅文档了解任何可能的限制),无需首先担心从远程系统进行摄取和数据工程。然而,这是内存中的数据,而不是持久数据。您可以通过多种方式将数据存放在云存储中。有许多文档资源和外部工具可用于在云存储中实际存放数据。这些可能取决于您选择的云服务提供商。尽管存储数据在您的云存储中是最佳实践,但使用Databricks 文件系统(DBFS)来存储本书示例项目中的数据也是可能的。
DBFS 是由 Databricks 提供的共享文件系统,所有给定工作区的用户都可以访问。存储在 DBFS 中的任何数据都可能对所有用户可访问,无论他们的组、角色或权限如何。因此,只有您愿意在组织内公开共享的非敏感和非生产数据才应该存放在 DBFS 中。非敏感数据的例子包括公开可用的Kaggle数据集。正是由于缺乏治理,我们建议将数据存储在 Databricks 卷中,在那里您可以应用治理。我们将在本章的最后部分更详细地介绍卷。
当涉及到云存储时,结构化数据的最佳格式几乎总是 Delta,我们在第一章中详细讨论了这一点。当一个表以 Delta 格式存储时,我们将其称为 Delta 表。您可以选择将表设置为“管理”或“外部”表。在这本书中我们使用这两种类型的表(当需要时,选择是合理的)。请参阅进一步阅读资源,了解更多关于两种类型表的信息。
讨论源控制
是否使用源控制通常不是问题。问题是某人应该如何使用它?Databricks 有一些功能可以帮助源控制。
第一项是笔记本中内置的版本历史记录。每个笔记本的更改历史在提交到远程仓库(使用 Git)之前就被跟踪了。版本跟踪的好处在于我们并不总是准备好进行 Git 提交,但仍然想要跟踪进度和协作。如果您不小心将某人的代码拉入您的工作远程分支,并且忘记在之前推送您的代码,这也会是一个变革性的变化。笔记本的历史记录将保留您的编辑副本,这样您就可以简单地回滚时间并恢复所有工作!
第二个特点是轻松将工作空间中的笔记本和文件连接到远程 Git 仓库。历史上,将 Jupyter 笔记本保存到远程仓库对于代码审查、共享和差异比较来说是一个技术噩梦。Databricks 代码仓库集成允许 Databricks 笔记本包含多种语言(Python、Scala、SQL)并像典型的 Python 文件一样跟踪它们。这种将笔记本作为标准文件在源中跟踪的能力,对于想要审查笔记本的数据工程师和科学家来说是一个改进,与之前将文件转换为 Python 并丢失所有输出和图像相比。每次保存笔记本时自动将笔记本保存为常规 Python 文件的钩子设置的日子已经过去了。
当然,你可以存储标准文件格式,如 markdown、分隔符分隔、JSON 或 YML,以实现整个可重复性方法。请注意,除非是测试用的数据样本,否则我们不推荐在仓库中保留数据。
在一个仓库中,团队如何定义每个项目的预期文件夹结构通常不如该结构的持续使用重要。然而,定义你的项目结构仍然很重要。我们建议阅读《MLOps 大全书》(Joseph Bradley,Rafi Kurlansik,Matthew Thomson 和 Niall Turbitt,2023,《MLOps 大全书,第二版》,www.databricks.com/resources/ebook/the-big-book-of-mlops)以确定最适合你团队或组织的结构。正如我们将在未来的章节中看到,MLflow 和仓库对于可重复研究至关重要。在数据科学和机器学习的特定领域,我们希望确保模型和实验的可重复性。
讨论数据准备
通常,任何数据科学项目的第一步是探索和准备数据。我们将这个过程称为根据 Medallion 架构方法将数据从“Bronze”层移动到“Silver”层。你可能认为这种类型的数据转换仅是数据工程任务,但它对于数据科学和机器学习也是至关重要的。
如果你不太熟悉这种架构术语,Medallion 架构是一种用于在仓库中逻辑组织数据的数据设计模式。这种架构也通常被称为“多跳”架构。它的目标是随着数据流过每一层而逐步和渐进地改进数据的结构和质量。Medallion 架构有三个层次:Bronze、Silver 和 Gold,如下所示:
-
Bronze层是原始数据层。它包含从源系统摄取的所有原始、未处理的数据。这些数据仍需要被清理或转换。
-
银层是经过验证的数据层。它包含经过清理且已接受各种验证和转换步骤的数据。这些数据可用于分析和建模。
-
金层是增强数据层。它是最高级别,包含添加了额外信息的数据,如商业智能指标和关键绩效指标(KPIs),以满足业务用户的需求。
Medallion 架构是一种灵活且可定制的架构,可以满足每个组织的特定需求。Medallion 架构与 Data Mesh 概念兼容。Data Mesh 是一种架构和组织范式,旨在确保数据的价值。Lakehouse 和 Data Mesh 是互补的范式。参见进一步阅读部分,了解如何利用 DI 平台利用数据网格的博客文章。这种分布式数据架构使组织能够通过使组织中的每个人都能访问和使用数据来释放数据的价值。
通信和协作对于数据准备过程至关重要。这一步骤涉及识别和纠正错误、填补缺失值以及解决数据中的不一致性。你所采取的行动应该作为团队讨论并记录下来。当跨数据团队协作时,这一点尤为重要,因为数据工程师和数据科学家往往对数据应该如何准备有不同的看法。例如,我们见过工程师在一个列中用零插补所有缺失值的情况。这种合理化是有道理的;列中已经有很多零了,这使得关键绩效指标(KPIs)的值正确显示。然而,从建模的角度来看,缺失数据与零不同,特别是如果数据集中已经存在零的话。用零替换空值的方法并不一定是不正确的;它只需要与数据下游的消费者进行讨论。一个有用的沟通工具是 Databricks 目录 UI 中的列标记功能。参见图 2.5的示例:

图 2.5 – 在目录中使用标记的示例,以向所有表用户传达对列进行的转换
这种不正确的插补方法的实现也作为一个想要回溯和重新处理历史的例子。幸运的是,使用 Medallion 架构方法论是一种救赎。在之前提到的情况下,所选的插补方法只会出现在银和金数据层中。同时,青铜层仍然包含原始的原始数据,因此真相来源并未丢失,重新处理是可能的。
Databricks 平台提高生产力和协作的一种方式是支持笔记本的实时协作功能。这个功能允许两个人或更多人同时查看和编辑一个笔记本。在疫情期间,能够在虚拟上结对编程对许多人来说是一个救星。我们非常欣赏那些在我们职业生涯的大部分时间里远程工作的人。与通过视频通话共享代码相比,笔记本的协作编辑要容易得多。虽然有许多代码审查的选项,但历史上,在笔记本中审查代码一直很困难,尤其是在将笔记本提交到源控制时。
完成转换后,使用笔记本中的 Markdown 进行文档编写变得容易。即使结果笔记本本身并未指定用于生产 ETL,但记录数据转换的如何和为什么对所有下游用户来说都很重要。要了解更多关于 Databricks 笔记本的信息,请参阅进一步阅读中的文档。
计划创建功能
数据工程师可能从银表构建金表以供业务使用。同时,数据科学家正在从相同的银表中构建特征以用于模型。如果我们不小心,两个没有沟通的独立工作者可能会创建相同指标的不同的版本。在架构你的统一 DI 平台时,务必考虑可重用性和可维护性。因此,对于功能而言,我们推荐功能即代码的方法。功能即代码是指软件开发实践一切皆代码,重点是创建一个可重用代码的仓库来定义特征,而不是将特征存储在表中。
你可以通过多种方式实现功能即代码。最初,我们主要关注函数的可重用性。你可以将你在多个笔记本或脚本中执行的功能放置在仓库根目录下的一个文件夹中。在应用我们的学习部分,你会看到即使不是在计算特征本身,我们也会在这里存储函数。我们称之为 utils。在整个示例项目中,你将引用mlia_utils笔记本。
你可以在 GitHub 仓库的根目录中找到mlia_utils函数(github.com/PacktPublishing/Databricks-Lakehouse-ML-In-Action)。我们在应用我们的学习部分中介绍了将 GitHub 仓库拉入 Databricks 的过程。在其中,你会找到包含我们将用于项目的有用函数的 Python 文件。最佳实践是保存、共享和跟踪函数,以确保我们计算出的指标和特征是一致的。注意,空的__init__.py文件也在utils文件夹中。拥有一个__init__.py文件是必需的。有了这种结构,我们可以将所有函数作为导入使用,例如,从mlia_utils.rag_funcs导入extract_doc_text。
特征即代码不仅是一种通过重用函数来减少重复工作的方法。它也是一种确保一致业务指标的好方法。例如,在线广告通常对不同类型的收入有复杂的计算。因此,如果其他人或团队以不同的方式计算业务关键指标,将很难确定真正的指标值。相反,你通常可以通过提供经高管批准的函数来避免这种混淆。我们将在 第五章 和 第六章 中再次讨论这个问题。除了特征集中存储且更容易找到之外,Databricks 还提供了轻松记录你的数据资产的方法。
创建一个需要团队记录表格和函数描述的业务流程,可以使当前和以往的努力更容易被发现。在 Databricks 目录 UI 中,你应该会看到 AI 生成 的建议来填写你的表格和列描述,这样你就不必从头开始。记录在数据表上执行转换的另一种好方法是使用标签。标签可以帮助进行文档和沟通。回想一下缺失数据被插补的例子(图 2**.5)。
更具体地关注 ML 特征,你将学习如何存储和提供特征函数以简化你的最终部署过程。你将创建一个按需特征函数并在你的模型中使用它。我们还将向你展示如何利用保存的特征表创建训练集。如果你想立即跳过,请参阅 第五章,其中我们涵盖了按需特征函数、特征查找、同步到在线商店以及 Databricks 特征工程客户端等主题。
Databricks 中的建模
在创建并存储为特征表的特征之后,我们创建训练集并专注于模型训练。我们将讨论如何利用 Databricks 促进模型生命周期的建模(第六章)。在第 第七章 中,我们将讨论 Unity 目录注册表及其如何用于跟踪关联实验的大量信息,包括模型血缘等细节。你可以在每个阶段注册多个版本的模型,并可以为这些不同版本提供别名,例如 冠军 和 挑战者,或者更具体的别名,用于 A/B 测试中的版本 A 和 B。参见 图 2**.6 中的别名示例。

图 2.6 – 用户可以为 A/B 测试或多臂老丨虎丨机游戏为模型指定特定名称进行别名设置
在第七章中,我们演示了如何触发测试脚本以在人工审查之前测试每个模型。当持续且有意地使用时,测试模型是一种提高将模型/代码过渡到生产环境时间的有效实践。我们建议定义成功通过隔离环境(从开发到预生产再到生产)的模型/代码的准则。明确定义的环境是使您能够跨所有模型创建清晰和一致模型质量预期的实践之一。务必查阅《MLOps 大全》以了解隔离和模型提升的最佳实践。无论您的环境在哪里,将日志记录纳入模型实验都是有益的。
我们在机器学习上下文中讨论日志记录,而不是软件开发意义上的日志记录。机器学习中的日志记录侧重于可重复研究,也称为实验跟踪。跟踪以下内容是常见做法:
-
训练模型所使用的输入数据
-
训练模型所使用的参数
-
模型在训练和推理过程中的准确性和速度性能
-
训练和推理过程中发生的错误
-
模型的运行环境
当使用 MLflow 时,您可以使用一个名为自动记录或自动记录的强大功能。自动记录非常出色,因为它使得跟踪机器学习实验的参数、指标和工件变得容易,无需显式指令。
注意
自动记录仅跟踪 MLflow 支持的风味。不支持自定义 pyfunc 模型。更多信息,请参阅进一步阅读。
MLflow 自动记录在单个实验中记录每个运行的参数值和模型。每次您训练和评估模型时,MLflow 都会记录您的标准指标和参数。如果您有与模型一起跟踪的自定义指标,也可以轻松添加。我们在第六章中演示了跟踪自定义指标,当时我们记录了流式事务模型的参数。
管理员可以在工作空间级别为所有附加到交互式集群的笔记本启用自动记录。在集群级别,您可以将 spark.databricks.mlflow.autologging.enabled=true 添加到集群配置的高级部分以在集群范围内开启自动记录。在笔记本范围内启用自动记录虽然不常见但可行,通过在笔记本中的一个 Python 单元中添加 mlflow.autolog() 实现。务必检查自动记录支持的建模风味列表。
默认情况下,MLflow 将跟踪项保存在 DBFS 中的托管文件夹中(未来将在 UC 中)。您也可以设置 artifact_location 以指向卷路径,这是我们示例项目中所做的。您还可以选择将位置设置为另一个云存储位置,尽管这样做将消除在 MLflow UI 中查看实验的能力。
The MLflow UI makes it incredibly easy to compare each trail; see Figures 2.7 and 2.8.

图 2.7 – 使用 MLflow UI 比较实验运行
There are numerous options for visualizing the results of experiments tracked using MLflow.

图 2.8 – 在 MLflow UI 中图形化比较参数和模型性能
我们已经探讨了如何使用 MLflow UI 比较实验中的参数和模型性能。接下来,我们将看看如何使用模型监控(Lakehouse 监控)来跟踪模型随时间的变化性能。
监控数据和模型
当我们思考模型监控及其实现方式时,它就不再仅仅是关于模型本身,而是更多地关注模型的输入和输出。因此,Databricks Lakehouse 监控专注于监控模型的输入和输出,这仅仅是数据。表指标的计算是在后台使用无服务器计算完成的,或者正如我们喜欢称之为的,托管计算。完全托管的计算抽象掉了复杂性和优化,因此用户只需关注要监控哪些表,即主表,而不是如何操作。Lakehouse 监控目前处于公开预览阶段,这意味着并非所有信息都准备好发布。有关此功能的最新信息,请查看 Lakehouse 监控产品页面。我们在第四章和第七章中演示了如何使用 Lakehouse 监控。
到目前为止,我们已经涉及了许多主题,从设置 Databricks 数据智能平台时的早期设计决策,到本书余下部分我们将涉及的关键主题。现在让我们深入到示例项目中。准备好在您自己的 Databricks 工作区中跟随操作,您将在设置工作区时进行操作。
应用我们的学习
本章的“应用我们的学习”部分专注于设置您的 Databricks 工作区,使其为我们将要工作的每个项目做好准备。我们还将介绍如何在 Kaggle 上设置,以便您可以下载本书余下部分我们将使用的数据集。让我们开始吧!
技术要求
在我们开始设置工作区之前,请查看完成本章动手实践所需的技术要求:
-
我们使用 Python 包,
opendatasets,从 Kaggle API 轻松下载所需数据。 -
我们使用 Databricks Labs Python 库,
dbldatagen,来生成合成数据。 -
要使用 Kaggle API,您必须下载您的凭证文件,
kaggle.json。 -
GitHub 账户对于连接 Databricks 和本书的代码仓库(
github.com/PacktPublishing/Databricks-ML-In-Action)很有帮助。除了 GitHub 账户外,将本书仓库分叉到您的 GitHub 账户也是理想的。您会看到每个章节都有一个文件夹,每个项目都在章节下有文件夹。在整个项目工作中,我们将通过名称引用笔记本。 -
我们将使用 Databricks Secrets API 来保存 Kaggle 和 OpenAI 凭证。Secrets API 需要使用 Databricks CLI。我们将逐步介绍此设置。但是,您需要在配置步骤中自己创建一个个人访问令牌(PAT):
docs.databricks.com/en/dev-tools/auth/pat.html -
我们使用的计算集群如下(它们根据您的数据云略有不同):
- 单节点 CPU 配置

图 2.9 – 单节点 CPU 集群配置,DBR ML 14.2
这将适用于本书中的大多数工作负载。
设置您的开发环境
如前所述,本节中讨论的工作空间指的是部署实例。在这里,我们将讨论工作空间设置建议、项目设置文件以及本书中使用的每个数据集的下载说明。
首次部署工作空间有详细的文档说明。如果您还没有 Databricks 账户和已部署的工作空间,那么您有几个起点。一种方法是进入您的云账户并通过市场激活 Databricks。另一种方法是直接从 Databricks 网站开始。对于更高级的用户,考虑使用 Terraform。鉴于大量的文档和不断变化的技术世界,我们将激活工作空间的练习留给您自己。
一旦我们部署了工作空间,我们就可以开始设置它。通常,我们从用户组和治理开始。设置 Unity Catalog 的体验经常更新以简化。因此,我们建议您观看最新的视频文档了解如何进行(见进一步阅读)。无论使用平台的数据角色如何,过程都是相同的。请确保在继续之前完成元存储和治理设置。
Kaggle 设置
您需要一个 Kaggle 账户来下载我们将要使用的 Kaggle 数据集,这些数据集需要 API 令牌进行身份验证。存在官方的 Kaggle API,但还有许多其他方式可以连接到 Kaggle 下载数据以及与 Kaggle 网站交互。所有方法都需要从 Kaggle 网站下载您的 API 凭证文件,kaggle.json。在下载数据之前,您需要使您的凭证可访问。以下有三种实现此目的的方法:
-
将
kaggle.json文件添加到您的项目文件夹。如果您选择这样做,请注意,您的凭据对其他人可见,即使只有管理员。此外,将kaggle.json添加到您的.gitignore文件中,以防止将凭据提交到仓库,并确保您不会将凭据提交到 Git 仓库。 -
.gitignore文件以防止将凭据提交到仓库。然而,根据您的角色,您可能无法控制删除其他用户的访问权限。此外,通常管理员可以查看所有文件。

图 2.10 – 将用户凭据传递给笔记本
- 选项 3:使用 Databricks 机密存储和检索您的用户名和令牌,以实现最佳安全性,如图 2.11所示。这是我们用于下载图片的方法。

图 2.11 – 使用机密存储和检索您的用户名和令牌
此代码位于 global_setup.py 中,但您也可以将其放在笔记本本身中
- 使用
o``pendatasets库在下载时粘贴您的凭据。这是一种安全的数据下载方式,因此我们使用 Favorita 销售数据来演示这一点。
我们将在稍后介绍 global-setup.py。文件的最后一部分是设置您的 Kaggle 凭据。我们建议设置一个包含凭据的秘密范围。一旦您有一个集群运行,我们将向您展示如何设置,因此无需四处跳跃。现在,只需下载您的 Kaggle 凭据即可。
设置我们的 GitHub 仓库
第一件事是从 GitHub 仓库拉取您将在整本书中使用的代码。

](https://github.com/OpenDocCN/freelearn-ml-zh/raw/master/docs/dtbrk-ml-act/img/B16865_02_12.jpg)
图 2.12 – 设置 Git 仓库:工作区 > 仓库 > 主文件夹 > 添加 > 仓库
导航到在“应用我们的学习”部分下的“技术要求”部分中提到的书的 GitHub 仓库分支。您可以将 HTTPS 链接复制并粘贴到添加仓库屏幕的 URL 部分,如图 2.12所示。接下来,您将链接您的 GitHub 账户。如果您不确定如何操作,请遵循进一步阅读部分中链接的文档,标题为关于个人访问令牌和设置 Databricks 仓库。一旦您的仓库准备就绪,如果还没有人这样做,您就可以创建一个集群。
创建计算
我们在 技术要求 部分提供了本项目使用的集群配置。如果您愿意,可以使用相同的配置。创建新的集群配置时,有多种选项可供选择。对于新用户来说,这可能会显得复杂,但在尝试选择正确的配置时请保持冷静。我们强烈推荐在 进一步阅读 链接中的 集群配置最佳实践 作为指导,特别是如果您负责为一或多个团队设置计算资源。让我们讨论一些与机器学习和本书相关的计算选项:
-
多节点与单节点:多节点非常适合分布式项目(例如 Spark)。单节点适用于在驱动程序上执行的项目或工作负载(例如 scikit-learn 或 pandas)。
-
访问模式:某些集群配置支持 Unity Catalog,而有些则不支持。为本书中的项目选择支持 UC 的集群。
-
(
pyenv)。您将在集群级别和几个项目笔记本中安装库。您可以在 图 2.13 中的 库 选项卡中看到。只需点击 安装新库 即可安装新库。

图 2.13 – 向《机器学习实战》(MLIA)集群配置中添加库
这是安装所需库的理想时机。通过 PyPI opendatasets、dbldatagen、databricks-feature-engineering 和 mlflow-skinny[databricks]>=2.5.0 进行安装。这些库在本书的多个笔记本中都会用到。
-
Photon 加速:Photon 是一个加速引擎,可以加快 ETL 和 SQL 工作负载。目前,Photon 对于标准机器学习建模并没有优势。
-
虚拟机类型:有众多虚拟机可供选择。您可以从下拉列表中选择按家族分类的虚拟机。如果您需要更多澄清或刚开始,可以从 通用目的 组的虚拟机开始。
-
最小和最大工作节点数:一般建议从少量最大工作节点开始,随着工作负载的增加逐渐增加工作节点数。请记住,您的集群会自动为您进行扩展。然而,我们仍然建议对于仅计算密集型示例(例如多标签图像分类深度学习项目中的某些笔记本),只从小规模开始,并逐步扩展。
您现在已设置好开发环境。您可以为代码中的安全使用锁定凭证。
设置 Databricks CLI 和密钥
Databricks CLI 是 Databricks 的命令行界面。我们建议使用你的集群的 Web 终端来安装 Databricks CLI 以及创建 Databricks 秘密。正如我们在本章前面提到的,有其他选项可以访问 Kaggle 数据集,但我们在本节中引导你设置秘密。请参阅进一步阅读中的文档以获取有关 CLI、安装、使用和秘密的更多详细信息。
-
前往你在上一节中设置的计算集群的应用标签页。你可以参考图 2.13来查看应用标签的位置。应用仅在集群运行时可用,因此最初可能为灰色。你必须启动你的集群才能继续。
-
选择 Web 终端。
-
安装 CLI 的最新版本。
curl -fsSL https://raw.githubusercontent.com/databricks/setup-cli/main/install.sh | sudo sh -
检查你的 Databricks 版本,确保它大于
0.2。我们必须指向 curl 安装的位置的更新版本。/usr/local/bin/databricks-v -
接下来,你需要配置连接。你需要你的 PAT 来完成此操作:
/usr/local/bin/databricks configure -
为存储与本书相关的凭据创建一个秘密作用域:
/usr/local/bin/databricks secrets create-scope "machine-learning-in-action" -
创建一个秘密来存储你的 Kaggle 用户名:
/usr/local/bin/databricks secrets put-secret --json '{"scope": "machine-learning-in-action", "key": "kaggle_username", "string_value": "readers-username" }' -
创建一个秘密来存储你的 Kaggle API 密钥:
/usr/local/bin/databricks secrets put-secret --json '{ "scope": "machine-learning-in-action", "key": "kaggle_key", "string_value": "readers-api-key" }' -
最后,列出你的秘密以确保一切按预期工作:
/usr/local/bin/databricks secrets list-secrets "machine-learning-in-action"
在第八章中,我们将创建另一个作用域来存储 OpenAI API 密钥,但到目前为止我们只需要 Kaggle 凭据。现在我们已经设置了秘密,让我们准备好我们的代码库!
设置你的代码库
我们使用设置文件来帮助保持多个项目笔记本中变量的一致性。每次你使用魔法命令%run运行项目笔记本时,你都会运行设置文件。这个命令将所有内容带入你的笔记本会话的内存中。global-setup.py文件有许多组件。让我们逐一介绍每个部分。你可以自由地编辑文件以适应你的需求。
注意
你可能会收到一个错误消息:py4j.security.Py4JSecurityException: Method public scala.collection.immutable.Map com.databricks.backend.common.rpc.CommandContext.tags() is not whitelisted on class class com.databricks.backend.common.rpc.CommandContext
这是因为你在一个共享的计算集群上。你可以简单地将current_user硬编码到你的用户名中。
通过小部件传递变量
小部件将变量传递到笔记本中,类似于命令行参数将变量传递到 Python 脚本中。图 2.14中的代码块创建了所需的小部件,用于使用 Databricks 实用工具或dbutils将Run命令中的变量传递到global-setup.py文件。你可以在进一步阅读中的 Databricks 实用工具文档中了解更多关于dbutils的功能。这些小部件创建、传递和访问参数。参数的顺序是变量名、默认值和详细名称。


图 2.14 – 创建接受笔记本特定变量的小部件
您可以通过在笔记本顶部添加带有适当参数的单行单元格来在运行文件时传递每个变量,如图图 2.15所示。

图 2.15 – 在我们的全局设置文件中运行项目特定变量
运行global-setup.py将脚本中定义的所有变量保存在内存中,以便于引用。
检查兼容性
接下来,在global-setup.py中,我们运行代码库和笔记本附加的集群之间的兼容性检查。
兼容性代码块检查以下内容:
-
一个项目名称被提交为一个变量。
-
集群配置了 ML 运行时并满足最低版本要求。为了确保代码中的所有功能都在使用的运行时中可用,我们设置了最低版本。
一旦所有检查都通过,我们分配用户和路径。
设置默认目录和项目特定数据库
本书提供了使用 Unity Catalog 目录的代码。您的默认目录基于您的环境设置。如果您没有设置环境或将其设置为dev,则目录名为ml_in_action。当环境为prod时,目录为ml_in_prod。数据库的默认名称始终是项目名称。但是,如果您希望提供不同的名称,可以通过输入数据库名称的项目变量来实现。

图 2.16 – 使用定义的变量通过重试设置默认值
我们要确保目录和数据库设置为笔记本的默认值。偶尔,在并行执行时,此命令在初始化过程中可能会失败;因此,我们添加了一些重试来解决这个问题,如图 2**.16所示。
授予权限
现在我们已经设置了目录和数据库的默认值,我们可以授予权限。


图 2.17 – 授予目录和数据库权限
我们授予account users组权限。如果您不希望将您的资产提供给其他人,请删除此权限或将其注释掉。
重要提示
在授予权限时,务必在您的组名或电子邮件地址周围使用勾号。如果您使用单引号,您将收到错误消息。
目录和数据库已准备好用于表格。然而,我们用于机器学习的并非所有数据都进入表格。对于其他数据、文件和对象,我们有卷。
设置卷
卷是云对象存储的视图。我们创建特定于项目的卷。使用它们进行基于路径的访问,以访问结构化或非结构化数据。卷位于目录下的数据库中,用于管理和提供对数据文件的访问。你可以使用 GRANT 语句来管理对卷的访问。卷提供可扩展的基于文件的存储,而不牺牲治理。我们通常在机器学习中使用非结构化、半结构化或非表格数据。图像是我们将在多标签图像分类项目中使用的非结构化、非表格数据的良好示例。为了处理这些图像,多标签图像分类项目使用卷。


图 2.18 – EndpointApiClient 类
开始项目
我们已经规划了我们的平台并设置了我们的工作区环境。接下来,让我们逐一处理每个项目。在 GitHub 中,你会看到每个章节都有一个包含对应每个项目文件夹的文件夹。当我们按名称引用笔记本时,我们假设你处于适当的章节和项目文件夹中。例如,本章的第一个笔记本是:
Chapter 2: Designing Databricks: Day One/
Project: Favorita Store Sales - TimeSeries Forecasting/
CH2-01-Downloading_Sales_Forecast_Data
我们只通过文件名本身来引用笔记本,CH2-01-Downloading_Sales_Forecast_Data。让我们开始第一个项目。
项目:Favorita 店铺销售 – 时间序列预测
回想一下 第一章,我们使用 Kaggle 提供的数据集来预测销售。在本章中,我们从 Kaggle 网站下载我们的数据。为了在你的工作区中跟随,请打开以下笔记本:
CH2-01-Downloading_Sales_Forecast_Data
在笔记本中,以及在此处 图 2.19 和 2.20 中的代码中,我们设置了我们的路径并从 Kaggle 下载了我们的数据。
首先,我们指定 raw_data_path 来存储文件。

图 2.19 – 设置我们的卷路径
在以下代码块(图 2.20)中,我们使用 Python 包 opendatasets,这是一个专门创建来从 Kaggle API 下载数据的库。你可以在 进一步 阅读 部分找到更多信息。

图 2.20 – 从 opendatasets 下载 Favorita 数据
本章关于 Favorita 店铺销售 项目的内容就到这里!现在,我们可以专注于为我们的 流式 事务 项目生成数据。
项目:流式事务
在流式事务项目中,你的目标是构建一个用于分类事务的模型。数据集由具有 Transaction、timestamp、Label、Amount 和 CustomerID 的 JSON 格式的事务组成。
在后面的章节中,你将添加一个产品列以展示模式演变。在本章中,你将创建本书其余部分使用的第一个版本的事务数据。为了在你的工作区中跟随,请打开以下笔记本:
CH2-01-Generating_Records_Using_DBKS_Labs_Datagen
您可以在我们处理它们时运行笔记本中的每个单元格,或者一次性运行它们。在设置命令之后,我们设置笔记本变量以确定每批交易生成的行数(nRows)、每批正标签行数(nPositiveRows)、您将存储 JSON 数据集的卷路径(destination_path)、临时路径(temp_path)以及您生成每批数据之间的秒数(sleepIntervalSeconds)。
以下代码块访问Reset小部件的值。如果小部件设置为True(其默认值),则已写入卷中的任何数据将被删除。

图 2.21 – 检查 Reset 小部件
接下来,我们设置数据生成器中用于创建交易的参数值。我们为每个CustomerID设置最小值和最大值。我们还创建了一个产品类型字典,并设置了min、max、mean、alpha和beta变量,您可以使用这些变量根据分布生成随机的交易金额。


图 2.22 – 保存用于 define_specs 函数中使用的变量的字典
变量设置完毕后,我们构建创建交易数据的函数,从define_specs函数开始。该函数接受产品类型(在图 2.22 中的字典中定义)作为输入,一个正标签或负标签,以及一个时间戳;它返回交易的金额。图 2.23 显示了代码的一部分;其余部分在配套的笔记本中。

图 2.23 – 定义 define_specs 函数以生成交易记录
接下来,我们编写一个函数,通过调用define_specs并包含当前时间戳来生成单个记录。

图 2.24 – 定义一个生成单个交易记录的函数
然后,我们构建generateRecordSet以生成每批中的recordCount个记录。请注意,在这个笔记本中,我们使用的是None产品类型,因此生成的记录将只有四个特征:CustomerID、TransactionTimestamp、Amount和Label(这在下一章中将非常重要!)。

图 2.25 – generateRecordSet 函数为每个产品和每个标签创建一个记录。每个记录包含 nRows 笔交易
最后,我们编写一个函数来生成一组数据,将数据转换为 DataFrame,并将其作为单个 JSON 文件写入临时路径。然后,我们将该文件移动到最终卷目标位置。

图 2.26 – writeJsonFile 函数生成一组记录
该集合包含作为整数的生成金额,因此我们将它们除以 100,将金额转换为美元并输入浮点数。该函数将 JSON 文件写入temp目录,然后将单个文件移动到最终目录。
在设置好一切后,使用提供的代码创建数据集。您可以自由增加迭代次数以构建更大的数据集。然后,继续下一个项目!
项目:检索增强生成聊天机器人
RAG 聊天机器人项目将摄入 PDF 文档以构建聊天机器人的知识库。我们使用体积来存储 PDF 文件。要在您的空间中跟随,请打开以下笔记本:
CH2-01-Downloading_PDF_Documents
文件可以直接在 Databricks 控制台的用户界面中上传到体积,如图图 2**.27所示;然而,此项目使用笔记本中提供的代码以编程方式下载并保存数据到体积中。

图 2.27 – 手动将文档上传到体积中
本章的代码从设置单元格和辅助函数开始,并在图 2**.28中指定了library_folder,我们将在此处保存下载的 PDF 文件。

图 2.28 – 指定用于存储此项目文件的库文件夹
我们正在使用在Arxiv页面上发布的与生成式 AI(GenAI)及其如何影响人力市场和经济学相关的开放文章。我们将 URL 传递给用作聊天机器人文档,并将这些文件加载到我们的体积中。

图 2.29 – 下载 PDF 文件并将它们保存到我们的体积中
现在我们已经下载了文档,它们准备好被处理以用于我们的聊天机器人。完成此操作后,我们可以继续我们的最终项目:多标签 图像分类。
项目:多标签图像分类
MIC 项目将图像摄入 Delta 表以微调来自Restnet家族的预训练模型以提高其准确性。我们将以编程方式从 Kaggle 下载图像并将数据保存到体积中。要在您的空间中跟随,请打开CH2-01-Downloading_Images笔记本:


图 2.30 – 使用 Databricks 魔法命令从 Kaggle 下载数据
现在我们创建体积文件夹,并将我们的分类项目的图像解压缩到我们的体积中。提取图像到Volumes需要大约一个小时(因为它包含 80K 个图像!)。

图 2.31 – 将图像解压缩到本项目的卷中
我们已下载或生成了所有四个数据集,它们已准备好在下一章被引入我们的青铜层。
摘要
本章涵盖了规划您的数据智能平台的各种设置决策、选项和流程。我们带您了解了 DI 平台的主要组件概述,从早期设计选择到我们将在后续章节中深入探讨的重要功能。您还学习了如何设置您的工作空间和项目代码库。我们希望您对平台的基础知识感到更加自在。随着 Databricks 准备就绪,项目数据已下载,我们现在准备深入了解构建青铜数据层意味着什么。
在 第三章 中,我们介绍了在 Databricks 智能平台内构建青铜数据层的要点。我们将数据格式化为最优化格式,了解模式演变、使用 Delta 进行变更数据捕获以及更多内容。
问题
以下问题旨在巩固需要记住的关键点,并将内容与您的个人经验联系起来。
-
Databricks 运行时如何实现稳定性?
-
我们如何使我们的数据更具可发现性?
-
设置 Databricks 工作空间需要哪些常见步骤?
答案
在思考这些问题后,比较您的答案与我们的答案。
-
Databricks 运行时通过提供一组一致的库来实现稳定性。
-
利用内置的元数据功能,例如表和列描述,使我们的数据更具可发现性。
-
设置工作空间的一些常见步骤是通过市场激活 Databricks 并设置用户组和治理。
进一步阅读
在本章中,我们确定了特定的库、技术特性和选项。请查看这些资源,深入了解您最感兴趣的领域:
-
什么是 Unity 目录?:
docs.databricks.com/data-governance/unity-catalog/index.html -
湖屋监控 演示:
youtu.be/3TLBZSKeYTk?t=560 -
UC 比 HMS 有更集中的模型生命周期管理方法:
docs.databricks.com/machine-learning/manage-model-lifecycle/index.html -
在 工作空间间 共享模型:
docs.databricks.com/en/machine-learning/manage-model-lifecycle/multiple-workspaces.html -
Azure 上的 Unity 设置 深入探讨:
youtu.be/itGKRVHdNPo -
连接外部 HMS 到 UC:
www.databricks.com/blog/extending-databricks-unity-catalog-open-apache-hive-metastore-api -
Unity Catalog 限制:
docs.databricks.com/en/data-governance/unity-catalog/index.html#unity-catalog-limitations -
最佳实践:集群配置 | 在 下拉菜单中选择云:
docs.databricks.com/clusters/cluster-config-best-practices.html -
Databricks 笔记本:
docs.databricks.com/en/notebooks/index.html -
Databricks Autologging | 在 下拉菜单中选择云:
docs.databricks.com/mlflow/databricks-autologging.html#security-and-data-management -
Kaggle API GitHub:
github.com/Kaggle/kaggle-api -
湖仓监控产品 页面:
www.databricks.com/product/machine-learning/lakehouse-monitoring -
系统 表:
www.databricks.com/resources/demos/tutorials/governance/system-tables -
Opendatasets Python 包:
pypi.org/project/opendatasets/ -
Kaggle API:
www.kaggle.com/docs/api -
GitHub:
github.com/ -
Databricks ML in Action GitHub 仓库:
github.com/PacktPublishing/Databricks-ML-In-Action -
Databricks Secrets API:
docs.databricks.com/en/security/secrets/secrets.html -
Databricks CLI:
docs.databricks.com/en/dev-tools/cli/index.html -
Databricks 实用工具:
docs.databricks.com/en/dev-tools/databricks-utils.html -
工作区 库:
docs.databricks.com/en/libraries/workspace-libraries.html -
数据网格和 DI 平台博客文章:
www.databricks.com/blog/2022/10/10/databricks-lakehouse-and-data-mesh-part-1.html,www.databricks.com/blog/2022/10/19/building-data-mesh-based-databricks-lakehouse-part-2.html -
关于托管表与外部表比较的短 YouTube 视频 UC:
youtu.be/yt9vax_PH58?si=dVJRZHAOnrEUBdkA -
HMS 的集中式模型注册工作区
docs.databricks.com/applications/machine-learning/manage-model-lifecycle/multiple-workspaces.html -
在 Unity 中管理模型生命周期 目录:
docs.databricks.com/machine-learning/manage-model-lifecycle/index.html -
Terraform https:
github.com/databricks/terraform-provider-databricks -
Kaggle API GitHub:
github.com/Kaggle/kaggle-api.
第三章:构建我们的青铜层
“数据是宝贵的,比系统本身更持久。”
– 蒂姆·伯纳斯-李,通常被认为是万维网的发明者
在本章中,您将开始您的 Databricks 平台数据之旅,探索青铜层的基础知识。我们建议在湖屋架构(如第二章中所述)中使用 Medallion 设计模式来组织您的数据。我们将从Auto Loader开始,您可以使用或不需要Delta Live Tables(DLT)来在架构中插入和转换数据。使用 Auto Loader 的好处包括快速将新数据转换为 Delta 格式,并强制执行或演进模式,这对于维护对业务和客户的持续数据交付至关重要。作为一名数据科学家,努力提高构建数据管道的效率,并确保您的数据为机器学习开发周期的步骤做好准备。您将通过示例项目最好地学习这些主题,因此本章的重点是应用我们的学习部分。
让我们看看本章将涵盖哪些主题:
-
回顾 Medallion 架构模式
-
使用 Auto Loader 将数据转换为 Delta 格式
-
DLT,从青铜开始
-
维护和优化 Delta 表
-
应用我们的学习
回顾 Medallion 架构模式
我们在第二章中介绍了 Medallion 架构。作为提醒,这指的是用于逻辑组织数据的数据设计模式。它包含三个层级——青铜、白银和黄金。在某些情况下,可能需要额外的细化层级,因此如果需要,您的 Medallion 架构可以扩展到钻石和铂金层级。青铜层包含原始数据,白银层包含清洗和转换后的数据,黄金层包含汇总和精选的数据。精选数据指的是为特定业务或建模目的选择、清洗和整理的数据集。这种架构非常适合数据科学项目。维护原始数据作为事实来源非常重要,而精选数据对于研究、分析和机器学习应用非常有价值。通过为特定目的选择、清洗和组织数据,精选数据可以帮助提高其准确性、相关性和可用性。
注意
本书将介绍许多项目任务,例如构建精选数据集,这些任务通常属于数据工程师的领域。也会有机器学习工程师、数据分析师等经常执行的任务。我们将所有这些工作包含在我们的示例中,因为在当今快速发展的世界中,角色是模糊的,并且会因公司而异。头衔和期望会迅速演变。因此,掌握整个端到端工作流程至关重要。
维护一个 Bronze 层允许我们在需要创建不同的特征、解决需要从另一个角度查看历史数据的新问题,或者仅仅为了治理目的而保持数据的原始级别时,回到原始数据。随着技术世界的不断发展,保持最新并跟随趋势至关重要,但核心原则将保持数年。在本章的剩余部分,我们将介绍便于构建 Bronze 层的 DI 平台功能。
使用 Auto Loader 将数据转换为 Delta
利用 Auto Loader 的力量来自动化您的数据摄取过程,显著提高您数据产品的工作流程效率。它可以从云存储和流数据源摄取数据。您可以配置 Auto Loader 按计划运行或手动触发。
使用 Databricks 的 Auto Loader 的一些好处:
-
它保持数据最新:Auto Loader 维护检查点,无需知道哪些数据是新的。Auto Loader 会自行处理所有这些。
-
它提高数据质量:Auto Loader 可以自动检测架构更改并恢复任何新的数据列,因此您可以确信您的数据是准确的。
-
它增加数据敏捷性:Auto Loader 可以帮助您快速轻松地摄取新的数据源,从而使您在应对业务变化时更加敏捷。
-
灵活的摄取:Auto Loader 可以批量或连续地流式传输文件。这意味着它可以以流的形式消耗批量数据,以减少更手动批量管道的开销。
Auto Loader 是一个强大的工具。它可以独立使用,作为 DLT 的底层技术,或者与Spark Structured Streaming一起使用。Spark Structured Streaming 是一个接近实时处理引擎;我们将在第五章中介绍如何创建实时功能。本章还涵盖了一个流式摄取的示例,在流交易项目中。让我们讨论 Auto Loader 随时间演进架构的能力。
架构演进
Auto Loader 的架构演进功能允许您无缝地在流数据中添加或修改字段。Databricks 会自动调整相关数据以适应新架构,同时保持现有数据完整性。这种自动化的架构处理使得随着业务需求和数据源的变化,您可以在不担心数据丢失或停机的情况下轻松地随时间演进您的数据架构。
新的模式在 应用我们的学习 部分中增加了一个额外的列。我们将展示即使在模式未通知的情况下更改,也不会丢失任何数据。在我们的案例中,Auto Loader 的默认模式演化模式 .option("cloudFiles.schemaEvolutionMode", "addNewColumns") 与 .option("mergeSchema", "true") 结合执行模式演化。Auto Loader 将为我们处理模式变化。当新数据字段可用时,无论是事先通知还是未通知,Auto Loader 跟踪变化是有益的;无需进行代码更改。
所有模式选项都有文档说明。我们项目所采用的方法是唯一适用于自动模式演化的选项。其他任何选项都需要手动干预。例如,您可以使用“rescue”模式来挽救数据以避免丢失。或者,您可以使用“failOnNewColumns”模式来使管道失败并保持模式不变,直到生产代码更新。Auto Loader 有许多选项和模式。在“进一步阅读”部分的 Common loading patterns with Auto Loader 链接中查看更多信息。
从青铜开始使用 DLT
如我们在前一章中提到的,请记住 DLT 主动简化了您的管道操作,使您能够专注于为您的管道设定明确的目标,而不是陷入操作细节。在此基础上,我们现在将深入研究 DLT 的功能。Auto Loader 的模式演化与 DLT 集成,强调了它在处理需要最少手动干预的动态数据模式中的实用性。
DLT 的优势和功能
DLT 是一个复杂的框架,旨在构建可靠的数据管道。DLT 自动化和简化了复杂的操作,如编排和集群管理,显著提高了数据工作流的效率。您只需指定您的转换逻辑即可启动运行。我们将重点关注与创建青铜数据层相关的 DLT 的几个优势,但我们也在本章末尾的“进一步阅读”部分中包含了一个 DLT 文档的链接。DLT 是您工具箱中用于摄取数据的另一个优秀工具。它提供了比传统 ETL 管道更多的优势,包括以下内容:
-
声明式管道开发:DLT 允许您使用 SQL 或 Python 定义您的数据管道,这使得它们更容易理解和维护。
-
自动数据质量测试:DLT 可以自动将您的测试应用到您的数据上,防止质量问题,这有助于确保您的管道产生准确的结果。
-
深度可见性用于监控和恢复:DLT 提供详细的跟踪和日志信息,使解决问题和从故障中恢复变得更加容易。
-
通过高效的计算自动扩展实现成本效益的流式处理:DLT 可以根据需求自动扩展或缩减计算资源,这有助于降低成本
DLT 是构建可靠和可扩展的批量或流式数据管道的强大工具。它可以帮助您提高数据处理工作流程的质量、效率和可见性。
以下是 DLT 的一些具体特性,它们提供了这些优势:
-
流式表:DLT 使用流式和实时表来实时处理数据,并确保您的管道与最新数据保持同步。
-
物化视图:DLT 使用物化视图来创建数据的快照。您可以在实时查询数据的同时,将其用于下游处理。
-
期望:DLT 使用期望来自动测试数据的质量问题,并在数据不符合期望时采取行动。
-
自动扩展:DLT 可以根据需求自动扩展或缩减计算资源,从而降低成本并提高管道的性能。
DLT 是构建可靠、可扩展和可测试的数据管道的好方法。接下来,我们将专注于青铜层背景下的 DLT。
DLT 中的青铜数据
DLT 使用 Auto Loader 来支持模式演变,在数据质量方面提供了显著的好处,这是 Medallion 架构中青铜层的关键方面。在这个架构中,青铜层作为原始数据最初摄入和存储的基础阶段。DLT 通过确保对原始数据应用的每个转换都精确捕获和管理来贡献这个层。作为数据科学家,理解这些转换对于维护数据处理工作流程的完整性至关重要。DLT 的一个强大功能是能够自动生成准确的流程有向无环图(DAG)。这个 DAG 不仅可视化这些数据转换的顺序和关系,还增强了整个数据管道的可靠性。
下面的截图展示了 DLT 管道工作流程:

图 3.1 – 本章交易数据集的 DLT 管道工作流程
在图 3.1 中,DLT 工作流程中有一个任务,但它可以容纳具有多个依赖关系的复杂工作流程。
一旦数据成功导入 Delta,我们可以采取一些措施来确保充分利用 Delta 的优势。
维护和优化 Delta 表
虽然本书的主要焦点不是 Delta 表的优化细节,但理解这些技术对于开发以数据为中心的机器学习解决方案至关重要。Delta 表的效率管理直接影响 ML 模型的表现和可靠性,因为这些模型高度依赖于底层数据的品质和可访问性。采用诸如VACUUM、液态聚类、OPTIMIZE和分桶等技术,以无与伦比的效率存储、访问和管理您的数据。优化后的表确保输入到 ML 算法中的数据得到有效处理。我们在这里简要介绍这些技术,但也建议您参考 Delta Lake 文档以全面了解每种技术。
VACUUM
VACUUM命令在管理 Delta 表内的资源方面至关重要。它通过清理无效文件和优化元数据布局来实现。如果您的 Delta 表经常进行update、insert、delete和merge操作,我们建议定期运行VACUUM操作。DML 操作可能会随着时间的推移生成大量的小文件。未能运行VACUUM可能会导致在线保留大量数据量极小的小文件,从而导致性能下降。
注意,VACUUM不会自动运行;您必须明确安排它。根据您的数据摄取频率和更新数据的频率,考虑定期安排VACUUM,例如每周或每月。此外,您可以选择配置保留期以优化存储和查询性能。delta.logRetentionDuration Delta 配置命令允许您通过指定希望保留数据文件的天数来控制保留期。这意味着您将删除超出保留设置(例如,只保留最后七天的元数据)的表的交易日志数据。这样,您就可以控制VACUUM操作在删除之前保留数据文件的时间长度。保留期影响您回顾表之前版本的能力。在决定保留元数据和交易日志多长时间时,请记住这一点。此外,交易日志并不大。
液态聚类
液态聚类是分区的一个很好的替代方案;请参阅如何在 图 3**.2 中实现它。通常,数据会被过度分区,导致分区中文件过少或不平衡。除非表的大小为兆字节或更大,否则您不需要分区。除了替换分区外,液态聚类还替换了 Delta 表上的 Z-排序。Z-排序与聚类表不兼容。在选择用于聚类的列时,包括您用于查询过滤的高基数列。另一个常见的例子是时间戳列。与其创建一个派生列日期以最小化基数,不如直接在时间戳上聚类。液态聚类为具有倾斜数据分布或变化访问模式的 Delta 表带来好处。它允许表通过重新定义聚类键而不重写数据来适应分析需求,从而实现优化的查询性能和灵活、维护高效的架构。启用液态聚类后,您必须使用 DBR 13.3+ 来创建、写入或优化 Delta 表。

图 3.2 – 使用液态聚类优化的表创建示例代码
优化
OPTIMIZE 命令将触发聚类。在流式传输数据时,这尤为重要,因为表在写入时不会进行聚类。OPTIMIZE 还会压缩数据文件,这对于具有许多小文件的 Delta 表至关重要。它将这些文件合并成更大的文件,提高了读取查询速度和存储效率,这对于大型数据集特别有益。
预测优化
预测优化是一个为您自动运行 VACUUM 和 OPTIMIZE 的功能。如果您有高级版本、已启用无服务器和已设置 Unity 目录,您的管理员可以在设置中启用它。
现在我们已经介绍了 Medallion 架构、Auto Loader、DLT 以及一些优化 Delta 表的技术,准备好在自己的 Databricks 工作区中跟随我们,通过项目来逐步分析 第三章 的代码。
应用我们的学习方法
在深入每个项目的核心“数据科学”方面之前,您将摄取数据。我们已经讨论了 Auto Loader、模式演变和 DLT 如何在存储中格式化数据。您会注意到以下项目使用不同的模式将数据加载到青铜层。流式事务项目使用 Auto Loader 摄取传入的 JSON 文件。您将独立使用 DLT 和 Structure Streaming 转换数据,这样您就可以获得两种方法的经验。
技术要求
在我们开始之前,请回顾完成本章动手实践所需的技术要求。
Databricks ML 运行时包括几个预安装的库,这些库对 ML 和数据科学项目很有用。因此,我们将使用具有 ML 运行时的集群。
项目 – 流式事务
我们流式事务项目的下一步是构建青铜层,也就是我们最终将在分类模型中使用的原始数据。我们特别创建了这个流式项目来练习使用 Auto Loader、模式演变、Spark Structured Streaming 和 DLT 功能,因此我们将在这部分项目中使用这些功能。要在你的工作区中跟进,请打开以下笔记本:
-
CH3-01-Auto_Loader_and_Schema_Evolution -
CH3-02-Generating_Records_and_Schema_Change -
delta_live_tables/CH3-03-Formatting_to_Delta_with_DLT
这里是我们项目流程中的当前状态:

图 3.3 – 合成流式事务项目的项目计划
在 第二章 中,我们生成并存储了我们的合成事务数据在 JSON 文件中。现在,我们将读取这些数据到 Delta 表中。我们还将更新数据生成笔记本,添加一个产品字符串列,这将演示模式演变,如之前在 模式演变 部分中提到的。让我们来探讨两种将数据流读取和写入 Delta 表的选项。两种选项都使用 Auto Loader 进行摄取。然后,文件由 Spark Structured Streaming 或 DLT 处理和写入。本节有两个笔记本。我们将从 CH3-01-Auto_Loader_and_Schema_Evolution 开始。
使用 Structured Streaming 的 Auto Loader 进行连续数据摄取
本节中的代码使用 Auto Loader 将传入的 JSON 文件格式化为 Delta。我们使用的表名是 synthetic_transactions。在处理数据之前,我们创建了一个小部件(见 图 3.4)来决定我们是否想要重置模式和检查点历史。重置历史记录在修改或调试管道时可能很有帮助。如果你重置(删除)你的检查点历史,你将重新处理所有历史数据。

图 3.4 – 创建小部件以重置检查点和模式
接下来,我们为脚本设置变量,这些变量主要是路径:

图 3.5 – 设置路径变量
设置文件为我们提供了 volume_file_path,其中我们存储合成数据、模式和检查点文件夹。
如 图 3.6 所示,我们添加 spark 配置以优化和减少推理的样本大小:

图 3.6 – 设置配置以优化和减少样本大小
你可以在集群的高级选项中设置这些 Spark 配置。这些配置将自动将小文件集压缩成大文件,以实现最佳读取性能。
配置数据摄取的流
流命令相对较长,所以让我们逐块分析代码:
- 我们正在创建一个流来从合成数据集读取。格式选项引用流格式。
cloudFiles指的是位于云存储中的文件。在这种情况下,我们生成数据并将其写入云存储。然而,使用.format("kafka")创建流是可能的,它可以直接从流中摄取而不先写入云存储。我们还指定文件格式为 JSON。

图 3.7 – 使用 CloudFiles 和 JSON 文件格式创建流
- 默认情况下,将列类型设置为
string。然而,我们可以提供模式提示,以便我们确信的列能够得到适当的类型。在推断模式的同时,我们还想推断列类型。新列是string类型,因此我们看不到这个选项的实际操作,因为新列默认为string。

图 3.8 – 设置模式提示以减少可能的数据类型不匹配。我们希望推断不在模式提示中的列的数据类型
- Auto Loader 使用
rescue列来捕捉变化,并迅速将新列投入使用而不会丢失数据!请注意,流将失败并需要重启。如果我们希望 Auto Loader 能够跟踪模式并在时间上进化它,则需要模式位置。

图 3.9 – 设置模式进化以添加新列并指定模式位置,以便 Auto Loader 能够跟踪模式随时间的变化
-
接下来,我们加载原始数据文件的位置。我们需要选择我们想要的字段。我们将选择所有数据字段,但你也可以选择性地拉取字段。
-
以下代码行开始流的“写入”部分。在这里,我们开始
writeStream。Delta 是默认的数据格式,但我们更喜欢明确设置它。我们还指定此流为只追加,因为我们没有执行任何更新或插入操作。 -
检查点是 Spark Structured Streaming 中的一种机制,允许您保存流的当前状态。如果您的流失败,当它重新启动时,它将使用检查点从上次停止的地方继续处理。合并模式选项是必不可少的。合并模式会将新列添加到到达时,而无需干预。

图 3.10 – 创建我们的检查点位置并设置合并模式
-
下一步是设置触发器。触发器设置指的是处理速度,有两种主要模式。根据以下代码,你可以指定基于时间的触发器间隔(以秒为单位)。我们的生成笔记本中的数据是连续的。在这里,我们通过微批有效地处理它。我们在步骤 4中提供了一个选择语句。现在我们可以将那个语句的结果写入
destination_location路径下的 Delta 文件。在步骤 7中,我们使用了一个 10 秒的处理时间触发器。处理时间意味着每 10 秒将处理一次微批数据。假设你不需要微批。如果你需要每小时或每天处理一次数据,那么
trigger.availableNow选项最佳。如果你想处理在过去一小时到达的任何新数据,请在你的管道中使用trigger.AvailableNow,并每小时使用作业集群启动工作流来安排管道。那时,自动加载器将处理所有可用数据然后关闭。 -
接下来,为了展示模式演化,我们将我们的数据生成笔记本从第二章更新到包含一个额外的
data列。你将在第三章文件夹中找到新版本,CH3-02-Generating_Records_and_Schema_Change。请注意,我们为writeJsonFile提供了一个可能的产品列表。结果是额外的字段,Product,包含记录的产品字符串(图 3**.11)。

图 3.11 – 生成带或不带产品字符串的数据的更新方法
由于我们的更改,你现在有一个数据流,在中间添加了一个额外的列。你可以启动自动加载器笔记本来查看模式演化的实际操作。当检测到额外的列时,流会停止,提供一个异常 – [UNKNOWN_FIELD_EXCEPTION.NEW_FIELDS_IN_RECORD_WITH_FILE_PATH]。不用担心;重启后,模式演化将接管。再次运行包含流的单元格以重启。
你已经使用 Spark Structured Streaming 完成了读取和写入操作。接下来,我们将向你展示如何使用 DLT(使用更少的代码!)完成相同的任务。
使用 DLT 的自动加载器进行连续数据摄取
本节使用自动加载器代码读取 JSON 文件的流,然后使用 DLT 将文件写入表。这个笔记本位于delta_live_tables文件夹中,标题为CH3-03-Formatting_to_Delta_with_DLT。
你只需要导入 DLT – import dlt。DLT 代码相对较短,部分原因是因为管道配置发生在管道对象中而不是代码中。在我们查看源代码之前,让我们导航到左侧导航栏中的Databricks Workflows面板,选择Delta Live Tables,然后点击创建管道,这将打开管道设置页面,如图图 3**.12所示。

图 3.12 – 工作流 UI 中的 DLT 管道设置
DLT 的管道配置
由于 DLT 执行优化,因此管道设置是最小的,所以设置说明也是最小的。输入到管道配置中的参数可以通过spark.conf.get在管道代码中访问,如图3.13和3.14所示:
-
输入管道名称。我们将使用
MLIA_Streaming_Transactions。 -
对于产品版,选择高级。此 DLT 版本包含最多功能,包括 DLT 的期望规则。
-
对于管道模式,选择触发。这将确保管道在成功运行后停止处理。
-
对于路径,从存储库中选择此笔记本作为源代码:
Databricks-ML-in-Action/ Chapter 3: Building Out Our Bronze Layer/ Project: Streaming Transactions/ delta_live_tables/ CH3-03-Formatting_to_Delta_with_DLT -
选择Unity Catalog作为您的存储选项。
-
对于目录选择
ml_in_action,对于目标模式选择synthetic_transactions_dlt。 -
在
raw_data_location中将table_name和synthetic_transactions_dlt作为配置输入,如下所示(如图3**.13所示):/Volumes/ml_in_action/ synthetic_transactions/files/ synthetic_transactions,

图 3.13 – 变量的高级管道配置设置
DLT 管道中的方法
现在我们已经填写了管道 UI,让我们专注于管道源代码中使用的的方法。在这个函数中,我们主要重用了我们之前的代码(图 3**.14)。请注意,在这个笔记本中我们不使用设置文件。相反,我们使用在管道设置的高级配置部分设置的变量。

图 3.14 – 自动加载流方法详情
在 DLT 管道中生成青铜表
generate_table()函数将使用 Auto Loader 创建的读取流馈送到 DLT。我们使用spark.conf.get('variable_name')来访问我们在管道的高级设置(图 3**.13)中定义的变量值。在笔记本中,您将看到最终步骤,一个名为generate_table()的单行单元格。

图 3.15 – 在 DLT 管道中生成青铜表
DLT 是独特的。它不是逐行运行的代码,因此您不需要在笔记本中执行管道。回到 DLT UI,我们保存并点击开始按钮。设置过程完成后,您将看到一个包括我们的表的图。开始不仅启动了管道,还创建了它。一旦完成,您将看到一个如图3**.1所示的屏幕。
查询使用 DLT 创建的流表
您可以像查询其他表一样查询使用 DLT 创建的流表。这对于填充仪表板很有用,我们将在第八章中介绍,监控、评估和更多。
重要提示
如果在笔记本中尝试查询您的流式表,您可能会得到这个错误:
执行异常:org.apache.spark.sql.AnalysisException: 403:您的令牌缺少此端点所需的权限。
这是因为要查询由 DLT 管道创建的流式表,您必须使用 Databricks Runtime 13.1 及以上版本的共享集群或 SQL 仓库。在 Unity Catalog 启用的管道中创建的流式表不能从分配或无隔离集群中查询。您可以更改您的集群或使用 DBSQL 查询编辑器。
管道创建了我们的大铜表,完成了这个关于流式事务数据的项目的收尾工作。
项目 – Favorita 商店销售 – 时间序列预测
在上一章中,您使用opendatasets从 Kaggle 下载了Favorita 销售预测数据集。我们现在将使用这些数据来创建 Delta 表。要在自己的工作区中跟随,请打开CH3-01-Loading_Sales_CSV_Data_as_Delta笔记本。
下载的数据是单个 CSV 文件。我们使用 pandas 读取数据集,并使用 Spark 写入 Delta 表。我们将在下面的代码块(图 3.16)中演示这一点。

图 3.16 – 使用 Pandas 读取销售假日事件数据集
我们利用数据概要功能(图 3.17)在写入表之前检查数据类型。概要显示日期字段的推断数据类型是字符串,而不是日期或时间戳。因此,我们在写入 Delta 表之前更改了数据类型。

图 3.17 – 使用 display(df),我们可以点击+来查看数据概要。这让我们可以快速查看数据类型和分布
Favorita 项目的每个表都类似地转换为 Delta 表。因此,我们只在书页中包含第一个表。然而,转换每个表的代码当然在存储库中。
项目 – 检索增强生成聊天机器人
RAG代表检索增强生成。一个 RAG 系统通常包括你的数据、一个向量数据库、一个搜索算法和一个生成式 AI模型来生成对用户查询的答案。图 3.18展示了我们将在这本书中构建的管道。

图 3.18 – 我们将在本书中尝试复制的管道示例
从 图 3.18 我们可以看到,我们需要根据用户查询检索相关数据。这就是我们的搜索方法将访问向量数据库并执行语义或混合搜索的地方。在 RAG 聊天机器人项目的这个阶段,我们的 PDF 文件以原始的非结构化形式存在。我们希望用户通过我们的聊天机器人访问这些知识,因此我们必须将所有 PDF 中的相关信息内容带入我们的聊天机器人中,该聊天机器人实时运行。为此,我们将所有 PDF 转换为机器可读格式。本章展示了如何从 PDF 文件中提取非结构化数据,将其分块,并将您的文本转换为嵌入。然后,我们将嵌入存储在 Delta 表中:
-
我们数据准备的第一步是从 PDF 文件中提取非结构化信息。要在您的工作区中跟随,请打开
CH3-01-Creating_EmbeddedChunks笔记本。 -
要开始构建青铜数据层,创建一个包含表模式的空 Delta 表。使用
GENERATED BY DEFAULT AS IDENTITY功能利用 Delta 表功能自动索引新到达的数据。此外,添加一个表属性以将Change Data Feed设置为true。

图 3.19 – 创建名为 pdf_documentation_text 的空 Delta 表
- 对于下一步,从
volume文件夹中读取原始 PDF 文件,并将其保存到名为pdf_raw的表中(图 3.20)。我们将在pdf_documentation_text表中返回。

图 3.20 – 以二进制格式读取 PDF 文件并将其写入青铜层表
- 将 PDF 存储在
content列的二进制格式中,以便稍后提取文本。让我们看看它在 Delta 表视图中的样子。每个 PDF 的二进制格式都在content列中:

图 3.21 – 在 Delta 表中显示摄取的内容
- 接下来,我们使用
unstructured库编写一个辅助函数,从 PDF 字节中提取文本。该函数位于mlia_utils.rag_funcs脚本中。

图 3.22 – 创建辅助函数以提取文档文本
- 让我们将此函数应用于我们拥有的其中一个 PDF 文件,并检查文档的内容:

图 3.23 – 将辅助函数应用于从 PDF 中提取信息
太好了!图 3.23 让我们窥见了其中一个导入的文档。你可能有很多 PDF 文件,这些文件可能非常长。长文档可能对我们的未来聊天机器人构成潜在问题,因为它们很容易超过大多数 LLM 的最大上下文长度(更多信息请参阅进一步阅读)。此外,我们可能不需要整个文档的文本来回答特定问题。相反,我们需要文本的某个部分或“数据块”。对于这个项目,我们使用 LlamaIndex 库的 SentenceSplitter 模块创建不超过 500 个令牌的数据块,数据块重叠为 50。你也可以使用 LangChain 库或任何你选择的库来将内容分割成数据块。我们将使用开源的 Llama-tokenizer,因为这将是我们在整个项目中的主要模型系列。请注意,分词器可能在你的 RAG 质量中扮演关键角色。我们已经利用 Pandas 用户定义函数(UDF)来跨所有文档的所有页面进行扩展。

图 3.24 – 为我们的提取函数创建 pandas UDF
- 现在,让我们将此函数应用于我们的 Delta 表:

图 3.25 – 使用 PySpark 应用辅助函数从 PDF 中提取信息
一旦我们的数据块准备就绪,我们需要将它们转换为嵌入。嵌入是我们将数据导入 Silver 层进行语义搜索所需的格式。
Databricks 模型托管现在支持 基础模型 API(FMAPIs),允许你从托管端点访问和查询最先进的开放模型。使用 FMAPIs,你可以快速轻松地构建利用高质量 GenAI 模型的应用程序,而无需维护自己的模型部署(更多信息请参阅进一步阅读部分中的部署已配置吞吐量基础模型 API)。
FMAPIs 提供两种访问模式:
-
按令牌付费:这是开始访问 Databricks 上的基础模型的最简单方法,并且推荐用于开始使用它们的旅程。
-
已配置吞吐量:此模型推荐用于需要性能保证、精细调优的模型或具有额外安全要求的工作负载:

图 3.26 – 通过 Databricks 的 FMAPIs 可用的模型
重要提示
在撰写本文时,FMAPI 仅适用于美国地区。如果你的工作区尚未在支持的地区,你可以使用任何你选择的模型(OpenAI、BERT、LlaMA 分词器等)将你的内容转换为嵌入。
你可能还需要微调你的模型嵌入,以便从你自己的内容中学习以获得更好的检索结果。
接下来,我们利用 DI 平台的按令牌付费能力,通过 FMAPI 提供您对 BGE_large_En 端点的访问,这是最近添加到 mlflow >=2.9 - mlflow 部署(以前称为 AI Gateway)的新功能。此功能统一了 Databricks 上的模型服务端点管理。

图 3.27 – 使用 BGE 端点应用 FMAPI 将“什么是 ChatGPT?”转换为嵌入
现在,我们在所有块上应用这个嵌入转换,并且再次创建 pandasUDF 以实现可扩展性。

图 3.28 – pandasUDF 在所有块上应用嵌入转换
应用我们的 UDF 将会为我们的 raw_table 块添加相应的嵌入:

图 3.29 – pandasUDF 在所有块上应用嵌入转换
一旦我们的数据准备过程的最后一步完成,我们使用追加模式将我们的表保存到最初预创建的 Delta 表 pdf_documentation_text 中。
注意
我们已经将此项目的 PDFs 一次性导入,这作为一个例子来说效果非常好。然而,这也意味着每次你想向你的聊天机器人知识库添加新的 PDF 时,你必须手动重新运行所有前面的步骤。我们建议为生产级解决方案制定工作流程来自动化前面的步骤,并随着存储中到达的 PDFs 逐步导入。
现在我们有一个数据集,可以用于向量搜索索引,我们将在 第四章 中介绍。
项目 – 多标签图像分类
在 第二章 中,我们在我们的卷中提取并存储了我们的原始图像数据。在本章中,我们准备我们的图像数据集,并将训练和验证集保存到 Delta 表中。要在您的空间中跟随,请打开 Ch3-01-Loading_Images_2_DeltaTables 笔记本:
- 我们首先创建变量,如果
Reset小部件的值为True,则删除现有数据。

图 3.30 – 如果 Reset = True,则清理现有数据
- 接下来,我们创建一个函数来将所有我们的图像放入一个表中。最初,每个标签都在其自己的
folder_label_name文件夹中。我们提取image_name、image_id和label_id,并使用追加模式创建label_name。

图 3.31 – 创建 prep_data2delta 函数
我们使用 prep_data2delta 函数来加载和准备我们的训练和验证数据集(图 3**.32)。请注意,如果 write2delta 标志为 True,则该函数将保存一个 Delta 表,如果 returnDF 标志的值为 True,则将返回一个 DataFrame。接下来,在笔记本中,我们为训练和验证集调用 prep_data2delta。
让我们谈谈数据加载器
当我们在微调或训练我们的深度学习模型时,我们以固定大小的批次加载数据。每个框架都原生支持特定的数据类型;一些扩展了它们的原生格式到其他开源格式。数据科学家有时更喜欢将他们的数据(在我们的例子中是图像)保存在 blob 存储中,并直接从存储中读取,而不是使用 Delta 表,因为他们认为这样可以避免额外的工作。然而,我们建议除非您正在处理每个图像大于 1 GB 的大图像,否则将图像存储在 Delta 表中。将您的图像存储在 Delta 表中可以让您利用 Delta 和 Unity Catalog 的额外好处,例如数据和方法血缘、数据版本控制、重复数据检查和质量保证。
在撰写本文时,您在使用 PyTorch 或 PyTorch Lightning 框架处理数据时有一些读取数据的选择:
-
DeltaTorchLoader(推荐) -
Petastorm
-
直接从 blob/disk/volumes 读取图像
我们的推荐是使用 DeltaTorchLoader。它在训练 PyTorch 管道时处理数据批处理、采样和多进程,而不需要像 Petastorm 那样复制临时文件。有关更多信息,请参阅进一步阅读。
在撰写本文时,我们将使用的 DeltaTorchLoader,用于将数据从 Delta 转换为 PyTorch/Lightning 数据加载器框架以训练我们的模型(见第六章),要求您在使用 UC 时拥有未管理的 Delta 格式的表。请放心;血缘信息与您的数据集相同的路径关联。我们将在第六章中更多地讨论血缘信息。这一要求是由于 UC 的 blob 存储的读写安全权限。blob 存储维护者目前不支持这些安全设置。如果您不使用 UC,您应该能够直接从托管表中读取 Delta 表。
您还可以使用 Petastorm 库来读取您的数据。我们不推荐使用 Petastorm,因为它需要更深入地理解某些陷阱。最常见的是由于数据缓存导致的内存使用问题,以及它使用 Apache Parquet 文件而不是 Delta 文件,因此它会消耗您所有版本的 parquet 文件。
DeltaTorchLoader 的创建者与 Petastorm 进行了一些基准测试。该基准测试在 数据和人工智能峰会(DAIS)上分享,并在 图 3.33 中展示。在本项目中,我们将比较 Petastorm 与经典 Torch 加载器在 第六章 中的性能提升。比较显示,在读取数据批次时速度有显著提升。如果您想了解更多信息,我们还在 进一步阅读 部分包含了一个关于 TorchDeltaLoader 的精彩视频。

图 3.32 – DeltaTorchLoader 基准测试 – DeltaTorch 和 Petastorm 加载器之间的性能比较
您可以在 Delta 表中保留文件名而不是图像,并在将它们传递给主 PyTorch 加载器时使用 trainer 函数进行收集。在 Delta 中保留文件对于避免重复和控制训练和验证期间使用的列表至关重要,因为您可以将 Delta 版本传递给 MLflow 以实现完整复制目的。
优化我们的数据
一旦我们的表创建并写入存储,我们就使用一些函数来提高 Delta 表的读取性能。首先,我们使用 OPTIMIZE 保持理想数量的文件(图 3.34)。其次,我们禁用删除向量,因为 DeltaTorchReader 目前还不支持它们(图 3.35)。我们使用 SQL 魔法命令 %sql 在 Python 笔记本中执行这些操作。

图 3.33 – 优化训练表的大小和数量
注意,我们在 Python 中保存的变量在 SQL 中不可访问,因此在这个例子中我们将其硬编码。您可以在 global-setup 笔记本中包含 SQL 变量以避免这种情况。

图 3.34 – 优化训练表
现在,我们已经加载并优化了训练和验证表,以便高效地处理这些图像数据以微调我们的多类计算机视觉模型。
摘要
在本章中,我们专注于在 Databricks 数据智能平台内构建青铜数据层的基本要素。我们强调了模式演变、DLT 以及将数据转换为 Delta 格式的重要性,并在我们的示例项目中应用了这些原则。本章强调了 Auto Loader 和 DLT 等工具在此过程中的重要性。Auto Loader 在处理文件跟踪和自动化模式管理方面的熟练程度,以及 DLT 在管道开发和数据质量保证方面的强大能力,对我们数据管理策略至关重要。这些工具促进了数据管道管理的有效和简化方法,使我们作为数据科学家能够更多地专注于有价值的任务,如特征工程和实验。
在创建了青铜层之后,我们现在从这项基础工作转向更高级的数据层——银层。第四章,向银层转变的转换,将带我们更深入地了解我们的数据,并展示各种 Databricks 工具,这些工具将帮助我们探索和转换我们的数据。
问题
以下问题有助于巩固需要记住的关键点,并将内容与你的经验联系起来:
-
Medallion 架构设计中的层名称是什么?
-
如果你想要构建一个使用流数据的托管管道,你会使用哪个产品——结构化流或 DLT?
-
我们使用了什么特性来在不进行人工干预的情况下将
product列添加到我们的流式事务数据中? -
你是否有来自你当前职位、经验或路线图的项目,可以从本章涵盖的一个或多个主题中受益?
-
在对高基数列进行分区时,减少分区数量的可能方法是什么?
答案
在思考这些问题后,将你的答案与我们的答案进行比较:
-
Medallion 架构的层是青铜、银和金。
-
我们建议使用 DLT 构建托管管道。
-
在流式事务项目示例中,我们使用了 Auto Loader 的模式演变功能来添加列,而不进行人工干预。
-
我们希望如此!一个例子是受益于 DLT 内置数据质量监控的托管流数据管道。
-
分桶是一种专门设计来为你的数据提供额外组织层的优化方法。它可以减少输出文件的数量,并更好地组织数据以便后续读取,当分区列具有高基数时,它尤其有用。
进一步阅读
本章介绍了将数据导入青铜层的不同方法。查看这些资源以了解更多关于你最感兴趣领域的相关信息:
-
使用液体聚类对 Delta 表进行聚类:
docs.databricks.com/en/delta/clustering.html -
Spark Structured Streaming:
spark.apache.org/docs/latest/structured-streaming-programming-guide.html -
Delta Live Tables:
docs.databricks.com/en/delta-live-tables/index.html -
DLT Databricks 演示:
www.databricks.com/resources/demos/tutorials/lakehouse-platform/full-delta-live-table-pipeline -
Auto Loader 选项:
docs.databricks.com/ingestion/auto-loader/options.html -
使用 Auto Loader进行模式演变:
docs.databricks.com/ingestion/auto-loader/schema.html#configure-schema-inference-and-evolution-in-auto-loader -
使用 Auto Loader的常见加载模式:
docs.databricks.com/ingestion/auto-loader/patterns.html -
使用 Apache Kafka 和 Databricks进行流处理:
docs.databricks.com/structured-streaming/kafka.html -
如何在 Delta Live Tables中以低于 1 美元的成本处理十亿条记录:
www.databricks.com/blog/2023/04/14/how-we-performed-etl-one-billion-records-under-1-delta-live-tables.html -
创建表 – 管理与 外部:
docs.databricks.com/en/data-governance/unity-catalog/create-tables.html#create-tables -
充分利用可用的自动调整 功能:
docs.databricks.com/delta/tune-file-size.html#configure-delta-lake-to-control-data-file-size -
从 Databricks 仓库导入 Python 模块:
docs.databricks.com/en/delta-live-tables/import-workspace-files.html -
Databricks ML 运行时:
docs.databricks.com/runtime/mlruntime.html#introduction-to-databricks-runtime-for-machine-learning -
集群高级 选项:
docs.databricks.com/en/clusters/configure.html#spark-configuration -
部署配置吞吐量基础模型 APIs:
docs.databricks.com/en/machine-learning/foundation-models/deploy-prov-throughput-foundation-model-apis.html -
在 Databricks 上使用 Delta Lake 存储格式扩展深度学习:
www.databricks.com/dataaisummit/session/scaling-deep-learning-using-delta-lake-storage-format-databricks/ -
DeltaTorchLoader:
github.com/delta-incubator/deltatorch
第二部分:高度关注用例
本部分向您介绍如何从数据源集合开始,并在整个平台上与之协作,从一端到另一端。本部分的目标仅仅是展示如何深思熟虑地使用平台的所有功能和特性。本部分提供了案例故事、代码、湖仓功能以及最佳实践。
本部分包含以下章节:
-
第四章, 了解您的数据
-
第五章, 在 Databricks 上执行特征工程
-
第六章, 寻找信号
-
第七章, 在 Databricks 上生产化机器学习
-
第八章, 监控、评估及其他
第四章:了解您的数据
“真理,就像金子一样,不是通过其增长,而是通过洗去其中所有非金子的东西来获得的。”
——列夫·托尔斯泰
在本章中,我们探讨了 Databricks DI 平台内的功能,这些功能有助于提高和监控数据质量,并促进数据探索。使用 Databricks 更好地了解您的数据有无数种方法。首先,我们将介绍如何使用 Delta Live Tables (DLT) 监督数据质量,以尽早发现质量问题并防止整个管道受到污染。我们将首先深入了解 Lakehouse Monitoring,它帮助我们分析数据随时间的变化,并可以提醒我们关注的变化。Lakehouse Monitoring 是一个节省大量时间的功能,让您能够专注于减轻或响应数据变化,而不是创建计算标准指标的笔记本。
探索数据,我们将探讨几种低代码方法:Databricks 助手和 AutoML。最后,我们将简要介绍嵌入。我们在 第三章 中从文本块中创建了嵌入,您将学习如何使用 Databricks 向量搜索 (VS) 来探索您的嵌入。
作为本章的一部分,您将学习以下内容:
-
使用 DLT 提高数据完整性
-
使用 Databricks Lakehouse 监控监控数据质量
-
使用 Databricks 助手探索数据
-
使用 AutoML 生成数据配置文件
-
准备数据以进行向量搜索和数据库索引
-
使用 Databricks 向量搜索增强数据检索
-
应用我们的学习
使用 DLT 提高数据完整性
在上一章中,我们介绍了 DLT 作为流数据管道开发的实用工具。在这里,我们专注于如何将 DLT 作为您的首选工具来积极跟踪数据质量。通常,数据集是动态的,不像在学校和培训中那样整洁有序。当然,您可以使用代码来清理数据,但有一个功能使清理过程更加容易:DLT 的预期。DLT 的预期捕获传入的数据质量问题,并自动验证传入数据是否通过指定的规则和质量检查。例如,您可能希望客户数据在年龄上有正值,或者日期遵循特定的格式。当数据不符合这些预期时,可能会对下游数据管道产生负面影响。实施预期后,您确保您的管道不会受到影响。
实施预期给我们更多的数据质量控制,提醒我们注意和采取行动的不寻常数据。在处理 DLT 中的错误数据时,有几个选项:
-
首先,我们可以设置一个警告,该警告将报告未通过预期的记录数作为指标,但仍然将那些无效的记录写入目标数据集;请参阅 图 4 中的
@dlt.expect()示例。1 -
第二,我们可以丢弃无效记录,这样最终数据集只包含满足我们预期的记录;参见图 4**.1中的
@dlt.expect_or_drop()。 -
第三,我们可以完全失败操作,这样就不会写入任何新内容(请注意,此选项需要手动重新触发管道)。
-
最后,我们可以将无效数据隔离到另一个表中以进一步调查。以下代码应该与第三章中的 DLT 代码相似,但现在增加了预期。

图 4.1 – 使用 DLT 预期来强制数据质量
让我们以我们的流式事务项目为例。在第三章中的应用我们的学习部分,我们使用 DLT 将交易数据写入表。利用相同的 DLT 代码,我们将通过在原始代码中添加一个预期来删除任何CustomerID为null的记录,从而节省手动清理CustomerID列的努力。我们还将设置另一个预期,如果Product字段为null,则发出警告。
现在,当我们调用generate_table()时,DLT 管道将自动清理我们的表,删除任何空CustomerID值,并标记没有Product值的记录。此外,DLT 将自动构建有用的可视化,以便立即调查数据的质量。
要自己尝试,请更新第三章中的 DLT 代码(这里提供笔记本路径作为提醒:Chapter 3``: Building Out Our Bronze Layer/Project: Streaming Transactions/delta_live_tables/),以匹配图 4.1,然后像之前一样重新运行 DLT 管道。一旦管道完成,它将生成 DAG。点击synthetic_transactions_silver表,然后从表详情中点击数据质量**选项卡。这将显示有关已处理的记录的信息,例如有多少条记录因未通过特定预期而被写入或丢弃,如图图 4**.2*所示。

图 4.2 – DLT 数据质量可视化
这些见解说明了预期如何帮助我们自动清理表并标记可能对下游使用此表的数据科学家有用的信息。在这个例子中,我们看到所有记录都通过了valid_CustomerID预期,因此现在我们知道我们不必担心表中存在空客户 ID。此外,近 80%的记录缺少Product值,这可能对使用此数据的数据科学和机器学习(ML)项目相关。
正如我们已经考虑了传入数据的正确性和一致性,我们还想考虑如何扩大我们的数据质量监督范围,包括数据漂移,例如,当您的数据分布随时间变化时。观察数据漂移是 Databricks Lakehouse 监控作为 DLT 的重要补充出现的地方,它提供了一个可配置的框架,以一致地观察和验证输入数据的统计特性和质量。
使用 Databricks Lakehouse 监控监控数据质量
使用 Databricks Lakehouse 监控来主动检测和应对数据分布中的任何偏差。随着时间的推移,数据可能在其基本模式上发生变化。这可能是特征漂移,即特征数据的分布随时间变化,或者是概念漂移,即模型输入和输出之间的关系发生变化。这两种类型的漂移都可能导致模型质量下降。这些变化可能在生产环境中缓慢或迅速发生,这就是为什么在数据成为您的机器学习模型和数据产品的输入之前监控数据至关重要。
Lakehouse 监控的机制
要在 Databricks 中监控一个表,您需要创建一个附加到该表的监控。要监控机器学习模型的性能,您需要将监控附加到包含模型输入和相应预测的推理表。Databricks Lakehouse 监控提供以下配置文件类型的分析:快照、时间序列和推理。
除了选择要监控的表,称为主表,您还可以选择性地指定一个基线表以参考测量漂移或随时间变化的价值。当您有一个您期望数据看起来如何的样本时,基线表非常有用,例如,使用您训练模型的数据。Lakehouse 监控自动计算与基线表预期数据值和分布的漂移。
自动创建表监控会自动创建两个度量表,profile_metrics 和 drift_metrics。Lakehouse 监控在您创建监控时指定的表上计算度量值,包括时间窗口和数据子集或“切片”。您还可以添加自己的自定义度量;有关详细信息,请参阅进一步阅读。
可视化和警报
Lakehouse 监控为每个监控自动生成一个 SQL 仪表板。这些仪表板为检查指标和采取行动提供了一个关键平台。Databricks 的警报系统充当一个警惕的守护者,及时通知您订阅的数据质量或分布的重大变化。图 4**.3 展示了 Lakehouse 监控的所有组件如何协同工作,使用主表和可选的基线表中的数据生成配置文件度量表和漂移表,然后填充仪表板并触发警报。

图 4.3 – 输入表、指标表、监控器和仪表板之间的关系
创建监控器
您可以使用 用户界面(UI)或,为了更灵活和可编程的方法,您可以使用 API 来创建 Databricks Lakehouse 监控器。当您想要编写脚本来创建监控器并将其集成到自动化数据管道中时,API 方法特别有利。以下是用 API 创建 Lakehouse 监控器步骤的高级概述:
-
Snapshot、TimeSeries和Inference。每种类型适用于不同的监控场景,其中TimeSeries和Inference类型需要时间戳列。推理配置文件还需要prediction_col和model_id_col。 -
使用
lakehouse_monitoring模块调用create_monitor函数,提供您的表的目录模式、表名、选择的配置文件类型以及监控器结果的输出模式。 -
MonitorCronSchedule对象,它接受 cron 表达式和时间区域 ID。 -
控制访问:创建监控器后,您可以使用 Unity Catalog 权限管理结果指标表和仪表板的访问权限。
-
run_refresh函数用于刷新和更新指标表。您还可以使用get_refresh函数检查特定运行的状况,并使用list_refreshes列出与监控器关联的所有刷新操作。 -
get_monitor函数允许您检索监控器的当前设置以供审查。
图 4**.4 展示了如何使用 Lakehouse 监控 API 创建 TimeSeries 配置文件监控器的示例:

图 4.4 – 创建简单的 TimeSeries 表监控器
在使用 Databricks Lakehouse 监控建立稳健的数据质量监控框架后,我们可以专注于增强我们的数据探索。这使我们转向 Databricks 助手,这是一个专门帮助开发者提高 Databricks 生产力功能。
使用 Databricks 助手探索数据
Databricks 助手是一个旨在提高你在 Databricks 中生产力的功能。它具有许多功能,包括从英语生成 SQL、解释代码、帮助调试错误和优化代码。随着更多功能的出现,Databricks 助手是一个令人兴奋的功能,我们希望让你体验一下这些可能性。由于本章是关于探索和监控数据,让我们看看你如何使用 Databricks 助手作为低代码解决方案来探索你的数据。假设你正在分析 Favorita 销售预测数据。你希望了解不同地区零售商店的分布情况。你心中有一个特定的查询:你想要了解瓜亚斯地区的商店格局。然而,SQL 查询并不是你的强项,也许编写完美的查询看起来很令人畏惧。为了探索你的数据,你可以使用 Databricks 助手。本节的项目仓库中没有笔记本,但我们鼓励你尝试在 Favorita 预测项目表上使用 Databricks 助手。任何 第四章 的 Favorita 笔记本都是一个很好的地方来访问 Databricks 助手。要访问它,点击笔记本左侧侧边栏中显示的图标(图 4**.5),点击图标将打开笔记本左侧的聊天界面,我们将在此处输入我们的问题。

图 4.5 – Databricks 助手图标
首先,我们向 Databricks 助手询问在 favorita_stores 表中(图 4**.6)有多少家商店和商店类型。请注意,Databricks 助手不需要 Unity Catalog,但使用 Unity Catalog 可以提供表信息。额外的信息使得 Databricks 助手的回答更加有用,并且更具体于你正在处理的表。这应该听起来类似于 检索增强生成(RAG)项目。我们通过提供相关信息来增强答案的生成。现在,让我们看看它是否可以帮助我们编写所需的 SQL 查询。记住,Databricks 助手由 生成式 AI 驱动,因此当你自己使用它时可能会看到不同的输出。

图 4.6 – 与 Databricks 助手的提问和回答交互
太好了!Databricks 助手给了我们一些 SQL 代码,可以直接粘贴到笔记本中并运行。然而,快速浏览查询后,我们发现我们只能得到商店和类型的唯一计数,而不是查看我们想要的商店类型分布。让我们完善我们的问题,然后再次尝试(图 4**.7)。

图 4.7 – 提交给 Databricks 助手的更新问题及其结果
在 图 4.7 中提交第二个问题后,Databricks 助手提供了一个新的查询,准确地捕捉了我们想要了解的内容。为了确保这一点,让我们复制提供的 SQL 代码,将其粘贴到笔记本中,并运行它。

图 4.8 – Databricks 助手生成的 SQL 查询结果
现在,我们看到瓜亚基尔地区的商店类型分布,正如我们希望的那样。Databricks 助手是一个实用的工具,我们可以确认玩弄它也是一件有趣的事情!我们鼓励您亲自尝试,看看您如何可以使用英语来探索您的数据。
Databricks 助手还为您的表格和字段生成注释建议。从之前探索的 favorita_stores 表格中,我们在 图 4.9 中看到 Databricks 助手为表格注释提出了建议,以帮助其他人理解表格的内容。

图 4.9 – Databricks 助手建议一个描述性的表格注释
Databricks 助手还可以通过在表格的“列”标签页右侧选择“AI 生成”按钮为表格中的每个字段生成描述性注释。您可以接受或编辑建议的注释。您可以通过选择“隐藏 AI 建议”按钮来关闭建议,如图 图 4.10 所示。10*。

图 4.10 – Databricks 助手为表格中的列建议注释
生成的注释可能看起来像是超出了了解您数据的范围,但文档对于使您的数据更容易被其他人发现至关重要(并且我们希望其他人也能使用生成的注释,这样您就可以更轻松地探索他们的数据集)。您越快了解一个数据集,就越容易进一步探索这些数据。
当您更喜欢用英语而不是直接编写代码来分析数据时,Databricks 助手是分析您数据的一个很好的方式,并且当您心中已有具体问题时。现在让我们讨论另一种更广泛的 探索性数据分析(EDA)方法:使用 AutoML 自动生成的笔记本。
使用 AutoML 生成数据概要
我们在第一章中介绍了 Databricks AutoML。这个工具自动化 ML 开发并增强数据科学工作流程。AutoML 最出名的是生成模型,但我们将会在第六章中讨论建模。由于我们正在讨论了解您的数据,我们首先想关注 AutoML 中内置的一个极其有用的功能,这个功能通常被忽视:自动生成的 Python 笔记本。除了为每个运行的实验提供笔记本代码外,AutoML 还提供了一个用于数据探索的笔记本。我们将直接进入创建 AutoML 实验,查看数据探索代码,然后稍后再返回探索建模部分。
我们将在 Favorita 项目笔记本中介绍如何通过 API 创建 AutoML 实验。我们鼓励您遵循这里的说明,使用 AutoML UI 设置一个简单的回归实验,这样我们可以查看创建的数据概要。在您开始之前,请确保您有一个 DBR ML 9.1+集群正在运行(您可以使用第二章中设置的DBR ML 14.2集群):
-
启动实验:导航到平台左侧导航栏上的实验标签页。点击AutoML 实验按钮以启动新实验。
-
ml_in_action.favorita_forecasting.favorite_train_set表,或您自己的数据(只需确保如果Regression不适用,更新问题类型)。 -
预测目标:选择您数据集中想要预测的特定列。AutoML 过程将使用您数据集中的其他列来尝试预测目标列中的值。如果您正在跟随 Favorita 场景,请选择销售。
图 4.11 展示了使用favorite_train_set训练表进行 AutoML 实验的配置。它说明了您如何自定义 AutoML 过程以适应您 ML 任务的特定要求。通过选择适当的问题类型、数据集和预测目标,您指导 AutoML 系统如何进行模型构建过程。

图 4.11 – 使用 Favorita train_set 表的 AutoML 实验配置
一旦您填写了 UI 并指定了 Favorita 表(或您选择的另一个表)作为您的输入训练数据集,请点击屏幕底部的开始 AutoML。AutoML 实验可能需要数小时才能完成,因为评估指标的改进仍在继续,尽管您可以通过更改超时值(在高级 配置下找到)为实验设置较短的时间限制。实验开始时,将打开一个新页面,显示进度更新。一旦实验完成,您将看到两个数据实体的链接:包含最佳模型代码的笔记本,标记为查看最佳模型笔记本,以及数据探索笔记本,标记为查看数据探索笔记本,如图图 4.12所示。

图 4.12 – 包含查看最佳模型笔记本和数据探索笔记本链接的 AutoML 实验页面
探索笔记本使用ydata-profiling(以前称为 pandas 的 profiler 库)生成统计数据并总结表中的所有字段数据。它还提供有关具有高度相关问题的字段的警报,这可能会对模型产生负面影响。这些警告也显示在 MLflow 实验 UI 中,如图图 4.13所示。

图 4.13 – 实验运行期间调用的 AutoML 警告
查看数据探索笔记本,以了解您数据的概览,从汇总统计到每个变量的详细配置文件。
我们现在已经探索了两种数据探索工具:Databricks Assistant 和ydata-profiling库。这些是许多经典机器学习项目开始的绝佳选择。接下来,我们将讨论更高级的数据格式以及如何使用 DI 平台来探索它:数据嵌入和向量搜索。嵌入是高级转换,将复杂、非结构化数据转换为有利于机器学习算法的数值格式,捕捉数据中的复杂关系,这对于复杂模型至关重要。
使用嵌入来理解非结构化数据
到目前为止,我们关注的是如何探索您的结构化数据。那么非结构化数据,如图像或文本呢?回想一下,我们在 第三章 的 RAG 聊天机器人项目工作中将 PDF 文本块转换为称为嵌入的特定格式。我们需要嵌入,即数据的数值向量表示,以在文本块之间执行相似性(或混合)搜索。这样,当有人向我们的聊天机器人提问,例如“使用 LLM 的自动化技术对经济有什么影响?”时,聊天机器人将能够搜索存储在 arXiv 文章中的文本块,检索最相关的块,并使用这些块更好地回答问题。对于更倾向于视觉阅读的读者,请参阅 图 4**.14 中的数据准备工作流程。我们在 第三章 中完成了 数据准备 步骤。现在我们将运行工作流程中的剩余设置步骤。

图 4.14 – 向量数据库设置是支持 RAG 检索步骤的先决过程
嵌入是构建任何聊天机器人的基本部分。请注意您的嵌入模型,确保它与任务相关。您不希望构建一个旨在用法语回答问题的聊天机器人,但使用一个只知道英语的嵌入模型——您的聊天机器人的响应质量肯定会受到影响!
捕捉语言细微差别的嵌入对于聊天机器人理解和生成上下文相关的响应至关重要。同样重要的是您应用于向量数据库本身的搜索和过滤技术。向量数据库类似于 SQL 数据库,但它存储的是向量嵌入,而不是表格数据。然后搜索算法可以搜索这些嵌入。在 RAG 项目的最终流程中,用户的提问也被转换为嵌入,搜索算法使用这些嵌入在向量数据库中找到相似的嵌入。聊天机器人从向量数据库中获取最相似的嵌入,以帮助它为用户的提问构建响应。
让我们考虑一个好的向量数据库解决方案的要求:
-
检索质量:搜索算法返回的作为相关内容的嵌入的正确性和完整性
-
解决方案的可扩展性:根据应用程序接收到的请求数量和动态流量进行扩展的能力
-
可访问性:能够轻松访问、实时读取、写入和使用应用程序的能力
-
治理:使用与创建向量嵌入和模型所使用的原始源相同的访问控制来管理向量存储的能力
-
集成:能够轻松集成当前市场技术并消除拼接技术和解决方案所需的时间
使用嵌入和向量搜索是改进各种机器学习项目的强大方式。向量数据库有许多用途,其中最常见的是以下几种:
-
RAG 系统:向量搜索促进了高效的数据检索,随后这些数据被用于增强大型语言模型(LLM)的响应。通过向量搜索的结果增强 LLM,可以导致聊天机器人响应更加准确,并最小化 LLM 输出中的幻觉等错误。
-
推荐系统:电子商务和流媒体平台使用向量搜索进行高效的最近邻搜索,将用户行为与相关建议相匹配。
-
图像和视频识别:向量搜索促进了在图像和视频中快速搜索相似特征。
-
生物信息学:向量搜索可用于 DNA 序列比对和蛋白质结构相似性搜索等任务,以提升临床研究。
使用 Databricks 向量搜索增强数据检索
Databricks VS 正在改变我们为 LLM 精炼和检索数据的方式。作为无服务器相似性搜索引擎,VS 允许在专用向量数据库中存储向量嵌入和元数据。通过 VS,您可以从 Unity Catalog 管理的Delta表中生成动态向量搜索索引。使用简单的 API,您可以通过查询检索最相似的向量。
这里是 Databricks VS 的一些关键优势:
-
无缝集成:VS 在 Databricks 生态系统内和谐工作,尤其是在 Delta 表方面。这种集成确保了您的数据始终保持最新,使其为机器学习应用做好准备。使用 VS,您可以从源 Delta 表创建向量搜索索引,并在源表更新时设置索引同步。
-
简化操作:VS 通过消除管理第三方向量数据库的需要,显著简化了操作复杂性。VS 在无服务器计算上运行,这意味着 Databricks 为您处理基础设施管理。
-
增强的可扩展性:与独立的向量库不同,VS 提供了无与伦比的可扩展性。VS 轻松处理大规模数据,自动扩展以满足您数据和查询负载的需求。这种可扩展性对于拥有大量数据且具有复杂搜索要求的企业至关重要。
-
统一的数据资产管理:VS 与 Unity Catalog 集成;Unity Catalog 处理数据治理和访问控制列表。为了防止生产数据泄露,您可以使用 Unity Catalog 管理对 Databricks VS API 和底层数据库的访问。
-
模型服务集成:模型服务自动化了模型服务端点的查询,以生成嵌入,无需用户承担任何开销。
支持嵌入模型的灵活性
VS 的一个主要优势是它支持你选择的任何嵌入模型。VS 支持托管或完全管理的嵌入。托管嵌入是自行管理的。你创建嵌入并将它们保存在 Delta 表中。对于完全管理的嵌入,准备好的文本保存在 Delta 表中,嵌入由 Databricks Model Serving 创建。Model Serving 将使用你选择的模型将你的传入数据转换为嵌入。Databricks VS 可以通过 Databricks Model Serving 端点、基础模型 API(如第三章中所述)或外部模型支持任何模型。外部模型包括 SaaS 模型,例如 OpenAI 的 ChatGPT 和 Anthropic 的 PaLM。你可以通过 Databricks 统一模型服务网关连接外部模型。有关更多信息,请参阅“进一步阅读”中的“Databricks Model Serving 中的外部模型”。
设置向量搜索
如前所述,VS 是一个无服务器产品。因此,我们需要与我们的聊天机器人应用程序到向量数据库中存储的相关内容保持实时连接。我们将在“应用我们的学习”,“项目 – RAG 聊天机器人”部分再次介绍这一点,但如果你准备好设置自己的端点,你只需要几行代码,如图4.15所示。

图 4.15 – 创建 Databricks VS 端点
一旦创建端点,你就可以在单个端点下托管多个向量搜索索引。端点将根据需求进行扩展。托管第一个索引的代码在“应用我们的学习”部分中展示)。
每个端点可以创建索引的数量和嵌入维度有限制。请查阅“进一步阅读”中链接的文档,因为随着产品的演变,Databricks 可能会删除或更新限制。
技术发展迅速,尤其是在生成式 AI 的世界里。Databricks VS 就是在撰写本书的同时被构建的,我们预计它将继续发展,未来不仅能够通过文本搜索,还能通过更强大的混合搜索引擎搜索图像和音频。
我们已经介绍了各种 Databricks 产品功能,旨在帮助你理解你的数据。准备好跟随我们在自己的 Databricks 工作区中工作,通过项目来执行第四章的代码,并将这些概念付诸实践。
应用我们的学习
是时候将这些概念应用到我们的示例项目中了。我们将利用所学知识来探索每个项目数据集,从使用 Databricks 助手到 AutoML,再到创建向量搜索索引和探索图像数据。
技术要求
在开始之前,请回顾并准备本章动手工作所需的技术要求:
-
我们使用
missingno库来解决合成交易项目数据中的缺失值:pypi.org/project/missingno/ -
对于 RAG 项目,你需要在你的集群或
CH4-01-Creating_VectorDB笔记本中安装以下内容。如果你选择在笔记本中安装它们,代码已经为你准备好了:-
typing_extensions==4.7.1 -
transformers==4.30.2 -
llama-index==0.9.3 -
langchain==0.0.319 -
unstructured[pdf,docx]==0.10.30
-
项目 – Favorita Store Sales – 时间序列预测
对于 Favorita Store Sales 项目,我们使用许多简单的 DBSQL 查询进行数据探索,并了解数据集之间的关系。此外,我们使用ydata_profiling库以 HTML 格式生成数据配置文件,如图 4.19 所示。要在你的工作空间中跟随,请参考以下笔记本:
-
CH4-01-Exploring_Favorita_Sales_Data -
CH4-02-Exploring_Autogenerated_Notebook -
CH4-03-Imputing_Oil_Data
在上一章中,我们创建了 Kaggle 的 Favorita Sales Forecasting 数据集的表格。现在,是时候探索了!打开第一个笔记本,CH4-01-Exploring_Favorita_Sales_Data,在 SQL 中进行一些初步的数据探索:
- 第一个单元是一个简单的
select *SQL 命令。运行单元后,关注单元格内的数据配置文件和可视化选项。

图 4.16 – 你可以在笔记本中创建 SQL 查询结果的视觉化和数据配置文件
-
选择数据配置文件并调查自动生成关于数据的信息。
-
选择可视化。你可以创建一个以日期(月份)与销售额总和的折线图,并按系列分组。请注意,并非所有数据都用于生成可视化;我们最初只看到 1 月。一旦保存可视化,图表将显示在单元格中。可视化底部的数据截断消息应该存在。要增加图表中的记录数,请选择在更多数据上聚合。
-
继续尝试不同的选项。在下一个单元中,我们将筛选出表现最好的产品系列。研究不同的图表看起来如何或有多相似。
现在我们已经对 Favorita 数据进行了初步探索,我们可以运行一个 Databricks AutoML 实验来生成一个基线模型。AutoML 可以在 UI 中启动,我们之前在本章的使用 AutoML 生成数据配置文件部分(图 4.11)中演示了这一点,或者你可以通过 API 创建一个实验,如图 4.17 所示。对于这个项目,我们将启动一个回归实验和一个预测实验。让我们从回归运行开始。
注意,在笔记本的顶部,默认语言是 SQL 而不是 Python。因此,当我们想要执行 Python 代码时,需要在单元格顶部包含%python。我们在第一个笔记本的最后一个单元格中使用 Python 进行 AutoML。我们将timeout_minutes变量设置为30,因此实验将运行最多 30 分钟。然而,如果验证指标不再提高,AutoML 将停止训练模型。在这种情况下,实验将提前完成。一旦运行完成,笔记本 UI 将显示链接到 MLflow 实验,其中可以访问模型版本,最佳试验笔记本包含最佳模型的代码,以及数据探索笔记本。由于本章重点在于探索数据,我们现在只打开数据探索笔记本。

图 4.17 – 从笔记本创建 AutoML 实验
数据探索的 AutoML
当你在CH4-01-Exploring_Favorita_Sales_Data中的最后一个单元格执行操作时,你会在结果中收到几个链接,如图 4.17所示。点击数据探索笔记本的链接(您也可以打开CH4-02-Exploring_Autogenerated_Notebook以查看我们在运行 AutoML 实验时自动生成的版本)。让我们看看这个笔记本。

图 4.18 – 使用 AutoML 创建的 EDA 笔记本
图 4.18显示了自动生成数据探索笔记本的一部分。该笔记本导入库并指向训练数据。它还自动将日期时间列转换为 pandas 日期时间。
该笔记本使用基于 pandas 的库,因此笔记本限制了数据为 10,000 行。
接下来,笔记本导入了ydata_profiling库,以及在此情况下添加的三个额外的相关性计算。ydata_profiling库提供了类似于使用summary()函数所获得的数据,例如关于缺失和相关性数据的详细信息。该库可以轻松导入笔记本以探索数据。一旦完成,您可以将其导出为 HTML 或 PDF 格式,以便轻松分享。在探索新数据集时,这是一个节省时间的好方法。

图 4.19 – AutoML 创建的笔记本中的 ydata_profiling
如图 4.17所示,我们通过调用automl.regress()通过 API 启动了一个回归实验。现在,我们使用 UI 创建另一个具有预测问题类型的实验。

图 4.20 – 在 UI 中创建 AutoML 预测实验
当我们创建一个 AutoML 预测实验时,我们可以在高级配置部分的国家假日选项中将一个国家的假日纳入模型。对于这个项目,我们将选择NONE,因为尽管在下拉菜单中有许多国家,但厄瓜多尔不在其中。NONE将确保假日不会被包括在模型的特征中。

图 4.21 – AutoML 预测实验高级配置
一旦所有字段都填写完毕,点击屏幕底部的开始 AutoML以运行实验(如果您想确保在给定时间内完成运行,请将超时变量调低)。当实验运行完成后,您将看到一个新屏幕,其中列出了生成的模型列表。
我们现在已经在笔记本中创建了一个 AutoML 实验,使用 AutoML 生成了一个用于 EDA 的笔记本,并使用 AutoML 进行时间序列分析。Databricks AutoML 通过最少的代码为 ML 和 EDA 做了很多繁重的工作。
The Favorita sales dataset contains oil prices, which we think could impact sales, so let’s augment the autogenerated data exploration with some of our own to explore the oil price data and see how we can use it.
探索和清理油价数据
要开始处理油价数据,请打开CH4-03-Imputing_Oil_Data笔记本。我们使用 Spark 上的 pandas API 查看数据(图 4.22)。我们重新索引数据,因为数据顺序混乱,并且某些日期的数据缺失。注意,最初数据从 2015 年 5 月开始,而不是从 2013 年 1 月开始。此外,5 月 9 日和 5 月 10 日似乎缺失。

图 4.22 – 在 Favorita 销售数据集中查看 Kaggle 提供的油价数据
如果我们将date列作为索引列,如图笔记本所示,您会看到行随后是有序的。然而,1 月 5 日和 1 月 6 日是缺失的。这是因为假日或周末没有提供股票价格。

图 4.23 – 通过重新索引包括所有日期并向前填充缺失的价格
我们使用reindex()命令根据油价数据的最早和最晚日期创建一个更新的索引。reindex 为所有缺失的日期创建行。当为缺失的日期创建新行时,价格是 NaN。我们使用ffill()函数,即前向填充,通过用前一天的价格填充没有价格的日期来更新 DataFrame。2013 年 1 月 1 日没有前一天的数据可以填充,所以它仍然是NaN。
现在,我们有一个干净且一致的油价银表,我们可以将其拉入我们的 Favorita 时间序列模型中。在下一章中,我们将使用 Favorita 销售数据进行特征工程。
项目 – 流式事务
合成数据集不需要清理(因为我们创建了它),但我们仍然可以探索数据以更好地理解它。要在您自己的工作区中跟随,请参考以下笔记本:
CH4-01-Exploring_Synthetic_Transactions_Data
打开笔记本,使用 seaborn 库生成如图 4.24 所示的视觉化。

图 4.24 – 合成事务数据的可视化
随意探索事务数据。接下来,我们将继续进行 RAG 聊天机器人。
项目 – RAG 聊天机器人
在上一章中,我们从我们的 PDF 文档中提取了文本块。我们使用 BGE 嵌入模型将这些块转换为嵌入。因此,我们现在已经准备好进行下一步,为检索准备我们的数据。要在您自己的工作区中跟随,请参考以下笔记本:
CH4-01-Creating_VectorDB
在 使用 Databricks Vector Search 增强数据检索 部分中,我们解释了 Databricks VS 是一个无服务器托管解决方案。换句话说,我们需要创建 VS 端点来托管我们的索引。

图 4.25 – 为 RAG 聊天机器人创建 Databricks VS 端点
作为提醒,我们将把我们在 第三章 中准备的源表导入索引,以便在聊天机器人应用程序中进行检索搜索。

图 4.26 – 读取包含文档文本的源表
我们从项目的 utils 文件夹导入函数,mlia_utils.rag_funcs。索引只需要创建一次。从现在起,我们只会写入它或从中读取。我们使用 if/else 语句来检查是否存在名为 catalog.database.docs_vsc_idx_cont 的索引。如果存在,我们只需将我们的 catalog.database.pdf_documentation_text 源表同步到它。

图 4.27 – 检查索引是否存在,如果需要则创建
在继续进行我们的聊天机器人项目之前,有几个关键点我们必须确保已经到位:
-
catalog.database.pdf_documentation_text是您使用自管理的嵌入函数准备的 Delta 表,作为其向量搜索索引的主要数据存储库。 -
使用 Databricks VS 的
catalog.database.docs_vsc_idx_cont。此索引链接到源 Delta 表。索引基于触发器基础更新(pipeline_type="TRIGGERED"),这意味着对历史文本的任何修改或新增都需要手动同步到您的向量搜索索引。如果您希望更改自动反映在向量搜索索引中,请选择CONTINUOUS模式。这种连续更新机制确保数据始终是最新的,并准备好进行分析。 -
text_chunks会自动通过 Databricks Model Serving 提供的模型转换为嵌入。这可以在设置中的embedding_model_endpoint_name参数下指定。这种集成保证了文本数据被高效地转换为向量,使其适合进行高级相似度搜索。
我们从 utils 文件夹导入 wait_for_index_to_be_ready() 函数。我们运行 图 4**.28 中的代码来反复检查索引的状态,直到它处于“在线”状态。由于 VS 索引只需要创建一次,这个函数在嵌入到达您的 VS 索引之前可能需要一些时间。一旦您的索引处于“就绪”状态,请继续操作。

图 4.28 – 索引等待函数检查索引状态,直到其上线并准备就绪
一旦索引上线,我们调用 get_index() 来执行相似度搜索。我们还调用 describe() 方法来展示您拥有的更广泛的 API 选项。

图 4.29 – 使用 get_index 和 describe 方法显示索引配置
由于我们使用自管理的嵌入,我们的 VS 索引没有连接到任何可以将我们的输入文本查询转换为嵌入并映射到数据库下的模型,因此我们需要先进行转换!这里我们再次利用 Foundational Model Serving API 中的 BGE 嵌入模型,然后将嵌入文本传递到我们的索引进行相似度搜索:

图 4.30 – 将我们的查询文本转换为嵌入并传递到索引进行相似度搜索
这里是检索查询的结果(仅显示找到的第一个,包含两列 pdf_name 和内容):

图 4.31– 检索查询结果的样本
现在,我们的 VS 索引已准备好在我们的聊天机器人中使用。我们将在 第六章 中探讨如何连接所有工具以生成适当的人类可读答案!
项目 – 多标签图像分类
在上一章中,我们将图像数据保存到卷中。接下来,我们将探索数据。要在自己的工作区中跟随,请参考以下笔记本:
CH4-01-Exploring_Dataset
我们创建了图像训练数据集。打印标签和训练数据的一个样本,以便查看我们希望模型进行分类的内容。

图 4.32 – 加载并查看训练数据集
我们可以使用display_image来查看卷中的几张图片。

图 4.33 – 在笔记本中显示图像
了解我们数据不同标签的比例是很有帮助的。这样你可以查看训练数据集中数据的比例。无论你在哪里执行多标签分类,都要确保标签分布良好。否则,考虑训练单独的模型,这些模型可以组合或补充缺失的标签!

图 4.34 – 查看训练数据集中标签的比例
现在我们已经对图像分类数据集进行了高级探索。对于这个项目,不需要进行转换,因此我们接下来对这个数据的步骤将在第六章中。
摘要
在使用数据之前理解数据是至关重要的。本章强调了在 Databricks 生态系统中探索和分析我们数据的各种方法。
我们首先回顾了 DLT,这次我们关注的是如何使用一个名为期望的特征来监控和改进我们的数据质量。我们还介绍了 Databricks Lakehouse Monitoring 作为观察数据质量的另一个工具。在其众多功能中,Lakehouse Monitoring 可以检测数据分布的变化,并向用户发出异常警报,从而在整个生命周期中保持数据完整性。我们使用 Databricks Assistant 通过用英语编写的即席查询来探索数据,并展示了为什么 AutoML 是数据探索的一个极其有用的工具,因为它可以自动创建全面的数据探索笔记本。所有这些工具共同为您理解并探索数据提供了一个坚实的基础。最后,本章深入探讨了 Databricks VS,以及如何使用它来查找相似文档以改善聊天机器人的响应。
我们现在已经为数据旅程的下一阶段奠定了基础。第五章将专注于如何基于我们的青铜层数据构建丰富的特征集,用于数据科学和机器学习项目。
问题
以下问题旨在巩固需要记住的关键点,并将内容与你的个人经验联系起来:
-
本章我们讨论了哪些低代码的数据探索选项?
-
你可能在何时使用 Databricks Assistant 进行数据探索,何时使用 AutoML 的数据概览笔记本?
-
你会如何以及为什么对你的数据进行预期设定?
-
你会在什么情况下使用常规数据库而不是向量数据库?向量数据库的一些常见用例是什么?
答案
在思考过这些问题后,将你的答案与我们的答案进行比较:
-
一些低代码数据探索选项包括使用
ydata库、单元格数据概要、Databricks 助手和 AutoML。 -
当你对想要构建的分析有很好的想法并且需要代码辅助时,Databricks 助手对数据探索很有用。Databricks 助手是加快编码过程或增强 SQL 知识的好方法。另一方面,AutoML 对于自动创建一个广泛涵盖你的数据集的概要笔记本非常有用。
-
我们会使用 Delta Live Tables 来设定预期。预期是一种灵活处理数据异常并给出报告坏数据、丢弃该数据或完全失败管道的选项的方式。
-
常规数据库,或关系数据库,是为表格形式的数据设计的,通常按行或列组织。向量数据库是为存储向量数据而设计的,例如嵌入和高维数据。向量数据库针对基于向量空间模型、相似性搜索、图像和视频分析以及其他机器学习问题进行优化。一些常见用例包括检索增强生成(RAG)系统、推荐系统和图像和视频识别。
进一步阅读
在本章中,我们指出了具体的技术、技术特性和选项。请查看这些资源,深入了解你最感兴趣的领域:
-
在 DBSQL 中通过聚合启用可视化:
docs.databricks.com/sql/user/visualizations/index.html#enable-aggregation-in-a-visualization -
使用 ydata 分析器探索数据:
ydata-profiling.ydata.ai/docs/master/index.html -
推进 Spark - 认识新的 Databricks 助手:
youtu.be/Tv8D72oI0xM -
介绍 Databricks 助手,一个上下文感知的 AI 助手:
www.databricks.com/blog/introducing-databricks-assistant -
模型监控自定义指标 创建:
docs.databricks.com/en/lakehouse-monitoring/custom-metrics.html -
Databricks 向量搜索:
docs.databricks.com/en/generative-ai/vector-search.html -
Databricks 模型服务中的外部模型:
learn.microsoft.com/en-us/azure/databricks/generative-ai/external-models/
第五章:Databricks 上的特征工程
“应用机器学习基本上就是特征工程。”
– 安德鲁·吴
随着我们从第四章(我们利用 Databricks 探索和精炼我们的数据集)的进展,我们现在准备深入研究 Databricks 的组件,这些组件使下一步:特征工程成为可能。我们将首先介绍 Unity Catalog 中的Databricks 特征工程(DFE),向您展示您如何使用Unity Catalog(UC)高效地管理工程特征。了解如何在 UC 中利用 DFE 对于创建跨训练和推理的可重复和一致的特征至关重要。接下来,您将学习如何利用 Spark Structured Streaming 在流上计算特征,这允许您创建模型进行快速决策所需的状态化特征。特征工程是一个广泛的话题。我们将关注 DI 平台如何促进某些特征类别的开发,例如时间点查找和按需功能。您还将学习如何在模型推理期间实时计算特征,这对于需要即时数据处理的场景至关重要。我们将介绍的最后一个产品功能是Databricks 在线商店。您将了解如何使特征可用于实时访问,并增强低延迟应用中机器学习模型的响应性。
在本章中,您将学习以下内容:
-
Unity Catalog 中的 Databricks 特征工程
-
流式特征工程
-
使用时间点查找
-
计算按需特征
-
将特征发布到 Databricks 在线商店
-
应用我们的学习
Unity Catalog 中的 Databricks 特征工程
在本章中,我们将关注几种类型的特征。特征类型可以根据它们相对于模型预测时间的计算时间大致分组。本章中我们涵盖的三种类型是批量、流式和按需:
-
在我们的Favorita 销售预测项目中,
holidays字段,因为我们可以在需要之前计算它,并且不期望其值频繁变化。 -
流式功能:这些功能在数据管道中实时或接近实时地处理,作为源数据被摄取,允许连续和增量地创建特征。为了演示这一点,我们将使用 Spark Structured Streaming 为我们的流式事务项目计算一个流式特征。
-
按需功能:与批量或流式功能不同,按需功能仅在需要时计算,也就是说,在推理时。这些功能对于事先未知且必须实时计算的特征值场景至关重要。我们将深入探讨计算和存储这些功能的机制,展示它们的实现和集成到预测模型中。
任何具有定义好的主键约束的 Unity Catalog 表都可以是一个集中式仓库,用于存储和预计算(例如,批量或流式)的特征。这些类型的表,其明确目的是集中存储整个组织在分析、数据科学和机器学习项目中使用的特征,通常被称为特征表。特征表允许数据科学家共享他们构建的特征,并找到其他团队成员构建的特征。
它们是确保业务逻辑集中存储的绝佳方式,可以节省团队成员重新创建已创建的特征,并防止重复工作。此外,Unity Catalog 管理所有数据的可发现性、血缘和治理,因此您的特征表可以像任何其他表一样轻松管理。在 Databricks 中,任何具有非空主键的表都可以是特征表。虽然没有特定的 API 调用来列出所有有资格成为特征表的表或列出官方创建的特征表,但我们建议使用标签或命名约定来识别特征表。本书的示例项目将遵循在特征表名称末尾附加 _ft 的约定。Unity Catalog 中的特征工程提供了用于创建和更新特征表的 FeatureEngineeringClient Python 客户端(通常以别名 fe 导入)(图 5.1):

图 5.1 – 使用 FeatureEngineeringClient 创建特征表的示例
正如我们提到的,Delta、UC 和特征工程客户端的组合提供了相当大的好处。特征可以在团队间共享和重用,减少从头开始重新创建它们的需求。可重用性可以节省时间和资源,还可以帮助确保特征在不同团队间的一致性。集中式特征表确保相同的代码在训练和推理时计算特征值。这对于避免在线/离线偏差尤为重要——也就是说,当模型训练阶段(离线)使用的数据转换与模型部署和进行预测时(在线)使用的数据转换不同时,可能会出现的差异。图 5.2 展示了一个数据科学项目工作流程,并突出了必须匹配的离线和在线转换。

图 5.2 – 通过确保在训练数据和推理数据上执行的数据转换相同,你可以避免准确性问题
我们将通过将数据转换过程包装在 第六章 (Chapter 6) 中的打包模型中来防止 流式事务 项目的在线/离线偏差。一致性可以提高模型的准确性,因为它确保相同的输入在生产环境中产生与训练时相同的输出。
注意
对于熟悉 Databricks Feature Store 的人来说,你可能想知道为什么我们在这章中没有使用它。在 Unity Catalog 之前,Databricks Feature Store 通过添加血缘和元数据细节提供了巨大的价值。随着 UC 的发展,而不是有一个单独的特征存储产品,每个使用 UC 的表都自动具有这些附加的好处。原始的 Databricks Feature Store 已经被吸收到 UC 中。
在前面的 应用我们的学习 部分中,我们将使用 SQL 和 FeatureEngineeringClient 将我们的特征保存到特征表中。一旦存储,Unity Catalog 就可以轻松跟踪创建特征所使用的数据源以及使用每个特征的下游工件(例如模型和笔记本)。更好的是,当你使用来自特征表的特征训练集记录模型时,特征元数据会与生成的模型一起打包。当我们在 流式 事务 项目上工作时,请注意这一点。
流上的特征工程
在深入探讨流上的特征工程之前,我们想澄清 流式管道 和 流数据 之间的区别。如果你之前没有使用过 Spark Structured Streaming,它是一个建立在 Spark SQL 引擎之上的流处理引擎。它使得编写类似于为静态数据编写表达式的流计算或转换变得容易。结构化流管道可以处理批量或流数据。流管道具有检查点等元素来自动化数据流。然而,流管道并不一定总是运行;相反,它们只有在开发者选择时才会运行。相比之下,流数据(也称为 实时数据)是指持续生成并可实时或批量处理的数据。为了简化,可以将流管道想象成工厂中一系列自动化的传送带,用于处理(数据)物品。这些传送带可以根据需要打开或关闭。另一方面,流数据就像是一条不断堆积在生产线起点的物品的永不停止的流动。根据流量的多少,可能需要立即处理。在我们的 应用我们的学习 部分中的 流式事务 示例中,我们使用这些自动化的传送带(流管道)来有效地管理和转换这种连续流动的物品(流数据)成有用的形式。
流数据有多个好处:
-
即时洞察:流式数据允许您快速获得洞察力,并基于数据做出实时决策。速度对于时间至关重要的应用程序至关重要,例如金融交易或工业设备的实时监控。
-
最新分析:实时处理流式数据允许进行更当前的数据分析。实时分析可以帮助您在事件发生时发现模式和趋势,并采取主动措施解决潜在的数据质量问题。
-
提高效率:流式数据可以帮助组织通过快速响应事件并主动采取行动来提高效率。短响应时间可以提高客户满意度,减少停机时间,并提高生产力。
流式数据可以为那些需要快速处理大量数据并基于这些数据做出实时决策的组织提供显著的好处。然而,有一些转换需要更复杂的流式处理类型,特别是有状态的流式处理。有状态的流式处理是指消耗连续数据流并持久化过去事件状态的流处理。持久化状态使得流“知道”之前交易的信息。这在计算时间窗口内的聚合时特别有用,因为聚合需要从流中的上一个窗口中获取值。为了使这一点更清晰,我们在流式事务项目中提供了一个示例。在进一步阅读部分还有一个解释有状态流式处理的详细信息的视频链接。
注意
在开始向流式特征表写入之前,应该修改这些表。运行ALTER TABLE命令会导致流停止。但是,如果您必须修改表,您可以重新启动流。尽可能做好准备和提前规划!
DFE 客户端支持对基于时间的特征进行智能处理和查找,例如我们标记的时间流特征。接下来,让我们了解一下这个节省时间的产品特性。
使用时间序列特征表的时间点查找
时间序列特征表是 Unity Catalog 中具有TIMESERIES主键的任何表。这些表有资格进行时间点查找,这是一种查找正确特征值的机制。在training_sets之前,在第六章中,我们经常将表连接起来,将训练行与其特征值连接起来。然而,细粒度的事件时间戳不适合连接。这导致了将时间戳四舍五入到分钟、小时甚至天。根据用例,这种方法可能或可能不适用。例如,在*图 5**.3 中,基于TransactionTimestamp的连接在标准连接中是不现实的,因此可能会创建TransactionMinute或TransactionHour。
| 交易时间戳 | 交易分钟 | 交易小时 |
|---|---|---|
| 2023-09-03 19:23:09.765676 | 2023-09-03 19:23:00 | 2023-09-03 19:00:00 |
| 2023-09-03 19:23:09.765821 | 2023-09-03 19:23:00 | 2023-09-03 19:00:00 |
| 2023-09-03 19:23:09.765899 | 2023-09-03 19:23:00 | 2023-09-03 19:00:00 |
图 5.3 – 时间戳舍入示例,便于连接
通过使用点时间查找,可以解决这个问题,因为它会为您处理时间匹配。对于那些熟悉谁是价格先生(The Price Is Right)的人来说,它是指不超过最近的特征值。更具体地说,它将与事件时间戳的最新特征值匹配,而不会提供事件之后计算的特征值。您无需担心训练过程中的数据泄露。如果没有Timeseries主键,特征的最新值将被匹配。
注意
建议在时间序列表上应用 Z 排序以在点时间查找中提高性能。Z 排序在第七章中有介绍。
查找特征非常好,通常是您用例的最佳选择。然而,在某些数据科学和机器学习任务中,我们需要在事先没有数据的情况下快速计算特征值。对于这些项目,我们需要按需特征。
按需计算特征
在短时间内计算每位客户的交易数量以流式处理方式工作,因为我们只需要使用历史数据。当我们想要使用仅在推理时间才可用的特征时,我们使用按需特征,直到推理时间之前其值未知。在 Databricks 中,您可以使用 Python training_set配置创建按需特征,以创建训练数据集,正如您将在第六章中看到的。
让我们再次考虑流式事务项目。我们希望添加一个功能,用于比较产品销售价格与其历史最高价格,并将其作为训练数据的一部分来预测生成的分类标签。在这种情况下,我们只有在收到交易后才知道购买价格。我们将在应用我们的 学习部分中介绍如何为流式事务项目构建 Python UDF 以计算按需特征。
此外,我们建议您查看如何通过实时计算提高 Databricks AI 模型准确性和在 Databricks 上实时特征计算的最佳实践这两篇文章,以获取 Databricks 按需专家的深入建议;请参阅进一步阅读部分获取链接。
我们已经讨论了在 Unity Catalog 中保存功能到特征表,这是没有低延迟要求的应用的标准的“离线”模式。如果您的业务问题需要低延迟或快速结果,您需要在在线表中存储数据或实现 Databricks Feature Serving。特征服务可以提供函数以及预计算的特性。对于低延迟项目,我们推荐使用 Databricks 模型服务,因为它消除了对特征服务的任何需求。本书中我们不涉及特征服务,但如果您打算将模型外部发布到 Databricks,特征服务可能对您感兴趣。
接下来,我们将学习如何利用 Databricks 在线商店。
将功能发布到 Databricks 在线商店
如果您想使用实时服务功能,可以将功能发布到低延迟数据库,也称为在线商店。将特征表发布到低延迟数据库允许在模型推理期间自动查找特征。选择在线商店时有很多选项可供选择。典型的数据服务解决方案需要专家工程师选择合适的数据库进行在线访问,构建数据发布管道,并协调部署。部署后,有人需要监控、管理和优化向在线商店提供数据的管道。这就是为什么我们推荐 Databricks 自带的完全托管的无服务器在线商店,它直接集成到平台中。它自动将您的 Delta 特征表与在线商店同步,使得使用起来非常方便。Databricks 在线商店与 Databricks 模型服务集成,因此您无需离开 Databricks 就可以轻松设置在线商店。要创建在线商店,请转到计算标签页,选择在线商店,然后选择创建商店。下一步是输入您的在线商店名称,您可以根据每秒查找次数选择商店的大小,如图 图 5**.4 所示。

图 5.4 – 从计算屏幕创建在线商店
要将数据同步到您的在线商店,请转到商店中您想要的数据表格,然后从创建按钮左侧的热狗菜单中选择同步到 在线商店。

图 5.5 – 从表格同步数据到您的在线商店
您需要指定用于查找的主键,如果需要,还需要指定时间戳列,然后确认同步您的数据。

图 5.6 – 使用其主键确认在线商店
您可以在详情标签页上检查您在线商店的同步状态。

图 5.7 – 查看实验运行的笔记本 UI
同步您的表很简单。不需要额外的工程!一旦您的特征表建立并准备好用于 Databricks 在线商店,只需通过提供主键、时间戳列(如果适用)以及同步频率(图 5**.8)来同步表。

图 5.8 – 同步特征表到 Databricks 在线商店的 UI
在线商店非常适合在低延迟速度下访问时仅存储记录的最新特征值。常见的用例包括需要快速特征查找和向应用程序提供数据的模型。您可以使用 Delta Lake 变更数据馈送(CDF)充分利用 Databricks 在线商店,它跟踪 Delta 表中的行级更改。使用 CDF,您只需更新特征表中的更改值,而不是覆盖整个表或跟踪时间戳。因此,您需要与 Databricks 在线商店同步的数据更少。此外,我们可以在 Unity Catalog 中通过将特征表保存为具有主键的 Delta 表来声明特征表。此外,我们可以创建在线特征商店并将我们的表同步,以便在低延迟用例或向应用程序提供数据时使用特征。接下来,我们必须考虑如何在我们的训练数据集中使用特征。
我们已经介绍了保存特征表、构建流式特征、实现点时间查找、创建按需特征以及发布到 Databricks 在线商店的方法。现在是时候准备好在自己的 Databricks 工作区中跟随我们,在处理 第五章 项目代码时进行操作了。
应用我们的学习
现在我们已经了解了 DI 平台的特征工程组件,让我们将这些主题付诸实践,并在示例项目数据集上添加新特征,以增强数据科学项目。
技术要求
这里是需要完成本章动手实践所需的技术要求:
- 流式事务 项目需要的计算能力超过了单节点集群所能提供的。我们创建了一个多节点集群来解决这个问题。参见 图 5**.9 中我们使用的多节点 CPU 配置。

图 5.9 – 用于本书的多节点 CPU 集群配置(在 AWS 上)
- 我们将使用托管卷来存储清洗和特征化的数据。
项目 – 流式事务
如果您一直在跟踪前几章中的代码,那么现在,您已经有了所需的数据流。在本章中,我们将使用之前讨论的一些特征工程技术来增强这些数据。首先,我们将创建一个流式特征,用于计算每个客户在过去两分钟内到达的交易数量。
在我们深入之前,让我们回顾一下我们现在在哪里以及我们打算去哪里。

图 5.10 – Streaming Transactions 项目的项目管道
我们正在构建一个流式管道,将传入的交易处理成特征。我们将使用有状态的流式处理来计算在两分钟时间范围内每个客户的交易数量。由于流中的计算需要知道已经发生了多少交易以及何时交易超出了两分钟窗口,因此需要使用有状态的流式处理。这些信息被称为客户的“状态”。
流式特征和按需特征是在两个不同的笔记本中创建的。在代码仓库中,你有以下四个笔记本:
-
CH5-01-生成记录: 这个笔记本几乎与之前章节中使用的数据生成器相同。两个主要区别是现在记录中始终存在一个产品,并且总时间步数(即时间步的数量)已增加,以提供更长时间的流。 -
CH5-02-自动加载器: 对自动加载器笔记本唯一的更改是数据写入的位置。 -
CH5-03-FE 使用 Spark Structured Streaming: 这个笔记本在本项目的 使用 Spark Structured Streaming 构建流式功能 子节中进行了详细解释。代码是用 Scala 编写的。现在 PySpark 也支持有状态的流式处理。有关更多详细信息,请参阅本章末尾的 进一步阅读 部分。 -
CH5-04-构建最大价格特征表: 这个笔记本计算产品在时间窗口内的最大价格。计算出的价格将在本笔记本中创建的 Python UDF 推理时使用。
前两个笔记本几乎与上一章的对应笔记本相同,所以我们将不再介绍它们。我们从 CH5-03-FE_Using_Spark_Structured_Streaming 笔记本开始。
使用 Spark Structured Streaming 构建流式功能
我们计算过去两分钟内每个客户的交易数量,并将这个新特征称为 transactionCount,它在代码中是一个案例类。
| 客户 ID | 交易时间戳 | … | … |
|---|---|---|---|
| 1 | 2023-09-03 19:23:09.765676 | ||
| 4 | 2023-09-03 19:23:09.765821 | ||
| 2 | 2023-09-03 19:23:09.765899 |
图 5.11 – 包含对应于 readStream 的示例数据的表
我们需要根据 CustomerID 字段聚合来自输入流的交易,InputRow 案例类。图 5.11 展示了输入流的示例表。此外,一旦交易超出指定窗口,我们必须删除这些交易;我们将这些称为“过期交易”。这意味着我们必须为每个客户创建并维护一个状态,即 TransactionCountState 案例类。每个客户状态由 CustomerID、transactionCount 和包含每个交易发生时间的 transactionList 组成。图 5.12 是客户状态的视觉表示。当客户交易到达时,它作为客户状态的一部分被添加到交易列表中。

图 5.12 – 每笔交易更新客户状态
状态是通过将状态流式逻辑应用于输入数据来创建的。然后,使用客户状态来写入如图 5.13 所示的特征表 transaction_count_ft:
| CustomerID | transactionCount | eventTimestamp | isTimeout |
|---|---|---|---|
| 5 | 3 | 2023-09-03T19:24:14.388 | false |
| 2 | 4 | 2023-09-03T19:24:16.721 | true |
| 3 | 0 | 2023-09-03T19:24:16.720 | true |
图 5.13 – 这是应用状态流式转换后的结果表
图 5.13 中显示的特征表包括 CustomerID 引用、该客户的 transactionCount、eventTimestamp 和一个布尔变量 isTimeout。eventTimestamp 是特征记录被写入的时间。我们称之为 eventTimestamp,因为新的交易或超时可能会触发对客户状态/事件的更新。为了知道它是哪种类型的事件,我们包括 isTimeout。当没有新的交易发生,但 transactionCount 的值已更改时,会发生超时——这是计数已减少的指示。

图 5.14 – 状态流式转换的逻辑流程
图 5.14 直观地表示了应用于客户状态的更新逻辑。逻辑路径可以分解为以下步骤:
-
对于客户
c的n个新交易,transactionCount被增加n次。 -
然后,对于
transactionList中的每个transactionTimestamp,ti,我们将当前时间与expirationTimestamp(ti+windowMinutes) 进行比较,以确定transactionCount中记录的交易是否已过期:-
如果有任何交易已过期,我们将
transactionCount减少一次,并从transactionList中删除相应的transactionTimestamp。 -
如果没有事务过期或已过期的交易中的
transactionTimestamp已被删除,那么我们将新的transactionTimestamp添加到transactionList中,并写出客户记录。
-
既然我们已经概述了我们的转换目标,让我们看看代码。要在自己的工作空间中跟随,请参考以下笔记本:
-
CH5-01-生成记录 -
CH5-02-自动加载器 -
CH5-03-FE 使用 Spark结构化流 -
CH5-04-构建最大价格特性表
在开始执行笔记本 3之前,请打开笔记本 1和笔记本 2,并点击两个笔记本的运行全部。这两个笔记本重新启动我们需要运行的用于运行笔记本 3的数据流。然而,您不需要所有流都在运行才能运行笔记本 4。
我们将要跳入的代码位于CH5-03-FE 使用 Spark Structured Streaming笔记本中。我们从头开始,包括导入和 delta 配置,如下截图所示:

图 5.15 – 为优化写入和压缩设置 delta 配置
这些配置也可以在集群配置中设置,但我们已在图 5.15中明确指出。这些设置将自动将小文件集压缩成大文件,以便在写入时实现最佳读取性能。图 5.16主要显示了重置命令,这些命令可以在需要时从头开始:

图 5.16 – 将小部件值设置为 True 运行此单元格中的命令,删除输出数据,包括检查点,并删除表
在此代码片段中,我们定义必要的变量并创建我们的表。请注意,从设置文件传递的变量在 Python 和 SQL 中,这意味着它们在 Scala 中不可用。尽管所有三种语言都可以在笔记本中使用,但它们之间不共享常量或变量值。因此,我们在 Scala 中定义了我们需要的变量,以便在 Scala 笔记本中访问。我们设置了文件、输出路径和inputTable名称的卷位置:

图 5.17 – 在 Scala 中设置变量、常量和路径
注意,我们在图 5.18中启用了我们的流特性表transaction_count_ft的 CDF。如果需要,我们可以将此表发布到在线商店。此外,我们设置了要写入所有交易的表名transaction_count_history:

图 5.18 – 创建表并启用 CDF
接下来,windowMinutes常量是我们想要为每个客户聚合交易的分钟数,而maxWaitMinutes正如其名。这是流在写入状态前等待交易之前等待的分钟数。maxWaitMinutes的值应该始终小于windowMinutes的值:

图 5.19 – 为我们的流设置 windowMinutes 和 maxWaitMinutes
我们将启动FeatureEngineeringClient并设置特征表标签,这样我们就可以轻松地看到这些表与哪个项目相关联:

图 5.20 – 在我们的表上设置特征表标签
接下来,我们定义案例类结构。图 5.21 显示我们的案例类定义了我们的数据结构。这是因为 Scala 是一种静态类型语言。

图 5.21 – 定义支持每个客户 ID 聚合的类结构
在图 5.22中,我们看到addNewRecords函数。latestTimestamp是通过比较transactionCountState中的最新时间戳与新记录中的最新时间戳来计算的。这是以防我们收到数据顺序出错。最后,我们创建并返回新的TransactionCountState对象,包含新计算的latestTimestamp,并将两个记录列表合并:

图 5.22 – 定义添加新记录的函数
下一个函数,图 5.23,通过计算状态过期时间戳(最新时间戳减去交易计数分钟)从TransactionCountState中删除超过windowMinutes旧的记录。然后,它遍历当前交易的列表,并保留任何在过期时间戳之前发生的交易。这在上面的屏幕截图中有显示:

图 5.23 – 定义一个函数以删除过时的记录
updateState函数使用我们的辅助函数来更新客户状态。这是调用flatMapGroupsWithState的函数。updateState函数接收客户 ID、值和当前状态。CustomerID是我们分组的键。values是InputRow的迭代器。在图 5.11中,我们看到InputRow是一个包含CustomerID引用和交易发生时间的交易记录。updateState函数有两种行为。假设收到一个或多个针对给定CustomerID的InputRow记录。在这种情况下,它将那些记录添加到状态中,从状态中删除任何超过windowMinutes的记录,并计算交易计数。请参阅图 5.18中的笔记本代码。

图 5.24 – 如果状态未超时,updateState 函数接收并处理记录
另一方面,如图 5.25 所示,如果在调用此函数后的一个分钟内没有接收到针对特定 CustomerID 的记录,它将删除状态中任何早于 windowMinutes 的记录,并调整计数:

图 5.25 – 如果状态未超时,updateState 函数接收并处理记录
注意,在 updateState 函数开始时创建的 transactionCounts 列表缓冲区作为迭代器返回。在这种情况下,输出将包含一条记录:特定客户的交易计数记录。
接下来,当我们准备创建读取流时,我们定义我们需要的读取流输入模式;参见图 5.26:

图 5.26 – 读取流输入模式
我们现在必须创建流的读取和写入组件。读取流读取我们在 第三章 中创建的 Delta 表。回想一下,我们通过流式传输 JSON 文件并将它们写入我们的 inputTable 来创建 Bronze 层。readStream 和 writeStream 代码很长,所以我们将在以下步骤中将它们分成更小的部分:
- 你应该从前面的章节中认出这一点。区别在于我们使用
selectExpr来隔离CustomerID和TransactionTimestamp。此外,我们特别设置了输出数据框的类型,使其符合flatMapGroupsWithState所期望的案例类:

图 5.27 – InputDF 是一个读取我们在第三章创建的表的读取流
- 我们将水印和
flatMapGroupsWithState函数应用于inputDf。在 Spark Streaming 中,水印是一个时间阈值,用于确定允许的延迟事件的最大延迟。我们允许数据在丢弃之前晚到 30 秒(参见 Thomas Treml 的文章《Spark Structured Streaming 中的水印》:towardsdatascience.com/watermarking-in-spark-structured-streaming-9e164f373e9)。flatMapGroupsWithState函数是一个任意有状态的流聚合操作符。它将我们的updateState函数应用于每个事务的微批,同时维护每个客户 ID 的状态:

图 5.28 – 将水印和 flatMapGroupsWithState 函数应用于 inputDf
- 我们为
foreachBatch函数定义了updateCounts函数,用于更新写入流中的计数。它将新事务计数上提到transaction_count_ft表中;这是 CDC 组件:

图 5.29 – updateCounts 函数将新事务计数上提到 transaction_count_ft 表中
- 流的最后一部分是写入,或者更确切地说,是更新。写入流应用
updateCounts函数。Delta 表不支持直接进行流更新,因此我们需要使用foreachBatch函数。foreachBatch函数类似于流式for循环,将函数应用于流中的每个微批数据。这个写入流类似于flatMapGroupsWithState,但没有对数据进行分组或维护状态。我们只是在更新 CDC 结果表。请注意,检查点是由我们处理的,并且我们的流每 10 秒触发一次,这意味着每 10 秒是数据的新微批。查询名称是可选的。它会在 SparkUI 中显示。

图 5.30 – 写入流使用 foreachBatch 应用 updateCounts 函数
- 除了写入 CDC 表之外,我们还想保留事务值的历史记录:

图 5.31 – 写入流将所有 transactionCounts 值记录到 Delta 表中
- 在流运行期间,我们可以观察输出表,
transaction_count_ft。当你的流运行时,刷新表视图,以便你可以随着输入数据的变化跟踪输出变化:

图 5.32 – transaction_count_ft 表的快照
- 在流运行期间,你还可以观察流统计信息。这个视图可以通过展开结果部分找到。

图 5.33 – writeStream 的流实时统计
导航到目录视图,查看是否出现了两个新的表。这标志着我们的流功能完成。接下来,我们将构建一个 Python UDF。
使用 Python UDF 构建按需功能
让我们再创建一个使用按需特征工程的特征表。关注CH5-04-Building_Maximum_Price_Feature_Table笔记本。我们在本章早期部分简要介绍了一个场景,要求我们实时计算交易与最高价格之间的差异。这可能对建模很有用。为了将差异作为按需特征,我们执行以下操作:
- 计算滚动窗口中每个产品的最大价格。我们首先创建
time_window。我们想要过去三分钟内的最大价格:


- 现在我们有了窗口,我们可以计算并将最大价格保存到 DataFrame 中。通常,最大价格的价值不会发生剧烈变化,所以每小时是一个合适的时间框架。我们添加一个名为
LookupTimestamp的新时间列,用于连接。


- 接下来,让我们从我们的 DataFrame 中创建一个新的特征表。我们将假设特定产品的最大价格变化不足以每小时计算此值,因此我们可以将此表设置为按固定时间表更新。在 GitHub 代码中,我们将实例化
FeatureEngineeringClient。在图 5.36 中,我们使用它将新的特征表作为 Delta 表写入 Unity Catalog:

图 5.36 – 将我们的表写入 Unity Catalog 中的 Delta 表
- 接下来,我们需要一个 Python UDF 来计算折扣或交易金额与产品最大价格之间的差异。我们将将其命名为
product_difference_ratio_on_demand_feature。我们可以使用相同的笔记本在 Unity Catalog 中相同的目录和架构下构建和保存这个简单的函数。


- 一旦我们运行此代码,我们就可以导航到 Unity Catalog 并看到
product_difference_ratio_on_demand_feature被列出。它已准备好在训练集中使用!我们将在第六章中引用此函数。


有了这些,我们已经为我们的流式交易数据集构建了特征。我们通过一个名为transactionCount的流式特征和一个按需特征函数丰富了原始数据,我们将使用这些特征在下一章构建训练数据集。
在下一节中,我们将汇总商店销售数据并将其保存到特征表中。
项目 – Favorita 商店销售 – 时间序列预测
在第四章中,我们使用 AutoML 探索了Favorita 销售数据集并创建了一个预测销售的基线模型。要在您自己的工作空间中跟随,请参考以下笔记本:CH5-01-Building –Favorita –``Feature Tables。
要创建 Databricks 特征表,我们可以使用 Python(通过 FeatureEngineeringClient)或 SQL。本章主要使用 Python,但我们首先使用 SQL 创建一个 stores_ft 特征表:

图 5.39 – 使用 SQL 从 favorita_stores 表创建 stores_ft 特征表
执行 图 5.39 中的代码将创建一个名为 stores_ft 的特征表,我们将将其用作重要店铺细节的中心存储库。store_nbr 被设置为 NOT NULL,因为它是主键。该表不包含日期列,因此这个特征表不是一个时间序列特征表。如果它包含日期列,我们可以包括一个额外的 TIMESERIES 主键。请注意,当将主键添加到表中时,您可以根据文档中的说明为约束命名一个唯一名称。我们更喜欢让 DFE 客户端自动命名约束。您可以使用 DESCRIBE TABLE EXTENDED 来查看您的主键约束名称。
剩下的两个特征表是时间序列表。经过一些转换后,我们将使用 Python 和 DFE 客户端创建特征表。让我们首先关注节假日。

图 5.40 – 节假日事件表
我们创建的特征包括各自店铺的本地、区域和国家节假日。我们可以查看 图 5.40 来回忆节假日数据的样子。
关于我们的数据,有一点需要注意,那就是有几天对于同一店铺会发生多个节假日。我们非常相似地处理三种类型的节假日。由于不需要在区域上进行匹配,国家节假日的转换略有不同。所有节假日转换都在 GitHub 代码中。然而,在书中我们没有详细说明每个转换。
以下步骤将引导您完成用于节假日特征表的本地节假日类型的转换:
- 我们通过单独识别本地区域并将类型重命名为
holiday_type来开始本地节假日的 ETL:

图 5.41 – 隔离本地节假日
使用在 步骤 1 中创建的青铜表,我们构建一个银色表,包含日期、店铺编号和本地节假日类型。我们必须考虑到同一店铺在同一天发生多个本地节假日的问题。我们通过使用 MIN 函数进行分组来选择节假日类型。使用情况语句将本地节假日类型更改为 Multiple,而 num_holidays 负责这些实例:

图 5.42 – SQL 检查多个节假日实例,并为本地节假日识别新的节假日类型
结果银色表如图 图 5.43 所示:

图 5.43 – local_holidays_silver 表的前五行
- 在前一步骤中完成区域和国家假日的相同过程后,我们将银色表格合并成一个 DataFrame。我们使用完全连接来包含所有假日。为了避免
null日期并存储数字,我们链式使用两个ifnull()函数:

图 5.44 – 将所有三个银色表格合并成一个 DataFrame
- 现在我们已经准备好了我们想要保存的特征 DataFrame,我们使用 DFE 的
create_table方法将 DataFrame 保存为特征表。我们指定primary_keys。请注意,我们不包括时间序列列。这是因为我们希望特征表查找仅匹配确切的日期。假日与点时间逻辑结合使用效果不佳。在下一章创建训练集时,主键也将是我们的查找键。一个最佳实践是包括一个深思熟虑的描述。

图 5.45 – 使用 DFE 客户端创建商店假日特征表
- 注意,在我们的特征表 图 5.46 中,当没有特定类型的假日时,存在
null值。当我们创建训练集时,特征查找功能将为不在表中的日期的值返回null。我们不需要为每个非假日日期创建null行,从而节省预处理时间。

图 5.46 – store_holidays_ft 特征表
- 除了假日和商店数据外,我们还提供了石油价格数据。我们可以使用这些数据作为经济的代理。让我们使用
oil_price_silver表创建一个额外的特征表。与store_holidays_ft不同,在null的位置拥有股票价格的先前值将是有帮助的。这是一个使用点时间查找功能的合适示例。为此,需要一个第二个主键。因此,我们将日期作为主键,但不作为timeseries_column,如图 图 5.47 所示:

图 5.47 – 从石油价格创建特征表
我们有多个特征表,我们可以使用 Kaggle 或任何其他相关训练数据提供的特定训练数据。例如,oil_10d_lag_ft 可以用作基于厄瓜多尔的任何数据集的经济代理。
为了未来的建模,使用 DFE 客户端将特征保存到特征表中将是有帮助的。这样做使得在推理时间查找特征与模型无缝对接。在下一章中,我们将使用 DFE 客户端将我们的特征表组合起来,为我们的模型创建训练集。
摘要
当我们总结 第五章 时,我们已经成功穿越了 Databricks 上特征工程的多元领域。我们学习了如何通过确保有一个非空主键,将我们的特征组织成特征表,无论是使用 SQL 还是 Python。Unity Catalog 提供了血缘和可发现性,这使得特征可重用。在继续进行流式项目时,我们还强调了使用有状态流创建流式特征。我们提到了 Databricks 最新的特征工程产品,如点时间查找、按需特征函数以及将表发布到 Databricks 在线商店。这些产品功能将缩短生产时间并简化生产流程。
你现在可以应对各种场景的特征工程了!接下来,我们将所学知识用于在 第六章 中构建训练集和机器学习模型。
问题
以下问题有助于巩固关键点并使内容与你的经验联系起来:
-
Delta 格式的哪个元素有助于可重复性?
-
你会选择将特征发布到在线商店的一些原因是什么?
-
你会如何使用特征工程 API 创建训练集?
-
在 Unity Catalog 中,特征表与任何其他表有什么区别?
-
在 应用我们的学习 的 流式事务数据集 部分,我们创建了一个经过转换的流。创建此管道的业务驱动因素可能是什么?我们完成了 如何做;那么 为什么 呢?
答案
在思考了这些问题之后,比较你的答案和我们的答案:
-
Delta 的时间旅行能力有助于可重复性。Delta 具有版本控制,允许我们进行点时间查找,查看我们的模型训练了哪些数据。对于长期版本控制,深度克隆或快照是合适的。
-
将数据写入在线商店为实时推理模型提供实时特征查找。
-
为你希望包含的每个特征表创建
FeatureLookups。然后,使用create_training_set。 -
特征表有一个唯一的主键,它表示特征所描述的对象或实体。
-
可能性是无限的。一个例子是行为建模或客户细分以支持欺诈标记。
进一步阅读
在本章中,我们确定了特定的技术、技术特性和选项。请查看这些资源,深入了解你最感兴趣的领域:
-
Databricks AI 如何通过实时 计算 提高模型精度:
www.databricks.com/blog/how-lakehouse-ai-improves-model-accuracy-real-time-computations -
使用 带时间点支持的 时间序列特征表:
docs.databricks.com/en/machine-learning/feature-store/time-series.html -
结构化流中的 Python 任意有状态处理 – Databricks 博客:
www.databricks.com/blog/2022/10/18/python-arbitrary-stateful-processing-structured-streaming.html -
Databricks 卷:
docs.databricks.com/en/sql/language-manual/sql-ref-volumes.html -
在 Databricks 卷中进行实验:
medium.com/@tsiciliani/experimenting-with-databricks-volumes-5666cecb166 -
优化有状态结构化流 查询:
docs.databricks.com/en/structured-streaming/stateful-streaming.html -
Databricks 博客 – 介绍适用于大规模数据湖的 Delta 时间旅行:
www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html -
YouTube 视频 – 由 Burak Yavuz 演讲的 Apache Spark 中的结构化流任意有状态聚合:
youtu.be/JAb4FIheP28?si=BjoeKkxP_OUxT7-K -
Databricks 文档 – 使用 Python 用户定义的 函数 在需要时 计算功能:
docs.databricks.com/en/machine-learning/feature-store/on-demand-features.html -
Delta Lake 变化数据馈送(CDF):
docs.databricks.com/en/delta/delta-change-data-feed.html
第六章:寻找信号
在本章中,我们将介绍如何使用数据科学在数据的噪声中寻找隐藏的信号。
我们将在前一章中在 Databricks 平台上创建的特征的基础上进行操作。我们首先使用自动机器学习(AutoML)进行基本建模方法,这提供了自动生成的代码,并迅速使数据科学家能够建立基线模型以超越。在寻找信号时,我们尝试不同的特征、超参数和模型。从历史上看,跟踪这些配置及其相应的评估指标本身就是一项耗时的工作。MLflow 提供的低开销跟踪机制,作为一个开源平台,用于管理数据科学项目和支撑机器学习操作(MLOps),将减轻手动捕获配置的负担。更具体地说,我们将介绍 MLflow Tracking,这是一个显著提高跟踪每个排列的许多输出的 MLflow 组件。然而,这仅仅是开始。随着数据科学团队被要求利用生成式人工智能(GenAI),我们还将展示如何利用大型语言模型(LLM)创建 SQL 机器人以及使用 PyTorch 的深度学习(DL)模型。这些示例表明,除了构建我们自己的解决方案外,我们还可以将外部创新解决方案集成到我们的工作流程中。这种开放性使我们能够从两个世界的最佳之处进行选择。
作为本章的一部分,你将学习以下内容:
-
使用 AutoML 进行基线
-
超越基本分类
-
应用我们的学习
技术要求
这里是需要完成本章动手实验的技术要求:
-
Databricks ML Runtime:
-
AutoML
-
MLflow
-
Pandas -
Sklearn -
Torch
-
-
对于我们的 LLM 模型,我们将与来自OpenAI的ChatGPT模型(
openai.com/)集成 -
在构建用于帕金森病冻结步态(FOG)问题的分类模型时,我们将使用PyTorch Lightning AI Python 包(
www.pytorchlightning.ai/index.html)和TorchMetrics(torchmetrics.readthedocs.io/en/stable/)
使用 AutoML 进行基线
基线模型是一个简单的模型,用作机器学习的起点。数据科学家经常使用基线模型来比较更复杂模型的性能。基线模型通常是简单的或常见的算法,例如多数类分类器或随机森林。
基线模型有几个价值,其中一些如下列出:
-
它们可以帮助你理解在当前数据集下寻找信号的难度。如果即使是最好的基线模型表现不佳,这也可能表明更复杂的模型在寻找有用的模式(即垃圾数据输入,垃圾模型输出)时也会遇到困难。
-
基准模型可以帮助你识别对机器学习任务最重要的特征。如果一个基准模型表现良好,那可能是因为它可以从最显著的特征中学习。
-
基准模型可以帮助你避免过拟合。过拟合是更复杂模型中常见的问题。当模型对训练数据学习得太好,无法推广到新数据时,就会发生过拟合。你可以通过将更复杂模型的性能与基准模型进行比较来确定该模型是否过拟合。如果复杂模型在训练数据上的表现优于基准模型,但在未见过的测试数据上表现较差,那么你就知道你已经过拟合了。
创建基准模型有多种方法。一种简单直接的方法是使用随机模型。随机模型是通过随机分配标签到数据创建的。这类模型帮助你评估其他模型与随机猜测相比的表现。另一种常见的方法是使用多数类分类器。多数类分类器总是预测训练数据中最常见的类别,为你提供了一个可以与更复杂模型比较的简单算法。
在数据湖中,我们有 AutoML,这是获取基准的另一种简单直接的方法。这是我们最喜欢的开始机器学习任务的方法,因为它在模型选择上比更简单的基准选项给我们带来了先发优势。回想一下,我们在第四章中使用了 AutoML 来探索Favorita 销售数据。在生成那个探索笔记本的同时,AutoML 还生成了模型实验,这是我们目前关注的重点。
AutoML 可以快速探索许多模型/超参数排列,以找到最适合你数据的基准模型,以及评估指标和实际代码。一旦你创建了基准模型,你可以使用准确率、精确率、召回率、混淆矩阵、接收者操作特征(ROC)曲线等来评估其性能,从而选择最佳的实验。然而,重要的是要记住,AutoML 并不是万能的。它可以减少为实验编写多个算法的一些开销,但你仍然负责决定下一步的方向。幸运的是,AutoML 会自动在 MLflow 中跟踪这些模型工件,这正是 MLflow 的亮点。跟踪许多特征、模型、超参数和评估指标确实是个头疼的问题。使用 MLflow 原生地跟踪所有这些内容可以救命,所以让我们继续探讨这一点。
使用 MLflow 跟踪实验
MLflow 是一个开源平台,由 Databricks 开发,用于通过整个机器学习生命周期管理数据科学项目,从实验阶段到打包代码再到生产环境中的模型部署。我们将在后面的章节中介绍部署。现在,让我们专注于 MLflow 的跟踪组件(mlflow.org/docs/latest/tracking.html#tracking)。在我们有 MLflow Tracking 之前,ML 实验需要在实际实验之外做很多工作。MLflow Tracking 处理了在测试期间捕获特征、算法和超参数配置的开销。此外,在 lakehouse 中使用 MLflow,您将能够访问基于 MLflow 的托管 MLflow。Databricks 笔记本内置了集成,使得通过 Mlflow 的轻量级 API 或通过用户界面(UIs)程序化地管理和比较实验结果变得容易。例如,图 6.1显示了我们在笔记本中如何查看我们的实验运行:

图 6.1 – 查看实验运行的笔记本内 UI
在 MLflow Tracking 术语中,数据科学代码的执行被称为运行。每个运行可以记录以下内容:
-
参数:输入参数的关键值对,例如给定运行使用的特征或随机森林中的树的数量。
-
指标:评估指标,如均方根误差(RMSE)或ROC 曲线下面积(AUC)。
-
工件:任何格式的任意输出文件。这可以包括图像、pickle 模型和数据文件。
-
来源:运行实验的原始代码以及用于训练的数据的确切版本。
当你在笔记本中训练模型时,模型训练信息会自动通过 MLflow Tracking 进行跟踪。要自定义自动记录配置,请在训练代码之前调用mlflow.autolog()。请注意,尽管许多常见库都有自动记录支持(例如 Scikit-learn、XGBoost 和 Keras),但请查阅文档以获取完整列表:mlflow.org/docs/latest/models.html#built-in-model-flavors。
当你在特定的 ML 任务上工作时,将你的运行分组到“实验”中是有帮助的。这是一种比较运行的好方法,无论是通过程序化方式还是通过 Databricks 实验 UI。
在第四章和第五章中,我们使用了 AutoML 来构建传统的回归和分类模型。在下一节中,我们将深入探讨更高级的分类技术,以解决更复杂的商业问题。
超越基本分类
Databricks AutoML 产品是分类、回归和预测模型的良好起点。除了基于树的模型、梯度提升模型和逻辑回归之外,还有更多高级的分类技术可以使用 lakehouse,因为它旨在与几乎任何开源机器学习模型一起工作。
Databricks ML 运行时包括预构建的深度学习基础设施和库,如 PyTorch、TensorFlow 和 Hugging Face 转换器。深度学习模型计算密集,分布式深度学习(DDL)框架如 Horovod 也与这些深度学习库协同工作,以实现更高效的 DDL。务必查看 Databricks 上的新 PyTorch!有一个名为 PyTorch on Databricks – Introducing the Spark PyTorch Distributor 的博客,如果你在使用 PyTorch,这个博客会很有用(www.databricks.com/blog/2023/04/20/pytorch-databricks-introducing-spark-pytorch-distributor.html)。
另一种令人兴奋的机器学习类型是生成对抗网络(GANs)。对于那些不熟悉的人来说,GANs 是一种由两个神经网络(NNs)组成的生成模型——生成器和判别器。生成器网络学习生成与真实数据相似的人工数据,如图像或文本,而判别器网络试图区分真实数据和人工数据。GANs 已被用于图像合成、数据增强和生成逼真的深度伪造视频。我们过去曾使用 GANs 来挫败图像分类算法。目标是仅对图像进行足够的修改以混淆深度学习算法,但又不至于让人的眼睛能识别出图像已被修改。要了解 GANs 的其他应用,请观看来自 Data + AI Summit 2023 的这个精彩演讲:Generative AI at Scale Using GAN and Stable Diffusion (www.youtube.com/watch?v=YsWZDCsM9aE)。
集成创新
数据科学和机器学习的世界发展非常迅速。你可能会遇到一些可以从标准机器学习库之外的创新中受益的项目。例如,如果你想在一个使用文本数据的项目上工作,你将想要探索大型语言模型(LLMs)。LLMs 是一种在大量文本数据上使用深度学习技术训练的高级语言模型。幸运的是,Databricks 平台使得与 OpenAI 的 ChatGPT 和 Hugging Face 提供的其他选项等项目的集成变得容易。
接下来,让我们看看使用 LLM(大型语言模型)帮助商业用户或分析师从他们的表中获取信息而不需要知道 SQL 的一个示例。我们将使用 OpenAI 的生成式预训练变换器 4(GPT-4)作为数据分析师来构建聊天机器人。在这个例子中,您将创建指令,说明它如何请求表列表、从那些表中获取信息以及从表中采样数据。聊天机器人能够构建 SQL 查询并解释结果。要在示例中运行这些笔记本,您需要在 OpenAI 开发者网站(platform.openai.com)上有一个账户,并且必须为 OpenAI API 请求一个密钥。
在第一本笔记本中,sql_resource,我们将为聊天机器人创建指令和参考。
笔记本从带有关于响应和响应格式的提示的注释文本开始,如下所示:

图 6.2 – 聊天机器人的响应文本和响应格式
下面的行是您创建无效响应文本和聊天机器人响应格式的位置:

图 6.3 – 无效响应的文本和聊天机器人的响应格式
为了让您的聊天机器人理解数据环境,您需要创建一个目录并定义函数以识别您的表列表、表定义和模式,如下所示:

图 6.4 – 为聊天机器人定义表和表位置
现在,您的聊天机器人知道在哪里获取信息。为了与您的聊天机器人进行交流,我们需要教它如何进行对话。为此,我们定义了一个对话日志、对话函数以及将对话发送到 OpenAI GPT-4 模型的函数。这也是您可以更改聊天机器人使用的模型的地方:

图 6.5 – 定义提交对话到 OpenAI API 的函数
我们希望我们的聊天机器人构建 SQL 查询以从我们的表中获取数据,因此我们创建一个函数来教它如何构建 Spark SQL 查询:

图 6.6 – 处理 SQL 的函数
我们在图 6.6 中创建的函数只有几行代码,但它使聊天机器人能够有效地针对图 6.4 中定义的表构建 SQL 查询。现在,我们需要通过定义如何处理对话和创建响应来将这些功能全部结合起来:

图 6.7 – 处理请求和响应的函数
我们现在已经构建了聊天机器人,创建了聊天机器人与提示交互的初始语言,指定了可用的数据和表格,并展示了如何组装查询和响应提示。在下一节中,我们将开始与聊天机器人一起工作。
我们下一个笔记本是我们与聊天机器人交互的地方,它从安装 OpenAI 库开始:

图 6.8 – 安装 OpenAI 库
接下来,我们将从我们的sql_resource文件中调用我们定义的函数:

图 6.9 – 从 sql_resources 导入函数
在安装了库并加载了函数之后,我们已经组装了所有需要的部分来交互。我们首先使用startConversation()函数来与我们的聊天机器人开始对话:

图 6.10 – 与聊天机器人开始对话
我们在与聊天机器人交互时都经历过的一件事是,它们并不总是第一次就提供您想要的信息,因此,在我们的聊天机器人中,我们可以进行一来一回的对话。在前面的对话中,我们想知道哪个客户订购得最多,但我们不知道客户订购了多少订单,所以在图 6.11 中,我们以不同的方式提出问题:

图 6.11 – 与聊天机器人继续对话
随着 OpenAI 的 GPT 模型新版本的发布,您的聊天机器人的结果和行为可能会发生变化。在这种情况下,GPT-3.5 版本比 GPT-4 版本提出了更多的问题,但 GPT-4 版本在利用命令列出表格和请求表格定义方面表现得更好。随着新的模型和方法变得可用,测试它们并观察这些变化如何影响您的工作和聊天机器人的结果是一种良好的实践。利用 MLflow 与您的聊天机器人实验相结合将帮助您跟踪和比较不同的功能和配置,并协助您的生产过程。
在本节中,我们将结合在第第五章中创建的功能来为我们的不同数据集创建模型。
应用我们的学习
在本章中,我们学习了如何使用 AutoML 创建基线模型,使用 MLflow 跟踪我们的 MLOps,甚至使用更高级的语言模型从我们的数据中提取更多信息,并最终获得商业价值。现在,让我们将我们学到的知识应用到我们在第四章中清理并在第五章中特征化的数据集上。
我们将首先为我们的帕金森病数据创建和训练一个分类模型,这样我们最终可以使用患者的跟踪数据来对犹豫进行分类。
帕金森病 FOG
如 技术要求 部分所述,我们正在使用 PyTorch。要使用此库,要么使用 pip 在笔记本中安装包,要么将其添加到集群配置下的 libraries:

图 6.12 – 安装 PyTorch 库
一旦加载了库,我们就导入所有我们使用的库:

图 6.13 – 导入库
为了简化,我们创建了一个专注于一个目标标签的模型,即 StartHesitation。为了便于重用,定义特征和目标变量:

图 6.14 – 定义指标和目标变量
接下来,我们创建一个自定义的 FogDataset 类。该类由 PyTorch 使用,并需要三个特定的类方法:__init__、__len__、__getitem__。
对于 LightningModel 类,正如之前所述,__init__ 类方法设置标签并将特征转换为张量。__len__ 类方法返回数据集中样本的总数。__getitem__ 类方法返回给定索引的 i-第样本和标签:

图 6.15 – 创建自定义 FogDataset 类
接下来,我们将使用函数定义 PyTorch 模型。在 PyTorch 模型定义中,我们调用 self.log,定义一个 forward 和 test set() 函数以在 TensorBoard 中显示标量。然后,这将可以直接与 PyTorch Lightning 一起使用,以创建一个快速模型:

图 6.16 – 定义 PyTorch 模型直到训练步骤定义
图 6.16 定义了 PyTorch 模型、前向传递和训练步骤的详细信息。在模型代码的第二部分,我们定义了测试和验证步骤,如下所示:

图 6.17 – PyTorch 模型定义的第二部分
我们使用 SQL 创建训练数据,将 tdcsfog 数据和 tdcsfog_metadata 连接起来。我们检查标签计数,然后将训练数据转换为 Pandas 以准备 Sklearn 库:

图 6.18 – 创建帕金森病训练数据集
我们将按主题对训练数据进行分层,打印标签分布以寻找最具代表性的训练/测试分割:

图 6.19 – 分层训练数据集
以下是一个输出片段,说明为什么检查折是过程中的一个必要步骤。有些折在测试和训练数据中的标签分布之间存在显著差异:

图 6.20 – 查看折的测试和训练标签
我们现在使用折0实现拆分:

图 6.21 – 在第 3 折中实现拆分
现在我们有了训练和测试索引,我们可以通过重置索引来清理我们的 DataFrames:

图 6.22 – 训练后重置索引
不正确索引的 DataFrames 会导致我们的FogDataset类中的__getitem__方法出现问题。现在,我们创建自定义数据集:

图 6.23 – 创建客户训练、测试和验证数据集
现在,我们使用我们创建的自定义数据集构建模型,并使用 PyTorch 的Trainer进行训练:

图 6.24 – 构建和训练模型
我们现在使用我们的帕金森病 FOG 数据构建和训练了一个用于预测数据集中犹豫不决的分类 PyTorch 模型。
预测 Favorita 销售
在第四章中,我们使用 AutoML 来启动我们的探索性数据分析(EDA)。现在,我们将使用 AutoML 创建一个基线模型。
要开始,我们创建一个汇总表以供 AutoML 使用。这不是必需的,但这是一个简单的开始方法:

图 6.25 – 创建汇总销售数据表
注意,代码创建了一个favorita_autoML_agg表,其中包含我们在第五章中创建的滞后特征。
我们创建我们的 AutoML 实验与之前类似。参见实验配置在图 6.1:

图 6.26 – 为 Favorita 预测销售示例的 AutoML 实验配置
注意,在这次实验中,我们通过在time列中将机器学习问题类型选择为date变量,将预测问题视为回归问题;参见图 6.27:

图 6.27 – 为 Favorita 预测销售示例的高级 AutoML 配置
该实验在达到不再对所选指标(在我们的案例中为R-squared)取得进展的点之前进行了大约 100 次运行,如图图 6.27所示:

图 6.28 – 为 Favorita 预测销售示例的高级 AutoML 配置
在 100 种组合中,只有 6 种具有 0.85 或更高的 R 平方值。使用 AutoML 为我们节省了大量的时间和精力。在实验过程中,MLflow 尝试了许多模型类型和Hyperopt超参数调整。这个实验也利用 Spark 的分布式能力,这意味着我们有一个经过有效调整的稳定模型。我们有一个基线模型,并且我们确信可以找到信号。从现在开始,我们希望努力超越模型。在这个阶段,超越模型是通过暴力方法实现的。我们通过创建新特征、收集更多数据点或丰富数据集来提高性能。这一点是暴力方法。我们通过创建新特征、收集更多数据点或丰富数据集来提高性能。
摘要
在本章中,我们讨论了创建基线模型的快速方法,并展示了这种方法如何提高生产力。
我们展示了支持 MLOps 并帮助跟踪模型训练和调整的 MLflow 功能。我们还介绍了可以在湖屋中使用的更复杂的分类框架。这些框架的访问使我们能够在 PyTorch 中实现帕金森病 FOG 示例的深度学习模型。Databricks 的开放性为开源和专有创新打开了大门,如 SQL 机器人 LLM 所示。这种集成通过避免重复造轮子,并更快地将 SQL 工具交到我们的分析师手中,节省了时间。
下一章将重点介绍将我们的模型投入生产。
问题
以下问题有助于巩固需要记住的关键点,并将内容与您的经验联系起来:
-
为什么你会使用基线模型?
-
更高级的分类技术有哪些例子?
-
你会在何时在您的数据湖中使用 LLM 模型,例如 OpenAI 的 ChatGPT 或Dolly?
答案
在思考过这些问题后,比较您的答案与我们的答案:
-
使用基线模型作为起点,以便稍后比较更复杂和更复杂的模型。
-
一些更高级的分类技术示例包括深度学习(DL)和生成对抗网络(GANs)。
-
如果我需要在我的数据湖中实现更高级的语言技术,例如聊天机器人,我会使用 LLM 模型。
进一步阅读
在本章中,我们指出了具体的技术、技术特性和选项。请查看这些资源,深入了解您最感兴趣的区域:
-
介绍 AI 功能:将大型语言模型与 Databricks 集成 SQL:
www.databricks.com/blog/2023/04/18/introducing-ai-functions-integrating-large-language-models-databricks-sql.html -
在 Databricks 上使用 PyTorch – 介绍 Spark PyTorch 分发器:
www.databricks.com/blog/2023/04/20/pytorch-databricks-introducing-spark-pytorch-distributor.html -
免费 Dolly:介绍世界上第一个真正开放的指令调整 LLM:
www.databricks.com/blog/2023/04/12/dolly-first-open-commercially-viable-instruction-tuned-llm -
*Ray 2.3 版本(PyPI):
pypi.org/project/ray/ -
Spark Databricks 上的 Ray 文档:
docs.databricks.com/machine-learning/ray-integration.html -
宣布在 Databricks 和 Apache Spark 集群上支持 Ray:
www.databricks.com/blog/2023/02/28/announcing-ray-support-databricks-and-apache-spark-clusters.html
第七章:在 Databricks 上实现 ML 的生产化
“生产是工作的 80%。”
—— 玛泰·扎哈里亚
一旦您已经优化了模型并获得了满意的结果,您就可以将其投入生产。我们现在已经进入了 机器学习操作 (MLOps) 的领域!不幸的是,这正是许多数据科学家和 ML 工程师遇到困难的地方,公司在这里遇到困难也很常见。在生产中实施模型比临时运行模型要复杂得多,因为 MLOps 需要不同的工具和技能集,有时甚至需要全新的团队。MLOps 是数据科学过程中的一个重要部分,因为模型的实际价值通常只有在部署后才能实现。
您可以将 MLOps 视为 DevOps、DataOps 和 ModelOps 的结合。MLOps 通常分为两个部分:内循环和外循环。内循环涵盖数据科学工作,包括跟踪模型开发和实验过程的各个阶段。外循环包括在整个生命周期中协调您的数据科学项目的方法,从测试到预生产和最终投入生产。
幸运的是,在使用 Databricks 数据智能 (DI) 平台时,从模型开发到生产的路径不必完全依赖于另一个团队和工具栈。使用 Databricks 产品将 ML 模型投入生产,通过整合诸如 Unity Catalog 注册表 (UC 注册表), Databricks 工作流, Databricks 资产包 (DABs) 和模型托管功能等功能,使这一过程更加直接和连贯。本章将涵盖将您的模型从开发到生产的工具和实践。
作为本章的一部分,您将学习以下内容:
-
部署 MLOps 内循环
-
部署 MLOps 外循环
-
部署您的模型
-
应用我们的学习
部署 MLOps 内循环
在 Databricks 中,MLOps 内循环使用 DI 平台内的一系列工具,这些工具我们在本书中已经多次提及,例如 MLflow、使用 Unity Catalog 的特征工程和 Delta。本章将突出展示您如何利用它们共同促进 MLOps 的实施。Databricks 的电子书 MLOps 大全 对 MLOps 进行了更深入的探讨,我们强烈推荐您阅读,如果您想了解更多关于构建自己的 MLOps 解决方案时的指导原则和设计决策。我们使用 mlflow.log_input() 方法。我们创建的特征表的上游来源会自动通过 UC 线索进行跟踪。
注册模型
让我们深入了解模型注册表及其在生产中的应用。模型注册表是一个集中的模型存储库,有助于管理整个模型生命周期,包括版本控制或别名、CI/CD 集成、webhooks 和通知。在 Databricks 中,UC 注册表扩展了 Unity Catalog 的治理功能到模型注册表,包括集中访问控制、审计、血缘关系和跨工作区的模型发现。UC 注册表是您模型及其时间顺序血缘关系的集中存储库。这意味着创建每个相应模型的实验和实验运行都与相应的代码和数据源相关联。一旦您对您的机器学习模型满意,首先要做的是在 Databricks 的中央模型注册表中注册它。已注册的模型是模型版本历史的逻辑分组。UC 注册表跟踪不同的模型版本,包括每个版本的训练数据、超参数和评估指标。模型很少只有一个版本。除了对模型类型和超参数值的实验外,还有我们想要对模型的不同版本进行实验的情况。我们可以使用模型别名来引用这些不同的模型版本。例如,同时部署不同版本对于 A/B 测试可能很有帮助;我们将在 模型推理 部分更详细地介绍这一点。有了 UC 注册表,您可以轻松创建和管理多个模型别名,这使得跟踪更改、比较性能以及在需要时回滚到早期版本变得更加容易。
协作开发
UC 注册表提供了一个协作的模型开发环境,使团队能够共享和审查模型。这种协作也被跟踪,使多个团队或负责人能够跟上模型开发过程。团队或项目负责人还可以在允许模型继续生命周期之前要求提供文档。我们发现,在整个项目过程中添加文档片段比试图记住所有内容并在之后花费时间写下它们要容易得多。
UC 注册表允许您对模型和模型版本进行标记。在流式事务项目中,我们使用标签来跟踪模型的验证状态。审批流程可以是自动化的,也可能需要人工交互。一个审批流程可以确保模型质量高且满足业务需求。
图 7**.1 展示了 UC 模型注册表的截图。请注意,其中内置了标签、别名和注释的位置:

图 7.1 – UC 模型注册表 UI 展示每个模型版本
UC 注册与 DI 平台紧密集成。这提供了一个单一的技术栈 – 一个统一的环境,用于将模型从实验移动到部署。无缝集成让您可以利用其他 Databricks 组件,例如 Databricks Notebooks、Databricks Jobs、Databricks Lakehouse Monitoring 和 Databricks Model Serving。
接下来,让我们继续探讨支持外部循环过程的产品功能。
部署 MLOps 外部循环
机器学习生命周期对于不同的用例看起来不同。然而,Databricks 平台上的工具集使得自动化变得可能,并支持您的 MLOps。外部循环通过工作流程、Databricks Terraform Provider、REST API、DABs 等将内部循环产品连接起来。我们介绍了通过 MLflow Tracking 和 UC 注册自动化跟踪过程。UC 注册与模型服务功能紧密集成,并具有一个强大的 API,可以轻松地通过 webhooks 集成到自动化过程中。这些功能中的每一个都可以在自动化机器学习生命周期中发挥作用。
工作流程
Databricks Workflows 是一个灵活的编排工具,用于生产化和自动化机器学习项目。工作流程通过提供统一的方式来连接机器学习的各个方面,从数据准备到模型部署,帮助机器学习生命周期。使用 Databricks Workflows,您可以指定任务之间的依赖关系,以确保任务按所需顺序完成。这些依赖关系通过连接任务的箭头进行可视化,如图7.2所示:

图 7.2 – 一个包含五个任务的 Databricks 工作流程,其中特征工程任务有两个依赖项
工作流程中的任务不仅限于笔记本。在第三章中,我们准备了一个 DLT 管道来准备青铜层的数据,DLT 管道可以是工作流程组件。其他对象,如 JAR 文件、Python 脚本和 SQL,也可以作为工作流程中的任务,如图7.3所示:

图 7.3 – 可以用作工作流程中任务的对象示例
工作流程稳健,在 Databricks 中自动化工作发挥着关键作用。DABs 是 Databricks 中生产化的另一种工具。
DABs
DABs 是一种为基于 Databricks 平台构建的所有数据产品的部署方法带来统一性和标准化的方式。它们是一种基础设施即代码(IaC)的方法,用于管理项目,允许开发者使用 YAML 配置文件概述项目的基础设施和资源。DABs 对于管理涉及众多协作者和需要自动化的复杂项目特别有用。在需要持续集成和持续部署(CI/CD)的地方,DABs 是管理跨环境 ML 管道资源和管理团队在整个开发和生产过程中的最佳实践的绝佳方式。
在底层,DABs 是 Databricks 工件(包括作业、DLT 管道和 ML 模型)和资产(例如笔记本、SQL 查询和仪表板)的集合。这些捆绑包通过创建和维护在源代码旁边的 YAML 模板进行管理。您可以手动构建 DAB YAML 文件或使用模板来自动化。您还可以为更复杂的处理任务构建自定义模板。
使用 DABs 需要 Databricks CLI。如果您想再次查看,我们已在第二章中讨论了 CLI 的安装。此外,DABs 相对较新,尚未纳入项目中。然而,在进一步阅读中列出了大量资源,深入介绍了这个新产品特性。
REST API
您在 UI 中能做的所有事情都可以通过 API 完成。UI 非常适合探索产品功能和构建首次使用的流程。例如,我们在 UI 中构建了 AutoML 实验后,自动化了该过程。此外,我们还看到了如何通过 API 完全包含密钥,而 UI 则无法访问。正如我们将在下一节中看到的,通过 API 部署模型是可能的。
部署您的模型
模型的部署方式有很多种,这取决于用例和数据可用性。例如,部署可能看起来像是将模型打包到容器中,并在端点或生产工作流程中每天运行的模型上部署,以提供可以被应用程序消费的表格预测。Databricks 提供了产品功能,为所有推理类型铺平通往生产的道路。
模型推理
我们已经介绍了帮助您在生产中设置模型的方法和工具,最终,您有一个准备进行推理的模型!但在这个过程中,您应该考虑的一个关键问题是您的模型应该如何使用。您是否每天需要结果一次?模型是否为需要实时结果的应用程序提供动力?您模型的目的将帮助您决定所需的部署类型。您在本章中已经几次看到了“批量”和“流式”这两个词,所以让我们快速定义在模型推理的上下文中这些词的含义:
-
批量推理:批量推理(也称为离线推理)指的是一次性对一组(或“批量”)数据生成预测的工作。批量作业被安排在指定的周期上运行,例如每天一次。当没有/低延迟要求时,这种推理类型最佳,并且允许你利用可扩展的计算资源。
-
流式推理:流式推理(也称为在线推理)指的是在数据流式传输时生成预测的工作。在 Databricks 平台上,这可以通过 Delta Live Tables 实现。
-
实时推理:实时推理(也称为模型服务)指的是将你的模型作为 REST API 端点公开的过程。这可以实现低延迟的、普遍可用的预测,当部署需要实时应用程序的预测模型时特别有用。
所有这些选项都可通过 Databricks UI 获取。让我们再次使用 Favorita Store 示例。也许我们已经遇到了我们的饮料业务团队,他们希望看到每周的预测以帮助他们决定应该购买每种产品的数量。我们将选择批量推理,因为我们只需要每周生成一次更新的预测。只需几步点击即可设置用于批量处理的模型。有关部署模型进行批量推理的详细说明,请参考 Favorita 销售数据集的“应用我们的学习”部分。
模型服务
让我们更深入地探讨实时推理或模型服务。模型服务的流程可能很复杂且成本高昂,需要额外的工具和系统来满足实时需求。幸运的是,从 Databricks 平台部署已注册的模型作为端点只需单击一次!因为模型服务与 MLflow 紧密集成,从开发到生产的路径要快得多。使用 MLflow 模型注册表中注册的模型,Databricks 自动准备一个生产就绪的容器并将容器部署到无服务器计算。
通过 API 部署模型也很容易,如这里所示。预测问题作为模型服务用例没有太多意义,所以让我们考虑一下我们在这本书中一直在工作的 MIC 问题。我们将使用模型服务在实时中提供我们的分类模型。以下示例代码片段创建了一个端点,该端点提供名为 asl_model 的模型版本:

图 7.4 – 通过服务端点部署模型
模型服务让您能够围绕模型端点构建工作流程,这为模型部署提供了充分的灵活性。例如,一个组织可能想要对两个或更多模型进行 A/B 测试。模型服务使得在相同端点后面部署多个模型并分配流量变得容易。在另一种模式中,您可以在多个端点后面部署相同的模型。以下是在进行 A/B 测试模型时可以执行的 UI 和分析示例:

图 7.5 – 模型服务为我们提供了在相同端点部署的模型进行 A/B 测试的灵活性
准备在您的 Databricks 工作区中跟随我们逐个项目地回顾 第七章 的代码项目。
应用我们的学习
让我们运用我们所学的知识来将我们的模型投入生产。
技术要求
这里是需要完成本章动手示例所需的技术要求:
-
按需功能需要使用 DBR ML 13.1 或更高版本。
-
RAG 和 CV 部分需要 DBR ML 14.2 和更高版本。
-
Python UDFs 在 UC 中创建和管理;因此,Unity Catalog 必须在工作区中启用 – 没有共享集群。
-
流式事务项目使用
scikit-learn==1.4.0rc1。需要它的笔记本会进行安装。 -
流式事务项目,再次证明,使用并行计算表现更佳。我们将使用来自 第五章 的多节点集群。参见 *图 7**.6 中的多节点 CPU 配置:

图 7.6 – 多节点 CPU 集群配置(在 AWS 上)
项目 – Favorita 销售预测
在本章中,我们讨论了使用托管 MLflow 和 UC 模型注册表来注册和准备模型以供部署。我们将首先通过 UI 进行操作,因此请打开以下笔记本和实验 UI 页面中的标签:
-
CH7-01-Registeringthe Model -
CH7-02-Batch Inference
作为提醒,在 第六章 中,我们进行了实验以找到基线模型,您可以从 Databricks 的实验 UI 页面中回顾这些实验。为了在您的空间中跟随,请打开来自 第六章 的实验 UI 页面,如图 *图 7**.7 所示:

图 7.7 – 探索实验运行的实验 UI 页面
为了项目的目的,我们将继续前进,好像最好的基线模型就是我们想要的在生产中的模型。要将模型投入生产,请按照以下步骤操作:
- 在 AutoML 实验页面上,点击最佳运行(按评估指标降序排列时位于顶部的运行)。这将打开运行详情页面。如图 7.8 所示,有四个选项卡 – 概述、模型指标、系统指标和工件:

图 7.8 – 探索模型详情页面
- 点击
CH7-01-注册模型笔记本。在您的工作区中运行笔记本之前,必须更新笔记本中的runs:/URL:

图 7.9 – 注册新模型
-
在您的笔记本中,执行最后一个单元格第二次。这将创建相同模型的第二个版本。
-
导航到 Unity Catalog 中的
favorita_forecasting数据库。选择模型选项卡将打开一个新的 UI,如图 7.10 所示:

图 7.10 – 在 Unity Catalog 中查看模型
- 选择预测模型。您会注意到我们有两个模型版本。为每个版本添加一个别名:champion和challenger是常见的,用来表示当前最佳模型和正在考虑替换当前最佳模型的新版本:

图 7.11 – 分配别名以识别模型状态
现在,是时候考虑我们想要如何部署这个模型了。由于这是一个预测 10+天前的销售预测用例,实时推理并不最合理。
- 打开
CH7-02-Batch Inference以在测试集上运行推理。注意在图 7.12中,我们使用别名而不是模型版本号来定义model_uri:

图 7.12 – 使用 Champion 模型在测试集上进行批量预测
此推理代码将始终使用 Champion 模型对提供的数据进行推理。如果我们后来确定更新版本更好,我们可以更改模型别名并运行正确的模型,而无需对推理代码进行任何代码更改。
下一个实际步骤是在计划中设置工作流程。请参考流式项目以查看演示。这标志着本项目的结束。在第八章中,我们将使用 Favorita 销售数据来展示如何使用 Foundational Model API 轻松创建 SQLbot。
项目 – 流式事务
我们还有很多事情要做来完成流式事务项目!我们将构建我们的模型,封装它,验证它,并实现批量推理。为了完成这项任务,我们将开始将标签摄入到不同的表中。这允许我们在预测发生后设置推理表并合并实际标签。我们将创建两个工作流程:生产流式事务和生产批量推理与 模型重训练。
就像任何项目一样,我们必须在生产过程中对之前编写的代码进行细化。这本书早期部分看起来熟悉的笔记本可能有一些小的更新,但大部分代码保持不变。
在我们深入之前,让我们通过快速查看项目流程来记住我们现在在哪里以及我们要去哪里:

图 7.13 – 生产流式事务项目的项目流程
要在您的工作区中跟随,请打开以下笔记本:
-
CH7-01-生成记录 -
CH7-02-自动加载器 -
CH7-03-特征工程流 -
CH7-04-更新最大价格特征表 -
CH7-05-封装和记录基线模型 -
CH7-06-封装和记录生产模型 -
CH7-07-模型验证 -
CH7-08-批量推理 -
CH7-09-生产批量推理 -
CH7-10-自动标签加载器 -
mlia_utils/transactions_funcs.py -
production_streams.yaml -
model_retraining_n_inference_workflow.yaml
我们建议使用多节点 CPU 集群来完成这个项目。前四个笔记本(CH7-01到CH7-04)几乎与它们之前的版本在第六章中相同,但第七章的版本都指向生产目录而不是开发目录。表名在控件中参数化,以便可以在工作流程中设置。以下是已对前四个笔记本所做的关键笔记本特定更改列表:
-
CH7-01-生成记录:标签和事务现在被写入不同的文件夹。数据生成组件也已移动到utils文件夹中的transactions_funcs文件。 -
CH7-02-自动加载器:标签列不再被添加到事务表中。对于生产,我们在流开始之前确保写入的表具有delta.enableChangeDataFeed = true属性。如果在流开始后设置表属性,则流会被中断并需要重启。最后,如果表属性从未设置,Lakehouse 监控将受到负面影响,将不支持连续监控。 -
CH7-03-特征工程流:与CH7-02-管道自动加载器笔记本类似,在写入任何数据之前设置表属性。 -
CH7-04-更新最大价格特征表:代码已清理,以迈向生产。具体来说,一旦存在,特征表就会更新而不是创建。
您需要生产目录中的交易数据来创建模型。注意新的设置变量$env=prod。管道工作流程笔记本——即CH7-01、CH7-02和CH7-03——已准备好添加到 Databricks 作业部分的流程中。首先点击production_streams.yaml,以引导您。请注意,在 YAML 文件和[图 7**.14]中,任务之间没有依赖关系:

图 7.14 – 生产流式事务作业的任务 DAG(左)和一些设置(右)
如[图 7**.14]所示,您可以使用[图 7**.6]中显示的计算集群来完成作业和其他笔记本。我们还选择在作业级别而不是单个任务级别添加参数。现在您可以轻松生成构建模型所需的数据。
我们将使用在第六章中创建的training_set来训练模型的更新版本。回想一下,在 Unity Catalog 中记录模型会将特征元数据与模型打包。因此,在推理时,它会自动从指定训练集中提供的特征表中查找特征。我们将此规范添加到了CH7-05-包装和记录基线模型和CH7-06-包装和记录生产模型笔记本中。我们不会单独介绍这些笔记本。它们之间的区别在于,基线模型是在开发目录中的数据上训练的。然后,使用推理表中的生产数据在生产环境中重新训练模型。
我们知道我们还没有推理表。不用担心——它即将到来!回到training_set,能够匹配特征只有在我们有特征值时才有用。我们使用特征表的时间边界来确保用于训练的原始交易具有特征值。此外,我们要求存在标签列,如[图 7**.15]所示:

图 7.15 – 定义推理模型的特征查找
[图 7**.15]中显示的交易来自推理表packaged_transaction_model_predictions,该表是在CH7-08-批量推理中创建的。基线模型使用raw_transactions表做类似的事情。基线模型还设置了模型描述,如[图 7**.16]所示:

图 7.16 – 设置模型描述
我们现在可以专注于模型了。让我们继续介绍剩余的过程:
-
将模型注册设置为 Unity Catalog,使用
mlflow.set_registry_uri("databricks-uc")。 -
使用
pip保存一个requirements.txt文件。 -
为
TransactionModelWrapper创建一个 PyFunc 包装器。
对于那些使用 Sklearn 创建过模型的人来说,TransactionModelWrapper 的大部分代码应该看起来很熟悉。初始化函数 __init__(self, model, X, y, numeric_columns, cat_columns) 接受一个模型和 DataFrame。训练数据和推理数据的数据预处理在包装器内部标准化。TransactionModelWrapper 由四个方法组成:init、predict、preprocess_data 和 fit。
初始化方法执行以下操作:
-
将数据分为训练集和测试集。
-
初始化并拟合
OneHotEncoder以处理提供的分类特征列。 -
初始化并拟合
StandardScaler以处理提供的数值特征列。 -
将
preprocess_data方法应用于训练数据和测试数据。 -
定义一个
evaluation方法来计算提供的 X 和 y 集合上的对数损失。 -
在预处理后的测试数据上调用
evaluation方法。 -
定义并调用
_model_signature方法,以便在记录模型时轻松提供签名。
predict 方法在执行并返回预测之前,在输入 DataFrame 上调用 preprocess_data (图 7.17) 方法。此方法用于处理训练数据和推理数据,确保预测的预处理相同:

图 7.17 – 模型的预处理方法
如 图 7.17 所示,拟合的数值缩放器和单热编码器作为输入传递。这可以防止训练和推理特征之间的偏斜。注意 TransactionTimestamp 是如何被删除的。这是因为特征表中的特征存在之后,我们不再需要一个时间戳。输入 DataFrame 可以是 Spark 或 pandas DataFrame。这就是为什么我们需要不同的语法来删除时间戳列。
在下面的命令单元格中,您自定义 mlflow.autolog 并开始 MLflow 实验以进行训练、测试、包装和记录模型。您将使用 mlflow.evaluate 来处理评估过程。记录过程很简单 – 您只需调用 log_model 并传入模型名称、包装模型、pyfunc 风味和先前创建的训练集。此过程还将模型注册到 Unity 目录中。这个笔记本的最后一件事是对预测函数进行快速测试,展示如何传递 Spark 上下文和输入数据。现在,您已经准备好验证模型。
接下来,关注CH7-07-Model Validation笔记本,该笔记本检查输入模型是否具有正确的元数据,以便其可以用于生产。此笔记本可以用于测试任何模型。理想情况下,您将添加许多检查,包括预测特定数据切片的能力以及测试其准确性的可能性。例如,您可以检查每个产品或地理区域的模型性能。当需要测试切片时,您可以通过标签传递这些列。
收集模型详细信息,如图图 7.18所示。注意util函数的使用,该函数是从上一个单元格中导入的mlia_utils.mlflow_funcs import get_latest_model_version:

图 7.18 – 使用 mlfclient 和 util 函数访问模型详细信息
每次训练并记录模型时,都会创建一个新的模型版本。使用标签,您可以指明哪些模型版本必须在部署前进行测试和验证:

图 7.19 – 断言以确保模型需要被测试
如图 7.20所示,所有生产模型都需要一个信息丰富的模型描述。我们建议您包括有关模型用途的信息。随着公司希望利用内部数据上的生成式 AI,元数据卫生变得越来越重要。这是因为 LLMs 使用元数据字段在模型中查找相关信息:

图 7.20 – 验证模型描述是否存在
与图 7.20中所示类似,笔记本会检查标签。这些是帮助您开始的示例。这是一个理想的扩展当前代码并继续添加验证结果和更新标签的部分:

图 7.21 – 处理验证测试的结果
使用经过测试的模型,您可以进行推理;参见CH7-08-Batch Inference笔记本。回顾在 DataFrame 上执行批量推理的示例(图 7.22)和 JSON 数据字符串:

图 7.22 – 通过在 DataFrame 上执行批量推理来加载和评分模型
现在,查看CH7-09-Production Batch Inference中的代码。主要变化包括scoring_df,这是我们应用模型进行预测的 DataFrame。注意在图 7.23中,min_time和max_time变量为交易提供了边界,确保批量特征值已计算。此外,推理表提供了一个边界,防止重复的预测计算:

图 7.23 – scoring_df查询的配置
CH7-08中的推理表需要更新以符合 Lakehouse Monitoring 提供的推理表监控要求。这意味着添加model_version和actual_label列。actual_label列设置为NULL,以便清楚地表明值尚未更新;见图7.24:

图 7.24 – 添加模型版本和实际标签列
这两个额外的推理表列是 Lakehouse Monitoring 的要求。InferenceLog监控器附带自动生成的仪表板。但是,您需要填充表格。首先创建一个用于交易标签的青铜表。自动加载器再次出现,专注于标签;见CH7-10-Auto Label Loader和图7.25。在笔记本中,创建了transaction_labels表;这与第三章中的代码类似。在图7.25中,您可以使用 CDF 和 CDC Delta 功能将地面真实标签更新到新的推理表中:

图 7.25 – 将交易标签合并到推理表中
现在,您有一个青铜表和将新标签合并到推理表中的能力。然而,推理表仍然是空的。因此,让我们创建一个如图7.26所示的流程作业,每 15 分钟生成一次预测:

图 7.26 – 推理(上方)和模型重新训练(下方)作业的 DAG
检查这两个工作流路径,从上方的路径开始。批量特征被更新,从而为推理提供特征数据。数据已准备好进行预测,推理任务可以开始。
作为其第一个任务,下方的路径更新标签。它将最新数据添加到transaction_labels表中,并将所有与先前预测匹配的新标签合并到推理表中。跳过第一次迭代之后,推理表不仅包含先前预测,还包括这些预测的标签。使用包含特征的更新表进行模型训练。只有在推理表中存在数据时,才会重新训练模型,如图7.27所示。当然,在需要时,重新训练过程之后会进行验证。当验证笔记本检测到最新版本的模型已经过测试时,它将退出:

图 7.27 – 如果没有数据重新训练,则重新训练笔记本退出
创建如图 7.29 所示的工作流程作业。你可以参考model_retraining_n_inference_workflow.yaml文件中的作业配置。工作流程自动提供所有上游和下游表的血缘关系。你可以在 图 7.26 中看到这些。这节省了我们在文档上的时间:

图 7.28 – 工作流程表血缘关系
剩下的只是同时运行两个工作流程。在运行一段时间后(别忘了安排生产批量推理和工作流程模型重训练),你应该会有一个类似于 图 7.29 所示的屏幕:

图 7.29 – 成功作业运行的历史视图
你现在拥有了将此项目投入生产的所有部件。
项目 – 多标签图像分类
我们目前有一个工作图像分类模型,我们在第六章中对其进行了训练和评估。现在,让我们在我们的代码周围添加一些基础设施来提供服务我们的模型,使其可供下游应用程序和最终用户使用。为了在你的工作区中跟随,请打开以下笔记本:
-
Ch7-01-Create_Final_Wrapper_Production -
Ch7-02-Serve_In_Production
我们将首先创建我们的模型类包装器。这个包装器包括两个函数,feature_extractor 和 predict。feature_extractor 函数是必需的,因为否则我们的微调模型将不包含在微调期间使用的相同预处理步骤,因此在服务期间将不一致。当然,如果你不需要对你的模型进行任何自定义修改,并且只需要原始格式输出,你可以简单地提供服务你的原始模型:

图 7.30 – 创建模型类包装器
将图像转换为服务模型所需格式的feature_extractor函数,与我们用于在第六章中评分模型的相同代码。让我们深入预测部分;它与我们在第六章中创建的用于评分模型的代码类似。
predict 函数与我们在第六章中使用 pandas_udf 评分模型的函数类似。请注意,我们不仅返回预测标签,还返回一个以字典格式对应的标签(这不是必需的,但我们想展示输出格式的灵活性):

图 7.31 – 在模型类包装器中包含 feature_extractor 和 predict 函数
现在,我们已经准备好将第四章中微调的模型封装到包装器中。为此,我们必须从 MLflow 加载工件并将其传递给预先创建的 CVModelWrapper 类:

图 7.32 – 从现有的 MLflow 实验中加载我们的模型
让我们测试我们的包装器是否按预期工作。为此,我们必须对一些图像进行编码(因为模型提供程序接受字符串,但不能接受图像并立即将它们转换),并将它们保存到一个 pandas DataFrame 中。然后,我们必须使用我们的模型包装器来获取预测:

图 7.33 – 使用我们的模型包装器在几幅图像上创建预测
接下来,我们将使用 MLflow 通过 Databricks Model Serving 记录和提供模型:

图 7.34 – 使用 MLflow 记录和运行模型
在生产阶段,你通常会操作别名和最新模型版本,因此在这里,我们将模拟设置别名“Champion”为表现最佳的模型,并获取要部署的最新模型版本:

图 7.35 – 加载我们的冠军模型
接下来,我们必须使用 Databricks SDK 创建我们的模型提供程序端点。你也可以使用 UI 创建你的端点。如果你决定使用 SDK,你必须为你的端点创建一个配置文件。以下示例是一个具有小型工作负载大小的 CPU 容器。如果你不熟悉此选项,请参阅 进一步阅读 部分的 创建模型提供程序端点:

图 7.36 – 为端点设置配置输入以提供我们的模型
一旦提供了设置,你就可以部署或更新你的端点,如果它已经存在:

图 7.37 – 如果不存在则部署新端点或更新现有端点
请记住,如果你的端点不存在,部署将需要一段时间:

图 7.38 – GPU 端点部署/更新时的 UI 示例
现在,我们可以对模型进行评分。同样,为了简单性和可重用性,我们将提供调用封装到 score_model 函数中:

图 7.39 – 定义模型评分函数
最后,我们必须使用我们的模型评分函数对模型进行评分,如图 图 7**.40 所示:

图 7.40 – 评分我们的模型
下面是在 UI 页面上评分的一个示例:

图 7.41 – 在 Databricks 模型服务的 UI 页面上评估我们的模型
现在模型已准备好投入生产,我们可以对其进行训练和创建,指定我们的冠军模型,在端点上提供服务,并进行评分。下一步可能包括设置监控器以跟踪图像像素分布、图像数量、标签分布和响应分布。我们将在 第八章 中更多地讨论模型监控。
项目 - 检索增强生成聊天机器人
在上一章中,我们完成了我们的聊天机器人,并在笔记本中进行了测试。可能有人会想立即跳到最终部署步骤,但那样会跳过过程中的一个关键步骤——评估!在将项目提供给最终用户之前,评估项目的正确性应该始终是开发过程的一部分。然而,为新技术和技巧构建自动评估解决方案可能特别棘手,例如在处理大型语言模型(LLMs)时。这是一个持续发展的研究领域,我们建议阅读 Databricks 关于 LLM 评估的最佳实践 的建议以获取更多信息(见 进一步阅读)。我们将介绍 MLflow 评估功能,以评估我们构建的 RAG 聊天机器人。
要在您的工作区中跟随,请打开以下笔记本:
-
CH7-01-GetData -
CH7-02-Evaluating_ChatBot
加载真实标签
我们将从第一个笔记本 CH7-01-GetData 开始。为了评估我们的模型,我们必须有真实标签——即正确答案。这通常涉及人力编写一些典型的您期望用户向您的聊天机器人提出的问题以及您期望聊天机器人响应的答案。为了简化此过程,我们为该项目创建了一个包含 35 个样本问题和相应人工生成的答案的文件,并将其保存到 Questions_Evaluation.csv。让我们加载此文件并检查问题和答案对:

图 7.42 – 读取我们预先创建的评估集
查看一些记录,以了解用户可能提出的问题和预期的答案。您还可以添加自己的示例来进一步扩充评估数据:

图 7.43 – 问答对示例
让我们将这些示例保存到名为 evaluation_table 的 Delta 表中。这样,如果上传了包含不同示例的新 Question_Evaluation.csv 文件,您可以将新示例追加到现有表中,而不会丢失原始数据:


在保存表之后,我们现在可以评估我们的模型:

图 7.45 – 将 questions_evaluation.csv 数据保存到 Delta 表
设置评估工作流程
现在,我们已经准备好打开第二个笔记本,CH7-02-Evaluating_ChatBot,并评估我们的聊天机器人与存储在evaluation_table中的地面真实标签。让我们简要讨论我们将如何比较我们模型的输出与人工生成的答案。虽然在这个自动化的 LLM 评估方法领域有许多正在进行的研究,但我们将专注于一种特定的技术:LLM 作为裁判。这种方法引入第二个 LLM 来评估第一个 LLM 的性能,自动化了将生成的答案与真实答案比较的繁琐任务,这是人类传统上必须做的。按照以下步骤进行:
- 要使用 LLM 作为裁判,我们必须加载我们在第六章中创建的原始模型:

图 7.46 – 将 mlaction_chatbot_model 作为 rag_model 加载
- 现在,我们必须运行一个快速测试来验证我们的 RAG 模型按预期工作:

图 7.47 – 验证我们加载的模型按预期工作
- 接下来,我们必须使用我们的 RAG 聊天机器人来生成所有存储在
evaluation_table中的示例问题的答案。这些回答是我们将与之比较的地面真实答案。我们将构建一个pandas_udf函数来使这部分运行更快:


我们使用 Llama-2-70b 作为裁判,但您可以使用 GPT-4 或任何您喜欢的其他 LLM(尽管我们无法保证满意的结果!)!我们的代码利用了 Databricks 基础模型 API,我们在第三章中创建 ArXiv 文章文本块嵌入时也使用了它。作为提醒,Databricks 基础模型 API 提供了从服务端点到最先进开放模型的直接访问,允许您在不维护模型部署的情况下将高质量的生成 AI 模型集成到您的应用程序中。我们在图 7.49中调用 Llama-2-70b 端点:

图 7.49 – 测试 Llama-2-70b 的 Foundation Model 端点
- 接下来,我们必须从
evaluation_table的问题和答案构建一个 DataFrame。如果你已经向这个数据集添加了更多的问答示例,你可能想要减少问题的数量并加快预测过程。然后,我们必须调用我们的 UDF,predict_answer:

图 7.50 – 使用问题和真实答案构建 DataFrame,并添加 RAG 聊天机器人答案
- 现在我们有了包含聊天机器人对每个问题的回答的 DataFrame,我们必须将其保存到 Delta 表中。我们将在代码的其余部分继续引用 DataFrame,但这样,如果我们将来想要查询这些数据,我们就不必再次生成聊天机器人的回答:

图 7.51 – 将我们的评估 DataFrame 写入新表
- 如本节开头所述,我们正在使用 MLflow 的评估功能来简化我们的模型评估。在我们评估 RAG 聊天机器人之前,让我们加载方法并验证 MLflow 评估默认的工作方式。首先,我们必须加载“答案正确性”指标,我们将直接使用它:

图 7.52 – 查看答案正确性指标
默认指标很好,但专业性也是我们用例的重要标准之一,因此我们将创建一个自定义的专业性指标。图 7.53 展示了如何使用 make_genai_metric() 函数构建我们的专业性评估指标:

图 7.53 – 添加自定义专业性指标
- 如
grading_prompt所示,我们设计了此指标,使其在 1 到 5 之间给出分数,其中 1 分将文本识别为非正式,5 分则评估文本为明显正式。这是一个强大的工具,可以根据对您的业务用例重要的标准评估您的模型。您可以根据需要修改模板。我们还必须添加该指标的示例,如 图 7.54 所定义:

图 7.54 – 添加自定义专业性指标的示例
- 使用我们的专业性指标,让我们使用 MLfLow 运行模型评估。要运行评估,我们可以调用
mlflow.evaluate()对包含问题、真实答案和聊天机器人生成的答案的 pandas DataFrame 进行操作。我们将包括答案正确性和专业性指标作为额外指标。以下代码将计算我们指定的两个指标以外的许多其他指标,例如令牌计数、毒性以及自动可读性指数等级(理解文本所需的近似等级):

图 7.55 – 使用 mlflow.evaluate() 运行 MLflow 实验
一旦我们运行了实验,我们可以在笔记本和 UI 中访问这些指标,这样我们就可以轻松地看到我们的聊天机器人在准确性和专业性方面的表现。
评估聊天机器人的响应
首先,让我们看看 Databricks 中的 MLfLow UI,以比较人工生成和聊天机器人生成的响应之间的结果。要做到这一点,导航到 CH7-02-Evaluating Chatbot)。然后,导航到 answers 匹配我们预期的内容,但当你想要测试和比较不同模型或分块策略的输出时,这也特别有用:

图 7.56 – 在 Databricks MLflow 中使用评估视图
查看评估数据集的一些示例。我们会看到,根据快速的人工评估,我们的模型表现相当不错。当然,这种评估形式不可扩展,所以让我们也深入查看其他指标。我们将使用常见的可视化库 plotly 来更仔细地查看我们的模型结果。首先,我们将查看聊天机器人响应中标记计数的分布:

图 7.57 – 绘制聊天机器人响应的标记计数
虽然很有趣,但我们关心的是我们之前讨论的两个指标:正确性和专业性。让我们看看正确性分数的分布:

图 7.58 – 绘制正确性分数分布
让我们再看看专业性分数的分布。我们的分布是三和四,这意味着语气通常是“边缘专业性”。这是我们自定义指标中的定义方式:

图 7.59 – 绘制专业性分数分布
总体来说,我们的模型看起来不错!如果我们对准确性和专业性分数满意,我们可以通过给它一个生产别名来标记这个模型为生产就绪:

图 7.60 – 为模型创建别名以显示其已准备好投入生产
因此,我们通过从我们的问答数据集中创建预测来评估我们的聊天机器人,创建了一个自定义评估指标来评估每个响应的专业性,并可视化了我们的模型输出信息。在最后一章中,我们将演示如何构建一个 Gradio 应用程序,这样你就可以将你的 RAG 聊天机器人带给你的最终用户!
摘要
在生产中实现模型可能会具有挑战性,但有了旨在支持模型生产化和自动化 MLOps 流程的工具,这会容易得多。在本章中,我们探讨了如何使用 UC 模型注册表来管理机器学习模型的生命周期。我们强调了 MLflow 及其如何被用来创建可重复、模块化的数据科学工作流程,这些工作流程可以自动跟踪参数和性能指标。我们还讨论了在推理时计算特征的技术。为了使端到端的 MLOps 流程更易于管理,我们展示了如何使用工作流程和 webhooks 来自动化机器学习生命周期。我们还展示了如何使用 MLflow 和 Databricks 平台来提供模型和进行推理。
在上一章“监控、评估和更多”中,我们将探讨如何在 Databricks Lakehouse 中监控我们的数据和机器学习模型,以便你能从你的数据中获得最大价值。
问题
通过以下问题来测试一下我们所学的内容:
-
是否可以同时生产多个模型?你会在什么情况下想要在生产中使用两个模型?
-
你可以使用 MLflow 的哪个组件来路由审批?
-
你可以使用 MLflow API 来提供你的模型吗?
答案
在思考了前面的问题之后,比较一下你的答案和我们的答案:
-
是的,同时在生产中拥有多个模型是可能的,这适用于比较挑战者/冠军测试中的模型或运行 A/B 测试等用例。
-
可以使用 UC 模型注册表来路由审批。
-
MLFlow 内部的模型服务 API 可以用于模型服务。
进一步阅读
本章讨论了帮助生产化机器学习的工具和技术。请查看这些资源,深入了解你最感兴趣的领域,并帮助你将更多的机器学习项目投入生产!
-
在生产中使用结构化流量的最佳实践 - Databricks 博客:
www.databricks.com/blog/streaming-production-collected-best-practices -
机器学习用例大全:
www.databricks.com/resources/ebook/big-book-of-machine-learning-use-cases -
Databricks 模型服务:
www.databricks.com/blog/2023/03/07/announcing-general-availability-databricks-model-serving.html -
使用 Mlflow 创建和管理服务端点:
docs.databricks.com/en/machine-learning/model-serving/create-serving-endpoints-mlflow.html -
MLFlow 中的模型评估:
www.databricks.com/blog/2022/04/19/model-evaluation-in-mlflow.html -
MLOps 的宝典:
www.databricks.com/resources/ebook/the-big-book-of-mlops -
Databricks 资产包 - 使用 CI/CD 最佳实践和工作流程程序化定义、部署和运行 Databricks 作业、Delta Live Tables 管道和 MLOps Stacks:
docs.databricks.com/en/dev-tools/bundles/index.html -
模型注册 Webhooks:
MLflow 模型注册 Webhooks在 Databricks -
Webhooks:
docs.databricks.com/en/mlflow/model-registry-webhooks.html -
使用 Git 和 Databricks 仓库的 CI/CD 工作流程 - 使用 GitHub 和 Databricks 仓库进行源代码控制和 CI/CD 工作流程:
docs.databricks.com/en/repos/ci-cd-techniques-with-repos.html -
使用 GitHub Actions 进行持续集成和交付 - 在 GitHub 上构建使用为 Databricks 开发的 GitHub Actions 的 CI/CD 工作流程:
docs.databricks.com/en/dev-tools/ci-cd/ci-cd-github.html -
在 Databricks 上使用 Jenkins 的 CI/CD – 为 Databricks 开发使用 Jenkins 的 CI/CD 管道:
docs.databricks.com/en/dev-tools/ci-cd/ci-cd-jenkins.html -
使用 Apache Airflow 调度 Databricks 作业 – 管理和调度使用 Apache Airflow 的数据管道:
docs.databricks.com/en/workflows/jobs/how-to/use-airflow-with-jobs.html -
*CI/CD 的服务主体 – 使用服务主体而不是用户进行 CI/CD 系统:
docs.databricks.com/en/dev-tools/ci-cd/ci-cd-sp.html -
RAG 应用程序 LLM 评估的最佳实践,第 1 部分:
www.databricks.com/blog/LLM-auto-eval-best-practices-RAG -
RAG 应用 LLM 评估的最佳实践,第二部分:
www.databricks.com/blog/announcing-mlflow-28-llm-judge-metrics-and-best-practices-llm-evaluation-rag-applications-part -
创建模型服务端点:
docs.databricks.com/en/machine-learning/model-serving/create-manage-serving-endpoints.html
第八章:监控、评估和更多
“关注最终用户客户如何看待你的创新的影响——而不是你,作为创新者,如何看待它。” —— 托马斯·A·爱迪生
恭喜,你已经到达了最后一章!我们已经走了很长的路,但在 Databricks 中仍有更多内容可以探索。在我们结束之前,我们将再次审视 Lakehouse Monitoring。我们将专注于监控模型推理数据。毕竟,你在构建一个健壮的模型并将其推入生产后投入了大量的工作,与广泛的受众分享学习成果、预测和其他结果至关重要。通过仪表板共享结果非常常见。我们将介绍如何在新的 Lakeview 仪表板和标准的 Databricks SQL 仪表板中创建仪表板可视化。部署的模型可以通过 Web 应用程序共享。因此,我们不仅将介绍 Hugging Face Spaces,还将通过 Gradio 应用程序在应用我们的学习中部署 RAG 聊天机器人。最后,我们将演示分析师如何通过 SQL AI 函数调用 LLMs!到本章结束时,你将准备好监控推理数据、创建可视化、部署 ML Web 应用程序,并使用突破性的 DBRX 开源 LLM 与 SQL 一起使用。
本章的路线图如下:
-
监控您的模型
-
构建金层可视化
-
连接您的应用程序
-
为分析师整合 LLMs
-
应用我们的学习
监控您的模型
机器学习生命周期并不在部署后结束。一旦模型投入生产,我们希望监控模型的输入数据和输出结果。在第四章中,我们探讨了与 Unity Catalog 集成的 Databricks Lakehouse Monitoring 的两个关键特性:快照和时序配置文件。快照配置文件旨在提供在特定时间点的数据集概览,捕捉其当前状态。这对于识别即时数据质量问题或变化特别有用。另一方面,时序配置文件专注于数据随时间的变化,因此它们非常适合跟踪趋势、模式和数据分布的渐进性变化。
在这些功能的基础上,Databricks 还提供了一种推理配置文件,专门用于监控生产中的机器学习模型。这个高级配置文件建立在时序配置文件的概念之上,增加了全面模型性能评估的关键功能。它包括模型质量指标,这对于跟踪预测的准确性和可靠性随时间的变化至关重要。它还记录预测,以及可选的地面真实标签,直接比较预期和实际结果。这一功能对于识别模型漂移至关重要,其中输入数据的变化或输入与输出之间的关系发生变化。
Databricks 中的推理表进一步增强了这种监控能力。它们包含模型预测、输入特征、时间戳以及可能的地面实标签等基本元素。在 InferenceTables 上构建具有相应 InferenceLog 的监控器,使我们能够持续监控模型性能和数据漂移。
在检测到漂移事件时,应立即采取行动 – 建议进行数据管道验证或模型重新训练和评估。这些步骤确保模型适应新的数据模式,保持准确性和有效性。持续监控基准和跨模型版本是尝试确保跨各种部署解决方案的稳定过程的一种策略。
图 8**.1 是使用 InferenceLog 配置文件类型创建具有模型质量指标的推理监控器的代码示例。这展示了这种监控设置的实用应用。我们指定 schedule 参数以确保这个监控器每小时刷新一次。

图 8.1 – 创建每小时刷新一次的推理配置文件监控器
模型监控是确保你的模型按预期为你工作的一种有效方式。我们希望这能让你思考你在 MLOPs 流程中使用监控的方式。
接下来,我们将了解创建仪表板的方法。
构建金层可视化
在你的数据湖中的金层是消费就绪层。在这个层中,最终转换和聚合使数据中的见解结晶,以便为报告和仪表板准备就绪。能够与受众分享你的数据至关重要,DI 平台提供了几种这样做的方式。事实上,Lakeview 和 Databricks SQL 仪表板都允许你在可视化中转换和聚合你的数据。让我们看看如何做到这一点。
利用 Lakeview 仪表板
在 Databricks 中的 Lakeview 仪表板是创建数据可视化和共享数据中隐藏的见解的有力工具。可视化可以使用英语进行,这使得仪表板创建对更多用户可用。要创建 Lakeview 仪表板,首先点击 ml_in_action.favorita_forecasting.train_set 表。这通过选择提供的表中的所有记录来创建一个数据集。注意我们不需要必须编写任何 SQL 或创建聚合来可视化数据聚合。

图 8.2 – 添加数据到 Lakeview 仪表板的“数据”选项卡
一旦你有了数据集,返回到 画布 选项卡。选择位于浏览器窗口底部蓝色栏上的 添加可视化 按钮。这为你提供了一个可以放置在仪表板上的小部件。放置后,你的小部件将类似于 图 8**.3。

图 8.3 – 一个新的 Lakeview 小部件
在新的小部件中,您可以使用右侧菜单上的选项手动创建一个可视化。或者,Databricks 助手可以帮助您仅用英语快速构建图表。您可以写下自己的问题,或者探索建议的查询。我们选择了建议的问题“按日期查看促销趋势是什么?”来自动生成图表,以及“图 8**.4”的结果。


图 8.4 – English text generated Lakeview widget
当您准备好分享您的仪表板时,您可以发布它!Lakeview 仪表板背后的引擎针对性能进行了优化,可以提供更快的交互式图表。它也足够强大,可以处理流数据。此外,Lakeview 仪表板通过 Unity Catalog 与 DI 平台统一,提供数据血缘。它们旨在轻松跨工作区共享,这意味着其他工作区中的用户可以访问您精心制作的仪表板。
使用 Databricks SQL 仪表板可视化大数据
Lakeview 仪表板是 Databricks 的未来。然而,您也可以使用select语句构建仪表板,您可以生成数据并用于多个可视化。
注意
要在您自己的工作区中重新创建“图 8**.5”,您需要取消选中LIMIT 1000复选框。可视化仍有 64,000 行的限制。绕过这个限制的最好方法是过滤或聚合。
图 8**.5是我们从一个简单的 SQL 查询(针对Favorita Store Sales数据)创建的示例可视化。


图 8.5 – 在 DBSQL 编辑器中执行选择语句后,我们创建可视化而无需编写任何代码
假设您的数据集包含您想要用于过滤和比较特征的分类变量,例如与Favorita销售数据一样。您可以在 DBSQL 编辑器中添加过滤器而无需修改查询。要添加过滤器,请点击+并选择filter或parameter。这两个选项都提供了用于过滤的小部件,如图图 8**.6所示。您可以使用这些小部件与任何与查询关联的可视化或仪表板。


图 8.6 – (L) 状态和家庭过滤器配置; (R) 向 Favorita 销售查询添加两个过滤器后的结果
如图 8**.7所示的仪表板功能内置在 Databricks SQL 中,作为展示从单个或多个查询创建的图表和其他可视化的方式。


图 8.7 – 从 Favorita 销售数据查询创建的图表仪表板
DBSQL 内置的可视化功能是快速探索数据的一种方式,无需连接到外部仪表板或数据可视化工具。
接下来,我们将通过一个示例来了解如何在 DBSQL 中使用 Python 用户定义函数(UDFs)进行可重用 Python 代码。
Python UDFs
Python UDFs 是在 Python 中创建可重用代码片段的方法,这些代码片段可以在 DBSQL 中使用。在这个例子中,我们将为销售分析师创建一个用于在客户记录中编辑信息的 UDF。第五行指示函数的语言语法是在 $$ 符号之间使用 Python:

图 8.8 – 在 DBSQL 中创建 Python UDF
UDFs(用户定义函数)作为 Unity Catalog 的一部分进行定义和管理。一旦定义了 UDF,您可以使用 GRANT EXECUTE 授予团队执行 UDF 的能力。

图 8.9 – 授予销售分析师组执行 UDF 的权限
在这个 SQL 查询中,我们将 redact UDF 应用到 contact_info 字段。
.jpg)
图 8.10 – 在 SQL 查询中使用 Python UDF
现在我们已经了解了可视化数据和在 SQL 中应用 Python UDFs 的基础知识,接下来让我们介绍一些小贴士和技巧。
小贴士和技巧
本节涵盖了与 DBSQL 相关的小贴士和技巧。一些技巧适用于 DBSQL 和 Lakeview,但并非全部:
-
尽可能使用托管计算(也称为无服务器计算):如 第一章 (Chapter 1) 中提到的,使用 Databricks 的 SQL 仓库进行查询的性能创下了记录。DBSQL 的新托管计算将首次查询性能缩短到大约 10 秒。这意味着空闲时间大大减少,这转化为成本节约。
-
使用子查询作为参数过滤器:在您的查询可视化和仪表板中,您可以预先填充下拉筛选框。您可以通过在 SQL 编辑器中创建和保存查询来实现这一点。例如,您可以创建一个返回客户名称唯一列表的查询。在 图 8.11 中,我们选择了一个名为 Customer Name Lookup Qry 的查询作为子查询,以按客户名称筛选查询可视化。因此,我们可以使用下拉列表来筛选 客户。

图 8.11 – 将子查询作为查询的参数使用
- 安排报告交付:如果您有希望定期收到最新仪表板的用户,您可以安排刷新并将其发送给订阅者。对于 DBSQL 仪表板,请记住在开发时关闭 启用,以免用户收到过多的更新。
![图 8.12 – 使用订阅者(T)DBSQL(B)Lakeview 计划仪表板报告
![图片 B16865_08_11.jpg]
图 8.12 – 使用订阅者(T)DBSQL(B)Lakeview 调度仪表板报告
- 使用 Databricks Assistant 加速开发:正如我们在第四章中所述,Databricks Assistant 是一个基于 AI 的界面,可以帮助生成、转换、修复和解释代码。助手是上下文感知的,这意味着它使用 Unity Catalog 来查看您环境中表和列的元数据,并为您个性化。在图 8.13 中,我们要求助手帮助编写一个使用分组语法的查询。它看到了Favorita****Stores表的元数据,并为该表和感兴趣的列提供了特定的代码。
![图 8.13 – 使用 Databricks Assistant 帮助编写查询
![图片 B16865_08_12.jpg]
图 8.13 – 使用 Databricks Assistant 帮助编写查询
- 保持警觉:通过警报关注重要数据变化。使用 SQL 调整警报,并通过图 8.14 中显示的 UI 在特定间隔内安排条件评估。您可以使用 HTML 创建格式化的警报电子邮件。
![图 8.14 – 当满足特定条件时触发调度警报
![图片 B16865_08_13.jpg]
图 8.14 – 当满足特定条件时触发调度警报
- 使用标签跟踪使用情况:在创建新的 SQL 仓库时,使用标签对您的仓库端点进行编码,以正确标记项目。标记是了解按项目或团队使用情况的好方法。系统表包含跟踪使用情况的信息。
![图 8.15 – 使用标签将端点连接到项目
![图片 B16865_08_14.jpg]
图 8.15 – 使用标签将端点连接到项目
接下来,您将学习如何将您的模型连接到应用程序。
连接您的应用程序
您可以使用 Databricks Model Serving 在任何地方部署您的模型,这是您在第七章中部署您的 RAG 聊天机器人模型的方式。在本节中,我们将介绍如何在Hugging Face(HF)中托管 ML 演示应用程序。拥有一种简单的方式来托管 ML 应用程序,让您能够构建您的 ML 投资组合,在会议或与利益相关者展示您的项目,并与 ML 生态系统中的其他人协作工作。使用 HF Spaces,您有多种选择来决定您使用哪个 Python 库来创建 Web 应用程序。其中两个常见的选择是 Streamlit 和 Gradio。
我们更喜欢 Gradio。它是一个开源的 Python 包,允许您快速为您的机器学习模型、API 或任何任意的 Python 函数构建演示或 Web 应用程序。然后,您只需使用 Gradio 内置的共享功能,在几秒钟内就可以分享您的演示或 Web 应用程序的链接。无需 JavaScript、CSS 或 Web 托管经验 – 我们非常喜欢它!
在应用我们的学习部分的 RAG 项目工作中,我们将向您展示如何将聊天机器人部署到 HF Space。
将 LLMs 与 SQL AI 函数结合为分析师
有许多用例可以集成 LLM,如 DBRX 或 OpenAI,以获得见解。使用 Databricks 数据智能平台,对于最舒适使用 SQL 的分析师来说,利用机器学习和人工智能的进步也是可能的。
在 Databricks 中,你可以使用AI 函数,这些是内置的 SQL 函数,可以直接访问 LLMs。AI 函数可用于 DBSQL 界面、SQL 仓库 JDBC 连接或通过 Spark SQL API。在图 8.16 中,我们正在利用 Databricks SQL 编辑器。
基础模型 API
Databricks 托管的基础模型的数据存储和处理完全在 Databricks 平台内部进行。重要的是,这些数据不会与任何第三方模型提供商共享。当使用连接到具有自己数据隐私政策的服务的 External Models API 时,这并不一定成立。当你关注数据隐私时,请记住这一点。你可能能够支付一个限制你数据使用的服务层级的费用。
让我们做一些简单的情绪分类。由于我们一直在使用的三个数据集都不包含任何自然语言,我们首先创建一个小数据集。你也可以下载一个数据集(如 Kaggle 的 Emotions 数据集)或使用你可用的任何其他自然语言来源:
- 首先,让我们探索内置的
AI_QUERYDBSQL 函数。此命令将我们的提示发送到远程配置的模型并检索结果。我们使用 Databricks 的 DBRX 模型,但你也可以使用各种其他开源和专有模型。打开 Databricks SQL 编辑器,并输入如图 8.16 所示的代码。让我们编写一个查询,以获取我们可以分类的样本句子。

图 8.16 – 使用 AI_QUERY 函数构建提示
- 如果你没有准备好数据集,也不想下载,你可以构建一个为你生成数据集的函数,如图所示。我们正在扩展步骤 1的提示,以获取几个 JSON 格式的句子。

图 8.17 – 创建生成虚假数据的函数
- 现在使用
GENERATE_EMOTIONS_DATA函数构建一个小数据集。快速查看数据后,看起来我们有一个很好的情绪样本。

图 8.18 – 生成虚假情绪数据
- 现在,我们将编写一个名为
CLASSIFY_EMOTION的函数。我们再次使用 AI 函数AI_QUERY,但这个函数将使用一个新的提示,要求模型将给定的句子分类为六种情绪之一。

图 8.19 – 创建按情绪分类句子的函数
- 让我们调用我们的函数来评估一个示例句子,并查看结果。
![图 8.20 – 调用 CLASSIFY_EMOTION 函数
![图片 B16865_08_19.jpg]
图 8.20 – 调用 CLASSIFY_EMOTION 函数
- 最后,为了对表中的所有记录进行分类,我们在表中的记录上调用
CLASSIFY_EMOTION函数并查看结果。
![图 8.21 – 在表上调用 CLASSIFY_EMOTION 函数
![图片 B16865_08_20.jpg]
图 8.21 – 在表上调用 CLASSIFY_EMOTION 函数
SQL AI 函数是将 LLM 的力量交到 SQL 用户手中的绝佳方式。像 SQL AI 函数这样的解决方案仍然需要一些技术知识。Databricks 正在研究允许业务用户直接访问数据的方法,这样就不需要太多的前期开发,以便让您的团队更快地运转。请密切关注令人兴奋的新产品功能,这些功能将消除编程经验障碍,释放您数据的价值!
应用我们的学习
让我们运用我们所学的知识,使用 Favorita 项目的表元数据构建一个 SQL 聊天机器人,监控流式事务项目的模型,并部署我们已组装和评估的聊天机器人。
技术要求
完成本章动手实践所需的技术要求如下:
-
SQLbot 将需要 OpenAI 凭证。
-
我们将使用 Databricks Secrets API 来存储我们的 OpenAI 凭证。
-
您需要个人访问令牌(PAT)才能将您的 Web 应用部署到 HF。请参阅进一步阅读以获取详细说明。
项目:Favorita 店铺销售
让我们使用 OpenAI 的 GPT 构建一个简单的 SQLbot,以询问有关我们的 Favorita 销售表的问题。请注意,尽管本节继续使用 Favorita Store Sales 数据,但它并不是早期项目工作的延续。在这个例子中,您将创建有关机器人如何请求表列表、从这些表中获取信息以及从表中采样数据的说明。SQLbot 将能够构建 SQL 查询并解释结果。要运行本例中的笔记本,您需要在 OpenAI 开发者网站上拥有一个账户,并请求 OpenAI API 的密钥。
要在自己的工作区中跟随,请打开以下笔记本:
CH8-01-SQL Chatbot
在 Databricks 笔记本中保留秘密 API 密钥绝不是最佳实践。您可以锁定笔记本访问并添加配置笔记本到您的 .gitignore 文件中。然而,您移除人们访问的能力可能不在您的控制之下,这取决于您的角色。通常,管理员权限包括查看所有代码的能力。OpenAI API 密钥与您的账户和信用卡相关联。请注意,运行笔记本一次花费了我们 $0.08。
我们将我们的 API 密钥添加到 Databricks 密钥中。Secrets API 需要使用 Databricks CLI。我们通过 Homebrew 设置了我们的 CLI。如果您还没有设置,我们建议为您的 workspace 设置 Secrets。这可能需要管理员协助。首先,安装或更新 Databricks CLI。当您获得版本 v0.2 或更高版本时,您就知道 CLI 已正确安装。我们正在使用 Databricks CLI v0.208.0。
我们遵循以下步骤设置我们的 API 密钥作为密钥:
-
创建一个作用域:
databricks secrets create-scope dlia -
在作用域内创建一个密钥:
databricks secrets put-secret dlia OPENAI_API_KEY -
将您的 API 密钥粘贴到提示中。
一旦您的密钥成功保存,我们就可以通过笔记本中的 dbutils.secrets 访问它。
现在,我们已经设置好通过 API 使用 OpenAI。我们不必担心意外提交我们的 API 或同事运行代码,而不知道这会花费您金钱。
接下来,让我们一步一步地专注于创建我们的 SQLbot 笔记本,从设置开始:
-
首先,我们安装了三个库:
openai、langchain_experimental和sqlalchemy-databricks。 -
要创建与 OpenAI 的连接,请传递之前设置的密钥并打开一个
ChatOpenAI连接。 -
在 图 8.22 中,我们创建了两个不同的模型。第一个是默认模型,第二个使用 GPT 3.5 Turbo。

图 8.22 – OpenAI API 连接
- 设置文件没有设置您的模式变量。定义您的模式;我们选择了
favorita_forecasting。我们一直使用database_name而不是模式。然而,我们指定了我们要对其提出 SQL 问题的数据库,这是不同的。


图 8.23 – (L) 收集表模式和系统信息模式; (R) 删除不必要的重复列
- 接下来,我们创建了两个辅助函数。第一个函数组织提供的模式信息
table_schemas,创建一个表定义。第二个函数收集两行数据作为示例。

图 8.24 – 组织表格信息的辅助函数
- 遍历表和列数据,利用我们的辅助函数格式化 SQL 数据库输入。

图 8.25 – 遍历表并利用辅助函数
- 现在,我们所有的数据都已准备好,可以创建一个 SQL 数据库,以便 OpenAI 进行通信。您需要编辑
endpoint_http_path以匹配您 workspace 中活动 SQL 仓库的路径。数据库被传递到默认的 OpenAI 模型和 GPT 3.5 模型。
![图 8.26 – 为 OpenAI 创建一个只包含我们提供的信息的查询数据库
![图片 B16865_08_26.jpg]
图 8.26 – 为 OpenAI 创建一个只包含我们提供的信息的查询数据库
设置完成后,我们现在可以与我们的 SQL 聊天机器人模型交互了!让我们从一个基本问题开始:哪个商店销售 最多?
在*图 8**.27 中,我们对问题运行了两个模型并得到了两个不同的答案。
![图 8.27 – SQL 聊天机器人模型对我们问题“哪个商店销售最多?”的响应。(T)db_chain.run(question) (B)chat_chain.run(question)
![图片 B16865_08_27.jpg]
图 8.27 – SQL 聊天机器人模型对我们问题“哪个商店销售最多?”的响应。(T)db_chain.run(question) (B)chat_chain.run(question)
随着 OpenAI 的 GPT 模型新版本的发布,你的 SQLbot 的结果和行为可能会发生变化。随着新模型和方法的可用,测试它们并观察这些变化如何影响你的工作和聊天机器人的结果是一个好的实践。在 SQLbot 实验中利用 MLflow 将帮助你追踪和比较生产过程中的不同特性和配置。
项目 -流式传输事务
你已经准备好完成这个项目了。生产工作流程笔记本是工作流程作业中创建的CH7-08-Production Generating Records、CH7-09-Production Auto Loader和CH7-10-Production Feature Engineering组件。一旦新工作流程到位,你将运行相同的作业。要在自己的工作区中跟随,请打开以下笔记本:CH8-05-Production Monitoring
在CH8-05-Production Monitoring笔记本中,你创建了两个监控器 – 一个用于prod_transactions表,另一个用于packaged_transaction_model_predictions表。参见图 8**.28了解后者。
![图 8.28 – 推理表监控
![图片 B16865_08_28.jpg]
图 8.28 – 推理表监控
恭喜!流式传输项目已完成。我们鼓励你添加改进并将其提交回仓库。以下是一些可能的示例:向验证笔记本添加更多验证指标,将推理性能结果纳入重新训练的决定,并对数据生成的配置进行调整以模拟漂移。
项目:检索增强生成聊天机器人
要在自己的工作区中跟随,请打开以下笔记本和资源:
-
CH8-
app.py -
CH8-01-Deploy Your Endpointwith SDK -
Hugging Face Spaces 页面
首先,我们需要确保我们的聊天机器人使用模型服务进行部署,如图 图 8**.30 所示。在这里,我们通过模型服务页面的 UI 使用最快的方式。为了跟随并服务,我们选择了我们在 第七章 中注册的已注册模型。选择最新版本 – 在我们的案例中,它是版本 4。对于这个演示项目,我们预计并发量最小,因此端点将只有四个可能的并发运行,并在没有流量时扩展到 0。我们正在同一目录下启用推理表以跟踪和可能进一步监控我们的有效载荷。我们不会在本章中演示如何为 RAG 项目设置监控器或数据质量管道,因为它已经在流项目中被演示过。我们鼓励您在自己的项目中应用它!

图 8.29 – 通过 UI 进行模型服务部署的示例
为了使您的应用程序能够连接到附加的资源,例如向量搜索,端点需要您在 高级配置 中为端点提供额外的配置,例如您的 PAT 和主机:

图 8.30 – 高级配置要求
注意
您还可以使用 Databricks SDK 服务来部署您的端点。如果您想了解如何使用 SDK 部署,请使用附在 CH8 - 01 -Deploy Your Endpoint 下的笔记本 with SDK。
跳转到 Hugging Face Spaces 网站。如何在 HF Spaces 中部署您的第一个 HF Space 的说明在 HF Spaces 的主页上有很好的解释,所以我们在这里不会重复它们。我们想强调的是,我们正在使用 Spaces 的免费部署选项,带有 2 个 CPU 和 16 GB 的内存。
当您部署您的 Space 时,它将看起来像这样:

图 8.31 – 空的 Hugging Face Space
我们想强调一些重要的事情,以便连接到使用 Databricks 模型服务实时提供的聊天机器人。要将聊天机器人连接到您的 HF Space,您必须设置 API_TOKEN 和 API_ENDPOINT。以下是设置这些值的方法:
-
前往您创建的 HF Space 的 设置。
-
滚动到 变量 和秘密。
-
将您的 API_ENDPOINT 设置为 Databricks 模型服务页面上提供的 REST API 的 URL。
-
使用 Databricks 生成的个人访问令牌设置您的 API_TOKEN。这是连接到端点所必需的。

图 8.32 – HF Spaces 上的变量和秘密示例
- 一旦设置完成,您就可以将您的 Gradio 网页应用脚本带入您的 HF Space。

图 8.33 – HF 空间中变量和秘密的示例
-
当您的端点准备好后,返回您的 HF 空间。
-
在预先创建的空间下方的 文件 选项卡中点击 + 添加文件**。
-
现在添加您得到的
CH8-app.py文件 – 您可以创建自己的网络应用。根据您的业务需求,自由地尝试设计。
让我们简要谈谈 CH8-app.py 文件中的 respond 函数 – 见 图 8.34,它被传递到我们应用的 UI 聊天机器人。在这个例子中,respond 函数是您部署的端点的调用者,我们不仅发送和接收响应,还可以塑造输入或输出的格式。在我们的案例中,端点期望接收一个格式为 JSON 的请求,其中包含字段输入的列表中的问题,而输出是一个包含字段预测的 JSON。

图 8.34 – 在 Gradio 应用中编写的响应函数
正如引言部分所述,要创建聊天机器人,我们使用了一个简单的 Gradio 示例,其中添加了诸如应用程序标题、描述和示例问题等选项。图 8.35 展示了完整的代码。

图 8.35 – 您 LLM 的 Gadio app.py 界面
聊天机器人现在拥有一个更用户友好的界面,如图 图 8.36 所示。

图 8.36 – 您聊天机器人应用的界面
让我们提出几个问题以确保我们的 RAG 聊天机器人提供正确的结果。

图 8.37 – 我们 RAG 应用中聊天机器人回答的示例
如果响应看起来不错,您的应用程序就准备好使用了!
摘要
从您的机器学习实践中获取价值的重要方式之一是分享您模型中的洞察。使用仪表板作为分享您信息的中介是一种便于与业务用户和数据科学团队之外的小组沟通洞察的方法。在本章中,我们讨论了如何构建黄金层,使用 DBSQL 仪表板展示数据的技巧,利用 DBSQL 中的创新,如 OpenAI 模型,以及您如何通过 Databricks 市场共享数据和 AI 艺术品,以从企业数据中获得最大价值。
我们希望您有机会亲自动手构建您的数据湖。从探索、清洗、构建管道、构建模型到发现数据中的隐藏洞察,再到分享洞察 – 所有这些都可以在 Databricks 平台上完成。我们鼓励您尝试使用笔记本进行实验!作者们很乐意听到您的反馈,以及这在本旅途中对您使用 Databricks 平台是否有帮助。
问题
让我们通过以下问题来测试一下我们所学的知识:
-
金层和银层之间有哪些区别?
-
你可以通过什么方式设置一个警报来识别一个表有无效值?
-
你为什么会选择使用外部仪表盘工具?
-
如果你通过 API(如 OpenAI)使用语言模型,你发送 API 的数据有哪些考虑因素?
-
一家公司为什么会在 Databricks Marketplace 上共享数据?
答案
在思考了这些问题之后,比较你的答案和我们的答案:
-
金层比银层更精细和聚合。银层为数据科学和机器学习提供动力,而金层为分析和仪表盘提供动力。
-
你可以监控字段的值,并在值无效时发送电子邮件警报。
-
有时公司会使用多个仪表盘工具。你可能需要提供团队习惯使用的仪表盘中的数据。
-
如果我是一个通过 API 的语言模型,我会对发送敏感数据保持谨慎,包括 PII、客户信息或专有信息。
-
一家公司可能会在 Databricks Marketplace 上共享数据,以便货币化数据或使其对外部人员易于使用且安全地使用。
进一步阅读
在本章中,我们指出了具体的技术、技术特性和选项。请查看这些资源,以深入了解你最感兴趣的领域:
-
Databricks SQL 语句执行 API:
www.databricks.com/blog/2023/03/07/databricks-sql-statement-execution-api-announcing-public-preview.html -
赋予 SQL 人群力量:介绍 Databricks SQL 中的 Python UDFs *:
www.databricks.com/blog/2022/07/22/power-to-the-sql-people-introducing-python-udfs-in-databricks-sql.html -
使用 Databricks SQL AI 函数在规模上执行客户评价*:
www.databricks.com/blog/actioning-customer-reviews-scale-databricks-sql-ai-functions -
Databricks 创下了官方数据仓库性能 记录:https://dbricks.co/benchmark
-
Databricks Lakehouse 和数据 Mesh:
www.databricks.com/blog/2022/10/10/databricks-lakehouse-and-data-mesh-part-1.html -
Hugging Face:
huggingface.co/spaces -
Gradio:
www.gradio.app/ -
Hugging Face Spaces:
huggingface.co/docs/hub/en/spaces-overview -
Databricks Lakehouse 监控 文档:
api-docs.databricks.com/python/lakehouse-monitoring/latest/databricks.lakehouse_monitoring.html#module-databricks.lakehouse_monitoring -
Databricks 个人访问令牌认证
docs.databricks.com/en/dev-tools/auth/pat.html


浙公网安备 33010602011771号