Tableau 中的自动化分析— Python 和 Tabcmd
概述了如何使用 Python 来自动洞察 Tableau,并介绍了 Tableau 命令行实用程序 Tabcmd。
简介
Tableau 连续七年被 Gartner 评为分析和商业智能平台的领先工具。几乎每个行业中各种形状和规模的公司的 BI/数据团队都开发了仪表板,以便在整个组织中有效地交流关键业务指标。
使用 Tableau 的一个主要优点(这一点经常被忽略)是,它公开了一个公共 API 来以编程方式处理几乎所有可以在应用程序 GUI 上执行的任务,包括管理。
这就是 Python 的用武之地。大量库的脚本功能和支持使其成为在 BI 工作流中处理端到端流程自动化的流行选择。
来自 tableau.com/products/viewer的
在您继续之前…
为了有效地使用集成,Tableau 工作簿应在以下位置可用:
1.Tableau Server允许您在组织服务器上或使用云服务提供商托管内部工作簿和数据源。
2。Tableau OnlineTableau 管理服务器基础设施,您可以通过它们托管您的工作簿,只需支付一些额外费用。
通过上述方法之一将工作簿托管在 Tableau 服务器上通常是一种好的做法——尤其是如果您的仪表板经常被多方查看,并且涉及定期数据刷新(每天/每小时)。
Tableau Online 有一个 14 天的免费试用期,默认情况下会加载一些示例工作簿。您可以创建一个免费试用帐户来试用下面列出的一些测试集成和代码片段。
创建 tableau 在线账户后,保存用户名、密码、Tableau 服务器地址和网站名称的凭证。一台 tableau 服务器可以有多个站点,每个站点都承载一组工作簿和数据源。
条条大路通罗马
将 Python 与 Tableau Server 集成有多种方式,每种方式都基于不同的用例。
- Tableau 服务器客户端(TSC) 库
(Python 3.5 或更高版本)
这可能是从 Python 脚本执行服务器相关任务的最佳选择。这是一个由 Tableau 管理的开源项目,它包装了 Tableau 服务器 REST API。
pip install tableauserverclient
- TabPy 库
允许您在 Tableau 的表计算中嵌入和执行 Python 脚本。它本质上允许 Tableau 远程执行 Python 代码。
pip install tabpy
从这个tabby 博客——在 Tableau 计算中嵌入 Python
3.使用 请求 库直接消耗 Tableau 服务器 REST API 。一个更简单的方法,但是你可以让 Tableau 以任何你认为合适的方式工作,只要 API 允许。
其他整合路线和变体包括:
1.JupyTab
将 Jupyter 笔记本数据带入 Tableau 可视化。
pip install jupytab
- Tabcmd
从 Windows Shell 向 Tableau Server 发出命令——Mac/Linux 原生不支持,但有一个 hack 。
Tabcmd 的执行可以通过在计划任务下的批处理文件中进行设置来实现自动化。将 Tabcmd 添加到您的 windows PATH
变量中,或者切换到安装它的目录来运行它的命令。
您可以使用
***os***
或**subprocess**
模块在 Python 源代码中执行 tabcmd 命令。将 tabcmd 语句构造为字符串,并使用***os.system()***
或***subprocess.call()***
函数将它们传递给 shell
你可以在 Tableau 的 GitHub 页面找到更多支持其他语言(比如 JavaScript)的项目
这里我们重点讲 TSC 和 Tabcmd 的用法。
假设每个 TSC 片段都可以访问下面列出的虚拟变量。用你自己的凭证代替这些。
tableau_user = 'cricks@gmail.com'
tableau_passwd = '123'
tableau_server = 'http://172.16.22.2/'
tableau_server_site = 'my_site'
server_version = '3.7'
对于 Tableau Online,tableau_server
字段看起来会像这样:
prod-apnortheast-a.online.tableau.com
基于您的服务器位置。
以下各节详细介绍了如何使用 TSC 和 Tabcmd 在 Tableau 服务器上执行特定任务。
认证
贸易与供应链
使用 TableauServerClient 登录到 Tableau 服务器
Tabcmd
> tabcmd login -s http://172.16.22.2/ -t my_site -u cricks@gmail.com -p 123
凭证的每个参数都作为 shell 中的一个标志传递。
输出应该如下所示:
===== redirecting to http://172.16.22.2/auth
===== Signed out
===== Creating new session
===== Server: http://172.16.22.2/
===== Username: cricks@gmail.com
===== Site: my_site
===== Connecting to the server...
===== Signing in...
===== Succeeded
如果任一路由的身份验证失败,请向 Tableau 服务器管理员检查您的用户权限/用户授权。
获取并下载工作簿
“超市”工作簿可作为所有 Tableau 发行版的样本。它将是我们代码片段演示中的默认工作簿。
找到工作簿&将其下载为 **.twbx**
文件
TSCT30workbooks.get()
上带TSC.Filter()
的
— TSC.Pager()
— TSC.RequestOptions()
可以找到一个工作簿。
TSC 返回一个带有工作簿 ID、工作簿名称等属性的工作簿对象。这些选项中的每一个都在下面的要点中被详细描述为一个函数。
可以使用
TSC.Server().workbooks.download(workbook_id)
将工作簿下载为twbx
(Tableau 打包工作簿)
从服务器获取工作簿对象并作为 twbx 下载的两种不同方法
您可以通过引用 workbook 对象上的id
属性在服务器上检索工作簿的 ID。
超市工作簿的产品视图
Tabcmd
Tabcmd 保持简短:
tabcmd get “/workbooks/Superstore.twbx”
可能有几个警告,特别是对于 Tabcmd 中的
*get*
命令的权限。请务必在此 查看完整的清单 。您可以使用*get*
下载 PDF 或 PNG 格式的工作簿。
对视图应用过滤器并作为文件下载
我们可以查询工作簿中的特定视图,并对其应用过滤器。
工作原理:
我们发出一个以过滤器为参数的视图请求。API 将请求应用于视图,并将快照取回请求客户端。
过滤前:
超市——所有地区概览
后过滤为Region = West
:
超级商店-区域字段过滤为一个值的概览
TSC
假设workbook id
可以被获取,我们将使用它作为一个虚拟变量。
过滤视图并以 PDF 格式下载
view_items
包含一个view
对象列表。一个视图对象有id
、workbook_id
、name
、csv
等属性。个人最喜欢的是total_views
属性,它返回当前引用的视图在服务器上被用户查看的总次数。
我们需要"populate
" pdf 格式的视图,因为它允许 TSC 仅从网络上获取必要的属性。工作簿或视图对象包含对服务器上该对象的所有其他属性的引用。当需要填充其中一个对象时,TSC 让请求获取所需的属性以满足填充参数。
使用ImageRequestOptions()
可以将图像保存为 PNG,使用CSVRequestOptions()
可以保存 CSV。
关于的用法,请参见此处的文档。
Tabcmd
export 命令接受指定视图的 URL 和下载选项的可选参数。
tabcmd export -t my_site "Superstore/Overview?refresh=yes&Region=West" --pdf --pagesize a4 --pagelayout landscape -f "Overview.pdf"
视图也可以导出为 PNG 或 CSV 格式。
引号中指定的 URI 与用于通过浏览器访问 Tableau 服务器上的视图的 URL 的子字符串完全相同。
以下是相同命令在浏览器上的 URL:
http://172.16.22.2/#/site/my_site/views/Superstore/Overview?Region=West
这有助于在使用 Tabcmd 将视图导出到本地之前,在浏览器上试验视图的外观。
'refresh=yes'
强制服务器端刷新视图并获取最新结果。应用多个过滤器*,在参数中用* ’
&'
将它们分开日期可以过滤为:‘…
?report_date=2020–01–01
数据源和连接
Tableau 作为一个软件的核心特性之一是它允许用户处理数据源、提取和连接输入可视化的数据的能力。
贸易与供应链
获取服务器上的所有数据源作为对象,并打印每个数据源的名称。
与工作簿或视图对象类似,datasource
对象也可以被过滤或分页。
Tabcmd
tabcmd refreshextracts --datasource sales_ds
TSC 与 Tabcmd
TSC 和 Tabcmd 都允许您对数据源、连接、工作簿、视图、用户等执行重要的 CRUD 操作。
虽然 TSC 本身与操作系统无关,但是如果您有 windows 系统或者能够将其配置为在 Mac/Linux 上手动运行,Tabcmd 仍然足以在服务器上执行大多数日常任务。
TSC 胜过 Tabcmd 的一个特殊用例是它能够并行处理对服务器的大量请求。使用 Tabcmd,请求总是在每个 shell 会话中序列化。TSC 可以多线程处理数十或数百个工作线程,从而大幅提升其服务器请求的性能。在 Python 上,您可以在一个使用 TSC 的函数的列表上实现带有map()
的ThreadPoolExecutor()
,并让它为您所用。
这可能有助于启动快速高效的 BI 报告。将这些与Python for Google Sheets/Excel或 Python for SQL 结合在一起可以增强你的工作流程。
Tableau 有丰富的关于使用 TSC 和 Tabcmd 的文档。本文中的代码片段只是触及了它们在 Tableau 服务器上可以执行的大量操作的表面。下面详细检查一下。
其他参考文献
希望这是一个足够温和的介绍,可以让您站起来开始这些集成。
干杯。
自动化 AWS SageMaker 笔记本电脑
了解如何使用 CloudWatch、Lambda 和生命周期配置安排自动执行 AWS SageMaker 笔记本
简介
SageMaker 提供了多种工具和功能来大规模标记、构建、训练和部署机器学习模型。其中最流行的是笔记本实例,用于准备和处理数据,编写代码来训练模型,将模型部署到 Amazon SageMaker 主机,以及测试或验证模型。我最近在做一个项目,涉及自动化 SageMaker 笔记本。
使用 Amazon Glue 在 Sagemaker 中部署模型有多种方式,如这里的和这里的和所述。您还可以使用端点 API 来部署模型。如果您不部署模型,而是一次又一次地执行脚本,那该怎么办?SageMaker 目前还没有直接的方法来实现自动化。另外,如果您想在执行完脚本后立即关闭笔记本实例,该怎么办呢?这肯定会节省你的钱,因为 AWS 是按小时收费的。
我们如何实现这一点?
正在使用的其他 AWS 功能和服务
- 生命周期配置:生命周期配置提供了 shell 脚本,这些脚本仅在您创建 notebook 实例或启动一个实例时运行。它们可用于安装软件包或配置笔记本实例。
- AWS CloudWatch :亚马逊 CloudWatch 是一项监控和可观测性服务。它可用于检测您环境中的异常行为,设置警报,并排显示日志和指标,并采取自动化措施。
- AWS Lambda : AWS Lambda 允许您在不提供或管理服务器的情况下运行代码。您只需为您消耗的计算时间付费,当您的代码不运行时,则不收费。
用于自动化的主要步骤:
- 使用 CloudWatch 触发调用 lambda 函数的执行
- lambda 函数启动相应的笔记本实例。
- 笔记本实例一启动,生命周期配置就会被触发。
- 生命周期配置执行脚本,然后关闭笔记本实例。
详细步骤
λ函数
我们利用 lambda 函数来启动一个笔记本实例。假设 lambda 函数被称为*‘测试-lambda-函数’*。确保选择一个有权限访问 lambda 和 SageMaker 的执行角色。
这里*‘test-notebook-instance’*是我们想要自动化的笔记本实例的名称。
云观察
- 转到规则>创建规则。
- 输入刷新频率
- 选择 lambda 函数名:‘测试-lambda-函数’。这是我们在上面创建的同一个函数。
生命周期配置
我们现在将为我们的’测试笔记本实例’'创建一个生命周期配置。让我们称这个生命周期配置为“测试-生命周期-配置”。
代码:
代码功能的简要说明:
- 启动 python 环境
- 执行 jupyter 笔记本
- 下载包含自动停止功能的 AWS 示例 python 脚本
- 等待 1 分钟。可以根据需要增加或降低。
- 创建一个 cron 作业来执行自动停止 python 脚本
之后,我们将生命周期配置连接到笔记本电脑。
我喜欢在 LinkedIn 上联系——https://www.linkedin.com/in/taufeeqrahmani/
查看我在 Data Sleek 的朋友的工作,寻找所有数据的解决方案。
自动关闭 AWS 服务器以进行深度学习
因为每个人都有忘记的时候,没关系。
最近,我一直在为一个机器学习项目使用 AWS EC2 服务器。我看到的每篇文章都在说同样的事情……“不要忘记关闭 EC2 实例”。看这个让我焦虑。只要一想到让 GPU 开着会在口袋里烧个洞,我就会莫名其妙地出汗。
所以我决定编写一个 Bash 脚本来启动服务器,SSH 进入,这样我就可以继续我的项目,然后当我退出时关闭服务器。我甚至在桌面上保存了一个脚本的快捷方式,这样我只需点击两下就可以开始工作了。
不幸的是,让脚本工作的过程并不简单,而且有点令人恼火。所以我决定写一个快速的帖子,这样社区也可以同样安心。
我的工作站是 Windows 10 PC,所以这些步骤对于 Mac 可能会有所不同。
先决条件 1:拥有一个 AWS 帐户并创建一个实例
您需要有一个 AWS 帐户,并实例化一个 AWS EC2 实例。FastAI 有一个关于如何做到这一点的教程在这里。如果这是您第一次创建 GPU 实例,您可能需要请求增加“p 型”实例的限制。对我来说,这花了大约两天时间才收到 AWS 的回复。
先决条件 2:设置 AWS CLI
您将需要 AWS CLI,这样 Bash 脚本就可以调用来启动/关闭服务器。你可以从这里下载 CLI。
AWS CLI 下载
在接下来的几个步骤中,我们将在 AWS IAM 中为您自己创建一个用户,然后生成并保存安全凭证,以便我们可以使用 AWS CLI。
IAM 控制台
如果 IAM 控制台中有用户,则不需要新用户。只需确保您拥有用户的“安全凭证”
如果您没有用户,请创建一个。
如果您创建了一个用户,请确保授予其“编程访问”权限。接下来,您将为用户生成安全密钥。
保存这些钥匙!
在 Windows 命令提示符下,您需要运行aws configure
并按照提示进行操作。用从 IAM 控制台获得的密钥填写访问密钥 ID 和秘密访问密钥。将默认区域设置为服务器所在的区域。
完成这些步骤后,您应该能够从命令行访问 AWS 实例了。尝试运行aws ec2 describe-instances
,您应该会看到 EC2 实例的列表。
先决条件 3:将 Git-Bash 连接到 AWS
如果您还没有安装 Git-Bash,请在这里安装 Git-Bash。您将需要它来运行 Bash 脚本。
Git-Bash 下载
下一步是将 Git-Bash 连接到 AWS CLI。为此,您需要在 bash 的根目录下创建一个. bashrc 文件。打开一个 Git-Bash 终端并执行以下操作。
cd ~vim .bashrc
这将打开一个文本编辑器。您可以在其中粘贴以下内容。
#!/bin/bashalias aws=”winpty -Xallow-non-tty -Xplain C://Program\ Files/Amazon/AWSCLI/bin/aws.exe”
现在 Git-Bash 终端将识别命令aws
。如果你跳过这一步,你将得到错误bash: aws: command not found
。确保上面插入的文件路径指向您的文件目录中的 aws.exe。
完成后,通过键入esc
和:wq
退出 vim 终端,然后按 enter 键。为了使更改生效,您需要关闭并重新打开 Git-Bash。这样做并执行aws
。您应该看到以下内容。
测试 AWS CLI 命令
创建脚本
这样,我们就非常接近我们的目标了。制作一个 Bash 脚本,自动启动、登录和关闭 EC2 服务器。
现在我们可以结束并编写脚本了。在您的 bash 终端中,导航到您想要脚本的任何地方(对我来说是cd C://Users/harrison/Desktop
),然后运行vim aws.sh
#!/bin/bashINSTANCE_ID=**<YOUR EC2 INSTANCE-ID HERE>** SSH_KEY=**<path/to/sshkey.pem>**echo "Starting AWS Server."
aws ec2 start-instances --instance-ids $INSTANCE_ID#Wait for server to come online
STARTED=False
while [ "$STARTED" != "True" ]; do
SERVER_STATUS=$(aws ec2 describe-instance-status --include-all-instances --instance-ids $INSTANCE_ID --output text --query 'InstanceStatuses[].InstanceState.Name')
if [ "$SERVER_STATUS" == "running" ]; then
STARTED=True
else
sleep 3
fi
doneSERVER_PUBLIC_DNS=$(aws ec2 describe-instances — instance-ids $INSTANCE_ID — output text — query ‘Reservations[].Instances[].PublicDnsName’)echo “Attempting to log into server.”
ssh -L localhost:8888:localhost:8888 -i $SSH_KEY ubuntu@$SERVER_PUBLIC_DNSecho “Shutting down server.”
aws ec2 stop-instances — instance-ids $INSTANCE_ID
echo "Sent shutdown command."
sleep 1echo "Querying instance status..."
aws ec2 describe-instance-status --include-all-instances --instance-ids $INSTANCE_ID --output text --query 'InstanceStatuses[]'
sleep 5
注意:我会定期对这个脚本进行改进。
用您的 EC2 实例的实例 id 填充INSTANCE_ID
。在SSH_KEY
中填入您的 SSH 密钥的路径。
现在,当您想开始在 EC2 服务器上工作时,只需运行 bash 脚本,您就可以连接到您的服务器了。从那里,您可以运行一个jupyter notebook
或者从 GitHub 加载 python 脚本。当您exit
退出实例时,脚本将继续运行并为您关闭服务器。
工作原理(可选)
aws ec2 start-instances — instance-ids $INSTANCE_ID
启动 EC2 实例。
您需要服务器的公共 DNS 才能登录。不幸的是,当您关闭服务器时,DNS 可能会改变。以下代码查询服务器的公共 DNS。
SERVER_PUBLIC_DNS=$(aws ec2 describe-instances — instance-ids $INSTANCE_ID — output text — query ‘Reservations[].Instances[].PublicDnsName’)
用ssh -L localhost:8888:localhost:8888 -i $SSH_KEYubuntu@$SERVER_PUBLIC_DNS
登录 EC2 实例
aws ec2 stop-instances — instance-ids $INSTANCE_ID
停止 EC2 实例。
用机器智能自动化代码
以及来自 OpenAI 的 GPT3 语言处理 API 的更多含义。
这是我的自由星期五关于机器人学& AI 的文章节选,请查阅。 看看这个视频,这是我见过的第一个引人注目的自动化软件生成演示。
来源。
这是什么
OpenAI 最新的语言处理模型 GPT-3(生成式预训练转换器)从两个示例片段创建了各种前端代码片段。(前端代码是在网站上呈现的代码,通常会大量重复以获得相同设计的变体,因此它是自动化的一个简单的初始目标)。
你可以在这里 (Twitter)与工具的作者进行交流。你可以在这里找到更多有创意的例子,或者在这里找到另一个代码生成例子。我特别喜欢的一个是写的创意小说或者是写的自动生成的游戏关于上一代的模型。
这是如何工作的
语言模型“生成式预训练转换器”使用了来自 OpenAI 的一个新的即插即用 API。下面是我的帖子中关于 NLP 和变形金刚的摘录( AI &仲裁真相——貌似每周都需要重温)。
科技—变形金刚& NLP
自然语言处理(NLP)是机器学习的子领域,涉及从文本中处理和提取信息。 用在智能助手、翻译器、搜索引擎、网店等等。 *NLP(以及计算机视觉)是少数货币化的最先进的机器学习发展之一。*是被用来诠释真理的候选人。
迄今为止最好的 NLP 工具是一个叫做 的神经网络架构,变压器 。长话短说,变形金刚使用一种 编码器和解码器结构 ,将单词编码到潜在空间,并解码为翻译、打字错误修复或分类(你可以认为编码器-解码器是通过神经网络将复杂的特征空间压缩到更简单的空间——非线性函数逼近)。NLP 领域的一个关键工具是一种叫做 注意力 的东西,它学习关注哪些单词以及关注多长时间(而不是硬编码到一个工程系统中)。
一个transformer结合了这些工具,以及一些其他的改进,允许模型被高效地并行训练。下图显示了数据如何流经转换器。
一个可视化来自一个 牛逼教程 我找到的。
为什么它很重要
这是我看到的第一个应用程序,人们可以用它来代替工程时间。前端设计人员可以借助这款工具大幅提高工作速度。这可能会被出售给许多现有的公司,新的企业将在未来使用它来创造有价值的服务。找到最好的应用程序需要一个有创造力的人,当然受到我们人类设计师的限制,很快就会被下一个最先进的模型所取代。
这是令人瞩目的,因为 OpenAI 著名的宪章。简而言之——我们将朝着 AGI 前进,如果另一家公司想抢先一步, 我们将加入他们的 。该产品背后的说法是,这些资金将帮助他们执行人工智能研究,但他们的领导层过去曾撤回模型,因为担心它们“太危险,无法分享”。这种 AI 危险的细线只会越来越尖锐。
书呆子角落:这个模型的训练量是 50[PETA](https://en.wikipedia.org/wiki/Peta-#:~:text=Peta%20(%2F%CB%88p%C9%9Bt,%CF%80%CE%AD%CE%BD%CF%84%CE%B5%2C%20meaning%20%22five%22.)翻牌/秒-天(这到底是什么意思?)仅培训费用就超过 1200 万美元[ 来源 ]。这是从费用中收回的一点成本。我喜欢思考这个模型如何与我用于回归任务的浅层神经网络相比较— 它的参数数量超过 1 亿倍。这是一个完全不同的函数逼近体系。对于书呆子来说,学术论文在这里是。
机器人和生成文本
我请求进入机器人研究的测试版。我有兴趣看看一个语言模型(大神经网络)的规划能达到什么水平,以游戏的形式给定上下文。 语言是否抓住了游戏中的基本意图和解决方案的结构?
从长远来看,我认为将语言整合到机器人奖励中是令人感兴趣的——它将允许与机器人一起工作的人类给机器下达口头任务(验证所述任务是另一个问题)。
示例:
- 给定一个游戏板的嵌入(书写、网格、其他方法),说“我应该移动到哪里。”
- 给出一个环境描述:“积木在椅子右边的球上,”问“球在椅子上面吗?”
这是一个非常初级的例子,但我认为来自商业化机器学习领域的链接,如视觉和语言的深度学习,是很有潜力的。
一个关于机器人和人工智能的博客,让它们对每个人都有益,以及即将到来的自动化浪潮…
robotic.substack.com](https://robotic.substack.com/)
与 Jenkins 一起自动化数据科学项目
了解如何使用 Jenkins 自动化数据科学代码
让我们描绘一个场景,您正在进行一个数据科学项目,起初,您有一个 80%的模型准确性,您使用 Flask 将该应用程序作为 API 部署到生产中。然后几天后,你决定继续这个项目,在调整了一些参数并增加了一些数据后,你有了比之前建立的模型更好的精确度。现在,您计划部署该模型,您必须经历构建、测试和再次将该模型部署到生产环境的麻烦,这是一项繁重的工作。在本文中,我将向您展示我们如何使用一个名为 Jenkins 的强大工具来自动化这个过程。
詹金斯是什么?
Jenkins 是一个免费的开源自动化服务器。它帮助自动化与构建、测试和部署相关的软件开发部分,促进持续集成和持续交付——维基百科
借助 Jenkins,您可以使用大量插件,在整个生命周期中自动化并加速软件交付过程。例如,您可以设置 Jenkins 自动检测存储库中的代码提交,并自动触发命令,从 Docker 文件构建 Docker 映像、运行单元测试、将映像推送到容器注册表或将其部署到生产服务器,而无需手动执行任何操作。我将解释一些我们需要知道的基本概念,以便在我们的数据科学项目中执行一些自动化。
詹金斯的优势
- 它是开源的
- 易于使用和安装
- 大量适合 DevOps 环境的插件
- 在代码上花更多时间,在部署上花更少时间
- 大型社区
詹金斯装置
Jenkins 支持跨平台安装,无论您是 Windows、Linux 还是 Mac 用户。您甚至可以将它安装在支持 PowerShell 或 Linux 实例的云服务器上。要安装 Jenkins,可以参考文档这里。
Jenkins 有很多惊人的特性,有些超出了本文的范围,要掌握 Jenkins 的窍门,你可以查看文档。
在我们开始实际操作之前,我想解释一些非常重要的术语,其中包括:
詹金斯工作
Jenkins 作业只是指由 Jenkins 控制的可运行任务。例如,你可以分配一个任务给 Jenkins 来执行一些特定的操作,比如运行“Hello World”,执行单元和集成测试等等。在 Jenkins 中创建工作非常容易,但是在软件环境中,你可能不会创建一个单独的工作,相反,你会做被称为管道的事情。
詹金斯管道
管道按照特定的顺序运行一组作业,让我用一个例子来解释。假设我正在 Jenkins 上开发一个应用程序,我想从代码库中提取代码,构建应用程序,测试并将其部署到服务器上。为此,我将创建四个作业来执行每个进程。因此,第一个作业(作业 1)将从存储库中提取代码,第二个作业(作业 2)将构建应用程序,第三个作业(作业 3)将执行单元和集成测试,第四个作业(作业 4)将代码部署到生产环境中。我可以使用 Jenkins 构建管道插件来执行这项任务。在创建作业并将它们按顺序链接起来之后,构建插件会将这些作业作为一个管道来运行。
詹金斯管道的类型:
- 声明性管道:这是一个支持管道作为代码概念的特性。它使管道代码更容易阅读和编写。这段代码写在一个 Jenkinsfile 中,它可以被签入一个源代码控制管理系统,比如 Git。
- 脚本管道:这是编写代码的老方法之一。使用这种方法,管道代码被写在 Jenkins 用户界面实例上,而不是写在文件中。尽管这两个管道执行相同的功能,并且使用相同的脚本语言(Groovy)。
在讨论了主要概念之后,让我们构建一个简单的迷你项目,并使用 Jenkins 实现自动化。
这个项目包含一个经过训练的机器学习模型,它可以检测来自 twitter 的与自杀相关的情绪,我使用 flask 将它部署为一个 API。我构建了我的 Jenkins 管道:
提交时从存储库中提取更改>>>构建 Docker 映像>>>将构建的映像推送到 DockerHub > > >删除未使用的 Docker 映像。
步伐
启动一个 Jenkins 服务器,安装 Git、Docker、Pipeline 和 build 插件,并在实例中安装 Git 和 Docker。对于本文,我在 AWS EC2 实例上使用了 Jenkins。
将代码推送到存储库,在本文中我使用了 Github。你可以在这里找到这篇文章的代码。
我的工作目录:
.
├── app.py
├── CustomCode
│ └── data_preprocessing.py
├── Dockerfile
├── Jenkinsfile
├── ML_model
│ └── model.pkl
└── requirements.txt
然后,我们需要告诉 Jenkins,每当代码库中发生更改时,就开始构建管道。为此,您需要将 Jenkins webhook 添加到 Github 存储库中,以便 GitHub 在代码发生变化时与 Jenkins 进行通信。为此:
点击代码库中的设置
然后导航到 webhooks,点击添加 Webhook
然后使用你的 Jenkins 服务器的公共 DNS 或公共 IP 并在末尾添加“/github-web hook/”,然后选择 application/json 作为内容类型。在“您希望哪个事件触发此网页挂钩?”,选择单个事件并选择仅推并点击添加 webhook。
现在,前往 Jenkins 并点击新项目
输入项目名称,选择管道,点击确定
从 General 向下滚动到 Build Triggers 并选择Github hook trigger for git SCM polling。它的简单作用是,每当代码中有提交时,帮助我们构建管道
然后滚动到管道,并在定义中从下拉列表中选择来自 SCM 的管道脚本。在 SCM(源代码管理)中,选择 Git 并输入存储库 URL,如果您的存储库是私有的,您需要使用您的用户名和密码创建一个凭证。在分支说明符中,您可以选择 master 或者您的代码存储库所在的任何分支,脚本路径选择 Jenkinsfile,Jenkins file 是我为项目编写管道的地方。然后选择保存。
现在让我们建立管道…
它贯穿了所有的阶段,构建是成功的
如果你查看你的 Docker Hub 库,你会在那里找到 Docker 图片。
现在让我们在代码库中做一点小小的改变
现在,如果你回到 Jenkins,你会看到它已经检测到已经做出的更改,并自动触发另一个构建。
这就是如何使用 Jenkins 来自动化这三个过程。
感谢阅读😃
深度 Q 学习的自动化毁灭:Tensorflow 中的一个实现。
强化学习的基础
介绍
在线学习方法是一个动态的强化学习算法家族,它是过去十年来人工智能领域许多成就的背后。在线学习方法属于基于样本的学习类强化学习方法,允许简单地通过重复观察来确定状态值,消除了对转换动态的需要。与它们的离线对应方式,不同,在线学习方法允许在环境事件期间对状态和动作的值进行增量更新,允许观察到持续的、增量的性能改进。
除了时间差异学习(TD ),我们还讨论了 Q-learning 的理论和实际实现,这是 TD 的一种发展,旨在允许增量估计和状态-动作值的改进。Q-learning 因成为模拟游戏环境的强化学习方法的支柱而闻名,如在 OpenAI 的健身房中观察到的那些。因为我们已经在过去的文章中涉及了 Q-learning 的理论方面,所以这里不再重复。
在线学习方法(如 TD)的快速情景内响应能力使其适用于高度动态的环境,在这种环境中,状态和动作的值通过多组估计值不断更新。也许最值得注意的是, **TD 是 Q-learning 的基础,**这是一种更先进的算法,用于训练代理处理游戏环境,如在 OpenAI Atari 健身房中观察到的环境,正如我们之前的实现中的一些所涵盖的。
在本文中,我们将探索如何通过使用开源的 OpenAI gym 包装库 Vizdoomgym ,将 Q-learning 应用于训练代理玩经典 FPS 游戏 Doom 。我们将指导您设置您的第一个代理,并为未来的工作奠定基础。
永恒经典的演变。我们将在这里关注 1993 年的版本。
超越 TD: SARSA & Q-learning
回想一下,在时间差异学习中,我们观察到一个主体在一个环境中通过一系列状态(S)、动作(A)和(奖励)循环地行为。
在 TD 期间,我们可以在到达下一个状态时更新前一个状态的值。我们可以进一步扩展我们的模型的范围,以包括状态-动作值,在一种称为 SARSA 的方法中,一种用于估计动作值的基于策略的 TD 控制算法。在 SARSA 期间,我们在给定的策略下连续地估计跨增量时间步长的动作值,同时使用这种知识来修改策略,使其趋向于动作值贪婪的替代方案。
让我们比较状态-动作和状态-值 TD 更新方程:
Q-learning 不同于 SARSA,它在更新期间强制选择具有当前最高动作值的动作,这与使用贝尔曼优化方程观察到的情况类似。我们可以检查贝尔曼和贝尔曼优化方程旁边的 SARSA 和 Q-learning,如下所示:
你可能想知道如何确保我们的状态-动作空间的完整探索,给定需要不断地为具有最高现有动作值的状态选择动作。从理论上讲,我们可能只是因为一开始就没有评估而避免了最佳行动。**为了鼓励探索,我们可以使用一个衰减的 e-greedy 策略,**本质上迫使代理以衰减的概率选择一个明显的次优行为,以便了解更多关于其价值的信息。通过使用衰减值,我们可以在评估完所有状态后限制探索,之后我们将为每个状态永久选择最佳操作。
有了我们的理论,让我们开始我们的实现。
履行
我们的 Google 协作实现是利用 Tensorflow Core 用 Python 编写的,可以在 GradientCrescent Github 上找到。关注我们出版物的读者会发现代码与我们之前在雅达利T4 环境中的实现相似。由于这种方法的实现非常复杂,让我们用总结一下所需动作的顺序:
1.我们定义我们的深度 Q 学习神经网络。这是一个 CNN,它拍摄游戏中的屏幕图像,并输出 Ms-Pacman gamespace 中每个动作的概率,或 Q 值。为了获得概率张量,我们在最后一层不包括任何激活函数。
2.由于 Q-learning 要求我们了解当前和下一个状态,我们需要从数据生成开始。我们将表示初始状态 s 的游戏空间的预处理输入图像输入到网络中,并获取动作的初始概率分布,或 Q 值。在训练之前,这些值将是随机的和次优的。
3.利用我们的概率张量,我们然后使用 argmax()函数选择具有当前最高概率的动作,并使用它来构建ε贪婪策略。
4.使用我们的策略,我们将选择动作 a ,并评估我们在健身房环境中的决定接收关于新状态s’、奖励 r 以及该集是否已结束的信息。
5.我们以列表形式将该信息组合存储在一个缓冲区中,并重复步骤 2-4 预设次数,以建立一个足够大的缓冲区数据集。
6.一旦步骤 5 完成,我们转到生成我们的目标y-值R’和A’,这是损失计算所需的。虽然前者只是从 R 中减去,但是我们通过将*S’*输入到我们的网络中来获得 A’。
7.有了所有的组件,我们就可以计算训练网络的损耗。
8.一旦训练结束,我们将评估我们的代理在新一集游戏中的表现,并记录表现。
让我们开始吧。随着 Tensorflow 2 在实验室环境中的使用,我们已经使用新的 compat 包将我们的代码转换为符合 TF2 标准。注意,这段代码不是 TF2 本地的。
让我们通过导入所有必需的包,包括 OpenAI 和 Vizdoomgym 环境以及 Tensorflow 核心:
import gym
import vizdoomgym
!pip install tensorflow==1.15
import numpy as np
import tensorflow as tf
from tensorflow.contrib.layers import flatten, conv2d, fully_connected
from collections import deque, Counter
import random
from datetime import datetime
接下来,我们定义一个预处理函数,对健身房环境中的观察结果进行标准化和调整大小,并将它们转换成一维张量。
from skimage.color import rgb2gray
from skimage import transform#prepro (240, 320, 3) uint8 frame into 30x40 1D float vector
color = np.array([240, 320, 74]).mean()
def preprocess_observation(obs):
img =obs/255.0
img[img==color] = 0 img_gray = rgb2gray(img)
preprocessed_frame = transform.resize(img_gray, [60,80])
return preprocessed_frame
接下来,让我们初始化健身房环境。我们将使用 Vizdoomgym 的健康收集场景,其中的目标是收集尽可能多的健康令牌,以便在通过一个具有破坏性酸性地板的方形房间时保持活着。
env = gym.make(‘VizdoomHealthGathering-v0’)
n_outputs = env.action_space.n
print(n_outputs)observation = env.reset()import tensorflow as tf
import matplotlib.pyplot as pltfor i in range(22):
if i > 20:
print(observation.shape)
plt.imshow(observation)
plt.show()observation, _, _, _ = env.step(1)
我们可以查看游戏画面,也可以查看游戏空间中的 3 个可用动作,即左转、右转或前进。当然,我们的代理人无法获得这些信息。
原始观察输入
我们可以借此机会比较我们的原始和预处理输入图像:
预处理图像输入
接下来,我们将输入帧堆叠和帧合成引入我们的预处理流水线,这是 Deepmind 在 2015 年推出的两项技术。这些方法分别为我们的输入提供时间和运动参考。
我们通过获取两个输入帧来应用帧合成,并返回这两个帧的元素式最大总和 maxframe 。然后,这些合成的帧被存储在一个队列或“堆栈”中,当引入新的条目时,它会自动删除旧的条目。
stack_size = 4 # We stack 4 composite frames in total stacked_frames = deque([np.zeros((60,80), dtype=np.int) for i in range(stack_size)], maxlen=4)def stack_frames(stacked_frames, state, is_new_episode):
# Preprocess frame
frame = preprocess_observation(state)
if is_new_episode:
# Clear our stacked_frames
stacked_frames = deque([np.zeros((60,80), dtype=np.int) for i in range(stack_size)], maxlen=4)
# Because we’re in a new episode, copy the same frame 4x, apply elementwise maxima
maxframe = np.maximum(frame,frame)
stacked_frames.append(maxframe)
stacked_frames.append(maxframe)
stacked_frames.append(maxframe)
stacked_frames.append(maxframe)
# Stack the frames
stacked_state = np.stack(stacked_frames, axis=2)
else:
#Since deque append adds t right, we can fetch rightmost element
maxframe=np.maximum(stacked_frames[-1],frame)
# Append frame to deque, automatically removes the oldest frame
stacked_frames.append(maxframe) # Build the stacked state (first dimension specifies different frames)
stacked_state = np.stack(stacked_frames, axis=2)
return stacked_state, stacked_frames
接下来,让我们定义我们的模型,一个深度 Q 网络。这基本上是一个三层卷积网络,它采用预处理的输入观察值,将生成的展平输出馈送到一个全连接层,生成将游戏空间中的每个动作作为输出的概率。请注意,这里没有激活层,因为激活层的存在会导致二进制输出分布。
tf.compat.v1.reset_default_graph() def q_network(X, name_scope):
# Initialize layers
initializer = tf.compat.v1.keras.initializers.VarianceScaling(scale=2.0) with tf.compat.v1.variable_scope(name_scope) as scope: # initialize the convolutional layers
layer_1 = conv2d(X, num_outputs=32, kernel_size=(8,8), stride=4, padding=’SAME’, weights_initializer=initializer)
tf.compat.v1.summary.histogram(‘layer_1’,layer_1)
layer_2 = conv2d(layer_1, num_outputs=64, kernel_size=(4,4), stride=2, padding=’SAME’, weights_initializer=initializer)
tf.compat.v1.summary.histogram(‘layer_2’,layer_2)
layer_3 = conv2d(layer_2, num_outputs=64, kernel_size=(3,3), stride=1, padding=’SAME’, weights_initializer=initializer)
tf.compat.v1.summary.histogram(‘layer_3’,layer_3)
# Flatten the result of layer_3 before feeding to the fully connected layer
flat = flatten(layer_3)
# Insert fully connected layer
fc = fully_connected(flat, num_outputs=128, weights_initializer=initializer)
tf.compat.v1.summary.histogram(‘fc’,fc)
#Add final output layer
output = fully_connected(fc, num_outputs=n_outputs, activation_fn=None, weights_initializer=initializer)
tf.compat.v1.summary.histogram(‘output’,output) # Vars will store the parameters of the network such as weights
vars = {v.name[len(scope.name):]: v for v in tf.compat.v1.get_collection(key=tf.compat.v1.GraphKeys.TRAINABLE_VARIABLES, scope=scope.name)}
#Return both variables and outputs together
return vars, output
让我们也借此机会为我们的模型和训练过程定义超参数。注意,由于我们的堆叠帧,X_shape 现在是*(无,60,80,4)* 。
num_episodes = 1000
batch_size = 48input_shape = (None, 60, 80, 1)learning_rate = 0.002
#Modified for composite stacked frames
X_shape = (None, 60, 80, 4)
discount_factor = 0.99global_step = 0
copy_steps = 100
steps_train = 4
start_steps = 2000
回想一下,Q-learning 要求我们选择具有最高行动价值的行动。为了确保我们仍然访问每一个可能的状态-行为组合,我们将让我们的代理遵循一个衰减的ε-贪婪策略,探索率为 5%。
epsilon = 0.5
eps_min = 0.05
eps_max = 1.0
eps_decay_steps = 500000def epsilon_greedy(action, step):
p = np.random.random(1).squeeze() #1D entries returned using squeeze
epsilon = max(eps_min, eps_max — (eps_max-eps_min) * step/eps_decay_steps) #Decaying policy with more steps
if p< epsilon:
return np.random.randint(n_outputs)
else:
return action
回想上面的等式,Q-learning 的更新函数要求如下:
- 当前状态 s
- 当前动作一个
- 当前动作后的奖励 r
- 下一个状态s’
- 下一个动作a’
为了以有意义的数量提供这些参数,我们需要按照一组参数评估我们当前的策略,并将所有变量存储在一个缓冲区中,我们将在训练期间从该缓冲区中提取迷你批次中的数据。让我们继续创建我们的缓冲区和一个简单的采样函数:
buffer_len = 20000
exp_buffer = deque(maxlen=buffer_len)def sample_memories(batch_size):
perm_batch = np.random.permutation(len(exp_buffer))[:batch_size]
mem = np.array(exp_buffer)[perm_batch]
return mem[:,0], mem[:,1], mem[:,2], mem[:,3], mem[:,4]
接下来,让我们将原始网络的权重参数复制到目标网络中。这种双网络方法允许我们在使用现有策略的训练过程中生成数据,同时仍然为下一个策略迭代优化我们的参数,减少损失振荡。
# we build our Q network, which takes the input X and generates Q values for all the actions in the state
mainQ, mainQ_outputs = q_network(X, ‘mainQ’)# similarly we build our target Q network, for policy evaluation
targetQ, targetQ_outputs = q_network(X, ‘targetQ’)copy_op = [tf.compat.v1.assign(main_name, targetQ[var_name]) for var_name, main_name in mainQ.items()]
copy_target_to_main = tf.group(*copy_op)
最后,我们还将定义我们的损失。这就是我们的目标动作(具有最高动作值)和我们的预测动作的平方差。我们将使用 ADAM 优化器来最大限度地减少我们在训练中的损失。
# define a placeholder for our output i.e action
y = tf.compat.v1.placeholder(tf.float32, shape=(None,1))# now we calculate the loss which is the difference between actual value and predicted value
loss = tf.reduce_mean(input_tensor=tf.square(y — Q_action))# we use adam optimizer for minimizing the loss
optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate)
training_op = optimizer.minimize(loss)init = tf.compat.v1.global_variables_initializer()
loss_summary = tf.compat.v1.summary.scalar(‘LOSS’, loss)
merge_summary = tf.compat.v1.summary.merge_all()
file_writer = tf.compat.v1.summary.FileWriter(logdir, tf.compat.v1.get_default_graph())
定义好所有代码后,让我们运行我们的网络并检查培训过程。我们已经在最初的总结中定义了大部分,但是让我们为后代回忆一下。
- 对于每个时期,在使用ε-贪婪策略选择下一个动作之前,我们将输入图像堆栈输入到我们的网络中,以生成可用动作的概率分布
- 然后,我们将它输入到网络中,获取下一个状态和相应奖励的信息,并将其存储到我们的缓冲区中。我们更新我们的堆栈,并通过一些预定义的步骤重复这一过程。
- 在我们的缓冲区足够大之后,我们将下一个状态输入到我们的网络中,以便获得下一个动作。我们还通过贴现当前的奖励来计算下一个奖励
- 我们通过 Q 学习更新函数生成我们的目标 y 值,并训练我们的网络。
- 通过最小化训练损失,我们更新网络权重参数,以便为下一个策略输出改进的状态-动作值。
with tf.compat.v1.Session() as sess:
init.run()
# for each episode
history = []
for i in range(num_episodes):
done = False
obs = env.reset()
epoch = 0
episodic_reward = 0
actions_counter = Counter()
episodic_loss = []
# First step, preprocess + initialize stack
obs,stacked_frames= stack_frames(stacked_frames,obs,True) # while the state is not the terminal state
while not done:
#Data generation using the untrained network
# feed the game screen and get the Q values for each action
actions = mainQ_outputs.eval(feed_dict={X:[obs], in_training_mode:False})
# get the action
action = np.argmax(actions, axis=-1)
actions_counter[str(action)] += 1
# select the action using epsilon greedy policy
action = epsilon_greedy(action, global_step)
# now perform the action and move to the next state, next_obs, receive reward
next_obs, reward, done, _ = env.step(action)
#Updated stacked frames with new episode
next_obs, stacked_frames = stack_frames(stacked_frames, next_obs, False)
# Store this transition as an experience in the replay buffer!
exp_buffer.append([obs, action, next_obs, reward, done]) # After certain steps, we train our Q network with samples from the experience replay buffer
if global_step % steps_train == 0 and global_step > start_steps:
o_obs, o_act, o_next_obs, o_rew, o_done = sample_memories(batch_size)
# states
o_obs = [x for x in o_obs]
# next states
o_next_obs = [x for x in o_next_obs]
# next actions
next_act = mainQ_outputs.eval(feed_dict={X:o_next_obs, in_training_mode:False})
# discounted reward: these are our Y-values
y_batch = o_rew + discount_factor * np.max(next_act, axis=-1) * (1-o_done) # merge all summaries and write to the file
mrg_summary = merge_summary.eval(feed_dict={X:o_obs, y:np.expand_dims(y_batch, axis=-1), X_action:o_act, in_training_mode:False})
file_writer.add_summary(mrg_summary, global_step)
# To calculate the loss, we run the previously defined functions mentioned while feeding inputs
train_loss, _ = sess.run([loss, training_op], feed_dict={X:o_obs, y:np.expand_dims(y_batch, axis=-1), X_action:o_act, in_training_mode:True})
episodic_loss.append(train_loss) # after some interval we copy our main Q network weights to target Q network
if (global_step+1) % copy_steps == 0 and global_step > start_steps:
copy_target_to_main.run() obs = next_obs
epoch += 1
global_step += 1
episodic_reward += reward
next_obs=np.zeros(obs.shape)
exp_buffer.append([obs, action, next_obs, reward, done])
obs= env.reset()
obs,stacked_frames= stack_frames(stacked_frames,obs,True)
history.append(episodic_reward)
print(‘Epochs per episode:’, epoch, ‘Episode Reward:’, episodic_reward,”Episode number:”, len(history))
一旦训练完成,我们就可以根据增量情节绘制奖励分布图。前 1000 集如下所示:
这一结果是可以接受的,改善的开始是可见的,考虑到最初的 Vizdoom 论文表明,要观察到更显著的改善,需要成千上万的情节。
img_array=[]
with tf.compat.v1.Session() as sess:
init.run()
observation, stacked_frames = stack_frames(stacked_frames, observation, True)
while True:# feed the game screen and get the Q values for each action
actions = mainQ_outputs.eval(feed_dict={X:[observation], in_training_mode:False})# get the action
action = np.argmax(actions, axis=-1)
actions_counter[str(action)] += 1# select the action using epsilon greedy policy
action = epsilon_greedy(action, global_step)
environment.render()
new_observation, stacked_frames = stack_frames(stacked_frames, new_observation, False)
observation = new_observation
# now perform the action and move to the next state, next_obs, receive reward
new_observation, reward, done, _ = environment.step(action)
img_array.append(new_observation)
if done:
#observation = env.reset()
break
environment.close()
最后,我们可以将我们的帧列表提供给 scikit-video 库,以生成视频序列输出供检查:
from random import choice
import cv2
from google.colab.patches import cv2_imshowimport numpy as np
import skvideo.ioout_video = np.empty([len(img_array), 240, 320, 3], dtype = np.uint8)
out_video = out_video.astype(np.uint8)for i in range(len(img_array)):
frame = img_array[i]
out_video[i] = frame
# Writes the the output image sequences in a video file
skvideo.io.vwrite(“/content/doom.mp4”, out_video)
让我们来看看我们的代理是如何工作的!
请注意代理在发现健康包时如何暂停,然后再继续向其移动。只是为了好玩,我们还为的基本场景训练了一个代理,目标是尽快击中怪物。而我们则取得了 ca 的最好成绩。1.3 秒,我们将在下面展示更早的一集。
这就结束了 Q-learning 的实现。在我们的下一篇文章中,我们将继续用更先进的 Q 学习方法处理更复杂的厄运场景,并将我们的代码切换到 Pytorch,这是人工智能研究中最流行的语言之一。
我们希望你喜欢这篇文章,并希望你查看 GradientCrescent 上的许多其他文章,涵盖人工智能的应用和理论方面。为了保持对 GradientCrescent 的最新更新,请考虑关注该出版物并关注我们的 Github 资源库。
参考文献
萨顿等人。强化学习
怀特等人。阿尔伯塔大学强化学习基础
席尔瓦等人。阿尔,强化学习,UCL
马卡洛夫等人。al,使用 VizDoom 第一人称射击游戏进行深度强化学习,HSE
肯普卡等人。al,ViZDoom:一个基于 Doom 的人工智能研究平台,用于视觉强化学习,PUT
Ravichandiran 等人。al,用 Python 实践强化学习
使用 AWS Lambda 自动化 ETL
使用 AWS Lambda 打包和部署无服务器 ETL 管道
哈桑·阿尔马西在 Unsplash 上的照片
介绍
我们周围的世界变化比以往任何时候都快。我们每天产生的数据量确实令人难以置信。每天会产生 2.5 万亿字节的数据,这意味着我们今天使用的数据明天可能就不再适用了。因此,我们需要一种方法来完全自动化我们的数据流流程,好消息是您不必担心需要昂贵的服务器和硬件来实现这一点,AWS 让您可以通过高性能和可扩展性的额外优势来实现这一点。
在本文中,我们将只使用 AWS 免费层产品。所以你可以跟着去。在我们开始这个过程之前,我们需要了解我们将要使用的 3 个 AWS 服务 EC2、AWS Lambda 和 Cloudwatch。
EC2
亚马逊弹性计算云 (EC2)是一项让你租用虚拟机的服务。我们可以用我们想要的任何配置(操作系统、存储等)启动一个虚拟机。)任何我们想要的时间。
λ
AWS Lambda 是一种无服务器计算服务,它运行我们的代码来响应事件,并自动为我们管理底层计算资源。我们可以使用 AWS Lambda 通过定制逻辑扩展其他 AWS 服务,或者创建我们的后端服务。 AWS Lambda 可以自动运行代码来响应多个事件,例如通过 Amazon API Gateway 的 HTTP 请求、对 Amazon S3 桶中对象的修改、Amazon DynamoDB 中的表更新。在我们的例子中,它将根据时间表运行代码。
云观察
顾名思义, CloudWatch 以日志、指标和事件的形式收集监控和运营数据,为我们提供运行在 AWS 和本地服务器上的 AWS 资源、应用程序和服务的统一视图。我们可以使用 CloudWatch 来检测我们环境中的异常行为,设置警报,并排显示日志和指标,采取自动操作,解决问题,并发现洞察力以保持我们的应用程序平稳运行。
AWS lambda 是我们进行编程以执行 ETL 的平台,但 AWS lambda 不包括大多数日常使用的包/库(Pandas,Requests ),标准的 pip install pandas 在 AWS Lambda 中无法工作。所以需要在本地或者 EC2 虚拟机上安装包/库,把它作为 zip 文件上传到 S3并作为层**附加到 Lambda 函数。**
这是我所说的工作流程的一个例子,
工作流程
创建并启动一个具有 S3 访问角色的 EC2 Linux 实例
登录 AWS 控制台。在服务下,选择 EC2,然后启动实例:
选择启动实例
第一步:为我们的 EC2 实例选择操作系统,我选择了Ubuntu Server 18.04 LTS(HVM),但是你也可以选择**Amazon Linux 2 AMI(HVM)或者任何你喜欢的环境。**
选择 Ubuntu Server 18.04 LTS (HVM)
第二步:选择一个实例类型,选择 t2.micro(它包含在免费层中,我们每个月最多可以获得 750 小时的微实例)。
****步骤 3:配置实例细节,除了 IAM 角色之外,其他都保留默认值。使用 S3 访问权限创建新角色。选择“创建新的 IAM 角色”。
创建新的 IAM 角色
我们将被重定向到“IAM 角色”页面,在这里我们可以选择创建角色,然后选择 EC2
选择创建角色
选择 EC2
附加“AmazonS3FullAccess”策略来读写 S3 存储桶,并为角色命名。点击创建角色。
附加 S3FullAccess 策略,以便我们拥有对 S3 的读写权限
给出角色名称
返回到“启动实例”页面,点击“IAM 角色”旁边的“刷新”,选择我们刚刚创建的角色,然后点击“查看并启动”。如果需要,我们还可以设置存储、标记和配置安全组,但目前,默认设置是好的。
选择 IAM 角色
****我们将转到步骤 7:查看实例启动-点击启动。系统将提示我们创建或选择一个密钥对。选择 create a new pair 并给它一个名字,下载密钥对,并点击 launch instance。
创建新的密钥对并启动实例
创建实例后,选择 view instance。然后选择我们刚刚创建的实例并点击 connect。
选择实例并点击连接
复制“示例”代码,并在计算机上的命令提示符下连接到实例。
复制示例代码并将其粘贴到命令提示符下
如示例所示粘贴 ssh 命令,更改密钥(my_key.pem)的路径,然后按 enter 键。一旦我们连接到我们的命令提示符,它应该看起来像这样。
命令提示符
在虚拟环境中安装我们需要的所有依赖项(库),将依赖项打包成一个 zip 文件,并将其导出到 S3
安装、打包和导出依赖项
按照上面的代码,我们已经成功地将打包的 zip 文件导出到一个 S3 桶中。
创建并添加 Lambda 图层
选择 AWS 控制台左上角的服务,导航到 AWS lambda,然后导航到 层。 选择创建图层。******
选择创建层
复制我们上传到 S3 桶的 zip 文件的对象 URL ,并将其粘贴到“亚马逊 S3 链接 URL”文本框中。点击创建。
复制对象 URL
粘贴 S3 链接,选择兼容运行时
选择添加层,并选择我们创建的层和版本。点击添加。
添加层
选择你刚刚在最后一步创建的层,点击添加
创建 Lambda 函数
在 AWS lambda 控制台上,选择函数,然后点击创建函数。给函数起一个名字,并选择用来编写函数的语言。点击创建。
创建函数
给出函数名并选择运行时
更新 Lambda 函数来提取、转换和加载数据。在这里,我使用熊猫读取 CSV 文件,并将其存储在 S3 桶中。这是我们可以执行转换并决定将数据加载到哪里的地方,在我们的例子中,它是一个 S3 存储桶。
λ处理器
选择 test,为测试事件输入一个名称,其余的保持默认。点击保存。再次点击 test,代码执行我们的 ETL 过程。
选择屏幕右上角的测试,并添加测试名称
给测试事件起一个名字,剩下的保持默认
最后一步:计划你的 ETL 过程
选择 AWS 控制台左上角的服务,导航到 CloudWatch,然后依次导航到事件和规则。选择创建规则。
服务-云观察-事件-规则-创建规则
*步骤 1:选择 schedule 后跟 Cron 表达式,输入 Cron 表达式(4 * ? )在每天 4:00 GMT 运行 Lambda 函数。
点击了解更多关于 Cron 的表情。
第 2 步:输入名称和描述。选择创建规则。
创建规则
给规则命名和描述
恭喜👏!!我们的 ETL 过程是自动化的,将每 24 小时在格林威治时间 4:00 更新一次。
PS:确保终止 EC2 以及任何弹性块存储(EBS ),这样您就不会超出自由层的使用范围。
祝您的无服务器之旅好运!我希望这篇文章是有帮助的,如果你有任何问题,请随时联系我。
**** [## Ashwin Muthiah Murugappan -市场监督后数据分析师
我是一名充满热情的工业工程研究生,拥有学习先进技术的巨大潜力
www.linkedin.com](https://www.linkedin.com/in/ashwinmuthiah/)****
自动化 Python 项目的各个方面
每个 Python 项目都可以从使用 Makefile、优化的 Docker 映像、配置良好的 CI/CD、代码质量工具等自动化中受益…
每个项目——不管你是在做 web 应用、一些数据科学还是人工智能——都可以受益于配置良好的 CI/CD、Docker 映像,它们既可以在开发中调试,又可以针对生产环境进行优化,或者受益于一些额外的代码质量工具,如 CodeClimate 或 SonarCloud 。所有这些都是我们将在本文中讨论的内容,我们将看到如何将它们添加到您的 Python 项目中!
这是上一篇关于创建 【终极】Python 项目设置 的文章的后续,所以在阅读本文之前,您可能需要检查一下。
TL;DR:这是我的储存库,里面有完整的源代码和文档:https://github.com/MartinHeinz/python-project-blueprint
用于开发的可调试 Docker 容器
有些人不喜欢 Docker,因为容器可能很难调试,或者因为它们的映像需要很长时间来构建。因此,让我们从这里开始,构建开发的理想映像——构建速度快且易于调试。
为了使映像易于调试,我们将需要基本映像,它包括所有我们调试时可能需要的工具——比如bash
、vim
、netcat
、wget
、cat
、find
、grep
等。似乎是这项任务的理想人选。默认情况下,它包括许多工具,我们可以很容易地安装所有缺少的东西。这个基础图像很厚,但这并不重要,因为它将只用于开发。你可能也注意到了,我选择了非常特殊的镜像锁定 Python 和 Debian 的两个版本——这是有意的,因为我们想最小化由 Python 或 Debian 的更新的、可能不兼容的版本引起的*“破损”*的可能性。
作为替代方案,您可以使用基于阿尔卑斯山的图像。然而,这可能会导致一些问题,因为它使用了musl libc
而不是 Python 所依赖的glibc
。所以,只要记住这一点,如果决定选择这条路线。
至于构建的速度,我们将利用多阶段构建来允许我们缓存尽可能多的层。这样我们可以避免下载依赖项和工具,如gcc
,以及我们的应用程序所需的所有库(从requirements.txt
)。
为了进一步加快速度,我们将从前面提到的python:3.8.1-buster
创建自定义基础映像,这将包括我们需要的所有工具,因为我们无法缓存下载和安装这些工具到最终转轮映像所需的步骤。
说够了,让我们看看Dockerfile
:
上面你可以看到,在创建最终的流道图像之前,我们将通过 3 个中间图像。其中第一个被命名为builder
。它下载了构建最终应用程序所需的所有必要库,包括gcc
和 Python 虚拟环境。安装后,它还创建实际的虚拟环境,然后由下一个映像使用。
接下来是builder-venv
映像,它将我们的依赖项列表(requirements.txt
)复制到映像中,然后安装它。缓存需要这个中间映像,因为我们只希望在requirements.txt
改变时安装库,否则我们就使用缓存。
在创建最终图像之前,我们首先要对我们的应用程序进行测试。这就是在tester
图像中发生的情况。我们将源代码复制到映像中并运行测试。如果他们通过,我们将继续进行runner
。
对于跑步者图像,我们使用自定义图像,包括一些普通 Debian 图像中没有的额外图像,如vim
或netcat
。你可以在 Docker Hub 这里找到这张图片,你也可以在base.Dockerfile
这里查看非常简单的Dockerfile
。因此,我们在这个最终映像中要做的是——首先,我们从tester
映像中复制包含所有已安装依赖项的虚拟环境,接下来,我们复制已测试的应用程序。现在我们已经有了映像中的所有源代码,我们移动到应用程序所在的目录,然后设置ENTRYPOINT
以便它在映像启动时运行我们的应用程序。出于安全原因,我们还将USER
设置为 1001 ,因为最佳实践告诉我们永远不要在root
用户下运行容器。最后两行设置图像的标签。当使用make
目标运行构建时,这些将被替换/填充,稍后我们将看到。
用于生产的优化码头集装箱
对于生产级图像,我们希望确保它们小巧、安全、快速。我个人最喜欢的任务是来自distroles项目的 Python 图像。然而什么是distroles?
让我这么说吧——在一个理想的世界中,每个人都将使用FROM scratch
作为他们的基础图像来构建他们的图像(即空图像)。然而,这不是我们大多数人想做的,因为它需要你静态地链接你的二进制文件,等等。这就是distroles发挥作用的地方——这是大家的FROM scratch
。
好了,现在来实际描述一下发行版是什么。这是由谷歌制作的一组图像,包含你的应用程序所需的最少内容,这意味着没有外壳、包管理器或任何其他工具会使图像膨胀,并为安全扫描仪(如 CVE )产生信号噪声,从而更难建立合规性。
既然我们知道我们在处理什么,让我们看看生产…实际上,我们不会改变太多,只有两行:
我们需要改变的只是构建和运行应用程序的基础映像!但是差别是相当大的——我们的开发映像是 1.03GB,而这一个只有 103MB,这是相当大的差别!我知道,我已经能听到你了— “但是阿尔卑斯山可以更小!”是的,没错,但是大小没那么重要。你只会在下载/上传的时候注意到图片的大小,这并不常见。当图像运行时,大小根本不重要。比尺寸更重要的是安全,在这方面distroles肯定更胜一筹,因为 Alpine (这是一个很好的选择)有很多额外的包,增加了攻击面。**
在谈论发行版时,最后值得一提的是调试映像。考虑到发行版不包含任何外壳(甚至不包含sh
),当你需要调试和探索时,这变得相当棘手。为此,所有的发行版镜像都有debug
版本。因此,当便便遇到麻烦时,您可以使用debug
标记构建您的生产映像,并将其部署在您的正常映像旁边,执行到其中,并执行例如线程转储。你可以像这样使用python3
镜像的调试版本:
一切只需一个命令
所有的Dockerfiles
都准备好了,让我们用Makefile
来自动化它吧!我们要做的第一件事是用 Docker 构建我们的应用程序。因此,要构建开发映像,我们可以执行make build-dev
,它运行以下目标:
该目标通过首先用运行git describe
然后运行docker build
创建的图像名称和标签替换dev.Dockerfile
底部的标签来构建图像。
接下来—使用make build-prod VERSION=1.0.0
进行生产建设:
这一个与前面的目标非常相似,但是在上面的例子1.0.0
中,我们将使用版本作为参数传递,而不是使用git
标签作为版本。
当你在 Docker 中运行所有东西时,你将需要在 Docker 中调试它,为此,有以下目标:
从上面我们可以看到入口点被bash
覆盖,容器命令被参数覆盖。通过这种方式,我们可以直接进入容器,或者运行一个 off 命令,就像上面的例子一样。
当我们完成编码并希望将图像推送到 Docker 注册表时,我们可以使用make push VERSION=0.0.2
。让我们看看目标做了什么:
它首先运行我们之前看到的build-prod
目标,然后只运行docker push
。这假设你已经登录到 Docker 注册表,所以在运行之前你需要运行docker login
。
最后一个目标是清理码头工件。它使用被替换到Dockerfiles
中的name
标签来过滤并找到需要删除的工件:
你可以在我的知识库中找到这个Makefile
的完整代码清单:https://github . com/MartinHeinz/python-project-blue print/blob/master/Makefile
具有 GitHub 操作的 CI/CD
现在,让我们使用所有这些方便的make
目标来设置我们的 CI/CD。我们将使用 GitHub Actions 和 GitHub Package Registry 来构建我们的管道(作业)和存储我们的图像。这些到底是什么?
- **GitHub 动作是作业/管道帮助你自动化你的开发工作流程。您可以使用它们来创建单独的任务,然后将它们合并到定制的工作流中,然后在每次推送至存储库或创建发布时执行这些工作流。
- **GitHub 包注册表是一个包托管服务,与 GitHub 完全集成。它允许您存储各种类型的包,例如 Ruby gems 或 npm 包。我们将使用它来存储我们的 Docker 图像。如果你不熟悉 GitHub 包注册表并且想要更多关于它的信息,那么你可以在这里查看我的博客文章。
现在,要使用 GitHub 动作,我们需要创建工作流*,这些工作流将基于我们选择的触发器(例如,推送至存储库)来执行。这些工作流是位于我们存储库中.github/workflows
目录下的 YAML 文件:*
在那里,我们将创建两个文件build-test.yml
和push.yml
。首先,build-test.yml
将包含两个作业,每次推送至存储库时都会触发这两个作业,让我们来看看这些作业:
名为build
的第一个作业验证了我们的应用程序可以通过运行我们的make build-dev
目标来构建。在运行它之前,它首先通过执行发布在 GitHub 上的动作checkout
来检查我们的存储库。
第二项工作稍微复杂一些。它针对我们的应用程序以及 3 个 linters(代码质量检查器)运行测试。与之前的工作一样,我们使用checkout@v1
动作来获取源代码。之后,我们运行另一个名为setup-python@v1
的已发布操作,它为我们建立了 python 环境(你可以在这里找到关于它的详细信息)。现在我们有了 python 环境,我们还需要来自requirements.txt
的应用程序依赖项,我们用pip
安装它。此时,我们可以继续运行make test
目标,这将触发我们的 Pytest 套件。如果我们的测试套件通过,我们将继续安装前面提到的棉条- 皮林特、薄片 8 和土匪。最后,我们运行make lint
target,它触发每个 linters。
这就是构建/测试工作的全部内容,但是推送工作呢?让我们也回顾一下:
前 4 行定义了我们希望何时触发该作业。我们指定这个作业应该只在标签被推送到存储库的时候开始(*
指定标签名的模式——在这个例子中是——任何东西)。这样我们就不会在每次推送到存储库时都将 Docker 映像推送到 GitHub 包注册表中,而是只有在我们推送到指定应用程序新版本的标签时才会这样做。
现在是这项工作的主体——首先检查源代码,并将环境变量RELEASE_VERSION
设置为我们推送的git
标签。这是通过使用 GitHub 动作的内置::setenv
功能完成的(更多信息在此)。接下来,它使用存储在存储库中的REGISTRY_TOKEN
密码和启动工作流的用户的登录名(github.actor
)登录 Docker registry。最后,在最后一行运行push
target,它构建 prod image 并将其与之前作为 image 标记的git
标记一起放入注册表。
你可以在我的库中的文件里签出完整的代码清单。
使用 CodeClimate 进行代码质量检查
最后但同样重要的是,我们还将使用 CodeClimate 和 SonarCloud 添加代码质量检查。这些将与上面显示的我们的测试作业一起触发。所以,让我们给它添加几行:
我们从 CodeClimate 开始,首先导出GIT_BRANCH
变量,我们使用GITHUB_REF
环境变量检索该变量。接下来,我们下载code climatetest reporter 并使其可执行。接下来,我们使用它来格式化由我们的测试套件生成的覆盖率报告,在最后一行,我们将它发送给 CodeClimate ,它带有测试报告者 ID,我们将它存储在存储库 secrets 中。
至于 SonarCloud ,我们需要在我们的存储库中创建sonar-project.properties
文件,如下所示(该文件的值可以在右下角的 SonarCloud 仪表板上找到):
除此之外,我们可以使用现有的sonarcloud-github-action
,它为我们做了所有的工作。我们所要做的就是提供两个令牌- GitHub 一个是默认在存储库中的,另一个是 SonarCloud 令牌,我们可以从 SonarCloud 网站获得。
注意:关于如何获取和设置前面提到的所有令牌和秘密的步骤在资源库自述 这里 。
结论
就是这样!有了上面的工具、配置和代码,您就可以构建和自动化下一个 Python 项目的所有方面了!如果你需要更多关于这篇文章中所展示/讨论的主题的信息,那么就在这里查看我的资源库中的文档和代码:【https://github.com/MartinHeinz/python-project-blueprint如果你有任何建议/问题,请在资源库中提交问题,或者如果你喜欢我的这个小项目,就开始吧。🙂
资源
本文最初发布于martinheinz . dev
使用开放式 python 库实现 GIS 和遥感工作流的自动化
实现空间 python 社区中一些最受欢迎的工具的实践指南
在我的职业生涯中,我使用 ArcGIS 平台参与了许多地理空间相关的项目,我非常喜欢这个平台。这意味着我可以在具有尖端地理空间技术的项目中提供咨询,如多维栅格、深度学习和空间物联网自动化。考虑到这一点,我总是试图跟踪如何在没有 Esri 精美制作的系统的情况下执行我正在使用的 相同的操作。
在过去的几个周末,在异常乏味的隔离期间,我一直在编写这个小脚本,它将重现我一直在用 ESRI 的生活地图集开发的东西,以实现 NDVI 区域统计 ( 归一化差异植被指数,遥感中的经典)农村地块的。
这里的计划是在不借助任何 GIS 桌面软件的情况下执行整个地理处理和遥感例程。我们从一个包含我们感兴趣的一些宗地的图层和一个包含特殊立法适用的保护区的图层开始。python 之外什么都不允许!这是我们今天的计划:
- 检查 parcels geojson 图层中的无效几何并进行更正;
- 以公顷为单位计算每个地块的面积;
- 验证每个宗地是否与任何保护区相交;
- 计算每个宗地的相交面积,并在宗地属性中插入受保护区域的名称;
- 获得最新的五张没有云的 Sentinel-2 卫星图像;
- 计算每幅图像上的 NDVI;
- 计算分区统计数据(平均值、最小值、最大值和标准差)。戴夫。)为每个包裹上的 NDVI;
- 创建显示每个宗地中裁剪结果的地图。
我们开始吧
所以。重要的事情先来。我们必须导入存储有地块的 geojson 文件。为此,我们将使用 geopandas 库。如果你不熟悉它,我的建议是熟悉它。Geopandas 基本上用 python 模拟了我们在经典 GIS 桌面软件(GRASS、GDAL、ArcGIS、QGIS……)中使用的功能,其方式与数据科学家非常流行的工具 pandas 一致,允许对几何类型进行空间操作。
为了导入我们的 geojson,我们首先必须注意 geopandas 中的数据类型。基本上,当我们运行.read_file
方法时,我们给polygons
变量分配了一个geodataframe
类型。在每个geodataframe
内部总会有一个geoseries
,我们可以通过.geometry
方法访问它。一旦我们找到了geoseries
,我们就可以利用.isvalid
方法,为我们系列中的每条记录生成一个真/假值列表。
当然,我们的数据集中存在无效的几何图形。这并不奇怪,因为这些地块来自汽车登记处,巴西的每个农村土地所有者都必须自行申报他们自己的财产范围。
那么,我们如何解决这个问题呢?也许您习惯于运行 ArcGIS 或 QGIS 中的 excelent 无效几何检查工具,这些工具甚至会生成一份报告,说明表中每条记录的问题所在。但我们无法接触到地质公园里的那些东西。相反,我们将做一点小技巧来修正几何图形,对所有几何图形应用 0 米缓冲。
现在我们终于可以通过使用.plot
方法来看看我们的多边形了,这个方法实际上是从geopandas
中的matplotlib
组件继承来的。
这是快速了解我们的数据在空间上的样子的一种快速而有用的方法,但它与地图不同。
计算面积
因为我们想知道我们每块土地的公顷面积,我们需要确保我们的地理数据框架在投影坐标系中。如果您不熟悉坐标参考系统(CRS ),您至少需要知道的是地理坐标系统以度为单位(如纬度和经度),而投影坐标系统以距离为单位,使我们能够使用公制计算面积。从我们刚刚创建的绘图中,我们可以看到多边形可能是根据纬度和经度绘制的,大约在-15.7,-47.7 之间。如果我们运行print(polygons.crs)
,我们将得到epsg:4326
作为响应。有许多可用的坐标系统,因此 EPSG 系统是跟踪它们的一个非常好的方法; 4326 表示我们的地理数据框架在 WGS84 坐标系中——实际上是一个地理坐标系。
所以我们确实需要转换我们地理数据框架的坐标系。为此,我们必须首先决定我们将把它转换成哪个系统。在这一点上,我非常习惯于从一个系统转换到另一个系统,但如果你有点迷路,选择投影坐标系的一个好方法是使用 WGS84 系统的墨卡托通用横轴投影。所以你要做的就是找出你的数据在哪个 UTM 区域,这样你就知道那是你的数据面积失真最小的区域。一个很好的方法就是这个小小的网络应用。
我们知道我们的数据在[-15.7,-47.7 ]坐标附近的某个地方,所以现在我们知道这相当于 23 度 UTM 区,而且就在巴西利亚市旁边!
所以剩下的就是访问 EPSG 权威网站并检查我们选择的投影的 EPSG 代码。接下来,我们需要使用.to_crs
方法定义一个新的地理数据框架变量。
现在,我们可以在新的地理数据框架中创建一个新的列,我将其命名为area_ha
,并计算面积(单位为米,因为我们使用的是 UTM 投影),我们必须除以 10,000 才能得到公顷。
这是我们新的地理数据框架的头部。现在填充 area_ha 字段的值看起来比例正确。
检查覆盖
现在,我们可以导入提供给我们的第二个图层,该图层包含所有保护区(UCs,或Unidades de conservao),这些保护区可能代表我们正在分析的地块中农业用途的法律限制。我们将导入它,就像我们导入之前的 geojson 一样。这一次的主要区别在于,这段数据实际上有更多的字段,有保护区的名称、创建日期以及更多的法律信息。
一个更加丰富的数据集,用 geopanda 绘制。头法。
我们感兴趣的是将所有丰富的信息放入与给定保护区相交的地块的属性表中。使用叠加方法,Geopandas 实际上很容易做到这一点。它确实字面上的 正是我们要找的。在我们的示例中,它将创建一个新的地理数据框,其中每个地块的每个相交部分都有一条记录,并包含有关其相交的受保护区域的信息。这样,我们就可以像以前一样,以公顷为单位计算相交区域的新字段。
它看起来像以前的同一块地,但现在我们的土地被分成更小的部分,如果它们与任何保护区相交的话。另外,它们现在包含了更多有用的信息。
现在是遥感部分
我们已经完成了本文的 GIS 部分,现在事情变得有趣了。我们想很好地了解每个地块的植被状况,因此我们将尝试获取最新的(免费)卫星图像,并进行一些分析。有许多免费卫星图像的选项,如 [Landsat 系列](http://Landsat Sciencelandsat.gsfc.nasa.gov),但 ESA 的 Sentinel2 任务提供了体面的空间比例(20x20m 像素)的免费图像。
要访问它,我们可以使用不止一个库。哨兵枢纽是一个坚实的,ArcGIS 生活地图集是另一个。但我个人的选择是谷歌地球引擎,原因很简单:只需稍作改动,我们就可以用相同的代码访问来自 Landsat 和 Sentinel 的数据,而且它**(仍然)**可以免费使用——但让我们不要忘记谷歌地图 API 发生了什么。这里真正的缺点是 GEE 的 python API 没有很好的文档记录。
我们想做的事情相当简单。我们必须从 GEE 调用 Sentinel 2 图像集合,根据感兴趣的区域、日期和云百分比对其进行过滤,并获得集合中最新的五幅图像。为了获得感兴趣的区域,我们必须使用 geopandas 再运行一个命令,即.total_bounds
方法,这将为我们提供一个矩形的坐标,该矩形包含我们地块的全部范围。
我们已经获取了这五张最新的图片,并将它们存储在我们的collectionList
变量中。但是让我们看一看,以确保卫星图像确实符合我们的期望。为此,让我们使用地球引擎的.Image
,将其设置为 RGB 合成——在 Sentinel 2 中,这意味着使用波段 4、3 和 2——并使用 Ipython 的.display
绘制它。
看起来不错,巴西利亚。
计算 NDVI
这一点其实很简单。GEE 使得计算归一化差异变得非常容易,这正是 NDVI 的情况:
归一化差异植被指数 ( NDVI )是一个简单的图形指示器,用于评估被观测目标是否包含活的绿色植被。与其他波长相比,健康的植被(叶绿素)反射更多的近红外(NIR)和绿光。但是它吸收更多的红光和蓝光。
NDVI 通过测量近红外(植被强烈反射)和红光(植被吸收)之间的差来量化植被。像陆地卫星和 Sentinel-2 这样的卫星传感器都有必要的近红外和红光波段。
NDVI 公式,或近红外和红光之间的归一化差异。
在 GEE 中,我们只需要使用正确波段的.normalizedDifference
方法。在我们的例子中,是波段 8(近红外)和波段 4(红色)。通常情况下,就是这样,但我是一个老式的 GIS 极客,所以我需要在地图上查看我的数据,以确保一切正常。
为此,我将创建一个简单的树叶地图——一种使用 python 渲染传单地图的方法——并将 NDVI 栅格和地块 geojson 加载到其中。
区域统计很有趣
我们快完了。我们现在需要做的是恢复我们刚刚为每个地块中的五个哨兵 2 图像计算的 NDVI 数据。遥感领域的人们已经这样做了很多年,使用了一种叫做区域统计的东西。该工具存在于许多 GIS 桌面软件中,甚至在 GEE python API 中也是可行的-同样,文档记录很少。为了简单、易于访问和可靠,我的首选工具实际上是 rasterstats 。
问题是,到目前为止,我们一直在用自己的格式处理图像。并且 rasterstats 将需要那些老派。TIF 档案。所以我们要把图像导出到本地文件夹。
最后,这是奇迹发生的地方。让我们使用一个小 for 循环来打开每个本地 NDVI 栅格文件,计算每个地块的统计数据,然后将的平均值、最小值、最大值和标准偏差的结果附加到熊猫的数据帧中。
我们已经为每个图像的每个 stat 创建了一个字段,所以我们将为每种请求的统计类型(最小值、最大值、平均值和标准值)创建五个字段。戴夫。)
现在,我们可以像以前一样,通过绘制数据来可视化每个地块中的 NDVI 统计数据,只是这次我们可以告诉 matplotlib 使用哪一列和哪一种配色方案。由于结果看起来不错,我们可以将地理数据框架导出到 geojson 文件中,并与不太懂技术的同事共享。
这是我们最近的哨兵 2 图像的平均 NDVI 属性的可视化。
这是所有的乡亲
这一块就到此为止!我们已经成功实施了经典的地理处理和遥感工作流,无需使用 ArcGIS 或 QGIS 一次!你可以在我的 Github 页面找到整个工作流程。如果你有问题或建议,不要犹豫,随时给我写信!
如果你喜欢这篇文章,考虑给我买一杯咖啡,这样我就可以继续写更多的文章了!
嘿👋我刚刚在这里创建了一个页面。你现在可以给我买杯咖啡了!
www.buymeacoffee.com](https://www.buymeacoffee.com/guilhermeiablo) [## guillermeiablo/ndvistats
jupyter Notebook com flow to cálculo de statistics zones para poli gonos selectors utilizations to geo pandas,google…
github.com](https://github.com/guilhermeiablo/ndvistats)
使用 GitLab CI 自动部署 Lambda 模块
在 Unsplash 上 Sai Kiran Anagani 拍摄的照片
在使用 terraform lambda 模块时,我很难找到最佳的存储库架构来自动化我的 lambdas 部署。我找不到任何可以作为指南的文章,这就是我写这篇文章的原因。
在从事大型项目时,项目组织是必备的*。在这个故事中,您将会看到一种组织您的存储库的方法,这样可以简化部署过程,使其更具可扩展性。*
在本文中,我们将构建以下存储库架构:
- Lambda 模块:包含 Terraform Lambda 模块的存储库。
- Lambda-Infra :包含部署到 AWS 中的 Terraform 代码的存储库。
- Lambda 代码:包含使用 Gitlab-CI 进行部署的 Lambda 代码的存储库。
λ模块
由 HashiCorp: 定义
**模块是一起使用的多个资源的容器。
使用 terraform 模块解决了组织配置、封装配置、重用配置等问题,并且它提供了一致性并确保最佳实践。
我们将使用一个 AWS lambda 模块,可以在这里找到。我不会深入讨论如何构建 lambda 模块的细节,因为这不是本文的主要目标。
λ-Infra
一旦你准备好了你的模块,你就可以建立一个仓库来集中你所有的 lambdas 基础设施。在下面的例子中,每个。tf* 代表不同的λ。*
*.
├── README.md
├── lambda_alarm.tf
├── lambda_general.tf
├── lambda_sms.tf*
准备好 lambda 模块后,你可以用它来构建你的 lambda 基础设施。
从下面的代码中可以看出,我们将 lambda zip 文件存储在 s3 bucket 中,该 bucket 已经激活了版本控制。这是至关重要的一步,因为 s3 中 zip 文件的版本 id* 将触发 lambda 的重新部署,以防代码发生任何变化。*
在上面的例子中, lambda-sms.zip 是我们的 lambda 源代码,将在下面定义。
λ代码
为了自动化 lambda 部署,有必要压缩 lambda 代码并将其放入 s3 存储桶。
首先,让我们检查我们的 lambda 代码示例。
*.
├── README.md
└── .gitlab-ci.yml
└── lambda
├── config.py
├── database.py
├── handler.py
├── package
├── queries
│ └── save_data.sql
└── requirements.txt*
我们的 CI 将负责:
- 运行 Flake8 以检查语法错误和林挺惯例。
- 安装在 requirements.txt 中定义的 lambda 依赖项
- 压缩我们的代码
- 使用 AWS CLI 将其移动到 AWS s3 存储桶
遵循 AWS 中的最小特权原则,您应该创建一个只有 Put-Object 权限的 IAM 用户:
您将在 GitLab 项目的 CICD 设置中存储您的 AWS CLI 凭据:
GitLab CICD 设定截图
一切就绪后,当你将代码推送到主分支时,你的 lambda 代码将被压缩并存储在你的 S3 桶中。
结论
让我们看一下所有的部署程序:
- 创建您的 lambda 代码,并将其推送到您的 GitLab 库。
- 然后,您的代码将被压缩并存储在您的版本化 s3 存储桶中。
- 用 l ambda-infra 代码运行 terraform。
- Terraform 将检查您的 lambda 源代码的版本 id 的变化。
- 如果它检测到新的。zip 文件已经上传到 s3,它将重新部署您的 lambda。
这种架构让我的生活变得更加轻松,给了我的代码更多的可伸缩性。我希望它能像帮助我一样帮助你!
参考
当您使用 Terraform 管理基础设施时,您将创建越来越复杂的配置。没有…
learn.hashicorp.com](https://learn.hashicorp.com/tutorials/terraform/module?in=terraform/modules) [## 自动从 Gitlab 上传文件到 S3
更新于 2017 年 12 月 3 日。最近开始使用 GitLab 和他们的自动化管道(GitLab CI)来托管…
correctme.ifiamwrong.com](https://correctme.ifiamwrong.com/posts/gitlabcitos3/)*
使用 Amazon Glue、Amazon SageMaker 和 AWS Step 函数 Data Science SDK 实现机器学习工作流的自动化
使用 Amazon Glue、Amazon SageMaker 和 AWS Step 函数 Data Science SDK 实现机器学习工作流的自动化
自动化机器学习工作流有助于建立可重复和可再现的机器学习模型。这是将机器学习项目投入生产的关键一步,因为我们希望确保我们的模型是最新的,并且在新数据上表现良好。亚马逊胶水、亚马逊 SageMaker 和 AWS 步骤函数可以帮助在托管环境中自动执行从数据处理到模型部署的机器学习工作流。
在这篇文章中,我将使用上面提到的 AWS 服务来开发和自动化一个机器学习工作流,其中 PySpark on AWS Glue 用于数据准备和处理,Amazon SageMaker 用于模型训练和批量预测。这样做的目的是为了展示工程师和数据科学家如何快速轻松地创建自动化的机器学习工作流。
AWS 服务:
AWS Glue 是一项完全托管的提取、转换和加载(ETL)服务,使客户能够轻松准备和加载数据进行分析。
Amazon SageMaker 是一项完全托管的服务,使数据科学家能够构建、训练、调整和部署任何规模的机器学习模型。该服务提供了一个功能强大、可扩展且易于使用的计算环境。
Amazon Step Functions 让您可以将多个 AWS 服务协调到无服务器工作流中,以便您可以快速构建和更新应用。
AWS Step 函数 Data Science SDK 是一个开源库,允许数据科学家使用 Amazon SageMaker 和 Amazon Step 函数轻松创建处理和发布机器学习模型的工作流。
概观
编排机器学习工作流程是生产 ML 的关键。为此,我用 AWS Step 函数和 Amazon SageMaker 创建了一个简单的端到端教程,使用了 AWS Data Science Step 函数 SDK。你可以在Amazon sage maker Samples GitHub仓库中找到完整的例子。
步伐
在这篇文章中,我们将按照以下步骤创建一个机器学习工作流:
- 在 AWS Glue 上编写用于数据处理的 PySpark 脚本
- 训练一个模型,使用亚马逊 SageMaker XGboost 算法
- 部署模型
- 用亚马逊 SageMaker 批量转换进行批量预测
先决条件
为了完成这个例子,我建议您按照亚马逊 SageMaker workshop 网站上的步骤启动一个亚马逊 SageMaker 笔记本实例。我们还建议您阅读如何创建运行 Amazon Glue 作业所需的 IAM 角色和权限。
创建 PySpark 脚本在 Amazon Glue 上运行
我假设您已经熟悉编写 PySpark 作业。这个例子触及了 Glue 的基础,对于更复杂的数据转换,请仔细阅读亚马逊 Glue 和 PySpark。下面的代码片段展示了 AWS Glue 中简单的数据转换。
示例 Amazon Glue PySpark ETL 脚本
创建 PySpark 脚本后,该脚本必须上传到 S3 的一个位置,Amazon Glue 可以访问该位置:
$ aws s3 cp glue-etl-processing.py s3://my-code-bucket/glue/glue-etl-processing.py
一旦以上成功完成,我们将使用 AWS Python SDK 、 Boto3 来创建一个胶合作业。请参见下面的示例:
准备工作流程
在这篇文章中,我们将使用 Amazon SageMaker 内置的 XGBoost 算法来训练和托管一个回归模型。数据集来自视频游戏销售预测亚马逊 SageMaker Workshop 示例。然而,我们不会深入研究完整的细节,因为它们可以在亚马逊 SageMaker Workshop 网站上找到。
为了准备工作流,我将使用AWS Step Functions Data Science SDK,这使得在 AWS 上创建 step function 状态机变得更加容易和快速。在下面的步骤中,我将展示如何为数据处理、Amazon SageMaker 模型培训和部署步骤以及 Amazon SageMaker 批量转换步骤创建一个粘合步骤。最后,我们将把这些步骤链接在一起,创建一个工作流,然后用 AWS 步骤函数执行该工作流。
涂胶作业步骤
AWS 将作业步骤与 AWS 步骤函数 SDK 粘合在一起
亚马逊 SageMaker 估算器和训练步骤
AWS 步骤函数 SDK 训练和模型步骤
最后,让我们将这些步骤串联起来,创建一个工作流
AWS 步骤功能 SDK 链工作流步骤
使用 Amazon Glue、Amazon SageMaker 和 AWS Step 函数 Data Science SDK 实现机器学习工作流的自动化
通过批量预测实现工作流程自动化
在本教程中,我们演示了如何使用 AWS 步骤函数 SDK 运行 orchestrate 批处理推理机器学习学习管道,从使用Amazon Glueforpy spark进行数据处理开始,到在 Amazon SageMaker 上进行模型创建和批处理推理。
结论
在这个例子中,我演示了如何使用 Amazon Step 函数创建机器学习工作流。您可以使用 Amazon CloudWatch 预定事件自动进行模型再训练。因为您可以每天进行批量预测,所以您可以用 AWS Glue 准备数据,运行批量预测,并用 step 函数 SDK 将整个步骤链接在一起。您还可以添加一个 SNSStep ,这样您就可以通过电子邮件、 slack 或 SMS 获得关于您的 ML 工作流状态的通知。许多可能性…
使用 Amazon Glue、Amazon SageMaker 和 AWS Step Functions Data Science SDK 以及 SNS 通知实现机器学习工作流自动化
进一步阅读
请分享您的想法和意见,期待您的反馈。您可以通过电子邮件联系我,在 Twitter 上关注我,或者在 LinkedIn 上与我联系。等不及收到你的来信了!!
使用 Bash 脚本自动构建 MXNet
为发布软件而构建二进制文件是非常辛苦的。但是使用 Bash 脚本的自动化证明是非常值得的!
作为测试 Apache MXNet 的一部分,我被委托为 Apache MXNet 内部分支构建二进制文件。
在构建和测试 MXNet 二进制文件时,我必须运行无数步骤。此外,该管道必须复制 8 次,以符合 Apache MXNet 支持的各种风格,如 CPU/GPU、+/- MKL 和+/-大张量(2 =8)
这项工作时间紧迫,同时也是重复的。需要按顺序执行某一组步骤。此外,它必须在多台机器上通过微小的调整进行复制。所有这些都需要自动化。
任何写了两遍以上的东西都可以而且应该自动化。
Bash (shell 脚本)是完成这项任务的理想选择。由于之前没有什么经验,我热衷于实时应用它。这里尝试捕捉我在这个过程中遇到的与 shell 脚本相关的概念。
#(哈希)+!(砰)= #!(舍邦)
从现有 shell 脚本中调用另一个 shell 脚本 拥有多个 shell 脚本来执行特定任务是一个非常常见的用例(考虑模块化,但在文件级而不是函数级)。由于需要调用另一个脚本,我很快意识到为什么我们需要shebang
。
有了 bash 的许多替代品(zsh,ksh,sh),在顶部添加一个 shebang 告诉操作系统(是的!OS ftw!)来使用提到的库。程序连同绝对路径(/usr/bin/env
)。如果未指定,操作系统将采用默认设置。
打印/记录
学习任何语言、测试任何代码、调试任何东西的第一步都是从打印语句开始的:控制台日志记录。打印到标准输出(标准输出)。
echo
向 shell 脚本传递参数
./pip_build_test.sh mkl
给定这个命令,mkl
是我们需要处理的参数。
在 bash 脚本中使用变量$1、$2 等访问参数
$1 是第一个参数(当然是在命令之后): mkl
另一种传递参数的方法叫做 Flags 方法,在这篇 livewire 文章中有很好的解释。
担心暴露凭据?
git 命令之一(针对托管在 AWS 代码提交上的存储库)需要用户名和密码。
git clone [https://username:password@server](https://username:)
虽然上面提到的方法在谷歌上的顶级搜索是存在的,但它肯定不是最好的方法。
公开 git(或任何)凭证从来都不是一个好主意。
又快又脏的变通方法?省略用户名和密码,让用户自己在机器上配置。具有讽刺意味的是,这是自动化过程中唯一的手工操作。
更好的解决方案?
- git-secrets
- AWS 秘密管理器 / SSH 密钥
- 环境变量!
将命令输出存储到变量中
有时,我们需要将命令的结果存储在一个变量中以备将来使用。可以使用var=$(command)
来实现
条件句
这让我们回到了阿尔戈尔!if
、else
得到其次是fi
、
镜像词的使用,得益于斯蒂芬伯恩、被从 Algol 移植到 Unix Shell 脚本语言。
if [[ condition ]]
then
echo "yes"
else
echo "no"
条件可以利用各种标志。例如,少数条件表达式-
-d
:搜索目录
-f
:搜索文件
-z
:如果字符串长度为零,则返回 True
关于进一步的细节man bash
命令。
旁注 : 测试 vs 扩展测试辩论。
[]
vs [[]]
:跟双[[
走。它有增强功能。为什么?改为。
将用户输入读入变量
此外,通过允许用户输入一个可以存储在变量中的值(也是为了将来使用),可以实现灵活性。
将可用性提高一个档次,我们可以允许用户使用
read -p “Continue? (Y/N): “ confirm && [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]] || exit 1
来确认
安全第一。终于。
感谢佩德罗·拉罗伊指出 2 个方便的细节。
首先要做的事情。为了使 bash 脚本安全,使用set -euxo pipefail
很重要。否则,bash 脚本中的错误将不会被发现,因为脚本将总是返回 true。其次,尽可能使用 Python 而不是 Bash。
为什么你会问?去阅读这篇关于编写安全 Shell 脚本的文章。
将脚本转换成可执行文件
说了这么多,做了这么多,还有最后一件事:将一个.sh
文件转换成一个可执行的.sh
脚本
chmod u+x <name of the file>.sh
现在,你可以选择其他权限来代替u
- u 代表用户。
- g 代表组。
- o 代表别人。
- a 代表全部。
最终外壳脚本
pip _ build _ 测试. sh
注意:aws-cli 一般可以使用
sudo apt install awscli
安装
上述使用 awscli-bundle 的过程是旧版本 Ubuntu 14.04 所必需的。(你能相信人们还在用 14.04 吗?老是金!)
这只是我典型的一天工作的一个例子。为 Apache MXNet 做贡献教会了我比在学校里学到的更多的东西。我们欢迎更多这样的贡献在我们的 Github 回购上:【https://github.com/apache/incubator-mxnet/
资源
感谢贡献一个堆栈溢出的答案!请务必回答问题。提供详细信息并分享…
stackoverflow.com](https://stackoverflow.com/questions/8967902/why-do-you-need-to-put-bin-bash-at-the-beginning-of-a-script-file) [## 如何将 grep 命令结果存储在 shell 中的某个变量中
感谢贡献一个堆栈溢出的答案!请务必回答问题。提供详细信息并分享…
stackoverflow.com](https://stackoverflow.com/questions/19951369/how-to-store-grep-command-result-in-some-variable-in-shell) [## 如何在 Bash 中将用户输入读入一个变量?
感谢贡献一个堆栈溢出的答案!请务必回答问题。提供详细信息并分享…
stackoverflow.com](https://stackoverflow.com/questions/18544359/how-to-read-user-input-into-a-variable-in-bash) [## 在 AWS 代码提交中使用用户名和密码进行 Git 拉/克隆
我需要使用 https url 作为一个命令行命令来执行 git pull。我需要将这个命令集成到 bash 脚本中。但是…
stackoverflow.com](https://stackoverflow.com/questions/46823193/git-pull-clone-with-username-and-password-in-aws-code-commit) [## 在线 Bash 编译器-在线 Bash 编辑器-在线 Bash IDE -在线 Bash 编码-练习 Bash…
在线 Bash 编译器,在线 Bash 编辑器,在线 Bash IDE,在线 Bash 编码,在线练习 Bash,执行 Bash…
www.tutorialspoint.com](https://www.tutorialspoint.com/execute_bash_online.php)
出于隐私和安全的考虑,剧本的内容有所改动。
用 Python 实现求职自动化
使用美素和硒
资料来源:unsplash.com
动机
我目前正在寻找一个新的数据科学职位,但我发现令人沮丧的是,有这么多不同的网站,在不同的时间列出不同的工作。不断检查每个网站以查看发布了哪些新角色变得很费力。
但后来我想起来了;我是一名数据科学家。一定有更简单的方法来自动化这个过程。因此,我决定创建一个管道,它包括以下步骤,并使用 Python 自动执行部分流程:
1。定期提取所有新的职位发布
我决定写一些 Python 代码来从我最常查看的网站上搜集信息。这是我将在这篇文章中概述的。
2。根据我的技能和兴趣查看新的招聘信息
我本来可以尝试自动化这一点,但我不想冒险忽略一个可能因为我放入代码的标准而感兴趣的工作。我决定手动检查我的网页抓取返回的帖子。
3。每周花一次时间申请符合条件的新工作。
我听说有人把这个舞台自动化了。然而,我相信如果你花时间和精力来定制应用程序,并且在原则上有点不同意这种方法,机会会更好。
注:本帖讨论的所有代码在 这里 都有。我也在底部分享了我最喜欢的学习资源。
我决定使用 BeautifulSoup 和 Selenium ,如果需要的话,我的进口声明如下:
来自 Indeed.co.uk 的工作信息—使用 BeautifulSoup
我寻找数据科学工作的主要网站之一是 Indeed.co.uk。
(1)提取初始 HTML 数据
我很高兴地看到,他们有一个标准化的网址格式,这将使网络抓取更容易。网址是“indeed.co.uk/jobs?”依次为*【q =职位】&【l =位置】* — 如下:
在伦敦 Indeed.co.uk 寻找“数据科学家”的工作
这使得修改职位名称和位置变得相当容易。我决定创建一个函数,将职位和位置作为参数,这样任何人都可以定制搜索:
使用来自 urllib 的 urlencode 函数使我能够插入参数来创建完整的 url。我在 URL 中包含了“fromage=list”和“sort=date ”,这样就只显示了最近的工作。
然后,在 BeautifulSoup 的便捷帮助下,我可以提取 HTML 并适当地解析它。
最后,我想找到包含所有工作列表的适当的
。我通过打开 URL(indeed.co.uk/jobs?q=data+scientist&l =伦敦)并使用‘Inspect’元素找到了它。使用这个,我可以看到包含了所有的工作列表,所以我使用 soup . find(id = " results coll ")来选择所有这些工作。
截图:Indeed.co.uk 网站
(2)提取工作细节
现在我有了包含所有工作列表的 HTML“汤”,下一步是提取我想要的信息,它们是:
- 职位名称
- 这些公司
- 完整职务简介的链接
- 列出了日期
对于其中的每一个,我再次使用 Inspect 来识别适当的部分,并使用了**。find()** 函数来识别它们,如下:
(3)迭代每个工作列表
使用‘Inspect’我看到每个工作卡都包含在一个 div 中,该 div 的类为‘jobsearch-SerpJobCard ’,所以我使用了 BeautifulSoup 的**。find_all** 功能如下:
然后,对于每张卡,我想提取上面列出的 4 条关键信息,并将它们保存在一个列表中。
我想让我的函数通用化,这样人们可以选择他们想要搜索的特征(在列出的职位、公司、链接和日期之外),所以我创建了一个列表‘desired _ characts’来指定这一点。
对于每个特征,我循环并将其添加到列表中,如下所示:
最后,我将所有这些放入一个 jobs_list 中,然后可以导出为所选的格式 Excel、DataFrame 或其他格式:
使用“cols”使我能够根据提取的特征为 jobs_list 字典的每个键指定标题。
“extracted_info”是一个列表列表;例如,每个列表包含所有职位或所有公司。
使用这些数据结构使得编译最终的 jobs_list 字典更加容易。
(4)存储和保存作业
我将“jobs_list”字典转换为数据帧,然后将其导出到用户使用以下函数选择的文件名和文件类型:
(5)集成到单个函数调用中
最后,我希望用户可以通过一个函数调用来完成上述所有工作。我是这样做的:
令人满意的是,这产生了一个可以很容易地调用的最终结果,如下所示:
来自 CWjobs.co.uk 的工作刮擦——使用硒
下一步是概括我的脚本,也从其他网站的工作列表。另一个我经常搜索的网站是 CWjobs。然而,添加这一点被证明是一个更大的挑战。
当我检查 URL 时,我注意到关键字参数没有一致的模式。
因此,我决定使用 Selenium Webdriver 与网站进行交互——输入指定的职位和位置,并检索搜索结果。
(1)下载并启动驱动程序
我使用 Google Chrome,所以我从这里的下载了合适的 web 驱动程序,并将其添加到我的工作目录中。然后,我创建了一个函数来启动驱动程序,如下所示:
(如果使用替代浏览器,您需要下载相关驱动程序,并确保其名称和位置如上所述)
(2)使用驱动程序提取作业信息 HTML‘soup’
(3)提取工作信息
接下来的步骤与上面真正的 job scraping 中的步骤 2 和 3 相同,只是针对 CWjobs 的 DOM 结构进行了调整,所以我在这里不再赘述。
一旦我完成了代码,看到我的网络浏览器被控制,而我没有触摸鼠标或键盘,这是非常酷的:
屏幕录制:web 驱动程序的使用
包扎
我对我的功能代码非常满意,并决定就此打住(毕竟我确实不得不申请工作)。
在 GitHub 上快速搜索发现,人们已经为 LinkedIn 和其他一些平台制作了类似的工作抓取工具。
我将代码上传到了一个带有自述文件的 GitHub 库中,以防其他人想用这个代码完成工作。
然后我坐下来,对自己感到非常满意。现在,我只是每周运行一次脚本,然后挑选出我想申请的工作。
老实说,使用脚本比手工操作节省的时间和精力是微不足道的。然而,我从编写代码中获得了很多乐趣,并且在 BeautifulSoup 和 Selenium 上得到了更多的实践。
作为一个潜在的下一步,我可能会在 Amazon Lambda 上设置这个,这样它就可以每周自动搜索一次新的工作,而不需要我去做。所以如果我真的做了,将来可能会有一个关于这个的帖子。
我希望这是有帮助的/有趣的!
我在做这个项目时找到的最好的资源
https://realpython.com/beautiful-soup-web-scraper-python/——一个关于网页抓取的很好的概述/复习,还有漂亮的汤
https://towards data science . com/looking-a-house-build-a-web-scraper-to-help-you-5b ab 25 badc 83 e—web scraper 的另一个有趣的用例:识别潜在的可购买房屋
https://towards data science . com/controlling-the-web-with-python-6 fceb 22 C5 f 08—Selenium 的精彩介绍
https://www.youtube.com/watch?v=-vqRAkcWoM—硒在使用中的精彩演示
https://github.com/kirkhunter/linkedin-jobs-scraper——一个领英刮刀,既展示硒又美汤
我制作了一个关于这个的视频
使用人工智能实现在线监考自动化
基于视觉和音频的半自动监考功能,可防止在线考试中的作弊,并同时监控多名学生。
随着新冠肺炎的出现,远程学习蓬勃发展。学校和大学可能已经关闭,但他们转向像微软团队这样的应用程序来完成他们的学年。然而,没有解决考试的办法。有些人把它改成了作业形式,学生可以从网上复制粘贴,而有些人干脆取消了。如果我们的生活方式要成为新的标准,就需要一些解决方案。
ETS 组织托福和 GRE 等考试,允许学生在家考试,在整个考试过程中,监考老师会全程监督。由于所需的劳动力,大规模实施这一计划是不可行的。因此,让我们用 python 创建一个人工智能,它可以使用网络摄像头和笔记本电脑麦克风本身来监控学生,并使教师能够同时监控多个学生。完整的代码可以在我的 Github repo 上找到。
人工智能将具有四种基于视觉的功能,这些功能使用多线程技术结合起来,以便它们能够协同工作:
- 视线跟踪
- 嘴巴张开或闭上
- 人数统计
- 手机检测
除此之外,来自麦克风的语音将被记录,转换为文本,并且还将与试卷的文本进行比较,以报告考生说出的常用单词的数量。
要求
- OpenCV
- Dlib
- 张量流
- 语音识别
- PyAudio
- NLTK
基于视觉的技术
视线跟踪
照片由 S N Pattenden 在 Unsplash 上拍摄
我们的目标是跟踪考生的眼球,并报告他是否在向左、向右或向上看,他可能是在看笔记本或向某人发出信号。这可以通过使用 Dlib 的面部关键点检测器和 OpenCV 进行进一步的图像处理来完成。我已经写了一篇关于如何进行实时眼球追踪的文章,详细解释了后面将要用到的方法。
在本教程中,学习通过 python 中的网络摄像头创建一个实时凝视探测器。
towardsdatascience.com](/real-time-eye-tracking-using-opencv-and-dlib-b504ca724ac6)
嘴部检测
嘴部追踪结果
这和眼睛检测很像。Dlib 的面部关键点再次用于该任务,并且要求测试者坐直(如他在测试中所做的那样),并且记录 100 帧的嘴唇关键点(5 个外部对和 3 个内部对)之间的距离并取平均值。
如果用户张开他/她的嘴,点之间的距离增加,并且如果对于至少三个外部对和两个内部对,距离的增加大于某个值,则报告侵权。
人数统计和移动电话检测
我使用在 COCO 数据集上训练的 YOLOv3 的预训练权重来检测网络摄像头馈送中的人和手机。关于如何在 TensorFlow2 中使用 YOLOv3 并执行人数统计的深入解释,您可以参考这篇文章:
[## 使用预先训练的 YOLOv3 计算网络摄像头中的人数
学习使用实例分割(YOLOv3)来计算使用 TensorFlow 预训练权重的人数…
medium.com](https://medium.com/analytics-vidhya/count-people-in-webcam-using-yolov3-tensorflow-f407679967d5)
如果计数不等于,可以发出警报。COCO 数据集中手机的索引是 67,因此我们需要检查是否有任何类别索引等于该索引,然后我们也可以报告一部手机。
使用多线程合并
现在让我们深入研究代码。由于眼球跟踪和嘴巴检测是基于 dlib 的,我们可以为它们创建一个单独的线程,另一个线程可以用于 YOLOv3 任务:人数统计和移动检测。
首先,我们导入所有必要的库以及助手函数。然后加载 dlib 和 YOLO 模型。现在在eyes_mouth()
函数中,我们找出面部关键点并对其进行处理。对于嘴部检测,已经定义了外部点和内部点之间的原始距离,并且我们计算当前距离。如果某个数量大于预定义的数量,则通知监考人。对于眼睛部分,我们找出它们的质心,如链接的文章所示,然后我们检查它们最接近哪个面部关键点。如果两者都在边上,则相应地进行报告。
在count_people_and_phone()
功能中,YOLOv3 应用于网络摄像头馈送。然后,检查检测到的对象的类别,如果检测到不止一个人或者检测到移动电话,则采取适当的行动。
这些函数在不同的线程中传递,其中有无限的循环,proctor 可以通过按两次“q”来打破这些循环。
声音的
这个想法是从麦克风录制音频,并使用谷歌的语音识别 API 将其转换为文本。API 需要来自麦克风的连续语音,这是不合理的,因此音频是以块的形式记录的,因此在使用这种方法时没有强制的空间要求(十秒钟的 wave 文件的大小为 1.5 Mb,因此三个小时的考试应该有大约 1.6 Gb)。使用不同的线程来调用 API,以便可以不间断地进行连续记录,并且 API 处理最后存储的一个,将其数据附加到文本文件,然后删除它以节省空间。
之后使用 NLTK,我们从其中删除停用词。抽取问题纸(文本格式),其停用词也被移除,并且它们的内容被比较。我们假设如果有人想作弊,他们会从试卷上说些什么。最后,将常用词及其频率呈现给监考人。监考人也可以查看包含考生在考试中所说的所有单词的文本文件。
直到代码中的第 85 行,我们一直在记录、转换和存储文件中的文本数据。顾名思义,函数read_audio()
用于使用由stream_audio()
传递给它的流来记录音频。函数convert()
使用 API 将其转换为文本,并将其附加到文件 test.txt 中,同时添加一个空格。这一部分将贯穿整个考试过程。
在这之后,使用 NLTK,我们将存储的文本转换为标记,并删除停用词。对试卷的文本文件也进行同样的操作,然后找出常用词并报告给监考人。
这个系统可以和安全浏览器结合起来防止作弊。该项目并没有消除对监考人的需要,因为他需要执行某些操作。通过这个系统也有一些作弊的方法,比如一个人坐在笔记本电脑后面通过写作与考生交流。为了彻底杜绝作弊,我们需要像眼镜摄像头这样的外部硬件来覆盖考生的整个视野,并在图像上应用计算机视觉。但这将消除制造一个任何人都可以使用的人工智能的目标,而不需要使用除了标准笔记本电脑之外的任何额外东西,并且使用这个监考人还可以一次使用多个学生。
完整的代码请参考这里。
使用 Excel 和 Python 实现个人投资自动化
如你所愿,随时更新你自己的股票投资数据。
在 Unsplash 上由 Ishant Mishra 拍摄的照片
还入门 Python?
很长一段时间以来,我一直想知道如何开发 Python 项目,因为 Python 在我的日常工作中并没有被大量使用。所以,我在这里看到两种你可能适合的情况:
要么你的工作没有给你提供你正在寻找的编程技能,要么事实上根本没有给你提供任何使用它的机会。
无论你的情况如何(甚至是不包括在上面的情况),在这篇文章中,你可能会发现一个有趣的 Python 项目,现在就开始。那么,到底是什么?我设法开发了一种方法,你可以输入你所拥有的股票,并每天跟踪每只股票的表现。
首先,代码实际上是做什么的?简而言之,你必须在一个 Excel 文件中提供关于你所拥有的每一只股票的 3 个输入,然后,使用本文中分享的 Python 脚本,以便每天更新每一只股票的表现。
Excel 文件中需要输入哪些信息?股票交易代码(“股票行情”)、、、股票数量(“数量”)、和每只股票的总成本(“买入价格”)。很简单吧?除了这些输入非常简单这一事实之外,强调您只需要输入一次也很重要。
PS:我是巴西人,所以考虑了一个例子,我从巴西股市挑选了一些股票。
Excel 文件输入— Stock.xlsx
事不宜迟,我们最后来看看代码本身。
代码:
我的目标是分享我构建分析的方式,并强调我认为最重要的事情。还有一点很重要,我鼓励你搜索任何你不确定如何工作的库、方法、或属性。
第一部分:
每次您想要加载过去的数据时,都应该执行以下命令。
1.1:
你可能从未听说过的库是 yfinance。这是我们代码的核心,因为它通过 Yahoo Finance API 提供了您可能想要跟踪的股票价格(和其他一些信息)。
PS:你可能注意到了我在 Excel 文件输入图像中使用的语法,重要的是确保你写下了股票谈判的名称,因为它们在雅虎财经中是可用的。
1.2:
还记得我之前提到的 Excel 文件吗?在我的例子中,它保存为“Stock.xlsx ”,与我保存的目录相同。py 文件(这就是为什么您不必像在其他示例中看到的那样担心提供完整的文件位置,例如“C:/Documents/…”)
1.3:
除了逻辑结构之外,我强烈建议您花点时间去理解,我列出了最重要的事情:
- ^BVSP 是巴西主要的股票市场指数,类似于纳斯达克综合指数(^ixic);
- “收盘”是每只股票的市场收盘价,这是 yfinance 的一个属性。
1.4:
这是我称为“第 1 部分”的结尾。你在这之前都有什么?您创建了一个 Pandas DataFrame ,涵盖了您在 Excel 文件“Stock.xlsx”中考虑的过去一段时间(在本例中为 2 个月)内每天开市的股票价格。
为了避免创建多个 Excel 文件,您可能会注意到我覆盖了原始文件。您应该能够看到类似下面的内容(来自表的一部分的快照):
Excel 文件被股票信息覆盖
第二部分:
你应该在每天股市开盘时执行以下命令。
2.1:
我只添加了 matplotlib.pyplot 库(对我们要做什么有任何猜测吗?).
2.2:
这取决于你将如何保存你的。py 文件。按照我上面写的方法去做,“第 2 部分”会被认为是一个不同的。py 文件(有一部分 1。py 分隔文件,“StockHistory”,因为我只需要执行一次)。如果你想在一个地方拥有一切。py 文件,只需忽略这段代码,将它与所有其他代码行放在一起(但是,您需要注意,您将每天执行不必要的任务)。
2.3:
closePriceList 是由执行方法当天的每只股票价格组成的列表(注意到“[-1]”元素了吗?看看这行代码提供了什么)。
2.4:
这里的要点是向我们一直使用的 Excel 文件“追加”一个新列。这些列中的每一列都由最近股票价格的列表组成。
2.5:
这是最长的代码块,但是它的目标很简单:处理 df 以便它的每一行都作为列表提供。需要这些列表来生成以下内容:
股票每日余额[BRL 价值]
这个投资组合所有者应该考虑改变策略,对吗?
我希望你喜欢它。
这是我在 Medium 上的第一篇文章。这里重要的是分享一些有用的东西,这些东西可以用 Python 来完成,特别是对于那些不直接使用它,但希望学习更多的人。例如,您可以修改此代码来绘制累计余额,并区分您购买每只股票的日期。这取决于你自己的想象力和必要性。
使用 Python 自动化投资组合优化和分配
使用 Python 中的现代投资组合理论为您的投资组合计算优化的资产权重和分配
尼克·崇在 Unsplash 上的照片
现代投资组合理论——(MPT)
现代投资组合理论(MPT)或均值-方差分析是一种数学模型/研究,用于开发和创建投资组合,旨在使给定风险的回报最大化。这种数学很大程度上基于一种假设和经验,即普通人更喜欢风险较低的投资组合。降低风险可以通过投资于传统的安全港或多样化来实现,这是 MPT 倡导的一项事业。
这个理论是由亨利·马科维茨在 20 世纪 50 年代提出的,他因此获得了诺贝尔奖。虽然 MPT 受到了相当多的批评,部分原因是其向后看的倾向以及无法将商业和经济中的不可抗力/趋势考虑在内,但我发现,通过衡量波动率作为代理,这一工具对于衡量一个人投资组合的风险很有价值。
模型的基础知识
我将使用 Python 来自动优化投资组合。该理论的概念简述如下
- 投资组合预期收益-
投资组合的预期回报的计算方法是将资产的权重乘以其回报,然后将所有资产的价值相加。为了引入前瞻性估计,可以引入概率来生成和合并商业和经济中的特征。
投资组合预期收益
2。投资组合差异-
在该模型中,投资组合方差被用作风险的度量。较高的方差表明资产类别和投资组合的风险较高。该公式表示为
投资组合风险(方差)|ρ—资产 i/j 之间的相关系数
3。夏普比率
夏普比率衡量与无风险利率(国债利率)及其风险状况相关的投资回报。一般来说,夏普比率值越高,表明投资越好,利润越大。因此,如果比较两个具有相似风险特征的投资组合,在其他条件相同的情况下,最好投资具有较高夏普比率的投资组合。
夏普比率
4。有效前沿-
该图衡量风险与回报,用于在考虑风险状况和投资者特征后选择最佳投资组合。根据目标和投资者的能力/特征,有效边界是第一和第二象限曲线的重要部分。
资本配置线(CAL)本质上是有效边界的切线。切线和边界之间的交点被认为是最佳投资,在正常情况下,对于给定的风险状况,它具有最大的回报
在 Python 中自动化投资组合优化
- 导入库
我们将首先导入所有相关的库,以便随着我们的进展使我们的生活变得更容易。
#Importing all required libraries
#Created by Sanket Karve
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import pandas_datareader as web
from matplotlib.ticker import FuncFormatter
此外,一个重要的库是 PyPortfolioOpt,它包含了帮助我们优化投资组合的函数。我们将使用以下命令安装该库
!pip install PyPortfolioOpt#Installing the Portfolio Optimzation Library
导入将进一步需要的函数-
from pypfopt.efficient_frontier import EfficientFrontierfrom pypfopt import risk_modelsfrom pypfopt import expected_returnsfrom pypfopt.cla import CLAfrom pypfopt.plotting import Plottingfrom matplotlib.ticker import FuncFormatter
2。从网上删除股票和金融数据
我们将从雅虎获取数据!各种股票报价机的融资。我用过的代码有 Boston Scientific、Berkshire Hathway、Invesco Trust、S&P 指数基金、AES Corp .和 Sealed Air Corp .这些代码被选择用于分散各种行业的投资。
输入报价器后,我们需要创建一个空白的数据框架,用于通过循环捕捉所有股票的价格。出于本练习的目的,我进行了过滤,以捕捉我们正在研究的股票的调整后收盘价。
tickers = ['BSX','AES','BRK-B','SEE','QQQ','SPY']thelen = len(tickers)price_data = []for ticker in range(thelen):prices = web.DataReader(tickers[ticker], start='2015-01-01', end = '2020-06-06', data_source='yahoo')price_data.append(prices.assign(ticker=ticker)[['Adj Close']])df_stocks = pd.concat(price_data, axis=1)df_stocks.columns=tickersdf_stocks.head()
检查捕获的值是否为“NaN”。较不重要的是零值。如果有 NaN 值,好的做法是考虑不同的时间序列,或者用 D-1,D+1 的平均价格填充数据。如果出现大的空白,我宁愿不考虑和删除时间序列数据,也不愿插入零值。
#Checking if any NaN values in the datanullin_df = pd.DataFrame(df_stocks,columns=tickers)print(nullin_df.isnull().sum())
3。计算
我们将继续进行投资组合优化的计算。从获取所选投资组合的预期收益和方差开始。
#Annualized Returnmu = expected_returns.mean_historical_return(df_stocks)#Sample Variance of PortfolioSigma = risk_models.sample_cov(df_stocks)
接着分别计算并存储具有最大夏普比率和最小波动性的投资组合权重值。
#Max Sharpe Ratio - Tangent to the EFef = EfficientFrontier(mu, Sigma, weight_bounds=(-1,1)) #weight bounds in negative allows shorting of stockssharpe_pfolio=ef.max_sharpe() #May use add objective to ensure minimum zero weighting to individual stockssharpe_pwt=ef.clean_weights()print(sharpe_pwt)
这将为你提供不同持股的权重。如果你想最小化“零”持有或重量,请随意使用 L2 回归。此外,weight_bounds 被设置为从-1 到 1,以允许计算“做空”股票。最小方差投资组合也将进行同样的操作。
4。绘制有效边界并优化投资组合配置
最后一步是为了直观的目的绘制有效边界,并计算投资组合中给定美元金额的资产分配(即购买或卖空的股票数量)。出于本练习的目的,我考虑了 10,000 美元 investopedia 上的默认起始值。
latest_prices = discrete_allocation.get_latest_prices(df_stocks)# Allocate Portfolio Value in $ as required to show number of shares/stocks to buy, also bounds for shorting will affect allocation#Min Volatility Portfolio Allocation $10000allocation_minv, rem_minv = discrete_allocation.DiscreteAllocation(minvol_pwt, latest_prices, total_portfolio_value=10000).lp_portfolio()print(allocation_minv)print("Leftover Fund value in$ after building minimum volatility portfolio is ${:.2f}".format(rem_minv))
这将为您提供优化的投资组合,如下所示
对于计算具有最大夏普比率的投资组合,也可以这样做。
结论
据说投资既是艺术又是科学。Python 和它的库允许我们自动化优化,并在这个过程中节省宝贵的时间。然而,必须注意的是,这些孤立的技术不太可能是最好的投资方法。
接下来,我将发布关于我们如何通过机器学习选择股票来复制指数基金,以建立我们的投资组合和 Python 可以帮助我们的许多其他功能。最后,我还创建了一个程序,用蒙特卡洛模拟来计算股价的潜在损失或变动。这个工具可以和这个投资组合优化器一起使用。
自动计算风险价值(VaR ),使用 Monte 管理 Python 中的投资组合风险、股权和股票…
towardsdatascience.com](/var-calculation-using-monte-carlo-simulations-40b2bb417a67)
以上信息绝不是专业的投资建议或实践,而仅仅是我讨论如何通过现代投资组合理论(MPT)使用 Python 来自动化投资组合优化所做的努力。如需完整的源代码或任何讨论,请随时联系
自动化随机森林
建立你自己的自动机器学习系统的教程。
克里斯里德在 Unsplash 上的照片
我最近完成了一个网站的开发,它可以进行端到端的机器学习(作为一个 GUI ),也就是说,它可以自动完成以下步骤:
- 使用表单从用户处获取培训数据和测试数据。
- 清理数据并使其可用于机器学习模型(如填充缺失值、处理分类变量等。).
- 根据数据训练随机森林并调整其超参数。
- 对数据执行特征工程。
- 为最终模型绘制特征重要性图。
- 根据测试数据生成预测,并将结果和功能重要性图发送到用户提供的电子邮件地址。
所以在这篇博客中,我将带你浏览设置这样一个系统的代码。你可以在这里找到包含网站机器学习部分核心代码的 GitHub repo。
我们将使用旧的 fastai 库(v0.7)的一部分作为开始的初始基础(代码直到第 500 行包含来自库的片段和其他将被使用的必要导入)。您可以复制代码片段或安装库。我们将从这里开始编码!
我将一段一段地解释代码。所以让我们开始吧!
上面的代码定义了一些函数,随着我们的深入,这些函数将被重复使用。两个功能最为突出:
- “print_score”:它将用于评估我们的模型在训练和验证数据集上的性能。
- “auto_train”:它将用于使用给定的超参数来训练随机森林。
下一个函数“data_trainer”有点长,所以我将把它分成两部分来解释给你听。它将用于执行以下任务:
- 清理数据,处理分类变量,从日期(如果有的话)中提取信息,并填充缺失的值。
- 训练随机森林并调整其超参数。
- 特征工程。
- 删除多余的变量。
- 绘制特征重要性图。
所以,让我们开始吧!我已经添加了注释来划分与每个过程相对应的部分。
上述代码(“data_trainer”的第一部分)执行以下任务:
- 它从日期列(如果有的话)中提取数据,比如年、日、月、季度末与否、年末与否等等。
- 它将分类变量转换成机器学习模型可以使用的格式。它还会填充缺失的值。
- 它将数据分成训练和验证数据集。
- 如果数据集非常大,它将使用“RF _ sampling”(fastai 中的一种加速方法)。
- 然后,它将使用循环开始调整随机森林的超参数,即“min_samples_leaf”和“max_features ”,以获得最佳结果。
上面的代码(“data_trainer”的第二部分)将执行特征工程,并删除不影响我们的目标变量或多余的变量。
之后,该函数将返回最佳超参数和用于训练最终模型的特征列表。
上面的代码定义了一个函数来预测测试数据集,并生成和保存特征重要性图。它执行以下所有操作:
- 像我们对训练数据集所做的那样,从日期列(如果有)中提取信息。
- 在整个数据集(训练+验证)上训练随机森林(使用在先前函数中获得的超参数和特征工程信息),并将其应用于测试数据集以生成预测。
- 生成特征重要性图并保存。
现在剩下要做的就是将所有先前定义的函数捆绑在一起,通过适当的输入以适当的顺序调用它们,这就是下面要做的。
总结:
我们首先定义了一个函数来清理训练数据,找到最佳超参数,并执行特征工程(称为“data_trainer”)。然后,我们定义了一个函数,使用从上述函数获得的信息来训练模型,并使用它来生成测试数据集的功能重要性图和预测(称为“auto_applyer”)。然后,我们使用一个名为“auto_predictor”的函数将一切联系起来。此外,如果你想建立一个电子邮件系统来发送包含结果的电子邮件,你可以在这里找到代码。
瞧!我们建立了自己的自动化机器学习系统。
你可以查看网站(端到端 GUI) 这里这里是 GitHub repo 。
非常感谢你阅读这个博客!
附言
如有任何问题或建议,请随时通过 LinkedIn 与我联系。
自动化房地产投资分析:Python 网络抓取机器人
python 中的数据挖掘实现房地产交易筛选自动化。
房屋图片(来自 unsplash
摘要
目标是构建一个能够分析投资属性的 python web 工具。该工具将使用数据挖掘来查找房地产价格,然后分析回报率。
索引
摘要
索引
动机
该应用程序
这些功能
总结和展望
动机
机器人或自动化在交易和投资中的应用并不新鲜。多个例子包括股票交易机器人,其任务是根据不同的模型或指标来购买或出售资产。复兴科技因其通过算法投资获得的回报率而受到世界关注,该回报率在 30 年的时间跨度内平均达到 60%以上的年化回报率。
自动化的好处有可能改变不同规模的企业。单个重复性任务可通过内部开发的软件或第三方 SaaS 平台实现自动化。
对于个人散户投资者来说,python 机器人为房地产投资的各种元素提供了一个有前途的解决方案。在本文中,我们将研究分析属性过程的自动化。其他可以自动化的流程包括:列出物业,向租户发送通知,筛选租户(机器学习或人工智能),甚至自动派遣维护人员。
该计划
输入和输出
该程序有三个输入:房源 URL、月租金价格和财产税税率。它返回每月现金流、上限利率和现金回报率。
- 现金流 —扣除所有费用(抵押贷款、物业管理、维修补贴、空置费用)后的每月利润
- —每年的净收入除以资产价格(百分比)
- —每年净收入除以用于资产的首付款(百分比)
包装
使用了以下软件包。注意对于那些在 Anacondas 环境中工作的人来说,streamlit 目前似乎不能通过这个包管理器使用。Streamlit 是和 pip 一起安装的,当 PIP 和 Anacondas 一起使用时可能会导致问题
- 请求 —这个包用于通过 HTTP 请求访问 python 中的网站。
- 美汤 4 —用于网页抓取和数据挖掘。我们能够使用这个包来检索描述网站内容和样式的 HTML 代码。一旦检索到 HTML 代码,就可以利用 beautiful soup 来隔离站点的特定部分。例如,在这个项目中,我们使用美丽的汤来获取房价。
- Streamlit —这个包让部署 web 应用程序变得超级简单。代码是在 Jupyter 笔记本上开发的,然后转换成。py 脚本一旦开始工作。Streamlit 允许无缝部署,并最大限度地减少用户界面上花费的时间。使用 streamlit,将 python 用于后端、flask 用于部署、react 用于动态内容的经典部署选项要简单得多。
编写代码
完成大部分繁重工作的函数是 price_mine 、 mortgage_monthly 和 net_operating 。
这些是分别执行以下职责的主要功能:
- 从 URL 中检索标价
- 计算每月抵押贷款成本
- 计算扣除所有费用后的每月净营业收入
- price _ mine|该函数用于从房源中检索房价。可以使用 API,但是网络抓取更强大。web 抓取的缺点是站点结构的改变需要在代码中更新。在这里,网页刮包使用的是美丽的汤。这个过程相对简单,使用 f12 检查网页,然后在 HTML 代码中找到所需的元素。这段代码可以被隔离在 beautiful soup 中,以检索页面的特定部分。检索到代码后,内置的 python 函数 replace 用于删除逗号、美元符号和不必要的空格,以便建立一个浮点变量。
****def** price_mine(url):
*#Currently this function takes an input of a URL and returns the listing prices*
*#The site it mines is remax*
*#The input must be a string input, we can reformat the input to force this to work*
*#Next we use regex to remove space and commas and dollar signs*
headers = ({'User-Agent':
'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36'})
response = get(url)
response_text = response.text
html_soup = BeautifulSoup(response_text, 'html.parser')
prices = html_soup.find('h2',{'class': 'price'}).text
prices = prices.replace(",", "")
prices = prices.replace("$", "")
prices = prices.replace(" ", "")
prices = float(prices)
**return** prices**
- ****mortgage _ monthly|该函数将挂牌价格、抵押期限和利率作为输入,并返回每月抵押价格。有许多方法来计算每月抵押贷款价格,没有作出具体的决定,至于使用哪种方法和一个通用算法,是相当容易实现的使用。
****def** mortgage_monthly(price,years,percent):
*#This implements an approach to finding a monthly mortgage amount from the purchase price,*
*#years and percent.*
*#Sample input: (300000,20,4) = 2422*
*#*
percent = percent /100
down = down_payment(price,20)
loan = price - down
months = years*12
interest_monthly = percent/12
interest_plus = interest_monthly + 1
exponent = (interest_plus)**(-1*months)
subtract = 1 - exponent
division = interest_monthly / subtract
payment = division * loan
**return**(payment)**
- net_operating | 该函数以月租金、税率和价格作为输入,返回每月的净营业收入。净营业收入的金额分别代表支付抵押贷款(本金和利息)、财产税、支付管理费(每月 10%)、物业维修补贴和空置补贴后的现金。有人可能会说,只有每月支付的利息才构成费用,因为本金是建立在股本基础上的。虽然这是真的,但我们的模型想知道在支付所有费用后还剩多少现金。个人投资分析机器人可以改变像这样的元素,使个人投资者的计算个性化。
****def** net_operating(rent, tax_rate, price):
*#Takes input as monthly mortgage amount and monthly rental amount*
*#Uses managment expense, amount for repairs, vacancy ratio*
*#Example input: net_operating(1000,1,400,200)*
*#879.33*
*#1000 - 16.67 (tax) - 100 (managment) - 4 (repairs)*
mortgage_amt = mortgage_monthly(price,20,3)
prop_managment = rent * 0.10
prop_tax = (price * (tax_rate/100)/12)
prop_repairs = (price * 0.02)/12
vacancy = (rent*0.02)
*#These sections are a list of all the expenses used and formulas for each*
net_income = rent - prop_managment - prop_tax - prop_repairs - vacancy - mortgage_amt
*#Summing up expenses*
output = [prop_managment, prop_tax, prop_repairs, vacancy, net_income]
**return** output**
其他功能:
使用的其他函数,如 cap_rate,以百分比计算净收入与资产价格的比率。完整的函数列表可以在项目的 GitHub 资源库中找到,但是不包括在本文档中。
构建界面
早期概念化
想法是让输入在页面的左边,输出在页面的右边。输入被放置在侧边栏中,这样输入和输出在视觉上是不同的。
初始用户界面概念草图
介绍 streamlit
构建这个仪表板的一个常见方法是用 HTML 创建一个静态网站,用 flask 部署后端,在某种数据库中存储值,然后用 react 链接所有内容。一种比这种方法更具优势的新的替代部署途径被称为 streamlit。
Streamlit 允许从 python 脚本快速过渡到现代用户体验。它还提供了一种简单快速的部署途径。转换的第一步是替换内置的 python 输入函数,并用 streamlit 输入框替换它们。对输出进行了同样的替换。
一旦完成,就可以从控制台部署streamlit 应用程序,并通过外部 IP 地址进行访问。
streamlit 内置的初始用户界面
一旦在 streamlit 中构建了用户界面,就要修改代码,为输入添加一个侧栏,如上面草图中最初描述的那样。
带有输入侧边栏的用户界面
最终代码
最终代码可以在 GitHub 上找到。
项目的 GitHub 存储库
总结和未来方向
尽管复兴科技(renaissance technology)等集团能够从应用于投资的数学模型中获利,但个人散户投资者也能从中受益,而且实施起来要容易得多。
房地产投资者可以从自动化中受益,处理许多以前需要助理或占用大量时间的任务。这是一个使用自动化来减少过滤交易时间的例子。如果自动生成摘要报告,并且只将最好的资产呈现给人类,投资者可以审查更多的交易。夫妻店、房地产投资者和企业家可以从自动化中受益,而不仅仅是财富 500 强公司。
注来自《走向数据科学》的编辑: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。