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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

建立一个异常检测系统?它必须满足的 5 个要求

原文:https://towardsdatascience.com/building-an-anomaly-detection-system-5-requirements-it-must-meet-23c9527e7760?source=collection_archive---------33-----------------------

成功解决方案的建议——从信号分析到大规模分享见解

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

阿里·哈坚Unsplash 上的照片

介绍

如果您已经找到了自己的路,那么您的企业很可能已经将异常检测确定为大幅降低成本或寻找新增长机会的一种方式,并且您正处于规划解决方案的早期阶段。

构建自己的异常检测系统是完全可能的——但是要想成功,你需要满足这五个要求。

这五个测试不仅仅会节省你的时间和精力,它们是人们实际使用你的系统和看一次就把它和其他听起来不错但在现实生活中不起作用的技术解决方案一起扔进垃圾箱的区别。

因此,如果你只是为了乐趣而从事一个数据科学项目,并且你享受这个过程,就像达到最终目标一样——无论如何,请随意跳过这篇文章,继续探索你能做什么。

但是,如果你真的想建立一个使用时间序列数据的最先进的系统——从信号分析到大规模呈现输出——请继续阅读。

(还不熟悉异常检测?这里有几个初级读本):

要求 1——您的系统需要能够处理现实生活数据的复杂性

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

克里斯·利维拉尼在 Unsplash 上的照片

如果用户没有通过“嗅觉测试”,他们会发现很难相信系统的输出。直觉对用户很重要。如果他们看不到某些东西是如何组合在一起的,他们就不会相信这些东西——例如,为什么会标记异常,趋势和季节性是否被正确计算?特别是对于被认为是异常的数据点,这有助于建立对系统能力的信心。

一个好的方法是将信号分解成关键部分:趋势、季节性、残差(参见 Hyndman 等人的快速提示)。对残差执行检测。这就是“噪音”。这不一定是特定的分布。现实生活并不总是那么简单!

此外,很少有商业数据集预先标记了异常,历史异常不太可能已经被识别出来!

推荐:

  1. 总是分解你的信号成分并验证它们——这样做是为了安心,但也是为了对照你的直觉和你的用户的直觉。给他们看一些他们能解释的东西,并确保当你拆开它时,它仍然有意义。
  2. 为非参数检测方法设置一些合理的阈值。(注意—您需要为研发投入额外的时间/资源。让用户选择阈值—对一个人来说是异常的,对另一个人来说可能不是。
  3. 防止出现问题,因为您假设数据是预先标记的,而不是假设您的数据是未标记的。没有人有时间回去用他们认为异常的点来标记数百甚至数千个时间序列图表

要求 2——您的用户不会停留在一个指标上。它需要在规模上可访问

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

Miguel Henriques 在 Unsplash 上拍摄的照片

你从头开始——通过构建核心算法。但是用例几乎总是很快变得更加复杂,因为人们看到了它在一个特定例子中工作的价值。例如,一个分析团队可能正在跟踪整体销售指标的收入,发现一些有趣的异常情况。消息传到其他利益相关者那里,很快,人们开始要求在更精细的层面(例如,按国家、产品类别或收购渠道划分的收入)进行跟踪,而不仅仅是跟踪一个顶线指标,从而迅速产生数百或数千个新的时间序列。

拥有一个他们无法解释的异常检测系统是没有意义的。这些用户不会费力地浏览那么多时间序列图表。即使他们知道怎么做,他们也不可能有时间。

推荐:

  • 理论上来说,运行这些是可能的(技术/基础设施资源除外),但是以一种不会给用户带来过多信息的方式呈现输出是绝对必要的。
  • 仔细想想你的系统如何只共享与某个用户相关的异常。否则,任何潜在的有价值的信号都将淹没在噪声中。

要求 3——你需要尽量减少误报。比你想象的要快

无论你的算法有多好,任何异常检测器都无法提供 100%正确的是/否答案。假阳性和假阴性永远存在,两者之间有取舍。

人类操作员将不得不做出决定,即使在同一个团队中,对于什么构成异常也可能有不同意见。

在最初的构建过程中很容易忽略这一点,但不预先解决这一问题会带来一些风险,异常检测系统可能会向用户发出警报“风暴”,对于没有数据流背景的业务用户来说,这可能会感觉系统没有充分管理通知。

误报有两种形式:

1.数据在一段时间内意外或莫名其妙地丢失/不完整。

2.数据是完整的,但检测错误地标记了异常。

推荐:

  1. 如果数据缺失/不完整/迟交,请等待数据完整。但是您需要等待多长时间将取决于该指标刷新的频率——有不同的方法可以解决这个问题,可以是手动的,也可以是编程的。前者靠的是“直觉”和历史知识,不太可能规模化。
  2. 如果数据是完整的,但你仍然得到假阳性——检查分解结果和残差计算——这对人类有意义吗?否则,这可能会导致用户不信任输出。(我们在需求 1 中谈到了通过嗅探测试的重要性)。在这里,确保有一种方法可以根据您的发现来调整/调整您的算法,或者更好的是,允许用户挑出这些数据点供您研究!

**警告:**在极端情况下,用户将简单地关闭异常检测系统,以避免被虚假警报淹没,所有构建该系统的良好工作都将付诸东流

要求 4——您的系统需要考虑事件和“已知”异常

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

照片由贝内迪克特·盖耶Unsplash 拍摄

商业数据上的异常检测算法通常会发现提前已知的“大”事件,例如黑色星期五、圣诞节、复活节、企业促销。这些对用户来说并不奇怪,他们会预料到,并希望异常检测也能这样做。

推荐:

考虑这些事件有两种方式:

  1. 如果异常与已知事件一致,则抑制任何通知,或提供背景叙述;
  2. 使用基于历史观察的估计值,修改具有已知事件的时间范围的期望值。例如,如果我们知道黑色星期五通常会出现 80%的销售额激增,那么下次我们遇到黑色星期五并看到销售额激增时,在考虑异常现象是否值得注意时,应该考虑预期的峰值。

要求 5——让用户能够轻松地与其他利益相关者分享见解,并找出原因

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

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

经过所有这些艰苦的工作,终于到了在 IT / BI 团队之外分享这些异常现象的时候了!这是你一直努力的方向。

这一部分需要仔细计划和执行。有一些重要的驱动因素:

  1. 多个用户想要访问同一个被跟踪的指标(并且他们不想单独创建它们);
  2. 根据用户的要求,需要跟踪成百上千的指标;
  3. 并不是每个指标都会引发异常——您需要引导用户只关注最近发生的异常活动,以避免他们淹没在数据中;
  4. 用户将希望得到一个易于理解的、简明的消息,显示已经识别出了什么异常情况(如果可能的话,还有为什么!)

推荐:

所有这些都需要前端和后端协同工作,而不仅仅是一个数据库(对于大多数用户来说,从可访问性的角度来看,数据库至少要走几步)。像 PowerBI、Tableau 或 Looker 这样的传统仪表板可能不会在这里出现——它们不是为这种类型的用例设计的。

房间里的大象:

在发现异常(例如,英国的收入异常低)后,用户会很快想找出原因——这可能很难回答。这就是根本原因分析可以发挥作用的地方——请在以后的文章中注意这一点!

总而言之

让一个生产就绪的异常检测系统为业务用户正常工作不仅仅是在数据集上设置一个松散的算法。如果你是一个动手的数据科学家,我鼓励你尝试一下上面的技巧。

构建一个帮助你钓更多鱼的应用程序

原文:https://towardsdatascience.com/building-an-app-that-helps-you-catch-more-fish-b2eb76b885d4?source=collection_archive---------52-----------------------

一个警报系统使用数据通知你何时何地捕鱼

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

凯利·西克玛在 Unsplash 上的照片

我最近开始涉足淡水捕鱼。任何一直在钓鱼的人都知道,这可能是命中或错过,特别是如果你是这项运动的新手或在一个不熟悉的地方钓鱼。没有人想得到*【一败涂地】*。幸运的是,养鱼使得这种情况更容易避免。

鱼类放养是指在孵化场饲养鱼类,并将其放入水体,以帮助补充现有种群或在没有种群的地方创造新的种群。放养通常由国家部门完成,它们也有助于休闲渔业,提供更丰富的鱼类种群。

在美国,州保护或环境部门经常在网上发布库存更新。通常,一旦人们看到他们已经被放养,他们就会聚集到这些地方,在接下来的几天里,这些地方会被大量捕捞。

这让我开始思考。如果我开发一个应用程序,可以抓取网站,并在库存更新时提醒我,会怎么样?

考虑到这一点,我决定构建一个 Python 脚本,并将其部署在 Heroku 上,以便在发现新的库存更新时通过电子邮件自动通知我。我的目标不一定是第一个尽快耗尽所有湖中的鱼,而只是意识到任何更新,而不是必须记住检查它。这样,如果我外出并得到通知,我可以顺便去钓鱼,享受一天中的时光!

下面,我将带您了解如何构建这个应用程序,以及它是如何工作的,以便您可以构建类似的应用程序。

目标数据

我将收集的更新是康涅狄格州能源和环境保护部(DEEP)发布的康涅狄格州鳟鱼放养报告。该报告存储在 PDF 格式的表格中,并放在他们的网站上。

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

CT DEEP 鳟鱼放养报告第 1 页。注:根据政策提取数据允许 CT 政府网站

报告顶部列出的日期将作为我们的指示器,指示自我们上次抓取 PDF 以来报告是否已更新。在此之下,每个页面都有一个长期运行的表,其中列出了所有特定的水体、它们的位置以及它们最后一次储存的详细信息。

读入 PDF 数据

我们要做的第一件事是创建一个单行文本文件last_stocked_date.txt,存储 PDF 的最后更新日期。首先,我们可以在文件中设置日期5/1/2021。这将允许我们读入数据,并将其存储到主程序的变量LAST_STOCK_DATE中。

接下来,我们要从网站下载并存储当前的 PDF。为了检查 PDF 文件是否已经更新,我们将使用pdfplumber打开文件,并仅从第一页提取所有文本。使用一些字符串操作,我们将基于子字符串“STOCKING UPDATE from”从该文本中提取日期。

检查最近的更新

在这里,我们将启动我们的主程序,并检查 PDF 中的日期是否与我们抓取并存储的上一个日期不同。如果是这样,程序将从前 8 页的表格中提取数据,并将其存储到数据帧中。我们只需要提取前 8 页,因为它们给出了库存的所有位置(任何超出的都是重复数据)。

接下来,我们将在 dataframe last_update中创建一个新列,该列只提取某个特定位置的最后库存时间,并将其转换为datetime类型。例如,我们可以通过过去 3 天的库存位置来过滤数据框。

此外,我们希望记得更新存储上次库存日期的文本文件。这将确保我们的脚本下次运行时,只有在确定了新日期的情况下才会继续处理。

发送电子邮件警报

接下来要做的是发送一封电子邮件来提醒我们鱼已经被放养了,以及它们被放养在哪里。

为此,我们需要首先设置环境变量来收集我们的 Gmail 帐户、凭据和收件人详细信息。由于发送电子邮件需要提供凭证,我们不想直接在我们的脚本中存储这样的敏感数据。相反,我们将创建一个环境文件来存储这些数据。这对于在本地运行脚本是可行的,但是当使用 Heroku 这样的云解决方案进行实时部署时,我们还需要将这些环境变量定义为Config Vars

接下来,我们可以加载所需的环境变量。

我们还希望将之前存储位置的过滤数据框转换为字符串,以便我们可以将它包含在电子邮件的消息或正文中。之后,我们可以把邮件的所有内容拼凑起来,选择我们想要的邮件主题。

有了这个设置,我们应该能够运行脚本并收到类似这样的电子邮件!注意——使用谷歌的 Gmail 时,您可能会在第一时间收到安全通知,并且可能需要并允许 不太安全的应用 使用您的凭据发送电子邮件。

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

程序成功发送电子邮件提醒的示例(由作者提供)

把所有东西放在一起

我们现在有一个完整的预警系统来跟踪鱼类资源的更新!完整的代码将包括错误处理,以及捕捉任何通知我们可能发生的任何潜在问题,如果 PDF 文件格式或数据以某种方式改变,不能再由程序的代码捕获。

自动化脚本

从这里开始,最后一步是自动运行警报系统。有许多方法可以做到这一点,但主要有两种方法:

  1. 在本地运行,通过Task Scheduler (Windows)或cron (Mac 或 Linux)等软件进行调度。
  2. 将程序部署到供应商的云平台,如HerokuAWS,并使用他们的工具对其进行调度。

第一种方法很容易设置,而且是免费的,但是需要启动机器才能运行脚本。第二种方法是托管在云中的服务器上,因此可以随时运行,但可能更复杂,并且可能需要花费资金来设置。

出于我们的目的,我已经使用免费会员在 Heroku 上部署了该应用程序,并安排脚本每小时运行一次。这足够每月免费运行,不需要超过 Heroku 为其基本会员提供的免费时间或积分。在 Heroku 上部署将需要我们的主程序中一些额外的步骤,以及额外的文件,如requirements.txtruntime.txt文件。

如果你更喜欢在本地运行程序,有很多很棒的教程教你如何使用像任务调度器这样的工具。

我希望你觉得这个教程是有用的,令人愉快的。如果您有任何问题或反馈,请联系我们。如果您对 Heroku 上更深入的部署指南感兴趣,请随时在下面发表评论!

这个项目的所有代码都可以在这个 Github 资源库 中找到,您可以下载并立即开始运行,无论是在本地还是在 Heroku(如果您有帐户的话)。

使用 Streamlit 上的调查数据构建应用程序

原文:https://towardsdatascience.com/building-an-application-with-survey-data-on-streamlit-5e7628597f31?source=collection_archive---------47-----------------------

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

乔里斯·贝特洛在 Unsplash 上的照片

在过去的几个月里,我一直在玩 Streamlit,因为它是一种仅用一个 Python 脚本就能生成数据科学 web 应用程序的非常棒的方式。

这项技术的美妙之处在于,它消除了对前端技术进行编程的要求,让您专注于好东西——讲述一个引人入胜的数据故事。

我处理大量的调查信息,我认为用我们从基于滑雪的调查中收集的数据构建一个应用程序会很有趣。

我用 Streamlit 开发这款应用的动机有几个原因:

  • 可共享性——将应用程序投入生产非常容易,它将位于 Streamlit 云上,并且为您提供了一个唯一的 url,您可以共享它,这使得它非常容易访问。它也是移动优先的,这对于跨设备兼容性非常好。
  • 互动性——我希望我的品牌合作伙伴和同事能够与应用程序互动和互动,通过调整输入参数产生不同的结果,从而提供更多价值。

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

Alex Lange 在 Unsplash 上拍摄的照片

本文将介绍如何在高层次上构建该应用程序,还有许多其他关于 Streamlit 复杂性的优秀文章。

数据清理

当调查数据从另一端出来时,通常会非常混乱——这是因为调查的问题和答案格式通常不会转换成清晰的格式化数据集。话虽如此,随着时间的推移,我利用我的经验来调整调查的问题结构,以使数据格式化过程更有效。

第一个目的地是将数据输入到 Jupyter 笔记本中,这样 Pandas 就可以用来将数据框格式化成我可以进行分析的东西。

在这里,我删除了包含调查问题信息的行,这样就只剩下了用户数据,并格式化了列,使它们易于使用——缩短名称、小写、无空格等。

数据工程

一旦我得到了我想要的信息,我就运行一些数据可视化来更好地理解数据,这让我可以开始构建我的故事。

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

探索性数据可视化

我想展示我们的观众根据他们一年滑雪的次数和他们喜欢的滑雪方式购买的品牌。

为了测试这一点,我在笔记本中构建了一个函数,然后调用该函数来查看输出。

简化 Python 脚本

一旦我从工程的角度理解了应用程序将如何运行,我就开始在一个. py 文件中构建应用程序。

如上所述,交互性对这个项目非常重要,我希望应用程序的用户能够选择输入数据,然后直接输入到脚本的核心功能中,然后产生输出数据和关键可视化。

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

选择框示例

我使用了 Streamlit 的 selectbox,它将选择的数据保存为变量,然后输入到核心函数并生成柱状图。

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

输出柱状图

结论

Streamlit 与我在 Python 中的数据分析技能相结合,使我能够创建一个交互式网络应用,将行人调查数据转化为一个工具,允许没有分析技能的用户提取大量价值。我很高兴看到技术的进步,我将继续探索 Streamlit 可以创造什么。

如果你想了解关于这个项目的更多信息,请在 LinkedIn 上与我联系,我将很乐意接受对话,该项目的源代码也可在 my GitHub 上获得。

用一行代码构建一个人工神经网络

原文:https://towardsdatascience.com/building-an-artificial-neural-network-in-one-line-of-code-9addc414c5e9?source=collection_archive---------17-----------------------

TensorFlow 2 最简单的神经网络

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

图片由维基媒体上的 mikemacmarketing 提供

关于人工神经网络的解剖和数学有大量的理论文章,所以我将采用另一种方法来撰写和教授这个主题。在这篇文章中,我们要马上动手了!

让我们直接开始吧。如果您想跳过安装部分,可以选择下面的部分。

安装
选项 1
选项 2
数据
模型
为什么要 TensorFlow?

装置

如果您已经安装了需求,那么您可以跳过这一节。

选项 1

我们需要做的第一件事是确保我们已经安装了 Python 编程语言,如果你还没有,那么就在这里安装它

请注意,如果在安装过程中询问您是否要将 Python 添加到 PATH 变量中,请务必同意。接下来要做的是打开终端或 CMD,这取决于您的操作系统。

如果您使用的是 windows,请按 Windows 按钮并键入“cmd”。然后双击结果顶部显示“命令提示符”的黑色图标。

现在只需输入:

pip install numpy
pip install matplotlib

pip install tensorflow

请注意,如果您在 Mac 或 Linux 上,您可能必须键入“pip3”而不是“pip”。

接下来你需要做的就是打开某种文本编辑器或 IDE,比如 nodepad、Pycharm、VSCode、Sublime 或其他编辑器。

选项 2

在你的谷歌硬盘中安装谷歌的合作实验室。你可以在网站上获得这样做所需的所有信息。

https://colab.research.google.com/notebooks/intro.ipynb#recent=true

Google Colab 的一个好处是你可以免费使用大量的计算能力。具体来说,你可以在云中的 GPU 上训练你的模型,这使得它成为一个很好的研究框架。

数据

当我们训练有监督的机器学习算法时,我们需要标记的数据。也就是说,我们需要一个数据集,其中对于每个示例 x 我们需要一个标签 y ,模型应该预测它何时被馈送 x

在本文中,我们将尽可能做最简单的事情。我们不会考虑测试,所以这是关于最佳实践的而不是!我们将简单地考虑一种线性关系,并通过在谷歌的机器学习库 TensorFlow 中建立一个只有一个神经元的神经网络来尝试拟合该模型。

让我们打开我们选择的编辑器,输入

这段代码确保加载了所有相关的库。对于某些 x ≥ 0 的情况,您可能希望 TensorFlow 的版本是 2.x,所以尝试一个简单的

print(tf.__version__)

您应该会看到类似 2.5.0 的内容。

让我们创建数据。我们将创建自己的数据。简单地像这样自己创造一个线性关系。

作为一个聪明的人,你可能已经注意到了这个模式。

如果你猜对了 f(x) = 1/2 + x/2 ,你就猜对了。

模型

想法是这样的:我们将显示来自 xs 数组的网络值,并以 ys 数组的形式告诉模型正确的答案,以便对于 x 的每个值,模型将做出猜测,并通过查看真实的对应 y 值来纠正自己。

然后,该模型将通过称为反向传播的东西来调整自己(我们将使用随机梯度下降),并且对于每个示例,该模型将会改进。

我们没有太多的数据,所以这当然会限制模型的准确性,但本文的唯一目标是捕捉神经网络的思想,并了解张量流的一些简单语法。

我们将在一行代码中创建单个节点的人工神经网络,即:

现在我们已经建立了网络,让我们来训练它。

优化器确保网络改进其猜测,并且损失函数测量单个猜测的好坏。

现在我们来做个预测。

我们大约得到了 4.12 。现在让我们策划一些预测。

我们得到的输出是下图,绿色显示地面实况,红色显示模型预测。

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

作者图片

请注意,这是而不是线性回归,因为这与“最佳拟合”没有任何关系,而是每次尝试都试图自我修正的模型的结果。数据的缺乏和模型的简单很能说明问题,但我们仍然设法在这个简单的任务中捕捉到了神经网络的本质。

为了充分理解这一点,请尝试再次运行此代码。你不会得到完全相同的预测,因为这是一个新模型,而机器学习模型本质上是概率性的。

例如,当我第二次运行它时,当我给模型输入数字 7 时,我得到了一个新的预测。我大概弄了 4.08 。你会得到与我不同的东西!

您可以尝试使用这段代码来熟悉(hyper)参数的语法和效果。

例如,尝试将纪元设置为 200 或 1000。试试其他线性关系。

为什么是 TensorFlow?

如果你想学习如何建立机器学习模型,TensorFlow 是一个非常好的选择,有几个原因。

TensorFlow 是当今最受欢迎的深度学习框架之一。

它是一个非常成熟的库,因为它是由 Google 构建的,并且它可以与 Python 一起使用,这是两个重要的原因,但是我们为什么不看看一些使用它的公司,感受一下它在行业中的重要性。

使用 TensorFlow 的公司包括

  • 爱彼迎(美国短租平台)
  • 空中巴士
  • 可口可乐
  • 谷歌
  • 美国英特尔公司(财富 500 强公司之一ˌ以生产 CPU 芯片著称)
  • 联想(电脑的品牌名)
  • 贝宝
  • Spotify
  • 推特

这样的例子不胜枚举…

所以 TensorFlow 将会一直存在,如果你想在未来成为一名数据科学家或 ML 工程师,有很多公司会雇佣 TensorFlow 开发人员,所以学习这个伟大的框架绝对值得你花时间。

我们到了这个关于张量流和神经网络的小而简单的介绍的结尾。

在未来,我会发布越来越多的高级机器学习帖子,但我们需要从简单开始。

如果您有任何问题、意见或顾虑,请联系 LinkedIn。

https://www.linkedin.com/in/kasper-müller-96ba95169/

下次见。

构建情绪检测应用程序

原文:https://towardsdatascience.com/building-an-emotion-detection-application-54697de9ae01?source=collection_archive---------32-----------------------

使用 AWS Rekognition 用不到 50 行 Python 代码构建计算机视觉项目

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

图片来自 Unsplash

计算机视觉(CV)可能是一个非常理论化和紧张的领域,需要大量的 ML 和数学知识来解开和理解为对象检测、面部识别和对象跟踪等主题提供动力的算法。如果你在理论上没有必要的经验,或者没有时间来构建一个定制的 ML/CV 模型, AWS Rekognition 可以让你通过 API 调用来构建强大的 CV 应用。AWS Rekognition 是 AWS 提供的众多自动人工智能服务之一。这些服务是为那些ML 中没有太多背景的开发人员,或者时间少的数据科学家快速构建强大的 ML 应用程序,或者根据你可能正在开发的定制模型进行性能基准测试。AWS Rekognition 是 AWS 上用于计算机视觉的事实上的自动人工智能服务。如果您对构建定制模型感兴趣,请查看关于如何在那里部署定制 TensorFlow 模型的 AWS SageMaker 和我的文章。对于本文,我们将构建一个 Streamlit 应用程序,它接受一幅图像,并使用 Rekognition 返回图像中检测到的主要情感。

注意:对于 AWS 的新手来说(有一些经验来完全理解这篇文章是很好的),如果你想继续下去,请确保在下面的 链接 中做一个记录。我还将提供一个我们将使用的服务列表,以及更深入的定义。如果您已经熟悉了这些服务,可以直接跳到代码演示。

目录

  1. AWS 服务
  2. 设置简化应用程序
  3. 集成认知
  4. 整个代码和结论

AWS 服务

AWS Rekognition:AWS 主要的 Auto-AI 计算机视觉服务。有大量的功能,从人脸检测,文本检测,到物体跟踪。

AWS S3 :亚马逊的主要存储服务,我们将使用该服务来存储我们的训练数据模型工件/信息。

Boto3 :针对 Python 开发者的 AWS 软件开发包( SDK ),可以用这个来配合 AWS 服务。在这个用例中,我们将使用 Boto3 与 S3 一起访问我们的图像并调用 Rekognition。

身份访问和管理(IAM) :通过权限和角色管理 AWS 服务的访问。在使用我的代码时,您可能希望通过 AWS CLI 对用户进行身份验证。这里有一篇文章详细介绍了设置过程,如果你需要帮助的话。

设置简化应用程序

在我们开始处理 Rekognition 部分之前,我们需要设置我们的 web 应用程序。我们希望我们的应用程序能够上传一个文件,然后我们可以使用 Rekognition 在后端处理它。Streamlit 有一个简洁的文件上传特性,我们可以在这个用例中使用。我已经为样本图像创建了一个小的目录,我们可以调用它进行分析。

将文件上传到 S3

我们从样本图像目录中捕获文件。然后,我们使用 Boto3 与 S3 合作,将我们的本地图像存储在我们创建的 S3 存储桶中。要创建 S3 存储桶,您可以转到 AWS 控制台手动创建,或者如果您有 AWS CLI 设置,您可以简单地运行AWS MB unique-bucket-name来创建您的存储桶。我们需要我们在 S3 的数据,因为 Rekognition 直接与 S3 集成,用于其 API 调用,从而将我们的图像上传到 S3 的代码。

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

文件上传到 S3(作者截图)

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

Streamlit 应用程序设置(作者截图)

我们现在有了一个 Streamlit 应用程序集,可以接受图像并将其推送到 S3,以便与 Rekognition 一起使用。

集成认知

我们现在可以专注于对样本图像进行情感检测。Rekognition 在 detect_faces 中有一个 API 调用,它获取输入图像并返回各种参数,例如:年龄范围、性别、眼睛睁开情况、情绪等等。出于这一应用的目的,我们将关注于情绪参数。我们首先需要为 Rekognition 创建一个 boto3 客户端,就像我们对 S3 所做的那样。

识别客户端

我们现在有了客户机,现在可以向 detect_faces API 调用输入适当的数据了。

重新确认 API 调用

现在我们已经得到了 API 响应,我们希望解析输出,将注意力集中在面部表情上。我们为演示上传的示例图像如下所示。

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

图片来自 Unsplash

我们现在解析响应,以显示检测到的多数情绪和所有其他情绪,以及 Rekognition 在该情绪中的置信度得分。

解析 Rekognition 输出

现在,如果我们使用streamlit run filename . py运行我们的 streamlit 应用程序,我们应该会看到我们的应用程序成功运行。

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

显示重新识别结果(作者截图)

我们看到大多数情绪以及 Rekognition 检测到的所有情绪,为了清理 UI,您还可以添加一个 CV 库,如 PIL 来显示您正在上传的样本图像或文件。

整个代码和结论

https://github.com/RamVegiraju/MoodDetectionApp

要访问该项目的完整代码,请单击上方的链接**。Auto-AI 正在快速扩张,AWS、Azure 和 GCP 等云提供商也在增长,并提供各种尖端服务,如 Rekognition,使您能够以简单的方式使用 ML 来支持应用程序。对于数据科学家和那些没有 ML 背景的人来说,Rekognition 对于快速启动和运行计算机视觉应用程序非常有用。在这些博客中查看一些更酷的 AWS 重新识别用例。**

我希望这篇文章对那些从事计算机视觉项目或探索 AWS 的人有用。请随时在 LinkedIn 上与我联系,或者在 T2 媒体上关注我,了解我更多的写作内容。分享任何想法或反馈,谢谢阅读!

在 Power BI 中构建端到端分析解决方案:第 1 部分—理解业务问题

原文:https://towardsdatascience.com/building-an-end-to-end-analytic-solution-in-power-bi-part-1-understanding-the-business-problem-85db9e2d745b?source=collection_archive---------24-----------------------

当我与不深入 Power BI 世界的人交谈时,我经常得到的印象是,他们认为 Power BI 只是一个可视化工具。在这一系列文章中,我将向您展示如何使用 Power BI 来创建一个成熟的分析解决方案。

在第一部分中,我们通过定义构建成功的分析解决方案的所有阶段来搭建舞台!

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

https://unsplash.com/photos/qwtCeJ5cLYs

当我与不了解 Power BI 世界的人交谈时,我经常得到的印象是,他们认为 Power BI 只是一个可视化工具。虽然这在一定程度上是对的,但在我看来,他们没有看到更大的图景,或者更好的说法是,他们看到的只是冰山一角!这个冰山一角是那些闪亮的仪表盘,KPI 箭头,花哨的人工智能东西,等等。

然而,事情远不止如此,因为真实的事情隐藏在表面之下……

在这一系列文章中,我将向您展示如何使用 Power BI 来创建成熟的解析解决方案 。从不提供任何有用信息的原始数据开始,构建不仅仅是好看的可视化,而是提取可用于定义适当行动的洞察力——我们称之为知情决策。

当我与不深入 Power BI 世界的人交谈时,我经常得到的印象是,他们认为 Power BI 只是一个可视化工具。虽然这在一定程度上是对的,但在我看来,他们没有看到更大的图景,或者更好的说法是,他们看到的只是冰山一角!这个冰山一角是那些闪亮的仪表盘,KPI 箭头,花哨的人工智能东西,等等。

然而,事情远不止如此,因为真实的东西就在表面之下…

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

作者使用 PowerPoint 的插图

这下面的部分,由多个单独的,但有凝聚力的部分组成,使表面上的作品闪闪发光!

在这一系列文章中,我将向您展示如何使用 Power BI 来创建一个成熟的解析解决方案。从不提供任何有用信息的原始数据开始,构建不仅仅是好看的可视化,而是提取可用于定义适当行动的洞察力——我们称之为知情决策。

搭建舞台

在这一系列文章中,我将使用一个包含纽约市汽车碰撞数据的开放数据集,可以在这里找到。这个数据集包含大约 180 万行。每一行代表纽约市发生的一起事故,至少有一人受伤/死亡,或者总损失至少为 1000 美元。数据来自 CSV 文件,包含 29 列。

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

晋振伟在 Unsplash 拍摄的照片

现在,在我们开始构建我们的解决方案之前,我们需要定义工作流并确定流程中的特定阶段。因此,第一个也是最重要的任务是设定创造最终结果的必要步骤。以下是我的清单:

  1. 了解业务问题 —这是起点,因为不了解业务问题,我们的解决方案就无法解决业务需求。我想增加销售额吗?留住客户是我的主要目标吗?如果我在下一季度放弃一些服务,会发生什么?这些是需要使用数据洞察来回答的业务问题的一些典型示例。在这个例子中,我们的“业务”问题是识别碰撞的关键位置,并试图防止将来发生事故
  2. 数据准备 —在这一阶段,我们需要执行一些步骤来使我们的数据为进一步的消化做好准备。从数据剖析开始,这样我们可以识别可能的异常值和异常,然后应用各种数据整形技术在数据成为我们数据模型的一部分之前准备数据
  3. 数据建模 —当我们构建一个解析解决方案时,数据模型必须满足(或者至少应该满足)一些与数据建模相关的一般假设。对于大多数分析系统,包括 Power BI,维度建模是必经之路——因此,我们需要分解原始的宽事实表,并利用星型模式概念来建立适当的数据模型
  4. 数据可视化 —这是文章开头的人最喜欢的阶段:)…是时候用数字来取悦我们的眼睛,并使用方便的 Power BI 视觉效果来显示它们了
  5. 数据分析——有一个好看的视觉是好的,但它需要给一个看着它的人提供一些洞察力。因此,这一阶段的主要目的是提供洞察力——例如,纽约市车祸的高峰时间是什么时候?最危险的地点是哪里?皇后区有多少行人受伤?等等…
  6. 明智的业务决策 —这是一个可选阶段,可以从该解决方案中排除,完全留给业务利益相关者。但是,嘿,让我们一直扮演我们的数据分析师角色,并根据我们在前一阶段获得的见解给出一些建议!

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

作者使用 PowerPoint 的插图

1.理解业务问题

构建您的(成功的)分析解决方案的第一步也是最重要的一步,为了达到其目的并被用户采用,就是给出关键业务问题的答案。没有人需要漂亮的仪表板和酷炫的视觉效果,如果它们不能提供洞察力并帮助决策者理解正在发生的事情及其原因。

我如何能增加我的销售?为什么上个季度那么多客户离开我们?我能做些什么来改善交付流程?什么时候是针对市场进行促销的最佳时期?

这些只是商业利益相关者最常问的几个问题。不仅如此——也许对底层数据的洞察可以帮助用户识别全新的模式并提出一个问题: 我们正在解决正确的问题吗?

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

斯蒂芬·道森在 Unsplash 上拍摄的照片

因此,在一开始就确定关键问题是极其重要的,这样我们就可以对我们的数据进行塑造和建模,以最有效的方式来回答这些问题。

对于我们的数据集,我们不必处理“经典”的业务问题——因为没有销售、产品、促销……然而,这并没有降低它的“价值”,更不用说允许我们跳过上面定义的一些步骤。我们的一些“业务”问题可能是:

  • 这个城市最危险的地方是哪里?
  • 一天中的哪个时间最关键?
  • 行人占所有受伤者的百分比是多少?
  • 哪个行政区的事故率最高?
  • 什么类型的汽车最容易发生事故?

找到这些问题的答案的最终目标是确定导致碰撞的关键指标(数据分析阶段),并设法采取行动,防止未来的事故,或至少减少事故数量(做出明智的决策)。

结论

Power BI 不仅仅是一个可视化工具!不断重复这句话,不要忘了开头的冰山插图。

在本文中,我们奠定了理论背景,并解释了每个成功的分析解决方案的关键支柱的概念。在下一部分中,我们将开始探索我们的数据集,尝试识别可能的异常,检查数据集的某些部分是否需要增强或重构,并最终将数据塑造成能够让我们为流程中的后续阶段构建高效数据模型的形式。

感谢阅读!

成为会员,阅读 Medium 上的每一个故事!

在 Power BI 中构建端到端分析解决方案:第 3 部分——提高数据建模水平!

原文:https://towardsdatascience.com/building-an-end-to-end-analytic-solution-in-power-bi-part-3-level-up-with-data-modeling-cfbf3e4e2cd?source=collection_archive---------20-----------------------

在我们清理和塑造了我们的数据之后,是时候升级游戏了!了解为什么星型模式和 Power BI 是天作之合,以及如何在 Power BI 中直接构建它!

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

福克斯在 pexels.com 拍摄的图片

当我与不深入 Power BI 世界的人交谈时,我经常得到的印象是,他们认为 Power BI 只是一个可视化工具。虽然这在一定程度上是对的,但在我看来,他们没有看到更大的图景,或者更好的说法是,他们看到的只是冰山一角!这个冰山一角是那些闪亮的仪表盘,KPI 箭头,花哨的人工智能东西,等等。

然而,事情远不止如此,因为真实的东西就在表面之下…

在这一系列文章中,我将向您展示如何使用 Power BI 来创建一个成熟的分析解决方案。从不提供任何有用信息的原始数据开始,构建不仅仅是好看的可视化,而是提取可用于定义适当行动的洞察力——我们称之为知情决策。

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

作者图片

在我们奠定了构建端到端分析解决方案流程背后的一些理论背景,并解释了为什么在构建解决方案之前理解业务问题至关重要,并应用了一些基本的数据分析和数据转换之后,现在是时候升级我们的游戏并花些时间来阐述我们的分析解决方案的最佳数据模型了。提醒一下,我们使用了一个关于纽约机动车碰撞的公开数据集,可以在这里找到。

简而言之,数据建模

当您构建一个分析解决方案时,创建一个 高效 解决方案的关键先决条件之一是拥有一个合适的数据模型。我不会深入解释如何构建企业数据仓库、OLTP 和 OLAP 模型设计之间的区别、谈论规范化等等,因为这些都是您需要掌握的极其广泛和重要的主题,尽管您使用的是 Power BI 或其他开发工具。

解析解决方案中最常见的数据建模方法是维度建模。本质上,这个概念假设所有的表都应该被定义为事实表或维度表。事实表存储事件或观察结果,如销售交易、汇率、温度等。另一方面,维度表是描述性的—它们包含关于实体的数据—产品、客户、位置、日期…

请务必记住,这一概念并不仅仅与 Power BI 相关,它是一个通用概念,已经在各种数据解决方案中使用了几十年!

如果你真的想从事数据领域的工作(不一定是 Power BI),我强烈推荐阅读这本书: 《数据仓库工具包:维度建模权威指南 ,作者 Ralph Kimball 和 Margy Ross。这是所谓的维度建模的“圣经”,并彻底解释了在构建解析解决方案中使用维度建模的整个过程和好处。

星象图和权力 BI——天作之合!

现在,事情变得越来越有趣了!对立双方之间正在进行讨论——是使用包含所有数据的单一平面表更好(就像我们目前在纽约碰撞数据集中使用的那样),还是规范化这个“胖”表并创建一个维度模型(称为星型模式)更有意义?

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

作者图片

在上图中,你可以看到一个典型的维度建模的例子,叫做星型模式。我想我不需要向你解释它为什么被这样称呼:)你可以在 Power BI 这里阅读更多关于星型模式相关性的内容。有一个有趣的讨论,星形模式是否是比在数据模型中只有一个表更有效的解决方案——星形模式反对者的主要论点是性能——在他们看来,如果没有连接、关系等,Power BI 应该工作得更快。

然后, Amir Netz ,微软分析公司的首席技术官和负责构建 VertiPaq 引擎的人员之一,在 Twitter 上澄清了所有的不确定性:

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

作者截图

如果你不相信一个完全知道事情如何在引擎盖下工作的人,那么也有一些由经验证的专家提供的额外的精彩解释,为什么星型模式应该是你在 Power BI 中建模数据的首选方式,例如【Patrick(立方体中的家伙)的这个视频,或者 Alberto Ferrari (SQL BI) 的这个视频。

而且,这不仅仅关乎效率,还关乎在您的报告中获得准确的结果!在这篇文章中,Alberto 展示了在一个平面表上编写 DAX 计算如何会导致意想不到的(或者说不准确的)结果。

不用深入解释为什么应该使用星型模式,让我向您展示使用一个平面表会产生不正确的数字,即使是一些琐碎的计算!

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

作者图片

这是我的平面表,其中包含一些关于销售的虚拟数据。假设业务请求是找出客户的平均年龄。如果有人问你顾客的平均年龄是多少,你会怎么回答?30,对吗?我们有一个 20 岁、30 岁和 40 岁的客户,所以平均年龄是 30 岁,对吗?来看看实力 BI 怎么说…

AVG Customer Age = AVERAGE(Table1[Customer Age])

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

作者图片

这怎么可能呢?!32 真的吗?!让我们看看我们是如何得到这个意外的(不正确的)数字的…如果我们将所有客户年龄值相加,我们将得到 320…320 除以 10(这是销售数字),瞧!好了,这是你的 32 个普通顾客的年龄!

现在,我将开始构建一个维度模型,并将客户数据放入一个单独的维度表中,删除重复的数据并保留 customers 维度中的唯一值:

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

作者图片

我还从原始销售表中删除了客户年龄,并在客户键列中建立了这两者之间的关系:

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

作者图片

最后,我只需要重写我的度量来引用新创建的维度表:

AVG Customer Age = AVERAGE(Customers[Customer Age])

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

作者图片

当然,有一种方法可以编写更复杂的 DAX,甚至可以用一个平面表来检索正确的结果。但是,为什么要这样做呢?我相信我们会同意,最直观的方法是像我一样编写一个度量,并用一个简单的 DAX 语句返回一个适当的数字。

所以,不仅仅是效率的问题,还有准确性的问题!因此,这里的关键要点是: 尽可能将您的数据建模为星型模式!

为 NYC 碰撞数据集构建星型模式

既然我们已经得出结论,星型模式是可行的,那么让我们开始为数据集构建最佳数据模型。第一步是去掉缺失值超过 90%的列,因为我们无法从中提取任何信息。我已经删除了 9 列,现在还剩下 20 列。

乍一看,我有 5 个潜在的维度表要创建:

  • 日期维度
  • 时间限度
  • 位置维度(区+邮政编码)
  • 促成因素维度
  • 车辆类型尺寸

但是,在我们继续创建它们之前,我想对我的崩溃时间列应用一个额外的转换。因为我们不需要在分钟级别上分析数据(要求的是小时级别的粒度),所以我将值四舍五入到起始小时:

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

作者图片

我现在将复制我的原始平面表 4 次(对于所需的每个维度,除了日期维度,因为我想使用一组更复杂的属性,例如星期几)。不要担心,因为我们将只保留每个维度中的相关列,并删除所有其他列。以下是位置维度的一个示例:

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

作者图片

下一个重要步骤是确保我们在每个维度中都有唯一的值,这样我们就可以在维度和事实表之间建立适当的 1-M 关系。我现在将选择我的所有维度列并删除重复项:

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

作者图片

我们需要对数据模型中的每个维度都这样做!从这里开始,由于我们在原始表中没有“经典的”键列(例如,在前面的例子中,当我们计算平均客户年龄时,我们在原始平面表中有 Customer 键列),有两种可能的方法:更简单的方法假设在文本列上建立关系——这“本身”没有问题,但是它可能对大型模型中的数据模型大小有影响。

因此,我们将走另一条路,为我们的每个维度创建一个代理键列。按照维度建模中的定义,代理键不具有任何业务意义——它只是一个简单的整数(或 bigint)值,该值按顺序递增并唯一地标识表中的行。

使用索引列转换在 Power Query 中创建代理键非常简单。

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

作者图片

这里只需要注意一点:默认情况下,使用索引列转换将中断查询折叠。然而,由于我们处理的是根本不支持查询折叠的 CSV 文件,我们可以安全地应用索引列转换。

下一步是将这个整数列添加到事实表中,并将其用作维度表的外键,而不是文本值。如何才能实现这一点?我将简单地将位置维度与我的碰撞事实表合并:

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

作者图片

出现提示后,我将对唯一标识维度表中一行的列执行合并操作(在本例中,是行政区和邮政编码的组合键):

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

作者图片

在 Power Query 应用这种转换之后,我将能够展开合并后的位置表,并从那里获取索引列:

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

作者图片

现在,我可以使用这一个整数列作为 Location 维度表的外键,只需删除两个属性列 BOROUGH 和 ZIP CODE——这样,我的表不仅更加整洁,而且还需要更少的内存空间——我们现在有一个整数列,而不是两个文本列!

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

作者图片

我将对其他维度(除了时间维度)应用相同的逻辑—包括索引列作为外键,并删除原始文本属性。

用日期维度和关系增强数据模型

现在,我们已经完成了 Power Query editor 中的数据建模,并准备好进入 Power BI,通过使用 DAX 创建一个日期维度来增强我们的数据模型。我们也可以在 Power Query 中使用 M 来完成,但是我有意将它留给 DAX,只是为了向您展示 Power BI 中数据建模的多种不同功能。

为了使 DAX 时间智能功能以正确的方式工作,设置正确的日期/日历维度至关重要。

为了创建一个日期维度,我使用了由 SQL BI 人员提供的这个脚本。

Date =
VAR MinYear = YEAR ( MIN ( Collisions[CRASH DATE] ) )
VAR MaxYear = YEAR ( MAX ( Collisions[CRASH DATE] ) )
RETURN
ADDCOLUMNS (
    FILTER (
        CALENDARAUTO( ),
        AND ( YEAR ( [Date] ) >= MinYear, YEAR ( [Date] ) <= MaxYear )
    ),
    "Calendar Year", "CY " & YEAR ( [Date] ),
    "Month Name", FORMAT ( [Date], "mmmm" ),
    "Month Number", MONTH ( [Date] ),
    "Weekday", FORMAT ( [Date], "dddd" ),
    "Weekday number", WEEKDAY( [Date] ),
    "Quarter", "Q" & TRUNC ( ( MONTH ( [Date] ) - 1 ) / 3 ) + 1
i

在我将这个表标记为数据表之后,就该构建我们的星型模式模型了。我将切换到模型视图并建立表之间的关系:

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

作者图片

这让你想起什么了吗?没错,看起来就像上面的星形插图。因此,我们遵循 Power BI 中关于数据建模的最佳实践,构建了一个星型模式模型。不要忘记,我们能够在不离开 Power BI 桌面环境的情况下做到这一点,只使用 Power Query Editor,并且不编写任何代码!我听到了,我听到了,但是日期维度的 DAX 代码不算:)

结论

我们的分析解决方案正在慢慢改进。在我们执行必要的数据清理和整形后,我们通过构建星型模式模型达到了更高的水平,这将使我们的 Power BI 分析解决方案能够高效地执行并提高整体可用性——既消除了不必要的复杂性,又能够为不同的计算编写更简单的 DAX 代码。

正如您所看到的,我们再次证明了 Power BI 不仅仅是一个可视化工具!

在本系列的下一部分,我们将最终移动到球场的那一边,开始构建一些很酷的视觉效果,利用我们在后台创建的数据模型的功能。

感谢阅读!

成为会员,阅读 Medium 上的每一个故事!

在 Power BI 中构建端到端分析解决方案:第 4 部分——从图表到洞察!

原文:https://towardsdatascience.com/building-an-end-to-end-analytic-solution-in-power-bi-part-4-from-chart-to-insight-56a543861477?source=collection_archive---------31-----------------------

准备好一些很酷的数据可视化了吗?在这一部分,我们将根据一些最佳的数据 viz 实践来构建我们的报告!

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

拉胡尔·潘迪特关于 pexels.com 的图片

当我与不了解 Power BI 世界的人交谈时,我经常得到的印象是,他们认为 Power BI 只是一个可视化工具。虽然这在一定程度上是对的,但在我看来,他们没有看到更大的图景,或者更好的说法是,他们看到的只是冰山一角!这个冰山一角是那些闪亮的仪表盘,KPI 箭头,花哨的人工智能东西,等等。

然而,事情远不止如此,因为真实的事情隐藏在表面之下……

在这一系列文章中,我将向您展示如何使用 Power BI 来创建成熟的解析解决方案 。从不提供任何有用信息的原始数据开始,构建不仅仅是好看的可视化,而是提取可用于定义适当行动的洞察力——我们称之为知情决策。

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

作者插图

好消息,伙计们-缓慢但稳步地,我们正在接近我们的目标-仅使用 Power BI 构建高效的端到端分析解决方案!我们强调了在创建解决方案之前理解业务问题的重要性,执行了一些简单的数据清理和转换,在前面的部分中,我们了解了为什么 Star schema 和 Power BI 是天造地设的一对,以及为什么您应该始终努力以这种方式对数据建模。

现在,是时候构建一些引人注目的可视化工具了,它们将帮助我们以最有效的方式讲述数据故事,并为业务决策者提供见解-最终,基于这些见解,他们将能够做出明智的决策-基于数据的决策,而不是基于个人的预感或直觉!

免责声明: 我认为自己不是一个有审美天赋的人,所以我的数据可视化解决方案大多基于我在书中读到的最佳实践(例如这一个)、博客,并受到一些了不起的社区成员的启发,例如 Armand Van Amersfoort、Daniel Marsh-Patrick、Kerry Kolosko、Ried Havens、Andrej Lapajne ( Zebra BI )或来自 powerbi.tips

数据可视化——我的首选

在我们卷起袖子开始可视化我们的数据之前,我想指出一些我一路收集的关于数据可视化的最佳实践。

1。一个仪表盘来统治所有人

这一条不仅仅适用于数据可视化,它更像是一条通用规则。没有单一的解决方案可以满足每一项业务需求!句号!首先,您应该确定仪表板的用途— 操作仪表板 为消费者提供时间关键型数据。我喜欢把操作仪表板想象成汽车或飞机的驾驶舱……另一方面, 分析仪表板 更侧重于从历史数据中识别趋势和模式,从而更好地做出中长期决策。

在我们的这个博客系列中,我们正在构建一个分析仪表板。

2。挑选合适的可视化类型

呃,这个可能是最难定义的了。从字面上看,有数百篇来自知名作者的博客文章、书籍和视频,解释了使用哪种可视化类型来表示特定的数据。基于您想要提供哪种洞察—例如,两个数据点之间的比较、特定值的分布、不同数据之间的关系、随时间的变化、整体的部分,等等—应该使用的某些视觉类型。

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

作者插图

我故意用了“应该”这个词,因为没人能禁止你在仪表盘上使用仪表图、饼状图、三维图,尽管很多公认的专家都反对这样做——只是要小心谨慎,注意在什么场景下使用什么视觉类型。

3。定义最重要的数据点

显然,一些数据点比其他数据点更重要。如果你的总收入比上个月低 50%,这肯定比看图表显示每种产品颜色的个别数字要重要得多。考虑到这一点,试着将所有关键数据点放在左上角,因为我们星球上的大多数人都是从左到右,从上到下阅读(想象一下阅读一本书,或报纸),这个位置自然会立刻引起他们的注意。

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

作者插图

4。保持一致!

这是需要记住的关键事情之一!一致性是什么意思?例如,坚持使用已定义的布局和设计,将相关信息放在一起,或者对类似类型的信息使用类似的视觉类型—您不希望在一个仪表板部件中使用饼图按区域显示销售额,然后使用柱形图按区域显示订单总数。

5。移开注意力

我已经写了一个关于从 Power BI 报告中排除干扰的具体案例。在你的仪表板上有很多可能的干扰物。让我们从字体开始:倾向于使用标准字体而不是艺术字体,因为它们更容易消费:

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

作者插图

上图展示了左侧卡片的可读性,它使用了一种标准字体(Calibri)。它还展示了另一个需要考虑的问题——缩短数字也是一种从你的仪表盘上消除干扰的好方法。

此外,注意适当的对齐,给你的视觉效果留出一些空间:

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

视觉效果之间适当的对齐和空间将提高清晰度 —作者插图

我想我们都同意上图中的仪表板比下图更易读:

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

作者插图

谈到数据可视化,还有更多最佳实践、技巧和建议。正如我已经强调的,我不认为自己是一个“数据 viz”向导,但是我仍然试图坚持本文前面部分提到的一些通用规则。

最后,尽管对于许多仪表板创建者来说,第一步是设置总体仪表板设计,然后将数据元素放入预定义的模板中,但我更喜欢反其道而行之:首先,我创建所有数据元素,然后基于我想用这些元素“讲述”的故事,我正在构建最终的解决方案…

可视化车辆碰撞数据

好了,现在我们已经确定了一些通用的数据可视化最佳实践,是时候动手使用 Power BI 来讲述纽约市的车辆碰撞事件了。

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

作者图片

这是我的报告的样子。在这一部分,我们不会深入每个视觉细节,但让我简单介绍一下整体概念。有两个页面——主页包含最重要的数据点,如碰撞、死亡和受伤的数量。还有一些“经典”的视觉效果,如折线图和柱形图,这将帮助我们从不同的角度提取对数据的见解。多行卡视觉快速说明谁是交通中最危险的。

一天中的时间是我们的关键分析类别之一,因此报告用户可以充分灵活地在同一视觉效果(碰撞、死亡、受伤)的不同指标之间切换,密切关注动态标题,这增强了整体用户体验!

请记住,我们在这里定义了一组问题,我们将尝试使用此报告来回答这些问题。可以使用日期切片器从日历的角度对数据进行切片。

详细信息页面提供了深入了解事故细节的可能性——介绍了针对行政区和邮政编码的附加切片器。小倍数视觉很好地将数字分为两类——人的类型和区,而其他元素扩展了主页的逻辑。

结论

在本系列的这一部分中,我们已经介绍了很多内容。这并不是说我们只是构建了自己的报告来可视化来自原始数据集的数据,我还与您分享了一些关于数据可视化的一般最佳实践,以及来自该主题的成熟专家的建议。

我再重复一遍:我认为自己远没有成为一名“设计师”的天赋,我相信你们中的许多人可以创造出一份更好看的 Power BI 报告。然而,最终目标是将关键数据点有效地传达给报告消费者,并使他们能够根据这种传达所提供的见解做出决策。

考虑到这一点,我相信我们已经为在本系列的最后部分总结所有内容打下了坚实的基础——我们将尝试从我们刚刚创建的报告中提取一些有意义的信息,并根据这些发现建议某些行动。

感谢阅读!

成为会员,阅读媒体上的每一个故事!

在 Power BI 中构建端到端分析解决方案:第 5 部分——请行动起来!

原文:https://towardsdatascience.com/building-an-end-to-end-analytic-solution-in-power-bi-part-5-action-please-a60dd23802a3?source=collection_archive---------31-----------------------

在最后一部分,我们将把我们的分析技能提升到另一个层次!不仅如此——基于所获得的见解,我们将推荐某些行动!

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

作者图片

当我和那些没有深入了解 Power BI 世界的人交谈时,我经常得到的印象是,他们认为 Power BI 只是一个可视化工具。虽然这在一定程度上是对的,但在我看来,他们没有看到更大的图景,或者更好的说法是,他们看到的只是冰山一角!这个冰山一角是那些闪亮的仪表盘,KPI 箭头,花哨的人工智能东西,等等。

然而,事情远不止如此,因为真实的东西隐藏在表面之下……

在这一系列文章中,我将向您展示如何使用 Power BI 来创建成熟的解析解决方案 。从不提供任何有用信息的原始数据开始,构建不仅仅是好看的可视化,而是提取可用于定义适当行动的洞察力——我们称之为知情决策。

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

作者插图

在这里,我们以 CSV 文件的形式获取原始数据,定义一组需要使用该数据回答的业务问题,然后清理和塑造原始数据集并构建高效的数据模型(星型架构),在前面的部分中,我们创建了引人注目的可视化,为业务决策者提供不同的见解。现在,是时候分析见解,并根据我们从这些见解中提取的信息,推荐一些行动了!

提取洞察力

先来分析一下碰撞造成的死亡。如果我们排除在车内的人,我们可以看到行人是最危险的交通参与者——与骑自行车的人相比,几乎多 8 倍的行人被杀!

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

作者图片

我们可以得出的下一个结论是,碰撞的主要原因是司机不注意/分心!如果我们看一下前 5 大冲突原因,您会发现所有其他原因加起来都低于前一个原因。

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

作者图片

继续,我们可以发现的下一个模式是下午早些时候,特别是下午 4 点和 5 点的碰撞高峰。这是有道理的,因为很多人在那段时间从办公室开车回家:

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

作者图片

这大约比早上(上午 8-9 点)高 30%,而在早上,交通参与者在辛苦工作一天后可能不会感到疲劳和分心。

让我们继续详细概述事故,并努力找出城市中的“黑点”。乍一看,大多数人是在布鲁克林被杀的,或多或少,所有其他区都遵循不同交通参与者之间的“死亡分布”模式,除了曼哈顿,那里骑自行车的人比开车的人被杀的多。

如果我们分析受伤的百分比,趋势与死亡率有很大不同:现在,司机是最危险的(同样,不包括车上的人)——司机受伤的人数几乎是行人的 4 倍!

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

作者图片

再往下,冲突最频繁的邮政编码是 11207 和 11101(一个在布鲁克林,另一个在皇后区)。如果我们关注具体的街道,我们可以看到百老汇(曼哈顿)和大西洋大道(布鲁克林,邮编 11207)是纽约市最关键的景点!

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

作者图片

请开拍!

好了,现在我们有了更多的信息来支持我们的业务决策。而且,因为我们已经定义了需要回答的一系列问题,所以让我们专注于提供适当的行动建议!

这个想法是以工具提示的形式显示建议——当有人将鼠标悬停在特定的视觉对象上时,相应的操作应该会显示出来!我已经写了如何使用工具提示页面增强你的报告,这里我们将遵循类似的方法:

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

作者图片

因此,当我将鼠标悬停在显示 5 大碰撞原因的画面上时,将会推荐一些行动:

  • 对违法者的更高处罚
  • 针对驾驶员的附加培训

同样,如果您想根据大多数碰撞发生的时间采取行动,只需将鼠标悬停在该画面上,您就会看到在这些高峰时段增加交通官员数量的建议:

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

作者图片

此外,为了能够减少特定位置的碰撞和伤亡数量,我们强调了增设交通灯和在“交通黑点”指派更多交通官员的重要性:

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

作者图片

结论

伙计们,收工了!提醒你一下,这是我们开始的地方:

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

作者图片

这是我们结束的地方:

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

作者图片

在这一过程中,我们清理和转换了我们的数据,使用星型模式构建了合适的数据模型,并可视化了关键数据点。你猜怎么着— 我们使用一个工具完成了所有这些:Power BI! 这就是我将这一系列博客文章命名为:用 Power BI 构建端到端分析解决方案的原因——我相信我们会同意这些文章毫不夸张地证明了这一点。

所以,下次当你听到“Power BI 只是一个可视化工具”时,请记住我们专门使用这个工具能够实现什么,并自己得出结论!

感谢阅读整个系列!

成为会员,阅读 Medium 上的每一个故事!

构建端到端的开源现代数据平台

原文:https://towardsdatascience.com/building-an-end-to-end-open-source-modern-data-platform-c906be2f31bd?source=collection_archive---------4-----------------------

帮助您浏览现代数据堆栈并使用开源技术构建自己的平台的详细指南。

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

克里斯多夫·伯恩斯在 Unsplash 上拍摄的照片

在过去几年中,数据工程领域的重要性迅速上升,为加速创新和进步打开了大门——因为今天比以往任何时候都有更多的人在思考数据资源以及如何更好地利用它们。这种进步反过来导致了第三次数据技术的浪潮***。***

第一波由 ETL、OLAP 和关系数据仓库组成,它们是商业智能(BI)生态系统的基石,无法应对大数据的四个 v的指数级增长。由于双向堆栈的潜力有限,我们随后见证了第二波:这是一个存储和计算可扩展性的时代,这要归功于 Hadoop 生态系统(允许公司横向扩展其数据平台)和 Apache Spark(为大规模高效内存数据处理打开了大门)。********

我们称之为“ 第三次浪潮 ”的时代是我们不再担心可扩展性或分布式存储的时代。相反,我们正在成熟的分布式数据平台上构建砖块和新功能。我们现在有可能考虑元数据管理、大规模数据发现和数据可靠性等主题。我们正处于可互换的 SaaS 模块、基于云的平台、ELT 和民主化数据访问的时代。欢迎来到 现代数据栈 浪潮。

在本文中,我们将从头开始构建一个端到端的现代数据平台,仅仅依靠开源技术和云提供商提供的资源。本文还附有一个 GitHub repo,其中包含构建平台所需的必要代码和基础设施代码(IaC)脚本。

**https://github.com/mahdiqb/modern_data_platform

该平台将由以下组件组成:

  • 数据仓库:这是我们设计中最重要的部分,因为不管其他部分有多复杂,低效的数据仓库都会给我们带来问题。从根本上说,数据仓库背后 40 年的概念和范例至今仍然适用,但与来自*、【第二波】、*的水平可伸缩性相结合,实现了高效的 ELT 架构。
  • 数据集成:不出所料,我们实际上需要将数据放入我们的平台。由于现代数据堆栈,以前配置和实现连接器的繁琐任务现在已经解决了。
  • 数据转换:一旦我们将数据放入我们的仓库(因此我们完成了 ELT 架构的 EL 部分),我们将需要在它上面构建管道来 转换 它,以便我们可以直接消费它,并从中提取价值和见解——这个过程是我们 ELT 中的 T,直到最近,它通常由管理不善的大型 SQL 查询或复杂的 Spark 脚本组成。 但是,在这个“第三次浪潮”中,我们现在拥有了更好地管理数据转换的必要工具。
  • 编排(可选——目前):我们仍然需要编排管道的执行,以确保数据尽快可用,并且数据生命周期从一个组件平稳地运行到下一个组件。这被标记为可选的,因为我们将使用的一些工具提供了开箱即用的调度功能,因此在平台生命周期的第一阶段,您不应该真正需要专用的编排组件(这会增加不必要的复杂性)。尽管如此,我们仍将在本文中讨论编排选项,因为您最终需要在您的平台上添加一个。
  • 数据监控(可选—目前):更多的数据意味着更多潜在的质量问题。为了能够信任我们的数据,我们需要监控它,并确保我们基于它生成准确的见解。这被标记为可选的,因为在开始时,最有效的选择是利用其他组件的数据测试功能,但是我们将在本文中讨论数据监控工具。
  • 数据可视化:这是我们实际探索数据并以不同数据产品的形式从中产生价值的地方,比如仪表板和报告。这个时代的主要优势之一是,我们现在拥有成熟的开源数据可视化平台,可以以简化的方式进行部署。
  • 元数据管理:我们平台的大部分功能(如数据发现和数据治理)都依赖于元数据,因此我们需要确保元数据在整个平台中得到集中和利用。

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

平台的架构(图片由作者提供)

最后,请记住,尽管我们将讨论的技术和工具是开源的,但我们将在云环境中构建平台,因此我们将使用的资源(用于计算、存储等)。)本身并不免费,但我们不会超过GCP 免费试用版提供的 300 美元预算。

如果您想避免建立云环境,您仍然可以在本地试验不同的工具,您只需要用一个开源的替代方案(像 PostgreSQL 这样的 RDBMS)替换数据仓库(在我们的例子中是 BigQuery)。

现在,事不宜迟,让我们建立我们的现代数据平台。**

首先,我们来谈谈数据

要构建一个样本数据平台,流程的第一步是挑选一个或多个数据集进行处理。这是一个探索在线可用的多个开放数据集之一的机会,我建议搜索一个你个人感兴趣的数据集-这将使这个过程更加愉快,因为你会对这些数据真正感兴趣。如果您想要一些灵感,请从以下数据集之一开始:

  • 一级方程式世界锦标赛(1950–2021):你可以从 Kaggle 下载或直接从er gast HTTP API检索的这个数据集包含了从 1950 年到 2021 年的一级方程式比赛、车手、制造商、排位赛、赛道、圈速、进站和锦标赛的所有可用数据点。如果你像我一样是 F1 粉丝,这个数据集可以给你许多关于这项运动的有趣见解。
  • 世界发展指标(1960–2020):这个由世界银行提供的数据集无疑是你能在网上找到的最丰富的开放数据集之一。它包含大约 1500 个发展指标,你可能会迷失其中。

数据仓库:BigQuery

如上所述,为您的用例选择正确的数据仓库是我们难题中最重要的一块。主要的三个选项是雪花大查询红移——是的,它们都不是开源的,但它们都提供了一个 无服务器 选项。这意味着我们可以利用复杂的现代数据仓库的功能,同时只需为我们在存储和计算方面消耗的资源付费。

好消息是,无服务器选项正是我们在这个阶段寻找的,即使该产品不是开源的。这是因为我们希望能够在存储和查询性能方面进行扩展,而不需要专门的维护工作。因此,入门时的理想选择是无服务器托管产品——这适用于我们所有需要弹性的组件,而不仅仅是数据仓库。

出于各种原因,BigQuery 非常适合这一需求,其中我们可以提到以下两点:

  • 首先,它本质上是无服务器的。其背后的设计由于存储和计算的分离,允许提高效率,使其成为所有类型使用情形的非常可靠的选择。另一方面,Redshift 的无服务器产品仍处于测试阶段。
  • 其次,它是云提供商产品的一部分,因此已经与 GCP 生态系统的所有组件实现了无缝集成。这进一步简化了我们的架构,因为它最小化了配置工作。

因此,对于我们来说,利用 BigQuery 作为这个平台的数据仓库是有意义的,但这并不能概括这个选择,因为在其他场景中,选择另一个选项可能更有意思。在选择数据仓库时,您应该考虑定价、可伸缩性和性能等因素,然后选择最适合您的用例的选项。

为了开始,我们只需要创建一个数据集,但是请随意熟悉 BigQuery 的一些更高级的概念,比如分区物化视图

在 ELT 架构中,数据仓库用于存储我们所有的数据层。这意味着我们不仅仅使用它来存储数据或查询分析用例,我们还将利用它作为不同转换的执行引擎。

现在我们已经选择了我们的数据仓库,架构看起来如下:

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

架构的当前状态(图片由作者提供)

在我们进入下一个组件之前,让我们将 BigQuery 审计日志存储在一个专用的数据集 ( 附加指令),因为当我们设置元数据管理组件时,这些信息将会派上用场。

获取数据:Airbyte

当考虑现代数据堆栈中的数据集成产品时,您会发现少数公司(使用闭源产品)竞相在最短的时间内添加最多的连接器。遗憾的是,这意味着更慢的创新(因为对每个产品做出贡献的人更少)和定制现有解决方案的可能性更小。

异常的亮点肯定是 Airbyte,这是这个领域中唯一一家从一开始就选择开源其核心产品的大公司。这使得它在成立不到一年的时间里迅速发展成一个大型贡献者社区,并提供了 120 多个连接器。

部署 Airbyte 对所有云提供商来说都是轻而易举的事情。在 GCP 上,我们将使用具有足够资源的计算引擎实例。理想情况下,您会希望通过 IaC 配置您的部署,这将使管理版本和自动化过程更加容易。(随附的报告中提供了 Terraform 配置示例。)

一旦启动并运行,我们只需通过定义以下内容来添加连接:

  • :您可以使用 UI 选择“文件”源类型,然后根据您的数据集和您上传数据的位置对其进行配置,或者如果您更喜欢冒险,您可以利用 Airbyte 的 Python CDK 构建一个新的 HTTP API 源,从您想要使用的 API 中获取数据。
  • A destination :这里您只需要指定与数据仓库交互所需的设置(在我们的例子中为 BigQuery )。

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

样本 Airbyte 连接(图片由作者提供)

值得注意的是,Airbyte——就目前而言——仅仅是为批量数据摄取而设计的(ELT 中的 EL ),所以很遗憾,如果您正在构建一个事件驱动的平台,它不在您的选择之列。如果你有这样的用例,那么你的最佳选择将是柔术细分的开源替代方案。

现在,我们已经启动并运行了 Airbyte,数据接收也已完成,我们的平台如下所示:

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

架构的当前状态(图片由作者提供)

管理我们英语教学中的 T: dbt

当我们想到现代数据堆栈时,dbt 可能是第一个想到的工具。这个始于 2016 年的项目(从一开始就是开源的)解决了当时一个普遍存在的问题:数据管道的版本很差,文档记录很差,并且没有遵循软件工程的最佳实践。

dbt 是第三次数据技术浪潮的理想代表,因为它代表了这一浪潮背后的主要目标:添加特性和功能,以更轻松地管理现有的数据平台,并从底层数据中获取更多价值。得益于 dbt,数据管道(我们 ELT 中的 T)可以划分为一组SELECT查询(称为“ 模型 ”),这些查询可以由数据分析师或分析工程师直接编写。这种能力为多种特性打开了大门,比如数据沿袭、版本控制、数据测试和文档。

设置 dbt 环境有两种不同的方式:

  • dbt Cloud :这是 dbt 实验室托管的基于 web 的集成开发环境(IDE)。这是一个需要最少工作的选项,但提供了更多功能,如计划作业、CI/CD 和警报。锦上添花的是,通过开发者计划,它实际上是免费的。
  • dbt CLI :该选项允许您直接与 dbt Core 交互,无论是通过使用pip在本地安装它,还是像我们之前部署的 Airbyte 一样在 Google Compute Engine 上运行 docker 映像。通过使用 CLI,您可以体验不同的 dbt 命令,并在您选择的 IDE 中工作。

为了允许 dbt 与您的 BigQuery 数据仓库进行交互,您需要生成所需的凭证(您可以创建一个具有必要角色的服务帐户),然后在您的profiles.yml文件中指明特定于项目的信息。这在 dbt Labs 的“入门”教程中有很好的解释,它介绍了你需要熟悉的所有概念。

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

运行 dbt 调试后的预期输出(图片由作者提供)

在最初的努力之后,现在是您享受数据的时候了:您可以使用 dbt 来定义模型以及它们之间的依赖关系。例如,对于 F1 数据集,您可以生成一个包含冠军得主数据的championship_winners模型(总积分、每场比赛的平均进站时间、整个赛季的最快圈数、平均排位等。)对于您正在处理的任何数据集,当涉及到数据可以回答的问题时,您会发现可能性的数量令人难以置信——这是一个很好的练习,会让您在处理新数据集时更有信心。

在处理完您的模型之后,您可以执行命令dbt docs generate来生成我们项目的文档(目录和清单文件)。

在这个阶段,在设置好 dbt 之后,我们现在有了可以处理 ELT 流程的三个步骤的组件,架构如下所示:

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

架构的当前状态(图片由作者提供)

当我们第一次介绍该架构时,我们说过编排和数据监控/测试现在都可以由另一个组件来处理——您可能已经猜到该组件是 dbt。借助 dbt Cloud,我们可以管理我们的管道的调度,并定义不同的执行触发器(例如通过 web hooks 定义),同时 dbt 还有一个强大的基于 SQL 的测试功能,我们可以利用它来确保数据质量问题不会被检测到。

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

运行 dbt 测试后的示例输出(图片由作者提供)

神奇的地方:Apache 超集

既然我们已经处理了我们的数据,并生成了不同的视图和表格来提供见解,那么是时候通过一组 数据产品 来实际可视化这些见解了。(如果你对这个术语不熟悉,Simon O ’ Regan的这篇文章详尽地概述了不同类型的数据产品。)

我们在这一阶段的目标是构建最终用户可以直接访问的仪表盘和图表(无论是用于分析还是监控,取决于您的数据集),就像过去的商业智能(BI)一样。

BI 是少数几个没有被数据技术的“第二波”破坏的领域之一,这主要是因为 Hadoop 生态系统专注于大规模处理数据,而不影响最终用户消费数据的方式。这意味着在很长一段时间内,BI 和数据可视化领域由专有工具(Tableau、PowerBI 和最近的 Looker)主导,只有少数缺乏开源项目的利基用例。

然后出现了 Apache Superset。当它在 2016 年首次由 Airbnb 开源时,它代表了第一个真正替代现有 BI 工具的开源工具,提供了企业级所需的所有功能。今天,由于其庞大的开源社区,它是第三次浪潮的领先技术之一。

生产超集部署由多个组件组成(如专用元数据数据库、缓存层、身份验证和潜在的异步查询支持),因此为了简单起见,我们将依赖一个非常基本的设置。

我们将再次利用 Google Compute Engine 来构建一个超集实例,我们将通过 Docker Compose 在其上运行一个容器。本文附带的报告中提供了必要的 Terraform 和 init 脚本。

一旦超集启动并运行,就可以通过以下命令连接到实例:

**gcloud --project=your-project-id beta compute ssh superset-instance -- -L 8088:localhost:8088 -N**

在登录到超集实例(通过官方文档中提供的步骤之后,您只需要将它连接到 BigQuery ,这样它就可以开始与您的不同数据集进行交互。

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

添加 BigQuery 连接后的预期结果(图片由作者提供)

建立连接后,您可以试验不同的图表类型,构建仪表板,甚至利用内置的 SQL 编辑器向 BigQuery 实例提交查询。

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

通过 SQL 编辑器查询 BigQuery 数据(作者图片)

现在,我们可以让最终用户通过超集直接访问数据,我们的数据平台如下所示:

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

架构的当前状态(图片由作者提供)

当谈到超集的功能时,您会很高兴地知道我们只是触及了表面。你可以管理访问角色,利用缓存构建自己的定制 viz 插件,使用丰富的 API,甚至执行行级访问策略。此外,通过预设,您可以选择一个托管版本,让您不必考虑部署。

堆栈的基石:OpenMetadata

元数据管理可能是数据社区中对如何处理分歧最大的领域。这是一个非常分散的空间( 25 种工具和计数),不同的工具在如何解决这个问题上采取了截然不同的方法。

在我个人看来,我坚信优步数据平台团队开源的产品 OpenMetadata 在这个领域采取了正确的方法。通过专注于提供水平元数据产品,而不仅仅是架构中的一块砖,它使拥有集中式元数据存储成为一个可实现的目标。它有非常丰富的 API,执行元数据模式,并且已经有一长串连接器

其他产品正在实现他们自己的管理元数据的方式,并且是在闭门造车的情况下进行的,这将导致在将它们添加到我们的平台时产生不必要的开销,而 OpenMetadata 专注于提供元数据的单一来源,其他产品可以通过其 API 与之交互。通过将它添加到体系结构中,数据发现和治理就成为了一种必然,因为它已经具备了实现这些目标的所有必要特性。如果你想在将它添加到我们的平台之前见证它的能力,你可以首先探索它的沙箱

像 Airbyte 和 Superset 一样,我们将通过 Google Compute Engine 实例部署 OpenMetadata(像往常一样,Terraform 和 init 脚本在附带的 repo 中提供)。部署完成后,您会注意到实际上有四个容器在虚拟机上运行,用于以下目的:

  • 在 MySQL 上存储元数据目录
  • 通过 Elasticsearch 维护元数据索引
  • 通过气流编排元数据摄取
  • 运行 OpenMetadata UI 和 API 服务器

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

启动 OpenMetadata 后的预期输出(图片由作者提供)

OpenMetadata 在后台尽职尽责地管理这些组件,无需您进行任何必要的配置,因此我们可以立即开始像利用任何其他产品一样利用它。启动并运行后,您可以首先通过以下命令连接到 Airflow 端口:

**gcloud --project=your-project beta compute ssh openmetadata-instance -- -L 8080:localhost:8080 -N**

然后在http://localhost:8080/(用户名:admin,密码:admin)进入气流 UI。您会注意到一些 Dag 已经运行来加载和索引一些样本数据。之后,让我们通过以下命令连接到 OpenMetadata UI(然后可以在[http://localhost:8585/](http://localhost:8080/)访问该 UI):

**gcloud --project=your-project beta compute ssh openmetadata-instance -- -L 8585:localhost:8585 -N**

现在,您只需通过 SSH 登录 GCE 实例,并将 OpenMetadata 连接到 BigQueryBigQuery 使用数据dbt超集。之后,您可以探索其不同的特性和功能,如数据发现和沿袭。

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

连接到 BigQuery 后打开元数据 UI(图片由作者提供)

既然我们已经将 OpenMetadata 添加到平台中,让我们来看看我们最终确定的架构:

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

最终确定的平台架构(图片由作者提供)

更上一层楼:可选组件

在本文的开始,我们提到了两个可选组件:编排和数据监控。在理论层面上,这是我们的数据平台的两个非常重要的功能,但是正如我们所看到的,dbt 在这个阶段可以很好地实现这两个功能。尽管如此,让我们讨论一下这两个组件在需要时如何集成。

编排我们的管道:阿帕奇气流

当平台进一步成熟,我们开始集成新的工具和编排复杂的工作流时,dbt 调度最终会变得不足以满足我们的用例。一个简单的场景是当特定的 dbt 模型更新时超集缓存失效——这是我们无法单独通过 dbt Cloud 的调度实现的。

自 2015 年由 Airbnb 开源以来,Airflow 一直是数据工作流编排领域的首选工具。这使得它成为多家科技公司大型数据平台不可或缺的一部分,确保了围绕它的一个庞大而非常活跃的开源社区——这反过来又帮助它在编排方面保持标准,即使在“第三次浪潮”中也是如此。

您应该推迟考虑气流(或其替代品)的原因是专用编排工具带来的额外复杂性。Airflow 以自己的方式看待世界,为了能够充分利用它,您需要做出妥协并调整您的工作流程以匹配其特性。

在集成编排工具时,您还应该考虑如何触发您的管道/工作流。Airflow 确实支持基于事件的触发(通过传感器,但是问题可能会很快出现,让你仅仅因为工具而适应你的需求——而不是让工具帮助你满足你的需求。

帮助我们晚上睡得更好:Soda SQL

就像编排一样,数据监控(最终将允许我们考虑数据的可观察性)是一种需求,dbt 最终将不再为我们的平台充分处理这种需求。

我们不只是验证 dbt 模型的数据,而是希望跟踪整个平台的数据问题,以便我们可以立即确定特定问题的来源并相应地修复它。

像数据集成一样,数据可观察性是公司仍然采用闭源方法的领域,这将不可避免地减缓创新和进步。另一方面,有两个开源产品可以满足我们的大部分需求: Soda SQLGreat Expectations

Soda SQL 是一个很好的起点,因为它不需要太多的投资,并且提供了多种方便的特性。你只需要几个 YAML 文件就可以启动并运行,然后你就可以定义定制测试协调扫描

接下来是什么?

这是一段漫长的旅程。我们经历了不同的技术——其中一些是我们正在见证的“第三次浪潮的产品,其他的是经过时间考验的“第二次浪潮的老手。在这一点上,主要的收获是,构建一个功能齐全的数据平台比以往任何时候都更容易—如果您遵循实施过程,您会发现自己在不到一个小时的时间内就构建了一个随时可用的现代数据平台。

当然,现代数据堆栈仍然是支离破碎的,在我们讨论的一些技术上下注可能是一个冒险的决定。除了 dbt 之外,没有任何现代数据堆栈工具在它所做的事情上是明显的赢家,因此生态系统将在未来几年通过整合和竞争不断变化。不过,可以肯定的是,激动人心的时刻就在我们面前。

要了解更多数据工程内容,您可以订阅我的双周刊时事通讯 Data Espresso,我将在其中讨论与数据工程和技术相关的各种主题:

**https://dataespresso.substack.com/ **

用 Keras 建立图像字幕模型

原文:https://towardsdatascience.com/building-an-image-captioning-model-with-keras-ebccaadb98b9?source=collection_archive---------54-----------------------

如何用 Python 构建 CNN-LSTM 架构

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

照片由海伦娜·赫兹Unsplash 上拍摄

我一直在做一个探索性的项目,以建立一个概念描述模型,为艺术品生成解释。首先,我开始使用 CNN-LSTM 架构,它可以作为一个简单的字幕生成器。在这篇文章中,我将描述如何构建一个基本的 CNN-LSTM 架构来创建一个可以基于图像输出文本标题的模型。请稍后继续关注我的项目。

CNN LSTM 频道

这种图像字幕的主要方法分为三个部分:1 .使用预先训练的对象识别网络从图像中获取特征;为了将这些提取的特征嵌入映射到文本序列,最后 3 .在给定特征图和文本序列的情况下,使用长-短时记忆(LSTM)来预测序列后面的单词。

数据

这是一个监督网络,我们将图像映射到一组特定的标题。所以我们需要一组有图片和说明的数据。这里有一些公开的数据集可供探索。

  • Flickr30K 数据集: Bryan Plummer 及其同事对来自 Flickr 的 3 万张图片以及多个对应描述的工作。
  • 概念说明 数据集: Google AI 从网络上收集概念说明的努力。它包含 300 多万张图片的标题和 URL 链接。

我不会在这里详细介绍如何下载或调整图片大小。我已经调整了所有图片的大小,使其适合 500x500 像素,并且是 jpg 格式。每个文件名都应该是将文件链接到图像描述的标识 ID。

特征抽出

第一步是使用预先训练的网络提取特征。该代码获取包含 jpg 文件的本地目录,并输出引用字典,该字典以图像 ID 作为键,以特征嵌入作为值。

这个过程可能需要一段时间,所以我添加了一段代码,让您可以在每 1000 次迭代时将进度转储到本地驱动器上。

描述预处理

附带的字幕需要预处理。该函数假设描述集采用具有嵌套元组(id, description)的列表格式。一些图像可能有多个相关联的描述,每一对都应该表示为一个单独的元组。在这一步中,我们还在每个句子中添加特殊的单词来标记序列的开始和结束(塞奇尼塞格芬)。

[(id1, 'description1-1'), (id1, 'description1-2'), (id2, 'description2-1') ... ]

此外,我添加了一个随机选择描述数量的功能,这样我就可以设置最大的标题数量,以防每张图片有太多的标题。

此函数将描述元组列表转换为预处理描述的字典,格式如下:

{ 'id1': ['description1-1', 'description1-2', ...], 'id2': ... } 
# or
{ 'id1': 'description1', 'id2': 'description2 }

交叉验证

现在我们有了数据集,让我们把它们分成训练集、验证集、测试集(这里我把它分成 7:1.5:1.5)。

**from** sklearn.model_selection **import** train_test_split
train_list, test_list = **train_test_split**(list(descriptions.keys()), test_size = 0.3)
val_list, test_list = **train_test_split**(test_list, test_size = 0.5)

序列发生器

概括地说,现在我们有三个 id 列表,分别用于训练集、测试集和验证集。我们还有描述词典和特征词典。现在我们需要将描述转换成一个序列。比如说一个 id 为 1234 的图片,有一个描述说“狗在跑”。这需要分解成如下的输入和输出集:

  • 1234 : [ 塞奇尼→[ ]
  • 1234 : [ 塞奇尼 ][ ] → [ ]
  • 1234 : [ 塞奇尼 ][ ][ ] → [ 跑步
  • 1234 : [ 塞奇尼 ][ ][ ][ 奔跑 ] → [ 塞奇尼】

但是我们不仅需要将句子标记成文本序列,还需要将它们映射成整数标签。例如,假设我们的整个语料库都有这些独特的单词:[ seqini,fast,dog,is,running,seqfin ]。我们可以把这些映射成一个整数映射:[0,1,2,3,4,5]。这将产生以下集合:

  • 1234 : [0] → [2]
  • 1234 : [0,2] → [3]
  • 1234 : [0,2,3] → [4]
  • 1234 : [0,2,3,4] → [5]

因此,逻辑是将整个训练描述集中的唯一单词分配给唯一索引,以创建文本到序列映射。然后我们遍历每个描述,对它们进行符号化,创建序列开发的子集(输入→输出),然后将它们转换成整数序列。因为我们使用在训练集期间创建的几个变量来处理测试集,所以我将它们全部放入一个序列生成器对象类中。

这将为每个训练集和验证集返回两组输入和一组输出。

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

休息一下…马特·霍夫曼在 Unsplash 上拍摄的照片

模特培训

现在让我们使用 Keras 训练模型。正如该方法中所提到的,其思想是通过 LSTM 层训练单词序列,以便它可以导出遵循该序列的最佳可能单词(实际上是分配给单词的数字)。

预言;预测;预告

预测测试图像的步骤与上述步骤相反。您计算测试图像的特征嵌入,并将其与初始序列一起输入到模型中,初始序列是起始单词’ seqini’ 的整数表示。然后,您获取预测,将其添加到序列中,并再次将其输入到模型中,并重复进行,直到模型预测出结尾单词’ seqfin’ 的整数序列。然后使用标记器,我们将整数转换回映射的词汇表。下面的函数将在给定图像 id 的情况下进行预测。

估价

评估机器生成的字幕并不像我们想象的那样简单。相反,我们可以看看预测的 n-grams 与参考标题的匹配程度。这个衡量标准被称为 BLEU(双语评估替角)分数。这个想法是取在机器生成的标题中找到的参考描述中 1-4 克的百分比的平均值,然后对可能夸大百分比的文本应用惩罚。

**from** nltk.translate.bleu_score **import** corpus_bleubleu_1 = **corpus_bleu**(references, # list (or next list)
                     predictions, # list 
                     weights = (1, 0, 0, 0)) # 1-4 grams weights 

我们研究了如何使用 CNN-LSTM 架构创建图像字幕模型。对于人类来说,描述视觉场景涉及不同层次的语言表达和感知,这取决于一个人过去的经验和当前的背景。此外,在人类认知中开发句子序列可能实际上不是“连续的”,因为句法并不直接匹配视觉显著性。因此,有一些重要的区别可以考虑,以推动这个模型进一步取得更成功和更像人类的表现。

快乐学习!

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

照片由杰米街Unsplash 拍摄

使用 Python 和机器学习构建图像分类器,从相册中过滤掉未使用的图像

原文:https://towardsdatascience.com/building-an-image-classifier-to-filter-out-unused-images-from-your-photo-album-with-python-and-6bc574ae57de?source=collection_archive---------22-----------------------

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

照片由 Soragrit WongsaUnsplash 上拍摄

使用 Keras 将我的相册图像分类为“保留”或“不保留”

浏览文件夹中的一堆图片,试图找出哪些应该保留,可能会很麻烦。为了解决这个问题,我决定通过构建一个图像分类器来自动化这个过程,该分类器根据我是否想要保留照片来对照片进行分类。

在本文中,我们将使用 Keras 实现一个简单的二进制分类器,将照片分类为“保留”或“不保留”,以自动过滤掉您的个人相册。

如果你愿意,你可以在这里查看我的 Youtube 视频:

台阶

做到这一点的步骤将是:

  • 设置和安装
  • 创建数据集
  • 创建训练/测试文件夹
  • 训练模型
  • 运行 app

如果你想跳过这篇文章直接看代码,可以在这里找到。现在,让我们来看一下这些步骤。

设置和安装

首先,我们将使用 conda 创建一个环境,并安装必要的包(kerasmatplotlibstreamlit):

conda create -n photo_album_sorter_mlpip install -r requirements.txt

创建数据集

我们将采取的第一步是按照创建时间对图像进行分类,并将它们移动到一个名为files_with_dates,的文件夹中,以保持图像相对有序:

在这个脚本中,我们简单地遍历用户提供的文件夹,将图像移动到files_with_dates文件夹,同时在文件名中添加创建时间。

要运行此命令,请在终端中键入:

python sort_creation_time.py — path ./path/to/your/images/folder

现在,我们可以为数据集创建文件夹,我们将标记图像来训练分类器。

这里,我们只是为数据集创建数据文件夹,并使用 matplotlib 建立一个简单的循环,将图像分类为“保留”或“不保留”。要运行此程序,请执行以下操作:

python create_dataset.py

现在,我们将文件拆分到 train 和 test 文件夹中。

在这里,我们只是将图像分割为 80%用于训练,20%用于测试。要运行 do:

python create_train_test.py

训练模型

我们将训练两种类型的分类器,从一个经典 CNN 的简单 Keras 实现开始,它是从 Fran ois Chollet 的博客文章中借来的。

要运行:

python train.py — epochs 10 — batch_size 16

注意你的图片的大小,在这个实现中,我们根据博客文章中关于猫和狗的例子将所有图片的大小调整为 150x150。

尽管这个模型的性能不是很好(在我的示例数据集上大约是 58%),我还是把它作为问题的基线。

我们还使用取自 Keras 文档的模板代码来训练预训练的 inception v3 模型。

在这里,我们只是按照一个基本的设置来微调一个 inception v3 模型,并添加一个小的 CLI 工具来使它易于运行:

python train_pretrained.py — epochs 10 — batch_size 16

这个模型产生了一些非常令人印象深刻的结果,没有过度拟合,在测试集上达到了 93%的性能!

这是一个好消息,但由于每个人都将使用自己的数据集,因此应该会有不同的表现,这取决于一系列因素,如图像的性质或您想从相册中排除的照片类型。

运行 app

现在,在训练之后,为了查看分类器的运行情况,我们将编写一个简单的 streamlit 应用程序来包装我们的模型:

要运行,请键入:

streamlit run app.py

您可以使用 streamlit 的文件上传程序加载图像,分类将写在图像下方。

关于使用 ML 过滤个人照片的最终想法

鉴于机器学习模型的插值性质,我们总是冒着模型将图像错误分类的风险,这可能最终导致我们丢失我们关心的重要照片,所以我的想法是将这作为一种清除杂乱图像的第一种方法,但在完全删除图像之前,总是先进行粗略的查看。

本文的源代码

如果你喜欢这篇文章,加入媒体关注订阅我的简讯。还有,订阅我的 youtube 频道Tiktok推特LinkedInInstagram 上和我联系!谢谢,下次再见!😃

如果你对机器学习设备感兴趣,这里有一个来自 MSI 的 3070 GPU 的附属链接:

https://www.amazon.com/gp/product/B097MYTZMW/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B097MYTZMW&linkCode=as2&tag=lucassoare079-20&linkId=1fd3f206c6077e5372d08c4518764124

这是一个附属链接,如果你购买的产品,我得到一小笔佣金,干杯!😃

参考

使用 Python 构建图像颜色分析器

原文:https://towardsdatascience.com/building-an-image-color-analyzer-using-python-12de6b0acf74?source=collection_archive---------8-----------------------

使用 Scikit-learn 和 OpenCV 的机器学习项目

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

埃里克·麦克林的照片|作者设计

在这篇文章中,我将向你展示如何创建一个程序来检测颜色,然后计算图像中颜色的权重。这将是一个有趣和简单的基于机器学习的计算机视觉项目,其中我们将使用 Scikit-learn 和 OpenCV 作为我们的主要模块。特别是,平面设计师和网页设计师会发现这个程序非常有帮助。不仅可以检测颜色,还可以在图像中看到它们的音量,这是一个非常好的功能。

作为一名技术和艺术爱好者,我喜欢从事与这两个领域都密切相关的项目。这就是我喜欢编程的原因。你的极限是你的想象力!

如果你对艺术/编程感兴趣,你可以在我的博客上找到很多这样的动手项目。抓紧时间,让我们开始工作吧!

目录

  • 入门
  • 读取图像
  • 功能
  • 图像颜色分析仪在工作
  • 结论

入门指南

在这个色彩分析项目中,我们将使用两个主要模块。它们是 Scikit-learn 和 OpenCV。Scikit-learn 是一个著名的人工智能和机器学习模块。而 OpenCV 是必备的计算机视觉模块。下面是 OpenCV 的一个简短定义。

OpenCV(开源计算机视觉库)是一个开源的计算机视觉和机器学习软件库。OpenCV 旨在为计算机视觉应用提供一个公共基础设施,并加速商业产品中的机器感知。

参考:https://opencv.org

图书馆

首先,让我给你介绍一下图书馆。这个项目我们需要五个图书馆。而这些库可以列举如下: OpenCV,Scikit-learn,NumPy,Matplotlib 和 Collections

现在,让我们使用 pip 来安装它们,pip 是一个 python 库管理器。顺便说一下,我们不需要安装 c*collections;*Python 默认自带。

pip install opencv-python scikit-learn numpy matplotlib 

安装完成后,我们可以继续导入它们。顺便说一下,这个项目我会用 Jupyter 笔记本。这是记录过程时间线的好方法。

from collections import Counter
from sklearn.cluster import KMeans
from matplotlib import colors
import matplotlib.pyplot as plt
import numpy as np
import cv2

这里是每个图书馆的官方链接。请随意查看,了解更多信息。

读取图像

我们需要选择一个图像来开始。这是我将在这个项目中使用的图像。

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

照片由埃里克·麦克林Pexels 拍摄

image = cv2.imread('test_image.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)plt.imshow(image)

我们使用 OpenCV 的 imread 方法来读取图像。然后,我们使用 cvtColor 将颜色格式从 BGR 转换成 RGB。我们在设备上看到的日常图像是 RGB 格式的。

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

作者图片

功能

在这一步,正如你从标题中可以理解的,我们将编写函数。我将定义三个对我们有用的函数。函数也是简化程序的好方法。

以下是这些函数及其定义。

rgb_to_hex

def rgb_to_hex(rgb_color):
    hex_color = "#"
    for i in rgb_color:
        i = int(i)
        hex_color += ("{:02x}".format(i))
    return hex_color

在这个函数中,我们将 RGB 颜色转换为十六进制颜色格式。这个函数将有助于最终可视化我们的分析结果。我们将有一个输出:十六进制值,而不是三个不同的值(红、绿、蓝)。

准备 _ 图像

def prep_image(raw_img):
    modified_img = cv2.resize(raw_img, (900, 600), interpolation = cv2.INTER_AREA)
    modified_img = modified_img.reshape(modified_img.shape[0]*modified_img.shape[1], 3)
    return modified_img

这个函数主要完成图像的预处理。如果您想在分析颜色之前对图片进行任何更改,这是您可以使用的功能。在这一步中,我们将调整图像的大小和形状。调整大小是可选的,但是为了使颜色分析模型正确工作,需要进行整形。我们将在下面的函数中看到它。

颜色分析

这就是奇迹发生的地方。我将重点介绍函数中发生的事情。

def color_analysis(img):
    clf = KMeans(n_clusters = 5)
    color_labels = clf.fit_predict(img)
    center_colors = clf.cluster_centers_ counts = Counter(color_labels)
    ordered_colors = [center_colors[i] for i in counts.keys()]
    hex_colors = [rgb_to_hex(ordered_colors[i]) for i in counts.keys()] plt.figure(figsize = (12, 8))
    plt.pie(counts.values(), color_labels = hex_colors, colors = hex_colors)
    plt.savefig("color_analysis_report.png") print(hex_colors)
  • 首先,我们使用 k-Means 聚类顶部的颜色。在函数内部,我们传递我们想要划分多少个集群的值。这里的是 K 均值聚类的文档。聚类之后,我们预测权重最大的颜色,这意味着在图像上获得最大的面积。
  • 其次,我们调用计数器函数。Counter 为作为字典键的元素创建一个容器,它们的容量作为字典值存储。如果您不熟悉字典,它们将数据存储在键:值对中。它们就像函数,当你传入“key”时,你可以“value”作为返回。然后我们根据颜色排序。
  • 第三,我们在 rgb_to_hex 函数中传递这些颜色,这样我们就可以得到这些颜色的十六进制值。
  • 最后,结果的可视化。我决定用饼状图,这样会有助于了解整张图片中每种颜色的权重。绘制完图形后,我也使用 savefig 方法将其保存到计算机中。这样,我们就有了结果的记录。

在我们进入最后一步之前,我想分享一篇与我们的计算机视觉项目相关的引人注目的文章:Salma Ghoneim使用 Python 通过基于颜色的图像分割进行对象检测。

运行中的图像颜色分析器

快好了!我们准备好了幕后场景。现在我们可以开始行动了。我们有前面定义的图像,并将其分配给“image”变量。我们将调用 prep_image 函数对图像进行预处理。

modified_image = prep_image(image)color_analysis(modified_image)

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

作者图片

结论

恭喜你!我们已经创建了一个程序来分析图像并以绘图的形式返回彩色报告。一个令人兴奋的特性是,我们可以定义我们想要将颜色分成多少组。我使用了五个集群,但是可以随意使用不同的值来尝试这个模型。剩下的用 Scikit-learn K-means 模型预测和 OpenCV 来完成。

最终结果出来了:

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

作者图片

希望你喜欢读这篇文章,并在今天学到一些新的东西。从事动手编程项目是提高编码技能的最佳方式。如果您在执行代码时有任何问题,请随时联系我

我们来连线。查看我的博客youtube 以获得灵感。谢谢你,

ML/人工智能项目

从头开始构建智能语音助手

原文:https://towardsdatascience.com/building-an-intelligent-voice-assistant-from-scratch-3d5749f4af07?source=collection_archive---------6-----------------------

在 RaspberryPi 和 Arduino Nano 33 BLE 上模拟谷歌助手

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

图片由穆罕默德·哈桑拍摄,来自皮克斯拜

在我的文章用 Alexa 实现家庭自动化中,我们学习了如何模拟物联网设备,并使用语音助理设备远程控制它们。在那里,我们使用了一个 Echo-Dot,每当 Alexa 这个词被发现时,它就会“醒来”。

但是,语音助手是如何工作的呢?

我们将在这个项目中尝试回答这个问题,使用 RaspberryPi 和 Arduino Nano 模拟谷歌助手。

介绍

首先,有必要认识到,市场上的语音助手,如 Google Home 或亚马逊 Echo-Dot,只有在被特定关键词“唤醒”时才会对人类做出反应,第一个关键词是“嘿谷歌”,第二个关键词是“Alexa”。

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

作者创造的形象

换句话说,识别语音命令的整个过程基于多阶段模型或级联检测。

**第一阶段:**Echo-Dot 或 Google Home 内部的一个更小的微处理器持续监听声音,等待关键词被发现。对于这种检测,在边缘使用 TinyML 模型。

阶段 2: 只有在被触发时,数据才会被发送到云端,并在更大的模型上进行处理。

TinyML是一个极好的概念,让机器智能就在物理世界旁边;此外,在微处理器级别运行机器学习模型(ML)可以避免延迟、功耗和安全性等问题。

对于这个项目的第一阶段(KWS 或关键词识别),我们将使用一个 Arduino Nano 33 BLE 感知微控制器。在几个集成的传感器中,它有一个数字麦克风,将用于识别关键词。对于第二阶段,RaspberryPi 将用于联系云端上的 Google 服务,以执行由 Arduino 触发的更复杂的任务。

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

“级联检测”:多阶段模型(改编自 TinyML 教程— HarvardX )

该项目将分为两部分:

第 1 部分:在 RPi 上模拟 Google Assistant

第 2 部分:在 Arduino Nano 上实现 KWS

在这里你可以对最终项目有一个概念:

第 1 部分—在 RPi 上模拟 Google Assistant

除了允许 RPi 模拟谷歌助手的软件之外,一些额外的硬件也是必要的。您可以安装外部麦克风和扬声器,或者为了简单起见使用帽子。在这个项目中,我们将使用一顶帽子,即 ReSpeaker 2-Mics Pi 帽子。

再代言人 2-Mics Pi 帽子

这是帽子的示意图。

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

图片来自https://wiki.seeedstudio.com/ReSpeaker_2_Mics_Pi_HAT/

它的安装非常简单:

将 ReSpeaker 2-Mics Pi HAT 连接到 Raspberry Pi

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

图片来自https://wiki.seeedstudio.com/ReSpeaker_2_Mics_Pi_HAT/

在 Raspberry Pi 上设置驱动程序

sudo apt-get update
sudo apt-get upgrade
git clone https://github.com/respeaker/seeed-voicecard.git
cd seeed-voicecard
sudo ./install.sh
reboot

检查安装在 RPi 上的声卡

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

作者终端打印屏幕

所以,在我的例子中,声卡是:

  • 卡 0: RPi HDMI
  • 卡 1: RPi 耳机音频插孔
  • 卡片 2:2-麦克风皮帽子

卡 2 应该是默认的,您可以在 Pi 首选项/音频设备设置中验证它:

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

作者打印屏幕

在我的例子中,ReSpeaker 2-Mics Pi HAT(音频插孔)上的输出无法正常工作,所以我将卡 2 定义为输入(ReSpeaker 上的 Mics),将标准 Rpi 音频插孔(卡 1)作为输出。

这种配置是通过编辑。作为/home/pi 文件夹中的 undrc 文件。要编辑该文件,请执行以下终端命令:

sudo nano /home/pi/.asoundrc

并将 pcm.output 从卡 2 更改为卡 1:

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

作者终端打印屏幕

每当 Pi 首选项/音频设备设置发生变化时,必须检查上述文件。此外,可以在声卡 1 —耳机(RPi 音频插孔)的同一菜单中更改输出音量。

此时,可以进行一些测试:

测试音频输出:

speaker-test -t wav

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

作者终端打印屏幕

你应该听扬声器里重复的“前”和“左”。按[CTRL]+[C]退出。

测试音频输入:

首先,安装 Python 库 pyaudio,用于在 RPi 上播放和录制音频:

sudo pip install pyaudio

在 puAudio 的网页上,http://people.csail.mit.edu/hubert/pyaudio/,你可以找到如何使用该库的信息和示例。

使用下面的脚本,录制几秒钟(5s)的音频:

import pyaudio
import waveRESPEAKER_INDEX = 2 # refer to input device id (card 2)
RESPEAKER_RATE = 16000
RESPEAKER_CHANNELS = 2
RESPEAKER_WIDTH = 2
CHUNK = 1024
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "record_test.wav"p = pyaudio.PyAudio()
stream = p.open(
    rate=RESPEAKER_RATE,
    format=p.get_format_from_width(RESPEAKER_WIDTH),
    channels=RESPEAKER_CHANNELS,
    input=True,
    input_device_index=RESPEAKER_INDEX,)
print("* recording")frames = []
for i in range(0, int(RESPEAKER_RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    frames.append(data)
print("* done recording")stream.stop_stream()
stream.close()
p.terminate()wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(RESPEAKER_CHANNELS)
wf.setsampwidth(p.get_sample_size(p.get_format_from_width(RESPEAKER_WIDTH)))
wf.setframerate(RESPEAKER_RATE)
wf.writeframes(b''.join(frames))
wf.close()

名为“record_test.wav”的文件应该出现在执行脚本的文件夹中。

要验证录制的音频,请执行以下脚本:

import pyaudio
import waveCHUNK = 1024
WAVE_INPUT_FILENAME = "record_test.wav"print("Playing a wave file: {}".format(WAVE_INPUT_FILENAME))
wf = wave.open(WAVE_INPUT_FILENAME, 'rb')
p = pyaudio.PyAudio()
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
    channels=wf.getnchannels(),
    rate=wf.getframerate(),
    output=True)data = wf.readframes(CHUNK)
while data != b'':
    stream.write(data)
    data = wf.readframes(CHUNK)stream.stop_stream()
stream.close()
p.terminate()

如果你听你录的,太好了!我们在出差!

在开始准备我们的 RPi 来模拟 Google Assistant 之前,让我们先来看看安装在 ReSpeaker 2-Mics Pi 帽子上的按钮和 RGB LEDs:

按钮

有一个板载用户按钮连接到 GPIO17,如下图所示。

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

ReSpeaker 2-Mics Pi HAT 原理图的一部分—参见

现在我们将尝试使用 python 和 RPi.GPIO 来检测它。

首先,安装 RPi。GPIO 库

sudo pip install rpi.gpio

接下来,您可以执行下面的脚本来测试按钮:

import RPi.GPIO as GPIO
import timeBUTTON = 17GPIO.setmode(GPIO.BCM)
GPIO.setup(BUTTON, GPIO.IN)while True:
    try:
        state = GPIO.input(BUTTON)
        if state:
            print("off")
        else:
            print("on")
        time.sleep(1)
    except KeyboardInterrupt:
        break

在终端上,您将验证按钮何时被按下。

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

作者终端打印屏幕

车载 RGB 发光二极管(APA102)

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

ReSpeaker 2-Mics Pi HAT 原理图的一部分—参见

三个板载 APA102 RGB LEDs 各有一个额外的驱动芯片。驱动芯片负责通过其输入线接收所需的颜色,然后保持该颜色,直到接收到新的命令。

安装 spidev 库:

sudo pip install spidev

并克隆以下文件:

git clone [https://github.com/respeaker/mic_hat.git](https://github.com/respeaker/mic_hat.git)

在 mic_hat 子文件夹中,执行 pixels.py 脚本,该脚本将对所有 led 执行测试。使用[CTRL]+[C]键关闭指示灯

python3 pixels.py

像素类有几个准备好的函数:

  • pixels.wakeup():打开所有 LEDS
  • pixels.off():关闭所有发光二极管
  • pixels.think():逐个打开 led,变换颜色
  • pixels.speak():打开所有发光二极管,改变其亮度

要在最终代码中有效地使用该函数,请将文件 apa102.py 和 pixels.py 放在同一个目录中。这样,您可以使用类似下面的简单代码来访问 led:

from pixels import Pixelspixels = Pixels()pixels.wakeup()
pixels.off()
pixels.think()
pixels.off()
pixels.speak()
pixels.off()

谷歌语音服务

此时,所有硬件都正常工作:

  • 音频输入
  • 音频输出
  • 纽扣
  • 发光二极管

是时候在我们的 RaspberryPi 上安装谷歌语音服务了。为此,我们将听取优秀教程http://www.makerspace-uk.co.uk/respeaker-2-mics-pi-hat/.的建议

安装谷歌助手 API

转到 Rpi 主目录,在子目录/voice-recognizer-raspi 下克隆 VoiceKit GitHub

cd ~
git clone -b voicekit https://github.com/google/aiyprojects-raspbian.git ~/voice-recognizer-raspi

转到这个创建的子目录,运行脚本来安装文件:

cd ~/voice-recognizer-raspi
scripts/install-deps.sh

要使用谷歌 Voicekit,必须有 picotts ,这是一个文本到语音的平台,它使用离线 pico 文本到语音引擎以自然的声音阅读文本。要在系统(通常是 Debian)上安装 pico TTS 库,请执行以下操作:

sudo apt-get install libttspico-utils

在一些 Raspbian 版本中,这个包是缺失的,但是你可以从 Debian 复制 arm deb 包。例如,在 Debian Buster 上,软件包丢失了,所以使用下面的命令来安装它:

wget http://ftp.us.debian.org/debian/pool/non-free/s/svox/libttspico0_1.0+git20130326-9_armhf.debwget http://ftp.us.debian.org/debian/pool/non-free/s/svox/libttspico-utils_1.0+git20130326-9_armhf.debsudo apt-get install -f ./libttspico0_1.0+git20130326-9_armhf.deb ./libttspico-utils_1.0+git20130326-9_armhf.deb

安装 gRPC(远程过程调用)

我为什么要使用 gRPC

主要使用场景:

  • 低延迟、高度可扩展的分布式系统。
  • 开发与云服务器通信的移动客户端。
  • 设计一种新的协议,它需要准确、高效且独立于语言。
  • 支持扩展的分层设计,例如身份验证、负载平衡、日志记录和监控等。
sudo pip install grpcio
sudo pip install grpcio-tools

现在,该安装 Google API 和 Google Assistant 库了:

sudo pip install --upgrade google-api-python-client
sudo pip install --upgrade google-assistant-library==1.0.1
sudo pip install --upgrade google-assistant-sdk[samples]==0.5.1

此时,安装了主要的软件包,重新启动系统:

reboot

原始谷歌语音工具包需要更改:

打开文件:

/home/pi/voice-recognizer-raspi/src/aiy/_apis/_speech.py

并注释以下几行:

#try:
# from google.cloud import speech
# from google.cloud.speech import enums
# from google.cloud.speech import types
#except ImportError:
# print("Failed to import google.cloud.speech. Try:")
# print(" env/bin/pip install -r requirements.txt")
# sys.exit(1)

现在,打开文件:

/home/pi/voice-recognizer-raspi/src/aiy/voicehat.py

并将按钮 GPIO(应该显示为 23)更改为在 ReSpeaker 2-Mics Pi HAT 上使用的按钮(应该为 17)

_GPIO_BUTTON = 17

此时,所有硬件和软件都应完成。缺少的部分是从 Google 获得在我们的树莓上运行语音工具包的凭证。

启用谷歌助手 API

启用 API 的所有步骤都可以在谷歌 AIY 语音工具包网站的“获取凭证”部分找到。

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

作者打印屏幕

这个部分位于页面的最下方(大约是一个长网站的一半)。你应该打开第二页的https://console.cloud.google.com/(谷歌云平台),然后按照第一页的指示去做。如果一切都正确,您的计算机上应该已经下载了一个 JSON 文件。这些说明还解释了如何创建一个 file assistant.json,其中必须保存此类下载文件的内容。该文件必须保存在您的 RPi 主目录中:

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

作者终端打印屏幕

除了上述说明之外,我还使用 OAuth 同意屏幕页面上的+添加用户选项,将我的电子邮件作为“测试用户”包括在内:

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

作者打印屏幕

就是这样!考验我们语音助手的时候到了!

测试语音助手

转到安装语音工具包的子文件夹:

cd ~/voice-recognizer-raspi

并运行位于/src 子文件夹中的演示程序:

python3 src/assistant_grpc_demo.py

如果一切正常,您应该在终端上看到以下消息:

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

作者终端打印屏幕

语音助手正在等待您按下按钮开始对话:

比如我按了按钮,出现了“正在收听…”的信息。我问:“现在几点了?”那也出现在终端上。同时,助理会说出答案。

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

作者终端打印屏幕

下面的视频更好地说明了一个真实的对话:

作为项目的最后一部分,让我们在上面的代码中包含帽子上可用的 led,如下所示:

将两个文件 apa102.py 和 pixels.py 复制到同一个目录中,在该目录中运行以下代码(在本例中为:“voice-recognizer-raspi/src ”)

import time
import aiy.assistant.grpc
import aiy.audio
import aiy.voicehat
from pixels import Pixels
import loggingpixels = Pixels()
pixels.off()logging.basicConfig(
    level=logging.INFO,
    format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s"
)def wakeup_assistant():
    pixels.wakeup()
    pixels.think()
    time.sleep(3)
    pixels.speak()
    time.sleep(3)
    pixels.off()def main():
    wakeup_assistant()
    status_ui = aiy.voicehat.get_status_ui()
    status_ui.status('starting')
    assistant = aiy.assistant.grpc.get_assistant()
    button = aiy.voicehat.get_button() with aiy.audio.get_recorder():
        while True:
            pixels.off()
            status_ui.status('ready')
            print('Press the button and speak')
            button.wait_for_press()
            status_ui.status('listening')
            print('Listening...')
            pixels.think()
            text, audio = assistant.recognize()
            if text:
                if text == 'goodbye':
                    status_ui.status('stopping')
                    print('Bye!')
                    pixels.off()
                    time.sleep(1)
                    break
                print('You said "', text, '"')
            if audio:
                pixels.speak()
                aiy.audio.play_audio(audio)
                pixels.off()
    pixels.off()if __name__ == '__main__':
main()

现在,一种“唤醒 LED 显示”将在启动过程中增加(一次)。此外,每次按下按钮时,语音助手都会“思考”等待我们的问题,为此我们将使用 pixels.think()函数强制 led 滚动。当助手“说话”时也是如此,led 将保持其 RGB 颜色,但会“褪色”。

注意,如果你说“再见”,助手将被关闭。

玩 GPIOs

在 RPi 上模拟 Google Assistant 的一个显著优势是,我们可以使用它的 GPIOs 来控制现实世界中的外部事物。我们已经使用 ReSpeaker 2-Mics Pi HAT 内置 led 和按钮实现了这一点。HAT 通过 Grove 连接器留有 2 个可用的 gpio(12 和 13),如其电路图所示:

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

ReSpeaker 2-Mics Pi HAT 原理图的一部分—参见

现在,我们在 RPI GPIO 13 上安装一个外部按钮,在 GPIO 12 上安装一个 LED,如下图所示:

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

作者创建的图像

我们把之前用来测试帽子按钮的脚本改成现在,测试外接按钮和 LED。每次按下按钮时,LED 都会亮起:

import RPi.GPIO as GPIO
import timeBUTTON = 13
LED = 12GPIO.setmode(GPIO.BCM)
GPIO.setup(BUTTON, GPIO.IN)
GPIO.setup(LED, GPIO.OUT)
GPIO.output(LED, GPIO.LOW)while True:
    try:
        state = GPIO.input(BUTTON)
        if state:
            GPIO.output(LED,GPIO.LOW)
            print("off")
        else:
            GPIO.output(LED,GPIO.HIGH)
            print("on")
        time.sleep(1)
    except KeyboardInterrupt:
        GPIO.cleanup()
        breakprint("clean up")
GPIO.cleanup() # cleanup all GPIO

视频展示了结果:

使用外部按钮唤醒语音助手

唯一需要做的就是改变助手的按钮 GPIO。打开文件:

/home/pi/voice-recognizer-raspi/src/aiy/voicehat.py

并将按钮 GPIO(应该显示为 17)更改为我们的外部按钮(13)所使用的按钮

_GPIO_BUTTON = 13

从现在开始,只要按下外部按钮,语音助手就会“醒来”。

用语音控制外部设备:

让我们也改变之前使用的完整代码,以纳入 LED,这应该接收一些语音控制:

  • 发动
  • 关掉
  • 眨眼

完整的代码如下:

import time
import aiy.assistant.grpc
import aiy.audio
import aiy.voicehat
from pixels import Pixels
import logging
import RPi.GPIO as GPIOLED = 12
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED, GPIO.OUT)
GPIO.output(LED, GPIO.LOW)pixels = Pixels()
pixels.off()logging.basicConfig(
    level=logging.INFO,
    format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s"
)def led_blink():
    for i in range (0,6):
    GPIO.output(LED,GPIO.HIGH)
    time.sleep(0.25)
    GPIO.output(LED,GPIO.LOW)
    time.sleep(0.25)def wakeup_assistant():
    pixels.wakeup()
    pixels.think()
    time.sleep(3)
    pixels.speak()
    time.sleep(3)
    pixels.off()def main():
    wakeup_assistant()
    status_ui = aiy.voicehat.get_status_ui()
    status_ui.status('starting')
    assistant = aiy.assistant.grpc.get_assistant()
    button = aiy.voicehat.get_button() with aiy.audio.get_recorder():
        while True:
            play_audio = True
            pixels.off()
            status_ui.status('ready')
            print('Press the button and speak')
            button.wait_for_press()
            status_ui.status('listening')
            print('Listening...')
            pixels.think()
            text, audio = assistant.recognize() if text:
                if text == 'goodbye':
                    status_ui.status('stopping')
                    print('Bye!')
                    pixels.off()
                    time.sleep(1)
                    break
                if 'turn on' in text:
                    pixels.off()
                    GPIO.output(LED,GPIO.HIGH)
                    play_audio = False
                if 'turn off' in text:
                    pixels.off()
                    GPIO.output(LED,GPIO.LOW)
                    play_audio = False
                if 'blink' in text:
                    pixels.off()
                    led_blink()
                    play_audio = False
                print('You said "', text, '"') if play_audio:
                if audio:
                    pixels.speak()
                    aiy.audio.play_audio(audio)
                    pixels.off()
    pixels.off()if __name__ == '__main__':
main()

结果在这里:

第 2 部分使用关键词识别(KWS)

到目前为止,在我们的语音助手上,用来唤醒它的方法是使用一个物理按钮,但正如在介绍中讨论的那样,语音助手,像 Google Home,应该在特定关键字被用作“嘿 Google”时做出反应。

该项目将使用一种被称为 KWS 或关键字识别的机制,用“虚拟按钮”取代物理按钮。我们将使用一个 Arduino Nano 33 BLE Sense ,这是一个集成了数字麦克风的微控制器,将用于识别关键词。

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

作者照片

为了简化(曾经这个项目的主要对象不是神经网络模型的开发),让我们重新使用 Google incorporated 在 Arduino IDE 上开发的一个代码,使用 TensorFlowLite 创建,命名为“micro_speech”。这幅草图包含了一个模型,它可以识别两个词:是,不是,除了未知和沉默。您可以从示例选项卡中获取,如下所示:

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

作者打印屏幕

为了测试,你可以把代码上传到你的 Arduino Nano 上,然后通过说“是”或“否”来测试。发现时,内部 RGB LED 应亮起(是:绿色,否:红色)。

快速回顾语音识别在微处理器上的工作原理

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

作者图片

Arduino 将在使用 TensorFlow 开发的预训练模型中执行推理。卷积神经网络模型(tiny_conv)用+100,000 个每秒(或更少)的记录样本来训练。wave 格式)的 35 个不同音素(谷歌语音命令数据集)。TensorFlowLite 将训练好的模型转换为 C 字节数组,以在小型微处理器上用作 Nano(最终模型的准确度超过 90%,大小仅为 19K 字节)。

观察原始数据(声音输入。波形格式)不能直接用于 CNN 模型。首先,声音数据应该转换成图像(40x49 像素),这是使用 MFCC 特征转换器完成的,如下所示:

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

作者图片

Mel-频率倒谱系数(MFCC)是共同构成 MFC 的系数,也就是说,它是声音的短期功率谱的表示,基于对数功率谱在非线性 Mel 频率标度上的线性余弦变换。

让我们看看代码一般是如何工作的:

1.Arduino 应该会持续聆听周围的声音。麦克风采集音频样本(1 秒),将其转换为 16 位数据(脉冲编码调制——PCM)。音频提供模块完成这项任务。

2.PCM 数据在用作推断之前应该进行预处理。在模块特征提供程序中,MFCC 特征转换器将原始数据转换为图像。每个样本将是单色图像(或大小为:[1,49,40,1]的张量)

3.TFLite 解释器运行推理,或者更好地说,将输入张量分为四个不同的类别。输出将是维数为[1,4]的张量,其中的值是输入声音为无声、未知、是或否的概率。

4.基于这些概率,模块命令识别器和响应器将使用 TFLite 解释器输出来决定是否听到命令并采取适当的行动。例如,如果声音是“是”的概率较高,内部绿色 RGB LED 将打开,如果是“否”,则打开红色 LED,最后,对于任何其他可能的单词,打开蓝色 LED。该模型被量化为 8 位整数,因此概率从 0 到 255。如果概率大于 200(80%左右),则执行该命令。

下图恢复了该过程:

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

作者图片

修改硬件

我们将安装两个外部 LED,复制 Nano 内部 RGB LED 的功能。绿色发光二极管将连接到纳米输出 D2 和红色的 D4。纳米输出 D3(与 GND 一起)将取代连接到 RPi GPIO13 的外部物理按钮。

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

作者图片

修改代码

我们必须修改代码,以便每次发现单词 YES(我们的唤醒词)时,外部绿色 LED 就会亮起,并向 RPi 发送一个脉冲,模拟按下一个按钮。

如您所见,唯一应该更改的模块是命令识别器& Responder 那会让事情发生的!这段代码在选项卡上:arduino_command_responder.cpp(这个选项卡在之前显示的 Arduino IDE 图像上高亮显示)。

下面是应该添加到 arduino_command_responder.cpp 中的新代码部分:

...#define GREEN_LED_PIN 2
#define SIM_BUT_PIN 3
#define RED_LED_PIN 4// Create a function to simulate a button pressed for 500msvoid buttonSimulator(){
  pinMode(SIM_BUT_PIN, OUTPUT);
  digitalWrite(SIM_BUT_PIN, LOW);
  delay(500);
  pinMode(SIM_BUT_PIN, INPUT);
}...pinMode(GREEN_LED_PIN, OUTPUT);
pinMode(RED_LED_PIN, OUTPUT);
pinMode(SIM_BUT_PIN, INPUT); // Open state...// If we hear a command, light up the appropriate LEDs and send signal to RPi
    if (found_command[0] == 'y') {
      last_command_time = current_time;
      digitalWrite(LEDG, LOW);  // Green for yes
      digitalWrite(GREEN_LED_PIN, HIGH);  // HIGH for yes
      buttonSimulator(); // Simulate button 
    } if (found_command[0] == 'n') {
      last_command_time = current_time;
      digitalWrite(LEDR, LOW);  // Red for no
      digitalWrite(RED_LED_PIN, HIGH);  // HIGH for yes
    }...// If last_command_time is non-zero but was >3 seconds ago, zero it
  // and switch off the LED.
  if (last_command_time != 0) {
    if (last_command_time < (current_time - 3000)) {
      last_command_time = 0;
      digitalWrite(LED_BUILTIN, LOW);
      digitalWrite(GREEN_LED_PIN, LOW);
      digitalWrite(RED_LED_PIN, LOW);
      digitalWrite(LEDR, HIGH);
      digitalWrite(LEDG, HIGH);
      digitalWrite(LEDB, HIGH);
    }...

要了解更多关于 TinyML 和原始代码是如何开发的,我强烈建议阅读由彼得·沃顿丹尼尔·斯图纳亚克TinyML 的伟大著作:在 Arduino 和超低功耗微控制器上使用 TensorFlow Lite 进行机器学习

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

图书封面

就是这样!

结果可以在简介中的视频和我的 GitHub 中完整修改的 Arduino 代码上得到验证。

结论

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

一如既往地希望这个项目能帮助其他人在 AI、电子和 IoT 的激动人心的世界中找到自己的路!

请访问我的 GitHub 获取更新文件:智能语音助手

更多项目,请访问我的博客:MJRoBot.org

来自世界南部的 Saludos!

我的下一篇文章再见!

谢谢你

马塞洛

在 Jupyter Notebook 中构建交互式注释工具

原文:https://towardsdatascience.com/building-an-interactive-annotation-tool-inside-jupyter-notebook-f3d92570ee16?source=collection_archive---------10-----------------------

朱庇特笔记本是❤️️的

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

来自的修改图像

在这篇博客中,我将讨论如何使用 ipywidgets 模块,并在你自己的 Jupyter 笔记本中构建一个交互式注释工具。所有现在或曾经在任何初创公司担任数据科学家的人都知道他们需要做的工作范围。其中,构建任何类型的接口*(用于展示 API 功能、注释等)*都很常见,由他们来设计和开发。这种用户界面从来不会出现在公众面前,而是季节性地用于内部目的和开发。

在这篇博客中,我们将会看到如何轻松地构建一个注释工具,并利用 Jupyter 笔记本来完成同样的任务。我假设您已经熟悉 Jupyter 笔记本,但是,如果我不得不写一行关于它的话,它是一个基于浏览器的交互式编码环境**具有许多令人惊叹的功能,如就地图形渲染、将代码导出为文档 (latex、pdf 等)等等。

我们将专注于为构建一个非常简单的注释工具奠定基础,该工具用于注释句子分类任务的数据,例如情感分类、意图分类等等。这同样可以扩展到图像。同样的也可以扩展到图像。下面的代码片段显示了我们将要构建的句子注释器工具的最终产品

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

使用 ipywidgets 在 Jupyter 笔记本中进行交互式注释|作者图片

我们首先从构建工具的描述部分开始。正如在下面的代码中可以看到的,我们从应该被注释的句子列表中读取输入,但是合并从文件系统中读取也不难,可以使用 glob 模块遍历文件,这将返回给定文件夹中所有文件的路径列表。

我们要做的下一件事是创建一个长度等于要注释的句子数量的空数据帧。然后,我们使用 HTML 小部件在我们的笔记本中呈现 HTML 样式的内容。这样,我们定义了可能需要的标题、任何指令等,帮助注释者顺利完成工作。

# data for text classification annotation  
 sentences = ["i like to eat food", "i like to play hockey", "food is the best thing that can be on earth", "do you know how to play chess"]  
 ####################################################################################################  
 # Instead of list you can take input from your LFS or Drive and transform data in the list format  
 ####################################################################################################  
 #to be shown at a time  
 BATCH = 10  
 # output dataframe  
 cols = ['sentence', 'label']  
 df = pd.DataFrame(columns=cols, index=range(len(sentences)))  
 title_widget = widgets.HTML(  
   value="""<h1>Welcome to the <font color='maroon'> Sentence Annotator</font></h1>  
   <p>It's an in-line annotation tool that let's you annotate sentences with their respective tags</p>  
   <p>Below are the set of instructions for the annotator to follow - </p>  
   <ol>  
    <li>Select sentence from the <b>sentences</b> area shown in the annotation area</li>  
    <li>You can select multiple sentences by pressing ctl+mouseclick</li>  
    <li><b>Label</b> area where you type the tags that are relevant for the given sentence</li>  
    <li>Progress let's you track the progress made so far in the annotation cycle</li>  
   </ol>  
   <p><font color='green'>P.S. Incase of multiple labels for any sentence. Use comma (,) as a seperator</font></p>""",  
 )  
 display(title_widget)

我们关注的下一件事是构建文本选择片段,在这方面,我们计划提供多选功能,因为这将加快进程,并帮助注释者一次选择多个句子并一次性注释它们。我们使用 SelectMultiple 小部件来实现这一点。我们还传入一些必要的参数,比如句子、批处理*(一次显示多少)*、段的描述以及要显示的宽度。

# sentence placeholder  
 sentence_widget = widgets.SelectMultiple(  
   options=sentences,  
   rows=BATCH,  
   description='Sentences',  
   disabled=False,  
   layout= widgets.Layout(width='50%')  
 )  
 display(sentence_widget)

接下来,我们研究如何制作标签、按钮和进度部分。我们使用文本小部件,它为我们提供了一个输入类标签的文本输入空间。我们还使用一个按钮小部件来冻结到目前为止为一个给定的批处理完成的注释,并用相关的字段进行初始化,比如描述、样式和工具提示。我们还使用 IntProgress 小部件制作了一个进度条,它为我们制作的每个注释更新一个单位的进度条。我们用最小值和最大值分别作为 0 和句子总数来初始化它。

# class placeholder  
 label = widgets.Text(description="Label", value='')  
 display(label)  
 # button placeholder  
 button = widgets.Button(description="Annotate", disabled=False, button_style="success", tooltip="Annotate")  
 output = widgets.Output()  
 display(button, output)  
 # progress bar placeholder  
 progress = widgets.IntProgress(  
   min=0,  
   max=len(sentences),  
   step=1,  
   description='Progress:',  
   orientation='horizontal',  
   layout= widgets.Layout(width='20%')  
 )  
 display(progress)

到目前为止,我们已经介绍了该工具的外观和感觉,现在我们继续编写相同的后端功能。我们的函数 annotate 负责所有这些事情,单击 annotate 按钮调用它。我们检查标签和句子小部件下的值,并通过某些强制检查来正确地获取它们。然后,我们遍历句子,将它们一个接一个地添加到我们之前创建的空数据框中。

counter = 0 #keep count of progress in dataframe  
 def annotate(_):  

   global counter  

   with output:  
     label_value = label.value  
     selected_sentence = sentence_widget.value  

     if not len(selected_sentence):  
       print("No sentence selected!")  
       return  
     if not label_value:  
       print("No class name selected!")  
       return  

     progress.value += len(selected_sentence)  

     for i in selected_sentence:  
      df.loc[counter].sentence = i  
      df.loc[counter].label = label_value  
      counter += 1  

 button.on_click(annotate)

这篇博客到此为止。随意访问 Colab 笔记本 ,也可以查看这个牛逼库的 官方自述

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

Jupyter 笔记本中的句子注释演示|图片由作者提供

注:如果 collab 笔记本无法使用,请考虑将笔记本下载到您的系统中,并在本地启动 Jupyter。

我希望这本书值得你花时间阅读。谢谢大家!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值