TowardsDataScience 博客中文翻译 2020(七百七十四)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

攀登熊猫:比较达斯克、雷、摩丁、瓦克斯和拉皮兹

原文:https://towardsdatascience.com/scaling-pandas-comparing-dask-ray-modin-vaex-and-rapids-c74c85a4e59c?source=collection_archive---------31-----------------------

如何更快地处理更多数据

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

加速与 Dask、Ray、Modin Vaex 和 RAPIDS 的数据争论——来源:作者

Python 和它最受欢迎的数据争论库 Pandas 人气飙升。与 Java 等竞争对手相比,Python 和 Pandas 使得数据探索和转换变得简单

但是众所周知,Python 和 Pandas 都有关于可伸缩性效率的问题。

Python 立刻失去了一些效率,因为它是一种解释型的动态类型语言。但更重要的是,Python 一直关注简单性和可读性,而不是原始能力。同样,Pandas 专注于提供一个简单的高级 API,很大程度上忽略了性能。事实上,熊猫的创造者写了“我讨厌熊猫的 10 件事”,总结了这些问题:

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

性能问题和缺乏灵活性是熊猫自己的创造者不喜欢这个库的主要原因。(来源)

性能问题和缺乏灵活性是熊猫自己的创造者不喜欢这个库的主要原因。(来源)

因此,许多开发人员试图以各种方式为 Python 和 Pandas 增加更多功能也就不足为奇了。一些最著名的项目是:

  • Dask**😗*一个低级的调度器和一个高级的部分 Pandas 替换,面向计算集群上的运行代码。
  • Ray: 跨处理器或集群并行化 Python 代码的底层框架。
  • 摩丁 : 熊猫的替代者,由达斯克驱动。
  • Vaex**😗*部分熊猫替代,使用惰性评估和内存映射,允许开发人员在标准机器上处理大型数据集。
  • 急流 : 一个运行在 GPU 上的数据科学库集合,包括 cuDF ,部分替代了熊猫。

还有其他人。以下是 Python 数据争论的概况:

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

Dask、Modin、Vaex、Ray 和 CuDF 经常被认为是彼此的潜在替代者。来源:使用工具创建

那么,如果您正在处理大量数据,并且需要更快的结果,您应该使用哪一种呢?

告诉我该试哪一个

在决定使用哪种工具之前,最好对每种方法有更多的了解。我们将仔细比较它们,但您可能希望按照以下顺序尝试它们:

  • 摩丁,以射线作为后端。通过安装这些程序,只需更改一行代码(将’ import pandas as pd ‘改为’ import modin.pandas as pd ')就可以获得显著的好处。与其他工具不同,摩丁的目标是与熊猫完全兼容。
  • 一个更大更复杂的项目。但是 Dask 也提供了 Dask.dataframe,这是一个更高级的类似熊猫的库,可以帮助你处理核外 T21 数据集。
  • **Vaex,**它旨在帮助您在标准笔记本电脑上处理大量数据。它的 Pandas replacement 包含了一些 Pandas API,但它更侧重于探索和可视化。
  • 激流、如果有 NVIDIA 显卡的话

快速比较

我们研究的每个库都有不同的优势、劣势和扩展策略。下表对这些进行了概述。当然,和很多事情一样,下面的大部分分数很大程度上取决于你的具体情况。

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

Dask 和 Ray 比较成熟,但是摩丁和 Vaex 比较容易上手。如果你有 GPU 的话,Rapids 是有用的。

Dask 和 Ray 比较成熟,但是摩丁和 Vaex 比较容易上手。如果你有 GPU 的话,Rapids 是有用的。

这些都是主观的分数,根据你的具体情况可能会有很大的不同。在分配这些等级时,我们考虑了:

  • **成熟度:**自第一次提交以来的时间和提交次数。
  • **人气:**GitHub 明星数量。
  • **易于采用:**用户期望的知识量、假定的硬件资源和易于安装。
  • **扩展能力:**每个工具的广泛数据集大小限制,取决于它是主要依赖于单个机器上的 RAM、硬盘空间,还是可以扩展到机器集群。
  • **用例:**无论这些库是被设计来加速 Python 软件的速度( General )、专注于数据科学和机器学习(数据科学)、还是被限制为简单地替换 Pandas 的“数据框架”功能(数据框架)。

CPU,GPU,集群,还是算法?

如果您的数据集太大,无法在单台机器上有效地工作,那么您的主要选择是跨…

  • **…多线程或处理器:**现代的 CPU 都有几个独立的内核,每个内核都可以运行很多线程。通过跨内核并行化来确保您的程序使用所有潜在的处理能力通常是最容易的起点。
  • **…GPU 核心:**显卡的设计初衷是高效地并行执行数百万像素的基本运算。然而,开发人员很快就看到了这种能力的其他用途,“GP-GPU”(图形处理单元上的通用处理)现在是一种流行的方法,可以加速严重依赖矩阵操作的代码。
  • **…计算集群:**一旦你达到单台机器的极限,你就需要一个联网的机器集群,协同工作。

除了增加更多的硬件资源,巧妙的算法也能提高效率。像 Vaex 这样的工具严重依赖于(在确定需要结果之前不做任何计算)和 内存映射 (将硬盘上的文件视为加载到 RAM 中)。

这些策略没有一个天生就比其他策略好,您应该选择适合您的特定问题的策略。

并行编程(无论您使用线程、CPU 内核、GPU 还是集群)提供了许多好处,但它也非常复杂,并且使调试等任务变得更加困难。

现代图书馆可以隐藏一些——但不是全部——增加的复杂性。无论你使用哪种工具,你都有可能期望一切都井井有条(左下),但结果却是一片混乱(右下)。

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

并行处理并不总是像你期望的那样完美。( Source Reddit )

并行处理并不总是像你期望的那样完美。(来源

达斯克 vs 雷 vs 摩丁 vs 瓦克斯 vs 激流

虽然并非所有这些库都是彼此的直接替代,但在决定为项目使用哪个库时,直接比较它们是有用的。

在进入细节之前,请注意:

  • RAPIDS 是一个图书馆集合。为了进行比较,我们只考虑 cuDF 组件,它相当于熊猫的急流。
  • Dask 最好被认为是两个项目:一个低级 Python 调度程序(在某些方面类似于 Ray)和一个高级 Dataframe 模块(在许多方面类似于 Pandas)。

达斯克对雷

Dask(作为一个底层调度器)和 Ray 在目标上有很多重叠,都是为了让 Python 代码更容易在机器集群上并行执行。Dask 更专注于数据科学领域,提供更高级别的 API,进而为 Pandas、NumPy 和 scikit-learn 提供部分替代,此外还有一个低级别的调度和集群管理框架。

Dask 和 Ray 的创建者在中讨论了这些库如何与 GitHub 线程进行比较,他们得出的结论是调度策略是关键区别之一。Dask 使用集中式调度器在多个内核之间共享工作,而 Ray 使用分布式自下而上的调度。

达斯克对摩丁

Dask(更高层次的数据框架)承认 Pandas API 的局限性,虽然它为了熟悉而部分地模拟了这一点,但它并不打算完全兼容 Pandas。如果你有复杂的现有 Pandas 代码,你不太可能简单地把 Pandas 换成 Dask。数据框架,让一切按预期工作。相比之下,这正是摩丁努力的目标:100%报道熊猫。Modin 可以运行在 Dask 之上,但最初是为了与 Ray 一起工作而构建的,这种集成仍然更加成熟。

Dask 对 Vaex

Dask (Dataframe)并不完全兼容熊猫,但是已经很接近了。这些紧密的联系意味着达斯克也背负着熊猫固有的一些包袱。Vaex 与 Pandas 的差异更大(尽管对于基本操作,如读取数据和计算汇总统计数据,它非常相似),因此也更少受到它的约束。

最终,Dask 更侧重于让您扩展代码以计算集群,而 Vaex 使在单台机器上处理大型数据集更容易。Vaex 还提供了一些功能来帮助您轻松地可视化和绘制大型数据集,而 Dask 则更专注于数据处理和争论。

达斯克对拉皮兹(cuDF)

Dask 和 RAPIDS 通过由 RAPIDS 提供的集成很好地合作。如果您有一个计算集群,您应该使用 Dask。如果你有 NVIDIA 显卡,你应该用 RAPIDS。如果你有一个 NVIDIA GPUs 的计算集群,你应该两者都用。

雷 vs .摩丁或瓦克斯或急流

把雷和摩丁,Vaex,或者激流比,没那么有意义。与其他库不同,Ray 不提供高级 API 或 Pandas 等价物。相反,雷为摩丁提供动力,而以类似于 Dask 的方式与急流整合。

摩丁 vs. Vaex

与 Dask 和 Vaex 相比,Modin 的目标是提供一个完整的 Pandas 替代品,而 Vaex 与 Pandas 的差异更大。如果您正在寻找一种快速的方法来加速现有的 Pandas 代码,那么 Modin 应该是您的第一选择,而 Vaex 更可能对新项目或特定用例感兴趣(尤其是在单台机器上可视化大型数据集)。

摩丁对急流(cuDF)

摩丁通过 Ray 或 Dask 使用许多 CPU 内核来扩展熊猫代码。RAPIDS 通过在 GPU 上运行熊猫代码来扩展它。如果您有可用的 GPU,请尝试一下 RAPIDS。但最容易的胜利可能来自摩丁,你可能应该先尝试过摩丁后再转向急流。

Vaex vs. RAPIDS (cuDF)

Vaex 和 RAPIDS 的相似之处在于,它们都可以在一台机器上提供性能提升:Vaex 通过更好地利用计算机的硬盘驱动器和处理器内核,而 RAPIDS 通过使用计算机的 GPU(如果可用且兼容的话)。RAPIDS 项目的整体目标是比 Vaex 更广泛,让你端到端地进行机器学习,而数据不会离开你的 GPU。Vaex 更适合原型开发和数据探索,允许您在消费级机器上探索大型数据集。

最后一句话:过早的优化是万恶之源

玩新的专业工具很有趣。也就是说,许多项目都存在过度工程化和过早优化的问题。如果你还没有遇到规模或效率问题,单独使用 Python 和 Pandas 也没什么问题。它们被广泛使用,提供了成熟性、稳定性和简单性。

一旦你达到了 Python 和 Pandas 自身的极限,你就应该开始研究这里讨论的库。否则,您可能会花费太多时间来选择和配置库,而不是在项目上取得进展。

我们已经用这些库构建了许多项目,并且知道何时以及如何使用它们。如果你需要第二种意见,请联系我们。我们很乐意帮忙。

利用在线回归等功能扩展实时推理

原文:https://towardsdatascience.com/scaling-up-real-time-inference-with-online-regression-and-more-902a939c171c?source=collection_archive---------53-----------------------

根据数据做出正确的决策意味着成功或失败。这就是为什么谷歌的团队试图实现“更多、更好、更快的实验”,也是为什么他们和许多其他公司投资开发内部实验平台(微软的 ExP网飞的闪亮优步的 XPBooking.com 的 ET ,不胜枚举)。基础是 A/B 测试,现在这种测试被大规模实时地广泛进行。

这些天来,我们的胃口已经超出了 A/B 测试。科学家们面临着挑战,要在越来越复杂的情况下运用更先进的技术来改进决策。作为一个个人例子,我帮助将微软的 CUPED 引入 Booking.com 的 ET 以增强实验能力。这有助于更好地做出决策,但我并没有快速或廉价地做出决策。它是每天使用整个数据集计算的,随着数据的增长,成本会越来越高。另一个例子是网飞的 XP 允许数据科学家部署任意的统计函数。同样的规模挑战也适用,因此他们有一个专门的数学工程团队来编写高性能代码并减少代价高昂的瓶颈(例如,分位数自举和 OLS 回归)。

巧合的是,这篇文章讨论了回归(CUPED 也基于此)对决策的价值,如何将结果扩展到大量数据并实时显示,以及一个简单的基础如何为实时统计方法的宝库铺平道路。下面是我们将涉及的技术部分的总结。

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

实时回归方法概述

附注:我正在分享这个问题统计方面的一个解决方案。首先,虽然我找不到它们,但其他解决方案可能已经存在了(我的意思是,网飞团队说它是可用的)。如果你知道并且有能力,我很乐意在评论中与你分享!另一件事是,这并没有涵盖问题的工程方面。为了大规模成功实施,您需要将了解这里发生的事情的数据科学家与知道如何适当地传输和存储数据的工程师配对。

回归

普通最小二乘回归(从现在开始我就称之为“回归”)是建模连续数据最广泛使用的方法之一。它在机器学习中被大量使用,但这不是我们在这里的目的。我们在这里用它进行统计推断。如果你不太熟悉这种使用方式,它应该会让你兴奋地了解到回归涵盖了许多有用的统计技术测试,从简单的 t 测试到结构方程建模。最后会有更多的介绍。基本上,在你的推理工具包中加入回归可以极大地扩展你做出正确决策的范围。

警告:我在故意推销回归的价值。然而,这种价值来自于对数据和结果的假设,这些假设对未经培训的用户构成了严重的风险。如果你对使用基于回归的方法进行推断感兴趣,一定要和一个了解风险的统计学家讨论。如果你不这样做,你最终可能会做出更糟糕的决定!

问题是,如何扩展回归并不像使用简单的技术那样显而易见。这当然是它没有被大规模利用的一个原因。因此,让我们开始研究如何扩展我们的回归工具包,以便大规模、实时地工作!

让它发挥作用的洞察力

压缩是关键

有效处理大规模数据通常涉及数据压缩。例如t——测试不需要每个数据点。他们只需要跟踪几个数字:组均值、方差和样本量(个人演示贴)。类似地,分位数自举可以用分桶数据来完成(网飞邮报)。如果您可以使用可以实时更新的压缩数据集,那么您就成功了!

事实证明我们可以利用这个来回归。无论您的总数据有多大,回归只需要一些汇总统计数据,这些统计数据可以随着新数据的到来而更新。

回归只需要协方差和 n

所有一个回归需要的是 协方差矩阵 和样本大小。

拥有 25 个指标和 1 亿个数据点。见鬼,10 亿个数据点?!没问题。你只需要 326 个数字。指标的 25x25 协方差矩阵(嗯,它的各种变换),它是对称的,因此有 325 个唯一的数字,一个数字代表样本大小。

现在我们知道了这一点,这篇文章的其余部分将介绍如何实现实时回归,然后讨论这种方法可能带来的其他好处。

让它工作

用于回归的实时数据压缩

注意:我将使用 r 来演示这项技术。你可以在这里 找到我的 GitHub 上的完整代码

我们需要协方差矩阵,但是随着数据的流入,使用中间对象更容易:偏差叉积矩阵。“偏差”指的是“与平均值的差异”,“叉积”是数值相乘的总和。因此,当一个新单元(例如,用户)的数据出现时,我们更新三样东西:样本大小、度量平均值(用于计算偏差)和偏差叉积矩阵。这里有一个总结:

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

当新实验单元的数据到达时,如何更新压缩数据

对于那些渴望代码的人来说,我写了一个 R 函数update_compression(),当新单元的数据到达时,它会这样做。你可以在 GitHub repo 中找到它。除了一个矩阵转置(如果你愿意可以避免),这都是基本的数学。

让我们通过一个简单的数据集来看看它的实际应用:

# A simple data set of 10 observations
xs#>              x1       x2        x3
#>  [1,] 0.1366358 5.719901 11.807291
#>  [2,] 2.0323437 4.750903  6.992279
#>  [3,] 1.2030423 5.903466  8.910174
#>  [4,] 1.9078714 5.649198  7.488551
#>  [5,] 2.6487667 7.465745 11.340035
#>  [6,] 4.5719305 7.744037 10.077654
#>  [7,] 0.7048246 4.347754  7.146864
#>  [8,] 2.5375564 6.234913  9.964397
#>  [9,] 1.2603890 4.258484  7.630200
#> [10,] 1.4273975 7.329029 12.639481

假设第一个单元(第一行)到达,我们运行我们的函数。结果是:

*# Compress first row of data*
compressed_d <- update_compression(xs[1,])
compressed_d#> $n
#> [1] 1
#> 
#> $means
#>         x1         x2         x3 
#>  0.1366358  5.7199010 11.8072912 
#> 
#> $dcrossp
#>      [,1] [,2] [,3]
#> [1,]    0    0    0
#> [2,]    0    0    0
#> [3,]    0    0    0

这表明我们的样本大小为 1,每个指标的平均值就是数据点本身。叉积都是 0,只有 1 个数据点。

现在每一行都按顺序显示。最后的结果是什么?

# Iteratively update the compression with remaining data **for** (i **in** 2:nrow(xs)) {
  compressed_d <- update_compression(xs[i,], compressed_d)
}compressed_d#> $n
#> [1] 10
#> 
#> $means
#>       x1       x2       x3 
#> 1.843076 5.940343 9.399693 
#> 
#> $dcrossp
#>           [,1]      [,2]      [,3]
#> [1,] 13.747618  8.726897  1.679592
#> [2,]  8.726897 14.509862 18.319109
#> [3,]  1.679592 18.319109 38.730283

样本量为 10。滴答!手段呢?

apply(xs, 2, mean)#>       x1       x2       x3 
#> 1.843076 5.940343 9.399693

滴答!

以及偏差叉积矩阵?我在回购协议中留下了一些更简单的检查方法。如果你知道你的矩阵代数,我们可以这样验证它:

xs_d <- sweep(xs, 2, apply(xs, 2, mean)) # all deviation scores
t(xs_d) %*% xs_d#>           x1        x2        x3
#> x1 13.747618  8.726897  1.679592
#> x2  8.726897 14.509862 18.319109
#> x3  1.679592 18.319109 38.730283

完美!

我们现在可以在单位进入我们的实验时更新高度压缩的数据。这是让事情实时、大规模运转的关键。

从压缩数据回归

我们现在需要的是根据请求从压缩数据中获得回归结果。下面是如何发生这种情况的总结。

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

从压缩数据(离差叉积矩阵和样本大小)到最终回归结果的进展总结

我为此写了另一个 R 函数,compressed_regression(),你也可以在这里的 repo】中找到它。请注意,这比数据压缩更复杂。你需要非常了解矩阵形式的回归,这样才容易理解。存在矩阵运算(例如,%*%的乘法运算、t()的变换运算和solve()的求逆运算)以及从 t 分布中获取 p 值的需求(使用pt())。不过,对于数据科学家和工程师来说,实现这些应该不是问题。

无论如何,让我们来测试一下。假设我们有之前的压缩数据,并想在 x2 和 x3 上回归 x1:

compressed_regression(
  compressed_d$dcrossp,
  compressed_d$n
)#>   coefficient standard_error   t_value     p_value
#> 1   1.3571198      0.2666634  5.089261 0.001416338
#> 2  -0.5985403      0.1632186 -3.667107 0.007994773

这与 R 的内置回归模型相比如何?

summary(lm(x1 ~ x2 + x3))$coefficients[-1,]#>      Estimate Std. Error   t value    Pr(>|t|)
#> x2  1.3571198  0.2666634  5.089261 0.001416338
#> x3 -0.5985403  0.1632186 -3.667107 0.007994773

完美!对于实现来说,这就差不多了。

注意:我的方法要求在计算中使用截距,但计算不准确。为什么?计算它需要额外的工作,但我从未见过截距在推理/假设测试(相对于预测)中有用。如果您想试着弄清楚它,您将想要开始修改代码 在这里 添加占位符值。

回归和超越!

随着实时回归成为一种选择,它还打开了什么?下图显示了一些统计技术,这些技术可以从这里讨论的完全相同的压缩数据中进行。我不打算解释它们或它们的用途,但我相信有统计学背景的读者会很兴奋。不过,如果你有问题,请提出来,因为这些答案可能会成为一篇好的后续文章。

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

只是一些统计技术,可以使用我们的压缩数据

对于推理和数据探索,大规模使用这些方法是非常令人兴奋的事情!如果你想探索一些更复杂的方法,我可以推荐用接受协方差矩阵作为输入的 lavaan 包在 R 中进行测试。

嗯,我就知道这么多了。感谢阅读,我希望这对你有用。如果你有问题,有改进的想法,或者你想更进一步,请评论!

扩展您的时间序列预测项目

原文:https://towardsdatascience.com/scaling-your-time-series-forecasting-project-9b7cb31a75dc?source=collection_archive---------30-----------------------

这篇博客基于我在国际预测研讨会 ISF2020 上的演讲,题目是— 扩大销售预测的最佳实践。

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

照片由埃里克·麦克莱恩Unsplash 上拍摄

我们预测什么,为什么?

Wix.com,我们一直在使用时间序列预测模型作为我们预测 Wix 未来产品系列的数据科学项目的一部分。这让该公司做了两件重要的事情:(1)基于未来的收款进行更好的预算规划;(2)对股市的准确引导。

预测收藏是一项具有挑战性的任务(每一项预测任务都是如此),但我们一直在不断改进,并取得了惊人的成绩。在这篇博客中,我想分享一些我们对扩展预测项目的见解和实践。

从底层开始扩展—设计的重要性

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

我们的设计基于独立的构建模块协同工作

为了使我们的系统能够扩展并容纳更多的特征、更多的模型以及最终更多的预测者,我们将它划分为上述构件。每个构件都独立存在,但也知道如何与他人沟通和合作。每个问题的简短解释(希望我将来能更深入地描述它们,请在下面评论/DM with requests):

  • 数据源—用于访问和查询我们所有不同的表格和数据库。
  • 特征存储 —使用来自数据源的数据创建时序特征。给定所请求要素的列表,它将返回一个时序数据集。
  • 模型— 为清晰起见,本文引用了时间序列的开源模型。
  • 模型库 —模型的包装器,具有我们选择的超参数,并与源自特征库的数据集兼容。
  • 预测器 —从特征存储中获取数据集,从模型库中获取模型,并为我们所需的任务创建时间序列预测器。
  • 气流 DAGDAG%20as%20code.)在我们的系统中扮演着几个角色,在这种情况下(后面会有更多)我们指的是它安排预报员的运行(在我们的情况下是每天)

如上所述,这种设计支持扩展,同样重要的是,它支持快速实验,这是每个成功的数据科学项目的基础。

让您的朋友和数据更亲密

数据始终是每个数据科学项目中最重要的部分。当预测一个源于你的业务的时间序列时,你自然会想要添加你可用的“内部”信息。当你想给时间序列预测增加一些特性时,你必须确保你知道这些特性的未来值是多少(或者你也必须预测它们,这会增加很多复杂性)。也就是说,这些要素可能会随着时间的推移而发生变化,并且可能会出现不同类型的错误,从而极大地影响您的结果。

从下游错误到 上游 解决方案 —密切关注您的结果和数据是发现下游问题的关键(下一节将详细介绍),这里的重点是将这些转化为上游解决方案——基于我们的设计,我们能够在不同层上进行数据验证:

  • 数据源验证我们正在获取符合我们预期的最新数据。
  • 特征库验证特征是否符合我们对数据集的要求。
  • 气流 DAG 在运行预测器之前验证表格是否已更新以及之前的流程是否成功完成。

监控——我们如何适应业务变化

我们可以将业务变更分为两类:

  • 内部变化 —例如,新销售、新产品、价格变化等…
  • 外部变化——比如一个新的竞争对手,甚至是一个遥远的全球性疫情。

尽管变化可能非常不同,但适应这些变化需要经历相似的阶段:

  1. 发现变化 —这是我们进行监控的地方,我们不断跟踪我们的结果,并通过分析报告和电子邮件提醒(再次使用 DAG)将它们与过去的结果进行比较。
  2. 了解变化— 变化有趋势吗?我们能量化影响吗?它从哪里来的?这在内部和外部变化之间是非常不同的,它总是一个非常具有挑战性的任务。有时甚至理解我们并不完全理解这种变化也可能是我们的结论。
  3. 帮助模型理解变化— 这很大程度上取决于我们在前一阶段得出的结论,如果我们对变化及其未来行为有很好的理解,我们可能会通过某个特征将其引入模型。我们也可以决定看看这个模型是否会自己发现这个变化。

何时以及如何改进您的车型

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

micha Parzuchowski 在 Unsplash 上拍摄的照片

如果你仔细遵循,现在你已经有了一个相当好的系统,但是现在呢?你应该在什么时候改进你的模型,如何改进?请做好准备,这一部分会包括一些棘手的问题,而不是很多决定性的答案。

也就是说,一个答案可以解决所有问题——实验是处理这些问题的关键。

如果它没坏,就不要修理它?

预测器运行良好,但是您开始考虑一个应该非常相关的新功能——您应该添加它吗?

如果它开始发出吱吱声,然后修理它?

预测者的误差略有增加,你要回到上一节,标出一些可能的变化。但是你不确定预测者的这种变化会是什么结果——你应该添加它们吗?

什么时候改变是好的改变?

改变预测器或增加一个功能会增加复杂性和未来可能的技术债务(尽管我们的系统旨在减少这种情况)。这项新功能的影响是什么?随着时间的推移,这种影响会增加吗?改进是否足够显著,足以证明增加新功能或改变预测工具的成本是合理的?

追踪变化,改写历史

假设我们已经添加了新的变更,现在是时候回去监控变更并查看其效果了。但从某种意义上来说,我们现在是在比较两种不同的预测者(苹果和橙子?).一方面,我们希望看到我们的新预测者与旧预测者的对比,但另一方面,我们希望看到我们的新预测者与新预测者的对比,就好像它在一周前运行一样(据此是苹果与苹果的对比)。

为此,我们有两个表:

  • 真实历史基本上是当天生产的模型的实况结果。
  • 更新历史历史,就好像我们当前的模型和当前的特征和数据一直伴随着我们(我们为此运行所有以前的日期)。

结论

当业务快速变化时,扩展并保持预测系统的准确性是一项非常具有挑战性的任务,但是使用这些实践对我们来说已经走了很长的路,希望它也能为您服务。

使用计算机视觉的扫描文档分类

原文:https://towardsdatascience.com/scanned-document-classification-using-computer-vision-33a42d9e01f9?source=collection_archive---------6-----------------------

一种解决扫描文档分类问题的深度学习方法

在数字经济时代,银行、保险、管理、医疗和法律等部门仍然需要处理各种手写笔记和扫描文档。在业务生命周期的后期,手动维护和分类这些文档变得非常繁琐。对这些非机密文档进行简单而有意义的自动化宁滨将使维护和利用这些信息变得容易得多,并大大减少人工工作量。

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

扫描的文档

本案例研究的目标是开发一个基于深度学习的解决方案,可以自动对文档进行分类。

**数据:**对于本案例研究,我们将使用 RVL-CDIP(瑞尔森视觉实验室复杂文档信息处理)数据集,该数据集由 16 类 400,000 幅灰度图像组成,每类 25,000 幅图像。有 320,000 幅训练图像、40,000 幅验证图像和 40,000 幅测试图像。调整图像大小,使其最大尺寸不超过 1000 像素。该数据集的大小超过 200 GB。

**业务-ML 问题映射:**我们可以将业务问题映射为多类分类问题。当前数据集中有 16 个类别。我们需要仅基于扫描文档的像素值来预测文档的类别,这使得问题变得困难。 但是等等,为什么不能用 OCR 提取文字,应用 NLP 技术呢?是的,我们也对这个想法感到兴奋,但是低质量的扫描导致了较差的文本提取质量。在实际的商业场景中,我们也无法控制扫描的质量,因此依赖于 OCR 的模型即使经过适当的预处理也可能会泛化能力差。

**KPI 和业务约束:**数据集相当平衡。因此,我们选择准确性作为主要指标,微观平均 F1 分数作为次要指标,以惩罚错误分类的数据点。我们还使用混淆度量来验证模型的性能。对延迟的要求适中,对可解释性没有具体要求。

我们能从文档的像素强度和大小中得到什么吗?

让我们尝试使用一个方框图来显示文档的平均像素强度和大小

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

从方框图中,我们可以观察到某些类型的扫描文件的尺寸与其他文件大不相同,但也有重叠。例如,类别 13 和类别 9 的文件大小差别很大,但是类别 9 的大小与类别 4 和类别 6,7 重叠。

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

我们可以观察到,对于 75%的情况,类别 4 的平均像素强度位于 160–230 像素之间。但是对于大约 50%的情况,它也与类别 6 的平均像素值重叠。对于其他类,平均像素值重叠。

分析方法

为了解决眼前的问题,我们在扩充的数据上训练了卷积神经网络(CNN)。我们已经尝试在有和没有数据增强的情况下训练模型,结果是可比较的。

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

高级分析工作流程图

太好了!但是如何决定网络架构呢?你是如何训练网络的,因为数据一次装不下?

从头开始训练神经网络需要大量的时间和计算资源来收敛,为了避免这种情况,我们采用了迁移学习的帮助。我们从在 ImageNet 数据集上训练和在我们的数据集上重新训练的预训练网络的权重开始。针对这类问题的当前 SOTA 模型使用域间和域内迁移学习,其中图像被分成四个部分:页眉、页脚、左体和右体。首先使用预训练的 VGG16 模型来训练整个图像(域间),然后使用该模型来训练部分图像(域内)。

在这个实验中,我们采用了一种稍微不同的方法。我们没有使用 VGG16 进行域内迁移学习,而是训练了两个并行模型 VGG16 和 InceptionResNetV2,并使用这些模型的堆栈作为我们的最终模型。我们的假设是,由于这两个模型的不同架构,他们将学习图像的不同方面,并将它们堆叠将导致良好的概括。 但是我们如何选择这些型号呢? 这基本上来自交叉验证的结果。 我们尝试了各种网络架构,像 VGG16、VGG19、DenseNet、ResNet、InceptionNet,选出了最好的两个。

我们使用 keras 的 ImageDataGenerator 类来预处理和加载训练数据,而不是将整个数据一次性加载到内存中。

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

VGG16 网络的最终培训阶段

好的。但是如何处理超参数呢?

对于任何 CNN 的超级参数是:学习率,池大小,网络大小,批量大小,优化器的选择,正则化,输入大小等。

学习速率对神经网络的收敛起着重要的作用。深度学习问题中使用的损失函数是非凸的,这意味着在存在几个局部最小值和鞍点的情况下,找到全局最小值不是一件容易的事情。如果学习率太低,它将缓慢收敛,如果学习率太高,它将开始振荡。在本案例研究中,我们使用了一种称为“循环学习率”的技术,其目的是以这样一种方式训练神经网络,即对于每个训练批次,学习率以循环方式变化。

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

但是它为什么会起作用呢?在 CLR 中,我们在一个阈值内改变学习率。周期性的较高学习率有助于克服它是否停留在鞍点或局部最小值。

对于其他超参数,我们开发了定制的效用函数来检查哪种配置效果更好。假设在 10 个时期之后,我们得到了 47%的准确度。我们将在那时使用该模型作为测试基线,并使用效用函数来检查哪个配置集(即 batch _ size/optimizer/learning _ rate)将在未来时代产生更好的准确性。

结果

我们使用 VGG16 模型实现了 90.7%的准确率,使用 InceptionResNetV2 实现了 88%的准确率。上述两个模型的比例叠加模型获得了 97%的训练准确率和 91.45%的测试准确率。

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

你可以在这里找到完整的实现。

引用:

  1. A.W. Harley,A. Ufkes,K. G. Derpanis,“用于文档图像分类和检索的深度卷积网的评估”,ICDAR,2015 年。
  2. https://arxiv.org/abs/1506.01186
  3. https://www . research gate . net/publication/332948719 _ Segmentation _ of _ Scanned _ Documents _ Using _ Deep-Learning _ Approach

使用 DeepAI 扫描旧的黑白胶片底片并将其转换为彩色图像

原文:https://towardsdatascience.com/scanning-and-converting-old-black-and-white-film-negatives-to-color-images-using-deepai-5eb9c549d34a?source=collection_archive---------27-----------------------

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

封面照片由Grzegorz Mleczek

这篇文章与我之前关于(生物)医学的文章无关,但是使用了我在博士研究期间学到的一些 Python 技巧。它没有深入研究深度学习背后的理论,而是展示了一个如何使用该技术的实际例子。我在本教程中使用 Adobe Photoshop 和 Lightroom,如果你成功地使用了开源软件,请在评论中告诉我。

世界大部分地区再次陷入困境,许多人又回到了家中。如果你正在寻找一件不涉及任何其他人的事情,你可能会在本教程中找到一些灵感。

我的祖父母给了我一些旧的黑白底片,这篇博客描述了我用 DeepAI 扫描、数字化和着色的过程:

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

之后 vs 之前

扫描胶片底片

我用我的 DSLR(尼康 D3500 和 Samyang 135 mm f/2.0 镜头)、一个三脚架、我的手机作为背光和一个纸箱扫描了胶片底片,我剪下这个纸箱以便底片可以放进去。如果你没有 DSLR,你可以用你的手机作为相机,笔记本电脑屏幕作为背光,但不要指望惊人的效果(使用一个捕捉原始文件的应用程序,最好是一个三脚架,以保持尽可能低的 ISO。我在下面添加了 DSLR 与小米 9T 相机的对比。

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

DIY 底片扫描仪,智能手机放在盒子背面。胶片和智能手机之间需要有一些距离,否则你最终会得到图像中的像素模式。

我的相机设置是 ISO100,f/4 和 1/8 秒快门速度(确保你拍摄的是 RAW 而不是 JPG),结果是这样的图像:

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

反转负像

每张照片都是不同的,所以你必须尝试什么是有效的。我是从亚历克斯·伯克的指导开始的。

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

扫描、裁剪和编辑 B&W

lightroom 预设可以在 my Github 上找到。

给 B&W 图像着色

现在我们进入最有趣的部分:使用深度学习将 B&W 图像转换为彩色图像。

互联网上有很多选择,但大多数要么很贵,要么没那么好(或者两者兼而有之)。我开始在 Photoshop 上使用新的神经过滤器的“着色”功能,但结果很糟糕。

在更多的谷歌搜索之后,我找到了 DeepAI。不幸的是,每个大于 1200x1200 像素的图像都会被缩小,如果您在工作流程的其余部分使用 RAW 文件和高分辨率图像,这是一个遗憾。据我所知,deepAI 的付费版本也不支持更大的图像,如果他们支持,请告诉我。

幸运的是,DeepAI 允许使用 API 提交作业。换句话说,如果我们将图像分割成 1200x1200 像素的重叠拼贴,给这些拼贴着色,然后将它们拼接在一起,应该不会有任何质量损失。分割图像可以用这个代码来完成:

一旦所有图像被分割,我们可以使用 Python 将每个单独的图像块提交给 DeepAI:

在 Photoshop 中自动合并单个帧:“文件”>“自动”>“Photomerge ”,并根据图像执行一些额外的调整(对比度、鲜明度等):

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

用我的智能手机代替我的 DSLR 得到的结果要差得多,但是我没有优化这个过程:

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

所有代码都在我的 GitHub 上。如果你发现 DeepAI 使用的模型有任何偏见,请发推文或电子邮件告诉他们。

玩得开心,呆在家里,保持社交距离,阻止冠状病毒的传播。

近红外光谱中的散射校正和异常值检测

原文:https://towardsdatascience.com/scatter-correction-and-outlier-detection-in-nir-spectroscopy-7ec924af668?source=collection_archive---------22-----------------------

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

人工智能领域的最新进展已经引起了 NIR 传感器数据和机器学习技术的集成,以实现这些结果。在这篇文章中,近红外传感器与电脑接口和样品进行扫描。我们对每个样本进行了十次扫描,扫描时间为十秒钟,以减少误差并包括样本的所有部分。在我们的案例中,扫描结果是分散的,并且由于光线、工作距离和扫描过程中的人为错误的变化,我们有异常值。为了减少散射和消除异常值,我们对近红外(NIR)数据实施了乘性散射校正(MSC)和标准正态变量(SNV)。

数据预处理是在近红外光谱和大多数光谱分析中建立大多数类型校正模型的基本步骤。通过精心设计的预处理步骤,可以大大提高模型的性能。

原始数据;样本 1 和样本 2 包含重复读数

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

图 1 .具有 10 个重复读数的样品 1 的原始吸收光谱。x 轴:波长,y 轴:吸光度单位

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

图 2 .具有 10 个重复读数的样品 2 的原始吸收光谱。x 轴:波长,y 轴:吸光度单位

Python 中的乘法散射校正

MSC 需要一个参考光谱作为开始。理想的参考光谱是没有散射效应的光谱。在实践中,我们将样本数据的平均值作为参考。这是 MSC 和 SNV 最重要的区别。

现在,正如你可以收集到的,得到一个没有不必要的散射效应的光谱并不容易,不是在我们感兴趣的所有波长上。因此,如果数据表现良好,我们可以将平均光谱作为我们所追求的理想光谱的近似。颗粒尺寸和路径长度的影响会因样品不同而随机变化,因此平均值会合理地减少这些影响,至少在这些影响真正随机的近似值中是如此。这是 MSC 背后的主要假设。

让我们认为 Xm 是平均谱。我们首先相对于平均光谱回归每个光谱 Xi。这是通过普通最小二乘法 Xi ≈ ai + biXm 完成的,然后我们计算校正的频谱 Xmsc = (Xi-ai)/bi

def msc(input_data, reference=None):
    """
        :msc: Scatter Correction technique performed with mean of the sample data as the reference. :param input_data: Array of spectral data
        :type input_data: DataFrame :returns: data_msc (ndarray): Scatter corrected spectra data
    """ eps = np.finfo(np.float32).eps
    input_data = np.array(input_data, dtype=np.float64)
    ref = []
    sampleCount = int(len(input_data))

    # mean centre correction
    for i in range(input_data.shape[0]):
        input_data[i,:] -= input_data[i,:].mean()

    # Get the reference spectrum. If not given, estimate it from the mean # Define a new array and populate it with the corrected data    
    data_msc = np.zeros_like(input_data)
    for i in range(input_data.shape[0]):
        for j in range(0, sampleCount, 10):
            ref.append(np.mean(input_data[j:j+10], axis=0))
            # Run regression
            fit = np.polyfit(ref[i], input_data[i,:], 1, full=True)
            # Apply correction
            data_msc[i,:] = (input_data[i,:] - fit[0][1]) / fit[0][0]

    return (data_msc)

此外,我们可以绘制 MSC 值

def linegraph(df,name="data"):
    """
        :linegraph: Plot absorbance unit vs wavelength number graph :param df: Spectral data containing absorbance units and wavelengths
        :type df: ndarray :returns: Absorbance unit vs wavelength graph
    """ # Read the spectral data file
    neospectraDataFile= neoSpectraSensorData.getNeospectraDataFile() # Get the wavelengths
    wavelengths =
    np.array(neospectraDataFile.columns).astype(np.float)
    x = wavelengths
    y = df
    ys = [i for i in y] #put into the format for LineCollection # We need to set the plot limits, they will not autoscale
    fig, ax = plt.subplots(figsize=(10,10), dpi=150)
    ax.set_xlim(np.min(x), np.max(x))
    ax.set_ylim(np.min(ys), np.max(ys)) # Make a sequence of x,y pairs
    line_segments = LineCollection([np.column_stack([x, y]) for y in ys],linewidths=(0.5),linestyles='solid')
    ax.add_collection(line_segments)
    ax.set_title('Absorbance unit graph of '+name, fontsize = 15)
    ax.set_xlabel(r'Wavenlength', fontsize=15)
    ax.set_ylabel('Absorbance', fontsize=15)

    return(plt.show())

理学硕士的结果:

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

图 3 .样品 1 的 MSC 校正数据图;x 轴:波长,y 轴:吸光度单位

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

图 4 .样品 2 的 MSC 校正数据图;x 轴:波长,y 轴:吸光度单位

Python 中的标准普通变量

与 MSC 不同,SNV 校正是在每个单独的光谱上进行的,不需要参考光谱。SNV 修正也可以分为两个概念步骤。

通过去掉其均值来对每个 Xi 频谱进行平均。将每个以平均值为中心的谱除以它自己的标准偏差:Xisnv =(Xi-Ximean)/sigma

def snv(input_data):
    """
        :snv: A correction technique which is done on each
        individual spectrum, a reference spectrum is not
        required :param input_data: Array of spectral data
        :type input_data: DataFrame

        :returns: data_snv (ndarray): Scatter corrected spectra
    """

    input_data = np.asarray(input_data)

    # Define a new array and populate it with the corrected data  
    data_snv = np.zeros_like(input_data)
    for i in range(data_snv.shape[0]): # Apply correction
    data_snv[i,:] = (input_data[i,:] - np.mean(input_data[i,:])) / np.std(input_data[i,:])

    return (data_snv)

通过调用上面的线图函数,进一步绘制 SNV 图

SNV 的结果:

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

图 5 是样品 1 的 SNV 校正数据图;x 轴:波长,y 轴:吸光度单位

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

图 6 样品 2 的 SNV 校正数据图;x 轴:波长,y 轴:吸光度单位

对原始数据应用 MSC 和 SNV 后的结果:

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

图 7. a .原始光谱 b. SNV 光谱 c .样品 1 的 MSC 光谱

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

图 8. a .原始光谱 b. SNV 光谱 c .样品 2 的 MSC 光谱

现在,结果被分散校正。MSC 中的异常值可以通过使用简单的 z 分数技术来消除。

分散校正数据的异常值检测

MSC(原始数据)的异常值相当低。因此,如果光谱中有超过 40%的点是异常值,我们就认为它是异常值

zscore =(individual sample-individual sample . median())/individual sample . STD()

定义 z 得分函数:

def zscorefunction(arrayMatrix, threshold=1):
    """
        :zscorefunction: Compute the z score of arrayMatrix     
        (Individual sample), relative to the sample median and   
         standard deviation. :param arrayMatrix: Array file containing spetral data of   
        one sample
        :type arrayMatrix: array :returns: The coordinates of the points which are 
        considered to be outliers. We are interested in x coordinate of the results. 
        Here, In our case, the x coordinate is the spectra number. - Example of the output:: output:(array([1,2,1,2,3,4]), array([1,5,8,70,85,143]))

            Read as, (spectra number, point in the spectra) 
            (1,1),(2,5),(1,8),(2,70),(3,85) and (4,143). 

            [1,2,1,2,3,4] are the spectra number of the sample 
            and [1,5,8,70,85,143] are the point in the spectra

            The 1st and 8th wavelength point in the 1st spectra 
            are outliers.similarly, The 5th and 70th wavelength   
            point in the 2nd spectra are outliers """
    # A z-score is the number of standard deviations away from a  
    mean for a data point. 
    zscore = (arrayMatrix - np.median(arrayMatrix))/   
    arrayMatrix.std()

    return (np.where(np.abs(zscore) > threshold))

z 得分函数返回被视为异常值的点的坐标。

def deleteOutliersSummary(X,Y,summary = True):
    """
        :deleteOutliersSummary: Calls the z score function to get   
        the outlier spectra numbers.We are interested in x 
        coordinate of the results. In our case, the x coordinate is 
        the spectra number.So, we apply the counter function on the 
        result to get the total count of outlier points for 
        spectra.and delete the spectra if the spectra has 75% of 
        its points as outliers :param X: Training spectral file (usually MSCTrain)
        :type X: array :param Y: Training target file      
        :type Y: array :returns: individualX (list) and y (list), 
        New spectral & target train files with outliers eliminated """ # A z-score is the number of standard deviations away from a 
    mean for a data point. 

    # We define a deleteSpectra where we store the Spectra number 
    with more than 75% (you can change this based on your MSC data)
    points as outliers deleteSpectra = []
    individualX = neoSpectraSensorData.getIndividualSamples(X)
    y= getMeanData.getMeanTarget(Y)
    out = 0
    noOut = 0
    sampleCount = len(individualX) for i in range(0,sampleCount):
        # call the function
        x = zscorefunction(individualX[i])[0]
        # print sample number and spectra number with its   
        corresponding number of outlier points

        if summary == True:
            # Counter gives the spectra number(index): number of  
            outlier points
            print("\nSAMPLE",i+1)
            print(Counter(x)) threshold = 0.75*X[1].shape[0]
        for j in range(0,individualX[i].shape[0]):
            # If the sepctra contains more than 75% of points as   
            outliers, delete the spectra

            if (Counter(x)[j] > threshold):
                deleteSpectra.append(j) # Delete the outlier spectra from the sample
        individualX[i] = np.delete(individualX[i], deleteSpectra, 0)
        y[i] = np.delete(y[i], deleteSpectra, 0)

        # If the sample has no outliers in all it's spectra then 
        display "No outliers detected"
        if deleteSpectra != []:
            out +=1
        else:
            noOut +=1

        if noOut == sampleCount:
            print("No outliers detected")

        if summary == True:
            print ("Delete Spectra:",deleteSpectra)
        del deleteSpectra[:]

    return(individualX,y)

输出:

计数器给出光谱数(指数):异常点的数量

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

从 MSC 数据中剔除异常值后绘制数据:

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

图 9 .从样品 1 的 MSC 数据中消除异常值后的图

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

图 10 .消除样本 2 的 MSC 数据上的异常值后的图

这里您可以看到,在经过散射校正的数据中,异常值被消除了。现在,我们可以使用这些数据来建立模型。

最终结果:

原始数据—原始数据的异常值剔除

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

图 11 .原始数据— MSC 数据—样本 1 的 MSC 异常值消除

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

图 12 .原始数据— MSC 数据—样本 2 的 MSC 异常值消除

谢谢你的时间。希望对你有帮助。

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

参考:https://nirpyresearch . com/two-scatter-correction-techniques-NIR-spectroscopy-python/

散点图:用 matplotlib、seaborn 和 pandas 绘制实验结果

原文:https://towardsdatascience.com/scattered-boxplots-graphing-experimental-results-with-matplotlib-seaborn-and-pandas-81f9fa8a1801?source=collection_archive---------9-----------------------

利用 python 可视化库绘制散点箱线图

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

Ciaran 库尼使用 Matplotlib 绘制。

Matplotlib、Seaborn 和 Pandas 的联合力量为数据科学家和工程师提供了丰富的资源,用于数据可视化和结果呈现。然而,对于初学者来说,将可用的工具操作成他们想象的美丽图形并不总是容易的。我在自己的工作(脑机接口博士学位)中发现,我获取的数据并不总是以直接适用于使用某些功能的方式进行组织,定制可能很困难且耗时。此外,选择最佳类型的图表来显示您的结果可能需要深思熟虑,并且经常需要反复试验。

散点图是一种非常有效的交流结果的方式,既能吸引观众的眼球,又能给观众提供信息。箱线图显示了结果的分布,显示了中间值、四分位距和其他与数据的偏斜度和对称性相关的因素。你可以在这里找到了解 boxplots 的有用教程:https://towards data science . com/understanding-box plots-5e 2 df 7 bcbd 51

使用散点图将特定的数据点叠加在箱线图上,是以一种吸引人的方式描绘结果的一种极好的方式,这种方式可以使读者很容易理解所呈现的内容。在这篇文章的剩余部分,我将逐步完成创建散点图的过程,提出一些定制的想法,并展示如何同时绘制多个图形。

Scatted box plots

在导入所需的 Python 包之后,我创建了一个小型数据集,表示可能从包含结果(例如,使用不同算法的分类结果)的 excel 文件中读入的数据类型。这里,我有四列数据,每一列包含从 65 到 95 的二十个值(类似于分类精度)。每列还有一个基本标题。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as snsdataset = np.random.default_rng().uniform(60,95,(20,4))
df = pd.DataFrame(dataset, columns=['data1','data2','data3','data4'])
df.head()

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

excel 格式的随机样本数据。

加载数据后,我通常喜欢做的一件事是将 dataframe 列重命名为更具描述性的名称,以便在绘制数据时使用。在这里,我修改了标题以表示实验编号。

for n in range(1,df.columns.shape[0]+1):
    df.rename(columns={f"data{n}": f"Experiment {n}"}, inplace=True)
df.head()

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

带有编辑过的列名的示例数据。

编辑完列名后,生成一个初始的散点图就非常容易了。首先,我为结果(val)、要绘制的数据名称(names)和要添加到散点图数据点的抖动(xs)创建列表变量。注意:抖动被添加到数值中,以提供将覆盖在箱线图顶部的数据点的分隔。然后,我使用 for 循环来遍历数据帧中不同数据列的范围,以组织绘图所需的数据。

vals, names, xs = [],[],[]for i, col in enumerate(df.columns):
    vals.append(df[col].values)
    names.append(col)
    xs.append(np.random.normal(i + 1, 0.04, df[col].values.shape[0]))  # adds jitter to the data points - can be adjusted

使用这些数据容器来绘制初始的散点图是非常简单的。matplotlib boxplot 函数只需要上面收集的 val 和 names 数据。散点图稍微复杂一点,但是只需要一个带有 python zip 关键字的 for 循环来遍历抖动值、数据点和调色板。

plt.boxplot(vals, labels=names)palette = ['r', 'g', 'b', 'y']for x, val, c in zip(xs, vals, palette):
    plt.scatter(x, val, alpha=0.4, color=c)plt.show()

只需几行简短的 python 代码,就可以生成一个描述结果分布的散点图:

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

最简风格的箱线图(来源:恰兰·库尼使用 Matplotlib)。

然而,这并不是一个非常漂亮的图形,所以我通常会尝试做一些事情来定制它,使它更有吸引力,希望更具描述性。我相信你们很多人都知道,seaborn 提供了一些主题,可以用来概括你的情节风格。目前,我更喜欢“白色网格”——但这种情况经常改变。此外,boxplot 函数接受多个可自定义的属性参数,以帮助您完善演示文稿。我在下面插入了一些选项,包括调整框的颜色、线条的粗细和中值标记的样式。

我要提醒你的是,分散的箱线图可能会做得过火,所以不要让图表过多,也不要使用太多冲突的颜色。

##### Set style options here #####
sns.set_style("whitegrid")  # "white","dark","darkgrid","ticks"boxprops = dict(linestyle='-', linewidth=1.5, color='#00145A')
flierprops = dict(marker='o', markersize=1,
                  linestyle='none')
whiskerprops = dict(color='#00145A')
capprops = dict(color='#00145A')
medianprops = dict(linewidth=1.5, linestyle='-', color='#01FBEE')

用吸引人的配色方案定制您的图是以引人入胜的方式呈现结果的一个非常重要的方面。你可以在上面的代码片段中看到,我使用十六进制颜色代码来定制属性。虽然 Matplotlib 提供了颜色选项,但我最近开始使用网站https://htmlcolorcodes.com/来高精度地选择我想要的颜色。在这里,我选择了 4 个十六进制颜色代码用于散点图点。

palette = ['#FF2709', '#09FF10', '#0030D7', '#FA70B5']plt.boxplot(vals, labels=names, notch=False, boxprops=boxprops, whiskerprops=whiskerprops,capprops=capprops, flierprops=flierprops, medianprops=medianprops,showmeans=False) 

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

带有附加样式的箱线图(来源:恰兰·库尼使用 Matplotlib)。

现在我可以给剧情添加一些可选的特性(**注:**这只是一个演示。在实践中,尽量避免过度填充图表,因为这会降低可读性)。让我们添加一条对应于 y 轴上某点的水平线。这种东西可以用来表示某个阈值或者某个模型的概率分类精度。

plt.xlabel("Categorical", fontweight='normal', fontsize=14)
plt.ylabel("Numerical", fontweight='normal', fontsize=14)sns.despine(bottom=True) # removes right and top axis lines
plt.axhline(y=65, color='#ff3300', linestyle='--', linewidth=1, label='Threshold Value')
plt.legend(bbox_to_anchor=(0.31, 1.06), loc=2, borderaxespad=0., framealpha=1, facecolor ='white', frameon=True)

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

增加了 x/y 标签、消旋和图例(来源:Ciaran 库尼,使用 Matplotlib)。

现在你有了它,一个快速简单的方法来产生一个分散的箱线图,它可以帮助你的结果向观众展示。下面我将这个功能扩展到同时绘制多个箱线图。

正在策划

有些情况下,单个箱线图不足以传达你想要呈现的结果。也许一个实验有多个条件,或者在几个不同的数据集上评估了几个独立的机器学习分类器。在这种情况下,我们可以使用 matplotlib 的子绘图函数来生成理想的图形。

事实上,实现这一点所需的大部分代码只是我们上面实现的代码的简单复制,但是完成这些步骤仍然是有用的。第一件事是创建第二个数据集。这里,我有效地使用了和以前一样的代码,但是我调整了数据点的范围,这样我们可以在两个图中看到这个效果。

dataset = np.random.default_rng().uniform(50,86,(20,4))
df_1 = pd.DataFrame(dataset, columns=['data1','data2','data3','data4'])
df_1.head()

然后,只需像以前一样完成这些步骤,将数据处理成我们需要的格式。唯一的区别是,现在我们是针对两个数据集进行的。

for n in range(1,df.columns.shape[0]+1):
    df.rename(columns={f"data{n}": f"Experiment {n}"}, inplace=True)
    df_1.rename(columns={f"data{n}": f"Experiment {n}"}, inplace=True)namesA, valsA, xsA = [], [], []
namesB, valsB, xsB = [], [], []for i, col in enumerate(df.columns):
    valsA.append(df[col].values)
    namesA.append(col)
    xsA.append(np.random.normal(i + 1, 0.04, df[col].values.shape[0]))for i, col in enumerate(df_1.columns):
    valsB.append(df_1[col].values)
    namesB.append(col)
    xsB.append(np.random.normal(i + 1, 0.04, df_1[col].values.shape[0]))

有了形状中的数据,我们就可以用两个轴对象创建一个 matplotlib 子图对象。接下来,我们分别在 ax1ax2 上绘制来自两个数据集的方框和数据点。

fig, (ax1, ax2) = plt.subplots(nrows=2, ncols=1, figsize=(5, 5))bplot1 = ax1.boxplot(valsA, labels=namesA, notch=False,     showmeans=False)bplot2 = ax2.boxplot(valsB, labels=namesB, notch=False, 
            showmeans=False)palette = ['#33FF3B', '#3379FF', '#FFD633', '#33FFF1']for xA, xB, valA, valB, c in zip(xsA, xsB, valsA, valsB, palette):
    ax1.scatter(xA, valA, alpha=0.4, color=c)
    ax2.scatter(xB, valB, alpha=0.4, color=c)

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

多个分散的箱线图同时绘制(来源:Ciaran 库尼使用 Matplotlib)。

你可以看到数据已经被正确地绘制出来,稍加努力,你甚至可以看出两者之间的差异。当然,如果我们试图描述两个图之间数据的一些重要方面,添加一点颜色来区分这两个图会很有帮助。下面,我修改了箱线图属性,加入了独特的蓝色和红色方案,以帮助区分数据。

boxpropsA = dict(linestyle='-', linewidth=1, color='#33B3FF')
flierpropsA = dict(marker='o', markersize=10,
                  linestyle='none', markeredgecolor='g')
whiskerpropsA = dict(color='#33B3FF')
cappropsA = dict(color='#33B3FF')
medianpropsA = dict(linewidth=1, linestyle='-', color='#33B3FF')  # colors median lineboxpropsB = dict(linestyle='-', linewidth=1, color='#FF4533')
flierpropsB = dict(marker='o', markersize=10, linestyle='none', markeredgecolor='g')
whiskerpropsB = dict(color='#FF4533')
cappropsB = dict(color='#FF4533')
medianpropsB = dict(linewidth=1, linestyle='-', color='#FF4533')  # colors median line

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

用颜色区分你的数据(来源:Ciaran 库尼使用 Matplotlib)。

最后,让我们看一两个小的补充,使图表更可读,更有吸引力。和以前一样,我将样式设置为 seaborn whitegrid。然后我使用 for 循环来设置两个支线剧情的某些属性。其中之一是移除内部 x 标签,只留下外部标签。我还设置了一个常见的 y 轴范围和一条指示某个阈值的水平线以及一个 y 轴标签。

sns.set_style("whitegrid")
for ax in fig.get_axes():
    ax.label_outer()
    sns.despine(ax=ax)
    ax.set_ylim(50, 100)
    ax.axhline(y=65, color='#ff3300', linestyle='--', linewidth=1,      label='Threshold')fig.text(0.04, 0.5, 'Classification accuracy (%)', ha='center', va='center', rotation='vertical', fontsize=12)

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

双图散点图的最终版本(来源:希兰·库尼使用 Matplotlib)。

你可以看到这些增加的效果。特别是,y 轴界限和水平线的结合使绘制的数据分布存在显著差异变得非常明显。如果你将它与第一个双盒图进行比较,你会发现现在已经做出了这些改变,推断信息要容易得多。

用于编写这篇文章的代码可在此处获得:https://github . com/cfcooney/medium _ posts/blob/master/scattered _ box plots . ipynb

我希望它能帮助你们中的一些人更好地展示你们的成果。

在 Windows 平台上调度 Python 脚本

原文:https://towardsdatascience.com/schedule-your-python-scripts-on-windows-platform-4c0b756b81e9?source=collection_archive---------38-----------------------

触手可及的生产力

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

法比安·阿尔伯特在 Unsplash 上的照片

在开始本教程之前,让我们想一个场景:

您的经理给你打电话,告诉你,“*客户希望在 IST 时间每天早上 6 点之前刷新数据。请更改您的轮班时间,并确保客户端批处理完成后脚本执行”。*这是什么意思?这意味着,从今天开始,你将开始失去宝贵的睡眠、与家人和朋友在一起的时间,最重要的是,你将在一天中效率最低的时候执行一些随机脚本。

如果以上听起来很熟悉,你想把自己从这样的噩梦中拯救出来,请继续阅读。在本教程中,我们将学习在 Windows 平台上调度 Python 脚本。

首先要做的事情

要实现我们的目标,我们需要三样东西:

  • Python 脚本—对于本教程,我已经编写了一个小的 Python 代码,让从我的 Windows 文件夹位置读取一个“CSV”文件。这个“CSV”文件包含 2 列,每列都有随机数。代码添加两个列以创建一个新的列并且将 CSV 文件的这个新版本保存在相同的文件夹位置。
**#### Importing the required library**
import pandas as pd**#### Reading csv file**
df = pd.read_csv("C:\\Ujjwal\\New_File_V1.csv")**#### Adding 2 columns**
df["Third_Column"] = df["Randome Numbers 1"] + df["Random Numbers 2"]**#### Exporting the data to same location**
df.to_csv("C:\\Ujjwal\\New_File_V2.csv",index = False)
  • 批处理文件 —批处理文件是一个带有“.”的脚本文件。蝙蝠”扩展。这些文件通常保存为简单的文本文件,包含可以在命令行界面(命令提示符)上执行的命令。当命令提示符执行这些文件时,它通读文件中写入的命令,然后逐行执行它们**。**
  • 调度器 —最后但同样重要的是,我们需要一个调度器,它能够读取批处理文件并且在设定的时间执行其中写入的命令。为此,我们将使用 Windows 的任务调度器会派上用场。

准备批处理文件

在上一节中,我们已经分享了我们计划安排的示例 Python 代码。所需的第二个组件是一个批处理文件。出于我们的目的,批处理文件将包含 2 个命令:

  • Python 应用的位置——这是 Python 应用()。exe”扩展名,用于执行脚本。在我们的批处理文件中,我们将提供这个应用程序的位置作为第一个命令。在我的系统上,这个位置如下:
**#### Location of Python Executable**
C:\Users\Ujjwal\Anaconda3\python.exe
  • Python 脚本的位置——这是您想要调度的脚本。我们将提供这个脚本的位置作为批处理文件的第二个命令。鉴于我们正在使用 Python 脚本,请确保文件夹位置中的反斜杠被正斜杠替换。我的脚本在 Windows 中的位置如下。
**#### Windows Location**
C:\Ujjwal\Executable.py**#### Backslash replaced with forward slash**
C:/Ujjwal/Executable.py
  • 最终脚本 —最终的批处理脚本如下所示。在任何 Windows 位置,将该脚本保存在扩展名为. BAT 的文本文件中。
**#### Final Batch Script**
C:\Users\Ujjwal\Anaconda3\python.exe "C:/Ujjwal/Executable.py"

设置时间表

在这一步中,我们将设置计划来定期执行我们的任务。逐步过程如下:

  • 打开 Windows 任务计划程序 —进入 Windows 搜索,搜索任务计划程序,并将其打开。任务计划程序界面如下所示:

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

任务计划程序界面(图片由作者提供)

  • 创建新任务 —点击右窗格中的创建基本任务,创建新任务。将弹出一个新窗口,提示您填写任务名称和描述。界面将如下所示:

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

创建基本任务的新窗口(作者图片)

  • 选择周期 —填写任务名称和描述详细信息后,点击下一步。现在,系统会提示您选择触发选项,在这里我们可以设置任务的周期。出于我们的目的,我们选择每日执行。触发器选项的完整列表如下:

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

计划周期(图片由作者提供)

  • 选择计划时间 —选择任务频率后点击下一步。现在,系统将提示您选择希望触发计划的特定时间。界面屏幕如下所示:

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

选择计划时间(作者图片)

  • 创建动作 —选择执行时间后点击下一步。在这一步中,调度器将提示您选择想要调度的动作。选择启动程序。界面将如下所示:

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

选择动作(作者图片)

  • 选择批处理文件 —选择所需动作后点击下一步。现在,应用程序接口将询问您想要调度的节目的位置。选择我们在上一节中创建的批处理文件。应用程序屏幕将如下所示:

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

选择批处理文件位置(按作者排列的图像)

  • 最后 —就这样,点击下一步,完成。您的 Python 脚本将在每天的特定时间执行。

结束语

我相信有了上面的解决方案,你可以自动完成所有重复的任务。

我希望这篇教程是有启发性的,并且你学到了一些新的东西。请评论并分享您的反馈。

下次请继续关注更多有趣的话题。在此之前:

快乐学习!!!!

Django 和 Heroku 安排的网页抓取

原文:https://towardsdatascience.com/scheduled-web-scraping-with-django-and-heroku-e832e1363c7a?source=collection_archive---------3-----------------------

创建一个 django 应用程序,每天抓取求职公告板

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

我们经常需要大量的训练数据来进行机器学习,网页抓取可以是获取这些数据的一种方式。

但在过去,有一家公司是我非常想去工作的。他们目前没有数据科学的职位,但他们一有,我就想申请。

解决办法?每天查看他们的工作公告板,这样每当有新工作发布时,我都会得到通知。

让我们构建一个简单的 django 应用程序,部署到 Heroku,并每天创建一个工作公告板。

设置应用程序

为应用程序创建目录,并将cd放入其中。

mkdir jobs && cd jobs

在您喜欢的任何代码编辑器中打开它。我用的是 Sublime。

创建并启动我们的虚拟环境。然后安装我们需要的软件包。

python -m venv env
source env/bin/activate
pip3 install django psycopg2 django-heroku bs4 gunicorn

创建项目(django 版本的 web 应用程序)。

django-admin startproject jobs

cd进入项目,创建一个 app 进行抓取。

cd jobs
django-admin startapp scraping

创建工作模型

我们只需要在这个应用程序中定义一个模型,一个作业模型。这代表我们将收集的工作。

用以下内容覆盖/scraping/models.py

from django.db import models
from django.utils import timezoneclass Job(models.Model):
    url = models.CharField(max_length=250, unique=True)
    title = models.CharField(max_length=250)
    location = models.CharField(max_length=250)
    created_date = models.DateTimeField(default=timezone.now) def __str__(self):
        return self.title class Meta:
        ordering = ['title'] class Admin:
        pass

/scraping/admin.py中注册您的模型。这允许我们在 Django 的默认管理面板中查看记录(我们很快会谈到这一点)。

from scraping.models import Job
admin.site.register(Job)

scraping添加到/jobs/settings.py中已安装的应用中。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'scraping'
]

设置数据库

设置数据库。我喜欢 postgres,所以我们要用它。

此时,确保您之前已经在 mac 上用brew安装了 postgres 并启动了它(这超出了本文的范围)。

在命令行上为此项目创建一个数据库。您可以使用下面的命令打开 postgres 控制台。

psql -d template1

创建用户和数据库,然后退出。

create user django_user;
create database django_jobs owner django_user;
\q

/jobs/settings.py中,更新DATABASES。在其他框架中,您可能希望专门针对开发环境来确定范围,但是在这里我们不会担心这个问题。不管怎样,它在 Heroku 上会起作用的(我们很快就会到达那里)。

注意,这些是我们在上面创建的用户名和数据库名。

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'django_jobs',
        'USER': 'django_user',
        'HOST': '',
        'PORT': ''
    }
}

创建迁移,并从命令行迁移数据库。

python manage.py makemigrations
python manage.py migrate

这将创建一个名为scraping_job的表。这是一个 django 名称空间约定,因为它属于scraping应用程序。

现在创建一个超级用户,并在命令行中给它一个密码。

python manage.py createsuperuser --email admin@example.com --username admin

测试当前应用

到目前为止,我们已经做了一些工作,但我们不知道是否有任何工作。我们先测试一下,然后再进一步。

在命令行上。

python manage.py runserver

然后在浏览器中导航至http://127 . 0 . 0 . 1:8000/admin。使用您刚刚创建的超级用户登录。

登录后,点击“抓取”下的“作业”,然后点击右上方的“添加作业”。现在填写一些编造的信息,然后点击“保存”。如果您可以看到您创建的作业,那么到目前为止一切都正常!

自定义 django-admin 命令

我们将设置一个定制的 django-admin 命令来抓取工作板。这是我们将在基础架构级别自动安排的内容,以便实现自动抓取。

/scraping模块中,创建一个名为/management的目录,在/management中创建一个名为/commands的目录。然后在/commands中创建 2 个 python 文件,_private.pyscrape.py

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

不在此处显示所有内容

将此代码放入scrape.py

from django.core.management.base import BaseCommandfrom urllib.request import urlopen
from bs4 import BeautifulSoup
import jsonfrom scraping.models import Jobclass Command(BaseCommand):
    help = "collect jobs" # define logic of command
    def handle(self, *args, **options): # collect html
        html = urlopen('[https://jobs.lever.co/opencare'](https://jobs.lever.co/opencare')) # convert to soup
        soup = BeautifulSoup(html, 'html.parser') # grab all postings
        postings = soup.find_all("div", class_="posting") for p in postings:
            url = p.find('a', class_='posting-btn-submit')['href']
            title = p.find('h5').text
            location = p.find('span', class_='sort-by-location').text # check if url in db
            try:
                # save in db
                Job.objects.create(
                    url=url,
                    title=title,
                    location=location
                )
                print('%s added' % (title,))
            except:
                print('%s already exists' % (title,)) self.stdout.write( 'job complete' )

将代码放在这样的目录结构中,然后用一个handle函数定义一个Command类,告诉 django 这是一个定制的 django-admin 命令。

在这里,我们使用美丽的汤刮杠杆工作板,然后保存在我们的数据库中。我没有附属机构,但我选择的工作板是为一家名为 Opencare 的出色公司设计的——如果他们发布了什么,你应该申请!

您现在可以从命令行运行它,如下所示。

python manage.py scrape

你会看到这个输出。

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

再运行一次,你会看到这个。

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

这是因为我们已经防止在上面的scrape.py代码中添加重复的作业记录。

如果您有一个数据库管理程序设置(如 dbeaver ,您还可以检查数据库中的行。我们不会在这里深入讨论,但它应该看起来像下面这样。

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

部署到生产

现在让我们把这个放在 Heroku 上。

冻结您的需求,以便 Heroku 知道在部署时安装什么。

pip3 freeze > requirements.txt

在命令行上,运行nano .gitignore并添加如下。

.DS_Store
jobs/__pycache__
scraping/__pycache__

然后ctrl+xyenter保存并关闭(mac 上)。这可以防止部署不必要的文件。

在根目录下创建一个名为Procfile的文件,并将下面的内容粘贴到里面。这告诉 heroku 启动一个 web dyno,第二个命令迁移 db。

web: gunicorn jobs.wsgi
release: python manage.py migrate

文件树将看起来像这样。

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

确保你有一个 [Heroku](http://heroku create flask-ml-api-123) 账号,然后在命令行上用heroku login登录。

用你想要的任何名字创建一个应用程序。但它需要在 Heroku 上的所有应用程序中是唯一的。我跑了heroku create django-scraper-879,这里的 app 名字是django-scraper-879。但是你需要自己选择。

现在将这几行添加到 settings.py 的最底部。

import django_heroku
django_heroku.settings(locals())

在设置中更新DEBUG。不想在调试模式下部署到 prod。

DEBUG = False

用下面的添加文件到 git。

git init
git add . -A
git commit -m 'first commit'

现在用这个把我们的 app 推给 Heroku。

git push heroku master

计划作业

您可以使用heroku run python manage.py scrape从本地命令行手动运行该作业,但是每天都必须手动运行它会很烦人。

让我们自动化这一点。

登录你的 Heroku 控制台,点击“资源”,然后“查找更多附加组件”。

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

现在找到并点击这个附加组件。尝试用“ctrl+f”来输入“schedule ”,以帮助找到它。Heroku 有一大堆潜在的附件。看起来像下面。

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

现在将它添加到您的应用程序中,这样您就有了。

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

点击它,创建一个作业,everyday at…12am UTC。不必要的 ping 网站是不好的!

输入您的命令并保存。

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

保存,我们就完成了!

现在只需等到 UTC 时间 12 点(或者你选择的任何时间),你的数据库就会被填充。

结论

我们在这里接触了很多东西。Django,Heroku,日程安排,网页抓取,Postgres。

虽然我用了想知道一家公司何时发布新工作的例子,但是有很多理由你可能想抓取一个网站。

  • 电子商务公司希望监控竞争对手的价格。
  • 高管招聘人员可能想知道公司何时发布职位空缺。
  • 你或我可能想知道 Kaggle 上什么时候增加了一个新的比赛。

本教程只是为了说明什么是可能的。让我知道你是否已经用网络抓取在评论中建立了任何酷的东西。

SCIEM:数据预处理的操作顺序

原文:https://towardsdatascience.com/sciem-an-order-of-operations-for-data-preprocessing-e3af0bf101b8?source=collection_archive---------39-----------------------

通过最小化调试时间来提高数据清理的效率。

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

CRISP-DM 流程的前 5 个步骤的循环最终看起来有点像上面的时间线。由于预处理可能会占用数据科学过程中的大部分时间,这可能会挤出用于业务理解、建模或评估结果的时间。建模只占项目时间的很小一部分,尽管它通常是人们想到数据科学时首先想到的事情。预处理会带来很大的时间负担,特别是对于大型数据集,或者从不同格式的许多来源编译的数据。

如何最大限度地减少预处理时间,使流程更加高效?

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

作者图片

在获取和导入数据之后,需要在建模之前进行预处理步骤,否则会导致错误。按照正确的顺序做这些事情可以通过减少错误来加速这个过程。就像数学中的 PEDMAS 一样,数据预处理的步骤有一个自然的顺序。下面是使用 Python 和 Pandas 预处理数据的操作顺序的新缩写。

PEDMAS 之于数学,正如 SCIEM 之于数据科学。

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

安托万·道特里的照片

  1. 拆分:列车试拆分
  2. 清洁:杂清洁
  3. 输入:输入缺失值
  4. **编码和缩放/标准化/规范化/转换/平衡:**对分类数据进行编码;根据需要缩放、标准化和转换数字数据。平衡是指纠正阶级不平衡。
  5. **模型:**训练机器学习算法

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

作者图片

为什么这些步骤会以这种顺序出现?

训练-测试-分割 在以任何方式操作数据之前,最好分割训练和测试数据。通常这是通过 sklearn 来完成的,对于大数据也可以用 Spark 来完成。如果可能的话,最好在查看数据之前就将其拆分。这防止了数据泄露,即来自测试数据的信息被用于训练模型。

清洗 这可能包括多种操作,例如:

  • 删除不适用的列
  • 删除重复项
  • 基于筛选条件删除行
  • 移除异常值
  • 删除错误值
  • 更改数据类型
  • 拆分或组合字符串格式的数据
  • 宁滨(将要素转换成组)
  • 特征聚合
  • 离散化
  • 重采样

如果在编码之前没有进行清理,调试过程将一次又一次地返回到这个步骤来解决错误,直到每个清理任务完成。

输入缺失值 输入缺失值是指用选择的替代值如均值、中值或众数填充 NAN(非数字)值。输入必须在编码前完成,因为编码器不喜欢南的。

One-Hot-Encoding
这需要是最后一步,因为如果您试图对 NAN 值进行编码,或者如果列数据类型不一致,将会导致错误。这里有一个关于 one-hot-encoding标签编码的资源。

作为数据理解的一部分,涉及基于领域知识手动缩小特征范围的特征选择应该在所有这些步骤之前进行。使用算法的特征选择应在预处理后进行。

如果您对预处理的顺序或如何有一个更有效的预处理工作流有任何进一步的见解,请不要犹豫留下评论。还有其他可能影响订单的潜在步骤。SCIEM 是一个可以遵循的通用框架。

参考文献:

  1. Maksym Balatsko, 关于预处理你想知道的一切:数据准备 ,2019,走向数据科学。
  2. Jason Brownlee, 如何用 Scikit 在 Python 中为机器学习准备你的数据——学习 ,2016,机器学习掌握。
  3. Syed Danish, 使用 Scikit 学习 Python 中数据预处理实用指南 ,2016,Analytics Vidhya。
  4. Robert R.F. DeFilippi, 用 Python 为数据科学清理和准备数据—最佳实践和有用的包 ,2018,中。
  5. 萨尔瓦多·加西亚,朱利安·卢恩戈和弗朗西斯科·埃雷拉,《数据挖掘中的数据预处理 ,2015,施普林格。
  6. Tarun Gupta,Python 中的数据预处理 2019,走向数据科学。
  7. Rohan Gupta,面向数据科学的数据科学家离散化技术介绍,2019。
  8. Ihab 易勒雅斯储旭数据清理,2019,计算机械协会。
  9. 问:伊森·麦卡勒姆(Ethan Mccallum), 《不良数据手册:清理数据,以便你可以重新开始工作》 ,2012 年,奥赖利。
  10. Jason Osborne, 数据清理最佳实践:收集数据前后需要做的所有事情的完整指南 ,2012 年,SAGE 出版社。
  11. Pranjal Pandey, 数据预处理:概念,2019 ,走向数据科学

数据科学——一个“古老”的故事

原文:https://towardsdatascience.com/science-of-data-an-old-story-d9db5e6cb00?source=collection_archive---------51-----------------------

为数据科学增添视角

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

Johannes Plenio 在 Unsplash 上拍摄的照片

我们(智人)与其他动物物种的主要区别之一是我们能够 想象识别模式 并基于这种理解做出 可操作的决策 。这帮助我们度过了最艰难的环境,征服了这个星球。我们通过有效地“处理”我们可用的“数据来做到这一点。在早期,人类通过识别掠食者攻击他们的方式衍生出新的生存策略。我们的祖先以此为“训练数据”,发现了躲避捕食者攻击甚至反击的方法。同样,他们从自然过程中观察数据,如“天气变化”、“草药的药性”、“用火烹饪”等,并获得可操作的见解,以提升进化链。因此,数据总是以某种形式存在。人类一直在利用数据造福人类。“数据科学”可能是今天的流行语,但人类从史前时代就开始使用这种数据科学。事实上,数据科学让我们达到了今天的水平。用简单明了的英语来说,如果你需要定义*“数据科学”,它的意思无非是“利用数据得出可操作的见解以使事情变得更好的科学”。*

在现代,“让事情变得更好”可能意味着“以更好的方式购物”、“更好地了解客户的行为”、“提出更好的建议”、“预测结果”等等。使用数据并在其上应用数据科学原理,有助于我们实现所有这一切,甚至更多。

为了对任何领域或概念建立牢固的理解,我们应该努力掌握该领域中使用的基本术语的含义。在数据科学领域,以下 3 个术语被过度使用:统计学、数据挖掘和机器学习。

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

M. B. M.Unsplash 上拍摄的照片

统计:

比方说,你经营一家杂货店,在那里销售一些产品。为了更好地了解你的企业是如何运作的,你记录下每天售出的产品数量。因为你有销售数据,你可以找出你每月的总销售额,比别人卖得多的前 10 个产品的列表,顶级客户的列表,一周的平均销售额或某一天的平均销售额等等。这些测量会让你知道你的生意做得怎么样。这就是简单统计学的意义。

统计学就是收集、组织、总结、分析和解释数据的科学。

让我们用一个例子来理解它。 UCI 机器学习库提供了一个数据集,其中包含一家总部位于英国的注册无店铺在线零售商在 2010 年 12 月 1 日至 2011 年 12 月 9 日之间发生的销售交易。(根据 UCI 机器学习知识库,这些数据是由公共分析小组主任陈大庆博士提供的。chend ‘@’ lsbu.ac.uk,伦敦南岸大学工程学院,伦敦 SE1 0AA,英国。)

使用 统计 方法可以回答的一些有趣问题有:

  • 完成交易的独立客户总数是多少?
  • 订单数量最多的前 10 名客户是谁?
  • 消费最高的前 10 名客户是谁?
  • 每年每个月的平均销售额是多少?

这些问题的答案可能会让你对业务有所了解

Python 3/Jupyter Notebook 已经用于探索数据和回答上述问题。(最后已经提供了完整笔记本的 github 链接。然而,我们将在下面详细讨论代码的每一部分。)

让我们导入所需的 Python 库并将数据加载到 Pandas 数据框架中

***#Import data
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns 
color = sns.color_palette()** **df_retail_sales = pd.read_csv(‘./input/data.csv’,encoding="ISO-8859–1")***

检查关于该数据帧的信息

***df_retail_sales.info()***

输出是

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

数据由 8 个属性组成,定义如下:

*InvoiceNo: 代表唯一的订单号或交易号。
**库存代码:**代表已售出产品的唯一产品代码。
**描述:**描述已售出的产品
**数量:**其在交易中售出的产品数量
**发票日期:**交易日期
**单价:**其售出的 1 件产品的售价
客户 ID: 其代表进行交易的客户
**国家:*国家名称

让我们执行基本的数据清理任务——删除属性为空值的行,删除数量列中为负值的行(负值对数量列没有任何意义)

***df_retail_sales['InvoiceDate'] = pd.to_datetime(df.InvoiceDate, format='%m/%d/%Y %H:%M')****df_retail_sales = df_retail_sales[df_retail_sales.Quantity > 0]****retail_sales = df_retail_sales.dropna()***

现在让我们做一些基本的 特征工程——这是一种有趣的说法,即我们在数据中添加一个新列或修改一个现有列,这样会更有用。例如,在我们的例子中,我们可以添加一个新列*“amount spend”,它将是数量单价的乘积。我们还应该为年**、添加单独的列,这些列可以从 InvoiceDate 派生。这些将有助于我们计算年、月和日销售额的数据。(记住……这就是基本统计学!)*

***retail_sales['AmountSpent'] = retail_sales['Quantity'] * retail_sales['UnitPrice']****retail_sales.insert(loc=6, column='YearMonth', value=retail_sales['InvoiceDate'].map(lambda x: 100*x.year + x.month))****retail_sales.insert(loc=7, column='Month', value=retail_sales.InvoiceDate.dt.month)****retail_sales.insert(loc=8, column='Day', value=(retail_sales.InvoiceDate.dt.dayofweek)+1)****retail_sales.insert(loc=9, column='Hour', value=retail_sales.InvoiceDate.dt.hour)***

我们的新数据框架“retail_sales”如下所示:

***retail_sales.info()***

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

现在让我们试着回答我们的问题。

完成交易的唯一客户总数是多少?

***retail_sales['CustomerID'].nunique()***

4339

订单数量最多的前 10 名客户是谁?

***orders = retail_sales.groupby(by=['CustomerID'], as_index=False)['InvoiceNo'].count()****orders.rename(columns={'InvoiceNo': 'Cnt_Invoices'}, inplace=True)****orders=orders.sort_values(by='Cnt_Invoices', ascending=False).head(10)****orders.plot(x="CustomerID", y=["Cnt_Invoices"], kind="bar")***

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

按订单数量排名的前 10 名客户

消费最高的前 10 名客户是谁?

***spending = retail_sales.groupby(by=['CustomerID'], as_index=False)['AmountSpent'].sum()****spending.sort_values(by='AmountSpent', ascending=False).head(10)****spending.plot(x="CustomerID", y=["AmountSpent"], kind="bar")***

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

按消费金额排名的前 10 名客户

每个月的平均销售额是多少?

***ax = retail_sales.groupby(‘YearMonth’)
[‘AmountSpent’].mean().sort_index().plot(‘bar’,color=color[1],figsize=(15,6))****ax.set_xlabel(‘Month’,fontsize=10)****ax.set_ylabel(‘Avg Sales’,fontsize=10)****ax.set_title(‘Sales (01-Dec 2010–09-Dec-2011)’,fontsize=14)****ax.set_xticklabels((‘Dec10’,’Jan11',’Feb11',’Mar11',’Apr11',’May11',’Jun11',’July11',’Aug11',’Sep11',’Oct11',’Nov11',’Dec11'), rotation=’horizontal’, fontsize=11)****plt.show()***

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

每月平均销售额

以上是一些基本统计如何帮助理解和分析数据集的例子。更进一步,我们还可以通过研究各种属性的分布,找出它们之间的关系,从数据中发现有用的信息。

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

伊万·班杜拉在 Unsplash 上的照片

数据挖掘:

以零售销售数据为例,我们可以发现:

  1. 忠诚的客户(经常购物)
  2. 休眠客户(不经常购物)
  3. 每个客户最早和最晚的订单日期。
  4. 特定人群在一年中的特定日子购买的一组产品。

数据挖掘是在大型数据仓库中自动发现有用信息的过程。

让我们为客户构建一个新的数据框架,并尝试找到一些此类信息

*customer_data=retail_sales.groupby(‘CustomerID’).agg(
 # Get count of orders column for each customer
 TotalOrders=(‘InvoiceNo’, ‘count’),
 # Get total amount spent for each customer
 TotalSpending=(‘AmountSpent’, ‘sum’),
 # Get earliest order date for each customer
 EarliestInvoice=(‘InvoiceDate’, ‘min’),
 # Get latest order date for each customer 
 LatestInvoice=(‘InvoiceDate’, ‘max’)
)customer_data.head()*

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

两个新属性:最早发票最新发票可用于确定客户是忠诚的还是休眠的。如果这两个日期的差异很小,则顾客频繁购物,否则他处于休眠状态。

“总支出”列可用于挖掘大买家的信息。该信息可以与库存代码(产品)的计数相结合,以找出哪些产品销售更频繁。

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

Clarisse CrosetUnsplash 上拍摄的照片

机器学习:

比方说,您的客户向您提供他们购买的反馈。为了从这种反馈中获得可操作的见解,你编写一个计算机程序,将它作为输入,并给你一个客户对你的产品的感觉或看法的分数。这些观点可以帮助你了解客户的需求,你可以采取一些措施来满足客户。随着不同客户的购买倾向于增长,新的反馈不断出现,你的程序在感知客户情绪方面变得更好。这是机器学习。

机器学习是计算机科学和人工智能的一个分支,旨在开发从数据中学习的系统,并在学习的基础上帮助做出决策和预测。

简单明了地说, 统计 技术被用来训练你的机器(或者你的电脑程序)去学习,从而帮助你挖掘你的数据,发现有用的模式和可操作的见解。

所讨论的示例代码可从 Github 获得

从 A 到 Z 用 NumPy 进行科学计算

原文:https://towardsdatascience.com/scientific-computing-with-python-daaaaddfa122?source=collection_archive---------47-----------------------

数据科学

关于 Numpy 你需要知道的

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

背景由乔·塞拉斯Unsplash

Numpy数值 PYthon 是 python 最强大的数学库之一。它使我们能够高效和有效地进行计算。由于其惊人的能力,它比普通的 python 更好。****

  • numpy 模块主要基于ndarray类,它允许面向向量的编程**。**
  • ndarray类允许实例化多维向量并用本地 python 指令处理它们,以简化科学计算。
  • 该模块完全是用 C 语言编写的调用函数的执行不通过虚拟机(就像 Python 的情况一样),这允许我们进行高性能的密集计算。****
  • 提供两种外观,一种是过程外观(函数和变量),另一种是面向对象外观(类、属性、方法、特性……)。

认识“ndarray”:

实例化 ndarray:

可以调用类 a ndarray的构造函数来构造 n 维向量的实例。主要参数是:

  • 形状:正整数元组,表示每个维度的元素数量
  • dtype: 表示数组元素的类型。因此,ndarray 是包含相同类型值的 n 维向量****

****重要提示:你也可以使用numpy.ndarray创建一个数组,但这不是推荐的方式(数组的构造应该如下段所示)。

****import numpy as np
np.ndarray((4,2), np.int)****

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

输出结果: Google Colab

****a = np.ndarray(shape= (4,2), dtype = np.int)****

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

输出结果: Google Colab

ndarray 的功能:

生成 numpy 数组:

np.array:这个函数允许你创建并从 python iterable 初始化一个多维向量并返回np.ndarray

  1. 一维 向量构造:
****a = np.array([1,2,3, 3+3j])** 
*# L =[1,2,3, 3+3j]
# a = np.array(L)***

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

输出结果: Google Colab

2.矩阵构造:

现在,参数是一个列表的列表,其中子列表具有相同的大小表示结果矩阵的行****

**m = np.array([[1,2,5], [3,2,5], [0, 3, 8]])**
*#L=[[1,2,5],
#  [3,2,5],
#  [0,3,8]]
#m = np.array(L)*

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

输出结果: Google Colab

3.三维矢量构造:

列表的列表的列表…

**a3 = np.array([[[1,2],[2,0]], [[0,1],[0,5]]])**

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

输出结果: Google Colab

离散化函数:

离散化是我们将连续数据转换成离散形式的过程。这些函数返回一个一维向量,该向量是将一个区间(连续的)划分为一组有限的点而得到的。

  1. 功能:“arange”:

返回给定间隔内间隔均匀的值。

**np.arange(5)**# *a vector of integers ranging from 0 to 4\. (the upper bound is excluded)***np.arange(0,1, 0.2)** *#division of the interval [0,1 [according to step 0.2*
**np.arange(1, 0, -0.1)** *#Negative step*

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

输出结果: Google Colab

numpy.arangerange python 内置功能有什么区别?

Python 内置函数“range”只接受整数作为参数。

**range(0, 1, 0.2)** *#Error*

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

输出结果: Google Colab

2.功能:“linspace”:

返回指定间隔内等间距的数字。

**a = np.linspace(0,1)** *#by default divides the interval into 50 equidistant points*
**b = np.linspace(0, 1, num = 10)**

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

输出结果: Google Colab

3.功能:“日志空间”:

返回在对数刻度上均匀分布的数字(默认情况下以 10 为基数)。

**np.logspace(0,1)**

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

输出结果: Google Colab

齐次 n 维向量:

  1. 功能‘0&1】:

返回给定形状和类型的新数组,用零填充。

**np.zeros((2,3), dtype = np.bool)
np.zeros(shape = (10,))**
**np.ones((2,5,2))** *#3D*
**np.ones((3,3), dtype = np.complex)**

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

输出结果: Google Colab

2.功能:“满”:

返回给定形状和类型的新数组,用相同的值填充。

*#np.full(shape****,*** *fill_value****,*** *dtype=None****)* np.full((5,5), 3, np.int)
np.full((2,4), fill_value=3+2j, dtype=np.complex)**

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

输出结果: Google Colab

我们可以用np.ones作为np.full的等价物。

**np.ones((2,4)) * (3+2j)
np.full((2,4),(3+2j))**

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

输出结果: Google Colab

矩阵函数:

  1. 单位矩阵:

线性代数中,大小为 n 的单位矩阵就是主对角线上有 1,其他地方有 0 的 n × n 方阵矩阵**。**

**np.identity(5)** #I5
**np.identity(5, dtype = np.int)**
**np.identity(4, dtype = np.bool)**

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

输出结果: Google Colab

2.功能‘眼’:

返回一个对角线上为 1,其他地方为 0 的二维数组。

*#**np.eye****(****N****,*** *M=None****,*** *k=0****,*** *dtype=<class 'float'>)* #**N** : *int :*Number of rows in the output.
#**M** : *int, optional :*Number of columns in the output. If None, #defaults to *N*.
#**k** : *int, optional :*Index of the diagonal**np.eye(3)** *#np.identity(3)*
**np.eye(3,3,-1)** *#fill the first diagonal below the main diagonal with ones.*
**np.eye(3,3,1)** *#fill the first diagonal above the main diagonal with ones.*
**np.eye(5,10, 3, dtype = np.int)**

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

输出结果: Google Colab

3.功能‘诊断’:

diag 函数有两个参数:

  • ndarray
  • 整数 k(默认值= 0)。如果‘v’的维数是 1,则该函数构造一个矩阵,其中它的对角线数 k 由向量‘v’的元素构成。如果 a 是一个矩阵(维数为 2 ),那么该函数提取一维向量中第 k 条对角线的元素。

提取一条对角线或构造一个对角线数组。

**np.diag([1,5,7])
a = np.ones((3,3)) * 5
np.diag(a)**

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

输出结果: Google Colab

3.函数‘from Function’:

通过对每个坐标执行一个函数来构造一个数组。
让我们创建一个基于其索引的向量。

#*numpy.fromfunction****(****function****,*** *shape)*
**np.fromfunction(lambda i,j : i-j, (3,3))
np.fromfunction(lambda i, j : i == j, (5,5))**

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

输出结果: Google Colab

ndarray和原生 python 迭代器有什么区别(和优势)?

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

输出结果: Google Colab** 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传****外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

输出结果: Google Colab

ndarray支持本地 Python 操作符(+、-、 …),以及 numpy 模块中可用的一组“矢量化”数学函数(numpy.cosenumpy.sinanumpy.exp …)。*

4.功能“矢量化”。

numpy.vectorize的目的是将不支持 numpy 的函数转换成可以操作(并返回)numpy 数组的函数

让我们构建一个函数sign,允许我们计算一个值的符号。

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

如果你对在 Jupyter 笔记本、Google Colab 或任何其他支持 LaTeX 数学写作的交互式笔记本中用 LaTex 写数学感兴趣,请查看这篇文章。

def sign(x):
   if x == 0:
      return 0
   elif x > 0:
      return 1
   else:
      return -1

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

输出结果: Google Colab

vectorized_sign = np.vectorize(sign)

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

输出结果: Google Colab

再比如:

我们来构建一个函数xlogx

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

如果你对在 Jupyter 笔记本、Google Colab 或任何其他支持 LaTeX 数学写作的交互式笔记本中用 LaTex 写数学感兴趣,请查看这篇文章。

import math
def xlogx(x):
   if x==0:
      return x
   else:
      return x * math.log(x)

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

输出结果: Google Colab

ndarrays 的“有趣”特性:

  • 属性(只读),告诉我们向量元素的类型。

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

输出结果: Google Colab

  • numpy.size返回数组中元素的个数。

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

输出结果: Google Colab

  • numpy.ndim返回数组维数。

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

输出结果: Google Colab

  • numpy.shape包含每个维度的元素数量的元组。该属性是可读/写的。

提醒: 元组元素的乘积应该等于数组的大小。

⟹形状属性允许你改变向量的形状,但不能改变它的总大小!!!

a.shape = (5,4)
a.shape = (10,2)

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

输出结果: Google Colab

两个不变关系:

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

如果你对在 Jupyter 笔记本、Google Colab 或任何其他支持 LaTeX 数学写作的交互式笔记本中用 LaTex 写数学感兴趣,请查看这篇文章

使用复杂系统:

**z = np.array([[1, 3+3j],[2+1j,3+5j],[5j,5]])**
**z.real** *#Return the real part of the complex argument.*
**z.imag** *#Return the imaginary part of the complex argument.* **np.conj(z)** *#Return the complex conjugate.*

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

输出结果: Google Colab

ndarray 的一些预定义方法:

ndarray.trace:

**trace方法:允许计算尺寸为> 1 的ndarray的轨迹。
**提醒:线性代数中,方阵 A 的迹(常缩写为 tr)定义为主对角线上元素的和。

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

数组维数应大于 1。

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

输出结果: Google Colab

ndarray.reshape:

它返回包含新形式的源数组的ndarray类的新实例。

a = np.arange(10)
b = a.reshape((2,5))

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

输出结果: Google Colab

reshape返回的向量不是初始向量的独立副本,而是与源共享相同的内存大小写。

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

输出结果: Google Colab

如何创建的独立副本?

我们使用.copy()方法。

**c = a.reshape((2,5)).copy()***#create an independent copy of a*

ndarray.dot

点积的计算(对于一维向量)。维数≥ 2 的向量的矩阵乘法。

v1 = np.array([1,2,3,4])
v2 = np.array([1,0,1,0])
v1.dot(v2) #dot productm = np.diag([1,2,3,4])
n = np.ones((4,4))
m.dot(n) #Matrix multiplication

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

输出结果: Google Colab

np.cross

返回两个向量(数组)的叉积。

v1 = np.array([1,2,3])
v2 = np.array([1,0,1])v3 = np.cross(v1,v2)
v3.dot(v1)

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

输出结果: Google Colab

ndarray.astype

允许创建一个新实例,该实例包含与源 vector 相同的值,但被转换为参数指示的类型。

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

输出结果: Google Colab

聚合方法:

  • ndarray.sum:返回给定轴上数组元素的和。
  • ndarray.sum:返回给定轴上数组元素的乘积。
  • ndarray.max:返回给定轴的最大值。
  • ndarray.min:返回给定轴的最小值。
  • ndarray.mean:返回给定轴上数组元素的平均值。
  • ndarray.cumsum:返回给定轴上元素的累积和。
  • ndarray.cumprod:返回给定轴上元素的累积积。
  • ndarray.var:返回数组元素沿给定轴的方差。
  • ndarray.std:返回数组元素沿给定轴的标准偏差。
  • ndarray.argmin:返回给定轴上最小值的索引。
  • ndarray.argmax:返回给定轴上最大值的索引。

****重要提示:列→轴=0。行→轴=1

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

a = np.array([[10, 11, 11], [20, 12, 21], [30, 22, 22], [40, 32, 23] , [50, 24, 24]])

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

输出结果: Google Colab

ndarrays 上的操作:广播

Numpy 解释形式为a 操作符 b的操作,其中a和/或b是类darray的实例,如下所示:具有最小尺寸的向量在最大向量中广播。让我们从例子开始:

B = np.arange(1,4)
A = np.array([Agenerator + i for i in range(10,31,10)])#or we can simply create them with np.array
#A = np.array([ [11, 12, 13], [21, 22, 23], [31, 32, 33] ])
# B = np.array([1, 2, 3])

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

输出结果: Google Colab

与广播相乘:

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

这张图说明了广播的工作方式:来源

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

输出结果: Google Colab

另一个例子:

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

来源

b = np.arange(1,4)
a = (b * 10).reshape((3,1))

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

输出结果: Google Colab

广播规则:

  • Numpy 用左边的 1 填充较小维度的向量的形状,以便有两个相同维度的向量。
  • Numpy 从右边开始比较 a.shape 和 b.shape 中的整数对(index -1) →较小的公维。
  • 二维 a.shape [i]和 b.shape [i]是相容的,如果:

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

如果你对在 Jupyter 笔记本、Google Colab 或任何其他支持 LaTeX 数学写作的交互式笔记本中用 LaTex 写数学感兴趣,请查看这篇文章。

索引数组:

简单索引:

索引数≤维度数。

  • 1D :
a = np.arange(5)
print("a[0]= ", a[0]) #first element
print("a[-1]= ", a[-1]) #last element
print("a[a.size]= ", a[a.size]) #error

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

输出结果: Google Colab

  • 2D :

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

输出结果: Google Colab

切片:

**#A[start:stop-1:step]**a = np.arange(5)
print(a[0:3])
print(a[::-1]) #reverse the order of the elements of a.

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

1D 切片。输出结果: Google Colab

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

多维切片。输出结果: Google Colab

示例:

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

如果你对在 Jupyter 笔记本、Google Colab 或任何其他支持 LaTeX 数学写作的交互式笔记本中用 LaTex 写数学感兴趣,请查看这篇文章。

  1. 创建a
  2. 应用切片从a中提取深绿色标记的部分。

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

a = np.fromfunction(lambda i, j : (i+1)*10 + (j+1), (5,5))
a[:3, 2:]

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

a[3:]

:更多例子请看 Google Colab 笔记本

屏蔽:

当您希望根据某种标准提取、修改、计算或操作数组中的值时,就会出现屏蔽。让我们生成两个数组并使用布尔掩码。

a = np.arange(25).reshape((5,-1)) # -1 >> python will automatically calculate ( or simply type .reshape((5,5))
c = a%2b = c == 0 #b is a boolean vector it can be used as a mask for the vector a
a[b] #gives the values which are overlayed with the elements which are True in b

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

输出结果: Google Colab

我们可以使用~not广播到数组元素中。

  • ~不是
  • &
  • |
  • %mod

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

输出结果: Google Colab

线性代数

进口

from numpy import linalg as alg#Let's generate some arrays:
d1 = np.diag([1,2,3])
d2 = np.array([[1,0,0],[2,0,0],[3,0,0] ])
d3 = np.array([[0,0,1], [0,1,0], [1,0,0]])

功能

  1. 函数’ det’: 计算一个数组的行列式。
alg.det(d1)
alg.det(d2)

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

输出结果: Google Colab

2.函数’ matrix_rank’: 计算一个数组的秩。

alg.matrix_rank(d1)
alg.matrix_rank(d3)

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

输出结果: Google Colab

3.函数‘inv’: 计算一个数组的逆矩阵。

print(d1)
print(alg.inv(d1))

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

输出结果: Google Colab

4.函数‘matrix _ power’: 将方阵提升到(整数)次幂n

alg.matrix_power(d1,2)
alg.matrix_power(d1,-1) # >> equivalent of alg.inv(d1)

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

输出结果: Google Colab

5.函数‘eigvals’: 计算一个数组的特征值

alg.eigvals(d1)

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

输出结果: Google Colab

6.函数‘EIG’:
计算一个方阵的特征值和右特征向量。

print(d1)
eigVal, eigVect = alg.eig(d1)

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

输出结果: Google Colab

7.函数‘求解’: 用两种不同的方法求解下列线性方程组:

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

如果你对在 Jupyter 笔记本、Google Colab 或任何其他支持 LaTeX 数学写作的交互式笔记本中用 LaTex 写数学感兴趣,请查看这篇文章。

#First method (using alg.solve):
x = alg.solve(a,b)#Second method (using alg.inv):
inv_a = alg.inv(a)
x = inv_a.dot(b)

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

输出结果: Google Colab

资源:

感谢阅读!😄

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

查看我的其他文章,关注我的 中型**

哈利菲艾哈迈德阿齐兹

带 Lambda 的科学 Python

原文:https://towardsdatascience.com/scientific-python-with-lambda-b207b1ddfcd1?source=collection_archive---------16-----------------------

Python Lambda 函数的正确用法:Python 科学编程的最佳语法。

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

(图片由作者提供)

介绍

在过去的十年里,Python 编程语言已经进入了科学计算领域的许多人的脑海。这是有意义的,因为 Python 是一种动态的、易于理解的编程语言,其背后有一个重要的生态系统。尽管 Python 有能力担当这个角色,但是,Python 并不是为科学计算甚至统计而设计的。因此,与其他科学编程语言相比,Python 的语法往往有很大不同。

虽然有很多例子表明 Python 在语法上可能不是应用数学的好语言,但是 Python 确实有一些有趣和令人兴奋的技巧来抵消这种天生的劣势。这方面最酷的函数之一是λ函数。

Julia 编程语言让我喜欢的一点是语法表达式的使用。在 Julia 语言中使用这些表达式允许您在一行中非常容易地将不同的类型分派给不同的操作。这使得数学表达式非常简单,写起来就像在论文里一样。举例来说,这对于微分方程,尤其是积分方程来说非常有用。虽然在我看来,Julia 的实现当然更好,但 Python 中的 lambda 函数可以被认为是一个等价的函数。如果您也想了解 Julia 的实现,这里有一篇关于它的文章:

[## 如何在 Julia 中使用语法表达式和调度

朱莉娅的面包和黄油:句法表达和多重调度

towardsdatascience.com](/how-to-use-syntactical-expressions-and-dispatch-in-julia-67ce155e4af9)

lambda 是什么意思?

lambda 函数是一个匿名函数,它将 Pythonic 表达式作为参数。将 lambda 视为应用程序是一个很好的方式。每当使用 lambda 时,它通常意味着我们希望将这个表达式应用于这个构造的类型。Lambda 还可以用来映射数据,在 for 循环中非常有价值。

在 Python 中,lambda 函数用于创建 Python 表达式,无需元解析。这很好,因为这也意味着我们避免了通常与执行随机代码行相关的危险——尤其是在 Python 中。然而,这个表达式也可以返回到一个变量,并在运行时环境中定义为一个函数。

使用λ

lambda 函数的用法类似于字典键。将键视为提供的变量或参数,将键下的数据视为调用键时要计算的表达式。

例如,让我们考虑 f(x) = x + 5:

x = [5,10,15]f = lambda x : [z + 5 for z in x]

我们想用 x 评估的表达式是[z + 5 for z in x].在这个循环中,我们简单地给列表 x 的每个元素加 5。每当我们把 x 放在冒号 lambda x :之前,我们就声明这些是将被提供来执行表达式的参数。最后,我们设置 f 等于 lambda 函数的返回——这将是一个接受参数 x 并执行算术[z + 5 for z in x]的函数。也就是说,f 现在被定义为这个函数:

print(f(x))
[10, 15, 20]

此外,我们可以创建一个带有多个参数的 lambda 函数。下面的函数将两个列表按元素相加:

f = lambda x, y : [w + i for w, i in zip(x, y)]

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

(图片由作者提供)

调度/λ

最后,在与我最喜欢的编程语言的比较中,Python 的 lambda 函数本质上扮演了与 dispatch 相同的角色,在一行代码中快速创建函数。尽管如此,我认为在代码之间画一个快速的比较可能是令人兴奋的。让我们使用两种语言中的两种方法创建一个正态分布,看看哪种方法更有效:

计算机编程语言

norm = lambda x : [i = (i-mean(x)) / std(x) for i in xt]norm(x)

朱莉娅

norm(x) = [i = (i-mean(x)) / std(x) for i in xt]norm(x)

从这两个例子中可以清楚地看出,这种方法在两种语言中的应用几乎没有什么不同。然而,Julia 版本的一个显著优点是,类型也可以被不同地分派和计算,例如,如果我们要通过 Julia 中的这个函数传递一个整数,我们会得到一个错误,因为我们不能遍历整数。对于 Python 来说也是如此。这两种语言的不同之处在于,当 x 的类型不是数组时,Julia 能够运行另一个完全独立的函数:

norm(x::Array) = [i = (i-mean(x)) / std(x) for i in xt]
norm(x::Int64) = (x - x) / std(x)

结论

尽管 Python 并不是一门在创建时就必须考虑科学计算的语言,但它确实非常适合这个角色。这种语言通过实现一些工具来做到这一点,这些工具使得利用语言内部的科学和数学语法变得更加容易。虽然 Python 的版本可能没有 Julian 实现好,但它表明 Python 是一种强大而通用的语言,可以在科学计算领域超越大多数其他语言。此外,lambda 是一个很好的工具,无论你是不是科学家,在用 Python 编程时牢牢掌握它是一件很好的事情。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值