功能商店入门
介绍什么是特征库,以及如何使用它们来简化机器学习过程
Artem Gavrysh 在 Unsplash 上拍摄的照片
介绍
创建能够在生产中可靠运行的机器学习模型可能是一个非常困难的过程。事实上,这些模型只能和用来训练它们的数据一样好。因此,能够创建一个能够准确预处理所有传入数据并以最佳方式构建数据以训练模型的流程,对于项目的长期成功至关重要。
数据科学家和数据工程师为了预处理将在机器学习模型中使用的数据而通常使用的技术的一些例子是:
- 特征工程: 修复数据中的不一致,通过合并/分割现有特征来创建新特征。
- 特征提取: 使用 PCA、t-SNE 等技术降低数据集维度
- 特征选择: 通过删除数据集中携带较少信息的特征或在分析中仅添加噪声的特征来减少特征数量。
彻底预处理我们的数据的一些主要好处是:
- 降低过度拟合的风险。
- 加快训练时间。
- 减少执行超参数优化的需求。
- 改进的数据可视化。
因此,在某些情况下,数据预处理可能是一个漫长的过程,以确保我们的数据尽可能采用最佳格式,并考虑所有不同的边缘情况(尤其是在管道中接收新数据时)。
随着越来越多的组织开始在其业务的许多不同领域使用机器学习过程,当涉及到预处理数据时,尝试避免任何形式的重复工作可能非常重要,这些数据随后可由组织内的不同团队和不同模型使用。为了确保消除业务中的任何重复工作,并更好地了解数据在组织中的使用情况,创建了功能库。
ML 的特征存储
特征存储是为机器学习过程设计的数据管理层。因此,特征存储充当公司内的中央存储库,存储所有不同的特征,这些特征被创建用于数据分析和机器学习。
除了存储所有不同的要素之外,要素存储还被设计为完全自动接收新数据(通过自动应用必要的数据预处理步骤)并跟踪其分布中的任何变化。通过这种方式,要素存储可用于存储和转换要素,从而使数据科学家更容易找到他们可能需要的任何要素并使用它们,而不必担心维护问题(要素会自动更新以用于未来预测,如果需要,可以检索任何更改的历史记录)。
最后,为了支持批处理和在线类型的应用程序,已经设计了特性存储。对于批处理应用程序,可能需要存储大量数据(取决于批处理更新的频率),而对于在线应用程序,实现低延迟通常是主要的优先事项。为了实现这一点,特性存储通常被设计成某种形式的双数据库(例如,存储批量数据的 SQL 数据库和快速处理在线数据的键值存储)。
图 1:示例特征库(图片由作者提供)。
因此,利用功能存储可以为组织带来许多不同的好处,例如:
- **自动数据准备:**一旦添加了新的原始数据,特征就可以自动更新(例如,如果我们有一个使用线性回归估算缺失值的预处理特征,一旦新数据添加到特征中,就可以应用相同的变换)。
- **改进的模型训练/重新训练:**拥有特征如何随时间变化的历史,可以帮助我们在新数据到来时快速重新训练我们的模型,并充分更新我们的测试数据,以反映自我们上次训练以来真实世界环境如何变化。
- **部署后改进的模型监控:**随着新数据的存储,可以添加检查,以查看每个特性的分布是否有任何剧烈的变化,并创建警报,然后重新训练我们的模型。
- **加快新模型的上市时间:**数据科学团队可以在预处理数据上花费更少的时间,而在试验和创建最佳模型上花费更多的时间。
- **团队间的特性共享:**一旦一个特性被创建并归档,它就可以在将来的其他项目中被自动重用。
- **确保使用最佳 MLOps 实践:**机器学习操作(MLOps)是一组最佳实践,旨在确保机器学习模型能够尽快创建,同时尽可能易于维护和管理。使用特征库可以极大地帮助我们实现这两个目标。
- **全面管理您的数据:**使用功能存储可以更轻松地查看组织在整个过程中是如何处理数据的,并在遇到任何监管问题时快速采取行动。
创建功能存储
在过去的几年中,不同的开源和企业解决方案已经被构思出来,以促进功能商店的采用。两个最常见的开源解决方案是 Feast 和 Hopsworks 。相反,对于企业用户来说,云服务中增加了功能商店功能,如 GCP 顶点人工智能、 AWS Sagemaker 和 Databricks 。
如果您不确定使用哪个平台作为您的功能商店,可以使用不同的工具,例如功能商店比较,以便为您提供不同提供商之间的差异分类。
联系人
如果你想了解我最新的文章和项目,请在媒体上关注我,并订阅我的邮件列表。以下是我的一些联系人详细信息:
SageMaker Studio 实验室地理空间分析入门
SpaceX 在 Unsplash 上拍摄的
实践教程
使用地理数据和地理空间图像来研究气候变化、自然灾害或人类活动的影响。
地理数据包括使用卫星图像和地理延迟系统(GPS)捕获的地理空间数据,以及通常用地理坐标明确描述的其他地理数据。地理空间分析包括使用软件工具、统计方法和机器学习来收集、报告、绘制和分析这些数据。地理空间分析用于 了解气候变化、自然灾害或人类活动 的影响,通常是对特定地理位置的影响。
使用地理空间数据的挑战
使用地理空间数据时存在一些挑战。首先, 地理空间数据可能非常庞大, 如果没有高容量的存储和计算,很难工作,有时甚至无法工作。解决规模复杂性的一个变通办法是缩小你的关注点或研究领域和时间段。这使得检索和分析一小部分数据变得相对容易。
接下来是围绕 不同格式 的复杂性。使用压缩算法以多种格式捕获地理空间数据,使数据传输和存储更加经济。此外,当您在处理地理数据时,您会经常发现自己在处理多个源,而这些源可能会使用的不同投影捕获数据(稍后将详细介绍)。这包括在使用数据进行分析之前对数据进行预处理和重新投影。
最后,随着卫星绕地球运行, 数据在一段时间内 批量捕获。你可能没有足够的数据或足够高质量的数据来研究特定的时间和地点。在这种情况下,您可能需要调整时间窗口或依靠数据处理来清理和扩充这些数据。
先决条件
这篇文章涵盖了在 SageMaker Studio 实验室上开始地理空间数据分析的基础知识。我们探索公开可用的地理数据集,然后探索在 AWS 开放数据注册处可用的 Sentinel-2 地理空间数据集。我们使用地理矢量数据集探索了加利福尼亚州的湖泊和县,然后重点关注加利福尼亚州的沙斯塔湖,以分析 Sentinel-2 地理空间数据并计算光谱指数。
如果您想跟随,您将需要以下先决条件,所有这些都是免费的。
- 一个 SageMaker 工作室实验室 账号
- 一个 自由层 AWS账户
- 一个 免费试用 的哨兵枢纽账号
亚马逊 SageMaker Studio 实验室提供 CPU 和 GPU 环境,您可以使用 CPU 环境完成这里描述的所有步骤。
设置您的环境
亚马逊 SageMaker Studio Lab 是一个免费的在线 web 应用程序,用于使用 Jupyter 笔记本学习和实验数据科学和机器学习。使用 Amazon SageMaker Studio Lab,您可以保存和恢复您的工作,访问命令行和克隆 git 存储库。点击这里注册一个免费账户。一旦你的账户被批准并登录,你就可以克隆这个库或者手动上传文件。
首先,您需要在 SageMaker Studio 实验室中创建一个环境。在 Studio Lab 中创建环境很容易。转到您的克隆目录,选择environment.yml
文件,右键单击 YAML 文件,并选择 create an environment。您也可以选择在 Studio Lab 中克隆存储库时自动运行 *environment.yml*
。这将创建一个新的 Studio Lab 内核,其中包含所有必需的包。环境创建完成后,您可以打开笔记本并选择新创建的内核。
选择自定义内核—按作者分类的图像
您也可以取消笔记本的包安装部分的注释,手动安装这些包。
下载数据
地理数据通常以shape file**、 **Geopackage、或 Geojson 格式提供。让我们从下载 shapefiles 开始,其中包括加利福尼亚各县和水体的地理矢量数据。
- ****加州县数据集包含加州州、县和地方的边界,来自美国人口普查局的 2016 年 MAF/老虎数据库此处。
- 加州水体数据集由加州渔猎局发布。海洋资源区,可在此下载。
下载数据集
下载完文件后,我们需要将它们解压缩到您的本地目录中。
带有地理数据的 EDA
一旦我们在本地获得了数据,我们就可以读取和执行探索性的数据分析。在我们的例子中,我们下载了 shapefiles。shapefile 是一种 ESRI 矢量数据存储格式,用于存储地理要素的位置、形状和属性。geopanads
Python 包使得读取这些 shapefiles 和创建一个 Geopanads 数据帧变得很容易。一个geopandas.DataFrame
对象是一个pandas.DataFrame
,它有一个带几何图形的列。除了标准的pandas.DataFrame
属性,它们还有另外两个属性,分别是 CRS 和geometry,都是可选的。CRS 用来指定 坐标参考系统中 的几何数据。几何包含地理数据的实际坐标,并在geopandas.DataFrame
对象中被设置为几何数据类型。
让我们将县形状数据文件读入geopandas.DataFrame
读取县数据
县—按作者分类的图像
像标准数据帧一样,geopandas.DataFrame
有一个方便的plot
方法,可以用来创建地理可视化。
绘制加州各县
绘制加州各县-作者图片
类似地,我们将把 California Lakes shapefile 读入一个geopandas.DataFrame
并绘制它。
读取和绘制湖泊数据集。
绘制加州湖泊——作者图片
数据争论
我们之前简单提到过投影和坐标参考系统。坐标参考系统表示二维数据,即我们的geopandas.DataFrames
中的数据,如何与地球上的真实位置相关联。当您使用不同来源的地理数据时,它们很可能使用不同的投影。
**我们希望将 California lakes 数据集与 counties 数据集叠加在一起,并将湖泊与 California counties 一起可视化。在此之前,我们需要检查并确保它们使用相同的坐标参考系统(CRS)进行投影。一个geopandas.DataFrame
对象的crs
属性就是这样做的。如果您使用counties.crs
和lakes.crs
检查坐标参考系统投影,您会注意到加州各县和湖泊的数据具有不同的 CRS。县数据集使用 **EPSG:3857,湖泊数据集使用 EPSG:4326 作为各自的 CRS。在我们一起使用这些数据集之前,我们需要重新规划湖泊,使其具有与县相同的 CRS。
重新设计 CRS
一旦在同一个 CRS 投影中有了地理数据集,就可以叠加和绘制它们。
覆盖物
绘制叠加数据-作者提供的图像
地理数据分析中的一项常见任务是缩小研究范围。我们可以选择一个数据子集来创建一个新的geopandas.DataFrame
对象,用于进一步的分析和可视化。对于我们的例子,让我们把重点放在沙斯塔湖。
选择沙斯塔湖
一旦我们选定了感兴趣的领域,就很容易更好地想象和研究它。
绘制沙斯塔湖—作者图片
使用地理空间图像
接下来,我们从地理矢量数据转移到地理空间图像。对于地理空间图像,我们将使用哨兵-2。 Sentinel-2 任务是一个由两颗卫星组成的陆地监测星座,为当前 SPOT 和 Landsat 任务提供高分辨率光学图像和连续性。Sentinel-2 数据集可在 AWS 开放数据注册处公开获取。
python 包使得直接从 AWS 搜索和下载特定于我们关注领域的数据变得容易。以下代码片段显示了如何配置您的凭据。在这个例子中,我使用一个可选的 JSON 文件来存储和检索我的凭证
设置凭据
AWS 上的 Sentinel-2 数据集包含 2017 年 1 月以来的全球数据,并定期添加新数据。在下载之前,我们需要指定要学习的搜索坐标和时间窗口。在我们的例子中,我们关注沙斯塔湖区域,我们将它指定为一个边界框和一个随机时间段。
哨兵搜索
Sentinel-2 数据被捕获并以瓦片的形式分发,这使得它很容易在网络上传输。我们迭代搜索符合搜索标准的可用图块,并选择特定的图块。为了获得最佳效果,我们选择云覆盖最少的图块。
选择特定的单幅图块
Sentinel-2 卫星各携带一台多光谱仪器(MSI ),在可见光/近红外(VNIR)和短波红外光谱范围(SWIR)有 13 个光谱通道。例如,我们将下载八个特定波段**,这将有助于我们的分析。你可以在这里阅读更多关于这些乐队的信息。**
哨兵数据下载
除了光谱带,Sentinel tiles 还包括预览图像。让我们先检查一下,以确保我们完整清晰地捕捉到了感兴趣的区域。
解析请求以提取波段和其他数据
绘制预览图像-按作者排列的图像
抽查几个额外的波段也是一个很好的做法,以确保我们拥有一切。我们绘制了波段 7——植被红边,波段 8——近红外光谱,波段 8A——窄近红外光谱。
绘制不同波段-按作者分类的图像
使用栅格数据
地理空间数据基本上由栅格数据或矢量数据组成。Sentinel-2 使用 GeoTIFF,这是一种用于卫星图像和地形模型的栅格数据集。地理空间光栅图像类似于数字图像,但也伴随有将数据连接到特定位置的空间信息。这包括栅格的范围和像元大小、行数和列数及其坐标参考系统(或 CRS)。Python 包可用于读取、检查、可视化和写入地理空间栅格数据。这里我们使用rasterio
来读取这些光栅阵列,然后创建一个真彩色图像。
读取栅格数据
我们使用rasterio
来创建一个.tiff
格式的真彩色图像。真彩色图像的文件尺寸较大。在创建之前,请验证您是否有足够的存储空间。
生成真彩色图像
在 Jupyter 中直接可视化 tiff 图像没有太大帮助。您将需要 GIS 软件来打开和查看它。下面沙斯塔湖地区的真彩色图像是在 QGIS 中渲染的。
在 QGIS 中渲染的真彩色图像—作者提供的图像
计算光谱指数
光谱指数是多光谱图像中两个或更多光谱波段的像素值的组合。光谱指数突出显示图像中感兴趣的土地覆盖类型的相对丰富或缺乏的像素。让我们来看几个例子
归一化差异植被指数(NDVI) 是一个简单的图形指标,用于分析观测目标是否包含活的绿色植被。它被计算为NDVI = (NIR — Red) / (NIR + Red)
,其中 NIR 是近红外波段 8,红色是波段 4
计算 NDVI
earthpy
Python 包可用于绘制光谱带。我们在这里使用它来显示沙斯塔湖地区周围的归一化植被指数差异。
策划 NDVI
NDVI 情节——作者形象
你可以看到绿色的植被区域,深色的植被区域。水体通常很少或没有植被,以对比鲜明的橙色显示。
归一化差异水分指数(NDWI) 使用反射的近红外辐射和可见绿光来增强这些特征的存在,同时消除土壤和陆地植被特征的存在。NDWI 对于分析水体很有用。它被计算为NDWI = (GREEEN — NIR) / (GREEN + NIR)
,其中绿色为波段 3,近红外为波段 8。大于 0.5 的值通常对应水体。
计算 NDWI
类似于我们在上一节中绘制 NDVI 的方式,您可以使用earthpy
来绘制被观察区域的 NDWI。
NDWI 图-作者提供的图片
上面的图像向我们展示了沙斯塔湖地区的数值。你可以看到蓝色的湖区。植被通常对应于小得多的值,而建筑面积对应于 0 到 0.2 之间的值,并以绿色阴影显示。
燃烧面积指数(BAI) 通过强调火灾后图像中的木炭信号,在红色到近红外光谱中突出显示燃烧过的土地。该指数是根据从每个像素到参考光谱点的光谱距离计算的,在参考光谱点处,最近燃烧的区域会聚。较亮的像素表示烧伤区域。
在我居住的南加州,野火是经常发生的自然灾害。下面我们举一个例子,白对 2020 年 Silverado 大火的分析。火灾后的图显示了火灾留下的烧伤疤痕。
Silverado Fire BAI —图片由作者提供
包扎
本文介绍了在 SageMaker Studio 实验室中设置地理空间分析环境、地理分析的基础知识、搜索和下载地理空间图像、操作栅格以及计算光谱指数。Studio Lab 是免费的,我们没有创建任何收费的 AWS 资源作为本练习的一部分。但是,您下载的地理和 GIS 数据以及生成的影像可能会占用大量存储空间。请确保检查您的存储利用率,并根据需要删除文件。
GitLab 入门:绝对初学者指南
入门
如何一步一步地使用 GitLab,即使你以前从未听说过 Git
不到一年前,我不知道“Git”这个词是什么意思。对我来说,这是一个相当野蛮的术语,开发团队用一种编码语言相互交流。有了商业背景,我以为自己永远也不会用到它,所以我从来没有真正关注过这个概念。
当我 2020 年开始在一家数据驱动的公司担任数据分析师时,我不得不面对它:处理我本地保存的文件,并使用像“v1”、“v2”等后缀更新它们。是历史。使用 Windows 的 SharePoint 或 Google Drive 等协作工具也不足以确保整个公司使用的代码的质量和统一性。**虽然修改和保存你自己的代码可能会奏效一段时间,但不幸的是,这种工作方式从长远来看是不可持续的。**您不仅会浪费时间来维护所有文件版本,还会在与他人沟通时遇到困难:
“你实际上指的是文件的哪个版本?”“你能把你最后的修改通过电子邮件发给我吗?”
“在哪里可以找到这个文件的“final-def-latest.sql”版本?”
如果只集中存储一个版本的代码,就可以避免与同事之间许多耗时的交流。比如其他团队和外部工具使用的“官方”版本的代码。例如,我工作的大部分代码都是由 Apache Airflow 每天处理的,并且供我以外的其他部门的同事使用。这正是 Git 和 GitLab 在这里的目的:
- 在一个唯一的地方存储和保存该代码的唯一有效版本
- 让每个人都能同时使用同一个版本
- 历史化公共代码片段中所做的更改
- 讨论要添加到代码主版本中的修改
入门:什么是 GitLab?
Git 的概念
首先也是最重要的:什么是 Git?正如 git 的网站所说,“ Git 是一个免费开源的分布式版本控制系统,旨在快速高效地处理从小型到超大型项目的一切”。该系统传统上用于在软件开发过程中协调合作开发源代码的程序员之间的工作。它允许跟踪任何一组文件中的变化,因此它与任何基于共享版本代码的协作项目高度相关。Git 的目标包括速度、数据完整性和对分布式非线性工作流的支持(在不同系统上运行的数千个并行分支)。
具体来说,这意味着两个不同的人可以在不妨碍彼此进度的情况下处理相同的代码。为了做到这一点,每个人都将在他们自己的分支上工作,分支是位于分支“主”上的主代码的副本。当保存修改时,每个用户提交他们的修改,并在所谓的合并请求中解释修改了什么。下面是一个可视化的例子,可以更好地理解 Git 分支背后的逻辑:
玛丽·勒费夫尔
GitLab:一个基于 Git 并为组织设计的在线平台
虽然 Git 可以直接在每个用户的电脑上使用,例如通过电脑终端或 Sublime Merge 等 Git GUI 客户端使用, GitLab 是一个在线平台,所有操作都可以在浏览器中完成。正如 GitLab 的网站上所描述的,它是“一个在代码上进行合作的开源软件”。创建 GitLab 帐户是免费的,因此如果您在公司环境中使用它,项目管理员会将您添加到公司的相关项目中。这意味着您可以使用相同的帐户在 GitLab 上进行专业项目和个人项目(取决于您用来创建帐户的电子邮件地址)。
在您的计算机上使用 Git 可以完成的大多数操作也可以在 GitLab 中完成。这在这里尤为关键,因为这意味着 GitLab 允许非开发人员(至少是从未学习过如何使用版本控制系统的人,比如一年前的我)在代码中添加修改,而不必接受计算机科学方面的广泛培训(T21)。
此外,GitLab 将自己标榜为“完整的 DevOps 平台”,因为它为组织提供了比简单地跟踪用户在主代码中所做的更改更多的功能。GitLab 还包括测试代码片段的工具,并允许将代码部署到产品中(当代码被依赖于它的外部工具实际应用和使用时)。在这里,我不会深入讨论细节,因为我想向软件开发领域的初学者介绍 GitLab 的主要特性。
入驻:如何在 GitLab 中找到合适的信息?
贮藏室ˌ仓库
GitLab 上的每个项目都对应一个存储库。这是**,在这里你可以找到你的项目中包含的所有文件,以及变更的历史和现有分支的状态**。当你发现一个新的项目时,这是你应该开始的地方,因为你将理解项目的结构和参与者是如何工作的。
请特别查看以下部分:
- 文件:顶部导航栏允许您找到您正在寻找的确切文件和版本
- 提交:该部分显示了所有最近提交并合并到所选分支中的变更
- 分支:在这里您可以看到项目的所有分支及其当前状态(“主”是主分支,您也可以浏览您或您的同事创建的分支)
投稿:如何将你的个人风格带入项目?
合并请求
现在你已经对你将要工作的项目有了更好的理解,你可以通过对位于“主”分支上的代码进行修改来开始对它做出贡献。为此,请转到“合并请求”(也称为“MR”)部分。
这一部分中最有用的功能包括:
- 合并请求概述:它允许您快速掌握您的团队成员一直在进行的变更,并希望整合到“主”分支中
- 创建一个新的合并请求:当你准备好让你的同事审查、批准你的修改,然后将你的修改合并到“主”分支时,你可以点击“创建一个合并请求”并按照指示操作
新的合并请求(示例
- 合并请求的详细信息:当你点击一个合并请求(应该是你的还是其他人的)时,你可以在四个选项卡中查看它的详细信息——概述、提交、管道和变更
合并请求的详细信息(示例
结论
从零到 GitLab,再从 GitLab 到 Git
正如我刚才介绍的, GitLab 是软件开发领域新手的易用工具。实际上,它的使用不需要高级的编程知识,只要用户熟悉他想要改变的文件的编程语言。
随着您对 GitLab 越来越熟悉,您可能会想在自己的计算机上使用 Git(通过终端或 Git GUI 客户端)。这将允许您节省时间,因为您将在桌面上有一份存储库文件的副本。相信我:我很不情愿从漂亮的 GitLab 界面切换到冰冷的终端窗口。但是在对 Git 的逻辑有了更好的理解,并对我对 master 分支所做的更改有了信心之后,我不得不承认,在浏览和更改我组织的项目时,我节省了大量的时间。
我给你的最后一个建议:慢慢掌握 Git 和 GitLab,剩下的会随着实践而来!
你喜欢读这篇文章吗? 成为 的一员,加入一个不断成长的充满好奇心的社区吧!
https://marie-lefevre.medium.com/membership
Neo4j 图形嵌入入门
实践教程
浅谈如何将网络图的节点转化为向量
图片由 Savionasc 提供,根据知识共享 署名-共享 4.0 国际版许可授权。未对原始图像进行任何更改。
介绍
所有机器学习的起点都是把你的数据变成向量/嵌入(如果他们还没有的话)。也许在你的问题中你是幸运的,你已经有了许多列与每个数据点相关联的规格化浮点数,它们很容易组合起来进行嵌入。或者你可以很容易地推导出它们。许多不同类型的数据可以用来生成向量,如文本、图像等。但是,当您的数据以图表或其他相互关联的数据的形式出现时,该怎么办呢?
在接下来的几篇博文中,我希望深入了解如何创建和调整这些向量的一些细节。为了这篇文章,我将介绍 Neo4j 的图形数据科学 (GDS)库中存在的三种方法。(我们将在一两篇不同的文章中讨论嵌入调整。这些超参数包含很多内容!)我们将使用一个使用 Neo4j 沙箱可用的小图(但你也可以使用 Neo4j 桌面或使用我在这篇文章中描述的自定义 Docker 容器来完成此操作),这是一个免费工具,可用于免费试用 Neo4j 和 GDS。
这篇文章是一系列文章中的第二篇,我们将看看如何用图表进行数据科学研究,从…
(在未来的博客文章中,我们将更多地使用 Docker 参考。)
Neo4j 沙盒入门
我已经在的另一篇博文中描述了这一点,所以让我们在这里重点讨论一下。第一步是创建沙箱本身。你可以在这里做。我们将创建一个新的沙盒实例,方法是选择“新建项目”,然后选择“图形数据科学”,如下所示。
创建图形数据科学沙盒数据库
一旦完成设置,点击右边的绿色按钮,告诉它“在浏览器中打开”
现在,让我们单击左上角看起来像数据库图标的按钮,看看我们在这个代表“权力的游戏”的预填充图形中有什么酷毙了。我们有几个节点标签和关系类型,这对以后的工作非常有帮助。当您发出 Cypher 命令MATCH (n) RETURN n
时,您的图形应该如下所示:
权力的游戏,形象化为网络图。(图片由作者提供。)
使用 GDS 创建内存中的图形
使用 GDS 的第一步总是创建内存中的图形,这是通过使用图形投影来实现的。关于图投影的好处是,您可以(并且通常应该)明确您想要为图的哪个(哪些)部分创建嵌入。一般来说,使用整个图表不是一个好主意,特别是当图表变大时。此外,GDS 中的一些图算法不适用于二分图或多分图。最后,使用内存中的图并不一定要永久地改变整个数据库,除非您使用带有.write()
的算法,您可以用它来编写作为节点属性的嵌入。当我们想在图上做 ML 时,这将是非常有用的,我将在这篇文章中展示如何做。所以使用内存中的图形。你会喜欢他们的!
有两种方法可以创建内存中的图形,这两种方法都是用投影表示的图形数据模型。投影指定了节点类型和关系类型,它们可以是全包含的。这两种方法包括通过 Cypher 投影或所谓的“本地”投影创建图形。Cypher 投影的优点是编写简单,同时还提供了 Cypher 查询的所有灵活性,但代价是比原生投影慢得多。
所以让我们从创建一个内存图开始。这里我将使用本机投影,但是如果您愿意,它们可以很容易地转换成 Cypher 投影。假设我想查看图表中的所有人。我们会使用
CALL gds.graph.create(
'people', {
Person: { label: 'Person' }
},
'*'
)
YIELD graphName, nodeCount, relationshipCount;
来创建这个内存中的图形。这里,节点投影简单地指定了具有标签Person
的每个节点。边缘投影'*'
包括与节点投影中的节点相关联的所有边缘。
我们可以创建一些更具体的东西,比如指定多个节点类型。然后我们可以使用语法
CALL gds.graph.create(
'a-different-graph', {
Person: { label: 'Person' },
House: { label: 'House' }
},
'*'
)
YIELD graphName, nodeCount, relationshipCount
所以现在我们有了人和房子,这可能对 ML 任务有用,比如预测人和房子之间的联系。(我们将把它留到以后的文章中。)
也许我们还想只包括人和房子之间的特定关系类型。(在 Cypher 中,你可以通过快速查询MATCH (p:Person)--(h:House) RETURN p, h
来查看所有的关系类型。)假设我们只关心关系BELONGS_TO
。为了创建内存中图形,我们将包括一个特定的边投影:
CALL gds.graph.create(
'belongs-graph', {
Person: { label: 'Person' },
House: { label: 'House' }
},
{
BELONGS: { type: 'BELONGS_TO',
orientation: 'NATURAL'
}
}
)
YIELD graphName, nodeCount, relationshipCount
边缘投影BELONGS
有一些我们已经包括的东西,即边缘类型和方向。关于后者的一个注意事项:GDS 的一些图形算法倾向于使用'UNDIRECTED'
方向,然而默认方向是'NATURAL'
。我们鼓励您查阅 API 文档来确定每个算法需要什么。当有疑问时,最安全的方法是假设无向单部图。
酷毙了。现在我们有了一些内存中的图形(请看CALL gds.graph.list())
)。最佳实践表明,您应该丢弃所有不打算使用CALL gds.graph.drop(graph_name)
的图形,以释放内存。
创建嵌入
您可以使用 GDS 创建三种类型的嵌入: FastRP 、 GraphSAGE 和 node2vec 。每一个都以自己的方式在内存图中创建节点的嵌入。在我们讨论每一个之前,让我们来看一下它们的一些公共参数,您将使用它们来生成嵌入。
所有的嵌入(事实上,所有的图形算法)都有一些不同的方法。我们这里要用的是.stream()
(把结果输出到屏幕上)和.write()
(把计算出来的东西写成节点属性)。对于它们中的每一个,我们都需要提供内存图的名称、一些配置参数集以及算法返回的内容。在.write()
的情况下,这将通过YIELD
语句返回。当您返回结果时,它们是根据节点 id 完成的,节点 id 是图的内部 id。请注意,它们特定于内存中的图形,并且不匹配数据库本身中的任何内容,因此我们将很快展示如何将它们转换回可识别的内容。这些配置往往是特定于每种算法的,我们鼓励您查阅这方面的 API 文档。
现在让我们看看三种嵌入算法。FastRP,顾名思义就是,嗯,快。它使用基于线性代数的稀疏随机投影,根据图的结构创建节点嵌入。另一个好处是,它很好地处理了有限的内存,这意味着它可以在沙箱中很好地工作。node2vec 的工作方式类似于 word2vec 的 NLP 矢量化方法,其中为每个节点计算给定长度的随机游走。最后,GraphSAGE 是一种归纳方法,这意味着当添加新节点时,您不需要重新计算整个图的嵌入,而对于其他两种方法,您必须这样做。此外,GraphSAGE 能够使用每个节点的属性,这对于以前的方法是不可能的。
因此,你可能会认为你应该总是使用 GraphSAGE。但是,它比其他两种方法运行时间更长。例如,FastRP 除了非常快(因此经常用于基线嵌入)之外,有时还可以提供非常高质量的嵌入。我们将在以后的博文中讨论嵌入结果的优化和比较。
现在让我们从一个内存图开始,看看使用 FastRP 创建嵌入的最基本的方法。我们将创建一个单部分、无方向的人物图:
CALL gds.graph.create(
'people', {
Person: { label: 'Person' }
},
{
ALL_INTERACTS: { type: 'INTERACTS',
orientation: 'UNDIRECTED'
}
}
)
YIELD graphName, nodeCount, relationshipCount
请注意,当我们创建一个无向内存图时,您正在创建两个方向上的关系投影(自然和反向)。
为了获得 FastRP 嵌入,我们将使用
CALL gds.fastRP.stream('people',
{
embeddingDimension: 10
}
)
YIELD nodeId, embedding
RETURN gds.util.asNode(nodeId).name AS name, embedding
在这里,我们已经告诉 FastRP 创建一个 10 维向量,流式传输到屏幕上。最后一行使用gds.util.asNode()
将这些内部节点 id 转换成我们可以理解的东西(在本例中是角色名)。当我们运行它时,我们会得到如下结果:
FastRP 嵌入。(图片由作者提供。)
如果我们想将这些作为属性写入数据库,我们可以使用
CALL gds.fastRP.write('people',
{
embeddingDimension: 10,
writeProperty: 'fastrf_embedding'
}
)
现在,如果你看一些人节点MATCH (p:Person) RETURN p LIMIT 3
你会看到,例如,詹姆·兰尼斯特给了我们
{
"identity": 96,
"labels": [
"Knight",
"Person"
],
"properties": {
"fastrf_embedding": [
-0.57976233959198,
1.2105076313018799,
-0.7537267208099365,
-0.6507896184921265,
-0.23426271975040436,
-0.8760757446289062,
0.23972077667713165,
-0.07020065188407898,
-0.15781474113464355,
-0.4160367250442505
],
"pageRank": 13.522417121008036,
"wcc_partition": 2,
"gender": "male",
"book_intro_chapter": "5",
"name": "Jaime Lannister",
"pageRank-1": 3.143866012990475,
"community": 304,
"title": "Ser",
"age": 39,
"birth_year": 266
}
}
我们可以看到有一个很好的嵌入在等着我们。
这个系列的下一部是什么?
在这篇文章中,我们演示了在 Neo4j 沙盒实例上创建 FastRP 嵌入。但是等等,node2vec 或者 GraphSAGE 呢?!这些方法需要更多一点的内存,所以我们将把它们保存到以后的文章中,我们将用更多的计算能力来完成。因此,我们将在未来的博客文章中使用 Docker 容器来讨论这些,可以通过这篇文章找到它。我们还将花一些时间讨论如何调优这些不同的嵌入,这是任何基于 ML 的解决方案都需要的一个步骤。当然,如果我们不讨论常见的基于 ML 的解决方案,如自动节点分类或链接预测,我们会怎么样呢?敬请期待!
Python 中的 NLP 入门
开始进入自然语言处理空间的旅程
在 Unsplash 上由 Jaredd Craig 拍照
阅读的乐趣在于发现新的见解。书籍帮助我们学习,但也挑战我们的理解。有了许多不同的流派,可以发现的知识深度是没有止境的。
我们每个人都可能有越来越多的建议需要阅读。我们可能还记得上一次我们进入图书馆,努力想知道从哪里开始。理解课文难度的有效方法会有帮助吗?是时候调用自然语言处理(NLP)算法了。为了从文本中提取价值,他们帮助区分小麦和谷壳。本文旨在开始理解如何通过使用几个 Python 包来获得价值。
首先,我们需要一个数据集,Kaggle 就是我们要去的地方。
Kaggle 数据集
Kaggle 内部有许多不同的竞赛,旨在挑战任何初露头角的数据科学家。我们将回顾 CommonLit 可读性竞赛中提供的数据集。
https://www.kaggle.com/c/commonlitreadabilityprize
CommonLit 为 Kaggle 提供了开发算法的机会,这些算法可以帮助管理员、教师、家长和学生理解如何以适当的技能水平分配阅读材料。在这方面,阅读材料应该提供乐趣和挑战,以帮助防止阅读技能停滞不前。这个项目的发现之路应该鼓励自然语言处理技术的发展,这种技术可以对应该分配给每个阅读水平的书的摘录进行分类/分级。
关键挑战
在深入分析之前,总是鼓励先假设我们要提取的关键特征。当回顾一篇文章的难度时,有几个感兴趣的方面:
- 单词难度
- 单词长度:长单词通常被认为比短单词更难。因此,可以在单词长度和文本难度之间建立相关性
- 词汇表:可以用来突出常用词的比例。一个单词越不常见,就越难被感知和理解。然而,请记住,很多时候,单词的难度会受到话题受欢迎程度的影响
2.句子难度
- 句子长度:更长的句子导致更难的文本。必须注意包含冒号和分号会影响句子长度以及句号
我们有一系列的初步想法要探索。分析的其余部分将提供几种可用于检查这些初始特性的方法。
初始数据分析
使用 Python 时,我们从导入包或包中的模块开始,以便在分析中使用。要使用的初始包的常见列表有:pandas(别名 pd)、numpy(别名 np)、matplotlib.pyplot(别名 plt)。每个软件包都有助于数据分析和数据可视化。
对于下面显示的代码,使用了一个 Jupyter 笔记本实例。Jupyter 笔记本是一种常用的探索性数据分析(EDA)工具。这是第一次探索数据以获得有价值的见解时可以帮助的许多选项之一。在最初的发现阶段之后,自动化的类和函数结构通常会就位。应用先探索数据然后自动分析的方法,确保可以更有效地探索数据集的未来版本。这个过程超出了本文的范围,但是我将在以后的材料中介绍它。
代码 1.1 导入训练数据集并执行初始 EDA
从代码 1.1 开始,数据首先被导入以开始分析。对于本次审查,csv 文件已被导入并存储在变量 train 中。pandas 包中的 read_csv()方法将 csv 文件转换成 pandas 数据帧。数据帧提供具有行和列的结构化表格数据集。
默认情况下,在 Jupyter 记事本中,code 单元格的最后一个元素将提供显示的结果。然而,我们可以通过运行第 4 行到第 6 行的代码来调整这些设置。这些调整后的设置将允许从第 9 行到第 12 行请求的每个输出一起显示。反过来,这确保了开发人员不必将应用于训练数据集的每个方法放入单独的 Jupyter 单元格中来显示输出。
Python 输出 1.1 来自训练数据集的 EDA
在 python output 1.1 中,已经获得了一些初步的见解。head()方法显示了训练数据集的前五行。默认情况下,使用值 5,开发人员可以通过在位置参数的括号()中放置一个值来调整这个值。我们可以看到,“摘录”列存储了用于审查的文本,“目标”列为模型分析提供了因变量。对于这个 NLP 分析,我们将把注意力集中在“摘录”列。
shape 方法通过输出数据集中的(行,列)数来提供数据集的结构。而 dtypes 方法显示列数据类型。在 python 中,对象数据类型表征字符串变量。float 数据类型表示一个数值变量。根据所需的数据精度,还可以使用其他几种数字格式。
最后,describe()方法有助于在数据集上执行初始 EDA。通过请求上面显示的参数,我们可以显示对象列的输出。describe()方法的默认选项是只输出数值变量的值。所有摘录值都是唯一的,而目标变量显示的值范围很广。当平均值高于中值(50%)时,变量中似乎存在一些偏斜。
NLP 分析
执行一些初始 EDA 后,我们对所提供的数据集有了更好的理解。然而,在建立模型对新数据进行预测之前,还需要进行更多的分析。在本节中,我们将开始关注分析的 NLP 部分。
代码 1.2 设置初始 NLP 步骤
首先,我们从设置 NLP 分析开始,这是 spacy 包被使用的地方。spacy.load()方法的一个实例已被赋给变量 nlp。这里提到的实例是一种定义方法的方式,请求的方法已经被打开使用,并且可以与已经定义的变量一起应用。为英文文本设置好参数值后,我们就可以开始了。
通过使用 pandas 方法 loc[],我们可以选择感兴趣的适当[行,列]。在这个 Python 方法中,索引值从零开始。因此,分配给 sample1 的变量将从第一行的“摘录”列中提取值。
Python Output 1.2 将示例摘录文本表示为 spacy 文档
我们可以从上面的输出中看到,nlp 方法已经将“摘录”文本放入到结果输出中。我们现在可以在下面显示的代码中请求额外的输出。
代币
一个标记可以被看作是一个句子中的每个唯一值。其中组成句子的单词和标点符号可以分别查看。
代码 1.3 检查文本中的标记
前两个 print 命令创建在输出中显示的顶部行。使用 for 循环有助于遍历 doc 变量中的前 20 个标记。
Python 输出 1.3 由文本中的每个标记产生
从输出来看,已经请求了许多功能。最初的标记有助于定义我们当前正在复习的句子的哪个元素。一个引理的目的是把意思相近的词连接成一个词。我们可以看到“改变”已经被还原为“变化”。而停用词代表一组不会给句子增加多少价值的单词。通过从句子中排除这些连接成分,我们保持了句子的上下文。最后,应用 len()方法检查令牌的长度。
停用词
如前一节所述,停用词被视为句子中的标记,可以在不破坏句子潜在含义的情况下将其删除。Python 中已经存在几个库,可以帮助揭开从头创建停用词列表的神秘面纱。
代码 1.4 不同可用停用词列表的比较
在代码 1.4 中,我们将比较两个可用列表。我们可以使用已经导入的 spacy 包和 nltk 包。自然语言工具包(nltk)有助于提供初始的 NLP 算法来开始工作。相比之下,spacy 软件包通过大量的方法库提供了更快、更准确的分析。
代码的第一部分(第 6 行和第 7 行)显示了输出 1.4 中的结果。这些列表显示了当前的停用词,使用 len()方法可以让我们快速了解停用词的数量。从这个分析中,我们可以看到 nltk 列表更小。
从代码的第二部分(第 9 行到第 22 行),我们可以看到输出 1.5 中显示的结果。在这段代码中,我们的目标是通过执行维恩图分析来理解列表之间的差异。通过应用 set()方法,我们确保了可迭代的元素都是不同的。执行 union()有助于显示两个 set 语句的组合,并为我们提供完整的停用词集。而取交集显示了在两个集合中看到的唯一值。最后的陈述旨在了解哪些值是每个集合独有的,而在另一个集合中看不到。
Python 输出了两个包的停用词的 1.4 结果
Python 输出 1.5 两个停用词列表的比较
正如我们从输出 1.5 中看到的,较大的 spacy 集合包含更多 nltk 集合中没有的唯一值。但是,nltk 集合中仍有一组 56 个值可以添加到空间集合中。如果空间集需要任何额外的停用词,我们可能需要重新访问这个片段。
实体
回顾句子的实体旨在发现提供上下文的关键标签。在 spacy 中,我们可以提取与实体相关的文本和标签。
代码 1.5 理解实体和句子特征
从代码 1.5 开始,每个实体都被请求。在第二部分(第 6 行到第 9 行)中回顾了其他见解。最后一部分旨在揭示每个句子的长度。
Python Output 1.6 结果来自实体和句子
输出显示了关键实体标签,其中一些与位置相关。理解句子中的名词和动词有助于提供项目和动作的细节。记录句子的数量有助于确定文章的结构。通过回顾每一个句子的长度,我们可以看到这篇文章是如何既有长句又有短句的。如果我们只回顾所有句子的平均长度,我们可能会错过这个范围。
使用 displacy 模块,我们还可以显示上面列出的每个实体如何在文本中显示。
代码 1.6 使用 displacy 模块显示文本
Python 输出 1.7 一个显示文档,突出显示文本中的实体
我们可以更好地理解最后一段包含了关于两个极点位置的更多细节。该上下文可以显示文本已经向不同的方向移动。如果我们只显示了前面看到的 for 循环中的实体,我们可能会错过文本中紧密相连的值。
结论
总的来说,我们已经回顾了 NLP 数据集的一些初始特征。我们已经介绍了执行初始 EDA 所需的步骤。通过获得这种洞察力,我们能够理解我们正在处理的数据集的结构。在执行额外的分析时,显示并始终建议对数据集总体进行采样。它有助于减少所需的处理和在应用于更大的群体之前消耗的内存。我们从这个 EDA 转移到 NLP 分析,并开始理解如何使用 spacy 从样本文本中获得有价值的见解。我们介绍了 NLP 分析的一些关键元素,并开始创建新的列,用于建立模型,将文本分类到不同的难度。
感谢阅读
spaCy 3.0 入门
理解运行 spaCy 代码时发生的事情
图片来源:威廉·冈克尔
关于这篇文章
这篇文章是故事“理解 NLP —从 TF-IDF 到变形金刚 ”的支持材料的一部分
本文详细介绍了如何开始使用 spaCy。我们将把重点放在内部,而不仅仅是写一些代码和执行它。这意味着——我们将尝试更深入地研究当您执行每个代码片段时发生了什么。
每个代码片段都被分解并详细解释。如果您只想查看运行中的代码,您可能想跳过中间的详细解释,直接在您的 IDE 上运行代码。
是给谁的?
如果您刚刚开始使用 NLP,最好阅读一些关于 NLP 基本概念的文章。
在继续之前,您可能想更新/理解一些概念—
- 代币
- 词性标注
- 命名实体识别(NER)
- 词汇化/词干化
这篇文章是写给任何一个刚开始尝试 spaCy 作为你的软件包的人的。在我们的例子中,我们将使用 spaCy v3.0。
关于空间的一个简短说明
spaCy
是一个工业级 NLP 包。
- 它很快(用 C 编写,带有 Python 的语言绑定)
- 这是生产级的
- 受到活跃社区的支持
- 围绕它构建了许多活跃的独立项目
安装和设置
步骤 1 ) 安装spaCy
就像安装任何其他软件包一样
> pip install spaCy
步骤 2)从命令提示符下下载至少一个预先训练好的管道模型(英语版)
> spacy download en_core_web_sm
这下载了一个小型的英语语言模型管道,在网上找到的大量文本样本上进行训练。对于我们下载的语言,它有weights
、vocabularies
等(我们还不用担心这些术语)。现在我们准备尝试一些例子。
你可以下载 4 个预先训练好的管道—
en_core_web_sm
—小型号(13 MB)en_core_web_md
—中型预训练型号(44 MB)en_core_web_lg
—大型预训练模型(742 MB)en_core_web_trf
( —基于变压器的预训练型号 438 MB)
输出的准确性和效率(执行速度)将取决于您选择的预训练模型。
#代码片段 1 —入门
import spacy
nlp = spacy.load("en_core_web_md")doc = nlp("On October 23, Apple CEO Tim Cook unveiled the new iPad Mini, fourth generation iPad with Retina display, new iMac, and the 13-inch MacBook Pro with Retina display.")
这里发生了什么?
- 我们导入了一个预先训练好的 spacy.lang 对象(如前所述,这个预先训练好的模型基于来自互联网的英语文本样本)。
- 运行这个
nlp()
管道(以一个字符串为参数,返回一个Doc
)。 - 返回一个我们可以操作的空间
Doc
对象
幕后发生了什么?
当你把文本放在nlp()
周围时,会发生很多事情。要知道发生了什么,调用pipeline
属性,你就会看到发生了什么。
>> nlp.pipeline
按正确顺序给出管道中包含的组件列表。
[('tok2vec', <spacy.pipeline.tok2vec.Tok2Vec at 0x24c8>),
('tagger', <spacy.pipeline.tagger.Tagger at 0x24c47c8>),
('parser', <spacy.pipeline.dep_parser.DependencyParser at 0x24c9ba8>),
('ner', <spacy.pipeline.ner.EntityRecognizer at 0x24c66508>),
('attribute_ruler',
<spacy.pipeline.attributeruler.AttributeRuler at 0x24c67e08>),
('lemmatizer', <spacy.lang.en.lemmatizer.EnglishLemmatizer at 0x2403a88>)]
这意味着当您调用 nlp()时,您正在运行一系列步骤—
spaCy 语言处理管道(图片由作者提供)
- 记号赋予器 —将文本转换成由单词和标点组成的小段——这些小段被称为记号。
- 标记器 —该组件根据所使用的语言模型,将每个单词标记为相应的 词性 。
- 解析器 —用于依赖解析的组件(换句话说,找到句子中单词之间的结构和关系——在本文的上下文中理解起来并不重要)。
- NER (命名实体识别器)。
- 属性标尺 —当您分配自己的规则(例如:单词/短语令牌匹配)时,该组件可以为单个令牌设置属性。
- 词条解释器 —该组件为文档中的每个单词/符号创建词条。(词条也称为单词的基本形式。)
哇!— 如你所见,这里完成了很多工作。如果你有一个非常大的文本,它可能需要一点时间。
此时,我们准备对doc
对象进行一些操作。
#代码片段 2 —显示命名实体
#if you want to show the named entities in the text
doc.ents # if you want to display the labels associated with it
for tkn in doc.ents :
print(tkn.text ," - " ,tkn.label_)
上面代码的输出会是这样的—
代码的输出(图片由作者提供)
或者如果你想要一个可视化的显示
from spacy import displacy
displacy.render(doc, style='ent')
会给你以下的输出。
文档中标识的实体的空间输出。(图片由作者提供)
#代码片段 3—探索 doc 对象
1。句子 —您可以使用doc
对象中的sents
属性将句子分成一个iterator
对象,创建一个迭代器保存每个句子。
#working with sentences txt = “Hello my dear fellow scholars ! This is Tomas from the German republic. Iam very happy to join you. How are you all feeling ?”doc = nlp(txt)for sentences in doc.sents :
print(sentences)# or you can store it as a list
list_sentences = list(doc.sents)
上述代码的输出如下所示
代码的输出(图片由作者提供)
👉注:从 doc 对象中提取的句子是一个统计预测,不一定是最准确的。它不进行简单的基于规则的拆分,例如:基于“句号”/“句号”字符)
#代码片段 4—规则和字符串匹配(自定义搜索模式)
spaCy 允许您搜索自定义搜索模式。这里有一个应用于前面例子的简单模式。
txt_apl = "On October 23, Apple CEO Tim Cook unveiled the new iPad Mini, fourth generation iPad with Retina display, new iMac, and the 13-inch MacBook Pro with Retina display."doc = nlp(txt_apl)
现在,创建并添加自定义搜索模式:
from spacy.matcher import Matcher
mat = Matcher(nlp.vocab,validate = True)#create patterns for matching
patrn_mac = [ {'LOWER': 'ipad'}]
patrn_Appl = [ {'LOWER': {'IN': ['apple', 'appl']}}]mat.add('patrn_mac', [patrn_mac])
mat.add('patrn_Appl', [patrn_Appl])for match_id, start, end in mat(doc):
print(doc[start: end], “found at “,[start,end])
上面代码的输出看起来像这样—
Apple found at [4, 5]
iPad found at [11, 12]
iPad found at [16, 17]
下面是正在发生的事情—分解成几个步骤:
- 导入相关包(此处为
Matcher
)。 - 通过包含
spacy.vocab.Vocab
对象,创建一个Matcher
对象mat
。 - 定义你的模式——这里我们想搜索任何字符串,转换成小写,并检查它是否匹配’
ipad
,并将该模式命名为patrn_mac.
。类似地,我们创建另一个名为patrn_Appl
的模式。 - 将这些图案添加到我们创建的
Matcher
对象(mat)
中。 - 对我们从文本中创建的文档运行/检查这个
Matcher
对象。mat(doc)
方法返回一个列表,其中包含匹配 ID、文档中匹配的开始和结束位置——如下所示:
[
(4260053945752191717, 4, 5),
(4964878671255706859, 11, 12),
(4964878671255706859, 16, 17)
]
概述
- 当您运行
nlp()
时,它运行一个组件管道—tok2vec
、tagger
、parser
、ner
、attribute_ruler
和lemmatizer
。 doc.ents
列出预训练模型识别的实体。- 您可以使用
displacy
直观查看 NER 输出。 - 在文档中列出你的句子。
- 您可以使用
Matcher
模块创建自定义字符串匹配模式。
结束语
这是对 spaCy 入门的简要介绍。然而,这篇文章并没有公正地评价 spaCy 作为一个高度可扩展的 NLP 包的能力和威力。后续文章将展示 spaCy 作为 NLP 包的生产就绪选择的强大功能。
如果你想阅读一些关于 NLP 的相关文章,这里有一篇
https://pythoslabs.medium.com/10-use-cases-in-everyday-business-operations-using-nlp-af49b9650d8f使用 NLP 的日常业务运营中的 10 个用例
**https://pythoslabs.medium.com/10-use-cases-in-everyday-business-operations-using-nlp-af49b9650d8f **
Python 预提交挂钩入门
定义拒绝不符合要求的提交的规则
布鲁克·安德森在 Unsplash 上拍摄的照片
这里是这个项目的模板。我们使用诗歌进行包装管理。本文主要关注预提交挂钩。
https://github.com/edkrueger/poetry-template
什么是预提交挂钩?
预提交钩子是 Git 钩子的子集。Git-hooks 是每当 Git 存储库中发生特定事件时自动运行的脚本。“预提交挂钩”在提交发生之前运行。
这些 Python 钩子被认为是静态分析的一种方法。静态代码分析是一种通过检查代码而不执行代码来进行调试的方法。
预提交挂钩通常用于确保代码在发布前被正确地链接和格式化。在我们的项目中,我们使用四个预提交钩子,black
、check-large-files、pylint
和我们的自定义钩子create-requirements
。
我们在一个名为pre-commit-config.yaml
的 YAML 文件中指定这些 Python 钩子。YAML 是一种人类可读的数据序列化语言,通常用于配置文件。YAML 文件包含带有键/值对的列表和字典。
预提交 Python 包
令人困惑的是,还有一个叫做pre-commit
的 Python 包。预提交是一个用于预提交挂钩的管理工具。这个包在每次提交之前管理安装和执行挂钩。
我们将需要这个pre-commit
包作为开发需求。此外,钩子check-added-large-files
来自这个预提交包,稍后你可以在我们的.yaml
文件中看到。
请注意,在[tool.poetry.dev-dependecies]
下,您会找到pre-commit.
pyproject.toml
提交前挂钩文件
使用包pre-commit
设置 git 挂钩非常容易。我们需要做的就是在我们的项目中创建并格式化一个.pre-commit-config.yaml
文件。然后包pre-commit
在你运行时寻找这个.yaml
文件:
> pre-commit install
因为 Python 我们的 Python 钩子在源代码中是以 YAML 的形式存储的,所以当我们把这个文件上传到 Git 时,它们会自动分发。这使得在新机器上设置项目的预提交挂钩就像克隆 repo 并运行上面的代码行一样简单。
如果您没有使用 Python 包、预提交和他们提供给我们的标准格式,这个过程会更复杂。
我们的.pre-commit-config.yaml
这是一个不错的通用pre-commit-config.yaml
。我们可以看到在repos
下面是一个字典列表,用键/值对来指定钩子和它们的行为。这个 YAML 包含了格式化钩子,文件大小过滤器,棉绒,和我们的自定义钩子。每个钩子都有一个伴随的id
,见第 5、9、12 和 18 行。
。预提交配置文件
这是标准的 .yaml
格式。您可以看到嵌套在repos.
中的repo
键,每个回购键后面都跟有所需钩子代码的值(URL)。第 2 行和第 6 行有对应于 Github 存储库的 URL。
在第 10 行,我们指定下面的钩子是local
钩子。这意味着我们在本地使用第 14 行的 bash 代码运行pylint
,使用第 20 行的代码运行create-requirements
。
本地运行pylint
给了我们对内衬行为更多的控制,因为我们可以指定 bash 命令如何工作。这节省了我们调试pylint
问题的时间,并允许更多的透明度和定制。此外,在本地运行pylint
意味着您在自己的环境中使用的是pylint
的版本。
值得注意的是,在第 3 行和第 7 行,我们使用rev
来指定我们想要使用的钩子的版本。这些版本可能与您的虚拟环境中的版本不同步。您必须手动保持这些版本的同步。如果这是一个问题,您可以在本地运行所有的挂钩,以确保挂钩使用的是您在虚拟环境中指定的相同版本。
运行提交前挂钩
我们运行poetry run pre-commit install
来初始化 git 挂钩。
提交前安装
现在我们的预提交钩子将在我们提交代码时运行。
使用预提交挂钩的 git 提交
这里的终端输出很简单。我们看到每个钩子都有一个skipped,passed, or failed
结果。
Black
被跳过,因为没有已更改的 Python 文件来运行格式化。钩子check-added-large-files
通过,因为没有超过 5Mb 的文件被提交。pylint
无法在我们的 Python 文件中找到任何林挺错误。最后,我们注意到我们的定制钩子失败了,因为我们的requirements.txt
文件与我们的pyproject.toml.
文件不同步
假设我们已经做了必要的修改,所以我们所有的预提交钩子都通过了(或者跳过了),并且我们已经使用了git add
在提交中包含了修改。现在,当我们运行git commit
时,我们的输出看起来略有不同。
带预提交的 git 提交
因为我们所有的预提交 Python 钩子都已经通过或跳过,所以提交将被完成和暂存。注意,当一个钩子失败时,提交也会失败。这就是当我们的代码不符合我们的标准时,预提交钩子如何避免我们犯错误。
现在我们可以git push
对我们的源代码进行修改,知道我们的提交没有语法错误、不必要的大文件或过时的 requirements.txt 文件。
结论
记住,“预提交钩子”在提交发生之前运行。Python 包 Pre-commit 使我们能够轻松地管理和运行钩子,我们需要这些钩子来确保代码在发布前被正确地链接和格式化。
通过最少的设置,预提交钩子可以避免错误的提交,从而节省时间。像black
这样的预提交钩子确保你发布的代码是干净和专业的。Pylint
在我们将错误添加到代码库之前向我们显示错误。在您意外地将大文件提交给 git 之前,大文件检查会向您发出警告。这种意外事故很难逆转,所以最好提前预防。
您甚至可以将自己的预提交挂钩编码为 bash 脚本,以满足定制需求。例如,您可以要求在提交代码之前运行测试。
有关使用 bash 编写自己的预提交钩子的更多信息,请查看这篇文章!
Python 虚拟环境入门
入门
避免 python 项目间冲突的简短指南
如果您刚刚开始使用 python 进行数据科学或开发,您可能会遇到一个常见的初学者问题——为什么您的项目在从事其他工作一段时间后不再运行。您可能也不知道您的 python 包存储在哪里,或者不知道如何在项目之间管理不同版本的 python。好了,松一口气吧,虚拟环境已经来拯救我们了(实际上它们已经存在很长时间了。长到找不到参考文献……)。
不要让你的 python 和你的头发纠缠在一起,使用虚拟环境。图片是卡拉瓦乔的美杜莎,来源于维基共享。
它们是什么?
简单地说,Python 虚拟环境是一个独立 python 在您的计算机上运行的封闭环境🐍。这意味着您可以拥有单独的虚拟环境,为您的每个项目提供单独版本的 python 和 python 包。因此,您可以在一个项目上安装或删除 python 包,这不会影响您可能拥有的任何其他项目。
注意:本指南假设您已经安装了 python 3。如果没有,请访问https://www.python.org/获取安装说明。
你把它们放在哪里?
有些人喜欢把他们所有的 python 虚拟环境放在一个文件夹中,然而,我发现这种方法很难跟踪什么环境属于什么项目。对于 python 虚拟环境,一个更常见的做法是将它们放在每个项目的根目录下。
例如,如果您有一个名为“example_project”的项目,您可以将当前目录更改到那里
cd example_project
然后按照以下步骤创建您的虚拟环境。
创建虚拟环境
人们用来创建虚拟环境的一种常见方式是使用一个名为 virtualenv 的 python 包,但从 python 3.3 版本开始,virtualenv 的部分内容实际上是以模块名venv
内置到 python 中的。现在,您可以使用以下命令创建虚拟环境:
python3 -m venv venv
这是怎么回事?
- 嗯,
python3
就是你安装的 python。如果你安装的 python 版本叫python
、python3.7
或者python3.9
或者别的什么,那就用那个; -m venv
是一个告诉 python 运行虚拟环境模块的参数,venv
;- 最后,最后一个
venv
是虚拟环境文件夹的名称。有些人喜欢用另一个名字(如 env 或。env),不过,这完全取决于你。
这个命令应该做的是在当前目录下创建一个名为 venv 的 python 虚拟环境。
注意:如果你使用 git,你会想把 *venv/*
添加到一个名为。gitignore 确保你不会对你的虚拟环境进行版本控制。如果您忘记了这一步,那么您的 git 存储库可能会被数百个额外的版本控制文件堵塞。
一旦你创建了你的虚拟环境,你就不需要再这样做了。现在,您将能够按照以下步骤使用您的环境。
如何使用它们
要使用虚拟环境,您需要使用以下命令“激活”该环境:
(在 MacOS 和 Linux 上)
source venv/bin/activate
或(Windows)
venv\Scripts\activate
如果您在 MacOS 或 Linux 上使用 fish shell(像我一样),您需要将上面的 MacOS 或 Linux 命令替换为:
source venv/bin/activate.fish
上述命令所做的是改变命令python
和pip
(python 包管理器)来引用那些位于 venv 文件夹中的命令。应该会出现一个有用的指示器,显示您正在使用虚拟环境,如下所示:
(venv) $
这意味着当您安装带有 pip 的软件包时,例如
pip install numpy
现在,您将把它安装到 venv 文件夹中的虚拟环境中。如果您愿意,您应该能够查看您在venv/lib/python3.9/site-packages
中安装的包的文件。如果不同,您必须用python3.9
替换您的版本。
按照上面的步骤操作,应该会看到类似下面 GIF 的东西。
创建虚拟环境。图片作者。
继续这个例子,如果您现在以交互模式启动 python,您将能够使用以下命令访问这些包:
pythonimport numpy as npprint(np.sqrt(5))
如果一切正常,您应该会看到类似下面的内容:
使用虚拟环境。图片作者。
在使用 python 运行 python 文件时,您还应该能够访问您安装的任何包。例如,如果您想使用虚拟环境中包含的 python 来运行一个名为“main.py”的文件,您可以使用以下命令:
python main.py
完成虚拟环境后,您可以关闭终端,或者使用如下命令停用环境:
deactivate
如果需要的话,这也将允许您为您的另一个项目激活一个不同的虚拟环境。
复制你的环境
为了重现 python 虚拟环境(例如,在另一台机器上),通常需要将安装的包保存到一个文件中。这将允许任何拥有您的文件的人安装您在开发项目时使用的相同版本的包。然而,你可能还是想告诉他们你使用的 python 版本。通常人们喜欢使用一个名为“requirements.txt”的文件来实现这个目的。
如果您已经激活了 python 虚拟环境,那么您可以自动生成 requirements.txt 文件,包含以下内容:
pip freeze > requirements.txt
您也可以编辑这个文件或者手动创建一个,如果您愿意的话(例如,您不想对包的版本要求如此严格)。更多详情见此处。
因此,如果您或其他人想要创建一个虚拟环境并使用与您相同的包,他们可以按照上面的命令创建并激活一个虚拟环境,然后安装您的需求。可以使用 pip 的-r 方法安装需求,如下所示:
pip install -r requirements.txt
现在去哪里?
我已经向您展示了使用 python 的虚拟环境的最简单和标准的方法,但是,如果您愿意,您可以使用虚拟环境和 python 的各种方法。大多数情况下,这些都不是不必要的,但是如果您愿意,一些著名的包提供了一种不同的方式来处理虚拟环境和包,它们是:
- 诗歌【https://python-poetry.org/】T2,还有
- https://www.anaconda.com/products/individual康达
如果你已经走了这么远,谢谢你。我希望这篇文章能帮助您在数据科学(或您所做的任何事情)之旅中取得更大的进步。如果你喜欢这篇文章,请鼓掌并关注我,让我有动力写更多。如果你有任何问题,请在下面补充。
PyTorch 入门
入门
通过示例学习基础知识
照片由来自 Pexels 的杰瑞米·毕夏普拍摄
介绍
在我之前的帖子“Tensorflow入门”中,我提到如果你想构建小型或大型深度学习解决方案,tensor flow 和 PyTorch 都是很好的选择。这两个平台都广泛应用于学术界和工业界,维护良好,是开源的,提供简单的 API 和高级功能。
在这里,我们将探索 PyTorch API。在“【Tensorflow 入门”的同时,我们将讨论 PyTorch 是如何产生的,以及如何将其用于深度学习。
PyTorch 是什么时候开发的?
大约在 PyTorch 0.1.1 版本于 2016 年 9 月发布时,有多个深度学习框架可用,为构建和训练复杂模型提供了低级和高级包装器。
Caffe、Chainer、Theano、Tensorflow、CNTK、MXNet 和 Torch 只是研究人员用来构建日益复杂的网络的几个低级库。
另一方面,Lasagne 和 Keras 专注于创建可以使用许多低级库之一的高级包装器。这种方法得到了从业者的大力支持,因为它允许他们从 Tensorflow、CNTK 或 Theano 等语言的低级语法中进行抽象。
在接下来的几年里,随着 frameworks⁴:的放弃和巩固,情况发生了巨大的变化
- Keras 被并入 Tensorflow,大大改变了方向;
- Caffe 2 被合并到 PyTorch 中,取代了 Torch 祖先的部分原始 Lua 实现;
- Theano、CNTK 和 Chainer 的开发和支持已停止。
谷歌在“机器学习和人工智能”类别下搜索 2017 年 1 月至 2021 年 7 月之间的顶级低/高级深度学习框架(Tensorflow、Keras、PyTorch)。为了进行比较,还显示了合并的 Tensorflow+Keras 和 PyTorch+Caffe2。图片由作者提供。
到 2021 年 6 月,超过 99%的谷歌搜索主要深度学习框架包含 Tensorflow/Keras 或 PyTorch/Caffe,其中第一个仍然明显更受欢迎(见图表)。
通过例子学习
在下面的小节中,我将介绍在 PyTorch 中构建两个简单神经网络的关键概念(一个用于回归,一个用于分类)。
为了使本教程与我之前的帖子“tensor flow入门”相媲美,我将重复使用相同的模拟数据集。为了使本教程自成一体,我将在这里再次重新介绍它们。
线性回归
在此示例中,我们将在 PyTorch 中构建一个简单的 1 层神经网络来解决线性回归问题。这将解释如何初始化你的权重(又名回归系数),以及如何通过反向传播来更新它们。
我们首先需要的是一个数据集。这里,我们将模拟一个噪声线性模型,如下所示
其中 Y 是我们的目标,X 是我们的输入,w 是我们要确定的系数,N 是高斯分布噪声变量。为此,在笔记本的第一个单元格中粘贴并运行以下代码片段。
这将显示 X 和 Y 之间关系的散点图,清楚地表明在一些高斯噪声下的线性相关性。在这里,我们期望一个合理的模型来估计 2 作为理想的回归系数。
代表高斯噪声下 X 和 Y 之间线性相关性的模拟数据。
在 PyTorch 中,我们通常使用张量来表示我们的输入、目标和回归系数(这里称为权重)。张量是由火炬表示的多维元素阵列。张量的对象。张量只有一种数据类型和一种形状。
现在让我们将输入(x)和目标(y)转换成火炬张量。为此,在 Colab 中复制并运行以下代码片段。
这将返回类(火炬。张量)、输入和目标张量的形状、大小和值。
Describing the features...
<class 'torch.Tensor'>
torch.float64
torch.Size([1000])
tensor([0.0000, 0.0010, 0.0020, 0.0030, 0.0040, 0.0050, 0.0060, 0.0070, 0.0080,
0.0090], dtype=torch.float64) Describing the target...
<class 'torch.Tensor'>
torch.float64
torch.Size([1000])
tensor([ 0.1587, -0.6984, 0.1692, 0.1368, 0.1386, 0.0854, 0.2807, 0.2895,
0.5358, 0.3550], dtype=torch.float64)
现在让我们用一个常数(0.1)开始我们的权重。为此,我们调用“torch.tensor ”,缺省值为 0.1,需要的数据类型(float)和存储张量的设备。在本例中,我们将在“cpu”中执行所有操作。为了提高大型神经网络模型的性能,我们可以将张量移至“gpu”。
运行这个代码片段将输出权重张量的类、形状、类型和值。注意,这个张量有一个“[]”形状,表示它是一个 0 维向量。
Describing the weights…
<class ‘torch.Tensor’>
torch.float32 torch.Size([])
tensor(0.1000, requires_grad=True)
给定初始化的权重张量和输入 X,为了获得预测的 Y (Yhat ),我们可以简单地调用 Yhat = x * w _ tensor.detach()。numpy()'。的’。分离()。“numpy()”用于将权重向量转换为 numpy 数组。复制并运行下面的代码片段,看看初始化后的重量如何符合数据。
正如你所观察到的,‘w _ tensor’的当前值与理想值相差甚远。回归线完全符合数据。
训练前模型拟合的表示。
为了找到‘w _ tensor’的最佳值,我们需要定义一个损失度量和一个优化器。这里,我们将使用均方误差(MSE)作为我们的损失度量,随机梯度下降(SGD)作为我们的优化器。
我们现在有了优化我们的“w _ 张量”的所有部分。优化循环需要自定义“前进”步骤的定义,从我们的损失度量调用“后退”步骤方法,从我们的优化器调用“步骤”方法。
自定义的“前进”步骤告诉模型如何将输入与权重张量相结合,以及如何计算我们的目标与预测目标之间的误差(下面代码片段中的第 5 行到第 8 行)。在一个更复杂的例子中,这将是一组定义从输入 X 到目标 y 的计算图的指令。
“向后”步骤告诉模型将错误反向传播到网络中的每一层(下面代码片段中的第 22 行)。
最后,“optimizer.step()”告诉模型计算并应用这次迭代的权重变化(下面代码片段中的第 23 行)。注意,在大多数情况下,您需要在调用优化器步骤之前清除梯度(下面代码片段中的第 21 行)。
在训练结束时,你的体重应该接近 2(理想值)。要使用该模型进行推理(即,在给定 X 值的情况下预测 Y 变量),只需执行“Yhat = x * w_tensor.detach()。numpy()'。
训练后模型拟合的表示。
分类问题
在本例中,我们将引入 PyTorch NN 顺序模型定义来创建一个更复杂的神经网络。如果你习惯 Keras,这个模块看起来会很熟悉。我们将把这个模型应用于一个线性可分的分类问题。
像以前一样,让我们从构建数据集开始。在下面的代码片段中,我们为第一个聚类创建了两个以(0.2,0.2)为中心的点聚类,为第二个聚类创建了两个以(0.8,0.8)为中心的点聚类。
我们可以很快观察到,用一条与两个聚类距离相等的线将两个数据集线性分离的模型是理想的。
模拟数据表示两个数据聚类,第一个聚类以(0.2,0.2)为中心,第二个聚类以(0.8,0.8)为中心。
让我们从定义自定义 NN 模型来解决这个问题开始。我们将定义一个 5 层神经网络如下:
- 有 10 个节点的线性层。这将有一个 2 x 10(输入形状 x 图层大小)的形状。
- 批量标准化层。这一层将对每一批的第一层的输出进行归一化,避免爆炸/消失梯度。
- Relu 激活层。这一层将为我们的网络提供非线性能力。请注意,我们仅以此为例。对于这个问题,relu 层是不必要的,因为它是线性可分离的。
- 具有两个节点的线性层。这将有一个 10 x 2(层大小 x 输出形状)的形状。
- Softmax 层。该层会将第 4 层的输出转换为 softmax。
和以前一样,让我们也将 x 和 y numpy 数组转换成张量,使它们对 PyTorch 可用,然后定义我们的损失度量和优化器。在这个例子中,我们应该使用分类损失度量,例如交叉熵。
对于优化器,我们可以像以前一样使用 SGD。然而,普通 SGD 的收敛速度慢得令人难以置信。相反,我们将使用最近的自适应梯度下降方法(RMSProp)。
和以前一样,我们先来检查一下我们的网络在训练前表现如何。要使用该模型进行推理,我们可以简单地键入“yhat = model(x)”。现在,复制下面的片段来可视化网络输出。
你可以确认网络一点也不好。显然需要一些训练来正确区分这两个类别。
训练前模型拟合的表示。
为了训练顺序 PyTorch 模型,我们遵循与第一个示例相同的步骤,但是用模型调用替换了自定义的“前进”步骤。将下面的片段添加到您的笔记本中,以训练模型。
在训练循环结束时,你的网络应该能够很好地分离这两个类。要使用该模型进行推理(即,在给定 X 值的情况下预测 Y 变量),您可以简单地执行“yhat = model(x)”。
训练后模型拟合的表示。
完整脚本
如需完整的脚本,请点击以下链接进入我的 github 页面:
https://github.com/andreRibeiro1989/medium/blob/main/pytorch_getting_started.ipynb
或者通过以下链接直接访问 Google Colab 笔记本:
结论
PyTorch 是目前开发定制深度学习解决方案的最佳深度学习框架之一(另一个是 Tensorflow)。在这篇博客中,我介绍了在 PyTorch 中构建两个简单 NN 模型的关键概念。
**警告!!!**正如我在《【Tensorflow 入门中提到的,你的学习才刚刚开始。要变得更好,你需要不断练习。官方 Pytorch 网站提供了从初学者到专家级别的示例,以及 Pytorch 软件包的官方文档。祝你好运!
[1]钦塔拉,苏密特。 PyTorch Alpha-1 发布(2016 年 9 月)
https://github.com/pytorch/pytorch/releases/tag/v0.1.1
[2]因陀罗·登·贝克。"深度学习框架之战—第一部分:2017,更多框架和接口"
https://towardsdatascience . com/Battle-of-the-Deep-Learning-frameworks-Part-I-cff0e 3841750
[3]麦迪逊·梅。"Python 深度学习框架概述"
https://www . kdnugges . com/2017/02/Python-Deep-Learning-Frameworks-Overview . html
[4]伊莱·史蒂文斯、卢卡·安提卡、托马斯·维赫曼。"用 PyTorch 进行深度学习"
https://py torch . org/assets/Deep-Learning/Deep-Learning-with-py torch . pdf
R Shiny 入门
向成为一名闪亮的专家迈出第一步
R 闪亮简介
Shiny 是一个 R 包,它允许程序员在 R 中构建 web 应用程序。对于像我这样发现用 Java 构建 GUI 应用程序非常困难的人来说,Shiny 让它变得容易多了。
这篇博客文章将让你用工作示例直接构建闪亮的应用程序。首先,确保你安装了闪亮的软件包。
install.packages("shiny")
闪亮的应用程序结构
和 R 文件一样,闪亮的应用也以*结尾。r 分机。*app 结构由三部分组成,分别是:
- 一个用户界面对象 (ui)
- 服务器功能
- 对 shinyApp 的函数调用
用户界面(ui
)对象用于管理应用程序的外观和布局,如单选按钮、面板和选择框。
*# Define UI for app*
ui <- fluidPage(
*# App title ----*
titlePanel("!"),
*# Sidebar layout with input and output definitions ----*
sidebarLayout(
*# Sidebar panel for inputs*
sidebarPanel(
)*# Allow user to select input for a y-axis variable from drop-down*
selectInput("y_varb", label="Y-axis variable",choices=names(data)[c(-1,-3,-4)]),*# Output: Plot*
("plot", dblclick = "plot_reset"))
server
函数包含构建应用程序所需的信息。例如,这包括生成图或表以及对用户点击做出反应的指令。
*# Define server logic here ----*
server <- **function**(input, output) {
*# 1\. It is "reactive" and therefore updates x-variable based on y- variable selection* *# 2\. Its output type is a plot*
output$distPlot <- renderPlot({
remaining <- reactive({
names(data)[c(-1,-3,-4,-match(input$y_varb,names(data)))]
})
observeEvent(remaining(),{
choices <- remaining()
updateSelectInput(session = getDefaultReactiveDomain(),inputId = "x_varb", choices = choices)
})
}output$plot <- renderPlot({
#ADD YOUR GGPLOT CODE HERE
subset_data<-data[1:input$sample_sz,]
ggplot(subset_data, aes_string(input$x_varb, input$y_varb))+
geom_point(aes_string(colour=input$cat_colour))+
geom_smooth(method="lm",formula=input$formula)}, res = 96)
}
最后,shinyApp
函数基于 UI/服务器对构建闪亮的应用程序对象。
library(shiny)
*# Build shiny object* shinyApp(ui = ui, server = server)
*# Call to run the application*
runApp("my_app")
什么是反应性?
反应性就是把用户输入和应用输出联系起来;以便 Shiny 应用程序中的显示可以根据用户的输入或选择进行动态更新。
反应式编程的构建模块
输入
传递给shinyServer
函数的input
对象允许用户访问应用程序的输入字段。它是一个类似列表的对象,包含从浏览器发送的所有输入数据,根据输入 ID 命名。
与典型的列表不同,输入对象是只读的。如果您试图修改服务器函数内部的输入,您将会得到一个错误。输入只能由用户设置。这是通过创建一个反应表达式来完成的,其中一个普通表达式被传递到reactive
。要从输入中读取数据,您必须处于由像renderText()
或reactive().
这样的函数创建的反应上下文中
输出
为了允许在应用程序中查看反应值或输入,需要将它们分配给output
对象。和input
对象一样,它也是一个类似列表的对象。它通常与类似renderTable.
的render
功能一起工作
render
功能执行以下两个操作:
- 它设置了一个反应上下文,用于自动将输入与输出关联起来。
- 它将 R 代码输出转换为 HTML 代码,以便在应用程序上显示。
反应式表达
反应式表达式用于将应用程序中的代码分割成相当大的代码块,这不仅可以减少代码重复,还可以避免重新计算。
在下面的例子中,反应代码接收来自用户的四个输入,然后用于输出独立样本 t 检验的结果。
server <- function(input, output) {x1 <- reactive(rnorm(input$n1, input$mean1, input$sd1))x2 <- reactive(rnorm(input$n2, input$mean2, input$sd2))output$ttest <- renderPrint({t.test(x1(), x2())})}
闪亮的应用示例
现在,我们知道一些基础知识,让我们建立一些应用程序。
应用一
该应用程序使用一个虚拟数据集,其中包括三个连续变量。对应用程序的要求如下:
- 在数据集中三个连续变量中的两个之间生成散点图,其中第一个变量不能相对于自身绘制。
- 用户可以选择 x 和 y 变量进行绘图
- 用户可以选择绘图公式(“yx”,“ypoly(x,2)”,“y~log(x)”)。
- 选择的分类变量用于给散点图中的点着色
- 用户可以选择行数(样本大小),范围从 1 到 1,000,用于绘图。
*#Load libraries*
library(shiny)
library(ggplot2)***#Create dummy dataset***
k<-1000
set.seed(999)
data<-data.frame(id=1:k)
data$gest.age<-round(rnorm(k,34,.5),1)
data$gender<-factor(rbinom(k,1,.5),labels=c("female","male"))
z = -1.5+((((data$gest.age-mean(data$gest.age)))/sd(data$gest.age))*-1.5)
pr = 1/(1+exp(-z))
data$mat.smoke = factor(rbinom(k,1,pr))
data$bwt<- round(-3+data$gest.age*0.15+
((as.numeric(data$mat.smoke)-1)*-.1)+
((as.numeric(data$mat.smoke)-1))*((data$gest.age*-0.12))+
(((as.numeric(data$mat.smoke)-1))*(4))+
((as.numeric(data$gender)-1)*.2)+rnorm(k,0,0.1),3)
data$mat.bmi<-round((122+((data$bwt*10)+((data$bwt^8)*2))/200)+
rnorm(k,0,1.5)+(data$gest.age*-3),1)rm(z, pr, k)***#Define UI***
ui <- fluidPage(
***#1\. Select 1 of 3 continuous variables as y-variable and x-variable***
selectInput("y_varb", label="Y-axis variable",choices=names(data)[c(-1,-3,-4)]),
selectInput("x_varb", label="X-axis variable", choices=NULL), ***#2\. Colour points using categorical variable (1 of 4 options)***
selectInput("cat_colour", label="Select Categorical variable", choices=names(data)[c(-1,-2,-5,-6)]), ** *#3\. Select sample size***
selectInput("sample_sz", label = "Select sample size", choices = c(1:1000)),
#4\. Three different types of linear regression plots
selectInput("formula", label="Formula", choices=c("y~x", "y~poly(x,2)", "y~log(x)")),
#5\. Reset plot output after each selection
plotOutput("plot", dblclick = "plot_reset")
)
server <- function(input, output) {
***#1\. Register the y-variable selected, the remaining variables are now options for x-variable***
remaining <- reactive({
names(data)[c(-1,-3,-4,-match(input$y_varb,names(data)))]
})
observeEvent(remaining(),{
choices <- remaining()
updateSelectInput(session = getDefaultReactiveDomain(),inputId = "x_varb", choices = choices)
})
output$plot <- renderPlot({
***#Produce scatter plot***
subset_data<-data[1:input$sample_sz,]
ggplot(subset_data, aes_string(input$x_varb, input$y_varb))+
geom_point(aes_string(colour=input$cat_colour))+
geom_smooth(method="lm",formula=input$formula)}, res = 96)
}***# Run the application***
shinyApp(ui = ui, server = server)
图 1:用户必须从 5 个不同的输入中进行选择
一旦用户选择了输入,就会生成下面的散点图。
图 2:应用一的输出图
这就是你的第一个 web 应用程序。然而,让我们进一步分解代码。
App 一解释
功能selectInput
用于显示下拉菜单,供用户选择绘图变量、散点图中各点的着色变量以及样本大小。
在server
函数中,基于用户对 y 变量的选择,用户对 x 变量的选择被更新。observeEvent
函数用于响应事件执行动作。在这个例子中,它更新了可以为 x 轴选择的 x 变量列表;因此不能在 y 轴和 x 轴上绘制同一个变量。
然后使用函数renderPlot
获取所有输入,x 变量、y 变量、分类变量、样本大小和公式,以生成或“呈现”一个图。
这就是你的第一个闪亮的应用程序。
现在,如果我们希望下拉菜单是一个滑块。您可以通过在中添加以下代码片段来修改代码。
ui <- fluidPage(
#3\. Select sample size
# numericInput("sample_sz", "Input sample size", 10000),
sliderInput(inputId = "sample_sz",
label = "Select sample size:",
min = 1,
max = 10000,
value = 1)
)
输出将类似于
图 App One 的输出显示了样本大小的滑块
现在,让我们进入下一个稍微复杂一点的例子。
应用二
在这个应用程序中,我们正在查看一个数据集,该数据集显示了新冠肺炎感染导致的五种威胁生命的后果。我们希望该应用程序能够做到以下几点:
- 允许用户从五个结果中选择一个作为输入
- 通过森林地块中选定的结果比较不同的县
- 如果用户在图中选择了一个县,那么应该生成另一个森林图,显示所选国家的所有五个结果。
- 显示缺少值的错误消息。
#Load libraries
library(shiny)
library(ggplot2)
library(exactci)#import the data and restrict the data to variables and patients of interest
patient.data<-read.csv("Synthea_patient_covid.csv", na.strings = "")
cons.data<-read.csv("Synthea_conditions_covid.csv", na.strings = "")
data<-merge(cons.data, patient.data)
data<-data[which(data$covid_status==1),]
data<-data[,c(12,14,65,96,165,194)]#Get the state average for each outcome
state.average<-apply(data[,-6],MARGIN=2,FUN=mean)#Make better names for the outcomes
names<-c("pulmonary embolism", "respiratory failure", "dyspnea", "hypoxemia", "sepsis")#Calculate and aggregate the obs and exp by outcome and county
data$sample.size<-1
list<-list()
for (i in 1:5) {
list[[i]]<-cbind(outcome=rep(names[i],length(unique(data$COUNTY))),
aggregate(data[,i]~COUNTY, sum,data=data),
exp=round(aggregate(sample.size~COUNTY, sum,data=data)[,2]
*state.average[i],2))
}
plot.data<-do.call(rbind,list)
names(plot.data)[3]<-"obs"#Lastly, obtain the smr (called est), lci and uci for each row
#Add confidence limits
plot.data$est<-NA
plot.data$lci<-NA
plot.data$uci<-NA
#Calculate the confidence intervals for each row with a for loop and add them to the plot.data
for (i in 1:nrow(plot.data)){
plot.data[i,5]<-as.numeric(poisson.exact(plot.data[i,3],plot.data[i,4],
tsmethod = "central")$estimate)
plot.data[i,6]<-as.numeric(poisson.exact(plot.data[i,3],plot.data[i,4],
tsmethod = "central")$conf.int[1])
plot.data[i,7]<-as.numeric(poisson.exact(plot.data[i,3],plot.data[i,4],
tsmethod = "central")$conf.int[2])
}# Define UI for application
ui <- fluidPage(
selectInput("outcome_var", label="Outcome",unique(plot.data$outcome)),
plotOutput("plot", click = "plot_click"),
plotOutput("plot2")
)
server <- function(input, output) {
output$plot <- renderPlot({#Output error message for missing values
validate(
need( nrow(plot.data) > 0, "Data insufficient for plot")
)
ggplot(subset(plot.data,outcome==input$outcome_var), aes(x = COUNTY,y = est, ymin = pmax(0.25,lci),
ymax = pmin(2.25,uci))) +
geom_pointrange()+
geom_hline(yintercept =1, linetype=2)+
coord_flip() +
xlab("")+ ylab("SMR (95% Confidence Interval)")+
theme(legend.position="none")+ ylim(0.25, 2.25)
}, res = 96)
#Output error message for missing values
#modify this plot so it's the same forest plot as above but shows all outcomes for the selected county
output$plot2 <- renderPlot({validate(
need( nrow(plot.data) > 0, "Data insufficient for plot as it contains a missing value")
)
#Output error message for trying to round a value when it doesn't exist/missing
validate(
need( as.numeric(input$plot_click$y), "Non-numeric y-value selected")
)
forestp_data<-plot.data[which(plot.data$COUNTY==names(table(plot.data$COUNTY))[round(input$plot_click$y,0)]),]
ggplot(forestp_data, aes(x = outcome,y = est, ymin = pmax(0.25,lci), ymax = pmin(2.25,uci))) +
geom_pointrange()+
geom_hline(yintercept =1, linetype=2)+
coord_flip() +
xlab("")+ ylab("SMR (95% Confidence Interval)")+
theme(legend.position="none")+ ylim(0.25, 2.25)
})
}# Run the application
shinyApp(ui = ui, server = server)
App 二解说
在这个应用程序中,像 App One 一样,用户从下拉框中选择一个结果。这产生了一个森林地块。这个森林图的计算是在闪亮的用户界面之外完成的。这个应用程序中的棘手之处是构建一个反应性的第二个图,以响应用户在第一个图中单击的 county。
这种反应发生在使用以下代码行的服务器函数中
plot.data[which(plot.data$COUNTY==names(table(plot.data$COUNTY))[round(input$plot_click$y,0)]),]
在这里,我们检查选择了哪个县,以便显示所有五个结果的第二个森林图。
图 App 2 中的第一个森林图是基于选择的结果生成的
图 5:单击给定县的第一个森林图,生成下面的第二个图,显示所选县的所有五个结果
在应用程序中,使用validate
功能显示一条错误消息,如果有数据丢失,则会显示一条由以下语法导致的错误:
[round(input$plot_click$y,0)],]
应用三
最终的 web 应用程序的目标是允许用户绘制数据集中变量之间的关系。一些变量是分类的,而另一些是连续的。当绘制两个连续变量时,用户应该只能在散点图上绘制它们。当选择了一个连续变量和一个分类变量时,用户应该只能绘制箱线图。用户不应该能够用两个分类变量绘图。根据用户的选择,应用程序应该一次只显示一个图。
#Load libraries
library(shiny)
library(ggplot2)#import data
setwd("C:/Users/User/Desktop/Synthea")
patient.data<-read.csv("Synthea_patient_covid.csv", na.strings = "")
obs.data<-read.csv("Synthea_observations_covid.csv", na.strings = "")patient.data$dob<-as.Date(patient.data$BIRTHDATE, tryFormats = "%d/%m/%Y")
patient.data$enc.date<-as.Date(patient.data$DATE, tryFormats = "%d/%m/%Y")
patient.data$age<-as.numeric((patient.data$enc.date-patient.data$dob)/365.25)
data<-merge(obs.data, patient.data)
data<-na.omit(data[,c(4,5,10:12,20,24,32,18,15,23,31,33,48:51,60)])
names(data)<-substr(names(data),1,10)
data$covid_stat<-as.factor(data$covid_stat)
data$dead<-as.factor(data$dead)# Define UI for application
ui <- fluidPage(
#1\. Select 1 of many continuous variables as y-variable
selectInput("y_varb", label="Y-axis variable",choices=names(data)[c(-1,-2,-14,-15,-16,-17)]),
#2 Select any variable in dataset as x-variable
selectInput("x_varb", label="X-axis variable", choices=names(data)),
#3\. Reset plot1 output after each selection
plotOutput("plot", dblclick = "plot_reset"))
server <- function(input, output) {
remaining <- reactive({
names(data)[-match(input$y_varb,names(data))]
})
observeEvent(remaining(),{
choices <- remaining()
updateSelectInput(session = getDefaultReactiveDomain(),inputId = "x_varb", choices = choices)
})
output$plot <- renderPlot({if ( is.numeric(data[[input$x_varb]]) ) {
ggplot(data, aes_string(input$x_varb, input$y_varb)) + geom_point()
} else {
ggplot(data, aes_string(input$x_varb, input$y_varb)) + stat_boxplot()
}})
}# Run the application
shinyApp(ui = ui, server = server)
图 6:选择分类变量和连续变量时显示的箱线图
图 7:如果选择了两个连续变量,则显示散点图
App 三解说
这个应用程序中的巧妙之处在于使用了renderPlot
中的 if-else 条件,因此只能选择两种类型的图(散点图或箱线图)中的一种。此外,当你想检查input$x_varb
的类时,使用双方括号(list)是必需的,data[[input$x_varb]],
否则输出将总是字符。
结论
现在,你有了三个简单的应用程序。让我们快速回顾一下这篇博客文章的内容。
- 一个闪亮的应用程序的结构
- 连接输入和输出
- 使用 reactive()和 observeEvent 创建动态用户界面
- 使用验证显示错误消息
强化学习入门
揭秘一些与强化学习相关的主要概念和术语,以及它们与人工智能其他领域的关联
列宁·艾斯特拉达在 Unsplash 上的照片
介绍
今天,人工智能(AI)经历了令人印象深刻的进步。根据机器逻辑地和独立地执行智力任务的能力,人工智能可以细分为三个不同的级别:
- 狭义 AI :机器在执行非常具体的任务(但不试图执行其他类型的任务)时比人类更有效率。
- 通用 AI :机器和人类一样聪明。
- 强 AI :机器在不同领域(在我们可能或根本无法执行的任务中)表现得比人类更好。
现在,由于机器学习,我们已经能够在狭窄的人工智能水平上实现良好的能力。使用的机器学习算法主要有三种类型:
- 监督学习: 使用带标签的训练集训练一个模型,然后对无标签的数据进行预测。
- 无监督学习: 给一个模型一个未标记的数据集,然后模型要试着在数据中寻找模式来做预测。
- 强化学习: 通过奖励机制训练模型,在表现良好的情况下鼓励积极的行为(特别用于基于代理的模拟、游戏和机器人)。
强化学习,现在被认为是最有前途的技术,以便进入人工智能范式的下一个阶段(图 1)。
图 1:强化学习代理玩超级马里奥[1]
强化学习
强化学习今天获得如此多兴趣的原因之一是它的跨学科性。这个领域的核心概念,事实上遵循基本的博弈论、进化和神经科学原则。
与所有其他形式的机器学习相比,RL 实际上可以被认为是试图复制人类和动物如何学习的最接近的近似方法。
强化学习主张人类最常使用的主要学习方式是通过使用他们的传感器和与环境交互(因此不需要像监督学习那样的外部指导,而是通过试错过程)。
在日常生活中,我们试图完成新的任务,根据我们尝试的结果,我们会影响周围的环境。通过评估我们的尝试,我们可以从经验中学习,以确定哪些行为给了我们更大的好处(因此最方便重复),哪些行为应该避免。图 2 总结了这个迭代过程,它代表了大多数基于强化学习的算法的主要工作流程。
一个代理(如软件机器人,机器人)被放置在一个环境中,通过与它的互动,可以学习,接收新的刺激和创造新的状态(如解锁一个新的场景或修改现有场景的结构)。然后,我们的代理的每一个动作都与一个奖励值相关联,以评估其实现预定目标的效率。
图 2:强化学习工作流程[2]
表征强化学习系统的两个主要挑战是:
- 与此同时,如果代理人甚至不尝试不同的行动,它可能永远不会发现更好的奖励是可能实现的。
- 延迟奖励的处理 :代理不被告知要尝试什么动作,而是应该想出不同的解决方案,测试它们,最后根据收到的奖励进行评估。代理不应仅根据眼前的回报来评估他们的行为。事实上,选择某种类型的行动可能会带来更大的回报,不是立即的,而是长期的。
核心组件
根据 Richard S. Sutton 等人[3]的观点,强化学习算法由 4 个主要的关键部分组成:策略、奖励、价值函数和环境模型。
- 策略: 定义代理行为(将不同的状态映射到动作)。政策最有可能是随机的,因为每个特定的行动都与被选择的概率相关联。
- 奖励: 是一个信号,用来提醒代理应该如何最好地修改它的策略,以达到规定的目标(在短时间内)。每当执行一个动作时,代理从环境接收一个奖励。
- 价值函数: 是为了获得一种感觉,什么行为从长远来看能带来更大的回报。它的工作原理是给不同的状态赋值,以评估如果从任何特定的状态出发,一个代理应该期望什么样的回报。
- 环境模型: 模拟智能体所处环境的动态,以及环境应该如何响应智能体采取的不同动作。取决于应用,一些 RL 算法不一定需要环境模型(无模型方法),因为可以使用试错法来接近它们。但是,基于模型的方法可以使 RL 算法处理需要规划的更复杂的任务。
结论
如果你有兴趣了解更多关于强化学习的内容,理查德·萨顿和安德鲁·g·巴尔托的《强化学习:导论》和《开放人工智能健身房》将在我的下一篇文章中讨论。)是两个很好的起点。
希望您喜欢这篇文章,感谢您的阅读!
联系人
如果你想了解我最新的文章和项目,请在媒体上关注我,并订阅我的邮件列表。以下是我的一些联系人详细信息:
文献学
[1]强化学习,Gfycat。访问时间:https://gfycat.com/gifs/search/reinforcement+learning
[2]强化学习—第 1 部分:Q-学习简介,Novatec。访问:https://www . novatec-gmbh . de/en/blog/introduction-to-q-learning/
[3]强化学习:导论,理查德·萨顿和安德鲁·巴尔托。麻省理工学院出版社剑桥,马萨诸塞州伦敦,英国。访问:https://web . Stanford . edu/class/psych 209/Readings/suttonbartoiprlbook 2 nded . pdf
在 AWS SageMaker 上用 PyTorch 和拥抱脸变形金刚微调 BERT
现实世界中的数据科学
使用 PyTorch、BERT 和 Amazon SageMaker 构建最先进的文本分类器的分步指南
在本教程中,我将向您展示如何在亚马逊 SageMaker 上构建和训练一个文本分类器。我们将利用出色的拥抱脸变形金刚库来训练一个最先进的 NLP 模型来对亚马逊书评进行分类。
云技术正成为数据科学家工作中越来越重要的一部分,AWS 技能非常受欢迎。我的目标是通过一步一步地指导您完成这一过程,消除新手无法使用云工具的常见障碍。
你在学习如何用 SageMaker 训练你的模型之后。
我们开始吧
如果你已经熟悉 SageMaker,只是想看看代码,这里有 repo 。
什么是 SageMaker?
亚马逊 SageMaker 是一个完全托管的机器学习服务,用于构建、培训和部署机器学习模型。SageMaker 内置了几个模型训练的框架( XGBoost 、 BlazingText 等)。),而且还可以使用像 PyTorch 和 TensorFlow 这样的框架轻松创建定制的深度学习模型。
为什么要学 SageMaker?
使用 SageMaker 对数据科学家和工程师有很多好处:
- 模特培训。SageMaker 使得利用 GPU 实例进行更快的模型训练变得更加容易。如果没有 GPU,训练许多深度学习架构是难以处理的。例如,微调最先进的语言模型(就像本教程中一样)和计算机视觉模型需要每一步更新数亿个参数。即使不需要,使用 GPU 进行训练也会加快你的开发周期,让你迭代更快和交付更多价值。
- 模型部署。SageMaker 使得将模型部署为可以通过 REST API 访问的生产级端点变得相对简单。您定义了容器、实例类型和一些扩展配置,剩下的由 SageMaker 处理。
- 超参数调谐。SageMaker 支持贝叶斯超参数优化用于许多建模框架。这个特性对于快速找到最佳超参数非常有价值。
- 这个清单还在继续。AWS 继续向 SageMaker 生态系统添加功能,解决模型监控、跟踪实验等问题。
Google Cloud 和 Azure 提供类似 AWS SageMaker 的解决方案。我选择 AWS 作为本教程的参考,因为它是行业领导者——越来越多的公司使用它,使它成为开发人员更有市场的技能。
使用 SageMaker 进行模型训练
- 设置。
- 数据。
- PyTorch 模型脚本。
- 启动模型培训。
设置
对于本教程,您需要创建一个 AWS 帐户,并设置一个 IAM admin 用户,以及一个 SageMaker 角色。您还需要安装和配置 AWS CLI,并创建一个 S3 bucket。按照这里的步骤 1-4开始!
为了访问 GPU,您还需要请求增加服务限制。为此,导航至控制台中的支持中心,点击创建案例。选择服务限制增加,对于限制类型选择 SageMaker 。在此表格中填写您将培训模特的地区:
数据
本指南使用的数据是亚马逊评论数据集的子集,具体来说就是书评,可以点击这里下载。该数据集相当大,因此您可能希望限制本练习的大小。在 GitHub repo 的中的data.zip
中可以找到该数据的较小版本。如果您想学习如何自己处理大型数据集,请查看我对在 AWS EMR 上使用 PySpark 的介绍。
使用自定义数据集或在 Kaggle 上找到一个数据集非常容易——你所需要的只是一个包含文本和标签行的文件。
模型
对于本教程,我们将使用来自拥抱脸的变形金刚库。拥抱脸可以很容易地加载预先训练的最先进的语言模型,并在自己的数据集上进行微调。这里使用的具体模型是distil BERT——它是 BERT 的一个分支,更小,因此训练和推理更快更便宜。
微调预先训练好的模型的做法被称为迁移学习— 在这里阅读更多信息。如果你有兴趣了解变革了 NLP 的 transformer 架构的更多信息,我强烈推荐杰伊·阿拉玛的《图解 Transformer》。
创建一个 SageMaker 评估程序脚本
我们需要一个 Python 脚本,将我们的训练数据上传到 S3,定义我们的 SageMaker 估计器,并启动训练作业。您需要更新bucket
和role
,以反映您在上面的设置部分中创建的存储桶和角色。
- 第一部分将我们的训练数据上传到 S3,SageMaker 可以访问这些数据。
- 接下来,我们定义
hyperparameters
,它实际上只是我们的模型脚本将接受的命令行参数。您可以使您的模型脚本非常灵活,以接受不同的数据预处理和模型训练参数。这在使用 SageMaker 超参数调谐器时非常方便。 PyTorch
估算器对象中的entry_point
定义了我们的模型脚本,这将在下一节中描述。PyTorch
估算器对象中的source_dir
让我们可以访问utils.py
中定义的函数,并安装requirements.txt
中定义的包。完整的source_dir
可以在这里找到。output_path
在PyTorch
估计器对象中定义了你的训练模型在 S3 的保存位置。
这是开始模型培训的完整脚本,我们将在创建模型脚本后进行。
模型脚本
在 SageMaker 上编写一个脚本来训练一个模型与在本地机器上做同样的事情没有什么不同。完整的脚本可以在 GitHub repo 中找到。
配置 argparse 以接受命令行参数
在文件底部的if __name__ == “__main__":
块中,我们需要利用argparse
模块,以便我们的脚本接受超参数作为命令行参数。在这种情况下,超参数可以是您希望传递给模型脚本用于数据预处理和模型训练的任何参数。
训练模型。
启动模型培训
运行train_model.py
并等待任务完成,或者在终端上观看火车模型。
警告:在撰写本文时, *ml.p2.xlarge*
实例每小时的成本为 0.90 美元。运行该脚本还会产生[最低限度的]S3 存储成本。如果您不希望收取月租费,请务必删除 S3 存储桶中的数据。
检查模型输出
通过在 AWS 控制台中搜索 SageMaker 并点击左侧导航栏中的 Training Jobs 来检查 CloudWatch 日志。然后,点击刚刚完成的培训工作,向下滚动点击查看日志。
点击日志流,您可以查看您的模特培训工作的日志,包括您在src/model.py
中打印的任何内容。
通过导航到train_model.py
中定义的output_path
来定位model.tar.gz
。您可以下载这个模型在其他地方使用,或者在 SageMaker 上通过这个 S3 路径访问它进行批量推理或实时推理。
包扎
我希望您现在能够使用 Amazon SageMaker 在云中构建和训练模型。查看 AWS Labs GitHub 页面,了解如何将 SageMaker 与其他框架一起使用,如 Keras / TensorFlow、 scikit-learn 等等。
更多 AWS 教程
如果你觉得这很有用,一定要关注我,看看我剩下的 AWS 教程。
取得联系
感谢您的阅读!请让我知道你是否喜欢这篇文章,或者你是否有任何批评。想打个招呼就在 LinkedIn 上联系我。干杯!
了解 SQL Server Management Studio —关于数据库、表和命名约定的第 2 部分
让你在派对上开心的技能!逐步地
迈克尔·泽兹奇在 Unsplash 上的照片
在最后一集…
欢迎光临!还是“欢迎回来!”?这是 SQL 和 SQL Server Studio 系列教程的第二部分。目标?让你熟悉和适应这个工具和语言。“这有什么关系?”我知道你在问。事实证明,好奇心和副业往往是被新项目选中的关键,甚至是获得新工作的关键。您已经使用了一个重要的工具,比如 SQL Server Studio,并且编写了一些 SQL 查询,这一事实可以并且将会给您一个清晰的开端。
如果您错过了关于如何设置我们的环境和本地服务器的第 1 集,请阅读本文,然后不要忘记回来😉。
期待什么?
今天,我们将看看数据库、表,并简要提及模式。还会有一个关于命名约定的重要注释。我们将看到创建表的两种方法,并编写删除表的查询。您将找到 SQL Studio 如何支持您编写无错误查询的示例,并能够查看查询性能和返回的结果。到本文结束时,您将会感到自信,并具备强大的基础知识,开始在 SQL Studio 中漫游。让我们直接跳进来吧!
创建您的第一个数据库
数据库,简称 DB,是表的集合。这是我们最简单的说法。让我们一步一步来创建我们的第一个。
- 我们假设已经启动了 SQL Server Studio,并连接到本地服务器的实例。
- 左边是对象资源管理器。右键单击数据库,然后单击“新建数据库”。
3.将出现一个新窗口。**最大的问题是如何命名我们的数据库。**为什么有关系?一点思考的内容:
- 它很可能会比我们将实施的许多应用程序、仪表盘和流程更长寿。
- 我们合作,所以这个选择的名字将会被使用,无论是口头的还是书面的。想象一下它被命名为 XRZPWO_JLM 。不错吧?祝你在口头对话中好运。随着时间的推移,你可能会经常用到这个术语。一年几百次。好吧,至少在书面形式下,你可以说‘是那个以 XR 开头的服务器……’。好吧,你说到点子上了。那是当然,除非它是唯一一个这样命名的。拥有一个名为 XRZPWO_JLM 的数据库给了我一个提示,在你的服务器的其余部分将会有更多名为**的方式*。你必须登录,检查,复制粘贴(你将无法通过记忆正确地交流)。您的收件人可能会花一些时间来找到它。听起来像地狱,对吧?*
- 名字作为参考。如果你从一个名为 XRZPWO_JLM 的数据库开始,几个月后,在厌倦了与它交流的麻烦后,你决定改变它,它可能会破坏相关的应用程序。双重痛苦。
那么如何命名呢?对于数据库中的内容,该名称应该是不言自明的。也应该是鲜明的。一个有趣的方法是使用数据库按项目分离我们的数据。
- HR_data 可以保存与您的人员相关的数据,如名字和姓氏、电子邮件、雇佣日期、级别。
- API_Finance 可以托管来自不同金融网站 API 的数据。
- Product_ABC 可以托管从名为 ABC 的产品中收集和生成的数据。
长话短说,命名要紧。这个主题应该有自己的一篇文章。有惯例,不同的方法。常识和实用性应该占上风。我们来看看 HR_data。
我们可以调整一系列设置,但我们将保留默认设置。我们按 enter 键,新的数据库就创建好了。
4.单击+展开“数据库”的层次结构,然后单击“HR_data ”,您应该会看到以下内容:
我们已经有了第一个数据库,我们已经准备好创建第一个表。
创建您的第一个表格
根据字段的不同,表中的元素可以有不同的名称。最常见的是行列称谓。
- 行也可以被称为记录或行,这取决于你问谁。
- 按照列,它们可以被称为“特征”或“变量”,这是数据科学中经常使用的行话。但是你可能知道:
其他名字的行闻起来还是一样香
现在,表命名和数据库命名一样重要。因为同样,我们可能会一遍又一遍地使用和讨论这些术语。这也使得在编写脚本或运行查询时,拥有清晰的名称和对表中内容的理解变得更加容易。
下面我们来看一个复杂的(剧透:不是很好的方式)例子:
上面的这些表形成了一个“规范化模式”——与平面表的模式相反,下一篇文章将详细介绍这一点——但是表和列的命名远非最佳。没有一致性,有些是不言自明的。让我们继续创建我们的第一个表。
- 右键单击表,然后单击新建表
2.将出现表设计器。可以通过多种方式创建表,既可以使用表设计器,也可以编写查询。我们先从前者说起。
使用表格设计器创建表格
我们将从小而简单开始,分为三栏:
- Department_ID —这将是部门的唯一标识符。由于这将是一个数字,我们指定 int (整数)作为数据类型。
- 部门名称—这是其通用名称。我们选择 nvarchar(50 ),因为字符串的长度(这里是部门名称)可能不同,因此数据类型中有“var”。(50)表示我们允许的最大长度。任何超出的都不会被记录。如果我们想使用最大可接受的长度,我们可以将它设置为 nvarchar(MAX)。“为什么不一直用 nvarchar(MAX)呢?”,我看你在问。嗯,因为性能的原因,比 nvarchar(n)慢。
- Department_Email —部门的电子邮件,例如共享邮箱。Nvarchar(50)也在这里。
稍后可以轻松调整 nvarchar(n)。如果您希望文本作为输入,或者如果您很懒并且性能不是您主要关心的问题(可能总是回来困扰您,但是您将能够调整到数字“n”),那么使用(MAX)最有意义。
3.让我们点击左上角的“保存”软盘,给我们的表起一个引人注目的名字,“部门”。
4.现在,该表在层次结构中的“表”下可见。如果没有显示,请点击“刷新”按钮,即“连接”旁边的圆圈箭头。使用网络服务器时,可能会出现表格不显示的情况,您需要单击“连接”并重新连接到服务器。
5.现在已经保存并创建了表,我们可以关闭设计窗口了
6.如果将来您需要调整表格,您可以右键单击表格,然后选择设计。“设计”窗口再次出现,并允许您修改表格。完成后,不要忘记保存更改。
通过编写查询来创建表
这是设计窗口的一种替代方式。当您编写脚本时,这可能会很方便,因为脚本需要创建一个表。结果是一样的,你得到了一个新的表。如果要更新、添加或删除表中的记录,最有可能使用这种方法。让我们看看如何编写一个查询来创建同一个表。
- 右键单击数据库 HR_data,然后单击新建查询
2.将出现一个查询窗口。让我们写以下内容
*CREATE TABLE HR_data.dbo.Departments(Department_ID int,Department_Name nvarchar(50),Department_Email nvarchar(50))*
其结构如下:
- “CREATE TABLE”是 SQL 语言中的一个命令名。
- 然后,通过点链或层次结构,我们精确地确定应该在哪里创建这个表。这里是在我们的表> 的 HR_data.dbo. <名称内。“Dbo”是默认设置。
- 然后我们打开一个方括号’(',开始输入我们的列名,后面是它的数据类型。每一行都以逗号结尾。
- 我们用另一个括号“)”结束列列表。
*3.在窗口中,您会看到查询的一部分用红色下划线标出。有点不对劲。我们的数据库中已经有一个这样的表。因此,在本练习中,我们将调整上面的查询,并将表称为 *Departments_temp。现代脚本和编码环境的一个有用特性是扫描潜在的 bug 或错误。这甚至在我们开始执行代码之前就节省了大量的时间。
让我们键入以下内容:
*CREATE TABLE HR_data.dbo.Departments_temp(Department_ID int,Department_Name nvarchar(50),Department_Email nvarchar(50))*
红色下划线消失了。
4.我们现在可以执行我们的查询。点击 F5 或“执行”绿色箭头。
5.我们会收到对我们的询问的即时反馈
6.让我们刷新我们的服务器,表出现。很棒的东西。
7.为了保持整洁,我们将删除这个 _temp 表。小心这个,因为一旦它掉了…它就掉了。不见了。
8.我们将回收我们的查询窗口,首先删除导致表创建的代码。然后写下以下内容,并点击执行或 F5:
*DROP TABLE HR_data.dbo.Departments_temp*
9.刷新层次结构后,我们看到表不见了。请注意,“刷新”只是从用户界面的角度来看。因为在后台,当您执行’ drop table …'查询时,该表已经被删除了。
查询我们的表
可以查询或“读取”表。让我们看看我们自己的 SQL“Hello World”。
- 清理您的查询窗口。或者关闭它并重新打开一个。
- 键入下面的,然后执行/F5
*SELECT *
FROM HR_data.dbo.Departments*
- 选择意味着我们将选择接下来的内容,
- *表示“一切”,即每一列,
- FROM 表示我们将从中选择“所有内容”的来源
查询窗口上的其他提示和注释
旗帜
在这一系列教程中,我们会遇到不同的颜色。下面先睹为快。
- 表名、列名是黑色的,
- SQL 命令(SELECT,FROM,…)将变成蓝色,
- 由简单引号’和’表示字符串将是红色,
- 系统功能将是粉红色的(纯粹主义者会说是洋红色),
- 运算符如 AND、OR 将是灰色的,
- 评论将是绿色的
自己看:
虽然它很漂亮,但没什么用处。
还有更多!
结果窗格
结果窗格显示我们的查询结果(如果我们正在进行“选择”):
它还提供了受“消息”影响的记录数量的信息。如果没有错误,您将得到以下结果:
如果出现问题,您会收到通知,并得到一些关于如何调试的支持,例如“无效的列名‘Departm’”。
结果窗格还为我们提供了以下一般信息:
- 查询的状态:
**
- 它的性能,即它运行了多长时间和返回的记录数,这里它在不到 1 秒的时间内执行,并返回 0 行,因为我们的表或查询有 0 个匹配。
最后的话和接下来会发生什么
暂时就这样吧!我的目标是让它简短、甜蜜、有趣,尽管这部电影中没有任何迷因。
- 我希望您现在有信心创建数据库和表,无论是使用设计工具还是通过编写查询。
- 您也有权删除表,但是要小心,因为除非您的数据库得到备份,否则您将丢失底层数据。您还会停止依赖于它的任何应用程序、过程或表。
- 您知道结果窗格、查询性能指标和返回的行数,这是调试的第一种方法。
- 我不能再强调正确的表和数据库命名的重要性了,因为它们会随着时间的推移而出现,如果您选择了糟糕的名称,它们可能会困扰您。
编码快乐!
感谢阅读!喜欢这个故事吗? 加入媒介 可完整访问我的所有故事。
从关于 CRUD 操作、主键和外键的第 3 集开始继续这一旅程!
*
或者选择你喜欢的另一集
在第 4 集中,我们讨论模式&主要的规范化步骤— 第 4 部分模式&规范化
在第 5 集,我们覆盖存储过程&调度,这是一个真正的野兽。我怎么强调这将如何促进和自动化你的日常(数据)生活都不为过。第五部分存储过程&调度
在第 6 集中,我们介绍了用于 ETL 的 SSIS 包,并回顾了如何在两个数据库之间以及一个数据库和 Excel 之间导入和导出数据。第六部 SSIS 套餐简介
在第 7 集中,我们将 SQL Studio 连接到 PowerBI,并构建了我们的第一批视觉效果。[第 7 部分连接到 PowerBI &第一视觉效果](http://Part 7 Connect to PowerBI & First Visuals)*
了解 SQL Server Management Studio —第 1 部分分步安装
这是一个免费且强大的工具,可以利用数据、提高技能并在面试中脱颖而出
迈克尔·泽兹奇在 Unsplash 上的照片
期待什么?
在这一系列文章中,我将对 Microsoft SQL Server Management Studio(SSMS)进行一次演练。今天,我们将从环境设置开始。在接下来的文章中,我们将创建自己的数据库和表。创建、读取、更新、删除记录。我们将编写、保存和修改我们自己的存储过程。我们还将安排作业,创建 SSIS 包…如果您不熟悉其中的一些术语,您很快就会掌握,并自己创建和管理它们。
SSMS 是一个强有力的工具,如果你想提高技能或面试另一份工作,这是一项有趣的技能。这也是一个在浏览器窗口上把你在 SQL 101 中学到的东西付诸实践的机会,但是从来没有机会体验数据库管理软件的感觉。
什么是 SQL?
SQL 代表**结构化查询语言。**它旨在管理关系数据库中的数据。剧透:它做得很好。这门语言诞生于 20 世纪 70 年代,自那以后已经有了很大的发展。在其存在的 40 多年里,新的数据类型、操作符和功能丰富了这种语言。
什么是 Microsoft SQL Server Management Studio?
Microsoft SQL Server Management Studio 通常被称为 SSMS,是一种用于配置、管理和控制数据的工具。该工具允许您连接到本地(酷孩子称之为“本地”)和云中的 SQL Server 实例。
你能实现什么?
简而言之:很多东西。更详细的回答是,在 SSMS,你可以:
- 连接到服务器及其实例,
- 创建和管理数据库及其底层表,
- 连接到可视化工具,如 PowerBI,Tableau,Spotfire,…
- 连接到 Power Automate 等自动化工具,或者 PowerApps 等低代码和无代码平台,
- 创建和管理存储过程,即您可以编写和保存的脚本。然后,可以在以后执行这些程序来利用您的数据,例如对您的数据进行一些操作、存档记录或表格、发送电子邮件等等
- 创建和管理触发器,这是在某个操作(创建/删除/更新记录等)之后触发的自动化操作
- 创建和管理计划作业,以便给定的存储过程以任何定义的频率运行,
- 备份和恢复数据,
- 导入和导出数据
- 创建 SSIS 软件包,用微软自己的话说就是:
“SQL Server Integration Services(SSIS)是一个构建企业级数据集成和数据转换解决方案的平台。使用 Integration Services 通过复制或下载文件、加载数据仓库、清理和挖掘数据以及管理 SQL Server 对象和数据来解决复杂的业务问题"
如果您想在数据库之间或服务器之间复制表,SSIS 包非常有用。可以保存 SSIS 包,然后将其用作计划作业的一部分。
这是一份很长的清单。但是如何以及从哪里开始呢?请继续阅读!
设置您的环境
这应该是一种解脱:安装和设置将不会是一场噩梦。这个软件是成熟和稳定的,我还没有遇到任何错误或崩溃。将有两个组件安装完成。
1.下载 SSMS
进入页面,在【下载 SSMS】下下载最新版本。在撰写本文时,它是 v18.8。启动程序要求您有大约 657MB 的空闲磁盘空间。一旦你完成安装,你应该会发现这样的标志。
一个相当于任何注重数据的人的锤子和镰刀的数据库。启动程序时,应出现以下屏幕:
进入矩阵
然后很快出现一个窗口,让您连接到服务器:
好吧,现在正是恐慌的时候。“连接到服务器?但是您没有告诉我们需要服务器。”你是对的。如果你有一个,你可以输入它的名字和实例:\实例#。例如 myserver\inst1。
如果你没有足够的服务器,不要担心,还有一个方法可以让你继续享受和探索 SSMS。进入第二次下载:
2。SQL Express
我们将使用我们的计算机和 SQL Express 作为我们的服务器和实例。转到本页并下载免费专业版‘Express’
安装完成后,让我们返回下面的 SSMS“连接到服务器”窗口:
首先,我们需要找到我们的计算机名。在 Windows 10 上,点击 Windows 键,然后输入“关于你的电脑,你应该会进入一个页面,我们需要的信息在“设备名称”之后。
您也可以右键单击桌面上的“我的电脑”图标,然后选择属性。你会发现和上面一样的窗口。
复制这个名字并粘贴在 SSMS 窗口。然后写\SQLExpress。它应该是这样的,用你的计算机名代替我的。
点击连接…我们就开始直播了!对象资源管理器提供了一个整洁的文件夹列表,每个文件夹都封装了 SSMS 的特性和功能。
这就是初始设置。在下一篇文章中,我们将讨论数据库和表的创建和设计,记录管理的 CRUD 缩写(创建、读取、更新、删除),等等。
编码快乐!
继续 SQL 之旅,阅读关于数据库、表等的第 2 部分!
或者选择你喜欢的另一集
在第 3 集中,我们介绍了 CRUD 操作以及主键和外键——第 3 部分 CRUD 操作,主键&外键
在第 4 集中,我们讨论模式&主要的规范化步骤— 第 4 部分模式&规范化
在第 5 集,我们覆盖存储过程&调度,这是一个真正的野兽。我怎么强调这将如何促进和自动化你的日常(数据)生活都不为过。第五部分存储过程&调度
在第 6 集中,我们介绍了用于 ETL 的 SSIS 包,并回顾了如何在两个数据库之间以及一个数据库和 Excel 之间导入和导出数据。第六部 SSIS 套餐简介
在第 7 集中,我们将 SQL Studio 连接到 PowerBI,并构建了我们的第一批视觉效果。[第 7 部分连接到 PowerBI &第一视觉效果](http://Part 7 Connect to PowerBI & First Visuals)
感谢阅读!喜欢这个故事吗? 加入媒介 获取完整的我的所有故事。
参考文献
- https://en.wikipedia.org/wiki/SQL
- https://docs . Microsoft . com/en-us/SQL/integration-services/SQL-server-integration-services?view=sql-server-ver15
SSH 入门
数据科学家开始使用 SSH 应该知道的一切
学习如何创建和管理多组 SSH 密钥对是任何有抱负的数据科学家或机器学习工程师的重要技能。来源:Samantha Lam ( Unsplash )
在某些时候,作为一名数据科学家,您需要处理一个需要比您的笔记本电脑或工作站更多计算资源(例如,磁盘空间、CPU 内存、CPU 或 GPU 数量)的数据集。当这种情况发生时,你需要知道如何访问一个拥有足够计算资源的远程服务器来完成手头的任务。无论这些远程服务器驻留在公共云中(即 AWS 、 GCP 或 Azure ),还是驻留在本地(即大学远程计算集群),您都将使用安全外壳(SSH) 协议来访问这些服务器。
在本文中,我将介绍使用 SSH 有效地连接到远程服务器需要了解的内容。特别是,您将学习如何使用 SSH 登录到远程服务器,如何生成自己的 SSH 密钥对,以及如何使用新的 SSH 密钥对部分自动化连接到远程服务器的过程。在以后的文章中,我将讨论如何配置 SSH 以获得最大的生产率,以及如何使用更高级的技术来完全自动化使用 SSH 登录远程服务器的过程。
我们开始吧!
OpenSSH
虽然 SSH 协议有许多实现,但我在本文中重点介绍的是 OpenSSH。OpenSSH 可能是使用 SSH 协议进行远程登录的最广泛使用的连接工具。它对所有流量进行加密,以消除窃听、连接劫持和其他攻击。此外,OpenSSH 提供了一大套安全隧道功能、几种身份验证方法和复杂的配置选项。
如果您运行的是 Mac OS 或 Linux,那么应该已经安装了 OpenSSH。Open SSH 于 2018 年秋季添加到 Windows 中,因此如果您运行的是较新版本的 Windows(特别是 Windows 10),那么 Open SSH 应该也已经安装了。如果您运行的是旧版本的 Windows,那么您可能需要安装并配置 OpenSSH 。
使用 SSH 登录
使用 SSH 登录的默认方式是使用用户名和密码使用[ssh](https://www.ssh.com/ssh/command/)
命令登录到特定的主机(可能是主机名或 IP 地址)。
ssh username@some.host.com # could also be an IP address
如果这是您第一次使用ssh
连接到这个远程服务器,那么您将会看到这样的消息:
The authenticity of host 'some.host.com' cannot be established.
ECDSA key fingerprint is SHA256:d/FZhiccG5Gs6MzA7XR6Hksvl9OZjSx6WVXEi6Ddrj3
Are you sure you want to continue connecting (yes/no)?
根据用于生成远程服务器的主机密钥 (上例中的 ECDSA)的算法类型,上面的消息可能看起来略有不同。键入yes
继续。这将把远程服务器添加到您的已知主机列表中(您的本地机器上的~/.ssh/known_hosts
文件)。
Warning: Permanently added 'some.host.com' (ECDSA) to the list of known hosts.
首次登录远程服务器时,系统会要求您验证并保存远程服务器的主机密钥,以便下次连接到该远程服务器时,您的本地计算机可以验证它实际上是同一个远程服务器(通过检查远程服务器的主机密钥是否包含在已知主机列表中)。
然后,系统会提示您输入密码,以完成身份验证过程。一旦通过身份验证,您就可以登录到您的远程服务器,并且会有一个新的 shell 提示符,通常看起来如下所示(~
表示您的当前目录是您的用户在远程服务器上的主目录)。
username@some.host.com ~$
反复使用您的用户名和密码进行身份验证既耗时又容易出错。在下一节中,我将向您展示如何使用公共/私有 SSH 密钥来部分自动化认证过程。
生成 SSH 密钥对
更高效(也更安全!)与远程服务器交互的方式是使用公共/私有 SSH 密钥对来部分自动化认证过程。如果您对 SSH 公钥/私钥对如何工作的直觉感兴趣,那么我推荐您观看下面的视频;如果您只想学习如何生成自己的公共/私有 SSH 密钥对,那么您可以放心地跳过视频。
[ssh-keygen](https://www.ssh.com/ssh/keygen/)
命令用于使用各种算法生成公共/私有 SSH 密钥对。使用椭圆曲线数字签名算法(ECDSA) 使用ssh-keygen
生成公共/私有 SSH 密钥对,如下所示。
cd ~/.ssh
ssh-keygen \
-t ecdsa\ # could also use older rsa algorithm with -b 4096
-b 521\ # alternatives are 256 or 384
-C "your.email@provider.com"
-f ~/.ssh/id_ecdsa # save your keys in ~/.ssh/
运行上述命令将启动生成公钥/私钥 ECDSA 密钥对的过程。系统将提示您提供保存密钥的文件路径。默认为~/.ssh/id_ecdsa
。您可能有许多组 SSH 密钥对,因此您应该更喜欢将您的密钥文件命名为不太通用的名称。
接下来,系统会提示您输入可选的密码(然后要求您确认密码)。
Enter passphrase (empty for no passphrase):
你应该总是使用密码保护你的私有 SSH 密钥。如果有人获得了对您的本地机器的物理访问权,而您的私钥没有密码保护,那么这个人也获得了对使用您的 SSH 密钥对的每个远程服务器的访问权。
输入(并确认)您的密码后,将生成密钥对并保存到指定的文件中。
Your identification has been saved in ~/.ssh/id_ecdsa.
Your public key has been saved in ~/.ssh/id_ecdsa.pub.
The key fingerprint is:
SHA256:2yyanHlvgr68zw1pS+h7zDTkvR0pujsyrKumPqHb3bY your.email@provider.com
The key's randomart image is:
+---[ECDSA 521]---+
|.. . |
|..o o B . o|
|..E.... @ * o. +o|
|. + + = = + +* o|
|. . + . S + o =o=|
| o o . = *.|
|. . + . o |
| . . + |
| .. |
+----[SHA256]-----+
将 SSH 密钥对添加到 authorized_keys
为了使用您新生成的 SSH 密钥对登录到您的远程服务器,您必须首先将新生成的公共 SSH 密钥添加到远程服务器上的授权密钥列表中(注意:新生成的私有 SSH 密钥应该始终保留在您的本地机器上)。
将您的公共 SSH 密钥添加到远程服务器上的授权密钥列表中可以通过三个步骤手动完成。
- 运行
cat
输出您的公共 SSH 密钥文件的内容,并复制公共 SSH 密钥。 - 用你的
$USERNAME
和密码登录你的远程服务器$HOSTNAME
。 - 打开
~/.ssh/authorized_keys
文件,在文件末尾粘贴新创建的公共 SSH 密钥。
您可以使用下面的命令,而不是手动将您的公共 SSH 密钥添加到授权密钥列表中(这很容易出错)。
ssh-copy-id -i ~/.ssh/id_ecdsa.pub username@some.host.com
运行上述命令时,系统会提示您提供登录远程服务器的密码,但是一旦命令完成,并且您的公共 SSH 密钥已被添加到授权密钥列表中,您应该能够注销,然后再次登录,而无需提供密码(但是您仍然需要提供密码来解锁您的私有密钥)。
一旦在远程服务器上配置了公钥,远程服务器将允许任何拥有私钥的连接用户(并且知道密码来解锁它!)登录,因此永远不要共享您的私钥。
摘要
下面三个(真的是两个!)命令将生成您的公共/私有 SSH 密钥对,并将公共密钥添加到远程服务器上的~/.ssh/authorized_keys
文件中。
cd ~/.ssh
ssh-keygen -t ecdsa -b 521 -C "your.email@provider.com"
ssh-copy-id -i ~/.ssh/id_ecdsa.pub username@some.host.com
如果您已经做到了这一步,那么恭喜您:您现在应该对 SSH 的基础有了很好的理解!
一旦您开始使用 SSH,您将很快发现您想要生成多个 SSH 密钥对(您需要访问的每个远程服务器都有一个不同的密钥对),因此在本系列的下一篇文章中,我将讨论如何配置 SSH 来有效地管理这些多个 SSH 密钥对。
开始使用 Airflow 2.0 中的任务组
一个包含两组任务的简单管道,使用来自 Airflow 2 的 TaskFlow API 的@taskgroup decorator。
介绍
在 Airflow 2.0 中的任务分组之前,子标记是分组任务的首选 API。在 Airflow 2.0 中,子标签被降级,现在被任务组功能取代。任务流 API 很简单,允许适当的代码结构,有利于清晰地分离关注点。
我们今天构建的是一个包含两组任务的简单 DAG,使用了来自气流 2 的任务流 API 的@taskgroup
装饰器。图表视图为:
作者图片
这条管道对给定的初始值进行不同的操作。任务实例化了一个值为0
的变量。然后,它传递给一组子任务(group_1
),这些子任务处理初始值。group_2
将所有的值聚合成一个。最后,end()
子任务将打印出最终结果。
让我们从将管道分成几个部分开始。
任务分组-分解
如上图所示,有一个init()
和end()
任务。在这两者之间,有两组任务,但是让我们从管道的第一个和最后一个任务开始。
作者图片
init()
任务是这个管道的起点——它返回将在整个管道中操作的初始值:0。任务将把管道中的所有操作打印到控制台。
让我们看看init()
任务的代码:
就是这样。现在是end()
任务的代码:
定义整个管道的流程也很简单,由包装所有内容的函数返回:
查看上面的代码,可以看到:
任务组#1 ( group_1
)
作者图片
group_1
有一组操纵原始数字的三个任务:
group_1
函数接收来自init()
任务的结果。注意这里返回的是什么:三个值的列表。每个值都源于subtask_1
、subtask_2
和subtask_3
。这个值列表就是将要发送给group_2
的内容。
任务组#2 ( group_2
)
作者图片
很简单。它接收从group_1
发送来的列表,并对所有值求和(subtask_4
完成),然后subtask_5
将来自subtask_4
的结果乘以 2:
就是这样——下一个任务是end()
,在本帖之前已经处理过了。同样,这里有可能看到完整的代码。
如果您检查“end()”任务的日志(参见我以前的帖子,了解如何检查任务日志),您将看到打印的结果。最后的结果应该是12
。
成功!🎉
结论
在 Airflow 2 中创建任务组很容易——它消除了以前存在的复杂性,并允许用干净的代码创建管道。
背景
这篇文章是 ETL 系列教程的一部分。这最初发布在pedromadruga.com上。如果你喜欢这篇文章,可以考虑订阅时事通讯或者在推特上关注我。
完整的代码可在这里获得。
原载于【https://pedromadruga.com】。如果你喜欢这篇文章,可以考虑订阅时事通讯或者在推特上关注我。