打造自己的小狗
了解如何对小狗使用 Java Builder 设计模式
设计模式是一个美丽的东西。他们接受普遍面临的软件开发问题,并为我们提供普遍接受的有效解决方案。
你知道还有什么是美丽的吗?小狗!
我们要用一件美好的事物来帮助我们理解另一件美好的事物。
如果没有简单的实现,理解这些设计模式可能会有点困难。
在学习构建器模式的工作原理时,我也遇到了同样的问题。在研究了这种模式的来龙去脉之后,我发现通过正确的解释,这个概念可以很快学会。
所以事不宜迟,让我们开始建立小狗!
目标
了解如何以及何时在 Java 应用程序中使用构建器设计模式。
设置
要跟随自己,我建议使用以下工具:
- 您最喜欢的 Java IDE
- JDK 8
如果你正在寻找一种快速的方法来开始使用 VSCode 构建 Java 应用程序,我写了下面的教程。
什么时候应该使用构建器模式?
想象你是一个小狗收养中心的主人。您需要存储每只小狗的所有信息,以便在应用程序的其他部分使用。
你需要保存品种、年龄、名字,以及它是否符合健康要求。它可能看起来像这样:
Puppy.java
这很简单,对吧?我们用一个构造器创建一个类,这个构造器具有这四个属性中的每一个,并在每次有小狗进来时实例化一个新的实例。
Puppy pup = new Puppy (“Bichon Frise”, 9, “Andy”, true);
在一个完美的世界里,这将是一个很好的解决方案。但是我们并不是生活在一个完美的世界里,不是吗?
有时当这些小狗进来时,它们没有我们需要的所有信息。我们可能不知道它的年龄或是否接种过疫苗。或者可悲的是,我们可能不知道它的名字。
试图用稀疏信息构造这些对象可能看起来像这样。
Puppy pup2 = new Puppy ("Golden Retriever", false);
Puppy pup3 = new Puppy (true);
Puppy pup4 = new Puppy ("Yorkie", "Johnny", false);
Puppy pup5 = new Puppy ("Doge", 13);
Puppy pup6 = new Puppy ("Shitzu");
在 Java 中,您必须创建不同的构造函数来支持这些实例化。或者你可以使用null
值来填充空白点。但那很乱。
此外,如果顺序与原始构造函数中定义的顺序不同,值可能会映射到错误的变量。这可能会在将来给你带来意想不到的运行时错误。
一定有更好、更灵活的方法来创建这些复杂的对象,对吗?
我们使用构建器模式。
小狗建造者
让我们建造一些小狗吧!(说起来有点奇怪。)
本教程将是实现构建器模式的一个精简的、最基本的例子。
我们将从创建一个名为PuppyMain.java
的主类开始。这个类是我们的切入点。
PuppyMain.java
接下来,我们将创建Puppy.java
来存放我们的构建器代码并构建我们的小狗对象。
我将把它分成两个部分:T2 部分和 T3 部分。然而,这些都属于同一个Puppy.java
级。如果您想查看整个班级,可以向下滚动到底部。
Puppy.java
这里,我们声明这些变量中的每一个都是不可变的。这意味着一旦它们被创建,就不能被改变。私有构造函数和 final 修饰符帮助我们实现了不变性。
创建新小狗的唯一方法是使用 PuppyBuilder。
我们将 PuppyBuilder 作为私有构造函数的一个参数,这样我们就可以将 Builder 变量映射到 Puppy 类变量。
现在让我们深入了解 PuppyBuilder 的核心:
Puppy.java
为了使这个对象尽可能灵活,我们将为每个变量创建一个单独的 setter。
如果我们想要任何必需的变量,我们可以这样定义构造函数内部的变量(其中breed
是必需的):
public PuppyBuilder(String breed){
this.breed = breed;
}
但是,这只是在我们希望包含必填字段的情况下。在这个例子中,我们所有的字段都是可选的。
另一个注意:这个类是静态的,所以我们不需要在每次想要构建小狗的时候都创建一个实例。这将允许我们使用我们的建设者作为一个实用的方法;需要时随时可用。
以下是完整的文件:
这是一个使用我们的PuppyMain.java
类中的 PuppyBuilder 创建不同小狗对象的例子。我们在这里利用流畅的界面。
根据维基百科的说法,流畅接口是“一种面向对象的 API,其设计广泛依赖于方法链接。”
您可以看到,无论我们向 PuppyBuilder 提供什么信息,当我们打印出每个对象的字符串版本时,它都得到了充分的处理。
回顾
实现 Builder 模式的代码有点冗长,但是我向您保证,它更容易阅读,并且会改进您的代码库。
尤其是对于下一个查看你的代码的开发者,他们将能够毫无问题地阅读你的代码。
巴拉蒂·坎南在 Unsplash 上拍摄的照片
如果您有任何问题、意见或顾虑,请随时留下您的意见。
我希望您喜欢学习如何使用小狗来实现构建器设计模式!
作为一个完全的初学者建立自己的网站:一本正经的指南
如何使用 Hugo+Github+Netlify 免费构建一个静态站点并使用自定义域托管它的分步指南
图片由 StartupStockPhotos 来自 Pixabay
我一直想写博客,拥有自己的网站,我终于做到了!感觉真好!
我从未想过自己会成为一名网络开发人员。老实说,web 开发本身及其背后的所有技术对我来说听起来很无聊。真正让我兴奋的是网站的设计部分。你如何做图形,互动,颜色,布局。你说吧。我认为一个网页设计师不仅应该精通技术,还应该是一个有创造性和艺术性的人,能够跳出框框思考:)
显然,我对 web 开发毫无头绪,从头开始学习 CSS、HTML 和 JS 的想法听起来也不太理想。我一直在谷歌上搜索,对所有的语言、平台和学习资源感到不知所措。如果你也有同样的感觉,不用担心。你并不孤单。相信我,你不必成为 HTML 和 CSS 专家就可以开始构建东西。一旦你知道了一些基本原理,你就可以边做边学了。
当你学习的时候,你可能不会从一个单一的来源学习, Freecodecamp 和 Edureka 是初学者学习 css、js 和 Html 基础知识的好地方。你也可以在 Udemy 上找到 Edwin Diaz 的这个惊人的 CSS 和 HTML 免费课程。这些是我的最爱。
在本文中,我将向您展示如何使用 Hugo + Github + Netlify 的组合来构建和部署静态网站。
得到💬任何数据科学或编程问题的 GPT 式答案。为成千上万的人生成摘要和学习笔记📚只需一次点击即可获得学习资源。👉
[## 面向数据科学家和开发人员的免费学习资源。精选的博客、教程、书籍和…
机器学习和人工智能工程师的培训课程、黑客马拉松、活动和工作
aigents.co](https://aigents.co/learn)
什么是静态站点生成器?
静态站点生成器是一个应用程序,它将使用 Markdown 语言编写的数据和内容应用到模板中,并以静态 Html 文件的形式生成页面视图,以便交付给访问者。应用程序本身可以用任何语言编写,例如,Ruby (Jekyll)、JavaScript 和 React (Gatsby)。我开始尝试盖茨比,因为它似乎有一个非常繁荣的社区。经过一个星期不断遇到 bug 和调试,我终于成功安装了盖茨比,下载了一个盖茨比网站的模板。然而,我最终决定使用 Hugo,这是一个用 go 编写的静态站点生成器,因为它非常用户友好,而且对我来说理解 go 并不是真正必要的。你可以在这篇文章中找到盖茨比和雨果的详细比较。
好了,说够了。我们开始吧!
第一部分。用 Hugo 建立你的静态网站
A .雨果装置
#1。安装巧克力
要在你的 Windows 操作系统上安装 Hugo,你需要确保你安装了 Chocolately,这是一个用于 Windows 的软件包管理器。参见此处的说明。
#2。安装 Hugo 一旦安装了 Chocolately,打开您的终端,从那里,您可以简单地用下面的命令行安装 Hugo:
choco install hugo -confirm
对于 Mac 和 Linux 用户,请参见此处的安装指南。
太好了!现在你应该已经在你的系统上安装了 Hugo。让我们开始建立你的网站吧!
B .建立你的网站
#1。生成 Hugo 网站
接下来你需要做的是用 Hugo CLI 生成你的站点。打开您的终端,键入以下命令:
hugo new site your_project_name
将创建一个与您提供的名称(您的项目名称)相同的文件夹。您现在应该在 C:\ User \ Hugo \ Sites \ your _ project _ name 有一个目录。默认的文件夹结构如下所示:
以下是每个目录的高级概述:
Config.toml
这是 Hugo 站点的主要配置文件。在这里,您可以指定有关您的站点的信息,如站点标题和描述。查看配置文档了解更多细节。
内容
你的网站的内容,例如,你的博客文章和照片将存在于这个目录中。Hugo 中的每个文件夹都被视为一个内容部分。例如,如果您的网站有三个主要部分—博客、时尚和艺术—您将在内容目录中有三个子目录,包括博客、时尚和艺术。
布局
你可以为你的网站定义非常复杂的布局。你可以做很多事情。布局文件夹以。描述如何将内容视图呈现到静态网站中的 html 文件。
静态
这个目录存储所有的静态内容——不变的内容:比如 css 和 JavaScript。
主题
你可以下载一个预建的模板,并把它放在主题文件夹和 boom!你有你的网站。你当然可以按照你想要的方式来调整你的网站的主题。
#2。让网站在本地运行
在终端上的网站目录中,键入以下命令:hugo server
这个命令的作用是启动一个本地开发服务器,在你的机器上托管你的网站。
注意:如果您得到一个错误消息:错误:无法定位配置文件或配置目录。确保您位于包含 config.toml 文件的文件夹中。
现在,如果你打开浏览器: http://localhost:1313/,你应该会看到你的网站。你会得到一个白页,因为服务器正在运行,但还没有主题/内容。
#3。选择一个主题
作为初学者,我发现拥有一个模板并使用结构良好和格式化的代码非常有帮助。你总是可以按照你想要的方式修改你的网站。Hugo 非常用户友好,它允许你使用预先构建的主题。去雨果的主题网站,有数百个主题可供选择。都是开源的。点击演示,你可以看到网站的样子,并选择你的选择之一。
比方说,你想安装 hugo-scroll 主题,从你的终端的 hugo 项目目录中,键入以下命令:
git clone https://github.com/janraasch/hugo-scroll.git .\themes\hugo-scroll
(注意:如果开发服务器仍在运行,您需要按 Ctrl-C 来杀死它,这样您就可以回到 Hugo 目录)
现在,您应该会在网站文件夹的主题目录中看到一个名为“hugo-scroll”的目录。
#4。配置
接下来我们需要告诉 Hugo 我们想使用新安装的主题。将下面一行添加到 config.toml 中:
theme = “hugo-scroll”
如果您现在查看本地主机上的网站,您会看到主题被直接应用。这是因为雨果跟踪所有需要建立您的网站的文件,将重建网站,并迫使网页在您的网页浏览器重新加载每当您编辑一个文件。
我相信你会想改变网站模板中的东西,例如,你的网站的名称!让我们在您的文本编辑器平台中再次进入 config.toml 文件,在我的例子中,我使用 Sublime。也可以使用 VisualStudio 之类的另一个平台。您可以添加网站的标题。
顺便说一句,请务必阅读许可文件。它基本上说的是,如果你在主题中做了任何改动,而你遇到了麻烦,那么创建主题的人不会对此负责。
加入 中等会员 计划继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。
阅读兰楚的每一个故事(以及媒体上成千上万的其他作家)。你的会员费直接支持兰初…
huonglanchu.medium.com](https://huonglanchu.medium.com/membership)
第二部分。用 GitHub 和 netlify 托管你的网站
#1。找个地方存放你的代码
你需要一个 GitHub 账户。如果您还没有创建,请在这里创建一个。接下来要做的是在 Github 上创建一个资源库。转到存储库并单击“新建”:
接下来,通过转到您网站的目录并键入以下命令来上传您的网站文件夹:
git init
git add .
git commit –m “first commit”
git remote add origin <url_of_your_repository>
git push –u origin master
到目前为止,您应该可以在 git 存储库中看到 website 文件夹中的所有子文件夹。
#2。使用 Netlify 部署您的网站
Netlify 是一个 web 开发平台,为 web 应用程序和静态网站提供托管和无服务器后端服务。Netlify 连接到你的 github 账户,通过你的 git 库,将所有代码复制到 Netlify。之后,它处理并发布网站。请遵循以下步骤:
第一步。创建一个网络账户
第二步。将您的 Netlify 帐户与 Github 帐户连接。
第三步。在 Netlify 上部署您的站点。
你可以在 Netlify 的网站上找到详细的说明。在这个过程之后,Netlify 将为您创建一个有趣的默认 url — random_name.netlify.app。我的名字是:深情-赫尔曼-8298bf。点击链接,看看你的网站现在是活的!祝贺你!
#3。创建自定义域
当然,你会希望有自己的域名,而不是一个有趣的来自 Netlify 的随机名称!在这篇文章中,你可以找到为你的网站创建自定义域名的逐步指南。
更新您的网站
要更新您的网站,您可能需要在本地对您的网站进行更改。在将网站推送到 Git Repo 之前,您还可以在 http://localhost:1313/ 运行以下命令来查看网站的外观:
hugo server
我惊讶地看到,在不到一秒钟的时间内,这些更改就在您的本地计算机上更新了!很酷吧?要将您的更改推送到您的网站,您首先需要使用以下命令添加更改、提交并将其推送到您的 Git 存储库:
git add .
git commit -m "Updates website"
git push origin master
Netlify 将立即检测到您推送到 git repo 的更改,并返回到 Netlify 站点部署新的更改,这将在几秒钟内发生!请看下面的快照,Netlify 在同一分钟内完成构建、处理和发布。
结论
一个 Hugo 模板并不能构建一个完美的网站。然而,作为一个初学者,你可以先建立一个基于模板的网站,然后在此基础上学习更多的 HTML、CSS 和 GO 技巧。一步一步来。熟能生巧。
我希望这有助于学习,并给你一些动力来建立自己的网站。我很乐意看看你的网站,一旦你完成建设。请在评论中告诉我。
用英伟达泰坦 RTX 和 RYZEN ThreadRipper 构建一个价值 5000 美元的机器学习工作站
3.8 GHz、24 核、64 GB、基于泰坦 RTX 的机器学习工作站
不是每个人都适合制造电脑。在高端,建立一个机器可以节省资金,并允许您准确地指定您希望的硬件。此外,随着更高级的组件变得可用或更经济,自定义计算机版本允许您计划和执行增量升级路径。这篇文章描述了我如何在 5000 美元(USD,2020 年 7 月)的价格范围内构建一个机器学习工作站。我还提供了一些建议来提高或降低这个价格。
我将从描述我的用例开始。我处理的任务可能是 GPU 或 CPU 密集型的。有时,我确实希望有大量的 RAM 用于数据处理和暂存。对于超出这台机器能力的内存需求,我通常使用 Spark 或 Dask。因为这些需求,我在 CPU、RAM 和硬盘访问上花费了相当多的钱。因为我的处理需求最常见的瓶颈是神经网络训练,所以我选择了高端 GPU。
机器规格和零件清单
我构建的计算机是一个 3.8 GHz(4.5 GHz 的加速时钟速率)24 核 AMD ThreadRipper (3960X),64GB 内存和一个英伟达泰坦 RTX 。在我创造计算机的时候,NVIDIA TITAN GPU 是有意义的。在这一点上,我建议看看 NVIDIA 30 系列,如 3080。我将完整的零件清单发布给电脑零件提货人。亮点包括:
- AMD thread ripper 3960 x 3.8 GHz 24 核处理器
- 英伟达泰坦 RTX 24 GB 显卡
- 微星 TRX40 PRO WIFI ATX sTRX4 主板
- 海盗船复仇 RGB Pro 64 GB(4x 16 GB)DDR 4–3200 CL16 内存
- Sabrent Rocket 4.0 2tb m . 2–2280 NVME 固态硬盘
- Corsair RMx 1000 W 80+金牌认证全模块化 ATX 电源
- 海盗船水晶 570X RGB ATX 中塔表壳
硬盘足够快,程序加载非常快。此外,在内存和硬盘之间移动我的数据并不慢。我额外支付了更快的 RAM,希望加快 CPU 和 GPU RAM 之间的加载速度。进一步的基准测试将让我知道这有多好。
选择 GPU
GPU 是机器学习工作站的重要考虑因素。而机器学习工程师可能希望运行使用机器的图形潜力的复杂可视化;大多数现代 GPU 应该能够处理用户的图形需求。GPU 的数字处理能力是机器学习工作站的一个重要特征。对于游戏系统来说,应该在 AMD 和 NVIDIA 之间做出选择。对于机器学习,特别是深度学习,GPU 的选择真的只是英伟达。
CUDA 或 OpenCL 是允许 GPU 充当软件数学引擎的功能。TensorFlow、PyTorch 等常用 CUDA,需要和 NVIDIA。OpenCL 更加开放,支持来自英特尔、AMD 和 NVIDIA 的 GPU。然而,由于各种原因,主要是性能原因,CUDA 得到了最广泛的支持。还有,NVIDIA 主导了 AWS 和 Azure 的云平台。谷歌云平台(GCP)确实提供了一种叫做张量处理单元(TPU)的替代技术;然而,TPU 在本地系统上并不常见。出于这些原因,尤其是云兼容性,我坚持使用 NVIDIA 的 GPU 产品。
NVIDIA 为游戏应用程序提供 GeForce GPUs,为更多以计算为中心的任务提供 Quadro。弥合这一鸿沟的是泰坦卡,它提供的额外内存往往比游戏更有利于深度学习;同时仍然提供与其最高端游戏 GPU 一样多的 CUDA 内核。NVIDIA 非常友好地给我的 YouTube 频道提供了一台泰坦 RTX。我决定,既然我得到了一个 2500 美元(2020 年 7 月)的 GPU,我就投资同样的金额,围绕这个神奇的 GPU 建立一个高级深度学习工作站。
英特尔还是 AMD
我希望我的工作站足够灵活,能够为以 GPU 和 CPU 为中心的任务提供高性能。基于 GPU 的深度学习有多伟大;我确实发现自己在使用 CPU 繁重的任务进行数据预处理和一些可视化。另外,由于我经常用 Python 编写自动化任务的代码;我能够利用多核技术来设计我的软件。除非你正在制造一台计算机,否则你很少能直接选择英特尔或 AMD 就像你有时被允许从硬件制造商那里选择 CPU 类型。
在观看/阅读了相当数量的关于英特尔 vs AMD 现状的报道后;我得出了以下结论。AMD 提供更多核心;然而以稍微降低的时钟速度。所以 AMD 在多线程软件上效率会更高。英特尔将在并行性较低的软件上更加高效,这些软件受益于更大的单核速度优势。因为我的大部分软件是多线程的,我可以选择设计自己定制的多线程软件,所以我选择了 AMD。
我选了一个 24 核的 AMD RYZEN ThreadRipper,适配一个 TRX4 插座,这是目前 AMD 最新的插座类型。这意味着我以后可以轻松地将我的 CPU 升级到更高级的 AMD 产品。传统上,我一直使用英特尔。我在 AMD 遇到的唯一小麻烦是,有时我必须等待最新的“微软内幕”预发布 Windows 版本。
操作系统选择
对于这台电脑,我决定用 Windows 10 Pro。我对微软的 Linux 子系统(LSU)能力印象非常深刻;尤其是现在 Linux 子系统可以访问底层的 GPU。我刚刚开始使用 LSU-2,所以我对这个系统的看法还在发展中。我希望在后面的文章和视频中发布更多关于 LSU 的内容。
与云的成本比较
在构建这台机器之前,我将我的大部分 GPU 工作负载发送到了云。我最常见的任务要么是 Kaggle 竞赛,要么是为我在华府大学的深度学习课程重新运行和优化示例。这些工作负载的云成本并不小。为了将这台机器与 AWS 云进行比较,我使用了以下成本(截至 2020 年 7 月):
- AWS 工作区:16 个 vCPU,122 GiB 内存,1 个 GPU,8 GiB 视频内存,每月 999.00 美元或每月 66.00 美元,每小时 11.62 美元。
上面引用的 AWS workspaces 实例比我的机器弱得多;然而,它是最接近的等效物。我有 24GB 的显存;而 AWS 机器只有 8 个。这可能需要对神经网络训练大小进行一些修改。此外,我有 24 个 CPU,而 AWS 上有 16 个,但 AWS 上的内存更多。在 999 美元/月,这是最有意义的重载,我会提前 5 个月出来。
如果你愿意围绕你的工作流程设计一些管道代码,并使用一些 AWS 专有技术,你可以通过使用 SageMaker 节省大量的 AWS 费用。我在这里不考虑 SageMaker 或 straight up EC2 实例,因为我正在寻找与我刚刚构建的系统最接近的桌面体验。
缩小比例
我敢肯定,阅读这篇文章的人都觉得我在这台机器上花了太多或太少。我曾经使用过基于特斯拉 V100 的先进系统,其造价是这台机器造价的 5 到 10 倍。如果你想少花钱,有很多选择。
其中最简单的就是审美。RGB 在系统构建者使用的组件中非常流行。你可以在下图中看到我的系统上的一些 RGB。不熟悉 RGB?任何发光的都是 RGB。
在计算机内部,发光的 RGB 组件
我是一个 Youtuber 用户,所以电脑是我“生活”中一个有趣的组成部分如果你打算把机器塞到桌子下面,买一个便宜但容易拿的箱子,不要用 RGB 组件。在这个构建的当前阶段,我在 RGB 方面有点失败。我有一个非常漂亮的 RGB RAM,被我真正有效的博格方块形状的“安静”冷却器所掩盖。不久的将来,我可能会把它换成液体 AIO 冷却器。
您可以缩减的零件:
- 硬盘速度:实际上,硬盘速度只是将数据加载到 RAM,一旦数据进入 RAM,硬盘速度就变得不那么重要了。
- RAM 速度:较慢的 RAM 也能让你过关。可能反正大部分处理都是在 GPU 上完成的。
- CPU:对于机器学习来说,内核越多越好。内核越少,性能越差。
- GPU : CUDA 内核决定你的 GPU 训练速度。GPU 内存决定了您需要对批处理和网络结构进行多大程度的切割才能运行某些东西。你不一定需要一个泰坦 RTX。
已完成构建的 YouTube 视频
我在 YouTube 上制作了这台电脑的视频。我的侄子内森协助建造。你可以在这里看到这个视频。
展望未来,我现在期待着对这个 GPU 进行基准测试,并使用它为我的 GitHub 资源库和 YouTube 频道制作出色的示例。请考虑关注我,查看所有最新内容。
使用 Python 构建条形码/QR 码阅读器
使用 Pyzbar 库的简单且可实际操作的机器学习项目
马库斯·温克勒在 Unsplash 上的照片
在这篇文章中,我将向你展示如何使用 Python 来构建一个条形码和二维码阅读器。这是一个很好的机器学习项目,可以从计算机视觉开始。在我以前的文章中,我展示了如何使用 python 来识别人脸和文本。这些都是锻炼你技能的好项目。今天,我们将介绍一些稍微不同的东西,那就是条形码和 QR 码阅读器。
我认为条形码/二维码非常酷和有趣,因为它们以不同的格式存储信息。有趣的是,在我们扫描它们之前,我们无法真正知道它们存储了什么。就像玩益智游戏一样。我喜欢它们的另一点是,它们可以成为现实世界的一部分,并且仍然将我们与互联网世界联系在一起。这不是很酷吗?
目录:
- 入门
- 库
- 解码功能
- 主要功能
- 视频演示
使用 OpenCv 库进行实时人脸识别的分步指南
towardsdatascience.com](/building-a-face-recognizer-in-python-7fd6630c6340)
入门指南
如果您想知道条形码和二维码阅读器是如何工作的,让我们做一个快速的实际练习。打开手机摄像头,显示这篇文章的特色图片。你会看到一个链接显示出来,这是非常简单的使用。今天,我们将创建我们自己的阅读器,马上开始吧!
我们将从安装这个项目所需的库开始,然后开始编程。对于这个项目,我建议使用常规的代码编辑器,而不是 Jupyter 笔记本。
图书馆
在这一步,我们将安装以下三个库:Pillow、OpenCV 和 Pyzbar。枕头库也被称为 PIL,代表 Python 图像库。OpenCV 是一个众所周知的库,尤其是在处理计算机视觉项目时。最后是 Pyzbar,它是一个 python 库,可以帮助我们读取条形码和二维码。让我们开始安装它们。
枕头
官方文件可以在这里找到。
pip install Pillow
OpenCV
OpenCV(开源计算机视觉库)是一个开源的计算机视觉和机器学习软件库。OpenCV 旨在为计算机视觉应用提供一个公共基础设施,并加速机器感知在商业产品中的应用。
参考:【https://opencv.org
pip install opencv-python
皮兹巴尔
Pyzbar 库的安装因您使用的计算机而异。我将显示 Mac OS 和 Windows 安装行。你也可以从 Pyzbar 的官方文档页面了解更多。
# Mac OS version
brew install zbar# Windows OS version
pip install pyzbar
解码功能
在这一步,我们编写解码函数,大部分酷的事情将在这里发生。解码功能将主要做三件事,可列举如下:
- 识别和解码我们将展示给摄像机的条形码/QR 码。
- 将存储的信息作为文本添加到识别的条形码/QR 码上。
- 最后,将存储的信息导出为文本文档。
让我们在写入函数之前导入我们安装的库:
#import librariesimport cv2
from pyzbar import pyzbar
现在,让我们写函数。我不会一部分一部分地添加,而是将整个功能分享给你。因为在用 python 编写时缩进很重要,所以我不想通过破坏代码的结构来打乱事情。我将在代码下面添加我的注释。
def read_barcodes(frame):
barcodes = pyzbar.decode(frame)
for barcode in barcodes:
x, y , w, h = barcode.rect #1
barcode_info = barcode.data.decode('utf-8')
cv2.rectangle(frame, (x, y),(x+w, y+h), (0, 255, 0), 2)
#2
font = cv2.FONT_HERSHEY_DUPLEX
cv2.putText(frame, barcode_info, (x + 6, y - 6), font, 2.0, (255, 255, 255), 1) #3
with open("barcode_result.txt", mode ='w') as file:
file.write("Recognized Barcode:" + barcode_info) return frame
了解功能:
- 首先,我们从条形码或 QR 码中解码信息。然后在它周围画一个矩形。这有助于我们了解我们的机器是否检测到条形码/二维码。
- 其次,我们在创建的矩形上添加文本。文本将显示解码的信息。
- 第三,我们将信息导出到文本文档中。如果您计划使用多个条形码或 QR 码进行测试,我建议您更改文档名称,否则它会被覆盖。
主要功能
在这一步中,我们将编写主函数,其中应用程序被提示工作。main 函数将打开计算机的摄像机,然后调用解码函数。代码如下:
def main(): #1
camera = cv2.VideoCapture(0)
ret, frame = camera.read() #2
while ret:
ret, frame = camera.read()
frame = read_barcodes(frame)
cv2.imshow('Barcode/QR code reader', frame)
if cv2.waitKey(1) & 0xFF == 27:
break #3
camera.release()
cv2.destroyAllWindows()#4
if __name__ == '__main__':
main()
了解功能:
- 首先,我们使用 OpenCV 打开计算机的摄像头。如果您有一个外部摄像头,您必须根据设备将值 0 更改为 1。
- 其次,我们运行一个 while 循环来继续运行解码功能,直到按下“Esc”键。否则,循环将不会停止并导致一些问题。
- 第三,我们正在释放我们在第一步中打开的摄像机。然后我们将关闭应用程序窗口。OpenCV 正在做所有的工作,我们只需要调用方法。
- 最后,我们调用主函数来触发程序。
完美!我们已经完成了编程部分。让我给你看一个快速演示,看看我们运行程序时它是如何工作的。
视频演示
测试程序
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
lifexplorer.medium.com](https://lifexplorer.medium.com/membership)
恭喜你。!您已经创建了一个程序,可以为您读取条形码和 QR 码。现在,你已经知道如何在现实生活中使用计算机视觉和人工智能。从事像这样的动手编程项目是提高编码技能的最好方式。如果你今天学到了新东西,我会很高兴。
如果您在执行代码时有任何问题,请随时联系我。
关注我的博客和 youtube 频道以获得灵感。谢谢你,
使用 GitHub 创建漂亮的静态网页
查找模板和为静态网页创建表单的位置
使用 GitHub Pages 托管的我的个人网页
你有没有想过建立自己的网页?也许你对 HTML 有一些经验(你好 Myspacers),也许你没有。这篇构建自己网页的教程是对 GitHub 页面教程的延伸。本文将介绍从哪里获得 HTML 模板以及如何创建动态表单,以便其他用户可以在您的 GitHub Pages 站点上连接到您。如果你正在经营一个有大量网络流量的大企业,我不推荐使用 GitHub 页面,因为静态网页的功能有限。对于个人网页或小型企业,GitHub 页面是一个很好的选择。TL;博士在总结的底部。
创建网站的步骤
- 查看该域名是否可用:我推荐使用域名搜索工具,比如 Whois.net。此工具允许您查看该域是否可用或谁拥有该位置。有些域名不包括域名所有者信息,而是有域名托管站点的联系信息。
- 购买域名:你可以通过任意数量的网站购买可用的域名。我会避免购买域名从另一个人或更糟,域名停车公司。
- 设置 GitHub: 对于不熟悉的人来说, GitHub 是一个版本控制的代码库。简单来说就是云端的代码备份。您可以注册一个电子邮件地址,并完成如何创建存储库的教程。存储库是你存储网站资料的地方。一旦您能够创建一个存储库,您将添加您的模板材料。在创建模板之前,我们可以将存储库连接到 GitHub 页面。为此,请单击位于存储库屏幕右上角的设置选项卡。向下滚动到标题为 GitHub 页面的部分。编辑 Source 选项卡,将存储库附加到 Github 页面。再次向下滚动到 GitHub 页面部分。您现在可以选择使用 Jekyll 添加模板。
- 编辑模板: Github 和 Jekyll 一起提供了一个简单的 HTML 模板。Jekyll 很棒,可能适合你的网站设计需求,但是我喜欢从 HTML5 到的模板。您可以下载一个模板,将其解压缩,然后通过单击绿色克隆或下载按钮旁边的上传文件按钮,将文件直接添加到您的存储库中。您可以通过简单地拖放文件将模板直接添加到存储库中。编辑模板以个性化您的网页。
- **将您的存储库连接到您的域(棘手的部分):再次点击 settings 选项卡,向下滚动到 GitHub 页面。在自定义域部分输入您的域,然后单击保存。此更改将在您的存储库中创建一个 CNAME 文件。转到您购买域名的网站,并导航到您可以管理域名设置的位置。你正在寻找一个像 CNAME,A,或 NS 项目的屏幕。将 CNAME 更改为指向您的 GitHub 页面库。这个名字可以在 GitHub Pages 部分的文本“自定义域允许您从
*your-repository.github.io*
*以外的域为您的站点提供服务”下找到。*您可以将 A 名称更改为指向 GitHub Pages 服务器。我会把 GitHub A 的四个名字都加上:185.199.108.153 | 185.199.109.153 | 185.199.110.153 | 185.199.111.153
。在 GitHub 页面标签下有一个强制 HTTPS 的复选框。出于安全原因,如果可以,请选中此框。 - 在静态网页上创建动态联系表单: GitHub 页面非常适合静态网页(也就是说,如果你不做更改,它们就不会更新),但是,如果你想添加一个需要第三方帮助的联系表单。查看 Formspree.io,了解如何向 html 文档添加表单模板的教程。基本上,你用 html 创建一个表单或者使用他们的模板,然后指向你的账户链接。html 将包括类似于
<form action="https:formspree.io/yourformlink" method="POST"
的东西,后跟你的表单和 html 标签来关闭所有东西。下面是一个 HTML 格式的示例要点。
概述
这就是使用 Github Pages 创建个人网页的要点。探索杰基尔和 HTML5 UP 上的一些模板。对于那些想要一些动态内容的人来说,比如联系方式,使用第三方如forms spree . io将你的电子邮件链接到静态网页。我用这些方法创建的网站包括我的个人网站codyglickman.com和我的初创公司 Data Dolittle 的网站datadolittle.com。感谢 Formspree.io 的 Cole 让我在静态页面上创建 html 表单变得简单。你可以在 LinkedIn 上找到我。感谢您与本文互动!如果您有任何问题或意见,请留言或通过我的个人网站与我联系。
从头开始构建图书推荐引擎并将其部署到 Web 应用程序中
概述了在完全部署的 web 应用程序中使用 Spark、Databricks 和 Flask 的分布式计算构建图书推荐系统的过程。
不管我们喜不喜欢,电子商务系统正在渗透我们生活的方方面面。从你的网飞个人资料上的标题下的一长串节目和电影,到 Spotify 上的为你制作的歌曲列表,我们已经进入了一个内容、媒体和信息都是根据我们独特的兴趣定制的时代。
虽然这可能是常识,但可能不太明显的是在幕后发生了什么来向用户提供这些推荐。我们经常听说“算法”和“机器学习”构成了这些系统的主干,但除此之外,我们通常将其余部分留给想象。
最近在研究生院上了一堂推荐系统课后,我开始钻研这些引擎背后的线性代数和软件。在课程的最后两周,我觉得我已经有足够的知识来构建一个完整的生产 web 应用程序,利用 PySpark 的分布式计算能力 、 PostgreSQL 、 Databricks 和 Flask 向用户推荐书籍。
如果对改编项目感兴趣,可以在我的 GitHub 上找到代码,并且可以在单独的 repo 中找到我的最终项目的描述,包括探索性分析和 ALS 算法在生产中的示例。
我也在这篇文章的末尾添加了网络应用程序链接,但是如果你想创建一个帐户,并开始对书籍进行评级/接收书籍推荐,你可以在这里加入:https://zach-book-recommender.herokuapp.com/。
推荐系统如何工作?
现在,在我们看一看我自己的引擎之前,提供一些关于这些系统的总体主题的背景可能是有帮助的。在非常基本的层面上,推荐系统通过机器学习算法来运行。通常,这些算法可以分为两类——基于内容的和协同过滤。
基于内容的方法测量项目属性的相似性,并根据用户以前的行为或明确的反馈(即通过调查或评级)重点推荐与用户喜欢的类似的其他项目。
尽管基于内容的方法在某些情况下非常有效,但它们也有缺点。协同过滤方法操作方式不同,尽最大努力解决基于内容过滤的一些局限性。通过协同过滤,算法同时使用用户和项目之间的相似性来提供推荐。本质上,底层模型被设计为基于相似用户 b 的兴趣向用户 A 推荐一个项目
降维和矩阵分解
协同过滤可以通过多种方式实现,然而,一种常见的方法是使用矩阵分解和维度缩减技术。交替最小二乘法(ALS)、奇异值分解(SVD)和随机梯度下降(SGD)等算法在这方面做得很好,当处理大量数据(即 1M 以上的数据点)时,这些算法与分布式计算和并行处理相结合,是构建具有大量数据的生产就绪型应用的良好解决方案。
如果您有兴趣了解更多关于这些技术的知识,我推荐您阅读这些优秀的 TDS 文章:
- 为 交替最小二乘
- 为 奇异值分解
- 为 随机梯度下降(SGD)
有了这些算法如何工作的一些基本知识,我将投入到我自己的项目中,使用 ALS 向用户提供图书推荐。
我的应用程序如何工作
在深入构建应用程序的每个组件之前,我将概述它如何工作的总体流程,以及在 Flask web 应用程序中向用户提供推荐所使用的技术:
将我的 Flask 应用程序与 PostgreSQL 和 Databricks 集成,每小时运行一次我的 ALS 模型,向用户提供图书推荐|作者图片
正如我们所看到的,这是一个非常复杂的系统,它严重依赖 Spark 中的分布式计算来处理大约 100 万本书的评级,并每小时为用户计算更新的推荐。它还依赖于部署的 PostgreSQL 数据库和包含我的 ALS 算法的 Amazon Web Services 集群之间的重要连接。
有了上面建立的总流程,我们现在可以分解构建引擎的每个步骤。
识别用于最大似然计算的高质量用户项目数据集
作为第一步,必须找到一个大的用户手册数据集,它将与我选择的算法很好地配合,并将向用户提供可靠的预测和建议。
所以我做了一些探索性的分析,决定用goodbooks-10k dataset**。**根据 Kaggle 的说法,这个数据集包含了一个流行图书平台 Goodreads 上的 1 万本不同书籍的近 100 万个评分。有了这个数据集,我注意到了一些事情:
- 该数据集包含总共 53,425 个用户,他们为至少 10 本书提供了评级。
- 图书的平均评分约为 3.85 分,在李克特量表 1 到 5 分中,4 分是最常见的。因此,大多数评级都相当正面。
- 正如所料,数据集非常稀疏( ~99.82%的评级文件为空白)。
- 数据集中一些最受好评的书籍是家喻户晓的,包括部分卡尔文和何拔斯的收藏、哈利波特,以及一些带有宗教原则的书籍。
要考察一些这种探索性的分析,你可以去 本 jupyter 笔记本 。
构建和部署网络应用
接下来,在做了一些探索性分析之后,我决定构建一个简单的 python Flask 应用程序 ,以便允许新用户做以下事情:
- 使用特定用户名注册/登录
- 加载一个个人资料页面,该页面显示用户已评级书籍的历史记录,并提供导航以对更多书籍进行评级或查看推荐书籍(参见下面的示例):
图书推荐者个人资料页面|作者图片
- 加入一个搜索功能,它与 Goodreads API 交互,允许用户按书名搜索一本书,然后在 1-5 的范围内给这本书打分(见下面的例子):
在 web 应用程序|作者图片中提交评级
- 在对几本书进行评级后,用户可以在单独的页面上看到他们的个性化推荐(将在本文后面显示)。
值得注意的是,这些来自应用程序的用户评级随后被合并回稳健的 goodbooks 数据集,并最终合并到 ALS 算法中。通过建立 PostgreSQL 数据库,我能够将新的用户 id、他们的评级和图书 id 与这个原始数据集进行匹配。因此,每当一个新的评级来自一个用户,它就被附加到我后来用于推荐引擎的评级数据集中。
在本地做了大量测试以确保图书 id 和用户 id 在数据库中匹配之后,我用 Heroku 部署了应用程序。
用于 Flask 和 PostgreSQL 部署的资源
关于如何使用 Heroku 部署 Flask 应用程序和相应的 PostgreSQL 数据库的说明,您可以 参考这个非常有用的 YouTube 教程 ,作者是 Brad Traversy 。使用 Heroku 部署的细节也可以在这个 中找到 。
使用 Databricks 和 PySpark —开发我的 ALS 算法
随着应用程序功能的设置和部署,我使用 Databricks 和 Pyspark 构建了一个交替最小二乘(ALS)算法,该算法从我的 PostgreSQL 数据库中吸收我的评分数据集,根据 Databricks 中建立的矩阵分解技术计算更新的预测,然后根据每个用户的最高预测分数向每个用户推荐图书。
下面的一小段代码概述了这一过程:
首先,在从 PostgreSQL 读取 ratings 表之前,我为 Spark 数据帧设置了一个模式:
**from** **pyspark.sql.types** **import** StructType, StructField
**from** **pyspark.sql.types** **import** DoubleType, IntegerType, StringType
ratings_schema = StructType([
StructField("col_id", IntegerType()),
StructField("userid", IntegerType()),
StructField("rating", DoubleType()),
StructField("book_id", IntegerType()),
StructField("username", StringType()),
StructField("isbn10", StringType())
])
然后,在设置了我们的环境变量和到我的远程 PostgreSQL 数据库的 JDBC 连接之后,我读入表并将其保存为 Spark 数据帧:
remote_table = spark.read.format("jdbc")\
.option("driver", driver)\
.option("inferSchema", ratings_schema) \
.option("url", url)\
.option("dbtable", table)\
.option("user", user)\
.option("password", password)\
.load()
将 Spark 数据帧加载到 Databricks 后,我开始设置数据来运行我的 ALS 模型。首先,我将数据框架分成训练、验证和测试数据集——60%训练,20%验证和 20%测试。验证数据集用于测试我的模型参数的微调,并允许我有一个保留测试集,用于计算最终优化模型的均方根误差(RMSE)。
(training, validation, test) = remote_table.randomSplit([0.6, 0.2, 0.2]) *# caching data to cut down on cross-validation time later* training.cache()
validation.cache()
test.cache()
通过数据分割,我对模型进行了一些微调,以确定最佳参数。然后,我用这些最佳参数运行 ALS 模型,并将其拟合到训练数据集。
als = ALS(maxIter=10, regParam=0.20, userCol="userid", itemCol="book_id", ratingCol="rating", coldStartStrategy="drop", nonnegative = **True**, implicitPrefs = **False**).setRank(50)model = als.fit(training)
您会注意到,我将矩阵的秩设置为 50,这减少了处理时间,并且仍然产生有价值的预测。然后,我能够使用这个模型来计算测试数据集的预测,并确定 RMSE 值。
predictions = model.transform(test)
rmse = evaluator.evaluate(predictions)
最后,我能够得到大约 0.9 的 RMSE 值,这对于我们的目的和 1-5 的李克特量表来说,还不算太差。然后,我能够使用该模型为完整的评级数据集生成预测和建议。为此,我使用 PySpark 中的recommendForAllUsers()
函数,为每个用户找到 10 本评分最高的书。
ALS_recommendations = model.recommendForAllUsers(numItems = 10)*# Temporary table* ALS_recommendations.registerTempTable("ALS_recs_temp") clean_recs = spark.sql("""SELECT userid, bookIds_and_ratings.book_id AS book_id, bookIds_and_ratings.rating AS prediction FROM ALS_recs_temp LATERAL VIEW explode(recommendations) exploded_table AS bookIds_and_ratings""")clean_recs.join(remote_table, ["userid", "book_id"], "left").filter(remote_table.rating.isNull()).show()
clean_recs_filtered = clean_recs.select("userid", "book_id", "prediction")
在创建了一个临时表来重定向推荐之后,我希望确保用户在应用程序中评价(并隐式阅读)的书籍不会在应用程序中被推荐给他们。因此,我做了一些额外的清理,只向用户推荐新书:
new_books = (clean_recs_filtered.join(remote_table, ["userid", "book_id"], "left").filter(remote_table.rating.isNull()))
最后一步,我只确定了通过我的应用程序注册的用户 id,以便将推荐附加回 PostgreSQL 数据库。因为最初的 goodbooks 数据集中有如此大量的预测和评级会返回到不存在的用户,所以我过滤了这些数据,只包括对通过 web 应用程序加入的用户的推荐:
new_books_fnl = new_books.select('userid', 'book_id', 'prediction')
new_books_users = new_books_fnl.filter(new_books_fnl['userid'] > 53424)
new_books_use = new_books_users.select('userid', 'book_id', 'prediction')
下面是一个向加入 web 应用程序的用户反馈建议的示例:
将在 web 应用程序|作者图片中推荐给用户的图书快照
我们现在在 web 应用程序中为用户提供了推荐!
正如我们所看到的,一些预测并不是很好——例如,表中的第一个用户将收到一本书,该算法预测他们的评分约为 3.5/4。理想情况下,我们希望找到用户真正喜欢的书(不考虑意外收获、新奇感等因素)。).所以,有了更多的时间和更广泛的用户基础,我希望看到预测评分更高的推荐书籍。
随着模型在 Databricks 中本地工作,我能够上传这个优化的模型并将其部署到 Amazon Web Services 集群,每小时运行一次 cronjob 来处理任何吸收到我的 PostgreSQL 数据库中的新评级。每小时一次的 cronjob 基本上会重新运行模型,重新计算预测和建议,然后用更新后的建议覆盖我的 PostgreSQL 中的建议表。然后,它会连接回我的 Flask 应用程序,为用户提供服务。关于 AWS 和数据块、、的部署说明,你可以在这里、找到一些文档。
我的 PostgreSQL 中的推荐表用我的推荐和它们对应的图书 id 更新后,我就可以利用 Goodreads API 来查找图书信息(例如图片、书名等)。)来构建前端应用程序。
那么,它的效果如何呢?
最后,我做了一些测试,注意到这些推荐并不太糟糕!例如,我创建了一些狂热的数据科学用户,并对许多数据科学书籍进行了评级。我有意让不同用户对书籍的评价有所重叠,但也试图为每个用户评价几本新书。
当我运行我的模型来提供推荐时,我很高兴地看到,没有被一个数据科学狂热者评级的书籍被推荐给了另一个数据科学狂热者的正面评级,这表明我的协作过滤技术正在起作用。请参见下面的示例:
一些数据科学读者的推荐页面示例|作者图片
正如我们从红色方框中的标题可以看到的,用户 2 对这两本书的评价非常高(评分为 5)。因此,当运行我们的机器学习算法时,用户 1 和用户 2 的书籍评级之间存在一些重叠——这意味着没有被用户 1 评级(并且隐含地没有被阅读)但被用户 2 评级很高的书籍被作为推荐给用户 1。
自己试试吧!
要尝试这个应用程序,请点击这里:https://zach-book-recommender.herokuapp.com/
尽管数据科学书籍的推荐看起来确实非常有效,但在其他类型和主题方面存在很大差距。您可能会注意到,您的推荐还会从 goodbooks-10k 数据集中引入其他评价非常高的书籍(例如卡尔文和霍布斯等)。),直到有更多和你口味相似的用户加入 app。因此,我建议与朋友分享,看看随着时间的推移,你的建议是否会越来越好!
连接
如果你喜欢这篇文章,或者觉得它有帮助,请联系我们!我喜欢在项目上与其他人合作,并向对数据科学工作充满热情的同行学习。
你也可以看看我的数据可视化作品集,在那里我主要使用 Javascript 和 D3.js,并谈谈我在研究生院完成的其他项目。
为我蹒跚学步的孩子制作一个播放视频的机器人
使用一个物体检测人工智能模型、一个游戏引擎、一个亚马逊 Polly 和一个在英伟达(NVIDIA)Jetson Nano 上运行的 Selenium automation 框架来构建 Qrio,这是一个可以说话、识别玩具并在 YouTube 上播放相关视频的机器人。
我和我妻子有一个超级好奇的 21 个月大的男孩,名叫德歇。虽然他还不会说话,但他真的很喜欢指着东西让我们告诉他是什么。它可以是他最喜欢的书里的一张动物图片,他卡片上的一张汽车图片,或者只是一个玩具。我喜欢和他一起做这项活动,最近我一直在给他看描绘老虎、海豚、火车和其他有趣事物的视频。他真的很喜欢看一只真正的老虎如何走路、吼叫和社交,我认为这对他的认知发展有好处。
德协指着一个飞机的机翼,一条鲸鱼和一个拉面!
有一天,我想到给他造一个机器人,可以和他一起玩这个指点游戏。不要误解我的意思,我们的目标不是取代我们,而是补充我们,让他尽早接触技术。
概念
经过一段时间的头脑风暴,我清楚地知道我想要建造什么。这是一个有着狗的外形的聊天机器人,狗是德西最喜欢的动物。她的名字叫 Qrio,是“问题”和“好奇”两个词的混合。在我为他买玩具的一年半时间里,我观察了他一直玩的玩具和不玩的玩具,我发现玩具越能模仿他能与之建立联系的生物(在这种情况下是一只狗),它成功的机会就越高。
为了最大限度地提高凝聚力,Qrio 以我们已故的爱犬百事可乐为模型,德克斯特在第一年就与百事可乐建立了关系。
百事和 Qrio
Qrio 将能够看到 Dexie 走过,并对他说:‘嗨,Dexie!你想过来给我看看你的玩具吗?接下来,当德茜拿起一个飞机玩具给她看时,她会继续说‘嘿,那是一架飞机。‘我给你放一段关于飞机的视频’,然后找一段飞机视频给他播放。
研究
为了实现上述目标,Qrio 需要具备以下模块:
- 视线。Qrio 必须确认 Dexie 和他携带的玩具。为此,我需要一个连接到人工智能系统的摄像头,以检测德歇和他的玩具的存在和位置。需要建立一个经过训练可以识别人脸和玩具的物体检测人工智能模型,该模型将在连接到摄像头的 GPU 驱动的设备上运行。
- 视觉存在——以虚拟狗的形式出现,它将与德歇互动。它将由显示在显示器上的虚拟木偶系统驱动。
- 语音,这样 Qrio 就可以和他打招呼,让他拿起一个玩具,说出玩具的名字等等,这需要一个文本到语音的技术,显然还需要一个扬声器。
- 视频搜索和播放,这样 Qrio 就可以在 YouTube 上搜索并播放一个相关的视频。这将由自动化工具驱动。
- 所有组件的协调者。
经过一番认真的研究,我列出了运行该系统所需的硬件清单。
- NVIDIA Jetson Nano(150 澳元)。这是一个微小的 GPU 驱动的嵌入式设备,将运行所有模块(特别是对象检测人工智能模型)。这是一个完美的工作设备,因为它可以通过一个简单的 HDMI 端口支持视频和音频输出,并且它有一个以太网端口,方便互联网接入。你甚至可以插入鼠标和键盘,在设备上进行开发和调试,因为它有一个功能齐全的 Ubuntu 18.04 操作系统。
- 电视(带 HDMI 输入和内置扬声器)(150 澳元)。这样 Dexie 就可以看到 Qrio,听到她在说什么,还可以播放 YouTube 视频。
- 相机——索尼 IMX219 ($AUD 35)。这是一个令人敬畏的微型 800 万像素摄像头,使 Qrio 能够识别 Dexie 和他的玩具。画质超赞,价格惊人的便宜。
NVIDIA Jetson Nano 和索尼 IMX219 摄像头
履行
有了一个可靠的计划,我开始完成我的使命。
建筑景观
首先,需要开发和训练一个对象检测组件来识别特定的人脸和玩具。请记住,NVIDIA Jetson Nano 的 GPU 不如 1080Ti 等桌面级 GPU 卡强大,因此选择一种在准确性和性能之间取得良好平衡的对象检测模型架构至关重要。首先,我决定了我能接受的最低每秒帧数(FPS)。然后,我逆向工作,寻找可以在 Jetson Nano 上提供这种 FPS 的模型。我选择了 8 FPS,实际上,当视频处理、文本到语音、虚拟木偶戏渲染等同时运行时,它将下降到大约 5 FPS。每秒少于 5 次检测将显著降低获得高质量捕捉的机会,在高质量捕捉中,Dexie 的脸和他的玩具清晰可见。获胜的模型架构是ssdlitemobilentv 2,它运行在 TensorFlow 1.8 对象检测 API 上。
我只用了四个类来训练这个模型:一张人脸和三个 Dexie 的玩具(飞机、火车和熊猫)。所有训练集图像(每类 150 个图像)都是从使用同一台索尼 IMX219 摄像机记录的视频文件中生成的。为了最大限度地提高检测精度,并确保照明和背景是一致的,它们是在我将运行该系统的同一个客厅中拍摄的。这三个玩具都是从视频中手动、费力地贴上标签的。然而,为了保持理智,我使用了 Amazon Rekognition ,这是一种现成的对象检测云服务,可以自动标记所有人脸。
人脸和玩具检测训练装置
视频录制是使用 GStreamer 完成的,通过执行下面的命令就可以轻松完成。以低 FPS 录制会导致最终视频中出现明显的运动模糊,并产生低质量的训练集。因此,我将录制帧速率设置为 120 FPS,稍后使用视频编辑工具对其进行向下采样。记录尺寸设置为 720x540,这已经足够了,因为我们的对象检测模型只能在 300x300 像素上运行,任何更大的图像在训练和推断期间都会自动调整为 300x300 像素。
*gst-launch-1.0 nvarguscamerasrc num-buffers=120000 ! 'video/x-raw(memory:NVMM),width=720, height=540, framerate=120/1, format=NV12' ! omxh264enc ! qtmux ! filesink location=out.mp4 -e*
我使用了 EVA ,一个伟大的免费物体检测标签工具,你可以安装在本地,并可以导入一个视频文件作为图像源。
训练在五个小时内完成,使用的是在实现 mAP=0.8 的 P3.2XLarge (Pascal V100)上运行的 AWS EC2 深度学习 AMI 。Mean Average Precision (mAP)是一种用于评估对象检测性能的指标,通过计算在各种 iOU 阈值上平均的精度/召回曲线下的面积来进行。这需要一个完整的博客帖子来解释,所以我会简单地让你看一下物体检测博客的地图。否则,你只需要相信我,0.8 的贴图已经很好了,而且还可以通过聚合几帧的检测来进一步改进。
培训统计
一旦你刷新了设备,在 NVIDIA Jetson Nano 上部署和运行这个模型是非常简单的(按照步骤这里),因为它运行的是全功能的 Ubuntu 18.04。我的意思是你可以安装 Tensorflow,Object Detection API 和所有的 Python 依赖项,就像在你的笔记本电脑或 PC 上一样。我使用 Tensorflow 1.8 是因为在写这篇博客的时候,由于缺少 contrib 依赖项,Tensorflow 2.0 不支持对象检测 API。
GStreamer 和 OpenCV 框架用于连接到摄像机并从摄像机获取视频。从那里,我们只需要将捕获的图像直接传递给我们的对象检测模型。请看这里的代码示例。
我设法让物体检测以 10 FPS 的速度运行,这超过了我的最低要求 8 FPS——并且具有相当好的检测精度!
目标检测结果
建立视觉存在
获得正确的视觉呈现组件至关重要。Qrio 必须有吸引力,更重要的是,看起来足够像一只真实的,活着的狗,让 Dexie 想和她一起玩。她的眼睛需要能够直视德谢的脸,无论他在哪里。像一只正常的狗一样,当她不与德西互动时,她需要通过摇尾巴,移动头部和随意看方向来坐立不安。作为一名 3D 动画程序员,我在一家专门从事面部动画和虚拟木偶戏的电影特效公司工作了五年,在这五年的美好时光中,我学到了如此宝贵的技能,对此我感激不尽。我现在需要的只是一个游戏引擎!
几个小时的挖掘让我找到了这个叫做 arcade 的可怕的 Python 框架,它拥有我需要的一切。嗯……差不多,我稍后会讲到这个。它支持游戏动画循环,能够渲染/显示带有旋转和缩放的精灵(PNG 透明图像)。由于该框架基于 OpenGL,NVIDIA Jetson Nano 的速度性能应该非常出色,因为它将进行 GPU 加速。
街机 python 游戏引擎
为了让 Qrio 身体的各个部分(耳朵、眼球、眉毛、头和尾巴)既能独立运动又能作为一个群体运动,需要将单独的精灵组装起来(例如,移动头部也会移动耳朵、眉毛和眼球)。我需要建立一个骨骼动画系统(SAS ),它允许你将几个物体以层次关系连接在一起(例如,头部是身体的孩子,而耳朵、眼睛和眉毛是头部的孩子)。因此,当您对一个对象应用变换(旋转、平移或缩放)时,它也会影响它的所有子对象。
大多数游戏角色,人类,动物,怪物,就像下面动画中的一样,都是用 SAS 制作的。
全身骨骼动画系统
大多数游戏引擎原生支持 SAS 然而,街机没有。由于我找不到替代框架,我决定从头实现 SAS 功能,这实际上并不难。我需要做的第一件事是建立一个存储所有精灵(耳朵、头、眉毛等)的树形数据结构。)并根据它们的关系连接它们的关节。接下来是构建一个 SAS 分层转换函数。这涉及到一点三角学和矩阵。如果你热衷于了解数学细节,你可以在这个博客中阅读。
下图展示了 Qrio 的 SAS。第一幅图像显示了如何使用精灵来定义每个身体部位,这些部位是按层次组合的,如下一幅图像所示。每个身体部位也将有一个定义为旋转中心的关节。最右边的图像显示了围绕其关节应用于右耳的变换(旋转),并且没有其他身体部位受到影响,因为右耳没有任何子体。下图描绘了围绕其关节应用于头部的旋转,它影响了眉毛、眼球和耳朵。注意标记显示右耳也相应地绕着头部关节旋转。
Qrio 的骨骼动画系统
为了完成视觉呈现模块,我需要建立的下一个东西是一个坐立不安的动画系统,它是基于一个简单的关键帧动画。关键帧动画允许您通过提供对象的初始和最终变换(位置、缩放和旋转)以及动画的持续时间来设置对象(如头部)的动画。系统对从初始值到最终值的变换进行插值。接下来,我定义了几个坐立不安的动画,比如耳朵的上下运动,头尾的旋转,眼球和眉毛的运动。每一个小动作都用随机选取的值(旋转/平移)、持续时间和频率使相应的对象从一个变换到下一个变换产生动画,以便看起来更自然。
我花了几个小时调整坐立不安的动画参数,最终得到我想要的结果。
Qrio 的坐立不安动画系统
最后,我添加了一种方法来按需覆盖眼球和眉毛的位置,方法是手动提供它们的位置,这是头部跟踪逻辑在稍后阶段跟随 Dexie 的脸的位置所需要的。
大厦演讲
随着她的视力和视觉呈现模块的完成,她接下来需要的是语言能力。经过几个小时的研究,我能找到的最好的免费离线文本语音转换应用是 pyttsx3 。该引擎支持一些驱动程序,但 Ubuntu 上唯一可用的驱动程序是 espeak,它的语音质量最糟糕。这听起来像已故的斯蒂芬·霍金的轮椅(无意冒犯)。Dexie 目前正处于重复我们说的每一句话的阶段,我最不希望他学会那样说话。查看以下内容,做自己的评判。
ubuntu OS 上的 pyttsx3、espeak 驱动程序产生的音频质量不佳
放弃线下发行后,我开始寻找线上发行。我登陆了亚马逊波利。玩了几分钟后,我完全被迷住了。语音质量提高了 100 倍,没有明显的延迟,尽管它需要通过互联网进行 API 调用,以生成并从云中下载结果音频文件。这最初是我主要关心的问题。生成 7 秒钟的音频文件只需要 200 毫秒。我知道这不是一个免费的解决方案。然而,它可以被大量缓存,因为 Qrio 最多只需要说出 50 个不同的句子,我们只需要支付 50 次亚马逊 Polly 呼叫(0.08 美分)。耶!!!
亚马逊波利
建立视频搜索和播放
正如我们之前讨论的,Qrio 需要能够在 YouTube 上搜索和播放特定的视频。最好的方法是使用自动化测试套件,它可以控制 web 浏览器在 YouTube 中执行搜索,并播放搜索结果中的视频。在这里,Selenium 自动化框架来拯救我们了!
Selenium 自动化框架
这是一个 QA 通常用来测试网站的工具。它允许您编写脚本来自动完成诸如在文本字段中键入内容、按下按钮等操作。你可以猜到,我将使用它来导航到 YouTube 网站,输入像 panda 这样的搜索词,然后自动点击搜索结果中的第一个视频,并按下全屏按钮以全屏播放它。首先,您需要为 Selenium 安装一个 Chromium-chrome 驱动程序,以便能够通过执行下面的 apt-get install 命令来控制 Chromium web 浏览器(Ubuntu 18.04 附带的原生浏览器)。
sudo apt-get install chromium-chromedriver
然后,您可以使用针对 Selenium 的 python 绑定,从您的 Python 代码中以编程方式执行 Selenium 脚本。为了确保播放的视频对孩子是安全的,我用 YouTubeKids.com 而不是普通的 YouTube。这带来了一点复杂,因为每次 Selenium 启动时,您都必须通过一系列步骤来证明您是家长。然而,我设法编写了一个 Selenium 脚本,它可以自动完成这些步骤,并且只需要执行一次。
你可以在这里看到代码。
构建协调器
该模块充当协调器,将所有其他模块粘合在一起。协调器的一个关键部分是跟踪游戏当前状态的状态机。为什么我们需要一个状态机?以便我们在接收到相同的事件时可以根据我们当前所处的状态做出不同的决定。例如,如果之前 Qrio 还没有看到 Dexie,看到一个飞机玩具本身不应该触发播放 YouTube 视频的调用,因为它可能是玩具飞机就在沙发上的情况。在播放完飞机视频后看到一个飞机玩具应该会让 Qrio 说‘嘿,我们以前玩过飞机。“你为什么不给我带点别的东西来,”这样,我们可以避免让 Qrio 一遍又一遍地播放相同的视频,如果 Dexie 在它之前被识别并且视频播放被触发后继续持有飞机的话。
有四种主要状态——空闲、占用、obec 识别和播放视频——如下面的状态图所示。当系统处于除播放视频之外的任何状态时,它会定期调用坐立不安动画系统来制作 Qrio 坐立不安的动画,并与视觉模块核对以获取所有可识别物体的位置。系统从空闲状态启动,如果检测到 Dexie 至少 0.5 秒(以减少错误检测),它将调用语音模块,说类似“嗨 Dexie,你想过来玩吗?”并将游戏状态设置为参与状态。
Qrio 全状态机图
此外,如果在我们处于参与模式时,可以看到一个熊猫玩具,Qrio 会说‘嗨,Dexie。我想那是一只熊猫,将进入物体识别模式。如果熊猫玩具在另外两秒钟内仍然可见,Qrio 将切换到播放视频状态,将说“让我给你播放一段关于熊猫的视频”,并将调用视频搜索和播放模块来搜索熊猫视频并播放它。然而,如果我们最近播放了一段关于熊猫的视频,它会说‘嘿,我们以前和熊猫玩过。为什么不给我带点别的?视频将只全屏播放 45 秒,而视线和坐立不安动画系统暂停,以集中 CPU 资源播放流畅的视频。视频播放完成后,浏览器窗口隐藏,视线和坐立不安动画系统恢复。当 Dexie 在接合模式下 10 秒钟不可见时,协调器将重置状态为空闲。
您还可以看到,除了播放视频之外,在任何状态下,当面部可见时,都会调用头部跟踪模块,以使 Qrio 的眼球跟随面部边界框的中心点。
设置和校准
一切准备就绪后,我在客厅安装了系统,进行最后的校准和测试。
Qrio 系统设置
初始化时,系统会顺利通过 YouTubeKids 的母授权。我看到 Qrio 的眼睛快速地跟随我的脸,这表明物体检测和头部跟踪逻辑工作得非常好。我注意到 NVIDIA Jetson Nano 已经被推到了极限,RAM 运行得非常低,设备变得非常热。这是完全可以理解的,因为它正在运行一个重型人工智能模型,仍然需要实时渲染游戏引擎,控制 Selenium 浏览器和解码视频。然而,整个系统似乎运行得很好,游戏引擎显示的基准为 5 FPS。
我现在需要的就是找个合适的时机把 Qrio 给 Dexie 看!
Qrio 系统校准和测试
表演时间
第一次看到 Qrio 的时候,是看着德谢的无价时刻。他好奇地冲向她,而 Qrio 在叫他,他站着不动,只是不相信地盯着她看了几秒钟。突然,他咯咯地笑了起来……我才知道我成功地通过了第一次测试——男孩和机器人的成功结合!
德歇第一次见到 Qrio
为了让他更加熟悉和舒适,我让他做任何他想做的事情,没有任何指导。他走向她,看着她坐立不安,摸着电视(以为他真的在摸她),甚至叫她“小狗”。
接下来是关键时刻——测试实际的游戏玩法。举个例子,我让他看我给 Qrio 展示他的飞机玩具,她完美地认出了它,并说,“嘿,我想这是一架飞机。让我给你放一段关于飞机的录像。德协看到飞机视频开始播放的时候超级兴奋!
视频播放完一次,我把一个熊猫玩具递给了德协。他模仿我,把熊猫玩具给 Qrio 看,她再次搜索并播放了一段合适的视频!你可以在下面的视频中观看整个经历。
德西第一次看到并和 Qrio 一起玩
学习和未来改进
系统还不完善。尽管它在 80%的时间里能够识别玩具并播放正确的视频,但它仍然会时不时地失败——这没什么。最重要的是,我学到了很多关于什么可行,什么不可行,为下次类似的项目做准备。
相机的 FOV
大多数故障发生在 Dexie 站得离电视太近时,这超出了摄像机的可视范围。如下图所示,相机有一个 77 度的 FOV,放置在距离电视中等距离的位置,但不是很近(红色圆圈标记的区域)。同样的问题也发生在垂直覆盖中,当他坐在地板上时,摄像机看不到他举得很低的玩具。降低相机的焦距可以解决这个问题,但会带来相反的问题,即当他站在相机附近时,看不到他的脸。
Qrio 的摄像头的水平盲点
Qrio 的相机的垂直盲点
解决这个问题的办法可能是买一台 FOV 更宽(120 度)的新相机,这样它可以覆盖更多的区域。然而,由于透镜失真,FOV 边缘周围的检测精度可能下降。
可回放性
到目前为止,Qrio sight 模块只对三个玩具进行了训练,并且总是为同一个玩具播放相同的视频。这只够娱乐德歇五分钟,直到他厌烦为止。因此,它具有低的可重复因子。我计划在未来增加对更多玩具的支持——如果我能鼓起勇气手动标记数以千计的额外图片的话。还可以添加一个随机化,从找到的前五个视频中随机选择,而不是总是选择第一个。
更快的 FPS
另一个需要改进的地方是游戏的 FPS。当视频搜索和播放模块执行 Selenium 脚本来控制 chromium 浏览器时,游戏以大约 5 FPS 的速度运行,偶尔会出现短暂的冻结和较长的冻结。你可能已经在上面的演示视频中发现了这一点。一个冻结的游戏引擎意味着 Qrio 停止移动,这不是那么好看。一个想法是将对象检测移到一个单独的线程中,这样它可以并发运行,而不会阻塞游戏引擎。同样的处理也可以应用于视频搜索和播放模块。然而,我们需要测试 OpenCV 和 Selenium 是否乐意在单独的线程上运行。除此之外,我还想测试一款更强大的设备,比如 NVIDIA Jetson NX T1,它可能更适合这种规模的项目。
就这样,伙计们!我希望你喜欢阅读我的令人兴奋的周末计划,就像我喜欢与你分享它一样。
完整的源代码可以在这里找到。
构建脑瘤分类应用程序
一个真正的机器学习应用程序,从零开始,使用 Dash
来源:https://unsplash.com/photos/rmWtVQN5RzU
在下面的文章中,我将展示一个我从零开始创建的机器学习应用程序。
1.目标
我想建立的是一个应用程序,它可以将大脑核磁共振图像作为输入。从那里,应用程序将返回一个预测,说图像上是否有肿瘤。
我发现这个想法很有趣,因为任何人都可以使用这个应用程序来确定是否存在脑瘤。不需要编码技能或关于大脑的知识。
为了实现这一目标,需要完成三个步骤,即创建预测图像类别的模型、创建应用程序以及最后部署应用程序本身。
2.构建卷积神经网络模型
CNN 是一类深度神经网络,通常用于分析视觉内容,这正是我在这里想要做的。
我用来建立 CNN 的数据来自这里的。
它包含 3264 幅脑 MRI 图像(2880 幅训练图像和 384 幅测试图像),分为 4 类:神经胶质瘤肿瘤、脑膜瘤肿瘤、垂体肿瘤和无肿瘤。
我用 Keras 建立模型。对于那些不知道的人,Keras 是一个运行在 Tensorflow 之上的高级 Python 神经网络库。其简单的架构、可读性和整体易用性使其成为使用 Python 进行深度学习时最受欢迎的库之一。
在为 CNN 导入并准备好图像后,我最终构建了以下模型。
model = Sequential()model.add(Conv2D(32, (3, 3), input_shape=(150,150,3), use_bias=False))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.25))
model.add(Dense(4))
model.add(Activation('softmax'))model.compile(loss = "categorical_crossentropy", optimizer=keras.optimizers.Adam(learning_rate=0.001), metrics=['accuracy'])
我把模型保持得非常简单。它只有两个卷积层,最末端的 softmax 层将返回 MRI 属于 4 类的概率。
然后我根据数据训练这个模型。
history = model.fit(trainData, trainLabel,batch_size = 128, epochs = 30 ,validation_data=(testData, testLabel))
这个只有 30 个历元的简单模型达到了大约 81%的准确率。那意思很明显,不要把这个 app 当做绝对真理,听医生的!
然后,通过保存模型,这意味着它可以很容易地在 Dash 应用程序中用于预测新图像。
model.save('model_final.h5')
现在这一部分已经完成,让我们继续使用 Dash 创建应用程序。
3.创建应用程序
我使用 Dash 来创建应用程序。该平台允许我们开发高质量的企业级分析应用,而不需要开发人员、JavaScript 或除了基本 Python 技能之外的任何东西。
关于如何构建 Dash 应用的完整教程,请点击这里。
我做的第一件事是导入运行 dash 应用程序和 keras 模型所需的所有包。之后,就可以构建应用程序了。这是它的完整代码。
那是相当长的,所以让我们检查一些事情。首先,names
函数的作用是根据模型的预测,给出一个特定的输出(即肿瘤的名称)。
现在,让我们来复习一下回调。它接受一个图像作为输入,即 html。来自parse_contents
函数的 Img 标签。list_of_contents[0]
意味着只有上传的第一张图片会被使用(所以上传多张图片是没有意义的)。
然后,以下代码获取 Dash 以 base64 字符串编码的图像,并使其可用于 CNN:
img_data = list_of_contents[0]
img_data = re.sub('data:image/jpeg;base64,', '', img_data)
img_data = base64.b64decode(img_data)
stream = io.BytesIO(img_data)
img_pil = Image.open(stream)
然后,用load_model
函数加载之前创建的模型,将图像转换成具有正确形状的 numpy 数组,并用answ = model.predict(x)
进行预测。这里的好处是,你可以创建任何你想要的 CNN 模型并加载它,应用程序仍然可以工作!
然后,根据该预测,给出关于图像上没有肿瘤的可能性和关于肿瘤的一些事实的第二个预测。
最后,返回 4 个输出(图像、两个预测和事实),从而结束长时间的回调。
4。Heroku 的部署
随着应用程序的创建,是时候让每个人都可以使用它了。Dash 应用程序可以部署在 Heroku 上,这是一个云应用程序平台,允许您完全免费运行您的应用程序。
要了解如何在 Heroku 上部署 Dash 应用程序,请点击右此处。
这款应用就在这里:https://brain-mri-app.herokuapp.com/。只是提醒一下,加载应用程序可能需要一段时间。这是因为它会在一段时间后进入睡眠状态(这是 Heroku 免费版的少数不便之处之一)。
这里有一个简短的 GIF 展示了该应用程序应该如何使用。正如您将看到的,这非常简单:
你可以用任何健康大脑的 MRI 图像,或者有神经胶质瘤、脑膜瘤或垂体瘤的大脑图像来尝试。例如,这是一张脑膜瘤的图像,你可以用它来预测。
感谢阅读,我希望你觉得这篇文章有趣!
所有的代码都可以在这个库中找到:https://github . com/francoistamant/brain-tumor-classifier-app
建立一个基于预算新闻的算法交易者?那么你需要很难找到的数据
我的故事——零美元建立一个算法交易者,分析免费 API、数据集和 web 抓取器。第 1 部分:API
利用新闻或股票信号的算法交易近年来越来越受欢迎。一个完整的行业已经从彭博和 Webhose 这样的巨头发展到成千上万的小公司,它们都在争夺最快、最准确、最广泛的新闻报道。然而,大多数这些服务的问题是,它们针对的是大公司,因此通常每个人要花费数百美元,很可能会被大多数人的算法淘汰,至少会侵蚀潜在的回报。出于这个原因,我决定尝试为在家开发人员拼凑最现实的解决方案,在探索了几十个来源后,我将搜索范围缩小到 10 个最可行的选项。这 10 个免费资源都没有为算法交易提供一个本垒打,但是认为这些资源的组合可以让大多数人达到一个伟大的境界是很现实的。在第 1 部分中,我将讨论前 5 个,它们都是 API!关于数据集和 web 抓取器的第 2 部分也可以在这里访问!
[## 建立一个基于预算新闻的算法交易者?那么你需要难以找到的数据——第 2 部分
我的故事——零美元建立一个算法交易者,分析免费 API、数据集和 web 抓取器。第 2 部分:数据集和…
towardsdatascience.com](/building-a-budget-news-based-algorithmic-trader-well-then-you-need-hard-to-find-data-part-2-2ddc4a9be1d8)
蜜蜂
API 是大多数平台的最爱,用于以编程方式向用户提供一致的新闻数据。用户将向一个端点发出请求,例如,请求与 Apple 有关的最近 10 篇文章,并从该端点接收响应。
优点:
快速编程访问——大多数 API 将在几百毫秒内返回请求的数据,允许用户快速收集数据
定制——API 倾向于有好的文档,如果构建得好,能够准确地返回用户正在寻找的东西。例如,我可以告诉 API,我想要这些日期的新闻源中的这么多文章。其他方法,如批量下载,可能需要更多的提取才能达到那个粒度级别
实时—用于新闻的 API 大部分时间将实时数据传输到端点。这意味着当您发送请求时,您将获得最新的信息。这对于适应不断变化的市场环境至关重要。
缺点:
使用限制—大多数 API 都是按使用付费的系统。这意味着,如果您使用的是免费层以上的任何东西,您很可能需要定期付费,这可能无法满足复杂系统的需求。许多人还会限制你在一段时间内的访问次数。
缺少历史数据——因为新闻 API 是建立在可以访问最新新闻的概念上的,所以历史数据的积压往往很少。当 ML 算法需要多年的历史数据来开始良好地执行时,这可能是一个问题。
由于 API 的压倒性优势,我发现的 10 个最佳来源中有 5 个都是 API,下面我将详细介绍每一个!
新闻 API
优点:
高使用上限——每天 500 个请求是一个非常好的自由层,普通开发人员永远不需要担心会超过这个上限!
包含大量元数据的准确文章—关于某个主题的请求通常每天会返回数百篇文章,并且包含诸如来源、作者、标题、描述、发布日期和文章内容等信息。这为每个请求提供了大量信息。
缺点:
内置延迟——免费层包括所有退回商品的 15 分钟延迟,这可能是一个交易破坏者,也可能根本不重要,取决于交易的类型。
普通积压—免费层积压可以追溯到 1 个月前(已付费 24 个月),这意味着找到梦寐以求的历史数据可能是不可能的。
超出免费层的高昂成本——如果您愿意每月支付 10 美元来获得更高的使用率和高级支持,那么使用 news API 是不可能的。他们的下一个计划包括 250,000 个请求,没有新闻延迟,价格为 449 美元,远远超出了大多数开发者的承受能力。
总体而言:
当你开始谷歌搜索金融新闻应用编程接口时,第一个结果,也是最好的结果之一,就是新闻应用编程接口。它使用简单,对于普通开发人员来说有很大的自由层!如果您可以通过其他方式填充您的历史数据,并且不介意延迟,那么新闻 API 很难被击败!
必应新闻搜索(通过 Rapid API)
优点:
实时—给定一个搜索,提供关于特定搜索主题或特定类别新闻的快速实时新闻
超出免费等级的优惠价格—对于超过 100 个请求/天限制的每个额外请求,您只需为每个额外请求支付 0.005 美元。如果在某些日子比其他日子需要更多的请求,这就提供了很大的灵活性!
缺点:
不存在的积压-无法为您的搜索结果指定时间范围。这使得查找昨天的数据变得非常困难,所以这个 API 对于检索历史数据是不理想的。
总体而言:
我认为这是一个非常普通的 API。返回的元数据是好的,但不是很好,每天 100 个请求的免费层也是中等水平,但它确实提供了实时的无价优势,但缺点是没有历史结果。它还具有由微软维护的可靠性。如果您所关心的只是可靠的实时结果,那么这个 API 就能满足您的需求!
上下文网络搜索(通过 Rapid API)
优点:
高使用上限—每月 10,000 个请求是一个非常好的免费层。除此之外,一旦达到上限,每个请求只需花费 0.0005 美元,是 bing 新闻搜索请求费用的 1/10!
相当好的积压——新闻搜索 API 带有可选的 to 和 from 日期参数,我能够访问早至 1 年的数据,这对于一个免费增值 API 来说是非常优秀的。对于复杂的交易者来说,这些数据可能不够,但是提供了一个合理的开始!
实时-搜索将自动返回最新的结果,除非另有说明,使实时数据很容易获得!
缺点:
相关性问题——在测试这个 API 时,如果我搜索一个特定的股票代码,大多数结果都是相关的,但是偶尔会出现不相关的结果。例如,在搜索与 AAPL 相关的新闻时,我收到的一篇文章的标题是“玛丽亚·凯莉对她的孩子太放纵了吗?”很明显,这不是任何人都希望输入到他们的 ML 算法中的数据!
高延迟 API 报告的平均延迟约为 4000 毫秒,在我的个人测试中,这个数字似乎很大。这有可能限制大量使用情况下可获得的数据量。
可靠性问题——据报道,API 的可靠性为 95%,对于一个免费服务来说,这已经不错了(尽管仍低于大多数水平)。但是在我的测试中,随机失败的数量是显而易见的,这是我在其他 API 中从未遇到过的。
总体而言:
这个 API 的最大特点是能够有选择地收集一年前的新闻数据,免费层提供了足够的使用量来轻松填充积压的文章(每次调用可以返回多达 50 篇文章)。它还可以提供实时结果,使这个 API 看起来像表面水平的赢家。然而,在表面之外,这个 API 有一些可靠性和相关性的缺陷,这些缺陷让它黯然失色。如果您不介意筛选可能杂乱的数据并实现失败检查,这个 API 可能是最好的万能解决方案!
彭博市场和金融新闻(通过 Rapid API)
优点:
具有丰富深度和元数据的高质量新闻 API 分为两个主要的搜索功能,第一,输入一个 ticker,返回 10 篇最近的文章及其标题和唯一关键字。提供了第二个 API 来输入这个惟一的键,并检索完整的文章和元数据。元数据非常深入,包括标签、相关主题、分成组件的文章等等。
新闻是专门按 ticker 排序的——其他大多数 API 都是新闻的网络搜索。彭博专门给文章贴标签,只给相关的标签。这意味着收到的新闻总是与想要的股票相关!
实时——在文章公开后的几毫秒内提供最新的文章!
超出免费层的良好定价-专业层为每月 10 美元,这对开发人员来说是非常合理的价格,包括每月 10,000 次请求,加上超出上限的合理的 0.002 美元/请求价格。
缺点:
免费层不足—免费层每月仅包括 500 个请求,每天不到 17 个。对于大多数系统来说,这是远远不够的,特别是考虑到使用这个 API 需要两次请求才能获得任何单个文章的深度元数据。
不存在积压——彭博擅长提供快速更新的金融新闻。这是以当前没有检索历史数据的能力为代价的。
总体而言:
彭博多年来一直是财经新闻的领导者,这一点在这个 API 中得到了很好的体现。如果文章的准确性、速度和深度是重要的,那么它显然是赢家。这方面的压倒性优势是以其他方面的代价换来的。没有积压,几乎被迫为一个高级帐户付费,这给本来是一个极好的 API 增加了压力!
雅虎财经 API(通过 Rapid API)
优点:
新闻是专门按股票代码分类的——像彭博一样,雅虎财经 API 的工作原理是输入一个股票代码,然后返回一个最近 10 篇文章的列表,这些文章被专门标记为与该公司相关。雅虎财经还增加了简单返回最新 10 篇一般财经文章的功能!
列表包含大量的元数据——当询问最近的 10 篇文章时,列表中的每一项都包含了大量的细节!这包括文章的标题、摘要、实体和内容!
实时——在文章公开后的几毫秒内提供最新的文章!
超出免费层的良好定价-就像彭博一样,专业层是每月 10 美元,这对开发人员来说是一个非常合理的价格,包括每月 10,000 次请求,加上超出上限的合理的 0.002 美元/请求价格。
缺点:
不存在积压——这个 API 擅长实时更新,所以没有编程。查看积压的工作。
平淡无奇的免费层——像彭博一样,这个 API 每月免费提供 500 次调用。虽然这在彭博几乎不可用,但是每次列表检索返回的元数据量使得 500/月更友好。这实际上每月可以访问 5,000 篇有深度的文章,虽然有点乏味,但对于较小的项目是有用的!
总体而言:
这个 API 的行为和感觉与彭博提供的非常相似,在准确性、速度和文章深度方面都有很大价值。虽然 Yahoo 每篇文章的深度和元数据略低,但它通过更友好的免费层弥补了这一点,并且检索类似数量的信息所需的 API 调用要少得多!总的来说,与列表中的其他 API 相比,它表现得很好!
原料药的总体印象
所有这些 API 都有各自的优缺点。它们都不能提供完美的解决方案,但大多数都以低成本或零成本提供了大量的价值。所有这些 API 都是可用的,我认为这个决定主要取决于个人认为什么是优势!这些解决方案中的任何一个都可能必须与补充数据配对,或者用户必须长时间收集数据才能在交易算法中使用。
评估 API 花费的时间比预期的长得多。为了避免 20 分钟的阅读时间,我将在本系列的第 2 部分讨论数据集和 web 抓取器,可以在这里访问!
[## 建立一个基于预算新闻的算法交易者?那么你需要难以找到的数据——第 2 部分
我的故事——零美元建立一个算法交易者,分析免费 API、数据集和 web 抓取器。第 2 部分:数据集和…
towardsdatascience.com](/building-a-budget-news-based-algorithmic-trader-well-then-you-need-hard-to-find-data-part-2-2ddc4a9be1d8)
目前就这些了!我希望这篇文章能消除在众多网络平台中筛选的痛苦和折磨!
如果你喜欢这篇文章,并且想读更多我写的东西,可以考虑看看下面的其他文章!
[## 我是如何用 eGPU 将我的旧笔记本电脑变成机器学习超级明星的
以新电脑的零头成本改造超极本的惊人简单之旅
towardsdatascience.com](/how-i-turned-my-older-laptop-into-a-machine-learning-superstar-with-an-egpu-66679aa27a7c) [## 深度学习预算:450 美元 eGPU vs 谷歌 Colab
Colab 对于开始深度学习来说是非凡的,但它如何与 eGPU +超极本相抗衡?
towardsdatascience.com](/deep-learning-on-a-budget-450-egpu-vs-google-colab-494f9a2ff0db)
建立一个基于预算新闻的算法交易者?那么你需要难以找到的数据——第 2 部分
我的故事——零美元建立一个算法交易者,分析免费的 API、数据集和网页抓取器。第 2 部分:数据集和 Web 抓取器
斯蒂芬·道森在 Unsplash 上拍摄的照片
为基于新闻的交易者寻找数据是一项非常具有挑战性的任务。获取一年多以前的历史数据要么是一项艰巨的挑战,要么将花费数百到数千美元购买。在第 1 部分中,我分析了访问数据的最佳新闻 API。如果你还没有读过那篇文章,我推荐你先读读这里。总结一下我发现的免费 API 的结果,它们在为交易者提供实时新闻方面非常出色,但在为用户提供积压的数据方面却非常欠缺。事实上,我找不到一年前的数据。它们还限制了用户在任何一个月中可以发出的请求数量。幸运的是,我们可以采取措施减轻 API 的缺点。在这篇文章中,我将分析免费的数据集和网页抓取工具,看看它们如何为创建算法交易者提供必要的数据。
数据集
数据集是快速访问海量数据的首选。如果有正确的数据可用,由于能够快速下载和使用大量数据,数据集在算法开发时间上提供了无价的加速。我从谷歌的数据集服务到 Kaggle 搜索了几十个数据库档案。令人惊讶的是,能够提供真正有用的数据集的唯一来源是 Kaggle,他们实际上有多个!
优点:
大量信息-可用的信息越多,学习和发现趋势就越容易,这就是经典数据集从未过时的原因!
快速编译—当数据集被下载时,访问、训练和使用数据集的速度非常快,从而缩短了开发时间。
缺点:
难以更新-更新不是由您创建的数据集是一项具有挑战性的任务,即使如此,您也可能会遇到拼接不完全匹配的源的问题。您可能会受数据集创建者的支配,发布新版本,或者可能只能永久访问旧数据,这都是经典数据集的显著缺点。
很难找到-找到新闻 API 比找到新闻数据集容易得多。即使您找到了数据集,也不太可能找到与您试图解决的问题完全匹配的数据集。这可能使使用数据集成为不可能的选择。
Kaggle 美国财经新闻文章
该数据集包含 2018 年 1 月至 5 月彭博、美国消费者新闻与商业频道、路透社、华尔街日报和财富杂志的文章。数据集的总大小超过 1 千兆字节,包含成千上万的文章和元数据。
优点:
充足的数据——1gb 是迄今为止我发现的最大的数据集。这意味着,无论你只想要特定的股票还是一般的新闻,任何用户都可以从这个数据集中提取他们需要的信息。它还有大量的元数据,包括文章是关于什么实体的,以及对该实体的看法。
可靠数据-数据集仅包含可靠的来源,提供可靠的新闻报道作为算法的基础。
缺点:
时间跨度短— 5 个月的数据是一个小样本。这段时间市场稳定,表现良好,这可能会导致不可靠的学习。
杂乱的数据——数据按文章排序,而日期和相关的实体存放在元数据中。这意味着在该数据集可用之前,可能需要大量的数据争论。
总体而言:
这个数据集是数据收集的一个很好的起点。它有一个明显的缺点,即缺乏一个大的时间跨度,但如果你以此为起点,并填写 2018 年 5 月以来的补充数据,这个数据集可能会被证明是有价值的!
消息对股票收盘价的影响
这个数据集非常轻量级,但却是这个列表中最有趣的数据集。它只包括微软和苹果公司从 2006 年到 2016 年的文章。每个日期包含开盘价和收盘价,以及《纽约时报》与该公司相关的所有标题。数据集包含对组合标题串的情感分析,指示是否检测到正面或负面情感。
优点:
长时间跨度——10 年的标题数据足以用来训练、测试和验证算法,并且可以通过在类似的方法中添加额外的数据来进一步改进。
补充信息-内置的股票价格和情绪分析列使这成为一个数据集训练准备!像自然语言处理这样的附加步骤已经为您完成了!
可靠的数据——数据直接来自《纽约时报》,虽然这不是一个多样化的数据来源,但它是一个可靠和一致的来源。
缺点:
只有 2 个报价器——从 2 个报价器中学习并推断出其他股票是危险的。这是一个耻辱,这个数据集不包含来自不同部门的 20+ticker!苹果和微软也是成功的公司,这可能会引入不必要的幸存者偏见。
数据越来越旧——只有 2016 年的数据可能会伤害到现在想要创建一个交易算法的人。这可能需要对丢失的信息进行大量的填充才能使用。
缺少元数据—提供的信息只是标题字符串。这缺乏可以证明有用的深度元数据和文章内容。
总体而言:
这个数据集对于学习如何建立一个算法交易者非常有用。它提供了大量的数据,并提供额外的分析。如果您想获取数据集并开始训练,没有比这更好的选择了!然而,我会谨慎地把它作为你唯一的数据源。尤其是如果你想建立一个全面的算法。旧数据的缺点和没有太多的信息阻碍了原本是一个伟大的数据集。
Kaggle 每日新闻进行股市预测
该数据集包含从 2008 年到 2016 年每天从 Reddit 的世界新闻论坛检索到的前 25 条世界新闻。它还包含道琼斯工业平均指数数据和一个布尔值,如果当天道琼斯指数收盘时较低,则为 0,如果收盘时较高,则为 1。
优点:
时间跨度长— 8 年以上,每天有 25 个标题,这足以用来训练、测试和验证算法,并且可以通过在类似的方法中添加额外的数据来进一步改进。
制作良好-数据集组织良好,可用于算法开发。数据集是由一位教授制作的,用于深度学习课程,因此它自然易于使用。
缺点:
数据有效性——根据用户投票赞成和投票反对的内容提取标题可能会给算法带来偏差。Reddit 也没有审查被投票支持的新闻来源的有效性。
数据越来越旧——只有 2016 年的数据可能会伤害到现在想要创建一个交易算法的人。这可能需要大量的回填信息才可用。
不具体—数据仅来自世界新闻,而非金融新闻或个别符号,因此无法提取具体的金融文章。
总体而言:
这是三个数据集中最全面的。它提供了充足的数据、很大的时间跨度,并为用户提供了轻松添加数据、使用 NLP 等技术扩充数据或使用数据快速开发算法的机会。然而,这种便利和大量免费数据带来了数据可靠性的缺点。
数据集的总体印象
所有这些数据集以令人难以置信的速度提供了大量的免费数据。然而,这些数据集没有一个是完美的。它们都有各自的缺点,可能会限制它们的实用性,并且都是 2018 年或更早的产品。然而,数据集的好处是,它们为向免费 API 或 web scraper 添加一些历史背景提供了一个很好的起点!
Web 刮刀
Web scrapers 涉及创建一个程序,该程序将从源站点系统地提取数据,并保存这些数据以备后用。它们是许多人的最爱,因为它们可以自由创建,并且完全可定制。在这篇文章中,我将介绍 web 抓取工具的两种方法!
优点:
完全可定制—您正在编写提取数据的代码,因此您正在完全按照您想要的方式存储您想要的数据。
无限制的免费访问——只要你允许,你的机器人就会运行,没有付费墙,或者对你接收的数据没有限制。
缺点:
可能会很慢—因为您是以编程方式访问网站,所以收集大量数据比使用 API 慢得多。
受限于网站——你也受限于在你抓取的网站上物理可见和可访问的内容,这可能意味着回到很久以前(比如获取几年前的推文)可能在编程上具有挑战性。
高开发成本——创建 web scraper 比使用 API 或下载数据集更具挑战性,耗时也更长。
硒
Selenium 是一个大多数编程语言都支持的工具包,用于使用脚本编程控制 web 浏览器。它广受欢迎,受到广泛支持,易于使用,目前被数百家公司用于 web 抓取、自动化和系统测试。
优点:
广泛的支持——借助对 Python、Java、Ruby、Javascript 和 C#的开发支持,使用您最喜欢的语言并开始自动化 web 浏览器变得非常容易!
完全可定制—您可以完全控制 web 浏览器。您可以在浏览器中做的任何事情都可以自动化,保存,并用于以编程方式存储数据!
缺点:
高开发成本——创建您的完美刮刀需要时间,此外,网站始终有可能发生变化,需要维护。
耗时——与利用 API 等其他来源相比,等待 scraper 收集足够的数据来创建任何有用的算法可能会令人望而却步。
总体而言:
硒真正是“你想要吗?建吧!”网页抓取选项。这是一个非常扩展和有用的工具,唯一的缺点是你只能通过浏览器来完成。如果您需要特定的数据,并且具有创建自己的解决方案的编程能力,没有比 selenium 更好的平台了。
Getdata.io
getdata.io 提供了一个有趣且可能更快的网络抓取解决方案。该平台允许使用其查询语言创建“食谱”,该语言将在网页变化时系统地从网页中抓取数据。然而,最重要的是,你不需要精通他们的查询语言,因为他们有一个 chrome 扩展,可以作为一个点击式的解决方案来生成食谱!与为执行任何基于 web 的任务而构建的 selenium 不同,它是为收集数据而定制和构建的!
优点:
快速学习-使用 getdata.io 时,开始抓取网页所需的时间不会太长。添加的 chrome 扩展使抓取数据变得简单!
专为提取数据而构建—该平台专为检测数据变化并相应更新而构建。然后,您可以使用 get 请求将任何数据拉入您的算法中!
数据社区——您创建的配方和提取的数据可以公开。这意味着你得到了一个已经在收集数据的巨大的社区!然而,我为金融新闻找到的食谱太弱,不足以报道。
缺点:
缺少历史提要——因为 scraper 只寻找变化,它不擅长向后搜索历史数据,这意味着您需要等待足够的数据!
比硒更有限——配方创建系统虽然简化了过程,但也限制了可以提取的内容的能力。复杂的提取可能更困难,从长远来看,这可能会使硒更容易提取。
总体而言:
对于那些想要简单了解网络抓取和轻松访问定制数据的人来说,这是一个很有吸引力的选择。它在深度上的不足在数据社区和快速启动时间上得到了充分的弥补!
卷筒纸刮刀的总体印象
Web scrapers 为需要创建自己的数据的人提供了最佳选择。虽然他们可能需要更长的时间来收集必要的数据,但可定制性的数量是无与伦比的。Web 抓取可以用来扩充现有的数据集或 API,也可以单独使用来获得巨大的成功。总的来说,你在 web scraper 上投入的工作量将决定它能否成功创建完美的数据集!
你有它!如果你跟着我看了这两部分,我希望我已经提供了一个很好的资源,告诉你从哪里开始寻找算法交易的新闻。我对创建免费数据集的总体建议是
- 不要害怕混合来源。只要你试图保持一致性,数据集和 APIs 刮刀就能很好地协同工作。
- 使用适合您的用例的资源。这些资源都不完美,但它们都是有原因的。这 10 个项目中的每一个都提供了至少一个其他 9 个项目没有涵盖的独特方面!
- 用自己的钱交易要小心!
如果您有我错过的最喜欢的 API、数据集或 web scraper,请告诉我,如果您喜欢这篇文章,请关注我,了解更多数据科学领域的内容!
构建纸板帝国:使用 Python 介绍 TCGplayer API
如何使用 Python 连接到 TCGplayer.com API
韦恩·洛在 Unsplash 上的照片
纸板的生活
我几乎一生都在玩纸牌游戏,并在 90 年代中期大约在二年级的时候开始玩魔法:聚会(MTG) 。虽然这不是一个让我受女孩欢迎的真正爱好,但我断断续续地坚持了下来,并在十几岁的时候花了许多周五晚上在纸牌店打磨构建的锦标赛和增强草案。现在我对编程和数据科学感兴趣,我很高兴了解到在线纸牌游戏市场,TCGplayer.com有一个免费的 API。
本文将带您了解如何使用 Python 和请求库连接和搜索 TCGplayer API。完整代码可在底部找到!
我的魔法中的几张卡片:收集
获取 API 密钥
TCGplayer 是一个收集物品的互联网市场,允许用户建立商店,通过它他们可以在线出售他们的库存。API 代表 应用编程接口 。
位于 api.tcgplayer.com 的 TCGplayer API 是一个 RESTful API 应用程序,它与 TCGplayer 商店站点进行交互。存在大量的端点,它们返回目录的所有方面,查找定价信息,并管理个人商店。—https://docs.tcgplayer.com/docs/welcome
要访问他们的 API,首先填写他们的申请表:
此处的所有原创内容均为 2018 TCGplayer,Inc .版权所有。TCGplayer.com 是 TCGplayer,Inc .的商标
developer.tcgplayer.com](https://developer.tcgplayer.com/developer-application-form.html)
使用 Python 通过请求访问 API
一旦你的文书工作被接受,TCGplayer 的代表将通过电子邮件向你发送一个申请 Id 、公钥和私钥。使用这些键,可以使用 Python 中的 请求 库创建到 API 的连接。根据需要使用 Pip 安装请求:
python -m pip install requests
文件 config.py &管理 API 密钥
本项目使用 API 密钥 。如果你是管理钥匙的新手,确保将它们保存到一个 config.py 文件中,而不是在你的应用程序中硬编码它们。 API 密钥非常有价值,必须加以保护。将配置文件添加到 gitignore 文件中,防止它也被推送到您的 repo 中*!*
用你的钥匙
创建需要公钥和私钥。一个无记名令牌基本上告诉系统给持有令牌的任何东西以访问权。它是由认证服务器自动生成的。
*#import dependencies
import requests#pull in api keys from config file
from config import public_key, private_key#construct api request
response = requests.**post**(
"[https://api.tcgplayer.com/token](https://api.tcgplayer.com/token)",
**headers**={
"Content-Type": "application/json",
"Accept": "application/json"},
**data**=(f"grant_type=client_credentials"
f"&client_id={**public_key**}&"
f"client_secret={**private_key**}")
)*
注意我使用了一个 POST 请求到 /token URL。我将包含 API 键的头和数据有效载荷传递到请求中。返回承载令牌和元数据。
使用查看响应中返回的数据。json()或。正文
*response.**json()**#output
# {'access_token': '**YOUR_GENERATED_TOKEN**',
# 'token_type': 'bearer',
# 'expires_in': 1209599,
# 'userName': '**YOUR_GENERATED_USERNAME**',
# '.issued': 'Sat, 12 Sep 2020 15:40:32 GMT',
# '.expires': 'Sat, 26 Sep 2020 15:40:32 GMT'}*
请注意,不记名令牌已过期。TCGplayer 建议缓存元数据,只在密钥即将过期时重新生成密钥。
既然已经生成了不记名令牌,就可以使用它与 API 进行交互了。
将无记名令牌保存到变量:
*access = response.json()['access_token']*
将无记名令牌连同单词“无记名”一起传入请求报头。
TCGplayer 还希望您在头文件中包含一个用户代理,这样他们可以更容易地跟踪 API 的使用情况:
*headers = {"accept": "application/json",
"Content-Type": "application/json",
**'User-Agent': 'YOUR_USER_AGENT',
"Authorization": "bearer " + access**}*
选择要与之交互的 API 端点。我将从目录>开始,列出所有类别 API 端点,并开始探索!
TCGplayer.com API 端点
*url = "[https://api.tcgplayer.com/catalog/categories](https://api.tcgplayer.com/catalog/categories)"response = requests.get(url, headers=headers)response.json()*
注意变量 URL 是我想要命中的 API 端点。
我将 URL 和头传递给 GET 请求并返回 JSON 响应。
如果我想探索某个特定类别的更多信息,我可以在 API 端点的 URL 中使用 categoryID。例如,下面的 URL 将让我搜索类别 1(魔术聚会是类别 1):
*#search the mtg catalog [https://api.tcgplayer.com/catalog/categories/1/search](https://api.tcgplayer.com/catalog/categories/1/search)*
虽然大多数 API 端点可以通过 GET 请求来访问,但有些端点,如目录>搜索类别产品允许您使用 POST 请求向请求传递过滤器。
比如说我要搜魔:聚拢卡什一税。我可以将一个排序选项,以及过滤器和聚合传递到 JSON 有效负载中。**
*url = "[https://api.tcgplayer.com/catalog/categories/1/search](https://api.tcgplayer.com/catalog/categories/1/search)"**payload** = {"**sort**":"Relevance",
"**filters**": [{
"**values**": ["Tithe"],
"**name**": "productName"
}]}search_response = requests.request("POST", url, json=payload, headers=headers)search_response.json()*
该请求返回产品 id 列表。根据项目的排序方式,产品 id 列表与结果在 TCGplayer.com 上的显示方式相匹配
Search_response.text 按相关性排序的 Tithe
按 TCGplayer.com 的相关性排序的什一税搜索结果
要在搜索请求中检索关于卡的信息,只需将逗号分隔的列表传递给 API 端点 URL。
*endpoint = "[https://api.tcgplayer.com/catalog/products/](https://api.tcgplayer.com/catalog/products/)"
productids = str(search_response.json()["results"])url = endpoint + productidsresponse = requests.get( url, headers=headers)response.json()*
注意,我只是将 API 端点与产品 id 列表结合起来。
response.json()
恭喜你!您现在可以导航和探索 TCGplayer API 了!
最终想法和代码
纸牌游戏并没有走向任何地方,它已经成熟成为一个受欢迎的利基市场。魔术:聚会到现在已经有将近 30 年了!使用像 TCGplayer API 这样的工具,有一个独特的机会来进行一些数据分析和数据科学,并开发新的工具和应用程序来帮助玩家建立和管理他们的收藏。通过 TCGplayer API,甚至可以运行您的在线商店!
如果你喜欢这篇文章,可以看看我关于编程和数据科学的其他文章:
* [## 如何使用 Python 和 Dash 创建控制股市的仪表板
自由期权订单流、价格、基本面、聊天集于一身
medium.com](https://medium.com/swlh/how-to-create-a-dashboard-to-dominate-the-stock-market-using-python-and-dash-c35a12108c93) [## 使用 Python 学习自然语言处理的 3 个超级简单的项目
单词云、垃圾邮件检测和情感分析的简单代码示例
towardsdatascience.com](/3-super-simple-projects-to-learn-natural-language-processing-using-python-8ef74c757cd9) [## 自我隔离时探索三种数据科学技术:什么是 Docker、Airflow 和…
探索 Docker、Airflow 和 Elasticsearch,扩展您的数据科学技术堆栈
towardsdatascience.com](/three-data-science-technologies-to-explore-while-you-self-isolate-what-is-docker-airflow-and-78969ba4f5fe)
完全码
下面是完整的代码
#import dependencies
import requests#pull in api keys from config file
from config import public_key, private_key#construct api request
response = requests.**post**(
"[https://api.tcgplayer.com/token](https://api.tcgplayer.com/token)",
**headers**={
"Content-Type": "application/json",
"Accept": "application/json"},
**data**=(f"grant_type=client_credentials"
f"&client_id={**public_key**}&"
f"client_secret={**private_key**}")
)access = response.json()['access_token']headers = {"accept": "application/json",
"Content-Type": "application/json",
**'User-Agent': 'YOUR_USER_AGENT',
"Authorization": "bearer " + access**}url = "[https://api.tcgplayer.com/catalog/categories](https://api.tcgplayer.com/catalog/categories)"response = requests.get(url, headers=headers)print(response.json())url = "[https://api.tcgplayer.com/catalog/categories/1/search](https://api.tcgplayer.com/catalog/categories/1/search)"**payload** = {"**sort**":"Relevance",
"**filters**": [{
"**values**": ["Tithe"],
"**name**": "productName"
}]}search_response = requests.request("POST", url, json=payload, headers=headers)print(search_response.json())endpoint = "[https://api.tcgplayer.com/catalog/products/](https://api.tcgplayer.com/catalog/products/)"
productids = str(search_response.json()["results"])url = endpoint + productidsresponse = requests.get( url, headers=headers)response.json()
谢谢大家!
- 如果你喜欢这个, 在 Medium 上关注我 获取更多
- 通过订阅 获得对我的内容的完全访问和帮助支持
- 我们来连线一下LinkedIn
- 用 Python 分析数据?查看我的 网站
与 Emily Robinson 一起开创数据科学事业
苹果 | 谷歌 | SPOTIFY | 其他 | 剪辑
艾米丽·罗宾逊在 TDS 播客
编者按:迈向数据科学播客的“攀登数据科学阶梯”系列由 Jeremie Harris 主持。Jeremie 帮助运营一家名为sharpes minds的数据科学导师初创公司。可以听下面的播客:
数据科学存在于许多真正的技术主题的交叉点,从统计学到编程到机器学习。所以很容易被愚弄,以为这是一个纯粹的技术领域。
但是数据科学和分析不仅仅是解决技术问题。正因为如此,数据科学求职不仅仅是编码挑战和竞争。作为一名数据科学家,获得一份工作或晋升需要大量的职业技能和软技能,而许多人没有花足够的时间来磨练这些技能。
在本期播客中,我采访了经验丰富的数据科学家和拥有 Etsy 和 DataCamp 背景的博客作者艾米丽·罗宾逊(Emily Robinson),讨论职业发展策略。关于这个话题,Emily 有很多话要说,特别是因为她刚刚与合著者 Jacqueline Nolis 合著了一本名为《在数据科学领域建立职业生涯》的书。这本书探讨了许多推动数据科学职业发展的伟大而实用的策略,其中许多我们在交谈中讨论过。
以下是我最大的收获:
- 如果你想引起雇主的注意,个人项目很重要,但仅仅有一个带有 Python 脚本或 Jupyter 笔记本的 GitHub repo 是不够的。阅读代码既无聊又辛苦,雇主也不太可能这么做,所以试着把你的项目写成一篇博文,或者把它做成一个独立的网络应用,你可以和其他人分享。
- 数据科学在不同的公司可能会有很大的不同,公司规模是一个重要因素:较大的公司往往有更专业的角色,并会费心区分分析师、数据科学家和机器学习工程师,而较小的公司可能需要你发展更全面的技能。
- 大公司通常能更好地提供在职指导等服务,而小公司在新员工入职方面可能会更加困难。出于这个原因,艾米丽建议,如果你刚开始职业生涯,就去看看大公司,以确保你获得成长为这个角色所需的支持。
- 人们不常想到的一件事是,一旦到了该继续前进的时候,离开一家公司的过程。让这个过程顺利进行(或者像艾米丽所说的,“优雅地离开”)是非常重要的:你会想和所有和你一起工作过的人保持良好的关系,因为以前的同事往往会成为很好的推荐渠道!
- 决定什么时候离开一家公司是困难的,但是做这个决定要考虑的一个关键因素是你是否还在学习。工作保障已经今非昔比,数据科学技术发展的快速步伐意味着,如果你涉水太久,你可能会让你的下一次求职变得更具挑战性。Emily 建议抓住每一个机会学习新的技能,并在你目前的职位上有所发展——如果你不能,那是一个好迹象,是时候改变了。
你可以在这里的推特上关注艾米丽,你也可以在这里的推特上关注我。
夹子
我们正在寻找能与我们的观众分享有价值的东西的客人。如果你碰巧知道谁是合适的人选,请在这里告诉我们:【publication@towardsdatascience.com】T4。
用 Python 构建猫脸识别器
机器能理解人和猫脸的区别吗?
在这篇文章中,我将向你展示如何编写一个简单的程序来检测猫的面孔。在我的人脸检测帖子中,我展示了如何使用 Python 来检测人脸。当我用许多图像测试代码时,我意识到其中一些图像中有动物。但是我们创造的人脸检测模型不能识别动物的脸。然后,我想知道是否有一种方法可以检测图像中的动物面孔,在互联网上做了一些研究后,是的,这是可能的。甚至在 Kaggle 上找到了很多免费的数据集,有几百张图片。Kaggle 是一个寻找免费数据集的好地方,他们也在组织数据科学竞赛。这是一个练习数据科学技能和向他人学习的好地方。无论如何,回到我们的项目。我很高兴在一个程序中结合了人类和猫的面部检测模型,这样我们的机器就可以学习区分人类和猫。这将是一个有趣的项目。我们开始吧!!
图书馆
首先,文书工作。当您处理机器学习项目时,安装和导入库是必要的。我们将为这个项目使用两个库,它们被称为 OpenCV 和 Pillow。OpenCV 是一个高度优化的库,专注于实时应用。Pillow 是一个很棒的图像处理库。枕头将作为“枕头”安装,但作为 PIL 进口。它们是一回事,不要混淆。
OpenCV(开源计算机视觉库)是一个开源的计算机视觉和机器学习软件库。OpenCV 旨在为计算机视觉应用提供一个公共基础设施,并加速机器感知在商业产品中的应用。作为一个 BSD 许可的产品,OpenCV 使得企业利用和修改代码变得很容易。
安装过程非常简单和容易。在您的终端窗口中编写以下代码行:
pip install opencv-python pillow
安装完成后,我们可以将其导入到我们的程序中。
import cv2 from PIL import Image
OpenCV 已经包含了许多预先训练好的人脸、眼睛、微笑等分类器。这些 XML 文件存储在 GitHub 文件夹中。我们将使用猫脸检测和人脸检测模型。
以下是链接:
如果您有帐户,可以从 Github 下载 XML 文件。如果你没有,请随意从上面的链接中复制代码,粘贴到你的文本编辑器中并保存它们。我将它们保存为“catface_detector.xml”和“humanface_detector.xml”。
将文件保存到您的文件夹后,让我们将它们加载到我们的程序中。
# Load the cascades
catface_cascade = cv2.CascadeClassifier('catface_detector.xml') humanface_cascade = cv2.CascadeClassifier('humanface_detector.xml')
形象
在这一步中,您将选择一个要测试代码的图像。确保你至少有几张图片来检查你程序的准确性。这些图像可以有人类和猫,也可以只有其中一个。如果你很难找到猫的图片,我在 Kaggle 上找到了一个免费的数据集。请随意下载并用于该项目。
以下是我将在我们的项目中使用的图片:
https://www.kaggle.com/c/dogs-vs-cats
选择图像后,让我们给它们重新命名。确保图像文件位于您正在处理的同一文件夹中。在保存它们之后,现在我们将对图像做一些修饰。
图像处理
在这一步,我们将对图像做一些小的修饰,以便更好地处理。我发表了一篇关于常用图像处理技术的文章。做这些修饰确实有助于我们的机器处理并给出更好的结果。在这个练习中,首先,让我们调整图像的大小,使它们大小相同。接下来,我们将它们转换为灰度,我们的模型处理灰度图像更快。
常用图像处理技术逐步指南
towardsdatascience.com](/image-manipulation-in-python-cbb86a61cf0)
为了使用这些图像编辑技术,我们将使用我们在文章开始时导入的图像模块。
调整大小
newsize = (600, 600) #First image retouches
imgr1 = Image.open("test1.jpg")
imgr1 = imgr.resize(newsize)
imgr1.save("resized1.jpg")#Second image retouches
imgr2 = Image.open("test2.jpg")
imgr2 = imgr.resize(newsize)
imgr2.save("resized2.jpg")
灰度等级
imgr1 = imgr1.convert('L')
imgr1.save('ready1.jpg') imgr2 = imgr2.convert('L')
imgr2.save("ready2.jpg")
导入编辑过的图像
最后,让我们将编辑好的图像导入我们的程序,这样我们就可以运行猫脸和人脸检测模型。我们使用 Opencv 库来导入图像。
# Read the input image
img1 = cv2.imread('ready1.jpg')
img2 = cv2.imread('ready2.jpg')
人脸检测
瀑布状物
是时候检测人脸了。我们将运行两行代码。第一个在图像中发现人脸的人。第二步是检测图像中的猫脸。如前所述,我们正在起诉 opencv 分类器。
human_faces = humanface_cascade.detectMultiScale(img1,
scaleFactor=1.3, minNeighbors=5, minSize=(75, 75)) cat_faces = catface_cascade.detectMultiScale(img2, scaleFactor=1.3,
minNeighbors=5, minSize=(75, 75))
画矩形
在这一步,我们将围绕检测到的人脸绘制矩形。这些矩形可以是不同的颜色,其厚度也是可调的。
for (i, (x, y, w, h)) in enumerate(human_faces): cv2.rectangle(img1, (x, y), (x+w, y+h), (220, 90, 230), 3)
cv2.putText(img1, "Human Face - #{}".format(i + 1), (x, y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.55, (220, 90, 230), 2) for (i, (x, y, w, h)) in enumerate(cat_faces): cv2.rectangle(img2, (x, y), (x+w, y+h), (0,255, 0), 3)
cv2.putText(img2, "Cat Faces - #{}".format(i + 1), (x, y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.55, (0, 0, 255), 2)
- (220,90,230)和(0,255,0)是我们要绘制的矩形的颜色。你可以玩玩它们,看看颜色是怎么变化的。
- (3)是线条的粗细。您可以更改该值并查看其外观。
保存您的结果
最后,我们将保存检测到人脸的图像。要看到你工作的最终结果,最好的方法就是保存下来,然后检查。确保变量名传递正确。在运行最后一段代码之前,如果一切正常,我建议继续检查整个代码。
#Saving the images using imwrite methodcv2.imwrite("faces_detected1.png", img1)cv2.imwrite("faces_detected2.png", img2)
结果
这是我的工作成果。第一个是人脸检测,第二个是猫脸检测结果。如你所见,我们的机器知道哪个是人,哪个是猫脸。我还通过将两张图片合成一张来测试这个程序。我收到的结果可以在下面找到。
faces _ detected1.png
faces _ detected2.png
额外的
不要逐个测试每个图像,让我们看看当我们将两个图像组合成一个图像并运行代码时会发生什么。我们可以看到,我们的机器现在能够理解和区分猫和人脸。
结果
恭喜你。!你已经创建了一个程序来检测图像中的猫和人脸。现在,你有一个想法,如何教一台机器同时为你做几件事。希望你喜欢这篇教程,并在今天学到一些新东西。计算机视觉是一个伟大的领域,你可以做的事情是无限的。请随意在不同的图像上测试您的代码,看看它是如何工作的。它可能不适用于所有图像,因为预测依赖于训练数据。在未来的帖子中,我计划向您展示如何用您自己的数据集训练机器,以便它可以为您提供更好的预测。
谢谢你,
你可能会感兴趣的机器学习项目:
如何使用文本识别器改进笔记记录过程
towardsdatascience.com](/building-a-simple-text-recognizer-in-python-93e453ddb759) [## 用 Python 构建语音识别器
使用谷歌云语音 API 将您的音频文件转换为文本
towardsdatascience.com](/building-a-speech-recognizer-in-python-2dad733949b4)
构建云原生、云无关的数据湖
摆脱云供应商的束缚
凯西·霍纳在 Unsplash 上的照片
为什么还要这样做?
最近,我有机会帮助我的一个客户解决一个有趣的问题。
他们在公共云平台上为特定地区构建了完整的数据湖和分析解决方案,并希望将该解决方案部署到另一个地区。负责管理该解决方案的部门希望该解决方案在不同的公共云平台上实施。
该解决方案基于公共云提供商提供的功能丰富的服务,要在不同的云平台上实施该解决方案,需要进行大量的重新工作。我的客户发现自己被绑上了金手铐。
这种特殊情况可能是一种独特的情况,可能适用于大公司,但越来越多的组织现在寻求在任何广泛可用的公共/私有云平台上实施其解决方案的灵活性。毕竟,云做出的一个重大承诺是实现解决方案的灵活性,那么现在它怎么能把它拿走呢。
有什么解决办法?
近年来,Kubernetes 已经成为实现云原生但与云无关的解决方案的黄金标准。对我来说,一些突出的好处是:
- 基于 Kubernetes 构建的解决方案可以使用行业标准的模式和工具。这些应用程序是可移植的,随时可以部署在任何平台(公共或私有)上。
- 它通常也比使用云提供商提供的现成服务便宜。
- 随着应用程序变得越来越复杂,Kubernetes 将更多的控制权交给了开发团队,使他们能够轻松地进行构建。
- 有大量的软件发行版可以作为 docker 图像和舵图表,很容易根据您的需要配置它们。
另一方面,基于 Kubernetes 的解决方案需要更多的努力来支持和管理。
好了,现在我们已经奠定了基础,让我们来看看所提议的解决方案的概要设计
作者图片
如您所见,我们使用 Kubernetes 作为我们的数据湖和分析解决方案的基础部分和抽象层,这将分离底层基础架构,并为您提供迁移到任何公共/私有/混合云解决方案的灵活性。
现在,让我们逐一探究该设计中的每个组件:
- 对象存储(Object Store):基于 S3 的存储是我们解决方案的绝佳选择,S3 与 Spark 合作,并且有一个全面的 API 列表(感谢亚马逊),可以用所有主要的编程语言与 S3 交互。 MinIO 完全符合要求。这是一个高性能,Kubernetes 本机对象存储,并会谈 S3。MinIO 将用于存储与 ETL 和下游处理相关的数据,而对于长期归档,公共云提供商将更加经济实惠。
- ETL :对于我们的 ETL 需求,我们使用了 Spark(具体来说就是 Pyspark)。它是快速的、分布式的,并且与 S3 配合得很好,所以不需要将所有数据导入 HDFS。Spark 原生支持 Kubernetes 已经有一段时间了,未来的管道看起来更有希望。
- 数据交付:独立 Hive 元存储和 Presto 的结合让您可以直接从您的 S3 存储中查询数据。Presto 是分布式的、可扩展的,符合我们并行处理的设计模式。它可以通过 JDBC 连接获得,并允许许多应用程序轻松地连接和查询数据。
- 工作流管理 : Apache airflow 是一个基于 Python 的工作流管理工具,它使您能够调度作业,创建复杂的作业依赖关系,定义重试和通知逻辑,所有这些都在 Python 中基于配置-代码的模式中完成。
- 治理:我们正在用各种工具和技术构建一个解决方案。使用 DevOps 和适当的日志记录和监控的原则是最重要的。我们将使用 Docker 来管理我们的映像注册表,使用 Git 和 Jenkins 来管理源代码控制和 CI/CD 管道,使用 Prometheus 和 Grafana 来监控我们系统的健康状况。
结论
这个解决方案中有许多组件,从头构建并维护它不是一件简单的任务。对我们来说,这是必要的,在 Kubernetes 上构建定制数据湖和分析解决方案的好处大于坏处。
我将尝试更详细地重新审视这些组件,并提供一些示例代码来帮助开发过程。同时,请随时留下任何反馈/建议/评论。
从头开始构建云架构堆栈
新冠肺炎推文的数据接收管道
什么是自动气象站云形成
CloudFormation(CF)是一项服务,它允许您通过模板设置和管理 AWS 资源。这使得您可以将更多的时间用于开发应用程序,而不是管理和配置资源。
所以如果要建立以下基础设施;
- 安全小组
- EC2 实例
- 一卷
- 托管数据库(如 Amazon RDS)
AWS CF 将使用正确的配置按正确的顺序配置所有资源
自动气象站云形成的一些好处:
- 代码为的基础设施
- 因为资源不是手动创建的,所以可以通过 git 建立版本控制。对基础设施的改变现在可以通过代码来控制。
- 一旦创建了一个模板,您可以通过估计成本选项找出每月的成本!
- 通过创建堆栈或删除它,部署或销毁任何资源也很容易。
我们将从这篇文章中学到什么?
在本帖中,我们将创建一个 CloudFormation 堆栈来提供以下资源:
- 一个弹性搜索域:用于存储和查询推文
- 一个 S3 桶:存储未能处理的推文
- Kinsesis firehose:用于流式传输 covid19 推文
- Lambda 函数:用于处理推文
AWS 数据管道。使用 draw.io 创建
首先让我们了解我们正在处理的数据,然后我们将了解摄取管道。
新冠肺炎推特流
Twitter 在他们的 Twitter 开发者实验室中发布了一个流媒体端点。流媒体端点将根据其内部 COVID19 注释返回推文。端点配置了一组过滤器,提供了关于该主题的对话的综合视图。
有兴趣探索实验室吗?我们在实验室中发布的端点是可能会更广泛发布的工具的预览…
developer.twitter.com](https://developer.twitter.com/en/docs/labs/covid19-stream/overview)
这些推文是由南加州大学的一个团队从流媒体端点收集的。该数据集根据知识共享署名-非商业性使用-类似共享 4.0 国际公共许可证( CC BY-NC-SA 4.0 )进行许可。通过使用该数据集,您同意遵守许可中的规定,继续遵守 Twitter 的服务条款,并引用以下手稿:
Chen E,Lerman K,Ferrara E 追踪关于新冠肺炎疫情的社交媒体话语:公共冠状病毒推特数据集的开发 JMIR 公共卫生监测 2020;PMID: 32427106
截至 2020 年 9 月 14 日,该数据集拥有超过 5 . 38 亿条推文!
Covid19 数据集中的推文总数
数据摄取管道
由于 Twitter 开发人员 API 的 ToS,只有 tweet IDs 存储在 github repo 中。这被称为将推文脱水。
更新推文是当我们使用推文 ID 并调用 twitter API 来填充其他字段(字典键)时,更新的推文然后被放入一个数据流中,该数据流写入 Kinesis firehose。
Lambda 函数用于处理批量为 5MiB 的推文。
Lambda 函数用于从 Tweet 对象中选择特定的一组键。
处理后的 tweets 随后被存储在 ElasticSearch 域中。如果流程失败,它们将被路由到 S3 存储桶。S3 存储桶也可以用来存储 e S 索引的快照。
给推文 id 补水
我已经在下面的 github repo 中上传了这个项目的 python 代码和其他文件。请随意使用、分享和使用它:
https://github . com/skyprince 999/Data-Engineering-covid 19-ETL
我们现在将创建用于调配资源的堆栈。
S3 铲斗的造云模板
这是我们栈中最简单的模板。事实上,您甚至不需要指定 bucket-name!
弹性搜索领域的云信息模板
我们将使用模板为 ES 域提供配置。我们在集群中有 4 个数据节点(实例计数)每个都是类型 t2.small ( 实例类型)
所有节点都有 35GiB 的 EBS 卷( VolumeSize )
ElasticSearch 版本是最新的(7.7)(elastic search version)
下一个要点是提供 es 域的访问策略。我们允许在域上执行所有操作。对 SourceIP (*)也没有限制,这意味着您可以从任何 IP 地址访问该域。
这不是配置访问策略的最佳实践。您可以将访问策略更改为更具限制性。
kine sis 消防水带云形成模板
cloudformation 模板用于配置 Kinesis 消防软管。该流的类型为 *DirectPut。*数据的缓冲时间间隔为 300 秒或直到大小为 5mb!
处理后的数据存储在 ElasticSearch 域中,而失败的数据存储在 S3 桶中。因为 ES 域和 S3 桶是通过 CF 栈创建的。我们可以通过使用 Fn::GetAtt 函数来访问他们的域名
查看我的公共 github repo 中完整的 CloudFormation 模板:
[## sky prince 999/数据工程-Covid19-ETL
通过在 GitHub 上创建帐户,为 skyprince 999/Data-Engineering-covid 19-ETL 开发做出贡献。
github.com](https://github.com/skyprince999/Data-Engineering-Covid19-ETL)
模板文件可以通过 CloudFormation 控制台上传。
云形成控制台。上传模板 yaml 文件
在设计器中检查模板,然后将其上传到 S3 存储桶。
为堆栈提供一个名称,然后检查配置。您可以使用 AWS 估算器来计算资源的成本。
我们配置的总成本约为 2300 美元(每年);每月支付约 200 美元
用 Python 构建颜色识别器
使用 OpenCV 的简单实用的机器学习应用程序
在 Unsplash 上由 Kelli Tungay 拍摄的照片
在这篇文章中,我将向你展示如何使用 Python 来构建你自己的颜色识别器。这个过程也称为“颜色检测”。我们将创建一个基本的应用程序来帮助我们检测图像中的颜色。该程序还将返回颜色的 RGB 值,这非常有用。许多图形设计人员和网页设计人员会理解 RGB 值是如何有用的。构建颜色识别器是开始使用计算机视觉的一个很好的项目。
如果你以前没有听说过计算机视觉,这是了解它的最好时机。大多数机器学习和人工智能领域都与计算机视觉有着紧密的联系。随着我们的成长和探索,看到外面的世界对我们的发展有很大的影响。这对机器来说也是一样的,它们通过图像来观察外部世界,这些图像被转换成计算机可以理解的数据值。
在以前的帖子中,我展示了如何检测人脸以及如何识别图像中的人脸,这些都是在人工智能和计算机视觉中实践 python 的伟大项目。让我们做点工作吧!
目录
- 入门
- 库
- 定义图像
- 颜色识别
- 应用
- 结果
入门指南
我们将为这个项目使用三个主要模块。他们是 NumPy,熊猫和 OpenCv。OpenCv 是一个高度优化的库,专注于实时应用。
OpenCV(开源计算机视觉库)是一个开源的计算机视觉和机器学习软件库。OpenCV 旨在为计算机视觉应用提供一个公共基础设施,并加速机器感知在商业产品中的应用。
每当贝希克居文出版时收到电子邮件。注册后,如果您还没有,您将创建一个中型帐户…
lifexplorer.medium.com](https://lifexplorer.medium.com/subscribe)
图书馆
如前所述,本项目将使用三个模块。要使用这些模块,我们必须安装必要的库。使用 pip 安装库是一个非常简单的步骤。Pip 是一个包管理工具。我们将使用命令行界面进行安装。下面是一次安装所有 3 个库的代码行:
pip install numpy pandas opencv-python
安装完成后,我们必须将它们导入我们的程序。在您喜欢的代码编辑器中打开一个新文件。以下是关于如何导入已安装库的代码:
import numpy as np
import pandas as pd
import cv2
OpenCv 作为 cv2 导入。对于其他库,我们将它们“作为”导入,以便在程序中更容易调用它们。
完美!现在,我们可以进入下一步,我们将定义要用来测试颜色识别器应用程序的图像。
定义图像
你可以选择任何你想要的图像。我会将我的图像保存在与我的程序相同的文件夹中,这样更容易查找和导入。
img = cv2.**imread**("color_image.jpg")
为了给你一些想法,这里是我将在这个项目中使用的图像:
太好了!你准备好编程了吗?抓紧时间,让我们进入下一步。
颜色识别
让我问你一个好问题。你知道机器是如此纯洁吗?嗯,我认为他们是因为你教他们什么,他们就学什么。它们就像一块白色的大画布。而你的程序就是你的画笔:)
教授颜色
首先,我们要教他们颜色。为此,我们需要包含颜色名称和一些与这些颜色匹配的值的数据。因为大多数颜色可以用红色、绿色和蓝色来定义。这就是为什么我们将使用 RGB 格式作为我们的数据点。我找到了一个现成的 csv 文件,其中有大约 1000 个颜色名称和 RGB 值。这里是 GitHub 链接。我们将在程序中使用这个 csv 文件。该文件的截图可以让您有所了解:
colors.csv
让我们使用 read_csv 方法将 colors.csv 文件导入到我们的程序中。因为我们下载的 csv 文件没有列名,所以我将在程序中定义它们。这个过程被称为数据操作。
index=["color", "color_name", "hex", "R", "G", "B"]csv = pd.read_csv('colors.csv', names=index, header=None)
全局变量
在下面的步骤中,我们将定义两个函数。为了让应用程序顺利工作,我们需要一些全局变量。你将知道在使用函数时全局变量是如何有用的。
clicked = False
r = g = b = xpos = ypos = 0
颜色识别功能
当我们双击图像的一个区域时,这个函数将被调用。它将返回颜色名称和该颜色的 RGB 值。这就是奇迹发生的地方!
def recognize_color(R,G,B):
minimum = 10000
for i in range(len(csv)):
d = abs(R- int(csv.loc[i,"R"])) + abs(G- int(csv.loc[i,"G"]))+ abs(B- int(csv.loc[i,"B"]))
if(d<=minimum):
minimum = d
cname = csv.loc[i,"color_name"]
return cname
鼠标点击功能
这个函数用来定义我们的双击过程。在创建我们的应用程序部分时,我们将需要它。
def mouse_click(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDBLCLK:
global b,g,r,xpos,ypos, clicked
clicked = True
xpos = x
ypos = y
b,g,r = img[y,x]
b = int(b)
g = int(g)
r = int(r)
希望你还和我在一起!这看起来可能有点复杂,但是当你开始在编辑器中写它们时,大局就会变得清晰起来。我尽最大努力让事情简单易懂。我会在这篇文章的最后加上我的联系方式,如果你需要任何帮助,请联系我。
应用
我很高兴你走到了这一步。在这一步,我们将使用 OpenCV 方法打开图像作为一个新窗口。在该窗口中,我们将使用之前定义的函数。这个应用程序非常简单,当你双击图像上的某个区域时,它会返回颜色名称和颜色值。
应用程序窗口
首先,让我向您展示如何使用 OpenCV 在新窗口中打开图像文件。
cv2.namedWindow('Color Recognition App')
其次,让我们调用我们创建的鼠标点击函数。这为我们的应用程序提供了更多的功能。
cv2.setMouseCallback('Color Recognition App', mouse_click)
应用程序
下面是开始我们的应用程序窗口工作的 while 循环。
while(1):cv2.imshow("Color Recognition App",img)
if (clicked):
#cv2.rectangle(image, startpoint, endpoint, color, thickness)-1 fills entire rectangle
cv2.rectangle(img,(20,20), (750,60), (b,g,r), -1)#Creating text string to display( Color name and RGB values )
text = recognize_color(r,g,b) + ' R='+ str(r) + ' G='+ str(g) + ' B='+ str(b)
#cv2.putText(img,text,start,font(0-7),fontScale,color,thickness,lineType )
cv2.putText(img, text,(50,50),2,0.8,(255,255,255),2,cv2.LINE_AA)#For very light colours we will display text in black colour
if(r+g+b>=600):
cv2.putText(img, text,(50,50),2,0.8,(0,0,0),2,cv2.LINE_AA)
clicked=False
关闭应用程序
如果您使用过 OpenCV 项目,您可能对这个步骤很熟悉。我们必须定义如何结束和关闭应用程序窗口。否则,它将永远运行,因为我们使用了 while(1) 来启动应用程序。添加下面几行对于您将来的项目来说是一个很好的实践。
#Break the loop when user hits 'esc' key
if cv2.waitKey(20) & 0xFF ==27:
breakcv2.destroyAllWindows()
结果
目前,我正在为这个项目制作一个演示视频。我收到了许多关于演示视频的积极反馈,它让我更好地了解了项目和申请流程。视频将发布在我的 youtube 频道 上。
(更新:视频准备好了,下面有。谢谢😊)
视频演示
恭喜你。!您已经创建了一个很酷的计算机视觉应用程序,它可以识别图像中的颜色。现在,您对如何在实际项目中使用计算机视觉有了一些了解。希望你喜欢读我的文章。如果你今天学到了新东西,我会很高兴的。从事像这样的动手编程项目是提高编码技能的最好方式。
如果您在执行代码时有任何问题,请随时联系我。
更多计算机视觉项目:
使用 moviePy 库的动手机器学习项目
towardsdatascience.com](/rendering-text-on-video-using-python-1c006519c0aa) [## 用 Python 构建人脸识别器
使用 OpenCv 库进行实时人脸识别的分步指南
towardsdatascience.com](/building-a-face-recognizer-in-python-7fd6630c6340)
构建命令行应用程序来检查开源漏洞
弗朗茨·哈文·阿西图纳在 Unsplash 上拍摄的照片
开源软件、编程语言或项目中的漏洞是一件大事,因为一次利用可能会导致许多混乱,并导致大组织数千美元的损失。
许多公司一直在关注软件中的漏洞、依赖性和他们在驱动系统时使用的语言,因为如果其中一个漏洞被利用,它们可能会受到攻击。
幸运的是,我们有一个公共数据库,所有新发现的漏洞和常见弱点都在其中公布,并在发现后立即提供修复。这些公开发布的漏洞数据库可以在类似 CVE 、 NVD 、白源漏洞数据库等网站上找到。
通过这些网站,您可以轻松地查找带有 ID 的漏洞,并获得相关信息。您可以了解严重性级别、受影响的组件、有时是什么导致了错误、如何临时或永久地修复它。
我们还可以通过构建一个简单的命令行应用程序来查找漏洞细节和信息,从而自动化并加速这一过程。
因此,在本文中,我们将探讨如何使用 Python 构建一个命令行实用程序来查找漏洞细节。
设置 Python 环境
构建命令行实用程序的第一步是设置 Python 开发环境。当从事 Python 项目时,我总是建议建立一个虚拟环境,因为它使事情变得更容易,并有助于避免模块版本中的冲突。
如果您使用 Python 3,您可以轻松运行 python3 -m venv 来创建虚拟环境,或者安装 virtualenvwrapper 或 virtualenv 来帮助设置虚拟环境。你可以在这里阅读更多关于如何设置你的环境的。
一旦您的环境启动,下一件事就是安装构建我们的应用程序所需的模块:
$ pip install requests beautifulsoup4 click lxml
对于这个项目,我们安装了:
- 请求:Python HTTP 请求客户端库
- BeautifulSoup:用于从 HTML 和 XML 解析和提取数据的 Python 库
- 点击:一个丰富的 python 命令行框架
- LXML:用于处理 HTML 和 XML 的 BeautifulSoup deps。
接下来,我们可以使用以下内容创建文件夹结构:
$ mkdir vulr && cd vulr
$ touch scraper.py main.py __init__.py
以下是适用于您的环境的完整设置命令:
$ python3 -m venv vulr-env && source vulr-env/bin/activate$ pip install requests beautifulsoup4 click lxml$ mkdir vulr && cd vulr$ touch scraper.py main.py __init__.py$ pip freeze > requirements.txt$ touch readme.md .gitignore # optional
您应该会得到如下所示的内容:
编写我们的网页抓取器
要使用我们的命令行从 WhiteSource 漏洞数据库中获取详细信息,我们需要构建一个简单的 web scraper,用于从数据库中提取所需的数据和关于漏洞的信息。
之前我们安装了 Requests 和 Beautifulsoup,我们将一起使用它们来构建一个简单的刮刀,并提取关于漏洞的所有可用细节。
基本上,当给定一个特定漏洞的 CVE ID 时,我们的网络抓取器将提取该漏洞的可用信息。为了便于识别,CVE ID 是给每个已发布漏洞的唯一 ID。
现在让我们为我们的 scraper 编写一个基本的代码设置:
import requests
from bs4 from BeautifulSoupBASE_URL = "[https://www.whitesourcesoftware.com/vulnerability-database/](https://www.whitesourcesoftware.com/vulnerability-database/)"def get_html(url):
request = requests.get(url)
if request.status_code == 200:
return request.content
else:
raise Exception("Bad request")def lookup_cve(name):
pass
上面我们已经为我们的网页抓取器创建了一个基本结构。我们添加了 WhiteSource 漏洞查找 URL,添加了获取请求的 HTML 内容的函数,还添加了一个空的 lookup_cve 函数。
现在让我们前往这个 WhiteSource Vuln Lab ,打开开发者控制台,研究页面的 DOM 结构。
接下来的事情是提取请求网页时发送的标题和 cookies。为了向网页发送一个成功的请求,我们需要像浏览器一样工作,这样我们就不会得到一个禁止的错误。
您可以在“Network”选项卡上执行此操作,因此单击“on ”,然后单击“All”。然后点击发送的请求以获取网页。它通常是浏览器发出的第一个请求。
右键单击它,鼠标悬停在复制上,然后单击复制为卷曲。这将以 cURL 格式复制请求,包括其标题和 cookies:
现在提取 cURL 命令,包括 Python 请求的头和 cookies,我们可以很容易地使用这个工具。这将有助于将 cURL 命令转换成任何语言和流行的 HTTP 请求库。
你所需要做的就是粘贴你的 cURL 命令,选择 Python,你就会得到一个格式良好的 Python 请求实现:
现在,从第二个文本框开始,我们将复制出 headers 和 cookies 字典,并更新我们的代码,如下所示:
import requests
from bs4 from BeautifulSoupBASE_URL = "[https://www.whitesourcesoftware.com/vulnerability-database/](https://www.whitesourcesoftware.com/vulnerability-database/)"cookies = {
'_ga': 'GA1.2.1677532255.1591419793179',
...
}headers = {
'authority': '[www.whitesourcesoftware.com'](http://www.whitesourcesoftware.com'),
'cache-control': 'max-age=0',
...
}def get_html(url):
request = requests.get(url, headers=headers, cookies=cookies)
print(request.content)
if request.status_code == 200:
return request.content
else:
raise Exception("Bad request")
接下来要做的是使用 dom 结构有序地提取页面上显示的所有信息。
根据上面的代码,我们:
- 提取了描述、日期、语言、引用、严重性分数、top_fix、弱点和报告。
- 我们添加了另一个函数 extract_cvs_table,从页面右侧的 cvs 表中提取数据。
- 然后我们将结果组织成一个简单的字典
要测试这一点,只需调用函数并传递 CVE id:
cve_details = lookup_cve("CVE-2020-6803")print(cve_details)
然后运行:
$ python scraper.py
瞧啊。我们已经成功地创建了我们的网络刮刀。
构建我们的命令行应用程序
现在要做的下一件事是使用我们之前安装的 click 库构建我们的命令行应用程序。
正如我之前简要解释的,Click 是一个命令行框架,由于其简单性和结构性,它是你能找到的最好的框架之一。
首先,让我们看看 main.py 中的 CLI 代码设置:
import sys
import click[@click](http://twitter.com/click).group()
[@click](http://twitter.com/click).version_option("1.0.0")
def main():
"""Vulnerability Lookup CLI"""
print("Hey")[@main](http://twitter.com/main).command()
[@click](http://twitter.com/click).argument('name', required=False)
def look_up(**kwargs):
"""Get vulnerability details using its CVE-ID on WhiteSource Vuln Database"""
click.echo(kwargs)if __name__ == '__main__':
args = sys.argv
if "--help" in args or len(args) == 1:
print("Vulnerability Checker - Vulr")
main()
通过上面的设置,我们创建了一个名为 look_up 的命令,并向该命令传递了一个参数——name。这将是用于获取漏洞信息的命令。
要在这个命令上实现 web scraper,您需要从 scraper.py 导入 lookup_cve,并将参数传递给函数。一旦我们这样做了,我们就可以通过打印来显示结果数据。
下面是如何做到这一点:
要运行此程序:
$ python main.py look-up CVE-2014-8338
哒哒!我们的命令行应用程序正在工作。
最后的想法
到目前为止,我们已经探索了如何构建一个 web scraper 来从 WhiteSource 漏洞数据库中提取数据,以获得漏洞信息,并在命令行应用程序中实现它,以便它可以用于直接从命令行显示漏洞细节。
接下来你可以在 PyPI 上发布它,这样其他用户就可以使用 PIP 包管理器来安装和使用它。
用 Elasticsearch、Kubeflow 和 Katib 构建一个完整的基于人工智能的搜索引擎
让我们看看如何在 Kubernetes 的基础上建立一个完整的搜索引擎,提供人工智能个性化的结果
建立搜索系统很难。让他们准备好机器学习真的很难。开发一个完整的集成 AI 的搜索引擎框架真的真的很难。
所以我们做一个吧。✌️
在这篇文章中,我们将从头构建一个搜索引擎,并讨论如何通过使用 Kubeflow 和 Katib 添加机器学习层来进一步优化结果。考虑到用户的上下文,这个新层将能够检索结果,这也是本文的主要焦点。
正如我们将看到的,多亏了 Kubeflow 和 Katib,最终的结果相当简单、高效且易于维护。
由 Kubeflow 执行的完整管道,负责协调整个系统。图片作者。
为了在实践中理解这些概念,我们将通过实践经验来实现这个系统。因为它是建立在 Kubernetes 之上的,所以您可以使用任何您喜欢的基础设施(只要经过适当的修改)。在这篇文章中,我们将使用谷歌云平台( GCP )。
我们首先简要介绍概念,然后讨论系统实现。
所以,没有进一步的麻烦,
1.你知道,为了搜索
如果你接受为你的公司建立一个搜索系统的挑战,或者想为你自己建立一个,你很快就会意识到最初的步骤有些简单。
首先,搜索引擎必须包含用于检索的文档。由于我们将与 Elasticsearch 合作,让我们将其作为参考(关于介绍,请参考他们的官方文件
文档应该按照 JSON 格式上传到 Elasticsearch。例如,如果我们正在为一个时尚电子商务商店构建一个搜索引擎,这里有一个文档示例:
上传到 Elasticsearch 的文档示例。图片作者。
接下来是检索步骤,本质上是将搜索查询与文档字段进行匹配:
搜索词与文档字段匹配的示例。图片作者。
排序阶段应用一些数学规则,如 TF-IDF 或 BM25F 来找出如何正确排序,从最佳到最差匹配对文档进行排序。大概是这样的:
Elasticsearch 在数据库中存储的文档中运行 BM25 评分检索到的正确排名的结果示例。图片作者。
进一步的优化可以利用包含性能指标的文档的特定字段。例如,在前面的例子中,我们知道 t 恤的点击率(CTR,即点击和总印象之间的原因)是 CTR=0.36 。可以使用该信息添加另一个检索层,并且将具有更好 CTR 的文档显示在顶部(也称为“提升”):
在检索规则中添加性能指标层的示例。先前的第二好的文档上升到结果的顶部。图片作者。
到目前为止一切顺利。但是让我们看看如何进一步优化更多。
考虑每个用户都有一个特定的上下文。再以我们的时尚网店为例。一些交通可能来自南方地区,那里可能比北方地区更热。他们可能更愿意穿轻薄的衣服,而不是冬季专用的产品。
等式中还可以加入更多的上下文:我们可以根据顾客喜欢的品牌、类别、颜色、尺寸、使用的设备、平均消费金额、职业、年龄来区分他们,这样的例子不胜枚举…
这样做也需要一些额外的工具。让我们深入一点。
2.机器学习层
Learn-to-rank ( LTR )是机器学习的一个领域,它研究的算法的主要目标是对一系列文档进行适当的排序。
它本质上像任何其他学习算法一样工作:它需要一个训练数据集,遭受诸如偏差之类的问题,每个模型都比某些场景有优势,等等。
基本上改变的是,训练过程的成本函数被设计成让算法学习排序,并且模型的输出是给定文档对于给定查询的匹配程度的值。
从数学上讲,它简单地由下式给出:
在我们的例子中, X 包含了我们想要用来为搜索添加上下文的所有特性。它们可以是诸如用户的地区、他们的年龄、喜爱的品牌、查询和文档字段之间的相关性等值。
f 是应该被训练和评估的排序模型。
最后, J 对判断进行了扩展,对于我们来说,它是一个范围从 0(意味着对于给定的查询特性,文档不是很好的匹配)到 4(文档是非常好的匹配)的整数值。我们通过使用判断从最好到最差排列文档*。*
我们的主要目标是获得 f ,因为它表示将机器学习层添加到搜索结果中的排序算法。为了获得 f ,我们需要一个已经包含判断值的数据集,否则我们无法训练模型。
事实证明,找到这些价值是相当具有挑战性的。虽然如何做到这一点的细节不会在这里讨论,这篇的帖子对这个话题有一个彻底的讨论;简而言之,我们使用用户与搜索引擎交互的点击流数据(他们的点击和购买)来拟合模型,这些模型的变量产生了判断值的代理。
在 pyClickModels 上实现的图形模型示例,用于查找与搜索引擎结果相关联的文档的相关性。图片作者。
在计算判断之后,我们剩下的是训练排名模型。Elasticsearch 已经提供了一个学习排名插件,我们将在这个实现中使用。该插件提供了从决策树到神经网络的各种排序算法。
这是所需培训文件的一个示例:
Elasticsearch Learn2Rank 插件要求的训练步骤的输入文件示例。图片作者。
这个想法是为每个查询(“women t-shirt”)注册结果页面中打印的所有文档。对于每个人,我们计算他们的预期判断并构建特征矩阵X。
在实践中,我们将首先准备所有这些数据,并将其输入到 Elasticsearch 的 Learn-To-Rank 插件中,这将产生一个经过训练的排名模型。然后,它可以用来添加我们正在寻找的个性化层。
关于建造 X 的更多细节将很快被讨论。
我们现在准备训练模型。到目前为止一切顺利。但是,我们仍然有一个棘手的问题:如何知道它是否有效?
2.1 估价框架
我们可以从几种方法中选择来检查排名模型的性能。我们将在这里讨论的是基于用户点击或购买的平均排名指标( pySearchML 只关注购买事件,但点击可以互换使用)。
数学上,它由下式给出:
该公式参考完整的文档列表,对与每个购买(或点击)的项目相关联的每个排名进行求和。分母只是流程中汇总的商品数量的基数(用户点击或购买的商品总数)。
实际上,在训练一个排名模型后,我们将遍历验证数据集(包含用户搜索的内容和购买的内容),并使用每个搜索词向 Elasticsearch 发送一个查询。然后,我们将结果与用户购买的东西进行比较,以计算适当的平均排名。
实践中的验证框架示例。对于数据集中的每个用户,我们使用他们的搜索词从 ES 结果中检索已经实现的排名模型。然后,我们获取用户购买商品的平均排名以及它们在 ES 结果中的位置。图片作者。
上图说明了这个概念。对于每个用户,我们将他们的搜索词发送到 Elasticsearch,其中已经包含了最近训练的模型。然后,我们将搜索结果与用户购买的内容进行比较,并计算排名。在前面的示例中,红色 t 恤出现在 3 个检索到的项目中的位置 2。因为只购买了一件商品,所以排名=66%。**
我们对数据库中的所有用户运行相同的计算,然后对它们进行平均,得到最终的排名表达式。
请注意,最终的等级度量必须低于 50% ,否则该算法只是作为文档的随机选择器来执行。
这个值很重要,因为它用于选择最佳排名模型。这就是我们使用 Kubeflow 的 Katib 的地方。
现在让我们看看如何将所有这些概念放在一起并构建搜索引擎:
3.库伯流程编排
如前所述,Kubeflow 是管道处理的指挥者。它的职责多种多样,从为 Elasticsearch 和培训准备数据到运行整个培训流程。
它通过定义组件及其各自的任务来工作。对于 pySearchML,下面是实现的完整的管道:
管道是通过接收各种输入参数来定义的,比如bucket
和model_name
,我们将能够在执行时更改这些值(我们很快就会看到)。
让我们看看管道实施中的每个组件及其用途:
在 pySearchML 中逐步实现。图片作者。
1.准备 _ 环境
下面是如何定义 prepare_env 组件的:
- **图像是在该步骤中运行的组件的 docker 引用。
- **参数是发送给在 Docker 的映像
ENTRYPOINT
中执行的脚本的输入参数。 - pvolumes 将卷声明装入
\data
。
这里是prepare _ env 中的所有文件:
-
run.py
负责针对 BigQuer y 运行查询,并准备 Elasticsearch。它的输入参数之一是model_name
,它设置使用哪个文件夹作为处理数据的参考。lambdamart0
是一种已经实现的算法,可用于 Google Analytics(GA) 公共样本数据集。 -
[Dockerfile](https://github.com/WillianFuks/pySearchML/blob/master/kubeflow/components/prepare_env/Dockerfile)
将整个代码捆绑在一起,并作为ENTRYPOINT
执行run.py
脚本: -
lambdamart0
是一个文件夹,专用于以此命名的算法的实现。它是为处理 GA 公共数据而构建的,是该系统的一个示例。以下是它包含的文件:
[ga_data.sql](https://github.com/WillianFuks/pySearchML/blob/master/kubeflow/components/prepare_env/lambdamart0/ga_data.sql)
是一个查询,负责从 GA 公共数据集中检索文档,并将其导出到 Elasticsearch[es_mapping.json](https://github.com/WillianFuks/pySearchML/blob/master/kubeflow/components/prepare_env/lambdamart0/es_mapping.json)
是文档中每个字段的索引定义- 如前所述,
[features](https://github.com/WillianFuks/pySearchML/tree/master/kubeflow/components/prepare_env/lambdamart0/features)
携带 X 的值。在lambdamart0
示例中,它使用 GA 公共数据作为构建特性的参考。
请注意名为[name.json](https://github.com/WillianFuks/pySearchML/blob/master/kubeflow/components/prepare_env/lambdamart0/features/name.json)
的特性:
学习排名插件要求将每个特征定义为有效的弹性搜索查询,并且分数结果与 X. 相关联
在前面的例子中,它接收一个参数search_term
,并继续对返回 BM25 匹配的每个文档的字段name
进行匹配,这实际上变成了我们的“ X0 ”。
在查询和名称字段之间使用 BM25 不足以增加结果的个性化。定制层的另一个进步是定义如下的[channel_group.json](https://github.com/WillianFuks/pySearchML/blob/master/kubeflow/components/prepare_env/lambdamart0/features/channel_group.json)
:
它接收参数channel_group
(将用户带到我们的网络商店的渠道)作为输入,并返回相应渠道的 CTR。
这有效地准备了模型来区分用户的来源以及如何对每个组进行排序。具体来说,例如,来自付费渠道的用户可能与来自有机渠道的用户行为不同。如果训练足够好,排序算法应该准备好处理这些情况。
尽管如此,这并没有告诉如何通过使用每个用户的内在特征来个性化结果。因此,这里有一个解决这个问题的可能性。特征[avg_customer_price.json](https://github.com/WillianFuks/pySearchML/blob/master/kubeflow/components/prepare_env/lambdamart0/features/avg_customer_price.json)
定义为:
它接收参数customer_avg_ticket
作为输入,并为每个文档返回平均用户票和文档价格之间的距离的日志。
现在,排名模型可以在训练阶段学习如何根据每个项目的价格与用户在网站上的平均支出的距离来管理每个项目的排名。
有了这三种类型的功能,我们可以在 Elasticsearch 的基础上为搜索系统添加一个完整的个性化层。特性可以是任何东西,只要它可以被抽象成一个有效的搜索查询,并且它们必须返回一些最终被翻译成我们的值 X 的评分标准。
对于 prepare_env 组件中的内容:
- 要素被导出到 Elasticsearch。
- Elasticsearch 上创建了一个定义文档字段的索引。
- 从 BigQuery 查询文档并上传到 Elasticsearch。
- 创建 RankLib 需求(特性集存储等等)。
为了用新的数据和特性实现新的模型,只需在 prepare_env(类似于modelname2
)中创建另一个文件夹,并设置它将如何查询数据并将它们上传到 Elasticsearch。
2.验证数据集
这是一个简单的步骤。它包括从 BigQuery 检索数据,其中包含用户搜索的内容、搜索的上下文和购买的产品列表。
下面是用于检索数据的 BigQuery 查询。它基本上选择所有用户,他们的搜索和购买,然后结合他们的背景。结果的一个例子:
search_keys
可以包含设置客户上下文的任何可用信息。在前面的例子中,我们在网站上使用他们的渠道组和平均消费票。
这些数据是我们在计算之前讨论的平均排名时输入到验证框架中的。
请注意,系统构建了三个不同的验证数据集:一个用于训练期,另一个用于常规验证,最后第三个用于最终测试步骤。这里的想法是分析训练模型的偏差和方差。
3.训练数据集
如前所述,这是负责构建 RankLib 训练文件的组件。完整的脚本其实相当简单。首先,它从 BigQuery 下载包含用户在搜索页面上的交互的输入点击流数据。这里有一个例子:
请注意,与搜索相关的关键字在search_keys
中聚集在一起。这些值是我们发送给 Elasticsearch 并适当替换每个特性 X 的值,如 prepare_env 中所述。在前面的 JSON 示例中,我们知道用户搜索上下文是:
- 已搜索酒具*。*
- 直接来到店里。
- 在网站上平均花费 20 美元。
judgment_keys
将用户在搜索页面上看到的文档组成的会话和他们在给定文档上的交互结合起来。
这些信息随后被发送到 pyClickModels ,后者处理数据并评估每个查询-文档对的判断。结果是换行符分隔的 JSON 文档,如下所示:
注意,键的值是search_term:bags|channel_group:organic|customer_avg_ticket:30
。
如前所述,我们希望我们的搜索引擎知道上下文,并在此基础上进一步优化。因此,判断是基于整个选定的上下文提取的,而不仅仅是 search_term。
通过这样做,我们可以区分每个上下文的文档,例如,我们会有这样的场景,对于来自北方地区的客户,产品接收到的判断为 4,否则为 0。
请注意,pyClickModels 给出的判断值的范围是 0 到 1。由于 Learn-To-Rank Elasticsearch 插件是建立在 RankLib 之上的,这个值的范围应该在整数 0 和 4 之间,包括 0 和 4。我们接下来要做的是,用变量的百分位数作为参考来转换变量。下面是构建最终判决文件的完整代码:
以下是此步骤的输出示例:
这些数据需要转换成 RankLib 所需的训练文件。在这里,我们将判断、文档、查询上下文的信息与特性 X 结合起来(这里是从 Elasticsearch 检索 X 的代码示例)。
上一步中包含搜索上下文和判断键的每一个 JSON 行都被循环并作为一个查询发送给 Elasticsearch,输入参数为search_keys
。结果将是从先前的准备 _ 环境步骤中已经定义的 X 的每个值。
最终结果是一个类似如下的培训文件:
对于每个查询和每个文档,我们都有由 pyClickModels 计算出的估计判断、查询的 id 以及一个特性列表 X 及其各自的值。
有了这个文件,我们现在可以训练排名算法。
4.Katib 优化
Katib 是一款来自 Kubeflow 的工具,它提供了一个自动超参数优化的接口。它有几种可用的方法;pySearchML 中选择的是贝叶斯优化。
贝叶斯优化算法的例子。随着它从允许的域中采样更多的数据点,它可能越接近给定函数的最佳值。在 pySearchML 中,域是一组变量,设置排名器应该如何拟合数据,它优化的成本函数是平均排名。图片来自维基媒体基金会。
Katib 所做的是根据勘探-开采之间的权衡为每个超参数选择一个新值。然后,它测试新模型并观察用于未来步骤的结果。
对于 pySearchML,每个参数都是一个 RankLib 的输入,RankLib 设置模型将如何拟合(例如使用多少棵树、总叶节点、网络中有多少神经元等等)。
Katib 是通过 Kubernetes 的自定义资源定义的。我们可以通过定义一个 YAML 文件并将其部署到集群来运行它,如下所示:
kubectl create -f katib_def.yaml
Katib 要做的是通读 YAML 文件并开始试验,每个试验一个特定的超参数值。它可以实例化并行运行的多个 pod,执行实验定义中指定的代码。
以下是此步骤中的文件:
[launch_katib.py](https://github.com/WillianFuks/pySearchML/blob/master/kubeflow/components/model/launch_katib.py)
负责从 Python 脚本启动 Katib。它接收输入参数,构建 YAML 定义,并使用 Kubernetes APIs 从脚本本身启动 Katib。
[experiment.json](https://github.com/WillianFuks/pySearchML/blob/master/kubeflow/components/model/experiment.json)
作为实验定义的模板。下面是它的定义:
它本质上定义了并行运行多少个 pods,以及为每个试验运行哪个 Docker 图像及其输入命令。请注意,并行运行的 pods 总数以及最大试验次数在 pySearchML 中是硬编码的。最好的方法是从管道执行中接收这些参数,并相应地替换它们。
launch_katib.py 将读取该模板,构建最终的 YAML 定义并将其发送给 Kubernetes,后者将启动 katib 流程。
其中一个输入参数是 ranker 它是从 RankLib(如 lambdaMart、listNet 等)中选择的排序算法。每个排名器都有自己的一组参数,下面是 launch_katib.py 中实现的 LambdaMart 算法的示例:
Katib 将从上面定义的域中选择参数,并运行 train.py ,其中 RankLib 被有效地用于训练排名模型。Python 中实现的命令示例:
这个字符串被发送给一个subprocess
调用(注意它需要 Java,因为 RankLib ),这个调用启动了训练过程。结果是一个新训练的排名模型,可以导出到 Elasticsearch。
当模型合适时,调用 validate.py 来计算期望的等级。发生的步骤是:
-
该脚本遍历验证数据集中的每个 JSON。
-
每一行都包含搜索上下文,然后用于构建 Elasticsearch 查询。下面是模型
lambdamart0
使用的查询,我们稍后会用到它: -
给定最近构建的查询,向 Elasticsearch 发送一个请求。
-
在搜索结果和购买的文档之间进行比较。
下面是负责构建 Elasticsearch 查询的代码:
注意,参数rescore_query
触发了 Elasticsearch learn-to-rank 插件上的机器学习层。
最后,函数compute_rank
将所有这些放在一起,如下所示:
Katib 实例化sidecars pod,它通过训练 pod 的 stdout 保持读取。当它识别字符串Validation-rank=(...)
时,它使用该值作为优化过程的结果。
在该过程中使用了一个持久卷来保存由 Katib 训练的最佳模型的定义,该模型将被我们的下一个组件使用。
5.后等级模型
最困难的部分已经完成了。现在所发生的是脚本简单地跟踪保存在文本文件中的最佳模型的定义,并将其上传到 Elasticsearch。
请注意,这种设计的主要优势之一是,该组件可以将模型导出到生产弹性搜索,而整个优化可以在分段复制引擎上进行。
6.最终测试
最后,当最佳模型被导出到 Elasticsearch 时,该系统就拥有了最佳优化排序模型。在该步骤中,执行最终验证,以便不仅验证一切工作正常,而且提供关于系统是否遭受偏差变化的进一步信息。
差不多就是这样!现在让我们运行一些代码来看看整个框架的运行情况。
4.动手操作部分
是时候在实践中实现整个架构了!完整的代码可从 pySearchML 资源库获得:
此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…
github.com](https://github.com/WillianFuks/pySearchML)
在这一节中,我们将使用 GCP 来用真实数据运行代码。此外,请记住,运行这个实验会有相关的成本(几美分)。
对于那些刚到 GCP 的人,有一个持续一年的 300 美元的免费信用礼品;只需登录并为本教程创建一个项目(例如 pysearchml )。您最终应该可以访问如下所示的仪表板:
GCP 仪表板项目示例。图片作者。
通过命令行与 GCP 交互需要 gcloud 。安装它非常简单。初始设置完成后,确保您可以通过运行以下命令登录:
gcloud auth login
现在剩下的就很简单了。将 pySearchML 克隆到您的本地:
git clone pysearchml && cd pySearchML
在您的平台中启用 Kubernetes 引擎。之后,只需触发执行 cloudbuild ,它将负责创建整个所需的基础设施(这一步应该需要 5~10 分钟)。
下面是构建如何触发运行:
您可以在变量SUBSTITUTIONS
中选择合适的值。注意_VERSION
设置了要导出到 Kubeflow 的管道版本。设置好一切后,只需运行脚本:
./kubeflow/build/build.sh
在 cloudbuild 上执行的步骤。图片作者。
- 准备密钥以允许访问和授权进入 GCP 工具。
- 在构建机器中准备已知主机。
- 本地克隆 pySearchML。
- 在步骤 4 中运行的文件 create_k8.sh 负责在 Google Kubernetes 引擎( GKE )之上创建 Kubernetes 集群,以及部署 Elasticsearch、Kubeflow 和 Katib。与此同时,系统所需的所有 Docker 映像都被构建并部署到 Google Container Registry(GCR)中,供以后在 Kubeflow 中使用。
- 运行几个单元测试。这些对于确认系统是否按预期运行非常重要。此外,它并行编译 Kubeflow 管道。
- 最后,将管道部署到集群。
完成后,如果你浏览到你的控制台并选择“Kubernetes 引擎”,你会看到它已经启动并运行:
Kubernetes 集群部署到 GKE 准备运行。图片作者。
这是一个小集群,因为我们不会使用太多数据,这有助于进一步节省成本。
已经安装了 Kubeflow 和 Katib。要访问它,首先运行以下命令将您的 gcloud 连接到集群:
gcloud container clusters get-credentials pysearchml
之后,通过运行以下命令将处理 Kubeflow 的服务移植到本地:
kubectl port-forward -n kubeflow svc/ml-pipeline-ui 8080:80 1>/dev/null &
现在,如果您在端口 8080 上访问本地主机,您应该会看到以下内容:
Kubeflow 仪表盘。图片作者。
并且流水线准备好执行。
这个实验使用公开的谷歌分析样本数据集,它由在谷歌商店浏览的一小部分客户样本组成。它从20160801
到20170801
不等,包含每个用户搜索的内容以及他们如何与搜索结果交互。
选择pysearchml_0.0.0
,然后选择“+创建运行”。您应该看到一个屏幕,其中显示了 Python 管道脚本中定义的所有可能的输入参数。选择合适的参数后,运行代码即可。
执行后,预期的结果如下:
完全执行 pySearchML 中定义的整个管道。图片作者。
Katib 组件的输出:
Katib 组件打印的输出示例。图片作者。
我们可以看到一个排名 36.05% 。然后,我们可以比较测试组件的结果:
测试组件打印的输出示例。图片作者。
这里的排名是 40.16 % 比验证数据集差一点。这可能表明模型有点过度拟合;更多的数据或进一步的参数探索可能有助于缓解这个问题。
而且,差不多,你有它!Elasticsearch 现在有一个经过全面训练的新的机器学习层,可以根据客户的背景来改善结果。
如果您想浏览为每个步骤创建的文件,有一个可用的部署。在 pySearchML 文件夹中,只需运行:
kubectl apply -f kubeflow/disk-busybox.yaml
如果您运行kubectl -n kubeflow get pods
,您会看到其中一个 pod 的名称类似于“nfs-busybox-(…)”。如果你进入它,你就可以访问这些文件:
kubectl -n kubeflow exec -it nfs-busybox-(...) sh
它们应该位于/mnt/pysearchml
。
还有一个快速和肮脏的可视化的整个过程。只需运行:
kubectl port-forward service/front -n front 8088:8088 1>/dev/null &
在localhost:8088
访问你的浏览器。您应该会看到这个(又快又难看)的界面:
用于在新培训的 Elasticsearch 上运行查询的前端界面。图片作者。
结果示例:
它不仅允许我们摆弄结果,还能让我们更好地了解优化管道是否在工作。
这几乎就是让一个完整的搜索引擎运行人工智能优化来处理任何商店的收入流量所需要的全部。
5.结论
现在,这是一个挑战!
构建 pySearchML 相当困难,我可以有把握地说这是我所面临的最残酷的挑战之一😅。无数的设计、架构、基础设施被考虑,但大多数都失败了。
在 Kubeflow 和 Katib 之上集成整个流程的实现只是在几个备选方案已经测试过之后才实现的。
这种设计的优点是最终代码变得非常简单和直接。它是完全模块化的,每个组件负责一个简单的任务,Kubeflow 协调整个执行过程。最重要的是,我们可以把主要精力放在代码开发上,让 Katib 去做寻找最佳参数的艰苦工作。
开发过程并不简单。必须吸取几个教训,包括来自 Kubernetes 的概念及其可用资源。尽管如此,这一切都是值得的。结果,一个完整的搜索引擎可以用几行代码从零开始构建,准备好处理真正的流量。
作为下一步,人们可能会考虑用某种深度学习算法来取代 RankLib,这种算法将进一步从数据中提取上下文。这样做的主要挑战之一是系统的响应时间可能会增加,成本也会增加(必须评估利弊)。
不管使用什么排序算法,体系结构在很大程度上保持不变。
希望这对于在这个领域工作的人来说是一个有用的帖子。现在是时候让我们休息一下,思考一下学到的教训,为下一次冒险做准备了:)。
至于这个帖子,它当然值得以任务完成配乐结束。
和往常一样,
下次任务再见;)!*