TowardsDataScience 博客中文翻译 2019(三十六)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

适应或死亡:为什么你的业务战略是失败的数据战略

原文:https://towardsdatascience.com/adapt-or-die-why-your-business-strategy-is-failing-your-data-strategy-387e6ca32874?source=collection_archive---------31-----------------------

几年前,我接到一位对冲基金分析师的电话,他正在寻找外部数据,用他的话说,就是提供“阿尔法值”。我解释说,我们公司连接到数千个数据源和数十万个公共数据集;我告诉他,我们正在不断地从 70 个国家获取开放数据,通过一个针对世界上最大的公共数据目录进行训练的摄取管道来实现标准化,并通过一套直接插入任何生态系统的 API 来提供这些数据。

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

有一个短暂的停顿,分析师说,“我都知道。你有什么我没有的吗?”

这让我很惊讶。“你是在告诉我,你已经在下载和处理来自美国每个公共机构和市政当局的数据了吗?”

“不,但我可以。很容易得到那种东西。我想要别人没有的东西。”

这不会是我最后一次听到有人这么说。认为公共数据易于访问的错误观念定义了开放数据运动的第一个十年,这对那些实际上试图使用它来做出明智商业决策的人非常不利。实际上,公共数据不容易访问,也不容易使用。我们称之为 可用和可用之间的差异,这是采用的一个重大障碍。

对于现代企业来说,有效地访问和使用数据无疑是非常重要的。无论是组织内部生成的数据、政府公开数据,甚至是其他企业发布的数据,通过将这些信息流导入分析模型或应用程序,都可以释放大量价值。面对如此多的新数据,高管们都迫不及待地想要获取新数据,因为他们知道谁创新最快,谁就能从适应不够快的人那里抢走市场份额。

这种对创新的关注导致组织雇用了大量数据科学家和分析师,他们的任务是创建可用于推动商业智能的新产品、服务和应用。

那么问题出在哪里?

问题在于业务部门基于结果的思维和数据科学家的现实之间的脱节。当你雇佣了一队数据科学家时,“创新”是被期待的,但在基层,他们所做的工作中只有一小部分可以被认为是开创性的。大多数时候,数据科学家都在为我在对冲基金的量化朋友认为很简单的事情而努力:获取数据,提炼数据,并将其插入应用程序。

由于处理数据的困难,我们看到人们对数据项目越来越不满意。炒作是有的,人才是有的,但结果却不是。由于有效使用数据的操作障碍,数月甚至数年的工作变成了无法生产的想法。这对数据科学家来说是令人沮丧的,对高管来说是一个紧迫的业务问题。

形势看起来很严峻。2016 年,Gartner 估计 60%的大数据项目失败,一年后 Gartner 分析师 Nick Heudecker 表示 这一数字可能接近 85% 。不管你的钱包有多鼓,没有一个正常的企业会一直把钱砸在一个每五次就有四次失败的东西上。

现实情况是,为了创新,所有企业都必须优化其数据战略。

从管理的角度来看,优化始于沟通。首席管理人员和数据科学部门之间需要更好的对话。运营目标应该明确,数据科学家必须获得有效完成工作所需的资源。拥有数据战略是朝着正确方向迈出的一步,但它已经实施了吗?想要数据驱动是不够的,你还需要了解这需要什么,并为你的团队提供工具和支持,使他们能够将想法投入生产。

优化数据基础架构的第二种方法是加快耗时的数据管理任务,这些任务一直困扰着各地的数据部门。

在理想情况下,数据科学家有权进行实验和尝试想法,但在操作上这通常是不可能的。寻找、收集、标准化、提炼和整合数据花费的时间太长了。这个操作陷阱的结果是两种情况之一:

  1. 想法来自高层,高管们决定关键目标,并把他们的数据部门扔给他们;或者
  2. 数据科学家在受控环境中工作,使用合成的小数据来测试模型。

在第一种情况下,数据科学家缺乏所有权,并被束缚在可能不可行的项目上。在第二种情况下,好的想法和体面的模型往往在它们被放入现实世界的那一刻就失败了。

通过采用 DataOps 框架并找到自动化收集数据的准备和处理阶段的方法,数据科学家将能够更快地测试和评估想法,并确保他们的模型可以投入生产。这将导致产出增加,从而带来更好的业务成果。优化会带来创新。

最近,我在和一个想开始使用公共数据的人开会。我向他介绍了这个平台,并解释了获取和集成数据的步骤。

他耸耸肩。“我的数据团队可以做到这一切。”

这次我准备好了。”那么他们为什么没有呢?

【https://blog.thinkdataworks.com】最初发表于。****

使用 PyTorch 的自适应和循环学习率

原文:https://towardsdatascience.com/adaptive-and-cyclical-learning-rates-using-pytorch-2bf904d18dee?source=collection_archive---------7-----------------------

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

Photo by Sirma Krusteva on Unsplash

学习率(LR)是调整神经网络的关键参数之一。具有自适应学习率的 SGD 优化器已经流行了一段时间:Adam、Adamax 和它的老兄弟们通常是事实上的标准。它们消除了手动搜索和安排你的学习速度(如衰减率)的痛苦。

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

Source: Jeremy Jordan’s blogpost

这篇文章将给出一个简短的例子,概述和比较最流行的自适应学习率优化。我们将使用 PyTorch,时髦的神经网络库的选择!

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

除此之外,fast.ai 还宣扬了循环学习率(CLR)的概念,提到了莱斯利·史密斯的伟大论文(链接)。我们将看看 SGD 如何与其他优化程序相抗衡。

为了演示,我们将承担两项分类任务:

  • 基于普通 CNN 架构的图像分类
  • 使用预训练(在 ImageNet 上)的 ResNet34 网络进行图像分类

该职位的所有代码和培训日志可以在 GitHub 上找到。

数据

在这篇文章中,我们将使用 Kaggle 的“鲜花识别”数据集(链接)。这是一个很好的测试图像分类网络的基本真实数据集。

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

example image of the class ‘dandelion’

使用 20%进行验证的数据被平均分配到 5 个类别中进行预测:

自适应优化器

在不深入研究每一个优化器的数学原理的情况下,这里有一个简短(有点过于简单)的概述,介绍一下我们将要与之对抗的优化器:

  • Adagrad :这将根据梯度的过去历史,缩放每个参数的学习率。本质上:大梯度= >小α,反之亦然。然而不利的一面是学习率会很快下降。
  • Adadelta :在 Adagrad 上继续,但是有了新的花样:只存储过去的 w 渐变而不是整个历史,(现在有限的)历史存储为衰减的平均值。
  • RMSProp :有点类似(请不要向我开枪,辛顿先生,先生),但是 RMSProp 将 LR 除以梯度平方的指数衰减平均值。
  • Adam :除了存储历史梯度平方和,它还计算过去梯度的指数衰减平均值(类似于动量)。
  • Adamax :这里,另一个技巧应用于平方梯度 v(t)的移动平均值,作者应用无穷范数ℓ∞来获得新的范数约束向量 v(t),将其插入 Adam,从而获得令人惊讶的稳定算法。

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

👉提示:如果你正在寻找优化者的更深入的数学比较,看看 Sebastian Ruder 的这篇精彩的博客文章,它对我写这篇文章有很大帮助。

循环学习率

CLR 的论文提出了两个非常有趣的观点:

  1. 它为我们提供了一种在训练过程中有效安排学习速率的方法,即以三角形的方式在上限和下限之间变化。
  2. 这给了我们一个非常合理的估计,哪个学习率范围最适合你的特定网络。

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

这里有许多参数可供选择:

  • 步长:LR 从下限上升到上限需要多少个历元。
  • max_lr :调度中最高的 lr。
  • base_lr :进度表中最低的 lr,实际上:本文作者建议将此取比 max_lr 小一个因子 R。我们的利用系数是 6。

当然,很难分析出这种方法行得通的确切原因。LR 的发展可能会导致网络在短期内出现更高的损耗,但这种短期的缺点在长期内证明是有利的。如果当前的网络不太稳定,它可以让网络跳到另一个局部最小值。

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

Source: Snapsshot Ensembles (https://arxiv.org/abs/1704.00109)

CLR 优于上述自适应方法的另一个优点是计算量较小。

在论文中,还提到你可以随着时间线性或指数递减上界,但这在这篇博文中没有实现。

那么这在代码中是如何工作的呢?…

第一步:找到上面的 LR

以一个普通的 CNN 为例:第一步是为你的模型计算学习率的上限。做到这一点的方法是:

  • 定义一个初始学习率,即您想要测试的范围的下限(假设为 1e-7)
  • 定义范围的上限(假设为 0.1)
  • 定义一个指数方案来逐步完成这个过程:

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

Used formula for the LR finder scheduling (N = number of images, BS = Batch Size, lr = learning rate)

幸运的是,PyTorch 有一个 LambdaLR 对象,它允许我们在 lambda 函数中定义上述内容:

  • 接下来,在你的网络中运行(我用了两个纪元)。在每个步骤(每个批量):获取 LR、获取损失并优化梯度:

👉注意:我们不是在每一步取“原始”损失,而是平滑损失,即:损失= α。损耗+ (1- α)。以前的损失

在此之后,我们可以清楚地看到 LR 遵循一个很好的指数规律:

基本网络的损耗-lr 曲线(见下文)如下所示:

我们可以清楚地看到,过高的 LR 会导致网络损耗发散,过低的 LR 根本不会导致网络学习太多…

在他的 fast.ai 课程中,杰瑞米·霍华德提到一个好的上限并不在最低点,而是向左 10 倍。

考虑到这一点,我们可以说学习率的一个好的上限是:3e-3。

根据这篇论文和其他资料,一个好的下限是上限除以因子 6。

步骤 2: CLR 调度程序

第二步是创建一个循环学习时间表,它在下限和上限之间改变学习速率。

这可以通过多种方式实现:

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

Various possibilites for the CLR shape (source: jeremy jordan’s blog)

我们要用简单的三角 CLR 时间表。

以编程方式,我们只需要创建一个自定义函数:

第三步:包装

在步骤 3 中,这可以被包装在 PyTorch 中的 LambdaLR 对象中:

训练

在一个时期内,我们需要使用’更新 LR。scheduler 对象的“step()”方法:

对比 1:香草 CNN

首先是使用普通的(非预训练的)CNN 进行分类。我使用了以下网络架构:

为了防止模型过度适应(相对较小的)数据集,我们使用以下技术:

  • 线性图层中的丢失
  • CNN 块中的 Batchnorm 层
  • 数据扩充:

👉提示:你需要提前计算通道标准化的均值和标准差,查看完整的笔记本,看看如何解决这个问题。

我们为 6 个优化器中的每一个训练了 150 个时期的网络。为了消除一些可变性,我们为每个优化器运行了 3 次。

训练和验证准确性看起来像这样:

Training accuracy

Validation accuracy

好了,孩子们,我们在这里能看到什么:

👉阿达格拉德:平庸的表现,正如所料

👉阿达德尔塔:在 acc 训练中不是真正的冠军,但在验证中表现非常出色

👉RMSProp:除非我在这里做错了什么,否则我对糟糕的表现感到有点惊讶

👉亚当:一直很好

👉Adamax:有希望的训练精度发展,但没有完美地反映在验证精度上

👉带 CLR 的 SGD:训练精度收敛快得多,验证精度收敛快,不算太差…

最终,SGD+CLR、Adam 和 Adadelta 似乎都以大约 83%的最终验证准确率结束。

对比二:Resnet34 迁移学习

如果你说:“小数据集上的图像分类”,你需要考虑迁移学习。

所以我们就这么做了,使用 Resnet34,在 ImageNet 上进行预训练。我相信数据集相当接近 Imagenet 图片,所以我只解冻了 5 个卷积块的最后一个块,并用新的线性层替换了最后一个线性层:

对于 6 个优化器中的每一个,网络被训练 100 个时期(由于更快的收敛):

Training accuracy

Validation accuracy

此处有重要提示:

👉总的来说:优化器之间的差异要小得多,尤其是在观察验证准确性时

👉RMSProp:仍然有点表现不佳

👉SGD+CLR 在训练准确性方面再次表现良好,但这并没有立即反映在验证准确性上。

对于迁移学习来说,调整学习速度和仔细选择优化器的绝对回报似乎不太大。

这可能是由于两个主要影响:

  • 网络权重已经大大优化
  • 优化器通常只能优化整个网络权重的一小部分,因为大部分权重保持冻结

结论

这篇博文的主要观点是:

不要只是采用任何旧的现成的优化程序。学习率是最重要的超参数之一,因此仔细研究它是值得的。如果你想比较,看看 SGD 的 CLR 时间表。

再次声明:所有代码都可以在这里找到,可以随意查看!

资料来源和进一步阅读

Matlab/Simulink 中传感器融合的自适应巡航控制

原文:https://towardsdatascience.com/adaptive-cruise-control-with-sensor-fusion-within-matlab-simulink-294aeb24e6e0?source=collection_archive---------8-----------------------

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

最近,我试图使用 Matlab/Simulink 工具箱运行一些先进的驾驶辅助系统(ADAS)测试台。近年来,Matlab 发布了自动驾驶工具箱,结合最近流行的机器/深度学习技术,使得单个 ADAS 功能的开发变得更加简单。

在我继续讲下去之前,必须先对相关主题做一个简短的总结。

目标检测

关于这个问题有大量的教程和例子。可以使用 Tensorflow API 或 Matlab/Simulink 计算机视觉工具箱利用各种类型的传感器数据,例如 3D 激光雷达云点和/或从相机拍摄的图片,从相机视频流中检测物体。

即使通过 ML/DL 技术有可能检测到目标,它仍然远离甚至简单的 ADAS 功能开发。由于 ADAS 或自动驾驶汽车必须首先在传感器数据的帮助下正确地解释现实世界,因此它还应该具备思考、规划和反应的能力,更具体地说是对汽车的控制。

模型预测控制

基于简单的自行车模型,运动学和动力学控制方程可以馈入 MPC 算法。

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

模型预测控制只是控制技术中的一种,由于具有多输入/输出以及约束的优化能力,它在 ADAS 开发中越来越受欢迎。对于线性时不变(LTI)控制系统,连续状态空间模型可以描述为

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

continuum state-space model. A, B, C D are constant state space matrices. x is state vector, y the output, u the input/control variable.

基于一个简单的自行车模型,状态函数可以写成

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

Vy,dot_Vy 用于横向控制,psi,dot_psi 用于转向控制,Vx,dot_Vx 用于纵向控制。详细信息可从 Matlab 文档页面找到。

Matlab 中有一个关于 MPC 的简短的网络研讨会,可以帮助理解背后的算法。MPC 的主要思想是对未来的工厂输出进行预测,优化器找到最优的控制输入序列,使工厂输出尽可能接近设定值。

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

例如,下图显示了在十字路口转弯的典型场景。MPC 将考虑道路图的曲率,并最小化道路图和工厂路径之间的误差。MPC 的主要优点之一是具有硬/软约束能力的多输入和多输出,这使得它非常适合于 ADAS 函数中的控制策略。

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

既然我们已经从对象检测技术和 MPC 策略中获得了输入,那么我们可以开始使用 Matlab/Simulink 工具箱来构建玩具模型。

关于前面提到的 MPC,重要的一点是它只对慢动作 senario 有效。当处理高速情况时,必须使用离散 MPC 技术。

自适应巡航控制系统

此处显示的示例演示了这样一个场景:自我车前面的一辆车从右侧切入自我车的车道。雷达和摄像头传感器检测并确认前车。出于安全原因,自车必须估计与前车的相对距离,如果该距离小于允许距离,则自车必须刹车并保持安全距离,直到完全停止。直到/当前面的车远离时,然后自我车逐渐加速,直到达到期望的速度。

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

ACC with sensor fusion function

在该测试台中,ACC 传感器融合模块具有这样的功能:检测在同一车道(以及在传感器检测范围内的其他车道)是否有领先车,融合检测结果(去除冗余),将检测结果传递给 MPCMPC 相应地减慢/加速 ego 汽车。

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

输入参数是视觉和雷达探测目标、模拟时间、自车的纵向速度和道路曲率。传感器融合和跟踪引导车子模块包含由于来自雷达的噪声而导致的第一次雷达检测聚类,然后将来自视觉和雷达的检测组合起来传递给多目标跟踪器。使用卡尔曼滤波器精确估计检测状态,并融合检测。然后,使用确认的轨迹和道路信息来确定本车和引导车之间的相对距离和相对速度,这将用于 ACC。

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

连同相对距离和相对速度,time_gap(驾驶员的反应时间?)使用 MPC 方案将纵向速度和驾驶员设定速度馈入自适应巡航控制系统。在该测试台中,使用了预建的 ACC 控制模块。也有可能建立用户特定的 MPC 模块,这里有一个教程如何这样做。该 ACC 模块的主要功能是跟踪驾驶员设定的速度,并通过调整本车的纵向加速度来保持与前方车辆的安全距离。该模块使用模型预测控制(MPC)计算最佳控制动作,同时满足安全距离、速度和加速度约束。算法结构的细节如下所示。然后,用户可以相应地从 Matlab 修改原始 ACC 模块。

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

Adaptive Cruise Control using Model Predictive Control

到目前为止,主要的 ACC 控制已经基本完成。然而,当在道路上驾驶时,驾驶员也必须始终保持在车道上。因此,车道跟踪功能,换句话说,转向控制也必须考虑。道路(地图)信息必须与 MPC 调节的纵向加速度一起输入车辆和环境 Simulink 模块。在当前的测试案例中,道路几何形状通过恒定曲率 1/R 进行简单描述,并且已经在 Matlab 的工作空间中创建,可以从子系统中直接使用。

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

Using the MPC regulated longitudinal acceleration and curvature of the road to update the position and yaw angle of the ego car. The steering control is achieved via PID control.

与 MPC 调节的 ego 汽车加速度一起,通过比例-积分-微分 (PID)控制方案实现转向控制。

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

基于带力输入的自行车模型,对自主车的位置和横摆角进行了仿真。

到目前为止,我们已经具备了运行 ACC 模拟所需的所有要素。单击 run 按钮,可以从鸟瞰范围查看结果,如下所示,仅显示一帧。

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

整个模拟结果看起来像

从视频中我们可以看到,当一辆速度较低的汽车切入速度较快的自我车的车道时,只要传感器检测到这种领先的汽车,在 MPC 控制的帮助下,自我车首先减速以保持安全距离。当前车离开同一车道时,本车再次加速,直到达到驾驶员设定的速度。自我车辆的速度和驾驶员设定速度如下图所示。还示出了自我车辆的相对距离和加速度曲线。

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

最后但同样重要的是,这种 ADAS 必须用 C 或 C++部署到特定的 ECU 上,Matlab 提供了代码生成器工具箱来轻松完成这一任务。如果需要添加或修改更多的 C 算法,那么可以基于生成的 C/C++代码继续工作。

到目前为止,我已经回顾了 Matlab/Simulink 实现的 ACC 测试 bensch。可以正确地恢复主要功能。对于更复杂或不同的驾驶场景,用户可以使用这里描述的类似时间表进行进一步的功能开发。

使用 Google Dialogflow 和 Vision API 为您的聊天机器人添加图像识别功能

原文:https://towardsdatascience.com/add-image-recognition-to-your-chatbot-with-google-dialogflow-and-vision-api-fd45cd0bdd45?source=collection_archive---------7-----------------------

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

对话式人工智能的使用案例多种多样。它们包括客户支持、电子商务、控制物联网设备、企业生产力等等。用非常简单的术语来说,这些用例涉及用户问一个特定的问题(意图),以及对话体验(或聊天机器人)通过调用后端系统(如 CRM、数据库或 API)来响应该问题。这些“意图”通过利用自然语言处理(NLP)和机器学习(ML)来识别。

事实证明,这些用例中的一些可以通过允许用户上传图像来丰富。在这种情况下,您会希望对话体验基于该图像中的确切内容采取行动。

让我们想象一个电子商务客户支持示例:如果您提供自动退款,那么您会要求用户上传收据的图像,将图像发送到预先训练的 ML 模型,从图像中提取文本,从文本中识别购买日期,查看它是否符合退款窗口,然后处理退款或拒绝退款。

让我们想象另一个支持示例:您的硬件产品要求客户遵循一些设置步骤,如果他们遇到问题,他们会求助于聊天机器人,聊天机器人会要求他们上传设备的图像,图像会被发送到预先训练的 ML 模型,该模型会识别问题可能是什么,并通过聊天机器人将其反馈给用户。

介绍

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

The chat experience that you will build as a part of this tutorial

在本教程中,您将学习如何将 Dialogflow 与 Vision API 集成在一起,以便对用户提供的图像输入做出丰富的、动态的基于 ML 的响应。您将创建一个简单的聊天机器人应用程序,该应用程序将图像作为输入,在 Vision API 中对其进行处理,并将识别出的地标返回给用户。见下图。

  • 您将创建一个 Dialogflow 代理
  • 实现一个 django 前端来上传文件
  • 实现 Dialogflow fulfillment 以针对上传的图像调用 vision API。就像下图一样。

这里的是解释接下来步骤的视频。

架构概述

我们正在创建一个自定义 Django 前端的对话体验,并将其与 Vision API 集成。我们将使用 Django-framework 构建前端,在本地运行并测试它,然后在 Google App Engine 上部署它。前端将如下所示:

请求流将是:

  1. 用户将通过这个前端发送一个请求。
  2. 这将触发对 Dialogflow DetectIntent API 的调用,以将用户的话语映射到正确的意图。
  3. 一旦检测到“探索地标”意图,Dialogflow fulfillment 将向 Vision API 发送请求,接收返回的响应并将其发送回用户。

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

整体架构:

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

Architectural Overview

什么是谷歌云视觉 API?

谷歌云视觉 API 是一个预先训练好的机器学习模型,有助于从图像中获得洞察力。您可以获得包括图像标记、人脸和地标检测、光学字符识别(OCR)和明确内容标记在内的洞察。此处是链接,以更具体地了解 Vision API。

创建对话流代理

  1. 转到对话流控制台
  2. 登录,如果你是第一次使用,然后使用您的电子邮件注册
  3. 接受条款和条件,您将进入控制台
  4. 创建一个**代理。要创建,**单击左侧窗格中的下拉菜单,以查看“创建新代理
  5. 称之为“VisionAPI”
  6. Dialogflow 为你创建了一个 Google Cloudproject 来访问日志,云功能等。您也可以选择一个现有的项目。
  7. 准备好后,点击创建
  8. 作为代理的一部分,Dialogflow 创建了两个默认意图。默认欢迎意图有助于问候您的用户。默认的回退意图有助于捕捉机器人不理解的所有问题。

在这一点上,我们有一个向用户问候的功能性机器人。但是我们需要稍微更新一下,让用户知道他们可以上传一张图片来探索地标。

更新默认欢迎意向以通知用户上传图像

  1. 点击“默认欢迎意向”
  2. 将“回复”更新为“嗨!可以上传一张图探索地标。”

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

创建实体

  1. 点击“实体”
  2. 创建一个新实体,命名为“文件名”和“保存”。

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

创建新意图

  • 点击“意图”
  • 将其命名为“探索上传的图像”
  • 点击“训练短语”,添加“文件是 demo.jpg”和“文件是 taj.jpeg”,以@filename 作为实体。

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

  • 点击“回复”并添加“评估文件”作为文本回复
  • 点击“履行”并切换“为此目的启用 webhook 调用”

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

设置实施以与 Vision API 集成

  • 导航到对话流代理“VisionAPI”并单击“实现
  • 通过切换开关启用内联代码编辑器。
  • 用下面的代码更新 index.js 文件,并用您的存储桶的名称更新您的-BUCKET-NAME。
  • 单击 package.json 并粘贴以下内容以替换其内容。
  • 点击页面底部的部署

下载并运行前端应用程序

设置您的本地环境

部署时,您的应用程序使用内置于应用程序引擎环境中的云 SQL 代理与您的云 SQL 实例进行通信。但是,要在本地测试您的应用程序,您必须在您的开发环境中安装并使用云 SQL 代理的本地副本。点击了解更多关于云 SQL 代理的信息。要在云 SQL 实例上执行基本的管理任务,可以使用 MySQL 客户端。

**注意:**您必须认证 gcloud 才能使用代理从本地机器连接

安装云 SQL 代理

下载并安装云 SQL 代理。云 SQL 代理用于在本地运行时连接到您的云 SQL 实例。

下载代理服务器:

curl -o cloud_sql_proxy [https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64](https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64)

使代理可执行:

chmod +x cloud_sql_proxy

创建云 SQL 实例

  • 为 MySQL 二代实例创建一个云 SQL。命名实例*“民意测验实例”*或类似。实例准备就绪可能需要几分钟时间。实例准备好后,它应该在实例列表中可见。请确保创建第二代实例。
  • 现在使用 Cloud SDK 运行以下命令,其中[YOUR_INSTANCE_NAME]表示您的云 SQL 实例的名称。记下为 connectionName 显示的值,以供下一步使用。connectionName 值的格式为**【项目名称】:【区域名称】:【实例名称】**
gcloud sql instances describe [YOUR_INSTANCE_NAME]
  • 或者,您可以通过单击实例从控制台获得连接名称

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

初始化您的云 SQL 实例

  • 使用上一步中的 connectionName 启动云 SQL 代理。
./cloud_sql_proxy -instances=”[YOUR_INSTANCE_CONNECTION_NAME]”=tcp:3306
  • 将[您的实例连接名称]替换为您在上一步中记录的连接名称的值。
  • 这一步建立了从本地计算机到云 SQL 实例的连接,用于本地测试。在本地测试应用的整个过程中,保持云 SQL 代理运行。

接下来,创建一个新的云 SQL 用户和数据库。

  • 使用 Google CloudConsole 为您的云 SQL 实例 polls-instance 创建一个新数据库。例如,您可以使用名称民意测验。

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

  • 使用 Google CloudConsole 为您的云 SQL 实例 polls-instance 创建一个新用户。

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

配置数据库设置

  • 打开 mysite/settings-changeme.py 进行编辑。
  • 将该文件重命名为 setting.py
  • 在两个地方,将[您的用户名]和[您的密码]替换为您之前在步骤“创建云 SQL 实例”中创建的数据库用户名和密码。这有助于为 App Engine 部署和本地测试建立到数据库的连接。
  • 在“HOST”行中,“cloud SQL/[项目名称]:[区域名称]:[实例名称]”用您在上一步中获取的实例名称替换[项目名称]:[区域名称]:[实例名称]。
  • 运行以下命令。为下一步复制输出的 connectionName 值。
gcloud sql instances describe [YOUR_INSTANCE_NAME]
  • 将[您的连接名称]替换为上一步中的连接名称
  • 用您在“初始化您的云 SQL 实例”步骤中选择的名称替换[您的数据库],然后关闭并保存 settings.py
# [START db_setup]if os.getenv(‘GAE_APPLICATION’, None):# Running on production App Engine, so connect to Google Cloud SQL using# the unix socket at /cloudsql/<your-cloudsql-connection string>DATABASES = {‘default’: {‘ENGINE’: ‘django.db.backends.mysql’,‘HOST’: ‘/cloudsql/[PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME]’,‘USER’: ‘[YOUR-USERNAME]’,‘PASSWORD’: ‘[YOUR-PASSWORD]’,‘NAME’: ‘[YOUR-DATABASE]’,}}else:# Running locally so connect to either a local MySQL instance or connect to# Cloud SQL via the proxy. To start the proxy via command line:# $ cloud_sql_proxy -instances=[INSTANCE_CONNECTION_NAME]=tcp:3306# See [https://cloud.google.com/sql/docs/mysql-connect-proxy](https://cloud.google.com/sql/docs/mysql-connect-proxy)DATABASES = {‘default’: {‘ENGINE’: ‘django.db.backends.mysql’,‘HOST’: ‘127.0.0.1’,‘PORT’: ‘3306’,‘NAME’: ‘[YOUR-DATABASE]’,‘USER’: ‘[YOUR-USERNAME]’,‘PASSWORD’: ‘[YOUR-PASSWORD]’}}# [END db_setup]

设置服务帐户

  • 在 Dialogflow 的控制台中,进入设置⚙,在常规选项卡下,你会看到谷歌项目部分。单击服务帐户。这将打开谷歌云控制台。

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

  • 在 Google Cloudconsole 中,呈现的网页会显示 Dialogflow 服务账号。点击最右边的“动作部分的 3 个点,然后点击“创建键

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

  • 一个 JSON 文件将被下载到您的计算机上,您将需要在下面的设置部分。

设置要从应用程序调用的 Dialogflow DetectIntent 端点

  • 在聊天文件夹内,用自己的凭证 json 文件替换 key-sample.json ,并将其命名为 key.json
  • 在聊天文件夹的 views.py 中,将 GOOGLE_PROJECT_ID = " <your_project_id>"更改为您的项目 ID</your_project_id>

创建 GCS 存储桶

为前端静态对象创建 GCS 存储桶

  • 导航到 Google CloudProject,从汉堡菜单中点击存储

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

  • 点击“创建新存储桶”
  • 提供名称—这必须是一个全局唯一的名称

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

  • 选择存储数据的位置—选择“区域”并选择最适合您需求的位置。
  • 选择数据的默认存储类别为“标准”

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

  • 选择如何控制对对象的访问,如“在存储桶级别统一设置权限”,然后继续创建存储桶。

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

  • 一旦创建了 bucket,单击“Browser”并找到您刚刚创建的 bucket。
  • 单击右侧对应于存储桶的三个点,然后单击“编辑存储桶权限”

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

  • 在显示的侧面板中,单击“添加成员”,然后添加新成员“ allUsers ”,然后单击“选择角色”,添加“存储对象查看器”角色。我们这样做是为了向所有用户提供对静态前端文件的查看访问。对于文件来说,这不是理想的安全设置,但对于这个特定的实验来说,这是可行的。

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

为用户上传的图像创建 GCS 存储桶

按照相同的说明,创建一个单独的存储桶来上传用户图像。

将权限设置为“所有用户”,并将角色设置为“存储对象创建者”和“存储对象查看者”

在前端应用程序中配置 GCS 存储桶

在 settings.py 中配置 GCS 存储桶

  • 打开 mysite/setting.py
  • 找到 GCS_BUCKET 变量,并用您的 GCS 静态 BUCKET 替换""
  • 找到 GS_MEDIA_BUCKET_NAME 变量,并用图像的 GCS 存储桶名称替换“”。
  • 找到 GS_STATIC_BUCKET_NAME 变量,并用静态文件的 GCS 存储桶名称替换“”。
  • 保存文件。
GCS_BUCKET = ‘<YOUR-GCS-BUCKET-NAME>’GS_MEDIA_BUCKET_NAME = ‘<YOUR-GCS-BUCKET-NAME-MEDIA>’GS_STATIC_BUCKET_NAME = ‘<YOUR-GCS-BUCKET-NAME-STATIC>’

在 home.html 配置 GCS 存储桶

  • 打开聊天->模板-> home-changeme.html
  • 将其重命名为 home.html
  • 查找,并将其替换为您希望保存用户上传文件的位置的 bucket 名称。我们这样做是为了不将用户上传的文件存储在前端,并将静态资产全部保存在 GCS bucket 中。Vision API 调用 GCS bucket 来获取文件并进行预测。

在本地构建并运行应用程序

  • 要在本地计算机上运行 Django 应用程序,您需要设置一个 Python 开发环境,包括 Python、pip 和 virtualenv。有关说明,请参见为谷歌云平台设置 Python 开发环境。
  • 创建一个独立的 Python 环境,并安装依赖项:
virtualenv envsource env/bin/activatepip install -r requirements.txt
  • 运行 Django 迁移来设置您的模型:
python3 manage.py makemigrationspython3 manage.py makemigrations pollspython3 manage.py migrate
  • 启动本地 web 服务器:
python3 manage.py runserver
  • 在你的网络浏览器中,输入这个地址 http://localhost:8000/ 你应该会看到一个简单的网页,上面有文本:“Dialogflow”文本框和提交按钮。

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

示例应用程序页面由运行在您计算机上的 Django web 服务器提供。当您准备好继续前进时,按 Ctrl+C 停止本地 web 服务器。

将应用部署到应用引擎标准环境

将所有静态内容收集到一个文件夹中。该命令将应用程序的所有静态文件移动到 settings.py 中 STATIC_ROOT 指定的文件夹中:

python3 manage.py collectstatic

通过在 app.yaml 文件所在的应用程序目录中运行以下命令来上传应用程序:

gcloud app deploy

等待通知您更新已完成的消息。

测试在云中运行的前端应用程序

在您的 web 浏览器中,输入以下地址:

https://<your_project_id>.appspot.com

这一次,您的请求由运行在 App Engine 标准环境中的 web 服务器提供服务。

该命令按照 app.yaml 中的描述部署应用程序,并将新部署的版本设置为默认版本,使其为所有新流量提供服务。

生产

当您准备好在生产中提供内容时,在 mysite/settings.py 中,将 DEBUG 变量更改为 False。

测试你的聊天机器人!

让我们用下面的提示来测试我们的聊天机器人

  1. 用户:“嗨”
  2. 聊天机器人回应:“嗨!可以上传一张图探索地标。”
  3. 用户:上传图像。
  4. 下载一张带有地标的图片,命名为“demo.jpg”
  5. 聊天机器人回应:“文件正在处理中,这里是结果:XXXX ”
  6. 总体来说,应该是这样的。

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

清除

确保删除 Google Cloud 项目和 Dialogflow 代理,以避免产生任何费用。

资源和后续步骤

查看我的视频系列 解构聊天机器人 ,在这里我分享如何开始使用 Dialogflow 和谷歌云工具建立对话体验。

参考

Appengine 上的 DialogflowDjango apphttps://github.com/vkosuri/django-dialogflow

添加这个单词,让你的熊猫申请更快

原文:https://towardsdatascience.com/add-this-single-word-to-make-your-pandas-apply-faster-90ee2fffe9e8?source=collection_archive---------1-----------------------

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

Image by Karolina Grabowska from Pixabay

易于实现并行化

作为数据科学家,我们有四核、八核和睿频加速的笔记本电脑。我们使用具有更多内核和计算能力的服务器。

但是我们真的利用了我们手头的原始力量吗?

有时,我们会受到我们所掌握的工具的限制。有时我们不愿意为了节省几分钟时间而编写所有无关的代码。后来才意识到时间优化从长远来看是有帮助的。

那么,我们能做得更好吗?

是的,很明显。

以前,我曾经写过如何让你的apply函数更快——使用多重处理,但是由于有了 swifter 库,它现在变得更加琐碎。

这篇文章是关于使用我们手头的计算能力,并使用 Swifter 将其应用于熊猫数据帧。

问题陈述

我们有一个巨大的熊猫数据框,我们想对它应用一个复杂的函数,这需要很多时间。

对于这篇文章,我将生成一些 25M 行 4 列的数据。

可以轻松使用并行化来获得额外的代码性能吗?

import pandas as pd
import numpy as nppdf = pd.DataFrame(np.random.randint(0,100,size=(25000000, 4)),columns=list('abcd'))

数据看起来像:

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

Data Sample

仅使用一项变更的并行化

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

Relax and Parallelize !!!

让我们做一个简单的实验。

我们将尝试在数据框架中创建一个新列。我们可以简单地通过在熊猫身上使用 apply-lambda 来做到这一点。

def func(a,b):
    if a>50:
        return True
    elif b>75:
        return True
    else:
        return Falsepdf['e'] = pdf.apply(lambda x : func(x['a'],x['b']),axis=1)

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

上面的代码运行大约需要 10 分钟。这里我们只是对两列进行简单的计算。

我们能做得更好吗?需要什么?

是的,我们可以做得更好,只要加上一个“神奇的词”——更快。

但是首先,您需要安装 swifter,这很简单:

conda install -c conda-forge swifter

然后,您可以在apply之前导入并附加 swifter 关键字来使用它。

import swifter
pdf['e'] = pdf.**swifter**.apply(lambda x : func(x['a'],x['b']),axis=1)

那么,这行得通吗?

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

是的。确实如此。与直接使用该函数相比,我们的运行时间提高了 2 倍。

那么这里到底发生了什么?

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

Source: How increasing data size effects performances for Dask, Pandas and Swifter?

Swifter 为您的函数选择实现 ***apply*** 的最佳方式,方法是对您的函数进行矢量化,或者在后端使用 Dask 来并行化您的函数,或者在数据集很小的情况下使用简单的 pandas apply。

在这个特例中,Swifter 使用 Dask 来并行化我们的应用函数,默认值为npartitions = cpu_count()*2

对于 MacBook,我使用的 CPU 数量是 6,超线程是 2。因此,CPU 计数为 12,这使得 npartitions=24。

我们也可以选择自己设置 n_partitions。虽然我观察到缺省值在大多数情况下工作得很好,但有时你也可以调整它来获得额外的加速。

例如:下面我设置 n_partitions=12,我们再次获得了 2 倍的加速。这里,减少我们的分区数量会缩短运行时间,因为分区之间的数据移动成本很高。

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

结论

并行化不是银弹;这是铅弹。

并行化不会解决您的所有问题,您仍然需要优化您的函数,但是它是您的武器库中的一个很好的工具。

时间一去不复返,有时我们也缺少时间。在这些时候,我们需要用一个词来处理并行化。

而那个字就是 更快

继续学习

另外,如果你想了解更多关于 Python 的知识,我想向密歇根大学推荐一门优秀的中级 Python 课程。一定要去看看。

将来我也会写更多初学者友好的帖子。在 媒体 关注我或者订阅我的 博客 了解他们。一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter @mlwhiz 联系到我。

此外,一个小小的免责声明——这篇文章中可能会有一些相关资源的附属链接,因为分享知识从来都不是一个坏主意。

将人工智能添加到您的组织中:从神话到现实

原文:https://towardsdatascience.com/adding-ai-to-your-organization-from-myths-to-reality-personal-page-of-massimiliano-versace-e86c9071ac80?source=collection_archive---------15-----------------------

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

在创新方面,没有企业想成为恐龙,而今天,人工智能处于前沿。据估计,80%的企业已经在以某种形式使用人工智能,向人工智能的过渡似乎和从打字机向个人电脑的过渡一样普遍。

尽管大肆宣传,但企业“感觉到”挑战:在最近的一项研究中,91%的公司预见到人工智能采用的重大障碍,包括缺乏 IT 基础设施,以及缺乏人工智能专家来指导过渡。

尽管如此,很少有组织真正理解摆在他们面前的是什么,以及真正需要做些什么来过渡到人工智能侏罗纪时代。让我们更仔细地看看人工智能采用的潜在现实,你的内部人工智能小组或顾问永远不会告诉你。

用例:将传统企业转变为人工智能支持的组织

为了描绘一幅图画,让我们考虑一个假设的公司,全球重工业公司(GHIC)。也许他们的目标是通过在全公司范围内部署人工智能来降低成本,提高生产设施的质量。

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

该公司制造工业机械,需要熟练工人从零件组装复杂的机械,并有一系列控制检查点来保持生产质量。目前,该过程完全是手动的。

随着最近人工智能意识的提高,加上来自低成本制造商的竞争压力,GHIC 已经制定了一个积极的路线图,通过利用现有的安全摄像头基础设施,在工厂中引入基于视觉的人工智能。

第一步?为他们的模型收集相关数据。

误解 1:我的人工智能需要的所有数据都是免费的

GHIC 面临的第一个障碍是为他们的视觉人工智能收集和准备数据。数据是人工智能的 DNA:神经网络和深度学习架构依赖于导出一个函数来将输入数据映射到输出数据。

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

这种映射功能的有效性取决于所提供数据的质量数量。一般来说,拥有更大的训练集已被证明能够在网络中实现更有效的特征,从而导致更好的性能。简而言之,大量高质量的数据导致更好的 AI。

但是公司如何着手生产和准备这些数据呢?收集和标注(或注释)通常是数据准备中最耗时、最昂贵的步骤。此过程使系统能够识别数据中感兴趣的类别或对象,并定义算法部署后应预测的适当结果。

出于隐私或质量方面的考虑,内部注释通常是企业的唯一选择。这可能是因为数据不能离开工厂,或者需要专家进行极其精确的标记。

GHIC 认识到,在相关环境中现场收集和标记数据是建立原型和工作系统的第一个必要步骤。需要收集和标记数百小时的视频,以及数以千计包含健康/缺陷零件的图像,质量控制专家知道生产质量的正常变化和问题之间的区别。因此,处理数据成为一项挑战。应对这一挑战的一种方法是让 GHIC 的人工智能能够持续学习,大幅减少所需的数据和训练时间,并实现人工智能的实时学习和改进。

误区 2:我可以轻松雇佣人工智能专家来构建内部人工智能解决方案

一旦数据准备就绪,第二个任务就是构建 AI 系统的初始实现。这是 GHIC 面临的下一系列挑战。虽然有太多的人工智能工具供开发人员使用,但人工智能专业知识很难找到。据估计,全球大约只有 30 万名人工智能专家(2.2 万名博士)。

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

毫无疑问,对人工智能人才的需求超过了需求。虽然加速人工智能培训的选择不可行——仍然需要四年才能获得博士学位——但唯一可行的选择是降低门槛,通过引入软件框架来回避对该领域深入知识的需求。否则,组织可能要永远等待才能找到足够的人工智能人才。

误解 3:我有一个概念验证,构建一个最终的人工智能解决方案只是“多做一点工作”

如果 GHIC 开始寻找内部/外部人工智能资源来实现概念验证(PoC),他们可能会认为他们离部署最终解决方案只有几步之遥。

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

事实上,人工智能的采用需要一个多步骤的方法。对于许多组织来说,第一步是 PoC。在 AI 工作多年后,我看到了无数的 POC 没有实现。为了避免浪费时间和金钱,组织需要设定一个时间表,并提前定义标准,以决定该技术是否应该投入生产。一个简单的基准,如“如果 PoC 提供 X at Y 功能,那么我们将在这里和这里推出它”将大大有助于企业定义一个实际的部署场景。

误解 4:当我从我的人工智能获得良好的性能时,我不再需要接触它

让我们假设 GHIC 克服了上述所有障碍,并成功实现了人工智能。随着时间的推移,GHIC 将面临不断出现的用例或不断变化的条件的挑战,以及及时和廉价地调整其人工智能的需求。

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

成功的组织放眼未来,询问他们的人工智能解决方案如何随着时间的推移而扩展。随着人工智能系统变得更加复杂,需要数据存储/管理、再培训成本/时间和整体人工智能生命周期管理工具来确保人工智能项目不会变得一团糟,或者更糟,无效。

超越人工智能神话:人工智能不是一次性的,它将一直存在

GHIC 已经艰难地认识到人工智能不是一个简单的一次性项目。相反,这可能会变成一场漫长而昂贵的努力。

为了有效地实施人工智能,企业需要开发混合工程、R&D 和产品的内部团队,这些团队在构建、测试和交付应用程序方面密切合作,并在未来监督维护和迭代。

新工具使越来越多的组织能够采用人工智能。通过夺回对其人工智能战略的控制权,企业团队将能够快速构建人工智能解决方案,在人工智能生命周期中部署和发展它们。

Max Versace 是 Neurala 的首席执行官兼联合创始人。

为多类文本分类模型增加可解释性

原文:https://towardsdatascience.com/adding-interpretability-to-multiclass-text-classification-models-c44864e8a13b?source=collection_archive---------9-----------------------

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

ELI5: Image by Sasin Tipchai from Pixabay

ELI5:增加可解释性,但不损失准确性

像我 5 岁一样解释。

对我来说,这是学习的基本原则之一,我试图以一种更容易接受的形式提炼任何概念。正如费曼所说:

我做不到。我不能把它降低到大一的水平。这意味着我们并没有真正理解它。

所以,当我看到旨在解释机器学习模型的 ELI5 库时,我只是必须尝试一下。

在向企业解释我们复杂的机器学习分类器时,我们面临的一个基本问题是*。*

有时候利益相关者想要理解——是什么导致了特定的结果? 可能是因为手头的任务非常关键,我们不能做出错误的决定。 想象一个基于用户评论采取自动货币行为的分类器。

也可能是对业务/问题空间了解多一点。

也可能是为了增加你的模型的 社会接受度

这个帖子是关于解读复杂文本分类模型的。

数据集:

为了解释 ELI5 如何工作,我将使用 Kaggle 上的堆栈溢出数据集。这个数据集包含大约 40000 个帖子和相应的帖子标签。

这是数据集的外观:

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

下面是不同类别的分布情况。

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

这是一个平衡的数据集,因此非常适合我们理解的目的。

让我们开始吧。你可以跟随这个 Kaggle 内核中的代码

凝视简单:

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

Interpretable ML Book

让我们首先尝试使用一个简单的 scikit-learn 管道来构建我们的文本分类器,稍后我们将尝试解释它。 在这个管道中,我将使用一个非常简单的计数矢量器和逻辑回归。

*from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.linear_model import LogisticRegressionCV
from sklearn.pipeline import make_pipeline# Creating train-test Split
X = sodata[['post']]
y = sodata[['tags']]X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)# fitting the classifier
vec = CountVectorizer()
clf = LogisticRegressionCV()
pipe = make_pipeline(vec, clf)
pipe.fit(X_train.post, y_train.tags)*

让我们看看我们得到的结果:

*from sklearn import metricsdef print_report(pipe):
    y_actuals = y_test['tags']
    y_preds = pipe.predict(X_test['post'])
    report = metrics.classification_report(y_actuals, y_preds)
    print(report)
    print("accuracy: {:0.3f}".format(metrics.accuracy_score(y_actuals, y_preds)))print_report(pipe)*

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

上面是一个非常简单的逻辑回归模型,它表现很好。 我们可以使用下面的函数来检查它的权重:

*for i, tag in enumerate(clf.classes_):
    coefficients = clf.coef_[i]
    weights = list(zip(vec.get_feature_names(),coefficients))
    print('Tag:',tag)
    print('Most Positive Coefficients:')
    print(sorted(weights,key=lambda x: -x[1])[:10])
    print('Most Negative Coefficients:')
    print(sorted(weights,key=lambda x: x[1])[:10])
    print("--------------------------------------")------------------------------------------------------------
OUTPUT:
------------------------------------------------------------Tag: python
Most Positive Coefficients:
[('python', 6.314761719932758), ('def', 2.288467823831321), ('import', 1.4032539284357077), ('dict', 1.1915110448370732), ('ordered', 1.1558015932799253), ('print', 1.1219958415166653), ('tuples', 1.053837204818975), ('elif', 0.9642251085198578), ('typeerror', 0.9595246314353266), ('tuple', 0.881802590839166)]
Most Negative Coefficients:
[('java', -1.8496383139251245), ('php', -1.4335540858871623), ('javascript', -1.3374796382615586), ('net', -1.2542682749949605), ('printf', -1.2014123042575882), ('objective', -1.1635960146614717), ('void', -1.1433460304246827), ('var', -1.059642972412936), ('end', -1.0498078813349798), ('public', -1.0134828865993966)]
--------------------------------------
Tag: ruby-on-rails
Most Positive Coefficients:
[('rails', 6.364037640161158), ('ror', 1.804826792986176), ('activerecord', 1.6892552000017307), ('ruby', 1.41428459023012), ('erb', 1.3927336940889532), ('end', 1.3650227017877463), ('rb', 1.2280121863441906), ('gem', 1.1988196865523322), ('render', 1.1035255831838242), ('model', 1.0813278895692746)]
Most Negative Coefficients:
[('net', -1.5818801311532575), ('php', -1.3483618692617583), ('python', -1.201167422237274), ('mysql', -1.187479885113293), ('objective', -1.1727511956332588), ('sql', -1.1418573958542007), ('messageform', -1.0551060751109618), ('asp', -1.0342831159678236), ('ios', -1.0319120624686084), ('iphone', -0.9400116321217807)]
--------------------------------------
.......*

这一切都很好。我们可以看到这些系数是有意义的,我们可以尝试使用这些信息来改进我们的模型。

但是上面有很多代码。 ELI5 让这个练习对我们来说相当简单 。我们只需使用下面的命令:

*import eli5
eli5.show_weights(clf, vec=vec, top=20)*

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

现在你可以看到 Python 的权重值与我们从手动编写的函数中得到的值相同。探索它会更加美丽和有益健康。

但这只是冰山一角。正如我们在下面看到的,ELI5 还可以帮助我们调试模型。

理解我们的简单文本分类模型

现在让我们试着找出为什么一个特殊的例子被错误分类。我使用的例子最初来自 Python 类,但被错误地归类为 Java:

*y_preds = pipe.predict(sodata['post'])sodata['predicted_label'] = y_predsmisclassified_examples = sodata[(sodata['tags']!=sodata['predicted_label'])&(sodata['tags']=='python')&(sodata['predicted_label']=='java')]***eli5.show_prediction(clf, misclassified_examples['post'].values[1], vec=vec)****

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

在上面的例子中,分类器以低概率预测 Java。我们可以检查上面例子中发生的许多事情来改进我们的模型。例如:

  1. 我们看到分类器考虑了很多数字(不好),这让我们得出清理数字的结论。或者用日期时间标记替换日期时间对象。
  2. 还可以看到,虽然 dictionary 对 Java 的权重为负,但单词dictionaries的权重为正。所以也许词干也有帮助。
  3. 我们还看到像<pre><code>这样的词正在影响我们的分类器。清洗的时候要把这些字去掉。
  4. 为什么date这个词会影响结果?一些值得思考的事情。

我们可以看看更多的例子来获得更多这样的想法。你知道要点了。

深入而复杂

这一切都很好,但是如果我们使用的模型不能像 LSTM 那样提供个体特征的权重呢?正是有了这些模型,可解释性才能发挥非常重要的作用。

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

为了理解如何做到这一点,我们首先在我们的数据上创建一个 TextCNN 模型。为了节省空间,没有显示模型创建过程,而是将其视为一系列预处理步骤,然后创建深度学习模型。如果有兴趣,你可以看看这个 Kaggle 内核中的建模步骤。

当我们有一个经过训练的黑盒模型对象时,从我们的角度来看,事情变得有趣了。

ELI5 为我们提供了eli5.lime.TextExplainer来调试我们的预测——检查文档中什么是重要的,以做出预测决策。

为了使用[**TextExplainer**](https://eli5.readthedocs.io/en/latest/autodocs/lime.html#eli5.lime.lime.TextExplainer)实例,我们向[**fit()**](https://eli5.readthedocs.io/en/latest/autodocs/lime.html#eli5.lime.lime.TextExplainer.fit)方法传递一个要解释的文档和一个黑盒分类器(一个返回概率的predict函数)。从文档来看,我们的预测函数应该是这样的:

预测 ( 可调用 ) —黑盒分类流水线。***predict***应该是一个函数,它接受一个字符串(文档)列表,并返回一个带有概率值的形状矩阵***(n_samples, n_classes)***-每个文档一行,每个输出标签一列。

因此,要使用 ELI5,我们需要定义自己的函数,该函数将一系列字符串(文档)作为输入,并返回一个形状为***(n_samples, n_classes)*** 的矩阵。 你可以看到我们是如何先预处理再预测的。

*def predict_complex(docs):
    # preprocess the docs as required by our model
    val_X = tokenizer.texts_to_sequences(docs)
    val_X = pad_sequences(val_X, maxlen=maxlen)
    y_preds = model.predict([val_X], batch_size=1024, verbose=0)
    return y_preds*

下面给出了我们如何使用TextExplainer。在我们的简单分类器中使用与之前相同的错误分类示例。

*import eli5
**from eli5.lime import TextExplainer****te = TextExplainer(random_state=2019)**
te.fit(sodata['post'].values[0], predict_complex)
te.show_prediction(target_names=list(encoder.classes_))*

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

这次它不会被错误分类。你可以看到关键字dictlist的出现影响了我们的分类器的决定。一个人可以尝试看到更多的例子,以找到更多的见解。

那么这到底是怎么运作的呢?

[**TextExplainer**](https://eli5.readthedocs.io/en/latest/autodocs/lime.html#eli5.lime.lime.TextExplainer)通过删除一些单词生成大量与文档相似的文本,然后训练一个白盒分类器,预测黑盒分类器的输出,而不是真正的标签。我们看到的解释是针对这个白盒分类器的。

本质上,这有点类似于师生模型的提炼,我们使用一个简单的模型来预测一个复杂得多的教师模型的输出。

简而言之,它试图创建一个简单的模型来模拟一个复杂的模型,然后向我们展示更简单的模型权重。

结论

理解至关重要。能够解释我们的模型可以帮助我们更好地理解我们的模型,从而更好地解释它们。

ELI5 为我们提供了一个很好的方法来做到这一点。它适用于各种模型,这个库的文档是我见过的最好的文档之一。

此外,我喜欢 ELI5 库提供的修饰输出,它以简单快捷的方式解释我的模型。并调试它们。

要在你的模型中使用 ELI5,你可以跟随这个 Kaggle 内核中的代码

继续学习

如果你想学习更多关于 NLP 和如何创建文本分类模型的知识,我想调出 高级机器学习专业化 中的 自然语言处理 课程。一定要去看看。它讲述了许多从初学者到 NLP 高级水平的主题。你可能也想看看我在 NLP 学习系列的 NLP 上的一些帖子。

谢谢你的阅读。将来我也会写更多初学者友好的帖子。在 媒体 关注我或者订阅我的 博客 了解他们。一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter @mlwhiz 联系

此外,一个小小的免责声明——在这篇文章中可能会有一些相关资源的附属链接,因为分享知识从来都不是一个坏主意。

通过概率维度添加新特征

原文:https://towardsdatascience.com/adding-new-features-by-probability-dimension-bea2a4be45d5?source=collection_archive---------17-----------------------

简介:

特征工程是机器学习中的一个重要课题。如果我们想让我们的机器学习,我们需要给它有意义的信息。深度学习架构可能不需要创建良好的功能,因为它们实际上可以自己创建功能。但是,这将需要一个巨大的数据集,也需要大量的计算能力。

对于特征创建,我们需要了解机器学习将处理的主题。如果是信号处理,我们需要了解一下信号处理。如果是金融,我们需要了解一些金融知识,这样我们才会知道我们可以创造哪些特色。

方法:

另一种可以应用于大多数领域的特征是概率。一个值与其他现有值一起存在于一个示例中的概率可能是一个有意义的特征。

示例:假设我们有一个数字图像 0,如下所示。当其他值存在时,我们将创建每个值存在的概率。

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

Digit 0 Image

我们将创建每个值的概率,并通过增加矩阵的维数来映射它。(表示是用 Python 语言编写的)

  1. 展平图像。(2D 至 1D) (imgFlat)
  2. 创建一个具有维度(valueRange,len(imgFlat))的零值矩阵。值域就是我们后面要确定的范围。
  3. 将 imgFlat 值作为二进制矩阵映射到我们的零值矩阵(我们将在这里确定值的范围。假设我们的取值范围是 10。值范围是我们将映射图像值的范围。图像中的值将被映射到 0 到 10 之间的值。).我们的带有映射值的 imgFlat 是[ 0,3,10,7,2,0,0,6,8,5,8,1,1,7,2,1,7,1,1,5,1,7,1,0,6,3,5,6,0,3,9,7,1,0]。因此,让我们根据 imgFlat 值创建二元矩阵。

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

Binary Mapping

4.所以,我们拉平了我们的矩阵。然后,我们又增加了一个维度。在这个维度上,我们增加了概率。但是,我们还没有完成。根据我的启发式方法,最好将概率映射到接近概率 1 值的值。因此,我们将得到类似于[0 0.3 0.7 1 0.7 0.3]的值,而不是[0 0 0 1 0 0]。为此,我创建了一个新的概率分布函数。

概率分布函数:

假设我们需要一个有两个根的函数,这个函数的最大输出值是 1。

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

Probability Distribution Matrix

def distFunc(argmax,xrange,valRange):
    x = np.linspace(0,valRange,valRange+1)
    a = argmax
    b = xrange
    y = ((x**2)-(2*x*a)+(a**2)-(b**2))/(valRange**2)
    return 1-y
yHist = exposure.rescale_intensity(y)#reason of this line is to distribute our values even more. ([skimage.exposure.rescale_intensity function](https://scikit-image.org/docs/dev/api/skimage.exposure.html#skimage.exposure.rescale_intensity))

为了看清楚,我将数值四舍五入为十进制 1。正因为如此,一些值变成了 1。请忽略它。

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

Probability Distribution to Binary Mapping

6.概率分布之后,我们展平 2D 概率矩阵。它变得相当大。因此,我将在下面补充其中的一部分。

[1 0.9375 0 0 0.987654 1 1 0 0 0 0 1 1 0 0.987654 0.987654 0 0.987654 1 0 0.987654 0.987654 0 0.987654 1 0 0.816327 0 0 1 1 0.816327 0 0 1 …]

这个结果意味着什么?

毕竟,我们的矩阵代表了下面给出的陈述。

矩阵中第 0 列的值 0 以概率 1 存在,第 10 列的值 8 以概率 1 存在,而第 3 列的值 1 也以概率 0.3 存在,同时…

这给了我们一种情况,我们用它们存在的可能性来赋予我们的价值以意义。

基于 SVM 和概率维特征的数字分类;

图书馆:

import numpy as np
from skimage import exposure
from sklearn.datasets import load_digits
from sklearn import svm

概率分布函数:

def distFunc(argmax,xrange,valRange):
    x = np.linspace(0,valRange,valRange+1)
    a = argmax
    b = xrange
    y = ((x**2)-(2*x*a)+(a**2)-(b**2))/(valRange**2)
    return 1-y

概率维特征的创建:

def createProbOfVal(kernel,valRange):
    kernelFlat = kernel.flatten()
    kernelFlat = kernelFlat/np.max(kernelFlat)*valRange
    tempBefore = np.zeros((valRange+1,len(kernelFlat)))
    tempAfter = np.zeros((valRange+1,len(kernelFlat)))
    for cnt in range(len(kernelFlat)):
        y = distFunc(int(kernelFlat[cnt]),1,valRange)
        yhist = exposure.rescale_intensity(y)
        tempBefore[int(kernelFlat[cnt]),cnt] = 1
        tempAfter[:,cnt] = yhist
    tempBeforeFlat = tempBefore.flatten()
    tempAfterFlat = tempAfter.flatten()
    return tempAfterFlat

数据集准备(图像到概率维度特征):

def prepareDataset(datasetImages,datasetLabels):
    dataset = []
    for cnt in range(len(datasetImages)):
        processedImage = createProbOfVal(datasetImages[cnt],10)
        dataset.append([processedImage,datasetLabels[cnt]])
    return dataset

加载并准备数据集:

digits = load_digits()
dataset = prepareDataset(digits.images,digits.target)

创建分类器实例并训练它:

clf = svm.SVC(gamma='scale')
clf.fit([np.array(row[0]) for row in dataset[0:1500]],[np.array(row[1]) for row in dataset[0:1500]])

测试:

preds = clf.predict([np.array(row[0]) for row in dataset[1500:1796]])
score = clf.score([np.array(row[0]) for row in dataset[1500:1796]],[np.array(row[1]) for row in dataset[1500:1796]])

准确率:92%

向 Spark 数据帧添加顺序 id

原文:https://towardsdatascience.com/adding-sequential-ids-to-a-spark-dataframe-fa0df5566ff6?source=collection_archive---------1-----------------------

怎么做,这是个好主意吗?

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

Photo by Markus Spiske on Unsplash

TL;博士

向 Spark 数据帧添加连续的惟一 id 并不是很直接,尤其是考虑到它的分布式本质。您可以使用 zipWithIndex()或 row_number()来实现这一点(取决于数据的数量和种类),但是在每种情况下都有一个关于性能的问题。

这背后的想法

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

Typical usages for ids — besides the obvious: for identity purposes

来自传统的关系数据库,如 MySQL ,以及非分布式数据框架,如 Pandas ,人们可能习惯于使用 id(通常自动递增)进行标识,当然,也可以使用它们作为参考来对数据进行排序和约束。例如,按 id(通常是一个索引字段)降序排列数据,将首先给出最近的行,等等。

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

A representation of a Spark Dataframe — what the user sees and what it is like physically

根据需要,我们可能会发现在 spark 数据帧中拥有一个(独特的)类似 auto-increment-ids '的行为对我们有好处。当数据在一个表或数据帧中时(在一台机器上),添加 id 是非常直接的。但是,当您将数据分散到可能驻留在不同机器(如 Spark)上的分区中时,会发生什么呢?

(更多关于分区的信息,请点击)

在这篇文章中,我们将探索显而易见和不那么显而易见的选项,它们的作用,以及使用它们背后的陷阱。

注释

  • 请注意,本文假设您对 Spark 有一定的了解,尤其是对 PySpark 有一定的了解。如果没有,这里有一个简短介绍以及它是什么,我已经在有用链接和注释部分放了几个有用的资源。我很乐意回答任何我能回答的问题:)。
  • 再次练习速写,是的,整篇文章都有可怕的速写,试图直观地解释我所理解的事物*。希望它们更有帮助,而不是令人困惑:)。*

RDD 之路—ziptwithindex()

一种选择是退回到 RDDs

弹性分布式数据集 (RDD),它是跨集群节点划分的、可以并行操作的元素的集合

并使用df.rdd.zipWithIndex():

排序首先基于分区索引,然后是每个分区内项目的
排序。所以第一个分区中的第一个项目得到索引 0,最后一个分区中的最后一个项目得到最大的索引。

当这个 RDD 包含
多个分区时,这个方法需要触发一个火花作业。

An example using zipWithIndex

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

The process of using zipWithIndex()

这里有四点:

  • 索引将从 0 开始*,并且排序由分区**完成*
  • 您需要将所有数据保存在数据框中— **添加不会添加自动递增 id***
  • 退回到 rdds,然后退回到 dataframe 可能会相当昂贵
  • 带有 id 的数据帧的更新版本将要求您做一些额外的工作以将数据帧恢复到原始形式。这也增加了性能损失*。***

你不能真正地更新或添加一个数据帧,因为它们是不可变的,但是你可以把一个数据帧和另一个数据帧连接起来,最终得到一个比原始数据帧有更多行的数据帧。

数据框架方式

如果您的数据可排序

如果您可以按其中一列对数据进行排序,比如我们示例中的column1,那么您可以使用[row_number](https://spark.apache.org/docs/latest/api/python/pyspark.sql.html#pyspark.sql.functions.row_number)()函数来提供行号:

Resuming from the previous example — using row_number over sortable data to provide indexes

row_number()是一个窗口函数,这意味着它在预定义的窗口/数据组上运行。

这里的要点是:

  • 您的数据必须是可排序的****
  • 你需要使用一个非常大的窗口(和你的数据一样大)
  • 您的索引将从 1 开始
  • 您需要将所有数据保存在数据框中— 更新不会添加自动递增 id
  • 没有额外的工作来重新格式化你的数据帧
  • ****但是你可能会以一个 OOM 异常结束,我稍后会解释。

如果您的数据不可排序,或者您不想改变数据的当前顺序

另一种选择是将row_number()monotonically_increasing_id()结合,根据文档创建:

>生成单调递增的 64 位整数的列。

>生成的 ID 保证是****单调递增且唯一的,而不是连续的。当前的实现将分区 ID 放在高 31 位,将每个分区内的记录号放在低 33 位。假设数据帧有不到 10 亿个分区,每个分区有不到 80 亿条记录。****

单调递增且唯一,但不连续的是这里的关键。这意味着你可以按它们排序,但你不能相信它们是连续的。在某些情况下,你只需要排序,monotonically_increasing_id()就非常方便,你根本不需要row_number()。但是在这种情况下,假设我们绝对需要后续 id。

再次,从我们在代码中留下的地方继续:

Resuming from the previous example — using row_number over initialy non-sortable data to provide indexes

当然有不同的方式(语义上)去做这件事。例如,您可以使用一个临时视图(除了可以使用 pyspark SQL 语法之外,它没有明显的优势):

*****>>> df_final.createOrReplaceTempView(‘df_final’)
>>> spark.sql(‘select row_number() over (order by “monotonically_increasing_id”) as row_num, * from df_final’)*****

这里的要点是:

  • 同上,但还有一点要注意,实际上排序是由分区完成的****

这整个努力的最大收获是

为了使用row_number(),我们需要将数据移动到一个分区中。两种情况下的Window(可排序和不可排序的数据)基本上都包含了我们当前拥有的所有行,因此row_number()函数可以遍历它们并增加行号。这可能会导致性能和内存问题——我们很容易崩溃,这取决于我们有多少数据和多少内存。所以,我的建议是,你真的要问问自己,你的数据是否需要一种类似自动递增/索引的行为,或者你是否可以用另一种方式来避免这种行为,因为这将是昂贵的。尤其是当您每次处理任意数量的数据时,因此无法仔细考虑内存量(例如,在组或窗口中处理流数据)。

每当您使用Window时,Spark 都会给出以下警告,而没有提供对数据进行分区的方法:

*******WARN WindowExec: No Partition Defined for Window operation! Moving all data to a single partition, this can cause serious performance degradation.*******

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

Using row_number() over Window and the OOM danger

结论:这到底是不是一个好主意?

嗯,大概不是。根据我的经验,如果你发现自己需要这种功能,那么你应该好好审视一下你的需求和你的转变过程,如果可能的话,找出解决方法。即使你使用了zipWithIndex(),你的应用程序的性能可能仍然会受到影响——但是对我来说这似乎是一个更安全的选择。**

但如果你无法避免,至少要意识到它背后的机制、风险,并做好相应的计划。

我希望这有所帮助。任何想法,问题,更正和建议都非常欢迎:)

有用的链接和注释

******* [## 用非技术性的方式解释技术性的东西——Apache Spark

什么是 Spark 和 PySpark,我可以用它做什么?

towardsdatascience.com](/explaining-technical-stuff-in-a-non-techincal-way-apache-spark-274d6c9f70e9)

从 0 开始调整指标

使用row_number()时的索引从 1 开始。要让它们从 0 开始,我们可以简单地从row_num列中减去 1:

df_final = df_final.withColumn(‘row_num’, F.col(‘row_num’)-1)

关于 rdd 和数据集

[## 三个 Apache Spark APIs 的故事:RDDs 与数据帧和数据集

总之,选择何时使用 RDD 或数据框架和/或数据集似乎是显而易见的。前者为您提供…

databricks.com](https://databricks.com/blog/2016/07/14/a-tale-of-three-apache-spark-apis-rdds-dataframes-and-datasets.html) [## RDD 节目指南

默认情况下,Spark 2.4.4 的构建和发布是为了与 Scala 2.12 协同工作。(Spark 可以构建为与其他……

spark.apache.org](https://spark.apache.org/docs/latest/rdd-programming-guide.html)

关于 createOrReplaceTempView

这将为您的数据创建一个延迟评估的“视图”(如果该视图名称已经存在,则替换它),这意味着如果您不缓存/持久化它,每次您访问该视图时,任何计算都将再次运行。通常,您可以在 Spark SQL 中使用 hive 表。

[## pyspark.sql 模块- PySpark 2.4.4 文档

schema-py spark . SQL . types . datatype 或数据类型字符串或列名列表,默认值为。数据类型字符串…

spark.apache.org](https://spark.apache.org/docs/latest/api/python/pyspark.sql.html#pyspark.sql.DataFrame.createOrReplaceTempView)

行号和窗口

[## pyspark.sql 模块- PySpark 2.4.4 文档

schema-py spark . SQL . types . datatype 或数据类型字符串或列名列表,默认值为。数据类型字符串…

spark.apache.org](https://spark.apache.org/docs/latest/api/python/pyspark.sql.html#pyspark.sql.functions.row_number) [## Spark SQL 中的窗口函数介绍

在这篇博文中,我们介绍了 Apache Spark 1.4 中添加的新窗口函数特性。窗口功能…

databricks.com](https://databricks.com/blog/2015/07/15/introducing-window-functions-in-spark-sql.html)

接下来去哪里?

理解你的机器学习模型的预测:

[## 机器学习的可解释性——带有 PySpark 的 Shapley 值

解读隔离森林的预测——不仅仅是

medium.com](https://medium.com/mlearning-ai/machine-learning-interpretability-shapley-values-with-pyspark-16ffd87227e3)*******

地址和城镇:使用谷歌地图 API + PhilGIS 进行地理标记

原文:https://towardsdatascience.com/addresses-and-barangays-geotagging-with-google-maps-api-philgis-73d575c0e8e1?source=collection_archive---------24-----------------------

将谷歌地图和 shapefiles 链接到他们的镇(菲律宾版的一个县),以避免痛苦的手动分类的需要

登革热在菲律宾是一个真正的问题。头痛、关节痛、全身皮疹和死亡——这种疾病今年在菲律宾已有 146,000 个病例,并夺走了 622 人的生命。在 17 个地区中,有 7 个地区已经宣布发生了流行病,围绕唯一获得许可的登革热疫苗的使用仍然存在很大争议。

作为防止登革热传播的努力的一部分,由 Wilson Chua 博士领导的蚊子实时普查项目旨在使用卫星数据来识别可能成为潜在登革热热点的死水区域。最终目标是在这些地区放置诱蚊产卵器和传感器,以检测蚊子的存在,并就可能的疫情向官员发出警报。

我的任务是将 6100 个地址映射到奎松市相应的镇。村是菲律宾最小的政府单位,包括从 10 个街区到 30 个街区(甚至更大)的范围。奎松市(大马尼拉地区最大的城市)由 142 个镇组成。

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

A bunch of barangays crammed like sardines in Manila

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

And Barangay Pasong Tamo casually sitting there just encompassing 3 villages, a park and a university

最初,这项任务需要手动完成。让事情变得更复杂的是,镇有旧名字和新名字,谷歌地图上出现的一些地区和区域的名字看起来是镇,但实际上不是。有多条街道有相同的名字,而镇镇通常不写在地址上。

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

幸运的是,Google Maps API 和 PhilGIS 的 barangay shapefiles(祝福你)有所有必要的信息来通过简化这个过程。

方法(快速和无统计)

使用 Python 模块请求,我提取了每个地址的谷歌地图信息,从中提取了纬度和经度。然后,对于每个地址,我检查它的纬度和经度是否在一个镇的区域内,该镇的坐标取自 PhilGIS 的 shapefiles。

对于用谷歌地图和菲尔吉斯找不到的镇,我不得不手动分类。找不到这些地址,因为它们太模糊或有冲突的信息。也许街道与地址中写的城市不匹配,或者建筑物的名称位于不同的街道上。在进行全面的强力搜索之前,我使用可以识别重要地点标识符的关键字标记了每个地址,即:

  • 布兰盖:BGY,布里吉
  • 村庄:村庄,SUBD,丘陵,家园,高地,HTS
  • 项目:PROJ 项目
  • 建筑:大楼,公寓,公寓,住宅,住宅
  • Road: RD,Road,ST,STR,STREET,DRIVE,EXT,EXTN,SCT,SCOUT
  • 大道,大道,道路

对于 Barangay、Project 和 Scout(马尼拉的一组道路),我在它们后面加上了一个单词,以给出这个地方的名称(例如, Barangay Tatalon, Project 4, Scout Chuatoco)。剩下的我就拿他们之前的话(达马尔,巴纳韦,草地民居,奎松大道)。

关键词是按照显示的顺序选择的:如果镇名写在地址中,就不需要进一步分类了——因为它已经在那里了!村庄非常具体,项目(住宅小区)和建筑也是如此,因为它们有特定的地址。道路和大道变得更加不具体,因为它们并不总是有特定的数字,而且镇的边界经常在道路/大道上相交,所以不会非常清楚哪个地址通向哪里。这些关键字有助于更快地阅读地址——而不是阅读整个地址,我只需查找村庄或建筑物的具体名称,或者直接复制 barangay,这使得任务更快。

结果

在任何自动化之前,我尝试手动操作。对于每个地址,我平均花了大约一分钟(花了很长时间,因为有些地址缩写怪异,在谷歌地图上匹配多个位置,有模糊的细节,等等。).因此,我需要 102 个小时才能完成。

另一方面,运行整个代码需要大约半个小时,并且它对所有地址的 97%进行了分类。我花了大约 3 个小时来分类剩下的 180 个地址。

该代码可供使用,并可以扩展到整个菲律宾几乎所有其他省份!细节在朱庇特笔记本上。

附录

点击查看代码

采用假设驱动的建模工作流程

原文:https://towardsdatascience.com/adopting-a-hypothesis-driven-modeling-workflow-9edc8b80a8ed?source=collection_archive---------27-----------------------

用作现代预测建模基础的许多算法使用迭代过程来获得优化的解决方案。对于某些模型类型,如 boosting,每次迭代都要参考前一次迭代的结果。作为一名模型构建者,我寻求实现一个工作流程,该工作流程反映了那些构成我的模型核心的预测算法:由假设决定的不断迭代。

  • 不断的迭代允许复杂性慢慢地在基本基线模型之上分层(例如,附加特性、缩放、输入、调整)。
  • **一次迭代评估模型的一组目标变更。**该过程允许模型构建者评估每组变更对整个模型的影响(仅保留那些具有积极影响的变更)。
  • 每次迭代都试图评估模型构建者所持有的假设的有效性。模型构建者的核心工作是形成和检验假设。假设的来源包括以前的经验(什么在过去有效?)、领域专业知识、探索性数据分析和直觉。

当构建预测模型时,我经常陷入的一个陷阱是,没有遵循上述迭代构建过程,就过快地增加了模型的复杂性。增加复杂性而不迭代意味着我失去了对我的假设中哪些是有用的,哪些是不相关的(从而可能增加噪音),以及哪些是有害的粒度理解。这通常会导致许多问题:

  1. **较慢的迭代:**模型运行的计算成本很高,降低了我快速迭代/工作的能力
  2. **理解力低:**我无法解释是什么赋予了我的模型预测能力,降低了我的优化能力。此外,该模型经常是不必要的复杂(例如,更简单的模型将实现类似的性能)
  3. **更少的想法:**我产生好的假设的能力降低了,因为我从模型中得不到太多的反馈(它通常是好想法的来源)

为了展示符合假设驱动迭代理念的工作流的力量,下面的可视化详细描述了我用来构建一个简单模型的迭代过程,该模型旨在预测位于坦桑尼亚的水泵是否正常工作,是否正常工作但需要维修,或者是否正常工作。该数据集是由 DrivenData 主办的正在进行的建模竞赛的一部分。

如下图所示,经过一系列的 10 次迭代,我的模型从 54%精度的多数类基线提高到大约 78%精度。

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

如图所示,一组相对简单的迭代产生了大约 78%准确度的预测模型(相比之下,原始基线为 54%)。作为我工作流程的一部分,对于每一次迭代,我都会详细说明:

  • 假设:我在用这个迭代测试什么信念?
  • **行动:**我要采取什么行动(改变模型)来测试假设?
  • **结果:**这对模型有什么影响?
  • 洞察力:假设正确吗?这个迭代如何通知未来的迭代?

下面的屏幕截图显示了我用来支持创建水泵状态预测模型的表格:

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

Google Sheets

老实说,我在构建这个模型时的第一次尝试并没有坚持通过不断迭代将复杂性分层到模型中的理论。更确切地说,我很少迭代,导致迭代之间的许多变更降低了我评估每个变更有效性的能力。虽然模型的性能相似,但迭代过于复杂且计算量大(降低了我测试假设的能力)。此外,我并不清楚为什么这款车型表现出色。

由于我的原始模型的复杂性,我最终不得不重新开始来增加我快速实验的能力。采用上述过程最终实现了更高性能、更轻的模型。

总之,虽然很容易给模型增加多层复杂性,但是接受不断迭代将提供对模型的更深入理解,产生更有创造性的假设,并产生更简单、更轻便的模型。

高级主动学习备忘单

原文:https://towardsdatascience.com/advanced-active-learning-cheatsheet-d6710cba7667?source=collection_archive---------30-----------------------

主动学习是为人类选择最佳未标记数据以供监督机器学习查看的过程。大多数真实世界的机器学习系统都是在数千甚至数百万人类标记的样本上训练的。在这种情况下,如果人类花时间查看正确的数据进行注释,你可以更快地让机器学习模型更准确。

有两种类型的主动学习:不确定性采样和多样性采样。不确定性采样的目标是那些在当前状态下明显使模型混乱的数据,而多样性采样的目标是那些在模型知识中存在缺口的数据。在机器学习的知识象限中,不确定性采样处理已知的未知,多样性采样处理未知的未知:

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

Knowledge Quadrant for Machine Learning

有关每种主动学习类型的更多信息,请参见前面的备忘单:

[## 不确定性采样备忘单

用于主动学习的四种常见不确定性抽样策略的快速参考。

towardsdatascience.com](/uncertainty-sampling-cheatsheet-ec57bc067c0b) [## 多样性抽样备忘单

主动学习的四种常见多样性抽样策略的快速参考。

towardsdatascience.com](/https-towardsdatascience-com-diversity-sampling-cheatsheet-32619693c304)

理想情况下,在你尝试实施更高级的主动学习策略之前,你应该亲自尝试实施我的书中的不确定性采样和多样性样本的例子。我的免费 PyTorch 库中也有主动学习算法的清晰示例:

[## rmunro/pytorch_active_learning

图书馆常见的主动学习方法伴随:人在回路中的机器学习罗伯特芒罗曼宁…

github.com](https://github.com/rmunro/pytorch_active_learning)

孤立地使用,不确定性采样方法通常会集中于特征空间的一部分,因此缺乏多样性。如果单独使用,多样性抽样方法通常会发现大多数多样性远离决策边界,因此不会对可能被错误标记的项目进行抽样。因此,大多数现实世界的策略将结合这两种方法来进行主动学习。

你将通过在你自己的数据上执行算法并评估哪种算法最适合你所面临的问题而学到最多。因此,我建议在您亲自尝试过这些方法,并对每种方法在数据上的优缺点积累了实际经验之后,使用这份备忘单作为参考。

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

Advanced Active Learning: the optimal methods are often the combination of simpler building blocks.

提示:把单独的主动学习方法看作是需要组合的积木

不确定性抽样和多样性抽样结合起来效果最好。虽然关于结合不确定性抽样和多样性抽样的学术论文关注的是结合两者的单一指标,但在实践中,你可以简单地将这些方法串联起来:应用一种方法获得大样本,然后用另一种方法提炼该样本。

这种脱节的原因是机器学习的学术界论文倾向于关注能够端到端完成任务的单一算法,主动学习也不例外。因此,如果你只阅读关于主动学习的学术论文,那么你可能会被误导,认为现实世界中的最佳方法也需要是一个复杂的组合指标。在关于高级主动学习的章节中,我们确实涵盖了将不确定性采样和多样性采样结合到单一方法中的最新方法。然而,我建议首先尝试组合更简单的方法:它们通常对数据来说是最佳的,并且更容易解释和实验。

比较简单的方法应该是比较高级方法的基线,所以无论如何都应该实现它们。

结合不确定性采样和多样性采样的 10 种策略:

  1. 基于聚类的最小置信度抽样: 对模型中容易混淆的项目进行抽样,然后对这些项目进行聚类,以确保样本的多样性(见下图)。
  2. 基于模型的异常值的不确定性采样: 对您的模型中容易混淆的项目进行采样,并在这些项目中找到模型中激活度较低的项目。
  3. 基于模型的异常值和聚类的不确定性采样: 结合方法 1 和 2。
  4. 典型的基于聚类的采样: 对您的数据进行聚类,以捕捉与您的目标域最相似的多节点分布和样本项目(见下图)。
  5. 从最高熵聚类中采样: 对你的未标记数据进行聚类,为你的模型找到平均混淆度最高的聚类。
  6. 不确定性抽样和代表性抽样: 既让你当前模型困惑又最像你目标域的样本项。
  7. 基于模型的离群值和代表性采样: 在你的模型中激活度低,但在你的目标域中相对常见的样本项。
  8. 聚类以自身为层次聚类: 递归聚类以最大化多样性。
  9. 从具有置信区间的最高熵聚类中采样采样: 找到具有最大混淆的聚类,然后在该聚类内对最大成对标签混淆进行采样。
  10. 将集成方法和漏失与个体策略结合: 通过蒙特卡罗漏失又名贝叶斯深度学习,聚合来自多个模型或来自一个模型的多个预测的结果。

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

Example of Least Confidence Sampling with Clustering-based Sampling: sample items that are confusing to your model and then cluster those items to ensure a diverse sample.

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

Example of Representative Cluster-based Sampling: cluster your data to capture multinodal distributions and sample items that are most like your target domain.

有许多不同的方法可以将不同的方法结合起来,以下是 10 种常见的方法。已经实现了几个组合 PyTorch 主动学习库并在书中进行了讨论。大多数组合只是几行额外的代码来组合更简单的方法。所以,你应该能够相对容易地尝试其他组合。

对于现实世界的多样性,您可能需要组合任意数量的这些方法,以最小化来自您的数据的任何偏差。就像这本书推荐的那样,你应该明确地跟踪你所关心的人口统计数据的准确性,并使用关注多样性的准确性度量标准来评估不同的方法。你还应该知道你的模型是否会纠正、反映或放大数据中的偏差,因为这也会改变你的主动学习策略。

下载备忘单:

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

你可以在这里下载 PDF 版本的 cheat sheet:http://www . Robert Munro . com/Advanced _ Active _ Learning _ cheat sheet . PDF

这份备忘单摘自我的书《人在回路中的机器学习:

https://www . manning . com/books/human-in-the-loop-machine-learning

我的书的章节已经出版了——高级主动学习章节已经出版,下一章将讲述如何将主动学习应用于不同的机器学习任务,如预测文本序列和图像的语义分割。我会一边走一边分享摘录!

罗伯特·芒罗

2019 年 12 月

高级分析很好,但是我们从简单分析开始怎么样?

原文:https://towardsdatascience.com/advanced-analytics-is-nice-but-how-about-we-start-with-simple-analytics-73ff6c7524fb?source=collection_archive---------17-----------------------

高级分析!每个人都想要一些,但很少有人需要一些。让我们先从健康的简单分析开始。

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

From simple analytics to advanced analytics

我知道,我明白了!您对自己的所有数据感到兴奋,并希望立即雇用一名数据科学家,开始对您的数据进行所有高级分析。

然而,在现实中,我不确定这句话的意思是否和你想的一样。停下来思考一下——有人对您的数据进行简单的分析吗?你真的开始挖掘简单的指标来看你的业务是如何运作的吗?作为一名数据科学家,我认为在 90%以上的情况下,听到“高级分析”这个术语的人会认为他们应该加入这个潮流。不幸的是,这可能会浪费你公司的时间和资源,直到你真正需要它。

高级分析的 80/20 法则

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

80/20 rule of advanced analytics

在这一点上,大多数人都熟悉 80/20 法则,或者帕累托法则。本质上,你从 20%的投入中获得了 80%的收益。对于分析来说也是如此。当你第一次开始了解你的业务并努力开发一种数据驱动的管理方法时,你可以用 20%的努力获得 80%的洞察力。这 20%的努力可以是关于你有多少用户,你做了多少销售,或者你在一段时间内的总收入的基本汇总统计。

高级分析绝对是 80%的努力换来 20%的收益。这就是为什么当你开始时,你肯定不需要高级分析。一旦你用基本工作充分发挥了理解你的业务和客户的能力,只有那时你才应该转向高级分析。

为什么您还不需要高级分析

这个世界只谈论像数据科学和人工智能这样性感的东西。你很少阅读《福布斯》或《商业内幕》上关于简单分析或数据管理等“无聊”内容的文章。然而在现实中,除非你需要细分客户群,从每个客户身上多挤出一点收入,否则你不需要高级分析。

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

Simple analytics before advanced analytics

我是精益创业运动最小可行产品(MVP) 的主要理念的超级粉丝。对你的业务来说,分析的 MVP 是简单分析。一旦你开始了解你需要什么样的数据、人员和资源来分析这些数据,那么你就可以继续进行高级分析了。

没有数据的数据科学工作

如果你不相信,让我给你讲个故事。我最近被聘为数据科学顾问,帮助一个组织解决一些业务问题。正如你们许多人所知,数据科学家并不是雇佣成本最低的人。

所以我走进大楼,在我的第一次计划会议上坐下来,问我什么时候可以访问数据…茫然的凝视。

我们以为你会那样做。我们不知道如何处理我们的数据

这正是我的观点。在考虑雇用拥有高学历和昂贵简历的人之前,你需要问自己和你的公司一些简单的分析问题,比如,我们甚至可以访问数据来进行高级分析吗?

最后,是的,你很可能最终会有人全职为你的公司做高级分析,但是请你为自己节省一些时间和金钱,先从简单的分析开始!

我的名字是 亚历山大·泰特斯 我患有旅游癖。我经常陷入沉思,迷失在树林中,而且经常同时迷失在两者之中。我的人生使命是重新定义 职业成功 以包含个人和职业追求的阶段。你可以在LinkedInTwitter 上找到我在网上分享的一些想法 和在

原载于 2019 年 8 月 17 日 https://alexandertitus.com

机器学习的高级烛台(一):刻度条

原文:https://towardsdatascience.com/advanced-candlesticks-for-machine-learning-i-tick-bars-a8b93728b4c5?source=collection_archive---------1-----------------------

在本文中,我们将学习如何构建分笔成交点,我们将彻底分析它们的统计属性,如回报率的正态性或自相关性,我们将探索在哪些情况下这些棒线可以很好地替代传统的基于时间的蜡烛图。为了说明分笔成交点在预测加密货币市场中的适用性,我们将基于由 16 个加密货币交易对组成的整个数据集进行分析,其中包括最受欢迎的加密资产,如比特币、以太币或莱特币

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

1.—导言

在之前的一篇文章中,我们探讨了如果我们计划训练机器学习(ML)算法,为什么传统的基于时间的烛台不是最合适的价格数据格式。即:(1)基于时间的蜡烛图过采样低活动期和欠采样高活动期,(2)市场越来越多地被不再遵循任何与人类相关的日光周期的交易算法所控制,(3)基于时间的蜡烛图在交易者和交易机器人中普遍存在,这增加了竞争,正如我们将在本文中看到的,(4)基于时间的蜡烛图提供了较差的统计属性。如果您错过了更新,请找到下面文章的链接。

[## 金融机器学习从业者一直在使用错误的烛台:原因如下

在这篇文章中,我们将探讨为什么传统的基于时间的烛台是一种低效的方法来汇总价格…

towardsdatascience.com](/financial-machine-learning-practitioners-have-been-using-the-wrong-candlesticks-heres-why-7a3fb85b5629)

在这篇文章中,我们将探讨其中一个建议的替代酒吧:滴答酒吧。让我们深入研究一下。

2.—构建刻度条

关于什么是分笔成交点,至少有两个主要的定义。报价投资媒体:

分笔成交点是衡量证券价格最小上下波动的指标。分笔成交点也可以指一种证券在不同交易中的价格变化。

在分笔成交点的例子中,我们关心的定义是第二个:在分笔成交点的范围内,分笔成交点本质上是一个交易和在交易所进行交易的价格。分笔成交点或分笔成交点蜡烛线只是预定义数量的分笔成交点的集合。例如,如果我们想要生成 100 点棒线,我们必须保存所有交易的数据,每次我们从交易所“收到”100 笔交易,我们就创建一个棒线或蜡烛线。然后通过计算开盘价、最高价、最低价、收盘价和成交量来构建烛台(通常简称为 OHLCV)。

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

开盘价和收盘价分别对应于第一笔和最后一笔交易的价格。最高价和最低价是蜡烛线中所有交易的最高价和最低价(可能与开盘价和收盘价重叠)。最后,交易量是所有交换资产的总和(例如,在 ETH-USD 对中,交易量以蜡烛线期间交换的以太物数量来衡量)。惯例是,当一根蜡烛的收盘价比开盘价高时,我们把它涂成绿色(或者空着),而如果收盘价比开盘价低,我们就把它涂成红色(或者填满黑色)。

下面是一个非常简单但快速的 Python 实现来生成刻度烛台:

这是与标准的基于时间的烛台相比,刻度条的视觉效果。在这种情况下,我们显示了 BTC-美元交易对的 4 小时和 1000 点棒线,以及 2017 年 1 月 21 日至 2017 年 2 月 20 日之间所有交易的价格。请注意,对于烛台,我们每次对一根棒取样时都会显示一个星号。

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

关于这些地块的两个主要观察结果:

  1. 是的,壁虱烛台看起来很丑。它们混乱、重叠、难以理解,但请记住,它们不应该对人类友好:它们应该对机器友好。
  2. 他们丑的真正原因是因为他们工作做得很好。看看星号,看看在价格变化很大的时期,有更多的星号(和更多的棒线)混杂在一起?而相反:当价格变化不大时,分笔成交点采样要低得多。我们实际上是在创建一个系统,在这个系统中,我们将信息到达市场(更高的活动和价格波动)与烛台的取样同步。我们终于在高活动期采样更多,在低活动期采样更少。万岁!

3.—统计属性

那么它们的统计特性如何呢?它们比传统的基于时间的同类产品更好吗?

我们将关注两个不同的属性:(1)序列相关性和(2)在 CryptoDatum.io,中提供的 15 种加密货币对中的每一种的回报的正态性,包括 Bitfinex 交易所的所有历史棒线,以及基于时间和分笔成交点的棒线大小:

  • 基于时间的条形大小 : 1 分钟、5 分钟、15 分钟、30 分钟、1 小时、4 小时、12 小时、1 天。
  • 刻度条尺寸 : 50,100,200,500,1000

3.1——序列相关性(也称为自相关)

序列相关度量时间序列中的每个值与下一个值(对于 lag=1)的相关程度,或者任何值 I 与任何其他值 i+n (lag=n)之间的相关程度。在我们的例子中,我们将计算对数回报的序列相关性,这是作为蜡烛收盘价的对数的一阶差来计算的。

理想情况下,我们系列的每个数据点应该是一个独立的观察。如果存在序列相关性,这意味着它们不是独立的(它们在滞后=1 或更高时相互依赖),这将在建立回归模型时产生后果,因为我们在回归中观察到的误差将小于或大于真实误差,这将误导我们的解释和预测。你可以在这里看到这个问题非常形象的解释。

为了测量序列相关性,我们将计算序列相对于移位自身的皮尔逊相关性(滞后=1,也称为一阶相关性)。结果如下:

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

Pearson auto-correlation

事实证明,分笔成交点(标记为 tick-)通常比基于时间的蜡烛图(标记为 time-)具有更低的自相关性,也就是说,皮尔逊自相关性更接近于 0。对于较大的时间棒线(4h、12h、1d),这种差异似乎不太明显,但有趣的是,即使是最小的分笔成交点(50 分笔成交点和 100 分笔成交点)也产生非常低的自相关性,这对于较小的时间棒线(1 分钟、5 分钟)并不成立。

最后,有趣的是,我们可以看到几种加密货币(BTC、LTC、ZEC 和 ZIL)在几个时间条中表现出相当强的负自相关性。Roberto Pedace 在这里评论了关于负自相关的:

当数据中观察值的顺序相关或重要时,回归模型中可能存在*自相关、*序列相关、序列相关。换句话说,对于时间序列(有时是面板或纵向)数据,自相关是一个问题。[…] 无自相关是指误差项的值之间不存在可识别关系的情况。[……]虽然不太可能,但负自相关也是可能的。负自相关发生在一个给定符号的误差之后往往是相反符号的误差。例如,正误差之后通常是负误差,负误差之后通常是正误差。

我们将执行一个额外的统计测试,称为 Durbin-Watson (DB)测试,它也诊断序列相关性的存在。DB 统计值在 0–4 范围内,其解释如下:

本质上,越接近 2,序列相关性越低。结果如下:

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

Durbin-Watson test

结果与 Pearson 自相关测试一致,该测试为以下叙述提供了证据:分笔成交点显示的自相关性略低于基于时间的蜡烛图。

3.2 —回报的正态性

我们可以查看的另一个统计数据是回报的正态性,这是我们的对数回报的分布是否遵循正态(也称为高斯)分布。

我们可以运行几个测试来检查正态性——我们将执行其中的两个测试:测试数据的偏斜度峰度是否符合正态分布的 Jarque-Bera 测试,以及检验样本是否符合高斯分布的最经典测试之一夏皮罗-维尔克测试

在这两种情况下,零假设是样本服从正态分布。如果拒绝零假设(p 值低于显著性水平—通常是< 0.05) there is compelling evidence that the sample does not follow a normal distribution.

Let’s look at the p-values for the Jarque-Bera first:

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

Jarque-Bera p-value

The results are almost unanimous: log returns do not follow a Gaussian distribution (most p-values < 0.05) . Two cryptocurrency pairs (Stellar and Zilliqa) seem to actually follow a Gaussian if we set our significance level at 0.05. Let’s take a look at their distributions (kernel density estimates):

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

Fair enough, some of them could look Gaussian (at least visually). However, notice that the number of samples (n) is very small (e.g. for XLM-USD candle_tick_1000 n=195) so I suspect that one of the reasons may just be the lack of sampling, which provides Jarque-Bera not enough evidence to reject the null hypothesis of normality.

In fact, a quick look at the CryptoDatum.io 数据库显示,XLM-美元和 ZIL-美元交易对分别在去年(2018 年)5 月和 7 月刚刚发布,它们似乎有相当低的成交量…

谜团解开了?😃

现在让我们进行夏皮罗-维尔克检验,看看它是否与先前的结果一致:

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

Shapiro-Wilk p-value

该死,夏皮罗,他们没教你在学校考试时不要抄袭吗?不管棒线的类型如何,回报的非正态性似乎是规律。

4.我们学到了什么?

  1. 通过聚合预定义数量的分笔成交点并计算相关的 OHLCV 值来生成分笔成交点蜡烛图。
  2. 在图表中,刻度线看起来很难看,但它们做得很好:它们在高活动期采样更多,在低活动期采样更少。
  3. 与基于时间的蜡烛图相比,即使在小尺寸(50,100 分笔成交点)下,来自分笔成交点的对数回报显示出较低的序列相关性。
  4. 基于分笔成交点和基于时间的棒线的日志回报都不服从正态分布。

感谢阅读。在接下来的几周,我们将讨论其他类型的高级棒线,如量棒线、美元棒线和(我最喜欢的)不平衡棒线。所以,如果你喜欢这篇文章:敬请期待!

这个项目是我们在cryptodatum . io研究的一部分,这是一个加密货币数据 API,旨在提供即插即用的数据集来训练机器学习算法。如果您喜欢我们在本文中展示的数据,您可以在https://cryptodatum . io获得免费的 API 密钥并亲自使用它

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

机器学习的高级烛台(二):体积和美元酒吧

原文:https://towardsdatascience.com/advanced-candlesticks-for-machine-learning-ii-volume-and-dollar-bars-6cda27e3201d?source=collection_archive---------7-----------------------

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

在本文中,我们将学习如何构建成交量和美元棒线,并探索它们相对于传统的基于时间的烛台和分笔成交点棒线的优势。最后,我们将在 16 个加密货币交易对的大型数据集中分析它们的两个统计属性——回报的自相关性和正态性

介绍

在一篇的前一篇文章中,我们学习了如何构建分笔成交点,并评估了它们根据市场中较高或较低的活动自动调节采样率的特殊能力。与分笔成交点相似,成交量和美元线也允许采样率与市场活动同步,但他们每个人对活动的理解不同。在分笔成交点的例子中,市场活动被定义为在交易所发生的交易数量。交易量条将交易量定义为交易所交易的资产数量,例如,交易的比特币数量。对于美元棒线,活动被定义为交换的固定价值,例如,每次交换 1000 美元的资产时对棒线进行取样,它可以用美元来衡量,也可以用欧元、日元等来衡量。

因此,每种棒线对市场活动的理解和同步方式不同,这种不同的理解带来了它的优点和缺点。让我们深入研究一下。

分笔成交点、成交量和美元棒线的优缺点

利用棒线,我们找到了一种方法来扫描交易所的交易历史,并在交易所执行更多交易时,简单地采样更多棒线。虽然交易数量和信息到达之间可能存在很强的相关性,但这种相关性是不确定的。例如,一个非常熟悉的算法或交易员可能会自动发出非常小的重复订单,以影响市场情绪(通过将交易历史“变绿”),隐藏交易总量(也称为冰山订单),或者只是通过伪造信息到达来迷惑其他交易机器人。

这种情况的一个潜在解决方案是使用音量条。成交量棒不关心交易的顺序或数量,他们只关心这些交易的总量。对他们来说,信息的到来是交易所用户之间交易量的增加。通过这种方式,交易量柱能够绕过对交易数量的误导性解释,代价是失去隐藏在实际交易序列中的任何信息。

成交量棒线的另一个有趣的特征,听起来很明显,但值得注意的是,市场成交量信息本身就编码在棒线上:每个成交量棒线都是一个预定义成交量的桶。同样,这听起来可能是显而易见的,但长期以来,直到今天,金融领域的许多研究人员对如何将交易量信息纳入他们的预测模型毫无头绪。音量条提供现成的音量信息。

现在,交易量柱的问题是,交易量可能与交易资产的实际价值密切相关。例如,在 2017 年初,1 万美元可以购买大约 10 个比特币,但到了 2017 年底,你只能用它购买半个比特币。潜在价值的巨大波动极大地削弱了量柱的力量,因为由于资产的重估,在某个时间点相关的量大小可能在不久的将来不相关。纠正这种波动的一种方法是,不计算交换的资产数量(数量条),而是计算交换的固定价值数量(美元条),对于 etc 美元货币对,这恰好是以美元计算的,但对于欧洲货币对,也可能是以欧元计算的,等等。

建筑体积和美元酒吧

现在我们已经看到了每种条形的优点和缺点,让我们来看看如何实际构建它们。

下面是构建音量条的快速 Python 实现:

Snippet 1. Volume bar implementation

这里是美元条的一个实现,它只包括对前面函数的一些小的修改——让我们看看您是否能发现它们:

Snippet 2. Dollar bar implementation

最后,以下是它们与传统计时烛台的对比:

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

Figure 1. Trade, time-based, volume and dollar bars depiction. Asterisks are plotted every time a candle is sampled

基于交易量和美元的蜡烛线在某种意义上类似于分笔成交点,虽然与基于时间的调和蜡烛线相比,它们看起来混乱和重叠,但只要市场活动有变化,它们就能很好地采样。

量柱的统计分析

现在让我们看看它们的统计特性。我们将通过 Pearson 自相关测试和 Durbin-Watson 测试来研究收益的序列相关性。最后,我们还将通过执行贾尔克-贝拉和夏皮罗-维尔克检验来研究结果的正态性。参考关于刻度条的旧文章,了解更多关于这些统计测试的信息。

在交易量柱的情况下,我们将显示 16 个交易对的结果,每个交易对有 7 个交易量(标记为第 1 层到第 7 层)。与分笔成交点不同,交易量大小是特定于加密货币的,因为它们取决于多种因素,如流通中的硬币总量、基础资产价值等。我们选择每种加密货币的交易量大小的方法是通过计算每天的平均交易量,然后将每天的平均交易量除以相同的比率,如 5 分钟、15 分钟、30 分钟、1 小时、4 小时、12 小时对应于 1 天,并四舍五入到最接近的 10。以下是每个加密货币对自动选择的数量:

Table 1. CryptoDatum.io volume bar sizes

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

Figure 2. Pearson auto-correlation for volume bars

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

Figure 3. Durban-Watson statistic for volume bars

结果与我们看到的分笔成交点一致。与基于时间的蜡烛图(图 2 和图 3)相比,量柱显示的自相关性稍低,并且在两个正态性检验(图 4)中的大多数情况下,正态性的零假设都被拒绝,因此我们确定收益不遵循高斯分布。

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

Figure 4. Jarque-Bera and Spahiro-Wilk tests p-value for volume bars

美元金条的统计分析

我们将重复之前对收益的自相关性和正态性的测试。在美元条的情况下,美元条的大小(以美元表示)定义如下表所示:

Table 2. CryptoDatum.io dollar bar sizes ($)

现在让我们看看正态性和自相关测试的结果:

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

Figure 5. Pearson auto-correlation for dollar bars

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

Figure 6. Durbin-Watson test results for dollar bars

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

Figure 7. Normality tests for dollar bars

与我们在分笔成交点和成交量棒线中看到的相反,结果是美元棒线与基于时间的蜡烛线相比,在自相关性方面几乎没有改善。我们可以观察到不同加密货币之间的自相关方差略低,但平均来看差异很小。最后,回归常态再次遭到广泛拒绝。

蜡烛内部价格变化分析

我们已经说过,分笔成交点、成交量和美元棒线采样适应市场活动,允许我们在高活动期采样更多,在低活动期采样更少。最终,这种属性应该反映在单根蜡烛的价格变化量上。这个想法是,基于时间的烛台在固定的时间间隔采样,而不管市场活动,而替代酒吧得到与市场活动同步。因此,基于时间的蜡烛图应该同时具有价格变化很小的蜡烛线(过采样期间)和价格变化很大的蜡烛线(欠采样期间),而替代棒线应该更加均衡,这似乎是很直观的。

然而,我们所理解的市场活动是什么?一个市场可以非常活跃,价格横向移动吗?答案是肯定的,虽然通常在高市场活动和大的价格变化之间存在相关性,但这种关系是不确定的。例如,在某些情况下,高 FUD(恐惧、不确定性和怀疑)会导致交易量激增,但价格变化很小。此外,在加密货币市场中,清洗交易并不少见。这些动作包括自我交易(买方和卖方是同一个人),这再次引发了巨大的交易量高峰,而价格变化很小。

为了弄清楚这个问题,让我们来看看每种类型的棒线的蜡烛线内价格变化的分布。蜡烛线内价格变化计算如下:

蜡烛线内变化=(高-低)/高

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

Figure 8. Intra-candle price variation for all the history of the BTC-USD pair at the Bitfinex exchange (data source: CryptoDatum.io)

我们可以看到,时间蜡烛图分布更偏向于 0,并且有一个向右的长尾,而其他分布在高价格变化期间有效地采样更多。

每日酒吧频率

B 在结束本文之前,我想看看日柱线的频率,以及交易资产的价格和市场活动如何影响采样率。让我们看看结果:

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

Figure 9. Bar sampling frequency per day for the whole BTC-USD history at the Bitfinex Exchange. Bitcoin log price is shown in grey line. (data source: CryptoDatum.io)

我们可以看到,基于时间的烛台以相同的速率采样(每天 24 根棒线),替代棒线的采样速率根据比特币价格的变化而变化(以灰色显示)。

有趣的是,在替代棒线中,成交量棒线的采样频率似乎仍然是 BTC 兑美元历史上最稳定的——只有当我们包括 2017 年的历史高点时,否则美元或分笔成交点棒线似乎更稳定。另一个让我惊讶的特征是,美元蜡烛应该更稳定,因为它们对实际资产价格有所“修正”,但在 2017 年的历史高点期间,美元蜡烛似乎失去了控制。我怀疑这是因为在大致稳定的交易量中,美元棒线能很好地修正资产的重估。然而,如果你结合资产价格增长 10 倍或更多的事实,总交易量,而不是由于资产的高成本而减少,保持增长,那么你会遇到一种情况,当美元棒采样简单地爆炸。

我们学到了什么?

  • 成交量棒线通过只关注交换的资产总额,解决了关于多个小额交易和冰山订单的价格棒线限制。
  • 美元棒衡量交换的固定价值,这在理想情况下可以校正资产(如加密货币)的波动价值。
  • 当市场活动增加时,成交量和美元棒线取样较多,当市场活动减少时,取样较少。
  • 与传统的基于时间的蜡烛图相比,量柱通常显示较低的序列相关性。
  • 美元棒线似乎不会产生较低的序列相关性。然而,请记住,美元棒线的数量似乎在历史高点期间爆炸,这意味着大多数美元棒线可能来自非常短的时间,因此平均自相关可能更高,只是因为棒线的紧密“相邻”。
  • 成交量和美元棒线的对数收益率都不服从高斯分布。
  • 传统烛台的蜡烛内变化分布似乎向零移动,并呈现长尾,这证实了它们不能使取样适应市场活动。或者,分笔成交点、成交量和美元棒线的蜡烛线内变化分布看起来更平衡,并向右移动。
  • 基于固定周期的烛台后,体积条的采样率似乎是最稳定的。
  • 美元的取样率似乎在泡沫中爆炸,体积非常大。

感谢阅读!在下一集,我们将谈论一种最有趣的酒吧:不平衡酒吧。这些棒线是根据交易顺序中观察到的不平衡来取样的,是信息驱动棒线的一个很好的例子。

这个项目是我们在cryptodatum . io研究的一部分,这是一个加密货币数据 API,旨在提供即插即用的数据集来训练机器学习算法。如果您喜欢我们在本文中展示的数据,您可以在https://cryptodatum . io获得免费的 API 密钥并亲自使用它

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

高级集成分类器

原文:https://towardsdatascience.com/advanced-ensemble-classifiers-8d7372e74e40?source=collection_archive---------11-----------------------

系综这个词是一个拉丁语派生词,意思是“各部分的结合”。常用的常规分类器容易出错。虽然这些错误是不可避免的,但是可以通过学习分类器的适当构造来减少它们。

集成学习是一种生成各种基本分类器的方法,从这些基本分类器中导出一个新的分类器,其性能优于任何组成分类器。这些基本分类器可能在使用的算法、超参数、表示或训练集方面有所不同。

集成方法的关键目标是减少偏差方差

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

The figure shows a basic outline of ensemble techniques.

一些高级集成分类器是:

  1. 堆垛
  2. 混合
  3. 制袋材料
  4. 助推

**堆叠:**堆叠是一种将单个训练数据集给多个模型并进行训练的方法。使用 k-fold 验证进一步划分训练集,并形成结果模型。这里,每个模型表示使用的不同算法。

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

size of the training data=m*n | no. of models=M

从这 M 个模型中做出的预测被用作最终模型的预测器。如此共同形成的变量用于预测最终分类,比每个基础模型更精确

**混合:**与叠加相比,混合是一种类似的技术,但唯一的区别是数据集直接分为训练和验证,而不是 k 倍验证。

Bagging(Bootstrap aggregation):在这种方法中,通过替换从训练数据中选取各种数据项,产生 n 个训练数据样本。

装袋时,由于数据是未加权的,所以抽样中的项目是随机选择的。

对于每次迭代,

  1. 在这些样本中的每一个上创建一个基础模型。
  2. 这些模型并行运行,相互独立。
  3. 通过组合所有模型的预测来确定最终预测。

这些模型共同形成更高等级的模型,以产生更高的准确性。最终模型的平均值为:

e =(σeᵢ)/n

e₁,e₂…在哪里…eₙ =基本分类器

e =最终分类器

打包算法:

  • Bagging 元估计量
  • 随机森林

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

**升压:**升压是一种自学习技术。它通过为数据中的各种项目分配权重来学习。提升技术最初以相等的权重开始,但是在每个模型之后,每个模型基于其性能被分配一个权重。

类似地,在评估每个模型之后,错误分类的数据被赋予更多的权重,以便下一个模型更加关注这些项目。

对于每次迭代,

  1. 它根据分类的不正确程度对每个训练样本进行加权。
  2. 做一个假设
  3. 权衡假设

因此,通过基于权重对数据组进行投票,最终模型是从关注不同数据组的各种模型中得出的。

使用加权平均法对最终模型进行平均

e =((σeᵢwᵢ)/*σwᵢ))/n

哪里,e₁,e₂……eₙ =基本分类器

w₁,w₂……wₙ=重量

n =模型数量

e =最终分类器

升压算法:

  • adaboost 算法
  • 马恩岛
  • XGBM
  • 轻型 GBM
  • CatBoost

注意:在 bagging 中,模型并行运行并且相互独立,而在 boosting 中,模型按顺序运行并且依赖于前面的模型。

数据科学的高级谷歌技能

原文:https://towardsdatascience.com/advanced-google-skills-for-data-science-350bf828dbe6?source=collection_archive---------15-----------------------

像专业人士一样搜索,优化您的编程

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

Photo by Clay Banks on Unsplash

“谷歌一下”的问题是

LMGTFY ”是一个历史悠久的笑话网站。“ RTFM ”是不屑的冷笑。(法语为 Ouais,aussien Fran ais。)

但是,如果找到答案就像在搜索引擎中输入自然语言查询和阅读手册页一样简单,那么就不会有图书馆学研究生学位,我也会失业。

LMGTFY:回答开放式问题不是一件小事。

除了作为一个未解决的、NLP 困难的机器学习问题,寻找“为什么我的代码不编译?”或者“我的模型有什么问题?”是你——用你的非人工智能——在日常生活中需要高效处理的问题,以成为一名有效的数据科学家和程序员。

在这里,我将分享信息专家工具箱中的一些强大工具,您可以使用它们来调试代码并更快地了解相关信息。

有目的的谷歌

它不仅仅是一个自然语言的问题框,尽管没有人否认自动完成是 AI 娱乐的最佳和最高形式。

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

Who hurt you?

如果你没有使用先进的谷歌搜索功能,你就错过了它的全部功能。这些功能包括:

  • 排除带负号的词语:比较热门搜索视频pythonpython -programming:

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

python

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

python -programming

  • 包含带双引号的词条:如果一个词条一定要出现,即使很少见,PageRank 也不怎么看重,那么你可以用引号把它括起来。python x86–64 assembly “fail”将确保你得到编译器“失败”的结果。
  • 同样,使用这些双引号来搜索与完全匹配的字符串。通过将 stderr 复制并粘贴到搜索引擎的一对双引号中来调试代码问题。
  • Bootstrap Google 来弥补另一个网站糟糕的搜索功能。将site:www.example.com作为查询的一部分会将您的搜索限制在该域内。

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

using Google as a single-site search engine

  • 如果你和我不一样,更喜欢 GUI 而不是语法,将高级搜索页面加入书签。它有翻译这些选项和更多的字段。

成为 Github 和 StackExchange 忍者

除了 Google 上的site:github.com,Github 的 UI 和 API 都提供了高级搜索功能,这通常符合我们刚刚讨论的语法。将高级搜索页面加入书签。

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

github advanced search

StackExchange 为高级无畏研究者提供了无数的语法选项。一个很棒的特性是能够使用主题标签上的任何搜索选项,用【括号】表示,来包含或排除内容(例如concurrency *ython -[java] ==“我想看关于 Cython 和 Python 中的并发性的答案,但不是 Java。”).StackExchange】也有一个支持高级搜索的 API (尽管 GitHub 的 API 与更酷的 GraphQL 一起工作)。

做你自己的 NLP 模型+参考馆员

编程的能力是强大的——你创造的东西可以创造其他东西。进行战术研究的能力是一种超能力——你学得更快,解决问题更有效率,并且在这个过程中利用你的元技能。

那么什么是“好的搜索”呢?

  • 把垃圾拿出来。思停话和 TF-IDF。(复习: TF-IDF 的基本思想是,如果一个词在你的语料库中出现得更频繁,它就更有意义,但如果它出现得如此频繁,无论上下文如何,它都不会更有意义。)
  • **获取具体。**可能需要几次尝试来校准查询特异性的水平,以找到相关的答案,但它介于“python 模块不起作用”和复制粘贴带有您的特殊用户名、文件路径和函数名称的回溯之间。试着上下拨动特异性键,看看你的点击会发生什么。
  • 尝试不同的单词。你所包含的术语有可能产生独特的结果吗,或者至少比一些更普通的词获得更多的信息吗?如果没有,你能不能用几种不同的方式来解释你的问题,看看其他人是否尝试过这些措辞?

有时,这是第三或第四个问题的重新措辞,在 StackExchange 搜索结果的第无数页上找到了金子。如果你被一些想法难住了,试试 textblob,它能让你快速地头脑风暴同义词、 meroynmsholonyms 、定义、例句和单词的其他意思,以丰富和重组你的查询。

虽然你可能更喜欢这个 Python 要点,而不是头脑风暴术语的模拟方法,但我还是鼓励你伸展你的精神肌肉,尝试一下。从学习看到一个问题的多个方面中获得的思维可塑性是一种帮助你成为更好的程序员的技能。

保留研究线索

一旦你找到了来之不易的答案,不要失去你已经取得的进步。记录下来。

  • 注释你的代码。你知道有多少次我忘记了一个复杂的研究线索的答案,并感谢过去的我把链接放在了一个屏蔽评论里?
  • 当我们谈到这个主题时,使用版本控制。你的研究笔记没有理由不能是本地 git 回购。一旦你解决了一个大问题,如果它坏了,你需要再次修复它,你会很高兴你有线索。养成写(或做书签)到文件、添加和提交的习惯。一个可追踪的研究轨迹几乎是自我文档化的,并且绝对会为你节省数小时的回溯时间。
  • **利用您的浏览器历史记录。**如果你使用 Chrome,使用谷歌 Chrome/Gmail 开发专用账户来跟踪你的浏览历史。
  • 使用 Vivaldi (我最喜欢的浏览器),这是一个基于 Chromium 的浏览器,允许您创建多个浏览配置文件和标签/书签组(例如,一个用于开发,一个用于 ML,一个用于前端,一个用于休闲时间……)
  • 保存研究文档。将书签存储在一个开源的、跨平台的、支持多媒体的引用和研究管理器 Zotero 中。
  • 或者,如果你也爱命令行,试试 papis

我主要使用一个 CLI,我用一堆普通的。txt 文件和一个 sqlite 后端来管理它们。但是 Zotero 是我最喜欢的与他人分享和合作的开源软件。Papis 功能丰富,我一直在关注概念作为吉拉式服务的一种降价友好、集成和防干扰的替代方案。

欢迎来到信息科学!

(重新)搜索是一门科学和艺术——我拥有这方面的硕士学位,并训练模型试图理解如何擅长它,这是有原因的。这很难——即使对聪明的人来说也是如此。

“谷歌一下”是个糟糕的建议。拿这个代替。

使用 Python 的高级直方图

原文:https://towardsdatascience.com/advanced-histogram-using-python-bceae288e715?source=collection_archive---------12-----------------------

让业务用户和数据科学家高兴的直方图

需要什么?

Python 对生成直方图有很好的支持。但在数据科学中,显示条形/条柱计数、条柱范围、给条形着色以分隔百分位数并生成自定义图例以向业务用户提供更有意义的见解是非常有用的。使用 Python 时,没有内置的直接方法来实现这一点。

所以作为数据科学家需要提供有用的直方图有:

  1. 如何在直方图中显示每个条形的数据点计数?
  2. 如何在直方图的 X 轴上显示条形/条柱范围?
  3. 如何根据百分比改变直方图中条形/条柱的颜色?
  4. 如何生成自定义图例?

我们尝试生成的最终输出将对最终用户非常有用,如下所示:

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

Advanced Histogram

这为什么有用?

了解数据范围和百分位数以及计数和标准化百分比对于确定如何处理/清理数据非常有用。业务用户也很容易理解直方图并从中获取价值。

例如,如果数据严重倾斜,无论是正的还是负的,并且有极端的异常值,则图表可能会揭示关于数据的一些有价值的见解。

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

Advance histogram for skewed data

上面的直方图显示,大约 99%的数据在 1 到 6788 的范围内。虽然数据范围是从 1 到 67875,但很明显,几乎 99%的数据都在 1 到 6788 之间,这有助于决定如何处理异常值。

您无法从下图所示的标准直方图中获得这种细节层次的洞察力。

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

Standard histogram for skewed data

Python 代码

你可以从我的AnalyticsInsightsNinjaGitHub 网站或者从 Azure 笔记本下载代码。

代码中重要的一行是:

counts,bin,patches = ax.hist(data,facecolor = perc _ 50 _ colour,edgecolor=‘gray’)

它返回以下内容:

计数 =直方图中每个面元/列的数据点计数的 numpy . n 数组

面元 =面元边缘/范围值的 numpy . n 数组

补丁 =补丁对象列表。每个 Patch 对象包含一个 Rectnagle 对象。例如矩形(xy=(-2.51953,0),宽度=0.501013,高度=3,角度=0)

通过操作这三个集合,我们可以获得关于直方图的非常有用的信息。

鸣谢:这个代码的灵感来自于 stackoverflow.com 大学的乔·金顿的一个回答

结论

虽然标准直方图很有用,但拥有一个可以显示数据范围和百分位数以及计数和归一化百分比的增强版本,对于数据科学家来说非常有用,可以帮助他们确定应该如何处理/清理数据,并为业务最终用户提供更多价值。

高级 Jupyter 笔记本:教程

原文:https://towardsdatascience.com/advanced-jupyter-notebooks-a-tutorial-3569d8153057?source=collection_archive---------7-----------------------

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

Photo by Scott Graham on Unsplash

Jupyter 笔记本是现代数据科学和分析的核心,在项目生命周期的两端都是非常强大的工具。无论您是快速制作创意原型、演示您的工作,还是制作完整的报告,笔记本电脑都可以提供超越 ide 或传统桌面应用程序的高效优势。

继《 Jupyter 初学者笔记本:教程》之后,本指南将带你踏上从真正的香草到彻头彻尾的危险的旅程。没错!Jupyter 的无序执行的古怪世界有着令人不安的力量,当涉及到在笔记本中运行笔记本时,事情会变得很复杂。

本指南旨在理清一些混乱的来源,传播想法,激发你的兴趣,激发你的想象力。已经有很多关于整洁的提示和技巧的伟大列表,所以在这里我们将更彻底地看看 Jupyter 的产品。

这将涉及:

  • 使用 shell 命令的基础知识和一些方便的魔术进行热身,包括调试、计时和执行多种语言。
  • 探索日志记录、宏、运行外部代码和 Jupyter 扩展等主题。
  • 了解如何使用 Seaborn 增强图表,使用主题和 CSS 美化笔记本,以及定制笔记本输出。
  • 最后深入探讨脚本执行、自动化报告管道和使用数据库等主题。

如果你是 JupyterLab 的粉丝,你会很高兴听到 99%的内容仍然适用,唯一的区别是一些 Jupyter 笔记本扩展与 JuputerLab 不兼容。幸运的是,令人敬畏的 替代品已经在 GitHub 上出现了。

现在我们准备好成为朱庇特巫师了!

Shell 命令

每个用户至少都会不时地受益于从他们的笔记本中直接与操作系统交互的能力。代码单元中以感叹号开头的任何一行都将作为 shell 命令执行。这在处理数据集或其他文件以及管理 Python 包时非常有用。举个简单的例子:

Hello World! pandas==0.23.4

还可以在 shell 命令中使用 Python 变量,方法是在前面加上一个与 bash 风格变量名一致的符号$

This is nifty

注意,在执行完成后,执行!命令的 shell 将被丢弃,因此像cd这样的命令将不起作用。然而,IPython magics 提供了一个解决方案。

基本魔术

Magics 是内置于 IPython 内核中的便捷命令,它使执行特定任务变得更加容易。尽管它们经常类似于 unix 命令,但实际上它们都是用 Python 实现的。存在的魔法比在这里介绍的要多得多,但是有必要强调各种各样的例子。在进入更有趣的案例之前,我们将从一些基础知识开始。

有两种魔法:线魔法和细胞魔法。它们分别作用于单个细胞株,也可以分布于多个细胞株或整个细胞。要查看可用的魔术,您可以执行以下操作:

Available line magics:
%alias  %alias_magic  %autocall  %automagic  %autosave  %bookmark  %cd  %clear  %cls  %colors  %config  %connect_info  %copy  %ddir  %debug  %dhist  %dirs  %doctest_mode  %echo  %ed  %edit  %env  %gui  %hist  %history  %killbgscripts  %ldir  %less  %load  %load_ext  %loadpy  %logoff  %logon  %logstart  %logstate  %logstop  %ls  %lsmagic  %macro  %magic  %matplotlib  %mkdir  %more  %notebook  %page  %pastebin  %pdb  %pdef  %pdoc  %pfile  %pinfo  %pinfo2  %popd  %pprint  %precision  %profile  %prun  %psearch  %psource  %pushd  %pwd  %pycat  %pylab  %qtconsole  %quickref  %recall  %rehashx  %reload_ext  %ren  %rep  %rerun  %reset  %reset_selective  %rmdir  %run  %save  %sc  %set_env  %store  %sx  %system  %tb  %time  %timeit  %unalias  %unload_ext  %who  %who_ls  %whos  %xdel  %xmode

Available cell magics:
%%!  %%HTML  %%SVG  %%bash  %%capture  %%cmd  %%debug  %%file  %%html  %%javascript  %%js  %%latex  %%markdown  %%perl  %%prun  %%pypy  %%python  %%python2  %%python3  %%ruby  %%script  %%sh  %%svg  %%sx  %%system  %%time  %%timeit  %%writefile

Automagic is ON, % prefix IS NOT needed for line magics.

如你所见,有很多!大多数都在官方文档中列出,该文档旨在作为参考,但在某些地方可能有些晦涩。线条魔法以百分比字符%开始,单元格魔法以两个字符%%开始。

值得注意的是,!实际上只是 shell 命令的一种奇特的魔法语法,正如您可能已经注意到的,IPython 提供了魔法来代替那些改变 shell 状态并因此被!丢失的 shell 命令。例子有%cd%alias%env

让我们再看一些例子。

自动保存

首先,%autosave魔术让你改变你的笔记本多久自动保存到它的检查点文件。

Autosaving every 60 seconds

就这么简单!

显示 Matplotlib 图

对于数据科学家来说,最常见的线条魔术之一当然是%matplotlib,它当然是与最流行的 Python 绘图库 Matplotlib 一起使用。

提供inline参数指示 IPython 在单元格输出中内联显示 Matplotlib 绘图图像,使您能够在笔记本中包含图表。在导入 Matplotlib 之前,一定要包含这个魔术,因为如果不包含它,它可能无法工作;许多人在笔记本的开头,在第一个代码单元中导入它。

现在,让我们开始看看一些更复杂的特性。

排除故障

更有经验的读者可能会担心没有调试器的 Jupyter 笔记本的最终功效。但是不要害怕!IPython 内核有它自己的接口Python 调试器,pdb ,以及几个在笔记本上用它调试的选项。执行%pdb line magic 将打开/关闭笔记本中所有单元格的 pdb on error 自动触发。

这暴露了一个交互模式,在该模式下您可以使用 pdb 命令

另一个方便的调试魔术是%debug,您可以在出现异常后执行它,以便在失败时深入研究调用堆栈。

作为题外话,还要注意上面的回溯是如何演示魔术如何被直接翻译成 Python 命令的,其中%pdb变成了get_ipython().run_line_magic('pdb', '')。改为执行这个等同于执行%pdb

定时执行

有时在研究中,为竞争方法提供运行时比较是很重要的。IPython 提供了两个时序魔法%time%timeit,每个都有行和单元模式。前者只是对单个语句或单元格的执行进行计时,这取决于它是用于行模式还是单元模式。

Wall time: 32.9 ms 499999500000

在单元模式下:

Wall time: 95.8 ms

%timeit%time的显著区别在于它多次运行指定的代码并计算平均值。您可以使用-n选项指定运行次数,但是如果没有通过,将根据计算时间选择一个合适的值。

34.9 ms ± 276 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

执行不同的语言

在上面%lsmagic的输出中,您可能已经注意到了许多以各种编程、脚本或标记语言命名的单元格魔术,包括 HTML、JavaScript、 RubyLaTeX 。使用这些将使用指定的语言执行单元格。还有其他语言的扩展,如 R

例如,要在笔记本中呈现 HTML:

这是真的整齐!

同样, LaTeX 是一种用于显示数学表达式的标记语言,可以直接使用:

一些重要的等式:

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

配置日志记录

您知道 Jupyter 有一种内置的方法可以在单元格输出上突出显示自定义错误信息吗?这对于确保任何可能使用您的笔记本的人都很难忽略诸如无效输入或参数化之类的错误和警告非常方便。一个简单的、可定制的方法是通过标准的 Python logging模块。

(注意:对于这一部分,我们将使用一些屏幕截图,以便我们可以看到这些错误在真实笔记本中的样子。)

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

日志输出与print语句或标准单元输出分开显示,出现在所有这些之上。

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

这实际上是可行的,因为 Jupyter 笔记本同时监听标准输出流stdoutstderr,但处理方式不同;print语句和单元格输出路由到stdout,默认情况下logging已被配置为流过stderr

这意味着我们可以配置loggingstderr上显示其他类型的消息。

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

我们可以像这样定制这些消息的格式:

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

请注意,每次运行通过logger.addHandler(handler)添加新流处理程序的单元时,每次记录的每个消息都会有一行额外的输出。我们可以将所有的日志记录配置放在靠近笔记本顶部的单元格中,或者像我们在这里所做的那样,强行替换日志记录器上所有现有的处理程序。在这种情况下,我们必须删除默认的处理程序。

日志记录到外部文件也很容易,如果您从命令行执行笔记本,这可能会派上用场,后面会讨论。用FileHandler代替StreamHandler即可:

最后要注意的是,这里描述的日志不要与使用%config魔法通过%config Application.log_level="INFO"改变应用程序的日志级别相混淆,因为这决定了 Jupyter 在运行时向终端输出什么。

扩展ˌ扩张

由于它是一个开源的 webapp,已经为 Jupyter 笔记本开发了大量的扩展,并且有一个很长的官方列表。事实上,在下面的使用数据库一节中,我们使用了 ipython-sql 扩展。另一个特别值得注意的是来自 Jupyter-contrib 的扩展包,它包含了用于拼写检查、代码折叠等等的独立扩展。

您可以从命令行安装和设置它,如下所示:

pip install jupyter_contrib_nbextensions
jupyter contrib nbextension install --user
jupyter nbextension enable spellchecker/main
jupyter nbextension enable codefolding/main

这将在 Python 中安装jupyter_contrib_nbextensions包,在 Jupyter 中安装,然后启用拼写检查和代码折叠扩展。不要忘记在安装时实时刷新任何笔记本以加载更改。

请注意,Jupyter-contrib 只能在普通的 Jupyter 笔记本上运行,但是 GitHub 上现在发布了 JupyterLab 的新的扩展。

使用 Seaborn 增强图表

Jupyter 笔记本用户进行的最常见的练习之一是制作情节。但是 Python 最流行的图表库 Matplotlib 并不以吸引人的结果而闻名,尽管它是可定制的。Seaborn 立即美化 Matplotlib 图,甚至添加一些与数据科学相关的附加功能,使您的报告更漂亮,您的工作更容易。它包含在默认的 Anaconda 安装中,或者通过pip install seaborn轻松安装。

让我们来看一个例子。首先,我们将导入我们的库并加载一些数据。

Seaborn 提供了一些内置的样本数据集用于文档、测试和学习目的,我们将在这里使用它们。这个“小费”数据集是一只熊猫DataFrame,列出了酒吧或餐馆的一些账单信息。我们可以看到账单总额、小费、付款人的性别以及其他一些属性。

我们可以很容易地在 Matplotlib 中绘制total_bill vs tip

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

在 Seaborn 绘图也一样简单!只需设置一个样式,你的 Matplotlib 图就会自动转换。

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

这是多么大的改进啊,而且只需要一个导入和一行额外的代码!在这里,我们使用了深色网格样式,但是 Seaborn 总共有五种内置样式供您使用:深色网格、白色网格、深色、白色和刻度。

但是,我们并没有止步于样式化:由于 Seaborn 与 pandas 数据结构紧密集成,它自己的散点图功能释放了额外的特性。

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

现在,我们为每个数据点获得了默认的轴标签和改进的默认标记。Seaborn 还可以根据数据中的类别自动分组,为您的绘图添加另一个维度。让我们根据买单的群体是否吸烟来改变标记的颜色。

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

这真是太棒了!事实上,我们可以做得更深入,但是这里的细节太多了。作为品尝者,让我们根据买单的人数来区分吸烟者和非吸烟者。

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

希望能弄清楚为什么 Seaborn 将自己描述为“绘制吸引人的统计图形的高级界面”。

事实上,这已经足够高级了,例如,为绘制数据的提供带有最佳拟合线(通过线性回归确定)的一行程序,而 Matplotlib 依赖于您自己准备数据。但是如果你需要的是更吸引人的情节,它是非常可定制的;例如,如果你对默认主题不满意,你可以从一整套标准的调色板中选择,或者定义自己的主题。

Seaborn 允许你用更多的方式来可视化你的数据结构和其中的统计关系,查看他们的例子

宏指令

像许多用户一样,您可能会发现自己一遍又一遍地编写相同的任务。也许当你开始一个新的笔记本时,你总是需要导入一堆包,一些你发现你自己为每个数据集计算的统计数据,或者一些你已经制作了无数次的标准图表?

Jupyter 允许您将代码片段保存为可执行宏,以便在所有笔记本上使用。尽管执行未知代码对其他试图阅读或使用您的笔记本的人来说不一定有用,但在您进行原型制作、调查或只是玩玩的时候,它绝对是一种方便的生产力提升。

宏只是代码,所以它们可以包含在执行前必须定义的变量。让我们定义一个来使用。

现在,要定义一个宏,我们首先需要一些代码来使用。

Hello, Tim!

我们使用%macro%store魔法来设置一个可以在所有笔记本上重复使用的宏。宏名通常以双下划线开头,以区别于其他变量,如下所示:

Stored '__hello_world' (Macro)

%macro魔术需要一个名字和一个单元格号(单元格左边方括号中的数字;在这种情况下,23 是在In [23],我们还通过了-q,使它不那么冗长。%store实际上允许我们保存任何变量以便在其他会话中使用;这里,我们传递我们创建的宏的名称,这样我们可以在内核关闭后或在其他笔记本中再次使用它。不带任何参数运行,%store列出您保存的项目。

要从存储中加载宏,我们只需运行:

为了执行它,我们只需要运行一个只包含宏名的单元格。

Hello, Tim!

让我们修改我们在宏中使用的变量。

当我们现在运行宏时,我们修改后的值被选中。

Hello, Ben!

这是因为宏只是在单元格的范围内执行保存的代码;如果name未定义,我们会得到一个错误。

但是宏并不是笔记本间共享代码的唯一方式。

执行外部代码

并非所有代码都属于 Jupyter 笔记本。事实上,尽管完全有可能在 Jupyter 笔记本上编写统计模型,甚至是完整的多部分项目,但是这些代码会变得混乱,难以维护,并且其他人无法使用。Jupyter 的灵活性无法替代编写结构良好的 Python 模块,这些模块可以轻松地导入到您的笔记本中。

总的来说,当您的快速笔记本项目开始变得更加严肃,并且您发现自己正在编写可重用的或者可以逻辑分组到 Python 脚本或模块中的代码时,您应该这样做!除了可以在 Python 中直接导入自己的模块,Jupyter 还允许您使用%load%run外部脚本来支持组织更好、规模更大的项目和可重用性。

为每个项目一遍又一遍地导入相同的包是%load魔术的完美候选,它将外部脚本加载到执行它的单元中。

但是已经说得够多了,让我们来看一个例子!如果我们创建一个包含以下代码的文件imports.py:

我们可以简单地通过编写一个单行代码单元格来加载它,就像这样:

执行此操作将用加载的文件替换单元格内容。

现在我们可以再次运行单元来导入我们所有的模块,我们准备好了。

%run魔术是相似的,除了它将执行代码和显示任何输出,包括 Matplotlib 图。您甚至可以这样执行整个笔记本,但是请记住,并不是所有代码都真正属于笔记本。让我们来看看这个魔术的例子;考虑一个包含以下简短脚本的文件。

当通过%run执行时,我们得到以下结果。

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

如果您希望将参数传递给脚本,只需在文件名%run my_file.py 0 "Hello, World!"后或使用变量%run $filename {arg0} {arg1}显式列出它们。此外,使用-p选项通过 Python 分析器运行代码。

脚本执行

虽然 Jupyter 笔记本电脑最重要的功能来自于它们的交互流程,但它也可以在非交互模式下运行。从脚本或命令行执行笔记本提供了一种生成自动化报告或类似文档的强大方法。

Jupyter 提供了一个命令行工具,它可以以最简单的形式用于文件转换和执行。您可能已经知道,笔记本可以转换成多种格式,可以从 UI 的“文件>下载为”下获得,包括 HTML、PDF、Python 脚本,甚至 LaTeX。该功能通过一个名为[nbconvert](https://nbconvert.readthedocs.io/en/latest/usage.html)的 API 在命令行上公开。也可以在 Python 脚本中执行笔记本,但是这已经很好地记录了,下面的例子应该同样适用。

%run类似,需要强调的是,虽然独立执行笔记本的能力使得完全在 Jupyter 笔记本中编写所有的项目成为可能,但这并不能替代将代码分解成适当的标准 Python 模块和脚本。

在命令行上

稍后将会清楚nbconvert如何让开发人员创建他们自己的自动化报告管道,但是首先让我们看一些简单的例子。基本语法是:

jupyter nbconvert --to <format> notebook.ipynb

例如,要创建 PDF,只需编写:

jupyter nbconvert --to pdf notebook.ipynb

这将获取当前保存的静态内容notebook.ipynb并创建一个名为notebook.pdf的新文件。这里需要注意的是,要转换成 PDF 需要安装 pandoc(Anaconda 自带)和 LaTeX(没有)。安装说明取决于您的操作系统

默认情况下,nbconvert不执行你的笔记本单元格代码。但是如果您也想的话,您可以指定[--execute](https://nbconvert.readthedocs.io/en/latest/execute_api.html#executing-notebooks-from-the-command-line)标志。

jupyter nbconvert --to pdf --execute notebook.ipynb

一个常见的障碍是,运行笔记本时遇到的任何错误都会暂停执行。幸运的是,您可以添加--allow-errors标志来指示nbconvert将错误消息输出到单元格输出中。

jupyter nbconvert --to pdf --execute --allow-errors notebook.ipynb

环境变量参数化

脚本执行对于不总是产生相同输出的笔记本电脑特别有用,例如,如果您正在处理随时间变化的数据,无论是从磁盘上的文件还是通过 API 下载的数据。例如,生成的文档可以很容易地通过电子邮件发送给订户名单,或者上传到亚马逊 S3 网站供用户下载。

在这种情况下,您很可能希望对笔记本进行参数化,以便用不同的初始值运行它们。实现这一点的最简单的方法是使用环境变量,这是在执行笔记本之前定义的。

假设我们想要为不同的日期生成几个报告;在我们笔记本的第一个单元格中,我们可以从一个环境变量中提取这些信息,我们将其命名为REPORT_DATE%env line magic 使得将环境变量的值赋给 Python 变量变得很容易。

然后,要运行笔记本(在 UNIX 系统上),我们可以这样做:

REPORT_DATE=2018-01-01 jupyter nbconvert --to html --execute report.ipynb

因为所有的环境变量都是字符串,所以我们必须解析它们以获得我们想要的数据类型。例如:

A_STRING="Hello, Tim!" AN_INT=42 A_FLOAT=3.14 A_DATE=2017-12-31 jupyter nbconvert --to html --execute example.ipynb

我们简单地解析如下:

解析日期肯定不如其他常见的数据类型直观,但是像往常一样,Python 中有几个选项。

在 Windows 上

如果你想设置你的环境变量并在 Windows 上用一行代码运行你的笔记本,那就没那么简单了:

cmd /C "set A_STRING=Hello, Tim!&& set AN_INT=42 && set A_FLOAT=3.14 && set A_DATE=2017-12-31&& jupyter nbconvert --to html --execute example.ipynb"

敏锐的读者会注意到上面定义了A_STRINGA_DATE后少了一个空格。这是因为尾随空格对 Windows set命令很重要,所以虽然 Python 可以通过首先去除空格来成功解析整数和浮点数,但我们必须更加小心我们的字符串。

Papermill 参数化

使用环境变量对于简单的用例来说是很好的,但是对于任何更复杂的情况,有一些库可以让你把参数传递给你的笔记本并执行它们。GitHub 上 1000 多颗星,大概最受欢迎的是 Papermill ,可以装pip install papermill

Papermill 将一个新的单元注入到您的笔记本中,该单元实例化您传入的参数,为您解析数字输入。这意味着您可以直接使用变量,而不需要任何额外的设置(尽管日期仍然需要被解析)。或者,您可以在笔记本中创建一个单元格,通过单击“查看>单元格工具栏>标签”并将“参数”标签添加到您选择的单元格中,使定义您的默认参数值。

我们之前生成 HTML 文档的例子现在变成了:

papermill example.ipynb example-parameterised.ipynb -p my_string "Hello, Tim!" -p my_int 3 -p my_float 3.1416 -p a_date 2017-12-31 jupyter nbconvert example-parameterised.ipynb --to html --output example.html

我们用-p选项指定每个参数,并使用一个中间的笔记本,以便不改变原始的。完全有可能覆盖原来的example.ipynb文件,但是记住 Papermill 会注入一个参数单元格。

现在,我们的笔记本电脑设置简单多了:

到目前为止,我们短暂的一瞥只揭示了造纸厂的冰山一角。该库还可以跨笔记本执行和收集指标,总结笔记本的集合,并提供一个 API 来存储数据和 Matplotlib 图,以便在其他脚本或笔记本中访问。在 GitHub 自述里都有很好的记载,这里就不需要赘述了。

现在应该清楚的是,使用这种技术,可以编写 shell 或 Python 脚本,这些脚本可以批量生成多个文档,并通过像 crontab 这样的工具进行调度,从而自动按计划运行。强大的东西!

造型笔记本

如果您正在寻找笔记本的特定外观,您可以创建一个外部 CSS 文件并用 Python 加载它。

这是因为 IPython 的 HTML 对象作为原始 HTML 直接插入到单元格输出 div 中。实际上,这相当于编写一个 HTML 单元格:

为了证明这一点,让我们使用另一个 HTML 单元格。

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

使用 HTML 单元格一两行就可以了,但是像我们第一次看到的那样,加载外部文件通常会更干净。

如果你想一次定制你所有的笔记本,你可以直接将 CSS 写入 Jupyter config 目录下的~/.jupyter/custom/custom.css文件中,尽管这只有在你自己的电脑上运行或转换笔记本时才有效。

事实上,所有上述技术也适用于转换成 HTML 的笔记本,但是不能用于转换成 pdf 的笔记本。

要探索你的样式选项,请记住 Jupyter 只是一个 web 应用程序,你可以使用浏览器的开发工具在它运行时检查它,或者研究一些导出的 HTML 输出。你会很快发现它的结构很好:所有的单元格都用cell类表示,文本和代码单元格同样分别用text_cellcode_cell表示,输入和输出用inputoutput表示,等等。

GitHub 上也有各种不同的 Jupyter 笔记本流行的预设计主题。最流行的是 jupyterthemes ,可以通过pip install jupyterthemes获得,它和运行jt -t monokai设置“monokai”主题一样简单。如果你正在寻找 JupyterLab 的主题,GitHub 上也出现了越来越多的选项。

隐藏单元格

虽然隐藏笔记本中有助于其他人理解的部分是不好的做法,但你的一些单元格对读者来说可能并不重要。例如,您可能希望隐藏一个向笔记本添加 CSS 样式的单元格,或者,如果您希望隐藏默认的和注入的 Papermill 参数,您可以修改您的nbconvert调用,如下所示:

jupyter nbconvert example-parameterised.ipynb --to html --output example.html --TagRemovePreprocessor.remove_cell_tags="{'parameters', 'injected-parameters'}"

事实上,这种方法可以选择性地应用于笔记本中的任何标记单元格,使[TagRemovePreprocessor](https://nbconvert.readthedocs.io/en/latest/config_options.html) 配置非常强大。顺便说一句,在你的笔记本里还有很多隐藏单元格的方法。

使用数据库

数据库是数据科学家的面包和黄油,所以平滑你的数据库和笔记本之间的接口将是一个真正的福音。 Catherine DevlinIPython SQL magic 扩展让您可以用最少的样板文件将 SQL 查询直接写入代码单元格,并将结果直接读入 pandas DataFrames。首先,继续:

pip install ipython-sql

安装好软件包后,我们通过在代码单元中执行以下魔术来开始:

这将加载我们刚刚安装到笔记本中的ipython-sql扩展。让我们连接到一个数据库!

'Connected: @None'

这里,为了方便起见,我们只是连接到一个临时的内存数据库,但是您可能希望指定适合您的数据库的细节。连接字符串遵循 SQLAlchemy 标准:

dialect+driver://username:password@host:port/database

你的可能看起来更像postgresql://scott:tiger@localhost/mydatabase,其中驱动是postgresql,用户名是scott,密码是tiger,主机是localhost,数据库名是mydatabase

注意,如果将连接字符串留空,扩展将尝试使用DATABASE_URL环境变量;在上面的脚本执行部分阅读更多关于如何定制的信息。

接下来,让我们从之前使用的 Seaborn 的 tips 数据集快速填充我们的数据库。

* sqlite:// 'Persisted tips'

我们现在可以在数据库上执行查询。注意,我们可以对多行 SQL 使用多行单元格魔术%%

* sqlite:// Done.

您可以通过在查询前加上冒号,使用局部范围的变量来参数化查询。

* sqlite:// Done.

我们的查询的复杂性不受扩展的限制,因此我们可以轻松地编写更具表达力的查询,比如查找账单总额大于平均值的所有结果。

* sqlite:// Done.

如您所见,转换成熊猫DataFrame也很容易,这使得从我们的查询中绘制结果变得轻而易举。让我们来看看 95%的置信区间。

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

ipython-sql扩展还集成了 Matplotlib,让您可以在查询结果上直接调用.plot().pie().bar(),并可以通过.csv(filename='my-file.csv')将结果直接转储到 CSV 文件中。阅读更多关于 GitHub 自述文件

包扎

从初学者教程开始到这里,我们已经讨论了广泛的主题,并为成为 Jupyter 大师打下了基础。这些文章旨在展示 Jupyter 笔记本广泛的使用案例以及如何有效地使用它们。希望您已经为自己的项目获得了一些见解!

我们还可以用 Jupyter 笔记本做很多其他的事情,比如创建交互控件和图表,或者开发自己的扩展,但是让我们把这些留到以后再说。编码快乐!

原载于data quest . io

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值