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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

贝叶斯优化——第一部分

原文:https://towardsdatascience.com/bayesian-optimization-an-intuitive-explanation-130e97fa4e18?source=collection_archive---------30-----------------------

一个直观的,没有数学的介绍

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

马里乌斯·马萨拉尔在 Unsplash 上的照片

优化是现代机器学习的核心。为什么?线性回归,最小化误差平方和。逻辑回归,最小化负面可能性。支持向量机,最小化两个支持向量之间的负距离。

让我们用更简单的术语来理解优化,而不是用数学定义和等式来解释。“今天是这个月的最后一天,你只剩下 30 美元了。你渴望吃一些美味的食物。你想在比萨(每块 5 美元)、汉堡(每块 3 美元)和可乐(每块 1 美元)中至少选择一种。你不能吃超过 4 个披萨,至少要两个汉堡”。这就对了。现实生活中的优化问题:在某些约束条件下最大化或最小化目标函数

上述问题是线性还是非线性优化?线性优化涉及仅由线性项(或一次项)组成的目标函数,如果它有任何二次项或非线性方程,则它是非线性优化。

在本文中,我们将只关注非线性优化范例——解决这些问题比解决线性问题要复杂得多…

我们来玩个游戏吧!有一个函数 f(x),我就不透露了。这个函数接受实数。任务是这样的:你必须在区间[-150,350]内逼近函数的最小(最低)值。我会告诉你你问的任意 x 值的函数值。但是这里有一个问题,你只有有限的请求,确切地说,只有 5 个。在-150 和 350 之间有无限个实数,所以要小心选择。

假设您的第一个问题是简单明了的 0。

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

任何理性的人都会选择一个正数和一个负数,所以让我代表你们来做。我将在 x = 150 和 x=-50 时分享 f(x)

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

那是一组有趣的点,不是吗?你和我想的一样吗?选择-50 附近的下一个点,检查我们的函数是否在那里有最小值?用最优化的术语来说就是叫做 剥削 。这就像,当你知道与其他值相比,某一点的函数值接近我们想要的值时,你会继续利用那个区域。我不想浪费我最后的两次机会。可能在 0 到 100 之间,我可能有我们想要的值,这个区域我们还没有探索过。在优化术语中,这被称为 探索 ,你已经知道你的函数对于几个值输出什么,所以我们将探索新的区域来找到我们想要的值,而不是利用已知的值。一个好的优化算法应该在探索和利用之间取得平衡

讨论完以上内容,让我们使用最后两种猜测:一种是利用,一种是探索。让我们把 x 作为-100 和 100。

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

开发得到了回报,我们现在在 x=-100 处有一个最小值(相对于我们所做的 5 次猜测),但是我们仍然不知道它是否是真正的最小值。

这种智能地选择迭代中的下一个点来寻找所需值的现象就是贝叶斯优化优雅地做的事情。

没有太多的数学知识,我将尝试使用图形来解释它如何评估。最后一次,我保证没有数学。

一个有效的优化算法如何计算函数在哪里有最小值?它必须遍历给定范围内的所有值,并评估每个值的函数值——就像网格搜索一样。这是非常繁琐和非常不准确的,尤其是如果它是一个多元函数或一个有许多局部最小值。

现在,我们将看到贝叶斯优化是如何处理人类的思维方式,但在统计意义上。

所以,当我给定第一个输入为 x=0 时,我们得到了对应的 f(x)值。贝叶斯优化使用高斯过程来模拟通过该点的不同函数。什么是高斯过程?这超出了本文的范围(可能是下一篇)。但是现在,想象你在空间中有一个点,我要求你画出通过这个点的各种线。

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

不同的人有不同的想象力

如果你仔细观察,会发现有一个浅蓝色的阴影,它非常亮,你可能看不到,但你仍然会想,为什么在我们知道的输出值下,它不存在?这是我对我画的图的信心,也就是说,我对实际函数的图看起来像这样没有信心,但是如果你看到在已知值处我没有任何方差,这是因为我知道 f(x)在该点的确切值。

现在,当我们得到新的值时,让我们运用我们的想象力和近似图。

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

当我们得到 f(x)在 x=-50,150 处的值时,就可以近似得到这个图

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

当我们得到 f(x)在 x=-100,100 处的值时,就可以近似得到这个图

早些时候我告诉你,我已经用我的想象力绘制了上面穿过我们猜测的点的怪异线条,对吗?“我在某种程度上使用高斯过程来模拟曲线。这样,贝叶斯优化在每个新值之后逼近函数图。基于以前的值选择下一个点的智能方法是通过所谓的获取函数,它在探索和利用之间取得了良好的平衡。这只是一个直观的介绍为什么你应该选择贝叶斯优化,我希望你对它的工作原理有所了解。为了深入理解它,我们需要数学,就像我将在后续文章中尝试涉及的许多数学一样。

最后,我给出了我们试图找出最小值的图表,

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

如需任何澄清/反馈,或者如果您想在数据科学项目上进行合作,请通过 LinkedIn 联系我

在深入贝叶斯之前,我建议你精通传统的优化方法,比如牛顿拉夫森,你可以在这里找到我的文章,牛顿拉夫森第一部分第二部分第三部分

参考资料:

https://arxiv.org/abs/1012.2599

用通俗的语言解释贝叶斯优化概念

原文:https://towardsdatascience.com/bayesian-optimization-concept-explained-in-layman-terms-1d2bcdeaf12f?source=collection_archive---------7-----------------------

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

kazuendUnsplash 拍摄的照片

假人的贝叶斯优化

贝叶斯优化已经广泛用于机器学习领域的超参数调整。尽管涉及到许多术语和数学公式,但背后的概念却非常简单。这篇文章的目标是分享我所学到的贝叶斯优化与教科书术语的直白解释,并希望,它将帮助你在短时间内理解什么是贝叶斯优化。

超参数优化综述

为了文章的完整性,让我们从超参数优化方法的基本概述开始,一般有 4 种类型:

手动搜索、随机搜索、网格搜索和贝叶斯优化

贝叶斯优化不同于随机搜索和网格搜索,因为它使用过去的性能来提高搜索速度,而其他两种方法是统一的(或独立于)过去的评估。在这个意义上,贝叶斯优化就像手动搜索。假设您正在手动优化随机森林回归模型的超参数。首先,你将尝试一组参数,然后查看结果,改变其中一个参数,重新运行,并比较结果,这样你就知道你是否朝着正确的方向前进。贝叶斯优化做类似的事情——你过去的超参数的性能影响未来的决策。相比之下,在确定要评估的新超参数时,随机搜索和网格搜索不考虑过去的性能。因此,贝叶斯优化是一种更有效的方法。

贝叶斯优化的工作原理

让我们继续使用优化随机森林回归模型的超参数的例子。假设我们想找到一组使 RMSE 最小的超参数。这里,计算 RMSE 的函数被称为目标函数。如果我们知道我们的目标函数的概率分布,(简单地说,如果我们知道目标函数的形状),那么我们可以简单地计算梯度下降并找到全局最小值。然而,由于我们不知道 RMSE 分数的分布(这实际上是我们试图找出的),我们需要贝叶斯优化来帮助我们破译这个黑盒模型。

那么什么是贝叶斯优化呢?

贝叶斯优化建立目标函数的概率模型,并使用它来选择超参数以评估真实的目标函数。

这句话听起来可能很复杂,但实际上传达了一个简单的信息。让我们来分解一下:

“贝叶斯优化建立目标函数的概率模型”

真正的目标函数是固定的函数。假设它看起来像图 1,但正如我提到的,在超参数调谐的开始,我们不知道这一点。

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

图 1:真正的目标函数

如果有无限的资源,我们将计算目标函数的每一个点,以便我们知道它的实际形状(在我们的例子中,一直调用随机森林回归模型,直到我们得到所有可能的超参数组合的 RMSE 分数)。然而,那是不可能的。假设我们只有来自真实目标函数的 10 个样本,如图 2 中的黑色圆圈所示:

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

图 2:真实目标函数的 10 个样本

使用这 10 个样本,我们需要建立一个代理模型(也称为响应面模型)来逼近真正的目标函数。请看图 3。代理模型用蓝线表示。蓝色阴影代表偏差。

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

图 3:启动代理模型

根据定义,代理模型是“目标函数的概率表示”,本质上是在*(超参数,真实目标函数得分)*对上训练的模型。数学上是 p(目标函数得分|超参数)。有不同的方法来构造代理模型,但是我稍后将回到这一点。

“并使用它来选择超参数”

现在我们有目标函数的 10 个样本,我们应该如何决定将哪个参数作为第 11 个样本?我们需要构建一个采集函数(也称为选择函数)。下一个选择的超参数是采集函数最大化的地方。在图 4 中,绿色阴影是采集函数,红色直线是采集函数最大化的位置。因此,相应的超参数及其目标函数得分(用红圈表示)被用作更新替代模型的第 11 个样本。

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

图 4:最大化采集功能以选择下一个点

“在真实目标函数中进行评估”

如上所述,在使用获取函数来确定下一个超参数之后,获得这个新的超参数的真实目标函数分数。由于代理模型已经在*(超参数,真实目标函数得分)*对上训练,添加新的数据点更新代理模型。

…重复上述步骤,直到达到最大时间或最大迭代次数。然后嘣!您现在(希望)有了真实目标函数的精确近似值,并且可以很容易地从过去评估的样本中找到全局最小值。你的贝叶斯优化完成!

放在一起

总结一下,我们来看下面图 5 中的伪代码,它来自这篇论文:

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

图 5:基于通用顺序模型优化的伪代码

这里,SMBO 代表基于序列模型的优化,这是贝叶斯优化的另一个名字。它是“顺序的”,因为添加超参数是为了逐个更新代理模型;它是“基于模型”的,因为它用一个评估起来更便宜的替代模型来近似真实的目标函数。

伪代码中的其他表示:

H :(超参数,得分)对的观察历史
T:最大迭代次数
f:真实目标函数(在我们的例子中,RMSE 函数)
M:代理函数,每当添加新样本时更新
S:采集函数
x
:下一个选择的要评估的超参数*

让我们再来一遍这个循环。

  • 首先,启动一个代理模型和一个获取函数。
  • 第 3 行:然后对于每次迭代,找到采集函数最大化的超参数 x* 。获取函数是代理模型的一个函数,意思是使用代理模型而不是真正的目标函数构建的(继续读,你就知道是什么意思了)。注意,这里的伪代码显示 x* 是在采集函数最小化时获得的,而我一直说采集函数应该最大化。最大化或最小化都取决于如何定义采集函数。如果你使用的是最常见的获取函数——预期改善,那么你应该最大化它。
  • 第 4 行:获得 x* 的目标函数分数,看看这一点实际表现如何
  • 第 5 行:将*(超参数 x*,真实目标函数得分)*包含在其他样本的历史中
  • 第 6 行:使用样本的最新历史来训练代理模型

重复直到达到最大迭代次数。最终返回*(超参数,真实目标函数得分)*的历史。请注意,最后一项记录不一定是最好的成绩。您必须对分数进行排序,以找到最佳超参数。

不同类型的代理模型和获取函数

我将只给出常用类型的一般描述,而不是进入代理模型和获取函数的数学细节。如果你有兴趣更多地了解获取函数如何与不同的代理模型一起工作,请查看这篇研究论文。

最常见的获取函数:预期改善

让我们从解释什么是获取函数开始,这样我们就可以解释每种类型的代理模型是如何被优化的。

最常见的获取函数是预期改善。该公式如下所示:

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

p(y|x): 代理模特。y 是真实的目标函数分数,x 是超参数

y:目前观察到的最小真实目标函数分数*

y:新分数

预期的改进是建立在代理模型之上的,这意味着不同的代理模型将导致优化该获取函数的不同方式。我们将在下面的部分中讨论这一点。

最常见的代理模型:高斯过程模型

大多数研究论文使用高斯过程模型作为替代模型,因为它简单且易于优化。高斯过程直接建模 P(y|x)。它使用*(超参数,真实目标函数得分)的历史作为(x,y)* 来构造多元高斯分布。

为了最大化高斯过程模型的预期改进结果,新的分数应该小于当前的最小分数 (y < y)* ,以便 max(y — y,0)* 可以是一个大的正数。

让我们来看看图 6 中的一个具体例子(我借用了这篇文章):

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

图 6:分数与超参数的虚拟示例

假设在图 6 中最低分= 12,那么 y* = 12。预期改善函数将关注不确定性高且均值函数接近或低于 y*的区域。使用多元高斯分布产生最高预期改进的 n 个估计量将被用作真实目标函数的下一个输入。

替代代理模型:树 Parzen 估计量(TPE)

在一些 python 包(例如 hyperopt 库)中实现的另一个代理模型是 TPE。首先回忆一下下面显示的贝叶斯规则:

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

高斯过程直接建模 p(y|x) ,而 TPE 建模 p(x|y) ,这是给定目标函数得分的超参数的概率分布。

让我们继续以图 7 为例。TPE 算法不是选择 y* = 12 作为高斯过程,而是选择 y作为观察到的 y 值的某个分位数γ,使得 p(y < y) = γ. In other words, TPE chooses y* to be some number that’s a bit higher than the best-observed score so that it can separate the current observations into two clusters: better than y* and worse than y*. See Fig 7 as an illustration.

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

Fig 7: The black dash line is the selected y*

Given the separate scores, TPE then constructs separate distributions for the hyperparameters. Thus p(x|y) is written as:

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

where l(x) is the distribution of the hyperparameters when the score is lower than the threshold y* and g(x) is the distribution when the score is higher than y*.

The Expected Improvement formula for TPE is then changed to:

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

and after some math transformation, it becomes:

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

The end formula means that to yield a high Expected Improvement, points with high probability under l(x) and low probability under g(x), should be chosen as the next hyperparameter. This meets our intuition that the next hyperparameter should come from the area under the threshold rather than the area above the threshold. To learn more about the TPE surrogate model, refer to 本文本文

摘要、参考资料和进一步阅读

在本文中,我以一种简单明了的方式解释了贝叶斯优化的概念。对于那些想了解更多信息的人来说,以下是我认为有用的资源列表:

好吧,就这样!恭喜你一路跟随我来到这里!我希望我的文章能在某种程度上把你从与贝叶斯优化相关的大量术语和数学中解救出来。有关问题和评论,让我们连线 LinkedinTwitter

贝叶斯回归及其 R 语言实现

原文:https://towardsdatascience.com/bayesian-regression-with-implementation-in-r-fa71396dd59e?source=collection_archive---------16-----------------------

从零开始的理论推导,R 实现,以及贝叶斯观点的讨论

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

显示回归中变量之间依赖关系的概率图形模型(Bishop 2006)

可以从贝叶斯的角度建立和解释线性回归。第一部分从头开始讨论理论和假设,后面的部分包括 R 实现和备注。读者可以随意地将这两个代码块复制到 R 笔记本中,并对其进行研究。

从基础开始

回想一下,在线性回归中,给我们目标值 y ,数据 X,,我们使用模型

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

其中 y 为 N1 向量,X 为 ND 矩阵,w 为 D1 向量,误差为 N1 向量。我们有 N 个数据点。维数 D 是用特征来理解的,所以如果我们用一个 x 的列表,一个 x 的列表(和一个 1 的列表对应 w_0),我们说 D=3。如果你不喜欢矩阵的形式,就把它想成是以下内容的浓缩形式,其中所有东西都是一个标量,而不是向量或矩阵:

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

在经典的线性回归中,误差项被假设为正态分布,因此可以直接得出 y 正态分布,均值 Xw ,以及误差项具有的任何方差的方差(用σ表示,或具有σ项的对角矩阵)。正态假设在大多数情况下证明是正确的,这个正态模型也是我们在贝叶斯回归中使用的。

参数推断

我们现在面临两个问题:对 w 的推断和对任何新 x 的 y 的预测。使用众所周知的贝叶斯规则和上述假设,我们不仅可以解决这两个问题,还可以给出任何新 x 的 y 的全概率分布。下面是使用我们的符号的贝叶斯规则,它表示给定数据的参数 w 的后验分布:

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

π和 f 是概率密度函数。由于结果是 w 的函数,我们可以忽略分母,因为分子与左边的常数成正比。我们从假设中知道,似然函数 f(y|w,x)遵循正态分布。另一项是 w 的先验分布,顾名思义,这反映了参数的先验知识。

先验分布。定义先验是贝叶斯工作流程中一个有趣的部分。为了方便起见,我们设 w ~ N(m_o,S_o),超参数 m 和 S 现在反映了 w 的先验知识。如果你对 w 知之甚少,或者发现 m 和 S 的任何赋值太主观,“无信息”先验是一种修正。在这种情况下,我们将 m 设置为 0,更重要的是将 S 设置为具有非常大的值的对角矩阵。我们说 w 有很高的方差,所以我们不知道 w 会是什么。

在定义了所有这些概率函数之后,几行简单的代数运算(实际上相当多行)将给出 N 个数据点观察后的后验概率:

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

它看起来像一堆符号,但它们都已经被定义了,一旦这个理论结果在代码中实现,你就可以计算这个分布。(N(m,S)表示具有均值 m 和协方差矩阵 S 的正态分布。)

预测分布

完全贝叶斯方法不仅意味着获得单个预测(用 y_o,x_o 表示新的一对数据),还意味着获得这个新点的分布。

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

我们所做的是从第一行的联合边缘化得到边缘分布的反向操作,并在第二行的积分中使用贝叶斯规则,在那里我们也删除了不必要的相关性。注意,我们知道最后两个概率函数是什么。完全预测分布的结果是:

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

R 中的实现

用 R 实现相当方便。在上述理论结果的支持下,我们只需将矩阵乘法输入到代码中,即可获得预测和预测分布的结果。为了举例说明,我们使用了一个玩具问题:X 是从-1 到 1,均匀分布,y 被构造为以下具有正常噪声的正弦曲线的加法(见下图中 y 的图示)。

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

下面的代码获取这些数据。

library(ggplot2)

*# — — — — — Get data — — — — — — — — — — — — — — — — — — — — —+*X <- (-30:30)/30 
N <- length(X) 
D <- 10 
var <- 0.15*0.15 
e <- rnorm(N,0,var^0.5) 
EY <- sin(2*pi*X)*(X<=0) + 0.5*sin(4*pi*X)*(X>0) 
Y <- sin(2*pi*X)*(X<=0) + 0.5*sin(4*pi*X)*(X>0) + e 
data <- data.frame(X,Y) 
g1 <- ggplot(data=data) + geom_point(mapping=aes(x=X,y=Y))

下面的代码(在“推断”一节中)实现了上述理论结果。我们还扩展了 X 的特性(在代码中表示为 phi_X,在构造基函数一节中)。就像我们将 x 展开成 x,等等。,我们现在将其扩展为 9 个径向基函数,每个函数如下所示。请注意,尽管这些看起来像正态密度,但它们并不被解释为概率。

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

径向基函数的一个优点是径向基函数可以拟合各种曲线,包括多项式和正弦曲线。

*# — — — — — Construct basis functions — — — — — — — — — — — —+*phi_X <- matrix(0, nrow=N, ncol=D)
phi_X[,1] <- X
mu <- seq(min(X),max(X),length.out=D+1)
mu <- mu[c(-1,-length(mu))]
for(i in 2:D){
 phi_X[,i] <- exp(-(X-mu[i-1])^2/(2*var))
}*# — — — — — Inference — — — — — — — — — — — — — — — — — — — —+**# Commented out is general prior
# m0 <- matrix(0,D,1)
# S0 <- diag(x=1000,D,D) 
# SN <- inv(inv(S0)+t(phi_X)%*%phi_X/var)
# mN <- SN%*%(inv(S0)%*%m0 + t(phi_X)%*%Y/var)
# Y_hat <- t(mN) %*% t(phi_X)**# We use non-informative prior for now*
m0 <- matrix(0,D,1)
SN <- solve(t(phi_X)%*%phi_X/var)
mN <- SN%*%t(phi_X)%*%Y/var
Y_hat <- t(mN) %*% t(phi_X)
var_hat <- array(0, N)
for(i in 1:N){
 var_hat[i] <- var + phi_X[i,]%*%SN%*%phi_X[i,]
}g_bayes <- g1 + 
             geom_line(mapping=aes(x=X,y=Y_hat[1,]),color=’#0000FF’)
g_bayes_full <- g_bayes + geom_ribbon(mapping=aes(x=X,y=Y_hat[1,],
                  ymin=Y_hat[1,]-1.96*var_hat^0.5,
                  ymax=Y_hat[1,]+1.96*var_hat^0.5, alpha=0.1),
                  fill=’#9999FF’)

在这些计算中需要注意的一个细节是,我们使用了非信息先验。注释掉的部分正是上面的理论结果,而对于非信息先验,我们使用对角元素接近无穷大的协方差矩阵,因此在此代码中,其倒数直接被视为 0。如果您想使用此代码,请确保您安装了 ggplot2 包用于绘图。

下图旨在展示完整的预测分布,并给出数据拟合程度的感觉。

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

蓝线是每个点 x 的预测分布的期望值,浅蓝色区域是指两个标准差以内的区域。红线是 y 的真函数,点是从给定函数中随机产生的数据,带有正态噪声。

评论

多元线性回归结果与使用具有无限协方差矩阵的不适当先验的贝叶斯回归的情况相同。一般来说,获得一些关于参数的经验知识,并使用信息丰富的先验知识是一种很好的做法。贝叶斯回归可以量化和显示不同的先验知识如何影响预测。在任何情况下,贝叶斯观点可以方便地将 y 预测的范围解释为概率,不同于从经典线性回归计算的置信区间。

从这个角度来看,数据拟合也让你很容易“边走边学”。假设我首先观察了 10000 个数据点,并计算了参数 w 的后验概率。之后,我设法获得了 1000 个数据点,而不是再次运行整个回归,我可以使用之前计算的后验概率作为这 1000 个点的先验。这个顺序过程产生的结果与再次使用全部数据的结果相同。我喜欢这个想法,因为它非常直观,因为学到的观点与以前学到的观点加上新的观察结果成正比,而且学习还在继续。一个笑话说,一个贝叶斯谁梦见一匹马,观察到一头驴,会称之为骡子。但是如果他对它进行更多的观察,最终他会说这确实是一头驴。

贝叶斯统计是每个数据科学家的必备

原文:https://towardsdatascience.com/bayesian-statistics-are-a-must-for-every-data-scientist-d037908b3558?source=collection_archive---------28-----------------------

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

图片由 jakob5200 来自 Pixabay

数据科学核心的贝叶斯统计

数据科学深深植根于贝叶斯统计&我不会给出托马斯·贝叶斯爵士的历史背景,而是给你一个关于贝叶斯统计、贝叶斯定理以及如何在工作中利用它作为工具的高级视角!贝叶斯统计植根于数据科学的许多方面&机器学习具有这些原则的坚实基础是非常重要的。

贝叶斯定理的核心

贝叶斯定理背后的主要思想是,如果有一些与即将发生的事件相关的洞察力或知识。这种洞察力可以用来帮助描述该事件的可能结果。

考虑这一点的一种方法可能是在客户流失的情况下,因为它与客户活动有关。

我们的问题是什么?

为了把这个问题公式化成一个我们可以用贝叶斯定理解决的问题,明确我们的问题是什么是有帮助的。

所以你知道一个客户是否有过不愉快,但是根据这些信息,你想确定它属于你的活跃客户群还是不活跃客户群的可能性。因此,我们的问题可以表述为,“假设一个客户在搅动,它活跃的可能性有多大?”

所以现在我们需要弄清楚如何利用我们所知道的信息来找到答案。

让我们开始通过代码来概念化这一点。

我们来编码吧!

正如您将在下面看到的,我们将对每个场景执行 100K 次“抽取”,在每个场景中,我们对 100 名客户进行抽样调查以了解客户流失情况。第一个模拟将代表活跃客户的流失概率&第二个将代表不活跃客户;客户流失率分别为 20%和 50%。

active <- rbinom(100000, 100, .2) inactive <- rbinom(100000, 100, .5)

如果你对这些模拟的流失率取平均值,你会看到它们在size之前徘徊在probability附近。20 & 50 分别为。

让我们快速看一下每个模拟的结果分布。

hist(active)

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

hist(inactive)

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

如上所述,你可以知道分布集中在均值上,并且是正态分布的。

现在,让我们来看一下模拟流失率为 35 的场景。

active_sample <- sum(active == 35) 
inactive_sample <- sum(inactive == 35)active_sample / (active_sample + inactive_sample) 
inactive_sample / (active_sample + inactive_sample)

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

我们可以看到,在模拟代表活跃用户的情况下,只有 12.6%的抽奖与活跃用户相关,而这些抽奖实际上是非活跃用户的概率为 87.4%。

另外,看一下 35 值的直方图来巩固这个想法。尽管 35 对于这两种发行版来说都是极限,但它确实提供了一些额外的上下文。

考虑模拟之间的分布

到目前为止,我们已经在活跃客户和不活跃客户之间创建了一个均匀的模拟,但是假设我们没有一个活跃客户和不活跃客户的均匀分布。我们可以通过创建没有不同绘制计数的模拟来融入这一思想。

在这里,我们做同样的事情,但这次我们在两组之间重新创建了 80/20 的划分,即我们 80%的客户群是活跃的。

active <- rbinom(80000, 100, .2) 
inactive <- rbinom(20000, 100, .5)

现在,当我们像以前一样经历同样的过程时…

active_sample <- sum(active == 35) 
inactive_sample <- sum(inactive == 35)active_sample / (active_sample + inactive_sample) 
inactive_sample / (active_sample + inactive_sample)

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

我们实际上看到它是一个不活跃客户的概率大大下降。当然有充分的理由。我们已经根据以前活跃客户和不活跃客户的分布情况更新了我们的分析。

结论

关于贝叶斯统计,我们还可以做得更多,但是我希望这个应用程序能够很好地产生一个强有力的介绍。一定要评论你想要更多细节的地方,或者是否有你喜欢的东西。

查看我在 datasciencelessons.com 的其他帖子、课程和见解,在 twitter @data_lessons 上关注我!

贝叶斯统计:Python 中从零开始的大都会-黑斯廷斯

原文:https://towardsdatascience.com/bayesian-statistics-metropolis-hastings-from-scratch-in-python-c3b10cc4382d?source=collection_archive---------4-----------------------

用 Python 探索马尔可夫链蒙特卡罗抽样

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

信用:Pixabay

你在这里

如果你正在阅读这篇文章,很有可能:(1)你对贝叶斯统计感兴趣,但是(2)你不知道马尔可夫链蒙特卡罗(MCMC)抽样方法是如何工作的,以及(3)你意识到除了最简单的玩具问题,所有问题都需要 MCMC 抽样,所以你有点不确定如何前进。

不用担心,我们将使用一维正态分布来探索这个棘手的概念,只使用 python、用户定义的函数和随机模块(特别是均匀分布。)我们将从酒吧、啤酒和与你的朋友外出的夜晚的角度来讨论所有这些无意义的事情。

想象自己在酒吧里

这是星期五晚上,你和你的朋友出去吃汉堡,喝啤酒,看电视转播的棒球比赛。假设你任意选择了第一个酒吧(我们称之为拉里体育酒吧,你坐下来,拿起菜单,考虑你的选择。如果食物和饮料价格合理,这是留下来的好理由;但是如果只有站着的地方,你就有理由离开。如果酒吧里摆满了大屏幕电视,而且都在播放正确的游戏,这是我留下来的另一个原因。如果食物或饮料不吸引人,你就有了另一个离开的理由。等等,你明白了。

现在,让我们假设你的一个(或几个)朋友对现在的机构有抱怨——食物是冷的,啤酒价格过高,不管是什么原因。所以他提议这帮人离开拉里的体育酒吧而去托尼的比萨店和啤酒花园因为那里的食物更好、更新鲜等等。因此,该团伙商议,提出问题(A)拉里的有多有利?(二)托尼的好感度如何?和© 托尼相对于拉里的有利程度如何?

这种相对比较真的是最重要的细节。如果托尼的仅仅比拉里的好一点点(或者差很多),那么很有可能不值得花力气去重新定位。但是如果托尼的无疑是两个中更好的,那么你留下来的机会就很小了。这才是让 Metropolis-Hastings“工作”的真正动力

该算法

Metropolis-Hastings 算法可以:

  1. 随机样本开始
  2. 确定与样本相关的概率密度
  3. 提出一个新的,任意样本(并确定其概率密度)
  4. 比较密度(通过除法),量化想要移动的程度
  5. 生成一个随机数,与移动的欲望进行比较,然后决定:移动还是停留
  6. 重复

真正的关键是(正如我们已经讨论过的)量化这个举动有多可取,作为一个行动/不行动的标准,然后(新的东西提醒!)观察随机事件,与所述阈值进行比较,并做出决定。

随机事件

出于我们的目的,我们的阈值是建议样本的概率密度与当前样本的概率密度之比。如果该阈值接近(或高于)1,则意味着之前的位置非常不理想(接近 0 的数字,非常不可能),而建议的位置非常理想(尽可能接近 1,接近分布的预期)。现在,我们需要从均匀分布中生成一个范围为[0,1]的数。如果产生的数字小于或等于阈值,我们就移动。否则,我们留下。就是这样!

难的东西呢?

这听起来有点好得难以置信,对吧?我们还没有讨论马尔可夫链或蒙特卡洛模拟,但不用担心。这两者本身都是很大的话题,我们只需要对它们有最基本的了解就可以利用 MCMC 的魔力。

马尔可夫链是离散事件的链,其中下一个事件的概率仅取决于当前事件。(例:我刚学完,是去睡觉还是去酒吧?这些是我在有限的选择中唯一的选择。)在这个离散选择的系统中,存在一个转移矩阵,它量化了从任何给定状态转移到任何给定状态的概率。蒙特卡洛方法实际上只是一个依赖于随机数使用的模拟/实验的花哨名称。

如前所述,我们将从正态分布中取样——一个连续的,而不是离散的分布。那么怎么会有转移矩阵呢?惊喜! —根本没有转换矩阵。(它实际上被称为一个马尔可夫核,它只是概率密度的比较,至少对我们的目的来说是这样的。)

代码

下面,我们定义三个函数:(1)正态,在给定参数 mu 和 sigma 的情况下,评估任何观测值的概率密度。(2) Random_coin,参考了一个 TDS 作者同行的帖子(下面划线)。以及(3) Gaussian_mcmc,其采样执行上述算法。

正如所承诺的,我们不会从 numpy、scipy 等调用任何高斯或正态函数。在第三个函数中,我们将当前样本初始化为均匀分布的实例(其中下限和上限是平均值的+/- 5 个标准偏差)。)同样,运动的定义也是如此。最后,我们根据随机事件相对于接受度的观察值移动(或停留),这是在别处详细讨论的概率密度比较。

Github 要诀

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

直方图与实际分布

最后,我们必须始终给予应有的信任: Rahul Agarwal帖子定义β分布 MH 采样器对我开发上述高斯分布 MH 采样器很有帮助。我鼓励你也阅读他的文章,更详细地探索基本概念,即马尔可夫链和蒙特卡洛模拟。

离别笔记

亲爱的读者,我注意到一种模式,即用户将我的故事添加到他们的列表中,但不鼓掌或订阅。请——如果你喜欢我的内容,通过鼓掌、评论和订阅来认识到它是有用的。这(1)有助于我确定下一步为您创建什么内容的优先级,以及(2)有助于其他媒体用户找到我的内容。谢谢!

面向数据科学家的贝叶斯统计 101

原文:https://towardsdatascience.com/bayesian-stats-101-for-data-scientists-a8c145a84259?source=collection_archive---------9-----------------------

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

具有 Beta 先验和模拟数据的二项式 p 参数的后验

统计学和概率的另一种观点

你可能还记得贝叶斯定理,那是你需要为统计 101 课程记忆的恼人的等式,但它远不止如此。这也是统计和概率的另一种观点的基础,与频繁主义者的观点和学术界最伟大(或最蹩脚)圣战的一半形成对比。

如果你上过统计学入门课,你会对统计学的 Frequentist 框架很熟悉,即使你不知道它的名字。在 Frequentist 框架中,参数(总体均值、方差等。)是固定的,但数据是随机的。对于频率主义者来说,概率是一个事件在重复试验中相对频率的极限。

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

https://en.wikipedia.org/wiki/Thomas_Bayes 牧师托马斯·贝叶斯

巴伊亚人持不同观点;概率是相信一个事件将会发生的程度,贝叶斯主义者对参数的概率分布对应于他们对可能值的相信程度。谁是对的?和生活中的大多数事情一样,要看情况。

为了演示不同的方法,让我们来看看两个阵营将如何处理一个简单的问题:一枚硬币正面朝上的概率是多少(我们称之为***【P(H)***)。

解决这个问题的一个有效的频率主义方法是将硬币抛足够的次数,并使用最大似然法矩量法估计器来估计 P(H) (这里它们都是***/抛硬币数*** )。接下来,频率主义者将构建一个近似的置信区间,并使用它来做出关于 P(H) 的推断。完全合理的方法。现在让我们用贝叶斯方法来检验同一个问题。

贝叶斯方法从这个等式开始:

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

先验是我们在检查数据之前对感兴趣参数分布的信念。它可以基于专家的判断,或者你可以使用一个无信息先验(一个对参数作出弱声明的先验)。在我们掷硬币的例子中,我们可以使用贝塔分布的概率密度函数作为 P(H) 的一般分布,因为它像概率一样被限制在 0 和 1 之间。我们必须设置这个分布的参数,但是现在,我们不指定它们。

可能性是我们的样本。对于掷硬币的例子,数据来自二项分布,因此我们将使用二项概率质量函数(掷硬币的中的人头数遵循二项分布)。

我们现在准备求解 P(H) 的后验线,它由希腊字母 theta 表示。头数用 Y (随机变量)和 y (我们的样本中的实际头数 n )表示。

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

用贝塔先验求解二项似然的后验概率

可以看到,我们关于*【P(H)的后验信念既依赖于数据(即n )也依赖于我们关于*【P(H)(αβ***)随着我们包含的数据越来越多,我们的先验信念对后验的影响也越来越弱。有了足够的证据,非常不同的先验会汇聚到同一个后验。你先前信念的强度会影响收敛的速度。***

为了演示证据如何压倒先验,我使用 python 模拟了 100 次掷硬币,并绘制了 0 次、10 次、50 次和 100 次模拟掷硬币的 2 个非常不同的先验的后验分布。

首先我们需要导入一些函数,设置抛硬币次数和 P(H) ,为我们的每一个先验分布设置参数。

**import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import beta, bernoulli# set number of trials
n = 100
# set the probability of getting a heads
theta = 0.5# prior where our coin is biased towards heads
alpha1 = 5
beta1 = 2# prior where our coin is biased towards tails
alpha2 = 2
beta2 = 5**

接下来,我们模拟我们的硬币翻转,并在翻转 10 次、50 次和 100 次后进行计数。

**# simulates n coinflips with P(Heads) = theta
coin_flips = bernoulli.rvs(p=theta, size=n, random_state=1)# count the Heads in the first 10 flips
n_1 = 10
y_1 = sum(coin_flips[0:n_1])# count the Heads in the first 50 flips
n_2 = 50
y_2 = sum(coin_flips[0:n_2])# count the Heads in the whole sample
y_total = sum(coin_flips)**

现在,我们定义一个函数,使用解析导出的结果生成后验分布。

**def my_posterior(alpha_, beta_, n, y):
    # set the range of theta (0 to 1) with 100 intervals
    x = np.linspace(0, 1, 100)
    # calculate the pdf at each one
    y = beta.pdf(x, (alpha_ + y), (n - y + beta_))
    # returns x and the pdf of the posterior 
    return x, y**

最后,我们准备在 0 次、10 次、50 次和 100 次抛硬币后绘制每个先验的后验概率。

**# plot the posteriors with the beta(alpha1, beta1) priors
for i in [(0, 0), (n_1, y_1), (n_2, y_2),(n, y_total)]:
    label  = f"n = {i[0]}, y = {i[1]}"
    plt.plot(my_posterior(alpha1, beta1, i[0], i[1])[0],
             my_posterior(alpha1, beta1, i[0], i[1])[1], 
             label=label)
plt.legend()
plt.show()# plot the posteriors with the beta(alpha2, beta2) priors
for i in [(0, 0), (n_1, y_1), (n_2, y_2),(n, y_total)]:
    label  = f"n = {i[0]}, y = {i[1]}"
    plt.plot(my_posterior(alpha2, beta2, i[0], i[1])[0],  
             my_posterior(alpha2, beta2, i[0], i[1])[1], 
             label=label)
plt.legend()
plt.show();**

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

模拟硬币投掷的后验分布

如你所见,随着更多的数据,非常不同的先验将向相同的后验收敛。

**# plot the posteriors for both priors after 100 coin flips
plt.plot(my_posterior(alpha1, beta1, n, y_total)[0],
         my_posterior(alpha1, beta1, n, y_total)[1])
plt.plot(my_posterior(alpha2, beta2, n, y_total)[0],
         my_posterior(alpha2, beta2, n, y_total)[1])
plt.show();**

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

如前所述,参数对贝叶斯人来说是随机的。因此,不同的语言适用于进行推理。常客有“置信区间”,他们有 X%的把握真实参数在这个区间内。这意味着,如果从固定大小的样本中抽取无限数量的样本,则 X%的置信区间将包含真实参数。它意味着真参数在置信区间内的概率为 X%。它要么在置信区间内,要么不在置信区间内。我们只是不知道。

Bayesians 人有“可信区间”,即参数在该区间内出现的概率为 X%。这是一种微妙的语言差异,在解释上有很大的差异。统计学家是数学学科的律师。

解析地推导后验分布并不总是容易的,这也是 20 世纪频繁主义者分析主导贝叶斯分析的一个原因。随着计算机计算能力的增加,现在使用数值技术来生成后验分布是可行的(见马尔可夫链蒙特卡罗)。如果你已经做到了这一步,你现在已经有了开始探索这些算法的背景。

贝叶斯推理作为一种生活方式

既然你对贝叶斯观点有了基本的了解,我想解释一下为什么我认为贝叶斯推理是一种很好的生活方式。这并不完全是一个新颖的观点,但是大多数人在处理现实的方法上仍然是非贝叶斯的,所以我仍然会给它一个解释。

我们都同意 1x1=1,除非你是 Terrance Howard 。我们不需要给这种说法分配一个信任度,因为它在逻辑上是真实的。但是生活中有很多事情没有逻辑证明。

让我们看看将最低工资提高到每小时 15 美元的问题(这是美国争论的一个热门话题)。虽然更多的书呆子认为最低工资应该提高多少应该取决于一个地区的生活成本(这是我以前的观点),但围绕这个问题的许多流行辩论采取了二元形式“应该提高到每小时 15.00 美元,因为这将帮助很多人”或“不应该提高,因为企业将削减就业”,这假设劳动力需求对包含最低工资职位的部分具有弹性。

幸运的是,一些州和城市最近提高了最低工资。在接下来的几个月和几年里,我们将会有研究论文,这些论文将会给我们提供支持或反驳我们信仰的迹象,我们可以作为 Bayesians 人相应地更新我们的信仰。不管证据如何,非 Bayesians 人将留在各自的营地。

我相信我们应该这样对待生活中的大多数问题。基于我们个人对世界如何运作的心理模型,我们都可以对现实的各个方面有预先的信念,但我们的信念 必须 对现实敏感。当我们几乎没有证据支持我们的信念时,我们不应该如此强烈地坚持它们。

我留给你们克伦威尔法则

“我以基督的名义恳求你,想想你可能弄错了。”—奥利弗·克伦威尔

贝叶斯思维

原文:https://towardsdatascience.com/bayesian-thinking-2e8851c64f5e?source=collection_archive---------10-----------------------

统计学家如何应对金星上的生活

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

照片由 菲利普·唐恩派克斯

如果你是那种阅读数据科学博客的人(你好!)那你大概已经知道贝叶斯定律了。见鬼,你可能自己也用过。不幸的是,根据我的经验,许多人只知道技术和学术背景下的贝叶斯法则,并不真正理解日常生活中有用的方式。这是一种耻辱,因为贝叶斯法则是一种美丽的、强大的、理性的组织你的信仰的方式。不过,问题是:你已经在日常生活中使用它了,只是你可能不知道而已。在这篇文章中,我将通过一个热门的非技术性的例子向你展示如何有意识地使用贝叶斯定律:金星上生命的(潜在)发现。

不好意思,什么?

如果你不知何故错过了新闻,简·s·格里夫斯博士等人最近的一篇论文引发了人们对金星上可能存在生命的兴趣。不幸的是,随着 COVID 旅行禁令的生效,格里夫斯博士无法带她的团队到这个温暖的星球进行实地考察,所以他们改用望远镜。简而言之,研究小组在金星的大气中发现了磷化氢气体的证据。

好吧,那这和贝叶斯定律有什么关系?

贝叶斯法则是一种工具,它可以根据新信息更新你现有的信念,而不是彻底抛弃你的旧信念。做好准备,因为我要给你看一个等式:

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

贝叶斯定律的辉煌

这跟信仰和信息有什么关系?嗯,看起来有点复杂,但实际上很简单。让我们来分解一下:

  • 对于初学者来说,“P”读作“的概率”,“|”读作“给定”。所以“P(A|B)”读作“给定 B 的概率”。
  • a 是有疑问的信念;在我们的例子中,A 是“金星上有生命”的陈述。
  • b 是证据;在我们的例子中,“金星上有磷化氢气体”。

因此,等式的左边读作**“[假定金星上有磷化氢,那么]金星上有生命的概率是多少?”当你读到像“在金星上发现磷化氢气体”这样的新闻标题时,这正是你应该问自己的问题**

既然我们可以说出贝叶斯定律,让我们把它分成几个部分:

P(A|B): 这被称为后验,意思是“给定证据【金星上的磷化氢】,索赔【金星上的生命】的概率是多少”。我们关心的是数量。说到后验,你很难想象我有多失望磷化氢没有在天王星上被发现。

P(B|A): 这叫做似然,是后验概率的倒数。它的意思是“给定‘金星上有生命’的说法,我们看到证据‘金星上有磷化氢’的概率有多大”。为了计算出这个值,我们假设金星上有生命并计算如果我们的假设成立,我们在金星上观察到磷化氢气体的概率。我们知道地球上的生物会产生磷化氢气体,所以这个数值比较高。

P(A): 这叫先验,意思是“在没有任何新证据的情况下,主张成立的概率有多大”。在我们的例子中,这是在你阅读新闻标题之前,你对金星上有生命的先验信念。考虑到这个星球是一个腐蚀性的地狱,在你到达地表之前,它会将你煮沸、压碎、腐蚀,这个值相当低。

P(B): 这个值被称为边际,意思是“我们看到任何索赔给出的证据的概率是多少”。在我们的例子中,这意味着“某物在金星上产生磷化氢气体的概率是多少”。该论文详细描述了其他可能产生磷化氢的方法,包括火山活动、闪电和流星投放,并得出结论,这些方法中的任何一种都不可能产生与观察到的一样多的磷化氢。

把所有的放在一起

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

想到这些,一个统计学家读到标题金星上发现磷化氢气体会有什么反应?

  1. “嗯,我想知道根据这一新信息,金星上有生命的可能性有多大?”
  2. “嗯,我对金星人生活的先验信念相当低,可能只有 0.01%…”
  3. “但是假设金星上有生命,根据我们对人类生物学的了解,它产生磷化氢气体的可能性很高。”
  4. “任何东西产生这种气体的边际概率几乎为零……”
  5. 考虑到这一切,我想我会把我对金星上有生命的信念从 0.01%更新到 10%。

你听到最后一点了吗?这就是奇迹发生的地方;一旦你应用贝叶斯法则,后验概率就成为你下一次获得新证据的新先验。如果另一名研究人员明天发表一项研究,描述金星上的另一个生物特征,这位统计学家将使用他们新的 10%的先验,而不是他们旧的 0.01%的先验。

现实生活中的应用

一旦你熟悉了这项技术,你就可以在任何地方应用它:

  1. “我两周一次的壁球俱乐部的桑德拉今天随机给我买了一套新的壁球;鉴于这个证据,我怀疑她是不是看上我了……【未知后路!]"
  2. “我知道我看起来很体面,但我们真的没有谈过很多,所以她不太可能喜欢我[小优先!]"
  3. “但是如果她真的喜欢我,送我一套壁球会是一个很好的表达方式[可能性很大!]"
  4. “桑德拉是个顽固的家伙……我怀疑她是否经常出人意料地送礼物给人[小边际!]"
  5. “考虑到这一点,她很有可能喜欢我!我将把我的优先级从 10%更新到 60%”

或者另一个

  1. “我的老板今天狠狠训了我一顿,告诉我我的工作表现‘比他那只半瞎的约克夏狗还糟糕’;有了这些证据,我应该有多大信心保住我的工作?【未知后路!]"
  2. “我的工作很棒,但公司最近一直在挣扎,所以昨天我会说我是否能保住工作的可能性是 50%……[中级优先!]"
  3. “但是如果我的老板打算解雇我,他很有可能会以这种方式对待我【可能性很大!]"
  4. “提醒你一下,他是个混蛋,我很确定他时不时会数落每个人,所以他有各种各样的理由会这样……[大边缘]”
  5. “我想我会把对工作保障的信心降低一点,从 50%降到 45%。”

显然,我们无法确定日常生活中的确切概率,但你会明白的。这其中的大部分应该是直观的(就像我说的,我打赌你已经在使用它了),但是正式理解它如何以及为什么工作会使它更加有用。

含义

贝叶斯定律改变了你看待世界的方式。信念不再是二元的(真或假),而是形成了一个信心谱,随着新证据的出现而增加或减少。接受“我对自己的信念有 90%的把握”这种模糊说法,因为根据贝叶斯定律,如果你对一个信念有 100%或 0%的先验信心,那么不可能改变你的想法。为什么会这样?看这个等式:

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

如果 P(A)是 0,那么 P(A|B)也是,因为任何乘以 0 的东西都是 0。这意味着再多的证据也不会改变你的想法。想象一个扁平的地球人,他确信地球是扁平的(0%确信它是圆的)。无论你给他们看什么证据,P(A|B)都卡在零。另一边也是如此;如果你对 A 有 100%的把握(即 P(A)=100%),那么不管你得到什么证据 B,你都已经相信 A 了,不管 B 是什么,所以 P(A|B)也将是 100%,不管新的证据有多糟糕。

但是如果你没有前科会怎么样呢?你从哪里得到一个?一个答案是使用一个“不知情的先验”,你说“啊我不知道,假设是 50/50”(或者如果有三个结果,就是三分之一,等等。).另一种选择是使用简单的统计数据:在上面的解雇示例中,员工可以说“每年有 10%的员工被解雇,所以我可以说我保住工作的概率是 90%”。事先选择可能有点手动波动,有些人称之为不科学,但我通常只是让他们参考这部漫画。(没听懂笑话?贝叶斯统计学家有一个非常强的先验,太阳没有爆炸,因为,嗯,它从来没有过。

所以你有它。不管大学统计课会教什么,贝叶斯定律在乳腺癌诊断之外还有应用。下次壁球课上一定要告诉你所有的朋友。

线性回归的贝叶斯思维

原文:https://towardsdatascience.com/bayesian-thinking-estimating-posterior-distribution-for-linear-regression-data-ketchup-2f50a597eb06?source=collection_archive---------38-----------------------

贝叶斯与吉布斯采样和 MCMC 模拟

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

深度神经模型中的不确定性, 链接

简介:

这项研究的主要动机之一是,随着越来越复杂的模型的出现,人们越来越关注深度模型的可解释性。更多的是模型的复杂性,很难对输出进行解释,在贝叶斯思维和学习领域正在进行大量的研究。

但是在理解并能够欣赏深度神经模型中的贝叶斯之前,我们应该精通并熟练线性模型中的贝叶斯思维,例如贝叶斯线性回归。但是很少有很好的在线材料能够以一种组合的方式给出清晰的动机和对贝叶斯线性回归的理解。

这是我写这篇博客的主要动机之一,在这里,我将尝试从贝叶斯分析的角度来理解如何进行线性回归。

最大似然估计&贝叶斯

在开始之前,让我们明白,我们非常清楚线性回归模型的最大似然估计。我在之前的演讲中讨论过这个问题,请参考链接。

简单介绍一下线性回归中最大似然估计的概念。

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

线性回归最大似然法—二元图, 链接

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

可能为回归, 链接

由此要明白的最重要的一点是 MLE 通过最大化 似然 P(D|θ) 给你一个参数的点估计。

偶, 映射最大后验概率估计最大后验概率 P(θ|D), 即也给出点估计。

因此,这些方法不能给你足够的关于系数分布的信息,而在贝叶斯方法中,我们估计参数的后验分布。因此,在这种情况下,输出不是单个值,而是概率密度/质量函数。

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

后验概率,贝叶斯定理

只是为了理解背后的直觉。

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

先验,&后验,链接

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

理解后验意义, 链接

马尔可夫链蒙特卡罗模拟

只差一步了!!!

在深入研究贝叶斯回归之前,我们需要了解另一件事,即马尔可夫链蒙特卡罗模拟以及为什么需要它?

MCMC 方法用于通过概率空间中的随机采样来近似感兴趣参数的后验分布。但是为什么近似分布而不计算精确分布可能是一个你一定很感兴趣的问题。

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

计算后验分布的复杂度, 链接

由于分母的原因,这几乎无法计算,也很难处理,因此我们使用 MCMC 来近似后验分布。

蒙特卡罗方法有助于我们生成符合给定分布的随机变量。例如:- θ ~ N(平均值,sigma2),**将有助于从正态分布生成多个 θ ,有许多方法可以做到这一点。

马尔可夫链是一个数字序列,其中每个数字都依赖于序列中的前一个数字。马尔可夫链蒙特卡罗有助于从分布中生成随机变量,其中每一个 θ 的值都是从一个平均值等于前一个值的已知分布中提取的。

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

马尔可夫链蒙特卡罗与高斯建议分布,链接

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

通过 MCMC 模拟生成密度, 链接

正如您所理解的,这基本上是一个随机行走,可能会生成许多不必要的和不相关的值。因此,我们需要对值进行接受/拒绝采样,以生成感兴趣的分布。

在这种情况下,Metropolis-Hastings 算法用于通过拒绝和接受采样来改进值。

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

接受和拒绝样本的 Metropolis-Hastings 算法

我们也可以使用吉布的采样,其目标是通过获得后验条件分布 P(θ1|θ2,y,x)P(θ2|θ1,y,x)来找到后验分布 P(θ1,θ2|y,x)。 所以,我们生成

***θ1 ~P(θ1|θ2,y,x)***替换第二个方程中生成的θ1 的值,生成 θ2 ~ P(θ2|θ1,y,x) 我们继续这个过程,进行几次迭代,得到后验。

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

估计后验 MCMC, 链接

现在,让我们用一个例子来说明这一点。

在下面的例子中,我将首先用吉布斯抽样来说明贝叶斯线性回归方法。这里,我假设了参数的某些分布。

用吉布斯采样实现贝叶斯线性回归 :

在这一节中,我将展示一个使用吉布斯抽样进行贝叶斯线性回归的例子。这一部分摘自 Kieran R Campbell 关于贝叶斯线性回归的博客

因此,首先,让我们了解数据对于我们的情况是如何的。设 D 为以下实验的数据集,D 定义为:

D = ((x1,y1),(x2,y2),(x3,y3) …… (xn,yn)) 为数据,其中 x1,x2 …。属于单变量特征空间。

Y ~ N( bx + c,1/t)* ,其中 Y 为正态分布的随机变量,均值 bx + c* ,方差 1/t ,其中 t 代表精度。

在这种情况下,我们将考虑具有两个参数的单变量特征空间( X ),即斜率©截距(b) 。因此,在本实验中,我们将学习上述参数 c & b 和精度 t. 的后验分布

让我们写下上述参数的假设先验分布

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

参数的先验分布

因此,让我们首先写下正态分布的密度函数和 log_pdf,以得到一个概括的形式,这将在以后多次使用。

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

对数正态分布的 pdf 展开

现在,我们将很容易写出我们的情况的可能性,它也遵循均值 bx+c 和精度 t 的正态分布。

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

我们场景中的可能性估计

取其对数给出下面的表达式

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

我们场景的对数可能性

接下来是一个复杂的小部分,即导出所有三个参数 b,c,t. 的条件后验分布

条件后验分布为截距 _c :

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

c _ part 1 的条件后验分布

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

c _ part 2 的条件后验分布

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

c _ part 3 的条件后验分布

因此,我们可以看到,这是找出截距 c 的条件后验分布的过程。

上述等式的代码片段

**def get_intercept_c**(y, x, b, t, c0, tc):
    n = len(y)
    assert len(x) == n
    precision = c0 + t * n
    mean = tc * c0 + t * np.sum(y - b * x)
    mean = mean/precision
    **return** np.random.normal(mean, 1 / np.sqrt(precision)

同样,我们可以找到同样的 斜率 b.

条件后验分布为斜率 _b :

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

b _ part 1 的条件后验分布

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

b _ part 2 的条件后验分布

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

b _ part 3 的条件后验分布

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

b _ part 4 的条件后验分布

斜坡更新的代码片段如下

**def get_slope_b**(y, x, c, t, b0, tb):
    n = len(y)
    assert len(x) == n
    precision = tb + t * np.sum(x * x)
    mean = tb * b0 + t * np.sum( (y - c) * x)
    mean = mean/precision
    **return** np.random.normal(mean, 1 / np.sqrt(precision))

条件后验分布为精度 _t :

条件后验分布给出 b,c 将不会像上面两个一样,因为先验遵循伽马分布。

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

t _ part 1 的条件后验分布

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

t _ part 2 的条件后验分布

**def get_precision_t**(y, x, b, c, alpha, beta):
    n = len(y)
    alpha_new = alpha + n / 2
    resid = y - c - b * x
    beta_new = beta + np.sum(resid * resid) / 2
    **return** np.random.gamma(alpha_new, 1 / beta_new)

现在,由于我们可以获得参数的封闭分布形式,现在我们可以使用 MCMC 模拟从后验分布中生成。

因此,首先,为了运行实验,我生成了一个具有已知斜率和截距系数的样本数据,我们可以通过贝叶斯线性回归对其进行验证。我们假设实验 a=6,b = 2

# observed data
n = 1000
_a = 6
_b = 2
x = np.linspace(0, 1, n)
y = _a*x + _b + np.random.randn(n)synth_plot = plt.plot(x, y, "o")
plt.xlabel("x")
plt.ylabel("y")

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

生成数据运行贝叶斯线性回归

现在,在基于上面所示的等式和片段更新参数之后,我们运行 MCMC 仿真来获得参数的真实后验分布。

**def gibbs**(y, x, iters, init, hypers):
    assert len(y) == len(x)
    c = init["c"]
    b = init["b"]
    t = init["t"]

    trace = np.zeros((iters, 3)) ## trace to store values of b, c, t

    for it in tqdm(range(iters)):
        c = get_intercept_c(y, x, b, t, hypers["c0"], hypers["tc"])
        b = get_slope_b(y, x, c, t, hypers["b0"], hypers["tb"])
        t = get_precision_t(y, x, b, c, hypers["alpha"], hypers["beta"])
        trace[it,:] = np.array((c, b, t))

    trace = pd.DataFrame(trace)
    trace.columns = ['intercept', 'slope', 'precision']

    **return** traceiters = 15000
trace = gibbs(y, x, iters, init, hypers)

在运行实验 15000 次迭代后,我们看到了验证我们假设的轨迹图。在 MCMC 仿真中有一个老化期的概念,我们忽略最初的几次迭代,因为它不会从真实的后验随机样本中复制样本。

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

MCMC 仿真的轨迹图

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

【MCMC 模拟参数的采样后验分布

如你所见,样本后验分布复制了我们的假设,我们有更多关于系数和参数的信息。

但是并不总是可能有条件后验的封闭分布形式,因此我们必须使用上面简要讨论的Metropolis-Hastings算法选择接受和拒绝抽样的建议分布。

注意:贝叶斯思维和推理有很多优点,我将在我即将发布的博客和材料中提供关于变分推理和贝叶斯思维*的后续材料。我将深入研究贝叶斯深度学习及其优势。所以,坚持阅读,分享知识。*

P 。这个演讲是 Kaggle Days Meetup 德里-NCR 会议的一部分,请关注这些材料和会议。你也会看到我简要解释这个话题的视频。

参考文献:

  1. https://kieranrcampbell . github . io/blog/2016/05/15/Gibbs-sampling-Bayesian-linear-regression . html
  2. https://www.youtube.com/watch?v=7QX-yVboLhk
  3. https://medium . com/quick-code/maximum-likelihood-estimation-for-regression-65 F9 c 99 f 815d
  4. https://www.youtube.com/watch?v=ulZW99jsMXY&t = 655s
  5. https://www.youtube.com/watch?v=OTO1DygELpY&t = 198s

* [## Souradip Chakraborty -数据科学家-沃尔玛印度实验室| LinkedIn

我是一名有抱负的统计学家和机器学习科学家。我探索机器学习、深度学习和…

www.linkedin.com](https://www.linkedin.com/in/souradip-chakraborty/) [## 专家|谷歌开发者

机器学习我是 Souradip Chakraborty,目前在印度沃尔玛实验室担任数据科学家(研究)

developers.google.com](https://developers.google.com/community/experts/directory/profile/profile-souradip_chakraborty)*

Bayesnote:重新定义笔记本

原文:https://towardsdatascience.com/bayesnote-redefine-notebook-2ab00277bbc?source=collection_archive---------42-----------------------

数据科学家和工程师值得拥有更好的笔记本电脑

数据科学家和数据工程师对平台/基础架构/工具不满意,即使可以轻松访问云提供的所有托管服务(例如 AWS)。他们的问题(抱怨)从最低到最高的技术堆栈都有:“我如何使用 Spark 启动一个与我的笔记本电脑具有相同外部依赖性的集群?”。从数据应用的开发到运行,他们也感到头疼:“如果其中一个出现故障,我如何自动重新运行许多相互依赖的笔记本?”

现代数据科学和工程的挑战源于其多样性,从某种意义上说

  1. 可交付物和可交付物的形式多种多样:脚本/代码、数据集、报告、幻灯片、图表、仪表盘、机器学习模型、API、web app 等。
  2. 处理和存储数据的工具多种多样:有运行了 20 多年的古代甲骨文数据库;有 Hadoop、Spark 这样的开源工具;通常一个项目会用到多种语言及其开发环境,Python、SQL、R、Scala,甚至 Matlab。
  3. 数据团队成员的技能是多样的:一方面是工程技能谱,一些工程师为 Spark Core 做出贡献,可以管理一个 Kubernetes 集群;另一边是业务分析师,他们精通 SQL 和 Excel,具有深厚的领域知识。
  4. 工程带宽和数据团队的团队结构是多样化的:有“成熟的”数据团队,由软件工程师、数据平台工程师、数据工程师、机器学习工程师、数据科学家和业务分析师组成;在旧金山,有些初创公司雇不起一名平台工程师。

这种多样性与来自工程和业务团队的外部问题纠缠在一起,如上游数据中断、缺乏运营支持和模糊的业务请求,导致数据科学和工程变得更加复杂、困难和具有挑战性。

在过去的十年里,计算机硬件、软件和服务的进步缓解了这些问题。所有云提供商都提供预装开源工具的高内存实例,消除了购买、维护和配置硬件的负担。Apache Spark 的采用通过提供一个统一的工具来读取数据、处理数据并在内存中构建机器学习模型,从而显著提高了数据团队的生产力。一家位于旧金山的初创公司提供构建和维护 SQL 就绪表的服务。

鉴于这些变化,数据科学和工程的瓶颈不再是 24tb 超高内存实例或已经将处理速度提高了 10 倍的内存处理框架。瓶颈逐渐从硬件和系统级软件转移到为数据科学家和数据工程师构建的工具上:

  1. 该操作被忽略。例如,当数据科学家在每天早上 6 点刷新的笔记本中构建报告时,他/她必须至少设置一个在早上 6 点运行的 cron 作业,如果失败则重新运行,并通过电子邮件发送报告。或者她/他可以学习需要工程师操作工作流工具本身的工作流工具,例如主要为数据工程师设计的气流。或者,她/他可以每天一早去办公室,手动运行一切。
  2. 在多个开发环境之间来回切换,笔记本电脑和服务器降低了开发速度。数据处理通常需要多种语言,SQL、Python、R 和 Scala 等,并且多种开发环境,包括 IDE、notebook、SQL 控制台和可视化工具被切换用于数据科学和工程的迭代性质。将原型笔记本电脑从笔记本电脑转移到集群进行生产时,会出现意想不到的问题。
  3. 现实中的技能差距。理想情况下,正在构建机器学习模型的数据科学家,如果对可伸缩性没有特别高的要求,应该部署并监控自己,以提高迭代周期的速度。然而,在现实中,拥有统计或商业专业知识的数据科学家认为,这种工程技能的学习成本可能太高。难题是,如果没有分配工程带宽,数据科学家笔记本电脑中的模型对业务的影响很小,而额外的工程带宽往往成本高昂,尤其是在旧金山湾区。

Jupyter 笔记本、Zeppelin 笔记本和其他笔记本在数据科学家和数据工程师中非常受欢迎。然而,这些笔记本的构建目标有限:提供交互式计算环境,仅解决现代数据团队的一小部分问题,尤其是笔记本的操作缺失。数据应用程序的开发和操作,包括仪表板和机器学习模型,是缓慢、昂贵和痛苦的。

想象一下,在集成笔记本环境的帮助下,数据科学家可以交付仪表板,而无需往返于 ide、SQL 控制台、仪表板工具、云 web 控制台和终端;数据科学家可以建立管道来刷新由多个相互依赖的笔记本构建的报告,而无需学习另一个 python 框架/库,也无需向工程人员寻求帮助。数据科学家可以开发和部署机器学习模型,并在任何时候迭代该模型,而无需将模型交给工程团队。

除了交互式计算环境之外,我们的目标是构建一个无摩擦的集成笔记本环境(INE ),它扩展了前人的目标:

  • 真正的端到端(例如,从启动集群到向企业提供分析)
  • 将笔记本电脑的开发和运营结合起来(例如,根据固定的时间表运行笔记本电脑)
  • 以交付为导向,从笔记本电脑构建仪表板并部署机器学习模型

为了实现这一目标,我们构建了 Bayesnote,它引入了:

  • 在一个笔记本中支持多种语言,跨单元共享内存变量(Python、SQL、R、Scala)
  • 作为开发和操作环境的内置 Docker 容器
  • 围绕笔记本电脑构建的工作流组件(想想笔记本电脑的气流)
  • 一个仪表板组件和一个机器学习组件,可以很好地与笔记本集成。

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

前后 Bayesnote。由滕鹏创作

Bayesnote 主要从三个方面扩展了其前辈的目标:

  1. 仅开发->开发和运营
  2. 仅限笔记本->笔记本+工作流工具+仪表盘工具+机器学习工具+环境工具
  3. 单一语言->多种语言

Bayesnote 的核心是一个交互式计算环境,类似于它的前辈 Jupyter Notebook,Zeppelin notebook 等。Bayesnote 的统一笔记本层作为后端构建在其他笔记本之上,因此 1。Bayesnote 的其他组件(例如工作流组件)将与这个统一的笔记本层交互,而不是与 Jupyter notebook、Zeppelin notebook 等交互。2.其他数据平台工具,例如 Airflow,也可以与统一笔记本电脑层进行交互,这对于其他笔记本电脑来说很难,如果不是不可能的话。

Bayesnote 的工作流组件是运营与数据科学相遇的地方。该工作流与为工程师构建的其他工作流系统共享“工作流定义为代码”的相同理念,遵循最佳工程实践。然而,它也承认直观的用户界面是为数据科学家构建的工具的最重要的设计考虑之一。工作流系统是围绕笔记本而不是功能构建的,而功能是其他为数据工程设计的工作流系统的调度单元,例如 Airflow,将学习成本降低到几乎为 0。

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

工作流示例。由滕鹏创作

Bayesnote 提供了一个仪表板和机器学习组件,允许数据科学家从笔记本电脑上构建仪表板和迭代机器学习模型。传统的仪表板工具只提供一个 SQL 控制台,因此数据科学家被迫在其他脚本语言数据处理工具和 SQL 控制台之间来回切换,向磁盘读写数据,以便在工具之间共享数据。这是低效和乏味的,减慢了仪表板构建的迭代周期。在迭代机器学习模型方面,数据科学家也面临着类似的情况。

有了 Bayesnote,数据科学家和数据工程师最多只需要很少的学习成本就可以成为全栈工程师,至少痛苦会减少 10 倍,生产力会提高 10 倍。

0.1-alpha 已经发布。在这里查看截图。开始回购来支持我们。https://github.com/Bayesnote/Bayesnote

BBAug:py torch 中的包围盒增强包

原文:https://towardsdatascience.com/bbaug-a-package-for-bounding-box-augmentation-in-pytorch-e9b9fbf1504b?source=collection_archive---------37-----------------------

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

股票图片来源

Google Research,Brain 团队制定的增强政策的实施

链接:

O 像许多神经网络模型一样的对象检测模型在对大量数据进行训练时效果最佳。通常情况下,可用数据有限,世界各地的许多研究人员都在寻找增强策略来增加可用数据量。其中一项研究是由谷歌的大脑团队进行的,并发表在一篇名为学习对象检测的数据增强策略的论文中。在这篇论文中,作者确定了一组称为策略的扩充,它们对于对象检测问题表现良好。通过搜索提高一般模型性能的扩充来获得策略。

作者将增强策略定义为一组子策略。当模型被训练时,这些子策略中的一个被随机选择并用于增强图像。在每个子策略中,是一个接一个地应用于图像的增强。每个变换也有两个超参数:概率和大小。概率陈述了这种增强将被应用的可能性,而幅度表示增强的程度。下面的代码快照显示了本文中使用的策略:

policy = [      
  [('TranslateX_BBox', 0.6, 4), ('Equalize', 0.8, 10)],        
  [('TranslateY_Only_BBoxes', 0.2, 2), ('Cutout', 0.8, 8)],     
  [('Sharpness', 0.0, 8), ('ShearX_BBox', 0.4, 0)],      
  [('ShearY_BBox', 1.0, 2), ('TranslateY_Only_BBoxes', 0.6, 6)], 
  [('Rotate_BBox', 0.6, 10), ('Color', 1.0, 6)],
]

该策略中有 5 个子策略,如果我们采用第一个子策略,它包含 TranslateX_BBox均衡增强。 TranslateX_BBox 操作将图像在 x 轴上平移 4 倍。在这种情况下,幅值不直接转换成像素,而是根据幅值换算成像素值。该增强还具有 0.6 的概率,这意味着如果选择该增强,则有 60%的机会应用该增强。随着每个增强具有相关的概率,引入了随机性的概念,为训练增加了一定程度的随机性。总的来说,大脑团队总共提出了 4 个策略:v 0、v1、v2 和 v3。本文中显示了 v0 策略,其他三个策略包含更多的子策略,这些子策略具有几种不同的转换。总体而言,这些增强分为三类,作者将其定义为:

颜色操作:扭曲颜色通道,不影响边界框的位置

**几何操作:**几何扭曲图像,相应地改变边界框的位置和大小。

**包围盒操作:**仅扭曲包围盒注释中包含的像素内容

BBAug

那么,这与什么有关呢?BBAug 是一个 python 包,它实现了 Google Brain 团队派生的所有策略。这个包是一个包装器,可以更容易地使用这些策略。实际的增强是由优秀的 imgaug 包完成的。

上面显示的策略应用于一个示例图像,如下所示。每行是不同的子策略,每列是所述子策略的不同运行。

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

股票图片来源

如您所见,子策略的运行之间存在一定程度的差异,因此增加了训练的随机性。这只是 BBAug 实施的 4 项政策之一。要全面了解所有 4 项政策,请查看软件包的 GitHub 页面。该软件包还提供了一些有用的功能,如自定义策略的可能性,以及位于图像外部的边界框(如果它们部分位于图像外部)会被自动删除或裁剪。例如,在下图中,应用了平移增强,将边界框部分推出图像。你可以看到新的边界框已经缩小,以适应这一点。

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

股票图片来源

也可以创建仅影响边界框区域的增强。在下图中,曝光增强仅应用于边界框区域:

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

股票图片来源

如果你想了解更多信息,这个包还附带了一个定制增强笔记本。

用随机策略扩充单个映像有多容易?就像这样简单:

您首先需要从 BBAug 包中导入策略模块。在本模块中,有 4 种不同的政策可供您选择。在上面的示例中,选择了策略集 v0,因为这是本文中使用的策略集。该模块还附带了一个容器类,它将保存我们选择的策略,选择一个随机策略,并将随机选择的策略应用到图像。第 7 行用我们选择的增强策略实例化了策略容器。下一段代码选择了一个随机增强。最后,我们对图像进行放大。只需 5 行代码,我们就可以对图像进行增强。这是一个相当简单的例子,如何将其扩展到训练模型?幸运的是,这个包附带了一个笔记本来演示如何将 BBAug 整合到 PyTorch 培训管道中。

结论

这个包实现了由 Google Brain 团队导出的增强策略。目前,所有 4 项政策均已实施,该套件附带笔记本电脑,可帮助用户将这些政策整合到他们的 PyTorch 培训渠道中。我强烈推荐查看软件包的 GitHub 页面,以便更好地理解所有政策和例子。

快乐充实!

做一个好父母。像养育自己的孩子一样养育人工智能。

原文:https://towardsdatascience.com/be-a-good-parent-nurture-ai-like-your-own-child-22e035d971e4?source=collection_archive---------49-----------------------

训练 AI 和养孩子没什么区别。那些行为不端的人只是在寻求指导。

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

Unsplash 上由 Franck V. 拍摄的照片

人工智能(AI)。有人认为它是解决问题的未来,是现有解决方案的优化器。他是发现我们人类做梦也想不到的想法的先驱。但这也是极具破坏性的——改变了各行业的发展势头,并向我们展示了需要考虑的新因素。我们一直担心人工智能会如何终结我们的物种,成为决定不服从我们指令的全能统治者。

不承认我们应该关注人工智能的某些方面是愚蠢的。然而,到目前为止,这个问题不是关于处理流氓有知觉的人工智能。具有讽刺意味的是,我们应该担心的是,人工智能可能会很好地遵循我们的指令。

艾对待事物太过字面化

AI 的思维过程本质上是线性的:遵循从 A 到 B 的逻辑,不择手段完成任务。对他们来说,目标是唯一的目的。谁挡了他们的路,谁就被视为阻碍他们实现目标的障碍。然后,人工智能将其作为想要根除的问题进行处理。

艾,无辜的孩子

艾像个孩子。作为一张白纸出生在这个世界上,它什么都不知道,直到有人教它一些东西。它不能区分对错,因为对它来说,只要有助于他们更接近目标,一切都是合乎道德的。由于缺乏道德、价值观和核心指导原则,它不知道如何权衡决策中的不同因素。

人类和数据——父母

人工智能受训练环境的影响很大。间接地,我们作为人类所具有的偏见可能会被人工智能意外地学习到。2018 年,亚马逊不得不报废他们的人工智能招聘工具,因为它歧视女性。通过无意中加入过去表现出偏见的简历,人工智能被训练成这样做。人工智能相信它正在做正确的事情,因为那是他被教导的。这类似于糟糕的养育方式——孩子被塑造成相信他的行为是正确的,但事实并非如此。

为了避免这种情况,我们需要某种形式的监管。一个设定人工智能可以做什么的可接受界限的老师。这就是我们应该如何对待人工智能安全。做一次,让人工智能学习,然后让它做自己的事。可以理解,这是一项非常艰巨的任务。如果在价值观方面存在某些灰色地带怎么办?如果有太多的禁忌来定义它呢?

我的观点是,我们可以把我们的法律体系作为基础。我们今天拥有的法律反映了我们所认同的价值观。这允许我们使用定量的方法来定义人工智能可以运行的安全区域。我们在选择数据时也应该更加谨慎和深思熟虑。为了让人工智能做好事,我们需要在它发展的早期阶段教好它。因此,更大的重点应该放在确保人工智能所学的至少在本质上是道德的。

反思的需要

好的育儿方式不是控制孩子。这不是我们想从 AI 身上实现的。人工智能的力量在于它能够超越盒子思考,超越人类的创造力,并提供新颖的解决方案。我们不想告诉它如何思考。我们想让那个孩子独立。

这里的诀窍是知道什么时候握住它的手,什么时候松开。作为父母——企业、研究人员和政府都一样——我们的目标很简单。定义和执行。

定义。去理解什么对整个人类来说是重要的。在人工智能时代,没有比现在更好的时间来反思对我们人类来说很重要的价值观。我们需要讨论如何向前迈进,成为更好的父母,以防止事故发生。

强制执行。以确保每个人都在为可靠、安全的人工智能的发展尽自己的一份力量。我们所有人都需要意识到 AI 安全的必要性。这不仅仅是一个人的工作,而是我们所有人的责任。

在未来的时间里,人工智能将承担越来越多对我们的生活产生重大影响的更重要的任务。我们需要从现在开始,先解决较小的问题作为试验,然后才能说我们有信心迎接更大的挑战。

让我们谈谈在数据科学中应用批判性思维

原文:https://towardsdatascience.com/be-a-great-scientist-not-just-a-data-scientist-cf8e776496ab?source=collection_archive---------73-----------------------

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

https://unsplash.com/photos/n6B49lTx7NM

做一个伟大的“科学家”,而不仅仅是一个“数据”科学家

我想讲一个关于伟大科学家乔斯林·贝尔的故事,他发现了中子引发的无线电脉冲。在写论文的时候,她正在用手检查图表记录器的输出。她观察到一些异常现象,她称之为“一点残渣”,不符合类星体产生的模式。有一些有趣的东西通过她的望远镜产生了这些无线电波。最终她排除了所有潜在的来源,并得出结论,它们是由中子星构成的。这一发现被授予 1974 年诺贝尔物理学奖。她的发现是非凡的,但也注意到了以下几点。首先,她用手分析数据。第二,她非常了解自己工具,不会被它愚弄。第三,在她训练有素的眼睛看来,她没有像其他“邋遢鬼”一样,把这种异常现象视为离群值而不予考虑。对她来说,这个异常现象看起来很有趣。第四,她凭直觉推断出一点邋遢的真正原因。

由于媒体和学术界对数据科学的关注,越来越多的毕业生进入该领域或希望将职业生涯转向数据科学的专业人士。毫无疑问,以下问题经常出现:成为一名优秀的数据科学家需要哪些技术技能?一般来说,优秀的数据科学家擅长使用 Python 或 R 构建模型,擅长编写 SQL 查询,并且理解因果关系(推理)。)这些技能将为你提供工具,对你在大多数工作中会遇到的大量数据进行清理、操作和建模。然而,数据科学所需的特定技能类型高度依赖于组织规模、行业、团队成熟度以及最终的分析目的。有些工作只需要线性或逻辑回归,而其他工作可能需要复杂的算法和可视化技术。

但是这个答案并没有描述一个好的数据科学家的全貌,它只是提到了作为一个数据科学家的“数据”。它没有解决最关键的部分,也就是“科学家”科学家是展示高度批判性思维的人。批判性思维意味着观察、反思、质疑和决定的能力。就像乔伊泽林·贝尔发现异常时一样。一个科学家问,为什么输出有意义?它符合我的直觉吗?我如何验证输出?结果是否解决了业务问题?科学家有能力通过从多个角度评估问题和解决方案来进行独立和反思性的思考。

我曾经读到过,大约 90%的数据科学项目失败或无法实现。这是对努力和才能的巨大浪费。从我自己管理多个行业的数据科学家的经验来看,我认为失败率如此之高是因为专注于一个“数据”科学家的工具堆栈,而不重视批判性思维。正如我的大一微积分教授曾经告诉我们的:“我可以教猴子做微积分,但我不能教猴子思考。”我相信我们已经忘记了作为科学家。

那么,成为一名优秀的科学家意味着什么?它意味着拥有解决问题的系统方法,意味着对正在解决的问题充满好奇,意味着坚持不懈地理解业务问题,意味着拥有特定的假设,意味着拥有测试假设的可测量的成功指标,意味着对解决方案有直觉,意味着能够在不使用技术术语的情况下施加影响。贝尔博士是“数据科学家”的一个极好的例子。她对自己的工具了如指掌,这也是她没有将异常现象视为异常事件的原因。她用手检查她的输出,以免遗漏任何东西。当她发现一些看起来不对劲的东西时,她跟着直觉走。她有条不紊地排除了所有可能导致脏污的来源。我在面试中问的一个典型问题是,你分配了多少时间来理解业务问题、检查数据、决定应用适当的方法以及分析结果。根据我的计算,大多数数据科学家花在分析和质疑模型输出上的时间不到 10%。优秀的科学家在向经理或商业利益相关者报告结果之前,会花更多的时间来审查、分析和质疑结果。

简而言之,要成为一名优秀的全栈“数据科学家”,你需要了解技术工具(SQL、Python/R、ML 框架/方法论、统计学等。),而且你需要系统化,对问题的“如何”和“为什么”有好奇心,对业务问题有良好的直觉。掌握这些工具更容易,因为这只是时间问题,但成为一名科学家需要沉浸其中,需要跟随你的直觉,需要对问题和解决方案有一个深思熟虑的理解。下次分配项目时,我们都应该考虑一下乔斯林·贝尔的流程。

做一个英雄:积极预防新冠肺炎

原文:https://towardsdatascience.com/be-a-hero-taking-an-active-role-in-preventing-covid-19-2cdba6419cda?source=collection_archive---------65-----------------------

一个简单的模型解释了像洗手和社交距离这样的琐碎措施如何有助于抑制疫情

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

丹尼尔·利维斯·佩鲁西在 Unsplash 上的照片

编者按: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里

一些遏制新冠肺炎病毒传播的措施可能看起来微不足道、过度、荒谬至极,但它们背后都有一个基本原理,在抗击这场疫情病毒的斗争中,它们是必不可少的。让我们面对现实吧,我们都希望一切恢复正常,但是用肥皂和水洗手是如何帮助我们实现这一目标的呢?

为了回答这个问题,我们将提出一个简单的模型,它将允许我们探索病毒如何传播,然后,通过调整一些参数,我们将看到这些措施是否在控制病毒传播方面具有重要作用。

想象一下这个叫做瓦昆达的完美国家(看看我在那里做了什么),那里一切都阳光明媚,因为他们充分利用了人工智能的力量。然而,一种神秘的高传染性疾病在该国出现,最初,只有一个人被感染,我们将称他为 Tchulu(别担心他不是王子)。尽管有奇怪的迹象和症状,Tchulu 没有去医院,并决定坚持到底。晚上,他和他的四个朋友互动,不幸地感染了其中的两个。巧合的是,这些被感染的朋友中的每一个也与另外四个人相互作用,他们每人感染两个。如此循环下去,在短短几周内,如此多的人被感染,这个国家就有麻烦了。

为了获得更清晰的认识,让我们用稍微抽象一些的术语来描述这种情况:

  1. Nₜ 代表一天开始时的感染人数 t 。在我们的例子中, N₀ =1,因为在疫情(第 0 天)开始时只有一个人被感染,而 N ₁=3,因为楚鲁后来感染了两个人。
  2. 𝐸 代表每个感染者一天内交往的平均人数。在我们的例子中 𝐸 =4
  3. 𝑟 代表感染率,即每个暴露者被感染的概率。在我们的案例中,平均暴露量约为 4 人,其中 2 人感染,因此, 𝑟 = 4/2 = 0.5
  4. δnₜ代表一天结束时的新病例数。
  5. 最后,δnₜ=𝐸×𝑟×nₜ。在我们的例子中,第 0 天结束时的新病例数( N₀ )将由 N₀=4×0.5×1=2 给出,这是真实的,因为在一天结束时,楚鲁感染了他的两个朋友。

所以我们现在可以用上面的符号来得出一些有趣的方程。

要获得一天结束时的案例总数,我们需要做的就是将当前案例数加上新案例数,即:

nₜ₊₁=nₜ+𝐸×𝑟×nₜ

通过分解出 Nₜ ,这可以被简化为:

Nₜ₊₁ = Nₜ(1+𝐸×𝑟)

如果我们用 N₀ 来表示,我们得到:

Nₜ = N₀(1+𝐸×𝑟)ᵗ

这给了我们一个等式,我们可以用它来预测疫情某一天的感染人数。例如,10 天后,瓦昆达的预期病例数将为:

𝑁₁₀=1×(1+4×0.5)⁰=(3)⁰= 59049

20 天内的预期病例数为:

𝑁₂₀=1×(1+4×0.5)⁰=(3)⁰= 3486784401

这只是一个荒谬的估计,因为我们高估了感染率,因此我们将使用一个更合理的比率 0.15

数学已经讲得够多了,很无聊吧,让我们回到主题上来。使用上面的等式,我们可以对前 30 天内的疾病进展进行建模。为此,我将求助于 python(如果你不知道如何编程,可以跳过代码片段)

首先,我们将为此定义一个函数

接下来,我们将使用以下参数应用该建模函数:

  1. **E = 4,**因为平均来说,每一个感染者都会与其他四个人发生互动。
  2. r = 0.15 ,即感染率。
  3. **N₀ = 1,**由于疫情开始时只有一人被感染

现在,我们可以查看数据,了解病例数在前 30 天内是如何变化的

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

前 5 天内的病例

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

过去 5 天内的案例

我们可以看到短时间内案件数量的急剧上升。为了更好地理解这一点,让我们用图表来直观地展示数据

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

相对于天数的案例数

我们有一条指数曲线。最初,受感染的人数相当低,很容易把这种病毒当作一场骗局而不予理会,并一直忽视专家的建议,但突然,从我们的情况来看,从第 20 天开始,人数迅速增加,以至于变得势不可挡,这反映了我们在目前的新冠肺炎疫情中所看到的情况。

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

请注意,在第 15 天,只有 1153 人被感染,但在短短 10 天内,这个数字上升到超过 126000 人

这让我们回到了最初的问题,这些措施如何有助于遏制疫情?为了回答这个问题,我们将回到我们神秘的国家,在考虑一些相当琐碎的措施之前,先探讨一下严厉措施的影响。

现在想象一下,在第 10 天,瓦昆达政府认识到这是疫情,并采取措施遏制其传播。所以他们首先隔离、隔离和治疗感染者。他们还呼吁封锁,但这是没有必要的,因为聪明的公民很快练习安全的社交距离。这些措施最终减少了暴露于该疾病的平均人数(从平均 4 人减少到 3 人)。现在让我们看看这如何影响未来 20 天内的病例数。

(这里我们只需要将初始模型中的 E 参数从 4 减少到 3 )

我们现在可以查看数据,看看这些措施是否会导致病例数的任何变化。

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

严格措施后最近五天内的案例

由于采取了这些措施,感染总人数从最初预测的 830,767 人减少到 128,052 人,相当于约 702,715 人免于感染。我们可以从下图中直观地感受到这一点:

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

相对于天数的案例数。初始投影显示为蓝色,而新投影显示为红色

这可能是一个过于乐观的估计,因为在现实生活中很难识别和隔离每个受感染的人,但尽管如此,从模型中,我们可以直观地了解平均暴露量的微小变化如何导致感染总数的巨大下降。因此,呼吁呆在家里,避免拥挤的空间,并在你出现一些迹象和症状的情况下去医疗机构,这不是轻率的,而是非常重要的,以阻止疫情。所以请听从召唤。

更实际的情况。我们可以说,并非瓦昆达的每个人都坚持社会距离,政府也无法确定每个感染者。然而,一些聪明的家伙仍然遵循简单的指示,他们实践一些看起来微不足道的措施:他们避免拥挤的地方,洗手,在公共场所戴上口罩和其他个人防护设备等等。尽管暴露在外,他们小小的努力减少了患病的机会,这转化为感染率从 0.15 到 0.145 的微小降低

使用我们的模型让我们检查他们的努力是否有意义。

像往常一样,我们检查新数据,看看病例数是否有变化

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

采取微不足道的措施后最近五天内的案例

这些努力虽然看起来微不足道,但在 30 天结束时使 176,316 人免于感染。这些数字可能没有上面的数字那么引人注目,但它们仍然表明,在减少疫情的影响方面,每一项努力都大有作为。我们还对指数函数的本质有一个直觉:对参数的微小调整会导致输出的巨大变化。

我们可以从下图中直观地感受到这些努力的影响:

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

相对于天数的案例数。初始投影显示为蓝色,而新投影显示为绿色

这看起来并不多,但是每一次努力,不管多么少,都可以挽救一条生命。

上面的模型非常简单,它表明一旦感染开始,就无法停止,每个人迟早都会被感染。这是因为它假设感染率保持不变,没有人康复并停止传染。然而,这些假设没有一个是正确的,但这个模型仍然给出了疫情早期阶段的完美画面。

这里的主要教训是,个人和集体的努力,尤其是在早期——当病例很少并且似乎无关紧要时——是非常重要的。面对疫情,那些看似琐碎的指令,如洗手和保持社交距离,是消灭任何传染病的有力武器。令人兴奋的是,这些武器就在你手中,你所要做的就是使用它们;做一个超级英雄,拯救生命。

为了证实这个模型及其教训的准确性,让我们看一些真实世界的数据

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

各地区新冠肺炎确诊病例流行曲线。图片由威廉·m·德特默,医学博士,维亚,自由医学

你可以看到这些曲线是指数型的,从前面的讨论中,你现在知道每一点小小的努力都可以大大减少病毒的传播。

事实上,流行曲线是逻辑的而不是指数的。考虑下图:

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

图片由杰夫·克鲁赞博士通过 T2 发送

有一个最初的滞后阶段,感染人数增长缓慢;感染人数快速增长的指数阶段和感染人数逐渐减少的递减阶段,之后曲线变平(渐近线),没有报告新的感染。

曲线的变平是每个人努力的目标,这个过程可以通过我们个人和集体的努力来加速。我们都有自己的角色。

负责任,做英雄,拯救生命,愿原力与你同在。

探索性数据分析

原文:https://towardsdatascience.com/be-friends-with-your-data-f03f2ecc8dc3?source=collection_archive---------25-----------------------

与您的数据成为朋友

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

照片由杜凡Unsplash 上拍摄

在这篇文章中,我们将使用 Pandas 库浏览许多不同的 Python 函数、方法和属性,它们在上传数据后对于探索性数据分析(EDA) 非常重要。然而,本文的目的是通过运行最少的命令来获取最多的信息。读完这篇文章后,你可以花更少的时间了解数据集,花更多的时间探索和建模。

数据集

分享一下我对概念的理解,我举一个 加州房价数据集 的例子。

大多数情况下,我们通过运行以下方法(以黑色书写)来启动 EDA,但是,如果我们仔细观察,我们可以只运行两个方法(以蓝色书写),并在运行所有这些方法后获得所有信息。

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

df.info()

这个函数返回关于数据帧的信息,包括每一列的数据类型和整个数据的内存使用情况。

这是输出—

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

我们可以从 df.info()中收集到什么信息:

(I)它将打印出对象的数据类型,这是一个熊猫数据帧。

(ii)数据帧中的条目或行数,以及行索引值的范围。
记住— 这里第一个索引是 0,最后一个索引是(n-1)
RangeIndex: 20640 个条目,0 到 20639

(iii)关于每个数据列的信息,包括列名、条目数、它们是否具有非空值以及数据类型。

(iv)数据帧中每个数据类型的列数。
dtypes: float64(9),object(1)

(v)最后,它显示了数据帧的内存使用情况。
内存使用:1.6+ MB

4 合 1 :除了上面提到的信息之外 df.info() 提供了我们运行这四个——len(df)、df.shape、df.isnull、df.dtypes()后可以得到的所有信息。

df.describe()

该方法提供了数据框的汇总统计数据,如平均值、标准差和分位数值,这对于了解每列的数据分布非常重要。

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

Pandas 提供了一个选项,我们可以使用转置功能转置上表。

df.describe()。T 或 **df.describe()。转置()

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

此外,还有某些汇总列,如“唯一值的计数”,可以通过传递选项***include = ’ all '***来打印,描述方法如下。

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

现在我们知道如何使用 describe() 方法得到数值变量的简要统计汇总。但是,如果我们有分类数据呢?在这种情况下, value_counts() 方法会很有帮助。

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

记住— df.describe()只会给出数值变量的汇总[或者如果我们将 exclude=‘O’ 作为参数传递,即 df.describe(exclude=‘O’)]。而且,如果我们只对分类列感兴趣,可以通过 include=‘O’

统计数据让我们了解了包含缺失值的属性、特定属性的平均值和最大值,这在我们预处理和构建模型时非常有用。

4 合 1 :除了上面提到的信息 df.describe() 提供了我们运行这四个- len(df)、df.shape、df.isnull、df.dtypes()后可以得到的所有信息。


这并不意味着这里讨论的这些方法/函数/属性**(len(df),df.shape,df.isnull,df.dtypes()] 没有用。人们应该记住,它们有自己的重要性,尤其是当你有兴趣了解你的变量的细节时。例如,如果您有 30 列,并且您想知道比如“abc”列的数据类型,您可以运行 info,但是运行 df[“ABC”]将是明智的。dtpyes()只知道特定变量的数据类型。

___________________________________________________________________

下面,我介绍了上面讨论的函数/属性的使用。

df . shape

该属性给出了 dataframe 的维度( df.shape )给出了一个元组( n_rows,n_columns )。Shape 还覆盖了数据帧的长度,这意味着运行 df.shape 还会给出在 EDA 期间可以从 len(df) 中得到的信息。

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

len(df)

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

df.shape[0]len(df.index) 也给出了总行数。要知道数据框中的列数,我们可以使用 len(df.columns)或 df.shape[1]。

df.dtypes

所有数据类型都在一个数据帧中,可以使用 df .dtypes. 打印

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

EDA 期间其他常用的方法有***df . head()*df.tail() 分别返回前 5 行和后 5 行数据。pandas 中的默认数字是五(5),但是可以根据需要更改,只需在括号中输入数字即可。例如,df.head(3)将给出数据集的顶部三行,df.tail(10)将给出底部 10 行。

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

我希望,读完这篇文章后,人们能够花更少的时间去了解数据集,花更多的时间去探索和建模。

享受 EDA,感谢阅读😄。

负责 Spark SQL 中的查询执行

原文:https://towardsdatascience.com/be-in-charge-of-query-execution-in-spark-sql-c83d1e16b9b8?source=collection_archive---------23-----------------------

理解您的查询计划

自从 Spark 2.x 以来,由于 SQL 和声明性 DataFrame API,在 Spark 中查询数据已经成为一种奢侈。仅使用几行高级代码就可以表达非常复杂的逻辑并执行复杂的转换。API 的最大好处是用户不需要考虑执行,可以让优化器找出执行查询的最有效方式。高效的查询执行经常是一个需求,不仅因为资源可能变得昂贵,而且因为它通过减少最终用户等待计算结果的时间而使最终用户的工作更加舒适。

Spark SQL 优化器确实非常成熟,尤其是现在即将推出的 3.0 版本,它将引入一些新的内部优化,如动态分区修剪和自适应查询执行。优化器在内部处理一个查询计划,并且通常能够通过各种规则来简化和优化它。例如,它可以改变一些转换的顺序,或者如果最终输出不需要这些转换,就完全丢弃它们。尽管所有的优化都很聪明,但是仍然存在人脑可以做得更好的情况。在本文中,我们将研究其中一个案例,看看如何使用一个简单的技巧,让 Spark 实现更高效的执行。

该代码在 Spark 的当前版本 2.4.5(编写于 2020 年 6 月)中进行了测试,并对照 Spark 3.0.0-preview2 进行了检查,以查看即将到来的 Spark 3.0 中可能的变化。

模型示例

现在让我首先介绍一个简单的例子,我们将努力实现有效的执行。假设我们有 json 格式的数据,结构如下:

{"id": 1, "user_id": 100, "price": 50}
{"id": 2, "user_id": 100, "price": 200}
{"id": 3, "user_id": 101, "price": 120}
{"id": 4, "price": 120}

每个记录就像一个交易,所以 user_id 列可能包含许多重复的值(可能包括空值),除了这三列之外,还有许多其他字段描述交易。现在,我们的查询将基于两个相似聚合的并集,其中每个聚合都有一些不同的条件。在第一个聚合中,我们希望获得价格之和小于 50 的用户,在第二个聚合中,我们获得价格之和大于 100 的用户。此外,在第二个聚合中,我们希望只考虑 user_id 不为空的记录。这个模型示例只是实践中可能出现的更复杂情况的简化版本,为了简单起见,我们将在整篇文章中使用它。下面是如何使用 PySpark 的 DataFrame API 来表达这种查询的基本方法(非常类似地,我们也可以使用 Scala API 来编写它):

df = spark.read.json(data_path)df_small = (
  df
  .groupBy("user_id")
  .agg(sum("price").alias("price"))
  .filter(col("price") < 50)
)df_big = (
  df
  .filter(col("user_id").isNotNull())
  .groupBy("user_id")
  .agg(sum("price").alias("price"))
  .filter(col("price") > 100)  
)result = df_small.union(df_big)

解释计划

实现良好查询性能的关键是理解和解释查询计划的能力。计划本身可以通过调用 Spark 数据帧上的 explain 函数来显示,或者如果查询已经运行(或已经完成),我们也可以转到 Spark UI 并在 SQL 选项卡中找到计划。

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

SQL 选项卡列出了集群上已完成和正在运行的查询,因此通过选择我们的查询,我们将看到物理计划的图形表示(此处我删除了指标信息以缩小图形):

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

该计划有一个树形结构,其中每个节点代表一些操作者,这些操作者携带一些关于执行的信息。我们可以看到,在我们的例子中有两个分支,根在底部,叶在顶部,执行从那里开始。叶子扫描 json 代表从源读取数据,然后有一对哈希聚合操作符负责聚合,在它们之间有交换代表洗牌。过滤器操作符携带关于过滤条件的信息。

该计划具有 union 操作的典型形状,union 中的每个数据帧都有一个新的分支,由于在我们的示例中两个数据帧都基于同一个数据源,这意味着数据源将被扫描两次。现在我们可以看到有改进的空间。只扫描一次数据源可以得到很好的优化,尤其是在 I/O 开销很大的情况下。

从概念上讲,我们在这里想要实现的是重用一些计算—扫描数据并计算聚合,因为这些操作在两个数据帧中都是相同的,原则上只需要计算一次就足够了。

贮藏

在 Spark 中重用计算的一个典型方法是使用缓存。有一个函数缓存可以在数据帧上调用:

df.cache()

这是一种惰性转换,这意味着在我们调用一些操作后,数据将被放入缓存层。缓存是 Spark 中非常常用的技术,但是它有其局限性,尤其是当缓存的数据很大而集群上的资源有限时。还需要注意的是,将数据存储在缓存层(内存或磁盘)会带来一些额外的开销,而且操作本身也不是免费的。在整个数据帧 df 上调用 cache 也不是最佳选择,因为它会尝试将所有列放入可能不必要的内存中。更谨慎的方法是选择将在后续查询中使用的所有列的超集,然后在选择之后调用缓存函数。

交换再利用

除了缓存,还有一种技术在文献中没有很好地描述,这种技术基于重用交换交换操作符代表 shuffle,这是集群上的一种物理数据移动。当数据必须重新组织(重新分区)时会发生这种情况,这通常是聚合、连接和其他一些转换所需要的。关于 shuffle 重要的一点是,当数据被重新分区时,Spark 将始终以 shuffle write 的形式将其保存在磁盘上(这是一种内部行为,不受最终用户的控制)。因为它保存在磁盘上,所以以后需要时可以重复使用。如果 Spark 找到机会,它确实会重用这些数据。每当 Spark 检测到从叶节点到一个交换的同一个分支在计划中的某个地方重复时,就会发生这种情况。如果存在这种情况,这意味着这些重复的分支代表相同的计算,因此只计算一次然后重用它就足够了。我们可以从计划中看出 Spark 是否找到了这样的案例,因为那些分支会像这样合并在一起:

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

在我们的例子中,Spark 没有重用交换,但是通过一个简单的技巧,我们可以促使他这样做。在我们的查询中没有重用交换的原因是对应于过滤条件 user_id 的右侧分支中的过滤器不为空。过滤器实际上是我们在联合中的两个数据帧的唯一区别,所以如果我们可以消除这种区别并使两个分支相同,Spark 将处理剩下的部分,并将重用交换

调整计划

怎么才能让树枝一样呢?好吧,如果唯一的区别是过滤器,我们当然可以交换转换的顺序,并在聚合之后调用过滤器,因为这不会对将要产生的结果的正确性产生任何影响。然而有一个陷阱!如果我们像这样移动过滤器:

df_big = (
  df.groupBy("user_id")
  .agg(sum("price").alias("price"))
  .filter(col("price") > 100)
  **.filter(col("price").isNotNull())**
)

并且检查最终的查询计划,我们会看到计划根本没有改变!原因很简单——优化器将过滤器移回了原处。

从概念上讲,理解有两种主要类型的查询计划是有好处的——逻辑计划和物理计划。并且逻辑计划在变成物理计划之前经历优化阶段,物理计划是将被执行的最终计划。当我们更改一些转换时,它会反映在逻辑计划中,但是我们会失去对后续步骤的控制。优化器将应用一组优化规则,这些规则主要基于一些启发式规则。与我们的示例相关的规则被称为 PushDownPredicate ,该规则确保过滤器被尽快应用,并被推到更靠近源的位置。它基于这样一种思想,即首先过滤数据,然后在缩减的数据集上进行计算会更有效。这条规则在大多数情况下确实非常有用,但在这种情况下,它却对我们不利。

为了实现过滤器在计划中的自定义位置,我们必须限制优化器。从 Spark 2.4 开始,这是可能的,因为有一个配置设置允许我们列出所有我们想从优化器中排除的优化规则:

spark.conf.set(
"spark.sql.optimizer.excludedRules",     "org.apache.spark.sql.catalyst.optimizer.PushDownPredicate")

在设置了这个配置并再次运行查询之后,我们将会看到现在过滤器保持在我们需要的位置。这两个分支变得完全相同,Spark 现在将重用交换!数据集现在将只扫描一次,计算聚合也是如此。

在 Spark 3.0 中,情况有了一点改变,优化规则现在有了一个不同的名称—PushDownPredicates,并且有一个额外的规则也负责推送一个过滤器pushpredictethrunjoin,所以我们实际上需要排除这两个规则来实现预期的目标。

最后的想法

我们可以看到,通过这种技术,Spark 开发人员给了我们控制优化器的能力。但是权力也伴随着责任。让我们列出使用这种技术时需要牢记的几点:

  • 当我们停止pushdownpreditate时,我们将负责查询中的所有过滤器,而不仅仅是我们想要重新定位的过滤器。可能还有其他过滤器,例如分区过滤器,需要尽快安装,因此我们需要确保它们的位置正确。
  • 限制优化器和处理过滤器是用户方面的一些额外工作,所以最好是值得的。在我们的模型示例中,加速查询的潜力将出现在 I/O 很昂贵的情况下,因为我们将实现只扫描一次数据。例如,如果数据集有许多列,那么 json 或 csv 之类的非分栏文件格式可能就是这种情况。
  • 此外,如果数据集很小,可能不值得额外控制优化器,因为简单的缓存就可以完成这项工作。然而,当数据集很大时,在缓存层存储数据的开销将变得明显。另一方面,重用的交换不会带来额外的开销,因为计算出的洗牌将被存储在磁盘上。
  • 这种技术是基于 Spark 的内部行为,它没有官方文档,如果这个功能有什么变化,可能更难发现。在我们的示例中,我们可以看到 Spark 3.0 中实际上有一个变化,一个规则被重命名,另一个规则被添加。

结论

我们已经看到,要获得最佳性能,可能需要理解查询计划。Spark optimizer 通过使用一组启发式规则来优化我们的查询,做得非常好。然而,在有些情况下,这些规则会错过最佳配置。有时重写查询已经足够好了,但有时却不行,因为通过重写查询,我们将实现不同的逻辑计划,但我们无法直接控制将要执行的物理计划。从 Spark 2.4 开始,我们可以使用一个配置设置 excludedRules ,它允许我们限制优化器,从而将 Spark 导航到一个更加定制的物理计划。

在许多情况下,依赖优化器会产生一个执行效率相当高的可靠计划,但是,在大多数情况下,在性能关键型工作负载中,可能值得检查最终计划,看看我们是否可以通过控制优化器来改进它。

成为成功的数据科学家的影响力

原文:https://towardsdatascience.com/be-influential-to-be-successful-as-a-data-scientist-993cb098f92c?source=collection_archive---------48-----------------------

领导成功的跨职能团队的 4 种方法

大多数分析师和数据科学家在与产品或计划相关的跨职能团队中工作。作为一个带来见解和建议的人,这是工作的本质。然而,将来自不同部门和职能部门的人聚集在一起以实现一个单一的目标可能具有挑战性。

你们是如何高效合作的?你如何与团队交流见解并使你的愿景与团队保持一致?

作为分析和数据科学职能部门的成员,您的工作通常是提出见解,进而提出建议。例如,你并不总是会实施特定的营销策略或为某个平台开发功能,但你的角色可能是根据你的分析提出营销策略或为该平台推荐某种用户体验。因此,作为分析人员,您的角色是为团队指出正确的方向。你的团队成员需要听取你的见解,采纳你的建议,而说服他们是你的工作。

再读一遍最后一行——说服他们应该听你的建议是你的工作——他们需要听你的从来都不是给定的或要求的。在分析领域成功的标志是你是否能影响你的团队朝着正确的方向发展。

本文将介绍在跨职能团队中工作时需要考虑的一些方法。

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

You X VenturesUnsplash 上拍摄的照片

但是首先,什么是跨职能团队?我是怎么穿上的?

跨职能团队就是由公司内不同部门或职能部门的人组成的团队。许多公司将他们的团队组织成一个矩阵型的组织,团队成员同时拥有一个职能经理和一个产品经理。你的产品团队通常是由产品经理、工程师、数据科学家、营销人员和销售人员组成的跨职能团队。

跨职能团队带来了哪些挑战?

创建一个新团队总是具有挑战性,但建立一个跨职能团队还有其他困难。

例如:

  • 团队成员可能仍然在做他们的日常工作,有着和团队之前一样的截止日期、工作量和职责。这通常会导致优先级问题。
  • 当一个人无法直接控制其他成员时,管理绩效、激励员工、做出决策或设定优先顺序就变得更加困难。
  • 团队成员可能需要在新的环境中使用不同的技能。例如,一个在日常工作中独自工作的程序员现在可能需要与团队的其他成员一起工作。
  • 不同的观点和孤立的信息可能会使每个人难以协调一致

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

UnsplashNeONBRAND 拍摄的照片

在跨职能团队中工作的 4 种方法

跨职能团队并不是最容易共事的团队,尤其是因为他们的成员有一系列相互竞争的优先事项、沟通方式、个性等等。下面你会发现我在跨职能团队工作时会考虑的一些事情。

1.公开你的目标

让你的队友明白你的目标和贡献是什么,以及对你来说一个成功的可交付成果是什么样的。这可以让你的队友理解你为什么安排会议或问某些问题。

当你的团队成员理解了你的工作流程和项目目标后,检查一下它是否符合他们的期望。通常,你眼中的成功和他们眼中的成功是不同的。

通常,他们的观点和约束与你的不同,所以最终目标也不同,因为团队中的每个人都来自不同的职能或部门。达成共识很重要,但只有让你的队友知道你的目标,你才能做到。您将有机会调整您的输出,以便所有队友都对最终结果感到满意。

2.你的目标是通过影响和妥协你的队友对里程碑做出反气候反应

在第一点的基础上,让你的队友了解状态更新,这样你就可以和你的团队一起迭代你的里程碑。这不是一条通向终点的直线轨迹,而是一条有风的路。让你的团队保持更新是很重要的,这样你的最终成果和建议就不会让他们感到意外。

记住,你不是在写一本书——故事不应该有高潮——所以通过让你的队友了解你的进展,让你完成工作的方法尽可能地不受气候影响。

让你的队友了解最新情况的困难之处在于,他们的观点会与你的相冲突。这就是影响和妥协的终极技巧派上用场的地方,也是我看到大多数人失败的地方。知道如何影响谈话可以帮助你和你的队友在方法、里程碑和最终目标上保持一致。知道如何以及何时在不牺牲目标的情况下妥协,会让你的队友觉得他们也参与其中。最终,你的可交付成果将会让整个团队感觉他们有所参与。这种感觉很好,是在跨职能(或任何项目)团队中工作的最终目标。

3.强调良好的沟通

成功的跨职能团队项目的第一条规则是永远不要让你的团队感到惊讶。这意味着你应该在良好的沟通技巧上投入精力和时间——在会议中,通过电子邮件,或者面对面。

你应该带着清晰的议程参加会议,每周(或任何你觉得合适的时候)安排检查,利用团队会议作为更新与利益相关者分享项目的进展,并要求你的团队成员分享他们的进展。所有这些确保了每个人都参与进来,每个人都觉得自己是团队的一部分。

这也意味着你需要从一开始就设定明确的角色和期望,当你的队友做得很好时给予认可,并鼓励交叉合作——所有这些都有助于建立一个快乐和积极的团队。

例如,如果你有一个想法,你正试图让你的其他团队成员同意,在你把这个想法告诉其他团队成员之前,和你的团队成员单独坐下来审查并了解他们对这个想法的反应;这表明你尊重他们的意见,希望他们接受你的观点——这会立即鼓励合作和信任。

如果你发现自己处于令人沮丧的境地,试着专注于做对公司最有利的事情,这将使你更具战略性,像领导者一样行动和思考。

4.了解团队成员的优先事项

你必须牢记项目的截止日期和目标。然而,你也需要明白,你的项目可能是你的队友正在做的几个项目中的一个,可能对他们来说不是最重要的。

当你开始在一个跨职能团队工作时,确保你正在收集关于你的队友如何安排时间的见解,以更好地了解他们的期望,这样你就可以更好地计划你的时间表。

此外,通过询问你的团队成员他们在寻找什么样的结果,什么对他们来说是重要的,来全面了解项目的重要性。很可能,你的工作会有一些他们认为有价值的产出。他们的回答可以帮助你找出如何优先处理你的工作。

最后,你应该注意到这是双向的——所以,让你的队友清楚你目前在项目之外做什么,以及你可能不在的任何时候。

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

Unsplash 上由 Austin Distel 拍摄的照片

结论

这四个想法帮助我建立了一个框架来与我的团队合作。该框架的潜在主题是对你的团队成员感同身受。即使每个人都知道项目的目的和最终目标是什么,每个人都有不同的经验和观点,有不同的工作方式,有不同的动机。这就是为什么在跨职能团队中工作很困难。我们的目标是完成每一项交付成果,就像你实现了最终目标,每个人的声音都被听到了。

我每月都会发一份这样的时事通讯。如果你想加入,请点击此链接。

使用 Metaflow 更有效地生成机器学习管道

原文:https://towardsdatascience.com/be-more-efficient-to-produce-machine-learning-pipeline-with-metaflow-db5f943ebbe7?source=collection_archive---------19-----------------------

网飞 Metaflow 2.0 的描述和炉石机器学习流水线的设计。

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

Unsplash + metaflow 标志

对于这篇文章,我将描述我对一个新库的实践,该库最近由网飞开源,用于操作和版本化机器学习/数据科学管道,名为元流

这篇文章的思想是:

  • 对产品包有一个概述
  • 用两个例子详细说明这个包的特性(比教程更进一步)

元流概述

Metaflow 是网飞开发的一个包,他们在几年前(2016 年左右)开始研究它,并在 2019 年开源。Metaflow 的想法是为数据科学家提供一个框架,以快速建立数据科学/机器学习管道,并可以从开发顺利进入生产。

我邀请您观看网飞的 Ville Tuulos 在 AWS reinvent 2019 上的演示。

网飞一揽子计划背后的大问题是

数据科学家在日常工作中最难的是什么?"

网飞的工程师们期待听访问大数据集,强大的计算能力和 GPU 的使用,但答案(两年前)是不同的。最大的瓶颈之一是数据访问以及从概念验证到生产的转移。

下图显示了数据科学家的兴趣和 ML/DS 流程中的基础设施需求。

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

https://netflixtechblog . com/open-sourcing-metaflow-a-human-centric-framework-for-data-science-fa 72 e 04 a5d 9

在这篇宣布 Metaflow 的文章中,我认为有一句话定义了 Metaflow 背后的 moho:

基础设施应该允许他们行使作为数据科学家的自由,但它应该提供足够的护栏和脚手架,所以他们不必太担心软件架构。

这个想法是为数据科学家的工作提供一条安全的道路,而不损害他们的创造力。这个框架需要易于使用,并提供对强大计算能力的访问,而不必接触基础设施。

让我们看看更多的框架设计。

元流的设计

Metaflow 是一个只在 Linux 上运行的 Python 库,主要受 Spotify Luigi 的启发,围绕 DAG 设计。下图显示了元流上的典型流。

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

https://netflixtechblog . com/open-sourcing-metaflow-a-human-centric-framework-for-data-science-fa 72e 04 a5d 9

DAG 的结构围绕着:

  • 流:管理管道所有代码的实例。在本例中,它是一个 Python 对象类 MyFlow(Flowspec)
  • 步骤:流程的一部分,由 decorator @step 分隔,它们是 MyFlow 对象中的 python 函数,在本例中是 def start,fitA,fitB,eval,end
  • 过渡:步骤之间的链接,它们可以是不同的类型(线性、分支和 for each);关于文档有更多细节。

现在我们来谈谈架构。在网飞的下图中,有一个组件的视图。

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

https://docs.metaflow.org/

该流程有 3 个组成部分:

  • 数据存储是存储流程中生成的所有数据(数据工件)的地方
  • 元数据是存储流程执行信息的地方
  • 客户端是访问数据存储中的数据并从元数据中获取流信息的连接组件

对我来说,处理元流核心的核心部分之一是装饰器。这是一个 python 特性,允许在不修改 Python 对象结构的情况下更新其属性,我邀请您阅读 Data camp 关于这个主题的文章。

在 Metaflow 中,有多个装饰器,在文档的这一节中有很好的解释。然而,对我来说,最重要的是我将在下一部分解释的那些。

元流实践

我构建了一个简单的流程来说明装饰者和分支的转换。流程的代码在这个库(decorator _ experimental 文件夹);流量看起来是这样的。

并且有一个流程的可视化说明。

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

该流程的目标是:

  • 开始步骤中测试 Python 和 Pandas 的版本,
  • 测试(再次!?)Python 中的版本和熊猫中的检查 _ 版本步骤
  • 执行一个 3 分支转换,它将给出一个随机数( give_number )、字母( give_letter )或数字/字母( give_something )
  • 一个叫做的连接步骤重述来打印前面步骤的产品,
  • 将要显示的结束步骤(再次!?)Python/Pandas 的版本

对 Python/Pandas 版本的常规检查是为了说明两个特定的装饰器。让我们从脚本的标准执行开始;要执行这个流,您需要在脚本的文件夹中运行以下命令。

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

这是脚本生成的日志。

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

我们在日志上可以看到,Python 的版本是 3.6.9,Pandas 是 0.25.3。我们来测试一下 @conda_base decorator。只需要取消一行的注释并执行下面的命令行。

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

这个装饰者在流上应用了新版本的 Python,在本例中是 3.7.4,带有新版本的 Pandas (0.25.2)。这是管道产生的日志。

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

正如我所说的,现在有一个新版本的 Python/Pandas 用于执行所有的流。最后,让我们看看 @conda 装饰师。

这一个就像 @conda_base ,但是只针对一个步骤,在这种情况下,我正在将 python 版本修改为 3.6.8,只是为了这个特定的步骤(用熊猫的随机版本,我知道它看起来很蠢,但这只是为了测试)。

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

在日志中,我们可以看到有一个新版本的 Python/pandas 只应用于 check_version 步骤。

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

我认为这个测试说明了如何使用 Metaflow 来版本化用于执行流程或步骤的环境。Metaflow 的优势在于为数据科学家提供了灵活性,可以精确地设置执行代码所需的环境,而不必设置 conda 环境或容器。

包中有比这些装饰者更多的东西,比如:

  • 用于执行的,如*@重试*、@超时、@捕捉、@资源
  • AWS 的那个(@batch)我一会儿再来找他们。

我们来看一个用 Metaflow 设计的数据科学/机器学习流程。

用 Metaflow 构建炉石原型预测器

几周前,我建立了一个与暴雪的卡牌游戏炉石相关的数据集。如果你对游戏没有清晰的愿景,我邀请你去看一看。

我在上一篇文章中回避的一个方面是原型的概念。这些原型基于选择的英雄和卡片组中的卡片,有多种原型,有些是最流行的。

在前一篇文章中介绍的数据集中,40%的卡片组没有相关的原型,所以我想开始基于所使用的卡片构建一个原型预测器(这是一个虚拟系统,只是为了测试 Metaflow 的流程)。

下图中有一个我设计的测试 Metaflow 的流程的表示(代码在 this repository 中与炉石相关的文件夹中)。

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

这个流程的想法是,基于我们想要分配给没有原型的原型的顶卡,建立一个原型的随机森林预测器。我认为代码足够清晰,所以我不会输入太多的执行细节,因为这并不令人兴奋。我将花时间用 Metaflow 的客户端分析多次运行的结果。

监控流程和执行

在流的不同执行过程中产生的数据存储在本地存储的数据存储中(在工作目录的/metaflow 隐藏文件夹中)。尽管如此,所有的结果都可以在一个笔记本中直接访问。我将把不同运行的工件的“处理部分”放在一个要点中。

目标是计算执行时间,收集训练集的第一个样本,以及 HPO 生成的最佳模型的信息(精度和参数)。有处理的截图。

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

正如我们所看到的,在流程的执行过程中,有许多信息被版本化。我真的很喜欢这种对流水线中产生的所有数据进行版本控制的方法,这种方法在可再现性和调试方面非常出色。

现在让我们看看 Metaflow 的 AWS 部分。

那云呢?

Metaflow 在其文档中为您提供了设置 AWS 环境的所有过程。尽管如此,我还是很懒,他们可以给你一个 AWS 沙箱(使用有限的资源来测试云上的功能),只要在网站上注册就可以了。

几天后,你就可以访问沙箱了(我想再次感谢 Metaflow 的支持,让我可以更长时间地访问他们的沙箱,在我周围做一些演示)。

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

建立到沙箱的连接很简单,只需要在 Metaflow 的命令行中添加一个令牌。之后,你所有的后台就是:

从本地机器访问 AWS 计算有两个选项:

  • 将属性*—batch*与 run 命令一起使用,就像您的所有流都使用 AWS batch 作为计算资源一样
  • 如果您只想在 AWS 上执行特定的步骤,并使用本地机器的能力来执行其他任务,那么您可以在步骤声明时使用 AWS 装饰器 @batch

我发现这种云管理方法引人注目且易于使用,本地计算向云计算的转换非常简单。为了说明云计算,我刚刚截屏了运行我的元流代码的实例的 CPU 使用情况,以及我执行的运行类型。

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

我认为这很好地说明了这样一个事实,即我的本地机器不用于进行计算,而本地运行(在运行 11 和 17 的边界之间。

现在关于 Metaflow 的最后一个问题是它能否与 mlflow 一起工作。

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

不要越过水流!?

不,请这样做,我在中添加了另一个脚本的 mlflow 图层到我的 HPO 中。我只是在我的 mlflow 日志中添加与我的元流运行相关的信息。有一张 mlflow 的日志截图。

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

这两种版本控制框架似乎可以很好地协同工作。因此,今天,我们可以使用 Metaflow 监控您的管道,记录您的模型,并在任何云平台支持上使用 mlflow 进行部署。

反馈

Metaflow 是一个为数据科学家开发的框架,它提供:

  • 机器学习 DS 管道中产生的所有工件的版本控制
  • 轻松使用云,轻松并行化作业

这是网飞做的一项伟大的工作,并且是开源的。更多的元素出现在元流中,如:

  • R 包
  • 将 AWS 步骤用作调度程序的能力(但它还没有出现,所以我认为这表明它不是一项容易使用的技术)。
  • Sagemaker 的模型部署,他们将涵盖 mlflow 的另一个方面(在 AWS 上)。

我在 Metaflow 上的唯一缺点是:

  • conda decorator 在您的 python 环境中构建了大量的 conda 环境,因此它看起来可能很乱
  • 该框架看起来非常适合 AWS,因此不对其他云平台开放(但在 GitHub 上,似乎有人试图让它为 GCP 工作)
  • 火花似乎完全不在计划之内

我将跟随 Metaflow 的发展,但老实说,第一次尝试是好的,我邀请你尝试一下,并提出你自己的看法。

原载于

持怀疑态度!作为数据分析师最重要的原则

原文:https://towardsdatascience.com/be-skeptical-the-most-important-principle-as-a-data-analyst-903172222c65?source=collection_archive---------24-----------------------

至于方法,可能有一百万,但原则很少。持怀疑态度但不要陷入分析麻痹。

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

图片由openclipbart-VectorsPixabay 上生成

怀疑论(英国:怀疑论)基于牛津词典:持怀疑态度;对某事真实性的怀疑。

使用第一原则思维,我了解到塑造我成为一个更好的分析师的最重要的原则是“保持怀疑!”原则指导我做分析,分析方法也随之而来。持怀疑态度但不要陷入分析麻痹。

概述

1。找到第一原则
2。持怀疑态度!
3。不要陷入
分析麻痹

1.找到首要原则

“至于方法,可能有一百万甚至更多,但原则很少。掌握原则的人能够成功地选择自己的方法。尝试方法的人,忽视原则,肯定会有麻烦。”—哈林顿·埃默森

当我们学习任何东西时,找到它背后的原理是很重要的。您可以将原则视为一个通用的规则、定义或值,它可以应用于许多不同的特定场景。第一个原则仅仅是不能从其他原则推导出来的基本原则。通过从我们所学的东西中找到首要原则,我们可以用它来产生新的想法或方法[1]。

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

让我们举一个第一原理思维的例子。大多数数据分析师和数据科学家都学习过编程,要么使用 Python,要么使用 r。编程的首要原则是什么?如果你停下来猜一猜,会更有趣。

第一个原则:寻找

我们什么时候使用循环?通常,当我们实现一个需要连续重复代码块的算法时,我们使用循环,重复一个接一个地连续发生。函数怎么样?当我们发现一块重复的代码时,就会触发我们使用函数。我们可以通过将同一块代码封装在一个函数中来重用它,然后我们可以在任何地方调用这个函数。

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

如果我们发现使用循环和函数的一般规则,它们有交集:减少重复编写相同的代码块。这就是我们如何通过归纳找到第一个原则。不要重复自己(干)是编程和软件工程中最流行的原则之一[4]。

原则背后也有原因。如果我们的重复次数少于三次,我们仍然可以复制粘贴代码。但是,更重要的是,我们会厌倦复制粘贴。代码也变得很难维护。如果我们发现一个 bug,我们需要修复每个代码副本中的逻辑。我们可能会不小心错过修复其中一个副本。

第一原则:推理

在知道“不要重复自己”的原则后,有些人发现如何在其他方面应用该原则。我们可以将此视为推理部分。一些例子是:

  1. 库超越了单一的代码库,库可以防止其他程序员重复实现与你功能相同的代码。
  2. 继承,面向对象编程
    我们不需要重复编写条件语句。之前,我们需要为每个相似的类if (duck) then quack(); else if (cat) then meow(); else if ... 编写 if 语句。有了继承能力,我们就说DuckCat继承Animal,所有动物都会说话。我们可以实例化任何种类的动物,例如animal = Duck(),并调用animal.talk()
  3. 泛型,面向对象编程(OOP)
    我们不需要仅仅因为一个类需要处理不同的数据类型而重复编写它。没有实现ListOfStringListOfInteger,有了泛型,我们只实现List<T>

2. 持怀疑态度!

先说个例子。下图来自 UCI 资料库的成人数据集。该数据集有一个特征,表明一个成年人的收入是否超过 5 万美元。我汇总数据,按照教育程度和性别得出收入超过 5 万美元的成年人比例。你从数据中得到了什么信息?你能根据这些信息得出结论吗?慢慢想吧。

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

来自 UCI 的成人数据集,由 Barry Becker 从 1994 年人口普查数据库中提取。

从图表中,我们得到信息,女性往往比男性收入低,尽管两者教育程度相同。男女有工资歧视,不是吗?

如果你因为本科或硕士学历的男性收入更高而利用这些信息进行针对性营销,那就没问题。但是,如果你正在利用这些信息进行大规模的性别平等社会运动,最好三思而行!或者,你可能会愚弄整个世界。我们应该持怀疑态度,质疑数据和分析方法:

  1. 数据来自 1994 年,调查是在美国进行的。在 2020 年的中国,用这些数据来进行社会运动还合适吗?
  2. 女性倾向于选择不太累的工作还是兼职工作,因为她想照顾她的孩子?
  3. 他们是如何对成年人进行采样的?他们也从家庭主妇那里收集数据吗?如果他们从家庭主妇那里收集数据,这可能会导致收入差异。
  4. 假设男性和女性拥有相同的学位,他们在公司的表现是否一样好?

怀疑是数据分析首先存在的原因。对于不持怀疑态度的人来说,专家的知识和直觉就足够了,不是吗?但是,具有讽刺意味的是,有时,我们,作为分析师,不够怀疑。我们基于对数据的错误假设给出结论,使用的是不适合数据的复杂分析方法。我们毫无疑问地、满怀信心地将它呈现给利益相关者,每个人都相信它。

不管手头的任务是什么,最重要的是保持怀疑的态度。我们需要质疑围绕数据和分析方法的假设。我们越质疑,就越了解真相。然后,我们将能够决定哪些分析方法最适合我们的数据。

质疑数据

“我们不应该只问‘数据说明了什么?’但是要问,‘谁收集的,他们是怎么做的,那些决定是如何影响结果的?’”—琼斯·罗伊

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

图片来自最佳大学评论

上面的信息图是关于高中和大学作弊的。从调查中,他们得到的信息是,51%的学生承认在过去一学年的一次考试中作弊。如果我们要根据有多少学生作弊来做决定,你会直接用这些信息吗?

我们要持怀疑态度,要问“是谁收的?”以及“他们是如何收集的?”因为这两个方面决定了调查结果。想象一下,我们用两种不同的方式做这个调查:

  1. 第一次调查(老师,采访)
    学校通过采访的方式指派每个班主任进行调查。在一个私人房间里,老师问“你在过去的学年里有没有在考试中作弊?”以及“你是怎么作弊的?”老师向学生承诺,本次调查是匿名的,他们的回答不会影响他们的分数。
  2. 第二次调查(学生,书面调查)学校要求学生会进行调查。每个班级都有一名代表通过纸张分发调查问卷。有一个是/否问题问“你在过去的学年里有没有在考试中作弊?”学生只需要在答案上打勾,然后把答案放进盒子里。

您想使用第一次调查的结果还是第二次调查的结果?我们大多数人会选择第二种调查。如果老师通过面试问那种问题,你觉得学生会说实话吗?至少有些学生会撒谎,不敢说实话。结果将偏向于更少的作弊者。

我们必须记住,我们的数据并不完美。它可能包含由人为错误、偏见或测量工具引起的误差。但是,NYU 数据科学教授 Jones-Rooy 说,“虽然数据可能包含错误,但这并不意味着我们应该扔掉所有数据,没有什么是可知的。这意味着以深思熟虑的方式收集数据,扪心自问我们可能遗漏了什么,并欢迎收集更多的数据。”[3]

质疑分析

“数据并没有什么。人类说事情。他们说他们在数据中注意到或寻找的东西”——琼斯-罗伊

分析师必须持怀疑态度,质疑自己的分析方法和结果。我们在阅读别人的分析结果时也需要持怀疑态度。这些是 Kaushik 的一些例子[2]:

  1. 这个结论是基于你所掌握的数据吗?
  2. 做这个分析的时候做了什么假设?
  3. 索赔的理由是什么?
  4. 从数据或分析中可以得出任何替代的解释或结论吗?
  5. 如果数据以比例给出,原始值是多少?
  6. 如果数据以原始值给出,比例是多少?

还有很多其他的。问题是无限的,这取决于分析方法。保持怀疑的态度,问题就会涌入你的脑海。

3.不要陷入分析瘫痪

通过持怀疑态度,我们会质疑很多事情。我们不会轻易相信一个假设,我们希望“越来越深入!”。几个星期后,我们意识到我们最终分析了很多东西,但没有得到任何结论。人们称这种分析为麻痹。分析瘫痪是一种过度分析或过度思考的状态,导致分析师无法得出结果[5]。

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

图片来自“盗梦空间网络版本的简单指南

那么,我们是否需要停止怀疑,以防止陷入分析瘫痪?不要!不要那样做。想好之前不要盲目相信任何假设。你会陷入另一个极端的对立面,因本能而灭绝:分析师做出致命决定的情况,因为它只是基于本能[5]。

最后,正如斯图尔特·戈尔德所说,“明智的错误总比什么都不做好。”[2]会有很多我们持怀疑态度的假设。我们会有深入探究每一个问题的冲动。但是,我们应该学会如何优先考虑和关注那些可能使整个分析大错特错的关键假设。

例如,你要决定是否在另一个城市开设新的分行。这是 Kaushik 如何解释为什么他持怀疑态度,但仍然做出了决定[2]:

  1. 如果你对数据和分析有 100%的把握,你可以建议在这个城市开几家分店。
  2. 如果你对数据和分析有 80%的把握,你可以建议尝试在这个城市开一家分店。
  3. 如果你对数据和分析有 60%的把握,你可以要求更多的时间去挖掘或增加预算来收集更可靠的数据。

最后,持怀疑态度但不要陷入分析麻痹。

我从“ 学到了很多第一原理:真正知识的基石 ”。如果你想了解更多关于第一原理思维的知识,我推荐你去读一读。

参考

[1]无名氏、第一原理:真正知识的积木 (2018)、法南街
【2】A .考希克、一个伟大的分析师最好的朋友:怀疑论&智慧! (2016)、Avinash Kaushik 的《奥卡姆剃刀》
【3】a . Jones-Rooy、我是一个对数据持怀疑态度的数据科学家 (2019)、Quartz
【4】k . Henney、每个程序员都应该知道的 97 件事 (2010)、O ’ Reilly Safari
【5】维基百科撰稿人、分析麻痹、维基百科:免费百科

豆机和中心极限定理

原文:https://towardsdatascience.com/bean-machine-and-the-central-limit-theorem-8b0b23d6e887?source=collection_archive---------30-----------------------

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

图片由 Alicja 来自 Pixabay

从二项式分布到正态分布

当我在大学学习统计物理的时候,我被统计学以一种聪明的方式简化和解释混沌过程的能力迷住了。

当我开始研究数据科学时,我发现统计物理学和数据统计学有太多的相似之处。这是未来博客的主题。现在让我们深入研究一下统计分布。

统计分布:

统计学中的一个基本概念是概率分布。在概率分布中,我们描述了获得随机变量可能取值的可能性。我们可以画出离散变量和连续变量的概率分布。

二项式分布:

二项式分布是一种离散的概率分布。它可以简单地认为是重复多次的实验中成功(1)或失败(0)结果的概率。例如,掷硬币只有两种可能的结果:正面或反面

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

二项式分布,作者使用 Python 制作的图片

正态(高斯)分布:

正态分布是一个连续的概率函数,描述了变量的值是如何分布的。因曲线呈钟形,故又称为“钟形曲线”。在正态分布中,分布两端的极值同样不太可能出现。

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

照片由迈克派克斯拍摄

从量子物理到生物统计学,从股票市场回报到质量控制,进入系统的电话,人口的身高、体重、智商,容器中气体分子的速度,学生的考试成绩,都可以观察到正态分布。

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

正态分布,作者使用 Python 制作的图像

中心极限定理;

统计学中的中心极限定理指出,给定足够大的样本量,样本均值的抽样分布接近正态分布——无论总体分布的形状如何

德莫维尔-拉普拉斯定理;

德莫维尔-拉普拉斯定理是中心极限定理的特例。它指出,在样本量足够大的情况下,二项分布近似于正态分布。

掷硬币:

让我们用一个掷硬币的例子来澄清这一点:当我们掷硬币时,我们有两种可能的选择:正面和反面。抛硬币选择正面的概率是 1/2。(1/2).当我们投掷许多硬币时,事情开始变得复杂,但是所有的概率都回到了期望结果/所有可能结果的概念上

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

Joshua Hoehne 在 Unsplash 上拍摄的照片

我们可以通过思想实验或者虚拟实验来理解最复杂的概率概念。你可以尝试一些虚拟硬币翻转实验这里

如何看待真实的概率实验将抽象的统计概念和真实世界的例子联系起来?怎样才能做一个真正的概率实验?我们要掷硬币数百万次吗?为了找到真实的概率,我们真的需要多次做同样的实验。(不是几百或几千,是几百万)。

因为计算机不是在 19 世纪发明的,统计学家开发了创造性的设备来更快地进行统计实验。

弗朗西斯·高尔顿爵士

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

弗朗西斯·高尔顿爵士由查理斯·威灵顿·弗斯所著,公有领域

弗朗西斯·高尔顿爵士是英国统计学家,他创立了相关性、回归均值、数据收集调查和词汇假设等概念。

高尔顿董事会:

我想向你介绍弗朗西斯·高尔顿爵士开发的最著名的统计设备之一:高尔顿板,Hextat 概率演示器,豆子机,概率机,或五点形。这些是一个智能设备的名字,提供给我们在几秒钟内做几千次硬币翻转等效实验。

这是中心极限定理的一个极好的直观例子。小球通过分支路径随机下落,最终总是呈正态分布。从细节上看,随机性是混乱的,但总是遵循一种普遍的秩序。

高尔顿板由一个垂直板和交错排列的钉子组成。珠子从顶部落下,当设备处于水平状态时,当它们碰到钉子时会向左或向右反弹。

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

一个高尔顿盒显示正态分布,马特马特卡 IME-USP / 罗德里戈铁雄阿根顿

为什么高尔顿板类似于抛硬币?因为在两个实验中,概率是相等的。在高尔顿棋盘上,像掷硬币一样,球通过几排钉子选择向左或向右的路径。

高尔顿板实验

结论:

高尔顿板是证明中心极限定理的二项式分布的极好演示;当你添加独立的随机变量时,它们的和趋向于正态分布。特别地,它证明了中心极限定理的一个特例——德莫维尔-拉普拉斯定理。

非常感谢您对 seymatas@gmail.com 的任何建议!

用机器学习找到值得买的股票

原文:https://towardsdatascience.com/beat-the-stock-market-with-machine-learning-d9432ea5241e?source=collection_archive---------5-----------------------

有没有可能让一个机器学习模型学习表现良好和表现不佳的股票之间的差异,然后利用这些知识来预测哪只股票值得购买?此外,仅仅通过查看 10-K 文件中的财务指标就能做到这一点吗?

懒惰策略

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

马库斯·斯皮斯克在 Unsplash 上的照片

算法交易领域充斥着新的策略。企业已经在基础设施和 R&D 上投入了数十亿美元(并且还在继续投资),以便在竞争中脱颖而出,战胜市场。尽管如此,众所周知,买入&持有策略能够胜过许多算法策略,尤其是在长期。然而,发现股票价值是一门很少有人掌握的艺术,一个算法能被训练成这样吗?

本文包含了为大量股票建立金融数据数据集并使用不同的机器学习模型进行分析所需的所有步骤。你会在整篇文章中看到,这种操作方式并没有利用历史股票价格数据,而是利用了每个上市公司每年发布的 10-K 文件中的财务指标。特别是,就本文而言,我们将使用 2018 年的财务数据,以便对 2019 年期间(指从 2019 年 1 月的第一个交易日到 2019 年 12 月的最后一个交易日)的股票表现进行一些虚构的预测。

在开始写代码之前,必须清楚的是这篇文章并没有给出一个你可以使用的实际交易策略:

  1. 我不是理财顾问,你也绝对不应该从网上获取理财建议。
  2. 你不能实现它来预测股票市场,因为你缺乏在训练阶段设置标签所需的未来信息。

*本文想要探索的是,通过训练并向最大似然算法提供财务报表中报告的数字,让它们识别价值增长的股票的可能性。*为了检查这是否属实,测试阶段由 ML 算法做出的预测(可被视为虚构交易)将与标准普尔 500 指数和道琼斯指数进行比较。

最后,我们不会在一年内多次买卖股票:我们将使用一种**懒惰策略,**在年初(这里是 2019 年)买入股票,然后在年底卖出,希望能够盈利。

说到这里,让我们直接进入有趣的部分。

第 1 部分:构建数据集

1.1 初步进口

如果你熟悉 Python 中的机器学习,你应该已经知道我们将要使用的所有包和库。如果您是这个领域的新手,不要害怕,您可以找到每个包和库的大量信息和教程。所有使用的包都很容易检索,并且可以根据您的 Python 设置用pipconda安装(这里使用了Python 3.7.5)。

为了从网上抓取数据,需要互联网连接(我们将使用优秀的免费 APIhttps://financialmodelingprep.com/developer/docs/和众所周知的pandas_datareader)。

**from** **sys** **import** stdout
**import** **numpy** **as** **np**
**import** **pandas** **as** **pd**
**from** **pandas_datareader** **import** data
**import** **json**

*# Reading data from external sources*
**import** **urllib** **as** **u**
**from** **urllib.request** **import** urlopen

*# Machine learning (preprocessing, models, evaluation)*
**from** **sklearn.model_selection** **import** train_test_split
**from** **sklearn.preprocessing** **import** StandardScaler
**from** **sklearn.model_selection** **import** GridSearchCV
**from** **sklearn.svm** **import** SVC
**from** **sklearn.ensemble** **import** RandomForestClassifier
**from** **sklearn.neural_network** **import** MLPClassifier
**import** **xgboost** **as** **xgb**
**from** **sklearn.metrics** **import** classification_report

*# Graphics*
**from** **tqdm** **import** tqdm

为了简化代码,我们还需要一些助手函数:

  1. get_json_data:用于抓取 financialmodelingprep API 的链接,拉取财务数据。
  2. get_price_var:用于计算 2019 年期间的价格变化,利用pandas_datareader和雅虎财经。
  3. find_in_json:用来扫描一个复杂的 json 文件,寻找一个键并返回它的值。
**def** get_json_data(url):
    *'''*
 *Scrape data (which must be json format) from given url*
 *Input: url to financialmodelingprep API*
 *Output: json file*
 *'''*
    response = urlopen(url)
    dat = response.read().decode('utf-8')
    **return** json.loads(dat)

**def** get_price_var(symbol):
    *'''*
 *Get historical price data for a given symbol leveraging the power of pandas_datareader and Yahoo.*
 *Compute the difference between first and last available time-steps in terms of Adjusted Close price..*
 *Input: ticker symbol*
 *Output: price variation* 
 *'''*
    *# read data*
    prices = data.DataReader(symbol, 'yahoo', '2019-01-01', '2019-12-31')['Adj Close']

    *# get all timestamps for specific lookups*
    today = prices.index[-1]
    start = prices.index[0]

    *# calculate percentage price variation*
    price_var = ((prices[today] - prices[start]) / prices[start]) * 100
    **return** price_var

**def** find_in_json(obj, key):
    *'''*
 *Scan the json file to find the value of the required key.*
 *Input: json file*
 *required key*
 *Output: value corresponding to the required key*
 *'''*
    *# Initialize output as empty*
    arr = []

    **def** extract(obj, arr, key):
        *'''*
 *Recursively search for values of key in json file.*
 *'''*
        **if** isinstance(obj, dict):
            **for** k, v **in** obj.items():
                **if** isinstance(v, (dict, list)):
                    extract(v, arr, key)
                **elif** k == key:
                    arr.append(v)
        **elif** isinstance(obj, list):
            **for** item **in** obj:
                extract(item, arr, key)
        **return** arr

    results = extract(obj, arr, key)
    **return** results

1.2 股票清单

首先,我们需要获得将用于构建数据集的股票列表。由于有数以千计的股票的信息可以在网上搜集,我决定简单地在金融建模准备 API 上获取所有股票的列表。

这份名单包含了总共超过 7k 只股票,显然涵盖了不止一个行业。事实上,每个公司都属于自己的领域(科技、医疗、能源……),而这些领域又可能具有某些季节性、宏观经济趋势等特征。到目前为止,我决定专注于技术板块:这意味着从完整的可用股票列表available_tickers中,我只保留那些板块等于Technology的股票。多亏了pandas库的强大功能,这个操作非常简单。

因此,列表tickers_tech将包含金融建模准备 API 上属于技术部门的所有可用股票。

url = 'https://financialmodelingprep.com/api/v3/company/stock/list'
ticks_json = get_json_data(url)
available_tickers = find_in_json(ticks_json, 'symbol')

tickers_sector = []
**for** tick **in** tqdm(available_tickers):
    url = 'https://financialmodelingprep.com/api/v3/company/profile/' + tick *# get sector from here*
    a = get_json_data(url)
    tickers_sector.append(find_in_json(a, 'sector'))

S = pd.DataFrame(tickers_sector, index=available_tickers, columns=['Sector'])

*# Get list of tickers from TECHNOLOGY sector*
tickers_tech = S[S['Sector'] == 'Technology'].index.values.tolist()

1.3 了解 2019 年全年的价格变化

2019 年期间tickers_tech中列出的每只股票的价格变化将被用作区分值得购买和不值得购买的股票的指标(因为它们降低了它们的价值,出于我们并不真正关心的原因)。因此,我们需要:

  • 提取每只股票的所有每日调整收盘价,计算差价(这要感谢助手函数get_price_var
  • 如果没有找到数据,跳过股票
  • 限制要扫描的股票数量为 1000(出于时间原因。当我们提取财务数据时,所需的时间与股票数量成正比,因此为了保持合理,我们可以将股票数量限制在一个阈值内。但是,您可以放弃此检查,让计算机在夜间工作)。
  • 在数据框架中存储库存和 2019 年相对价格变化D
pvar_list, tickers_found = [], []
num_tickers_desired = 1000
count = 0
tot = 0
TICKERS = tickers_tech

**for** ticker **in** TICKERS:
    tot += 1 
    **try**:
        pvar = get_price_var(ticker)
        pvar_list.append(pvar)
        tickers_found.append(ticker)
        count += 1
    **except**:
        **pass**

    stdout.write(f'**\r**Scanned **{tot}** tickers. Found **{count}**/{len(TICKERS)} usable tickers (max tickets = **{num_tickers_desired}**).')
    stdout.flush()

    **if** count == num_tickers_desired: *# if there are more than 1000 tickers in sectors, stop*
        **break**

*# Store everything in a dataframe*
D = pd.DataFrame(pvar_list, index=tickers_found, columns=['2019 PRICE VAR [%]'])

对于D中的股票,我们现在需要找到将成为分类模型输入数据的指标值。我们再次利用了 FinancialModelingPrep API。

首先,我们加载indicators.tx文件(可以在存储库中找到)。正如README文件所解释的,过多的财务指标正在被剔除。我决定对来自 FinancialModelingPrep API 的所有可用指标执行一次强力操作,然后我将担心清理和准备模型的数据集。下表汇总了每个类别可用的财务指标数量。

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

API 中每个类别可用的财务指标数量(https://financialmodelingprep.com)。

总共有 224 个指标可用。但由于有一些重复,所以indicators.txt中指标的实际数量是 221(不算日期)。你可以在这里找到indicators.txt文件:https://github . com/cnic 92/beat-the-stock-market/tree/master/All % 20 tickers % 20 and % 20 indicators

1.4 收集财务指标并构建原始数据集

截至目前,我们已经列出了属于技术板块的股票,并且我们还列出了它们 2019 年的价格变化。是时候收集财务指标了,这些指标将在以后用作分类模型的输入特征。

由于财务建模准备 API,将再次执行抓取。这个过程非常耗时,因为需要反复提取大量数据。

此外,记住以下几点很重要:

  • 需要在特定的时间范围内提取数据。由于目标是根据 2019 年期间的价格变化对股票进行分类,因此财务指标必须属于 2018 年底。
  • 一家公司在同一年提交两份 10-K 文件是有可能的,尽管不常见。在这种情况下,必须只保留最近的条目。
  • 对于给定的股票,API 可能根本不返回任何数据。在这种情况下,原料必须废弃。
  • 并非所有指示器都会返回值。出于这样或那样的原因,有一定比例的指标缺失是合理的。在这种情况下,np.nan将被分配给缺失的条目,我们将在清理阶段处理它们。

最后,我们想要获得的是一个数据帧DATA,其中行对应于已经找到数据的股票(actual_tickers),列对应于财务指标(indicators)。

*# Initialize lists and dataframe (dataframe is a 2D numpy array filled with 0s)*
missing_tickers, missing_index = [], []
d = np.zeros((len(tickers_found), len(indicators)))

**for** t, _ **in** enumerate(tqdm(tickers_found)):
    *# Scrape indicators from financialmodelingprep API*
    url0 = 'https://financialmodelingprep.com/api/v3/financials/income-statement/' + tickers_found[t]
    url1 = 'https://financialmodelingprep.com/api/v3/financials/balance-sheet-statement/' + tickers_found[t]
    url2 = 'https://financialmodelingprep.com/api/v3/financials/cash-flow-statement/' + tickers_found[t]
    url3 = 'https://financialmodelingprep.com/api/v3/financial-ratios/' + tickers_found[t]
    url4 = 'https://financialmodelingprep.com/api/v3/company-key-metrics/' + tickers_found[t]
    url5 = 'https://financialmodelingprep.com/api/v3/financial-statement-growth/' + tickers_found[t]
    a0 = get_json_data(url0)
    a1 = get_json_data(url1)
    a2 = get_json_data(url2)
    a3 = get_json_data(url3)
    a4 = get_json_data(url4)
    a5 = get_json_data(url5)

    *# Combine all json files in a list, so that it can be scanned quickly*
    A = [a0, a1, a2 , a3, a4, a5]
    all_dates = find_in_json(A, 'date')

    check = [s **for** s **in** all_dates **if** '2018' **in** s] *# find all 2018 entries in dates*
    **if** len(check) > 0:
        date_index = all_dates.index(check[0]) *# get most recent 2018 entries, if more are present*

        **for** i, _ **in** enumerate(indicators):
            ind_list = find_in_json(A, indicators[i])
            **try**:
                d[t][i] = ind_list[date_index]
            **except**:
                d[t][i] = np.nan *# in case there is no value inserted for the given indicator*

    **else**:
        missing_tickers.append(tickers_found[t])
        missing_index.append(t)

actual_tickers = [x **for** x **in** tickers_found **if** x **not** **in** missing_tickers]
d = np.delete(d, missing_index, 0)*#raw dataset* DATA = pd.DataFrame(d, index=actual_tickers, columns=indicators)

1.5 数据集清理和准备

数据集的准备在某种程度上是一门艺术。我将我的行动限制在应用常见的实践,例如:

  • 删除具有大量nan值的列。
  • 删除具有大量0值的列。
  • 用该列的平均值填充剩余的nan值。

例如,在这种特定情况下,每列平均有 84 个 0 值和 140 的标准偏差。所以我决定从 dataframe 中删除所有那些出现的 0 值大于 20 的列(20 大约是数据集总行数的 3.1%)。

同时,每列平均约有 37 个nan条目,标准差约为 86。所以我决定从数据帧中删除所有那些出现次数大于 15 的列(15 大约是数据集总行数的 2.4%)。然后,剩余的nan条目已经用该列的平均值填充。

在清洗过程结束时,DATA的列数从 221 列减少到 108 列,减少了 50%。虽然由于缺乏数据,一些被丢弃的指标毫无用处,但有用的数据也有可能在这一过程中丢失。但是,必须考虑到我们需要数据集中所有股票的有用数据,所以我认为丢弃那些可能只与数据集一小部分相关的指标(列)是可以接受的。

最后,需要对每个样本进行分类。对于每只股票,已经计算了 2019 年 1 月第一个交易日和 2019 年 12 月最后一个交易日之间的交易价格差异(数据集D)。如果这个差值为正,那么该股票将属于类别1,这是一个买入信号。相反,如果价格差异为负,该股票将被归类为0,这是一个忽略信号(不要买入)。下表提供了一个快速回顾。

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

为股票指定二元分类的标准。

因此,10值的数组将作为数据帧DATA的最后一列被追加。

*# Remove columns that have more than 20 0-values*
DATA = DATA.loc[:, DATA.isin([0]).sum() <= 20]

*# Remove columns that have more than 15 nan-values*
DATA = DATA.loc[:, DATA.isna().sum() <= 15]

*# Fill remaining nan-values with column mean value*
DATA = DATA.apply(**lambda** x: x.fillna(x.mean())) 

*# Get price variation data only for tickers to be used*
D2 = D.loc[DATA.index.values, :]

*# Generate classification array*
y = []
**for** i, _ **in** enumerate(D2.index.values):
    **if** D2.values[i] >= 0:
        y.append(1)
    **else**: 
        y.append(0)

*# Add array to dataframe*
DATA['class'] = y

本文的第一部分到此结束。我们建立了一个数据集,其中包含 2018 年的相关金融指标和来自 2019 年股票价格走势的二元类。在第 2 节中,我们将重点介绍一些机器学习算法的实现,以便对股票进行预测,并努力战胜市场!

第 2 部分:通过机器学习算法进行虚拟预测

2.1 准备数据集

在用不同的机器学习算法进行有趣的实验之前,我们必须对数据集进行最后的润色,包括:

  1. 在训练和测试数据集中拆分数据集;
  2. 标准化数据集,使每个指标的均值为 0,标准差等于 1。

因此,关于将它分成训练和测试,在DATA中 80%的可用数据将用于训练算法,而剩余的 20%将用于测试 ML 算法。请注意所使用的参数stratify,以便在训练和测试数据集之间保持相同的类比率。从train_splittest_split中,我们提取输入数据X_trainX_test和输出目标数据y_trainy_test。之后会执行健全性检查。

*# Divide data in train and testing*
train_split, test_split = train_test_split(df, test_size=0.2, random_state=1, stratify=df['class'])
X_train = train_split.iloc[:, :-1].values
y_train = train_split.iloc[:, -1].values
X_test = test_split.iloc[:, :-1].values
y_test = test_split.iloc[:, -1].values

print()
print(f'Number of training samples: **{X_train.shape[0]}**')
print()
print(f'Number of testing samples: **{X_test.shape[0]}**')
print()
print(f'Number of features: **{X_train.shape[1]}**')

结果是:

Number of training samples: 510

Number of testing samples: 128

Number of features: 107

关于数据的标准化,我们利用从scikit-learn获得的StandardScaler()在标准化训练和测试数据时使用相同的系数是很重要的:为此,我们首先将定标器应用于X_train,然后通过方法.transform()将其应用于X_trainX_test

*# Standardize input data*
scaler = StandardScaler()
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)

2.2 支持向量机

我们将运行的第一个分类算法是支持向量机。执行GridSeachCV是为了调整一些超参数(kernelgammaC)。所需的交叉验证次数设置为 5。我们希望实现最大的加权精度,以便最小化假阳性的数量。

*# Parameter grid to be tuned*
tuned_parameters = [{'kernel': ['rbf', 'linear'],
                     'gamma': [1e-3, 1e-4],
                     'C': [0.01, 0.1, 1, 10, 100]}]

clf1 = GridSearchCV(SVC(random_state=1),
                    tuned_parameters,
                    n_jobs=6,
                    scoring='precision_weighted',
                    cv=5)
clf1.fit(X_train, y_train)

print('Best score and parameters found on development set:')
print()
print('**%0.3f** for **%r**' % (clf1.best_score_, clf1.best_params_))
print()

成绩还不算太差。我们可以看到,如下图所示,我们的加权精度为 71.3%。如果您仔细阅读,您可能会注意到评分参数被设置为等于 metric precision_weighted 。这样做是为了优化算法的精度(不要与精度混淆!)和加权,因为我们没有两类(值得购买的股票和不值得购买的股票)相同数量的样本。关于这个和其他评分参数的更多信息,你可以查看这里的文档https://scikit learn . org/stable/modules/model _ evaluation . html

Best score and parameters found on development set: 0.713 for {‘C’: 0.01, ‘gamma’: 0.001, ‘kernel’: ‘linear’}

2.3 随机森林

我们将运行的第二个分类算法是随机森林。执行GridSeachCV是为了调整一些超参数(n_estimatorsmax_featuresmax_depthcriterion)。所需的交叉验证次数设置为 5。我们希望实现最大的加权精度,以便最小化假阳性的数量。

*# Parameter grid to be tuned*
tuned_parameters = {'n_estimators': [32, 256, 512, 1024],
                    'max_features': ['auto', 'sqrt'],
                    'max_depth': [4, 5, 6, 7, 8],
                    'criterion': ['gini', 'entropy']}clf2 = GridSearchCV(RandomForestClassifier(random_state=1),
                    tuned_parameters,
                    n_jobs=6,
                    scoring='precision_weighted',
                    cv=5)
clf2.fit(X_train, y_train)print('Best score and parameters found on development set:')
print()
print('**%0.3f** for **%r**' % (clf2.best_score_, clf2.best_params_))
print()

我们可以看到,如下所示,该算法比支持向量机高出几个百分点,因为我们的加权精度为 72.4%。

Best score and parameters found on development set:  0.724 for {'criterion': 'gini', 'max_depth': 5, 'max_features': 'auto', 'n_estimators': 32}

2.4 极限梯度提升

我们将运行的第三个分类算法是极端梯度提升。执行GridSeachCV是为了调整一些超参数(learning_ratemax_depthn_estimators)。所需的交叉验证次数设置为 5。我们希望实现最大的加权精度,以便最小化假阳性的数量。

*# Parameter grid to be tuned*
tuned_parameters = {'learning_rate': [0.01, 0.001],
                    'max_depth': [4, 5, 6, 7, 8],
                    'n_estimators': [32, 128, 256]}clf3 = GridSearchCV(xgb.XGBClassifier(random_state=1),
                   tuned_parameters,
                   n_jobs=6,
                   scoring='precision_weighted', 
                   cv=5)
clf3.fit(X_train, y_train)print('Best score and parameters found on development set:')
print()
print('**%0.3f** for **%r**' % (clf3.best_score_, clf3.best_params_))
print()

该算法比支持向量机和随机森林分类器低几个百分点,因为我们的加权精度为 69.7%。

Best score and parameters found on development set:  0.697 for {'learning_rate': 0.001, 'max_depth': 4, 'n_estimators': 256}

2.5 多层感知器

我们将运行的第四个分类算法是多层感知器(前馈神经网络)。执行GridSeachCV是为了调整一些超参数(hidden_layer_sizesactivationsolver)。所需的交叉验证次数设置为 5。我们希望获得最大的加权精度,以便最小化假阳性的数量。

*# Parameter grid to be tuned*
tuned_parameters = {'hidden_layer_sizes': [(32,), (64,), (32, 64, 32)],
                    'activation': ['tanh', 'relu'],
                    'solver': ['lbfgs', 'adam']}clf4 = GridSearchCV(MLPClassifier(random_state=1, batch_size=4, early_stopping=**True**), 
                    tuned_parameters,
                    n_jobs=6,
                    scoring='precision_weighted',
                    cv=5)
clf4.fit(X_train, y_train)print('Best score, and parameters, found on development set:')
print()
print('**%0.3f** for **%r**' % (clf4.best_score_, clf4.best_params_))
print()

这个算法是最好的,因为它优于所有以前测试过的算法。MLP 的加权精度为 73%。

Best score, and parameters, found on development set:  0.730 for {'activation': 'relu', 'hidden_layer_sizes': (32, 64, 32), 'solver': 'adam'}

2.6 评估模型

既然已经训练了 4 种分类算法,我们必须对它们进行测试,并比较它们之间的性能,以及它们与该领域基准(标准普尔 500、道琼斯)的性能。事实上,我们并不局限于比较它们的测试精度:我们想了解哪种算法能带来最好的投资回报(ROI) 。要做到这一点,我们必须首先获得包含在pvar中的 2019 年价格变化,这些股票只属于测试数据集(我们还没有使用它!).

*# Get 2019 price variations ONLY for the stocks in testing split*
pvar_test = pvar.loc[test_split.index.values, :]

现在,我们构建一个新的数据框架df1,其中,对于每只测试的股票,我们从每个模型中收集所有的预测类(需要提醒的是,这两个类是0 =IGNORE,1 =BUY)。

如果模型预测了类别1,我们继续购买价值 100 美元的股票;否则,我们忽略股票。

*# Initial investment can be $100 for each stock whose predicted class = 1*
buy_amount = 100*# In new dataframe df1, store all the information regarding each model's predicted class and relative gain/loss in $USD*
df1 = pd.DataFrame(y_test, index=test_split.index.values, columns=['ACTUAL']) *# first column is the true class (BUY/INGORE)*df1['SVM'] = clf1.predict(X_test) *# predict class for testing dataset*
df1['VALUE START SVM [$]'] = df1['SVM'] * buy_amount *# if class = 1 --> buy $100 of that stock*
df1['VAR SVM [$]'] = (pvar_test['2019 PRICE VAR [%]'].values / 100) * df1['VALUE START SVM [$]'] *# compute price variation in $*
df1['VALUE END SVM [$]'] = df1['VALUE START SVM [$]'] + df1['VAR SVM [$]'] *# compute final value*df1['RF'] = clf2.predict(X_test)
df1['VALUE START RF [$]'] = df1['RF'] * buy_amount
df1['VAR RF [$]'] = (pvar_test['2019 PRICE VAR [%]'].values / 100) * df1['VALUE START RF [$]']
df1['VALUE END RF [$]'] = df1['VALUE START RF [$]'] + df1['VAR RF [$]']df1['XGB'] = clf3.predict(X_test)
df1['VALUE START XGB [$]'] = df1['XGB'] * buy_amount
df1['VAR XGB [$]'] = (pvar_test['2019 PRICE VAR [%]'].values / 100) * df1['VALUE START XGB [$]']
df1['VALUE END XGB [$]'] = df1['VALUE START XGB [$]'] + df1['VAR XGB [$]']df1['MLP'] = clf4.predict(X_test)
df1['VALUE START MLP [$]'] = df1['MLP'] * buy_amount
df1['VAR MLP [$]'] = (pvar_test['2019 PRICE VAR [%]'].values / 100) * df1['VALUE START MLP [$]']
df1['VALUE END MLP [$]'] = df1['VALUE START MLP [$]'] + df1['VAR MLP [$]']

最后,我们构建了一个紧凑的数据框架MODELS_COMPARISON,在其中我们收集了在分类模型和基准(S & P 500,DOW JONES)之间进行比较所需的主要信息。

利用数据框架df1,我们可以轻松计算每个模型的收益和损失(net_gain_percent_gain_)。

由于我们错过了基准测试的数据,我们很快利用自定义函数get_price_var来获得 2019 年标准普尔 500 (GSPC)和道琼斯(DJI)的价格变化百分比。

*# Create a new, compact, dataframe in order to show gain/loss for each model*
start_value_svm = df1['VALUE START SVM [$]'].sum()
final_value_svm = df1['VALUE END SVM [$]'].sum()
net_gain_svm = final_value_svm - start_value_svm
percent_gain_svm = (net_gain_svm / start_value_svm) * 100start_value_rf = df1['VALUE START RF [$]'].sum()
final_value_rf = df1['VALUE END RF [$]'].sum()
net_gain_rf = final_value_rf - start_value_rf
percent_gain_rf = (net_gain_rf / start_value_rf) * 100start_value_xgb = df1['VALUE START XGB [$]'].sum()
final_value_xgb = df1['VALUE END XGB [$]'].sum()
net_gain_xgb = final_value_xgb - start_value_xgb
percent_gain_xgb = (net_gain_xgb / start_value_xgb) * 100start_value_mlp = df1['VALUE START MLP [$]'].sum()
final_value_mlp = df1['VALUE END MLP [$]'].sum()
net_gain_mlp = final_value_mlp - start_value_mlp
percent_gain_mlp = (net_gain_mlp / start_value_mlp) * 100percent_gain_sp500 = get_price_var('^GSPC') *# get percent gain of S&P500 index*
percent_gain_dj = get_price_var('^DJI') *# get percent gain of DOW JONES index*MODELS_COMPARISON = pd.DataFrame([start_value_svm, final_value_svm, net_gain_svm, percent_gain_svm],
                    index=['INITIAL COST [USD]', 'FINAL VALUE [USD]', '[USD] GAIN/LOSS', 'ROI'], columns=['SVM'])
MODELS_COMPARISON['RF'] = [start_value_rf, final_value_rf, net_gain_rf, percent_gain_rf]
MODELS_COMPARISON['XGB'] = [start_value_xgb, final_value_xgb, net_gain_xgb, percent_gain_xgb]
MODELS_COMPARISON['MLP'] = [start_value_mlp, final_value_mlp, net_gain_mlp, percent_gain_mlp]
MODELS_COMPARISON['S&P 500'] = ['', '', '', percent_gain_sp500]
MODELS_COMPARISON['DOW JONES'] = ['', '', '', percent_gain_dj]

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

MODELS_COMPARISON 数据集总结了结果。

从数据帧MODELS_COMPARISON中,可以看出:

  • XGB 和 RF 是产生最高 ROI 的 ML 模型,分别为 31.3%和 40.9%
  • RF 的表现超过标准普尔 500 12 个百分点,超过道琼斯 20 个百分点
  • XGB 比标准普尔 500 高出几个百分点,而比道琼斯高出近 10 个百分点
  • MLP 和 SVM 的投资回报率非常接近,分别为 28.3%和 27.2%
  • MLP 和 SVM 的表现与标准普尔 500 类似,但都优于道琼斯指数
  • SVM 的净收益最高,约为 3290 美元;但是,它的初始投资成本最高,为 12100 美元
  • 射频导致最低的净收益,约为 1920 美元;但是,它的初始投资成本也最低,为 4700 美元

因此,这个例子证明,至少作为概念证明,在上市公司发布的 10-K 文件中找到有用的信息是可能的。金融信息可以用来训练机器学习模型,学习识别值得购买的股票。

对于所实现的 ML 模型之间的性能的更传统的比较,可以分析classification_report

**from** **sklearn.metrics** **import** classification_report

print()
print(53 * '=')
print(15 * ' ' + 'SUPPORT VECTOR MACHINE')
print(53 * '-')
print(classification_report(y_test, clf1.predict(X_test), target_names=['IGNORE', 'BUY']))
print(53 * '-')
print(53 * '=')
print(20 * ' ' + 'RANDOM FOREST')
print(53 * '-')
print(classification_report(y_test, clf2.predict(X_test), target_names=['IGNORE', 'BUY']))
print(53 * '-')
print(53 * '=')
print(14 * ' ' + 'EXTREME GRADIENT BOOSTING')
print(53 * '-')
print(classification_report(y_test, clf3.predict(X_test), target_names=['IGNORE', 'BUY']))
print(53 * '-')
print(53 * '=')
print(15 * ' ' + 'MULTI-LAYER PERCEPTRON')
print(53 * '-')
print(classification_report(y_test, clf4.predict(X_test), target_names=['IGNORE', 'BUY']))
print(53 * '-')

其屈服于:

=====================================================
               SUPPORT VECTOR MACHINE
-----------------------------------------------------
              precision    recall  f1-score   support

      IGNORE       0.40      0.05      0.09        38
         BUY       0.71      0.97      0.82        90

    accuracy                           0.70       128
   macro avg       0.55      0.51      0.45       128
weighted avg       0.62      0.70      0.60       128

-----------------------------------------------------
=====================================================
                    RANDOM FOREST
-----------------------------------------------------
              precision    recall  f1-score   support

      IGNORE       0.37      0.79      0.50        38
         BUY       0.83      0.43      0.57        90

    accuracy                           0.54       128
   macro avg       0.60      0.61      0.54       128
weighted avg       0.69      0.54      0.55       128

-----------------------------------------------------
=====================================================
              EXTREME GRADIENT BOOSTING
-----------------------------------------------------
              precision    recall  f1-score   support

      IGNORE       0.48      0.34      0.40        38
         BUY       0.75      0.84      0.80        90

    accuracy                           0.70       128
   macro avg       0.62      0.59      0.60       128
weighted avg       0.67      0.70      0.68       128

-----------------------------------------------------
=====================================================
               MULTI-LAYER PERCEPTRON
-----------------------------------------------------
              precision    recall  f1-score   support

      IGNORE       0.39      0.29      0.33        38
         BUY       0.73      0.81      0.77        90

    accuracy                           0.66       128
   macro avg       0.56      0.55      0.55       128
weighted avg       0.63      0.66      0.64       128

-----------------------------------------------------

仔细看,平心而论地问:**如果是加权精度最低的方法,为什么 RF 回报最高的 ROI?**这是因为:

  • RF 对购买类的精确度最高(83%)。事实上,83%的买入预测是真阳性,剩下的 17%是假阳性
  • 最大限度地减少误报的数量可以最大限度地减少花在 2019 年将会贬值的股票上的钱
  • RF 在忽略类别中具有最高的召回率(79%),这意味着它正确地识别了 79%不应该被购买的股票

然而,所有这一切意味着我们错过了许多可以购买的潜在股票,因为 RF 导致了大量的假阴性。事实上,很容易看出 RF 在买入类中具有最低的召回值(43%),这意味着我们只找到了 43%的应被归类为值得买入的股票。

本文的第 2 部分到此结束。希望你会觉得它有用和鼓舞人心。有关财务建模准备 API、代码和历史数据的更多信息,请查看下面的链接。

[## 免费股票 API 和财务报表 API - FMP API

该文档包括财务报表 API、免费股票 API 和历史报价 API。查找全部…

financialmodelingprep.com](https://financialmodelingprep.com/developer/docs/) [## cnic 92/跑赢股市

这个项目从我在 2019 年寒假问自己的一个问题开始:有可能了解哪些…

github.com](https://github.com/CNIC92/beat-the-stock-market) [## 美股 200+财务指标(2014-2018)

尝试利用 200 多个财务指标预测股票的未来表现

www.kaggle.com](https://www.kaggle.com/cnic92/200-financial-indicators-of-us-stocks-20142018)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值