TowardsDataScience 2023 博客中文翻译(二百四十八)

原文:TowardsDataScience

协议:CC BY-NC-SA 4.0

Orca: 正确模仿专有 LLMs

原文:towardsdatascience.com/orca-properly-imitating-proprietary-llms-44ffa0293adb

利用模仿来创建高质量的开源 LLM…

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Cameron R. Wolfe, Ph.D.

·发表于 Towards Data Science ·阅读时长 16 分钟·2023 年 9 月 30 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(照片由 Thomas Lipke 拍摄,来自 Unsplash

随着对大型语言模型(LLMs)研究的深入,一个关键问题尚未得到回答,那就是现有的高质量 LLM 是否可以有效地用来训练另一个 LLM。目前,围绕这一主题存在大量的辩论和争议。最近,开源模仿模型的爆炸性增长最初表明,像 ChatGPT 这样的专有 LLM 可以以低成本轻松复制。然而,随后的研究得出结论,这些模型的评估是不完整且具有误导性的,发现这些模型实际上在理解方面存在很大差距。在这次概述中,我们将研究工作[1],旨在通过更稳健的方法解决专有 LLM 的开源复制品的局限性。特别是,我们将看到,通过策划一个更大、更详细的数据集,模仿学习可以变得更加有效。

“随着这些模型的不断发展并变得更强大,一个有趣的问题出现了:我们能否利用模型本身来监督其自身行为或其他 AI 模型的行为?” — 来源于 [1]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来源于 [1])

背景信息

在深入概述之前,我们将介绍一些与 LLM 和深度学习相关的概念。这些概念可能在我们阅读的论文中没有明确描述,而是通过引用或被假定为常识。因此,了解这些基本概念将使这次概述及其涉及的论文更容易理解。

指令调整

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [12])

指令调整最初由FLAN [12] 提出,旨在提供一种训练形式,教会大语言模型(LLM)解决语言基础任务,而不是特定任务。具体而言,这通过对一组“指令”或输入提示进行微调来完成——包括解决的任务描述——以及期望的模型输出;见上文。最近的大语言模型主要使用一种特定的指令调整变体,该变体通过人类或其他 LLM 的对话示例对 LLM 进行微调。通常,指令调整是在预训练之后进行的微调步骤;见下文。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

指令调整与其他常见训练范式(来自 [12])

合成指令调整。 尽管人类可以手动创建用于指令调整的数据,我们也可以使用 LLM 合成生成这些数据。有两种基本方法:

  • 从另一个模型获取示例对话会话(例如,从ShareGPT)。

  • 使用提示框架(例如,自我指令 [9])来生成和完善高质量的对话示例。

这两种方法都是有效的,但它们各有局限。例如,公共 LLM 对话示例往往偏向于某些任务,例如创意内容生成或信息获取对话。此外,通过自我指令 [9] 生成的对话往往缺乏复杂性,尽管这个问题通过 Evol-Instruct [2] 策略得到了缓解,该策略明确指示和引导 LLM 生成更复杂的内容;见下文。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [2])

系统消息

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 OpenAI API 文档)

我们互动的大多数基于聊天的 LLM 允许我们提供系统消息;见上文。该消息基本上是对模型的指令,描述了期望其如何对用户做出反应。在 ChatGPT 和 GPT-4 API 使用的聊天标记语言中,该系统消息被赋予“系统”角色——与“用户”或“助手”相对——在聊天记录中。通常,系统消息是我们应该放置在与用户对话过程中 LLM 应遵循的任何指令的地方。

现代大型语言模型是可引导的。 尽管以前的大型语言模型(例如早期版本的 GPT-3.5-turbo)对系统消息关注不多,但当前的模型(例如 GPT-4)则更具引导性。这意味着我们可以在系统消息中提供详细的指示,以供大型语言模型遵循。在实践中,现代大型语言模型的这一特性可以用来调整它们的风格或格式(通过系统消息),以精确匹配我们正在解决的应用或任务。

其他有用的想法

  • 知识蒸馏和模型模仿:我们在之前的综述中已经详细解释了这个概念,但它与本综述中提出的分析非常相关。[link]

  • 打包技术:这是在[1]中使用的一个技巧,简单地将多个文本序列连接成一个单一示例进行训练,以避免在每个序列后面过多的填充,并提高效率。[link]

  • 思维链提示[13]:我们已经看到,鼓励大型语言模型在回答问题时给出问题解决的理由,可以提高推理能力。在[1]中的解释调优(更多细节稍后提供)与这种技术有很多基本的相似之处。[link]

  • 课程或渐进学习:我们可以制定一个特定的策略或课程来展示这些数据给模型,而不仅仅是训练一个模型处理我们所有的数据。在[1]的案例中,这个课程包括首先用 ChatGPT 的对话示例训练模型,然后在 GPT-4 对话上进一步训练。这个术语相当通用,因为可能存在许多不同类型的课程。[link]

开源大型语言模型的爆炸性增长

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

开源大型语言模型的未来几乎和这张照片一样光明(来自 DreamStudio)

随着大型语言模型的受欢迎程度不断上升,最具影响力的模型(例如 GPT-3 和 ChatGPT)最初仅通过付费的专有 API 提供。然而,正如我们在最近的综述中了解到的那样,LLM 社区正在蓬勃发展,致力于创建强大的开源模型!虽然已经提出了许多开源模型,但这一运动特别受到最近提出的 LLaMA [4]的推动,这是一套高性能的基础模型,具有不同的规模,仅在公开数据上进行训练。

LLaMA 和模仿模型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从 LLaMA 创建的衍生模型(来自[5, 6, 7, 8])

LLaMA 套件中的 LLM 权重已公开发布(用于研究目的),随后在线泄露,任何人都可以访问。此泄露事件后,LLaMA 快速获得了人气,并被用于创建各种开源衍生模型,我们在之前的概述中已进行了探讨。

  • 超越 LLaMA:开源 LLM 的力量 [link]

  • 模仿模型与开源 LLM 革命 [link]

这些 LLaMA 衍生模型主要是通过模仿方法创建的,该方法在来自更强大模型(例如 ChatGPT)的对话示例上调整 LLaMA。这些模仿模型接连被提出,似乎表现非常好——在某些情况下甚至与像 ChatGPT 这样的强大模型相媲美 [6]。这使得 LLM 社区相信专有 LLM 可以很容易地被复制,但事情比这要复杂一些。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [3])

模仿还是限制? 尽管模仿模型似乎表现良好,但我们在之前的工作 [3] 中看到,这仅在微调过程中观察到的小部分任务中适用。即,大多数模仿模型捕捉了像 ChatGPT 这样的专有 LLM 的风格,但它们未能捕捉这些模型的知识、推理能力和理解能力。这种限制在人类对模型的评估中很容易被忽视,因为验证模型的信息是否事实正确需要大量时间投入。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

由于现代 LLM 在生成连贯文本方面非常出色,它们之间的差异可能难以测量,尤其是当被比较的模型具有相似的风格和流畅度时。当模仿模型通过广泛的定量基准进行更严格的评估时,我们开始清楚地看到它们的不足之处。例如,Vicuna [6] 的表现——这是用 LLaMA 创建的较高性能的模仿模型之一——在更困难和复杂的基准测试中远远落后于 ChatGPT;见上文。

为什么模仿没有效果?

当我们研究通过模仿方法创建开源专有 LLM 的现有尝试时,我们看到的大多数问题都由相同的问题造成:我们没有足够的高质量数据用于指令调整。我们可以生成这些数据的三种基本方法是:

  1. 让人类生成数据

  2. 使用提示框架(例如,自我指导 [9])生成合成数据

  3. 直接在现有 LLM 的输出上进行训练

像 GPT-4 这样的流行 LLMs 在大量人类反馈上进行训练,但生成数据是昂贵且耗时的。为了自动化数据收集,近期的模仿模型依赖于某种变体的自我指导[9]来生成合成——即数据是由 LLM 生成而非人类——微调数据集。不幸的是,这种方式生成的数据集往往缺乏多样性和复杂性。而且,当直接在从公共 API 或 ShareGPT 获取的 LLM 对话上进行微调时,我们也会遇到类似的问题。这些数据集往往规模小且同质化,这对于创建强大的模仿模型是不足够的。

“我们得出结论,纯粹通过模仿广泛匹配 ChatGPT 需要全力收集巨大的模仿数据集,并且需要比目前可用的数据更为多样化和高质量的模仿数据。” — 来自[3]

前进的道路。 尽管现有的模仿尝试未能达到预期,但我们可以有几种不同的前进方式。如[3]中所提,我们可以从创建更强大的开源基础 LLMs 开始,这些基础 LLMs 可以作为更好的“起点”进行指令调优。之前的工作表明,使用更好的基础 LLM 可以显著提高结果模仿模型的性能。我们看到,像FalconMPT这样令人惊叹的开源基础模型的提案已经在广泛探索这个领域。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自[1])

另外,我们可以考虑改进或扩展现有的用于模仿学习的数据集。目前的工作仅依赖于 LLM 生成的提示和响应对;见上文。在这个概述中,我们将把这些对话称为“浅层”模仿示例,因为它们仅包含关于专有 LLM 对提示的响应的信息。超越浅层模仿,本概述将探讨通过专有 LLM 提供的更详细输出来增强合成指令调优数据集的想法,例如:

  • 解释跟踪

  • 逐步思考过程

  • 复杂指令

模仿模型可以从专有模型在微调过程中生成的额外信息中学习。我们希望模仿数据集大而多样。然而,在这个概述中,我们将看到使用的数据类型和粒度也可以产生巨大的差异。这些额外信息可以让较小的开源 LLMs 学习到更强大模型所遵循的推理过程。

正确学习模仿

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自[1])

为了缓解现有模仿模型的问题,文献 [1] 中的作者提出了一个 130 亿参数的模仿 LLM,称为 Orca。与先前的模仿模型类似,Orca 基于 LLaMA 系列的 LLMs,但它使用的不仅仅是一小部分“浅层”模仿示例进行微调。更具体地说,Orca 在两个主要方面与先前的工作有所不同:

  • 一个更大、更全面的模仿数据集

  • 在每个指令调优示例中注入详细的解释痕迹

结果模型在各种基准测试中表现相当出色,从而缩小了模仿模型与专有 LLMs(例如,ChatGPT 或 GPT-4)之间的差距;见下文。然而,正如我们将看到的,GPT-4 仍然要好得多。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

更大更好的数据。 Orca 从 FLAN collection [10] —— 一个用于指令调优的大型数据源 —— 中有选择地抽取任务,并从这些任务中的复杂提示中获取了来自 ChatGPT 和 GPT-4 的数百万个回应。通过系统消息,作者鼓励这些模型用更多细节解释其回应,从而为每个由 LLM 生成的输出提供“解释痕迹”。这种方法对模型质量有着巨大影响,因为它提供了一个更丰富的信息来源,从中模仿模型可以学习。我们将这种方法称为“解释调优”——它只是对包含解释痕迹的数据进行的指令调优!

“我们的研究表明,无论这些逐步解释是由人类还是更先进的 AI 模型生成的,逐步解释的学习都是提升模型能力和技能的一个有前途的方向。” — 来自 [1]

与先前工作的关系。 在先前的概述中,我们看到基于 LLaMA 的模仿模型远远不能模仿专有 LLMs。为了缩小模仿模型与专有 LLMs 之间的能力差距,我们需要一个显著更大和更多样化的模仿数据集。文献 [3] 中的先前工作声称获取这样的数据集太困难,表明模仿模型是一条死胡同。然而,文献 [1] 中的作者正是这样做的(即,生成一个大规模且复杂的模仿数据集),以实现模仿模型质量的突破。

更好的模仿学习方法…

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

Orca 在模仿模型质量上的突破可以归因于其更大、更详细和更复杂的模仿数据集;见上文。让我们探索这个数据集的细节,重点关注专有模型如何被提示以输出逐步问题解决解释,这对于开源模仿模型是一个更强大的学习信号。

解释调优。 之前的模仿模型是在由 LLM 生成的提示和相关回应对上进行训练的。虽然这种方法可以教会模仿模型复制或记忆教师模型的输出,但仅从模型的回应中学到的东西不多——这些信息浅显且缺乏有关回应是如何产生的或为何产生的详细信息。在[1]中,作者探索了一种替代方法,该方法训练模仿模型如何复制教师模型的推理过程。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来源于[1])

为此,我们只需要提示教师模型输出详细解释以及其正常回应。借鉴零样本 CoT 提示的思想[11],我们可以通过调整系统消息来鼓励模型在每次回应时提供详细解释;见上文。然后,我们可以利用回应和解释作为训练信号来微调模仿模型。正如我们在先前的工作中所见[11],教会一个 LLM 在每次回答时输出如此详细的解释痕迹,可以显著改善推理任务和复杂指令的跟随。

创建数据集。 为了微调 Orca,通过从FLAN collection中包含的数百万条指令中采样来创建一个大规模的模仿数据集,如下表所示。结果数据集称为 FLAN-5M。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来源于[1])

FLAN-5M 指令集通过使用 OpenAI API 从 ChatGPT 获得的回应和解释进行增强。同样,使用一组称为 FLAN-1M 的较小采样指令集(即,我们基本上只是从原始的 5M 指令集中进行子采样),使用 GPT-4 执行类似程序,生成一个总计 600 万条指令示例的数据集,每条指令配有来自专有教师模型的回应和解释。有趣的是,[1]中的作者指出,从每个模型收集数据需要几周时间——即使使用Azure OpenAI service——由于速率限制;见下文。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来源于[1])

渐进学习。 我们可以通过首先在 ChatGPT 基础上的解释中微调 Orca,然后再在 GPT-4 的解释中微调,从而在所有数据上训练时实现性能的提升。鉴于 Orca 基于一个较小的 LLaMA 模型,这个模型的能力明显低于专有 LLM,这种渐进学习方法使得模仿模型能够先从“较简单”的例子中学习,然后再从像 GPT-4 这样强大的模型的更详细解释中学习。这种方法的积极影响可能源于 GPT-4 往往生成较长且复杂的解释,这些解释更难以学习;见下文。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

基于解释的模仿学习是有效的!

Orca 与多种不同的基准进行比较,包括 Vicuna [6]、text-davinci-003(即 GPT-3.5)、ChatGPT 和 GPT-4。文献 [1] 中的作者考虑了一系列不同的基准,包括写作、理解和推理任务;见下文。Orca 的评估策略被做得非常全面,以避免先前模仿模型所遇到的误导或不完整的评估结果问题。值得注意的是,我们在 [1] 中看到,由标准化测试组成的基准提供了一个令人惊讶的强大评估框架。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

开放式生成。 在开放式生成任务的评估中,Orca 在所有实验设置中都大幅超越了 Vicuna;见下文。在这里,性能通过考虑参考模型(例如,ChatGPT 或 GPT-4)并提示 GPT-4 来确定候选模型生成的输出是否优于参考模型的输出来衡量。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

我们在这些实验中看到,Orca 在数据集上保持了 ChatGPT 质量的 95% 和 GPT-4 质量的 85%。虽然这些指标表明与先前的模仿模型相比性能有显著改善,但我们应记住 LLM 基于评估不完美 且仍在探索中。因此,这些结果虽然积极,但可能会误导。

推理。 Orca 在推理基准测试中继续表现出与 ChatGPT 相似的性能。例如,在 AGIEvalBigBench-Hard 数据集的(几乎)所有主题中,Orca 的表现接近或超过了 ChatGPT!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

尽管 Orca 在标准化考试中的表现仍然低于 ChatGPT 的某些情况,但我们看到[1]中的工作在弥合专有 LLMs 与之前模仿模型之间的差距方面取得了显著进展;见下文。尽管这可能并不令人惊讶,但 GPT-4 在几乎所有被考虑的任务中仍然是明显的领先者。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来源于 [1])

其他发现。 除了[1]中提出的主要实证结果之外,我们发现建议的课程(或渐进式)学习方法——即模型首先在 5M 个 ChatGPT 对话示例上进行微调,然后在 1M 个 GPT-4 示例上进行微调——对 Orca 的性能产生了很大且积极的影响。此外,Orca 在建模长序列时始终表现不如 ChatGPT。

结语

“我们的发现表明,Orca 在性能上显著优于其他开源较小模型。此外,在一些设置中,它可以匹配甚至超越 ChatGPT 的质量,但与 GPT-4 之间仍然存在较大的差距。” — 来源于 [1]

对开源 LLMs 的研究不断发展。一个星期,我们认为专有 LLMs 已经完全失去了优势,而下一个星期我们发现开源(模仿)模型远比最初声称的要差。尽管几周前模仿模型似乎是死路一条,但我们在本概述中看到模仿是一种有效的方法!我们所需要的只是更大更好的数据集。这项工作的主要结论如下。

从逐步说明中学习。 之前的模仿模型研究依赖于简单的提示-回应对进行训练。我们在这里看到,通过详细的解释轨迹来增强这些数据,使得结果模型能够从更丰富的信息源中学习。我们可以让专有的 LLM 的解决问题过程被复制,而不是仅仅记住模型在一小部分示例上的回应。因此,文献[1]中的方法使得模仿模型的性能能够超越在微调期间看到的数据。

“我们强调了数据规模和覆盖范围在将较小模型对齐到更强大的模型(如 GPT-4)时的重要作用。” — 来源于 [1]

大量的模仿数据。 之前模仿模型的一个主要问题是它们仅在与其微调数据集中的数据相似的任务上表现良好。鉴于这一特定限制,我们显然需要更大、覆盖范围更广的模仿数据集。尽管之前的工作表明,生成这样一个数据集会太困难,但我们在[1]中看到这是可能的。鉴于更大且更全面的数据集(即数百万个示例),我们可以使模仿模型比以前表现得更好。

剩余工作。 尽管 Orca 的表现令人印象深刻,但仍然不及最佳的专有语言模型——需要更多工作才能使开源语言模型真正具有竞争力。弥合这一差距很可能是多项正在进行的倡议的结果,例如模仿学习、创建更好的基础模型以及策划更好的公开数据集用于指令调整和语言模型改进。然而,开源产品不应被低估,因为它们将继续与专有产品一同改进。

与我联系!

非常感谢阅读本文。我是 Cameron R. WolfeRebuy 的 AI 总监。我研究深度学习的实证和理论基础。如果你喜欢这个概述,订阅我的 Deep (Learning) Focus 新闻通讯,我将通过从头到尾的相关话题概述帮助读者理解 AI 研究。你也可以在 XLinkedIn 上关注我,或查看我在 medium 上的 其他著作

参考文献

[1] Mukherjee, Subhabrata 等。“Orca: 从 GPT-4 的复杂解释痕迹中逐步学习。” arXiv 预印本 arXiv:2306.02707(2023)。

[2] Xu, Can 等。“Wizardlm: 赋能大型语言模型以遵循复杂指令。” arXiv 预印本 arXiv:2304.12244(2023)。

[3] Gudibande, Arnav 等。“模仿专有语言模型的虚假承诺。” arXiv 预印本 arXiv:2305.15717(2023)。

[4] Touvron, Hugo 等。“Llama: 开放且高效的基础语言模型。” arXiv 预印本 arXiv:2302.13971(2023)。

[5] Taori, Rohan 等。“斯坦福 Alpaca: 一款遵循指令的 LLaMA 模型。”(2023)。

[6] Chiang, Wei-Lin 等。“Vicuna: 一款开源聊天机器人,令人印象深刻的 GPT-4 质量达到 90%*。”(2023)。

[7] Geng, Xinyang 等。“Koala: 一款用于学术研究的对话模型。”(2023)。

[8] Yuvanesh Anand, Zach Nussbaum, Brandon Duderstadt, Benjamin Schmidt 和 Andriy Mulyar。“GPT4All: 使用从 GPT-3.5-Turbo 提取的大规模数据蒸馏训练助手风格的聊天机器人。”(2023)。

[9] Wang, Yizhong 等。“Self-Instruct: 将语言模型与自生成指令对齐。” arXiv 预印本 arXiv:2212.10560(2022)。

[10] Longpre, Shayne 等。“flan 集合:为有效指令调整设计的数据和方法。” arXiv 预印本 arXiv:2301.13688(2023)。

[11] Kojima, Takeshi 等。“大型语言模型是零样本推理器。” arXiv 预印本 arXiv:2205.11916(2022)。

[12] Wei, Jason 等。“微调语言模型是零样本学习者。” arXiv 预印本 arXiv:2109.01652(2021)。

[13] Wei, Jason 等。“思维链提示引发大型语言模型中的推理。” arXiv 预印本 arXiv:2201.11903(2022)。

使用 LLM 编译器框架有效协调知识图谱的推理

原文:towardsdatascience.com/orchestrating-efficient-reasoning-over-knowledge-graphs-with-llm-compiler-frameworks-749d36dc32b9

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 安东尼·阿尔卡拉兹

·发布于 数据科学前沿 ·6 分钟阅读·2023 年 12 月 29 日

人工智能软件被用来增强本文文本的语法、流畅性和可读性。

最近,大型语言模型(LLM)设计中的创新推动了少样本学习和推理能力的快速进步。然而,尽管取得了进展,LLM 在处理涉及大量相互关联知识的复杂现实世界情境时仍面临限制。

为了应对这一挑战,一种有前景的方法在检索增强生成(RAG)系统中出现。RAG 结合了 LLM 的自适应学习优势与从外部知识源(如知识图谱(KGs))中进行可扩展检索的能力。与其试图将所有信息静态编码在模型中,RAG 允许根据需要从索引知识图谱中动态查询所需的上下文。

然而,有效地协调跨互联知识源的推理和检索带来了自身的挑战。那些简单地在离散步骤中检索和拼接信息的天真方法,往往无法充分捕捉密集知识图谱中的细微差别。概念的相互关联性意味着,如果没有相互关系的分析,关键的上下文细节可能会被遗漏。

最近,一个名为 LLM Compiler 的有趣框架在优化 LLM 中多个函数调用的协调方面展示了早期成功,自动处理依赖关系并允许并行执行。

[## 一个用于并行函数调用的 LLM 编译器

大型语言模型(LLM)在各种复杂推理基准上表现出了显著的成果。推理…

arxiv.org](https://arxiv.org/abs/2312.04511?source=post_page-----749d36dc32b9--------------------------------) [## llama-hub/llama_hub/llama_packs/agents/llm_compiler/llm_compiler.ipynb at main ·…

一个由社区创建的用于大语言模型的数据加载器库——可与 LlamaIndex 和/或 LangChain 一起使用…

github.com](https://github.com/run-llama/llama-hub/blob/main/llama_hub/llama_packs/agents/llm_compiler/llm_compiler.ipynb?source=post_page-----749d36dc32b9--------------------------------)

在本文中,我们探讨了将大语言模型编译器技术更广泛地应用于知识图谱检索和推理的潜力。在论文发布之前,我们已经做了一个工作原型:

## 实现混乱背景下的结构化推理:思路提示和…

大语言模型(LLMs)展示了令人印象深刻的少量学习能力,迅速适应新任务…

towardsdatascience.com

我们分析了诸如自动规划、依赖管理和并行执行等技术如何使对互联知识的分析更加高效和结构化。

计划:

1. 大规模知识图谱推理的挑战

2. 知识图谱作为模块化大语言模型工具

3. 由大语言模型编译器驱动的结构化推理

4. 知识吸收的操作系统

1. 大规模知识图谱推理的挑战

[## blogs/llm/devops_rag.ipynb at master · tomasonjo/blogs

支持我图数据科学博客文章的 Jupyter 笔记本,网址为 https://bratanic-tomaz.medium.com/ …

github.com](https://github.com/tomasonjo/blogs/blob/master/llm/devops_rag.ipynb?source=post_page-----749d36dc32b9--------------------------------)

在解决大规模知识图谱推理的挑战时,必须整合先进的技术和方法来优化数据检索和处理。这涉及利用各种计算策略来平衡分析大规模互联数据集中的效率、准确性和完整性。以下部分详细介绍了这些方法:

a. 优化 Cypher 查询以进行数学运算

目标: 提高 Cypher 查询的性能,特别是针对图数据的数学聚合。

方法论:

- 识别机会: 识别可以高效应用数学聚合的图数据场景。

- 模块化步骤: 将过程分解为并行检索组、并发执行聚合函数和高效连接。

- 示例应用: 计算分配给 A 队的高优先级任务数量。这涉及到检索任务节点、按优先级和团队进行筛选,并汇总计数。

b. 规划并行向量搜索

目标: 实现并行向量搜索,以高效导航图基数据。

方法论:

  • 分析种子实体问题:剖析查询以确定作为向量搜索起点的关键实体。

  • 探索并发向量空间:从不同的种子实体启动搜索,同时探索图。

  • 持续节点检索:基于向量相似性动态检索节点,扩展有针对性的搜索。

  • 示例应用:通过探索以不同实体为根的向量空间来识别描述类似于‘PaymentService’的服务。

c. 协调图算法的使用

目标: 选择并应用最合适的图算法以处理特定查询。

方法论:

  • 检查算法选择问题:分析查询的性质,以选择相关算法(如遍历、社区检测)。

  • 模块化应用:以模块化的方式应用算法,每个算法针对特定目标进行优化(例如效率、准确性)。

  • 解决依赖关系:确保算法之间的协调,特别是在一个算法的输出需要用于另一个算法的执行时。

  • 示例应用:使用社区检测和遍历算法找到紧密连接的服务子图。

LLM 编译器协调

一个 LLM 编译器可以作为这些任务的中央协调者。它将管理数学运算的 Cypher 查询的执行,监督并行向量搜索,并协调各种图算法的应用。LLM 编译器在此背景下的主要目标是确保知识图谱推理的整个过程不仅高效和准确,而且全面。这需要对数据结构有深入的理解,能够预测计算需求,并能根据实时数据分析结果动态调整策略。

2. 知识图谱作为模块化 LLM 工具

Kim 等人 2023 年提出的 LLM 编译器系统包括 3 个关键组件:

  1. LLM 规划器: 分解任务并构建依赖图

  2. 任务提取单元: 分派处理依赖的任务

  3. 执行者: 并行运行工具函数

值得注意的是,LLM 编译器将工具视为可以并发执行的模块化函数(当可能时)。

在这一范式的基础上,一个引人入胜的观点是将知识图谱本身视为模块化工具,由 LLM 进行协调:

  • 查询引擎通过知识图谱(KGs)成为 LLM 访问的工具

  • 图算法和嵌入提供了工具级定制

  • LLM 规划器确定最佳的多图探索策略

通过这种框架,LLM 编译器的自动化规划和结构化执行技术对于复杂知识检索显得非常有前景。

3. 由 LLM 编译器驱动的结构化推理

通过专门化 LLM 编译器技术来整合多个工具和执行图,我们可以提升知识图谱推理的多个方面:

a. 并行探索

规划分解将允许从多个“入口点”同时查询知识图谱的不同区域。多跳路径可以并行遍历,加速探索。

b. 模块化检索

针对独特子图的查询引擎使用独特的算法和嵌入,实际上充当了独立的工具。LLM 编译器在整合不同的模块能力方面表现出色。

c. 依赖管理

中间查询结果通常会影响后续的搜索。LLM 编译器对工具间依赖关系的自动处理能够实现实体和关系的无缝传播。

d. 递归重新规划

对于复杂问题,后续的检索阶段高度依赖于之前的阶段。LLM 编译器允许在更新的上下文揭示新依赖时进行递归重新规划。

e. 本体辅助规划

提供关键实体高层次模式的本体可以进一步协助规划模块。元级知识指导更加结构化的任务分解,符合领域概念。

e. 多样化数据源

规划器可以将额外的数据源,如 SQL 数据库、图像和互联网搜索引擎,整合为 LLM 可访问的模块化工具。

通过在本体知识驱动的结构化规划框架下协调知识检索模块,LLM 编译器可以实现对广泛信息空间的显著高效和精准的导航。

4. 知识吸收的操作系统

从宏观上看,我们可以设想 LLM 编译器技术会产生一个新范式——LLM 作为操作系统来监督各种知识功能。就像操作系统平衡线程和内存一样,LLM 可能会在知识存储中调度检索、推理和学习。基于 ML 的优化器将自动调整各种“工具”模块的路由和使用。

在这个生态系统中,LLM 编译器将充当关键的工作流协调框架,接口连接操作系统和工具。它将处理 LLM 操作系统代表下的所有依赖解析、并发优化和资源分配的复杂性。

LLM 作为操作系统

LLM 作为协调者,监督并在各个模块之间分配资源:

  • 为检索、推理和学习功能之间的最佳并发安排计划

  • 将查询和决策路由到最适合的组件

  • 监控执行以动态优化分配

  • 随着新能力的上线,实现模块化扩展性

语言模型作为语义粘合剂

语言模型提供了将不同组件联系在一起的共同语义表示:

  • 将查询、检索的上下文、生成的决策嵌入到共享向量空间

  • 在组件接口之间翻译查询和指令

  • 通过将输入/输出编码为可传输的嵌入,在线路之间传播信号

语言模型作为推理引擎

语言模型在专业组件的输入上进行元推理:

  • 通过基于更广泛的理解解决歧义来进行信号的语境化

  • 将低层次的输出抽象为更高层次的见解

  • 在概念基础上评估假设和解释

  • 确定解释性推论,连接相互关联的输出

语言模型因此在计算和语义上充当了狭义和广义 AI 之间的连接纽带。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

由 Dall-E-3 生成的图像

结论

随着语言模型不断成熟为更通用的推理引擎,围绕它们的架构创新仍然至关重要。特别是,有效利用外部知识为克服固有模型局限性提供了一条途径。语言模型编译器及其协调模块功能的技术提供了一个有前景的范式,用于构建可扩展的知识检索结构。

在开发这些连接和大规模整合检索能力方面还有很多工作要做。

但通过将知识框定为由语言模型编译器协调的模块化工具,我们为在复杂推理中实现平衡的效率、简洁性和连贯性打开了有趣的可能性。

在这些方面的进展仍然至关重要,因为我们期望实现真正的系统智能。

机器学习风险管理中的组织过程

原文:towardsdatascience.com/organizational-processes-for-machine-learning-risk-management-14f4444dd07f

负责任的人工智能

组织过程是机器学习系统可靠性的一个关键非技术性决定因素。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Parul Pandey

·发表于 Towards Data Science ·7 分钟阅读·2023 年 9 月 23 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片

在我们关于机器学习风险管理的持续系列中,我们已经研究了一些确保机器学习(ML)系统可信赖性的关键元素。在我们的第一篇文章中,我们详细讨论了 机器学习风险管理中的文化能力****t。其中提供的见解为我们当前的探索奠定了基础,因此,我强烈建议你在继续阅读本文章之前先阅读那部分内容。

## 机器学习风险管理中的文化能力

组织的文化是负责任的人工智能的一个重要方面。

towardsdatascience.com

在这篇第二篇文章中,我们将重点转向机器学习系统背景下的另一个重要元素:组织过程。虽然技术细节常常掩盖了这些过程,但它们是确保机器学习模型安全性和性能的关键。正如我们认识到文化能力的重要性一样,我们现在承认组织过程是构建机器学习系统可靠性的基础基石。

本文讨论了组织过程在机器学习风险管理(MRM)领域中的重要作用。整篇文章强调了从业者必须认真考虑、记录和主动解决其 ML 系统中已知或可预见的故障模式的关键性。

1️. 预测失败模式

在机器学习(ML)系统中识别和解决可能出现的问题至关重要,但将这一理念付诸实践需要时间和精力。然而,近年来,能够帮助 ML 系统设计师更系统地预测问题的资源显著增加。通过仔细整理潜在问题,使得在现实世界中让 ML 系统变得更强大、更安全变得更容易。在这种背景下,可以探索以下策略:

从过去的失败中学习

就像交通专业人员调查和编目事件以防止未来的发生一样,ML 研究人员和组织也开始收集和分析 A.I.事件。A.I.事件数据库是一个重要的存储库,允许用户搜索事件并获得宝贵的见解。开发 ML 系统时,咨询此资源至关重要。

如果类似的方法在过去曾导致事件,这就作为一个强烈的警告信号,表明新系统也可能存在风险,需要仔细考虑。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

通过编目事件防止现实世界中的人工智能失败重复发生:人工智能事件数据库 | 来源: arxiv.org/pdf/2011.08512.pdf

解决想象力失败

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

克服人工智能系统开发和部署中的想象力失败 | 来源: arxiv.org/pdf/2011.13416.pdf

通常,人工智能(A.I.)事件源于 ML 系统操作中未预见或理解不足的背景和细节。论文中概述的结构化方法克服人工智能系统开发和部署中的想象力失败提供了对这些具有挑战性的未来风险进行假设的方法,并考虑了(包括投资者、客户和易受害者)、什么(涵盖福祉、机会和尊严)、何时(包括即时、频繁和长期情境)以及如何(涉及行动和信念改变)等方面。

虽然人工智能事件可能会对组织造成尴尬、昂贵,甚至非法的后果,但预见性可以缓解许多已知事件,可能会导致系统的改进。在这种情况下,实施的暂时延迟远远低于由于系统缺陷发布给组织和公众带来的潜在伤害。

2. 模型风险管理流程

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

21 页的 S.R. 11–7 模型风险管理指南的快照。该文档可免费公开访问 | 来源: www.federalreserve.gov/supervisionreg/srletters/sr1107a1.pdf

机器学习风险管理(MRM)构成了一个全面的框架和一系列程序,旨在识别、评估、缓解和监控与开发、部署和操作机器学习系统相关的风险。这些元素是治理结构的重要组成部分,特别是在美国联邦储备系统的模型风险管理监督指南(S.R. 11–07)的背景下,该指南监督用于重要消费者金融应用的预测模型。

文档是合规性变得具体的地方,使从业者承担责任并指导他们构建稳健的模型

虽然较大的组织可能更容易实现完整的 MRM,但较小的组织也可以提取有价值的见解。本节将 MRM 程序分解为更小、更易管理的组件,使其更易于理解和使用。

1. 风险分级

在评估机器学习系统部署中的风险时,常见的方法涉及计算重要性,考虑伤害的可能性和预期损失。高重要性的应用程序需要更多的关注。有效的治理适当地将资源分配给高、中和低风险的系统。例如,最近发布的Anthropic A.I.负责任的扩展政策引入了人工智能安全级别(ASL)的概念,这一概念在一定程度上受到美国政府生物安全等级(BSL)标准的启发,用于管理危险的生物材料。以下是一个快照:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来自 Anthropic 的 RSP 快照 | 来源:www-files.anthropic.com/production/files/responsible-scaling-policy-1.0.pdf

2. 模型文档

MRM 标准要求全面的系统文档,以满足多个目的,包括利益相关者责任、持续维护和事件响应。系统间的标准化文档简化了审计和审查流程,使其成为合规性的关键方面。文档模板指导数据科学家和工程师在模型开发过程中,确保所有必要步骤都得到执行,以构建可靠的模型。不完整的文档表明训练过程存在不足,因为大多数模板要求从业人员填写每个部分。此外,在最终模型文档中包括姓名和联系信息,有助于促进问责制。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

MRM 文档中典型部分的粗略组合以及附件中推荐的 欧盟人工智能法案 | 图片由作者提供

详尽的模型文档可能令人望而却步;较小的组织可以选择像数据表这样的简单框架,模型卡可以帮助较小的组织实现这些目标。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

L: 数据集数据表:来源:arxiv.org/pdf/1803.09010.pdf | R: 模型监控卡:来源:arxiv.org/pdf/1810.03993.pdf

3. 模型监控

机器学习(ML)安全的基础在于 ML 系统在现实世界环境中的固有不可预测性,因此需要对这些系统进行持续监控,从部署到退役。一个主要关注点是 输入漂移,当现实世界情况与静态训练数据发生偏差时,例如市场波动、监管变化或意外事件(如疫情)时,输入漂移会出现。这种偏差可能对系统功能构成威胁。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

研究与生产中的机器学习。 | 幻灯片来自于‘安全可靠的机器学习:防止和识别故障’,在 ICLR-2019 上展示,可在 slideslive.com/38915708/safe-and-reliable-machine-learning-preventing-and-identifying-failures 查阅,采用 CCO 许可协议

高效的 ML 系统通过仔细监控数据和模型质量的变化来降低这些风险。这种监控不仅关注性能,还会查看异常数据或预测、安全问题和公平性问题。这有助于确保在不断变化的操作环境中进行全面的风险管理。

4. 模型清单

MRM 的核心是模型清单——全面的数据库,列出组织中所有的机器学习系统,并连接到监控策略、审计结果、系统维护记录和事件响应计划等重要资源。

任何部署机器学习的组织都应该能够回答像这样简单明了的问题:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

任何部署机器学习的组织都应该能够回答这些简单明了的问题 | 图片来源:作者

对于任何重视利用机器学习的组织而言,维护一个强大的模型清单不仅是一个良好的实践——而是必不可少的。

5. 系统验证和过程审计

传统 MRM 实践的一个重要方面是,在机器学习系统发布之前,它会经过两个主要评估。首先,专家测试其技术部分,查找并修复问题。接着,一个团队确保系统遵循所有规则和指南,包括其设计和未来计划。如果这些系统有重大更新,还会再次审查。有些小公司可能觉得只能进行部分检查,但基本的想法是要有外部的人员来测试,确保它符合所有规则,并在使用重要系统之前获得批准。

在机器学习中,有效的 MRM(模型风险管理)意味着双重审查。

6. 变更管理

机器学习系统像其他复杂的软件一样,拥有各种组件,如后台代码、API 和用户界面。一个组件的变化可能会影响其他组件。数据模式的变化、新的隐私法律以及对第三方软件的依赖等挑战使得管理这些变化变得至关重要。在关键机器学习系统的早期阶段,规划这些变化是必要的。如果没有这种规划,可能会发生错误,例如未经许可使用数据或系统不匹配,并且这些错误可能在问题出现之前未被察觉。

结论

从 文化能力 到组织流程,我们探讨了确保机器学习系统安全性和性能的各种方面。正如我们所看到的,预测失败模式、细致的模型风险管理和警惕的监控是这一路径中的关键支柱。构建强健的模型、维护全面的清单和拥抱变更管理是实现负责任的人工智能的关键步骤。这些基础要素不仅确保了机器学习系统的安全性和性能,还赢得了用户和利益相关者的信任。

> 阅读本系列中的下一篇文章 >

[## 跨领域桥接:将金融、隐私和软件最佳实践融入机器学习风险管理

理解超越传统模型风险管理的策略

向数据科学迈进

参考资料与进一步阅读

使用 Pants 组织机器学习单一仓库

原文:towardsdatascience.com/organizing-a-machine-learning-monorepo-with-pants-8e0570de0c4c

MLOps

简化你的机器学习工作流管理

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Michał Oleszak

·发布于 Towards Data Science ·阅读时间 20 分钟·2023 年 8 月 18 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你是否曾经在项目之间复制粘贴公用代码块,导致不同仓库中存在多个版本的相同代码?或者,可能在更新存储数据的 GCP 存储桶名称后,你需要对数十个项目进行拉取请求?

上述情况在机器学习团队中经常发生,其后果从单个开发者的不满到团队无法按需交付代码等各不相同。幸运的是,有解决办法。

让我们深入探讨单一仓库,这是一种在谷歌等大型科技公司广泛采用的架构,了解它如何提升你的机器学习工作流。单一仓库提供了众多优势,尽管存在一些缺点,但它仍然是管理复杂机器学习生态系统的有力选择。

我们将简要讨论单一仓库的优缺点,研究为什么它是机器学习团队的优秀架构选择,并窥探大科技公司如何使用它。最后,我们将了解如何利用 Pants 构建系统将你的机器学习单一仓库组织成一个强大的 CI/CD 构建系统。

系好安全带,我们将开始简化你的机器学习项目管理之旅。

本文最初发布在 neptune.ai 博客

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

什么是单一仓库?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

机器学习单一仓库。作者提供的图片,来源于 neptune.ai。

Monorepo(单体仓库的缩写)是一种软件开发策略,其中多个项目的代码存储在同一个仓库中。这个想法可以广泛到所有公司代码用各种编程语言存储在一起(有人说 Google 吗?),也可以狭窄到由一个小团队开发的几个 Python 项目放在一个仓库中。

在这篇博客文章中,我们关注于存储机器学习代码的仓库。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Monorepos 与 polyrepos

Monorepos 与 polyrepos 方法形成鲜明对比,在 polyrepos 中,每个单独的项目或组件都在其自己的仓库中。关于这两种方法的优缺点已经讨论了很多,我们不会过于深入探讨。我们只讨论一些基本内容。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Monorepo 架构。图片由作者提供,通过 neptune.ai。

Monorepo 架构提供了以下优势:

  • 单一 CI/CD 管道,意味着没有隐藏的部署知识分散在不同仓库的个体贡献者之间;

  • 原子提交,由于所有项目都存在于同一个仓库中,开发人员可以进行跨项目的更改,这些更改跨越多个项目但作为单个提交合并;

  • 跨项目轻松共享 公用程序和模板;

  • 轻松统一 编码标准和方法;

  • 更好的 代码可发现性

自然地,没有免费的午餐。我们需要为上述好处付出代价,而代价表现为:

  • 可扩展性挑战:随着代码库的增长,管理 monorepo 可能变得越来越困难。在非常大的规模下,你将需要强大的工具和服务器来处理克隆、拉取和推送更改等操作,这可能需要大量的时间和资源。

  • 复杂性:Monorepo 可能更难管理,特别是与依赖和版本控制有关。共享组件的更改可能会影响多个项目,因此需要额外的谨慎以避免破坏性更改。

  • 可见性和访问控制:由于每个人都在同一个仓库中工作,控制谁可以访问什么可能会很困难。虽然这本身不是缺点,但在代码受严格 NDA 保护的情况下,可能会引发法律问题。

是否值得支付 monorepo 提供的优势由每个组织或团队单独决定。然而,除非你在极其庞大的规模上运作或处理绝密任务,否则我认为——至少在我擅长的领域,即机器学习项目中——monorepo 是大多数情况下的良好架构选择。

让我们来谈谈原因。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用 monorepo 的机器学习

至少有六个原因说明单一代码库特别适合机器学习项目。

  1. 数据管道集成

  2. 实验间的一致性

  3. 简化模型版本控制

  4. 跨职能协作

  5. 原子性更改

  6. 编码标准的统一

让我们逐一讨论这些方面。

数据管道集成

机器学习项目通常涉及预处理、转换和将数据输入模型的数据管道。这些管道可能与机器学习代码紧密集成。将数据管道和机器学习代码保存在同一代码库中,有助于保持这种紧密集成,并简化工作流程。

实验间的一致性

机器学习开发涉及大量实验。将所有实验保存在单一代码库中可以确保环境设置的一致性,并减少由于代码或数据版本不同而导致的实验间差异风险。

简化模型版本控制

在单一代码库中,代码和模型版本是同步的,因为它们被检查到同一个仓库中。这使得管理和追踪模型版本变得更加容易,这在机器学习可重复性至关重要的项目中尤其重要。只需查看任何时刻的提交 SHA,它即可提供所有模型和服务的状态信息。

跨职能协作

机器学习项目通常涉及数据科学家、机器学习工程师和软件工程师之间的合作。单一代码库通过提供所有项目相关代码和资源的唯一真实来源来促进这种跨职能协作

原子性更改

在机器学习的背景下,模型的性能可能依赖于数据预处理、特征提取、模型架构和后处理等各种互相关联的因素。单一代码库允许进行原子性更改——对多个组件的更改可以作为一个整体提交,确保依赖关系始终保持同步。

编码标准的统一

最后,机器学习团队通常包括没有软件工程背景的成员。这些数学家、统计学家和计量经济学家是拥有出色想法和训练解决业务问题模型能力的聪明人才。然而,编写干净、易读且易于维护的代码可能并不是他们最擅长的领域。

单一代码库通过自动检查和执行所有项目的编码标准,帮助确保高代码质量,并且帮助工程能力较弱的团队成员学习和成长。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

行业中的做法:著名的单一代码库

在软件开发领域,一些全球最大、最成功的公司使用单一代码库。以下是一些值得注意的例子。

  • Google: Google 长期以来一直坚定支持单一代码仓库方法。他们的整个代码库,估计包含 20 亿行代码,都集中在一个庞大的仓库中。他们甚至发表了一篇相关论文

  • Meta: Meta 也为其庞大的代码库使用了单一代码仓库。他们创建了一个名为“Mercurial”的版本控制系统,以处理单一代码仓库的规模和复杂性。

  • Twitter: Twitter 已经长期使用 Pants 来管理他们的单一代码仓库,接下来我们将讨论这个构建系统!

许多其他公司,如 Microsoft、Uber、Airbnb 和 Stripe,也在部分代码库中使用单一代码仓库方法

理论讲解够了!让我们看看如何实际构建一个机器学习单一代码仓库。因为仅仅把曾经分开的仓库放到一个文件夹中是不够的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如何用 Python 设置机器学习单一代码仓库?

在本节中,我们将围绕我为本文创建的示例机器学习仓库展开讨论。它是一个简单的单一代码仓库,仅包含一个项目或模块:一个名为 mnist 的手写数字分类器,以其使用的著名数据集命名。

目前你只需知道,在单一代码仓库的根目录下,有一个名为 mnist 的目录,其中包含用于训练模型的 Python 代码、相应的单元测试,以及一个用于在容器中运行训练的 Dockerfile。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们将使用这个小示例来保持简单,但在更大的单一代码仓库中,mnist 仅是仓库根目录中的众多项目文件夹之一,每个文件夹至少会包含源代码、测试、Dockerfile 和需求文件。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

构建系统:你为什么需要一个,以及如何选择?

为什么需要构建系统

想一想,除了编写代码,开发不同项目的各个团队在单一代码仓库中的开发工作流中还会采取哪些行动。他们会对代码运行静态分析工具,以确保符合风格标准,运行单元测试,构建例如 Docker 容器和 Python wheels 这样的工件,将它们推送到外部工件库,并将它们部署到生产环境。

以测试为例。你在维护的工具函数中进行了更改,运行了测试,所有测试都通过了。但是你如何确保你的更改不会破坏其他团队可能正在使用的代码?你当然也应该运行他们的测试套件。

但要做到这一点,你需要准确知道你所更改的代码在哪里被使用。随着代码库的增长,手动查找这点并不高效。当然,作为替代方案,你可以始终执行所有测试,但再次强调:这种方法并不是特别高效。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

为什么你需要一个构建系统:测试。图像由作者提供,来自 neptune.ai。

另一个例子:生产部署。无论你是每周、每日还是持续部署,当时间到来时,你会构建 monorepo 中的所有服务并将其推送到生产环境。但,嘿,你需要在每次部署时全部构建吗?在大规模时这可能会耗时且成本高昂。

有些项目可能已经好几周没有更新了。另一方面,它们使用的共享工具代码可能已经进行了更新。我们如何决定构建什么?再次,这全关乎依赖关系。理想情况下,我们只会构建那些受最近更改影响的服务。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

为什么你需要一个构建系统:部署。图像由作者提供,来自 neptune.ai。

所有这些在代码库较小的情况下可以通过简单的 shell 脚本处理,但随着规模的扩大和项目开始共享代码,挑战也随之出现,其中许多挑战都围绕着依赖管理。

选择合适的系统

如果你投资一个合适的构建系统,上述问题将不再存在。构建系统的主要任务是构建代码。它应该以一种聪明的方式来完成这项任务:开发者只需要告诉它构建什么(“构建受我最新提交影响的 Docker 镜像”或“仅运行那些涵盖了我更新的方法的代码的测试”),但如何进行则应该留给系统来处理。

有几个优秀的开源构建系统。由于大多数机器学习是用 Python 完成的,我们来关注一下支持 Python 最好的构建系统。在这方面最受欢迎的两个选择是 BazelPants

Bazel 是 Google 内部构建系统 Blaze 的开源版本。Pants 也受到 Blaze 的极大启发,并且它旨在实现与 Bazel 类似的技术设计目标。感兴趣的读者可以在这篇 博客文章 中找到对 Pants 和 Bazel 的比较(但请注意,这来自 Pants 的开发者)。monorepo.tools 底部的表格提供了另一种比较。

两个系统都很棒,我并不打算在这里宣布哪一个更好。话虽如此,Pants 通常被描述为更易于设置,更易于接触,并且对 Python 进行了良好的优化,这使得它非常适合机器学习 monorepo。

根据我个人的经验,决定使用 Pants 的关键因素是它活跃且乐于助人的社区。每当你有问题或疑虑时,只需在社区 Slack 频道发帖,许多支持者将很快帮助你解决。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

介绍 Pants

好了,进入重点吧!我们将一步一步介绍不同的 Pants 功能及其实现方法。你也可以在这里查看相关的示例代码库。

设置

Pants 可以通过 pip 安装。在本教程中,我们将使用截至本文撰写时的最新稳定版本 2.15.1。

pip install pantsbuild.pants==2.15.1

Pants 可以通过一个名为pants.toml. 的全局主配置文件进行配置。在其中,我们可以配置 Pants 自身的行为以及它依赖的下游工具的设置,如 pytest 或 mypy。

让我们从一个最基本的pants.toml 开始:

[GLOBAL]
pants_version = "2.15.1"
backend_packages = [
    "pants.backend.python",
]

[source]
root_patterns = ["/"]

[python]
interpreter_constraints = ["==3.9.*"]

在全局部分,我们定义 Pants 版本和我们需要的后端包。这些包是 Pants 的引擎,支持不同的功能。作为起点,我们只包含 Python 后端。

在源部分,我们将源设置为代码库的根目录。从版本 2.15 开始,为了确保这一点,我们还需要在代码库的根目录下添加一个空的 BUILD_ROOT 文件

最后,在 Python 部分,我们选择要使用的 Python 版本。Pants 会在我们的系统中查找符合这里指定条件的版本,因此请确保你已经安装了这个版本。

这是一个好的开始!接下来,让我们来看一下任何构建系统的核心:构建文件。

构建文件

构建文件是用于以声明方式定义目标(要构建的内容)及其依赖项(它们工作所需的内容)的配置文件。

你可以在目录树的不同层级拥有多个构建文件。文件越多,对依赖管理的控制就越细粒度。实际上,Google 在其代码库中的几乎每个目录都有一个构建文件。

在我们的示例中,我们将使用三个构建文件:

  • mnist/BUILD — 在项目目录中,这个构建文件将定义项目的 Python 需求和要构建的 docker 容器;

  • mnist/src/BUILD — 在源代码目录中,这个构建文件将定义 Python 源文件,即需要进行 Python 特定检查的文件;

  • mnist/tests/BUILD — 在测试目录中,这个构建文件将定义哪些文件使用 Pytest 运行,以及这些测试执行所需的依赖。

让我们来看一下mnist/src/BUILD

python_sources(
    name="python",
    resolve="mnist",
    sources=["**/*.py"],
)

mnist/BUILD 看起来是这样的:

python_requirements(
    name="reqs",
    source="requirements.txt",
    resolve="mnist",
)

构建文件中的两个条目被称为目标。首先,我们有一个 Python 源代码目标,我们称之为python,虽然名称可以是任何东西。我们将 Python 源代码定义为目录中的所有 .py 文件。这是相对于构建文件的位置,也就是说:即使我们在mnist/src目录之外有 Python 文件,这些源代码只捕获mnist/src文件夹中的内容。还有一个 resolve 字段,我们稍后会谈论它。

接下来,我们有 Python 需求目标。它告诉 Pants 在哪里可以找到执行我们 Python 代码所需的需求(同样,相对于构建文件的位置,在这个例子中是 mnist 项目的根目录)。

这就是我们需要的所有信息。为了确保构建文件定义正确,让我们运行:

pants tailor --check update-build-files --check ::

正如预期的那样,我们得到: “未发现对 BUILD 文件的必要更改。”作为输出。很好!

让我们再花点时间了解一下这个命令。简而言之,裸的pants tailor可以自动创建构建文件。然而,它有时会添加过多的文件,这就是为什么我倾向于手动添加文件,然后使用上述命令检查其正确性。

结尾的双分号是 Pants 的表示法,它告诉 Pants 对整个 monorepo 运行该命令。或者,我们可以用mnist::替换它,以仅对mnist模块运行。

依赖项和锁定文件

为了进行高效的依赖管理,Pants 依赖于锁定文件。锁定文件记录每个项目所使用的所有依赖项的特定版本和来源。这包括直接依赖和传递依赖。

通过捕捉这些信息,锁定文件确保在不同环境和构建中一致地使用相同版本的依赖项。换句话说,它们作为依赖关系图的快照,确保在构建中的可重现性和一致性。

要为我们的mnist模块生成锁定文件,我们需要在pants.toml中添加以下内容:

[python]
interpreter_constraints = ["==3.9.*"]
enable_resolves = true
default_resolve = "mnist"

[python.resolves]
mnist = "mnist/mnist.lock"

我们启用了 resolves(Pants 对锁定文件环境的术语),并为mnist定义了一个,传递了一个文件路径。我们还将其设置为默认的。这是我们之前传递给 Python 源代码和 Python 需求目标的 resolve,这就是它们知道需要什么依赖项的方式。我们现在可以运行:

pants generate-lockfiles

以获取:

Completed: Generate lockfile for mnist
Wrote lockfile for the resolve `mnist` to mnist/mnist.lock

这在mnist/mnist.lock创建了一个文件。如果你打算在远程 CI/CD 中使用 Pants,该文件应该用 git 进行检查。而且,自然地,每次更新requirements.txt文件时,它都需要更新。

在 monorepo 中有更多项目时,你可能会选择有选择性地为需要它的项目生成锁定文件,例如 pants generate-lockfiles --resolve=mnist

设置完成了!现在让我们使用 Pants 做一些对我们有用的事情。

使用 Pants 统一代码风格

Pants 本身支持多种 Python linter 和代码格式化工具,如 Black、yapf、Docformatter、Autoflake、Flake8、isort、Pyupgrade 或 Bandit。它们的使用方式相同;在我们的示例中,让我们实现 Black 和 Docformatter。

为此,我们向pants.toml中添加两个适当的后端:

[GLOBAL]
pants_version = "2.15.1"
colors = true
backend_packages = [
    "pants.backend.python",
    "pants.backend.python.lint.docformatter",
    "pants.backend.python.lint.black",
]

如果我们想的话,可以通过在 toml 文件中添加额外的部分来配置这两个工具,但现在我们先使用默认设置。

要使用格式化工具,我们需要执行一个称为 Pants 目标的操作。在这种情况下,有两个目标相关。

首先,lint 目标将以检查模式运行这两种工具(按照它们在后端包中列出的顺序,所以 Docformatter 先,Black 后)。

pants lint ::
Completed: Format with docformatter - docformatter made no changes.
Completed: Format with Black - black made no changes.
✓ black succeeded.
✓ docformatter succeeded.

看起来我们的代码符合这两个格式化工具的标准!但是,如果不是这样,我们可以执行 fmt(“格式化”的缩写)目标,以适当地调整代码:

pants fmt ::

实际上,你可能会想使用多于这两个格式化工具。在这种情况下,你可能需要更新每个格式化工具的配置,以确保它与其他工具兼容。例如,如果你使用的是 Black 的默认配置,就像我们这里做的一样,它将期望代码行不超过 88 个字符。

但是如果你还想添加 isort 来自动排序你的导入项,它们会发生冲突:isort 会在 79 个字符后截断行。为了使 isort 与 Black 兼容,你需要在 toml 文件中包含以下部分:

[isort]
args = [
    "-l=88",
 ]

所有格式化工具都可以通过将参数传递给其底层工具的方式在pants.toml中进行配置。

使用 Pants 进行测试

让我们运行一些测试!为此,我们需要两个步骤。

首先,我们向pants.toml中添加相应的部分:

[test]
output = "all"
report = false
use_coverage = true

[coverage-py]
global_report = true

[pytest]
args = ["-vv", "-s", "-W ignore::DeprecationWarning", "--no-header"]

这些设置确保在运行测试时会生成测试覆盖率报告。我们还传递了一些自定义的 Pytest 选项来调整其输出。

接下来,我们需要回到我们的 mnist/tests/BUILD 文件,并添加一个 Python 测试目标:

python_tests(
    name="tests",
    resolve="mnist",
    sources=["test_*.py"],
)

我们将其称为 tests 并指定要使用的 resolve(即锁定文件)。Sources 是 Pytest 查找要运行的测试的地方;在这里,我们显式传递了所有以“test_”开头的 .py 文件。

现在我们可以运行:

pants test ::

获取:

✓ mnist/tests/test_data.py:../tests succeeded in 3.83s.
✓ mnist/tests/test_model.py:../tests succeeded in 2.26s.
Name                               Stmts   Miss  Cover
------------------------------------------------------
__global_coverage__/no-op-exe.py       0      0   100%
mnist/src/data.py                     14      0   100%
mnist/src/model.py                    15      0   100%
mnist/tests/test_data.py              21      1    95%
mnist/tests/test_model.py             20      1    95%
------------------------------------------------------
TOTAL                                 70      2    97%

正如你所看到的,运行这个测试套件大约花了三秒钟。如果我们再次运行它,我们将立即得到结果:

✓ mnist/tests/test_data.py:../tests succeeded in 3.83s (memoized).
✓ mnist/tests/test_model.py:../tests succeeded in 2.26s (memoized).

注意 Pants 如何告诉我们这些结果是被缓存的。由于测试、测试的代码或要求没有更改,因此无需实际重新运行测试——它们的结果是保证一致的,因此只是从缓存中提供。

使用 Pants 检查静态类型

我们再添加一个代码质量检查。Pants 允许我们使用 mypy 来检查 Python 中的静态类型。我们需要做的就是在pants.toml中添加 mypy 后端:pants.backend.python.typecheck.mypy

你可能还想配置 mypy 以使其输出更具可读性和信息量,可以包含以下配置部分:

[mypy]
args = [
    "--ignore-missing-imports",
    "--local-partial-types",
    "--pretty",
    "--color-output",
    "--error-summary",
    "--show-error-codes",
    "--show-error-context",
]

有了这个,我们可以运行 pants check :: 来获取:

Completed: Typecheck using MyPy - mypy - mypy succeeded.
Success: no issues found in 6 source files
✓ mypy succeeded.

使用 Pants 发布 ML 模型

让我们谈谈发布。大多数机器学习项目涉及一个或多个 Docker 容器,例如处理训练数据、训练模型或通过 Flask 或 FastAPI 通过 API 提供服务。在我们的玩具项目中,我们还有一个 用于模型训练的容器

Pants 支持自动构建和推送 Docker 镜像。让我们看看它是如何工作的。

首先,我们在 pants.toml 中添加 Docker 后端:pants.backend.docker. 我们还将对其进行配置,传递一些环境变量和一个构建参数,这在稍后会派上用场:

[docker]
build_args = ["SHORT_SHA"]
env_vars = ["DOCKER_CONFIG=%(env.HOME)s/.docker", "HOME", "USER", "PATH"]

现在,在 mnist/BUILD 文件中,我们将添加两个目标:一个文件目标和一个 Docker 镜像目标。

files(
    name="module_files",
    sources=["**/*"],
)

docker_image(
    name="train_mnist",
    dependencies=["mnist:module_files"],
    registries=["docker.io"],
    repository="michaloleszak/mnist",
    image_tags=["latest", "{build_args.SHORT_SHA}"],
)

我们将 Docker 目标命名为 train_mnist。作为依赖项,我们需要传递要包含在容器中的文件列表。最方便的方式是将此列表定义为单独的 files 目标。在这里,我们简单地将 mnist 模块中的所有文件包含在一个名为 module_files 的目标中,并将其作为依赖项传递给 Docker 镜像目标。

自然地,如果你知道容器只需要某些文件的子集,传递这些文件作为依赖项是个好主意。这一点很重要,因为这些依赖项被 Pants 用来推断容器是否受到了更改影响并需要重建。在这里,module_files 包括所有文件,如果 mnist 文件夹中的任何文件发生更改(即使是 readme!),Pants 会将 train_mnist Docker 镜像视为受到了这一更改的影响。

最后,我们还可以设置外部注册表和要推送镜像的仓库,以及推送时使用的标签:在这里,我将把镜像推送到我的个人 Docker Hub 仓库,总是带有两个标签:“latest”和短的提交 SHA,后者将作为构建参数传递。

有了这个,我们可以构建一个镜像。还有一件事:由于 Pants 在其隔离的环境中工作,它不能从主机读取环境变量。因此,要构建或推送需要 SHORT_SHA 变量的镜像,我们需要将其与 Pants 命令一起传递。

我们可以这样构建镜像:

SHORT_SHA=$(git rev-parse --short HEAD) pants package mnist:train_mnist

获取:

Completed: Building docker image docker.io/michaloleszak/mnist:latest +1 additional tag.
Built docker images: 
  * docker.io/michaloleszak/mnist:latest
  * docker.io/michaloleszak/mnist:0185754

快速检查显示镜像确实已被构建:

docker images
REPOSITORY            TAG       IMAGE ID       CREATED              SIZE
michaloleszak/mnist   0185754   d86dca9fb037   About a minute ago   3.71GB
michaloleszak/mnist   latest    d86dca9fb037   About a minute ago   3.71GB

我们还可以使用 Pants 一次性构建和推送镜像。只需将 package 命令替换为 publish 命令即可。

SHORT_SHA=$(git rev-parse --short HEAD) pants publish mnist:train_mnist

这将构建镜像并将其推送到我的 Docker Hub,它们确实已经到达了

Pants 在 CI/CD 中

我们刚刚手动在本地运行的相同命令可以作为 CI/CD 流水线的一部分执行。例如,你可以通过 GitHub Actions 或 Google CloudBuild 等服务来运行它们,比如在功能分支被允许合并到主分支之前作为 PR 检查,或者在合并之后验证其是否有效,并构建和推送工件。

在我们的玩具仓库中,我实现了一个预推送提交钩子,该钩子在 git push 时运行 Pants 命令,并且仅在所有命令通过时才允许推送。在其中,我们运行以下命令:

pants tailor --check update-build-files --check ::
pants lint ::
pants --changed-since=main --changed-dependees=transitive check
pants test ::

你可以看到一些用于pants check的新标志,这是使用 mypy 进行类型检查的功能。它们确保检查仅在与主分支相比发生了更改的文件及其传递依赖项上运行。这很有用,因为 mypy 的运行时间较长。将其范围限制在实际需要的部分可以加快处理速度。

在 CI/CD 管道中,docker 构建和推送会是什么样的?大致如下:

pants --changed-since=HEAD^ --changed-dependees=transitive --filter-target-type=docker_image publish

我们像以前一样使用 publish 命令,但增加了三个额外的参数:

  • --changed-since=HEAD^--changed-dependees=transitive 确保仅构建与先前提交相比受更改影响的容器;这对于在合并后的主分支上执行非常有用。

  • --filter-target-type=docker_image 确保 Pants 只做构建和推送 Docker 镜像的工作;这是因为publish命令可能会引用其他目标,例如,它可以用来将 helm charts 发布到 OCI 注册表。package命令也是如此:除了构建 docker 镜像,它还可以创建 Python 包;因此,传递--filter-target-type选项是一种良好的做法。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结论

单体仓库通常是机器学习团队的绝佳架构选择。然而,大规模管理它们需要对适当的构建系统进行投资。其中一个系统是 Pants:它易于设置和使用,并且提供对机器学习团队经常使用的许多 Python 和 Docker 功能的本地支持。

此外,它是一个开源项目,拥有一个庞大且乐于助人的社区。我希望在阅读完这篇文章后,你能尝试一下。即使你目前没有一个单体仓库,Pants 仍然可以简化和促进你日常工作的许多方面!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

参考文献

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

感谢阅读!

如果你喜欢这篇文章,为什么不订阅电子邮件更新我的新文章呢?通过成为 Medium 会员,你可以支持我的写作,并获得对所有其他作者和我自己的故事的无限访问权。

想时刻掌握机器学习和人工智能领域日新月异的动态吗?查看我的新通讯,AI Pulse。需要咨询吗?你可以问我任何问题或在这里预约一对一咨询。

你还可以尝试我的其他文章。无法选择?可以看看这些:

## 开箱 DINOv2,Meta 的新型通用计算机视觉骨干网

视觉基础模型是否正在赶上大型语言模型?

towardsdatascience.com ## 自监督学习在计算机视觉中的应用

如何用仅有的几个标记样本来训练模型

towardsdatascience.com ## 如何通过假设检验检测数据漂移

提示:忘记 p 值吧

towardsdatascience.com

组织生成式人工智能:数据科学团队的 5 个经验教训

原文:towardsdatascience.com/organizing-generative-ai-5-lessons-learned-from-data-science-teams-2f271874ae4a?source=collection_archive---------4-----------------------#2023-08-25

大语言模型(LLMs)拥有巨大的潜力,但创造可持续的价值将需要的不仅仅是一个特种小组

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 shane murray

·

关注 发布于 Towards Data Science ·9 min read·2023 年 8 月 25 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由作者提供

你做到了!

在执行领导层含糊其辞地向利益相关者承诺将把新的生成式人工智能功能整合到整个组织之后,你的特种小组 快速地生产了一个符合要求的最小可行产品(MVP)。将 OpenAI API 集成到你的应用程序中并不困难,而且它可能最终会变得有用。

那么现在会发生什么?虎队不可能永远疾驰。每个成员在组织内都有另一角色,这将再次占据他们的大部分时间和注意力。

更不用说,为了这个项目而忽视加快的典型流程和结构,这是有其原因的。事实证明,它们对确保产品适配性、从开发到运营的过渡以及成本优化(等等)非常关键。

仔细想想,现在项目完成了,实际上没有任何平台基础设施可以帮助扩展下一轮 LLM 模型或其他通用 AI 产品特性。

现在看来是时候开始考虑如何在您的数据组织内构建和支持通用 AI 团队了。尽管那些华丽的产品演示使过程看起来轻而易举,但未来可能会面临波涛汹涌的迹象:

  • 除非你是六大科技巨头之一,否则数据科学和通用 AI 专业知识都是稀缺的。到目前为止,没有人真正有任何重要的经验。对每个人来说都是新的。

  • 业务知道它想要通用 AI,但还不完全知道为什么。技术令人兴奋,但具体的使用案例还不明确。没有人有维护部署的多少经验。

  • 这个生态系统一夜之间蓬勃发展起来,但支持技术和最佳实践还没有成熟。风险通常是未预见的,不确定性很高。

如果这听起来很熟悉,那是因为确实如此。在过去五年左右,数据科学团队在其机器学习算法和应用程序中遇到了所有这些问题

这是一次痛苦的经历。2020 年,Gartner 报道显示,仅有 53%的机器学习项目从原型成功进入生产阶段 —— 这是在具有一定 AI 经验的组织中。对于仍在努力发展数据驱动文化的公司而言,这个数字可能更高,一些失败率估计甚至飙升至接近 90%。

作为曾在纽约时报领导数据团队并遇到许多这些挑战的人,我可以证明组织结构、流程和平台对这些倡议的成功有多重要。

我还与来自各种公司规模和行业的数百名数据领导交谈过,他们表达了一套共同的经验教训。这些通过数据科学团队的血汗和泪水赢得的最佳实践应该成为每位数据领导思考其长期通用 AI 战略和团队结构的首要考虑因素。

经验教训 1:理解结构性权衡和成熟度曲线

就像你不能在没有任何训练的情况下起床去跑马拉松一样,你的组织在加强其运营能力之前,无法建立一个与领先数据团队相匹配的生成 AI 组织结构。

我在这方面看到的最常见的错误之一是急于去分散化并在公司内部嵌入(也许是在一个数据网格),从而使人才资源过于分散。虽然这样可以更好地理解和接近业务,但持续创造价值是困难的。

可能会有一些成功的案例,但这些往往依赖于一两个自我驱动者的才能。数据科学人才稀缺,而能够独立识别、优先排序、沟通并执行高价值项目的高级数据科学人才更为罕见。

当那些有才华的个人离开时,机构知识、代码库和项目进展往往会随之离开。他们留下的团队成员被迫扮演考古学家的角色,试图解读这些被遗弃项目所留下的文物的目的和意义。大多数情况下,需要从接近零的状态重新开始。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由作者提供。

对于较小的数据科学和机器学习团队来说,咨询模型往往是一种更成功的方法。这种方法汇集了大量的人才,可以集中于最高优先级的项目。需要缓解的潜在缺点是,你要防止卓越中心变成一个产生教授可能喜欢的镀金模型的实验室,但这些模型与实际业务挑战不符。

随着团队规模的扩大和成熟度曲线的提升,稍有不同的组织结构会变得更加合适。“专业化”模型通常会将数据科学和机器学习资源集中于几个高价值的问题上,并在相关业务领域内部署团队。

这一现象最常见的表现是,当机器学习成为产品的核心部分(例如个性化或欺诈检测)时,与产品或工程团队的关联比与核心数据团队的关联更为重要。核心数据团队通常在数据科学方面有自己的投资,这与专业化团队大体独立。

这种模型可以成功,但确实会造成低效和孤岛现象。例如,中央团队和专业化团队通常会有定制的平台,几乎没有共享服务。产品领域中的流数据可能会从由中央团队收集的自定义数据中受益,但这种连接可能永远无法建立。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由作者提供。

另一种后期组织结构可以被描述为“平台”模型。嵌入式和专业化模型可能会因为缺乏跨业务领域的可见性和凝聚力而受到影响,每个数据科学问题都有其自己的全栈解决方案,尽管在解决的问题类型上存在固有的相似性。

解决方案是与业务领域或垂直行业有一些故意的分隔,以避免过度适配他们的运营模型,就像你对待其他横向平台团队一样。

将机器学习视为平台追求的一个主要好处是,一旦你展示了每个机器学习应用的价值,就可以投资于共享平台基础设施,因为这可以降低部署和维护新应用的资源和成本。这种投资相对于应用团队的投资初期应该较小,使他们能够相对独立地运营,追求业务伙伴的长期目标。

在这种平台模型中,可以创建一个 GenAI 团队作为应用团队之一,赋予其定制堆栈的任务和工程资源,以提供价值,同时与其他平台团队协调,以重用基础设施和标准,从而为组织提供持续的价值。我强烈建议采用这种模型,而不是试图将 Gen AI 分散到许多团队中。关键质量很重要。

课程 2:按用例组织而不是按业务职能组织

最近,我与一家媒体公司的一位数据领导进行了对话,这是这篇文章的灵感来源。他们告诉我,他们的数据科学团队按领域(在这种情况下是媒体属性)组织。

数据科学团队在每个领域内从事相同类型的项目,即文章推荐算法。毫无疑问,每个领域都受益于对其特定问题的专注,每个数据科学团队也受益于与各自业务和编辑合作伙伴的接近。但这有助于突出这种组织结构的一些缺点;人才部署效率低下,尽管许多团队解决的是相同类型的内容排名问题,但缺乏共享的基础设施。

在《纽约时报》,我们发现围绕共同问题组织数据科学团队是有效的。一旦在一个领域证明了模型的有效性,通常对其进行调整和修改以适应另一个领域的独特输入和约束比让两个团队并行创建两个模型更为高效。从逻辑上讲也是如此,构建原型总是比后续产品花费更多时间。

生成 AI 也应以同样的方式考虑。让团队专注于一个适合技术的高价值用例,例如为事件市场提供个性化座位建议,或为媒体网站进行语言本地化,然后将这一解决方案应用于其他适用领域。

课程 3:关注长期价值和难题

在技术和数据领域,“长期”有其独特的含义,其中首席数据官的平均任期大致与一罐花生酱相当。

当项目收官时,这一目标仍然会是个问题吗?五年后,它仍然有需求吗?在这段时间内,新模型是否能够迭代并发现附加价值?

现实是,假设你没有利用现成的模型,机器学习和生成 AI 项目可能会很昂贵(尽管 LLMs 正在迅速商品化)。开发一个经过良好训练和管理的模型以适应用例可能需要几个月,或者在某些情况下,甚至几年。

其他选择相比,提升效果最好是值得的。例如,一个旨在优化 Facebook 广告支出的机器学习模型可能听起来很吸引人,但你会发现这在广告平台内部本地完成。

尽管如此,关注长期价值并不意味着制定一个第一个发布计划在 2025 年的路线图。

课程 4:将 AI 团队与业务赞助者配对

那么,如何确保你的数据科学和生成 AI 团队专注于重要的业务问题呢?将他们与业务赞助者配对。

寻找新技术的创新应用不太可能是一个线性旅程,预计会有绕道。与业务赞助者建立强大的合作伙伴关系就像一个指南针,确保团队在探索前沿时不会偏离业务价值。我发现这也扩展了团队的视角,超越了横跨多个团队的问题。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片来源:Jamie StreetUnsplash

一位强大的业务赞助者还将确保团队在整个旅程中得到充分支持,解锁资源并帮助导航任何涉及内部流程或政治的困难地带。这种导航的一部分可能需要跨团队对齐路线图,以提供一致的后端和前端体验。

由于这些举措可能会跨越多个季度,执行层的参与对于确保这些项目不会过早终止也至关重要。

课程 5:了解数据平台的前提条件

建造制造机器的机器总是比生产最终产品更困难。这一点在生产汽车的工厂和用于开发和生产大语言模型的数据平台中都是如此。

商业领袖总是会考虑商业目标,并经常忽视实现这些目标所需的数据平台投资。他们并不是恶意的,他们只是依赖你这个数据专家来告诉他们需要什么。

例如,机器学习团队已经投资建设或购买了特征存储和 MLops 解决方案。更不用说对云数据环境、数据质量及相关附加功能的基础投资了。

对于生成式 AI 计划,数据平台和数据管道架构的大部分内容将保持不变(如果你还没有投资现代数据栈,那么这是起点)。没有可发现的高质量数据就没有生成式 AI 项目。然而,还会有一些针对LLM 工程的额外解决方案,比如模型托管、缓存、AI 代理框架等,还有许多尚未被发明的解决方案。

从过去中学习或重蹈覆辙

毋庸置疑,生成式 AI 是一种颠覆性技术,学习如何大规模利用它将创造出一系列痛苦的经验教训。然而,不必从零开始。为了长期成功,结构化你的数据科学和生成式 AI 团队。

这篇文章由 Michael Segner 共同撰写。

在 Medium 上关注我,获取更多关于数据领导力、数据科学应用以及相关主题的故事。订阅,将我的故事直接送到你的收件箱。

其他机器学习术语:文本的稀疏和密集表示

原文:towardsdatascience.com/other-ml-jargons-sparse-and-dense-representations-of-texts-for-machine-learning-21fcd7a01410

其他机器学习术语

向量化的简要介绍及其在自然语言处理中的重要性

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Nabanita Roy

·发表于 Towards Data Science ·9 分钟阅读·2023 年 2 月 15 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由 Compare Fibre 提供,来源于 Unsplash

介绍

矩阵和向量是机器学习(ML)算法进行模式学习和预测所需的量化信息。将这些技术应用于文本数据时,文本的数值表示被工程化为矩阵,以包含文本中的相关信息。“稀疏性”和“密集性”概念有助于高效设计和构建这些矩阵,用于人工智能领域中的所有高维数据处理用例。

向量表示在自然语言处理中的重要性

将文本数据表示为向量是应用机器学习技术进行预测、推荐或聚类的必要条件。在自然语言处理(NLP)中,“相似的单词出现在相似的上下文中”这一概念是基础的。让我们来看看:

  1. 文本分类用例中,如支持票据的分类、垃圾邮件检测、虚假新闻检测和反馈情感分析,具有相似单词的文本会被分类到特定类别中。

  2. 推荐系统中,具有相似个人资料信息、浏览历史和过去订单的人表示对产品有类似的选择或口味。这些信息用于生成推荐。

  3. 无监督聚类在文本中寻找模式和相似的单词,以便对文档和文章进行分组。典型应用包括新闻文章的分类、趋势分析和客户细分。

  4. 信息检索系统中,索引文档会与查询进行匹配,有时以“模糊”的方式进行,然后将匹配的文档集合返回给用户。此外,相似度度量用于对搜索结果进行排序。

因此,捕捉这些向量中的相似性是自然语言处理领域的一个主要研究方向。这些向量被投影到一个 N 维平面中,然后从 N 维空间中的这些向量中提取模式以对文本进行分类。有时会应用降维技术,如 PCA 或 t-SNE。向量的设计控制了基于文本的机器学习模型的整体性能,因此至关重要。

向量设计大致分为“稀疏”(意指很少填充)和“密集”(意指密集填充)两类。在本文中,我从数学的角度回顾了矩阵和向量的概念,然后讨论了这两种向量化技术——稀疏向量表示和密集向量表示,包括分别使用 Scikit Learn 和 Gensim 的演示。我还在文章末尾总结了这些表示的应用和实用性。

矩阵和向量的入门

在数学上,矩阵定义为一个二维矩形数字数组。 如果数组有 m 行和 n 列,那么它是一个 m × n 的矩阵。

如果一个矩阵只有一行或只有一列,它被称为向量。1×n 矩阵或向量是行向量(其中有 n 列但只有 1 行),而 m × 1 矩阵或向量是列向量(其中有 m 行但只有 1 列)。这里有一张清晰演示这一点的图片:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片来源:数据科学线性代数 Ep1 — 使用 Python 介绍向量和矩阵

这是一个 标量、向量和矩阵的入门 和 数据科学中使用 Python 介绍向量和矩阵。

稀疏表示 | 矩阵 | 向量

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由 Henning Witzel 提供,来自 Unsplash

在几乎所有实际应用中,基于计数的量化数值表示信息通常是稀疏的,换句话说,数值表示 只包含在海量数字中对你有用的一小部分。

这是因为,从直观上看,在文档集合中,只有作为文章、介词、连词和代词的单词被明显使用,因此具有较高的出现频率。然而,在一组体育新闻文章中,诸如‘soccer’或‘basketball’的术语,其出现次数有助于确定文章关联的运动类型,尽管出现次数较少,但频率并不很高。

现在,如果我们为每个新文章构造一个向量,假设每篇文章有 50 个单词,那么‘soccer’会出现约 5 次。因此,在 50 次中,45 次向量元素将为零,这表示我们关注的单词的缺失。因此,长度为 50 的向量中 90%是冗余的。这是one-hot 向量生成的一个例子。

稀疏矩阵生成的另一个典型例子是Count Vectorizer,它确定一个单词在文档中出现的次数。它为每个文档生成一个“计数向量”矩阵,从而构成一个d × v的矩阵,其中 d 是文档的数量,v 是文档集合中的单词或词汇的数量。

这里演示了 Count Vectorizer 的工作原理:

以下是‘demo’一词的四种不同含义,每种含义代表一个文档 ~

**文档 1:**演示一个产品或技术

**文档 2:**公开会议或游行,抗议某事或表达对政治问题的观点

**文档 3:**录制一首歌曲或音乐作品,以展示音乐团队或表演者的能力,或作为完整录音的准备

**文档 4:**演示软件或其他产品的功能

我使用了Scikit Learn 的 CountVectorizer实现来生成这四个“文档”的稀疏矩阵。以下是我使用的代码👩‍💻

图片来源:作者

*_cv.toarray()*的输出是4 × 34 数组中单词的数字表示(使用.toarray()从向量转换),如下图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这个 Jupiter Notebook 中找到这个例子 | 图片来源:作者

在矩阵中:

  • zero 表示完全没有出现(基本上没有信息)

  • 任何大于零的数值是单词在四个文档中出现的次数(一些有用的信息和一些冗余的信息)。

  • 34 是词汇表的大小(或文档中唯一单词的总数),因此形状为 4 x 34。

稀疏性的最简单衡量标准是零元素占总元素的比例,在这种情况下约为~

  • 零的数量 = 93

  • 数组中的元素数量 = 4 × 34 = 136

因此,数组中超过 50%的元素完全没有信息(93 个中的 136 个),但这是一个高维矩阵,需要更多的内存(增加的 空间复杂度)和计算时间(增加的 时间复杂度)。如果机器学习模型使用这个高维数据,它将发现很难处理。

  • 寻找模式

  • 为所有维度调整权重将花费过高。

  • 它最终会导致预测时的延迟问题。

稀疏性类似于维度诅咒的概念。推荐系统和协同过滤技术、计数数据表示,包括著名的 TF-IDF,都容易受到文本数据稀疏性相关的问题。

稠密表示 | 矩阵 | 向量

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Mike LUnsplash 拍摄

出路?一种包含更多信息且冗余更少的表示,数学上定义为大多数元素非零的矩阵或向量。这种数据表示被称为稠密矩阵或稠密向量。它们通常比稀疏矩阵的尺寸更小。

使用稠密向量进行机器学习的优点

  1. 维度越小,优化机器学习模型的权重就越快、越容易。

  2. 尽管稠密向量的维度可能比稀疏矩阵小,但它们也可能足够大以挑战计算基础设施(想象一下 Word2Vec 或基于 BERT 的表示),但仍然包含丰富且有用的信息,如句法、语义或形态关系。

  3. 它们对文本元素之间关系的概括能力更强,这一点通过 word2vec 算法的成功得到了明确证明。

将稀疏表示转换为稠密表示的常见自然语言处理技术:

  1. Word2Vec: 这是最受欢迎的算法之一,使用浅层神经网络学习稠密表示,同时尝试预测可能的词汇并捕捉语义关系。

  2. FastText: 另一种使用浅层神经网络实现相同目标的算法,只是 FastText 使用了字符级 n-grams。然而,Word2Vec 被认为对英语效果最好,但 FastText 对形态丰富的语言如阿拉伯语、德语和俄语更为适用。此外,它在捕捉句法特征方面优于语义特征。

  3. GloVe: 同样!学习密集表示,但基于共现的概率。

这是一个简明的演示,展示如何使用Gensim 的 word2vec算法获取密集表示。

以下是词汇‘demonstration’的长度为 10 的密集表示(请注意vector_size参数对于word2vec模型的值是 10)。注意此数值表示中没有零。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片来源:作者

通常,向量的尺寸越大,捕捉的知识就越好,特别是语义信息。这些对评估文本相似性和在无监督的文本处理技术中非常有用。

此外,以下是我们第一个文档“产品或技术的演示”中每个单词获得的密集向量的快照,这些向量按文档中出现的顺序排列。这次我没有清理文本,而是保持原样,因此列表中有七个词向量:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对文档‘产品或技术的演示’获得的长度为 10 的密集向量显示该数值表示中没有非零元素 |* 图片来源:作者

像这样的密集向量也可以在大型语料库上进行预训练,这些语料库通常可以在线访问。想象一下一个字典,像往常一样列出所有唯一的词汇,但其词汇意义被包含其数值表示的预训练词向量替代,颇似一个**“量化字典”**。这里有两个流行的“量化字典”可以下载并应用于文本处理任务:

  • Google:使用 Google 新闻数据集训练,包含约 1000 亿个词汇。300 维的词向量可以从这里下载。词汇表的大小为 300 万。

  • GloVe:使用 Wikipedia 文章训练,包含 50、100、300 和 500 维的词向量,可以从这里下载。词汇表的大小是 400k。

结论

传统上,一维热编码向量、词频矩阵(或计数向量)和 TF-IDF 评分(稀疏表示)被用于文本分析。它们并不保留任何语义信息。然而,现代方法通过神经网络(如 Word2Vec)或更复杂的统计方法和归一化技术(如 GloVe)来获取词嵌入,更好地保留了词的“意义”,并使我们能够对出现于类似上下文中的词进行聚类。但这些方法也带来了计算时间更长的复杂性,这使得它们在扩展时成本较高(取决于学习超参数,特别是更高的向量表示大小)。此外,它们也更难以解释。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由Michał Parzuchowski拍摄,发布在Unsplash

在所有现实世界的案例中,这两种方法都是适用的。例如,在著名的垃圾邮件分类数据集中,稀疏表示方法可以获得接近完美的模型表现。在这种情况下,我们无需计算稠密向量嵌入即可获得更好的性能,因为我们用简单透明的方法就能成功实现目标。

因此,推荐的文本处理任务起点是使用基于频率的词袋模型,该模型生成稀疏向量。对于这样的管道,清理和整理文本数据至关重要。通过合适的特征和词汇工程,它们在速度和性能方面可能是最有效的,特别是当不需要语义信息时。

这是 Jupyter Notebook ,其中包含完整的 Python 演示,展示了如何为相同示例获取稀疏和稠密向量(使用 Gensim 的 Word2Vec)。

💡 想了解更多关于自然语言处理的矩阵设计吗?这里有一篇文章可以进一步学习:

## 自然语言处理中的向量空间模型矩阵设计

自然语言处理中的知识表示简要哲学和分布式词矩阵设计的简明指南……

towardsdatascience.com

💡 想要实现 Word2Vec 用于文本分类?这里有一个关于多类文本分类的实用教程,讲解了如何使用 Keras 的嵌入层以及 Gensim 的 Word2Vec 算法学习稠密表示:

## 使用 Keras 进行多类文本分类:有词嵌入与无词嵌入的比较…

词嵌入是否为文本分类模型增加价值?让我们在这个多类预测任务中来探讨一下…

towardsdatascience.com

参考资料:

  1. machinelearningmastery.com/sparse-matrices-for-machine-learning/

  2. kavita-ganesan.com/fasttext-vs-word2vec/#.Y-OP7XbP02w

感谢访问!

我的链接: Medium | LinkedIn | GitHub

我们的 MLOps 故事:为十二个品牌提供生产级机器学习

原文:towardsdatascience.com/our-mlops-story-production-grade-machine-learning-or-twelve-brands-a8727fd56c94

在荷兰 DPG Media 以有限资源构建 MLOps 平台的过程中,我们学到的东西

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Jeffrey Luppes

·发表于 Towards Data Science ·阅读时间 12 分钟·2023 年 6 月 5 日

部署一个机器学习模型一次是一个直接的任务;重复将机器学习模型投入生产则要困难得多。为了应对这一复杂过程,MLOps(机器学习运维)的概念应运而生。MLOps 代表了 DevOps、机器学习和软件工程实践的融合。这里有几个细微之处,但 MLOps 具体包含什么的更好定义仍在讨论中,也是供应商推销其产品的战场。为了简洁起见,我宁愿继续讲述我们的 MLOps 故事。

我们的 MLOps 之旅始于 2021 年 9 月。我们的团队仅在六个月前成立,我们开始时接手了少量继承的项目。我们团队的目标在纸面上很简单:我们要为在线服务提供数据/机器学习平台,这是 DPG Media 的一部分,专注于网站和社区。我们的“投资组合”包括十多个品牌,其中包括:一个受欢迎的科技新闻网站及其社区、两个招聘门户网站、一个期待父母的社区、几个可以购买二手车的网站,以及几个具有类似受众的网站。这一点对本文的其余部分很重要。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

当我们开始构建平台时,我们计划支持这十二个(荷兰)品牌。

当时,机器学习团队只有一名数据科学家和我,一名机器学习工程师。我们两人相隔两周被聘用,对我们被期望投入的组织都是全新的。

当时,我们的机器学习生产环境(我宽松地使用这个术语)如下所示:

  • 一个建议工作,为用户提供建议,通过 Airflow 在 Spark 上运行,适用于品牌 #1。

  • 一个给汽车定价建议的模型,同时作为 Airflow 的批处理作业运行,用于品牌 #2。

  • 一个针对品牌 #3 的 Databricks 目标受众的模型,作为计划好的笔记本再次作为批处理作业运行。

  • 一个在 EC2 上运行的单个 Flask 应用程序,将各种模型加载到内存中,以便演示和展示各个品牌的项目。

面对十二个品牌,每个品牌可能在自己的系统和云上,我们不能对我们开发的任何东西如何被使用做出强烈假设。

两位现已离职的数据科学家完成了所有先前的项目。他们的大多数项目都存在于 Jupyter Notebooks 中,服务它们的 Flask 应用程序托管在 EC2 上 — 且经常宕机。一个单一的 MLflow 服务器在 EC2 上运行,但已过时,并且存在一些安全问题。Databricks 项目只是一个单一的笔记本,甚至没有版本控制。我们甚至不知道谁为我们安排作业的集群付费。

我们的团队需要扩展,承担更多项目,并仅花少量时间支持旧项目。我们无法继续以原有方式运作,特别是当我们希望进行实时推理时。机器学习的良机开始出现,我们的客户要求实时模型。对 MLOps 的结构化方法的必要性变得明确。

制定计划

我们可以依赖数据工程师(我们的团队有四名专职数据工程师)、架构师和 DPG 的系统工程师的帮助,但显然我们应该自己掌握平台。特别是我们的数据工程师已经捉襟见肘,面临着自己的截止日期和迁移。未来我们需要自己管理和更新我们的系统。我们必须亲自掌控。

我们在团队内部组织了几次头脑风暴会议,并采访了组织中的几位架构师。事情逐渐变得更为确定,而不是像之前那样在我们办公室五楼的一个阴暗角落的白板上涂涂画画。我们想给 MLflow 另一个机会,并尽可能地将所有内容保留在 AWS 上。毕竟,AWS SageMaker 显然在向更成熟的平台发展。我们的一位团队负责人敦促我们尽早适应 Terraform(或某种形式的 IaC)。由于我们的数据工程师已经在使用 Terraform,这成为了我们平台的基石。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

拍打白板 这个家伙只能容纳这么多功能。图片由作者提供。

我加入了 MLOps 社区以了解更多工具,并与供应商进行了几次对话。开始参加聚会。幸运的是,我们还有一个 AWS 企业支持团队可以帮助我们,因为我们已经是 AWS 的大用户。很多想法,可能太多了,开始涌入。MLOps 场景(现在仍然是)有点混乱,这在预期之中;对我们来说,重要的是快速行动并决定最重要的事情。

我们最终决定平台的原则大致如下:

  • 用 Terraform 做所有事情,除非我们不能…

  • 尽量遵循数据网格(我们组织在 2021 年采纳了),除非…

  • 尽可能使用托管服务,除非…

  • 转向无服务器,除非…

  • 尽可能避免使用 Kubernetes

  • 随着进展 建设,并在我们重新访问旧项目时迁移它们

模型工件和实验跟踪以及我们的第一个 MLOOPS

尽管有意图仅在需要时迁移,但我们尝试的首件事之一是将 MLflow 服务器迁移到 AWS Fargate,并将数据库放在 AWS RDS 上,而不是与服务器运行在同一个 EC2 实例上。根据业务单元,我们决定托管一个实例,测试和生产用不同的服务器。这样,四个业务单元意味着 4 x 2 几乎相同的设置。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

MLflow 在 AWS 上的示例架构。取自 aws.amazon.com/blogs/machine-learning/managing-your-machine-learning-lifecycle-with-mlflow-and-amazon-sagemaker/

这证明是一个相当昂贵的想法(8 份这个设置,每个都有自己的负载均衡器和数据库!),而我们正在做的项目数量远远不足以支撑它。后来我们将其减少到两个实例。像这样大规模启动也意味着要直接解决 terraform、弹性负载均衡器、IAM 和 route 53。学习曲线相当陡峭,花了很多时间熟悉 AWS 的各个部分。

我们的第一个 ML-OOPS 尝试在需要之前设置大量(昂贵的)实例并维护它们。

对于实验(即 Jupyter 笔记本),我们决定使用 AWS SageMaker 的 Notebook 实例。这些笔记本实例配备了一个生命周期脚本,会将正确的 MLflow uri 设置为环境变量。我们创建了一些脚本来批量更新这些实例,以及监控笔记本本身,比如在有人将实例留在办公时间外时在我们的 Slack 频道中发出警报。

模型部署和训练

很快就到了部署我们的第一个模型的时候。我们使用了 SageMaker 的模型端点,并决定使用 Lambda 和 API 网关的设置。SageMaker 本质上可以作为一个一站式部署服务,尽管相比于自己启动 EC2 实例并托管模型,费用更高。相比于自己管理的 Kubernetes 集群,费用也更高。不过,你会得到很多回报。SageMaker 处理各种部署策略、自动扩展,并在需要时允许我们选择 GPU 类型。

我们通过 SageMaker SDK 轻松地从本地和云环境(例如 Jupyter notebook 或 Airflow)部署模型。AWS Lambda 为模型的输入和输出提供了额外的控制,而 API Gateway 提供了一个可以用 API 密钥供用户使用的 restful 接口。除了模型本身,所有元素都通过 terraform 进行部署,添加新模型只需添加一个 terraform 模块,主要指定名称和从哪里提取 Lambda 的代码。这也意味着我们可以改进模型的(前)处理,而无需更改 SageMaker 端点,并为 lambdas 单独设置 CI/CD。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

AWS 上的典型部署。图像由作者提供。

训练任务也委托给了 SageMaker。为我们的前几个 ML 训练任务(使用 TensorFlow 构建的文本分类 LSTM 模型)创建模板并从训练任务容器内部将其记录到 MLflow 上,花费了相当大的精力。我们为训练任务制作了一个通用模板。SageMaker 对接收训练任务有相当明确的要求,这意味着你需要遵循平台的某些约定——即使在使用 TensorFlow 时也是如此。幸运的是,在后台,SageMaker 的模型服务仍然使用 TensorFlow Extended 处理 TensorFlow 模型,因此与 SavedModels 有一定的直观操作性。

我们通过 Airflow 协调训练任务,并明确不包括任何代码合并后的再训练。我们的一些模型相当昂贵,一些则不然,但几乎所有模型都需要大量计算或存储。如果在计划运行之前需要,我们可以简单地触发 dag 并运行管道。

监控和警报

我们 AWS 购物清单上的最后一项是监控和警报。我们首先尝试了 Amazon Managed Prometheus 和 Amazon Managed Grafana,希望能够将 CloudWatch 中的数据导入这些工具中,从而节省 CloudWatch 的成本。事实证明,这可以通过 exporter 工具实现。我们瞄准了 YACE(yet-another-cloudwatch-exporter),但它需要存放在某个地方。这个地方很快就会是 EC2,然后是 ECS。

我们还需要跟踪来自一个业务单位的一些指标。这意味着我们需要某种接口来与之互动。起初,这似乎可以通过 Managed Prometheus 的 Remote Write 功能实现,但我们需要更多控制,因此我们还是设置了 YACE(Prometheus 每五分钟抓取一次)。我们决定将 YACE 和 Prometheus 移动到 ECS 集群,并设置 Remote Write 加 pushgateway 来接收来自我们环境之外的指标。最后,我们放弃了 Amazon Managed Prometheus。

不幸的是,YACE 并不支持我们使用的所有 AWS 服务。我们缺乏 SageMaker 的导出功能,对我们的模型端点一无所知。幸运的是,Amazon Managed Grafana 实例也从 CloudWatch 中提取统计数据,虽然这需要支付额外的费用。

在 Amazon Managed Grafana 中,我们创建了一个通用仪表板,通过将 json 模型参数化,将其转换为模板。一旦完成,我们通过 terraform 推出了每个模型的仪表板。不幸的是,Amazon Managed Grafana 需要一个 API 密钥,以便我们的 terraform 和 ci/cd 正常运行,该密钥的最大有效期为 30 天。我们设置了一个密钥轮换 Lambda,每 29 天销毁并重新创建一个密钥,并将其存储在一个 AWS 秘密中,我们可以在 terraform 代码中请求它。这样,当部署模型时,我们现在可以在几秒钟内自动生成一个 API、监控和日志记录以及一个自定义仪表板。

由于 Grafana 也可以设置在指标超过某个阈值时发送警报,这种设置还允许我们在出现问题时触发警报,并将其转发到 Slack 或 OpsGenie。由于我们仍然只有两个人,我们制定了一个值班计划,每人轮流值班一周。诀窍是从不定义高优先级的警报。

结果

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从一瞥来看,组成“部署”平台的最重要服务。图片来源:作者。

我们最终的“框架”相当轻量级,细心的读者会发现它实际上并没有努力实现完全的端到端自动化。目前我们有大约 15 个模型部署用于实时推断,一年下来仍由两个人组成的团队维持。上面的图片是 AWS 为中心的视图,而下面的蓝图,使用了 AI 基础设施联盟 的模板,提供了迄今为止堆栈功能的概述。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们的 MLOps 堆栈。图片来源:作者。

我们希望保持灵活性,觉得使用一个更重的“为我们做所有事情”的框架可能会更具限制性和更昂贵。我们尽量不做强假设。例如,并不是每个项目都有新数据进入或有来自生产的反馈。我们可能不被允许随时存储预测结果。并不是每个模型都部署在 SageMaker 上(有些可以很好地运行在 Lambda 中!)。

就像 Lak Lakshmanan 最近的帖子(标题引发关注的“不,你不需要 MLOps”)以及现在著名的MLOps without much Ops博客系列(“你不需要更大的船”),我们有一个努力保持简单的平台。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

也就是说,如果你想保持灵活性、节省时间、预算或复杂性。

尽管如此,在构建平台时我们确实有很多需求。展示了我们需求映射的 ML 生命周期的高层次图表显示,我们现在覆盖了大部分需求。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们希望在平台中拥有的功能以及我们已覆盖的功能的可视化。请注意,我们在这篇博客文章中没有讨论所有功能。

向前思考

现在我们已经讨论了我们构建了什么以及它如何融入更大的图景。接下来我们要做什么?

该平台在测试和验证方面仍然存在盲点。除了偶尔的测试外,我们没有正式的框架。提前构建这些框架并确保不进行过早优化相对困难,尤其是在压力下。同时,从软件开发的角度来看,这是我们确实无法缺少的。

作为一家媒体公司,我们有处理文本、图像、点击流、图形、向量和表格数据的模型。一些模型处理多种数据类型。模型可以包括从 XGBoost 和随机森林到 Transformer 及各种递归神经网络和卷积神经网络的任何东西。我们如何希望构建或购买能够测试所有数据类型和模型的东西呢?

另一个需要解决的问题是减少 Lambda 函数的冷启动时间。Lambda 函数是在被调用时运行的服务函数。第一次调用后,Lambda 会保持活动状态约 15 分钟,除非有其他调用跟随,最长寿命约为两小时。在首次分配资源和镜像时会出现冷启动。有时这只是几秒钟,但如果在 Lambda 中添加 TensorFlow 导入,你可能会看到你的 API 超时。

这是使用 Lambda 的生活事实——但这意味着我们或 API 的用户需要具备错误处理机制,以应对运行时间过长的问题。虽然建议不要在低流量的情况下使用 Lambda,但它仍然是我们所拥有的最便宜的选择,并且有助于抵消 SageMaker 的成本溢价。此外,它们非常容易维护。然而,冷启动是否真正成为问题,完全取决于业务背景和请求量。

我希望将来能离开我们自托管的 MLflow。它没有基于角色的访问控制。这意味着每个用户都可以查看(和删除)每个模型,并且用户需要滚动浏览可能上百个模型才能找到他们需要的。使用它还需要认知负担;任何使用它的数据科学家都必须主动注意设置实验和调用诸如 mlflow.log 或 mlflow.autolog 的函数。由于我们没有使用从 MLflow 部署到 SageMaker 的选项,我们可以切换到这个领域中的其他工具之一。我们实际上只是将 MLflow 用作跟踪过去模型运行的一种方式。

结束语

总结来说,本文介绍了我们创建适合我们需求的 MLOps 堆栈的过程。我们使用了 AWS 服务和开源工具来选择一套工具,以处理我们大部分的用例。随着团队的发展,这个堆栈将继续演变。我们的主要收获是:

  • 选择托管服务,别回头看。 如果你的团队相对较小,选择托管服务是个很好的主意,这样你就不会有同样的管理开销。

  • 获取 Sagemaker。 Sagemaker 非常适合小型团队,并且在部署方面表现出色(虽然更新方面表现一般,这个以后再说),但熟悉它需要一些时间。

  • 顺其自然。 Airflow 和 MLFlow 是机器学习堆栈中的好工具,因为它们允许编排和机器学习记账,这使你能够专注于最重要的工作。

  • 基础设施即代码是云计算的 10 倍放大器。 说真的,Terraform 为我们节省了大量工作,真是太疯狂了。

我希望这种完全开放的讨论能帮助其他团队决定他们的技术栈并评估他们的需求。希望未来我们使用的平台和工具能够变得更加成熟,并且更好地集成。

本文得到了 Gido SchoenmackerJoost de WitKim SterenborgAmine Ben Slama 的帮助。

Jeffrey Luppes 是位于荷兰阿姆斯特丹的 DPG Media 的机器学习工程师。

单变量数据集中的分布拟合异常值检测

原文:towardsdatascience.com/outlier-detection-using-distribution-fitting-in-univariate-data-sets-ac8b7a14d40e

学习如何使用概率密度函数检测异常值,以实现快速、轻量级的模型和可解释的结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Erdogan Taskesen

·发表于数据科学前沿 ·阅读时间 16 分钟·2023 年 2 月 18 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由Randy Fath提供,来自 Unsplash

异常或新奇检测适用于各种需要明确早期警告的异常情况,例如传感器数据、安全操作和欺诈检测等。由于问题的性质,异常值不常出现,并且由于缺乏标签,创建监督模型可能变得困难。异常值也被称为异常或新奇,但在基本假设和建模过程上存在一些根本差异。在这里,我将讨论异常和新奇之间的根本差异以及异常值检测的概念。通过一个实际的例子,我将演示如何创建一个无监督模型,用于使用概率密度拟合来检测单变量数据集中的异常和新奇。 distfit 库在所有示例中都被使用。

如果你觉得这篇文章有帮助,可以使用我的 推荐链接 继续无缝学习,并注册 Medium 会员。此外, 关注我 以保持对我最新内容的关注!

异常还是新奇?

异常和新颖性都是与标准、正常或预期的情况偏离的观察。对于这种观察的集体名称是异常值。一般来说,异常值呈现在分布的(相对)尾部,远离其余的密度。此外,如果你观察到某个值或小范围值的密度出现大幅尖峰,这可能指向潜在的异常值。虽然异常和新颖性检测的目标是相同的,但在概念建模上存在一些差异 [1],简要总结如下:

异常是已知存在于训练数据中的异常值,并且偏离正常或预期的情况。 在这种情况下,我们应该旨在对具有预期/正常行为的观察值(也称为内点)进行建模,并忽略偏离的观察值。那些超出预期/正常行为的观察值即为异常值。

新颖性是指训练数据中未曾出现的异常值。数据中不包含偏离正常/预期的观察。 新颖性检测可能更具挑战性,因为没有异常值的参考。在这种情况下,领域知识更为重要,以防止模型对内点过拟合。

异常值可以分为三类。

我刚刚提到异常和新颖性之间的区别在于建模过程。但不仅仅如此。在我们开始建模之前,我们需要对“异常值应该是什么样的”设定一些期望。异常值大致可以分为三类(图 1),总结如下:

  • 全局异常值(也称为点异常值)是单个独立的观察值,与所有其他观察值偏离[1, 2]。当提到“异常值”时,通常指的是全局异常值。

  • 上下文异常值发生在特定观察值在特定上下文中不符合预期时。上下文可以表现为双峰或多峰分布,而异常值在上下文中偏离。例如,冬季气温低于 0 度是正常的,但在夏季则不寻常,因此被称为异常值。除了时间序列和季节性数据,其他已知应用还包括传感器数据[3]和安全操作[4]。

  • 集体异常值(或称为群体异常值)是一组具有不寻常行为的相似/相关实例,与数据集中的其他数据点相比具有不同的表现[5]。这类异常值群体可能形成双峰或多峰分布,因为它们通常表示与个体异常值不同的问题类型,例如批处理错误或数据生成过程中的系统性问题。请注意,集体异常值的检测通常需要不同于个体异常值的检测方法。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1. 从左到右展示了全局异常值、上下文异常值和集体异常值的示例。图片由作者提供。

在开始建模异常值之前,还有一个需要讨论的部分是数据集部分。从数据集的角度来看,异常值可以根据单一特征(单变量)或每个观察值的多个特征(多变量)进行检测。继续阅读,因为下一部分是关于单变量和多变量分析的。

异常值可以以单变量或多变量方式建模。

检测任何类型异常值的建模方法有两个主要类别;单变量和多变量分析(图 2)。我将重点讨论单变量随机变量的异常值检测,但在此之前,我将简要描述它们的区别:

  • 单变量方法是指使用一个变量一次性标记样本/观察值为异常值,例如,一个人的年龄、体重或时间序列数据中的单一变量。在这种情况下,分析数据分布适合于异常值检测。

  • 多变量方法是指样本/观察值包含多个特征,可以一起分析,例如年龄、体重和身高。它适合于检测具有(非)线性关系或每个变量的值分布(高度)偏斜的异常值。在这些情况下,单变量方法可能效果不佳,因为它未考虑变量之间的关系。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2. 单变量与多变量分析在异常值检测中的概述。图像由作者提供。

使用分布拟合进行单变量异常值检测。

在单变量数据集中,有多种(非)参数化的异常值检测方法,如 Z 分数、Tukey 围栏和基于密度的方法等。这些方法的共同点是建模底层分布。因此,distfit库[6]特别适合于异常值检测,因为它可以确定单变量随机变量的概率密度函数(PDF),还可以使用百分位数或分位数以非参数方式建模单变量数据集。此外,它可以用于建模任何三类异常值:全局、上下文或集体异常值。有关使用distfit库[6]进行分布拟合的更详细信息,请参见这篇博客。建模方法可以总结如下:

  1. 计算随机变量在不同 PDF 中的拟合度,然后使用拟合优度检验对 PDF 进行排名,并通过自助法评估。注意,可以使用带分位数或百分位数的非参数方法。

  2. 直观检查直方图、PDF、CDF 和分位数-分位数(QQ)图。

  3. 根据步骤 1 和 2 选择最佳模型,但也要确保(非)参数模型(例如,PDF)的属性与使用案例相匹配。选择最佳模型不仅是一个统计问题;也是一个建模决策。

  4. 使用(非)参数模型(如 PDF)对新的未见样本进行预测。

连续随机变量的新颖性检测。

我们从一个简单而直观的例子开始,展示如何通过分布拟合和假设检验来实现单变量的新颖性检测在这个例子中,我们的目标是追求一种新颖的方法来检测全球异常值,即数据中不包含偏离正常/预期的观察值。这意味着,在某些时候,我们应该仔细融入领域知识,以设定异常值的边界。

假设我们有 10,000 人的身高测量值。让我们生成一个mean=163std=10的随机正态数据,代表我们的人类身高测量值。*我们期望一个包含两个尾部的钟形曲线;那些身高比平均值小或大的数据。*请注意,由于随机成分,重复实验时结果可能会略有不同。

# Import library
import numpy as np

# Generate 10000 samples from a normal distribution
X = np.random.normal(163, 10, 10000)

1. 确定最佳拟合人类身高的 PDF。

在检测任何异常值之前,我们需要拟合一个分布(PDF),以描述人类身高的正常/预期行为。distfit 库可以拟合多达 89 种理论分布。我将把搜索限制在常见/流行的概率密度函数,因为我们预计会有一个钟形曲线(见以下代码部分)。

# Install distfit library
pip install distfit
# Import library
from distfit import distfit

# Initialize for common/popular distributions with bootstrapping.
dfit = distfit(distr='popular', n_boots=100)

# Estimate the best fit
results = dfit.fit_transform(X)

# Plot the RSS and bootstrap results for the top scoring PDFs
dfit.plot_summary(n_top=10)

# Show the plot
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3. 人类身高与最常见分布的 RSS 分数拟合情况。

loggamma PDF 被检测为人类身高的最佳拟合,依据是拟合优度检验统计量(RSS)和自助法。请注意,自助法评估了 PDF 是否存在过拟合。自助得分范围在[0, 1]之间,描绘了 PDF 的自助数量(n_bootst=100)的拟合成功率。也可以从图 3 中看到,除了loggamma PDF 外,还有多个其他 PDF 也被检测出低残差平方和,即Beta, Gamma, Normal, T-分布, Loggamma, 广义极值, 和 Weibull 分布(图 3)。然而,只有五种 PDF 通过了自助法。

2: 视觉检查最佳拟合的概率密度函数(PDF)。

最佳实践是视觉检查分布拟合。distfit 库包含内置的绘图功能,如结合 PDF/CDF 的直方图和 QQ 图。可以按照如下方式创建图表:

# Make figure
fig, ax = plt.subplots(1, 2, figsize=(20, 8))

# PDF for only the best fit
dfit.plot(chart='PDF', n_top=1, ax=ax[0]);

# CDF for the top 10 fits
dfit.plot(chart='CDF', n_top=10, ax=ax[1])

# Show the plot
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4. 帕累托图,显示了经验数据的直方图和估计的 PDF。左侧面板:最佳拟合的 PDF(贝塔)。右侧面板:前 10 个最佳拟合的 CDF。置信区间基于 alpha=0.05。

视觉检查确认了顶级 PDF 的拟合优度评分。然而,有一个例外,即威布尔分布(图 4 中的黄色线)似乎有两个峰值。换句话说,尽管 RSS 较低,但视觉检查未显示出对我们随机变量的良好拟合。请注意,引导法很快排除了威布尔分布,现在我们知道原因了

步骤 3:通过使用 PDF 属性进行决定。

最后一步可能是最具挑战性的,因为仍然有五种候选分布在拟合优度测试、引导法和视觉检查中得分非常高。我们现在应该决定哪个 PDF 在其基本属性上最适合建模人类身高。我将逐步阐述与我们人类身高建模用例相关的顶级候选分布的属性。

正态分布 是一个典型的选择,但需要注意的是,对人类身高的正态性假设在所有人群中可能并不成立。它没有重尾,因此可能无法很好地捕捉异常值。

学生 t 分布 通常在样本量较小或总体方差未知时作为正态分布的替代。它比正态分布具有更重的尾部,这能更好地捕捉数据中的异常值或偏斜。如果样本量较小,这种分布本可以是一个选项,但随着样本量的增加,t 分布趋近于正态分布。

伽玛分布 是一种连续分布,通常用于建模数据呈正偏态,即存在长尾的高值。人类身高可能因异常值(如非常高的个体)而呈正偏态。然而,引导法显示了较差的拟合。

对数伽玛分布 具有偏斜的形状,类似于伽玛分布,但具有更重的尾部。它建模值的对数,这使得当数据具有大量高值时更为合适。

贝塔分布 通常用于建模比例或率[9],而不是像我们用于身高的这种连续变量。如果身高被一个参考值(如中位身高)除以,那么它本是一个合适的选择。因此,尽管它在拟合优度测试中得分最高,我们通过视觉检查确认了良好的拟合,但它不会是我的首选。

**广义极值(GEV)**分布可以用来建模人群中的极值分布,例如最大值或最小值。它也允许重尾分布,可以捕捉数据中的离群值或偏斜。然而,它通常用于建模极值的分布 [10],而不是像人类身高这样的连续变量的总体分布。

Dweibull 分布可能不是这个研究问题的最佳匹配,因为它通常用于建模具有单调增加或减少趋势的数据,例如故障时间或事件时间数据 [11]。人类身高数据可能没有明确的单调趋势。PDF/CDF/QQ 图的视觉检查也显示没有良好的匹配。

总结来说,loggamma 分布在考虑了拟合优度检验、引导法、视觉检查以及现在基于与研究问题相关的 PDF 属性后,可能是这个特定使用案例中最佳的选择。请注意,我们可以轻松指定loggamma 分布并在输入数据上重新拟合(参见代码部分),如果需要的话(参见代码部分)。

# Initialize for common or popular distributions.
dfit = distfit(distr='loggamma', alpha=0.01, bound='both')

# Estimate the best fit
results = dfit.fit_transform(X)

# Print model parameters
print(dfit.model)

# {'name': 'loggamma',
#  'score': 6.676334203908028e-05,
#  'loc': -1895.1115726427015,
#  'scale': 301.2529482991781,
#  'arg': (927.596119872062,),
#  'params': (927.596119872062, -1895.1115726427015, 301.2529482991781),
#  'color': '#e41a1c',
#  'CII_min_alpha': 139.80923469906566,
#  'CII_max_alpha': 185.8446340627711}

# Save model
dfit.save('./human_height_model.pkl')

第 4 步. 对新的未见样本进行预测。

使用拟合模型,我们可以评估新(未见)样本的重要性,并检测它们是否偏离正常/预期(内点)。预测是基于理论概率密度函数进行的,这使得它轻量、快速且易于解释。PDF 的置信区间是通过alpha参数设置的。这是需要领域知识的部分,因为我们的数据集中没有已知的离群值。 在这种情况下,我设置了置信区间(CII)alpha=0.01,这导致最小边界为 139.8cm,最大边界为 185.8cm。默认情况下,两个尾部都会被分析,但这可以使用bound参数进行更改*(参见上面的代码部分)*。

我们可以使用predict函数对新的未见样本进行预测,并创建预测结果的图表(图 5)。请注意,显著性经过了多重测试校正:multtest='fdr_bh'因此,离群值可能位于置信区间之外,但不会被标记为显著。

# New human heights
y = [130, 160, 200]

# Make predictions
results = dfit.predict(y, alpha=0.01, multtest='fdr_bh', todf=True)

# The prediction results
results['df']

#        y   y_proba y_pred         P
# 0  130.0  0.000642   down  0.000428
# 1  160.0  0.391737   none  0.391737
# 2  200.0  0.000321     up  0.000107

plt.figure();
fig, ax = plt.subplots(1, 2, figsize=(20, 8))
# PDF for only the best fit
dfit.plot(chart='PDF', ax=ax[0]);
# CDF for the top 10 fits
dfit.plot(chart='CDF', ax=ax[1])
# Show plot
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5. 左面板:经验数据和对数-伽马 PDF 的直方图。黑线是经验数据分布。红线是拟合的理论分布。红色垂直线是设置为 0.01 的置信区间。绿色虚线被检测为离群值,红色叉号则不显著。(作者提供的图像)

预测结果存储在results中,包含多个列:yy_probay_predPP代表原始 p 值,y_proba是经过多重测试校正后的概率(默认值:fdr_bh)。请注意,使用todf=True参数时会返回一个数据框。两个观察值的概率alpha<0.01,并标记为显著updown

真实世界数据中的异常检测。

到目前为止,我们已经看到如何拟合模型并检测新颖性检测中的全球异常值。在这里,我们将使用真实世界的数据进行异常检测。 使用真实世界的数据通常更具挑战性。为了演示这一点,我将从 Thomson Reuters [7] 下载天然气现货价格的数据集,这是一份开源且免费提供的数据集 [8]。下载、导入并去除 nan 值后,共有 6555 个数据点,覆盖 27 年。

# Initialize distfit
dfit = distfit()

# Import dataset
df = dfit.import_example(data='gas_spot_price')

print(df)
#             price
# date             
# 2023-02-07   2.35
# 2023-02-06   2.17
# 2023-02-03   2.40
# 2023-02-02   2.67
# 2023-02-01   2.65
#           ...
# 1997-01-13   4.00
# 1997-01-10   3.92
# 1997-01-09   3.61
# 1997-01-08   3.80
# 1997-01-07   3.82

# [6555 rows x 1 columns]

对数据集的可视化检查。

为了直观地检查数据,我们可以创建一个天然气现货价格的折线图,以查看是否存在明显的趋势或其他相关问题(图 6)。可以看出,2003 年和 2021 年包含两个主要的峰值(这表明存在全球异常值)。此外,价格动作似乎呈现出自然的波动,有局部的高点和低点。基于这个折线图,我们可以对预期的分布形成直观的理解。价格主要在[2, 5]范围内波动,但在 2003 年至 2009 年之间有一些异常年份,价格范围更多在[6, 9]之间。

# Get unique years
dfit.lineplot(df, xlabel='Years', ylabel='Natural gas spot price', grid=True)

# Show the plot
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 6. 从 Thomson Reuters [7, 8]获取的天然气现货价格数据集开放数据源。

让我们使用distfit来更深入地研究数据分布,并确定相应的 PDF。搜索空间设置为所有可用的 PDF,bootstrap 方法设置为 100,以评估 PDF 的过拟合情况。

# Initialize
from distfit import distfit

# Fit distribution
dfit = distfit(distr='full', n_boots=100)

# Search for best theoretical fit.
results = dfit.fit_transform(df['price'].values)

# Plot PDF/CDF
fig, ax = plt.subplots(1,2, figsize=(25, 10))
dfit.plot(chart='PDF', n_top=10, ax=ax[0])
dfit.plot(chart='CDF', n_top=10, ax=ax[1])

# Show plot
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 7. 左:PDF,右:CDF。所有拟合的理论分布以不同颜色显示。(图片由作者提供)

最佳拟合的 PDF 是Johnsonsb(图 7),但当我们绘制经验数据分布时,PDF(红线)并未完全跟随经验数据。一般来说,我们可以确认大多数数据点位于[2, 5]范围内(这是分布的峰值所在位置),并且在分布中存在一个较小的第二个峰值,价格动作大约在 6 附近。这也是 PDF 未能平滑拟合经验数据的地方,导致一些低估和高估。通过总结图和 QQ 图,我们可以更好地研究拟合情况。让我们使用以下代码创建这两个图:

# Plot Summary and QQ-plot
fig, ax = plt.subplots(1,2, figsize=(25, 10))

# Summary plot
dfit.plot_summary(ax=ax[0])

# QQplot
dfit.qqplot(df['price'].values, n_top=10, ax=ax[1])

# Show the plot
plt.show()

在汇总图中看到拟合优度测试在所有顶级分布中显示了良好的结果(低分)很有趣。然而,当我们查看自助法的结果时,显示除了一个分布外,所有分布都过度拟合(图 8A,橙色线)。这并不完全意外,因为我们已经注意到超调和欠调。QQ 图确认拟合的分布与经验数据之间存在较大偏差(图 8B)。只有Johnsonsb分布显示出(边际)良好的拟合。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 8. A. 左侧面板:根据自助法得分和拟合优度测试对 PDF 进行排序。B. 右侧面板:QQ 图,比较经验分布与所有其他理论分布。(图片由作者提供)

全球和上下文异常值检测。

我们将继续使用Johnsonsb分布和predict功能来检测异常值。我们已经知道数据集中包含异常值,因为我们遵循了异常方法,即分布是基于内点进行拟合的,而现在落在置信区间之外的观察值可以标记为潜在的异常值。 使用predict函数和lineplot我们可以检测和绘制异常值。从图 9 可以看到,虽然我们没有明确对其建模,但全球异常值和一些上下文异常值都被检测到了。红色条形图表示不足代表的异常值,绿色条形图表示过度代表的异常值。可以设置alpha参数来调整置信区间。

# Make prediction
dfit.predict(df['price'].values, alpha=0.05, multtest=None)

# Line plot with data points outside the confidence interval.
dfit.lineplot(df['price'], labels=df.index)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 9. 拟合分布并进行预测后的异常值绘制。绿色条形图表示在 95%置信区间上界之外的异常值。红色条形图表示在 95%置信区间下界之外的异常值。

结语。

我描述了异常检测与新颖性检测之间的区别,以及如何使用分布拟合创建模型。通过使用distfit库,可以评估 89 种理论分布,选择合适的分布,并对新的未见样本进行预测。通过一个实际示例和一个真实数据集,我展示了如何确定最佳匹配的 PDF。请注意,可能没有任何已知的理论分布显著匹配。在这种情况下,distfit库还提供了使用百分位数分位数进行非参数拟合的选项。更多信息请参考我之前的博客关于分布拟合[6]。需要注意的是,异常检测是一项具有挑战性的任务,因为什么是正常或预期的定义可能是主观的,并且可能根据应用而有所不同。此外,异常可能由测量误差、数据错误或自然波动引起,因此在得出任何结论之前,仔细考虑偏差的根本原因非常重要*。

保持安全。保持警觉。

干杯 E.

如果你觉得这篇文章对你有帮助,请使用我的 推荐链接 继续无限学习并注册 Medium 会员。此外, 关注我 以保持最新内容的更新!

软件

让我们联系吧!

参考文献

  1. Breunig, Kriegel, Ng, 和 Sander (2000), LOF: 识别基于密度的局部异常点 Proc. ACM SIGMOD

  2. scikit-learn.org/stable/modules/outlier_detection.html

  3. Hayes, M.A., Capretz, M.A. 大传感器数据的上下文异常检测框架. 《大数据期刊》 2, 2 (2015). doi.org/10.1186/s40537-014-0011-y

  4. A. AlEroud 和 G. Karabatis, 一种上下文异常检测方法用于发现零日攻击, 2012 国际网络安全会议, 美国弗吉尼亚州亚历山德里亚, 2012, 第 40–45 页, doi: 10.1109/CyberSecurity.2012.12

  5. Song W., Dong W., Kang L. 基于贝叶斯框架和遗传算法的群体异常检测, Inf. Sci. (NY), 533 (2020), 第 138–149 页, 10.1016/j.ins.2020.03.110

  6. E. Taskesen, 如何找到数据的最佳理论分布, 2023 年 2 月 Medium。

  7. Thomson Reuters,天然气现货价格

  8. Thomson Reuters,天然气现货价格开放源数据

  9. 维基百科,贝塔分布.

  10. statisticshowto,极值分布与极值理论

  11. 维基百科,威布尔分布

主成分分析与霍特林 T2 及 SPE/DmodX 方法的异常值检测

原文:towardsdatascience.com/outlier-detection-using-principal-component-analysis-and-hotellings-t2-and-spe-dmodx-methods-625b3c90897

由于 PCA 的敏感性,它可以用于检测多变量数据集中的异常值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Erdogan Taskesen

·发表于Towards Data Science ·阅读时长 11 分钟·2023 年 3 月 11 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由Andrew Ridley提供,拍摄于Unsplash

主成分分析(PCA)是一种广泛使用的降维技术,能够在保持相关信息的同时减少维度。由于其敏感性,它也可以用于检测多变量数据集中的异常值。异常值检测可以为异常情况提供早期预警,允许专家在问题升级之前识别和解决问题。然而,由于高维度和缺乏标签,在多变量数据集中检测异常值可能具有挑战性。PCA 在异常值检测中提供了几个优势。我将描述使用 PCA 进行异常值检测的概念。通过实际示例,我将展示如何为连续和分类数据集创建一个无监督模型来检测异常值。

异常值检测。

异常值可以通过单变量多变量方法建模(见图 1)。在单变量方法中,异常值是通过对一个变量进行数据分布分析来检测的。有关单变量异常值检测的更多详细信息,请参阅以下博客文章[1]:

## 单变量数据集中的分布拟合异常值检测

了解如何使用概率密度函数检测离群点,以获得快速且轻量的模型和可解释的结果。

towardsdatascience.com

多变量方法使用多个特征,因此可以检测具有(非)线性关系或偏斜分布的离群点。scikit-learn 库有多种多变量离群点检测解决方案,例如一类分类器、孤立森林和局部离群因子[2]。在这篇博客中,我将专注于使用主成分分析[3]进行多变量离群点检测,其自身具有可解释性等优点;离群点可以通过主成分分析的降维得到可视化。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1. 单变量与多变量分析在离群点检测中的概述。*多变量数据集的离群点检测将在此博客中描述(*图像由作者提供)。

异常与新颖性

异常与新颖性是与标准/预期行为偏离的观察结果,也称为离群点。尽管有一些不同:异常是之前见过的偏差,通常用于检测欺诈、入侵或故障。新颖性是之前未见过的偏差,用于识别新的模式或事件。在这种情况下,使用领域知识非常重要。由于什么是正常或预期的定义可以是主观的并且基于应用而有所不同,因此检测异常和新颖性都可能具有挑战性。

主成分分析用于离群点检测。

主成分分析(PCA)是一种线性变换,它减少了数据的维度并寻找数据中方差最大的方向。由于这种方法的特性,它对具有不同值范围的变量以及离群点都很敏感。一个优点是它允许在二维或三维散点图中可视化数据,使得更容易直观地确认检测到的离群点。此外,它提供了对响应变量的良好解释性。PCA 的另一个重大优点是它可以与其他方法结合使用,例如不同的距离度量,以提高离群点检测的准确性。在这里,我将使用包含两种离群点检测方法的 PCA 库:Hotelling’s T2 和 SPE/DmodX。有关更多细节,请阅读关于主成分分析和pca库的博客文章[3]。

## 什么是 PCA 负荷和如何有效使用 Biplots?

主成分分析的实用指南

[towardsdatascience.com

如果你觉得这篇关于异常值检测的文章对你有帮助, 关注我 以保持最新内容!通过我的 推荐链接 来支持这篇内容,这将为你提供 Medium 会员无限制的学习和阅读。

连续随机变量的异常值检测。

让我们从一个示例开始,演示如何使用Hotelling’s T2SPE/DmodX进行连续随机变量的异常值检测。我将使用来自 sklearn 的wine dataset,该数据集包含 178 个样本,13 个特征和 3 个葡萄酒类别[4]。

# Intallation of the pca library
pip install pca
# Load other libraries
from sklearn.datasets import load_wine
import pandas as pd

# Load dataset
data = load_wine()

# Make dataframe
df = pd.DataFrame(index=data.target, data=data.data, columns=data.feature_names)

print(df)
#     alcohol  malic_acid   ash  ...   hue  ..._wines  proline
# 0     14.23        1.71  2.43  ...  1.04  3.92   1065.0
# 0     13.20        1.78  2.14  ...  1.05  3.40   1050.0
# 0     13.16        2.36  2.67  ...  1.03  3.17   1185.0
# 0     14.37        1.95  2.50  ...  0.86  3.45   1480.0
# 0     13.24        2.59  2.87  ...  1.04  2.93    735.0
# ..      ...         ...   ...  ...   ...  ...
# 2     13.71        5.65  2.45  ...  0.64  1.74    740.0
# 2     13.40        3.91  2.48  ...  0.70  1.56    750.0
# 2     13.27        4.28  2.26  ...  0.59  1.56    835.0
# 2     13.17        2.59  2.37  ...  0.60  1.62    840.0
# 2     14.13        4.10  2.74  ...  0.61  1.60    560.0
# 
# [178 rows x 13 columns]

我们可以在数据框中看到每个特征的值范围差异很大,因此归一化步骤很重要。归一化步骤是pca library中的一个内置功能,可以通过normalize=True设置。在初始化时,我们可以分别指定异常值检测方法,ht2用于 Hotelling’s T2,spe用于 SPE/DmodX 方法。

# Import library
from pca import pca

# Initialize pca to also detected outliers.
model = pca(normalize=True, detect_outliers=['ht2', 'spe'], n_std=2  )

# Fit and transform
results = model.fit_transform(df)

运行 fit 函数后,pca库会对每个样本进行异常值评分。对于每个样本,会收集多个统计数据,如下面代码部分所示。数据框中的前四列(y_probap_rawy_scorey_bool)是使用 Hotelling’s T2 方法检测的异常值。后两列(y_bool_spey_score_spe)则基于 SPE/DmodX 方法。

# Print outliers
print(results['outliers'])

#     y_proba     p_raw    y_score  y_bool  y_bool_spe  y_score_spe
#0   0.982875  0.376726  21.351215   False       False     3.617239
#0   0.982875  0.624371  17.438087   False       False     2.234477
#0   0.982875  0.589438  17.969195   False       False     2.719789
#0   0.982875  0.134454  27.028857   False       False     4.659735
#0   0.982875  0.883264  12.861094   False       False     1.332104
#..       ...       ...        ...     ...         ...          ...
#2   0.982875  0.147396  26.583414   False       False     4.033903
#2   0.982875  0.771408  15.087004   False       False     3.139750
#2   0.982875  0.244157  23.959708   False       False     3.846217
#2   0.982875  0.333600  22.128104   False       False     3.312952
#2   0.982875  0.138437  26.888278   False       False     4.238283

[178 rows x 6 columns]

Hotelling’s T2 计算了基于前n_components的卡方检验和 P 值,从而允许通过y_proba对异常值进行从强到弱的排序。请注意,异常值的搜索空间是 PC1 到 PC5,因为预期最高的方差(因此也是异常值)会出现在前几个组件中。注意,深度是可选的,以防方差在前五个组件中捕捉得不好。让我们为葡萄酒数据集绘制异常值并标记它们(图 2)。

# Plot Hotellings T2
model.biplot(SPE=False, HT2=True, density=True, title='Outliers marked using Hotellings T2 method.')

# Make a plot in 3 dimensions
model.biplot3d(SPE=False, HT2=True, density=True, arrowdict={'scale_factor': 2.5, 'fontsize': 20}, title='Outliers marked using Hotellings T2 method.')

# Get the outliers using SPE/DmodX method.
df.loc[results['outliers']['y_bool'], :]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2。左面板:PC1 与 PC2 的关系图以及使用 Hotelling’s T2 方法检测的 9 个异常值的投影样本。右面板:带有异常值的三维图。(图片由作者提供)

SPE/DmodX方法是实际观察值与其投影之间的距离度量,使用主成分。距离中心的值由 Hotelling’s T2 值表示,因此图 3 中的椭圆表示样本超出 Hotelling’s T2 的边界。样本根据前两个主成分的均值和协方差被标记为异常值(图 3)。换句话说,当它在椭圆之外时。

# Plot SPE/DmodX method
model.biplot(SPE=True, HT2=True, title='Outliers marked using SPE/dmodX method and Hotelling T2.')

# Make a plot in 3 dimensions
model.biplot3d(SPE=True, HT2=True, title='Outliers marked using SPE/dmodX method and Hotelling T2.')

# Get the outliers using SPE/DmodX method.
df.loc[results['outliers']['y_bool_spe'], :]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3A. 使用 SPE/DmodX 方法检测到的离群值用菱形标出。使用 Hotelling T2 方法检测到的离群值用十字标出。(作者提供的图像)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3B. 使用 SPE/DmodX 方法检测到的离群值在 3D 图中可视化。

使用两种方法的结果,我们现在也可以计算重叠情况。在这种用例中,有 5 个离群值重叠(见下方代码部分)。

# Grab overlapping outliers
I_overlap = np.logical_and(results['outliers']['y_bool'], results['outliers']['y_bool_spe'])

# Print overlapping outliers
df.loc[I_overlap, :]

分类变量的离群值检测。

对于分类变量中的离群值检测,我们首先需要对分类变量进行离散化,使得距离可以互相比较。通过离散化的数据集(独热编码),我们可以使用 PCA 方法,并应用 Hotelling’s T2 和 SPE/DmodX 方法。我将使用学生成绩数据集[5]进行演示,该数据集包含 649 个样本和 33 个变量。我们将按照下方的代码部分导入数据集。关于列描述的更多细节可以在这里找到。如果数据集中存在标识符列或浮点类型的变量,我会将其删除或将其分类为离散区间,但在这里不会删除任何列。

# Import library
from pca import pca

# Initialize
model = pca()

# Load Student Performance data set
df = model.import_example(data='student')

print(df)
#     school sex  age address famsize Pstatus  ...  Walc  health absences
# 0       GP   F   18       U     GT3       A  ...     1       3        4
# 1       GP   F   17       U     GT3       T  ...     1       3        2
# 2       GP   F   15       U     LE3       T  ...     3       3        6
# 3       GP   F   15       U     GT3       T  ...     1       5        0  
# 4       GP   F   16       U     GT3       T  ...     2       5        0  
# ..     ...  ..  ...     ...     ...     ...  ...   ...     ...      ...  
# 644     MS   F   19       R     GT3       T  ...     2       5        4  
# 645     MS   F   18       U     LE3       T  ...     1       1        4  
# 646     MS   F   18       U     GT3       T  ...     1       5        6  
# 647     MS   M   17       U     LE3       T  ...     4       2        6  
# 648     MS   M   18       R     LE3       T  ...     4       5        4  

# [649 rows x 33 columns]

变量需要进行独热编码,以确保变量之间的距离可以相互比较。这会导致 649 个样本产生 177 列(见下方code部分)。

# Install onehot encoder
pip install df2onehot

# Initialize
from df2onehot import df2onehot

# One hot encoding
df_hot = df2onehot(df)[‘onehot’]

print(df_hot)
#      school_GP  school_MS  sex_F  sex_M  ...  
# 0         True      False   True  False  ...  
# 1         True      False   True  False  ...  
# 2         True      False   True  False  ...  
# 3         True      False   True  False  ...  
# 4         True      False   True  False  ...  
# ..         ...        ...    ...    ...  ...  
# 644      False       True   True  False  ...  
# 645      False       True   True  False  ...  
# 646      False       True   True  False  ...  
# 647      False       True  False   True  ...  
# 648      False       True  False   True  ...  

# [649 rows x 177 columns]

我们现在可以使用处理后的独热数据框作为 PCA 的输入并检测离群值。在初始化过程中,我们可以设置normalize=True以对数据进行标准化,并且需要指定离群值检测方法。

# Initialize PCA to also detected outliers.
model = pca(normalize=True,
            detect_outliers=['ht2', 'spe'],
            alpha=0.05,
            n_std=3,
            multipletests='fdr_bh')

# Fit and transform
results = model.fit_transform(df_hot)

# [649 rows x 177 columns]
# [pca] >Processing dataframe..
# [pca] >Normalizing input data per feature (zero mean and unit variance)..
# [pca] >The PCA reduction is performed to capture [95.0%] explained variance using the [177] columns of the input data.
# [pca] >Fit using PCA.
# [pca] >Compute loadings and PCs.
# [pca] >Compute explained variance.
# [pca] >Number of components is [116] that covers the [95.00%] explained variance.
# [pca] >The PCA reduction is performed on the [177] columns of the input dataframe.
# [pca] >Fit using PCA.
# [pca] >Compute loadings and PCs.
# [pca] >Outlier detection using Hotelling T2 test with alpha=[0.05] and n_components=[116]
# [pca] >Multiple test correction applied for Hotelling T2 test: [fdr_bh]
# [pca] >Outlier detection using SPE/DmodX with n_std=[3]
# [pca] >Plot PC1 vs PC2 with loadings.

# Overlapping outliers between both methods
overlapping_outliers = np.logical_and(results['outliers']['y_bool'],
                                      results['outliers']['y_bool_spe'])

# Show overlapping outliers
df.loc[overlapping_outliers]

#     school sex  age address famsize Pstatus  ...  Walc  health absences 
# 279     GP   M   22       U     GT3       T  ...     5       1       12  
# 284     GP   M   18       U     GT3       T  ...     5       5        4 
# 523     MS   M   18       U     LE3       T  ...     5       5        2 
# 605     MS   F   19       U     GT3       T  ...     3       2        0 
# 610     MS   F   19       R     GT3       A  ...     4       1        0 

# [5 rows x 33 columns]

Hotelling T2 检验检测到 85 个离群值,SPE/DmodX 方法检测到 6 个离群值(图 4,见图例)。两个方法重叠的离群值数量为 5 个。我们可以使用biplot功能绘制图形,并将样本根据任何类别(例如sex标签)进行着色,以便进一步调查。离群值用x*标记。这是进行深入检查的良好起点;在我们的案例中,我们可以在图 4 中看到这 5 个离群值与其他所有样本逐渐分离。我们可以对离群值进行排名,查看载荷,并深入调查这些学生(见前述代码部分)。为了对离群值进行排名,我们可以使用 Hotelling T2 方法的y_proba(值越低越好),以及 SPE/DmodX 方法的y_score_spe(值越大越好,它是样本到中心的欧几里得距离)。

# Make biplot
model.biplot(SPE=True,
             HT2=True,
             n_feat=10,
             legend=True,
             labels=df['sex'],
             title='Student Performance',
             figsize=(20, 12),
             color_arrow='k',
             arrowdict={'fontsize':16, 'c':'k'},
             cmap='bwr_r',
             gradient='#FFFFFF',
             edgecolor='#FFFFFF',
             density=True,
             )

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4. 使用 SPE/DmodX 方法检测到的离群值用菱形标出。使用 Hotelling T2 方法检测到的离群值用十字标出。(作者提供的图像)

结束语。

我展示了如何使用 PCA 对连续和分类变量进行多变量异常值检测。通过使用pca库,我们可以使用 Hotelling 的 T2 和/或 SPE/DmodX 方法来确定候选异常值。每个变量对主成分的贡献可以通过负载获取,并在低维 PC 空间中使用双变量图进行可视化。这些可视化见解有助于提供关于异常值检测的直觉,并判断是否需要后续分析。一般来说,异常值检测可能具有挑战性,因为确定什么被认为是正常的可能是主观的,并且根据具体应用而有所不同。

保持安全,保持冷静。

干杯,E.

如果你觉得这篇关于异常值检测的文章对你有帮助, 关注我 以便了解我最新的内容!通过使用我的 推荐链接 支持这篇内容,这将为你提供 Medium 会员的无限学习和阅读机会。

软件

让我们联系!

参考资料

  1. E. Taskesen, PCA 负载和双变量图是什么?,Medium,Towards Data Science,2022 年 4 月

  2. Scikit-Learn,异常值检测

  3. E. Taskesen,如何为你的数据找到最佳理论分布,2023 年 2 月 Medium。

  4. Wine 数据集,https://archive-beta.ics.uci.edu/dataset/109/wine

  5. P. Cortez 和 A. Silva,利用数据挖掘预测中学生表现,ISBN 978–9077381–39–7

异常值检测与 Scikit-Learn 和 Matplotlib: 实用指南

原文:towardsdatascience.com/outlier-detection-with-scikit-learn-and-matplotlib-a-practical-guide-382d1411b8ec

了解可视化、算法和统计如何帮助你识别机器学习任务中的异常值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Riccardo Andreoni

·发布于 Towards Data Science ·阅读时间 10 分钟·2023 年 10 月 27 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

气球与异常值有什么关系?在引言中找到答案。图片来源: pixabay.com

想象一个房间里充满了五彩斑斓的气球,每个气球象征数据集中一个数据点。由于它们的特征不同,气球浮在不同的高度。现在,想象一些充氦的气球意外地飞得比其他气球高得多。正如这些特殊的气球打破了房间的均匀性,异常值也会打乱数据集中的模式。

回到纯统计学的角度,异常值被定义为异常现象,或者更准确地说,是明显偏离数据集其余部分的数据点。

考虑一个机器学习算法,它根据患者数据来诊断疾病。在这个实际的例子中,异常值可能是实验室结果或生理参数中的极端高值。虽然这些异常值可能源于数据收集错误测量不准确或真正的稀有事件,它们的存在可能导致算法做出错误的诊断。

这就是为什么我们,机器学习或数据科学从业者,必须始终小心处理异常值

在这篇简短的文章中,我将讨论几种有效识别和删除数据中的异常值的方法。

其中之一是 支持向量机,我在这篇文章中探讨了这个方法。

## 支持向量机与 Scikit-Learn:友好的介绍

每个数据科学家都应该在工具箱中有 SVM。通过实际操作来掌握这一多功能模型…

towardsdatascience.com

什么是异常值?

异常值是数据集中不具代表性的数据点,或者更准确地说,是那些与其他数据点显著偏离的数据点。尽管其定义简单,检测这些异常并非总是直接的,但首先,让我们回答以下基本问题。

为什么我们要检测数据集中的异常值?

对这个问题有两个答案。检测异常值的第一个原因是这些异常值可能隐藏数据中的有意义模式,并扭曲机器学习算法的学习过程。例如,在一个基于特征的房价数据集中,一个小而位置差的公寓的异常高价格,可能是异常值,导致偏差预测。

其次,广泛的数据科学应用的唯一目标就是检测异常值。在这些情况下,异常检测不仅仅是数据准备任务,而是应用的整个范围。例如,金融中的欺诈检测:算法的目标是识别不寻常的交易模式,指示欺诈活动。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由作者提供。

对于这份入门指南,我将介绍几种异常检测方法,这些方法分为以下三大类:

  • 图形方法:通过数据可视化来检测异常值。

  • 统计方法:通过统计分析和概率分布来检测异常值。

  • 算法方法:通过机器学习模型来检测异常值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由作者提供。

图形方法

异常检测的图形方法利用了人脑的卓越模式识别能力。它使用散点图、箱线图和热图等可视化工具,提供数据的叙述,并允许数据科学家发现模式中的不规则性

散点图

在一个散点图中,异常值将表现为明显偏离主要聚类的点。

在生成合成数据后,我将使用Matplotlib Pyplot库在Python中创建散点图。

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# Generate synthetic data with outliers
np.random.seed(42)
normal_data = np.random.normal(loc=50, scale=10, size=100)
outliers = np.random.normal(loc=15, scale=5, size=10)

# Combine normal data with outliers
data = np.concatenate((normal_data, outliers))

# Visualize data using a scatter plot
fig, ax = plt.subplots(figsize=(8, 6))
ax.scatter(range_1, normal_data, color=sns.color_palette("hls",24)[7], alpha=.9, label='Normal Data')
ax.scatter(range_2, outliers, color=sns.color_palette("hls",24)[0], alpha=.9, label='Outliers')
ax.set_xlabel('Index')
ax.set_ylabel('Value')
ax.set_title('Scatter Plot')
ax.spines['top'].set_visible(False)
ax.spines['bottom'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.xaxis.set_ticks_position('none') 
ax.yaxis.set_ticks_position('none')
plt.legend()
plt.show()

结果图将突出显示一个数据集,其值与其他数据显著不同:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由作者提供。

箱线图

使用相同的数据,我们可以显示一个箱线图,其中离群点显示为箱线图“须”之外的点

Python代码如下。

# Visualize data using a box plot
fig, ax = plt.subplots(figsize=(8, 6))
b_plot = ax.boxplot(data, vert=True, patch_artist=True, notch=True)
ax.set_ylabel('Value')
ax.set_title('Box Plot')
ax.spines['top'].set_visible(False)
ax.spines['bottom'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.xaxis.set_ticks_position('none') 
ax.yaxis.set_ticks_position('none')
ax.xaxis.set_ticks([])
# Color the box
for box in b_plot['boxes']:
    box.set_facecolor(sns.color_palette("hls",24)[12])

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由作者提供。

小提琴图

除了箱线图,小提琴图不仅展示了数据的分布,还显示了其概率密度

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由作者提供。

在这种情况下,离群点表现为超出数据主体的细小部分。一般来说,如果我注意到小提琴图的某些部分远远超出其他部分,那些很可能是离群点。

你可以用以下代码生成相同的图,或对其进行个性化调整。

# Visualize data using a violin plot
fig, ax = plt.subplots(figsize=(8, 6))
v_plot = ax.violinplot(data, vert=True, showmedians=True, showextrema=False)
ax.set_ylabel('Value')
ax.set_title('Violin Plot')
ax.spines['top'].set_visible(False)
ax.spines['bottom'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.xaxis.set_ticks_position('none') 
ax.yaxis.set_ticks_position('none')
ax.xaxis.set_ticks([])
# Color the violin
for pc in v_plot['bodies']:
    pc.set_facecolor(sns.color_palette("hls",24)[7])
    pc.set_edgecolor('black')
    pc.set_alpha(.8)

统计方法

虽然图形方法确实更易理解,但也有局限性。主要问题是它们提供的是定性的而非定量的结果。因此,散点图、箱线图和分布图有助于有效沟通,但为了进行一致的分析,我们必须依赖数学严谨性统计指标

统计工具如Z 分数四分位距 (IQR)利用统计参数评估数据点。它们使数据科学家能够通过测量数据点偏离预期统计分布的程度,系统地识别离群点。

考虑Z 分数,它测量数据点距离均值的标准差数。Z 分数超过某个阈值的数据点可以被标记为离群点。通常,Z 分数高于 2 或 3 表示离群点。

import numpy as np

# Generate a random dataset with outliers (100 normal points and 10 outliers)
np.random.seed(42)
data = np.concatenate((np.random.normal(loc=50, scale=10, size=100), 
                        np.random.normal(loc=110, scale=20, size=10)))

# Calculate mean and standard deviation
mean_data = np.mean(data)
std_dev = np.std(data)

# Set Z-score threshold (typically 2 or 3)
z_score_threshold = 2

# Identify outliers using Z-score
outliers = [value for value in data if (value - mean_data) / std_dev > z_score_threshold]

类似地,IQR依赖于数据分布的第一和第三四分位数之间的范围。任何显著超出此范围的数据点都会被识别为离群点。由于有时第一和第三四分位数之间的范围可能过于严格,我们可以进行参数调整,例如考虑第一和第九分位数之间的范围。

从数学上讲,超出范围Q1–1.5IQRQ3+1.5IQR的数据点通常被归类为离群点。

另外,Tukey 的围栏方法是一种基于 IQR 范围的参数方法。它将所有落在Q1-kIQRQ3+kIQR范围之外的数据点视为异常值,其中k是一个常数。通常,k的取值在 1.5 到 3 之间。

import numpy as np

# Generate a random dataset with outliers (100 normal points and 10 outliers)
np.random.seed(42)
data = np.concatenate((np.random.normal(loc=50, scale=10, size=100), 
                        np.random.normal(loc=110, scale=20, size=10)))

# Calculate Q1 and Q3
Q1 = np.percentile(data, 25)
Q3 = np.percentile(data, 75)

# Calculate IQR
IQR = Q3 - Q1

# Set lower and upper bounds for outliers
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR

# Identify outliers using IQR method
outliers = [value for value in data if value < lower_bound or value > upper_bound]

在同一数据集中,以图形化方式展示这三种异常值检测方法的区别非常有趣。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片。

你可以看到,在这种情况下,原始的 IQR 方法过于严格。

算法方法

最后,算法方法利用了机器学习算法的力量,克服了简单统计方法的局限性。

存在多种异常值检测模型,包括孤立森林局部异常因子一类支持向量机。这些模型提供了可靠的技术来辨别复杂多维数据集中的异常值。与传统统计方法不同,这些算法更擅长理解数据的复杂模式和定义更复杂的决策边界。

孤立森林

我介绍的第一个异常值检测算法是孤立森林,因为它可能是我在日常任务中使用最频繁的机器学习模型。

孤立森林依赖于更著名的随机森林的原理,以及整体上的集成学习技术。如果你不熟悉随机森林或集成学习,我建议你参考这个简单的指南。

## 使用 Scikit-Learn 的集成学习:友好的介绍

像 XGBoost 或随机森林这样的集成学习算法是 Kaggle 竞赛中的顶级表现模型之一…

[towardsdatascience.com

孤立森林的核心思想基于这样一种观察:异常值由于其稀有性,通常需要在树结构中较少的步骤就能被孤立。因此,孤立森林构建了一个决策树的集成,由于其稀疏特性,更快速地孤立异常值。通过测量这些树中数据点的平均路径长度,孤立森林有效地为每个数据点量化异常值分数。

实现 Python 中的 Isolation Forest 非常简单,这要归功于Scikit-Learn(sklearn)库。

from sklearn.ensemble import IsolationForest
import numpy as np

# Generate synthetic data with outliers
np.random.seed(42)
normal_data = np.random.normal(loc=50, scale=10, size=10000)
outliers = np.random.normal(loc=20, scale=5, size=1000)
data = np.concatenate((normal_data, outliers)).reshape(-1, 1)

np.random.shuffle(data)

# Apply Isolation Forest for outlier detection
clf = IsolationForest(contamination=0.1, random_state=42)
clf.fit(data)

# Predict outliers
outlier_preds = clf.predict(data)
outliers_indices = np.where(outlier_preds == -1) 

局部异常因子(LOF)

基于这样一个观点:异常点通常在特征空间中比其* k *最近邻更孤立,局部异常因子(LOF)评估每个数据点的局部邻域,计算其相对于邻居的密度。

异常值通常显示出显著低于其邻居的局部密度,这使得它们通过 LOF 算法被检测出来。

Scikit-Learn(sklearn)提供了一个方便的工具来用 Python 实现 LOF。

from sklearn.neighbors import LocalOutlierFactor
import numpy as np

# Generate synthetic data with outliers
np.random.seed(42)
normal_data = np.random.normal(loc=50, scale=10, size=10000)
outliers = np.random.normal(loc=20, scale=5, size=1000)
data = np.concatenate((normal_data, outliers)).reshape(-1, 1)

np.random.shuffle(data)

# Apply Local Outlier Factor (LOF) for outlier detection
clf = LocalOutlierFactor(n_neighbors=20, contamination=0.1)
outlier_preds = clf.fit_predict(data)

# Identify outlier indices
outliers_indices = np.where(outlier_preds == -1)

应用 LOF 算法时需要调整的参数包括用于密度估计的邻居数量以及污染系数。最后一个参数表示期望的异常值比例。

结论

我展示了三种不同的异常检测方法,每种方法都有优点和局限性

图形化方法,如散点图和箱线图,毫无疑问是最直观的方法,适用于初步的数据探索。然而,它可能在处理高维数据时遇到困难,并且缺乏数值精度,仅仅是一个定性工具。

图形化方法的这一缺点被统计方法的数值稳健性所弥补。像 Z-score 这样的统计方法提供了数据异常值的精确度量,并探索了更复杂的数据关系。统计方法的局限在于数据常常假设为正态分布,这导致在处理偏斜数据时遇到一些困难。

最后,机器学习算法如 Isolation Forest 是前沿方法,因为它们在理论上比图形化和统计方法更强大。它们在理解复杂的数据空间中表现出色,其中模式难以发现。这些优点伴随着参数调整的限制。

这个介绍是一个很好的起点,但它仅仅触及了异常检测领域的表面。对于那些有兴趣深入这个领域的人,我提供了一些有趣且富有洞察力的资源列表。

如果你喜欢这个故事,可以考虑关注我,以便了解我即将推出的项目和文章!

这是我过去的一些项目:

## 使用 NetworkX 进行社交网络分析:温和的介绍

了解像 Facebook 和 LinkedIn 这样的公司如何从网络中提取洞察

towardsdatascience.com ## 高级降维模型简明介绍

学习如何高效地应用先进的降维方法,并提升你的机器学习…

towardsdatascience.com ## 使用 Scikit-Learn 进行集成学习:友好的介绍

类似 XGBoost 或随机森林的集成学习算法是 Kaggle 竞赛中的顶尖模型之一…

towardsdatascience.com

参考文献

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值