TowardsDataScience 博客中文翻译 2021(七百二十二)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

使用 Terraform 的版本控制大查询(也使用 CI/CD)

原文:https://towardsdatascience.com/version-control-big-query-with-terraform-with-ci-cd-too-a4bbffb25ad9?source=collection_archive---------5-----------------------

确保大查询中的所有更改都是负责任的

介绍

当人们在没有通知团队其他成员的情况下开始改变视图时,使用大查询和创建视图的团队工作可能会变得混乱。

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

该片段取自作者大查询视图

一些团队习惯于在视图顶部使用注释,甚至是电子表格来记录变更。显然,从长远来看,这会导致一个问题,因为人们可能会忘记评论或没有正确地做。

事不宜迟,我如何对我的大查询进行版本控制,以确保我可以跟踪并在需要时回滚更改,并与我的团队一起更好地管理项目。

为了实现这一点,我们将研究两种技术,即 Terraform (基础设施即代码),以及您选择的版本控制系统(Github、Gitlab 等)。我们今天将使用 Github!如果你从未听说过 Terraform,不要太担心,这篇文章也可以算是“GCP terra form 的快速介绍”!

快速跳跃

  1. 入门
  2. 初始化地形环境
  3. 在 Terraform 中创建数据集和视图
  4. 版本控制和设置
  5. git 提交,git 推送
  6. 做出改变并测试我们是否达到了目标
  7. 结论

入门指南

这一部分将用于尚未设置的环境。
入门不多!你只需要安装:
1。地形。他们提供了一个很好的指南,所以只要确保你跟着做,你应该能够在你的终端/命令提示符
2 中调用terraform。饭桶。请为您的操作系统安装 git,这样我们就可以执行基本命令,如git push

TL;步骤的 DR

  1. 在 GCP 项目上创建服务帐户
  2. 为服务帐户创建并下载 JSON 密钥
  3. 设置 Google 云存储(GCS)来存储地形状态
  4. 授予服务帐户在该存储桶中读取、写入和创建对象的权限
  5. 设置 Terraform 以连接到 GCS

首次创建服务账户和密钥的详细信息

Terraform 将代表我们使用一个叫做服务账户的东西与我们的谷歌云平台(GCP)项目进行互动。

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

该片段摘自授予 IAM 角色的作者 GCP 项目

继续用谷歌提供的教程创建你的 GCP 项目。当您到达选择 IAM 角色的提示时(截至 2021 年 6 月的教程中的步骤 7),出于本教程的原因,您需要授予 大查询数据编辑器 角色,如上面的代码片段所示。随着您的进步,请随意将权限缩小到仅需要的内容。单击下一步和完成。

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

该片段摘自作者 GCP 创建新密钥的项目

创建服务帐户后,单击服务帐户,您将看到一个类似于上面代码片段的屏幕。选择*键- >添加键- >创建新键。*接下来会出现一个弹出窗口,选择 JSON,点击 create。它将下载一个 JSON 文件。保管好它!

创建一个 Google 云存储(GCS)来存储地形状态

Terraform state 基本上记住并告诉 Terraform 你的基础设施现在是什么样子。我建议阅读 Terraform 文档来更好地理解它。我们将使用 GCS 来存储状态,主要有两个原因:
-在 Github 上共享状态通常不是一个好的做法,因为它可能包含敏感信息
-您不需要担心丢失它和重建基础设施

因此,让我们开始按照这里的教程创建一个 GCS bucket。记住您创建的存储桶名称,因为我们稍后将使用它。在该存储桶上,选择 permission 并添加之前创建的具有 Storage Admin 权限的服务帐户。你可以按照这个教程去做。

初始化地形环境

创建一个工作文件夹,在这个文件夹中,我们将创建一个名为providers.tf的文件。我通常使用 Visual Studio 代码来管理我的 Terraform 配置。tf 是一个 Terraform 配置文件,我们所有的 Terraform 内容都将存放在其中。平台提供商基本上是你将要与之合作的平台,无论是微软 Azure、GCP、AWS 还是其他。我将这个文件命名为providers.tf,,因为这是我保存所有提供者配置的地方,你可以随意命名,但是提供者会是一个更好的标准。

将以上内容粘贴到您的providers.tf中。在名为 terraform {…}的第一个“块”中,我们告诉 terraform 将我们的状态存储在 GCS 中。将 YOUR_BUCKET_NAME 更改为您之前创建的 BUCKET 名称。前缀基本上只是桶内的文件夹。
下一个称为 provider 的块表示我们正在使用 Terraform Google Provider 配置,并用您的 YOUR_PROJECT_NAME 对其进行初始化。

现在,Terraform 还不能读取您的 GCS 存储,这就是我们的服务帐户发挥作用的地方。将有一些方法向 Terraform 声明您的服务帐户,但是我们将使用的方法将在稍后在 Github 上设置 CI/CD 时有用。我们将把环境变量设置为我们先前下载的 JSON 文件,所以把那个 JSON 文件也移到您的项目文件夹中。在同一文件夹中,打开终端/命令提示符,并将环境设置为:

Windows 用户:

set GOOGLE_CREDENTIALS=JSON_FILE_NAME.json

Linux/macOS:

export GOOGLE_CREDENTIALS=JSON_FILE_NAME.json

Terraform 上的 Google provider 将自动从环境变量中检测服务帐户密钥。现在您的第一个 Terraform 命令来初始化环境了!

terraform init

如果一切顺利,您应该会在控制台上看到许多绿色文本。GCS 现在应该显示一个名为 state 的文件夹和该文件夹中一个以. tfstate 结尾的文件。

然而,如果你遇到了错误,不要担心,仔细阅读是什么错误。如果是关于 NewClient()失败的问题,请确保您的环境变量被正确地设置到 JSON 文件中。如果是关于拒绝访问,请确保您在 Google IAM 页面上为您的服务帐户提供了适当的访问权限。

创建我们的第一个数据集和视图

太好了!现在我们已经初始化了我们的环境,我们可以开始使用 Terraform 管理大型查询。

就像我们如何用providers.tf来管理我们的提供商一样,我们将创建bigquery.tf来管理我们的大查询。您甚至可以深入到数据集、表和视图的 3 个独立文件,但目前,我们将只创建bigquery.tf。我们将在bigquery/views/vw_aggregrated.sql创建另一个文件夹来存储我们的视图 SQL。

# Some demo content in vw_aggregrated.sqlSELECT 
   LoadDate, Origin, Destination, COUNT(ID) AS counts
FROM
   `terraform-testing-gcp.demoset.DemoTable`
GROUP BY
   1, 2, 3

将上面的代码复制粘贴到bigquery.tf中。为了理解发生了什么,第一个资源包含两个参数,第一个是资源类型*(Google _ big query _ dataset),第二个是 ID (views) 您可以自己定义。你可以在这里找到谷歌提供商可用的资源。我们正在美国使用 ID 为“views”“Google _ big query _ dataset”*块创建数据集。我已经给了它一个描述和一些标签。标签是完全可选的,你可以删除它们。

接下来,我们创建一个资源*“Google _ big query _ table”,ID 为“VW _ aggregated”。对于 dataset_id,它引用我们之前创建的视图* dataset_id。这一次,由于我们正在创建一个视图,我们将不得不打开一个视图块,如教程这里所述。我们将传入的第一个参数是我们想要使用的 SQL。有两种方法可以做到这一点,一种是直接将 SQL 键入 bigquery.tf 本身,例如:query = "SELECT * FROM ... WHERE 1 = 1。然而,我们正在研究可维护性,所以我们已经在bigquery/views/vw_aggregated.sql的一个文件夹中定义了我们的 SQL。

好吧!让我们运行一个命令来标准化我们的 Terraform 代码格式,然后试运行我们的配置。Terraform plan 将基本上“计划”并让我们知道什么资源将被创建/删除/修改等。

terraform fmt
terraform plan

如果你看到x resource to be created,x 是一个数字,你就可以走了!如果您正在获取x resource to be deleted,请检查并验证这是否是有意的。一旦确认这是预期的操作,运行terraform apply应用配置。

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

Terraform 创建的 author 大查询数据集的片段

如果操作正确,检查您的大查询 UI,您应该看到您在 Terraform 配置中定义的资源已创建!在我们的例子中,创建了一个名为视图vw_aggregated 的数据集。

版本控制设置

在我们验证了我们的 Terraform 配置按预期工作后,是时候对配置的变更进行版本控制了。第一步是创建一个 Github 项目,并将其设置为私有 repo,因为您不希望您的基础设施设置公开:)。

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

作者 Github 秘密创作画面片段

按照 Github 的指南创建一个名为GOOGLE_CREDENTIALS的秘密。这个秘密的值将是我们刚才用来设置环境变量的 JSON 密钥文件的内容。只需用文本编辑器打开 JSON 文件,并将内容复制粘贴到秘密值字段中。它应该类似于上面的代码片段。

我们将保持的“秘密”是服务帐户密钥,以允许 Github 动作在每次我们提交更改时帮助应用我们的 Terraform 配置。
Github secret 在我们的场景中非常棒,原因有两个:
-我们不需要提交我们的 JSON 密钥文件,其他贡献者/成员可以下载和滥用

  • Github 操作将应用配置,并且您不需要向贡献者分发具有写权限的服务帐户。这迫使贡献者/成员总是提交他们的工作和变更,以便将其应用到生产中

接下来,我们需要告诉 Github Actions,一旦提交发生,需要做什么。创建一个名为.github/workflows的文件夹,并将以下内容粘贴到新创建的名为terraform.yml的目录中的一个文件中。

在推送至 Github 之前,我们需要排除一些文件或文件夹。在根文件夹上,创建一个名为.gitignore的文件,并粘贴以下内容。这将排除我们之前复制到目录中的 JSON 键,以及任何状态文件(如果有的话)。也可以随意添加自己的文件!

*.json
*.tfstate

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

作者项目目录的一个片段

对于那些仍然对我们之前创建的许多文件感到困惑的人来说,如果你完全按照这个教程来做(忽略vw_origin_KUL.sql),你的目录应该是这样的。

git 提交,git 推送

黄金时刻来了。以下命令将初始化 git 并将您的配置推送到 Github。理想情况下,如果运行良好,Github Actions 将在您的代码被推送的那一刻开始运行。

terraform fmt
git add .
git remote add origin LINK_TO_YOUR_GIT_REPO
git branch -M main
git commit -m "Initial commit"
git push -u origin main

git add 将在该目录中添加新的和已更改的文件和文件夹,除了那些在.gitignore中定义的。
*git remote add originhttps://github.com/…*会定义你当前目录应该属于的库。
git branch -M main 将创建一个名为 main
*git commit-M " YOUR _ MESSAGE _ HERE "*将创建一个“changelog”,一个好的消息将帮助你自己和你团队中的其他人识别出什么被更改了,而无需阅读太多代码
git push-u origin main将把你的代码推送到主分支。

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

作者 Github 操作工作流页面的片段

现在检查你的 Github 库,你应该在那里看到你的代码。单击 Actions 选项卡,您将看到我们之前在.github/workflows/terraform.yml创建的工作流。

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

作者 Github 操作工作流详细信息的片段

如果你看到一个绿色或橙色的勾号在跑,你就可以走了!如果出现错误,只需点击进入工作流程并阅读每个步骤的日志,因为错误很容易缩小范围。如你所见,这些步骤是我们在.github/workflows/terraform.yml中定义的。

做出改变并测试我们是否达到了目标

我们几乎完成了整个管道!接下来是测试我们计划实现的目标是否已经实现。让我们对bigquery/views/vw_aggregated.sql做一些改变。我已将我的查询更改为

# Some demo content in vw_aggregrated.sqlSELECT 
   CAST(LoadDate AS DATE) AS LoadDate, 
   Origin, Destination, COUNT(ID) AS counts
FROM
   `terraform-testing-gcp.demoset.DemoTable`
GROUP BY
   1, 2, 3

现在,我们将需要添加任何已更改的内容,创建一个 changelog 消息,然后将其推送到我们的存储库,以便 Github Actions 可以为我们应用它。总是terraform fmt保证代码标准化。

terraform fmt
git add .
git commit -m "Updated vw_aggregated to CAST LoadDate"
git push origin main

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

作者 Github commit 的一个片段

检查回购,我们可以看到我所做的更改( jonathanlawhh ),如上面的片段所示。

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

更新后的作者 Github 操作工作流片段

检查“Actions”选项卡,我们可以看到该提交的工作流已成功完成!

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

更新后的作者大查询视图片段

最后,我们可以看到大查询中的视图已经按照预期进行了更新。

结论

总之,我们首先建立一个 Github 存储库,初始化一个 Terraform 环境,并将 Terraform 配置推送到 Github 存储库。与此同时,我们还准备了一个 CI/CD 配置terraform.yml,以便在我们推出变更时帮助部署我们的配置。至此,可以有把握地说,我们已经实现了使用 Terraform 对大查询进行版本控制的目标,并实现了对我们项目的持续集成和部署。

希望这篇文章足以启动您的实现,并帮助您更多地了解 Terraform 可以实现什么!当然,实现可以根据您的环境进行改进。

如果您有任何问题,请随时联系我,甚至通过
Messenger widget 向我问好:https://jonathanlawhh.com
电子邮件:jon_law98@hotmail.com

版本控制您的数据库第 1 部分:创建迁移和播种

原文:https://towardsdatascience.com/version-control-your-database-part-1-creating-migrations-and-seeding-992d86c90170?source=collection_archive---------7-----------------------

轻松规划、验证和安全地应用对数据库的更改

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

想象一下,这些盒子里塞满了模式和表格(图片由赖爷·苏比扬托像素上拍摄)

如果您没有在数据库中处理迁移,那么您就错过了。就像 Git 管理对源代码的更改一样,您可以使用迁移来跟踪对数据库的更改。执行和恢复更改,并将数据库恢复到以前的状态。

设置迁移比您想象的要简单,而且优势巨大。迁移是独立于数据库的,提供一个真实的来源,跟踪变化,甚至可以用一些数据播种您的数据库。当您阅读完本文后,您将能够:

  • 创建带有索引和外键的表
  • 在开发数据库中轻松规划、验证和安全应用更改,然后将所有更改同步到生产数据库
  • 重置开发数据库(全部撤消,再次迁移)
  • 在数据库中创建所有指定的表,包括索引和关联
  • 为数据库设定种子(插入数据)
  • 执行到任何数据库的迁移(例如 PostgreSQL 和 SQL Server)

我将试着用实例展示所有这些特性,这些实例使用您可以重用的真实代码。我将这个过程分为 4 个步骤:设置、创建迁移、执行和撤销,最后是播种。不要因为这篇文章的长度而气馁,你可以使用简单的步骤轻松完成。我们走吧!

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

我们的计划已经制定,让我们开始吧(照片由斯科特·格雷厄姆Unsplash 上拍摄)

步骤 1:设置

在这一步的最后,Sequelize 安装完毕,可以使用了。如果你是一个有经验的程序员,那么跳过“解释”部分。在这一部分的底部,您可以找到所有命令的摘要。

1.1 安装 NPM

安装 NPM 。用npm -v验证

说明:
对于这个项目,你需要安装NPMJavaScript 包管理系统。它类似于 Python 中的 pip,您可以使用它来安装软件包。在此下载 NPM 并遵循安装说明。一旦安装完成,你应该能够打开一个终端(如命令提示符)并运行nmp -v。如果您的是阿瑟版本(如 v14.15.4 ),则节点安装正确。

1.2 设置您的项目

打开终端,导航到您的项目文件夹并执行npm init

解释:
创建一个你想要创建这个项目的文件夹,例如c:/migrationtool
打开一个终端,导航到这个文件夹:cd c:/migrationtool
调用npm init新建一个项目。NPM 会问你一些关于项目名称、版本、描述和作者姓名的问题。这些都不是必填项,可以跳过,也可以以后填写。完成后,项目文件夹中会出现一个名为“package.json”的文件。在这里,我们所有的项目元数据都将被注册。

1.3 安装软件包

在根文件夹中执行

# installing packages
npm install --save sequelize sequelize-cli
npm install --save pg pg-hstore   # for PostgreSQL
npm install --save tedious        # for SQL Server

说明:
我们的项目准备好了,让我们安装我们的包吧!首先我们需要 Sequelize 和 Sequelize-cli。这些包允许我们开始进行和执行迁移:npm install --save sequelize sequelize-cli。这是允许我们创建迁移的主包。
为了实际执行这些迁移(例如创建数据库、表或新列), Sequelize 需要了解更多关于数据库的信息。出于演示目的,我们将在项目中使用两种数据库:PostgreSQL 和 SQL Server。为了让 Sequelize 与这些数据库一起工作,我们需要安装一些额外的包:npm install — save pg pgh-store tedious。如果你使用另一个数据库,如 mysql sqllite 或许多其他数据库,你可以在这里选择使用哪个包。你会注意到出现了一个新文件夹;节点 _ 模块。我们所有的软件包都安装在这里。我们的 package.json 文件也扩展了,跟踪我们所有已安装的包。

1.4 初始化序列

在你的根文件夹中执行npx sequelize-cli init 并运行所有步骤

说明:
我们所有的包都安装好了。初始化序列:npx sequelize-cli init。请注意,我们在这里使用的是 NPX,而不是 NPM。NPX 用来执行我们和 NPM 一起安装的包。
命令完成后,您会注意到又出现了三个文件夹:

  • config:保存数据库凭证之类的文件
  • 模型:保存将数据库表表示为模型的文件
  • seeders:在表格中插入和删除数据的文件

1.5 配置序列

Sequelize 已经可以使用了。在我们深入研究之前,我们将让 Sequelize 的工作变得更简单一些
我们将让配置的工作变得更简单一些。根据我的经验,JS 文件比 JSON 更容易使用。转到 config 文件夹,将 config.json 改为 config.js 。然后调整内容从

{
  "development": {

module.exports: {
    "development": {

我们对“我们需要告诉 Sequelize 如何处理新情况”进行了更改。转到项目的根目录(c:/migrationtool/)并创建一个新文件。将这个文件命名为.sequelizerc。请注意,这个文件没有名称,只有扩展名。打开文件并添加下面的内容。这告诉 Sequelize 我们现在使用 config.js 而不是 config.json。

const path = require('path');
 module.exports = {
   "config": path.resolve('./config', 'config.js'),
    "models-path": path.resolve('./models'),
    "migrations-path": path.resolve('./migrations'),
    "seeders-path": path.resolve('./seeders')
 }

乐趣开始前的最后一步:转到 models 文件夹(c://migrationtool/models)并打开 index.js 文件。在第 8 行,将 config.json 替换为 config.js。

摘要

我们准备好出发了!在我们进入下一步之前,检查一下我们使用的命令。

#Creating folder
cd c:/
mkdir migrationtool
cd migrationtool#Setting up project
npm init# installing packages
npm install --save sequelize sequelize-cli
npm install --save pg pg-hstore   # for PostgreSQL
npm install --save tedious        # for SQL Server# Initialize Sequelize
npx sequelize-cli init

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

续集到了,我们开始吧。(照片由 Handiwork NYCUnsplash 上拍摄)

步骤 2:创建迁移

在 Sequelize 中,迁移是一个 JavaScript 文件。它的内容描述了在执行和撤销时应该发生什么,例如“创建一个名为‘person data’的模式。让我们创建一个!

2.1 创建我们的首次迁移

在您的根文件夹中执行以下命令。
npx sequelize-cli migration:create -- name create_schemas。这将告诉 sequelize 创建一个新的迁移。执行这个命令将在我们的 migrations-folder 中生成一个文件,名称如下:“20210519183705-create _ schemas . js”。在里面你会发现下面的代码。

我们的第一次迁徙

如您所见,迁移包含两个功能“向上”和“向下”。第一个函数将包含实现我们想要做的事情的所有代码;创建模式。第二个功能将取消“向上”功能;它是它的对立面。让我们完成第一次迁移:

为我们的迁移采取一些行动

这段代码告诉 queryInterface 创建一个名为“app”的模式。

2.2 创建表迁移

让我们加快一点速度;我们将使用npx sequelize-cli migration:create -- name create_country_table创建新的迁移。为新创建的迁移提供以下内容:

这在我们的模式中创建了一个新表

这种迁移有点奇特。首先,它创建了一个事务,在该事务中定义了一个包含几列的表。然后,它将 we 索引添加到表中,然后提交它。事务是为了确保要么一切成功,要么什么都没有。如果创建其中一个索引失败,它将回滚到创建表。down 函数只是删除新创建的表。

还要注意,创建和修改的列都有默认值。

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

我们的迁移已经确定,让我们构建数据库模型吧!(图jeshoots.com像素上)

3.执行和撤销我们的迁移

我们的数据库中还没有发生任何事情。我们刚刚生成了一些现在必须执行的指令。我们希望将指令迁移到数据库中。首先,我们将定义我们的数据库连接,然后我们将使用该连接告诉数据库如何执行迁移

3.1 设置数据库连接

编辑 config.js 文件的内容(在 root/config 文件夹中)。我已经创建了两个数据库连接:

module.exports = {
  development: {
    username: "mike",
    password: "my_secret_password",
    database: "country_db_dev",
    host: "localhost",
    port: "5432",
    dialect: "postgres"
  },
  production: {
    username: "mike",
    password: "my_secret_password",
    database: "country_db",
    host: "localhost",
    port: "1433",
    dialect: "mssql"
  }
}

解释:
我做了两个连接:开发和生产。这些文件允许我们的迁移工具连接到数据库来执行迁移。

当我们告诉 Sequelize 执行迁移时,它需要知道要连接到哪个数据库。为此,我们将 NODE_ENV 设置为我们的一个数据库连接的名称。我们有“开发”和“生产”。让我们与“发展”联系起来。在您的根文件夹中打开一个终端,执行下面的一行(与您的操作系统匹配):

# On windows
SET NODE_ENV=development
# On OSX
export NODE_ENV=development
#On powershell
$env:NODE_ENV="development"

3.2 执行迁移

既然 Sequelize 知道向何处写入,我们就可以执行迁移了。请注意,在上一步中,我们已经定义了数据库。我们可以执行到任何数据库的迁移,在本文的步骤 1.3 中我们已经为这些数据库下载了包。这样,我们可以在 PostgreSQL 中测试我们的迁移,然后将所有内容迁移到我们的 SQL Server 生产数据库中!
让我们执行:

npx sequelize-cli db:migrate

这段代码将执行所有的迁移,在其中创建我们的模式和一个表,请看:

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

我们漂亮的表,有列、主键和索引

3.3 撤消迁移

等等,回去!调用下面的代码删除表和模式。npx sequelize-cli db:migrate:undo:all。看看你的数据库里面,都是干净的!您也可以通过在下面的命令
npx sequelize-cli db:migrate:undo:all — to XXXXXXXXXXXXXX-create_country_table.js中指定文件名来撤销直到一个特定的迁移

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

我们已经成功执行了!(图 byu SpaceXUnsplash

4.播种

为数据库设定种子非常类似于创建迁移。让我们快速浏览一下代码。

4.1 创建种子

第一步:生成种子文件
npx sequelize-cli seed:generate --name seed_country_table
,内容:

这将在我们之前创建的表中插入两条记录。向下删除它们

4.2 执行种子

npx sequelize-cli db:seed:all执行

4.3 撤销种子

比如用
撤销种子用npx sequelize-cli db:seed:undo `
或者直到一个特定的种子像

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

很难相信这些小种子会成长为一个漂亮的关系数据库模型

结论

我们今天完成了相当多的工作!我们已经完成了以下工作:

  • 安装的节点
  • 已安装的序列和所有必要的软件包
  • 配置序列
  • 创造了一些迁移
  • 执行和撤消迁移
  • 创造了一些种子
  • 已执行和未执行的种子

点击 此处 进入下一部分,我们将关注更高级的内容;我们将开始创建表和策略之间的关联,一旦它所依赖的记录被删除,记录应该如何操作。关注我敬请期待!

—迈克

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

这是一篇很长的文章,所以这里有一只小猫,如果你还和我在一起!(照片由乔·克利里Unsplash 上拍摄)

数据库的版本控制第 2 部分:表关系的迁移和种子

原文:https://towardsdatascience.com/version-control-your-database-part-2-migrations-and-seeds-for-table-relations-d4fb185d95d8?source=collection_archive---------29-----------------------

如果你喜欢啤酒、效率或建模高性能数据库,请阅读本文

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

我们数据库中的所有表格都整齐地链接在一起,并植入了数据(图片由克林特·王茂林Unsplash 上提供)

的上一部分中,我们已经设置了迁移工具,对其进行了配置,创建了一些迁移,甚至在新迁移的表中植入了一些数据。如果你不知道我在说什么,请查看这篇文章。在这一部分中,我们将着重于向表中添加更多的功能。您可以在这里找到我们将在本文中构建的库。当您阅读完这一部分后,您将能够:

  • 在事务内迁移
  • 创建表之间的关联
  • 设置具有类型和约束的列
  • 在新创建的数据库中植入数据
  • 只需按一下按钮,就能建立一个功能齐全的专业数据库,给别人留下深刻印象

0.目标和准备

我们的目标是为一个名为 BeerSnob 的网站创建一个数据库结构;一个专门为喝优质啤酒的人建立的网站。它允许用户分享关于他们在特定场所喝的啤酒的评论;在提供价格和口味信息的同时,对场地和啤酒进行评级。为了实现我们的目标,我们必须有一个可以存储以下信息的数据库:

  • 用户(撰写评论的人)
  • 啤酒(名称、类型)
  • 国家、城市和比赛场地(出售啤酒的地方)
  • 报告:一个用户在某个地方写一些关于啤酒的信息(比如价格、评级和评论)

报告是我们设计中最重要的部分。查看下面的概述,在一个漂亮的数据库模型中捕获这些需求:

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

BeerSnobs 数据库模型图

如你所见,我们将国家、城市和地点分别放在不同的表格中,这可能有点过分。目前我们并不真的需要它,但如果说这些年来我学到了什么,那就是需求很少保持不变。在未来,我们希望增加可能需要这样设置的功能。以这种方式构建我们的表,我们保证了未来发展的灵活性。

从这个结构来看,报告似乎是最重要的表;它指定了由用户给出的某个地点的啤酒的价格、等级和评论。这是用户在网站上将寻找的东西!

1.设置

我们将在前面的部分中编写的代码的基础上进一步构建。如您所知,我们已经创建了 2 个迁移:

  1. 创建一个名为“app”的模式
  2. 在“app”模式中创建一个名为“countries”的表

如果你想继续编码,从这里拉出代码。

2.添加用户和啤酒表

我们将以创建国家表的相同方式创建用户和啤酒。为了防止这篇文章变得太长,我将跳过重复。检查这个库中的代码。

3.为具有外键的表创建到另一个表的迁移

我们已经定义了相当多的表。现在让我们开始将表连接在一起。首先我们将讨论为什么我们应该使用外键,然后我们将创建一个实现外键的迁移。

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

让我们将这些表格链接在一起(图片由 Travis Saylor像素上拍摄)

为什么要使用外键?

外键子表中的列到父表中的主键。在我们的例子中,我们将把城市表中的 CountryId 列连接到国家表中的 Id 列。外键对于保持数据库的整洁和快速非常方便。他们通过防止不正确的输入来做到这一点(不能输入不存在 countryId 的城市)。它还使您能够控制当父表中的引用值被更新或删除时将采取的操作。如果一个国家被删除,外键可以确保属于被删除国家的所有城市也被删除。

创建迁移

现在让我们开始创建一个通过外键将两个表链接在一起的迁移;城市餐桌。首先,我们将使用 npx sequelize-cli migration:create --name create_city生成一个新的迁移。我们将如下定义迁移:

这段代码中有几件有趣的事情:

  1. 我们用引用创建 CityId。我们将在第 1 部分中定义的 tableModel_countries 表中的 Id 列作为目标。这将创建一个外键。
  2. 我们设置了一些列默认值(新日期()用于创建和修改)。当你没有传递一个值时,它默认为这里设置的值。
  3. 我们在 Id 和 Name 列上创建 come 索引
  4. 我们在一个事务中完成所有这些。例如,如果添加索引失败,它也会回滚到创建表。这样我们保证要么一切都失败,要么一切都成功。点击了解更多交易信息

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

我们新做的 PK,FK 和指数

在这次迁移中,我们创建了包含 5 列的城市表,一个主键(蓝色箭头),一个外键(绿色箭头)和两个索引(橙色箭头)。记住,迁移是独立于数据库的;这是非常强大的东西!

4.添加场馆表

这与城市表非常相似。查看中的代码以了解细节。

5.添加报告表

这是一切汇集的地方;我们必须真正注意这里!我们必须创建一个表,其中的外键指向另外 3 个表。让我们开始吧:

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

更有 PK,FK 和指数

如您所见,我们已经成功地创建了带有绿色外键、蓝色主键和橙色索引的表。

6.删除/添加列

迁移不仅在设置表时很重要;它们也可以在数据库生产时使用。在 BeerSnob 中,我们希望进行迁移,从“countries”表中删除“Capital”列。这无关紧要。在下面的迁移中,我们定义了如何进行和撤消:

'use strict';
let tableModel = { schema: 'app', tableName: 'countries' };
module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.removeColumn(tableModel, 'Capital')
},
down: async (queryInterface, Sequelize) => {
    await queryInterface.addColumn(tableModel, 'Capital', {
     allowNull: true, type: Sequelize.STRING });
 }
};

在迁移中,您可以看到 queryInterface 是如何删除和添加列的。

7.使用我们的模型→播种一些数据

我们创建了表,设置了外键,完成了索引;我们的数据库模型创建完成了!让我们插入一些数据,这样我们就可以检查是否一切正常。

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

播种会将一些默认数据放入我们的数据库中,如管理帐户(图片由 Binyamin MellishPexels 上提供)

处理用户数据

用户将向我们发送一个包,其中包含一个或多个(或很多,如果他有一个良好的夜晚)报告。每个报告都链接到用户配置文件(用户表)、啤酒表中的特定记录和地点。在网站和数据库之间将有一个 API 来处理数据包。如果用户报告一种尚不存在的啤酒,那么 API 应该首先在 Beers 表中创建一条记录,并在将记录写入报告时使用新创建的啤酒的 Id 列。在这篇文章中,我们将研究 API 是如何做到这一点的。现在我们用种子来模拟它。

插入种子数据

首先,我们将为所有的表插入一条记录。我不会在本文中详细讨论每一个种子,但是你可以在这里的库中查看它们。我将在下面提供一个例子,说明我是如何植入报表的,这是我们最重要的表。首次运行npx sequelize-cli seed:create --name seed_reports。迁移编码如下:

相当简单!唯一困难的是获得正确的 VenueId、BeerId 和 UserID,但这是 API 的工作。在这篇文章中我们不要担心它。

实践中的外键

查看app.reports表;您将看到我们在种子文件中定义的三条记录。想象一下当一个场馆关闭时。我们不能对不存在的场馆进行报道!这就是外键的用武之地。请记住,父表中的记录链接到子表中的相关记录。因为我们已经删除了[onDelete: CASCADE],所以删除 Venues 表中的记录会导致删除 reports 表中的相关记录。通过执行DELETE FROM app.venues WHERE “Id” = 2;来尝试一下,然后再次检查报告表!

结论

在本文中,我们在第一部分的基础上构建。我们对它进行了大量升级,增加了一组完美的链接表,包括索引、主键、默认值和其他约束。我们已经走了很长的路,但更多的升级等待着我们。查看这篇文章,了解我们如何通过构建一个与数据库通信的 API 来允许访问数据库数据,而无需编写一行 SQL!关注我了解更多改进。

—迈克

附注:在 https://github.com/mike-huls/beersnobv2 查看完整的项目

页(page 的缩写)又及:比如我正在做的事?跟我来

使用 Google Drive 对大型数据集进行版本控制

原文:https://towardsdatascience.com/version-control-your-large-datasets-using-google-drive-dd42211ab740?source=collection_archive---------24-----------------------

使可再现的数据集成为可能

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

照片由大卫·普帕扎Unsplash 上拍摄

MLOps 最近在机器学习社区获得了一些关注。有了这么多的实验,跟踪、管理和协调它们与其他组件已经成为最近讨论的一个重要主题。特别是,当你尝试你的实验时,数据集一直在变化。您可能正在进行缩放、创建新要素、消除要素或只是对整个数据集进行采样。像data_feat1.csvdata_scaling.csvdata_v2.csv等命名约定。对于最初的几个实验来说是可以的,但是当你扩大实验规模的时候就很痛苦了。

所以,我想我们可以使用 git 来控制数据集的版本。但是 git 不允许存储大于 100 MB 的数据或者对数据进行版本控制。例如,这里我只是将一个非常著名的MNIST数据集用于版本控制。

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

图片来自作者

git add *
git commit -m "Adding files"
git push -u origin master

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

从上面的截图可以看出,git 不接受大于 100 MB 的文件直接推送。我遇到了两个可供尝试的选择:

  1. 使用 Git 大文件存储(建议在输出终端使用)
  2. 使用 DVC 进行数据集的版本控制。

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

作者创建的图像

我没有使用 Git LFS(大文件存储),因为当使用版本控制系统如 DVC 来跟踪你的模型、度量等时。把所有东西都放在一个系统下会变得更容易。DVC 提供了几个选项来存储数据集,如亚马逊 S3、Azure Blob 存储,但我最喜欢的是 Google Drive。DVC 设计的系统,整个过程是无缝集成,一旦你开始使用 DVC。以下是说明如何做到这一点的步骤:

步骤 1:初始化存储库:

在您当前拥有数据集的本地目录/位置中初始化 git 和 DVC。转到终端,键入以下内容:

$ git init
$ dvc init

注意:dvc init需要输入准确的位置。git 文件已定位。请确保这一点,否则您的dvc将无法识别 git 文件。这里我们将尝试初始化大约 105 MB 的训练数据。

步骤 2:暂存要提交的文件:

$ dvc add *
$ ls -alh

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

您将看到创建了一个名为train.csv.dvc的新文件,使用以下代码将新文件提交给 git:

$ git add .gitignore train.csv.dvc
$ git commit -m "Adding training data"

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

如果您看到这个.dvc文件的内容,您会看到 md5 和 path,这是一个链接到数据的元文件,可用于跟踪数据。

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

在这里,提交是在本地完成的。然而,这些文件还没有被推送或存储到任何地方(这里是 google drive)。

第三步:将文件推送到谷歌硬盘:

下一步是定义要存储文件的存储位置。您可以使用以下代码来完成该操作:

$ dvc remote add -d storage gdrive://auth_code_folder_location

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

接下来是 git 提交,使用:

git commit .dvc/config -m "Config remote storage"

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

您可以使用以下方式将数据推送到存储位置:

dvc push

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

作者形象

如果您没有安装软件包pydrive2,可能会出现上述错误。

pip install pydrive2

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

点击链接并验证它是否提供了访问 DVC 的权限,以将文件推送到谷歌存储。一旦您允许,它将提供一个需要输入终端的验证码,如下所示:

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

一旦你输入代码,你会看到文件被推送到谷歌驱动器。

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

作者创造的形象

第 4 步:将您的元信息推送到 Github:

现在所有的跟踪信息都在本地 git repo 中进行版本控制。你可以把这些都推给你的 Github 回购计划。您可以在终端中执行以下步骤:

$ git remote add origin <your repo>
$ git push -f origin master

您应该可以在 github 上看到所有的变化:

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

现在让我们说,如果你想从其他地方/电脑访问数据,你需要安装 DVC,你可以按照下面的步骤在本地下载数据。

首先要检查数据是否存在,您只需输入以下内容:

dvc list <your repo>

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

作者的形象

但是在下载数据之前,您需要克隆存储库。您可以执行以下操作:

git clone <your repo>

克隆回购后,可以进行git pull。它将提示一个 url,需要像以前一样进行验证。请参见下面的截图:

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

最后,您会看到文件被下载到您的本地计算机上!瞧。!

感谢您抽出时间阅读本文。我希望你喜欢这个内容,并对你有所帮助。请随意发表评论,提出任何建议/想法。

跟我上 Twitter 或*LinkedIn*。你也可以通过 pratikkgandhi@gmail.com 联系我**

如您想成为 中型会员 并无限享受阅读文章的乐趣,请注册会员。Medium 将与我分享使用上述链接注册的任何成员的一部分!谢谢。

版本化机器学习实验与跟踪它们

原文:https://towardsdatascience.com/versioning-machine-learning-experiments-vs-tracking-them-f3096a67faa1?source=collection_archive---------26-----------------------

了解如何利用 DVC 提高 ML 重现性

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

照片由王思然·哈德森Unsplash 上拍摄

在进行机器学习项目时,通常会运行大量实验来寻找算法、参数和数据预处理步骤的组合,从而为手头的任务产生最佳模型。为了跟踪这些实验数据,由于没有更好的选择,科学家们习惯于将它们记录到 Excel 表格中。然而,由于大部分是手动的,这种方法有其缺点。举几个例子,它容易出错,不方便,速度慢,而且完全脱离实际实验。

幸运的是,在过去的几年中,实验跟踪已经取得了很大的进步,我们已经看到市场上出现了许多工具,可以改善实验跟踪的方式,例如 Weights & Biases、MLflow、Neptune。通常这样的工具提供了一个 API,您可以从代码中调用它来记录实验信息。然后,它被存储在一个数据库中,您可以使用一个仪表板来直观地比较实验。有了它,一旦你改变了你的代码,你再也不用担心忘记写下结果——这是自动为你做的。仪表板有助于可视化和共享。

在跟踪已经完成的工作方面,这是一个很大的改进,但是……在仪表板中发现一个已经产生最佳指标的实验并不能自动转化为准备好部署的模型。很可能你需要先重现最好的实验。然而,您直接观察到的跟踪仪表板和表格与实验本身的联系很弱。因此,您可能仍然需要半手工地追溯您的步骤,以将准确的代码、数据和管道步骤缝合在一起,从而重现该实验。这能自动化吗?

在这篇博文中,我想谈谈版本化实验,而不是跟踪它们,以及这如何在实验跟踪的好处之上带来更容易的可重复性。

为了实现这一点,我将使用 DVC ,这是一个开源工具,在数据版本化的环境中最为人所知(毕竟它就在名字中)。然而,这个工具实际上可以做得更多。例如,您可以使用 DVC 来定义 ML 管道,运行多个实验,并比较指标。您还可以对参与实验的所有活动部件进行版本控制。

实验版本

为了开始对 DVC 进行版本控制实验,您需要从任何 Git repo 中初始化它,如下所示。注意,DVC 希望你的项目有一个合理的结构,你可能需要重新组织你的文件夹。

$ dvc exp init -i
This command will guide you to set up a default stage in dvc.yaml.
See [https://dvc.org/doc/user-guide/project-structure/pipelines-files](https://dvc.org/doc/user-guide/project-structure/pipelines-files).DVC assumes the following workspace structure:
├── data
├── metrics.json
├── models
├── params.yaml
├── plots
└── srcCommand to execute: python src/train.py
Path to a code file/directory [src, n to omit]: src/train.py
Path to a data file/directory [data, n to omit]: data/images/
Path to a model file/directory [models, n to omit]:
Path to a parameters file [params.yaml, n to omit]:
Path to a metrics file [metrics.json, n to omit]:
Path to a plots file/directory [plots, n to omit]: logs.csv
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
default:
  cmd: python src/train.py
  deps:
  - data/images/
  - src/train.py
  params:
  - model
  - train
  outs:
  - models
  metrics:
  - metrics.json:
      cache: false
  plots:
  - logs.csv:
      cache: false
Do you want to add the above contents to dvc.yaml? [y/n]: yCreated default stage in dvc.yaml. To run, use "dvc exp run".
See [https://dvc.org/doc/user-guide/experiment-management/running-experiments](https://dvc.org/doc/user-guide/experiment-management/running-experiments).

您可能还注意到,DVC 假设您将参数和指标存储在文件中,而不是用 API 记录它们。这意味着您需要修改代码,从 YAML 文件中读取参数,并将指标写入 JSON 文件。

最后,在初始化时,DVC 会自动创建一个基本管道,并将其存储在 dvc.yaml 文件中。有了它,您的培训代码、管道、参数和指标现在就存在于可版本化的文件中。

实验即代码方法的好处

干净的代码

当以这种方式设置时,您的代码不再依赖于实验跟踪 API。您不必在代码中插入跟踪 API 调用来将实验信息保存在中央数据库中,而是将其保存在可读文件中。这些在您的 repo 中总是可用的,您的代码保持干净,并且您有更少的依赖性。即使没有 DVC,您也可以使用 Git 读取、保存和版本化您的实验参数和度量,尽管使用普通的 Git 并不是比较 ML 实验的最方便的方式。

$ git diff HEAD~1 -- params.yaml
diff --git a/params.yaml b/params.yaml
index baad571a2..57d098495 100644
--- a/params.yaml
+++ b/params.yaml
@@ -1,5 +1,5 @@
 train:
   epochs: 10
-model:
-  conv_units: 16
+model:
+  conv_units: 128

再现性

实验跟踪数据库并不能捕获重现实验所需的所有信息。经常缺失的一个重要部分是端到端运行实验的管道。让我们看一下已经生成的管道文件“dvc.yaml”。

$ cat dvc.yaml
stages:
  default:
    cmd: python src/train.py
    deps:
    - data/images
    - src/train.py
    params:
    - model
    - train
    outs:
    - models
    metrics:
    - metrics.json:
        cache: false
    plots:
    - logs.csv:
        cache: false

这个管道捕获运行实验的命令、参数和其他依赖项、度量、绘图和其他输出。它只有一个“默认”阶段,但是您可以根据需要添加多个阶段。当将实验的所有方面都视为代码时,包括管道,任何人都可以更容易地复制实验。

减少噪音

在仪表板上,你可以看到你所有的实验,我是说所有的实验。在某一点上,你将会有如此多的实验,你将不得不对它们进行分类、标记和过滤以跟上进度。有了实验版本,你在分享什么和如何组织事情上有了更多的灵活性。

例如,您可以在一个新的 Git 分支中尝试一个实验。如果出了问题或者结果不令人振奋,可以选择不推分支。这样您可以减少一些不必要的混乱,否则您会在实验跟踪仪表板中遇到。

同时,如果一个特定的实验看起来很有希望,你可以把它和你的代码一起推送到你的 repo,这样结果就和代码和管道保持同步。结果与相同的人共享,并且已经使用您现有的分支机构名称进行了组织。你可以继续在那个分支上迭代,如果一个实验偏离太多,开始一个新的,或者合并到你的主分支,使它成为你的主要模型。

为什么用 DVC?

即使没有 DVC,您也可以更改代码,从文件中读取参数,向其他文件写入指标,并使用 Git 跟踪更改。然而,DVC 在 Git 上添加了一些特定于 ML 的功能,可以简化实验的比较和再现。

大型数据版本控制

在 Git 中不容易跟踪大型数据和模型,但是通过 DVC,您可以使用自己的存储来跟踪它们,但是它们是 Git 兼容的。初始化时,DVC 开始跟踪“模型”文件夹,让 Git 忽略它,但存储和版本化它,这样你就可以在任何地方备份版本,并在你的实验代码旁边检查它们。

单命令再现性

整理整个实验管道是实现可重复性的第一步,但是仍然需要用户来执行管道。有了 DVC,你只需一个命令就能重现整个实验。不仅如此,它还会检查缓存的输入和输出,并跳过重新计算之前生成的数据,这有时会节省大量时间。

$ dvc exp run
'data/images.dvc' didn't change, skipping
Stage 'default' didn't change, skippingReproduced experiment(s): exp-44136
Experiment results have been applied to your workspace.To promote an experiment to a Git branch run:dvc exp branch <exp> <branch>

更好的分支机构

虽然 Git 分支是一种灵活的组织和管理实验的方式,但是通常有太多的实验不适合任何 Git 分支工作流。DVC 跟踪实验,所以你不需要为每个实验创建提交或分支:

$ dvc exp show ┏━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━┓ ┃**Experiment**               ┃ **Created**      ┃    **loss** ┃    **acc** ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━┩ │**workspace**                │ **-**            │ **0.25183** │ **0.9137** │ │**mybranch**                 │ **Oct 23, 2021** │       **-** │      **-** │ │├──9a4ff1c **[exp-333c9]**   │ 10:40 AM     │ 0.25183 │ 0.9137 │ │├──138e6ea **[exp-55e90]**   │ 10:28 AM     │ 0.25784 │ 0.9084 │ │├──51b0324 **[exp-2b728]** │ 10:17 AM     │ 0.25829 │ 0.9058 │ └─────────────────────────┴──────────────┴─────────┴────────┘

一旦您决定了这些实验中哪些值得与团队分享,就可以将它们转换成 Git 分支:

$ dvc exp branch exp-333c9 conv-units-64
Git branch 'conv-units-64' has been created from experiment 'exp-333c9'.
To switch to the new branch run:git checkout conv-units-64

这样你就可以避免在回购中产生混乱的分支,并且可以专注于比较那些有前途的实验。

结论

总的来说,实验版本化允许您以这样一种方式来编码您的实验,即您的实验日志总是连接到进入实验的确切数据、代码和管道。你可以控制哪些实验最终与你的同事分享以供比较,这可以防止混乱。

最后,复制一个版本化的实验变得像运行一个命令一样简单,如果一些管道步骤缓存了仍然相关的输出,它甚至可以比最初花费更少的时间。

谢谢你陪我到帖子结束!要了解更多关于管理 DVC 实验的信息,查看文档

振动数据及其分析技巧

原文:https://towardsdatascience.com/vibration-data-and-a-few-techniques-to-analyze-it-549f311cd1e9?source=collection_archive---------17-----------------------

振动信号和几种有前途的时频分析技术

什么是振动信号?

振动是一种机械事件,其中围绕一个平衡点发生振荡,携带这些振荡信息的时间序列称为振动信号。这些来自平衡点的振荡需要以高采样率获得。振动信号通常可以用正弦波来表示,如下图所示,正弦波有几个重要的特性,在分析时应该记住(如下所述)。

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

“作者提供的图像”

  • 振幅或峰值: 提供了冲击事件的细节,但它不考虑持续时间,因而也不考虑事件中的能量。
  • 峰峰值: 提供波的最大偏移,这在查看位移信息时很有用
  • RMS (均方根):最有用,因为它与振动信号的能量含量直接相关,并因此与振动的破坏能力相关,因为它考虑了波形的时间历程。

振动信号大多是非线性、非平稳的,对非平稳信号进行分析是一项具有挑战性的任务。

什么是平稳和非平稳信号?

稳定的信号可以由具有恒定时间周期的正弦波表示,而非稳定的信号将具有具有变化时间周期的正弦波。或者换句话说,如果信号的频率或频谱内容不随时间变化,我们可以称之为平稳信号,因为非平稳信号的频率随时间变化。下图给出了平稳和非平稳信号的一个例子,以及它们的频率分布。

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

平稳和非平稳信号及其功率谱示例[ref-1]

分析振动信号的技巧有哪些?

经验模式分解

EMD 是一种自适应方法,它将非线性和非平稳信号分解成几个固有模态函数(IMF)和一个残差。EMD 算法基于筛选过程,当残差保持为常数、单调斜率或只有一个极值的函数时,筛选过程结束。

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

一个“信号”分解成 10 个“IMF”和“残余”。参考文献 2

基于希尔伯特-黄变换和经验模态分解的特定频带分离

经验模态分解(EMD)可以将振动信号 S[n]分解成窄带 IMF。每个 IMF 都满足两个基本条件:

  • 数据中极值的计数和零交叉的计数必须相同,或者允许相差最大一个,以及
  • 根据它们的定义,从局部最大值和局部最小值获得的包络的平均值在瞬间为零。

将振动信号分解成窄带后,对 IMFs 进行希尔伯特变换,提取瞬时频率。例如,下图显示了振动信号的五个基于频率范围的频带,它们是在瞬时频率的帮助下从 EMD 分解的振动信号中分离出来的,瞬时频率是使用 HT 从每个 IMF 中提取的,HT 为每个样本确定一个频率值。

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

频率范围内振动信号的五个频段,(I)delta:0–4Hz,(II)theta:4–8Hz,(III)alpha:8–13Hz,(IV)beta:13–30Hz 和(V)gamma:30–60Hz参考文献 3

利用上述方法,可以提取振动信号的多种节律,这对各个方面都有帮助。

对振动信号进行时频分析的几种常用方法如下:

  1. 短时傅立叶变换(STFT)
  2. 小波变换(连续/离散小波变换)
  3. 斯托克韦尔变换
  4. 维格纳-维尔分布(WVD)
  5. 平滑伪维格纳-维尔分布

我们将通过一个非常简单的振动信号(包含低频和高频)示例来理解它们的时频表示,如下图所示。

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

具有两种不同频率的人工振动信号【参考文献 4】。

现在,让我们用各种方法来看看给定信号的时频表示(TFR)。

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

给定信号在短窗和长窗下的短时傅里叶变换[ref-4]。

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

给定信号的连续小波变换[ref-4]。

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

给定信号的 ST[ref-4]。

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

使用 WVD 对给定信号进行 TFR,我们可以注意到交叉项伪像以高幅度出现【参考文献 4】。

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

使用 SPWVD 计算给定信号的 TFR,我们在这里看不到交叉项伪像[ref-4]。

这里,变换的目的是可视地呈现有区别的时间和频率特征;因此,只显示了幅度。通过这个博客,人们可以了解如何从各种方法计算的频谱有区别地提出一个振动信号。技术的选择取决于信号特性和/或结果的进一步使用或后续处理。重要的方面是期望的时间和频率分辨率以及伪影的耐受性。例如,如果我们想要检测交叉项伪像,我们应该考虑 WVD,而忽略伪像 SPWVD 是更好的选择。

选择方法的另一个例子是上图(具有短窗口和长窗口的 STFT)包含短窗口和长窗口的频谱图,其中我们分别看到频率的高分辨率和低分辨率。根据应用,我们可以选择窗口大小。然而,随着高分辨率频率的增加,时间分辨率降低。同时,我们不能同时具有高分辨率,但是窗口大小允许我们在时间和频率分辨率之间进行权衡,并且可以根据要求优化窗口大小。

关于本博客中包含的方法,有以下几点,可能有助于根据需求选择合适的方法。

  • STFT——易于解读;使用快速傅立叶变换的快速实现:但是有限且固定的分辨率
  • WT —分辨率不固定;分辨率取决于频率(多尺度属性);通常,较低频率分量具有更令人满意的频率分辨率和更粗糙的时间分辨率,而较高频率则相反
  • ST —倾向于强调更高频率的内容。
  • WVD——克服了分辨率有限(计算每个时间步长的频率内容)、强伪像、实施速度慢的问题

下面给出了变换分辨率的示意图,包括用于比较的时域表示和标准傅立叶频谱。

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

[参考文献 4]

本博客简要介绍了振动信号及其重要特征。在博客的后面,我们将讨论时间序列的平稳和非平稳属性。我们还讨论了几种流行的用于振动信号分析的时频分析技术。在博客的最后,我们将讨论这些技术的优缺点,以及如何选择振动信号分析技术。

参考文献

  1. 普恩特·吉伦出版社,2016 年。根据驾驶行为预测困倦(利兹大学博士论文)。
  2. Rai,k .,Bajaj,v .和 Kumar,a .,2015 年。用于病灶和非病灶脑电信号分类的特征提取。在信息科学与应用(第 599–605 页)。斯普林格,柏林,海德堡。
  3. Bajaj,v .,Rai,k .,Kumar,a .,Sharma,d .,Singh,G.K .,2017 年。基于节律特征的局灶性和非局灶性脑电信号分类。 IET 信号处理11 (6),第 743–748 页。
  4. 学校,s . 2021。傅立叶、Gabor、Morlet 或 Wigner:时频变换的比较。 arXiv 预印本 arXiv:2101.06707

云中的视频人工智能:6 个平台和 API

原文:https://towardsdatascience.com/video-ai-in-the-cloud-6-platforms-and-apis-a0aeed65ba99?source=collection_archive---------22-----------------------

概述了这一新兴领域的一些领先厂商的产品功能。

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

来源: Pixabay

人工智能(AI)越来越多地被用于管理视频内容。基于深度学习的计算机视觉技术可以帮助识别视频流中的概念和人脸,对视频进行分类,自动添加字幕,并使用超分辨率等技术增强视频和图像。

从零开始开发视频 AI 是一项巨大的投资。今天,你可以利用许多云平台提供的强大的视频 API,利用视频人工智能功能。

在这篇文章中,我将描述几个世界上最先进的视频人工智能平台:

  • 自动警报系统
  • 微软 Azure
  • 谷歌云平台
  • IBM 沃森
  • Pixop
  • 瓦洛萨

1.AWS 上的视频 AI

AWS 为视频提供的核心人工智能服务有:

亚马逊认知

这项服务使用成熟、高度可扩展的深度学习技术,可以轻松地将图像和视频分析添加到您的应用程序中。该服务不需要机器学习专业知识。它可以让您:

  • 识别图像和视频中的物体、人物、文本和场景
  • 检测不适当的内容
  • 执行精确的面部分析和面部检测—适用于用户识别、人口统计和公共安全场景
  • 亚马逊 Kinesis 视频流

这项服务可以让您安全地将视频从连接的设备流式传输到 AWS,以进行分析、机器学习(ML)分析和播放。

Kinesis Video Streams 可自动设置和扩展从数百万台设备中捕获视频流数据所需的所有基础设施。它可以永久存储、加密和索引视频数据,以便通过易于使用的 API 进行访问。

Kinesis Video Streams 支持实时和点播视频流,并允许您执行基于人工智能的视频分析视频 Amazon Rekognition,以及 Apache MxNet、TensorFlow 和 OpenCV 等开源框架。

2.微软 Azure 上的视频 AI

微软认知服务是 Azure cloud 上提供的一项服务,包括支持视频图像分析的视觉包。视觉套件提供以下功能:

  • 计算机视觉 —可以识别物体、打字和书写的文本、动作(比如走路),可以识别图像的主色。
  • 内容仲裁者 —可以检测文本、视频和图像中的不当内容。
  • 人脸 API —可以检测人脸并进行分组,还可以识别人脸的年龄、性别、情绪、姿势和面部毛发。
  • Emotion API —可以识别和描述面部表情的人脸识别工具。
  • 定制视觉服务 —让您用自己的数据构建定制的图像识别模型。
  • 视频索引器 —一个可以帮助你在视频中找到人的工具,还可以检测言语的情绪,标记某些关键词。

在 Azure cloud 中,通常使用弹性 blob 存储服务来存储数据。然而,对于要求苛刻的应用程序和实时 AI 处理,有时使用 Azure premium 存储更好

3.谷歌云平台上的视频 AI

谷歌云平台提供服务和 API,让你对视频流和视频文件进行基于 AI 的操作。

视频智能 API

提供预训练的机器学习模型,可以自动识别存储和流式视频中的大量对象、位置和动作。它开箱即用,在常见用例中提供高性能,并不断更新和重新训练新的对象和概念。

自动视频智能

Google AutoML Video Intelligence 提供了一个图形界面,允许具有最少机器学习经验的用户训练定制模型,以便对视频中的对象进行分类和跟踪。该解决方案适用于需要预训练视频智能 API 未涵盖的标签的项目。

4.IBM Watson 的视频人工智能

IBM Watson Media 是一个用于媒体工作流和视频处理的人工智能平台。其视频丰富产品为视频数据提供计算机视觉解决方案。

您可以通过 IBM Watson Media 流式传输事件、观看、视频营销产品发布和 OTT 流。视频丰富使您能够优化视频质量,执行自动视频搜索并自动创建字幕。教育工作者和媒体公司使用该解决方案来改进视频工作流程和盈利内容。

5.使用 Pixop 的视频人工智能

PIxop Platform 是一个 web 应用程序,可以帮助您在云中存储、转码和处理视频文件,利用机器学习。

Pixop 提供了广泛的功能,包括视频质量分析、基于项目的视频资产管理模块,以及一些支持团队和客户之间协作的功能。

Pixop 平台完全基于云,不需要硬件投资,也不需要安装软件。以下是 Pixop 的几个显著特点:

  • Pixop 深度恢复 —通过执行去模糊、消除压缩伪像以及将细节注入降级视频等任务,帮助恢复视频质量。
  • Pixop 超分辨率 —这是一个透明的升级器,有助于锐化和提高分辨率,提供比插值更精确的结果。
  • Pixop Denoiser —帮助减少数码噪音,改善粒状素材。
  • Pixop 解交错扫描仪 —帮助重建交错视频的细节,并将其转换为非交错和渐进的形式。
  • Pixop 去抖动器 —帮助稳定和修复因视频转换为数字格式而移位的扫描线。

6.视频人工智能与瓦洛萨

Valossa AI 是一个技术平台,为视频内容提供分析和自动化配置。它提供了以下主要功能:

  • 自动预览 —自动生成视频预览,加速内容营销和促销活动。可用于创建视频点播服务,提供在线视频的智能预览。
  • 视频识别 API —能够检测和描述视频流中的关键概念。生成场景级别的时间编码元数据,支持视频内容的搜索、检索和组织。
  • 人脸分析工具包 —实时识别视频内容中的人脸。分析实时行为和人口统计属性。这通过将人工智能与实时摄像头馈送结合起来,实现了交互式应用。

结论

基于云的视频人工智能平台提供了令人惊叹的功能,即使你的团队不具备数据科学技能,你也可以轻松利用这些功能。通过使用视频人工智能平台,您可以实现以下部分或全部目标:

  • 视频流的自动化预处理
  • 自动优化视频质量
  • 识别视频中的对象、文本和概念
  • 自动为视频添加标题、标签和类别
  • 创建视频预览和短片

我希望这将有助于您构建下一代视频产品。

边缘视频分析

原文:https://towardsdatascience.com/video-analytics-at-the-edge-1c1e05c5fd5a?source=collection_archive---------20-----------------------

使用 Raspberry PI 和英特尔 NCS 从 CCTV IP 摄像机中检测人体

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

尼克·洛格在 Unsplash 上的照片

我最近在家里安装了闭路电视系统。它由 4 台 IP 摄像机组成。我希望他们更聪明一点。不要总是看闭路电视录像,如果任何一个摄像机检测到有人,最好能得到通知。这真是一个很酷的东西。我想,如果任何一台摄像机检测到运动,我能在电报中得到一个警报,那就太好了。虽然我开始只是为了好玩,但我学到了很多。从根本上说,它无需云就能在边缘实现视频分析。我在这里分享我的学习,并渴望向你学习,如果有优化的方法。

目标

我有 4 个不同的 IP 摄像头,可以以 25FPS 的速度播放 720P 的视频。我有一个闲置的树莓派,还有一个英特尔 Movidius 神经计算棒(即第一代 NCS)。我希望 Raspberry PI 和 NCS 执行人体检测,并在摄像头检测到人体时向我发送电报通知。在构建过程中,我认为有几件事非常重要,它们是

1.我应该能够几乎 24/7 运行应用程序,这意味着代码应该是高效的。CPU 利用率必须尽可能低,以便 PI 的温度得到控制。

2.我应该会立刻收到通知。最优先考虑的是,一旦发生,人的检测应该尽快完成。

3.通知应该包含一个图像,以便我可以理解警报的上下文(是谁的人)。

让我提前告诉你,第 1、2 项比我想象的要难多了。

项目开始:

我认为这是一个简单的任务,假设 Raspberry pi 可以从每个摄像机获得视频帧,NCS 可以执行人体检测。然而,这并不容易。

像往常一样,我从普通的 OpenCV 代码开始,在一台摄像机上读取视频 RTSP 流,看看它是如何工作的。

cap = cv2.VideoCapture(“RTSP URL of the IP Camera”)

while(True):

    ret, frame = cap.read()

    cv2.imshow('frame',frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):

        break

cap.release()

cv2.destroyAllWindows()

然而,很少有事情不像我预期的那样。首先也是最重要的,在实时获取帧时有巨大的延迟。也就是说,即使没有处理(人工检测),也会有大约 5 到 10 秒的延迟,在某些情况下,在运行应用程序的几分钟内,延迟会达到 40 秒。CPU 利用率立即达到 100%。在这一点上,我意识到这比我想象的要复杂得多。所以,我不得不从头开始,看看解决这个问题的最好方法是什么。

在我的分析过程中,我观察到这种解决方案不需要处理来自相机的每一帧。我们绝对不需要分析一秒钟内产生的 25 帧。这是我在设计中使用的主要原则之一,我提出了以下设计。什么参数将帮助我们定义系统可以处理的帧数将在后面讨论。

设计

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

作者图片

正如你可能注意到的,这个想法是在每 X 秒钟内从每个摄像机捕捉 N 个帧。这并不是使系统有效运行的唯一原因。该解决方案利用了 Raspberry pi 中可用的硬件加速,因此 CPU 使用率非常低。这将在我描述 GStreamer 时详细介绍。帧数和持续时间可变的原因是,它完全基于用于处理帧的硬件的处理能力。据我所知,第一版英特尔 NCS 能够执行的推理数量较少。正如您所想象的,该图清楚地显示了处理引擎中的瓶颈,因为它必须处理所有的帧。由于我计划利用现有的英特尔 NCS,我必须根据 NCS 的能力调整这些参数。

作为一个起点,我决定在每一秒钟内从每一台摄像机中捕捉一帧。这在我看来是有道理的。因为对于一个人来说,在不到一秒的时间内通过摄像机的观察区域实际上是不可能的。然而,处理引擎有可能无法检测到对象,但这是一个单独的主题,我们将在后面讨论。

我意识到,当我使用 OpenCV 时,很难指定我想要捕捉的帧数/秒。因此,探索并发现可能有两种方法来解决这个问题。一个是 GStreamer,另一个是 FFMPG。所以我决定进一步探索第一个选项 GStreamer。

我发现 GStreamer 非常强大,但由于缺乏文档/示例,它非常复杂。所以我开始在 youtube 上探索一些教程,我发现它们非常有用。我在参考资料部分提到了帮助我学习 GStreamer 的链接。我相信这对你也会有帮助。

安装和设置

这个实验的源代码可以在这里找到:

https://github.com/abypaulvarghese56/Edgevisionpi

我的第一步是在 Raspberry PI 中安装 GStreamer。这是相当直接的。

sudo apt-get install gstreamer1.0-tools

下一步是为 raspberry PI 安装英特尔 OpenVino toolkit。这是必要的,因为处理引擎是英特尔 NCS。我必须安装一个支持英特尔 NCS 的 OpenVINO 版本,因为最新版本的 OpenVINO 只支持英特尔 NCS 2。请点击下面的链接,并根据您拥有的 NCS 安装 OpenVINO。

其他库包括:

pip install telepot
pip install viztracer

sudo apt-get install pkg-config libcairo2-dev gcc python3-dev libgirepository1.0-dev
sudo apt-get install python3-gi

pip install gobject PyGObject

下一步是创建 GStreamer 管道。正如我前面提到的,它是非常强大的工具。Gstreamer 通过使用管道来配置,管道是一系列命令,指定从哪里获取视频,如何处理和编码视频,然后将视频发送到哪里。

让我们看看我创建的管道。

pipelinestring = "rtspsrc location={0} name=m_rtspsrc ! rtph264depay ! h264parse ! v4l2h264dec capture-io-mode=4 ! video/x-raw ! v4l2convert output-io-mode=5 capture-io-mode=4    ! video/x-raw, format=(string)BGR, width=(int)640, height=(int)480 ! videorate ! video/x-raw,framerate=1/1 ! appsink name=m_appsink sync=false"

让我们看看每个元素的用途。

RTSP src location = { 0 }-该位置是摄像机流的 RTSP url。

rtph264depay —从 RTP 包中提取 H264 视频。

v4l 2h 264 dec——这个很有意思。这告诉 Raspberry PI 使用 GPU 解码 H264。请记住,有一个替代方案是使用 CPU 来解码。是 avdec_h264。如果我们试图只从一个摄像头解码,使用 avdec_h264 可能会有效。然而,因为我们的目标是从 4 个摄像头捕捉,所以将它卸载到 GPU 是非常必要的。

让我们看看参数,

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

将视频解码卸载到 GPU 是我们实现最小化 CPU 使用的目标的关键一步。

v4l2convert —这是让系统知道使用 GPU 而不是 CPU 来转换帧。有一个相当于视频转换 CPU。这又是一个 CPU 密集型过程,所以我们应该使用 v4l2convert 来利用 Raspberry PI 提供的硬件加速。我们在这里做一些转换,他们是

将源格式转换为 BGR 格式。帧尺寸缩小到 640x480(从原来的 720P)。v4l2convert 的文档显示,有一个选项可以使用 v4l2convert 本身来控制帧速率。然而,我不能让它工作。请让我知道,如果你们中的任何人让它工作,我会很高兴听到。我不得不使用另一个 videorate 来控制帧速率,因为我无法让 v4l2convert 控制帧速率。

这将帮助我们控制我们想要在应用程序中捕获的帧速率。在我们的例子中,我们希望从摄像机中每秒只捕捉一帧。所以会是 framerate="1/1 "。假设我们只想在两秒钟内捕捉一帧,那么帧速率将是“1/2”。如果我们想在一秒钟内捕捉 5 帧,帧速率将是“5/1”

现在的想法是使用多重处理运行视频捕获应用程序,以利用 Raspberry PI 的不同内核。主程序将为每个摄像机启动一个单独的进程。

其余的事情相当简单。一旦帧被捕获,它就被转换成 OpenCV 格式并被推入队列。目前这种转换是使用 python 代码完成的,请让我知道是否有办法在 GStreamer 管道中处理它。我假设会有,但我没有调查。据我所知,如果我们能够在 GStreamer 管道中处理它,它可以进一步减少 CPU 的使用。因为我们有 4 个不同的摄像机,所以会有 4 个不同的队列。队列使用 TCP 协议,因为如果我们希望这个系统在多个硬件上工作,这将有助于我们将来分配负载。也就是说,我们可以根据我们的需求扩展处理服务器,提高帧速率或捕捉间隔,或者添加更多的摄像头。也许我们会在下一个版本中针对分布式环境进行优化。

在 main_prgall.py(第 27 行)中,您需要输入您的流的 RTSP URL

self.camlink1 = 'rtsp://<username>:<password>@192.168.1.2:554/cam/realmonitor?channel=1&subtype=0&unicast=true&proto=Onvif' #Add your RTSP cam link

并根据您的环境添加其余的流 URL。

您可以从 OpenCV 使用 GStreamer 管道。Opencv 需要在 GStreamer 支持下构建。

处理服务器

这个想法非常简单,从队列(4 个队列)中抓取帧,并将其推送到英特尔 NCS。这里的队列使用发布/订阅模型工作。摄像机是酒馆,流程服务器是 SUB。如果 NCS 在一个帧中检测到一个人,我们将把这个帧移到另一个队列中。我使用的是英特尔型号 zoom 的个人检测零售 013 型号。该模型的详细信息可在此处找到:

https://docs.openvinotoolkit.org/2021.2/omz_models_intel_person_detection_retail_0013_description_person_detection_retail_0013.html

您应该使用与您的设备兼容的型号,这一点非常重要。如果您有 NCS2,那么您应该使用支持 NCS 2 的型号。这是一个可以在视频帧中检测出人的模型。它接受高度为 320、宽度为 544 的输入帧

通信引擎

这是一个非常简单的组件。它从队列中获取已处理的数据,并将图像存储到本地目录中。它还与电报机器人连接,并发送附有图像的通知。

Bot 密钥和用户 ID 从源代码中删除。你必须插入你自己的电报机器人密钥和用户 ID

结果

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

从图像中可以看出,这些帧几乎是实时处理的。在我的测试中,我发现所有的帧都能在不到 2 秒的时间内处理。(在不到 2 秒的时间内检测到运动)。电报机器人发送图像时可能会有轻微的延迟,但这是基于你的互联网连接。然而,我发现它在几乎所有的情况下都可以忽略不计。

CPU 消耗

CPU 消耗大约为 30–35 %,考虑到它每秒钟处理 4 个不同流的视频,这是可以接受的。下图显示了 raspberry pi 报告的 CPU 消耗和温度。

我发现了另一种降低 CPU 占用率的方法。这不在 python 脚本中,而是在 CCTV 本身中。大多数 IP 摄像机支持多个流。即一个主流(具有高质量分辨率和帧速率)和一个分辨率降低的子流(在我的例子中是 640x480)。以下截图显示了我的相机网络界面中的设置

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

下图显示了连接到子流时的 CPU 利用率和温度

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

您可能会注意到,整体 cpu 利用率在 16–22%之间,这似乎非常合理。由于繁重的工作是由 GPU 完成的,因此系统能够在不到 2 秒的时间内处理多个流,同时占用较少的 CPU 资源

结论

树莓派是一个很棒的平台。您将能够找到大量的库和支持。相对便宜又高效。英特尔 NCS 1 尽职尽责。很可能英特尔 NCS2 将能够执行更多的推理,因为它被宣传为在性能方面更好。我没有机会在 NCS 2 中测试这个应用程序,因为我没有机会。我真的很想听听你们中是否有人愿意在 NCS2 中测试脚本并报告性能。话虽如此,只是碰巧我的实验用到了 NCS1 和 Raspberry PI。从成本角度来看,如果你从零开始,这可能不是最好的平台。RPI 将花费大约 4K 印度卢比,NCS 花费我大约 8K 印度卢比。很好奇想知道 Nvidia 的 Jetson Nano 2GB 怎么样?它比 NCS2 有更好的性能,不需要像 PI 那样的另一个 SBC。费用在 5000 印度卢比左右。也许我会在下一次更新中提到它。

参考文献

https://github.com/sahilparekh/GStreamer-Python——这是一个很棒的报告,展示了如何在 OpenCV 中获取 RTSP 流。我在我的项目中扩展了这个样本,这归功于各自的所有者。

https://www.youtube.com/watch?v=HDY8pf-b1nA—这是开始学习 GStreamer 的好地方。这真的帮助我了解了 GStreamer。

http://life style transfer . com/how-to-use-gstreamer-app src-in-python/—这是学习高级 Gstreamer 概念的好地方。一组很好的工作示例和很好的解释。

使用 PyTorch 理解视频

原文:https://towardsdatascience.com/video-understanding-made-simple-with-pytorch-video-and-lightning-flash-c7d65583c37e?source=collection_archive---------28-----------------------

了解如何使用 PyTorch 视频和 Lightning Flash 通过 3 个简单的步骤推断自定义视频理解模型

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

沃尔玛最近开发了一个视频理解系统,可以检测新鲜食品的缺陷和腐败迹象。照片由来自 PexelsPixabay 拍摄

视频理解,自动化广泛的商业用例,从零售到医疗保健到农业,它使计算机能够识别视频中的行为、对象和活动。

在其最新发布的版本中,Lightning Flash使用脸书 AI Research 的新 PyTorchVideo 由 Lightning 提供动力的库,为视频理解提供支持。

**https://github.com/PyTorchLightning/lightning-flash

Flash 是一个用于快速原型制作、基线和微调可扩展深度学习任务的库。使用 Flash 进行视频理解使您能够根据自己的数据训练、微调和推断 PyTorch 视频模型,而不会被所有细节淹没。

一旦您获得了基线模型,您就可以无缝覆盖默认配置,并体验 PyTorch Lightning 的全部灵活性,从而在您的数据集上获得最先进的结果。

在这篇文章中,你将学习如何通过三个简单的步骤推断一个定制的视频分类模型。

3 个简单步骤中的视频理解

先决条件从 Github Main 安装 Flash

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

导入 Flash

首先,我们简单地从 flash.video 导入 VideoClassifer 任务。

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

步骤 2 加载预训练模型

然后我们加载我们想要推断的模型。

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

Flash 使训练自定义模型变得容易,要了解更多信息,请查看 Lightning 开发人员教程,了解如何通过 5 个简单步骤轻松微调视频理解模型。

https://devblog.pytorchlightning.ai/5-steps-to-training-your-first-video-classifier-in-a-flash-dd11d472fded [## 快速训练第一个视频分类器的 5 个步骤

devblog.pytorchlightning.ai](https://devblog.pytorchlightning.ai/5-steps-to-training-your-first-video-classifier-in-a-flash-dd11d472fded)

根据视频数据进行推断

然后,我们可以通过传递一个有效的路径来推断单个视频或视频目录的模型,如下所示。

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

把所有的放在一起

这样你就有了根据自己的数据推断视频理解模型所需的所有信息。为了方便起见,所有代码都在这里。

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

后续步骤

现在你知道了如何用 Flash 的三行代码推断出一个视频理解模型,你可以看看 Flash 使其他 7 个计算机视觉任务变得和视频理解一样简单。

  1. 多标签图像分类
  2. 图像嵌入
  3. 物体检测
  4. 语义分割
  5. 风格转移

新的任务一直在贡献,所以请留意更新。如果您有任何问题,欢迎在下面评论或通过 SlackTwitter 与我们联系。

关于作者

亚伦(阿里)博恩施泰因 是一名人工智能研究员,对历史充满热情,致力于新技术和计算医学。作为 Grid.ai 的开发者宣传负责人,他与机器学习社区合作,用改变游戏规则的技术解决现实世界的问题,然后将这些技术记录在案,开源,并与世界其他地方共享。**

SQL 中的视图:未充分利用,但非常有用

原文:https://towardsdatascience.com/views-in-sql-underutilised-yet-very-useful-6895cf607456?source=collection_archive---------18-----------------------

视图如何帮助跨 SQL 数据库的分析

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

来源:图片来自 Pixabay

视图是 SQL 中的虚拟表,其功能类似于标准表,但不需要物理存储,即它只存储在内存中,不占用实际存储空间。

例如,经常会有人希望看到表中数据的子集,或者以某种方式组织的数据。

但是,如果只是为了便于理解数据,那么将数据存储在一个表中可能效率很低,因为这意味着额外的存储空间将被用来有效地从另一个表中创建重复的数据。

让我们来看一些例子。

使用 ORDER BY 和 LIMIT 查询创建视图

考虑下面这个名为衣服(所有条目都是作者虚构的)的假设表,它描述了一家商店出售的一系列衣服。

item               | price   | size 
-------------------+---------+--------
Sky Blue Jeans     |  79.99  | 31
Fire Red Jeans     |  89.99  | 36
Sky Blue Shirt     |  59.99  | 38
Grass Green Shirt  |  69.99  | 34
...
Peach Purple Hat   |  79.99  | 40
Sun Yellow Jeans   |  109.99 | 42
Olive Green Hat    |  89.99  | 37

想象一下,一个表中有数千个这样的条目。但是,商店的所有者想要创建一个视图,其中 1)只显示商品和价格,2)只显示按价格排列的前三个条目。让我们创建一个视图,并将其命名为 condensedclothes :

create view condensedclothes as select item, price from clothes order by price desc limit 3;

结果输出如下:

>>> select view condensedclothes from database;
item               | price   
-------------------+---------
Black Sunglasses   |  149.99
Blue Sneakers      |  129.99
Red Polo Shirt     |  129.99

在这个假设的场景中,我们可以看到下面的视图让所有者快速查看哪些商品的零售价格最高。然而,使用视图具有以下优点:1)它允许所有者快速查看相关信息,而不必每次都输入单独的查询;以及 2)视图不使用存储空间来显示,因为它存储在存储器中。

创建具有内部连接的视图

除了上表之外,假设还存在另一个提供所列项目说明的表:

>>> select * from clothes limit 1;
item               | price   | size 
-------------------+---------+--------
Sky Blue Jeans     |  79.99  | 31>>> select * from clothes2 limit 1;
item                | colour   | type 
--------------------+----------+----------
Grass Green T-Shirt | Green    | T-Shirt

现在,让我们假设所有者希望将两个表连接在一起,并按价格查看前三个销售商品——但这次是从衣服 2 表中添加信息。

>>> create view orderedclothes as select t1.item, t1.price, t2.colour, t2.type from clothes as t1 inner join clothes2 as t2 on t1.item=t2.item order by t1.price desc limit 3;
CREATE VIEW>>> select * from orderedclothes;
           item           | price   | colour  | type
--------------------------+---------+---------+-------
Black Sunglasses          |  149.99 | Black   | Sunglasses
Blue Sneakers             |  129.99 | Blue    | Sneakers
Red Polo Shirt            |  129.99 | Red     | Polo Shirt
(3 rows)

正如我们所看到的,选择新创建的视图(在本例中命名为ordered waters),允许我们按降序查看价格最高的三个项目,但是添加了来自第二个表的信息。

同样,视图存储在内存中,没有使用数据库本身的存储。

视图的缺点

正如我们所看到的,从能够快速方便地查看表的重要部分的角度来看,视图非常有用。它们还具有不占用存储空间的优点。

然而,使用视图也有一些缺点——主要是在数据操作方面。

例如,虽然更新视图中包含的数据是可能的,但在许多情况下都不可能做到。这包括在更新视图时使用联接,使用 GROUP BY 子句,以及在使用视图时 DISTINCT 子句不可用。

在这方面,如果需要定期更新视图中的数据,视图并不总是最佳选择。

但是,值得记住的是,视图中的数据本身可以存储为一个单独的表。

例如,假设我们希望获取 condensedclothes 视图,并将数据存储在一个表中(我们称这个表为 condensedtable )。我们可以这样做:

>>> create table condensedtable as select * from condensedclothes;
SELECT 3>>> select * from condensedtable;
item               | price   
-------------------+---------
Black Sunglasses   |  149.99
Blue Sneakers      |  129.99
Red Polo Shirt     |  129.99
(3 rows)

一旦来自一个视图的数据现在被存储在一个表中,用户就可以更加灵活地利用更大范围的查询,而这在使用视图本身时是不可能的。

结论

本文介绍了 SQL 中的视图以及如何使用它们。特别是,我们看了看:

  • 视图的优势和使用它们的原因
  • 如何在一系列 SQL 查询中实现视图
  • 视图的缺点以及何时以表格格式存储更有意义

同样,使用视图的主要优点之一是,它允许查看表的精简版本,而不必使用存储空间——因为视图存储在内存中。

事实上,视图可以提供两方面的优势,1)在视图中快速分析数据,2)当希望执行更高级的查询时,将数据存储在表中。

非常感谢阅读,任何问题或反馈都非常感谢!您还可以在这里找到原始文章,以及有用的 SQL 实践的更多例子。

参考

  • 斯蒂芬斯、琼斯和普勒(2016):24 小时内的 SamsTechYourself

免责声明:本文是在“原样”的基础上编写的,没有任何担保。它旨在提供数据科学概念的概述,不应被解释为专业建议。本文中的发现和解释是作者的发现和解释,不被本文中提到的任何第三方认可或隶属于任何第三方。作者与本文提及的任何第三方无任何关系。

Viola Jones 算法和 Haar 级联分类器

原文:https://towardsdatascience.com/viola-jones-algorithm-and-haar-cascade-classifier-ee3bfb19f7d8?source=collection_archive---------4-----------------------

初学者完全解释和数学

Viola Jones 是一种快速检测物体的新方法,具有每秒 15 帧的运行能力。这是第一个实现实时目标检测。

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

(图片由作者提供)

在本文中,我将讨论“Viola Jones 算法”,它包括以下子主题:

  1. 维奥拉·琼斯探测器
  2. Haar like 特征是什么?
  3. 什么是整体形象?
  4. 用积分图像计算类哈尔特征
  5. 升压和 AdaBoost 算法
  6. 深入研究 AdaBoost 算法数学
  7. 级联过滤器
  8. 使用 OpenCV 库实现

维奥拉·琼斯探测器

一种中提琴琼斯检测器,包括以下步骤:

  1. 计算积分图像
  2. 计算类哈尔特征
  3. AdaBoost 学习算法
  4. 级联过滤器

哈尔有什么样的特征?

哈尔特征是人脸检测的相关特征。它是由阿尔弗雷德·哈尔在 1909 年提出的。它们就像卷积核。有各种类型的 haar 类特征,但最常用的特征是:

  1. 2 个矩形哈尔特征
  2. 3 个矩形哈尔特征
  3. 4 个矩形哈尔特征

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

(图片作者)灵感(https://docs . opencv . org/3.4/D2/d99/tutorial _ js _ face _ detection . html)

2 矩形特征的值是 2 个矩形区域内的像素之和的差。这些区域具有相同的形状和大小,并且水平和垂直相邻。三矩形特征计算中心矩形的总和。最后,四矩形特征计算矩形对角线对之间的差异。这些不同大小的区域的各种变化在图像中进行卷积,以获得将被输入到 AdaBoost 训练算法的多个滤波器。使用标准技术计算这些特征将需要很长的计算时间。为了缩短这一时间,作者提出了一种称为积分图像的新方法。

什么是积分图?

因为我们必须在所有可能的大小和位置使用 haar-like 特征,这最终导致大约 200k 个特征来计算哪个是真正大的数字。haar 特征的新颖计算的问题在于,我们必须多次计算给定区域的平均值,并且这些操作的时间复杂度是 O(n*n)。我们可以使用积分图像方法来实现 O(1)运行时间。积分图像中的给定像素是左边所有像素和它上面所有像素的总和。

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

(图片由作者提供)灵感(https://www.mathworks.com/help/images/integral-image.html)

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

(图片由作者提供)灵感(https://m.blog.naver.com/natalliea/222198638897)

原始图像中所有紫色框的总和等于积分图像中绿色框的总和减去积分图像中的紫色框。

利用积分图像计算类哈尔特征

使用积分图像,我们可以实现哈尔特征的恒定时间评估。

  1. 边缘特征或 2 个矩形特征仅需要 6 次存储器查找
  2. 线特征或 3 个矩形特征仅需要 8 次存储器查找。
  3. 对角线特征或 4 个矩形特征只需要 9 次存储器查找。

2 矩形 = A-2B+C-D+2E-F

3 矩形 = A-B-2C+2D+2E-2F-G+H

4 矩形 = A-2B+C-2D+4E-2F+H-2I+J

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

计算区域和的技术,用于在恒定时间量内计算 haar 类特征。(图片由作者提供)

升压和 AdaBoost 算法

Boosting 是指任何可以将几个弱学习者组合成一个强学习者的集成方法。大多数 boosting 方法的一般思想是顺序训练预测器,每个预测器都试图纠正其前任。AdaBoost 也称为自适应增强,是最常用的增强技术之一。

AdaBoost :新预测器校正其前任的一种方法是多注意前任欠拟合的训练实例。这导致新的预测者越来越关注疑难病例。这被称为适应性增强。例如,为了构建自适应提升分类器,第一基本分类器(例如决策树或 SVM 分类器)被训练并用于对训练集进行预测。改变和增加误分类预测的相对权重,以便在进行下一个预测时更加重视这些预测。使用更新的权重训练第二分类器,并且再次对训练集进行预测,权重被更新,等等。一旦训练了所有的预测,集成方法使得预测非常类似于增强,除了预测器具有不同的权重,这取决于它们在加权训练集上的整体准确度。这种算法的缺点是它不能并行化,从而增加了所需的时间。因此,在所有特征上成功运行 AdaBoost 之后,我们剩下的是检测所需的最相关的特征。因此,这减少了计算时间,因为我们不必遍历所有的特征,并且效率更高。

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

(图片由作者提供)受启发(使用 Scikit-Learn、Keras 和 TensorFlow 进行动手机器学习:构建智能系统的概念、工具和技术)

深入研究 AdaBoost 算法

让我们仔细看看 AdaBoost 算法。每个实例权重 w(i)最初被设置为 1/m。训练第一预测器,并在训练集上计算其加权误差率 r1

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

这里,我们只取错误分类的实例,将这些实例的权重相加,得到加权错误率(图片由作者提供)

然后使用下面给出的公式计算预测器的权重 j。预测器越精确,其权重就越高。如果只是随机猜测,那么它的权重将接近于零。然而,大多数情况下,它是错误的,其权重将是负的。

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

(图片由作者提供)

接下来,使用下面提供的公式更新实例权重,以提升错误分类的实例

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

(图片由作者提供)

然后,使用下面提供的公式对所有预测值进行归一化。

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

(图片由作者提供)

最后,使用更新的权重来训练新的预测器,并且重复整个过程,直到达到用户指定的预测器的期望数量。

在推理过程中,AdaBoost 简单地计算所有预测器的预测值和权重,然后使用预测器权重αj。预测类是获得大多数加权投票的类。

级联过滤器

  • 强特征形成二元分类器。:正匹配将被发送到下一个特征。否定匹配被拒绝并退出计算。
  • 减少花费在错误窗口上的计算时间。
  • 可以调整阈值来调整精度。阈值越低,检测率越高,假阳性越多。

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

(图片由作者提供)灵感(https://www . research gate . net/figure/Cascade-classifier-illustration-2 _ fig 2 _ 323057610)

简而言之,每个特征都充当级联过滤器中的二元分类器。如果从图像中提取的特征通过分类器,并且它预测图像由该特征组成,则它被传递到下一个分类器,用于下一个特征存在检查,否则它被丢弃,并且检查下一个图像。这因此减少了计算时间,因为我们必须只检查对象不存在的窗口中的一些特征,而不是检查所有特征。这是算法的主要部分,允许它以大约每秒 15 帧的速率处理视频,并实现实时实施。

使用 OpenCV 库实现

参考文献

  1. 使用简单特征的增强级联的快速对象检测:https://web.iitd.ac.in/~sumeet/viola-cvpr-01.pdf
  2. 检测人脸(Viola Jones 算法)——电脑爱好者:【https://www.youtube.com/watch?v=uEJ71VlUmMQ】T2
  3. 使用 Scikit-Learn、Keras 和 TensorFlow 进行机器实践学习:构建智能系统的概念、工具和技术

敬请关注新的研究论文这样的解释!

*请随时联系并给出你的建议:【https://www.linkedin.com/in/mrinal-tyagi-02a1351b1/ *

https://github.com/MrinalTyagi

Python 中的 Violin、Strip、Swarm 和 Raincloud 图是箱线图的更好(有时)替代方案

原文:https://towardsdatascience.com/violin-strip-swarm-and-raincloud-plots-in-python-as-better-sometimes-alternatives-to-a-boxplot-15019bdff8f8?source=collection_archive---------8-----------------------

何时使用它们,如何在 seaborn 库中创建、调整和组合这些类型的可视化

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

来自 Pixabay

创建箱线图是显示数据集统计摘要的最常用方式。然而,有时,我们可能需要可视化额外的统计信息,并对我们的数据进行更细致的查看。这就是其他类型的图表发挥作用的地方:小提琴图、带状图和虫群图,以及它们的混合图,其中最有趣的是雨云图。在本文中,我们将探索 Python 的 seaborn 库中箱线图的这些替代方案,并找出它们中的每一种在哪些情况下最适用。

对于我们进一步的实验,我们将使用 seaborn 的一个示例数据集— diamonds。让我们下载并快速浏览一下:

import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inlinediamonds = sns.load_dataset('diamonds')
print(f'Number of diamonds: {diamonds.shape[0]:,}\n'
      f"Diamond cut types: {diamonds['cut'].unique().tolist()}\n"
      f"Diamond colors:     {sorted(diamonds['color'].unique().tolist())}\n\n"
      f'{diamonds.head(3)}\n')**Output:**Number of diamonds: 53,940
Diamond cut types: ['Ideal', 'Premium', 'Good', 'Very Good', 'Fair']
Diamond colors:     ['D', 'E', 'F', 'G', 'H', 'I', 'J']

   carat      cut color clarity  depth  table  price     x     y     z
0   0.23    Ideal     E     SI2   61.5   55.0    326  3.95  3.98  2.43
1   0.21  Premium     E     SI1   59.8   61.0    326  3.89  3.84  2.31
2   0.23     Good     E     VS1   56.9   65.0    327  4.05  4.07  2.31

数据集相当大。让我们将我们的关注点缩小到超过 2 克拉的理想切割或优质切割的钻石,并且只处理这个较小的数据集。我们只对最好的钻石感兴趣!😀

df = diamonds[((diamonds['cut']=='Ideal')|(diamonds['cut']=='Premium')) & (diamonds['carat']>2)]
print(f'Number of diamonds in "df": {df.shape[0]:,}')**Output:** 
Number of diamonds in "df": 1,216

箱线图

现在,我们可以为每个钻石颜色类别的价格范围创建一个箱线图。颜色用大写字母表示,我们可以在这篇维基百科文章中找到更多关于钻石颜色分级的信息。根据外延,我们数据集中的钻石都是无色或接近无色的。

箱线图的主要作用是显示数据集的五位数描述性统计数据:最小值和最大值、中值、第一(Q1)和第三(第三季度)四分位数。此外,它还显示了较高和较低的异常值(如果有),我们还可以选择在图表上添加第六个维度—平均值:

sns.set_style('white')plt.figure(figsize=(12, 7))
sns.boxplot(x='price', y='color', data=df, color='yellow', width=0.6, showmeans=True)# Create a function to customize the axes of all the subsequent graphs in a uniform way.
def add_cosmetics(title='Prices by color for ideal/premium cut diamonds > 2 ct', 
                  xlabel='Price, USD', ylabel='Color'):
    plt.title(title, fontsize=28)
    plt.xlabel(xlabel, fontsize=20)
    plt.ylabel(ylabel, fontsize=20)
    plt.xticks(fontsize=15)
    plt.yticks(fontsize=15)
    sns.despine()add_cosmetics()

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

作者图片

除了定制图形和轴,我们实际上用 seaborn 编写了一行代码来创建上面的箱线图。我们只调整了图的颜色和宽度,并在每个框上添加了平均值。

上面的方框图清楚地显示了每个颜色类别的价格范围的总体统计数据。此外,从它们的形式来看,存在较低的异常值,平均值几乎在所有情况下都低于中值,我们可以假设每种情况下的价格分布是左偏的,这意味着钻石价格往往相当高。然而,仅仅看这些图,我们无法理解底层数据分布的实际形状和结构。例如,特定颜色类别的分布是单峰的还是多峰的?每个类别包含多少个观察值?不同类别的样本大小有可比性吗?各个观测值在每个分布中的确切位置。

让我们看看创造一个小提琴情节是否有助于我们回答这些问题。

小提琴情节

violin 图类似于 box 图,显示了数据集的相同统计摘要,只是它还显示了底层数据的内核密度图:

plt.figure(figsize=(12, 8))
sns.violinplot(x='price', y='color', data=df, color='yellow', cut=0)
add_cosmetics()

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

作者图片

我们只调整了cut参数,将其设置为 0。这将每个小提琴限制在实际数据的范围内,而不是向外扩展。

回到我们上面的问题,我们可以说,除了从每把小提琴中间的“迷你箱线图”中获得的每个类别的总体统计数据,我们现在可以看到每个分布的形状。是的,我们关于左偏分布的假设现在被完全证实了。

按类别划分的底层数据的结构呢?我们可以调整inner参数来可视化每把小提琴内部的观察位置和密度:

plt.figure(figsize=(12, 8))
sns.violinplot(x='price', y='color', data=df, color='yellow', cut=0,
               inner='stick')
add_cosmetics()

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

作者图片

现在,我们可以看到每个类别范围内的观察密度。显然,D 和 E 色的钻石比 H 和 I 色的钻石少得多,尽管相应的分布形状看起来非常相似。

然而,调整参数后,我们再也看不到每把小提琴内部的微型盒图了。此外,我们还看不到每个的底层数据点。

带状和群体图

这两种类型的图代表了分类变量的散点图的实现,即它们都精确地显示了分布的内部结构,特别是其样本大小和单个观察值的位置。主要区别在于,在群集图中,数据点不会重叠,而是沿着分类轴进行调整。另一方面,带状图中点重叠的问题可以通过设置调节点透明度的alpha参数得到部分解决。

让我们比较一下这些图:

plt.figure(figsize=(16, 11))plt.subplot(2, 1, 1)
sns.stripplot(x='price', y='color', data=df, color='blue',
              alpha=0.3, size=4)
add_cosmetics(xlabel=None)plt.subplot(2, 1, 2)
sns.swarmplot(x='price', y='color', data=df, color='blue', size=4)
add_cosmetics(title=None)plt.tight_layout()

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

作者图片

带状图和群集图的主要缺点是,它们只能在相对较小的数据集上运行良好。此外,它们不像箱线图和小提琴图那样显示五位数的描述性统计数据。

杂交地块

为了避免丢失有价值的信息并结合不同图表类型的优势,我们可以考虑创建混合图。例如,让我们结合每个类别的 violin 和 swarm 图:

plt.figure(figsize=(15, 8))
sns.violinplot(x='price', y='color', data=df, color='yellow', cut=0)
sns.swarmplot(x='price', y='color', data=df, color='blue')
add_cosmetics()

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

作者图片

我们现在清楚地看到,小提琴的内部结构在不同的类别中有很大的不同,尽管它们的外部形状相当相似。实际上,对于具有很少数据点的 D 和 E 颜色类别,创建小提琴图实际上没有意义,甚至会导致错误的估计。然而,对于有许多数据点的类别,swarm 和 violin 图的结合有助于理解更大的画面。

值得注意的是,在上图中,我们几乎看不到被点覆盖的迷你盒图(除非我们决定引入alpha参数),所以我们将移除盒子。此外,让我们为群体图添加另一个维度:区分理想和优质钻石切工的数据点:

plt.figure(figsize=(15, 8))
sns.violinplot(x='price', y='color', data=df, color='yellow',
               cut=0, inner=None)
sns.swarmplot(x='price', y='color', hue='cut', data=df,
              palette=['blue', 'deepskyblue'])plt.legend(frameon=False, fontsize=15, loc='upper left')
add_cosmetics()

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

作者图片

我们可以观察到,相对“便宜”的钻石大多是溢价切割,而不是更高等级的理想切割。

如果组的数量不超过三个,带状图和群集图有助于区分不同组的单个数据点。出于同样的目的,我们可以尝试另一种方法:根据颜色类别分别为理想和优质切割创建分组的小提琴图。然而,考虑到我们的一些颜色类别已经非常小,将它们分开以创建分组的 violin 图将导致每个部分的样本大小和数据密度的进一步减少,使得这样的图更不具有代表性。因此,在这种情况下,带状和群集图看起来是一个更好的选择。

有一种类型的混合地块值得特别关注,所以让我们更详细地讨论它。

雨云图

雨云图本质上是半小提琴图、箱形图和带状图的组合。从上到下连续放置,这些地块共同提醒雨云,因此命名为混合地块。不幸的是,无论是在 seaborn 中还是在 Python 中,都没有针对这类情节的预定义代码解决方案(至少目前是这样,而且至少是以易于使用和理解的形式)。因此,我们将从零开始创建它,结合并调整可用的工具。代码注释中解释了每个步骤的技术细节:

plt.figure(figsize=(15, 10))# Create violin plots without mini-boxplots inside.
ax = sns.violinplot(x='price', y='color', data=df,
                    color='mediumslateblue', 
                    cut=0, inner=None)# Clip the lower half of each violin.
for item in ax.collections:
    x0, y0, width, height = item.get_paths()[0].get_extents().bounds
    item.set_clip_path(plt.Rectangle((x0, y0), width, height/2,
                       transform=ax.transData))# Create strip plots with partially transparent points of different colors depending on the group.
num_items = len(ax.collections)
sns.stripplot(x='price', y='color', hue='cut', data=df, 
              palette=['blue', 'deepskyblue'], alpha=0.4, size=7)# Shift each strip plot strictly below the correponding volin.
for item in ax.collections[num_items:]:
    item.set_offsets(item.get_offsets() + 0.15)# Create narrow boxplots on top of the corresponding violin and strip plots, with thick lines, the mean values, without the outliers.
sns.boxplot(x='price', y='color', data=df, width=0.25,
            showfliers=False, showmeans=True, 
            meanprops=dict(marker='o', markerfacecolor='darkorange',
                           markersize=10, zorder=3),
            boxprops=dict(facecolor=(0,0,0,0), 
                          linewidth=3, zorder=3),
            whiskerprops=dict(linewidth=3),
            capprops=dict(linewidth=3),
            medianprops=dict(linewidth=3))plt.legend(frameon=False, fontsize=15, loc='upper left')
add_cosmetics()

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

作者图片

从上面的 raincloud 图中,我们可以提取每个颜色类别的价格范围的完整统计信息:整体五位数统计、平均值、分布形状、样本大小、基础数据的内部结构,包括各个数据点的位置,以及每个类别中两个不同组之间的区别。然后,我们可以比较颜色类别,了解它们之间的关系和大致趋势。

为了创建一个垂直的雨云图,我们必须对上面的代码做一些小的改动。特别是,在创建每种类型的内部图时,我们必须用 y 替换 x,反之亦然,并剪切每把小提琴的右半部分(即,宽度除以 2,高度保持不变)。至于装饰调整,我们必须交换 x 轴和 y 轴标签,并将图例放在左下角:

plt.figure(figsize=(15, 10))# Create violin plots without mini-boxplots inside.
ax = sns.violinplot(y='price', x='color', data=df,
                    color='mediumslateblue', 
                    cut=0, inner=None)# Clip the right half of each violin.
for item in ax.collections:
    x0, y0, width, height = item.get_paths()[0].get_extents().bounds
    item.set_clip_path(plt.Rectangle((x0, y0), width/2, height,
                       transform=ax.transData))# Create strip plots with partially transparent points of different colors depending on the group.
num_items = len(ax.collections)
sns.stripplot(y='price', x='color', hue='cut', data=df,
              palette=['blue', 'deepskyblue'], alpha=0.4, size=7)# Shift each strip plot strictly below the correponding volin.
for item in ax.collections[num_items:]:
    item.set_offsets(item.get_offsets() + 0.15)# Create narrow boxplots on top of the corresponding violin and strip plots, with thick lines, the mean values, without the outliers.
sns.boxplot(y='price', x='color', data=df, width=0.25,
            showfliers=False, showmeans=True, 
            meanprops=dict(marker='o', markerfacecolor='darkorange',
                           markersize=10, zorder=3),
            boxprops=dict(facecolor=(0,0,0,0), 
                          linewidth=3, zorder=3),
            whiskerprops=dict(linewidth=3),
            capprops=dict(linewidth=3),
            medianprops=dict(linewidth=3))plt.legend(frameon=False, fontsize=15, loc='lower left')
add_cosmetics(xlabel='Color', ylabel='Price, USD')

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

作者图片

当然,我们也可以很容易地将前面的所有图形垂直化,用 y 替换 x,反之亦然,交换 x 轴和 y 轴标签,并移动图例(如果适用)。

结论

在本文中,我们探索了 Python 的 seaborn 库中箱形图的各种替代方案,即 violin、strip 和 swarm 图,以及它们的混合图,包括作为特例的 raincloud 图。我们讨论了每种类型的可视化的优势和局限性,如何对它们进行调整,以及它们可以揭示什么样的信息。最后,我们考虑了适用于垂直旋转图的修改。

为现实世界的任务选择正确类型的图表并不一定意味着试图显示数据中所有可能的信息。相反,它取决于任务本身和可用的数据。有时,仅仅创建一个箱线图就足够了,而在其他情况下,我们必须更深入地挖掘数据,以获得有意义的见解并发现隐藏的趋势。

感谢阅读!

你会发现这些文章也很有趣:

https://medium.com/geekculture/creating-a-waterfall-chart-in-python-dc7bcddecb45

虚拟血管生成:一套新的计算机血管生成工具

原文:https://towardsdatascience.com/virtual-angiogenesis-a-new-set-of-tools-for-creating-in-silico-blood-vessels-96301d5b477d?source=collection_archive---------46-----------------------

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

版权所有:Panthermedia.net/Ugreen

思想和理论

在心血管研究领域,在全球或区域循环中发现的许多循环系统疾病始于控制外周(小动脉和毛细血管)血流和细胞功能之间相互作用的功能失调的化学-机械配对。循环的数学模型和计算机模拟及其与细胞功能的耦合为拓展心血管研究的边界提供了强有力的工具。

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

顺序血管生长(图片由作者提供)。

然而,血流模型和细胞耦合需要在微血管水平实现定义域。这可以通过成像技术来实现,这种技术能够提供动物模型中小血管的高分辨率图像。但是,即使有了这些工具的力量,它们对不同血管区域的适用性还是相当有限,对人类的翻译也是如此。通过开发旨在以自动方式生成血管网络的方法,找到了避免缺乏关于周围床的血管结构的信息的解决方案,该方法由生理标准驱动并符合一组形态测量约束和经验法则。如此生成的血管网络可以在统计学上与解剖学描述一致,因为它们可以再现在血管网络中观察到的主要拓扑特征和功能反应。

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

分级血管生长:(左)用标准 CCO 算法获得的血管化;(右)使用 DCCO 算法的血管化(图片由作者提供)。

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

尺度特异性血管生长:(左)用标准 CCO 算法获得的血管形成;(右)使用 DCCO 算法的血管化(图片由作者提供)。

自动生成血管床有两类算法:分形算法和空间填充算法。第一类算法可以容易地遵循主要形态测量(血管半径、长度、纵横比和分叉角)的统计模型,而不考虑血管区域的形状。第二类算法允许在(2D 或 3D)空间中定义的脉管区域内生成脉管网络。这种空间填充算法的一个特殊类别被称为约束构造优化(CCO ),因为血管网络的顺序生成是由成本函数的约束最小化来驱动的。

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

具有等径血管入口的圆形和球形区域的同时血管化(图片由作者提供)。

我们在具有简单领域的学术场景和涉及多阶段血管生长的现实场景中测试了用于血管网络生成的自适应 CCO (DCCO)算法,从从人体解剖代表性区域中的详细人体模型中获取的现有血管网络开始。

视网膜内血管形成

除了无血管的视网膜中央凹区之外,作为眼睛血管层之一的视网膜内血管层是均匀血管化的。有趣的是,DCCO 血管化在视网膜动脉的插入点附近产生了四个分支,以与体内观察到的相同的方式形成了基于象限的排列。在更远的位置,通过与解剖描述一致的算法来传递均匀的血管模式。这个简单的例子显示了 DCCO 从一小组约束和阶段中复制体内血管模式的能力。**

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

由两阶段生长过程产生的内部视网膜脉管系统:(第一行)初始化 S0;(第二行)作为初始条件(蓝色)给出的、在 S1 阶段(浅蓝色)和 S2 阶段(红色)生成的生成树鉴别容器;(第三行)血管半径沿生成网络的变化(图片由作者提供)。

大脑皮层血管化

在第二个例子中,我们在原型人脑的左额回中血管化了灰质组织。作为初始条件 S0,使用以左大脑前动脉(l.ACA)为根的动脉树。

生成的脉管树再现了在实验研究中观察到的几个结构特征。灌注脑回的所有主要分支都发育良好,为组织提供大量血流。观察到不同分支的分布在性质上相似,但在数量上有一些差异,这是由每个分支所供应的相应脉管区域的大小造成的。此外,皮质血管在脑回表面呈现均匀的覆盖,其主要的软脑膜血管在此分支为穿入血管,穿入血管向内延伸,几乎与脑回表面垂直。这导致了到达灰质的第一代血管。反过来,这些穿入的血管引起深部血管的局部分支。最终的血管树均匀地灌注灰质体积,正如在 S3 和 S4 生成的血管的分散所证明的。

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

由四阶段生长过程产生的额上回中的灰质脉管系统:(第一行)初始树 S0,示出了流入和流出约束;(第二行)从左到右,对应于软脑膜网络(S1 和 S2)、穿透小动脉(S3)和深小动脉(S4)的血管;(第三行)上-后部(左)和头-尾轴(右)中间部分的冠状切片,描述了软脑膜(红色)、贯穿(绿色)和深(蓝色)血管穿过组织的结构组织;以及(第四行)描绘血管半径的最终血管树(图片由作者提供)。

胃血管化

作为最后一个案例,我们根据文献中的解剖描述为胃建立了血管化。

得到的血管树与文献中报道的血管结构定性一致,其中浆膜下丛向浆膜层输送均匀的灌注,而来自该浆膜下网络的穿支供应粘膜下层丛。最后,肌肉层的血液由这种浆膜穿支和粘膜下层丛同时提供。由于在所有区域(浆膜下丛血管化粘膜下层、血管化粘膜下层肌层、血管化粘膜下层肌层)存在将血液输送到邻近区域的血管,该器官的复杂结构在所有阶段呈现更复杂的血管半径分布。

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

由五阶段生长过程产生的胃脉管系统:(第一行)初始树 S0,包括流入和流出约束;(第二和第三排)从左到右和从上到下,对应于浆膜层(S1 和 S2)、穿支肌层(S3)、粘膜层(S4)和肌层(S5)的血管;(底部一行)最终的血管树描绘了胃的前视图和后视图中的血管半径(图片由作者提供)。

我们介绍了 DCCO 作为一种方法,用于生成具有一系列功能和结构特征的血管网络。这项工作描述了实现 DCCO 的算法,以及为实现不同的和不同的解剖现实的脉管系统的表示所必需的阶段建模的基本原理。

此外,进行了进一步的扩展,以将自动血管形成过程与可用数据相结合,例如从医学图像或心血管系统的详细模型中获得的数据。这些特征使我们能够在患者特定的几何结构中使用 DCCO,为探索小尺度血管的作用及其在不同临床场景中的生理特征提供了新的研究机会。

本文由 DProf 的 Maso Talou 博士、Safaei 博士撰写。亨特、布兰科和 https://www.nature.com/articles/s41598-021-85434-9 最初发表于https://www.nature.com/articles/s41598-021-85434-9

绝对初学者的虚拟环境——什么是虚拟环境,如何创建虚拟环境(+例子)

原文:https://towardsdatascience.com/virtual-environments-for-absolute-beginners-what-is-it-and-how-to-create-one-examples-a48da8982d4b?source=collection_archive---------1-----------------------

深入探究 Python 虚拟环境、pip 和避免纠缠依赖

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

🎵你必须把我分开🎵(图片由凯利·莱西派克斯拍摄)

如果你从事许多不同的项目,那么你会认识到依赖——多个项目需要多个版本,多个包。你不能全局安装所有的软件包,你如何保持跟踪?同样,当项目 a 需要 PackageX_version1,而项目 b 需要 PackageX_version2 时会发生什么?当一切都是相互依赖的一团乱麻时,你如何保持理智?

在这篇文章中,我将试图说服使用 venv(虚拟环境)是保持依赖关系与其他项目分离的方法。我们将从定义什么是 venv 开始,它有什么作用,为什么你需要它。然后我们将创建一个并看到它的所有好处。最后,我们将有一些基本的规则来保持我们项目中的依赖关系尽可能的干净。

1.什么是 venv,我为什么需要它?

当您的一个项目需要一个与另一个项目版本不同的包时,会发生什么呢?当你为一个项目更新一个包时会发生什么:它会破坏依赖于那个包的另一个项目中的代码吗?你如何与他人分享你的代码?

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

让我们不要让我们的项目的依赖性纠缠在一起(图片由 Vika AleksandroveUnsplash 上提供)

为了了解 venv 是什么,我们将把它分成两部分:环境

* *

环境

一个你已经熟悉的环境。例如,当你安装 Python3.10 时,你不仅安装了 Python 引擎,还安装了 pip。当您使用 pip 来安装一个包时,它最终会出现在 Python 安装目录下的 Scripts 文件夹中。这是您的环境:Python 3.10 以及所有已安装的包。

如果你像python main.py一样运行你的程序,就会发生这种情况:

  1. 你的系统通过系统路径变量查找你安装 python 的地方,这样它就把你的命令翻译成类似于C:\Program Files\Python39\python.exe main.py的东西。
  2. 接下来,脚本 main.py 被传递给 Python 引擎。例如,如果你在脚本中的某个地方使用了import requests,它将在 python 的安装目录中查找这个包,在Lib文件夹中(在我的例子中是C:\Program Files\Python39\Lib)。
  3. 如果你已经安装了这个包,python 可以在这个文件夹中找到它并导入代码,这样你就可以使用它了,否则它会返回一个错误,说你试图导入的包没有安装

如果不使用虚拟环境,Python 的这种全局安装是您唯一的环境。您可以看到,将所有项目的依赖关系捆绑在一个大盒子里是很危险的。是时候将它划分到虚拟环境中了。

* *

虚拟的

我喜欢把 venv 想成是专门为这个项目创造一个全新的、稍微轻松一点的环境。我们将在接下来的部分中看到,当您为项目创建 venv 时,您实际上为这个特定的项目重新安装了 Python、pip 和 dependencies-folder。这段代码不在你的默认 Python 路径中(例如C:\Program Files\Python39),而是可以安装在任何地方,例如在你的项目文件夹中(例如C:\myProject\weatherApp\venv)。

* *

共享和构建环境

一旦你有了一个虚拟环境,你可以告诉它为你创建一个包含所有包的列表。然后,当其他人想要使用你的代码时,他们可以创建自己的 venv,并使用这个列表来安装所有的软件包,同时安装正确的版本。这使得与他人分享你的代码变得非常容易(通过 git、邮件或 u 盘)。

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

构建我们的新环境(图片由 Rodolfo Quirós 在 Pexels 上拍摄)

2.创建虚拟环境

让我们创建我们的虚拟环境吧!在下面的步骤中,我们将确保可以创建虚拟环境。对于这一部分,如果您对使用终端没有经验或不熟悉,建议阅读本文。我们将使用名为 virtualenv 的 Python 包来创建我们的 venvs。

*

2.1 安装 Python

  1. 检查您的系统架构;不是 32 位就是 64 位。
  2. Python 网站 下载并安装 Python。确保与您的系统匹配(32 位或 64 位。
  3. 如果您在终端中执行python --version后看到您已经安装的版本,那么 Python 安装正确。

2.2 安装 virtualenv

Virtualenv 是一个 Python 包,它允许我们创建 venvs。我们将在我们的机器上全局安装它。

  1. 使用 pip 安装 virtualenv 包:我们简单地通过调用pip install virtualenv来安装它
  2. 如果你能执行
    python -m virtualenv -h,说明 Virtualenv 安装正确。
    这个命令告诉 python 加载它的一个(-m)模块,即 virtualenv 模块。h 标志要求 virtualenv 显示“帮助”选项。它会显示一些提示,然后你就知道它安装正确。

2.3 创建我们的第一个虚拟环境

既然我们有了创建虚拟环境的软件,我们就可以创建一个了。

  1. 导航到要创建项目的文件夹。我们称之为根文件夹。我的情况是cd c:/applications/newpythonproject
  2. 告诉 python 使用 venv 创建一个新的虚拟环境
    python -m venv c:/applications/newpythonproject/venv `
    这将在你的根文件夹中创建一个名为 venv 的新目录,包含 Python 和 pip 的新版本。我们将在这里安装我们的软件包。

3.使用我们的虚拟环境

让我们开始使用我们的虚拟环境。在这一部分,我们将激活它,安装一些软件包,并再次停用它。

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

我们的食材准备好了;我们做饭吧!(图片由 Ella OlsonPexels 上拍摄)

3.1 激活我们的虚拟环境

当我们现在运行pip install requests时,它仍然会全局安装它们,这不是我们想要的。为了在我们的 venv 中安装软件包,我们必须激活我们的 venv 以便在那里安装它们。在你的根文件夹中,我们执行这个命令:venv\scripts\activate。(注意斜线是\,其他的(/)不起作用。

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

蓝色:激活前;红色:激活 venv 后

如果你的环境被激活,你会在你的终端上看到(venv)在你的路径之前,如上图所示。你将要安装的每个包都将被安装到你的虚拟环境中。

3.2 使用我们的虚拟环境

例如,现在打电话pip install requests会将它安装到您的 venv 中。你可以在你激活的环境中调用pip list来看到这一点;您将在那里看到请求。另一方面,如果您在另一个终端(没有激活 venv)调用pip list,您将看到一个不同的已安装包列表。

3.3 停用我们的虚拟环境

你可以通过在你的终端执行deactivate来关闭你的 venv。

4.出口和建造 venv

您已经创建了一个应用程序,它可以处理一些依赖项。假设您已经安装了 requests 和 pandas 来从 API 请求数据,在 pandas 中进行一些清理,然后将其保存到一个文件中。现在你想让其他人使用你的程序,但问题是:他们需要安装完全相同的依赖项和正确的版本。让我们给他们一个清单。

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

很像一本烹饪书,我们为其他用户创建了一些说明(图片来自rod nae productionsonPexels

4.1 在 requirements.txt 中列出您的依赖项

图像你有一个你的程序依赖的包的列表。Pip 可以读取这个列表并安装所有的包。

这正是 requirements.txt 所做的。它使用下面的命令pip freeze > requirements.txt冻结文本文件中pip list的内容。非常简单!唯一需要注意的是,上面的命令会在您当前所在的文件夹中创建 requirements.txt 文件,例如您的根文件夹。你也可以在其他地方或者用不同的名字pip freeze > c:/some/other/path/mylist.txt冻结文件,但是不推荐这样做。

4.2 加载您的依赖项

如果你有 requirements.txt,你可以简单地调用pip install -r requirements.txt让 pip 安装所有列出的包。r 标志代表 read,因此 pip 会将它读取的所有包安装到您指定的文件中。

再次注意,它在您当前所在的文件夹中搜索 requirements.txt。也可以像pip install -r c:/some/other/location/requirements.txt一样从另一个位置加载。

4.3 忽略 git 中的虚拟环境

如果你想把你的项目添加到一个像 Github 这样的版本控制系统中,建议不要包含你的整个虚拟环境。这要占用大量的空间和时间来上传和下载。

建议告诉 git 忽略包含虚拟环境的文件夹。为了做到这一点,你可以简单地在你的根文件夹中创建一个名为.gitignore的文件(注意 gitignore 是扩展名,这个文件没有名字),并给它以下内容venv/。这告诉 git 忽略你的 venv 文件夹。如果你保存 venv 的文件夹是别的名字,显然你必须在这里写下正确的文件夹名。

4.4 使用排除的 venv 从 git 项目安装包

现在,当 Bob 从 Github 获取您的代码并想要使用您的程序时,会发生什么呢?如果你聪明的话,你可以把你的包冻结在 requirements.txt 中。Bob 可以简单地pip install -r requirements.txt并开始使用你的程序!

4.5 虚拟环境,requirements.txt 和 docker

Docker 需要一个构建容器的指令列表,requirements.txt 非常适合。docker 文件可能如下所示:

FROM python:3.9-slim-buster# 1\. Copy application code to a folder in container
COPY . /usr/src/downloadService# 2\. Cd to the folder
WORKDIR /usr/src/downloadService# 3\. Tell pip to install all required packages
RUN pip install -r requirements.txt# 4\. Execute app
EXPOSE 5000
WORKDIR /usr/src/downloadService/src
CMD ["python", "-i", "app.py"]

如果你对 Docker 没有经验,不要担心,只要知道我们可以自动将我们所有的源代码转移到一个容器中,安装所有的包(# 3),然后启动我们的应用程序。

5.最佳实践:防止依赖地狱

依赖地狱是指我们所有的项目都被它们的依赖关系纠缠在一起。这很难避免独自工作,尤其是当你在团队中工作的时候。这一部分试图为如何使用 Python 项目制定一些基本规则。

  • 每个 python 项目都有自己的虚拟环境
  • pip freeze冻结依赖地狱!每次安装或卸载时更新 requirements.txt
  • 在根目录下包含一个名为pythonversion.txt的文件,其中记录了您的 python 版本(python --version)。
  • 不总是需要的:在 Docker 容器中构建应用程序,这样你也可以跟踪操作系统

遵循这些规则,对于操作系统、python 及其所有依赖项的类型和版本应该没有问题。

结论

我希望我能阐明虚拟环境和 Python 安装依赖项的方式,以及如何让依赖项在项目间纠缠在一起。

如果你有建议/澄清,请评论,以便我可以改进这篇文章。同时,看看我的其他文章关于各种编程相关的主题,比如:

编码快乐!

—迈克

页(page 的缩写)学生:比如我正在做的事情?跟我来!

https://mikehuls.medium.com/membership *

为 Python 数据科学项目创建虚拟环境

原文:https://towardsdatascience.com/virtual-environments-for-python-data-science-projects-on-mac-os-big-sur-with-pyenv-and-virtualenv-60db5516bf06?source=collection_archive---------15-----------------------

了解如何在 Mac OS Big Sur 上使用 Pyenv、Virtualenv 和 Pip 为 Python 数据科学项目创建虚拟环境

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

图片由 www_slon_pics 来自 Pixabay

如果你以前使用过 Python,你可能会遇到一种被称为“依赖地狱”的情况。有些包依赖于其他包才能工作。有时候,另一个包所依赖的包必须是某个版本。稍后,您可能需要使用该包的不同版本,因为还有另一个包依赖于该包是另一个版本。避免依赖地狱和创建专业项目的有效方法是使用虚拟环境。

虚拟环境就像是你的项目的一个小胶囊,在一个地方包含了所有合适的包,合适的版本。这使得您可以轻松地从一个项目切换到另一个项目。它还能让其他人在以后复制它。有不同的虚拟环境包,但我喜欢用 Pyenv

在本教程中,我将解释如何结合使用 Pyenv、Virtualenv 和 Pip 来管理 mac OS Big Sur 上的虚拟环境。对于 Linux,这些指令可能也是类似的。如果你有 Windows,你可以在这里了解更多关于如何使用 Pyenv 和 Windows 的信息。

注:这款 tutoria l 有一个 存档版本供卡特琳娜用户使用。主要区别在于,对于 Catalina 用户,基于我的个人偏好,我建议使用 Bash。然而,Zsh 现在是 Big Sur 的默认 shell,使用 Bash 完成这种设置的典型过程在 Big Sur 上是无效的。

一、用自制软件安装 Pyenv

根据他们的口号,家酿是“mac OS 和 Linux 缺失的软件包管理器。”要查看您是否已经有了自制软件,请输入:

% brew update

新手注意: 在跟随这些教程时,不需要输入百分号(%)。它应该已经为你准备好了。当您在教程的代码片段中看到 百分号(%) 美元符号($) 时,这通常表示该代码片段应该在命令行中输入(在终端中)。百分号表示终端使用的语言是 Zsh,美元符号表示语言是 Bash。 查看这篇文章,了解更多关于 的差异。

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

准备好接受命令的终端窗口示例。

如果显示您没有自制软件,我建议您阅读本教程以确保您正确设置完成这些说明。

现在,我们可以用自制软件安装 Pyenv。

% brew install pyenv

我知道这看起来有点太容易了,所以这就是问题所在。有一个特殊的文件,你需要访问,使这实际工作。作为一个初学者,我总是发现这部分很难,所以我把它分成了几个小部分。对于一个更高级的用户来说,这种解释可能有点过于具体,但是为了初学者的缘故,我尽量做得具体一些。

二。创造。zshrc

您需要访问的文件称为**。zshrc** 。注意(。)在最前面。当您在文件名前面看到一个点时,这意味着该文件是一个隐藏文件。

当我们启动终端时,我们是从我们的主目录开始的。您的主目录通常被命名为您的用户名。要查看主目录中的文件,您可以键入命令 ls 。然而,如果你想看到隐藏的文件,你需要添加参数 -a

输入以下内容:

% ls -a

将出现所有文件的列表,包括隐藏文件。

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

显示机密文件的 Mac OS 个人目录

仔细看文件。你看到一个叫的文件了吗?zshrc ?如果不行,我们一起努力。选择下面两种方法之一来创建此文件。

选项 1:创建。带文本编辑(或任何文本编辑器)的 zshrc

去创造。zshrc 使用任何文本编辑器应用程序,只需在 Finder 中打开您的主目录。

接下来,输入**命令+ Shift +。**显示秘密文件。

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

显示秘密文件的 Mac OS Big Sur 个人文件夹。

如果你看不见。zshrc,打开文本编辑器,将下面几行粘贴到一个新文档中。

eval “$(pyenv init -)”
eval “$(pyenv virtualenv-init -)”

在您的主目录中将文件保存为. zshrc。

选项 2:创建。末端为纳米的 zshrc

MAC 电脑装有一个轻型文本编辑器,你可以在名为 Nano 的终端中访问它。要打开 Nano,只需输入:

% nano .zshrc

该命令表示您希望运行程序 Nano。zshrc 是我们将要创建的文件的名称。如果已经创建了该文件或任何文件,Nano 将打开具有该名称的现有文件,而不是创建新文件。

现在,只需将以下内容复制并粘贴到 Nano 中:

eval “$(pyenv init -)”
eval “$(pyenv virtualenv-init -)”

输入 CTRL + x. 退出 Nano,出现提示时,输入 Y 保存文件。

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

Mac OS Big Sur 终端中的纳米文本编辑器

三。将 Pyenv 添加到路径

最后,我们可以通过在主目录的终端中运行以下命令,将 Pyenv 添加到我们的路径中

echo ‘export PYENV_ROOT=”$HOME/.pyenv”’ >> ~/.zshrc
echo ‘export PATH=”$PYENV_ROOT/bin:$PATH”’ >> ~/.zshrc

这会将 Pyenv 添加到您的路径中,以便您可以在命令行中使用 Pyenv 命令。

四。使用 Pip 安装 Virtualenv

下一步是安装 Virtualenv 与 Pyenv 一起使用来管理我们的虚拟环境和后续依赖项。

使用以下命令调用 Pip 来安装 Virtualenv。

% pip3 install virtualenv
% pip3 install virtualenvwrapper
% brew install pyenv-virtualenv

四。我们做了什么?

1.更新了家酿并安装了 Pyenv
2。在我们的主文件夹中显示秘密文件。
3。使用 nano 找到和/或创建了. zshrc 文件。
4。将 Pyenv 添加到我们的路径中,这样我们就可以在命令行中使用它。
5。已安装 virtualenv、virtualenvwrapper 和 pyenv-virtualenv。
6。将 pyenv 和 virtualenv 正确配置到我们的 shell 中。

动词 (verb 的缩写)下一步是什么?

在下一篇教程Jupyter 笔记本入门中,我将向您展示如何为您的项目创建一个独特的虚拟环境,并安装一些最流行的数据科学包,如 Jupyter 笔记本和 Pandas。

虚拟环境 Python 中的设置和重要性

原文:https://towardsdatascience.com/virtual-environments-setup-importance-python-4375fed7d40b?source=collection_archive---------14-----------------------

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

(图片由作者提供)

直观的 5 步演练,可作为值得收藏的参考

虚拟环境往往是我发现自己反复返回谷歌的数据科学任务之一,以检查我的语法和日常使用中的类似情况。我希望浏览这个过程及其所有值得注意的元素,作为对自己的提醒,并希望作为一个值得收藏的资源,供其他人方便地参考。

我将在我的 Macbook Pro 上使用 virtualenv for Python。我主要使用 JupyterLab,它将在我以后的一些参考资料中出现。在本文中,我将介绍:

  1. 虚拟环境的重要性
  2. 创建虚拟环境(virtualenv)
  3. 完成设置—激活和停用虚拟环境
  4. 将虚拟环境连接到 Python
  5. 使用 Pipfile (pipenv)管理需求/依赖关系

虚拟环境的重要性

随着项目组合的增长,管理包依赖变得更加重要。从一个项目跳到另一个项目意味着不同的库用于不同的目的,并且需要进行版本调整以确保兼容性。所有的软件包都不是以相同的节奏维护的,所以自从最新的熊猫发布以来,它可能不再与你在深夜搜索时发现的单人维护的软件包兼容。

虚拟环境为我们解决了这个问题。我们没有创建一个工作环境,试图不断适应我们正在进行的各种项目,这对多任务者来说是一个很大的麻烦,特别是,我们为每个项目创建了一个独立的工作环境。有点像一系列的容器,用来存放和保持我们的项目工作区分开和独立。这使得我们可以进入一个工作环境,而不用担心任何其他项目会影响我们当前正在进行的代码的稳定性。因此,每次我们在一个项目之间切换来运行我们的代码时,不再需要更新 pandas 版本。相反,我们简单地创建一个环境,该环境具有特定的项目依赖性和版本控制。当我们从中断的地方重新开始各自的项目时,或者当我们需要一个测试平台来确保我们在发布之前有正确的环境设置时,我们可以切换到那个环境。

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

(由纪尧姆·博尔达克Unsplash 上拍摄)

2.创建虚拟环境(virtualenv)

让我们开始创建第一个虚拟环境。在您的终端中,您需要确保安装了 virtualenv,您可以使用 pip 来安装它。如果需要,可以按如下所示安装 Virtualenv。

pip install virtualenv

现在已经安装了 virtualenv,可以用它来设置我们的第一个虚拟环境。仍然在终端中,使用终端中的“ls”和“cd”命令导航到要创建虚拟环境文件夹的位置。在终端中遇到的关于未找到引用文件的任何错误通常需要检查当前目录,以确保使用了正确的位置。下面的代码将在当前工作目录中创建我们的第一个虚拟环境。

所用的{…}包括括号本身,代表了我用来替代编码者为各自项目选择的名称的代码区域

virtualenv {name_for_your_virtualenv}

示例:virtualenv finance_web_app

现在,工作目录中应该会出现一个以您的虚拟环境命名的文件夹。它应该包含几个其他的嵌套文件夹,比如 python 安装,以及将来在环境中安装的任何库的程序。

3.完成设置—激活和停用虚拟环境

现在,在我们开始我们刚刚为之创建环境的项目之前,我们需要激活该环境,以便从终端安装任何需要的库。我们应该使用用于创建环境的同一工作目录,否则我们将需要为要定位的虚拟环境指定额外的路径详细信息。请注意,“bin”是我们在第 2 步中刚刚创建的{name_for_your_virtualenv}文件夹中的一个文件夹。

source {name_for_your_virtualenv}/bin/activate

示例:source finance _ web _ app/bin/activate

可选:通过检查在终端中运行的以下代码“哪个 python”是否返回包含虚拟环境名称(例如:“finance_web_app”)的路径,来验证虚拟环境是否已激活。

which python

一旦安装了项目所需的库(见第 5 节),我们就用下面的代码关闭虚拟环境。停用后,现在可以激活不同的虚拟环境进行维护或更新。

deactivate

4.将虚拟环境连接到 Python

现在,假设虚拟环境已经设置好了,我们仍然需要将它连接到 python,以确保它被识别,并且可以作为内核在 shell 程序中用于我们的项目。

运行以下代码,将虚拟环境“连接”到 Python,作为创建的每个虚拟环境的内核选项。可以同时连接多个虚拟环境,并在 Python shell 程序中进行切换。

ipython kernel install --user --name={name_for_your_virtualenv}

示例:ipython 内核安装—用户名=财务 _web_app

现在,让我们用期望的虚拟环境(内核)来运行项目。在 Jupyterlab 中,当我开始一个新的笔记本时,我看到下面的选项来选择我希望在其中运行我的项目的环境。Python 3 是默认的内核,所有的库都是在没有虚拟环境的情况下安装的。请注意,我们之前创建的 finance_web_app 虚拟环境现在显示在列表中。

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

(图片由作者提供)

这些内核选项也可以通过点击页面左下方的一个已经打开的笔记本来显示,这个位置当前显示“Python 3”,这是项目运行的当前内核的名称。

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

(图片由作者提供)“Python 3”代表了该项目的当前内核选择

在 Jupiter Notebook 中,内核选择位置与上面略有不同,但在创建一个新项目或在当前项目中使用内核下拉菜单时有类似的体验。

成功!此时,创建的虚拟环境已经准备就绪。所以小心世界,因为这个虚拟环境已经准备好发出一个大大的“你好!”

当然,根据项目所需的库,可能需要额外的安装。安装包将在下一节也是最后一节介绍。

稍后删除旧的虚拟环境相当容易,可以删除文件本身,并运行以下代码来防止它在 Python shell 中显示为可用环境。只要确保当前目录与文件的位置匹配即可。

jupyter kernelspec uninstall {name_for_your_virtualenv}

示例:jupyter kernelspec 卸载 finance_web_app

5.使用 Pipfile (pipenv)安装和管理需求/依赖关系

在您的环境中安装软件包有几个不同的选项。

Pip 方法

首先,需要激活相应的虚拟环境。然后可以执行软件包的 pip 安装,此时它应该是 shell 中的一个可导入库(可能需要刷新)。下面是 numpy 最新版本和 pandas 特定版本的安装示例。

pip install numpy
pip install pandas==0.21

如果后来在 shell 中导入该库时找不到它,可能是您的终端正在安装到您的默认 python 位置,而不是您的虚拟环境。

Pipenv 方法

如果使用 pipenv 与 Pipfile 的相关性跟踪功能,请确保目标虚拟环境是其文件夹中的唯一环境。这是因为创建的 Pipfiles 将在同一父文件夹中跟踪任何虚拟环境的已安装包。这可能需要使用“cd”命令将工作目录导航到这个新文件夹/路径。

另一种可以缓解这类问题的方法是使用 pipenv,它是 pip 命令的包装器。Pipenv 将确保在虚拟环境中安装所有软件包。它可以用下面的代码安装,而不需要激活虚拟环境。

pip install pipenv

Pipenv 是可选的设置,通过激活虚拟环境,然后运行以下代码,除了安装包(更多细节见下文)之外,还提供其他功能。这将在与虚拟环境相同的父文件夹中创建 Pipfile 和 Pipfile.lock 文件。

pipenv install

现在我们已经设置好了,下面的代码显示了一个使用 pipenv 为最新版本的 numpy 和特定版本的 pandas 安装程序的例子。

pipenv install numpy
pipenv install pandas==1.2.1

除了 pipenv 方法确保将这些包安装到您的虚拟环境之外,它还内置了帮助记录项目依赖关系的功能。

“requirements.txt”文件作为记录项目所需包的标准方法被广泛使用。这里的挑战是,它通常是手动维护的,这带来了出错或不完整的可能性。pipenv 的好处是**一旦运行“pipenv install”命令,**就会创建两个 Pipfiles,或者伪“requirements.txt”文件,它们会随着软件包的安装而自动更新(和卸载)。Pipfile 包含一个散列,因此如果 python 文件和 Pipfile 被其他用户共享或从 Github 下载,他们只需运行下面的代码(“pipenv install”),Pipfile 将使用散列位置自动定位,并使用必要的包设置环境。

pipenv install

如果之前使用了“requirements.txt ”,那么其中列出的依赖项也可以很容易地用 pipenv 安装,如下所示。

pipenv install -r requirements.txt

Murtaza Gulamali 的这篇文章很好地详细介绍了 pipenv 的用法,作为额外的参考。

结论

这就结束了我对虚拟环境设置和日常使用的演练。希望除了我自己之外,它还可以帮助其他人,在那些语法模糊的时刻作为一个简单的参考,这对于初学者来说是每天都会发生的,对于有经验的人来说甚至仍然是经常发生的脑雾时刻。

欢迎提出任何意见或建议,我会很高兴有机会与您联系。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值