admin管理员组

文章数量:1645534

原文:TowardsDataScience

协议:CC BY-NC-SA 4.0

从原始文本到模型预测,不到 30 行 Python 代码

原文:https://towardsdatascience/from-raw-text-to-model-prediction-in-under-30-lines-of-python-32133d853407

快速探索 NLP 管道的快速指南

照片由андрейсизов在 Unsplash

介绍

自然语言处理(NLP)是处理人类语言数据的机器学习的子领域。在能够用机器学习模型进行预测之前,处理人类文本通常涉及标准的预处理步骤,如数据清理和将文本转换为数字向量。

在这个故事中,我们将带您浏览一个示例,解释如何使用 ATOM 库快速处理大量文本文档,并将它们分类到预先确定的主题中。ATOM 是一个开源的 Python 包,旨在帮助数据科学家加快机器学习管道的探索。如果你想对图书馆有一个温和的介绍,请阅读这个故事。

加载数据集

我们开始获取文本文档并初始化 atom 实例。我们将要使用的数据是 20 个新闻组数据集,可以使用 sklearn 轻松下载。该数据集包含 20 个主题的大约 18000 篇新闻文章,为了加快计算速度,我们只使用了其中的 5 篇。目标是预测每篇文章的主题。

import numpy as np
from atom import ATOMClassifier
from sklearn.datasets import fetch_20newsgroups# Load the dataset (get only 5 topics)
X, y = fetch_20newsgroups(
    return_X_y=True,
    categories=[
        'alt.atheism',
        'sci.med',
        'comp.windows.x',
        'misc.forsale',
        'rec.autos',
    ],
)# atom expects a 2-dimensional array, so reshape to (n_articles, 1)
X = np.array(X).reshape(-1, 1)# Initialize atom
atom = ATOMClassifier(X, y, test_size=0.2, verbose=2)

atom 中的数据存储在熊猫数据帧中。注意,我们拥有的唯一特性(包含文章)被自动调用corpus。这很重要,因为 atom 的所有 NLP 方法只应用于数据集中具有特定名称的列。这种机制允许 atom 将包含文本语料库的数据集与其他非文本特征结合起来(我们不会在本文中使用)。使用dataset属性检查数据。

atom.dataset

文本清理

让我们看看第一篇文章。

atom.corpus[0]

注意它的混乱。文本数据很少干净。无论是从网站上搜集来的还是从纸质文档中推断出来的,通常都填充了与模型无关的信息,比如电子邮件地址、数字、html 标签等…我们可以使用 atom 的text clean方法从新闻文章中去除这种“噪音”。该方法对语料库应用以下变换:

  • 将 unicode 字符解码为 ascii 表示形式
  • 将所有字符转换为小写
  • 从文本中删除电子邮件地址
  • 从文本中删除 URL 链接
  • 从文本中删除 HTML 标签
  • 从文本中删除表情符号
  • 从文本中删除数字
  • 删除文本中的标点符号

atom.textclean()

使用drops属性来检查每篇文章删除了什么。

atom.drops

现在看看第一篇。

atom.corpus[0]

标记化

下一步是将文章转换成令牌序列。在这种情况下,单词。我们需要这样做有两个原因:能够使用像词干化或词汇化这样的算法,这些算法要求文档由标记组成,以便知道应该考虑哪些单独的单词;并且能够将文本映射成模型可以接受的数字。

atom.tokenize()

现在每篇文章都由一系列单词组成。

atom.corpus[0][:7]

***提示:*使用 atom 的plot _ word cloud方法对语料库中最常见的术语进行可视化处理。

atom.plot_wordcloud()

正常化

规范化是将单词列表转换为更统一的标准的过程。这有助于减少模型必须处理的不同信息量,从而提高效率。像变元化这样的规范化技术的目标是将一个单词的屈折形式和派生相关形式简化为一个共同的基本形式,例如 universal → universe 或 running → run。

我们可以通过删除所有停用词来进一步降低文章的复杂性。停用词是任何自然语言中最常见的词,例如英语中的“the”、“a”、“is”。使用 atom 的文本规格化 方法可以实现规格化和停用词移除。

atom.textnormalize(stopwords="english", lemmatize=True)

还是那句话,我们来看看第一篇文章的前 7 个字。请注意,“从”和“在”不再存在。

atom.corpus[0][:7]

N-grams

有时,单词本身的意思和与相邻单词组合在一起的意思不同。例如,当单词“york”直接跟在单词“new”后面时,它的意思与不跟在后面时完全不同。这两个词的组合被称为二元模型。使用plot_ngrams方法检查语料库中哪些两个单词的组合是最常见的。

atom.plot_ngrams(ngram=2)

Atom 的

atom.tokenize(bigram_freq=200)

二元模型频率为 200 意味着如果二元模型在语料库中至少出现那么多次,就认为它是二元模型。使用bigrams属性查看创建了哪些二元模型。

…向量化…

文本数据不能直接馈送给算法本身,因为它们中的大多数期望具有固定大小的数字特征向量,而不是具有可变长度的文本文档中的单词。矢量化是将一组文本文档转换成数字特征向量的一般过程。

在大型语料库中,一些单词可能非常常见,但携带的关于文档实际内容的有意义信息非常少。如果我们将计数直接输入到分类器中,那些非常频繁的词将会掩盖更罕见、但更有趣的词的频率。使用 TF-IDF 策略将计数特征重新加权为浮点值。创建的列以它们正在计数的单词命名。

atom.vectorize(strategy="tfidf")

由于在完整的语料库中有许多单词,并且每个单词都有自己的列,所以数据集的维度增加了很多。

atom.shape

为了处理这个庞大的数据集,矢量化方法默认返回稀疏数组的数据帧。

atom.dataset.dtypes

***信息:*您可以使用该方法的return_sparse参数来改变这种行为。请注意,当语料库包含许多单词时,使用 return_sparse=False 会使转换非常缓慢,并占用大量内存。

建模和结果

要为我们的数据选择正确的模型,我们需要检查哪些模型具有对稀疏数据帧的本地支持。

atom.available_models()

看看第 17 行的accepts_sparse栏。看起来随机森林(RF) 很适合我们的任务。

atom.run(models="RF", metric="f1_weighted")

就这样,我们训练了一个模型来对文本数据进行预测。使用以下工具快速评估各种指标的结果:

atom.evaluate()

该模型似乎总体得分较高。使用 atom 的绘图方法进一步分析结果。

atom.plot_confusion_matrix()

ATOM 还集成了 shap 库,可以根据 Shapley 值快速洞察图形。例如,在对第一篇文章进行预测时,查看哪些单词对算法的影响最大。

atom.decision_plot(index=0, target=atom.predict(0), show=10)

或者检查所有文章中哪些词对预测第一个主题最重要:无神论。

atom.beeswarm_plot(target=0, show=15)

结论

我们展示了如何使用 ATOM 包快速探索自然语言数据集。首先,我们将原始文本文档转换成向量,之后,我们训练并评估了一个分类器。以及不到 30 行代码中的所有内容!

关于 ATOM 的更多信息,请看一下软件包的文档。对于 bug 或功能需求,请不要犹豫,在 GitHub 上提出问题或给我发邮件。

相关故事:

  • https://towards data science . com/atom-a-python-package-for-fast-exploration-of-machine-learning-pipelines-653956 a16 e7b
  • https://towards data science . com/how-to-test-multiple-machine-learning-pipelines-with-just-the-less-lines-of-python-1 a16 CB 4686d
  • https://towards data science . com/from-raw-data-to-we B- app-deployment-with-atom-and-streamlit-d 8df 381 aa 19 f
  • https://towards data science . com/exploration-of-deep-learning-pipelines-made-easy-e1cf 649892 BC
  • https://towards data science . com/deep-feature-synthesis-vs-genetic-feature-generation-6 ba 4d 05 a6 ca 5

参考资料:

  • 20 个新闻组数据集是机器学习技术文本应用实验的一个流行数据集,最初由 Ken Lang 为他的news weaver:Learning to filter net news论文收集。
  • 这个故事中所有没有说明的图片都是作者创作的。

从原始视频到 GAN 培训

原文:https://towardsdatascience/from-raw-videos-to-gan-training-implementing-a-data-pipeline-and-a-lightweight-deep-learning-6274de917be9

在 AWS 上使用 ClearML 实现数据管道和轻量级深度学习数据湖

介绍

Hour One 是一家以人工智能为中心的初创公司,其主要产品是将文本转换成虚拟人类主持人的视频。

仅基于文本生成真实、流畅和引人注目的人类演讲者用多种语言说话和打手势的视频是一项具有挑战性的任务,这需要训练复杂的深度学习模型——以及大量的训练数据。

这篇文章描述了我使用 ClearML 和 AWS 为 Hour One 构建的数据管道和数据管理解决方案的设计和实现。

该解决方案基于轻量级版本的
Deep Lake 架构模式。

视频深度学习的数据管道和数据管理。作者图片

注意:我与 ClearML 项目或其支持者没有任何关系。

从视频到准备好的数据集

Hour One 的人工智能模型需要将文本作为输入,并生成逼真的视频作为输出。

实现这一点的一种方法是通过在真人展示各种文本的视频上训练模型。

该模型然后尝试预测视频中的下一帧或帧序列,同时最小化损失函数,这有助于确保输出是真实的和高质量的。

从数据准备和管理的角度来看,这需要:

将视频数据转换为有用的表示形式— 使训练人员能够专注于输入的正确“特征”。

例如,以一种用于频谱分析的格式表示音频,或者将视频像素编码成一种可以馈入模型的紧凑格式。

丰富提供详细监督的数据层— 天真地,被训练来预测图像的模型可以尝试最小化与地面真实图像的简单像素距离。
然而,这个损失函数可能不是考虑真实性、平滑性或一致性的最佳方式。

为了支持更详细的监督,在训练期间可以使用附加的注释或数据层。
例如,考虑一层关于视频中每一帧中人脸确切位置的信息(“注释”)。

这些层可以由人工注释器以编程方式生成,也可以两者都有。

清理数据以确保其适合训练— 例如,删除不包含对着摄像机说话的人的部分。
一些清洗逻辑需要在转换的甚至是丰富的数据上运行。

捕获元数据 —为了帮助构建多样化且平衡的数据集,我们需要将数据映射到多个领域维度,例如演讲者的性别、照明条件、语音质量等。

元数据可以描述整个视频、视频的片段或视频内非常短的序列,例如帧级别。

作为从源获取数据的一部分,可以提供描述整个视频的一些基本维度。

在其他情况下,需要计算元数据,例如通过附加的深度学习算法对数据进行推断。

长期存储数据+元数据— 所有形式的数据都需要长期存储,包括原始的、经过转换和丰富的以及精选的数据集。

使数据可搜索— 该解决方案需要允许研究人员通过搜索具有所需属性/维度/元数据组合的实例的数据来快速构建数据集,例如“获取 100 个训练实例,其中多达 40%应该具有闪烁的字符”。

构建和存储版本化的训练数据集— 一旦为数据集选择了实例,它就应该以版本化的方式存储,并在需要时被拉入训练机器。

光深湖的视频资料。作者图片

让我们深入了解解决方案每个部分的需求。

要求

管道

数据流水线子系统的目标是执行处理步骤的 DAG,并发出数据,这些数据随后将被存储在数据管理子系统中。

输入和触发

管道的输入是一个文件,其中包含指向原始视频的指针,以及一些关于其内容的元数据。

流水线通常在获取新数据后被触发,并且只处理新的数据增量。

有时,我们可能会选择从头开始对所有数据运行它,或者对输入数据的特定子集运行它。

加工

管道应该运行多个异构的数据处理步骤。一些步骤可以运行外部过程,一些可以运行模型的推断,一些可以执行图像或信号处理。

每个步骤的输出可以被过程中的下一个步骤、训练过程或两者使用。

扩展性和进化

一些低级处理阶段被认为是相对稳定的,不太可能经常改变。

管道的其他部分,如浓缩逻辑,将继续高速发展——我们需要允许研究人员在不依赖工程师的情况下在管道中增加浓缩阶段。

子 DAG 执行和回填

当管道逻辑发展时,新的逻辑需要在整个数据语料库上运行。在数据工程中,这通常被称为“回填”或“填充”。

在我们的案例中,由于数据的大小和处理的复杂性,在整个数据语料库上重新运行整个管道是一项昂贵且耗时的工作。

因此,流水线需要支持触发部分执行,即只运行用户指定的子 DAG

结果缓存

作为一个相关的要求,我们希望管道能够“缓存感知”——即跳过昂贵的处理阶段,以防自上次执行以来数据、代码和配置没有任何变化。

输出处理语义

当对旧数据运行管道时,我们可能会决定覆盖旧数据,或者将输出作为新版本的数据追加。

横向扩展 随着数据量的不断增长,我们需要一个能够在多台机器上运行的解决方案**。**

在这种模式下工作时,应该可以通过 UI 或调度程序调用管道。

本地运行 与此同时,能够在本地将管道作为完全标准的 Python 流程运行非常有用——从源代码、包或 Docker 容器内部运行,而不依赖于云基础设施,也不发布其输出,主要用于开发和本地测试。

CPU 和 GPU

流水线中的一些阶段执行适合 CPU 的视频裁剪或编码/解码等活动,一些阶段执行深度学习模型的推断(例如,检测演员面部周围的边界框),这些活动受益于 GPU 加速。

用户应该能够以声明的方式指定哪些任务应该在哪个处理单元上运行。

数据管理

数据管理子系统的目标是长期存储数据和元数据。此外,它应该:

  1. 使数据可搜索并可访问以构建数据集
  2. 以版本控制的方式支持新数据集的创建
  3. 允许用户下载数据集进行培训

存储

对于长期存储,我们需要一种可扩展的对象存储技术,如 S3。

媒体存储格式

我们希望以标准格式存储较大的媒体文件,包括原始文件和预处理文件,以便尽可能使用标准工具(例如. mp4、.哇哇,还有。png)

元数据存储和模式 遵循 Deep Lake 架构模式,元数据应该使用提供结构的格式存储,并且是可查询的。

同时,我们需要在模式管理中允许高度的灵活性,而不引入复杂或僵化的数据引擎。

数据版本化 媒体文件的底层和繁重的预处理逻辑不会经常改变,如果改变了,通常覆盖以前的版本是安全的。

另一方面,丰富逻辑往往会随着时间而变化,在数据足迹方面更轻(想想边界框和地标坐标),因此它们的输出应该被版本化。

训练数据集应该受版本控制。

ClearML 101

ClearML 是一个开源的 MLOps 项目,它结合了实验跟踪、数据集管理、远程代码执行和用 Python 编写的作业管道。

ClearML HL 架构。图片来自 ClearML github 项目https://raw . githubusercontent . com/allegro ai/clear ml-docs/main/docs/img/clear ml _ architecture . png

任务和实验跟踪

在高层次上,您可以用几行代码来检测 Python 程序,以将其连接到 ClearML。一个被检测的 Python 程序被称为一个 任务

任务执行时,例如在您的本地机器上,插装代码自动收集信息,例如命令行参数、git diff 和 latest commit、解释器可用的 Python 包列表,甚至 ML 工具的特定状态,例如 PyTorch 指标。

然后,被跟踪的元数据被发送到 ClearML 服务器并存储在那里,可以通过 UI 和 API 访问。

您还可以在任务执行期间从代码中显式报告数据。这对于例如在训练过程中跟踪指标是有用的。

远程执行

当 ClearML 跟踪一个任务时,服务器会存储复制它所需的所有信息——包括在远程机器上运行它。

为了在远程机器上执行一个任务,您“克隆”它(通过 UI 或 API 调用),并把它放在一个队列中。

运行在远程机器上的一个 阿根 t 轮询新任务的队列,一旦它将一个任务出队,它就将其作为一个(本地)Python 进程来执行。运行代理的远程机器称为工作器

管道

任务的 DAG 被称为 流水线。 流水线的流程由一个 控制器 任务——另一个触发任务执行的 Python 函数,在它们之间传递参数和信息。

控制器通常会执行任务,将它们发送到 队列 ,在那里它们将被 工作器 拾取。**

数据集

一个 数据集 是一种特殊的任务,其中用户报告“数据”而不是像正常实验中那样报告度量。

数据可以是任何东西,但通常是存储在某个文件系统上的文件,如挂载的磁盘、NFS 或对象存储。

数据集可以用与 Git 类似的方式进行版本化,每次提交版本时,它只存储与以前版本的差异。

关于数据集的元数据存储在 ClearML 服务器中,而实际数据(例如数据集中包含的文件)可以存储在您选择的存储设备中,例如 S3 或 NFS 服务器,只要它可供需要下载和使用它的工作者机器使用。

为什么是 ClearML

功能适用性

ClearML 支持所有主要的功能需求:

  • 在 Python 中定义和运行媒体处理管道
  • 在 CPU 和 GPU 上以远程/分布式执行方式运行管道。
  • 长期存储大量二进制或半结构化文件,并将其管理和保存到数据集中。
  • 允许下游处理步骤和训练过程容易地使用数据集。

ClearML 可以执行所有这些任务。

然而,如果你一直在关注,你会注意到 ClearML 并没有提供一种可以在数据集内存储的数据上运行的查询语言,而这是我们需求的一部分。

然而,正如我们将看到的,我们有一个解决这个限制的方案,成功地完成了工作。

赞成的意见

虽然有许多工具可以实现这一功能,但 Hour One AI 团队已经采用 ClearML 进行实验跟踪。

与此同时,该团队在运行关系数据仓库或云基础设施方面的经验要少得多,因此该工具的 Pythonic 式和熟悉的界面对其有利。

作为一个更普遍的优势,该工具是开源的,并且有一个活跃的社区。

最后,我们知道 ClearML 非常灵活,一旦你掌握了任务和远程执行机制,你就可以构建非常复杂的工作流——所以我们知道我们可以让它工作。

骗局

该工具的自动特性是有代价的——当事情不按预期运行时,需要时间来理解发生了什么。

调试没有按预期执行的 ClearML 代码需要打开工具的代码,通过它进行调试,在 slack 上提出问题,并且通常具有分布式计算、云 API、Python 依赖管理、docker 内部机制等方面的工作知识。

退一步说,文档可能是不完整的。

最后,灵活性也是一个缺点——因为 ClearML 不是一个固执己见的工具。这意味着你通常可以让它做你想做的事情,但你需要知道你在做什么才能让你的工作流有意义。

系统设计

高水平(位)

  • 该工作流被实现为一个 ClearML 管道 (具体来说——使用 PipelineDecorator )。
  • 流水线中的每个 任务 以一个 数据集 ID 为输入,生成一个或多个 数据集 作为输出。
  • 关于生成数据的元数据(包括世系)长期存储在 数据集中。 数据本身以多种不同的格式驻留在 S3 上。
  • 使用 ClearML 队列自动缩放器 来缩放流水线
  • 大多数其他需求(缓存、子 DAG 执行、使用相同的代码库在本地和远程运行)都是通过仔细分离关注点以及使用低级 ClearML API 来实现的。

逻辑流程

按照图表从左到右:

  • 管道由一个参数触发,该参数将管道指向一个包含原始视频链接的文件。
    文件被添加到代表“所有原始数据”的数据集中。
  • 第一个任务是根据文件中存在的元数据将原始视频分割成更短的部分(“片段”)。
    结果是分割的视频和元数据文件,每个都存储为 ClearML 数据集。
  • 下一步是对来自分离视频的视频和音频数据的基本预处理。
    每个都存储到 ClearML 数据集中。
  • 进一步丰富和净化音频和视频信号——另外约 10 项任务。

管道逻辑流和输出数据集。作者图片

数据管理

  • 每个任务的每次运行都会生成一个或多个独立的 ClearML 数据集
  • 每个数据集对象包含一个指向任务的指针,任务为沿袭创建了数据集对象(反之亦然)。
    这使我们能够提取特定管道运行产生的所有不同数据集。
  • 每个数据集包含其包含的视频片段的索引。
  • 大型媒体文件以它们的标准格式存储在 S3 上,ClearML 数据集使用外部文件机制保存它们在 S3 上的位置的引用。
  • 较小的文件被克隆并以 ClearML 格式存储(也在 S3 上)。

元数据模式和查询处理

正如上面所讨论的,我们希望允许研究人员在不需要了解关系数据库和其他外部工具的情况下轻松地发展模式。

此外,管道计算的许多元数据是半结构化的,例如,视频中每一帧的边界框或面部标志。

数据的结构使得通过关系查询引擎进行查询有点困难。

我们决定避免向解决方案中添加另一个移动部分,并保持它纯粹基于 ClearML。下面是我们实现查询的方法:

  1. 研究者获得他们想要查询的数据集 id 的列表。典型地,这些将包括元数据或注释(不是媒体)。
  2. 使用 ClearML 工具,用户下载这些数据集并将其合并到本地数据集副本中。
    例如——获取代表人脸边界框和界标的数据集。
  3. 研究人员使用 numpy 或 Pandas code 等标准工具执行“查询”,以便选择她想要训练的数据。
    例如,迭代表示面部边界框的 Numpy 数组,并且仅过滤掉边界框的总面积大于 X 并且所有界标都落在边界框内的元素。
    该“查询”结果中的每个元素将包含一个指针,该指针指向它所源自的帧和视频。
  4. 研究人员以编程方式创建一个新的数据集,其中包含 ClearML 中经过过滤的视频。
  5. 稍后,训练代码将数据集从(4)下载到本地磁盘,并开始训练。

使用 ClearML 数据集的查询流。作者图片

实际上,构建数据集的过程涉及满足数据集结构约束的线性规划。

基于远程和集群的执行

该过程工作如下:

  1. 用户触发管道执行——通过在她的机器上运行管道或者通过 UI
  2. ClearML 服务器接收呼叫
  3. ClearML 服务器将代表流水线逻辑( 【控制器】 )的任务的执行排入 队列
  4. 运行在某台机器上的一个 代理 拉这个任务
  5. 代理 开始执行管道方法代码。
  6. 控制器 为流水线中的每一步产生 ClearML 任务 ,并将它们放入 队列
  7. 额外的工人机器拉出这些 任务 并在本地启动它们
  8. 每个任务逻辑调用 ClearML 数据集 API 来创建它的输出 数据集 ,其中元数据存储在 ClearML 服务器上,实际数据存储在 S3 上。

带有远程任务执行的 ClearML 管道。作者图片

自动缩放

让数十台机器持续运行以等待任务排队是没有意义的。

ClearML 提供了一个自动缩放器,能够根据队列的状态上下旋转机器。

自动缩放流程非常复杂:

  1. “自动缩放逻辑”实际上是一个 ClearML 任务,它被放在一个专用队列中(例如“DevOps”队列)。
  2. 一台专用的机器(总是运行的)运行一个代理来监听这个队列。
  3. 代理选择自动缩放任务,该任务基本上永远运行
  4. 任务逻辑包括轮询队列和使用配置,为每个队列启动各种类型的机器
  5. 使用云提供商 API(例如 AWS 上的 Boto3)来启动机器。
  6. 衍生的机器有一个用户数据启动脚本,该脚本用凭证设置它们,并以守护模式启动 ClearML 代理
  7. 启动脚本完成后,代理将监听队列

小字:

  • 秘密管理由你负责。ClearML 希望您输入 AWS 凭证和 git。ssh 凭证保存到一个配置文件中,并将其保存在 ClearML 服务器中——从基本的安全实践来看,这是行不通的。
  • 代理需要访问 S3,因此新机器需要能够承担具有适当权限的角色。
  • 用户数据脚本是以非常间接的方式生成的——从配置到自动缩放代码到 AWS API 调用等等。任何错误都很难修复/测试。

我们必须找到替代解决方案,例如,使用适当的实例配置文件,并将机密存储在机密管理解决方案中。

支持 GPU 和 CPU 任务

这是通过两个队列实现的,一个用于 CPU 任务,一个用于 GPU 任务。

每个任务(Python 函数)都用它应该被发送到的队列的名称进行了注释。

代码级设计笔记

管道代码库非常简单。以下是我们构建管道的伪示例。

第 7–8 行— 主控制器逻辑有一个pipeline decorator . pipeline()decorator**。此外,它的参数(通常解析自命令行参数)应该可以使用 json 或 pickle 进行序列化。

第 9 行 —任何导入都应该在函数内部执行(远程运行时需要)。

**第 13 行 —我们使用一个工厂来创建一个“追踪器”对象。**追踪器是大部分魔法发生的地方。它有两个实现——一个本地跟踪器(或多或少是无操作的),和一个 ClearML 跟踪器(实际上针对 ClearML 执行调用)。

基于命令行标志实例化正确的类。

第 15–19 行 —该流程通过在方法(任务)之间传递数据集 id 来实现。

当这些代码以远程模式在 ClearML 上运行时,这些调用触发远程任务的创建,并将它们所依赖的先前任务的结果发送给它们。

现在让我们来分析一下任务:

第 1 行 —该任务是一个带有 ClearML 装饰器的纯 Python 函数。

第 3–5 行 —该函数执行导入,如果我们希望能够远程运行它,就需要执行导入,然后它初始化自己的跟踪器实例。

第 7–9 行-跟踪器对象负责获取缓存的结果(如果存在),或者,如果不存在,则将输入数据集下载到本地文件夹。

第 14–15 行 —使用跟踪器,我们将第 11–12 行生成的数据上传到名为“split_videos_media”的 ClearML 数据集。

本地运行

要打开本地运行,我们需要在管道方法之前调用pipeline decorator . run _ locally()

还支持其他一些运行模式,比如:在本地运行管道任务,将任务作为本地进程或远程任务运行。

仅在子 Dag 上运行

这也由 tracker 对象处理,它能够遍历 DAG 并自动跳过所有不需要的任务。

血统追踪

tracker 对象用管道运行 ID 标记所有任务,并用它创建的数据集列表标记每个任务——这些数据集作为工件存储在 ClearML 中。

附加功能

跟踪器负责所有的命名、数据收集和报告约定,以便任务作者可以专注于他们的业务逻辑。它还能够将外部任务作为监听器附加到管道执行中,按计划运行等等。

摘要

为训练深度学习模型准备大规模媒体数据需要对原始数据运行多个处理和浓缩步骤。

它还要求以一种结构良好的方式存储处理过的数据,这种方式支持版本控制,并使研究人员能够查询数据以构建数据集。

ClearML 可以用来实现以上所有功能。

它的亮点在于其纯粹的 Pythonic 接口、直观的数据集范式以及对许多非功能性需求的支持,如自动伸缩,尽管这些都是有代价的。

虽然 ClearML 没有提供数据查询机制,但它仍然可以组织数据,以便拉动数据并在本地执行查询可以完成工作,特别是如果查询发生在数据生命周期中定义明确的点上。

从散点图到故事:谷歌数据工作室版

原文:https://towardsdatascience/from-scatter-plot-to-story-google-data-studio-edition-ff1bd1ac3d96

通过在 Google Data Studio 中增强您的散点图来讲述完整的故事

TLDR:本文之前的另外三篇配套文章都展示了如何用 Python 或 Stata 代码以编程方式生成散点图。如果你对编写计算机代码不感兴趣,但是你对通过一个简单的散点图讲述一个完整的故事感兴趣,这篇文章适合你。

概观

出于对一个简单想法的极大热情,这篇文章至少有三个其他版本。文章的每个版本都展示了将一个简单的散点图转换成完整故事的过程。每篇文章都关注不同的工具。有一款 Seaborn 版。有一个 MatplotLib 版。而且还有一款 Stata 版。

现在我介绍谷歌数据工作室版。正如我先前解释的那样:

散点图是许多分析师和数据专家的重要工具。它们说明了两个(或更多)变量之间的关系。它们很快就会生成。它们很容易解释。

如果你还不知道,Google Data Studio 是一个简单、强大、免费的数据可视化工具。你可以在datastudio.google了解更多。谷歌关于这个工具的信息说:

你的数据很漂亮。使用它。
利用交互式仪表盘和漂亮的报告激发更明智的业务决策,释放数据的力量。既轻松又免费。

要理解这篇文章背后的故事,首先要了解一些背景知识。

背景

这个项目的假设目标是审查一个车辆列表,并决定哪一辆车将是为扩大公司车队而购买的最佳车辆。有一个假设的指导方针,确定最低车辆效率为每加仑 16 英里。还有另一个假设的指导方针,确定 29 英里每加仑为最佳车辆效率。耐久性和“韧性”也是车辆选择的一个重点。

由古斯塔沃在 Unsplash 上拍摄的照片

要访问该项目的数据,您需要在 python 中运行以下代码行。运行下面几行代码后,您将拥有 csv 文件中的汽车数据集。

import pandas as pddataurl = 'http://www.stata-press/data/r15/auto.dta'df = pd.read_stata(dataurl)df.to_csv('auto.csv', index=False)

下面是数据的前五个观察结果如何出现在大多数 csv 文件阅读器中。

图片鸣谢:作者截屏 auto.csv。

Google Data Studio 入门

图片来源:作者对 datastudio.google 的截屏。

如果你还没有使用谷歌数据工作室,在 datastudio.google 很容易上手。当您到达并登录后,您将看到以下屏幕和选项。

图片来源:作者登录后 datastudio.google 的截屏。显示创建新的“空白报告”、“教程报告”或“acme 营销”报告的选项。

要继续本指南,请选择“空白报告”选项。选择“空白报告”选项后,您将看到另一个类似于下图的屏幕。

图片来源:作者选择“空白报告”后 datastudio.google 的截屏显示了连接多个数据源的选项,包括“文件上传”选项。

要继续本指南,请选择“文件上传”选项。点击“文件上传”选项后,你会看到一个类似于下图的屏幕。

图片来源:作者选择“文件上传”后 datastudio.google 的截屏显示上传数据源的选项。

上传文件后,你会看到另一个类似如下的屏幕。还需要单击屏幕右下角的“添加”按钮。单击“添加”按钮会将数据添加到您的报告中。

图片来源:作者上传 CSV 文件并选择“添加”数据到您的报告后的 datastudio.google 截屏。在继续之前,请务必单击“添加”按钮。

将自动数据添加到报告后,下一步是添加图表。下图显示了添加散点图(或散点图)后报告的外观。要添加此图表,请使用报表顶部菜单/功能区中的“添加图表”按钮。

图片来源:作者在上传 CSV 后以及更改 y 轴和 x 轴以显示车辆效率(mpg)和重量之间的关系后对 datastudio.google 的截屏。

要确保 mpg 数据沿垂直 y 轴运行,重量沿水平 x 轴运行,请使用报告右侧的设置选项卡(在红色圆角框内)。

这个过程的下一步将是调整图表的范围。要调整图表的范围,请切换到样式选项卡。如下所示,在红色圆角框中进行编辑。

图片来源:作者在上传 CSV 文件、更改 y 轴和 x 轴变量以及调整 y 轴(10 到 42.5mpg)和 x 轴(1500 到 5,000 lbs)的范围后拍摄的 datastudio.google 的屏幕截图。

具体来说,上面显示的是散点图的一个版本,控件上有三个红色圆角框。第一个红色框突出显示“样式”选项卡。“样式”选项卡将提供编辑轴范围的权限。如第二个红框所示,我已经将 y 轴的最小值更改为 10 mpg,将 x 轴的最大值更改为 1,500 lbs。

添加参考线和注释

到目前为止,上述数据可视化提供了关于车辆列表的大量信息。我们知道最小和最大效率以及最小和最大车辆重量。我们还看到,随着重量的增加,效率下降。

这是大量的信息!然而,为了讲述一个完整的故事,这张图表有一点不足。有太多未回答的问题。这个练习的目标是制作一个视觉效果,观众可以看到并快速理解一个完整的故事。

为了完成这个故事,我们可以添加参考线和注释。第一步将是在最低和最佳效率水平添加参考线。下图显示了(在红色圆角框内)如何在 Google Data Studio 中向图表添加参考线。

图片来源:作者在上传 CSV 文件、更改 y 轴和 x 轴变量以及调整 y 轴和 x 轴的范围后拍摄的 datastudio.google 的屏幕截图。这张图片上的红框显示你可以在谷歌数据工作室的图表上添加参考线。

在 Google Data Studio 的“style”选项卡中,有一些选项可以让你调整图表,包括添加参考线的选项。在添加参考线的选项中,还有向参考线添加注释或“标签”的选项。这些选项还允许更改参考线的颜色。

注释特定的数据点

最后一步是注释特定的数据点。要注释的特定数据点是最能满足所需车队车辆要求的车辆。在这种情况下,它将是丰田花冠,每加仑效率为 31 英里,重量为 2,200 磅。

为了添加最终的注释,Google Data Studio 提供了添加文本块、线条、箭头和其他形状的机会。下图显示了(在圆角红色框中)文本块、线条、箭头和形状控件。

图片来源:作者截屏 datastudio.google,散点图显示了车辆效率和车辆重量之间的关系。红色方框显示了 Google Data Studio 的文本块、线条、箭头和形状工具。

通过添加带有“丰田卡罗拉(31 Mpg 2,200 lbs)租金昂贵,最佳里程”字样的文本块,为最符合车队车辆选择标准的车辆创建注释。

感谢阅读

你准备好了解更多关于数据科学职业的信息了吗?我进行一对一的职业辅导,并有一份每周电子邮件列表,帮助专业求职者获取数据。联系我了解更多信息。

感谢阅读。把你的想法和主意发给我。你可以写信只是为了说声嗨。如果你真的需要告诉我是怎么错的,我期待着尽快和你聊天。推特:@ adamrossnelsonLinkedIn:亚当罗斯尼尔森。

从散点图到故事:Seaborn 版

原文:https://towardsdatascience/from-scatter-plot-to-story-the-seaborn-edition-fb15f3c4cd72

通过增强散点图讲述完整的故事

概观

就绘图而言,散点图是最受欢迎的。它们迅速揭示了两个(或更多)变量之间的关系。如果做得好,散点图可以很快传达给观众一个完整的故事。你的目标是让你的听众对自己说…

我们知道现在该做什么…

理想情况下,你的散点图将在瞬间激发上述意识。这篇文章将展示如何将你的可视化从一个简单的散点图变成一个完整的故事。这是 Seaborn 版。后续文章将在基础 Matplotlib 和 Stata 中展示相同的内容。

背景

你的工作是帮助决定你的公司应该购买什么样的车辆,因为它希望扩大其企业车队。还有,现在是 1978 年。我们假设现在是 1978 年,因为我们有这一年的数据。

我以前写过这些数据。

这些数据告诉我们大约 74 辆车。我们知道每辆车的品牌、价格、效率(mpg)和其他因素。

我们公司规定最低效率要求是每加仑 16 英里,但我们的最佳效率标准是每加仑 29 英里。分析任务是在最佳效率标准之上找到最具成本效益的车辆,同时也是最重的(将是最重型的)。

入门指南

最容易查看的图是简单的散点图。在 Seaborn 的帮助下,看起来像这样:

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as snsdf = pd.read_stata('[http://www.stata-press/data/r15/auto2.dta'](http://www.stata-press/data/r15/auto2.dta'))plt.figure()
ax = sns.scatterplot(data=df, 
                     x="weight", y="mpg", 
                     color = '#060b3f')
plt.show()

对于下面的结果(这不是很有帮助,也不是有益的,也不是艺术):

作者的再现。使用此处指定的数据和代码。

尺寸、比例、大小和标签

美化这种视觉效果的一些首要任务是:

  • 更改尺寸(更加水平,以适合我们的目标 8.5 x 11 英寸页面报告。
  • 指定将减少混乱的刻度和刻度线。
  • 添加精细的网格线,帮助读者将各个数据点与它们在 y 轴上的位置联系起来。
  • 并更新轴标签以提供更好的信息。
plt.figure(figsize = (15,6))
ax = sns.scatterplot(data=df, 
                     x="weight", 
                     y="mpg", 
                     color = '#060b3f')
ax.set(xlabel='Weight (lbs).', ylabel='Mileage (mpg).')
ax.yaxis.grid(True, color = '#CCCCFF')
plt.xticks(np.arange(2000, 6000, 1000))
plt.yticks(np.arange(10, 45, 10))
plt.show()

对于以下结果:

作者的再现。使用此处指定的数据和代码。

设置上下文(可选)

Seaborn 的一个特性是能够设置你的上下文。粗略地说,上下文指定了你想要显示视觉效果的地方。例如,你可以将你的视觉效果放在一张纸上、一个笔记本上、一次会议上或者一张海报上。

虽然许多人认为这一步是可选的,但我经常支持为海报设置背景。我发现它在任何背景下都是最具可读性的。seaborn.set_context(context='poster')为我们做工作。

plt.figure(figsize = (15,6))
sns.set_context(context='poster')
ax = sns.scatterplot(data=df, 
                     x="weight", 
                     y="mpg", 
                     color = '#060b3f')
ax.yaxis.grid(True, color = '#CCCCFF')
ax.set(xlabel='Weight (lbs).', ylabel='Mileage (mpg).')
plt.xticks(np.arange(2000, 6000, 1000))
plt.yticks(np.arange(10, 45, 10))
plt.show()

对于结果(更大的字体、更大的数据点、更粗的线条等。):

作者的再现。使用此处指定的数据和代码。

添加参考线

这里是商店展示自己的地方。为了勾勒出我们故事的轮廓,我们可以在图形上添加一些额外的信息。我们可以添加与我们公司的效率标准相关的信息。

这里sns.lineplot()让我们添加水平参考线。而ax.text()让我们注释那些参考线。

plt.figure(figsize = (15,6))
sns.lineplot(data=df, x="weight", 
             y=[29]*len(df), color = 'green')
ax = sns.scatterplot(data=df, 
                     x="weight", 
                     y="mpg", 
                     color = '#060b3f')
sns.lineplot(data=df, x="weight", 
             y=[16]*len(df), color = 'red')
ax.text(3200, 30, 
        'Green line indicates optimal efficiency Standards.', 
        color = 'green')
ax.text(1800, 15, 
        'Red line indicates minimum efficiency requirements.', 
        color = 'red')
ax.set(xlabel='Weight (lbs).', 
       ylabel='Mileage (mpg).')
ax.yaxis.grid(True, 
              color = '#CCCCFF')
plt.xticks(np.arange(2000, 6000, 1000))
plt.yticks(np.arange(10, 45, 10))
plt.show()

对于几乎最终的结果:

作者的再现。使用此处指定的数据和代码。

最后,注释特定的数据点

最后的亮点是注释一个特定的数据点。这里的版本表明,丰田卡罗拉(每加仑 31 英里,2200 磅)是我们下一轮车队采购的最佳车辆。

为了注释一个特定的数据点,这段代码使用了ax.plot(),它指定了一个特殊标记的具体位置(坐标)以及其他标记属性。

这个最终版本还使用plt.suptitle()plt.title()添加了标题和副标题。

最终版本是否完美?不。话说回来,没有一幅画是完美的。然而,这个最终版本展示了如何,通过一些深思熟虑的更新,你可以从散点图到故事。

在锡伯恩:

plt.figure(figsize = (15,6))
sns.lineplot(data=df, x="weight", 
             y=[29]*len(df), color='green')
ax = sns.scatterplot(data=df, 
                     x="weight", 
                     y="mpg", 
                     color='#060b3f')
sns.lineplot(data=df, x="weight", 
             y=[16]*len(df), color='red')
ax.text(3600, 30, 
        'Green line indicates optimal efficiency Standards.', 
        color='green')
ax.text(1800, 15, 
        'Red line indicates minimum efficiency requirements.', 
        color='red')
ax.text(2250, 32.2, 
        'Toyota Corolla (31mpg 2,200lbs)',
        color = 'green', size = '14')
ax.text(2250, 30.8,
        'Least expensive above optimal', 
        color = 'green', size = '14')
ax.set(xlabel='Weight (lbs).', 
       ylabel='Mileage (mpg).')
ax.plot(2200, 31, 
        'g', marker='$\\bigoplus$', markersize=15)
ax.yaxis.grid(True, color = '#CCCCFF')
plt.suptitle("The 'Best Value' For Fleet Purchases", 
             fontsize=20)
plt.title("A Preliminary Analysis",
          fontsize=15)
plt.xticks(np.arange(2000, 6000, 1000))
plt.yticks(np.arange(10, 45, 10))
plt.show()

为了最终的结果(如果你愿意,故事):

作者的再现。使用此处指定的数据和代码。

https://adamrossnelson.medium/membership

感谢阅读

你准备好了解更多关于数据科学职业的信息了吗?我进行一对一的职业辅导,并有一份每周电子邮件列表,帮助专业求职者获取数据。联系我了解更多信息。

感谢阅读。把你的想法和主意发给我。你可以写信只是为了说声嗨。如果你真的需要告诉我是怎么错的,我期待着尽快和你聊天。推特:@ adamrossnelsonLinkedIn:亚当罗斯尼尔森。

从沙普利到 Shapley 理解数学

原文:https://towardsdatascience/from-shapley-to-shap-understanding-the-math-e7155414213b

如何计算 SHAP 要素贡献的概述

克拉拉·库利科娃在 Unsplash 上的照片

假设你(玩家 1)和一个朋友(玩家 2)参加了一场猜拳比赛。你最终赢得了一等奖,10,000 美元。现在,你想公平地分配这笔钱。你的朋友建议你平分它。但是,你的超参数调优技术更胜一筹。你认为你应该得到更大的份额,因为你对团队的贡献更大。考虑到这一点,你怎么能公平地分配这笔钱呢?

很方便,你的朋友有一台时光机。你们各自回到过去,独自重新进行卡格尔竞赛。你最终获得第二名,并赢得 $7,500 。你的朋友仅获得第三名,赚了 $5,000 。如果你们都不玩,就不会赢得任何奖金( $0 )。我们将这 4 个玩家联盟的价值记录如下。很明显,你应该得到更多的奖金,但是如何分配还不清楚。

联盟价值观(来源:作者)

一种方法是通过计算每个玩家的预期边际贡献。这是玩家对其可以加入的所有联盟贡献的加权平均值。

例如,参与人 1 (P1)可以加入只有参与人 2 (P2)的联盟。P2 从第三名升至第一名,奖金增加了 $5000 。P1 也可以加入一个没有玩家的联盟,增加 7500 美元的奖金。这些是 P1 的边际贡献。这些因素的平均值为我们提供了预期边际贡献 $6,250

参与人 1 的预期边际贡献(来源:作者)

我们可以按照类似的过程来计算 P2 的预期边际贡献。这次的价值是 3750 美元。最终,P1 将获得 6250 美元,P2 将获得 3750 美元。这两个值也被称为沙普利值。请注意,这些值加起来的总奖金为 10,000 美元。

参与人 2 的预期边际贡献(来源:作者)

沙普利价值观被认为是一种公平的奖金分配方式。这是一个来自博弈论的概念。我们只计算了两个人的团队。我们能够使用它们来计算任何规模的团队的公平分配。我们将花时间来理解这个的广义沙普利值公式。这个公式可能看起来很可怕。然而,当我们得到引擎盖下你会看到它有一个直观的解释。

沙普利值=预期边际贡献

这是玩家对其可以加入的所有联盟贡献的加权平均值。

从划分奖金到解释机器学习模型,这似乎是一个很大的飞跃。然而,Shapley 值可以用来理解每个模型特征(玩家)如何对预测(奖金)做出贡献。我们将解释 Shapley 值如何扩展到解释模型预测。我们将以探索对这一领域研究的贡献来结束。也就是说,它们极大地提高了我们逼近 Shapley 值的速度。****

3 人游戏的 Shapley 值

在我们继续之前,让我们再看一个例子。这将使一般方程更容易理解。这次我们有一个由三名球员组成的队伍。计算很复杂,我们还得再回溯几次。

现在将有 8 个可能的联盟,如下所示。你们一起赢得一等奖( 10 , 000 ∗ ∗ ) 。现在有 3 个 2 人联盟。例如, P 1 和 P 3 的联盟将获得第二名 ( ∗ ∗ 10,000** )。现在有 3 个 2 人联盟。例如,P1 和 P3 的联盟将获得第二名(** 10000)。现在有32人联盟。例如,P1P3的联盟将获得第二名( 7500)。也会有一个玩家的联盟。例如,如果 P3 独自比赛,他们将不会获得任何奖金( $0 )。也许他们应该投资一个更好的 GPU。

联盟价值观(来源:作者)

我们可以用这些联盟值来计算 P1 的沙普利值。现在 P1 可以加入 4 个联盟。P1 可以加入 P2 和 P3 的联合政府,或者只有 P2 或 P3 的联合政府,或者没有成员的联合政府。像以前一样,我们计算 P1 对每个联盟的边际贡献。最后,我们取加权平均值。这给了我们一个沙普利值$ 5000**。**

参与人 1 的预期边际贡献(来源:作者)

你可能会问,我们从哪里得到这些重量?这就是为什么我们把第一个边际贡献的权重定为 1/3,第二个边际贡献的权重定为 1/6,以此类推……这些就是 P1 做出这些特定贡献的概率。通过概率加权给我们一个 预期 边际贡献。

这些概率从何而来并不明显。首先,我们需要找出三个人组成联盟的方法。这是因为只有所有 3 名成员齐心协力才能赢得全部奖金(10,000 美元)。

为了做到这一点,我们假设每个成员都有平等的机会依次加入团队。例如,P1 加入,然后 P3,然后 P2。这样我们总共有 3 个!=形成联盟的 6 种方式。你可以在下面看到所有这些。一般来说,有 n 个!组建 n 人团队的方法。

形成 3 人联盟的 6 种方式(来源:作者)

上面我们看到,如果 P1 加入 P2 和 P3 的联盟,他们将贡献 5000 美元的边际贡献。这可能以两种方式发生。要么 P2 加入,然后是 P3,然后是 P1,要么 P3 加入,然后是 P2,然后是 P1。换句话说,P1 将为团队组建的 6 种方式中的 2 种做出边际贡献。这给了我们 2/6 = 1/3 的概率,P1 做出了这一贡献。

只有一种方法可以让 P1 做出第二笔捐款(【2,500 美元】)。也就是说,如果 P2 加入,然后是 P1,然后是 P3。这给了我们 1/6 的概率。同样,第三次贡献($ 7500**)的概率是 1/6。第四次贡献( $5000 )有 1/3 的概率。就像第一次捐款一样,P1 有两种方式。先是 P1 加入,然后是 P2,然后是 P3,或者是 P3,然后是 P2。**

我们可以对 P2 和 P3 采取同样的做法。对于这些玩家,Shapley 值分别为 $3,750$1,250 。同样,所有 Shapley 值加起来就是总奖金。Shapley values 将始终公平地分配所有奖金。现在让我们看看如何推广 Shapley 值。

广义 Shapley 值

等式 1 给出了 p 玩家游戏中玩家 i 的 Shapley 值的公式。从求和符号开始,我们对所有联盟 S 求和。其中 S 是不包括参与人 I 的联盟的子集。换句话说,S 包含参与人 I 能够做出边际贡献的所有联盟。回到三人组的例子,有 4 个联盟不包括 P1。

等式 1:p 玩家游戏中玩家 I 的 shapley 值(来源:作者)

在方括号中,我们有参与人 I 对联盟 S 的边际贡献。具体来说,我们有联盟 S 的价值(val ),包括参与人 I 减去联盟 S 的价值。价值函数取决于正在进行的特定游戏。在我们三个玩家的例子中,我们使用了不同的符号。我们谈到了联盟的价值观,并使用了字母 C 和玩家下标。这些联盟值给出了 Kaggle 游戏的价值函数。

最后,我们对边际贡献进行加权。下面,你可以看到重量的每个组成部分代表什么。这里 |S| 是联盟 S 中玩家的数量,这意味着 p-|S|-1 是在玩家 I 之后需要加入联盟的玩家数量

在权重分子中,我们有联盟可以形成的方式的数量。分母是整个团队可以形成的方式的数量。因此,当博弈中有 p 个参与者时,权重给出了参与者 I 对规模为|S|的联盟做出贡献的概率。如果你代入我们 3 人游戏的值,你会得到和以前一样的权重。

把 Shapley 值分解一下,可以看到它有一个直观的解释。我们用参与人 I 做出贡献的概率来衡量他们的边际贡献。然后我们将参与人 I 可以加入的所有联盟的加权贡献相加。这给了我们一个预期边际贡献**。使用这些值,我们可以在所有玩家之间分配游戏的总价值。**

凭直觉,看起来预期边际贡献是一种公平的方式。我们考虑对所有联盟的贡献。这意味着我们考虑了玩家的个人贡献和玩家之间的互动。也就是说,一些玩家可以很好地合作,增加他们的共同价值。问题是可能有其他看起来公平的价值分配方式。我们需要证明 Shapley 值是公平的。

匀称的公理

Shapley 值实际上来源于 3 个公理。我们只对它们进行总结,但它们也可以用数学来定义。这些公理可以被认为是公平的定义。因此,满足这一定义的价值分割方法可以被认为是公平的。

如果两个玩家对所有联盟做出相同的贡献,他们就被认为是可以互换的。如果两个玩家可以互换,那么他们必须得到游戏总价值的同等份额。

****无效玩家财产如果一个玩家对所有联盟的边际贡献为零,那么他们将一无所获。

****可加性如果我们合并两个游戏,那么一个玩家的总贡献是两个单独游戏贡献的总和。这个公理假设任何游戏都是独立的。

我们可以从数学上证明 Shapley 值是满足这 3 个公理的唯一有效值。所谓高效,我们的意思是游戏的价值没有剩余。最终,在这个定义下,沙普利值是唯一公平的价值分配方式。令人惊讶的是,这样一个直观的公式可以从 3 个简单的公理推导出来。

机器学习的 Shapley 值

我们可以使用 Shapley 值来理解模型是如何做出预测的。现在,游戏的价值就是模型预测**。特征值是玩家。要明确的是,玩游戏的不是特征,而是用于特定观察的特征的 。但是,我们将这些称为特性。我们使用 Shapley 值来计算每个特征对预测的贡献。**

例如,在之前的一篇文章中,我们训练了一个模型来预测鲍鱼的年龄。您可以在图 1 的中看到特定观察的 Shapley 值。这些给出了平均预测年龄 E[f(x)]和观测值预测值 f(x)之间的差值。例如,去壳重量的值使预测年龄增加了 1.81。我们称之为特性的贡献。****

图 1:SHAP 价值观的例子(来源:作者)

为了计算这些,我们可以使用与前面相同的 Shapley 值公式。我们需要做的就是改变价值函数。等式 2 给出了我们用于特定观察的函数 x 。这里 S 是特征值的联合, f 给出模型预测,模型具有 p 个特征。 S 的值是不在 S 中的所有特征的模型预测值。我们使用 S 中的实际值。

等式 2:机器学习的价值函数 Shapley 值(来源:作者)

我们实际上是在上式中做多重积分。为了忽略某个特征,我们将预测函数与特征值的概率相结合。我们对 s 中的所有特征都这样做,为此我们需要知道特征分布或使用经验分布。

上面的公式里有很多运动的部分。在本节的下一部分,我们将通过一个 ML 示例来更好地理解它。然后我们将继续讨论如何近似 ML 的 Shapley 值**。为了结束这一节,我们将讨论 Shapley 值的**性质。这些来自公理,我们将讨论它们在机器学习环境中的含义。****

ML 示例

假设我们想预测某人的收入。我们有两个特征——年龄(特征 1)和学位(特征 2)。我们以下面的模型 f 结束。对于年龄,我们假设特征在 18 到 60 岁之间均匀分布。类似地,对于学位,我们假设某人拥有学位(1)或没有学位(0)的机会是均等的。在我们的观察中,我们有一个 20 岁有学位的人。该模型将预测此人的收入为 5000 美元。

(来源:作者)

我们可以计算功能 2 {2}对功能 1 的联合的边际贡献,S = {1}。这可用于帮助计算特征 2 的 Shapley 值。换句话说,计算特征 2(度=1)对预测的贡献。

我们首先计算两个特征的联合的值,S = {1,2}。这相对简单。s 包含这两个特性,所以我们不必忽略任何特性。我们可以使用特性的实际值。如下所示,这与该观察的预测相同。

(来源:作者)

然后我们需要计算联盟的价值,S = {1}。在这种情况下,S 不包含{2}。我们忽略功能 2,使用功能 1 的实际值。记住,特征 2 不是连续的。为了忽略特性的价值,我们不需要使用集成。我们只是将每个值的预测值乘以该值的概率(即 50%)相加。

(来源:作者)

我们现在可以计算特征 2 对 S={1}的边际贡献。该贡献的权重以与标准 Shapley 值相同的方式计算。为了清楚起见,我们使用联合中特征的数量和特征值的总数。我们有|S| = |{1}| = 1 和 p = 2。这给了我们一个权重(1!)(0!)/2!= 1/2.

(来源:作者)

这仅给出了特征 2 的 Shapley 值所需的部分计算。我们还需要计算特征 2 对 S={}的边际贡献。为此,我们需要计算 S = {}的价值函数。这将要求我们忽略这两个特性的分布。

Shapely 值的近似值

计算精确的 Shapley 值在计算上是昂贵的。在上面的例子中,我们只有两个特征。随着我们添加更多的功能,可能的联盟数量呈指数增长。在实践中,只有接近 Shapley 值才是可行的。

一种方法是使用蒙特卡罗抽样。对于特征 I,我们先用特征值(+i)计算预测。我们在没有值(-i)的情况下做同样的事情。也就是说,我们为特征 I 取一个随机值。其余的特征值也将全部被随机采样。我们取这两个预测的差值。如下所示,我们这样做 M 次,并找出所有这些差异的平均值。通过随机采样和平均,我们隐含地根据特征的分布进行加权。

(来源:作者)

上述过程仍然不切实际。我们可能需要许多样本来获得一个合理的 Shapley 值的近似值。这就是 SHAP 的用武之地。正如我们在上一节中讨论的,这是一种更快的近似 Shapley 值的方法。在我们继续之前,我们将在机器学习的背景下讨论 Shapley 值的属性。

Shapley 值的性质

沙普利是解释预测的一种方法。它因其令人满意的特性而广受欢迎。这些大部分是从 Shapley 值的公理中得出的。

效率如前所述,沙普利值是有效率的。以前,这意味着游戏的全部价值在玩家之间分配。对于最大似然,这意味着预测在特征之间划分。具体地,Shapley 值满足下面的等式。所有 Shapley 值和平均预测值之和等于观测值的预测值。我们在前面的图 1 中看到了这一点。

(来源:作者)

另一种流行的当地解释方法是石灰。相比较而言,石灰不一定有效。计算出的权重将不会与原始预测相加。对 Shapley 来说,我们知道每个特征对预测的贡献有多大。对于 LIME,我们只知道哪个特征对预测最重要。

****对称性如果两个特征对所有联盟做出相同的贡献,那么它们将具有相同的 Shapley 值。

Dummy 如果一个特征从未改变预测,则其 Shapley 值为 0。换句话说,模型中不使用的特征将不具有 Shapley 值。

****可加性机器学习的 Shapley 值也是可加的。这仅与集合模型相关。在这种情况下,可以通过对集合中每个模型的 Shapley 值进行加权平均来计算总 Shapley 值。其中权重将与给予每个模型的预测的权重相同。例如,在随机森林中,来自每个决策树的预测被赋予相等的权重。

****一致性这个属性来源于前面的 3 个属性。假设我们把一个模型从 M1 换成 M2。如果一个特征现在比以前增加了更多的预测,那么它的 Shapley 值将增加。这意味着我们可以可靠地比较不同模型的特性贡献。

SHAP 价值观

SHAP python 包已经成为使用 Shapley 价值观的代名词。这个包广泛实现的关键是它可以进行近似的速度**。我们在下面讨论一些方法。速度的提高意味着我们也能够计算许多 Shapley 值。这允许对值进行不同的聚合,从而为我们提供模型的全局视图。**

KernelSHAP

内核 SHAP 将 Shapley 值重新定义为线性模型中的参数。简单地说,近似方法通过首先置换特征值来工作。在足够的排列之后,使用线性回归联合估计 Shapley 值。与其他采样方法相比,一起估计这些值需要更少的计算。例如蒙特卡罗采样,其中单独计算每个特征的 Shapley 值。

KernelSHAP 也是一种模型不可知的近似 Shapley 值的方法。这意味着它可以用于任何型号。前提是 SHAP 已经为你的建模包实现。

树形

与模型无关的近似方法是 TreeSHAP。它利用了集合模型中个体树的结构。因此,它只能用于基于树的算法,如随机森林和 XGBoost。TreeSHAP 的优点是明显比 KernelSHAP 快。

使用 KernelSHAP,我们可以在指数时间内估计 Shapley 值与特征数量的关系。而 TreeSHAP 可以在线性时间内估计它们。我们将在下面的文章中详细讨论这种差异。我们还探讨了模型的其他方面如何影响近似时间。这包括集合中的树的数量、最大深度和叶子的数量。

**

如前所述,这些方法可以近似计算大量的 Shapley 值。我们可以用不同的方式将它们结合起来,以了解模型作为一个整体是如何工作的。一个例子是图 2 中给出的蜂群图。

在这里,我们对每个特性的值进行分组(例如壳重)。我们可以看到倾向于具有大的正负 Shapley 值的特征。这些是倾向于对预测做出重要贡献的特征。我们还根据特征的值给点着色。这样我们就可以开始理解特征和目标变量之间的关系。

图 2:蜂群图的例子(来源:作者)

这些类型的地块易于实施是 SHAP 一揽子计划被广泛采用的另一个原因。我们将在下面的文章中探索如何使用这个包。我们讨论 Python 代码,并探索该包提供的一些其他聚合。

我希望这篇文章对你有帮助!如果你想看更多,你可以成为我的 推荐会员 来支持我。你可以访问 medium 上的所有文章,我可以得到你的部分费用。

https://conorosullyds.medium/membership

你可以在|Twitter|YouTube|时事通讯上找到我——注册免费参加 Python SHAP 课程

图像来源

所有图片都是我自己的或从www.flaticon获得的。在后者的情况下,我拥有他们的保费计划中定义的“完全许可”。

参考

南伦德伯格, SHAP 蟒包 (2021) https://github/slundberg/shap

南 Lundberg & S. Lee,解释模型预测的统一方法 (2017),https://arxiv/pdf/1705.07874.pdf

C.Molnar,可解释机器学习*(2021)https://christophm . github . io/Interpretable-ml-book/shap . html*

南 Masís,用 Python 进行可解释的机器学习 (2021)

L.S. Shapley,对博弈论的贡献,第一章为 n 人对策的价值。( 1953)

了解沙普利值

正文 S1:沙普利值的公理化基础**

人工智能的未来:从统计学习到想象空间中的行动和思考

原文:https://towardsdatascience/from-statistical-learning-to-acting-and-thinking-in-an-imagined-space-7149ad51e64a

建造具有人类思维的机器需要抛弃统计学,支持因果关系

由 iStock 上的艾夫林拉德科夫拍摄的照片

尽管人工智能领域近年来蓬勃发展,但我们仍远未开发出具有人类思维的机器。事实上,机器还不能像人类一样轻松地适应新的不同环境。此外,计算机系统还不具备对人类进化至关重要的想象力。这些限制来自于当前在该领域中采用的学习范例,该范例仅仅基于相关性学习。在本文中,我们将首先回顾人工智能领域的历史,看看该领域多年来是如何发展的,然后,我们将再次论证,该领域的革命是强制性的。具体来说,如果我们真的想建造一台接近人类智能水平的机器,我们需要抛弃当前的统计和数据驱动的学习范式,转而采用基于因果的方法。

在 20 世纪 70 年代和 80 年代初,计算机科学家认为,对人类事先提供的符号的操作足以让计算机系统表现出智能并解决看似困难的问题。这个假说后来被称为 符号规则假说

然而,尽管最初取得了一些令人鼓舞的进展,如计算机象棋和定理证明,但很快人们就发现,基于规则的系统无法解决对人类来说似乎很简单的问题。正如汉斯·莫拉维克所说:

让计算机表现出成人水平的性能相对容易……,而让它们掌握一岁儿童的技能却很难或不可能。

此外,基于规则的系统无法在不确定性或矛盾数据下很好地工作,由于随机和系统误差,这在自然界中是普遍存在的。由于这些限制和缺乏前景,人们对 AI 的兴趣下降,该领域进入了一个被称为 AI 寒冬 的时期。

最终,几年后,在很大程度上独立于经典人工智能领域之外,一个被称为 机器学习 的新领域开始出现。像罗森布拉特早期关于感知机的工作一样,机器学习建立在这样的观察基础上,即自然智能系统的表示和规则是通过进化和学习过程从经验中获得的,而不是通过符号规则假设获得的。自那以后,机器学习,尤其是基于人工神经网络的机器学习的子领域 深度学习 ,在人工智能领域取得了最显著的成功。

然而,尽管这些巨大的发展让许多科学家感到惊讶,并使许多人相信强人工智能的到来已经不远了,但我们仍然远远没有开发出一台接近人类智能水平的机器,而且,也许,除非人工智能研究发生重大转变,否则我们将无法实现这一目标。事实上,当前最先进的人工智能系统的泛化能力仍然非常差,这限制了它们在狭窄和特定任务中的应用。相比之下,人类可以轻松适应新的完全不同的环境。

最引人注目的是,像 “如果我做了……会怎么样?”“怎么…?”“为什么…?”“如果我做了…?” ,人类觉得相对容易回答的问题,对计算机系统来说却是望而却步。其直接结果是,机器无法思考它们的行为对外部环境的可能影响,也无法在这些有意的改变中做出选择,以产生想要的结果。此外,他们缺乏想象力和反思力,因为他们不能反思自己过去的行为,也不能设想其他的情景。

也许,这些限制不足为奇;毕竟,当前的机器学习系统完全以纯粹的联想模式运行,最终它们的成功归结为四个主要因素: (i)独立且同分布的随机变量假设,(ii)海量数据,(iii)高容量模型和(iv)高性能计算 。简而言之,他们只是试图通过捕捉统计相关性来拟合原始数据的函数,而不是对复杂的因果关系网进行推理,他们通过吃掉大量原始数据和计算资源来做到这一点。例如,撑开的雨伞和雨天是相互关联的现象,但只有后者与前者有直接的因果联系。因此,当看到人们打着伞时,表明正在下雨,但合上伞并不能停止下雨。虽然这对人类来说似乎微不足道,但机器还没有这种关系的线索,因此,它们会预测合上雨伞实际上会阻止下雨。因此,就像柏拉图的洞穴寓言中的囚犯一样,机器学习程序学习预测洞穴中阴影的运动,但他们未能理解那些阴影仅仅是三维物体的投影。

即使我们的祖先最初也缺乏因果知识,但正如尤瓦尔·赫拉利在他的书 智人 中所假设的那样,一旦人类开始意识到某些事情会导致其他事情,并且玩前者可以改变后者,我们就以惊人的速度进化。这个进化过程被称为 认知革命 。所有这些考虑都表明,除非我们将一个基于因果知识的心智模型嵌入其中,否则我们无法实现建造一台能够在康拉德·劳伦兹意义上的想象空间中行动的人类思维机器的雄心。

为了实现这一目标,被称为的新科学最杰出的倡导者之一 Judea Pearl 提出在未来的人工智能系统中植入一个 【因果推理机】 。这个因果推理机是一个机器,它接收一个查询和一堆数据作为输入,从而生成一个估计命令和对答案的估计。虽然估计需求可以被认为是回答查询的方法,并且它是根据基本的因果模型产生的,但是估计是根据输入数据的实际答案。因此,与传统的统计方法不同,数据的作用只限于估算的计算。这与基于数据驱动学习的机器学习形成了深刻的对比。**

这种设计背后的基本原理是原始数据天生是愚蠢的。事实上,尽管当前的研究趋势似乎希望每当因果问题出现时,以数据为中心的方法将引导我们找到正确的答案,但可以证明,因果问题无法直接从原始数据中得到答案。事实上,因果推理需要一些关于潜在数据生成过程的假设,因果领域已经表明,我们可以通过一组称为 因果模型 的数学对象将这些假设正式化。

在这一点上,我们应该指出,因果关系领域传统上假设因果模型是由人类先验给出的。此外,由基本因果模型生成的因果变量被假定为可直接观察的。然而,这些假设通常是不现实的。
的确,在某些领域,我们的知识还处于胚胎状态,以至于我们对世界如何运转毫无头绪。此外,现实世界的观察通常不会被结构化为因果变量单位。例如,首先需要提取图像中允许因果推理的对象。因此,随着机器学习超越了符号规则假设,不需要先验地给出符号,因果关系的新兴领域将努力学习现实世界现象的因果模型,并以自动的方式从现实世界的观察中发现它们的因果变量单元。毕竟,未来配备了因果推理机的强人工智能机器应该能够对世界做出一些假设,并在获得更多经验后对其进行微调。

这些缺点可以通过受益于机器学习的进步来解决。事实上,从非结构化原始数据中发现因果变量并连续学习底层因果模型都是以数据为中心的操作,而机器学习擅长于此。此外,现代机器学习技术可以帮助我们在因果推理机的统计估计步骤中克服维数灾难。所有这些都让我们得出一个结论,如果我们真的想造一个接近人类智能的机器,那么我们需要将因果性和机器学习融合到一个单一的领域: 因果性机器学习

总而言之,要建造一台具有人类思维的机器,我们还有很长的路要走,要实现这一目标,当前人工智能研究趋势的转变是必不可少的。就像人工智能领域通过接受机器学习的进步超越了符号规则假设一样,现在有必要抛弃纯粹的统计和数据驱动的学习范式,转而采用基于因果的方法。然而,新兴因果领域的工具不足以赋予机器因果思维的天赋。这就是为什么,虽然这两个领域是分开产生和发展的,但因果关系和机器学习需要合并成一个新的有前途的领域,称为因果机器学习。也许,当我们人类开始问自己因果问题时,我们的进化速度惊人地快,一旦我们发现如何成功地将因果关系与机器学习配对,那么 奇点 将指日可待。

建议阅读:

  • j .珀尔和麦肯齐博士(2019 年)。原因之书。企鹅图书。
  • schlkopf,b .,Locatello,f .,Bauer,s .,Ke,N. R .,Kalchbrenner,n .,Goyal,a .,& Bengio,Y. (2021)。迈向因果表征学习 2021。 arXiv 预印本 arXiv:2102.11107
  • schlkopf,b .和 von kugel gen,J. (2022 年)。从统计学习到因果学习。 arXiv 预印本 arXiv:2204.00607
  • schlkopf,B. (2022 年)。机器学习的因果关系。在概率和因果推理:朱迪亚珀尔的作品(第 765-804 页)。

从监督学习到非监督学习:计算机视觉中的范式转变

原文:https://towardsdatascience/from-supervised-to-unsupervised-learning-a-paradigm-shift-in-computer-vision-ae19ada1064d

慢慢地从训练过程中去除人类知识的注入

自从现代计算机视觉方法出现以来,这些技术的成功应用只能在监控领域中看到。为了使模型有助于执行图像识别、对象检测或语义分割等任务,人工监督曾经是必要的。在一个重大转变中,过去几年的计算机视觉研究已经改变了该领域的焦点:从人类监督下的保证成功转向新的前沿:自我监督和非监督学习。

以非监督方式对不同类进行聚类的动画。来源:【1】

让我们踏上一个已经开始的新时代的征程。

监督学习的成功

原始 AlexNet 架构的插图。来源:【2】

AlexNet 标志着神经网络应用于图像任务的第一次突破,更具体地说是 ImageNet 挑战。从那时起,游戏开始了,计算机视觉研究界开始致力于完善多种计算机视觉任务的监督技术。

对于图像分类,自最初的 AlexNet 论文以来,已经出现了许多模型的变体。ResNet 已经无可争议地成为卷积神经网络中的经典。诸如 EfficientNet 之类的高效架构已经出现。甚至是针对移动设备优化的网络,如 MobileNet 架构。最近,视觉变压器获得了越来越多的关注(无意的玩笑),并显示出在正确的设置下(大量数据和计算)优于卷积神经网络。最初是为语言任务而发明的,它们在计算机视觉方面的应用取得了巨大的成功。另一个有趣的方法是设计网络设计空间,其中量化的线性函数定义称为 RegNet 的网络架构。

监督学习成功解决的下一个任务是对象检测和语义分割。r-CNN 在第一个领域引起了第一次轰动,随后在计算效率和准确性方面取得了许多进步。值得注意的方法是 Fast、Faster 和 Mask R-CNN,还有 YOLO 算法和单次检测器,如 SSD MobileNet。语义分割领域的一个里程碑是 U-Net 架构。

此外,不要忘记基准数据集使监督技术更具可比性。ImageNet 为图像分类设立了标准,MS COCO 对于对象检测和分割任务仍然很重要。

所有这些技术都有一个共同点:它们依赖于经过提炼的人类知识和技能,以标记数据的形式表现良好。事实上,他们是围绕这个资源建立的,并依赖于这个资源。

在某种程度上,所有这些技术都采用模拟人类生物神经网络的人工神经网络。但是,这些模型学习感知的方式与人类学习感知的方式非常不同。为什么只模仿人脑的生物形态,而不模仿学习识别和分类背后的认知过程?

这就是下一次进化的切入点:自我监督学习。

将自我监督引入流程

想想你是如何学会观察的。你如何学会识别苹果?当你年轻的时候,你见过许多苹果,但并不是所有的苹果上都有一个标志,上面写着“这是一个苹果”,也没有人告诉你每次你看到一个苹果时它就是一个苹果。你学习的方式是通过相似性:你一次又一次地看到这个物体,每周多次,甚至每天。你认出来了:哎…这是一回事!

然后,有一天,有人教你这是苹果。突然间,这个抽象的物体,这个视觉表现,现在变成了你所知道的“苹果”。这是在自我监督学习中使用的类似过程。

SimCLR 培训过程的图示。来源:【3】

最先进的技术如 SimCLR 或 SwAV 复制了这一过程。对于预训练,所有标签都被丢弃,模型在不使用人类知识的情况下进行训练。向模型显示同一图像的两个版本,图像可能被裁剪、颜色扭曲或旋转,它开始学习尽管它们的视觉表示不同,但这些对象是相同的“东西”。事实上,这在它们相似的潜在向量表示中是可见的(记住这一点以备后用)。因此,该模型学习为每一类对象产生一个一致的矢量。

接下来是“教学”步骤:这次向预训练的模型显示一些带有标签的图像。它可以更快更有效地学习对不同种类的物体进行分类。

如此多的人类知识已经从训练过程中移除,但不是全部。但下一步就在眼前。

走向无监督学习

为了使一个模型完全不受监督,它必须在没有人类监督(标签)的情况下进行训练,并且仍然能够完成预期的任务,例如对图像进行分类。

请记住,自我监督模型已经朝着这个方向迈出了一步:在向它们展示任何标签之前,它们已经能够为不同的对象计算一致的矢量表示。这是去除所有人类监督的关键。

以非监督方式对不同类别进行聚类的示例。来源:【1】

这个向量通常表示的是维数减少的图像。事实上,自动编码器可以被训练来重建图像像素。因为它的降维,我们可以使用一种在计算机视觉中长期被忽略的技术:k 近邻分类器。如果我们的向量表示很好,只有相同的对象形成一个簇,而不同的对象在远处聚集,我们可以给模型一个新的未知图像,模型会将它分配到正确类别的簇中。模型将不能告诉你类名是什么,但是它属于哪组图像。如果为该组指定一个类名,则该组中的所有对象都可以被分类。毕竟类名是人类人工创造的(有人定义这个东西叫苹果),只是被人类赋予了意义。

由于所有标签都从训练过程中移除,并且像 DINO 这样的论文中的结果非常有希望,这是我们从计算机视觉模型的训练过程中移除所有监督的最接近的方式。

但是还有更多的事情要做,还有更大的提升空间。

包装它

如果你一直读到这里,我非常感谢你花时间阅读。我特意没有在这个故事中加入任何图片,因为它们会转移你对这篇文章的注意力。我是说,我们都想成为一个好的变形金刚,对吧?(这次是有意的)

衷心感谢您阅读本文。如果你对自我监督学习感兴趣,可以看看我的其他故事,在这些故事中,我试图向任何感兴趣的人解释这个领域中最先进的论文。如果你想在高级计算机视觉领域更深入地探索,考虑成为我的追随者。我试着每周发一篇文章,让你和其他人了解计算机视觉研究的最新进展。

参考资料:

[1] Meta AI 研究博文。https://ai . Facebook . com/blog/dino-paws-computer-vision-with-self-supervised-transformers-and-10x-more-efficient-training/

[2] Krizhevsky、Alex、Ilya Sutskever 和 Geoffrey E. Hinton。"使用深度卷积神经网络的图像网络分类."神经信息处理系统进展25(2012):1097–1105。https://proceedings . neur IPS . cc/paper/2012/file/c 399862d 3 b 9d 6 b 76 c 8436 e 924 a 68 c 45 b-paper . pdf

[3]陈,丁等:“视觉表征对比学习的一个简单框架。”机器学习国际会议。PMLR,2020 年。https://arxiv/pdf/2002.05709.pdf

从技术项目经理到机器学习工程师

原文:https://towardsdatascience/from-technical-project-manager-to-machine-learning-engineer-ecb185c16968

差距、陷阱和技巧

图片由作者提供;它只显示普通路径,而不是所有可能的路径;

这是一个具有挑战性的转变,需要付出巨大的努力,而人工智能/机器学习对于组织来说仍然是一个时髦的词,数据团队通常是第一个被解雇的人。另一方面,人工智能世界正在快速发展,从 AlphaFold 、文本到图像(稳定扩散 / Dall-E 2 )到多模态机器学习的突破性进展,人工智能的采用继续增长,收益仍然显著。

我在两年半的时间里过渡到了机器学习工程师,并从 2020 年开始担任商业分析硕士候选人的行业导师。这篇文章中分享的陷阱和技巧是基于我的经验和来自校友、同事和各行各业演讲者的见解。

希望我的故事能帮助激励你的转变,并指导你的决定。

职业转型前

我的职业生涯始于一家跨国电信公司的系统集成工程师,最终成为一名高级技术项目经理,后来我决定辞职,作为联合创始人加入一家初创公司,建立一个金融科技 SaaS 解决方案。

新的旅程

我的家人在 2017 年移居澳大利亚,和许多新移民一样,这意味着挑战和机遇,让你重新审视自己的职业规划。自 2013 年以来,我一直关注人工智能和云的发展,我相信云和人工智能,因为它们已经开始全面重塑行业,而这只是一个开始。

缺口

知识差距显然很大,所以不考虑非全日制学习。我一直在寻找一个密集、实用、核心、贴近业务且不超过 1 年的过渡。

知识缺口,先于商业分析硕士学位

墨尔本商学院的全日制商业分析硕士 (MBS)是最合适的人选:

按作者分类的图片,工作数据/业务分析的类型可能导致

  • 核心和实用课程——统计学习、预测分析、决策和优化、机器学习、编程以及如何在商业中应用数据分析。
  • 高强度的快节奏训练,速度比正常训练快 3 倍,将你推向极限。
  • 为期 5 周的团队实习,整合了学术学习和在组织中实施数据分析的实际挑战。
  • 非凡而聪明的候选人,大多数在知名咨询公司、金融机构或财富 500 强公司开始他们的数据职业生涯。

该计划为您的职业生涯建立了坚实而广泛的数据分析基础,更不用说强大的校友社区,因为许多校友已经开始成为行业领导者。

从英国帝国理工学院商学院到美国麻省理工学院索兰商学院,全球各地的商学院都在提供商业分析硕士课程。

如果你正在寻找一个密集和高质量的过渡,并且已经拥有业务领域的知识,这条道路可能很适合你作为起点。

行业差距,张贴商业分析硕士学位

我的数据职业生涯始于在澳大利亚一家领先的数据咨询公司担任数据顾问,这确实加速了我在该行业的职业生涯,并弥合了“Jupyter 笔记本中的结构化和静态数据”与“云中的非结构化和海量数据”之间的差距。

除了从客户项目中获得经验,破解认证/在线课程是获得丰富行业知识和实践的一种高效方式。我在两年内破解了 19 个证书/在线课程,以下是一些强烈推荐的证书:

图片由作者提供;每个工作范围的认证;

破解认证并不意味着你是该领域的主题专家,所以不要高估它的价值。然而,这些证书确实有助于建立对现代数据/机器学习解决方案的整体理解。凭借强大的云工程和数据分析技能,我后来从数据顾问转型为机器学习工程师。

这不是关于证书,而是关于你在这个行业中的知识/经验差距的意识,并成为一个快速的学习者,用你自己的策略缩小差距。

陷阱:

注意事项:本节分享的见解可能有失偏颇。

  • 头衔膨胀:许多数据科学家头衔的工作与建模、模型分析或特征工程无关,但面向数据分析师(仪表板报告、即席 SQL 查询等)。拥有强大数据科学背景的候选人(尤其是博士候选人)可能会对那些职位感到失望和失落。如果你有很强的领域知识并接近业务部门,成为一名数据分析师是一个非常有吸引力的职业。但我假设大多数数据科学或博士毕业生更喜欢机器学习建模/实现——了解现实中的工作范围,并妥善管理你的期望。
  • 机器学习建模工作很少,由机器学习驱动的组织通常实施成熟的行业级模型/解决方案。数据工程、系统设计和软件开发技能远比构建自己的模型更重要(你团队的模型击败正在推动人工智能军备竞赛的大型技术公司的尖端模型的可能性很低)。而是作为一名数据科学家或机器学习工程师,你的主要职责是:提高数据质量(与数据工程师团队一起);识别用例(与业务涉众一起);设计和实施基于云的机器学习端到端解决方案(与软件工程师 DevOps 一起)以证明用例——远离 Jupyter 笔记本并学习软件开发实践。
  • 对利益相关者的 AI 101 教育是必不可少的,不是因为他们是项目发起人,而是更重要的是,他们需要了解人工智能的局限性,而不是将其视为解决一切问题的神奇技术——在许多情况下,你不需要花哨的机器学习模型,企业需要可解释的人工智能。
  • 数据团队通常处于第一波裁员中,尤其是数据分析师、数据科学家和机器学习工程师,而数据工程师相对更安全——数据科学家可能不是“21 世纪最性感的工作”,不幸的是,至少目前不是。

小贴士:

注意事项:本节分享的小技巧可能会有偏差。

  • 避免头衔膨胀陷阱的一个技巧是在面试时问这个职位是与机器学习产品化相关还是与内部报告相关。
  • 云知识(AWS/Azure/GCP)是非常可取的,无论你的工作角色如何,它都是必备的,而大多数数据科学/分析项目都不涉及它。对于应届毕业生和大三学生来说是一大利好。
  • 坦诚面对自己的优势和劣势,从第一天开始规划自己的数据职业生涯。

按作者分类的图像,按角色分类的主要工作范围

  • 个人品牌很重要,知识分享也很贴心——建立你的影响力要从分享你的知识开始,越早越好。
  • 该行业正朝着以数据为中心的人工智能方法发展,数据工程和 MLOps 将更加关键。垃圾进,垃圾出。我们最近通过 8% 改进了一个模型在生产中的性能——通过简单地修复训练集中不一致的数据注释。

以下是帮助我转型的书籍/博客列表:

技术

  • 使用 Scikit-Learn、Keras 和 TensorFlow 进行机器实践学习
  • 用 Chip Huyen 设计机器学习系统
  • 系统设计访谈—内部人员指南:第 2 卷
  • 彼得的数据科学家实用统计学。b 安德烈。B&·彼得。G
  • 设计数据密集型应用程序:可靠、可伸缩和可维护系统背后的重要思想
  • AWS 解决方案库由 AWS

软技能

  • 用数据讲故事
  • 芭芭拉·明托的金字塔原理
  • 量子黑对人工智能的见解

最终想法:

数字化转型和人工智能的采用仍处于早期阶段,人工智能项目的高失败率并不新鲜。释放数据的价值并实现成功的 ML 项目需要对强大的基础进行投资,特别是用例一致性、文化转变、人工智能教育和流程变革管理,这实际上比实施人工智能技术本身更重要。对于那些拥有商业领域知识并随后转向数据职业的人来说,除了你的技术技能之外,培养“分析翻译”技能可以让你更具竞争力,正如我所观察到的那样,它们对成功的 ML/AI 项目更为关键。

[1]报道于 IBM 、优步、 Airbnb 和 Sejuti Das 的分析*《数据科学家如何也容易受到危机中裁员的影响》、*、 Analytics India Magazine ,2020 年 5 月 21 日、、https://oreil.ly/jobmz

[2]2021 年的 AI 状态

https://www . McKinsey . com/capabilities/quantum black/our-insights/global-survey-the-state-of-ai-in-2021

[3]与 Andrew 就 MLOps 的对话:从以模型为中心到以数据为中心的人工智能

https://www.youtube/watch?v=06-AZXmwHjo

从理论到实践用贝叶斯神经网络,用 Python

原文:https://towardsdatascience/from-theory-to-practice-with-bayesian-neural-network-using-python-9262b611b825

以下是如何用几行代码将不确定性融入你的神经网络

在 Unsplash 上由Towfiqu barb huya拍摄的照片

我拥有物理学硕士学位,是一名航空航天工程研究员。

物理学和工程学是两种截然不同的科学,它们都渴望了解自然,并有能力模拟自然。

物理学家的方法更多的是理论上的。物理学家观察这个世界,并试图以尽可能精确的方式对其建模。物理学家模拟的现实是不完美的,有一些近似,但是一旦我们考虑到这些不完美,现实就变得整洁、完美、优雅。

工程师的方法更加实用。工程师意识到物理学家的模型的所有限制,并试图在实验室中尽可能顺利地体验。工程师可能会做更残酷的近似(例如 pi = 3),但它的近似在现实生活的实验中实际上更有效。

戈登·林赛·格莱格的这段话总结了工程师的实践方法和物理学家优雅的理论方法之间的差异

科学家可以发现一颗新星,但他不能制造一颗。他将不得不请一位工程师为他做这件事。

在研究人员的日常生活中,事情是这样的。物理学家是对特定现象有理论的人。工程师是一个科学家,他可以进行实验,看看理论是否可行。

实际上,当我开始从物理学家到工程师的转变时,我经常被问到的一个问题是:

“好吧,你的模型似乎是可行的……但它有多稳健?”

这是典型的工程师问题。

当你有了一个物理模型,给定一定的条件,这个模型理论上是完美的

作者图片

尽管如此,当你进行实验时,还是有一定程度的误差,你必须能够正确地估计它。

作者图片

在这个例子中,我们如何估计理论输出和实验结果之间的能量差?

两个选项:

A.如果模型是确定性的,您可以通过某个增量改变初始条件(例如,将确定性规则应用于输入的噪声版本)

B.如果模型是概率的,对于一些给定的输入,你从输出中提取一些统计信息(例如,平均值、标准偏差、不确定性边界……)

现在让我们进入机器学习的**语言。**在这种特殊情况下:

A.如果机器学习模型是**确定性的,**我们可以通过改组训练集和验证集来测试它的鲁棒性。

B.如果机器学习模型是概率,对于一些给定的输入,您从输出中提取一些统计信息(例如,平均值、标准偏差、不确定性边界……)

现在,假设我们要使用的模型是神经网络。
第一个问题:需要神经网络吗?如果答案是肯定的,那么你一定要用(你不说)。问题:

“你的机器学习模型健壮吗?”

神经网络的原始定义是“纯粹确定性的”。
我们可以调整训练、验证和测试集,但我们需要考虑到神经网络可能需要很长时间来训练,如果我们想进行多次测试(假设 CV = 10,000),那么,你可能需要等待一段时间。

我们需要考虑的另一件事是,使用一种称为梯度下降的算法来优化神经网络。这个想法是我们从参数空间中的一个点开始,顾名思义,沿着损失的负梯度指示的方向下降。这将理想地把我们带到一个全球最小值(剧透:它实际上从来不是全球性的)。

不切实际的简单 1D 损失函数的理想情况如下:

作者图片

现在,在这种情况下,如果我们改变起点,我们仍然收敛到唯一的全局最小值。

更现实的情况是这样的:

作者图片

所以,如果我们从不同的起点随机重启训练算法,我们会收敛到不同的局部最小值

作者图片

所以如果我们从点 1 或者点 3 开始,我们会到达一个比起点 2 更低的点。

损失函数可能充满了局部最小值,因此找到真正的全局最小值可能是一项艰巨的任务。我们可以做的另一件事是从不同的起点重新开始训练,并比较损失函数值。这种方法和以前一样,我们也有同样的问题:我们只能做这么多次。

有一种更健壮、更严格、更优雅的方法,以一种概率的方式使用神经网络的相同计算能力;它被称为贝叶斯神经网络。

在本文中,我们将了解:

  1. 贝叶斯神经网络背后的想法
  2. 贝叶斯神经网络背后的数学公式
  3. 使用 Python 的贝叶斯神经网络的实现(更具体地说 Pytorch )
  4. 如何使用贝叶斯神经网络解决回归问题

开始吧!

1.什么是贝叶斯神经网络?

正如我们前面所说,贝叶斯神经网络的思想是给典型的神经网络增加一种概率“感觉”。我们如何做到这一点?

在理解贝叶斯神经网络之前,我们可能应该回顾一下贝叶斯定理。

观察贝叶斯定理的一个非常有效的方法如下:

“贝叶斯定理是一个数学定理,它解释了为什么如果世界上所有的汽车都是蓝色的,那么我的汽车也必须是蓝色的,但仅仅因为我的汽车是蓝色的,并不意味着世界上所有的汽车都是蓝色的。”

在数学术语中,已知事件“A”和“B”,已知事件“B”已经发生,事件“A”发生的概率如下:

作者图片

假设事件“A”已经发生,事件“B”发生的概率如下:

作者图片

连接第一个和最后一个表达式的等式如下:

作者图片

明白了吗?太好了。现在,假设你有了你的神经网络模型。这个神经网络只不过是一组将给定输入转换为期望输出的参数。

前馈神经网络(最简单的深度学习结构)通过将输入乘以参数矩阵来处理您的输入。然后,非线性激活函数(这是神经网络的真实能力)被逐项应用于该矩阵乘法的结果。结果是下一层的输入,其中应用相同的过程。

我们现在将模型的参数集称为 w 。现在我们可以问自己这个棘手的问题。

假设我有一个数据集 D,它是一组成对的输入 x_i 和输出 y_i,例如,第 I 个动物的图像和第 I 个标签(猫或狗):

作者图片

给定某个数据集 D,有一组参数的概率是多少?

这个问题你大概需要看 3、4 遍才能领会,但是思路是有的。如果你在输入和输出之间有某种映射,在极端的确定性情况下,只有一组参数能够处理输入并给你带来想要的输出。在概率方式中,会有一个概率参数集比另一个更有可能。

所以我们感兴趣的是数量。

作者图片

现在,有三件事很酷:

  1. 当考虑给定该分布的平均值时,您仍然可以将其视为标准的神经网络模型。例如:

作者图片

等式的左手代表计算的平均输出,右手代表所有可能的参数结果集(N)的平均值,概率分布提供每个结果的权重。

2.虽然 p(w|D) 显然是个谜,但 p(D|w)是我们可以一直研究的东西。如果我们对一个巨大的 N 使用上面的等式,就不需要机器学习了。你可以简单地说:“尝试给定某个神经网络的所有可能的模型,并使用上面的等式权衡所有可能的结果”

3.当我们得到 p 时,我们得到的不仅仅是一个机器学习模型;我们实际上获得了无限的机器学习模型。这意味着我们可以从你的预测中提取一些不确定性边界和统计信息。结果不仅是“10.23”,更像是“10.23,可能的误差为 0.50。”

我希望我让你兴奋了。让我们进入下一章

2.一些数学

我不想让这篇文章成为闲聊,但我也不想让它成为一种痛苦。如果你对贝叶斯神经网络有所了解,或者你已经知道它们背后的数学原理,可以跳过这一章。如果想有个参考,下面是一个不错的。(动手操作贝叶斯神经网络——深度学习用户教程)

现在这一切看起来很酷,但我认为,如果你是一个机器学习用户,你应该有这样的想法:

“我怎么才能优化这样一个奇怪的生物?”

简单的回答是,“通过最大化:

作者图片

但我不认为这是不言自明的。

在这种情况下,优化原则是找到分布 p(w|D)的最佳估计。我们称这个分布为 q,我们需要两个分布函数之间距离的度量。

我们将使用的指标称为kull back–lei bler散度

作者图片

一些有趣的事实:

  1. 对于两个相等的分布,它是 0
  2. 如果两个分布的分母趋向于零,而分子仍然不为零,那么它就是无穷大
  3. 它是不对称的。

现在,你在上面看到的损失函数是 Kullback-Leibler 散度的替代量,它被称为证据下限(ELBO)

权重 q 的分布被认为是具有均值μ和方差σ2 的正态分布:

作者图片

因此,优化是为了确定该分布的最佳 mu 和 sigma 值。

作者图片

在实际的 PyTorch 实施中,分布的平均值和目标值之间的 MSE 也被添加到我们的 L (mu,sigma)中。

3.Pyt(orch)hon 实施

使用 PyTorch 在 Python 中实现贝叶斯神经网络非常简单,这要归功于一个名为*torchbn的库。*

安装非常简单,因为:

*pip install torchbnn*

正如我们将看到的,我们将建立一个非常类似于标准 Tor 神经网络的东西:

*model = nn.Sequential(
    bnn.BayesLinear(prior_mu=0, prior_sigma=0.1, in_features=1, out_features=1000),
    nn.ReLU(),
    bnn.BayesLinear(prior_mu=0, prior_sigma=0.1, in_features=1000, out_features=1),
)*

实际上,有一个库可以将您的 torch 模型转换成它的贝叶斯代理:

*transform_model(model, nn.Conv2d, bnn.BayesConv2d, 
                args={"prior_mu":0, "prior_sigma":0.1, "in_channels" : ".in_channels",
                      "out_channels" : ".out_channels", "kernel_size" : ".kernel_size",
                      "stride" : ".stride", "padding" : ".padding", "bias":".bias"
                     }, 
                attrs={"weight_mu" : ".weight"})*

但让我们来做一个实际操作的详细示例:

4.动手回归任务

首先要做的是导入一些库:

之后,我们将制作非常简单的二维数据集:

因此,给定我们的 1D 输入 x(范围从-2 到 2),我们想找到我们的 y

Clean_target 是我们的地面真相生成器,而 target 是我们的噪声数据生成器。

现在我们将定义我们的贝叶斯前馈神经网络:

正如我们所看到的,它是一个具有贝叶斯层的两层前馈神经网络。这将允许我们有一个概率输出。

现在我们将定义我们的 MSE 损失和剩余的 Kullback-Leibler 散度:

这两个损失都将用于我们的优化步骤:

已经用了 2000 个纪元了。

让我们定义我们的测试集:

现在,从模型类得出的结果是概率。这意味着,如果我们运行我们的模型 10,000 次,我们将得到 10,000 个略有不同的值。对于从-2 到 2 的每个数据点,我们将得到平均值和标准偏差,

我们会画出置信区间。

5.包装它

在本文中,我们看到了如何建立一个机器学习模型,该模型结合了神经网络的力量,并仍然保持对我们预测的概率方法。

为了做到这一点,我们可以建立所谓的贝叶斯神经网络。这个想法不是优化一个神经网络的损失,而是优化无限个神经网络的损失。换句话说,我们正在优化给定数据集的模型参数的概率分布。

我们使用了一个损失函数,这个函数包含了一个叫做 Kullback-Leibler 散度的度量。这用于计算两个分布之间的距离。

*在优化我们的损失函数后,我们能够使用一个**概率模型。*这意味着,如果我们重复这个模型两次,我们会得到两个不同的结果,如果我们重复 10k 次,我们能够提取结果的稳健统计分布。

我们使用 torch 和一个名为 torchbnn 的库实现了这一点。我们建立了简单的回归任务,并使用两层前馈神经网络来解决它。

6.结论

如果你喜欢这篇文章,你想了解更多关于机器学习的知识,或者你只是想问我一些问题,你可以:

A.在 Linkedin 上关注我,我在那里发布我所有的故事
B .订阅我的 简讯 。这会让你了解新的故事,并给你机会发短信给我,让我收到你所有的更正或疑问。
C .成为 推荐会员 ,这样你就不会有任何“本月最大数量的故事”,你可以阅读我(以及数千名其他机器学习和数据科学顶级作家)写的任何关于最新可用技术的文章。

从训练到部署:用机器学习停止咬指甲

原文:https://towardsdatascience/from-training-to-deployment-stop-biting-your-nails-with-machine-learning-ffed31a59040

了解如何通过几次点击来训练机器学习模型,在简单的 web 应用程序中将其付诸实践,并将其部署到云上与他人共享。

为了完成所有这些,我们将使用 Teachable Machine、ReactJS、GitHub Actions 和开发者沙箱。

照片由帕特里克·福尔在 Unsplash 拍摄

介绍

Teachable Machine 是一个令人兴奋的工具,它提供了一种简单的方法来训练和测试机器学习模型,而无需该领域的专业知识。数据集可以直接从网络摄像头或麦克风创建,并用于训练图像、声音或姿势分类器。

训练本身是由工具自动完成的,并且在训练完成后可以立即测试生成的模型。如果您对刚刚构建的模型满意,可以将其导出为 Tensorflow 格式,并在应用程序中使用。

这里有一个值得一看的展示可教机器的视频。

现在你已经对可教机器有了更好的了解,我相信你已经绞尽脑汁在想用这样一个神奇的工具可以做的许多应用了。查看这个资源库,它提供了一个用可教机器建造的项目的精选列表。

因此,我想展示如何使用由可教机器训练的模型来构建一个简单的 web 应用程序。这个应用程序也将被部署到云中,使它成为一个更真实的应用程序,并使您能够与其他人共享它。

别担心,我们只会使用免费的东西。此外,一切都将是客户端的唯一,这意味着没有个人数据将流向服务器。

让我们开始吧!

游戏攻略

第一步:考虑一个应用程序

我们的应用将是一个咬指甲探测器

该检测器的目的是在用户工作/学习/玩耍等时通过他们的网络摄像头监控用户,并在手指靠近嘴时发出恼人的警报。希望这将把一个不愉快的触发器映射到用户的大脑中,这将使他们在再次向嘴移动手指时三思而行。

由于我们将构建一个 web 应用程序,并将其部署到云中,因此几乎任何带有摄像头和浏览器的设备都可以用来进行这种令人不安的现代监控。然而,重点将放在坐在电脑前的人身上,即面对他们的网络摄像头,这使得我们的模型更容易构建。

我理解有些人努力摆脱这种强迫性习惯,所以让我们试着建立一些可能帮助他人的东西,对吗?!

第二步:训练机器学习模型

训练我们的咬指甲探测器用可教的机器很容易。

使用网络摄像头,我们需要收集两类图像:(1) 咬指甲类,由手指靠近嘴的图像表示;(2) 正常类,由手指离开嘴的图像表示。

因此,一旦您开始使用可示教机器(转到开始图像项目标准图像模型),继续按下录制按钮,直到您每节课获得大约 500 张图像,这对该分类器来说应该绰绰有余。

在收集图像时改变位置(主要是手和脸)以在数据集中创建多样性是很重要的。此外,在 nnormal类中包括一些没有人在镜头前的图像,只是为了确保模特明白没有人在镜头前意味着一切都很好。你甚至可以创建一个 nobody 类!

使用从网络摄像头拍摄的图像构建训练数据集

一旦收集了数据集,就只需要训练和测试模型了。如果结果看起来不错,那么将训练好的模型导出为 Tensorflow.js 格式。输出将是一个 zip 文件,包含两个 JSON 文件(model.jsonmetadata.json)和权重(weights.bin)。

测试得到的训练模型

**注意:**请记住,最终的训练模型非常简单,可能最适合在创建数据集时记录的同一个人,并且条件相似。然而,你可以通过更精细的训练来改进它,比如收集更多的数据和调整训练超参数。

步骤 3:创建 web 应用程序

我不打算从头开始实现 ReactJS 应用程序,因为这不是本文的目标。相反,我已经为我们的 web 应用程序准备了样板代码。这是一个简单的 ReactJS 应用程序,我称之为可教机器游乐场,在这里你可以很容易地添加你的新页面来练习你的新模型。

代码是开源的,可以在 GitHub 库上获得,供你克隆或派生。您将发现一个简单的 ReactJS 应用程序,其中包含一些随时可以使用的组件。脚本和 GitHub 工作流也可以让生活变得更简单。

在继续之前,克隆库并构建应用程序。确保已经安装了 Node.js 和 Yarn 。您可以简单地在应用程序的根文件夹中运行yarn install && yarn build:dev来构建代码。此命令将安装所有尚未安装的依赖项,并在开发模式下构建代码。

现在让我们看看如何向代码中添加一个新的模型。

3a)添加训练好的模型文件

解压缩从可示教机器中导出的文件,并将其放在/static/models文件夹下的新文件夹中。

在我的例子中,我创建了一个名为nail-biting-detector 的文件夹,并将模型文件放在那里。

添加训练好的模型文件

3b)配置路线

寻找Routes.tsx文件(/src/app/Routes.tsx)。您必须分别向与您的新页面路径和模型文件相对应的navmodels对象添加条目。这些条目将允许您为您的模型创建一个新的路由页面,并使其易于访问模型文件。

在我的例子中,我用nbd键添加条目,这是nail-biting detector的缩写。当所有步骤完成后,我可以通过/nail-biting-detector路径访问我的新页面。

为页面和模型文件创建路线

3c)设置型号信息

在将模型文件添加为应用程序的一部分并相应地配置了路线之后,让我们创建一个对象,该对象将包含一些关于模型的有用信息,并使前面的步骤中加载模型变得容易。

查找Model.tsx文件(/src/app/Model.tsx)并导出一个ModelDescriptor常量。在我的例子中,我用与咬指甲检测器模型相关的信息添加了NAIL_BITING_DETECTOR_MODEL常量。

设置模型信息(仅显示代码的相关部分)

3d)添加模型页面

既然路线已经准备好了,您只需要在/src/pages文件夹下实现页面的逻辑。我已经准备了一些组件和挂钩,以便于开发使用网络摄像头和火灾通知的页面。

在我的例子中,当检测到类nail-biting时,页面NailBitingDetectorPage简单地呈现网络摄像头并发出烦人的通知(浏览器和声音)。很简单,是吧?!

**注意:**实施的通知行为可能因操作系统/浏览器而异。我已经在 Ubuntu/Chrome、Android/Chrome、Windows/Chrome 和 macOS/Safari 上验证过了。

创建 NailBitingDetectorPage(仅显示代码的相关部分)

最后,你需要去App.tsx ( /src/app/App.tsx)和地图的路线与网页,以便它可以访问。

用 NailBitingDetectorPage 映射路线(只显示代码的相关部分)

3e)构建并运行

一旦前面的步骤都完成了,你就可以开始尝试了!

在应用程序的根文件夹中执行yarn install && yarn build:dev来构建代码。此命令将安装所有尚未安装的依赖项,并在开发模式下构建代码。

然后执行yarn start启动开发服务器,在浏览器中打开 https://localhost:9001 。您甚至可以在连接到同一网络的其他设备上加载应用程序,但您需要使用您的 IP 地址,而不是localhost

可教机器游乐场主页

**注:**每次添加新路线,都会在主页上显示为要导航到的链接。

步骤 4:构建并推送容器映像

对于这一步,您必须用yarn build:prod构建生产代码,用yarn build:image构建容器映像,并将其推送到 quay.io 或 docker hub 等注册中心。

我使用podman来构建图像,但是如果你喜欢的话,也可以随意使用docker。如果你不使用podman,你将不得不对yarn build:image脚本(/package.json)做一些小的改动。

要自定义映像注册表、名称或标记,您可以在构建映像之前导出以下预定义的环境变量:

IMAGE_REGISTRY (default value: quay.io/caponetto)

IMAGE_NAME (default value: teachable-machine-playground)

IMAGE_TAG (default value: latest)

如您所见,使用默认值将准备一个名为teachable-machine-playground的容器图像,该图像将被推送到我的quay.io帐户,标签为latest,这里的是可用的。

如果您计划将代码推送到您的 GitHub 帐户,我还准备了一个 GitHub 工作流(/.github/workflows/publish.yml),它构建并将容器映像推送到quay.io。您只需定制环境变量,并添加 quay.io 密码作为存储库密码(REGISTRY_PASSWORD)。

将容器图像推送到 quay.io 的环境变量(仅显示代码的相关部分)

步骤 5:将您的 web 应用程序部署到开发人员沙箱中

现在,让我们使用已经发布到 quay.io 的容器映像,在 Red Hat OpenShift 的开发人员沙箱(或简称为开发人员沙箱)上创建一个应用程序。

如果你不熟悉开发者沙盒,这里有一段来自官方网站的引言,它几乎概括了它的所有功能:

沙盒在一个共享的多租户 OpenShift 集群中为您提供了一个私有的 OpenShift 环境,该集群预先配置了一组开发人员工具。您可以轻松地从源代码或 docker 文件创建容器,使用提供的示例和堆栈构建新的应用程序,从我们的模板目录添加数据库等服务,部署 Helm charts,等等。

此外,如果您想了解更多,请查看我的一次演讲,我在演讲中展示了如何将开发者沙箱与托管的卡夫卡和 DMN 连接起来。

一旦您登录到您的开发人员沙箱实例,转到Developer透视图并单击Add。您将看到创建应用程序的各种方法。然后点击Container images卡,在表格中填入适当的信息。

您必须提供图像 URL 并确保您的路线在 HTTPS 可用(移动通知仅适用于 HTTPS)。下面的 GIF 详细展示了怎么做。

将容器映像部署到开发人员沙箱

或者,您可以使用我之前提到的 GitHub 工作流(/.github/workflows/publish.yml)来部署您的映像。在这种情况下,您必须设置与您的 OpenShift 实例(OPENSHIFT_SERVEROPENSHIFT_TOKEN)和名称空间(OPENSHIFT_NAMESPACE)相关联的秘密。

**注意:**来自开发者沙箱的令牌每天到期。

部署到 OpenShift 的环境变量(仅显示相关的代码部分)

一旦这些信息准备就绪,您就可以在触发发布工作流时选择“部署”复选框。除了构建 web 应用程序并将容器映像推送到 quay.io,工作流还将在 OpenShift 实例上部署应用程序。自动化❤

好了,我们快到了!既然已经从容器映像创建了应用程序,那么只需等待几秒钟,应用程序就会启动。一旦准备就绪,您就可以访问和测试您的应用程序了。

测试部署的应用程序

正如你所看到的,当我把手放在嘴边时,浏览器会触发一个桌面通知(部分显示在 GIF 的顶部)。你听不到,但是浏览器也会发出烦人的声音警报。

如果您构建了这个应用程序,并且想要监控您自己,请让这个浏览器窗口保持打开,正常地做您的事情。如果你走神,把手放在嘴附近,你会收到通知。😄

重要提示:同样,如果您打算将该应用程序用作您的个人咬指甲探测器,请确保在专用浏览器窗口中加载该应用程序。只要不最小化应用程序窗口,您就可以正常使用电脑(在应用程序窗口上方打开其他窗口)。如果您最小化浏览器窗口或在同一个浏览器窗口中切换选项卡,网络摄像头将停止拍摄帧。

注意:开发者沙箱可以让你的应用程序运行 8 个小时。过了这段时间,你必须再次扩大规模。

结束语

在这篇文章中,我展示了创建包含从机器学习模型派生的功能的 web 应用程序是多么容易。我打算激励人们去思考机器学习模型的适用性,而不是把时间花在编码本身上。这就是为什么我选择了 Teachable Machine 并提供了样板代码(但尽可能保持简单)。

希望您可以运用一些想法,并使用这些工具轻松创建概念证明。如果它们变得适用,那么您可以将更多的时间集中在编码部分(训练一个更高级的模型和构建一个好看的应用程序)。

我会试着想出更多的应用程序,并将它们添加到库。此外,拥有桌面版和移动版的 playground 也不错,这样我们就可以拥有操作系统的全部功能。

也许我们可以在打响指、拍手甚至做一些手势时触发设备上的某些东西?你放在抽屉底部的那部旧手机可以变成一个监控管家,对你做的一些手势或声音做出反应!自动化工作并节省时间是很棒的,不是吗?

所以一定要尝试你的想法并分享结果!

**注意:**如果您发现了任何问题或想要对代码做出贡献,请不要犹豫,提出问题、讨论或请求。你将非常受欢迎!另外,这是我的个人网站,你可以在那里找到我的社交媒体链接来联系我。

今天到此为止。感谢阅读!😃

从模糊到有价值—数据从业者的见解

原文:https://towardsdatascience/from-vague-to-value-data-science-analytics-practitioner-insights-fed92a4bda08

作为数据专业人员,我们都想解决很酷的数据问题,并在这些项目中取得成功。然而,令人惊讶的是,当你从学校进入行业时,酷的定义和衡量成功的标准也发生了变化。当我们从在受控环境(如学校、训练营等)中从事数据项目时,就会发生范式转变。)到处理现实世界中的数据项目。凭借我多年的数据专业经验,参与各种对话,并担任有抱负的数据科学家的导师,我想在本文中分享一些从业者的见解。

1.数据是答案,但问题是什么?

数据专家不断地重新评估,不仅是我们是否正确地解决了问题,更重要的是,我们是否正确地解决了问题。在学校,总有人知道问题;这个问题很明确,至少在老师看来是这样。然而,我们的利益相关者很少确切地知道需要做什么。他们通常会带着担忧或希望来找你,希望你提供数据背景,填补空白,必要时进行反驳,并形成整体的问题陈述。我们的工作是将模糊的想法转化为可量化的问题陈述,然后再转化为数学语言。

一旦你得出一个可量化的问题陈述,这也不是路的尽头。可用数据很可能不支持您最初设想的分析类型(缺失值、隐藏的混杂变量、稀疏特征、稀疏数据点等)。).像这样的情况会进一步调整和完善你的问题陈述。

适应性、实用性和适应模糊性是数据科学家工具箱中最有价值的三项技能。

2.价值>准确性

数据科学的目标不是寻找和调整最准确的机器学习模型;目标是为组织提供价值。价值可以定义为金钱、时间、客户商誉、市场信任等。我们与业务和产品利益相关方合作,了解业务需求并量化 。通常,您会发现简单性和可解释性比模型的准确性和复杂性更受重视,因为前者与降低风险和增加部署模型成功的信心相关。

在学校里,你被鼓励学习和尝试越来越先进的技术来优化准确性,而在解决实际数据问题时,你必须找到,有时提倡,在准确性与成本或准确性与花费的时间之间进行权衡。技术的复杂性需要与技术解决问题的能力以及它为业务提供的价值相平衡。

认识到机器学习是解决方案,而不是解决方案,这一点很重要。在许多情况下,多变量统计分析、基于启发式的 case 语句和行为状态机等成本较低的技术可以提供我们想要的结果。

3.更多!=更好

数据的稀疏性给我们带来了许多众所周知的挑战。然而,很少被讨论的是,丰富的数据并不一定使分析或分析师的生活变得更容易。

在现实世界的数据科学应用中,选择正确的数据和正确的数据量至关重要。在学校项目中,我们通常试图获得尽可能多的数据,并从这些数据中提取尽可能多的信息,因为(a)这是我们获得额外学分的原因,(b)如果这是一个基于研究的项目,探索越多越好。

然而,在现实世界的数据项目中,我们在业务和产品的约束下运作,时间和金钱是其中的两个,并且关注的是效率而不是完整性。限制探索范围和缩小所需数据集的范围是很有价值的技能。添加到分析中的数据越多,分析就变得越复杂。对于数据清洁度、完整性、插补、大数据的分布式处理、代码复杂性、测试要求等问题,复杂性不是线性增长,而是呈指数增长。在复杂性呈指数增长的情况下,价值增益通常是对数的。认识到并停在甜蜜点是至关重要的。

4.当心沉没成本谬论

沉没成本谬误是这样一种现象,即如果一个人已经投资了一项努力,他可能会继续下去,即使很明显放弃会更有益。

数据专业人员处理的问题通常是开放式的,结论也不总是直截了当的。例如,您可能必须优化彼此反向相关的指标。或者你的项目可能朝着一个好的方向发展,但是没有确保足够的价值让涉众再花一个季度在你的工作上。如果你和其他主要利益相关者认为一个项目不再可行,可以继续进行。继续前进并不表示失败或浪费;相反,成熟到为了每个人的最佳利益而放手是专家和领导者的标志。在这些情况下,我们严格审查整个项目,做笔记和学习,与相关利益相关者召开回顾会议,然后继续前进!

数据科学和分析是一个迷人的领域,我们的任务是从模糊的走向有价值的。毫无疑问,这需要专业的技术知识,但更重要的是,这需要超越算法、代码和混淆矩阵的思维定势。**数据专业人员的思维模式在模糊和权衡的土地上茁壮成长;不那么死板,更灵活,对每一个假设都持开放态度。**我们希望这篇文章有助于您在开始数据科学和分析专业之旅时建立这种心态。

关注作者 @DrBushraAnjum

注意:文章的更新版本已经由内置专家贡献者网络发布。


图像属性:
女工分析数字数据、图表和图形。由 redgreystock 创建的背景矢量—www.freepik/矢量/背景

Fugue 和 duck db:Python 中的快速 SQL 代码

原文:https://towardsdatascience/fugue-and-duckdb-fast-sql-code-in-python-e2e2dfc0f8eb

使用 Python 和 DuckDB 优化您的 SQL 代码

动机

作为一名数据科学家,您可能对 Pandas 和 SQL 都很熟悉。然而,可能有一些查询和转换,您会觉得用 SQL 而不是 Python 来做比较舒服。

如果你能使用 SQL 查询熊猫数据帧,那不是很好吗…

作者图片

…同时在处理大量数据时还能加速您的代码

这时候 Fugue + DuckDB 就派上用场了。

在上一篇文章中,我展示了如何使用 pandas 引擎通过 SQL 查询 pandas 数据帧。

在本文中,我将向您展示如何使用 DuckDB 引擎来加速您的查询。

为什么是赋格和 DuckDB?

Fugue 是一个 Python 库,允许用户组合 Python 代码和 SQL 命令。这使得用户可以在 Jupyter 笔记本或 Python 脚本中灵活地切换 Python 和 SQL。

默认情况下,Fugue 会将您的 SQL 代码映射到 pandas。但是,当数据大小超过几个 GB 时,使用 pandas 并不理想,因为它:

  • 一次只允许您使用一个内核
  • 创建大量数据的中间副本,这会增加内存使用

Fugue 还允许您使用 Spark 或 Dask 来扩展 SQL 代码。但是,较小的组织可能没有可以向其移植工作负载的集群。

DuckDB 简介

DuckDB 是一个进程内 SQL OLAP 数据库管理系统。在本地机器上,即使是千兆字节的数据,速度也非常快。

因此,FugueSQL 和 DuckDB 的结合允许你使用 SQL 和 Python无缝地加速你的代码

要使用 DuckDB 引擎安装 FugueSQL,请键入:

pip install -U fugue[duckdb,sql] 

建立

首先,我们为赋格导入一些设置函数。这将让我们使用 Jupyter 笔记本中的%%fsql细胞魔法。我们还导入了 DuckDB 引擎。

加载数据

本文将使用币安加密小猫数据集。这可以通过知识共享许可从 Kaggle 下载。

文件夹crypto-binance包含 1000 多个不同的文件,总内存超过 5GB。我合并了这些文件并将新文件保存为raw.parquet

下载完加工文件后,一个文件名raw.parquet会保存在你的本地机器上。从获取新文件的位置开始:

现在我们来比较一下熊猫和 DuckDB 的加载速度。

熊猫

从使用 pandas 加载数据开始:

作者图片

请注意,加载数据花费了我们 10.5 秒。这太慢了。让我们看看是否可以通过使用 FugueSQL 和 DuckDB 来加快这个过程。

赋格+ DuckDB

要在 Jupyter 笔记本单元格中使用 DuckDB 作为引擎编写 SQL,只需在单元格的开头添加%%fsql duck:

作者图片

在上面的代码中,

  • PRINT允许我们打印输出
  • 双括号{{}}允许我们在 SQL 中使用 Python 变量。

上面的代码在 303 毫秒内加载数据!使用 DuckDB 作为引擎比使用 pandas 作为引擎快 34 倍以上。

处理

我们来对比一下熊猫和 DuckDB +神游的数据处理速度。

熊猫

作者图片

赋格+ DuckDB

作者图片

注意 :类似于 SQL 临时表,FugueSQL 允许多个 *SELECT* 语句。这使得代码可以自顶向下阅读,并消除了样板代码。如果未指定 *FROM* ,SQL 语句将使用堆栈中的最后一个数据帧。

观察

我们可以看到用 Fugue + DuckDB 比用熊猫快了差不多 4 倍。用 SQL 编写上面的处理代码也比用 pandas 稍微容易一些。

为什么 DuckDB 快了这么多?

DuckDB 更快,因为它使用了惰性求值。

作者图片

例如,在上面的代码中,PRINT语句默认返回 10 条记录。DuckDB 知道最终结果只需要 10 条记录,所以它只获取那些记录

另一方面,熊猫被急切地处决了。这意味着只有在整个文件加载到后,获取前 10 行的操作才会运行。

但是为什么神游呢?

DuckDB 有自己的 Python API ,为什么要用 Fugue 搭配 DuckDB?

这是因为 Fugue 提供了自定义函数,允许您轻松地与 Python 对象进行交互。在接下来的部分中,我们将学习如何使用这些自定义函数来改进您的 SQL 代码。

使用赋格数据帧

在上面的代码中,这一行

YIELD DATAFRAME AS top_symbols

…输出赋格数据帧并保存为top_symbols

你可以很容易地把top_symbols变成熊猫的数据帧:

作者图片

…或者在另一个 SQL 查询中使用top_symbols:

作者图片

为中间输出指定名称

有时,您可能希望为中间输出指定名称,以便它们可以被同一个 SQL 查询中的其他流程使用。神游允许你使用=给你的中间输出命名:

作者图片

在上面的代码中,我将中间输出保存到src,然后将srctop_symbols连接起来。

Python 扩展

同时使用 Fugue 和 DuckDB 还允许您通过扩展在 SQL 代码中使用 Python 逻辑。让我们来看看这些扩展。

输出

SQL 不允许您绘制输出。然而,我们可以用 Python 创建一个绘图函数,然后在我们的 SQL 代码中使用它。

要使用上面的plot_by功能,只需在plot_by旁边添加OUPUT USING:

作者图片

作者图片

改变

有些函数用 Python 比用 SQL 更容易编写。如果您想使用 Python 转换 SQL 查询的输出,请使用TRANSFORM

要了解这个扩展是如何工作的,首先创建一个名为macd的函数。该函数使用 pandas-ta 来获取时间序列的某个趋势。

我们还将模式提示作为注释(# schema: *,macd:double)添加到函数macd之上,以便 Fugue 可以读取这个模式提示并应用该模式。

现在我们可以使用这个函数来转换查询中的数据:

作者图片

作者图片

酷!我们刚刚使用 Python 函数转换了 SQL 输出。

点击了解更多关于赋格中TRANSFORMPREPARTITION的信息。

神游+生产中的 DuckDB

要将 FugueSQL 从 Jupyter 笔记本中取出并放入 Python 脚本中,我们需要做的就是将 FugueSQL 查询包装在一个fsql类中。然后我们可以调用.run()方法并选择一个执行引擎作为"duck"

结论

恭喜你!您刚刚学习了将 FugueSQL 和 DuckDB 一起用作后端,以充分利用本地执行。由于 DuckDB 提供的惰性评估,我们可以在将数据提交给 Pandas 进行进一步分析之前快速预聚合数据,这在 SQL 中是很难做到的。

使用 Fugue 作为界面还可以让我们无缝地使用 DuckDB 的优势。

随意发挥,并在这里叉这篇文章的源代码:

https://github/khuyentran1401/Data-science/blob/master/productive_tools/Fugue_and_Duckdb/Fugue_and_Duckdb.ipynb

我喜欢写一些基本的数据科学概念,并尝试不同的数据科学工具。你可以通过 LinkedIn 和 Twitter 与我联系。

如果你想查看我写的所有文章的代码,请点击这里。在 Medium 上关注我,了解我的最新数据科学文章,例如:

💔-tools-to-track-and-visualize-the-execution-of-your-python-code-666a153e435e> [## 3 个跟踪和可视化 Python 代码执行的工具

towardsdatascience](/3-tools-to-track-and-visualize-the-execution-of-your-python-code-666a153e435e)

参考

币安加密线。2018–01–16.币安。
CC0:公共领域。从 https://www.kaggle/binance/binance-crypto-klines检索到 2022–03–01

全栈数据科学家现在是趋势:这里是你如何成为一个

原文:https://towardsdatascience/full-stack-data-scientists-are-trending-right-now-heres-how-you-can-become-one-d5398dff60e7

软件工程和数据工程是你需要温习的两项技能

迈克尔·D 在 Unsplash 上的照片

2019 年,大家都想成为数据科学家。

2020 年,每个人都想成为一名数据工程师。

2021 年,大家都想成为机器学习工程师。

2022 年,事情又回到了原点——几乎是。

现在,公司希望有人能做所有的事情——翻译业务问题,编写生产就绪的代码,开发机器学习模型,设计数据管道,向 C 级高管演示,等等。公司的愿望和需求开始推动下一代数据驱动型技术人员的未来,他们希望在该领域找到一份工作。然而,这一次,公司倾向于更倾向于技术领域软件方面的个人,只是有数据科学的天赋。

这一次,2022 年,公司在找全栈数据科学家。

什么是全栈数据科学家?

我们从未见过这么多全栈数据科学家的招聘广告。但是到底什么是一呢?

一个 f 全栈数据科学家是一个独角兽,他能够履行软件工程师、数据工程师、商业分析师、机器学习工程师和数据科学家的角色,所有这些都包装在一个包中。这些人拥有不同的技能,甚至超过了普通数据科学家的技能,可以成为公司管理数据科学项目整个生命周期的一站式商店。

这种全生命周期方法意味着全栈数据科学家能够识别业务需求(或与 C 级高管合作确定需要解决哪个问题),建立项目所需的数据架构,分析数据和构建模型,并最终将模型部署到生产环境中。

从本质上讲,这个人是一个单人数据科学团队,可以满足一家小公司的所有数据需求。

全栈数据科学家与数据科学通才有何不同?

全栈数据科学家可能比你想象的要简单一点。

本质上,大多数有前途、有经验的数据科学家都具备成为全栈数据科学家所需的大部分技能。

让全栈数据科学家与众不同的一点是他们的软件和数据工程技能。这就是数据科学通才和全栈数据科学家的不同之处。数据科学通才将在多个领域拥有多种技能(如果你愿意,可以称之为多面手),但可能不具备在整个团队中执行端到端工作的丰富经验。

公司不再需要为他们最初的目的雇佣数据科学家,而是希望数据科学家能够带来各种各样的技能。这导致数据科学家希望通过扩展他们的数据和软件工程技能来适应现在摆在桌面上的所有工作要求,从而变得更有影响力。

如何成为一名全栈数据科学家

全栈数据科学家拥有普通数据科学家的所有基本技能,还具备强大的数据和软件工程技能。

在基础层面,全栈数据科学家将具备解决任何一般数据科学问题所需的数学、分析、设计和编码技能。这些基础知识超出了本文的范围,但是可以在这里找到更多信息:

从那里,数据科学家可以扩展他们的数据和软件工程技能,成为完整的包。

软件工程

最容易提高的技能是软件工程。所有这些都需要你写出比现在更好的代码。

全栈数据科学家需要了解的软件工程围绕着能够端到端地进行数据项目,这意味着您可以在最后将它发布到生产环境中。这将包括开发模块化、文档化和自动化测试的技能。

模块化指的是编写代码,将它的功能分成独立的、可互换的模块。这些模块应该被分成可访问的类和函数,允许你写一次代码,提高你的代码的性能,并保持你的代码文件小且易于导航。

提高软件工程技能的下一步是学习如何编写好的代码文档。令人惊讶的是,将新代码集成到现有的生产环境中,却没有代码文档来帮助您清理混乱,这种情况非常普遍。好的代码文档很容易创建,并且围绕着突出逻辑中的任何关键点,提前排除故障,并且通常给出代码做什么以及它应该如何工作的良好概述。

提高软件工程技能的最后一步是培养自动化测试的感觉。与普通测试相比,普通测试包括手动运行代码,并在每次输入一段逻辑时查看是否会抛出错误,自动化测试是使用为您执行这些任务的工具来执行的。您可以执行的自动化测试类型包括单元测试、冒烟测试、集成测试、回归测试、API 测试、安全测试、性能测试、验收测试等等。您将熟悉的一些工具包括 Selenium、LambaTest 和 QMetry Automation Studio。这里有一个很棒的视频,可以帮助你开始自动化测试:

数据工程

数据工程是你在称自己为全栈数据科学家之前需要提高的另一项技能。

数据工程涉及“设计和构建收集、存储和分析大规模数据的系统”。更广泛地说,这可以扩展到包括获取数据集,开发算法来清理数据,创建数据验证模型,确保符合数据安全政策,等等。

数据工程围绕着使用编程、数据库、分布式系统和云工程技能的组合来开发数据管道,这对一个好的数据科学项目来说是至关重要的。

数据工程技能,就像软件工程技能一样,可以通过免费的在线课程轻松掌握。获得全面的数据工程教育的最佳来源是 DataTalks 的免费在线课程。名为数据工程 Zoomcamp 的俱乐部。本课程将带您了解基础知识,从设置您的环境到学习工作流程编排,再到在本地和云中创建数据管道。还涵盖了数据仓库、批处理和端到端项目。

https://github/DataTalksClub/data-engineering-zoomcamp

订阅将我的故事直接发送到您的收件箱:故事订阅

请成为会员,使用我的推荐链接获得无限制的媒体访问权限(我将收取少量佣金,无需额外费用):媒体会员

通过捐赠来支持我的写作,以资助更多像这样的故事的创作:捐赠

从浓缩咖啡中充分提取咖啡

原文:https://towardsdatascience/fully-extracting-coffee-from-espresso-e2310dc6c289

咖啡数据科学

为另一个实验做准备的有趣数据

当我在准备一个实验时,我很好奇我是否能完全取出一个冰球。我的目标是为另一个实验生产废咖啡,但以前的实验总是显示一些可溶物仍然存在。所以我在制作这个用过的咖啡时做了一些测量,并在圆盘中放了很多水。

设备/技术

意式咖啡机 : 像样的意式咖啡机

咖啡研磨机:利基零

咖啡:家庭烘焙咖啡,中杯(第一口+ 1 分钟)

镜头准备:断奏夯实

预灌注:长,约 25 秒

输液:压力脉动

过滤篮 : 20g VST

其他设备: Atago TDS 计、 Acaia Pyxis 秤

发射

我开了一枪:

所有图片由作者提供

然后,我以 2、4、6 和 8 毫升/秒的流速,分四个阶段倒入 3 个杯子中。

结果看起来像奶油。

三杯及其级数

最终产品看起来像几瓶淡啤酒。

冰球看起来很奇怪。通常,颜色是均匀的,但是现在,上面的颜色比下面的颜色深。

倒置的用过的冰球。

所以我把这个冰球放回篮子里,并让更多的水通过它。

当然流出的水少了。

所以我把冰球拿出来,混在一起,然后把它塞回篮子里。

所有这些都是为了从咖啡中提取所有的可溶物。

然而,结果却很奇怪。

收集数据

我收集了每个阶段的 TDS。

这个测量可以告诉我们提取了多少咖啡。通常情况下,30%的咖啡是可溶的,但更多的咖啡不断从圆盘中流出。

我想过继续,但是我不需要为了我的实验而继续。我降到了 0% TDS,我想进行更大的实验。然而,这个数据是如此有趣和引人注目,因为它违背了我所假设的最大提取量。数据还表明,有微通道导致一些咖啡碎片没有暴露在足够的水流中进行提取。

如果你愿意,可以在推特、 YouTube 和 Instagram 上关注我,我会在那里发布不同机器上的浓缩咖啡照片和浓缩咖啡相关的视频。你也可以在 LinkedIn 上找到我。也可以关注我在中和订阅。

我的进一步阅读:

我未来的书

我的链接

浓缩咖啡系列文章

工作和学校故事集

Python 中的函数包装器:模型运行时和调试

原文:https://towardsdatascience/function-wrappers-in-python-model-runtime-and-debugging-243da483b9d6

使用函数包装器进行机器学习

图片由Acharaporn Kamornboonyarush在像素上拍摄

函数包装器是修改函数行为的有用工具。在 Python 中,他们被称为装饰者。Decorators 允许我们扩展函数或类的行为,而不改变包装函数的原始实现。

decorators 的一个特别有用的应用是用于监控函数调用的运行时,因为它允许开发人员监控一个函数成功执行和运行需要多长时间。这一过程对于管理时间和成本等计算资源至关重要。

函数包装器的另一个应用是调试其他函数。在 Python 中,定义打印函数参数和返回值的调试器函数包装器非常简单。这个应用程序对于使用几行代码检查函数执行失败的原因非常有用。

Python 中的 functools 模块使得定义定制装饰器变得容易,它可以“包装”(修改/扩展)另一个函数的行为。事实上,正如我们将看到的,定义函数包装器与在 Python 中定义普通函数非常相似。一旦定义了函数装饰器,我们只需在想要修改或扩展的函数之前的代码行中使用“@”符号和包装函数的名称。定义定时器和调试器函数包装器的过程遵循类似的步骤。

在这里,我们将考虑如何为简单分类模型定义和应用函数包装器来剖析机器学习模型运行时。我们将使用这个函数包装器来监控简单机器学习工作流中的数据准备、模型拟合和模型预测步骤的运行时。我们还将看到如何定义和应用函数包装器来调试这些相同的步骤。

我将使用 Deepnote ,这是一个数据科学笔记本,它使管理机器资源变得容易,并提供各种数据科学工具之间的无缝切换。这些特性使得运行可重复实验变得简单。我们将使用虚构的电信客户流失数据集,该数据集在 Kaggle 上公开。数据集在 Apache 2.0 许可下可以自由使用、修改和共享。

监控机器学习工作流的运行时间

让我们通过一个例子来看看这个过程是如何工作的。

数据准备

让我们通过导航到 Deepnote 平台开始数据准备过程(如果您还没有帐户,注册是免费的)。让我们创建一个项目。

作者截图

并将我们的项目命名为 function_wrappers,将我们的笔记本命名为 profiling_debugging_mlworkflow:

作者截图

让我们将数据添加到 Deepnote:

作者截图

我们将使用熊猫图书馆来处理我们的数据。我们来导入一下:

import pandas as pd

接下来,让我们定义一个函数,我们称之为 data_preparation:

def data_preparation():
  pass

我们来补充一些基本的数据处理逻辑。该功能将执行五项任务:

  1. 读入数据
  2. 选择相关列
  3. 该函数将接受列名列表作为输入
  4. 清理数据
  5. 指定列数据类型
  6. 为培训和测试拆分数据
  7. 该函数将把测试大小作为输入
  8. 返回训练和测试集

让我们首先添加读入数据的逻辑。让我们也添加显示前五行的逻辑:

def data_preparation(columns, test_size):
  df = pd.read_csv("telco_churn.csv")
  print(df.head())

让我们调用我们的数据准备函数。现在,让我们传递“none”作为列和测试大小的参数:

def data_preparation(columns, test_size):
  df = pd.read_csv("telco_churn.csv")
  print(df.head())
  data_preparation(None, None)

作者截图

接下来,在我们的 data_preparation 方法中,让我们使用 columns 变量来过滤我们的数据框,定义我们将使用的列名列表,并使用 columns 变量调用我们的函数:

def data_preparation(columns, test_size):
  df = pd.read_csv(“telco_churn.csv”)
  df_subset = df[columns].copy()
  print(df_subset.head())
columns = ["gender", "tenure", "PhoneService", "MultipleLines","MonthlyCharges", "Churn"]
data_preparation(columns, None)

作者截图

接下来,让我们指定另一个函数参数,我们将使用它来指定每一列的数据类型。在我们函数的循环的中,我们将为每一列指定数据,这些数据将从我们的数据类型映射输入字典中获得:

def data_preparation(columns, test_size, datatype_dict):
  df = pd.read_csv(“telco_churn.csv”)
  df_subset = df[columns].copy()
  for col in columns:
  df_subset[col] = df_subset[col].astype(datatype_dict[col])
  print(df_subset.head())
columns = ["gender", "tenure", "PhoneService", "MultipleLines","MonthlyCharges", "Churn"]
datatype_dict = {"gender":"category", "tenure":"float", "PhoneService":"category", "MultipleLines":"category", "MonthlyCharges":"float", "Churn":"category"}
data_preparation(columns, None, datatype_dict)

在另一个 for 循环中,我们将把所有分类列转换成机器可读的代码:

def data_preparation(columns, test_size, datatype_dict):
  df = pd.read_csv("telco_churn.csv")
  df_subset = df[columns].copy()

  for col in columns:
     df_subset[col] = df_subset[col].astype(datatype_dict[col])

  for col in columns:
   if datatype_dict[col] == "category":
     df_subset[col] = df_subset[col].cat.codes

columns = ["gender", "tenure", "PhoneService", "MultipleLines","MonthlyCharges", "Churn"]
datatype_dict = {"gender":"category", "tenure":"float", "PhoneService":"category", "MultipleLines":"category", "MonthlyCharges":"float", "Churn":"category"}
data_preparation(columns, None, datatype_dict)

最后,让我们指定我们的输入和输出,分割我们的数据用于训练和测试,并返回我们的训练和测试集。首先,让我们从 Scikit-learn 中的模型选择模块导入训练测试分割方法:

from sklearn.model_selection import train_test_split

接下来,让我们指定我们的输入、输出、训练和测试集:

def data_preparation(columns, test_size, datatype_dict):
  df = pd.read_csv("telco_churn.csv")
  df_subset = df[columns].copy()

  for col in columns:
     df_subset[col] = df_subset[col].astype(datatype_dict[col])

  for col in columns:
   if datatype_dict[col] == "category":
     df_subset[col] = df_subset[col].cat.codes
  X = df_subset[["gender", "tenure", "PhoneService", "MultipleLines","MonthlyCharges",]]
  y = df_subset["Churn"]
  X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size, random_state=42)
  return X_train, X_test, y_train, y_test

columns = ["gender", "tenure", "PhoneService", "MultipleLines","MonthlyCharges", "Churn"]
datatype_dict = {"gender":"category", "tenure":"float", "PhoneService":"category", "MultipleLines":"category", "MonthlyCharges":"float", "Churn":"category"}
X_train, X_test, y_train, y_test = data_preparation(columns, 0.33, datatype_dict)

模特培训

现在我们已经准备好了训练和测试数据,让我们来训练分类模型。为简单起见,让我们定义一个函数,用默认参数训练一个随机森林分类器,并设置一个随机状态再现性。该函数将返回经过训练的模型对象。让我们从导入随机森林分类器开始:

from sklearn.ensemble import RandomForestClassifier

接下来,让我们定义我们的拟合函数并存储训练好的模型对象:

def fit_model(X_train,y_train):
   model = RandomForestClassifier(random_state=42)
   model.fit(X_train,y_train)
   return model

model = fit_model(X_train,y_train)

模型预测和性能

让我们也定义我们的预测函数,它将返回模型预测

def predict(X_test, model):
   y_pred = model.predict(X_test)
   return y_pred

y_pred = predict(X_test, model)

最后,让我们定义一个报告分类性能指标的方法

def model_performance(y_pred, y_test):
   print("f1_score", f1_score(y_test, y_pred))
   print("accuracy_score", accuracy_score(y_test, y_pred))
   print("precision_score", precision_score(y_test, y_pred))

model_performance(y_pred, y_test)

作者截图

现在,如果我们想使用函数包装器来定义我们的计时器,我们需要导入 functools 和 time 模块:

import functools
import time

接下来,让我们定义我们的定时器函数。我们称之为 runtime_monitor。它将采用一个名为 input_function 的参数作为自变量。我们还将把输入函数传递给 functools 包装器中的 wrappers 方法,我们将把它放在实际的计时器函数之前,称为 runtime_wrapper:

def runtime_monitor(input_function):
  @functools.wraps(input_function)
  def runtime_wrapper(*args, **kwargs):

接下来,在运行时包装器的范围内,我们为输入函数指定计算执行运行时的逻辑。我们定义了一个开始时间值,函数的返回值(我们执行函数的地方)一个结束时间值,以及运行时间值,即开始时间和结束时间之差

 def runtime_wrapper(*args, **kwargs):
     start_value = time.perf_counter() 
     return_value = input_function(*args, **kwargs)
     end_value = time.perf_counter()
     runtime_value = end_value - start_value 
     print(f"Finished executing {input_function.__name__} in {runtime_value} seconds")
     return return_value

我们的计时器函数(runtime_wrapper)是在 runtime_monitor 函数的范围内定义的。完整的功能如下:

作者创建的嵌入

然后,我们可以使用 runtime_monitor 来包装我们的 data_preparation、fit_model、predict 和 model_performance 函数。对于数据准备,我们有以下内容:

@runtime_monitor
def data_preparation(columns, test_size, datatype_dict):
  df = pd.read_csv("telco_churn.csv")
  df_subset = df[columns].copy()
  for col in columns:
     df_subset[col] = df_subset[col].astype(datatype_dict[col])
  for col in columns:
   if datatype_dict[col] == "category":
     df_subset[col] = df_subset[col].cat.codes
  X = df_subset[["gender", "tenure", "PhoneService", "MultipleLines","MonthlyCharges",]]
  y = df_subset["Churn"]
  X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size, random_state=42)
  return X_train, X_test, y_train, y_test

columns = ["gender", "tenure", "PhoneService", "MultipleLines","MonthlyCharges", "Churn"]
datatype_dict = {"gender":"category", "tenure":"float", "PhoneService":"category", "MultipleLines":"category", "MonthlyCharges":"float", "Churn":"category"}
X_train, X_test, y_train, y_test = data_preparation(columns, 0.33, datatype_dict)

作者截图

我们看到我们的数据准备函数需要 0.04 来执行。对于 fit_model,我们有:

@runtime_monitor
def fit_model(X_train,y_train):
   model = RandomForestClassifier(random_state=42)
   model.fit(X_train,y_train)
   return model

model = fit_model(X_train,y_train)

作者截图

我们预测:

@runtime_monitor
def predict(X_test, model):
   y_pred = model.predict(X_test)
   return y_pred

y_pred = predict(X_test, model)

作者截图

最后,对于模型性能:

@runtime_monitor
def model_performance(y_pred, y_test):
   print("f1_score", f1_score(y_test, y_pred))
   print("accuracy_score", accuracy_score(y_test, y_pred))
   print("precision_score", precision_score(y_test, y_pred))

model_performance(y_pred, y_test)

作者截图

我们看到 fit 方法是最耗时的,这是我们所期望的。在构建像这样简单的机器学习工作流时,能够可靠地监控这些函数的运行时对于资源管理是必不可少的。

调试机器学习模型

定义调试器函数包装器也是一个简单的过程。我们先来定义一个叫做调试方法的函数。类似于我们的定时器函数,iit 将接受一个函数作为输入。我们还将把输入函数传递给 functools 包装器中的 wrappers 方法,我们将把它放在实际的调试器函数之前,称为 debugging_wrapper。debugging_wrapper 将参数和关键字参数作为输入:

def debugging_method(input_function):
  @functools.wraps(input_function)
  def debugging_wrapper(*args, **kwargs):

接下来,我们将把参数的表示、关键字及其值分别存储在名为 arguments 和 keyword_arguments 的列表中:

def debugging_wrapper(*args, **kwargs):
       arguments = []
       keyword_arguments = []
       for a in args:
          arguments.append(repr(a))    
       for key, value in kwargs.items():
          keyword_arguments.append(f"{key}={value}")

接下来,我们将连接参数和 keyword_argument,然后将它们连接成一个字符串:

 def debugging_wrapper(*args, **kwargs):
    ...#code truncated for clarity
    function_signature = arguments + keyword_arguments
    function_signature = "; ".join(function_signature) 

最后,我们将打印函数名、它的签名和它的返回值:

 def debugging_wrapper(*args, **kwargs):
    ...#code truncated for clarity
     print(f"{input_function.__name__} has the following signature: {function_signature}")
     return_value = input_function(*args, **kwargs)
     print(f"{input_function.__name__} has the following return: {return_value}") 

debugging_wrapper 函数也将返回输入函数的返回值。完整的功能如下:

作者创建的嵌入

数据准备

现在,我们可以用调试方法包装数据准备函数:

作者创建的嵌入

模特培训

我们可以对 fit 函数做同样的事情:

作者创建的嵌入

模型预测和性能

对于我们预测函数:

作者创建的嵌入

最后,对于我们的性能函数:

作者创建的嵌入

这篇文章中的代码可以在 GitHub 上找到。

Python 中使用的函数包装器

函数包装器在软件工程、数据分析和机器学习中有着广泛的应用。当开发机器学习模型时,涉及数据准备、模型训练和预测的操作的运行时间是主要关注的领域。在数据准备的情况下,根据数据的大小和操作的复杂性,诸如读入数据、执行聚合和输入缺失值等操作在运行时会有所不同。记住这一点,当数据改变时,监视这些操作的运行时如何改变是有用的。

此外,将模型拟合到训练数据可以说是机器学习管道中最昂贵的步骤。根据数据对模型进行定型(拟合)的运行时间可能会随着数据大小的不同而有很大的变化,包括包含的要素数量和数据中的行数。在许多情况下,机器学习的训练数据会随着更多的数据而刷新。这导致模型训练步骤在运行时增加,并且通常需要更强大的机器来成功完成模型训练。

模型预测调用也可能因预测输入的数量而异。尽管几十到几百个预测调用可能不会有很长的运行时间,但在某些情况下,需要进行几千到几百万次预测,这会极大地影响运行时间。能够监控预测函数调用的运行时对于资源管理也是必不可少的。

除了监控运行时,使用函数包装器进行调试在构建机器学习模型时也很有用。与运行时监控类似,该过程对于解决数据准备、模型拟合调用和模型预测调用的问题非常有用。在数据准备步骤中,数据刷新可能导致曾经可执行的功能失败。此外,当数据被刷新或用于训练的模型输入被修改时,问题和错误可能出现。使用函数包装器进行调试有助于指出输入、数组形状和数组长度的变化是如何导致 fit 调用失败的。在这种情况下,我们可以使用函数包装器来找到这个 bug 的来源并解决它。

Python 中的函数包装器使得运行时监控和调试变得简单明了。虽然我只讨论了一个非常简单的例子的数据准备、模型拟合和模型预测,但是这些方法对于更复杂的数据会变得更加有用。在数据准备的情况下,运行时监控和调试功能对于其他类型的数据准备非常有用,例如预测缺失值、合并数据源以及通过规范化或标准化来转换数据。此外,在拟合模型和进行预测时,模型类型和模型超参数会对运行时间和错误产生重大影响。拥有可靠的运行时监控和调试工具对于数据科学家和机器学习工程师来说都是很有价值的。

本帖原载于 内置博客 。原片可以在 这里找到

本文标签: 中文翻译博客TowardsDataScience一百七十