TowardsDataScience-博客中文翻译-2020-八十九-

TowardsDataScience 博客中文翻译 2020(八十九)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

在线课程、自动化教育和数字化学位

原文:https://towardsdatascience.com/online-courses-automating-education-and-digitalizing-degrees-at-uc-berkeley-cs-b45dfdd8bcb0?source=collection_archive---------38-----------------------

加州大学伯克利分校计算机科学教学的启示。

我们要去哪里。照片由像素皮克斯拜拍摄

一些学校会冒险,一些会领先,一些会保持现状,一些会失败。教学正在转向数字领域,所以我们将会看到更多的数字效果——而我们的机构并不是围绕它而设计的。 这是我免费星期五写的关于机器人学& AI 的文章节选,请看

想想加州大学伯克利分校夏季人工智能导论 CS 188出席情况。我们提供一堂有广泛讨论时间的课,以鼓励世界各地的学生参与,并录制所有的讲座和讨论材料。

  • 入学人数:约 190 人
  • 按天计算的听课人数:120,95,87,75,56,…
  • 讨论出席率反映了这个数字的总和(低参与度和运行理论是,去听讲座的人去讨论,而不是一半一半)。

60%的学生在干什么?他们只是在看录像吗?作为参考,当我去年春天给 800 名注册者(在 Zoom 上)讲授这门课程时,100 人观看了直播,而录像很少达到 250 次观看。450/800 的学生在决赛前都没见过。这是在我们的学生遍布全球之前,作为一名员工,我们对此一无所知,这是一个教育机构的困境。这就引出了重大问题:

  • 大多数学生在做什么?
  • 学生们是否选择将此作为在线课程,他们是否有时间承诺冲突或时区冲突?
  • 大学是否应该在全球课程中适应每个学生的时间偏好?

我想谈三个主题:

  1. 网络课程中的行为,
  2. 这些课程如何倾向于自动化教育,
  3. 以及数字学位的含义。

行为和在线课程:

在线课程对学生来说是一个未知领域。这是一种趋势的融合,即课程中的社区减少,而学生个人的数字参与增加。学生通过有机会参与来学习和感受价值。一篇总结敬业度研究趋势的博客文章切中要害(查看它引用的研究):

研究历史表明,学生参与度(通常定义为对重点领域的关注、对学习的积极参与以及在任务上的时间)与学生成绩之间有很强的相关性。这些相关性在所有层次的教学、所有学科领域以及各种教学活动中都很强。

这是我们无意中争论的问题。当前的大学是为面对面交流而构建的(除了巨大的演讲厅),但这在向在线课程的过渡中没有任何分量。 查看更多关于课堂反应和辍学率方面的参与度和学习之间的联系。

(线上课程大概可以借鉴直播流,比如 3blue1brown )。

缩放室气氛

毫无疑问,学生通过聊天室提问比面对面提问障碍更小,但我认为这留下了一个断层。学生和教师之间微妙的情感暗示存在反馈回路。在你快速浏览了太多的演讲幻灯片后,你无法复制 100 张困惑的脸抬起头看着你的感觉(从经验来说,这是令人畏惧的)。这种不匹配是有后果的。

考虑一下春季时一位 Data 100 讲师(感谢 Vikram )的话:

“我认为助教需要更多的帮助来创造那种(积极参与的)氛围。例如,在教室里,我很容易走到黑板前写出一个例子,但如果我们使用变焦镜头,我就做不到了(即使有 iPad,也不太容易,除非你有 Apple Pencil)。”

这种帮助来自哪里?帮助来自聊天框吗?当考虑面对面提问与缩放聊天提问时,我们会觉得:

“提一个问题并让学生回答真的很容易👍🏽或者👎🏽它在 Zoom 上——但我不确定这些真的有助于培养大量的参与度"

这又回到了我开始的地方。当我们给学生讲课时,他们是在玩被动的缩放游戏,还是这仍然是一种有用的教学形式。

变焦免费下载,学生离开,和平衡

学生们从变焦室进进出出,好像没有社交障碍,这是因为没有——有一个数字按钮。

我想知道的一个问题是:在讨论部分,人们不会离开/不会参与/不会自由浮动的最佳位置是什么?例如,考虑到离开机制(太空或太满)和搭便车效应,在线讨论的最佳学生人数是多少。我的假设是 8-12 名学生,这比面对面讨论少得多(放大了已经存在的效应,因为离开很容易,不参与也很容易)。

问题是,这不能扩大到更大的班级——已经没有足够的教师了!那么,如果学生要看录像,我们还应该主持讨论吗?

学生同步性与员工覆盖率

如果所有内容都被记录下来,无论是在网上还是在出版的笔记本上,那么在一个章节中重复内容的价值就不大了。课程应该设计成完全同步的(学生们互相学习材料)还是涵盖每个学生的偏好?

设置课程时,员工通常希望每个学生都能参加每个选项。通常,唯一的限制是其他课程,现在最大的限制是全球时区。当在学期初设定讨论时间时,问题是覆盖面是一个访问问题还是一个人员配备问题。

  • 访问问题:个别学生是否需要有时间才能参加部分?他们应该有多大的准入压力?
  • 人员配备问题:由于新的分配,我们需要更多的员工还是更分散的员工?

一个关于今年夏天为 CS 188《人工智能导论》设计时间的小故事。

我们使用 Piazza 来查询时区(没有很好的选项,但这不是我们要用的)。不出所料,这显示出 关注太平洋时间,但也有学生认为世界各地的每个时区都是工作时间。我不认为大学里的任何人会想让讨论时间与偏好完全成比例(因为导师很少,四舍五入会将人排除在外),但保证每个学生都有机会的任务是艰巨的。

或者,考虑一下我的朋友、康奈尔大学的大卫·德尔尚教授的方法:他单独录制他的讲座,然后发布,这样那些能赶上讲座时间的学生就没有优势了,现在讲座时间是办公时间。这些设计决策的实施没有来自部门的开销,也没有可供参考的研究。

最小化基于地位的优势

当我们从学生、教师和教授那里得到稀疏的信号时,每个人都需要问的问题是:这对那些没有麦克风来表达他们的关切的代表性不足的群体有什么影响。我想到了两种机制。

  1. 缺乏数字输入的无障碍技术(纽约时报的三篇文章:渴望上学在线学习对大脑的影响公立学校与私立学校)。
  2. 课程材料中的互动方法,例如,在聊天中键入问题,而不是在拥挤的大厅中举手(这可能是一个均衡器,但应得到确认)。

附加注释

a)如果没有面对面的交流网络,在错过截止日期等之后,如何保持员工的可信度?学生在网上或多或少宽容了吗?这是如何逐学期演变的?

b)学校的走廊效应。随机交互有什么好处,对谁有好处?应该有不和谐的渠道来聊天吗?大学能促进这一点吗?网络效应会在每个班级的基础上衰减吗(表明这种联系是持久的),更快(表明经常见到人是重要的),还是更慢(表明有更复杂的效应在起作用)?

照片由像素皮克斯拜拍摄

自动化教育

行业分析师认为教育是最难自动化的行业[ 来源来源 ]。我提炼出这个:我们可以自动化学习,但我们不能自动化教育。教育是一个系统,学习是一门学科。

谁受益于大规模在线开放课程(MOOC ),谁受益于结构化的增量教育?花一秒钟制定你自己的优先事项。

那些想要了解特定主题的人受益于当今的 MOOCs(想想那些学习计算机科学技能的人),但我还没有听说过一个人从在线课程中获得他们的科学能力和批判性思维——那些来自允许自由(辩论深度)的结构化(广度)学习。 人们利用现有的能力,并将其与快速、可用的在线学习相结合,以改变职业或制造产品。

机器人导师

有些人认为机器人导师可以解决这个问题(阅读关于机器人教学),但我认为这离真相非常非常远。机器人可以提供信息,但无法处理教学的复杂交互。在线课程很大程度上是机器人试图在狭窄的轨道上教人们——这不太合适。现在 AI 的语言处理能力有限,也没有内容创作的 AI,所以我真的怀疑错综复杂的自动学习系统会有可比性(简单的还是有价值的是的)。

对机器人来说很容易:

  • 给作业评分并生成现有问题的排列。
  • 基于表现的时间调整材料:将表现分数保持在一个范围内,如果领先就加速,如果落后就减速。
  • 作为教育路径的树的分枝。

对机器人来说很难:

随着大学变得越来越像在线课程,教育系统将更像只是学习东西,而不是产生智能过程。这是我害怕的滑坡。

更多相关文章:佛兰德斯的教育/文化权衡一项关于非裔美国学生的教育文化研究《华盛顿邮报》一篇关于教育超越学习的文章

数字度数

写这篇文章时,我收到了加州大学伯克利分校的一封电子邮件,称校园内的 COVID19 病例数量从 2020 年 7 月之前的累计 23 例跃升至上周的 47 例新病例(追溯至希腊生活党)。我认为,在未来 12 个月内,大型城市中心的公立学校系统和大学将很难开学。

巨人之间的分歧

这是一个简短的部分,因为它大多只是最近发生的事情。许多学校宣布了他们秋季的计划。两个大的例子是哈佛上线康奈尔开学。康奈尔大学令人惊讶的声明是基于一项调查,该调查显示,如果上网,大多数学生仍然愿意来校园(就校园对他们的意义而言,这是学生的一个重要价值陈述)。康奈尔大学将利用这种物理存在来监测病例并提供医疗帮助,而不是让学生在没有正式开放的情况下呆在校园和周围。

开放的能力来自于一个孤立的位置。像哈佛这样的城市的学校将很难开学(尽管哥伦比亚大学已经说过了,但我认为这是一种风险)。

学费价格、有效投诉和教育品牌

你知道,当他们上网时,有很多关于教育价值的笑话,有几个原因让这很难——困难在于消除不同个人接受的不同价值观的歧义。一些学生完全受益于品牌(和关系——典型的哈佛学生运动员),这将保证维持学费(或在某些学校提高学费),但许多学生确实受益于教育(每年价值低于 5 万美元)。

这种差距是无法量化的,但当他们不进入一些学校,一些学校关闭,一些学校被迫创新(可能会削减学费,并以转校为目标以增加收入)时,个人会清楚地表明这一点。

数字化大学?

我将带着一个想法离开这篇文章:会有任何中等水平的大学选择以名誉为代价增加数字化招生吗?这个过程是:大幅降低学费(~10%),使转学接受率高,官僚负担低。当课堂材料都是数字化的且易于复制时,这会从其他学校偷走学生吗?

[## 自动化大众化

一个关于机器人和人工智能的博客,让它们对每个人都有益,以及即将到来的自动化浪潮…

robotic.substack.com](https://robotic.substack.com/)

在线深度学习(ODL)和对冲反向传播

原文:https://towardsdatascience.com/online-deep-learning-odl-and-hedge-back-propagation-277f338a14b2?source=collection_archive---------27-----------------------

在线学习是一种 ML 方法,其中数据是按顺序提供的,我们使用它来预测每个时间步的未来数据。在线深度学习非常具有挑战性,因为它不能使用反向传播。

简介

由于深度神经网络的主要概念是在批量设置中通过反向传播进行训练,因此要求数据在离线设置中可用。因此,该方案对于许多实际情况来说是不相关的,在这些情况下,数据按顺序到达并且不能被存储。例如股票、车辆位置等等。ODL 非常具有挑战性,因为它不能使用反向传播。两年前,Sahoo 等人(2018)提出了在线学习和深度学习之间的差距,他们声称“如果没有深度的力量,就很难学习复杂的模式”。他们为 ODL 提出了一个新颖的框架(将在后面讨论)。

作者图片

在线学习概述(OL)

OL 是一种 ML 方法,其中数据是按顺序提供的,我们使用它来预测每个时间步的未来数据。此外,在 OL 中,我们实时更新预测器。Shai Shalev-Shwartz 认为:“OL 是在已知(可能是部分)前面问题的正确答案和可能的额外可用信息的情况下,回答一系列问题的过程”。OL 的家族包括在线凸优化,(这导致了高效的算法),当系统观察到损失值但没有观察到实际真实值时的有限反馈模型,等等(更多信息我推荐阅读参考文献[2])。

深入

反向传播的局限性和“由浅入深”的概念

在线学习可以直接应用于深度神经网络(在线反向传播)。然而,他们遭受许多收敛问题(消失梯度等)。).此外,网络的最佳深度(通常)是未知的,这使得问题更加困难。最近有作品改编了“由浅入深”的概念。根据这个概念,浅层模型比深层模型收敛得更快。为了实现这一概念,成本函数控制层数(陈等)。还有许多其他的概念,但让我们坚持这一个。

陈等,“网络 2 网:通过知识转移加速学习”

该体系结构和许多其他体系结构被设计成基于网络输出/最深层来优化成本函数。它们不能总是产生良好的在线性能,因为最深层需要有意义的时间来收敛。对于所讨论的在线学习概念,这种基于反向传播的深度学习技术不是最佳的。

对冲反向传播(HBP)

Sahoo 等人提出了一种值得注意的方法。在他们的工作中,他们建议在应用 HBP 时,网络深度会根据数据本身自动调整。这种对冲方法有一些重要的性质,如:1。根据分类器在深度上的表现确定网络深度(专家建议)。2.使用浅层神经网络架构进行初始化——更加鲁棒。3.它允许实时算法不断学习和适应(更多可用数据)。

以下图表摘自 Sahoo 等人的论文,对 HBP 进行了精彩的描述:

D.Sahoo 等人,“在线深度学习:动态学习深度神经网络”

该图描述了对冲反向传播背景下的在线深度学习框架。蓝线代表前馈流,绿线代表反向传播方法。重要的橙色线代表预测时间内套期保值方法遵循的(softmax)输出。更多详细信息,请参考原论文。

自主深度学习

去年 1 月(2020 年),Ashfahani 和 Pratama 出版了一本名为《自主深度学习:动态环境下的持续学习方法》的巨著。他们提到了许多 DL 方法的静态和离线性质,并提出了一种新的连续学习算法,除了漂移识别机制之外,该算法还可以确定网络深度。他们建议为每一层都包含一个产生局部输出的 softmax 层。然后,使用动态投票计算全局输出。作者在他们的模型中指出了四个主要贡献:1 .不同深度的网络结构(每个隐藏层中的 softmax 层)。2.自动生成新的隐藏节点。3.基于漂移检测的网络适应深度。4.适应新信息,同时重温旧信息。它可能会解决“灾难性遗忘问题”。

学习政策。“自主深度学习:动态环境下的持续学习方法”

总结 ADL 概念,方案宽度的调整基于方差和偏差的估计,而深度根据漂移检测方法确定(如上图所示)。

QActor:针对带噪声标签的 Strem 数据的在线主动学习

我想讨论的最后一个主题是嘈杂的现实生活问题。最近,T. Younesian 等人(2020)的一部作品发表了。它处理在线噪声标记数据的问题,这可能导致任何 ODL 系统的不良性能。在这项工作中,他们专注于带有极其嘈杂标签的流数据,其中超过一半的标签是错误的。主要的挑战是选择信息丰富的数据,以便纳入学习框架。QActor 设计的在线主动学习算法将主动学习与一定的质量模型相结合。该模型基于不同的不确定性度量过滤掉有噪声的标签。这是原始论文工作流程的概述:

QActor:针对带噪声标签的流数据的在线主动学习——概述

总结

总而言之,在线深度学习的领域相当新,并且受到许多非常规问题的困扰,例如我们都熟悉的离线设置中的反向传播,并且应该适合在线设置。我们讨论了一些最近处理这些问题的方法,如自主深度学习、对冲反向传播等。最后,我们提到了在线设置中的噪声标记示例的问题。

更多故事请关注我,别忘了鼓掌!

— — — — — — — — — — — — — — — — — — — — — — — — —

关于作者

Barak 获得了以色列理工学院的航空工程学士学位(2016 年)、硕士学位(2018 年)以及经济和管理学士学位(2016 年,成绩优异)。他曾在高通工作(2019-2020),在那里他主要研究机器学习和信号处理算法。巴拉克目前正在海法大学攻读博士学位。他的研究兴趣包括传感器融合、导航、深度学习和估计理论。

访问我的个人网站:【www.Barakor.com

领英【https://www.linkedin.com/in/barakor/ 领英

推特:巴拉克 2

— — — — — — — — — — — — — — — — — — — — — — — — —

参考文献。

[1] D. Sahoo 等,“在线深度学习:动态学习深度神经网络”。新加坡管理大学信息系统学院。ArXiv,2018。

[2] Shalev-Shwartz,Shai。"在线学习和在线凸优化."机器学习的基础和趋势4.2(2012):107–194。

[3]陈等.“网络 2 网:通过知识转移加速学习” arXiv 预印本 arXiv:1511.05641 (2015)。ICLR (2016 年)。

[4] N. Gravin 等人,“在专家建议下实现预测的最佳算法”。ArXiv,2014。

[5]阿什法哈米和普拉塔马。“自主深度学习:动态环境的持续学习方法”。ArXiv,2020。

[6] B.Bfulb 等《灾难性遗忘:仍是 DNNs 的问题》,ArXiv 2019。

[7] T .尤内西安。“QActor:带噪声标签的流数据的在线主动学习”。ArXiv,2020。

只有 R 重要:数学流行病学和感染率

原文:https://towardsdatascience.com/only-r-matters-mathematical-epidemiology-and-infection-rate-2d890386a992?source=collection_archive---------54-----------------------

Hazy 的数据科学

这一简短的时间、死亡和疾病回顾将帮助你理解图论和传染率的重要性。

数学流行病学的历史与现代疫情有什么关系?一切真的。除了我们用图形表示它的方式——也就是用 Graph——以及它处理更大的、影响全球的数据集的能力,没有太大的变化。希望这篇文章能给你一本入门书,帮助你开始理解我们今天在试图解决像新冠肺炎这样的数学问题时所面临的斗争。

数学流行病学简史

流行病的数学模型可以追溯到 18 世纪瑞士数学家丹尼尔·伯努利,他显然不满足于力学、统计学和经济学的基础工作,还创建了第一个已知的关于流行病传播的数学模型。他的模型根据感染率和死亡率给出了预期寿命,适用于当时在整个欧洲流行的天花爆发。

另一种疾病启发了许多人所认为的流行病学的基础,那就是霍乱。由于基础设施不足、过度拥挤以及缺乏准确的细菌和感染医学模型,霍乱爆发在 19 世纪的伦敦是一种非常常见的现象。现在看来这很了不起,但当时有两种相互竞争的理论:细菌理论和瘴气理论。瘴气理论认为,霍乱和其他疾病是由空气中传播的腐烂有机物引起的——考虑到当时伦敦市中心普遍存在的污染,以及首都许多地区缺乏污水处理系统,这可能不是一个像今天这样奇怪的理论。

从很多方面来说,约翰·斯诺是 T2 的第一位数据科学家。他绘制了一张 1854 年在布罗德街附近的索霍区爆发的传染病地图。他拒绝了流行的瘴气理论,而是专注于追踪霍乱在供水系统中的传播。他使用现在被称为 Voronoi 图的方法追踪感染。最终,他认定一个特殊的水泵可能是霍乱爆发的源头。他的工作为细菌理论提供了经验证据,并确定水供应是霍乱的主要传播媒介。他的工作还导致了公共卫生立法的重大修改,涉及提供清洁水和安全废物处理。在索霍区有一家酒吧,靠近水泵,水泵是以他的名字命名的宽街传染病的发源地。

自从这项开创性的工作以来,许多流行病学模型被开发出来,包括微分方程系统、随机过程和那些基于图形的模型。我们将看看图论如何作为疾病传播的模型来应用。

什么是图?

图论作为数学探究的对象可以追溯到一个被称为柯尼希斯堡七桥的问题。这是一个听起来很简单的问题,但是它的解决方案让莱昂哈德·欧拉发展了一种全新的数学理论,以便得到一个明确的答案。在解决这个问题的同时,欧拉发明了图论;这是欧拉做了相当多的事情,对物理学、天文学、地理学、逻辑学、拓扑学、数论、微积分以及许多其他领域做出了根本性的贡献。

两条河流穿过柯尼斯堡市,七座桥梁横跨其间。欧拉全神贯注的问题,并导致了图论的发现,是创建一个步行穿过每座桥一次,但只有一次。下面是柯尼斯堡的地图,蓝色是河流,红色是桥梁。

柯尼斯堡的桥梁。来源:maa.org

在创立/发现了图论之后,欧拉表明不可能通过穿过每座桥一次来创建一次柯尼斯堡之旅。

图由两个不同的对象组成,顶点边。一个顶点可以在一张纸上画成一个点或一个圆。边是可以在两个顶点之间画出的连接它们的线。代表柯尼斯堡桥梁的图表如下所示。

柯尼斯堡桥图: GNU 自由文档许可

图论已被证明是数学问题的丰富来源,对纯数学和应用数学的许多领域做出了贡献,并扩散到许多其他科学和技术领域。

erdős–rényi 图

1959 年,保罗·ERdős 和阿尔佛雷德·雷尼发表了一个创建随机图的模型,被恰当地称为 Erdős-Rényi 图或 er 图。Erdős 和雷尼研究了几种生成随机图的方法。

G(n,p) 模型中,通过随机连接顶点来构建图。以概率 p 在两个顶点之间画一条边。这个概率随着从 0 增加到 1,给出了图中任意两条边将被连接的可能性。

不同的 p 值的效果可以在下图中看到。两者都有 50 个顶点,但是连接它们的边的概率不同。对于上图,我们有 p= 0.05,对于下图,我们有 p= 0.2。

具有 n =50 个顶点并且 p =0.05 的 ER 图

ER 图,也是用 n=50 个顶点,但用 p=0.2

图表和流行病

图论的许多应用之一涉及流行病的传播。

让我们看看如何用图表来建立一个原始的流行病学模型。(数学生物学家和流行病学家使用的真实模型比一个简单的 ER 随机图复杂得多;但是,它仍然是许多此类模型的基础)。

让我们考虑由 n 个个体组成的群体。

一个随机的个体——在图论中是一条——被一种传染性媒介感染,例如,这种媒介可能是一种病毒。

如果我们假设这种相互作用的网络可以用 ER 图来描述,那么概率 p 表示从一个人到另一个人(一个顶点到另一个顶点)的感染已经发生的可能性。

这将代表一个 SI 模型,来自易感-感染。当一个人被感染时,他们可以以一定的概率传递感染、病毒、细菌。

我们创建一个 ER 图,在图中的顶点之间有随机连接(边)。我们也随机选择一个顶点——我们人口中的一个感染者。我们假设随机个体只有在他们有联系的情况下才能将感染传递给另一个个体,并使用相同的 p 值来确定他们是否传递感染。

然后,我们允许这个模型运行多个时间步长, T= 20。感染在人群中传播,从一个人传播到另一个人,并输出被感染的人群比例。

我们对模型进行多次迭代( N= 1000 次试验),然后对输出进行平均(感染人群的比例)。

下图显示了感染概率p∈[0.01,0.05,0.1,0.5]的各种不同值在 ER 图上的传播情况。,2, 0.4, 0.6, 0.8].

具有不同传染概率的 ER 图上传染病的传播。

这类似于最近媒体引用的关于新冠肺炎科拉那病毒的感染率。R 是感染率,即一个人将其感染传给另一个人的概率。

从图中可以看出,很明显,感染率越高,受感染的人口比例就越高。

给定这样一个简单的模型,我们能对感染率和概率之间的关系说些什么?

让我们以稍微不同的侧重点重新审视一下这个模型。我们又有了一个规模为 N. 的人口,人口中的每个人都由图中的一个顶点来表示。如果感染在两个顶点 ij 之间传播,则可以通过在这两个顶点之间放置一条边来构建该图。图中感染人数可以认为是图的连通分支。一个合理的问题是:这个组件会变得多大?

从流行病(或者说全球大流行)的角度来看,坏消息是 ER 随机图模型经常表现出所谓的 巨型组件,其中一个连通组件包含整个图的一个大的、有限的部分!

如果我们有 p ≤ ( 1 — ϵ)/ N,其中ϵ > 0,那么很有可能所有的连通分量的大小都是 O(log N)的量级,我们没有一个巨型分量。然而,如果我们有 p ≥( 1 +ϵ)/ N,那么很有可能,我们将有一个单一的,巨大的组件。

从我们的(公认简单的)ER 感染模型来看,我们人口的很大一部分将被感染。实际上,这将是一场流行病,大多数人都会受到感染。

由于我们才刚刚开始审视和理解我们当前的疫情,这一历史上的数学、流行病学之旅强调了一个关键事实,即我们真正能控制的只是感染率。如果没有任何降低感染概率的措施,传染病将会以指数速度在人群中传播。

ONNX:轻松交流深度学习模型

原文:https://towardsdatascience.com/onnx-easily-exchange-deep-learning-models-f3c42100fd77?source=collection_archive---------26-----------------------

ONNX(开放式神经网络交换格式)及其潜在应用的实践演练

面条金姆Unsplash 上的照片

介绍

ONNX(开放式神经网络交换格式)是一种旨在表示任何类型的机器学习和深度学习模型的格式。

支持框架的一些例子有:PyTorch、TensorFlow、Keras、SAS、Matlab 等等。这样,ONNX 可以更容易地将模型从一个框架转换到另一个框架。此外,使用 ONNX.js,我们可以轻松地在线部署任何以 ONNX 格式保存的模型。

在图 1 中,使用 ONNX.js 在线部署了一个简单的变型 Autoencoder PyTorch 模型示例,以便按需进行推理。在我的个人网站上的链接可以找到这种部署模式的完整工作示例。

1:使用 ONNX.js 的在线 VAE

ONNX 的主要目标是将所有不同的人工智能框架聚集在一起,并尽可能容易地使它们相互通信,以便构建可以在任何类型的平台或硬件上支持的更好的模型。

将模型转换为 ONNX

将模型转换成 ONNX 格式相对容易。我们所要做的就是,确保我们的训练模型处于评估模式,并创建一个简单的虚拟输入,其形状与我们的模型预期的相同。

下面是 PyTorch 中的一个简单示例。在这个简单的例子中,我们实例化了一个变化的 Autoencoder 模型,加载其预训练的权重,将其置于评估模式并创建一个示例输入。使用这些参数,我们可以创建 ONNX 文件。

import torchpre_trained = VAE(encoder, decoder)
pre_trained.load_state_dict(torch.load('trained.pt'))
pre_trained.eval()ex_input = torch.zeros(1, 28, 28)torch.onnx.export(pre_trained, ex_input, "onnx_model.onnx")

然后,我们的 ONNX 文件将由我们的模型的图形表示构成,该图形表示可用于将我们的模型转换为其他类型的框架(通过重新创建图形中的指令)或使用我们训练的模型进行在线推断。ONNX 目前的一个局限是,并不是所有的操作(如定制损失函数、特定的神经网络层等)都被所有的框架所支持。PyTorch 支持的所有操作符列表可在链接中找到。

在 ONNX 库的开发过程中,开发了不同的操作集版本(【op set _ version】)。因此,通过指定我们最喜欢的 opset_version 作为导出函数的参数,我们可以决定我们想要默认可用的操作集。

使用 ONNX.js 部署模型

拥有在线模型的一些好处是:

  • 我们减少了延迟,因为数据不必从服务器来回发送。
  • 不向服务器发送数据也增加了隐私,因为用户数据不会被远程访问。
  • 网站可以只用静态文件来建立,这使得可扩展性不成问题。

有不同的技术可用于在线部署模型,如 Tensorflow.js 和 ONNX.js。使用 Tensorflow.js 的主要优势之一是可以在线训练模型(使用 ONNX.js 则不是可用选项)。另一方面,ONNX.js 比 Tensorflow.js 更高效,因此在进行在线推理时速度更快。

下面显示了一个简单的模板,可以用来开始使用 ONNX.js。在这种情况下,假设存在一个名为 getInputs() 的函数能够自动为我们的模型创建输入数据。

<html>
  <head> </head>
  <body>
    <!-- Loading ONNX.js library -->
    <script      src="https://cdn.jsdelivr.net/npm/onnxjs/dist/onnx.min.js">
    </script>
    <script>
      // Creating a session
      const sess = new onnx.InferenceSession();
      // Loading the created ONNX file
      sess.loadModel("onnx_model.onnx").then(() => {
      // Getting an imput for our model from an example function 
      const input_data = getInputs();
      // Feeding the input to our model and fetching the output
      sess.run(input_data).then((output) => {
      // Storing and displaying the output prediction 
      const outputTensor = output.values().next().value;
      console.log(`Model prediction: ${outputTensor.data}.`);
        });
      });
    </script>
  </body>
</html>

从这个示例模板开始,使用标准的 Javascript 功能,可以开发复杂的应用程序。

如果您正在寻找创建模型、将其转换为 ONNX 然后在线部署的完整示例,可以在 this my Github 资源库中找到。此外,使用 ONNX.js 部署的示例模型集合可在 ONNX.js 官方网站此链接获得。

联系人

如果你想了解我最新的文章和项目,请通过媒体关注我,并订阅我的邮件列表。以下是我的一些联系人详细信息:

ONNX:防止框架锁定

原文:https://towardsdatascience.com/onnx-preventing-framework-lock-in-9a798fb34c92?source=collection_archive---------27-----------------------

介绍如何使用 ONNX 标准实现深度学习框架之间的互操作性。

里克·梅森在 Unsplash 上的照片

在这篇博客中,我们将看到什么是 ONNX 标准,它的组成部分以及如何在不同的深度学习框架之间进行互操作。本博客将讨论以下部分:

  • 简介
  • ONNX 是什么?
  • 什么是 ONNX 运行时?
  • 互操作性:从 PyTorch 到其他框架

所以让我们开始吧!

介绍

PyTorchTensorflowCaffe2MXNet 等,只是今天开发深度学习模型最流行的一些框架。尽管这些框架之间的共同点是深度学习模型的培训和调整,但“它们如何做”以及它们针对的领域是主要的区别点。一些框架更加面向研究(如 PyTorch ),而另一些则主要用于设备部署(如 Tensorflow ),同样,一些框架的设计架构基于静态图(如 TensorflowCaffe2 ),而其他框架则基于动态图(如 PyTorch )。

显然,这些框架中的每一个都提供了不同于其他框架的优势,然而,我们如何将这些优势联系起来呢?我们如何互操作不同的框架?我们如何用框架“ x ”优化一个模型,并在为框架“ y ”优化的架构中部署它?嗯,这种类型的互操作性的实现要感谢 ONNX 标准和 ONNX 运行时(我们将在后面看到)。在图 1 中,描述了由 ONNXONNX 运行时解决的问题。

图一。ONNX 和 ONNX 运行时解决的问题|作者图片|取自平面图标的图标

ONNX 已经开始打破框架和硬件架构之间的依赖。 ONNX 寻求成为不同深度学习框架之间可移植性和互操作性的默认标准。那么,让我们更详细地看看什么是 ONNX 和什么是 ONNX 运行时

ONNX 是什么?

ONNX 是首字母缩写,代表 开放式神经网络交换 。它指的是促进深度学习框架之间互操作性的标准模型。ONNX 标准始于 2017 年,由微软、脸书和亚马逊三大巨头发起。基本想法是提出一个标准,允许已经众所周知的深度学习框架之间的可移植性和互操作性。

开放神经网络交换(ONNX) 是一个开放的生态系统,使人工智能开发者能够随着项目的发展选择正确的工具[1]。

ONNX 已经开始简化机器学习模型从研究到生产的生命周期,因为一些框架更适合原型化和优化模型,而其他框架则提供加速部署到不同设备的工具,这是很常见的。因此,需要特别提及的是,目前 ONNX 已经具备支持推理的能力,即我们可以在框架“ a 中训练一个模型,在框架“ b 中进行推理。图 2 提供了对框架互操作性的可视化描述。

图二。ONNX 互操作性|作者图片|取自原始来源的徽标

ONNX 规范针对以下三个组件来实现互操作性:
1 .一种可扩展计算图模型的定义。
2。标准数据类型的定义。
3。内置运算符的定义。

到目前为止,已经有几个框架集成了一个扩展,能够在 ONNX 规范下导出模型,同样,还没有集成导出模块的框架利用了工作良好的包装器。

好了,到目前为止,我们已经知道为什么框架之间的互操作性需要一个标准,同样我们也已经知道 ONNX 在这个生态系统中的参与情况,现在我们必须知道" ONNX Runtime "是什么,以及它在行业中产生的巨大影响,所以让我们开始吧!

什么是 ONNX 运行时?

ONNX Runtime 是一个多平台加速器,专注于训练和模型推理,与最常见的机器学习&深度学习框架【2】兼容。换句话说, ONNX 运行时就是 ONNX 标准的实现。

ONNX 运行时的出现是因为需要一个接口来加速不同硬件架构中的推理。在 ONNX 运行时之前,将主要针对基于 CUDA 的架构优化的模型部署到基于 NUPHARnGraphOpenVINO 的架构等是非常昂贵的。换句话说,在框架和硬件架构之间存在着一种依赖关系,模型就是为这种依赖关系而优化的。有了 ONNX 标准和 ONNX 运行时加速器,框架和硬件架构之间的互操作性的大门就敞开了。

ONNX 运行时的一些主要优势是:

  • 推理性能提高,推理时间大大减少。
  • 减少培训时间
  • 用 Python 开发和训练模型,并在基于 C、C ++或 Java 的应用程序中部署。

很好,现在我们知道了 ONNXONNX 运行时互操作性和可移植性方面的影响,让我们来看一个例子!

互操作性:从 PyTorch 到其他框架

在下面的例子中,我们将演示如何使用 ONNX 标准,以便能够在不同的深度学习框架之间进行互操作。

示例的架构给出如下,我们将在 PyTorch 中训练一个分类器,然后我们将使用这个训练好的模型在 TensorflowCaffe2ONNX 运行时中进行推理。该示例的架构如下所示:

图 3。示例架构|作者图片|取自平面图标的图标

开始吧!

如果你想看看完整的代码,这是实现:https://github.com/FernandoLpz/ONNX-PyTorch-TF-Caffe2。随意克隆或者叉!

首先,我们将创建通用数据,其想法是创建一个虚拟模型,因此让我们定义以下生成器,它将返回训练和测试数据:

代码片段 1。数据生成程序

现在,让我们定义我们的虚拟模型的结构以及正向函数。我们基本上定义了两个线性层,这就够了。

代码片段 2。PyTorch 模型定义

完美!到目前为止,我们已经有了通用数据以及我们的虚拟模型,是时候训练模型了!

代码片段 3。PyTorch 培训模式

正如我们所看到的,训练阶段非常简单,不需要太多的解释。那么让我们继续下面的,是时候将我们的模型导出到 ONNX 标准了,因为这个 PyTorch 已经为我们提供了一个扩展来导出 ONNX 格式的模型,让我们看看我们是怎么做的!

代码片段 4。导出到 ONNX

我们先来看第 4 行的 if-else 语句。我们正在定义一个"虚拟输入,因为 ONNX 需要遍历由 PyTorch 定义的整个图形,这样 ONNX 将负责跟踪每个图形实例中定义的每个层和参数。在这种情况下,我们使用变量定义一个通用输入,或者在它的情况下,我们将虚拟输入定义为训练中使用的真实输入。

稍后,在第 9 行和第 10 行中,我们定义了我们将分配给图中每个层的名称,这些名称将由 ONNX 生成,否则 ONNX 将使用通用名称。

最后,在第 13 行中,我们使用了 PyTorchONNX 扩展,我们将训练好的模型、虚拟输入和分配给图中每个元素的名称作为参数传递。查看第 22 行中传递的参数很重要,因为推理张量在维度大小上可能有一些变化(通常是指批量大小的维度),我们将这样的维度定义为" dynamic ",因此在推理时,我们可以传递任何批量大小,而不是训练原始模型时使用的那个。

嗯,到目前为止,我们已经在 PyTorch 中训练了一个模型,并保存在 ONNX 标准下,现在我们看看如何用不同的框架加载这个模型来进行推理。

ONNX 运行时推理

为了用 ONNX 运行时执行推理,我们需要导入ONNX 运行时库,然后我们只需要用 onnx 模块加载 onnx 模型并生成预测。

代码片段 5。ONNX 运行时推理

咖啡 2 推断

为了使用 caffe2 框架进行预测,我们需要为作为后端工作的 onnx 导入 caffe2 扩展(类似于 tensorflow 中的会话),然后我们将能够进行预测。

代码片段 6。咖啡 2 推断

张量流推理

要使用 Tensorflow 进行预测,需要使用 onnx_tf 模块,该模块提供一个包装器(模拟会话),以便进行预测。

代码片段 7。张量流推理

恭喜你!我们到达了博客的结尾。

如果你想看看完整的代码,这是 https://github.com/FernandoLpz/ONNX-PyTorch-TF-Caffe2 的实现:。随意克隆或者叉!

结论

在这篇博客中,我们解释了 ONNX 标准产生的必要性。我们也提出了 ONNX 如何帮助防止框架锁定的想法。另一方面,我们解释了 ONNX 标准与 ONNX 运行时如何让我们减少深度学习生命周期中的时间,因为它加快了培训阶段和部署阶段之间的联系。
最后,我们看到了一个例子,使用 ONNX ,我们可以在给定的框架中训练一个模型,并在其他框架中执行推理。

参考

[1]https://github.com/onnx/onnx

https://microsoft.github.io/onnxruntime/docs/

哎呀!预测视频中的无意动作

原文:https://towardsdatascience.com/oops-predicting-unintentional-action-in-video-87626aab3da3?source=collection_archive---------41-----------------------

理解运动的意向性

有意与无意的行动1

实际上,人类是不完美的代理人,他们的行为可能是不稳定的和不可预测的。虽然以前的研究主要集中在人类活动识别和预测上,但哥伦比亚大学的研究人员采用了一种新的方法——分析目标导向的人类行动。戴夫·爱泼斯坦、袁波·陈和卡尔·冯德里克在《哎呀!预测视频中的无意动作1:

  1. 提出 3 项新任务:分类、定位和意外行为预测
  2. 引入新的基准数据集:大型、公共和(部分)注释的(光流、无意运动的时间戳等)
  3. 对比无意动作中级感知线索:视频速度(新)、视频上下文【2】、事件顺序【3】

运动的意向性

许多研究试图模拟人类行为的物理和原子后果,但很少有人试图理解运动背后的意图。本文区分有意运动和无意运动,旨在识别、定位和预测无意运动。

哎呀!数据集

哎呀!数据集【4】由 20,338 个视频剪辑(3-30 秒长,总计 50 多个小时)组成,这些视频剪辑来自 YouTube fail 汇编,都被证实包含一些无意的“野外”人类行为。由于作者提出了一种自我监督的方法来完成这项任务,该数据集被分成 3 个子集:7,368 个视频作为标记的训练集,6,739 个标记的视频作为测试集,其余的是用于预训练的未标记集。为了分类,视频中的动作被标注为“有意的”、“无意的”或“过渡的”;对于定位,工作人员在故障的时间位置(故障开始的时刻)标注时间戳标记。附加数据集注释包括光流和自然语言描述。在数据集中,270 个视频被指定为诊断集,可以看到更细粒度的手动注释。这些视频被分为 9 种类型的无意行动:“有限的技能”、“有限的知识”、“环境”、“意外”、“有限的可见性”、“计划错误”、“执行错误”、“单代理人”、“多代理人”。

1:数据集统计1

作者还报告了各种数据集统计数据,包括视频剪辑长度和故障时间标签的分布,以说明数据的多样性;来自不同人类注释者的标签的标准偏差,以展示高度的人类(注释者)一致性;动作和场景类别的分布(由它们的完全监督基线预测)。

来自中级感知线索的自我监督特征

作者调查了视频中自然存在的自我监督线索(或需要最小限度的注释),以了解人类行动中意向性的深层、可转移的表征。具体来说,检查视频速度、视频上下文和事件顺序。所有的通讯网络都是通过 ResNet3D-18 模型【5】实现的。

视频速度

基于之前的研究【6】,作者指出,人类对意图的判断在很大程度上受到视频速度的影响。由于视频速度是每个视频固有的,因此通过速度进行推断需要最少的预处理。对于训练,作者综合改变视频的速度,并训练一个自我监督的神经网络来预测真实的帧速率。正如作者所指出的,这种 ConvNet 生成的特征与事件的预期持续时间相关联(鲁棒性来自对具有综合改变的速度的视频的训练),并对逐帧运动信息进行编码,从而构建了视频速度信息的有用表示。

视频背景

作者声明“无意的行动往往是对预期的偏离”,并探讨了作为意向性视觉度量框架的可预测性。在先前研究【2】的指导下,他们将帧 x_{t-1}x_{t+1} 视为周围视频上下文,并激励模型对中间目标帧 x_t 的特征图进行插值。值得注意的是,他们利用噪声对比估计【7】和对比预测编码【2,3,8】的概念来构造要最大化的目标函数:

目标函数1

以便最大化目标帧特征和上下文嵌入之间的距离,同时最小化目标帧和非上下文剪辑特征之间的距离。

事件顺序

作者提出的基本原理是“无意运动往往表现为混乱或不可逆的运动”,导致独特的时间事件顺序。为了生成事件顺序的表示【3】,他们对视频中的二次抽样剪辑进行置换和洗牌,并训练一个 ConvNet 来预测所应用的置换序列。这是通过一个 3 部分模型实现的,该模型由片段特征编码器、成对片段关系网络(其中特征表示片段的相似性)和事件顺序预测器组成。

从上述自监督模型中提取的特征然后被用作线性分类器的输入,该线性分类器利用类来执行 3 类分类:“有意的”、“无意的”和“过渡的”运动。

实验

绩效以 3 个任务为基准——分类、定位(定位从有意到无意运动的过渡的时间边界)、预测(预测失败的开始),并进行 3 个层次的比较:首先,在不同的自我监督附带线索(视频速度(新提出的)、视频上下文、事件顺序)之间进行比较;其次,比较自监督模型和全监督基线(在动力学动作识别数据集上的预训练加上微调、细粒度注释:运动幅度、划痕、机会);最后,比较机器和人的表现(人的同意)。

1(分类精度)、表 2(定位精度)、表 3(预测精度)1

分类、定位、预测

在所有 3 个任务中,动力学监督产生了最好的机器性能,而视频速度监督始终优于所有其他自我监督和完全监督的方法。全监督和自监督方法之间的性能差距在分类中最小(表 1),在时间定位中最大(表 2)。为了量化定位精度,与任何地面实况时间位置(一些视频有多个地面实况)重叠的预测(在 1 秒和 0.25 秒内报告的结果)被认为是正确的。

图 2:分类混淆矩阵1

特别是,自我监督的模型比完全监督的模型遭受更多的假阳性边界预测,在完全监督的模型中,它们将有意运动与故障的开始混为一谈(图 2)。此外,作者对 9 种无意运动类别中的每一种进行了详细的错误率分析(图 3 )(在上述诊断集中)。他们报告说,由意外因素(“如突然俯冲的鸟”)或环境因素(“如在冰上滑倒”)引起的无意运动最难检测,并假设多智能体场景由于其更明显的视觉线索而记录了最低的错误率。其他挑战包括有限的视频可见性(被遮挡的物体)和有限的知识(“例如理解火是热的”)。从结果可以看出,自我监督和完全监督的方法都明显落后于人的表现。

图 3:性能分解【T6【1

结论

“哎呀!预测视频中的无意行为”介绍了理解人类行为中的意向性的 3 个新任务,并为未来的工作提供了一个大型基准数据集。作者提出了一种自我监督的方法,并报告了使用视频速度作为视频表示的附带线索的有希望的结果。

参考文献

[1]戴夫·爱泼斯坦、袁波·陈和卡尔·冯德里克。糟糕!预测视频中的无意动作。2020 年,CVPR。
[2]亚伦·范·登·奥尔德、亚哲·李和奥里奥尔·维尼亚尔斯。对比预测编码的表征学习。 arXiv 预印本 arXiv:1807.03748 ,2018。
[3]徐德静,,,邵剑,,庄悦婷。通过视频片段顺序预测的自我监督时空学习。2019 年,CVPR。[4]戴夫·爱泼斯坦、袁波·陈和卡尔·冯德里克。哎呀!预测视频中的无意动作。检索自https://oops.cs.columbia.edu/
【5】原研哉、片冈博胜、佐藤丰。时空 3d cnns 能否追溯 2d cnns 和 imagenet 的历史?2018 年 CVPR。尤金·M·卡鲁索,扎卡里·C·伯恩斯,本杰明·匡威。慢动作增加感知意图。2016 年 PNAS。
[7] Rafal Jozefowicz、Oriol Vinyals、Mike Schuster、Noam Shazeer 和吴永辉。探索语言建模的极限。 arXiv 预印本 arXiv:1602.02410,2016。
[8]韩腾达、、谢和安德鲁·齐塞曼。通过密集预测编码的视频表示学习。2019 年 ICCV 研讨会。

不透明的人工智能模型可能具有欺骗性。

原文:https://towardsdatascience.com/opaque-ai-models-can-be-deceptive-17165cb91d61?source=collection_archive---------40-----------------------

我们使用的模型可能会产生昂贵的、意想不到的影响。

Icons8 团队Unsplash 上的照片

就其本身而言,技术就像能源一样,是纯粹的潜力。我们如何部署它,以及出于何种目的,对它的影响至关重要。人工智能(AI)也不例外。

网飞最近的纪录片《社会困境》深入探讨了从控制我们的注意力和改变我们的行为中获利的商业利益是如何利用技术,尤其是人工智能来控制我们的。

虽然误用的可能性不是人工智能的独特特征,但人工智能模型构成更严重威胁的一些独特原因。作为这个行业的专业人士和它的“用户”,我观察到驱动人工智能的模型的不透明是我们正在冒的一个关键风险。

不透明的人工智能模型

去年在多伦多大学的深度学习暑期学校,我了解到大多数人工智能模型使用机器学习、深度学习或强化学习方法。机器学习方法基于高级统计建模,用于做出更好的预测。深度学习和强化学习使用神经网络。神经网络是模拟我们大脑中决策结构的多层算法。虽然不像生物神经网络那样复杂,但这些网络提供了相当真实和详细的过程模型。

高级统计方法和神经网络的问题在于,决策越复杂,它们就越不能清楚地说明模型是如何得出特定结果的。几乎不可能弄清楚最初输入模型的几个输入中的哪一个或两个驱动了这些结果。这是因为大多数此类分析都在观察新的模式并创造新的见解。

科学研究,尤其是在商业和经济研究中,直到这一点始于对世界运行方式的直观理解,然后使用数据来证实或质疑它。人工智能建模基于不同的理念。我们使用大数据集来训练算法,然后期望这样训练的模型查看其他大数据集,以获得关于世界运行方式的新见解。这种见解是有价值的,因为它们通过揭示我们用肉眼或纯逻辑思维无法辨别的模式和关系,扩展了我们对我们所居住的世界的知识。不幸的是,这并不等同于对世界有了更好的理解。这些模型和它们产生的洞见并不一定能加深我们对这些模式存在的原因和驱动因素的理解。这些模型是不透明的。

意想不到的后果

在这些技术处理的任务的复杂性和方法的可解释性之间有一个不可否认的权衡。应用程序越复杂,解释模型如何决定就越困难。当然,研究人员可以控制各种特征(变量)的权重,以及组合这些特征来表示交互的方式。然而,一旦模型被调整到位,它就变得神奇了,并不是所有的都可以被剖析回最重要的特性,以什么方式和为什么。

2007 年金融危机之后,我有机会与几家不同的储备银行合作。让我们对金融风险模型的不透明感到恐惧的是,基于此类模型的结果而采取的政策措施会产生“意想不到的后果”。这些模型和它们的建议过于复杂,难以理解。

类似地,预测基于黑盒型人工智能(或更早的金融工程模型)设计的行动或政策的所有后果是不可能的。

模型的不透明是导致金融危机的复杂性的根源,却没有人注意到。正如用于构建金融产品的复杂金融工程模型模糊了这些产品的实际风险一样,黑盒人工智能可能隐藏着可能会解开整个系统的关键相互联系。一个微小但关键的故障螺母可以拖垮一个庞大但相互关联的系统——这就是复杂性经济学,它同样适用于技术支持的决策系统,也适用于风险相互关联的银行系统。

走向可解释和更安全的人工智能

在过去的几年里,有一股巨大的推动力促使人工智能变得可以解释,消除模型偏见,并为机器学习和人工智能的道德使用建立道德和原则。

可解释的人工智能已经成为谷歌、特斯拉、微软等大型科技公司议程中不可或缺的一部分,以及许多其他将人工智能用于主流业务的公司。关注它是完全有商业意义的。不仅很难说服高管根据黑盒软件的建议采取行动,而且几乎不可能说服政策监管机构相信这种人工智能的安全性。因此,可解释的人工智能已经成为一种必然。

大学和智库也在缓慢但稳步地研究让人工智能模型更安全的科学方法。OpenAI 和人类未来研究所(Future of Humanity Institute)等智库正在推动研究和调整哪些方法可以使人工智能模型本质上更安全,即使那些无法完全解释的方法也是如此。多伦多的 Vector Institute 和英国的 Alan Turing Institute 等其他机构正在围绕人工智能模型的安全使用开展政策对话。例如,牛津大学人类未来研究所的研究员瑞安·凯里(Ryan Carey)利用他的医学博士背景,将经济学理论应用于代理人的激励,以帮助创造更安全的人工智能。

人工智能模型必须帮助我们进一步理解。

随着我们取得进展,我们必须记住,在人工智能的最初几十年里,我们做出和不做出的选择将对人工智能和由人工智能驱动的世界的功能产生乘数效应。

复杂模型的诱惑是巨大的,然而,人工智能产生任何有意义影响的唯一方式是拥抱简单。我们必须坚持发展对人工智能能做什么的直觉理解。我们需要建立模型,这些模型不仅能通过消化大量数据集得出答案,还能帮助我们加深对世界运行机制的理解。

Rust 支持的基于 Open-CV 的数独求解器

原文:https://towardsdatascience.com/open-cv-based-sudoku-solver-powered-by-rust-df256653d5b3?source=collection_archive---------39-----------------------

一个基于图像的锈电池数独解算器

安特·罗泽茨基在 Unsplash上的照片

项目动机

好吧,有一天浏览 Reddit,我发现了一个项目,是一个使用视频视频流的数独解算器。这个项目很酷,但有一点我不喜欢:它用来裁剪数独图像,并给出一个已解决的数独图像解决方案。

所以我想为什么不把解决方案投射回原始图像,让它看起来像是在原始图像中解决的?

很酷吧?!

关于项目

该项目很简单,采取数独图像,解决它,并投射回原始图像的解决方案,仅此而已!!

嗯,这是我最初的计划,但执行是另一回事。

简要项目技术描述:

  • 获取图像中的数独块— Python OPEN CV
  • 裁剪数独图像并改变视角— Python OPEN CV
  • 以某种有序的方式提取数字— Python KNN 模型
  • 使用 Rust Sudoku Solver 求解数独—
  • 将解决方案投影回原始图像— Python OPEN CV

我们可以用 python 来解决数独,但出于某种原因,我想尝试给 python 添加 Rust,它解决数独的速度也比 Python 快。

如果你觉得有趣,那就开始吧!!

裁剪和变化视角

在这一部分之后,我们将把完整的图像转换成裁剪过的数独图像。

初始图像:

好的,基本逻辑是

  1. 得到图像中最大的盒子,因为它将是T21【大概】T22数独盒子。
  2. 接下来是沿着数独盒边缘画出线条
  3. 找出这些线的交点。
  4. 使用交叉点改变图像的视角,得到裁剪的数独。

好了,让我们一步一步来看!

获得最大的盒子:

让我们来理解代码!

首先,轮廓基本上是任意的闭合形状****

我们将使用 opencv 库,步骤是:

  • 将图像转换为灰色****
  • 使用自适应阈值将图像的每个像素转换为黑色或纯白色。
  • Opencv 有一个函数findContours它返回轮廓( 闭合形状 )
  • 遍历每个轮廓并获得最大面积轮廓。

在这之后,我们将拥有最大的轮廓,很可能是数独盒子。

由于这只是给出了形状的轮廓,我们不能用它来得到数独盒,我们需要四个角点来改变视角。

因此,我们将首先在空白图像上绘制该轮廓,然后在该形状上绘制直线,这将为我们提供四条线,稍后将用于获得四个角点。

在这之后,我们将沿着数独游戏的边绘制线条,但事实是,沿着一条边有多条线条,因为Houghlines使用大致的线内点来绘制线条,并且由于我们的图像不是非常清晰,也不是正确的透视,因此我们得到的是沿着一条边的多条线条。

因此,我们要做的是,我们将消除所有相互靠近的线,但留下一条线,因此我们将剩下 4 条线用于 4 条边。

所以现在我们有 4 条线,剩下的就是得到这些线的交点。

因为我们的线不平行,所以我们将得到 6 个交点。为了解决这个问题,我们将使用线条的斜率,我们将线条分为两类,水平垂直。这样我们只能得到 4 分。

****注:线条不是横的竖的,只是两类。

for (rho,theta) in createhor:
        for (rho1,theta1) in createver:
            if (rho,theta)!=(rho1,theta1):
                a=[[np.cos(theta),np.sin(theta)],[np.cos(theta1),np.sin(theta1)]]
                b=[rho,rho1]
                cor=np.linalg.solve(a,b)
                if list(cor) not in points:
                    points.append(list(cor))

现在我们有 4 个角点,是时候施展魔法,得到数独图像了。

没什么特别的,我们将使用warpPerspective来改变视角并得到图像。

最终输出:

从数独图像中提取数字

这一部分将集中在从数独图像中提取数字。

所以首先是一些腐蚀和扩张,以消除噪音。

下一步是得到数字的轮廓,并在一个新的空白图像上绘制。之后就是画分割线了。

在这之后,我们会得到

一个干净的数独图像,没有噪音。

接下来很简单,只需遍历每个框并预测数字。第一种方法失败了非常非常悲惨是使用 CNN 模型并训练它预测数字。但出于某种原因,不管输入是什么,它都只能预测 6。

经过一些试验后,我开始使用 KNN 的型号。

问题是创建数据集,尝试过 kaggle 但是显然没有简单普通数字的数据集。所以我创建了一个脚本,首先在图像上写数字,添加一些噪声和模糊 T21 使它更真实,然后裁剪它。

然后我用了另一个好的库Augmentor。它使用当前的图像,并添加随机的倾斜、旋转、T2 等。因此,我得到的是每个数字 10k 的图像。相当酷!!至少对我来说,在做完那件杰作之后,我无法入睡。好了,在我们考虑完这个问题之后,让我们开始训练这个模型。

接下来很简单,只需使用这个模型来预测数字,并创建一个数独的新图像。

经历了这一切之后,我们拥有的是:

解决数独

我们将在本节中使用 Rust 解决数独。

在我们的最后一节之后,我们有了数独图像中的数字,剩下的是用 rust 编写一个数独解算器,谢天谢地我们可以把它导出到一个可以用 python 导入的库中。

有一个库 sudoku 提供了一个很好的 sudoku 解算器,所以我用它创建了一个函数,并编写了 Python 绑定来导入到 Python 中,另一个杰作 moment lol。

在此之后,解决数独和创建一个解决方案的面具是左。

最终的解决方案是这样的。

太好了!!让我们进入下一部分。

将解决方案投影到原始图像

最后一部分,它将专注于将解决方案投射到原始图像上。

一旦我们将解决方案映射到黑色图像上,只需执行位非位非位和位就足以移除图像的黑色部分,而且由于我们有了初始点,改变回透视也很容易

M = cv2.getPerspectiveTransform(pts2,pts1)

    img = cv2.warpPerspective(sudoku_image,M,(original.shape[1],original.shape[0]))
    img = cv2.bitwise_not(img)
    img = cv2.bitwise_and(img,original)

仅此而已!!最终的图像是

源代码

您可以在找到完整的源代码!!

** [## pr4k/数独求解器

所以我的目标是创建一个项目来解决数独难题,只是使用它的图像,并增加解决方案…

github.com](https://github.com/pr4k/sudoku-solver)

感谢阅读!!**

面向工业人工智能的开放数据源

原文:https://towardsdatascience.com/open-data-sources-for-industrial-ai-b58cef3ffd0d?source=collection_archive---------25-----------------------

将人工智能应用于制造过程

安德烈·阿米亚戈夫乘坐穿梭者

当启动一个新项目来用人工智能增强生产设施的能力时,常见的问题是:“这可行吗?”工业背景下的人工智能需要大量数据来训练底层算法。运行中的系统正在生成数据。但是这些数据通常是封装的,或者数据库没有连接。他们可能无法用于将人工智能引入公司的团队,因为公司自己的数据无法用于构建这样的系统。由于时间和预算的限制,开发团队面临着如何获得训练数据的问题。

为什么数据源对于人工智能入门至关重要

预测系统、全自动系统和知识发现系统需要正确训练数据。数据质量定义了人工智能系统提供的操作结果。如果你没有足够的有用数据,你的训练结果往往表现不佳。因此,人工智能无法构建所需的抽象,因此,它无法创建一个提供出色结果的人工智能系统。尽管有一些强化学习方法不需要大量数据,但一般的监督深度学习人工智能需要大量的标记数据。

从培训到操作的数据流程

当在工业背景下启动一个 AI 项目时,你需要考虑构建一个可用的 AI 的一般工作流程。第一步,您需要访问相关的历史数据,这些数据可能是包含所需信息的文件或数据库。在数据科学领域,第一步中可用的完整数据集合被称为数据湖。这个数据湖包含非结构化和结构化数据。通常,数据湖中的数据格式是原始格式。这意味着从不同来源进入湖泊的数据没有预处理。从相关传感器或历史记录中检索数据集合。这些数据不仅是测量数据,也是来自图像、视频或音频等来源的数据。

在下一步中,在预处理步骤中处理数据。这里看的是数据。它们是可视化的,因此主题专家可以评估数据的质量。然后它们可以被清理和减少,因此原始数据被转换成更有意义的数据。

这些数据是开发预测模型的基础。机器学习算法通常用于从数据中学习。例如,数据科学家可能会选择神经网络模型,这些模型应该在学习新的未知数据后进行验证,并检查训练。培训阶段包括多轮反馈,以查看培训结果是否符合需求。

机器学习在工业应用中的工作流程

最后,现成的人工智能组件应该在企业范围内集成。这种整合是双重的。一方面,有边缘人工智能与嵌入式设备和硬件解决方案,伴随着现场的机器。另一方面,以软件组件的形式集成到企业系统中。这些软件模块应该被修改以适应现有的操作。

nostal6ieShutterstock

问题不是数据太少,而是太多

但是去哪里找这些数据来训练你的神经网络呢?由于数据似乎是当今世界的新石油,您可能会发现自己企业之外的数据源很棘手。工业公司为自己保留他们的价值和数据。然而,也有其他行业,尤其是 IT 公司,经历了为自己保留数据和源代码的相同阶段。甚至有一小部分公司仍在这样做。但是最近几年,开源方法取得了难以想象的成功。甚至像微软这样非常专有的公司也在开发开源软件。分享创造了新的商业机会,并为整个行业增加了价值。因此,行业协会和财团开始倡议共享数据。免费开放数据的另一个来源是公共资助的活动和研究。像 NASA 或 CERN 这样的组织提供了大量有价值的数据。这些数据集用于一般任务和新算法的测试。它们是算法开发的基准。当你在互联网上搜索数据时,你会被大量的可用数据所淹没。

但是伴随着这些海量数据而来的是一个问题。人工智能是一个热门话题,每个人都渴望得到关注。因此,通常很难决定哪些开放数据适合您的项目。有许多非结构化的提议,数据质量差,或只有弱描述的数据集可用。人工智能被用于如此多的不同领域,用于如此多的不同用例,以至于有很多数据集不适合你的需求。

工业人工智能的相关开放数据源

当你查看应用工业人工智能的类别时,你会发现你可以将人工智能添加到你的许多产品和服务中。通过这种方式,你可以改善客户的体验。例如,对于制造工具,自我诊断的机器将提高操作设备的整体性能。它提高了机器的效率、可靠性和安全性,并延长了机器的寿命。他们在工具提示上看到自己的磨损迹象,如钻头、锯条、焊接工具或夹子。

您需要数据的第二个应用是自动化。趋势研究者称之为超自动化。它有助于已经存在的工业过程自动化获得另一个推动。它使人变得过时,使变化变得微不足道。在这里,来自自动驾驶和智能机器人标准的数据被用来为工业自动驾驶车辆和机器提供个体培训。

人工智能应用的第三个领域是工程系统的知识发现。这里的目标是在 AI 的帮助下找到问题的根源,消除风险。许多关键区域通过传感器和日志提供大量数据。在这里,人工智能可以创造超越异常检测和简单故障模式感测的真正洞察力。人工智能可以预测不可预料的事情。它发现过去类似事件和当前传感器读数之间的关系。这有助于防患于未然。

需要什么数据?

有了这些给定的应用领域,你可以搜索公开可用的相关数据。由于许多工业应用需要大量的传感器数据,这些数据并不总是可以直接下载。有时,您需要通过给定的 API 访问数据。这个 API 创建一个到现有数据库的连接,并允许您提取和分析它们。

可用传感器数据的一个例子是由 NASA 提供的涡轮风扇发动机预测维护数据集。它具有来自 100 个相同型号发动机的传感器数据。该数据集包括使用 C-MAPSS 飞机发动机模拟器的四组不同的发动机数据。发动机在不同的操作条件和故障模式下进行测试。

东成梭托

这些涡轮风扇发动机数据来源于美国宇航局卓越预测中心。这个美国宇航局部门甚至有更多公开的数据集可用。它以来自各种大学、机构或公司的数据集为特色。这些时间序列数据有助于创建预测算法。它们显示了从某种名义状态到失败状态的转变。包括了许多不同的工业任务。你会发现铣削数据和轴承测试。你会找到电子产品和电池的数据。

从英国可以获得更自由和公开的存储库。位于 NDR 的英国石油和天然气国家数据库提供 130 万亿字节的海上数据。它覆盖了 12,500 多个井眼、5,000 次地震勘测和 3,000 条管道。这些数据对每个人都是免费的。但是 NRD 并不是英国独有的。这些类型的国家数据仓库在许多国家都有,并提供开放的数据和开放的政府方式。

来自政府的有价值的数据不仅限于石油和天然气行业。英国地质调查局也提供了大量的数据集。它提供全英国 100 多个地震仪站的实时地震图和历史数据。超过 525 个不同地质主题的数据集。

开放数据的主要搜索引擎

为你的人工智能项目寻找开放数据源的最佳方式是特定的搜索引擎、目录和聚合器。在这些工具的帮助下,你将能够快速找到一个合适的数据集。他们将在可用的开放数据源的丛林中进行引导。就像传统的搜索引擎一样,你可以输入你要找的东西,搜索引擎会向你展示有趣的数据集。

谷歌数据集搜索、【datasetsearch.research.google.com】和给了现有的免费数据集一个令人印象深刻的概述。一旦你完成了你的搜索,搜索结果不仅会给你一个到知识库的链接。它还为您提供了有关所提供的数据格式和数据访问方式的直接信息。这个新发布的工具拥有大约 2500 万个公开可用的数据集。

研究数据存储库、re3data.org注册表提供了对其链接存储库的全面的基于文本的搜索。它在“按主题搜索”下有一个很好的图形探索工具,可以找到公开的数据。但是对于工程科学来说,结果很少。此外,这个搜索引擎不会直接引导你找到数据。它只是将您发送到继续搜索的存储库。

最重要的是,值得看看著名的 Kaggle 平台,因为它不时举办与行业相关的比赛。还有一个新的平台,叫做出土,致力于解决工业 4.0 概念背景下的数据科学挑战。

有了这些起点,您将快速找到正确的开放数据。开放数据帮助您直接启动您的工业人工智能项目,您不必等待您的运营传感器和企业设置被改造。

本文最初发表于 AiThority

开源 CityGML 3D 语义建筑模型

原文:https://towardsdatascience.com/open-source-3d-semantical-building-models-in-2020-f47c91f6cd97?source=collection_archive---------13-----------------------

开源 3D 城市模型的完整列表

在 CesiumJS 框架中可视化的 3D Tiles 格式的纽约市 3D 城市模型。(作者)

** 2021 年 1 月更新*

为什么是语义模型?

在最近的地理数据科学项目中,语义三维城市模型或高级分析和可视化任务越来越多地用于各种应用领域,如城市规划、室内/室外行人导航、环境模拟、文化遗产或设施管理[1]。

最流行的数据模式之一是 OGC 城市 GML。CityGML 是用于描述 3D 地理空间化城市模型的全球数据模型模式;由 OGC(开放地理空间联盟)开发。CityGML 描述了城市对象,如建筑物、道路、桥梁、树木等。在三维地理空间中。CityGML 城市对象数据属性类包括语义、几何、拓扑和外观。CityGML 是一个开放的国际共识标准,经过了超过 15 年的合作开发和使用[2]。

示例使用案例:环境建筑能源模拟/分析

例如,基于 CityGML 的语义 3D 建筑模型可用于模拟其全年的供热能源需求。下图显示了我们位于 HFT 斯图加特的研究实验室分别在鹿特丹市、德国路德维希堡和美国布鲁克林计算能源需求的仪表板结果。

根据 CityGML 模型计算鹿特丹建筑的热需求。(作者开发并截图)

德国路德维希堡(左)和美国布鲁克林(右)城市能源数据的网络 3D 可视化【5】(由作者开发并截图)

开源 3D 语义建筑模型

世界上越来越多的城市为研究人员和开发者提供了他们的 3D 城市模型。然而,你们中的一些人可能不知道这个现有的有价值的数据来源!

本文包括我所知道的可用的官方开源 3D 语义数据模型的列表。

美利坚合众国

纽约市(在 LoD2 中)

在 CesiumJS 框架中可视化的 3D Tiles 格式的纽约市 3D 城市模型。(作者开发并截屏)

纽约市的三维建筑体量模型被开发成一个混合规格的组合元素。它包含屋顶、立面和地平面等属性。所有主要屋顶结构都已建模。模拟倾斜屋顶;然而,圆顶和圆形屋顶不是。不包括所有屋顶附属物,包括但不限于烟囱、女儿墙、主轴和天线。此外,纽约市“标志性”建筑的子集被建模为 LOD 2。详情请访问 元数据 页面【3】。

  • 【nyc.gov】city GML:下载
  • 多面体 : 下载 (来自 nyc.gov)
  • :下载 (来自 nyc.gov)
  • 3D 磁贴 : 下载 (使用 FME 由 CityGML 转换而来,仅限曼哈顿地区,分享自我的 Google Drive)

美国的所有建筑(LoD1)

开放城市模型为美国的所有建筑提供了一个开放的 3D 城市模型数据集。它为美国的每座建筑提供 3D 几何图形;包含大约 1.25 亿栋建筑。

  • CityGML,CityJSON : 下载 ( 来自开放城市模型 Github【2】)

加拿大

蒙特利尔(在 LoD2)

****在 ArcGIS for JavaScript 应用程序框架中可视化的 i3s 格式的蒙特利尔 3D 城市模型。(作者开发并截屏)

蒙特利尔市已经提供了具有 CityGML 和一些蒙特利尔自治市的 3DM 格式的纹理的 LOD2 3D 建筑物的数字模型。在上面的示例中,我使用 FME 工作台将 CityGML 转换为 i3s 文件格式,然后使用 ArcGIS for JavaScript 可视化模型

瑞士

苏黎世(在 LoD 1 和 2 中)

  • CityGML: 下载入口(来自施塔特苏黎世开放数据)
  • CityJSON: 下载(来自 TUDelft)

荷兰

您可以从 3D 包项目下载门户下载整个荷兰的原始 3D 建筑模型数据,包括几何图形和属性。

芬兰

埃斯波

Espoo 的城市信息模型涵盖了 CityGML 标准中包含和定义的所有对象类型,但工程结构(桥梁和隧道)除外。

赫尔辛基

****赫尔辛基的 3D 城市模型,在 CesiumJS wen 应用程序中以 3D Tiles 格式显示。(作者开发并截屏)

赫尔辛基有两种下一代 3D 城市模型:语义城市信息模型和视觉上高质量的现实网格模型。您可以在http://kartta.hel.fi/3d/查看 3D 城市模型并下载其信息。你可以在这里找到更多信息https://www . hel . fi/Helsinki/en/administration/information/general/3d/

  • CityGML: 下载(赫尔辛基市)

德国

北莱茵-威斯特伐利亚州(在 LoD 1 和 2 中)

****科隆市的 3D 城市模型,在 CesiumJS 框架中以 3D Tiles 格式可视化。(作者开发并截屏)

北莱茵-威斯特法伦州位于德国西部,面积超过 34000 平方公里,是德国第四大州。可以按本州城市下载开源的 3D 城市模型(多特蒙德、杜塞尔多夫、科隆、波恩、埃森等)。).

汉堡(在 LoD 1 和 2 中)

****汉堡市的 3D 城市模型,在 CesiumJS 框架中以 3D Tiles 格式可视化。(作者开发并截屏)

汉堡的 3D 城市模型有 LoD 1 和 LoD 2 两种版本。

柏林(带纹理的 LoD 2)

自 2009 年以来,柏林商业定位中心已经成功地将 3D 城市模型用于柏林商业定位的虚拟展示。直到 2018 年,来自柏林的面向对象的 LoD2 模型被用于 3D 演示,自 2019 年以来,3D 网格模型被自动从航班中导出。下面的示例截图是在 3D 环境中探索这些模型的示例可视化平台。

在 VirtualCitySystems 框架中可视化的 3D Tiles 格式的汉堡 3D 城市模型()。****

新加坡

****在 Mapbox 框架上可视化的新加坡 3D 城市模型【4】。

自 2019 年以来,新加坡所有公共住房(HDB)建筑的开放 3D 城市模型现已可用,并附有关于该模型如何生成的开源代码。新加坡国立大学的城市分析实验室用两个数据集生成了这个模型,分别是来自 OpenStreetMap 的 2D 建筑足迹HDB 房产信息

  • CityJSON: 下载 ( 来自新加坡公屋(HDB)建筑 3D 城市模型 Github

结论

本文以 OGC 城市 GML 模式为例,简要概述了语义三维城市模型,并给出了三维地理数据科学中的一些用例。此外,它还提供了全球可用的最新 3D 城市模型列表。我希望你喜欢这篇文章,并发现它对你的日常工作或项目有用。如果您有任何问题或意见,请随时给我留言。

关于我&查看我所有的博客内容:链接

安全健康健康!💪

感谢您的阅读。📚

参考

[1]格哈德·格罗格;卢茨·普吕默(2012 年):city GML——对 3D 城市模型的互操作访问https://doi.org/10.1016/j.isprsjprs.2012.04.004

[2]开放城市模型(2020 年):美国开放城市 gml 数据https://github.com/opencitymodel/opencitymodel T2

[3]纽约市(2020 年):纽约市 3d 建筑模型https://www1 . NYC . gov/site/doit/initiatives/3d-Building . page

[4] Biljecki,F. (2020): 探索东南亚的开放数据以生成 3D 建筑模型,ISPRS Ann。摄影镜头。遥感空间信息。Sci。,VI-4/W1–2020,37–44,https://doi.org/10.5194/isprs-annals-VI-4-W1-2020-37-2020

[5] Würstle,p .,Santhanavanich,t .,Padsala,r .,& Coors,V. (2020 年)。使用 3D 城市模型的城市能源仪表板概念。第十一届 ACM 未来能源系统国际会议论文集。提交于 e-Energy '20:第十一届 ACM 未来能源系统国际会议。https://doi.org/10.1145/3396851.3402650

开源数据科学抗击新冠肺炎(冠状病毒)

原文:https://towardsdatascience.com/open-source-data-science-to-fight-covid-19-corona-virus-95bf4ebcb52c?source=collection_archive---------26-----------------------

建立模型来找出最脆弱的。

随着新冠肺炎在我们生活中变得越来越自信,医疗数据科学界有机会在缓解这种新兴疫情方面发挥重要作用。历史表明对此类疾病的反应可以极大地改变此类疾病的最坏影响。许多城市实施了社会距离措施,关闭了任何有大量人群聚集的地方,还可以采取进一步措施来帮助隔离和保护人口中最脆弱的群体。为了做到这一点,我们必须首先确定谁面临的风险最大,这促使我的团队创建了一个开源项目,即新冠肺炎脆弱性指数

CV19 指数是一个开源的、基于人工智能的预测模型,可以识别出那些很可能对新冠肺炎严重并发症具有高度脆弱性的人。CV19 指数旨在帮助医院、联邦/州/地方公共卫生机构和其他医疗保健组织识别、计划、应对和减少新冠肺炎对其社区的影响。在本帖中,我们将回顾这个开源项目的高级细节。有关数据选择和模型构建的更详细描述,请参见我们的白皮书

第一步——制作带标签的数据集

尚不存在新冠肺炎住院治疗的数据。当数据开始出现时,我们可以查看作为真实事件代理的受影响人群和事件。鉴于这种疾病最糟糕的结果集中在老年人身上,我们可以关注医疗保险账单数据。我们可以预测替代医疗事件,特别是由于呼吸道感染导致的住院,而不是预测新冠肺炎住院。例子包括肺炎、流感和急性支气管炎。我们通过解析医疗账单数据和搜索描述这些事件类型的特定 ICD-10 代码来识别这些标签。所有的预测都是在特定的一天做出的。从某一天开始,我们回顾过去 15 个月的特征。由于医疗索赔数据报告的滞后,我们排除了预测日期后三个月内发生的任何事件。去年的任何诊断都会成为我们在所有模型中使用的特征。

第二步—模型

这类项目需要考虑大量的模型。最终,我们希望这些模型能够在尽可能有效和医疗数据科学家能够尽快访问之间取得平衡。选择我们使用的数据的原因之一是因为医疗保健数据科学家可以广泛获得医疗保险索赔数据。如果您的组织可以访问额外的数据源,您可以通过合并这些信息来观察性能的提高。权衡这些因素后,我们根据采用的难易程度和模型的有效性创建了 3 个模型。

第一种是使用少量特征的逻辑回归模型。在 ClosedLoop,我们使用标准的 Python 数据科学堆栈。一个非常简单的模型的动机是,它可以移植到像 R 或 SAS 这样的环境中,而不必读写一行 python。在低警报率下,该模型的性能接近更复杂版本的模型。前面提到的白皮书包含了有限特性集的所有权重,因此可以手工移植。

比较所有三种模型性能的 ROC 图。

接下来的两个模型都是使用 XGBoost 制作的。 XGBoost 始终为对结构良好的数据进行预测提供最佳性能,只要进行正确的数据转换,医疗账单数据就具有这种结构。第一个 XGBoost 模型出现在我们的开源包中。这个模型有一个简化版本,所以您只需要构建一个数据转换管道,将您的账单数据转换成 repo 中指定的格式。如果您可以构建一个函数来解析特定代码的数据,那么您可以简单地遍历所有代码。这就是我们为开源模型选择有限特性集的原因。这非常有效,同时从数据管道的角度来看,仍然只需要合理的提升水平。我们还让医疗机构能够在平台内访问我们的模型。这个版本的模型使用完整的诊断历史,加上大量的工程特征。请注意,ROC 曲线显示,开源版本与我们平台中包含的版本具有几乎相同的性能。

结论

全世界都在参与反对这个疫情的斗争。医疗保健数据科学界可以对抗击这种疾病产生重大影响。已经有很多优秀的努力使用数据可视化和蒙特卡洛模拟来帮助对抗疫情的传播。我们认为,我们的模型解决了健康政策的一个补充性的重要方面,确定了那些风险最大的人群。通过将这些努力和医疗保健技术领域的许多其他优秀努力结合起来,我们希望减轻这种可怕疾病的影响。

如果阅读这篇文章让你有了贡献的想法,我们鼓励你分享我们的知识库。如果你在医疗保健数据科学社区,请使用该工具,如果你想联系,请随时前往 https://closedloop.ai/cv19index了解更多信息。

原载于 2020 年 3 月 17 日https://closed loop . ai

您需要了解的 Python 开源能源项目

原文:https://towardsdatascience.com/open-source-energy-projects-in-python-you-need-to-know-about-6d770474121c?source=collection_archive---------13-----------------------

应对气候变化所需的数据科学工具指南

Pexels.com

在学习如何编程的过程中,我最喜欢的一部分是发现开源软件的力量。很有可能,每当你准备投入一个新项目,构建一个新工具,或者进行一些新的分析时,有人已经想到过那个项目——或者非常类似的东西。对你选择的主题或问题进行定义明确的谷歌搜索,通常会带来大量有用的博客文章、软件包和由聪明的付费转发者创建的 Github 知识库。

Pexels.com

开发开源项目最困难的部分是它们是公共产品——每个人都受益,但创作者很少得到他们工作所提供的全部价值的补偿。真正好的工作通常是学位的副产品,直接由补助金资助,或由一家科技公司作为善意行为发布,该公司可以分享一些它认为对其酱料不重要的秘密(想想阿帕奇·斯帕克或脸书的先知)。

凭借我在可再生能源方面的背景,我对将数据科学应用于能源转型特别感兴趣,或者更具体地说,对如何管理电网上可再生发电的涌入特别感兴趣。这一领域的一些常见问题包括电力负荷预测、太阳能和风力发电预测、整体电力系统建模(测量整个电网的性能)和电池优化模型(重要的是让智能系统管理储能解决方案,以最大限度地发挥可再生能源的优势)。在我转向数据科学的过程中,我偶然发现了一些这样的项目,并想分享一些。

电力基因组计划

公用事业公司、项目开发商、倡导组织和其他电网利益相关者在其工作中强烈需要电力系统建模。随着风能和太阳能继续抢占市场份额,我们需要了解如何规划和运营具有高比例可变可再生能源的电网。这种初步分析被称为容量扩展规划,这对于一些利益相关者来说是一个巨大的障碍,因为它通常是资源密集型的、复杂的和耗时的。显然需要一种工具,使资源有限的可再生能源倡导者能够测试产能扩张计划,并创建支持其观点所需的数据。

专注于能源转换的环境影响的数据科学家 Greg Schively 正在利用赠款创建 Power Genome 项目。这一开源项目将允许用户专注于美国的特定地区,并考虑各种各样的基本变量,如现有发电成本、传输约束、预计燃料成本、负荷曲线等。它还允许用户根据他们的特定项目通过聚类生成来修改调整各种粒度级别的设置。

该项目目前面向# energy witter star Jesse Jenkins 的 GenX 项目,但很快将变得更加普遍,允许支持可再生能源的倡导者或任何需要电力系统建模的人利用这些工具来支持能源过渡。

链接:【https://github.com/gschivley/PowerGenome

公用事业数据解放(PUDL)

所有数据科学家都知道,查找、组织和清理特定项目所需的数据非常耗时,而且往往是项目成功的最大障碍。对于能源行业来说尤其如此,联邦能源管理委员会(FERC)、能源信息管理局(EIA)和许多其他组织发布了大量有用的数据,但格式和标准不同。

https://catalyst.coop/

Catalyst Cooperative 是一个由数据科学家和政策专家组成的小组,作为一个工人所有的咨询机构,创建了公共事业数据解放(PUDL)项目来解决这个问题。用他们的话说,PUDL“通过在一个数据库中清理、标准化和交叉链接来自不同来源的公用事业数据,获取已经公开可用的信息,并使其公开可用”PUDL 数据库目前包括燃料使用、发电组合、发电厂运营成本的数据,甚至来自环境保护署(EPA)的排放数据。该团队还着眼于增加几个新的数据集。

这个团队正在解决一个巨大的问题:组织所有这些数据,并将其转换为机器可读的格式。与 Power Genome project(使用 PUDL)类似,Catalyst Cooperative 旨在降低能源系统分析的准入门槛,并使这些资源可供所有人使用。

链接:https://github.com/catalyst-cooperative

皮伊索

负责经营批发电力市场和平衡不同地区电网电力的独立系统运营商(ISOs)被要求每隔 15 天公布一次负荷数据。然而,收集这些数据需要将 web 抓取和下载 CSV 文件不方便地混合在一起。

WattTime 是一家非营利组织,收集实时 ISO 数据,使电力消费者能够在电网中可再生能源比例最高的时候使用能源。WattTime 开源了 PYISO 库,该库为他们的 API 提供支持,允许任何人方便地访问历史和实时负载和发电数据。我实际上使用这个库创建了 Peaky Finders ,这是一个 NYISO(纽约 ISO)的峰值负载预测应用程序,为我节省了很多时间和麻烦。

与 PUDL 类似,PYISO 的创建者们意识到有必要将公用事业公司和 ISO 需要发布的数据标准化。虽然只有几岁,但我发现这一集与创始人的播客对了解项目背后的背景和原理非常有帮助。

链接:https://github.com/WattTime/pyiso

其他几个

值得一提的其他一些项目:

WindML

Pvlib

奥斯莫

  • 随着储能资源激增以最大化可再生能源发电,电池优化建模是一个巨大的挑战——这是一个开源工具,有助于入门。
  • 链接:https://github.com/RyanCMann/OSESMO

打开黑匣子:理解是什么驱动了深度 NLP 模型中的预测

原文:https://towardsdatascience.com/open-the-black-box-understand-what-drives-predictions-in-deep-nlp-models-833f3dc923d0?source=collection_archive---------55-----------------------

实用且可重复的演示

约什·卡斯维尔 一起写的文章

电影 1917 的 IMDB 评论—使用 Captum 生成并使用 ipyvuetify 可视化的预测属性

目标 - 通过检查属性
理解和感知-检查模型决策制定-可视化令牌属性
-提供易于使用的代码,以便任何人都可以将其应用到他们的 PyTorch 模型中

深度神经网络为 NLP 做了令人难以置信的事情——每年都有艺术记录被打破,全新的研究和应用子领域蓬勃发展。

毫无疑问,这些模型使研究人员能够创造出令人印象深刻的结果。从艾写诗到在保持意义的同时改变信息的语气。具体怎么做?结果如此令人印象深刻,以至于几乎很容易忘记去问。

匿名作者(来源)

大量的参数、抽象的架构方法、令人印象深刻的出版物以及创新的纯粹步伐可能会分散注意力——跟上深度学习是相当全职的努力。

  • 模型是如何做出如此高质量的预测的?
  • 他们知道什么?
  • 什么 他们知道?
  • 他们有多可靠?
  • 是什么情况让他们纠结?

这些是很难回答的问题。见证一些领先的研究人员投入时间和工作来提供答案真是太棒了。但是有许多应用该技术的从业者,他们需要理解和可靠地解释它做什么和为什么。

这篇文章的目的是提供一个快速和实用的介绍,一个伟大的,公理化的方法来建模可解释性。我们专注于 NLP,并提供代码示例让您直接进入并获得自己独立的体验。

可解释性是关键。当高级利益相关者或法规遵从性不支持某件事情时,他们怎么会支持呢?这会带来什么新的风险?

机器学习模型是模型架构、用于训练的数据集和训练过程的结果。这意味着每个模型都是不同的,并且您需要用自己的数据集来评估自己创建的模型。

我们将重点关注一种称为集成梯度的方法,并使用来自著名的 fast.ai 深度学习 for coders 课程的预训练评论情感分类器。

照片由拍摄于 Unsplash 上的

路径集成渐变

综合梯度是作者 Mukund SundararajanAnkur TalyQiqi Yan中介绍的公理化归因方法,用于深度网络(2017)

它旨在显示深度神经网络输入的哪些部分影响输出,以及有多强烈。

关键的是,与基线输入相比,属性被计算 。换句话说,它不依赖于离散的直接梯度 wrt。输入的变化,但需要一个假定为中性的参考基线。空白画布与彩绘图像。

从基线到输入端,通过空间的一条直的、连续的路径。

IG 是一种路径方法

  1. 创建从基线(空的和中性的)到输入(我们要解释的信号)的穿过空间的直线路径,
  2. 在连续路径上每一步聚集梯度,
  3. 计算这些累积梯度的路径积分。

它的关键优势在于公理起源。它具有来自数学原理的理想特征。这与源自经验的归因方法(阅读“尝试看看会发生什么”)形成了对比,顺便说一下,这种方法也很棒。

该方法的两个核心原则:

  • 敏感度—如果基线和输入之间存在差异,属性需要非零。
  • 实现不变性——“如果两个网络的输出对于所有输入都相等,则这两个网络在功能上是等价的”

暗示其他期望的自然属性也起作用。其中之一是完整性——属性加起来就是给定输入与基线的模型(网络)输出的确切差异。

我们强烈推荐阅读这篇论文,它清晰明了,附有证据,并且有精心准备的例子。

我们正在使用的版本已经在 Captum 库中实现。

嵌入

对于 NLP 模型,输入特征是转换成记号的单词、标点符号和其他文本信息(例如,大写字母)。标记是离散的,不适用于这种路径方法。

当记号通过嵌入层进入网络时,它们获得了意义的连续表示。我们需要连接到这一层——文字和数字的界面——来计算有意义的属性。

AWD-LSTM 建筑

该模型最初由 正则化和优化 LSTM 语言模型(2017)中提出,由 Stephen MerityNitish Shirish KeskarRichard Socher 编写,作为免费的 f ast.ai 深度学习 for coders 课程的一部分讲授。

AWD-LSTM,非常宽泛地说,包括两个阶段:

  1. 基于 RNN 的编码器
  2. 一个汇集线性分类器,为编码器的输出增加分类能力。

它结合了许多谨慎应用的正则化技术,并且很好地展示了对 LSTMs 内部工作原理的理解。

编码器可以在语言建模任务上预先训练,事实上这是由 fast.ai 团队教授的方法。该架构做得非常好,同时比各种新的 transformer 模型小得多。这在资源受限的情况下非常有利,事实上 fast.ai 值得高度赞扬,因为他们为实现深度学习所做的工作非常有影响力。

虽然本文是基于这个特定的模型,但是该方法将适用于任何使用嵌入层的 NLP 架构。

威廉·戴尼奥Unsplash 上拍摄的照片

将 Captum 应用于 AWD-LSTM 情感分类器

在这一部分,我们将讨论 3 个主题:

  • 如何计算属性,从一个预先训练好的 fast.ai Learner对象开始
  • 关于选择基线的说明
  • 处理较长的序列

1.计算属性

fast.ai 的 AWD LSTM 实现不能直接与 Captum 一起工作。

收集渐变时,我们需要钩入正确的图层。这不会自动发生,我们需要深入模型结构以找到该层。

提取右侧图层

看起来好像有重复,但实际上,那些是嵌套模块,原因是fast . ai团队实现的自定义嵌入丢失。**

另一方面,Captum IG 类需要模型输出一个没有任何附加的预测我们从 AWD-LSTM 模型中得到的是一个元组,其中预测伴随着来自编码器的隐藏状态。此外,我们必须应用 softmax。

幸运的是,我们可以将模型包装在一个函数中,以我们需要的方式呈现输出。

应用 IG

此时,我们可以自由地创建一个来自 Captum 的LayerIntegratedGradients实例。

调用属性方法的情况如下:

我们提供:

  • 标记化的输入文本(有人称之为数字化的)
  • 对应的基线记号序列
  • 要解释的目标预测
  • 用多少步来近似积分

我们收到:

  • 对于每个嵌入向量的每个元素,从基线到给定输入的路径上的积分梯度

接下来,让我们对嵌入维度求和并归一化——属性就可以显示了。

要查看、克隆和运行这个完整的示例,请查看这个笔记本

形象化

属性以标准化浮点数的形式出现——每个令牌一个值。在可视化这种格式时,有很多选择。在这一节中,我们为您提供代码,让您快速生成条形图和颜色编码的标记(“显著图”方法)。

此处适当可视化的目的是使您能够立即理解预测解释,让您快速、轻松地判断性能。

点击图片下方的链接,访问可以在 Jupyter 中运行的代码示例!

显著图——彩色筹码

链接到笔记本上

Chart.js 条形图

使用 Chart.js 库转换标准化输出的示例可参见此处:

积极向上的情绪。为了可读性,删除了一些标点符号和描述性符号。(显著性图+条形图)

matplotlib/pandas 中的条形图

指定目标的一个好处是你可以得到“为什么不呢?”就像“为什么是的?”

什么是好的基线?

追寻这个问题的答案和计算归属一样有益。

基线是模型的预测中性输入,并且是特定于模型的。它描述了你的模型。

真的是中立吗?是什么让它动摇了?知道你在生产中使用的模型的那些事情不是很棒吗?

您可能希望尝试一些方法来制定基线:

  • 零嵌入向量序列,长度与输入序列匹配
  • 单个标记的序列,如,中性符号(换行符、点号),按长度匹配输入序列
  • 多重基线——你期望中立的句子的集合
  • 使用梯度来计算嵌入序列,该序列对于所有潜在的类都是同样不确定的

这可以附在你的模型的文档中。积分梯度是一种适用于任何预测函数的方法,因此它甚至可以包括在模型测试中,以寻找不公平的偏差等问题。

我们在带有 IMDB 评论的示例笔记本中包含了一个示例发现过程。使用< BOS >标记构建基线序列,然后重复一个在类别概率中显示高度模糊的标记。该标记作为关键字参数保存,以便快速试验。

处理较长的句子

我们在将 IG 应用于 fast.ai 实现时发现的一个早期问题是在较长的输入句子上的失败。使用情况表明,评估超过 70 个标记的句子会产生错误。仔细调试表明,这是由 AWD-LSTM 模型中通过时间反向传播(BPTT)参数的默认设置 70 造成的。

bptt参数是(由同名算法)用来指定基于 RNN 的语言模型在试图预测下一个单词时将考虑多长时间的序列的值。在这种情况下,在尝试预测下一个标记之前,最多考虑 70 个标记。

BPTT 是一种训练 RNNs 的有用算法,它显著地提高了训练速度。但是,在内部将序列分成 70 个更小的序列,这在尝试创建正确大小的遮罩尺寸(甚至是完全空的遮罩)时会导致模型的其他部分出现问题。

解决方案是将模型的bptt属性设置为高于句子长度,作为将模型设置为评估模式的一部分。

结论

解释具有数千万个参数的超大型深度神经网络需要新的工具和方法。我们希望这为数据科学家的工具包提供了另一个工具,并有助于形成他们自己的测试方法的基础。

一个公理化的解释方法,加上一个简单的、迭代的和可视化的检查过程,使得“了解”ML 模型变得很容易。当数据科学家这样做时,他们可以同时创建测试用例。

作者是伦敦 fast.ai 研究小组成员。我们运行免费的非正式课程迭代,专注于实践现代深度学习和构建项目。如果你想加入我们的小组,请联系我们!

Josh 是一名在金融部门工作的高级数据科学家,他对在商业环境中使用 NLP 技术和在滑雪环境中使用 python 感兴趣。

Michal 通过他的咨询公司create . ml提供数据科学和人工智能项目,他为机构和个人提供数据科学、机器学习和 Python 方面的培训。

OpenAI 的 GPT 3:货物邪教程序员的终结

原文:https://towardsdatascience.com/openais-gpt-3-the-end-of-cargo-cult-programmers-23102f70f855?source=collection_archive---------9-----------------------

不过不用担心,它不会抢走技术活

列宁·艾斯特拉达在 Unsplash 上的照片

Cargo coding 是一种编程风格,开发者希望从其他地方复制粘贴代码片段,并希望它能工作。task 的人通常不太了解语言的深度,而是依靠 StackOverflow 这样的论坛来完成他们的工作。

既然我们已经得到了这个定义,让我们把注意力放在手头的主要主题上:OpenAI 的新语言模型。

由埃隆·马斯克和彼得·泰尔等人共同创立的 OpenAI 曾经是一个非营利组织。它在过去几年里取得了巨大的进步,弥合了人工智能和普通人类智能之间的差距,今天已经商业化。

OpenAI 的新 GPT-3 有什么宣传?

除非你生活在岩石下,否则你可能听说过 OpenAI 的最新 GPT 版本。它席卷了社交媒体。

GPT 3 号现在被大肆宣传的原因是它巨大的模型尺寸。今天,它是世界上最大、最强大的自然语言处理机器学习模型之一。

经过超过 1 万亿个单词的训练,并基于 transformer 神经网络架构,生成式预训练模型能够完成几乎任何自然语言任务,无论是编写提示、聊天机器人问答,还是生成特定语言的代码。

GPT-3 模型使用了 1750 亿个参数。这是十亿个 b,是 GPT-2 训练参数的 100 多倍。

用于训练该模型的大量参数和大量数据几乎已经抛弃了任何微调的需要——伯特和 GPT-2 不得不依靠这些来完成特定任务。

本质上,你只需要告诉 GPT-3 模型在输入英语时需要做什么,它就会根据下一个单词的预测为你计算输出。例如,你可以在输入框中输入“如果特朗普是程序员”,它会自动为你完成这个故事(当然,直到某个极限)。

虽然目前 OpenAI 只在私人测试版中发布了 GPT-3,但早期测试者已经分享了他们的发现,这些发现已经在 Twitter 上传播开来。其中一个展示了如何创建一个简单的 web 应用程序,只需用简单的英语输入你的需求,它就会为你生成语言代码和应用程序。

尽管关于 GPT-3 的复杂性有很多要讨论的,但我会跳到它对开发人员和他们的工作意味着什么。如果你倾向于深入探索 GPT-3,我推荐阅读这篇文章。或者干脆谷歌一下。

程序员们,GPT-3 不会偷走你们的技术工作

自 2020 年初以来,有一个非常普遍的概念,即编码的未来是无代码的。事实上,有一个巨大的隐忧,那就是有一天人工智能会接管人类和他们的工作。

这一点,加上目前 GPT 3 的迅速出现,在开发人员社区引起了轰动——一些人认为编程的无代码时代终于到来了。

虽然人工智能可以在 10 年后接管大部分编程工作,但目前 OpenAI 的 GPT-3 模型尽管庞大,但仍远远达不到一般人类的智能。

编程是艺术和科学的结合,解决问题需要一些更深入的思考,而不仅仅是在视觉布局中生成代码。此外,理解复杂的需求来编写生产级代码还不是 AI 准备好以万无一失的方式去做的事情。

我们已经有了很多无代码的可视化工具,比如 CreateML,用于构建基于迁移学习的简单模型。GPT-3 将会是一个很好的补充,帮助程序员加速他们的工作流程。

如果有的话,这将使程序员的工作更有成效,因为他们将有特定的角色,没有基本的任务。

GPT-3 永远不会扼杀熟练开发者的工作。相反,它为货物编码员和开发人员敲响了警钟。这将促使他们系好安全带,提高技能,以确保他们能够解决复杂的计算机编程问题。

OpenAI 的 GPT-3 将有助于提高入门级开发人员的门槛,这些人到目前为止都很自满,并乐于做一些猴子任务,如从谷歌复制粘贴代码片段。

或许,GPT-3 可以大大减少开发者对谷歌的依赖。

此外,这一突破可能带来的另一个积极的事情是,它将鼓励更多的非开发人员自己构建简单的网站和应用程序,同时获得编程专业知识。

结论

请记住,GPT-3 模型,尽管它很大,但离人类大脑智能仍有数英里远。它只是编程上的一个新的抽象层。

当然,那些注定要在 HTML、CSS 和 SwiftUI 中做简单的无脑逻辑工作的开发人员,可能会随着 GPT-3 在明年的商业化而被淘汰。但无论如何,它不会扼杀编程或数据科学工作。

正如人们常说的,当人工智能接管编程的那一天,它将接管所有的工作。

Elon Musk 掌舵 OpenAI,实际上是为了减轻人工智能对人类的威胁。他的愿景是将人工智能与我们融合,让我们拥有对它的最终控制权,而不是相反。GPT-3 可能还没有接近通用人工智能,但它可能是人工智能与普通人相遇的第一个跳板。

OpenAI 的 MADDPG 算法

原文:https://towardsdatascience.com/openais-multi-agent-deep-deterministic-policy-gradients-maddpg-9d2dad34c82?source=collection_archive---------24-----------------------

多主体 RL 问题的行动者批评方法

萨法尔·萨法罗夫在 Unsplash 上拍摄的照片

新方法

多主体强化学习是一个正在进行的、内容丰富的研究领域。然而,在多智能体环境中天真地应用单智能体算法“使我们陷入困境”由于许多原因,学习变得困难,尤其是由于:

  • 独立主体间的非平稳性
  • 状态和动作空间的指数增长

研究人员提出了许多方法来减轻这些挑战的影响。这些方法的一个大子集属于“集中计划,分散执行”的范畴

集中规划

每个代理只能直接访问本地观测。这些观察可以是许多事情:环境的图像、与地标的相对位置、或者甚至其他代理的相对位置。此外,在学习过程中,所有代理都由一个集中的模块或评论家指导

尽管每个代理只有本地信息和本地策略需要训练,但是有一个实体可以忽略整个代理系统,建议他们如何更新策略。这降低了非平稳性的影响。所有代理都在具有全局信息的模块的帮助下学习。

分散执行

然后,在测试期间,集中的模块被移除,只留下代理、它们的策略和本地观察。这减少了增加状态和动作空间的不利影响,因为联合策略从未被明确学习。相反,我们希望中央模块已经给出了足够的信息来指导本地策略培训,以便一旦测试时间到来,它对于整个系统是最优的。

OpenAI

OpenAI、加州大学伯克利分校和麦吉尔大学的研究人员介绍了一种使用多代理深度确定性策略梯度的多代理设置的新方法。受其单一代理对手 DDPG 的启发,这种方法使用演员-评论家风格的学习,并显示出有希望的结果。

照片由 Alina GrubnyakUnsplash 上拍摄

体系结构

我们假设熟悉单代理版本的 MADDPG:深度确定性政策梯度(DDPG)。快速回顾一下, Chris Yoon 有一篇精彩的文章对此进行了概述:

[## 解释了深层确定性策略梯度

连续动作空间中的强化学习

towardsdatascience.com](/deep-deterministic-policy-gradients-explained-2d94655a9b7b)

每个智能体都有一个观察空间和连续行动空间。此外,每个代理都有三个组件:

  • 一个演员网络,使用本地观察来进行确定性动作
  • 用于训练稳定性的具有相同功能的目标演员网络
  • 一个使用联合状态动作对来估计 Q 值的批判网络

随着时间的推移,评论家学习联合 Q 值函数,它向演员发送适当的 Q 值近似值以帮助训练。我们将在下一节看到对这种交互的更深入的研究。

请记住,批评家可以是所有 N 个代理之间的共享网络。换句话说,不是训练 N 个估计相同价值的网络,而是简单地训练一个网络,并用它来帮助所有参与者学习。如果代理是同质的,这同样适用于行动者网络。

MADDPG 架构(Lowe,2018 年)

学问

首先,MADDPG 使用经验回放进行高效的政策外培训。在每个时间步长,代理存储以下转换:

体验回放过渡

其中存储了联合状态、下一个联合状态、联合行动以及每个代理收到的奖励。然后,我们从体验回放中抽取一批这样的转换来训练我们的代理。

评论家更新

为了更新代理的集中评论,我们使用一步前瞻 TD-error:

其中 mu 表示演员。请记住,这是一个集中式评论器,意味着它使用联合信息来更新其参数。主要动机是知道所有代理采取的行动使得环境静止,即使当策略改变时。

请注意右侧目标 Q 值的计算。尽管我们从未明确存储下一个联合动作,我们在更新期间使用每个代理的目标角色来计算这个下一个动作,以帮助训练稳定性。目标参与者的参数会定期更新,以匹配代理的参与者参数。

演员更新

类似于单代理 DDPG,我们使用确定性策略梯度来更新每个代理的参与者参数。

其中 mu 表示代理的演员。

让我们稍微深入一下这个更新等式。我们使用一个中心评论家来指导我们,相对于演员的参数进行渐变。要注意的最重要的事情是,即使演员只有局部的观察和动作,我们在训练期间使用一个集中的评论家,为整个系统提供关于其动作的最优性的信息。这减少了非平稳性的影响,同时将策略学习保持在较低的状态空间!

拍摄的桑德韦特林Unsplash

政策推理和政策集合

我们可以进一步下放权力。在早期的 critic 更新中,我们假设每个代理自动知道其他代理的行动。然而,MADDPG 建议推断其他代理的政策以使学习更加独立。实际上,每个代理增加了 N-1 个网络来估计每个其他代理的真实策略。我们使用一个概率网络,并最大化输出另一个代理的观察行为的对数概率。

其中我们示出了第 I 个代理的损失函数,用熵正则化器估计第 j 个代理的策略。结果,当我们用我们的预测行为替换代理行为时,我们的 Q 值目标变成了一个稍微不同的值!

那么,我们到底做了什么?我们已经排除了所有特工都知道彼此政策的假设。相反,我们试图训练代理人通过一系列观察来正确预测其他政策。实际上,每个代理都是通过从环境中提取全局信息来独立训练的,而不是自动将它放在手边。

照片由蒂姆·莫斯霍尔德Unsplash 拍摄

政策组合

上述方法有一个大问题。在许多多智能体环境中,特别是在竞争环境中,智能体可以制定策略来适应其他智能体的行为。这使得策略变得脆弱、不稳定,并且通常是次优的。为了弥补这一点,MADDPG 为每个代理训练了一组子策略。在每个时间步,代理随机选择一个子策略来选择操作。然后,执行。

政策梯度略有改变。我们对 K 子策略进行平均,使用线性期望值,并通过 Q 值函数传播更新。

后退一步

这概括了整个算法!在这一点上,重要的是后退一步,内化我们到底做了什么,并直观地理解它为什么有效。本质上,我们做了以下事情:

  • 为仅使用本地观察的代理定义参与者。这有助于抑制呈指数增长的状态和动作空间的影响。
  • 为每个使用联合信息的代理定义了一个集中的评论家。这有助于减少非平稳性的影响,并引导参与者使其对全球系统最优
  • 定义策略推理网络以评估其他代理的策略。这有助于限制代理的相互依赖性,并消除代理对完美信息的需求。
  • 已定义的策略集合,以减少过度适应其他代理策略的影响和可能性。

该算法的每个组件都服务于一个特定的委托目的。这就是 MADDPG 成为强大算法的原因:它的各种组件都经过精心设计,可以克服多智能体系统通常会遇到的巨大障碍。接下来,我们来看看算法的性能。

照片由反推去飞溅上拍摄

结果

MADDPG 在许多环境中进行了测试。有关其性能的完整概述,请随意查阅本文[1]。这里我们只讨论协同通信任务。

环境概述

这里有两个代理:一个说话者和一个听者。在每一次迭代中,听者会得到一个彩色的路标,并得到与路标距离成反比的奖励。这里有个问题:听者只知道它的相对位置和所有地标的颜色。它不知道应该去哪个地标。另一方面,说话者知道这一集的正确地标的颜色。因此,两个代理必须进行通信和协作来解决任务。

比较

在这项任务中,该论文将 MADDPG 与最先进的单代理方法进行了对比。通过使用 MADDPG,我们可以看到显著的改进。

还表明,即使策略并不完美,策略推断也能获得与使用真实策略观察相同的成功率。更好的是,收敛速度没有明显放缓。

最后,政策组合显示了有希望的结果。论文[1]测试了竞争环境中的群体效应,并证明了比只有一种策略的代理人明显更好的性能。

结束语

就是这样!在这里,我们综述了一种新的方法来解决多代理强化学习问题。当然,在“MARL 保护伞”下有无穷无尽的方法,但是 MADDPG 为解决多代理系统的最大问题的方法提供了一个强有力的起点。

参考

[1] R. Lowe,Y. Wu,A. Tamar,J. Harb,P. Abbeel,I. Mordatch,混合合作竞争环境下的多主体行动者-批评家 (2018)。

从经典到最新,这里有讨论多代理和单代理强化学习的相关文章:

[## DeepMind 的虚幻算法解释

最佳深度强化学习

towardsdatascience.com](/how-deepminds-unreal-agent-performed-9-times-better-than-experts-on-atari-9c6ee538404e) [## 分层强化学习:封建网络

让电脑看到更大的画面

towardsdatascience.com](/hierarchical-reinforcement-learning-feudal-networks-44e2657526d7)

OpenCV:用代码掌握计算机视觉基础的完全初学者指南!

原文:https://towardsdatascience.com/opencv-complete-beginners-guide-to-master-the-basics-of-computer-vision-with-code-4a1cd0c687f9?source=collection_archive---------3-----------------------

入门

包含代码的教程指南,用于掌握计算机视觉的所有重要概念,以及如何使用 OpenCV 实现它们

图片由 Gerd AltmannPixabay 拍摄

计算机视觉可能是人工智能中最有趣、最迷人的概念。计算机视觉是一个跨学科的领域,研究计算机或任何软件如何学习对周围环境可视化的高级理解。获得这个概念透视图后,自动化任务或执行所需的操作会很有用。

对人脑来说显而易见的任务对计算机来说并不那么直观,因为它们需要经过专门的训练才能产生有效的结果。这个过程涉及复杂的步骤,例如从现实世界中获取数据,以合适的格式处理获取的数据,分析处理后的图像,最后教导和训练模型以非常高的精度执行复杂的任务。

为了更直观地理解计算机视觉,让我们考虑一个例子。假设你必须教一台计算机区分各种颜色。考虑一下,你有三个颜色的物体,即红色、蓝色和绿色,你想相应地区分这些颜色。这项工作对于人脑来说是一项极其简单的任务,但对于计算机来说却是一项相当复杂的任务。

上面提到的任务是使用计算机视觉可以执行的最基本的动作之一。我们将了解数字世界中的图像是如何工作的,并试图理解图像以及这些堆叠的层到底是如何工作的。。我们还将深入了解 open-cv 模块的基础知识。最后,我们也将使用这个库实现一些基本级别的项目。因此,事不宜迟,让我们深入了解掌握基本计算机视觉技能所需的所有方面。

处理图像:

作者截图

这三种颜色,即红色、绿色和蓝色的组合可以用来组合几乎任何其他颜色。将它们以正确的比例混合,我们就可以设计出任何其他想要的颜色。这个概念从几十年前的阴极射线电视就存在了。那么这到底是怎么回事呢?

每种颜色都有一个 8 位的整数值。这意味着这些矩阵的范围可以从 0 到 255。这是因为 2⁸是 256,0–255 由 256 个值组成。这些颜色中的每一种都有一个这个范围的值,因为我们有一个三维图像,我们可以将这些颜色相互叠加。这可能是一个稍微复杂的例子,所以让我们切换到灰度图像,它只包含黑色和白色,这将更容易理解。下面是灰度表示。

作者截图

上面显示的灰度表示应该是更好地理解图像在计算机视觉中如何工作的概念的良好起点。下图显示了当我们从第 0 个标记移动到第 255 个标记时,等级变化是如何开始发生的。经过 256 级的变化,我们从全黑的阴影变成全白的阴影。

作者截图

这只是一种颜色。灰度图像在 0 处的值为黑色,在 255 处的值为白色。仅使用通道数= 1 的灰度图像模式,我们能够获得如下所示的复杂图像。

作者修改的截图。原始来源维基

即使只有一个频道,我们也能够实现如此酷的画面。现在想象一下,你有三种颜色,分别是红色、绿色和蓝色,你把它们一个叠在另一个上面,你就能得到理想的 RGB 颜色的完美图像。让我们看看用三个通道得到的图像,注意到颜色图案的显著增加。

图片来自维基

上面的图像是当所有三个通道堆叠在一起。请注意,上面的图片有一个红色、绿色和蓝色的图像,它们都被放置在一个三维矩阵中,这给了我们上面所需的图像。我希望这个解释能让你对如何在计算机视觉中处理图像有一个简单的概念。有了对图像工作原理的简单理解,你就可以相应地理解我们接下来遇到的几个模型。现在,让我们深入 python 中的开放 cv 模块,执行一些计算机视觉任务。

使用 OpenCV 和计算机视觉

现在我们已经简单了解了图像是如何工作的,我们可以进一步学习 openCV 库,以及如何利用这个模块来执行计算机视觉任务。OpenCV 模块是迄今为止执行复杂机器学习、深度学习和计算机视觉任务的最佳模块。它为正在构建的模型的分析和性能提供了简单性和高标准。它是一个开源库,可以与 NumPy 等其他 python 模块集成,以完成复杂的实时应用程序。它被广泛的编程语言所支持,并且可以在大多数平台上运行,比如 Windows、Linux 和 MacOS。

opencv 模块的安装过程非常简单。我提到了安装 openCV for python 以及在 anaconda 虚拟环境中构建模块的两种方法。请随意选择最适合你的方法。

安装:

openCV 的简单安装过程可以通过在命令提示符下使用以下命令来完成。

pip install opencv-python

如果您正在使用 anaconda 环境,那么您也可以选择使用下面的安装过程在您的虚拟环境中构建库 opencv 模块。在 anaconda 命令终端中键入下面的命令。

conda install -c conda-forge/label/cf202003 opencv

一旦我们完成了安装过程,我们可以专注于一些编码。今天,我们将主要讨论计算机视觉的三个基本方面,即:

  1. 阅读、书写和查看图像。
  2. 用 openCV 绘图
  3. 访问网络摄像头

所以,事不宜迟,让我们从这三个基本概念开始。

1.读取、写入和查看图像:

我们将连续执行这三项任务。图像的读取、显示和写入是计算机视觉的重要组成部分,因为你必须始终如一地处理图像。除了前面提到的优点之外,opencv 最大的优点是它还允许您访问各种图像格式。因此,我们可以处理所有这些图像格式,而不会面临任何重大问题。在本节的剩余部分,我将使用 lena.png 图像格式。

您可以随意下载相同的图像并跟随。下载图像并将其放在与 python 文件相同的文件夹或目录中。这将有助于我们直接访问图像,而无需不断提及查看各个图像的路径。一旦您将图像放在与 python 文件相同的位置,我们就可以开始访问它们,并使用 opencv 模块提供的各种功能。让我们从相应地导入和读取图像开始。

  • 读取并显示图像:

在任何计算机视觉任务中,最重要的事情显然是知道如何阅读图像并恰当地显示它。

作者截图。原始来源维基

这里的第一步是导入 cv2 模块。这是检查安装是否成功的方法。一旦导入了 cv2 模块,运行上面的程序,使用相应的代码行来读取图像。cv2.imread 执行 pillow 模块的类似任务,您可以使用 open()来读取您选择的图像。一旦你阅读了图像,你需要一些方法来显示下面的图像。完成这项任务主要有两种方法。

第一种方法是使用 cv2.imshow()命令,如上面的代码块所示。必须给出 waitKey()命令,以确保在传递 cv2.imshow()命令时打开的 cv2 窗口保持不变。waitKey()中的数字表示图像显示的时间。使用的时间段以毫秒为单位。处理上述图像分析的第二种方法是利用 matplotlib 库模块。使用 matplotlib 库模块中的 pyplot 函数,我们可以使用 plt.imshow()函数直接显示 jupyter 笔记本中的图像,而不必显示使用 cv2.imshow()时出现的 cv2 图形窗口。然而,你必须确保将其转换为 RGB 图像,因为 cv2 出于某种原因使用了 BGR 格式。我将在同一节的后续主题中探讨这个概念。

让我们通过使用 image.shape 属性来分析我们正在处理的图像的主要特征。利用这一点,我们可以计算出图像显示的所有维度和通道数。以下是存储在您的目录中的我们的 lena.png 图像的特征—

Height of the Image = 512Width of the Image = 512Number of channels = 3

图像的高度和宽度为 512 像素。上面图像的通道数量显然是三个,因为我们主要使用三种颜色,即红色、蓝色和绿色。分析完我们的图像和尺寸后,我们可以进入本节的下一个主题,处理图像的书写。

  • 写图像:

在这一节中,我们将看看如何编写图像,并将其保存到我们的桌面。我将展示的例子很简单,我将重写我们阅读时的相同图像。不过,你可以随意绘制自己的图像,用文件格式书写,并适当地保存它们。下面显示的代码行准确地展示了如何将图像写入桌面并保存。

作者截图

以上图片取自我各自的文件夹/目录,你可以看到那里有两张图片。一个是原始的 Lena 图像,另一个是我们编写的图像,即 lena1 图像。您也可以指定您想要写入和保存图像的路径。现在,我们已经了解了如何执行读取图像、显示图像以及写入和保存图像的基本操作,我们可以进入下一个主题,学习如何操作这些图像。

  • 调整图像大小:

现在,我们已经对计算机视觉的基本操作有了一个简单的了解,让我们继续了解我们可以处理图像的方式。这对于需要有效执行的特定任务非常有用和重要。调整大小功能帮助我们将图像调整到不同的维度。我们可以选择让它变大或变小,这完全取决于用户,也高度依赖于正在执行的任务。下面是代表调整图像大小的代码块。我已经将原始图像的尺寸减半,以得到一个只有原始图像一半大的新图像。

作者修改的截图。原始来源维基

上面的图片展示了我们如何成功地处理现有的图片,并将其缩放至更大或更小的维度。这在需要特定尺寸的图像以更有效地执行任务的各种应用中非常有用。这方面的一个例子可以是我们建立的迁移学习深度神经网络模型。

  • 转换成灰度图像:

处理图像功能的下一个方法是将它们转换成灰度图像。这有时是一个极其重要的步骤,因为它有助于减少正在训练的模型的负荷。与处理 RGB 图像相比,处理灰度图像相对简单。对于不具有用于处理和计算 RGB 图像的有效资源的模型,可以增加计算强度。将 RGB 图像惯例转换为灰度图像惯例的步骤正如下面的代码块中所引用的。cv 模块有一个内置系统,可以有效地将这些彩色图像计算为灰度图像。

作者修改的截图。原始来源维基

OpenCV 使用 BGR,而不是标准的 RGB 约定,所以不要对将 RGB 图像转换为灰度图像时使用的这一特定概念感到困惑。这在前面的章节中也有提及。当您试图在 opencv 读取图像上实现 matplotlib 库时,您可能会将它读取为 BGR 图像格式,而不是 RGB 格式。这个问题可以通过使用计算机视觉模块提供的简单转换颜色操作来解决。

  • 模糊图像:

在这一部分,我们要研究的最后一个任务是图像的模糊化。模糊图像的主要原因是为了消除影响实际图像性能的外部噪声,并帮助平滑图像。这就像使用基于内核的滤波技术来处理图像中的不均匀性和整体噪声分布。低强度边缘也被去除,这对于更好的处理和提高图像的整体质量是非常有用的。出于安全目的或隐私问题,它也可用于隐藏数据。以下代码块可用于通过 opencv 模块激活模糊操作。类似于灰度和重新缩放操作的模糊操作广泛用于处理各种计算机视觉任务。

作者修改的截图。原始来源维基

高斯模糊是图形软件中广泛使用的效果,通常用于减少图像噪声和细节。在应用于机器学习或深度学习模型之前,它也用作预处理阶段。(19,19)是我用来在现有图片上获得更模糊图像的内核大小。确保只使用奇数个内核,而不是偶数个。您可以更改和编辑(19,19)的内核大小,使其更适合您的目的。

这就完成了处理图像的第一部分。下一步是看看我们如何使用 opencv 模块来绘图。这个概念是掌握计算机视觉的下一个重要课题。让我们继续下一节,学习如何画一些重要的图表。

2.使用 OpenCV 绘图:

接下来是一些显而易见的绘图方法,可以使用 opencv 模块来使用和实现。因此,我们将更快地了解每一个,并直观地理解它们。让我们从使用这个库画一条简单的线开始。

  • 画线:

下面的代码块是用于在 cv2 图形窗口中绘制简单线条的方法。第一个命令是确保显示的整个图像是黑色的,以获得更好的视觉效果。如果更适合你,你可以选择使用传统的白色背景方法。然后,我们定义一条要绘制的线,如下所示:

  1. 应该绘制线条的图像。
  2. 具有 x 和 y 坐标的起点。
  3. 具有 x 和 y 坐标的终点。
  4. 在下一个属性中,我们将为线条分配颜色。这里的格式是 BGR。利用我使用的方法,我们可以得到一条蓝线。
  5. 属性的最后一个槽定义了线条的粗细。

作者截图

上图是一条对角线穿过整个图形窗口的示意图。您可以使用首选的起点和终点坐标来可视化和显示线。

  • 画矩形:

opencv 模块允许我们执行的下一个操作是绘制矩形。这可以通过使用下面的代码块有效地完成。我不会对此解释太多,因为它与之前提到的画线非常相似。在这里,您还可以定义一个起点和终点,如果定义的点符合要绘制的矩形,那么操作将成功执行。

作者截图

上图是在图形窗口中心绘制的一个矩形。您可以在任何方向和维度渲染图像,也可以改变颜色。

  • 画圆:

opencv 库也允许我们以类似于直线和矩形的方式画一个圆。然而,在画圆的时候有一个关键的区别。您需要给出一个中心位置点,并给出 x 和 y 中心坐标点。在这一步之后,您可以指定圆的半径。圆的半径将决定圆的大小,你也可以根据自己的喜好调整颜色和粗细。下面的代码块显示了如何在 opencv 模块的帮助下绘制一个圆的精确表示。

作者截图

从中心绘制的黄色圆的图像。像往常一样,您可以使用各自的坐标、颜色和可变厚度的半径来渲染您的圆。

  • 插入文字:

我们已经完成了大部分的绘图,但是在某些时候,向显示的图像添加一些文本也变得很重要。幸运的是,opencv 允许我们访问 putText()命令,该命令可用于在图形窗口中添加文本可视化。下面的代码块精确地描述了如何执行这项任务。我在这个代码块中使用了 Hershey Simplex 字体,但是我强烈建议你们查看 opencv 中的各种字体选项,并根据自己的喜好选择一种。选择要以正确的尺寸、字体、所用字体的比例、颜色、粗细和可选线型显示的图像和文本。我还建议观众深入了解各种可用的线型选项。

作者截图

图像显示文本计算机视觉显示在中心。我为我的文本选择了红色,厚度为 3。请根据您的喜好随意尝试各种选项,并探索更多信息。只有通过探索和实践,才能真正掌握计算机视觉和人工智能。

  • 绘制多边形:

在进入下一个主题之前,这是我们将在本节中执行的最后一个绘图操作。opencv 模块中的折线函数可以用来绘制任何你想要的东西。从下面的代码块可以看出这个函数的主要方法。我正在下图中构建一个六边形。我已经提到了一个由 6 个点组成的数组,包含了正在设计的六边形的各个位置。一旦数组设计成功,我们有了所有必要的点,我们就把它重新塑造成一个多边形曲线数组。我们确保它是一个封闭的多边形图像,最后定义颜色属性来用它各自的颜色表示多边形。

作者截图

以上表示属于六边形。不用说,通过使用折线方法,您可以使用此方法来绘制任何其他多边形大小的图像。我们也可以用这种方法画三角形、正方形和长方形。只要确保你定义了正确的坐标数,并且它们都排列在正确的位置上。

我们已经成功地完成了计算机视觉模块中涉及的所有绘画基础知识。在我们进入最后一个话题之前,我想重申实践和探索是计算机视觉成功的关键。有了这些计算机视觉的基础知识,你可以尝试 opencv 中的绘图功能来设计一些非常酷的东西。如果你对这个项目感兴趣,那么请给我发你设计的截图。我很想看看你们设计的东西。

让我们转到本节的最后一个主题,我们将讨论如何访问网络摄像头的所有复杂细节,这对计算实时和现实生活场景非常有用。因此,让我们进入下一部分,更详细地理解这个主题。

3.访问网络摄像头:

我们已经到了本节的最后一部分,即访问您的网络摄像头进行实时以及实时图像或视频分析。这种访问对于实时对象检测、人脸识别、视频监控以及许多其他应用非常有用。Opencv 允许您访问外部摄像机,并为您提供选择您想要选择的摄像机的选项。与我们查看图像的方式相比,同样的选项也可以用于以类似的方式查看图像。访问您的网络摄像头的步骤可以通过以下方式完成:

让我们从概念上详细理解上面代码块中的每一行。cap 变量用于捕获和访问网络摄像头。当网络摄像头捕捉视频存在时,我们将在此过程中显示的外部 cv2 图形窗口中逐个图像地读取相应的视频图像。我们将给出前面章节中指定的 waitKey 命令。如果在视频运行期间按下按钮“q ”,则程序会立即退出图形窗口,无法执行其他操作。cap.release()命令用于释放网络摄像头,而 destroy all windows 命令用于退出并销毁基于 cv2 的图形窗口。

如果你想播放文件夹中保存的视频,这也很容易做到。如果您选择指定视频文件的播放位置,而不是指定要使用的外部网络摄像头选项,那么您将能够获得类似的结果。您可以成功播放您想要的视频。只是为了确保我们都在同一页上,您不会被本段中的陈述所混淆,请遵循下面的代码行,以便执行和播放您选择的视频。

Video = cv2.VideoCapture(“your path”) # Read The Video

至此我们已经结束了处理计算机视觉问题语句的基本概念,以及如何有效地使用 opencv 模块来成功地实现期望的任务。然而,这并不是结束,因为我们仍然需要知道这些知识将如何帮助我们解决更复杂的计算机任务,以及我们需要执行的这些任务到底是什么。为了对此有一个更具战略性的理解,让我们在本文的下一部分详细看看计算机视觉的应用。

照片由来自佩克斯克里斯蒂娜·莫里洛拍摄

计算机视觉的应用

除了本文前面讨论的所有内容之外,还有数十亿个项目可供您选择。我将提到其中的几个项目和它们背后的方法论,如果你觉得舒服的话,你也可以尝试一下。在这一节的最后,我还会给你们提供一个有用的链接来帮助你们,并指导你们完成五个计算机视觉项目。让我们深入研究计算机视觉的应用。

  1. 人脸检测和人脸识别项目是一些最受欢迎的计算机视觉项目。人脸识别是对人脸以及用户授权姓名的程序性识别。人脸检测是一个更简单的任务,可以被认为是一个初级水平的项目。人脸检测是人脸识别的必要步骤之一。人脸检测是一种将人脸与身体的其他部分和背景区分开的方法,而人脸识别执行包围人脸并识别特定人是谁的任务。
  2. 对象检测和对象跟踪是计算机视觉项目的其他流行选择。对象检测是一种计算机视觉技术,它允许我们在图像或视频中识别和定位对象。通过这种识别和定位,可以使用对象检测来计数场景中的对象,并确定和跟踪它们的精确位置,同时准确标记它们。对象跟踪是识别特定对象并在整个视频中或实时跟踪已经识别的对象的任务。
  3. 图像分割任务对于协调和可视化周围环境以及训练程序执行特定任务非常有用。经过训练的模型能够在基于内容的图像检索、交通控制和分析系统、视频监控和生物医学领域等任务上取得良好的结果,用于不同的预定目的。图像分割的任务是对特定帧或图像中具有固定名称的每个对象进行分类,并根据颜色、图案或某些固定特征对它们进行相应的计算。
  4. 光学字符识别——这是另一个最适合初学者的基础项目。光学字符识别是通过使用电子或机械设备将二维文本数据转换成机器编码的文本形式。你使用计算机视觉来阅读图像或文本文件。读取图像后,使用 python 的 pytesseract 模块读取图像或 PDF 中的文本数据,然后将它们转换为可以在 python 中显示的数据字符串。光学字符识别在数据输入、帐单细节、OCR 接收器和 OCR 客户端、任务等方面有各种应用。,以及许多其他使用案例。
  5. 情绪或手势识别是另一个令人惊叹的计算机视觉应用,它使用深度学习技术和计算机视觉来执行高度复杂的任务,如情绪和手势识别。根据相对于特定面部的情绪显示的情绪来检测和分类各种面部。这些模型不仅对情绪进行分类,而且还相应地对所识别的手指的不同手势进行检测和分类。在区分人的情绪或姿势之后,由训练的模型分别提供对人的情绪或姿势的准确预测的声音响应。这是一项稍微复杂的任务,需要许多步骤才能成功完成。关于如何从头开始开发这些项目的更多链接,请参考结论部分。你可以按照我的指导,自己从头开始实现这些项目。

如果你有兴趣更深入地研究计算机视觉这个令人惊奇的课题,想从概念上更好地理解与之相关的所有方面,那么从事各种各样的项目是一个不错的选择。我强烈推荐你们看看下面链接中我以前的一篇文章,看看你们可以尝试的五个很棒的计算机视觉项目。它们都有参考链接来帮助你,指导你努力完成你选择的项目。

[## 5 个关于 Python、机器学习和深度学习的超棒的计算机视觉项目创意!

讨论 5 个很酷的计算机视觉项目,学习新的技能,增强你的简历

towardsdatascience.com](/5-awesome-computer-vision-project-ideas-with-python-machine-learning-and-deep-learning-721425fa7905)

照片由 Cookie 在 Unsplash 上的 Pom 拍摄

结论:

计算机视觉教程到此结束。我希望这个指南对你们所有人有所帮助,帮助你们巩固基础知识,理解这个难以置信的跨学科领域的重要方面。理解事物的内部工作方式在计算机视觉中至关重要,因为这有助于你弄清楚计算机究竟是如何分析和处理数据的,以及欣赏其方法背后的美。

我希望这些带有详细解释的例子能帮助你们更直观地理解 open-cv 的概念。如果您有任何疑问、问题或与此相关的问题,请随时打电话给我,让我知道您不明白的地方。我会尽力给你解释,帮你从概念上解决。在下一篇教程中,我将详细介绍人脸检测,以及它是如何从头开始工作的。敬请关注!

对于一些更棒的计算机视觉项目,请查看下面的链接。这些包括面部识别、情感和手势检测。我将在未来发布更多的计算机视觉项目,所以请关注即将到来的文章。

[## 智能面部锁定系统

建立高精度人脸识别模型

towardsdatascience.com](/smart-face-lock-system-6c5a77aa5d30) [## 使用深度学习的人类情感和手势检测器:第 1 部分

了解如何从零开始构建具有深度学习的人类情感和手势检测器。

towardsdatascience.com](/human-emotion-and-gesture-detector-using-deep-learning-part-1-d0023008d0eb) [## 使用深度学习的人类情感和手势检测器:第 2 部分

深入探究人类情感和手势识别

towardsdatascience.com](/human-emotion-and-gesture-detector-using-deep-learning-part-2-471724f7a023)

从下面的链接查看我最近的两篇表现良好的文章:

[## 迷失在密林中:用简单的代码对机器学习中稀疏性的直觉!

为什么 ML 需要稀疏性?理解稀疏性的核心概念。

towardsdatascience.com](/lost-in-a-dense-forest-intuition-on-sparsity-in-machine-learning-with-simple-code-2b44ea7b07b0) [## 神经网络拿 TensorFlow 游乐场开玩笑!

使用 TensorFlow Playground 探索神经网络并从中获得乐趣

towardsdatascience.com](/neural-networks-made-fun-with-tensorflow-playground-4e681a0c4529)

谢谢你们坚持到最后。我希望你们都喜欢这本书,并学习了计算机视觉的基础知识。再次感谢你们,我希望你们都有美好的一天!

OpenCV + CUDA + AWS EC2 +(不再流泪)

原文:https://towardsdatascience.com/opencv-cuda-aws-ec2-no-more-tears-60af2b751c46?source=collection_archive---------3-----------------------

将 OpenCV 库与 CUDA 驱动程序绑定以支持对 OpenCV 代码进行 GPU 处理的逐步说明。

克里斯蒂安·威迪格在 Unsplash 上拍摄的照片

默认情况下,不需要为 GPU 处理启用 OpenCV 和 CUDA,但在生产过程中,当您需要对图像/视频文件进行大量 OpenCV 操作时,我们可以利用 OpenCV CUDA 库来使这些操作在 GPU 而不是 CPU 上运行,这样可以节省大量时间。

据说连接 OpenCV 库使其与 CUDA 兼容并不容易,我不得不经历一周的痛苦过程来正确地建立连接,这也是一个既费时又费钱的过程。所以这次我想记录下整个过程,为了我的未来,也为了别人。

为了进行演示,我在 AWS 中租用了一个 EC2 实例和一个 p3.8xlarge 实例,它有 4 个 Nvidia GPUs。

来源— AWS EC2 定价

因此,如果你在第一次启动 EC2 实例时需要任何帮助,你可以参考我以前关于在 AWS 中逐步创建 EC2 实例的文章,并通过 Putty & WinSCP 访问它,在此过程中选择你需要的 GPU 实例。

现在,在进入实例之后,在我们进入流程之前,我们需要安装许多包来准备好环境。

注意:我已经合并了我从头到尾运行的所有命令,并将它们添加在底部。如果你更好奇的话,可以在这个 链接 中找到它们,然后跟着一起走。

在您的实例上一个接一个地运行下面的命令,并且我已经证实了截图,将输出与我的进行比较。

下文使用的所有截图均来源于作者。

目录:

  1. 安装 OpenCV 依赖、Nvidia CUDA 驱动、CUDA 工具包
  2. 下载 OpenCV 源代码
  3. 配置 Python 虚拟环境
  4. 确定你的 CUDA 架构版本
  5. 配置支持 Nvidia GPU 的 OpenCV
  6. 编译 OpenCV 并创建一个符号链接
  7. 参考文献
  8. 命令历史

第一步:安装 OpenCV 依赖,Nvidia CUDA 驱动,CUDA 工具包。

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install build-essential cmake unzip pkg-config
sudo apt-get install gcc-6 g++-6
sudo apt-get install screen
sudo apt-get install libxmu-dev libxi-dev libglu1-mesa libglu1-mesa-devsudo apt-get install libjpeg-dev libpng-dev libtiff-dev
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-devsudo apt-get install libxvidcore-dev libx264-dev
sudo apt-get install libopenblas-dev libatlas-base-dev liblapack-dev gfortransudo apt-get install libhdf5-serial-dev
sudo apt-get install python3-dev python3-tk python-imaging-tk
sudo apt-get install libgtk-3-dev
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt-get update
sudo apt-get install nvidia-driver-418
sudo reboot

安装完成后,重新启动系统。一旦你的系统启动,键入nvidia-smi,它应该会给出类似的输出,正如你在下面的代码片段中看到的,我用 4 个特斯拉 v100 GPUs 供电。

mkdir installers
cd installers/
wget [https://developer.nvidia.com/compute/cuda/10.0/Prod/local_installers/cuda_10.0.130_410.48_linux](https://developer.nvidia.com/compute/cuda/10.0/Prod/local_installers/cuda_10.0.130_410.48_linux)mv cuda_10.0.130_410.48_linux cuda_10.0.130_410.48_linux.run
chmod +x cuda_10.0.130_410.48_linux.run
sudo ./cuda_10.0.130_410.48_linux.run --override

这是所有步骤中最重要的一步,我在网上找到的大多数文章中都没有详细说明,并且花了一天多的时间来解决这个难题。

在您阅读并接受 EULA 协议后,有一些是(y)/否(n)命令,并根据下面的回答填写。

现在,在你成功地安装之后,你将被提供需要被添加到 bashrc 文件的路径,并且以后来源它。

sudo vim ~/.bashrc
source ~/.bashrc
nvcc -V

记下#NVIDIA CUDA Toolkit 下的命令,并根据您在之前的命令中获得的路径添加它们。

# NVIDIA CUDA Toolkit
export PATH=/usr/local/cuda-10.0/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-10.0/lib64:$LD_LIBRARY_PATH

现在找到它,保存更改并在以后安装一些依赖项。

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install build-essential cmake unzip pkg-config
sudo apt-get install libjpeg-dev libpng-dev libtiff-dev
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install libgtk-3-dev

第 2 步:下载 OpenCV 源代码

现在我们需要下载 OpenCV & OpenCV contrib 并手动运行它们的安装文件。这里我使用的是 OpenCV 包的 4.2.0 版本。

cd ~
wget -O opencv_contrib.zip [https://github.com/opencv/opencv_contrib/archive/4.2.0.zip](https://github.com/opencv/opencv_contrib/archive/4.2.0.zip)wget -O opencv.zip [https://github.com/opencv/opencv/archive/4.2.0.zip](https://github.com/opencv/opencv/archive/4.2.0.zip)unzip opencv.zip
unzip opencv_contrib.zip
mv opencv-4.2.0 opencv
mv opencv_contrib-4.2.0 opencv_contrib

步骤 3:配置 Python 虚拟环境

在这里,我们使用一个虚拟环境,并将在此后的环境中构建 OpenCV CUDA 的绑定。

在这一部分,我将使用virtualenvvirtualenvwrapper作为虚拟环境。

wget [https://bootstrap.pypa.io/get-pip.py](https://bootstrap.pypa.io/get-pip.py)
sudo python3 get-pip.py
sudo pip install virtualenv virtualenvwrapper
sudo rm -rf ~/get-pip.py ~/.cache/pip

安装完这些包后,您需要在~/.bashrc中添加这些行,以便让 bash 在每次终端启动时加载 virtualenv 和 virtualenvwrapper:

sudo vim ~/.bashrc

# Add them inside bashrc# virtualenv and virtualenv wrapper
export WORKON_HOME=$HOME/.virtualenvs
export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
source /usr/local/bin/virtualenvwrapper.sh

现在在添加之后,来源它。现在跑source ~/.bashrc

# Create a virtual environment. The first step is to create a virtual environment:mkvirtualenv opencv_cuda -p python3
pip install numpy
nvidia-smicd ~/opencv
mkdir build
cd build

在这里,我在虚拟环境中安装 Numpy 库。

步骤 4:确定您的 CUDA 架构版本

要找到架构,运行nvidia-smi并记下您被分配到的 Nvidia GPU 的名称。对我来说,我有特斯拉 v100

作为一名经验丰富的 CUDA 程序员,确定 CUDA 架构版本是一项必需的实践,因为它让编译器在您的 GPU 上生成更高效的代码。此外,设置不包括 Nvidia GPU 架构的架构参数会让您的程序在执行时无法工作。

我们可以用nvidia-smi算出你的 Nvidia GPU 是什么型号:

获得 Nvidia GPU 模型后,您可以使用此页面找到您的 CUDA 架构:

https://developer.nvidia.com/cuda-gpus

向下滚动到“您的 GPU 计算能力”段落。由于我使用的是 Nvidia Tesla v100,我将点击“支持 CUDA 的 Tesla 产品”部分。

检查后,我意识到我的 Nvidia GPU 架构版本是7.0。提醒一下,您的 GPU 架构版本可能会有所不同。

一旦你得到了 GPU 架构版本,请记下它,因为我们将在下一步使用它。

来源— Nvidia 的开发者网站

步骤 5:用 Nvidia GPU 支持配置 OpenCV

OpenCV 使用 CMake 来配置和生成构建。首先,激活opencv_cuda虚拟环境,如果之前没有启用的话。

同样在 CMake 命令中,在参数 CUDA_ARCH_BIN=x.x 中,将它替换为您在上一步中获得的计算容量版本。这里我用的是 7.0,请换成你的版本。

cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D INSTALL_PYTHON_EXAMPLES=ON -D INSTALL_C_EXAMPLES=OFF -D OPENCV_ENABLE_NONFREE=ON -D WITH_CUDA=ON -D WITH_CUDNN=OFF -D OPENCV_DNN_CUDA=ON -D ENABLE_FAST_MATH=1 -D CUDA_FAST_MATH=1 -D CUDA_ARCH_BIN=7.0 -D WITH_CUBLAS=1 -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules -D HAVE_opencv_python3=ON -D PYTHON_EXECUTABLE=~/.virtualenvs/opencv_cuda/bin/python -D BUILD_EXAMPLES=ON ..

还有一点,检查 CMake 输出的Python 3部分的install path。我们将使用install path它。所以请留下T5 的备注。

步骤 6:编译 OpenCV 并创建一个符号链接

如果cmake没有错误地退出,那么用下面的命令编译 OpenCV。

需要注意的是,在运行下一个命令之前,最少需要 45 分钟,最多需要 5 个小时,请确保 ssh 连接没有超时,如果您通过 putty 访问它,请每隔 15 分钟按一次 Enter 键。

make -j$(nproc)
sudo make install
sudo ldconfig

ls -l /usr/local/lib/python3.6/site-packages/cv2/python-3.6cd ~/.virtualenvs/opencv_cuda/lib/python3.6/site-packages/ ##Next, create a sym-link to your virtual environment: ##ln -s /usr/local/lib/python3.6/site-packages/cv2/python-3.6/cv2.cpython-36m-x86_64-linux-gnu.so cv2.so

然后,我们将创建一个符号链接,将 OpenCV Python 绑定到您的 Python 虚拟环境中。如前一步所述,我们知道install path就是/usr/local/lib/python3.6/site-packages/cv2/python-3.6

要确认,您可以使用ls命令:

您可以看到我的 OpenCV Python 绑定的名称是cv2.cpython-36m-x86_64-linux-gnu.so(您自己构建的绑定可能有一个类似的名称)。

接下来,创建一个指向虚拟环境的符号链接:

记得花点时间检查你的文件路径,因为如果 OpenCV 绑定的路径不正确的话,ln会让无声地失败

验证安装— OpenCV Python

运行 OpenCV + CUDA 启用的代码,而不是 OpenCV 代码,这一次,它似乎工作。

因此,大多数 OpenCV 函数都可以用 CUDA 包装,要查看可用的函数,请在 Python IDE 中运行命令。

## To check the supported methods for opencv in CUDA ##
import cv2print(dir(cv2.cuda))

检查它在与我的实例连接的 WinSCP 中的相应输出。

OpenCV CUDA 启用代码的输出,其中我调整了颜色通道的大小并将其转换为灰色。

因此,当您下次登录到您的实例并希望进入 OpenCV CUDA 环境时,请使用该命令。

这里我的虚拟环境的名字是“opencv_cuda”。

source ~/.virtualenvs/opencv_cuda/bin/activate

恭喜你,如果你已经在文章和实现中达到了这一点,现在你可以在 OpenCV CUDA 支持下部署生产级应用了。

参考

如果没有我在网上找到的这些惊人的参考资料,这对我来说是不可能的。

要了解更多细节,你可以访问其中任何一个。

https://github . com/spmallick/learnopencv/tree/master/Getting-Started-OpenCV-CUDA-Module

https://github . com/codecentric/computer-vision-drone/blob/master/_ posts/2017-02-18-install-opencv-on-AWS-with-cuda . MD

https://gist . github . com/Raul qf/f42c 718 a 658 cddc 16 f 9 df 07 ECC 627 be 7

https://developer.nvidia.com/cuda-10.2-download-archive?target _ OS = Linux&target _ arch = x86 _ 64&target _ distro = Ubuntu&target _ version = 1804&target _ type = runfile local

https://medium . com/@ sb . jaduniv/how-to-install-opencv-4-2-0-with-cuda-10-1-on-Ubuntu-20-04-lts-focal-fossa-BDC 034109 df3

https://medium.com/@Linh.NG/installing-opencv-3-3-0-on-Ubuntu-16-04-lts-7db 376 f 93961

https://cuda-Chen . github . io/image % 20 processing/programming/2020/02/22/build-opencv-dnn-module-with-NVIDIA-GPU-support-on-Ubuntu-1804 . html

https://www . pyimagesearch . com/2020/02/03/how-to-use-open CVS-dnn-module-with-NVIDIA-GPU-cuda-and-cud nn/

[## 使用 CUDA 支持编译 OpenCV-PyImageSearch

light,这样您就在支持 GPU 的系统上安装了 NVIDIA CUDA Toolkit 和 cuDNN 库。接下来呢?让我们…

www.pyimagesearch.com](https://www.pyimagesearch.com/2016/07/11/compiling-opencv-with-cuda-support/)

命令的历史记录:

正如我所说的,我正在添加合并的代码,我已经运行了很长时间,你可以按照上面相应的截图进行操作。

最后,作为一个预防措施,它花费了我 48 美元来制作这个帖子,还花费了我以前的实例破损的杂项费用,因为我以前由于不正确的绑定不得不终止多个实例。

确保根据您的使用情况使用相应的 GPU 实例。

在那之前,下次见。

文章作者:

BALAKRISHNAKUMAR V

OpenCV & AWS Rekognition:把一块纸板变成物联网智能开关

原文:https://towardsdatascience.com/opencv-rekognition-an-iot-smart-switch-with-a-piece-of-cardboard-3f3a64df18d6?source=collection_archive---------29-----------------------

我的物联网交换机

你有没有试过让 Alexa 打开被一大群尖叫的孩子包围的客厅的灯?难吗?那么在深夜,你会冒着吵醒孩子的风险,让 Alexa 关掉经常被遗忘的浴室灯吗?没错:你得从沙发上站起来。

在这些和许多其他情况下,最合适和可持续的智能开关是一张漂亮的纸板!你不相信吗?我带你去看。

它是如何工作的

没有诡计

几天前,我问自己如何使用安装在我家内外的安全摄像头,让它变得更加智能。

嗯!一个无声的 Alexa 替代品会很方便!

因此,我试图找到使用相机图像来生成事件的方法,例如打开或关闭灯泡。主要的想法是:识别一个容易识别的物体并阅读它上面的文字,简而言之就是一个标志!一个可以用来给我们的物联网设备下命令的标志。

目标检测

我使用树莓 PI4 来分析我的相机的视频流,并通过 CV2 库、其 DDN(深度神经网络)模块和 mobilenessd V2 可可模型来识别物体。

在浏览模型识别的物体类别时,一辆漂亮的“巴士”立刻吸引了我的目光。完美!一个很容易辨认的物体,而且几乎不在我的客厅里,只是为了避免引起假阳性。我选择用来装饰我的标志的图像立刻被模特认出是一辆公共汽车。太好了!

照片由赫森·罗德里格兹Unsplash 拍摄

然而,在不同的背景下使用该图像,结果并不乐观。其他已识别对象(人和沙发)的存在以及与整个图像相比我的公交车的尺寸减小,都影响了它的正确识别。

未检测到货车

寻找轮廓

我要放弃吗?不会吧!我们的标志是一个漂亮的长方形。为什么不检测图像中的矩形,提取其内容并将其用于对象检测?

边缘检测

去分析轮廓并寻找那些大约有 4 条边的轮廓,嘣!找到了!

矩形检测

现在,我可以将矩形中包含的图像提交给对象检测模型,是的!它被正确地识别为总线。

裁剪图像:检测到货车

文本识别

我对自己说:我们的总线是“激活图像”,就像“Alexa”这个词在 Echo 设备附近发音时是“激活词”。我只需要将图像提交给文本识别系统来识别命令并采取相应的行动。

我选择了云解决方案,使用 Amazon Rekognition。当在图像中识别出一辆公共汽车(或卡车或汽车)时,它就被转移到一个 S3 桶中,接受文本识别算法的处理。结果?非常好。

正确检测到文本

Detected text:ALL ON 
Confidence: 98.95% 
Id: 0 
Type:LINE

结论

现在,我只需根据 Amazon Rekognition 返回的文本运行命令。在我的情况下,我限制自己打开直接连接到 PI4 的几个 led,但这个限制是幻想!

完整的 源代码在这里

在幕后

关于实现同一个项目的一些提示:分辨率和相机的位置是非常重要的,需要调整以获得良好的效果。在 Raspberry PI4 上不要使用非常大的图像分辨率:有必要在文本识别系统所要求的质量和为其精心制作所请求的资源之间找到一个折衷。

要在 Raspberry 上安装 OpenCV,请检查这个链接。无缓冲视频捕捉类来自本帖。盒子识别是从这个页面开始的。

原载于 2020 年 1 月 16 日https://www . vittorionardone . it

1 部分—初始设置+深度(OpenCV 空间人工智能竞赛之旅)

原文:https://towardsdatascience.com/opencv-spatial-ai-competition-journey-part-1-e76593d456fe?source=collection_archive---------12-----------------------

罗伯特·诺顿在 Unsplash 上的照片

作为 OpenCV 空间竞赛一部分的盲人社交距离反馈系统开发之旅

更新:这篇文章是系列文章的一部分,我将记录我在 OpenCV 空间竞赛中为盲人开发社交距离反馈系统的旅程。查看完整系列: 第一部 第二部

OpenCV 空间人工智能竞赛

最近,OpenCV 的人发起了由 Intel 赞助的 OpenCV 空间 AI 竞赛,作为 OpenCV 20 周年庆典的一部分。竞赛的主要目标是开发受益于全新OpenCV AI Kit with Depth(OAK-D)特性的应用。比赛分为两个阶段,第一阶段的获胜者可以免费获得一台 OAK-D 来开发他们的应用程序,第二阶段的获胜者将获得高达 3,000 美元的现金奖励。

OAK-D 包含一个用于深度神经推理的 12 MP RGB 摄像头和一个使用英特尔 Myriad X Vision 处理器(VPU)进行实时深度估计的立体摄像头。

如果你想了解更多关于 OAK-D 的信息,请务必查看 Ritesh Kanjee 对 Brandon Gilles的采访,他是 OpenCV AI 套件的首席架构师。作为他们拥有 4000 多名支持者的 Kickstarter 活动的一部分,该工具包已经筹集了 80 多万美元。如果你有兴趣,你也可以在 Luxoni 的社区 slack 频道(https://luxonis-community.slack.com/)找到更多关于这个套件的信息

由于 OAK-D 的有趣特性,我决定申请 OpenCV 空间 AI 竞赛,并有幸被选为第一期的获胜者之一。您还可以在此 查看第一阶段剩余获奖者的项目

这篇文章是一系列文章的一部分,在这些文章中,我将描述作为我的竞赛项目的一部分,我与新 OAK-D 一起发展的旅程。

拟议系统

所提出的系统的输出如何能够检测戴面具的人以及他们与用户的距离的图示。

我的提案题目是“ 视障人士使用可穿戴相机的社交距离反馈 ”。由于目前新冠肺炎病毒在世界范围内的爆发,社交距离已经成为一种新的社会规范,作为防止疫情传播的一种措施。

然而,视力受损的人正在努力在新的社会距离常态中保持独立。对于盲人来说,不容易确认他们是否与周围的人保持着社会距离。例如,皇家国家盲人研究所(RNIB)推特账户 中的一个 视频展示了由于社会距离,盲人在日常生活中遇到的困难。

此外,常见的盲人解决方案(如白手杖或狗)无法帮助盲人保持社交距离。更糟糕的是,盲人无法知道他们身边的人是否戴着口罩,因此他们遭受感染的风险更高。

出于这些原因,我的项目的目标是为盲人开发一个反馈系统,告知周围其他人的距离以及某人是否没有戴面具。

对于这类项目,深度和人工智能需要实时结合,OAK-D 是理想的系统。如 德泰实验的一个例子所示,OAK-D 能够实时检测图像中人脸的位置,以及他们是否戴着面具。通过将该信息与从立体相机获得的深度信息相结合,可以估计用户周围的人的位置以及某人是否没有戴面具。

然后,该系统将使用连接到 OAK-D 板上的五个触觉电机通知用户与周围人的距离。触觉电机将与 5 个方向角相关:-40 度,-20 度,0 度,20 度和 40 度。例如,如果系统检测到有人在-20 度角附近(如上图所示),那么左边第二个电机将会振动。此外,为了告知人有多近,马达的强度将随着被检测的人越来越近而变化。最后,如果系统检测到有人没有戴面罩,系统将通过改变振动模式来通知用户。

Windows 安装和初始测试

本周我收到了 OpenCV AI 套件。如下图所示,该套件包含一个 OAK-D,一个 USB-C 电缆,一个 5V (3A)壁式充电器和一个 3D 打印的 GoPro 底座。

OAK-D. 的组成部分注:树莓 Pi Zero 不包含在套件中,仅用于比较尺寸。

OAK-D 的尺寸较小(46 x 100 毫米),呈 T 形。实际上,板的下部与 Raspberry Pi Zero 的宽度相匹配,因此将两块板组合在一起的系统可以具有紧凑的尺寸,如下图所示。

为了连接 OAK-D,Luxonis 的人开发了DepthAI Python API。DepthAI API 是开源的,可以在不同的操作系统上运行。查看官方安装网站了解如何安装:https://docs.luxonis.com/projects/api/en/latest/install/

i̶n̶c̶l̶u̶d̶i̶n̶g̶̶u̶b̶u̶n̶t̶u̶,̶̶r̶a̶s̶p̶b̶i̶a̶n̶̶a̶n̶d̶̶m̶a̶c̶o̶s̶.̶̶i̶n̶̶t̶h̶e̶̶c̶a̶s̶e̶̶o̶f̶̶w̶i̶n̶d̶o̶w̶s̶̶1̶0̶,̶̶a̶s̶̶o̶f̶̶t̶o̶d̶a̶y̶̶(̶a̶u̶g̶u̶s̶t̶̶8̶,̶̶2̶0̶2̶0̶)̶̶i̶t̶̶i̶s̶̶s̶t̶i̶l̶l̶̶e̶x̶p̶e̶r̶i̶m̶e̶n̶t̶a̶l̶.̶̶h̶o̶w̶e̶v̶e̶r̶,̶̶f̶o̶l̶l̶o̶w̶i̶n̶g̶̶t̶h̶e̶̶i̶n̶s̶t̶r̶u̶c̶t̶i̶o̶n̶s̶̶d̶e̶s̶c̶i̶b̶e̶d̶̶i̶n̶̶h̶e̶r̶e̶,̶̶t̶h̶e̶̶p̶r̶o̶c̶e̶s̶s̶̶w̶a̶s̶̶q̶u̶i̶t̶e̶̶e̶a̶s̶y̶.̶̶o̶n̶e̶̶i̶m̶p̶o̶r̶t̶a̶n̶t̶̶n̶o̶t̶e̶,̶̶i̶f̶̶y̶o̶u̶̶d̶o̶̶n̶o̶t̶̶w̶a̶n̶t̶̶t̶o̶̶h̶a̶v̶e̶̶t̶o̶̶c̶o̶m̶p̶i̶l̶e̶̶t̶h̶e̶̶a̶p̶i̶,̶̶m̶a̶k̶e̶̶s̶u̶r̶e̶̶t̶o̶̶u̶s̶e̶̶t̶h̶e̶̶p̶y̶t̶h̶o̶n̶̶3̶.̶7̶̶(̶3̶2̶̶b̶i̶t̶)̶.̶̶i̶̶t̶r̶i̶e̶d̶̶t̶o̶̶u̶s̶e̶̶t̶h̶e̶̶p̶y̶t̶h̶o̶n̶̶3̶.̶8̶̶(̶3̶2̶̶b̶i̶t̶)̶̶b̶u̶t̶̶i̶t̶̶d̶i̶d̶̶n̶o̶t̶̶w̶o̶r̶k̶̶c̶o̶r̶r̶e̶c̶t̶l̶y̶,̶̶s̶o̶̶m̶a̶k̶e̶̶s̶u̶r̶e̶̶y̶o̶u̶̶a̶r̶e̶̶u̶s̶i̶n̶g̶̶t̶h̶e̶̶c̶o̶r̶r̶e̶c̶t̶̶p̶y̶t̶h̶o̶n̶̶v̶e̶r̶s̶i̶o̶n̶.̶

一旦我安装了 depthAI API 及其依赖项,我就可以通过运行以下命令来运行默认演示程序(确保位于 depthAI 文件夹中):

*python depthai.py*

默认情况下,该演示运行 MobileNet SSD 对象检测模型,该模型可以检测图像中 20 种不同类型的对象(自行车、汽车、猫……)。此外,该演示将被检测对象的边界框与立体相机的深度信息相结合,以提供每个被检测对象的 3D 位置。作为一个例子,下面,我展示了检测水瓶的演示输出,这是可以检测默认演示模型的类之一。

演示能够以 30 fps 的速度跟踪物体并计算深度,没有任何问题。通过查看 depthai.py 脚本的 Python 代码,我看到在运行演示时,可以通过添加参数将演示配置为其他模式。例如,运行下面的代码有可能获得彩色化的深度(注:只对 Windows 10 的重构版本有效,在原来的存储库中配置已经改变):

*python depthai.py --streams depth_color_h*

使用 OAK-D 的深度输出。

总的来说,在背景的左边有一些黑色区域,深度看起来相当不错。然而,该区域包含玻璃面板,并且可能立体相机系统不能从中提取许多特征,因此没有为这些区域提供深度。

深度估计:OAK-D 与 Azure Kinect DK

尽管 OAK-D 的深度估计不是它的主要功能,但我想将 OAK-D 的深度估计与最新的 Azure Kinect DK 进行比较。为此,我编写了一个小的 Python 脚本( hello_depth.py ),它读取原始深度值并像在 Azure Kinect 中一样显示深度。

至于 Azure Kinect,我使用了 Azure Kinect SDK 的 my Python 库中的深度估计示例程序。在下图中,比较了两种设备的估计深度。

Azure Kinect 和 OAK-D 的深度估计比较。

可以看到,尽管 OAK-D 使用了 estereo 相机,但效果非常好。特别是在桌子的情况下,OAK-D 能够正确地估计深度,而 Azure Kinect 中的 TOF 传感器却失败了。

这是第一部分的全部内容,在下一部分中,我将使用 OAK-D 测试面具检测示例,我还将在我的库https://github.com/ibaiGorordo/Social-Distance-Feedback中上传该项目的所有脚本。

参考

【2】:BBC 新闻。(2020 年 6 月 24 日)。社交距离视觉障碍者的“斗争”,https://medium . com/@ arinbasu/you-can-use-footnote s-that-babus % C2 % B9-6c 485 C4 eff 1e

在 Windows 上使用 GStreamer 和 QT 的 OpenCV

原文:https://towardsdatascience.com/opencv-with-gstreamer-and-qt-on-windows-6f0fdb075993?source=collection_archive---------14-----------------------

使用 OpenCV 的 GStreamer 管道的分步指南和实例

作者图片:颜色反映组件之美,OpenCV,GStreamer,Qt,CMake,Visual Studio

OpenCV 是一个开源的计算机视觉库,主要面向实时系统。它基于 C++,为不同平台的视觉处理提供优化的代码,如 Windows、Linux、FreeBSD、macOS 等。由于开发人员和研究人员的活跃社区,代码很容易用于成像管道的不同步骤;从图像/视频捕获、校准、预处理、特征提取开始,到分类。虽然是用 C++编写的,但 OpenCV 有针对 python 和 Java 等不同语言的绑定。

GStreamer 是一个多媒体框架,支持不同的媒体处理组件,如音频、视频、录制和流媒体等。它通过让用户创建不同的管道和无缝集成不同的插件来提供高度的模块化。
既有图书馆;OpenCV 和 GStreamer 可以单独使用,但是两者的结合为处理多媒体流和数据提供了更大的灵活性。

与 Windows 相比,在 Linux 环境下使用 GStreamer 构建 OpenCV 更加简单,因为可以获得更好的在线支持和安装过程。然而,对于快速原型开发,人们可能觉得需要在 windows 环境下使用 OpenCV 和 GStreamer 以及 QT 配置。

在本文中,一步一步地介绍了如何使用 GStreamer、QT、OpenCV contrib 和 CUDA 包从源代码构建 OpenCV。在本教程的最后,我们将使用 OpenCV 开发一个 GStreamer 管道,将网络摄像头流式传输到本地主机,接收数据并使用 GStreamer-CLI 显示该流。在下一节中,我们将下载源文件并安装使用 GStreamer 构建 OpenCV 所需的工具。

下载源文件、安装程序和安装

  1. 从 OpenCV GitHub 下载源文件;建议下载最新版本。本实验基于 OpenCV 4.3.0

作者图片:来自 OpenCV Github 库的快照

2.从与主 OpenCV 相同的发布标签下载 OpenCV contrib 文件。在这种情况下,它是 4.3.0

图片由作者提供:来自 OpenCV contribute 资源库的快照

3.下载并安装 CMake 。我已经下载了 3.17.2。

4.下载并安装用于 MSVC 64 位(VS 2019)的 GStreamer 开发包和运行时安装程序

5.下载并安装 Visual Studio 社区【2017 版或 2019 版。我已经用 MSVC 64 位编译器安装了 2017。

作者图片:在 VS 安装程序中选择的选项

微软 C++ 构建工具包含在Visual Studio 安装过程中,但出于某种原因,我不得不单独下载。

图片由作者提供:从 Microsoft C++构建工具中选择的选项

6.使用 QT 在线安装程序下载并安装 QT Creator 开源版。我已经下载了 QT Creator 4.12.0。

配置 OpenCV、GStreamer、QT 和 CUDA

提取 OpenCV、OpenCV contrib 和 GSreamter,并开始配置构建过程。

  1. 配置设置
  • 创建一个构建文件夹,并使用 CMake 指向它,如下图所示。此外,在 OpenCV_EXTRA_modules_PATH 字段中给出“MODULES”文件夹的路径。

作者图片

  • 勾选 OPENCV_DNN_CUDA 的复选框

作者图片:CMake 源和构建文件夹路径

  • 选中 QT 框

图片作者:QT 打勾

  • 选中 WITH_GSTREMER 的复选框,并在 CMake 值中给出 GStreamer 开发包的路径。记住要仔细配置这个步骤。

GStreamer 库路径

下面提供了参考路径。请根据您的设置进行更改。

C:/gstreamer/1.0/x86_64/lib/gstapp-1.0.lib
C:/gstreamer/1.0/x86_64/lib/gstbase-1.0.lib
C:/gstreamer/1.0/x86_64/include/glib-2.0
C:/gstreamer/1.0/x86_64/lib/glib-2.0.lib
C:/gstreamer/1.0/x86_64/lib/glib-2.0/include
C:/gstreamer/1.0/x86_64/lib/gobject-2.0.lib
C:/gstreamer/1.0/x86_64/include/gstreamer-1.0
C:/gstreamer/1.0/x86_64/lib/gstreamer-1.0.lib
C:/gstreamer/1.0/x86_64/lib/gstpbutils-1.0.lib
C:/gstreamer/1.0/x86_64/lib/gstriff-1.0.lib
  • 在可选平台中配置编译器并选择 x64。在前面的一个步骤中,我们已经选择了 x64 位。

图片作者:记得选择平台。

  • 按下 configure 选项并检查输出,查看 GStreamer 和 QT 是否已正确配置。
QT: YES (ver 5.14.2)
GStreamer: YES (1.16.2)
  • 现在按下生成按钮

  • 您的文件已经为构建和安装步骤做好了准备。

构建 OpenCV 并安装

  1. 在发布模式下构建 OpenCV。首先将构建过程更改为 x64 模式。右键单击 ALL_BUILD,然后按 BUILD。

图片由作者提供:右键单击 ALL_BUILD 并按 BUILD

2.在发布模式下安装文件。右键单击“安装”,然后按“构建”。

图片由作者提供。右键单击安装,然后按构建

3.如果您还想在调试模式下构建,请重复以上两个步骤进行调试。

4.您的文件已经可以在带有 GStreamer 的 QT creator 中使用了。下一步,我们需要 x64 文件夹中的 include 文件夹、bin 等和 lib 文件夹。

图片作者:构建 OpenCV 文件。

5.创建一个文件夹 Opencv34,并复制步骤 4 中的 include folder、bin 等文件夹和 lib 文件夹。

图片由作者提供:环境变量中给出了 bin 文件夹路径,QT 中给出了 include 和 lib 路径。专业文件

编辑 OpenCV 和 GStreamer 的环境变量

图片由作者提供:根据您的设置更改 Visual Studio 路径

示例:使用 OpenCV 的 GStreamer 管道

我们将使用端口号为 50050 的 localhost (127.0.0.1)在同一台计算机上测试发送方和接收方 GStreamer 管道。一些制作自己的 GStreamer 管道的好参考[ link ] [ link 。GStreamer 直播摄像机流管道在下面作为 OpenCV 代码给出,而接收管道作为 GStreamer-CLI 给出。

  • GStreamer 使用 OpenCV 的直播摄像机流管道可以从访问
  • 使用命令行接口(CLI)给出了用于接收摄像机流的 GStreamer 管道。在 CLI 中键入给定的命令。挑战;在 OpenCV 中实现这个 GStreamer-CLI 管道,并作为响应共享您的 GitHub 存储库作为注释。
gst-launch-1.0 udpsrc port=50050 caps=application/x-rtp ! rtpjpegdepay ! jpegparse ! jpegdec ! videoconvert ! autovideosink

GStreamer 管道的输出窗口

参考

  1. https://fun vision . blogspot . com/2020/03/compile-opencv-4-for-visual-studio-2019 . html

相关文章

[## NVIDIA Jetson Nano vs Google Coral vs Intel NCS。比较

用于计算机视觉和机器学习的边缘人工智能硬件加速器

towardsdatascience.com](/nvidia-jetson-nano-vs-google-coral-vs-intel-ncs-a-comparison-9f950ee88f0d) [## 入门:Nvidia Jetson Nano,对象检测和分类

边缘计算的未来

towardsdatascience.com](/getting-started-nvidia-jetson-nano-object-detection-and-classification-161ad566d594)

Java 中的 OpenGL:如何使用硬件加速

原文:https://towardsdatascience.com/opengl-in-java-how-to-use-hardware-acceleration-676334f18f11?source=collection_archive---------15-----------------------

2D 图形教程:介绍和第一个“你好世界”计划

Silicon Graphics 作为高端 2D/3D 图形硬件加速渲染工作站大放异彩。他们引入了 IrisGL API(被认为是 OpenGL 的直接始祖),并在 90 年代广泛应用于电影和电视行业。照片中,一个来自《侏罗纪公园》的胶片框。在电影和恐龙建模和渲染过程中都使用了硅图形工作站。

介绍

硬件加速通常被视为游戏开发的利基解决方案,但还有许多其他图形应用程序可以受益于这项技术,尤其是那些涉及数据可视化的应用程序,如专业的数据科学工具或显示实时数据的软件。传统的制图工具和库对于这项任务来说不够快,因此需要定制的图形编程。

硬件加速曾经是专用计算机的高端功能,如 20 世纪 90 年代在电影和电视行业广泛使用的 Silicon Graphics UNIX 工作站,但现在它是过去 15 或 20 年间制造的每台计算机的常见功能。虽然有些显卡比其他显卡性能更强、功能更多,但几乎所有现代设备都有一套基本的 2D 和 3D 加速功能。

这是通过专门的 CPU(称为 GPU — 图形处理单元 —)来实现的。GPU 是一种专用 CPU,提供浮点和矩阵处理功能,通常用于 2D 和 3D 渲染。它基本上允许软件绘制复杂的图形处理用户坐标,缩放,平移,缩放,旋转和纹理渲染,在 2D 和三维。

通过提供接近实际光栅化输出设备的这种功能,减少了 CPU 使用和 I/O 总线带宽,这有效地使得能够在 2D 和 3D 中进行复杂的渲染和动画制作。依靠主 CPU 来完成这些任务意味着只能完成不太复杂的渲染,而且会浪费大量 CPU 时间来处理图形例程。

在这篇文章中,我将简要介绍 OpenGL 及其在 Java 中的用法,包括一个介绍性但非常有用的教程。该教程涵盖了 2D,但它实际上是对 OpenGL 的一个很好的介绍,所以如果你对 3D 感兴趣,它仍然是一个很好的介绍材料,因为 2D 和 3D 的概念非常相似。

OpenGL 是什么?

在 2D 和 3D 加速中有两个主要的竞争标准:DirectX 和 OpenGL。理解 OpenGL 和 DirectX 是硬件加速标准是很重要的,它们定义了哪些 API 应该由图形卡公开。从这个意义上说,它与任何其他计算标准(如 POSIX 或 C++11 标准)完全相同。在标准之外,将会有实现它们的库,因为 DirectX 库是由微软直接提供的,并且在 OpenGL 的情况下,有许多开源解决方案。

主要的图形卡制造商决定他们的硬件设备是否支持一种技术或另一种技术,或者两者都支持(这是通常的情况)。

DirectX 和 OpenGL 并不是唯一提供 2D 和 3D 渲染功能的标准/API。还有其他的,主要是 Vulkan 和 Metal。不过 DirectX 和 OpenGL 基本上都是应用最广泛的。Metal 专注于苹果设备,Vulkan 打算对 OpenGL 进行改进。我还没有评估这些,因为我不认为他们对我的需求感兴趣。

DirectX (Direct2D 和 Direct3D)是微软创建的一组 API,在 Windows 中实现。DirectX 不仅包括图形,还包括音频和输入。虽然它们是标准,理论上可以在任何操作系统架构中实现,但现实是 DirectX 仅用于 Microsoft Windows(以及 XBOX,以防有人发现该信息相关)。所以基本上 DirectX 是微软生态系统的标准解决方案。

相反,OpenGL 旨在成为一种跨平台语言,可以在发布的所有主流操作系统中使用。它实际上是旧的硅图形平台的直接后代,早在 1991 年就将 IrisGL 定义为提供专业 2D 和 3D 渲染功能的硬件 API。

几乎每一款现代显卡(我说的现代是指最近 15 年)都将提供与 DirectX 和/或 OpenGL 的给定版本的兼容性,因此它的使用不再是一件奇怪的事情,并且您有可能不再操作任何没有硬件加速功能的计算机。

理解这些 API 旨在提供渲染功能而不是用户界面是很重要的。一些窗口小部件/框架已经建立在 OpenGL 和 Direct2D 之上以满足这种需求,尽管它们没有像没有明确的硬件加速使用的常规框架那样被广泛使用。这背后的原因是硬件加速通常与游戏开发(不需要标准用户界面)和专门的图形应用程序有关。

为什么选择 OpenGL 和 Java?

我评估了一些关于硬件加速的组合。主要的有 Direct2D、C++和 OpenGL,使用 C++或 Java。在我看来,哪种组合更好并没有明确的答案。

如果你不需要跨平台(所以你基本上是为 Windows 开发)你也不需要开发复杂的用户界面,我会说 Direct2D 是正确的选择。它更容易,它在 Windows 中得到很好的支持,可以满足所有的需求。

然而,如果你对其他操作系统感兴趣,那么 OpenGL 无疑是一个不错的选择。开箱即用,它将支持所有主要的操作系统。

关于使用 Java 还是 C++,我个人选择了 Java,因为它允许更容易地与现有的用户界面框架(特别是 Java Swing)集成。我的需求包括图形加速和用户界面,所以我使用 OpenGL 的方法可能与你在互联网上找到的大部分材料略有不同,这些材料通常专注于游戏开发。这解释了为什么每种语言和用户界面框架如何与 OpenGL 交互对我如此重要。

对于 Windows 和 Direct2D 下的 C++来说,如何在 C++之上实现用户界面没有直接的答案。如果你愿意用。NET 中有像 Win2D 这样的东西,它支持在。NET 框架(从而无缝地访问所有用户界面框架),同时受益于 Direct2D 硬件加速。然而,这并不是一个广泛使用的解决方案,所以这意味着你没有使用主流技术/库,在我看来,这在支持、文档和未来维护方面总是一个有风险的提议。

如前所述,C++用户界面开发不像使用。NET 框架。你可以混合 C++和。NET framework,方法是使用 C++/CLI 来访问 WinForms(这不是主流解决方案),或者您可以依赖传统的 ATL/MFC 类,尽管它们被视为传统技术,但仍然得到了正确的维护。MFC 也迫使你处理许多样板文件,包括许多微软特有的详细类,这些类现在已经被 C++标准模板库所取代。你最终会写出与微软紧密结合的代码,以至于它不再被认为是可移植的 C++。

最重要的是,有可能使用其他跨平台的小部件框架(如 wxWidgets 或 Qt),我个人不喜欢这种方法,因为我认为如果你需要跨平台,Java 是最简单的途径,如果你想专注于 Windows,使用微软主流工具是最安全的方式。

无论如何,所有这些解决方案都包含一定程度的样板文件(有时它们实际上实现起来相当复杂)。Windows APIs 从未在可用性和简单性方面大放异彩。而。NET 改变了这种模式,现在用 C#或 VB 构建应用程序相当容易,它仍然更侧重于性能不是问题的生产力应用程序。

在我看来,如果你需要硬件加速,一个中等复杂的用户界面和一个跨平台的解决方案,没有什么比带有 Swing 和 OpenGL 的 Java 更容易的了。许多人认为 Java Swing 已经过时了,但事实是它仍然为桌面应用程序带来了相当现代的界面,它非常轻量级,而且功能强大,足以提供良好的用户界面体验。除非你正在寻找一个尖端的 UI 设计,Java Swing 将会完成这项工作。对于可用性和功能性比界面外观和感觉更重要的利基应用程序来说尤其如此。

我回顾了 OpenGL 的所有 Java 替代方案,最终选择了 JOGL。原因是 JOGL 是通用的 OpenGL 实现,不像其他库(如 LWJGL)那样只专注于游戏。它可以与 AWT 和 Swing 集成,因此您可以同时拥有两个世界:自定义硬件加速图形和通过 Swing 轻松开发和实现用户界面。

使用 Java/Swing/OpenGL 的这种组合还有一个好处,那就是你的软件可以在 Linux/UNIX 和 Windows 系统中运行而不需要任何改变。作为一个权衡,如果你的软件需要低级别的数据处理,Java 有时比 C++稍差一点,而且可能会稍微慢一点。

也有建立在 OpenGL 之上的替代框架。运行用户界面不需要其他任何东西,但是根据我的研究,没有一个界面成熟到可以被认为是安全的。他们也倾向于只为特定的 OpenGL 实现工作,他们也依赖于其他库,所以最终仍然有一些外部依赖。这些框架的绑定通常只为 C++提供。

你好,Java 中的 OpenGL 世界

不再拖延,让我们编码我们的第一个 OpenGL 程序。我将使用 Netbeans 8.2 和 Oracle JDK 8。

你可以从其主要网站https://jogamp.org下载 JOGL,你需要将 gluegenjogl 库整合到你的 IDE 中。关于如何做到这一点的具体说明很容易找到,所以我不会在这里重复它们,特别是因为它们将取决于您正在安装的特定版本和您正在使用的 IDE。我只想说,您可以从 JOGL 的主网站上下载 jar 文件,放在 Build/Downloads — Zip 下。下载“所有平台”。并将它们安装到您的项目中。您将得到类似这样的结果:

IDE 中要包含的基本库,以便在 Java 项目中使用 JOGL OpenGL。

首先,我们将实现一个扩展 JFrame 的类,这样它将基本上定义一个窗口,我们可以在其中使用 OpenGL 绘图。

这门课:

  1. 扩展 JFrame ,因为我们想要一个独立的窗口,我们可以在那里绘图。这与 OpenGL 无关,只是一种在 Java Swing 中创建窗口的方式。
  2. 实现 GLEventListener 接口,这是 JOGL 实现 OpenGL 的一个要求。这个接口需要实现四个方法:显示整形初始化处理
  3. 在这个例子中,实际上只实现了显示方法。在这里,我们将执行实际的绘图(稍后将详细介绍)。
  4. 我们需要一个 GLProfile 和一个 GLCapabilities 对象,它们定义了哪个特定的 OpenGL 版本和哪些功能正在被实现。
  5. 我们需要一个 GLCanvas 对象,基本上就是实现 OpenGL 的 Canvas 对象。这将被添加到一个实现了 GLEventListener 接口的类中,在我们的例子中是我们的 JFrame 类。这可能通过简单地检查在源代码中创建 GLCanvas 对象的三行代码来更好地理解。

概括地说,我们基本上是在创建一个 JFrame 类,它实现了 GLEventListener 接口并包含了一个 GLCanvas 对象。这允许我们在 GLCanvas 对象上使用 OpenGL。

有了所有这些步骤,我们就可以开始绘制了,这是通过实现 display 方法来实现的。

第一个 OpenGL 示例

在这种情况下,显示方法非常简单。它接收一个 GLDrawable 对象作为参数。从这个对象中,我们可以得到一个 GL2 对象,这就是我们用来绘制的对象。

要划清界限,我们只需:

gl.glBegin(GL2.GL_LINES);
gl.glVertex3f(-0.50f, -0.50f, 0);
gl.glVertex3f(0.50f, -0.50f, 0);
gl.glEnd();

我们附上我们在 glBeginglEnd 定义之间的图纸。作为 glBegin 参数,我们提供 GL2。GL_LINES 告诉 OpenGL 我们正在画一条线。因为我们正在画一条线,所以我们知道我们需要提供两个点(OpenGL 也希望如此)。因此,我们定义了两个顶点(点),在这种情况下是在 3D 中定义的。这两点是定义这条线的点。

基本思想是,我们开始绘图,并提供必要的信息(在本例中,绘制一条线需要两个点),GPU 需要这些信息将它绘制到画布对象上。其他绘图图元需要 glBeginglEnd 之间的其他信息。

为了完成我们的三角形,我们只需画三段。

OpenGL 中的 Hello World 程序

最后,为了显示窗口,JFrame 需要像 Java Swing 中的任何 JFrame 一样被调用。我们的主类就像这个一样简单:

我们的主类只是调用扩展的 JFrame 类

这就完成了我们的第一个 Java OpenGL 程序。相比之下,用 Java 比用 C++更容易得到一个工作示例,因为 Java Swing 比微软现有的 API 更容易编码。在下一个系列中,我们将继续编写 OpenGL。

Java 中的 OpenGL:管道和着色器

原文:https://towardsdatascience.com/opengl-in-java-pipelines-shaders-907f137c5bd5?source=collection_archive---------21-----------------------

2D 图形教程(二):现代 OpenGL——顶点、管道和着色器

的另一篇文章中,我介绍了 OpenGL,并简单讨论了我为什么选择 Java、OpenGL 和 JOGL。我还展示了一个 Java 工作示例,它相当于第一个“Hello World”程序。预期的例子是使用旧的 OpenGL 语法,这很容易理解,但没有优化。它在 OpenGL 中被称为“即时”模式,在这种模式下,绘图命令被直接提交给包含在 glBeginglEnd 块中的 GPU。

从 OpenGL 3.3 开始,推荐使用所谓的核心语言对 OpenGL 进行编程。在这种模式下,通过被称为着色器的已编译 GLSL 程序来使用 OpenGL。那些着色器流水线,所以我们有一个链接的软件流来渲染我们的图形。GLSL 程序需要编译,通常存储在我们源代码的单独文件中,因为它们本身就是一种单独的编程语言。

当编写 OpenGL 时,我们为并行运行的 GPU 编写流水线代码。这意味着我们编码的方式不同于常规程序。例程需要简洁和无状态,因为执行顺序是未知的。每个管道阶段的操作不能依赖于同一阶段的其他操作。代码也必须编译并下载到 GPU,这是在运行时完成的。

在本文中,我们将简要解释这个管道是如何工作的,着色器是如何编码的,以及顶点坐标是如何使用的。我们将使用这些概念按照完整的过程画一个正方形。虽然这个例子很简单,但是这个过程反映了 OpenGL 是如何编程的。

请记住,这不是一个解释每一个 OpenGL 概念的详尽教程,而是我收集的解释我在学习 OpenGL 时发现更复杂的步骤的材料。重点是做基本但完整的例子,说明如何使用 OpenGL 的 2D 数据可视化应用。如果您不确定某些 OpenGL 关键字的范围,请不要担心,重点是了解着色器和管道如何工作的总体想法,这将使学习补充材料更加容易。准备这些例子也是为了填补我在最推荐的学习材料中发现的空白(我将在本系列教程的最后重新讨论这些内容),并强调我花了更多时间来解决的领域。

管道和着色器

OpenGL 就是渲染由顶点定义的基本形状。如果你想建立一个 3D 恐龙模型,它很可能是用非常小的三角形来塑造的,小到在人类的边缘看起来是一个连续的纹理。

因此,OpenGL 将把顶点集转换成实际的渲染图像,并且它将使用所谓的着色器来完成这项工作。对 2D 来说,也是一样,我们只是一直在 z=0 平面上绘图。

简单地说,事情是这样的:

  1. 应用程序(例如 Java 或 C++)将为要绘制的每个形状/图元定义要使用的点。这只是一个顶点列表,所以如果你想画一个三角形,每个三角形图元需要三个顶点。
  2. 顶点着色器程序将为每个顶点执行一次,它将定义顶点位置和要绘制的基本形状/图元/对象。顶点着色器用于对每个顶点进行缩放和平移等操作。
  3. 可选地,几何着色器将顶点转换成形状。通过这样做,将有可能把正方形的中心传递给程序,并让几何着色器推断正方形的四个顶点。
  4. 片段着色器程序将为每个要绘制的像素执行一次,并定义像素的颜色。

使用 GLSL 语言为图形卡 GPU 定义和编译(在运行时)所有着色器。

镶嵌着色器是 OpenGL 4 中引入的可选着色器,允许定义和操作由大量三角形组成的网格。它已被纳入 OpenGL 第 4 版,旨在建立像三维景观的东西。

在这个例子中,我们将使用一个顶点着色器,一个几何着色器和一个片段着色器。这个想法是,应用程序给定一组坐标(顶点),我们的 GPU 将绘制以这些坐标为中心的正方形,并根据它们在窗口中的位置将它们着色。这是一个非常有效的例子,完美地说明了如何使用“核心”模式编程 OpenGL。

OpenGL 管道包括生成光栅化图像的几个连锁步骤。图片来源:Khronos 集团财团。

对我来说,一件新奇的事情是着色器无状态的概念。着色器背后的想法是它们可以以任何顺序并发执行。这有效地使 GPU 能够并行执行大量着色器(每个着色器处理一个顶点/像素)。这就是为什么即使在高清显示器上也能实现快速响应和渲染而不影响 CPU 的原因。作为一个权衡,我们编码的每个着色器必须是无状态的,不能依赖于其他着色器。这意味着我们编码着色器的方式与我们习惯的方式略有不同。

使用着色器和 GLSL 绘制像素

顶点着色器

让我们准备一个程序,使用顶点着色器片段着色器绘制一个像素。我们将首先定义将在一个单独的文件中分配的源代码,这可能是您想要做的。

我们的顶点着色器什么都不做,它只是将顶点传递给下一个着色器,但它仍然是必需的。

我们的第一个顶点着色器只定义了一个正方形的顶点。

让我们详细分析一下源代码。

第一行声明我们正在使用 OpenGL 3.3 核心。即使在撰写本文时,OpenGL 已经达到了 4.6 版本,我们也将为 3.3 编码。这样做的原因是 3.3 是第一个执行核心编程的版本,这样我们就可以使用旧的显卡。

第二行声明我们将使用一个输入布局变量,我们将其命名为 squareCenterPosition ,这样命名的原因是在下一个例子中我们将使用它作为一个正方形的中心。现在,请记住这只是单个像素的位置。

布局子句允许指定限定符,这在上下文中定义了我们在顶点矩阵中使用的位置。关于布局限定符做什么的完整规范可以在 OpenGL 规范页面上阅读。随时准备检查规范,以澄清对代码示例的疑问。

vec2 类型的变量定义了一个双浮点向量。当我们面对 2D 时,我们只需要两点。如果需要,可以提供更多的数据。

第二块是主函数。OpenGL 在许多方面类似于 C 语法,所以着色器总是有一个“主”函数。在这个函数中,我们定义了在 OpenGL 中有特殊含义的变量 gl_Position 。它定义了顶点的最终位置。在这种情况下,我们定义一个 4 浮点向量,它包括 3D 坐标和一个用于投影的值。在我们的例子中,Z 坐标是 0,投影值被硬编码为 1

这就是我们在顶点着色器中所要做的,将 x/y 位置转换成一个合适的 4 浮点向量。

几何着色器

下一个着色器是几何着色器。该着色器可以操纵顶点和计算图元。理解 GPU 处理基本图元是很重要的:点、线和三角形。仅此而已。

作为一个例子,我们将首先提供一个几何着色器,它只在顶点周围生成 4 个点:

我们的第一个几何着色器接收一个输入顶点,并从中生成 4 个顶点。把它想象成一个从中心点出发的正方形生成器。

对于几何着色器,我们为着色器的输入和输出数据定义了布局子句。在我们的着色器中,我们定义了接收到的每个点都有 4 个点。这可能是不同的情况(我们将在后面看到一个例子),我们可以为每个点传递一个三角形。

gl_Position 是用于定义顶点位置的 OpenGL 变量。在这种情况下,我们定义它四次,每个生成的顶点一次。请注意我们是如何获得输入值( gl_in[0] )并用偏移量 0.2 对其进行转换,以构建我们的假想正方形的每个点。对于每个点,我们调用 EmitVertex()EndPrimitive() ,因为我们生成 4 个图元,每个图元 1 个顶点(一个点仍然是一个图元)。稍后,我们将在每个位置生成四个三角形,以进一步说明几何着色器的工作方式。

片段着色器

现在我们已经有了顶点着色器定义的像素,我们将编码我们的片段着色器,这也是一个愚蠢的例程,它只是用红色绘制像素( RGB 1,0,0 )。代码如下:

片段着色器,它只画一个红色像素。

VBA 和 vbo

在进入实际的 JOGL 实现代码之前,让我们回顾一下 OpenGL 中的 VAOs 和 VBOs 是什么。VBO(顶点缓冲对象)是存储在图形卡内存中的缓冲区,其中包含着色器要操作的数据。在显卡内部分配和存储数据,比从 CPU 来回移动数据要快得多。这个想法是,我们用渲染数据加载这些缓冲区,然后由 GPU 处理这些缓冲区。每个 VBO 通常包含与一个实体相关的数据。VBO 可以包含与恐龙的 3D 模型相关的所有信息,例如,在 2D,每个 VBO 可以包含顶点和必要的信息,以在 EDA(电子设计自动化)CAD 程序中绘制逻辑门或晶体管。

VAO 是维也纳组织的超集,这意味着我们至少需要一个 VAO。VAO 使用的一个潜在示例是将 VAO 中某个游戏级别的所有渲染 vbo 分组。通过这样做,主程序更容易管理需要加载哪些缓冲区。这是一种将可能同时需要的缓冲区分组的方法。基本的 2D 应用程序只需要一个 VAO 就可以工作。对于复杂的应用程序,它的使用可能会提供一些优势,尤其是当您不能同时将所有信息放入内存时。

OpenGL Java 类

我们将创建一个名为 Window C 的新类,它包含三个着色器。我们将定义一个 VAO 和两个 VBOs,每个将包含一个 2D x,y 坐标。我们将处理这两个 VBOs,最终将在屏幕上绘制两个假想的正方形。

OpenGL 类扩展 JFrame 并实现 GLEventListener。它定义了一个 VAO,两个仅包含一个(x,y) vec2 的 vbo。这些 vec2 通过顶点、几何和片段着色器来获得围绕这些坐标绘制的虚拟正方形。

我们还需要我们的主类:

Main 类,它只是调用 WindowsC JFrame 对象。

正如所料,我们得到的结果是两个假想正方形的顶点,分别位于(0.5,0.5)和(-0.5,-0.5)周围。

使用着色器的第一个程序输出。请注意,所有工作都已在 GPU 上完成。应用层只是定义了我们想象的正方形的中心。

画三角形而不是点

在结束这个例子之前,让我们想象一下,我们想要在每个点上画一个三角形,而不是一个假想正方形的顶点。为此,我们只需使用 triangle_strip 而不是点作为输出来修改我们的几何着色器。在调用 EndPrimitive() 之前需要定义三个顶点。

修改了几何着色器代码,以在每个点绘制三角形。

带有修改的几何着色器的程序的输出。

摘要

虽然这个例子很简单,但它说明了使用 OpenGL 的硬件加速程序的基本工作流程。它使用渲染程序中使用的三个主要步骤:顶点着色器、几何着色器和片段着色器。它说明了 OpenGL 程序是如何简洁并且不容易理解,但同时为软件提供了强大的计算能力,因为所有的图形绘制工作都是由 GPU 交付的。这释放了我们的应用程序和 CPU,有效地简化了代码并提高了性能。

我有意忽略了任何其他会使 OpenGL 中使用的基本工作流程复杂化的方面。请记住,我们已经定义了一些坐标,每个坐标都存储在一个 VBO 中,两个 vbo 都包含在一个 VAO 中,GPU 已经编码为使用顶点、几何图形和片段着色器,并且我们已经渲染了形状。

在接下来的文章中,我们将继续讨论缩放、平移和调试(至少是错误检查)。

用石灰打开黑盒模型——美女与野兽

原文:https://towardsdatascience.com/opening-black-box-models-with-lime-beauty-and-the-beast-9daaf02f584a?source=collection_archive---------34-----------------------

一个简单的分步指南(带 Python 代码)真正解释了什么是 LIME,它是如何工作的,以及一些潜在的陷阱。

来自 SlideshareKasia Kulma 的照片

尽管机器学习在做出关键决策方面得到了蓬勃发展,但许多机器学习模型仍然是黑箱。在这里,使用机器学习做决策的信任和伦理挑战就出现了。因为错误预测的现实后果可能会很昂贵。2017 年,对三家负责设计和开发自动化计算机系统的美国公司提起诉讼,该系统被密歇根州政府失业机构使用,并提出了 2 万项虚假欺诈指控。一个好的老板还会质疑他的数据团队,为什么公司应该做出这些关键的商业决策。为了不盲目信任机器学习模型,理解模型的行为、它做出的决策以及任何相关的潜在陷阱的需要是议程上的优先事项。

模型可解释性——事后解释技术

数据科学界和文献中普遍接受的现象(Johansson,Ulf 等人,2011;Choi,Edward 等人,2016 等。)是在模型准确性和可解释性之间存在权衡。有时
当你有一个非常大的潜在复杂的数据集时,使用复杂的模型,如深度神经网络和随机森林,通常可以实现更高的性能,但可解释性较低。相比之下,更简单的模型,如线性或逻辑回归,仅举几例,往往提供较低的性能,但更高的可解释性。这就是事后解释技术出现并成为机器学习文献中游戏规则改变者的地方。

传统的统计方法使用假设驱动的方法,这意味着我们通过训练模型来构建假设和验证假设。相反,事后技术是“事后”应用的设置技术——在模型训练之后。所以人们想出的主意是首先建立复杂的决策模型,然后用更简单的模型来解释它们。换句话说,先建立复杂的模型,然后才是假设。事后解释技术的一些例子包括莱姆,SHAP,锚,缪斯等等。我在本文中讨论的重点将是解释什么是 LIME,如何使用 Python 代码一步一步地指导它的工作,以及与 LIME 相关的好与不好。

得到💬任何数据科学或编程问题的 GPT 式答案。为成千上万的人生成摘要和学习笔记📚只需一次点击即可获得学习资源。👉

[## 面向数据科学家和开发人员的免费学习资源。精选的博客、教程、书籍和…

机器学习和人工智能工程师的培训课程、黑客马拉松、活动和工作

aigents.co](https://aigents.co/learn)

那么石灰到底是什么,它是如何工作的?

LIME 是局部可解释模型不可知解释的缩写。本质上,LIME 是模型不可知的,这意味着它可以基于每个复杂模型都是黑盒的假设而应用于任何模型。通过可解释的方式,它意味着 LIME 将能够解释模型如何表现,它选取了哪些特征,以及它们之间发生了什么样的相互作用来驱动预测。最后但同样重要的是,LIME 是特定于观察的,这意味着它试图理解影响感兴趣的单个实例周围的黑盒模型的特性。LIME 背后的基本原理是,由于全局模型的可解释性在现实中很难实现,所以通过简单的局部模型来近似黑盒模型要简单得多。

在实践中,黑盒模型的决策边界可能看起来非常复杂。在下图中,黑盒模型的决策边界由蓝粉色背景表示,这似乎太复杂了,无法用线性模型精确地近似。

图一。黑箱模型的决策边界。来源

然而,研究(Baehrens、David 等人(2010 年)、Laugel 等人(2018 年)等。)已经表明,当你放大并观察一个足够小的邻域(请耐心等待,我将在下一次会议中讨论它意味着什么)时,无论模型在全局水平上有多复杂,局部邻域的决策边界都可以简单得多,事实上甚至可以是线性的。例如,某人患癌症的概率可能与他的年龄成非线性关系。但是,如果你只关注一小部分 70 岁以上的人,那么对于这部分人群来说,患癌症的风险可能与年龄增长呈线性相关。

也就是说,LIME 所做的是在一个非常局部的水平上前进,并到达一个点,在这个点上,它变得如此局部,以至于一个线性模型足够强大,可以解释原始黑盒模型在局部水平上的行为,并且在该局部上(在我们想要解释的观察的邻域中)它将是高度准确的。在这个例子中(图 1),红色的粗体叉是正在解释的实例。LIME 将通过对所选实例周围的邻域进行采样来生成新的实例,对该邻域应用原始黑盒模型来生成相应的预测,并根据这些生成的实例到被解释实例的距离对它们进行加权。

在这个获得的数据集中(包括生成的实例、相应的预测和权重),LIME 训练一个可解释的模型(例如加权线性模型、决策树),该模型捕获该邻域中复杂模型的行为。该局部线性模型的系数将充当解释器,并告诉我们哪些特征以这种或那种方式驱动预测。在图 1 中,虚线是黑盒模型在特定位置的行为,这可以通过线性模型来解释,并且该解释在该位置被认为是可信的。

石灰的完整配方,一步一步的指南(和 Python 代码)

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import StandardScaler
import seaborn as sns

第一部分。加载数据并训练随机森林模型。

LIME 可以应用于所有类型的数据。本文中开发的示例将仅限于分析表格数据。我在 Hackereath 上使用这个贷款违约的数据集。在我的 GitHub 上可以找到完整的笔记本。因为它是一个非常大的数据集,所以在这个例子中,我只使用训练集作为我的完整数据集。基本上,我有一个贷款违约数据集,其大小超过 500.000 个观察值,在该数据集中的特征中,我挑选了 3 个与目标变量(违约或非违约)具有最高相关性的特征(贷款金额、借款人年收入和 member_ID)。您可以找到所用数据的摘要,并遵循下面提供的代码所采取的步骤。

#About the data
#Loan_status: Current status of the loan 0: default, 1: non-default #annual_inc: The reported annual income provided by the borrower 
#loan_amnt: The listed amount of the loan applied for by the borrower.
#member_id: A unique assigned ID for customers.**#Loading dataset**df = pd.read_csv("credit_default.csv")#Plotting and doing some data **# Exploratory data analysis**ax1=df['annual_inc'].plot.hist()
ax1.set_xlabel('annual_inc')
df.boxplot(column=['annual_inc', 'funded_amnt','member_id'])**#Removing outliers for annual_income**Q1 = df['annual_inc'].quantile(0.25)
Q3 = df['annual_inc'].quantile(0.75)
IQR = Q3 - Q1
print(IQR)
df_outliers = df[(df['annual_inc'] < (Q1 - 1.5 * IQR)) | (df['annual_inc'] > (Q3 + 1.5 * IQR)) ] 
df_clean = df[(df['annual_inc'] > (Q1 - 1.5 * IQR)) & (df['annual_inc'] < (Q3 + 1.5 * IQR)) ]**#Correlation matrix**sns.heatmap(data = df_clean.corr(),annot=True, linewidths=1.5, fmt='.1g',cmap=plt.cm.Reds)**# Picking up features for the model**
features = ['member_id', 'annual_inc', 'funded_amnt']
tmp=df_clean[features]**#Standardization**X = StandardScaler().fit_transform(tmp)**#Training the model**from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size = 0.33)
X_train.shape[0] == y_train.shape[0]from sklearn.ensemble import RandomForestClassifier
Model = RandomForestClassifier()**#Predicting using the test set and get accuracy, recall and precision score**Model.fit(X_train, y_train)y_predicted = Model.predict(X_test)
metrics.accuracy_score(y_test, y_predicted)
tn, fp, fn, tp = metrics.confusion_matrix(y_test,y_predicted).ravel()
recall = tp/(tp+fn)
precision = tp/(tp+fp)

print("accuracy = **{acc:0.3f}**,**\n**recall = **{recal:0.3f}**,**\n**precision = **{precision:0.3f}**".format( acc=accuracy, recal=recall,precision=precision))

在训练了一个 Randome 森林模型后,我的准确率为 0.80,精确率为 0.61,召回率为 0.44。好吧,让我们继续莱姆的解释。

第二部分。石灰说明

第一步。在您的原始数据集中选择感兴趣的实例(Xi ),您需要为其解释黑盒模型。

Xi = np.array([ -0.71247975, -0.04996247, -1.02083371])

鉴于我已在上一步中对数据进行了标准化,在此,我将通过对 Xi 周围的正态分布和训练数据集中的解释变量的标准偏差进行采样,来生成新的实例(在被解释的实例的邻域-Xi)。

num =750 # number of perturbations generated
sigma = 1 # Standard deviation
X_perturb = np.random.normal(Xi,sigma,size=(num,Xi.shape[0]))

如果您还没有标准化数据,LIME 将在内部为您完成。需要注意的是,默认情况下(看看 LIME 在 Python 中的实现),LIME 样本取自特征数据的平均值,代表全局解释。但是,您可以选择在感兴趣的实例周围进行数据采样,这是一种更加局部驱动的解释。在这种情况下,如前所述,我选择围绕所选实例(Xi)进行采样。如果围绕要素的平均值进行采样,可能会生成远离您想要解释的实例的实例。这是有问题的,因为您在生成的数据集上得到的解释可能与正在解释的实例的解释不同。

图二。围绕被解释的实例进行采样(蓝色)(左)和围绕要素数据的平均值进行采样(右)-按作者进行可视化

第三步。使用复杂的原始黑箱模型对受扰动的实例进行预测

y_perturb = Model.predict(X_perturb)

第四步。

根据生成的样本到我们想要解释的实例的距离对它们进行加权。权重由核函数确定,该核函数将欧几里德距离和核宽度作为输入,并输出每个生成实例的重要性分数(权重)。

distances = np.sum((Xi - X_perturb)**2,axis=1)#euclidean distance
kernel_width = 0.9 # I select a kernel width myself. By default in LIME, kernel width = 0.75 * sqrt(number of features)
weights = np.sqrt(np.exp(-(distances**2)/(kernel_width**2))) #Kernel function

LIME 使用欧几里德距离作为生成的实例和正在解释的实例之间的相似性度量。下图是否让你想起了数学课上的勾股定理?

对于 n 维数据,欧几里德距离的公式如下:

关于核宽度,默认情况下, LIME 的实现使用指数核,其中核宽度被设置为等于训练数据集中特征数量(N)的平方根的 0.75 倍。您可能想知道这个 sqrt(N)来自哪里。现在假设向量σ = [σ1,σ2,σ3]是向量特征 X [X1,X2,X3 ]的标准差。sqrt(N)是被解释的实例和生成的实例之间的均方根距离。如果我们有一个单一的特征,我们生成一个新的实例,从一个正态分布,均方根距离你期望将等于西格玛(标准偏差)。更正式地说,这个距离由均方根偏差给出。对于统计上独立的 N 个特征,每个特征都来自正态分布,均方可以相等地相加,因此均方根偏差为 sqrt(N)。或者在公式中:

第五步。

使用所生成的实例(X_perturb)、黑盒模型对所生成的实例的相应预测(y_perturb)和权重(在步骤 4 中)来训练可解释的局部模型(在这种情况下是线性模型),以导出用作对黑盒模型在该局部的行为的解释的系数。局部(线性)模型的系数将告诉你哪些特征驱动黑盒模型的预测。

from sklearn.linear_model import LinearRegression
local_model = LinearRegression() 
local_model.fit(X_perturb, y_perturb, sample_weight=weights)
y_linmodel = local_model.predict(X_perturb)
local_model.coef_

局部线性模型系数—作者计算

本地模型的系数表明,融资额(贷款额)的增加会将预测推向违约类别(y = 0),同时年收入的增加会将预测推向非违约类别(y =1)。图 3 说明了本地模型的三维决策边界。

图 3。绘制局部模型的 3D 决策边界。作者可视化。

什么是有意义的邻里?

和其他案件一样,细节决定成败。实现一个有意义的地方绝非易事。有目的的邻域需要足够小以实现局部线性。此外,使用大的邻域会带来产生局部模型的风险,该局部模型产生的解释不符合局部情况。原因是,当你创建一个大的邻域时,你会冒有实例远离的风险,因此与你想要解释的实例不同。这意味着对那些远距离实例的黑盒模型的解释可能不同于对所选实例的解释,并且您的解释偏向于全局级别。同时,过小的邻域意味着只将高权重分配给非常接近的实例,这表明您面临欠采样的威胁,并且局部模型的系数在周围的邻域中将是不稳定的。

如果你还记得第四步(如果没有,请回来),权重是由所谓的内核宽度决定的。这里事情变得棘手,因为内核宽度决定了邻域的大小。一个小的内核宽度意味着你分配更多的权重给生成的实例,这些实例靠近正在解释其预测的实例。同时,大的核宽度意味着无论扰动的实例离原始实例有多近/多远,它们仍然会对局部模型产生一定的影响。在图 4 中,圆圈的大小代表重量。

图 4。选择较小的内核宽度(左)和较大的内核宽度(右)—作者可视化

为了查看内核宽度对局部解释的影响,在图 5 中,我说明了内核宽度的变化将如何导致局部模型系数的变化。虚线表示内核宽度的默认值(0.75 乘以特征数量的平方根)。显然,值为 0.5 的核大小将很好地解释黑盒模型在该局部的行为,因为从该阈值上升,局部系数达到稳定。然而,如果我们将内核宽度减小到 0.3 或更低,则局部模型的所有三个系数都会发生剧烈变化,这表明从阈值 0.3 开始,内核大小的减小会降低系数的稳定性。

widths = np.linspace(0.01, sigma*np.sqrt(3), 1000)
 alist = []
 blist = []
 clist = []
 sigma = 1
 for width in widths:
     X_perturb, y_perturb, weights = make_perturbations(Xi, sigma=sigma, num=num_perturb, kernel_width = width, seed=8 )
     a,c = get_local_coeffs(X_perturb, y_perturb, weights)
     alist.append(a[0])
     blist.append(a[1])
     clist.append(a[2])
 miny, maxy = np.min([alist,blist,clist]), np.max([alist,blist,clist])
 plt.figure()
 plt.plot(widths, alist, label = "coef1", c = 'yellow')
 plt.plot(widths, blist, label = "coef2", c = 'purple')
 plt.plot(widths, clist, label = "coef3", c = 'green')
 plt.plot([0.75*sigma*np.sqrt(3), 0.75*sigma*np.sqrt(3)], [miny, maxy], c='black', ls=':')
 plt.ylim([miny,maxy])
 plt.xlabel("Kernel width")
 plt.ylabel("Regression coefficient")plt.legend()
 plt.show()

图 5。不同核宽度的局部模型系数——作者举例说明

为了进一步证实,我展示了 100 个不同模型的系数的均值和置信区间,这些模型具有我的黑盒模型中 3 个特征的不同核宽度。三条实线(紫色、蓝色和橙色)代表 100 个不同模型的相应平均系数。阴影(紫色、蓝色和橙色)区域表示每个特征的 95%置信区间。正如所观察到的,随着内核宽度大于 0.3,平均系数变得不那么分散(由较小的 CI 表示)。同时,小于 0.3 的核宽度将导致所有特征的系数不稳定。显然,在系数稳定性和内核宽度(作为局部性级别的度量)之间有一个折衷。本质上,为了识别一个最优的邻域,你的目标是获得最小的核宽度,其中线性模型的系数保持稳定。这个问题 Alvarez-Melis,d .,& Jaakkola,T. S. (2018)和 Thomas,a .等人,(2020)已经做了充分的分析和讨论,你可以看看进一步的了解。

图 6。不同内核宽度的 100 个不同局部模型的系数—作者可视化

美女与野兽

那么当我有高精度模型时,我还需要石灰吗?问题是,在不知道模型选择哪些症状来做决定的情况下,你不知道模型是否能为错误的原因给出正确的答案。由于 LIME 能够根据它的解释找到本地模型,您可以与领域专家交流并询问这是否有意义。因此,LIME 还可以提供关于黑盒模型如何以及为什么做出错误预测的见解。

我能信任莱姆吗?一些想法:首先,LIME 解释是不稳定的,因为它依赖于你生成的假实例的数量和你选择的内核宽度,正如上面讨论的。在某些情况下,你可以通过改变内核宽度来完全改变解释的方向(如图 5,6 中系数的变化所示)。

其次,LIME 是一种基于事物在局部水平上具有线性关系的假设的事后技术。这是一个非常大的假设。有时,当你的黑盒模型非常复杂,而模型又不是局部线性的,那么使用线性模型的局部解释就不够好了。也就是说,当模型过于复杂时,我们必须非常小心,并相应地调整内核宽度。我高度怀疑莱姆可以用来解释任何复杂的模型。

简而言之,LIME 将能够给出一个好的局部解释——只要实现了正确的邻域和局部线性。但是由于上面提到的潜在隐患,石灰应该同时非常小心地使用。

感谢您的阅读。希望这对学习有帮助。

参考

[1] Alvarez-Melis,d .,& Jaakkola,T. S. (2018)。论可解释性方法的稳健性。 arXiv 预印本 arXiv:1806.080499

[2] Baehrens,d .,Schroeter,t .,Harmeling,s .,Kawanabe,M .,Hansen,k .,和 M ' ller,K. R. (2010 年)。如何解释个人分类决策?机器学习研究杂志11(6 月),1803–1831 年。

[3]莫尔纳尔,C. (2019)。可解释的机器学习。露露。com。

[4]里贝罗,M. T .,辛格,s .,& Guestrin,C. (2016 年 8 月)。“我为什么要相信你?”解释任何分类器的预测。第 22 届 ACM SIGKDD 知识发现和数据挖掘国际会议论文集(第 1135-1144 页)。

[5] Thomas,a .等人,可解释的机器学习方法的局限性(2020 年)

[6] 媒体博客上的石灰由 Lar

[7]使用 LIME 框架的可解释机器学习— Kasia Kulma(博士),数据科学家,Aviva — H2O.ai

确认

感谢罗伯特的讨论,并帮助我与一个很好的三维绘图。

打开黑匣子——超越梯度下降

原文:https://towardsdatascience.com/opening-the-black-box-beyond-gradient-descent-439596fce294?source=collection_archive---------44-----------------------

梯度下降近似视图介绍

当训练模型时,我们试图最小化训练样本上模型损失函数的平均值:

对于以上总和中的每个 if_i ,是 iᵗʰ训练样本所遭受的损失,作为模型的参数向量 w 的函数。对于损失最小化任务,我们采用随机梯度方法的变体:在步骤 k ,我们从{ f_1 ,…, f_n }中随机选择一个函数 f ,并计算:

梯度步长

该方法存在许多变体,如 mini-batching、Ada-Grad 和 Adam,但有一点是所有这些方法共有的:每个损失 f 都作为“黑箱”给出——除了计算其梯度的能力之外,没有任何假设。

黑盒方法有其优点,例如,我们可以很容易地改变损失函数,而不改变训练算法。但是这种方法有一个主要缺点——我们没有利用任何关于 f 的知识,如果利用这些知识,可能会导致更有效的算法,并大大减少训练我们的模型所需的计算资源。

热身——近视图

梯度步骤通常被教导为“在负梯度方向上迈出一小步”。但是还有一种替代观点,即近端观点:

梯度法的近视图。蓝色——在 w_k 处的切线。红色——靠近 w_k

让我们简化上面的“多毛”公式。蓝色项是切线,或在 w_k 处的一阶近似,而红色项是对 w_k. 的近似度量。因此,根据近似视图,

在每次迭代中,我们最小化一个在沿切线下降和保持接近 w_k 之间平衡的函数。

两个冲突力之间的平衡由 1 /η — 邻近项的权重决定。正切和邻近项之和在 w_k 处产生一条‘正切抛物线’,其最小值是下一次迭代。

因此,直观地说,近端视图将梯度步长解释为正切抛物线的最小值,其局部近似我们的损失函数,如下所示。 η 越大,抛物线越“平”,因此我们离当前迭代 w_k 越远。

黑色曲线——损失函数 f .橙色曲线——局部近似正切抛物线。我们计算梯度步长,作为正切抛物线的最小值。

形式上,要说服自己上面的公式确实是变相的梯度步长,我们来解决最小化问题。取 argmin 内的项的梯度 w.r.t w 并使其等于零,得到:

两边乘以 η 并提取 w ,恢复梯度步长。

备注:梯度法的近似观点在优化领域已经广为人知很久了,可以在 Boris Polyak 1987 年出版的《优化导论》一书中找到。

变暖—正规化

切线当然是我们一无所知的函数的合理近似。但是如果我们知道些什么呢?我们可以用更好的近似值代替蓝色部分(切线)吗?

我们来看一个具体的例子。假设每个损失都被正则化,即,

其中 lᵢ 是(可能加权的)‘原始’损失,我们在其上添加一个正则化项。在这种情况下,我们可以用切线来近似 lᵢ ,同时保持正则项不变。为什么我们要?因为以下直觉的经验法则:

我们逼近得越少,关于损失函数的信息被保留和利用得越多,从而获得更好的算法。

在我们的例子中,原来的梯度步骤被替换为

看看能否得到一个 w_{k+1} 的显式公式。取梯度 w.r.t w ,等于零,结果为:

提取 w ,我们得到

我们得到了一个全新的算法,它与直接应用于损失的随机梯度法有本质的不同。根据我们的新算法,在每次迭代中,我们将随机梯度步骤应用于“原始”损失 l ,然后将结果除以(2 η +1)。

超越 L2 正则化

如果正则项不是平方欧几里德范数,而是其他函数 g 会发生什么?明确地写,损失是

最近的问题变成了

我们获得了众所周知的近端梯度阶梯。为了在实践中实现,我们需要一个显式的公式来进行下一次迭代 w_{k+1}。

在前面的例子中, g 是平方欧几里德范数,在这种情况下,我们可以很容易地获得一个显式公式。一般来说,推导这样一个公式并不总是可能的,当它是可能的时候,它取决于函数 g 。每个 g 导致不同的定制更新步骤,因此该方法不再是“黑盒”——我们为每个 g 定制它。

因此, g 应该足够“简单”,这样就可以得到一个简单的显式公式,因此这个方案只适用于这种“简单”的函数 g

更多主题

  • 不同的近似值而不是正切值导致稳定的学习——它对步长的选择不太敏感,为我们节省了昂贵的步长调整。参见[1]中的示例。
  • 超越切线抛物线—考虑非二次邻近项。例子包括众所周知的镜像下降算法[2]的随机变体,这对于许多问题类别是有利的。

参考

[1]:希拉勒·阿西,约翰·杜奇(2019 年 7 月)。随机(近似)邻近点方法:收敛性、最优性和适应性。https://arxiv.org/abs/1810.05633

[2]:阿米尔·贝克、马克·特布尔(2003)。凸优化的镜像下降和非线性投影次梯度方法。https://www . science direct . com/science/article/ABS/pii/s 0167637702002316

打开集群的黑匣子— KMeans

原文:https://towardsdatascience.com/opening-the-black-box-of-clustering-kmeans-e970062ff415?source=collection_archive---------29-----------------------

无监督学习系列的第一部分

Brian Kostiuk 在 Unsplash 上拍摄的照片

这是聚类的三部分系列的第一部分,其中我将介绍一些最流行的聚类算法,包括 K-Means凝聚聚类高斯混合模型。这些是分别基于分区/距离、层次和密度的不同聚类方法。

本文专门介绍 K-Means 聚类。

“无监督学习是未来大多数人的学习方式。你脑子里有这个世界如何运转的模型,你正在对它进行提炼,以预测你认为未来会发生什么。”— 马克·扎克伯格

无监督学习形成了机器学习的一个非常小众的部分,只是因为大多数任务都有一个标签(监督)。然而,在我们缺少这些标记为数据的情况下,聚类方法可以通过对数据集进行推断来帮助我们找到模式。应用聚类的常见领域包括客户细分(针对广告定位)、人口分析(了解人口统计数据)以及异常检测。

一些人认为无监督学习是机器学习中的一个灰色区域,因为有时很难解释算法输出的聚类类型,因为没有单一的“度量”可以告诉我们这些预测的聚类有多有意义。

k 均值

K-means 聚类是一种基于距离的聚类方法,用于在一组未标记的数据中寻找聚类和聚类中心。这是一个久经考验的方法,可以使用 sci-kit learn 轻松实现。

K-Means 的目标相当简单——将“相似”(基于距离)的点分组在一起。这是通过将数据点的中心视为相应聚类(质心)的中心来实现的。

核心思想是这样的:通过迭代计算更新聚类质心,迭代过程将继续,直到满足某些收敛标准。

工作原理:

  1. 首先,选择期望的集群数量,比如说 K
  2. 从数据集中选择 K 个随机点作为聚类质心。
  3. 在每一步,选择一个未分配的数据点,并检查哪个质心最接近它。亲密度的定义通常由距离度量来衡量,通常以欧几里德距离的形式。
  4. 为每个点分配一个聚类后,使用同一聚类内数据点的平均值重新计算新的聚类质心。这用于优化群集质心的位置。
  5. 重复步骤 3 和 4,直到 a) 质心已经稳定(不超过阈值)或者 b) 已经达到期望的迭代次数。

注意,质心实际上不是数据集中的实际数据点。

使用虹膜数据集的示例

对于那些不熟悉这个数据集的人来说,它包含了鸢尾花的变异数据,特征包括sepal_lengthsepal_widthpetal_lengthpetal_width。由于这是一个无人监督的问题,我不会透露有多少种不同类型的虹膜(要了解更多关于数据集的信息,请访问此 链接 )。

我们将使用iris数据集来展示 K-Means 如何工作。让我们首先导入数据并将其可视化。

import numpy as np
from sklearn import datasets, cluster
import matplotlib.pyplot as plt
%matplotlib inlineiris = datasets.load_iris()
x = iris.data[:, [1,3]] # takes the 2nd and 4th column of the data
plt.scatter(x[:,0], x[:,1])
plt.xlabel('Sepal width')
plt.ylabel('Petal width')
plt.show()

上述代码块的输出

从上面的形象化来看,似乎有两个不同的星团。现在,让我们使用 sci-kit learn 的 K-Means 算法。

from sklearn.cluster import KMeansx_ = iris.data # Note that in we use all 4 columns here
random_state = 2020kmeans = KMeans(n_clusters=2, init='k-means++', random_state=random_state)
kmeans.fit_transform(x_)
label = kmeans.labels_
color = ['red','green','blue']plt.figure(figsize=(8, 6))
plt.scatter(x_fit[:,0], x_fit[:,1], c=[color[i] for i in label], marker='+')
plt.title('Kmeans on Iris dataset with 2 clusters', fontweight='bold', fontsize=14)
plt.show()

虹膜数据集上的 k-均值算法

看起来使用n_clusters = 2的分离产生了相当不错的结果,除了少量可能被错误聚类的数据点(中间的绿色数据点应该是红色的)。

从上面,我们通过视觉检查数据(使用两个特征)来确定集群的数量n_clusters。很明显,确定最优的n_clusters是聚类中非常重要的一步,尤其是 K-Means,这个数字必须在算法中预先指定。通过使用两个特征来直观地检查数据显然是不够的,因为如果我们的数据是高维的,可能会有额外的聚类,并且我们的人类判断可能会失败(特别是对于任何更三维的数据)。

如何确定最佳聚类数

方法 1: 弯头绘图

该方法使用 sklearn 的inertia_方法计算总的类内误差平方和 (SSE)。肘部扭结的点(梯度急剧变化)表明收益递减,我们通常希望在这种情况发生之前采取n_clusters。直觉上,我们想要一个最小化 SSE 的数字k,但同时增加的k会自然地将 SSE 减少到零(其中每个数据点都是它自己的聚类)。在下面的例子中,n_clusters = 3似乎是最理想的。

elbow = []
kmax = 10for k in range(2, kmax+1):
    kmeans = KMeans(n_clusters = k).fit(x_)
    elbow.append(kmeans.inertia_)

plt.figure(figsize=(8,6))
plt.plot(np.arange(2,11), elbow)
plt.xlabel('Number of Clusters')
plt.ylabel('Inertia (Intra cluster sum of squares)')
plt.title('Inertia vs n_clusters to determine optimal cluster size', fontweight='bold')
plt.show()

利用惯性确定最佳 n _ 簇

但是,当数据不是很集中时,这种方法可能不太适用。因此,用我们的下一个方法做交叉检查可能更好。

方法 2: 剪影图

轮廓系数本质上就是我们所说的簇间距离。一般来说,聚类旨在最小化类内距离,同时最大化类间距离。使用这两种方法将确保n_clusters被更好地定义。

from sklearn.metrics import silhouette_score
sil = []
kmax = 10for k in range(2, kmax+1):
    kmeans = KMeans(n_clusters = k).fit(x_)
    labels = kmeans.labels_
    sil.append(silhouette_score(x_, labels, metric = 'euclidean'))

plt.figure(figsize=(8,6))
plt.plot(np.arange(2,11), elbow)
plt.xlabel('Number of Clusters')
plt.ylabel('Silhouette Coefficient (Inter-cluster distance)')
plt.title('Silhouette vs n_clusters to determine optimal cluster size', fontweight='bold')
plt.show()

利用剪影系数确定最佳 n 簇

理想情况下,我们希望轮廓系数尽可能高(即最大化聚类间距离)。在这种情况下,n_clusters = 2似乎是最理想的。

协调肘部和轮廓之间的差异

既然手肘图提示n_clusters = 3而侧影图提示n_clusters = 2我们该怎么办?

方法一:尽量把数据可视化!在这种方法中,我们使用主成分分析(PCA ),以便我们可以绘制数据的三维图。因为这个主题是关于聚类的,所以我不会深究 PCA 的细节(如果你们想了解它,请在评论中告诉我!).

from sklearn import decomposition
from mpl_toolkits.mplot3d import Axes3Dx_full = iris.datapca = decomposition.PCA()
xr = pca.fit_transform(x_full)kmeans = cluster.KMeans(n_clusters=3, init='k-means++', random_state=random_state)
kmeans.fit(xr)
label = kmeans.labels_
color = ['red', 'green', 'blue']plt.figure(figsize=(12, 12))
fig = plt.subplot(1, 1, 1, projection='3d')
fig.scatter(xr[:,0], xr[:,1], xr[:,2], c=[color[i] for i in label])
fig.scatter(kmeans.cluster_centers_[:,0], kmeans.cluster_centers_[:,1], c='yellow', s=100)
fig.set_xlabel('Principal Component 1')
fig.set_ylabel('Principal Component 2')
fig.set_zlabel('Principal Component 3')
plt.show()

虹膜数据集的三维图(PCA 后)

从上面的三维图来看,似乎确实有三个不同的集群——尽管不能完全确定,因为集群间的距离并不高。

方法 2: 使用描述性统计来理解聚类

描述性统计涉及使用平均值、最大值、最小值和中值等度量来找出聚类之间的差异。在无监督学习中,手头的问题没有“正确”的答案,大多数时候,找到最佳数量的聚类需要查看这些聚类的结果(即,比较这些不同聚类的描述性统计数据)。

(然而,在这种情况下,如果我们想要“作弊”,我们确实知道在数据集中实际上有 3 种不同类型的虹膜变体(因为它被标记了!)

K 均值评估

优点:

  • 易于使用和理解
  • 适用于聚类之间的层次关系易于检测的数据集
  • 相对较低的时间复杂度和较高的计算效率,从而带来较高的可扩展性

缺点:

  • 不适合非凸数据
  • 对聚类质心的初始化高度敏感——值得调整超参数,如n_initinit='random',以确保获得一致的聚类结果
  • 对异常值高度敏感——K-Means 中的表示表示异常值会显著扭曲聚类质心——其他使用众数或中位数的算法不太容易出现异常值
  • 容易陷入局部最优
  • 聚类结果对聚类数很敏感

最后的想法和结束语

对于任何聚类问题,K-Means 都是一个很好的入门模型,因为它能够适应高维数据。但是,重要的是要知道正在使用哪种距离度量、模型对异常值的敏感度,以及最重要的是,使用领域知识来相应地调整模型。

在这个 3 部分系列的第二部分中,我将探索一个不同的数据集,并使用凝聚聚类(层次聚类的两种变体之一)进行分析。我还将通过一些方法来获得模型所产生的集群的描述性统计数据。

专业提示 :解释生成的聚类与获取聚类本身同等重要(如果不是更重要的话)!

请继续关注这个聚类系列剩下的两个部分——凝聚聚类高斯混合模型

OpenPose 研究论文摘要:具有深度学习的多人 2D 姿态估计

原文:https://towardsdatascience.com/openpose-research-paper-summary-realtime-multi-person-2d-pose-estimation-3563a4d7e66?source=collection_archive---------21-----------------------

机器理解人类的姿势。

AI 篮球分析。图片由 Chonyy 提供。

介绍

这篇论文总结会让你很好的理解 OpenPose 的高层概念。由于我们将重点放在他们的创造性管道和结构上,所以在这个总结中不会有困难的数学或理论。

我想先谈谈为什么我想分享我从这篇精彩的论文中学到的东西。我已经在我的AI 篮球分析 项目中实现了 OpenPose 库。在我构建这个项目的时候,我只知道 OpenPose 的基本概念。我花了大部分时间研究代码实现,并试图找出将 OpenPose 与我最初的篮球投篮检测相结合的最佳方式。

来源:https://github.com/CMU-Perceptual-Computing-Lab/openpose

现在,正如你在 GIF 中看到的,这个项目已经基本完成了。我在搭建了这个项目之后,对 OpenPose 的实现有了充分的掌握。为了更好地了解我一直在处理的事情,我想现在是我更深入地看看 研究论文 的时候了。

图像取自“使用部分亲和场的实时多人 2D 姿势估计”。

概观

在这项工作中,我们提出了一种实时方法来检测图像中多人的 2D 姿态。

所提出的方法使用非参数表示,我们称之为部分亲和场(PAF),以学习将身体部分与图像中的个体相关联。这种自下而上的系统实现了高精度和实时性能,而不管图像中有多少人。

为什么难?

让我们先来谈谈是什么让估算图像中多人的姿势变得如此困难。这里列出了一些困难。

  • 人数不详
  • 人们可以以任何姿势或比例出现
  • 人的接触和重叠
  • 运行时的复杂性随着人数的增加而增加

通用方法

OpenPose 绝对不是第一个面临这个挑战的团队。那么其他团队是如何解决这些问题的呢?

来源:https://medium . com/synced review/now-you-see-me-now-you-don-folling-a-person-detector-aa 100715 e 396

一种常见的方法是采用一个人检测器,并为每次检测执行单人姿势估计。

这种自上而下的方法,听起来真的很直观简单。然而,这种方法有一些隐藏的陷阱。

  • 早期承诺:当人员探测器出现故障时,没有资源进行恢复
  • 运行时间与人数成正比
  • 即使人检测器失败,也执行姿态估计

最初的自下而上方法

如果自顶向下的方法听起来不是最好的方法。那我们为什么不试试自下而上呢?

毫不奇怪,OpenPose 并不是第一个提出自下而上方法的团队。其他一些团队也尝试了自下而上的方法。然而,他们仍然面临着一些问题。

  • 在最终解析时需要昂贵的全局推理
  • 没有保留效率上的收益
  • 每幅图像需要几分钟

开放式管道

整体管道。图像取自“使用部分亲和场的实时多人 2D 姿势估计”。

(a) Take the entire image as the input for a CNN
(b) Predict confidence maps for body parts detection
(c) Predict PAFs for part association
(d) Perform a set of bipartite matching
(e) Assemble into a full body pose 

置信图

置信图是特定身体部位可以被定位的信念的 2D 表示。单个身体部位将被表示在单个地图上。因此,地图的数量与身体部位的总数相同。

右图只用于检测左肩。图像取自“使用部分亲和场的实时多人 2D 姿势估计”。

阵发性心房颤动

部分亲合场(PAF),一组 2D 矢量场,对图像域上肢体的位置和方向进行编码。

图像取自“使用部分亲和场的实时多人 2D 姿势估计”。

二分匹配

图像取自“使用部分亲和场的实时多人 2D 姿势估计”。

在寻找多人的全身姿态时,确定 Z 是一个 K 维匹配问题。这个问题是 NP 难的,存在许多松弛问题。在这项工作中,我们添加了两个针对我们领域的优化放松。

  • 松弛 1:选择最小数量的边来获得生成树骨架。
  • 松弛 2:将匹配问题进一步分解为一组二部匹配子问题。独立确定相邻树节点中的匹配。

结构

原结构

图片由 Chonyy 提供。

原来的结构是分裂成两个分支

  • 米色分支:预测置信图
  • 蓝色分支:预测 PAF

这两个分支都被组织为迭代预测架构。来自前一阶段的预测与原始特征 F 连接,以产生更精确的预测。

新结构

图像取自“使用部分亲和场的实时多人 2D 姿势估计”。

第一组阶段预测 PAFs L t,而最后一组预测置信图 st。每个阶段的预测和它们相应的图像特征被连接用于每个后续阶段。

与他们以前的出版物相比,他们取得了重大突破,提出了一种新的结构。从上面的结构可以看出,置信图预测是在最精确的 PAF 预测之上运行的。

为什么?原因其实真的很简单。

我凭直觉,如果我们看一下 PAF 通道的输出,身体部位的位置就能猜到。

其他图书馆呢?

越来越多的计算机视觉和机器学习应用需要 2D 人体姿态估计作为其系统的输入。OpenPose 的团队绝对不是唯一做这项研究的人。那么,为什么我们总是想到 OpenPose 当谈到姿态估计而不是阿尔法姿态?以下是其他图书馆的一些问题。

  • 要求用户实现大部分管道
  • 用户必须构建他们自己的框架阅读器
  • 面部和身体关键点检测器没有组合

人工智能篮球分析

我在这个 AI 篮球分析 项目中实现了 OpenPose 。一开始我只有一个想法,就是想分析射手的射击姿势,但是完全不知道怎么做!幸运的是,我遇到了 OpenPose,它给了我想要的一切。

图片由 Chonyy 提供。

虽然安装过程有点麻烦,但实际的代码实现相当简单。它们的功能以一帧作为输入,输出人体坐标。更好的是,它还可以在框架上显示检测覆盖图!代码实现的简单性是他们的 repo 能够在 GitHub 上获得 18.6k+ stars 的主要原因。

我的项目在下面,可以随意查看!

[## chonyy/AI-篮球-分析

🏀用机器学习分析篮球投篮和投篮姿势!这是一个人工智能应用…

github.com](https://github.com/chonyy/AI-basketball-analysis)

参考

[1]曹哲,学生会员,IEEE,吉恩斯·伊达尔戈,学生会员,IEEE,托马斯·西蒙,施-韦恩,亚塞尔·谢赫,“OpenPose:使用部分亲和场的实时多人 2D 姿势估计”,CVPR,2019。

使用气流在 Apache Mesos 和 Hadoop 上操作 ML 管道

原文:https://towardsdatascience.com/operationalization-of-ml-pipelines-on-apache-mesos-and-hadoop-using-airflow-8c1d89e0ad3b?source=collection_archive---------55-----------------------

在《纽约客》将 ML 模型投入生产的架构

这篇博文最初出现在《纽约客》科技博客上。

西蒙·米加吉在 Unsplash 上拍摄的照片

零售公司中对机器学习影响最大的用例之一是降价。作为欧洲最大的时装零售商之一,纽约客为我们在 45 个国家的 1100 家商店出售的每件商品设定了初始价格。价格在一系列降价中逐渐降低,直到商品售完。目标是预测何时以及如何降价,以便整个存货以尽可能高的价格出售。从而使公司收益最大化。

解决这个用例涉及两个任务:创建一个提供准确预测的模型,并在我们当前的基础设施上将它投入生产流水线。

在本文中,我们将重点关注后一项任务,并介绍一种使用气流在 Apache Mesos 和 Hadoop 上编制生产中的机器学习管道的架构。我们从机器学习模型的需求以及我们当前的基础设施和数据工程架构提出的需求开始。然后,我们提出了一个满足这些要求的架构,包括容器化、流水线流程编排、性能考虑和简化的 DAG 代码。最后是总结和对未来工作的展望。

要求

让我们从我们希望实施的模型的需求开始,以及从我们当前的基础设施和数据工程架构中产生的需求。

模型的训练数据作为 Parquet 文件存储在我们的 Hadoop 集群中的 HDFS 上。它们是使用 Spark 进行大量前期批量数据处理的结果,包括数据清理、汇总和必要的插补。这个遗留的 ETL 还没有与 Airflow 进行编排,它使用 Luigi 进行工作流管理,使用 Cron 作业进行调度。

模型是用 Python 写的,采用的机器学习框架应该由我们的数据科学家来选择。目前使用的是 LightGBM。训练和推理是在每个国家的基础上完成的,这一特性我们可以在以后的并行化中利用。GPU 支持很重要,因为我们的数据科学家也在考虑深度学习方法,这将从中受益。

模型的结果预测需要写入我们的 ERP 系统的持久层——一个关系数据库。这些预测为我们的定价部门提供指导,定价部门通过 ERP 的用户界面检查这些预测的合理性,并在其认为合适的时间和地点应用建议的降价。由于预测变化非常缓慢,因此需要在每周初刷新一次。

除了前面提到的 Hadoop 集群,我们还在基础设施中部署了一个DC/操作系统集群。它为我们提供了基于 Apache Mesos 的容器编排和资源调度。GPU 可以通过马拉松应用节拍器作业定义用于长时间和短时间运行的应用。我们有一个在 DC 操作系统上运行的集装箱化气流装置,用于编排我们的大部分数据管道。

体系结构

为了满足上述要求,我们提出了以下架构。

集装箱化

我们已经决定将模型训练和推理计算容器化,并使用 DC/OS 来运行它。这有两个好处。首先,它保留了我们的数据科学家选择的机器学习框架的独立性。其次,我们可以利用 DC/OS 集群上现有的 GPU 来加速未来的深度学习方法。

如果我们选择在 Hadoop 上使用 SparkML 或使用 Spark 并行化另一个 ML 框架,我们将不得不将现有的 LightGBM 模型迁移到这种方法。这样我们就基本上锁定了所采用的 ML 框架。此外,为了方便 GPU 的使用,我们需要在 Hadoop 集群上安装 GPU,或者将它们从 DC/操作系统集群移动到 Hadoop 集群。还需要将 Hadoop 版本从目前的 2.x 升级到 3.x。所有这些都不是小事,而且非常耗时。

容器本身具有以下工作流程:

开始时,它从 HDFS 下载训练数据。然后,它在此基础上训练模型,并计算给定国家的预测。最后,预测在 ERP 的底层关系数据库中被刷新。

预测的刷新在单个事务中完成,即,它删除单个国家所有项目的旧预测,并写入新预测。我们在这里不使用更新,因为预测集会随着时间而变化。这样,ERP 的用户将总是在 UI 中看到对所选项目集的预测,而不会停机。

我们已经对容器进行了参数化,因此它不仅可以计算和刷新单个国家的预测,还可以计算和刷新特定国家组的预测。

管道编排

有了用于模型训练和推理的参数化容器,我们现在可以继续部署和编排它的多个实例,以在气流的帮助下形成适当的管道:

对于短期运行的应用程序,如作业,DC 操作系统在 Mesos 上提供 Metronome 作为任务调度器。由于我们的容器本质上是短暂的,我们可以使用 Metronome 将其部署在 DC/OS 集群上。我们使用 MetronomeOperator 从气流中实现这一点,稍后我们将对此进行更深入的介绍。

我们为国家组启动 MetronomeOperator 的多个实例,以便覆盖所有 45 个国家,从而有效地并行化工作。

由于传统的 ETL——在 Hadoop 上处理所需的训练数据——还没有与气流协调,我们采用了一个经过修改的 HDFS 传感器来触发 MetronomeOperator 实例的启动。最初的气流 HDFS 传感器只能在 Python 2 中使用。我们做了一些小的改动,以便它可以与我们在集装箱式气流安装中使用的 Python 3 版本一起工作。

它的代码可以在这里找到:
https://github . com/new Yorker data/ny-public-air flow-operators

我们安排管道与 Hadoop 上的遗留 ETL 同时启动。HDFS 传感器将持续轮询成功文件,并在找到文件时触发 DAG 中的其余操作员。

注意:作为生产管道的一部分,我们也将预测写给 HDFS,供将来分析。在计算过程中,我们记录了所有的弹性搜索步骤。我们已经部署了 Kibana 仪表板,目前使用 elastalert 来监控异常情况并发出警报,例如,预测数量比上次运行时减少了 10%。
在促进生产变更之前,我们使用 Neptune 作为测试管道的一部分,以跟踪和评估各种变更对模型本身的影响。

节拍器气流操作器

据我们所知,在项目开始时,没有节拍器操作员负责气流。所以我们创造了一个。

它将 Metronome 作业定义作为 JSON 参数,如下图所示工作:

首先,我们从 IAM REST API 获得一个授权令牌,以便能够在 DC/OS 集群上部署容器。其次,我们通过 Metronome REST API 检查作业是否存在。根据响应,我们向上插入作业定义。然后我们开始工作。最后,我们轮询作业状态,根据响应,将气流操作员的状态更改为成功失败

操作员的代码可以在这里找到:
https://github . com/new Yorker data/ny-public-air flow-operators

性能考虑因素

在 Metronome 作业定义中,我们可以为容器指定 CPU、RAM 和 GPU 的使用。因此,我们可以纵向扩展。关于横向扩展,我们通过并行化国家组的模型训练和推断来实现。然而,并行度并不是无限的,而是受到可用集群资源的限制。为了不耗尽所有资源,我们使用气流资源池特性来限制并发运行的容器数量。资源池名称在所有 MetronomeOperator 实例中设置,我们将在下面的 DAG 代码中看到。因此,资源池的大小等于并行度。

实施为气流 DAG

下面你可以找到简化版的气流 DAG:

*default_args = {
    "owner": "ny-data-science",
    "start_date": datetime(2020, 1, 1),
    "provide_context": True
}dag = DAG(
    "markdown-pricing-dag",
    schedule_interval="0 8 * * 1", # every Monday at 8am
    dagrun_timeout=timedelta(days=1),
    default_args=default_args,
    max_active_runs=1,
    catchup=True
)# Example list of countries for the model training and inference
COUNTRY_LIST = ["DEU", "AUT", "NLD", "FRA", "ESP", "ITA"]# Job template we will use in the MetronomeOperator
METRONOME_JOB_TEMPLATE = """
{{
  "id": "{}",
  "description": "Markdown Pricing ML Job",
  "run": {{
    "cpus": 4,
    "mem":  32768,
    "gpus": 0,
    "disk": 0,
    "ucr": {{
      "image": {{
       "id": "registry-dns-address:1234/markdown-pricing:latest-master",
       "forcePull": true
        }}
     }},
     "env": {{
        "COUNTRY_GROUP": "{}",
        "DB_USER": "{}",
        "DB_PASSWORD": "{}"
     }}
   }}
}}
"""# Creates a Metronome job on DC/OS by instantiating the MetronomeOperator with the job template above
# and setting the country group and other environment variables
def create_metronome_job_for_country_group(country_group, index):
    return MetronomeOperator(
        task_id=f"metronome_operator_{index}",
        metronome_job_json=
        	METRONOME_JOB_TEMPLATE.format(f"markdown-job-{index}",
                                          country_group,
                                         Variable.get("markdown_erp_db_user"),                                          Variable.get("markdown_erp_db_pwd")),
        dcos_http_conn_id="dcos_master",
        dcos_robot_user_name=Variable.get("robot_user_name_dcos"),
        dcos_robot_user_pwd=Variable.get("robot_user_pwd_dcos"),
        dag=dag,
        pool="markdown_metronome_job_pool",
        retries=3
    )# Get the resource pool size (in slots) for the MetronomeOperator instances from Airflow configuration
metronome_job_pool_size = get_pool_size(pool_name="markdown_metronome_job_pool")# Split the country list into groups into N parts of approximately equal length for parallelization purposes.
# N is here the size of the Metronome job pool.
# Given the COUNTRY_LIST defined above and N = 3, the function will return: [["DEU","AUT"], ["NLD","FRA"], ["ESP","ITA"]]
country_groups = split_country_list(COUNTRY_LIST, metronome_job_pool_size)# Iterates through the country groups and creates a Metronome job for each of those groups
metronome_countries_jobs = [create_metronome_job_for_country_group(country_group=country_group, index=index) for
                            index, country_group in enumerate(country_groups)]# HDFS sensor on the latest training data
training_data_sensor = NYHDFSSensor(
    task_id="training_data_sensor",
    filepaths=[f"/data/production/markdown_training_data/{get_current_date()}/_SUCCESS"],
    hdfs_conn_id="hdfs_conn_default",
    retries=1440,
    retry_delay=timedelta(minutes=1),
    timeout=0,
    dag=dag)# Create DAG
training_data_sensor >> metronome_countries_jobs*

结论和未来步骤

我们展示了一种架构,它允许我们在混合的 Mesos 和 Hadoop 集群环境中使用 Airflow 轻松编排机器学习管道。我们利用 Mesos 的容器编排和资源调度来水平和垂直扩展模型训练和推理,同时能够利用 GPU 提供的可用硬件加速。我们采用 Airflow 的强大功能,如传感器和动态 Dag,来跨集群有效地管理整个工作流。

未来我们仍有许多需要改进的地方。
例如,将 Hadoop 上的传统 ETL 从 Luigi/Cron 迁移到 Airflow 将允许我们弃用 HDFS 传感器,并通过使用 Airflow 的管道互依特性来简化 DAG。
我们也知道有些计算在所有国家都很普遍。这个步骤可以在一个单独的阶段中提取,所有进一步的阶段都将依赖于这个阶段,从而可能提高性能。

最后,我们正在准备将我们的集群从 Mesos 迁移到 Kubernetes。短期内,我们需要调整我们所有的机器学习管道。这在理论上应该相对容易实现,例如在 Dag 中使用 KubernetesOperator 而不是节拍器 Operator* 。从长远来看,Kubernetes 在机器学习操作化方法方面开辟了一个新的可能性世界,如 Kubeflow。*

2022 年制造业运营的漏桶和数据管道

原文:https://towardsdatascience.com/operations-in-year-2022-7c01716ef382?source=collection_archive---------56-----------------------

我被 2022 年制造运营和采购行业将如何发展的愿景所激励。对我来说,2017 年就已经为 2022 年有效的首席采购官和首席运营官的角色奠定了新的基础。拥有采购和供应链运作的核心领域知识是先决条件。但是,对业务场景中的数据科学和自动化有实际的理解是 cxo 的战略方向所在。

本文总结了我在供应链运营和采购行业长达十年的经验,以及我在数据科学和机器学习领域的两年历程。

根据 2016 年安永的数据,仅在印度就有 630 亿美元的库存过剩。除了现金对现金之外,周期数字显示了印度和世界其他地区营运资本周期的一个关键对比。例如,根据安永 2016 年的数据,印度食品生产商的 C2C 为 57 天,高于美国和欧洲的 34 天和 28 天。与 C2C 为 25、24 和 33 天的日本、欧洲和美国相比,印度电力公用事业部门的 C2C 为 70 天,表现不佳。

所以,以下是我写这篇文章的动机:

作者图片

首先,我想画一张制造组织运作过程的价值流图。这是一个由 6 个主要垂直市场组成的安排。从销售预测活动到订单执行。

作者图片

所有这些垂直市场都有各自的商业环境变量和多个利益相关者。例如,销售预测通常是分销网络中每个销售办公室或单位的综合需求汇总报表。

销售和运营计划(也称为 S&OP)是一项优化活动,其中 SKU 生产成本、交付周期等是要优化的目标。

重要的是要知道,这些垂直行业之间的有效互动对公司的底线极其重要。高效的交互意味着清晰、具体和准确需求的无缝传递。我多么希望是这样。在我看来,需求预测和 S&OP 仍然是“漏桶”现象的起点。“漏桶”是我对低效率运营的比喻,在这种运营中,由于执行质量差而导致成本流失。

让我们找出之前绘制的价值流中的漏桶。

作者图片

因此,我提议优先考虑 5 个漏桶。首席运营官必须开发自己的一套性能指标来衡量这些漏桶的健康状况。从表面上看,我认为从数据科学的角度来看,这些问题是这样的。

虽然图表是不言自明的,但如果您想从数据科学的角度来看这 3 个关键问题,它们是

1.)数据预测

2.)数据可用性

3.)数据优化

在提出解决方案之前,我认为对我来说,解释“现状”场景(即目前的实践)是非常重要的。

销售预测

让我们以销售预测为例。我们都知道供应链中的牛鞭效应。但是,它是如何开始的呢?答案是不准确的销售预测。

分销网络中的每个销售单位对其每月销售的每台 SKU 进行预测。然后,来自所有销售单位的数据被整合到一个 Excel 文件中(印度 80%的中小型制造公司都是如此)。然后,按照管理层建议的方向,在所有 SKU 中应用平均缩放/标准化功能。够公平吗?不,不是的。我觉得这种方法很懒惰。

这个过程本身存在固有的问题。单独的过去数据不足以产生准确的销售预测。一个好的销售预测应该考虑到

1.)不同 SKU 销售之间的相关性,以识别同类相食。这可以在每个区域进行。

2.)销售季节性因素

3.)因促销和折扣带来的销售增长

4.)我最喜欢的参数是考虑到由于没有存货而造成的销售损失。这是大多数 ERP 软件难以解决的问题,更不用说超越预测了。你如何对由于需求低而导致销售为零的情况和缺货的情况进行建模?

目前,印度制造业一个月的需求预测准确率为 65%。此外,S&OP 依赖这些预测来制定生产计划。从销售预测到生产计划的典型周期为 3-4 周。

这意味着预测中的任何修正在 3-4 周之前都不会被考虑在内。祝那些未售出的存货好运!这引发了一系列事件,导致印度库存过剩 630 亿美元。

采购

如果糟糕的销售预测会影响公司的收入,那么被动的采购方式会影响公司的收入。我非常详细地研究了一些领先制造商的采购方法。如果我必须概括目前的“现状”,它看起来像下面这样

作者图片

我希望您只用两个词来描述目前的采购行业。

1.)反应

2.)费力

大多数首席采购官都认为,在线平台是解决这一棘手问题的答案。我不同意。大多数在线平台仅仅是数据输入用户界面。此外,在此类在线平台的开发阶段,所有权成为一个问题。要么是内部 it 团队的,要么是外部咨询机构的。将你的问题外包给不同的团队并不能解决问题。这是懒惰。ERP 爱好者将会提出一个与今天的 MRP/MRP 模块相反的叙述,但是我对垃圾输入和垃圾输出是否适合今天所有的 ERP 套件持怀疑态度。

世界正快速从统计学转向微积分。ERP 软件实施的大部分是基于统计的,如果他们选择不进行过渡,到 2022 年将变得无关紧要。

大多数工具/分析是采购职能仍然在 Excel 中使用短期测量工具完成的,如条形图、加权平均值、成本指数和份额。如我所说,这是被动反应。

前进的道路

2022 年的运营前景看起来与今天截然不同。数据科学和机器学习将成为采购和运营经理的必备技能。是的,每个人都需要学习计算机编程的基础知识。以下是我在上述变化背景下的思考。

作者图片

2022 年的运营将被塑造成自主的、数据驱动的、最重要的可靠活动。只有目标的定义将由经理决定,其余的一切将自动运行。这就是我的 OPS 2.0。

那么,如何开始这段旅程呢?

在我看来,制造业运营可以从互联网 B2C 公司学到很多东西。他们已经开始了迈向 Ops 2.0 的旅程。他们的回答?机器学习

作者图片

OPS 2.0:高效布局

从“漏桶”结构来看,OPS 2.0 将有 3 个简单的垂直市场。

1.)预生产

2.)生产

3.)后期制作

连接这三个垂直领域的将是数据引擎的服务层。

作者图片

如果您还记得上面的幻灯片,我们已经强调了数据管理之旅的 3 个主要领域

1.)数据组织

2.)数据分析

3.)数据可用性

数据组织是指将所有不同的数据源整合到一个数据库中。随着团队的多样化,这是最耗费时间的操作。

多个 Excel 文件、不同格式的相同信息、针对同一组问题的不同假设集、多个利益相关方,这些都是给 OPS 2.0 之旅带来巨大压力的几个因素。

简而言之,合作是第一步。是的,在线平台是向前迈出的一大步。我在许多在线平台实施后的学习是专注于消除冗余信息。

“每个利益相关者都能一次性获得正确的信息”是我们应该采纳的座右铭。

然后,第 2 步需要 CPO、业务经理、采购经理和运营经理的核心领域知识。商业分析将由机器学习算法驱动。没有完美的算法,即使使用标准算法,也必须根据业务环境选择超参数。

机器学习就是优化。但是,它必须由目标或数据科学家定义的术语来指导:成本函数必须优化或分类。

如果你指望你的 IT 团队实现一个尺寸适合所有机器学习算法,准备失望吧。

在这三个垂直领域中的每一个领域,都有专门的数据科学家团队进行算法开发+业务经理亲自操作 python 和最小编码+ IT 团队使信息可访问。

这就是 OPS2.0 将由数据层即服务部署驱动的地方。

以下是我实施 OPS 2.0 的蓝图

作者图片

祝你 OPS2.0 之旅一切顺利!

如果您热衷于讨论更多内容,请随时联系我!我喜欢有用。

你可以免费使用这些内容。

问候

高拉夫·夏尔马

运筹学——内容、时间和方法

原文:https://towardsdatascience.com/operations-research-what-when-and-how-6dc56c48fed7?source=collection_archive---------2-----------------------

范围、示例和职业

“运筹学”这个(有些模糊的)术语是在第一次世界大战期间创造的。英国军方召集了一群科学家来分配不足的资源——例如,食物、医务人员、武器、部队等。—以最有效的方式应对不同的军事行动。所以“作战这个术语就是来源于“军事作战”。成功地进行军事行动是一件大事,在 40 年代,运筹学在大学里成为了一门独立的学科。

运筹学维基百科页面

当你在谷歌上搜索“运筹学”时,你会得到一篇很长的维基百科文章,然而,解释却有点杂乱无章,说实话,也过时了。所以我想我应该给这个我在研究生院学习的主题一个小小的更新。

以下是我的观点:

1.运筹学一个词:优化。

假设我们正在做一个决定。如果我们必须做出可能的最佳决策,我们该怎么做?

你通过权衡每个选项的利弊来评估每个可能的选项。

例如,为了让优步有一个主路线计划,它必须决定哪个司机应该被送到哪里,何时,以及他们应该向客户收取多少费用。这些决策必须在优化使用可用资源的同时做出。

我不知道优步的目标函数是什么,但是他们正试图通过派遣车手来达到最大化。假设是收益。此外,每次派送都会产生相关成本,路线计划应符合优步政策的具体限制。

运筹学一句话:在约束下把事情做得最好。

用数学术语来说,上面的问题可以写成:

 **Maximize F(X1, X2, …, Xn)****Such that it meets the constraints C1, C2, …, Cm.** 

这种类型的公式化称为最优化数学规划

有一个目标函数要被最大化(即利润)或最小化(即成本、损失、某些不良事件的风险等)。) X决策变量。它们是我们可以调整的东西。比如每个 X 都可以是一个驱动。 X_i=1 表示驱动程序 I 被选中,并将发送给客户。 X_i=0 表示他没有被选中。 C 的约束。例如,每辆车与潜在客户之间都有一个距离。司机一天只能开这么多小时。每条路都有限速,每辆车都有最大载客量。

这是运筹学最常见的例子。

2.OR 中的三个主要问题类别

或中的大多数问题都属于三个问题类别之一。

Ⅰ.最佳化

  • 数学规划:和上面优步的例子一样,我们选择决策变量 (司机调度)目标函数(利润最大化)和一组(物理、技术、经济、环境、法律、社会等)。)约束。然后,我们用数学方法解决它们。
  • 数值优化:数值优化可以是基于梯度的,也可以是非梯度的。梯度下降,机器学习中最流行的优化算法之一,是一种基于梯度的(顾名思义)优化。还有很多非梯度算法(无导数优化)以及贝叶斯优化、 布谷鸟搜索遗传算法等。当目标函数不光滑或者目标函数的封闭形式不可用时,使用非梯度算法。

机器学习与优化密切相关。许多 ML 问题被公式化为一些损失函数的最小化。在训练过程中,优化算法使训练集上的损失最小化。然而,最大似然的最终目标是最小化不可见数据的损失。因此,机器学习是一个以“泛化”为目标的优化问题

Ⅱ.概率建模

概率模型输出概率分布,而确定性模型输出事件的单一可能结果。

众所周知的概率模型之一是交叉熵,我们经常使用它来预测目标上的概率分布 贝叶斯推理和最大后验概率(MAP) 也是概率模型的重要应用。

Ⅲ.模拟

当推导一个概率分布不方便时,模拟用于近似一个概率分布。它使用重复随机抽样并获得数值结果。这个想法是利用随机性来解决本质上可能是确定性的问题。模拟有多种用途;例如,从不同的概率分布中生成抽奖、数值积分、强化学习、期权定价等。

3.现实生活中的应用

运筹学被应用到许多真实世界的用例中。

  • 指派(指派优步司机给客户)
  • 时间安排(将多个电视节目安排在一起,以获得尽可能多的观看次数)
  • 金融工程(资产配置、风险管理、衍生品定价、投资组合管理等。)
  • 智能竞价在 Youtube 上,算法广告的自动竞价系统(确定一个特定的印象可以带来多少增量价值,以及我们应该为此支付多少钱。)
  • 定价科学(机票定价)
  • 路线(主规划公交车路线,使需要的公交车尽可能少)
  • 设施位置(决定仓库、工厂或消防站等新设施的最合适位置)
  • 网络优化(数据包路由)

最后但同样重要的是…脑筋急转弯(科技面试)!

这些脑筋急转弯在科技面试中非常常见,至少在 FAAMG 中是如此。我个人被问了下面三个中的两个。

  • N 皇后问题:如何将 N 个皇后放置在 N×N 的棋盘上,使得其中没有两个互相攻击。两个皇后不应在同一行、列或对角线上。

解决方案:https://www . geeks forgeeks . org/n-queen-problem-backtracking-3/

  • 旅行推销员问题:OR 中的经典问题。一名销售人员将在不同的城市会见许多客户。最短的往返旅程是什么时候?用数学术语来说,给定一个有向的边加权图,图中每个节点恰好经过一次的最短循环路径是什么?

https://xkcd.com/399

解:https://www . geeks forgeeks . org/traveling-salesman-problem-set-1

  • 斯蒂格勒饮食法 :以诺贝尔经济学奖获得者乔治斯蒂格勒命名,他计算出一种廉价的方法来满足给定一套食物的基本营养需求。这是一个经典的线性优化问题。我们如何选择一套食物,以最低的成本满足一套日常营养需求?

解决方案:https://developers . Google . com/optimization/LP/glop . html # stigler

4.你将学习的科目,如果你选择学习或。

我在哥伦比亚大学攻读了运筹学硕士学位,毕业时有四门必修课。

一.概率论

您将学习描述性统计、如何构建统计模型、推断性统计,例如寻找最大似然估计量和构建置信区间。还会学习联合分布、条件独立独立随机变量之和矩母函数、大数定律、中心极限定理、无限可分定律等。

二。确定性模型

使用确定性模型,无论重新运行模型多少次,对于特定的输入,您都会得到完全相同的结果。换句话说,确定性模型中不包含随机性,这在现实世界中不太可能发生。在这堂课中,你将学习问题公式化、线性规划、单纯形算法、动态规划、对偶理论、灵敏度理论等。

三。随机性模型

你将学习运筹学中的随机建模技术,如马尔可夫链、生灭过程、泊松过程、赌徒的破产问题、、布朗运动等。对我来说,这是我的课程中最有趣也是最具挑战性的一门课。

你可以将这些技术应用于强化学习(随机过程探索)、金融工程(看涨/看跌/一揽子期权定价、保险风险测量等)。)、排队/可靠性/库存建模等。

与确定性模型不同,随机模型考虑了随机性。因此,具有相同参数的相同模型可能会输出不同的结果。

四。模拟

您将学习如何从不同的分布中生成随机变量,蒙特卡罗,分层抽样,接受-拒绝方法,使模拟更有效的方差减少技术,马尔可夫链蒙特卡罗(MCMC),吉布斯采样器,验证模拟模型的统计验证技术,如何分析模拟输出等。

你也可以选修很多课程:博弈论、机器学习(数据挖掘)、高级优化、非线性优化、随机控制、实数分析、金融工程、资产配置、定价模型、金融风险管理、信用风险建模、结构化和混合产品、深度学习、供应链管理、物流等。

5.职业

如果我追踪曾经和我在同一个项目中的朋友现在在哪里,他们无处不在。

很多都是金融行业的。可能因为我的学校离华尔街很近。他们在不同的团队工作,如风险管理、交易、量化研究,甚至在销售或投资银行

他们中的许多人也成为了科技公司的数据/应用科学家。Azure 和 AWS 广泛雇用数据科学家,以便优化他们的云停机时间,分配计算能力,估计实时需求等。此外,按需服务公司(优步、Lyft、AmazonPrimeNow、Doordash 等)的定价团队和调度团队。)专门寻找运筹学专业的科学家角色。社交媒体公司(Twitter、脸书、YouTube 等)的算法竞价(Adtech)团队(T7)。)对广告竞价定价、受众定位、用户参与度预测模型等方面有很多需求。

就我个人而言,我刚毕业就开始在一家金融服务公司工作,做外汇衍生品交易商。然后我加入了一家 adtech 初创公司,担任数据科学家。现在我在微软做研究工程师,研究问题回答(NLP)问题。

如果你对应用数学的运筹学有扎实的掌握,你可以选择的行业范围是非常广泛的。

补充几点:

  1. 根据“搜索没有免费的午餐定理”,没有一个特定的优化算法对每个问题都是最好的。

“我们证明,当对所有可能的成本函数进行平均时,搜索成本函数极值的所有算法的性能完全相同。特别是, 如果算法 A 在某些成本函数上优于算法 B,那么粗略地说,一定存在同样多的其他函数 B 优于算法 A

因此,选择您将使用的优化算法应该取决于问题。例如,当我训练深度学习 NLP 模型时,我的 go-to 算法是 ADAM,因为它效果好,速度快。我从来没有真正使用 L-BFGS,即使理论上它收敛更快,因为根据我的经验, SGD 在训练时间和最终结果方面与二阶算法一样好。然而,当 L-BFGS 提供比 SGD 更好的性能时,会有一些问题。这是郭乐的论文(它发表于 2011 年,所以有点旧了)“关于深度学习优化方法的”指出 L-BFGS 击败了 SGD:

“我们的实验结果反映了不同优化方法的不同优缺点。在我们考虑的问题中, L-BFGS 对于低维问题,尤其是卷积模型,具有很强的竞争力,有时甚至优于SGDs/CG。* 对于高维问题,CG 更具竞争力,通常表现优于 L-BFGS 和 SGDs。 此外,通过 SGD 使用大型迷你批处理和线搜索可以提高性能"*

2.谷歌有一个很好的开源工具或者工具

  • 约束编程
  • 线性和混合整数规划
  • 装箱和背包算法
  • 旅行推销员问题的算法
  • 车辆路径问题
  • 图形算法(最短路径、最小费用流、最大流、线性和分配)等。

* [## 或者-工具|谷歌开发者

developers.google.com](https://developers.google.com/optimization)*

围绕 OpenCV AI kit 的炒作值得吗?

原文:https://towardsdatascience.com/opinion-26190c7fed1b?source=collection_archive---------31-----------------------

意见

如果你是一个有抱负的计算机视觉爱好者,OpenCV OAK-1 和 OAK-D 套件到处都是新闻。但是值得吗?

迈克尔·泽兹奇在 Unsplash 上的照片

OpenCV 逐渐成为最好的计算机视觉库之一。它开始于在 OpenCV 3.3 版本中添加 DNN 模块,现在它的大多数更新都是关于复杂模块的,比如最近在 OpenCV 4.4 中添加的 YOLOv4 和 EfficientDet 模块。现在,随着两个硬件模块即 OAK-1 和 OAK-D 的推出,它在行业中产生了进一步的影响,它们之间的区别是普通相机和立体相机。

我将从一个学生的角度写这篇文章,这是一篇观点文章。你可能会有不同的观点,所以请在评论中告诉我。那么值得买吗?为了找到答案,我们先来看看这款设备及其功能。

特性和功能

它由 OpenCV 和 Luxonis 联合创建,配备了人工智能芯片 Myriad-X,可以执行计算机视觉应用。它是完全开源的,拥有麻省理工学院许可的硬件。它支持 OpenVINO 支持的所有操作系统,因此它支持 Windows,Linux 和 Mac-OS 没有任何问题。这些设备将带有兼容 Python 和 OpenCV 的 OAK-API。人工智能处理是在硬件本身上完成的,这意味着它不会给它所连接的系统带来任何额外的负载,也不需要任何基于云的服务。这也意味着数据可以保持安全,因为它是在本地处理的。

正如在其 Kickstarter 页面上看到的那样,它可以用来检测和跟踪物体,执行分割,以 30FPS 的速度播放 4K 视频,还支持定制的神经网络。有了 OAK-D 套件,live depth 可以与被视为作弊代码的 AI 相结合,以改善结果。他们声称,它只需要 30 秒的设置和功能如下所示。

Kickstarter 页面上给出的完整功能列表

  1. 神经推理——对象检测、图像分类、语义分割等。
  2. Warp/Dewarp —支持鱼眼应用的附加镜头
  3. 对象跟踪—最多 20 个具有唯一 id 的对象
  4. Apriltags——结构化导航(April tag 是一种视觉基准系统,可用于多种任务,包括增强现实、机器人和摄像机校准)
  5. H.264 和 H.265 编码(HEVC、1080P 和 4K 视频)—4K 视频 3.125 MB/s,Pi Zero 可以用它录制 4K/30FPS 视频!
  6. 特征跟踪——光学和视觉惯性导航。
  7. JPEG 编码— 12MP 静止图像
  8. 运动估计—允许实时背景减除
  9. MJPEG 编码——用于简单的网络流等。
  10. 边缘检测哈里斯滤波。

OAK-1 的具体特征

  1. 基于运动的自动无损变焦:
  • 12 倍无损变焦,720p 输出
  • 6 倍无损变焦,1080 输出
  • 1.5 倍无损变焦,4K 输出

OAK-D 的特异功能

  1. 立体深度(包括中值滤波)—扩展的视差和亚像素可实现更宽的动态范围。
  2. 3D 对象定位-具有立体视差深度的单目人工智能和用于小对象/特征支持的立体人工智能(即立体神经推理)
  3. 3D 空间中的对象跟踪—实时 3D 轨迹,并支持以米为单位的运动统计。

摄像机规格

以下是两种 OAK 设备的摄像头规格。

橡木色摄像机规格:

  • 图像传感器:IMX378
  • 最大帧速率:60fps
  • H.265 帧速率:30fps
  • 分辨率:12 百万像素(4056 x 3040 像素)
  • 视野:DFOV 81°—HFOV 68.8°
  • 镜头尺寸:1/2.3 英寸
  • 自动对焦:8 厘米
  • 光圈数:2.0

OAK-D 立体摄像机规格:

  • 同步全局快门
  • 图像传感器:OV9282
  • 最大帧速率:120fps
  • 像素大小:3um x 3um
  • 分辨率:1280 x 800 像素
  • 视野:DFOV 81°—HFOV 71.8°
  • 镜头尺寸:1/2.3 英寸
  • 焦距(固定):19.6 厘米— ∞
  • 光圈数:2.2

Kickstarter 活动带来的其他好处

Kickstarter 受益于承诺的总金额

他们能够在活动开始的前 20 分钟内达到目标!在编写本报告时,还有 18 天时间,已经筹集到 544,058 美元。因此,即使 Kickstarter 现在结束,支持者也会获得一门免费课程,教他们如何使用这些设备。除此之外,OAK-D 设备还将配备惯性测量单元(IMU)传感器,通过使用加速度计和陀螺仪以及通常的磁力计来测量和报告方向、速度和重力。

所以直到现在,我只是谈论了这些设备的一般功能,在这些基础上,我觉得围绕这些模块的宣传是完全合理的。学生可能会觉得 OAK-1 和 OAK-D 的 100 美元和 150 美元的价格有点高,但这个价格现在是 50%的折扣,在 Kickstarter 于 8 月 13 日结束后,价格将会翻倍。此外,没有其他类似的硬件模块可用,从单独的组件组装一个意味着更庞大和昂贵的解决方案。正如 PyImageSearch 上的这篇文章所指出的,更多关于使用它的文章即将到来,所以使用它的难度不会成为问题。

这些以人工智能为动力的空间套件为学生和研究人员提供了执行现实世界项目的机会,而不是只处理可用的数据库,并报告测试精度,但从未看到它在现实世界中工作。这些相机提供了在生产环境中测试模型的途径,而不需要任何其他外部硬件。

所以,总之,我觉得如果一个人是一个有抱负的计算机视觉学生,这当然是值得的。很多开发将会在它上面发生,它可能会像 Raspberry Pi 为业余硬件爱好者所做的那样为计算机视觉做些什么。

观点:我们应该对冠状病毒有多担心?

原文:https://towardsdatascience.com/opinion-how-worried-should-we-be-of-the-coronavirus-71bc987453c8?source=collection_archive---------9-----------------------

关于小说《新冠肺炎》的数据驱动观点

照片由葡萄牙重力Unsplash 上拍摄

免责声明: 本文使用的原始数据是从约翰·霍普斯金怀汀工程学院的 Github 知识库 中检索的,这些数据是从诸如世卫组织、CDC 和其他卫生政府网站等值得注意的来源中提取的,我绝不是基于主观性来操纵它们的数字。数据是从 2020 年 1 月 22 日至 2020 年 3 月 11 日收集的,必须记住,随着时间的推移,这些数字将继续变化。

此外,我做出的许多推论包含我自己的观点,可能有偏见。每个人都应该有权发表自己的意见,如果你需要额外的信息来源,你应该经常与外部参考进行交叉核对。

利用数字传播恐惧

在写这篇文章的时候,冠状病毒(新冠肺炎)已经席卷全球。大多数媒体所描绘的似乎是致命的疾病,在许多公民和网民中有着非法的恐惧和非理性。

一个普通的新闻媒体利用恐惧来获得点击量(来源: CCN

来源:太阳

在这一点上,冠状病毒不仅仅是一种流行病,它也是一种数字游戏。全球新闻媒体正在等待这些数字达到一个里程碑,并用引人注目的标题来增添趣味,这样人们就会点击并阅读他们的文章。因为更多的读者给了他们更多的收入,对吗?

这并不是说这些媒体应该立即被指控为假新闻。相反,大多数记者都受过报道事实的训练,但这并不意味着他们不能在文章中加入一点感情色彩。

以上述头条为例。对他们来说,10 万个案例是一个值得报道和吸引读者注意力的里程碑。接下来的这些文章可能只是最高的这个和最高的那个的附加数字。

“……从那里,病毒像野火一样蔓延,在中国肆虐,1 月 11 日出现了第一例死亡。

自从病毒在全球爆发以来,已经有 3383 人死于这种致命病毒。

这是因为世界各地的政府都害怕一个全球性的疫情…”(The Sun UK

好吧,那康复案例呢?

有,但是被举报的可能性要小得多。许多记者利用了一种被称为 厌恶损失 的常见心理现象。他们知道大多数人对负面新闻更敏感,这可能会导致更高的点击率。

“……厌恶的反应反映了负面情绪(焦虑和恐惧)对损失的关键作用(Rick,2011)。换句话说,厌恶损失是恐惧的一种表现。这解释了为什么我们倾向于关注挫折而不是进步。负面情绪,比如受到批评,比正面情绪,比如受到表扬,有更强的影响……”(今日心理学)

恐惧对健康的影响

我不会深究恐惧的方方面面。否则,我可能会偏离本文的主题。然而,我想谈谈恐惧对健康的影响,特别是对我们免疫系统的影响,因为这是我们接触病毒后抵御病毒的唯一方法。

我们知道有很多人因为冠状病毒而生活在恐惧中。不,我说的不是那种战斗或逃跑反应的恐惧。我说的是日常生活中的压力或由于潜在暴露于冠状病毒而产生的恐惧。下面是苏珊·C 和格雷戈里·E 进行的一项科学研究的摘录:

“具有人类进化祖先面临的战斗或逃跑情况的时间参数的紧张性刺激引发了免疫系统的潜在有益变化。然而,压力越是偏离这些参数,变得越是慢性,免疫系统就有越多的成分受到潜在的有害影响。"(苏珊娜 C 和格雷戈里 E )

现在我们都知道,任何类型的流感都无法治愈,只有疫苗作为预防普通流感的一种形式。击退病毒的唯一方法是确保你的免疫系统在对抗病毒时是有效的,同时很少得到缓解症状药物的帮助。

我们中的许多人也知道,佩戴外科口罩很少或根本不能防止感染病毒,尽管它们确实有助于防止病毒的传播。

然而,总会有一群人打安全牌,在外出和处理日常事务时佩戴安全牌。如果恐惧是他们选择的主要原因,我会说虚假的安全感仍然比生活在恐惧中要好,知道持续的压力会抑制我们的免疫系统。

不服气?看看这段视频,从迈克医生的角度看媒体对冠状病毒的看法:

使用原始数据作为可靠的信息来源

我写这篇文章的目的和 Mike 博士一样:通过展示许多媒体来源很少报道的数据的某些方面来教育和减轻我的读者朋友们的恐惧

为此,我求助于由约翰·霍普斯金·怀汀工程学院在其 Github 知识库中发布的公开数据集。

[## CSSEGISandData/新冠肺炎

这是由约翰·霍普金斯大学运营的 2019 年新型冠状病毒视觉仪表板的数据存储库…

github.com](https://github.com/CSSEGISandData/COVID-19)

这并不是说他们提供了 100%准确的数据,只是因为他们整理了全球政府卫生网站和当地媒体的所有数据。由于在早期阶段无症状,感染病毒的未报告病例必然会发生。由于缺乏症状,一些医生甚至不检查他们的病人。

[## 观点|一周三次急诊,了解我是否有冠状病毒

以为我有症状,我看到了令人不安的纽约市混乱和自相矛盾的方法…

www.nytimes.com](https://www.nytimes.com/2020/03/09/opinion/coronavirus-testing-new-york.html)

对这个问题的量化风险有基本的了解

对于这篇文章的标题,可能有人有自己的答案。对一些人来说,只要病毒存在,不管有多少人被感染,只要他们走出家门,就被认为是有风险的。就我个人而言,我将其分为 3 个不同的类别,以评估感染病毒的风险和疾病的严重程度:

  1. 案件总数
  2. 当地病例数
  3. 个人年龄范围

1.案件总数

确诊病例将永远是新闻媒体喜欢挑剔的目标数字,因为它们只会不断增加。但是什么是确诊病例呢?确诊病例是记录在案并用于追踪接触者的报告病例。这个数字包括康复和死亡病例。

“X 人冠状病毒痊愈出院”,说几乎没有标题过。

“X 确诊病例和 Y 死亡病例来自冠状病毒”,表示一些 clickbait 标题。

甚至在谷歌上搜索冠状病毒恢复案例也没有帮助:

通过一些清理和处理,将原始数据插入 Python,我们可以直观地看到确诊病例的数量。这是大多数媒体喜欢放在标题中的数字:

从确诊病例中减去康复病例和死亡病例后,我们得到下图:

从这张图表中,我们可以看到中国城市中现有病例的数量正在减少。

这是否意味着中国比世界其他地方做得更好?

不一定对。请记住,这种病毒源自中国,在它传播到全球之前,感染很早就在中国开始并传播。自 1 月份以来,现有病例的指数式增长与世界其他地区 2 月中旬现有病例的指数式增长是同义的。虽然中国的许多人由于早期接触病毒已经康复,但世界其他地区的许多人仍然在指定的医疗保健区受到监护或隔离。

那么,为什么病例总数被认为是一种风险呢?因为旅行还没有完全被限制。不管是空运、陆运还是海运。一个无症状的携带者可能会不知不觉地侵入一个地区,并在当地开始传播。

2.当地病例数

并非世界上每个国家都受到冠状病毒的困扰。如果你玩过瘟疫公司,一个流行病模拟器游戏,玩家知道选择格陵兰岛作为爆发的开始,由于其相对较低的人口和人口密度,就像在硬核模式下玩一样。巧合的是,截至 2020 年 3 月 11 日撰写本文时,格陵兰尚未报告任何冠状病毒病例。

当考虑感染该病毒的风险时,你应该考虑贵国现有病例与当前人口的比例。

让我们以新加坡为例,因为它是最早遭受冠状病毒袭击的国家之一,并且在 2020 年 2 月初保持着最高确诊病例数的第二名位置:

从 2 月中旬到 3 月初,失业率似乎在稳步下降,这是因为一些人即使生病也继续参加社交活动和上班。

麦国强卫生部医疗服务主任周二表示,接触者追踪目前在控制病毒爆发方面仍有作用,即使存在广泛的社区感染,它也将继续“有意义”。

这是因为受感染的个人继续从事社会活动和工作的放大效应,导致进一步的暴露和感染。”——(海峡时报

但是让我们把注意力放在数字上。截至撰写本文时,现有 82 例感染患者全部处于隔离状态。总会有感染者四处游荡,但我们不知道具体数字。

虽然我不知道有多少未被发现的病例,但新加坡是一个今天拥有超过 580 万人口的国家,这使得感染这种病毒的可能性极低。

就我个人而言,我把现有的病例作为我在日常通勤中被感染的可能性的衡量标准。由于现有病例数量每天都在数十例上下波动,这感觉就像是中了彩票才能接触到这种疾病。

考虑到这一点,我只需要保持警惕,但我并不焦虑。

3.个人年龄范围

孙开元等人 完成的一项早期流行病学研究在受感染个体中建立了年龄和死亡之间的相关性。

来源:开元孙等人。艾尔

这加强了我之前的观点,即个人的免疫系统对他们自己的康复负有主要责任。Beata Berent-Maoz 等人在下面的研究中描述了随着年龄增长免疫力下降的相关性。艾尔:

[## 免疫系统老化的原因、后果和逆转

衰老对免疫系统的影响表现在多个层面,包括 B 细胞和 T 细胞的减少。

www.ncbi.nlm.nih.gov](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3582124/)

由于年轻人通常具有较高的免疫力和较低的死亡率,他们不必太担心死亡,即使他们不可避免地会感染病毒。正确饮食,保持身体健康和水分充足是增强对冠状病毒免疫力的最常见方法之一。

流行病学背后的数学

任何人都很容易认为,随着病毒在人与人之间传播,它将遵循指数曲线。一开始是这样,如果各个国家的预防措施不到位,这种情况肯定会加剧。但在某些时候,我们需要明白,正如逻辑增长曲线所示,利差最终会放缓。这里有一段视频,清楚地解释了这种流行病学背后的数学原理:

回到问题:你应该有多担心?

我们已经够害怕这个世界了。事实证明,传播恐惧和非理性比冠状病毒本身要快得多。

从恐慌性抢购甚至 争抢卫生纸 、短期股市崩盘以及健康时因恐惧而戴上外科口罩,我们开始看到人性阴暗面的表面。

基于您的地理位置,您应该能够粗略地评估实际感染病毒的可能性。如果你住在一个发病率很高的地方,尽你所能,远离人群密集的地方,努力保持个人卫生。这尤其适用于已经存在健康问题的人,如果你感染了病毒,这些问题肯定会加剧。

在我看来,保持身体健康和采取预防措施远比担心感染病毒更重要。阅读最有可能引发额外恐惧的新闻可能会导致恐慌和错误的决定。你能做的最糟糕的事情就是开始在社交媒体上传播假新闻和错误信息。

尽你的责任,保持安全,保持警惕,不要惊慌!

如果您需要冠状病毒情况的额外可视化,这里有一个仪表板的链接,该仪表板利用原始数据为桌面用户提供连续的实时更新:

[## 约翰霍普金斯冠状病毒资源中心

约翰霍普金斯大学全球公共卫生、传染病和应急准备方面的专家一直在…

coronavirus.jhu.edu](https://coronavirus.jhu.edu/map.html)

以下链接适用于移动用户:

[## ArcGIS 的操作仪表板

编辑描述

arcgis.com](https://arcgis.com/apps/opsdashboard/index.html#/85320e2ea5424dfaaa75ae62e5c06e61)

用于创建简单图表的代码可以在我的 Github 这里 找到。

如果你喜欢这篇文章,可以考虑通过下面的链接在我的个人网站上看看我的其他作品:

[## 鲍比·马尔乔诺

数据分析师

www.bobbymuljono.com](https://www.bobbymuljono.com/)

基于 VADER 和 gensim 的潜在狄利克雷分配法的 Twitter 意见挖掘

原文:https://towardsdatascience.com/opinion-mining-in-twitter-using-vader-and-gensims-latent-dirichlect-allocation-lda-a834c2a936?source=collection_archive---------37-----------------------

Viktor Forgacs 在 Unsplash 上拍摄的照片

人们如何在网上对新冠肺炎做出反应,他们在社交网络中的互动告诉我们他们对该病毒及其威胁的立场是什么?

这很重要,因为…

想象一下,在全球疫情期间,你是一名卫生政策决策者。你不想知道人们对这个问题的看法吗?

数据

我再次转向 Twitter 寻求答案。原始材料无缝地流入我的数据库,我看到自己拥有来自世界各地的 100 万条推文,都包含通用词,如“冠状病毒”和“新冠肺炎”,包括它们的每一个可能的版本。

为了掌握网络的内部结构,我用 Gephi 绘制了数据。选择的算法是 OpenOrd ,这是在大型网络中可视化底层子社区的理想算法。我能够识别出至少 15 个社区,其中两个最大的社区几乎占了现有节点的 25%。总而言之,该网络看起来像一个巨大的、彩色的斑点,最大的社区由大约 70k 个节点组成,因此被选来进行分析。去朱庇特!

笔记本,。gephi 文件,而数据集都在我的github repo上。

方法学

我的目标是在第一个社区的推文文本中进行意见挖掘,这样我就可以从总体上评估该社区对疫情冠状病毒主题的感受和互动。幸运的是,这 72k 条推文中的自然交流语言是英语。

经过大量研究,我决定使用 VADER (效价感知词典和情感推理器)情感强度分析器(在 NLTK 中实现),这是一种情感感知词典方法,用于分析社交媒体文本中的情感。它建立在现有的词汇基础上,但被社交媒体中存在的丰富因素所丰富,如表情符号、大写字母(通常用于表示强调)和缩写(omg!),等等。

VADER 的 SIA 的结果是一个指标及其相应分数的字典,拆分成一个数据框后看起来像这样。

推文及其 VADER 情感评分。

前三个分数与落入每个类别的单词的比例相关,因此总计为 1。它们对于多维情感分析很有用。“复合”度量是对词典中的所有词价分数计算的加权和归一化的综合分数。这是最有用的一维情绪得分,就像我现在感兴趣的那个。根据 VADER 的文档,小于-0.05 的复合分数是负的,大于 0.05 是正的,中间的范围是中性的,这意味着-11 的值分别对应于极度负面和极度正面的情绪分类。

在对推文进行了意见挖掘之后,我接着进行了 NLP 分析,特别是识别人们在谈论什么。我决定执行潜在狄利克雷分配(Latent Dirichlet Allocation)或 LDA,这是一种生成概率机器学习技术,它允许我们将观察结果(文档中的单词)建模为潜在概率分布(主题)的未观察集合的可能表示。换句话说,LDA 获取文档中的单词,并计算潜在的主题分布,这些主题分布很可能是观察到的文本(在这种情况下是我们的推文)中讨论的主题的来源。

我的 LDA 实现很大程度上受到了 Susan Li 的文章的启发,并依赖于 NLTK 的预处理工具箱和 gensim 的开源 LDA 语义建模方法。

分析的预处理部分包括移除 URL、标记化、停用词(最常见的词)移除、词干化和词条化,所有这些都是为了尽可能地从词汇和句法上减少推文。看看这个经过处理的推文及其原始表示的例子:

已处理的推文。

原创推文。

然后,我创建了一个术语字典,以及它们在推文中的相应频率,之后,我挑出最常见的,出现在至少一半推文中的,以及最罕见的,出现在不到 50 条推文中的,以获得包含最频繁的 10 万个术语的最终字典。然后,通过 gensim 的 doc2bow 方法将结果转化为语料库,稍后将该语料库传递给 TF-IDF 训练的模型,以获得整个语料库中每个术语的权重。术语频率-逆文档频率(TF-IDF)是一种计算每个术语相对于语料库的权重的模型,因此当术语出现在文档中时,权重增加,但当语料库中的其他文档也以该术语为特征时,权重减少。在实践中,最常用的单词权重会降低,从而生成更加规范化的语料库。

现在,LDA 模型已经准备好接受训练,返回十个不同的潜在主题,这些主题最终被认为是推文的主题。返回的主题如下:

LDA 确定的 10 个主题。

从确定的可能主题列表中,我们可以很好地掌握每个主题的内容。例如,主题 0 可能涉及种族主义和仇恨的各个方面,可能是在仇外心理和民族主义的框架内,同时又害怕病毒。或者主题 2,最有可能是关于测试套件的讨论;或者关于医务人员和急救人员的主题 4。你明白了。

准备好主题列表后,我可以计算每条推文中最有可能的主题的比例,显示最有可能来自该主题的单词的比例。举个例子,让我们看看上面的推文:

推文的主题和概率得分。该推文很可能属于主题 0。

最后,我根据 VADER 的综合得分(负的 0.05,中性的>-0.05 和< 0.05),将社区划分为包含消极、中性和积极情绪的推文。

调查的结果

结果分为三类。首先,那些对新冠肺炎持“负面”看法的人。该群组包括 33000 多条推文,最常见的主题是主题 3 (14%)、主题 9 (13%)、主题 5 (12%)和主题 8 (12%)。

负面推特主要是关于什么的。

作为复习,主题 3 涉及诸如人、小说、捐赠、保护、王牌、关闭、学校、帮助、covid 和国家等术语。这里的推特用户可能在请求总统的帮助和更精确的政策来保护人们免受病毒的侵害,例如关闭学校。

主题 9 包含术语 covid、病毒、trump、健康、月份、呼叫、阀门、声明、包含和类型。

主题 5 包含测试、费率、装运、柏林、开始、处理、创建、最低、产品和编号。可能是指在传染率和治疗需求不断上升的情况下,迫切需要获得快速检测方法。

主题 8 涉及诸如英国、策略、死亡、结果、政府、日、百、现实主义者、基地和千等术语。

“正面”推文的主题。

现在,“积极的”推特用户数量减少了,大约有 2.9 万条。最常出现的主题是主题 3 和 1,共占 34%。

和以前一样,主题 3 涉及的术语有:人、小说、捐赠、保护、王牌、关闭、学校、帮助、covid 和国家。也许在这种情况下,推文不是批评政府的立场,而是捍卫它(可能是为了不使国家经济不必要地放缓)。

主题 1 包含天才、告诉、担忧、气候变化、记忆、社会、关怀、沙漠和热带雨林等术语。这里的推文很可能暗示了气候变化中经济放缓的积极结果,或者通过记住关心他人来呼吁更多的社会责任。

中性推特的话题。

最后,更多的“中性”推文占所有推文的 9800 条,主要涉及主题 9 (18%)、8 (15%)和 2 (13%)。

主题 9 包含术语 covid、病毒、trump、健康、月份、呼叫、阀门、声明、包含和类型;主题 8 涉及诸如英国、策略、死亡、结果、政府、日、百、现实主义者、基地和千等术语;主题 2 涉及 covid、测试、同意、思考、帮助、工具包、病毒、访问、屁眼和症状。

这里的主题解释有些困难,因为我们没有它们应该有的可能的“方向”或意义(消极或积极),所以我将让你来辨别。

结论

毕竟,这有什么关系?

想象一下,在全球疫情期间,你是一名卫生政策制定者。你不想知道人们对这个问题的看法吗?

如果你试图让人们呆在家里来拉平曲线,你可能不需要在那些已经同意你的观点并敦促他们的社区帮忙和呆在家里的人身上浪费沟通资源。相反,如果你能直接瞄准那些否认手头问题严重性的代理人(想想一些带有“负面”观点的推文),或者还没有决定怎么想的代理人,你很可能在危机时刻更有效率。

后者是最重要的群体,因为想一想:仅仅通过了解他们对问题的看法和他们的感受,说服这 10,000 名男性和女性支持讨论的任何一方有多容易?犹豫不决的人可能只差一个广告就要采取额外的步骤去关心(或决定不关心)。

限制和结尾

  • 这种解决方案的真正力量是建立一个数据管道,允许推文直接进入处理和分类。人们的观点突变几乎和病毒本身一样快。
  • 此分析旨在作为概念的简单证明。在同一个数据集中,有 20 多个社区准备好在全球范围内进行分析,尽管实现需要语言检测和多功能多语言 NLP 库。
  • 确定情感极性得分的更精确的方法是实现所谓的基于方面的情感分析(或基于方面的意见挖掘),就像这个由 Peter Min 完成的漂亮的实现。然而,请注意,这将是一个监督学习模型,需要关于感兴趣主题的多标签注释数据集(类似于 Peter 的餐馆评论)。
  • 已经采取了这样的方法,并且结果是有趣的。看看最近寨卡疫情前后的这个情绪检测实施
  • 从 LDA 模型的输出中解释什么主题是非常困难的,有时甚至是任意的。我绝不试图根据模型的输出对推文的内容做出明确的断言:我只是指出概率和比例,并试图给出合理的解释。

使用 Python 的不到 10 行代码的光学字符识别(OCR)

原文:https://towardsdatascience.com/optical-character-recognition-ocr-with-less-than-12-lines-of-code-using-python-48404218cccb?source=collection_archive---------3-----------------------

使用 pytesseract 将图像中的文本转换为可编辑的数据

资料来源:Gerd Altmann (pixabay)

假设您有一个文档,想要提取它的文本,而不是自己键入整个内容。

本文中的几行代码将会加快这个过程,并真正节省时间。

必须考虑的一些事情是你有什么样的文件或图像,它的质量如何,以及书面内容是手写的还是计算机字体。(显然,计算机字体比手写文本更有可能达到更高的准确度。)

以下几点也可能影响精度:

  • 字体太小或者文本通常只占图像的一小部分
  • 图像尺寸太小(没有足够的像素来很好地检测字体)
  • 图像的光线质量不好
  • 字体不能很好地与背景分开
  • 字体或文档歪斜或扭曲

输入图像。

你需要的只是几个安装,你的文件和你就可以走了。让我们看看我们需要导入什么(确保您之前安装了 pip):

import cv2import pytesseractimport numpy as np

想看更多这样的故事?每月仅需 4.16 美元。

开始使用

安装后,我们需要使用 openCV 加载映像,openCV 安装在 cv2 下。如果该图像不是仅由黑白像素组成的图像,则需要将其转换为二进制图像(对于二进制图像,您可以跳过存储在 gray 变量中的两行代码)。首先对二进制图像进行灰度化,然后执行算术运算,在这种情况下就是按位非运算。灰度转换采用图像的三个 RGB 值,并使用以下公式进行转换

转换为代表灰色阴影的单个值。每个像素的值在 0 到 255 的范围内,255 是最亮的灰色(白色),0 是最暗的灰色(黑色)。之后,阈值处理用于决定像素值是低于还是高于某个阈值。下面的所有像素都变成白色像素,上面的所有像素都变成黑色像素,结果是一个二进制图像。由于二值图像具有白色背景和黑色前景,即字母或符号,因此需要反转图像。这是通过逐位非运算完成的。每一个为 1 并因此为白色的像素被转变为黑色像素,每一个为 0 并因此为黑色的像素被转变为白色像素。

阅读更多关于灰度、RGB 和数字图像处理的信息点击这里

img = cv2.imread('/Users/marius/Desktop/jimdoo.png')**#Alternatively: can be skipped if you have a Blackwhite image** gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
gray, img_bin = cv2.threshold(gray,128,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)
gray = cv2.bitwise_not(img_bin)

然后我们需要做一些形态学操作来去除字符周围的噪声。我们使用的两种运算是腐蚀和膨胀。首先,我们定义一个 2×1 像素的内核,它滑过图像并执行操作。腐蚀用于检测内核是包含白色前景像素还是黑色背景像素。如果内核填充有白色像素,则原始图像中的像素将被视为 1,因此是白色的。如果内核包含黑色像素,原始像素将被视为黑色。因此,白线被侵蚀。侵蚀的形态学对应部分是扩张。如果内核下的至少一个像素是白色的,则原始图像的预期像素将被视为白色。因此,白色区域被扩大。在图像预处理中,腐蚀和膨胀经常以所提出的顺序结合起来以去除噪声。

kernel = np.ones((2, 1), np.uint8)img = cv2.erode(gray, kernel, iterations=1)img = cv2.dilate(img, kernel, iterations=1)out_below = pytesseract.image_to_string(img)print("OUTPUT:", out_below)

结果是下面的文本。请注意,宇宙魔方有几个检测选项,包括不同的语言。所以如果你想把它换成一种不同于英语的语言,你必须对它稍作调整。

输出的图像。

感谢您的阅读,希望您对 OCR 有所了解!
我感谢反馈。

另请阅读了解数字图像处理和计算机视觉的基础知识。

[## 请继续关注马里乌斯·哈克的新文章

请继续关注 Marius Hucker 的新文章。如果您还没有注册,您将创建一个中型帐户…

medium.com](https://medium.com/subscribe/@hucker.marius)

光学音乐识别:现状和主要挑战

原文:https://towardsdatascience.com/optical-music-recognition-state-of-the-art-and-major-challenges-aa100923c78d?source=collection_archive---------67-----------------------

关于 OMR 的综述文件——范式转变和可能的方向。

最近,我的第一篇论文被 2020 年国际音乐符号和表现技术会议(男高音)接受。出版的旅程是非常有见地的,它将成为我未来出版的指南。

https://arxiv.org/abs/2006.07885

本文总结了以前的工作,并对我的研究课题——光学音乐识别(OMR)领域的进展作了定位。你可以在我的上一篇文章中读到更多关于 OMR 的内容。在我的学术旅程开始时,我听到了发表立场文件的利弊。然而,写这篇论文让我怀疑自己,这总是导致学习更多。

回到论文的实际内容,我试着总结了 OMR 管道的四个主要阶段,在每个阶段发表了各种作品。此外,我试图捕捉 OMR 使用的方法从传统的计算机视觉系统到端到端深度学习网络的范式转变。

整体 OMR 传统管道[13]

最初,OMR 的四个阶段包括图像预处理、音乐对象检测、音乐符号重建以及最终将音乐知识编码到机器可读文件中。在图像预处理阶段,主要应用了增强、去歪斜、模糊、噪声去除和二值化[1,2,3,4,5]。二值化是将图像转换为二值(只有黑白像素)的过程。最初,使用传统技术执行这种处理,例如基于图像的全局直方图选择二值化阈值。例如,稍后使用分段自动编码器完成二值化[6,7]。这些编码器学习二进制化的端到端转换。

转到音乐符号检测,这个阶段有三个子阶段:五线谱处理、音乐符号处理和最后的分类。在五线谱处理中,首先检测五线谱线,然后根据病历报告将其删除。最近,Pacha 等人使用对象检测技术证明,删除五线谱并不能保证更好的性能[8]。

音乐对象检测阶段在很大程度上受益于计算机视觉的最新发展,特别是受益于一般的对象检测。诸如快速 R-CNN、更快 R-CNN、单次检测器(SSD)之类的模型被用于检测音乐对象。他们使用预先训练好的模型,然后在手写乐谱数据集 MUSCIMA++中进行微调[9]。这项工作为在乐谱中使用深度学习进行对象检测绘制了基线。

最复杂的阶段之一是重建音乐符号之间的结构和语义关系。这一步通常使用音乐知识、规则和启发法来完成[10,12]。最近这个阶段也接触了深度学习方法和端到端学习[11]。然而,这里的一个主要问题是找到能够捕捉音乐中结构和语义关系的表达。这是因为音乐具有非常复杂的结构,符号具有空间关系和长期依赖性。这些关系构成了音乐的结构,它们的语义就是音乐本身。因此,找到一种嵌入所有这些信息的表示是非常具有挑战性的。

最终,目标是将所有检索到的关系编码到一个机器可读的文件中。这种格式有很多种。虽然有些格式对乐器、音高、力度和开始部分进行了编码,但这些只能促进可回放性。其他格式可以编码更多的信息,这不仅有助于可再现性,而且有助于近似符号在纸上的外观。

OMR 走向端到端学习[13]

总而言之,OMR 目前面临的主要挑战是缺乏更大的标记数据集、音乐对象和五线谱检测、语义重建,以及缺乏标准化、评估指标和输出表示[13]。

在这里阅读更多:https://arxiv.org/abs/2006.07885

参考

  1. I. Fujinaga,“使用投影的光学音乐识别”,博士论文,加拿大蒙特利尔麦吉尔大学,1988 年。
  2. B.Couasnon,P. Brisset,I. Stephan 和 C. P. Brisset,“使用逻辑编程语言进行光学音乐识别”,第三届 Prolog 实际应用国际会议论文集。Citeseer,1995 年。
  3. A.Fornes,J. Llados,G. Sanchez 和 H. Bunke,“旧手写乐谱中的作者识别”,2008 年第八届 IAPR 国际文档分析系统研讨会。IEEE,2008 年,第 347–353 页。
  4. A.Fornes,J. Llados,G. Sanchez 和 H. Bunke,“在旧手写乐谱中使用纹理特征进行作者识别”,2009 年第十届国际文档分析和识别会议。西班牙巴塞罗那:IEEE,2009 年,第 996-1000 页。【在线】。可用:http://IEEE explore . IEEE .org/document/5277541/
  5. 长度 J. Tardon、S. Sammartino、I. Barbancho、V. Gomez 和 A. Oliver,“用白色音符书写的乐谱的光学音乐识别”, EURASIP 图像和视频处理杂志,2009 年第 1 卷,第 843401 页,2009 年。
  6. A.-J. Gallego 和 J. Calvo-Zaragoza,“使用选择式自动编码器去除五线谱”,专家系统及应用,第 89 卷,第 138–148 页,2017 年。
  7. J.Calvo-Zaragoza 和 A.-J. Gallego,“一种用于文档图像二值化的选择性自动编码器方法”,模式识别,第 86 卷,第 37–47 页,2018。
  8. A.Pacha,K.-Y. Choi,B. Couasnon,Y. Ricquebourg,R. Zanibbi 和 H. Eidenberger,“手写音乐对象检测:公开问题和基线结果”,载于 2018 年第 13 届 IAPR 国际文档分析系统研讨会。维也纳:IEEE,2018 年 4 月,第 163–168 页。【在线】。可用:https://IEEE explore . IEEE . org/document/8395189/
  9. Haji、Jan 和 Pavel Pecina。"用于手写光学音乐识别的 MUSCIMA++数据集." 2017 第十四届 IAPR 国际文档分析会议
  10. 页(page 的缩写)d、结构化文档图像分析中的“标准刻写乐谱的计算机模式识别”。施普林格,1992 年,第 405-434 页。
  11. A.Pacha,J. Calvo-Zaragoza,J. Hajic jr,“用于全流水线光学音乐识别的学习记谱法图构造”,载于2019 年第 20 届国际音乐信息检索学会会议
  12. D.Bainbridge 和 T. C. Bell,“用于光学音乐识别的音乐符号构建引擎”, Softw。,Pract。Exper。,第 33 卷,第 173-200 页,2003 年。
  13. E.Shatri 和 G. Fazekas,“光学音乐识别:技术现状和主要挑战”,arXiv 预印本 arXiv:2006.07885 ,2020 年

使用 Bigtable 优化性能:使用 Apache Beam 更改表的键

原文:https://towardsdatascience.com/optimal-performance-with-bigtable-changing-the-key-of-your-table-with-apache-beam-9139542a445e?source=collection_archive---------39-----------------------

克里斯蒂安·恩格梅尔在 Unsplash 上拍摄的照片

Cloud Bigtable 是一个高性能的分布式 NoSQL 数据库,可以存储数 Pb 的数据,并以低于 10 毫秒的延迟响应查询。然而,为了达到这一性能水平,为您的表选择正确的键非常重要。此外,您能够进行的查询类型取决于您为表选择的键。

Bigtable 附带了 Key Visualizer 工具,用于诊断我们的键是如何执行的。为了开始产生结果,Key Visualizer 至少需要 30 GB 的数据和一些工作负载。您拥有的数据越多越好,因为结果会越接近您在生产环境中部署时的结果。

所以当你在 Bigtable 中存储了很多数据之后,如果你发现你的键性能不好怎么办?如何更新密钥?需要再从头开始吗?

不,您可以使用 Apache Beam 管道来更新密钥。

在这篇文章中,我们描述了如何使用 Apache Beam 管道来更改表的键,只需编写几行代码来定义新的键。我们将使用演示数据在本地运行所有内容(Apache Beam 使用 DirectRunner,Bigtable 使用模拟器),因此没有必要为了跟进这篇文章而使用 Google Cloud 项目。但是你需要安装Google Cloud SDK

对于有大量数据的真实情况,建议在数据流中运行这个管道,但是对于演示来说,DirectRunner 就足够了。

Google Cloud 专业服务团队的 Github repo 中提供了管道:

[## Google cloud platform/professional-services/examples/bigtable-change-

更改 Bigtable 中表的键的数据流管道

github.com](https://github.com/GoogleCloudPlatform/professional-services/tree/master/examples/bigtable-change-key)

克隆 repo 并转到此管道的目录。您可以在本地或在云外壳中克隆回购。

git clone [https://github.com/GoogleCloudPlatform/professional-services](https://github.com/GoogleCloudPlatform/professional-services)cd professional-services/examples/bigtable-change-key

如果您已经有了一个 Bigtable 实例,可以转到下一节。在这里,我们将展示如何启动 Google Cloud SDK 附带的 Bigtable 模拟器,因此您不需要为 Bigtable 实例付费来试用这篇博客文章。

为了启动模拟器,我们在终端中运行以下命令:

gcloud beta emulators bigtable start

它通常会在端口 8086 启动一个服务器。但是不要担心这些细节,因为我们稍后将使用gcloud实用程序来设置它们。

现在,在不同的 shell 会话中(例如,新的终端窗口或新的终端标签),我们将设置一些环境变量来使用模拟器。我们将不得不使用该会话来运行管道,因此请确保在新的终端中继续运行命令。现在,通过运行以下命令来设置环境变量:

$(gcloud beta emulators bigtable env-init)

我们可以检查一下,现在有一些变量指向我们的本地 Bigtable 服务器:

echo $BIGTABLE_EMULATOR_HOST

您应该会看到类似于localhost:8086的输出

如果您得到一个空的输出,那么一定是出了问题(也许您不是在同一个 shell 会话中运行?).

我们现在需要配置cbt来使用这个模拟器作为 Bigtable 实例。为此,我们需要在~/.cbtrc处编辑文件,并设置以下内容(我们必须在管道配置中使用相同的项目实例名称):

project = my-fake-project
instance = my-fake-instance

现在您已经有了一个正在运行的 Bigtable 实例,让我们用数据填充它。为此,我们可以在管道中使用 Github 中包含的一个脚本。在管道的主目录中(在我们的 repo 克隆中),我们运行以下脚本,创建一个名为taxis的表:

./scripts/create_sandbox_table.sh taxis

现在我们可以检查表是否已经创建。记住,您需要配置cbt来访问您的实例。在上一节中,我们已经为 Bigtable 模拟器完成了这项工作。如果您跳过了前一部分,请检查如何配置 cbt

我们运行这个命令

cbt ls taxis

我们应该得到这样的输出

Family Name      GC Policy
-----------      ---------
id               <never>
loc              <never>

我们还可以通过运行以下命令来检查该表中有 3 行

cbt count taxis

Bigtable 模拟器将这些数据保存在内存中。也就是说,它是短暂的。如果停止模拟器,数据将会丢失。因此,您需要再次填充它才能使用它。不要在仿真器中存储任何有价值的数据,它不会被保存

现在我们在一个表中有了一些数据,我们可以编写代码来更改表的键。我们将对密钥做一个简单的更改:我们将反转它。对于自动递增的值,比如时间戳,这是一个常见的技巧来尝试改善表中数据的分布。有更多的考虑和可能的改变,但是对于这篇文章,我们将只做这些改变。

一般来说,要更改现有表的键,在我们的管道中,我们将使用以下两个元素来决定新键:当前(旧)键和完整记录(包含所有列)。

我们应该能够根据这些信息决定新的密钥。因为我们只是反转旧密钥,所以在本例中,我们将忽略该记录来生成新密钥。

为了实现这种密钥更改,我们需要更新管道的代码。你需要改变 [com.google.cloud.pso.pipeline.BigtableChangeKey](https://github.com/GoogleCloudPlatform/professional-services/blob/433da74fa5665dff9bb368133b46c384731eb0e2/examples/bigtable-change-key/src/main/java/com/google/cloud/pso/pipeline/BigtableChangeKey.java#L41-L50)中的 [transformKey](https://github.com/GoogleCloudPlatform/professional-services/blob/433da74fa5665dff9bb368133b46c384731eb0e2/examples/bigtable-change-key/src/main/java/com/google/cloud/pso/pipeline/BigtableChangeKey.java#L41-L50) 函数。代码如下面的代码片段所示:

函数来更新记录的键

该函数需要返回一个带有新密钥的String。输入参数是当前键(作为一个String),以及包含所有列的完整记录(作为一个Row)。记录的类型是Row,可以在 Google Bigtable 库中找到

如何恢复该记录中的列和所有数据?参见管道中的一个例子,它遍历记录以创建它的副本(这就是为什么它创建一个突变列表,在 Bigtable 的隐语中更改一行)。但是总的来说,只需遍历列族、列和单元格值,就可以恢复该记录中包含的所有元素(请记住,一个单元格可能有一个以上的单元格版本,这就是为什么会有多个单元格)。这段代码片段展示了如何遍历一个Row

显示如何在 Java 中遍历 Bigtable 行的代码片段

管道中包含的默认代码反转密钥,因此不需要实际做任何更改来反转它。但是请随意更改代码,尝试不同的密钥更新功能。请记住,每个记录的键应该是唯一的;具有相同键的记录将被管道覆盖。

现在我们已经编写了更新密钥的代码,让我们运行管道。在这个例子中,我们将使用 Apache Beam 的DirectRunner(而不是,例如,DataflowRunner),因为我们正在处理一个只有 3 条记录存储在 Bigtable 模拟器中的表。

在运行管道之前,我们必须确保目标表存在,并且它与我们从中复制的表具有相同的列族。为此,我们运行以下脚本。该脚本使用的是cbt,我们已经将其配置为指向我们的 Bigtable 实例。

./scripts/copy_schema_to_new_table.sh taxis taxis_newkey

这应该会生成一个额外的表。如果我们执行cbt ls,我们应该得到这个输出:

taxis
taxis_newkey

新表应该有两个柱族。cbt ls taxis_newkey的输出应该返回类似如下的内容:

Family    Name GC Policy
------    --------------
id        <never>
loc       <never>

我们可以检查一下桌子是不是空的。命令cbt count taxis_newkey应该返回 0。

现在,让我们编译并构建这个包。为此,我们跑

mvn package

构建应该成功,并在target/bigtable-change-key-bundled-0.1-snapshot . jar中创建一个包

我们现在可以使用本地运行器运行管道:

JAR_LOC=target/bigtable-change-key-bundled-0.1-SNAPSHOT.jar

INPUT_TABLE=taxis
OUTPUT_TABLE=taxis_newkey

RUNNER=DirectRunner

java -cp ${JAR_LOC} com.google.cloud.pso.pipeline.BigtableChangeKey \
        --runner=${RUNNER} \
        --project=my-fake-project \
        --bigtableInstance=my-fake-instance \
        --inputTable=${INPUT_TABLE} \
        --outputTable=${OUTPUT_TABLE}

运行管道后,我们可以检查命令cbt count taxis_newkey现在返回 3。让我们比较输入表taxis和输出表taxis_newkey中的元素。

如果我们执行cbt read taxis,我们将获得三条记录,为了简洁起见,我在这里只包括一条:

----------------------------------------
**33cb2a42-d9f5–4b64–9e8a-b5aa1d6e142f#132**
 **id:point_idx**                        @ 2020/05/31–01:35:26.865000
 “132”
 **id:ride_id**                          @ 2020/05/31–01:35:25.198000
 “33cb2a42-d9f5–4b64–9e8a-b5aa1d6e142f”
 **loc:latitude**                        @ 2020/05/31–01:35:28.591000
 “41.7854”

所以你可以看到,这个键实际上是由ride_idpoint_idx串联而成,由#分隔。

现在执行cbt read taxis_newkey并尝试找到具有相同ride_id和相同point_idx的记录:

----------------------------------------
**231#f241e6d1aa5b-a8e9–46b4–5f9d-24a2bc33**
 **id:point_idx**                          @ 2020/05/31–01:35:26.865000
 “132”
 **id:ride_id**                            @ 2020/05/31–01:35:25.198000
 “33cb2a42-d9f5–4b64–9e8a-b5aa1d6e142f”
 **loc:latitude**                          @ 2020/05/31–01:35:28.591000
 “41.7854”

你注意到什么了吗?该行的键现在是原始表中键的反转:33cb2....132是原始键,231....2bc33是新键。如果你检查其他记录,你会注意到钥匙被颠倒了。

现在回到transformKey函数的代码,尝试编写不同的键。使用相同的模式创建一个新的输出表,重新编译并再次运行本地管道,以查看代码的效果。

那么如果你需要改变一个有 GBs 或者 TBs 数据的表的键呢?数据流中运行此管道,创建一个副本表,但使用一个新的键。只是不要浪费云资源来检查新的 transform key 函数是否按预期工作。首先利用 Bigtable 模拟器和 Apache Beam Direct Runner 在本地运行管道,并确保在激发数据流中的数百个工人之前生成正确的密钥。

最佳样本量的确定

原文:https://towardsdatascience.com/optimal-sample-size-determination-43c5dca1f720?source=collection_archive---------30-----------------------

如何从统计上找到所需的样本量,以做出准确和高度可信的概括。(附实例!)

晨酿Unsplash 上拍摄的照片。

介绍

从收集选举中的投票意向到评估公司机器的质量,寻找最佳样本量在许多不同的情况下都很重要。找到最能代表总体的样本有助于减少成本和时间,同时还能提供适用于总体的结论。

帮助理解这一点的方法来自乔治·盖洛普,他是调查抽样技术的先驱。

“如果你煮了一大锅汤,你不需要把它都吃完,然后再看是否需要更多的调料。你可以尝一勺,只要你把它搅拌好”,乔治·盖洛普。

为了选择样本量,可以使用统计学方法。这可以让量化我们对样本的信心。

这篇文章将首先给出样本大小选择的数学证明,然后用 Python 做一个计算证明,展示如何在一些模拟数据上工作。

战略

本节将讨论如何在二元情况下找到最佳样本量——这是指有两种结果的情况。一个例子可以是带有“是”或“否”问题的投票,或者是对机器的好或坏的评级。

首先,这篇文章将讨论这个方法所基于的置信区间,然后最后讨论如何从置信区间计算最优样本量。

设置

在统计学中,样本是一组对象或测量值,是通过统计抽样技术获得的整个总体的子集。我们把二元问题的两个结果叫做结果 1结果 2

定义 p结果 1 发生的概率,给出结果 2 的概率为 1-p.

问题是,我们需要多大的样本量才能高精度地计算 p ?

置信区间

为了回答这个问题,我们需要一个 p. 的置信区间

定义:一个 p95% 置信区间是这样一个区间,如果我们计算区间 100 次其中 95 次将包含给定样本量 np 的真值。

对于一般情况,其公式为:

其中 p hat 是我们对 p 的估计值(我们试图寻找的值),z 表示正态分布的 z 得分(例如,1.96 表示 95%的 z 得分)。

最佳样本量

现在,为了计算最佳样本量,我们可以从另一个角度来看这个问题,并重新排列这个公式以找到 n。首先,让我们扩大置信区间:

因为我们想要找到高精度的 p ,我们将想要使这个置信区间小于某个宽度(你选择的),让我们称这个宽度为 W 。将这些放在一起,我们得到:

这给出了:

现在继续重新排列直到 n 在一边是T9:

这是一个通用公式,如果你已经对 p 有了一个很好的估计,就可以使用这个公式,但是如果没有的话,还可以通过一个假设进一步使用这个公式。让我们看看二项分布的方差公式:

为了编码我们的不确定性,我们可以最大化这个方差,在 n 保持不变的情况下,这是通过假设 p 值为 0.5 来实现的。这给了我们:

可以简化为:

现在,让我们输入一些值。对于 95%的置信水平,我们想设置 z = 1.96 (来自标准正态分布),让 W = 0.02W 是置信区间的宽度,这意味着 W/2误差幅度,因此在这个例子中,我的误差幅度为 0.01。

将所有这些放在一起:

对于这个例子,我们现在可以说,样本量大于 9604 的样本中,95%的样本将包含准确度在 1%以内的真实比例

例子

现在,数学证明已经完成,我将生成一些数据来给出一个动手的例子。

进一步阅读

结论

这篇文章介绍了一种在给定的置信水平和允许的误差范围内寻找好的样本量的方法,但是这里只讨论了二进制方法。为了将这里计算的结果扩展到多类场景(其中有两个以上的选项),该问题可以简单地视为几个二元问题。这就留给读者了。

有关相关的公式笔记本和示例笔记本,请访问我的 Github

基于 Google Colab 的最优停止算法

原文:https://towardsdatascience.com/optimal-stopping-algorithm-with-googles-colab-5b7f9f217e51?source=collection_archive---------40-----------------------

将众所周知的问题移植到最新的云计算服务中

图片来源:unsplash.com

谷歌的 Colab 是一个强大的工具,就像你们中的许多人已经习惯了谷歌驱动、文档、表格一样。你可以在远程机器上运行 python 代码,甚至可以访问 GPU/TPU。

最近我对 Brian Christian 和 Tom Griffiths 的书《赖以生存的算法》非常感兴趣,他们讨论了最优停止算法(也称为秘书问题)。网上有许多很好的资源(下面的链接)描述了这个问题,但这里有一个总结:

问题总结

假设你想从 N 个助手中雇佣一个助手。这些候选人是随机面试的,你必须在面试后马上做出决定——接受还是拒绝。一旦你拒绝了一个候选人,他们就不能被召回。

当然,在你面试他们的时候,你知道这个候选人有多好,并且能够将他们与之前的候选人(你拒绝了并且无法回忆起来的候选人)进行比较。困难是双重的——你无法回忆起过去的候选人,也不了解未来的候选人。你所能做的就是将你面前的候选人与过去的候选人进行比较。

你什么时候停下来接受一个候选人?

当你停下来的时候,你获得最佳候选人的概率是多少?

测试案例

让我们做几个测试案例。

N = 1(只有一名候选人申请。)

在这种情况下,你的最佳候选人也是你的最差候选人,所以你得到最佳候选人的概率是 100%(或 1.0)

N = 2(有两名候选人申请。)

这就像扔硬币一样。无论你停在第一个还是第二个候选人,你得到最佳候选人的概率是 50% (0.5)

N = 3(三名候选人申请。)

这是第一个必须应用策略的真实例子。排名候选人有 6 种不同的方式展示自己:

候选人可以展示的 6 种不同方式(1 =最好,3 =最差)

如果你停在第一个候选人,你得到最佳候选人的机会是 1/3(见最后两个排列)。

如果你停留在第二个候选人,并且只有在这个候选人比你面试的第一个候选人更好的情况下才选择候选人,那么你获得最佳候选人的几率是 3/6(见下图)。

在第一个候选者之后停止,如果这个候选者比第一个更好(否则继续)

如果你停在第三个候选人,你的选择是有限的,只有 2/6 的机会你得到最好的候选人。

假设你一直在寻找 N 个候选人,这是你最终应该收敛的(下面的代码将总结你应该选择多少,以及“得到最好的”的机会)

来自:亨利·张伯伦来源:comicsgrinder.com

Google Colab

我们可以用谷歌的 Colab 来表示这个算法:

首先导入所需的包并设置样式。我在这里使用了 seaborn-whitegrid。

设置申请人数并创建一个空数组:

循环多次重复(我在这里对每个 N 数重复了 10,000 次,并对结果取平均值)。通过更高的重复次数,您将获得更接近真实概率和最佳选择指数的数字:

最后,创造情节:

我鼓励你通读这些关于最优停止问题的参考资料,你会注意到这个概率收敛到 37%左右。

作者图片

请不要折磨自己试图复制上面的脚本,用我的:

谷歌 Colab 脚本

参考资料:

[1]希尔,T. 知道什么时候停止。(2009),美国科学家

[2]维基百科:最优停止访问时间:2020 年 10 月

[3]斯旺森,A. 根据《华盛顿邮报》math (2016)

最佳停止和 50 个高斯阴影

原文:https://towardsdatascience.com/optimal-stopping-and-50-shades-of-gauss-2ed031faf865?source=collection_archive---------39-----------------------

当我还是个孩子的时候,以色列电视上一个很受欢迎的节目是“谁想成为百万富翁”。对于那些不熟悉这种形式的人来说,参赛者会被问一些选择题形式的琐事问题(在希伯来语中,出于某种原因,这被称为“美国风格”)。如果他是正确的,他的试探性收益会翻倍,但是如果他没有回答正确,他将一无所获。在任何时候,他都可以退出,带着他所拥有的离开。这种直截了当的游戏形式中的主要戏剧是决策——以及对损失一大笔钱的不可避免的遗憾。通常 64k NIS 级别是真正的戏剧开始的地方。

你如何着手模拟这个决策过程,并建议参赛者何时退出?作为建模者,你需要考虑几个问题:

  • 这些问题是“公平的”(概率模型)还是“敌对的”,也就是说,在某些时候,产品会试图给你越来越难的问题,这些问题可能针对你的弱点?(然后,在初步问卷中,在你真正擅长的事情上表现很差可能是明智的)

在一个概率模型中,你会假设提升到下一个级别的指标函数来自一个 I . I . d .伯努利试验,其中每个参赛选手都有一个不同的 p-强选手的 p 接近 1,而弱选手的 p 接近 0。

对抗模型更适合在线算法框架,所以我不会在这里讨论它。

  • 参赛选手是厌恶风险还是热爱风险?他参加比赛的财务目标是什么?

要想知道如何解决这类问题,让我们转到劳勒的书《随机过程简介》。第 4 章讨论了“最优停止”的问题。这是概率世界中关于决策的一般概率理论,有时也被称为“随机优化”或“随机控制”。他很好地处理了三种不同的场景——普通最优停止、带成本的最优停止和带折扣因子的最优停止。成本意味着你选择留在游戏本身就有一些成本,所以你每多走一步都会有所损失。贴现因子是同一事物的乘法版本——它意味着仅在下一步获得收益的价值可能是现在获得收益的 90%。

让我们来看一个练习——4.8——幸运之轮。在这种设置中,一个有 12 个点的轮子每轮转动一次。它上面有 100 美元到 1100 美元的数字,1 点是破产——如果达到这个数字,您的所有收益都将丢失,游戏结束。问题是什么时候停止是最优的,在这个策略下你的预期收益是多少。

我们的决策规则看起来怎么样?我们只能使用所谓的停止时间,即只能考虑游戏中目前发生的事情,而不能考虑未来会发生什么的规则。然后,我们需要定义一个从系统的这些状态到我们的决策的映射,在这种情况下,是一个{0,1}变量的退出/继续。可以看出,在我们的例子中,整个历史并不重要——如果你目前有 2000 美元的试探性收益,你的决定不应该受到你是在两轮中获得 1000 美元还是在 20 轮中获得 100 美元的影响。唯一重要的等式是下面的递归关系:

V[n+1] = 11/12 * (600 + V[n])

也就是说,如果在第 n 轮有 V[n]次试探性的收益,在第 n+1 轮,你应该预期以 1/12 的概率获得 0 次收益,以 11/12 的概率获得当前的收益+ 600(这一轮的平均赢款)。每当右侧大于当前 V[n]时,您应该继续,否则退出。这给出了等式

V = 11/12 * (600 + V)

或者干脆 V=6600。因此,6600 美元是阈值,如果你的钱少,你应该继续,如果你有这个数目或更多,你应该退出。

现在给定这个规则,我们可以使用动态规划来计算预期的游戏价值。请注意,游戏的预期价值与您提取的价值并不相同!至于你的策略,你会一直坚持到 6600 年,但这并不意味着宇宙会允许你走这么远。对于我在这个 github 库中实现的动态编程过程,我们从 6600 向后传播条件期望。如果我们到达 6600 点,那么我们可以预期 6600 点的增益(或者 X 对于任何 X > 6600 点)。如果我们到达 6500 点,根据停止规则,我们可以预期 11/12 * (600 + 6500)。如果我们到了 6400,我们可以期待 1/12 * v(6500) + 10/12 *(650 + 6400)(为什么?)等等。通过线性期望,我们可以推断出游戏的价值大约是 3134 美元。

我对大多数劳勒最优停止问题的解决方案也在 github 资源库中,你可以在尝试自己解决后查看它们——这些都是很好的问题。

让我们来看一个稍微难一点的问题,这次来自 Rubinstein Kroese 关于蒙特卡罗方法和交叉熵的书。

所以提醒一下,每次你碰到“绳子”(“蛇”)的上侧,你就会下到相应的下侧方块,反之亦然。为了计算穿过整个棋盘的预期时间,您可以尝试以动态编程的方式反向传播条件预期的相同方法,但是当您到达方块 16/17 时,您会遇到一个小问题——它们实际上取决于尚未计算其值的方块。但这只是意味着,不要把它当作一个动态规划问题,你需要把它当作一个线性方程组问题,并为每个方块求解由递归关系定义的系统。解决方案在 snakes.py 脚本中,您大约掷出 7.1 次骰子(我假设您从 0 开始,每当越过 20 就结束,但其他常见版本都假设您从 1 开始,只有当您正好落在 20 时才结束,否则您会回到掷骰子时的松弛量。这将改变递归关系,并相应地改变预期时间,可能会更长一点)。

你可以考虑这个问题的优化版本,它与计划有关。如何定位蛇和梯子,以便最大限度地增加玩耍时间(对于那些希望孩子在家工作时忙碌的父母来说,这很有用)。如何定位它们,使游戏时间的变化最大化(可以带来更有趣的游戏体验)。在所有可能的游戏配置上,我没有发现比蛮力更好的方法,这在小棋盘上是可行的。这产生了大约 7.67 掷骰子的最大预期游戏时间,但是它在最开始有一个非常清楚的定位梯子的结构(所以有很大的机会完全错过它们)和在最后的绳子,所以看一看是否有更正式的东西可以在总体上解决这个问题是很有趣的。

高斯 50 度

现在来点完全不同的。我曾经认为模拟随机变量是一个技术和枯燥的领域,但实际上它非常有趣。计算机编程的艺术第 2 卷第 3 章给出了一个很好的背景,解决了“什么是随机的”这一重要的哲学问题。既然我们生活在现实世界中,你如何确定一个数字序列是“随机”的?32 乘以 0 的序列与 011110011001010000001011011011111101 一样代表 32 次独立的伯努利试验,但不知何故我们认为后者更“随机”。关于随机模拟的 Asmussen 书的第 1 章和第 2 章给出了关于如何在计算机系统中实现从概率分布中抽取的更多技术背景。重要的概念是,一旦你知道如何模拟任何概率分布,就有办法通过反演重要性抽样和其他方法将其重塑为任何其他概率分布。练习 2.9 非常好,它要求你用 6 种不同的方法从标准正态分布中提取数据。我做了 9 个。通过对样本执行μ+σ* RES,这可以容易地推广到正态分布的任何参数化(μ,σ)。在这个过程中,我学到了一些关于 python 实现中这个基本操作的警告的重要经验

  • 随机包普通变量实现有点慢。它使用制服比例方法,该方法似乎比箱式研磨机变体更慢。高斯函数更好(使用 box-muller),但由于它没有要求多个样本的选项,因此它会抛出许多不必要的样本。由于 box-muller 每次运行产生两个样本,如果您要求 random.gauss 产生 100k 个样本,您实际上将丢弃 100k 个其他样本,浪费两倍的时间。
  • numpy 包非常好——特别是因为它使用了 cython,这占了节省时间的大部分(比现在提到的 2 倍因素多得多)。但这只有在你要求一批样品的情况下才适用——如果你一个一个的要求,效率非常低!我很高兴我现在知道它有多重要(对于 100k 样本,它是 0.03 秒和 20 秒之间的差异——660 倍的因子)。

代码在 github 库中给出。

最优运输:一颗隐藏的宝石,赋予今天的机器学习以力量

原文:https://towardsdatascience.com/optimal-transport-a-hidden-gem-that-empowers-todays-machine-learning-2609bbf67e59?source=collection_archive---------16-----------------------

解释目前机器学习中最新兴的方法之一

来源:尼古拉斯·邦尼尔,通过 Youtube

如果我说,对于神经科学中的大脑解码、计算机图形学中的形状重建、计算机视觉中的颜色转换以及神经语言处理中的自动翻译等不同问题,有一种单一的解决方案,你会相信吗?如果我要在这个列表中添加转移学习、图像配准和音乐数据的频谱分解,而事实上我所说的解决方案与深度学习无关呢?好吧,如果你猜不到正确的答案,那么请继续阅读,因为这篇文章是关于最优运输(OT):一个可以追溯到 18 世纪晚期的数学理论,最近在纯数学领域蓬勃发展(在过去的 12 年里获得了 2 个奖!)和机器学习成为目前最热门的话题之一。和我一起走过 OT 跨越过去三个世纪的美丽历史,了解它为什么成为今天机器学习如此重要的一部分。

开始

像许多美好的事物一样,这一切都始于 18 世纪晚期路易十六统治下的法国,大约是 1789 年法国大革命的十年前。在那个阳光明媚的日子里,路易十六在和他的国家最杰出的科学家之一加斯帕尔·蒙日讨论一件政府最重要的事情时,看起来很关心。

“你看,加斯帕德,”路易十六说,“我们在法国有三种类型的奶酪认证:完全不需要离开农场制作的费米尔奶酪,工匠用附近农场的牛奶制作的手工奶酪,以及在工厂用同一地区的牛奶制作的莱蒂尔奶酪。问题是,制作手工奶酪的工匠往往会浪费太多时间四处奔波,从太远的农场取奶。加斯帕德,我希望你能帮助我们解决这个问题,弄清楚哪个农场把所有的牛奶都给了哪个工匠,这样奶酪才会丰富,生活才会美好。

“哦!”加斯帕德有点激动地喊道,“就像我最近和我的冶金学家同事们一起研究的矿石和矿井的问题一样。”

“随便吧,加斯帕德,”陛下回答道。“只要奶酪在桌子上,人民高兴。”

假设一头奶牛的牛奶足以生产一块奶酪,这里的最优 T 将是箭头所示的分配,总距离为 19 公里。

在与国王的这次谈话后,加斯帕德立即意识到,他正在处理的问题可以用左边的表格来表达。在这里,每个单元格给出了农场和工匠之间的距离,而奶牛和奶酪的数量则表明了它们各自的生产能力和供应需求。目标是找到一个函数 T,称为蒙日图,通过考虑农场之间的距离和各自的需求,以最佳方式将每个农场分配给一个工匠。

尽管它看起来很简单,但数学家们花了将近 200 年的时间来完全描述这个问题(比著名的费马大定理少了大约 140 年),直到扬·白来尼在 1991 年表明,它在科学中使用的一些常见距离的一般(连续)情况下承认了一个解决方案。但是,在此之前,发生了以下重要的事情。

共产主义意想不到的好处

图书管理员尼娜在 20 世纪 30 年代末的工作就像今天的谷歌搜索一样,她盯着列宁格勒国立图书馆的书架,试图找到夏尔·波德莱尔的书《恶之花》。后者是列昂尼德要的,他是一个年近三十的诗歌爱好者,现在正不耐烦地等在柜台前。

“我们没有夏尔·波德莱尔,坎特罗维奇同志,”她回到工作场所时说。“但这里有一篇关于冶金学的好文章,作为线性编程的发明者和光荣的苏联公民,你可能会感兴趣”。

她提到的那篇好文章是加斯帕尔·蒙日的“mémoire sur la théOrie des déblais et des remblais”Leonid Kantorovich 有点失望地接受了这篇文章,并在回家阅读时想出了如何改进的方法。

在 Kantorovich 公式中,我们被允许在工匠之间分割生产,以最小化他们所走的距离。

“蒙日问题(T21)的问题是那些君主主义者不分享东西,而我们,苏联人民,彼此分享一切,”列昂尼德自言自语道。“以牛奶为例。我们为什么要关心不让农场在所有工厂之间分配生产呢?”

这让他想到了后来被称为蒙赫-坎特罗维奇问题的想法,在这个问题中,与寻求一个函数 T 将每个农场分配给一个工匠相反,我们现在希望找到一个(概率)函数г,它允许在所有工匠之间分割农场的生产。

与 Monge 的问题相反,这个问题可以被证明:1)在一些关于所用距离的温和假设下总是有解,2)在过去 60 年中,十几个不同的研究人员为此获得了诺贝尔奖、菲尔兹奖和其他杰出的奖项。最后,它暗示了为什么后苏联国家的奶酪尽管以不同的名字出售,味道却是一样的,我的朋友,这是一个伟大的现代谜团,需要加以解释(相信我,我出生在乌克兰)。

低级视图

正如你可能已经猜到的,到目前为止,所有的故事都是为了娱乐而简化的(甚至是虚构的),并提供了一个隐藏在 OT 背后的一般直觉,因为蒙赫和坎特罗维奇所考虑的真正问题要比这复杂得多。

事实上,OT 的真正力量隐藏在其作为一种机制的的能力中,这种机制以尽可能最低的努力将一个概率分布转化为另一个

后一个标准是通过某个函数来测量的,该函数为两个分布中的任何一对点提供了不相似性。

用直方图表示的离散概率分布和用绿色和紫色线给出的拟合连续近似表示的 Monge 问题。

回到我的农场和工匠的例子,我现在可以定义两个离散分布,概率由每个农场的产量(7 头奶牛中的 3 头给我 3/7 的概率)和每个工匠的需求给出。然后,我将获得两个直方图,之前考虑的距离将成为将第一个分布中的点转换为第二个分布中的点的成本。

“但这为什么如此重要?”你可能会问。

嗯,主要是因为数据科学从业者操纵的大量对象可以建模为概率分布

例如,任何图像都可以被视为像素上的分布,概率由它们的强度归一化总和为 1 给出。这同样适用于文本文档,您可以看到单词的离散分布,概率由它们的出现频率给出。这样的例子数不胜数,当您需要比较两个如此复杂的对象时,OT 允许您处理所有的例子。

“但是我们通常用距离来比较物体!”你可能会注意到。

好吧,我们再一次讨论了这个问题,因为这个问题的 Kantorovich 公式定义了一个关于分布空间的真实度量,称为瓦瑟斯坦距离,它服从三角不等式,当两个分布相等时消失。

使用 OT 在蒙日和康托洛维奇肖像之间插值。中间图像显示了将一幅图像转换成另一幅图像的最短路径。

此外,当 OT 问题找到将一个分布转换为另一个分布的最有效方法时,您可以使用它的解决方案在它们之间平滑地插值,并沿此路径获得中间转换。为了说明这一点,让我们以加斯帕尔·蒙日和列昂尼德·坎特罗维奇的形象为例,解决他们之间的优选论问题。上图中的结果显示了两幅图像之间的测地线路径,该路径通过最有效的方式(最短路径)将一幅图像逐渐转换为另一幅图像,其几何形状(或本例中像素之间的成对距离)由您使用的成本函数指定。很酷吧。!现在让我们最终回到现代,看看这对机器学习到底意味着什么。

应用程序的预告片

下面,我将只介绍 OT 在计算机视觉和神经语言处理中的一些应用,以及用于产生结果的代码,这些代码将在“Python 最优传输工具箱实践指南:第 2 部分”中详细介绍。另外,查看本文“Python 最优传输工具箱实用指南:第 1 部分”中的 Python 最优传输工具箱介绍。

顶行 : —原始天空图像; —原始日落天空图像;中间 —颜色转移的结果。底行:蓝色和红色频率点的坐标,突出显示两幅图像的不同颜色风格。读者可以使用下面的代码来重现结果。

颜色转移。这个应用中,我们有两幅图像:一幅是海洋上空的蓝天,另一幅是日落。我们的目标是将第一张图像的颜色风格转移到第二张图像,这样日落图像的颜色看起来就和白天的一样。如前所述,我们将两幅图像视为由 RGB 立方体中的三维向量给出的像素概率分布。我们从每幅图像中抽取 1000 个像素,并使用 OT 将它们对齐。最终的结果在左边的中间图像中给出,显示了带有白天颜色的高度真实的日落图像。

使用中的代码(此处为)通过 OT 对泊松图像编辑进行颜色渐变调整的结果。请注意,使用更精确的图像遮罩可以改善最终结果。

图像编辑。对于这个任务,目标是通过使用另一个图像的补丁替换图像的一部分来编辑图像。例如,在左边的图片中,你可以看到我的脸,蒙娜丽莎的脸,以及我的脸无缝复制到她的脸上的结果。这里的最佳传输被应用于两个图像的颜色梯度,然后求解泊松方程以计算编辑的图像。更多这方面的例子,请看这篇论文

使用 OT 对齐以不同语言编写的文档的嵌入为自动翻译跨语言信息检索提供了最先进的结果。

自动翻译。现在让我们把注意力转向图像以外的东西,并考虑文本语料库。我们的目标是找到两种不同语言中单词和短语的匹配。让我们以下面的一对为例:给定英语命题"猫坐在垫子上"及其法语翻译"le chat est assis sur le tapis",我们希望找到一个提供对应关系" "- " 聊天","坐在 "- " assis "和"垫子 "-"的匹配你明白我的意思了,是吗?!我将定义每个命题的分布,并将每个单词视为一个点。然后,我将使用它们嵌入之间的距离来匹配 OT 的两个分布。这个匹配的结果可以在左边看到。**

还有更多 OT 被证明有用的应用,例如包括形状重建、多标签分类、大脑解码图像超分辨率等等。OT 本身就是一个巨大的宇宙,而且它只会不断上升,这一点在顶级机器学习会议上越来越多的研究论文中得到了证实。

后记

这篇文章故意跳过了所有关于蒙日和蒙日-坎特罗维奇问题、对偶理论和最近引入的熵正则化的数学细节,以便即使没有数学背景的读者也能理解。要了解更多的技术细节,读者可以参考许多关于 OT 理论的精彩综述,包括 Gabriel Peyré和 Marco Cuturi 的新书以及 Cédric Villani 的更深入的专著。

优化算法—自适应矩估计(Adam)

原文:https://towardsdatascience.com/optimisation-algorithm-adaptive-moment-estimation-adam-92144d75e232?source=collection_archive---------13-----------------------

自动协调机制的实施

如果你曾经使用过任何一种深度学习的包,你一定使用过亚当作为优化者。我记得有一段时间,我有一个想法,每当你试图优化一些东西,就用亚当,仅仅因为它是最好的。在这篇文章中,让我们打开黑盒子,看看是什么让亚当如此特别和强大。

圣经》和《古兰经》传统中)亚当(人类第一人的名字

每一种算法都不是凭空出现的,它要么是从另一种算法演化而来,要么是克服了另一种算法的某些不足。这同样适用于亚当。优化算法大致通过以下方式发展:

vanilla gradient descent => sgd + momentum => adaptive gradient

(解释与实现:梯度下降SGD+动量自适应梯度)

SGD 为梯度下降增加了随机性,momentum 加速了收敛,而 adaptive gradient,顾名思义,适应不同参数的不同学习速率,Adam 在某种程度上集合了其他算法的优点,使之成为一种算法。

自适应矩估计(Adam)是另一种计算每个参数的自适应学习率的方法。除了存储过去平方梯度s的指数衰减平均值(如 Adadelta 和 rms prop ), Adam 还保存过去梯度v的指数衰减平均值,类似于 momentum。动量可以被视为一个沿斜坡向下运行的球,而亚当的行为就像一个有摩擦力的重球,因此更喜欢误差面上平坦的极小值。

我们来看看它的更新过程:

其中v是第一时刻,它类似于记录过去标准化梯度的动量。s为二阶矩,与自适应梯度下降& RMSprop 中引入的相同。这个术语有助于给出不同参数的不同学习率。

由于vs被初始化为 0 的向量,Adam 的作者观察到它们偏向于 0,尤其是在初始时间步长期间,尤其是当衰减率较小时。他们通过计算偏差修正的一阶和二阶矩估计来抵消这些偏差:

最后的更新是:

最终的更新过程实际上与自适应梯度下降中引入的公式相同,只是命名器中的梯度被替换为v,因此现在应该清楚的是,Adam 结合了其先例的思想,并演变成了更好的版本。

履行

为了与之前的介绍保持一致,我们仍将使用相同的优化任务:

我们试图用两个参数a, b最小化y — f(x)的损失,上面计算了它们的梯度。

样本生成将是:

我们生成了 100 个xy的样本,我们将使用它们来找到参数的实际值。

实现将遵循上面的公式:

我们设置β1 = 0.9, β2 = 0.999,学习过程会是这样的:

我在这里展示的例子并没有显示 Adam 的明显优势,然而,在更复杂的场景中,Adam 似乎是目前最好的选择。

上面的实现有点冗长,因为我们一直在为每个参数重复相同的过程。下面给出了一个更简洁的实现:

最后,你可以在这里实现

参考:

  1. https://ruder . io/optimizing-gradient-descent/index . html # stochasticgradientdescence

使用 Python 中的蒙特卡洛模拟优化您的待办事项列表

原文:https://towardsdatascience.com/optimise-your-todo-list-with-monte-carlo-simulations-in-python-1682a8a5eb84?source=collection_archive---------11-----------------------

创建蒙特卡洛模拟,找出管理待办事项列表的最佳策略

从我的假期回到现实世界是相当痛苦的。我怀念没有被闹钟吵醒的日子,怀念没有通勤去办公室的日子,怀念没有一整天排着一个接一个会议的日子。我也怀念没有待办事项的日子,除了清晨和妻子一起在海滩散步。

(鸣谢:张秀雄)

像很多人一样,我的待办事项列表中有很多事情。保存待办事项清单有不同的思想流派——有些人喜欢把它们保存在手机的应用程序中,有些人与他们的电子邮件客户端同步,还有一些人在纸上有一个系统,甚至有一个私人助理来帮助组织它们!不管是哪一种,待办事项列表的想法都是为了帮助你更有效地完成任务。

另一个待办事项列表(鸣谢:https://www . Flickr . com/photos/robandstephanielevy/4616960925)

这就引出了一个显而易见的问题——如果你的待办事项清单上有多项任务,你应该先做哪一项?单子上的第一个?最容易做的一个?先说重要的?或者你应该有更复杂的方法来解决它们吗?

如果你有有限的时间来完成我们的任务,这一切会变得更有趣。如果你没有足够的时间,你应该先处理哪一个,用什么策略来优化你的时间?

显然,这在很大程度上取决于你想优化什么——你想完成尽可能多的任务吗?还是完成尽可能多的高优先级任务?还是尽可能多的及时完成任务?

建模

我喜欢蒙特卡洛模拟。我想大多数程序员都是这样。除非你非常擅长数学,否则解决问题的好方法就是简单地对问题建模,生成随机数据,并尽可能多地运行模拟。

就这么想吧。假设你想找出掷出三个骰子得到 4、5 和 6 的可能性。你可以想出一个数学公式,或者我们可以简单地掷骰子十万次,记录每次掷骰的结果来得到概率。

(鸣谢:张秀雄)

掷骰子十万次是相当乏味的,但是如果你是一个程序员,你将编写一个简单的脚本来生成 1 到 6 之间的两个随机数,然后循环它。

当然,在这个例子中,得出数学公式更容易,因为你可能在小学数学中学过,但对于更复杂、更难解决的问题,这可能是得出答案的一种非常有效的方法。

这就是蒙特卡罗模拟的本质。这就是我们在试图优化待办事项列表时,用来找出最佳策略的方法。我们将使用 Python 3 建立一个蒙特卡洛模拟,在 Jupyter 笔记本上运行。模拟将测试各种策略,我们将通过我们设计的一组指标来衡量它们的有效性。

我们开始吧!

模型

我们需要做的第一件事是建立一个模型。这很简单,我们唯一真正需要建模的是任务。

在大多数待办事项列表中,我们都有任务描述、一些注释和截止日期。许多人还对任务设定了优先级。作为任务建模的一部分,我们还需要指出任务花费的时间以及任务完成的日期。

换句话说,我们将使用以下属性对任务进行建模:

  • 重要性(权重)
  • 到期日
  • 复杂性(持续时间)
  • 完工日期

对待办事项任务建模

我用recordtype来代表Task。它就像一种叫做 tuple 的可变类型,并且相对简单。为了创建一个任务recordtype,我们需要一个函数来创建任务。

创建任务

create_task函数获取任务数来创建并返回任务列表。对于每个任务,我需要设置weightdue日期、duration和完成日期(done)。

weight只是 1 到 100 之间的一个随机数,数字越大,任务越重要。我使用randint来生成随机数。它采用了离散的均匀分布,这真的就像是扔一个有 100 个面的骰子(这个确实存在,我不骗你)。

d100 模具(又称二面体)(演员表:https://www.skullsplitterdice.com/pages/how-to-use-a-d100)

due日期是另一个整数,表示该任务离模拟开始的天数。待办事项列表中的截止日期大多接近当前日期,更远的截止日期并不常见。为了对此建模,我创建了一个指数分布,速率参数( λ) 值为 5。然后我从这个分布中随机选择一个值。这样做的目的是让预产期更接近,而不是更晚。

分布= NP . round(NP . random . index(5,10000)) + 1

任务的duration参数是完成该任务需要多少时间,这实际上是任务的复杂性。持续时间应该小于截止日期,否则不可能完成任务!为了对此建模,我将持续时间设为 1 到到期日之间的一个随机整数,再次使用randint

最后,当任务被创建时,完成日期或done属性被设置为 0,并且一旦任务被完成,它将被设置为一个整数,该整数表示自模拟开始以来已经过去的时间量。

我们还需要一个在运行模拟后统计结果的函数。

清点

tally函数接受一个已完成任务列表和一个为模拟创建的所有任务列表,并返回一个由 3 个值组成的元组:

  1. 已完成的任务数
  2. 已经完成的重要任务的数量
  3. 及时完成的任务数

这些值也是我们衡量算法有效性的标准。让我们看看我们是如何得出这些值的。

完成的任务

为了计算已完成任务的百分比,我们只需计算已完成任务的数量与所有任务的总数之比。

completed = len(completed_tasks)/len(all_tasks)

完成的重要任务

计算出有多少重要任务已经完成是很棘手的。首先,我们如何确定哪些任务是重要的?每个任务有一个值在 1 和 99 之间的weight。该值越大,任务越重要。

25 个任务的列表,权重表示任务的重要性

一种方法是画一条线,说如果weight大于 75,它将被认为是一个重要的任务。然而,每个模拟的权重都是随机设置的,这意味着我们有可能最终没有重要的任务或者有很多重要的任务。这不是我们想要的。

另一种方法是使用百分比法来确定哪些任务是重要的。首先,我们根据任务的重要性对其进行排序。然后我们使用一个百分点,在这种情况下,重要任务的第 75 个百分点(使用第 75 个百分点是任意的)。例如,如果我们运行一个有 25 个任务的模拟,那么第 75 个百分位数是具有最大weight值的前 6 个任务,因此这些任务被认为是该特定模拟的重要任务。

percentile = round(0.75 * len(all_tasks))    
important_tasks = sorted(all_tasks, key=lambda x: x.weight)[percentile:len(all_tasks)]

对任务进行排序后,前 75%的任务(6)被认为是重要的任务(用颜色表示的任务)

现在我们有了一个重要任务的列表,我们可以检查完成的任务列表中有多少任务(也就是说,有多少重要的任务已经完成)。我们用这个数字除以所有任务的总数来表示完成的重要任务的百分比。

及时完成的任务

计算这个很简单。我们只需要检查给定列表中每个已完成的任务,并确保done日期小于due date。如果是,说明任务及时完成了,否则就不是。我们只是用在模拟中所有任务中按时完成的任务数来表示按时完成的任务的百分比

intime = len(intime_tasks)/len(all_tasks)

模拟

接下来我们来看看模拟。如前所述,如果我们有足够的时间来完成所有的任务,我们可能不需要优化待办事项列表。不幸的是,在现实世界中,我们没有这种奢侈。为了模拟这种时间的缺乏,我们将所有任务的持续时间相加,并取总持续时间的一个百分比。这将是我们的deadline

当我们进行模拟时,我们会跟踪elapsed time。我们遍历给定的任务列表,对于每个任务,我们将任务持续时间添加到运行时间中。只要elapsed_time没有超过deadline,我们就将任务完成日期设置为经过的时间,并将任务添加到已完成任务列表中。

一旦经过的时间超过了最后期限,模拟就结束了,我们最终会得到一个已完成任务的列表。记住,即使任务完成了,也不意味着及时完成了。

蒙特卡洛

不是这个蒙特卡洛(来自:https://en.wikipedia.org/wiki/Monte_Carlo_Casino)

如果我们只运行一次模拟,那么它就不是蒙特卡罗模拟。蒙特卡罗模拟就是反复运行模拟来解决一个问题。为此,我们将创建一个名为run的函数。

这个函数非常简单。我们按照以下步骤进行多次迭代:

  1. 创建模拟任务
  2. 使用给定的算法模拟任务的执行
  3. 获取结果并将其添加到最终列表中

一旦我们有了最终的数据集,我们将它除以迭代的次数,以获得特定算法的最终结果集。

待办事项算法

这是有趣的部分!该模拟旨在测试不同的 todo 策略或算法,以确定它们的有效性。使用 3 个度量来测量算法的有效性(如上所述):

  1. 完成了多少任务
  2. 完成了多少重要的任务
  3. 有多少任务按时完成了

这是我们将要实验的不同算法的列表。对于这些算法中的每一个,我们传入一个任务列表,算法的工作是根据我们希望如何处理它们来排序任务。

把所有的放在一起

现在我们已经有了我们需要的所有部件,让我们把它们组装在一起,运行我们的蒙特卡洛模拟!对于我们使用的每个算法,我们还想创建一个结果的雷达图。

对于模拟,我们将使用以下参数:

  1. 完成所有任务的最后期限是总时间的 50%
  2. 我们将为每个模拟创建 25 个任务
  3. 我们将运行模拟 20,000 次

运行蒙特卡洛模拟

您可以在以后运行自己的模拟时更改任何参数,以查看它们如何影响最终结果。

结果

这是我们运行的每个算法的结果。

照他们来的做

这是默认设置,实际上只是按照任务创建时的顺序执行任务。这根本不需要处理,我们只是简单地返回任务列表!

Do as they come
- tasks completed                        : 48.47%
- important tasks completed              : 47.77%
- tasks completed in time                : 11.76%

正如预期的那样,由于我们只有 50%的时间来完成任务,我们预计只有大约 50%的任务完成。这也适用于重要的任务。

至于任务的完成时间,事实证明只有 12%左右。这也并不意外——因为我们是按顺序执行任务,而不是并行执行,所以许多任务无法及时完成。

先完成到期的任务

在这个算法中,我们希望那些提前到期的任务先被完成。换句话说,我们希望按截止日期进行升序排序。

Due tasks first
- tasks completed                        : 78.04%
- important tasks completed              : 77.63%
- tasks completed in time                : 29.13%

有了这个算法,我们有了好得多的结果!如果我们先完成到期的任务,我们就完成了大约 78%的重要任务。因为我们首先关注的是截止日期,所以我们自然会设法及时完成更多的任务——所有任务中大约有 29%是及时完成的。

做最后到期的任务

只是为了测试模拟,我们想把它翻转过来,先做晚些时候到期的任务。如果我们的模拟有效,我们应该会得到很差的结果。

Due tasks last
- tasks completed                        : 18.46%
- important tasks completed              : 18.27%
- tasks completed in time                : 6.68%

果然,完成的任务数量相当低,约为 18%,只有 7%左右的任务及时完成。

先做重要的任务

在这个算法中,我们希望关注任务的重要性,所以我们根据它们的权重,以降序对它们进行排序。

Important tasks first
- tasks completed                        : 48.40%
- important tasks completed              : 99.43%
- tasks completed in time                : 11.74%

通过首先关注重要的任务,我们完成了几乎所有的重要任务!记住,我们只有一半的时间去做,所以这是一个相当好的结果。正如预期的那样,完成的任务和及时完成的任务的结果与随来随做算法相同。

先做简单的任务

对于这个算法,我们想先做比较简单的任务,所以我们按持续时间对任务进行升序排序。

Easier tasks first
- tasks completed                        : 83.47%
- important tasks completed              : 83.03%
- tasks completed in time                : 46.66%

这里的结果很好,但令人惊讶。

我们完成了大约 83%的重要任务。这是意料之中的,因为我们首先瞄准容易的,这意味着我们可以更快地完成它们,从而完成更多的任务。

然而,令人惊讶的是,大约 47%的任务也能及时完成。这个数字甚至高于预定任务优先算法!

然而,从另一个角度来看,如果我们先做简单的任务,这意味着我们最终会做更多的任务,从而缩短完成日期。在这种情况下,我们最终会及时完成更多的任务是有道理的。

首先做更简单、更重要的任务

我们以前使用的算法是相当一维的。也就是说,我们只关注重要性、截止日期或复杂性。如果我们使用更二维的算法呢?

对于这个算法,我们先做那些比较容易的重要任务。也就是说,我们用每项任务的重要性来衡量其持续时间,并根据结果进行排序。

Easier important tasks first
- tasks completed                        : 78.29%
- important tasks completed              : 93.29%
- tasks completed in time                : 45.69%

因为这是一个混合算法,我们应该期望结果介于两者之间。对于已完成的重要任务,正如所料,这是在简单任务优先重要任务优先算法之间。同样,对于已完成的任务,我们也有介于重要任务优先简单任务优先之间的结果。

对于及时完成的任务,我们实际上得到的结果与简单任务优先算法几乎相同!

先完成应该完成的简单任务

最后,我们试着先做容易的任务。这意味着我们再次衡量每项任务的持续时间,但这次是根据其截止日期,并根据结果进行排序。

Easier due tasks first
- tasks completed                        : 77.73%
- important tasks completed              : 77.28%
- tasks completed in time                : 46.49%

这个算法的结果有点令人惊讶。对于所有已完成的重要任务,结果与到期任务优先算法大致相同,而及时完成的任务与较容易任务优先算法大致相同。

下一步是什么?

正如你现在可能意识到的,没有最好的算法,最好的算法是优化你想要的算法。如果你想及时完成尽可能多的任务,那么使用简单任务优先算法会做得很好。如果你想完成最重要的任务,那么就用重要任务优先算法

正如老话所说,这只是冰山一角。还有很多需要探索和改进的地方。例如,您可以尝试改进模型:

  1. 假设任务是按顺序运行的,而不是并行运行的。在现实世界中,这不一定是真的
  2. 任务是相互独立的。同样,在现实世界中,这不太可能是真的
  3. 我们只使用 3 个参数来模拟一个任务,当然可以有更多的参数分配给一个任务,然后使用它们来找出如何优化它们

你也可以创建更复杂的算法来优化待办事项列表。例如,我只做了两个简单算法的简单混合,你可以尝试创建一个算法,链接起来的重量,到期日和持续时间参数,甚至更多。

此外,我所有的算法只是对待办事项列表进行排序。你实际上可以定制一个特定的任务序列,最大化所有 3 个指标!事实上,您可以尝试在待办事项列表中创建任务序列的不同排列,并通过模拟运行它们,以找出最佳排列。然而,请注意,这并不一定构成一个特定的算法来优化你的待办事项列表,一个复杂的算法在现实生活中很难实践。

请在此随意查看整个 Jupyter 笔记本,并做出您的更改!让我知道你的结果。

有所有代码的 Jupyter 笔记本

模拟很好玩!

我们刚刚经历了一系列不同的策略来优化你的待办事项列表,并通过蒙特卡洛模拟来尝试每一种策略。但是模拟有多逼真呢?

正如著名统计学家乔治·博克斯所说:

所有的模型都是错的,但有些是有用的

然而,模拟帮助我们更好地理解我们正在模拟的真实事物或事件。它允许我们操纵参数和应用不同的策略来测试什么是最好的。归根结底,模拟只是让我们更好地制定战略和计划的工具。

玩得开心!

用遗传算法优化垃圾收集策略

原文:https://towardsdatascience.com/optimising-a-rubbish-collection-strategy-with-genetic-algorithms-ccf1f4d56c4f?source=collection_archive---------33-----------------------

用 Python 从头开始实现遗传算法

遗传算法是一系列优化技术,大致类似于自然界的进化过程。这可能是一个粗略的类比,但如果你眯着眼睛看,达尔文的自然选择确实大致类似于一项优化任务,其目标是制造完全适合其环境的生物体。虽然人类可能花了几千年才发展出相对的拇指和鹰来发展 20/4 的视力,但在本文中,我将展示如何用 Python 实现遗传算法,在几个小时内“进化”出一个垃圾收集机器人。

张家瑜Unsplash 上拍照

背景

我遇到的演示遗传算法如何工作的最好例子来自 Melanie Mitchell 的一本关于复杂系统的极好的书,名为“复杂性:导游”(强烈推荐)。在一章中,米切尔介绍了一个名叫 Robby 的机器人,它生活的唯一目的就是捡垃圾,并描述了如何使用遗传算法优化 Robby 的控制策略。下面我将解释我解决这个问题的方法,并展示如何用 Python 实现这个算法。有一些构建这类算法的很棒的包(比如 DEAP ),但是在本教程中,我将只使用基本 Python、Numpy 和 TQDM(可选)。

虽然这只是一个玩具示例,但气体在现实世界中有许多应用。作为一名数据科学家,我最常使用它们进行超参数优化和模型选择。虽然它们在计算上可能很昂贵,但 GAs 允许我们并行探索搜索空间的多个区域,并且在计算梯度很困难时是一个很好的选择。

问题描述

一个名叫 Robby 的机器人生活在一个充满垃圾、被 4 面墙包围的二维网格世界里(如下图)。这个项目的目的是为 Robby 进化出一个最佳的控制策略,让他能够有效地捡起垃圾,而不会撞到墙上。

作者图片

罗比只能看到他自己的四个方格 NESW 以及他所在的方格,每个方格有 3 个选项;它可以是空的,里面有垃圾或者是一堵墙。因此,罗比可能处于 3⁵ = 243 种不同的场景中。罗比可以执行 7 种不同的动作;移动 NESW,随机移动,捡垃圾或保持不动。因此,Robby 的控制策略可以被编码为 0 到 6 之间的 243 位数字的“DNA”字符串(对应于 Robby 在 243 种可能情况下应该采取的行动)。

方法

概括地说,使用任何遗传算法进行优化的步骤如下:

  1. 生成问题的随机解决方案的初始“群体”
  2. 每个个体的“适应度”是根据它解决问题的能力来评估的
  3. 最适合的解决方案是“繁殖”并将“遗传”物质传递给下一代的后代
  4. 重复第 2 步和第 3 步,直到我们得到一批优化的解决方案

在我们的任务中,你创建第一代机器人,初始化为随机 DNA 串(对应于随机控制策略)。然后你模拟让这些机器人在随机分配的网格世界里跑来跑去,看看它们表现如何。

健康

机器人的适应度是它在 n 次移动中捡了多少垃圾和撞了多少次墙的函数。在我们的例子中,机器人每捡起一件垃圾,我们就给它 10 分,每次撞到墙上就减 5 分。然后,机器人与和它们的健康分数相关的概率“交配”(即捡了很多垃圾的机器人更有可能繁殖后代),新一代就产生了。

交配

有几种不同的方法可以实现“交配”。在米切尔的版本中,她将两个父母 DNA 串随机拼接,然后将它们结合在一起,为下一代创造一个孩子。在我的实现中,我从每个父母那里概率地分配每个基因(即,对于 243 个基因中的每一个,我抛硬币来决定哪个父母将传递他们的基因)。例如,使用我的方法,这里是两个父母和一个可能的孩子的前 10 个基因:

Parent 1: 1440623161
Parent 2: 2430661132
Child:    2440621161

变化

我们用这种算法复制的自然选择的另一个概念是“突变”。虽然孩子的绝大多数基因将从父母那里遗传下来,但我也构建了基因突变的小可能性(即随机分配)。这种突变率让我们有能力控制勘探和开采之间的权衡。

Python 实现

第一步是导入所需的包,并为此任务设置参数。我选择了这些参数作为起点,但是它们是可以调整的,我鼓励您尝试一下。

接下来,我们为网格世界环境定义一个类。我们用记号‘o’,‘x’和‘w’来代表每一个细胞,分别对应于一个空细胞,一个有垃圾的细胞和一面墙。

接下来,我们创建一个类来表示我们的机器人。本课程包括执行动作、计算适应度和从一对父机器人生成新 DNA 的方法。

最后是运行遗传算法的时候了。在下面的代码中,我们生成了一个机器人初始种群,让自然选择顺其自然。我应该提到,当然有更快的方法来实现这种算法(例如,利用并行化),但为了本教程的目的,我牺牲了速度的清晰。

虽然最初大多数机器人不捡垃圾,总是撞到墙上,但在几代人的时间内,我们开始看到简单的策略(如“如果与垃圾成直角,捡起来”和“如果靠近墙,不要撞到墙”)在群体中传播。经过几百次迭代,我们只剩下一代不可思议的垃圾收集天才!

结果

下图显示了我们能够在 400 代中“进化”出一个成功的垃圾收集策略。

作者图片

为了评估改进的控制策略的质量,我手动创建了一个基准策略,其中包含一些直观的合理规则:

  1. 如果垃圾在当前方块中,捡起来
  2. 如果垃圾在邻近的方格中可见,移动到那个方格
  3. 如果靠近墙壁,向相反的方向移动
  4. 否则,向随机方向移动

平均而言,这种基准测试策略获得了 426.9 分(T0)的健康分数(T1),但这比不上我们最终“进化”的机器人,后者的平均健康分数(T2)为 475.9 分(T3)。

策略分析

这种优化方法最酷的一点是,你可以找到反直觉的解决方案。机器人不仅能够学习人类可能设计的合理规则,还能自发地提出人类可能永远不会考虑的策略。出现的一项复杂技术是使用“标记”来克服近视和记忆缺失。例如,如果一个机器人目前在一个有垃圾的方块中,并且可以看到东面和西面方块中的垃圾,一个简单的方法是立即捡起当前方块中的垃圾,然后移动到相邻的一个方块中。这种策略的问题是,一旦机器人移动了(比方说向西),他就无法记住东边 2 格处有垃圾。为了克服这个问题,我们观察了我们的进化机器人执行以下步骤:

  1. 向西移动(留下当前方块中的垃圾作为标记)
  2. 捡起垃圾,搬回东边(它可以看到留下的垃圾作为标记)
  3. 捡起垃圾,搬到东边去
  4. 捡起最后一块垃圾

作者图片

从这种优化中出现的反直觉策略的另一个例子如下所示。OpenAI 使用强化学习(一种更复杂的优化方法)教代理玩捉迷藏。我们看到代理一开始学习“人类”的策略,但最终会学习新的解决方案,如利用 OpenAI 模拟环境的物理特性的“盒子冲浪”。

结论

遗传算法以独特的方式结合了生物学和计算机科学,虽然不一定是最快的算法,但在我看来,它们是最漂亮的。本文中的所有代码都可以在 my Github 上找到,还有一个演示笔记本。感谢阅读!

利用无监督学习优化 Boids 算法

原文:https://towardsdatascience.com/optimising-boids-algorithm-with-unsupervised-learning-ba464891bdba?source=collection_archive---------37-----------------------

利用 DBSCAN 聚类降低算法复杂度。

在群体智能中,许多个体在一个系统中相互作用。这些个体遵循一套简单的规则,通过他们的互动,可以出现更复杂的行为。

“整体大于其部分之和”——大概不是亚里士多德

突现行为的一个著名例子是克雷格·雷诺兹的“Boids”程序。“机器人”最早诞生于 1986 年,模拟了栩栩如生的群体行为:

我实现的 Boids 算法。

整个鸟群的运动看起来很复杂。然而,如果我们考虑个人,我们可以看到复杂的行为来自三个简单的规则:

  • 分离:机器人移动以避免相互碰撞。
  • 对齐:机器人转向以匹配其周围机器人的平均方向。
  • 内聚力:物体向其周围物体的中心移动。

趋吉避凶。

遵循这些规则的单个 boid 在计算上是廉价的。然而,该算法的基本实现是非常低效的。一个 boid 需要考虑所有其他 boid 来计算其速度更新。因此,在没有额外编程的情况下,boids 算法相对于 boids 的数量具有复杂度 O(n)。随着我们向模拟中添加更多的 boids,我们的工作量会异常增加。

快速提示:我们使用名为“减速”的指标来衡量绩效。实质上,减速是创建模拟所需的时间与该模拟的实时持续时间之间的比率。

指数级性能下降。

提高 boids 性能的一种常见方法是使用空间数据结构。在 O(n)算法中,boid 考虑环境中的所有其他 boid。然而,它们的速度更新只受它们靠近的 boids 的影响。空间数据结构根据 boids 的位置来存储它们。这使得只比较存储在一起的 boids,节省了计算。

最著名的空间数据结构之一是切片。平铺通过在环境上放置一组瓷砖来标记 boids 的位置。Boids 只考虑它们的瓷砖和围绕它的瓷砖中的其他 boids。

可视化平铺。

相对于 boids 的数量,平铺可以将 Boids 的效率提高到接近 O(n)。然而,平铺的一个经常被忽视的问题是它在大状态空间中的效率。随着我们所居住的“世界”的大小增加,瓷砖的数量也呈二次方增加。

计算 boid 的速度更新具有复杂度 O(n ),其中 n 是 boid 范围内的 boid 的数量。因此,我们预计在更宽敞(boid 密度更低)的环境中性能会有所提高。不幸的是,因为平铺在状态空间大小上具有指数复杂性,所以它的性能并没有提高多少。

对于这个问题,我提出的解决方案是使用一种相对于环境规模而言复杂度为 O(n)的算法。

DBSCAN 是一种无监督学习聚类算法,根据点的密度产生聚类。将 DBSCAN 应用于 boids 会创建一组子群,这些子群相距太远,无法相互交互。这些子群中的 boid 和瓷砖中的一样,只需要考虑群中的其他 boid。

实时 DBSCAN 聚类。

相对于环境大小的表现。

在大的状态空间中,DBSCAN 的性能明显优于平铺。平铺必须在整个环境中放置许多冗余的瓦片,在最极端的情况下会有数千个。DBSCAN 只需要考虑 boids 的位置作为点,这样就可以快速地对它们进行聚类。

DBSCAN 不一定是普遍的改进。在高 boid 密度情况下,DBSCAN Boids 具有与 O(n)实现相当的性能。为了解决这个问题,我将 DBSCAN 与前面讨论的平铺算法结合起来。其结果是,相对于环境的大小而言,这种分块算法的效率要高得多。

红框显示了正在执行切片更新的环境区域。我们可以看到,环境中有一小部分需要在时间步长之间进行更新。这给出了相对于原始平铺方法的近乎普遍的改进,以及在高 boid 密度情况下相对于普通 DBSCAN 的提高的性能。

boid 划分算法的性能比较。

尽管我们已经看到了对基本 boids 实现的很好的改进,但我们只处理了改进算法的逻辑。通过优化代码和使用并行编程,可以进一步提高性能。

编辑:使用 KD 树的初步结果显示在高 boid 密度环境中比 DBSCAN/Tiling 性能更好。

我为这篇文章编写的代码可以在这里找到。

最初发布于https://Adam price . io

优化 Javascript 代码

原文:https://towardsdatascience.com/optimising-javascript-code-bb7de4bb14d5?source=collection_archive---------68-----------------------

有些 web 应用程序需要一段时间才能加载,这种情况并不少见。这可能是因为计算量过大或文件过大。这篇文章着眼于代码优化的两种主要方法,以及如何在谷歌的闭包编译器的帮助下完成这些。

照片由蒂尔扎·范·迪克Unsplash 上拍摄

状态

在 web 应用程序中,javascript 通常有两个可以克服的瓶颈——小型化和代码优化。

缩小

在处理网站时,文件大小对应用程序的性能起着至关重要的作用。这是因为任何代码首先需要下载,然后运行。缩小的行为去除了源代码中任何多余的字符,从而产生一个更紧凑的(尽管可读性通常更差)文件。这方面的一个例子如下:

var array = [];for (var i = 0; i < 20; i++) {var j = Math.random()*i/100
  array.push(j)}

https://jscompress.com(它使用丑化 JS 3巴别塔缩小)缩小它,我们得到 32%的压缩,节省了 0.03 kb 和以下更紧凑的代码:

for(var j,array=[],i=0;20>i;i++)j=Math.random()*i/100,array.push(j);

缩小器的工作原理是从代码中删除不必要的字符和空白,但除此之外一般不会改变太多内容。

自我语言翻译

在编译语言中,优化通常处理复杂循环的展开、缓存阻塞或选择正确的列/行顺序来索引矩阵等过程。然而,这种技术计算方式不一定是 JS 工作流程的一部分。

相反,我们希望简化复杂的方程(例如 pythonsympy符号引擎可以帮助将一个方程重写为一个计算强度较低的方程),或者我们可以将长变量重命名为较短的变量,以帮助简化过程。

这就是 google closure 编译器发挥作用的地方。

Google 闭包编译器

这是一个 javascript 编译器,它以一种紧凑和更有效的方式重写和精简现有代码。与传统编译不同,闭包编译器不会将 javascript 转换成机器代码,而是转换成更好的版本。

装置

它的安装很简单,可以通过 node.js 完成。

npm i google-closure-compiler

运转

同样,它的运行也相当直观。Javascript 文件带有--js标志(在本例中,我使用了*通配符来选择所有的.js文件),这些文件被处理成一个单独的输出文件(compiled.js),可以在它们的位置导入。

npx google-closure-compiler --js=*.js --js_output_file=compiled.js 

注意:如果文件顺序是必需的,那么你可以通过使用多个 *--js=* 标志顺序加载所有文件来解决这个问题。

那么闭包编译器做什么呢?

正如你所期待的,谷歌提供了许多工具和技巧来改进代码。最简单的方法是查看长变量名并将其缩短:

function hello(longName) {
  alert('Hello, ' + longName);
}
hello('New User');

已更改为:

function hello(a){alert("Hello, "+a)}hello("New User");

更高级的选项可以进一步简化代码,它解析代码以删除死的(未使用的)函数并检查语法。在文档中给出了一个例子,其中下列功能:

function unusedFunction(note) {
  alert(note['text']);
}

function displayNoteTitle(note) {
  alert(note['title']);
}

var flowerNote = {};
flowerNote['title'] = "Flowers";
displayNoteTitle(flowerNote);

简化为:

function unusedFunction(a){alert(a.text)}function displayNoteTitle(a){alert(a.title)}var flowerNote={};flowerNote.title="Flowers";displayNoteTitle(flowerNote);

然后简化为:

var a={};a.title="Flowers";alert(a.title);

结论

Googles 的 closure compiler 不仅缩减了 javascript 代码,还降低了它的复杂性。静态方程如var x = 17 + 2 被重写(var x=42)以避免不必要的运行时计算,ECMAScript 6 代码可以被转换成 ECMAScript 3——这样它就可以在旧的浏览器上运行。“编译器”使用简单,大大减少了浏览器需要做的工作。

有用的链接

优化—下降算法

原文:https://towardsdatascience.com/optimization-descent-algorithms-bf595f069788?source=collection_archive---------6-----------------------

在本帖中,我们将看到几种基本的优化算法,您可以在各种数据科学问题中使用它们。

机器学习中使用的许多算法都是基于基本的数学优化方法。由于所有的先决条件,在机器学习的背景下直接发现这些算法可能会令人困惑。因此,我认为,为了更好地理解这些技术,将这些算法脱离任何上下文可能是一个好主意。

下降算法

下降算法意味着最小化一个给定的函数,就是这样。真的。这些算法不断地进行迭代,这意味着它们不断地改进当前的解决方案。你可能会想:

如果我想求一个函数的最大值呢?

简单来说,在你的函数前面加一个号,就成了一个“min”问题!

让我们开始吧。这是我们的问题定义:

我们的问题包括寻找一个能使函数 f 最小的向量 x*

你必须知道的一个先决条件是,如果一个点是最小值、最大值或鞍点(意味着两者同时存在),那么函数的梯度在该点为零。

1D 案件

下降算法包括构建一个序列【x },该序列将向【x (arg min f(x)*)收敛。该序列按以下方式构建:

为了到达 x*我们试图建立的序列

其中 k 为迭代, d 为向量,大小与 x 相同,称为下降向量。那么,这就是算法的样子:

x = x_init
while ||gradient(f(x))|| > epsilon:
    x = x + d

就是这样!我们一直进行更新,直到梯度的范数足够小(因为它应该在某个极值达到零值)。

我们将看到 3 个不同的下降/方向向量:牛顿方向、梯度方向和梯度+最佳步长方向。首先,我们需要定义一个函数,在我们的实验中,我们会尽量使它最小化。

罗森布罗克函数

我选择了 Rosenbrock 函数,但你可能会发现许多其他函数,比如这里的。另一个很好的例子是 Himmelblau 函数。

罗森布罗克函数—维基百科

它在 (x,y)=(a,a ) 处有全局最小值,其中 f(a,a ) = 0 。我会用 a=1,b=100 这些都是常用值。

我们还需要另外两条信息,函数的,以及 黑森 矩阵。

罗森布罗克函数的梯度

罗森布罗克函数的海森

让我们打开一个文件并启动一个 Python 脚本。我将在 Google Colab 中这样做,本文中使用的所有代码都可以在这里找到:

** [## 下降算法

奥马尔·阿夫拉克

colab.research.google.com](https://colab.research.google.com/drive/1jOK_C_pSDV6J98ggV1-uEaWUrPuVm5tu)

这是我们的第一段代码。

从现在开始,我将函数输入向量称为 x ,类似于前面的问题定义。现在我们准备好了,让我们看看第一个下降向量!

牛顿方向

牛顿的方向如下:

牛顿方向

所以更新是:

**

快速注释 1

你可以通过做f(x+d)的二阶泰勒展开找到这个更新的公式,因为我们正在执行的更新是x _ new =x+d

我们希望找到 d 使得 f(x + d) 尽可能低。假设f″(x)为正,这个方程是一条有最小值的抛物线。当 f(x + d) 的导数为零时,达到该最小值。

在 n 维中,f″(x)成为 hessian 矩阵,1/f″(x)表现为 hessian 矩阵的逆。最后, f'(x) 将是渐变。

快速注释 n 2

我们需要计算海森矩阵的逆矩阵。对于大型矩阵,这是一项计算量非常大的任务。因此,在实践中,我们解决这一点有点不同,但在一个完全等同的方式。

线性方程

代替计算 hessian 矩阵的逆矩阵,我们为 g 求解该方程,并使更新规则如下:

现在让我们编写算法代码:

您会注意到与我在开始时介绍的算法有一点不同。我加了一个 max_iteration 参数,这样算法不收敛就不会无限期运行。让我们试一试。

我们得到这样的结果:

x* = [1\. 1.]
Rosenbrock(x*) = 0.0
Grad Rosenbrock(x*) = [0\. 0.]
Iterations = 2

该算法仅在 2 次迭代中收敛!那真的很快。你可能会想:

嘿,初始的 x 非常接近目标 x,这使得任务很容易!*

你说得对。尝试使用一些其他值,例如x _ init =【50,-30】,算法终止于 5 次迭代。

这个算法叫做牛顿法所有的下降算法都是这个方法的修改!这是一种母亲配方。它真正快速的原因是它使用了二阶信息(黑森矩阵)。

使用 hessian 矩阵,即使它是 dope,也是有代价的:效率。计算逆矩阵是一项计算量很大的任务,因此数学家们想出了解决这个问题的方法。主要有:拟牛顿方法,和梯度方法。拟牛顿法试图用各种技术逼近 hessian 矩阵的逆矩阵,而梯度法只是简单地坚持一阶信息。

渐变的方向

如果你做过机器学习,你可能已经看过这个了。渐变方向:

渐变的方向

其中 α 称为步长(或以 ML 为单位的学习速率),是一个在 [0,1]范围内的实数。

如果你一直在做一些机器学习,现在你知道这个公式实际上是一个更大的公式的一部分:牛顿方向,只是我们用一个常数代替了逆 hessian!不管怎样,现在的更新规则是:

该算法变成:

让我们试一试:

您可以调整 alphaepsilonmax_iterations 的值。为了得到类似牛顿法的结果,我想出了这些方法。这是结果:

x* = [0.99440769 0.98882419]
Rosenbrock(x*) = 3.132439308613923e-05
Grad Rosenbrock(x*) = [-0.00225342 -0.00449072]
Iterations = 5000

哇!梯度下降法需要 5000 次迭代,而牛顿法只需要 2 次!而且算法没有完全达到最小点 (11)

与牛顿相比,该算法收敛如此缓慢的主要原因是,我们不仅不再拥有由 f、的二阶导数给出的信息,而且我们使用了一个常数来代替逆 hessian。

想想吧。函数的导数是该函数的变化率。所以黑森给出了梯度变化率的信息。由于寻找最小值必然意味着零梯度,hessian 变得非常有用,因为它告诉你梯度何时上升或下降。

ML 中的许多论文只是关于为这个特定的步骤找到一个更好的方法。Momentum、Adagrad 或 Adadelta 就是一些例子。

梯度的方向+最佳步长

对经典梯度下降的一个改进是在每次迭代中使用可变步长,而不是常数。这不仅是一个可变的步长,而且也是可能的最佳步长。****

αk 是迭代 k 时的步长

更新是:

我们如何找到 α ?由于我们希望此次更新尽可能高效,即尽可能减少 f ,我们正在寻找 α ,以便:

注意,在这一步, xgrad(x) 是常量。因此,我们可以定义一个新的函数 q :

其中 q 实际上是一个变量的函数。我们想找到最小化这个函数的 α 。嗯……梯度下降?我们可以,但是既然这样,让我们学习一个新方法: 黄金分割搜索

黄金分割搜索旨在寻找一个函数在指定区间内的极值(最小值或最大值)。由于我们在[0,1] 范围内使用 α,这是使用该算法的绝佳机会。

黄金分割搜索—前 5 次迭代

因为这篇文章开始变得很长,所以我不打算深入细节。希望在我花了很长时间制作的精美 GIF 和下面的代码的帮助下,你能够理解这里发生了什么。

维基百科实现

既然我们能够找到最佳的 α ,让我们用最佳步长编码梯度下降!

然后,我们可以运行这段代码:

我们得到以下结果:

x* = [0.99438271 0.98879563]
Rosenbrock(x*) = 3.155407544747055e-05
Grad Rosenbrock(x*) = [-0.01069628 -0.00027067]
Iterations = 3000

即使在这种情况下,结果没有明显好于纯梯度下降,通常最佳步长执行得更好。例如,我尝试用 Himmelblau 的函数进行同样的比较,最优步长的梯度下降比纯梯度下降快两倍多。

结论

本帖到此结束。希望你学到了一些新的东西,触发了你对数学优化的好奇心!还有很多其他有趣的方法。去找他们!不要忘了检查一下 Google Colab 文件,你会发现所有使用的代码和我们在这里对 Himmelblau 函数做的相同测试。不要犹豫,留下评论,直到下次,和平!😃

Python 中的优化—实习

原文:https://towardsdatascience.com/optimization-in-python-interning-805be5e9fd3e?source=collection_archive---------24-----------------------

编程,PYTHON

了解 Python 的优化技术——实习

乔治·斯图尔特在 Unsplash 上拍摄的照片

有不同的 Python 实现,比如 CPythonJythonIronPython 等等。本文中我们将要讨论的优化技术与标准 Python 实现 CPython 相关。

实习生

实习是按需重用对象而不是创建新对象。这是什么意思?让我们试着用例子来理解整数和字符串的实习。

—这个用来比较两个 python 对象的内存位置。
id —返回以 10 为基数的内存位置。

整数实习

启动时,Python 将一个整数列表预加载/缓存到内存中。这些都在-5 to +256范围内。每当我们试图在这个范围内创建一个整数对象时,Python 会自动引用内存中的这些对象,而不是创建新的整数对象。

这种优化策略背后的原因很简单,即-5 to 256中的整数使用频率更高。因此将它们存储在主内存中是有意义的。因此,Python 在启动时将它们预加载到内存中,以便优化速度和内存。

1:

在这个例子中,ab都被赋值为 100。由于在范围-5 to +256内,Python 使用了 interning,因此b也将引用相同的内存位置,而不是创建另一个值为 100 的整数对象。

作者图片

从下面的代码中我们可以看到,ab都引用了内存中的同一个对象。Python 不会创建新的对象,而是引用a的内存位置。这都是因为整数实习。

作者图片

例二:

在本例中,ab都被赋予了值 1000。由于超出了-5 到+256 的范围,Python 将创建两个整数对象。所以 a 和 b 将被存储在内存的不同位置。

作者图片

从下面的代码中我们可以看到,ab都存储在内存的不同位置。

作者图片

字符串实习

像整数一样,一些字符串也会被保留。通常,任何满足标识符命名约定的字符串都会被保留。有时候会有例外。所以,不要依赖它。

1:

字符串“Data”是一个有效的标识符,Python 对该字符串进行了整形,因此这两个变量将指向相同的内存位置。

作者图片

例 2 :

字符串“数据科学”不是有效的标识符。因此,这里没有应用字符串滞留,所以 a 和 b 都指向两个不同的内存位置。

作者图片

上面所有的例子都来自 Google Colab,它有 Python 3 . 6 . 9 版本

在 Python 3.6 中,任何长度≤ 20 的有效字符串都将被保留。但是在 Python 3.7 中,这个已经改成了 4096。正如我之前提到的,这些东西会随着不同的 Python 版本而不断变化。

由于不是所有的字符串都被保留,Python 提供了使用sys.intern()强制保留字符串的选项。除非有必要,否则不应该使用这种方法。请参考下面的示例代码。

作者图片

为什么字符串实习很重要?

让我们假设您有一个应用程序,其中有许多字符串操作正在发生。如果我们使用equality operator ==来比较长的字符串,Python 会尝试一个字符一个字符地比较,显然这需要一些时间。但是如果这些长字符串可以被保留,那么我们知道它们指向同一个内存位置。在这种情况下,我们可以使用is关键字来比较内存位置,因为这样会快得多。

结论

希望你已经理解了 Python 中优化的 interning 的概念。

如果你有兴趣学习更多关于优化的知识,请浏览 窥视孔优化

[## Python 中的优化—窥视孔

Python 的窥视孔优化技术简介

towardsdatascience.com](/optimization-in-python-peephole-e9dc84cc184d)

要了解 M 的不变性和 Python 的不变性,请 点击这里 阅读文章。

阅读更多关于 Python 和数据科学的此类有趣文章, 订阅 到我的博客【www.pythonsimplified.com】 你也可以通过LinkedIn联系我。

运输问题中的最优化

原文:https://towardsdatascience.com/optimization-in-transportation-problem-f8137044b371?source=collection_archive---------0-----------------------

运输问题(TP)及示例(西北角规则、最小费用法、VAM、平衡 TP、非平衡 TP)

照片由赞·李Unsplash 拍摄

在这个快速发展的世界里,对商品的需求与日俱增。因此,交通的重要性在社会中扮演着重要的角色。将商品从这个国家的一个角落运到另一个角落的公司的利润和财富是由运输决定的。当运输成本和运输时间压倒生产成本和生产时间时,更是如此。如果所有领域的运输都得到专业的处理,如果所涉及的成本都达到最优,那么即使其他因素不变,这个国家的生产率也会提高。

最优运输资源分配的研究是;运输理论或运输理论。法国数学家加斯帕尔·蒙日在 1781 年正式提出了这个问题。第二次世界大战期间,苏联数学家和经济学家 Leonid Kantorovich 在该领域取得了重大进展,因此被称为 Monge-Kantorovich 运输问题。

线性规划(LP) 解决的运输问题的一个重要类型是从几个供应中心到需求中心的货物和服务的物理分配领域。换句话说,运输问题处理的是商品从不同的来源到不同的目的地的移动,总的目标是最小化运输成本。运输问题的这种线性规划公式也被称为希区柯克库普曼运输问题。

运输模型应用于航空业、研发、旅行推销员、转运等。

先决条件

要解决运输问题,必须给出以下信息:

  • m=源的数量。
  • n=目的地的数量。
  • 每个来源的可用总量。
  • 每个目的地的总需求量。
  • 将一件商品从一个来源运输到另一个目的地的成本。

假设

在使用任何运输技术之前,做出以下基本假设:

  • 所有来源的可用总量等于目的地的需求总量。如果它们彼此不匹配,则添加伪源或伪目的地。
  • 从一个起点到一个目的地的单位运输成本是已知和确定的。
  • 单位成本与运输的货物数量无关。
  • 目标是最小化总运输成本。
  • 虽然运输问题可以公式化为一个 LPP,其他更简单的算法被开发出来解决它们。

解决运输问题

基本上有 3 个主要步骤

1.LPP 交通模型的建立

2.找到一个基本可行的解决方案(BFS)

3.最优性测试

我们来详细说说

1。LPP 交通模式的制定

在解决一个运筹学问题时,关键在于通过解码问题来建立模型。对于运输问题,通常会以表格形式或矩阵形式给出问题,称为运输表或费用-效益矩阵。

下面我们来看一个例子。

一个运输问题的例子,来源={A,B,C},总供应量=70,目的地={1,2,3},总需求= 70[图片作者提供]

这里,

Source = {A,B,C}

它们分别代表供应能力为 10、35、25 单位商品的来源(以橙色给出)

因此,总供应量=10+35+25=70

目的地= {1,2,3}

它们分别代表需要 20、25、25 单位商品的目的地(以绿色给出)。

因此,总需求=20+25+25=70

矩阵中表示的元素(白色部分)称为成本。即把单位商品从一个产地运到另一个目的地所涉及的单位成本。

举个例子,

1 单位商品从产地 a 运到目的地 1 所产生的成本= ₹2/-

1 单位商品从来源 a 移动到目的地 1 所产生的成本= ₹2/-(这里,我们正在查看来源 a 和目的地的横截面 1 ) 【作者图片】

同样的,

将一个单位的商品从产地 b 运到目的地 2 所产生的成本= ₹4/-

诸如此类。[这里,我们正在查看来源和目的地的横截面]

运输问题的类型

在继续之前,让我们检查不同类型的运输问题。

运输问题基本上有两种类型:

1.平衡运输问题

2.不平衡运输问题

根据可获得的供给和需求,将运输问题分为平衡运输和不平衡运输。【作者图片】

让我们窥探一下。

1。平衡运输问题

可用总量=需求总量

即总供给=总需求

让我们看看下面的例子。

来源={A,B,C}总供应量=75,目的地={1,2,3}总需求=75 的平衡运输问题示例【作者图片】

这里,

总供应量=75

总需求=75

因此,总供给=总需求

2。不平衡运输问题

可用总量≠需求总量

即总供给≠总需求

所有来源的可用总量等于目的地的需求总量。如果它们彼此不匹配,则添加虚拟源或虚拟目的地,使其成为标准运输问题。

有两种情况会导致这种不平衡状态

(我)。总供给>总需求

(二)。总供给<总需求

(我)。 总供给>总需求

即可用总量>需求总量

让我们看看下面的例子。

来源={A,B,C}总供给=65,目的地={1,2,3}总需求=60 的不平衡运输问题示例【作者图片】

这里,

总供应量=65

总需求=60

因此,总供给大于总需求

在这种情况下,我们添加一个虚拟目的地,给出虚拟需求,每个成本为零(0),但虚拟目的地的虚拟需求为总供应-总需求。

一个不平衡运输问题的例子,来源={A,B,C},总供给=65,目的地={1,2,3},虚拟需求=5,总需求= 65[作者图片]

在本例中,虚拟需求= 65–60 = 5

因此,总供给=总需求

(二)。总供给<总需求总需求

即可用总量

Let’s check the example below.

An example unbalanced transportation problem with Source ={A,B,C} with total supply=65 and Destinations={1,2,3} with total demand=75 【作者图片】

这里,

总供应量=65

总需求=75

因此,总供应量

In such cases, we add a dummy source giving dummy supply with each cost as zero (0) but dummy supply for the dummy destination as total demand-total supply.

An example unbalanced transportation problem with Source ={A,B,C} with total supply=65 and Destinations={1,2,3} with dummy supply=10 making total supply=75 【作者图片】

在本例中,伪电源= 75–65 = 10。

因此,总供给=总需求

运输中的每一个问题所寻求的解决方案都是从每一个源头到哪一个目的地的数量,使得所有的需求同时成本保持最小。

为此,我们必须将每个问题转换为标准问题才能走得更远。

2。 基本可行方案(BFS)

有不同的方法可以获得初始的基本可行解。它们是:

(1).西北角规则

(2).最小费用法(或矩阵最小法)

(3).沃格尔近似法VAM

让我们深入研究每种方法。

为了更好地理解,让我们考虑一个示例问题。

下面给出问题。

【作者图片】

第一步是使它成为一个标准的运输问题。

为此,检查它是平衡运输问题还是不平衡运输问题。

【作者图片】

给定的问题是一个平衡运输问题。那么,我们继续吧。

现在,我们必须找到一个基本可行的解决方案。同样,我们有 3 种不同的方法。我们借助这个问题,一个一个来查。

①。西北角规则

西北方向【图片由作者提供】

选择西北角单元。即第一行和第一列的交点的成本。[此处,5(以蓝色给出)]

比较该细胞的需求和供给。[此处,65 和 70(以红色给出)]

【作者图片】

分配具有最小值的单元格[这里是 65(以黄色给出)]

减去具有最小值的排除像元。即分配的小区值。[在这里,70–65 = 5]

【作者图片】

通过划掉相应的列或行来删除它。[此处,目的地为 1 的列(用红线标记)]

总需求和总供给总是保持不变。(可以考虑这个方法来验证自己走的路是否正确。)因为我们以总需求和总供给保持不变的方式给单元分配新值。

[即,在这里,42+43+65=150(总需求)和 5+30+50+65=150(总供给)]

现在用剩余的细胞继续这个过程。

再次找到西北(N-W)单元,并执行与上面给出的步骤相同的步骤。

让我们在这个例子中看到同样的情况。

【作者图片】

【作者图片】

【作者图片】

【作者图片】

这里,需求和供给将是相同的,这将在剩余的单个单元中进一步分配。【这里,43】(这是验证以上所有步骤是否正确的另一种方法。)

验证流程正确性的方法:

总需求和总供给在所有步骤中保持不变。

在最后一步中,将为单个单元分配需求或供应中的值,因为两者具有相同的值。

如果需求和供给具有相同的值;平局,你可以选择其中任何一个来分配单元格使其他值为零。(决定选哪个,纯属用户选择。👍)

包含所有已分配单元格的最终表格如下所示。

这通过 N-W 拐角方法给出了初始可行解。

【作者图片】

现在让我们来计算与这些分配相关的成本。

要找到相同的结果,请将所有分配的像元值(以黄色给出)和相应像元的成本(以蓝色给出)的所有乘积相加。

即总成本=(65x 5)+(5x 7)+(30x 4)+(7x 7)+(43x 7)

=325+35+120+49+301

=830

现在,让我们了解一下我们发现了什么

₹830-represents 商品运输的总成本。

我们用西北角方法找到的路径用红色箭头表示。

【作者图片】

让我们用表格来表示同样的情况

最终方案表【图片由作者提供】

这可能代表也可能不代表该问题的最佳解决方案,即,可能存在其他分配方式,这些方式可能以较低的总成本给出更好的解决方案。
必须进行最优性测试,以测试所获得的答案是否是最优的。如果没有,最优性测试将我们引向一个可能的改进。

②。最小费用法(或矩阵最小法)

我们用同一个例子来讨论。

【作者图片】

【作者图片】

选择所有成本中的最小值(以白色给出)。即最低成本。[此处,4(以蓝色给出)]

这里有两个成本最低的单元。决定选哪个纯粹是用户的选择。

如果有 1 个以上的单元具有相同的最小成本;一条领带,你可以选择其中任何一条。(决定选哪个,纯属用户选择。👍)

【作者图片】

比较该细胞的需求和供给。[这里,30 和 65(以红色给出)]分配具有最小值的单元格[这里,30(以黄色给出)]

减去具有最小值的排除像元。即分配的小区值。[在这里,65–30 = 35]

通过划掉相应的列或行来删除它。[此处,带有源 B 的行(用红线标记)]

总需求和总供给总是保持不变。(可以考虑这个方法来验证自己走的路是否正确。)因为我们以总需求和总供给保持不变的方式给单元分配新值。

[即,在这里,35+42+43+30=150(总需求)和 70+50+30=150(总供给)]

现在用剩余的细胞继续这个过程。

同样,找到最小成本的像元,并执行与上述步骤相同的步骤。

让我们在这个例子中看到同样的情况。

【作者图片】

【作者图片】

【作者图片】

【作者图片】

这里,需求和供给将是相同的,这将在剩余的单个单元中进一步分配。【这里,43】(这是验证以上所有步骤是否正确的另一种方法。)

验证流程正确性的方法:

通过这些步骤,总需求和总供给将保持不变。

在最后一步中,将为单个单元分配需求或供应中的值,因为两者具有相同的值。

如果需求和供给具有相同的值;平局,你可以选择其中任何一个来分配单元格使其他值为零。(决定选哪个,纯属用户选择。👍)

包含所有已分配单元格的最终表格如下所示。

这通过最小成本方法给出了最初可行的解决方案。

【作者图片】

现在让我们来计算与这些分配相关的成本。

要找到相同的结果,请将所有分配的像元值(以黄色给出)和相应像元的成本(以蓝色给出)的所有乘积相加。

即总成本=(35×5)+(30×4)+(35×7)+(7×7)+(43×7)

=175+120+245+49+301

=890

现在,让我们了解一下我们发现了什么

₹890-represents 商品运输的总成本。

我们用最小成本方法找到的路径被红色的箭头标出。

【作者图片】

让我们用一个表格来表示。

最终方案表【图片作者】

这可能代表也可能不代表该问题的最佳解决方案,即可能存在其他分配方式,这些方式可能以较低的总成本给出更好的解决方案
,必须执行最优性测试,以测试所获得的答案是否是最佳的。如果没有,最优性测试将我们引向一个可能的改进。

( 3)。沃格尔近似法【VAM】(或称罚函数法)

我们用同一个例子来讨论。

【作者图片】

在 VAM,选择要分配的成本单元并不像我们在西北角方法和最小成本单元方法中讨论的那样容易。(冷静伙计,😎不过,这并没有那么难。😇但是这个过程比以前长了一点。😅)

在 VAM 中,我们首先要在每行和每列中找出两个最低成本之间的差异。这些被称为罚金/额外成本。

考虑两个最小值之间的差异。

【作者图片】

[这里,惩罚= {2,0,11,3,1}]

现在,在不考虑行或列的情况下,找出惩罚中的最大值。

[此处,最大(惩罚)=3(以粉红色给出)]

如果有平局,选择任何人。(决定选哪个,纯属用户选择。👍)

【作者图片】

现在,相应地查看相应的行或列。

[此处,该列(以粉红色给出)]

选择所有成本中的最小值(以粉红色给出)。即最低成本。[此处为 4(在下图中以蓝色给出)]

如果有 1 个以上的单元具有相同的最小成本;一条领带,你可以选择其中任何一条。(决定选哪个,纯属用户选择。👍)

【作者图片】

比较该单元格的需求和供应[这里是 30 和 42(用红色表示)]

【作者图片】

分配具有最小值的单元格[这里,30(以黄色给出)]

减去具有最小值的排除像元。即分配的小区值。[在这里,42–30 = 12]

通过划掉相应的列或行来删除它。[此处,带有源 B 的列(用红线标记)]

总需求和总供给总是保持不变。(可以考虑这个方法来验证自己走的路是否正确。)因为我们以总需求和总供给保持不变的方式给单元分配新值。

[即,在这里,65+12+43+30=150(总需求)和 70+50+30=150(总供给)]

现在用剩余的细胞继续这个过程。

再一次,找到罚分,按照上面给出的步骤做同样的事情。

让我们在这个例子中看到同样的情况。

【作者图片】

【作者图片】

【作者图片】

【作者图片】

这里,需求和供给将是相同的,这将在剩余的单个单元中进一步分配。【这里,43】(这是验证以上所有步骤是否正确的另一种方法。)

验证流程正确性的方法:

通过这些步骤,总需求和总供给将保持不变。

在最后一步中,将为单个单元分配需求或供应中的值,因为两者具有相同的值。

如果需求和供给具有相同的值;平局,你可以选择其中任何一个来分配单元格使其他值为零。(决定选哪个,纯属用户选择。👍)

包含所有已分配单元格的最终表格如下所示。

这给了 VAM 一个初步可行的解决方案。

【作者图片】

现在让我们来计算与这些分配相关的成本。

要找到相同的结果,请将所有分配的像元值(以黄色给出)和相应像元的成本(以蓝色给出)的所有乘积相加。

即总成本=(65x 5)+(5x 7)+(30x 4)+(7x 7)+(43x 7)

=325+35+120+49+301

=830

现在,让我们了解一下我们发现了什么

₹830-represents 商品运输的总成本。

VAM 发现的红色箭头代表了他所走的道路。

【作者图片】

让我们用一个表格来表示。

最终方案表【图片由作者提供】

这可能代表也可能不代表该问题的最佳解决方案,即可能存在其他分配方式,这些方式可能以较低的总成本给出更好的解决方案。
必须执行最优性测试,以测试所获得的答案是否是最优的。如果没有,最优性测试将我们引向一个可能的改进。

3.最优性测试

虽然基本可行的解决方案可能会考虑到所有的源和位置限制,但它不需要给出成本最低的解决方案。可能有几个基本可行的解决方案,但是最小化总运输成本的方案被认为是最佳方案。在通过上面列出的任何一种方法确定了一个基本可行的解决方案之后,该解决方案将被进一步测试,因为优化测试将验证给定的解决方案是否是最好的,如果不是,它将引导我们找到更好的或最优的解决方案(我会选择一个坏的方案而不是最坏的方案)。😉(我们将在另一篇文章中详细讨论它,因为对我来说这本身似乎太长了。😂)

参考

K. P. Phaneesh 博士,运筹学(2009 年),Sudha 出版物

End-Note

到目前为止,我们已经讨论了找到一个基本可行的解决方案。我们只能在最优性测试后做出选择正确路径的决定,这将在另一篇文章中讨论。😊

请随意分享你的宝贵想法💭,想法💡甚至怀疑😕😵。

用 Python 和 Gurobi 优化周生产计划—第 1 部分

原文:https://towardsdatascience.com/optimization-of-a-weekly-production-plan-with-python-and-gurobi-part-1-d1257ad29a9?source=collection_archive---------12-----------------------

实践教程

了解如何使用 Python 和数学求解器 Gurobi 解决优化问题

即使在 2020 年,许多制造企业仍在手工进行生产规划,导致不必要的直接成本增加。让我们一起来看看如何使用 Python 和 Gurobi 优化求解器来降低这些成本。

莱尼·屈尼Unsplash 上拍摄的照片

语境

你自豪地拥有一家制造公司,拥有三条生产线。在每一条生产线上,你都可以生产同样的产品,但不幸的是,每条生产线的设计都不一样,每条生产线的小时人工成本也不一样。您希望能够充分利用您的设备,以获得最大的成本效益。

在本文中,我们将了解如何使用 Python 和 Gurobi solver 通过一个简单的模型来优化工作时间,以便熟悉这些工具。在第二部分中,我们将更深入地优化,添加更多的约束并比较结果。

问题陈述

如上所述,贵厂拥有三条生产线。1 号线和 3 号线的小时人工成本为 245 美元/小时,2 号线为 315 美元/小时。由于目前的规章制度,你对每天的工作时间有一些限制:一条线每天不能运行少于 7 小时或超过 12 小时。

客户的要求是一周中每天的生产小时数,您希望在需要的那一天安排这些小时,这意味着没有提前或延迟计划。

让我们深入研究一下,看看如何使用 Gurobi solver 来回答这个问题。

问题图解|作者图片

一个简单的计划优化模型

输入的创建

第一步是定义将用于我们的问题的数据,在问题陈述中描述。我们将创建一些字典和 pandas 数据框,如下所示,其中包含与本周客户需求相关的信息、我们优化计划的时间表、可用生产线列表以及相关的小时成本。

启动模型并创建变量

我们现在已经定义了所有的输入;让我们建立我们的模型。我们需要初始化它,并创建将在我们的函数中使用的所有变量。

我们将使用类型提示来获得更干净的代码,并确保变量的类型是正确的。我们函数的输入是我们希望实现计划的时间表、可用工作中心的列表、每天的需求以及每个工作中心的每小时成本。

让我们启动我们的模型并创建决策变量。我们用 addVars() 添加变量,并在属性中为每个变量设置大小、边界和类型。

  • working_hours :我们范围内每天由工作中心索引的整数变量。为了尊重您公司的规章制度,边界下限设置为 7,上限设置为 12。
  • line_opening :表示每条生产线每天的状态的二进制变量,如果生产线关闭,取值 0;如果生产线正在运行,取值 1
  • total_hours :以天数和工作中心为索引的整数变量;它是每条线路的实际营业时间。
  • labor_cost :一个整数值,衡量每行的每日人工成本。

作者对 total_hours 变量的图解|图片

现在,我们刚刚创建了每个变量,没有指定任何关系。一些变量相互关联,我们现在必须创建一些约束来设置它们的值。

设置约束

类似地,让我们用add consts()创建约束。如果您只想创建一个约束,您应该使用不带“s”的add const(),但是在本例中,我们为每天和每条生产线创建多个约束。

首先,我们需要链接之前创建的变量。总时数的价值是工时和线路开通的乘积,人工成本的价值是总时数和 wc_reg_cost 中包含的每个工作中心的小时成本的乘积。

现在,运行我们的模型的一切都准备好了。在解决它之前,我们需要创建最后一个来自我们与客户的协议的约束。事实上,如前所述,每天的需求必须在同一天得到满足。可以翻译如下:

模型完全建立后,我们现在可以定义我们的目标函数并求解它。

创建目标函数和解决方案

尽管所有这些都很有趣,但我们不要忘记我们的目标:我们希望通过更好地平衡 3 条生产线上的工作量来最大限度地降低劳动力成本。这是我们的目标函数!

现在,我们刚刚完成的模型可以求解,并将为我们提供最具成本效益的规划。

您可以使用以下代码来可视化您的模型,查看您的所有变量、约束和目标函数,这有助于纠正错误并检查模型是否是您想要的。

当然,在这里,我们的模型是正确的,可以直接运行。我们可以提取溶液,并根据需要将其成型。

可视化解决方案

我们现在拿出了最好的生产计划来满足客户的要求;我们需要提取并使其更加可视化。为此,我们将使用 Altair 库的直观界面和我们可以轻松创建的图形设计。由于这不是本文的目的,我不会详细说明我是如何做到这一步的,但您可以在我的 GitHub (Model1.py)上找到它,如果您需要任何解释,请联系我。

我们的优化算法的结果用 Altair 库绘制

正如预期的那样,当 1 号线和 3 号线在开通 2 号线之前达到最大负荷时,我们的生产计划得到优化,因为这条线上的每小时成本更高。我们可以看到,界限是受到尊重的,我们每天不开通少于 7 小时或超过 12 小时的线路。更重要的是,尊重客户的要求,当天满足每天的要求,不提前也不迟到。

限制和后续步骤

第一个模型是使用 Gurobi 求解器进行生产计划优化的第一种方法,但存在许多局限性。事实上,我们没有考虑因加班或周末工作而产生的额外成本。此外,需求可能不允许我们在同一天生产它;比如不到 7 个小时,我们就不能开通线路。这就是为什么我们将在第二部分添加更多的约束来考虑这个问题,并且我们将比较结果。

如果你需要进一步的信息或者想就这个话题交换意见,请随时联系我。你可以在 LinkedIn 上找到我。

资源

这个项目在我的 GitHub 上的资源库:https://GitHub . com/baptistesoulard/Production-plan-optimization/tree/master/Planning _ optimization _ part 1

解释 SAP 如何在其计划优化模块中使用线性优化:http://www . guro bi . com/pdf/user-events/2017-Frankfurt/SAP . pdf

Gurobi 文档:https://www . guro bi . com/documentation/8.0/examples/work force 5 _ py . html

用 Python 和 Gurobi 优化周生产计划—第二部分

原文:https://towardsdatascience.com/optimization-of-a-weekly-production-plan-with-python-and-gurobi-part2-6ebcefe85e52?source=collection_archive---------25-----------------------

实践教程

了解如何使用 Python 和数学求解器 Gurobi 解决优化问题。

本文是关于生产计划优化的系列文章的第二篇,它补充了第一篇文章,增加了更多的约束条件,以便更好地代表实际情况。目标保持不变:优化生产计划以降低直接成本。

为了更好地理解,我强烈建议您阅读本系列的第一篇文章:

[## 用 Python 和 Gurobi 优化周生产计划—第 1 部分

了解如何使用 Python 和数学求解器 Gurobi 解决优化问题。

towardsdatascience.com](/optimization-of-a-weekly-production-plan-with-python-and-gurobi-part-1-d1257ad29a9)

卡洛斯·阿兰达Unsplash 上拍摄

语境

在第一篇文章中,我们学习了如何使用 Python 和数学求解器 Gurobi 来解决一个基本的优化问题。我们看到了如何使用这些工具在几条生产线之间以优化的方式安排来自客户订单的日常需求,从而降低劳动力成本。

现在,我们将看看如何将问题复杂化,使其更加现实。事实上,我们在第一篇文章中开发的模型主要由于以下两点而受到限制:

  • 我们没有考虑周末和加班时间的额外劳动力成本。
  • 我们将生产线的开放时间限制为最短 7 小时,最长 12 小时。因此,如果需求不在此范围内(例如,如果每日需求为 3 小时),则不可能解决我们的模型。

在接下来的部分中,我们将看到如何修改我们的第一个模型来处理这些限制。我们不会详细回顾所有的代码,而只是展示对第一个模型所做的更改。你可以在我的 GitHub 上找到完整的代码。

每个模型的不同考虑|作者的图片

1 部分:让我们在模型中加入加班和周末额外成本

与第一篇文章一样,我们拥有 3 条生产线,每天可以运行 7 小时到 12 小时,我们将了解如何优化生产计划以降低直接成本。下一张图片提醒了我们的背景:

问题图解|作者图片

在现实生活中,不可能无限制地设置操作员的工作时间。的确,劳动力不会免费加班,我们需要在模型中考虑这些额外成本。

例如,在正常工作时间开三条生产线可能比在两条生产线上加班更划算。考虑到这一新的约束条件,这次,我们假设我们的操作员每天工作 8 小时,按固定工资标准支付工资,而加班时间的工资则高出 50%。此外,在周末工作时,操作员的工资是正常工资的两倍。

输入

如上所述,正常工作时间、加班时间和周末的每小时成本是不同的。让我们设置这些新的人工成本,加班时间的系数为 1.5,周末时间的系数为 2:

变量

与我们之前设置的变量唯一不同的是, 总工作时间 变量是基于两个元素构建的: 正常工作时间加班时间 。让我们用 addVars 创建这些变量,并按照上下文演示中提到的那样设置它们的边界。

由于劳动力成本在周末是不同的,我们需要将我们的时间表分成两个列表,一个用于工作日,一个用于周末。我们稍后将分别迭代这两个列表上的约束。

限制

至于约束条件,我们需要将加班时间总时数 联系起来,对于每个工作中心,每天用【addconsts

最后,考虑到新的变量,劳动力成本的价值发生了变化。按照本文开头解释的规则,它是针对工作日和周末分别计算的。

我们现在已经添加了所有新的约束,我们可以解决我们的模型。

形象化

与第一种模式相反,这种计划不会最大化 1 号线和 2 号线(较便宜的那条)的工作时间,但会减少加班时间。

你可以观察到周末的情况并非如此。这是因为在此期间不存在加班额外成本的概念,该成本是正常人工成本的两倍,但全天保持不变。

第 2 部分:现在让我们允许早期生产,并将库存成本添加到模型中

尽管以前的模型非常令人满意,但它们受到一个主要的限制!不可能在要求的交货日期之外的某一天计划生产,这可能导致许多无法解决的情况。

除了这一点,我们的直接成本也可以通过在我们的时间线内平衡生产来降低,这在我们以前的模型中是不允许的。

为了解决这个问题,我们现在将允许提前生产。但是,早期生产伴随着存储成本,我们需要控制它。

输入

大多数投入保持不变,但是,一个新的直接成本产生了:持有成本。持有成本包括组织由于持有存货而产生的所有费用。它包括资本成本、存储成本和风险成本。实际的运输成本会有很大的差异,这取决于你所在的位置、你生产的产品类型以及许多其他因素。然而,根据 APICS,制造业的失业率通常估计在 20%至 30%之间。(1)

在我们的问题中,我们正在处理生产时间。我们需要使用的单位持有成本是对一天存储一小时产品的持有成本的估计。我们可以认为它相当于一小时内平均生产库存的 20–30%。在我们的例子中,让我们把它设置为 25 美元。

变量

由于有可能在要求的交货日期前制定计划,我们需要提前知道生产的数量。让我们创建变量,稍后我们将设置它的值。

为了获得在要求的交货日期之前计划的工时数,我们将计算从第一天到最后一天的累计需求和累计计划工时之间的差异。该矩阵的总和是需求前一天计划的工作小时数。稍后,我们将把这个值乘以单位存储成本,就可以知道早期规划产生的总额外成本。

以下是该变量的计算示例:

早期生产计算插图|作者图片

在这个例子中,我们可以看到提前一天计划了一个小时的生产(蓝色方块)。是我们用我们的逻辑计算早期产量时能发现的。以下是用于我们模型的公式:

对于时间线中的 k:

通过减去(1)到(2):

既然我们已经了解了如何计算早期生产的价值,我们可以创建一个约束来设置它的价值。

限制

在以前的模型中,我们设置了一些约束条件,以强制在要求的交货日期进行计划。这一次,我们将取消这一限制,因为我们希望允许早期规划。然而,由于客户满意度是我们的第一要务,我们希望防止规划滞后。要做到这一点,最简单的方法就是简单地将我们的 的下界早生产 变量限制为零。

在定义变量时已经完成了这一步,我们可以删除以前模型中关于准时调度的约束集。

目标函数

我们的目标还是一样,降低直接成本。但是这一次,我们的直接成本包含了需要添加到目标函数中的持有成本。这些成本是用单位账面成本乘以 前期生产 计算出来的。

形象化

这一次,我们可以观察到,我们的解决方案倾向于平衡一周内的生产,并最大限度地减少加班时间,甚至减少周末的工作时间。的确,周末的工作时间是最贵的,是正常工作时间的两倍。然而,当我们考虑存储成本时,早期生产被最小化。

三种模式的比较

最后,这三种优化模型给出了不同的结果。前两个模型的输出是错误的,因为我们没有告知我们的算法额外的成本,并且我们不允许提前计划。由这两个第一模型提出的计划的成本比由第三模型提出的成本高大约 5000 美元。

总之,绝对有必要建立广泛的模型,考虑现实生活中发生的所有约束,以便用优化算法得出有意义的结论。

如果你需要进一步的信息或者想就这个话题交换意见,请随时联系我。你可以在 LinkedIn 上找到我。

资源

1.斯蒂芬·n·查普曼,j·r·托尼·阿诺德,安·k·盖特伍德,劳埃德·m·克莱夫 物料管理简介。

这个项目的资源库可以在我的 GitHub 上找到。

关于 SAP 如何在其计划优化模块中使用线性优化的文档在此

Gurobi 文档此处

* [## 用 Python 和 Gurobi 优化周生产计划—第 1 部分

了解如何使用 Python 和数学求解器 Gurobi 解决优化问题。

towardsdatascience.com](/optimization-of-a-weekly-production-plan-with-python-and-gurobi-part-1-d1257ad29a9)*

预测土壤粘粒含量的弹性网络正则化优化

原文:https://towardsdatascience.com/optimization-of-elastic-net-regularization-for-predicting-soil-clay-content-7df09f6a68f8?source=collection_archive---------55-----------------------

建立了基于弹性网的正则化线性回归模型,从数百个 LIBS 光谱数据中预测土壤粘粒含量。

照片由 Heino Elnionis 拍摄

最近,大量研究致力于检验光谱和机器学习方法预测土壤颗粒大小的潜力——沙子、淤泥和粘土百分比。在这方面,LIBS 被认为是一种有用和有利的分析技术,因为它具有简单、快速、微创等特点,并且可以进行原位分析,无需进行土壤取样,而土壤取样通常既耗时又容易出错。在 LIBS,微等离子体是通过将高功率激光束聚焦到材料表面上产生的,以诱导特征原子发射线,从而能够直接确定材料的元素组成。

在本文中,从一个研究区域采集的 300 个土壤样本首先由 LIBS 进行分析,然后随机分为训练集(80%)和测试集(20%)。每个样品都有其相应的粘土含量,该含量是通过标准比重计方法预先确定的。然而,影响 LIBS 光谱数据建模的一个主要问题是“维数灾难”及其推论的多重共线性。为了解决这些问题,基于弹性网算法的正则化回归模型使用重复的双重交叉验证过程来开发。在该过程中,使用训练集进行 100 次重复的 10 重交叉验证,并使用测试集测试所得模型的预测能力。该过程以不同的随机分割重复 5 次。

超参数优化

弹性网是岭回归和 lasso 正则化之间的折衷,它最适合对具有大量高度相关预测值的数据进行建模。让我们考虑一个大小为 n × p 的数据矩阵 X 和大小为 n × 1 的响应向量 y ,其中 p 是预测变量的数量, n 是观测值的数量,在我们的例子中是 pn 弹性网络旨在最小化以下损失函数:

最小二乘优化问题。

其中,𝜆是正则化参数,𝛼是混合参数(或百分比)。𝜆参数是非负的,即𝜆 ∈ [0,∞)。当𝜆 = 0 时,正则化不起作用。换句话说,唯一的目标是最小化损失函数。当𝜆接近无穷大时,正则化效应增强,唯一的目标变成保持系数𝛽小,而不是最小化损失函数。而𝛼则是。当𝛼 = 0 时,弹性网与岭回归相同(一组相关预测因子的系数以类似的方式向零收缩),另一方面,当𝛼 = 1 时,弹性网与 lasso 相同(其中一个相关预测因子的系数较大,而其余的收缩为零)。

对这两个集合的笛卡尔积中的每一对(𝜆,𝛼)进行网格搜索以训练弹性网模型,并评估它们在来自训练集合的交叉验证上的性能,其中每对训练多个模型。最后,网格搜索算法输出在重复交叉验证过程中获得最高分数(RMSE)的设置。

我使用了介于 0.05 和 1 之间的 20 个𝛼值,以及介于 0.0001 和 10 之间的 300 多个𝜆值。给出最小交叉验证误差的(𝜆,𝛼)对的平均值为(0.0053±0.0005,0.90±0.03)。有趣的是,最终的模型接近 lasso,但弹性网比 lasso 更有优势,因为在我们病态的线性最小二乘问题中产生了超过 n 个非零系数。

优化故事:KKT 条件

原文:https://towardsdatascience.com/optimization-stories-kkt-conditions-f86aea4fb6c2?source=collection_archive---------10-----------------------

将 KKT 条件与最优化问题中的最优性联系起来

关键概念:互补松弛,对偶,对偶间隙,KKT 条件,拉格朗日函数,拉格朗日乘子,单纯形算法

这篇文章的目标是帮助读者理解上面的关键概念在最优化问题中的最优化搜索中所扮演的角色。在整篇文章中,我将以自上而下的方式涵盖所有概念,从最基本的问题开始:优化的目标是什么。

优化目标

优化问题的目标是在给定一定的约束条件下找到最佳解,或者在一定的时间内找到足够“好”的解,比如训练深度神经网络模型中的参数,使其损失函数最小(非凸优化问题)。下面的线性规划问题是前一种情况的例子。

对于线性规划问题,可以通过高效的 单纯形算法 找到最优解(如果存在)。对于问题(I),最佳解决方案是

单纯形算法和其他一些优化算法是迭代算法,从起点 x₀ ,在每次迭代中更新 x

直到找到最优解,或者满足某个停止条件。

但是我们怎么知道当前的解是最优解呢?这就是 KKT 的情况。

KKT 条件

卡鲁什-库恩-塔克(KKT)条件形成了线性和非线性规划的主干

  • 线性规划最优性的充要条件。
  • 凸优化中最优性的充要条件,如线性回归中的最小二乘最小化。
  • 对于非凸优化问题中的最优性是必要的,比如深度学习模型训练。

不等式约束线性规划的 KKT 条件

考虑下面的问题(II):

KKT 条件 : x 对前述问题最优当且仅当条件(1)-(3)成立。

条件(1)仅仅陈述了 x 是可行解,通常称为 初始可行性 。条件(2),通常称为 对偶可行 ,说明 x 也是对偶问题的可行解。 λv 称为 拉格朗日乘数 (或 对偶变量 )分别对应约束 Ax ≥ bx ≥ 0 。最后,条件(3)称为。具体来说,λ(ax-b)= 0 表示,在最优解 x ,不失一般性,要么【λᵢ】= 0,要么aᵢx =bᵢ(即)自然, vx = 0 也可以用类似的方式解读。**

重温问题(一)

**

对于线性规划,最优解(如果存在)总是位于顶点。在这种情况下,[0,0]、[4,0]、[4/3,8/3]和[0,2]是 4 个候选项。然后,我们可以使用 KKT 条件来验证哪一个是最优解。

对于[0,0]来说,绑定约束是 x₁≥ 0 和 x₂≥ 0,所以 w₁=w₂= 0 被互补松弛。但对偶可行性条件 λA+v=c 导致 v= (-1,-3),违反了另一个对偶可行性条件 v≥ 0。

类似的过程可以应用于其他 3 个顶点,直到我们验证[4/3,8/3]满足所有 KKT 条件,并声称它是最优解。

等式约束线性规划的 KKT 条件

考虑下面的问题(III):

KKT 条件 : x 对前述问题最优当且仅当*条件(4)-(6)成立。*

在看到问题(II)的 KKT 条件(1)-(3)后,(4)-(6)变得直观。鉴于问题(I)中的约束 Ax ≥ b 现在成为所有约束情形 Ax=b ,对应的拉格朗日乘子 λ 成为无限制。

非线性问题的 KKT 条件

考虑下面的非线性优化问题(IV):

**KKT 条件:条件(7)-(9)是 x 成为前述问题(IV)的最优解的必要条件。如果(IV)是凸的,(7)-(9)也成为充分条件。

(7)类似于(1),是 脑瓜子可行性 条件。先跳到条件(9),不等式约束的 互补松弛 条件gᵢ(x)≤**0,对应问题(二)中的条件(3)。

最后,(8)是 对偶可行性 条件保证对偶问题中的可行性。不难发现,问题(II)中的条件(3)是(8)的特例,与

λv分别代表 拉格朗日乘数 对于 Ax ≥ bx ≥ 0 ,我们有

条件(8)的第一部分也称为非线性优化问题的一阶条件。

值得一提的是,或者你可能已经注意到了,如果问题中的不等式约束是“≥”格式,那么对应的拉格朗日乘子是非正的。或者,您也可以将一阶条件更改为以下格式,以保持它们非负。

到目前为止,我们已经回顾了各种问题的 KKT 条件。虽然 原始可行性 条件相当直观,但问题是我们应该如何解释 对偶 可行性互补松弛 的最优性。

二元性

一个优化问题可以从两个角度提出,原始问题或对偶问题。有时,一个问题可以用对偶形式解决,这比用原始形式要有效得多。

对于极小化问题,其对偶形式的任何可行解都提供了其原始形式解的下界。因此,对偶最优解和原始最优解之间的差异称为 对偶缺口

对于线性问题和凸非线性问题,对偶间隙为零。对于这些问题,一个解不可能对原始和对偶都可行,除非它是最优解。因此,寻找最优性等价于寻找一个在原始和对偶中都可行的解。

线性问题

重温问题(二)

(二)的对偶问题是

由问题定义,我们有如下推论

因为线性问题的对偶间隙为零,所以我们有

这是原问题中的互补松弛条件。

非线性问题

重温问题(四)

给出了(IV)的对偶问题

对偶问题的目标函数又称为 拉格朗日对偶函数。 回想一下,拉格朗日函数的一阶导数,连同这两组约束,是非线性情况下的互补松弛度 的对偶可行性条件。**

互补松弛的经济学解释

互补的懈怠也可以用经济学的方式来解释。回想一下,在最优性条件下,互补松弛只要求以下两种情况中的一种适用于约束条件(在非退化情况下):

  • 约束是有约束力的(即平等)
  • 这个约束的拉格朗日乘数为零

如果我们将约束视为资源约束(例如,材料、空间、时间等)。)和拉格朗日乘数作为该资源的价值或价格,那么补充松弛度就是说:

  • 如果约束是有约束力的,这意味着我们在最大化目标时耗尽了这个资源。这意味着,如果我们拥有更多的这种资源,我们的客观价值就会增加。因此,这种资源是有价值的,它的价格(拉格朗日乘数)应该是正数。这就是为什么有时拉格朗日乘数也被称为影子价格。
  • 如果约束是非绑定的,那么就潜在的问题而言,这意味着这个资源是无用的。因此,它的价格(拉格朗日乘数)应该为零。

优化技术—模拟退火

原文:https://towardsdatascience.com/optimization-techniques-simulated-annealing-d6a4785a1de7?source=collection_archive---------1-----------------------

一种优化模型参数的流行方法

照片由克莱门特·HUnsplash 上拍摄

什么是物理退火?

照片由米盖尔·阿奎莱拉Unsplash 拍摄

模拟退火算法是基于现实生活中的物理退火。物理退火是加热材料直到其达到退火温度然后将缓慢冷却以将材料改变成所需结构的过程。当材料变热时,分子结构变弱,更容易发生变化。当材料冷却下来时,分子结构变得更硬,更不容易改变。

这种类比的另一个重要部分是来自热力学的以下方程:

这个等式计算能量大小增加的概率。给定一些能量大小和一些温度 t 以及玻尔兹曼常数 k ,我们可以计算出这个值。

模拟退火

模拟退火(SA)模拟物理退火过程,但用于优化模型中的参数。这一过程对于存在大量局部极小值的情况非常有用,这样像梯度下降这样的算法就会停滞不前。

局部极小值问题的例子

在类似上面的问题中,如果梯度下降从指定的起点开始,它将停留在局部最小值,而不能到达全局最小值。

算法

第一步:我们首先从一个初始解开始 s = S₀ 。这可以是符合可接受解决方案标准的任何解决方案。我们也从初始温度开始,t = t₀。

第二步:设置降温功能α。通常有 3 种主要的降温规则:

每种缩减规则以不同的速率降低温度,并且每种方法更擅长优化不同类型的模型。对于第三个规则, beta 是一个任意的常数。

步骤 3: 从初始温度开始,循环通过步骤 4 的 n 次迭代,然后根据α降低温度。停止该循环,直到达到终止条件。终止条件可以是达到某个最终温度、对于给定的一组参数达到某个可接受的性能阈值等。时间与温度的映射以及温度下降的速度称为退火程序

步骤 4: 给定解的邻域 N(s) ,选择一个解,并计算旧解和新邻域解之间的成本差。解的邻域是所有接近该解的解。例如,如果我们改变五个参数中的一个,但保持其余四个不变,则一组五个参数的邻域可能是。

第五步:如果新旧方案的成本差大于 0(新方案更好),则接受新方案。如果成本差异小于 0(旧的解决方案更好),则生成一个介于 0 和 1 之间的随机数,如果它低于根据之前的能量幅度方程计算的值,则接受它。

在模拟退火的情况下,该等式被修改为如下:

其中δc是成本的变化, t 是当前温度。

这种情况下计算出的 P 就是我们应该接受新方案的概率。

高温与低温

由于计算概率的方式,当温度较高时,算法是否更有可能接受更差的解决方案。这促进了搜索空间的探索,并允许算法更有可能沿着次优路径行进,以潜在地找到全局最大值。

给定温度为 0.9 的样本接受概率

当温度较低时,算法不太可能或不愿意接受更差的解决方案。这促进了利用,这意味着一旦算法处于正确的搜索空间,就没有必要搜索搜索空间的其他部分,而是应该尝试收敛并找到全局最大值。

给定温度为 0.1 的样本接受概率

一些用 SA 优化问题的例子

  • 旅行推销员问题
  • 调度问题
  • 任务分配
  • 图的着色和划分
  • 非线性函数优化

SA 的优势与劣势

优势

  • 易于实施和使用
  • 为各种问题提供最佳解决方案

不足之处

  • 如果退火计划很长,可能需要很长时间运行
  • 该算法中有许多可调参数

SA 的实施

这是模拟退火的一个样本样板实现。

结论

模拟退火是一种用于优化多参数模型的流行算法,可以相对快速地实现。如果需要多次迭代,模拟退火的计算量会非常大,但它能够找到全局最大值,而不会陷入局部最小值。

优化技术—禁忌搜索

原文:https://towardsdatascience.com/optimization-techniques-tabu-search-36f197ef8e25?source=collection_archive---------10-----------------------

一种优化模型参数的流行方法

Unsplash 上由 Carlos Muza 拍摄的照片

什么是禁忌搜索?

禁忌搜索是一种常用的元启发式算法,用于优化模型参数。元启发式算法是一种用于指导和控制实际启发式算法的通用策略。禁忌搜索通常被认为是将记忆结构整合到局部搜索策略中。由于局部搜索有很多局限性,禁忌搜索被设计用来解决这些问题。

禁忌搜索

禁忌搜索的基本思想是惩罚将解带入先前访问过的搜索空间的移动(也称为禁忌)。然而,禁忌搜索确实坚决地接受非改进解,以防止陷入局部极小值。

短期记忆和长期记忆

短期记忆基于出现的最近度,用于防止搜索算法重新访问之前访问过的解决方案,也可用于返回好的组件,以便定位和加强搜索。这是通过禁忌列表完成的,也称为强化

长期记忆基于出现的频率,用于多样化搜索,并通过避免探索区域来探索搜索空间中未被访问的区域。这是通过频率记忆实现的,也称为多样化

禁忌列表

禁忌表是利用短期记忆的基石。该列表存储固定数量的最近移动。在一些实现中,使用完整的解决方案来代替所使用的移动,但是如果由于空间限制,完整的解决方案非常大,这是不理想的。这些移动的一些例子是:

  • 交换图/旅程中的节点
  • 在 0 和 1 之间切换一点
  • 在图形中插入或删除边

禁忌占有制

禁忌占有期是一步棋在禁忌列表中停留的迭代次数。禁忌列表中的移动是不能再次进行的移动,因为它最近已经被访问过。有两种方法可以实现禁忌任期( T ):

  • 静态:选择 T 为常数(常为 sqrt(T) )
  • 动态:在某个 T_minT_max 之间随机选择 T

愿望标准

这是禁忌搜索的可选部分。作为期望标准一部分的移动或解决方案取消了禁忌,即使它在禁忌列表中,也可以进行移动。在禁忌列表禁止所有可能的移动的情况下,这也可以用来防止停滞。愿望标准的一些例子是:

  • 如果新的解决方案比当前的最佳解决方案更好,那么新的解决方案将被使用,即使它在禁忌列表中
  • 将禁忌任期设置为较小的值

储频装置

该内存保存了自搜索开始以来每个解决方案的总迭代次数。被访问次数多的解决方案不太可能被再次选择,并且会促进更多样化的解决方案。多样化有两种主要方法:

  • 重启多样化:通过从这些点重启搜索,允许很少出现在当前解决方案中的组件
  • 持续多样化:用这些移动的频率来偏向对可能移动的评估。不经常出现的移动将有更高的概率进行。

算法

第一步:我们首先从一个初始解 s = S₀ 开始。这可以是符合可接受解决方案标准的任何解决方案。

第二步:生成当前解 s 的一组相邻解,标注为 N(s) 。从这组解决方案中,除了符合期望标准的解决方案之外,禁忌列表中的解决方案将被删除。这组新的结果就是新的 N(s)

第三步:N(s) 中选择最佳解,并将这个新解标注为s’。如果s’的解优于当前最佳解,则更新当前最佳解。之后,不管 s' 是否比 s 好,我们把 s 更新为' s '

步骤 4: 通过移除所有超过禁忌期限的招式来更新禁忌列表,并将新招式【s’添加到禁忌列表中。此外,更新符合抽吸标准的溶液组。如果使用了频率记忆,那么也用新的解决方案增加频率记忆计数器。**

步骤 5: 如果满足终止标准,则搜索停止,否则将进入下一次迭代。终止标准取决于手头的问题,但一些可能的例子是:

  • 最大迭代次数
  • 如果找到的最佳解决方案优于某个阈值

使用 TS 解决的问题示例

  • n 皇后问题
  • 旅行推销员问题
  • 最小生成树
  • 分配问题
  • 车辆路线
  • DNA 测序

TS 的优点和缺点

优势

  • 可以通过选择非改进的解决方案来避免局部最优
  • 禁忌列表可用于避免循环和恢复旧的解决方案
  • 可应用于离散和连续解决方案

不足之处

  • 迭代次数可能非常高
  • 该算法中有许多可调参数

实施技术服务

这是一个 Tabu 搜索的样本实现。实际的实现取决于问题。

结论

禁忌搜索是一种流行的算法,用于优化多参数模型,可以产生异常的结果。尽管实现并不简单,需要调整,但是一旦创建了它,就能够解决各种各样的问题。

Python 中使用拉格朗日乘子的约束优化

原文:https://towardsdatascience.com/optimization-with-constraints-using-lagrange-multiplier-in-python-82769c9a43fe?source=collection_archive---------13-----------------------

具有 1 个等式约束的二元函数的拉格朗日乘子

作者图片

拉格朗日乘数法是一种在约束条件下优化函数的方法。在本文中,我将展示如何使用拉格朗日乘数来优化一个相对简单的例子,这个例子包含两个变量和一个等式约束。我用 Python 解决了一部分数学问题。

你可以在这里跟随 Python 笔记本。

举个例子,某公司的在线营销部门收到了一笔固定预算,用于社交媒体和电视宣传活动的组合:

  • 假设我们有 2500 美元的固定营销预算。
  • 假设我们可以选择投资两种类型的活动:社交媒体和电视,你必须做出决定
  • 简而言之,我们假设在社交媒体上的一次活动花费 25 美元,在电视上的一次活动花费 250 美元。
  • 假设我们在过去做了很多实验,我们已经能够将收入定义为两种媒体投资的函数。
  • 在这本笔记本中,我将展示如何使用拉格朗日乘数法找到最大收益和你应该购买的不同类型的活动的数量。

检查成本

成本的等式是:

25 美元乘以社交活动次数+ 250 倍于电视活动次数

由于我们想准确地花费预算,我们知道这等于 2500 美元,给出以下约束:

*25 *社交+ 250 电视= 2500

策划可能的预算支出方式

在下图中,我画出了不同的预算支出方式。由于预算是固定的,如果我们在社交活动上花更多的钱,我们自然会在电视活动上花更少的钱,反之亦然。

  • 线下的每个工时和材料组合都在预算之内。
  • 每一个超出预算的工时和材料组合都超出了预算。
  • 如果我们想花掉整个预算(我们通常会这样做),我们必须准确地在线上。

作者图片

检查收入

假设通过实验和分析,有人已经能够确定你的企业的收入曲线,它被定义为:

收入(以千美元为单位)是社交活动次数的 7 倍,电视活动次数的 3/4 倍,1/4 倍

这可以用 Python 函数来表示,如下所示:

问题的三维表示

在我们的练习中,我们有三个变量:收入、社会活动的数量和关于材料的电视活动的数量。当然,我们希望收入最大化。

我们还有一个预算约束,就是上面显示的 2D 线:我们可以花费的最大金额。
目标是在预算之内找到最大收益。

我将首先展示这个问题的三维表示,我们看到:

  • 社交活动和电视活动的 3D 收入。
  • 收入图表下方 2D 显示的约束行。

目标是确定 3D 曲线上的最高点,该最高点正好在约束线上。

作者图片

问题的 2D 表示

3D 看起来很酷,但相对难以阅读。因此,我制作了两个 2D 图,显示了完全相同的信息:不是将 Z 轴上的收入相加,而是将收入表示为颜色渐变(左)和轮廓渐变(右)。

目标保持不变:找到最高的收入,只要它低于预算约束线。

作者图片

视觉解决方案

如果我们检查图表(无论是梯度还是等高线),我们可以在红线(最大预算)上看到,最高收入值大约是 3 个电视广告活动和 70 个社交广告活动。

有了这第一个直观的估计是很棒的,现在让我们用数学找到确切的值。

数学解决方案

最大值在哪里?

我们需要找到收益曲线与约束线相切的点。我们使用的方法是拉格朗日乘数法。

简而言之,它的工作原理如下:
我们可以在收益等高线的梯度与约束线的梯度成正比的点上找到最大值。
你可以回头看看等高线图,看看这是不是真的。

如何表示比例性?

所以我们需要解决比例问题,而不是等式问题。
所以不是:“收入梯度”=“约束梯度”
而是:“收入梯度”与“约束梯度”成正比
我们在数学上这样表述
“收入梯度”=λ乘以“约束梯度”

这个λ使它成为一个比例的声明。
这个λ叫做拉格朗日乘数。

梯度是导数

在使用内置的 python 优化器之前,一个棘手的步骤是通过获得收入函数和约束函数的导数来获得梯度。因为每个变量有两个,我们需要两个偏导数来得到这两个导数的向量。

计算导数

在下图中,我展示了如何创建三个方程,我们可以在 python 求解器中传递这些方程。

  • 首先要做的是从收益函数和约束条件到它们的导数。
  • 然后设置收益函数的导数等于λ乘以约束的导数。这为求解器提供了前两个方程。
  • 第三个等式就是约束本身。

作者图片

现在我们有了三个方程,我们可以手动解出这个系统。或者,更简单的是,我们可以将它传递给 Python 的 sympy 解算器:

结论:

拥有:

  • 2500 美元的预算
  • 25 美元的社会活动费用
  • 250 美元的电视广告费用
  • 一个收入函数:
    收入(以千美元为单位)是社交活动次数的 7 次幂 3/4 次幂电视活动次数的 1/4 次幂

使用线性求解器,我们确定了 75 个社交活动和 2.5 个电视活动将获得最大收益。总收入(以千美元计)将为 224,即 224,000 美元:

我希望这篇文章阐明了如何在业务优化用例中使用拉格朗日乘数。当然,你可以很容易地将代码改编成另一组方程和约束,。现在,感谢阅读!

优化注释和训练:在线主动学习框架

原文:https://towardsdatascience.com/optimize-annotation-and-training-an-online-active-learning-framework-d1319d746b3f?source=collection_archive---------37-----------------------

作者图片

为生产简化您的机器学习项目。

Picsell.ia ,我们致力于提供以低成本构建计算机视觉系统的最有效方法。

众所周知,深度学习的标签和培训成本很高,但在过去的几年里,我们看到了有趣技术的出现,使它变得更加实惠。

今天,我将谈论其中的两个:

  • 主动学习
  • 在线学习

这可能会有点长,所以喝杯咖啡,准备好和我一起潜入 Picsell.ia 平台的幕后。

请注意,我们的在线主动学习框架在 Github 上发布于此:【https://github.com/PicselliaTeam/Online-Learning

主动学习的基本概念

2009 年结算

一个经典的监督模型通常会随着更多的标记数据而变得更加精确。然而,注释所有这些数据会花费大量的时间和/或金钱。根据您的目标、预算和时间限制,您可能会考虑减少要标记的数据数量。

主动学习的全部意义在于聪明地选择哪些数据需要被标记以及以什么样的顺序。大量研究论文已经证明,主动学习方法可以减少达到特定精度所需的训练数据量。

我将简要介绍主动学习的基本原理,因为有足够多的文章描述了这个过程,可能比我能描述的更好。

[## 主动学习:你的模特的新私人教练

首先,一些事实。事实:主动学习不仅仅是强化学习的另一个名称;主动学习不是…

medium.com](https://medium.com/@ODSC/active-learning-your-models-new-personal-trainer-a89722c0db5a) [## 主动学习导论

机器学习目前的实用性和可访问性部分是由于…

medium.com](https://medium.com/@ODSC/an-introduction-to-active-learning-d050beaa8882)

主动学习循环由三个主要步骤组成。

  • 第一个是注释数据集的子集
  • 然后,我们希望根据这些标记的数据训练一个模型
  • 最后,我们使用子集上训练的模型对未标记的数据池进行预测。

有了这些预测,我们使用一个采样方法对注释器进行查询(在文献中称为“ Oracle ”)。

最常用的一套抽样方法被称为“不确定抽样”。这些方法将关注模型的决策边界,并选择最不确定的数据。

罗伯特·芒罗的交互式不确定性采样热图

但是不确定性采样本身并不总是选择数据的最相关方式,因为你基本上是忽略了远离决策边界的未标记空间

这在文献中通常被称为“利用,然而你也需要对你的数据进行一些“探索”。

当你的模型在每次训练迭代中更新自己时,决策边界也在移动,这意味着你正在做一些探索。但是加入适当的探索方法是很重要的。

探索数据集最常见的方法是简单地混合“不确定性采样”和“随机采样”。通过这种方法,我们选择利用概率为 p 的数据(不确定性采样)和探索概率为 1-p 的数据(随机采样)。

存在更复杂和有效的探索方法,例如基于聚类的采样,但是我们今天不打算明确它们。

勘探和开采之间的平衡是该领域中常见的难题。

基本概念非常简单,但实现起来却很棘手:

  • 我应该选择哪种抽样方法?
  • 如何在数据集的探索和利用之间找到平衡?
  • 发送回 oracle 的项目数量应该是多少?
  • oracle 在等待查询时应该做什么?…

所有这些问题都没有最终答案。例如,您可能希望您的模型实时适应注释…或者您可能每年标记一批数据,因此您不需要经常更新您的模型。

在考虑主动学习的实际应用时,主要的实际考虑是:

“我会通过主动学习节省时间和金钱吗?”

的确,我们已经知道可以用更少的数据进行学习,但是实施主动学习很容易导致浪费时间

  • 检索带标签的数据
  • 初始化训练
  • 训练本身
  • 对未标记的数据进行预测并最终进行查询实际上比注释所有数据更耗时。

取决于你希望你的模型适应新的训练数据的速度,你在那里失去的时间可能是交易的破坏者。

就像我之前说的,这真的取决于你更新模型的频率。

事情是这样的,如果你有一个非常大的数据集要注释,并且不能全部完成,或者如果你想让你的模型用来自现实世界的新鲜数据不断学习,那么你可能要使用“在线学习”这是一个很大的词,可以说是实时学习,或者至少接近实时学习。

在线学习

在线学习的原则是一旦新的训练数据可用就训练你的模型,而不需要在每次迭代中重新初始化所有变量,并且总是将它保存在内存中。

这与标准方法相反,在标准方法中,您在开始培训之前已经准备好了所有的培训数据。
通过这种方法,你的模型可以实时适应新数据(或者如果你决定进行批量在线学习,几乎可以适应)。

实时学习的主要挑战是实现而不是概念。

缺点

如果不在每次迭代中对整个数据集进行训练,在线学习很容易忘记以前的数据。

事实上,如果你只对新的例子进行训练,就像每次都用以前的数据获得的权重进行迁移学习一样。其中随着时间给予旧数据的权重越来越小。

反过来的危险是,如果你每次都用所有的数据进行训练,在某个时候你的数据集的大小将无法再被处理,而且你的模型会认为你的旧数据仍然和你的新数据一样相关,这可能会在现实世界中导致大问题。

在多个 GPU 实例上进行水平扩展也很困难

但是,一旦您完成所有设置(我们将随时为您提供帮助),您将很快看到显著的优势!

将主动学习与在线学习相结合

是时候总结一下我们在本文中看到的内容了:

  • ****主动学习允许我们对未标记的数据集进行查询,以减少达到特定性能阈值所需的数据量。
  • 我们还看到,我们可以实现在线学习来使我们的模型实时适应输入数据流。

两者结合呢?

我们之前提出的所有关于主动学习的问题仍然适用。
但这将导致更多问题,如:

  • "在将数据发送到模型之前,需要缓冲多少数据?"
  • "我应该每次都训练整个数据集,还是只训练新收到的数据?"
  • “我应该持续训练并动态添加新数据,还是在每次迭代后等待新数据的到来?”

这就是为什么我们想提出一个 小型开源框架 来试验在线主动学习(在计算机视觉上)并防止您在试图回答这些问题时遇到很多麻烦!

我们的框架

这是一个有两个服务器的小型网络应用程序,一个在后面有一个用于分类和主动学习的最小标记应用程序,另一个则训练模型。

作者图片

目前只支持图像分类,但是我们很快会添加一个物体检测后端!(当 Tensorflow 对象检测 API 更新到 TF2 -里程碑:2020 年 7 月 8 日)

想法是在总是注释数据的同时训练和进行主动学习查询。通过使用我们的框架简化流程,即使主动学习策略不成功,你也不会浪费时间。但是如果你尝试我们的工具并找到好的策略,你可以为你的整个项目节省多达 5 倍的时间!****

您可以使用不同的参数来调整您的在线主动学习策略,例如:

  • 发送新数据前的缓冲区大小
  • 模型
  • 抽样方法...

但是你也可以在标准不确定性采样方法之间切换。

我们将增加更多的回购,但你也可以很容易地定义你的。

以下是您目前可以找到的内容:

  • 熵抽样
  • 最小置信抽样
  • 置信区间抽样
  • 置信抽样比率
  • 不确定性+随机抽样

我们添加了一个简单的函数,允许利用概率 p 随机化不确定性采样方法。

有了这个框架,我们希望任何人都可以学习如何有效地训练模型,也许可以回答我们之前提出的问题,但它也给你一些直觉,告诉你如何更好地为不同的用例选择参数。

如果你想给我们关于框架的反馈,你可以在 Github 上写一个请求。在您的帮助下,我们很高兴能进一步发展!

与此同时,请关注我们以获取更多关于机器学习或计算机视觉的文章,加入 Picsell.ia 并访问我们的开放简历平台,其中包含大量免费数据集和预训练模型!

资源

[1]罗伯特·芒罗,循环中的人类机器学习 (2021)

[2] A. Bondu,V. Lemaire,M. Boullé,主动学习中的探索与利用:贝叶斯方法 (2010)

[3] 调查毛刺落定,主动学习文献 (2010)

使用数据操作技巧优化选秀王 NBA 阵容

原文:https://towardsdatascience.com/optimize-draftkings-nba-lineups-using-data-manipulation-skills-fdf47b2a27e5?source=collection_archive---------37-----------------------

编程;编排

R 中数据操作的实用指南

免责声明 本帖唯一目的是展示 R 中的数据操作技巧;它不应作为任何形式的投资建议或认可。投资伴随着风险!

迪安·贝内特在 Unsplash 上的照片

终于,运动回来了!

NBANFLMLB 回来了!

所以像 DraftKings 这样的在线博彩网站。一边看着你最喜欢的球员赢得比赛,一边和朋友一起存点钱,这才是正确的做法!

我的阵容策略是分析玩家最近的表现,挑一个手热的下注。然而,不可能只选择最热门的球员,像勒布朗詹姆斯,安东尼·戴维斯,尼古拉·约基奇等。,谁来工资高。作为一个限制, DraftKings 有 5 万美元的工资帽。如果你选择了三名顶级球员,而让其他人都坐冷板凳,薪水不低,却没有上场时间,这不会是一个胜利的阵容策略。

为了找到手热工资合理的球员,我随手找到了 R 中的 dplyr 库。在这篇文章中,我们学习了一些数据分析和阵容建设的技巧。

学习编程的推荐方法是通过实践!

有趣的编码方式就是从中赚几个钱!

照片由埃德加·恰帕罗Unsplash 上拍摄

让我们开始吧。我们将在分析 9 月 18 日洛杉矶湖人队对丹佛掘金队的比赛中球员的表现后,提出第二场比赛的阵容,并与 9 月 20 日的实际表现进行交叉检查。

数据集

有两个数据集:Basic _ Infor _ Game _ 1Actual _ point _ Game _ 1)。我强烈建议下载这两个数据集,并随着我们的继续复制代码。

#1 data preparation # load the dataset 1
Basic_Infor_Game_1 <- read.csv('Basic_Infor_Game_1.csv')# load the dataset 2
Actual_point_Game_1 <- read.csv('Actual_point_Game_1.csv')# merge the two datasets according to players' names
game_one_9.18 <- merge(Basic_Infor_Game_1,Actual_point_Game_1,by.x= 'Name', by.y ="Player")head(game_one_9.18)

注意事项

Name: players’ names Position: what position they playSalary: the salary assigned to the playerAPPG: average points per game Drafted_perc: the percentage of users drafted this playerActual: the actual points scored for Game 1

正如你在上面看到的,有太多我们不需要的还原剂变量。首先,我们只能选择关键变量。

#2 load the library: dplyr
library(dplyr)merged_9.18 %>% 
  select(Name, APPG, Actual)

好多了,干净多了!

球员越优秀,薪水越高,得分也越高。问题是如何对照他们的工资来评估他们的表现?换句话说,顶级球员提供的积分工资值和替补球员一样吗?

为了回答这些问题,我们创建一个名为Actual _ predicted _ ratio的新变量,通过实际得分(实际得分)和预测得分()的平均值之间的除法来计算。这个比率是一个很好的指标,表明球员的表现或与平均表现的偏差。**

以降序方式重新排列结果,仅显示前 10 个案例。

**merged_9.18 %>% 
  select(Name, APPG, Actual) %>% 
  mutate(actual_predicted_ratio = Actual/APPG) %>%
  arrange(desc(actual_predicted_ratio)) %>% 
  head(10)**

最后一列 实际 _ 预测 _ 比率 ,按降序排列。在上面,迈克尔·波特是得分率最高的球员,为 1.808456,这意味着 MP 的得分几乎是他场均得分的 1.8 倍。

太棒了。

肯塔维奥斯·卡德维尔·波普和拉简·朗多分别位居第二和第三。

然而,这不是超级有用的,因为 DraftKings 只允许 6 个玩家玩他们的 showtime 游戏。如果我们根据实际预测的比例来选择前 6 名球员,我们将无法选择像安东尼·戴维斯和詹姆斯这样的球员。

我们根据分数对玩家进行排名,选出第一场比赛的前 10 名。

**## Top 10 players who scored the most
top_10_scored_players <- game_one_9.18 %>% 
  select(Name,Salary, APPG, Actual) %>% 
  arrange(desc(Actual)) %>% 
  head(10)
top_10_scored_players**

安东尼·戴维斯和勒布朗詹姆斯高居榜首!

同样的,我也在想谁是选秀最多的球员。

**## Top 10 most drafted players
game_one_9.18 %>% 
  select(Name,Salary, APPG, Drafted_perc) %>% 
  arrange(desc(Drafted_perc)) %>% 
  head(10)**

雄心勃勃的球员薪水更高,这限制了我们阵容中顶级球员的数量。所以,我们可以使用 过滤器 选择各个薪资区间的球员。

我把顶级玩家定义为那些薪水在 8000 美元或以上,但仍超出预期的人。

**## Top players with high salary cap (>=8k) and still beat expectation game_one_9.18 %>% 
  select(Name,Salary, APPG, Actual, Drafted_perc) %>% 
  mutate(actual_predicted_ratio = Actual/APPG) %>% 
  filter(actual_predicted_ratio>=1 & Salary>=8000) %>% 
  arrange(desc(actual_predicted_ratio))**

只有迈克尔波特和安东尼·戴维斯在第一场比赛中有这样的表现。特别是,戴维斯有 10800 美元的高薪,仍然能够以超过平均得分 1.1 倍的成绩超出预期。这显示了他的出色表现,使他成为一个明确的选择。

尽管波特有显著的优异表现,但他在最后一节用大量的垃圾时间得到了他的大部分得分。数据告诉你,如果比赛很紧张,他可能是一个可疑的选择。

对于我们的价值型打法,让我们看看$3,000 到$8,000 范围内的玩家。

**## Good value players (3k-8k) and still beat expectationgame_one_9.18 %>% 
  select(Name,Salary, APPG, Actual, Drafted_perc) %>% 
  mutate(actual_predicted_ratio = Actual/APPG) %>%# new variable: actual_predicted_ratio
  filter(actual_predicted_ratio>=1 & Salary>=3000 & Salary<8000) %>% 
  arrange(desc(actual_predicted_ratio))**

这五名球员有很好的价值,我们可能会考虑在第二场比赛中再次选中他们。

阵容建设

核心球员:安东尼·戴维斯→勒布朗詹姆斯→尼古拉·约基奇→贾马尔·穆雷

价值球员:肯塔维奥斯·卡德维尔·波普→拉简·朗多→丹尼·格伦→德怀特-霍华德→阿莱克斯-卡鲁索

我会包括两个核心球员(戴维斯是我的最爱)和两个或三个价值球员,最后一个位置来自其他廉价球员。

NBA 季后赛竞争激烈,球员往往会在一场比赛和另一场比赛之间波动。不确定是不可避免的。我的应对策略是通过混合和匹配核心与价值参与者来整合不确定性和风险。

事实证明,这些玩家在第二场比赛中获胜。

(我保证在写这篇文章的时候,我没有挑选任何提到他们在第二场比赛中表现的球员)。

免责声明 本帖唯一目的是展示 R 中的数据操作技巧;它不应作为任何形式的投资建议或认可。投资伴随着风险!

喜欢读这本书吗?

请在 LinkedInYoutube 上找到我。

还有,看看我其他关于人工智能和机器学习的帖子。

用 DGL-柯优化知识图嵌入

原文:https://towardsdatascience.com/optimize-knowledge-graph-embeddings-with-dgl-ke-1fff4ab275f2?source=collection_archive---------48-----------------------

了解软件优化,以加速知识图嵌入的训练,并在几分钟内训练你的第一个模型与 DGL 柯

作者:Cyrus Vahid,首席解决方案工程师,郑达,乔治·卡里皮斯和巴拉吉·卡马科蒂:AWS AI

介绍

在我们的上一篇文章中,我们介绍了知识图嵌入(KGEs)的概念,以及在 DGL-柯中用来生成它们的两个流行模型。这篇博客概述了 DGL-克如何加速 KGE 的训练。我们还分享了一个读者可以在本地机器上运行的例子。

什么是 DGL 柯

综上所述,DGL-克是一个高性能,易于使用,可扩展的工具包,用于从大型图中生成知识图嵌入。它建立在深度图形库 (DGL),一个实现图形神经网络(GNN)的开源库之上。

如上图所示,DGL-克实现了一些最流行的知识嵌入模型,如 TransE、TransR、RotateE、DistMulti、RESCAL 和 ComplEx。

挑战

尽管有多种模型可用于生成嵌入,但是训练这些嵌入对于大型图来说要么是耗时的,要么是不可行的,原因有两个:

  • 大小:很多知识图有几百万个节点,几十亿条边,几万个关系。这种规模的图的训练嵌入需要的计算资源远远超过任何单个机器的能力。因此,计算必须分布在不同的设备上。这尤其困难,因为这些设备需要平衡工作负载并减少数据移动开销。
  • 稀疏度:知识图通常有很多缺失的边,一些关系很少被观察到。这使得很难训练涉及少数关系的实体的嵌入和不经常观察的关系的嵌入。

本博客的其余部分将探讨 DGL-柯为应对这些挑战而实施的这些优化。但是在我们探索这些优化之前,让我们回顾一下训练 KGEs 所需的硬件基础设施。

硬件要求

在大型图上训练 KGEs 需要大量的硬件资源,比如多核 CPU 机器、多 GPU 机器和机器集群。目前支持的三种主要配置是:

  • 单个共享内存多核机器( 多核 ),其中同一机器上的几个核心用于训练。
  • 具有多个 GPU(多 GPU )的单个共享内存多核机器,其中使用同一机器上的多个 GPU。
  • 一个多核机器集群( 分布式 ),其中多个共享内存多核机器 CPU 机器用于训练一个嵌入。

DGL-科为所有这些硬件配置提供统一的软件优化,以高效地培训 KGE。

KGE 培训概述

对于所有的硬件配置,训练过程从分割 KG 的预处理步骤开始,然后是小批量训练。您可以使用此资源了解更多关于小批量训练的信息。分割步骤将 KG 中不相交的三元组集分配给设备。小批量训练执行以下步骤:

  • 从属于某个进程的本地分区中采样三元组以形成小批量,并为正三元组构造负样本。
  • 从全局实体和关系嵌入张量中获取小批量中涉及的实体和关系嵌入。
  • 对上一步提取的嵌入执行前向和后向传播,以计算嵌入的梯度。
  • 应用梯度来更新小批量中涉及的嵌入。该步骤需要应用优化算法来调整梯度,并将梯度写回全局实体和关系嵌入张量。

DGL-克对每一步都进行了优化,以加速训练。

优化数据分布

在训练过程中,每个设备上的小批量计算需要访问与 KG 相关联的数据——实体和关系嵌入。将这些数据放在正确的位置,并协调其访问和更新对 DGL-柯的性能至关重要。

  • 在多核系统中,实体和关系嵌入驻留在系统的共享内存中。所有流程都可以有效地访问它来生成小批量,读取嵌入内容,并更新它们。
  • 在多 GPU 系统的情况下,由于实体嵌入太大而不适合 GPU 内存,因此它们与知识图一起保存在多核系统的共享内存中。然而,为了减少数据传输,关系嵌入被存储在 GPU 存储器上。GPU 进程从多核系统的共享内存中读取和更新小批量中涉及的实体嵌入。
  • 分布式系统上的培训是不同的,因为我们需要分割数据并最大化每台机器的数据局部性。DGL-凯通过使用最小割图分割算法来实现这一点,以平衡负载和最小化通信的方式在机器之间分割知识图。此外,它使用每台机器的 KV-store 服务器来存储对应于分配给它的节点的实体的嵌入。然后,训练器进程使用 API 来获取嵌入数据并将更新(渐变)发回。

下图以图形方式说明了这些数据分布的执行情况。

负采样

DGL-柯为每个三联体构建了大量的负样本。总是使用系统 CPU 执行采样。如果负样本是独立构造的,将导致跨硬件访问大量实体。为了减少数据通信,我们对一批中的边的负边进行联合采样,使得一批中被访问的实体的数量不会由于负采样而急剧增加。
由于度数较高的节点需要更多的数据来发现更多的模式,我们执行与节点度数成比例的负采样。这导致产生阴性样本。这些硬阴性样品通常会提高 KG 包埋的质量。

分割关系

KG 中的实际关系相对于批量大小的比率越大(≈1000≈1000),关系嵌入越稀疏。DGL-克采用稀疏关系嵌入读取和更新来提高通信效率。在多 GPU 训练中,DGL-克将关系进行分组,将一个组分配给一个 GPU,以减少 CPU 和 GPU 之间的数据通信。

渐变更新

DGL-克使用 CPU 对小批量进行采样,并加载实体嵌入,然后将其发送到 GPU 进行梯度计算。一旦 GPU 完成了嵌入梯度的计算,它会将它们发送到 CPU 以更新相应的嵌入。这意味着,如果一个进程串行运行,GPU 必须等待 CPU 创建一个小批量,并向嵌入中写入梯度。为了防止 GPU 闲置,DGL-柯将 CPU 中的小批量创建和梯度更新与 GPU 中的小批量计算重叠。

由于关系划分,DGL-克将关系嵌入保存在 GPU 中,并与 CPU 中的实体嵌入分开更新。更新实体嵌入被卸载到每个训练者的专用过程。这种优化在 Freebase 数据集上为许多 KGE 模型提供了 40%的加速。

训练你的第一个知识图嵌入

安装 DGL-科

如果您的机器上安装了 conda ,使用以下命令创建一个环境:

:~$conda create -n dgl_pytorch python==3.8:~$conda activate dgl_pytorch(dgl_pytorch)…:~$

在机器上安装合适版本的 PyTorch 。如果您使用的是 Mac,您可以使用

(dgl_pytorch)…:~$conda install PyTorch torchvision -c PyTorch

我用的是 Ubuntu 机器,配有 4 个 GPU 和 CUDA 10.0,所以我运行的是:

(dgl_pytorch)…:~$conda install PyTorch torchvision cudatoolkit=10 -c PyTorch`

测试您的安装

(dgl_pytorch)…:~$python — version` #should output Python 3.8.0(dgl_pytorch)…:~$python>>>import torchtorch.__version__ #outputs the version number of PyTorch you have installed. Mine is ‘1.5.0’>>>quit()

安装 DGLDGL 克:

(dgl_pytorch)…:~$pip install dgl dglke

测试您的安装

(dgl_pytorch)…:~$python>>> import dgl>>> import dglke>>> dgl.__version__, dglke.__version__ #It should output versions of dgl and dglke respectively. Mine is: (‘0.4.3post2’, ‘0.1.0’)>>>quit()

让我们做一个快速测试

# create a new workspace(dgl_pytorch)…:~$mkdir my_task && cd my_task# Train transE model on FB15k dataset(dgl_pytorch)…my_task:~$DGLBACKEND=pytorch(dgl_pytorch)…my_task:~$dglke_train — model_name TransE_l2 — dataset FB15k — batch_size 1000 \ — neg_sample_size 200 — hidden_dim 400 — gamma 19.9 — lr 0.25 — max_step 500 — log_interval 100 \ — batch_size_eval 16 -adv — regularization_coef 1.00E-09 — test — num_thread 1 — num_proc 8 — — — — — — — Test result — — — — — — — Test average MRR : 0.47339627234644155Test average MR : 58.33693352067851Test average HITS@1 : 0.2806791826784717Test average HITS@3 : 0.6246889336561088Test average HITS@10 : 0.7729342655448528 — — — — — — — — — — — — — — — — — — — — -

刚刚发生了什么?

首先,我们将 DGL 的后端设置为 PyTorch 。然后,我们使用 dglke-train 创建了一个训练任务。这个训练任务使用带 L2 损耗的 TransE,下载 FB15k 数据集。然后,我们指示模型构建 k=200k=200 个负样本,其中γ=400 用于嵌入维度,1000 用于小批量大小(batch_size 1000),batch_size_eval=16 作为用于测试的超参数。

下一步是什么?

了解更多关于DGL-柯DGL 的信息,并继续关注更多的例子。

在 Jupyter 笔记本中优化 Python 代码

原文:https://towardsdatascience.com/optimize-python-code-in-jupyter-notebook-9df92832a23e?source=collection_archive---------11-----------------------

无聊地等待缓慢的 Python 作业完成?让我们找到瓶颈并优化它。

PIRO4DPixabay 上制作的视频

想在 Jupyter 笔记本里让一个慢的 Python 代码变快?以 sum aggregate 为例,我们将使用%%time测量运行时间,并使用%lprun行分析器找到瓶颈。

要优化的函数:Sum 聚合

假设 Pandas 没有 group-by 和 aggregate 函数,我们需要自己实现它。我们希望按名称聚合上表,并计算值的总和。

也许,在我们的第一次迭代中,我们会产生如下代码。我们在字典的帮助下汇总该值(命名为⇨值)。通过迭代每一行,我们更新了字典的值。在迭代结束时,我们将字典转换回 Pandas 的数据框架。

在我们优化代码之前,我们需要问:“我们真的需要优化代码吗?为什么?”如果我们花更多的时间来优化,而不是多等一会儿来完成工作,这是不值得的,不是吗?

"过早优化是万恶之源."—姜懿翔·克努特

现在,让我们假设 sum aggregate 代码太慢,我们需要优化它。我们如何做到这一点?

原则 1:我们不能改进我们不能测量的东西

“如果你不能衡量它,你就不能改善它。”—彼得·德鲁克

我们需要测量代码运行时间的能力来比较优化前后。我们有可能让事情变得更糟,特别是如果我们使用像 Numpy 和 Pandas 这样的外部库。我们不知道这个库是如何实现的。

前缀为%%的代码是 IPython cell magic-function。我们可以通过向单元添加%%time来测量单元的运行时间。我们不需要为此安装任何新的库。我们只需要导入time,它是 Python 标准库的一部分。

**%%time** sum_aggregate_1(df, 'name', 'value').sort_values('value', ascending=False).head()

sum_aggregate_1 的运行时间

实测运行时间约为 38 s,现在我们需要优化哪个部分?如果是我在猜,我会选择优化time.sleep()部分。似乎显而易见。基于直觉的优化可能最终没有显著的改进,只是浪费时间。我们需要找到瓶颈。

原则 2:优化瓶颈

"除了瓶颈之外,任何地方的改进都是一种幻觉."—吉恩·金

优化不是瓶颈的代码部分不会显著减少总运行时间。这就是为什么吉恩·金说,改进只是一种错觉,毫无用处。怎么才能找到瓶颈?

我们可以使用line-profiler库来获得每一行的执行时间。我们需要安装line-profiler。之后,我们需要用%load_ext导入魔法功能。

! pip install line-profiler
%load_ext line_profiler

我们需要向线路分析器提供function to profileexecution trigger参数。在我们的例子中,我们想要分析的函数是sum_aggregate_1,我们用sum_aggregate_1(random_df, 'name', 'value)触发执行。

# %lprun -f [function to profile] [execution trigger]
# [function to profile]: sum_aggregate_1
# [execution trigger]: sum_aggregate_1(random_df, 'name', 'value')%lprun -f sum_aggregate_1 sum_aggregate_1(random_df, 'name', 'value')

从结果中,我们可以看到该函数的主要瓶颈在第 4 行。现在,我们知道DataFrame.iterrows()对于迭代来说非常慢。它花费了 66%的执行时间。

在我们发现瓶颈之后,我们可以继续优化代码。我们可以简单地从搜索引擎中找到DataFrame.iterrows()的替代品。

一种替代方法是将键和值列作为 Numpy 数组。之后,压缩两个 Numpy 数组并遍历它。我们可以观察到瓶颈现在正从迭代部分转移到time.sleep()部分。总运行时间从 38 秒减少到 7 秒

通过反复寻找和优化瓶颈,我们首先进行最有效的优化。这就像使用“贪婪算法”的思维模式来确定优化的优先级。当代码运行时足够快时,我们可以停止优化,尽管做进一步的优化很诱人。

最后一个音符

进行优化时,需要记住三件非常重要的事情:

  1. 在真正需要的时候进行优化 如果代码不值得你花时间去优化,那就不要去优化,因为这样做不但不会使代码变得更快,反而有可能引入新的 bug。
  2. 我们无法改进我们无法衡量的东西 首先,我们必须选择我们想要优化的指标。之后,我们需要找到如何衡量它。目前,我们试图优化运行时间。在其他情况下,我们也可以选择优化内存使用。
  3. 优化瓶颈
    我们可以使用line-profiler库来找到瓶颈。

你可以从我的 Google Colab 笔记本中获取并运行上面的所有代码。从笔记本中,你可以看到我们如何分析一个类方法的例子。有一个例子可以说明如何分析触发函数调用的另一个函数。

感谢阅读。希望这能帮助你在代码太慢的时候优化代码。如果您有任何建议或反馈,请留下评论或留言。

使用数据驱动策略优化贷款组合

原文:https://towardsdatascience.com/optimizing-a-loan-portfolio-using-a-data-driven-strategy-92e46b790bf0?source=collection_archive---------21-----------------------

金融分析师可以基于以数据为中心的策略和定量算法优化贷款组合吗?

作者:诺亚·穆赫塔尔沙恩·科利沙赫尔·亚尔·贾汉吉尔拉米·哈曼

(负空格,像素 2020)

(期待最好的,Pexels 2020)

银行害怕 P2P 借贷吗?

虽然传统上银行是贷款的主要提供者,但小企业的需求正在发生变化,现在有了更多的顾虑。

2020 年带来了运营成本的飙升和需求波动的加剧。

这些是中小企业在融资时面临的一些极端挑战,而融资是它们增长的一个关键因素。银行经常忽略这些,结果,这为 P2P 借贷市场的发展打开了大门。

这就是为什么我们要为 P2P 贷款公司 Prosper market place 创建一个数据驱动的投资策略,该策略将从处理原始数据到推断业务结果进行全面概述。

总的来说,我们的预测模型将作为规定工具,直接描述对投资者&业务的影响。

投资者决策

投资者需要两个基本步骤来更好地了解投资哪笔贷款:

  1. Prosper 的投资者将不得不决定投资多少资金(考虑潜在回报)并分配给其他投资选项。
  2. Prosper 的投资者将需要决定选择“好”贷款(即:最终将完全还清的贷款)进行投资,这是我们的贷款分类模型将关注的重点。

然而,重要的是要注意,没有一个理想的投资,因为它在很大程度上取决于投资者的风险偏好。

资料组

使用注册的 Prosper 帐户,可在线下载本次分析中使用的数据集。

预测器

该数据集包含每年公布的所有贷款的综合信息和一组涵盖单笔贷款不同属性的 22 个变量。

Prosper 数据集描述(22 个变量)

这些信息包括但不限于贷款金额、支付的利息&费用金额、贷款期限、Prosper 信用评级得分以及贷款状态及原因(如果已完成或违约)。

已完成贷款与违约贷款:0s 与 1s

在 Prosper 的数据中,贷款有 4 种结果:

  1. 已完成(A)
  2. 注销(B)
  3. 电流(摄氏度)
  4. 默认(D)

为了简化我们的 Prosper 数据分析,我们决定将值 0 分配给已完成的贷款(A) ,将值 1 分配给剩余的 3 种贷款状态 (B,C,& D) ,它们指的是尚未完成的贷款。

我们如何识别“好”的贷款?

为了获得识别良好贷款的直觉,认识到所有变量之间的相关性和相互作用是很重要的。

然而,良好贷款的定义仍然相当模糊,因此预测应该基于这些目标之一是至关重要的:贷款是否会违约,提前偿还,违约时间,或者如果提前偿还,偿还所需的时间。

数据探索

分析贷款条款

每种贷款的每期贷款金额的小提琴图

该图显示了 60 个月期限(更长的期限)的一些有趣的见解,例如完成贷款和未完成贷款的最高贷款金额约为 15,000 美元。不出所料,借款人倾向于接受更高的贷款额来偿还长期贷款。

而 36 个月期限(较短期限)的贷款往往金额小得多,而且更一致地分布在已完成和未完成贷款中。

分析每个贷款状态的利率分布

每个等级每个贷款状态的利率小提琴图

构建了另一个小提琴图,显示了每个等级类型的每种贷款状态的不同利率水平(范围从 AA-HR:最高等级到最低等级)。

已完成(0)和未完成(1)的较高等级贷款的利率较低,这种趋势对于两种贷款状态都是一致的。

数据泄露

当使用在未来预测时不可用的预测器构建模型时,会出现这种现象。因此,我们需要忽略这些预测因素,以防止我们的模型出现偏差。

关于如何识别泄漏,主要有两种情况:

1.与目标变量高度相关的预测值。我们将使用所有 22 个预测因子的热图或相关矩阵来检验这一点。

2.在总回报预测期间,预测器信息不可用,例如,late _ fees _ paid 变量。

相关热图

不出所料,我们注意到与数据泄露相关的变量,如支付的利息和支付的本金,与贷款状态有很高的相关性。

基于这种泄漏的定义以及在预测贷款是否会违约时大多数泄漏都不可用的事实,我们忽略以下预测因素:

贷款数量、逾期费用、账龄、逾期天数、发起日期、本金余额、已付本金、已付利息、逾期费用、已收债务、销售收入、贷款违约原因、贷款违约原因、描述、下一次付款到期日期、下一次付款到期金额、共同借款人申请

投资者回报的计算

确定给定贷款的潜在回报所需的最重要数据是每笔贷款收到的总付款的计算

为了建立一个有效的投资策略,我们需要在每笔贷款的回报金额上建立一个强有力的指标变量。至关重要的是 回报应考虑部分偿还的违约贷款和在到期日之前已经偿还的贷款

一般来说,使用以下变量可以创建三种有效的回报标准:

1.由变量 p 表示的总支付账户

2.用变量 f 表示的(借款人借入的金额)贷款的总投资额

3.以月为单位的贷款名义期限(贷款期限),以变量 t 表示

4.用变量 m 表示的贷款的实际月长度(贷款长度

我们的三大投资策略

我们将通过 3 种不同策略下的场景测试来计算预期收益:

1)悲观(M1)

悲观的方法指出,当贷款偿还后,投资者仍然不能再投资,直到贷款期限到期。

悲观逼近公式

使用等式 1,我们的团队能够创建一个新变量,称为:“ ret_PESS ”。

值得注意的是,这种方法有利于长期贷款,因为损失在更大范围内蔓延,贷款会提前违约。

2)乐观(M2)

乐观的方法是,一旦偿还了贷款,投资者的钱也就回来了,投资者可以立即投资于另一笔同样回报的贷款。

乐观接近公式

使用等式 2,我们的团队能够创建一个名为:" ret_OPT "的新变量。

这种方法可以重新表述为贷款在有效期间的年月度回报。然而,它受到一种假设的困扰,即资金可以以相同的利率进行再投资,如果贷款提前违约,损失可能是对负回报的严重高估。从好的方面来看,使用这种方法,短期和长期贷款得到了同等对待。

3)固定地平线(M3)

固定期限方法包括计算 3 种不同利率的固定时间回报:1%,3%和 6 %。

固定水平接近公式

构建了一个名为 ret_method_3() 的函数来复制等式 3,并计算数据集中每笔贷款的 3 个新变量。

通过平衡贷款期限和违约贷款之间的差异,这种方法可能是最准确的。然而,它倾向于忽略货币随时间的贬值价值。

繁荣等级(等级)明细

对 prosper 信用评级(“等级”)变量进行了更深入的研究,以探索每种回报类型(M1-M3)的任何重大趋势。

Prosper 等级汇总统计

等级越高,违约比例越小,利率也越低。

平均回报率%非常一致,不同等级的回报率略有上升。此外,任何级别都没有负的平均回报值。

解决平衡数据集选项

对每种类型的贷款状态数量进行快速计数显示,与未完成贷款相比,已完成贷款的数量明显更高,这表明数据集中的类别不平衡。

因此,最有可能的选择是尝试重新平衡数据集,使其包含 50%的已完成贷款和 50%的未完成贷款。然而,这样做可能被证明是有害的,并导致平均回报为负,完全违背了吸引潜在投资者签约繁荣的目的。

因此,为了捕捉真实的趋势和真实的比例,对数据集进行物理平衡会妨碍对分析的实际理解。

相反,将在模型构建阶段使用校准曲线测量来检查构建的模型是否因数据不平衡而有偏差。

预测模型分析

预测建模将包括两个阶段的方法:

首先,我们将构建一个二元分类模型,使用各种行业标准算法预测贷款违约概率,并评估最佳和最准确模型的性能。

第二阶段涉及使用各种行业标准回归器构建回归模型,以预测每种回报方法(M1-M3)下贷款可能为投资者产生的回报金额。

两个阶段的模型都将通过交叉验证的超参数调整进行优化,以获得更高的精度。

第一阶段:贷款结果分类

第一个模型是确定贷款的等级利率的预测能力,这通常是行业的标准做法。

蓝色:违约贷款|红色:已完成贷款[利率]

预测指标: 等级&利率

1 号模型—准确率:85%

这意味着这两个特征单独有助于成功地确定贷款状态,就像使用所有的预测指标一样。

然而,为了建立一个更健壮的模型并避免欠拟合,我们必须完全放弃这两个特性。

预测指标:所有不包括等级&利率

2 号模型——准确度分数:~85%

分类模型比较

使用除了等级和利率之外的所有预测因子,模型的精确度达到了大约 85%。虽然朴素贝叶斯提供了非常高的准确性,但它无法解释由于数据不平衡而出现的偏差。

所有上述模型的校准曲线和 AUC 分数都很高,表明性能强劲。校准代码显示了一种衡量模型是否受不平衡影响的方法。如果校准是完美的,这意味着模型不会因不平衡的数据集而产生偏差。换句话说,它不会总是试图预测结果是绝大多数,这是已完成贷款 (0) 的情况。

由于随机森林是最佳选择模型,我们决定探索同类最佳的树算法,也称为微软开发的轻型 GBM 分类器。它被认为是最新的行业趋势和多个 Kaggle 竞赛的获胜者,所以我们很好奇它在 Prosper 案例中的表现如何。正如假设的那样,对于轻型 GBM 分类器,所有的模型度量都非常高。

特征重要性

随机森林特征重要性

大多数模型的特征重要性图也是在分类阶段生成的。

我们的模型确定“已付服务费”、“已付推荐费”和“借款金额”是预测我们的目标变量“贷款状态”最有用的,这与投资直觉非常匹配。

学习曲线

当与样本 L2 逻辑回归模型比较时,还绘制了学习曲线以评估最佳随机森林模型的学习率。

当训练规模以 25 个数据点的间隔增加直到非常大的数量时,随机森林模型 AUC 增加,这意味着该模型将继续学习,并相对于逻辑模型给出更高百分比的准确回报预测。

第二阶段:预测预期收益

使用不同的功能集测试了各种模型。计算了不同回归方法下各种回归模型的 R2 值。

Prosper 回归模型比较

与建立的其他模型相比,随机森林回归给出了所有不同类型回报的最高分。

投资策略

通过利用分类和回归模型来预测贷款是否会违约和估计回报,可以制定投资策略,以基于用于计算回报的不同方法来最大化投资者的平均回报。

测试了四种不同的投资策略:

  1. 随机策略
  2. 基于默认值
  3. 基于简单返回
  4. 基于违约和回报的策略。

【Prosper 的投资策略回报率

为了描述现实生活中的情景,M3 回报法似乎是一种更准确的衡量%回报的方法。因此,我们比较不同投资策略的基准是 M3 方法。尽管如此,在研究 M3 回报方法时,无论使用哪种投资策略,回报似乎都非常接近。

%回报率的大小也高度依赖于再投资利率(M3)。

投资组合规模的敏感性测试

接下来,对投资组合规模与投资回报百分比进行了敏感性测试

Prosper 敏感性分析图

随着潜在投资者投资的贷款数量增加,投资回报的百分比下降。这也很直观,因为贷款违约的风险系数会随着投资的贷款数量增加而增加

换句话说,投资者可能有类似的机会获得高回报,然后由于贷款违约而失去大部分回报,这种循环会不断重复,导致总回报百分比随着投资贷款数量的增加而下降。

优化

在本节中,我们使用 Prosper 实现了三种不同的优化模型来改进投资策略。

三种不同的优化方法是:

1)直接最大化总利润

在我们的数据集中,为每笔贷款都设置了一个二元变量。添加贷款数量约束(根据我们数据集中的最大贷款数量)并定义目标函数(最大化总利润)。

2)在预算约束下实现利润最大化

第二个优化模型考虑了潜在投资者的预算约束。与第一个模型一样,添加了一个新的预算限制约束(测试不同的预算),优化问题得到了解决。

3)通过风险回报权衡实现利润最大化

第三个优化策略包括通过考虑收益的方差来纳入投资组合风险因素。

为了实现这一点,首先,投资者用可调整的 k 参数训练聚类模型。其次,计算每个聚类的标准偏差。第三,可以根据每个聚类的欧几里德距离将每笔贷款分配给特定的聚类。第四,每笔贷款的回报率的标准差可以使用聚类的标准差来估计。

然后建立模型,在包含风险收益权衡约束的情况下使利润最大化。投资者可以设置敏感度/惩罚因子,以说明投资者的风险承受能力。

三种不同场景下投资回报的优化

结果显示,Prosper 的最优投资策略是利用预算约束实现利润最大化,预期回报率为 10.5%。

结论

总之,我们看到了来自不同属性的信息如何被用来创建新的预测因子,这些预测因子最终可能会提高我们的模型相对于原始模型的统计显著性。需要注意的是,模型在将数据划分为交叉验证折叠时的表现可能会产生误导,因此多次运行我们的模型以开发训练/测试分割的不同迭代是至关重要的。另一个重要的部分是校准,以及如何测量模型产生的概率是否正确。

未来扩展

如果我们的模型与宏观经济外部数据(代表潜在经济当时的表现,如油价或世界银行的利率)挂钩,以进一步扩展悲观指标的表现,那么看看我们的模型会有什么表现将是很有趣的。

此外,对投资者进行情绪分析以了解他们的风险偏好会很有意思,而不是要求数字输入,因为他们可能缺乏对 P2P 贷款市场如何运作的了解。

商务化人际关系网

[## 诺亚·穆赫塔尔-麦吉尔大学-加拿大| LinkedIn

我是一个有抱负的分析师,喜欢把点点滴滴联系起来:不管是来自不同学科的想法,还是来自不同领域的人…

www.linkedin.com](https://www.linkedin.com/in/nmukhtar/) [## 加拿大蒙特利尔德绍特尔管理学院

查看 Shaan Kohli 在世界上最大的职业社区 LinkedIn 上的个人资料。Shaan 的教育列在…

www.linkedin.com](https://www.linkedin.com/in/shaan-kohli/) [## Shaher yar Jahangir -顾问-项目经理&建模师- Aéro Montréal | LinkedIn

沙赫尔贾汉吉尔是麦吉尔大学分析管理硕士(MMA)项目的候选人

www.linkedin.com](https://www.linkedin.com/in/sjahangi/) [## 加拿大蒙特利尔德绍特尔管理学院

在世界上最大的职业社区 LinkedIn 上查看 Ramy Hammam 的个人资料。Ramy 有 5 份工作列在他们的…

www.linkedin.com](https://www.linkedin.com/in/ramy-hammam/) [## Maxime Cohen -麦吉尔大学副教授| LinkedIn

马克西姆科恩是零售管理和运营管理副教授和本萨登学院学者…

www.linkedin.com](https://www.linkedin.com/in/maximecohen/) [## 丹尼尔·盖塔-商业分析倡议主任,专业…

在全球最大的职业社区 LinkedIn 上查看丹尼尔·盖塔的个人资料。丹尼尔列出了 5 份工作…

www.linkedin.com](https://www.linkedin.com/in/daniel-guetta-b4262212/) [## Kevin Jiao -定量研究员-美国金融监管机构| LinkedIn

查看 Kevin Jiao 在全球最大的职业社区 LinkedIn 上的个人资料。凯文有两个工作列在他们的…

www.linkedin.com](https://www.linkedin.com/in/kevin-jiao-98211134/) [## 福斯特教务长-杰出科学家-指南针| LinkedIn

在全球最大的职业社区 LinkedIn 上查看福斯特·普罗沃斯特的个人资料。福斯特有 3 份工作列在…

www.linkedin.com](https://www.linkedin.com/in/foster-provost/)

开源代码库

[## Noah MMA/贷款 _ 投资组合 _ 优化

如何使用数据驱动的策略和定量算法优化贷款组合 GitHub 是 50 多个…

github.com](https://github.com/NoahMMA/loan_portfolio_optimization)

我们的灵感——原创研究

https://www.liebertpub.com/doi/pdf/10.1089/big.2018.0092

使用优步移动数据优化救护车响应时间

原文:https://towardsdatascience.com/optimizing-ambulance-response-time-using-uber-movement-data-4e6618240b67?source=collection_archive---------62-----------------------

变更数据

蒙特卡洛模拟,评估基础设施对救护车响应时间的影响(伦敦塔桥案例研究)。

图片由eroykapix abay(免版税)分享

介绍

紧急医疗服务(EMS)的效率是一个运行良好的卫生系统的主要指标。在这份报告中,我比较了各种救护车队的管理策略,以尽量减少他们的反应时间。基于现实生活中的数据,我分析并比较了模拟结果与伦敦 EMS 响应时间的基准。此外,我测试了救护车平均速度的变化以及伦敦塔桥在 2016 年最后一个季度关闭对平均响应时间的影响。

方法学

将伦敦的道路网格编译成一个网络在计算上是昂贵的,因此该方法是对系统进行粗粒度处理,以区域(平均面积为 1.6 km)作为构建块。使用开源的优步运动数据集,这座城市由大约 1000 个由多边形组成的大伦敦地区构成。接下来,在两个给定区域之间创建边依赖于它们的多边形共享的坐标数(即,如果一对区域共享至少一个坐标,则它们是相邻的,因此它们与边链接)。

使用 Networkx 软件包生成的大伦敦地区网络

为了进行更有针对性的分析,选择了伦敦地区的一个分区,包括市中心周围的 71 个地区。优步运动的数据集填充了所有区域对之间的平均旅行时间,然后用作伦敦网络分段的边权重(深灰色表示高平均旅行时间,浅灰色表示低平均旅行时间

请求救护车的概率因地区而异。利用伦敦大都会警察局发布的犯罪率指数,每个地区都有一个犯罪率指标,用网络中节点的颜色来表示(T2,红色代表高犯罪率,蓝色代表低犯罪率)。节点的大小反映了以千米为单位的区域面积。最后,伦敦的医院使用谷歌地图 API ( 绿色节点)定位,然后在伦敦的分区网络中与它们各自的区域相关联。(即,如果医疗中心的坐标落在一个区域的多边形内,那么它将包含在该区域的节点中)。

伦敦 71 个分区的网络

假设

尽管网络的构建接近真实设置,但以下假设可作为解释模拟结果的前提:

  • 所有救护车都由同一个提供者协调(即,所有请求都到达一个中央计划者,然后根据紧急请求的接近程度来调度救护车)。
  • 犯罪率是一个整体指标,包括不涉及住院治疗的犯罪。换句话说,人们可以认为旅游景点会因为扒窃而抬高犯罪率,这并不一定意味着大量的救护车请求。
  • 平均行驶时间是基于优步骑行的测量,但救护车可以通过跳过红灯或当汽车为他们让路时切断交通。通过引入救护车速度参数,模拟显示了这种优势。
  • 医院被模拟成拥有数量不受限制的救护车。
  • 在现实生活中,紧急事件是按优先级分类的,但为了简单起见,模拟中生成的所有紧急事件都具有相同的优先级。

建模和仿真

给定底层数据结构,我设计了一个面向对象的程序,它将网络作为输入以及其他参数(救护车的平均速度、医院节点和紧急请求的数量)。这种方法是所有的请求一次生成,然后模拟通过它们来计算平均响应时间。

  • generate_requests: 该函数使用由标准化犯罪率加权的正常随机抽样器在城市的不同区域生成紧急呼叫。(即犯罪率相对较高的地区会有更频繁的救护车呼叫)。

  • estimated_travel_time: 该函数使用医院和发出紧急呼叫的地区之间的最短路径序列来估计平均行驶时间。对于最短路径上的每条边,样本取自正态分布,其平均值设置为边上的平均行驶时间,标准差设置为边上的行驶时间。最后,它返回边缘样本的总和。(注:平均值和标准差的估计值均来自优步运动数据)

  • shortest_path: 该函数按照以下过程计算医院节点和产生紧急呼叫的节点之间的最短路径:

运行模拟

模拟的迭代性质依赖于两个变量,即生成的请求数和每次模拟的运行次数。使用 2016 年第三季度的旅行时间数据,我控制救护车的速度为 20 公里/小时,然后运行模拟 500 次,每次迭代产生 2000 个请求,这产生了以下响应时间分布的直方图。

救护车的平均速度

根据 NHS 伦敦救护车服务的说法,伦敦的救护车在法律上被限制在 20 英里/小时(约 32 公里/小时)的速度限制内。为了测试速度变化的影响,我生成了 2000 个请求,针对从 10 到 35 公里/小时的每个速度进行 100 次模拟

平均响应时间是逐渐减少的;因此,上升的速度有递减的回报。从 10 公里/小时开始,响应时间集中在 700 秒左右,然后平均速度为 20 公里/小时时减少到 570 秒左右,在 35 公里/小时时达到最大值 500 秒。请注意,这些测量值的标准偏差在不同速度(25 秒)下大致相同

伦敦塔桥

选择伦敦的一个令人信服的原因是测试基础设施的变化对救护车响应时间的影响。在 2016 年最后一个季度,伦敦塔桥因施工而关闭,并于 2016 年 12 月 30 日重新开放。这是一个很好的自然体验,可以理清对响应时间的因果影响。比较是在两个网络之间进行的(第一个包含 2016 年第三季度的行驶时间,第二个包含第四季度的数据)。

这两种分布都近似正常,但是中间相隔 10 秒,因为在桥关闭之前,整个网络的响应时间要快 10 秒。两种分布的置信区间具有相同的范围(13 秒)

新救护基地

最初,网络模拟有一组分散在伦敦网络中的六家医院。添加新救护车基地的一个启发是首先对具有最高响应时间的节点进行排序。该图显示了一个基于给定节点生成的所有请求的平均响应时间进行着色的网络。我们注意到,与网络的其他部分相比,东北地区的响应时间很长。

突出显示每个地区平均响应时间的模拟结果的网络

由于五个区域之间的行程时间大致相同,我们可以选择一个节点将其指定为医院节点(假设区域 155 包含救护车基地)。通过这样做,我们希望降低整个网络的平均响应时间。

这两种分布是截然不同的(不重叠),因为添加了一个基数后,响应时间减少了 60 秒(从 573.52 秒减少到 512.96 秒)。

为了便于比较,在 155 区增加一个基地与将救护车的平均速度从 20 公里/小时改为 30 公里/小时具有相同的影响

结论

响应时间对患者及时接受护理的机会有着至关重要的影响。对许多紧急情况来说,轻微的改善可以挽救生命。使用模拟,我们不仅可以判断优化响应时间的经济高效的策略,还可以评估和设计减轻基础设施变化影响的方法。

在伦理背景下,在两种策略之间进行选择不仅要考虑均值,还要考虑每个分布的分布,因为使用功利主义方法来优化大多数可能会伤害异常区域。(例如,我们不希望响应时间最长的区域离平均值太远)。调查结果提到,这些差距最多为 15 秒,这是一个令人放心的指标,表明这些战略在合理/可行的范围内,可以作为决策包括在内。

优化共享单车分配路线

原文:https://towardsdatascience.com/optimizing-bike-sharing-allocation-routes-in-chicago-81f17b13a4a5?source=collection_archive---------47-----------------------

解决大城市共享单车车辆路径问题的新途径

Gabriela Bavaresco Kataoka 摄

住在大城市的好处是出行选择范围广。在芝加哥,Divvy 是一家自行车共享公司,在整个城市有 600 多个站点,尽管你经常会发现这些站点是空的,特别是在拥挤和受欢迎的地区。这对于公司和寻找廉价、高效、健康的城市出行方式的顾客来说都是不利的。

当希望应用从我们的分析硕士优化课程中学到的技能时,我们的团队——由 Amy Lin、Divya Ravindran、Grace Yin 和 Luis Flosi 组成——决定解决这样一个问题,即找到一辆 divy 面包车在选定的自行车站之间行驶的最佳路线,收集和重新分配自行车,以最大限度地减少在客户最需要时丢失自行车的机会。幸运的是,Divvy 已经在芝加哥的数据门户公开了其自行车的所有行程数据。我们还收集了黑暗天空的天气数据来丰富我们的模型。我们最终的代码库可以在 GitHub 上找到。

我们将从了解数据开始,然后创建预测模型以了解车站之间的需求和供应,最后基于两种不同的方法优化配送路线:线性规划和模拟退火。

数据探索

这些数据是在之前的项目中从 Amy 所在的小组导入、清理和结构化的。我们的重点是了解一周中的几天、几个小时和几个月之间的乘车模式,以及这些变化如何影响一个车站的自行车数量。

我们发现,在高峰时段,相当多的车站变得空无一人或人满为患。我们还发现,工作日的模式与周末非常不同。最后,季节对旅行总数也有很大的影响,因为芝加哥的冬天非常寒冷。这项分析由 Amy 负责,她制作了以下图表:

假设

我们确定了我们的模型如何能够在给定我们可用的信息和我们可以合理假设的情况下解决问题:

  • 我们可以访问 2019 年的每一次旅行,每个车站的自行车容量和每小时的容量状态。从天气数据集中,我们还设法确定了每次旅行的能见度和温度。
  • 考虑到分配不一定每小时执行一次,我们将工作日和周末划分为不同的时间段,如上面红线所示。自行车分配将在这些时间范围内执行。
  • 作为一个假设,我们建议一辆货车的容量为 20 辆自行车。这个假设可以很容易地在我们的模型中进行调整。
  • 为简单起见,我们还假设芝加哥所有地区的交通流量恒定且相等,这意味着车站之间的距离是影响两站之间货车运输“成本”的唯一因素。尽管对于模型来说这也可以很容易地改变,但是在这一点上收集交通信息会更复杂。
  • 在我们的模型中,一辆货车只负责一组特定的站点。在未来的模型中,我们肯定会将其扩展到考虑所有站点的无限数量的货车。然而,我们发现,当同时考虑数百个站点时,这种类型的优化问题(通常称为车辆路径问题,或 VRP)的计算量太大。

在这种情况下,我们意识到缺少的主要模型输入是任何给定日期每个站点的预测需求。

需求估计

为了估计需求,Divya、Grace 和 Luis 创建了两个预测泊松模型,用于估计到达和离开每个站点的自行车数量。它们考虑了天气状况、月份、小时和星期几。

尽管模型显示了接近零的卡方 p 值,但它们在测试集上表现也很好,显示的误差范围在-1 到 5 个预测行程之间。在预测低值率时,p 值检验可能会产生误导,因此我们决定将该模型用于预测出行。然而,在现实生活中,我们肯定会进一步发展这个模型,使之更加健壮。

根据上面的模型,我们限制了他们的出行预测,以考虑每个站点的自行车容量。最后,我们利用 95%的预测出行上限作为实际出行次数。我们决定考虑上层,以确保大多数日子不会缺少自行车。

对于优化模型,我们将需求定义为需要运输到一个站点的自行车数量,以便满足所有客户的出行。正需求意味着一个加油站在一段时间内有多余的自行车。考虑到这一点,我们将需求定义为:

D = B — (UL — A)

其中 D =需求,B =时间段 T 开始时可用的自行车,A 是时间段 T 内到达的自行车数量,UL 是时间段 T 内离开车站的自行车数量的上限估计值

根据到达和离开每个车站的行程数量,我们能够将每小时的数量汇总到预定义的时间范围内,在该时间范围内将进行优化。从那里,我们只需要计算在时间 T 开始时每个站点实际可用的自行车数量(考虑优化后的变化)。

对于 T = midnight,我们假设可用自行车的数量总是相同的,等于午夜历史时段的平均值,因为 Divvy 历史上在那个时间执行分配。从那时起,每个时间范围将有自行车的数量将被考虑:前一个时间范围的分配结果(实际可用的自行车数量);“A”代表前一时间段和离开车站的自行车平均数(非上限)。

B_t+1 = O — (L — A)

其中,O 是前一时间段 T 内可用的优化自行车数量,A 是前一时间段内到达车站的自行车数量,L 是前一时间段内模型预测的平均离开自行车数量。

我们对每个新的时间框架重复这个过程,每次计算优化模型的输入 D。

配送路线优化

我们使用了两种不同的方法来优化自行车分配路线。第一个是使用 Julia 的 Gurobi 解算器解决的线性规划问题,第二个是使用模拟退火(s a)技术解决的,该技术受这篇研究论文的结果启发,该结果显示 SA 可用于以少得多的计算量解决 VRP 问题。

两种解决方案都考虑了由 Amy 导出的相同的目标函数。优化后,我们最小化预期站库存和实际库存之间的绝对差异之和:

1.Julia 中的线性规划求解

变量

限制

线性规划解决方案需要定义目标函数将服从的约束。约束条件不仅需要定义容量(如货车和车站容量),还需要创建路径连接并建立距离作为“成本”,为此将有一个可达到的最大成本(意味着在时间范围到期之前货车可以行驶的总时间)。以下函数也是 Amy 在团队其他成员的支持下开发的:

容量限制

路由约束

2.模拟退火方法

前一种方法的主要缺点是计算量非常大。不仅要花几个小时或几天的时间来一次运行所有站点的优化,在一些情况下,只有 20 个站点可能要花几个小时来处理。

前面提到的论文使用模拟退火找到了类似 VRP 模型的替代方法,模拟退火是一种随机选择解决方案并对其进行评估直到找到最佳解决方案的算法。然而,该算法的独特方法是,它允许“坏的”解决方案,以逃避局部最优。

一旦我们完成了最终项目的优化类设置的范围,我们决定更进一步,在我们的数据中实现 SA 算法,以找到我们难以处理的场景的解决方案。尽管我们只实现了 SA 的有限的初稿版本,但我们在运行曾经需要几个小时才能处理的案例时,只用了几分钟就取得了很好的结果。

Luis 针对我们的具体情况对 SA 进行了修改,在此进行了概述。代码可以在我们的知识库中找到。

结果和最终考虑

为了展示我们的结果,Divya 和 Grace 选择了一个“默认”的夏季,在工作日的下午 7 点时段有良好的能见度,芝加哥有 29 个随机站点。在 Amy 使用我们的线性模型处理了这个案例之后,他们一起制作了下面的图像来演示最终的路线:

请注意,优化可以在任何给定的情况下运行,只要它有需求、容量约束和距离/行程时间的输入。此外,这是我们冬季季度演示的结果,我们在演示中使用了之前的预测模型。从那以后,我们在 GitHub 页面上看到这个模型得到了改进。

在现实生活中,这可以在任何给定的一天提前运行,为货车创建动态路线,以优化日常工作日、周末、夏季或冬季,甚至特殊活动日的自行车分配。这将允许 Divvy 以最佳和最快的方式合理地分配自行车,不仅最大化它们的机会,而且最大化整体客户满意度。

通过超参数调整优化深度学习算法

原文:https://towardsdatascience.com/optimizing-deep-neural-networks-through-hyperparameter-tuning-1c8ae15bd3c7?source=collection_archive---------53-----------------------

神经网络中超参数的简单指南

Denys Nevozhai 在 Unsplash 上拍摄的照片

在进入调优和优化机器学习算法之前,让我们看看超参数到底是什么。超参数是一组确定神经网络训练方式和神经网络结构的参数。基本上,超参数在决定你训练的神经网络是否适用于你试图解决的问题方面起着至关重要的作用。

实际上,应用机器学习是一个高度迭代的过程,更简单地说,是一个反复试验的过程。即使是非常有经验的深度学习实践者也无法第一次就获得这些“超参数”。这个过程就是把你的想法变成代码,实验,评估结果,做出改变,重复这个过程,直到你得到预期的或者满意的结果。

下面我们就把其中的几个超参数逐一细说。

1.学习率

学习率是一个具有小正值(通常范围在 0.0 到 1.0 之间)的超参数,它控制模型适应问题的速度,换句话说,学习率决定权重在梯度方向上应该有多远,以满足全局最小值。

作者图片

如果学习率太低(图 1 ),训练将进展非常缓慢。如果学习率设置得太高,如图 3 所示,训练可能不会收敛于全局最小值,而是超过它,并继续使模型损失更严重。立刻获得正确的学习速度是不可能的(除非你非常有经验,同时又非常幸运)。正如所有的超参数一样,这是一个反复试验的场景。然而,衰减的学习速率(将随着训练的进行而降低)优于固定的学习速率。学习率的衰减可以是基于时间的衰减、阶跃衰减或指数衰减。

2。批量

批量大小可以定义为神经网络一次训练的数据(样本)数量。假设你有 1000 个样本需要训练。你可以一次通过神经网络传播所有 1000 个样本,也可以小批量传播,比如一次传播 100 个样本。神经网络将首先获取前 100 个样本,然后训练网络,然后是接下来的 100 个样本,我们可以让神经网络继续这样做,直到它被所有样本传播。使用小批量的优势在于,它们需要的内存更少,训练速度比完整批量更快。

3.时代数

历元数是学习算法将遍历整个训练数据集的次数。有人可能认为更高的历元数会导致更精确的模型,但这并不总是正确的。

作者图片

从上图中可以看出,随着历元数的增加,训练误差和验证误差都在减少,但只减少到某一点。此后,由于过拟合,验证误差不断增加。因此,为了使模型在面对新数据时表现良好,训练应该在训练和验证误差都最低的点处结束,并且该点处的时期数是理想的时期数。在 TensorFlow 等库中,我们可以选择以这样一种方式编写代码,即当验证误差达到某个期望值时,训练将被终止。

4.隐藏单元和层的数量

这些超参数在很大程度上取决于它们所应用的问题维度。隐藏层是神经网络的输入层和输出层之间的层。对于一个简单的问题,几个隐藏层和几个隐藏单元就足够了,但是问题越复杂,需要的隐藏层和隐藏单元就越多。实践中的经验法则是在输入和输出层的单元之间保持隐藏单元的数量。然而,应该记住,不希望的较高数量的隐藏层和隐藏单元不仅会浪费计算能力,而且会导致过拟合,这会降低神经网络的精度。

5.辍学者

Dropout 是一种正则化技术,用于减少验证误差,换句话说,用于避免过度拟合。简而言之,丢失意味着随机忽略神经元(单元),这样做将在神经网络的前向和后向传播中被忽略。在训练期间,神经元开始相互依赖,这限制了利用独立神经元的能力,而随机丢弃几个神经元我们能够防止这种情况。

作者图片

漏失以百分比给出,假设你给出了 20%的漏失值,每 5 个神经元中就有 1 个会被随机丢弃,并在训练中被忽略。退出增加了为了收敛到全局最小值而需要执行的迭代次数,但是每次迭代的训练时间将会减少。

6.激活功能

激活函数基本上是用于向神经网络引入非线性的数学方程。现在让我们进入数学,

作者图片

正如你所看到的,激活函数实际上决定了每个神经元的输出应该如何表现,因此应该根据你要将训练好的模型应用到的问题仔细选择正确的激活函数。Sigmoid、ReLu 和 tanh 是一些广泛使用的激活函数。每一个激活函数都有它的优点和缺点。要更深入地了解激活功能,请参考下面链接的我的文章。

[## 了解神经网络中的激活函数。

什么是激活功能,为什么你应该知道它们?

towardsdatascience.com](/getting-to-know-activation-functions-in-neural-networks-125405b67428)

结论

正如我在本文开头提到的,超参数调整传统上是手动完成的,这是一个迭代过程。然而,优化算法的研究仍在进行中。网格搜索、随机搜索和贝叶斯优化是一些广为人知的优化算法,但是,这些算法可能计算量很大,并且各有利弊,这超出了本文的范围。(也许是改天的话题!).

感谢您的阅读,希望我能有所帮助。

资源

优化 Apache Spark 上的基因组数据处理

原文:https://towardsdatascience.com/optimizing-genomics-data-processing-on-apache-spark-3333d6d41ed6?source=collection_archive---------46-----------------------

宏基因组序列数据的低记忆 k-mer 分析

B 生物信息学产生大量数据。特别是“组学”(基因组学、转录组学、蛋白质组学……)及其相关的序列数据(如 NGS、下一代测序)可能在计算上具有挑战性。处理它会消耗大量的 CPU、内存和磁盘空间。人们可能想要运行的许多工作负载甚至经常不被考虑。

亚历山大·波波夫Unsplash 上拍照

其中一个原因是,许多重要的组学工具是为在单台机器上运行而设计的,而不是为分布式(集群)处理而设计的。这是可以理解的,因为分布式处理给已经棘手的软件开发工艺增加了新的难度。然而,这导致了一种情况,有时我们需要访问具有 100 GB RAM 的机器,以便执行例如宏基因组学的分类学分类(其中我们识别 DNA 样本中存在的所有不同物种)。即使是拥有如此强大机器的人也无法回避这样一个事实,即它的内存对可运行的分析规模有着严格的限制。在一个负担得起的云计算服务和商用硬件的时代,我们应该能够做得更好。我们希望能够选择以高效的方式在集群或云中运行我们的计算。

火花

Apache Spark 是一个强大的大数据分析框架,近年来已被广泛接受。它结合了函数式编程、MapReduce 编程模型的优点,对于那些想要它的人来说,它还结合了现代的 Scala 编程语言(也可以使用 Python、Java 和 R)。它处理大型分布式数据集合,并包含一个查询优化引擎,有助于充分利用硬件。它也受到主要云提供商的支持,比如 AWS 和 Google Cloud,当然你也可以在你自己的机器上运行它。鉴于所有这些好处,似乎我们应该尝试在 Spark 上运行一些繁重的组学分析。

然而,我们不能简单地将现有的工具(如 BLAST in Spark)包装起来,并期望它能够工作。在分布式计算中,我们必须将问题分解成相对独立的部分,以便从中获益。当我们能够以这种方式表达算法时,Spark 就可以为我们完成繁重的工作,并在集群上平稳地运行工作负载。当然,这是否可能取决于每种情况下所考虑的算法或问题。

k -mer 计数

为了理解这个领域的基本原理,我们实现了一个用于kmer 计数的工具。K-mers 是长度为 k 的 DNA 序列的短片段。因此,我们可以说三聚体、四聚体、三十一聚体等等。mer 分析形成了许多组学方法的主干,包括基因组组装、短阅读的质量控制、基因组大小估计和分类学分类。对我们来说,mer 计数似乎是这个领域中最简单的问题,解决起来很有意义,但在计算上仍然具有挑战性,一个好的基于 Spark 的解决方案应该是解决其他组学相关问题的良好基础。本质上,在给定的 DNA 序列数据集中,我们必须识别每个不同的 k- mer,并计算每个 mer 出现的次数。在一台机器上,传统上你可以使用一个工具,比如水母来解决这个问题。下面是 k=28 时的输出示例(整个表将有数十亿行)。

ATAATAATAGGAAGGCATTTTCGGACGA 1
ATAATAGGAAGGCATTTTCGGACGATTA 8
ATAATAGGCAGCCATGCCCGGACGGTGC 1
ATAATGTAGGTTCCATATTCAGGACATC 1
ATAGGAAACGCTTCTCGGACGGAAAGGT 2

你将如何以一种分散的方式计算 k 个 mers?我们不能简单地使用一个大的分布式阵列,因为潜在的 31 聚体(例如)的数量是巨大的:4。我们不能在内存或磁盘上维护那么多的计数器,而且 k 可能比 31 大得多。这些计数器中只有一小部分会在实践中使用。有了这样稀疏的键,宁滨将是必不可少的。如果你知道你的算法,你就会知道散列函数通常被用来将数据分配到 bin 中。这就是我们如何创建数据结构,如地图和字典。在 Spark 上,这是分区的基础。良好的分区是激发性能的关键之一,因为它控制着如何将工作分配给不同的工作机器。不良的分区会导致数据倾斜,在这种情况下,例如,一个工作节点可能会收到大量数据,使其不堪重负。这不仅会降低它的速度,还可能会迫使所有其他节点等待速度慢的节点完成。此外,这可能会大大增加该节点(以及所有节点)的 RAM 需求,因为我们无法控制大块数据的最终位置。这样我们又回到了起点。

打个比方,假设分布式管道实际上是一个管道系统,您的工作负载由您希望通过管道发送的球组成。如果有许多高尔夫球而只有一个保龄球,所有的管道都必须非常宽。但是如果所有的球都是高尔夫球,那么窄的管道就足够了。因此,均匀地划分数据将是有效利用资源的关键。

分担工作量

不需要太多的细节,将 k- 个 mers 散列到 bin 的公认方法是一种叫做 最小化器 的方法,这也是水母之类的工具倾向于使用的方法。(您可能想知道为什么不能简单地使用编程语言自带的标准字符串散列。主要原因是单独散列每个kmer 会导致输入数据的大小在计数前的中间阶段爆炸 50 倍或更多。在 Spark 中,这将导致网络上的大量缓慢移动。最小化者通过将许多相邻的 k 个聚在一起来避免这种情况,这是我们寻求保持的特性。)

最小化机在单台机器上适用于宁滨,但可以生产尺寸相差很大的箱子。对于分布式应用程序,这并不理想,因为我们会有数据倾斜。为了解决这个问题,我们开发了一个新的哈希函数(一篇论文正在准备中),它取代了最小化器,产生了更加均匀的分区。这可以通过给定箱总数的最大箱的大小来测量。我们的测试案例是奶牛瘤胃宏基因组数据,从 PRJNA60251 运行 SRR094926。在大约 1,000,000 个箱时,我们的“最差”箱不到最小箱的 1/100,如下图所示( k = 28)。这是非常有价值的,因为最大的 bin 大体上决定了整个应用程序的内存需求。

最大箱大小(k-mers 数)与箱数的关系。越小越好。奶牛瘤胃宏基因组学数据(k=28)。新方法有更多的数据点,因为它有许多可能的参数组合。

这允许我们将工作负载平滑地划分成大量的小分区,然后简单地遍历每个分区并计算那里的k-mer。当我们应用了这种哈希并优化了其他瓶颈时,与用于分布式kmer 计数的领先工具(使用最小化器)相比,我们的运行时间稍微快了一些,并且当应用于奶牛瘤胃宏基因组数据集时,内存使用率大约是竞争工具的 10%。如此低的内存使用率允许我们使用,例如,Google Cloud 上的“高 cpu”节点,它的内存更少,每小时比普通节点更便宜。这项创新节约了成本。或者,我们可以使用普通节点,但分析 10 倍以上的数据,而不会耗尽资源。因此,我们实现了一种高效、经济、可扩展的分布式计算 k- mers 的方法,并有望成为该领域其他有用工具的基础。

例如,对于 k =28,此时我们能够在 1.5 小时内在 4 个工作“highcpu”节点上计算 2.94x10 个⁰非重复k-mer(总共 7.23x10 个⁰),这 4 个工作“high cpu”节点总共有 57.6 GB RAM 和 64 个 CPU。这相当于十亿分之 1.33 个 CPU 小时。

结论

在这一过程中,我们学到了很多经验,但我们目前的主要观点是,找到消除数据不对称的方法对 Spark 性能非常有帮助。通过这样做,我们能够提高性能并减少 90%的内存使用。根据具体情况,开发自己的散列函数或自定义分区方案可能是非常值得的。对于组学数据中的 k- mers,可以完全改变权衡。

更一般地说,当我们从在单台机器上运行算法转移到在集群上运行时,全新的问题可能会出现。为了从 Spark 获得最佳结果,有必要在这些问题出现时理解并解决它们。如果能够解决这些问题,Spark 可能是组学数据分布式(云或集群)处理的一个非常好的选择。

最后,我要感谢 U.F. Petrillo 等人的 FastKmer(BMC bio informatics 2019),它为我们的 k-mer 计数实现提供了一些重要的启发和思路。

更新(2020 年 11 月):这项工作背后的代码经过进一步开发后,已经作为应用折扣的一部分发布(GitHub 上的 )。我上面描述的散列函数现在已经发展成为最小化者的“通用频率排序”。BioRXiv 上的 是一篇相关论文,它描述了我们的最新结果,并包含了关于该主题的更多细节。

以正确的方式优化超参数

原文:https://towardsdatascience.com/optimizing-hyperparameters-the-right-way-3c9cafc279cc?source=collection_archive---------10-----------------------

使用 Python 中的 skopt 通过贝叶斯优化有效地探索参数搜索。TL;我的超参数总是比你的好。

高效探索问题空间的广阔峡谷—Photo byfine as AntononUnsplash

在这篇文章中,我们将使用多个优化器构建一个机器学习管道,并使用贝叶斯优化的力量来为我们所有的参数获得最佳配置。我们所需要的就是 sklearn 管道Skopt
你可以用你喜欢的 ML 机型,只要有 sklearn 的包装(看你 XGBoost 或者 NGBoost)。

关于超参数

寻找能够解决问题的最佳模型的关键点是而不是仅仅是模型。在给定数据集的情况下,我们需要找到最佳参数来使我们的模型以最佳方式工作。这被称为寻找或搜索超参数。
例如,我们想在实践中实现一个随机森林,它的文档声明:

class sklearn.ensemble.RandomForestClassifier(n_estimators=100, *, criterion='gini', max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features='auto', max_leaf_nodes=None, ...

所有这些参数都可以探索。这可以包括从 1 到 10.000 的森林中所有可能的估计数(n_estimators),您可以尝试使用 {"gini "," entropy"} 进行分割,或者您的树的最大深度是另一个整数,还有许多许多选项。这些参数中的每一个都会影响你的模型的性能,最糟糕的是大多数时候当你开始处理一个新的问题集时,你不知道正确的配置

手提钻又名网格搜索

寻找最佳配置的强力方法是执行网格搜索,例如使用 sklearn 的 GridSearchCV 。这意味着您要在模型上尝试所有可能的参数组合。
从好的方面来看,你可能会找到想要的价值观。问题是运行时间是可怕的,并且总的来说网格搜索不能很好地扩展。对于您想要尝试的每个新参数,您也将测试所有其他先前指定的参数。这种方法非常缺乏信息,感觉就像在我们的问题空间中盲目地测试所有可能的按钮和配置。与此相反的是我们对超参数的理解:

我们有一种直觉,一些参数的选择比其他的更能提供信息。

一些参数更有意义,一旦我们知道一些参数范围比其他范围更好。此外,一旦我们知道什么方向起作用,我们就不必在错误的领域探索所有的价值。

我们不需要测试所有的参数——尤其是那些我们知道相差很远的参数。
朝正确方向的一步是像 RandomizedSearchCV 一样的随机搜索,我们在朝正确方向移动的同时随机选取参数。

更好的贝叶斯搜索

我们选择的工具是 BayesSearchCV 。这种方法使用逐步贝叶斯优化来探索问题空间中最有希望的超参数。
简而言之,贝叶斯优化在大型问题空间中找到目标函数的最小值,并且非常适用于连续值。为此,它对目标函数使用高斯过程回归。一个彻底的数学介绍可以在【2】中找到。在我们的例子中,目标函数是在给定我们指定的模型参数的情况下,达到最佳模型输出。
贝叶斯优化方法的好处是,我们可以给出更大范围的可能值
,因为随着时间的推移,我们会自动探索最有希望的区域,并丢弃不太有希望的区域。简单的网格搜索需要很长时间来愚蠢地探索所有可能的值。
由于我们的行动更加有效,我们可以有更大的活动空间。我们来看一个例子*。*****

问题集

今天我们使用来自 sklearn 的糖尿病数据集,以方便使用。
这省去了我们加载和清理数据的麻烦,而且这些特性已经被整齐地编码了。

我们有一组编码栏,包括年龄、性别、体重指数、血压和血清值,用数字编码。我们的目标值是疾病进展的量度。
我们可以在 s 柱(血清值)上看到一些相互作用,表明某种程度的相关性。

为了构建我们的管道,我们首先将数据集以 80:20 的比例分别分为训练和测试。

X_train, X_test, y_train, y_test = train_test_split(diabetes_df.drop(columns="target"), diabetes_df.target, test_size=0.2, random_state=21)

修建管道

我们需要三个元素来构建管道:(1)要优化的模型,(sklearn 管道对象,以及(skopt 优化过程。

首先,我们选择两个助推模型** : AdaBoost 和 GradientBoosted 回归器,对于每个模型,我们在关键超参数上定义一个搜索空间。来自 sklearn 库深度的任何其他回归器都可以,但 boosting 可能会为您赢得下一次黑客马拉松(…现在是 2015 年,不是吗?)
搜索空间是一个带有
键值对的字典:= { ' model _ _parameter':skopt . space . object }。
对于每个参数,我们在我们想要的范围内从 skopt 库中设置一个空间。分类值也通过将它们作为字符串列表传递来包含(参见下面的分类)😗*

ada_search = {
    'model': [AdaBoostRegressor()],
    'model__learning_rate': Real(0.005, 0.9, prior="log-uniform"),
    'model__n_estimators': Integer(1, 1000),
    'model__loss': Categorical(['linear', 'square', 'exponential'])
}gb_search = {
    'model': [GradientBoostingRegressor()],
    'model__learning_rate': Real(0.005, 0.9, prior="log-uniform"),
    'model__n_estimators': Integer(1, 1000),
    'model__loss': Categorical(['ls', 'lad', 'quantile'])
}

其次,我们通过另一个模型选择回归模型,这是我们的管道元素,其中两个优化器(adaboost 和 gradientboost)一起进行选择:

pipe = Pipeline([('model', GradientBoostingRegressor())])

第三,我们优化我们的搜索空间。为此我们调用 BayesSearchCV。我们还指定优化器应该如何调用我们的搜索空间。在我们的例子中是 100 次调用。然后我们用一个简单的目的来安装管道。fit() 命令:

opt = BayesSearchCV(
    pipe,
    [(ada_search, 100), (gb_search, 100)],
    cv=5
)opt.fit(X_train, y_train)

拟合完成后,我们可以要求找到最佳的参数。这包括对看不见的测试数据使用分数函数。

我们可以看到验证和测试分数以及最佳拟合的参数。具有最佳结果的模型是 AdaBoost 模型,具有线性损失和 259 个估计器,学习率为 0.064。干净利落。
从输出中我们还可以看到,优化器使用了一个 GP 进行底层优化:

GP 最小化

为了便于说明,我们也可以专门调用 GP 最小化,我们将使用 AdaBoost 回归器,只关注数值超参数空间。

ada = AdaBoostRegressor(random_state=21)# numerical space
space  = [Real(0.005, 0.9, "log-uniform", name='learning_rate'),
          Integer(1, 1000, name="n_estimators")]

这里的主要变化是我们必须定义一个目标函数来优化。为了查看模型在参数空间上的表现,我们使用了 named_args 装饰器。

@use_named_args(space)
def objective(**params):
    ada.set_params(**params)
    return -np.mean(cross_val_score(ada, X_train, y_train, cv=5, n_jobs=-1,
                                    scoring="neg_mean_absolute_error"))

因此,我们的优化是使用负平均绝对误差从交叉验证拟合中获得的负平均分数。其他评分功能可能更适合你。
然后,我们使用 GP 最小化来拟合回归变量的最佳参数。gp_minimize(objective, space, n_calls=100, random_state=21)

可视化问题空间—优化后

直接使用 GP 优化允许我们在最小化过程中绘制收敛图。

寻找 AdaBoost 回归器相对于数据集中目标列的最佳超参数时 GP 最小化的收敛性。

我们可以看到,在大约 40 次迭代之后,已经达到了函数值的最小值。
最后一个优秀的特性是
可视化探索的问题空间。因为我们在这一点上只使用了数字输入,所以我们可以通过使用 skopt 绘制来评估问题空间,如下所示:

将问题空间上调用的 learning_rate 和 n_estimator 值可视化为直方图。问题空间显示为散点图,使得每个 GP 运行(100 次中的一次)揭示该空间中的一个函数值。最小值由散点图中的红星标出。

从上图中我们可以看到,在我们的学习率谱的低端进行了大量的探索,经过尝试和测试的估计数的峰值是 200 和 800 以上。
散点图描绘了我们试图优化的问题空间有多困难——最小值标有红星。每个 GP-minimize 运行发现一个函数值,给定它作为输入的参数。虽然我们已经达到收敛,但在最小值周围的区域中没有很多值是明显的,并且可以考虑增加评估的数量。

既然我们有了给定参数空间的最佳模型,我们就可以相应地实现该模型,并进行具体的分析。

结论

我们已经表明,我们可以有效地探索可能的模型参数的巨大空间,节省时间和计算资源。我们通过将对超参数的搜索公式化为目标函数来做到这一点,我们使用贝叶斯优化来为该目标函数找到最优值。没有必要通过尝试每一个参数来测试无用的参数。如你所见,skopt 是一个在优化领域提供了很多东西的库,我鼓励你在日常的 ML 工程中使用它们。

探索愉快!

完整的代码可以在笔记本上找到这里:

** [## RMI chae 1/烟火研究

github.com](https://github.com/RMichae1/PyroStudies/blob/master/Bayesian_Optimization.ipynb)

参考

  1. 马克·克拉森,巴特·德·穆尔机器学习中的超参数搜索 。arXiv 上 2015。
  2. 彼得·弗雷泽。 贝叶斯优化教程 。arXiv 上 2018。
  3. sci kit-优化贡献者(BSD 许可证)。Scikit-学习超参数搜索包装器 。**

不平衡数据集的精确度与成本敏感方法和 ROC 曲线

原文:https://towardsdatascience.com/optimizing-logistic-regression-with-different-cutoff-values-174b6e56ea8d?source=collection_archive---------29-----------------------

用不同的截止值优化逻辑回归

逻辑回归是一种非常适合二分类问题的技术。在给定输入预测值的情况下,该模型计算可确定每个观测值类别的概率。在这项研究中,我们调查了不平衡数据的模型性能评估指标,重点是选择逻辑回归的最佳临界值。我们将逻辑回归应用于甲状腺数据(收集自 UCI 机器学习库),以检验该模型在不同临界值下的表现[1]。

甲状腺数据集包含 3,772 个观察值和 53 个属性,包括解释患者状态(1:患者有甲状腺,0:患者没有甲状腺)的目标变量。数据集是不平衡的,因为近 94%的观测值在类 0 中,而类 1 包含剩余的观测值。图 1 显示了数据集的不平衡类别分布。我们应用 70%: 30%的比率将数据分成训练和测试数据,同时保持类别分布。数据集中的变量比例不同。因此,训练和测试数据都利用 z 分数标准化技术进行了标准化。在标准化测试数据的过程中,我们使用了为训练数据计算的参数(平均值和标准偏差)。最后,将训练数据输入逻辑回归算法来训练模型,并利用测试数据进行预测。

1:甲状腺数据的类别分布

图 2:不同临界值的精确度

逻辑回归的预测是每个观察值的后验概率[2]。因此,可以将截止值应用于计算的概率,以对观察值进行分类。例如,如果考虑截止值 t ,那么大于或等于 t 的分数被分类为 1 级,而小于 t 的分数被分类为 0 级。图 2 示出了对于范围从 0.0 到 1.0 的不同截止值的模型的精确度。该模型的精度越来越高,直到在 0.4 的截止值达到其最大值 96.37%。从 0.4 的临界值开始,模型的准确性下降,并且没有显示出改善的迹象。

图 3 示出了混淆矩阵的不同结果,例如真阳性(TP)、假阳性(FP)、假阴性(FN)和真阴性(TN ),具有范围从 0.0 到 1.0 的不同截止值。它展示了我们在选择合理的截止值时所经历的权衡。如果我们增加截止值,那么 1) TN 增加,TP 减少,2) FN 增加,FP 减少。因此,对于 0.4 的截止值,我们可以实现更好的准确性,但是假阴性的数量仍然相对较高。此外,如果我们将测试数据中的所有观察结果分类为负面(0 类),我们仍然可以达到 94%的准确性,这与模型的准确性相对接近。因此,考虑到不平衡的数据集,精确度不是一个好的性能指标。

图 3:不同临界值的混淆矩阵结果

成本敏感方法在这个分类问题中,假阴性意味着一个人是甲状腺患者,但我们的模型未能检测到它,另一方面,假阳性意味着模型将这个人分类为患有甲状腺,而他没有。因此,假阴性会导致严重的后果,如不正确的治疗过程,因为疾病被忽略了,假阳性会导致不必要的护理。因此,产生假阴性比假阳性代价更高,因此,在这个问题中,最小化假阴性比最小化假阳性更重要。我们研究了不同截断值的假阴性和假阳性之间的最佳权衡。

成本分析是确定最佳临界值的方法之一。当假阳性和假阴性的成本已知时,在不同的截止值下计算成本,以实现假阳性和假阴性之间的合理平衡[4]。由于这个问题的真实成本是未知的,我们为一个假阴性指定 500 的成本,为一个假阳性指定 100 的成本。FN 的成本更高,因为它比 FP 的成本更高。图 5 示出了与从 0 到 1 的各种截止值相关联的成本曲线。当截止值为 0.2 时,达到最小成本 12,000。

ROC 曲线接收机工作特性(ROC)图对于组织分类器和可视化其性能非常有用【3】。这是所有可能临界值的真阳性率与假阳性率的关系图[4]。图 4 显示了 ROC 曲线,该曲线显示了基于范围从 0.0 到 1.0 的截止值的正确和不正确决策的所有可能组合。该 ROC 曲线下的面积为 0.887,这通常表明该模型的效率。最好的 AUC 可能是 1,而最差的是 0.5(45 度随机线)。当给定数据集不平衡时,我们可以利用 ROC 曲线来检验不同模型的有效性。

图 4: ROC 曲线

图 5:利用成本曲线的最佳截止值

模型性能评估指标在选择最佳模型时起着重要的作用。准确性是模型选择过程中公认的性能指标之一。然而,考虑不平衡数据的指标的局限性要求引入其他测量方法,如成本敏感的最佳临界值和 ROC 曲线。成本敏感分析可用于寻找最佳截止值,此外,ROC 曲线可用于检查模型效率并在给定数据集不平衡时选择最佳模型。

参考

【2】http://ethen 8181 . github . io/machine-earning/unbalanced/unbalanced . html

[3]t .福塞特(2004 年)。ROC 图:研究人员的注意事项和实际考虑。机器学习,31(1),1–38 页。

【4】https://ncsswpengine . net dnassl . com/WP content/themes/NCSs/pdf/Procedures/NCSS/One _ ROC _ Curve _ and _ cut off _ analysis . pdf

用张量流剖面仪优化模型训练

原文:https://towardsdatascience.com/optimizing-model-training-with-tensorflow-profiler-eb94eab0ec18?source=collection_archive---------19-----------------------

使用 TensorFlow 优化 GPU 性能

作者的 TensorFlow Profiler 漫游

我们希望我们的模特训练得非常快。我们使用 GPU 使操作执行得更快。然而,即使在加速计算之后,该模型在流水线本身中也可能效率低下,因此可能训练得更慢。在这种情况下,调试代码变得非常困难,事实上,甚至很难判断什么是慢的。

这可以通过使用张量流剖面仪来解决。分析器“分析”张量流代码的执行。在本文中,我们将讨论分析器、如何使用它、最佳实践以及如何优化 GPU 性能。

注意本文期望训练 TensorFlow 模型和使用 Tensorboard 的基础知识。你可以参考我在 Tensorboard 上的文章,如果你不知道的话。

张量流剖面仪

首先,甚至在优化任何东西之前,让我们讨论一下分析器是什么,它提供了什么。

分析有助于您了解模型中各种 TensorFlow 操作(ops)的硬件资源消耗(时间和内存),解决性能瓶颈,并最终使模型执行得更快。

张量流文档

基本上,分析器监控模型训练。它记录了执行 ops 所需的时间、执行完整步骤所需的时间,收集了关于时间和内存方面的资源利用率的见解,并为理解这些见解提供了可视化效果。

在接下来的章节中,我们将了解如何使用分析器:

  1. 我们将通过分析训练一个简单的模型。
  2. 探索剖析器,深入了解培训内容。
  3. 利用这些见解优化培训。

如何给模特做侧写?

要了解如何使用探查器,我们先来训练一个模型!我们将使用来自 tensorflow-datasets 的著名 mnist 数据集:

要安装 TensorFlow Profiler,请使用:

pip install -U tensorboard_plugin_profile

注意 Profiler 要求安装最新版本的 TensorFlow 和 TensorBoard。

现在,加载并预处理数据集:

(ds_train, ds_test), ds_info = tfds.load(
      'mnist',
      split=['train', 'test'],
      shuffle_files=True,as_supervised=True,with_info=True,                       )def rescale(image, label):
      return tf.cast(image, tf.float32) / 255., labelds_train = ds_train.map(rescale)
ds_train = ds_train.batch(128)

构建模型:

model = tf.keras.models.Sequential([
      tf.keras.layers.Flatten(input_shape=(28, 28, 1))
      tf.keras.layers.Dense(128,activation='relu'),
      tf.keras.layers.Dense(10, activation='softmax')
])model.compile(
      loss='sparse_categorical_crossentropy',
      optimizer=tf.keras.optimizers.Adam(0.001),
      metrics=['accuracy']
)

现在,启用分析器非常简单。您只需要在 tensorboard 回调中添加一个额外的参数:

tensorboard_callback = tf.keras.callbacks.TensorBoard(
      log_dir = logs,
      histogram_freq = 1,
 **profile_batch = '500,520'**
)

profile_batch参数告诉 TensorFlow 捕获执行性能并对其进行分析。【500,520】指定您希望评测的批次,即型号从批次 500 到 520 的性能将被捕获。

现在,我们将像往常一样使用上面的回调来训练模型:

model.fit(
      ds_train,
      epochs=2,
      validation_data=ds_test,
      **callbacks = [t****ensor****board_callback]**
)

使用分析器

现在我们已经训练了模型,让我们看看在分析器的帮助下我们做得如何:

概览页面

按作者分类的探查器概述页面

本节对模型性能进行了高度概括。以下是一些需要注意的事项:

  1. 步进时间图(右图)是****步数** (x 轴) v/s 执行相应步骤(步进时间,y 轴)所需时间的曲线图。它还显示了每个类别(彩色分区)使用了该步进时间的哪一部分。看上面的图,我们可以知道我们的模型是‘高度输入限制’,,也就是说,它在输入操作上花费了大量的训练时间。我们将在一段时间内对此进行优化:)**
  2. ****平均步进时间(在性能总结下)给出了平均步进时间的细分。在理想情况下,我们希望我们的模型将大部分时间花在实际的“训练”上,即保持 GPU 忙碌(设备计算时间必须是最高的,所有其他开销必须尽可能低)。
  3. TF Op Placement (在性能摘要下)显示主机(CPU)与设备(GPU)上执行的操作百分比。为了最大化 GPU 利用率,设备操作位置必须最大化。

在理想情况下,您的程序应该具有高 GPU 利用率、最小的 CPU(主机)到 GPU(设备)通信,并且没有来自输入管道的开销。

张量流文档

跟踪查看器

按作者的跟踪查看器

因此,在这个工具变得更加可怕之前,让我们来分解一下:

  • ****左边(垂直灰柱),可以看到两大板块:/device/host。这告诉我们哪个 TensorFlow op 在哪个设备(GPU 或 CPU)上执行。).
  • ****到右侧,彩色条表示各 TensorFlow 操作已经执行的持续时间。

通常,主机执行输入操作,预处理训练数据并将其传输到设备,而设备执行实际的模型训练。

张量流文档

探索这个工具将使您对这些持续时间有更好的了解(分别使用 W 和 S 来放大或缩小)。首先,看看这个:

探索跟踪查看器

  1. 流#19 显示了用于启动计算内核和制作设备到设备副本的时间线。
  2. 流#20 用于主机到设备的拷贝,并且
  3. #21 用于设备托管拷贝。

理想情况下,GPU 计算时间线必须是拥挤的(即,GPU 繁忙)。主机到设备和设备到主机的拷贝应该最少。

使用步骤时间线,您可以看到模型的不同阶段,如向前传递** ( sequentialdense)、损失计算 ( sparse_categorical_crossentropy)、向后传递 ( gradient_tapeAdam)。这些操作间应挤满台阶之间的最小空间。空格表示 GPU 空闲时间,拥挤表示利用率。**

其余工具提供了关于概述页面和跟踪查看器中涵盖的特定类别或操作的全面见解。让我们快速浏览一下:

  1. ****输入管道分析器:输入管道分析器检查输入管道,并通知是否存在性能瓶颈。它还告诉我们,如果我们的模型是输入绑定的。
  2. ****GPU 内核统计:这个工具显示每个 GPU 内核的性能统计数据和原始 op。
  3. ****内存分析:该工具分析 GPU 内存使用情况。这可用于分析和调试 GPU 内存耗尽时引发的 OOM (内存不足)错误。
  4. TensorFlow Stats: 该工具给出了执行的每个 TensorFlow op 的**性能概述。为了可读性,它为主机和设备操作提供了一个合适的分组。**

最佳化

在前面的部分中,我们训练了我们的模型,并看到了分析器如何帮助识别管道和资源利用中潜在的低效。本节将尝试解决这些效率低下的问题,看看我们的模型是否做得更好…

现在,我们已经看到我们的模型是高度'输入受限的,也就是说,它的大部分训练时间都花在了输入操作上(例如,预处理)。如果你从轨迹查看器中观察tf_data_iterator_get_next ,我们可以看到tf.data操作占了很多时间。这是因为我们的tf.data.Dataset在训练期间实时获取批次。

我们可以做的一件事就是使用 缓存预取

  1. [tf.data.Dataset.cache](https://www.tensorflow.org/guide/data_performance#caching)将数据集加载到内存或本地存储器中。这将为昂贵的 I/O 操作节省时间,如在每个时期从文件中打开和读取数据。****
  2. [tf.data.Dataset.prefetch](https://www.tensorflow.org/guide/data_performance#prefetching)实质上是提前准备数据和并行准备。****

因此在没有预取的情况下,在给定的步骤s,首先在时间t1获取(并预处理)数据。然后,模型在时间t2中根据这些数据进行训练。现在步骤s的总步骤时间变为(t1 + t2)

但是在预取的情况下,一个后台线程获取步骤(s + 1) 的数据,同时模型正在针对步骤s的数据进行训练。因此,如果为步骤(s + 1)获取数据所需的时间是t1,为步骤s训练模型所需的时间是t2,那么步骤时间将是max(t1, t2)

让我们在前面的代码中添加缓存和预取功能:

ds_train = ds_train.map(rescale)
ds_train = ds_train.batch(128)
ds_train = ds_train.cache()
ds_train = ds_train.prefetch(tf.data.experimental.AUTOTUNE)

然后,用和之前完全一样的方法训练模型。

现在我们已经优化了我们的培训,让我们来看看评测器:

优化后的探查器

  • 可以清楚地看到,输入开销显著降低。此外,平均步骤时间几乎减半(6.2 到 3.2)。你可以在推荐中看到,程序是'适度输入绑定的。****
  • 设备 TF Op 布局也有相当大的增加。

让我们检查跟踪查看器:

优化后的跟踪查看器

  • 注意流#19** 现在更加拥挤,这意味着 GPU 利用率有所提高。**
  • 流#20#21 已经最小化,因此主机到设备和设备到主机的拷贝已经减少。
  • 由于我们使用了缓存预取,这次tf_data_iterator_get_next也不那么拥挤了。****

关于优化的更多信息

在上一节中,我们看到了优化如何提高模型性能。为了便于演示,我只做了一个优化更改。但是优化远不止这些。

在这一节中,我们将浏览一些优化来寻找:

  1. 首先,使用 GPU 并不总是好的。在前面的章节中,我们已经看到,将计算卸载到 GPU 会产生设备到主机和主机到设备的复制开销。此外,启动 GPU 内核也会增加延迟。那么,如果你的模型很小,以至于这些开销所需的时间比实际训练时间还多,那么使用 GPU 真的是正确的事情吗?****
  2. 在跟踪查看器中,我们看到步骤之间的间隔应该很小(间隔表示 GPU 空闲时间)。我们在上一节中优化了输入管道,但我们看不到间隙长度有太大差异。其中一个可能的原因是:GPU 在每一步开始时执行一些主机端活动,如复制数据或调度。同时,tf.data在线程上运行,在 CPU 端并行化输入流水线。这些 CPU 端线程有可能会干扰 GPU 活动。为此,您可以设置环境变量:TF_GPU_THREAD_MODE=gpu_private这确保了 GPU 内核从它们自己的专用线程中启动,而不会排在** tf.data 工作之后。**
  3. 即使在调试线程之后,如果步骤之间的间隔没有缩小,检查您的回调、步骤之后的执行以及度量评估。如果禁用这些可以提高性能,那么您可能需要考虑只在几个步骤中计算这些。此外,对于定制培训,您可以使用[tf.while_loop](https://www.tensorflow.org/api_docs/python/tf/while_loop)
  4. 我们已经讨论过,理想情况下,大多数运算必须放在 GPU 上。总览页面上的 TF Op 位置有助于我们做到这一点。这减少了用于制作拷贝的主机-设备通信。这里有一个确保运算在 GPU 上得到最佳分配的技巧:即使对于一个 GPU,也要使用像** [tf.distribute.OneDeviceStrategy](https://www.tensorflow.org/api_docs/python/tf/distribute/OneDeviceStrategy)这样的分配策略。**

结论

在这篇非常详尽的文章中,我们讨论了一个非常有用的 TensorFlow 工具,它可以用来调试模型。我们看到了该工具提供的功能、使用它的基础知识,以及在 GPU 上优化 TensorFlow 模型性能的方法。

关于分析器和优化还有很多,我鼓励您阅读文档(参考资料中的链接)了解更多!

本文中我没有提到的一项重要优化技术是使用 XLAfp16 混合精度。这实际上可能需要一段时间来涵盖,最好在一个单独的文章中解释!

参考

** [## 使用 Profiler | TensorFlow Core 优化 TensorFlow 性能

使用分析器提供的工具来跟踪 TensorFlow 模型的性能。查看您的模型如何…

www.tensorflow.org](https://www.tensorflow.org/guide/profiler) [## 张量流分析器:分析模型性能|张量板

机器学习算法通常计算量很大。因此,量化…的性能至关重要

www.tensorflow.org](https://www.tensorflow.org/tensorboard/tensorboard_profiling_keras) [## 使用 TensorFlow Profiler 优化 TensorFlow GPU 性能

本指南面向利用 GPU 提高模型性能的 TensorFlow 用户。使用张量流剖面仪作为…

www.tensorflow.org](https://www.tensorflow.org/guide/gpu_performance_analysis) [## 使用 tf.data API | TensorFlow 核心提高性能

GPU 和 TPU 可以从根本上减少执行单个训练步骤所需的时间。实现最佳性能…

www.tensorflow.org](https://www.tensorflow.org/guide/data_performance) [## 每个 ML 从业者必须知道的 10 个张量流技巧

为什么 TensorFlow 是完整的 ML 包

towardsdatascience.com](/10-tensorflow-tricks-every-ml-practitioner-must-know-96b860e53c1) [## TensorBoard 快速入门指南

如何使用 TensorBoard 可视化 ML 实验

towardsdatascience.com](/a-quickstart-guide-to-tensorboard-fb1ade69bbcf)**

利用二项式分布和 Python 优化工作面试次数

原文:https://towardsdatascience.com/optimizing-number-of-your-job-interviews-with-binomial-distribution-and-python-c784cb199254?source=collection_archive---------56-----------------------

了解如何通过使用统计方法和一点 Python 语言来优化每月的面试次数,从而最大化获得工作机会的机会。

照片由 Cytonn 摄影Unsplash 上拍摄

在就业市场上,每个求职者都试图最大化他们成功的机会(获得工作机会)。他们和求职顾问之间最受欢迎的话题之一是每月活跃的申请和面试的推荐数量。时间太短意味着没有给自己足够的成功机会,而约会太多意味着不能为之做好准备。

那么,如何找到一个折中的办法呢?这就是一种特殊的统计方法发挥作用的地方——由于二项分布和一些关于我们自己的假设,我们可以优化每月的面试次数。为了做到这一点,我们必须首先了解什么是二项分布,它是用来做什么的。

它的数学公式写在下面。这里应该注意,它不是一个连续函数,在这种情况下,它被称为概率质量函数(PMF)。

二项式 PMF 公式

在哪里

这里的符号“!”表示阶乘(从 1 到阶乘数的所有整数的乘积,例如 4!表示 123*4)。这个等式计算出有多少个事件的组合。

k —期望成功的次数

n——试验次数

p —基本事件成功概率

一般来说,二项式分布告诉你在 n 次试验中 k 次成功的概率是多少

在我们的例子中,这将是在给定的面试次数(k)后收到的工作邀请数(k)。还有一个参数——单次事件成功的概率(p)。如果在实验中是常数,我们称之为伯努利实验。这种实验最常见的例子是抛一枚公平硬币——p 是常数,等于 50%。

在我们的例子中,基本概率是成功通过每一次面试的可能性。要评估它,在没有任何先验数据的情况下,我们必须对我们的表现和机会做出一些假设。

假设你能准备好 5 次面试,你估计你有 25%的机会。随着面试次数的增加,你的准备程度会降低,机会也会减少。在你可以考虑的最大面试次数,比如说 20 次,你只给自己 5%。使用分段线性函数,我们可以绘制我们的性能曲线。因此我们的基本概率不再是常数,而是 n 的函数:

下面的代码允许我们生成值。

n1 = 4
p1 = 0.25
n2 = 20
p2 = 0.05slope = (p2-p1)/(n2-n1)
intercept = p1-slope*n1
kink_point = n1def performance(x):
    'Piece-wise linear performance function'
    if x<kink_point:
        return p1
    else:
        proba = intercept + slope*x
        return proba

我们可以把它画在图上。它以一种漂亮的图形形式展示了我们的假设。

现在我们要做的是定义我们期望的成功次数(k)——通常建议最后有不止一个工作邀请——以便在谈判阶段有一个杠杆。

所以让我们假设我们希望在月底至少有2 个工作机会(k 个)(3 个、4 个或更多更好!).因此,我们想计算概率的总和:

如果你不加总,你会计算在月底得到 确切地说 2 份工作机会的概率是多少。

现在,已经定义了所有的输入,剩下的就是将这些值插入我们的等式并绘制输出。不要用手算这个!Python 的 NumPy 和 scipy 库允许我们非常方便地用几行代码进行计算。

它可以通过两种方式实现:使用 Numpy 库的采样技术或使用 SciPy 库中的 PMF 方法。后者更快更精确,因此我将在这里使用它。

**import numpy as np
from scipy.stats import binomdef binomial_pmf(k,n,p):
    'Binomial Probability Mass function summation'
    result = 0
    for k in np.arange(k,n+1):
        result += binom.pmf(k,n,p)  # summing probabilities
    return resultdef binomial_sampling(k,n,p):
    'Binomial distribution sampling technique'
    sample_size = 100000  # number of samples
    result = sum(np.random.binomial(n,p,sample_size)>=k)/sample_size  
    return resultp_success = []  # probability of success
k = 2  # minimum desired numbers of successesns = np.arange(1,21)  # number of interviews (trials)
ps = [performance(x) for x in ns]  # elementary success probabilityfor i, n in enumerate(ns):
    p_success.append(binomial_pmf(k,n,ps[i]))**

结果图(如下)告诉我们,在月末,当我们有 11 次面试时,获得 2 份工作邀请的可能性最高——大约 55%。然而,请注意,9 次和 11 次面试有相似的概率——仍然超过 50%,你可以腾出一些时间。因此,在这种情况下,你可以争取每个月有 9 到 11 次面试,以最大化你的机会。

现在,计算方案已经确定,我们可以考虑通过使用 S 形曲线来改进我们的假设,例如,使用逻辑函数代替性能曲线的分段线性函数。逻辑函数的等式是:

物流功能

其中:
L —最大值(饱和水平,上限)
x₀—s 形中点(曲率转换点)
K —逻辑增长率(定义斜率/陡度)

由于标准的逻辑函数是一个递增函数,我们希望拟合它的逆函数。此外,我们需要偏移它,这样我们就可以上下移动它来定义我们想要的概率下限——否则默认为 0。将这个函数拟合到一组给定点超出了本文的范围,但是您可以使用它的参数来得到令您满意的结果。最后,我们的等式看起来像:

偏移为 U 的反向逻辑函数

其中 U 是我们需要的偏移值。

**def logistic_perf(x,l,k,x0,offset):
    "inverted logistic performance"
    return l/(1+np.exp(-k*(x-x0)))-offset**

下面是拟合数据的示例性曲线。

最终结果如下所示。在这种情况下,求职面试的最佳次数是每月 9 次。为了仍有超过 50%的成功,你可以把目标定在每月 8 或 9 次。请注意,在 18 次面试之后,这种可能性再次上升。这是因为您的性能几乎保持不变(较低的饱和度值),但您有越来越多的尝试。

现在你可以使用所有的变量和系数,看看哪个数字最适合你。玩得开心,祝你好运!

优化珊瑚边缘 TPU 的姿态估计

原文:https://towardsdatascience.com/optimizing-pose-estimation-on-the-coral-edge-tpu-d331c63cfed?source=collection_archive---------35-----------------------

辅导的

如何访问 PoseNet 模型中的低级特征并在边缘 TPU 设备上释放姿态估计的全部潜力

2018 年,谷歌宣布发布 PoseNet 的 TensorFlow,这是一种机器学习模型,能够检测图像中的人,并估计他们身体部位的位置,这种技术被称为姿势估计

由 Coral Edge TPU 加速器上运行的 PoseNet 算法估计的姿态。右侧是在边缘 TPU 模型中通常不可访问的关键点热图的叠加图。原照片 by 贾辛格拉索尔 / CC BY 2.5

PoseNet 检测框架可用于 JavaScript(tensor flow . js)、Android/iOS 移动设备( TensorFlow Lite )和 Edge TPU 加速器( Google Coral )。

最近,我对该框架的 Edge TPU 版本最感兴趣,因为我一直在从事几个涉及“野外”人员检测和跟踪的项目,TPU 的 USB 版本使得在小型嵌入式设备上执行实时姿态估计成为可能,如树莓 PiSTM32P1 平台。

针对边缘 TPU 的 PoseNet 的限制

Coral 工程师在打包代码和模型方面做得很好,使得开发人员可以轻松地使用 PoseNet 框架。然而,为了简化使用,一些模型参数已经被硬编码。例如,可以在图像中检测到的个人物/姿势被限制为 10 个。解码算法的其他参数也是硬编码的,虽然我发现默认值在许多情况下都很好,但我认为有机会通过微调一些隐藏的参数来改善姿态估计。如果你对细节感兴趣,请继续读下去。

谷歌珊瑚缘 TPU 产品,来源 https://coral.ai

背景:波森特建筑

PoseNet 实现基于两级架构,包括****卷积神经网络(CNN)** 和解码算法。**

****卷积网络被训练生成热图,预测图像中所有关键点(即身体部位)的位置。它还生成短程和中程偏移向量,有助于在同一幅图像中出现多人时“连接这些点”。

****解码算法获取 CNN 生成的热图和偏移向量,并创建身体部位和人物实例之间的关联,试图确保来自同一个人的所有关键点都关联到同一实例。你可以从开发这项技术的谷歌研究团队的两份出版物[ 12 ]中读到所有细节。

PoseNet-source【2】中热图、偏移和位移矢量之间的关系

解码算法的参数— 在拥挤的场景中,确保身体部位和人物实例之间的正确关联是一项相当具有挑战性的任务,在拥挤的场景中,许多人可能看起来彼此紧密接触。为了在各种条件下确保最大的准确性,PoseNet 的作者提供了一些参数来控制解码算法的工作方式。

在计算最终输出时,影响速度精度的一些参数如下:

  • 最大姿态检测 —要检测的最大姿态数。
  • 姿势置信度阈值 — 0.0 到 1.0。在高层次上,这控制了返回的姿势的最小置信度得分。
  • 非最大抑制(NMS)半径 —以像素为单位的数字。在高层次上,这控制返回的姿势之间的最小距离。

请参见 TensorFlow 组的中的帖子以获得参数的通俗易懂的描述。通过试验实时多姿态在线演示中的参数值,可以获得额外的见解。

边缘 TPU 上的 PoseNet 实现

在 JavaScript 和移动实现(Android 和 iOS)中,解码算法都包含在源代码库中,参数可以在运行时更改。然而,对于 EdgeTPU 版本,代码维护人员选择了不同的方法,并决定将解码算法作为自定义操作符直接嵌入 TensorFlow Lite 模型中。

[……]请注意,与 TensorflowJS 版本不同,我们在 Tensorflow Lite 中创建了一个自定义 OP,并将其附加到网络图本身。[……]优势在于我们不必直接处理热图,当我们通过 Coral Python API 调用该网络时,我们只需从网络中获取一系列关键点。(来源:https://github.com/google-coral/project-posenet)

虽然一方面,这种方法使得在边缘 TPU 上启动和运行 PoseNet 更容易,但另一方面,它阻止了我们调整解码参数并在精度和速度之间实现最佳平衡的可能性。例如,在 EdgeTPU 实现中,姿势的最大数量固定为 10 个,因此如果我们试图处理超过 10 个人的图像,我们将无法获得预期的结果。此外,如果我们要处理单姿态场景,我们可能会浪费一些 CPU 周期来解码不在图像中的姿态。

访问边缘 TPU 模型中的热图和偏移向量

在接下来的部分中,我们将探讨一些可以用来(重新)访问卷积网络输出的步骤,看看如何“手动”解码,同时保留调整算法参数的可能性。我们将首先了解如何检查边缘 TPU 实现中可用的 PoseNet 模型,以及如何修改它们以访问卷积层产生的低级功能。

步骤 1:检查原始 TFLite 模型(可选)

PoseNet 的珊瑚 TPU 代码库包含三个基于 MobileNet 架构的模型,并针对三种不同的图像分辨率进行了优化:

1) posenet_mobilenet_v1_075_353_481_quant_decoder_edgetpu.tflite
2) posenet_mobilenet_v1_075_481_641_quant_decoder_edgetpu.tflite
3) posenet_mobilenet_v1_075_721_1281_quant_decoder_edgetpu.tflite

模型以 TFLite 格式保存,可以使用 TensorFlow 代码库中包含的visualize.py工具检查其内容。

我们将把最小的模型( 353 x 481 )转换成 HTML 文件进行检查。注意,由于模型的名称很长,创建一个到它的符号链接更容易。

# Create symlink to original model (353x481)
MODEL=/path/to/posenet_mobilenet_v1_075_353_481_quant_decoder_edgetpu.tflite
ln -s ${MODEL} /tmp/input_model.tflite# Convert file from TFLITE format to HTML
cd ~/tensorflow/tensorflow/lite/tools
python visualize.py /tmp/input_model.tflite /tmp/input_model.html

HTML 文件包含关于模型中存在的输入/输出张量和运算符的所有信息:

用 theTensorflow 实用程序 visualize.py 生成的 TFLITE 模型 posenet _ mobilenet _ v1 _ 075 _ 353 _ 481 _ quant _ decoder _ edge TPU . TFLITE 的 Html 表示

从 HTML 文件中我们可以看到有两个操作符 Ops (0,1)。第一个, Ops #0,将在具有维度[1,353,481,3]的张量 3 内以 RGB 格式存储的原始图像作为输入。第二个操作符 Ops #2 ,用姿态估计过程的结果产生输出张量:

- Tensor 4, FLOAT32 [1, **10**, **17**, 2]...: **Keypoint coordinates** (y, x)
- Tensor 5, FLOAT32 [1, **10**, **17**]......: **Keypoint scores** - Tensor 6, FLOAT32 [1, **10**]..........: **Poses scores** - Tensor 7, FLOAT32 []...............: **Number of poses**

张量 4、5、6 中的第二维度等于 10 是因为,如前一节所述,姿势的最大数量参数被硬编码为 10。张量 4 和 5 中的第三维值与 PoseNet 当前检测到的 17 个关键点相匹配:

PoseNet - Image source 检测到 17 个姿态关键点 TensorFlow

如果我们想要解码 10 个以上的姿势或改变一些其他输入参数,我们将需要使用存储在以下张量中的第一个操作符 Ops#0 的输出:

- Tensor 0, UINT8 [1, 23, 31, 17]....: **Keypoint heatmap** - Tensor 1, UINT8 [1, 23, 31, 34]....: **Keypoint offsets** - Tensor 2, UINT8 [1, 23, 31, 64]....: **Forward and backward displacement vectors (mid-range offsets)**

【2】中提供了热图、关键点偏移和位移矢量的详细描述。

请注意,热图的大小为[23, 31],因为该特定模型使用了OUTPUT_STRIDE = 16,图像大小和热图大小之间的关系由以下等式给出:

heatmap_height = 1 + (img_heigth - 1) / OUTPUT_STRIDE
heatmap_width = 1 + (img_width - 1) / OUTPUT_STRIDE

步骤 2:获取热图、偏移量和位移向量

TFLite 模型使用 Google Flatbuffer 协议文件格式序列化到磁盘。在大多数情况下,处理这种格式所需的工具链必须从源代码安装(参见本 StackOverflow 帖子中的说明作为示例)。安装完成后,您将可以访问flatc模式编译器,该编译器支持从 TFLite 格式到 JSON 的转换,反之亦然。转换所需的模式文件可在 tensor flow repo(schema . FBS)中获得,应在具有以下语法的调用中使用:

# Converts from TFLITE to JSON
SCHEMA=~/tensorflow/tensorflow/lite/schema/schema.fbsflatc -t --strict-json --defaults-json -o /tmp ${SCHEMA} -- /tmp/input_model.tflite

下图显示了 JSON 输出中包含的数据的概要,它与我们在 HTML 表示中已经看到的内容相匹配:

JSON 文件相当大(~25MB),不容易“手动”编辑。但是我们可以用一些简单的 Python 代码来操作它,如下所示。其思想是移除自定义算子解码算法(Ops #1)、任何未使用的张量,并确保模型输出由张量0,1,2给出。

用于修改 TFLITE 模型的 Python 脚本

最后,我们使用与第一步转换相同的flatc实用程序将输出从 JSON 格式转换回 TFLite 格式:

# Converts from TFLITE to JSON
SCHEMA=~/tensorflow/tensorflow/lite/schema/schema.fbsflatc -c -b -o /tmp ${SCHEMA} /tmp/output_model.json

转换的结果现在应该可以在output_model.tflite(你可能想给它一个更具体的名字)flatbuffer 文件中找到。我们可以验证当我们从 TensorFlow 加载这个模型时,它会产生三个具有预期大小的输出张量:

输出张量的大小与预期尺寸相匹配:

Output #0, UINT8 [1, 23, 31, 17]....: **12121** elements (heatmap)Output #1, UINT8 [1, 23, 31, 34]....: **24242** elements (offsets)Output #2, UINT8 [1, 23, 31, 64]....: **45632** elements (disp. vectors)

到目前为止,一切顺利……😃

解码热图和偏移向量

我们现在准备好了过程的最后一步,包括从模型中获取新的输出(热图、偏移和位移向量)并提取姿态。

正如介绍中提到的,PoseNet 的 JavaScript 和 Android/iOS 版本都包含解码算法的实现。谷歌没有发布相同算法的官方 Python 实现,但幸运的是,我们可以依赖 GitHub 上辉煌项目 PoseNet-Python 中可用的非官方端口。

从 PoseNet 的 JavaScript 版本移植而来的代码位于文件[decode_multi.py](https://github.com/rwightman/posenet-python/blob/master/posenet/decode_multi.py)中,该文件包含一个带有以下签名的函数:

def decode_multiple_poses(
        scores, offsets, displacements_fwd, displacements_bwd,
        output_stride, max_pose_detections=10, score_threshold=0.5,
        nms_radius=20, min_pose_score=0.5):

在上面的函数中,第一个参数scores代表关键点热图,而偏移和位移向量(向前和向后)与我们之前讨论的张量相匹配。

让这个函数起作用的唯一棘手的部分是正确地预处理热图,并重塑位移向量,以匹配decode_multiple_pose函数所期望的格式。下面的代码片段包含函数extract_outputs,它负责将修改后的 TFLite 模型的输出转换成可以直接传递给解码函数的格式。

演示如何解码修改后的 TFLite 模型的输出的最小工作示例。注意,我们现在可以访问解码算法的所有参数。

结论

这篇文章展示了如何检查一个边缘 TPU TFLite 模型,并改变它,以获得在一个 PoseNet 模型卷积层的输出。它还显示了如何利用解码算法的参数来获取该输出并提取姿态。我打算写一篇后续文章,探索在基于姿态估计的真实世界计算机视觉应用中改变这些参数的影响。如果您有想法或建议,请留下评论或通过 Stura.io 联系我。

具有重叠关键点热图的姿态检测输出(右半部分)

参考

[1] G .帕潘德里欧等人。,野外多人姿态精确估计 (2017),CVPR 论文集。

[2] G .帕潘德里欧等人。, PersonLab:利用自下而上、基于部分的几何嵌入模型进行人物姿态估计和实例分割 (2018)。

使用回归优化产品价格

原文:https://towardsdatascience.com/optimizing-product-price-using-regression-2c17688e65ea?source=collection_archive---------7-----------------------

应用数据科学

收益最大化价格优化的 Python 实现

照片由 Maddi BazzoccoUnsplash 上拍摄

价格和数量是决定每项业务底线的两个基本指标,设定正确的价格是一家公司可以做出的最重要的决定之一。如果消费者愿意多付钱,定价过低会损害公司的收入,另一方面,如果消费者不愿意以更高的价格购买产品,定价过高也会以类似的方式损害公司的收入。

因此,考虑到价格和销售之间的微妙关系,最大化产品销售和赚取最多利润的最佳点——最佳价格——在哪里呢?

本文的目的是通过在 Python 环境中实现经济理论和回归算法的结合来回答这个问题。

1.数据

我们是根据历史价格和销量的关系来优化一个未来价格,所以首先需要的是这两个指标的过往数据。在这个练习中,我使用了历史牛肉销售和相应单价的时间序列数据。

# load data
import pandas as pd
beef = pd# view first few rows
beef.tail(5

该数据集包含总共 91 个按季度报告的数量-价格对观察值。

数据科学中通常会进行探索性数据分析(EDA),但我将跳过这一部分,专注于建模。然而,我强烈建议采取这一额外的步骤,以确保您在构建模型之前理解了数据。

2.图书馆

我们需要导入库有三个原因:操作数据、构建模型和可视化功能。

我们正在导入用于创建和操作表格的numpypandas,用于可视化的mtplotlibseaborn,以及用于构建和运行回归模型的statsmodels API。

import numpy as np
from pandas import DataFrame
import matplotlib.pyplot as plt
import seaborn as sns
from statsmodels.formula.api import ols
%matplotlib inline

2.定义利润函数

我们知道收入取决于销售量和产品的单价。

我们也知道利润是通过从收入中扣除成本计算出来的。

将这两者放在一起,我们得到以下等式:

# revenue
revenue = quantity * price # eq (1)# profit
profit = revenue - cost # eq (2)

我们可以结合 eq 改写利润函数。#1 和# 2 如下:

# revised profit function
profit = quantity * price - cost # eq (3)

等式 3 告诉我们,我们需要三条信息来计算利润:数量、价格和成本。

3.定义需求函数

我们首先需要建立数量和价格之间的关系——需求函数。这个需求函数是根据价格和数量之间的线性关系从“需求曲线”中估算出来的。

# demand curve
sns.lmplot(x = "Price", y = "Quantity", 
data = beef, fig_reg = True, size = 4)

为了找到需求曲线,我们将拟合一个普通最小二乘(OLS)回归模型。

# fit OLS model
model = ols("Quantity ~ Price", data = beef).fit()# print model summary
print(model.summary())

以下是回归结果,带有进一步分析所需的必要系数。

5.寻找利润最大化的价格

我们正在寻找的系数来自上面的回归模型——截距和价格系数——来测量相应的销售量。我们现在可以将这些值代入等式 3。

# plugging regression coefficients
quantity = 30.05 - 0.0465 * price # eq (5)# the profit function in eq (3) becomes
profit = (30.05 - 0.0465 * price) * price - cost # eq (6)

下一步是从一系列选项中找到我们想要的价格。下面的代码应该是直观的,但基本上我们在这里做的是计算每一个价格和相应的销售数量的收入。

# a range of diffferent prices to find the optimum one
Price = [320, 330, 340, 350, 360, 370, 380, 390]# assuming a fixed cost
cost = 80Revenue = []for i in Price:
   quantity_demanded = 30.05 - 0.0465 * i

   # profit function
   Revenue.append((i-cost) * quantity_demanded)# create data frame of price and revenue
profit = pd.DataFrame({"Price": Price, "Revenue": Revenue})#plot revenue against price
plt.plot(profit["Price"], profit["Revenue"])

如果绘制价格和收入,我们可以直观地识别收入的峰值,并找到使收入位于曲线最高点的价格。

因此我们发现,当价格设定为 360 美元时,不同价格水平下的最大收益达到 3726 美元。

# price at which revenue is maximum
profit[profit['Revenue'] == profit[['Revenue'].max()]

总结和结论

本文的目的是演示如何结合使用经济理论和统计建模来找到收入或利润最大化的价格。在最初的步骤中,我们定义了需求和利润函数,然后运行回归来找到需要输入利润/收入函数的参数值。最后,我们检查了不同价格水平下的收入,以获得相应的最大收入价格。

优化星巴克应用产品

原文:https://towardsdatascience.com/optimizing-starbucks-app-offers-e9f10689972?source=collection_archive---------25-----------------------

利用机器学习创造个性化的客户体验

韦斯利·麦克拉克伦在 Unsplash 上的照片

介绍

除了是世界上最大的咖啡馆公司,星巴克还因其奖励计划而臭名昭著。今年早些时候,他们的会员基础增加了创纪录的 140 万名客户,截至本季度末,美国共有 1890 万名活跃会员,同比增长 16%。随着其技术倡议 Deep Brew 的推出,星巴克不断构思和开发一套人工智能工具,以提升他们业务的各个方面。

那么星巴克到底做对了什么?可以实施什么来实现收益最大化?这些是我试图更好地理解的一些问题,将在这篇博客中探讨。通过回答这些问题,星巴克可以瞄准更有可能兑现优惠的客户,这将降低促销成本,并最大限度地提高优惠收入。成功地将优惠瞄准合适的用户还会带来增强的个性化体验,这反过来会提高客户保留率。

目标

在本帖中,我们将分析模拟数据,模拟真实顾客在星巴克奖励应用上的购买行为。我们将探究交易、人口统计和报价数据,以揭示消费者行为趋势。这些趋势将被用于建立一个预测报价成功的机器学习模型。目标是向更有可能响应的用户发送促销信息,并且只向他们发送有较高兑现概率的优惠。

数据集

Udacity 提供的星巴克数据集包含来自星巴克奖励移动应用的人口统计、报价和交易数据。同样的数据集可以在 Kaggle 上的这里找到。请随意下载这些并跟随!

星巴克每隔几天就会通过手机应用程序向用户发送一次优惠信息。这些优惠可以是广告、折扣或买一送一(BOGO)促销。并非所有用户都收到相同的促销信息,每个用户的优惠频率也各不相同。数据包含在三个文件中,模式如下:

portfolio.json —包含报价 id 和关于每个报价的元数据(持续时间、类型等)。)

  • id(字符串)—优惠 id
  • offer_type (string) —优惠的类型,如 BOGO、折扣、信息
  • 难度(int) —完成报价所需的最低花费
  • 奖励(int) —为完成一项提议而给予的奖励
  • duration(int)-报价开放的时间,以天为单位
  • 频道(字符串列表)
  • profile.json —每个客户的人口统计数据
  • transcript.json 记录交易、收到的报价、查看的报价和完成的报价

profile.json —每个客户的人口统计数据

  • 年龄(整数)—客户的年龄
  • 成为会员日期(整数)—客户创建应用程序帐户的日期
  • 性别(str) —客户的性别(请注意,有些条目包含“O”代表其他,而不是 M 或 F)
  • id (str) —客户 id
  • 收入(浮动)—客户的收入

transcript.json —记录交易、收到的报价、查看的报价和完成的报价

  • 事件(str) —记录描述(即交易、收到的报价、查看的报价等。)
  • 人员(字符串)—客户 id
  • 时间(整数)—测试开始后的时间,以小时为单位。数据开始于时间 t=0
  • value —(字符串字典)—报价 id 或交易金额,具体取决于记录

挑战

这些数据中存在几个挑战:

  1. 底层模拟器只有一种产品,而星巴克卖几十种。这种简化使我们的分析更容易,但由于缩放限制了现实世界的应用。
  2. 交易不能直接链接到已兑现的优惠。客户不会选择他们收到的报价。使用该应用程序的人可能会在没有收到或看到报价的情况下通过该应用程序进行购买。
  3. 结果并不代表个人层面的用户行为。用户以不同的频率收到不同的促销,有些人可能几周都收不到优惠。数据集不考虑这种变化。

鉴于数据集的局限性,清理和数据预处理对于揭示消费者行为趋势和建立预测模型至关重要。

路标

我们的分析将遵循这个大纲:

  1. 数据评估和清理
  2. 探索性数据分析
  3. 数据可视化
  4. 预测建模
  5. 总结想法

1.数据评估和清理

投资组合评估:

让我们从评估投资组合数据集开始。在我们对该数据帧的初步观察中,我们可以看到“通道”可以被分成单独的列,以便更好地进行分析。我们还可以将“id”列重命名为“offer_id”

原始投资组合数据框架

投资组合清理步骤:

  • 将“频道”分成不同的列
  • 将“id”列重命名为“offer_id”

干净的数据集应该如下所示:

清理的投资组合数据框架

简介评估:

转到配置文件数据集,我们再次看到,将“id”列重命名为“customer_id”会更清楚性别也可以转换成数字,或者可以分隔成列。“成为成员日期”应该是可读的日期格式。虽然 118 是一个可能的剖面年龄,但在绘制分布图时,我们可以看到这个值是一个异常值。没有介于 101 岁和 118 岁之间的年龄。基于该分布和该年龄差距,我们可以推断这是用户输入错误,并用 NaN 替换该值。我们也可以删除缺少年龄、性别和收入数据的行。

原始轮廓数据集

轮廓清洗步骤:

  • 删除缺少年龄、性别和收入的行
  • 将“年龄”值 118 替换为 NaN
  • 将' date '从 int 转换为 datetime dtype
  • 将“成为成员”转换为日期时间格式
  • 将“id”列重命名为“customer_id”
  • 使用虚拟变量创建性别列

清理后的配置文件数据帧应如下所示:

已清理的配置文件数据集

成绩单评估:

对于副本数据,我们可以将“person”列重命名为“customer_id”“值”列可以分为 offer_id 和 amount 列。“事件”列也可以按报价类型和交易分成几列。由于我们在清理的配置文件数据帧中有一个“customer_id”列,我们可以删除配置文件数据集中没有的副本客户 id。

原始转录数据帧

抄本清理步骤:

  • 将“人员”列重命名为“客户标识”
  • 拆分“值”列以创建 offer_id 和金额列
  • 拆分“事件”列以根据报价和交易创建列
  • 删除配置文件数据集中不存在的 customer_id 值
  • 删除重复项

清理后的转录数据集应该如下所示:

已清理的转录数据帧

合并已清理的数据帧以进行探索性数据分析:

在下一节中,我们要探索所有变量,所以让我们合并这些数据帧。在查看优惠 id 时,我们可以看到有 10 种优惠:

按优惠类型列出的优惠 ID

在这里,我们可以看到 10 个不同的优惠 id 及其相关的优惠类型。让我们把它们重新命名为:' bogo_1 ',' bogo_2 ',' discount_1 ',' info_1 '等等。最后,让我们合并清理过的数据集。合并的数据帧应具有以下品质:

汇总的个人资料、投资组合和交易数据

2.探索性数据分析

现在有趣的部分,让我们来看看一些趋势。当查看合并的数据帧中的形状和时间列时,我们可以看出该实验运行了 30 天,收集了 272,388 个事件。

I .在实验过程中向用户提供分发的类型和 id

发送给用户的优惠类型和优惠 id

  • BOGO 是分布最广的促销活动,有 63,676 名用户获得了这项特别优惠。折扣促销是第二受欢迎的(62,095),信息优惠是最不常见的(22,660)。
  • “discount_3”是发送给 18,016 个用户的最常见的优惠,其次是“discount _ 2”(17,881)。分发最少的推广是“info_1”,发送给了 10,144 个用户。

到目前为止,我们已经查看了在这 30 天内发送给用户的报价。让我们构建一个数据框架,通过聚合交易、报价和人口统计数据来分析客户行为。

构建客户数据框架的步骤:

  1. 获取每个客户的优惠类型数据
  2. 获取每个客户的优惠 id 数据
  3. 分组年龄和收入,以便更好地显示(年龄四舍五入到第 10 位的第 5 位,收入四舍五入到较低的第 10000 位)
  4. 通过合并提取的变量、人口统计数据、报价和交易数据来构建数据框架(merged_cust)

生成的 merged_cust 数据帧应具有以下品质:

客户数据框架模式

二。按性别、年龄和收入分布划分的平均客户支出

从这里开始,我们可以使用客户数据框架来绘制以下变量:

  1. 性别计数和平均支出
  2. 年龄分布和平均支出
  3. 收入分配和平均支出

按性别、年龄和收入分布划分的平均客户支出

  • 从这些图中,我们可以看到数据集包含 8,484 名男性、6,129 名女性和 212 名其他性别的用户。虽然大多数用户是男性,但女性花费更多,平均支出总额为 140.91 美元。其他性别的平均总支出为 124.32 美元,男性为 99.59 美元。
  • 大多数用户在 50-70 岁年龄组。随着年龄的增长,用户花费更多。
  • 55,000-78,000 美元的工资范围在用户中最常见。收入越高的人花费越多。

3.数据可视化

I .按优惠类型和人口统计数据分列的消费模式

我们的探索性发现揭示了人口消费趋势和优惠类型。让我们从客户数据框架中按报价提取客户行为,并完成以下步骤:

  1. 获取已收到但未查看优惠、已查看但未完成优惠以及已查看并完成优惠的用户的数据,按“已收到”、“已查看”和“已完成”分组
  2. 获取已收到但未查看优惠、已查看但未完成优惠以及已查看并完成优惠的客户的平均费用,按列分组
  3. 按已收到、查看并完成报价的客户绘制平均交易价值图(对所有三种报价类型都这样做)

BOGO 提供的人口统计支出趋势

  • 随着年龄的增长,BOGO 的报价以更高的交易价格完成
  • 收入较高的用户在兑换 BOGO 优惠时会花更多的钱
  • 女性在 BOGO 提供的每笔交易中花费最多

按折扣优惠划分的人口统计支出趋势

  • 70 岁以上的用户不经常查看折扣
  • 已查看和已完成折扣的平均交易价值随着年龄的增长而增加
  • 折扣优惠的交易额随着收入的增加而增加
  • 女性在每次交易中为折扣优惠花费最多

按信息提供的人口统计支出趋势

  • 信息要约的平均交易价值从 35-75 岁开始增加,在 75-80 岁之间下降,然后略有增加
  • 交易价值随着薪水的增加而增加,超过 90,000 美元后开始下降
  • 女性在每笔交易中花费的钱比男性和其他性别的人都多

二。10 大优惠

在我们对合并数据框架的初步评估中,我们发现了 10 个不同的报价 id。让我们按照以下步骤来看看他们在收入方面的排名:

  1. 获取已查看并完成报价的客户的净费用
  2. 根据导致最高净费用的出价对出价进行排序

打印结果显示以下报价排名:

从最高收入到最低收入排列的最高报价

  • “bogo_1”报价返回的最大值为每位客户平均收入 145.70 美元。“bogo _ 2”(145.69 美元)和“discount _ 1”(145.53 美元)的报价分别位居第二和第三。“info_2”报价带来的收入最少,平均每位客户 103.29 美元。

三。按出价列出的成功百分比

我们可以通过定义一个按 ID 聚合已完成要约的函数来评估每个要约的成功百分比。让我们继续编写这个函数。

现在,我们可以按报价类型绘制成功率。让我们也画出要约类型计数,看看计数和成功率之间是否有任何关联。

优惠类型计数和成功百分比

  • 从这些图中,我们可以看到“bogo_3”报价的成功率最高,为 28.91%,其次是“discount _ 4”(27.67%)和“discount _ 3”(27.51%)。成功率最低的报价是“bogo_2 ”,成功率为 20.25%。
  • 结果并没有暗示要约计数和成功率之间的关联。我们看到‘bogo _ 4’、‘bogo _ 1’和‘bogo _ 2’的数量急剧下降,尽管数量保持相对稳定。

4.预测建模

现在,我们将使用我们分析中确定的客户消费趋势来建立一个模型,预测用户是否会对优惠做出反应。向用户发送促销信息的过程需要人工,并且是组织的一项成本。如果星巴克实现了预测模型,他们可以缓解这些资源,同时确保促销活动发送给历史上与优惠互动的客户,并且只有高成功率的优惠才会发送给他们。兑换优惠数量的增加和内部资源使用的减少将使星巴克的收益最大化。

一.数据预处理

虽然最初的清理对于我们的分析来说已经足够了,但是需要将数据转换成用于培训的有用且高效的格式。我们还将删除与我们的模型不相关的功能。每个数据集的预处理步骤概述如下:

投资组合 _ 建模

  • 复制 portfolio_clean 并重命名为 portfolio_modeling
  • 独热编码通道
  • 一次性编码 offer_type 列

简介 _ 造型

  • 复制 profile_clean 并重命名为 profile_modeling
  • 转换成数值
  • 标准化同质性

交易 _ 建模

  • 从抄本中提取交易 _clean

报价 _ 建模

  • 从抄本 _clean 中提取聘用相关数据
  • 一键编码提供事件

建模 _df

  • 将所有数据集合并到单个建模 _df 中
  • 这将用于训练和建立模型
  • 删除“时间”、“客户标识”、“电子邮件”、“信息”、“已接收”、“已查看”和“已完成”列

最终的数据帧应该如下所示:

分成训练和测试数据集

现在,让我们将数据分为训练和测试数据集,并通过评估测试数据性能指标来确保模型不会过度拟合数据。

评估朴素预测器性能:

朴素分类器假设所有报价都是成功的,并作为基础模型。我们可以使用朴素预测器性能来比较我们将构建的机器学习算法。让我们看看性能指标:

朴素预测器性能指标

天真的分类器显示有 64%的成功机会。

二。逻辑回归模型

逻辑回归模型构建一个线性决策边界来区分成功和不成功的报价。让我们使用 liblinear clf 作为 RandomizedSearchCV 中的估计器来构建这个模型,以拟合训练数据。

现在让我们定义模型性能评估函数:

评估逻辑回归模型性能:

逻辑回归性能指标

模型性能评估表明,逻辑回归模型的准确性和 f1 值优于朴素预测。

精确度:

  • 朴素预测值:0.471
  • 逻辑回归:0.696

F1 分数:

  • 朴素预测值:0.640
  • 逻辑回归:0.691

逻辑回归模型构建了一个线性决策边界,区分成功和不成功的提议。然而,对用户人口统计和报价类型的探索性分析表明,决策边界是非线性的。为此,集合方法随机森林和梯度推进将在接下来建立和测试。

三。随机森林分类器模型

随机森林使用多个决策树,并使用数据的随机样本独立训练每棵树。让我们构建一个随机森林模型,它使用 n_estimators、max_features、max_depth、min_samples_split 和 min_samples_leaf 作为调整参数,并使用 RandomizedSearchCV 进行拟合:

评估随机森林模型性能:

随机森林分类器性能度量

结果表明,随机森林模型的准确性和 f1 值优于朴素预测模型

精确度:

  • 朴素预测值:0.471
  • 随机森林:0.711

F1 分数:

  • 朴素预测值:0.640
  • 随机森林:0.723

四。估计特征重要性

特征重要性指的是描述特征对构建最大化其评估度量的模型的贡献的数值。随机森林分类器是在训练期间估计特征重要性的模型。让我们使用 scikit-learn 中实现的要素重要性算法来检索每个输入要素的相关重要性分数:

现在,让我们根据随机森林来绘制估计的要素重要性:

通过随机森林估计特征重要性

客户报价有效性培训数据表明,基于重要性的前五大特征是:

  1. 持续时间(优惠在到期前运行多长时间)
  2. 奖励(兑换优惠时客户获得的星级)
  3. 难度(兑换优惠所需的最低消费)
  4. 收入
  5. 社交(社交媒体上的广告)

我们可以使用该特征重要性排序,通过选择具有最高分数的特征并移除具有最低分数的特征来改进我们的预测模型。

动词 (verb 的缩写)梯度推进分类器

梯度增强一次构建一棵树,其中每个新树都有助于纠正先前训练的树所犯的错误。让我们使用随机网格和 loss、learning_rate、n_estimators、min_samples_leaf 和 min_samples_split 参数来构建这个模型,以便使用 RandomizedSearchCV:

评估梯度推进模型性能:

梯度提升分类器性能度量

结果表明,梯度推进模型的准确性和 F1 值优于朴素预测

准确(性)

  • 朴素预测值:0.471
  • 梯度推进:0.713

f1-分数

  • 朴素预测值:0.640
  • 梯度推进:0.716

不及物动词选择最佳模型

基于训练数据准确度的模型排名

  1. GradientBoostingClassifier 模型精度:0.713
  2. RandomForestClassifier 模型精度:0.711
  3. 逻辑回归模型精度:0.696
  4. 朴素预测准确度:0.471

基于训练数据 f1-得分的模型排名

  1. 随机森林分类模型 f1-得分:0.723
  2. 梯度增强分类器模型 f1-得分:0.716
  3. 物流回归模型 f1-得分:0.691
  4. 原始预测值 f1-得分:0.640

结果表明,梯度推进模型具有最好的精度,随机森林模型具有最好的 f1 值。

准确度&f1-得分

在理想的情况下,最好的模型应该具有最高的准确度和 f1 值。既然事实并非如此,让我们评估两个性能指标,以确定最佳的调优和优化模型:

  • 准确度是正确预测的观测值与总观测值的比率。高精度不一定表示最好的模型。在评估误报和漏报值几乎相同的对称数据集时,精确度最高。评估最佳模型需要额外的参数。对于我们的梯度推进模型,精度是 0.713,这意味着该模型大约 71.3%准确。
  • F1-score 是精度(正确预测的正面观察值/预测的正面观察值+总预测的正面观察值)和召回率(正确预测的正面观察值/所有观察值+总假阴性观察值)的加权平均值。由于 f1 分数同时考虑了假阳性和假阴性,因此通常更准确。如果假阳性和假阴性具有相似的成本,则准确性最好。如果假阳性和假阴性的成本非常不同,那么最好看看 f1 值,因为它包含了精确度和召回率。

梯度推进与随机森林分类

优势

渐变增强:

  • 高性能的
  • 可用于解决几乎所有的目标函数,包括排序和泊松回归,这在随机森林分类中很难实现

随机森林:

  • 更容易调整,因为通常有两个参数(树的数量和每个节点上要选择的特征的数量)
  • 不太可能过度拟合模型

弱点

渐变增强:

  • 对过度拟合更敏感,尤其是在有噪声数据的情况下
  • 因为树是按顺序建立的,所以训练需要更长的时间
  • 比随机森林更难调整,因为通常有三个参数(树的数量、树的深度和学习率)

随机森林:

  • 由于大量的树,实时预测缓慢
  • 对于包含分类变量的数据不可靠(偏向于具有更多级别的属性)
  • 对于包含相关要素组的数据不可靠(算法倾向于较小的组而不是较大的组)

由于此分析中的用户数据是不对称的,f1 分数将用于确定最佳模型。给定最佳 f1 分数,随机森林模型将用作此分析剩余部分的最佳模型。这种模型也最有意义,因为随机森林通常会产生训练速度很快的高质量模型。随机森林可以高效地处理大量训练数据,因此它非常适合未来在星巴克 1890 万活跃用户的大数据下处理多类问题。

七。调整超参数

让我们首先构建一个根据性能对所有模型进行排序的数据框架,来调整我们的随机森林模型。从这个数据集,让我们打印模型的最佳超参数。

输出:

最佳模型的超参数

有了这些信息,我们可以使用“最佳”超参数改进我们的模型:

让我们来看看优化的随机森林模型的超参数:

精细随机森林超参数

最后,我们应该评估测试数据的性能,以确保随机森林模型数据不会过度拟合训练数据:

随机森林测试数据性能指标

0.695 的测试数据准确度和 0.797 的 f1 分数表明所构建的随机森林模型没有过度拟合训练数据。

5.总结想法

一.结果

星巴克用户统计:

  • 57%的用户为男性,41%为女性,1.4%为其他性别。虽然大多数用户是男性,但女性花费更多,平均支出总额为 140.91 美元。其他性别和男性的平均总支出分别为 124.32 美元和 99.59 美元。
  • 该数据集中的大多数用户年龄在 50-70 岁之间。随着年龄的增长,用户花费更多。
  • 55,000-78,000 美元的工资范围在数据集中的用户中最常见。收入越高的顾客花费越多。

星巴克优惠表现:

  • BOGO 促销活动带来了最大的利润,平均每位顾客 138.43 美元。折扣促销的平均回报为 135.23 美元,信息优惠的平均回报为每位顾客 113.74 美元。
  • 训练数据表明,基于重要性的前五个特征是:
  1. 持续时间(优惠在到期前运行多长时间)
  2. 奖励(兑换优惠时客户获得的星级)
  3. 难度(兑换优惠所需的最低消费)
  4. 收入
  5. 社交(社交媒体上的广告)

基于人口统计的客户行为:

  • 在所有报价类别中,女性的每次交易花费最多
  • 在所有促销类别中,平均交易价值随着年龄的增长而增加,在过去 75 年中有所下降
  • 在所有三种优惠类型中,收入较高的客户每次交易花费更多

机器学习模型:

  • 在所建立的模型(逻辑回归、随机森林和梯度增强)中,随机森林分类被选为最佳,其依据是性能指标、高质量输出和快速训练该模型的能力。随机森林可以有效地处理大量的训练数据,因此它非常适合未来用于处理星巴克 1890 万活跃用户的多类问题。然后使用来自网格搜索的超参数来改进随机森林分类器模型。得到的模型具有 0.824 的训练数据准确度和 0.881 的 f1 分数。0.695 的测试数据准确度和 0.797 的 f1 分数表明所构建的随机森林模型没有过度拟合训练数据。

二。推荐

  1. 星巴克应该继续经营折扣和 BOGO 促销,因为它们被所有人口统计的顾客所兑换,有很大的成功率,回报也很高。在考虑收入、成功率和功能重要性时,信息性报价排在最后。也没有办法跟踪信息优惠是否兑现(只能看到用户是否收到或打开信息优惠)。基于这些结果,我建议星巴克只继续 BOGO 和折扣优惠。信息性报价应被视为一种广告,因为没有可测量的属性来跟踪可与 BOGO 和折扣报价相比的收益。
  2. 为了使平均交易收入最大化,星巴克应该瞄准女性、40 岁及以上的年龄组,以及年薪 60k 及以上的用户。
  3. 星巴克应该使用随机森林分类模型来预测顾客是否会对报价做出反应。这将最大限度地减少发起要约所涉及的资源和费用的使用,并增加最大回报的可能性。

三。继续探索

客户数据:

随着年龄和收入的增长,消费者的支出也越来越大。星巴克是否应该根据年龄和薪水增加促销频率,这或许值得探讨。由于女性比所有其他性别花费更多,探究这些更高数字背后的原因也将是有趣的。

  • 例如,女性会购买价格更高的商品吗?他们购买的频率更高了吗?他们会购买更多商品吗?有没有暗示他们在为一群人采购?

随机森林模型:

由于前三个特征与客户报价相关联,因此可以通过创建将报价成功率描述为报价持续时间、难度和报酬的函数的特征来改进该模型。这些特性的添加应该构建一个更好的决策边界,将成功和不成功的客户报价分开,返回一个具有更可靠的性能指标的模型。

四。结束语

像星巴克这样的公司专注于建立世界级的人工智能和人工智能能力是有原因的。在这种特殊情况下,用于分发个性化促销的机器学习模型增加了报价转换的几率,并降低了劳动力成本,从而使利润最大化。星巴克对人工智能的实施日益增强了他们的个性化引擎,优化了商店劳动力分配,并推动了库存管理。星巴克不断实施变革,正如他们最近的忠诚度计划更新所示,它提供了更多支付和赚取奖励的方式,使顾客更容易获得他们的下一杯免费咖啡

无论你是忠实的星巴克消费者还是无法理解 PSL 在时代精神中 17 年地位的咖啡爱好者,想想是什么促使你在下一次拜访时购买这家咖啡巨头的产品。

优化曲线!模拟新冠肺炎的最佳封锁出口

原文:https://towardsdatascience.com/optimizing-the-curve-modelling-optimal-lockdown-exit-for-covid-19-dfc81f2fb0c1?source=collection_archive---------32-----------------------

具有最优控制的扩展 SEIR 模型旨在“拉平曲线”而不会“拉平经济”太多。

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

介绍

绝大多数新冠肺炎预测模型预测有多少人可能被感染(“估计曲线】)。大量模型还估计了控制措施(如封锁)对受感染曲线的影响(“使曲线变平”)。然而,很少有模型试图回答这个关键问题——如何以最佳方式引入和放松控制措施?(《优化曲线》)。因为,事实上,强有力的控制措施,比如封锁,会对社会和经济产生巨大的负面影响。

在这篇文章中,我将提供一个简化的模型,其中将包括最佳控制措施的估计。它将回答如何最佳地进入然后退出封锁或放松任何其他控制措施的问题。我不会深究优化背后的复杂数学,并将尽可能提供直观的例子。正如您将看到的,生成的模型将使用不到 100 行 Python 代码(不包括交互式绘图部分),并将使用众所周知的库——NumPy 和 SciPy 来计算解决方案。

正如我之前提到的,很少有模型和研究将最优控制应用于新冠肺炎建模。你可以在这里找到其中的几个。它们包括许多复杂的数学。在文章中,我特意省略了它,以便用更容易理解的方式解释这些概念。因此,这里提供的模型将被简化,并应被视为主要是教育。它既不应被视为现实的预测模型,也不应作为任何决策的基础。

本文将包含以下几个部分:

  • 背景:所选模型和控制方法背后的理论。
  • 编码:一个关于如何用 Python 编码模型的分步指南。
  • 用例:估计应对新型冠状病毒病毒在一个假想城市传播的控制措施的 6 种不同情景
  • 比较:开发的模型与另一个具有更先进求解技术的模型进行比较。
  • 结论:总结与成果。

这里是模型、场景和比较的完整代码。

正如英国著名统计学家乔治·博克斯所说:

“所有的模型都是错的,但有些是有用的”。

考虑到这一点,我希望这里提供的模型可以作为所有现有观点的补充,并作为构建更高级和更现实的模型的基础。

让我们开始创建模型吧!

背景—模型

选择正确的建模方法至关重要。我们希望估计受感染个体的数量以及控制措施如何影响它(包括‘估计曲线’‘使曲线变平’部分)。只有利用这两个估计值,我们才能够预测最佳控制策略。在这种情况下,最常用的方法是估计房室流行病学模型,易感-感染-去除(SIR)模型或其任何扩展。在本文中,我们不会深入探究基于 SIR 的模型背后的概念,因为它们已经在许多其他资料中广泛涉及(例如这里,或者这里)。********

我们将使用一个扩展的易感-感染-移除模型。这将导致新型冠状病毒出现相当长的潜伏期,也将反映哪些受感染的个体住院并影响医疗系统的能力,以及哪些个体康复以及哪些因病毒而死亡。我们还将在模型中添加一个参数 u(t ),它将反映控制措施的强度(社交距离政策、锁定等)。与非药物干预相关的一切)。此外,我们的模型将有变化的死亡率,这将取决于医疗保健能力是否不堪重负。******

从这个意义上说,我们的模型中有 6 个区间:

  • 易感者:有被感染风险的个体。
  • 暴露(E): 已经感染,但尚未将病毒传播给他人的个体(这个额外的间隔反映了潜伏期)。
  • 已感染(I): 轻度感染并可将病毒传播给他人的个体。
  • 住院(H): 严重感染并需要医疗护理、医院床位或 ICU(这种额外的隔间影响医疗保健系统的容量)的个人。
  • 恢复(R): 恢复并假定对病毒免疫的个体。
  • 死者(D): 因病毒而去世的个体。

在房室模型中,个体根据时间和一些参数在房室之间转换。这些参数可以在“比率-概率-人口”流程图中进行描述,如本文:“比率描述过渡需要多长时间,人口是该过渡适用的一组个体,概率是个体发生过渡的概率”。**

流程图形式的模型

从数学的角度来看,我们的模型是一个由 6 个常微分方程(ODE)组成的系统,每个方程代表给定固定的时间(t)变化时一个房室值的变化。

颂歌形式的模型

其中,对于流程图和 ODE 表示:

  • S(t): 时间 t 时易感人数
  • E(t):t 时刻的暴露数(E)
  • I(t): 在时间 t 感染的数量(I)
  • H(t):t 时刻住院人数(H)
  • R(t): 在时间 t 恢复的数量(R)
  • D(t): 在时间 t 死亡人数(D)
  • 人口总数。N = S + E + I + H + R + D 在每个时间 t。
  • tInf (传染期):受感染个体可能将病毒传染给他人的时间段。
  • β(有效接触率):单位时间内个体之间导致感染的接触次数。也是病毒的基本繁殖数 R0(总易感人群中一个感染个体平均感染多少个体)除以 tInf。( beta 决定病毒传播的“速度”)。**
  • u(t) :控制措施的强度,直接降低β(注意:0 < = u(t) < = 1)。控制措施可能包括强化卫生协议、社交距离、封锁等。有苹果移动趋势或者谷歌社区移动报告,可以作为逼近 u(t)的第一步。**
  • tLat (潜伏期):个体只暴露于病毒,但不传染给他人的时间段。
  • 那些影响医疗系统能力的人住院的时间。
  • p mild:感染时仅出现轻微症状的概率。****
  • p 死亡:****住院时死亡的概率。当医疗保健能力不堪重负,没有更多的病床或 ICU 可用时,该参数被认为具有相当高的值。在我们的模型中,它将是 H(t) (当前住院人数)和 Q (卫生保健系统能力)的函数。

让我们提供一个直观的例子来更清楚地解释这个模型是如何工作的。假设一个群体,其中有 99 个易感个体和 1 个受感染个体。这个人在时间 t=1 时,立即将其他人暴露于病毒(立即,因为这里的比率=1)。还有多少人——取决于β和种群中剩余易感个体的比例(S/N ),以及控制强度 u(t)。所有暴露的个体,在潜伏期(tLat)后,也受到感染(所有,因为这里的概率= 1),除了开始时的那个个体。反过来,他们开始将其他人暴露给病毒,导致病毒快速传播。**

在他们的感染期(tInf)过去后,他们中的一些人会过渡到康复期,一些人会出现更严重的症状并过渡到住院治疗(这取决于只出现轻微症状的概率——p mild)。从那里,在时间 tHosp 之后,他们可以以概率 pFatal 过渡到死亡间隔,或者以概率(1-pFatal)过渡到恢复间隔。如果在某个时间点发生医疗容量溢出,pFatal 会显著增加,因为它是我们模型中的一个功能参数。

背景—控件

什么是最优?

我们定义了一个模型,它反映了【估计曲线】**【拉平曲线】部分,但它仍然缺乏最优控制。让我们假设,如果以下两个条件都满足,则控制强度 u(t)在时间 t 是最优的:**

  • 条件 1 无医疗容量溢出。住院人数(H)应始终低于医疗能力(Q)。否则,如我们的模型中所定义的,pFatal 参数增加,导致更多的致命病例。
  • 条件二。控制强度 u(t)最小。尽可能小,防止容量溢出。由于对经济和社会的不利影响,我们不想保持严格的控制太久。

  • 重要提示:疫情发生后,当人群获得足够程度的自然免疫(群体免疫)或足够数量的人群接种疫苗时,控制 u(t)可能达到最小值,因此不存在第二波疫情的风险,因此不需要采取控制措施。然而,这里我们不考虑疫苗的发展,只考虑自然群体免疫,它被认为在发展后保持不变。

因此,如果 u(t)最小化容量溢出和控制措施,则 u(t)可被认为是最优的。在数学上,如果 u(t)最小化以下成本函数 C(u) ,则 u(t)在我们的模型中被认为是最优的:

其中:

  • T :时间段总数
  • H(t):t 期间住院人数(通过求解 ODE 系统得出)
  • Q(t) :医疗保健系统在 t 时期的能力(在我们的模型中,假设它是常数)

下面的图表也说明了公式背后的想法。

在成本函数的等式中,第一项占容量溢出曲线下的区域,第二项占控制措施曲线下的区域。通过最小化这些项的组合,我们确保定义的条件 1 和 2 都得到满足。但问题是——使用什么技术来最小化如此复杂的成本函数?****

如何优化?

我们说过,我们需要为每个时间段 t 选择这样的 u(t) ,使得 C(u) (“我们控制的成本 u ”)最小。当我们想要对一个 2 年的时间段建模时,其中 T = 730 天,我们需要选择 730 个不同 u(t)的组合,这将最有效地最小化 C(u)!这种类型的问题可能需要为大规模非线性动态优化定制的高级求解算法,这些算法本质上是复杂的,并且需要大量计算资源来找到精确的最优解。

然而,在本文中,我们将开发一种更简单的方法**,它将在几秒钟内引导我们找到一个非常近似的最优解,消耗更少的资源并使用众所周知的 Python 库,如 SciPy 和 Numpy。我们还将在“比较”部分将我们的解决方案与使用高级求解算法获得的更精确的解决方案进行比较。****

因此,我们不是一次为整个 T 找到几十个不同的 u(t) 的正确组合,而是:

  1. 将时间段 T 分割成相等的时间范围( h )。
  2. 用固定的 u 在单个层位上运行我们的模型,并测量我们的成本函数 C(u) 的值。
  3. 基于测量—借助相对简单的最小化算法,调整我们的固定 u,使 C(u) 最小化。
  4. 找到最小固定 u 后,继续下一个层位,重复步骤 2 和 3。同样的逻辑适用于所有的地平线。

这种方法,当我们在模型运行期间根据它自己的测量结果调整我们的模型时,被称为简单模型预测控制 (MPC)。在这里的一系列视频中,可以很好地解释模型预测控制如何应用于新冠肺炎模型。

我们的方法也可以说明如下。

在这里,我们将我们的时间段分为 4 个时间段。在第一个地平线 t(h1)期间,我们看到,没有容量压倒的唯一 u 是“强的”,因此应用它。在 t(h2)处我们看到不再需要“强”控制 u ,唯一同时满足条件 1 和条件 2 的 u、为“中”,于是我们将 u 调整为“中”。类似地,在 t(h3)处,我们看到,“弱” u 是唯一最优的,并将我们的 u 调整到它。在 t(h4)处,控制措施可以最终放松。

这种方法相对简单,给了我们额外的灵活性。我们可以声明,我们将每周(h=7 天)或每月等调整我们的 u 。,这是一个更现实的控制策略。然而,这种简单性和灵活性是有代价的。为了得到一个近似的最优解,我们必须仔细选择我们控制干预的频率(f)和正确的控制范围(h)。****

编码——模型

让我们创建一个简单的 Python 类,它将存储模型所需的一切。我们类的 init 方法:

  • 接受每个需要的参数,如 R_0、tInf、tLat 等。
  • 有一个可选参数 dt (求解我们的 ODE 系统所需的步长)。例如,如果 dt = 0.1 并且 n_periods =730 天,我们将有 730/0.1 = 7300 个时间段,这在求解 ODE 时给了我们更好的精度。
  • 有可选参数: rInf —每天新感染个体的真实数据, rU —控制强度的真实数据(u)。rInf 数据可以允许我们将我们的模型的预测与真实数据进行比较,而 rU 也允许我们在已经应用了某种控制之后对最优控制进行建模。

MSEIR 类接受我们的所有参数,并执行一些需要立即执行的基本转换:

  • 它根据 dt 变换 rInf 和 tU
  • 它计算参数β(作为 r0/tInf)**
  • 它基于 n_periods 和 dt 定义了我们的总体建模周期 t,

现在,让我们定义 ODE 系统,我们将在我们的模型中解决:

  1. 我们首先定义一个方法 _ovf 。它将计算我们的功能参数 pFatal ,假设该参数具有某个更高的值 — pOvf,,以防医疗容量溢出。
  2. 然后,我们在方法 _ode 中定义我们的 ODE 系统。它接受 cU(这是我们当前的控制措施强度 u(t))和我们人口的初始条件数——易感、暴露、感染等个体的初始数量。隔间。

_ode 方法根据当前的给定值以及我们之前定义的所有参数和规则,计算下一个时间段我们的区间中的值。在数学方面, _ode 使用的技术是求解 ode 的简单数值欧拉法。可能有更复杂的技术,可以提供更高的精度,我们将在“比较”部分将我们的解决方案与它们进行比较。****

从逻辑上讲,下一步是创建一个方法,该方法将为每个时间步长运行 _ode ,以获得所有区间的预测值。这是通过方法求解完成的。

在这个方法中,我们首先用区间的初始值创建一个列表 C 的列表,稍后用下一个值填充它。我们还定义了 yUf 变量,负责识别 U 是固定的还是有一些关于控制措施的真实数据。此外,U 根据模型中使用的步长 dt 进行变换。

关键的解决技术在于循环的。对于每个时间点 t,我们选择必要的控制 cU,并使用列表 C 中的最后值作为隔间的初始值,运行 _ode 方法。我们将 _ode 的结果存储在变量 nVal 中,并将其追加到 C 表中,所以它们成为最后的值。在循环的结束后,我们得到最终解。****

该模型的完整代码如下所示。

正如您所注意到的,我们当前的模型只有不到 50 行代码。请随意尝试!

编码—控制

目前,该模型包括“估计曲线”和“平坦曲线”两部分。但是最优控制呢?要对它进行编码,我们需要 SciPy,这是 Python 中科学计算的事实上的标准库。我们需要 simps 方法来计算成本函数中的积分,以及 minimize 方法来应用函数最小化算法。让我们将成本函数添加到我们的类中。

Method _ costf,类似于求解方法,得到我们的 ODE 系统的解。但是它不是返回解决方案,而是基于该解决方案计算成本函数,并返回成本函数的值。它接受控制 u(t)(作为 x)和类似于 _ode 方法的初始条件。这样的设计需要使用 scipy.minimize 在上面。

有了成本函数,让我们根据我们的简单模型预测控制框架修改我们的求解方法。

关键的修改在于 for 循环——U 的优化仅在以下情况下开始:

  • 优化参数被设置为真。**
  • 在真实数据 rInf 中,当前时间 t 超过 t (如果我们向我们的模型提供真实数据,并且想要在之后对最优控制进行建模)。
  • t 与频率参数(freq)相匹配,因此如果我们将控制干预的频率设置为 7 天,则在 t=7、t=14 时将满足该条件,依此类推…

优化开始时-当前隔离专区值和优化时间范围(hor)存储在 args 变量中。Args 和 _costf 被提供给 SciPy 的最小化方法,该方法使用选定的最小化算法来寻找在给定控制范围(hor)期间 _costf 在什么 cU 下具有最小值。我们还为 cU 设置了一些界限,因为我们的控制强度是一个值,总是在 0 和 1 之间。SciPy 中适合我们的有界极小化问题的极小化算法有:‘L-BFGS-B’,‘TNC’,‘SLSQP’‘trust-const’。在本文中,我们不会深究它们背后的数学原理,它们在这里有记录。注意,对于我们的问题,‘SLSQP’似乎在收敛、精度和时间方面工作得更好,所以它被设置为默认值。**

此外,为了方便起见,我们的 solve 方法将最终解决方案转换为 Pandas DataFrame,并向其中添加一些附加数据:时间段、U 和 Q 值、rInf 数据和 mInf 数据,后者是模型预测的每日新感染个体的数据。它简单地计算为每个时间段易感人群的减少。

我们的模型现在已经完全投入使用了。只是为了最终确定它,让我们添加一个产生代表性情节的方法。我们将使用一个 plotly 库来产生可视化效果。为了方便起见,我们的 plot 方法也将我们的时标 t 转换为从 sdate 参数开始的真实日期。此外,您可以在 size 参数中指定绘图的大小,并在 comps 参数中指定要显示的隔离舱。

这是我们的最佳控制和绘图模型的完整代码。

这是你可能得到的结果的例子。

第一个支线剧情,在顶部,是我们的控制措施强度 u(t),第二个支线剧情是我们的车厢值。这里,我们选择仅绘制感染、住院和死亡(I、H、D)以及医疗保健能力(Q)。最后一个子图显示了我们的模型(mInf)预测的以及输入真实数据(rInf)中陈述的每天的新感染病例,如果向模型提供了一个输入真实数据的话。

使用案例

假设有一个城市 X ,拥有 5 00 万居民的人口和1 万张病床和 ICU 的医疗保健能力。2020 年 11 日,第一个人似乎感染了具有新型冠状病毒特征的病毒(导致新冠肺炎)。所有的特征都在这篇文章中作为一个整体:****

不幸的是,流行病的爆发无法在一开始就被抑制,也没有疫苗。幸运的是,我们现在有了一个模型,它允许我们基于非药物干预(社交距离、面具、封锁等)来估计不同的场景最优控制策略。).我们想为未来两年的可能结果建模。让我们用我们将在模型中使用的所有参数创建一个 Python 字典。****

现在,让我们使用我们的模型,估计第一个非常简单的场景。

场景 1。【零点控制】

在这种“无所事事”的情况下,我们没有任何控制权,因此没有与之相关的经济或社会成本。但在疫情结束时,我们有 229,689 人死亡,超过所有感染者的 5%(死亡率为 5.01%)。

让我们看看,如果我们的目标是使用恒定控制策略来“拉平曲线”,会发生什么。**

场景二。【恒控制】

这里,应用的控制措施是 ~ 0.55 恒定(在最小水平以防止容量溢出)。我们看到,死亡人数 大幅下降至 42481(死亡率 2.56%)。然而,有两个问题。首先,控制持续时间是无限的,因此封锁或任何其他措施可能永远不会放松。其次,这是这里唯一的场景,在最后没有获得群体免疫(最后易感/总种群>*1/基本繁殖数,通过这篇文章中的公式)。因此,放松控制措施会引起新一轮的感染。*******

现在,让我们假设更现实的场景,在疫情爆发的前 120 天里,该市官员已经在出台了一些控制措施。让我们看看如果控制被立即移除会发生什么。**

场景 3:“从电流到零控制”

所引入的控制措施起初是成功的,但随后在 3 月 18 日发生了容量溢出,不得不将它们增加到 0.8 个点。经过大约 23 天的严格控制,它开始被删除。这个场景展示了从第一个被感染的个体开始 120 天后,如果它下降到零会发生什么。在这里,控制在 2020 年 4 月 29 日结束。我们看到,在一次控制结束后不久,第二波感染发生,导致医疗能力严重过剩。最终,这一政策导致207112 例死亡(4.72%病死率),确实更接近‘完全零控制’情景 1**

如果 120 天后官员突然透露如何最佳控制疫情会怎样?让我们考虑下一个场景。

场景 4:“从当前到最佳控制”(最佳锁定出口)

这里,在 120 天之后,在我们的模型中,控制趋向于尽可能的最优——每天发生最小控制干预,以便防止容量溢出。在这样一个封锁出口的完美案例中,与之前的场景(104,464 对 207,112 个人)相比,死亡人数几乎减少了两倍。尽管总体控制比严格 85%(就 u 项下的面积而言,889 比 480),并且持续到 2020 年 9 月 11 日,与之前的场景相比,延长了 125 天。**

就目前而言,我们考虑了两种情况,即官员们在疫情爆发的前 120 天采取了一些控制措施。但是如果官员们从一开始就有一个最优的控制政策呢?

场景 5:“恒定最优控制”

这里从一开始就考虑完美最优控制的情况。每天审查控制力度,并引入最低要求的措施。在这种情况下,控制在 2020 年 8 月 10 日结束,死亡人数为 93,526 人* ,死亡率为 2.56%。这里的关键点是致死率与持续控制的场景 2 相同,但是控制的有限持续时间为 179 天,并且严格程度要低得多。此外,除了第二种情况,这种情况意味着死亡人数最少。***

事实上,由于日常的精确干预,这种控制政策在实践中很难实施。如果官员们试图通过每个月左右的干预来实施最优控制政策会怎样?****

场景 6:“现实最优控制”

这最后一个场景与之前的相似,但更现实的干预频率为 43 天。控制稍微严格一些(769 比 717,根据 u 下的面积),并提前一周结束,在 2020-08-02。死亡总人数为 93632 人,与相同,死亡率为 2.56%**

场景总结

总共考虑了 6 种情况。

让我们提供一个表格,总结每个场景的关键指标。

很明显,最优控制方案比其他方案有优势。通过最佳控制,与零控制(从 229,689 人减少到 93,526 人)相比,有可能在疫情结束时将死亡人数减少近 60%* 。最优控制策略也具有与恒定无限控制相同的死亡率,但是它持续有限的时间,即 179 天,之后控制为零(T21)。此外,研究表明,每 43 天干预一次,而不是每 1 天干预一次,可以使最优控制策略更加实用,而且效果基本相同。***

比较

如前所述,对于常微分方程和大规模动态优化问题,都有更先进的求解算法。这里的文章就是一个很好的例子。那里的模型构建使用了 Python 库 Gekko,它提供了一组用于大规模非线性动态优化的工具。该模型使用内点求解方法进行 ODE 和动态优化,其中显著的 IPOPT 解算器在引擎盖下。

我们将使用该模型作为基准,但将通过添加住院和死亡区间对其进行修改,因此它将与我们当前的修改后的 SEIR (MSEIR)模型具有完全相同的区间。这里是的完整代码进行比较。

让我们对两个模型使用相同的一组参数,并比较结果。

下面是对比结果的图表。蓝线表示 Gekko+IPOPT 模型的解。

以及两种解决方案的主要结果的摘要表。

两个模型的 U(t)曲线相似,而 Gekko+IPOPT 模型产生的形状曲线更类似于这篇文章,在这里计算出精确解。已故的最终值是两个模型之间的等于。此外,Gekko 模型的求解时间,如其打印输出所示,等于 27.409 秒,而 MSEIR 模型需要 1.182 秒的挂钟时间来找到解。**

结论

在本文中,我们估计了流行病模型,该模型包括最优控制措施,并回答了如何在考虑经济和社会成本的情况下“拉平曲线”以及如何以最优方式进入和退出封锁或任何其他控制措施的问题。我们考虑了一个城市的情况,在那里具有新型冠状病毒特征的病毒已经传播,并且没有预期的疫苗。**

我们展示了最佳控制措施如何以最小的控制强度降低与疾病相关的死亡率。在 179 天的控制时间内,与“什么都不做”的情况相比,我们的最优控制策略产生的死亡病例减少了 60%,此后,与恒定控制情况下的无限时间和无群体免疫相比,在群体中获得了群体免疫。我们还将最优控制调整为更实用的政策,大约每月执行一次控制干预,而不是完美最优控制场景中的每日干预。**

我们用来估计最优控制的模型,虽然很简单,但它导致了一个很好的近似最优解,如比较部分所见。它的简单性也增加了好处:对于这种大规模的动态优化问题,计算时间惊人地快,以及巨大的灵活性,因为我们可以定义任何干预频率和控制范围,定制成本函数并添加变化的参数,如死亡率。**

该模型仍然充满了与确定性 SIR 框架和我们的简单模型预测控制方法相关的假设。我希望它能成为更先进的模型的起点,这些模型可以应用于真实的病例,并为现有流行病学模型的控制应用提供更多的信息。

这里是模型、场景和比较的完整代码。

参考

[1] M. Kantner,T. Koprucki,超越仅仅“使曲线变平”:用纯粹的非药物干预对流行病的最佳控制(2020 年),网址:https://arxiv.org/pdf/2004.09471.pdf

***[2] APMonitor,新冠肺炎最优控制响应(2020),网址:【https://apmonitor.com/do/index.php/Main/COVID-19Response ***

***[3] S .布伦顿,控制理论和新冠肺炎(2020),网址:【https://www.youtube.com/watch?v=BTLZu-1IMcE ***

[4] H. Froese,传染病建模:超越基本 SIR 模型(2020),网址:https://towardsdatascience . com/Infectious-Disease-modeling-Beyond-the-Basic-SIR-Model-216369 c584c 4

优化…目标变量(?)交易机器学习模型的例子

原文:https://towardsdatascience.com/optimizing-the-target-variable-an-example-for-trading-machine-learning-models-48a1587d7b9a?source=collection_archive---------23-----------------------

我们的目标是静态的吗?

Clem Onojeghuo 在 Unsplash 拍摄的照片

0.a)动机和…飞镖(?)

是的,你没看错,优化目标变量。你可能会想,“但是,那就像欺骗”或者“你能改变过去吗?”。别担心了!我既不是一个骗子,也不是一个试图改变过去只是为了改善他的机器学习模型的时间旅行者(利用这种能力还有很多更令人兴奋的事情要做)。

如果你去找你的第一个数据集,学习关于泰坦尼克号,在那里你尝试一切来预测乘客是否幸存,或者 MNIST 数据库,那里有你甚至不能识别的数字,你可能会有点困惑。“如果有乘客幸存,这个人能优化吗”或者“他选择 9 是 4 来提高他们的准确性吗?”

显而易见的答案是否定的。但是正如你将看到的,有时目标变量不是事实(可能是事实,但不是事实-事实)。所以今天,我们要谈论我们最喜欢的朋友,当它是关于监督学习!

我想把这个问题比作飞镖比赛(如果我们谈论目标,你能想出更好的例子吗?).典型的职业比赛分为几段,在这几段比赛中,选手们试图准确地达到 501 分,条件是在最后一次投掷中,飞镖必须进入“双程”,这意味着,到达外环上的任何区域或“公牛”(50),将结束这一段比赛。每个玩家每回合有三次飞镖。

摘自维基百科

从数字上看,很明显每个玩家都会试图在第一轮中获得尽可能多的分数。在实际比赛中是这样的:他们开始主要瞄准 60 岁。

当他们必须完成游戏时,有趣的部分出现了。想象你有 441 分的最后一个转弯(还剩 60 分)。你必须打出“双杀”,所以瞄准 60 是不可能的。稍加思考后,你扔出祈祷 50,奇迹般地你得到了它!。

你现在还有 10 分,所以你可以直接扔向外 10 分区域来结束游戏。你扔了,你甚至没有接近,你打了一个 8。在你最后的机会里,你瞄准外围 2 区。整个球场都在等待,你的对手在咽口水,你有了最后的想法“我什么时候成了飞镖职业选手?”,但你忘了那一秒,深呼吸,最后抛…胜负?你成功了!这条腿是给你的。

摘自维基百科和来自这里的飞镖

有数百种组合可以得到 60 分,所以每次投掷后,你必须灵活并检查你站在哪里(在这样做的时候,我看到了很棒的比赛,首先是这个和复仇这里,稍后感谢我)。不可思议,你可以向你的朋友炫耀你的飞镖知识,但我们能从中获得什么?

嗯,现实生活中发生的问题与飞镖游戏中发生的问题是一样的:你的目标是赢得比赛,但你可以扔向不同的区域来实现这个目标!镖靶是静态的,但你的目标可能会不断变化!。

好吧,但是你怎么把它和真正的问题联系起来呢?。别急,我先给你讲讲背景。

当你想训练一个机器学习模型进行交易的时候,有无数种方法可以做到。您可以训练自回归模型并跟踪预测的运动。此外,您可以创建解释变量来预测积极或消极的目标,定义战略要点中的信号,如果讨论这是本文的目标,我认为我们可以讨论您的想法几个小时。

我们的目标与标题相关,因此,我不会详细阐述,因为定义一种方法来面对这个问题是一个独立的世界。相反,我将向您简要介绍一种具体的可能方法。如果你觉得你想知道更多,我建议你从以下几点开始:

[## 交易的概率机器学习方法+ MACD 商业理解

在文章的最后,你会知道如何用概率的方式构造一个交易问题。此外,您将…

towardsdatascience.com](/probabilistic-machine-learning-approach-to-trading-macd-business-understanding-6b81f465aef6)

这也是一个很好的第一步,如果在读完接下来的内容后,你对一些概念感到不知所措,想要清楚地理解它们。它还有一些关于模型构造的重要细节。技术方面的问题将在这里浅尝辄止。但是,不要担心,如果你对优化目标变量的想法更感兴趣,我为你准备了一个温和的介绍。

事实上,我们将使用股票价格来阐述所有的想法,并不意味着你需要知道任何关于交易留在这里。交易问题将只是一个工具!。

此外,我们将在问题表述和模型的结果解释方面做出巨大努力,将它们与商业价值联系起来,这不仅仅是为了准确性而奋斗!

所以留在这里!这完全值得,因为我属于方型的人,让我们从时间表开始吧!

0.b)议程

  1. 快速概述分配给问题的结构及其与 darts 的联系(也是对流失问题的认可)。
  2. 我们将描述为什么这是一个提高我们预期回报的机会,展示从币安收集的 ETH-USDT 配对数据的见解。
  3. 我们将考虑优化目标变量的想法,在我们的头脑中,在你的屏幕上阐述问题,引导我们思考如何解决这个问题。
  4. 是时候应用我们将学到的一切了!我们将训练不同的随机森林,以检查我们的目标变量的哪个组合使我们的回报最大化。
  5. 最后回顾一下我们的主要成就和对这一想法的进一步改进。

1)问题概述,还有更多飞镖!

考虑一下交易问题,假设我们有一些解释变量,它们都是基于股票交易量和价格创建的。我们还开发了一种方法来确定先发生什么:在接下来的 N 个周期中 I%增加或 D%减少。

我们的目标是根据我们的变量(监督学习)来预测这两种结果中哪一种更有可能发生。).这可以看作是一个二元分类问题。当第一个收盘价上涨时,我们用 1 标记,否则用 0 标记。我们都准备好了!

等等……是吗?但是,I%和 D%呢?我们如何选择这些数字?最后,我们需要开始的问题!

如你所见,我们的目标会有所不同,这取决于我们选择哪些数字来决定成功或失败。如果我们首先达到 I%,我们就称之为我们的 T/P,否则,我们就称之为 S/L

为了更好地理解这一点,我为你准备了一个简单的图示。让我们用我们未来公司“概率 ML 贸易公司”的股票价格来分析一下,1 只股票的价值在第一天将是 100 美元,在随后的 12 天里,这些值将分别是 96,110,104,91,84,93,107,118,111,101,91,80。

在下面的图表中,将有四种情况,每个人将代表相同的股票价格。你会看到 T/P 和 S/L 点是绿色和红色的水平线。每个散射颜色将是一个增加-减少(I-D)的组合。顺序如下:

  • 第一种情况,黄色散射:10%I-10%D。
  • 第二种情况,青色散射:15%I-15%D
  • 第三种情况,蓝色散射:15%I-20%D
  • 第四种情况,洋红色散射:20%I-20%D

同一数据集上的不同目标变量。

尽管我们公司最终崩溃了,但理解正在发生的事情是一个很好的视觉化。

正如你所看到的,当价格超出预定线时,我们就到达了终点。第一种情况和第三种情况的目标变量是相同的。但是对于第二个和第四个,情况恰恰相反。基于相同变量训练的模型可能认为价格会上涨,而另一个模型可以肯定价格会下跌。有趣吧!。

这就是我告诉你我们的目标变量是一个事实,但不是事实-事实的意思。这是一个事实,因为我们无法改变收盘价——以我们的飞镖为例,我们无法改变镖靶——然而,这不是一个事实——事实,因为根据我们为结果设定的条件,我们的目标可能会有所不同————我们的目标可能是“双倍”——

我相信这可以应用于不同类型的问题,所以如果你开始考虑你的目标变量,而不是一个静态的建筑,而是一个乐高积木,我相信你可以为自己和你的公司获得很多价值!。

1.1)少量流失参考

举个简单的例子,当你定义客户何时离开时,让我们考虑一下流失问题。需要做出一些决定。设想一个月订阅,当你在设计问题时,当客户要离开时,你必须选择。如果你选择两个或三个月,而不是定义他在下个月“翻腾”,会怎么样?

Alex Holyoake 在 Unsplash 上拍摄的照片

这可以让你找到不同的模式!想象一下,当客户不打算流失时,但当他们只是在思考时,保留策略会有更好的结果。也许使用更长的时间段会导致更高的保留率!独立于模型,你的商业目标可能会有更好的结果。因此,我们需要根据问题的业务属性来定义我们的度量标准。

1.1 节,只是让你看看这个想法的应用的另一个例子,但是我知道你仍然对我们将如何在我们的交易实际问题上测试这些概念感到有点好奇,所以和我呆在一起吧!我并没有在第一部分做出如此荒谬的努力,以至于忽略了核心内容。事实上,这个介绍只是一个工具,激励你去阅读接下来的内容。

2)机会

好吧,为什么这是一个机会?为了解释这一点,我们有必要(重新)回顾一下预期收益的概念。简而言之,它只是一个场景的回报和它的概率之间的乘积之和(此处了解更多细节)。

我们的目标是最大化预期收益,除了模型的准确性,你还应该考虑将解决最大价值的公式。

在特定的交易问题中,我们需要把 I%和 D%和这个表达式联系起来。做一个简单的开始,让我们想象一下,我们甚至不会训练一个模型。我们想随机进入市场。我们会选择不同的 I%和 D%的组合,我会在图表和等式中向你们展示发生了什么。同样,假设我们将持有多头头寸

技术说明:我们今天工作的数据将从币安检索,选择 ETH-USDT 对的最后 550 天,间隔 5 分钟。有 157.912 个数据点。

我们将使用 N=200,每 5 分钟一次,大约 17 个小时的结果。如果价格从未越过障碍,将被标记为“没有结果”。从币安收集数据的代码在这里有更详细的解释

让我们看看如何用重要的特性来检索数据。

在这种情况下,我们将假设,如果我们“没有结果”,我们将失去的只是费用(如果您激活您的币安档案,您将获得 0.075%的接受者和 0.075%的与 BNB 支付费用的制造者)。我们将每次购买 100 USDT ETH。这是定义结果的方法。

接下来,您将看到我们将训练不同的模型,因此代码是在牢记这一点的情况下创建的。矩阵里有所有的组合。这是我们保存每个场景的方式:

首先,我们将看到两种不同的情况(I=3%,D=-1.5%)和(I=1.5%,D=-1.5%)。我们能从这两个人身上期待什么?如果你的第一个想法是我们可以在第一个案例中预见到更多的“减少”和“没有结果”的案例,我们可能开始相互理解了!。我们来对比一下!。

基于 I=3.0%和 D=-1.5%的病例结果百分比

基于 I=1.5%和 D=-1.5%的病例结果百分比

发生这种情况是因为 D%的值越高,价格越难达到该点。

但是,他们的预期回报是什么呢?好了,我在这里给你留下了通用的公式(0。),然后是两种情况的计算。该值将假设 100 个条目,每个条目 100 个 USDT(如果您只想要单个实例的预期回报,只需将预期回报除以 100)。

随机进入市场的预期收益

对于第一种情况(I=3%,D=-1.5%):

基于 I=3.0%和 D=-1.5%随机进入市场的预期回报

对于第二种情况(I=1.5%,D=-1.5%):

基于 I=1.5%和 D=-1.5%随机进入市场的预期收益

好吧,这些公式可能很烦人,但它们是开始构建我们将要做的事情的极好基础。我不仅仅是在两个案例中这样做的。事实上,我为《黑客帝国》中的每一种组合都做了一个网格。

因为我知道你在等着看一些东西,我创建了这个 3d 散点图,y 轴是积极的结果障碍,x 轴是消极的,z 轴将代表一个条目的预期回报。

我使用了一些我们将在下一节看到的结果,所以为了避免误解,这里是要点

如你所见,我们不能用随机进场来战胜市场。但是,通过选择在[2,-0.3]区域附近,我们得到接近 0 的值,尽管有费用和随机性!。因此,根据 I%和 D%的组合,我们进入市场可能处于更好或更坏的位置,只要仔细定义我们的目标变量。

但是正如你所知道的,我们需要训练一个模型,所以程序并不像这样直接。但那是下一节的事情,这一节的任务,只是向你们介绍,我们的目标变量的不同组合如何影响我们的预期收益,取决于它的行为。

3)我们能解决这个问题吗?

思考一个提议的解决方案时,我们需要稍微停顿一下,给我们的创造力发挥的机会。此外,我们不会在这一部分编写任何代码。我想引用爱因斯坦关于解决问题过程的陈词滥调,或者亚伯拉罕·林肯关于 T2 斧头的陈词滥调。但正如你将在嵌入的文字中看到的,没有证据表明他们说过这些话。不管怎样…我知道你明白了。

照片由乌古尔·皮克Unsplash 上拍摄

我们路线图上的第一件事应该是:什么实际上代表了更高或更低的 I%或 D%?。您是否注意到,在我们的场景图表中,它们的值越高,等待时间越长的可能性就越大?好吧,让我们详细解释一下为什么会这样。

第一个原因似乎是显而易见的:考虑到某个特定时间段的增加或减少并不是那么高,我们需要等待更多的时间段才能达到该值。如果我们有一个趋势,价值需要以自己的速度前进的时候到了。

因此,我们可以注意到,数据粒度(时间间隔)和预期的 I%或 D%之间必须有一定的比例。如果我们想预测股票在未来一年的价值,看过去 8 小时是没有任何意义的。正因为如此,我们应该在一个合理的邻域中寻找这些值。

第二个原因更重要:想象一下,我们在上涨趋势前买入,在价格突破这个阈值几个小时后,我们希望价格上涨 5%。我们想“为什么我们现在必须离开?…正在上升”。我们等了一会儿,发现价格开始下降。可能会有逆转!我们可以误导我们的模型!

照片由杰米街Unsplash 上拍摄

为什么反转如此重要?因为当我们进去的时候,信号显示市场正在上涨,而且确实发生了!但当出现逆转时,迹象可能恰恰相反。我们看到的信号只在某一点上有效!所以如果 a 在周期 T 上有一个信号,那个信号每秒钟都会开始失去值!。

当 I%或 D%的值太小时,情况完全相同:价格的轻微波动可能会产生与信号相反的结果,因为我们为股票移动定义了一个超级短的空间。

那么,从这里我们能学到什么呢?这些信号在 I%和 D%上有一个阈值,它们不再与结果相关,导致模型显示出比它们应该显示的更多的随机性。

3.1)我们的方法

好了,现在我们有了一些原则,可以开始考虑解决方案了。我们如何选择我们的 D%和 I%?为此,我们应该重新思考我们的目标是什么:最大化预期收益!我不会停止重复它!但我们如何做到这一点,我们不能构建一个公式,并根据检查约束的目标函数进行优化,因为我们需要首先训练模型。

为了继续,我们需要定义这个特定案例的一些东西。
我们将假设我们已经完成了所有的特征工程过程,并选择训练一个随机森林。

那么…我们将如何评估模型性能?我们可以选择一些数据,并将其分成测试集和训练集。测试数据将代表一个我们不知道的场景,它可以被看作是我们将使用的策略的模拟。为了避免误解,我们将随机但均衡地选择数据。

3.1.1)我们不会做什么

你可以匆忙采用这个解决方案:

该模型将为我们提供进入市场的可能性。如果我们可以相信 predict_proba 方法(它决定了一个特定案件的结果的几率,从此将成为我们的主角),我们就知道如果我们进去,成功的概率是多少(我们将称之为 P(p))。此外,如果我们将 P(p)乘以场景的回报,我们甚至可以在训练模型之前就知道我们的最佳选择是什么。

值得一提的是,如果我们有两个结果(P(n)是一个负结果的概率),P(p)+P(n)=1,predict_proba 方法知道这一点。

例如,我们评估一种情况,我们选择 I=1.5%,D=-1%。如果我们不考虑费用,我们只需要 0.4 或更高的 P(p)值(计算如下)。但是,如果不看模型和它的结果,似乎很难优化我们的目标变量的组合:我们如何知道有多少情况将满足该条件?。

示例公式

另一个问题是,一般来说,模型不是完美校准的,predict_proba 可以告诉我们 0.4,但在测试集中,它可能做得更好或更差。这里的关键是我们不能避免训练模型。

3.1.2)在这个解决方案中,我们信任!

我们的解决方案需要评估我们训练的每个模型,并检查每个 P(p)的回报,这可能会给我们带来正的金额。为了做到这一点,你将在下一节看到关于我们将如何创建返回场景的图表,但现在,我将解释这个想法。

我们将训练我们的模型,并利用测试数据,在 P(p)应该高于特定值的条件下,我们将计算每个数据点的正面结果(P(p))的概率。我们将评估每一个概率高于某个数字的案例,我们将检查其中有多少实际上成功了。

我们可以假设我们将在每笔交易中投入相同数量的资金:100 USDT。由于我们的最终金额的简单性,这就是在百分比上做这件事的重要性所在。我们可以计算真实的回报,只需要稍微改变一下我们原来的公式。

返回选择市场条目。

你注意到不同了吗?它只是将“% Cases”更改为相应的“Cases”例如,如果我们训练一个模型,其中 I%=1.5,D=-1%,其中 1000 个数据点的概率 I>0.5。我们会看到其中有多少是准确的。在这种情况下,我们会说 450 有积极的结果,50 没有结果。我们可以这样翻译:

回报计算示例

在这种特殊情况下,我们将在期末获得 24.875 USDT 的利润。

您可以注意到,返回的值取决于案例的数量和条目的质量。在模型的情况下,如果我们要求更高的概率,我们将有更少的情况。这是我们的主要权衡!许多“常规条目”可能比少数“好条目”更差或更好

所以会有两个优化过程!首先,给定每个模型的 P(p ),我们将最大化回报。之后,我们将评估所有组合的每个模型的最佳回报!

这将类似于网格搜索,但在我们的情况下,我们不会校准参数,我们将比较他们的回报!正如我所承诺的,我们将改变我们的目标变量,而不是改变参数!

似乎是个好计划?如果您同意,让我们看看我们刚刚构建的解决方案的结果!

4)真相时刻!

所有的精心制作过程可能有点苛刻,但它即将得到回报!

技术说明:我取了 20%的平衡数据用于下面的评估,另一部分用于训练模型。假设我们使用了 550 天,我们可能会说在 110 个随机的日子里预期会有回报。我更喜欢这种方法,而不是在上升趋势或下降趋势中进行评估,因为我认为这更可靠。

此外,本节我只补充模型训练和模型评估的要点。图表代码会在 gists 和 jupyter 笔记本中,我会在这个 repo 中留给你。我刚刚上传了结果,因为模型太重了。

遵循我们在第 3 节中设定的原则,如果我们有 18 个小时来观察结果,那么设置 0.3 个隔离屏障是合理的。还有,事实上我们无法知道什么时候是太多或太少的信号来误导我们的模型,我们应该尝试很多组合!。

在本节中,我们将训练许多随机森林,每一个都基于 I%和 D%的不同组合(“矩阵”)。这将引导我们找到确切的概率,我们应该要求的模型,以确定我们是否可以进入市场,最大化我们的回报。

这里是模型的代码,我保存它们是因为每个模型的训练需要大约 5 分钟,而对于 169,你可以自己计算一下,了解一下仅仅训练它们就需要一个晚上:

在第 4.1 节中,我们将通过一个组合来了解每次我们测试一个新的组合时会发生什么。在第 4.2 节中,我们都在期待什么:最终的目标变量优化 …!

4.1)我们的第一个完整场景

正如我之前告诉你的,这里,会有更多的图表!我将从展示一个开始,这样我们可以巩固我们在上一节中所做的内容。第一个柱状图包含 I%=1.5 和 D=-1.5 组合的模型结果。此外,每个条形顶部的病例数。

X 轴表示 P(p)>X 输出(所有满足此条件的案例)的筛选器,我们将使用它来选择模型预测为市场进入的案例。条形图的高度代表成功率,散点图的点可以看作是特定点的回报。

不要觉得不知所措!这里有很多信息,但是如果你停下来理解它,你会发现没有什么可怕的。在这一节结束的时候,你可以重温这个图表,我发誓!这完全说得通。我将把这个分析分成两部分:第一部分,我们将讨论 predict_proba 给我们的信息,第二部分,我们将分析回报。

4.1.1)预测概率重要性

你可能已经注意到 predict_proba 方法是这篇博文的亮点,现在我将向你解释为什么。数据科学过程的这一部分至关重要,因为这是我们理解模型给我们的信心的时候。

对于这个组合,我将根据概率将它们分成三份,并解释这个数字在我们的情况下代表什么。请注意,我用的是 0.5,因为 I%与 D%相同:

  • P(p) <<0.5: What’s the difference between going into the market randomly and filtering these cases? Well, the model is telling us that he (I’m talking about him as a person, I know) has some clarity and thinks that the outcome will be negative. For our situation, this means that if we avoid those cases, we are not sure if we will have a good outcome, but at least we will leave behind those that are bad-looking.
  • P(p)~0.5: If we choose the cases around 0.5, we will be hitting the most uncertainty scenarios. The model is practically saying you ‘flip a coin’. For cases like this, we should avoid using the confusion matrix, these cases are meant to be less accurate!
  • P(p)> >0.5:这是我们最好的猜测。模特在说,“如果可以选择,就挑这些!”。这就是为什么它们很重要。我们的目标不是预测所有的情况,我们只想对其中的一部分有信心。

现在回到图表,您可以注意到每个条形都是基于 x 轴数字过滤的特定置信范围。成功率越来越高。这是因为另一个右边的每一个条形都比左边的条形更挑剔。。

这也意味着,当我们向右走的时候,我们的情况更少,正如在第三节中讨论的,随着情况的减少,我们的回报达到了一个不能再攀升的点。但那是 4.1.2 节的事。

我强调 P(p)过滤器只是为了提醒您,选择的阈值应该与问题中的商业价值相联系,使用 AUC-ROC 曲线可能是不够的。你需要把模型的结果和你的目标函数联系起来!。

来自 imgflip

4.1.2)返回时间!

回报是用我们在上一节中构建的公式计算的。我只是根据 S/L 和 T/P 点,对“无结果案例”给他们一点惩罚或奖励。例如,如果我们有[-3.6,0.3],该值很可能超过 0,因此该效果被包含在内(代码中有详细说明)。

如果你认为我们每笔交易都有 100 USDT,不要因为图表显示的 110 天回报率是 750%而惊慌失措。回报没有那么高,因为你可能有很多同时交易等待达到阈值。所以你需要超过 100 个 USDT 来应用这些策略。

因此,回报是我们将寻求优化的价值。现在分析散点图点会更容易。在这种特殊情况下,你可以清楚地看到,回报找到一个点(大约在 0.485),在那里它有 0 回报,并继续上升,直到 0.55,在那里它达到最高回报。之后不出所料,往下走,因为太挑剔涉及机会少。

看到这一点给了我们一个很好的洞察力:仅仅通过选择一个正确的 P(p)阈值就可以决定是否达到我们的业务目标。

4.2)优化目标变量!

但是,如你所知,我们不会就此止步。我们的主要目标是优化目标变量,定义最佳的 I%和 D%组合。现在是时候来评价这些车型了!下面的代码可以避免重复前面几节的整个过程,但我还是会向您展示它。这是由于模型和数据的保存和加载过程。它可以通过一个更快的选项来避免。

我们加载数据和具有各自特征的模型,重新创建训练过的环境。在代码的后半部分,我们使用 P(p)过滤器来保存成功率的所有概率,以便在将来进行分析。

对其中的每一个,我们将重复本节第一部分的程序,以获得局部最佳回报。之后,我们会比较每个组合的最佳回报。在这里你将看到我们最佳的五款车型回归!

我们最好的 5 个模型的 P(p)与回报。动画的要点在这里

我们注意到的第一件事是,第一个 P(p)滤波器的回波是相同的。这是因为模型不会给我们低于 0.25 的概率,所以回报和随机进入市场是一样的。另一件重要的事情是,在所有的模型中,回报率回到 0,因为没有足够的案例达到 P(p)值。

正如你所看到的,在这五种情况下,当 P(p)高于一个概率可以处理 I%和 D%之间的差异的值时,模型越过 0 返回障碍。比如模型[2.4,-3.6]比其他几个持续的时间稍微长一点达到顶峰,因为你需要更多的正面案例来中和负面的。

我们的赢家[3.9,-3.6],能够达到超过 3000 USDT 的回报!这令人难以置信,因为如果我们只使用第 4.1 节的标准——只评估一个组合——我们最终只会得到 750 USDT 的回报。

优化目标变量的价值是惊人的!现在,您已经了解了理解我们在本节开始时看到的图表所需的所有重要内容,我现在可以添加相同的图表,但针对的是我们的最佳情况。

我们的最优案例,比较 P(p)与成功率,回报与案例数之和。要诀

最佳情况是寻找-3.6%的 S/L 和 3.9%的 T/P,并且我们应该进入 P(p)>0.53 的每种情况的市场。看到这里,我们可以带着自负的微笑结束这一节。每笔交易的预期回报大约是 0.85 USDT,包括费用!

5)简单回顾一下,回头见!

我在这里想要做的是将我们的注意力集中在可以给我们模型的商业价值上。我们动态地改变概率过滤器和结果定义来提高我们策略的回报。

进一步的改进可以通过交叉验证的方式进行分析。此外,回报的衡量还可以做很多事情,例如,它可以除以同时平均交易的次数,以标准化每一美元的投资,但我认为这对今天来说已经足够了。

我希望您可以看到,除了模型准确性之外,还有其他可以评估的东西。如果你读过我以前的一篇文章,你就知道接下来会发生什么。我们的主要收获:

  • 我们现在是飞镖专家。
  • 我们知道我们的目标变量可以根据问题陈述而改变。
  • 我们看到了在概率模型上定义不同阈值以最大化我们的业务目标的重要性。
  • 我们制作了一个应用案例,以便更好地理解如何在实际环境中应用这一点。

各位,今天就到这里。如果你到了这一步,我希望这二十多分钟是值得的。

如果我感受到你的热情支持——就像我对上一个一样——我可以给你带来新的东西!请在下面留下你的评论和想法!读懂你的想法对我来说超级重要。

这是强制性的,你不能用这个策略投资或交易,因为这篇文章的主要目的是讨论目标变量。交易的理念:它只是一个获取真实问题和真实数据的工具。如果你遵循这个未经证实的系统,你很容易失去你的存款!。

如果你喜欢,就在 MediumLinkedin 上关注我。如果你想给我写信,我最近在推特上。我很乐意与你交谈!

来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指南 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

使用 Python 的订单批处理提高仓库生产率

原文:https://towardsdatascience.com/optimizing-warehouse-operations-with-python-part-1-83d02d001845?source=collection_archive---------7-----------------------

设计一个模拟模型来评估几种单一提货人路线问题策略对您的提货生产率的影响

使用 Python 的订单批处理提高仓库生产率—(图片由作者提供)

配送中心(DC),在拣货路线中从一个地点到另一个地点的步行时间可占操作员工作时间的 60%到 70%

减少步行时间是提高你 DC 总体效率的最有效方法。

(1)场景 1: 每波拣货 1 单的拣货路线—(图片由作者提供)

本系列文章旨在确定如何设计一个模型来模拟几种拣货流程和路径选择方法的影响,通过使用二维仓库模型(x 轴,y 轴)的单拣货员路径选择问题(SPRP) 来寻找最优订单拣货。

SPRP 是一般旅行商问题的具体应用回答问题:

“给定存储位置列表和每对位置之间的距离,访问每个存储位置并返回仓库的最短可能路线是什么?”

SPRP 用于确定提货流程中准备一个或多个订单的最短路线。

💌新文章直接免费放入你的收件箱:时事通讯

一、什么是挑波?

在这项研究中,我们将使用电子商务类型 DC 的例子,其中商品存储在 4 层货架上。这些货架分为多行(第 1 … n 行)和多条通道(第 1 … A_n 通道)。

假设

(2)仓库提货车—(图片由作者提供)

  1. 物品尺寸:小而轻尺寸物品
  2. 拣货车:轻型拣货车,可装载 10 个订单
  3. 拣货路线:拣货路线在同一地点开始和结束

场景 1 在生产率方面最差,但可以很容易地优化,因为

  • 地点:订单#1 和订单#2 有共同的提货地点
  • 区域:订单在一个公共区域中有提货地点
  • 单行订单:items _ picked/walking _ distance 效率很低

(3)场景 2:应用于场景 1 的波拾取—(图片由作者提供)

优化这一流程的第一个直观方法是将这三个订单组合在一条提货路线中,这一策略通常被称为波式提货

了解更多关于拣选效率的信息

我们将建立一个模型来模拟几波 的影响,为制定拣货策略 中的总行走距离做好准备。

二。测试几种优化算法

1.带有存储位置映射的仓库布局

(5)带有 2D 坐标的仓库布局—(图片由作者提供)

基于实际的仓库布局,存储位置用 2-D (x,y)坐标绘制,该坐标将用于测量步行距离。

使用 主数据 将每个存储位置链接到一个参考。( 比如参考#123129 位于坐标(,易))。

然后,您可以将每个订单行链接到一个地理位置进行提货。

2.仓库管理系统(WMS)中的订单行

(6)数据库模式—(图片由作者提供)

订单行可以从您的【WMS】数据库 中提取,该表应与主数据表相结合,将每个订单行链接到一个存储位置及其在您仓库中的(x,y)坐标。

可以添加额外的表格,以便在您的模型中包含更多的参数,如(目的地、交货提前期、特殊包装、..).

3.用于计算领料路线距离的函数

功能 1: 计算两个拣货位置之间的距离

(5)仓库中两个存储位置之间的不同路线—(图片由作者提供)

此函数将用于计算从点 i (xi,易)j (xj,yj) 的步行距离。

目标:返回从 I 点到 j 点两条潜在路线之间的最短步行距离。

因素

y_low:你巷子的最低点(y 轴)
y_high:你巷子的最高点(y 轴)

你可以在我的 GitHub 资源库中找到完整的代码:链接
我的作品集与其他项目: Samir Saci

代码

功能 2: 下一个最近的位置

(6)下一个存储位置场景—(图片由作者提供)

该功能将用于在几个候选中选择的下一个位置,以继续您的提货路线。

目标:返回最近的位置作为最佳候选

(**)我们稍后将会看到,这一选择将会影响整体生产力。

代码

功能 3: 创建您的提货路线并计算总步行距离

此功能将用于从一组要准备的订单中创建您的提货路线。

  • 输入:基于该路线要提货的物品的(x,y)位置列表
  • 输出:覆盖位置和总步行距离的有序序列

代码

4.用于创建订单波的函数

功能 1: 创建一批 n 个订单同时拣货

  • 输入:订单行数据帧 (df_orderlines) ,每波订单数 (orders_number)
  • 输出:映射了波数的数据帧(列: WaveID ),总波数 (waves_number)

代码

功能 2: 列出 wave_ID 提货路线的提货地点

  • 输入:订单行数据帧 (df_orderlines) 和波号 (waveID)
  • 输出:您提货路线中包含的地点 I(,易)列表

代码

[## 萨米尔 Samir 供应链组合的数据科学

🏭使用高级数学概念的供应链网络优化👨‍🏭仓储的持续改进…

samirsaci.com](http://samirsaci.com)

三。结果和后续步骤

1.结果

在设置了衡量提货距离的所有必要功能后,我们现在可以用提货订单行测试我们的提货路线策略。

在这里,我们首先决定从一个非常简单的方法开始

  • 订单波:订单按收到 OMS 的时间顺序(时间戳)分组
  • 拣货路线:拣货路线策略遵循下一个最近位置逻辑

为了评估分批拣货策略对您生产率的影响,我们将针对每批订单的渐进数量进行多次模拟:

  1. 测量总步行距离:每条路线的订单数增加时,步行距离减少多少?
  2. 记录每波提货路线:记录每条路线的位置顺序,以便进一步分析

代码

(8)5000 条订单行的结果,每条路线的订单比例从 1 到 9—(图片由作者提供)

2.后续步骤

关注我,了解更多与供应链数据科学相关的见解。

这个解决方案远非最佳

  • 订单可以按照提货地点的地理集群进行分组,以减少提货人的步行距离

[## 通过 Python 使用空间聚类提高仓库生产率

物流持续改进通过使用拣货功能将订单分批分组,提高仓库拣货生产率

www.samirsaci.com](https://www.samirsaci.com/improve-warehouse-productivity-using-spatial-clustering-with-python/)

  • 下一个最近位置策略有其局限性,可通过选择路线记录轻松指出

[## 使用 Python 的寻路算法提高仓库生产率

物流持续改进实现基于旅行商问题的寻路算法

www.samirsaci.com](https://www.samirsaci.com/improve-warehouse-productivity-using-pathfinding-algorithm-with-python/)

在下一部分,我们将对第一种解决方案进行详细分析,以了解其局限性以及如何改进。

关于我

让我们在 LinkedinTwitter 上连线,我是一名供应链工程师,使用数据分析来改善物流运营和降低成本。

如果你对数据分析和供应链感兴趣,可以看看我的网站

[## Samir Saci |数据科学与生产力

专注于数据科学、个人生产力、自动化、运筹学和可持续发展的技术博客

samirsaci.com](https://samirsaci.com)

通过 Python 使用空间聚类提高仓库生产率

原文:https://towardsdatascience.com/optimizing-warehouse-operations-with-python-part-2-clustering-with-scipy-for-waves-creation-9b7c7dd49a84?source=collection_archive---------22-----------------------

通过使用拣货位置空间聚类对订单进行分批分组,提高仓库拣货效率

使用 Python Scipy 的空间聚类提高仓库生产率—(图片由作者提供)

本文是关于使用 Python 优化仓库操作的系列文章的一部分。( 第一部分 )

💌新文章直接免费放入您的收件箱:时事通讯

一.优化的两个杠杆

在第一篇文章中,我们使用以下公式建立了估算一组订单的总提货路线行走距离的基础:

  • 仓库映射:将每个订单行与仓库中相关的提货地点坐标(x,y)相链接
  • 距离计算:计算从两个拣货位置的步行距离的功能

我们还决定采用一种简单的方法

  • 拣货路线设计:给定几个拣货位置的选择,仓库拣货员将总是选择去最近的(下一个最近的位置策略)
  • 订单波动:订单按照从 OMS 接收时间(时间戳)进行波动排序和分组

提高我们解决方案性能的两个杠杆—(图片由作者提供)

在研究复杂的算法之前,我们可以尝试用简单的解决方案找到优化算法的方法。

你可以在我的 GitHub 资源库中找到完整的代码:链接

为了帮助操作员找到他们的路,您的操作可以使用语音拾取

二。使用提货地点聚类的订单波

单行订单具有位于单一存储位置的优势;通过聚类将几个单行订单分组可以确保我们的提货人停留在划定的区域。

单行订单位于何处?

(2)订单行数据框架—(图片由作者提供)

功能:计算每个货位单行订单数(%)

代码

(1)每个存储位置的单行订单行分布— 5,000 个订单行(%)

见识:让我们以上面的分配为例

  • 范围:23 个通道的 5000 个订单行
  • 单线订单: 49%的订单位于A11、A10、A09 胡同

1.使用 Scipy 进行提货地点聚类

(3)订单行处理,用于使用按提货位置聚类的订单波提货—(图片由作者提供)

创意:提货地点集群 通过集群对提货地点进行分组,以减少每条提货路线的步行距离。(例如:两个地点之间的最大步行距离为< 15 米)

空间聚类的任务是将一组点组合在一起,使同一聚类中的对象之间的相似性高于其他聚类中的对象。

(4)三个提货地点聚类的示例—(图片由作者提供)

这里,相似性度量将是从一个位置到另一个位置的步行距离。

例如,我希望对地点进行分组,确保两个地点之间的最大步行距离为 10 米

1|挑战 1: 欧几里得距离与步行距离

对于我们的特定模型,我们不能使用使用欧几里德距离的传统聚类方法。的确,步行距离(使用 distance_picking 函数)不同于欧几里得距离。

(5)欧几里得与自定义距离示例—(图片由作者提供)

对于这个特定的例子,i (xi,Yi)和两点 p (x_p,y_p)和 j (x_j,y_j)之间的欧几里德距离是相等的。但是,如果我们比较采摘者步行距离,p (x_p,y_p)更接近。

对于此模型,提货人行走距离是我们想要减少的具体指标。因此,聚类算法应该使用我们定制的 distance_walking 函数来获得更好的性能。

示例:25 米距离内的位置聚类(5000 个订单行)

(6)左[使用步行距离聚类] /右[使用欧几里德距离聚类]——(图片由作者提供)

左边使用步行距离的示例是将同一通道内的位置分组,以减少提货路线距离;而正确的示例可以对覆盖几个通道的位置进行分组。

2 |功能:聚类为单行订单使用步行距离

对于一组订单,lines 提取单行 (df_orderlines) 订单,并使用自定义距离函数 (dist_method)在距离 (dist_method) 内创建存储位置集群。

下面的 Python 代码使用 Scipy's ward 和 fcluster 函数,使用 distance_func 度量(步行距离)创建拣选位置的聚类。

代码

3|函数:使用 ClusterID 映射单行订单

对于一组订单,行提取单行 (df) 订单、集群 id 和订单编号该函数将数据帧与集群 ID 进行映射,以创建波形。

代码

2.多行订单的领料库位聚类

1 |功能:每个多行订单的质心

与单行订单不同,多行订单可以涵盖多个领料库位。然而,我们可以将同样的方法应用于存储位置的质心。

示例:订单有 3 行,涵盖 3 个不同的提货地点

(7)三个采摘地点的质心—(图片由作者提供)

代号

使用这个函数后,我们回到单行订单的情况,每个订单有一个点(x,y)。

然后,我们可以对这些点进行聚类,尝试根据最大距离条件对每个地理区域的订单进行分组。

[## 萨米尔·萨奇

数据科学博客,专注于仓储,运输,数据可视化和机器人流程自动化…

samirsaci.com](http://samirsaci.com)

二。模型模拟

综上所述,我们的模型构建,见下图,我们在拾取路线创建之前有几个步骤使用 Wave 处理。

在每一步,我们都有一组可以调整以提高性能的参数:

(8)带参数的模型构建—(图片由作者提供)

1 |比较 3 种波形处理方法

(9)波形处理的三种方法—(图片由作者提供)

首先,我们将评估提货地点集群对订单波处理的影响。

我们将测试三种不同的方法。

  • 方法 1: 我们不应用聚类(即初始场景)
  • 方法 2: 我们仅对单行订单应用聚类
  • 方法 3: 我们对单行订单和多行订单的质心应用聚类。

模拟场景

  • 订单行: 20,000 行
  • 距离阈值:两个领料位置之间的最大距离(距离阈值= 35 米)
  • 每波订单:订单 _ 数量在[1,9]

(10)测试 1: 20,000 个订单行/ 35 米距离阈值—(图片由作者提供)

结果

  • 最佳性能:方法 39 个命令/波83% 减少行走距离
  • 方法 2 与方法 1: 单行订单的聚类将步行距离减少了 34%
  • 方法 3 与方法 2: 单行订单聚类将步行距离减少 10%

2 |聚类的调谐距离阈值

现在,我们已经验证了第一个假设,即方法 3 最适合我们的特定场景 (20,000 个订单行,35 米距离阈值)

让我们看看距离阈值对总步行距离的影响。

(10)提货地点聚类的不同距离阈值—(图片由作者提供)

两个位置之间的步行距离和波浪大小之间的权衡:

  • 距离短:两个地点之间的步行距离短,但是每波(更多波)的订单更少
  • 距离远:两个地点之间的步行距离更远,但是每波订单更多(波数更少)

(11)将 5,000 条线分组为 9 阶波,距离阈值为1,95的结果(图片由作者提供)

我们可以找到一个局部最小值,对于 Distance_Threshold = 60 m ,其中距离减少了39%vs .Distance _ Threshold = 1m

(11)将 20,000 条线分组为 9 阶波的结果,距离阈值为1,95——(图片由作者提供)

我们可以找到一个局部最小值,对于距离 _ 阈值= 50 米,其中距离相对于距离 _ 阈值= 1减少了 27%

四。下一步

关注我的 medium,了解更多与供应链数据科学相关的见解。

根据这一反馈,下一步将是:

  • 提货路线创建:关于提货地点列表,我们如何找到步行距离最短的最佳路线?

[## 使用 Python 的寻路算法提高仓库生产率

物流持续改进实现基于旅行商问题的寻路算法

www.samirsaci.com](https://www.samirsaci.com/improve-warehouse-productivity-using-pathfinding-algorithm-with-python/)

关于我

让我们在 LinkedinTwitter 上连线,我是一名供应链工程师,正在使用数据分析来改善物流运营并降低成本。

如果你对数据分析和供应链感兴趣,可以看看我的网站

[## Samir Saci |数据科学与生产力

专注于数据科学、个人生产力、自动化、运筹学和可持续发展的技术博客

samirsaci.com](https://samirsaci.com)

参考

[1] Samir Saci ,使用 Python 的订单批处理提高仓库生产率,链接

使用 Python 的寻路算法提高仓库生产率

原文:https://towardsdatascience.com/optimizing-warehouse-operations-with-python-part-3-google-ai-for-sprp-308c258cb66f?source=collection_archive---------14-----------------------

用 Google AI 运筹学库设计的旅行商问题实现寻路算法

使用谷歌人工智能设计寻路算法以提高仓库生产率—(图片由作者提供)

本文是关于使用 Python 优化仓库操作的系列文章的一部分。( 第一部分 第二部分 )

💌新文章直接免费放入你的收件箱:时事通讯

I .用于拣选路径创建的寻路算法

在第一篇文章中,我们建立了一个模型来测试订单波创建的几种策略,以减少提货的步行距离

  • 仓库映射:将每个订单行与仓库中相关的提货地点坐标(x,y)相链接
  • 距离计算:计算从两个提货地点步行距离的功能
  • 提货地点聚类:功能使用地理(x,y)聚类按波对订单进行分组,以减少同一提货路线上两个地点之间的最大距离

(0)提货路线计算流程图—(图片由作者提供)

在这个阶段,我们有按 wave 分组的订单要一起挑选。对于每一波,我们都有一个仓库提货人需要覆盖的提货地点列表。

下一个目标是设计一个函数来查找一系列位置,使步行距离最小化。

(1)覆盖 3 个提货地点的波浪的潜在路线—(图片由作者提供)

初始解决方案:下一个最近位置策略

在第一篇文章中,我们提出了一个使用次最近位置策略的初始解决方案。

(2)下一个存储位置场景—(图片由作者提供)

这个简单的策略不需要大量的计算工作。

从位置 j (xj,yj) 开始,该函数将把潜在的下一个位置的列表 [(xj,yj),(xk,yk),(xh,yh)] 作为输入。

使用自定义步行距离函数,输出将是最近的位置,作为要覆盖的下一个位置的最佳候选位置。

问题:是否为拣货路线创建的最优解?

[## 萨米尔·萨奇

数据科学博客,专注于仓储,运输,数据可视化和机器人流程自动化…

samirsaci.com](http://samirsaci.com)

二。旅行商问题在仓库拣货路线设计中的应用

目的:使用单拣货员路径问题(SPRP) 为二维仓库寻找拣货路径创建的最优算法。

是一般旅行商问题(TSP)** 的具体应用,回答问题:
“给定一个存储位置的列表和每对位置之间的距离,访问每个存储位置并返回仓库的最短可能路线是什么?”**

使用谷歌人工智能的 OR 工具建立旅行推销员模型

OR-Tools 是用于组合优化的开源工具集。从大量可能的解决方案中,我们的目标是找到最佳解决方案。**

或者——Google AI 解决方案的工具部分——(来源:Google AI Logo,链接)

这里,我们将把他们的旅行推销员问题用例用于我们的具体问题。

  1. 改编谷歌-OR 模型

我们唯一需要做的调整

输入数据

  • 提货地点坐标列表:
    List_Coord = [(xi,易),(x2,y2),……,(x_n,y_n)]
  • 步行距离函数
    f: ((x_i,y_i),(x_j,y_j)) - >距离(I,j)

你可以在我的 GitHub 资源库中找到完整的代码:链接
我的作品集与其他项目: Samir Saci

代码

在 Google OR 的例子中,字典是通过以下方式创建的:

  • 距离矩阵:【距离(I,j)为 i in [1,n]为 j in [1,n]】****
  • 车辆数量:我们场景的 1 辆车****
  • 货栈= 起点和终点的位置:start = end =**List _ Coord[0]****

2。模拟:OR-刀具解决方案与最近的下一个位置

目标是评估如果我们使用谷歌的 TSP 优化解决方案或与我们最初的最近的下一个位置解决方案相比,对总步行距离的影响。

我们将使用第 2 部分的方法来模拟场景

  • 订单行: 20,000 行
  • ****距离阈值:每组中两个提货地点之间的最大距离(距离阈值= 35 米)
  • ****每波订单:订单 _ 数量在[1,9]
  • 3 种聚类方法
    方法 1: 不应用聚类
    方法 2:只对单行订单应用聚类;
    方法三:对单行订单和多行订单的质心进行聚类;

(10)第二条:20,000 订单行/ 35 米距离阈值—(图片由作者提供)

最佳性能
方法 3
9 个订单/波83% 减少步行距离

问题 通过应用谷歌的 TSP 优化解决方案或在此基础上,我们能减少多少步行距离?

代码

3。OR-工具解决方案与最近的下一个位置

使用这三种方法运行 Waves 后,我们使用以下方法估计提货路线:

  • ****下一个最近的位置:距离 _ 初始
  • Google-OR 的 TSP 优化解决方案: distance_or
  • *距离缩减(%): 100 (距离初始化-距离初始化)/距离初始化

很少见识

  • ****每波订单:当每波订单数或-工具更有影响力时
  • ****方法:增加波形处理聚类或-工具影响较低时

最佳场景结果 方法 3(所有订单聚类)影响为总行走距离的 -1.23 %

了解有关实施该解决方案的语音拾音系统的更多信息

** [## 萨米尔·萨奇

数据科学博客,专注于仓储,运输,数据可视化和机器人流程自动化…

samirsaci.com](http://samirsaci.com)**

三。了解 TSP 解决方案

对于方法 3(对所有订单进行聚类)或工具 TSP 解决方案,将总行走距离减少 1.23 % —让我们看一个具体的例子来理解。

最高差距:21 个提货点 60 米

一个具体的例子,一个提货波覆盖 21 个地点:

  • 或-工具 TSP: 距离= 384 米
  • ****下一个最近的位置:距离= 444 米
  • 距离缩减: 60 米

(11)21 个位置的下一个最近位置解决方案路线(距离:444 米)——(图片由作者提供)

(12)21 个地点的 OR-Tool TSP 优化解决方案路线(距离:384 米)——(图片由作者提供)

次最近位置(NCL)算法的限制

TSP 点 2(点 A)
在这个具体的例子中,我们可以看到 TSP 优化解决方案对于第二点(19.5,21)的好处

(13)NCL vs TSP 的具体例子—(图片由作者提供)

从点 1 开始,三个最近的点是{A,B,C}

  1. 离点 1 最近的点是 A
  2. NCL 点直达 C,TSP 从 A 出发
  3. TSP 一次覆盖{A、B、C},而 NCL 只覆盖{B、C},让 A 稍后覆盖

(14)NCL vs TSP 的具体例子—(图片由作者提供)

NCL 点 21

在上例中,在点 20(点 A)之后,仓库提货人仍然需要在到达仓库(点 1)之前到达点 21(点 D)。这个额外的距离极大地影响了这一波的 NCL 效率。

四。结论

关注我,了解更多与供应链数据科学相关的见解。

将旅行商问题解决方案应用于拣选路径的创建,可以减少总行走距离,提高整体生产率。

结合智能订单波处理,它可以通过找到覆盖最大数量位置的最短路径来优化要覆盖的大量提货位置的波的提货顺序。

关于我

让我们在 LinkedinTwitter 上连线,我是一名供应链工程师,正在使用数据分析来改善物流运作和降低成本。

如果你对数据分析和供应链感兴趣,可以看看我的网站

** [## Samir Saci |数据科学与生产力

专注于数据科学、个人生产力、自动化、运筹学和可持续发展的技术博客

samirsaci.com](https://samirsaci.com)

参考

[1] Google OR-Tools,用 OR-Tools 求解 TSP,链接

[2] Samir Saci ,使用 Python 的订单批处理提高仓库生产率,链接

[3] Samir Saci ,使用 Python Scipy 的订单批处理空间聚类提高仓库生产率,链接**

优化您的 Python 代码

原文:https://towardsdatascience.com/optimizing-your-python-code-156d4b8f4a29?source=collection_archive---------4-----------------------

使用 Python 处理大量数据的基本技巧

照片由克里斯里德Unsplash 拍摄

虽然您只是偶尔需要运行一个分析器来分析您的代码并找到瓶颈,但是养成编写高效代码的习惯并找出您可以立即改进的地方绝对是一个好主意。

在寻找优化代码的方法时,要记住的一件重要事情是,很可能总会有一些折衷要接受。例如,它要么是一段运行更快的代码,要么是一段更简单的代码。这里的简单不仅仅指“看起来不那么酷的代码”(想想著名的 Python“一行程序”)。更简单的代码意味着更容易维护和测试。

此外,关于如何优化 Python 代码的每一个技巧都需要根据您的情况进行严格的检查。当然,有一般性的观察,但是你也可能有一个上下文,在这个上下文中那些观察是不相关的,或者甚至产生相反的结果。所以你需要了解“幕后”发生了什么,以及它将如何在你的案例中起作用。

然而,在某些情况下,你确实需要给你的代码一点提升,这里是我在学习 Python 时发现的一些有用的地方。

1.列出理解

在 Python 中,一个伟大的语法结构是 list comprehensions ,它在创建列表时比传统的循环计算效率更高。因此,如果您需要一个二进制特征向量作为数据点,其中所有负数将被分配 0,其余的将被分配 1,而不是:

>>> input_list = [1, 2, -3]
>>> output_list = []>>> for x in input_list:
...    if x >= 0:...        output_list.append(1)...    else:...        output_list.append(0)>>> output_list[1, 1, 0]

您可以:

>>> output_list = [1 if x >= 0 else 0 for x in input_list]>>> output_list[1, 1, 0]

您可以尝试使用[timeit](https://docs.python.org/3/library/timeit.html)模块来比较哪种实现运行得更快。

你也可以像嵌套循环一样使用嵌套列表理解,但是通常不鼓励这样做,因为这样会使代码更难阅读、维护和测试。

2.尽可能避免 for 循环和列表理解

事实上,在前面的例子中,如果您创建一个只有一个初始化值的向量,而不是使用低效的 for 循环甚至列表理解,您可以这样做:

>>> my_list2 = [0] * len(my_list1)
>>> my_list2
[0, 0, 0]

3.避免不必要的功能

一个很好的例子是函数调用,这种方法可以帮助减少大量的运行时复杂性,但需要仔细考虑权衡。虽然您确实希望函数提供良好的抽象性、可扩展性和可重用性,但是您可能不希望为每一件事情都提供一个函数,因为在 Python 中函数调用是非常昂贵的(如果您感兴趣,在这篇文章中有一些有趣的观察)。所以有时候,你可能想要牺牲,例如,写一个 getter 和/或 setter。另一方面,函数越少,代码的可测试性越差。因此,最终的决定实际上取决于您的具体应用。

4.尽可能使用内置的

另一个与函数相关的提示是选择内置函数,如max()sum()map()reduce()等。而不是自己完成这些计算——它们通常用 C 语言编写,运行速度会更快。此外,如果您使用内置函数——您需要为自己编写的测试代码会更少。因此,举例来说,如果您想要一个包含所有input_list绝对值的集合,您可以这样做:

>>> output_set = set(map(abs, input_list))
>>> output_set
{1, 2, 3}

如果您正在处理文本数据,用于字符串连接,而不是+=:

>>> sentence_list = ['This ', 'is ', 'a ', 'sentence.']
>>> sentence = ''
>>> for i in sentence_list:
...     sentence += i
>>> sentence
'This is a sentence.'

使用[str.join()](https://docs.python.org/3/library/stdtypes.html#str.join):

>>> sentence = ''.join(sentence_list)
>>> sentence
'This is a sentence.'

使用+=,Python 为每个中间字符串分配内存,如果使用了str.join(),则只分配一次。

使用[operator.itemgetter](https://docs.python.org/3/library/operator.html#operator.itemgetter)进行分类。例如,如果您有一个名和姓的元组列表,如下所示:

>>> my_tuples =[('abbie', 'smith'), ('jane', 'adams'), ('adam', 'johnson')]

默认排序将返回以下内容:

>>> sorted(my_tuples)
[('abbie', 'smith'), ('adam', 'johnson'), ('jane', 'adams')]

如果你想按姓氏而不是名字来排序,你可以这样做:

>>> sorted(my_tuples, key=operator.itemgetter(1))
[('jane', 'adams'), ('adam', 'johnson'), ('abbie', 'smith')]

5.避开圆点

如果您有一个对象,并且正在使用它的一些属性,请先将它们赋给局部变量:

rectangle_height = rectangle.heightrectangle_width = rectangle.width

所以如果你在代码的后面计算,比如说,它的表面,你会做:

surface = rectangle_height * rectangle_width

如果以后你也计算它的周长,你将重复使用相同的变量:

perimeter = 2 * rectangle_height + 2 * rectangle_width

您可以再次使用timeit模块来验证它为您节省了对矩形对象及其属性的每个引用的查找时间。

出于同样的原因,通常不鼓励使用全局变量——你不希望浪费时间首先查找全局变量本身,然后查找你可能引用的它的每个属性。

这也适用于函数引用。例如,如果您正在处理一个数据点序列,并且正在将每个结果项追加到一个列表中,您可以执行以下操作:

push_item = my_list.append

然后将其应用于每个结果项目:

push_item(item)

6.了解您的数据结构,并了解它们在您的 Python 版本中是如何工作的

除了每个典型数据结构的一般属性之外,例如,从链表中检索一个条目的复杂性,了解 Python 数据结构是如何实现的以及哪里可以节省一些 CPU 或内存也是很好的。例如,如果你在字典中查找一个键,你甚至不需要引用dict.keys(),这在 Python 3 中会慢一点。你可以简单地做:

>>> if k in dict:...    do_something(k)

在 Python 2 中,dict.keys()甚至用来创建一个额外的键列表!

7.明智地选择一种方法

同时,不要忘记看一看更大的画面。如果您有一个要处理的项目列表,并且您知道在集合中查找是 O(1)对列表中的 O(n ),那么您可能会尝试将列表转换为集合:

>>> my_set = set(my_list)

然而,如果你只是查找列表中的一项,如果你先把列表变成一个集合,你可能会让事情变得更糟。在幕后,Python 将遍历整个列表,并将每个项目添加到一个新创建的集合中。创建集合的开销会使您失去在集合中查找的优势。

另一方面,如果您想有效地从列表中删除重复项,将它转换为 set 可能是一个不错的选择(尽管 Python 中还有其他选项可能更适合您的情况)。

因此,正如我之前提到的,有一些一般性的观察,但是你需要仔细检查它们,以了解它们如何在你的案例中起作用。

有很多更高级的方法来管理您的代码,以便使它更有效和执行得更快——从并行性或并发性到不同的技巧,如设计更小的对象,以便它们适合堆内存的缓存层而不是主缓存层。对于某些任务,您可能能够使用实际上为优化这些任务而设计的库。然而,以上是我在学习 Python 时不得不开始注意的第一件事。你在使用什么技巧和方法?

如果您在数据科学领域使用 Python,请随意查看我关于 Python 3.9 中的新特性和 Python 中的并发性的文章!

Python 中的希腊选项

原文:https://towardsdatascience.com/option-greeks-in-python-97980df3ab0b?source=collection_archive---------26-----------------------

自动偏微分 JAX

来自佩克斯安德里亚·切的照片

T4 期权对每个期权交易者来说都是必不可少的。但是,希腊人到底是什么?希腊人是布莱克-斯科尔斯方程关于每个变量的偏导数…

希腊人

  • δ—δ—基础资产的一阶偏导数
  • γ—γ—关于基础资产的二阶偏导数
  • Vega — v —关于波动率的偏导数
  • θ—θ—呼气前时间的偏导数
  • ρ—ρ—相对于给定利率的偏导数

用简单的英语来说,希腊人告诉我们,当只有那个参数变化时(所有其他参数保持不变),期权的价格是如何变化的。交易平台通常会自动计算每份合约的希腊价格。然而,当将市场数据流式传输到 Python 时,或者使用您自己的定价模型时,您将需要自己计算这些值。尽管布莱克-斯科尔斯希腊方程有闭合形式的解(这大大加快了他们的计算速度)。然而,我认为这将是对 Python 库 JAX 的一个很酷的介绍,它可以用来自动计算任何函数的梯度。

源自 JAX 的希腊模型的美妙之处在于,它可以用于任何定价模型,而不仅仅是 Black-Scholes 模型,让对冲外来风险变得不那么痛苦。

什么是梯度向量?

梯度向量,或简称为梯度,是任何给定多变量函数的偏导数的集合。

给定以下功能 f

梯度-∇-如下…

这一概念适用于所有函数,不管维度如何…

关于渐变的更多信息,请查看渐变矢量

使用 JAX 的布莱克-斯科尔斯梯度

你会注意到这两个概念的交集在于偏导数。希腊人(γ除外)是布莱克-斯科尔斯方程对每个变量的一阶偏导数。如果我们能从布莱克-斯科尔斯方程推导出梯度,我们将有一个函数能产生 5 个希腊人中的 4 个!

JAX 是由谷歌开发和维护的库,主要用于机器学习,提供了一种自动计算梯度函数的简单方法。

不幸的是,在撰写本文时,JAX 仅在 IOS 上受支持。

在我们开始之前,重要的是要注意,为了使用 JAX,我们将需要通过 JAX 本身引用任何线性代数(numpy)或统计分布(scipy)

我已经为欧式调用建立了类,并放入了结构正确的 Python 以用于 JAX…

通常,如果变量的类型不是浮点型,JAX 会返回错误,因为有多种近似技术用于求解导数。你会发现在上面的所有课程中都提到了。因为这个原因。**

让我们实现 JAX 的 grad 函数来自动计算希腊人…

在上面的代码中,在计算每个期权价格后,我添加了一个调用 JAX 函数的字段。grad 函数既接受函数,也接受关于梯度中包含哪些参数的元组。在计算完 gradient_func 之后,我用它分别给 delta,vega,theta,rho 赋值。您还会注意到,我们需要做一些调整,因为 vega 和 rho 是以百分比表示的,而 theta 是按年计算的。

现在让我们使用这个类来计算希腊人的一个示例选项…

为了实现这些类,我们按照以下顺序创建了一个选项参数的 JAX-numpy 数组…

  • 资产价格
  • 波动性
  • 执行价格
  • 到期时间(年化)
  • 无风险利率

然后我们创建一个欧式期权类的实例,并使用填充 JAX-numpy 数组。astype('float') 避免计算梯度时出现错误。最后,我们打印使用梯度函数导出的希腊人的值…

0.6300359 3.1931925 -1.3295598 1.3750976[Finished in 1.253s]

使用 Python 进行期权交易技术分析

原文:https://towardsdatascience.com/options-trading-technical-analysis-using-python-f403ec2985b4?source=collection_archive---------16-----------------------

照片由马克·芬恩Unsplash 上拍摄

我最近发现了今年内的期权交易。这是一次有趣的经历,每次我钻研金融交易领域的其他话题时,我都会学到一些新东西。

最近偶然看到 Option Alpha 的一个视频叫技术分析——新手期权交易。他提到了三个技术分析指标,非常适合我这样的新手。这些指标是 MACDCCIRSI 。我决定将它们编程到 Python 中,以进一步理解这些指标是如何工作的。他提到,这三者应该结合使用,才能看出股票的走向。

概述

完整代码访问此处

因此,我喜欢在开始编码之前,先草拟出我需要的东西。我发现我需要一年的股票数据。因此,我只需要从当前日期开始一年的数据,为此我将使用datetimepandas_datareader。我还将继续使用一个技术分析库,它将为我做所有的计算,名为[ta](https://technical-analysis-library-in-python.readthedocs.io/en/latest/)。然后作为加分项,我也会用matplotlib把这些数据全部可视化。

让我们先从我们的进口货开始吧。

我知道很乱,但我们继续吧。我将使用微软作为这个代码的例子。股票代码是MSFT让我们把它设置为一个变量。然后我将使用datetime,以便检查当前日期,然后输出该日期作为我们数据的起点。我们将使用pandas_datareader从雅虎获取股票数据。然后,我们将它放入一个数据帧中,并使用来自ta.utilsdropna删除所有空值。

代码应该是这样的,我们的数据帧应该是这样的。

我们现在可以使用plt.plot(df[‘Close’])绘制图表。根据你设定的日期和股票,我看到的可能与你的不同。

现在有趣的是技术指标,我不是财务顾问,所以我对每个指标的设置都没有经过验证。所以请注意,我在经济上不对你负责。

MACD

所以 MACD 是一个很好的指标,它会告诉你何时买入或卖出。你要寻找的主要东西是当这些线互相交叉的时候。对于这个例子,如果蓝线跌破橙线,我们想卖出我们的头寸。如果蓝线高于橙线,我们就买入。下面是代码和下面的情节。

CCI

CCI 也是一个类似的指标。除了我们想关注它在哪里达到零。如果它是正的,触及零,我们想卖,如果它是负的,触及零,我们想买。我还加了一行零是为了更好的形象化情节。下面提供了代码和图像。

RSI

下一个指标与其他两个有点不同,因为它不是趋势指标。这是一个动量指标,意味着它衡量股价的涨跌。这些的标准是看它是高于 70 还是低于 30。意思是当价格上涨时卖出,当价格下跌时卖出,这是一个很好的买入指标。

结论

现在我们有了这些指标,我个人的下一步是创建一些 if else 语句,它将告诉我是否购买,如果所有这些指标都是绿色的,可以使用。如果他们也处于买入的有利位置,否则我也会创建一些声明,告诉我持有或保持关注。

来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指南 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

如果您喜欢这篇文章,请随意查看我的其他 Python 文章,这些文章也深入研究了金融交易领域:

[## 使用 Python 和 Robinhood 创建一个简单的低买高卖交易机器人

所以我最近一直在折腾 Robinhood,一直在努力理解股票。我不是财务顾问或…

towardsdatascience.com](/using-python-and-robinhood-to-create-a-simple-buy-low-sell-high-trading-bot-13f94fe93960) [## 使用 Python 和 Robinhood 构建一个钢铁秃鹰期权交易机器人

所以我最近发现了期权交易的潜在收益。

towardsdatascience.com](/using-python-and-robinhood-to-build-an-iron-condor-options-trading-bot-4a16e29649b0) [## 使用 Python 将股票数据可视化为蜡烛图

烛台数据是一个非常重要的方式来显示数据在股票市场如何移动。

towardsdatascience.com](/using-python-to-visualize-stock-data-to-candlestick-charts-e1a5b08c8e9c)

Orange 数据挖掘工具和关联规则

原文:https://towardsdatascience.com/orange-data-mining-tool-and-association-rules-caa3c728613d?source=collection_archive---------32-----------------------

奥列格·马尼通过像素拍摄的照片

在本文中,将使用 Orange 数据挖掘工具来研究关联分析。Apriori 算法将用于创建关联规则。算法步骤将显示在一小组市场购物数据上。

关联规则

关联分析是试图揭示隐藏在数据集中的 if-else 规则的研究。分类数据通常会产生良好的结果。关联分析最常见的例子是购物篮分析。此外,它还具有生物信息学、疾病诊断、web 挖掘和文本挖掘等广泛的用途。

篮子分析

在购物篮分析中,我们将购物者购买的产品保存在一个列表中,并想知道哪些产品在一起销售得更多。

数据

假设我们有一个数据,包含市场中的 5 笔交易,比如:
1 面包、牛奶
2 面包、茶、咖啡、鸡蛋
3 牛奶、茶、咖啡、可乐
4 面包、牛奶、茶、咖啡
5 面包、牛奶、茶、可乐

我们可以看到,在数据集中,大多数购买茶的购物者也会购买咖啡。现在,让我们使用一键编码来显示数据集。数据集可以从这里下载。

一键编码

关联规则的一些定义

产品列表:篮子中所有产品的列表,即{面包、牛奶、鸡蛋}。

支持计数(σ): 购买时传递的商品数量,即σ({牛奶、茶、咖啡}) = 2

支持率:产品列表在交易所中的比例,即 s({牛奶、茶、咖啡}) = 2/5

产品列表频率:特定值以上产品的支持率列表。

这里有更多关于关联规则的信息。在这篇博客中,我将展示如何使用 Orange 工具利用关联规则。

Apriori 算法

Apriori 算法是购物篮分析中最常用的算法。该算法从指定阈值开始。例如,我们将最低支持阈值设为 60%。

第一步:按频率输入产品列表,找出出现频率最高的产品。将产品数量乘以阈值,并删除低于您找到的值的产品。

步骤 2: 将产品数量乘以阈值,并移除低于您找到的值的产品。

第二步

第三步:为二元乘积集创建频率表。

第三步

第四步:为三元乘积集创建频率表。

橙色数据挖掘工具

图片来自橘子

Orange 是和开源机器学习和数据可视化。

一些重要特征;

  • 免费、开源
  • 机器学习和数据可视化工具
  • 简单的图形界面和附加支持
  • 也可以开发 Python 代码。

关联规则与橙色工具

安装 Orange 后,选择选项> >附加组件并安装 Associate !我们正在设置附加组件。您可以下载数据集(。csv)我们在篮子分析中使用这个地址。打开数据集后,我们可以显示对频繁项集支持最少的规则。最后,我们可以用关联规则来展示关联规则。

就这样,现在可以使用自己的数据集来查找隐藏在数据中的 if-else 规则了。

我也在我的个人网站分享这个土耳其语的博客。

参考

通过 AWS 步骤功能编排瞬态数据分析和 ML 工作流

原文:https://towardsdatascience.com/orchestrating-transient-data-analytics-workflows-via-aws-step-functions-c9e8309f63bf?source=collection_archive---------31-----------------------

AWS 自动化提示和技巧

郭锦恩Unsplash 上拍照

介绍

AWS 步骤功能 是一个完全托管的服务,旨在协调和链接一系列步骤,为自动化任务创建一个称为状态机的东西。它支持可视化工作流,状态机通过 亚马逊状态语言 ( ASL )定义为 JSON 结构。此外,状态机可以通过Amazon cloud watch作为事件规则 cron 表达式进行调度。

在这篇博客中,我将带你经历 1。)如何通过 亚马逊 EMR 和 2 来编排数据处理作业。)如何通过 亚马逊 SageMaker 在一个训练好的机器学习模型上应用 batch transform 来编写预测。步骤功能可以与多种 AWS 服务集成,包括: AWS LambdaAWS FargateAWS BatchAWS Glue亚马逊 ECS亚马逊 SQS亚马逊 SNS亚马逊 DynamoDB

示例 1:通过 Amazon EMR 编排数据处理作业

1a。)让我们在亚马逊 S3 中查看我们的输入样本数据集(来自我最喜欢的视频游戏的虚拟数据)。

作者图片

1b。)接下来,我将创建一个状态机,它通过 ASL 启动一个 EMR 集群(一组 EC2 实例)。

1c。)现在,我们可以通过向集群提交一个作业并在完成后通过 ASL 终止基础架构来执行一些数据处理(简单的按列分区)。让我们也在 S3 中检查我们的输出数据。

作者图片

1d。)这里是完整的 JSON ASL 结构和正在进行的可视化工作流截图。

作者图片

1e。)最后,让我们通过 CloudWatch 调度每 15 分钟执行一次,作为一个简单的 cron 表达式(0 */15 *).

作者图片

总之,对于这个例子,您可以利用步骤函数来自动化和调度您的数据处理作业。复杂程度通常取决于数据量,可以是单台 EC2 机器上的几个简单步骤,也可以是在同一个集群上并行分配多个作业,或者跨多个集群使用不同的实例类型。我建议在 JSON ASL 中为选定的软件(即 YARN、Spark、Hive、Sqoop)包含额外的 EMR 调优配置,以优化工作性能。此外,明智地选择 EC2 实例类型的数量和种类,以节省成本和执行时间。您的决定应该主要取决于需要处理的总数据量和作业类型(CPU 或内存受限)。

到下一个例子…

示例 2:通过 Amazon SageMaker,使用经过训练的 ML 模型对数据进行批量转换以进行推理

2a。)为了便于理解数据,让我们查看原始的带标签的(因变量是最后一列名为的)训练数据集(来自 UCI 机器学习库的鲍鱼)在 S3 中。经过训练的模型通过物理测量来预测鲍鱼(一种贝类)的年龄。

https://archive.ics.uci.edu/ml/datasets/abalone

作者图片

2b。)接下来,让我们创建 ASL 结构,该结构触发原始未标记(无列)批处理数据集上的批处理转换作业,该数据集需要通过存储在 S3 中的训练模型进行推理。 请注意,目前您必须将内联策略附加到为状态机 选择的角色。

图片来自亚马逊网络服务

图片来自亚马逊网络服务

2c。)最后,我们可以查看步骤功能可视化工作流程以及添加了预测分数栏的作业输出结果。注意,该模型是一个流水线模型,包括预处理(一个热编码、缩放等。)数据,然后将其发送到监督学习算法。

作者图片

作者图片

总之,对于本例,您可以利用步骤功能来自动化和调度您的机器学习作业(预处理、训练、调优、模型托管、自助服务&批量推理)。步骤函数SageMaker 集成支持以下 API:CreateEndpointCreateEndpointConfigCreateHyperParameterTuningJobCreateLabelingJobCreateModelCreateTrainingJobCreateTransformJob

结论

这两个例子涵盖了 AWS 服务能够扩展数据工程和机器学习工作流的一小部分。感谢你阅读这篇博客。

根据以下建议整理你的 Jupyter 笔记本

原文:https://towardsdatascience.com/organise-your-jupyter-notebook-with-these-tips-d164d5dcd51f?source=collection_archive---------2-----------------------

整理数据科学工作流程的实用技巧

数据科学家做大量的探索和实验。Jupyter Notebook(从这里开始的笔记本)是一个探索和实验的好工具。然而,当使用笔记本电脑时,事情会很快变得杂乱无章。保持你的工作流程干净、有条理和易于理解是一项重要的技能,它将在你的职业生涯中很好地为你服务。在这篇文章中,我将分享一些关于如何让你的笔记本和工作流程更有条理的小技巧。

阿里·叶海亚Unsplash 上的照片

📍提示 1。对每个主要任务使用单独的笔记本

不要把从探索性数据分析到建模的工作流程放在一个巨大的笔记本里,最好把它们分成几个逻辑部分,并描述性地给每个笔记本命名。让我们看一个例子:

看看这个例子,我们有几个笔记本。从名字就能看出笔记本的顺序。例如,我们可以猜测 3_base_models.ipynb4_gbm_model.ipynb 之前,而 4_gbm_model.ipynb4_rfc_model.ipynb 可能正在并行探索两个选项。如果我们将这两个重命名为 4A_gbm_model.ipynb4B_rfc_model.ipynb ,那么我们也可以用稍微不同的方式在名称中暗示顺序。

您可以拥有比示例更多或更少的笔记本。也就是说,笔记本的确切数量并不重要。这里的关键思想是让逻辑上的主要任务(这取决于你如何定义它)分散开来,这样就更容易看到整个工作流和找到东西。例如,当编写用于部署的生产就绪代码时,我们只需参考5 _ final _ pipeline . ipynb .

📍技巧二。为表达性文档使用标记

与代码注释相比,Notebook 中的 Markdown 单元格使我们在记录工作流时更具表现力。我们可以使用不同字体大小的标题、有序或无序的项目列表、表格、数学公式、复选框、超链接、图像等等。下面是对 Markdown 常用语法的一分钟介绍:

#### Headers
# Header 1 
## Header 2

#### Styles
*Italic*, **bold**, _underscore_, ~~strikethrough~~

#### Hyperlink
[hyperlink](https://www.markdownguide.org/)

#### Table
| Default | Left-aligned | Center-aligned | Right-aligned |
|---------|:-------------|:--------------:|--------------:|
| Default | Left | Center | Right |

#### Others
* Bulleted item 1
    * Bulleted subitem 1
* Bulleted item 2

***
1\. Ordered item 1  
    1.1\. Ordered subitem 1  
2\. Ordered item 2

***
- [ ] Unchecked box
- [x] Checked box

下面是上述语法的输出结果:

你可以从这里这里了解更多关于降价的信息。

📍技巧三。用泡菜

Pickles 不仅美味,而且当在 Python 的上下文中使用时,它允许我们将对象保存为。 pkl 文件。保存对象的过程称为酸洗。

酸洗在数据科学中的一个流行用途是将训练好的模型或机器学习管道保存到。pkl 文件。在下面的例子中,我们可以看到 pickle 中保存了几个模型:

例如,这将允许我们将训练好的模型或管道加载到不同的笔记本中,以便对预测进行扩展分析。

pickles 的另一个好的用途是保存列表、字典之类的对象。例如,如果我们将分类特征的手动选择分配给一个笔记本中的列表,并计划在另一个笔记本中使用它,我们可以将该列表写入 pickle 文件并将其加载到其他笔记本中。这样,如果我们手动更改列表,那么我们只需要在一个地方做。这里有一个编写或加载 pickle 文件的示例代码,该文件名为categorial . pkl,其中categorial引用 Python 中的一个对象(例如 list)。

如果你想了解更多关于泡菜的知识,请查阅这篇文档

📍技巧四。创建用户定义的函数并将其保存在模块中

你可能听说过干原则:不要重复自己。如果你以前没有听说过这个软件工程原则,它是关于“不要在一个系统内复制一个知识”。我对数据科学中这一原则的解释之一是创建函数来抽象出重复出现的任务,以减少复制粘贴。如果对您的情况有意义,您甚至可以使用类。

以下是这个技巧的建议步骤:

  1. 创建一个函数
  2. 确保函数有一个直观的名称
  3. 用 docstring 记录函数
  4. (理想的)单元测试功能
  5. 将函数保存在. py 文件中(。py 文件被称为模块)
  6. 在笔记本中导入模块以访问该功能
  7. 使用笔记本中的功能

让我们试着用例子来描述这些步骤:

这里有一个简单的方法来评估一个函数是否有一个直观的名字:如果你认为一个以前没有见过这个函数的同事仅仅通过看它的名字就能大致猜出这个函数是做什么的,那么你就对了。在记录这些函数时,我采用了一些对我来说更有意义的不同风格。虽然这些示例可作为数据科学的工作示例功能,但我强烈建议您查看以下官方指南,以了解命名和文档约定、样式指南和类型提示方面的最佳实践:

你甚至可以浏览成熟软件包的 Github 库中的模块来获得灵感。

如果您将这些函数保存在一个 helpers.py 文件中,并导入了 helpers 模块(顺便说一下,Python 模块只是指一个)。py file)在我们带import helpers的笔记本里,你可以通过写函数名后跟 Shift + Tab 来访问文档:

如果你有很多功能,你甚至可以把它们分类放在不同的模块里。如果您采用这种方法,您甚至可能想要创建一个包含所有模块的文件夹。虽然将稳定的代码放入一个模块是有意义的,但我认为将实验性的功能放在笔记本中是没问题的。

如果你实现了这个建议,你很快就会发现你的笔记本看起来不那么杂乱,更有条理了。此外,使用函数会使你不容易犯愚蠢的复制粘贴错误。

单元测试没有在这篇文章中讨论,因为它应该有自己的章节。如果您想了解数据科学的单元测试,这个PyData talk可能是一个很好的起点。

📍技巧五。确保笔记本电脑自上而下运行

做实验时,在笔记本的任何地方调整部分代码并不罕见。然而,一旦你完成实验,清理它,重新启动内核,并确保你的笔记本中的细胞自上而下运行一次,这样你就不会有这样的无序细胞:

Voila❕:这些是我整理你的 Jupyter 笔记本工作流程的建议。✨

您想访问更多这样的内容吗?媒体会员可以无限制地访问媒体上的任何文章。如果你使用 我的推荐链接成为会员,你的一部分会费会直接去支持我。

谢谢你看我的帖子。我希望你能利用这些技巧来建立一个更有条理的工作流程。如果你感兴趣,这里有我的一些帖子的链接:

◼️python 中的简单数据可视化,你会发现有用的
◼️ 在 seaborn(python)
◼️python 中的探索性文本分析
◼️️ 给 pandas 用户的 5 个提示
◼️️pandas 中数据聚合的 5 个提示
◼️️ 在 pandas 中编写 5 个常见的 SQL 查询
◼️️ 在 pandas 中编写高级 SQL 查询

再见🏃💨

组织数据盲扼杀了数据科学团队

原文:https://towardsdatascience.com/organizational-data-illiteracy-kills-data-science-teams-b1fe1a630053?source=collection_archive---------21-----------------------

数据的成本在领导层显得幼稚

我在不成熟的数据科学从业者和数据科学团队中经常看到的事情是过度复杂。当没有足够的数据支持时,希望使用复杂的神经网络,或者希望包括各种实际上没有增加预测价值的变量。

具有讽刺意味的是,使用简单的解决方案往往是复杂的标志。我认识的有经验的数据科学家知道什么时候复杂性是合理的,但最终,简单往往会产生最佳的努力点:报酬率。

对于没有经验的数据从业者来说,不必要的复杂性的原因是显而易见的:想要证明你知道复杂的方法,以及缺乏知道什么时候适可而止的经验。在建立投资组合和积累经验时,这可能是件好事。

在不成熟的数据科学团队中,这个问题通常是更严重的问题。这导致了我所说的数据废话:为了听起来复杂而过度复杂的数据科学项目。

帕斯卡尔·范·德·万德尔在 Unsplash 上的照片

数据幼稚导致不正当的动机

我以前的一位老板总是吹嘘我们团队制作的模型“包含了成千上万的变量”。这是真的。他没有说的是,我们可以用这些变量的极小一部分获得相同的模型性能。额外的变量只是膨胀,这导致了提取所有数据元素的复杂性,代码中不必要的复杂性使其更难维护,更不用说增加了几个月的开发时间。

有一大堆唾手可得的果实,我们可以通过小而有针对性的项目增加巨大的价值,但没有一个听起来足够壮观。如果他声称我们正在做的事情听起来非常复杂,涉及到其他团队没有的技能,即使简单的东西也会一样有效,那么就更容易受到关注。

我看到这是一种重复的模式:一个只知道足够危险的领导者,一个人们无法分辨什么是废话的数据幼稚组织,以及有理由证明数据科学团队是合理的,因为他们的数据科学工资昂贵。

每个数据科学家在每个项目中都应该问的最重要的问题

在一个组织中,人们对统计模型和机器学习听起来像魔法一样的谈论感到惊叹,这种普遍的数据幼稚导致了这些不正当的激励——特别是当高管层存在数据幼稚时。如果高层的人不知道如何嗅出数据胡说八道,他们会被解决方案的复杂性震惊,并错误地认为复杂性是必需的,从而证明昂贵的团队是合理的。实际上,更简单的解决方案会更好、更快地实施,但这些解决方案太容易解释了,因此没有显示出数据科学团队在提出该解决方案方面有多么“特别”(尽管发现简单的解决方案可以用在什么地方通常需要更多的经验,而不是用厨房水槽来解决问题)。

这种不必要的过于复杂的方法的趋势在这个组织中达到了一个极端,当时一位高管建议我们在我们的一些站点捕获声音数据,以查看合规性问题和声音特征之间是否存在模式。

这将是一个巨大的后勤噩梦——实际上是在数千个地点种植记录硬件,建立数据管道来收集和处理数据,处理放置记录设备的潜在法律问题,收集几个月的数据只是为了获得少量积极的数据点,等等。由于一些愚蠢的因素,比如设备被放置在一个地点的什么地方,数据中会有如此多的差异,每个懂数据的人都很清楚,这些数据不可能有助于这种分类。

更重要的是,还有很多其他方法可以获得更多相关数据,但目前并未使用——他们希望在噪声数据中寻找的最重要的东西之一是发出警报,但我们可以更直接地触发警报,而不需要任何硬件!但这些都不够好,因为这位高管认为这个主意听起来不错。的确如此——他发表了关于这个想法的演讲,他的创新思维吸引了很多关注。

我是这个项目团队中两名数据科学家之一。我们都知道这注定要失败,但无法说服数据盲领导层。它降低了士气,耗费了我们大量的时间和资源。我最终离开了公司,很高兴不再参与这个项目。

结论

数据盲导致数据扯淡。使用数据科学的公司中的领导层需要要么精通数据,要么愿意倾听那些精通数据的人的意见。否则,你将会以浪费时间的项目而告终,失去你最好的数据科学家,并且完成的项目将会过于复杂混乱。

用概念组织和记录你的机器学习(或任何)研究项目

原文:https://towardsdatascience.com/organize-and-document-your-machine-learning-or-any-research-project-with-notion-623d52fae972?source=collection_archive---------22-----------------------

由于缺乏组织和文档,研究可能会很困难。

费伦茨·霍瓦特在 Unsplash 上的照片

每个机器学习研究人员最终面临的主要问题之一是他们必须管理的大量数据:论文、网络链接、数据集、模型、问题、想法、实验结果...把它们都放在同一个数字空间不是很好吗?而且井井有条?试试这个概念设置。

这篇文章分享了一个概念设置,通过将所有项目资源保存在同一个地方,并在它们之间建立关系,来帮助研究人员组织和记录他们的过程。它主要集中在一个样本机器学习项目上,因为这是我有经验的领域,但一些工具可能对任何其他研究领域都有用。

概念是一个一体化的工作空间,你可以在其中添加多种类型的块来创建待办任务、笔记、文档页面或数据库。

概念在几个方面不同于其他软件。一旦你掌握了这些基础知识,你就可以建造任何你想要的东西

概念文档

设置主页的屏幕截图。封面图片由 @chrisliveraniUnsplash 上拍摄。

本文分为三个部分,涵盖了普通研究过程所需的大部分工作,以及如何使用应用程序提供的工具来正确地记录和组织它们:文献综述我的项目开发问题管理&小组会议

1.文献评论

研究项目的一个关键部分是相关工作的文献综述。它提供了一个起点,并使其他作者的想法回忆起来。参考文献收集和管理的工具有很多,比如论文或者门德利。这些比本节中介绍的工作流更强大,但是使用它们会导致只有这个任务有一个不同的位置。我想强调的是,这种设置的目的是将一个研究项目的所有资源放在一个工作空间中。然而,这些参考资料收集工具可以作为一种补充。

对于这个任务,我有一个概念数据库,在那里我保存了所有对我的项目有用或感兴趣的资源,主要有三种类型:论文、数据集和网页。数据库是高度可定制和非常强大的,因为它们允许你过滤,标签,排序,当然:搜索,所有必要的行动时,管理大量的保存项目。但是我最喜欢概念数据库的一点是创建多个视图的可能性,因此可能性是无限的:在每个视图中,您可以决定要查看什么(应用过滤器)以及如何查看(视图类型和要显示的属性选择)。此外,数据库中的每一项都有自己的页面,因此您可以向其中添加任何额外的信息。

文献综述表视图:论文、数据集和网络。

在我的设置中,我有一个包含所有已保存资源的通用表格视图,以及三个针对每个类别的附加表格视图。我使用标签对来自相同研究领域的出版物进行分组,并上传(如果有的话)相应论文的 PDF 文件作为 Files 属性中的附件。

2.我的项目开发

这一部分旨在组织构成你的研究项目开发的不同资源。根据我的经验,机器学习项目本质上由训练数据集、测试集和实验的版本组成。显然,代码库或 Jupyter 笔记本也是项目的一部分,但这将不可避免地出现在另一个工作空间中。

这种概念设置可以帮助建立数据集版本化系统和所进行的不同实验的记录(具有实际的实验-数据集关系)。如果您需要在一个地方安排项目特定的细节,如数据集分布、实验指标或混淆矩阵,这也很有用。

训练数据集和测试集

在训练/测试数据集部分,我再次使用了一个数据库表,它显示了代表特定数据集版本的所有字段。

用于训练数据集版本控制的概念数据库示例

该表有一个“文件和媒体属性,我将。培训和测试流程所需的 csv 文件。还有一些其他属性,如项目和类的数量。我在这里添加的重要信息是生成方法,一个“文本”属性让我可以轻松地识别版本,例如:数据集通过每个类取 X 个项目来平衡,或者是否使用了预训练数据扩充技术。

正如您在图中所看到的,假设存在一个实际的实验-数据集关系,可以创建一个 Lookup 属性,自动列出使用该版本进行的所有实验。我们将在实验部分看到如何在数据库之间创建这种关系。

在一个条目的页面上,我添加了一些在任何时候都可能有用的附加信息,比如类分布直方图、文件或者关于这个特定版本的任何注释。

数据集版本页面示例

实验

虽然数据集版本系统很重要,但实验过程是对我帮助最大的地方。从组织和记录的角度来看,这是一项艰巨的任务,因为在某些情况下,有一组巨大的参数定义了一个实验。我知道一些研究人员使用保存参数配置的电子表格。我过去一直在使用它,虽然它有一些优点,但我发现这个应用程序更适合,原因如下:

  • 为同一个数据库创建多个视图的可能性。对于这个任务,我发现 Board 视图非常有用,它会神奇地将您的表项目转换为看板卡,这样您就可以直观地表示您不同实验的生命周期,并在各个列中移动它们。

从表格视图转换到纸板视图

  • 对于数据库中的每一项,你都有一整页来保存与实验相关的任何东西:评估结果、代码块、数学方程、与文献综述数据库中某篇论文的关系,或者你发现了一些有趣的实验内容的网页。任何事。

实验页面详细信息

  • 正如我之前提到的,您可以向训练数据集数据库添加一个“关系”属性,这将实际上链接一个实验到所使用的版本。这允许您属性从另一个表导入到实验表中,因此您可以通过数据集版本的属性来过滤实验。

3.问题管理和小组会议

这一部分是我个人整理与项目相关的东西的一组页面。

  • 问题管理是一种简单的待办事项方法,我发送任务,比如“向 X 发送电子邮件”或“在系统 X 中安装这个依赖项”。与这个领域中其他更强大的工具相比,这个工具有一个优点:您可以在其他数据库中的任务和元素之间建立关系。例如,您可以创建一个任务“Read paper”,该链接会将您带到该项目,您可以在其中阅读其 pdf 或您之前所做的注释。

  • 最后,我在这里使用了一个稍微修改过的模板,它是由 idea 提供的,用于记录您的小组会议。它允许我在会议开始前计划我想与我的研究团队分享的东西。在会议期间,我通常会记下一些重要的事情。对于这个数据库,我发现日历视图很有用,它使浏览会议更容易。

小组会议的日历视图示例

这个装置实现了一个基础研究项目,我希望它能帮助研究人员组织他们的研究过程。即使您使用不同的工具,也不要犹豫分享您对类似项目的想法或工作流程。每一个想法都欢迎改进。

我想祝贺理念团队的出色工作。

你可以在这里找到模板的链接。你可以点击复制:将其添加到你的工作区

[## 研究计划

由@Sergio Ruiz 创作。@serchu。

www . opinion . so](https://www.notion.so/Research-Project-a3601a544f2f4de18bc123a2c1322b90)

使用面向对象编程和 Pickle 组织您的数据和模型

原文:https://towardsdatascience.com/organize-your-data-and-models-using-the-object-oriented-programming-and-pickle-876a6654494?source=collection_archive---------28-----------------------

来自GIPHY.com

为了未来的自己和他人

我喜欢创建一个做笔记的系统。当我记起某个地方写下了什么东西,但又不能马上认出来时,我会非常激动。因此,当我在一个数据科学项目中处理多个模型时,我需要它们在一个地方,当我稍后回来引用它们时。另外,我讨厌为了回到之前的位置而重新运行代码。是的,你总是可以用 python 处理几乎每一种类型的东西,但是我想要一个 pickle 文件,把所有的东西都组织好。所以今天我想分享我是如何使用 pickles 和创建类来组织数据和建模结果的。这篇文章可以帮助你在数据科学项目中实践你的面向对象编程技能。

使用字典来组织创建 pickle 文件的项目。

例如,在我的前一篇文章的中所写的项目中,我创建了一个名为finals的字典,并在数据准备的每一步转换时保存处理过的数据。

在数据准备的每个步骤中保存参数和数据

创建一个与字典同名的 pickle 文件

我将关键字作为代码中使用的变量名,这样当我以后加载 pickle 文件时,我可以直接加载字典、分配变量和使用代码,而不用从头开始运行。

当您需要时,这非常有用:

回到探索性数据分析步骤;

使用尚未准备好放入模型的数据(如未缩放、创建虚拟变量之前的数据)创建用于准备演示或撰写报告的可视化效果。;

使用单独的 Jupyter 笔记本进行数据处理和建模,并加载数据。

加载 pickle 文件并创建变量,变量的名称引用字典中的键。

创建一个类来保存不同的建模结果

注意,在__init__方法中,没有必需的参数。我这样做是为了让它可以更灵活地用于不同类型的事物,并且更容易创建对象实例。但是我创建了我希望对象拥有的属性。

为了利用这一点,我创建了以下内容:

1.两个Pandas.DataFrames用于保存和绘制评估指标,一个字典Result用于保存result对象。

2.向result对象的属性输入信息并显示模型结果的功能。请注意,我已经将X_trainX_testy_trainy_test作为全局变量,但是您可以修改它们作为输入。注意,步骤 1 中创建的DataFrames也保存在Results字典中

那么这是如何工作的呢?

让我用一个简单的逻辑回归模型来演示一下。

现在,你可能会问,当我已经有空间保存评估分数时,我在哪里使用这些数据帧。一旦我收集了不同型号的分数,就很容易创造一个情节来比较他们的表现。

最后,一旦我在字典中添加了我创建的所有内容,下次我需要它时,它就会被腌起来。

我希望你觉得这是有用的。此外,如果你有更好的方法来保存你的结果和数据,请在下面留下评论,让我知道。你可以在这里看到我在本文中使用的示例代码。

感谢您的阅读。

用数据科学整理我的 Spotify 播放列表

原文:https://towardsdatascience.com/organizing-my-spotify-playlists-with-data-science-9a528110319?source=collection_archive---------43-----------------------

使用 K-means 聚类来组织我的 Spotify 播放列表

安库什·巴拉德瓦伊

照片由晨酿Unsplash 拍摄

介绍

我们大多数人都有一个有点大的 Spotify 播放列表。这个播放列表可能是作为一个精心策划的 R&B 氛围开始的,其轻快的人声和催眠的节拍为你早上的一杯咖啡提供了完美的配乐。然而,随着时间的推移,你不断变化的情绪和 Spotify 的推荐将这个播放列表变成了一个不同歌曲和流派的滚动 bumrush,无法提供一致的收听体验。

因此,我试图用这个项目回答以下问题:

给定一个包含太多歌曲的 Spotify 播放列表,我如何使用数据科学将这个大的播放列表分成包含相似歌曲的较小播放列表?

获取播放列表曲目和音频功能

该过程的第一步是访问我的播放列表中的曲目列表,以及它们的音频功能。为此,我使用 Python 库 Spotipy 来访问 Spotify 的 Web API。

首先,我在Spotify for Developers Dashboard上登录我的 Spotify 帐户,然后选择“创建应用程序”来创建一个新的应用程序。只要你的 app 是“非商业”的,相信你在这个过程中应该不会遇到什么问题。在我创建了我的应用程序之后,我找到了我的客户端 ID 和客户端秘密,并将它们存储在 client_id 和 client_secret 变量中。这些变量随后被用于验证对 Spotify Web API 的访问:

import spotipy
from spotipy.oauth2 import SpotifyClientCredentialsclient_id = 'client_id'
client_secret = 'client_secret'client_credentials_manager = SpotifyClientCredentials(client_id, client_secret)
sp = spotipy.Spotify(client_credentials_manager = client_credentials_manager)

从这里,我访问了音轨和它们的音频特征:

sp.user_playlist_tracks('username', 'playlist_id') 
sp.audio_features('song_id') #'username' of individual who created playlist
#'playlist_id' of playlist
#'song_id' of song 

使用这些请求,我用播放列表中每首歌曲的曲目名称、曲目艺术家和曲目音频特性填充了一个 Pandas 数据帧。Spotify 为每首歌曲提供了许多音频功能,这些音频功能的详细信息可以在这里找到。此外,我参考了这篇文章和来自 Spotipy 网站的示例来访问我的播放列表中的曲目及其音频功能。如果你对 Spotipy 和 Spotify 的 Web API 感到好奇,可以查看 Spotipy 的文档页面和 Spotify 的 Web API

探索数据

为了开始研究我的数据,我使用 Seaborn 的热图和聚类图可视化了音频特征的相关性和层次聚类。

import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inlinesns.heatmap(df.corr())
sns.clustermap(df.corr()) 
#make sure that your dataframe df for both of the above calls have all categorical columns removed

聚类图

在浏览了聚类图之后,很明显,除了能量和响度之外,大多数音频特征彼此之间没有强相关性(在这种情况下,强正相关性完全有意义)。对我对数据的理解有些不满意,我决定进行主成分分析。

主成分分析(PCA)是一种降维方法,即当一个包含许多变量的数据集被压缩成几个成分时,这些成分可以解释原始数据集中的大部分,但不是全部。更多信息可以在杰克·范德普拉斯的 Python 数据科学手册摘录中找到。

主成分分析的每个额外分量解释了数据集中的额外方差,我想绘制出当你增加 n 时,分量的数量 n 解释了多少方差。这样做将有助于我找到解释数据的组件的理想数量,方法是在该图中寻找“肘部”,即 n 的增加导致解释方差的增加减少,在图上呈现为一个尖点。然而,对于这个数据集,我的图看起来像:

成分数与解释方差的比率

那是粗糙的。尽管每个附加成分解释的方差比率在下降,但我需要 8 个成分来解释数据中 76%的方差,这似乎没什么帮助。

然而,我的研究结果表明,我的数据没有表现出多重共线性,这表明预测变量之间没有高度的线性相关性,如果我想使用线性模型,这是很有用的。

k-均值聚类和我的新播放列表

是时候将我的歌曲组合成新的播放列表了!我使用了 K-means 聚类,这是一种将你的数据分成 K 个聚类的聚类算法。如果你想了解更多关于算法的知识,Ben Alex Keen 的这篇文章非常好。

from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters = 4)
kmeans.fit(df)
#once again, make sure df has no categorical variables

第一次运行 K-means 时,我将我的曲目分为四个簇,因为这似乎是一个很好的播放列表数量(在大多数其他情况下,“肘方法”用于确定使用多少个簇)。然而,一个集群只有七首曲目,这不是我经常听的播放列表。因此,我转而用三个集群运行 K-means。

我现在想看看这些集群之间是否有清晰可见的区别。由于原始数据集有许多变量,我返回到我的 PCA 并将数据集分解为两个分量,希望这两个分量会显示出一些聚类之间的视觉分离。

PC1 与 PC2 上的集群

每个点表示一个轨迹,颜色表示该轨迹的簇。不幸的是,没有一个好的图表可以直观地根据主成分来区分聚类。

相反,为了理解每个聚类之间的差异,我构建了一个 Pandas 数据框架来比较每个聚类中每个音频特征的平均值,其中指数代表聚类:

每个聚类中音频特征的平均值

逻辑回归

我仍然很想知道一个音轨的音频特征是如何影响它的聚类的。知道数据没有多重共线性,我决定使用线性模型来探索这个问题。具体来说,我首先用 K-means 聚类法将我的数据分成两个聚类,然后使用逻辑回归来预测一个音轨的聚类。

X = df['feature_variables']
y = df['track_cluster']from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = .3)from sklearn.linear_model import LogisticRegression
log = LogisticRegression()
log.fit(X_train, y_train)
y_pred = log.predict(X_test)log_coeff = pd.Series(log.coef_[0], index = feature_column_names)

在最后一步中,我创建了一个名为 log_coeff 的 Pandas 系列,它显示了模型用来确定音轨类别的每个音频特征的系数。与较大幅度的系数配对的音频特征对于模型对音轨的分类更重要。

每个音频特征的系数

我还检查了我的 logistic 模型的分类报告和混淆矩阵,以确保模型足够准确。这两个函数都可以在 sklearn.metrics 中找到,实现如下:

from sklearn.metrics import confusion_matrix, classification_report
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))

结论

总之,通过这个项目,我把我的播放列表分成三个小的播放列表。在这个过程中,我使用了主成分分析,K-均值聚类和逻辑回归。

用于这个项目的完整代码可以在这里找到。

AutoML 的起源:最佳子集选择

原文:https://towardsdatascience.com/origins-of-automl-best-subset-selection-1c40144d86df?source=collection_archive---------43-----------------------

所有图片均由作者生成

以及选择后推理的危险

由于有很多关于 AutoML 的传言,我决定写一下最初的 AutoML;逐步回归和最佳子集选择。然后,我决定忽略逐步回归,因为它是,可能应该停止教授。这就留下了最佳子集选择来讨论。

最佳子集选择背后的想法是选择变量的“最佳”子集以包括在模型中,一起查看变量组,而不是一次比较一个变量的逐步回归。我们通过评估哪个子模型最符合数据来确定哪组变量是“最佳”的,同时对模型中的独立变量的数量进行惩罚以避免过度拟合。评估模型拟合程度的指标有多种:调整后的𝑅-squared、阿凯克信息标准(AIC)、贝叶斯信息标准(BIC)和马洛的 𝐶𝑝 可能是最著名的。

每一个的公式如下。

对于校正后的 R 平方,您希望找到具有最大校正后 R 平方的模型,因为它解释了因变量中的最大方差,从而降低了模型的复杂性。对于其他模型,您希望找到具有最小信息标准的模型,因为它是因变量中具有最小未解释方差的模型,这会降低模型的复杂性。它们是同一个概念,即最大化好的东西与最小化坏的东西。

AIC 和 Mallow 的 𝐶𝑝 都倾向于给出更好的预测模型,而 BIC 则倾向于给出自变量更少的模型,因为它对复杂模型的惩罚比其他两个更重。

像生活中的大多数事情一样,自动化模型选择是有代价的。如果你用你的数据选择一个线性模型,所选变量的系数将偏离零!每个系数的单个 t 检验和整体模型显著性的 F 检验的零假设都基于每个系数的均值为 0 的正态分布假设。由于我们在系数中引入了偏差,这些测试的I 型误差水平会增加!如果您只需要一个预测模型,这可能不是一个问题,但是它会使使用所选模型做出的任何统计推断完全无效。AutoML 可能能够生成体面的预测模型,但推理仍然需要一个人仔细思考问题,并遵循科学的方法。

证明最佳子集选择的偏差

我进行了一项模拟研究来证明由最佳子集选择引起的偏差。我们不看系数中的偏差,而是看模型中误差项的估计标准差中的偏差

其中误差项是同分布且独立分布的【𝑁(0,𝜎】随机变量。

在每一轮模拟中,从相同的分布中产生 100 个观察值的样本。真实模型,它只包含真正重要的变量,以及 AIC 和 BIC 选择的最佳子集模型也被估计。从每个模型中,我用公式估算了的误差项

这被执行 500 次。

我模拟的具体参数如下:= 100,#个自变量= 6,= 1,有效自变量个数为 2。截距也很重要,所以 3 个系数是非零的。使用【𝑁(5,1随机数来选择非零系数,因为我懒得定义固定的数字,但它们在所有轮次的模拟中都保持固定。******

我首先定义了自己的函数,使用 AIC 或 BIC,通过查看变量的每个组合,使用一种简单的方法来执行最佳子集选择。它只对少量变量有效,因为它必须考虑的模型数量随着变量数量的增加而增加。考虑的模型数量为

但是最佳子集选择的更聪明的实现使用树搜索来减少考虑的模型数量。

感兴趣的图形位于最佳子集选择函数和模拟代码块的下方。

红线是 y 轴等于 x 轴的线,是真实模型对 𝜎 的无偏估计。正如你在下面的图表中看到的,𝜎的估计值偏离了 best AIC 和 BIC 选择的模型。事实上它们将永远小于或等于来自真实模型的的无偏估计。这说明了为什么通过最佳子集选择选择的模型对于推理是无效的。**

奖励部分:调查 LASSO 和岭回归中误差项的估计标准差的偏差

在进行上述模拟研究时,我对正则化方法在线性模型中估计误差项的标准偏差时的潜在偏差产生了兴趣,尽管人们不会使用正则化模型来估计参数以进行推断。众所周知,LASSO 和岭回归有意地将估计系数偏向零,以减少模型中的方差(来自同一总体的样本之间估计系数的变化量)。套索可以设置系数等于零,执行变量选择。岭回归使系数偏向零,但不会将它们设置为零,因此它不是像最佳子集选择或套索那样的可变选择工具。

我使用与之前相同的设置,但是将样本大小从 100 增加到 200,自变量的数量从 6 增加到 100,重要自变量的数量从 2 增加到 50。使用三重交叉验证在 0.01、0.11.0 和 10.0 之间选择套索和脊模型中的收缩参数。为了计算𝜎̂,我计算了 LASSO 模型中非零系数的数量,并使用了所有 100 个系数,加上 1 个用于岭模型的截距,因为它将系数偏向于零,但没有将它们设置为零。**

显然,正则化的线性模型对于推断的目的是无效的,因为它们使系数的估计有偏差。我仍然认为,调查误差项的估计标准差中的任何偏差都值得编写一点代码。

这些图位于这个代码块的下方,用于模拟。

通过目测,在 LASSO 模型中出现向下的无偏估计,但是无偏估计并不像在最好的 AIC 和 BIC 模型中那样形成一个上界。岭模型在估计这个参数时没有表现出明显的偏差。让我们用配对 t 检验来研究一下,因为估计值是在每次迭代中从同一个样本中得到的。我使用标准的 p 值截止值 0.05,因为我懒得决定我想要的测试功效。**

正如目测所猜测的,没有足够的证据表明来自真模型和岭模型的的估计值之间存在均值差异。然而,在 0.05 的显著性水平上有足够的证据可以得出结论,LASSO 模型倾向于对做出向下有偏的估计。这是否是一个普遍的事实还不知道。做出结论需要正式的证据。****

谢谢你坚持到最后。虽然使用数据选择模型会使经典的推断假设失效,但是选择后的推断是统计研究的一个热门领域。也许几年后我们会谈到自体感染。

我这个项目的所有代码都可以在这里找到。

其他 ML 术语:标签泄漏

原文:https://towardsdatascience.com/other-ml-jargons-label-leakage-9e85b22c6fd0?source=collection_archive---------46-----------------------

其他 ML 术语

机器学习中的标签泄漏及其对模型性能的影响

你是否被一场完美或近乎完美的模特表演压垮过?那种快乐是不是被那个出卖了你的功能给破坏了?

简而言之,当你想要预测的信息直接或间接出现在你的训练数据集中时,就会发生标签泄漏目标泄漏或简单地说泄漏。它导致模型过度表现其泛化误差,并极大地提高了模型的性能,但使模型对任何现实世界的应用都无用。

照片由 Erlend EksethUnsplash 上拍摄

数据泄露是如何发生的

最简单的例子是用标签本身训练模型。在实践中,在数据收集和准备过程中,不经意间引入了目标变量的间接表示。触发结果的特征和作为目标变量的直接结果的特征是在数据挖掘过程中收集的,因此应该在进行探索性数据分析时手动识别。

数据泄露的主要指标是“好得令人难以置信”模型。该模型很可能在预测期间表现不佳,因为它是该模型的次优版本。

数据泄漏不仅仅是因为训练特征是标签的间接表示。也可能是因为来自验证或测试数据的一些信息保留在训练数据中,或者来自未来的一些信息保留在历史记录中。

标签泄漏问题示例:

  1. 预测一个人是否会开立一个具有表示此人是否有相关银行账号的特征的银行账户的概率。
  2. 在客户流失预测问题中,一个叫做“面试官”的特征是客户是否流失的最佳指标。这些模型表现不佳。原因是这位“面试官”是一名销售人员,只有在客户确认他们打算流失后才会被指派。

如何打击标签泄露

  1. 移除它们或添加噪声以引入可以平滑的随机性
  2. 使用交叉验证或确保使用验证集在看不见的实例上测试您的模型。

3.使用管道,而不是缩放或转换整个数据集。当基于所提供的整个数据集缩小特征时,例如,使用最小-最大缩放器,然后应用训练和测试分割,缩放的测试集也包含来自缩放的训练特征的信息,因为使用了整个数据集的最小值和最大值。因此,总是建议使用管道来防止标签泄漏。

4.根据保留数据测试您的模型并评估性能。就基础设施、时间和资源而言,这是最昂贵的方法,因为整个过程必须使用正确的方法再次进行。

结论:

数据泄漏是最常见的错误之一,在特征工程、处理时间序列、数据集标注以及巧妙地将验证集信息传递给训练集时可能会发生。重要的是,机器学习模型仅暴露于预测时可用的信息。因此,建议仔细挑选特征,在应用转换之前拆分数据,避免在验证集上拟合转换,并使用管道。

参考:

  1. https://www . cs . umb . edu/~ ding/history/470 _ 670 _ fall _ 2011/papers/cs 670 _ Tran _ preferred paper _ leaking data mining . pdf
  2. https://machine learning mastery . com/data-leakage-machine-learning/
  3. https://bridged . co/blog/7-用于创建培训数据的最佳实践/

我们的人工智能未来

原文:https://towardsdatascience.com/our-ai-future-473245c11438?source=collection_archive---------75-----------------------

跟上新的硅基适者生存

安迪·凯利在 Unsplash 上的照片

没有人喜欢浪费时间。他们为什么要这么做?这是我们拥有的最宝贵的资源。每天我们有 86400 秒,不多也不少。无论你多么富有或强大,我们都无法让时光倒流。时间是终极资源,我们都平等地获得它。

我们如何使用这种资源是我们的选择。现在,你正在阅读这篇文章来发展你自己。明天变得比今天更好。为了变得更好,我们必须学习。随着世界以越来越快的速度前进,我们必须迅速适应这个新世界。

碳基进化通过适者生存决定了成功。这很快被新的硅基进化所取代。成功取决于我们的适应能力。为了适应,我们必须学习。

然而,有时我们会错过趋势。我们今天学到一些东西,明天就不再相关了。我们今天选择忽略某事,因为它明天会成为下一件大事。

幸运的是,我们有太多的专家了。技术前沿的智库、行业领袖和研究人员。

我们可以也应该从中吸取教训。他们有很多话要说。

李开复

李开复,第一个能够识别不同声音的语音识别系统的创造者。他曾在苹果、微软和谷歌担任高管职位。

在苹果公司时,李开复领导了 R&D 多语言人工智能系统部。其中之一是卡斯帕,他与李和苹果公司首席执行官约翰·斯考利一起出现在《早安美国》节目中。这是在 1992 年,距离 Siri 发布整整 19 年。

1998 年,李开复在北京建立了微软亚洲研究院的前身。

"这在各个方面都是一种现象。"—比尔·盖茨在北京实验室

在硅谷占据绝对主导地位的时代。建立这样一个实验室绝非易事。2004 年,微软亚洲研究院迅速成为世界上最热门的计算机实验室。

在这一点上,李休息一下,享受并陶醉于他超人的成就可能是有意义的。

相反,他去了谷歌中国,在该地区建立了公司,并监督他们在这个竞争异常激烈的市场中的发展。

2009 年,李开复从谷歌中国辞职。他这样做是为了进入他的下一个,可能是迄今为止最雄心勃勃的项目。现在被称为 Sinovation Ventures,这是李氏的风险投资基金。

该基金培育中国的科技初创企业,通过它,李开复为中国的大部分科技市场铺平了道路。据李开复和世界各地的许多其他专家称,中国现在将取代硅谷,成为新的全球科技超级大国。

人工智能超能力

李开复是我们应该听的人。他的书《人工智能的超能力》是关于人工智能主题以及我们可以期待它带我们去哪里的最好的书之一。

Lee 专注于人工智能在全球范围内迅速变化的地理优势。他指出,在某些领域,中国已经在人工智能至上的竞赛中超过了美国。他认为,用不了多久,中国就会在人工智能领域获得完全或接近完全的主导地位。

人工智能播客

麻省理工学院的人工智能研究员 Lex Fridman,尽管是一个非常有才华的研究员。找到了另一个利基,并迅速成为跟上人工智能世界的世界级资源。

人工智能播客挖掘顶级研究人员和行业领袖的思想——从 Yann LecunYoshua Bengio ,到 Elon Musk 和我们自己的李开复

Lex 不仅设法在这个播客上收集了绝对最好的想法,而且这些采访的深度简直是惊人的。

莱克斯本人就是专家。他建立了这个播客,作为尖端人工智能研究的象牙塔和我们普通人生活的世界之间的桥梁。

这些播客可以通过 YouTube苹果播客访问。

第四次工业革命

世界经济论坛创始人兼执行主席克劳斯·施瓦布的这本书是对工业未来的极好总结。

施瓦布不仅专注于人工智能,还关注物联网、生物技术和先进材料等其他技术。让我们对未来的科技有更广阔的视野。

这很重要,因为人工智能本身并不是未来。相反,我们将有一个来自不同领域的多学科合并。

我们可以在中国的感知人工智能中看到这种技术合并,它严重依赖其他技术,如嵌入式系统(IoT)。

模糊界限

感知人工智能是溢出到物理世界的东西。由于传感器和物联网设备的快速增长,感知人工智能正在模糊数字世界和物理世界之间的界限。

中国备受争议的社会信用体系就是一个最好的例子。忽略伦理(这不应该被忽略),它确实是西方世界无与伦比的奇迹。

将中国的大规模监控系统与人工智能相结合,公民会被自动排名。积极支持献血、志愿工作或慈善捐赠等行为。

另一方面,在公共交通工具上吃东西、多占座位、或制造噪音[2],或没有正确分类个人垃圾[3]都会降低你的分数。

像这样一个系统的规模是难以置信的巨大。这是一个工程奇迹——有点奥威尔式的意味。

OpenAI 博客

OpenAI 是世界上最前沿的人工智能研究机构之一。自然,他们会产生绝对迷人的研究。

研究论文对于保持最新信息非常重要,但有时更容易看到写得好的、信息丰富的文章。这正是我们在他们的博客上发现的。

截图来自 OpenAI 网站,展示了他们最近的几篇突破性文章。

这让我们对人工智能研究的绝对前沿有了惊人的了解。

OpenAI 在可视化他们的研究成果方面做得非常好。阅读他们关于从多主体互动中使用紧急工具的文章,我们得到了一个连续的演示正在讨论的行为的视觉流。

除此之外,对于更多的技术人员来说。OpenAI 总是包含相关的研究论文和每篇文章的代码。涵盖了我们在试图理解这些突破的含义和用途时所希望的一切。

结论

我们正在迅速进入一个新时代。成功在很大程度上取决于我们的学习和适应能力。

通过建设未来的个人和团队的眼睛,一瞥未来的风景。我们可以更好地理解我们要去哪里。希望我们能从这迷人的旅程中获得最大的收获。

当然,在了解我们共同的未来时,这不是一个完全全面的清单,但这是一个开始。我很想听听你推荐的文章、书籍、播客和其他资源。

我希望你喜欢这篇文章并从中受益。一如既往的感谢阅读!

参考

[1] G .黄,世界上最热的计算机实验室 (2004),麻省理工学院技术评论

[2] B .于,【北京市轨道交通客运管理规定】 (2019),人民网

[3] E .黄,中国垃圾分类违规者现在面临被垃圾信用评级处罚的风险 (2018),石英

这些令人着迷的人工智能技术之一是生成对抗网络(GANs)。

我最近处理了这些架构的开发,并写了一些我们可能犯的错误和误解,这些错误和误解破坏了我们开发工作模型的机会。如果你对此感兴趣,你可以在这里阅读:

[## 打甘游戏

开发“自切片面包以来最酷的东西”的技巧

towardsdatascience.com](/beating-the-gan-game-afbcce0a20be)

我们的专栏

原文:https://towardsdatascience.com/our-columns-53501f74c86d?source=collection_archive---------20-----------------------

TDS 上的专栏是我们的团队围绕特定主题、想法或格式精心策划的帖子集合。

Unsplash 上由 Alex Geerts 拍照

我们每天发表几十篇一流的文章。为了帮助你找到一些最好的文章,我们已经创建了几个围绕特定主题和文章类型的集合。

例如,你可能正在寻找关于获得机器学习工作的见解;你可以去我们的办公时间专栏找到我们推荐的相关文章。如果你有心情进行一次长时间的深思熟虑的阅读,你可以浏览我们的深度阅读页面,在那里我们收集了一些更有实质性的贡献。诸如此类。

如果你是一个新的或者有抱负的 TDS 投稿人,浏览我们的专栏会让你对我们团队认为特别有吸引力的文章类型有一个坚实的概念。快乐阅读!

入门

如果您是数据科学的新手,请从这里开始!我们的入门专栏包括一系列文章,将帮助您在许多数据科学和机器学习领域入门。

编辑推荐

我们作为编辑精选的帖子代表了最好的 TDS:见解深刻,在新鲜和发人深省的主题上引人入胜的写作。有些非常技术性,有些可能更投机,甚至固执己见。它们都是必读书目。

深潜

从让复杂概念变得容易理解的耐心解释者,到带有大量代码示例的逐步指南,这个集合汇集了真正值得您花费时间和全部注意力的文章(它们通常至少需要 12 分钟的阅读)。

办公时间

你有兴趣在数据科学领域找份工作吗?你想知道如何为工作面试做准备,或者了解数据科学家的典型一天是什么样的吗?这些只是我们办公时间专栏中的一些话题。

月刊

每个月,我们的团队都会就某个特定主题发布一些精选的最佳文章。你可以在这里找到我们所有的月刊!

我们的播客

探索我们所有的播客剧集,聆听关于数据科学和机器学习的精彩对话。🎧

意见

在我们的观点专栏中,您可以找到不同的观点、有争议的观点、对现有问题的新观点等等。我们鼓励我们的作者参与智慧的讨论,我们也很高兴在这里看到你的想法。

实践教程

你在为你的下一个机器学习项目寻找灵感吗?您是否正在尝试寻找一个能够教给您编程和数据科学最佳实践的教程?你想看看顶尖组合项目的例子来帮助你在求职中脱颖而出吗?您可以在我们的实践教程专栏中找到所有这些以及更多内容。

理解大数据

如果您对分析和处理大数据感兴趣,可以看看这篇专栏文章。它包括数据工程的高级教程、模型部署的最佳实践、公司案例研究等等。

数据变更

我们相信数据科学有助于让世界变得更美好。我们认为正确使用和解释数据可以改善我们的生活。要找到更多讨论数据的力量和重要性的文章,请访问我们的数据促进变革专栏。

小窍门

Python 101 之后是什么?面向对象的设计是如何工作的?如果你想在基础知识之外提高你的编程技能,你可以收藏这个专栏。它的特色是教授高级编码语法的文章,干净代码的技巧,以及介绍提高编码性能的工具。

数据新闻

你是新闻迷吗?请查看本专栏中结合了强烈视觉效果和分析严谨性的文章。数据记者解读数据,并在引人入胜的叙述中展示他们的发现,揭示报道不足的问题。

思想与理论

数据科学和机器学习是发展最快的两个研究领域。在这里,我们策划来自学者、积极的学生和行业专家的研究突破。

业内笔记

数据科学在实践中是什么样子的?我们有兴趣向从业者学习他们认为在行业用例中最有用的工具。本专栏将重点介绍从机器学习技术到管理云基础设施的应用案例研究。

数据科学和机器学习中的新问题

我们还创建了几个专栏,在这些专栏中,我们收集了一些有助于确保数据科学和机器学习技术以造福人类的方式发展的故事(你可以在这里了解更多关于这一点的信息):

我的数据分析原则

原文:https://towardsdatascience.com/our-data-analytics-principles-4be44d262245?source=collection_archive---------55-----------------------

Unsplash,演职员表:艾萨克·史密斯

我如何帮助我的客户

当我开始 Enka Analytics 的时候,我非常确定我要坚持的原则。当你在经营一家企业或过普通生活时,我怎么强调有原则的重要性都不为过。原则帮助我们在危机时刻坚持选择的道路。它有助于做出艰难的决定。想一想,当我们在做一个无法区分黑白的决定时,想想你的原则,哪个决定违反了你的哪条不可协商的原则。最终结果,决策变得容易。因此,我也为自己设定了一些不容商量的原则。下面列出了它们(没有特定的顺序)。

永远不要报告不准确的见解

如果你问我对数据分析领域的看法,这将与我开始时的看法大相径庭。即使是在最结构化和最干净的数据中,得出有意义的发现也绝非易事。当你试图挖掘一个洞察力时,往往会有灰色地带,有时需要很长时间才能得到结果。然后,当结果不符合预期时,我们走一条简单的数据挖掘之路。千万不要那样做!

想象一下你提供的错误见解的后果。假设,你正在分析一个销售团队的生产力,为了留下好印象,你沉迷于数据钓鱼。结果,如果没有被组织交叉检查,可能会导致一个多产的推销员不必要的解雇。另一方面,如果组织意识到调查结果不准确,他们会发现很难再相信你的结果,这对你来说是一个损失。

因此,我保证无论在分析中投入多少努力,报告虚假信息都是不允许的,即使这意味着重新做整个项目。

隐私不容商量

可能是最重要的一点。 数据隐私不容商量。当你处理客户信息时,他们信任你。当然,当信息被共享时,是有法律规定的。尽管如此,永远不要在数据隐私上妥协。最好投资于保证保护的基础设施,例如使用安全云和软件。

请记住,一旦你失去了客户的信任,以后就很难挽回了。

我们所做的一切都是我们自身的延伸

这个原理不仅限于数据分析,事实上,它可以用于任何领域。我们的行为决定了我们是谁。史蒂夫·乔布斯曾经说过一句名言:

我们创造产品,并自豪地出售,可以推荐给我们的家人和朋友。

从那以后,我一直使用这个原则,只是稍加修改。我们提交的每份报告、仪表板或调查结果,都确保以最佳方式呈现。我们把我们的灵魂倾注其中,确保它代表了 100%的我们。报告中的一个小拼写错误会破坏印象,因为它清楚地表明了不专业的行为。图表中使用的颜色定义了你的个性,选择的字体,标点符号的使用等等,决定了我们是谁。报告的安排和结构显示了你的思维方式。这是对小事情的关注,积累起来会给人留下深刻的印象。这种印象的好处远远超出人们的理解。把你提交的任何报告都当成你自己的一部分。你会展示你不引以为豪的东西吗?

从心中的目标开始

想象一下,当某人口述结构时,他让你在一张普通的纸上画点什么。类似于:

向下画一条 3 厘米长的水平线,然后从端点向左画一条 45 度角的对角线,使对角线的端点与线的起点平行。将对角线的终点连接到初始线的起点,并画一个半圆将其连接回对角线。向下 3 厘米画一条水平线。你得到了多少数字?

想象一下,有人向你背诵这个,你应该完全按照说明来画。这将是很难做到的,你可能会成功,但你必须更加专注,导致能量的损失。

现在,考虑第二个场景,你已经在开始时看到了这个图形,你完全清楚它看起来是什么样子。现在你画画会容易些。这是我的下一个数据分析原则。

从心中的目标开始。除非你清楚你要解决的问题,否则你的结果永远不会是最好的。当我说清晰的时候,我指的是绝对意义上的清晰,目标的清晰,小细节的清晰,你想要的结果的清晰。一旦这样做了,你将会用更少的努力和时间完成任务。你会提供客户想要的东西,让你的客户满意。

简单就是极致世故

客户问的事情从来都不简单。商业运作的方式从来都不简单。机器学习算法从来都不简单。然而,客户的期望是以团队可以轻松实现的简化方式交付东西,这就是数据分析的艺术方面。让复杂的事情看起来简单是一门艺术。

假设您是一家大型组织的首席执行官,从数据分析团队那里收到了一份 10 页的报告。在某些情况下,首席执行官没有时间看完一份 10 页的报告。现在问题来了,我们怎样才能吸引首席执行官的注意力,而不占用她太多的时间,让她了解每一个重要的发现。对于一个给定的洞察,选择哪一个图表,使得信息很容易理解?我们要不要去掉坐标轴,在图上标注一下标签?我们如何简单地描述一个模型,说明它的优点和缺点?所有这些都需要额外的时间和努力。无论分析中涉及到什么样的复杂性,都应该简单到容易理解,但是,不要简单到错过重要信息。

正如阿尔伯特·爱因斯坦曾经说过的:

天才是把复杂的想法变得简单,而不是把简单的想法变得复杂。

这些是我的一些数据分析原则。这绝对不是一个详尽的列表,因为我每天都在学习新的东西。随后,随着经验的积累,更多的原则得到发展。然而,这些是我每天生活的原则,每当我在日常活动中面临任何困境时,我都会求助于这些原则来提醒我们是谁,我们做得最好。

感谢您的阅读。我们真诚地希望你觉得这篇文章很有见地,我们一如既往地欢迎讨论和建设性的反馈。

文章作者:伊桑·乔德里,Enka Analytics 创始人。

联系一山:【icy.algorithms@gmail.com

LinkedIn 上和他联系。

我们在 2049 年的生活

原文:https://towardsdatascience.com/our-life-in-2049-8396a0e2a123?source=collection_archive---------37-----------------------

迫切需要改变硅谷“快速移动和打破常规”的思维模式,因为我们今天正在建立的技术,如人工智能、区块链和基因组学,将对人类社会产生更广泛和更深刻的影响。

UnsplashLucrezia Carnelos 拍摄的照片

上周末,我参加了旧金山的“第二个创意之夜”,这是一个 6 年前在巴黎发起的活动,后来已经传播到全世界。这是在旧金山公共图书馆举行的长达七小时的马拉松式辩论、小组讨论、表演和互动体验。

从一个会议走到另一个会议,你可以听到来自大楼其他角落的音乐和声音。你可以看到人们四处走动,寻找他们感兴趣的话题。感觉就像我们在蜂窝里。所有这些辩论、讨论和经历会激发更多的思考和创造力,而不是蜂蜜和蜡。

创意之夜 SF 2020 项目时间表

今年的主题是“生活在边缘”,每一层都有一个主题,包括混乱+创造,奇迹+担忧,排斥+归属,真实+怀疑,流通+边界,以及景象+声音。

听到如此不同的声音和观点是很有趣的,尤其是对我们这些生活在旧金山泡沫中的人来说。特别是,我发现欧洲和美国的思想流派之间的对比非常有趣。

增强 vs 增强

在一个医疗保健小组中,法国初创公司 Ganymed Robotics 的联合创始人兼首席执行官索菲·卡亨(Sophie Cahen)描述了美国和欧洲之间的巨大差异。

从她的角度来看,美国公司,尤其是硅谷的公司,一直在寻找增强人类能力的方法,就好像我们只是复杂的机器一样。另一方面,欧洲人更保守。他们乐于修复或增强,而不是增强人类。

她补充说,如果你考虑咖啡和鞋子的强化,强化人类可以追溯到几千年前。最古老的外科手术大约在 7000 年前实施。这是几年前在法国发现的一种截肢术。乳腺癌最古老的证据是在一具 4200 年前的埃及骨骼中发现的。

增强和治疗对我们来说都不再陌生。它们存在了几千年。然而,这次不同的是,我们不满足于仅仅增强或修复人体,我们想通过生物黑客和基因工程重写代码。

AI 的所有权

关于人工智能(AI)和大数据的另一个有趣的观点是在题为“2049 年我们的生活”的主题演讲中提出的在美国,人工智能大多是由私人组织开发的,以获取利润。人们似乎并不过度关注这一点。

人们普遍认为,资本主义、竞争和对利润的追求创造或加速了创新。如果人工智能是在公共部门开发的,那么这项技术真正起飞需要更长的时间。

然而,如果人工智能真的像吴恩达所说的那样是新的电力,难道不应该像其他公共产品一样受到更严格的监管,以确保每个人都可以使用它吗?难道我们不应该开发更多易于使用的工具,以便 AI 不仅仅掌握在少数公司手中吗?

我们知道ML 模型的性能随着用更多的数据进行训练而提高。越来越多的初创公司开始出售训练数据集或标签服务,如 Scale AI 和 Lionbridge。

为什么我们要免费赠送我们的个人数据?

为什么我们要让科技巨头利用我们的大量个人数据积累巨额利润?另一方面,欧洲人似乎更关心大公司拥有大部分数据的事实。这反映在 GDPR,欧盟法律中关于数据保护和隐私的规定。

谷歌已经阅读了你所有的电子邮件,知道你去了哪里。现在它甚至可以追踪你的心跳,并且可以访问数百万份医疗记录。卡亨说:“入侵我们每一个人,而不仅仅是我们的笔记本电脑,越来越容易了。”。

她警告说,生物学、算法和大数据的这种融合使得人体越来越容易被黑客攻击。如果有一天算法确定你有很高的患癌风险,而你却感觉完全健康,怎么办?如果这些数据被泄露或分享给你的雇主怎么办?

[## 设计 ML 产品的用户体验

三个原则:期望、错误和信任!

towardsdatascience.com](/designing-the-user-experience-of-ml-products-8aef5afb510b) [## 为什么我们明明应该信任机器,却不信任它?

为什么人类必须留在自动化循环中?如何才能创造人机关系的美好未来?

towardsdatascience.com](/why-dont-we-trust-machines-when-we-obviously-should-dede847dde73)

结论

这不是全新的信息,但我们并没有太关注它。我们中的大多数人,包括我自己,仍然享受着科技巨头提供的方便和免费的服务,而没有过多地考虑其潜在的影响或潜在的副作用。

知道至少另一个大陆上的一些人对技术和未来生活有不同的看法,多少让人感到欣慰。因此,希望我们能够避免在任何一个方向走得太远。

各国如何在全球范围内就这些重大问题达成一致?幸运的是,我们已经看到美国人近年来稍微倾向于更多的政府监管,并将人工智能或数据视为公共产品。欧洲人也变得更有企业家精神。

迫切需要改变硅谷“快速行动,打破常规”的思维模式因为我们今天正在构建的技术,如人工智能、区块链和基因组学,将比移动应用程序对人类社会产生更广泛和更深刻的影响。

我们连线吧!如果你喜欢读这篇文章,请在这里订阅我的个人博客!

Bastiane Huang 是 OSARO 的产品经理,OSARO 是一家总部位于旧金山的初创公司,致力于开发软件定义的机器人。她曾在亚马逊的 Alexa 小组和哈佛商业评论以及该大学的未来工作倡议中工作。 她写的是关于 ML、机器人和产品管理的文章。跟着她到这里

我们的机器学习算法正在放大偏见,并使社会差距永久化

原文:https://towardsdatascience.com/our-machine-learning-algorithms-are-magnifying-bias-and-perpetuating-social-disparities-6beb6a03c939?source=collection_archive---------46-----------------------

人工智能伦理和考虑

对于机器学习工程师,雇用他们的公司,以及受他们调整的算法影响的用户:

凯文·Ku 在 Unsplash 上拍摄的照片

在我开始学习机器学习课程后不久,我意识到媒体对人工智能的状况有一种荒谬的夸大。许多人的印象是,人工智能是研究开发有意识的机器人实体,很快就会接管地球。每当有人质疑我的研究时,我通常会打起精神,因为我的回答经常过早地遭遇惊恐的喘息或愤怒的对抗。可以理解。

有意识的机器人实体即将接管?

然而,现实是,机器学习不是危险的魔法精灵,也不是任何形式的有意识实体。为了简单起见,我通常说人工智能的本质是数学。有人说这只是“美化的统计数据”。或者正如凯尔·加拉丁(Kyle Gallatin)所言,“机器学习只是 y=mx+b 的破解。'

当然,这是一种简化,因为机器学习来自许多学科,如计算机科学、神经科学、数学、科学方法等。但问题是,媒体充斥着各种措辞,让人感觉我们正处于被人工智能生物接管的直接危险之中。

事实是,我们不是。但是,在机器学习的产生过程中,还有许多其他经常被忽视的潜在问题。fast.ai 的联合创始人雷切尔·托马斯(Rachel Thomas)提到,她和其他机器学习专家都认为,“关于人工智能意识的炒作被夸大了”,但“其他(社会)危害没有得到足够的重视”。今天,我想详细阐述雷切尔提出的这些社会危害之一:“人工智能编码并放大了偏见”。

机器学习的真正危害:垃圾进垃圾出

这其中最令人不安的方面——人工智能放大偏见的想法——是机器学习在社会过程自动化中的承诺是保持最高程度的中立。众所周知,医生在医疗诊断中可能持有偏见,陪审团在刑事司法判决中可能持有偏见。机器学习应该理想地综合记录中的大量变量,并提供中立的评估。

“但事实是,机器学习程序在很大程度上延续了我们的偏见。所以不是法官对非裔美国人有偏见,而是一个机器人。”——布莱恩·雷斯尼克

我们期望模型是客观公正的;正是这种幻灭的客观立场,使得整个磨难感觉阴险,尤其令人失望。

那么这是怎么发生的呢?

图一.(来源)

“垃圾输入垃圾输出”是一个众所周知的计算机科学公理,这意味着低质量的输入产生低质量的输出。通常,“非垃圾”输入是指干净、准确、标记良好的训练输入。然而,我们现在可以看到,我们的垃圾输入很可能是我们社会过去行为的完美、准确的表现。机器学习的真正危险与机器人意识实体关系不大,而与另一种类型的意识实体——人类——关系更大。当有社会偏见的数据被用来训练机器学习模型时,潜在的结果是一个歧视性的机器学习模型,它预测了我们旨在消除的社会偏见。

精度更高!=更好的社会成果

这个问题从预测进一步延伸到永久化;我们创造了一种强化循环。

例如,假设一个企业主想要预测他们的哪些客户可能会购买某些产品,这样他们就可以提供一个特殊的捆绑包。他们继续要求数据科学家建立一个预测算法,并使用它向特定群体做广告。在这一点上,该模型不仅仅是预测哪些客户会购买,而是在强化它。

虽然在这个例子中是无害的,但这可能导致对社会进程有害的结果。这正是导致这些意想不到的标题:

图二。作者照片。文末引文。

同样,如果我们的应用是针对医疗保健的,目的是基于先前的数据来预测哪一组应该得到更多的关注,我们不仅仅是为了优化而预测,我们现在正在积极地放大和延续先前的差异。

那么,我们废除机器学习是因为我们知道它会导致世界毁灭吗?

简而言之,没有。但也许我们应该重新想象我们练习机器学习的方式。如前所述,当我刚开始练习机器学习时,对人工智能发展意识的过度夸张的司空见惯的恐惧开始有点迁就我。我认为可能发生的最糟糕的事情是像我们拥有的任何工具一样被滥用,尽管滥用可能在物理工具上比在数字工具上更明显。

然而,YouTube 上 Alter 的短片“屠宰场机器人”引发了许多关于伦理和自主人工智能可能存在的危险的思考。“生命未来研究所”创作这部电影的主要原因是为了传达以下思想: “因为自主武器不需要人类的单独监督,它们是潜在的可扩展大规模杀伤性武器——少数人可以发射无限数量的武器。”

在这部短片的背景下,无人机被用于伤害。然而,使用人工智能系统会产生灾难性的意外后果吗?如果我们在没有任何监督预防措施的情况下创建 AI 来优化一个松散定义的目标和松散定义的约束,并意识到它超出了我们的预期,会发生什么?如果我们创建了一个系统,其初衷是用于社会公益,但结果却是灾难性的、不可逆转的损害,那该怎么办?意识的缺失变得无关紧要,但并没有最小化潜在的伤害。

然后,我开始偶然发现挑战当前人工智能标准模型的相关资源,并解决这些问题,这最终导致了这篇博文的合成。

逆向强化学习

第一个是斯图尔特·罗素的“人类兼容”,这表明人工智能的标准模型是有问题的,因为缺乏干预。在当前的标准模型中,我们专注于优化我们最初设置的指标,而没有任何人在回路中的监督。Russell 用一种假设的情况来挑战这一点,即我们在一段时间后意识到我们最初目标的结果并不完全是我们想要的。

相反,斯图尔特提出,与其使用我们的人工智能系统来优化一个固定的目标,不如我们灵活地创建它们,以适应我们潜在的摇摆不定的目标。这意味着在算法的不确定性水平上编程,它不能完全确定它知道我们的目标,所以它会故意问它是否需要重定向或关闭。这被称为“逆向强化学习”

下面你可以看到普通强化学习目标和逆向强化学习目标之间的区别:

图三。强化学习 vs 逆向强化学习(来源

传统的强化学习的目标是在给定的情况下找到最佳的行为或行动来最大化回报。例如,在自动驾驶汽车领域,模型保持在道路中心的每一个时刻都会收到一个小奖励,如果它闯红灯,则会收到一个负奖励。该模型在环境中移动,试图找到最佳的行动路线,以获得最大的回报。因此,强化学习模型被输入奖励函数,并试图找到最佳行为。

但是,有时候奖励作用并不明显。为了说明这一点,反向强化学习被输入一组行为,并试图找到最佳的奖励函数。鉴于这些行为,人类真正想要的是什么?IRL 的最初目标是在给定行为是最有利行为的假设下揭示奖励函数。然而,我们知道情况并非总是如此。按照这一逻辑,这一过程可能有助于我们揭示人类存在偏见的方式,这反过来将允许我们通过意识来纠正未来的错误。

有偏比较算法

另一个相关和及时的资源是线性离题的插曲“种族主义,刑事司法系统和数据科学”。在这一集中,凯蒂和本机智地讨论了 COMPAS,这是一种代表替代制裁的矫正罪犯管理概况的算法。在美国一些州,法官在量刑时使用这种算法来预测被告再次犯罪的可能性是合法的。

图四。J. Dressel 等人,科学进展,EAAO55850,2018 ( 来源)

然而,各种研究挑战了算法的准确性,发现种族歧视的结果尽管缺乏种族作为输入。线性离题探讨了种族偏见结果出现的潜在原因,并以一系列挥之不去的强大的,发人深省的伦理问题结束:

一个算法的合理输入是什么?当你考虑整体背景时,如果一个算法引入了不公平,那么它是否公平?投入来自哪里?输出将在什么环境中部署?当将算法插入到已经复杂且具有挑战性的流程中时,我们是否花费了足够的时间来检查上下文?我们试图自动化什么,我们真的想自动化它吗?

凯蒂在这一集的结尾巧妙地提出的最后一串问题是非常紧迫的问题,给人留下了持久的印象,因为我是机器学习对社会有益的巨大支持者。我确信,这些考虑将成为我打算用算法解决的每个复杂的、数据驱动的社会问题的一个组成部分。

最后的想法和反思

这些模型在很大程度上伤害了许多人,同时提供了一种虚假的安全感和中立感,但也许我们可以从中获得的是承认我们的数据中不可否认的代表性不足。当算法显然不适用于某些少数群体时,这些群体的数据缺乏是很明显的。

偏见是我们的责任,至少要认识到,这样我们才能推动减少偏见的举措。

此外,在“我们该如何应对人工智能中的偏见”中,James Manyika、Jake Silberg 和 Brittany Presten 提出了管理团队最大限度提高人工智能公平性的六种方式:

  1. 保持对人工智能和伦理的最新研究。
  2. 建立一个在部署人工智能时可以减少偏差的流程
  3. 围绕潜在的人类偏见进行基于事实的对话
  4. 探索人类和机器可以整合起来对抗偏见的方法
  5. 在偏见研究方面投入更多努力,以推动该领域的发展
  6. 通过教育和指导投资于人工智能领域的多样化

总的来说,我对机器学习帮助人类决策的能力感到非常鼓舞。既然我们意识到了数据中的偏差,我们就有责任采取措施来减轻这些偏差,这样我们的算法才能真正提供一个中立的评估。

鉴于这些不幸的事件,我希望在未来几年,会有更多关于人工智能监管的对话。已经有一些很棒的组织,如 AI Now、等,致力于围绕理解人工智能的社会影响进行研究。现在,我们有责任继续这一对话,走向一个更加透明和公正的社会。

图五、AI Now 首页(来源)

用于图二的物品:

  1. 人工智能把人送进监狱——而且做错了
  2. 运行我们生活的算法是种族主义和性别歧视的。见见试图修理她们的女人
  3. 谷歌在其视觉人工智能产生种族主义结果后道歉
  4. 医疗保健算法存在偏差,结果可能是致命的
  5. 自动驾驶汽车更容易撞上黑人
  6. 为什么亚马逊的招聘人工智能对女性有偏见一点也不奇怪

我们的问答机器人& Python 语言的 WordCloud

原文:https://towardsdatascience.com/our-q-a-bot-wordcloud-in-python-c8e7593a3256?source=collection_archive---------66-----------------------

创建首个个性化单词云的 whistlestop 指南

Candide 是一个植物爱好者社区。我们的用户经常会来到我们的 feed,询问关于他们的植物的问题。

上个月,我们推出了问答机器人(Q&A Bot ):这是一个试图回答用户提出的任何问题的系统,利用我们文章中的智慧和应用程序中更广泛的内容。

我对我们收到的问题的内容进行了分析,并使用 Python 的 WordCloud 包创建了一个可视化的单词云。我不会详细说明代码是如何工作的,但是如果你想看这个,请在下面评论,我很乐意写一个关于这个主题的教程。

因此,准备好大约 2500 个问题,由 1000 多名 Candide 用户通过问答机器人提交给我们,让我们开始吧!

首先,我们导入将要使用的库:numpypandaswordcloudmatplotlib.pyplot

import numpy as np
import pandas as pd
from wordcloud import WordCloud, STOPWORDS

import matplotlib.pyplot as plt

然后,我们将数据加载到熊猫数据框架中。

# Dataframe
df = pd.read_csv("questions.csv", index_col=0)

接下来,我们将所有提交的问题合并到一个文本中,并确保全部是小写字母,如下所示:

# Combine all questions into one text
text = " ".join(question for question in df.text)
# Make sure all words are lower case
text = text.lower()

我们现在准备使用cloudwordmatplotlib来生成和绘制我们的单词云,如下所示:

# Generate a wordcloud
stopwords = STOPWORDS
wordcloud = WordCloud(background_color="white", max_words=1000, stopwords=stopwords)
wordcloud.generate(text)

# Plot
plt.figure(figsize=[20, 10])
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis("off")
plt.show()

瞧啊!结果看起来像这样:

Word Cloud,使用提交给我们问答机器人的问题

热门词汇是:植物、花和叶子🌱。没什么好惊讶的🙂!

现在,如果我们想要个性化输出,我们可能想要让这个单词云有一个特定的形状。为此,我们将使用以下机器人植物的剪影,由我的设计师同事好心提供, Kat (这毕竟是一个关于植物问题的 Q & A Bot!)

使用上面的图像和下面的代码:

# Personalised cloud of words
path = "/Users/amine/code/HackDayMay2020/robot-plant.png"
mask = np.array(Image.open(path))
wordcloud = WordCloud(background_color="white", max_words=1000, mask=mask, stopwords=stopwords)
wordcloud.generate(text)

# Plot
plt.figure(figsize=[20, 10])
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis("off")
plt.show()

我们得到了一个最终的结果,一堆单词组成了我们的机器人工厂的形状!

机器人工厂!

最后,我们不应该忘记将我们的图像保存到文件中,代码如下:

# Save to file
wordcloud.to_file("robot-plant-word-cloud.png")

在下一篇教程中,我将分析用户的问题是如何随着时间和季节变化的。如果你想让我制作一个更深入的教程来解释 wordcloud 是如何工作的,请在评论中告诉我!

参考资料和资源

  1. WordCloud for Python 文档https://github.com/amueller/word_cloud
  2. word cloud 项目的 Github 代码https://github.com/amueller/word_cloud
  3. 用 Python 生成 word cloud作者 Duong Vuhttps://www . data camp . com/community/tutorials/word cloud-Python
  4. 用 Python 生成单词云由 SumedhKadamhttps://www.geeksforgeeks.org/generating-word-cloud-python/

我们的标签

原文:https://towardsdatascience.com/our-tags-1d4f6b370db3?source=collection_archive---------18-----------------------

如果您正在寻找某个特定主题的最新内容,探索我们的标签将会很有帮助。

照片由阿尔方斯·莫拉莱斯Unsplash 拍摄

下面列出了我们最常用的标签。如果你想搜索一个特定的标签,你可以去http://towards data science . com/tagged/[tag]然后用你要找的术语替换[tag]。

您还可以通过 RSS feed 访问标签,如这里的所述。例如,您可以通过这里获得我们的“数据科学”标签的 RSS 提要:https://medium . com/feed/forward-data-science/tagged/data-science

请注意,Medium 的应用程序目前不支持标签。

数据科学

机器学习

软件工程

编程

为什么“目的证明手段是正当的?”是个错误的问题

原文:https://towardsdatascience.com/outcome-bias-versus-moral-philosophy-cb82f42c4437?source=collection_archive---------22-----------------------

结果偏差与道德哲学

在最近的一篇文章中,我写了关于结果偏差和决策分析的核心原则:

决策的质量应该仅使用决策者在做出决策时可用的信息来评估。

如果你是这个话题的新手,我推荐你看看我的温柔介绍。这篇文章是我的书呆子同伴的脚注。

道德哲学的三个主要视角

  • 结果主义:考虑后果!
  • 义务论:尽你的责任!
  • 德性伦理:要有德性!

道德宣传还是决策情报?

不要把 结果偏差 误解为反对结果主义者 道德观的宣传。

如果你一直被结果偏差的平淡解释所困扰,这种解释反复无常地使用“意图”“结果”,那么你会认为这是有道理的

事实上,结果偏差的心理学现象并不偏爱现代道德哲学的主题,也没有对美德伦理学或功利主义等领域做出陈述。

那么,为什么会有误解呢?

图片:来源

混乱的根源

  1. 认为道德哲学的核心问题是“结果证明了手段的正当性吗?”这是错误的
  2. 认为“决定和结果”“意图和结果”的同义词是错误的。

如果你同时犯了这两个错误,你可能会形成这样的印象:一个毫无争议的决策建议(避免结果偏差)侵犯了哲学中的公开问题。**

"目的证明手段是正当的吗?"

啊,语言;好困惑!尤其是对于老式的精粹短语。原来“目的”有多重含义,包括“结果”和“目标”如果你习惯于将“结果”理解为“结果”,那么你可能会发现在那里添加一个额外的单词是有帮助的...

现代结果主义与结果无关

结果主义的哲学观点不是通过一个行为的实际后果(结果)来判断其道德性,而是通过做出决定时的可能的/可预见的/预期的(取决于你最喜欢的口味)结果来判断,比如在中,“预期的结果证明了手段的正当性。”

结果偏差理论不是对结果主义的批评。

技术细节:**哲学为了完整保留了一个动物园,里面有各种各样的-主义,包括多种结果主义(其中最著名的是古典功利主义)。哲学家们普遍批评为荒谬的是一种叫做“实际结果主义”的东西科学家们会对这一特殊品种提出异议,但幸运的是我们不必这样做:哲学家们代表我们认为这是荒谬的。如果我们把这个亚种从我们的可行主义列表中移除,那么现代结果主义者可以从中选择的口味还有很多。我这里指的就是这个系列。

现代意向性也不是关于结果的

一个意向性的哲学观点(例如各种各样的美德伦理学义务论中的一种)从与美德或责任等概念的一致性来判断一个决定的道德性,例如,“手段比预期的结果更重要。”

结果偏差理论不是对意向性的批判。

转移注意力的例子:偷窃是错的吗?

“如果你在试图偷一个溺水的人的手表时不小心救了他,这是道德行为吗?”

我看到这个例子流传开来,博客上说结果主义者会说,而意向主义者会说。就我的理解,那是一种误解。

结果主义者不会宽恕那种快乐的意外作为一种道德行为。(也没有什么迫使他们一起分析这两个问题来判断道德。营救溺水者可以被视为与盗窃完全不同的道德问题。)大多数结果主义的信徒会谴责这种行为,如果小偷想通过偷窃使世界其他地方变得更糟的话。

但是,如果小偷想救一个饥饿的孩子,而这个孩子除了典当手表之外,没有别的办法养活,那该怎么办呢?那些有意向主义倾向的人可能会回答说“偷窃行为在道德上总是错误的,无论如何”而那些有结果主义倾向的人可能不同意。当你遇到由谁来设定预期的问题时,事情就变得棘手了:如果小偷找不到任何其他方式来实现更好的预期结果,但社会可能会不敢苟同呢?社会是根据 T4 当时知道的来判断,还是根据小偷知道的来判断?被告知是一种责任吗?抓住一个朋友,开始辩论吧!开放式问题的开放是有原因的。

掌握好时态

如果你总结了可行的现代 -isms-ologies ,一定要掌握好时态。所有这些都是关于现在时态的道德评价——只使用决策/行动时已知的东西——这正是决策科学喜欢的方式。

  • 结果主义:我行动的结果会是什么?
  • 义务论:我的行为符合我的职责吗?
  • 美德伦理:我的行为是由美德驱动的吗?

一旦你用适当的时态思考,如何正确对待道德决策在哲学上是一个未解决的问题,我不会去解决它。(不过,你所在国家的法律通常会代表你做出选择。)

道德哲学:“预期的结果证明了手段的正当性吗?”

决策科学说什么

只要你不谴责决策者没有使用水晶球,决策科学就不会从技术上反对你的道德观点。

无论你选择哪种思想流派(或它们的混合),决策科学家都会鼓励你根据当时已知的情况来分析情况。例如,如果你最喜欢道义论,那么如果你根据一个人目前的职责而不是他们在行动时的职责进行评估,我们会感到惊讶。

决策科学:“不要谴责决策者没有使用水晶球。”

当我们告诉你避免结果偏差时,我们指的是判断决策者的能力并形成有效的决策策略。我们不争论道德,因为那是不同学科的范围。

现在是完全不同的东西…

感谢阅读!如果你在这里玩得开心,并且对人工智能感兴趣,这里有一个初学者友好的介绍供你娱乐:

在这里欣赏整个课程播放列表:bit.ly/machinefriend

与凯西·科兹尔科夫联系

让我们做朋友吧!你可以在 TwitterYouTubeLinkedIn 上找到我。有兴趣让我在你的活动上发言吗?用这个表格联系。

异常值检测——理论、可视化和代码

原文:https://towardsdatascience.com/outlier-detection-theory-visualizations-and-code-a4fd39de540c?source=collection_archive---------18-----------------------

什么是离群点检测?

离群点检测也称为异常检测、噪声检测、偏差检测或异常挖掘。没有普遍接受的定义。(Grubbs,1969)的早期定义是:异常值,是指明显偏离样本中其他成员的值。(Barnett 和 Lewis,1994)最近的定义是:

似乎与该组数据的其余部分不一致的观察结果。

原因

直接从这篇优秀的文章来看,离群值最常见的原因有:

  • 人为错误 —数据录入错误
  • 仪器误差 —测量误差
  • 实验错误 —数据提取或实验计划/执行错误
  • 故意的 —为测试检测方法而制造的虚拟异常值
  • 数据处理错误 —数据操作或数据集意外突变
  • 采样错误 —从错误的或各种来源提取或混合数据
  • 自然 —不是错误,数据中的新奇

应用程序

根据(Hodge,V.J .和 Austin,j .,2014)利用异常值检测的应用程序列表如下:

  • 欺诈检测 —检测信用卡欺诈申请,
    陈述利益或检测信用卡或手机的欺诈使用。
  • 贷款申请处理 —检测欺诈申请或
    潜在的问题客户。
  • 入侵检测 —检测计算机
    网络中的未授权访问。
  • 活动监控 —通过监控
    电话活动或股票市场中的可疑交易来检测手机欺诈。
  • 网络性能 —监控计算机
    网络的性能,例如,检测网络瓶颈。
  • 故障诊断 —监测过程,以检测
    航天飞机上的电机、
    发电机、管道或航天仪器的故障。
  • 结构缺陷检测 —监控生产线以
    检测有缺陷的生产运行,例如有裂缝的横梁。
  • 卫星图像分析——识别新颖特征或误分类特征
  • 检测图像中的新奇事物 —用于机器人或监视
    系统。
  • 运动分割 —检测独立于背景运动的图像特征。
  • 时序监控 —监控安全关键应用
    ,如钻孔或高速铣削。
  • 医疗状况监测 —如心率监测器。
  • 药物研究 —识别新的分子结构。
  • 检测文本中的新颖性 —检测新闻故事的开始,用于
    话题检测和跟踪,或用于交易者确定股票、商品、外汇交易故事,表现优于或劣于
    商品。
  • 检测数据库中的意外条目—用于数据挖掘,以
    检测错误、欺诈或有效但意外的条目。
  • 在训练数据集中检测标签错误的数据

方法

有 3 种异常值检测方法:

1.在没有数据先验知识的情况下确定异常值。这类似于无监督聚类。
2。模拟正常和异常。这类似于监督分类,需要标记数据。
3。只模拟常态。这被称为新颖性检测,类似于半监督识别。它需要属于正常类的标记数据。

我会先处理接近。这是最常见的情况。大多数数据集没有关于异常值的标记数据。

分类学

根据 Ben-Gal I .(2005)离群点检测方法可分为单变量方法和多变量方法。离群点检测方法的另一个基本分类是在参数(统计)方法和非参数方法之间,参数(统计)方法假设观察值的已知基本分布,非参数方法是无模型的,如基于距离的方法和聚类技术。

资料组

我将使用 Pokemon 数据集,并对 2 列 ['HP ',' Speed'] 执行异常值检测。这是一个有趣的数据集,它的观察值很少,计算速度很快,很多人都很熟悉它。仅选择两列仅用于可视化目的(二维)。观察散点图中的结果。这些方法可以在多维中缩放。

离群点检测算法

将遵循的算法是:

  • 隔离林
  • 扩展隔离林
  • 局部异常因素
  • 数据库扫描
  • 一班 SVM
  • 以上的合奏

代码和可视化

这篇文章的代码在我的 GitHub 上。为了保持简洁,我不会在文章中包含代码。

读取数据后,前五行是这样的:

隔离森林

  • 隔离森林和任何树集合方法一样,是建立在决策树的基础上的。在这些树中,通过首先随机选择一个特征,然后在所选特征的最小值和最大值之间选择一个随机分割值来创建分区。
  • 为了在树中创建分支,首先选择一个随机特征。然后,为该特征选择一个随机分割值(在最小值和最大值之间)。如果给定的观察值具有该特征的较低值,则所选的观察值遵循左分支,否则遵循右分支。这个过程一直持续到孤立一个点或达到指定的最大深度。
  • 原则上,异常值比常规观测值更少出现,并且在值方面与常规观测值不同(在特征空间中,它们离常规观测值更远)。这就是为什么通过使用这种随机划分,它们应该被识别为更靠近树的根(更短的平均路径长度,即,观察在树中从根到终端节点必须经过的边的数量),需要更少的分裂。

关于隔离林的更多信息:

我将使用 sklearn 库中的 IsolationForest 。在定义算法时,有一个称为污染的重要参数。它是算法认为是异常值的观察值的百分比。我设为等于 2% 。我们将 X (2 个特征 HP 和速度)拟合到算法中,并使用 fit_predict 在 X 上也使用它。这产生了简单的异常值(-1 是异常值,1 是内部值)。我们还可以使用函数 decision_function 来获得 Isolation Forest 给每个样本的分数。

运行该算法后,发现了 785 个内点和 15 个外点。

让我们画出结果。

或者,我们可以绘制纯分数,而不仅仅是离群值/内部值。

从视觉上看,这 15 个异常值似乎是合法的,并且在数据点的主要斑点之外。

我们可以做一个更高级的可视化,除了内部和外部显示隔离森林的决策边界。

颜色越深,该区域的异常值越大。

最后,我们可以看到分数的分布。

这种分布很重要,有助于我们更好地确定我们案例中正确的污染值。如果我们改变污染值,isoletionForest_scores 将改变,但分布将保持不变。该算法将调整分布图中异常值的临界值。

扩展隔离林

隔离林有一个缺点:它的决策边界要么是垂直的,要么是水平的。因为线只能平行于轴,所以存在包含许多分支切割和仅一些或单个观察值的区域,这导致一些观察值的不正确异常分数。

扩展隔离林选择 1)分支切割的随机斜率和 2)从训练数据的可用值范围中选择的随机截距。这些项实际上是线性回归线。

有关扩展隔离林的更多信息:

sklearn 中没有实现扩展隔离林,但是在 Github 上有

我们必须将它的分数乘以-1,以便与其他算法的分数具有相同的形式。

扩展隔离林不提供普通的离群值和内联值(as -11)。我们只是通过将分数中最低的 2%作为异常值来创建它们。这个算法的分数和基本的隔离林是不一样的。这里所有的分数都是负数。

如果你检查代码,你可能会注意到我在这个图中使用了 cmap=plt.cm.Blues ,而不是前面的 cmap=plt.cm.Blues_r (反向)。我们可以看到不同异常区域之间的过渡更加平滑。

该算法发现了 16 个异常值。

局部异常因素

  • LOF 是一种计算方法,通过查看某一点的相邻点来找出其密度,并在稍后将其与其他点的密度进行比较。
  • 点的 LOF 表示该点相对于其相邻点的密度。如果一个点的密度远小于其相邻点(≫1 附近)的密度,则该点远离密集区域,因此是异常值。
  • 这是有用的,因为如果整个区域不是数据点的全局空间中的外围区域,则并非所有方法都不会识别相对于附近的点簇为异常值的点(局部异常值)。

点 P 的 LOF 会有一个:

  • 高值 if → P 远离其邻居且其邻居具有高密度(靠近其邻居)(LOF =(高距离和)x(高密度和)=高值)
  • 如果-> P 远离其邻居,但其邻居的密度较低,则值较低(LOF =(高总和)x(低总和)=中间值)
  • 如果-> P 靠近其邻居且其邻居的密度较低,则值较低(LOF =(低总和)x(低总和)=低值)

关于局部异常因素的更多信息:

运行 sklearn 库中的代码后,它确定了 21 个局部异常值。

我们可以创建另一个有趣的图,其中局部异常值越大,其周围的圆圈就越大。

这个算法和之前的有很大不同。它也能发现异常值,但方式不同。它发现局部异常值。你是否注意到在图的主体内有异常值?

基于密度的噪声应用空间聚类

一种经典的聚类算法,其工作原理如下:

  • 随机选择一个尚未分配给聚类或指定为异常值的点。通过查看在ε距离内其周围是否至少有 min_samples 个点来确定其是否为核心点。
  • 创建该核心点及其ε距离内所有点(所有可直接到达的点)的聚类。
  • 找到聚类中每个点的ε距离内的所有点,并将它们添加到聚类中。找到所有新添加的点的ε距离内的所有点,并将这些点添加到聚类中。冲洗并重复。(即执行“邻域跳跃”以找到所有密度可达的点并将它们添加到聚类中)。

对于我们的示例,在调整了ε参数后,它发现了 13 个异常值。

该算法不提供异常值强度的分数。

一级 SVM

  • 单类分类器适用于仅包含正常类样本的训练数据集,但也可用于所有数据。一旦准备好,该模型被用于将新的例子分类为正常或不正常。
  • 与标准 SVM 的主要区别在于,它是以无监督的方式拟合的,并且不像 c 那样提供用于调整余量的正常超参数。相反,它提供了一个超参数“nu ”,该参数控制支持向量的灵敏度,并且应该调整到数据中异常值的近似比率。

更多关于一级 SVM

运行算法后,我得到以下散点图

在这个数据里好像行不通。找不到更好的。对于其他 nu 值,离群值比内值多。如果有人有任何想法,请分享,我会更新!

全体

最后,让我们将这 5 种算法结合起来,形成一个健壮的算法。我将简单地添加离群列,离群列为-1,内联列为 1

我不会用一等的 SVM。

将结果相加后,我们得到:

data['outliers_sum'].value_counts()value  count 
    4    770
    2     15
   -4      7
   -2      7
    0      1

outliers_sum=4 的观察值意味着所有 4 个算法都同意它是一个内点,而对于完全的外点一致性,和是-4。

我们先来看看对于哪 7 个口袋妖怪所有算法都同意离群值。我们也可以将 sum=4 的观察值作为内值,其余的作为界外值。这取决于我们。

data.loc[data[‘outliers_sum’]==-4][‘Name’]121              Chansey
155              Snorlax
217            Wobbuffet
261              Blissey
313              Slaking
431    DeoxysSpeed Forme
495             Munchlax

个别图片取自 pokemondb

这些是我们在惠普和速度上的异常值!

感谢阅读!

用 RNN 自动编码器检测异常值

原文:https://towardsdatascience.com/outlier-detection-with-rnn-autoencoders-b82e2c230ed9?source=collection_archive---------27-----------------------

利用重构自动编码器模型检测时间序列数据中的异常。

由作者生成的图像。

注来自《走向数据科学》的编辑: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

TL DR:Historic-Crypto PackageCode。**

什么是异常?

异常值,通常被称为离群值,是指不符合数据序列总体行为的数据点、数据序列或数据模式。因此,异常检测的任务是检测与更广泛的数据中存在的模式不一致的数据点或序列。

异常数据的有效检测和删除可以为许多业务功能提供非常有用的洞察力,例如检测网站中嵌入的断开链接、互联网流量峰值或股票价格的剧烈变化。将这些现象标记为异常值,或制定预先计划的响应可以节省企业的时间和金钱。

异常的类型?

异常数据通常可以分为三个不同的类别,时间变化电平移动 。**

加性异常值 表现为数值的突然大幅增加或减少,可由外源或内源因素驱动。附加异常值的例子可能是由于在电视上出现而导致的网站流量的大幅增加(外生),或者由于强劲的季度表现而导致的股票交易量的短期增加(内生)。

时间变化 的特点是序列较短,不符合数据中更广泛的趋势。例如,如果网站服务器崩溃,对于一系列数据点,网站流量将降至零,直到服务器重启,此时正常流量将恢复。

电平转换 是大宗商品市场的常见现象,因为对电力的高需求与恶劣的天气条件有着内在联系。因此,由于天气驱动的需求曲线和可再生能源发电曲线的变化,可以观察到夏季和冬季电价之间的“水平变化”。

什么是自动编码器?

自动编码器是设计用来学习给定输入的低维表示的神经网络。自动编码器通常由两个组件组成:一个 编码器 ,它学习将输入数据映射到更低维度的表示;一个 解码器 ,它学习将表示映射回输入数据。

由于这种架构,编码器网络迭代地学习有效的数据压缩函数,该函数将数据映射到较低维度的表示。在训练之后,解码器能够成功地重建原始输入数据,因为重建误差(输入和由解码器产生的重建输出之间的差)是整个训练过程的目标函数。

实施

现在我们已经理解了自动编码器模型的底层架构,我们可以开始实现这个模型了。

第一步是安装我们将使用的库、包和模块:

其次,我们需要获得一些数据进行分析。本文使用 Historic-Crypto 包获取从‘2013–06–06’到现在的历史比特币(‘BTC’)数据。下面的代码还生成每日比特币回报和当天价格波动,然后删除任何丢失的数据行并返回数据帧的前 5 行。

现在我们已经获得了一些数据,我们应该直观地扫描每个序列,寻找潜在的异常值。下面的plot_dates_values函数支持数据框中包含的每个系列的迭代绘图。

我们现在可以迭代调用上述函数,为比特币的交易量、收盘价、开盘价、波动率和回报率生成 Plotly 图表。

由作者生成的图像。

值得注意的是,2020 年交易量出现了大量峰值,调查这些峰值是异常的还是更广泛系列的指示可能是有用的。

由作者生成的图像。

2018 年收盘价存在明显的飙升,随后暴跌至技术支持水平。然而,积极的趋势广泛存在于所有数据中。

由作者生成的图像。

每日开盘价遵循与上述收盘价相似的模式。

由作者生成的图像。

价格波动在 2018 年和 2020 年都出现了一些明显的峰值。因此,我们可以调查这些波动峰值是否被自动编码器模型视为异常。

由作者生成的图像。

由于回报序列的随机性质,我们选择测试比特币每日交易量中的异常值,如Volume所示。

因此,我们可以开始自动编码器模型的数据预处理。数据预处理的第一步是确定训练数据和测试数据之间的适当拆分。下面概述的generate_train_test_split功能支持按日期拆分培训和测试数据。在调用下面的函数时,生成两个数据帧,即training_datatesting_data作为全局变量。

为了提高模型的准确性,我们可以“标准化”或缩放数据。该函数缩放上面生成的training_data数据帧,保存training_meantraining_std用于以后标准化测试数据。

注: 使用相同的尺度对训练和测试数据进行尺度转换是很重要的,否则尺度的差异会产生可解释性问题和模型不一致。

正如我们在上面调用的normalise_training_values函数,我们现在有一个包含标准化训练数据的 numpy 数组,称为training_values,我们已经将training_meantraining_std存储为用于标准化测试集的全局变量。

我们现在可以开始生成一系列可用于训练自动编码器模型的序列。我们定义该模型将被提供 30 个先前的观察值,提供形状的 3D 训练数据(2004,30,1):

现在我们已经完成了训练数据处理,我们可以定义自动编码器模型,然后根据训练数据拟合该模型。define_model函数利用训练数据形状来定义适当的模型,返回自动编码器模型和自动编码器模型的摘要。

随后,model_fit函数在内部调用define_model函数,然后向模型提供epochsbatch_sizevalidation_loss参数。然后调用这个函数,开始模型训练过程。

一旦对模型进行了训练,绘制训练和验证损失曲线以了解模型是否存在偏差(欠拟合)或方差(过拟合)是很重要的。这可以通过调用下面的plot_training_validation_loss函数来观察。

由作者生成的图像。

值得注意的是,训练和验证损失曲线在整个图表中趋于一致,验证损失仍然略大于训练损失。给定形状和相对误差,我们可以确定自动编码器模型没有欠拟合或过拟合。

现在,我们可以定义重建误差,这是自动编码器模型的核心原则之一。重建误差表示为train_mae_loss,重建误差阈值确定为train_mae_loss的最大值。因此,当计算测试误差时,任何大于最大值train_mae_loss的值都可以被认为是异常值。

由作者生成的图像。

上面,我们将training_meantraining_std保存为全局变量,以便使用它们来缩放测试数据。我们现在定义normalise_testing_values函数来缩放测试数据。

随后,在testing_dataVolume列调用该函数。因此,test_value被具体化为一个 numpy 数组。

接下来,定义generate_testing_loss函数,计算重建数据和测试数据之间的差异。如果任何值大于train_mae_loss的最大值,它们被存储在全局异常列表中。

此外,还介绍了试验 MAE 损失的分布,以便与训练 MAE 损失进行直接比较。

由作者生成的图像。

最后,异常值如下图所示。

由自动编码器模型表征的异常数据用橙色表示,而符合的数据用蓝色表示。

由作者生成的图像。

我们可以看到,2020 年很大一部分比特币交易量数据被认为是异常的——可能是由于新冠肺炎推动的零售交易活动增加?

尝试 Autoencoder 参数和数据集——看看你能否在比特币收盘价中找到任何异常——或者使用historical-Crypto库下载不同的加密货币!

编码快乐!

离群值——为什么它很重要?

原文:https://towardsdatascience.com/outlier-why-is-it-important-af58adbefecc?source=collection_archive---------16-----------------------

极端数据的故事

威尔·梅尔斯在 Unsplash 上拍照

什么是离群值?根据维基百科的说法,离群值是数据集中与其他数据或观察结果显著不同的数据点。就看上图,有一系列的瓶子,但是有一个颜色不一样。这个瓶子就是我们所说的异常值。

异常值本质上不同于噪声。异常值是与其他数据相比明显不同的数据,而噪声是随机误差或方差。离群值是数据的一部分,但噪声只是一个随机误差(可能被错误标记或出错,甚至丢失数据)。

许多参数统计,如均值、相关性,以及基于这些的每个统计对异常值都很敏感。由于标准统计程序或模型的假设,如线性回归和方差分析也是基于参数统计的,因此异常值会打乱您的分析。

那么,数据集中的离群值呢?我们是如何分类的?我们如何检测它?为什么是必不可少的?如何处理异常值?让我们开始吧。

离群分类

通常,离群值可以分为两类:

  • 单变量异常值。这是一个出现在单个变量中的异常值,或者换句话说,是单个列中的异常值。下面一个例子来看看。

在上面的薪金列中,存在一个异常值(5000)。这个异常值只出现在薪金列中,这就是为什么这个异常值被归类为单变量异常值。

  • 多元异常值。这是发生在两个(双变量)或多个(多变量)变量的联合组合中的异常值,与单变量异常值相反。

作者创建的图像

例如,上图是工资和年龄变量之间的散点图。在该图中,两个变量的关联存在两个二元异常值。在单个变量中,数据可能不是异常值,但当它与另一个变量相关联时,可能会出现异常值。这就是我们所说的多元异常值。

多元异常值只存在于 n 维空间中(n 个特征),其中 n 大于 1。当 n 数大于 3 时,我们可能很难想象或想象它。这就是为什么我们需要训练一个模型来为我们做这件事。

根据环境的不同,异常值也可以分为三种不同的类型:

  • 全局离群值(点离群值)。这是一个单独的数据点,相对于其他数据而言,被视为异常值。以上多元异常值图中的异常值可视为全局异常值。
  • 语境离群值。这个异常值不同于另一个异常值,因为我们需要领域知识或上下文理解。我们可以将上下文异常值定义为基于所选上下文显著不同的数据点。例如,你认为加拿大多伦多 12 度的气温会被认为是异常值吗?这取决于季节(冬天或夏天)。可能不会在夏天,但会在冬天。
  • 集体离群。尽管单个数据可能不是异常值,但相对于整个数据集的数据集合(子集)明显不同,这就是异常值。下面我们来看一个例子。

作者创建的图像

单独的数据可能不是离群值,但作为一个整体,它会成为离群值。这就是我们所说的集体离群

检测异常值

一般来说,没有一种方法可以说这种技术是检测异常值的最佳方法。重要的是我们理解为什么我们想要找到异常值。因此,检测异常值的上下文比技术本身更重要。此外,你必须有一个清晰的背景来区分噪音和异常值,因为有时人们会把事情搞混。

另一个我们必须要问的问题,是单变量/多变量离群值吗?变量分布是否满足参数/非参数条件?

在这篇文章中,我将只展示一些经常使用的方法,而没有更深入的理解,因为我在这篇文章中的目的是说明为什么离群值是重要的。

一些重要的技术包括:

还有很多技术,但就像我之前说的。没有一种技术是检测异常值的最佳技术。我们必须分析结果,而不是依赖技术本身。

异常值重要性

我们已经知道异常值是一个极端的数据或与其他数据有显著差异的数据,但为什么它很重要呢?

一个原因正如我上面解释的;许多统计过程都会受到异常值的影响。由于异常值的存在,这些方法的统计功效会降低;因此,结果不可靠。那么,删除异常值是否会更好?如果你只关心统计结果,那么移除异常值可能是一个选择,但是在我们放弃它之前,我们仍然需要问几个问题。

  • 异常值是因为测量错误还是输入错误?—那么它就是一个噪声,应该被丢弃(或者改变,如果你知道数据的真正价值)
  • 异常值不会改变结果,但会影响假设吗?在这种情况下,你可以丢弃离群值,也可以不丢弃。看看下面的例子,不管有没有异常值,回归线仍然保持不变。

作者创建的图像

  • 异常值会影响统计结果和假设吗?在这种情况下,我们不能仅仅放弃离群值。尝试在有或没有异常值的情况下运行分析,看看结果如何。让我们看看下面的例子;如果我们去掉异常值,回归线就会移动。这个异常值肯定是数据的一部分,需要一个合理的结果来丢弃它。

作者创建的图像

  • 离群值是否产生了显著的关联?如果是这样,明智的做法是丢弃异常值。下面我们来看一个例子;数据点之间肯定没有关系。有了离群值,就创建了关联。这意味着回归系数不能真实地描述两个变量之间的关系。

作者创建的图像

很明显,从统计学的角度来看,有一些排除异常值的建议。如果没有,可以选择转换数据以获取高数值或使用不同的模型。

这些“异常值解决方案”的问题是,它们也会导致问题——有偏差的参数估计和权重不足或有效值剔除。

我们需要记住什么;并非所有的离群值都一样。有些影响很大,有些则完全没有。有些是有效且重要的数据值。有些仅仅是错误或噪音。

因此,我不会给出任何建议,而是花些时间搞清楚几件事:

  1. 为什么要找出离群值?您可能想要查看异常值,因为您对异常感兴趣。想想你的问题是什么。
  2. 异常值是否“实际上”导致了结果、影响或假设的任何问题?
  3. 离群值从何而来?这可能需要深入的分析和领域专业知识。此外,你不能总是告诉它从哪里来,但尝试考虑不同的可能性,因为它可以帮助告知最佳的前进方式。

结论

无论你采取哪种方法,你都需要了解你的数据并做好你的研究。你也可以尝试不同的方法,看看哪种方法更有理论意义,更适合回答你的问题。我的建议是花点时间做离群点研究。

如果你喜欢我的内容,并想获得更多关于数据或作为数据科学家的日常生活的深入知识,请考虑在这里订阅我的时事通讯。

如果您没有订阅为中型会员,请考虑通过我的推荐订阅。

R 中的异常值检测

原文:https://towardsdatascience.com/outliers-detection-in-r-6c835f14e554?source=collection_archive---------17-----------------------

了解如何通过描述性统计、Hampel 过滤器、Grubbs、Dixon 和 Rosner 异常值测试来检测 R 中的异常值

威尔·迈尔斯的照片

介绍

一个 离群值是一个值或一个观察值,它远离其他观察值,也就是说,一个与其他数据点显著不同的数据点。Enderlein (1987)走得更远,因为作者认为异常值是偏离其他观察值如此之多的值,人们可能会假设不同的基本采样机制。

在称之为异常值之前,必须将一个观察值与对同一现象的其他观察值进行比较。事实上,与普通人群相比,身高 200 厘米(美国身高 6 英尺 7 英寸)的人最有可能被视为异常值,但如果我们测量篮球运动员的身高,这个人可能不会被视为异常值。

异常值可能是由于观察到的现象中固有的可变性造成的。例如,在收集工资数据时,经常会出现异常值,因为有些人比其他人赚得更多。离群值也可能是由于实验、测量或编码误差引起的。例如,当对受试者的体重进行编码时,人的体重 786 kg (1733 磅)显然是错误的。她或他的体重很可能是 78.6 公斤(173 磅)或 7.86 公斤(17 磅),这取决于测量的是成人还是婴儿的体重。

因此,有时正式区分两类异常值是有意义的:(一)极端值和(二)错误。极值在统计学和哲学上更有趣,因为它们是可能的,但不太可能的答案。(感谢 Felix Kluxen 的宝贵建议。)

在本文中,我介绍了几种检测 R 中异常值的方法,从简单的技术如描述性统计(包括最小值、最大值、直方图、箱线图和百分位数)到更正式的技术如 Hampel 过滤器、Grubbs、Dixon 和 Rosner 异常值测试。

虽然在进行统计分析之前,对于是否应该从数据集中移除异常值没有严格或唯一的规则,但至少移除或估算由于实验或测量误差(如人的体重为 786 kg (1733 磅))引起的异常值是很常见的。一些统计测试要求没有异常值,以便得出合理的结论,但是并不建议在所有情况下都删除异常值,必须谨慎操作。

本文不会告诉您是否应该删除异常值(也不会告诉您是否应该用中值、平均值、众数或任何其他值对它们进行估算),但它会帮助您检测它们,以便作为第一步验证它们。在他们被验证之后,你可以选择在你的分析中排除或包括他们(这通常需要研究者方面深思熟虑的思考)。移除或保留异常值主要取决于三个因素:

  1. 你的分析和研究问题的领域/背景。在某些领域中,移除异常值是很常见的,因为它们通常是由于过程故障而出现的。在其他领域,离群值被保留是因为它们包含有价值的信息。还会发生两次分析,一次有异常值,一次没有异常值,以评估它们对结论的影响。如果结果由于一些有影响的值而发生剧烈变化,这应该提醒研究者做出过于雄心勃勃的声明。
  2. 您将要应用的测试对于异常值的存在是否稳健。例如,一个简单线性回归的斜率可能随一个异常值而显著变化,而非参数检验,如 Wilcoxon 检验通常对异常值稳健。
  3. 异常值离其他观测值有多远?一些被认为是异常值的观测值(根据下面介绍的技术)与所有其他观测值相比实际上并不极端,而其他潜在的异常值可能与其余观测值相距甚远。

来自{ggplot2}包的数据集mpg将用于说明 R 中异常值检测的不同方法,特别是我们将关注变量hwy(每加仑公路英里数)。

描述统计学

最小值和最大值

检测 R 中异常值的第一步是从一些描述性统计开始,特别是从最小值和最大值开始。

在 R 中,这可以通过summary()函数轻松完成:

dat <- ggplot2::mpg
summary(dat$hwy)##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   12.00   18.00   24.00   23.44   27.00   44.00

其中最小值和最大值分别是上面输出中的第一个和最后一个值。或者,它们也可以用min()max()函数计算:

min(dat$hwy)## [1] 12max(dat$hwy)## [1] 44

一些明显的编码错误,比如一个人 786 公斤(1733 磅)的体重,已经可以通过这种非常简单的技术很容易地检测出来。

柱状图

检测异常值的另一个基本方法是绘制数据的直方图

使用 R 基(箱的数量对应于观察数量的平方根,以便比默认选项有更多的箱):

hist(dat$hwy,
  xlab = "hwy",
  main = "Histogram of hwy",
  breaks = sqrt(nrow(dat))
) # set number of bins

或者使用ggplot2(通过[esquisse](https://www.statsandr.com/blog/rstudio-addins-or-how-to-make-your-coding-life-easier/#esquisse) 插件或通过本教程学习如何用这个包创建绘图):

library(ggplot2)ggplot(dat) +
  aes(x = hwy) +
  geom_histogram(bins = 30L, fill = "#0c4c8a") +
  theme_minimal()

从直方图来看,似乎有几个观察值高于所有其他观察值(见图右侧的条形)。

箱线图

除了直方图,箱线图也有助于检测潜在的异常值。

使用 R 碱基:

boxplot(dat$hwy,
  ylab = "hwy"
)

或者使用ggplot2:

ggplot(dat) +
  aes(x = "", y = hwy) +
  geom_boxplot(fill = "#0c4c8a") +
  theme_minimal()

箱线图通过显示五个常见位置汇总(最小值、中值、第一和第三四分位数以及最大值)以及使用四分位数间距(IQR) 标准分类为可疑异常值的任何观察值,帮助可视化定量变量。IQR 标准意味着所有高于 q0.75 + 1.5 ⋅ IQR 或低于 q0.25-1.5⋅IQR 的观测值(其中 q 0.25 和 q0.75 分别对应于第一和第三四分位数,iqr 是第三和第一四分位数之间的差值)都被 r 视为潜在异常值。换句话说,以下区间之外的所有观测值都将被视为潜在异常值:

I =[q 0.25-1.5⋅iqr;q0.75 + 1.5 ⋅ IQR]

被 IQR 标准视为潜在异常值的观察值在箱线图中显示为点。基于这一标准,有 2 个潜在的异常值(参见箱线图顶部垂直线上方的 2 个点)。

请记住,并不是因为某个观察值被 IQR 标准认为是潜在的异常值,您就应该删除它。移除或保留异常值取决于(I)您的分析环境,(ii)您将对数据集执行的测试是否对异常值具有鲁棒性,以及(iii)异常值与其他观测值的距离。

借助boxplot.stats()$out函数,还可以根据 IQR 标准提取潜在异常值:

boxplot.stats(dat$hwy)$out## [1] 44 44 41

如您所见,实际上有 3 个点被认为是潜在的异常值:2 个值为 44 的观察值和 1 个值为 41 的观察值。

得益于which()功能,可以提取与这些异常值相对应的行号:

out <- boxplot.stats(dat$hwy)$out
out_ind <- which(dat$hwy %in% c(out))
out_ind## [1] 213 222 223

有了这些信息,您现在可以轻松地返回到数据集中的特定行来验证它们,或者打印这些异常值的所有变量:

dat[out_ind, ]## # A tibble: 3 x 11
##   manufacturer model   displ  year   cyl trans   drv     cty   hwy fl    class  
##   <chr>        <chr>   <dbl> <int> <int> <chr>   <chr> <int> <int> <chr> <chr>  
## 1 volkswagen   jetta     1.9  1999     4 manual… f        33    44 d     compact
## 2 volkswagen   new be…   1.9  1999     4 manual… f        35    44 d     subcom…
## 3 volkswagen   new be…   1.9  1999     4 auto(l… f        29    41 d     subcom…

也可以使用mtext()功能将异常值直接打印在箱线图上:

boxplot(dat$hwy,
  ylab = "hwy",
  main = "Boxplot of highway miles per gallon"
)
mtext(paste("Outliers: ", paste(out, collapse = ", ")))

百分位数

这种异常值检测方法基于百分位数。使用百分位数方法,位于由 2.5 和 97.5 百分位数形成的区间之外的所有观察值将被视为潜在的异常值。也可以考虑其他百分位数,如 1 和 99,或 5 和 95 百分位数来构建区间。

可以使用quantile()函数计算下限和上限百分点值(以及区间的下限和上限):

lower_bound <- quantile(dat$hwy, 0.025)
lower_bound## 2.5% 
##   14upper_bound <- quantile(dat$hwy, 0.975)
upper_bound##  97.5% 
## 35.175

根据这种方法,所有低于 14 和高于 35.175 的观察值都将被视为潜在的异常值。然后可以用which()函数提取间隔之外的观察值的行号:

outlier_ind <- which(dat$hwy < lower_bound | dat$hwy > upper_bound)
outlier_ind##  [1]  55  60  66  70 106 107 127 197 213 222 223

然后可以打印出他们每加仑的公路里程值:

dat[outlier_ind, "hwy"]## # A tibble: 11 x 1
##      hwy
##    <int>
##  1    12
##  2    12
##  3    12
##  4    12
##  5    36
##  6    36
##  7    12
##  8    37
##  9    44
## 10    44
## 11    41

或者,可以打印这些异常值的所有变量:

dat[outlier_ind, ]## # A tibble: 11 x 11
##    manufacturer model    displ  year   cyl trans  drv     cty   hwy fl    class 
##    <chr>        <chr>    <dbl> <int> <int> <chr>  <chr> <int> <int> <chr> <chr> 
##  1 dodge        dakota …   4.7  2008     8 auto(… 4         9    12 e     pickup
##  2 dodge        durango…   4.7  2008     8 auto(… 4         9    12 e     suv   
##  3 dodge        ram 150…   4.7  2008     8 auto(… 4         9    12 e     pickup
##  4 dodge        ram 150…   4.7  2008     8 manua… 4         9    12 e     pickup
##  5 honda        civic      1.8  2008     4 auto(… f        25    36 r     subco…
##  6 honda        civic      1.8  2008     4 auto(… f        24    36 c     subco…
##  7 jeep         grand c…   4.7  2008     8 auto(… 4         9    12 e     suv   
##  8 toyota       corolla    1.8  2008     4 manua… f        28    37 r     compa…
##  9 volkswagen   jetta      1.9  1999     4 manua… f        33    44 d     compa…
## 10 volkswagen   new bee…   1.9  1999     4 manua… f        35    44 d     subco…
## 11 volkswagen   new bee…   1.9  1999     4 auto(… f        29    41 d     subco…

根据百分位数法,有 11 个潜在的异常值。要减少这个数字,您可以将百分比设置为 1 和 99:

lower_bound <- quantile(dat$hwy, 0.01)
upper_bound <- quantile(dat$hwy, 0.99)outlier_ind <- which(dat$hwy < lower_bound | dat$hwy > upper_bound)dat[outlier_ind, ]## # A tibble: 3 x 11
##   manufacturer model   displ  year   cyl trans   drv     cty   hwy fl    class  
##   <chr>        <chr>   <dbl> <int> <int> <chr>   <chr> <int> <int> <chr> <chr>  
## 1 volkswagen   jetta     1.9  1999     4 manual… f        33    44 d     compact
## 2 volkswagen   new be…   1.9  1999     4 manual… f        35    44 d     subcom…
## 3 volkswagen   new be…   1.9  1999     4 auto(l… f        29    41 d     subcom…

将百分位数设置为 1 和 99 会产生与 IQR 标准相同的潜在异常值。

汉佩尔过滤器

另一种方法称为 Hampel 滤波器,包括将由中值加上或减去 3 个中值绝对偏差(MAD)形成的区间(I)之外的值视为异常值

I =[中值 3 ⋅疯了;中位数+ 3 ⋅疯狂]

其中 MAD 是绝对偏差的中值,定义为绝对偏差相对于数据中值的中值~X=median(X):

MAD =中位数(| Xi ~ X |)

对于该方法,我们首先通过median()mad()功能设置区间限制: 2

lower_bound <- median(dat$hwy) - 3 * mad(dat$hwy, constant = 1)
lower_bound## [1] 9upper_bound <- median(dat$hwy) + 3 * mad(dat$hwy, constant = 1)
upper_bound## [1] 39

根据这种方法,所有低于 9 和高于 39 的观察值都将被视为潜在的异常值。然后可以用which()函数提取间隔之外的观察值的行号:

outlier_ind <- which(dat$hwy < lower_bound | dat$hwy > upper_bound)
outlier_ind## [1] 213 222 223

根据 Hampel 过滤器,hwy变量有 3 个异常值。

统计测试

在本节中,我们将介绍 3 种更正式的技术来检测异常值:

  1. 格拉布斯试验
  2. 狄克逊试验
  3. 罗斯纳试验

这 3 个统计测试是异常值检测的更正式技术的一部分,因为它们都涉及与表列临界值(基于样本大小和期望的置信水平)相比较的测试统计的计算。

请注意,只有当数据(没有任何异常值)为近似正态分布时,3 个测试才是合适的。因此,在对异常值进行这些测试之前,必须验证正态假设(参见如何在 R 中测试正态假设)。

格拉布斯试验

Grubbs 检验允许检测数据集中的最高值或最低值是否为异常值。

格拉布斯检验一次检测一个异常值(最高值或最低值),因此无效假设和替代假设如下:

  • H0:最高值是而不是异常值
  • H1:最高的值是一个异常值

如果我们想测试最高值,或者:

  • H0:最低的而不是异常值
  • H1:最低的值是一个异常值

如果我们想测试最低值。

对于任何统计检验,如果p-值 小于所选的显著性阈值(通常α = 0.05),则零假设被拒绝,我们将得出结论最低/最高值是异常值。相反,如果-p-值大于或等于显著性水平,则不拒绝零假设,并且我们将得出结论,基于数据,我们不拒绝最低/最高值不是异常值的假设。

请注意,格拉布斯检验不适用于样本量为 6 或更少(n≤6)的情况。

为了在 R 中执行 Grubbs 测试,我们使用了{outliers}包中的grubbs.test()函数:

# install.packages("outliers")
library(outliers)
test <- grubbs.test(dat$hwy)
test## 
##  Grubbs test for one outlier
## 
## data:  dat$hwy
## G = 3.45274, U = 0.94862, p-value = 0.05555
## alternative hypothesis: highest value 44 is an outlier

p-值为 0.056。在 5%的显著性水平,我们不拒绝假设最高值 44 是而不是异常值。

默认情况下,测试在最高值上执行(如 R 输出所示:alternative hypothesis: highest value 44 is an outlier)。如果您想测试最小值,只需在grubbs.test()函数中添加参数opposite = TRUE:

test <- grubbs.test(dat$hwy, opposite = TRUE)
test## 
##  Grubbs test for one outlier
## 
## data:  dat$hwy
## G = 1.92122, U = 0.98409, p-value = 1
## alternative hypothesis: lowest value 12 is an outlier

R 输出表示测试正在最低值上进行(参见alternative hypothesis: lowest value 12 is an outlier)。

p-值为 1。在 5%的显著性水平上,我们不拒绝假设最低的值 12 是而不是异常值。

为了便于说明,我们现在将用一个更极端的值替换一个观察值,并对这个新数据集执行 Grubbs 测试。让我们用值 212 替换第 34 行:

dat[34, "hwy"] <- 212

我们现在应用格拉布斯检验来检验最高值是否是异常值:

test <- grubbs.test(dat$hwy)
test## 
##  Grubbs test for one outlier
## 
## data:  dat$hwy
## G = 13.72240, U = 0.18836, p-value < 2.2e-16
## alternative hypothesis: highest value 212 is an outlier

p-值为< 0.001。在 5%的显著性水平,我们断定最高值 212 是异常值。

狄克逊试验

与 Grubbs 检验类似,Dixon 检验用于检验单个低值或高值是否为异常值。因此,如果怀疑有一个以上的异常值,必须对这些可疑异常值分别进行测试。

注意,Dixon 检验对小样本(通常 n ≤ 25)最有用。

为了在 R 中执行 Dixon 测试,我们使用了{outliers}包中的dixon.test()函数。然而,我们将我们的数据集限制为 20 个第一次观察值,因为 Dixon 测试只能在小样本量上进行(R 将抛出一个错误,只接受 3 到 30 个观察值的数据集):

subdat <- dat[1:20, ]
test <- dixon.test(subdat$hwy)
test## 
##  Dixon test for outliers
## 
## data:  subdat$hwy
## Q = 0.57143, p-value = 0.006508
## alternative hypothesis: lowest value 15 is an outlier

结果显示最低值 15 是一个异常值( p -value = 0.007)。

要测试最大值,只需将opposite = TRUE参数添加到dixon.test()函数中:

test <- dixon.test(subdat$hwy,
  opposite = TRUE
)
test## 
##  Dixon test for outliers
## 
## data:  subdat$hwy
## Q = 0.25, p-value = 0.8582
## alternative hypothesis: highest value 31 is an outlier

结果显示最高值 31 是而不是一个异常值( p -value = 0.858)。

一个好的做法是始终对照箱线图检查异常值的统计测试结果,以确保我们测试了所有的潜在异常值:

out <- boxplot.stats(subdat$hwy)$out
boxplot(subdat$hwy,
  ylab = "hwy"
)
mtext(paste("Outliers: ", paste(out, collapse = ", ")))

从箱线图中,我们可以看到,除了之前对值 15 进行的测试之外,我们还可以对值 20 进行 Dixon 测试。这可以通过找到最小值的行号来完成,从数据集中排除该行号,然后最后对这个新数据集应用 Dixon 测试:

# find and exclude lowest value
remove_ind <- which.min(subdat$hwy)
subsubdat <- subdat[-remove_ind, ]# Dixon test on dataset without the minimum
test <- dixon.test(subsubdat$hwy)
test## 
##  Dixon test for outliers
## 
## data:  subsubdat$hwy
## Q = 0.44444, p-value = 0.1297
## alternative hypothesis: lowest value 20 is an outlier

结果显示第二个最低值 20 是而不是异常值(p-值= 0.13)。

罗斯纳试验

罗斯纳的异常值检验具有以下优点:

  1. 它用于一次检测几个异常值(与 Grubbs 和 Dixon 测试不同,后者必须反复执行以筛选多个异常值),以及
  2. 它旨在避免屏蔽问题,即一个离群值与另一个离群值接近的离群值可能无法被检测到。

与 Dixon 检验不同,注意 Rosner 检验在样本量较大(n ≥ 20)时最为合适。因此,我们再次使用初始数据集dat,它包括 234 个观察值。

为了执行罗斯纳测试,我们使用了{EnvStats}包中的rosnerTest()函数。这个函数至少需要两个参数:数据和可疑异常值的数量k(默认的可疑异常值数量为k = 3)。

对于本例,我们将可疑异常值的数量设置为 3,正如本文开头的方框图中列出的潜在异常值的数量所示。 2

library(EnvStats)
test <- rosnerTest(dat$hwy,
  k = 3
)
test## $distribution
## [1] "Normal"
## 
## $statistic
##       R.1       R.2       R.3 
## 13.722399  3.459098  3.559936 
## 
## $sample.size
## [1] 234
## 
## $parameters
## k 
## 3 
## 
## $alpha
## [1] 0.05
## 
## $crit.value
## lambda.1 lambda.2 lambda.3 
## 3.652091 3.650836 3.649575 
## 
## $n.outliers
## [1] 1
## 
## $alternative
## [1] "Up to 3 observations are not\n                                 from the same Distribution."
## 
## $method
## [1] "Rosner's Test for Outliers"
## 
## $data
##   [1]  29  29  31  30  26  26  27  26  25  28  27  25  25  25  25  24  25  23
##  [19]  20  15  20  17  17  26  23  26  25  24  19  14  15  17  27 212  26  29
##  [37]  26  24  24  22  22  24  24  17  22  21  23  23  19  18  17  17  19  19
##  [55]  12  17  15  17  17  12  17  16  18  15  16  12  17  17  16  12  15  16
##  [73]  17  15  17  17  18  17  19  17  19  19  17  17  17  16  16  17  15  17
##  [91]  26  25  26  24  21  22  23  22  20  33  32  32  29  32  34  36  36  29
## [109]  26  27  30  31  26  26  28  26  29  28  27  24  24  24  22  19  20  17
## [127]  12  19  18  14  15  18  18  15  17  16  18  17  19  19  17  29  27  31
## [145]  32  27  26  26  25  25  17  17  20  18  26  26  27  28  25  25  24  27
## [163]  25  26  23  26  26  26  26  25  27  25  27  20  20  19  17  20  17  29
## [181]  27  31  31  26  26  28  27  29  31  31  26  26  27  30  33  35  37  35
## [199]  15  18  20  20  22  17  19  18  20  29  26  29  29  24  44  29  26  29
## [217]  29  29  29  23  24  44  41  29  26  28  29  29  29  28  29  26  26  26
## 
## $data.name
## [1] "dat$hwy"
## 
## $bad.obs
## [1] 0
## 
## $all.stats
##   i   Mean.i      SD.i Value Obs.Num     R.i+1 lambda.i+1 Outlier
## 1 0 24.21795 13.684345   212      34 13.722399   3.652091    TRUE
## 2 1 23.41202  5.951835    44     213  3.459098   3.650836   FALSE
## 3 2 23.32328  5.808172    44     222  3.559936   3.649575   FALSE
## 
## attr(,"class")
## [1] "gofOutlier"

有趣的结果在$all.stats表中提供:

test$all.stats##   i   Mean.i      SD.i Value Obs.Num     R.i+1 lambda.i+1 Outlier
## 1 0 24.21795 13.684345   212      34 13.722399   3.652091    TRUE
## 2 1 23.41202  5.951835    44     213  3.459098   3.650836   FALSE
## 3 2 23.32328  5.808172    44     222  3.559936   3.649575   FALSE

基于罗斯纳测试,我们看到只有一个异常值(见Outlier列),它是值为 212(见Value的观测值 34(见Obs.Num)。

附加备注

您会发现许多其他检测异常值的方法:

  1. {outliers}包中,
  2. 通过{DMwR}包中的lofactor()函数:局部异常值因子(LOF)是一种算法,用于通过比较一个点与其邻居的局部密度来识别异常值。
  3. {car}包中的outlierTest()给出了基于给定模型的最极端观察值,并允许测试其是否为异常值,以及
  4. {OutlierDetection}包装中,以及
  5. 使用{mvoutlier}包中的aq.plot()功能(感谢 KTR 的建议。):
library(mvoutlier)Y <- as.matrix(ggplot2::mpg[, c("cyl", "hwy")])
res <- aq.plot(Y)

还要注意,一些转换可能会“自然地”消除异常值。值的自然对数或平方根减少了由极值引起的变化,因此在某些情况下,应用这些变换将消除异常值。

感谢阅读。我希望这篇文章能帮助你通过几个描述性统计(包括最小值、最大值、直方图、箱线图和百分位数)或者借助于更正式的离群点检测技术(包括 Hampel 过滤器、Grubbs、Dixon 和 Rosner 检验)来检测 R 中的离群点。现在轮到您验证它们了,如果它们是正确的,在进行分析之前,决定如何处理它们(即保留、删除或删除它们)。

和往常一样,如果您有与本文主题相关的问题或建议,请将其添加为评论,以便其他读者可以从讨论中受益。

参考

恩德莱因,G. 1987。霍金斯,Dm:离群值的识别。查普曼和霍尔,伦敦-纽约 1980 年,188 年代,14,50 年生物统计学杂志29(2):198–98。

  1. 默认值为 3(根据皮尔逊法则),但也可能是另一个值。 ↩︎
  2. 默认情况下,mad()函数中的常数是 1.4826,因此必须将其设置为 1,以找到中位数绝对偏差。更多详情见help(mad)。感谢艾丽塞给我指出了这一点。 ↩︎
  3. 为了避免得出有缺陷的结论,在进行罗斯纳测试之前,预先筛选数据(例如用箱线图)以尽可能准确地选择潜在异常值的数量是很重要的。 ↩︎

相关文章

原载于 2020 年 8 月 11 日 https://statsandr.com

通过 Tensorflow 超越 Google Cloud AutoML Vision

原文:https://towardsdatascience.com/outperforming-google-cloud-automl-vision-with-tensorflow-and-google-deep-learning-vm-34a45e3860ae?source=collection_archive---------20-----------------------

利用深度学习检测卫星图像中的云

iStock 上的sharp _ done拍摄

动机

有数百篇关于机器学习和深度学习项目的博客文章,我从我读过的那些文章中学到了很多。我想通过讨论我最近从事的一个深度学习项目来增加这些知识。这个项目/博客帖子有一些方面我认为值得一读:

  • 它在数据集上训练了一个 Google AutoML Vision 模型作为基线,然后打败它:)。
  • 它描述了一个基本但现实的数据管道和模型开发工作流,一个小团队可以在野外使用它从原始数据到产品模型服务实例。例如,它解释了如何使用 Docker 容器来部署模型训练实例,而大多数博客文章只描述了如何手动提供模型训练实例。
  • 它包括截至 2020 年 2 月的有关 CNN 架构和超参数调谐的最佳实践。例如,有一个默认的 Keras 参数,如果不改变,可能会很危险,还有一种方式,我看到许多人错误地配置了 hyperopt hyperparameter 调谐库。
  • 它面向已经了解深度学习基础知识的读者,因此对卷积如何工作等基本概念的回顾较少,而更多地关注应用。

项目中使用的关键技术

该项目有以下步骤,这篇博文的结构反映了这些步骤:

  • 识别分类问题并找到数据集
  • ETL 数据,为数据分析和模型训练做准备
  • 执行探索性数据分析
  • 使用 Google AutoML Vision 获取基线
  • 设置模型开发工作流
  • 原型深度学习模型
  • 谷歌深度学习虚拟机上的训练模型
  • 分析模型性能和商业价值
  • 在 Google Cloud 虚拟机上部署获胜模型
  • 最后的想法和谷歌自动视觉的回顾

我在一个 Github repo 中分享了项目代码。

识别分类问题并找到数据集

卫星图像中的云检测是一个重要的分类问题。它在遥感领域被大量使用,因为云掩盖了下面的土地,并且数据集中太多的云图像使得模型更难学习有意义的模式。一个强大的云分类器将使研究人员更容易自动筛选云图像,并构建更大和更准确标记的数据集。

BigEarth 数据集是世界上最大的公共卫星图像数据集,由柏林工业大学的一个德国研究小组于 2019 年创建。数据集由近 600,000 个 120x120 像素的卫星影像切片组成,每个切片有 13 个波段,这些切片已根据土地利用(河流、城市等)、影像是否被云遮挡以及其他元数据(如影像坐标)进行了标注。我构建了一个 CNN 二进制分类器,它使用云标签和每个图像块的红色、绿色和蓝色条带来将图像块分类为多云(cloud图像)或非多云(no_cloud图像)。

这里有一些cloud图像,出于数据探索的目的,我从 tiff 转换成 jpg,下面打印出了类别标签和图像网格位置。

还有一些no_cloud图片:

为了检查这些标签是否有意义,以及这个项目是否可行,我随机查看了 100 张 jpg 图片,并将它们归类为cloudno_cloud。我看到了一些难以分类的图像,比如位于图形位置(2,0)和(2,1)的图像。如果我正在为一个生产应用程序做这个深度学习项目,我会对这些困难的标签进行更多的调查,以确保它们没有被错误分类。尽管如此,我还是能够正确地对 100 幅图像中的 77%进行分类,这给了我继续推进深度学习模型的信心。

ETL 数据,为数据分析和模型训练做准备

大约有 600,000 幅卫星图像,数据集是 60GB 的压缩文件。ETL 过程包括获取目标文件,提取它,生成一些汇总像素统计数据,并将图像转换为可用的格式,以便在 Google AutoML Vision、Google Cloud VM 和本地笔记本电脑上进行深度学习。

ETL 管道由以下步骤组成:

  • 下载。tarfile 从 BigEarth.net 到一个连接了持久磁盘的 Google Cloud 虚拟机,并提取. tarfile。
  • 使用 dask 来聚合。将每个图像的 json 元数据文件平铺到一个. csv 文件中。
  • 对于每个图像拼贴,将 RGB 波段 tiff 文件聚合到一个单独的文件中。npy 和。png 文件。

我在同一个。npy 文件,以提高训练时的读取性能。我选择了。npy 文件格式,因为它与 keras 和 pytorch 都兼容(以防我在某个时候想用 pytorch 重写我的代码)。我将文件存储在磁盘上,而不是谷歌云存储中,因为这样更容易实现高读取吞吐量,还因为 RGB 数据集相当小,只有 50GB。如果你有兴趣深入探讨这个话题,我强烈推荐这篇关于机器学习文件格式的文章

我在一个. png 文件中存储了另一个图像切片的波段副本,因为该文件格式与 Google AutoML Vision 兼容。该产品目前不接受。npy 或者。tiff 文件

进行探索性数据分析

我创建了一个包括所有 9000 张cloud图像和 9000 张随机no_cloud图像的数据集,并通过从大数据集中随机抽取 1200 张cloud图像和 1200 张no_cloud图像创建了一个小的训练数据集。我使用较大的数据集来训练来自小数据集训练回合的获胜模型。

我创建了一个平衡的数据集,因为我想确定问题的范围,为自己的成功做准备。如果我有更多的时间,我会创建一个不平衡的数据集,更准确地反映数据集中cloudno_cloud图像的比例。有一个信息丰富的 tensorflow 教程和一个 kaggle 内核概述了处理不平衡数据的不同策略。

我想了解像素值在整个数据集和样本中的分布,包括cloud图像和no_cloud图像。我还想确认像素值分布在cloudno_cloud图像之间是不同的,并且在样本和整个数据集之间的每个类内是一致的。如果不使用高内存(> 60GB)实例,内存中容纳不下太多的像素值,所以我使用 dask 来计算所有 600K 图像的统计数据(在下图中标为all),以及大数据集和小数据集的每类统计数据。

所有波段的平均值和标准差cloud像素值都高于no_cloud像素值,这提供了分类任务是可学习的证据。

样本和整个数据集之间的每个类中的均值和标准差像素值是相似的,这使我有相当高的信心认为样本代表了数据集。

使用 Google AutoML Vision 获取基线

现在我对数据有了基本的了解和更多的信心,我可以用 Google AutoML Vision 模型得到一个基线。我通过上传样本创建了一个数据集。png 文件到谷歌云存储。注意,目标 GCS 桶必须在us-central-1区域中。AutoML 文档建议您在训练时提供尽可能多的图像,因此为了帮助验证和测试准确性,我使用了albuminations库为样本中的每个图像创建翻转、旋转和翻转+旋转图像。我把这些增强的图像添加到数据集中。

我上传了一个包含数据集分割和 GCS 图像斑点路径的. csv 文件。AutoML 可以为您进行拆分,但是我需要自己进行拆分,以便在相同的数据上训练我自己的模型。

然后,我在小型和大型数据集上训练该模型。82%的准确率和召回率是一个良好的开端。在这篇博文的后面,你会看到我的模型如何与谷歌的相抗衡。

谷歌云自动视觉控制台

我通过使用基于逻辑回归的 SGDClassifier 实现增量学习获得了另一个简单的基线,该分类器将展平的图像数组作为输入。训练准确率为 63%,验证准确率为 65%。

建立模型开发工作流程

我需要一个模型开发工作流,让我能够在本地笔记本电脑上的原型工作和云实例上的繁重培训工作之间轻松转换。我必须能够在 jupyterhub 上以 CPU 和 GPU 模式运行 tensorflow,使用我自己的代码模块,配置依赖关系,在运行之间保存笔记本,并连接到云实例上的 GPU。Docker with conda 是显而易见的解决方案,但我必须弄清楚细节。

深度学习环境有很多移动部分:NVIDIA 驱动程序、CUDA 工具包和安装 jupyter、python、tensorflow 和其他库的 conda 环境。我做了一些关于最佳实践的研究,发现了大量不同的选项,以及大量未回答的 StackOverflow 问题、Github 问题和人们遇到安装问题的博客帖子讨论。很难过。我想避免这种事发生在我身上。

GCP 提供深度学习 VM 镜像,将 NVIDIA 驱动库和 tensorflow 库安装到 VM 上。但是 VM 并没有提供我所需要的一切,因为我在 VM 上运行一个容器,我需要能够在容器内运行 CUDA 工具包和 Tensorflow。我还想了解安装过程是如何工作的,GCP 没有公开其深度学习 VM 镜像源代码。最后,我想要一个解决方案,如果我需要的话,它可以为我将来的 Kubernetes 部署做好准备。所以我决定使用 GCP 深度学习虚拟机来安装 CUDA 驱动程序和 nvidia-docker 工具包来运行 GPU 加速的 docker 容器,然后将其他所有东西安装到我在虚拟机上运行的 Docker 容器中。

我在 GCP VM 主机上安装了 CUDA 驱动程序,因为由于 NVIDIA 的驱动程序代码是专有的,所以在 Docker 容器中安装驱动程序的解决方案没有得到广泛支持。X11docker 提供了支持,但是我没有找到很多人使用它的例子,并且厌倦了添加另一个工具。我使用了 GCP common-cu100 基本虚拟机映像,它在实例上安装了 NVIDIA 驱动程序和 CUDA 10.0 工具包。注意,尽管 CUDA 工具包安装在主机上,我还是在容器中使用了这个工具包。

支持 NVIDIA 的应用程序的组成部分(来源)

至于配置 Docker 映像在 VM 上运行,我考虑过使用一个 GCP 深度学习容器作为基本 Docker 映像,但该产品截至 2019 年 6 月处于测试阶段,并且源 Docker 文件不是公开的。缺乏透明度将使调试任何问题变得困难。我对谷歌云人工智能平台笔记本(在谷歌云上管理的 Jupyterhub)有类似的担忧,因为它们运行的是测试版深度学习容器。

Google 的 Kubernetes 引擎文档cloudml-samples repo 都有使用nvidia/cuda作为基础映像来处理 CUDA 工具包安装和路径配置的例子。所以我使用了nvidia/cuda:10.0-devel-ubuntu18.04图像,并在上面安装了miniconda来建立一个python3.6jupyterhubtensorflow-2.0.0-gpu环境。

下面是创建 GCP 虚拟机实例的 gcloud 命令、GCP 虚拟机实例启动脚本和构建虚拟机实例上运行的映像的 Dockerfile

概括地说,我的工作流程是:

  • 在本地运行 Docker 容器进行模型原型制作
  • 在 GCP 虚拟机实例上运行 Docker 容器进行模型训练
  • 在这两种环境中,使用装载在主机上的 Docker 卷来保存 jupyter 笔记本
  • 使用 scp 使 GCP 上的模型笔记本与本地模型笔记本保持同步(一个更健壮但速度较慢的解决方案可以使用 github repo 进行笔记本同步)

原型深度学习模型

现在我有了一个工作流,我在本地运行 docker 容器,并原型化了一个 Keras CNN 二元分类器,它将把cloud图像分类为1,把no_cloud图像分类为0

我遵循了安德烈·卡帕西和吴恩达推荐的模型开发流程组合。首先,我用遵循当前最佳实践的最简单的模型建立了培训和评估。

神经网络用的是 ReLU 激活,所以我用的是明凯/he_uniform 初始化而不是 Xavier 初始化进行权重初始化。詹姆斯·德林杰对这些差异做了很好的概述。以下是关键要点:

当使用 ReLU 激活时,单个层的平均标准偏差非常接近输入连接数量的平方根除以两个的平方根,或者我们示例中的√512/√2。

将层激活的标准偏差保持在 1 左右将允许我们在深度神经网络中堆叠多个层,而不会出现梯度爆炸或消失。

因此,明凯初始化将每个初始激活乘以*√*2/*√n*,其中*n*是从前一层的输出进入给定层的传入连接数(也称为“扇入”)。

这种更智能的初始化意味着网络更有可能收敛,尤其是在深度网络中:

泽维尔对明凯的 30 层小模式的收敛(我们的)。何等人。艾尔。(2015)

我了解到 Keras 默认使用 Xavier/glorot_uniform,但是有一个开放的 Tensorflow 票证可以将该默认更改为 he_uniform。

权重初始化参数是一个很好的例子,说明在不理解默认参数的情况下在机器学习方法中使用默认参数是多么危险,因为它们可能是任务的不正确参数。

我使用了 Adam 优化器,因为 Adam 优化器收敛速度很快,并且被普遍认为可以很好地处理各种任务。我选择了 3e-4 的学习率,因为我见过很多人使用这个学习率(包括 Andrej Karpathy)。这也比 Tensorflow 中 Adam 的默认学习速率低一个数量级,因为数据集很小,所以我没意见。

我通过一个优化的 tf.data API 管道向模型提供数据,该管道利用预取和并行图像增强来准备向神经网络模型提供的批处理。这大大加快了训练速度。

顺序处理与并行处理(Tensorflow 文档)

我对输入神经网络的批次数据、未经训练的神经网络的预测以及未经训练的神经网络的性能进行了全面检查。由于这是一个二元分类问题,二元交叉熵被用于损失函数。

我检查了神经网络预测的二进制交叉熵损失与随机预测01之间的类别概率的模型的近似损失不太远。我还检查了预测的分布是否以.5为中心。

将偏差减少(拟合)步骤与正则化步骤分开很有用,因为如果模型不能过度拟合数据,则表明数据集中存在缺陷或限制。为此,我只在训练集上过度使用网络。我用云类的正面和负面例子在 10 次观察中反复训练模型,直到准确率达到 100%。

我确认预测值和实际值完全匹配。

在谷歌深度学习虚拟机上训练模型

现在我对我的训练过程有了信心,我将我的 docker 训练映像部署到一个 Google 深度学习 VM 并启动它。我添加了一个定制的 Keras 回调函数,它子类化了 ModelCheckpoint,并在每次达到新的最佳精度时将最佳模型和实验元数据写入 GCS。这允许我为部署持久化模型,并在训练结束后在一台不太昂贵的本地机器上分析实验结果。

我使用验证数据和批量标准化(BN)从原型阶段开始调整模型,以最小化过度拟合并提高验证集的准确性,同时尽可能保持训练集的准确性。我添加了一个验证集,并将成本函数改为使用验证损失而不是训练损失。关于具体的 BN 层放置有很多争论,但我也在激活层之后向神经网络添加了 BN 层。

这些变化导致初始验证精度为. 862,训练精度为. 999。

训练和验证性能之间仍有差距,所以接下来我添加了一个图像增强步骤,使用albuminations库来随机翻转和/或旋转一批图像。这将验证准确度从 0.862 提高到 0.929,同时将训练准确度从 0.999 降低到 0.928。

我将神经网络输出可视化,以确保它是合理的。预测的类别概率的分布显示了我的预期,因为分类器已经清楚地将类别分开。

我研究了添加 Dropout 层来提高验证性能。李、项等。艾尔。表明在模型架构中,在批量标准化层之前插入漏失层可能会对后面的 BN 层的性能产生负面影响。这些 BN 层在训练期间学习归一化数据中的某个协变量偏移,但是在测试时,当关闭压差时,该协变量偏移不再准确。所以我在最后一个 BN 层之后用一个 Dropout 层训练了一个模型。与 BN +增强模型相比,它没有带来任何改进,而且需要更长的训练时间。于是我对 BN +增强模型进行了超参数调优,没有掉线。

我对优化器和学习率执行了超参数调整,以便改进初始神经网络架构搜索的最佳模型。我选择这些参数是因为我已经有了一个运行良好的神经网络架构。如果我没有一个好的神经网络基础性能,我会使用神经结构搜索作为超参数调整步骤的一部分。

贝叶斯优化搜索(BO)是目前推荐的超参数优化方法,优于随机搜索,因为它可以在更少的迭代次数内达到最佳结果。我发现没有公开发表的论文对这两种搜索方法做了明确的比较,但是 Google 的 hyperparameter tuning 产品的默认优化方法,大多数 automl 库支持的优化方法,以及像 T2 这样的几个 ML talks 都推荐 BO 而不是随机搜索。我使用了hyperpt库来执行优化。值得一提的是,我看到许多教程在数值超参数上使用 hp.choice,这是不正确的,因为它删除了这些参数的数值排序所传达的信息,从而降低了搜索的效率和有效性。参见这篇关于 hyperpt的高度评价评论,以获得进一步的讨论。

超参数调整结果

最佳模型具有 Adam 优化器和 2e-4 的学习率,这与未优化的优化器相同,并且几乎与未优化的 3e-4 的学习率相同。我最初的学习速度和优化器表现良好,这在一定程度上是幸运的,因此通过超参数调优来确认我已经在该搜索空间中找到了最好的模型之一是很好的。超参数调整带来了改进,因为最佳模型将验证精度从. 929 提高到. 945,同时将训练精度保持在. 928。获胜模型的训练时间略多于 8 分钟。

我还用 Resnet50V2 作为特征提取器进行了迁移学习。它在 25 分钟的训练时间内达到了 0.921 的验证精度。

我在包含所有 9000 张云图像和 9000 张 no_cloud 图像的大数据集上训练了来自小数据集的最佳模型。验证精度从 0.945 下降到 0.935,但训练精度保持不变,为 0.928,这表明模型的过度拟合程度低于它在小数据集上的情况。虽然大数据集的大小是小数据集的 9 倍,但训练时间仅增加了 3 倍,达到 27 分钟。正如在以前的模型运行中,预测的类概率是我所期望的,有明确的类分离。

在大型数据集上训练 Resnet50V2 分类器似乎也是值得的。它在小数据集上有很好的验证准确性,模型越复杂,它就越能从额外的数据中受益。训练时间太慢,无法尝试超参数调优,所以我坚持使用 Adam 优化器和 3e-4 的学习率,并在 82 分钟的训练时间内找到了验证精度为. 905 的模型。我很失望验证的准确性没有提高,但这仍然是一个相当好的结果。

分析模型性能和商业价值

我评估了最强模型(姑且称之为hp_tuned_keras_cnn)和resnet50_v2模型在小型和大型数据集上的测试性能,并将这些结果与 Google AutoML 模型(google_automl)在小型和大型数据集上的性能进行了比较。在两个数据集上,在 0.5 类预测阈值的情况下,hp_tuned_keras_cnnresnet50_v2在精度和召回率上胜过google_automl。以下是大型数据集性能的结果:

hp_tuned_keras_cnn 精度/召回率与阈值

google_automl 精度/召回率与阈值

每个模型的混淆矩阵显示,两个模型在将no_cloud图像分类为no_cloud时表现最佳,但在cloud图像上与第二类错误(假阴性)斗争最激烈。鉴于我对cloud图像中令人困惑和扭曲的形状的视觉观察,这是有道理的。

hp_tuned_keras_cnn混淆矩阵

google_automl混淆矩阵

我考虑了这个分类器的实际应用。一个应用程序将使用这个模型来筛选出有云的图像,为其他一些图像分类任务做准备。如果我有大量的图像,我会优先考虑云分类任务的召回而不是精度,因为假阳性会导致图像不在数据集中使用,而假阴性会导致有噪声的云图像被添加到数据集中。当然,精度仍然需要很高,因为否则太多的图像(可能还有太多同一土地类型的图像)会被筛选掉。

考虑到这种商业环境,我比较了以更高召回率为目标的模型。在 0.26 的云预测阈值下,hp_tuned_keras_cnn的召回率为 95.8%,准确率为 91.2%。在 0.25 的云预测阈值下,google_automl具有相同的召回率,但准确率为 75.3%。hp_tuned_keras_cnn拥有我一直在寻找的云探测能力。下一步将是在不平衡数据集上测试该模型,然后看看该模型在新数据集上的表现如何。

在谷歌云虚拟机上部署获胜模型

对于部署,我使用了一个 Docker 容器,它在 conda 环境中运行 Flask 和 tensorflow,并在运行时从 Google 云存储中加载模型。客户端通过展平图像张量并向服务器发送 JSON 序列化的张量来发出推断请求。服务器重塑张量,进行类预测,将类预测作为 JSON 发回。

模型部署的重要技术

我将容器部署在一个没有 GPU 的 Google VM 实例上,获得了 100 毫秒的模型服务器响应速度(50 毫秒的推理+50 毫秒的数据处理和其他请求开销)。

在一个成熟的生产系统中,我会对这个部署做一些改进。100 毫秒的延迟高于人类可以察觉的 70 毫秒阈值,因此为了减少延迟,我将使用 TensorFlow 服务于的容器,使用请求批处理而不是 Flask,并在 GPU 而不是 CPU 上运行。在 Kubernetes 上部署该模型还会增加水平可伸缩性。

我还会在部署中添加更多的 MLOps 功能。d .斯卡利等人。艾尔。⁴讨论 ML 系统中隐藏技术债务的来源。一个强有力的建议是监控模型预测分布。如果分布发生了显著变化,这可能表明输入数据的性质发生了变化,模型的最新部署发生了回归,或者两者都有。

谷歌汽车视觉回顾

AutoML Vision 是一款很有潜力的有趣产品。我可以看到 AutoML Vision 在非技术人员或工程师想要深度学习功能但没有人实现它的情况下有其一席之地。然而,我对 AutoML 的性能没有什么印象,因为我能够用一个简单的模型和一个迁移学习模型击败它。我希望 AutoML 至少能超过这些基准。这可能是这个数据集没有发挥 AutoML 的优势,但我也发现是一个性能基准,AutoML 在时尚 MNIST 数据集上的表现比最先进的模型差 93.9%到 96.7%。

AutoML 也不便宜。培训费用 $3.15 每节点小时,最少 16 小时。如果您遵循针对您的数据集大小的建议训练时间,这将快速增加,而且这还不包括推理请求的定价,或者许多生产级模型所需的重复训练运行。培训 16 个节点小时的小型 AutoML 模型花费 38 美元,培训 65 个节点小时的大型 AutoML 模型花费 195 美元。作为对比,小的hp_tuned_keras_cnn模型训练 8 分钟,花费 0.40 美元,大的hp_tuned_keras_cnn模型训练 27 分钟,花费 1.35 美元。鉴于运行一个 Tesla V100 可抢占实例的成本为每节点小时 0.82 美元,如果 Google 能够提供一个更宽松的 sla 价格点就好了。同样,也许这个产品的成本对于一个没有足够的 ML 专业知识的组织来说是可以接受的。

最终想法

成功小子迷因生成器(来源)

咻!如果你已经读到这里,恭喜你,谢谢你。我希望你能从我的经历中学到一些有用的东西。这个项目非常有趣,让我有机会玩更多最新的 ML 技术。

我期待着在未来建立更多的机器学习驱动的系统,无论是在我的工作中还是在我的兼职项目中。我对机器学习领域工具的增长感到兴奋,包括堆栈的所有部分。随着这些工具的成熟,它们将使机器学习更容易为每个人所用。我也对神经网络最佳实践的发展速度感到惊讶。看看这种创新会走向何方将是一件有趣的事情。

有兴趣联系或一起工作吗?在下面分享你的回答,或者在 linkedin 上给我留言。

本文使用的代码可以在这个 资源库 中的 my GitHub 上获得。

[1] G. Sumbul,M. Charfuelan,b .德米尔,V. Markl, BigEarthNet:遥感影像理解的大规模基准档案库 (2019),IEEE 国际地球科学与遥感研讨会

[2] K. ,X. ,S. J .孙深入研究整流器:在 ImageNet 分类上超越人类水平的性能 (2015),IEEE 计算机视觉国际会议(ICCVV)

[3] X 李S 陈X 胡J 杨用方差移位理解丢失与批量归一化的不协调 (2019),IEEE 计算机视觉与模式识别会议()

[4] D .斯卡利,g .霍尔特,d .戈洛文,e .达维多夫,t .菲利普,机器学习系统中隐藏的技术债务 (2015),神经信息处理系统进展 28 (NIPS)

超过 100 个数据科学家面试问题和答案!

原文:https://towardsdatascience.com/over-100-data-scientist-interview-questions-and-answers-c5a66186769a?source=collection_archive---------0-----------------------

来自亚马逊、谷歌、脸书、微软等公司的面试问题!

图片由阿曼达·福西特提供

我知道这很漫长…

真的很长。但是不要被它的长度吓倒——我已经把它分成了四个部分(机器学习、统计、SQL、杂项),这样你就可以一点一点地看完它。

请将此视为一本工作簿或一门速成课程,其中包含数百个数据科学面试问题,您可以用这些问题来磨练自己的知识,并找出差距,以便随后填补。

我希望这对您有所帮助,并祝您在数据科学事业中好运!

如果你喜欢这篇文章并想支持我,请考虑订阅我下面的链接!😃

[## 通过我的推荐链接加入 Medium-Terence Shin

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

terenceshin.medium.com](https://terenceshin.medium.com/membership)

目录

机器学习基础

问:在应用机器学习算法之前,数据争论和数据清洗的一些步骤是什么?

当数据争论和数据清理时,可以采取许多步骤。下面列出了一些最常见的步骤:

  • 数据剖析:几乎每个人都是从了解他们的数据集开始的。更具体地说,您可以使用。形状和对数值变量的描述。描述()。
  • 数据可视化:有时,用直方图、箱线图和散点图来可视化数据很有用,这样可以更好地理解变量之间的关系,也可以识别潜在的异常值。
  • 语法错误:这包括确保没有空格,确保字母大小写一致,检查错别字。您可以使用。unique()或使用条形图。
  • 标准化或规范化:根据您正在处理的数据集和您决定使用的机器学习方法,标准化或规范化您的数据可能会很有用,这样不同变量的不同尺度就不会对模型的性能产生负面影响。
  • 处理空值:有多种方法来处理空值,包括完全删除具有空值的行,用均值/中值/众数替换空值,用新的类别(例如未知)替换空值,预测值,或者使用可以处理空值的机器学习模型。阅读更多此处
  • 其他还有:去除无关数据,去除重复,类型转换。

请务必 订阅此处 或至我的 独家快讯 千万不要错过另一篇关于数据科学的指南、技巧和提示、生活经验等!

问:如何处理不平衡的二元分类?

有许多方法可以处理不平衡的二进制分类(假设您想要识别少数类):

  • 首先,你要重新考虑你用来评估模型的指标。你的模型的准确性可能不是最好的衡量标准,因为我将用一个例子来解释为什么。假设 99 次银行取款不是欺诈,1 次取款是欺诈。如果你的模型只是简单地将每个实例归类为“非欺诈”,那么它的准确率将达到 99%!因此,您可能需要考虑使用精度和召回率等指标。
  • 另一种改善不平衡二进制分类的方法是通过增加错误分类少数类的成本。通过增加这样的惩罚,该模型应该更准确地对少数民族进行分类。
  • 最后,你可以通过过采样少数阶级或者欠采样多数阶级来改善阶级的平衡。你可以在这里阅读更多关于它的

问:箱形图和直方图有什么区别?

箱线图与直方图

虽然箱线图和直方图是用于显示数据分布的可视化工具,但它们传达信息的方式不同。

直方图是显示数值变量值的频率的条形图,用于估计给定变量的概率分布。它允许您快速了解分布的形状、变化和潜在的异常值。

箱线图表达了数据分布的不同方面。虽然您无法通过箱线图看到分布的形状,但您可以收集其他信息,如四分位数、范围和异常值。当您想要同时比较多个图表时,箱线图尤其有用,因为它们比直方图占用更少的空间。

如何阅读箱线图

问:描述不同的正则化方法,如 L1 和 L2 正则化?

L1 和 L2 正则化都是用于减少训练数据过拟合的方法。最小二乘法使残差平方和最小,这可能导致低偏差但高方差。

L2 正则化,也称为岭回归,最小化残差平方和加上λ乘以斜率平方。这个附加项被称为岭回归惩罚。这增加了模型的偏差,使得对训练数据的拟合更差,但是也减少了方差。

如果采用岭回归罚分并用斜率的绝对值替换它,则得到套索回归或 L1 正则化。

L2 不太稳健,但有一个稳定的解决方案,而且总是一个解决方案。L1 更稳健,但是具有不稳定的解,并且可能具有多个解。

StatQuest 有一个关于套索和山脊回归的惊人视频这里

问:神经网络基础

一个神经网络是一个受人脑启发的多层模型。就像我们大脑中的神经元一样,上面的圆圈代表一个节点。蓝色圆圈代表输入层,黑色圆圈代表隐藏层,绿色圆圈代表输出层。隐藏层中的每个节点代表输入经过的功能,最终导致绿色圆圈中的输出。这些功能的正式术语称为s 形激活功能

如果你想要一步一步的创建神经网络的例子,请点击这里查看 Victor Zhou 的文章。

如果你是一名视觉/音频学习者,3Blue1Brown 在 YouTube 上有一个关于神经网络和深度学习的惊人系列这里

务必 订阅此处 或至我的 独家快讯 千万不要错过另一篇关于数据科学的指南、窍门和技巧、生活经验等!

问:什么是交叉验证?

交叉验证本质上是一种用于评估模型在新的独立数据集上表现如何的技术。交叉验证最简单的例子是将数据分成两组:定型数据和测试数据,其中定型数据用于构建模型,测试数据用于测试模型。

问:如何定义/选择指标?

没有放之四海而皆准的标准。选择用于评估机器学习模型的度量取决于各种因素:

  • 是回归还是分类任务?
  • 商业目标是什么?精确度与召回率
  • 目标变量的分布是什么?

可以使用的指标有很多,包括调整后的 r 平方、MAE、MSE、准确度、召回率、精确度、f1 分数等等。

问:解释什么是精确和召回

回忆一下试图回答“正确识别实际阳性的比例是多少?”

Precision 试图回答“多大比例的肯定识别实际上是正确的?”

摘自维基百科

问:解释什么是假阳性和假阴性。为什么这些对彼此很重要?举例说明假阳性比假阴性更重要,假阴性比假阳性更重要,以及这两种错误同等重要

一个假阳性是当一个条件不存在时对其存在的不正确识别。

假阴性是对实际存在的条件不存在的错误识别。

假阴性比假阳性更重要的一个例子是癌症筛查。与其说有人得了癌症,后来才发现没有,不如说有人没得癌症。

这是一个主观的论点,但从心理学的角度来看,假阳性可能比假阴性更糟糕。例如,赢得彩票的假阳性可能比假阴性更糟糕,因为人们通常不会期望赢得彩票。

问:监督学习和无监督学习有什么区别?给出具体的例子

监督学习包括学习一个函数,该函数基于示例输入-输出对将输入映射到输出[1]。

例如,如果我有一个包含两个变量的数据集,年龄(输入)和身高(输出),我可以实现一个监督学习模型,根据年龄预测一个人的身高。

由作者创建

与监督学习不同,非监督学习用于从输入数据中进行推断和发现模式,而不参考标记的结果。无监督学习的一个常见用途是根据购买行为对客户进行分组,以找到目标市场。

查看我的文章' 六分钟解释所有机器学习模型 '如果你想了解更多这方面的信息!

问:假设您需要使用多元回归生成一个预测模型。解释你打算如何验证这个模型

有两种主要方法可以做到这一点:

A)调整后的 R 平方

r 平方是一种度量,它告诉你因变量的方差在多大程度上是由自变量的方差来解释的。更简单地说,当系数估计趋势时,R 平方表示最佳拟合线周围的散布。

然而,添加到模型中的每一个额外的独立变量总是增加 R 平方值——因此,具有几个独立变量的模型可能看起来更适合,即使它不是。这就是调整后的 R 的用武之地。调整后的 R 补偿每个额外的独立变量,并且仅在每个给定变量将模型改进到超出概率可能的程度时才增加。这很重要,因为我们正在创建一个多元回归模型。

B)交叉验证

大多数人常用的一种方法是交叉验证,将数据分成两组:训练数据和测试数据。有关这方面的更多信息,请参见第一个问题的答案。

问:NLP 代表什么?

NLP 代表自然语言处理。它是人工智能的一个分支,赋予机器阅读和理解人类语言的能力。

问:什么时候你会使用随机森林来对抗 SVM,为什么?

为什么随机森林是比支持向量机更好的模型选择,有几个原因:

  • 随机森林允许您确定要素的重要性。SVM 不能这么做。
  • 随机森林比 SVM 建造起来更快更简单。
  • 对于多类分类问题,支持向量机需要一种 one-vs-rest 方法,这种方法扩展性差,占用内存多。

问:为什么降维很重要?

降维是减少数据集中要素数量的过程。这主要在您想要减少模型中的方差(过度拟合)的情况下很重要。

维基百科陈述了降维的四个优点(见此处):

  1. 它减少了所需的时间和存储空间
  2. 多重共线性的消除改善了机器学习模型参数的解释
  3. 当数据降低到非常低的维度时,如 2D 或 3D ,将变得更容易可视化
  4. 它避免了维数灾难

问:什么是主成分分析?解释你会用主成分分析来解决哪类问题。

从最简单的意义上来说,PCA 涉及将高维数据(例如 3 维)投影到更小的空间(例如 2 维)。这导致数据的维度降低(2 维而不是 3 维),同时保持模型中的所有原始变量。

PCA 通常用于压缩目的,以减少所需的内存并加速算法,以及用于可视化目的,使汇总数据更容易。

问:为什么朴素贝叶斯这么差?如何改进使用朴素贝叶斯的垃圾邮件检测算法?

朴素贝叶斯的一个主要缺点是,它有一个很强的假设,即假设这些特征彼此不相关,但事实通常并非如此。

改进这种使用朴素贝叶斯的算法的一种方法是对特征去相关,使得假设成立。

问:线性模型的缺点是什么?

线性模型有几个缺点:

  • 线性模型有一些强有力的假设,在应用中可能不成立。它假设线性关系、多元正态性、没有或很少多重共线性、没有自相关和同方差
  • 线性模型不能用于离散或二元结果。
  • 您不能改变线性模型的模型灵活性。

问:你认为 50 个小决策树比一个大决策树好吗?为什么?

问这个问题的另一种方式是“随机森林是比决策树更好的模型吗?”答案是肯定的,因为随机森林是一种集成方法,需要许多弱决策树来形成强学习器。随机森林更准确、更健壮,并且不容易过度拟合。

问:为什么均方差不是衡量模型性能的好方法?你有什么建议?

均方误差(MSE)对大误差给予相对较高的权重,因此,MSE 往往过于强调大偏差。更可靠的替代方法是 MAE(平均绝对偏差)。

问:线性回归需要哪些假设?如果这些假设中的一些被违反了呢?

这些假设如下:

  1. 用于拟合模型的样本数据是代表人口的
  2. X 和 Y 的均值之间的关系是线性****
  3. 残差的方差对于 X 的任何值都是相同的(同方差)****
  4. 观察是相互独立的
  5. 对于 X 的任意值,Y 都是正态分布

极端违反这些假设将使结果变得多余。对这些假设的小的违反将导致估计的更大的偏差或方差。

问:什么是共线性,如何处理共线性?如何去除多重共线性?

当多元回归方程中的一个自变量与另一个自变量高度相关时,就存在多重共线性。这可能是有问题的,因为它破坏了一个独立变量的统计意义。

您可以使用方差膨胀因子(VIF)来确定自变量之间是否存在多重共线性-标准基准是,如果 VIF 大于 5,则存在多重共线性。

问:如何检查回归模型是否很好地拟合了数据?

有几个指标可供您使用:

R 平方/调整后的 R 平方:**相对拟合度。这在之前的回答中已经解释过了

****F1 得分:评估所有回归系数都等于零的原假设与至少一个不等于零的替代假设

RMSE: 绝对契合度。

什么是决策树?

图片来自 Kaggle

****决策树是一种流行的模型,用于运筹学、战略规划和机器学习。上面的每个方块被称为一个节点,节点越多,你的决策树就越精确(一般来说)。决策树的最后一个节点,也就是做出决策的地方,被称为树的。决策树直观且易于构建,但在准确性方面有所欠缺。

问:什么是随机森林?为什么好?

随机森林是一种基于决策树的集成学习技术。随机森林包括使用原始数据的自举数据集创建多个决策树,并在决策树的每一步随机选择一个变量子集。然后,该模型选择每个决策树的所有预测的模式。依靠“多数获胜”模型,它降低了单个树出错的风险。

例如,如果我们创建一个决策树,第三个,它会预测 0。但是如果我们依赖所有 4 个决策树的模式,预测值将是 1。这就是随机森林的力量。

随机森林提供了其他几个好处,包括强大的性能,可以模拟非线性边界,不需要交叉验证,并赋予功能重要性。

务必 订阅此处 或至我的 独家快讯 千万不要错过另一篇关于数据科学的指南、窍门和技巧、生活经验等!

问:什么是内核?解释内核技巧

核是一种计算两个向量 𝐱 x 和 𝐲 y 在某个(可能是非常高维的)特征空间内点积的方法,这就是为什么核函数有时被称为“广义点积”[2]

核心技巧是一种使用线性分类器来解决非线性问题的方法,方法是将线性不可分的数据转换为高维线性可分的数据。

摘自分析 Vidhya

问:在拟合 SVM 之前进行降维是否有益?为什么或为什么不?

当特征的数量大于观察的数量时,那么执行维数减少通常会改善 SVM。

问:什么是过度拟合?

摘自维基百科

过度拟合是一种错误,即模型“拟合”数据太好,导致模型具有高方差和低偏差。因此,过度拟合模型将会不准确地预测新的数据点,即使它对训练数据具有高的准确性。

问:什么是助推?

Boosting 是一种集成方法,通过减少模型的偏差和方差来改进模型,最终将弱学习者转换为强学习者。总体思路是训练一个弱学习器,通过对前一个学习器的学习,依次迭代改进模型。你可以在这里 了解更多

一定要 订阅 千万不要错过另一篇关于数据科学指南、技巧和提示、生活经验等的文章!

统计、概率和数学

问:商品在位置 A 的概率是 0.6,在位置 b 的概率是 0.8。在亚马逊网站上找到该商品的概率是多少?

我们需要对这个问题做一些假设才能回答。让我们假设在亚马逊上有两个可能的地方购买一件特定的商品,在位置 A 找到它的概率是 0.6,在位置 B 找到它的概率是 0.8。在亚马逊上找到该商品的概率可以这么解释:

我们可以把上面的话重新措辞为 P(A) = 0.6,P(B) = 0.8。此外,让我们假设这些是独立的事件,这意味着一个事件的概率不受另一个事件的影响。然后我们可以使用公式…

P(A 或 B) = P(A) + P(B) — P(A 和 B)
P(A 或 B) = 0.6 + 0.8 — (0.6*0.8)
P(A 或 B) = 0.92

点击查看亚马逊数据科学家采访指南

问:你从 100 枚硬币中随机抽取一枚——1 枚不公平硬币(正面朝上),99 枚公平硬币(正面朝下),然后掷 10 次。如果结果是 10 头,硬币不公平的概率是多少?

这可以用贝叶斯定理来回答。贝叶斯定理的扩展方程如下:

假设选到不公平硬币的概率表示为 P(A),连续翻转 10 个头像的概率表示为 P(B)。那么 P(B|A)等于 1,P(B∣ A)等于 0。⁵ ⁰,P( A)等于 0.99。

如果填入等式,那么 P(A|B) = 0.9118 或者 91.18%。

问:凸与非凸代价函数的区别;当一个代价函数是非凸的时候意味着什么?

摘自加州大学洛杉矶分校谢卓瑞

****凸函数是指在图上任意两点之间画出的一条线位于图上或图上。它有一个最小值。

****非凸函数是在图上任意两点之间画的线可能与图上其他点相交的函数。它的特征是“波浪形”。

当成本函数是非凸的时,这意味着该函数有可能找到局部最小值而不是全局最小值,从优化的角度来看,这在机器学习模型中通常是不期望的。

问:浏览概率基础知识

为此,我要在这里和四种不同的计数方法(详见* 这里 )。***

概率的八大法则

  • 规则#1:对于任何事件 A,0≤P(A)≤1*;换句话说,一个事件的概率范围可以从 0 到 1***
  • 规则 2:所有可能结果的概率总和总是等于 1
  • 规则#3: P(不是 A)= 1—P(A)这个规则解释了一个事件的概率和它的补事件之间的关系。补充事件是指包含 a 中没有的所有可能结果的事件**
  • 规则#4:如果 A 和 B 是不相交事件(互斥),那么 P(A 或 B)= P(A)+P(B)这被称为不相交事件的添加规则**
  • 规则#5: P(A 或 B) = P(A) + P(B) — P(A 和 B)这就是所谓的一般加法法则。**
  • 规则#6:如果 A 和 B 是两个独立事件,那么 P(A 和 B)= P(A) P(B)这叫做独立事件的乘法法则。***
  • 规则#7:给定事件 A,事件 B 的条件概率是 P(B|A) = P(A 和 B) / P(A)
  • 规则#8:对于任意两个事件 A 和 B, P(A 和 B)= P(A) P(B | A)这就是所谓的一般乘法法则***

计数方法

阶乘公式:n!= n x (n -1) x (n — 2) x … x 2 x 1 当项目数等于可用位置数时使用。例:找出 5 个人可以坐在 5 个空座位上的总方式数。
= 5×4×3×2×1 = 120

基本计数原理(乘法) 当允许重复且填充空位的方式数不受之前填充的影响时,应使用此方法。早餐有 3 种,午餐有 4 种,甜点有 5 种。组合总数= 5 x 4 x 3 = 60

排列:P(n,r)= n!/(n r)!
例如,一个代码有 4 个数字,按特定顺序排列,数字范围从 0 到 9。如果一个数字只能用一次,有多少种排列?
P(n,r) = 10!/(10–4)!=(10 x 9 x 8 x 7 x 6 x 5 x 4 x 3 x2 x 1)/(6x 5 x 4 x 3 x2 x 1)= 5040

组合公式:C(n,r)=(n!)/[(n r)!r!] 当不允许替换并且项目的排列顺序不重要时使用。要赢得彩票,你必须从 1 到 52 中以任意顺序选出 5 个正确的数字。有多少种可能的组合?
C(n,r) = 52!/ (52–5)!5!= 2598960

问:描述马尔可夫链?

Brilliant 提供了马尔可夫链的一个很好的定义(此处):

“马尔可夫链是一个数学系统,它按照一定的 概率 规则经历从一个状态到另一个状态的转变。马尔可夫链的定义特征是,无论 过程 如何到达其当前状态,可能的未来状态都是固定的。换句话说,转换到任何特定状态的概率只取决于当前状态和经过的时间。”

马尔可夫链背后的实际数学需要线性代数和矩阵的知识,所以我会在下面留下一些链接,以防你想自己进一步探索这个主题。

查看更多 此处 此处

问:一个盒子里有 12 张红卡和 12 张黑卡。另一个盒子里有 24 张红牌和 24 张黑牌。你想从两个盒子中的一个里随机抽取两张卡片,一次抽取一张。哪个盒子得到同色卡片的概率更大,为什么?

有 24 张红卡和 24 张黑卡的盒子获得两张同色卡片的概率更大。让我们走过每一步。

假设你从每副牌中抽出的第一张牌是红色的 a。

这意味着在有 12 个红和 12 个黑的牌组中,现在有 11 个红和 12 个黑。因此,你再抽一张红色的几率等于 11/(11+12)或 11/23。

一副牌中有 24 个红和 24 个黑,那么就有 23 个红和 24 个黑。因此,你再抽一张红色的几率等于 23/(23+24)或 23/47。

由于 23/47 > 11/23,所以卡数较多的第二副牌有较大概率得到相同的两张牌。

问:你在赌场,有两个骰子可以玩。你每掷一次 5 就赢 10 美元。如果你一直玩到你赢了然后停止,预期的回报是多少?

  • 我们假设每次你想玩的时候要花 5 美元。
  • 两个骰子有 36 种可能的组合。
  • 在 36 种组合中,有 4 种组合会掷出 5(见蓝色)。这意味着有 4/36 或 1/9 的机会掷出 5。**
  • 1/9 的胜算意味着你会输八次,赢一次(理论上)。
  • 因此,您的预期支出等于$ 10.00 * 1-$ 5.00 * 9 =-35.00。

编辑:谢谢各位的评论和指出,应该是-$35!

问:如何判断给定的硬币是否有偏差?

这不是一个难题。答案很简单,就是进行假设检验:

  1. 零假设是硬币没有偏向,翻转头的概率应该等于 50% (p=0.5)。另一个假设是硬币有偏差,p!= 0.5.
  2. 抛硬币 500 次。
  3. 计算 Z 得分(如果样本小于 30,则需要计算 t 统计量)。
  4. 对比 alpha(双尾检验所以 0.05/2 = 0.025)。
  5. 如果 p 值>α,则不拒绝 null,硬币不偏。
    如果 p 值<α,则 null 被拒绝,硬币有偏差。

了解更多假设检验 这里

让不公平的硬币变得公平

由于抛硬币是二进制的结果,你可以通过抛两次硬币来使不公平的硬币变得公平。如果你掷两次,有两种结果可以赌:正面跟着反面或者反面跟着正面。

P(正面) P(反面)= P(反面) P(正面)**

这是有意义的,因为每一次抛硬币都是一个独立的事件。这意味着如果你得到正面→正面或反面→反面,你需要重新抛硬币。

问:你即将登上去伦敦的飞机,你想知道你是否需要带雨伞。你随便打电话给三个朋友,问他们是否在下雨。你的朋友说实话的概率是 2/3,他们通过撒谎对你恶作剧的概率是 1/3。如果他们三个都说在下雨,那么伦敦下雨的概率是多少。

你可以看出这个问题与贝叶斯理论有关,因为最后一个陈述本质上遵循这样的结构,“假设 B 为真,A 为真的概率是多少?”因此,我们需要知道某一天伦敦下雨的概率。假设是 25%。

P(A) =下雨的概率= 25%
P(B) =三个朋友都说在下雨的概率
P(A|B)假定他们说在下雨的概率
P(B|A)假定在下雨的情况下三个朋友都说在下雨的概率= (2/3) = 8/27

第一步:求解 P(B)
P(A | B)= P(B | A) * P(A)/P(B),可以改写为
P(B)= P(B | A)
P(A)+P(B |非 A)
P(非 A)
P(B)=(2/3)
0.25+(1/3)* 0.75 = 0.25 * 8/27+0.75 * 1/1***

*第二步:求解 P(A | B)
P(A | B)= 0.25 (8/27)/(0.25 * 8/27+0.75 * 1/27)
P(A | B)= 8/(8+3)= 8/11

因此,如果三个朋友都说在下雨,那么有 8/11 的几率是真的在下雨。

问:给你 40 张四种不同颜色的卡片——10 张绿卡、10 张红牌、10 张蓝卡和 10 张黄牌。每种颜色的卡片都从一到十编号。随机抽取两张牌。找出所选卡片不是相同号码和相同颜色的概率。

由于这些事件不是独立的,我们可以使用规则:
P(A 和 B) = P(A) * P(B|A),也等于
P(非 A 非 B) = P(非 A) * P(非 B |非 A)

例如:

P(非 4 非黄)= P(非 4) * P(非黄|非 4)
P(非 4 非黄)= (36/39) * (27/36)
P(非 4 非黄)= 0.692

所以,挑出来的牌不是同号同色的概率是 69.2%。

问:如何评估洞察力的统计显著性?

您将执行假设检验来确定统计显著性。首先,你要陈述零假设和替代假设。其次,您将计算 p 值,即假设零假设为真,获得测试观察结果的概率。最后,您将设置显著性水平(alpha ),如果 p 值小于 alpha,您将拒绝 null 换句话说,结果具有统计显著性。

问:解释什么是长尾分布,并提供三个具有长尾的相关现象的例子。为什么它们在分类和回归问题中很重要?

长尾分布的例子

长尾分布是一种重尾分布,它有一条(或多条)逐渐渐近消失的尾巴。

3 实际例子包括幂定律、帕累托原则(通常称为 80-20 法则)和产品销售(即最畅销的产品与其他产品相比)。

在分类和回归问题中注意长尾分布是很重要的,因为出现频率最低的值构成了总体的大多数。这最终会改变您处理异常值的方式,并且它也与一些假设数据正态分布的机器学习技术相冲突。

问:什么是中心极限定理?解释一下。为什么重要?

来自维基百科

统计学如何为 CLT 提供了最好的定义,这就是:

“中心极限定理表明,无论总体分布的形状如何,随着样本量的增加,样本均值的抽样分布都接近正态分布。”[1]

中心极限定理很重要,因为它用于假设检验和计算置信区间。

问:什么是统计能力?

“统计功效”是指二元假设的功效,即假设替代假设为真,测试拒绝零假设的概率。[2]

问:解释选择偏差(关于数据集,而不是变量选择)。为什么重要?丢失数据处理等数据管理程序如何使情况变得更糟?

选择偏倚是指在选择个人、群体或数据进行分析时,没有实现适当的随机化,最终导致样本不能代表总体的现象。

理解和识别选择偏差是很重要的,因为它会严重扭曲结果,并提供关于特定人群的错误见解。

选择偏差的类型包括:

  • 抽样偏倚:由非随机抽样引起的有偏倚的样本
  • 时间间隔:选择支持预期结论的特定时间框架。例如,在临近圣诞节时进行销售分析。
  • 暴露:包括临床易感性偏倚、原发性偏倚、适应症偏倚。此处阅读更多****
  • 数据:包括摘樱桃、压制证据、证据不全的谬误。
  • 流失:流失偏倚类似于生存偏倚,即只有那些在长期过程中“存活”下来的人才会被纳入分析,或者类似于失败偏倚,即只有那些“失败”的人才会被纳入分析
  • 观察者选择:与人择原理有关,这是一种哲学上的考虑,我们收集的关于宇宙的任何数据都要经过过滤,为了让它可以被观察到,它必须与观察它的有意识和有智慧的生命兼容。[3]

处理缺失数据会使选择偏差变得更糟,因为不同的方法会以不同的方式影响数据。例如,如果您用数据的平均值替换空值,您就增加了偏差,因为您假设数据并不像实际可能的那样分散。

问:提供一个简单的例子,说明实验设计如何帮助回答一个关于行为的问题。实验数据和观测数据如何对比?

观察数据来自观察研究,即观察某些变量并试图确定它们之间是否存在关联。

实验数据来自实验研究,即当你控制某些变量并保持它们不变,以确定是否存在因果关系。

实验设计的一个例子如下:将一组分成两个。对照组正常生活。测试组被告知在 30 天内每天晚上喝一杯酒。然后可以进行研究,看看酒是如何影响睡眠的。

问:缺失数据的均值插补是可接受的做法吗?为什么或为什么不?

均值插补是用数据的均值替换数据集中的空值的做法。

均值插补通常是不好的做法,因为它没有考虑特征相关性。例如,假设我们有一个显示年龄和健康分数的表格,并假设一个 80 岁的老人缺少健康分数。如果我们从 15 岁到 80 岁的年龄范围内取平均健康分数,那么 80 岁的人看起来会有一个比他实际应该有的高得多的健康分数。

第二,均值插补减少了数据的方差,增加了数据的偏倚。由于方差较小,这导致模型不太精确,置信区间较窄。

问:什么是异常值?解释如何筛选异常值,如果在数据集中发现异常值,您会怎么做。此外,解释什么是内联体,如何筛选内联体,如果在数据集中发现了内联体,你会怎么做。

一个异常值是一个明显不同于其他观察值的数据点。

根据异常值的原因,从机器学习的角度来看,它们可能是坏的,因为它们会降低模型的准确性。如果异常值是由测量误差引起的,那么将它们从数据集中移除是非常重要的。有几种方法可以识别异常值:

Z 值/标准偏差:如果我们知道一个数据集中 99.7%的数据位于三个标准偏差之内,那么我们可以计算一个标准偏差的大小,将其乘以 3,并确定超出该范围的数据点。同样,我们可以计算给定点的 z 分数,如果它等于+/- 3,那么它就是异常值。
注意:使用该方法时,需要考虑一些意外情况;数据必须呈正态分布,这一点不适用于小数据集,过多异常值的存在会影响 z 值。

四分位距(IQR): IQR,用于构建箱线图的概念,也可用于识别异常值。IQR 等于第三个四分位数和第一个四分位数之差。然后,如果一个点小于 Q1-1.5 * IRQ 或大于 Q3 + 1.5IQR,则可以确定该点是否为异常值。这达到大约 2.698 个标准偏差。*

照片来自迈克尔·加拉尼克

其他方法包括 DBScan 聚类、隔离森林和稳健随机采伐森林。

一个内联者是一个数据观察,它位于数据集的其余部分内,是不寻常的或者是一个错误。由于它位于数据集中,通常比异常值更难识别,需要外部数据来识别它们。如果您发现了任何内联者,您可以简单地将它们从数据集中删除以解决它们。

问:你如何处理丢失的数据?有什么插补技巧推荐?

有几种方法可以处理丢失的数据:

  • 删除缺少数据的行
  • 均值/中值/众数插补
  • 分配唯一的值
  • 预测缺失值
  • 使用支持缺失值的算法,如随机森林

最好的方法是删除缺少数据的行,因为这样可以确保没有偏差或差异被添加或删除,并最终产生一个稳健而准确的模型。但是,只有在开始时有大量数据并且缺失值的百分比很低的情况下,才建议这样做。

问:你有呼叫中心通话时长的数据。为如何编码和分析这些数据制定一个计划。解释一下这些持续时间的分布情况。你如何测试,甚至是图形化地测试,你的期望是否实现了?

首先,我会进行 EDA——探索性数据分析,以清理、探索和理解我的数据。见我关于 EDA 的文章 这里 。作为我的 EDA 的一部分,我可以构建一个通话持续时间的直方图来查看潜在的分布。**

我的猜测是,呼叫的持续时间将遵循对数正态分布(见下文)。我认为它是正偏的原因是因为下限被限制为 0,因为调用不能是负秒。然而,在高端,很可能有一小部分通话时间相对较长。

对数正态分布示例

您可以使用 QQ 图来确认通话时长是否符合对数正态分布。参见 此处 了解更多 QQ 剧情。**

问:解释行政数据集和从实验研究中收集的数据集之间可能的差异。管理数据可能会遇到什么问题?实验方法如何帮助缓解这些问题?它们带来了什么问题?

行政数据集通常是政府或其他组织出于非统计原因使用的数据集。

管理数据集通常比实验研究更大,更具成本效益。假设与管理数据集相关联的组织是活动的并且正在运行,那么它们也会被定期更新。与此同时,管理数据集可能无法捕获用户可能需要的所有数据,也可能不是所需的格式。它还容易出现质量问题和遗漏条目。

问:你正在为每个月上传的用户内容编写一份报告,并注意到 10 月份的上传量有一个峰值。特别是图片上传的高峰。您可能认为这是什么原因造成的,您将如何测试它?

照片上传数量激增的潜在原因有很多:

  1. 一项新功能可能已经在 10 月份实施,它涉及上传照片,并获得了用户的大量关注。例如,提供创建相册能力的功能。
  2. 同样,有可能之前上传照片的过程不直观,在 10 月份得到了改善。
  3. 可能有一场病毒式的社交媒体运动,包括持续了整个 10 月的上传照片。八月天,但更具扩展性的东西。
  4. 这有可能是因为人们上传了自己穿着万圣节服装的照片。

测试的方法取决于尖峰的原因,但是您可以进行假设测试来确定推断的原因是否是实际原因。

问:给出既不是高斯分布也不是对数正态分布的数据的例子。

  • 任何类型的分类数据都不会有高斯分布或对数正态分布。
  • 指数分布——例如,汽车电池的持续时间或地震发生前的时间。

一定要 订阅 千万不要错过另一篇关于数据科学的文章,包括指南、诀窍和技巧、生活经验等!

问:什么是根本原因分析?如何识别原因和相关性?举例说明

根本原因分析:用于确定问题根本原因的解决问题的方法[5]

相关性衡量两个变量之间的关系,范围从-11因果关系是指第一个事件似乎引发了第二个事件。因果关系主要看直接关系,而相关性可以看直接和间接关系。****

例句:在加拿大,较高的犯罪率与较高的冰淇淋销售额有关,也就是说,它们是正相关的。然而,这并不意味着一个导致另一个。相反,这是因为当室外温度较高时,这两种情况发生得更多。

您可以使用假设检验或 A/B 检验来检验因果关系。

问:举一个例子,中间值比平均值更好衡量

当有许多异常值正或负地扭曲了数据时。

问:给定两个公平的骰子,得分总和为 4 的概率是多少?到 8?

滚动 a 4 有 4 种组合(1+3,3+1,2+2):
P(滚动 a 4) = 3/36 = 1/12

有滚安 8 的组合(2+6,6+2,3+5,5+3,4+4):
P(滚安 8) = 5/36

问:什么是大数定律?

大数定律是一种理论,它指出随着试验次数的增加,结果的平均值将越来越接近期望值。

正面硬币 100,000 次的翻转次数应该接近 0.5 次而不是 100 次。

问:如何计算所需的样本量?

误差幅度公式

您可以使用误差幅度(ME)公式来确定所需的样本量。

  • t/z =用于计算置信区间的 t/z 分数
  • ME =期望的误差幅度
  • S =样本标准偏差

问:当你取样时,你会造成什么样的偏见?

潜在的偏见包括:

  • 抽样偏倚:由非随机抽样引起的有偏倚的样本
  • 覆盖偏差:采样太少的观测值
  • 生存偏差:忽略没有通过选择过程的观察的错误。

问:你如何控制偏见?

你可以做很多事情来控制和减少偏见。两种常见的方式包括随机化,参与者被随机分配,以及随机抽样,每个成员被选中的概率相等。

问:什么是混杂变量?

混杂变量或混杂因素是一种既影响因变量又影响自变量的变量,导致虚假关联,即两个或更多变量相关但无因果关系的数学关系。

问:什么是 A/B 测试?

A/B 检验是假设检验和双样本假设检验的一种形式,用于比较单个变量的两个版本,即控制变量和变量。它通常用于改善和优化用户体验和营销。

查看我的文章,数据科学 A/B 测试的简单指南。

问:只知道性别身高,你如何证明男性平均比女性高?

你可以用假设检验来证明男性平均比女性高。

零假设是男性和女性平均身高相同,而另一个假设是男性的平均身高高于女性的平均身高。

然后,您将收集男性和女性身高的随机样本,并使用 t 检验来确定您是否拒绝空值。

问:医院的感染率高于每 100 人-日感染 1 例被认为是高的。某医院在过去的 1787 人/天中有 10 例感染风险。给出医院是否低于标准的正确片面检验的 p 值。

由于我们查看的是给定时间段内发生的事件数量(感染数量),因此这是一个泊松分布问题。

在一个区间内观察到 k 个事件的概率

零(H0):每人每天 1 例感染
备选方案(H1): >每人每天 1 例感染

k(实际)= 10 次感染
λ(理论)= (1/100)
1787
p = 0.032372 或 3.2372% 计算使用。excel 中的 poisson()或 R 中的 ppois
*

由于 p 值< alpha (assuming 5% level of significance), we reject the null and conclude that the hospital is below the standard.

Q: You roll a biased coin (p(head)=0.8) five times. What’s the probability of getting three or more heads?

Use the General Binomial Probability formula to answer this question:

General Binomial Probability Formula

p = 0.8
n = 5
k = 3,4,5

P(3 头以上)= P(3 头)+ P(4 头)+ P(5 头)= 0.94 或 94%

问:一个随机变量 X 是正态的,均值为 1020,标准差为 50。计算 P(X>1200)

使用 Excel…
p =1-norm.dist(1200,1020,50,true)
p= 0.000159

问:假设出现在公交车站的人数为泊松分布,平均值为 2.5 人/小时。四小时内最多出现三人的概率是多少?

x = 3
平均值= 2.5
4 = 10
*

使用 Excel…

p = poisson.dist(3,10,true)
p = 0.010336

问:艾滋病毒检测的敏感性为 99.7%,特异性为 98.5%。患病率为 0.1%的人群中的受试者获得阳性测试结果。测试的精确度是多少(即他是 HIV 阳性的概率)?

精度方程(PV)

精度=阳性预测值= PV
PV =(0.001 * 0.997)/[(0.001 * 0.997)+((1–0.001)
(1–0.985))]
PV = 0.0624 或 6.24%
*

查看更多关于这个方程的 这里

问:你正在竞选公职,你的民意调查机构调查了数百人。他们中的 60 个人声称他们会投你的票。你能放松吗?

  • 假设只有你和另一个对手。
  • 另外,假设我们想要 95%的置信区间。这使我们的 z 值为 1.96。

置信区间公式

p-hat = 60/100 = 0.6
z * = 1.96
n = 100
这就给了我们一个[50.4,69.6]的置信区间。因此,给定 95%的置信区间,如果你可以接受最糟糕的捆绑情形,那么你可以放松了。否则,你不能放松,直到 100 分中有 61 分说是。

问:盖革计数器在 5 分钟内记录 100 次放射性衰变。找到每小时衰变数的大约 95%的区间。

  • 因为这是一个泊松分布问题,均值=λ=方差,这也意味着标准差=均值的平方根
  • 95%的置信区间意味着 z 值为 1.96
  • 一个标准偏差= 10

因此置信区间= 100 +/- 19.6 = [964.8,1435.2]

问:苏格兰的谋杀率从前年的 115 下降到了去年的 99。这种报道的变化真的值得注意吗?

  • 因为这是一个泊松分布问题,均值=λ=方差,这也意味着标准差=均值的平方根
  • 95%的置信区间意味着 z 值为 1.96
  • 一个标准偏差= sqrt(115) = 10.724

因此置信区间= 115+/- 21.45 = [93.55,136.45]。由于 99 在这个置信区间内,我们可以假设这个变化不是很值得注意。

问:考虑双亲异性恋家庭的流感流行。假设父母中至少有一方患病的概率是 17%。父亲感染流感的概率为 12%,而母亲和父亲都感染该疾病的概率为 6%。母亲感染流感的概率有多大?

利用概率中的一般加法法则:
P(母亲或父亲)= P(母亲)+ P(父亲)— P(母亲和父亲)
P(母亲)= P(母亲或父亲)+ P(母亲和父亲)— P(父亲)
P(母亲)= 0.17+0.06–0.12
P(母亲)= 0.11

问:假设 35-44 岁男性的舒张压(DBPs)呈正态分布,均值为 80(毫米汞柱),标准差为 10。随机选择一个 35-44 岁的人,其 DBP 低于 70 的概率是多少?

因为 70 比平均值低一个标准差,所以取一个标准差左边的高斯分布的面积。

= 2.3 + 13.6 = 15.9%

问:在感兴趣的人群中,9 名男性的样本产生了 1,100cc 的样本平均脑容量和 30cc 的标准偏差。这个新群体的平均脑容量的 95%学生 T 置信区间是多少?

样本的置信区间

假设置信度为 95%,自由度等于 8,t 值= 2.306

*置信区间= 1100±2.306 (30/3)
置信区间= [1076.94,1123.06]

问:在六周的时间里,9 名受试者服用了减肥药。体重的平均差异(随访-基线)为-2 磅。要使 95% T 置信区间的上端点达到 0,体重差异的标准偏差必须是多少?

上限=平均值+ t 得分(标准偏差/sqrt(样本大小))
0 =-2+2.306 (s/3)
2 = 2.306 * s/3
s = 2.601903
因此,标准偏差必须至少约为 2.60,95% T 置信区间的上限才能达到 0。

问:在一项关于急诊室等待时间的研究中,调查人员考虑了一种新的标准的分流系统。为了测试系统,管理员选择了 20 个晚上,并随机分配新的分流系统在 10 个晚上使用,标准系统在其余 10 个晚上使用。他们计算了每晚看医生的平均等待时间(MWT)。新系统的平均 MWT 为 3 小时,方差为 0.60,而旧系统的平均 MWT 为 5 小时,方差为 0.68。考虑与新系统相关的平均 MWT 差异的 95%置信区间估计。假设方差不变。间隔是多少?按此顺序减去(新系统—旧系统)。

查看这里寻找两个独立样本的置信区间的完整教程。

置信区间=平均值+/- t 分数标准误差(见上文)***

均值=新均值-旧均值= 3–5 =-2

给定 df = 18(20–2)和 95%的置信区间,t 得分= 2.101

标准误差= sqrt((0。⁶ 9+0.⁶⁸ 9)/(10+10–2)) sqrt(1/10+1/10)
标准误差= 0.352
*

置信区间= [-2.75,-1.25]

问:为了进一步测试医院的分诊系统,管理员选择了 200 个晚上,并随机分配了一个新的分诊系统用于 100 个晚上,一个标准系统用于其余的 100 个晚上。他们计算了每晚看医生的平均等待时间(MWT)。新系统的平均 MWT 为 4 小时,标准偏差为 0.5 小时,而旧系统的平均 MWT 为 6 小时,标准偏差为 2 小时。考虑与新治疗相关的平均 MWT 降低的假设。相对于这一假设,方差不等的 95%独立组置信区间说明了什么?(因为每组有如此多的观察值,所以用 Z 分位数代替 t 分位数。)

假设我们按照这个顺序减去(新系统—旧系统):

两个独立样本的置信区间公式

均值=新均值-旧均值= 4–6 =-2

z 得分= 1.96 95%的置信区间

st. error = sqrt((0。⁵ 99+ 99)/(100+100–2)) sqrt(1/100+1/100)
标准差= 0.205061
下界=-2–1.96 * 0.205061 =-2.40192
上界= -2+1.96
0.205061 = -1.59808****

置信区间= [-2.40192,-1.59808]

如果您想测试自己的代码,请查看Saturn cloud,一个可扩展、灵活的数据科学平台。******

SQL 练习题

问题 1:第二高的薪水

编写一个 SQL 查询,从 *Employee* 表中获取第二高的薪水。例如,给定下面的雇员表,查询应该返回 *200* 作为第二高的薪金。如果没有第二高的薪水,那么查询应该返回 *null*

**+----+--------+
| Id | Salary |
+----+--------+
| 1  | 100    |
| 2  | 200    |
| 3  | 300    |
+----+--------+**

解决方案 A:使用 IFNULL,OFFSET

  • IFNULL( 表达式,alt ) : ifNULL()如果为 null 则返回指定值,否则返回预期值。如果没有第二高的薪水,我们将用它返回 null。
  • OFFSET : offset 与 ORDER BY 子句一起使用,忽略您指定的前 n 行。这将是有用的,因为你想得到第二排(第二高的薪水)
**SELECT
    IFNULL(
        (SELECT DISTINCT Salary
        FROM Employee
        ORDER BY Salary DESC
        LIMIT 1 OFFSET 1
        ), null) as SecondHighestSalary
FROM Employee
LIMIT 1**

解决方案 B:使用 MAX()

这个查询说选择不等于最高工资的最高工资,相当于说选择第二高的工资!

**SELECT MAX(salary) AS SecondHighestSalary
FROM Employee
WHERE salary != (SELECT MAX(salary) FROM Employee)**

在你下一次面试之前,这里有三个 SQL 概念需要回顾!

问题 2:重复的邮件

编写一个 SQL 查询,在一个名为 *Person* 的表中查找所有重复的电子邮件。

**+----+---------+
| Id | Email   |
+----+---------+
| 1  | a@b.com |
| 2  | c@d.com |
| 3  | a@b.com |
+----+---------+**

解决方案 A:子查询中的 COUNT()

首先,创建一个子查询来显示每封电子邮件的频率计数。然后在计数大于 1 时过滤子查询。

**SELECT Email
FROM (
    SELECT Email, count(Email) AS count
    FROM Person
    GROUP BY Email
) as email_count
WHERE count > 1**

解决方案 B: HAVING 子句

  • HAVING 是一个子句,本质上允许您将 WHERE 语句与 aggregates (GROUP BY)结合使用。
**SELECT Email
FROM Person
GROUP BY Email
HAVING count(Email) > 1**

问题#3:温度上升

给定一个 *Weather* 表,编写一个 SQL 查询来查找与前一个(昨天的)日期相比温度更高的所有日期的 id。

**+---------+------------------+------------------+
| Id(INT) | RecordDate(DATE) | Temperature(INT) |
+---------+------------------+------------------+
|       1 |       2015-01-01 |               10 |
|       2 |       2015-01-02 |               25 |
|       3 |       2015-01-03 |               20 |
|       4 |       2015-01-04 |               30 |
+---------+------------------+------------------+**

解决方案:DATEDIFF()

  • DATEDIFF 计算两个日期之间的差异,用于确保我们将今天的温度与昨天的温度进行比较。

简单地说,该查询是说,选择某一天的温度高于昨天温度的 id。

**SELECT DISTINCT [a.Id](http://a.id/)
FROM Weather a, Weather b
WHERE a.Temperature > b.Temperature
AND DATEDIFF(a.Recorddate, b.Recorddate) = 1**

问题 4:部门最高工资

*Employee*表包含所有员工。每个雇员都有一个 Id,一份薪水,还有一个部门 Id 列。

**+----+-------+--------+--------------+
| Id | Name  | Salary | DepartmentId |
+----+-------+--------+--------------+
| 1  | Joe   | 70000  | 1            |
| 2  | Jim   | 90000  | 1            |
| 3  | Henry | 80000  | 2            |
| 4  | Sam   | 60000  | 2            |
| 5  | Max   | 90000  | 1            |
+----+-------+--------+--------------+**

*Department*表包含公司的所有部门。

**+----+----------+
| Id | Name     |
+----+----------+
| 1  | IT       |
| 2  | Sales    |
+----+----------+**

编写一个 SQL 查询来查找每个部门中工资最高的雇员。对于上面的表,您的 SQL 查询应该返回下面的行(行的顺序无关紧要)。

**+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT         | Max      | 90000  |
| IT         | Jim      | 90000  |
| Sales      | Henry    | 80000  |
+------------+----------+--------+**

解决方案:IN 子句

  • 子句中的允许您在 WHERE 语句中使用多个 OR 子句。例如,country = 'Canada '或 country = 'USA '与 WHERE country IN ('Canada ',' USA ')相同。
  • 在这种情况下,我们希望筛选 Department 表,只显示每个部门的最高工资(即 DepartmentId)。然后我们可以连接两个表,其中 DepartmentId 和 Salary 位于筛选的 Department 表中。
**SELECT
    Department.name AS 'Department',
    Employee.name AS 'Employee',
    Salary
FROM Employee
INNER JOIN Department ON Employee.DepartmentId = Department.Id
WHERE (DepartmentId , Salary) 
    IN
    (   SELECT
            DepartmentId, MAX(Salary)
        FROM
            Employee
        GROUP BY DepartmentId
 )**

问题 5:交换座位

玛丽是一所中学的老师,她有一个表 *seat* 存储着学生的名字和他们对应的座位号。列 id 是一个连续的增量。玛丽想给相邻的学生换座位。

您能编写一个 SQL 查询来为 Mary 输出结果吗?

**+---------+---------+
|    id   | student |
+---------+---------+
|    1    | Abbot   |
|    2    | Doris   |
|    3    | Emerson |
|    4    | Green   |
|    5    | Jeames  |
+---------+---------+**

对于样本输入,输出为:

**+---------+---------+
|    id   | student |
+---------+---------+
|    1    | Doris   |
|    2    | Abbot   |
|    3    | Green   |
|    4    | Emerson |
|    5    | Jeames  |
+---------+---------+**

注: 如果学生人数为奇数,则无需换最后一个座位。

解决方案:CASE WHEN

  • 想一个例子,当 THEN 语句类似于代码中的 IF 语句时。
  • 第一个 WHEN 语句检查是否有奇数行,如果有,确保 id 号不变。
  • 第二个 WHEN 语句为每个 id 加 1(例如 1,3,5 变成 2,4,6)
  • 类似地,第三个 WHEN 语句将每个 id 减 1(2,4,6 变成 1,3,5)
**SELECT 
    CASE 
        WHEN((SELECT MAX(id) FROM seat)%2 = 1) AND id = (SELECT MAX(id) FROM seat) THEN id
        WHEN id%2 = 1 THEN id + 1
        ELSE id - 1
    END AS id, student
FROM seat
ORDER BY id**

多方面的

问:如果有 8 个重量相等的弹珠和 1 个稍重的弹珠(总共 9 个弹珠),需要称重多少次才能确定哪个弹珠最重?

作者创建的图像

需要称重两次(见上文 A 和 B 部分):

  1. 你将九个弹珠分成三组,每组三个,称其中两组的重量。如果天平平衡(选择 1),你知道重的弹球在第三组弹球中。否则,您将选择权重更大的组(选项 2)。
  2. 然后你将练习同样的步骤,但是你将有三组一个弹球,而不是三组三个。

问:改变基本会员费会对市场产生什么影响?

我对这个问题的答案没有 100%的把握,但我会尽力而为!

让我们举一个主要会员费上涨的例子——有两方参与,买方和卖方。

对于买家来说,提高会员费的影响最终取决于买家需求的价格弹性。如果价格弹性很高,那么给定的价格上涨将导致需求大幅下降,反之亦然。继续购买会员费的买家可能是亚马逊最忠诚和最活跃的客户——他们也可能更加重视 prime 产品。

卖家将受到打击,因为现在购买亚马逊一篮子产品的成本更高了。也就是说,一些产品将受到更严重的打击,而其他产品可能不会受到影响。亚马逊最忠实的顾客购买的高端产品可能不会受到太大影响,比如电子产品。

问:如果 iOS 上 70%的脸书用户使用 Instagram,但 Android 上只有 35%的脸书用户使用 Instagram,你会如何调查这种差异?

有许多可能的变量会导致这种差异,我将检查一下:

  • iOS 和 Android 用户的人口统计数据可能会有很大差异。例如,根据 Hootsuite 的调查,43%的女性使用 Instagram,而男性只有 31%。如果 iOS 的女性用户比例明显高于 Android,那么这可以解释这种差异(或者至少是部分差异)。这也适用于年龄、种族、民族、地点等
  • 行为因素也会对差异产生影响。如果 iOS 用户比 Android 用户更频繁地使用手机,他们更有可能沉迷于 Instagram 和其他应用程序,而不是那些在手机上花费时间少得多的人。
  • 另一个需要考虑的因素是 Google Play 和 App Store 有什么不同。例如,如果 Android 用户有明显更多的应用程序(和社交媒体应用程序)可供选择,这可能会导致用户的更大稀释。
  • 最后,与 iOS 用户相比,用户体验的任何差异都会阻止 Android 用户使用 Instagram。如果这款应用对安卓用户来说比 iOS 用户更容易出错,他们就不太可能在这款应用上活跃。

查看更多脸书数据科学面试问题点击这里

问:每个用户的点赞数和在一个平台上花费的时间在增加,但用户总数在减少。它的根本原因是什么?

一般来说,你会想从面试官那里获得更多的信息,但是让我们假设这是他/她唯一愿意提供的信息。

关注每个用户的点赞数,有两个原因可以解释为什么这个数字会上升。第一个原因是,随着时间的推移,用户的平均参与度普遍提高了——这是有道理的,因为随着使用该平台成为一种习惯性做法,久而久之的活跃用户更有可能成为忠实用户。每个用户点赞数会增加的另一个原因是分母,即用户总数,在减少。假设停止使用该平台的用户是不活跃的用户,也就是参与度和点赞数低于平均水平的用户,这将增加每个用户的平均点赞数。

上面的解释也适用于在平台上花费的时间。随着时间的推移,活跃用户变得越来越活跃,而很少使用的用户变得不活跃。总体而言,参与度的增加超过了参与度很低的用户。

更进一步说,有可能“参与度低的用户”是脸书能够检测到的机器人。但随着时间的推移,脸书已经能够开发出识别和删除机器人的算法。如果以前有大量的机器人,这可能是这种现象的根本原因。

问:脸书发现赞数每年增长 10%,为什么会这样?

给定年份的总赞数是用户总数和每个用户的平均赞数的函数(我称之为参与度)。

用户总数增加的一些潜在原因如下:由于国际扩张而获得的用户以及随着年龄增长而注册脸书的年轻群体。

参与度增加的一些潜在原因是用户对应用程序的使用增加,用户变得越来越忠诚,新的特性和功能以及用户体验的改善。

问:如果我们测试产品 X,你会看什么标准来确定它是否成功?

决定产品成功的标准取决于商业模式和企业试图通过产品实现的目标。《精益分析》一书展示了一个很好的框架,人们可以用它来确定在给定场景中使用什么指标:

精益分析框架

问:如果一个项目经理说他们想把新闻订阅的广告数量增加一倍,你如何判断这是不是一个好主意?

您可以通过将用户分成两组来执行 A/B 测试:一组是广告数量正常的对照组,一组是广告数量翻倍的测试组。然后,您将选择指标来定义什么是“好主意”。例如,我们可以说零假设是广告数量翻倍会减少花在脸书上的时间,另一个假设是广告数量翻倍不会对花在脸书上的时间有任何影响。但是,您可以选择不同的指标,如活跃用户数或流失率。然后,您将进行测试,并确定拒绝或不拒绝 null 的测试的统计显著性。

问:什么是:提升、KPI、稳健性、模型拟合、实验设计、80/20 法则?

提升:提升是针对随机选择目标模型测量的目标模型的性能的度量;换句话说,lift 告诉你你的模型在预测事物方面比没有模型时好多少。

KPI: 代表关键绩效指标,这是一个可衡量的指标,用于确定公司实现其业务目标的情况。错误率。

健壮性:健壮性通常是指系统处理可变性并保持有效的能力。

模型拟合:指模型拟合一组观察值的程度。

实验设计:也称为 DOE,是在假设反映变量的条件下,旨在描述和解释信息变化的任何任务的设计。[4]本质上,实验的目的是根据一个或多个输入(独立变量)的变化来预测结果。

80/20 法则:又称帕累托原理;80%的结果来自 20%的原因。80%的销售额来自 20%的顾客。

问:定义质量保证,六西格玛。

质量保证:一项或一组活动,旨在通过减少错误和缺陷来维持期望的质量水平。

六西格玛:一种特定类型的质量保证方法,由一套用于过程改进的技术和工具组成。六西格玛流程是指所有结果的 99.99966%没有缺陷。

参考

1中心极限定理,定义及例题步骤简单如何统计**

[2] 权力,统计,百科

[3] 人择原理,百科

[4] 实验设计,百科

[5] 根本原因分析,百科

感谢阅读!

如果您喜欢这篇文章,请务必点击 订阅此处 千万不要错过另一篇关于数据科学指南、技巧和提示、生活经验等的文章!

不确定接下来要读什么?我为你挑选了另一篇文章:

**** [## 超过 100 个数据科学家面试问题和答案!

来自亚马逊、谷歌、脸书、微软等公司的面试问题!

towardsdatascience.com](/over-100-data-scientist-interview-questions-and-answers-c5a66186769a)

或者你可以查看我的介质页面:

[## 特伦斯·申—中号

阅读特伦斯·申在媒体上的文章。数据科学@ KOHO,SaturnCloud |理学硕士,MBA |…

terenceshin.medium.com](https://terenceshin.medium.com/)

特伦斯·申

使用 Python 的整体设备效率

原文:https://towardsdatascience.com/overall-equipment-effectiveness-with-python-fb34ccc6127b?source=collection_archive---------42-----------------------

面向工业工程师的 Python

测量制造业生产率

图片由 Marek Szturc 拍摄,可在 Unsplash 获得

整体设备效率

总体设备效率(OEE)是监控和提高工艺效率的一种行之有效的方法;它被认为是一种诊断工具,因为它不提供给定问题的解决方案。OEE 是一个关键的过程指标,用于衡量有效性以及与有效机器性能的偏差。它在全面生产维护(TPM)和精益计划中被广泛使用,用于定位低效率的来源和量化低效率的程度。

OEE 的目标是减少六大设备损失:设备故障、设置和调整、轻微停工、减速、启动报废和产品报废。这些损失分为三类:

  • 可用性:考虑可用性/时间损失,包括所有与计划外停机(如设备故障、材料短缺)和计划内停机(如转换时间)相关的事件。可用性衡量机器或单元运行时间占总理论可用时间的比例。
  • 性能:考虑性能/速度损失,包括所有阻止机器或单元以最大/最佳速度运行的因素(例如,慢循环、小停止)。性能衡量在给定的运行中生产的单位占可能生产的单位总数的比例。
  • 质量:考虑质量 损失,包括导致不符合客户质量标准和规格的缺陷单元的所有因素(如返工、报废、缺陷)。质量衡量无缺陷单位占生产的总单位的比例。

OEE 计算

OEE 可以通过其三个组成部分相乘得到:

OEE 公式

它被分解为:

OEE 配方成分

其中:

  • =总可用时间
  • B=运行时间
  • C =生产能力
  • D =实际产量
  • E =产品产量(与实际产量相同)
  • F =实际良品(即产品产量减去废品)

通过测量 OEE 和潜在损失,公司和组织可以深入了解如何系统地改进制造流程,从而消除浪费。

OEE 作为基准和基线

作为基准,OEE 可用于将给定制造流程的性能与行业标准、相似(或相同)制造流程或同一制造流程不同班次的结果进行比较。

作为基线,OEE 可用于监控和跟踪给定制造流程的改进和废物减少。

什么被认为是“好的”OEE?

  • 100% —完美生产:没有停机时间,没有废料,产品以最高速度生产
  • 85% —离散制造商的世界级水平:这是一个合适的长期目标
  • 60% —典型的离散制造商:表示有很大的改进空间
  • 40% —低:常见于开始跟踪和改善制造绩效的公司

在下面的示例中,让我们获取一台机器的 OEE,该机器的总可用时间为 100 小时,但由于某些物料短缺和意外维护而运行了 85 小时,该机器的最大生产率为每小时 10 件,但在运行中生产了 700 件,其中 50 件有缺陷。让我们来看看 Python 代码!

综合效率图

在前一示例中分析的机器的 OEE 为 65%,根据之前解释的 OEE 基准,可以认为该机器的 OEE 高于标准值(即 60%),但仍低于世界级 OEE(即 85%)。

任何旨在提高 OEE 和减少特定流程浪费的公司或组织的真正挑战不是提高 OEE 本身,而是随着时间的推移保持 OEE。

把 OEE 想象成赛车的速度。尽管 F1 的一些赛车速度可以达到 220 英里/小时(约 354 公里/小时)或更高,但发动机在某些时候会出现故障(即车手无法让赛车长时间保持最大速度)。生产机器和设备也是如此:由于大多数情况下 100%的 OEE 是不可能维持的,因此 85%或以上的 OEE 仍然被认为是世界级的 OEE。

总结想法

OEE 是生产设施中的运营经理跟踪给定制造过程性能的一个很好的工具。这是一个必须不断监控的指标,以确定其组成部分中的机会领域,从而在必要时制定和执行行动计划。

有效的生产计划和调度,以及准确的预防性维护计划,可以导致有效运行时间( B )的增加,这将提高 OEE 可用性部分。对操作人员进行充分的培训可以通过减少小停车来提高实际产量( D ),从而提高 OEE 性能。最后,在流程改进项目中使用精益和六西格玛工具可以减少最终结果的浪费和可变性( F ),从而提高 OEE 质量。

Python 代表了一种简单而有效的工具,只需几行代码就能计算出流程的 OEE。同样,它允许获得 OEE 图,以图形化方式显示其组成部分和损失,从而显示过程中的实际附加值百分比。

如果你觉得这篇文章有用,欢迎在GitHub上下载我的个人代码。你也可以直接在 rsalaza4@binghamton.edu 给我发邮件,在LinkedIn上找到我。有兴趣了解工程领域的数据分析、数据科学和机器学习应用的更多信息吗?通过访问我的媒体 简介 来探索我以前的文章。感谢阅读。

——罗伯特

克服 Apache Spark 最大的痛点

原文:https://towardsdatascience.com/overcoming-apache-sparks-biggest-pain-points-b374cebcf6a4?source=collection_archive---------7-----------------------

理解大数据

关于 Spark 最具挑战性的方面以及数据科学家和工程师如何克服它们的高级指南

卡姆拉奈季诺夫创作的电脑照片—www.freepik.com

大约 6 年前,我第一次使用 Apache Spark,当时,它是“大数据”分析领域的开端。毫无疑问,掌握 Spark 是任何想成为数据科学家或数据工程师的人的职责;毕竟,除此之外,如何利用海量数据和分布式 CPU 计算来创建尽可能最好的机器学习模型?

如果那时我可以看到 2020 年的未来,我可能会有点惊讶,很大一部分 ML/AI 从业者仍然不使用 Spark 或只将其用于数据工程,而不是机器学习。一部分自然是因为兴趣部分转移到面向 GPU,而不是面向 CPU 的机器学习技术,尤其是深度学习。但是对于图像和自然语言处理之外的大多数应用程序,面向 CPU 的技术的有用性是毋庸置疑的,令人惊讶的是许多数据科学家仍然严重依赖单机 ML 工具,如 Scikit-learn 以及 XGBoost 和 LightGBM 的非分布式版本。

就我个人而言,我觉得这很遗憾,因为如果使用得当,Spark 对于任何处理数据的人来说都是一个非常强大的工具,可以帮助我们避免浪费时间来找出如何将大型数据集放入内存和处理器,并允许我们完全控制数据分析工作流,包括提取数据、生成模型以及将模型部署到生产和测试中。

在 Apache Spark 上举办了研讨会并指导了几十名数据科学家和工程师,我能够理解用户在使用该工具时通常面临的最大困难,为什么会发生这些问题以及如何克服它们。这份由两部分组成的指南是为那些不仅想使用 Spark,而且想真正理解 Spark 的内部原理以解决复杂问题并生成高性能、稳定代码的人准备的。

注意,我假设读者已经对 Spark 有了基本的了解,例如,什么是 Spark 驱动程序和执行器,数据集被划分为分区,什么是懒求值以及 Spark 的基本数据结构。

1 部分:Spark 的分区和资源管理

挑战

与单处理器的 vanilla Python(例如 Pandas)不同,在 Pandas 中,内部处理的细节是一个“黑盒”,使用 Spark 执行分布式处理需要用户做出大量决策:

  • 每个数据集使用多少个分区
  • 何时对数据集进行重新分区
  • 要用多少个 Spark 执行器,给它们分配多少内存和多少内核?
  • 火花驱动器分配多少内存?

让事情变得更复杂的是:

  • 一个典型的处理流水线将涉及多个操作,每个操作可能会产生大小显著不同的数据集,这使得不太可能找到适合整个数据流水线的单一参数集。
  • 某些 Spark 操作会自动改变分区的数量,这使得用户更难跟踪每个数据集使用了多少分区。例如,连接操作会将输出数据集的分区数量更改为在spark.sql.shuffle.partitions配置参数中指定的数量。

知道什么是重要的

关于分区和资源管理的每个决定的含义可以总结如下:

  1. 如果我们为一个特定的表使用太多的分区,由于优化和并行化开销等多种原因,可能会导致资源的缓慢/浪费,因为Spark 作为单个分区处理一定量的数据所需的 CPU 总量比作为多个分区处理要快得多。即使在同一个物理服务器中处理分区时也是如此;
  2. 如果我们为一个特定的表使用太少的分区,这可能会导致资源的缓慢/浪费,因为许多执行器在处理完他们的分区 s 后将会“空闲”,等待其他分区完成处理;
  3. 如果我们过于频繁地执行重新分区,可能会由于改组而导致速度变慢/浪费资源,改组包括在执行器之间重新安排分区。洗牌是一种高成本的操作,无论是从处理还是内存方面来说,它都严重限制了我们稍后将讨论的 Spark 的处理优化;
  4. 如果我们没有使用足够的重新分区,可能会由于不平衡分区导致的执行器过载和空闲而导致速度变慢/浪费资源;即非常大的分区可能会导致执行器在内核和内存方面资源不足,并使其他执行器在等待分区处理时处于空闲状态
  5. 如果我们在每个执行器上使用太多的内核,由于并行化水平低于预期,可能会导致速度变慢/资源浪费。当执行器控制多个内核时,它会尝试创建多个线程来同时处理多个分区,从而允许线程共享内存中的变量。然而,这种并行化并不完美,可能会受到 I/O 操作的限制(例如写入 HDFS 或其他分布式数据存储)。通常,即使用户为每个执行器分配了多个内核,也会使用单个内核。此外,由于一个执行器只能在一个物理服务器上运行,因此不可能在执行器中分配用户请求的所有内核。用户可以通过 Spark UI 监控执行器有效使用的内核数量;
  6. 如果我们在每个执行器上使用的内核太少,由于创建每个执行器所需的开销,可能会导致速度变慢/资源浪费。由于 Spark 知道同一个执行器中的内核肯定在同一个物理服务器中,因此它可以优化处理,使它们之间的并行化开销比跨执行器的并行化开销小得多。

为了处理流水线的多个步骤中分区和资源需求的变化,以及跟踪每个中间数据集的分区数量的困难,有两种策略可以单独使用或组合使用:

  • 当计算资源在用户池中共享或用户同时运行多个作业时,通过spark.dynamicAllocation.maxExecutorsspark.dynamicAllocation.enabled参数激活执行器的动态分配可以大大减少 Spark 计算资源的闲置;
  • 将一个大型处理任务分割成多个较小的任务,每个任务的数据集大小变化较小,这使我们能够更好地调整配置参数和每个步骤的分区数量。对于每一个更小的任务,我们也可以适当地设置参数spark.default.parallelismspark.sql.shuffle.partitions,以避免不断的重新分区。像 Airflow 这样的管道工具对于设置和部署由较小作业组成的复杂数据任务非常有用。

第 2 部分:Spark 的不变性、惰性评估和执行计划优化

挑战

Spark 用户首先学到的两件事是不变性和惰性求值的概念。不变性意味着 Spark 数据集不能被修改;对数据集的每个操作都会创建一个新的数据集。惰性评估基于数据集上有两种操作的事实:

  • 转换产生一个新的 Spark 数据集作为输出(Spark 具有不变性,因此它永远不能修改现有的数据集,只能创建新的数据集);
  • 动作将 Spark 数据集作为输入,但会产生 Spark 数据集以外的东西,比如写入存储、创建局部(非 Spark)变量或在用户 UI 中显示某些东西。

转换与行动说明(图片由作者提供)

当流程调用转换操作时,这会导致创建一个不可变的、内存中的“执行计划”,该计划描述了如何基于其他数据集生成数据集。但是,此时不会生成实际数据。只有当一个动作操作被调用时,Spark 才会评估输入的执行计划,以生成计算输出所需的数据。因为输入本身可能有依赖于其他数据集的执行计划,所以这些计划被递归地评估,并且该过程继续。

如果在某个时刻触发了另一个动作,要求再次重新创建相同的中间数据集,则该过程重复进行;重新创建执行计划,并且需要再次执行执行计划的所有步骤。为了防止这种情况发生,用户可以“保存”中间数据集。当通过触发执行计划创建“持久化”数据集时,数据集将被保存到分布式内存中(或一些配置的分布式存储,如果内存中没有足够的空间),它将保留在那里,直到手动“取消持久化”或直到 Spark 的垃圾收集器识别出数据集“超出范围”(不能由运行的代码访问)。

许多 Spark 用户没有深入思考不变性和惰性评估的概念及其实际后果,认为知道我们应该“持久化”一个将被多次使用的中间数据集就足够了,防止重复计算不止一个操作需要相同的中间数据集。

然而,事实是,很好地利用不变性和懒惰评估远不止于此。事实上,它们与一个鲜为人知的方面密切相关,即通过 Spark Catalyst 完成的执行计划优化。不深入理解这些概念很容易导致缓慢、不稳定的 Spark 处理,以及用户在调试和解密神秘的错误消息上浪费大量时间。

知道什么是重要的

  • Spark 在分区级别执行转换,而不是数据集级别

我们可能会有一个错误的印象,即调用一个操作会导致该操作之前的一系列转换被逐个执行,每个步骤都会生成一个中间数据集。如果是这样的话,如果数据帧 2 是通过转换数据帧 1 生成的,Spark 将首先创建数据帧 1,然后创建数据帧 2,就像我们使用 Pandas 时的情况一样。

但事情没那么简单。当一个动作被调用时,所有必要的执行计划实际上被合并成一个执行计划,除了洗牌的情况,每个分区的处理都是独立完成的。这意味着转换是在分区级别完成的,而不是数据集级别。因此,对于一个分区,Spark 可能仍在生成数据帧 1,而对于另一个分区,Spark 可能已经在从数据帧 1 生成数据帧 2。例如,我们可能有如下情况:

(图片由作者提供)

从性能角度来看,这是一种强大的机制,因为它防止处理器和内存浪费,即在移动到下一个中间数据集之前等待整个中间数据集生成。分区级转换的另一个优点是,我们将在下一节看到,它允许 Spark 更好地优化处理。

  • Spark 优化执行计划,执行计划越大,优化效果越好

Spark 催化剂无疑是 Spark 最有价值的特性之一。,因为实现高效的分布式处理比实现高效的单核或单内存处理要复杂得多。本质上,Catalyst 将优化执行计划以最大化分布式性能。例如,在 Spark 中,一次在同一行中执行多个操作,然后移动到下一行,以此类推,比在同一列中执行多个操作,然后移动到下一列要快得多,因此执行计划会相应地得到优化。

需要考虑的一个重要因素是单个大型执行计划比多个小型执行计划有更大的优化潜力。类似地,通过利用转换是在分区级别而不是数据集级别完成的这一事实,Spark 可以为相同的分区组合多个转换,并优化它们以获得更好的性能。以我们之前的例子为例,优化后的结果如下所示:

(图片由作者提供)

  • Spark 的惰性求值和分区级转换使得调试更加复杂

然而,从开发/调试的角度来看,如果发生了错误或者出现了性能瓶颈,惰性评估与分区级转换相结合,会使用户很难准确地找出是哪个处理步骤导致了错误或瓶颈。毕竟,Spark UI 只会告诉用户哪个触发操作导致了错误或瓶颈,而不是实际的转换。

解决方案是“强制”Spark 每次生成一个完整的中间数据集,方法是插入多个persist()语句,后跟动作,如count()take()。然而,由于前面提到的处理器/内存浪费和缺乏优化,这些代码的效率非常低,所以最好只在开发目的(而不是生产)和临时的基础上使用这种解决方案。

  • 太大/太多的执行计划也会成为问题

我观察到的一件事是,执行计划并不总是与操作的数量成线性关系,有时是多项式或指数关系。由于执行计划存储在 Spark 驱动程序的内存中(与存储在 Spark 执行器内存中的持久化对象不同),这可能会导致 Spark耗尽驱动程序内存,或者由于 Spark Catalyst 的优化而变得极其缓慢。这有点讽刺,因为 Catalyst 应该在部署到 Spark 执行器时使代码运行得更快;但是在火花驱动器中运行的催化剂会成为处理本身的瓶颈。

对于具有数千列的数据帧来说尤其如此,在这种情况下,我们需要跨所有列执行多个操作。Spark 的不变性使情况变得更糟,因为它不断地有新的执行者计划实例被 Catalyst 创建和评估。

坚持可能是处理这个问题的有效策略。它将消除在生成持久化的中间数据集之前创建执行器计划的新实例的需要,以及防止 Catalyst 在创建数据集之前试图优化执行计划。

然而,对于复杂、长的管道,执行计划变得非常庞大,甚至不频繁的持久化也不能防止由优化或驱动程序耗尽内存导致的缓慢,因为持久化可以防止大型执行计划的多个实例化,但不能首先防止它们的创建。此外,过多的持久化本身也会成为一个问题,因为它会占用分布式内存和存储空间。虽然经常尝试去持久化和/或尝试构建代码以最大化垃圾收集肯定有所帮助,但这是一项艰巨的工程任务,并不能总是防止资源耗尽。

一种解决方案是名为检查点的技术,它包括从用户定义的适当存储系统中保存和加载中间结果。当有效使用时,检查点既可以防止执行计划规模的巨大增长,又可以防止 Spark 的分布式资源与持久化对象发生冲突。

另一个解决方案,已经提到过,是将一个大的处理任务分割成更小的任务。这样,执行计划就不会变得太大,也不需要担心驱动程序或执行程序内存中的剩余对象。

结论

当然,关于 Spark,本文还会涉及更多内容,例如,如何构建代码以提高 Catalyst 优化的质量。但是我希望这篇文章可以帮助一些人克服 Spark 的困难,并利用它在数据工程和机器学习方面的非凡能力和多功能性。虽然 Spark 仍然是一个具有挑战性的工具,但我可以诚实地证明,在我使用它的 6 年时间里,Databricks 和开源社区如何在用户友好性和灵活性方面大大改进了它。

如果你想学习如何使用 Spark 和 Apache Hadoop YARN 并行运行多个分布式作业,比如模型训练的多个实例,查看我的另一篇文章

克服确认偏差

原文:https://towardsdatascience.com/overcoming-confirmation-bias-during-covid-19-51a64205eceb?source=collection_archive---------5-----------------------

为什么确认偏差是数据科学的克星,以及如何与之对抗

下面是文章的音频版本,由作者为你朗读。

让我们来谈谈一种令人讨厌的心理效应,这种效应可能会破坏你有效应对每天涌入的信息的能力: 确认偏差

让你陷入麻烦的并不是你不知道的事情。你确定的事情并不是这样的。马克·吐温。

这是什么?

确认偏差 是以确认或强化个人先前信念的方式搜索、解释、偏好和回忆信息的倾向。”—维基百科

是啊,但这是什么?

这个:

保罗 J 插图,经许可使用。

如果你热衷于研究心理学,让我们将确认偏差与其他一些现象区分开来:

  • 确认偏差:你的已有观点改变了你对信息的感知方式。
  • 一厢情愿的盲目:你的利己主义改变了你对信息的感知方式,尤其是在道德决策的背景下。(不要和 故意视而不见 混淆),这是一个来自法律的术语。)
  • 滤泡指智能隔离在线回音室。如果一种算法被设计成对你喜欢的内容进行优先排序,并且你倾向于喜欢来自已经同意你的人的内容,那么你就不太可能接触到可能改变你想法的内容。**

我不会用如何从回音室里爬出来的建议来烦你——你已经全都听过了。"某事某事……寻求……某事……与你意见相左的人的智力训练。"对吧?没错。

图片由作者提供。

一厢情愿的盲目是一个棘手的问题,因为这是一个相对较新的理论,没有太多关于如何克服它的研究。

我最喜欢引用的关于一厢情愿的盲目的话,在我们称之为一厢情愿的盲目之前。

不过,确认偏差自 20 世纪 60 年代以来就一直存在,所以让我们来关注一下这个问题。

过滤泡沫是关于扭曲的信息,而确认偏差是关于扭曲的感知。

****确认偏差不是指你的社交媒体反馈与自身过于一致的情况。这要微妙得多:即使你接触到与你的观点不一致的信息,你也可能不会接受。你可能会记错。你可能会找到忽略它的理由。你将继续挖掘,直到你看到的数字是你想看到的。头脑就是那样滑稽。

确认偏差意味着我们都可以看到同一个数字,并对它有不同的理解。事实不再仅仅是事实。

换句话说,确认偏差数据科学的死对头,因为它意味着一个事实不再仅仅是一个事实,无论你投入多少数学和科学去得到它。你和我可以看着同一个数字,然后感知到不同的。努力让自己接触更好的信息来源并不足以解决一个始于你眼前的问题。

确认偏差是数据科学的宿敌。

在信任自己的大脑时,你应该小心。(那个叛徒!)如果你从一个强烈的无知的观点开始,去搜寻信息,你很可能在完成后以同样的观点结束。何必呢?除非你预先对抗确认偏见并且按照正确的顺序做事,否则你对数据的尝试注定是浪费时间。

有兴趣了解更多关于扭曲的数据感知吗?见我关于 apophenia 的文章。图片:维基百科

确认偏差和新冠肺炎

一言以蔽之:如果你对新冠肺炎有强烈的看法,然后你去寻找支持它们的证据,你会认为你看到了……不管那些看法有多古怪。你也将更难吸收指向相反方向的证据。

如果你感到害怕,你去寻找让你感觉更好的信息,确认偏见反而会让你感觉更糟。

更糟糕的是,每当你感到恐慌,并试图用一个愉快放松的互联网会话来抚慰自己时,你很可能会找到更多恐慌的理由。

快速恐慌不是一种美德——通常会适得其反。

虽然恐慌会让你肾上腺素激增— “确认偏差:一个奇怪的技巧来提高你的家庭健身计划”—但它不会帮助你做出更好的决定。这通常会适得其反,削弱你清晰思考的能力,对你的情绪或应对压力的能力没有任何好处。无论你的处境有多糟糕,冷静的现实主义会比恐慌更好地为你服务。

如何对抗确认偏差

结果是,一个强有力的开始意见会搞乱你的决策和你的心情。幸运的是,有四种简单的方法可以对抗确认偏见:

  • 不要固执己见。
  • 强调决定,而不是意见。
  • 专注于你能控制的事情。
  • 改变获取信息的顺序。

图片由作者提供。

保持你的观点宽松

这一条可能说起来容易做起来难,尤其是如果你已经在头条新闻中煎熬了一段时间,但是保持开放的心态,不要太认真地对待你的观点,这是一个很好的智力练习,即使它们是基于大量的数据(嗨, Bayesians )。

这里还有一个值得了解的偏见:过度自信偏见(一种根深蒂固的偏见,在这种偏见中,一个人对自己判断的主观信心确实大于这些判断的客观准确性,尤其是在信心相对较高的时候。”—维基百科)是啊,但是是什么呢?你可以通过养成不严格坚持自己观点的习惯来减轻压力。**

松散地持有你的观点会减少他们扭曲你的感知的能力。

我所知道的最好的决策者是适应性强的。他们有接受新信息并承认错误的技能。在你跑去钦佩那些坚定不移地做出判断的领导者之前(坚定而忠诚,对吗?),花点时间从心理学家的角度来看他们:他们受到确认偏见的阻碍,无法恰当地处理新信息(或者他们是出色的演员)。

如果你渴望抑制自己的自大倾向,那就从科学家的书里取一页吧。有没有注意到应用科学的研究论文充满了警告,谦逊地提醒读者那些可能使他们的结论无效的未知情况?这是一个不错的目标标准。

强调决策,而不是意见

在我看来,呃,放松你的观点对你的情绪和决定的控制的最好方法是养成先做决定的习惯。如果一个观点在森林里消失了,并且没有任何行动受到它的影响,这个观点重要吗?

通过我们的决定——我们的行动——我们影响着周围的世界。

想象一下,我相信尼斯湖水怪是真的。如果我的信念不以任何方式影响我的决定——与世界的互动,这有什么害处呢?另一方面,如果我的信念确实影响了我的行为(有意识地或下意识地),那么也许我应该在它会影响的行为的背景下评估我的观点。这涉及到在发表意见之前思考行动(按重要性顺序),然后作为第二步形成测试假设。我的文章是这里的。

图片由作者提供。

“这些信息会让我采取不同的行动吗?”

每当你发现自己收到新信息时,记得问问自己:“这是可操作的吗?”如果是,它会影响您的哪些决定?

关注你能控制的事情

谈到新冠肺炎,我们许多人已经发现我们的决策受到新规则的约束。如果我们不花一点时间去认识到我们一直担心的一些决定已经不再摆在桌面上,我们会在没有作用的意见上浪费不必要的精力。

难道你不想专注于对那些在你控制之下的事情做出决定和计划吗?(或者把那段时间用在给你带来快乐的活动上?)

例如,在 2020 年初的纽约(是的,我知道)我这个月不再有去剧院的选择。无论我对在拥挤的空间里会如何影响我的健康有什么看法——这是我从阅读世卫组织的出版物中粗略得出的看法——我都无法将这些信息作为输入做出决定。

这个月,即使我想,我也不再有在人群中的选择。这个决定不在讨论范围内。

也许我最好将我的认知努力转移到其他地方,转向对我来说已经摆在桌面上的决定,例如是否远程帮助(是的),是否在线订购卫生纸(不,这是我所有教科书的目的),以及是否投入大量精力拍摄关于数据科学的家庭视频系列(也许不是,除非我已经放在 YouTube 上的视频获得更多流量)。

埃德温·胡珀在 Unsplash 上拍摄的照片

远离那些你无法影响的事情并不是对无知的呼唤。比较下列使用你精神能量的方法:

  1. 担心你的市长正在努力应对的一个决定,同时努力思考如果你处在他们的位置,你会怎么做。
  2. 从你所做的决定的角度来考察你的市长的决策技巧(例如,投票支持/反对市长连任)。
  3. 考虑你应该采取哪些行动——如果有的话——来回应(或准备)你的市长正在选择的每一个可能的选项。
  4. 决定你是否应该尝试运用你自己的影响力/努力去影响市长的决定或其潜在后果。

其中,(2)-(4)是更有用的观点(除非你的兴趣是学术),而(1)是对决策学生的良好实践()“如果我是负责人,我会如何做出这个决定,我能在这里学到什么技能?”但对于情绪失控的人来说,这并不是一个有效的利用空间的方法。

区别不在于你寻找什么信息。这是你寻求它的方式。作为奖励,你可能会发现你能控制的比你意识到的要多。

请注意,这种差异不是消息灵通与否的问题。区别在于你是否明确地将你的精力集中在该由你做出(或影响)的决定上。纠结于别人的决定很可能会让你感到无能为力,被模糊的信息淹没(尤其是当负责决策的人比你掌握更多信息的时候)。如果你发现自己在压力大的时候采取了(1)这样的观点,转向(2)、(3)或(4)可能会给你带来一些缓解。作为奖励,你可能会发现你能控制的比你意识到的要多。

改变获取信息的顺序

既然你已经把注意力集中在行动和决定上了,是时候揭示大笑话了:消除确认偏见的最有效方法是在你寻找信息之前*计划好你的决策。*****

在你看到球落在哪里后,用一种防止你移动球门柱的方式来框定你的决策。

换句话说,重要的是,在你看到球落地的地方后,要以一种防止你移动球门柱的方式来框定你的决策。好奇想了解更多?我有一篇一般的文章加一篇循序渐进的新冠肺炎决策指南帮你出。

现在是完全不同的东西…

感谢阅读!如果你在这里玩得开心,并且对人工智能感兴趣,这里有一个初学者友好的介绍供你娱乐:

在这里欣赏整个课程播放列表:bit.ly/machinefriend

喜欢作者?与凯西·科兹尔科夫联系

让我们做朋友吧!你可以在 TwitterYouTubeSubstackLinkedIn 上找到我。有兴趣让我在你的活动上发言吗?使用此表格取得联系。

过量饮食评论[1312.6229]

原文:https://towardsdatascience.com/overfeat-review-1312-6229-4fd925f3739f?source=collection_archive---------29-----------------------

过量进食的理论综述

演职员表:https://en.wikipedia.org/wiki/Object_detection

我已经计划阅读主要的物体探测论文(虽然我已经粗略地阅读了它们中的大部分,但我会详细地阅读它们,好到足以写一篇关于它们的博客)。这些论文与基于深度学习的对象检测相关。随时给建议或询问疑惑会尽我所能帮助大家。我将在下面写下每篇论文的 arxiv 代码,并在下面给出博客(我写的时候会不断更新)和他们论文的链接。任何从这个领域开始的人都可以跳过许多这样的论文。当我读完所有的论文后,我还会写下它们的优先级/重要性(根据理解主题的必要性)。
我写这篇博客是考虑到和我相似并且仍在学习的读者。万一我犯了任何错误(我将通过从各种来源(包括博客、代码和视频)深入理解论文来尽量减少错误),任何人都可以随意地在博客上强调它或添加评论。我已经提到了我将在博客末尾涉及的论文列表。

我们开始吧:)

Overfeat 论文探讨了三个计算机视觉任务分类,定位,检测分别按照难度递增的顺序。每个任务都是下一个任务的子任务。所有任务都使用一个框架和一个共享的功能学习库来解决。

分类

用于分类的架构类似于 alexnet,但有一些改进。作者准备了两种不同的架构:快速和准确。与 alexnet 架构的不同之处包括没有对比度归一化、汇集区域不重叠、由于步幅较小而具有较大的第一层和第二层特征地图。我将添加显示快速和精确架构的表格。训练和推理步骤的执行是不同的。我在这里解释训练步骤,后面解释推理步骤分类器的训练是在 221*221 大小的单一尺度上完成的。通过首先将图像大小调整为 256,然后裁剪为 221,提取了 5 个随机裁剪及其水平翻转。我不会详细讨论训练的细节,比如学习速度,体重下降等等。该架构可以在图 1 中看到。

图一。过度饮食建筑

ConvNets 和滑动窗口效率(在 convnets 内部应用滑动窗口)

我们知道滑动窗口方法可以改善分类和定位的结果,但是增加了许多倍的计算。ConvNets 在应用滑动窗口技术方面具有内在的效率,因为它们共享重叠区域的共同计算(大部分将重叠)。我将在 CNN 的内部解释这个滑动窗口是如何工作的。拿这个图做参考。

图二。

我希望你意识到感受野(即使你在这篇博客之后没有阅读它,这是一个重要的概念)。上图分为两个子部分,先考虑第一部分。应用第一次卷积后,输出变为 1010(如果计算卷积运算的输出尺寸,请阅读)。)之后是最大池层,类似地在后面的层中给出 11 的最终输出。这里我们可以直观地说,最终的 11 编码了 1414 输入的信息(基本上这是一个感受域)。没有跳转到第二部分,过滤器大小没有变化,唯一的变化是输入大小(1616)。当第一个卷积被应用,随后是最大池时,输出大小变成 66,在先前的情况下是 55,现在当具有 55 滤波器大小的卷积将被应用时,输出大小将是 22 而不是 11。如果您看到 22 输出中的蓝点,它会对输入中蓝色部分的所有信息进行编码,而不会看到黄色区域。类似地,22 输出的第二个点((输出矩阵上的(0,1)位置)将永远看不到输入的前两列和底部两行(我们的模型的感受野是 14*14,因此输入大小的增加线性地增加了输出大小)。

多尺度分类

在推理时,为了提高分类精度,他们使用了多视图投票。他们使用培训中讨论的类似策略生成 10 幅不同的图像,并对预测进行平均。但这忽略了图像中的许多区域(因为与滑动窗口方法不同,我们只对每幅图像使用 5 次裁剪)。因此,他们采用了一种更好的方法,解释如下:

他们使用了 6 种不同的输入比例,从而生成了不同大小的第 5 层要素地图(这些大小请参考下表)。

图三。多尺度方法的空间维度

在这里我们可以看到不同尺度下模型输入大小的变化是(36,72)。这里的 36 值(二次采样率)类似于我们在上一节中观察到的 2 像素移动。第 5 层(上表中的预池)的输出将因规模而异。应用 33 最大池。考虑输出形状为 1717 的第一个比例。这里,如果在没有填充的情况下应用 max-pooling(33 ),则生成的输出大小将为 55。在这里,我们可以观察到最大池的输出没有来自预池化特征地图的最后两行和列的任何输入。由于 CNN 具有本地连接性,在原始图像的情况下,这两个列和行变成大约 30。为了解决这个问题,考虑到起始像素位置为(x{0,1,2},y{0,1,2},总共应用了 9 次最大池。因此,现在输出将是 3*3 的形状(前面提到的 9 倍是 2d 的行和列)。作者在图 4 中解释了这一点。

图 4。

从上一段继续。因此,我们得到的总输出是(55)(33)的形状。应用 5×5 卷积来获得最终的分类器图。它的形状是(11)(33)C,这里 C 是因为这是我们得到预测的最后一步。对于其他比例,最大池化后生成的输出地图会有所不同。对于其他规模,它将是类似的,我想你现在可以计算我们如何得到输出尺寸。现在,通过首先在每个尺度上取空间最大值(33C 或 69*C 中的最大值)来计算最终输出。然后对所有尺度的输出进行平均,最终得到每个图像的一个类输出。

我们完成了分类,我们的主要任务是对象检测,我们甚至还没有开始。

别担心,现在没那么久了。我们几乎涵盖了所有的理论。

本地化

分类训练网络由回归网络代替分类图层,并对其进行训练以预测每个空间位置和比例的边界框。回归网络从第 5 层获取合并的要素地图,随后是大小为 4096 和 1024 的两个 FC 层。最终输出有 4 个单元(见图 5。).特征提取层(前 5 层)的权重是固定的,并且使用 l2 损失来训练模型。训练是在多个尺度上进行的(不同于在单个尺度上训练的分类网络,在多个尺度上仅生成预测)。这将使预测跨尺度正确匹配,并增加合并预测的可信度。

图 5

为了生成对象边界框预测,我们跨所有位置和规模同时运行分类器和回归器网络。由于这些图层共享相同的要素提取图层,因此在计算分类网络后,只需重新计算最终回归图层。

由于模型将预测多个框(在本地化的情况下将有一个框),我们需要一些策略来消除所有的坏预测。应用了一个贪婪的合并策略,如图 6 所示(你可以跳过它,因为我没有看到任何其他论文使用这种策略,NMS(将在未来的博客中讨论)使用得更频繁)。

图 6

这里,match_score 被计算为 b1 和 b2 的中心之间的距离之和。box_merge 计算边界框坐标的平均值。

侦查

在检测的情况下,与定位任务的主要区别在于当不存在物体时,需要预测背景类别。因此,我们现在从定位网络获得的先前属于某个类别的盒子现在属于背景,因此我们可以移除这些预测,并且仅获得在哪个类别中被有把握地预测的预测。

过量论文总结到此结束。如果我做错了请重点指出,提出疑问作为评论。

参考文献:

  1. https://arxiv.org/pdf/1312.6229
  2. https://medium . com/coin monks/review-of-over feat-winner-of-ils vrc-2013-localization-task-object-detection-a6f8b 9044754
  3. https://www.youtube.com/watch?v=JKTzkcaWfuk
  4. https://www.youtube.com/watch?v=3U-bZgKFS7g&t = 70s
  5. Alexnet
  6. 感受野:https://medium . com/ml review/a-guide-to-receptive-field-algorithm-for-卷积神经网络-e0f514068807

论文列表:

  1. OverFeat:使用卷积网络的综合识别、定位和检测。←你完成了这篇博客。
  2. 丰富的特征层次,用于精确的对象检测和语义分割(RCNN)。 [ 链接到博客 ]
  3. 用于视觉识别的深度卷积网络中的空间金字塔池。 [ 链接到博客
  4. 快速 R-CNN 【链接到博客】
  5. 更快的 R-CNN:用区域提议网络实现实时目标检测。【博客链接】
  6. 你只看一次:统一的,实时的物体检测。【博客链接】
  7. SSD:单次多盒探测器。[博客链接]
  8. R-FCN:通过基于区域的完全卷积网络的目标检测。【博客链接】
  9. 用于目标检测的特征金字塔网络。【博客链接】
  10. DSSD:解卷积单粒子探测器。[博客链接]
  11. 密集物体检测的焦点丢失(视网膜网)。【博客链接】
  12. YOLOv3:一种渐进的改进。[博客链接]
  13. 狙击手:高效多尺度训练。[博客链接]
  14. 标注像素和区域的高分辨率表示。【博客链接】
  15. FCOS:全卷积一级目标检测。[博客链接]
  16. 物为点。[博客链接]
  17. CornerNet-Lite:高效的基于关键点的对象检测。【博客链接】
  18. CenterNet:用于对象检测的关键点三元组。[博客链接]
  19. 用于实时目标检测的训练时间友好网络。【博客链接】
  20. CBNet:一种用于目标检测的新型复合主干网络体系结构。【博客链接】
  21. EfficientDet:可扩展且高效的对象检测。[博客链接]

和平…

机器学习中的过拟合和欠拟合

原文:https://towardsdatascience.com/overfitting-and-underfitting-in-machine-learning-89738c58f610?source=collection_archive---------21-----------------------

在这篇文章中,你将了解什么是过度拟合和欠拟合。您还将学习如何防止模型过拟合或欠拟合。

在数据集上训练模型时,人们面临的最常见问题是过拟合和欠拟合。过度拟合是机器学习模型性能不佳背后的主要原因。如果你曾经面临过过度拟合的问题,也不用担心。浏览一下这篇文章。在本文中,我们将通过一个运行示例来展示如何防止模型过度拟合。在此之前,让我们先了解什么是过拟合和欠拟合。

我们在机器学习中的主要目标是正确地估计训练数据集中的分布和概率,以便我们可以有一个可以预测测试数据集的分布和概率的通用模型。

过度拟合:

当模型学习到数据中的模式和噪声,以致损害模型在新数据集上的性能时,称为过拟合。该模型与数据拟合得如此之好,以至于它将噪声解释为数据中的模式。

过度拟合的问题主要发生在其决策边界是非线性的非线性模型中。在逻辑回归的情况下,线性决策边界的例子可以是直线或超平面。如上面的过度拟合图所示,您可以看到决策边界是非线性的。这种类型的决策边界是由非线性模型(如决策树)生成的。

我们也有非线性模型中的参数,通过这些参数我们可以防止过度拟合。我们将在本文后面看到这一点。

欠拟合:

当模型既没有从训练数据集学习也没有在测试数据集上很好地概括时,它被称为欠拟合。这种类型的问题并不令人头痛,因为这可以很容易地通过性能指标检测出来。如果性能不好,尝试其他模式,你一定会得到很好的结果。因此,对拟合不足的讨论不像对拟合过度的讨论那样频繁。

非常适合:

既然我们已经看到什么是过度拟合和欠拟合,让我们看看什么是良好拟合。

在欠拟合和过拟合中间的点是好的拟合。

在现实世界中,得到一个完美的模型是非常困难的。你不可能一下子找到完美的模特。首先,您将有一个将在生产中使用的初步解决方案,然后您将根据您随时间收集的数据重新训练该模型。

如何解决过度拟合

在这一节中,我将通过一个真实的案例研究来演示如何防止模型过度拟合。我们将使用亚马逊美食评论数据集,并在此数据集上训练决策树。我还会提供一个 GitHub 链接供进一步参考。我假设你们都知道什么是决策树。我们将使用 sklearn 库。

您可以通过使用像 K-fold 交叉验证和超参数调整这样的技术来防止模型过度拟合。一般人们用 K 重交叉验证来做超参数调优。我将通过一个决策树的例子来展示如何做到这一点。首先,我来解释一下什么是 K 倍交叉验证。

K-fold 交叉验证:在这种技术中,我们通常将数据集分为三个部分。训练部分包含 80%的数据,测试部分包含 20%的数据。此外,在训练期间,训练数据集被分成 80:20 的比例,80%的数据用于训练,20%用于交叉验证。在决策树中,超参数是树的深度和每个节点上的数据点的数量,在此之后节点将被分割。我们将看到 k-fold 交叉验证是如何工作的。这里我举一个 5 重交叉验证的例子。因此,训练数据集将被分为 5 个部分,随机选择 4 个部分进行训练,1 个部分进行验证。这将重复 5 次,并且该度量的平均值将是该时期的最终度量。在一个时期中,树的深度和分裂值是固定的。例如:在一个纪元中,我们可以让树的深度为 100,分割值为 200。让训练数据集 D 被分成 D1、D2、D3、D4 和 D5。对于超参数的固定值,验证计算如下所示。

交叉验证计算。

这有助于监控培训,因为在培训期间,我们会根据看不见的数据验证模型。现在让我们以准确性作为衡量标准。训练后 A1 是训练精度。如果训练精度和测试精度都接近,则模型没有过拟合。如果训练结果非常好,而测试结果很差,则模型过度拟合。如果训练精度和测试精度较低,则模型有欠拟合。如果模型欠拟合或过拟合,那么我们改变超参数的值,并再次重新训练模型,直到我们得到一个很好的拟合。

超参数调整:在这个过程中,我们取一系列的超参数,然后我们监控所有可能的超参数组合的交叉验证准确性。我们采用给出最佳精度的超参数(这里我们将精度作为度量)。然后我们用那个超参数训练模型,然后测试。以下是如何计算每个超参数组合的交叉验证准确度。

交叉验证计算示例。

我们可以使用 sklearn 库提供的 GridSearchCv 或 RandomSearchCv 来做超参数。GridSearchCv 将检查所有可能组合的交叉验证,但 RandomSearchCv 通过随机选择组合进行检查。下面是进行超参数调整的代码。要查看完整代码,点击 此处

进行超参数调整的代码。

我希望这能弄清楚什么是过度拟合和欠拟合,以及如何解决它们。

难以理解为什么我们会交叉熵。通过这篇 博客 来有一个清晰的直觉。

[## 交叉熵、对数损失及其背后的直觉

在这篇博客中,你会对交叉熵和对数损失在机器学习中的应用有一个直观的了解。

medium.com](https://medium.com/@riteshk981/cross-entropy-log-loss-and-intuition-behind-it-364558dca514)

如果您在理解校准方面有困难,请浏览此 博客

[## 机器学习中的校准

在这篇博客中,我们将学习什么是校准,为什么以及何时应该使用它。

medium.com](https://medium.com/analytics-vidhya/calibration-in-machine-learning-e7972ac93555)

参考资料:

  1. https://en.wikipedia.org/wiki/Overfitting

2.https://sci kit-learn . org/stable/modules/generated/sk learn . model _ selection。RandomizedSearchCV.html

3.https://machine learning mastery . com/over fitting-and-under fitting-with-machine-learning-algorithms/

过度合身和不够合身:视觉上解释得像你五岁

原文:https://towardsdatascience.com/overfitting-and-underfitting-visually-explained-like-youre-five-8a389b511751?source=collection_archive---------47-----------------------

关于机器学习和深度学习中过度拟合和欠拟合的检测和预防,我们需要知道的一切

来源:【2】【3】【4】【5】—名词项目

每周,我的花园里都会长出一束花。你可以把它看成一个数据集。这是一个向我的孩子有趣地介绍复杂概念的好方法。在这篇文章中,我们将通过这个绚丽的花园来强调:

  • 理解数据集的重要性。
  • 过拟合欠拟合
  • 特异性一般化的平衡
  • 检测过拟合和欠拟合
  • 防止过度配合
  • K 重交叉验证
  • 分割训练、验证测试

了解数据集

我花园里所有的花都一模一样。但我不得不撒了点小谎。我说有些花帮助我们的兔子长得更快更聪明。其他的花什么都不做。

在两个星期里,我们采摘了花园里所有的花,把蓝色的 T42 树枝放在魔法花上,紫色的树枝放在普通花上。对于每一朵花,我都发明了它是不是魔法,但这并不重要。我们有一个花的数据集,我们知道它们在棍子上的 X,Y 位置,以及棍子的颜色,它们是神奇的还是普通的。

出于实际原因,在我的插图中,花将被替换为点。

一般化

我和我的孩子用我们种在花园里的棍子制作了我们的小数据集。我们称之为训练集。我现在希望我的孩子能够根据现有的数据预测花园里下一朵生长的花会是神奇的还是普通的,取决于它们的位置。我又等了一周,等待数据集的另一部分。我们没有摘这些花,甚至没有把树枝放在它们的位置上。我们将这组花称为验证集

你将如何做出预测

这些是我孩子的游戏规则。当他试图为我们的兔子划定花园中种植魔法花的区域时,他需要做出选择。他必须做出选择:

  • 一根刚性绳索
  • 一根柔性绳索
  • 多根柔性绳索

接下来的规则很简单:尽可能以最好的方式布置电缆,将的神奇花卉区与普通花卉区区分开来。每当我的孩子试图解开的绳子时,我就会根据验证集向他报告他所犯的错误。

你猜对了。所以是 3 种不同的型号,参数或多或少。它可以是任何预测模型,但是例如,我将使用神经网络插图来说明这些绳索。

欠拟合

在理解什么是欠配合之前,更容易理解过配合。当模型过于简单时,出现欠拟合。或者当模型对于给定数据不够好时。

这是很少遇到的情况。另外,我的孩子没有选择刚性绳。使用听起来太死板而没用的东西似乎很荒谬。

如果我的孩子使用硬绳:

  • 他会试着把他已经知道种类的花放在一起。
  • 他会用我的反馈一步步评估刚性绳索的正确位置以提高他对它的预测。

但是这种刚性绳索的选择不够灵活,不适合我们的数据。在机器学习或深度学习中,无论使用什么算法(SVM、安、随机森林),我们都必须确保我们的模型对于我们的数据有足够的特征。因此,了解数据集非常重要。

过度拟合

来源:【2】【3】【4】【5】—名词项目

如果你已经明白什么是欠拟合:过拟合是的反义词。经常使用以下比喻:

  • 欠配合:试着用苍蝇拍杀死哥斯拉
  • 过度配合:尝试用火箭筒杀死一只苍蝇

我的孩子选择用我向他提出的最后一个选择来划定神奇的花区:多根柔性绳索。人们总是倾向于使用过多的功能,而不是最基本的功能。本能的,我们都是孩子!

这是我们太容易犯的错误。为什么不用什么都有而不是什么都没有?我们大多数人对此都有偏见。作为我的孩子,我们也会选择带上所有的绳索。

多亏了这束绳子,我的孩子终于设法把魔法花生长的所有地方都围了起来。

"100%!恭喜你!”

然后我们用我们的验证集和哎呀 …本周的神奇花朵进行评估,准确性非常差。甚至比刚性绳更糟糕,导致不匹配。

我承认我真的没有孩子,我从来没有在这篇文章之外编过这个花的故事。但是我的孩子是我编程的模型。我邀请你去考虑你的模特。因为如果我们让他们选择使用许多功能,那么我们就可以确定我们的模型会使用所有的功能。那它就会超负荷。

找到一个好的平衡点

我们刚才已经看到的是我们必须在特异性和普遍性之间找到正确的平衡

  • 一般化:将应用于一组可见数据中的不可见数据的能力。
  • 特异性:在最细微的细节发现数据的能力。

在训练一个模型时,你应该小心找到正确的平衡点:

  • 过拟合 : 泛化,特异性
  • 欠拟合:高泛化,特异性

因此与直觉相反的是,预测神奇花朵生长区域的模型应该是简单的柔性绳子。不是那几根柔韧的绳子。

检测过度拟合

嗯,我们必须小心过度合身。知道这一点很好,但是我们如何检测它呢?有两种思想流派:

  • 验证设置上的错误可以被监控。训练集上的误差将继续减少,训练的特异性越来越强。当验证集上的错误开始增加时,您会注意到开始过拟合
  • 验证集上的度量可以被监控。这在视觉上和上一点是一样的。

我更喜欢度量监控。我知道描绘普通花和神奇花的区域的线条的误差距离不感兴趣。我感兴趣的是那些线条的精确度。对我来说,误差用来调整绳索的位置。该度量用于评估他们的位置。

一旦确定,防止过度拟合的最简单和最直观的方法是应用提前停止。如果在验证集上准确度开始下降,是时候停止我们的训练以避免失去泛化和过度拟合。

防止过度拟合的另一个显而易见的方法是检查我们的模型对于给定的数据集是否包含太多的特征。换句话说,如果我们的模型有过度拟合的趋势,那么我们可以逐渐移除特性和/或它们的灵活性。这允许我们获得一个更适合数据集的模型。

验证和测试设备

当我们修改模型的架构、学习率或参数初始化方法时:这些是我们正在修改的超参数

  • 参数:由模型自身在训练过程中选择并更新以最小化误差。
  • 超参数 : 提供给型号。这些元素无法在培训期间学习。它们定义了模型以及如何优化其性能。

让我们回到基础。我们需要一个验证测试来确定我们没有执行任何可能导致过度拟合的特异性。但是我们用验证集来评估这个性能。调整超参数后,验证数据本身变得有偏差。我们用它们在某种程度上“训练”我们的超参数。

这就是为什么有必要将数据集分成 3 个不同的集合。一个给训练的模特。另一个是验证我们的培训和调整我们的模型。最后,一个测试设定来验证我们的模型。该套件只能在最末端使用。你不应该使用这个设置来重新调整你的模型。

k 重交叉验证

另一种防止过度拟合的方法是所谓的 K 倍交叉验证。让我解释一下。当我们分割数据集时,我们把测试留到最后。然后我们我们的训练集划分为个子集

在我们的花卉数据集中,我们可以方便地进行。我们用每个的花来划分我们的数据集。在第一次迭代中,我们用前两周训练我们的模型,用最后一周评估它。在第二次迭代中,我们为每次迭代切换并重复过程

这将限制特异性到一个星期的魔法花,这些魔法花本来会生长在更稀少的区域。这个导致了泛化。在最后,我们将能够在接下来的一周评估我们的模型,我们的测试集。

防止过度拟合的其他方法

还有其他方法可以防止过度拟合:

  • 集合:几个不同模型的组合****投票预测。
  • 规则化:人为强制模型变得简单的方法。

然而他们很快就会有自己的文章😜

结论

  • 了解你的数据集。
  • 不要对你的模型的特性过于贪婪。
  • 总是评估你的模型。
  • 注意在特异性概括性之间的正确平衡。
  • 监控错误或度量的行为以提前停止培训。
  • 保留一个测试集
  • 使用分区数据集上的交叉验证防止过度拟合。

知识就是分享。
支持我,一键获取 我所有文章的访问

来源图像

1【2】【3】【4】【5】—名词项目

其他图片有自制的免费使用的

过度拟合,不仅仅是一个问题

原文:https://towardsdatascience.com/overfitting-more-than-an-issue-fac2d8b1fb5d?source=collection_archive---------45-----------------------

识别过度拟合的实例

图片来自 Pixabay ,由 alehigalgo 提供。

我多年来一直从事机器学习和深度学习模型的研究。在这段时间里,我发现有些情况下过度拟合并不明显。同样,我也见过其他人,比如朋友、同事或学生,他们不能在自己的问题中识别过度匹配。

因此,我决定制作这个小指南,讲述我遇到的难以识别过度拟合的案例,以及在试图解决它时遇到的主要错误。

什么是过度拟合?

当处理经典的机器学习或深度学习问题及其模型时,如人工神经网络或用于分类的 SVM,有一个初始训练阶段。在训练期间,模型被输入选定的数据,以便教会它如何对给定的数据进行分类。

一旦用数据训练了模型,就该用新数据测试它了。这被称为测试阶段,它证明模型是否能够从以前从未学习过的数据中提取信息。

如果模型对训练数据有好的结果,但对测试数据有坏的结果,则称该模型过度拟合。这些结果来自评估指标,如准确度、召回率、精确度……通常,当第一次学习机器学习时,据说训练期间的准确度或召回率接近 100%,但测试期间没有,这意味着过度拟合。

有时候这并不完全正确。可能有 70%的召回涉及过度拟合的情况。因此,这里列出了一些不容易识别过度拟合的情况。

案例 1:兴趣类的问题

这个案例是我在生物信息学问题中看到比较多的一个。先说个例子。在这个例子中,我们是生物信息学家,试图找到一个深度学习模型,该模型必须能够检测神经退行性疾病的存在。神经退行性疾病通常有阶段,越早发现,治疗越有效,因为疾病还没有发展到那种程度。

我们关注的疾病有 3 个阶段,阶段 1 是疾病的初始表现,阶段 3 是最晚期的表现。因此,检测阶段 1(感兴趣的类别)比阶段 2 和 3 更重要,因为治疗会更有效。

在训练过程中,我们达到了预期的情况,我们几乎完美地检测到了第一阶段的病例。在测试过程中,阶段 3 的病例被最好地检测到,而阶段 1 的病例被正确分类的最少。这显然是一个过拟合问题,因为模型无法对新数据进行分类。

有时这并不像看起来那样清楚。当我在学习深度学习时,我面临过这样的问题。我的模型在训练时对阶段 1 有 70%的回忆,是最好的分类,阶段 3 有 50%的回忆,是第二好的分类。测试时,第一阶段的召回率为 60%,而第三阶段的召回率为 80%。这些结果表明这个模型不好,但是我没有足够的经验去理解它。首先,这个模型对于医学专家来说是没有用的,因为他们想要一个可以在疾病不明显的时候诊断疾病的模型。第二,即使第一阶段的回忆没有显著变化,第三阶段的回忆还是有显著变化。这意味着训练数据不能代表测试期间可能出现的情况,并且模型不能概括其知识。

正如我之前所说,这在生物信息学问题中非常常见,在一些科学论文中,作者无法发现他们过度拟合了他们的模型,或者没有以适当的方式解决它。

大多数人使用数据扩充技术是为了产生更多不同案例的新例子。这在一些情况下很有用,比如图像增强问题。在图像恢复问题中,模型识别噪声之类的伪像,并试图消除它们。它在训练中学习的不同类型的工件越多,它对新图像的处理就越好。一些作者用人工噪声创建新的图像,以便在训练期间增加多样性。

在其他问题中,比如医学问题,人工数据可以代表自然界中不可能存在的病例。用错误的数据训练模型可能会使它产生偏差。这在学生或刚开始机器学习的人中间很常见。他们不检查增加的数据,然后有像这样的不现实的情况:

图片编辑自 Pixabay ,由 toubibe 提供

案例 2:不平衡数据

第二种情况是我在新手中看到的。当我还是个大学生时,我也遇到了同样的问题。有些问题是使用的数据非常不平衡。例如,在我使用的数据集中,90%的数据来自类 0,10%来自类 1

当将数据分为测试和训练数据时,我使用了保留策略,80%的数据用于训练,20%用于测试。很明显这是个坏主意。在训练过程中,模型显示了很高的准确性和回忆价值。测试中的这些值也很高,因为数据来自相同的数据集。我并没有在那一刻意识到,因为我在训练和测试阶段都取得了不错的成绩。

当使用非常不平衡的数据时,模型倾向于学习最常见的类。我的情况是 0 级。大多数人没有意识到的问题是,模型将大多数的例子归为一个特定的类。发生这种情况是因为该模型了解到给定的示例更有可能来自该类,所以它不会从其他类中提取信息。

在这种情况下,大多数人试图解决过度拟合问题,从代表过多的类中删除示例,或者从代表不足的类中重复数据,以便每个类包含相同数量的元素。

如果选择了删除数据的解决方案,您可能会从定义该类的可能案例范围中删除重要的和有代表性的数据。然后,该类的评估指标可能会变得更差,因为新的示例可能包含模型无法学习的用于抽象知识的特征。

另一方面,重复数据可能会使代表性较低的类的分类产生偏差。当重复数据时,大多数例子都要重复多次。该模型可以学习那些重复的例子作为该类的最具代表性的例子,并忽略该类中其他代表性较低的例子。例如,如果我们正在训练一个动物分类器,并且我们只重复灰色猫的图像,那么我们的模型可能只将灰色猫识别为猫。

一个类别的数据种类很少也会在分类中产生偏差。也就是说,该模型是欠拟合的,并且在训练期间显示出较差的结果。一个众所周知的袋子是图里奥·里贝罗等人在 2016 年[1]测试的一个区分狼和哈士奇的模型。最终的结果是一个模型,如果背景中有雪,它会将图像中的动物检测为狼。

案例 3:数据种类少

有时数据很难获得。有时没有可用的资源或数据,而获取这些资源或数据又很昂贵。当这种情况发生时,人们倾向于只使用他们拥有的少量数据。例如,医疗数据很难获得。有时研究人员只有一个病人或几个病人的数据(几个来源)。这意味着大多数数据示例是相关和依赖的。

当数据来自少数来源时,模型在部署用于生产时可能会出现问题。在我的案例中,我只有一个病人的视网膜图像,并且我正在尝试制作一个系统来检测视网膜图像中的血管。由于示例数量较少,我不得不将数据分成训练和测试数据进行交叉验证。在培训和测试中,我都取得了不错的成绩。

在部署该系统时,对第二名患者进行了测试。不出所料,结果很糟糕。人体的器官通常互不相同。

与前一种情况一样,所有类别中的少量数据可能会产生偏差,但不会过度拟合。只检测到与训练模型的少数案例非常相似的案例。

当这种情况发生时,缺乏经验的人很难找到问题的根源。因此,为了能够做出特别的解决方案,最好尝试不同的技术,而不仅仅是机器学习。当你没有更多的数据时,这将是一个快速的解决方案。

经验是伟大的老师

这里解释的案例是一些人们通常不会识别过度拟合问题的例子。都是我亲身遇到的案例。我发现它们都很有趣,尤其是对那些刚刚起步的人来说。这个世界上没有人生来就什么都懂,实践和实验是我们最好的老师。永远不要停止学习和实验。

如果你对这篇文章有任何疑问或修正,请不要犹豫,通过 LinkedIn 向我提出问题或建议。

谢谢您们。

参考

[1] M. T .里贝罗,s .辛格,c .盖斯特林,“我为什么要相信你?《解释任何分类器的预测》(2016),第 22 届 ACM SIGKDD 知识发现和数据挖掘国际会议论文集。

事件表中的重叠时间段问题

原文:https://towardsdatascience.com/overlapping-time-period-problem-b7f1719347db?source=collection_archive---------40-----------------------

在数据科学领域,人们往往认为清理数据很无聊,并希望更多的机器学习和建模挑战,但有时可能会出现一些问题,如有趣的脑筋急转弯或数据清理期间的算法难题。这是我最近在清理活动桌时遇到的一个有趣的例子。它不像疯狂的 ML 算法或新的很酷的 python 工具,而是一个值得花几分钟去解决的有趣的小问题。

当我们构建任何类型的数据管道或 ML 管道时,尤其是在处理预测问题时,事件表是非常常见的。事件表类似于事务表,通常具有开始时间、结束时间、人员 ID 和其他事件属性。每一行都是一个事件,一些事件可能会重叠,这可能是一个问题。现实世界中的事件表可能如下所示:

 person_id      start        end
0          1 2017-01-01 2017-06-01
1          1 2017-02-01 2017-03-01
2          1 2017-05-01 2017-08-01
3          1 2017-09-01 2017-10-01
4          1 2017-11-01 2018-02-01
5          1 2018-01-01 2018-03-01

有时我们可以忍受,但有时我们希望将那些重叠的行合并成一行,最早开始时间和最晚结束时间如下:

 person_id      start        end
0          1 2017-01-01 2017-08-01
1          1 2017-09-01 2017-10-01
2          1 2017-11-01 2018-03-01

也就是说,由于第二个事件和第三个事件都与第一个事件重叠,即使第三个事件不与第二个事件重叠,我们希望合并的事件具有第一个事件的开始时间和第三个事件的结束时间。这看起来很简单,但要找出一个好的解决方案并不容易。

在这里,我用 python 来解决这个问题。

简单案例:

在第一种解决方案中,我们可以将此视为图连通性问题。每个事件都是一个节点。如果两个事件重叠,那么它们用一条边连接。因此,前三个事件将形成一个连通子图,第三个事件是一个孤立节点类子图,第四个和第五个事件将形成另一个连通子图。我们在原始数据帧中给每个子图分配一个 group_id。现在,我们可以按 group_id 分组,并按 min(开始时间)和 max(结束时间)聚合,然后我们就有了答案。

为了实现这一点,我们将创建一个邻接矩阵来表示该图。首先,我们要定义“重叠”。这里的重叠是指:对于任意两个节点 A 和 B,如果节点 A 的开始日期在节点 B 的结束日期之前,节点 A 的结束日期在节点 B 的开始日期之后,那么 A 和 B 重叠。我们可以用numpy数组实现逻辑来创建一个稀疏矩阵。存在几种算法来解决连通图问题。我们可以使用一个现成的功能scipy.sparse.csgraph.connected_components来实现这一点。scipy用类似于 Tarjan 算法的东西实现函数。然后,我们只要做简单的熊猫groupby方法就能得到我们想要的结果。

就其数学方法而言,这是一个很好的解决方案。那只是一个人的。如果我们有数千或数百万人,这通常是真实世界的情况,图形将会变得非常大,空间复杂性将以 n 为单位增长。我们仍然可以通过在创建邻接矩阵的行中添加另一个“&”逻辑来实现这一点。

理论上,Tarjan 算法的时间复杂度是线性的。n^2空间的复杂性使其无法扩展。这让我思考如何和pandas一起用可扩展的方式解决。

老实说,我不是pandas的粉丝,因为它的查询方式不直观,但是如果我们有一个矢量化的解决方案,它确实会提供很好的性能。

矢量化的解是这样的。

让我们忘掉所有的图、节点和边,用一些纯粹简单的时间序列数据来重新思考这个问题。首先,我们打破开始时间和结束时间,通过排序创建一维时间序列。我们有一列start_end来表示是开始时间还是结束时间,其中1是开始时间,-1是结束时间。然后,我们对列cumsum中的序列执行累积求和。通过查看,我们注意到新的开始时间是其cumsum1\. A 的开始时间,新的结束时间是其cumsum0的结束时间。所以现在我们有了一个new_start列。接下来,我们对new_start列执行另一个累积求和来得到group_id。最后,我们做同样的汇总得到答案。

看一下mergedf可能更容易理解这里发生了什么。

 person_id       time  start_end  cumsum  new_start  group
0          1 2017-01-01          1       1       True    1.0
1          1 2017-02-01          1       2      False    1.0
1          1 2017-03-01         -1       1      False    1.0
2          1 2017-05-01          1       2      False    1.0
0          1 2017-06-01         -1       1      False    1.0
2          1 2017-08-01         -1       0      False    1.0
3          1 2017-09-01          1       1       True    2.0
3          1 2017-10-01         -1       0      False    2.0
4          1 2017-11-01          1       1       True    3.0
5          1 2018-01-01          1       2      False    3.0
4          1 2018-02-01         -1       1      False    3.0
5          1 2018-03-01         -1       0      False    3.0

性能

由于我不想太深入的研究 scipy 的connected_component的实现,分析它的复杂性,所以我只想用一种实证的方式比较一下可扩展性。我所做的只是将示例n重复几次,以创建一个大的事件表,并随着n数量级的增长来测量运行时间和峰值内存。

在 n 达到 10 之前,这两种方法在运行时和内存上都有点相似。在那之后,很明显,图表方法很快在运行时和内存中爆炸。我实际上是在一台 200GB RAM 的机器上用n=100000运行图形方法时遇到了内存泄漏。肯定有一些方法可以优化图形方法,这是我很想看到的,但我在这里试图指出的是,scipy 的connected_component背后的操作比 pandas 中的矢量化更加占用内存。我猜有时候丑陋的算法可能会打败美丽的算法。

 size    mem     runtime       approach
0        10     82    0.083125          graph
1        50     83    0.111390          graph
2       100     85    0.094990          graph
3       500    150    0.458318          graph
4      1000    305    1.544724          graph
5      5000   6964   27.119864          graph
6     10000  27576  113.710234          graph
7    100000    inf         inf          graph
8        10     82    0.092768  vectorization
9        50     83    0.125092  vectorization
10      100     83    0.121607  vectorization
11      500     86    0.091670  vectorization
12     1000     89    0.168066  vectorization
13     5000    101    0.154213  vectorization
14    10000    115    0.224327  vectorization
15    50000    216    1.523057  vectorization
16   100000    351    2.482687  vectorization
17   500000   1407    6.840897  vectorization
18  1000000   2707   12.607009  vectorization

在疫情和抗议声中俯瞰纽约市的犯罪

原文:https://towardsdatascience.com/overlooking-crime-in-new-york-city-amid-the-pandemic-and-protests-d227e698182e?source=collection_archive---------47-----------------------

到目前为止,犯罪数据讲述了 2020 年纽约市怎样的故事?

简介:纽约是怎么回事?

这些天来,纽约市的犯罪率有了非常矛盾的想法。一些政治家说,暴力犯罪在纽约猖獗,但其他一些人说,由于封锁,这里比以往任何时候都安全。随着选举的临近,我想这只是一直以来被用于政治利益的公共话题之一。但我个人也得到了很多版本的故事。

我有朋友和家人说它变得不适合居住了。与此同时,我还没有从仍在这座城市的外国朋友或同事那里听到任何不同的消息。这让我有兴趣回到我差不多一年前的关于纽约犯罪的老项目,这次做些不同的事情。

相互矛盾的信息无处不在。来源:谷歌

主题

基于上述非常矛盾的观点,我可以想到这两个相关的问题:

  1. 我们能找到 COVID19 或抗议对犯罪率的总体影响吗?
  2. 纽约变得比以前更加暴力或危险了吗?2020 年什么类型的犯罪最突出?

数据

鉴于 2020 年与前几年有着前所未有的不同,这不是一件容易的事情。为了不涉及政治观点或预设,我选择开源数据来做研究。我们将在 NYCOpenData 上重新查看 NYPD 的投诉数据,但这一次,我们将选取过去五年(从 2015 年开始)的数据。然而,要回答这些话题,有一个巨大的警告和问题。

  1. 我们必须假设 NYPD 的犯罪记录系统在任何特定事件中没有出现任何故障。记录并没有因为疫情或抗议而停止或更改可能会影响记录在数据集中显示方式的过程。
  2. 由于这篇文章的时间是 2020 年 11 月初,我们错过了这一年另一半的数据。因此,我们只提取了每年前六个月的数据来做测试。

众所周知,犯罪率会随着季节的变化而变化。如果我们将前几年的数据与时间一起绘制,我们可以清楚地看到一些相同的季节性。

p.s.2 大部分过程我都是用 Python 搭配 Pandas & Matplotlib 包。为了简单起见,我将在整篇文章中保留最少的代码,但是如果您对数据处理、可视化或某些细节感兴趣,请随时联系我以获取更多信息。

我们能找到 COVID19 或抗议对犯罪率的总体影响吗?

在应用任何统计数据之前,我们可以从简单的图表中发现明显的差异。上半年中期(3 月左右),2020 年起的犯罪数据有一个大的低谷。之后,犯罪率略微恢复到温和水平,如下图所示。

如果我们把一个更详细的时间框架放在轴上,并专注于 2020 年,我们可以发现一些重大事件和下降之间的巧合。

从上图来看,行政命令与下跌多少有些关联。令我们惊讶的是。抗议并没有明显增加犯罪事件的总数。(我们会深入挖掘,在后面的部分考察犯罪类型。)

统计分析

到目前为止,我们可能已经看到了这两组之间的差异,但让我们只是说,我们不考虑时间因素,而只考虑每天犯罪数量的总分布的差异。通过统计测试(安德森-达林测试T5【一种统计测试,测试给定的数据样本是否来自给定的概率分布),我们可以看到过去 5 年和 2020 年代的分布是否相同。在设定下(零假设是“2020 年的数据取自同一个分布”,置信度设定为 95%),我们理直气壮地否定了假设,说 2020 年的数据不是从一个 5 年数据的同一个分布产生的。

这是一个图表(直方图和累积分布函数),以直观的方式显示了这两者之间的不同。

p.s .虽然日犯罪案件数是离散值,但对于通常用于连续数据的 Anderson-Darling 检验来说,采样数已经足够大了(5 年直方图类似于正态分布)。

直到这一点,我们已经证明了 2020 年的犯罪率不同于之前的 5 年。此外,我们可以推测,COVID 似乎会显著影响犯罪率,但抗议不会以这种方式出现。为了对后一部分进行一点扩展,我们应该进入下一个主题,研究犯罪类别。

纽约变得比以前更加暴力或危险了吗?2020 年什么类型的犯罪最突出?

在这里,我将使用相同的任意规则对犯罪事件进行分类(更多解释请参见我的上一篇文章)。我们将调查与之前的 5 年相比,2020 年是否有任何类型的犯罪激增。

另外,为了避免与犯罪类型相关的可能的季节性,我们将只使用上半年的数据。还有,5 年数据是过去 5 年数据的平均值。

从 5 年和 2020 年数据的差异可以看出,2020 年大多数类型的犯罪事件都有所下降。然而,在某些类型中有一些明显的增加。入室盗窃、机动车盗窃、纵火和谋杀在 2020 年会有一定程度的增加。

让我们绘制这些类型随时间的变化图,以便更仔细地观察。

我们可以从上面的情节中总结出一些要点:

  1. 大多数犯罪似乎都受到了 COVID19 关闭的影响,因为我们在 3 月份看到了几乎相同的下降。然而,由于某种原因,机动车辆盗窃、入室盗窃、纵火和赌博在 3 月份似乎没有受到影响。可能这些类型的犯罪并不一定受到关闭的限制。
  2. 总的来说,在经历了 3 月份的大规模下跌后,大多数犯罪事件在一定程度上有所反弹,但仍低于年初的数字。我们可以推测,犯罪事件在某种程度上与经济活动水平相关,特别是非暴力犯罪(例如,社会商业相关犯罪、盗窃、欺诈)
  3. 在这些分布的后半部分(大约 5 月),我们可以看到一些事件的高峰。具体的暴力犯罪(如破坏财产罪、纵火罪、严重伤害罪、入室盗窃罪)已经超过了过去 5 年的正常水平。我们可能将此归因于 5 月 29 日开始的一系列抗议活动。入室盗窃和纵火案达到创纪录的高水平,因为这在正常情况下并不经常发生。
  4. 抗议确实引发了特定类型的犯罪事件,这对这座城市来说是灾难性的。也就是说,大多数犯罪事件仍然低于 5 年的平均水平,媒体广泛报道的一些具体事件(入室盗窃和纵火)仅在一周内上升。当我们看到一些趋势时,恶性袭击和机动车辆盗窃可能是新的问题,但是这里的可用数据 并不完全支持纽约市这些天变得更加暴力的说法,在我看来

值得指出的一点是,谋杀案件的实际数量远小于其他案件(例如,规模为 100 起)。因此,该百分比会随着轻微的波动而显得更加吓人。然而,这并不是淡化令人痛心的事件!对于像谋杀和枪击这样的犯罪,感知和原因远比数字更重要。这需要更详细的数据来确定根本原因(如街头帮派、个别事件)。这种探索的局限性阻止了我们在这个问题上获得更具体的见解。

结论:现在还很难说

鉴于多个前所未有的事情同时且紧密发生(纽约市上一次宵禁是在 1945 年!).然而,看真实的数据并试图描绘出这个主题的真实概貌是有趣的,或者说是负责任的。

为了结束这项研究,我只能轻率地得出结论:由于疫情,纽约市的犯罪率较低,尽管它在一到两周内经历了“激进抗议”的高峰。很容易得出这样的结论:纽约市现在是一个犯罪的粪坑,但与过去相比,这个城市至少在上半年还不算太糟。如果我们想得出任何可靠的结论,关键是要继续跟踪数据,看看总体犯罪数字是否有系统性的变化。

卢卡·布拉沃Unsplash 上拍摄

下一步是什么?

过了 2020 年(希望,我们能做到😀),我会再次重温这个主题,看看是否有更有趣的东西可以调查。还有一个更有影响力的事件,11 月份的美国大选,这将是另一个观察政治活动如何影响城市犯罪率的绝佳机会。

感谢阅读长文!有任何想法和意见,欢迎随时回复,或者通过 Linkedin 联系我!

附:如果你对新冠肺炎的一些州级信息感兴趣,一定要访问这个整洁的个人仪表盘来跟踪曲线。

杰夫

覆盖 Power BI 中的日期过滤器

原文:https://towardsdatascience.com/override-date-filter-in-power-bi-743b9e8b9b2?source=collection_archive---------10-----------------------

在 Power BI 中覆盖标准的日期过滤可能比您想象的要复杂

伊加特·库尚列夫在 Unsplash 上拍摄的照片

最近,我的一个朋友从他的客户那里得到了一个有趣的请求。他们需要根据日期选择来查看过去指定时间段的值。

例如,如果他们选择 2020 年 3 月 31 日,他们需要查看前 12 个月的值,因此从 2019 年 4 月 1 日开始。此外,他们需要一个选项来选择特定的日期,并查看所选日期的年初值。同样,如果他们选择 2020 年 3 月 31 日,他们需要查看从 2020 年 11 日开始的值。视觉效果将被调整为基于用户选择动态变化

也就是说,编辑交互作为一种从特定视觉中移除过滤器的方式,并不是一种选择,因为它会完全拒绝用户选择任何特定的值进行过滤。

棘手的部分

这里最棘手的事情是建立日期维度和事实表之间的正确关系。因为,如果您依赖于日期维度和事实数据表之间的“正常”关系,数据将根据日期选择进行筛选,日期选择充当这两个表之间的关系。

让我们前往 Power BI Desktop,看看是否可以做些什么。

正如您在上面的模型视图中所看到的,DimDate 和 FactOnlineSales 与 DateKey 列相连接。因此,只要我在切片器中选择日期,我的条形图就只显示那些由切片器选择过滤的值,如下面的屏幕截图所示。

这里的主要问题是:我们如何“覆盖”从日期切片器传递的值。

解决方案的关键

这里的关键是断开日期维度和事实表之间的“常规”关系。我们需要一个独立的,不连续的日期表,这将有助于定义我们需要在条形图视觉显示值的时间框架。

因此,我将使用以下定义创建一个新表:

Dates = DISTINCT(FactOnlineSales[DateKey])

这将包括事实表中的所有日期。该表与我们的事实表保持断开,正如您在模型视图中看到的:

现在,让我们创建一个新的度量,它将计算我们指定的日期内的销售额:

Sales Amt = 
         VAR MaxDate = MAX(Dates[DatesDateKey])
         VAR MinDate = CALCULATE(MIN(Dates[DatesDateKey]),
                                ALLEXCEPT(Dates,Dates[DatesDateKey])
                                )
            VAR SalesAmt = CALCULATE(SUM(FactOnlineSales[SalesAmount]),
                              FILTER(FactOnlineSales,FactOnlineSales[DateKey] >= MinDate && FactOnlineSales[DateKey] <= MaxDate))
            RETURN
            SalesAmt

我们在这里所做的基本上如下:我们正在定义一个变量,该变量将选择最后选择的日期(MaxDate)。然后,我们定义我们的起点:在这种情况下,它将在日期表中找到第一个日期,用 ALLEXCEPT 函数覆盖现有的过滤器上下文。最后,我们使用过滤器函数计算 SalesAmt 值,以便根据变量中设置的日期限制时间范围。在我们将新的度量拖到条形图视觉效果后,我们将得到以下结果:

因此,如果我选择 2008 年的第 4 季度,我将看到从开始(事实表中的第一个日期值)到所选期间的所有值。如果我选择 2009 年第 3 季度,我将得到以下值:

很酷吧,哈?

微调我们的解决方案

但是,如果我们只需要查看所选日期年初以来的值,或者所选日期之前 12 个月的值,该怎么办呢?

断开连接的表保持不变,因为,别忘了,它是解决这个问题的关键要素。我们将稍微改变一下计算销售额的方法。

如果要查看年初以来的所有值,可以像这样调整 measure:

Sales Amt StartYear = 
        VAR MaxDate = MAX('Dates'[DatesDateKey])
        VAR MinDate = STARTOFYEAR('Dates'[DatesDateKey])
        VAR Result = CALCULATE(
                            SUM(FactOnlineSales[SalesAmount]),
                            FILTER(FactOnlineSales,
                                FactOnlineSales[DateKey] >=MinDate && FactOnlineSales[DateKey]<=MaxDate)
        )
        RETURN
        Result

所以,唯一的区别是 MinDate 变量的定义。这里,我们使用 DAX 函数 STARTOFYEAR 来获取所选日期的第一个日期。

另一个选项使您能够查看您根据需要定义的尾随期间:以下示例显示了过去 12 个月,但您可以轻松地修改它:

Sales Amt -12 Months = 
        VAR MaxDate = MAX('Dates'[DatesDateKey])
        VAR MinDate = DATE(YEAR(MaxDate),MONTH(MaxDate)-12,DAY(MaxDate))
        VAR Result = CALCULATE(
                            SUM(FactOnlineSales[SalesAmount]),
                            FILTER(FactOnlineSales,
                                FactOnlineSales[DateKey] >=MinDate && FactOnlineSales[DateKey]<=MaxDate)
        )
        RETURN
        Result

同样,唯一的区别在于起点的定义。通过组合日期月份函数,我们告诉我们的度量我们想要计算过去多长时间。在这种情况下,它是-12 个月,但您也可以使用年、季度、天作为标准。

年初的例子

-12 个月的示例

结论

正如您所看到的,我们可以使用一些非标准的技术来覆盖过滤器的常规行为,比如创建定制的非连接表。

感谢阅读!

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

过采样和欠采样

原文:https://towardsdatascience.com/oversampling-and-undersampling-5e2bbaf56dcf?source=collection_archive---------1-----------------------

一种不平衡分类技术

照片由晨酿Unsplash 拍摄

我简介

不平衡分类问题是当我们的训练数据的类别分布存在严重偏斜时我们所面临的问题。好吧,偏斜可能不是非常严重(它可以变化),但我们将不平衡分类识别为一个问题的原因是因为它可以影响我们的机器学习算法的性能。

不平衡可能影响我们的机器学习算法的一种方式是当我们的算法完全忽略少数类时。这之所以是一个问题,是因为少数民族阶层通常是我们最感兴趣的阶层。例如,当构建一个分类器来根据各种观察结果对欺诈性和非欺诈性交易进行分类时,数据中的非欺诈性交易可能比欺诈性交易多,我的意思是想一想,如果我们有等量的欺诈性交易和非欺诈性交易,这将非常令人担忧。

1:欺诈检测问题的类别分布示例

应对这一挑战的方法是随机抽样。执行随机重采样有两种主要方式,各有利弊:

过采样 —从少数类中复制样本

欠采样 —从多数类中删除样本。

换句话说,过采样和欠采样都涉及引入一种偏向,从一个类别中选择比另一个类别更多的样本,以补偿数据中已经存在的不平衡,或者如果采取纯粹随机的样本,可能会出现的不平衡(来源:维基百科)。

我们将随机抽样定义为一种幼稚的技术,因为在执行时,它不假设任何数据。它涉及创建我们数据的新转换版本,其中有一个新的类分布,以减少数据对我们机器学习算法的影响。

注意:我们称随机重采样为幼稚,因为在执行时,它不对数据做任何假设。

在本文中,我们将利用 2014 年启动的imbalanced-learn框架,主要关注 SMOTE(另一种不平衡数据技术)的实施。多年来,已经实现了额外的过采样和欠采样方法,并使该框架与流行的机器学习框架scikit-learn兼容。访问不平衡学习获取安装指南和完整文档。

from sklearn.datasets import make_classification
from imblearn.over_sampling import RandomOverSampler
from imblearn.under_sampling import RandomUnderSampler
from collections import Counter# defining the dataset
X, y = make_classification(n_samples= 10000, weights=[.99])# class distribution
**print**(Counter(y))Counter({0: 9844, 1: 156})

完整的代码你可以访问我的 Github

[## kurtispykes/演示

github.com](https://github.com/kurtispykes/demo/blob/master/notebook/kpy_random_sampling_example.ipynb)

随机过采样

随机过采样包括用替换从少数类中选择随机样本,并用该样本的多个副本补充训练数据,因此单个样本可能被选择多次。

随机过采样可能增加过拟合发生的可能性,因为它精确复制了少数类的例子。以这种方式,举例来说,一个符号分类器可能构建表面上准确的规则,但实际上覆盖了一个复制的例子。”—第 83 页,从不平衡数据集学习,2018。

对于受偏斜分布影响的机器学习算法,如人工神经网络和支持向量机,这是一种非常有效的技术。然而,在许多情况下建议调整目标类分布,因为为严重不平衡的数据集寻求平衡分布会导致算法过度适应少数类,从而导致我们的泛化错误增加。

我们应该意识到的另一件事是计算成本的增加。当我们训练模型时,增加少数类中的示例数量(特别是对于严重偏斜的数据集)可能会导致计算量增加,并且考虑到模型多次看到相同的示例,这不是一件好事。

尽管如此,过采样是一个相当不错的解决方案,应该进行测试。下面是我们如何用 Python 实现它…

# instantiating the random over sampler 
ros = RandomOverSampler()
# resampling X, y
X_ros, y_ros = ros.fit_resample(X, y)# new class distribution 
**print**(Counter(y_ros))Counter({0: 9844, 1: 9844})

随机欠采样

随机欠采样与随机过采样相反。该方法试图从多数类中随机选择和移除样本,从而减少变换数据中多数类中的样本数量。

“在(潜在的)随机欠采样中,大量数据被丢弃。[……]这可能是一个很大的问题,因为这些数据的丢失会使少数和多数实例之间的决策界限更难了解,从而导致分类性能的损失。”——第 45 页,不平衡学习:基础、算法和应用,2013 年

欠采样的结果是在多数类中具有较少样本的变换数据集——可以重复该过程,直到每个类中的样本数量相等。

尽管存在严重的不平衡,但在少数类有足够数量的例子的情况下,使用这种方法是有效的。另一方面,考虑有价值的信息被删除的可能性总是很重要的,因为我们随机地将它们从我们的数据集中删除,因为我们没有办法检测或保存在多数类中信息丰富的例子。

为了更好地理解这个方法,这里有一个 python 实现…

# instantiating the random undersampler
rus = RandomUnderSampler() 
# resampling X, y
X_rus, y_rus = rus.fit_resample(X, y)# new class distribution
print(Counter(y_rus))Counter({0: 156, 1: 156})

结合两种随机抽样技术

与单独执行的方法相比,结合使用两种随机采样方法有时可以提高整体性能。

其概念是,我们可以对少数类应用适度的过采样,这改善了对少数类示例的偏差,同时我们还对多数类执行适度的欠采样,以减少对多数类示例的偏差。

为了在 Python 中实现这一点,利用imbalanced-learn框架,我们可以在过采样和欠采样技术中使用sampling_strategy属性。

# instantiating over and under sampler
over = RandomOverSampler(sampling_strategy=0.5)
under = RandomUnderSampler(sampling_strategy=0.8)# first performing oversampling to minority class
X_over, y_over = over.fit_resample(X, y)
**print**(f"Oversampled: {Counter(y_over)}")Oversampled: Counter({0: 9844, 1: 4922})# now to comine under sampling 
X_combined_sampling, y_combined_sampling = under.fit_resample(X_over, y_over)
**print**(f"Combined Random Sampling: {Counter(y_combined_sampling)}")Combined Random Sampling: Counter({0: 6152, 1: 4922})

包裹

在本指南中,我们讨论了不平衡分类的过采样和欠采样。在许多情况下,我们可能会遇到不平衡的数据集,应用随机抽样可以为我们提供一个非常好的模型来克服训练中的这个问题,并仍然保持一个可以很好地推广到新示例的模型。

让我们继续 LinkedIn 上的对话…

[## Kurtis Pykes -人工智能作家-走向数据科学| LinkedIn

在世界上最大的职业社区 LinkedIn 上查看 Kurtis Pykes 的个人资料。Kurtis 有两个工作列在他们的…

www.linkedin.com](https://www.linkedin.com/in/kurtispykes/)

非少数类的过采样

原文:https://towardsdatascience.com/oversampling-with-a-non-majority-class-7bbf73b8505e?source=collection_archive---------41-----------------------

有意或无意地使用 SMOTENC 方法

平衡法~律师和数据集;图片来自 Robert J. Debry Associates

我的一个朋友最近决定申请法学院,这是一项需要多年准备的艰巨任务。参加 LSAT 本身就是一项令人生畏的任务,而且这仅仅是收集你的建议并使每一份申请适合学校的漫长过程中的第一步。

就在那时,我决定创造一个预测器,它可以告诉你被某所法学院拒绝、列入等候名单或录取的概率。这帮助了她,也有望帮助其他人决定去哪里申请并投入他们的精力和金钱(法学院的申请并不便宜!).

我从一个非盈利网站搜集数据,该网站允许以前的法学院申请者输入他们在法学院的统计数据和成绩。我在这里使用的统计数据是本科 GPA、LSAT、URM 和工作经验作为我的预测指标。值得注意的是,所有这些数据都是自我报告的。

法学院通常是根据排名来评判的,而排名每年都会变化。排名基于许多变量,包括毕业率、即将入学班级的 LSAT 中值分数、就业安置成功率以及即将入学班级的本科生 GPA 中值。法学院每年都会调整他们的入学标准。我在创建预测器时考虑到了这一点,将最近一年的数据“加权”得比往年更重。

实际上,这听起来是个好主意,但是我在 Python 实现上遇到了一些麻烦。衡量最近一年的最佳方法是什么?我将 2019 年至 2020 年的入学周期作为我的测试数据,并希望 2018 年至 2019 年比之前的几年更重要。

首先,我复制了一些行,发现 F-measure 得分比我的基线模型有所提高。

school_df = school_df.append([df_cycle18],ignore_index=True)

然而,我认为这并没有给模型提供任何额外的信息。我想为我的模型创建新的信息和新的可行数据,所以我考虑使用 MCMC,但最终使用了 SMOTE。为了使用 SMOTE 来增加最近一年的观测数据,我不得不重组这个问题。

入学年是现在的目标,我的新预测指标是 GPA,LSAT,URM,工作经验和决定(旧目标:录取,拒绝,等待)。我通过创建一个字典并将其传递给 SMOTE 的sampling_strategy参数来指定要过采样的周期:

cycles = np.unique(smote_cycle_y)for cycle in cycles:
    smt_dict[cycle] = smote_cycle_y[smote_cycle_y==cycle].shape[0]smt_dict[np.max(smote_cycle_y)] = smt_dict[np.max(smote_cycle_y)]*2oversample = SMOTE(sampling_strategy = smt_dict)

然后我看了看我的数据,发现 SMOTE 默认只处理连续变量。它将我的接受、拒绝或等待变量转换成浮点数。我之前定义良好的分类问题也有一些浮动,因此创建了 3 个以上的类。作为一个快速的解决方案,我将这些浮点数四舍五入为整数 0、1 或 2,这一结果令人惊讶地好。然而,我需要一个更好的解决方案。

接下来,我开始搜索多标签分类 SMOTE,并争论创建一个自定义类,然后我找到了答案,SMOTENC。SMOTENC 允许您识别哪些类是名义类,哪些是范畴类,因此称为“NC”。最近一年的过采样现在是无缝的:

smt_dict2 = {}for cycle in np.unique(smt_cycle_y):
    smt_dict2[cycle] = smt_cycle_y[smt_cycle_y==cycle].shape[0]smt_dict2[np.max(smt_cycle_y)] = smt_dict2[np.max(smt_cycle_y)]*2oversample = SMOTENC(sampling_strategy = smt_dict2, categorical_features = [0,3,4], random_state = 7)

结果很好,再次提高了 F 值。现在我在我的少数民族类上使用了来自我的原始数据的 SMOTENC,这非常有帮助。

smote_2_y = df_resample_train[['decision_numeric']] #original targetsamp_dict_2 = {}max_class = np.max(smote_2_y['decision_numeric'].value_counts())for cycle_id_smote in np.unique(smote_2_y):
    samp_dict_2[cycle_id_smote] = max_classoversample_2 = SMOTENC(sampling_strategy = samp_dict_2, categorical_features = [2,3])smote_2_y = df_resample_train.decision_numericX_fin, y_fin = oversample_2.fit_resample(smote_2_X,smote_2_y)

如您所见,F-measure 增加了,对数损失减少了,我们的整体模型得到了改善:

希望本文对您有所帮助,并向您展示了过采样的强大功能。要阅读更多关于 SMOTE 方法论的内容,请查看这里的文档和这个伟大的解释。这里是代码报告和工作法学院预测应用(使用 streamlit 制作)的链接!)

如果这篇文章对你有帮助,我很乐意听听!在LinkedIn上联系我。

VAEs 过采样

原文:https://towardsdatascience.com/oversampling-with-vaes-e410887fe51?source=collection_archive---------45-----------------------

使用 VAEs 生成欺诈交易

我作为一个研究团队的成员与 VAEs 一起工作了一段时间。我总是想知道它们在实践中何时何地被使用。当然有很多很好的例子。在这篇博客中,我想向你展示如何使用 VAE 在高度不平衡的信用卡欺诈检测数据上训练一个分类器。

  • 如何训练一个简单的 VAE
  • 如何使用训练有素的 VAE 平衡数据?(我将讨论两种策略)
  • SMOTE 的讨论与比较

使用简单的流程生成复杂的数据。图片摘自[http://PhD thesis-bio informatics-maxplanckinstitute-molecularplanphys . Matthias-scholz . de/]

1.如何训练简单的 VAE?

VAE 是一种生成模型,试图通过将特征与一组潜在变量相关联来捕捉特征的联合概率分布。

假设有一个简单高斯分布的变量z。如果我们通过一个密集的神经网络传递这个变量,z的不同维度开始混合在一起,并在输出的维度(在这种情况下是数据的特征)之间创建高度复杂的相关性。

p(x) = p(x|z)p(z)

在提供的代码中,您将看到如何定义一个模型并训练它。

为了简化,我修改了目标,使用 MSE 作为 VAE 目标的重建部分的目标函数。所以我们训练的不是爱尔博,而是一个伪爱尔博。

我选择只在少数民族班训练 VAE。这完全忽略了数据中的结构(在这种情况下,正常的事务是什么样子)。然而,我认为这没关系,因为少数类不同于正常数据。

2.如何使用训练有素的 VAE 平衡数据?

一旦我们有了训练好的模型,我们就可以使用生成尽可能多的样本。

2.1 通过正向传递生成样本

如所解释的,使用 VAE 的分级设计,我们可以通过简单地使正态高斯分布的样本通过解码器网络来从模型中采样。根据模型的能力,我们可能会也可能不会准确地捕捉到这种分布。这就是所谓的方差高估。

使用这种方法,开箱即用的 XGBoost 分类器给出的平均精确召回分数为 0.50

2.2 通过潜在空间中的插值生成样本

另一种生成样本的方法是使用 VAE 的 autoencoder 属性。

首先,我们通过编码器网络传递现有数据。一旦我们找到了最佳点(每个潜在维度的平均值),我们就可以用它在不同的点之间进行插值。例如,我们可以取另一个第二个数据点,找到它的最佳潜在变量值,然后在潜在空间中的值之间随机插值。

Z1 ~ p(Z1 | x1),z2 ~ p(z2 | x2)

z = a Z1+(1-a)z2

x~p(x | z)

如果我们对所有可用的数据进行编码,并对它们进行许多随机配对插值,我们就可以生成许多新的样本,用少数类来扩充数据。

该方法显著改善了分类结果。我发现 XGBoost 和 Random Forest 给出了或多或少相同的召回率、f1 值和 0.65 的平均精确召回率。

结论

我们可以看到使用 VAE 对数据集进行过采样是多么容易。这种方法工作得非常好,它提高了 F1 分数和回忆分数,同时保持大约相同的准确度(并且非常高,达到 99.98%)。

然而,似乎像 SMOTE 这样更好的方法更适合过采样的工作。平心而论,如果我们有大量的维度,SMOTE 的计算量要少得多。这还能进一步改进吗?

最后的想法

我想我留给你几个问题。我可能会创建其他博客来回答这些问题。
——你认为这是 VAE 的一个好用途吗?
-您认为使用 VAE 可以在多大程度上改善过采样过程?
-你还能想到其他能受益于 VAE 的应用吗?
-有没有办法通过将信息传播到 VAE 来提高分类器的性能?

请查看这个存储库,获取工作示例、代码和更详细的讨论。
https://github.com/hosseinsadeghi/oversampling_vae

聚类算法概述

原文:https://towardsdatascience.com/overview-of-clustering-algorithms-27e979e3724d?source=collection_archive---------40-----------------------

实践聚类算法:Python 中的演练!

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

使聚集

聚类是一种无监督的技术,其中相似数据点的集合被分组在一起以形成聚类。如果簇内(同一簇内的数据点)相似性高,而簇间(簇外的数据点)相似性低,则称该簇是好的。聚类也可以被视为一种数据压缩技术,其中一个聚类的数据点可以被视为一个组。聚类也称为数据分割,因为它对数据进行分区,使得一组相似的数据点形成一个聚类。

聚类与分类有何不同?

分类算法是区分组和分类的好技术。分类需要手动标注数据,当数据集很大时,这是一个很累的过程。反过来的过程怎么样?即将相似的数据点分割在一起,并给它们分配聚类标签。聚类算法不需要标签来进一步处理,因为它是一种无监督的技术。

集群的要求

  • 可量测性
  • 应对不同属性的潜力
  • 对噪声和异常值的鲁棒性
  • 面对高维数据的能力

聚类方法

最常见的聚类方法是,

  • 分割方法
  • 分层方法
  • 基于密度的方法
  • 基于模型的方法

分区方法: 分区方法包括对数据进行分区,对相似项的组进行聚类。该方法中常用的算法有,

  • k 均值
  • k-水母类
  • k 模式

分层方法: 分层方法是将数据进行分层分解。存在两种类型的分层方法,

  • 凝聚(自下而上的方法)
  • 分裂(自上而下的方法)

基于密度的方法: 基于密度的方法用于异常检测。高密度的数据点被分组在一起,留下低密度的数据点。

  • 带噪声应用的基于密度的空间聚类
  • 光学(排序点以识别簇结构)

基于模型的方法: 基于模型的方法涉及应用模型来寻找最佳的聚类结构。

  • EM(期望最大化)算法

在这篇文章中,我们集中讨论一些分割方法和基于密度的方法的算法。

用 Python 加载所需的库

分割方法

1.k 均值聚类

k 均值聚类是一种经典的聚类方法。K-Means 通过计算一个聚类的均值来迭代地重新定位聚类中心。

  • 最初,K-Means 随机选择 k 个聚类中心。
  • 计算每个数据点和聚类中心之间的距离(通常使用欧几里德距离)。数据点被分配给与其非常接近的聚类。
  • 在所有数据点被分配到一个聚类之后,该算法计算聚类数据点的平均值,并将聚类中心重新定位到其对应的聚类平均值。
  • 这个过程一直持续到聚类中心不变。

PC:作者

使用 K-Means 的优点是可伸缩性。K-Means 在大数据上表现很好。使用 K-Means 的主要缺点是对异常值敏感。在计算聚类的均值时,离群点会产生严重的影响。聚类结果根据 k 值和聚类中心的初始选择而不同。K-Means 算法仅适用于球形数据,而不适用于任意形状的数据。

2.k-模式聚类

K-Means 适用于连续数据。分类数据呢?K-Modes 聚类可以解决这个问题。该算法非常类似于 K-Means,但是 K-Modes 不是计算聚类的平均值,而是计算聚类的模式(一个经常出现的值)。

  • 最初,K-Mode 随机选择 k 个聚类中心。
  • 计算每个数据点和聚类中心之间的相似性。数据点被分配给与其具有高相似性的聚类。
  • 在所有数据点被分配到一个聚类之后,该算法计算聚类数据点的模式,并将聚类中心重新定位到其对应的聚类模式。
  • 这个过程一直持续到聚类中心不变。

如何为 k 找到一个最优值?

肘方法和轮廓指数是最常用的方法来寻找 k 的最佳值。

基于密度的方法

1.基于密度的噪声应用空间聚类

DBSCAN(带噪声的应用程序的基于密度的空间聚类)是一种基于密度的聚类算法,能够对任意形状的数据执行良好的操作。DBSCAN 查找密集的数据点,并将其分配给一个聚类,将不太密集的数据点从该聚类中分离出来

数据库扫描术语

  • 如果一个数据点 q 在另一个数据点 p半径ϵ 内,那么该数据点 q 被认为是该数据点 pϵ-neighborhood(ε邻域)
  • 如果点 p 的ϵ-neighborhood 由 MinPts(最小点)中提到的值组成,则称数据点 p核心对象** 例如,考虑 MinPts = 5,如果 p 的ϵ-neighborhood 由 5 个数据点组成,则 p 被称为核心对象。
  • 如果点 pq 的ϵ-neighborhood 内,则称一个数据点 p 是从点 q 直接密度可达的。

它是如何工作的?DBSCAN 检查每个数据点的ϵ-neighborhood。如果 p 是核心对象,并且其在ϵ-neighborhood 的数据点高于 MinPts 的值,则它在核心对象 p 周围形成新的聚类。DBSCAN 迭代地直接寻找密度可达的数据点,并且可以合并其他少数聚类。该过程继续进行,直到不再有要分析的点。

PC:作者

使用 DBSCAN 的缺点是存在超参数ϵ和 MinPts。产生的结果因超参数的选择值而异。

2.光学

OPTICS(排序点以识别聚类结构)是一种聚类算法,克服了在 DBSCAN 中使用超参数所面临的缺点。光学与 DBSCAN 非常相似,但它使用灵活的半径ϵ.值

光学术语

  • 使点 p 成为核心对象的𝜖′的最小值(小于𝜖′的值)称为 p核心距离
  • p 的核距离和 p 与 q 之间的欧氏距离的最大值称为点 q 相对于另一个对象 p 的可达距离

PC:作者

摘要

聚类在销售和营销行业中用于识别正确的客户群。网飞使用聚类算法将兴趣相似的观众分组。聚类是研究工作的一个领域,可用算法的许多变体都处于开发阶段。

在我的 Kaggle 笔记本中找到这篇文章:https://www . ka ggle . com/srivignesh/overview-of-clustering-algorithms

参考文献:

[1]韩家玮和 Micheline Kamber,数据挖掘:概念和技术第二版(2006)

LinkedInTwitter上与我联系!**

快乐的机器学习!

谢谢!

人体姿态估计神经网络概述—HRNet+higher rnet,架构和常见问题— 2d3d.ai

原文:https://towardsdatascience.com/overview-of-human-pose-estimation-neural-networks-hrnet-higherhrnet-architectures-and-faq-1954b2f8b249?source=collection_archive---------6-----------------------

高分辨率网络(HRNet) 是一种用于人体姿势估计的最先进的神经网络,这是一种图像处理任务,可以在图像中找到对象的关节和身体部位的配置。该网络的新颖之处在于保持输入数据的高分辨率表示,并将其与高到低分辨率子网络并行组合,同时保持有效的计算复杂性和参数计数。

演示视频 HRNet 姿势估计超过世界纪录侏儒发射!

在本帖中,我们将介绍:

  • 为什么选择 HRNet?
  • 人力资源网与建筑
  • HigherHRNet:用于自下而上人体姿态估计的尺度感知表征学习
  • 演示视频
  • 代码常见问题

为什么选择 HRNet?

  • 良好的文档化和维护的开源(链接)。github 上的 2490 颗星——在所有人类姿势评估中排名最高。
  • 它被用作同一研究领域中最近的新架构的主干(例如在项目
  • 许多姿势估计挑战中的顶级竞争者(参考):

可可排名第一

可可排名第一

PoseTrack2017 排名第二

MPII 排名第六

HRNet 解释道

当处理人体姿态估计时,我们需要能够检测图像中的人,并估计他的关节(或关键点)的配置。因此,存在两种可能的姿势估计方法:

自顶向下和自底向上的姿态估计

自下而上的方法首先找到关键点,然后将它们映射到图像中的不同人物,而自上而下的方法首先使用一种机制来检测图像中的人物,在每个人物实例周围放置一个边界框区域,然后估计边界框内的关键点配置。

自上而下的方法依赖于单独的人检测网络,并且需要为每个人单独估计关键点,因此它们通常是计算密集型的,因为它们不是真正的端到端系统。相比之下,自下而上的方法首先通过预测不同解剖关键点的热图来定位输入图像中所有人的无身份关键点,然后将他们分组到人实例中,这有效地使他们更快。

自上而下的方法更为普遍,并且目前实现了更好的预测准确性,因为它将两项任务分开,以使用为每项任务训练的特定神经网络,并且因为自下而上的方法由于图像中不同人的比例变化而在预测关键点方面存在问题(也就是说,直到 HigherHRNet 出现——如下)。自顶向下方法中不存在这种比例变化,因为所有人员实例都被规范化为相同的比例。而自底向上的方法被认为更快,因为

HRNet 使用自上而下的方法,该网络是基于由另一个网络(FasterRCNN)在推理\测试期间检测的人包围盒来估计关键点而构建的。在训练期间,HRNet 使用给定数据集的带注释的边界框。

两个数据集用于训练和评估网络

  • COCO —超过 20 万张图片和 25 万个人实例,标注了 17 个关键点。COCO 数据集评估还需要评估人的边界框,这是使用 FasterRCNN 网络完成的。评估度量是对象关键点相似性(OKS)——标准的关键点检测准确度度量。
  • MPII 人体姿势——大约 25000 张照片,40000 个主题。MPII 评估是使用数据集中带注释的边界框完成的。

体系结构

以下是基于 git 项目中代码的神经网络图,之后是研究论文中描述的网络图。

基于公开开源的 HRNet 网络架构

HRNet 网络体系结构如本文所述

需要注意的重要结构是,网络计算高分辨率子网络(分支 1)与低分辨率子网络(分支 2–4)并行。子网络通过融合层融合,使得每个高到低分辨率表示反复接收来自其他并行表示的信息,导致丰富的高分辨率表示。

输入图像为 256 x 192 或 384 x 288,对应的热图输出尺寸为 64 x 48 或 96 x 72。前两个卷积根据预期的热图大小减小输入大小。网络输出热图大小和 17 个通道-热图中每个关键点(17 个关键点)的每个像素的值。

所描述的开源架构是针对 32 通道配置的。对于 48 个通道,从第一个过渡层开始改变每一层,直到 48 个通道,不同的乘数为 2。

本文中的交换块是开源中的一个模块,交换单元是开源中的保险丝层。在纸图中,过渡层看起来像子网络的独立融合,而在代码中,当创建较低分辨率(较高通道)的子网络时,过渡是基于与另一个卷积层的融合,该融合导致先前最低分辨率的子网络。此外,在开放源代码中,最后一层的融合仅针对高分辨率分支(分支 1)进行计算,而不是针对纸图中看到的所有分支。

下采样是在融合部分(或交换单元)从高分辨率分支转移到较低分辨率分支的跨距=2 的卷积,对于双倍和三倍下采样,仅在最后一次下采样中扩大通道的数量。这要么是代码中的错误,要么是论文中没有明确解释。很可能是代码中的错误,因为信息没有从较大分辨率映射到较深通道中的第一个下采样,即 git 中的开放问题。

如果有疑问,使用基于开源的图表——这是运行训练有素的网络时使用的图表。

网络培训

  • 对于权重初始化,作者使用 ImageNet 分类数据集上的不同输出层训练相同的网络,并使用权重值作为姿势估计训练的初始化值。
  • 在 COCO 数据集上训练 HRNet-W32 的 210 个历元需要大约 50-60 小时,使用 4 个 P100 GPU—参考

higher rnet:自下而上人体姿态估计的尺度感知表示学习

这是同一个研究小组使用 HRNet 作为主干的自下而上姿势跟踪的新网络。作者解决了自下而上姿态估计中的尺度变化问题(如上所述),并表示他们能够通过输出多分辨率热图和使用 HRNet 提供的高分辨率表示来解决该问题。

HigherHRNet 在 COCO 数据集上的表现优于所有其他自下而上的方法,对于中等身材的人来说收益尤其大。HigherHRNet 还在 CrowdPose 数据集上取得了最先进的结果。作者表示,这表明自下而上的方法比自上而下的方法对拥挤的场景更鲁棒,但在同一数据集上没有与常规的自上而下的 HRNet 结果进行比较。

该网络的主干是常规的 HRNet,但在末端增加了一个部分,用于输出更高分辨率的热图:

体系结构的右侧部分输出两个热图,一个用于低分辨率,一个用于高分辨率,分辨率分别为 128 x 128 和 256 x 256。在推断期间,两个热图被平均聚合到更高的分辨率,并且最高值的点被选择用于关键点检测。梯形是一个反卷积层,它输出 2 倍高的分辨率,后面是 4 个剩余块。此外,对于每个关键点,计算输出标量标签,近标签值形成属于特定人的一组关键点,远标签值指示属于不同人的关键点组。标签是根据本文中描述的“关联嵌入”方法计算的。仅针对最低分辨率的热图训练和预测标签值,因为作者发现,根据经验,较高分辨率的热图标签值无法很好地预测,甚至无法收敛。

在训练期间,损失函数是热图预测损失和标签值损失的加权平均值(根据关联嵌入方法,相同组的标签之间的较小距离导致较低的损失,不同组的标签之间的较大距离也是如此)。每个热图分辨率损失是根据地面实况独立计算的,它们是总和。

检查 HigherHRNet 的开源代码还没有推理代码可用于创建基于训练好的网络的演示姿势估计视频。

演示视频

演示视频基于 HRNet 中的推理脚本(这是一个修改过的脚本,在 joins 之间画棍子,运行时不打开 pop 图像— 脚本链接)。感谢罗斯·史密斯的 Youtube 频道。

视频特征

  • 1920X1080 像素,每秒 25 帧,56 秒(1400 帧)。
  • 多人、挑战性场景的好例子——同质和异质背景、变化的背景、不同的摄像机角度,包括放大和缩小,以及姿势令人敬畏的侏儒。

运行时信息

  • 带有 Resnet50 的 FasterRCNN 用于人员检测
  • 使用具有 48 个通道和 384 x 288 分辨率输入图像的 HRNet。
  • 戴尔笔记本电脑酷睿 i5–7200,32GB 内存,GeForce 940MX,使用 Ubuntu 18.04。推断期间 GPU 达到 100%利用率。
  • 跟踪一帧中所有边界框的平均时间:1.14 秒
  • 一帧中所有姿态估计的平均时间:0.43 秒
  • 一帧解析的平均总时间:1.62 秒
  • 代码在整个视频上运行推理的总时间:2586.09 秒

演示中的问题

当评估图像处理算法的结果时,重要的是要注意该算法哪里执行得不好,这给出了其固有问题的线索:

  • 具有木制背景的赤膊者在 faster CNN 中未被很好地检测到-这可能是 faster CNN 网络的训练数据问题,没有足够的赤膊样本或没有足够的背景颜色类似于人的颜色的样本
  • 大黄色蹦床被检测为人(分钟 00:11)-这可能显示了同质场景的快速 CNN 的固有问题。
  • 在边界框中检测到 17 个关键点,即使框中没有人或没有显示所有关节 HRNet 的构建方式是必须预测所有 17 个关节,即使它们不是可视的。

  • 值得注意的是,在视频的开始,即使有遮挡,也有很好的姿势估计。处理图像中由于模糊而丢失的信息是一件棘手的事情,HRNet 能够很好地解决这个问题。
  • 另外值得一提的是,矮人手持的棍子估计不是四肢之一,这也是一个积极的迹象。

代码常见问题

  1. 姿势跟踪在 RGB(https://github . com/leoxiaobin/deep-high-resolution-net . py torch/issues/41)中完成,而人检测基线训练网络在 BGR(https://github . com/leoxiaobin/deep-high-resolution-net . py torch/issues/15)中完成
  2. 使用 coco 数据集 API pycocotools 与 python 3【https://github.com/cocodataset/cocoapi/issues/49 不兼容。HRNet 基本上可以工作,但是一旦你开始使用 pycocotools,可能会有例外。
  3. 必须使用 numpy 1.17:https://github . com/leoxiaobin/deep-high-resolution-net . py torch/issues/177
  4. 如何用自己的数据集训练网络:https://github . com/leoxiaobin/deep-high-resolution-net . py torch/issues/68
  5. 在推理中,考虑使用 model.no_grad 来提高性能和降低内存使用量(我还没有测试过)
  6. 第三个关节参数似乎总是为零,对于 joints_3d_vis 对象,前两个参数总是具有相同的生存能力标志,而第三个参数也是零,来自 coco . py--> _ load _ coco _ key point _ annotation _ kernal()。joins dataset->getitem()->affine _ transform 中,关节的大小为 3,作为仿射变换的准备,但第三个参数从未使用过(可能是遗留的,或者,它被放置在适当的位置,供以后用于 HigherHRNet)。同样的事情似乎发生在 MPII 数据集上。
  7. 在验证\测试期间,不使用带注释的关节(即使它们保存在 dataloader 管道中),因此测试运行期间打印的准确性结果不正确。试运行期间的整个精度计算流程是多余的。在运行结束时,他们使用 coco api 来计算正确的精度度量
  8. 推理配置为 384X288(但自述文件说使用 256X192)

图像和关节变换

  • 演示/推断— box_to_center_scale()根据框缩放图像,但不清楚 pixel_std=200 做什么。关于它有几个公开的问题:
    https://github . com/Microsoft/human-pose-estimation . py torch/issues/26
    https://github . com/leoxiaobin/deep-high-resolution-net . py torch/issues/23
    https://github . com/leoxiaobin/deep-high-resolution-net . py torch/issues/9
    https://github . com 别管它了。
  • 中心和比例是根据原始图像中检测到的注释 bbox 的位置。中心是原始图像上 bbox 的中心,比例应该是 bbox 相对于原始图像的大小—来自 coco . py--> _ load _ coco _ person _ detection _ results()。bbox 由 x,y,w,h = box[:4] (x,y,width,height)构成。计算比例时,会根据预先配置的 pixel_std 和 1.25 比例进行纵横比和归一化。
  • 推理-> get _ pose _ estimation _ prediction 返回原始图像上的坐标(没有旋转,只有每个边界框的中心和比例)
  • JointsDataset-> getitem-> get _ affine _ transform 获取一个变换,该变换根据原始图像比 bbox 大多少来放大原始图像的比例,然后将图像置于 bbox 的中心。
  • 然后,warpAffine 将原始图像转移到中心,并提供缩放比例,这意味着我们应该在输出图像中看到 bbox 的区域。输出图像被裁剪,其' 0,0 点对应于原始图像上的点,该点在转换后落在 0,0 坐标上,裁剪是从该点向右下移动完成的。
  • 在训练期间,仿射变换还具有随机旋转缩放和翻转类关节 Dataset → getitem()
  • JointsDataset 中 self.db 中的对象通过引用进行更改。self.db 填充在 coco dataset-> _ load _ coco _ person _ detection _ results()类的第 246 行。
  • 变换计算是:x_new(of x_old),y_new(of y_old),z = T*(x_old,y_old,1)
    好地方看例子:https://docs . opencv . org/master/DD/d52/tutorial _ js _ geometric _ transformations . html
  • 变换后关节位置可以是负的,它们使用与图像相同的变换矩阵进行传递,并且由于存在向中心的变换和根据边界框的放大比例,一些关节可以在框外。
  • MPII 的中心和比例尺标注不完全清楚—https://github . com/leoxiaobin/deep-high-resolution-net . py torch/issues/51

原载于 2020 年 6 月 13 日https://2d3d . ai

自然语言处理中的标记化算法综述

原文:https://towardsdatascience.com/overview-of-nlp-tokenization-algorithms-c41a7d5ec4f9?source=collection_archive---------5-----------------------

符号化方法介绍,包括子词、BPE、词块和句子块

汉娜·赖特在 Unsplash 上的照片

⚠️读了我在⚠️博客中的原帖

本文是对标记化算法的概述,从词级、字符级和子词级标记化,重点是 BPE、单字 LM、词块和句子块。这意味着专家和初学者都可以阅读。如果有任何概念或解释不清楚,请与我联系,我很乐意澄清任何需要。

什么是标记化?

标记化是自然语言处理的第一步,它的任务是将一个文本序列分割成具有语义意义的单元。这些单元被称为记号,记号化的难点在于如何得到理想的拆分,使得文本中的所有记号都具有正确的含义,并且没有遗漏记号。

在大多数语言中,文本由空格分隔的单词组成,其中每个单词都有一个语义。我们稍后会看到使用符号的语言会发生什么,其中符号的含义比单词复杂得多。现在我们可以用英语工作。举个例子:

  • 原文:我吃了一个汉堡,味道不错。
  • 标记化文本:['I ',' ate ',' a ',' burger ',',' and ',' it ',' was ',' good ','.']

“Burger”是一种食物,“and”是连词,“good”是积极的形容词,等等。通过这种方式标记,每个元素都有一个意义,通过连接每个标记的所有意义,我们可以理解整个句子的意义。标点符号也有自己的记号,逗号分隔从句,句号表示句子的结束。下面是另一种标记化方法:

  • 标记化的文本:['I ate ',' a ',' bur ',' ger ',' an ',' d it ',' wa ',' s good ','.']

对于多词单位“我吃了”,我们可以只添加“我”和“吃了”的含义,对于子词单位“bur”和“ger”,它们没有单独的含义,但通过将它们连接起来,我们可以得到熟悉的单词,我们可以理解它的意思。

但是我们怎么处理它呢?这是什么意思?作为人类和说英语的人,我们可以推断出‘it’是代词,字母‘d’属于前一个单词。但在这种标记化之后,前面的单词“an”在英语中已经有了意义,冠词“an”与“and”非常不同。这个怎么处理?你可能会想:坚持使用单词,给标点符号赋予它们自己的符号。这是最常见的记号化方式,叫做词级记号化。

单词级标记化

它只包括用空格和标点符号分割句子。Python 中有很多这样的库,包括 NLTK、SpaCy、Keras、Gensim,或者你可以自定义正则表达式。

对空白进行拆分也可以拆分应该被视为单个标记的元素,例如 New York。这是有问题的,尤其是名字、借用的外国短语以及有时由多个单词组成的复合词。

像“不要”这样的词,或者像“约翰的”这样的缩写词呢?获得标记“不要”或“做”和“不要”更好吗?如果文中出现错别字,burger 变成了‘birger’怎么办?我们人类可以看到这是一个打字错误,用'汉堡'代替这个词并继续,但机器不能。错别字会影响整个 NLP 管道吗?

单词级标记化的另一个缺点是它产生了巨大的词汇量。每个标记都保存在一个标记词汇表中,如果这个词汇表是用所有输入文本中的所有唯一单词构建的,那么它将创建一个巨大的词汇表,这会在以后产生内存和性能问题。一个当前最先进的深度学习架构, Transformer XL ,拥有 267735 的词汇量。为了解决词汇量大的问题,我们可以考虑用字符代替单词来创建标记,这就是所谓的字符级标记化。

字符级标记化

Karpathy 在 2015 年首次推出,它不是将文本拆分成单词,而是拆分成字符,例如,smarter 变成了 s-m-a-r-t-e-r。词汇量大大减少到语言中的字符数,英语加上特殊字符为 26 个。拼写错误或生僻字处理得更好,因为它们被分解成字符,而这些字符在词汇表中是已知的。

在字符级标记序列已经显示出一些令人印象深刻的结果。来自 OpenAI 的拉德福德等人(2017) 表明字符级模型可以捕捉文本的语义属性。来自 Deepmind 的 Kalchbrenner 等人(2016)Leet 等人(2017) 都演示了角色层面的翻译。这些都是特别令人印象深刻的结果,因为翻译的任务是捕捉潜在文本的语义理解。

减小词汇表的大小需要权衡序列长度。现在,每个单词被拆分成所有的字符,标记化的序列比初始文本长得多。单词“smarter”被转化为 7 种不同的符号。此外,标记化的主要目标没有实现,因为字符,至少在英语中,没有语义。只有当字符连在一起时,它们才有意义。作为单词和字符标记化之间的中介,子单词标记化产生了子单词单元,比单词小,但比字符大。

子词级标记化

子词标记化示例

子词级标记化不会转换大多数常用词,而是将罕见词分解成有意义的子词单元。如果“不友好”被标记为一个罕见的词,它将被分解为“un-friend-ly”,这些都是有意义的单位,“un”表示相反的意思,“friend”是一个名词,“ly”将其转化为副词。这里的挑战是如何进行细分,我们如何做到“不友好”而不是“不友好”。

截至 2020 年,最先进的深度学习架构,基于 Transformers、使用子词级标记化。 BERT 对这个例子做了如下的记号化:

  • 原文:我有一个新的 GPU。
  • 标记化文本:['i ',' have ',' a ',' new ',' gp ',' ##u ','.']

词汇表中的单词被标记为单词本身,但是在词汇表中找不到“GPU ”,它被视为一个罕见的单词。根据一种算法,决定将其分割成‘gp-u’。“u”前的##表示这个子词与前一个子词属于同一个词。BPE、单字标记法、单词块和句子块是最常见的子词标记化算法。因为这是一个介绍性的帖子,所以会对它们进行简单的解释,如果你对更深入的描述感兴趣,请告诉我,我会为它们每个做更详细的帖子。

BPE

Sennrich 等人在 2015 年推出,它迭代合并最频繁出现的字符或字符序列。该算法大致是这样工作的:

  1. 获得足够大的语料库。
  2. 定义所需的子词词汇大小。
  3. 将单词拆分为字符序列,并附加一个特殊的标记,分别显示单词的开头或单词的结尾的词缀/后缀。
  4. 计算文本中的序列对及其频率。例如,(' t ',' h ')有频率 X,(' h ',' e ')有频率 y。
  5. 根据出现频率最高的序列对生成一个新子词。例如,如果(‘t’,‘h’)在一组对中具有最高的频率,则新的子词单元将变成‘th’。
  6. 从步骤 3 开始重复,直到达到子词词汇大小(在步骤 2 中定义)或者下一个最高频率对是 1。按照这个例子,语料库中的(' t ',' h ')将被替换为' th ',再次计算对,再次获得最频繁的对,并再次合并。

BPE 是一种贪婪和确定性的算法,不能提供多重分割。也就是说,对于给定的文本,标记化的文本总是相同的。关于 BPE 如何工作的更详细的解释将在后面的文章中详述,或者你也可以在的许多其他文章中找到。

Unigram LM

Unigram 语言建模( Kudo,2018 )基于所有子词出现都是独立的假设,因此子词序列是由子词出现概率的乘积产生的。算法的步骤如下:

  1. 获得足够大的语料库。
  2. 定义所需的子词词汇大小。
  3. 通过给出一个单词序列来优化单词出现的概率。
  4. 计算每个子字的损失。
  5. 按损失对符号进行排序,保留单词的前 X %(例如 X=80%)。为了避免超出词汇表实例,建议将字符级作为子词的子集包括在内。
  6. 重复步骤 3-5,直到达到子词词汇大小(在步骤 2 中定义)或者没有变化(步骤 5)

Kudo 认为,unigram LM 模型比 BPE 模型更灵活,因为它基于概率 LM,可以输出多个分段及其概率。它不是从一组基本符号开始学习,也不是像 BPE 或单词块那样用某种规则进行合并,而是从大量词汇(例如,所有预标记的单词和最常见的子字符串)开始,然后逐渐减少。

文字片

word piece(Schuster and Nakajima,2012 )最初用于解决日语和韩语语音问题,目前已知用于 BERT,但精确的标记化算法和/或代码尚未公开。它在许多方面与 BPE 相似,只是它基于似然性而不是下一个最高频率对来形成新的子词。算法的步骤如下:

  1. 获得足够大的语料库。
  2. 定义所需的子词词汇大小。
  3. 将单词拆分成字符序列。
  4. 用文本中的所有字符初始化词汇表。
  5. 根据词汇建立一个语言模型。
  6. 通过组合当前词汇中的两个单元来生成新的子词单元,以将词汇递增 1。当添加到模型中时,从所有可能性中选择最能增加训练数据的可能性的新子词单元。
  7. 重复步骤 5,直到达到子词词汇大小(在步骤 2 中定义)或者可能性增加低于某个阈值。

句子片断

到目前为止,所有的标记化方法都需要某种形式的预标记化,这构成了一个问题,因为不是所有的语言都使用空格来分隔单词,或者有些语言是由符号组成的。SentencePiece 可以接受特定语言的预发音。你可以在 Github 找到开源软件。例如, XLM 使用了句子片断,并为中文、日文和泰文添加了特定的前缀词。

SentencePiece 在概念上类似于 BPE,但它不使用贪婪的编码策略,实现了更高质量的标记化。SentencePiece 认为字符分组中的模糊性是训练期间模型正则化的一个来源,这使得训练变得更慢,因为有更多的参数需要优化,并且不鼓励 Google 在 BERT 中使用它,而是选择 WordPiece。

结论

历史上,标记化方法已经从单词发展到字符,最近发展到子单词级别。这是对标记化方法的一个快速概述,我希望文本是可读和可理解的。关注我的推特了解更多 NLP 信息,或者在那里问我任何问题:)

人工智能关键技术综述

原文:https://towardsdatascience.com/overview-of-the-key-technologies-of-artificial-intelligence-1765745cee3?source=collection_archive---------31-----------------------

探索大数据和人工智能

构建人工智能平台的关键组件

人工智能是一门研究和发展模拟人类智能延伸和扩展的理论、方法、技术和应用系统的新技术学科。人工智能研究的目标是让机器执行一些需要智能人类才能完成的复杂任务。也就是说,我们希望机器可以代替我们解决一些复杂的任务,不仅仅是重复的机械活动,而是一些需要人类智慧参与的活动。在本文中,我将向您概述人工智能技术以及构建人工智能平台的关键组件。

人工智能的关键技术

人工智能的关键技术自下而上可分为基础设施层和算法层。在基础设施层,有基础硬件,包括 CPU、GPU、专用人工智能芯片、高速网络。在这个基础硬件之上,我们可以搭建算法框架,比如 Tensorflow、Caffe、Mxnet、Torch、Keras、PyTorch、Theano 等。基础设施层之上是算法层。算法层最具代表性的是机器学习算法,包括深度学习、迁移学习、一般对抗网络、强化学习等一系列机器学习算法。

基础设施层

基本硬件

随着我们介绍人工智能基础设施的基础硬件,分为 CPU、GPU、专用芯片、高速网络四个方向,我们来说两个类似的:CPU 和 GPU。CPU 主要针对一组串行执行的任务进行优化,而 GPU 主要针对复杂的图形和图像计算算法进行优化。两者的区别在于,CPU 是串行执行的,而 GPU 是更小、更高效的计算单元,它们一起并行处理计算。此外,还有一种专门为人工智能算法开发的特殊芯片,即谷歌的 TPU 芯片。

克里斯蒂安·威迪格Unsplash 上拍摄的照片

为了充分利用人工智能的能力,我们需要高速网络。在一些复杂数据模型的训练和计算过程中,我们需要巨大的网络带宽保证。如今,网络已经成为整体机器学习性能的重要组成部分。现在我们通常有 10G、20G、40G 网络。随着 Infiniband 网络技术的出现,相信在未来,网络将为人工智能的学习和训练提供更广阔、更快捷的通道。

Webaroo.com.au 在 Unsplash的照片

算法框架

基础设施中的第二层是算法框架。算法框架可以简单理解为运行算法的框架。就像一个建筑框架,我们可以在上面运行我们的业务。Google 开发了一个非常著名的框架,叫做 TensorFlow,友好、快捷、方便。TensorFlow 让我们在里面实现相关的 AI 算法,运行这些方法。

照片由🇨🇭·克劳迪奥·施瓦茨| @purzlbaumUnsplash 上拍摄

算法层

我刚才讲了算法框架,那我就讲算法。首先,机器学习是人工智能中的一个核心概念。我们所有人都要学习,我们人类的知识传递也是通过这样的学习方法进行的。我们学习祖先的知识,然后通过推理创造新的知识。我们也希望机器有这样的能力:通过学习之前的信息,让机器更像有智能,能够对未来新的输入做出相应的反应。这叫做机器学习。

机器学习过程

你知道机器学习最典型的过程是什么吗?首先,我们收集历史数据,然后我们训练历史数据。我们从训练结果中得到一个模型。然后,随着新数据输入到模型中,我们可以预测我们的结果。这是最典型的机器学习过程。我们可以简单的说,通过训练产生一个模型,然后用模型来指导新数据的预测。

我们以房价预测为例。首先,我们假设房价只和房子的面积有关。我们可以输入一维数据,如历史房价和房屋面积的一维数据。在房价模型中,我们可以通过训练预测进入新房区域后的房价。这是一个最简单的机器学习的例子。

机器学习的分类

在机器学习中,我们可以将其分为监督学习算法、非监督学习算法和半监督学习算法。那么它们之间有什么区别呢?

布鲁诺·马丁斯在 Unsplash 上的照片

首先,我们来看看监督学习。有监督的学习意味着这种学习在训练时是有标签的。如果标签是离散的,我们称之为分类。如果标签是连续的,我们称之为回归。这是监督学习。

无监督学习是无标签的,也就是我们常说的聚类。

最后一种半监督学习,也就是说它里面的样本有的是有标签的,有的是没有标签的,放在一起进行更复杂的混合运算,那么它就变成了半监督学习算法。

深度学习算法

当我们谈论人工智能时,我们经常会听到机器学习和深度学习等概念。其实它们是一种包容关系,人工智能包括机器学习和深度学习,而机器学习中的一种特定的学习形式叫做深度学习。它主要基于神经网络算法。目前,深度学习已经在图像识别、语音识别、自然语言处理、音频识别、社交网络过滤、机器翻译、医学图像分析、棋盘游戏程序等领域取得了很大进展。

神经网络

说到深度学习算法,就不得不说卷积神经网络和递归神经网络。神经网络类似于人脑的神经传递,从一个输入单元到下一个输入单元得到一个结果。这是一个简单的神经网络的原理,就是模拟人脑中神经传递信息。它将信息从一个神经元传递到另一个神经元,然后向下传递。随着神经网络算法的兴起,深度学习算法可以解决很多实际问题。

BP 神经网络

神经网络算法发明后,很多问题在一定程度上得到了解决。同时,人们也在不断优化这个算法。首先,一个应用非常广泛并且非常经典的是 BP 神经网络。BP 神经网络比原神经网络多了一个隐含层。输入层和输出层中还有其他隐藏层。通过梯度下降的方式可以大大降低计算量和计算难度。

卷积神经网络

但是有了 BP 神经网络之后,我们发现 BP 神经网络的计算量还是很大。它有时无法在我们可接受的时间范围内给出最优解,或者给出最优解的时间太长,不符合我们某些应用的需求。然后出现了卷积神经网络(CNN),它本质上也是一种神经网络算法,但它优化了 BP 神经网络中的内容,它使计算更快,并且它可以在许多问题上获得最大化。出色的解决方案。它通过高度并行地处理相关信息来提高其计算效率。同时,大大降低了 BP 神经网络之间的计算复杂度。因此,卷积神经网络目前可以在很多问题上快速达到最优解。

递归神经网络

目前通过这种学习算法训练出来的递归神经网络模型,已经达到了可以写诗的结果。它不是单项输出,它是用以前的输出作为重新输入,重新进入模型行计算。这个模型很神奇,因为它有一定的记忆能力。

迁移学习

在传统的机器学习中,我们针对特定的问题训练了几个不同的模型,每个模型都可以解决这类问题。在迁移学习中,我们试图将某个领域(我们称之为原域)的训练结果存储为知识。我们在原始域中训练算法。经过训练,我们希望它能解决新的问题,这就是所谓的有针对性的任务。在我们输入目标任务后,它可以根据在解决原有领域的问题时积累的知识来推断新的问题,并且可以在不需要训练的情况下得到结果。我们称之为迁移学习,将之前学习的结果转移到新的问题中。

生成对抗网络

生成对抗网络(GAN)中的“对抗”一词是指生成的两个网络之间存在竞争关系。在这两个网络中,一个负责生成样本,另一个负责确定样本的正确性。产生样本的小组希望愚弄鉴别样本的小组。鉴别样本的群体希望不要被产生样本的群体的结果所愚弄,它们之间有一定的竞争和对抗关系。在这样的关系中产生一个学习结果更准确。

强化学习

强化学习也是机器学习的一个重要分支。它的本质是解决决策问题,即自动决策,连续决策。主要包括两部分,首先是代理人,然后是环保行动奖励。强化学习的目标是获得最多的累积奖励。我们举个例子,一个婴儿学走路就是一个强化学习的过程。宝宝是一个代理人,他希望通过一个动作比如走路来改变环境的状态。他走的每一步都是状态的变化。如果他迈出了正确的一步,我们会给他奖励。否则,如果他没有迈出正确的一步,那么我们就不给他奖励。通过这个过程,一个小宝宝慢慢学会了走路。

人工智能平台

构建人工智能平台的目标是为用户提供人工智能研发所需的基础设施、算法、计算能力和相关数据。许多大公司规划并建立了统一的人工智能 R&D 云平台,部署在混合云资源池中,并直接连接到 IT 大数据平台。统一的人工智能研发云平台主要由数据平台、深度学习平台和人工智能能力平台组成。其中,数据平台可以提供开放的公共数据集,提供数据挖掘所需的海量数据,可以很好地挖掘大部分大事务所存储的大数据优势,提供数据标注和数据共享服务。深度学习平台是基于 AI 硬件的 AI 集群,集成了主流的深度学习算法框架,为 AI 开发提供基础设施支持,如算法和计算能力。人工智能能力平台提供核心人工智能能力,如语音语义、图形图像和智能数据分析,以及数据模型管理和共享机制。

摘要

让我们总结一下这部分所学的内容。在这一部分,我们首先对人工智能的关键技术进行了概述。它包括基础设施层和算法层。然后我们解释了基础设施层的一些主要基础设施,包括硬件 CPU,GPU,网络,和专用芯片以及我们在基础设施层构建的底层技术算法的框架,非常有代表性的是 Google 的 Tensorflow。我们还介绍了一些经典的人工智能算法,如对抗学习、强化学习等。

补充一下,人工智能的发展也必须依靠大数据技术。它需要大量的数据来支持。技术创新才刚刚开始,还有更多的新技术需要我们不断学习。技术创新才刚刚开始,还有更多的新技术需要我们不断学习。

Google BigQuery 主要特性概述——练习撰写营销分析请求

原文:https://towardsdatascience.com/overview-of-the-main-google-bigquery-features-28f3ef3af6f?source=collection_archive---------39-----------------------

来源: Unsplash

在本文中,我们将研究 BigQuery 的主要功能,并通过具体的例子展示它们的可能性。您将学习如何编写基本的查询并在演示数据上测试它们。

企业积累的信息越多,在哪里存储信息的问题就越尖锐。如果你没有能力或者没有意愿维护自己的服务器, Google BigQuery (GBQ)可以帮忙。BigQuery 为处理大数据提供了快速、经济高效且可扩展的存储,它允许您使用类似 SQL 的语法以及标准和用户定义函数编写查询。

什么是 SQL,BigQuery 支持哪些方言

结构化查询语言(SQL)允许您在大型数组中检索数据、添加数据和修改数据。Google BigQuery 支持两种 SQL 方言:标准 SQL 和过时的遗留 SQL。

选择哪种方言取决于您的偏好,但是 Google 建议使用标准 SQL,因为它有以下好处:

  • 嵌套和重复字段的灵活性和功能性
  • 支持 DMLDDL 语言,允许您更改表中的数据以及管理 GBQ 中的表和视图
  • 与传统 SQL 相比,处理大量数据的速度更快
  • 支持所有未来的 BigQuery 更新

您可以在 BigQuery 文档中了解更多关于方言差异的信息。

默认情况下,Google BigQuery 查询在遗留 SQL 上运行。

您可以通过几种方式切换到标准 SQL:

  1. 在 BigQuery 界面的查询编辑窗口中,选择显示选项并取消勾选使用遗留 SQL 旁边的复选标记:

图片由作者提供

  1. 在查询之前,添加#standardSQL 行,并从新行开始查询:

图片由作者提供

从哪里开始

首先,下载您的演示数据表,并将其上传到您的 Google BigQuery 项目。最简单的方法是使用 OWOX BI BigQuery Reports 插件。

  1. 打开 Google Sheets 并安装 OWOX BI BigQuery Reports 插件
  2. 打开下载的包含演示数据的表格,选择OWOX BI big query Reports–>上传数据到 BigQuery :

图片由作者提供

  1. 在打开的窗口中,选择您的 Google BigQuery 项目,一个数据集,并为将要存储加载数据的表想一个名称。
  2. 指定加载数据的格式(如屏幕截图所示):

图片由作者提供

如果您在 Google BigQuery 中没有项目,创建一个。要做到这一点,你需要在谷歌云平台中有一个活跃的付费账户。不要让你需要链接银行卡吓到你:在你不知情的情况下,你不会被收取任何费用。此外,当你注册时,你会收到 12 个月的 300 美元,你可以用它来存储和处理数据。

在讨论 Google BigQuery 特性之前,让我们记住传统 SQL 和标准 SQL 方言中的基本查询是什么样的:

Google BigQuery 特性

在构建查询时,您将最常使用聚合、日期、字符串和窗口函数。让我们仔细看看每一组函数。

聚合函数

聚合函数为整个表提供汇总值。例如,您可以使用它们来计算平均支票金额或每月总收入,或者您可以使用它们来选择购买次数最多的用户群。

这些是最常用的聚合函数:

让我们看看演示数据,看看这些函数是如何工作的。我们可以计算交易的平均收入、最高和最低金额的购买、总收入、总交易和唯一交易的数量(以检查购买是否重复)。为此,我们将编写一个查询,在其中指定 Google BigQuery 项目的名称、数据集和表。

#传统 SQL

**SELECT**   
  **AVG**(revenue) **as** average_revenue,   
  **MAX**(revenue) **as** max_revenue,   
  **MIN**(revenue) **as** min_revenue,   
  **SUM**(revenue) **as** whole_revenue,   
  **COUNT**(transactionId) **as** transactions,      EXACT_COUNT_DISTINCT(transactionId) **as** unique_transactions 
**FROM**   
  [owox-analytics:t_kravchenko.Demo_data]

#标准 SQL

**SELECT**   
  **AVG**(revenue) **as** average_revenue,   
  **MAX**(revenue) **as** max_revenue,   
  **MIN**(revenue) **as** min_revenue,   
  **SUM**(revenue) **as** whole_revenue,   
  **COUNT**(transactionId) **as** transactions,      **COUNT**(**DISTINCT**(transactionId)) **as** unique_transactions 
**FROM**   
  `owox-analytics.t_kravchenko.Demo_data`

结果,我们将得到以下结果:

图片由作者提供

您可以使用标准的 Google Sheets 函数(SUM、AVG 和其他函数)或使用数据透视表,在带有演示数据的原始表格中检查这些计算的结果。

从上面的截图可以看出,交易数和唯一交易数是不一样的。这表明我们的表中有两个事务具有相同的 transactionId:

图片由作者提供

如果您对唯一的事务感兴趣,请使用计算唯一字符串的函数。或者,您可以使用 GROUP BY 函数对数据进行分组,以便在应用聚合函数之前消除重复项。

日期函数

这些函数允许您处理日期:更改它们的格式,选择必要的字段(日、月或年),或者将日期移动一定的间隔。

在下列情况下,它们可能有用:

  • 将不同来源的日期和时间转换为单一格式,以设置高级分析
  • 创建自动更新的报告或触发邮件(例如,当您需要过去两个小时、一周或一个月的数据时)
  • 创建群组报告,其中需要获取几天、几周或几个月的数据

这些是最常用的日期函数:

有关所有日期函数的列表,请参见遗留 SQL标准 SQL 文档。

让我们来看看我们的演示数据,看看这些函数是如何工作的。例如,我们将获取当前日期,将原始表中的日期转换为格式% YYYY -% MM-% DD,将其删除,并添加一天。然后,我们将计算当前日期和源表中的日期之间的差值,并将当前日期分成单独的年、月和日字段。为此,您可以复制下面的示例查询,并用您自己的查询替换项目名称、数据集和数据表。

#传统 SQL

**SELECT** **CURRENT_DATE**() **AS** today,     
DATE( date_UTC ) **AS** date_UTC_in_YYYYMMDD,    
**DATE_ADD**( date_UTC,1, 'DAY') **AS** date_UTC_plus_one_day,              **DATE_ADD**( date_UTC,-1, 'DAY') **AS** date_UTC_minus_one_day,     **DATEDIFF**(**CURRENT_DATE**(), date_UTC ) **AS** difference_between_date,     **DAY**( **CURRENT_DATE**() ) **AS** the_day,     
**MONTH**( **CURRENT_DATE**()) **AS** the_month,     
**YEAR**( **CURRENT_DATE**()) **AS** the_year   
**FROM**     
  [owox-analytics:t_kravchenko.Demo_data]

#标准 SQL

**SELECT** 

today,   
date_UTC_in_YYYYMMDD,   
 **DATE_ADD**( date_UTC_in_YYYYMMDD, INTERVAL 1 **DAY**) **AS**                            date_UTC_plus_one_day,   
 **DATE_SUB**( date_UTC_in_YYYYMMDD,INTERVAL 1 **DAY**) **AS** date_UTC_minus_one_day,   
 DATE_DIFF(today, date_UTC_in_YYYYMMDD, **DAY**) **AS** difference_between_date,   
 **EXTRACT**(**DAY** **FROM** today ) **AS** the_day,   
 **EXTRACT**(**MONTH** **FROM** today ) **AS** the_month,   
 **EXTRACT**(**YEAR** **FROM** today ) **AS** the_year 
**FROM** (   
  **SELECT**     
    **CURRENT_DATE**() **AS** today,     
    DATE( date_UTC ) **AS** date_UTC_in_YYYYMMDD   
**FROM**     
  `owox-analytics.t_kravchenko.Demo_data`)

运行查询后,您将收到以下报告:

图片由作者提供

字符串函数

字符串函数允许您生成一个字符串,选择和替换子字符串,计算字符串的长度以及子字符串在原始字符串中的索引序列。例如,使用字符串函数,您可以:

  • 使用传递到页面 URL 的 UTM 标签过滤报表
  • 如果源和活动名称写在不同的寄存器中,将数据转换为单一格式
  • 替换报告中不正确的数据(例如,如果活动名称打印错误)

以下是处理字符串最常用的函数:

您可以在遗留 SQL标准 SQL 文档中了解更多关于所有字符串函数的信息。

让我们看看演示数据,看看如何使用所描述的功能。假设我们有三个分别包含日、月和年值的列:

图片由作者提供

使用这种格式的日期不太方便,所以我们可以将这些值合并到一列中。为此,请使用下面的 SQL 查询,并记住在 Google BigQuery 中替换您的项目、数据集和表的名称。

#遗留 SQL

**SELECT**   
  **CONCAT**(the_day,'-',the_month,'-',the_year) **AS** mix_string1 
**FROM** (   
  **SELECT**     
    31 **AS** the_day,     
    12 **AS** the_month,     
    2018 **AS** the_year   
  **FROM**     
    [owox-analytics:t_kravchenko.Demo_data]) 
**GROUP** **BY**   
  mix_string1

#标准 SQL

**SELECT**   
  **CONCAT**(the_day,'-',the_month,'-',the_year) **AS** mix_string1 
**FROM** (   
  **SELECT**     
    31 **AS** the_day,     
    12 **AS** the_month,     
    2018 **AS** the_year   
  **FROM**     
    owox-analytics.t_kravchenko.Demo_data) 
**GROUP** **BY**   
  mix_string1

运行查询后,我们在一列中收到日期:

图片由作者提供

通常,当您在网站上下载页面时,URL 会记录用户选择的变量的值。这可以是支付或交付方法、交易号、购买者想要提取物品的实体店的索引等。使用 SQL 查询,您可以从页面地址中选择这些参数。考虑两个例子来说明如何以及为什么要这样做。

1 。假设我们想知道用户从实体店提货的购买次数。为此,我们需要计算从 URL 中包含子字符串 shop_id(实体店的索引)的页面发送的交易数量。我们可以通过以下查询来实现这一点:

#遗留 SQL

**SELECT**   
  **COUNT**(transactionId) **AS** transactions,   
  **check** 
**FROM** (   
  **SELECT**     
    transactionId,     
    page CONTAINS 'shop_id' **AS** **check**   
**FROM**     
  [owox-analytics:t_kravchenko.Demo_data]) 
**GROUP** **BY**   
  **check**

#标准 SQL

**SELECT**   
  **COUNT**(transactionId) **AS** transactions,   
  check1,   
  check2 
**FROM** (   
  **SELECT**     
    transactionId,     
    REGEXP_CONTAINS( page, 'shop_id') **AS** check1,     
    page **LIKE** '%shop_id%' **AS** check2   
**FROM**     
  `owox-analytics.t_kravchenko.Demo_data`) 
**GROUP** **BY**    
  check1,   
  check2

从结果表中,我们看到 5502 个交易(check = true)是从包含 shop_id 的页面发送的:

图片由作者提供

例二。您已经为每种交付方法分配了一个 delivery_id,并在页面 URL 中指定了该参数的值。要找出用户选择了哪种交付方法,您需要在单独的列中选择 delivery_id。

为此,我们可以使用以下查询:

#传统 SQL

**SELECT**   
  page_lower_case,    
  page_length,   
  index_of_delivery_id,   
  selected_delivery_id,   
  **REPLACE**(selected_delivery_id, 'selected_delivery_id=', '') **as** delivery_id 
**FROM** (   
  **SELECT**     
    page_lower_case,     
    page_length,     
    index_of_delivery_id,     
    **SUBSTR**(page_lower_case, index_of_delivery_id) **AS** selected_delivery_id   
**FROM** (     
  **SELECT**       
    page_lower_case,       
    **LENGTH**(page_lower_case) **AS** page_length,                 **INSTR**(page_lower_case, 'selected_delivery_id') **AS** index_of_delivery_id     
**FROM** (       
  **SELECT**         
    **LOWER**( page) **AS** page_lower_case,         
    **UPPER**( page) **AS** page_upper_case       
**FROM**         
  [owox-analytics:t_kravchenko.Demo_data]))) 
**ORDER** **BY**   
  page_lower_case **ASC**

#标准 SQL

**SELECT**   
  page_lower_case,   
  page_length,   
  index_of_delivery_id,   
  selected_delivery_id,   
  **REPLACE**(selected_delivery_id, 'selected_delivery_id=', '') **AS** delivery_id 
**FROM** (   
  **SELECT**     
    page_lower_case,     
    page_length,     
    index_of_delivery_id,     
    **SUBSTR**(page_lower_case, index_of_delivery_id) **AS** selected_delivery_id   
**FROM** (     
  **SELECT**       
    page_lower_case,       
    **CHAR_LENGTH**(page_lower_case) **AS** page_length,         STRPOS(page_lower_case, 'selected_delivery_id') **AS** index_of_delivery_id     
**FROM** (       
  **SELECT**         
    **LOWER**( page) **AS** page_lower_case,         
    **UPPER**( page) **AS** page_upper_case       
**FROM**         
  `owox-analytics.t_kravchenko.Demo_data`))) 
**ORDER** **BY**   
  page_lower_case **ASC**

结果,我们在 Google BigQuery 中得到这样一个表:

图片由作者提供

窗口功能

这些函数类似于我们上面讨论的聚合函数。主要区别在于,窗口函数不在使用查询选择的整个数据集上执行计算,而只在部分数据上执行计算——子集或窗口

使用窗口函数,您可以在组节中聚合数据,而无需使用 JOIN 函数来组合多个查询。例如,您可以计算每个广告活动的平均收入或每台设备的交易数量。通过向报表中添加另一个字段,您可以很容易地找到,例如,黑色星期五广告活动的收入份额或移动应用程序的交易份额。

除了查询中的每个函数,您还必须详细说明定义窗口边界的 OVER 表达式。OVER 包含您可以使用的三个组件:

  • 分区依据—定义将原始数据划分为子集的特征,如 clientId 或 DayTime
  • 排序依据-定义子集中行的顺序,例如小时 DESC
  • 窗口框架-允许您处理特定要素子集内的行(例如,仅当前行之前的五行)

在此表中,我们收集了最常用的窗口函数:

您可以在遗留 SQL 和标准 SQL 的文档中看到所有聚合分析函数和 导航函数的列表。

1 。假设我们想要分析客户在工作时间和非工作时间的活动。为此,我们需要将事务分为两组,并计算感兴趣的指标:

  • 1 组—在 9:00 至 18:00 的工作时间内购买
  • 第 2 组—00:00 至 9:00 和 18:00 至 23:59 的下班后购买

除了工作和非工作时间,形成窗口的另一个变量是 clientId。也就是说,对于每个用户,我们将有两个窗口:

让我们使用演示数据来计算平均、最大、最小和总收入、交易总数,以及每个用户在工作时间和非工作时间的唯一交易数。下面的请求将帮助我们做到这一点。

#传统 SQL

**SELECT**   
  date,   
  clientId,   
  DayTime,   
  avg_revenue,   
  max_revenue,   
  min_revenue,   
  sum_revenue,   
  transactions,   
  unique_transactions 
**FROM** (   
  **SELECT**     
    date,     
    clientId,     
    DayTime,     
    **AVG**(revenue) **OVER** (**PARTITION** **BY** date, clientId, DayTime) **AS** avg_revenue,     
    **MAX**(revenue) **OVER** (**PARTITION** **BY** date, clientId, DayTime) **AS** max_revenue,     
    **MIN**(revenue) **OVER** (**PARTITION** **BY** date, clientId, DayTime) **AS** min_revenue,     
    **SUM**(revenue) **OVER** (**PARTITION** **BY** date, clientId, DayTime) **AS** sum_revenue,     
    **COUNT**(transactionId) **OVER** (**PARTITION** **BY** date, clientId, DayTime) **AS** transactions,     
    **COUNT**(**DISTINCT**(transactionId)) **OVER** (**PARTITION** **BY** date, clientId, DayTime) **AS** unique_transactions   
**FROM** (     
  **SELECT**       
    date,       
    date_UTC,       
    clientId,       
    transactionId,       
    revenue,       
    page,       
    **hour**,       
    **CASE**         
      **WHEN** **hour**>=9 **AND** **hour**<=18 **THEN** 'working hours'         
      **ELSE** 'non-working hours'       
**END** **AS** DayTime     
**FROM**       
  [owox-analytics:t_kravchenko.Demo_data])) 
**GROUP** **BY**   
  date,   
  clientId,   
  DayTime,   
  avg_revenue,   
  max_revenue,   
  min_revenue,   
  sum_revenue,   
  transactions,   
  unique_transactions 
**ORDER** **BY**   
  transactions **DESC**

#标准 SQL

#standardSQL 
**SELECT**   
  date,   
  clientId,   
  DayTime,   
  avg_revenue,   
  max_revenue,   
  min_revenue,   
  sum_revenue,   
  transactions,   
  unique_transactions 
**FROM** (   
  **SELECT**     
    date,     
    clientId,     
    DayTime,     
    **AVG**(revenue) **OVER** (**PARTITION** **BY** date, clientId, DayTime) **AS** avg_revenue,     
    **MAX**(revenue) **OVER** (**PARTITION** **BY** date, clientId, DayTime) **AS** max_revenue,     
    **MIN**(revenue) **OVER** (**PARTITION** **BY** date, clientId, DayTime) **AS** min_revenue,     
    **SUM**(revenue) **OVER** (**PARTITION** **BY** date, clientId, DayTime) **AS** sum_revenue,     
    **COUNT**(transactionId) **OVER** (**PARTITION** **BY** date, clientId, DayTime) **AS** transactions,     
    **COUNT**(**DISTINCT**(transactionId)) **OVER** (**PARTITION** **BY** date, clientId, DayTime) **AS** unique_transactions   
**FROM** (     
  **SELECT**       
    date,       
    date_UTC,       
    clientId,       
    transactionId,       
    revenue,       
    page,       
    **hour**,       
    **CASE**         
      **WHEN** **hour**>=9 **AND** **hour**<=18 **THEN** 'working hours'         
      **ELSE** 'non-working hours'       
    **END** **AS** DayTime     
**FROM**       
  `owox-analytics.t_kravchenko.Demo_data`)) 
**GROUP** **BY**   
  date,   
  clientId,   
  DayTime,   
  avg_revenue,   
  max_revenue,   
  min_revenue,   
  sum_revenue,   
  transactions,   
  unique_transactions 
**ORDER** **BY**   
  transactions **DESC**

让我们以 clientId 为 1020 的用户为例,看看结果会怎样。56660.68668686661 在该用户的原始表中,我们有以下数据:

图片由作者提供

通过运行该查询,我们将收到一份报告,其中包含来自该用户的平均、最小、最大和总收入,以及该用户的交易总数。正如您在下面的截图中看到的,这两笔交易都是用户在工作时间进行的:

图片由作者提供

例二。现在是一个更复杂的任务:

  • 根据事务的执行时间,将所有事务的序列号放在窗口中。回想一下,我们通过用户和工作/非工作时隙来定义窗口。
  • 报告窗口内下一个/上一个交易(相对于当前交易)的收入。
  • 在窗口中显示第一笔和最后一笔交易的收入。

为此,我们将使用以下查询:

#遗留 SQL

**SELECT**   
  date,   
  clientId,   
  DayTime,   
  **hour**,   
  **rank**,   
  revenue,   
  lead_revenue,   
  lag_revenue,   
  first_revenue_by_hour,   
  last_revenue_by_hour 
**FROM** (   
  **SELECT**     
    date,     
    clientId,     
    DayTime,     
    **hour**,     
    **DENSE_RANK**() **OVER** (**PARTITION** **BY** date, clientId, DayTime **ORDER** **BY** **hour**) **AS** **rank**,     revenue,     
    **LEAD**( revenue, 1) **OVER** (**PARTITION** **BY** date, clientId, DayTime **ORDER** **BY** **hour**) **AS** lead_revenue,     
    LAG( revenue, 1) **OVER** (**PARTITION** **BY** date, clientId, DayTime **ORDER** **BY** **hour**) **AS** lag_revenue,     
    **FIRST_VALUE**(revenue) **OVER** (**PARTITION** **BY** date, clientId, DayTime **ORDER** **BY** **hour**) **AS** first_revenue_by_hour,     
    **LAST_VALUE**(revenue) **OVER** (**PARTITION** **BY** date, clientId, DayTime **ORDER** **BY** **hour**) **AS** last_revenue_by_hour   
**FROM** (     
  **SELECT**       
    date,       
    date_UTC,       
    clientId,       
    transactionId,       
    revenue,       
    page,       
    **hour**,       
    **CASE**         
      **WHEN** **hour**>=9 **AND** **hour**<=18 **THEN** 'working hours'         
      **ELSE** 'non-working hours'       
    **END** **AS** DayTime     
**FROM**       
  [owox-analytics:t_kravchenko.Demo_data])) 
**GROUP** **BY**   
  date,   
  clientId,   
  DayTime,   
  **hour**,   
  **rank**,   
  revenue,   
  lead_revenue,   
  lag_revenue,   
  first_revenue_by_hour,   
  last_revenue_by_hour 
**ORDER** **BY**   
  date,   
  clientId,   
  DayTime,   
  **hour**,   
  **rank**,   
  revenue,   
  lead_revenue,   
  lag_revenue,   
  first_revenue_by_hour,   
  last_revenue_by_hour

#标准 SQL

**SELECT**   
  date,   
  clientId,   
  DayTime,   
  **hour**,   
  **rank**,   
  revenue,   
  lead_revenue,   
  lag_revenue,   
  first_revenue_by_hour,   
  last_revenue_by_hour 
**FROM** (   
  **SELECT**     
    date,     
    clientId,     
    DayTime,     
    **hour**,     
    **DENSE_RANK**() **OVER** (**PARTITION** **BY** date, clientId, DayTime **ORDER** **BY** **hour**) **AS** **rank**,     revenue,     
    **LEAD**( revenue, 1) **OVER** (**PARTITION** **BY** date, clientId, DayTime **ORDER** **BY** **hour**) **AS** lead_revenue,     
    LAG( revenue, 1) **OVER** (**PARTITION** **BY** date, clientId, DayTime **ORDER** **BY** **hour**) **AS** lag_revenue,     
    **FIRST_VALUE**(revenue) **OVER** (**PARTITION** **BY** date, clientId, DayTime **ORDER** **BY** **hour**) **AS** first_revenue_by_hour,     
    **LAST_VALUE**(revenue) **OVER** (**PARTITION** **BY** date, clientId, DayTime **ORDER** **BY** **hour**) **AS** last_revenue_by_hour   
**FROM** (     
  **SELECT**       
    date,       
    date_UTC,       
    clientId,       
    transactionId,       
    revenue,       
    page,       
    **hour**,       
    **CASE**         
      **WHEN** **hour**>=9 **AND** **hour**<=18 **THEN** 'working hours'         
      **ELSE** 'non-working hours'       
   **END** **AS** DayTime     
**FROM**       
  `owox-analytics.t_kravchenko.Demo_data`)) 
**GROUP** **BY**   
  date,   
  clientId,   
  DayTime,   
  **hour**,   
  **rank**,   
  revenue,   
  lead_revenue,   
  lag_revenue,   
  first_revenue_by_hour,   
  last_revenue_by_hour 
**ORDER** **BY**   
  date,   
  clientId,   
  DayTime,   
  **hour**,   
  **rank**,   
  revenue,   
  lead_revenue,   
  lag_revenue,   
  first_revenue_by_hour,   
  last_revenue_by_hour

我们可以使用一个已知用户的例子来检查计算结果:clientId 10 204 2036767636767

图片由作者提供

从上面的截图中,我们可以看到:

  • 第一笔交易在 15:00,第二笔交易在 16:00
  • 15:00 交易后,16:00 有一笔交易,收入 25066(列 lead_revenue)
  • 在 16:00 交易之前,15:00 有一笔交易,收入 3699(列 lag_revenue)
  • 窗口内的第一笔交易发生在 15:00,此交易的收入为 3699(first _ revenue _ by _ hour 列)
  • 该查询逐行处理数据,因此对于所讨论的事务,窗口中的最后一个事务将是它本身,并且 last_revenue_by_hour 和 revenue 列中的值将是相同的

结论

在本文中,我们研究了最流行的函数组:聚合、日期、字符串和窗口。然而,Google BigQuery 有许多更有用的功能,包括:

  • 允许您将数据转换为特定格式的转换函数
  • 允许您访问数据集中多个表的表通配符函数
  • 正则表达式函数,允许您描述搜索查询的模型,而不是它的确切值

两大云数据仓库概述:亚马逊红移和 Azure SQL DWH

原文:https://towardsdatascience.com/overview-of-the-top-2-cloud-data-warehouses-amazon-redshift-azure-sql-dwh-6ff42fc26052?source=collection_archive---------45-----------------------

了解云数据仓库相对于传统数据仓库的优势

Unsplash 上由 C Dustin 拍摄的照片

简介

在云数据仓库出现之前,大多数公司采用传统的数据仓库。

传统的数据仓库系统允许从组织的各种外部或内部来源收集数据以支持分析操作,但存在各种困难。

一般来说,传统数据仓库的体系结构由三层组成:

  • 底层由不同种类的支持工具和实用程序组成,它们从不同的来源提取数据,转换数据并将其加载到数据仓库中。
  • 中间层,以 OLAP 服务器为特征,这些服务器执行业务数据的多维分析,以便将数据转换成允许进行复杂计算的格式。
  • 顶层,我们可以在其中使用不同的查询和报告工具。因此,我们可以执行数据分析和数据挖掘。

无论如何,为了维持这种系统,公司花费了大量资金来维护硬件、服务器机房以及雇佣特定团队来运行它的成本。云数据仓库成为这些问题的解决方案。

在本文中,我将向您概述当今最常用的云数据仓库,即 Amazon Redshift 和 Azure 数据仓库。

照片由晨酿Unsplash 上拍摄

第一部分:亚马逊红移

Amazon Redshift 是一个快速、可扩展的数据仓库,被世界上最大的公司所使用。它允许公司构建强大的应用程序并生成报告。

红移是组织成称为集群的组的节点的集合。每个集群都运行在 Amazon redshift 引擎上,并且包含一个或多个数据库。该群集有一个领导节点和一个或多个计算节点。

该机制非常直观,领导节点接收来自客户端应用程序的查询,并传递查询和开发合适的执行计划。在建立计划之后,划分为片的计算节点通过在节点之间传输数据来解决查询,从而开始处理计划。

因此,一旦执行完成,领导者节点聚集来自计算节点的结果,并将其发送回客户端应用程序。

每次启动集群时,我们都需要指定节点类型,可以是使用硬盘驱动器的密集存储节点(DS)或使用固态驱动器的密集计算节点。

决定使用哪种类型的节点是基于我们希望导入 Amazon Redshift 的数据量、我们希望运行的查询的复杂性以及依赖于我们的查询的下游系统的需求。

对于 Amazon Redshift 与传统数据仓库相比的优势,我们可以很容易地理解,使用 Redshift 可以通过调整集群大小来快速扩展。因此,您可以向上扩展并增加计算节点的数量,也可以向下扩展并减少计算节点的数量。或者,您可以使用单节点或多节点选项。

Amazon Redshift 的一个特殊方面是列数据存储,它允许按列存储数据,而不是像传统数据仓库那样按行存储。列存储允许更好的数据压缩,减少了输入/输出操作,并且通过将所有记录一起存储在一个字段中,数据库可以更快地对相似类型的数据进行查询和分析。

Amazon Redshift 的另一个特别优势是大规模并行处理,即不同的处理器一起计算。事实上,正如您所记得的,集群有一个领导节点和一个或多个划分为片的计算节点。因此,当领导者节点收到查询时,它会制定执行计划。计算节点和片一起或并行工作来执行该计划。之后,领导者节点将结果发送回客户端应用程序。

Redshift 是一个非常经济的数据仓库,因为与传统的数据仓库不同,我们不需要花费硬件、不动产、电力和员工成本。这一事实大大降低了公司的成本。还有一点很重要,Amazon Redshift 允许从 Data Lake 中查询数据,Data Lake 是一个存储库,可以保存原始格式的原始数据。

最后但并非最不重要的是,Redshift 中的数据安全可靠,这要归功于备份和恢复选项。当我们在 Amazon Redshift 中存储数据时,会在 S3 上制作数据的副本。红移还提供了加密数据的选项。

第二部分:Azure SQL 数据仓库

Azure SQL 数据仓库是一个大规模并行处理系统,允许我们实现关系型大数据存储。它是一个平台即服务(PaaS ),这意味着我们不必担心底层架构,包括操作系统、存储、服务器等。

Azure SQL DWH 由存储和两种类型的节点组成,如控制节点和多个计算节点。

在 Azure 中,数据存储在 Blob storage 中,这是一种将非结构化数据作为对象存储在云中的服务。Blob 存储可以存储任何类型的文本数据。

控制节点作为 Amazon Redshift 中的领导节点,协调运行并行查询所需的所有数据移动。因此,当 Azure SQL DWH 收到请求时,控制节点会将请求转换为在每个计算节点上并行运行的独立查询。

我们可以将计算节点定义为旨在存储数据和处理查询的数据库。处理之后,结果返回到控制节点,控制节点汇总结果并向用户提供最终结果。

重要的是要知道,当计算节点与数据交互时,节点直接从 blob 存储中写入和读取。

结论

感谢亚马逊红移和 Azure SQL DWH 的两个例子,我们可以确认,对于一个公司来说,无论其规模大小,今天的最佳选择是考虑云数据仓库,而不是传统的数据仓库。

事实上,云 DWH 速度更快,具有超弹性,这使得公司可以轻松扩展。此外,它还提供现收现付模式或固定资产购买模式。

云 DWH 消除了客户进行软件升级和硬件迁移项目的需要。

构建传统数据仓库需要可靠的硬件预算,但有了云,就不需要可靠的硬件预算。事实上,我们可以从小架构开始,随着数据量和用户数量的增长而不断发展。

我发出一份期刊简讯。如果你想加入,请通过此链接T5 报名。

除了我的简讯,还可以在我的电报群 数据科学初学者 中取得联系。

神经网络中各种优化器综述

原文:https://towardsdatascience.com/overview-of-various-optimizers-in-neural-networks-17c1be2df6d5?source=collection_archive---------12-----------------------

理解各种优化器之间的关系以及它们的优缺点。

Unsplash 上由 Hitesh Choudhary 拍摄的照片

优化器是用于改变神经网络属性(如权重和学习速率)以减少损失的算法或方法。优化器用于通过最小化函数来解决优化问题。

优化人员是如何工作的?

你应该如何改变你的神经网络的权重或学习速率来减少损失是由你使用的优化器定义的。优化算法负责减少损失,并尽可能提供最准确的结果。

使用一些初始化策略来初始化权重,并且根据更新等式在每个时期更新权重。

上面的等式是更新等式,使用它来更新权重以达到最精确的结果。使用一些称为优化器的优化策略或算法可以获得最佳结果。

在过去的几年里,人们研究了各种各样的优化器,每一种都有其优缺点。阅读整篇文章,了解算法的工作原理、优点和缺点。

梯度下降(物品):

梯度下降是最基本的一阶优化算法,它依赖于损失函数的一阶导数。它计算权重应该以何种方式改变,以便函数可以达到最小值。通过反向传播,损耗从一层转移到另一层,并且模型的参数(也称为权重)根据损耗进行修改,以便损耗可以最小化。

图片 1

从上图(图 1)可以看出,权重被更新以收敛到最小值。

优点:

  1. 实现起来非常简单。

缺点:

  1. 该算法一次采用 n 个点的整个数据集来计算导数,以更新需要大量存储器的权重。
  2. 极小值是在很长一段时间后达到的,或者是永远达不到的。
  3. 该算法可能会卡在局部最小值或鞍点:

图片 2

在上图(图 2)中,梯度下降可能会卡在局部最小值或鞍点,永远不会收敛到最小值。为了找到最佳解决方案,算法必须达到全局最小值。

随机梯度下降(SGD):

SGD 算法是 GD 算法的扩展,它克服了 GD 算法的一些缺点。GD 算法有一个缺点,它需要大量的内存来一次加载 n 点的整个数据集到计算机导数。在 SGD 算法的情况下,每次取一个点来计算导数。

图 3

从上图(图 3)可以看出,与梯度下降相比,更新需要更多的迭代次数才能达到最小值。在图 3 的右边部分,GD 算法达到最小值需要较少的步骤,但是 SGD 算法噪声更大,迭代次数更多。

优势:

  1. 与 GD 算法相比,内存需求更少,因为每次只取一个点来计算导数。

缺点:

  1. 与 GD 算法相比,完成 1 个历元所需的时间很长。
  2. 需要很长时间才能收敛。
  3. 可能会陷入局部最小值。

小批量随机梯度下降(MB-SGD):

MB-SGD 算法是 SGD 算法的扩展,它克服了 SGD 算法时间复杂度大的问题。MB-SGD 算法从数据集中取出一批点或点的子集来计算导数。

可以观察到,MB-SGD 的损失函数的导数与 GD 的损失函数的导数在若干次迭代之后几乎相同。但是与 GD 相比,MB-SGD 实现最小值的迭代次数很大,并且计算成本也很高。

权重的更新取决于一批点的损失的导数。在 MB-SGD 的情况下,更新的噪声更大,因为导数并不总是朝向最小值。

优点:

  1. 与标准 SGD 算法相比,收敛的时间复杂度更低。

缺点:

  1. 与 GD 算法的更新相比,MB-SGD 的更新噪音更大。
  2. 比 GD 算法需要更长的时间来收敛。
  3. 可能会陷入局部最小值。

SGD 带动量:

MB-SGD 算法的一个主要缺点是权重的更新非常嘈杂。具有动量的 SGD 通过对梯度去噪克服了这个缺点。权重的更新依赖于有噪声的导数,并且如果我们以某种方式对导数去噪,那么收敛时间将会减少。

想法是使用指数加权平均来对导数进行去噪,即与先前更新相比,给予最近更新更多的权重。

SGD 更新公式:

使用所有先前的更新来计算时间“t”处的动量,与先前的更新相比,给予最近的更新更大的权重。这导致收敛速度加快。

动量如何加速收敛?

图 4

当通过仅减去具有先前权重的梯度项来计算新权重时,更新在方向 1 上移动,并且如果通过减去具有先前权重的动量项来计算新权重,则更新在方向 2 上移动(图 5)。

如果我们结合这两个方程,通过用动量和梯度项之和减去先前的权重来计算新的权重,那么更新将向方向 3 移动,这导致对更新去噪。

图 5

上图(图 5)总结了 SGD+动量降噪梯度,与 SGD 相比收敛更快。

优点:

  1. 具有 SGD 算法的所有优点。
  2. 比 GD 算法收敛得更快。

缺点:

  1. 我们需要为每次更新多计算一个变量。

内斯特罗夫加速梯度(NAG):

NAG 算法的思想非常类似于带有动量的 SGD,只是略有不同。在具有动量算法的 SGD 的情况下,动量和梯度是在先前更新的权重上计算的。

根据 NAG 算法,首先计算点 W_(t-1)的动量 V_t,并沿该方向移动以到达 W_dash,然后计算新的更新权重 W_dash 处的梯度,并再次向梯度移动(图 6)。净运动导致朝向最小值的方向。

图 6

NAG 和带动量算法的 SGD 工作得一样好,并且具有相同的优点和缺点。

自适应梯度(AdaGrad):

对于前面讨论的所有算法,学习率保持不变。因此,AdaGrad 的关键思想是为每个权重设定一个自适应的学习速率。权重的学习速率将随着迭代次数而降低。

因此,随着迭代次数(t)的增加,学习率α增加,这导致学习率自适应地降低。

优势:

  1. 无需手动更新学习率,因为它会随着迭代自适应地变化。

缺点:

  1. 当迭代次数变得非常大时,学习率降低到非常小的数值,这导致收敛缓慢。

阿达德尔塔:

以前的算法 AdaGrad 的问题是学习率随着大量迭代而变得非常小,这导致收敛缓慢。为了避免这种情况,AdaDelta 算法有一个取指数衰减平均值的想法。

亚当:

在 AdaDelta 算法的情况下,我们存储梯度平方的指数衰减平均值来修改学习速率。对于 Adam optimizer,想法是存储梯度的一阶矩(g_t)和二阶矩(g_t 的平方)。

一阶矩的 EDA:

二阶矩的 EDA:

偏差校正:

更新功能:

优化器的结论和比较:

来源:https://arxiv.org/pdf/1412.6980.pdf

上图是本文中讨论的算法的迭代次数与训练损失的关系图。

对于给定的迭代次数(假设 100),从图中可以观察到 adam 在所有其他算法中收敛最快。

什么时候选择哪种算法?

来源:https://ruder . io/content/images/2016/09/saddle _ point _ evaluation _ optimizer . gif

  • 在上面的动画中,可以看到 SGD 算法(红色)停滞在一个鞍点上。所以 SGD 算法只能用于浅层网络。
  • 除 SGD 之外的所有其他算法最终一个接一个地收敛,AdaDelta 是最快的,其次是动量算法。
  • AdaGrad 和 AdaDelta 算法可用于稀疏数据。
  • 动量和 NAG 在大多数情况下工作良好,但速度较慢。
  • Adam 的动画不可用,但是从上面的图中可以看出,它是收敛到最小值的最快算法。
  • Adam 被认为是上面讨论的所有算法中最好的算法。

感谢您的阅读!

用 Flask 和 Heroku 构建和部署推荐器

原文:https://towardsdatascience.com/overview-on-building-a-local-coffee-drinking-outlet-recommender-and-deployment-with-flask-and-39b16fb40388?source=collection_archive---------30-----------------------

使用 Heroku 构建混合推荐器和部署基于内容的过滤组件时基于模型的观点

我的数据科学沉浸式计划的顶点演示幻灯片的首页

在这篇文章中,我用 Flask 和 Heroku 展示了一种构建混合推荐器和部署一个基于模型的内容过滤系统的方法。这是我在新加坡大会(GA)下的数据科学沉浸式项目中的顶点项目。更多详情可以在这些 GitHub 回购链接中找到: GA_CapstoneGA _ Capstone _ Flask _ Heroku _ deployment

对于这个项目,我选择了咖啡作为感兴趣的主题,因为我周围都是热爱咖啡的社会团体(尽管我不喝咖啡!)而且我很清楚,在寻找喝茶的好去处时,实际上存在着无穷无尽的选择。因此,我认为建立一个推荐器可以解决被选择淹没的问题,并且不需要根据过多的属性如位置、服务标准等来过滤选择。,在这里可能会派上用场。

待建推荐系统类型概述

基于模型的内容过滤

一种基于内容的过滤模式,在受监督的机器学习算法(由特征 X 和目标 y 定义)的背景下构建,其中项目(在这种情况下为咖啡店)的各种特征(特征矩阵, X )用于预测用户评级(目标 y )。预测的用户评级然后以降序排列,并且认为合适的前 5 个或任意数字 n 被呈现为前 5 个或前 n 个推荐,供用户检查。

基于模型的协同过滤

一种基于机器学习算法的协同过滤范例,该算法从现有数据中学习用户-项目交互,以预测用户的项目评级(或在我们的上下文中用户的咖啡出口评级), 通过考虑具有相似评级模式的其他用户的项目评级——这就是为什么协作过滤 RecSys 经常遇到冷启动问题的原因,在该问题中,不可能找到具有与未对任何项目进行评级的新用户相似的评级模式的用户——然后向感兴趣的用户推荐那些相似用户最喜欢的项目(因此本质上是协作的)。

混合 RecSys

混合 RecSys 结合了基于内容的过滤和协作过滤,试图减少其中任何一种的缺点,以产生更整体和更全面的系统(可以说是两全其美),例如,基于内容的过滤不能产生交叉推荐,即,它倾向于只推荐与用户曾经喜欢的项目类型相同的项目。协同过滤通过其协同特性解决了这一问题——可以潜在地推荐不属于用户曾经喜欢的项目类别的项目,只要那些项目是具有相似评级模式的其他用户最喜欢的。另一方面,对于只涉及显式反馈的数据集,如用户评级(如 Yelp 数据集),协同过滤只考虑用户-项目交互矩阵,该矩阵包括用户 id评级项目 id。在这种情况下,基于内容的过滤可以通过提供更细粒度的项目特征来丰富 RecSys 的项目特征数据集(即类别review_countavg_store_rating 等)。从而使 RecSys 更加全面和强大。

数据

该数据集包括大约 987 家当地咖啡饮食店和相关功能,6,292 条用户评论和 7,076 条用户评级,这些都是使用 BeautifulSoup 和 Yelp 的 API 令牌的组合从 Yelp 搜集来的。

由于在收集的数据集中有很大比例的用户只对 1-2 家商店进行评级,因此在随后的模型评估阶段的 train_test_split()交叉验证阶段,当数据集被分成由 userids 分层的训练和验证集时(尤其是如果 test_size 小于 0.5 并且交叉验证折叠数大于 2),针对所有这些用户的模型训练将不可避免地遇到错误。因此,我只将对至少 10 个不同渠道进行评级的用户纳入基于内容的过滤模型(这导致 110 /2552 用户被纳入模型训练)。数字 10 是任意选择的,尽管这可能与用户应该如何提供 10 个评级以生成部署模型中的前 5 个建议有关,我们将在后面看到。

从训练数据来看,我们的目标 y (用户评分)明显不平衡:

不平衡的目标类别:在类别 1 和类别 2 中几乎没有任何评级,在类别 3 中最小,大多数属于类别 4 和类别 5,其中类别 4 占主导地位

由于目标类的不平衡性质,以及我们不希望推荐差的推荐(误报)也不希望错过好的推荐(误报),一个微平均 F1 分数,这实质上是一个定义为精度和召回之间的微平均平衡的指标,用于稍后评估各个模型的性能。

型号

基于内容的过滤

将被合并到基于内容的过滤模型中的项目(或咖啡店)方面的特征是:

基于内容的过滤功能:评论、类别、评论数量和平均商店评级

使用 naive Tf-idf 矢量器将评论分解为词项频率,该矢量器用于在模型训练之前显示每个评论词项的区分强度及其与各种咖啡店的关联。

我调整并试验了各种有监督的机器学习算法,如逻辑回归决策树分类器,以及集成方法,如极端梯度提升分类器(XGB)。 XGB 表现最好(微观平均 F1 分:0.97 ),被选中部署。XGB 是一种极端的梯度推进回归树(GBRT)算法,它:

  • 减少偏差、方差,并从过去弱学习器的错误中“学习”以产生强学习器,因为它从浅的低方差/高偏差基础估计器开始,并根据过去估计器的错误迭代拟合估计器,以纠正那些错误/错误分类
  • 通过使用更规则的模型形式化来控制过拟合 ,从而比常规的梯度增强方法如梯度增强分类器执行得更好
  • 能够很好地处理混合数据类型(回想一下:用于基于内容过滤的数据集混合了数字和分类数据类型,分别像 review_countreviews )

XGB 的一个实例——感谢https://blog.quantinsti.com/xgboost-python/

协同过滤

使用交替最小二乘法(ALS)算法,并使用 Pyspark 的交叉验证器 ( 微平均 F1 分数:1.0 )进行调整。ALS 是一种矩阵分解技术,它将用户-项目交互矩阵(如具有显式反馈的数据集的用户-项目评级矩阵)分解为用户和项目潜在因素,其中它们的点积将预测用户的项目评级(或在此上下文中各种咖啡店的用户评级)。它在固定用户或项目潜在因素之间交替,以在最小化损失(实际和预测用户评级之间的误差)的过程中,通过每次迭代的梯度下降来求解另一个:

矩阵分解损失函数:解释潜在的用户和项目因素,这些因素将在使用 ALS 算法时通过梯度下降来学习

混合 RecSys

基于内容的过滤和协作过滤通过对来自两个过滤系统的评级预测进行加权求和而结合在一起。例如,如果基于内容的过滤的预测用户评级是 3,而协作过滤的预测用户评级是 4,则最终的预测用户评级将是:

(0.97/(0.97(XGB 的微平均 F1)+1.0(ALS 的微平均 F1))(基于 XGB 的微平均 F1 分配给基于内容的过滤的权重)x3+(1.0/(0.97(XGB 的微平均 F1)+1.0(ALS 的微平均 F1))(基于 ALS 的微平均 F1 分配给协同过滤的权重)x 4 = ~3.51 = 3.5(四舍五入到最接近的 0.5)

混合 RecSys 的微平均 F1 分数为 1.0

Flask 应用程序实现

使用 Flask python 脚本和一些 html 模板,在本地虚拟环境中成功实现了混合 RecSys。

基本上,用户应该选择并评价他们以前去过或熟悉的 10 个当地咖啡饮品店(最好每个评价等级有 2 个不同的店,以便允许在后端工作的机器学习模型更全面地了解用户的“偏好”,这反过来将产生更可靠的推荐),并点击“提交以产生前 5 个推荐供所述用户检查。

在本地虚拟环境中实现的 Flask 应用程序的首页:用户首先根据既定的准则提交一些商店的评级

Flask 应用程序的首页还提供了额外的 Yelp 链接,链接到喝咖啡的商店,供用户在给它们评分前参考

根据提交的 10 个评分,为用户生成的前 5 个推荐示例

然而,与大多数部署的机器学习模型不同,这些模型仅简单地基于作为用户输入提供的看不见的特征(即 X_test )来预测结果,这种混合 RecSys 依赖于一对手动组合的机器学习模型来训练新的看不见的评级(即目标、 y_train) 和已评级的咖啡店(即特征、 X_train )并预测用户对其他未评级的咖啡店的评级。因此,点击“提交”后,平均需要15–20 多分钟才能在 Flask app 上生成前 5 条建议……这种持续时间对于 Heroku 这样的正式部署平台来说是不可接受的,只要等待时间超过仅仅 30 秒 ,Heroku 就会终止任何 web 应用程序的进程,并在错误日志中输出一条“请求超时消息和一个 H12 错误……

使用 Heroku 部署基于内容的过滤

鉴于上述情况,我只能尝试部署 RecSys 的“一半”,特别是 XGB 组件:因为 ALS 只能从 Pyspark-py spark . ml . recommendation库导入,而且我还没有找到详细介绍使用 Heroku 部署 py spark 代码的在线资源。找到的大多数资源都是关于 Scala 和 Spark 应用程序的,这些应用程序需要用 Scala 构建工具 ( sbt )和 jar 汇编进行编译,这对于我使用最少 Pyspark 代码的 Flask 应用程序来说似乎有点太复杂了——甚至没有 SparkContextspark-submit ,只有 SparkSession 和 ALS 组件。

随着 RecSys 被削减到只有 XGB 组件,“请求超时”仍然是一个问题。在用% %的时间削减了代码的 XGB 组件并在 Jupyter Notebook 中记录了每个代码单元的运行时之后,我能够充分缩短运行时,以便 XGB 组件可以通过 Heroku 正式部署,而不是通过这里的

与 Heroku 一起部署的基于内容的过滤 RecSys:首页,用户在此提交 10 个出口评级

与 Heroku 一起部署的基于内容的过滤 RecSys:基于提交的 10 个评级的用户前 5 个建议的结果页面

模型限制

混合 RecSys 的一些局限性包括:

  • 缺乏隐含数据
  • RecSys 基于不更新的静态数据,因此将来可能会过时
  • 可疑的数据质量(大多数用户只对 1-2 个网点进行评级,因此不可能对包含所有 2552 个用户的模型进行训练和交叉验证)
  • 很难同时调整 Tf-idf 和训练具有单词术语和数字特征组合的模型——因此 Tf-idf 没有被调整,而是使用了一个简单的版本
  • 均值归一化可作为 RecSys 根据每个网点的平均用户评级向开始时未提供任何评级的用户推荐网点的备用方案

未来计划

在线关注各种部署平台、 stackoverflow 和 Pyspark 部署的更新,看看 Pyspark ALS 组件是否可以整合到 Heroku 部署中,以便可以在线部署完整的混合 RecSys。

如果上述结果很好,可以潜在地结合用户设计/用户体验的概念,以更好地设计 html 用户界面,为 A/B 测试做准备,以衡量混合 RecSys 构建的有效性。

概述:每个学科和每个任务的最先进的机器学习算法

原文:https://towardsdatascience.com/overview-state-of-the-art-machine-learning-algorithms-per-discipline-per-task-c1a16a66b8bb?source=collection_archive---------5-----------------------

了解自然语言处理、计算机视觉、语音识别和推荐系统的最佳算法

CV =计算机视觉,NLP =自然语言处理,RS =推荐系统,SR =语音识别|来源:来自作者。

机器学习算法正在兴起。每年都有新的技术出现,超越了当前领先的算法。其中一些只是现有算法的微小进步或组合,而另一些是新创造的,并带来了惊人的进步。对于大多数技术,已经有很好的文章解释了其背后的理论,其中一些还提供了代码和教程实现。目前还没有人提供当前领先算法的概述,所以这个想法出现了,根据所取得的结果(使用性能分数)来呈现每个任务的最佳算法。当然,还有更多的任务,并不是所有的任务都可以呈现。我试图选择最受欢迎的领域和任务,并希望这可能有助于更好地理解。本文将重点讨论计算机视觉、自然语言处理和语音识别。

文中介绍了所有的领域、任务和一些算法。如果您只对某个子部分感兴趣,请跳到您想深入了解的部分。

计算机视觉

计算机视觉是机器学习中研究最多、最热门的领域之一。它用于解决许多日常问题,并连续涉及多种应用,其中最受欢迎的是自动驾驶汽车的愿景。我们将要研究的任务是语义分割、图像分类和目标检测。

语义分割

语义分割可以被视为在像素级别上理解图像的结构和组件。语义分割方法试图预测图像中的结构和对象。为了更好地理解,可以在下面看到街道场景的语义分段:

用 SegNet 进行语义分割【https://mi.eng.cam.ac.uk/projects/segnet/

目前领先的算法 HRNet-OCR 是由 Nvidia 的 Tao 等人在 2020 年提出的。它实现了 85.1%的平均交集/并集(平均 IOU)。HRNet-OCR 对图像进行缩放,并对每个缩放比例使用密集遮罩。然后,所有尺度的预测“通过在掩模之间执行逐像素乘法,然后在不同尺度之间进行逐像素求和,从而获得最终结果”[1]。

查看 Github 来的技术:
https://github.com/HRNet/HRNet-Semantic-Segmentation

其他顶层技术(方法—数据集):

想看更多这样的故事?每天只需要 0.13 美元。

开始使用

图像分类

不同于语义分割,图像分类不关注图像上的区域,而是关注图像的整体。这个学科试图通过分配一个标签来对每个图像进行分类。

来源:图片由作者提供。

FixEfficientNet 已经于 2020 年 4 月 20 日与脸书人工智能研究团队的相应论文一起首次提交[2][3]。它目前是最先进的,在 ImageNet 数据集上具有最好的结果,480M 参数,前 1 名准确率为 88.5%,前 5 名准确率为 98.7%。FixRes 是 Fix Resolution 的简称,它试图为用于训练时间的 RoC(分类区域)或用于测试时间的 crop 保持固定的大小。EfficientNet 是 CNN 维度的复合缩放,提高了准确性和效率。

欲了解 FixEfficientNet 的更多信息,请阅读此

其他顶层技术(方法—数据集):

目标检测

对象检测是识别图像中某一类对象的实例的任务。

目前领先的物体检测技术是谷歌大脑团队(Tan 等人)在 2020 年首次提出的Efficient-Det D7x[4]。它实现了 74.3 的 AP50 ( 了解 AP50 的更多信息:在 50 的固定 IoU 阈值下的平均精度)和 55.1 的 box AP。Efficient-Det 是 EfficientNets 与双向特征金字塔网络( BiFPNs )的组合。

正如上面简要解释的那样, EfficientNet 是 CNN 维度的复合缩放,它提高了准确性和效率。更多关于 EfficientNet 的信息,你可以点击这里

在计算机视觉中,提高精确度的典型方法是创建具有不同分辨率的同一图像的多个副本。这导致了所谓的金字塔,因为最小的图像被布置为顶层,而最大的图像被布置为底层。要素金字塔网络代表了这样一个金字塔。双向意味着不仅有自上而下的方法,同时也有自下而上的方法。每个双向路径都被用作特征网络层,这导致了 bip pn。它有助于提高准确性和速度。有关 bip pn 的更多信息,点击此处

其他顶层技术(方法—数据集):

自然语言处理

自然语言处理的常见定义如下:

NLP 是人工智能的一个子领域,它赋予机器阅读、理解和从人类语言中获取意义的能力。

NLP 任务的范围很广,正如定义所揭示的,它们都试图从我们的语言中推断出一些含义,并根据我们的语言及其组成部分进行计算。基于 NLP 的算法可以在各种应用和行业中找到。仅举几个你可能每天都会遇到的应用程序,如翻译器、社交媒体监控、聊天机器人、垃圾邮件过滤器、微软 word 或 messengers 中的语法检查和虚拟助手。

情感分析

情感分析是文本挖掘的一个领域,用于对文本数据中的情感进行解释和分类。目前领先的算法之一是 BERT ,它在 2019 年的 SST-5 细粒度分类数据集上实现了 55.5 的准确率。最初的论文由谷歌人工智能团队发布【5】。

BERT 代表来自变压器的双向编码器表示,并应用变压器技术的双向训练。Transformer 技术是一种用于语言建模的注意力模型,以前只应用于一个方向。从左到右或从右到左解析文本。更多细节,请阅读这篇伟大的文章

其他顶层技术(方法—数据集):

语言建模

语言建模是基于现有文本/先前单词来预测文本中的下一个单词或字母的任务。GPT-2 模型被赋予了两个关于生活在安第斯山脉的一群独角兽的句子,它创造了一个惊人的故事。这里可以看

在语言建模中,表现最好的算法之一可以在 Megatron-LM 中找到。这个模型和论文是英伟达团队在 2019 年首次提出的。一个类似 GPT-2 的模型在 83000 亿个参数上进行训练。它能够将当前最高水平的 15.8 分降低到只有 10.8 分的测试困惑度。使用的数据集是 WikiText103 [6]。

该模型利用了变压器网络。在他们的工作中,变形层由一个自我注意块和两层、多层感知机(MLP)组成。在每个块中,使用模型并行性。这有助于减少通信并保持 GPU 的计算能力。GPU 的计算被复制以提高模型的速度。

其他顶层技术(方法—数据集):

  • GPT-3——宾州树木银行
  • GPT-2——维基百科 2,文本 8,环境 8

机器翻译

机器翻译被用于谷歌翻译或 www.deepl.com 翻译等应用中。它用于使用算法将文本翻译成另一种语言。

这个领域最有前途的算法之一是 Transformer Big +BT。由谷歌大脑团队于 2018 年在本文中提出。一般来说,变压器是处理序列和机器翻译的最先进技术。转换器不使用循环连接,而是同时解析序列[7]。

输入以绿色表示,提供给模型(蓝色)并转换为输出(紫色)。 GIF 来源

正如你在上面的 gif 中看到的,输入和输出是不同的。这是由于两种不同的语言,例如输入是英语,而输出语言是德语。为了提高速度,并行化是该模型的一个关键方面。这个问题通过使用 CNN 和注意力模型来解决。自我关注有助于提高速度和对某些单词的关注,而 CNN 用于并行化[8]。更多关于变形金刚的信息,请阅读这篇伟大的文章。作者应用反向翻译(BT) 进行训练。在这种方法中,训练数据集被翻译成目标语言,并且算法将其翻译回原始语言。然后可以很好地观察表演[7]。

其他顶层技术(方法—数据集):

文本分类

文本分类的任务是给一个句子、一篇文章或一个单词分配一个特定的类别。目前在三个不同数据集(DBpedia、AG News 和 IMDb)上领先的算法是 XLNet。

谷歌人工智能团队在 2019 年首次展示了论文和技术 XLNet 。它在 20 个任务中改进了领先的算法 BERT。 XLNet 首创的方法叫做置换语言建模。它利用了单词的排列。假设你有三个单词,顺序如下[w1,w2,w3]。然后检索所有排列,这里是 321 = 6 个排列。显然,对于长句,这导致了无数的排列。位于预测字(例如 w2)之前的所有字用于预测[9]:

w3 w1 **w2**
w1 **w2** w3
w1 w3 **w2**
 …

在行 1 中,w3 和 w 1 用于 w2 的预测。在行 2 中,只有 w1 用于预测,依此类推。为了更好地理解这项技术,你可以在这里阅读更多相关内容。

其他顶层技术(方法—数据集):

问题回答

问答是训练一个算法来回答问题的任务(通常基于阅读理解)。这项任务是迁移学习的一部分,因为要学习给定的文本数据库,并存储知识以在稍后的时间点回答问题。

通过 T5–11B,谷歌人工智能团队在四个不同的数据集上实现了最先进的基准测试:GLUE、SuperGLUE、SQuAD 和 CNN/Daily Mail。T5 代表文本到文本转换转换器中的五个 T,而 11B 代表用于训练算法的 110 亿个数据集。与 BERT 和其他优秀的算法相比,T5–11B 不输出输入句子的标签。相反,正如名称所示,输出也是一个文本字符串[10]。

来源:https://ai . Google blog . com/2020/02/exploring-transfer-learning-with-t5 . html

论文的作者已经严格评估和提炼了几十个现有的 NLP 任务,以将最好的想法应用到他们的模型中。这些包括对模型架构、预训练目标、未标记数据集、训练策略和规模的实验,如作者所述[10]:

模型架构 ,在这里我们发现编码器-解码器模型普遍优于“只有解码器”的语言模型;

预训练目标 ,我们确认填空式去噪目标(训练模型以恢复输入中缺失的单词)效果最佳,最重要的因素是计算成本;

未标记数据集 ,其中我们展示了对域内数据的训练可能是有益的,但是对较小数据集的预训练可能导致有害的过拟合;

缩放 ,其中我们比较模型大小、训练时间和集合模型的数量,以确定如何最好地利用固定的计算能力[11]

完整的 T5–11B 型号是现有 NLP 型号(如 BERT)的 30 多倍。

其他顶层技术(方法—数据集):

  • T5–11B1.1 班开发
  • 阿尔伯特上的 SA-Net-squad 2.0
  • 坦达-罗伯塔

推荐系统

你很可能已经见过并使用过各种各样的推荐系统。你最喜欢的网上商店或平台用它来推荐你可能感兴趣的类似产品。

该领域目前领先的算法之一是贝叶斯时间 SVD++。它是由谷歌团队在 2019 年提出的,并在 MovieLens100K 数据集上达到了 SOTA 基准。谷歌团队尝试了多种不同的方法和方法组合,直到他们找到贝叶斯矩阵分解和 timeSVD++的领先组合。使用吉布斯采样训练贝叶斯矩阵分解模型。更多关于这个模型和所有尝试过的方法,你可以在这里找到【12】。

其他顶层技术(方法—数据集):

语音识别

和推荐系统一样,语音识别也参与了我们的日常生活。越来越多的应用程序以虚拟助手的形式利用语音识别,如 Siri、Cortana、Bixby 或 Alexa。

该领域的领先算法之一是基于 ContextNet + SpecAugment 的带 Libri-Light 的嘈杂学生训练,由谷歌团队于 2019 年首次推出,论文【13】。

顾名思义,这种方法结合了语境和嘈杂的学生训练。上下文网络是一个 CNN-RNN 转换器。该模型由用于输入音频的音频编码器、用于产生输入标签的标签编码器和用于解码的两者的联合网络组成。对于标签编码器,使用 LSTM,音频编码器基于 CNN。嘈杂的学生训练是一种半监督学习,使用未标记的数据来提高准确性[13]。

在有噪声的学生训练中,连续训练一系列模型,使得对于每个模型,该系列中的前一个模型充当数据集的未标记部分上的教师模型。嘈杂的学生训练的显著特征是利用增强,其中教师通过读入干净的输入来产生高质量的标签,而学生被迫用大量增强的输入特征来复制这些标签。”[13]

Libri 光指的是未标记的音频数据集,模型在该数据集上被训练,并且该数据集是从音频书籍中导出的。

其他顶层技术(方法—数据集):

结论

过去十年在多个学科和任务方面取得了突破。新的技术、算法和应用已经被发现和开发,而我们仍处于开始阶段。这主要是通过两项发展实现的:1)不断增长的数据库,这使得为算法提供足够的数据成为可能;2)处理器、RAM 和显卡的技术发展,使得训练需要更多计算能力的更复杂的算法成为可能。此外,随着数据科学投资的增加以及越来越多的人对数据科学和机器学习领域感兴趣,最先进的算法的半衰期也在缩短。连续,这篇文章可能已经过时一年。但是现在,这些领先的技术有助于创造越来越好的算法。

如果你知道其他应该添加的方法或学科,你可以评论或联系我。感谢您的反馈,希望您喜欢这篇文章!

** [## 通过我的推荐链接加入 Medium-Hucker Marius

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

medium.com](https://medium.com/@hucker.marius/membership)**

参考文献:

[1]陶,a .,萨普拉,k .,&卡坦扎罗,B. (2020)。语义切分的分层多尺度注意。ArXiv:2005.10821【Cs】http://arxiv.org/abs/2005.10821

[2]h .图夫龙、a .韦达尔迪、m .杜泽和 h .杰古(2020 年 b)。修正训练-测试分辨率差异。ArXiv:2003.08237 [Cs] 。http://arxiv.org/abs/2003.08237

[3]h .图夫龙、a .韦达尔迪、m .杜泽和 h .杰古(2020 年 a)。修复列车测试分辨率差异。ArXiv:1906.06423【Cs】http://arxiv.org/abs/1906.06423

【4】谭,m,庞,r,&乐,秦文伟(2020)。EfficientDet:可扩展且高效的对象检测。ArXiv:1911.09070【Cs,Eess】http://arxiv.org/abs/1911.09070

**【5】Devlin,j .,Chang,m-w .,Lee,k .,& Toutanova,K. (2019)。BERT:用于语言理解的深度双向转换器的预训练。ArXiv:1810.04805【Cs】。【http://arxiv.org/abs/1810.04805 **

[6] Shoeybi,m .,Patwary,m .,Puri,r .,LeGresley,p .,Casper,j .,& Catanzaro,B. (2020 年)。威震天-LM:使用模型并行性训练数十亿参数语言模型。ArXiv:1909.08053【Cs】http://arxiv.org/abs/1909.08053

[7]艾杜诺夫,s .,奥特,m .,奥利,m .,&格兰吉尔,D. (2018)。理解大规模回译。ArXiv:1808.09381【Cs】http://arxiv.org/abs/1808.09381

[8] Vaswani,a .,Shazeer,n .,Parmar,n .,Uszkoreit,j .,Jones,l .,Gomez,A. N .,Kaiser,l .,& Polosukhin,I. (2017)。你需要的只是关注。ArXiv:1706.03762【Cs】http://arxiv.org/abs/1706.03762

[9]h .图夫龙、a .韦达尔迪、m .杜泽和 h .杰古(2020 年 b)。修正训练-测试分辨率差异。ArXiv:2003.08237 [Cs] 。http://arxiv.org/abs/2003.08237

[10] Raffel,c .,Shazeer,n .,Roberts,a .,Lee,k .,Narang,s .,Matena,m .,周,y .,Li,w .,和刘,P. J. (2020)。用统一的文本到文本转换器探索迁移学习的局限性。 ArXiv:1910.10683 [Cs,Stat]http://arxiv.org/abs/1910.10683

【11】https://ai . Google blog . com/2020/02/exploring-transfer-learning-with-t5 . html

[12] Rendle,s .,Zhang,l .,& Koren,Y. (2019)。评估基线的困难:推荐系统的研究。ArXiv:1905.01395【Cs】http://arxiv.org/abs/1905.01395

**[13] 朴德生、张、杨、贾、杨、韩、魏、邱、陈正忠、李、吴正荣、&乐、秦文武(2020)。改进自动语音识别的嘈杂学生训练。*ArXiv:2005.09629【Cs,Eess】【http://arxiv.org/abs/2005.09629 ***

我如何建立一个帮助我更有创造力的系统

原文:https://towardsdatascience.com/overwhelmed-as-a-data-professional-here-is-how-to-keep-up-c0f6b1b39a93?source=collection_archive---------66-----------------------

“你的头脑是用来有想法的,而不是持有想法的。”—大卫·艾伦

来自 Pexels 的第三人拍摄的照片

T 数据空间中的信息和技术数量惊人——作为一名数据工程师,我亲身经历过。技术概念、数据库、云服务、开源框架以及用于数据科学、可视化和 ETL 过程的工具——似乎不可能跟上。如今我们消费了如此多的内容,我们不应该责怪自己没有能力管理这些信息过载。在本文中,我分享了几种技术和一个可行的模板,以组织我们消费的内容,并在我们作为数据专业人员的繁忙生活中为新的创意留出空间。

捕捉信息

在不断发展的技术世界中,很难跟上最新的发展。幸运的是,我们不必知道所有的事情,而是知道在哪里可以找到我们想要的信息。

我遇到过许多软件工程师,他们不写任何东西,仅仅依靠谷歌搜索(或者更确切地说是栈溢出搜索)来进行信息检索。不要误解我,我喜欢栈溢出,但是我讨厌解决同一个问题两次,仅仅因为我忘记了我以前是如何得到解决方案的。

因此,我开发了一个可以依赖的做事系统,它可以让我存储并在以后找到我需要的一切。基本原则是:

"你的头脑是用来有想法的,而不是用来持有想法的。"

大卫·艾伦[1]

如果你能把学过的东西捕捉到某个外部系统 ( 你的“第二大脑”)并依靠它快速找到相关信息,你就不需要把所有东西都储存在你的脑袋里。它给你更多的空间来思考新的想法,并把注意力放在最重要的事情上。

实现细节,比如你最后用哪个 app 做笔记(比如 idea,Evernote,Roam,RemNote,OneNote 等。),只要能让你捕捉、组织、检索一切,都无所谓。许多人仍然喜欢做物理笔记,如果这对你有用,那也没关系。

为什么获取信息如此重要?

以前我会看博文,看视频或者看一本关于某件事的书,它让我相信我抓住了它的要旨,我会记住它。但是当我几个月后不得不应用这些信息时,结果是我忘记了其中的大部分,并且我找不到我正在使用的资源。

我从中学到的是:

我们在技术工作中遇到的信息量是巨大的,我们不能依赖于记住所有的东西。

如今,事情变化得如此之快,以至于我们可能没有充分利用时间去了解事情的细节。很多时候,拥有一个宏观视角并在需要时更深入地研究我们捕捉到的笔记就足够了。

没有捕捉,我们仅仅依靠我们易错的记忆,这给我们自己很大的压力。如果我们没有抓住我们所学的东西,我们可能需要以后完全重新学习,因为几个月或几年后我们几乎忘记了一切。

照片由 bongkarn thanyakijPexels

系统思维

作为一个雄心勃勃的人,你可能正在为自己设定目标。但是当你实现了目标,接下来呢?目标似乎有助于指明方向。然而,围绕它们来组织我们的工作可能会适得其反,因为目标关注的是目的地而不是过程。写下可实现的、可衡量的里程碑的愿景和计划可能会有所帮助,但最终:

“你没有达到你的目标。你会下降到你的系统的水平。”——詹姆斯·克利尔[2]

系统给了我们一个框架,将我们雄心勃勃的目标分解成小的可管理的步骤,并随着时间的推移看到更大的画面。一个健壮的系统允许捕获、组织、审查,并最终找到和应用相关信息。

查看和组织信息

在我们将任何信息捕获到一个可靠的系统中之后,我们应该能够很容易地将其组织成组。工作项目、个人项目,甚至是关于如何与朋友和家人共度时光的想法)并根据什么是最重要的,对所有事情进行优先排序。这种分类有很多好处:

  • 我们可以看到更大的图景
  • 我们可以区分什么是真正重要的,什么只是紧急的
  • 我们可以开始处理我们最重要的事情
  • 我们可以跟踪我们的进展,看看小任务是如何完成的。每天坚持阅读一本书的一章会让我们有所成就。

最后,我们可以睡得更好,因为我们知道一切(或至少一部分)都在我们的控制之下,因为所有的“生活类别”都在我们的系统中得到照顾。

实施一个完成任务的系统

建立任何可靠的系统都具有挑战性。例如,你可以使用概念来记录项目、工作任务以及任何你正在学习的东西。实际的工具比它的使用方式更重要。

完成任务系统的组成部分

理想的完成任务系统将让您:

  • 跟踪你的项目,例如使用看板,
  • 快速捕捉新信息——例如。通过使用某种收件箱
  • 轻松对信息进行分类和组织以便于访问,例如,将待办事项或看板中的笔记分类到笔记本、页面、类别中,或者用标签进行标记(上图所示的知识库部分
  • 通过创建模板使捕捉过程更容易
  • 存储代码片段
  • 轻松检索任何东西——例如。在概念中,你可以使用快捷键 Cmd + P ( 或者 Windows 上的 Ctrl + P)来搜索任何关键词——它甚至可以搜索你的代码片段
  • 对你的任务进行优先排序
  • 以对你有意义的方式组织信息。

最后一点很关键:如果你总结构建任何捕捉到的信息让它对你有意义,你会让你的“未来自我”更容易理解你的意思。最重要的是,它将使扩展和与他人共享变得更容易管理。

在实践中运用知识

我们都是人,我们喜欢做简单的事情:看网飞,吃冰淇淋,或者仅仅是通过观看 YouTube 视频或浏览 Reddit 来获取信息。但是,纯粹的内容被动消费就不坚持了。例如,让我们想象两种场景:

  1. 被动学习:你正在看一段视频,视频中有人在解释如何编写程序。
  2. 主动学习:****你试图自己编写一些东西,你必须搜索特定的信息来解决你的问题,通过试错找到解决方案,并从你的错误中学习。

你也许能从第二个场景中回忆起更多。一个简单的积极参与内容的行为会使任何信息停留更长时间。例如,回到学校和大学,我经常用纸和笔做笔记,因为这让我不会对讲座感到厌烦。与此同时,记笔记时,我总是能够在以后更容易地回忆起这些信息。

主动学习和被动学习之间的区别可能是为什么我们通过做而不是仅仅看着别人做某事而学得更好的原因。

没有应用的知识就像知道一门外语的全部词汇,但仍然不能说。没有应用,这些知识在我们的大脑中就没有长期记忆的联系。我发现,即使编写最短的代码示例,也能更容易理解和记住任何编程概念。这同样适用于学习外语的过程——用我们刚学过的新单词造一个简单句,把它放在如何使用它的语境中,这样更容易记住它。

结论

在这篇文章中,我们讨论了完成任务系统的组件,这些组件可以通过捕捉我们学习到的信息到我们的“第二大脑”来帮助我们更积极地消费内容,第二大脑是一个外部系统,允许我们存储和组织我们工作的事情。如果使用得当,这样的系统将降低我们的压力水平,释放我们的精神资源,因为我们不再需要将所有东西都存储在我们的精神“RAM”中,而是可以将其中的一部分移动到一些“外部驱动器”中。

我鼓励你试一试。创建一个系统来组织项目,捕捉你所学的东西,并定期更新你的知识库,这在未来很可能会有指数级的回报。这将使工作和学习变得更加愉快,因为你将有一个系统来释放你的精神资源,专注于重要的事情。最后,我们永远不会停止学习,尤其是在技术领域,所以最好用系统来接近它。

感谢您的阅读!

参考文献

[1]“把事情做好”——作者:大卫·艾伦大卫·凯尔文·艾伦

[2]“原子习惯:建立好习惯、改掉坏习惯的简单而有效的方法”——詹姆斯·克利尔的书

被 R 压倒?慢慢开始

原文:https://towardsdatascience.com/overwhelmed-by-r-start-slow-ef5cec78ca26?source=collection_archive---------67-----------------------

面向非程序员的 R 命令的第一课

由 minkewink 在 Pixabay 上拍摄的照片

如果你没有做过大量的编程工作,学习 R 可能会相当令人生畏。

但如果你专注于基础,并通过实践慢慢积累技能,那就更容易了。在这里,我将给出一个简短的教训,告诉你在 r 中可以做的最基本的事情。

这篇文章改编自我的在线课程 ,所以你需要学习 R 。它假设你已经安装了一个r studio的副本,对个人来说是免费的。

让我们从如何在 R 中输入命令的基础开始,告诉 R 我们想要做什么。这叫做给 R 一个表达式

做一些数学

如果您打开一个 RStudio 会话,您将看到一个控制台,其中有一些介绍性文本和一个提示(小的 > 符号):

RStudio。图片作者。

您可以在提示符后键入命令,在您按下 Return 或 Enter 键后,R 将会对它们进行评估;这意味着它将解释它们的含义,并试图计算出某种结果。

首先,让我们把 R 作为一个美化了的科学计算器。输入这些命令并按 Enter 键以获得一些输出:

1 + 2
3 - 1

所以 R 理解数字和常见的数学运算符。这包括带星号*的乘法和带正斜杠/的除法。

2 * 6
6 / 3

您可以使用插入符号^ (shift-6)来计算幂,例如计算四的平方。你也可以做负数。

4 ^ 2
4 ^ -2

数字

r 理解十进制记数法(是 a .还是 a,取决于你的国家;r 在这方面通常很聪明)。但是我们不在大数字中使用逗号或其他千位分隔符:那会给我们一个错误。

1.2345 + 1 
12,345 + 1

圆括号

r 也理解并尊重操作顺序。乘方先于乘法,乘法先于加法,依此类推。是的,你必须重温高中数学的记忆。对于同一级别内的操作,R 从左到右工作。

1 + 2 * 3
4 / 2 / 8

您可以用括号修改这个顺序,就像您在任何其他
数学上下文中一样。如果你想让一加二先求值,你把它放在括号里,得到一个完全不同的答案:

(1 + 2) * 3
4 / (2 / 8)

我们也可以用括号来定义分数。这在某些情况下真的很重要。例如,如果你想求一个数的根呢?根实际上是分数幂。所以不要…

4 ^ 2

我们想反过来,这样我们从 16 开始,然后求平方根。

16 ^ 1 / 2

但是我们实际上做错了:上面的命令不会按照我们想要的顺序进行计算,因为 R 会先取插入符号——意思是先取幂——这意味着这实际上是 16 的 1 次方,然后除以 2。

但是我们想求平方根。我们需要把分数放在括号里。然后我们得到 16 的正确根是 4(不是 8)。

16 ^ (1 / 2)

还要注意,在我的例子中,我在 r 中留出了符号。这两个命令产生相同的结果:

3^4/2+(1/2)
3 ^ 4 / 2 + (1 / 2)

但是第二种可能更容易阅读。

一个例子

让我们用一个稍微更实用的例子来结束这一部分。我们可以做一道几何题,比如求球体的体积。公式是圆周率的三分之四乘以半径的立方:

v = 4/3⨉π⨉r

使用近似圆周率和半径 100,我们可以在 R 中输入如下内容:

4 / 3 * 3.14 * 100 ^ 3

r 也碰巧将单词 pi 理解为一个特殊符号,所以我们可以用它来代替,得到一个更准确的答案:

pi
4/3 * pi * 100 ^ 3

现在,给你一个小练习,反向计算:从体积 100 开始,确定半径是多少。

这并不难,是吗?现在你明白 R 是如何解释简单语句的了。接下来,您可以开始考虑在变量中存储值,以及如何使用它们。

Jasper McChesney 是一名高级数据分析师,拥有生物科学和数据可视化方面的背景。他曾在非营利组织、人力资源和高等教育部门工作过。他在马萨诸塞大学教授 R 课程,并在 Udemy 网上授课。

[## 所以你需要学习 R

所以你需要学习 r,但你不是程序员。不要惊慌。在本课程中,我将带您参观…

www.udemy.com](https://www.udemy.com/course/so-you-need-to-learn-r/?couponCode=E01B6507F68E1467FCF4)

覆盖现实

原文:https://towardsdatascience.com/overwriting-reality-7a0631728997?source=collection_archive---------35-----------------------

为引人注目的 AR 内容整合已有经验

增强现实(AR)体验的一个关键部分是数字内容的质量和丰富程度。在之前的一篇文章中,我们探索了构建以对象为中心的通用 3d 模型,使用了传统的基于运动的结构( SfM )技术以及用于深度推断和姿态估计的已有架构。这里的重点是采用更好的方法来使用深度学习推断场景深度,以解决难以绘制地图的区域。

在本文中,我们考虑了从真实世界捕获构建高质量模型的一些其他挑战。例如,考虑从以下视频构建表示的任务:

目标;建立一个精确的,视觉上吸引人的日产探路者模型

这里的目标显然是从一个短视频中创建一个吸引人的 3d 车辆模型。传统的流水线相对简单:

  1. 估计摄像机的轨迹和它的内在参数
  2. 在多视图立体管道中使用该估计轨迹来提供密集的点云
  3. 从估计的立体点构建平滑的网格,并使用视频数据对其进行纹理处理

然而,闪亮的金属表面往往对多视图立体方法反应不佳(尽管我们可以利用更复杂的深度恢复方法,如前所述)。我们还遇到了另一个更难解决的问题:重建只能和场景覆盖一样好。下图说明了这一点:

从上面的视频轨迹恢复的场景结构。注意车辆后面未被观察到的大片区域。

从上面的重建中可以清楚地看到,相机没有完全探索场景,因此场景是不完整的——几个大区域丢失了。这是我们寻求补救的典型问题;即使没有一个完全探索过的场景,我们也应该能够对目标的几何形状和外观做出有根据的猜测。

这篇文章的核心论点是,我们对正在讨论的对象的内在属性有一个很好的想法,一辆 2000 年初的日产探路者。如果我们有一个现有的 3d 模型,我们可以直接用我们的先验模型替换推断的模型,只要定位、比例和纹理与视频紧密匹配。

我们的第一个任务是将场景分成前景/背景;使用现代全景分割方法,这是微不足道的:

场景的每帧实例遮罩。

给定上面的密集(每像素)每帧分割,我们可以轻松地将场景几何和纹理划分为前景和背景组件,如下所示:

稀疏的相机点云,与重建的网格形成对比。(为清晰起见,省略了部分网格)

上面的模型被渲染为背景网格和前景点云。虽然立体点不够密集,无法完全恢复汽车本身,但它们对于提供关于汽车的汇总统计数据很有用:位置、方向、比例。

给定背景分割和要插入的新内容的类别、位置和比例,我们如何着手生成实际的 3d 输入?一种方法是利用部分重建的网格并执行形状完成(例如,[ 1 ,[ 2 ,[ 3 )。或者,我们可以从图像中合成完整的 3d 形状,例如[ 1 、[ 2 、[ 3 、[ 4 以获得清晰的概览]。在本文中,我们将探讨后者。

在这种情况下,形状合成是从 2d 图像推断完全 3d 结构。作为一个例子, IM-NET 是一种用于生成形状建模的学习隐式场方法,其对于单视图 3d 重建特别有用。下面的动画展示了形状生成模块 IM-GAN 的示例:

IM-GAN 的样车模型。注意多样性和质量。

通过将估计的比例、平移和旋转应用于来自网络的采样 3d 输出,我们可以将合成的内容直接插入到场景中,如上所示。

使用来自单视图重建(SVR)模块对来自我们数据集的分割图像的预测输出,我们可以产生精确平滑的合成模型(合成模型与估计位置和比例的融合),这是我们对象的近似。然后使用原始视频中的图像进行纹理处理:

IM-SVR 的预测输出,使用原始视频图像进行纹理处理。未观察到/观察不到的组件以灰色呈现。

尽管上面有一些可见的伪像(车辆的车轮与估计的模型不完全匹配,并且由于可见性问题,一些区域没有纹理),但结果是令人信服的——我们不需要为我们(先验地)非常了解的对象建立繁重的数据收集例程。对于以可扩展的方式为已知对象生成准确、相关的模型,这是一种很有前途的方法。

2020 年牛津(真实)农业会议

原文:https://towardsdatascience.com/oxford-real-farming-conference-2020-28f48bd47bda?source=collection_archive---------37-----------------------

NLP:3,8K tweets 的情感分析、单词嵌入和主题建模

介绍

上周,1 月 7 日至 9 日,牛津主办了历史悠久、传统而又务实的 牛津农业会议【OFC】及其解药 牛津真正的农业会议【ORFC】。两者都旨在将农业和食品部门的参与者联系起来,以应对当今农业的挑战。

过去三个月,我在世界可持续发展工商理事会为即将发表的论文“蛋白质途径:通过商业创新加速可持续食品体系转型”工作,该论文将在 2020 年达沃斯世界经济论坛上发布,我发现有必要看看该领域的最新讨论。

OFC 和 ORFC 为我提供了一个独特的机会。这些会议讨论了英国以及世界在农业方面面临的诸多挑战:应对粮食安全的必要性、保护自然生态系统的责任以及减少温室气体排放的必要性。

本文的目的是总结在 OFC 和 ORFC 期间发生的讨论,并获得英国农业食品部门最突出的参与者的概况。

粮农组织拍摄的图片

数据和方法

这篇博文的数据是使用 Twitter API 收集的。OFC 于 1 月 7 日至 9 日举行,ORFC 于 1 月 8 日至 9 日举行。我提前 5 天(2 日)开始收集推文,并在会议结束后一天(10 日)停止收集。总共记录了 3671 条推文,使用的标签是#OFC20、#OFC2020、#ORFC2020。

一旦收集了推文,我就使用自然语言处理(NLP)技术,即情感分析、词语嵌入主题建模

推文分析

以下图表说明了为更好地理解牛津(Real)农业会议的讨论而进行的分析。

菜单如下所示:

  • 探索性数据分析:每日和每小时的推文频率,按推文数量排名前 10 的推文,按点赞、转发和回复数量排名前 10 的推文。
  • 情绪分析:每日情绪得分,前 5 条最正面推文,前 5 条最负面推文
  • 语义分析:前 10 个单词,前 10 个标签,与“耕作”、“农业”和“食品”最接近的单词,推文中的主题

探索性数据分析

下面的线形图显示了从 OFC 和 ORFC 2020 开始前一周到两场会议结束后一天每天的推文数量和每小时的平均推文数量。最活跃的一天是 1 月 8 日,ORFC 的第一天和 OFC 的第二天,累积到近 2k 条推文。推文的每小时频率显示两个峰值,第一个在早上,上午 11 点,第二个在下午 3 点。这突出了会议与会者使用 Twitter 直接分享和评论正在进行的会谈。

左边的线形图显示了两次会议之前、期间和之后每天的推文数量,右边的线形图显示了每小时的平均推文数量。

看看以#OFC20 和#OFC2020 或#ORFC20 和#ORFC2020 为标签的十个最受欢迎的推特账户,就可以了解事件的主要参与者。下图显示了 OFC 和 ORFC 推特数量最多的十个推特账户。

左边的条形图显示了牛津农业会议的推文数量排名靠前的推文,右边的条形图显示了牛津真实农业会议的推文数量排名靠前的推文。推文的时间线是从 2020 年 1 月 2 日到 10 日。

在 OFC,最高职位大多由发人深省的演讲者占据,这与 ORFC 形成鲜明对比,后者由知名慈善机构和农民协会走在前面。

一些最活跃的 OFC 和 ORFC 参与者的快速事实!

莎拉·贝尔(Sarah Bell)是农业数字领导主题的一位有影响力的演讲者,罗布·约克(Rob Yorke)是农业主题的著名评论员,并促进了讨论:“如何资助“农业生态农业”?菲奥娜·史密斯教授是国际贸易教授,并在英国退出欧盟会议后讨论了英国农业食品贸易,马特·奈洛尔是 2017 年至 2020 年 OFC 的主任,也是“agrespect”的创始人,在农村促进和支持多样性、包容性和赋能。

土壤协会、农业生态学、可持续食品信托、创新农民、盖亚基金会(英国和爱尔兰种子主权)或可持续土壤与许多农民合作,并为可持续食品和耕作系统开展活动。食品伦理委员会的现任主任丹·克罗斯利毫无争议地赢得了推特发布数量的冠军。

图片来自土壤协会

下表显示了十条最受欢迎的推文,包括赞和转发。特别看看这些推文,可以深入了解最受欢迎的对话。气候变化、工业化植物汉堡的营养价值、英国农业食品贸易、泥炭地燃烧、种族主义、农林农业生态以及牲畜对土壤肥力是热门推文中的主要话题。

该表显示了当时最受欢迎的推文(按点赞数、转发数)。请点击此链接进行交互式可视化。

同样有趣的是查看回复最多的推文。与上面的相比,这些推文显示了哪些话题引起了主要的讨论和辩论。

仔细看看内容,可以发现严肃的问题和有趣的评论很好地结合在一起!你想知道“如何开始一个农业会议”的答案是什么吗?!"?如果有,那就在这里看一下

下表显示了当时最受欢迎的推文(根据回复数量)。请点击此链接进行交互式可视化。

情感分析

这种技术用于发现文本中表达的潜在情绪(积极、中性、消极)。已经为这项任务开发了几种工具。在这里,我使用了 VADER 图书馆,它是专门为理解社交媒体上表达的情绪而开发的。 Parul Pandey 文章GitHub 资源库是更好地了解 VADER 的绝佳资源。

下面的线形图显示了 OFC 和 ORFC 的平均情绪,其中+1 表示非常积极,-1 表示非常消极。

左边的线形图显示了 OFC 每天的平均情绪,右边的线形图显示了 ORFC 每天的平均情绪。

在会议开始的前一天,人们对会议的看法相对积极,但在会议开始后,这种看法略有下降。虽然 OFC 情绪在会议结束时再次上升,但 ORFC 情绪继续下降。

看起来 OFC 最终比 ORFC 发出了更加积极的信号!

如果你想知道这两次会议上最积极和最消极的推文是什么,看看下表吧!

这些表格显示了 OFC 和 ORFC 2020 年最积极和最消极的五条推文。

语义分析

为了从 tweets 中获得更细粒度的文本理解,我使用来自 gensim 库的 Word2Vec 模型创建了单词嵌入。这种技术可以很方便地找出哪些单词彼此关系更密切。对于 Word2Vec 模型背后的数学原理,请看一下托马斯·米科洛夫团队的原始研究论文。或者你可能更喜欢卡维塔·加内桑的更简化的文章或者维沙尔·库马尔精彩应用

但首先,让我们来看看最流行的词和标签在推文中的出现频率。

左边的线形图显示了 OFC 每天的平均情绪,右边的线形图显示了 ORFC 每天的平均情绪。

有趣的词是未来、变化和战略,指出农业系统需要规划和适应明天的气候。有趣的标签有“农业生态学”、“土壤健康”和“农林学”,以及“农场化”、“农村包容”和“精神健康”。第一组代表促进可持续农业的耕作方法,例如保护自然资源和确保粮食安全。第二组确定了当今农业系统中人们面临的主要挑战:精神压力和排斥。

词语嵌入

下面的四个散点图显示了与“牲畜”、“土壤”、“气候”和“生物多样性”实体更密切相关的词。

这四张图显示了与关键词牲畜、土壤、气候和生物多样性相关的最近的词(最近的邻居)。

牲畜

有意思的是“养畜”被收为“助养”、“减养”、“影响”、可持续”,即指“重要的”、讨论“围绕着养畜生产的部门。更具体地说,对于这个问题:有哪些可能的可持续措施可以用来帮助畜牧业减少排放?毫不奇怪,饲料质量、饲料添加剂、动物健康、厌氧消化器或放牧管理等词也与家畜相近,因为这些实体说明了农业食品专家提到的缓解选项。

也接近于“牲畜】、并指向在 ORFC 讨论森林的会议。这种耕作方式将树木和牧场整合成一个单一的畜牧系统,有利于减缓气候变化、动物福利和饲料供应。

土壤

”显示与“”有一些相似的词语。这里重要的是“一词,即可能指 土壤固碳 。这个想法是通过更好的 T42 土地管理措施,可以显著提高土壤质量和土壤吸收有机碳的能力。

气候

看着密切相关的实体为“气候”、“必须”、“政策”、“人人”和“工作”有趣地指出。也许你正在思考格里塔·图恩伯格在 2019 年 9 月美国国会呼吁采取行动应对气候变化时所说的话:“你必须采取行动。你必须做不可能的事。”。或者是关于【每个人【行动、协作工作“应对气候变化的需要”政策、企业领导的需要、可持续发展的农民和负责任的消费者

生物多样性

重要的是,与“生物多样性”接近的词有“农业生态学”、“实践”、“有机消费者”。这说明了对有助于保护自然栖息地而不是破坏自然栖息地的农业实践的需求,也说明了消费者需要采用健康、均衡和可持续的饮食

粮农组织提供的图片

结论

给你!虽然我错过了会议、鼓舞人心的演讲和人们,但我还是能瞥见辩论!当然,仍然有巨大的潜力来进一步挖掘推文,但这不会是今天。

你可以在这里找到交互式仪表盘可视化!

感谢阅读!

奥德

Ps:我有兴趣做社交网络分析!如果你碰到了什么好的文章或者 python 教程,请告诉我!

我是 数据和植物学家 垂直未来 ,以前在WBC SD。理学硕士。在城市分析和智能城市方面,来自 UCL 的 Bartlett 伦敦的 CASA 和 BSc。在食品科学方面来自 苏黎世联邦理工学院 。对城市、美食、健康充满热情通过TwitterLinkedIn取得联系。

测试的 p 值和功效

原文:https://towardsdatascience.com/p-value-and-power-of-a-test-fde61dd8c742?source=collection_archive---------14-----------------------

解释 p 值

我们在统计类中都用过这个:如果 p <0.05. This short blog is about an explanation of p-value, and how it is connected to the confidence interval and power of a test.

p 值定义(来自统计 101/维基百科) ,则零假设被拒绝

p 值是在假设零假设正确的情况下,获得至少与实际观察到的结果一样极端的测试结果的概率。(难以轻易理解)

尝试另一种方法

零假设是我们想要检验的世界的描述(给一张优惠券是否会增加销售)。在这个世界上,我们相信赠送优惠券不会增加销售额。我们收集数据样本(希望它能代表总体)并获得我们的统计数据(均值、方差、中值等)。p 值是我们想要检查的世界丢弃我们从样本集合中获得的数字的概率。更多解释见下图。

图一。解释 p 值

p 值只是告诉我们,我们的零假设是否为真,以便我们可以拒绝它,或者我们不能拒绝它。但是,我们不应该满足于 p 值的局限性

p 值没有给出零假设真实程度的概率。它只是给出一个二元决策,决定是否可以拒绝

  1. p 值不考虑效果的精确程度(因为它假设我们知道样本大小,并不能说明太多关于样本大小的信息)
  2. 第一类错误会导致机会成本,但第二类错误可能更有害。考虑医学发展。拒绝一种可能有效的药物会让公司在投资上赔钱。然而,接受一种不起作用的药物会使人们的生命处于危险之中。我记得第一类和第二类错误是生产者的风险和消费者的风险。因此,检验的功效也很重要(检验的功效= 1-类型 II 错误=当零假设为假时拒绝零假设的概率)。更多关于测试能力的信息,请参见图 2。

图二。检验的势

置信区间也是根据α计算的。置信区间被解释为:(1)如果我们收集了 100 个样本(并为每个样本的统计量创建了一个置信区间),这些包含统计量真实值(如总体平均值)的置信区间的频率趋向于 1-α。(2)当我们计算一个置信区间时,我们说在未来的实验中,真实的统计值将位于该置信区间内(这相当于现在在(1)中讨论的进行多次重复)。

The confidence interval is also calculated from alpha. The confidence interval is interpreted as: (1)if we collect 100 samples (and create a confidence interval for a statistic for each of the sample), the frequency of these confidence intervals which will contain the true value of the statistic (e.g. population mean) tends to be 1-alpha. (2)When we calculate one confidence interval, we say that in future experiments, the true statistic value will lie within that confidence interval (which is equivalent to doing multiple replications now a discussed in (1)).

Python 代码的 p 值基础

原文:https://towardsdatascience.com/p-value-basics-with-python-code-ae5316197c52?source=collection_archive---------1-----------------------

阿奇·范顿在 Unsplash 上拍摄的照片

什么是 p 值?它是在给定实际分布的情况下,你获得测试结果的概率。或者在 A/B 测试设置中,在给定初始假设的情况下,例如“我们认为平均订单价值为 170 美元”,这是我们衡量某些东西的概率,例如平均订单价值。

p 值是以一定的置信度回答问题。你经常听到人们说,“我有 90%的信心得到那份工作”或者“我有 99.99%的信心我唱不出佛莱迪·摩克瑞的水平”或者类似的涉及自信程度的话。这是一样的,除了它是一个实际的数量。

我们在中心极限定理文章中看到,如果我们抽取足够多的样本,这些样本均值的分布将是正态分布,该正态分布的均值接近总体均值。那么一个自然的问题是,我们观察到某个样本均值的可能性有多大。

让我们看一个例子。

我们假设,和之前的一样,我们公司客户的平均订单价值是 170 美元。也就是说,我们的总体均值是 170 美元(标准差是 5 美元)。 所以我们的假设是,我们整个客户群的平均订单价值为 170 美元。

现在我们想验证我们的假设。总的来说,我们不能测试整个人口,所以我们求助于测试许多较小的人口样本。现在,如果我们抽取 10,000 个样本,那么这些样本平均值的分布将如下所示:

整个客户群(数百万人)的平均订单价值为 170 美元。如果你一次选取较小的人群样本,将这个样本重复 10,000 次,并绘制样本均值,它将看起来是这样的分布。样本均值将在 150 美元和 190 美元之间变化。

因此,您可以看到,任何给定样本的平均值都可能从 150 美元到 190 美元不等。

然后,假设我们对一组人进行抽样,得到他们的平均订单价值,结果是 183 美元。我们想知道这种情况发生的概率。但是在统计学中,我们会问,假设总体平均值为 170 美元,样本平均值为 183 美元或以上的概率是多少。

这可以通过计算上图中所有大于 183 的数字,并除以抽样总数 10000 来计算。将和中的代码用于:

pvalue_101(170.0, 5.0, 10000, 183.0) 

大于 183.0 的数字百分比为 0.35%。这是一个很小的百分比,但不是零。如果你拒绝总体均值为 170 美元的假设,那将是错误的,因为我们清楚地从总体分布中得出这个样本均值。

同样,如果你想问,样本均值与总体均值 170 美元相差超过 13 美元的概率是多少?也就是说,得到小于 157 美元或大于 183 美元的样本均值的概率是多少?

超过人口平均数 170.0+/-13.0 的人数百分比为 0.77%。你可以看到,这个百分比是样本平均值的两倍,可能仅仅大于 183 美元。这是因为正态分布是围绕平均值对称的。

理解这个微小但非零的概率是很重要的。即使从完全相同的总体中抽取样本,样本平均值与总体平均值相差很大的可能性也不是零。因此,如果我们只运行 A/B 测试一天,这相当于抽取一个样本,我们就不能对总体均值做出决定。我们能做的是,估计在给定总体的情况下,我们得到样本均值的概率。

现在,假设你想知道相反的情况——95%的样本均值离总体均值有多远?这时68–95–99.7 规则就派上用场了。

图片鸣谢http://www . muela ner . com/WP-content/uploads/2013/07/Standard _ deviation _ diagram . png

上面写着:

  1. 我们有 68.2%的信心,如果我们抽取许多随机样本,样本均值将在μ+/- σ之间。在我们的例子中,170 +/- 5,即 68.2%的时间样本均值将在$165 和$175 之间
  2. 95.4%的时间我们的样本均值将在μ+/- 2σ之间。也就是说,95.4%的情况下,我们的样本均值将介于 160 美元和 180 美元之间。

在商界,人们经常谈论 p 值。p 值与上述规则密切相关。p 值衡量在给定总体平均值和标准差的情况下,样本平均值为某个值或更大值的概率。

结论

p 值给出了我们观察到我们所观察到的东西的概率,假设假设是真的。它没有告诉我们零假设为真的概率。

在我们的例子中,

  1. 假设总体均值为 170 美元,p 值为 0.35%将给出样本均值超过 183 美元的概率。
  2. 假设总体均值为 170 美元,p 值为 0.77%将给出样本均值大于 183 美元或小于 157 美元的概率。
  3. 它没有给我们假设为真的概率。 事实上拒绝总体均值为 170 美元的假设是危险的,因为我们显然是从总体均值 170 美元中得到样本均值的。

错误结论

人们通常会在开始一个实验时说他们想要 95%的置信度,这意味着他们期望 p 值为 5%(来自 100%-95%)。然后他们会取上述样本均值 183 美元,取其 p 值 0.35%,并说:“由于 0.35%<0.5%,我们的样本均值比我们允许的 5%更靠近尾部。因此,我们拒绝人口平均数为 170 美元的假设”。我们知道这是一个错误的结论,因为我们使用了 170 美元的总体均值来生成一些高于 183 美元的样本均值,尽管数量很少(见上图)。

你不能说假设是真是假。事实上,你甚至不能仅凭这一个数据点就否定这个假设。

开车回家是一个很难的教训。但总的来说,在生活中,我们无法说出任何假设为真的概率——我们所能说的只是根据某人的假设进行观察的概率。

Python 代码再现情节

您可以使用以下 Python 代码生成本文中的图和 p 值。

**def** pvalue_101(mu, sigma, samp_size, samp_mean=0, deltam=0):
    np.random.seed(1234)
    s1 = np.random.normal(mu, sigma, samp_size)
    **if** samp_mean > 0:
        print(len(s1[s1>samp_mean]))
        outliers = float(len(s1[s1>samp_mean])*100)/float(len(s1))
        print(**'Percentage of numbers larger than {} is {}%'**.format(samp_mean, outliers))
    **if** deltam == 0:
        deltam = abs(mu-samp_mean)
    **if** deltam > 0 :
        outliers = (float(len(s1[s1>(mu+deltam)]))
                    +float(len(s1[s1<(mu-deltam)])))*100.0/float(len(s1))
        print(**'Percentage of numbers further than the population mean of {} by +/-{} is {}%'**.format(mu, deltam, outliers))

    fig, ax = plt.subplots(figsize=(8,8))
    fig.suptitle(**'Normal Distribution: population_mean={}'**.format(mu) )
    plt.hist(s1)
    plt.axvline(x=mu+deltam, color=**'red'**)
    plt.axvline(x=mu-deltam, color=**'green'**)
    plt.show()

p 值—已解释

原文:https://towardsdatascience.com/p-value-explained-c7f5547c0562?source=collection_archive---------18-----------------------

它的含义和使用方法。用一个用例解释。

迈克尔·泽兹奇在 Unsplash 上的照片

p 值是推断统计学中的一个基本概念,用于根据统计检验的结果得出结论。简而言之,p 值是极端或不太可能的度量。事件发生的可能性帮助我们做出明智的决定,而不是随机的选择。

为了理解 p 值的重要性,我们应该熟悉两个关键术语:总体和样本。

  • 人口是一个群体中的所有元素。例如,美国的大学生是指包括美国所有大学生的人口。欧洲的 25 岁人群包括了所有符合描述的人。

对人口进行分析并不总是可行或可能的,因为我们无法收集人口的所有数据。因此,我们使用样本。

  • 样本是总体的子集。例如,美国 1000 名大学生是“美国大学生”人口的一个子集。

p 值提供的是基于样本统计评估或比较总体的能力。因此,P 值可以被认为是群体样本之间的桥梁。

我更喜欢用现实生活中的例子来解释这种概念,我认为这样更容易理解这个主题。

假设你和你的朋友创建了一个网站。你对目前的设计不满意,想做些改变。你告诉你的朋友,如果你在设计上做一些改变,更多的人会点击网站,你会通过广告赚更多的钱。然而,你的朋友认为这是浪费时间,改变设计不会增加点击率(CTR)。

当前设计

  • 你的朋友:改变设计不会提高点击率(零假设)。
  • 你:改变设计会提高点击率(替代假设)。

新型设计

既然你们不能达成一致,你想做一个测试。顺便说一下,这种测试叫做假设测试,比较无效假设和可选假设。

测试设置

  • 一半访问网站的人看到当前的设计,另一半看到新的设计
  • 你记录两种设计的每日点击率

但是,您需要运行测试多长时间?在这种情况下,人口是从你开始测试之日到永远访问你的网站的所有人。这个数据是不可能收集的。因此,您收集了代表总体的样本。您运行测试 30 天,并分别记录每天的 CTR。现在,两个种群都有 30 个样本。为什么是 30?我们稍后会谈到这一点。

30 天的测试结果

每天都是一个样本。每天的数值是当天的平均 CTR(即样本平均值)。

取 30 天的平均值,可以看到新设计的 30 天平均 CTR 高于当前设计。你要求你的朋友立即改变网站的设计,因为新的设计增加了流量。你的朋友回答道:

  • “坚持住!没有一致和大的差异,所以结果可能是由于随机的机会。如果我们再进行 30 天的测试,目前的设计可能会有更高的点击率。”

你的朋友建议做一个统计显著性检验并检查 p 值以了解结果是否具有统计显著性。

统计显著性测试测量样本的测试结果是否适用于整个人群。

是时候引入一些新概念了。

  • 概率分布:显示事件或实验结果概率的函数。
  • 正态(高斯)分布:一种看起来像钟的概率分布;

描述正态分布的两个术语是均值标准差。Mean 是被观察到的概率最高的平均值。标准偏差是对数值分布程度的测量。随着标准差的增加,正态分布曲线变宽。y 轴表示要观察的值的概率。

中心极限定理

正态分布用于表示分布未知的随机变量。因此,它被广泛应用于包括自然科学和社会科学在内的许多领域。证明为什么它可以用来表示未知分布的随机变量的理由是中心极限定理(CLT)

根据 CLT ,当我们从一个分布中抽取更多样本时,样本平均值将趋向于一个正态分布,而不管总体分布如何。通常,如果我们有 30 个或更多的样本,我们可以假设我们的数据是正态分布的。这就是我们进行 30 天测试的原因。

假设数据呈正态分布,因此当前版本样本均值的分布函数如下:

:要绘制正态分布,只需要知道均值标准差。您可以使用收集的 30 个样本平均值来计算这些值。

样本平均值似乎是 10,因此更有可能观察到 10 左右的值。例如,CTR 为 11 并不奇怪,因为这种可能性很高。然而,获得 16.5 的值将是一个极端的结果,因为根据我们的分布函数,它具有非常低的概率。

如果根据当前设计的分布,新设计的样本均值被观察到的概率非常低,我们可以得出结论,新设计的结果不是随机出现的。如果结果不太可能被随机观察到,我们说这些结果在统计上是显著的。为了确定统计显著性,我们使用 p 值。 P 值是获得我们的观察值或有相同或较少机会被观察的值的概率。

假设新设计的样本平均值为 12.5。因为它是一个连续函数,所以区间的概率就是函数曲线下的面积。因此,12.5 的 p 值是上图中的绿色区域。绿色区域表示获得 12.5 或更极端值(在我们的例子中高于 12.5)的概率。

假设 p 值是 0.11,但是我们如何解释它呢?p 值为 0.11 意味着我们对结果有 89%的把握。换句话说,有 11%的概率结果是随机的。类似地,p 值为 0.5 意味着有 5%的概率结果是随机的。

p 值越低,结果越确定。

为了根据 p 值做出决定,我们需要设置一个置信水平,它表示我们对结果的确信程度。如果我们将置信度设为 95%,则显著性值为 0.05。在这种情况下,要使检验具有统计显著性,p 值必须低于 0.05。

如果你和你的朋友将置信水平设为 95%,发现 p 值为 0.11,那么你的结果在统计上不显著。你的结论是,由于随机因素,新设计的平均值更高。因此,您不需要更改设计。

如果新设计的样本平均值是 15,这是一个更极端的值,p 值将低于 0.11。

如果新版本的 CTR 高于当前版本,结果为 15.0,则为 p 值

我们可以看到,p 值比前一个小很多。假设 p 值现在是 0.02。因此,根据 95%的置信水平,该 p 值表明结果具有统计学意义。

值得一提的重要一点是,我们正在测试新设计的结果是否比当前设计的结果。因此,在计算更多极值的概率时,我们只考虑右侧的值。如果我们检验结果是否不同,我们需要考虑分布函数的两边。

如果新版本的 CTR 与当前版本不同,结果为 15.0,则为 p 值

感谢您的阅读。如果您有任何反馈,请告诉我。

p 值、假设检验和统计显著性

原文:https://towardsdatascience.com/p-value-hypothesis-testing-and-statistical-significance-63bdd7277e66?source=collection_archive---------36-----------------------

如何理解差异是否真的重要?

你可能听说过双陆棋。虽然是最古老的棋盘游戏之一,但它抵制了数字时代,在许多东方文化中仍然非常普遍。双陆棋是一种双人游戏,每位玩家有 15 颗棋子。目标是将棋子移动到棋盘的角落并收集它们。玩家掷出一对骰子,并相应地移动棋子。因此,这是一个需要策略和运气同步才能获胜的游戏,我认为这是它存在了很长时间的主要原因。在这篇文章中,我们对双陆棋的“运气”部分感兴趣。

Backgommon ( 图源)

骰子有六种结果,从 1 到 6。当你掷两个骰子时,结果数增加到 36 (6x6)。为了简单起见,我假设这个游戏只有一个骰子。你能移动的次数取决于骰子的结果。所以,如果你掷出更高的数字,你可以快速移动,增加你赢的机会。如果你一直掷出所有的六,你的对手会在掷出几个后开始叫你“幸运”。例如,连续三次掷出 6 是极不可能的。现在是时候引入 p 值了。

P 值是一个事件发生可能性的量度。该定义可能会导致将 p 值理解为事件的概率。它与事件的概率有关,但它们不是一回事。

P 值是获得我们的观察值或有相同或更少机会被观察的值的概率。

考虑掷骰子的例子。让我们将事件 A 定义为“连续三次掷出 6”。那么,事件 A 的概率:

这个小数字是事件 a 的概率。事件 a 的 P 值是多少。P 值有三个组成部分:

  1. 事件 A 的概率
  2. 与事件 A 有同等机会发生的事件的概率
  3. 比事件 A 发生几率小的事件的概率

我们已经知道了事件 a 的概率,我们来计算其他部分。与事件 A 有同等机会发生的事件连续三次掷出不同的数字。比如三次滚动一个 1。由于骰子上有 6 个数字,这些事件的概率(排除 6 个,因为已经计算过了):

注意:为了简单起见,顺序被忽略。如果考虑顺序,5–6–6 或 6–5–6 与 6–6–6 的概率相同。我们认为情况 5–6–6 和 6–5–6 是相同的(一次 5 和两次 6)。

在我们的案例中,不存在发生几率更低的事件,因此发生几率更低的事件的概率为零。因此,连续三次滚动 6 的 p 值:

p 值很低,因此我们可以说这是一个不太可能发生的事件。

p 值多用于假设检验。考虑我们有一个网站,并计划在其设计上做一些改变,以增加流量。我们想测试“新设计”是否会吸引更多的注意力,从而增加网站的流量。我们应该定义两个假设:

  • 零假设:新设计不会增加流量
  • 替代假设:新设计增加了交通流量

我们通过点击率(CTR)来衡量流量。当不可能或不可行比较两个总体时,我们抽取样本并代表总体比较样本。在我们的例子中,人口是我们网站存在期间的所有流量,在它消亡之前是不可能知道的。所以我们取样本。我们向一半的观众展示当前的设计,向另一半的观众展示“新设计”。然后我们测量 50 天的点击率(即收集 50 个样本)。我们计算了所有样品的 CTR,发现“新设计”的平均 CTR 高于当前设计。我们是否仅仅通过比较手段就永久地改变了设计?绝对不行。

我们可能通过随机机会获得更高的点击率。我们需要检查 p 值。在进入这一步之前,我将提到一个被称为中心极限定理的最新定理:

根据中心极限定理,当我们从一个数据分布中取更多的平均值时,平均值将趋向于一个正态分布,而不管总体分布如何。如果样本量很大,样本数超过 30,中心极限定理就更加确定。

因此,当前版本的样本均值分布如下:

这是概率分布。如图所示,当前设计最有可能的 CTR 似乎是 10。我们可以说它可能观察到 12.5 和 7.5 之间的值。但是,随着值不断增加或减少,概率会显著降低。尾部的值非常极端,很难观察到。如果从新设计中获得的平均 CTR 约为 12.5,那么我们可以得出结论,这个结果可能是随机的,因为它也可能从当前设计中获得。回想一下,p 值是获得我们的结果或同样可能或更极端结果的概率。因此,这种情况下的 p 值是下图中的绿色区域。

从新版本中获得 12.5 的 p 值

假设新设计的平均 CTR 为 15.0,这是当前设计的极限值。使用当前设计观察 15.0 的 p 值可以在下图中看到。由于使用当前设计得到 15.0 的可能性极小,我们可以得出结论,新设计和当前设计的结果之间的差异是而不是由于随机机会。因此,新的设计实际上提高了网站的点击率。

从新版本中获得 15.0 的 p 值

p 值告诉我们这种差异是否真的重要。

:我们正在测试新设计的结果是否比当前设计的。如果我们要测试新设计的结果是否与当前设计的不同,我们将需要包括左边尾部的值,其概率等于或低于我们的结果。在这种情况下,p 值变为:

如果新版本不同于当前版本,则 p 值为 15.0

p 值越低,结果越确定。

如果 p 值是 0.05,那么我们对结果有 95%的把握。换句话说,有 5%的可能性结果是随机的。代表总体比较两个样本的过程称为统计显著性检验。

统计显著性检验测量样本的检验结果是否可能适用于整个人群。

在进行统计显著性测试之前,我们设置了一个置信水平,它表明我们对结果的确信程度。如果我们将置信度设为 95%,则显著性值为 0.05。在这种情况下,要使测试具有统计显著性,p 值必须低于显著性值。假设我们将测试的置信水平设为 95%,发现 p 值为 0.02,则:

  • 我们 98%确定新设计的 CTR 高于当前设计。
  • 有 2%的几率由于随机机会而获得结果。
  • 根据我们的置信水平,结果具有统计学意义。

我们现在可以将样本结果应用于整个人口。在假设检验方面,这一结果建议拒绝零假设,并根据替代假设采取行动。回想一下两个假设:

  • 零假设:新设计不会增加流量
  • 替代假设:新设计增加了交通流量

我们可以采用新的设计。

置信度取决于任务。95%是一个常用值。对于像化学反应这样的敏感任务,置信度可以设置为高达 99.9%。在 99.9%置信水平的情况下,我们寻找 0.001 或更小的 p 值。

感谢您的阅读。如果你有任何问题,请让我知道。

p 值,以及何时不使用它们

原文:https://towardsdatascience.com/p-values-and-when-not-to-use-them-92cab8a86304?source=collection_archive---------11-----------------------

如果你在涉及数据分析的领域(如今基本上是每个领域)查看已发表的研究论文,你会经常看到数字旁边有一个小星号*,并有一个脚注说“统计显著”。统计显著性本质上是一种检查,我们可以用来验证我们的结果不是由于偶然,它们涉及到计算一种叫做 p 值(概率值)的东西。虽然统计显著性星号通常被解释为对研究有效性的认可,但我们盲目使用 p 值会遇到一些问题。但是在我解释什么是 p 值以及与之相关的问题是什么之前,理解这类研究使用的一般框架——假设检验是很重要的。

假设检验

假设检验框架包括比较“零假设”和“替代假设”。通常,空值是现状,替代值是你的假设——你想要测试的假设。例如,假设你有一枚幸运硬币,你认为它偏向正面,你想收集数据来验证(或否定)你的想法。在这种情况下,无效假设或现状是硬币是而不是偏向的——正面的概率是 0.5。

零假设:P(头数)= 0.5

另一个是你想要测试的假设,硬币偏向正面。换句话说:

替代假设:P(头数)> 0.5

我们可以根据你想要测试的确切想法,用不同的措辞来表达。例如,如果你认为硬币是有偏向的,但是不确定偏向哪个方向,你可以选择概率(正面)!= 0.5.

现在,关于假设检验,有一件重要的事情需要注意——我们并不试图明确地说另一个假设是否正确。我们对这个框架所能做的就是,比如说,在一定程度上,我们收集的数据是否能让我们拒绝零假设。因此,我们正在收集证据反对无效,而不是数据支持备用。在这个框架中,您可能会犯两种错误:第一类错误,当 null 实际上为真时,您拒绝它;第二类错误,当 null 为假时,您保留它。这里还有一点很重要——I 类错误通常比 II 类错误更糟糕。当现状实际上是真的时,我们想要避免拒绝现状,所以我们通常会在拒绝空值时格外“保守”。你会看到一个常见的类比是刑事审判——零假设是被告是无辜的,只有当你收集的证据压倒性地否定零假设时,你才会得出相反的结论。在被证明有罪之前是无辜的。

最后要注意的是一个叫做“测试统计”的数字。这通常只是一些聚集你的数据的量,比如你所有观察的平均值。在我们掷硬币的例子中,检验统计量可以是我们看到的人头的比例。我们最终决定是否拒绝空值取决于这个检验统计量的值。如果它非常“极端”或不太可能给定零假设(假设我们看到 10 个头,如果硬币是无偏的,这是不太可能的),那么我们可以拒绝零。但是我们如何准确地测量检验统计量的极端程度呢?这就是 p 值的来源。

你如何计算 p 值?

我将重点介绍 p 值的解释,在实践中,p 值通常用于实际计算。p 值是在零假设下我们观察到一个测试统计量至少和我们实际看到的一样极端的概率。这个概率越低,我们观察到的数据就越极端。如果空值为真,数据越极端,越有证据表明空值不是真。

在我们抛硬币的例子中,假设我们将硬币抛了 10 次,看到了 7 次人头。获得这种极端或更高结果的概率包括获得正面 7、8、9 或 10 次。假设硬币真的是无偏的,这个概率是 0.172。这是我们的 p 值。

所以 p 值只是一个数字,代表有多少证据反对你的零假设。根据测试和测试统计的确切性质,我们会做出不同的假设和近似来获得该概率的值,但其核心是,这就是计算 p 值的全部内容。我们将根据预先确定的显著性水平选择拒绝或保留空值,这取决于 p 值是低于还是高于该水平。这种阈值最常用的显著性水平是 0.05,如果 p 值低于 0.05,我们拒绝空值,否则,我们保留它。我们称这种低 p 值的情况为“统计显著”结果。在掷硬币的例子中,由于我们的 p 值是 0.172,我们保留了硬币是无偏的零假设。换句话说,我们收集的数据不足以让我们拒绝零假设。

现在,快速说明一下什么是 p 值不是。不是 null 为真的概率!这样解释很容易,因为当 p 值很小时,我们拒绝空值,但这不是 p 值。事实上,假设检验框架根本没有给假设分配概率。它只查看在特定假设下看到数据的概率,如果概率很低,则拒绝该假设。给一个为真的假设分配一个概率完全是另外一回事,由贝叶斯推理解决(远远超出了这篇博文的范围)。

现在,让我们继续讨论为什么 p 值本身会产生误导。

统计意义与科学意义

反对 p 值的第一种情况需要理解统计显著性和科学显著性的区别。为了说明这一点,考虑一个例子。假设我们正试图测试一种用于治疗潜在致命疾病的新药的疗效。我们要测量的量是预期寿命。我们的无效假设是该药物不会影响预期寿命,我们的替代假设是该药物提高了预期寿命。假设我们运行一个实验,收集数据,计算我们的 p 值,结果是 0.03。那还不到 0.05,太棒了!我们已经证明了这种药物的有效性,对吗?

但是等等,我们真的知道预期寿命提高了多少吗?p 值表明,有足够的证据反对药物没有效果的假设,但它没有告诉我们预期寿命是增加了一周还是一年,这当然是该研究的一个重要方面。这是 p 值的一个核心问题——我们收集的数据越多,我们能够识别的影响就越小。虽然这通常是一件好事,但在大多数情况下,我们的零假设并不完全正确,因为现实世界如此复杂。即使在我们掷硬币的例子中,由于硬币的设计和我们投掷的方式,正面的实际概率也可能是 0.5001。给定足够多的掷硬币,我们可以潜在地检测到这一点并拒绝空值——但这并不意味着它实际上是一个重要的结果。所以单单一个很小的 p 值只能说明我们可以剔除零(统计显著性),而不能说明影响有多大(科学显著性)。

已发表研究中的选择偏差

这似乎是一个显而易见的观点,但对科学研究的有效性有着深远的影响——通常,只有积极的结果才会被发表。你很难找到试图测试一种药物疗效的公开研究,这种药物显示出高 p 值,因此无法证明该药物的有效性。这看起来很自然,对吗?为什么我们要公布一堆负面的结果,显示什么不起作用?当然,我们应该把重点放在实际显示积极结果的研究上。

然而,当我们考虑这种只在 p 值和统计显著性的确切含义的背景下发布积极结果的倾向时,我们开始遇到一些问题。要理解为什么会这样,假设一堆人决定要测试我的幸运币。1000 个人每人拿着硬币,翻转 10 次,计算 p 值。现在,如果我的硬币实际上是无偏的,我们会看到这样的分布:

1000 次抛硬币实验的结果

所以大多数人会像我们预期的那样得到 4、5 或 6 个头。对这些人来说,p 值很高,他们认为硬币是无偏的。但是很可能会有一些人最终连续翻转 10 个头像。在这组特定的实验中,有 3 个人翻转 10 个头。现在这些翻转并没有什么特别的,只是当你重复实验很多次时,你所期望发生的。但是在这种情况下 p 值是多少呢?0.00098!太好了,小于 0.05,所以他们继续发表他们的发现,第二天一篇文章出来了——“科学家明确证明幸运硬币是有偏见的”。

显然,这是一个极端的例子,但你可以看到这里的问题。根据定义,p 值允许有很小的假阳性机会。当类似的研究由多个小组进行,但只在结果为阳性时才发表时,很有可能许多已发表的研究正是如此——假阳性。这就是再现性如此重要的原因。如果有人重复一个已发表的实验,他们也应该能够实现低 p 值。这一问题以及其他相关问题导致了大约 15 年前的一场巨大的可重复性危机,引发这场危机的是约翰·约安尼迪斯的一篇著名论文,题为为什么大多数发表的研究结果是错误的。报纸上的一段引文:

p 值并不能最恰当地代表和概括研究,但是,不幸的是,有一种普遍的观念认为医学研究文章只能根据 p 值来解释。研究发现在这里被定义为任何达到正式统计学意义的关系,例如,有效的干预、信息预测、风险因素或关联。“负面”研究也很有用。“否定”实际上是一个用词不当的词,曲解的现象普遍存在。

XKCD 甚至有一个关于这个问题的相关漫画:

来源: XKCD

这个问题没有简单的解决方法。总会有一些遇到 1 型错误的机会,我们不能期望每一个负面的结果都被公布,以获得所进行研究的完整全球视图。一种可能性是降低我们认为显著的 p 值。几年前,一群科学家(包括约安尼迪斯)提出了一个提案,就是为了做到这一点,将 p 值阈值降低到 0.005。

即使这成为常态,这也只是权宜之计。解决根本问题的最佳办法是为负面研究提供发表的途径(如 Arxiv ),确保发表的正面结果研究包含所有需要由其他团队复制的信息,并以健康的怀疑态度解释即使很低的 p 值。

多重比较问题

关于 p 值和统计显著性的第三个问题与前一个问题非常相似,但考虑到它与大多数科技公司都采用的 A/B 测试框架的相关性,我认为值得一提。在技术领域,进行随机实验来测试各种变化的影响是很常见的。例如,如果您想测试更改首页字体的颜色会如何影响用户参与度,通常您会将一定比例的用户分配到现有的颜色(控制),将一定比例的用户分配到新的颜色(处理),并测量这两组用户参与度的差异。

现代的 A/B 测试框架已经变得非常复杂,以至于你可以查看大量的指标来试图理解你的治疗到底做了什么。由于样本量较大,它们通常还允许您测量非常小的差异(效应大小)。自然,它们也包含了 p 值计算和统计显著性。虽然这使我们能够全面分析我们运行的任何实验,但重要的是要注意,如果我们只是简单地查看所有可用的指标,我们最终会遇到与上一个案例相同的问题。不存在的差异仅仅因为噪音而显示出统计学意义的可能性总是很小,当我们查看大量指标时,很可能最终会遇到一些假阳性。

这只是统计学意义的本质,并不能真正避免。唯一的解决方案是记住这一点,并在运行实验之前定义您期望影响的指标。当您确实产生了您不期望改变的度量差异时,重要的是进一步挖掘并理解您的处理是否真正导致了差异,或者它只是碰巧是噪声。然而,除了 p 值之外,我们还可以采用其他方法。

置信区间

在结束之前,我将快速讨论置信区间,它通常比 p 值更能提供信息。基于您收集的数据,您可以构建一个对应于 95%置信区间的参数值范围。如果你重复你的实验很多次,你会期望你构建的置信区间在 95%的时间里“捕获”真实的参数值。置信区间的好处是它们更容易解释,因为它们实际上显示了一系列的值!这意味着你可以看到效果的实际大小,以及结果是否有统计学意义。例如,考虑以下情况:

来源:为什么 P 值文化不好,置信区间是更好的选择

x 轴是你的效果的大小,或者你的治疗组和对照组之间的差异。0 代表零假设,虚线表示您认为“临床上”或“科学上”显著的差异水平,例如,您的药物将预期寿命延长了一年(这可能因实际研究而异)。

水平线显示了不同的置信区间,以及你可以从中推断出什么。当您的 95%置信区间不包含 0 时,这就相当于说您的 p 值小于 0.05,您的结果具有统计学意义。虽然知道这一点很有用,但你可以看到置信区间如何包含这一点,以及更多信息。如果您的置信区间高于您的临床显著性阈值,则结果最强。在图中,您可以看到统计和临床显著性的不同组合。然而,你只能通过查看置信区间来得到这个。如果你只看左边显示的 p 值,它们不能提供同样丰富的信息。所以从这个意义上说,置信区间比 p 值更有用。

结论

因此,我们已经看到了假设检验框架背后的动机和 p 值的直观含义。但除此之外,我们已经看到单独使用 p 值常常会导致误导性结果,尤其是在研究发表过程的背景下。鉴于这些问题,重要的是采取严格的实验过程,并尽可能促进负面结果的公布。这与置信区间的使用一起,通常有助于提供更可靠和信息更丰富的结果。

参考

[1] 所有的统计:拉里·乏色曼的统计推断简明教程

[2] 为什么大多数发表的研究结果都是假的

[3] 一场关于 p 值的无聊辩论展示了科学——以及如何解决它

[4] 即使是科学家也无法轻松解释 P 值

[5] 重新定义统计显著性

[6] 对假设检验和 P 值的直观解释

[7] 假设检验和 p 值:一个温和的介绍

[8] 为什么 P 值文化不好,置信区间是更好的选择

posted @ 2024-10-14 11:49  绝不原创的飞龙  阅读(280)  评论(0)    收藏  举报