TowardsDataScience 博客中文翻译 2021(一百五十一)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

从零开始在 JAX 建造一个变压器

原文:https://towardsdatascience.com/build-a-transformer-in-jax-from-scratch-how-to-write-and-train-your-own-models-9aa02b5b28fd?source=collection_archive---------16-----------------------

如何编写和训练自己的模型

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

作者图片

在本教程中,我们将探讨如何开发一个神经网络(神经网络)与 JAX。还有什么比变压器更好的型号可以选择。随着 JAX 越来越受欢迎,越来越多的开发团队开始尝试使用它,并将其整合到他们的项目中。尽管它缺乏 Tensorflow 或 Pytorch 的成熟度,但它为构建和训练深度学习模型提供了一些很好的功能。

如果你还没有对 JAX 的基础知识有一个坚实的理解,看看我以前的文章。你也可以在我们的 Github 库中找到完整的代码。

俳句和 Flax 似乎是 Google/Deepmind 内部最多的框架,拥有最活跃的 Github 社区。对于本文,我将从第一个开始,看看以后是否还需要另一个。

所以你准备好用 JAX 和俳句做一个变形金刚了吗?对了,我假设你对变形金刚有扎实的了解。如果你还没有,请指点我们关于注意变形金刚的文章。

让我们从自我关注块开始。

自我关注障碍

首先,我们需要引进 JAX 和俳句

*import* jax
*import* jax.numpy *as* jnp
*import* haiku *as* hk
import numpy *as* np

幸运的是,俳句有一个内置的MultiHeadAttention模块,可以扩展来构建一个屏蔽的自我关注模块。我们的块接受查询、键、值以及掩码,并将输出作为 JAX 数组返回。可以看到代码非常熟悉标准 Pytorch 或者 Tensorflow 代码。我们所要做的就是构建因果掩码,使用np.trill()使第 k 个以上数组的所有元素无效,乘以我们的掩码,并将所有内容传递给hk.MultiHeadAttention模块

这个片段允许我介绍俳句的第一个关键原则。所有模块都应该是hk.Module的子类。这意味着他们应该实现__init____call__,以及其他方法。在某种意义上,这与 Pytorch 模块的架构相同,我们实现了一个__init__和一个forward

为了清楚起见,让我们构建一个简单的 2 层多层感知器作为hk.Module,它将方便地用在下面的变压器中。

线性层

一个简单的两层 MLP 看起来像这样。你可以再次注意到它看起来多么熟悉。

这里需要注意一些事情:

  • 俳句为我们提供了一组hk.initializers下的权重初始化器,在这里我们可以找到最常见的方法
  • 它还内置了许多流行的层和模块,如hk.Linear。如需完整列表,请查看官方文档。
  • 没有提供激活函数,因为 JAX 已经有一个名为jax.nn的子包,在那里我们可以找到激活函数,比如relu或者softmax

标准化层

层规范化是 transformer 架构的另一个组成部分,我们也可以在 Haiku 的公共模块中找到它。

变形金刚

现在说说好东西。下面你可以找到一个非常简单的转换器,它利用了我们预先定义的模块。在__init__中,我们定义了基本变量,如层数、注意力头和辍学率。在__call__中,我们使用一个for循环组成一个块列表。

如您所见,每个模块包括:

  • 标准化层
  • 自我关注障碍
  • 两个脱落层
  • 两个标准化层
  • 两个跳跃连接(h = h + h_attnh = h + h_dense)
  • 两层致密块体

最后,我们还添加了一个最终的规范化层。

我想现在你已经意识到用 JAX 建立一个神经网络非常简单。

嵌入层

最后,让我们也包括嵌入层。很高兴知道俳句还提供了一个嵌入层,它将从我们输入的句子中创建标记。令牌然后被添加到位置嵌入,产生最终输入。

hk.get_parameter(param_name, ...)用于访问模块的可训练参数。但是你可能会问,为什么不像我们在 Pytorch 中那样使用对象属性呢?这就是俳句的第二个关键原则发挥作用的地方。我们使用这个 API,这样我们就可以使用 hk.transform将代码转换成一个纯函数。这不是很容易理解,但我会尽可能地把它说清楚。

为什么是纯函数?

JAX 的力量体现在它的函数转换中:用 T2 向量化函数的能力,用 T3 自动并行化,用 T4 实时编译。这里需要注意的是,为了转换一个函数,它需要是纯的。

纯函数是具有以下特性的函数:

  • 对于相同的参数,函数返回值是相同的(没有局部静态变量、非局部变量、可变引用参数或输入流的变化)
  • 函数应用程序没有副作用(没有局部静态变量、非局部变量、可变引用参数或输入/输出流的变异)。

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

来源: Scala 纯函数 by O’Reily

这实际上意味着一个纯函数将总是:

  • 如果用相同的输入调用,返回相同的结果
  • 所有的输入数据都通过函数参数传递,所有的结果都通过函数结果输出

Haiku 提供了一个名为hk.transform的函数转换,它将具有面向对象的、功能上“不纯”的模块的函数转换成可以与 JAX 一起使用的纯函数。为了在实践中看到这一点,让我们继续训练我们的 Transformer 模型。

向前传球

典型的向前传球包括:

  1. 获取输入并计算输入嵌入
  2. 运行通过变压器的块
  3. 返回输出

上述步骤可以很容易地用 JAX 组成如下:

虽然代码很简单,但它的结构可能看起来有点奇怪。实际的正向传递通过forward_fn功能执行。然而,我们用返回forward_fnbuild_forward_fn函数包装它。什么鬼东西?

接下来,我们需要使用hk.transformforward_fn函数转换成一个纯函数,这样我们就可以利用自动微分、并行化等功能。

这将通过以下方式实现:

这就是为什么我们不是简单地定义一个函数,而是包装并返回函数本身,或者更准确地说是一个可调用的。然后,这个可调用函数可以被传递到hk.transform中,成为一个纯函数。如果这是清楚的,让我们继续我们的损失函数。

损失函数

损失函数是我们熟知的交叉熵函数,不同之处在于我们还考虑了掩模。JAX 再次提供了one_hotlog_softmax功能。

如果你还和我在一起,喝一口咖啡,因为从现在开始事情会变得严重。是时候建立我们的训练循环了。

训练循环

因为 Jax 和 Haiku 都没有内置的优化功能,我们将使用另一个框架,名为 Optax 。如开头所述,Optax 是渐变处理的 goto 包。

首先,您需要了解一些关于 Optax 的事情:

Optax 的关键改造是GradientTransformation。转换由两个函数定义,即__init____update____init__初始化状态,__update__根据状态和参数的当前值转换梯度

state = init(params)
grads, state = update(grads, state, params=None)

为了减少我们的main函数,我们将把渐变更新提取到它自己的类中。

首先,GradientUpdater接受模型、损失函数和优化器。

  1. 该模型将是由hk.transform转换的纯forward_fn函数
forward_fn = build_forward_fn(vocab_size, d_model, num_heads, num_layers, dropout_rate)forward_fn = hk.transform(forward_fn)

2.损失函数将是具有固定forward_fn和“vocab_size”的部分的结果

loss_fn = functools.partial(lm_loss_fn, forward_fn.apply, vocab_size)

3.优化器是一组按顺序运行的优化转换(可以使用optax.chain组合操作)

optimizer = optax.chain(
    optax.clip_by_global_norm(grad_clip_value),
    optax.adam(learning_rate, b1=0.9, b2=0.99)
)

梯度更新器将被初始化如下:

updater = GradientUpdater(forward_fn.init, loss_fn, optimizer)

看起来会像这样:

__init__中,我们用self._opt.init(params)初始化优化器,并声明优化的状态。状态将是具有以下内容的字典:

  • 当前步骤
  • 优化程序状态
  • 可训练参数
  • (一个随机生成的密钥传入jax.random.split)

update功能将更新优化器的状态以及可训练参数。最终,它将返回新的状态。

updates, opt_state = self._opt.update(g, state['opt_state'])params = optax.apply_updates(params, updates)

这里还有两件事需要注意:

  • jax.value_and_grad()是一个特殊函数,它返回一个带梯度的可微函数。
  • __init____update__都用functools.partial(jax.jit, static_argnums=0标注,这将触发即时编译器,并在运行时将它们编译成 XLA。注意,如果我们没有将forward_fn 转换成一个纯函数,这是不可能的。

最后,我们准备构建整个训练循环,它结合了迄今为止提到的所有思想和代码。

注意我们是如何合并GradientUpdate的。这只是两行代码:

  • state = updater.init(rng, data)
  • state, metrics = updater.update(state, data)

仅此而已。我希望你们现在对 JAX 及其能力有了更清楚的了解。

感谢

所展示的代码在很大程度上受到了俳句框架的官方例子的启发。已经对其进行了修改,以适应本文的需要。有关完整的示例列表,请查看官方知识库

结论

在本文中,我们看到了如何使用俳句在 JAX 开发和训练一个普通的变压器。尽管代码并不难理解,但它仍然缺乏 Pytorch 或 Tensorflow 的可读性。我强烈建议尝试一下,发现 JAX 的优点和缺点,看看它是否适合你的下一个项目。根据我的经验,JAX 非常适合需要高性能的研究应用,但对于现实项目来说还不够成熟。在我们的不和谐频道让我们知道你的想法。别忘了访问我们的博客艾夏获取类似文章。

原载于 2021 年 3 月 19 日【https://theaisummer.com】

使用 Python 构建您自己的自定义数据集

原文:https://towardsdatascience.com/build-a-your-own-custom-dataset-using-python-9296540a0178?source=collection_archive---------8-----------------------

我是如何从零开始构建数千行数据点的

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

肖恩·托马斯在 Unsplash 上拍摄的照片

D ata 是数据科学和机器学习的基础。为了分析、可视化、得出结论和建立 ML 模型,需要成千上万的数据点。在某些情况下,数据是现成的,可以免费下载。其他时候,数据无处可寻。

在数据不容易获得但需要的情况下,您将不得不求助于自己构建数据。您可以使用许多方法从 webscraping 到 API 获取这些数据。但是有时,您最终需要创建假的或“虚假的”数据。当您知道将要使用的确切功能和包含的数据类型,但是您没有数据本身时,虚拟数据会很有用。

在这里,我将向您展示我是如何创建 100,000 行虚拟数据的。这个数据也不完全是随机的。如果是的话,建造它会容易得多。有时,当从头开始创建虚拟数据时,您需要在数据中开发可能反映真实世界行为的趋势或模式。你以后会明白我的意思。

在这里注册一个中级会员,可以无限制地访问和支持像我这样的内容!在你的支持下,我赚了一小部分会费。谢谢!

构建数据集的需求

假设你正在从头开始构建一个应用程序,需要建立一个庞大的用户群来进行测试。为您提供了一个要素及其各自数据类型的列表。

这个用户群也需要在一定程度上准确地反映真实世界的用户和趋势,所以它不能完全随机。例如,您不希望一个用户拥有大学学历,但也只有 10 岁。或者,您可能不希望某个特定数据点的代表性过高,例如男性多于女性。这些都是创建数据集时需要注意的事项。

由于真实世界的数据很少是真正随机的,所以像这样的数据集将是对您将来要处理的其他数据集的一个很好的模拟。它还可以作为你希望训练的任何机器学习模型的试验场。

现在让我们开始吧,请随意跟进,我将向您展示我是如何构建这个数据集的…

构建数据集

要进行编码,首先要导入以下库:

import pandas as pd
import uuid
import random
from faker import Faker
import datetime

大小

数据集大小将为 100,000 个数据点(您可以做得更多,但可能需要更长时间来处理)。我将这个数量分配给一个常量变量,我在整个过程中都使用这个变量:

num_users = 100000

特征

我挑选了我认为在常规用户数据集中最常见的 10 个特征。这些功能和各自的数据类型是:

  • ID —标识每个用户的唯一字符串。
  • 性别 —三种选择的字符串数据类型。
  • 订阅者 —他们订阅状态的二元真/假选择。
  • Name —用户的名和姓的字符串数据类型。
  • Email—用户电子邮件地址的字符串数据类型。
  • 上次登录 —上次登录时间的字符串数据类型。
  • 出生日期 —年-月-日的字符串格式。
  • 教育 —字符串数据类型的当前教育水平。
  • Bio —随机词的短字符串描述。
  • 评分——对某事物从 1 到 5 的整数型评分。

我输入上面的内容作为初始化熊猫数据框架的特征列表:

# A list of 10 features
features = [
    "id",
    "gender",
    "subscriber",
    "name",
    "email",
    "last_login",
    "dob",
    "education",
    "bio",
    "rating"
]# Creating a DF for these features
df = pd.DataFrame(columns=features)

创建不平衡的数据

上面的一些属性通常应该包含不平衡的数据。通过一些快速的研究,可以有把握地假设,有些选择不会被同等地代表。对于更真实的数据集,需要反映这些趋势。

本能冲动

对于 ID 属性,我使用uuid库生成了 10 万次随机字符串。然后,我将它赋给数据帧中的 ID 属性。

df['id'] = [uuid.uuid4().hex for i in range(num_users)]

UUID 是一个很好的库,可以为每个用户生成唯一的 ID,因为它复制 ID 的几率非常低。在生成独特的识别字符集时,这是一个很好的选择。但是,如果您希望确保没有重复的 id,那么您可以使用以下命令对数据帧进行简单的检查:

print(df['id'].nunique()==num_users)

如果数据集中的所有 id 都是唯一的,这将返回 True

性别

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

照片由 Dainis GraverisUnsplash 上拍摄

该属性是不应该使用同样随机的选择的实例之一。因为,可以有把握地假设,每一种选择发生的可能性并不相等。

对于性别,我提供了三个选项:男性、女性和 na。然而,如果我使用 Python 的random库,那么每个选择可能会平等地显示在数据集中。事实上,男性和女性的选择要比北美多得多。所以我决定在数据中展示这种不平衡:

genders = ["male", "female", "na"]df['gender'] = random.choices(
    genders, 
    weights=(47,47,6), 
    k=num_users
)

通过使用random库,我向choices()函数提供了性别选项列表、每个选项的权重,以及由“ k 表示的要做出多少个选择。然后将它分配给 dataframe 的“ gender ”属性。我之前描述的不平衡,在权重部分表示为大约 6%的时间出现“na”选择。

订户

对于这个属性,选项可以在真和假之间随机选择。因为可以合理地预期大约一半的用户将是订户。

choice = [True, False]df['subscriber'] = random.choices(
    choice, 
    k=num_users
)

就像之前的“性别”一样,我使用了random.choices(),但是没有权重,因为这个属性可以在两个选项之间随机拆分。

名字

在这里,我使用 Faker 库为所有这些用户创建了数千个名字。Faker 库在这种情况下很棒,因为它有一个男性和女性名字的选项。为了处理性别化的名字,我创建了一个函数来根据给定的性别分配名字。

# Instantiating faker
faker = Faker()def name_gen(gender):
    """
    Quickly generates a name based on gender
    """
    if gender=='male':
        return faker.name_male()
    elif gender=='female':
        return faker.name_female()

    return faker.name()# Generating names for each user
df['name'] = [name_gen(i) for i in df['gender']]

我使用我的简单函数根据之前的“性别”属性数据快速生成一个姓名列表,并将其分配给 dataframe。

电子邮件

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

照片由 Daria NepriakhinaUnsplash 拍摄

电子邮件被证明是更棘手的属性之一。我想创建与生成的名称相关的电子邮件地址。然而,可能会有重复的机会,因为人们可以共享相同的名称,但不是相同的电子邮件。

首先,我创建了一个新函数,它可以将名字格式化成带有默认域名的电子邮件地址。它还可以通过在格式化名称的末尾添加一个随机数来处理重复的地址:

现在,为了恰当地利用这个函数的目的,我创建了一个循环,当遍历“ Name 属性时,这个循环将在必要时重新运行这个函数。该循环将继续运行该函数,直到创建一个唯一的电子邮件名称。

emails = []for name in df['name']:

    # Generating the email
    email = emailGen(name)

    # Looping until a unique email is generated
    while email in emails:

        # Creating an email with a random number
        email = emailGen(name, duplicateFound=True)

    # Attaching the new email to the list
    emails.append(email)

df['email'] = emails

在所有电子邮件生成之后,我将它们分配给 dataframe 的“ Email ”属性。您还可以使用与 IDs 相同的方法进行可选的检查,以查看每封电子邮件是否是唯一的。

上次登录

这个属性现在需要特定的格式,通过使用datetime库,这变得更加容易。在这里,我希望用户有过去一个月左右的登录历史。我使用了另一个自定义函数来帮助:

该函数主要生成两个给定时间之间的时间戳列表。它生成了一个随机时间戳列表来分配给数据帧。

出生日期

这个属性很简单,因为它类似于“上次登录”。我所做的只是通过删除小时、分钟和秒来改变时间格式。我再次使用datetime来帮助为每个用户随机选择一个日期,但是这次时间范围从 1980 年到 2006 年,以获得一个很好的年龄随机分布。下面的代码与前面的代码基本相同,但格式和日期范围不同:

教育

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

马特·拉格兰在 Unsplash 上拍摄的照片

教育”属性依赖于“出生日期”。在这些情况下,教育水平是基于使用者的年龄,而不是他们达到的最高教育水平。这是随机选择教育水平不能反映真实世界趋势的另一个属性。

我创建了另一个简单的函数,它根据今天的日期检查用户的年龄,并返回他们当前的教育水平。

生成教育水平列表后,我将它分配到数据框架中。

个人简历

对于这个属性,我想根据用户的订阅状态来改变简历的长度。如果用户是订阅者,那么我会假设他们的 bios 比非订阅者的要长。

为了适应这种情况,我构建了一个函数来检查他们的订阅状态,并从 Faker 返回一个长度不等的随机句子。

在上面的函数中,我根据订阅状态随机选择了假句子的长度。如果他们是订阅者,那么他们的简历会比平时长,反之亦然。

评级

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

乔治·帕甘三世在 Unsplash 上的照片

为了完善这个数据集,我想包含一个数字数据类型。我选择“ rating ”为整数类型。1 到 5 的评级代表任何东西,它只是为了任何自由裁量的目的而存在。

对于评分本身,我选择将 1 到 5 的分布向极端倾斜,以反映用户似乎对他们的评分更加绝对的倾向。

# The different ratings available
ratings = [1,2,3,4,5]# Weighted ratings with a skew towards the ends
df['rating'] = random.choices(
    ratings, 
    weights=(30,10,10,10,30), 
    k=num_users
)

我再次使用了random.choices()函数,但是权重偏向 1 和 5。

保存数据集

既然数据已经完成,如果您正在编写代码,那么在决定保存它之前,可以随意查看数据帧。如果一切正常,那么用这个简单的命令将数据帧保存为一个.csv文件:

df.to_csv('dataset.csv')

这将数据集作为一个相当大的 CSV 文件保存在本地目录中。如果您想检查保存的数据集,请使用以下命令查看它:

pd.read_csv('dataset.csv', index_col=0)

一切都应该看起来不错,现在,如果你愿意,你可以执行一些基本的数据可视化。如果您想了解更多关于数据可视化的知识,请查看我的以下文章:

[## 为什么我使用 Plotly 进行数据可视化

towardsdatascience.com](/how-to-use-plotly-for-data-visualization-f3d62bbcfd92)

结束语

我希望您能从我构建这个数据集的经历中学到一些新东西。如果有的话,构建它提供了一点创建 Python 函数和算法的实践。此外,我相信构建自己的数据集可以让你对数据集有更好的理解。它也许能让你准备好处理任何你需要的大量数据。

如果您愿意,您可以通过向数据分布添加更多的限制或依赖性,甚至向数据帧添加更多的属性来改进它。请随意探索这些数据或对其进行扩展!

不是中等会员?点击这里支持 Medium 和我!

Github 上的代码

https://github.com/marcosan93/Medium-Misc-Tutorials/blob/main/Build-a-Dataset.ipynb

用 FastAPI & SQLAlchemy 构建异步 python 服务

原文:https://towardsdatascience.com/build-an-async-python-service-with-fastapi-sqlalchemy-196d8792fa08?source=collection_archive---------0-----------------------

使用 FastAPI 和新的 SQLAlchemy AsyncIO 支持构建一个完全异步的 python 服务,包括异步数据库查询

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

约翰·卡梅隆Unsplash 上拍照

背景

在开始之前

在这篇博文中,我们将构建一个小的 CRUD python 应用程序(我将使用 Python 3.9,但它应该可以在 3.7+上工作)。这篇文章将关注 FastAPI 和 async SQLAlchemy 的实现和使用,而不是 AsyncIO 在 Python 中的理论和一般用法。此外,这个职位假设你有以下主题的知识:
1。Python 语言与生态系统(venvs,IDE)
2。SQL 和 SQLALchemy
3。HTTP web 服务概念

这篇文章中的所有代码都可以在这个公共知识库中找到:https://github.com/azimovMichael/my-async-app

异步编程和 python AsyncIO

异步编程是一种编程模式,它使代码能够独立于主应用程序线程运行。异步编程被用在许多用例中,比如事件驱动的系统、高度可伸缩的应用等等。

异步编程并不是一个新概念。它已经存在了一段时间,尤其是在 JavaScript 生态系统中。Python 3.4 引入了 asyncio 包,实现了 Python 对 Async/Await 设计的支持。有很多关于它的例子和教程,但我最喜欢的是:python 异步编程简介多任务不是我的强项,所以我怎么能责怪 Python 呢?(由我的同事 Danielle shaul )和Concurrent Burgers-Understand async/await(由 FastAPI 的创建者 Sebastián Ramírez )

初始设置

准备环境

首先,你需要用一个新的虚拟环境创建一个新项目。在新的 venv 里面,安装我们的第一个包——FastAPIuvicon

pip install fastapi uvicorn[standard] 

FastAPI 是一个相当新的 python(微)web 框架,内置了对异步端点的支持。

Uvicorn 是我们选择的 ASGI 服务器。ASGI 是 python WSGI 的异步姐妹。

现在我们已经准备好了一些代码。

第一个异步端点

要配置 FastAPI 服务,创建一个名为app.py的 python 模块,代码如下:

这段代码没做什么。它使用 uvicorn ASGI 服务器在端口 1111 上启动了一个 FastAPI 应用程序,没有任何自定义端点。FastAPI 自带对 OpenAPI Docs 的开箱即用支持,因此你可以运行该应用程序,并在浏览器中转至:http://127 . 0 . 0 . 1:1111/Docs。如果一切顺利,您应该会看到类似如下的网页:

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

自动生成的 API 文档的初始视图

现在我们准备创建我们的第一个异步端点。

在您的app.py文件中,添加一个名为hello_world的异步函数,并将其挂载到基本 GET 路径:

重新运行服务,您应该会看到两个新东西:在 API 文档中,您应该会看到我们的新端点,您也可以使用“试用”按钮调用它:

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

我们新终端的文档

你也可以去http://127 . 0 . 0 . 1:1111/,在我们的浏览器中看到“hello_world”响应文本。

我们有了第一个异步端点!🎆

书店 CRUD 应用程序

所以,这篇文章的目的是建立一个小的 CRUD 应用程序。出于演示的目的,我们将构建一个简单的书店应用程序,能够创建、更新和获取书籍。

SQLAlchemy 和 AsyncIO

为了使用 DB 来存储书籍,我使用 Python 的 SQLalchemy 库和支持 asyncio(aiosqlite)的 sqlite 方言

安装必要的软件包:

pip install SQLAlchemy==1.4.3 aiosqlite

SQLAlchemy 1.4.X 是一个非常新的版本,有很多升级和新特性(这是迈向备受期待的 2.0 版本的第一步),在这里详细介绍。在这篇文章中,我将主要关注新的异步支持。
SQLAlchemy****Asyncio 在 1.4 版本早期应该算是 alpha 级别(!).

一旦我们安装了 SQLAlchemy,我们需要配置我们的数据库连接。创建一个名为db的新 python 包,并在其中创建一个名为config.py : 的新模块

我们的数据库服务器是 SQLLite(一个本地test.db文件)的本地实例,我们将使用支持异步查询的aiosqlite 方言与它对话。我们正在使用新的create_async_engine函数创建 db 引擎。创建的会话标记有两个唯一的标志:expire_on_commit=*False* 确保我们的数据库实体和字段在会话提交后仍然可用,而class_=AsyncSession是新的异步会话。我们还将使用好的、旧的declarative_base来配置我们即将创建的 DB 模型。

如果你想使用不同的数据库(MySql、PostgreSQL 等),你需要安装一个支持 AsyncIO 的兼容驱动程序,并更新DATABASE_URL参数。

数据库模型

我们正在构建一个书店应用程序,所以我们的主数据库表应该是一本书,这一点也不奇怪。在db包中创建一个名为models的新包,并在其中创建一个名为book.py 的新模块。
我们的图书实体也会有一些字段——名称、作者、发行年份:

为了创建一个新的实体,我们将使用一个 DAL(数据访问层)类,它将负责这个 DB 模型的所有 sql 函数。在其中创建一个dals包和一个book_dal.py模块:

我们有 3 个函数:一个create_book函数接收我们的实体字段,并将一条新记录保存到数据库。一个get_all_books函数返回数据库中的所有书籍,一个update_book函数接收 book_id 和书籍字段的可选新值并更新它们。在update_book函数中,我们添加了一个名为synchronize_session的执行选项,它告诉会话使用fetch方法“刷新”更新的实体,以确保我们在内存中的实体将与我们更新的新值保持一致。

现在我们需要一些将使用这些 DAL 函数的新端点,所以让我们将它们添加到我们的app.py :

每个端点异步创建一个 DB 会话,一个带有会话的 BookDAL 实例,并调用相关函数(如果您的“干净代码”本能现在正在尖叫,那完全没问题,我们将在几个段落中解决它们)。

注意 PUT 方法:通过使用带有默认值的Optional类型,我们使查询参数成为可选的。

但是,为了让所有这些好东西实际工作,我们需要创建我们的书籍 表格。为此,我们将利用 FastAPI 的事件特性,并在应用启动时创建必要的表(显然,这不是我们想要在生产应用中做的事情):

现在,您可以运行应用程序,并查看 API 文档页面。它应该是这样的:

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

API 文档是交互式的,因此您可以直接从该页面调用我们的新端点。创建一本书:

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

您可以使用任何想要的输入参数。执行该命令后,您应该会在我们的 books 表中看到一条新记录。现在,让我们使用 get 端点来获取它:

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

正如你所看到的,我们的应用程序用我们的新书作出了回应,这本书被赋予了 id 1。我们现在可以使用更新图书上传功能来更新该图书:

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

然后再次获取它,并验证该书的名称实际上已经更改:

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

祝贺你,你已经创建了你的第一个完全异步的 python 服务!🎉

重构

现在我们有了一个可以工作的异步应用程序,我想使用一些 FastAPI 特性来使代码更简洁。

API 路由器

目前,我们的app.py文件包含了我们所有的端点。在现实世界的应用程序中,我们可以有更多的端点,这个文件可以变得非常大。为了避免这种情况,我们可以使用 FastAPI 的 API 路由器特性。创建一个routers包并在其中创建一个book_router.py文件:

book_router.py文件将包含与我们的 book 实体相关的所有 http 路由。现在我们需要更新我们的app.py文件来包含这个新的路由器:

您可以使用交互式 API 文档来验证我们的端点是否正常工作。

属国

你注意到我们在端点实现中使用的所有样板代码了吗?数据库会话初始化?如果我们不必为我们的每一个端点实现它,那该有多好,对吗?幸运的是,FastAPI 再次帮助了我们!

我们可以使用 FastAPIs 依赖注入功能使book_dal成为端点的依赖。这样我们只实现一次 BookDAL 的创建逻辑,然后就可以在每个端点使用了。创建一个dependencies.py文件并添加一个get_book_dal函数:

现在,我们需要使用 FastAPIs 依赖特性使这个函数成为端点的依赖项:

FastAPIs 依赖注入特性,非常强大而且易于使用。在我们的用例中,我们用它来为我们的端点注入 DAL 类,但是我们可以注入许多其他的东西——安全组件、商业智能组件等等。

验证我们的端点仍然工作,这就结束了!

结论

Python asyncio 相对较新,有很多复杂性和其他有趣的用例我们没有涉及,我鼓励你们每个人探索这个令人兴奋的新世界。

FastAPI 是一个新的现代 web 框架,强调速度、易用性,当然还有对 AsyncIO 的内置支持。

在本文中,我们构建了一个完全异步的 python 应用程序——从使用 FastAPI 的异步 http 端点到使用 SQLAlchemy 1.4 的异步 DB 查询。一个非常重要的话题是测试异步端点和代码,这个话题我们在这篇文章中没有涉及,我期待在我的下一篇文章中讨论这个话题。

为你的机器学习模型建立一个令人敬畏的用户界面

原文:https://towardsdatascience.com/build-an-awesome-ui-for-your-machine-learning-models-7fab52ecdd86?source=collection_archive---------8-----------------------

我如何为我的 PDF-to-audiobook 转换器构建一个出色的用户界面

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

PDF 到有声读物

最终界面托管在 Gradio hub!

https://gradio.app/hub/aliabd/text_speech

简介

数据科学家、数据分析师和机器学习工程师面临的一个重大挑战是向非技术人员展示和演示他们的模型。这通常需要额外的技能,包括前端开发、后端开发,有时甚至是开发运维。即使你在这些领域很熟练,完成这项工作也需要大量的时间。一些库可以为您处理这项工作,让您将更多的精力放在模型开发任务上。 Gradio 就是一个很好的例子;这是一个 Python 库,可以为每个机器学习模型生成易于使用的 UI。

本教程将探索这个库,并向您展示如何使用它来构建 PDF-to-Audiobook 演示。所以,让我们开始吧!

格拉迪欧是什么?

Gradio 是一个开源 Python 库,它允许你为机器学习模型构建一个用户界面,并在几行代码中进行部署。如果你之前在 python 中用过 Dash 或者 Streamlit,也差不多;然而,它直接与笔记本集成,不需要单独的 python 脚本。

如何运作?

用起来很简单;为了渲染一个界面,我们需要五个组件:前三个我们可以根据你的模型的用例自由定制,最后两个绑定到渲染和部署:

  1. 一个输入组件:定义输入的类型(文件、文本框、图片上传等)。)
  2. 一个输出组件:定义输出的类型(文件、文本框、标签、音频等)。)
  3. 可调用函数:应用于输入并呈现在输出中的主要推理函数。该功能可以是任何东西,从简单的打印到预先训练的模型— 查看组件列表
  4. 接口类:是一个 python 类,它将可调用函数与呈现接口中的输入进行映射。
  5. launch() 函数负责在 gradio 服务器上运行应用程序。

查看更多详细文档和 Gradio 入门页面

在幕后,Gradio 使用 Flask 框架构建接口组件并在本地运行,然后在它们的域上进行端口转发,这样您就有了一个已部署的链接(24 小时有效)。

如果你想要一个永久的链接,你可以设置一个 Gradio 高级账户,Gradio 将在他们的服务器上的 docker 镜像中托管你的整个应用程序。

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

Gradio 工作流程

调用launch()会生成一个公共的、可共享的链接,只要您的服务器打开,您就可以自由地共享它——因为它共享工作区会话依赖项。在使用 colab 笔记本的情况下,总是会自动创建一个可共享的链接。一般是这样的: XXXXX.gradio.app 。尽管该链接与 gradio 域相关联,但它只是本地服务器的代理,并不从托管界面收集或存储数据。

但是,要注意这些可共享的链接是公开的,这意味着任何人都可以访问你的界面。因此,不要通过输入函数暴露任何敏感数据,也不要允许对您的机器进行任何危险的修改。我们可以通过设置用户名和密码在 launch 函数中配置 auth 参数来解决这个问题。

如果您设置 share=False(默认),则仅创建一个本地链接,您可以通过端口转发与特定用户共享该链接。

在接下来的几个步骤中,我们将使用 Gradio 为 PDF-to-audiobook 转换器构建一个用户界面,以便更加熟悉这个库。

步骤 1:将文本转换为语音的逻辑(后端)

在下面的代码中,我利用 pdfminer 将 pdf 文件转换成纯文本。接下来,我使用谷歌文本语音转换将文本转换成音频格式。

函数 pdf_to_text()将是我们将传递给接口的可调用函数。

第二步:定义输入输出组件

根据功能和用例,您可以传递多个输入。但是,您需要将多个输入作为一个列表(数组)结构来传递。在我们的例子中,我们将只传递一个输入组件和一个输出组件。

输入将是一个文件;输出将是一个音频文件。我们可以通过指示组件名来决定输入或输出的类型,如下所示:

import gradio as griface = gr.Interface(
   fn = pdf_to_text,
   inputs = 'file',
   outputs = 'audio'
   )

第三步:启动应用

启动应用程序将初始化 flask 应用程序,并触发本地主机服务器显示该应用程序。launch()函数有许多参数,允许您共享接口、在 colab 上调试它、内联显示它或在浏览器中打开它。所以,当他们走到一起时:

当您运行上面的代码片段时,您将得到类似如下的内容:

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

在 Gradio 本地服务器上运行的接口

假设您正在使用 colab 笔记本。在这种情况下,您可以直接使用该界面,或者在页面顶部导航与 gradio 应用程序相关联的外部 URL。然后拖动任何 pdf 文件,点击提交,等待编译。

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

上传 pdf 文件并将其转换为音频

现在,我们有了输入文本的音频版本。厉害!

我们还可以使用实时 URL 来临时公开共享应用程序——正如我们前面讨论的那样,这样人们就可以尝试它,而不必担心安装依赖项和拥有在本地服务器上运行应用程序的基本技能。你需要做的就是在 launch(share = true) 函数中把 share 标志变成 True。然而,该链接将可用于 24 小时导航;如果你想让它永久托管在 Gradio 主机上,你可以考虑创建一个 Gradio 高级账户

此外,我们可以在接口函数中为同步响应将标志“live”设置为 true。你也可以添加一个标题,描述,甚至写一篇文章或报告来描述这个界面。这些参数可以接受 markdown 或 HTML 中的文本,这不是很棒吗?您可以在这里查看所有可用的界面选项

下面是将前面的功能添加到界面功能后的最终应用:

如下图所示,我们添加的段落在< p > 标签下创建了一个新 div,并带有一个名为 article 的类。

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

确认它接受 HTML 降价

部署

为了维护该界面的永久链接,您可能需要订阅 Gradio,每月 7 美元。使用与您的 GitHub 回购相同的账户进行认购至关重要。您需要做的就是选择项目存储库、分支名称、可执行文件名称以及您希望接收通知的电子邮件。

他们允许每个人在二月份使用二月份促销代码部署一个免费链接

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

部署梯度屏幕

一旦你点击启动按钮,它将建立界面-这可能需要几分钟,取决于应用程序的大小。

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

启动屏幕

最后,我们有一个永久的界面 URL,你可以在这里试用一下。

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

最终接口托管在 Gradio hub

它在移动设备上看起来也很整洁,反应灵敏👌

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

在 iPhone x 尺寸上模拟的界面

如果您导航回您的帐户,您可以选择在 Gradio Hub 发布与社区的界面。

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

用户帐户仪表板

此外,您可以从 Logs 链接访问部署错误。

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

部署后记录输出

成交记录

我希望这篇短文让您对使用 gradio 库有了全面的了解。一旦您的工作是活的,您可以有更多的反馈,最终使您能够增强模型。这是一个迭代的过程,反馈是其中必不可少的一部分。使用 gradio 可以使这一步更加舒适和灵活,使您能够专注于改进模型。如有疑问,请在下方评论区评论;我很乐意帮忙。感谢阅读!

参考

用 Shiny 和 Flexdashboard 构建交互式机器学习模型

原文:https://towardsdatascience.com/build-an-interactive-machine-learning-model-with-shiny-and-flexdashboard-6d76f59a37f9?source=collection_archive---------25-----------------------

构建房价预测交互式仪表盘的分步指南

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

作者图片

在这篇文章中,我们将介绍用 r 构建交互式机器学习仪表板的步骤。如果你不熟悉 flexdashboard 和 Shiny,请参见我以前的文章这里的以获得如何使用 flexdashboard 和 Shiny 构建基本交互式仪表板的分步教程。

要开始使用,请确保您已经安装了***shiny*** ***flexdashboard*** ***dplyr*** ***plotly*** ***DT***

仪表板概述

我们将使用美国住房数据,通过线性回归来预测房价。用户将能够控制独立变量和监测结果的变化。

仪表板将有四种不同的输出。(1) 线性回归汇总显示了模型的 R2 统计量和 F 统计量,以及参数的 p 值和标准偏差。(2) 实际与预测散点图揭示了模型预测与实际结果的匹配程度。真实值和期望值之间的差异见(3) 残差直方图;直方图的形状显示残差是否呈正态分布,以及线性回归模型是否适合该结果。用户也可以从预测表中导入数据。当更多的独立变量添加到模型中时,R 的平方增加,残差减少,所有点都更接近回归线。

让我们开始吧

步骤一。创建仪表板布局

使用**文件>新文件> R 减价>创建空文档,从 R Studio 初始化空减价。**接下来,让我们复制模板,保存它,并编织文档。

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

作者图片

这将创建一个带有侧栏、两列和两行的仪表板。

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

作者图片

第二步。收集和准备数据

我们将使用的美国住房数据。数据分为 7 列,包括 5000 次观察。变量包括房价、家庭地址和市场人口统计数据,包括人口、平均收入、平均房龄以及房间和卧室的平均数量。

让我们在仪表板的代码块下加载和准备数据。

第三步。创建用户输入

我们将在侧边栏中创建一个小部件,允许用户为线性模型选择一个或多个自变量。

SelectInput 小部件提供了一个基本的下拉菜单。指定了三个参数:(1) Name :对用户不可见,我们用它来访问小部件的值,(2) label :显示在下拉菜单上方,以及(3) choices: 用户选择的值列表。

仪表板在呈现时应如下所示:

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

作者图片

第四步。创建反应式表达式

为了限制在不同的代码块中重复运行同一个函数,我们使用了一个反应表达式。我们第一次运行反应表达式时,它会保存输出。下次我们运行反应表达式时,它会返回保存的值,而不进行任何计算。

反应表达式模型 1** 使用输入变量,运行线性回归模型,并保存输出。可以通过调用表达式的名称后跟括号来访问输出,例如 model1() 。可以从反应函数或渲染函数内部调用反应表达式。在下一节中,我们将使用渲染函数(renderPrint、renderPlotly 和 renderDataTable)来访问 model1 的值。**

第五步。用户输出

5.1 添加线性回归输出

使用一个简单的 renderPrint 函数来呈现和打印一个线性模型概要输出。我们在 render 函数中使用 model1() 反应表达式来访问我们在步骤 4 中创建的值。

5.2 添加数据表

用 DT DataTable 包构建交互式表格。这个包的主要功能是 datatable()。它创建了一个 HTML 小部件,用数据表显示 R 数据对象。让我们显示实际价格、预测价格和剩余价格三列。残差是实际值和预测值之间的差值。

5.3 添加 Plotly 散点图:预测价格与实际价格。

让我们使用renderPlotly函数创建一个散点图,显示预测房价与实际房价。X 轴代表实际值,Y 轴代表预测值。

5.4 添加残差的 Plotly 直方图

现在画出我们的线性回归模型的残差直方图。围绕零均匀分布的对称钟形直方图表明正态假设可能是正确的。

这是没有 CSS 的仪表板的样子。让我们设计仪表板的样式,调整线性回归汇总的字体和颜色以及表格格式。

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

作者图片

第六步。使用 CSS 的样式

有几种方法可以将 CSS 添加到 flexdashboard 中。因为我们只是做了一些小的调整,所以我们将 CSS 作为一个单独的代码块来添加。随着 CSS 文件变得越来越大,它会使代码更难阅读和调试,在这种情况下,最好将 CSS 作为一个外部文件。

您可以简单地在浏览器中打开仪表板,并检查它的 CSS 选择器。选择器是用来选择我们想要样式化的元素的模式。如果你不熟悉 CSS 选择器和基本的 CSS 属性,我将在参考部分为你提供一些额外的链接。

CSS 选择器

  • *.dt-center* 选择器从仪表板中选择桌子。
  • *#section-section .shiny-bound-output*选择器选择线性汇总模型的输出。

CSS 属性

  • 属性设置元素的背景颜色。
  • *color*属性定义了文本的颜色。
  • 属性指定了一个元素的字体。
  • *font-size*属性设置字体大小。

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

第 6 步—最终仪表板。作者图片

结论:

***Shiny 是一个强大的工具,用于将 R 的数据处理、可视化和机器学习功能集成到一个交互式 web 应用程序中。在构建高度个性化的基于 web 的解决方案时,Shiny 添加 CSS 代码的能力提供了一个很大的优势。Flexdashboard 提供了一个简单的框架,并且是用大家熟悉的 R markdown 编写的。Shiny 和 Flexdashboard 共同提供了一个优雅的解决方案。查看 闪亮画廊 中的一些精彩例子,获取更多灵感。

完成的仪表盘可以在下面的 页面 中找到。我希望你在制作仪表板的时候玩得开心。我欢迎并感谢您的建议和反馈!***

谢谢大家!

参考

构建一个接口来解析任何类型文档中的文本

原文:https://towardsdatascience.com/build-an-interface-to-parse-text-from-any-type-of-document-in-1-line-of-code-33f9dcf8003e?source=collection_archive---------21-----------------------

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

Unsplash 上由 Clayton Cardinalli 拍照

使用面向对象的设计模式从 txtdocxpdf 、html、 pptx 等文件中提取文本

这篇文章是关于将面向对象的设计原则应用到一个常见的数据科学任务中,从文档中提取文本。我们将构建一个可维护和可定制的接口来从多种文件类型中提取文本。我所说的接口是指一个对象,即一个类的实例,它可以在一行中从文档中提取文本,而不管文件类型如何。如果您正在构建文本挖掘应用程序,并且希望从各种文件类型中提取文本数据,那么您将需要这个功能。

有一种好的方法和一种不太好的方法来编写代码来执行这项任务。你不应该这样做:

一个很难维护的从不同文件格式中解析文本的代码示例。

该函数有多种用途:确定文件类型,选择使用 if-elif-else 结构执行哪个逻辑路径,最后执行该路径。从软件工程的角度来看,这是有问题的,因为它违反了单一责任原则[1]。

假设您想要添加新的逻辑路径或者改变现有的路径以提供更多的功能,或者因为一个包更新迫使您更改代码;为了做到这一点,你必须修改负责解析所有文件类型的代码。这增加了 bug 完全破坏应用程序的可能性,而不是部分破坏。此外,你可能很快就会得到一个包含数十条 elif 语句的巨大函数:你添加的越多,你就越有可能引入一个 bug,而且没有人(包括你自己)会喜欢试图理解在使用、修改或修复代码时发生了什么。我们需要把它分解成几个部分。

我们将通过使用工厂方法模式来重构这段代码,这是一种在 90 年代流行的面向对象的设计模式,用于生成一个类的新实例。在我们的例子中,我们想要生成的对象将是一个字符串,但是最初,我们并不确切地知道如何去做,因为这取决于我们想要读取的文件类型。

工厂模式方法定义了一个接受任何文件类型的接口,然后将对象生成的实现委托给一个子类或函数。为了澄清这个概念,让我们来谈谈下面的例子中发生了什么。

使用工厂方法模式重构

定义一个通用接口来解析 txt 和 docx 文件。

DocParser 有一个方法 *parse。*当用户用文件路径调用 parse 时,会发生一系列事件:

  1. 路径传递给第 6 行中的函数 get_format ,返回值存储在变量解析器中。
  2. get_format 从路径中提取文件扩展名,并在其返回语句中将其传递给另一个函数 get_parser,
  3. get_parser 内部,使用一个 if-elif-else 结构,根据文件扩展名执行三个逻辑路径之一。如果提供了有效的文件扩展名,则返回两个函数之一, parse_txtparse_docx
  4. 此时,第 6 行中定义的变量 parser 现在存储的是 parse_txtparse_docx。第 7 行,将文件路径传递给存储在解析器中的函数,并将结果字符串对象返回给用户。

这就是为什么我们将 DocParser 的实例称为接口的原因,因为它唯一的职责是充当用户和生成用户所请求的对象的逻辑之间的接口。接收到文件类型后,接口将确定文件类型、选择解析函数和实际生成对象的责任传递给其他函数。这就是我们所说的接口推迟了类的实现的意思。

函数 parse_txtparse_docx 被称为该类的具体实现,它们是为给定文件类型生成字符串对象的部分。

现在,最初的功能已经被分解为多个部分,每个部分都有一个单一的职责。为什么这样更好?

我们现在可以添加和更改我们接口的功能,而不必触及代码的其他部分,我们只需定义一个新的具体实现作为一个函数,并添加另一个 elif 语句到 *get_parser。*这更容易维护,尤其是当您想要解析的文件类型数量增加时,这意味着如果一部分停止工作,其余的代码将不受影响。下面是如何修改上面的例子来提供解析 pdf 、 *html、*和 pptx 文件的功能。

解析 pdf、html 和 pptx 文件的额外功能可以很容易地添加到界面中。

我们做的第一件事是向 get_parser 添加更多的 elif 语句,然而,由于我们在每个逻辑路径中只有一个 return 语句,函数仍然可读。然后我们定义了三个新函数 parse_pdf、 parse_htmlparse_pptx ,而原来的解析函数保持不变。很容易理解如何继续这种模式来解析任何类型的文件。

使用公共界面

通过将上述代码保存在一个文件中, parse_file.py,我们可以用一个简单的 import 语句将接口导入到我们的应用程序中。我们需要做的就是实例化一个 DocParser 对象,我们可以使用 parse 方法在一行中读取我们定义的所有文件类型的文本,如下面的第 17 行所示。

如何使用 DocParser 的实例来解析每个不同文件类型的文本。

在这个例子中,我们在一个循环中调用 parse 方法,路径指向 *txt、docx、pdf、html、*和 pptx 文件,并将结果打印到终端。你可以在项目 GitHub repo 访问测试文件,我在这里从下载了 html 文本文件。输出如下面的动画所示。

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

每个测试文件中包含的文本被顺序打印到终端上(我添加了一个 2 秒钟的 sleep 命令,以使动画更容易观看)。作者的动画。

如您所见, DocParser 的单个实例可以解析我们传递给它的所有五种文件类型。 pdfhtml 文件包含一些空白,所以如果你愿意,你可以去编辑 parse_pdfparse_html 来移除这个,安全地知道你的其他解析功能将保持不变。

结论

我们已经介绍了如何使用工厂方法设计模式来构建可维护的接口,该接口可以解析许多不同类型的文档,使我们能够在文本挖掘项目中利用尽可能多的数据源。一旦构建了接口,我们就可以用它在一行代码中提取文本,保持应用程序文件的整洁。

请注意,这种模式是通用的,可以在任何用于生成对象的逻辑依赖于某些参数的情况下使用,这些参数通常由应用程序的用户决定。在其他地方,我发现这对于为 API 提供额外的功能非常有用,这样它就可以接受各种请求负载。稍加考虑,您可能会找到在自己的应用程序中使用这种设计模式的方法,保持它们的整洁、可维护性和通用性。

[1] 单一责任原则

[2] 设计模式:可复用面向对象软件的要素

我们连线: Linkedin

建立一个无与伦比的棋盘游戏人工智能

原文:https://towardsdatascience.com/build-an-unbeatable-board-game-ai-68719308a17?source=collection_archive---------18-----------------------

一个详细的指南,以编码一个复杂的算法,掌握回合制战略游戏

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

阿瑟·奥西皮扬在 Unsplash 上的照片

介绍

如果你想尝试人工智能,甚至是一点博弈论,那么建造一台赢棋的机器是一个很好的项目。

我实现了这个 AI 来玩 Connect Four,但它适用于许多不同的游戏。不过,我还是推荐像 Connect Four 这样的游戏,因为游戏机制很简单。

以国际象棋为例:Minimax 可以下棋,但你有几个不同的棋子,可以走不同的棋,有捕捉,阉割,检查和将死等。而使用 Connect Four,您所能做的就是将一片放入一列中。这意味着每一步棋都非常简单,可以用一个整数来表示(棋子所在列的索引),棋盘只是一个 2D 数组。

像井字游戏这样的游戏也是一个不错的选择,但是即使在那里,你也必须考虑列和行。

现在让我们来谈谈这个人工智能将如何实际工作:极大极小算法。

Minimax 如何工作

在博弈论中,极大极小是一种递归算法,它最大化自己的机会,同时最小化对手的机会。因此,这个名字不言自明。

假设对手先动。一旦移动完成,Minimax 会查看游戏棋盘的状态,然后考虑它可能做出的每一步棋。对于每一个结果游戏状态,它会考虑对手可能采取的每一个可能的行动,等等…

这将一直进行,直到找到一个终端游戏状态(游戏获胜或棋盘已满),或者直到达到某个深度。深度是有上限的,否则所有可能的游戏状态的树会快速增长,计算起来会变得非常慢。

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

最小最大算法考虑了所有可能的棋盘状态(所有图片由作者提供)

现在,在每个级别,这些棋盘状态中的每一个都将根据一组参数(由您定义)分配一个分数,以确定该状态对于最大化玩家或最小化玩家(无论轮到谁)在机会方面有多“好”或“坏”。例如,当前玩家的获胜棋盘将被分配极高的分数,而对手的获胜棋盘将被分配极低的分数。还必须分配中间分数,因为除了最简单的游戏,大多数棋都不是赢棋。

然后,算法选择最终导致 AI 得分最高而对手得分最低的棋盘状态。这就是它将要采取的行动。

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

选择最高和最低分数的极大极小算法

履行

设置

为了能够编写极大极小算法,你需要一些变量和函数,它们的实现取决于你的棋盘游戏:

npc => In my case, just a character that represents the AI's piece
opponent => Another character to represent the opponent's pieceisTerminalNode() => To determine if a board is terminal (boolean)
isWinningMove()  => To determine if a move wins the game (boolean)
getValidMoves()  => To get all possible valid moves (array)
score()          => To calculate a board state's score (integer)
tempBoard()      => To make a copy of the game board (2D array)
makeMove()       => Make a hypothetical move on the board (void)

因为我的游戏是 Connect Four,所以我的 isTerminalNode() 方法调用一系列帮助器方法来完成以下任务:

  1. 检查一行中是否有四个(对角、垂直或水平)。
  2. 检查棋盘是否已满,不能再移动了。

您需要 getValidMoves() ,因为一列可能会变满,因此 Minimax 不应该试图在该列中移动。

并且 score() 方法调用更多的帮助器方法,这些方法最终为当前棋盘分配一个分数。这是我如何分配分数的(这是你可以支付的——调整损失函数):

Current player gets 4 in a row                              => 100
Current player gets 3 in a row with an empty adjacent space => 5
Current player gets 2 in a row with 2 empty adjacent spaces => 2
Opponent has 3 in a row with an empty adjacent space        => -500

这将确保你的人工智能把它的棋子一个接一个地摆放,同时阻止对手连续获得 4 个。

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

照片由真诚媒体Unsplash 上拍摄

该算法

我用 Java 编写了我的代码,但是我打算在这里把它翻译成一种 Java/Python 风格的伪代码,以保持这篇文章的语言不可知。

  • 在第一部分中,检索所有可以进行的有效移动,并检查棋盘是否处于终止状态。
  • 我们每次都会减少深度,所以当深度为 0 或者棋盘是终点时,检查游戏是 NPC(非玩家角色)赢了还是对手赢了。
  • 如果是,分别返回一个很高或很低的分数。如果没有,返回该板的分数。
minimax(board, depth, maximisingPlayer)
    int[] validCols = *getValidMoves*(board)
    boolean isTerminalNode = *isTerminalNode*(board)
    if (depth == 0 || isTerminalNode)
        if (isTerminalNode)
            if (*isWinningMove*(board, *npc*))
                return null, 1000000000
            else if (*isWinningMove*(board, *opponent*))
                return null, -2000000000
            else
                return null, 0
        else
            return null, *score*(board, *npc)*

注意这个函数返回两件事:分数和移动。

  • 创建两个变量:移动(有效移动列表中的随机移动)和(分数)
  • 现在检查当前回合是针对我们的 AI(我们想要最大化的玩家)还是对手(我们想要最小化的玩家)。这作为一个参数传递到函数中—检查上面代码块中的签名。
  • 如果轮到最大化玩家,将设置为非常低的值,比如负无穷大。
  • 接下来,遍历有效走法的数组,对每个走法进行走法(在棋盘的副本上,以便不改变原始棋盘的状态——我定义了一个函数来浅层复制我的棋盘),递归调用 *minimax(),*传入新的游戏棋盘,深度减 1 并为 false(因为现在我们要为最小化玩家走法)。调用末尾的[1]表示我们希望返回第二个东西,即分数。
  • 如果 minimax() 返回的分数大于负无穷大,则给 value 赋值并移动。
 int move = validCols[(Math.*random*() * validCols.length)]
    double value if (maximisingPlayer)
        value = *NEGATIVE_INFINITY*;
        for (int validCol : validCols)
            char[][] tempBoard = *tempBoard*(board)
            *makeMove*(validCol, tempBoard, *npc*, *ROWS*)
            int newScore = *minimax*(tempBoard, depth - 1, false)[1]
            if (newScore > value)
                value = newScore
                move = validCol

最后,在为最小化玩家调用函数的情况下,进行完全相反的操作。

 else
        value = *POSITIVE_INFINITY*
        for (int validCol : validCols)
            char[][] tempBoard = *tempBoard*(board)
            *makeMove*(validCol, tempBoard, *opponent*, *ROWS*)
            int newScore = *minimax*(tempBoard, depth - 1, true)[1]
            if (newScore < value)
                value = newScore
                move = validCol return move, value

返回的移动是你最终想要的。就这么简单。

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

照片由马库斯·温克勒Unsplash 上拍摄

最佳化

你的人工智能对可能的棋盘看得越深,它就越复杂。然而,正如我前面提到的,这需要很高的计算成本。

当然,你可以通过一种叫做 alpha-beta 剪枝的方法来优化 Minimax 算法,我将在另一篇文章中讨论这一点,当它出来的时候在这里链接。

结论

你会注意到,有了这些简单的规则,人工智能开始表现出优秀玩家推荐的行为。例如,当我的 AI 第一个移动的时候,它总是把它的棋子放在中间。我从来没有明确地编程让它这么做,这只是让人工智能的可能性最大化的一步。

我已经把游戏发给了我的一个朋友,他认为自己是一个相当强大的 Connect Four 玩家,他是那个称人工智能为“不可战胜”的人。

这应该给你实现你自己的棋盘游戏-粉碎人工智能所需要的东西。如果你真的做了一些很棒的东西,请留下回复。

同时,祝您编码愉快!

资源

凯斯加利连接四个极小极大艾 https://www.youtube.com/watch?v=MMLtza3CZFM

辉煌 极大极小算法https://brilliant.org/wiki/minimax/

FreeCodeCampMinimax 算法https://www . FreeCodeCamp . org/news/playing-strategy-games-with-Minimax-4 ECB 83 b 39 B4 b/

用 Diffbot 构建和分析知识图

原文:https://towardsdatascience.com/build-and-analyze-knowledge-graphs-with-diffbot-2af83065ade0?source=collection_archive---------15-----------------------

如何用知识图谱回答疑难问题

动机

当你想进一步了解一个人的时候,你通常会怎么做?你可能会决定使用维基百科等网站来了解一个人。

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

作者图片

但是,文本可能会很长,您可能需要一段时间才能获得所需的信息。

既然我们更擅长吸收图像形式的信息而不是文本,那么如果你在搜索史蒂夫·乔布斯时能得到如下的图表岂不是很好?

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

作者图片

这时 Diffbot 就派上用场了。在本文中,您将学习如何使用 Diffbot 构建和分析知识图。

什么是知识图?

知识图表示实体的集合,这些实体是对象、事件、抽象概念,并说明它们之间的关系。谷歌使用知识图表来增强其搜索引擎的结果。

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

作者图片

用 Diffbot 访问知识图

Diffbot 是世界上最大的知识图,允许你访问网络上万亿个相关事实。

从 Diffbot 开始,注册 14 天的免费试用。这次免费试用将允许您搜索 Diffbot 的知识图谱。

登录后,单击搜索选项搜索 Diffbot 知识图。

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

作者图片

分析苹果的员工

你有没有想过:

  • 苹果的员工去了哪所学校,
  • 他们的专业是什么,
  • 苹果公司最受欢迎的角色是什么?

我们可以使用 Diffbot 的搜索来回答这些问题。首先通过以下方式搜索苹果公司的 Diffbot ID:

  • 选择“组织”
  • 按“包含”apple 的“名称”过滤
  • 点击“搜索”

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

作者图片

您将看到 61,820 个与苹果相关的结果。由于我们只对苹果公司感兴趣,请点击“苹果公司”

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

作者图片

您将被引导至显示 Apple Inc .具体信息的网站。复制该网站 URL 中的 ID。在下面的 URL 中找到的 ID 是“EHb0_0NEcMwyY8b083taTTw”。

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

作者图片

要搜索 Apple Inc .的所有员工,请单击查询选项卡,然后传递:

type:Person employments.employer.id:”EHb0_0NEcMwyY8b083taTTw”

…到搜索框。

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

作者图片

点击“搜索”后,Diffbot 将返回超过 200k 的结果。

获取知识图

单击右上角的图表图标,查看结果的知识图表。

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

作者图片

而且你应该会看到如下的知识图!这张图表显示了苹果公司和其他实体之间的关系。与这些实体的关系可以是“城市”、“雇主”、“市区”、“机构”等

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

作者图片

请注意,此图仅显示了前 25 个结果。要获得接下来 25 个最重要结果的知识图表,请单击图表顶部的“更多”按钮。

为了更好地查看某个节点,可以将其移动到另一个位置。

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

作者 GIF

要查看每个实体的信息,请单击该实体。您应该会看到如下信息:

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

作者 GIF

获取 JSON

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

作者图片

要获得 JSON 格式的结果,单击右上角的 JSON 选项卡。

寻找苹果员工的顶级技能

苹果的员工有哪些技能?我们可以通过查看 JSON 文件中的技能部分找到答案。

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

作者图片

一个员工可以拥有多种技能,不同的员工拥有不同的技能。有没有一种方法可以总结这些技巧?这可以通过在前面的查询中添加facet:skills.name来轻松实现:

type:Person employments.employer.id:"EHb0_0NEcMwyY8b083taTTw" facet:skills.name
  • facet将显示关于指定字段的值的汇总数据
  • skills.name告诉 Diffbot 访问 JSON 文件中skills字段内的name字段。

苹果员工的 50 大技能:

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

作者图片

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

作者图片

获取专业

苹果公司的员工在大学时都是学什么专业的?我们可以通过在查询中添加facet:educations.major.name来找出答案:

type:Person employments.employer.id:"EHb0_0NEcMwyY8b083taTTw" facet:educations.major.name

苹果员工最喜欢的 25 个专业是:

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

作者图片

从上图中,我们可以看到热门专业计算机科学、工商管理相关。这一结果并不令人惊讶,因为苹果是一家专门从事消费电子产品、计算机软件和在线服务的技术公司。

得到学校

苹果的员工上过哪些顶尖的学校?这可以通过在查询中添加facet:educations.institution.name来找到:

type:Person employments.employer.id:"EHb0_0NEcMwyY8b083taTTw" facet:educations.institution.name

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

作者图片

苹果员工去过的前 5 所学校是:

  • 斯坦福大学
  • 加州大学伯克利分校
  • SJSU
  • 哈佛大学
  • 凤凰城大学

我们可以看到很多这样的大学都是全国顶尖的大学,而且都位于加州。这并不意味着你需要去这些顶尖大学才能被苹果录取。这确实意味着,如果你去这些大学,你可能有更高的机会被苹果公司录取。

分析人工智能公司

你有没有想过:

  • 人工智能公司的收入是多少,
  • 这些公司位于哪些国家,
  • 这些公司有多少员工?

让我们用 Diffbot 来回答这些问题。从选择“组织”开始,然后按行业过滤搜索。单击下拉框并向下滚动,直到您看到“人工智能公司”选项。

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

作者图片

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

作者图片

搜索结果中显示的前 25 家公司的知识图表:

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

作者图片

热门描述符

这些人工智能公司排名前 50 的描述符是什么?让我们通过将facet: descriptors添加到前面的查询中来找出答案:

type:Organization industries:"Artificial Intelligence Companies" facet: descriptors

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

作者图片

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

作者图片

收入

这些公司的收入如何?

type:Organization industries:"Artificial Intelligence Companies" facet: revenue.value

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

作者图片

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

作者图片

这些公司中的大多数收入在10 万到 100 万美元之间。

要获取收入在特定范围内的公司,可以将以下内容添加到查询中:

type:Organization industries:"Artificial Intelligence Companies" revenue.value>=100000 revenue.value<500000

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

作者图片

与人工智能相关的公司数量最多的国家

另一件有趣的事情是,哪些国家拥有最多的人工智能公司。

type:Organization industries:"Artificial Intelligence Companies" facet: location.country.name

前 25 个国家的位置:

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

作者图片

人工智能公司数量最多的前 5 个国家的名称:

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

作者图片

雇员人数

这些公司的平均员工人数是多少?

type:Organization industries:"Artificial Intelligence Companies" facet: nbEmployees

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

作者图片

大多数公司的员工人数从 5 到 100 不等。员工超过 10 万人的公司只有 4 家。它们是什么?

让我们通过点击图表下方表格中的数字来找出答案:

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

作者图片

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

作者图片

全球只有 4 家公司员工超过10 万人,而且都是日本公司!这可能是因为许多日本工人忠于他们的公司。

这些结果很酷。但是,如果您想从 Diffbot 中导出数据以进行进一步分析,该怎么办呢?这可以使用 Python 或命令行来完成。

从 Diffbot 下载数据

使用 Python 下载

要使用知识图 API,请向以下端点发出 HTTP GET 请求:

https://kg.diffbot.com/kg/dql_endpoint?token=...&type=query&query=...

我们还可以创建一个返回端点的函数。该函数采用:

  • Diffbot 的 API 令牌
  • 我们想要下载的 JSON 文件的 URL

您可以在控制面板的右上角找到该令牌。

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

作者图片

单击右上角的 JSON 选项卡可以找到 JSON 文件的 URL。

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

作者图片

使用您被定向到的页面的 URL 作为函数get_diffbot_json的第二个参数。

您将获得一个可下载的 URL:

[https://kg.diffbot.com/kg/dql_endpoint?token=your-token&type=query&query=type%3APerson+id%3A%22EyauXV2QZOW2fEP8Cb_Hoxg%22&from=0&size=25&output_format=](https://kg.diffbot.com/kg/dql_endpoint?token=c2887c50296c48408adef6ca12ce831c&type=query&query=type%3APerson+id%3A%22EyauXV2QZOW2fEP8Cb_Hoxg%22&from=0&size=25&output_format=)

要下载由get_diffbot_json返回的 URL 中的数据,使用请求库:

并且 JSON 文件将保存在您的本地机器中!

使用命令行下载

您也可以使用wget在您的终端上下载 JSON 文件:

wget [https://kg.diffbot.com/kg/dql_endpoint?token=your-tokenc&type=query&query=type%3APerson+id%3A%22EyauXV2QZOW2fEP8Cb_Hoxg%22&from=0&size=25&output_format=](https://kg.diffbot.com/kg/dql_endpoint?token=c2887c50296c48408adef6ca12ce831c&type=query&query=type%3APerson+id%3A%22EyauXV2QZOW2fEP8Cb_Hoxg%22&from=0&size=25&output_format=)

结论

恭喜你!您刚刚学习了如何使用 Diffbot 构建知识图和总结基本事实。希望这篇文章能给你动力去探索你感兴趣的其他话题。

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

这个回购如果你想检查我写的所有文章的代码。在 Medium 上关注我,了解我的最新数据科学文章,例如:

[## 如何用 Excalidraw 勾画您的数据科学想法

towardsdatascience.com](/how-to-sketch-your-data-science-ideas-with-excalidraw-a993d049f55c)

为你的机器学习模型构建并运行一个 Docker 容器

原文:https://towardsdatascience.com/build-and-run-a-docker-container-for-your-machine-learning-model-60209c2d7a7f?source=collection_archive---------0-----------------------

使用简单的机器学习模型快速简单地构建 Docker 容器

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

Annamária Borsos 摄影

本文的想法是用一个简单的机器学习模型快速简单地构建一个 Docker 容器并运行它。在阅读本文之前,请务必阅读为什么使用 Docker 进行机器学习Docker 的快速安装和首次使用

为了开始为机器学习模型构建 Docker 容器,让我们考虑三个文件: Dockerfile、train.py、inference.py.

你可以在 GitHub 上找到所有文件。

train.py 是一个 python 脚本,它接收并规范化 csv 文件(train.csv)中的 EEG 数据,并训练两个模型对数据进行分类(使用 scikit-learn)。该脚本保存了两个模型:线性判别分析(clf_lda)和神经网络多层感知器(clf_NN)。

将调用 inference.py 通过加载之前创建的两个模型进行批量推理。该应用程序将对来自 csv 文件(test.csv)的新 EEG 数据进行标准化,对数据集进行推理,并打印分类准确性和预测。

让我们创建一个简单的 Dockerfile ,使用 jupyter/scipy-notebook 图像作为我们的基本图像。我们需要安装 joblib 来允许我们的训练模型的序列化和反序列化。我们将 train.csv、test.csv、train.py 和 inference.py 文件复制到映像中。然后,我们运行 train.py ,它将拟合和序列化机器学习模型,作为我们映像构建过程的一部分,这提供了几个优势,例如在过程开始时进行调试的能力,使用 Docker 映像 ID 进行跟踪或使用不同的版本。

为了构建映像,我们在终端中运行以下命令:

docker build -t docker-ml-model -f Dockerfile .

输出如下所示:

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

是时候对新数据执行推断了(test.csv):

docker run docker-ml-model python3 inference.py

输出如下所示:

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

我们可以做一些事情来改善我们的集装箱化体验。例如,我们可以使用 docker 文件中的 WORKDIR 绑定容器中的主机目录:

推论. py 中,我们可以决定保存一个输出. csv 文件,其中包含 X_test 数据:

当您构建并运行它时,您应该能够在 /mydata 中看到 output.csv 文件:

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

我们还可以在 Dockerfile 文件中添加 VOLUME 指令,生成一个将创建新挂载点的映像:

使用我们指定的名称, VOLUME 指令创建一个挂载点,该挂载点被标记为保存从本地主机或其他容器外部挂载的卷,我们在这些容器中找到我们想要处理的数据。

对于未来的开发,可能有必要从一开始就设置环境变量,只需在构建时设置一次,以便持久化训练好的模型,并可能向特定位置添加额外的数据或元数据。设置环境变量的好处是避免在代码中到处都是必要路径的硬代码,并且在一个商定的目录结构上更好地与他人共享您的工作。

让我们再举一个例子,用一个新的 docker 文件:

我们需要给 train.py 添加环境变量:

推论. py :

下一步是什么?

我们的目标是通过简单的机器学习模型,产生快速简单的步骤来构建 Docker 容器。构建就像做一个docker build-t my-docker-image 一样简单。

从这一步开始,我们可以开始部署我们的模型,这将更加简单,并消除发布和扩展您的机器学习模型的恐惧。下一步是用一个 CI/CD 工具(持续集成/持续交付)产生一个工作流,比如 Jenkins。得益于这种方法,可以在任何地方构建和服务 docker 容器,并公开 REST API,以便外部利益相关者可以使用它。如果您正在训练一个需要高计算需求的深度学习模型,您可以将容器移动到高性能计算服务器或您选择的任何平台,如内部、私有或公共云。这个想法是,您可以扩展您的模型,但也可以创建弹性部署,因为您可以跨区域/可用性区域扩展容器。

我希望您能看到容器提供的极大的简单性和灵活性。通过容器化你的机器/深度学习应用,你可以让它对世界可见。下一步是在云中部署它并公开它。在某些时候,您需要借助 Red Hat open shift(Kubernetes 发行版)等技术来协调、监控和扩展您的容器,以便为数百万用户提供服务。

来源

https://docs.docker.com/engine/reference/builder/

https://mlinproduction.com/docker-for-ml-part-3/

https://theaisummer.com/docker/

通过修剪构建更好的决策树

原文:https://towardsdatascience.com/build-better-decision-trees-with-pruning-8f467e73b107?source=collection_archive---------3-----------------------

通过限制最大深度和修剪减少决策树的过度拟合和复杂性

作者:爱德华·克鲁格希德尔·邦戈尔道格拉斯·富兰克林

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

照片由 Ales Krivec 在 Unsplash 上拍摄

在另一篇文章 中,我们讨论了决策树或 CART 算法的基本概念,以及在回归或分类问题中使用决策树的优势和局限性。

点击这里阅读更多内容:

[## 了解决策树是如何生长的

towardsdatascience.com](/learn-how-decision-trees-are-grown-22bc3d22fb51)

有关决策树的视频介绍,请查看本 8 分钟课程:

**在本文中,**我们将重点关注:

  • 决策树中的过度拟合
  • 限制最大深度如何防止决策树过拟合
  • 成本复杂性修剪如何能够防止过度适应决策树
  • Python 中实现一棵全树、一棵有限最大深度树和一棵修剪树
  • 修剪的优点限制

下面使用的 代码 在本 GitHub 资源库 中可用。

过度拟合和决策树

决策树容易过度拟合。如果我们允许决策树增长到其最大深度,它将总是过度适应训练数据。

当决策树被训练为完全适合训练数据集中的所有样本时,该决策树是过度适合的。您可以调整一些参数,如 min_samples_leaf ,以最小化默认过拟合。这种类型的调整被称为**预修剪,**但是超出了本文的范围。

你让你的树长得越深,决策规则的序列就变得越复杂。给一棵树指定一个最大深度可以简化它并防止过度拟合。

让我们来看看一个没有使用 Python 修剪的完整决策树:

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

这些 ipynb 单元包含导入、数据文件的路径以及构建和交叉验证树模型所需的变量。

现在让我们用 scikit-learn 来种出我们的第一棵树。

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

在这里,我们创建了full_tree,一个 scikit-learns DecisionTreeClassifier的实例。然后,我们将模型与训练数据进行拟合。

接下来,我们使用 matplotlib 来确定可视化的大小,使用 scikit-learn 的plot_tree来绘制我们的树。

注意这棵树的大小。这个二元分类器中有多少规则?

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

如果你数的是“18”,你答对了。下面是这棵树遇到测试数据时的分类报告。

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

注意精确度,91。在我们构建下两棵树时,请记住这一点。

默认情况下,树会一直生长,直到每个叶节点中的所有点都来自同一个类。换句话说,直到每片叶子都

怎样才能产生一个规则更少结果更好的树?

如何用最优最大深度简化决策树

现在让我们建立一棵树,并限制其最大深度。

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

在上面的第一个单元格中,我们找到了整个树的深度,并将其保存为max_depth。我们这样做是为了从 1 → max_depth建立一个网格搜索。

这种网格搜索建立深度范围为 1 → 7 的树,并比较每棵树的训练精度,以找到产生最高训练精度的深度。

最精确的树的深度为 4,如下图所示。

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

这棵树有 10 条规则。这意味着它是一个比完整树更简单的模型。

它在测试数据上的表现如何?

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

看那个!规则更少,准确率更高。当我们限制我们的最大深度时,我们确实建造了一个更好的模型。

然而,有时设置一个最大深度可能会过于苛刻,导致拟合不足。

我们如何以更精确的方式调整我们的树模型?

什么是修剪?

修剪是一种用于减少过度拟合的技术。修剪还通过删除最弱的规则来简化决策树。修剪通常分为:

  • 预修剪(提前停止)在树完成对训练集的分类之前停止树,
  • 后期修剪允许树对训练集进行完美的分类,然后对树进行修剪。

在本文中,我们将重点关注后期修剪

修剪从一棵未修剪的树开始,获取一系列子树(修剪过的树),并通过交叉验证选择最佳的一棵。

修剪应确保以下几点:

  • 子树是最优的,这意味着它在交叉验证的训练集上具有最高的准确性。(采油树可以针对对工程师最重要的任何参数进行优化,但并不总是精确的)
  • 对最优子树的搜索在计算上应该是易处理的。

在 scikit-learns DecisionTreeClassifier中,ccp_alpha成本复杂度参数。

本质上,修剪递归地找到具有“最弱链接”的节点最弱的链路由有效α来表征,其中具有最小有效α的节点首先被修剪。

数学上,树 T 的成本复杂性度量由下式给出:

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

  • R(T) —叶节点的总训练误差
  • |T| —叶节点数
  • α —复杂度参数(整数)

随着 alpha 的增加,更多的树被修剪,这增加了树叶的总杂质。

如果只是试图减少训练误差 R(T) ,会导致树相对更大(叶节点更多),造成过拟合。

成本复杂性修剪生成一系列树,其中子树 Tₜ 的成本复杂性度量为:

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

参数 α 通过控制叶节点的数量来降低树的复杂度,最终减少过拟合。

最终选择哪个子树取决于α。如果α= 0*,那么将选择最大的树,因为复杂度惩罚项实质上被丢弃了。当α接近无穷大时,将选择大小为 1 的树,即单个根节点。*

为了了解什么样的ccp_alpha值将有助于减小树的大小,scikit-learn 提供了一个函数cost_complexity_pruning_path,它返回修剪过程中每一步的有效 alphas 和相应的总叶子杂质。

让我们构建最终的树模型,看看它的表现如何。

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

上面的每个ccp_alpha代表一个最优子树。我们再次构建网格搜索来比较不同的树。这里,网格搜索比较每个最优子树的训练精度。

我们看到最准确的子树是由ccp_alpha,0.0059340658…

现在让我们画出这棵修剪过的树。

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

这个模型只包含 5 条规则!

与以前的决策树图相比,修剪后的模型不太复杂,更容易解释,也更容易理解。

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

使用最大深度限制树的一半规则,我们已经达到了相同的精度。我们又一次改进了我们的模型!这一次,我们在保持性能的同时降低了复杂性。

修剪决策树的优势

  • 修剪降低了最终树的复杂性,从而减少了过度拟合。
  • 可解释性——修剪过的树更短,更简单,也更容易解释。

修剪的局限性

类似于套索正则化,没有真正的劣势。然而,修剪带来了很高的计算成本。

资源

进一步阅读

要继续学习相关概念,请查看这篇由 Aliaksandr Kazlou 撰写的关于随机森林和过度适配的文章。

用 LASSO 构建更好的回归模型

原文:https://towardsdatascience.com/build-better-regression-models-with-lasso-271ce0f22bd?source=collection_archive---------10-----------------------

学习如何在 SciKit 中实现 LASSO 学习提高线性回归的可解释性和性能

爱德华·克鲁格艾琳·欧菲琳

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

照片由普里西拉·杜·普里兹Unsplash 拍摄

在本文中,我们将介绍使用 LASSO 回归需要了解的基础知识:

  • 我们将简要介绍拉索背后的理论
  • 我们将讨论为什么正确使用套索需要具有相似比例的特征。
  • 我们将讲述如何用标准化特征解释线性回归和套索回归中的系数
  • 我们将介绍数据集,并给出一些见解为什么 LASSO 帮助
  • 我们将在 SciKit-Learn 中展示如何实现线性回归、套索回归和岭回归。

浏览理论的表面

在上一篇文章中,我们讨论了 LASSO 如何以及为什么提高广义线性模型的可解释性和准确性。我们将在这里重述基础知识,但是如果你有兴趣深入研究这个理论,可以看看下面的文章。

https://edkruegerdata.com/lasso-increases-the-interpretability-and-accuracy-of-linear-models-c1b340561c10

我们可以使用套索通过选择特征来改善模型中的过度拟合。它与线性回归,逻辑回归和其他几个模型。本质上,如果模型有系数,可以使用 LASSO。与其他特征选择技术不同,LASSO 中的特征选择是内生的。即,它出现在模型的算法内部。LASSO 不是查看要素的每个组合或实施逐步子集选择,而是在算法中选择要素,自动生成子集选择。

LASSO 的工作原理是对损失函数应用 L1 罚函数。由于 L1 罚函数所隐含的约束区域的形状,LASSO 可能选择系数的备用估计。即,一些系数可能被设置为 0,并且实际上,这些特征被移除。惩罚系数越大,趋势越明显。

具有较少的特征通常会减少模型中的过度拟合,这可能会提高模型的可解释性。提高模型的复杂性通常会减少测试误差。

数据集

我们将使用 SciKit-Learn 的糖尿病数据集演示 LASSO。你可以在这里找到数据集【1】。该数据集非常适合演示 LASSO,因为它的所有要素都是数值型的。当分类变量存在时,可以使用 LASSO,但当缩放时,它们可能很难解释。

数据集中的目标是对糖尿病进展的数值评估。这些特征包括年龄、性别、体重指数(身体质量指数)、血压和标记为“s1”到“s6”的六个血清测量值。

使用与StandardScaler使用的过程相同的过程对特征进行缩放。但是,整个数据集已被用于计算每个要素的平均值和标准差,因此从技术上讲,存在一些可能无害的数据泄漏。我们将使用管道中的StandardScaler来重新调整数据集,该管道将仅使用训练集来重新调整数据,以计算平均值和标准差。这将使我们的演示适用于尚未缩放的数据。

我们来看看特征之间的相关性。我们在下面包括相关矩阵和相关的绝对值。通过查看绝对值,可以更容易地看出相关性的强度。

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

相关矩阵(来源:作者)

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

相关矩阵的逐元素绝对值(来源:作者)

查看特性之间的相关性,我们可以看到特性之间存在一些共线性。特别地,s3 和 s4 高度负相关,s2 和 s4 高度相关。所有的血清测量值都有显著的相关性。LASSO 更有可能移除相关要素集中的要素,因此如果 LASSO 移除要素 s2、s3 和 s4 中的一个或两个,也不会令人惊讶。另一方面,LASSO 基于交叉验证的度量选择正则化强度,即惩罚强度。因此,如果一个特征背后有一些额外的解释力,即使它与另一个特征密切相关,也可能不会被删除。

缩放对套索很重要

在我们进入代码之前,我们需要更深入地理解缩放。如果我们想在 SciKit-Learn 中正确地应用 LASSO,我们需要首先缩放我们的数据。与线性回归不同,LASSO 中的要素缩放至关重要。这是因为 LASSO 的罚函数包含了特征系数的绝对值之和。

为了更好地理解这一点,让我们来理解缩放是如何影响线性回归的。

线性回归的拟合不受线性变换的影响

虽然这并不能完全构成一个证明,但让我们看看为什么“*特征的线性变换不会影响线性回归做出的预测”*的说法是正确的。我们会看看一元线性回归,但是

给定一个特征“x”,对于任何数字“a”和“b”,该特征的线性变换可以写成如下形式。

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

x 的线性变换(来源:作者)

回想一下,特征“x”的单变量线性回归的形式可以写成如下形式。优化选择系数,使平方和最小。

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

x 的线性回归形式(来源:作者)

对于转换后的特征,可以写成如下形式。再次选择系数以最小化平方和。

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

变换特征的线性回归形式(来源:作者)

在定义中代入转换后的特征,我们得到以下结果。

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

重写的变换特征的线性形式(来源:作者)

让我们看看分组术语。对于这两项,总项可以取任何值,并且我们已经从未变换的问题中知道了最佳系数。因此,实际上,转换后的形式等同于未转换的形式。

这是系数的变化

在其他条件不变的情况下,如果我们将一个特征除以 1000,那么系数会发生什么变化?举个更具体的例子,如果我们以“米”为特征,1 米对目标的作用是 1,那么 1 公里对目标的作用是什么?

看看上面的数学,或者咨询一下你的直觉。转换的效果是将系数乘以 100。

记住 LASSO 根据系数的大小增加了一个惩罚,现在看到缩放可以影响系数,我们可以看到不同的缩放会如何导致 LASSO 中最佳系数的不同选择。

标准化是一种线性转换

在 SciKit-Learn 中作为StandardScaler提供的标准化是一种线性转换。如果你想确定的话,看看 SciKit-Learn 文档中定义的这里的缩放程序,并把它改写成线性变换的形式。MinMaxScalar也采用线性变换。

用比例特征解释线性回归

StandardScaler通过将每个观测值转换为一个新的尺度来单独转换每个特征,该尺度表示观测值相对于平均值的标准偏差。

让我们来看看代码

我们将跳过如何加载数据集并将其分成训练集和测试集。如果您想更深入地了解这一部分,可以在这里查看与本文相关的资源库。

线性回归

为了预先用缩放步骤拟合线性回归,我们可以使用 SciKit-Learn Pipeline。SciKit-Learn 提供了一个简单的接口来创建一个带有make_piplinePipeline,我们将在下面使用。

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

制作和训练线性回归管道(来源:作者)

因为以模型结尾的Pipeline——从技术上讲是Estimator的子类——行为就像模型一样。由于这条管道在一个模型实例LinearRegression中结束,我们可以用.fit()方法训练它。

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

计算 MSE(来源:作者)

为了验证Pipline实例,我们可以使用它的 predict 方法来获得估计值并计算均方误差(MSE)。这里我们的 MSE 是 2900 左右。

为了得到系数,我们必须从流水线的最后一步提取它们。幸运的是,Pipeline中的步骤可以像数组元素一样被索引。我们使用-1索引糖来检索线性回归。

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

提取和显示线性回归系数(来源:作者)

为了解释这些系数,请记住,每个特征都经过缩放,因此一个单位的变化代表标准差的一个单位的变化。因此,对于每个特征,我们可以将每个系数解释为目标变化对平均值的一个标准差的影响。例如,以身体质量指数为例,身体质量指数值与平均值的一个标准差会使一个人的糖尿病进展增加 25.6 倍。

套索回归

sci kit-了解回归问题中 LASSO 的一些不同实现。最常见的两个LassoLassoCV。你可以在这里找到文档页面这里这里。两者的区别在于Lasso希望您设置惩罚,而LassoCV使用交叉验证的 MSE (CV-MSE)执行网格搜索,以找到正则化强度的最佳选择。实际上,除非您以前处理过相同或非常相似的数据集,否则您永远不会知道罚超参数的理想值。因此,在实践中,您几乎总是会使用LassoCV——这里我们也是这样做的。

与使用管道时的情况一样,用于训练和验证的代码几乎是相同的——这是使用管道的优势之一。除了从LassoCV的实例中提取系数,我们还可以根据 CV-MSE 提取最优的正则化 str。让我们看看结果。

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

Lasso 回归的代码和结果(来源:作者)

请注意,MSE 略有下降,这意味着我们得到了一个更准确的模型。通过查看系数,我们可以看到线性回归和套索之间的变化。LASSO 将年龄 s2 和 s4 设置为 0,有效地将它们从模型中排除。

里脊回归

值得一提的是,有一种在计算上和理论上与 LASSO 非常相似的技术叫做岭回归。它将稍微不同的约束区域应用于损失函数,并且不是选择特征,而是收缩所有的系数。此外,SciKit-Learn 中的代码几乎是相同的,因此不涵盖它将是一个遗憾。那么,让我们来看看。

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

岭回归的代码和结果(来源:作者)

对于这个数据集,岭回归没有做得很好,但我们可以看到,一般来说,系数较小。

如果你想了解更多关于岭回归的知识,可以看看下面这篇由 Qshick 撰写的文章!

比较系数

最后,让我们将三种不同技术的系数可视化!我们可以看到,岭回归发现几乎所有系数都更小,更接近于 0,其中 LASSO 将一些系数设置为 0。对于这个数据集,更稀疏的系数也导致具有更低 MSE 的更精确的模型。拥有更少的特征,它也更容易被理解。

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

系数图(来源:作者)

我们希望你喜欢这篇文章!要了解更多关于数据科学、机器学习和开发的内容,请查看 Edward 的 YouTube 频道,并订阅我下面的邮件列表,成为第一个听到新文章的人!

https://edkruegerdata.com/subscribe [## 每当爱德华·克鲁格发表文章时,就收到一封电子邮件。

edkruegerdata.com](https://edkruegerdata.com/subscribe)

参考

[1]sci kit-learn:Python 中的机器学习,Pedregosa 等人,JMLR 12,第 2825–2830 页,2011 年。

构建更好的时间序列模型:ByteHub 简介

原文:https://towardsdatascience.com/build-better-time-series-models-introducing-bytehub-98b548b98977?source=collection_archive---------35-----------------------

了解如何使用要素存储来简化您的数据科学工作流

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

数据管道对机器学习至关重要。西格蒙德Unsplash 上拍照。

本文介绍 ByteHub:一个开源的特性库,,旨在帮助数据科学家建立更好的时间序列数据模型,准备用于预测和异常检测等任务。虽然我们经常关注用于这些任务的机器学习技术和算法,但数据管道经常被忽视,尽管它对于开发高质量的模型以及能够将其作为更大项目的一部分进行部署和维护来说至关重要。

我们将探索在构建时间序列模型时改进数据科学工作流的三种方式,并通过示例演示如何使用 ByteHub。

获取数据

模型的好坏取决于它们接受训练的输入数据。对于任何使用时间序列模型的数据科学家来说,一项重要的任务是确定要使用的数据源。结果可能是戏剧性的:例如,在处理零售、能源、运输和其他部门的各种建模问题时,包含单个天气变量的结果通常会大大提高准确性。

添加天气数据会使伦敦自行车租赁数据的时间序列模型产生很大的性能差异[1]。

不幸的是,向模型中添加新的数据源通常不是一件容易的事情。数据集经常被锁在不同的数据库中或复杂的 API 后面,这使得很难快速迭代不同的数据输入并找到最好的。

ByteHub 通过两种方式解决了这个问题。首先,通过提供一种简单的方法来存储时间序列数据,以便可以轻松地访问、过滤、重新采样并输入模型。例如,以下代码片段演示了如何加载多个时间序列要素并将其重新采样到每小时分辨率,以便在模型训练中使用,而无需任何额外准备。

快速加载和重新采样时间序列特征。

其次,这些数据集存储有描述和额外的元数据,并且可以从简单的 Python 接口中进行搜索。数据科学家可以更轻松地搜索和重用现有数据,在更短的时间内开发出更好的模型,而不是在每个新项目上重新发明轮子。

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

在 Python 中快速搜索数据集和要素。

准备数据

找到正确的数据后,下一步是在将数据输入模型之前准备和转换数据。被称为特征工程,它允许我们使用我们自己的领域专业知识来提高模型性能。

ByteHub 引入了一个叫做特征转换的概念:可以应用于原始时间序列数据的 Python 代码片段。这些可以链接在一起,允许您构建非常复杂的功能工程管道,然后发布这些管道,以便在不同的项目和模型之间重用。

例如,在这个天气预报示例中,我们需要将风速和风向转换为 x 和 y 风速,因为否则我们使用的模型将很难正确解释风的角度。下面的 Python 函数包含了实现这一点所需的数学知识,而 decorators 将这些转换添加到特性库中,以便可以重用它们。

使用 Python 函数将原始时序数据转换为模型要素。

保持整洁!

在过去,所有这些数据管道很容易产生难以理解和维护的代码鸟巢。通过使用特征库,可以将数据准备从模型训练代码中分离出来。这不仅使模型更容易理解,也使更容易部署:数据加载和准备可以用一行代码完成。例如,ByteHub 中的典型模型训练脚本如下所示,其中包含加载数据、构建和训练模型的简单而清晰的步骤。

一旦所有的数据准备都转移到特征存储中,模型训练代码就会变得更加简单和易于理解。

最后的想法

我希望这篇文章能激发你在下一个时间序列建模项目中尝试 ByteHub。如果你想试一试,完整的文档和安装说明在 GitHub 上。

https://github.com/bytehub-ai/bytehub

所有的教程和示例都可以从 Google Colab 笔记本上运行。

如果您有任何想法、意见或问题,请在下方留言或直接联系我们。

[1]伦敦交通局:桑坦德循环雇佣计划的雇佣总人数,按日、月、年统计

使用 Argparse 在 Python 中构建命令行界面

原文:https://towardsdatascience.com/build-command-line-interfaces-in-python-using-argparse-6031daa28252?source=collection_archive---------24-----------------------

在 Python 中使用命令行授权!

Argparse 是一个内置的 Python 库,有助于在 Python 代码上构建命令行界面。Argparse 意味着解析参数。当我第一次听 Argparse 时,我感到害怕,但一旦我开始探索和学习,它就成为我的脚本中不可或缺的一部分。它为您的 Python 代码提供了额外的灵活性。您可以发送您修改的参数、参数选择等。通过命令行和 Argparse 会照顾它。下图解释了我对 Argparse 的理解:

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

作者创造的形象

为了实时解释这一点,让我们从一个基本的例子开始。让我们假设我们有下面的脚本 argparsetest.py. 该脚本可以根据用户输入执行两个变量的加法或减法。

在这里,我们只定义了两种可能性“add”或“sub”。如果用户两者都没有提供,它将作为无效操作返回(以黄色突出显示),如下面的屏幕截图所示:

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

用户可以通过提及下面的语法来传递参数:

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

关于库的更多详细信息:

**💡位置参数:**您需要在每次执行脚本时指定这些参数。如果没有提到默认值,则不能跳过它们,因为默认值是必须提供的。例如,在我们之前提到的示例中,如果我们只是要求用户从命令行提供 b 的值,则需要对脚本进行如下微调:

显示位置参数的脚本

命令行中的命令如下所示:

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

带有位置参数的命令

如果我们不指定“b”输入,我们会得到类似下面这样的错误:

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

不带位置参数的命令

如果有多个位置参数,它需要按照脚本的特定顺序出现。试试看,看看效果如何!

**💡可选参数:**与 positional 相反,这些参数可以是可选的,不指定也可以。将默认值添加到位置参数会转换为可选参数,如以下脚本所示:

显示可选参数的脚本

如前所述,如果我们不指定参数,它将采用默认值并执行脚本,没有任何错误

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

不带参数的命令

**💡获得帮助:**如果你想知道脚本中需要/使用的参数,你可以通过添加“- h”获得帮助。下面的截图显示了如何做到这一点:

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

**💡设置值的数量:**如果您想为一个变量提供多个值作为输入,您也可以这样做。传递的值以列表的形式读取。例如,添加’ c '作为参数,并将 nargs 定义为 3,,这意味着需要 3 个输入值。

带 nargs 的脚本

我们通过命令行将这些值传递给 c ,如下所示:

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

**💡设置输入参数的类型:**你可以明确地指出需要什么类型的输入。例如,我们只需添加’ int '作为 b 的必需变量,如果用户未能提供所需输入类型的输入,脚本将抛出一个错误。该脚本将更改如下所示的内容:

如果我提供字符串而不是整数b 它将抛出如下错误:

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

总之,argparse library 是通过命令行界面提供用户友好方法的完美方式!这些只是开始使用 argparse 的基础。如果你有任何其他的诀窍/技巧,请随时评论。感谢您的宝贵时间!

TwitterLinkedIn 上关注我。你也可以通过 pratikkgandhi@gmail.com 联系我

如何构建和部署 React + Flask 应用程序

原文:https://towardsdatascience.com/build-deploy-a-react-flask-app-47a89a5d17d9?source=collection_archive---------0-----------------------

简单易懂的教程

简明指南

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

ZanUnsplash 上的照片

当我试图弄清楚如何构建和部署我的 React + Flask 应用程序时,我设法在网上找到了各种教程。我所做的是,我首先谷歌并找出如何构建 React+Flask 应用程序,然后我试图搜索如何部署它。

可惜我好不容易找到的大部分教程都太复杂了(个人观点)。如果你谷歌“如何建立一个 React Flask App”,这里是我的前三个结果:链接链接链接

它们可能是很棒的教程,但是如果你现在不想为 Nginx、各种配置和额外的包**(你只是想从 Flask 返回一些东西进行反应,然后开始在线查看它的部署),你可能想试试这个教程。**

它分为三个部分——后端(Flask)、前端(React ),最后是在 Heroku 上的部署。这是 GitHub 回购协议——https://github.com/Reine0017/reactFlaskTutorial。

我们开始吧!ʕ•́ᴥ•̀ʔっ

第 1 部分—后端(烧瓶)

根据您自己的需求,您可能需要预先安装必要的 python 包。我使用 pip 安装了我需要的所有包,而没有使用虚拟环境(尽管这是强烈推荐的)。要创建一个名为 venv 的新 python 虚拟环境(您可以将其命名为其他名称,只需将下面命令中的最后一个 venv 替换为您自己的 venv 名称),请运行:****

python -m venv venv

要激活 venv:

source venv/bin/activate

我们将首先从后端烧瓶设置开始。有许多方法可以构建您的项目,但是要稍后在 Heroku 上部署,Procfile 必须在根目录中公开(稍后将详细介绍 Procfile)。在根目录中,创建一个名为 app.py 的文件。

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

暂时忽略其他文件

这是我们运行 flask run 时运行的东西。我将我的命名为 app.py,但是你可以选择将它命名为除 flask.py 之外的任何名称,因为这将与 flask 本身相冲突。

在第 6 行,我们创建了 Flask 类的一个实例。参考官方的 Flask 文档,你会注意到在我的例子中还有两个参数(static_url_path 和 static_folder)。static_url_path 可用于为 web 上的静态文件指定不同的路径,它默认为 static_folder 文件夹的名称。static_folder 指向 react 项目的构建目录(因为我将子目录命名为 frontend,所以在我的例子中是 frontend/build——相应地更改它)。

第 10–12 行:@app.route decorator 告诉 Flask 哪个 URL 应该触发我们的 serve(path)函数。最后,send_from_directory 允许我们从“前端/构建”目录发送“index.html”文件。

第 3、7 行:这是为了消除我们在向不同的域发出 API 请求时经常遇到的恼人的 CORS 错误。在当前阶段(部署之前),React 在端口 3000 上运行,Flask 在端口 5000 上运行。因此,当 React 向 Flask 后端发出请求时,会弹出这个 CORS 错误。关于 CORS 错误的更多信息,请查看这个这个链接。

第 4、8、14 行:为了可读性,我将 HelloApiHandler.py 放在了一个名为 api 的子目录中。

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

在我的 HelloApiHandler.py 中只有两个简单的 GET 和 POST 函数来处理对这个 API 端点的 GET 和 POST 请求:

要检查一切是否正常,请键入

$ flask run

在您的终端中,然后转到 localhost:5000/flask/hello(上面 app.py 中的参考行 14 ),您应该会看到:

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

事情正在解决:')

第 2 部分—前端(反应)

接下来,我们将在项目目录中为前端(React)创建一个文件夹。我把我的叫做“前端”。

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

cd 放入前端文件夹并运行

npx create-react-app .

这将创建一个新的 React 项目。

在您的 app.js 文件中,进行以下更改来测试我们对 flask 后端的 GET 请求。

如果一切正常,您应该会看到:

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

原谅偏心裁剪,只是想表明它在 localhost:3000 上

好极了,所以它在本地工作!让我们试着把它部署在 Heroku 上。

第 3 部分 Heroku 上的部署

对于 Heroku,设置一个帐户,然后创建一个新的应用程序。在您的设置选项卡中,您可以向下滚动并看到如下内容:

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

https://react-flask-tutorial.herokuapp.com是你的用户访问你的应用的网址

https://react-flask-tutorial.herokuapp.com/flask/hello是我们将从 React 前端发出请求的后端端点。因此,在 App.js(前端)中,将 axios . get(’ http://localhost:5000/flask/hello ‘)更改为 axios . get(’ https://react-flask-tutorial . heroku app . com/flask/hello ')。

我们必须做的另一个小编辑是在我们的后端(App.py)注释掉与 CORS 相关的内容。

接下来,在前端目录中,运行 npm run build:

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

这将创建我们的构建文件夹:

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

在根目录中,创建一个 Procfile,并在其中写入:

web: gunicorn app:app

记得记下空格!!

接下来,要生成 requirements.txt,将 cd 放入这个项目的根目录并运行:

pip freeze >> requirements.txt

我个人不得不在 requirements.txt 中注释掉 TBB 行,以使部署工作。不太清楚为什么。

因为我已经有了一个现有的 heroku 应用程序(我在 heroku 的网站上创建了一个新的应用程序),所以我只运行了:

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

接下来,就像你将如何提交给 GitHub 一样,做通常的事情:

git add .
git commit -m "first deployment"
git push heroku master

注意最后一行是 heroku 而不是 origin。

然后等待并希望它能起作用:')

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

是的,它有效!!

好了,这就是本教程,让我知道你是否有任何问题或面临任何问题:)

快乐的通货膨胀!_( ͡❛ ͜ʖ ͡❛)_/

我真的不喜欢无耻的插头,但如果你已经在考虑每月 5 美元获得中等会员资格,如果你能使用我的推荐链接来注册,我会非常感激-【https://reine-ran.medium.com/membership:】

即使您不知道如何编码,也要构建 ETL 数据管道

原文:https://towardsdatascience.com/build-etl-data-pipelines-even-when-you-dont-know-how-to-code-a6f09f60364d?source=collection_archive---------42-----------------------

当您想要的只是通过简单的步骤将分散在各处的良好数据集中到一个位置,以便快速洞察业务时,不要让编码和基础设施的复杂性阻碍您。

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

作者图片

了解如何整合各种来源的数据并执行简单的转换来解决数据质量问题是从大数据中获取洞察力的第一步。在这篇博文中,我们将探讨如何在谷歌云平台(GCP)上通过云数据融合构建和部署简单的 ETL 数据管道,而无需编码。

你将了解:

  1. 为什么我们需要云数据融合?
  2. 如何用云数据融合构建和部署 ETL 管道?

为什么我们需要云数据融合?

问题:你从大数据中获得深刻见解的第一个障碍

尽管复杂的数据分析和机器学习技术越来越受欢迎,但有些事情从未改变。获得伟大洞察力的第一个障碍通常是数据集成,包括将分散在各处的相关数据收集到一个单一的统一位置,并执行许多预处理步骤以使其清晰可用。

我们的数据集成需求可能非常简单,比如删除空值、将各种数据集连接在一起、删除不相关的列或者将所有数据放入数据仓库以供快速查询。然而,作为一个技术知识有限的业务用户,这样简单的需求可能会引发不适,因为您经常不得不考虑两个同样不方便的选项。

  1. 你需要学习如何自己编写代码
  2. 你必须等待一段时间,直到数据工程团队有足够的带宽来帮助你建立一个定制的数据管道(让我委婉地提醒你,在现实中,不是每个公司都有足够的预算来聘请数据工程师,更不用说资助数据工程团队了。)

怎么样,棕色的母牛?

解决方案:云数据融合如何提供帮助

由开源项目 CDAP 提供支持,云数据融合是一个完全托管的云原生企业数据集成服务,用于快速构建和管理数据管道。

—来自谷歌云

有了谷歌云平台上可用的云数据融合,你不必知道代码如何让简单的事情发生。简而言之,这就是你可以通过云数据融合做的事情。

  • 构建数据管道,从多个来源收集数据,并将其放入一个位置进行查询和提取见解
  • 转换数据以解决任何数据质量问题,或将数据转换成可用的格式
  • 自动管理部署数据管道的所有方面,例如配置基础架构、集群管理和作业提交

这和你有什么关系?用外行人的话来说,这就是为什么它很重要。

无需编写任何代码,您不必成为每一个数据源的专家,就可以将所有数据整合在一起,获得快速的洞察力。在编码上花费更少的时间(并确保它一直工作)意味着有更多的时间来了解您的数据,回答更多关于业务绩效和如何做出更好决策的紧迫问题。有什么不喜欢的?

此外,**由于数据管道的部署是自动化和完全管理的,你不必担心 IT 基础设施。这意味着更快地获得您想要的结果,而不必担心后端的管理工作。**毕竟,为什么业务用户要费心去理解基础设施意味着什么,或者如何配置实例或管理集群呢?

如何才能使用云数据融合?

说得够多了,让我们看看如何构建和部署一个简单的 ETL 管道,结合两个不同的数据源。

初始设置

先决条件

这是你开始之前需要的。

  • 创建谷歌云项目启用计费
  • 通过导航菜单> IAM & Admin > IAM 检查与您的帐户相关的角色和权限。您需要管理员权限来启用云数据融合 API

创建云融合实例

  1. 在 GCP 控制台主页面上,在搜索框中键入“云数据融合”。

2.选择云数据融合 API

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

作者图片

3.看到下面的屏幕后,选择启用

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

作者图片

4.刷新页面并选择导航菜单。向下滚动到大数据,选择数据融合

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

作者图片

5.点击创建一个实例

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

作者图片

6.按照屏幕上的说明输入实例的名称。选择基本作为版本类型,并将所有其他字段保留为默认值。点击创建。但是如果你看到创建按钮是灰色的(就像下面的截图),确保先点击授予权限

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

作者图片

7.单击创建后,实例创建过程可能需要大约 15–20 分钟。一旦创建完成,你会收到一个通知铃按钮在哪里。

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

作者图片

8.创建实例后,让我们授予与新数据融合实例相关联的服务帐户对项目的权限。要继续,请单击实例名称(不是视图实例)并将服务帐户复制到剪贴板。

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

作者图片

9.进入导航菜单> IAM & Admin > IAM ,点击添加

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

作者图片

10.将复制的服务帐户添加为新成员。点击选择角色,在过滤框中输入 云数据融合 。在所有过滤选项中,选择云数据融合 API 服务代理角色。然后点击保存

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

作者图片

11.在继续下一步操作之前,请确保与新创建的数据融合实例相关联的服务帐户作为您的项目的授予权限之一可见(类似于下图)。

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

作者图片

创建 ETL 数据管道

计划

为了比较和对比 COVID19 在不同国家传播的严重性,我们通常可以查看病例和死亡的总数。然而,如实地描述病例和死亡人数是行不通的,因为每个国家的人口规模都有很大的不同。

考虑到不同的人口规模,一个更常见的方法是比较每 100,000 人口中的病例和死亡总数。

每 10 万人口总发病数=总发病数/人口 10 万*

不幸的是,病例数和死亡数的信息不包括人口数据。因此,我们将构建一个 ETL 管道来使用云数据融合将一个 CSV 文件(包含病例和死亡总数)与一个 BigQuery 表(包含每个国家的人口)结合起来。

这篇博文使用的数据集摘自新冠肺炎公共数据集,该数据集可在谷歌云平台this GitHub 上获得。在我们使用流水线之前,下面是我们的计划。

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

作者图片

加载 CSV 数据

  1. 从导航菜单中,进入数据融合并点击查看实例

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

作者图片

2.按照屏幕上的提示,您应该能够看到如下所示的云数据融合 UI。由于我个人想从一些数据探索入手,点击牧马人。如果您想探索其他选项,请随意尝试 UI。

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

作者图片

3.让我们将 CSV 数据集加载到管道中,方法是选择左侧的云存储默认值,并单击包含每个国家一段时间内的病例数和死亡数的存储桶的名称。

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

作者图片

4.选择表名。

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

作者图片

5.一旦从 CSV 加载了数据,您可能会注意到所有属性都组合在同一个 body 列下。所以我们必须将 CSV 数据解析成适当的列。点击位于 body 栏左侧的向下箭头,选择解析> CSV

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

作者图片

6.选择适当的分隔符并勾选框,选择第一行作为标题。然后点击应用

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

作者图片

7.随着不同的属性被拆分到各自的列中,我们现在可以开始研究我们的数据集了。看看下面的截图。您能猜出为什么有些列(如 country_name)全是绿色,而 subregion2 _ code 显示一点绿色,而大部分是红色吗?

**提示:**红色代表每列空值的比例。简单地说,如果条形的大部分是红色的,您可以很容易地注意到,由于缺少许多值,数据属性对于分析可能不是很有用。

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

作者图片

8.以更直观的方式探索数据的另一个有用功能是 Insights 。例如,在这里我可以很容易地观察到这个数据集包含从 0 到 3 的不同级别的聚合。这是我必须小心处理的事情,因为我只对国家一级的数字感兴趣,而不是次区域一级的数字。

提示:**不要急于下结论,因为这些见解是从数据集中的 1000 个样本中产生的。**这可能有助于初步理解,但并不代表整个数据集中的所有可用信息。

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

作者图片

转换 CSV 数据

在详细检查了 CSV 数据之后,下面是一些常见的数据转换步骤,我们可以通过这些步骤将原始数据清理和整形为可用的格式。

按特定值过滤行

如上所述,数据集包括每个国家的新冠肺炎病例和死亡人数(这是我们想要的),以及每个次区域的数字(这是我们不想要的)。

要仅保留国家级别的数字,单击 aggregation_level 列旁边的向下箭头,并过滤以保留 aggregation_level = 0 的行

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

作者图片

删除冗余列

在右侧的菜单中,勾选方框以选择您想要保留的。然后点击任一选定列旁边的向下箭头,并点击保持选定列

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

作者图片

删除冗余列后,点击#旁边的向下箭头,并选择清除所有以返回正常数据视图,进行后续转换步骤。

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

作者图片

将字符串转换为数值数据类型

对于每个数字列(如 new_confirmed、new _ deceased、cumulative_confirmed、cumulative _ deceased),点击向下箭头,选择更改数据类型,选择整数或小数。

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

作者图片

解析字符串到日期

要将字符串转换为适当的日期类型,对于每个日期列,单击向下的箭头,选择解析>简单日期

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

作者图片

选择合适的日期格式,点击应用

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

作者图片

更改列名

要将原来的列名更改为更直观的名称(例如从 cumulative_confirmed 更改为 total_case),双击列标题,输入新名称并按回车键。

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

作者图片

对 CSV 数据的最终格式满意后,点击创建管道,然后选择批处理管道。

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

作者图片

但是请记住,我们还需要我们的人口数据,这些数据目前位于 Google BigQuery 表中。所以让我们把它带进来。

加载包含人口数据的 BigQuery 表

  1. 从左边的菜单中,导航到并选择您试图集成的数据源。这里我选择了大查询

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

作者图片

2.一旦 BigQuery source 的新节点出现,将鼠标悬停在 BigQuery 节点上并单击属性

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

作者图片

3.选择浏览

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

作者图片

4.导航到您想要集成的 Google BigQuery 表

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

作者图片

5.要验证 BigQuery 表是否包含您正在寻找的正确信息,请单击获取模式。BigQuery 表的所有列都将出现在向导的右侧,供您查看。

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

作者图片

从模式中可以看出,我们不需要 BigQuery 表的每一列。所以让我们剔除我们不需要的。但是首先,我们需要退出 BigQuery 属性。

6.单击右上角的 X 按钮,退出 BigQuery 属性并返回数据管道。

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

作者图片

转换 BigQuery 数据

  1. 为了消除多余的列,我们将需要使用牧马人。在左侧菜单中,导航至变形并选择牧马人

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

作者图片

2.要将两个节点连接在一起,请拖动 BigQuery 节点右边缘的连接箭头,放在新的 Wrangler 节点上。将鼠标悬停在新的牧马人节点上,点击属性

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

作者图片

3.为了避免与我们用来转换 CSV 数据的前一个 Wrangler 节点相混淆,让我们通过指定一个新标签给这个节点一个新名称。点击辩论配置清理和整形数据的步骤。

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

作者图片

4.导航并选择包含我们需要清理的人口数据的 BigQuery 表。

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

作者图片

5.对于这个人口数据集,我们只需要“key”和“population”列。因此,类似于我们如何消除 CSV 文件的冗余列,在右边的菜单中,勾选框以选择您想要保留的。然后点击任一选定列旁边的向下箭头,并点击保留选定列

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

作者图片

6.点击应用返回到属性视图。然后单击右上角的 X 按钮,退出 BigQuery 属性并返回到数据管道。

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

作者图片

将两个数据源连接在一起

是时候将新冠肺炎数据和人口数据结合在一起了。这一次,我们将需要使用 Joiner 节点,它位于分析部分之下。

  1. 从左侧菜单中,导航至分析并选择连接器

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

作者图片

2.一旦新的 Joiner 节点出现在屏幕上,通过拖放连接箭头将两个牧马人节点连接到 Joiner 节点。然后将鼠标悬停在 Joiner 节点上,单击属性来配置这两个表应该如何连接在一起。

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

作者图片

3.指定连接类型和连接条件。这里我们做了一个内部连接来匹配人口数据集中的“key”列和新冠肺炎数据集中的“location_key”。单击获取模式以验证输出列是否是您正在寻找的。

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

作者图片

4.对输出满意后,单击右上角的 X 按钮,退出连接器属性并返回数据管道。

在 Google BigQuery 中存储最终数据集

由于我们已经成功地将新冠肺炎数据和人口数据缝合在一起,ETL 管道的最后一步是将所有数据加载到一个存储位置(即一个接收器),以便您可以随时回去分析数据。

在这里,我选择将最终数据集存储在 Google BigQuery 中,因为我可以轻松地使用 SQL 查询它来计算每 100,000 个国家的病例和死亡人数,或者将其与任何数据可视化工具(如 Tableau、Google Data Studio 等)相连接。

  1. 从左侧菜单中,导航至接收器并选择大查询

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

作者图片

2.将 Joiner 节点连接到新创建的 BigQuery 节点。将鼠标悬停在 BigQuery 节点上,点击属性来配置数据存储。

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

作者图片

3.指定您想要存储组合数据集的引用名称、项目 ID、数据集

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

作者图片

4.为确保所有内容都被正确指定,点击验证。当您看到未发现错误时,单击右上角的 X 按钮退出 BigQuery 属性并返回数据管道。

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

作者图片

查看 ETL 数据管道

最后,我们已经完成了第一个 ETL 数据管道的构建,将新冠肺炎数据和人口数据结合起来计算每 100,000 人口中的病例数和死亡数。这是我们简单的 ETL 数据管道目前的样子。大家一起击鼓吧!

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

作者图片

在直接进入部署之前,我强烈建议花 15-20 分钟从头到尾回顾一下 ETL 管道,并给管道命名。

提示:不要忘记给每个节点取一个有意义的名字。你最不希望的是 3 个月后,你发现自己盯着 5 个不同的牧马人节点,挠头试图理解 Wranger3 和 Wranger5 之间的区别。让我们善待自己,善待任何可能继承这个 ETL 管道的人,好吗?

部署 ETL 管道

好吧!是时候看看我们的 ETL 管道在运行了。你准备好了吗?

  1. 在页面右上角,点击部署

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

作者图片

2.看到以下屏幕后,点击运行立即启动数据整合过程。或者,您可以点击计划来设置该 ETL 数据管道的每日或每周执行,或者监控状态。请注意,需要一段时间才能完成,状态将变为成功

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

作者图片

在 BigQuery 中计算每 100,000 人口的病例和死亡总数

一旦 ETL 管道运行完成,下面是您可以在 BigQuery 中看到的组合数据集。

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

作者图片

由于新冠肺炎数据和人口数据现在很好地结合在一起,编写一个 SQL 查询来计算一段时间内每 100,000 人口的病例和死亡总数再简单不过了。

SELECT 
EXTRACT(DATE FROM date) AS record_date, 
country_name, 
new_case/ population*100000 AS new_case_per_100k_pop, 
new_death/ population*100000 AS new_death_per_100k_pop, 
total_case/ population*100000 AS total_case_per_100k_pop,
total_death/ population*100000 AS total_death_per_100k_pop 
FROM `covid19-305322.epidemiology.covid19_with_population_data`;

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

作者图片

包扎

面对现实吧!在编码和管理基础设施上花费更少的时间意味着有更多的时间来了解您的数据,回答更多关于业务绩效和如何做出更好决策的紧迫问题。云数据融合只是市场上许多其他数据集成解决方案中的一种,这些解决方案可以帮助业务用户将分散在各处的良好数据集中到一个位置,而不必担心编码或管理基础架构的复杂性。现在是时候为业务用户提供工具和功能,将大数据快速转化为业务洞察力,同时保持简单的事情简单。

感谢您的时间,如果您觉得这篇文章有用,请在 LinkedIn 和 T2 Twitter 上关注我,了解关于数据、商业和这两者之间的任何令人兴奋的故事。下一集再见!

原载于 2021 年 2 月 22 日 http://thedigitalskye.comhttp://thedigitalskye.com/2021/02/23/build-etl-data-pipelines-even-when-you-dont-know-how-to-code/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值