轻松为您的手机创建人工智能应用程序—零编码体验
图片来自皇家菲尔德网站
我用可教机器和 P5JS 创建了一个简单的 AI webapp。当我用手机摄像头指向我的摩托车皇家恩菲尔德经典 350 时,这款应用程序显示了它们的每个部件的名称。下面是同样的视频:
Fabin Rasheed 的视频
在网上分享这个视频让许多朋友好奇这是如何工作的,我想我会写一个关于这个的教程。
这可以在 3 个较大的步骤中完成,并且需要非常非常少的编码。事实上,任何人都可以通过笔记本电脑、智能手机和 wifi 连接做到这一点。我将尝试用现有的教程视频解释第一步,并详细解释第二步和最后一步。好的,我们开始吧。
步骤 1:使用可示教机器™
可教机器是一个漂亮的工具,可以用来进行基于人工智能的实验,如图像分类、声音分类等。你可以用它来分类你的蔬菜,创建一个应用程序来教你的孩子不同的形状等等。
从可教机器开始非常简单直观。不过,以下是可教机器“入门”系列的视频,帮助您入门。(这里就不细说 TM 怎么用了。)
采集样本:https://youtu.be/DFBbSTvtpy4
训练你的模型:https://youtu.be/CO67EQ0ZWgA
出口型号:https://youtu.be/n-zeeRLBgd0
练习到这里,慢慢适应 TM。然后,我们可以继续创建移动网络应用程序。
第二步:为应用程序创建数据
因此,可示教机器目前仅适用于台式机。但是这种实现也将其扩展到了移动电话。第一步是收集图像。
我所做的是:
- 用我的手机为自行车的每个部分录制了一段视频。
- 然后使用 Adobe Media Encoder 将视频转换成帧(图像)(你也可以试试这个)。每个部分的图像被放在不同的文件夹中。(所以有一个文件夹存放“油箱”图片,另一个文件夹存放“发动机”图片)
每个部分的图片在一个单独的文件夹中(图片由 Fabin Rasheed 提供)
3.这些文件夹随后被用作可示教机器的输入。(点击上传按钮,而不是网络摄像头按钮)
每堂课有将近 700 张图片。例如,此处显示的样本较少。(图片来自可示教机器)
4.然后对模型进行训练。
第三步:制作 app
好了,现在开始在智能手机中设置 webapp 的部分:
1.前往 https://github.com/nurecas/visualmanual点击克隆/下载——下载 Zip。(如果您还没有 Github 帐户,可能需要创建一个)。将其提取到一个文件夹中,最好是在桌面中,将文件夹重命名为 RoyalEnfield。
2.在括号、MS visual studio、记事本等文本编辑器中打开文件夹内的 RoyalEnfield.js。
3.现在打开你的可教机器实验,按“导出模型”。
4.现在在 Tensorflow.js 下,你会发现“上传我的模型”。点击那个。
来自可示教机器的图像
5.上传完成后,复制生成的链接。
6.使用 RoyalEnfield.js 打开文本编辑器。在第 4 行中,替换 URL,即,
变化
let imageModelURL = ‘[https://teachablemachine.withgoogle.com/models/s379EsNn/](https://teachablemachine.withgoogle.com/models/s379EsNn/)';
随着
let imageModelURL = ‘**the URL you just copied**’;
7.保存文件。
8.如果您使用的是 Mac,请打开终端(CMD+Space,键入终端)。
如果您在 Windows 中,打开命令提示符(在这种情况下,您可能需要安装 python )
9.使用“cd”命令更改您提取的文件夹的路径。例如,如果您在桌面中,请键入:
cd Desktop/RoyalEnfield/
10.键入以下命令启动本地服务器(这适用于 MacOS Catalina 或最新的 Windows 版本):
python -m http.server 8013
如果这不起作用,并且您有较旧的操作系统,请键入以下内容:
python -m SimpleHTTPServer 8013
如果你能创建一个 HTTPS 服务器而不是 HTTP 服务器,那是强烈推荐的。这里的步骤创建了一个简单的 HTTP 服务器,应该只用于测试/原型/实验>
11.服务器启动后,测试您电脑中的浏览器是否一切正常:
在浏览器的地址栏中输入 localhost:8013 并按回车键。如果一切顺利,继续。
12.现在你需要找到你的计算机的本地 IP 地址。这可以通过点击 Mac 顶部的 WiFi 图标并选择“打开网络偏好设置”来找到。你会看到“WiFi 连接* * * IP 地址是 x.y.z.a”。记下这个数字 IP 地址(x.y.z.a)
对于 Windows,检查此链接。
13.如果一切正常,那就把你的手机和 Mac 连上同一个 WiFi。
14.打开手机中的 Chrome,输入 chrome:flags ,然后按回车键。
15.搜索“不安全的来源被视为安全的”。在显示的文本框中输入您的 IP 地址和端口 8013。例如,如果您的 IP 地址是 192.168.23.3,请键入 http://192.168.23.3:8013 。
我知道这一步听起来令人毛骨悚然,但这一步必须完成,因为我们设置的服务器是 HTTP 服务器,而不是安全的 HTTPS 服务器。如果您通过其他方法创建了 HTTPS 服务器,您可以忽略这一步。>
图片来自谷歌浏览器
16.现在将禁用更改为启用。
< 请务必在玩完实验 > 后将其改回禁用状态
17.按重启键
18.好吧!我们已经走到了尽头。现在,在手机的网络浏览器中键入您的 IP +端口(例如http://192 . 168 . 23 . 3:8013/),然后按回车键。如果所有步骤都做对了,你就能让它工作了。
如果您看到黑屏,请再次尝试步骤 15–17。
我希望这能帮助你开始并运行一些简单的人工智能实验。如果你遇到任何问题,请随时在我的推特上给我留言:https://twitter.com/@fabinrasheed
所有的荣誉都归于可教机器和 P5JS 背后的神奇团队。
在 www.nurecas.com 跟随我的作品
谢谢:)
我与皇家恩菲尔德品牌没有关系,也不认可这个品牌。我喜欢这辆自行车,我只是想在这里展示智能手机中人工智能的一个用例。
使用 Metropolis-Hastings 轻松改进任何 GAN
无需在 TensorFlow 中进行额外培训即可创建更高保真度的样品
如何才能以尽可能少的工作来改进我们的 GAN?(图片来自 Pixabay )
从你的 GAN 得到可信的输出有困难吗?在本文中,我们将回顾最近对 GANs 的改进,该改进通过简单易用的 Tensorflow 2 实现来提高输出质量,让您自己的 Metropolis-Hastings GAN 起步!
关于报纸
2018 年末,优步工程发布了一篇题为**“Metropolis-Hastings 生成对抗网络”(Turner 等人)的论文,其中作者介绍了一个简单的技巧,在 GAN 的不增加 GAN 的训练时间的情况下,提高了 GAN 的输出。如果你对 GANs 不是很熟悉,我建议在继续深入了解我们正在处理的模型之前,先阅读这篇文章。**
来自“Metropolis-Hastings Generative Adversarial Networks”(2018,Turner 等人)的视频,展示了 MH 如何提高渐进式 gan 的输出
优步工作的基本前提是,通常在训练后被丢弃的鉴别器包含有价值的信息,用于确定哪些样本类似于真实的数据分布。作者提出了一种新颖的采样方案,其中使用 Metropolis-Hastings 从生成器的潜在空间中抽取样本,由鉴别器选择接受哪个生成的样本。
图 1:来自优步论文的 Metropolis-Hastings GAN 伪代码
这种方法的巧妙之处在于,它适用于任何 GAN 架构或损失函数,因为 MH-GAN 实际上只是一种训练后采样方法。在我们展示如何应用这种采样方法之前,让我们先训练一个 GAN 来使用它!
在 TensorFlow 2 中培训我们的 GAN
为了开始我们训练 MH-GAN 的旅程,我们首先要训练最小平方 GAN,因为它的稳定性和易于实现。如果你想了解更多关于 LS-GANs 的知识,我在文章底部提供了一个链接。对于数据,我们将使用 TensorFlow 中包含的时尚 MNIST 数据集,因此这些结果很容易在家中复制!
请注意,下面的一些训练代码改编自位于此处的官方 tensor flow DC-甘教程:
请注意,我们还使用了tensorflow-addons
包来实现一些更高级的功能,如 Ranger 优化器和 Mish 激活层,以平滑训练过程。
定义我们的生成器和鉴别器
训练我们的网络的下一步是定义我们的生成器和鉴别器对象,以馈入我们的 LS-GAN 类:
我们有一个基类来训练一个最小平方 GAN 以及一个生成器和鉴别器,现在是时候开始实现 MH-GAN 了!
大都会-黑斯廷斯算法
在实现 MH-GAN 时,我们需要了解的第一件事是 Metropolis-Hastings 算法。MH 是一种马尔可夫链蒙特卡罗方法,用于从难以直接采样的分布中进行采样。在这种情况下,我们试图从鉴别器隐含的真实数据分布中进行采样。
我们不会深入探讨 Metropolis-Hastings 背后的理论,但如果你想了解更多,我在本文底部提供了一个链接。
一旦我们有了一个经过训练的生成器和鉴别器,我们使用以下步骤来抽取遵循真实数据分布的样本(请随意参考上面的伪代码):
- 用真实的数据样本作为链的种子(作者这样做是为了避免 Metropolis-Hastings 带来的漫长磨合期)
- 对于 K 次迭代,我们从生成器中抽取一个随机样本,并从鉴别器中计算得分
- 在每次迭代中,如果以下表达式大于范围[0,1]中的随机数,则接受新样本并与下一次迭代进行比较:
图 2:MH-GAN 中接受新样品的条件(摘自优步 MH-GAN 论文)
本质上,该规则所做的是比较建议样本的鉴别器分数与当前样本分数的比率,以确定我们是否应该“接受”新样本。通过足够的迭代,我们的独立链将近似我们的鉴别器输出所暗示的真实数据分布!
如果我们在一定次数的迭代后无法接受任何样本,作者建议从合成样本重新开始链以保证收敛,尽管速度较慢。
然而这并不是故事的结尾,因为我们的鉴频器的输出还有一个悬而未决的问题,我们将在下一节解决这个问题。
校准我们的鉴别器
在应用 Metropolis-Hastings 时所做的一个假设是,我们的鉴别器的概率是校准好的。这意味着鉴别器输出必须被解释为置信水平。不幸的是,神经网络分类器的原始输出几乎从未被很好地校准过,这意味着我们必须应用额外的步骤来校准输出。即使我们在最后一层使用 sigmoid 或 softmax 激活,也是如此!
Scikit-Learn 文档中有很大一部分是关于校准的这里是,但是论文作者推荐的是使用一种称为保序回归的技术将网络输出转换为校准的概率,作为后处理步骤。不幸的是,这需要在一个固定的集合中完成,这意味着我们必须将我们的时尚 MNIST 分成一个训练和验证集合(幸运的是 Tensorflow 为我们做到了这一点!)
下面是一个校准曲线(一个说明模型校准的诊断工具,45 度线代表完美的校准),显示了我们的等张预测如何满足 Metropolis-Hastings 条件。另一方面,我们的原始输出显然没有校准好。
图 3:校准曲线显示对鉴频器输出应用保序回归后的改善
一旦我们校准了鉴别器,我们就可以使用校准的概率来确定我们上面概述的独立 MCMC 链中新样本的接受概率!
编码我们的 MH-GAN
现在,终于到了用我们上面编码的 LS-GAN 的子类进行校准和 Metropolis-Hastings 采样的时候了。请注意,我们可以很容易地将这个子类应用于遵循我们上面概述的 API 的任何其他种类的 GAN,甚至可以使它适应现有的 GAN 包。
请注意,这里有几件事情要做,首先我们需要实现一种方法来训练我们的校准器以及一种校准的评分方法。
为了训练校准器,我们只需拿出一组样本,从生成器中生成相同数量的样本。接下来,我们训练 Scikit-Learn 中的 IsotonicRegression 类,将鉴别器分数转换成真实概率。
最后,我们有我们的generate_mh_samples()
方法,它生成指定数量的接受样本,给出一个真实的例子来播种 MCMC 链。你能在这里看到一个共同的主题吗?校准后的评分和 MH 样品生成方法与 LS-GAN 的score_samples()
和generate_samples()
方法完全相同!
是时候使用时尚 MNIST 的数据来体验这个新的课程了!
比较结果
为了开始使用我们闪亮的新 MH-GAN 类,我们必须做的第一件事是加载我们的时尚 MNIST 数据,并将其分成我们的训练和验证集,以及归一化像素。好在 tf.keras 让这个超级容易!
既然我们已经有了训练集和测试集,我们要做的就是用上面声明的生成器和鉴别器初始化我们的MHGAN
对象,以及生成器和优化器学习率的噪声维度。然后,我们将训练 50 个历元(这是相当随意的,通常这需要对 GANs 进行更多的考虑),最后校准我们的鉴别器。我们的面向对象方法允许我们用 3 行代码就可以做到这一点!
训练完成后,我们可以通过使用正常的朴素 GAN 采样或优步论文中的 Metropolis-Hastings 算法,从我们训练的 MH-GAN 中提取样本。
让我们来看看使用 LS-GAN、MH-GAN 生成的 15 幅图像,以及一些真实图像进行比较:
图 4:LS-GAN 和 MH-GAN 输出与时尚 MNIST 数据集真实样本的比较
****哇!我们可以肯定地看到,MH-GAN 几乎完全避免了样品明显造假的问题!这一发现与优步团队的发现一致,他们在 CelebA 数据集上报告说,他们的方法大大减少了低保真度图像的数量。我们可以看到来自 LS-GAN 的样本实例看起来就像不明确的斑点,而这在我们的 MH-GAN 中发生的频率要低得多。
该团队还认为,它解决了模式崩溃问题,但在我对他们的方法的试验中,我并没有真正看到这种情况发生,但 MNIST 和时尚-MNIST 并不总是算法性能的最佳指标,这不是一个问题。
结论
如果你对我们在本文中展示的 GAN 的快速改进感兴趣,我强烈推荐阅读下面链接的 MH-GAN 原文!此外,我们已经展示了 TensorFlow 2 使应用这种技术变得极其容易,只需要很少的额外代码!
关于基于鉴频器的 GAN 采样,还有许多其他有趣的论文,如 Azadi 等人的“鉴频器抑制采样”和 Che 等人的“您的 GAN 实际上是一个基于能量的模型,您应该使用鉴频器驱动的潜在采样”,显示了该领域的前景。毫无疑问,看看未来几年这种趋势会变得有趣。
如果你对这篇文章有任何问题或意见,请不吝发表在下面!
参考资料和资源
链接到优步最初的 MH-GAN 论文:
**[## Metropolis-Hastings 生成对抗网络
我们介绍了 Metropolis-Hastings 生成对抗网络(MH-GAN ),它结合了马尔可夫链的各个方面
arxiv.org](https://arxiv.org/abs/1811.11357)**
优步工程公司关于 MH-GANS 的原始网站文章:
** [## 如何免费获得更好的 GAN:介绍大都会-黑斯廷斯 GAN
生成对抗网络在真实感图像生成和图像修复方面取得了令人瞩目的成就
eng.uber.com](https://eng.uber.com/mh-gan/)
一篇关于最小二乘 GAN 的有用文章
感谢 F-GAN,它建立了 GAN 训练的一般框架,最近我们看到了 GAN 的修改…
wiseodd.github.io](https://wiseodd.github.io/techblog/2017/03/02/least-squares-gan/)
Metropolis-Hastings 采样快速指南:
[## 从零开始:贝叶斯推理,马尔可夫链蒙特卡罗和大都会黑斯廷斯,用 python 编写
0-我的第一篇文章
towardsdatascience.com](/from-scratch-bayesian-inference-markov-chain-monte-carlo-and-metropolis-hastings-in-python-ef21a29e25a)**
轻松可视化 Scikit-learn 模型的决策界限
一个简单的效用函数来可视化 Scikit-learn 机器学习模型/估计器的决策边界。
图片来源: Pixabay(免费授权)
介绍
Scikit-learn 是一个令人惊叹的 Python 库,用于工作和试验过多的监督和非监督机器学习(ML)算法和相关工具。
它的构建考虑到了健壮性和速度——尽可能多地使用 NumPy 和 SciPy 方法和内存优化技术。最重要的是,该库为所有类型的 ML 估计器提供了一个简单而直观的 API(T10)——拟合数据、预测和检查模型参数。
图像:Scikit-learn 估计器图示
对于监督最大似然领域中的许多分类问题,我们可能希望超越数值预测(类别或概率)并可视化类别之间的实际决策边界。当然,这尤其适用于二元分类问题和一对要素,可视化显示在二维(2D)平面上。
例如,这是来自 Scikit-learn 官方文档的支持向量机(SVM)教程的决策边界的可视化。
图片来源: Scikit-learn SVM
虽然 Scikit-learn 没有提供现成的、可访问的方法来实现这种可视化,但在本文中,我们将研究一段简单的 Python 代码来实现这一点。
一个简单的 Python 函数
完整代码在我的 Python 机器学习上的 Github Repo 这里给出 。当然也欢迎你到探索整个库寻找其他有用的 ML 教程。
这里,我们展示了 docstring 来说明如何使用它,
实用函数的文档字符串
您可以将模型类和模型参数(对于每个模型类是特定且唯一的)以及要素和标签数据(作为 NumPy 数组)传递给函数。
这里的模型类表示精确的 Scikit-learn 估计器类 ,您在中调用它来实例化您的 ML 估计器对象。请注意,您不必传递您正在使用的特定 ML 估计器。只有类名就足够了。该函数将在内部拟合数据并预测以创建适当的决策边界(考虑您传递的模型参数)。
目前,函数仅使用前两列数据来拟合模型,因为我们需要找到网格样式散点图中每个点的预测值。
主代码部分
一些说明性结果
代码很无聊,而结果(和情节)很刺激,不是吗?
为了演示,我们使用了离婚分类数据集。这个数据集是关于完成个人信息表和离婚预测量表的参与者。该数据是在 UCI 门户上公开的数据的修改版本(在注入一些噪声之后)。有 170 个参与者和 54 个属性(或预测变量)都是实值。
我们在同一个数据集上比较了多个最大似然估计的性能,
- 朴素贝叶斯
- 逻辑回归
- k-最近邻(KNN)
因为这个特定数据集的二进制类是相当容易分离的,所以所有的 ML 算法表现几乎一样好。然而,它们各自的决策边界看起来彼此不同,这就是我们感兴趣的通过这个效用函数可视化。
图片:离婚预测数据集的类别可分性
朴素贝叶斯决策边界
来自朴素贝叶斯算法的决策边界是平滑的,并且略微非线性。而且,只有四行代码!
逻辑回归决策边界
正如预期的那样,来自逻辑回归估计器的决策边界被可视化为线性分隔符。
k-最近邻(KNN)决策边界
k-最近邻是一种基于特征超平面上数据分布的局部几何(以及它们的相对距离度量)的算法。因此,决策边界表现为非线性和不平滑的。
你甚至可以通过神经网络分类器
该函数适用于任何 Scikit-learn 估计器,甚至神经网络。这里是 Scikit-learn 的MLPClassifier
估计器的决策边界,它模拟一个密集连接的神经网络(具有用户可配置的参数)。注意,在代码中,我们传递了隐藏层设置、学习率和优化器(随机梯度下降或 SGD)。
检查模型参数的影响
如前所述,我们可以将我们想要的任何模型参数传递给效用函数。在 KNN 分类器的情况下,随着我们增加相邻数据点的数量,决策边界变得更加平滑。使用我们的效用函数,可以很容易地看到这一点。注意,在下面的代码中,我们如何在一个循环中将变量k
传递给n_neighbors
模型参数。
摘要
我们展示了如何编写一个简单的效用函数来接受任何 Scikit-learn ML 估计器(具有用户希望传递给模型的任何模型参数),用于二进制分类任务,并使用几行代码可视化正类和负类之间的判定边界。
该函数可与任何 Scikit-learn 估计器配合使用,并且可扩展和配置,以便在将来包含更多的类和多绘图功能。
再次说明,我在 Python 机器学习上的 Github Repo 里这里给出了 完整代码 。将根据需要添加更新。
如果您有任何问题或想法要分享,请联系作者在tirthajyoti【AT】Gmail . com。此外,您可以查看作者的 GitHub 资源库中的代码、想法和机器学习和数据科学方面的资源。如果你和我一样,对人工智能/机器学习/数据科学充满热情,请随时在 LinkedIn 上添加我或在 Twitter 上关注我。
[## Tirthajyoti Sarkar - Sr .首席工程师-半导体、人工智能、机器学习- ON…
通过写作使数据科学/ML 概念易于理解:https://medium.com/@tirthajyoti 开源和有趣…
www.linkedin.com](https://www.linkedin.com/in/tirthajyoti-sarkar-2127aa7/)
轻松访问世界上最大的数据源
Python 的维基百科 API
数据的重要性远高于在数据科学中构建最先进的算法。如果没有合适的大量数据,我们就无法很好地训练模型,以获得令人满意的结果。
作为世界上最大的百科全书,维基百科可以作为许多项目的巨大数据源。有许多网络抓取工具和框架允许从维基百科获取数据。然而,Python 的 Wikipedia API 可能是最简单易用的。
在本帖中,我们将看到如何使用维基百科 API 来:
- 访问特定页面的内容
- 搜索页面
您可以轻松地安装和导入它。我将使用谷歌 Colab,所以这里是它是如何在 Colab 中完成的:
pip install wikipedia
import wikipedia
页面的内容可以用 page 方法提取。页面的标题作为参数传递。以下代码将支持向量机页面作为 WikipediaPage 对象返回。
page_svm = wikipedia.page("Support vector machine")type(page_svm)
wikipedia.wikipedia.WikipediaPage
这个对象保存了可以通过 url 方法访问的页面的 URL。
page_svm.url[https://en.wikipedia.org/wiki/Support_vector_machine](https://en.wikipedia.org/wiki/Support_vector_machine)
我们可以用 content 方法访问页面的内容。
svm_content = page_svm.contenttype(svm_content)
str
内容以字符串形式返回。以下是 svm_content 字符串的前 1000 个字符。
返回的内容是一个字符串,这不是分析的最佳格式。我们可以处理这个原始字符串来推断有意义的结果。有一些高效的自然语言处理(NLP)库可以处理文本数据,比如 NLTK、BERT 等等。
我们不会详细讨论 NLP 任务,但让我们做一个简单的操作。我们可以将内容字符串转换成 python 列表,该列表将单词作为单独的元素包含在内。然后我们可以计算一个特定单词出现的次数。
content_lst = svm_content.split(" ")len(content_lst)
57779content_lst.count("supervised")
4
title 方法用于访问页面的标题。
references 方法返回页面上使用的引用列表。本页的前 5 个参考如下:
同样,我们也可以提取页面上图像的链接:
我们心里并不总是有一个确切的标题。假设我们正在寻找标题中包含“心理学”一词的页面。这可以通过搜索方法来完成。
在某些情况下,返回的列表太长,所以我们可能希望限制返回的项目。只需将所需的项目数传递给结果参数。
注:除非另有说明,所有图片均由作者创作。
编辑:感谢尼克·韦伯指出这一点。Wikipedia API 的创建者明确声明“这个库是为了易用性和简单性而设计的,而不是为了高级用途。如果您计划执行重要的抓取或自动请求,请使用 Pywikipediabot(或其他更高级的 Python MediaWiki API 包装器之一),它具有更大的 API、速率限制和其他功能,因此我们可以考虑 MediaWiki 基础架构。”
结论
维基百科是一个非常有价值的数据来源。它提供了对许多主题的结构化信息的访问,并作为机器学习和深度学习任务的数据源。例如,这些数据可以用来训练复杂的 NLP 模型。
维基百科 API 使得访问和使用这个巨大的数据源变得非常容易和简单。
感谢您的阅读。如果您有任何反馈,请告诉我。
用于机器学习模型的简单自动化特征工程
自动化模型开发的痛苦部分
照片由 Goh Rhy Yan 在 Unsplash 上拍摄
作为一名数据科学家,我们知道处理数据是我们的日常活动。从拉数据,分析数据,创建一个有用的机器学习模型。
虽然许多人认为创建机器学习模型很容易,但事实并非如此。人们可能认为我们只需要输入一些编码语言,瞧!机器学习模型做好了。
它可能是这样工作的,但是这个模型有用吗,对业务问题有什么影响吗?大部分时间可能不是。这是因为现实生活中的数据是杂乱的,如果没有适当的测量,它将导致一个有缺陷的模型。
提高机器学习模型性能的一种行之有效的方法是从现有特征或特征工程中创建新特征。
特征工程的概念很容易理解,因为这个想法是关于从现有的特征中创建新的特征。例如,我们有产品价格及其重量的数据。
从这两个特性中,我们可以创建一个新的特性。比方说每克的产品价格。在这种情况下,我们需要将价格除以产品重量。
就这样,我们得到了一个新的特性。这就是特征工程的概念。
机器学习模型的核心是数据,提高性能的方法是通过特征工程,尽管掌握特征工程需要很多技能。我们需要有创造力,了解商业领域。这肯定要花很多时间。
为了解决特征工程问题的局部部分,我们可以自动化时间任务特征工程过程。
自动化特征工程
用于执行自动化特征工程的主要开源库之一是 Featuretools 。它是一个库,旨在通过自动化过程来加快特征生成过程。
在 Featuretools 中,有三个我们应该知道的包的主要组件。它们是:
- 实体
- 深度特征综合(DFS)
- 特征基元
解释在下面的文章中。
- 实体是 Featuretools 中熊猫数据框的表示。多个实体被称为一个实体集。
- 深度特征合成 (DFS)是 Featuretools 中的一种特征工程方法。这是用于从单个和多个数据框创建新要素的方法。
- DFS 通过将特征原语应用于 EntitySet 中的实体关系来创建特征。特征基元是我们称之为手动生成特征的方法,例如,基元平均值是聚合级别的变量的平均值。
这是足够的理论;我们可能会直接跳到工具的实际用途。为了做好准备,我们需要先安装库。
pip install featuretools
现在,Featuretools 最适合用于具有许多关系的多个数据集。在这种情况下,我会使用来自 Kaggle 的 Olist Brazallian 电子商务数据集。
数据在 CSV 文件中,由许多数据组成。在这种情况下,我会选择一些数据作为例子。
olist_items = pd.read_csv('olist_order_items_dataset.csv')
olist_product = pd.read_csv('olist_products_dataset.csv')
olist_customer = pd.read_csv('olist_customers_dataset.csv')
olist_order = pd.read_csv('olist_orders_dataset.csv')
我们简单看一下数据。首先,我们来看看 olist_customer 数据。
我们可以看到数据包含一个唯一的变量作为标识,名为“customer_id”。当我们想使用 Featuretools 时,这个变量是必要的,因为特征工程的实体将使用这个唯一的变量作为分组指示符。
让我们看看 olist_order 数据。
我们可以看到,olist_order 数据包含“order_id”变量作为标识,还包含“customer_id”变量来指示是谁下的订单。
对于最后一个,我需要产品的数据和商品的订单号,但是因为它分散在两个数据集中,所以我将它合并成一个。我还会删除一些我们不需要的功能,并为标识重置索引。
olist_item_product = pd.merge(olist_items, olist_product, on = 'product_id')olist_item_product.drop(['order_item_id', 'seller_id'], axis =1, inplace = True)olist_item_product.reset_index(inplace = True)
现在我们有了所有需要的数据集。让我们尝试使用 Featuretools 来实现特征工程的自动化。
首先,我们需要准备的是执行 DFS 的实体。那么,我们到底需要在实体中准备些什么呢?正如我之前提到的,实体是一种数据框表示。在实体的情况下,我们将准备一个包含实体名称和带有标识的数据帧的字典。
实体的例子解释如下。
#We prepare the dictionary with the specification is
#'name of the entity' : (dataframe, identification)entities = {
"customer" : (olist_customer, 'customer_id'),
"order": (olist_order, 'order_id'),
'item_product':(olist_item_product, 'index')
}
接下来,我们需要指定实体之间的关系。当两个实体存在一对多关系时,我们称“一”实体为“父实体”,“多”实体为“子实体”。父子关系是这样定义的。
#The relationship are defined by the entitiy name and the variable identification
(parent_entity, parent_variable, child_entity, child_variable)#Example
relationships = [
('customer', 'customer_id', 'order', 'customer_id'),
('order', 'order_id', 'item_product', 'order_id')
]
在上面的例子中,我用“customer_id”变量定义了“customer”实体和“order”实体之间的关系,这两个变量存在于两个数据集中。
现在是自动化特征工程的时候了。这很容易做到;你只需要按照下面的线。请注意,这个过程需要一些时间,因为数据集非常大。
import featuretools as ftfeature_matrix_customers, features_defs = ft.dfs(
entities=entities, relationships=relationships,
target_entity="customer")
从上面的代码,我会解释一下。正如我之前解释的,创建自动化的方法是 DFS。在这种情况下,DFS 方法主要接受三个参数。它们是:
- 实体
- 人际关系
- 实体目标
前两个参数是我们之前创建的,最后一个“实体目标”是聚合的分组。在下面的例子中,假设我们想要基于客户级别的特征工程。
流程完成后,我们可以看到,我们最终获得了许多基于客户聚合的新特性。
feature_matrix_customers.columns
正如我们在上面的图片中看到的,由于自动化特征工程,我们现在有 410 个特征。
如果你对如何阅读一些列名感到好奇,我可以解释一下。以 SUM(item_product.price)为例。此列表示它是 item_product 实体的价格与客户聚合级别的总和。所以,用一个更人性化的术语来说,就是顾客所购买的商品的总价。
下一步,当然是用我们刚刚产生的数据开发机器学习模型。虽然我们已经创建了这个功能,但它是否有用还需要更多的实验。重要的是,我们成功地自动化了模型开发的耗时方面。
结论
特征工程是开发机器学习模型的一个重要方面,因为它正在影响我们的机器学习模型。然而,这个过程可能需要很长时间。
在这种情况下,我们可以使用名为 Featuretools 的开源库来自动化我们的功能工程过程。
Featuretools 中我们需要记住的三个术语是实体、深度特征合成、特征基元。
如果你想了解更多关于 Featuretools 的信息,你可以访问主页这里。
希望有帮助!
如果你喜欢我的内容,并想获得更多关于数据或作为数据科学家的日常生活的深入知识,请考虑在这里订阅我的时事通讯。
如果您没有订阅为中等会员,请考虑通过我的推荐订阅。
易于操作的开发环境
像越来越多的工程师一样,数据科学家正在向码头工人 T2 转移。这个框架将资源和应用程序从全球系统中分离出来,有助于更好的可复制性,从而解决了软件安装和部署过程中的一些问题。
虽然它主要用于部署独立的应用程序,但是我们可以通过一种稍微派生的方式来利用这种技术来构建轻量级和可移植的开发环境。
随着越来越多不同的工具和库,有时很难知道我们的工作站中安装了什么,以及如何轻松地管理所有这些东西。每个人都遇到过仅仅为了安装一个特定的 Python 库或 Bash 实用程序而进行几个小时的调试。
如果你想了解更多关于 Docker 技术的细节,在 Medium 这里已经有很多好的资源 。
带码头的移动实验室
当我收到最后一台笔记本电脑时,我没有在全局系统安装上安装任何库或代码实用程序。相反,我将许多日常工作转移到 Docker 容器中。
这种工作流程有很多优点:
- 您可以安装和测试库,而不用担心会破坏您的全局系统。全部隔离在容器中。
- 由于 Dockerfiles(在 Git 中跟踪),您可以跟踪不同的工作区以及它们是如何发展的。
- 您可以在任何计算机上运行您的任何工作区。只需要安装 Docker(这非常简单)。
- 您可以共享工作区。您的任何项目都可以在朋友的电脑上运行。
好的,听起来不错。安装或升级库时,我们将不再害怕。在任何地方运行项目的可能性是非常令人兴奋的,由于 Git,获得所有历史变更将节省时间。
尽管如此,还是有一点缺点:您必须编写很长的命令才能启动这些容器
在 Docker 容器中运行 Jupyter 记事本的 Docker 命令示例。
我们总是想要快捷简单的工具
为了解决这个问题,我首先想到了 docker-compose 。这个工具对于定义和运行多容器 Docker 应用程序非常有用。它可以将复杂的运行操作恢复成简单的docker-compose up
命令。
然而,这不是我们在我们的环境中使用的工具,至少有两个原因:
首先,您必须在包含docker-compose.yml
的文件夹中运行 docker-compose 命令,或者提供相当长的完整 docker 文件路径。这并不像我们习惯的那样,仅仅在你的控制台中输入jupyter-notebook
或者启动 Rstudio 应用程序那么简单。
其次,你得安装 docker-compose。好了,这还不是最难的。但是在安装工作空间时,您仍然需要添加这个层。
所以我问自己,在大多数 Unix 系统上,默认的工具是什么?简单回答:Bash。
行动诞生了。
操作:Docker 环境支持 Bash。
这个工具非常简单。事实上,它只是 docker 容器运行命令到 shell 脚本中简单表达式的映射。
环境——或“操作”——由一个docker 文件和一个配置文件定义。后者用于指定容器运行命令和所有需要的参数,如卷、环境变量等
Jupyter 笔记本操作后面的配置文件。
映射被解释成一个简单的 shell 脚本。我们可以用一个简单的operation briefing
构建所有的 Docker 图像。
然后,不用运行长 Docker 命令来运行 Jupyter 笔记本,只需键入operation jupyter
。
操作被设计得非常简单,它不是一个革命性的工具,只是一个小的附带项目。目标是能够运行单个应用程序或开发工具,而不用担心系统依赖性和安装。
当在一个更复杂的项目中工作时,我更喜欢在项目中建立 docker 文件甚至 docker-compose 文件,而不是在操作中构建它。这对项目的可重复性更好。
由于我主要使用 Python 和 R,我开始构建像 IPython 或浏览器内 Rstudio 环境这样的“操作”。我还利用这个解决方案设置了一些任务,虽然我不是每天都做,但是这些任务非常有用,比如 CSV 文件转换、图像旋转或日期时间操作。
这些小工具可以安装在我的全球系统上。它们不需要太多的依赖。尽管如此,我还是希望能够使用它们而完全不用担心我的系统配置,并且当我换到另一个工作站时能够快速找到它们。
有了手术,我手头就有了。
背后的故事
这个想法并不新鲜。杰西·弗雷泽勒,前 Docker-Google-微软工程师已经有了一个完整的 Docker 文件库来运行独立的桌面应用。我鼓励你去看相应的博文。
读了汤姆·克兰西的书后,我想到了“手术”这个名字。像军事行动一样,Docker 容器被定义、操作,然后分类。为了实现这个想法,我甚至添加了“秘密”行动的别名。例如,您可以启动运行operation ipython
或operation rattlesnake
的 IPython 控制台。
这个锁定也让我学习了一些关于 3D 建模和 Blender 渲染的知识。围绕码头鲸创作了一些艺术品。了解有关具体行为项目的更多信息。
https://www.behance.net/gallery/95156933/Operation
未来的发展
我利用锁定开始这个小项目,并提高我的 Bash 技能。由于我们过去面对许多新的工具和环境,它可能会定期更新。可以进行许多改进,例如:
- 优化图像定义并遵循 Docker 的良好实践。
- 更好的安装过程(apt-获得支持?).
- 潜在的卷“安全性”和授权违规。
- 改进文档。
- 添加操作“优先级”以快速构建特定的 Docker 映像。
- 比 Bash 更好的 CLI,无需使用任何其他工具。
目前每个操作都非常接近我的个人喜好。如果你想添加你自己的操作:添加你的 Dockerfile 并填充一个config.yml
文件,你就准备好了。
你有改进的想法吗?认为应该创造一些新的环境?你可以在 Github 上找到这个库。不要犹豫,添加问题或创建合并请求,在下面添加评论,或在 Twitter 上与我联系。我将很高兴收到你的来信。
红移性能的简单修复
由 Ricardo Gomez Angel 在 Unsplash 拍摄的照片
或者如何将自己从分布式数据库的糟糕查询中解救出来
edshift 很棒,直到它不再是那样。通常,当这种情况发生时,并不是红移的错。使用红移的人面临的最常见的问题之一是查询性能差和查询执行时间长。这可能很难理解,但大多数红移问题是显而易见的,因为人们只是习惯于查询关系数据库。虽然传统的 ACID 兼容关系数据库和 MPP 分布式关系数据库的外观是一样的,但是存储分布的基本原则完全改变了游戏。
与兼容 ACID 的关系数据库(如 MySQL、PostgreSQL 等)相比,红移的两个主要特点改变了一切。
- 底层存储 —列存储而不是基于行的存储
- 大规模并行处理架构——尽管在 MySQL、PostgreSQL 等中也是可能的。这也是红移的默认设置
现在,我们将列出一些快速修复方法和开始使用红移工作负载时需要记住的事项。如果你不了解红移,阅读下面的文档会很有帮助。
[## 影响查询性能的因素
许多因素都会影响查询性能。数据、集群和数据库操作的以下方面…
docs.aws.amazon.com](https://docs.aws.amazon.com/redshift/latest/dg/c-query-performance.html)
记住——红移中没有索引
与关系数据库不同,Redshift 不支持索引。不要编写与 MySQL 或 PostgreSQL 等关系数据库相同的查询。红移旨在当您选择您绝对最肯定需要查询的列时执行最佳——与您应该在基于行的数据库中SELECT
记录的方式相同,您需要在基于列的数据库中选择列。
没有索引?那么,如何有效地连接表呢?
关系数据库中的联接使用索引。正如我们刚刚确定的,红移中没有索引,那么您将使用什么?您将使用一个类似的探测结构来连接表。这种构造被称为分布键——一列数据基于它分布在红移星团的不同节点上。数据的分布方式由为给定表选择的分布样式定义。
[## 分发示例
AWS 文档中描述的 AWS 服务或功能可能因地区而异。要查看适用于…的差异
docs.amazonaws.cn](https://docs.amazonaws.cn/en_us/redshift/latest/dg/c_Distribution_examples.html)
统计的重要性
类似于任何其他数据库,如 MySQL,PostgreSQL 等。,Redshift 的查询规划器也使用关于表的统计信息。基于这些统计信息,当选择许多计划中的一个来执行查询时,查询计划决定采用哪种方法。这就是为什么时不时地去牌桌是个好习惯。没有一个好的频率来运行这个适合所有人。请注意ANALYZE
可能是一项耗时的活动。在决定频率之前,做一个快速的成本效益分析。
有一篇很棒的文章提到了我在这里谈到的一些事情。更多细节请参考。
Amazon Redshift 是一个数据仓库,可以快速、简单且经济高效地分析数 Pb 的数据…
www.intermix.io](https://www.intermix.io/blog/top-14-performance-tuning-techniques-for-amazon-redshift/#use_change_data_capture_cdc)
为您的列选择合适的压缩方式
列数据库的一个优点是可以实现高级别的压缩,因为大量同类数据是连续存储的,这意味着磁盘上的许多块包含相同数据类型的数据。这样不是更容易压缩吗!
对于基于行的数据库,一行中的所有数据都是连续存储的。这就是为什么减少扫描的行数更好。
因此,在基于行的数据库中很难进行压缩,因为一行可能包含不同数据类型的数据,这意味着磁盘上的相邻块可能具有不同的数据类型。
相同颜色的磁盘/内存块是连续的。图片来自维基共享资源(标记为重复使用)
[## 压缩编码
压缩编码指定在添加行时应用于数据值列的压缩类型…
docs.aws.amazon.com](https://docs.aws.amazon.com/redshift/latest/dg/c_Compression_encodings.html)
照顾好磁盘空间
管理磁盘空间通常是所有数据库的一个问题,尤其是当您处理分析负载时,因为分析师、数据工程师会创建大量的表以供进一步分析。即使事实并非如此,减少的可用空间也会严重影响查询性能,因为这会使查询执行引擎难以通过引发大量交换来在磁盘上创建临时内容。
如果您对磁盘空间没有任何控制,那么 Spectrum 中更灵活的选项更好—在这里,您实际上是将所有数据移动到 S3,它可以根据您的需要进行扩展,而不会因为增加磁盘空间而停机。
这些是你应该记住的一些基本的东西。你可以在 AWS 的文档中找到更多关于红移的想法。文档并不总是有用的。那时,你可以参考一些通过这篇文章分享的链接和下面的参考资料部分。
参考
如果你正在寻找红移的深入实用指南,没有什么比 Periscope 的这个更好的了。
这篇文章是一个案例研究,关于我们如何修复一些红移性能问题,我们开始运行,因为我们有更多的…
www.hudl.com](https://www.hudl.com/bits/the-low-hanging-fruit-of-redshift-performance) [## 亚马逊红移|亚马逊网络服务的十大性能调优技术
客户使用 Amazon Redshift 做各种事情,从加速现有的数据库环境,到摄取网络日志…
aws.amazon.com](https://aws.amazon.com/blogs/big-data/top-10-performance-tuning-techniques-for-amazon-redshift/) [## 查询 86.6 亿条记录 Starburst Presto 和…
如果您是应用程序所有者,迟早您会需要分析大量数据。好消息是什么?无论如何…
www.concurrencylabs.com](https://www.concurrencylabs.com/blog/starburst-presto-vs-aws-redshift/) [## 提高查询性能
以下是一些影响查询性能的常见问题,以及诊断和解决这些问题的方法说明…
docs.aws.amazon.com](https://docs.aws.amazon.com/redshift/latest/dg/query-performance-improvement-opportunities.html)
两个视频—
托尼·吉布斯的亚马逊红移最佳实践
通过真实使用案例对红移进行深入的回顾
SparkSQL 性能的简单修复
Emile Perron 在 Unsplash 上拍摄的照片
数据工程
针对 performant SparkSQL & PySpark 的快速简单的修复、最佳实践和检查
S park 是当今最流行的数据分析和工程工具之一。它拥有广泛的覆盖面和采用率,这促使主要的云提供商提供基于它的服务。有 Azure Databricks、AWS Glue 和 Google data proc——所有这些服务都在底层运行 Spark。Spark 受欢迎的原因之一是它同时支持 SQL 和 Python。对于独特的 RDD 特性,第一个 Spark 产品之后是 DataFrames API 和 SparkSQL API。从那以后,它统治了市场。
很多人在第一次尝试 Spark 时,都说 Spark 非常慢。这显然非常慢,因为他们不了解 Spark 的内部以最佳方式(甚至是足够好的方式)使用它。我写这篇文章是为了指出几个针对 SparkSQL 的快速修复方法,您可以在不深入 SparkSQL 内部的情况下使用它们。话虽如此,解决这个问题的最好方法是深入内部。但是在这里,我们将只讨论非性能 SparkSQL 问题的低挂果实。
查询任何传统关系数据库的经验法则
towardsdatascience.com](/easy-fixes-for-sql-queries-ff9d8867a617)
这是我的早期文章之一的延续,在那里我谈到了对任何关系数据库的 SQL 查询的快速和简单的修复。在某种程度上,许多相同的概念也适用于 SparkSQL 尽早过滤数据、正确过滤数据、高效分发数据、减少不对称等等。让我们继续讨论这些常见问题。
1.广播(广播加入)
就像数据库一样,Spark 的数据存储也有小文件和大文件。就像在传统的分布式数据仓库系统中一样,我们将维度表推送到集群的所有节点以避免混乱,我们在这里通过使用 SparkSQL 的广播特性来做同样的事情。Broadcast 做的完全一样——它提前将一个小表的所有数据复制到 worker 节点,以减少执行者之间的混乱。
减少执行人之间的推诿
我们可以指定提示来指示 Spark 在执行一个关系(表/文件)到另一个关系的操作时做什么。虽然这并不普遍,但普遍认为 Spark 工作中的更多阶段会导致更多的执行者之间的洗牌。让我们谈谈那个。
2.减少阶段的数量
我不断回想起 Jim Gray 的这个伟大类比,他谈到了从磁盘读取和从内存读取的延迟之间的巨大差异。在这种情况下,如果可以避免的话,从磁盘获取数据几乎是犯罪行为。
计算机性能有点像骗局。你总是在等待四样东西之一:磁盘 CPU 内存网络…
blog.codinghorror.com](https://blog.codinghorror.com/the-infinite-space-between-words/)
正如我在介绍中提到的,像 Redshift、Snowflake、Spark、Hadoop 等分布式系统。面临这个常见的问题,即在作业运行的网络上共享数据。这个共享数据是从磁盘中获取的。正如 Jim Gray 所展示的那样,磁盘 I/O 的成本非常高。显然,不仅仅是获取数据——这些数据的开销工作(如 serde)使情况变得更糟。
吉姆·格雷的存储延迟类比
减少给定 Spark 作业的阶段数量肯定有助于减轻您面临的一些性能问题。使用丰富的 Spark UI 来确定 Spark 作业的每个阶段有多少数据被打乱。
阅读关于洗牌的 Spark UI 的一个积极的副作用是,你可以了解除了级数之外的问题,比如你的数据的偏斜度。
3.分区修剪
过滤、下推谓词、分区修剪——本质上都是同一构造的实现。查询执行引擎希望您尽可能多地丢弃数据,以降低查询成本。在传统的数据库中,这是通过索引和分区来完成的。
分区是对数据进行分组,以便查询执行引擎查找查询所需的数据。修剪是一种能够拒绝查询不需要的整个分区的技术。您也可以使用查询提示在SELECT
语句中指定分区。
分区的替代方法是分桶。从概念上讲,它试图实现相同的性能优势,但分桶不是为每个分区创建一个目录,而是使用桶值的散列将数据分布到一组预定义的桶中。
4.小心缓存
首先要明白的是,和 Spark 中所有的转换一样,cache()
操作也是懒洋洋求值的。它不像动作那样调用驱动程序的数据移动。cache()
应该只在你确定缓存的 RDD 将被用于进一步的转换时使用。
不要因为 RDD 很小就进行缓存。不要仅仅因为它是维度表就缓存它(而是广播它)。缓存必须从数据血统的角度来看,即转换的 DAG。
理解缓存和广播之间的区别——前者将缓存数据的副本发送/广播到执行者的内存(和/或存储器)中。
请记住,过多的缓存会给 LRU 算法带来开销,因为它会不断驱逐被缓存的内容,并引入新的内容来替换它们。这个循环将会继续。
您可以继续查看 Spark UI 中缓存的数据量(百分比)。观察 UI 一定会让你的人生更早。
结论
这些是识别和修复 SparkSQL 性能问题的一些最快捷、最简单的方法。我会再写一篇关于修复 SparkSQL 查询的具体用例的帖子!
SQL 查询的简单修复
由思想目录在 Unsplash 上拍摄的照片。不是 101 篇文章,但是这里有一些提示和想法将会改变你写 SQL 的方式。他们可能不会改变你的想法。为了改变你的思维方式,你应该多读书,与真实的人交谈,并确定你需要改变你的思维方式。我可以一直唠叨下去。如果你能读一读这篇关于 SQL 的该死的文章,那不是很好吗!我已经花了将近十年的时间学习 SQL,并且仍然很强大。
更好的 SQL
查询任何传统关系数据库的经验法则
SQL 对于任何角色来说都是一个强大的工具。数据驱动着公司的所有决策。数据只使用一种语言,那就是 SQL。写 SQL(或者说,如果你是个书呆子的话)很简单。大多数人都能做到。只有一些人做得很好。这个会超级短超级有用。
不管您使用的是什么关系数据库管理系统或 RDBMS (MySQL、PostgreSQL、SQL Server、Oracle ),一些经验法则都适用于所有这些。以下是在你的数据库上做SELECT
的规则
1.总是使用 WHERE 子句(总是使用索引)
换句话说,只获取您绝对需要的数据——这可以通过使用古老的WHERE
子句来完成。只有在极少数情况下,您会发现不使用索引可以获得更好的性能。不要担心罕见的情况。索引强制数据做二分搜索法(尽管不同数据库的二分搜索法实现不同)。本质上,你将能够在对数时间而不是线性时间内SELECT
你的数据。
只获取你绝对需要的数据
例如,对一个有 10 亿条记录的表进行查询 而不使用 索引,可能需要多达 10 亿次才能得到您想要的记录。然而,使用 索引对您正在搜索的列进行查询 将花费更少的次数,并且将更快地获得结果,因为 10 亿的对数以 2 为底大约是 30(准确地说,是 29.897352854)。这是对搜索过程的过度简化。
感谢纠正日志上以 2 为基数的值不正确 普拉莫诺·温纳塔 。
2.确保使用了索引
当查询引擎无法使用索引时,可能会出现问题。这将导致查询速度缓慢。速度的快慢取决于查询所扫描的数据量。当查询引擎无法理解或映射带有表数据定义的搜索值的字符集(在WHERE
子句或JOIN
中)时,通常会出现问题。在这种情况下,显式类型转换通常会有所帮助。
不使用索引时,使用显式强制转换
来自 MySQL 文档
对于字符串列与数字的比较,MySQL 不能使用列上的索引来快速查找值。避免这类问题的一个方法是使用
[*CAST()*](https://dev.mysql.com/doc/refman/5.5/en/cast-functions.html#function_cast)
。
所有的数据库都非常相似。问题的严重性取决于任何数据库中查询引擎的实现。
3.明智地使用子查询
在许多数据库中,使用子查询会强制将数据复制到磁盘,并且对您的查询数据的计算将发生在磁盘上(数据将被一次又一次地读取和写入磁盘),而不是内存中。如果发生这种情况,如果数据很大,它会成为一个严重的开销。当这种情况发生时,延迟会成为性能杀手。查看由格蕾丝·赫柏上将制作的关于一纳秒意味着什么的惊人视频。延迟通常以纳秒为单位。
当心子查询和磁盘的使用
事实上,明智地使用任何在磁盘上创建(强制创建)临时表的方法—
GROUP BY
和ORDER BY
—是的,这也会导致数据子集被写入磁盘。在所有数据库中,您可以预定义一块内存(RAM)用于写入查询数据。如果您的数据集很大,并且您的查询数据的子集超过了这个限制,那么它肯定会被写入磁盘并从那里进行管理。JOINS
—是的,即使是JOINS
也可以将数据写入磁盘,以便进一步检索。一个JOIN
本质上是一个SEARCH
和MAP
操作。
4.避免排序/分类数据
排序操作成本极高。每个数据库都有自己的排序算法实现。他们可能使用了传统的排序算法,也可能想出了自己的排序算法。在任何情况下,由于这是一个非常耗费资源的操作,而且还涉及到将数据推入磁盘和从磁盘中取出数据,因此应该谨慎地使用排序。
5.不要使用[LIKE](https://mode.com/sql-tutorial/sql-like/)
查询
当您长时间查询数据时,传统的关系数据库会导致争用问题。这正是你做LIKE
查询时发生的事情。它们会影响整个数据库和其他正在运行的查询的性能。除了使用LIKE
,还有其他选择
- 关系数据库的全文功能。现在几乎所有的数据库都支持全文搜索。
- 如果全文搜索不是一个选项,你可以使用像 Elasticsearch,Solr 或 Algolia 这样的全文搜索引擎。它们是为文本分析而设计的。虽然,对于这些新系统,你没有一个像传统数据库那样强大的 SQL 接口。
使用关系数据库的全文功能,或者使用类似 Elasticsearch 的工具进行文本搜索
如果你想成为 SQL 超人
- 了解关系数据库的内部结构——数据库如何使用内存和磁盘
- 了解查询的执行顺序——首先评估查询的哪个子句。是
JOIN
先发生还是WHERE
从句先发生还是GROUP BY
先发生 - 了解查询引擎如何准确解析、估计、优化、重写和执行查询的底层实现细节。
- 了解基于云的关系数据库实现,如 Amazon Aurora、Amazon RDS 和 Azure SQL 数据库等等。
这并不是一份详尽的清单。还有更多关于DISTINCT
和OR
以及EXISTS
和IN
子句的用法,但我选择的这些似乎是最有问题的,也是最容易修复的。这些只是编写和重写查询时应该记住的一些通用规则。
轻松互动剧情——熊猫剧情后端
熊猫系列和数据框架中的一行交互式情节
熊猫提供了一种探索数据的简单方法(EDA)。一个例子是,我们如何在不导入任何可视化模块的情况下,仅从 Pandas 系列或数据框中创建绘图。我在下面的案例中展示给你看。
#I only use seaborn to import sample dataset
import pandas as pd, seaborn as snstips = sns.load_dataset('tips')
tips['tip'].plot(kind = 'hist')
仅仅通过使用.plot
属性,我们就可以默认生成一个 matplotlib 图。不过,在这篇文章中,我要展示的是我们如何用上面类似的线条创建一个交互式的 plotly plot。示例结果如下所示。
如果你想了解更多关于熊猫的 EDA,这里有一篇由 Pararawendy Indarjo 撰写的文章很好地涵盖了你可以用熊猫做什么,但在这篇文章中,我将只专注于创建一个互动的情节。
Plotly
Plotly 是一个模块,可以改善任何可视化,变得更加互动。2020 年 5 月 26 日,Plotly 发布了支持熊猫绘图的 4.8.0 版本。这是一个我个人很兴奋使用的新功能。后端是由 plotly-express 驱动的,这是 plotly 中的另一个包,用于创建快速、交互式的情节。以下是数据分析期间 plotly express 用法的示例。
import plotly.express as px
fig = px.histogram(tips['tip'])
fig.show()
现在,Plotly 4 . 8 . 0 版提供了一个后端来在 Pandas 系列或数据框中使用它,而不是导入 plotly.express。要实现这一点,您需要首先安装 Plotly 模块。
#If you never install Plotly
pip install plotly#If you have install Plotly previously
pip install -U plotly
安装了 Plotly 模块后,我们需要首先使用以下代码设置环境。
pd.options.plotting.backend = "plotly"
这样,我们已经将 pandas plot 后端从默认的 matplotlib 更改为 plotly 模块。让我们尝试我们能创造的各种各样的情节。
- 散点图
tips.plot.scatter(x = 'tip', y='total_bill')
- 箱线图
tips['tip'].plot.box()
- 水平条形图
#The y axis in the Plotly bar plot is the index, that is why I set up another column as the indextips.set_index('sex')['size'].plot.barh()
- 刻面图
tips[['tip', 'smoker']].plot.box(facet_col = 'smoker')
这是通过熊猫 Plotly 后端支持的几个情节。准确的说,目前只有scatter
、line
、area
、bar
、barh
、hist
、box
剧情可用。如果你想了解更多,你可以参考文档这里。
结论
在这篇文章中,我只是展示了如何使用 Plotly 从熊猫系列和数据框创建一个简单的互动情节。这个特性在本文创作时还是全新的,但是我相信在将来,这个功能会实现更多我们可以使用的情节。
如果您喜欢我的内容,并希望获得更多关于数据或数据科学家日常生活的深入知识,请考虑在此订阅我的简讯。
如果您没有订阅为中等会员,请考虑通过我的推荐订阅。
用 Tableau 映射芝加哥的交通事故
让 Tableau 做繁重的工作。
当探索带有地理标记的数据时,地图是发现重要趋势的最有力的工具之一。Tableau 是创建地图的理想选择,因为它只需几次点击就能提供高质量的描述性可视化效果。在这篇博文中,我将通过使用 Tableau 调查过去几年芝加哥的交通事故来展示它的威力。
问题陈述
让我们想象一个假设的场景,芝加哥市已经获得了一项计划的资金,该计划旨在使该市的驾驶条件更加安全。部分预算将用于重新设计事故多发的十字路口和街道。作为参与该项目的数据科学家,您的首要任务是使用城市交通数据来确定哪些区域最需要关注。
数据
芝加哥公共数据门户包含了关于过去几年报道的所有交通事故的地点和细节的综合数据集。对于每个单独的事故,人们可以找到关于张贴的速度限制、受伤人数、照明条件、天气条件等信息。对我们来说最重要的是,每个事故的位置都以经度和纬度的形式报告。
使用 Tableau 查看数据
我们首先需要用 Tableau 读入数据。因为我使用的是 Tableau Public,所以我只是下载了数据并直接连接到 csv 文件。如果您继续操作,在打开一个空白工作表后,您应该会看到下面的屏幕。
包含芝加哥交通事故数据的空白 Tableau 工作表
我们首先简单地分别用经度和纬度填充列和行。因为我们想要每个地点的事故数量,我们可以拿起记录数量药丸,并把它放在带有计数测量的标记下。在这个例子中,我还把我的标记改成了金红色,但是这一步是可选的。现在,我们应该有一张地图了!当鼠标悬停在不同的点上时,我们会得到每个位置发生了多少起车祸的信息。
一张简单的地图,标明某一地点的事故数量
太好了!只需点击几下,我们就可以制作地图,现在我们可以开始调查了!对吗?
错了!
我们刚做的地图有个大问题。如果您一直在查看芝加哥数据门户上的数据,或者使用 Python 等其他工具,您可能会注意到经度和纬度坐标精确到小数点后 9 位。对于我们要完成的任务来说,这实在是太精确了。
交通事故的原始经度和纬度数据
当你放大并将鼠标放在地图上的不同坐标上时,你会注意到有许多地点发生了事故,但 Tableau 只报告了小数点后 2 位的经度和纬度。
在地图上放大,表明太精确的问题
为了解决这个问题,我们需要使用 Tableau 将我们自己的纬度和经度四舍五入到小数点后三位。如果您以前从未这样做过,请右键单击纬度测量,然后转到创建->计算字段。然后,键入以下内容:
创建四舍五入的纬度测量
一定要对经度做同样的事情。现在,我们可以用我们的新度量取代原来的经纬度药丸,并将其转换为维度。现在,当我们将鼠标放在不同的位置上时,我们将开始看到事故数量的汇总。
地图的放大图,显示了更多的事故总数
清理东西
我们现在拥有的地图比我们开始时的地图信息量更大,但它还可以做得更好。首先,它在视觉上不是很吸引人。为了补救这一点,我们可以采取以下措施:
1.)在屏幕顶部的工具栏上,选择地图->背景地图->街道。
2.)在标记下的下拉列表中选择地图选项。你可能也想玩一下大小设置。
更好看的地图
现在,这开始看起来更像一个实际的地图!尽管如此,还是有一些小问题。原来,这个数据集实际上包含了两个被错误标记为经度 0 的点。我们将通过右键单击我们的 round_lon 度量并选择 filter 来过滤掉它们。然后,只需将值设置为最接近芝加哥的经度和纬度值。确切的数字并不重要——它只需要不接近 0。
过滤掉经度异常值
接下来,你可能也注意到了在奥黑尔国际机场有大量的事故。如果你曾经在这个机场的上下车区开过车,这可能不会让你感到惊讶。对我们来说,问题是似乎没有任何关于事故可能发生在这个地区的细节。由于我们主要对城市的主要部分感兴趣,我们将从地图中排除这些点。为此,选择奥黑尔中间的点,然后点击“排除”
排除奥黑尔国际机场不需要的点
既然我们已经处理了异常值,我们就快完成了!让我们回到最初的问题陈述。请记住,我们感兴趣的是车祸发生率高的地区。这意味着我们可能不想让我们的视野被所有只有一两个事故的点所遮蔽。为了更容易地查看我们的地图,我们可以引入一个滑动过滤器,允许我们隐藏事故数量低于给定阈值的任何点。通过右键单击事故数量的标记,我们可以选择“显示过滤器”您现在应该在右侧有一个滑动条,这将允许您将地图限制为仅显示在所提供的范围内具有事故数量的点。
带有事故数量过滤器的最终地图
摘要
暂时就这样吧!总的来说,Tableau 允许我们通过将经度和纬度拖动到列和行中,几乎立即获得地图的工作版本。通过限制经度和纬度测量的精度,我们能够在统计交通事故数量时执行更具描述性的聚合。最后,我们使用 Tableau 的过滤和排除功能来消除异常值,使事情变得更加动态。
带有函数式编程的简易 Matplotlib 图例
使用多轴绘图时简化构建 matplotlib 图例的过程
介绍
Matplotlib 是标准的 Python 绘图库。它几乎可以完成您可能需要的任何事情,并生成出版物质量的图形。然而,它确实有点冗长。一个例子是,当一个图包含多个轴时,构建一个完整图例所需的代码量。
幸运的是,Python 标准库itertools
可用于开发一个简单的函数,收集所有轴上的所有标签,将它们组合成一个图例。
案例示例
我们来举例说明。考虑以下四个不同函数的数据—线性函数、对数函数、指数函数和幂函数。因为我们将每个函数的截距强制为零(或者指数函数和幂函数的截距为 1),所以我们可以很容易地计算出每个函数的斜率,即每个函数的斜率值为 f ( x =1000) = 100。让我们首先导入numpy
和matplotlib
并评估我们的函数:
然后我们可以绘制这些图进行比较:
我们四种不同功能的比较
很简单,对吧?但是,如果我们要线性化每一个函数呢?我们可以通过使用对数轴的各种组合来实现这一点。这意味着我们需要将每个函数绘制在它自己的轴上:
每个轴都有自己的图例
好了,我们已经线性化了每个函数…但是我们现在对每个图都有一个图例,而不是一个单独的图例!解决这个问题的标准方法是将每个对plot()
的调用分配给一个变量,然后在我们调用plt.legend()
时组合这些变量:
手动累积所有控点和标签会产生所需的图例样式
这是可行的——但是,有几个问题。首先,正如我们在介绍中提到的,它非常冗长。随着我们的情节变得越来越复杂,我们必须分配许多临时变量。其次,我们必须按照图例的正确顺序提供这些。第三,我们必须在对图例的调用中写出标签,而不是在相关行的实际情节调用中保留它们。
``chain`功能
那么我们能做什么呢?理想情况下,我们能够以编程方式获得每个轴的序列handles
和labels
,组合它们,并将它们传递给plt.legend()
。matplotlib
确实有获得handles
和labels
的功能!我们可以叫ax.get_legend_handles_labels()
。不幸的是,我们必须为每个轴调用这个函数,这意味着我们仍然需要编写一个for
循环,并将handle
和label
追加到一个列表中。这意味着我们也需要一种自动获取所有轴的方法…否则,我们只是将手动输入每一行替换为手动输入每一个轴!
幸运的是,plt.Figure
类确实包含一个axes
属性,它是轴的序列。但是我们仍然没有解决迭代每个轴的需要。解决方案在于采用函数式编程方法。在命令式编程中,我们编写一个控制结构来循环遍历某个值序列,我们可以使用函数式编程概念来将 映射 一个函数到那个序列。itertools
是这类技术的最佳选择。
itertools
是一个标准的 Python 库,包含了多个有用的函数。我们将使用[chain()](https://docs.python.org/2/library/itertools.html#itertools.chain)
,它将多个Iterable
有效地“组合”成一个Iterable
(例如,像一个链中的链接)。虽然chain()
对任意长度的参数序列进行操作,但是如果我们只有一个Iterable
的Iterable
呢?那样的话,我们还有另外一个功能,chain.from_iterable()
。这里有一个简单的例子来说明这些是如何工作的:
我们需要的另一个函数是zip()
。这个函数接受一个序列Iterable
并返回一个Iterable
的Iterable
,其中第一个Iterable
是每个参数的第一项,第二个是每个参数的第二项,依此类推。没有zip.from_iterable()
,但是我们可以使用*
操作符简单地“拍打”一下Iterable
。让我们也来举例说明一下:
Python 中的列表理解(在实践中)与map
相同,所以我们将使用该语言的习语来编写我们的函数。首先,我们得到句柄和标签,这给了我们[[handle_1, handle_2, ...], [label_1, label_2, ...]]
。
接下来,我们zip()
将轴 1 的句柄与轴 2、轴 3 等的句柄组合起来。,变成自己的Iterable
。对于标签也是如此。我们得到类似于([[handle_1, handle_2, ...], [handle_4, handle_5, ...]], [[label_1, label_2, ...], [label_4, label_5, ...]])
的东西。
最后,我们使用chain()
将所有句柄组合成一个Iterable
,将所有labels
组合成一个Iterable
,并返回一个Tuple[handles, labels]
。然后在作业中解包。
如果在函数调用中传递的是一系列轴,而不是一个数字,我们只需添加一个chain()
来组合fig
参数和剩余的args
参数。
让我们把它编码起来:
我们在类型注释中看到,这个函数可以接受*plt.Figure
或plt.Axes
的序列。最简单的就是通过数字。然而,如果我们想改变图例中手柄的顺序,我们可以手动传递轴。该函数返回一个字典,然后我们可以使用 splat 操作符(**)将它作为关键字参数解包到plt.legend()
。让我们使用我们的新功能:*
和以前一样,但是更容易!
我们做到了!不管我们创建了多少个轴,我们的函数总是会将每一行添加到我们的图例中。更好的是,我们可以通过在绘制线条时是否提供label
参数来轻松控制将哪些线条添加到图例中。这大大简化了多轴复杂地块的构建。当我们绘制每条线时,我们可以控制我们所需要的,不需要手动跟踪额外的变量及其顺序。
使用脸书的 DETR 轻松检测物体
面对宇宙的人。格雷格·拉科齐
用真实世界的例子简要介绍 DETR
在我之前的一篇文章,昆汀中,我和我试图从网上废弃的低质量图像中检测出人。为此,我们使用了 Yolo,一个流行的对象检测工具。我们的目标是从摄像机镜头中发现人。不幸的是,正如你在下面的图片中看到的,由于我们图像的质量,我们会错过很多人。
Yolo 在斯德哥尔摩关键区域从摄像机镜头中检索一帧并自动检测人员后的输出。我们注意到算法漏掉了一些人。
最近,我看到了脸书研究所的一篇有趣的论文。他们公开提供了 DETR ,代表检测转换器,这是一种使用 Pytorch 非常简单的对象检测算法。作为一个 python 迷,Pytorch 里的任何东西都让我开心!🤗
在本文中,我们将快速尝试 DETR 对一些高质量和低质量的图像。
在去 1000 个追随者的路上。 保证你跟着我在 AI 空间学习。我将在我的个人旅程中免费分享我所有的学习**。**
DETR 概况
DETR 可以检测从人员检测到牙刷检测的 91 类。作者提供的 colab 中提供了详尽的列表。然而,在这篇文章中,我们将主要关注人物检测,就像我们之前关于瑞典社交距离的文章一样。
让我们通过一个简单的图像来快速了解 DETR 的力量。我们在 GPU 上遵循以下步骤:
- 实例化 DETR 模型并将其推送到 GPU。
- 定义 DETR 可以检测的类别。
- 加载您的图像并使其正常化。这里要小心,需要是一个形状(800,600)的 RGB 图像。
- 使用 cuda 支持将您的图像推送到 GPU。
- 通过模型转发您的图像,并获得预测:i/预测框,带有检测到的对象在图像中的位置,ii/检测到的 100 个图像中每一个的预测概率。对于后者,我们对于每个检测到的图像,都有对应于每个类别的值的分布。例如,在使用 softwax 函数对其进行归一化之后,我们为每个图像获得大小为(1,N_CLASSES)的向量,其中 N_CLASSES = 91,以及每个类别的概率。输出形状:(100,91)
- 然后我们对前面输出的每一行应用 argmax 来获得类的索引,最大化对象从其中一个类中被提取的概率。请注意,之前使用 Softmax 进行规范化是不必要的,因为我们只对 argmax 感兴趣,即我们的概率向量中关于类的最大概率的索引。输出形状:(100,1)
- 现在我们有了图像中检测到的每个对象的预测类,我们可以在图像上画一个方框来显示该对象及其相关的类。在步骤 5 中,从 DETR 的输出之一中找到这种盒子的坐标。
DETR 的作者提供了一个可乐杯来展示它的易用性。" DETR 使用标准 ImageNet 规范化,并以[𝑥center,𝑦center,𝑤,ℎ]格式输出相对图像坐标中的框,其中[𝑥center,𝑦center]是边界框的预测中心,而ℎ𝑤是其宽度和高度。因为坐标是相对于图像维度的,并且位于[0,1]之间,所以为了可视化的目的,我们将预测转换为绝对图像坐标和[𝑥0,𝑦0,𝑥1,𝑦1]格式
DETR 在良好和低质量图像上的性能
我们修改了 colab 中提供的源代码,让一切都可以在 GPU 上工作。你可以看看我们的可乐布并玩玩它。在本节中,我们首先分析 DETR 在高质量图像上的输出。
原始图像与几个学生和一名教师写作。
应用步骤 1 到 7,我们可以用 DETR 检测图像中的物体。
检测原始图像中所有 100 个对象时的 DETR 输出。在矩形框的顶部,我们有被检测物体的概率。这个值越接近 1,我们的模型对它的预测就越有信心。
现在,人们可以根据目标过滤掉对象。我们的目标是主要关注人物检测。因此,除了前面列出的步骤 1 到 7 之外,我们只需要绘制与标签“person”相对应的方框。
DETR 只在原始图像中检测人物时输出。在矩形框的顶部,我们有被检测物体的概率。这个值越接近 1,我们的模型对它的预测就越有信心。我们注意到这个模型对它的预测非常有信心。
*现在让我们看看 DETR 是如何在摄像机镜头中表现的,这通常对应于低质量的图像。我们决定用两个来自瑞典哥德堡的摄像机镜头的例子来玩。我们从一个例子开始,我可以检测到大约 17 个人。**你自己察觉到有多少人?*🤗
瑞典哥德堡的摄像机镜头。我们可以在这个图像中检测到大约 17 个人。
我们可以手动检测这类人,如下图所示。然而,在实践中,这将需要大量的时间和努力。因此,像 DETR 这样的工具对于自动人体检测是有用的。
瑞典哥德堡摄像机镜头的人工检测。我们可以在这个图像中检测到大约 17 个人。
现在,我们想知道我们的模型以足够的信心预测了多少人。可以将这个置信水平作为超参数进行调整(参见我们的 colab 中函数 detect 中的参数 confidence_level )。下面,我们展示了 DETR 的两个输出,第一个对应于设置为 70%的置信度。
我们在哥德堡拍摄的第一个镜头中 DETR 的输出。它检测到 12 个人的置信度高于 0.70。
第二输出对应于设置为 10%的较低置信水平。在这种情况下,模型实际上不确定预测,因为它预测对象类的概率至少为 0.10。
我们在哥德堡拍摄的第一个镜头中 DETR 的输出。它检测到了 36 个置信度高于 0.10 的人。
我们可以注意到,置信水平,或者对于给定对象检测到某个类别的概率,是一个关键的超参数。事实上,一些错过的人被 DETR 正确地检测到,但是概率低于 0.70。让我们试着看看当我们将置信度设置为 0.60 而不是第一个实验中的 0.70 时的输出。
我们在哥德堡拍摄的第一个镜头中 DETR 的输出。它检测到了 18 个置信度高于 0.60 的人。
我们仍然可以看到,我们的模型预测中存在一些不匹配。让我们用高于 0.70 的置信水平圈出模型没有检测到的对象(人),并用红叉标出假阳性。
我们在哥德堡拍摄的第一个镜头中 DETR 的输出。它检测到 12 个人的置信度高于 0.70。我们手动圈出遗漏的人,红叉出误报。
约罗和 DETR 的简单比较
正如引言中提到的,在之前的文章中,我们与 Yolo 合作,以便在从摄像机镜头中检索的帧中检测人类。正如我们看到的,在人体检测并不困难的帧中,有几个人被遗漏了。因此,现在有必要快速了解一下约罗与 DETR 相比如何。我们决定这样做是基于从摄像机镜头中随机截取的两个画面。
这一次,我们将使用 Yolo 的 Pytorch 实现。我们复制了在他们的实现中提出的对象检测,在这种情况下,我们进行一般的对象检测,而不过滤‘person’类。
对于 DETR,我们遵循之前在DETR 概述一节中列出的步骤 1-7。
首先,我们从在瑞典斯德哥尔摩拍摄的摄像机镜头中检索帧。下面我们可以看到一个低质量的图像,即使对一个人来说,也很难正确地检测到人。
原始帧 1。来自斯德哥尔摩的一段录像。
我们从使用 Yolo 检测任何物体开始。令人惊讶的是,该算法没有检测到任何人。由于源代码不够清晰,我保持检测原样。如果您在建议的代码中发现任何明显的问题,请告诉我!🤗
框架 1。在斯德哥尔摩用 Yolo 进行物体探测的镜头。
现在,让我们使用 DETR 进行‘人体检测’。这一次,非常容易,人们可以立即看到如下所示的结果,最低置信度设置为 0.70。
框架 1。在斯德哥尔摩用 Yolo 进行人体探测的镜头。
我们用如下所示的另一个框架来重现相同的实验。
原始帧 2。来自斯德哥尔摩的一段录像。
这次 Yolo 检测到一个人的概率是 0.32。我们并不确切知道为什么在这样的帧中没有检测到额外的物体。我们还可以注意到,检测到的人是不匹配的。基于此,应该使用具有不同权重参数的不同架构。在以后的文章中,我们可能会考虑此类任务的其他参数。
框架 2。在斯德哥尔摩用 Yolo 进行物体探测的镜头。
另一方面,如下图所示,DETR 在人体检测任务中表现出色。
框架 2。在斯德哥尔摩用 Yolo 进行物体探测的镜头。
显然,这样的实验不够严谨。人们应该建立一个更大的标记图像数据集,并在其上比较这两种架构。脸书的研究人员做了更彻底的分析。下面,我们报告他们论文中的一个比较表,其中我们可以看到 DETR 与更快的 R-CNN、ResNet-50 和 ResNet-101 的性能比较。
论文第 4 节中的表 1:“使用变压器的端到端对象检测”。
结论
在本文中,我们快速介绍了 DETR,这是一种非常容易使用的人体检测算法。然后,我们看到了它在好的和低质量的图像上的整体表现。最后,我们比较了 DETR 和一个叫做 Yolo 的流行算法。
总的来说,这篇文章只是对 DETR 的一个粗浅的介绍。关于算法的更多信息可以通过阅读研究论文和访问 github repo 找到。看看最初的 colab 和我们为这篇文章改编的 one 。
数据流中的简单异常检测
一种在数据流中寻找异常值的简单方法及其 Python 实现
在我的上一篇文章中,我已经解释了流算法的概念,并给出了许多如何应用它们的例子。其中之一是计算数据流的滚动平均值,而不保存数据流中的元素。现在,我想扩展这个例子,并向您展示在异常值检测环境中的另一个流算法用例。
当我们监控机器的功耗以检测任何异常行为时,就会出现这样的问题。如果我们看到异常值增加(不寻常的观察),这可能是这台机器的一个默认指标,可能值得检查。
定义和示例
离群值可以用多种方式定义。在本文中,我们将使用以下定义:
如果一个数字数据流中的一个元素不在目前所见元素平均值的 3 个标准偏差之内,则该元素被视为异常值。
这需要举一个小例子。让我们假设我们按这个顺序得到数据 3,2,4,3,5,3,2,10,2,3,1。让我们进一步假设我们从零的均值和方差(以及标准偏差)开始,即如果不等于零,第一个元素将总是被视为异常值。
所以, 3 被认为是离群值,因为 3 > 0+30。*现在我们根据目前看到的元素更新均值和方差,只有数字 3。因此新均值为 3,方差为 0 。
然后我们看到一个 2。我们有 2 > 3+30,所以 2 也被认为是异常值。这是有道理的,因为到目前为止我们只看到了一个 3,所以任何其他数字都不符合该模式。平均值更新为(3+2)/2 = 2.5**,方差更新为*((3–2.5)+(2–2.5))/2 = 0.25*,这意味着标准差为 0.5 。*
现在我们看到一个 4。由于 2.5–3 * 0.5≤4≤2.5+3 * 0.5,因此该数字不是异常值(即正常值*)。平均值更新为(3+2+4)/3=3 ,方差更新为((3–3)+(2–3)+(4–3))/3 = 2/3**,,因此标准偏差约为 0.81** 。*
以下数字 3、5、3 和 2 被认为是正常的。凭直觉,我们会认为下面的数字 10 又是一个异常值。让我们看看算法是做什么的。此时的平均值约为 3.1,标准偏差约为 1。因为 10 > 3.1+31* ,10 被认为是一个异常值,正如我们所希望的。**
如果你继续最后 3 个元素,你会看到它们都是正常的。
***问题:*要计算均值和标准差,我们得把目前看到的所有元素都背下来。如果我们有一个每天输出成千上万个元素的系统,这不是一个选项。
拯救流媒体算法
解决这个问题的一种方法是使用流算法,该算法在数据流的每个扫描元素之后更新其内部状态。内部状态由迄今为止在任何点看到的所有元素的均值和方差组成,在看到任何元素之前,从均值和方差为零开始。准确的说,让 mₙ 为均值 vₙ 为看到数据流的第 n 个元素后的方差,附加定义 m₀=v₀=0 。
计算平均值
在我关于流算法的文章中,我们已经看到了如何仅使用旧的平均值、正在扫描的最新元素以及迄今为止看到的元素数量来更新平均值。这意味着我们在任何时候都只需要用这种方法存储两个数字,而不是像简单方法那样存储 n 个。让我再展示一次,将数据流的第 i 个输入元素表示为 aᵢ:
这个公式不难开发,对吗?有了它,我们就有了预期元素大小的基线。现在,我们只需要标准偏差,我们可以将平均值分为异常值和正常数据点。我们通过计算方差,然后求它的平方根来得到标准差。
计算方差
在这种情况下,我们也可以毫不费力地找到一个递归公式。首先,看到 n 个元素后的方差如下所示
*让我们试着用 n 、 *vₙ、和最新的元素再写一遍。因为方差取决于平均值,我们也想包括 mₙ.在我们开始之前,让我们重新安排一下这个公式,让事情变得简单一些:
现在,我们的目标是把 vₙ放进去。一种方法是从下面的简单重排开始,分离平方和,直到索引 n ,它也作为术语出现在 vₙ 中:
这相当于
这反过来导致
现在,我们有了公式,让我们看看它在 Python 中是如何工作的!
用 Python 实现
我们可以通过以下方式实现上述解释:
*class StreamingMeanAndVariance:
def __init__(self):
self.mean = 0
self.variance = 0
self.n_elements = 0
def update(self, element):
self.variance = ((self.variance + self.mean ** 2) * self.n_elements + element ** 2) / (self.n_elements + 1)
self.mean = ((self.mean * self.n_elements) + element) / (self.n_elements + 1)
self.variance = self.variance - self.mean ** 2
self.n_elements += 1*
*注意:update
方法的第一行计算方差,但是**没有减去当前的均方值。*第二行,计算当前平均值。在第三行中,从方差中减去它,因为它在第一行中仍然缺失。
为了使用它,我们做到了
*import numpy as np
m = StreamingMeanAndVariance()
n = 10000
for i, s in enumerate(np.random.randn(n)):
if not - 3 <= (s - m.mean) / np.sqrt(m.variance) <= 3:
print(i, s)
m.update(s)*
这将扫描数据流,该数据流在本例中由 10000 个正态分布的数字组成(我们将其表示为 N (0,1) ),并在异常值出现时打印出来。
如果您将正常点的间隔与平均值(黄色)一起绘制,您将得到下图:
用蓝色,你可以看到测量结果。绿色区域包含正常点,其外的测量值(以红色表示)被视为异常值。在黄色部分,您可以看到期望值(平均值)。
讨论
算法做了我们期待的事情!然而,到目前为止,我们没有看到它是如何处理分布的变化的,而只是在任何时候都是标准的正态分布的数字。
让我们测试算法在执行以下操作时的表现:
- 经过 10%的观察,我们将分布从 N (0,1)转移到 N (2,1)
- 在另一个 40%之后,我们将分布从 N (2,1)转移到 N (-2,1)
结果看起来像这样:
一切都在慢慢适应新数据。
好人
这看起来很有希望!一切都会自动适应新数据。当数据的均值从 0 转移到 2 时,我们可以看到许多异常值,这是有意义的。新平均值 2 的观测值越多,检测到的异常值就越少,因为大约 2 是新的常态。
当将平均值从 2 改为-2 时,我们可以看到更多的异常值,因为变化要严重得多。到目前为止,一切顺利。
坏事
如果你看图的右半部分,你可以看到对新数据的适应相当缓慢。一段时间后,平均值和标准差将再次达到正确水平,正如您所看到的,因为黄线(平均值)下降,绿色区域也再次变窄。但是直到它变平,没有异常值被检测到。
为了解决这个问题,我们只能使用最后的 k 个样本来计算平均值和标准偏差,因为这打破了第一次测量的影响。如果我们将 k 设为无穷大,我们就可以得到之前的算法。
我们设定的 k 越低,算法适应新数据的速度就越快。然而,将 k 设置得过小可能会导致丢弃异常值,因为算法认为新数据就像这个*。在设置 *k=1 的极端情况下,没有元素被认为是异常值,因为只考虑最新的元素。
根据不同的使用情况,也许几百或几千应该没问题。
结论
在本文中,我们看到了如何为数据流构建一个非常简单的异常检测机制。我们的算法不需要存储所有的测量值,这使得它非常容易应用,也可以在极其有限的硬件上应用,并且只需要恒定的存储。该算法甚至可以适应数据的变化,因此无需手动更新。
唯一需要调整的是适应率,我们在本文中没有涉及到,但这是一件容易的事情。
我希望你今天学到了新的、有趣的、有用的东西。感谢阅读!
作为最后一点,如果你
- 想支持我多写点机器学习和
- 无论如何都计划获得一个中等订阅,
为什么不做 通过这个环节 ?这将对我帮助很大!😊
说白了,给你的价格不变,但大约一半的订阅费直接归我。
非常感谢,如果你考虑支持我的话!
如有问题,在LinkedIn上写我!
使用 Algorithmia 轻松实现关键字提取算法的生产部署
基于 Algorithmia 的关键词抽取 NLP 模型的无服务器生产部署
图片来自 Pixabay 并由艺术 Chrome 插件风格化
最近,我发布了我的副业项目 AiArtist ,这是一个 chrome 扩展,可以自动为任何给定的故事或文章建议无版权的图片。构建广告的一个关键部分是从任何文本中提取关键字并将其部署到产品中。
今天我们将看到我如何使用 Python 关键短语提取库,Spacy 来开发一个关键词提取算法,并使用 Algorithmia 以无服务器方式将其部署到生产中。
自动建议图像
这篇文章的主要图片是由 AiArtist 通过给出文章的标题自动建议的。
让我们开始吧:
投入
算法的输入将是一些我们从中提取关键字的文本。例如:
Ahead of its mid-2020 world premiere, the first set of images of the updated Fortuner has surfaced online. While the Fortuner facelift's India launch is still some time away, these images give us a clear idea of what to expect from the mid-cycle update of Toyota's popular SUV.With this update, the Toyota Fortuner gets cosmetic restyling at the front, with a bumper and grille design that's now in line with newer Toyota SUVs like the RAV4 and Raize. The grille is a lot slimmer and has glossy black bits instead of the chrome trim, and the bumper is more pronounced with triangle-shaped faux air intakes on each corner. Also, the headlight shape seems to be mildly altered with new inserts that make the refreshed Fortuner look sharper than the pre-facelift version. The gloss-black finish on the skid plate completes the visual update for the SUV. The Fortuner facelift is also expected to get styling tweaks to the rear, including a mildly restyled bumper and tail-lamp inserts. There is no news on the interior upgrades for the updated Fortuner but it is safe to expect a better infotainment system and some minor changes. As far as engines go, Toyota sells the Fortuner with multiple petrol and diesel options globally, and the list includes 2.7 and 4.0-litre petrol engines, and diesel engines with 2.4, 2.8- and 3.0-litre displacements, depending on the market.
输出
输出将是文章中的关键字列表:
[ "fortuner", "bumper", "toyota", "update", "grille design", "toyota suvs" ]
在 Algorithmia 上部署
登录 Algorithmia 并点击仪表板中的创建新算法>算法。输入一个算法名,例如:关键字提取,保留所有默认设置,点击创建新算法。
Algorithmia 仪表板
一旦创建了算法,点击源代码选项卡。您将被带到如下所示的 IDE
源代码集成开发环境
在自动创建的关键字 Extraction.py 中输入下面的代码。
单击依赖项选项卡,输入以下内容,然后单击保存依赖项—
algorithmia>=1.0.0,<2.0
six
git+git://github.com/boudinfl/pke.git
spacy==2.2.4
nltk==3.3
thinc==7.4.0
[https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-2.2.5/en_core_web_sm-2.2.5.tar.gz](https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-2.2.5/en_core_web_sm-2.2.5.tar.gz)
在 IDE 的主控制台中点击保存,并点击构建。你会看到算法版本 XXXXX 现在在线。现在输入任何示例文本,例如:“老虎杀死了鹿”,并查看关键字 [“老虎”、“鹿”] 的输出
现在你的算法可以工作了,可以发布了。点击发布。
在发布工作流程中输入所有细节,如输入/输出,然后最后点击发布版本 x.x.x 。
现在你的算法已经可以使用了。您可以在双引号之间输入任何文本,并点击运行示例查看输出。
你可以使用任何编程语言并通过 API 调用算法,如安装和使用部分所示-
您已经正式将一种高效的关键字提取算法以无服务器的方式部署到生产环境中。恭喜你!
注意事项:
- 我只从文章中提取名词关键词。您可以相应地更改代码来提取其他词类关键字。
- PKE 图书馆使用 spacy.load('en ')在内部加载 spacy 英语模型。但是 Algorithmia 并不像他们博客中提到的那样支持它。
如果您使用的库依赖于在en_core_web_md
和en
之间创建符号链接的空间,请找到一个替代库,因为我们不支持手动创建该符号链接
但是我们通过在 Spacy 代码中动态链接" en_core_web_sm “到” en "巧妙地解决了这个问题。
# Link spacy code
import spacy
model_name = "en_core_web_sm"
from spacy.cli import link
from spacy.util import get_package_path
package_path = get_package_path(model_name)
# print (package_path)
link(model_name, "en", force=True, model_path=package_path)
使用自然语言处理的问题生成——教程
我推出了一个非常有趣的 Udemy 课程,名为“使用 NLP 生成问题”,扩展了这篇博文中讨论的一些技术。如果你想看一看,这里是链接。
使用 Python 实现简单的语音到文本转换
语音转文本
亚历山大·佩莱斯在 Unsplash 上拍摄的照片
语音是最常见的交流方式,世界上大多数人依靠语音相互交流。语音识别系统基本上将口头语言翻译成文本。有各种语音识别系统的实际例子。例如,苹果 SIRI 可以识别语音并将其截断为文本。
语音识别是如何工作的?
语音识别过程
隐马尔可夫模型(HMM),深度神经网络模型用于将音频转换成文本。完整详细的过程超出了本博客的范围。在这篇博客中,我演示了如何使用 Python 将语音转换成文本。这可以借助“ 语音识别” API 和“ PyAudio ”库来完成。
语音识别 API 支持几个 API,在这篇博客中我使用了谷歌语音识别 API。更多详情,请查看本。它有助于将语音转换成文本。
Python 库
将音频文件转换成文本
步骤:
- 导入语音识别库
- 初始化识别器类以识别语音。我们正在使用谷歌语音识别。
- 语音识别支持的音频文件: wav,AIFF,AIFF-C,FLAC 。我在这个例子中使用了’ wav’ 文件
- 我用过“拍摄”的电影音频剪辑,上面写着*“我不知道你是谁,我不知道你想要什么,如果你想要赎金,我可以告诉你我没有钱”*
- 默认情况下,谷歌识别器读取英语。它支持不同的语言,更多细节请查看这个文档。
密码
输出
如何转换不同的音频语言?
例如,如果我们想读取一个法语语言的音频文件,那么需要在 recogonize_google 中添加语言选项。其余代码保持不变。请参考更多关于文档
输出
麦克风语音转换成文本
步骤:
- 我们需要安装 PyAudio 库,用于通过麦克风和扬声器接收音频输入和输出。基本上,它有助于让我们的声音通过麦克风。
2.代替音频文件源,我们必须使用麦克风类。其余步骤相同。
密码
我只是说“你好吗?”
输出
用不同的语言交谈怎么样?
同样,我们需要在 recognize_google()中添加所需的语言选项。我说的是泰米尔语,印度语,并在语言选项中添加“ta-IN”。
我只是用泰米尔语说“你好吗”,它就会准确地用泰米尔语打印文本。
输出
注意:
谷歌语音识别 API 是一种将语音转换为文本的简单方法,但它需要互联网连接才能运行。
在这篇博客中,我们看到了如何使用 Google 语音识别 API 将语音转换成文本。这对 NLP 项目非常有帮助,尤其是处理音频文本数据。如果你有什么要补充的,欢迎随时留言评论!
感谢阅读。请继续学习,并关注更多内容!
你也可以在 KDnuggets 上阅读这篇文章。
可视化 3D 地下钻孔数据的简单技术
实践教程
绘制分散在 3D 坐标系中的连续和分类地理空间数据,使用 Matlab 应用于挖掘数据集
加拿大马拉其露天煤矿(作者摄影)
地下钻孔数据是通过钻探和提取岩石或土壤岩心收集的,由分散在三维空间中的样本组成,这些样本测量不同的连续变量或分类变量。每个样本记录:(1)由东、北和高程表示的 3D 空间坐标,(2)连续变量,例如元素浓度、污染物、矿石品位或温度等,以及(3)分类变量,例如岩性、蚀变或矿化单位。
左上图显示了钻孔样本在 3D 散点图中的位置,左下图放大显示了单个钻孔内的样本,右边的图像是显示物理岩石样本外观的带方框的岩心记录(作者拍摄的照片)
钻孔数据或类似的 3D 地理空间数据集用于地球科学和自然资源行业,以获得对地下的了解,用于各种不同的应用,例如采矿中的矿体建模、石油和天然气中的储层测绘、水文地质学中的污染物跟踪以及用于建筑或地质灾害目的的岩石或土壤稳定性描绘。除了传播和分析目的之外,可视化 3D 地理空间信息通常也是任何后续地质建模、工作流或探索性数据分析的第一步。
尽管可视化钻孔数据很重要,但一些地球科学家经常依赖昂贵的软件来绘制他们的 3D 数据,因为大多数从事岩石和土壤工作的人通常缺乏丰富的编程经验。绘制 3D 钻孔数据实际上非常容易,可以用任何编程语言完成,如 Python(使用 numpy 和 matplotlib)、R、Octave 或 Matlab。以下是一个用 Matlab 编写的简单教程,用于可视化应用于一个主要铜矿床的真实采矿数据集的钻孔数据。
挖掘数据集采用以下格式。
正在使用的挖掘数据集的标题行和前五行数据
虽然本教程是在采矿环境中介绍的,但可视化技能也适用于石油和岩土工程行业以及建筑、地质灾害和水文地质等领域中使用的相同类型的 3D 地理空间数据集。
首先,我们导入将在演示中使用的挖掘数据集和所有相关变量。数据集包含 16,258 个样本,分布在东距约 3 km、北距约 2 km、海拔约 1 km 的矩形区域内,每个样本测量连续的地球化学元素浓度以及分类地质蚀变单元。
data = importdata('Dataset.txt');%Spatial coordinates
x = data(:,1); %Easting coordinates in km
y = data(:,2); %Northing coordinates in km
z = data(:,3); %Elevation coordinates in km%Continuous variables
Cu = data(:,4); %Copper grade in ppm
Mg = data(:,5); %Magnesium grade in wt%
Al = data(:,6); %Aluminum grade in wt%%Categorical variable
Alte = data(:,7); %Geological alteration unit
在绘制任何变量之前,使用scatter3
功能,地理坐标将用于显示所有样本的位置。轴的比例应始终相等,除非夸大高程可能会暴露由于数据在其他两个主要方向上的空间范围而遗漏的要素。在 Matlab 中使用axis equal
命令可以很容易地缩放轴。以下示例比较了三维散点图与未缩放轴和缩放轴。
使用地理坐标显示的样本位置,左侧未按比例绘制,右侧按比例绘制
现在我们已经正确地缩放了轴,我们可以使用颜色来绘制变量,以表示它们在空间中的值。我们还可以使用对数色条或不同的颜色来更好地可视化某些变量或变量比率。下面展示了几个使用不同色条和色标的例子。
左侧为铜品位的 3D 散点图,带有线性色标,右侧为铝/镁比率的 3D 散点图,带有对数色标,均显示了整个体积内绘制变量的空间分布
还可以通过改变标绘点的大小或形状来引入额外的维度,这可以作为空间数据的多维探索性分析的额外工具。在下面的示例中,点的大小设置为等于铝镁比(Al/Mg ),颜色用于显示铜的品位。
多维散点图,使用位置在 3D 空间定位样品,使用大小显示铝/镁比率,使用颜色表示铜品位
多维图强调了在 Al/Mg 的中间值时如何发现更高等级的铜,因为更大和更小的点通常具有更小的铜浓度。
使用地质区块模型更好地可视化不同数量的分类数据
我们希望将采矿数据集中的四个不同分类变量可视化,这些变量由以下地质蚀变单元组成:绿泥石-绢云母、石英-绢云母、钾质和泥质。绘制此分类数据的一种方法是创建一个 3D 散点图,并根据其分类值为每个点着色,就像我们对连续变量所做的那样,如下例所示。
散点图显示了样品位置和四个地质蚀变单元:绿泥石-绢云母(Chl-Ser)、石英-绢云母(Qtz-Ser)、钾质和泥质
当处理分类数据时,当将分类单元或域可视化为块模型中的体积而不是分散在 3D 空间中的点时,我们获得了更多可操作的信息。通过以下方式生成块模型:( 1)创建贯穿整个体积的规则间隔点的网格,以及(2)基于来自数据的最近相邻样本的类别为每个点分配类别。对于更具代表性的块模型,应过滤这些点,以仅包括来自实际数据样本的设定搜索半径内的点。
这很容易编程和可视化,因为在大多数编程语言中有几个最近邻库可用,下面显示了一个在 Matlab 中编码的例子。
%Step size and radius inputs
SS = 0.01; % Step size in km
r = 0.01; % Search radius in kmxp=0:SS:max(x); yp=0:SS:max(y); zp=0:SS:max(z);
[X,Y,Z] = meshgrid(xp,yp,zp); % Create grid of points
Xp = X(:); Yp = Y(:); Zp = Z(:);Data_xyz = [x y z]; % Spatial coordinates in matrix
Block_xyz = [Xp Yp Zp]; % Block model coordinates in matrix[Idx D] = knnsearch(Data_xyz,Block_xyz); % Nearest neighbor search
Block_xyz(:,4) = alte(Idx); % Assign block values an alteration unit to nearest sampleBlock_xyz = Block_xyz.*(D<=r); %Filter to search radius %visualize Block_xyz with scatter3
应该使用足够小的步长来填充体积,同时保持合理的总点数,以便于处理和可视化。适当的步长将取决于所考虑的总体积,较大体积的步长成比例地较大,较小体积的步长较短。
对于正在使用的挖掘数据集,步长设置为 10 米,因此在所有三个方向上每 10 米有一个点。应测试不同的搜索半径,以确定哪一个能充分显示体积。根据以下示例,66 米到 100 米之间的搜索半径对于该数据集来说就足够了。
具有不同搜索半径的地质区块模型,显示了四个蚀变单元的空间分布
最后,可以在总体积内分别绘制每个区域的块段模型,以便更好地显示每个区域的空间分布,如下例所示。
使用 75 米搜索半径的蚀变单元的最终地质区块模型。组合块段模型显示在每个单独绘制的蚀变单元上方,突出显示每个单元在总体积内的空间分布位置和方式
块段模型使总结每个地质蚀变单元的位置变得更加容易:
- 绿泥石-绢云母单元自西向东由高到低逐渐倾斜
- 石英-绢云母单元更密集地聚集在该体积的东侧
- 含钾单位集中在该体积的西北角的顶部
- 在高海拔地区,粘土单位分布在东西和南北两个方向
结论
可视化钻孔数据在地球科学和自然资源行业中至关重要,许多地球科学家目前依赖昂贵的商业软件包来实现。使用任何标准编程语言绘制 3D 地理空间数据实际上都非常简单,本文展示了一些在 3D 空间环境中可视化连续、分类和多维变量的技术。
尽管此处介绍的教程使用了采矿数据集,但 3D 可视化技术也可应用于各种其他应用,例如绘制地下水污染物、土壤强度参数、岩石强度和稳定性、石油和天然气体积以及地下地热温度等。
作者说明
我希望这篇教程对所有读者都有用,尤其是对从事地球科学或自然资源行业的目标读者。我想鼓励所有在工业界和学术界使用地下钻孔数据或类似的 3D 地理空间数据集的人尝试编写自己的可视化脚本,而不是仅仅依赖商业软件。
随着我从学术界进入工业界,我目前正在寻找与自然资源或环境相关的地理空间数据分析项目。如果你想在这个领域合作或建立新的联系,请随时通过电子邮件或 LinkedIn 联系我!
在您的服务器上实现 Python 模型训练自动化的简单工具
我用来自动化我的 API 的工具
(src = http://python.org)
eb 自动化是未来的概念,但是非常复杂和难以设置。自动化解决方案通常涉及许多相互依赖的移动部件,并且容易发生故障。通常,这一过程包括三个步骤:
生成数据
自动化再培训
部署 API
这些步骤在理论上听起来很简单,但在实践中会创建一个相互依赖的文件和应用程序的复杂网络。通常,在这些情况下,正确的工具非常需要用于正确的工作,但是了解您的选项以及您可用的工具是战斗的一个重要部分。从获取数据到部署 API,这个难题的每一部分都需要紧密集成,从获取数据开始。
生成数据
(src = "http://python.org ")
“生成”可能是一个错误的术语,但创建可用于培训的数据是一项巨大的挑战。目前最好的工具是 Python。运行 Python 脚本来填充数据库当然是可行的,而且这可以用 RDS 很容易地完成。不过,在常规的 Linux VPS 端,我建议将 Python 与 CronJob 结合使用。
(src = "http://cronjob.com ")
CronJob 将在接下来的步骤中多次出现,这是有充分理由的。CronJob 允许您调度任务在分配的时间运行,这对于服务器自动化特别有用。这是通过使用由分钟、小时、月、星期几等组成的循环“Cron”时间戳来完成的。根据您的使用情况,CronJobs 也可以在更短或更长的时间范围内进行调度。如果有一个有价值的工具我会考虑在 Linux 领域内学习,CronJob 很可能是其中之一。在 Unix 系统上,您可以使用 CronJob 做很多不同的事情,了解如何使用 CronJob 无疑可以为您的服务器管理和部署增加很多功能。
通常,Python 和 CronJob 的协同工作足以让您的工作正常运行,并让 SQL 数据库或本地存储的数据文件不断填充新数据。通常,这些数据将使用 Python 从 API 中提取出来,并被推送到 JSON 或 CSV 格式,或者更理想的是推送到 SQL 数据库。
自动化再培训
自动化再培训是 CronJob 真正展示其能力的地方。虽然你当然可以在烧瓶路线上进行训练——但这肯定不理想。首先,关于路线的训练将会增加 CPU 和 RAM 的使用量,使得系统对于大量的请求非常不可用,并且会拒绝其中的许多请求。此外,根据您的模型,可能需要 10 分钟以上的训练时间,这对于 GET 请求来说一点也不理想。
所以通常情况下,解决方案是使用 CronJob 或 AWS Lambda 解决方案。在这两者中,克朗乔布最有可能
- 更便宜,
- 更具可扩展性
- 更多便利
- 更简单。
每当我部署一个 API 时,可伸缩性总是我最关心的问题。考虑到这一点,很难证明随着使用而增加费用的解决方案是合理的。在 VPS 上运行 CronJob 肯定是一个很好的方法,因为 AWS Lambda 的所有问题都可以完全避免,同时增加很少的问题。因此,通常情况下,CronJob 和您选择的语言的组合也是您的致命武器。
部署
在列出的所有步骤中,部署无疑是最简单的,但也是最复杂的。部署还涉及到更多的步骤,需要前面讨论的所有内容完全一致。不幸的是,这可能相当伤脑筋,因为一次中断可能会使您的整个系统变得无关紧要。
首先你需要一个网络服务器,我总是使用 Nginx。通常,另一个选择是 Apache,但是我选择 Nginx 有几个主要原因:
- 开放源码
- 背后是 10 年的发展
- 出色的表现
- 简单的配置
通常情况下,在 Nginx web 服务器上进行部署会涉及到编辑/etc/nginx/conf.d 中的文本文件,如果您想了解更多相关信息,我已经编写了完整的教程,您可以在这里找到:
应用程序部署通常会带来意想不到的后果和错误。部署可以是制定或…
towardsdatascience.com](/deploying-flask-with-gunicorn-3-9eaacd0f6eea)
本文还涵盖了 Supervisor,这将是部署难题的下一个重要部分。Supervisor 允许专用工作组内部的人工用户在后台运行命令。主管将持有运行我们网络服务器的命令,可以是 Django、Genie 或 Flask。Supervisor 配置也相对简单,在/etc/supervisor/conf.d 中有一个非常相似的配置文件,很容易编辑和访问。
Flask 是一个很好的部署选项,它既轻便又简单,非常适合在 web 服务器上返回 GET 请求的预测。使用 Flask API,通过 get 或 POST 请求输入和输出数据通常就像预测和返回一样简单。
拼图的最后一块将会是古尼康。Gunicorn 是运行 Flask 应用程序的客户端服务器。你可以通过 Pip 和一些包管理器来安装 Gunicorn(它在 Apt 中,而不是 Dnf 中)
sudo apt-get install gunicorn3
这是将从 supervisor 配置文件中运行的命令。然后用简单的
service supervisor reload
你将完全部署完毕,准备出发!
在 2020 年,有了所有这些有价值的工具,你可以在你的服务器上创建一些非常酷的模型和一些非常棒的自动化。拥有一个根据实时数据不断重新训练的模型将是非常有价值和非常可扩展的,这样做的解决方案肯定是最佳的!
简单的视觉问答
使用神经网络的视觉问题回答(VQA)的温和介绍。
快速回答——这张图片描述了什么运动?
图片来自 CloudCV VQA 演示
你可能马上就知道答案:棒球。很简单,对吧?
现在想象你是一台电脑。给你同样的图像和文字“在这个图像中描绘了什么运动?”并要求出示答案。不再那么容易了,是吗?
这个问题被称为视觉问答(VQA) :回答关于图像的开放式问题。VQA 很有趣,因为它需要结合视觉和语言理解。解决这一任务的模型展示了对图像的更一般的理解:它必须能够回答关于图像的完全不同的问题,有时甚至解决图像的不同部分。
起初,这似乎是一个很难解决的问题,但实际上它可能比你想象的更容易解决。在本帖中,我们将探索执行 VQA 的基本方法,并用 Python 构建我们自己的简单实现。下面是这篇文章最终产品的演示:
[## 简易 VQA 演示
在易 VQA 数据集上训练的可视化问答模型的 Javascript 演示。
easy-vqa-demo.victorzhou.com](https://easy-vqa-demo.victorzhou.com)
警告:**这篇文章假设了卷积神经网络(CNN)**的基本知识。我的CNN 简介涵盖了你需要知道的一切,所以如果有必要就从这里开始吧。
我们还将使用 Keras ,一个 Python 的深度学习库,来为我们的模型提供动力,所以如果你以前从未看过 Keras 代码,我建议你回顾一下我的Keras 神经网络简介。
这个前言说够了。我们开始吧!
只是找源代码/结果?跳到 结果 。
这篇文章最好在 victorzhou.com 浏览
1.数据集
在 visualqa.org 的可以找到 VQA 最著名的数据集,它包含 20 万多张图像和超过一百万个关于这些图像的问题(带答案)。这里有一些来自最初的 VQA 论文的例子:
印象深刻吧。不幸的是,这种程度的 VQA 超出了这篇博文的范围。我们将使用专门为这篇博文创建的自定义数据集: easy-VQA 。
易 VQA 数据集中的图像要简单得多:
问题也简单多了:
- 图像中是什么形状?
- 三角形是什么颜色的?
- 图像中是否有绿色形状?
- 图像包含一个圆吗?
总的来说,easy-VQA 包含 5000 幅图像和大约 50000 个问题,分为训练集(80%)和测试集(20%)。这些问题有 13 个可能的答案:
- 是/否:是,否
- 形状:圆形、长方形、三角形
- 颜色:红色、绿色、蓝色、黑色、灰色、蓝绿色、棕色、黄色
2.方法
执行 VQA 的标准方法如下所示:
- 处理图像。
- 处理问题。
- 结合步骤 1/2 中的功能。
- 给每个可能的答案分配概率。
请注意,我们正在使用一个固定答案集,其中保证可能的答案中只有一个是正确的。这让我们的生活变得容易多了,因为我们不必得出正确答案,我们只需回答实际上是一个选择题。大多数尖端的 VQA 系统有 1000 个可能的答案,但在这篇文章中,我们只允许包含在 easy-VQA 中的 13 个可能的答案。
步骤 1 和 2 通常分别使用来自计算机视觉和自然语言处理的方法,将原始图像/文本输入转化为经过处理的数据向量。然后,这两种输出表示可以一起用于分析,以最终选择最可能的答案。
一个例子
这里有一个非常简单的例子,说明 VQA 系统如何回答问题*“三角形是什么颜色的?”*关于上面可视化中的图像:
- 在图像中寻找形状和颜色。一个简单的 CNN 可以被训练识别出我们的图像包含一个蓝色的三角形。
- 了解题型。由于问题以*“什么颜色”*开头,很容易意识到答案应该是一种颜色。
- 对于每个可能的答案选项,根据前两步的信息确定其“强度”。答案“蓝色”将具有高强度,因为:(1)我们知道图像具有蓝色形状,并且(2)我们知道答案应该是颜色。
- 使用类似于 Softmax 的东西将每个答案的“强度”转换成概率。答案“蓝色”将有接近 100%的概率。
在接下来的几节中,我们将为 easy-VQA 数据集详细介绍实现这 4 个步骤的细节。
代码设置
如果你想跟随这篇文章,而不是从零开始,克隆易-VQA-克拉斯回购:
git clone [https://github.com/vzhou842/easy-VQA-keras.git](https://github.com/vzhou842/easy-VQA-keras.git)
cd easy-VQA-keras
pip install -r requirements.txt
否则,如果您想从头开始安装,请确保您使用的是 Python 3 并安装了几个包:
pip install easy-vqa keras tensorflow Pillow
我们需要 tensorflow 为 Keras 供电,我们将使用 Pillow 进行图像处理。我们还将使用 easy-vqa Python 包,这使得访问 easy-vqa 数据集变得简单。稍后会有更多相关信息——现在,让我们开始吧。
3.图像模型
首先:我们的形象模型。正如我们之前提到的,我们将构建一个卷积神经网络 (CNN)来从图像输入中提取信息。为此,我们将使用 Keras ,这是一个初学者友好但功能强大的 Python 深度学习库。我已经写了一篇关于使用 Keras 实现 CNN 的指南——在继续之前,在一个新的标签中打开它或者浏览它可能会有帮助。
我们的图像数据集并不复杂,所以我们可以用一个相对简单的 CNN 来处理它:
- 从数据集中的 64x64 图像开始。
- 通过使用“相同”填充的八个 3x3 滤镜的 conv 层,产生 64x64x8 的音量。
- 使用标准的最大池层将体积切割为 32x32x8。
- 通过另一个 conv 层,这一次有 16 个过滤器,产生一个 32x32x16 的体积。
- 再次使用最大池,切割到 16x16x16。
- 展平体积,这会产生一个具有 16 = 4096 个节点的层。
迷茫?以上所有概念都在我的CNN 简介 中有所涉及。
代码如下:
这段代码使用了 Keras 的模型(功能)API。我们没有使用 Keras 的顺序模型 API,因为我们稍后需要将我们的图像模型和问题模型结合起来(你会看到,继续阅读)。
4.问题模型
接下来:我们的问题模型。大多数 VQA 模型会使用某种递归神经网络 (RNN)来处理问题输入,但这对我们的用例来说有点大材小用。易 VQA 数据集中的问题简短、简单,来自一组固定的问题模板,因此与你在现实世界中可能看到的问题相比,它们更容易理解。
我们将采用一种更简单的方法,而不是复杂的 RNN 架构:
- 使用一个单词包 (BOW)表示法将每个问题转化为一个向量。
- 使用该向量作为标准(前馈)神经网络的输入。
如果你不完全明白那是什么意思,不要担心。我们将在下面完成这两个步骤。
单词袋(蝴蝶结)
BOW 表示通过计算每个单词在文本中出现的次数,将任何文本字符串转换为固定长度的向量。我已经写了一篇简短的、初学者友好的关于单词袋模型的介绍——如果你对它们不熟悉,我建议你现在就去读!从现在开始,我假设你对弓模型有一个基本的了解。
我们将利用 Keras 的记号赋予器类来实现 BOW:
注意,我们从easy-vqa
包中读取问题数据。如果你想了解这些 API 的细节,请参考 easy-vqa 文档。
神经网络时间!
如前所述,我们的问题数据集相对简单,因此我们的问题模型不需要太花哨的东西。我们将把我们的弓向量表示传递到 2 个全连接 (FC)神经网络层:
提醒:全连接层的每个节点都连接到前一层的每个输出。如果你需要复习,我们在我的 神经网络介绍 中使用了全连接层。
下面是我们的实现,它也使用了 Keras 的模型(函数)API:
vocab_size
变量是我们 BOW 向量表示的长度,它是我们问题模型的输入。
5.合并
我们将使用一个非常简单的方法来合并我们的图像和问题向量:逐元素乘法。用 Keras 的多重合并层实现这个是一行程序:
out
向量现在包含了从图像和问题中得到的信息。
一个例子
为了说明这是如何有用的,考虑这个(有点做作的)例子:
- 当图像包含蓝色形状时,图像向量中的第一个元素为高电平**,否则为低电平**。****
- 当问题包含单词“blue”时,问题向量中的第一个元素是高,否则是低。
那么out
向量中的第一个元素只有在图像和问题都与蓝色相关时才会为高。这个结果对于回答类似“图像中有蓝色的形状吗?”****
实际上,我们的模型不太可能准确地学习这种行为。记住,模型是通过在它的层中传播渐变来学习的,这不太可能产生如此简单的结果。相反,关注直觉:**
- 图像和问题向量中都嵌入了颜色信息。
- 乘法运算后,结果的某些部分可以用来回答关于颜色的问题。
实际上,我们可以用任何可微的方法来合并这两个向量。Keras 的合并图层部分中列出的其他合并方法包括Add
、Subtract
、Concatenate
和Average
,所有这些方法都做您认为它们做的事情。对于我们简单的数据集来说,大多数方法可能都和Multiply
一样好用——你可以自己尝试一下!
6.输出
最后,是我们的 VQA 系统给出答案的时候了。回想一下,我们正在使用一个固定答案集:我们知道所有可能的答案,并且只有一个保证是正确的。
对于这一步,我们将使用 Softmax 将我们的输出值转化为概率,这样我们就可以量化我们对每个可能答案的确信程度。如果你不熟悉 Softmax,我强烈建议在继续之前阅读我对 Softmax 的解释。**
首先,我们将加入一个全连接层,然后使用 Keras 内置的 Softmax 实现:
就是这样!剩下的工作就是构建和编译模型:
如果你需要复习,我在我的 CNN 系列中解释了 交叉熵损失 。
7.数据处理
既然我们已经弄清楚了我们的模型,我们只需要多一点代码来准备好所有的数据。对于这一部分,我建议在单独的标签中打开easy-VQA文档以供参考。为了简洁起见,我将省略对我们从easy-vqa
开始使用的方法的解释。
首先,我们将从easy-vqa
中提取一些数据:
接下来,我们将读取并预处理我们的图像:
然后,我们将创建用于训练模型的实际输入和预期输出:
Keras 的to _ categorial是一种从索引中生成 one-hot 向量的简便方法。我们需要一个热点矢量来匹配我们的输出 Softmax 层的尺寸。
作为一个可选步骤,我们将设置一个 Keras ModelCheckpoint 以在每个时期后保存我们的最佳模型:
终于,我们准备好训练了!
8.结果呢
为了节省空间,我不会在这篇文章中包含完整的代码,但你可以在 GithubT5上找到它。将这些行复制并粘贴到您的终端中,亲自训练模型:
**git clone https://github.com/vzhou842/easy-VQA-keras.git
cd easy-VQA-keras
pip install -r requirements.txt
python train.py**
运行代码会得到如下结果:
**Epoch 1/8
loss: 0.8887 - accuracy: 0.6480 - val_loss: 0.7504 - val_accuracy: 0.6838
Epoch 2/8
loss: 0.7443 - accuracy: 0.6864 - val_loss: 0.7118 - val_accuracy: 0.7095
Epoch 3/8
loss: 0.6419 - accuracy: 0.7468 - val_loss: 0.5659 - val_accuracy: 0.7780
Epoch 4/8
loss: 0.5140 - accuracy: 0.7981 - val_loss: 0.4720 - val_accuracy: 0.8138
Epoch 5/8
loss: 0.4155 - accuracy: 0.8320 - val_loss: 0.3938 - val_accuracy: 0.8392
Epoch 6/8
loss: 0.3078 - accuracy: 0.8775 - val_loss: 0.3139 - val_accuracy: 0.8762
Epoch 7/8
loss: 0.1982 - accuracy: 0.9286 - val_loss: 0.2202 - val_accuracy: 0.9212
Epoch 8/8
loss: 0.1157 - accuracy: 0.9627 - val_loss: 0.1883 - val_accuracy: 0.9378**
对于这样一个简单的模型来说,8 个时代一点也不差:
- 我们达到了 93.8% 的验证准确率
- 我们清楚地看到了培训的进展(损失减少,准确性提高)
- 该模型还没有过度拟合得太糟糕(训练/验证损失和精确度足够接近)
如果您愿意,您可以自己对代码进行试验,以获得更好的结果。我的带 Keras 的 CNN 简介中的扩展部分是一个很好的起点。考虑到这个问题相对简单,您应该能够非常容易地通过 99%的验证准确率。供参考:官方的 easy-VQA 演示使用了一个模型,该模型实现了 99.5%的验证准确性,参数仅略有不同。
9.结束了
您现在已经实现了一个工作的 VQA 模型!然而,这篇文章只是一个温和的介绍。您还可以做更多的事情:
- 了解递归神经网络 (RNNs),它可以比我们使用的简单的基于 BOW 的问题模型更强大。
- 以原始的 VQA 数据集为例,它包含更难的图像和问题。
- 查看 VQA 的调查,了解艺术模特使用的更复杂的方法。
- 试试 CloudCV VQA 演示(印象相当深刻!).
感谢阅读!
注意:这篇文章用了第一人称(“我”、“我的”),读起来好像是我(Victor Zhou)在说话。然而,正如最上面指出的,这篇文章是由我的好朋友Phillip Wang共同撰写的,他是最近从 CMU 毕业的计算机科学毕业生,也是 ML 的一员。谢谢菲利普。
最初发表于https://victorzhou.com*。*
从广告服务向 Google Analytics 导入成本数据的简单方法
来源:沉积照片
为什么需要将成本数据导入 Google Analytics,以及如何做。
当你与许多广告服务打交道时,你最终会遇到这样一种情况:你需要衡量和比较它们的有效性。但问题是,非谷歌服务(如 Instagram、脸书广告、Bing、LinkedIn 广告等)没有与谷歌分析进行原生集成。因此,如果你想控制你的广告成本并评估广告活动的成功,你必须收集不同广告服务的活动数据,然后设法分析它们。
事实上,为了成功地工作并对任何营销变化做出快速反应,你需要获得关于活动效率的数据并存储在一个地方。由于谷歌分析仍然是最受欢迎和最方便的服务,让我们看看我们可以做些什么来建立基于任何广告服务的完整数据的报告。
所以这并不简单——你需要的只是数据,你广告服务的所有成本数据。您可以手动完成(例如,使用 CSV。文件),或者您可以设置自动数据导入,节省您的时间、金钱和精力。
我们建议使用 OWOX BI 连接器来自动收集和合并所有广告数据。这项服务是 Supermetrics 或 Funnel.io 等昂贵工具的免费替代品,免费到 2020 年底。
OWOX BI 数据导入的独特优势
这项服务是根据分析师和营销人员的要求创建的,这就是为什么它有许多独特的好处。
- 成本数据格式同。处理数据时最常见的错误是广告服务和谷歌分析视图中的货币不同。但是,OWOX BI 会自动转换货币,并在必要时扣除增值税。
- 数据的准确性和质量。OWOX BI 处理动态参数,检查您活动中的现有 UTM 标签,并借助 OWOX BI 数据监控工具报告可能的错误。
- 更新和历史数据。如果广告服务中的数据发生变化,OWOX 会在 21 天内自动更新数据。此外,您可以从广告服务下载过去 2-6 个月的广告,并评估您过去的活动。
图片由作者提供
简而言之,OWOX BI 服务可帮助您避免基于完全未采样数据制作营销报告的持续人工工作。
我们挑选了 7 个关于该服务的最受欢迎的问题,以便您可以看到它已准备好迎接任何挑战。
OWOX BI 向 Google Analytics 上传了哪些数据
OWOX BI Pipeline 从广告服务中导出这些数据:
- 来源(必需)
- 中等(必需)
- adCost(必需)
- 运动
- Google Ads 活动 ID(与您广告帐户中的活动 ID 完全匹配)
- 广告位置
- 关键字
- 广告内容
- 广告点击
- 印象
可选数据取决于您的谷歌分析数据集的配置。
OWOX BI 数据监控
有时,由于系统故障,广告服务 API 不提供下载的费用数据。结果就是你的 ROI 计算错误,甚至看不出成本数据的导入没有发生。
然而,在数据监控工具的帮助下,你可以确定从脸书、Twitter、Criteo 等广告服务导出到谷歌分析的成本数据。您可以在一个页面上使用 OWOX BI 项目中成本数据的每日统计数据,并获取所选日期的数据状态:
图片由作者提供
历史数据更新
广告服务中的信息可以更改,因为这些服务可以删除不正确的数据,如机器人活动、虚假点击等。因此,上传到您的 Google Analytics 个人资料的信息可能不准确。但是,OWOX BI 会自动检查 21 天的追溯数据,并根据需要进行更新。
也就是说,您的 Google Analytics 个人资料或 BigQuery 表格中的数据将与您的广告服务帐户中显示的数据完全相同。
谷歌分析何时提供这些数据
这些数据在 36 小时内可在谷歌分析中获得。一旦数据在广告平台上可用,使用 OWOX BI 服务导入和处理数据需要 12 个小时。处理完成后,可能需要24 小时才能在报告中获得数据。
在 Google Analytics 的什么地方可以看到导入的成本数据
采集/活动/ 成本分析报告 是您可以找到所有导入的成本数据的地方。此外,您可以使用以下工具通过 API 访问数据:
可以通过广告服务中的自定义活动过滤成本数据吗
您不能通过自定义活动过滤导入的成本数据,但可以对导入的 UTM 标签值使用 Google Analytics 过滤器。
例如,您可以按 utm_campaign 参数中的特定值筛选数据,以排除特定的成本。
图片由作者提供
我们建议将不同网站的活动划分到不同的帐户,以避免广告服务对每个活动的 API 调用次数的限制。
货币兑换是如何发生的
OWOX BI 使用一个开放的 API Yahoo Finance 来获取货币汇率。货币根据广告显示时的相关汇率进行转换。
换句话说,如果广告服务和 GA 视图的货币没有差异,数据就没有变化。当货币变化时,使用开放汇率 API 将成本数据转换为 GA 视图的货币。
请注意一些广告服务传输成本数据不含增值税(不像谷歌广告或脸书)。如果你不指定计算增值税的百分比,你最终会高估你的活动成本。使用 OWOX BI,您可以随时在数据管道的设置中更改增值税百分比。
图片由作者提供
觉得有意思?让我们看看如何开始使用 OWOX BI 导入成本数据。
OWOX BI 服务具有完全的透明性和安全性:只有 您可以控制对您的数据的访问级别 。
如您所见,您不必害怕提供对您个人资料的访问,OWOX BI 服务不会对您的数据进行任何更改。
使用 OWOX BI 从广告服务开始导入成本数据的 5 个步骤
- 使用您的促销代码并使用您的 Google 帐户登录。
- 选择要从中导入数据的广告服务。
- 提供对谷歌分析中选择的广告服务和数据集的访问。
- 定义设置(开始日期、增值税和货币)。
- 等待长达 36 小时,以获取您的谷歌分析个人资料中的所有数据。
如你所见,用 OWOX BI 导入成本数据很容易!放下服务中的日常工作,专注于真正重要的事情:
- 发现你广告的真正价值;
- 更多地了解你的客户;
- 有效管理你的广告预算。
弗雷德里克顿餐馆数据分析
在 Python 中探索、操作和分析数据
数据分析,21 世纪最热门、最繁荣的领域之一。不断增长的数据和对智能系统的旺盛需求要求对数据进行积极的分析。无论你使用 Siri 或 Alexa 之类的虚拟助手,还是在网飞或亚马逊之类的媒体服务提供商上获得内容推荐;数据分析是每个智能系统的基础。它已经在世界各地生根发芽,无论是支持企业发展的决策,还是成为我们生活方式的一部分。
在我们开始之前,让我们使用数据分析来探索加拿大的一个城市。这篇文章将带领你探索弗雷德里克顿的餐馆和附近的场地。使用数据科学方法论的术语,我们将推动它从描述问题到用可能的答案来总结它。
简介:
- 背景
弗雷德里克顿是加拿大新不伦瑞克省的首府,人口约 6 万。新不伦瑞克的主要城市中心之一,是该省第三大城市。
作为省会,它的经济与公共部门紧密相连;然而,这座城市也包含了一个成长中的 IT 和商业部门。该市拥有全省最高的大专以上学历居民比例,也是新不伦瑞克省人均收入最高的城市[1]。
作为这座城市的居民,我决定探索弗雷德里克顿的场馆。这座城市是完全多样化的,有很多社区,它正变得越来越密集,因为它吸引了全球更多的人。事实上,这里不能否认食物多样性的重要性。
- 问题
该项目的目的是探索弗雷德里克顿的场馆。由于弗雷德里克顿的居民区并不密集,人数也较少,所以我们希望找出弗雷德里顿市的餐馆类别及其在食物多样性中所占的份额。
- 利息
这个项目将有助于了解这个城市的不同菜系。任何政府官员或食品行业专家都可以利用这一分析结果来了解城市中的食品多样性。计划建立他们的餐馆或食品经销店的供应商可以利用这种分析来帮助他们做出决定。
数据:
以下数据来源是本次分析的一部分:
- 维基百科
加拿大邮政编码列表:E [2]
这一页有新不伦瑞克 FSAs(前分拣区)的邮政编码列表。上传页面数据,使用 Python 包抓取邮政编码表。这个数据包含所有街区的邮政编码,我们可以使用这个数据来获得弗雷德里克顿街区的空间坐标。
- Foursquare API
Foursquare 是一家建立了大量位置数据数据集的科技公司。目前,它的位置数据是最全面和相当准确的。它为苹果地图、优步和 Twitter 等许多流行服务提供位置数据。
使用 API [3],我得到了弗雷德里克顿社区的场馆数据。API 在 JSON 中提供了响应,并检索了场馆及其类别和其他详细信息。我用这些数据探索了这个城市的食物多样性。
方法:
- 废弃维基页面,获得邻居
为了探索城市,首先我们需要城市数据。那是从维基百科页面上检索到的;我用 Python 的 BeautifulSoup 包抓取了页面数据。wiki 页面中的表格被转换为下面的 pandas 数据框。
新不伦瑞克邮政编码
- 获取空间坐标
为了在地图上表示邻近区域,并从 foursquare API 获取场地,需要空间坐标。为了获得邻域的空间坐标,我使用了 Python 的地理编码库。
使用地理编码,我能够得到我们在上一步中搜索到的所有街区的经度和纬度。因此,创建了以下数据帧:
新不伦瑞克与自治市相协调
数据框的形状为(111,5),这意味着新不伦瑞克有 111 个邻域。未分配的邮政编码已从数据框中清除。
以上数据框包括新不伦瑞克省的所有行政区。可以使用叶库在地图上可视化;下面的图片是使用叶子库在顶部叠加了邻居的新不伦瑞克的表示。
叠加在新不伦瑞克地图上的街区
因为我们希望只探索弗雷德里克顿社区,所以我在一个新的数据框中分离出了“弗雷德里克顿”区的数据。
弗雷德里克顿街区
- 从 Foursquare 获取场地:
调用 Foursquare API 需要客户端 ID 和 Secret,可以在 Foursquare 开发者网站注册生成。Foursquare 为 API 端点提供了不同的过滤器选项。我首先试图为弗雷德里克顿的整个社区找到场地。弗雷德里克顿社区并不密集,所以我保持半径为 10000 米,限制为 100 米。从 Foursquare 收到 JSON 数据后,它被解释并转换成以下数据帧:
弗雷德里克顿社区活动场所
探索性数据分析:
合并后的数据框包含所有邻近地点的信息。让我们做一个热门的场馆编码。我将场地类别转换为新数据框的列,并在其中添加了邻居列。
数据框的形状是(4,53 ),表示有 52 个独特的场馆类别。使用此数据框,我们可以找到弗雷德里克顿社区最常见的活动场所。我尝试获得前三个公共场地,结果如下:
弗雷德里克顿最常见的地方
结果告诉我们弗雷德里克顿社区的三个最常见的场所。正如我们所见,最常见的场所包括三个社区的餐厅。然而,北弗雷德里克顿是唯一一个在公共场所没有餐厅的社区。与弗雷德里克顿的其他地区相比,北弗雷德里克顿的人口很少。因此,它的网点数量相对较少。
弗雷德里克顿只有四个街区。因此,在这里聚集邻域不是一个好的选择。因此,我们将对餐馆类别做进一步分析,以了解弗雷德里克顿的口味。
我再次使用 Foursquare API,但这次传递了类别 id,只获取食物类别的地点。JSON 响应以与我们之前相同的方式被解释,并被传输到数据帧中。有 22 个独特的食物类别,也包含一般类别,如就餐者,食物和美食广场。我列了一个一般类别的列表,并从数据框中删除了这些场馆。
由于我们希望探索弗雷德里克顿市的餐馆类别,因此我在数据框中为行政区添加了一列,并将值插入为弗雷德里克顿。
为了使数据更加结构化,我将场地类别作为列,并用类别的平均值乘以 100 对“区”进行分组。它给了我弗雷德里克顿市每一类的百分比值。具有类别平均值的数据框如下所示:
弗雷德里克顿市食品类别
为了可视化上述数据,我从上述数据框中获得转置数据,将百分比小数四舍五入为 2 点,并将数据框转换如下:
转置数据帧
上面的数据框现在很容易想象。一个水平条形图将是一个很好的选择形象化,并显示在弗雷德里克顿餐馆类别的百分比。
结果:
让我们使用 Matplot 和 Seaborn 库在上面创建一个条形图。以下是该数据的水平条形图:
条形图
该条形图显示了弗雷德里克顿各类餐馆的百分比。每个条形的百分比与其自身一起显示。图表清楚地显示,快餐店以大约 25%的份额领先。比萨和三明治店也领先于这个城市的任何一种特色美食。在弗雷德里克顿丰富多样的食物中,中国餐馆占有一席之地。在这座城市里,还有其他的美食可以提升弗雷德里克顿的品味。
结论:
在考虑了结果之后,可以说快餐店正在主宰弗雷德里克顿的食品市场。结果显示了城市中的食物多样性,考虑到城市的人口,这是相当活跃的。此外,不可否认的是,城市人口的增长将促进城市对更多美食的需求。因此,这将为打算投资食品行业的商家带来更多的机会。
此外,如果我们看到弗雷德里克顿的街区,餐馆类别可能不会出现在北弗雷德里克顿最常见的场所,但建筑在上面;它进一步抓住了利益相关者的注意力。
通过获取人口数字、社区主导位置及其利益的数据,可以进一步扩展这种分析的范围,以了解城市的确切需求;这可能是供应商做出决定的决定性因素。
参考文献:
【https://en.wikipedia.org/wiki/Fredericton】
****【2】https://en . Wikipedia . org/wiki/List _ of _ postal _ codes _ of _ Canada:_ E
****【3】https://developer.foursquare.com/
感谢您阅读文章!如果你喜欢,请在评论区分享你的想法。
Jupyter 笔记本和详细报告可从 GitHub 获取。