人工智能项目的敏捷框架——需求
多年来,软件开发社区已经达成了广泛的共识,即软件开发应该有一个迭代的生命周期——根据用户反馈不断改进产品。
今天,许多人工智能团队在采用迭代生命周期之前,面临着与传统软件团队相似的困难。虽然人工智能并没有改变构建符合产品市场的优秀产品的本质,但它确实有细微差别和复杂性,使得应用现有的方法很困难。这一系列文章的目标是提出一个迭代生命周期框架,它适应于以人工智能为中心的软件。
这篇文章是独立的,不需要阅读系列中的前一篇文章。在上一篇文章中,我们已经讨论了这个框架的动机,并提供了一个概述,为很好地执行它打下了基础。在这篇文章中,我们将讨论框架的需求阶段。
端到端思考
现实世界问题的人工智能解决方案——往往不仅仅是一个“端到端”解决问题的单一机器学习模型。它们是许多不同算法的组合——机器学习、经典算法(例如“后处理”)和“胶水代码”。
虽然机器学习模型可能解决大多数“最棘手”的问题— 但只有所有这些组件的组合才能产生用户体验到的“下游”结果。
许多产品经理和决策者陷入了定义“核心”算法组件(例如,核心深度学习模块)的需求的陷阱,而在实践中,它通常与用户体验没有足够强的关联。这是定义需求和附加步骤中的常见错误。我们已经看到工程经理要求他们的团队“报告算法的性能”。工程师报告核心模型的准确性超过 95%,而实际上,与用户体验最相关的“下游”指标要低得多。
我们将把这种不同算法组件的组合称为“算法包”,以将其与单一模型明确区分开来:
影响用户在生产中体验到的算法性能的所有代码、模型、二进制文件(例如神经网络权重)和配置。即使在单个文件中的改变也定义了算法的新版本。
作为“算法包”整体的结果,是用户体验到的结果——它们是对业务有意义的结果——远远超过任何单个模型或组件的结果。算法的努力应该是为了优化这个整体包的需求。
在许多情况下,“核心模型”的性能可能看似很低,但优化软件包的其他组件仍然更有好处(反之亦然——模型看似极高的性能仍然会导致下游性能低下)。这个例子证明了在执行管理人工智能项目的过程中,将软件包作为一个整体来考虑是很重要的。大部分过程应该集中在那个抽象层次上。
要求
跳过这一部分,直接进入“看看模型能做什么”可能很有诱惑力。然而,如果你想在终点线达到预期的结果,这些要求是至关重要的。
请注意,本系列的目的是通过几个核心示例来指定流程中的步骤——即“什么”(例如评估算法设计的可行性)。我们将不描述“如何”(例如,为算法执行有效 POC 的原理)。
下面,我们将描述组成需求定义阶段(见上图)的两个步骤以及执行它们的指导方针。这两个步骤应该以交替的方式执行— 在这两个步骤之间来回循环,作为能够确定最具成本效益的需求的过程。
1.确定产品(算法包)需求及其背后的逻辑
需要记住的事项:
产品经理应该在算法包的层次上定义需求,因为它下面的模型和子算法是实现细节。通常他们的性能对用户感觉的准确性的影响(这是产品应该关心的)是非常不直观的。
线性增加需求会成倍增加模型的复杂性。来源:https://xkcd.com/1425/
力求简单——线性地增加需求可以指数地增加模型的复杂性。通常,需求并不严格,通过对需求稍作妥协(通过删除整个特性或降低性能目标)可以获得很多,这使得能够更快地获得用户反馈,并重新评估需求。
比定义准确的需求集更重要的是向工程师传达这些需求背后的逻辑。在接下来的步骤中,工程师将提出执行这些要求的替代方案,理解其中的逻辑,可以帮助他们通过做出合理的妥协找到更具成本效益的替代方案。
工程师应该努力获得这些知识,因为这可以提高他们的效率,即使这些知识不是由产品引发的,也要提出要求。
2.评估算法设计方案的可行性和复杂性
来源:https://xkcd.com/974/
2.1.讨论可能的解决方案备选方案及其成本效益(通过评估成功的可行性和复杂性)
算法包的需求被定义(或更改)后,需要提出几个技术方案来执行这些需求。
每个选择实际上为包的每个子算法定义了一组不同的需求,以一种满足整体需求的方式。
每个备选方案可以在包的子算法之间不同地分布权重,例如,单个备选方案可能对模型要求更多,而另一个备选方案可能仅要求后处理,甚至不改变模型。
**也提出替代方案,在需求上做出合理的妥协,同时显著降低执行成本。**如果相关工程师不精通产品逻辑,发起与产品的讨论以理解合理的妥协。
评估每个备选方案的成本效益:相关工程师应首先彻底评估每个备选方案成功实现需求范围的可行性,以及资源(时间、人力、数据注释等)。)是该备选项所必需的。
一旦对所有备选方案进行了评估 —评估将被完整地呈现给相关决策者,因为他/她决定了所选备选方案中的“冒险”程度(包括性能风险\折衷和浪费资源的机会成本风险)。如果相关决策者不是产品经理,则项目经理应意识到绩效风险承担\妥协。
评估替代品成本效益的技巧:
1.算法的简单性
经过验证、可用(见下文)和\或简单的首选解决方案,按重要性排序
记住,尝试高级模型\算法是很容易的,但是在实践中,一个简单得多的模型可以给出一个非常有效和可部署的基线,以后可以根据产品优先级进行改进。
关于类似问题的(已证实的)工作的可用性(更高的可用性增加了成本效益)。使用以下问题确定可用性,问题按预期重要性排序:
- 替代方案是否可以基于公司已经开发和验证的现有管道?(利用资产)
- 类似的问题在大规模的产品中解决过吗?
- 替代方案可以基于流行的开源库吗?
- 关于类似的问题,有哪些(多少)可靠的文献?
- 对于市场上没有类似技术的算法,作为产品需求阶段的一部分,执行可行性评估的复杂性是什么?
- 算法在生产中会有哪些计算约束?
2.数据采集成本(较高的成本降低了成本效益)
- 我们有不同/相似项目的数据吗?
- 获取原始数据有多难?
- 数据标注有多耗时和昂贵(考虑到可以加速标注的工具和简单/较慢的模型)?
- 需要多少数据?
2.2.对选择的备选方案进行设计同行评审
同行评审确定了可以在生命周期早期解决的问题。在许多情况下,在生命周期的早期发现的问题,修复成本要低得多。例如,在以兼容的方式对数据进行注释之前,或者在执行大量开发工作之前,理解算法设计是不够的。
来源:grmarc 创建的技术向量—【www.freepik.com
这个帖子系列是与 Idan Bassuk 合著的。
我将很高兴听到你的想法和经验。在下面的帖子中,我们将讨论开发阶段。
设计游戏关卡的人工智能
我们如何为我们的益智游戏开发遗传算法
几个月前,我的儿子雨果(12 岁)和我决定学习用 Unity 开发游戏。我们会做一个。我们想出了一个名为 Elemaze 的益智游戏,代表四种元素的小家伙必须合作才能在迷宫中找到通往箱子的路径。我们学到了很多关于编码、图形、游戏机制等方面的知识。Hugo 继续创作他自己的游戏“人工智能将生存”,作为对自己的挑战(见 i tch.io 和 Google Play ),我们参加了两次游戏堵塞(我们真的没有做得很好,但这都是为了体验和乐趣)。然而,我们真正学到的是,一旦有了基础,花时间的不是编码、机械、音乐或图形,而是制造关卡。
Elemaze 的菜单屏幕。
所以,这是一个关于我们如何创造一个遗传算法来为 Elemaze 设计关卡的故事。这也是一个关于更传统的人工智能方法如何仍然令人难以置信地相关,更容易实施,并且,特别是在遗传算法的情况下,可以提出全新的,创造性的和令人印象深刻的解决方案来解决那些会让我们无休止地挠头的问题的故事。
Elemaze:游戏
我们创作的游戏比较简单,重点是相对。每一关都是一个网格中的迷宫,每个格子/瓷砖都有四种颜色的地板:白色代表空气,蓝色代表水,红色代表火,绿色代表土。在迷宫的某个地方有一个箱子,目标是让四个角色中的一个——飞行员、船工、消防员和地球人——到达箱子。每个角色都可以被告知去迷宫中任何其他未被占据的单元,并会沿着最短的路径到达那里。到目前为止足够简单,但显然还有更多。每个角色都可能被某一种颜色杀死,并且可以从一种颜色变成另一种颜色。即:
- 飞行员在地球上行走会死
- 水人在空中行走会死亡,并把火变成水
- 消防员在水上行走会死,并把泥土变成火
- 地球人在火上行走会死,会把水变成土
埃勒梅兹的一个关卡。没有一个角色能直击胸膛。消防队员必须离开,这样沃特曼就可以给地球人腾出一条上去的路。然后地球人必须回去,这样消防员就可以为飞行员打开通向胸腔的路。这是一个 6 步解决方案的水平。
这创造了很多有趣的可能性,其中一个角色将不得不在某个地方改变颜色,以便另一个角色可以移动,但不是在另一个角色离开之前。关卡可以很简单(移动一个角色为另一个角色开路),也可以更复杂(几次来回移动,直到一个角色最终到达胸部)。然而,想出那些更复杂的层次是非常困难的。在决定我们需要帮助之前,我们手工创建了 18 个级别,其中大多数很简单(2 到 4 步),有些稍微难一点(5 到 6 步)。
准备好基础
花费几个小时来创造足够的关卡以使游戏可以发行的观点并没有让我们充满快乐。我们经常想出一个我们认为很难的水平,直到我们测试它,并意识到它有一个简单的解决方案或根本没有解决方案。懒惰是创新的驱动力,那时我们想:“也许我们可以解决这个问题!”。很长一段时间以来,我一直在从事人工智能方面的研究,并教授了许多不同的人工智能技术。我知道我们拥有的成分(一个具有相对可测量的成功标准的“设计”问题:关卡应该很难解决),以及我们没有的成分(数千个好关卡的例子,如何制作关卡的规则,等等)。遗传算法似乎非常适合这一点,但在开始之前,我们必须将许多事情落实到位,包括一种表示级别的方法和一种自动(最好是快速)解决它们的方法。
跳过大约一百万个细节,我们创建了一个基本的 JSON 格式来表示层次(每个角色的胸部位置,以及一个包含每个角色颜色和方向信息的单元格矩阵)。我们还想出了一个在终端显示关卡的方法(见下文),因为每次我们想看结果的时候都加载 Unity 是行不通的。
基于 ASCII 的表示终端中的关卡,以及游戏中相应的关卡。
给定任何水平,然后我们需要能够解决它,所以我们可以知道,首先,它有一个解决方案,其次,它有多难解决(它需要多少步骤)。跳过更多细节,我们实现了 A* 搜索算法,其中搜索的每一步都对应于将一个字符移动到该层中的给定单元格。对要尝试的下一步的评估是基于已经完成的步数(【g(n)】)以及作为对延长路径的成本的估计(【h(n)】),角色和胸部之间的最小距离,忽略墙壁。因为这总是低估了从给定位置到达胸部的成本,所以根据 A*算法的特性,我们保证找到的解是最优的。它总是用最少的步骤找到解决方案。
一个 5 步解决方案:消防员移动,然后是水兵,地球人,地球人,最后,消防员到达胸部。
遗传算法
你可能会认为,解决一个关卡并不能让我们离发明一个关卡更近一步,对吗?实际上,这就是遗传算法的全部意义:你需要做的一件事就是用一种可以测试的方式知道你在寻找什么。遗传算法基于进化论:由于自然选择(“适者生存”)和随着时间的推移对基因库的小修改(突变),物种变得更适应它们的环境。所以我们首先需要的是能够知道一个级别有多“适合”。我们需要一个适应度函数来告诉我们一个级别是否是一个好级别。
健康
那么我们怎么知道一个水平好不好呢?我们想要不太容易解决的级别,因此解决方案需要一定数量的步骤。因此,我们可以说,如果一个级别接近需要解决的理想的大量步骤 S ,那么这个级别就更合适。就这么简单。假设我们的求解器不仅返回给定级别 l 的解,还返回该解中的步骤数 nsol(l) 。我们对于级别 l 的适应度函数可以像
适合度(l) =最小值(S,nsol(l))/最大值(S,nsol(l))
例如,如果 S 是 12,并且当前级别需要 7 步解,则该级别的适应度值是 7/12,或 0.583。请注意,在代码中,我们使用了稍微复杂一些的东西,因为我们在函数中添加了一个组件,使级别更加紧凑(占用更少的空间),但这通常可以忽略。
变化
假设我们有一个级别,下一个问题是,可以对它进行哪些非常小的改变,以便它可能走向更好的解决方案(或者,更有可能的是,成为该物种中无法解决、无法生存的成员)。在这里,我们可以随机改变 3 件事:一个角色的位置,一个房间的地板颜色或者一个房间的墙壁颜色。所以我们所做的是随机选择其中一个变化,并应用到随机的角色或细胞上。
生成人口 0
我们有适应性,我们有突变。为了完整,我们通常还会添加交叉,即混合成对的选定个体,以创建新的解决方案。我们把它留在这里有两个原因:简化一个已经很长的故事,因为我们的第一次测试没有交叉,结果很好。有了这两个元素,遗传算法的一般过程如下:
我还没有谈到的一点是第一步:生成初始群体。事实证明,创建一个可以生成随机但有效的级别的过程是最乏味的工作。给角色赋予随机的位置,给单元赋予随机的颜色,放置随机的墙壁,这些都不是问题,重要的是确保关卡“有意义”。字符应该放置在非空的单元格上,而不是一个在另一个的上面(或者在箱子的上面)。墙壁的放置应该确保你不会从水平面上掉下来,或者掉到一个空的房间里,等等。为了避免不必要的无聊的细节,让我们假设我们已经做了,所以对选择!
新一代的选择和创造
使用“轮盘赌选择”(或“健康比例选择”)为下一代选择个体。简而言之,这是一种在群体中“不完全随机”选择个体的方式,这样,一个健康状况是另一个健康状况两倍的个体被选中的可能性会增加一倍。换句话说,这是一种实现“适者生存”的方式,而不是像短语听起来那样二进制(应该是“适者生存概率最高”)。这就像投掷一个装满的骰子,只要群体中有多少个人,骰子每个面上的重量就与相应个人的适合度成比例。然后,我们选择骰子提示我们应该选择的人,不太适合的人可能不会继续下去,而真正适合的人可能会被选择不止一次。
既然我们已经选择了一个新的种群,我们只需要改变其中的一些。正如你现在可能已经意识到的,随机性是这个过程的一个重要部分,所以这就是我们再次做的:我们随机选择人口的一个子部分(其大小由突变率给出),我们对其应用上面描述的随机突变。
那么,这行得通吗?
就是这样。我们在一个有足够多个体的群体中运行了许多代的适应度、选择和突变,理论上,应该会发生一些事情。
但是什么?遗传算法最让我惊讶的是,如果你这样描述它,作为一个过程,完全随机的事情通过几乎随机选择的个体的“代”被完全随机地改变,它怎么可能给你除了随机结果之外的任何东西?
答案就在“几乎随机”中的“几乎”一词里:适应度驱动的选择概率。因为更健康的人更有可能前进,平均来说,每一代人都应该更健康。由于随机突变的发生,新种类的个体(“突变体”)出现,它们要么更适合(因此更有可能将突变传递给后代),要么不适合(因此更有可能因未被选择而消失)。
这就是它的美妙之处。你唯一需要的是知道如何识别某样东西是好的,它会让你最初随机的解决方案变得越来越好。最终的结果看起来像是已经设计好的,但是过程中没有关于如何设计好的解决方案的信息,只有关于什么是好的解决方案。看到这样的东西被创造出来是令人难以置信的兴奋,它看起来很聪明,看起来很有设计感,但它实际上只是在经过几代选择后才出现的突变。
当我们在 Elemaze 关卡中尝试这个魔法时,我们看到了吗?绝对的!
我们最初多次运行该过程,寻找 4x4 细胞的迷宫,每个溶液的理想步骤数为 9,群体为 30 个个体,突变率为 30%,极限为 100 代。因为解决这么多层次的问题需要时间,所以每次运行都需要几个小时(我们在多台计算机上多次运行)。自然,第一代并不是很有前途:大多数生成的关卡没有解决方案,有时,我们会有一个一步解决方案(即移动一个角色到胸部)。然而,在大多数过程中,它最终找到了需要 4 步甚至 5 步的层次。有几次跑到了 7 步,有几个人甚至在 8、9 和 10 步中找到了解决问题的方法。下图显示了一个有效的、可玩的 8 步关卡的最佳解决方案的步数。
遗传算法运行的每一代中求解级别的最大步骤数。
正如你所看到的,这符合预期:随着世代的进化,种群大多会变得更好。问题中的八步关卡是我们在游戏中测试的第一个关卡。看起来是这样的:
一个需要 8 个步骤来解决的关卡,是根据遗传算法生成的关卡创建的。
这可能不会给你留下深刻的印象,但我们花了几个小时试图找出如何为这个游戏制造关卡,以及如何构建它们,使它们具有足够的挑战性和趣味性。这个人工智能过程发明了一个关卡——实际上是几十个关卡——不仅可玩,而且复杂、有趣和困难。它唯一要做的事情是:“我们想要需要很多步骤才能解决的水平”。每次运行在笔记本电脑上(没有并行处理,所以只使用一个内核)几个小时内,从数百行 Python(使用 Python2.7 附带的模块)生成了不止一个有效级别(上面的一个也有有趣的 6 步、5 步,甚至 10 步级别)。
这种“智能”过程的优雅让我更感兴趣,尤其是如果你将它与需要多个 GPU 和数千个训练样本才能实现的东西相比较的话。正是这种优雅,也让它更适用,更易懂,更可教。Hugo 12 岁,在过去的几天里,我们一直在讨论什么样的人口规模是最好的,我们应该让这个过程运行多少代,我们的笔记本电脑应该根据其 CPU 的强度进行配置,等等。我们还分享了我们对水平如何发展的惊讶,当其中一个过程达到 7 步以上的水平时,我们会在屋子里大喊,并对测试它的想法充满了不耐烦。
我们的游戏结束了:你可以从 Google Play 或 itch.io 下载。其中 18 层是手工制作的。其他 34 个是由遗传算法设计的。你能认出他们是谁吗?
寻找股票交易最佳移动平均线的算法
一个简单的算法,为每只股票或 ETF 寻找最佳移动平均线
均线是股票交易中最常用的工具之一。许多交易者实际上只使用他们投资工具箱中的这个工具。让我们看看它们是什么,以及我们如何使用 Python 来微调它们的特性。
什么是均线?
在一个时间序列中,某一时刻 *t,*的周期 N 的移动平均是 t 之前的 N 个值的平均值(含)。它是为每个时刻定义的,不包括第一个 N 个时刻。在这种特殊情况下,我们谈论的是简单移动平均线(SMA ),因为平均线的每个点都具有相同的权重。有几种移动平均线以不同的方式衡量每一点,给最近的数据更多的权重。这就是指数移动平均线(EMA)或线性加权移动平均线(LWMA)的情况。
在交易中,用来计算平均值的先前时间序列观察值的数量称为*周期。*所以,周期为 20 的 SMA 表示最近 20 个周期的移动平均线。
具有 20 周期简单移动平均线的时间序列
如你所见,SMA 遵循时间序列,它有助于去除信号中的噪声,保留趋势的相关信息。
移动平均线常用于时间序列分析,例如 ARIMA 模型,一般来说,当我们想要将时间序列值与过去的平均值进行比较时。
均线在股票交易中是如何使用的?
移动平均线经常被用来检测趋势。很常见的假设是,如果股价高于其移动平均线,它可能会继续上升。
SMA 的周期越长,趋势的时间跨度越长。
脸书股票价格和不同的 SMAs
正如你所看到的,短均线对于捕捉短期运动很有用,而 200 周期的 SMA 能够检测长期趋势。
一般来说,交易中最常用的 SMA 周期有:
- 20 用于摇摆交易
- 中期交易 50
- 200 用于长期交易
交易员的一般经验是,如果股价高于 200 天移动平均线,趋势是看涨的(即价格上涨)。所以他们经常寻找价格高于 200 周期均线的股票。
如何选择 SMA 时期?
为了找到 SMA 的最佳周期,我们首先需要知道我们要在投资组合中持有该股票多长时间。如果我们是波段交易者,我们可能希望保持 5-10 个工作日。如果我们是仓位交易者,也许我们必须把这个门槛提高到 40-60 天。如果我们是投资组合交易者,在我们的股票筛选计划中使用移动平均线作为技术过滤器,也许我们可以专注于 200-300 天。
选择投资期限是交易者的自由选择。一旦我们确定了它,我们必须设法设置一个合适的 SMA 周期。我们见过 20 期,50 期,200 期,但都是好的吗?不完全是。
市场在这段时间变化很大,他们经常让交易者微调他们的指标和移动平均线,以便跟随波动爆发,黑天鹅等等。所以对于移动平均线周期并没有正确的选择,但是我们可以建立一个模型,它可以自我适应市场变化,自我调整,以便找到最佳的移动平均线周期。
最佳移动平均的算法
我这里提出的算法,是根据我们选择的投资期限,寻找最佳移动平均线的一种尝试。在我们选择这个周期后,我们将尝试不同的移动平均线长度,并找到最大化我们投资的预期回报的长度(即,如果我们在 100 买入,在选择的周期后价格上涨到 105,我们有 5%的回报)。
使用 N 天后的平均回报作为目标函数的原因非常简单:我们希望我们的移动平均线根据我们希望在投资组合中保留股票的时间为我们提供最好的趋势预测,因此我们希望在这样的时间内最大化我们投资的平均回报。
在实践中,我们将执行以下操作:
- 取我们股票几年的每日数据(例如 10 年)
- 将此数据集拆分为训练集和测试集
- 对训练集应用不同的移动平均线,对于每一个,当收盘价高于移动平均线时,计算 N 天后的平均回报值(本例中我们不考虑空头头寸)
- 选择最大化平均回报的均线长度
- 使用此移动平均值计算测试集的平均回报
- 验证测试集的平均回报与定型集的平均回报在统计上相似
最后一点是最重要的一点,因为它执行交叉验证,帮助我们避免优化阶段后的过度拟合。如果这个检查是满意的,我们可以使用我们找到的移动平均长度。
对于这个例子,我们将使用不同的股票和投资期限。平均值的统计显著性将使用韦尔奇检验来完成。
Python 中的一个例子
短期投资
首先,我们必须安装 yfinance 库。这对于下载股票数据非常有用。
!pip install yfinance
然后我们可以导入一些有用的包:
import yfinance
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import ttest_ind
让我们假设我们希望将标准普尔 500 指数的 SPY ETF 保留 2 天,并且我们希望分析 10 年的数据。
n_forward = 2
name = 'SPY'
start_date = "2010-01-01"
end_date = "2020-06-15"
现在我们可以下载我们的数据,并计算 2 天后的回报。
ticker = yfinance.Ticker(name)
data = ticker.history(interval="1d",start=start_date,end=end_date)
data['Forward Close'] = data['Close'].shift(-n_forward)data['Forward Return'] = (data['Forward Close'] - data['Close'])/data['Close']
现在,我们可以执行优化来搜索最佳移动平均线。我们将为跨越 20 周期移动平均线和 500 周期移动平均线的循环做一个*。对于每个时期,我们将数据集分为训练集和测试集,然后我们只查看收盘价高于 SMA 的那些日子,并计算远期回报。最后,我们将计算训练集和测试集中的平均前向回报,使用韦尔奇测试对它们进行比较。*
result = []
train_size = 0.6for sma_length in range(20,500):
data['SMA'] = data['Close'].rolling(sma_length).mean()
data['input'] = [int(x) for x in data['Close'] > data['SMA']]
df = data.dropna() training = df.head(int(train_size * df.shape[0]))
test = df.tail(int((1 - train_size) * df.shape[0]))
tr_returns = training[training['input'] == 1]['Forward Return']
test_returns = test[test['input'] == 1]['Forward Return'] mean_forward_return_training = tr_returns.mean()
mean_forward_return_test = test_returns.mean() pvalue = ttest_ind(tr_returns,test_returns,equal_var=False)[1]
result.append({
'sma_length':sma_length,
'training_forward_return': mean_forward_return_training,
'test_forward_return': mean_forward_return_test,
'p-value':pvalue
})
我们将通过训练平均未来回报对所有结果进行排序,以获得最佳移动平均。
result.sort(key = lambda x : -x['training_forward_return'])
得分最高的第一项是:
如您所见,p 值高于 5%,因此我们可以假设测试集中的平均回报率与训练集中的平均回报率相当,因此我们没有遭受过拟合。
让我们根据找到的最佳移动平均线(即 479 周期移动平均线)来看价格图。
很明显,价格通常高于 SMA。
长期投资
现在,让我们看看如果我们设置 n_forward = 40 (也就是说,我们保持我们的头寸开放 40 天)会发生什么。
最佳移动平均线会产生以下结果:
正如你所看到的,p 值低于 5%,所以我们可以假设训练阶段引入了某种过拟合,所以我们不能在现实世界中使用这种 SMA。另一个原因可能是,波动性变化太大,在让我们投资之前,市场需要稳定下来。
最后,让我们看看投资 40 天的黄金 ETF(股票代码:GLD)会发生什么。
p 值相当高,所以没有过度拟合。
最好的移动平均线周期是 136,我们可以在下面的图表中看到。
结论
在本文中,我们看到了一个简单的算法来寻找股票和 ETF 交易的最佳简单移动平均线。它可以很容易地应用于每个交易日,以便日复一日地找到最好的均线。这样,交易者可以很容易地适应市场变化和波动。
本文展示的所有计算都可以在 GitHub 上找到这里:https://GitHub . com/gianlucamalato/machine learning/blob/master/Find _ the _ best _ moving _ average . ipynb。
来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指南 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
新冠肺炎测试的算法方法
算法新冠肺炎测试
本文讨论了一种二分搜索法算法来测试印度潜在的新冠肺炎患者,以便有效地增加每天测试的患者数量。
印度有超过 13 亿人口,潜在冠状病毒携带者的数量每天都在呈指数增长。
照片由 Unsplash 上的 Fusion 医疗动画提供
问题是
随着每天潜在冠状病毒患者数量的增加,采用快速检测方法是当务之急,并且以经济的方式做到这一点极其重要。
该国正面临着检测试剂盒的巨大短缺,目前的情况是这样的-对于每一个潜在的携带者,都要进行一次测试,以测试该人对病毒是阴性还是阳性。这意味着,为了能够将 100 人中的每一个人归类为病毒阳性或阴性,我们最终要使用 100 个检测试剂盒。考虑到每天需要检测的患者数量远远高于可用的检测试剂盒数量,这种方法效率不高。
二分搜索法来了
这里有一个提议的二分搜索法算法,用不到 100 个测试套件测试 100 个人。
考虑一组 100 个被隔离的人,其中 5 人被感染(当前情况——在印度,每 100 个被检测的人中有 5 人检测为阳性)。
假设我们能够将 100 个人的样本混合成一个大样本(比如样本 X ),然后测试这个样本 X 的病毒。如果检测结果为阴性,我们可以宣布该群体中没有感染者。如果样本检测呈阳性,我们可以说这个群体中至少有一个感染者。
由于我们的示例假设有 5 名受感染的患者,因此样本 X 测试为阳性。
现在,我们将这一组 100 人分成两组,每组 50 人,测试样本 Y(第 1 组 50 人)和 Z(第 2 组 50 人)的病毒。如果样本测试呈阳性,我们会再次分解该组继续测试,如果测试呈阴性,我们会让该组退出,并宣布其为安全组。
该图帮助我们直观地了解了在一个 100 人的小组中检查每个人的病毒所需的测试次数。红色圆圈表示至少有一名感染者的群体,绿色圆圈表示健康和安全的个体群体。
将一组人分类为安全或不安全的二叉树。
在第 1 级,我们测试 1 组 100 人。在第 2 级,我们测试两组,每组 50 人。在第 3 级,我们测试 4 组,每组 25 个,对于随后的级别,我们只需测试最多 5 组仍然是红色的(因为假设总共只有 5 人被感染,所以在任何给定的级别,将显示被感染的确定性的组的最大数量是 5)。对于我们在每个级别测试的每个组,我们需要每个组一个测试套件。
对于每一个新级别的人,我们开始关闭包含受感染患者的群体,并开始消除不包含受感染患者的群体。
我们最多深入 7-8 层,才能在 100 人的群体中准确定位感染者。总共使用了多少套测试工具?
总结每一关使用的套件,1+2+4+5+5+5+5 =32。
我们只需要32 套装备。这与使用多达 100 套工具相比是一个巨大的退步。
结论
许多非程序员医生可能不知道这样的算法,如果我们当前的设备可以被修改以进行如上所述的池测试,它将使每天进行更多数量的测试成为可能。
德国的研究人员已经开始使用这种方法,并成功地大幅提高了检测新冠肺炎的能力。
一个业余数据科学家:通过业余爱好项目学习编程
木星不仅仅是一颗行星
我自己的“研究”项目帮助我对编程变得自信,并为下一个职业水平做准备。所涉及的工具和语言的概述。
完成了将近 32 个数据营章节后,我仍然不能称自己为数据科学家。在多次求职面试中,这一点变得很明显。虽然 DataCamp 和 Code Academy 似乎提供了很多编程实践,但我不会写任何特设的代码。这是个大问题。
开始一个爱好项目
我需要更多的练习。我查看了 DataCamp 建议的项目,但不知何故我不喜欢它们。其中一个 R 初学者的课程使用了国际电影数据库(被称为 IMDB)来解释描述性统计和基本的数据清洗。
因为我是一个电影迷,所以我从 IMDB 获得了行数据,并开始“摆弄”它,就像他们在 DataCamp 上所说的那样。
我心中没有特定的研究问题。但是我必须说,光是整理 IMDb 的数据就花费了大量的时间和精力。
实际上,每个用户都可以在 IMDB 上添加电影。然后给任何一部电影打分。这导致了很多不相关的条目,比如没人看的电影,或者几千集的同一部电视肥皂剧。
寻找你的数据集:Kaggle 和公司。
实际上,你有很多公开的数据集可供选择,比如来自经合组织或欧盟统计局的经济发展数据。
初学者的另一个大数据集来源是 Kaggle。这是一个在线平台,在这里你可以创建你的个人资料,并做你从其他社交网络中知道的所有事情:给喜欢,关注别人,如果有人喜欢你,你会感到高兴。
作为额外津贴,大公司在 Kaggle 上发布他们的数据,作为众多竞争的一部分,你要么赢得金钱,要么被公司雇用。
如果你的电脑无法平衡数据,你可能想免费使用 Kaggle 作为云计算服务。
从描述到关联
但是让我回到我的 IMDB 实验。一开始,我花了相当长的时间才停止犯“语法”错误。这只证明了我自学方法的效率。
只要我开始把所有的逗号和括号保持在适当的位置,而不是每次都咨询谷歌,编码就变得非常流畅和令人愉快。我可以更上一层楼。这个项目正从一团乱麻发展成有意义的东西。
我开始问研究问题。首先,非常描述性的。比如,哪种流派最有代表性?哪种流派得分最高?
很重要的是,我发现《肖申克的救赎》是有史以来最好的电影。
然后我转到了相关性的问题。该数据库于 1990 年启动(根据维基百科)。在那个日期之后发行的电影,尤其是在互联网接入成为我们生活的一部分之后,有更多的机会得分。
然而,这并不适用于所有的电影。例如,不是“肖申克的救赎”。它于 1994 年出版。
数据即更深入的见解
通过绘制数据和使用在线课程中的其他 dataviz 知识,我发现了更多的依赖性。例如,类型和评分之间的相关性,或者类型和年代之间的相关性。在 20 世纪 80 年代之前,你几乎不能把科幻小说作为一种严肃的电影类型来谈论。但在 2000 年后,这种类型爆炸了。
发现电影分数和制作年份之间的关系
箱线图给了我一些不太直观的结果。有趣的是,对于不同的流派,乐谱的含义是不同的。6 分的喜剧仍然是好的,而 6 分的戏剧很差,根本不值得看。
我的项目的可视化部分让我寻找我们在在线课程中没有涉及的新包。它还帮助我从归纳和总结开始。
电影配乐及其与流派的关系
永无止境的学习
两年后,我回到 IMDB 笔记。我经历了相同的数据清理和绘图过程,但这次用 Python 编写了代码。我也换了 Jupyter 笔记本。
我还使用 GitHub 目录来跟踪和备份脚本中的更改。我这样做更多的是为了熟悉平台以及分支和合并的概念。然后我的项目迁移到了 Jupyter,GitHub 和 Kaggle 都被放弃了。我发现在 Jupyter 中通过简单的复制粘贴来跟踪变更更容易,而且它足够快,可以将所有版本的代码保存在一个工作区中,而不会让您的 PC 喘不过气来。
超越数据科学
最后但同样重要的是,这个(正在进行的)项目帮助我了解了 API 调用。
有一天,我更仔细地阅读了 IMDB 版权指南。它表示,数据处理的结果不允许交给任何第三方,只能私人使用。
出于这个原因,我开始寻找一些其他实质性的电影数据库。我看到了电影《DB》。它只允许 API 调用,不允许 IMDB 提供的 CSV 下载。除了标准的 API 包,我更接近了神秘的 JSON 格式。
我还不得不再次编写我的数据清理脚本。有时候我收到的数据对我来说毫无意义。不是因为语法错误,而是因为我要么发送了一个不太详细的请求,要么没有从 JSON 中获得正确的数据。
除了编码本身,我在这里学到了两个教训。首先,总是准确地检查 JSON 结构。缺少一个级别使我无法获得我需要的全部数据。第二,也是相当平庸的,总是仔细通读文档。
旧数据,新角度
最后,我的 IMDB 项目如此有趣,以至于我决定做更多。我润色了一下我的研究问题,变成了下面这个:
“与同类型的其他电影相比,被查询电影的评分有多高?”
《泰坦尼克号》( 1997)的配乐及其在戏剧类型中的地位
作为一个解决方案,我获得了一部电影的数据,包括电影类型,然后查询该类型的所有电影,然后构建一个方框图,将描述性统计数据显示为一个方框图,其中一部电影被标记为星号。
这应该有助于评估这部电影的真实价值。它对分数进行了加权,并给出了类似电影分数的实际范围,而不仅仅是它在抽象的 1-10 范围内的位置。
当我完成数据清理和描述部分后,我非常兴奋,我决定编写一个小的 one function Python 应用程序来查询电影标题,然后以按钮的形式显示出来。然后,用户可以按一个按钮来获得电影的方框图。但这是后话。
结论
在这期间,我学会了流利地编写 R 和 Python 代码,无需检查任何语法或函数的源代码。流畅性对于保持编程流程非常重要。
如果你在工作面试时有一个技能测试,这也是非常有帮助的。
综上所述,如果你想更接近你的数据科学梦想,但你目前的工作并没有给你提供很多实践机会,你可以遵循以下步骤:
- 完成在线课程
- 找到一个具有足够数量一致数据的数据集
- 使用开源工具和语言进行一些实践
- 在数据科学社区中发布您的结果
- 把它作为你的作品集
- 开始写你的数据科学工作申请。
祝你好运!
典型工作日的音乐收听分析
使用 Python 和 Spotify API 探索音乐属性如何在一天中演变
斯蒂芬·尼梅尔通过像素拍摄的照片
音乐是语言的一种形式
我每天醒着的时候有超过 60%的时间在听音乐。我早上一醒来就放一个播放列表。当我早餐煮鸡蛋时,当我上下班时,当我全神贯注于工作时,当我试图用跑步代替健身房锻炼时,我都会听音乐。我花更多的时间选择和排队我想在淋浴时听的歌曲,而不是真正淋浴。可以肯定地说,我的音乐流媒体游戏比我的疯狂观看游戏更强。
如此多的音乐让我思考:我们听的音乐类型取决于一天中的时间吗?如果有,如何量化?一天中的音乐是否讲述了一个准确反映这一天的故事?
这一分析是试图找到上述问题的答案。
方法和数据收集
出于分析的目的,我将一个工作日分为以下几个部分。假设在这些部分中的每一部分播放的音乐具有不同的属性。
- 早晨
- 练习
- 工作
- 晚上
- 烹饪
- 主餐
- 夜晚
- 睡眠
Spotify 忠实于其出色的广告,其口号是适合每种情绪的音乐,Spotify 有几个全天服务的播放列表。对于上面的每个部分,我只是搜索了那个关键词( morning 代表 morning),并根据每个部分的点赞数整理了 Spotify 创建的前五个播放列表(不包括用户生成的播放列表)。对于每个播放列表,我使用播放列表 ID 获取曲目 ID,然后使用曲目 ID 从 Spotify 的 API 获取音频特性。
Spotify 开发者 API 为单首曲目提供了以下有趣的功能。
- Acousticness: 从 0.0 到 1.0 的音轨是否声学的置信度度量。1.0 表示音轨是声学的高置信度。
- **可跳舞性:**根据音乐元素的组合,包括速度、节奏稳定性、节拍强度和整体规律性,描述一首曲目适合跳舞的程度。值 0.0 最不适合跳舞,1.0 最适合跳舞。
- **能量:**从 0.0 到 1.0 的度量,代表强度和活动的感知度量。通常,高能轨道感觉起来很快,很响,很嘈杂。
- **乐器性:**预测音轨是否不包含人声。乐器度值越接近 1.0,轨道不包含人声内容的可能性就越大。
- **语音:**检测音轨中是否存在语音。高于 0.66 的值描述可能完全由口语单词组成的轨道。介于 0.33 和 0.66 之间的值描述可能包含音乐和语音的轨道,可以是分段的,也可以是分层的,包括说唱音乐。
- **效价:**从 0.0 到 1.0 的一个量度,描述一个音轨所传达的音乐积极性。高价曲目听起来更积极(例如,快乐、愉快、欣快),而低价曲目听起来更消极(例如,悲伤、沮丧、愤怒)。
更多的特性,每个特性的详细定义和分布可以在这个链接中找到,上面的定义都是从这里剪裁、复制和粘贴的。
使用 API 的 Python 实现spot ipy,我检索了之前选择的 40 个播放列表的所有歌曲的音频特征。
雷达图是很棒的工具!
这里的想法是查看(I)音乐属性在一天中的任何时间如何相互比较,以及(ii)它们在一天中如何变化。最简单的显示方式通常是时间序列图,但是有这么多的属性,这是不可理解的。下一个逻辑选项是为不同的属性绘制一个时间序列图表网格,但是它不允许我将不同的属性彼此并列。
我决定把重点放在上面的(I)上,并绘制了一个雷达图的网格,这是一个可视化多元数据的好方法。下面显示了六个变量,每个变量的值在 0 到 1 之间。对于网格中的每个单独的图表,针对每个特征绘制的值是一天中相应时间的前五个所选播放列表中所有歌曲的该特征的平均值。
在本文的其余部分,让我们假设存在一个人,比如说乔*,他拥有如下图所示的平均音乐属性。*
乔的一天看起来怎么样?
早晨:(希望)睡了一夜好觉后,乔醒来听着欢快的原声(0.43)歌曲。他的能量(0.52)还不是最高的,但他仍然在跳舞(0.59),同时梳洗打扮,准备进行大强度的锻炼。
播放列表:晨间音响、晨间漫步、晨间通勤、晨间动力、清晨之巅
***锻炼:*乔以早晨的快乐状态(0.45)继续他的一天,并达到一天中的最高能量水平(0.77)。他毫不犹豫地释放内心的兽性,全力以赴,让他在接下来的一天里充满活力。
播放列表:野兽模式、混合动力、健身程序、力量健身程序、有氧运动
***工作:*在工作时,乔戴上耳机,进入一种的心流状态听着高度声学(0.76)和器乐(0.85)的音乐。
播放列表:健脑食品、深度聚焦、专注音乐、完美专注、Workday Lounge
***晚上:*在漫长而辛苦的一天工作之后,乔听着音乐(0.71),每听一首,他的头可能会摆动一次(0.52),同时决定他是想叫外卖还是做饭。
播放列表:晚间原声、晚间酷乐、晚间通勤、晚间爵士、晚间音乐
***烹饪:*乔决定穿上围裙,他对自己的决定非常满意(0.65)。他喜欢精力充沛地(0.52)切蔬菜,并在锅里翻动它们。
播放列表:厨房霸气,你的厨房音响,蓝调厨房,用灵魂烹饪,用摇摆烹饪
***晚餐:*晚餐准备好了!Joe 仍然骑在来自烹饪的能量(0.42)波上,并且继续听类似的音乐。
播放列表:与朋友共进晚餐、晚餐音乐、感觉良好晚餐、爵士晚餐、晚餐休息室
夜晚 : 在一顿有益健康的晚餐后,是时候改变一下风格,听一些充满能量(0.49)的器乐(0.38)和原声(0.45)音乐了。
播放列表:深夜爵士乐、夜骑士、深夜音乐、Spotify & Chill、午夜时光
睡眠:乔觉得这一天永远不会结束。他穿上睡衣,带着计时器上床睡觉,30 分钟后停止音乐,放一些平和的低能量(0.22)、高声(0.72)和器乐(0.89)的音乐。
播放列表:睡眠、夜雨、睡眠爵士乐、自然噪音、梦幻氛围
乔不喜欢说唱吗?
乔所有音乐的平均语速是 0.065,根据以下分布,Spotify 上的大多数音乐都是如此。所以可以说乔对说唱音乐不感冒。
Spotify 上所有歌曲的语音功能分布
属性相关吗?
为了绘制下面的相关性矩阵,我考虑了为该分析选择的 40 个播放列表中的所有 3,519 首歌曲。
相关矩阵
- 快乐的歌是可以跳舞的歌;0.63 的正相关
- 原声歌曲一点也没有活力;负相关 0.8
- 器乐歌曲并不总是积极向上的;负相关 0.56
与乔的音乐日相比,我的音乐日看起来如何?
虽然我在一天的每个时段都没有不同的播放列表,但我有一堆反复播放的播放列表。为了进行比较,我尝试将播放列表与本次讨论中考虑的一天中的部分时间对齐。
- 我以比乔更低的能量(0.33)开始了我的一天,听着来自 Lo-Fi Beats 的高度器乐化(0.74)的歌曲。
- 我的锻炼,这是不存在的往往不是,或多或少类似于乔的。我听 MKBHD 视频,里面有我最喜欢的 YouTubeMKBHD之一的视频介绍中使用的歌曲。
- 我工作中的心流状态,自带高能(0.64)器乐(0.78)歌曲。我喜欢坐在椅子上从一张桌子转到另一张桌子,耳机里放着低调的科技音乐。
- 我的晚间播放列表 Ultimate Indie 类似于我的锻炼播放列表,充满了积极(0.55)和活力(0.61)。
- 我不经常做饭,但当我做的时候,我会即兴演奏传奇吉他独奏。顾名思义,声音(0.13)和能量(0.72)的空间很小。
绿线代表我的播放列表,橙色线代表乔的播放列表。
- 晚餐时,我通常是网飞,但有时我喜欢调暗灯光,坐在餐桌旁而不是沙发上,享受一顿美好而深情的晚餐。乔的晚餐播放列表和我的几乎相似,除了乔喜欢在他的歌曲中多一点乐器感(0.21)。
- 晚上,我喜欢到阳台上看星星和云,进行一场充满活力的(0.71)表演,让自己放松。不像乔的夜晚播放列表,房子音乐有更高的乐器性(0.77)。
- 在探索了一整天的新音乐后,我回到了过去一年中我听过的一些最喜欢的歌曲。看起来我的能量(0.74)一整天都很高,甚至当我想睡觉的时候。
结论
在 Spotify 的音频功能的帮助下,我能够量化不同的歌曲,并为一个人的日常音乐之旅整理出一个故事。我看到使用雷达图作为比较工具,我一整天都在听很多充满活力的音乐。
巧的是,朋友们也经常说我是个活泼的人。活泼和我的其他性格特征会影响我听的音乐和最终添加到我的播放列表中的内容吗?或许,有了丰富的数据在手,就有可能根据一个人的播放列表来预测他的情绪和性格。我猜是改天的项目。
所有代码都可以在 Github 上获得。如有任何问题、建议或反馈,请通过 LinkedIn 联系我。
参考
- 雷达图
https://python-graph-gallery . com/392-use-faceting-for-radar-chart/ - Spotify 开发者 APIhttps://Developer . Spotify . com/documentation/we b-API/reference/tracks/get-audio-features/
美国警察致命枪击案分析
2015 年至 2020 年间的致命警察枪击事件。
《华盛顿邮报》发布了一份包含 2015 年至 2020 年间美国警察致命枪击案的数据集。在关于种族主义的讨论中,这个数据集可能有助于了解当前的情况。
我们将使用数据分析工具和技术来揭示一些概括数据集的数字。这篇文章旨在成为数据分析的实用指南,并从多个角度讨论美国警察枪击事件。
华盛顿邮报的这份报告提供了该数据集。我将使用 python 数据分析和可视化库。让我们从导入这些库开始。
# Data analysis
import numpy as np
import pandas as pd# Data visualization
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style='darkgrid')
%matplotlib inline
我们现在可以将数据集读入熊猫数据帧。
df = pd.read_csv("/content/fatal_police_shootings.csv")print("Dataset has {}".format(df.shape[0]),
"rows and {}".format(df.shape[1]), "columns")
每一行代表一次枪击事件,而每一列给出了枪击事件的详细信息。让我们看看这 14 列中有什么样的数据。
这些名字过于个人化,不能使用,可能会侵犯个人权利。id 列是多余的。因此,我将删除这些列。
df.drop(['id','name'], axis=1, inplace=True)
剩余的 12 列是:
我们有关于被枪击者、枪击地点和枪击行为本身的数据。下一步是检查缺失值并处理它们。
缺失值
df.isna().sum()
“武装”、“年龄”、“性别”、“种族”和“逃离”列缺少值。missingno library 提供的缺失值矩阵是一个关于缺失值的更具信息性的工具。它给出了数据帧中缺失值分布的概念。
import missingno as msnomsno.matrix(df)
“性别”和“种族”列上的缺失值似乎在某种程度上重叠(即它们可能在同一行)。我们可以检查缺失值的热图来确认:
msno.heatmap(df, figsize=(10,6))
“种族”和“年龄”列中缺少的值是相关的。
“逃离”和“武装”栏描述了被枪击者的行为。
df.flee.value_counts()
“不逃”的动作支配着“逃”栏。我们可以用“不逃”来填补缺失的值。请注意,这不是处理缺失值的严格规则。您可以选择不同的方式来处理它们(例如,丢弃它们)。
df.flee.fillna('Not fleeing', inplace=True)
让我们检查“武装”一栏。
df.armed.value_counts()
“Gun”是最常见的值,因此我将使用它来填充缺失的值。我们可以使用从 value_counts 函数返回的序列的索引:
df.armed.fillna(df.armed.value_counts().index[0], inplace=True)
我将删除“种族”、“年龄”和“性别”列中缺少值的行,因为它们描述了被枪击的人,因此在没有准确信息的情况下做出假设可能会产生误导。
df.dropna(axis=0, how='any', inplace=True)print("There are {}".format(df.isna().sum().sum()), "missing values left in the dataframe")There are 0 missing values left in the dataframe
数据帧没有任何缺失值。
数据类型
数据类型在数据分析过程中非常重要,因为它们决定了如何处理某些操作和计算。
分类变量可以用“对象”或“类别”数据类型来表示。年龄可以用“整数”或“浮点”数据类型表示,真/假数据类型用“布尔”处理。除了日期列之外,所有的数据类型似乎都合适。
我将把它转换成 datetime,这是 pandas 处理日期的数据类型。转换后,我将从日期中提取“年”和“月”,并创建新列。我们可以用它们来查看年或月的投篮命中率。
df['date'] = pd.to_datetime(df['date'])
df['year'] = pd.to_datetime(df['date']).dt.year
df['month'] = pd.to_datetime(df['date']).dt.month
【2015 年至 2020 年
我们来看看 2015 年到 2020 年每天的枪击案数量有没有持续上升或者下降的趋势。
一种方法是分组日期和每天拍摄的次数。
df_date = df[['date','armed']].groupby('date').count().sort_values(by='date')
df_date.rename(columns={'armed':'count'}, inplace=True)
df_date.head()
“武装”列是随机选择的,只是为了计算每天的行数。我们现在可以创建一个时间序列图。
plt.figure(figsize=(12,6))
plt.title('Daily Fatal Shootings', fontsize=15)
sns.lineplot(x=df_date.index, y='count', data=df_date)
这说明不了什么。如果我们绘制 10 日平均线,效果会更好。
df_date.resample('10D').mean().plot(figsize=(12,6))
plt.title('Fatal Shootings - 10 day average', fontsize=15)
我们可以观察到一些峰值,但没有连续的趋势。
地点和年代
让我们来看看数字在不同的状态下是如何变化的。我将使用侧表,这是熊猫实用程序库。它就像是 value_counts 的高级版本。
!pip install sidetable
import sidetabledf.stb.freq(['state'], thresh=50)
加州发生了 684 起致命枪击事件,约占所有枪击事件的 14%。枪击事件总数排名前 3 的州是加利福尼亚州、德克萨斯州和佛罗里达州。当考虑到各州的人口时,这并不奇怪。
我认为“年龄”是一个重要的考虑因素。可以根据不同的年龄组设计预防措施。
plt.figure(figsize=(12,8))
plt.title('Age Distribution of Deaths', fontsize=15)
sns.distplot(df.age)
大多数被枪杀的人都不到 40 岁。每个人的生命都同样重要,但当一个年轻人死去时,对家庭来说就更难了。
种族
种族主义是人类历史上最严重的疾病。它比冠状病毒或人们一直与之斗争的任何其他流行病都更危险。不幸的是,不同种族的致命枪击数量有所不同。
我们将首先创建一个新的 dataframe,其中包含每个种族每年的射击次数。数据集由 6 个不同的种族组成,它们是:
df_race = df[['race','year','armed']].groupby(['race','year']).count().reset_index()df_race.rename(columns={'armed':'number_of_deaths'}, inplace=True)
df_race.head()
只有死亡人数不能告诉我们太多,因为这些种族在人口方面没有按比例代表。因此,我将使用每 100 万人的死亡人数作为基线。
我将使用 2019 年的人口数据,这些数据可以在美国人口普查网站上找到。尽管从 2015 年到 2020 年,这一比例有所变化,但并不像 10-15%那样剧烈。我认为比率保持在几个百分点的范围内。但是,您可以使用每年的确切人口数来提高准确性。
df_pop = pd.DataFrame({'race':['W','B','A','H','N','O'],
'population':[0.601, 0.134, 0.059, 0.185, 0.013, 0.008]})df_pop['population'] = df_pop['population']*328
df_pop
人口栏代表每个种族的人口,以百万计。我们现在可以合并 df_race 和 df_pop 数据帧。
df_race = pd.merge(df_race, df_pop, on='race')
df_race['deaths_per_million'] = df_race['number_of_deaths'] / df_race['population']df_race.head()
我们可以创建一个柱状图,显示从 2015 年到 2020 年每场比赛中警察枪击的百万分之死亡人数。
plt.figure(figsize=(12,8))
plt.title("Fatal Shootings by Police", fontsize=15)
sns.barplot(x='year', y='deaths_per_million', hue='race', data=df_race )
黑人(B)的比率明显高于其他种族。土著人(N)和其他人(O)人口很少,所以更合理的比较应该是在黑人(B)、白人(W)、西班牙人(H)和亚洲人(A)种族之间。
每百万人死亡的总比率:
如果黑人的百万分之死亡率是西班牙人的两倍。黑人(B)和白人(W)的差别就更大了。
最后的想法
种族主义是我们甚至不应该讨论的东西。不应该存在。当一个孩子听到“种族主义”这个词时,他的反应应该是“这是什么意思?”。世界上任何地方的任何类型的种族主义都需要消失。遗憾的是,现在的世界并非如此。但是,我们可以用一种方式教育我们的孩子,让“种族主义”这个词不复存在。
感谢您的阅读。如果你有反馈,请告诉我。
参考文献
- https://github.com/washingtonpost/data-police-shootings
- https://www.census.gov/quickfacts/fact/table/US/PST045219
一种利用人工智能检测 DDoS 攻击的方法
这是一个研究实验,解释了如何利用机器学习以及数据科学的不同方面来检测 DDoS 攻击。
摘要
DDoS 攻击是互联网上最强大的黑客技术之一。黑客在这些类型的攻击中使用的基本武器是网络流量,用来关闭或瘫痪网站。这种攻击有各种子类别,每一个类别都定义了黑客试图入侵网络的方式。在这项研究中,我们讨论了一种通过人工智能模型检测 DDoS 攻击威胁的方法,准确率超过 96%。我们将 DDoS 威胁以及安全或健康的网络分为 7 个不同的子类别。
简介
分布式拒绝服务(DDoS)攻击的目标是网站和在线服务。这种攻击的目的是用压倒性的流量堵塞网络或服务器。它通过利用多个受损系统作为攻击流量的来源来实现有效性。相对于 OSI 模型,根据 DDoS 攻击试图攻击的网络连接层,DDoS 攻击有不同的子类别。我们通过研究划分的一些子类别有 SYN Flood、UDP Flood、MSSQL、LDAP、Portmap、NetBIOS。
机器学习和深度学习是迄今为止人工智能最常见的支柱之一。我们使用这些方法来解决不同领域的问题,精确度接近人类的表现。通过这项研究,我们再次测试了人工智能在检测网络安全领域的威胁方面的极限。在这项研究中,我们对 DDoS 攻击期间生成的日志进行了彻底的分析,使用监督和非监督技术来检测威胁,并最终使用深度学习来实现不同类型 DDOS 威胁分类的 96%以上的准确率以及安全连接。
数据预处理
处理数据是我们面临的首要挑战之一。这些数据有 88 个属性或特征。在有限的 RAM 内存中处理如此庞大的数据对我们来说确实是一项具有挑战性的任务。因此,我们降低了属性的数据类型,从而减少了数据帧的内存使用。float64 的数据类型降级为 float32,int64 降级为 int32,int32 降级为 uint32,依此类推。我们成功地将初始大小减少了将近 42%。我们的数据框仍然具有最大值接近无穷大的属性或要素,因此我们也在预处理阶段处理这些数据。
目标特征分布
图片由 Victor Basu 用 Matplotlib 绘制
可以看出,我们试图保持目标特征与数据集的均匀分布。
尽管 UDPLag 相对于其他的分布有点不均匀,但我们仍然在研究的后期处理了这个案例。
探索性数据分析
图像由维克多·巴苏与西博恩一起绘制
维克多·巴苏与海博恩一起绘制的图片
在上述两个分析中,我们可以清楚地观察到,与良性或安全连接相比,DDoS 攻击期间的比特流和分组流存在漂移。
维克多·巴苏与西博恩一起绘制的图片
维克多·巴苏与海博恩一起绘制的图像
我们还分析了每种类型的威胁在每种类型的协议和入站中的分布。下面是显示分析的图表。
维克多·巴苏与西博恩一起绘制的图像
维克多·巴苏与西博恩一起绘制的图像
维克多·巴苏与西博恩一起绘制的图像
维克多·巴苏与西博恩一起绘制的图片
维克多·巴苏与西博恩密谋的图像
图像由维克托·巴苏与西伯恩一起绘制
威胁检测的无监督方法
在无监督的方法中,我们不让我们的模型通过目标变量学习,而是迫使我们的算法从输入数据本身学习,并自己发现模式和信息。
训练前的预处理。我们已经从数据中删除了一些功能,如流 ID、源 IP、源端口、目的 IP、目的端口、时间戳、流数据包、流字节。“流量门襟/秒”和“流量字节/秒”已被删除,因为在标准缩放后,这些功能转换为对于 float64 和 NaN 值来说太大的值。
我们通过标准缩放来缩放数据,然后进行归一化。利用主成分分析进行降维,将维度降维为二维数据。
图片由 Victor Basu 用 Matplotlib 绘制
图片由维克多·巴苏用 Matplotlib 绘制
因此,从上面的两个可视化中,可以清楚地观察到,我们的算法可以在一定程度上成功地从数据中聚类出不同的威胁。
让我们看看我们的无监督模型如何标记生成的聚类。
图片由维克多·巴苏用 Matplotlib 绘制
嗯,看起来我们的无监督模型已经成功地找到了数据中的模式,并可以在某种程度上单独分割出我们的目标变量。
注意— 无监督学习为您提供了关于数据形状和结构的详细分析见解。当数据的形状和结构改变时,来自数据的无监督聚类和目标标签预测会改变,因为它不知道目标数据可能是什么。没有办法确定它们有多准确,这使得有监督的机器学习更适用于现实世界的问题。这也是无监督训练模型不适合在生产中部署的原因之一。
检测威胁的监督方法
这与无监督方法正好相反,这里我们让我们的模型通过目标变量学习,这进一步帮助我们的模型通过目标标签从数据中学习模式。我们应用了与无监督方法相同的数据预处理。在这种情况下,我们已经使用深度学习来训练我们的模型。
我们 DL 模型的结构
图片由 Victor Basu 提供,截图来自 Jupyter 笔记本,同时运行 tensorboard
由于我们的目标变量是不平衡,所以我们使用分层 K 折叠来训练和验证每个折叠的数据。它相对于期望的不平衡特征来平衡训练和验证的分布。
我们使用 Adam 作为我们的基本优化器和 ROC_AUC 分数来评估模型的性能。ROC_AUC 得分根据预测得分计算受试者工作特征曲线下的面积(ROC AUC)。
我们已经对我们的模型进行了 10 次以上的训练和验证,并且我们已经获得了超过威胁检测平均值 96%的 ROC_AUC 分数,并且获得了 97%以上的最高准确度。
图片由 Victor Basu 提供,截图取自 Jupyter 笔记本,同时运行 tensorboard
图片由 Victor Basu 提供,截图来自 Jupyter 笔记本,当时正在运行 tensorboard
10 折之一的分类报告
图片由 Victor Basu 提供,截图取自 Ms-Excel
从 10 个折叠中的一个分类每个类别的准确度
图片由 Victor Basu 提供,截图取自 Ms-Excel
结论
即使与现实生活中的未标记数据相比,您只有非常少的标记数据,也有像半监督学习和自监督学习这样的技术来实现显著的性能。
模型公平性指标也是 TensorFlow 工具之一,可用于更好的模型评估和性能扩展。
使用的工具和数据集
新不伦瑞克大学提供了这个数据集。
TensorFlow、Scikit Learn、Matplotlib、Seaborn,以获取整个研究中使用的工具。
商品价格预测中 ARIMA 模型和 NNAR 模型的比较
本文对两种广泛使用的预测商品价格的机器学习模型进行了全面的比较。
D.库拉大学数学学科
凯文·Ku 在 Unsplash 上的照片
简介:
一个可靠的预测模型,预测我们日常生活中最常用的两种商品价格的未来情景:小麦(零售)和大米(粗粮)。本研究采用季节自回归移动平均(ARIMA)和神经网络自回归(NNAR)对商品价格涨跌的时间序列特征进行了分析。容格盒检验证实,这两个模型都有很好的拟合和预测性能,NNAR 模型比 ARIMA 模型拟合得更好,因为 NNAR 模型的 p 值远高于 ARIMA 模型。RMSE、MAPE、MAE 和 MASE 值足够低,表明这两个模型都能够给出良好的预测,但相对而言,NNAR 模型显示的值低于 ARIMA 模型。NNAR 模型再次显示出比 ARIMA 模型更好的预测性能。在 NNAR 模型中,R 平方值为 0.98,而在 ARIMA 模型中,两种情况下的 R 平方值均为 0.95。手动计算这个值需要相当大的训练集。因此,基于所有这些测试,NNAR 模型适用于上述序列的预测任务。
在孟加拉国,小麦和大米是两种最常用的商品。近年来,这些商品的价格变化非常神秘,很难预测未来几年将会发生什么,因为天气变化和全球疫情袭击可能会对价格变化产生巨大影响。在本研究中,价格变化的未来行为是根据以前的行为预测的。一些有用的预测方法用来通过做时间序列分析来预测未来的状态。这些方法从可用的观察中分析模式,并对未来的结果做出很好的预测。
自回归移动平均(ARIMA)是由电气工程师在 20 世纪 30-40 年代发展起来的一种时间滤波方法。20 世纪 70 年代后期,两位统计学家乔治·博克斯和格温里姆·詹金斯开发了一种系统的方法,将它们应用于商业和经济数据。该模型假设时间序列是由一个线性过程产生的。但是在现实世界中,系统通常是非线性的。人工神经网络(ANN)是一种能够分析输入变量和响应之间这种非线性关系的技术。神经网络自回归(NNAR)是一种人工神经网络,其中时间序列的滞后值可以用作神经网络的输入。
在这项研究中,ARIMA 和 NNAR 被用来预测价格变化的未来行为。在本研究中,使用这两种模型进行了长期预测(根据现有数据,未来 36 个月)。在本研究中,小麦(零售)和大米—粗粮(零售)被纳入测试范围。
数据收集:
数据从互联网(data.humdata.org)收集,并在拟合模型前进行分析和重新排列。商品的价格因站而异。就像达卡市某一天 1 公斤小麦的零售价格不会和库尔纳市一样。这项研究的目的不是预测每个电视台的价格,而是预测全国的价格。为了解决这个问题,考虑了每个月商品的中间价格。
分析:
a)选择 ARIMA:
小麦和水稻的 ACF 图和 PACF 图分别如图所示。在这两种情况下,我们看到对 ACF 和 PACF 的几何影响,这表明选择 ARIMA 模型。
ACF 和 PACF 的大米和大米时间序列
b)平稳性:
首先对大米和小麦数据进行测试,以检查时间序列数据是否平稳。为了做到这一点,我们分解了水稻和小麦的时间序列数据。正如我们从这两个图中看到的,右边的条形很小,这意味着价格成分以很小的平均值变化。因此,这对全球并不重要。
图中的季节性成分表明时间序列包含季节性行为,并保证随机成分对季节性行为有显著影响。因此,时间序列的平稳性被图形拒绝。为了得到更多的证实,我们对两个数据集都进行了增强的 Dickey Fuller (ADF)测试。结果如图 4 所示。从结果中我们可以看到 p 值高于 0.05,这意味着我们不能拒绝 ADF 检验的零假设。这个测试证实了我们的两个时间序列数据都不是平稳的。
分解大米和小麦时间序列
ADF 测试的结果
c)型号选择:
在平稳性检验确定后,我们不得不选择具有季节成分的 ARIMA 模型,即 SARIMA 模型。对不同阶次和季节的 SARIMA 模型进行了研究,最终根据最低的 AIC、AICc 和 BIC 值分别选择 SARIMA(1,1,3)(1,1,1)[12]和 SARIMA(3,1,3)(1,1,1)[12]作为小麦和水稻的数据。
根据最小 sigma 平方值和 RMSE 分别为小麦和水稻选择 NNAR(5,1,10)[12]和 NNAR(3,1,10)[12]。
模型验证:
Ljung-Box 测试已经在所有训练数据集上执行,以验证它们的性能。每个模型都给出了大于 0.05 的 p 值,以确保残留物呈正态分布,并且不会影响拟合。因此,通过容格检验可以降低数据过拟合的可能性。两个模型都测试了 TSCV。
箱式测试的结果
预测方法:
a) ARIMA:
在 ARIMA 模型中,通过应用数据点的有限差分,使非平稳时间序列变得平稳。使用 ARIMA(p,d,q)的标准符号,其中参数用整数值代替,以指示要使用的特定 ARIMA 模型。这里,p =滞后阶,d =差分阶,q =移动平均的阶。这个模型的过程说任何时间序列都可以用下面的等式来描述,
i)季节性 ARIMA:
季节性 ARIMA 模型是通过在 ARIMA 模型中引入一个附加项而形成的。它由 ARIMA(p,D,q) (P,D,Q)[m]描述,其中部分(P,D,Q)[m]描述季节性部分。ARIMA(1,1,1)(1,1,1)[4]被定义为
b) NNAR:
神经网络用于复杂的非线性预测。NNAR 通常用 NNAR (p,k)来描述,其中 p =滞后输入,k =隐藏层数。NNAR(p,P,k)是季节性 NNAR 的一般表示。
NNAR 模型是一个前馈神经网络,它包括一个线性组合函数和一个激活函数。这些函数的形式被定义为,
a)萨里玛:
SARIMA(1,1,3)(1,1,1)[12]和 SARIMA(3,1,3)(1,1,1)[12]模型分别应用于小麦和水稻数据,并给出以下图表:
用 ARIMA 模型预测价格
残差分布图显示残差呈正态分布,这证实了该模型不存在过拟合问题。
ARIMA 模型的残差
b) NNAR:
NNAR(5,1,10)[12]和 NNAR(3,1,10)[12]分别应用了小麦和水稻数据,并提供了以下图表:
用 NNAR 模型预测价格
残差分布图显示残差呈正态分布,这证实了该模型不存在过拟合问题。
NNAR 模型的残差
精度评价方法:
评估准确度最常用的方法有 RMSE 法、MAE 法、MAPE 法和 MASE 法。这些方法的一般公式是:
精度测量:
这两种方法的预测能力可以通过 ME、RMSE、MAE、MPE、MAPE 和 MASE 等指标进行比较。对于两个不同的时间序列,结果如下表所示:
拟合模型上小麦时间序列的精度度量
水稻时间序列在拟合模型上的精度度量
如表所示,在这两种情况下,NNAR 方法与 ARIMA 相比显示出非常好的度量,因为所有值都低得多。
结论:
根据上述研究,近期商品(小麦和大米(粗粮))的价格正在上涨,这可能是孟加拉国经济状况的一个警示信号,因为这两种商品是孟加拉国最常用的商品。
在这项研究中,对 NNAR 和 ARIMA 两个模型进行了测试和比较,其中 NNAR 在 R 平方统计的预测能力和预测能力方面都表现出了更好的性能。在预报过程中,NNAR 模式的误差比 ARIMA 模式低得多。
其他故事:
3)R 市场份额预测
跨越各种神经网络的架构之旅,对应于分子生物学建模中的十个革命性挑战
利用神经网络架构的能力解决生命科学问题
受自然启发的建筑人造奇迹。意大利圣彼得广场。@ Pexels
作为一名数据科学家,有没有人问过你:“深度学习是模仿大脑吗?”此时,你可能会脸红,因为你不知道该怎么回应。嗯,没有错误的问题,但肯定有不好的答案*……本博客试图通过对为什么在被称为分子生物学的惊人领域使用各种神经网络 (NN)模型的问题给予直觉来阐明一个答案。这些微型分子很少见到(也许它们生活在它们神秘世界的边缘:-);然而,它们完全构成了我们的存在,存在于地球上任何生物的每一个细胞中。正如标题所暗示的那样,*
在这次演讲中,我将涵盖通过利用大约十种神经网络架构的力量解决的十个生命科学问题,同时指出其他机器学习* (ML)传统算法的缺点。*
就像在时间机器中一样,我们将从过去跳到现在,通过生物体的进化到 RNA、DNA、蛋白质和细胞的功能(按照自然规律排序)。通过领域精英对一级文献(约 30 篇)的探索,了解遗传病、病毒,甚至了解 2020 年诺贝尔化学奖是怎么回事(CRISPR)。
绘制草图来描述与每个相应挑战相关的各种神经网络是本次讨论的主题。从最简单的神经网络开始:多层感知器、卷积(CNN)和长短期记忆* (LSTM),我们将弥补理解由图像处理启发的高级模型的差距,如残差、生成对抗网络 (GAN)和对比网络。随着变形金刚(通过注意力机制)的兴起,以及序列模型、自动编码解码器等经典模型的兴起,通过翻译生命语言(蛋白质)滑向自然语言处理 (NLP)。受分子信息传递的启发,我们将使用图 神经 网络 (GNN)来表示一个分子,其中原子是节点,键是边。同样重要的是,我们将用 maxout 层破解最优激活函数。最后但同样重要的是,从 Atari 游戏切换到细胞,我们将以深度强化学习(正如大多数演讲一样)来结束这次演讲。机器学习的基础知识将在数据扩充、迁移学习和 t-SNE 中随处可见。*
我希望看完这篇博客,你会对 NNs(当然还有分子生物学)了如指掌。
词汇
我在下面列出了一些值得了解的短语(不仅仅是为了阅读这篇博客),这些短语来自我在生物信息学领域的数据科学经验。
系统发育、基序、外显子组、计算机模拟、聚糖、寡基因到多基因、组学、宏基因组学、生物聚合物、异质性、病原体、神经嵴、外显子、剪接 DNA、外显子组、细菌分支、染色质、texa 树、k-mer 编码器、细胞、基因本体
挑战
为了简单起见,我推断下一个标题最好地代表了每个挑战的潜在思想:(1)挑战的动机,(2)我们试图预测什么,(3)使用这个特定架构的基本原理是什么,(4)训练网络的输入(最重要的是表示)和输出,最后,(5)替代方法(如果有的话)。挑战的内部和外部顺序是根据模型的复杂性组织的,每个挑战中最有影响力的论文都被突出显示,以区别于其他论文(尽管所有的论文都是经过严格挑选的-保证!).说到这里,重要的是要提到,这里讨论的一些文章仍然处于 arxiv 状态(等待接受)。然而,在考虑验证过程时,我仍然看到了解它们对于理解整体架构选择的有益价值(这是本博客中所缺乏的,也许下次——更新:这里有一个关于验证的我的博客的链接,将其视为附录)。现在,请欣赏您对与分子生物学相关的高级 ML 方法的介绍。
事不宜迟,让我们转移到我们目前在这个令人兴奋的研究时代面临的革命性挑战。
1.遗传病
通过基因的镜头,生命的每一个方面都通过测序编码来解决。然而,仅通过临床病例研究了关于特定疾病的部分信息。如何通过分析基因位点(基因型)来诊断疾病(表现型)?这是一个严肃的问题,因为相对于过去几代人来说,在这个年龄活着的价值已经大大增加了……然而,生物学家和生物信息学在调查哪些基因对特定疾病负责方面还有很长的路要走,如下例所示。在本节中,我将描述如何潜在地将 ML 用作诊断工具,为未来的临床应用和推进个性化医疗铺平道路,并在总体上有望改善我们的生活质量。
我们的主题是从对照组中预测基于外显子组的计算机模拟诊断为克罗恩病CD【2】和双相情感障碍BD【1】患者的疾病组,以及根据基因表达数据预测肺癌生存特征【3】。输入是 Fg × Ng 的张量(Ng 代表参与这种特定疾病的基因列表,Fg 是特征列表),输出是概率得分。例如,在 CD 病例中,在文献中发现了导致疾病的两组基因{222,691}(每组中的基因数)和描述基因的 11 个特征(代表每个基因的突变负荷,如外显子、内含子、剪接等)[2]。在对肿瘤类型进行分类的第三种情况下,输入图像(175×175 像素)是通过将基因表达值直接映射到一组固定的颜色来生成的,使用域特异性信息来确定每个基因在图像中的位置[3]。
该架构非常简单,利用了 NN 的基本原理,包括完全连接的层(多层感知器网络【2】)和卷积层(用于染色体表示【1】)以及迁移学习*(用于图像【3】)。问题是神经网络是否有资格对基因进行分类,甚至是在基本的编码水平?可以公平地说,一个(共享的)神经元将包含一些输入特征的“隐藏的”压缩表示。这种表示被优化以允许下面的层区分病例和控制。从这个意义上说,编码网络可能包含一些显著简化的基因表示,例如,神经网络模型利用滑动窗口技术(在卷积情况下)来理解它们的表示(特征)之间的相互作用。*
2.RNA 结合蛋白质类
RNA 序列的潜在模式由称为基序的短连续氨基酸组成,蛋白质与之结合(RNA 结合蛋白 RBP)。序列中基序的变异改变了结合的亲和力。另一种影响结合的模式是 RNA 二级结构,根据 RBP 的偏好增加或减少结合亲和力。
考虑到影响结合的各种生物因素的以下数据限制,预测蛋白质结合的挑战并不那么容易。(1)高质量数据(基因序列通常非常嘈杂和有偏见)和元数据(凭经验确定的二级结构)的可用性仍然是一个问题。(2)本实验包括不代表 RNA 可形成的二级结构多样性的短序列。(3) RNA 竞争是体外的,因此它不能如实再现体内的条件,在体内存在其他蛋白质并可能竞争结合位点。
这些都是负面的,现在让我们改变对 ML 的态度(积极的一面)。许多氨基酸在生物学上可以互换,但是甘氨酸到丙氨酸(G->A)的替换可能是中性的,而色氨酸到丙氨酸(T->A)的替换可能不是。因此,通过研究合适的编码器来表示氨基酸来降低维数是有意义的,甚至是实际可行的。语言模型中使用的嵌入减少了输入的维数,因为人类字母表中有许多字母,它们可以组成许多不同长度的单词。然而,对于 DNA/RNA 序列,只有 4 个注释字母{T/U,A,C,G},采用一键编码,所有的核苷酸都是相似和不相似的,让分类器来找出它们如何与序列中的单个项目和组合相关。
描述完表示之后,是架构部分;CNN 过滤器可以被视为基序*,这是生物学家的金矿,因为它允许他们解释蛋白质的结合偏好,并将其与现有的结合偏好知识进行比较。另一方面,LSTM 层提供了比 CNN 过滤器更大范围的上下文相关性,并且当在二进制分类设置中使用时,它们的输出被直接解释为绑定配置文件。因为 LSTM 节点具有记忆能力,能够记住和检测对分类任务重要的上下文线索,所以当分析长序列如 RNA 序列时,它们特别有用。他们没有对二级结构做任何特别的建模,而是“简单地”学习结合基序的上下文。LSTM 节点本质上是单向的,因为它们依赖于时间;他们有过去的记忆,但没有未来的知识。每个时间步都是一个核苷酸,因此为了让模型知道上游和下游元素,我们使用一个 LSTM 层来分析正向序列,另一个层来分析反向序列。这通常是一种有用的方法,因为即使是语言处理也需要过去和现在的知识来完全理解句子的意思。将这些结合起来称为双向 LSTM (biLSTM)架构,但大约是两个常规的 LSTM 层。*
因此,我们使用双向层,因为蛋白质结合不是固有的定向过程,而是会受到上游和下游序列的影响。deep clip【5】的 LSTM 层是基于卷积层检测到的基序的不同分布来馈送的。在某种程度上,CNN 层也可以被认为是放大镜或双筒望远镜,通过增强输入序列的这些区域来引导 LSTM 层的注意力。该领域的最新模型称为 ResidualBind [6],表明单独使用卷积层在捕获所有序列变化方面效率低下,因为 RBP 在其绑定模式中具有不同程度的复杂性(一些绑定模式可能简单,而另一些可能复杂)。因此,残差模块允许网络建立在第一卷积层的模式上,同时考虑卷积层的扩展长程上下文。
3.演变
**系统发育在进化生物学中的核心作用在查尔斯·达尔文的《物种起源中有所推断,书中唯一的数字是一些物种假设系统发育的草图(达尔文 1859)。系统发育表现的天才体现在其简单而优雅的组织方式上,定义为树。在这里,几个预测任务,探讨分析系统进化树的建设;从使用宏基因组学数据评估 IBD 病的严重程度[7],预测聚糖的分类来源[8],到预测具有四个分类群的树的拓扑结构(即四元组树)[9]。
在 CNN 模型中,宏基因组学数据可以松散地解释为一幅图像,后面是特征之间的邻近性(距离)概念。就像图片(像素)一样,细菌进化枝也是如此。宏基因组学数据被转换成一组图像[7],每个样本一个,其中对应于相同细菌物种的像素在所有样本中具有相同的位置(坐标),像素的强度对应于像素的数据丰度。
在这种情况下,卷积层在细菌分支之间的系统发育关系策略下发挥作用,稍后由分类器在区分患者时使用。在深入探讨架构方面之前,我们先来谈谈其他机器学习方法的局限性,如 SVM 、 RF 等。当输入是多模态的,并且由序列和系统发生树组成时(如我们的情况)。与卷积层不同,卷积层负责处理树节点的距离,没有其他方法能够以如此合适的方式同时处理这两种模态。此外,跨位点和谱系的置换过程中异质性的性质要求明确考虑序列进化的置换模型。在这种情况下,其他方法可能会因模型设定错误和不足而失败。
既然我们对神经网络对我们问题的有效性有相同的看法,让我们详细了解一下输入和输出。抽象地说,最初的 quartet 种系发生假设【9】任务只是从四个序列的输入数据中预测一个离散状态(从三个中选择)。因此,4 个 4×20×L 的比对氨基酸序列被输入到残差网络中,其中 20 代表蛋白质序列任何位点可能的氨基酸状态,4 表示 4 个分类单元,L 代表序列长度。网络输出包括三个数字,代表一个给定分类单元是其他分类单元的姊妹分类单元的可能性。理论上,剩余层将输入信息作为输出的附加部分进行记忆,允许更深层次的网络结构,而不会受到消失梯度效应的影响,因此可以更好地学习复杂的进化过程【9】。
4.CRISPR
成簇的规则间隔短回文重复序列(CRISPR) -关联(Cas9)系统现在是基因编辑中的一项著名技术(特别是在今年诺贝尔奖授予 Emmanuelle Charpentier 和 Jennifer Doudna 之后)。CRISPR/Cas9 主要发现于链球菌 化脓中,它利用这种机制来抵御入侵的病毒。从那时起,CRISPR DNA 工程发展迅速,并已应用于治疗多种疾病。简而言之,CRISPR 使用结合 DNA 靶位点的指导 RNA (gRNA)。之后,核酸酶,如 CRISPR 相关蛋白 9 (Cas9),在切割 DNA 之前引起构象变化。然而,它有一个偏离目标的风险。切除非靶位点会严重伤害细胞[12]。因此,研究目标是准确预测单个 gRNA 对靶敲除功效【10】。对于监督学习,输入是 gRNA 序列的矩阵 L×4(4 个核苷酸和 L 序列长度),输出是已知的目标敲除功效。
NNs 理解数据内部结构的能力令人印象深刻,这种能力来自于层类型和拓扑的灵活组合,相对于浅层模型(例如决策树)而言,这种能力非常突出。例如,卷积层具有通过共享本地连接处理数据信息的独特特性。考虑到 DNA 和 RNA 碱基在局部相互影响,卷积层可能是处理这些序列相关问题的合理选择。RNN 也是建模 sgRNA 相关问题的合适方法,因为序列数据自然地匹配 RNN 的拓扑结构。然而,与 CNN 网络相比,RNN 网络通常很难训练,并且需要更多的数据来实现可接受的性能。因此,通过数据扩充增加研究案例有助于缓解泛化能力【12】。
5.非编码 DNA
当你阅读这篇文章时,请坐下来,因为你将听到关于你自己身体的消息。让我们直接面对遗传学的一个基本事实。科学家承认(白纸黑字写着):“已知人类基因组中 98%以上是非编码的,93%的疾病相关变异位于这些区域”[14]。如果你已经被这个理论压倒了,让我安慰你,你并不孤单;我们同舟共济驶向未知,希望了解这些区域的功能。然而,这项任务具有挑战性,因为大多数这些区域的功能还没有被很好地理解。仅从 DNA 序列预测非编码变体的功能效应,使用适当的特征提取和特定功能效应的选择方法,实际上是解决多标签分类问题。对于那些熟悉生物学的人来说,这项任务的大画面将被表示为预测转录因子结合(与蛋白质结合),处理由深海和丹克的和准备的数据集,对 1000 个输入序列长度的 919 个二元目标(染色质特征)进行分类。
DeepSEA 提出了一个利用 CNN 从原始 DNA 序列中捕获基序的模型,听起来很简单:这个模型包含三个连续的卷积层,后面是执行模式识别的完全连接层和用于空间缩放的池层[13]。卷积层实际上非常类似于 DNA 序列中的扫描基序,这可能类似于转录因子等蛋白质如何识别 DNA 序列。然后,较高层识别较长序列上的序列模式,并捕获基序相互作用和元模式。另一方面,DANQ 通过在 CNN 之上添加一个 biLSTM 网络来优化模型。基本原理是将基序解释为遵循由物理约束支配的调节语法,该语法规定了体内基序组合的*空间排列和频率,这是一种与组织特异性功能元件如增强子相关的特征【14】。到目前为止还不错,但是来点更辣的怎么样?也许要加强一点语法联想,注意力机制的时机成熟了吗?本研究[15]展示了各种架构的集合,从卷积层开始,卷积层捕获调控基序,然后循环层捕获调控语法,最后是类别注意层,用于选择不同功能的相应有效特征,然后是对预测标签进行分类的密集层[15]。*
不同的头可以关注来自各种潜在空间的不同种类的信息。注意力分数(由多头相加得到)可以近似找到 DNA 序列中的功能位点,在可解释性方面非常有用。此外,使用注意力机制的权重分配策略将局部连接参数的数量从 1000 万减少到 1000 万。实现这一点的方法是通过确定每个二元目标的相关特征,然后局部连接层消除每个特定目标的所有不必要的连接[15]。为了让你看一看模体的识别是如何为医学服务的,看一下下面的“湿实验”:从数千个习得的模体中,数百个与已知的模体匹配,这些模体具有显著的潜在发展重要功能效应,如 NRSF、EZH2 和 P300 [15]。
6.蛋白质语法
自然语言处理 NLP 已经被推广到理解生命语言(蛋白质)。由于无监督学习,NLP 方法通常独立于昂贵的标记数据,这简化了蛋白质序列(包括最丰富的蛋白质修饰之一,聚糖)中生命语言(语法上)的实现。这种方法背后的主要概念是将蛋白质序列表示为句子,将它们的组成成分氨基酸表示为单个单词(在多聚糖中,每个标记* ( 三聚体)表示可以在多聚糖中的给定位置找到的糖单词)。本节讨论的主要挑战是将氨基酸解释为口语,这意味着揭示语法(及其派生物,如风格、修辞、表达等)。).当听到蛋白质数据集的规模时,对生物/医学数据可用性持悲观态度的人(像我一样)会受到启发。显然, UniRef 和 BFD 数据集包含来自 21 亿个蛋白质序列的多达 3930 亿个氨基酸(单词),这使得它成为写作时可用的最大的蛋白质序列集合(是整个英文维基百科的 22 倍和 112 倍)[18]。*
被证明能够学习蛋白质的有用表示的架构之一是 Transformers,它优于基于 LSTM 的方法,以及使用 word2vec [18]的非结构化方法,尽管它缺乏透明性。然而,通过变压器内部工作的镜头,注意力机制,可以在标记水平(蛋白质属性)和标记对水平(接触图)检查各种蛋白质属性[1]。更多关于那些“模糊”模型的可解释性技术将在后面讨论,而这里的重点是解释实例级预测(事后解释)。变形金刚模型与两种主要方法有关:自回归或自动编码*。自动回归预测序列中的下一个标记,给定所有先前的标记,而自动编码重建损坏的输入训练。在翻译任务中,通常,单向模型(自回归)与双向模型(自动编码)一起执行。*
以下是在蛋白质序列数据集上训练的四个知名Transformer*的汇总/对比: *Bert,Albert,Transformer-XL,和 XLNet 。首先, Bert 是一个双向模型,最初试图重建损坏的标记,现在被认为是 NLP 中迁移学习的事实标准。第二, Albert 通过其注意力层之间的硬参数共享降低了 bert 的复杂度,增加了注意力头的数量(改善了交通堵塞)。第三, Transformer-XL 通过将序列切割成片段(芯片)克服了最大序列长度的障碍(这些数据集中约 20%的序列长于 510 个氨基酸),这是所有以前的变压器共有的,但允许信息在它们之间流动,以便更长的蛋白质重用其已处理片段的隐藏状态。最后, XLNet 使用了由 Transformer-XL 引入的类似的单向内存机制,通过在一个内存片段中收集双向上下文来处理任意长度的序列。
回到可解释性,为了探测在令牌级捕获的信息,例如结合位点和二级结构,我们冻结了原始模型的权重,并建立了一个具有单一线性层的分类器,后跟 softmax。对于记号对探测任务(接触图),成对特征向量的连接通过两个记号的输出向量的元素差异和乘积来处理[16]。
在阅读了所有这些枯燥和大量的信息后,你瞧,通过享受可视化美丽的视觉嵌入空间,通过使用 t-SNE [18]将高维表示投影到二维来创建,图 6。
*在这篇博客讨论的所有挑战中,我最兴奋的是讨论以下两个挑战!我如此兴奋的原因是作为神经网络的**系统构建的模型的复杂性,*同时每个架构的好处都被充分利用,甚至管理模型中的另一个网络以给出最好的结果(把它想象成有史以来最好的工作团队,在优化时,网络代表你工作……)。
7.蛋白质功能
蛋白质在细胞途径中与其他蛋白质接触,因此通过蛋白质-蛋白质相互作用(PPI)网络理解这些途径的功能是至关重要的。基因本体论术语注释(GO)将蛋白质分为大约 200 个不同的功能类,聚集到分子功能、生物过程和细胞成分的部分。面临的挑战是在给定蛋白质序列和结构的输入数据的情况下预测 GO 项概率(表示为从 3D 形状中的分子相互作用得到的图形)。选择两种类型的序列多样性用于实验:使用来自相同生物体或跨物种的序列,而最后一种利用大规模训练集并克服仅相同生物体的蛋白质共有的有限特征空间的问题[21]。
在 DeepFRI ,图卷积网络中,GCN 获得输入:一个一键编码的蛋白质序列- >两个堆叠的前向 LSTM 层,每个层有 512 个单元- >训练嵌入+一个邻接矩阵(蛋白质图),并返回输出:一个单一的特征矩阵,该矩阵随后馈入两个完全连接的层以产生最终的预测[19]。邻接矩阵,也称为接触图*,是一个 2D 二元矩阵,代表所有可能的蛋白质连接对之间的距离。卷积层适用于这种结构问题,因为它们在离散路径(通过接触图)上卷积蛋白质特征,这些路径在一级序列中是不同的,但在 3D 空间中彼此接近。Kipf&Welling【30】的公式定义了添加到第一个 GCN 层的表示方程,它表示接触图矩阵和最终 LSTM 层的隐藏状态的乘积。*
做 NN 常用的激活功能如 ReLU,Sigmoid,Tanh 等。对生物序列中的常规或常见模式进行适当编码?另一种架构方法是其层具有 maxout 激活功能的网络。层的最大激活是一组输入仿射变换的元素最大值。这些激活函数逼近任何任意连续函数,并且优于由特定假设(例如,修正函数或 sigmoid 函数)参数化的其他传统激活函数。
由于在这个预测任务中占用的空间高度稀疏和不平衡,一个支持向量机 (SVM)来拯救使用最大输出网络功能,并提供独立的边缘校准,每个类的二进制分类(具有其特定的决策边界)[20]。在这种情况下,要提到的一点是网络的结构模式(就单元数量而言)。虽然为了降维任务而减少每一层中的单元数量是常见的,但情况并非总是如此。特别是在这里,因为网络最初被训练成一个大的多标签分类器,留给你的是大量的类,即几百个输出单元。因此,后面的图层通常会提供更大的深度,以允许对内部要素制图表达进行不同的解释。因此,需要一个大空间来编码这种高信息量的表示[20]。
8.病毒
免疫系统通过招募抗体来阻止入侵,从而中和抗原,即病毒入侵者。然而,适当的反应可以持续几天到几周。对新病毒突变的预测能否产生预定义的中和抗体?抗原和抗体之间高度选择性相互作用的过程决定了抗体介导的病毒中和的基础。对由病毒基因组合成的相应抗原-表位序列的预测实际上是一个比直觉认为的更广泛的问题,考虑到不同病毒物种中进化群体的突变,学习一个广义的时间可逆进化模型[24]。
出于训练过程的考虑,评估是通过收集各种病毒的抗体-抗原序列进行的,包括 HIV、流感、登革热、SARS、埃博拉、肝炎等。使用生物信息学、结构生物学和分子动力学中的功能模拟来寻找最稳定的抗体【22】;并且开发了两种表示法。第一种表示法被命名为图解蛋白质特征化GPF【22,23】,第二种表示法是二元进化树*(部分结构化)【23】。为了让您对 GPF 的表示有所了解,让我们假设您有一个长度为 N 的序列。首先,构建一个邻接矩阵 Nx20 (20 代表代表蛋白质的氨基酸总数,N 代表序列长度)。然后,因为我们对于每个氨基酸有 38 个特征 F,所以特征矩阵形状是 20x38。现在,我们将邻接与特征矩阵相乘来构造图嵌入。我们把这个产品叫做图嵌入,它有 NxF 的形状。最后,我们的意思是池在图的嵌入上将其转换成 Fx1 向量。这个向量乘以它的转置,得到 FxF 的最终矩阵。最后,FxF 矩阵被展平以创建一个 1444 大小的向量(38x38 = 1444)。*
另一种架构基于一个分布式网络框架* GAN 内的 seq2seq 生成器,它生成用随机噪声增强的完整蛋白质序列(从而避免专家手工定制的工作)[24]。未来病毒群体的那些可能突变是长度超过 300 个氨基酸的全长蛋白质,通过利用 uni 和双向 LSTM(类似于句子翻译)[22,23],模仿原始抗原序列可能来自的潜在正态分布 N(0,1)。这些新的序列不应该与原始抗原有显著的不同(具有极其多样的序列没有太多的生物学意义)。因此,自动编码器被用作鉴别器,它接收两个序列并确定输入序列是否是真正的父子对。请记住,在编码器层使用 biLSTM 和在解码器中使用 LSTM(而不是两者的任何其他变体)的基本原理是整体高性能架构,该架构结合使用 seq2seq 模型和 LSTM 来解决特定的翻译任务。对于 biLSTM,序列是向前和向后输入的,需要整个序列(这对编码器来说不是问题,因为我们已经有了整个输入(父)序列)。然而,这对于解码器没有意义,因为输出(子)序列是在每一步中生成的,直到我们到达停止点;因此,这是一个单向 LSTM。*
9.蛋白质表示
我选择在所有蛋白质部分之后提出这个主题,作为对“这就是生活”主题的一个比喻,这意味着蛋白质的优化表示,我们在过去三次挑战中大量讨论的这一点在这一部分得到了总结。
捕获有意义属性的生物序列的预训练嵌入表示可以减轻生物学中的许多监督学习问题。学习蛋白质序列嵌入程序将任何蛋白质序列映射到载体嵌入序列,每个氨基酸位置一个,编码结构信息。理想的嵌入干净地分离了潜在空间的数据集域,不需要参数调整或额外的评估标签。
表征学习的美妙之处在于,所有的生物属性都是以纯数据驱动的方式自动学习的,在这种方式下,模型会推断出隐藏的特征,这些特征对于确保自然发生的蛋白质序列的语义和语法意义至关重要。虽然其他方法不编码结构信息,**be pler等人的框架通过编码序列和结构将任何蛋白质序列映射到载体嵌入。他们的模型使用三个 biLSTM 层进行训练,每个层具有 512 个隐藏单元,最终输出嵌入维数为 100,蛋白质序列具有两部分反馈机制,该机制整合了来自(I)蛋白质之间的全局结构相似性和(ii)单个蛋白质的成对残基接触图的信息[25]。**
对比学习的灵感已经被 Oord 指出,他说 : “无监督学习最常见的策略之一是预测未来、缺失或上下文信息……在神经科学中,预测编码理论表明,大脑预测不同抽象层次的观察结果”。在模型的自我监督预训练期间,在蛋白质的潜在表示中捕获期望的嵌入,该模型将小块呈现为捕获基序、异常结构元素、异常氨基酸组成区域、催化位点部分等。一般公式为:给定输入 X,将{x1,x2}定义为 X 的两个不同“视图”(例如,图像的小块,或不同序列时间步长的表示),以及分别编码{x1,x2}的编码器{g1,g2}。目标是找到最大化输出之间的互信息 MI 的编码器映射。该模型的直觉是,全球蛋白质背景决定其功能,影响序列/结构的每个局部片段。通过最大化全局上下文和局部上下文之间的交互信息,模型“被迫”学习蛋白质整体功能中与局部序列/结构相关的方面。这种方法在准确性和参数数量方面表现出色,表明它是最“熟练”的蛋白质表示法[26]。橙色星号表示对比模型,蓝色十字表示之前讨论过的其他方法([26],图 1)。**
10.细胞迁移
训练有素的特工可以在几个雅达利游戏中击败人类水平的分数。如果是这样的话,为什么不训练一个模型来预测细胞的运动呢?细胞运动被视为由细胞内或细胞间信号调节的衍生和受控行为的结果。模拟细胞间的相互作用,如运动的共同吸引和接触抑制,对于理解集体细胞迁移是必不可少的。集体细胞迁移是一组细胞的协调运动,通常在例如胚胎发育和伤口愈合过程中观察到。通过人工智能模型来预测这些生物物理行为比以往任何时候都更加接近。然而,虽然调控网络可以在细胞、群体、组织甚至胚胎水平上定义,但当时只模拟了单个细胞运动(领导者代理)及其相邻细胞(追随者代理)的运动。感觉我在这里描述一个游戏… 😃
这个游戏的主要问题是,代理人的下一步行动是什么?我们可以用什么样的轨迹和模式来模拟它们向集体细胞迁移的运动?答案各不相同,从通过计算机视觉跟踪了解它们的运动(然而,从昂贵的实验到离散空间,这里有大量的问题)到应用像旧时尚一样的动态方程(但这是一个好的,或至少最有可能模仿生物行为)——扩散【29】。要全面了解政策学习,敬请关注。
深度强化学习擅长处理高维输入,因为它从全局角度优化了细胞在相当大的时间和空间跨度上的迁移路径。更重要的是,它克服了使用贪婪算法的传统的基于规则、基于代理的建模所遇到的局部优化问题。这里主要关心的是如何收集观察数据。我的意思是,建立一个基于主体的建模框架,以建立一个使用 3D 延时显微图像的集体细胞迁移的模拟平台的最佳方法是什么[28]?不要想太多,因为大多数网络都是基于图像的,通常很耗时,计算量也很大。此外,有限数量的输出不能为偏移方向生成无限连续的表示。
深度确定性策略梯度 DDPG 可以使用具有生物学参数的低维观察和应用强化学习来学习领导者和追随者细胞的通用策略【29】。因此,两个网络被训练出来,即评论家和演员。actor-network 有三个具有 64、128 和 64 个神经元的隐藏层和一个具有一个神经元的输出层。关键网络从行动者网络的输出层输入位置、浓度梯度方向和行动值,并通过另一个类似的架构网络找到 Q 值(最佳行动值)。然后,扩散模型描述了在模拟环境中通过粒子动力学运动收集的浓度场。当药剂移动时,它们作为化学引诱剂的多个移动源,影响浓度场的分布,从而决定药剂的作用。接下来,粒子运动和浓度空间之间的相互作用需要模拟环境迭代求解扩散方程,这是由于代理的新位置【29】。
关闭
与分子生物学相关的研究方法的进步令人难以置信,即使考虑到 2020 年我们将在家里呆很长一段时间(躲避冠状病毒)的事实。然而,利用神经网络的潜力来解决这些重大挑战,鼓励了数据科学界“还击”,对这些直接影响我们生活的惊人创新领域进行全天候的认真研究。也许全国紧急疫情引起的恐慌是一个令人耳目一新的警钟,引导我们探索将生物学和机器学习方法整合到一种方法中的严肃创新选项?
另一个值得一提的想法是成功 NN 模型的来源。到目前为止,vision 和 NLP 社区已经开发了这里讨论的大部分架构。因此,我的大部分解决方法是研究受这些应用程序启发的模式(视觉和 NLP 是应用程序,而不是纯数学)。然而,这提出了一个问题:一个新的架构模型是否会从生物信息学/生物技术/生物医学/生物学/遗传学社区中冒出来(这些社区可能发现自己在分子池中游泳)?虽然令人印象深刻的作品来自模仿自然行为,但类似的灵感会为下一代 ML 架构带来创新吗?
参考
- 深度双相情感障碍:通过深度学习识别双相情感障碍的基因突变。人类突变38.9(2017):1217–1224。
- 一个可解释的低复杂度机器学习框架,用于克罗恩病患者的基于外显子组的计算机诊断 NAR 基因组学和生物信息学 2.1 (2020): lqaa011。
- López-García,Guillermo 等,“使用基因表达数据通过卷积神经网络进行癌症生存预测的迁移学习”《公共科学图书馆·综合》杂志 15.3 (2020): e0230536。
- 通过深度学习预测 DNA 和 RNA 结合蛋白的序列特异性。自然生物技术33.8(2015):831–838。
- Grø nning,Alexander Gulliver bjrnholt 等人,“DeepCLIP:通过深度学习预测突变对蛋白质 RNA 结合的影响。”核酸研究 48.13(2020):7099–7118。
- 全球重要性分析:一种量化深层神经网络中基因组特征重要性的方法。 bioRxiv (2020)。
- 宏基因组学中的系统发育卷积神经网络。 BMC 生物信息学 19.2 (2018): 49。
- 《甜蜜起源:从聚糖中提取进化信息》 bioRxiv (2020)。
- 邹,,等.〈深度残差神经网络解析四重分子系统发育〉分子生物学与进化37.5(2020):1495–1507。
- 揣,郭辉,等。“DeepCRISPR:通过深度学习优化 CRISPR 指导 RNA 设计。”基因组生物学 19.1 (2018): 80。Optimized CRISPR 通过深度学习指导两个高保真 Cas9 变体的 RNA 设计
- 王,大齐,等,“利用深度学习优化两个高保真 Cas9 变异体的 CRISPR 指导 RNA 设计。”自然通讯10.1(2019):1–14。
- 张,于,等,“DL-CRISPR:一种用于 CRISPR/Cas9 中脱靶活动预测的数据增强深度学习方法。”IEEE 访问 8(2020):76610–76617。
- 周、简和奥尔加. g .特罗扬斯卡娅。"用基于深度学习的序列模型预测非编码变体的效果."自然方法12.10(2015):931–934。
- 光,丹尼尔和谢晓辉。" DanQ:一个混合卷积和递归深度神经网络,用于量化 DNA 序列的功能."核酸研究 44.11 (2016): e107-e107。
- DeepATT:一种用于识别 DNA 序列功能效应的混合类别注意神经网络。生物信息学简报 (2020)。
- 生物学与生物学的相遇:解读蛋白质语言模型中的注意力。arXiv 预印本 arXiv:2006.15222 (2020)。
- 丹尼尔·博亚尔、迪奥戈·m·卡马乔和詹姆斯·j·科林斯。“使用自然语言处理来学习多聚糖的语法.” bioRxiv (2020)。
- 《ProtTrans:通过自我监督的深度学习和高性能计算破解生命语言代码》arXiv 预印本 arXiv:2007.06225 (2020)。
- 使用图形卷积网络的基于结构的函数预测。 bioRxiv (2020): 786236。
- 用深度最大输出神经网络提高蛋白质相互作用网络的功能预测精度。PloS one14.7(2019):e 0209958。
- 网络被子:使用同源信息网络相似性进行基于深度多物种网络的蛋白质功能预测。 bioRxiv (2020)。
- Magar、Rishikesh、Prakarsh Yadav 和 Amir Barati Farimani。"使用机器学习发现新型冠状病毒的潜在中和抗体."arXiv 预印本 arXiv:2003.08447 (2020)。
- 王、于洋、普拉卡什·亚达夫和里什凯什·马加尔。“用于多类病毒突变预测的生物信息蛋白质序列生成.” bioRxiv (2020)。
- MutaGAN:预测进化蛋白质群体突变的 Seq2seq GAN 框架。 arXiv 预印本 arXiv:2008.11790 (2020)。
- 贝普勒,特里斯坦和邦妮·伯杰。“利用结构信息学习蛋白质序列嵌入.” arXiv 预印本 arXiv:1902.08661 (2019)。
- 基于互信息最大化的蛋白质表征自我监督对比学习。 bioRxiv (2020)。
- 王,子,等。线虫胚胎发生早期细胞运动的深度强化学习。生物信息学34.18(2018):3169–3177。
- 用深度强化学习加速集体细胞迁移 BMC 生物信息学20.18(2019):1–10。
- 基于确定性策略梯度的神经嵴细胞群体迁移深度强化学习模型。arXiv 预印本 arXiv:2007.03190 (2020)。
- T.N. Kipf 和 M. Welling,“使用图卷积网络的半监督分类”,2016 年 9 月。
一个人工智能学会玩战舰
在你训练计算机玩游戏之后,看它玩游戏可能比使用机器学习模型来进行预测更有价值。在强化学习的背景下,我们可以训练一个人工智能(一台笔记本电脑)来做决定,并赋予它能力,使其成为适应不断变化的情况的“终身学习者”。在这篇文章中,我分享了我在强化学习领域的早期步骤,其中包括从头开始编码,以理解使用 OpenAI Gym 进行更高级和标准化的强化学习方法的基本概念。
一台电脑在一个简化的 5x5 网格上玩战舰游戏,其中一艘隐藏的船占据 3 个单元。顶部网格是计算机的计分板。底部的格子对电脑来说是隐藏的,它显示了船在每场游戏开始时被随机放置的位置。“X”代表得分板上的命中,而“O”代表未命中。
在这个前所未有的生活在冠状病毒统治下的时期,我被困在家里,这给了我完成这篇文章的机会。这篇文章是关于我学习和编码强化学习(RL)元素的经验,这是教一台机器如何玩战舰所需要的。我选择战舰的原因是因为在我看来,编写它的框架很好地解决了第一次尝试 RL 时可能遇到的挑战。此外,编写人类可能用来赢得游戏的策略代码,然后将这个策略与机器提出的策略进行比较,也相对容易。当我第一次开始阅读强化学习时,我并不期望它与机器学习有那么大的不同,但事实是,设置教机器在特定情况下行动需要不同的方法和一些编程工作。事实上,用于预测建模的机器学习总会有一个库来帮助。相反,机器“教学”需要你思考如何适当地奖励你的机器,以便未来采取的任何行动都更像人类。此外,在大多数情况下,你没有任何数据可以开始,你设计机器所处“情况”的方式和机器采取的行动将在尽可能快地教会机器时产生重大影响。
我将遵循两种方法:
- 从头开始编码并使用线性模型来近似代理学习;
- 使用 OpenAI 健身房库和更先进的近似模型。
我在这里保留了第一种方法,因为它是我学习经验的一部分,理解任何更高级的 RL 方法的基础是很重要的。读者可以随意跳过它。同样,对于 RL 更详细的回顾,读者可以看这里或者这里。在本文中,我将只涉及几个关键术语和方程。最后,我没有花太多时间来改进本文发布的代码,而是把它作为我在 RL 的学习经历。
目录。
战舰快速强化学习。
在每场比赛或一集的开始和比赛期间,每个球员或经纪人看到自己的计分板。计分板代表玩家的环境。在任何时候,具有给定数量的命中、未命中和空单元的板配置代表代理“感知”的状态。当所有船单元被击中时,代理处于终止状态。代理从当前状态做出的任何可能的移动都是一个动作。代理因采取任何行动而获得奖励。这可以是一个正数或负数,它的定义需要在算法上使代理学习。在我的第一个方法中,我使用了下面的定义来分配奖励。当我使用第二种方法时,我将改变这个奖励方案。
为了避免懒惰的学习者,代理人在进行非法移动时利用的每个随机动作都会被分配一个惩罚。对于一次击中,会分配一个正的奖励,但会根据自上次击中以来这次击中所花费的数量进行折扣。事实上,这个想法是让代理人学会在击中目标后关注哪里,并防止它四处游荡。
行动价值函数 Q(s,a)是代理人通过执行行动𝑎从𝑠.获得的预期收益(或未来报酬)q 用于学习代理赢得游戏所需遵循的最佳政策或策略。最好的(真正的)政策是未知的先验。实际上,近似方法是用来获得一个最优策略的,它可能离最优策略很远。近似 Q 的模型可以被认为是代理“大脑”。
类人策略与完全随机策略。
为了简单起见,我们先问一个问题:“在一艘船(叫做巡洋舰)占据一个棋盘上三个格子的情况下,我会怎么玩战舰?”我随机呼叫一些位置,直到我击中一个船细胞或缩小位置的数量,这样我就可以比随机移动更聪明。
我们可以对这种方法进行编码,并为训练有素的代理创建一个基准:
- 循环遍历所有空单元,并制作一个计数矩阵,描述在每个位置有效装运单元可能出现的次数。具有最高计数的单元将是下一个动作。
- 如果命中已经存在,只考虑它周围的非空单元格。
(左)一个完全随机的代理人需要在 5x5 的棋盘上走 25 步才能在 12%的游戏中完成一个游戏(击中一艘有 3 个单元的船)(在这个例子中是 100,000)。(右)一个类似人类的代理人平均需要在 10x10 的棋盘上走 18 步才能完成一场游戏(击中 3 个细胞的船)6-8%的时间。代理将从不需要超过大约 40 次移动(0.4 个网格大小)。
根据经验,一个类似人类的策略平均需要大约 0.2 倍的网格单元数量来完成一个游戏:10x10 的网格需要 20 步,8x8 的网格需要 13 步等等。
q-学习最佳行动。
一个代理从它与环境的交互历史中学习最优策略。代理学习需要在算法中实现。在本文中,我们将使用 Q-learning,这是一种基于值的学习算法。Q 值是假设代理处于状态 s 并执行动作 a. 的整体预期回报的度量
Q-learning 是非策略,即代理评估并改进一个估计 策略,同时使用一个行为 策略(例如ε-贪婪)来驱动进一步的学习,从而从当前策略之外的动作中学习。估计策略的核心是逼近 Q 的函数,该函数使用下一状态的 Q 值来更新。这个下一个状态是通过做出有最大回报的(贪婪)行为而达到的。如果我们回忆一下 Q 学习方程式
该术语
𝑠′州的𝑎′行动是 q(𝑠′最大化吗?正如我们所看到的,我们下一步采取什么行动并不重要,目标是一样的:采取使 q 最大化的行动。
像 SARSA 这样的基于策略的学习方法意味着在更新 Q 函数之后继续遵循当前策略。如果我们回忆一下萨尔萨方程
𝑎′下一步的行动将遵循目前的政策。
根据 Q-learning 训练代理的伪代码是
使用 Q 学习和线性模型的智能体训练。
一个经过最佳训练的代理人将遵循一个估计的策略,同时受行为(ε贪婪)策略的“残余贪婪”的驱动,这是保证足够的探索和缩小产生最大回报的可能行动所需要的。ε-贪婪策略允许以固定速率ε对下一个动作进行随机猜测。遵循估计策略的行动预计会产生最高的回报。在训练代理时为 epsilon 找到合适的值有助于代理在训练结束后获得最佳策略。
当用ε-贪婪策略训练代理时,有两种选择:
- 将ε固定为所有训练集的值;
- 使ε随时间衰减,直到达到最小值。
在第一种情况下,当训练结束时,代理将优化其策略,保持探索的速率ε。因此,即使它的估计策略可能是完美的,代理也将以速率 1-ε使用它,同时以速率ε维持随机选择。
在第二个场景中,我们依赖于这样一个事实,即随着时间的推移,代理将已经学习到足够多的知识,以便它可以做出越来越好的估计移动,以有限次数的随机猜测击中敌船(获得更高的总奖励),其概率保持在最小ε值。需要这个最小ε来保证对代理的足够探索。事实上,随机移动有助于缩小敌舰的可能位置。有人可能会说,未经训练的代理人的估计移动也可以被认为是随机移动,那么为什么不让代理人从错误的估计移动中学习呢?随着时间的推移,这些动作会变得更好,对吗?现实是,如果我们让代理在每场比赛中从自己的错误中学习,而不让它进行足够的探索,它的策略永远不会是最好的。换句话说,估计策略的损失函数最终将被最小化,但是更低的最小值可以通过更好的策略来定位。此外,也有可能完全错过最小值。
重现下面结果所需的代码可以在这里找到。我用 10 万集的时间训练了一个代理,让他在 5x5 的棋盘上玩战舰,并把战舰的数量限制为一个由三个单元组成。我使用线性模型来近似 Q 函数,并且随机梯度下降,学习速率为 0.001,动量为 0.9,以最小化损失,这是 Q 值的均方误差函数。我让 epsilon 在前半集衰减,直到它达到 0.01 的值。
为了确保算法按预期运行,我做了一个初步测试,在每集开始时保持飞船位置不变。
正如预期的那样,估计策略线性模型在大约 10,000 集之后过度拟合:代理了解了船的位置。
在这个初始测试之后,我做了一个更真实的实验,让隐藏的飞船在每集开始时随机重新定位。
在 100,000 集的情况下,代理平均需要大约 13 步才能赢得一场游戏(0.5 个棋盘大小)。我们能做得更好吗?
使用 OpenAI Gym 的神经网络进行 q 学习。
学习如何为战舰游戏实现目标的代理的先前实现可以被修改以使用最新的 RL 算法,这些算法可以通过 OpenAI 稳定基线库获得。使用这些库的主要改变是让战舰环境与开放的体育馆库环境兼容。OpenAI gym 标准化了任何 RL 项目中需要的所有步骤。OpenAI 健身房所需的基本组件如下图。
完整的战舰环境在这里可用以及重现本文中描述的所有结果所需的代码。
对于我用 OpenAI 库执行的实验,我修改了奖励方案,如下所示
这转化为下面的代码。
修改奖励方案的原因是使其适应于处理重复的非法行为(移至非空牢房)。我尝试了许多版本,然后提出了这个简化版本,只取决于网格边长。在 OpenAI 健身房,我发现处理非法动作并不简单。事实上,非法移动需要随着时间的推移改变动作空间,这是我没有找到一个很好的解决方案。
一旦实现了环境,我们就可以使用稳定基线提供的环境检查器来检查它。我的实现允许在每个游戏开始时随机生成敌人的棋盘或者用户定义的敌人的棋盘。
最后,我们可以观察游戏是如何进行的,并查看奖励、动作和下一个状态,以确保一切按预期进行。
上面的例子显示了一个完全随机的代理在工作。
我做的第一个实验是训练一个代理人在一个 5x5 的板子和一艘巡洋舰上玩 1,000,000 集的战舰,它只由三个单元组成。代理人使用同步的、确定性的异步优势行动者评论家(A3C) 算法变体进行训练,称为 A2C 。我选择了使用一个 2 层 64 节点的多层感知器网络(称为“MlpPolicy”)来实现。演员评论方法背后的主要思想是使用两个神经网络,称为评论家和演员。评论家估计 Q 值;参与者按照评论家建议的方向更新策略分布。A2C 是 A3C 的变体,但是没有异步部分。经验表明,A2C 的性能与 A3C 相当,但效率更高。
训练一个有稳定基线的代理很简单。一旦实现了有效的环境,策略训练就可以无缝处理,我们只需要担心选择算法和优化其超参数。
我创建了回调函数来监控训练并保存最佳策略。他们可以在我的代码完整版这里找到。
代理人在 5x5 棋盘上用一艘巡洋舰玩战舰游戏的学习曲线。1000 集的滑动窗口用于平滑曲线。
在步骤 900,000 保存了最佳模型。该策略平均需要 7 步左右才能完成一局。
第二个实验,我用的是 6x6 的板,500 万集。
最佳模型保存在第 4,789,994 步。该策略平均需要 10 步左右才能完成一局。如果我们考虑到一个类似人类的策略平均需要大约 8 步,那么这肯定不是一个完全优化的策略。这也可以在下图中看到,其中曲线没有达到饱和。
代理人在 6x6 的棋盘上用一艘巡洋舰玩战舰游戏的学习曲线。1000 集的滑动窗口用于平滑曲线。训练有素的代理人演奏也显示在渲染板上。顶部网格是代理的计分板。底部的格子对代理是隐藏的,它显示了巡洋舰在每个游戏开始时被随机放置的位置。在一个案例中(第三集),代理人的行为出乎意料。
增加董事会规模会让学习变得更加困难,或者至少需要更长时间的培训。我的目标是看看代理是否能在第一次击中后学习下一步该做什么,以及在稍大的网格中学习正确的动作需要多长时间。
因此,在我的第二个实验中,我使用了 7x7 板和 10,000,000 集。然而,这一次,在为这许多集进行训练之前,我使用 Python 库 hyperopt 优化了模型超参数。事实上,像以前一样使用默认的超参数会使模型难以收敛。我只优化了与神经网络相关的超参数,特别是批量大小(n_steps)、学习速率、学习速率调度程序类型、学习速率衰减(alpha)、RMSProp 的ε因子,将所有其他超参数保留为默认值。优化空间如下所示。更多细节可以在代码中看到。
发现超参数的最佳值是α= 0.99,n_steps=10,learning_rate=0.007,lr _ schedule =‘常数’,
ε= 0.001。然而,我只有耐心等待 20 次试验,每一次都训练代理人 20 万集。根据想要尝试的试验次数(超参数组合),找到最佳超参数可能需要很长时间。我把这个留给读者去玩。
代理人在 7x7 棋盘上用一艘巡洋舰玩战舰游戏的学习曲线。1000 集的滑动窗口用于平滑曲线。训练有素的代理人演奏也显示在渲染板上。顶部网格是代理的计分板。底部的格子对代理是隐藏的,它显示了巡洋舰在每个游戏开始时被随机放置的位置。如前所述,在某些情况下,由于策略没有完全优化,代理的行为会出乎意料。
训练有素的特工平均需要 14 步才能完成一局游戏。对代理人进行更长时间的培训可能会带来更好的政策。
在 8x8、9x9 或 10x10 的网格上训练一个代理需要多少集?使用来自 5x5、6x6 和 7x7 网格的结果进行粗略的外推表明,我们可能很容易需要数亿个,并且可能永远不会达到近似模型的损失函数的最小值。同样,我的目标是学习 RL,我没有花时间来解决这个特殊的问题。
为了更快地收敛到最优策略,可以尝试的事情很少:
- 修改奖励方案;
- 使用不同的算法;
- 优化算法超参数。
在这三者中,找到一个更好的奖励方案将使收敛到最优政策的速度明显加快。
结论。
在这篇文章中,我描述了我使用战舰游戏进行强化学习的经历。对于任何愿意学习 RL 的人,我会建议同样的方法:选择一个游戏,编写它的框架,让它准备好应用 RL 技术,用它来实验 RL 的美丽和局限性。
我要感谢 Sundar Krishnan 所有有益的讨论。
代码。
利用自主加工系统优化工厂产量
用 21 世纪的技术对抗 20 世纪的思维定势
来源: PLC 学院
简介
在 MachineMetrics,我们选择将公司标志变成绿色,作为一种生产力的闪烁信号。绿色表示“开始”,在机器度量系统中,它还表示生产目标“达到目标”。
但是环保意义上的绿色呢?我们提高车间效率和减少浪费的具体方法是什么?从另一种绿色环保的角度来看,这又如何惠及我们的客户:金钱?
最近发布的 MachineMetrics 软件提供了一个生动的例子,它使我们能够部署一个解决方案,为我们的一个客户减少 90%以上的废弃零件。部署完全是远程的,不需要运输任何额外的物理硬件或安装售后传感器。在新冠肺炎疫情期间,我们完整地实施了这个解决方案;不需要任何人出差,我们从来没有踏进客户的机器车间,我们的客户也不需要安装任何额外的东西。我们为该客户节省了大约 5000 美元/年每台部署了该解决方案的机器的成本,并且只有一台边缘(物联网)设备为他们的整个工厂提供服务。
本质上,我们采取了一种纯粹基于算法和信息的方法来产生积极的物理影响,既有利于我们客户的底线,也有利于整个环境。为什么最大限度减少浪费和保护环境很重要?简单的答案是,低浪费和高效率是密不可分的一对——最大限度减少浪费的公司必然拥有更高效的运营。想象一下工业革命时期污染、肮脏的工厂,并把它们与今天时髦、现代的机器车间相比较。
我们对其他客户进行了调查,以了解该产品的潜力,并确定了多个可以远程部署该产品的其他站点,以使我们的客户和环境受益。这项技术的可伸缩性和最少监督的特性是其成功的关键。
技术的核心
在我们之前的博客文章中可以找到对该技术更深入的剖析,但简单地说,我们正在使用控制制造商现有的 API 从机器的主轴电机中提取加工物理数据。如果你想一想,主轴和刀具是机器的最后两个部件,在完成之前接触到正在制造的零件。机器的所有问题,无论是松动的滚珠轴承,任性的夹头,还是过度振动,最终都会影响到主轴,在主轴上产生零件的光洁度问题。
某些指标必须以非常高的频率可用,以启用机器中的反馈系统。反馈在机床控制中是强制性的,因为它们需要根据与制造零件相关的变化的外部(物理)条件不断调整它们消耗的功率量。例如,当刀具和材料相互接触时,主轴突然需要更大的功率来保持高速运转。反馈机制持续监控速度和扭矩等指标,以便正确执行这些调整。我们只是出于自己的目的提取这些指标,以优化机器操作、降低废品率和预测工具故障。
我们能够从高频控制数据中获得各种物理力和机器属性,无需传感器。来源:数控车床加工
事实证明,用于保持主轴以正确速度运行的相同指标也非常适合评估零件质量和刀具健康状况(惊讶吧!).我们可以从这些指标中精确测量加速度、摩擦力,甚至工具锋利度、材料硬度和零件几何形状。这实际上有一个非常优雅和美丽的原因。
现代机床使用一种称为 PI(比例积分)控制器的东西,这种控制器通常用于各种需要闭环反馈机制、需要自动控制的系统。你的汽车的巡航控制使用相同的机制——当你下坡时,汽车会由于外部环境而自然加快速度,从期望的设定点(比如 60 英里/小时)产生一个误差。PI 控制器检测到该误差,并改变进油量和应用的制动,以最小化该误差并回到期望的设定点。当你上坡时,误差在另一个方向,因此燃料和刹车在另一个方向上按比例使用。
PI 控制系统的简图,这是一个闭环系统,它不断尝试将外部刺激干扰引起的设定点误差降至最低。来源:联合学院 ECE 系
我们中的一些人有过巡航控制期间检查发动机灯亮起的经历。这可能会发生,因为 PI 系统是特别征税,并可能有助于暴露潜在的问题与您的汽车。机床总是运行 PI 系统,但是所涉及的度量标准通常不会以非常复杂或灵活的方式被监控。当为时已晚并且您的机器由于严重故障已经停止生产时,预设的安全阈值可能会启动并向您发出警报。
MachineMetrics 在其边缘设备上收集这些信息,也可以批量发送到云端进行离线分析。这使我们能够使用基本上任意复杂和定制的算法来监控 PI 控制器指标,可能会将特定机器的行为信息追溯到几个月或几年前,以及我们监控的所有商店中类似机器的行为。
当检测到问题时,出现问题的一种方式是通过机器度量系统向操作员或车间经理发出警报。但是,正如我们将很快看到的,问题也可以直接反馈给机器控制,允许它几乎立即采取适当的预编程动作。
回顾一下,PI 控制器的本质是来自设定点的误差被不断地测量和最小化。在机床的情况下,设定点是机器的每个主轴和轴的指令速度和位置。当刀具接触金属时,设定点的误差增加,使得机器有必要调整用于旋转主轴和移动刀具的功率量,以实现期望的位置和速度。我们无需在常用的边缘设备上添加任何额外的硬件,就可以提取该流程中使用的指标来衡量机器的健康状况。
部署
算法
正如你可能想象的那样,当工具变钝或以其他方式受损时,制造相同的零件会消耗更多的能量。当你用铅笔写字时,如果铅笔变钝或笔尖折断,你必须更用力才能做出同样的记号。因此,当我们客户的一些机器上的功率消耗超过某个点时,我们在历史上看到了与工具受损的 100%相关性。过了这一步,机器可能表面上看起来运行正常,但它生产的零件实际上是不合格的,注定要成为废品。在车间有人发现问题并更换工具之前,我们的客户通常会收到 10 到 50 个废弃零件。这些废弃零件每隔几天就会出现一次。
这个问题的性质使得它可以有一个相当简单和健壮的解决方案。我们观察特定加工操作过程中消耗的总主轴能量,并根据过去“正常”零件与过去报废零件的比较来设置阈值。在下图中,垂直红线代表操作员干预和机器度量中的相应注释,而每个点代表连续零件消耗的能量。
在工具失效之前,能量的跳跃大约是 10 个部分。周期性下降来自于被截断的周期。
作为一个基于状态的(物理)模型,我们用这种方法在 O(100)次出现上实现了 100%的精确度和 100%的召回率。也就是说,这种类型(立铣刀故障)的所有实例都被捕获,每次我们触发进给保持时,它都适合这种情况,并停止机器制造废料零件。物理学不会说谎。
驱动机构
当我们的 edge 软件检测到这种能量跳跃时,仅仅提醒操作者已经发生了这种跳跃是不够的。尤其是现在,当工作人员被保持在最低限度时,在操作员有时间干预之前可能会有很长的延迟。相反,我们已经想出了一种方法,在观察到的第一个废料部分后,我们自己也可以远程停止机器。
我们这样做的机制使用了我们所谓的“握手”我们不直接控制机器,而是 MachineMetrics 命令改变控制器上的特定宏变量,只有当该变量已经被客户预先设置为特殊值,表明他们准备好接收我们的警报。然后,我们自己对这个宏变量的特殊更改会使客户的 g 代码程序执行一些不同于其通常路径的操作。这种机制的目的是与客户分担责任——是他们的程序使我们的系统能够传达警报,也是他们的程序根据我们的警报信号决定做什么。在这种情况下,我们已经安排他们触发程序停止。**
在这个特定的实现中,我们选择了未使用的宏变量寄存器#600 来传递我们的信号。客户有责任将该变量保持在特殊值 1313,以使我们的警报系统起作用。如果观察到这种情况,并且随后观察到特征能量跳跃,表明生产有缺陷,我们将该值重置为 86。程序在特定点检查#600 的值。在#600=1313 的正常操作条件下,这里没有任何有趣的事情发生,它只是返回到开始。但是如果它观察到#600 由于 MachineMetrics 而变成了 86,它会执行一组额外的命令。下面是这种形式的一个简化程序的动画,其中额外的命令改变一个内部信号变量(改变 ENDMILL)并将#600 重置为其“等待”值 1313。
能量的跳跃导致我们的程序将#600 变量从 1313 改为 86。其随后将 g 代码程序分叉到另一个路径。
现在都在一起了!
那么这在我们的产品中是什么样子的呢?如下图所示,“负载异常检测器”值上升,我们停止机器,操作员重置机器,操作继续正常进行,在更换工具后,我们的能量敏感变量再次降至正常水平。整个过程花费了我们的客户一个零件。
该时间线还显示,在“变量异常检测器”下,宏变量从 1313 切换到 86,然后在客户的 g 代码程序中收到信号后切换回 1313。
负载跳跃,程序停止,操作员更换工具,负载恢复正常。
我们的系统会持续实时监控这一情况,坚定耐心地等待故障条件出现,并在产生大量废料之前停止机器。
一个加速的“实时视图”展示了我们系统的神奇之处。
自主加工系统的技术案例
我们之所以认为这家制造商具有 20 世纪的思维模式,是因为他们的制造过程有利润动机。简而言之,所有者明确指出,以两倍于其额定能力的速度运行机器更有利可图,可以生产更多的零件,但也会损坏更多的工具并产生更多的废料。该所有者完全有理由采用这种策略,因为零件数量几乎翻倍所带来的利润远远超过了与额外的加工、报废和停工相关的业务成本。在资本主义社会中,公司被激励去最大化他们的利润——任何不这样做的公司都是对他们的股东不公平,并且由于未能利用他们的资本获得最大的货币收益而造成无谓损失。
然而,我们相信有一种方法既能最大化利润,又能最小化有害的外部性。这不是政策的转变,而是技术的转变。简单的经济学告诉我们,监管、税收和关税为企业和个人参与某些行为创造了负面激励。烟酒税抑制了这些商品的消费,就像碳税抑制了化石燃料的生产一样。经济学 101 还告诉我们,任何税收、关税或监管都必然会造成无谓损失,或因资源配置不当而导致的市场无效率。
这是因为我们破坏了供需的微妙平衡——消费者仍然需要天然气来为他们的汽车提供燃料,但生产者不再有动力以满足需求的水平生产,从而导致价格低效率。消费者现在为燃料支付更高的价格,而生产商获得的利润更少,这使得双方在未来机会上花费的现金更少,并阻碍了经济增长。在一个利用银行来增加资本的现代经济中,任何来自税收的收入都远远超过经济中自由资产流动的损失。消费者不再有那么多钱花在房屋、家庭和教育投资上,而制造商也不再有那么多钱花在更多的机器、技术改进或雇佣更多的工人上。
税收降低了生产者的利润,也增加了购买者的成本,导致生产和需求的损失。来源:此事
答案在于政策和技术进步的结合。我们的技术使我们的客户能够在传统资本主义的框架内运营,使他们能够最大限度地增加利润,同时最大限度地减少这些决策带来的负面外部性,而不会造成市场效率低下。
一场关于废弃零件的曝光
那么我们下一步该怎么做?这项技术的真正价值在于防止零件报废。对于我们的客户来说,废弃零件代表了三个方面的改进。它们如下:
- 制造废弃零件需要资金,当被扔进垃圾箱时,就意味着制造零件所涉及的可变成本的全部损失。这不仅包括材料的成本,还包括与零件相关的任何人工以及公用设施的使用(如电力、冷却剂和润滑剂)。
- 废弃零件不能出售,因此也代表了制造商的机会成本。在制造这些废弃零件的过程中,机器本可以制造出可以出售获利的好零件。一台机器花费时间制造废弃零件构成了永久损失的时间,这些时间本可以用来制造有利可图的零件。
- 废弃零件是一个质量问题,通常由 QA 发现。然而,零件检测是一个手动过程,通常需要借助计量仪器和取样方法。这容易出现人为错误。当本应报废的零件被出售给最终客户时,这将损害双方的关系,如果在零件成为最终产品时没有发现缺陷,甚至可能成为一个安全问题。
还有其他与废弃零件相关的“隐性成本”——不应该忽视产生不必要废物的环境影响。
- 对于我们的大多数客户来说,废料相当于废物。制造商通常看不到足够的经济收益来尝试回收与废弃零件相关的金属,也看不到返工零件所涉及的劳动力和机器时间。这位顾客只是把它们扔进了垃圾堆,随后被倾倒到了垃圾填埋场。你可以想象每个制造商每月废弃数千个零件对我们地球的全球环境影响。
- 废弃零件不仅不必要地填满了垃圾填埋场,还会将有毒物质吸到地下水和土壤中,给社区带来公共健康危害。例如,Inconel 718,一种用于航空部件的普通金属,被 OSHA 归类为已知的致癌物。制造业中常用的其他物质也是已知的对人类健康的刺激物,适当的处理,尤其是小夫妻店,并没有严格执行。
在宏观层面上,报废零件到底是个多大的问题?让我们来看看气候变化专家索尔·格里菲斯的一项研究。他试图量化美国能源使用的来源和产出。与我们相关的一点是,60%的能源被浪费掉了。我们对此的第一个倾向是,这主要是生产过程中作为热能损失的能量(这是一个纯粹基于物理学的问题)。事实上,并非如此。
这实际上是我们在这里讨论的那种浪费。这是由不受利润动机抑制的负外部性造成的。化学公司向河流中倾倒污泥,因为这不需要他们付出任何代价,采矿公司在自然资源耗尽后建造和废弃矿山,机械工厂制造数百万废弃零件,只是为了倾倒到垃圾填埋场,这些都是造成这种浪费的原因。我们正在采取措施在制造业中解决这一问题——利用 21 世纪的算法和技术解决一个古老的问题。
来源:弗雷明汉打捞公司
有感而发
在我们作为一个社会为自己建立的经济框架内工作,对浪费的最好补救是技术进步。减少产生的污泥量,允许为采矿基础设施制造和快速部署解决方案,并使用算法来检测何时会出现废弃零件/在发生之前停止机器——不仅对底线,而且对应对废物和气候变化这两大祸害都至关重要。不浪费的工厂也更有效率。
如果有任何环境政策的改变可以加快这一进程,这是一个完全不同的话题,但我们在 MachineMetrics 感到幸运的是,我们能够将这些创新带到市场上,不是不顾而是由于我们所生活的当前系统。我们从风险投资资本看到的充足资金和持续兴趣使我们能够以极快的速度创新,资助变革性技术,同时让我们的客户获得更高水平的利润,并优化他们的运营以减少浪费和过剩。
我们热衷于使美国制造业在 21 世纪具有竞争力,并坚信我们实现这一目标的方式是通过增加收入和降低成本,赋予制造商更具竞争力的工具,而不是通过限制他们的生产能力或通过繁重的税收和监管使他们更难做生意。
我们很高兴迎来一个新的制造时代,一个能够利用云技术、可快速部署和扩展的数据科学算法以及机器远程管理的时代。未来的自动化工厂近在咫尺,我们渴望成为其中的一员。
11/18/20 回顾:自这篇博文发表以来,已经发布了 28 个远程 feed-hold,召回率为 100%,假阳性 1 个(准确率为 96.4%)。假阳性是由于阈值设置过低造成的,阈值设置提高了约 10%。从那以后没有假阳性。一次进给暂停是在工具故障期间发出的,原因是适配器在机器故障过程中崩溃并在此后不久启动。当适配器关闭时,在机器停止之前,产生了 103 个废弃零件。适配器错误已被修补。
根据保守估计,我们每次停止机器可防止大约 25 个废弃零件,在过去的两个月里,我们已经防止了大约 750 个废弃零件,而且从未涉足工厂车间。
当我们偶然重启我们的适配器时,机器正处于故障模式中。
参考文献
格里菲斯索尔。能源知识,2020 年。http://energyliteracy.com/
格里菲斯索尔。重新布线美国现场手册,2020。https://static 1 . squarespace . com/static/5e 540 e 7 FB 9d 1816038 da 0314/t/5 f 21 edad 94 f 7832d 9 B1 a 31 BF/1596059082636/Rewiring _ America _ Field _ manual . pdf
R 中人的可变性对实验结果的影响
一种简单的方法,有意义地可视化您的主题内数据。
照片由mārtiņš·泽姆利克斯在 Unsplash 上拍摄
一旦相同的个人或事物被测量了不止一次,我们就处理重复测量的数据,这种情况在数据科学和实验研究中非常常见。在这些情况下,您有机会估计个体差异在多大程度上导致了数据的可变性——以及观察到的数据在多大程度上可能是由于实验操纵(这是大多数人感兴趣的!).然而,与受试者之间的设计相比,重复测量数据的探索和呈现并不直接,因此您的受试者内数据可视化可能比您想象的更有偏见。这个循序渐进的代码教程将为您提供一个简单的方法
- 使用适当的视觉效果探索重复测量数据
- 计算受试者内的误差棒,以理清个体间差异的实验影响。
为了这个目的,让我们想象一下下面的实验:你对咖啡因对运动表现的影响感兴趣,因此想知道与只喝水相比,咖啡是否能让跑步者跑得更快。幸运的是,你有机会研究 40 名参与者,并在 10 公里跑中测量他们的个人速度两次:在第一次跑步中,一些参与者在第二次跑步前喝了双份浓缩咖啡和一瓶水——反之亦然。有理由认为,不同的人代谢咖啡因的方式不同,天生就有不同的跑步能力。
首先,这段代码模拟了一个随机的主题数据,包括每个参与者喝完咖啡和喝完水后的平均跑步速度。我们假设饮水后的真实跑步配速约为每公里 7 分钟,标准差为 2 分钟/公里。假设跑步者在喝咖啡的情况下稍微快一点,我们故意从每个跑步者在喝水的情况下的配速中减去 0.8 分钟/公里,并包含一点随机噪音。
模拟运行数据。
正如你在这个例子中看到的,跑步者在他们的速度上有很大的不同,并且在只喝水后似乎有点慢。然而,即使在相同的条件下,个体的价值观在每一个主体中比在不同的主体中更加一致。尽管这些是模拟数据,但这在本质上并不罕见,因为您可以假设个人有一个“真实”值(例如,跑步速度),该值仅部分地被观察到的数据捕获,而这些数据在环境真空下无法测量,因此通常非常嘈杂。现在我们有了运行数据,让我们使用 Dowle 等人(2019)的 data.table 包将它们转换成长数据格式,这对于我们以后的数据可视化至关重要。
每个主题在这个数据框中出现两次:一次是咖啡条件,一次是水条件。
免责声明:这些是用于说明目的的模拟数据,不以任何方式反映真实的运行数据。我不知道在这种情况下平均跑步速度会是什么样子。
可视化受试者内部数据——错误的方式
那么每个参与者的数据是什么样的呢?一些跑步者比其他人从咖啡中获益更多吗?一些跑步者与对照组相比没有表现出任何差异吗?或者更令人惊讶的是——是不是有些跑步者不能忍受咖啡因,因此可能跑得更慢?现在我们的数据已经准备好绘制了,让我们创建一个图表,通过按条件绘制每个参与者的跑步速度来找出答案。
第 1 级—单个原始数据
每条线代表同一个运动员。y 轴代表跑步者的速度,x 轴代表你的实验条件。
嘣!你可以看到,在咖啡和水的情况下,速度似乎略有增加。因此,你可以假设这种影响不会向相反的方向发展(例如,咖啡对一些人的跑步速度有害),但似乎一些人从喝咖啡中获益很少。但是你能回答咖啡在多大程度上让跑步者跑得更快吗平均来说?嗯——我不能通过看这个图表。因此,让我们用 ggpubr 软件包创建一个图——它将显示单个斜率,但也显示两个条件之间的总体趋势。
第 2 级—单个原始数据+总体趋势
好的,现在看来,平均来说,跑步者喝完咖啡后跑一公里需要的时间比喝水少。既然我们已经意识到了跑步者之间的差异,让我们忽略它们,试着只画出总的趋势。在出版物中,您可能经常会看到显示误差线的点图,误差线代表置信区间或平均值的标准误差。这是平均值不确定性的图形表示。通过 Ryan Hope 创建的 Rmisc 包,我们将计算平均值周围 95%的置信区间,然后使用结果来包含平均值周围的图形不确定性,这是由于实验的采样性质。请注意,在 frequentist 统计中,一个常见的误解是 95%置信区间误差线将代表包含具有 95%概率的真实平均值的值的范围。相比之下,我们的想法是,如果我们多次重复这项研究,CI 误差线将包含 95%情况下的真实平均值(Greenland 等人,2016)。
3 级——原始数据的总体趋势
好的——看起来误差线有轻微的重叠,这表明影响不显著(Cumming & Finch,2005)。但是我们还没有完成。
我们真的可以相信这个情节吗?这是否表明咖啡没有系统性地加快跑步者的速度?不完全是。我们现在还不知道。如果我告诉你,一个配对样本 t 检验揭示了喝咖啡和喝水条件之间的显著差异(p < .001)? How can that be, given that the plot suggests something different?
Remove between-subject variability
The answer is: we have used techniques to visualize between-subjects data on a repeated measures design. But we are actually not interested in the fact how fast runners are per se and how they differ from each other independently from our experimental manipulation. More specifically, we are interested in the extent each runner’s pace compares to his or her own pace in the other condition. Basically, we have done something similar like using an unpaired t-test for independent samples on a within-subjects study. As we know that this is obviously wrong for statistical inference, we should similarly account for the interindividual variability while plotting the data. In our previous plots we have done just that — the fact that individuals vary by nature (independently from conditions) was not controlled for. Again, we are interested in 将每个跑步者与他或她自己进行比较,但是我们已经绘制了反映跑步者之间差异的误差线,会怎么样?
根据 cosineau 的标准化程序
幸运的是,这个问题有一个非常简单直接的解决方案,由 Cosineau (2005)描述。按照这种方法,我们将对每位跑步者的基线配速进行修正——这样我们就可以最终看到配速的差异,这种差异主要是分别归因于咖啡和水的条件。使用快速而强大的 data.table 语法,我们将控制受试者之间的可变性(在这种情况下——跑步速度的自然差异)。我们只需从每次观察中减去受试者的平均配速,然后加上总体平均配速。通过这种方式,我们可以将观察到的数据中特定于条件的部分与特定于受试者的部分区分开来。这并不意味着我们的数据不受其他系统效应的影响(如血糖水平、心血管健康等)。)或非系统性的影响(例如,日常表现),但至少我们有机会了解咖啡对跑步是否有好处。
新值=原始值-个体基线+总体平均值
如您所见,每个人在不同条件下的平均值相同(由变量“check”表示),这与受试者和条件下的总体平均值相同。
可视化受试者内的数据——这次是以正确的方式
现在,我们将使用修正值(配速范围)来重新绘制图表,显示受试者在每种情况下的跑步者配速。
1 级—个人标准化数据
哇!看看这个!现在我们已经掌握了不同跑步者喝咖啡的好处(斜率)的不同程度。例如,与水相比,饮用咖啡的益处对于橙色显示的个体来说是最差的(根据相对平坦的斜率)。尽管这种影响看起来比实际要大(看 y 轴:与我们之前的可视化相比,这个范围相当小),但似乎一些人在喝咖啡后的速度比其他人快。
…如果我们想同时查看单个数据和总体趋势,该怎么办?
第 2 级—单个标准化数据+总体趋势
现在,显示 75%分布的方框受到了相当大的挤压——当我们考虑个体差异并查看咖啡与水之间的速度变化时,之前由自然速度差异导致的差异消失了。虽然我总是会选择展示数据分布的图,但我不建议将这样的图用于出版目的,因为在控制了受试者之间的差异后,它的解释并不真正简单。
最后,如果我们现在绘制校正数据的总体趋势,我们可以看到误差线不再重叠,变得非常小,这让我们有理由相信咖啡因可能影响了跑步者的速度。在我们虚构的例子中,也许咖啡消费应该被禁止,以确保跑步者之间的公平,并允许更合理的比较。
为了得出这一结论,我们将使用 Rmisc 包中的 summarySEwithin 函数——这允许我们计算误差条,这些误差条说明了数据的重复测量性质,因为我们指定了我们感兴趣的测量(例如 pace)、指定受试者内条件的变量(例如 condition ),以及最重要的表示测量来自同一参与者(例如 subj)的变量。如果你对其背后的统计基础感兴趣,一定要看看奥布赖恩和科西诺(2014)的论文。
3 级——标准化数据的一般趋势
注意:如果您想将图表与原始数据示例进行比较,使用相同的比例非常重要。
那又怎样?
人们是不同的,这很好。但是,如果我们对同一个人有多种衡量标准,我们应该充分利用这些标准,以便以更有意义的方式探索所研究的现象。
参考
[1] M .道尔,a .斯里尼瓦桑,j .戈雷基,m .基里科,p .斯捷岑科,t .肖特,…和 x .谭,《包》资料。表’ (2019),‘数据延伸。框架’
[2]阿·卡桑巴拉,包‘gg pubr’,(2020)R 包
[3] S. Greenland,S. J. Senn,K. J. Rothman,J. B. Carlin,C. Poole,S. N. Goodman & D. G. Altman,统计检验、P 值、置信区间和功效:误解指南,(2016),《欧洲流行病学杂志》, 31 (4),337–350
[4] G. Cumming & S. Finch,目测推断—置信区间和如何阅读数据图片 (2005),美国心理学家,60(2),170–180。doi:10.1037/0003–066 x . 60 . 2 . 170
[5] D. Cousineau,受试者内设计的置信区间:Loftus 和 Masson 方法的更简单解决方案 (2005),心理学定量方法教程,1 (1),4–45
[6] F. O’Brien & D. Cousineau,在典型软件包中表示受试者内设计的误差条 (2014),心理学的定量方法, 10 (1),56–67
一个简单的 YouTube 数据 API 3.0 的 Python 包装器
业内笔记
一个收集 YouTube 数据和运行有趣的数据科学项目的伟大工具
YouTube 是教育、娱乐、广告等等的主要来源之一。YouTube 拥有如此多的数据,数据科学家可以用它们来运行有趣的项目或开发产品。如果你是一个新手或者数据科学家专家,你一定听说过情感分析,这是自然语言处理的主要应用之一。例如,情感分析正被用于监控社交媒体或顾客评论。
当你在网上搜索时,你可以很容易地找到几个收集了亚马逊产品评论或 IMDB 电影评论的情感分析数据集。尽管如此,让您处理在线数据的 API 服务并不多。几周前,我决定在 YouTube 视频评论上运行一个情感分析项目。
对于没有经验的数据科学家来说,YouTube 数据 API 服务可能有点混乱。这就是为什么我决定编写一个用户友好的 Python 包装器来加速数据科学社区的开发。
我配置好一切,进行了我的实验。幸运的是,谷歌推出了一个强大的 API 来搜索符合特定搜索标准的 YouTube 视频。然而,我发现他们的数据服务对于没有经验的数据科学家来说可能有点混乱。这就是为什么我决定为 YouTube 数据 API 编写一个名为youtube-easy-api
的用户友好的 Python 包装器。该模块帮助社区更快地运行更有趣的数据科学项目。在本文中,我想向您展示如何使用这个模块。希望你喜欢它。
[## 人工智能:非正统的教训:如何获得洞察力和建立创新的解决方案…
通过 Kindle 分享。描述:这不是你的经典 AI 书。人工智能:非正统的教训是一个…
read.amazon.ca](https://read.amazon.ca/kp/embed?asin=B08D2M2KV1&preview=newtab&linkCode=kpe&ref_=cm_sw_r_kb_dp_8QSSFbEFAX8DD&reshareId=CK4K0MBDHW11XYFQ5EFE&reshareChannel=system)
获取您的 Google 证书
首先,您必须设置您的凭据,然后才能使用此模块。如果你有你的 Google API 密匙,你可以跳过这一节;否则,看看下面的视频。当你想初始化youtube-easy-api
模块时,你必须通过API_KEY
。
从 PyPI 服务器安装模块
首先你要从 PyPI 服务器安装 Google 开发的必备库如下:google-api-python-client
、google-auth-oauthlib
、google
。然后,您可以使用pip
命令安装youtube-easy-api
模块,类似于上面的库。
pip3 install youtube-easy-api
这个模块提供了一个简单的界面来提取 Youtube 视频元数据,包括标题、评论和统计数据。你…
pypi.org](https://pypi.org/project/youtube-easy-api/)
现在,您可以开始使用该模块了…
youtube-easy-api
模块目前支持两种方法search_videos
和get_metadata
。
-如何在 YouTube 视频中搜索
您可以指定一个关键字,并使用search_videos
方法在所有 YouTube 视频中进行搜索。这个方法接受一个search_keyword
并返回一个有序的字典列表,每个字典包含video_id
、title
和channel
。你可以在下面找到一个例子。必须在初始化步骤通过API_KEY
。
from youtube_easy_api.easy_wrapper import *
easy_wrapper = YoutubeEasyWrapper()
easy_wrapper.initialize(api_key=API_KEY)
results = easy_wrapper.search_videos(search_keyword='python',
order='relevance')
order
参数指定 API 响应中使用的排序方法。默认值是relevance
(即,按照与搜索查询的相关性排序)。根据原始 API 文档,其他可接受的值如下。
date
—按时间倒序排序(创建日期)rating
—从最高评级到最低评级排序viewCount
—按视图数量从高到低排序
如上所述,search_videos
方法返回一个字典列表。如果使用上面的调用,结果的第一个元素如下。
results[0]['video_id'] = 'rfscVS0vtbw'
results[0]['title'] = 'Learn Python - Full Course for Beginners ...[Tutorial]'
results[0]['channel'] = 'freeCodeCamp.org'
-如何提取 YouTube 视频的元数据
有了video_id
,就可以提取所有相关的元数据,包括标题、评论和统计数据。注意,URL 中还使用了video_id
。因此,您可以使用search_videos
方法、网页抓取工具或手动选择来检索video_id
。你可以在下面找到一个例子。必须在初始化步骤通过API_KEY
。
from youtube_easy_api.easy_wrapper import *
easy_wrapper = YoutubeEasyWrapper()
easy_wrapper.initialize(api_key=API_KEY)
metadata = easy_wrapper.get_metadata(video_id=VIDEO_ID)
最终可以提取出metadata
字典中存储的title
、description
、statistics
、contentDetails
、comments
等所有 YouTube 视频元数据;get_metadata
方法的输出。你可以在下面找到一个例子。
metadata = easy_wrapper.get_metadata(video_id='f3lUEnMaiAU')
print(metadata['comments][0])'Jack ma is like your drunk uncle trying to teach you a life lesson. Elon musk is like a robot trying to imitate a human'
现在,您可以访问情感分析项目所需的所有数据。还有一点,你有一个每天调用谷歌设置的这项服务的限额。因此,如果超过这个限制,您将会遇到一个错误。你必须等待第二天或认购增加你的每日限额。
感谢阅读!
如果你喜欢这个帖子,想支持我…
[## 通过我的推荐链接加入 Medium—Pedram Ataee 博士
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
pedram-ataee.medium.com](https://pedram-ataee.medium.com/membership)
关于深度学习和 Keras 的情感分析的简单教程
了解如何轻松构建、训练和验证递归神经网络
艾莉娜·格鲁布尼亚克在 Unsplash 上的照片
放松点,这将会花你几分钟的时间来阅读,但是希望你能坚持看完整篇文章。我将带您完成一项基础任务,作为数据科学家/机器学习工程师,您必须知道如何执行这项任务,因为在您职业生涯的某个阶段,您会被要求这样做。在本文的上下文中,我假设您对我接下来要讲的内容有一个基本的理解。我会在前进的过程中不断积累概念,保持一种非常低级的语言——如果你在字里行间感到有些困惑,不要担心,稍后我可能会澄清你的疑问。主要意思是让你明白我将要解释的内容。话虽如此,还是动手吧(顺便说一句,不要错过任何细节,从我的回购下载整个项目。)
我将首先定义标题中的第一个不常见的术语:情感分析是文本分类中非常常见的术语,本质上是使用自然语言处理(通常简称为 NLP)+机器学习来解释和分类文本信息中的情感。想象一下确定一个产品的评论是正面还是负面的任务;你可以自己通过阅读来完成,对吗?但是当你工作的公司每天销售 2k 产品时会发生什么呢?你是不是假装看完所有的评论,手动分类?老实说,你的工作会是有史以来最糟糕的。这就是情绪分析的用武之地,它让你的生活和工作变得更加轻松。
让我们进入这个问题
有几种方法可以实现情感分析,每个数据科学家都有他/她自己喜欢的方法,我将通过一个非常简单的方法来指导你,这样你就可以理解它涉及的内容,但也可以建议你一些其他的方法来研究它们。让我们先把重要的事情放在第一位:如果你不熟悉机器学习,你必须知道所有的算法只能理解和处理数字数据(尤其是浮点数据),因此你不能给它们输入文本,然后等着它们来解决你的问题;相反,您必须对数据进行几次转换,直到它达到一个有代表性的数字形状。常见且最基本的步骤是:
- 从每个样本中删除网址和电子邮件地址——因为它们不会增加有意义的价值。
- 去掉标点符号——否则你的模型不会理解“好!”和“好”其实是一个意思。
- 全部文本小写——因为您希望输入文本尽可能通用,并避免出现这种情况,例如,短语开头的“good”与另一个示例中的“Good”理解不同。
- 删除停用词——因为它们只会增加噪音,不会让数据更有意义。顺便说一下,停用词指的是一种语言中最常见的词,如“我”、“有”、“是”等。我希望你明白这一点,因为没有一个官方的停用词列表。
- 词干化/词汇化:这一步是可选的,但是对于大多数数据科学家来说是至关重要的。我会告诉你,取得好的结果并不重要。词干化和词汇化是非常相似的任务,都期望从语料库数据的句子的每个单词中提取词根。词汇化通常返回有效的单词(存在的),而词干技术返回(大多数情况下)缩短的单词,这就是为什么词汇化在现实世界的实现中使用得更多。lemmatizers vs. stemmers 的工作方式是这样的:假设你想找到“caring”的词根:“Caring”->lemmatizer->“Care”。另一方面:‘牵挂’->词干->‘车’;你明白了吗?如果业务需要,您可以研究这两种方法并实施其中任何一种。
- 将数据集(文本)转换成数字张量——通常称为矢量化。如果你记得上面的一些行,我解释过,像所有其他神经网络一样,深度学习模型不接受原始文本作为输入:它们只对数字张量起作用,这就是为什么这一步没有商量的余地。有多种方法可以做到这一点;例如,如果你要使用一个经典的 ML 模型(不是 DL ),那么你肯定应该使用 CountVectorizer、TFIDF Vectorizer 或者只是基本的但不太好的方法:单词袋。这取决于你。然而,如果你打算实现深度学习,你可能知道最好的方法是将你的文本数据(可以理解为单词序列或字符序列)转化为低维浮点向量——不要担心,我稍后会解释这一点。
这是一个非常基本的文本清理 Python 函数的样子(这是一个非常简单的方法,您可以实现一个最适合您的目的的方法—外面有非常完整的库,如 Gensim 或 NLTK):
def depure_data(data):
*#Removing URLs with a regular expression*
url_pattern = re.compile(r'https?://\S+|www\.\S+')
data = url_pattern.sub(r'', data)
*# Remove Emails*
data = re.sub('\S*@\S*\s?', '', data)
*# Remove new line characters*
data = re.sub('\s+', ' ', data)
*# Remove distracting single quotes*
data = re.sub("**\'**", "", data)
return data
根据最短和最长的单词通常没有用的想法,现在有一个非常简单的方法来从数据集中删除重复的单词:
def sent_to_words(sentences):
for sentence **in** sentences:
yield(gensim.utils.simple_preprocess(str(sentence), deacc=True))
最后,一个去除所有句子标记的函数(这是因为我将使用单词嵌入,而不是这种老式的标记方法):
def detokenize(text):
return TreebankWordDetokenizer().detokenize(text)
要以正确的顺序运行一切,您只需运行以下命令:
temp = []
*#Splitting pd.Series to list*
data_to_list = train['selected_text'].values.tolist()
for i **in** range(len(data_to_list)):
temp.append(depure_data(data_to_list[i]))
data_words = list(sent_to_words(temp))
data = []
for i **in** range(len(data_words)):
data.append(detokenize(data_words[i]))
print(data[:5])
此时,您已经将嘈杂的文本数据集转换成了一个非常简单的文本数据集。在这个特殊的例子中,你会从这个:
['I`d have responded, if I were going',
'Sooo SAD',
'bullying me',
'leave me alone',
'Sons of ****,']
对此:
['have responded if were going', 'sooo sad', 'bullying me', 'leave me alone', 'sons of']
如果你想更进一步,那么走词干化或词尾化的道路,你会得到更好的结果。在这个具体的操作方法中,将保持这种方式,只有你可以跳过这一步,完全有可能取得伟大的成果(如果你在商业环境中建立你的模型,那么你将 100%有义务这样做,不要跳过它!)
从句子到单词嵌入
好了,是时候理解在处理文本数据时必须处理的一个极其重要的步骤了。一旦您的文本数据完全清除了噪声,就该将它转换成浮点张量了。为了完成这个任务,我们将使用单词嵌入。
单词嵌入(或有时称为单词向量)从数据中学习,本质上是低维浮点向量(密集向量,与从诸如 one-hot-encoding 等过程中获得的稀疏向量相反),其在几个维度中打包信息。为什么你会使用这种方法而不是其他不同的更简单的方法呢?因为深度学习模型用密集向量比用稀疏向量更容易收敛。同样,它总是取决于数据集的性质和业务需求。
有两种方法可以获得单词嵌入:
- 在模型上使用预训练的单词嵌入堆栈,就像使用预训练的 NN 层(或层组)一样——这是一种非常少见的方法。
- 从头开始学习单词嵌入。为了实现这一点,你可以从随机单词向量开始,逐步学习有意义的单词向量,就像神经网络学习其权重一样。这是我们将使用的选项,实际上,随着每一个新任务学习一个新的嵌入空间是合理的。幸运的是,对于 TensorFlow 或 Keras,这一步非常简单,您可以实现单词嵌入,就像在 NN 堆栈中增加一层一样。
在前进之前,我们需要迈出前一步。我们需要将文本数组转换成 2D 数字数组:
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
from keras import regularizers
max_words = 5000
max_len = 200
tokenizer = Tokenizer(num_words=max_words)
tokenizer.fit_on_texts(data)
sequences = tokenizer.texts_to_sequences(data)
tweets = pad_sequences(sequences, maxlen=max_len)
print(tweets)
您将得到的输出如下所示:
[[ 0 0 0 ... 68 146 41]
[ 0 0 0 ... 0 397 65]
[ 0 0 0 ... 0 0 11]
...
[ 0 0 0 ... 372 10 3]
[ 0 0 0 ... 24 542 4]
[ 0 0 0 ... 2424 199 657]]
上一步是什么意思?让我们从官方的 Keras 文档中获取定义,您会更好地理解这一点:
这个函数将序列列表(长度为
num_samples
)转换成形状为(num_samples, num_timesteps)
的 2D Numpy 数组。num_timesteps
或者是maxlen
参数(如果提供的话),或者是列表中最长序列的长度。比
num_timesteps
短的序列用value
填充,直到它们长到num_timesteps
。长于
num_timesteps
的序列被截断,以便符合所需的长度
嵌入层
非常重要的是你要记住,无论你使用 TensorFlow 还是其他任何as action API比如 Keras *、*在你的训练结束时你都应该得到相同的结果。在这次机会中,我们将使用 Keras,原因很明显:它非常容易实现。这是创建嵌入层的方法:
from keras.layers import Embedding
embedding_layer = Embedding(1000, 64)
上面的层采用形状的 2D 整数张量(样本,sequence_length)和至少两个参数:可能的记号的数量和嵌入的维数(这里分别是 1000 和 64)。更形象地说,只需想象嵌入层是一个将整数索引链接到密集向量的字典。最后,它返回一个形状的 3D 浮点张量(样本,序列长度,嵌入维数),现在可以由我们的神经网络处理。让我们来谈谈这个话题,特别是当需要处理文本相关序列时,递归神经网络是最好的。
递归神经网络变得简单
通常,其他类型的神经网络如密集连接网络或卷积网络没有记忆,这意味着每个输入都是独立处理的,与其他输入无关。这与你阅读一段文字时通常会做的事情相反:当你阅读时,你会在记忆中保留你在前面几行读到的内容,对吗?你有一个整体意义的感觉,这正是 RNNs 采用的原则。它们处理序列的方式是沿着序列元素进行迭代,并保存与迄今为止已处理的内容相关的信息。老实说,在 RNN 引擎盖下的数学是一个你应该自己去理解它的逻辑的话题。我建议你读一读汤姆·霍普的《学习张量流》(此处有),它以一种非常简单的方式解释了所有的过程。
在本文中,我将实现三种 RNN 类型:单一 LSTM(长短期记忆)模型、双向 LSTM 和很少使用的 Conv1D 模型。作为奖励,我展示了如何实现一个 SimpleRNN 模型,但老实说,它并没有在生产中部署,因为它非常简单。
LSTM 层
回到我们的例子,这是实现单个 LSTM 层模型及其相应的嵌入层时的代码:
from keras.models import Sequential
from keras import layers
from keras import regularizers
from keras import backend as K
from keras.callbacks import ModelCheckpointmodel1 = Sequential()
model1.add(layers.Embedding(max_words, 20)) #The embedding layer
model1.add(layers.LSTM(15,dropout=0.5)) #Our LSTM layer
model1.add(layers.Dense(3,activation='softmax'))
model1.compile(optimizer='rmsprop',loss='categorical_crossentropy', metrics=['accuracy'])
checkpoint1 = ModelCheckpoint("best_model1.hdf5", monitor='val_accuracy', verbose=1,save_best_only=True, mode='auto', period=1,save_weights_only=False)history = model1.fit(X_train, y_train, epochs=70,validation_data=(X_test, y_test),callbacks=[checkpoint1])
在上面的代码中有几件事情需要强调:当实现一个 Keras 顺序模型时,这都是关于堆叠层的。LSTM 图层(以及所有其他 RNN 图层)可以接受几个参数,但我定义的参数是 15 ,这是图层中隐藏单元的数量(必须是正整数,表示输出空间的维度)和图层的丢失率。 Dropout 是 NNs 最有效和最常用的正则化技术之一,包括在训练期间随机关闭隐藏单元,这样网络就不会 100%依赖于所有的神经元,而是迫使自己在数据中找到更有意义的模式,以增加你试图优化的指标。还有几个其他的参数要传递,你可以在这里找到完整的文档,但是对于这个特殊的例子,这些设置会达到很好的效果。
仅供参考,有时一个接一个地堆叠几个递归层是有用的,这样可以增加网络的代表性。如果你想这样做,那么你必须返回完整的输出序列。这是一个例子:
*model0 = Sequential()*
*model0.add(layers.Embedding(max_words, 15))*
*model0.add(layers.SimpleRNN(15,return_sequences=True))
model0.add(layers.SimpleRNN(15))
model0.add(layers.Dense(3,activation='softmax'))*
在我们的 LSTM 示例中,我堆叠了一个具有三个输出单元的密集图层,这三个输出单元将是数据集的 3 个可能的类。为了进行概率输出,最好在最后一层使用“softmax”作为激活函数。构建神经网络时使用下表,您会感到困惑:
神经网络配置和训练的基本参数。
当编译模型时,我使用 RMSprop optimizer 的默认学习速率,但实际上这取决于每个开发人员。有人爱 Adam,有人爱 Adadelta,以此类推。老实说,RMSprop 或 Adam 在大多数情况下应该足够了。如果您不知道优化器是什么,它只是一种不断计算损失梯度并定义如何逆着损失函数移动以找到其全局最小值并因此找到最佳网络参数(模型内核及其偏差权重)的机制。作为损失函数,我使用 categorical _ crossentropy(检查表格),它通常在处理多类分类任务时使用。另一方面,当需要二进制分类时,可以使用 binary_crossentropy。
最后,我使用检查点来保存在训练过程中获得的最佳模型。当您需要获得最能满足您试图优化的指标的模型时,这非常有用。然后是经典的 model.fit 步骤,等待它完成训练迭代。
这是该神经网络体系结构在上一个时期获得的验证分数:
Epoch 70/70
645/645 [==============================] - ETA: 0s - loss: 0.3090 - accuracy: 0.8881
Epoch 00070: val_accuracy did not improve from 0.84558
让我们用一个更复杂的网络来比较一下。
双向层
这是我们示例的 BidRNN 实现的样子:
model2 = Sequential()
model2.add(layers.Embedding(max_words, 40, input_length=max_len))
model2.add(layers.Bidirectional(layers.LSTM(20,dropout=0.6)))
model2.add(layers.Dense(3,activation='softmax'))
model2.compile(optimizer='rmsprop',loss='categorical_crossentropy', metrics=['accuracy'])
checkpoint2 = ModelCheckpoint("best_model2.hdf5", monitor='val_accuracy', verbose=1,save_best_only=True, mode='auto', period=1,save_weights_only=False)
history = model2.fit(X_train, y_train, epochs=70,validation_data=(X_test, y_test),callbacks=[checkpoint2])
让我们更好地理解双向层是如何工作的。它最大化了 rnn 的顺序敏感性:本质上,它由两个 rnn(lstm 或 gru)组成,这两个 rnn 在一个不同的方向上处理输入序列,以最终合并表示。通过这样做,他们能够捕捉到比单个 RNN 层更复杂的图案。换句话说,其中一层按时间顺序解释序列,第二层按反时间顺序解释,这就是为什么双向 rnn 被广泛使用,因为它们比常规 rnn 提供更好的性能。
它们的实现方式并不复杂,只是一层在另一层之内。如果你仔细阅读,我使用几乎相同的参数,但在其整体训练中实现了大约 0.3%的验证准确性:
Epoch 70/70
644/645 [============================>.] - ETA: 0s - loss: 0.2876 - accuracy: 0.8965
Epoch 00070: val_accuracy did not improve from 0.84849
这是一个非常好的数字,即使它是一个非常简单的模型,我并没有专注于超参数调整。我确信,如果你致力于调整它们,你会得到一个非常好的结果。不幸的是,没有神奇的公式可以做到这一点,这一切都是关于调整其架构,迫使它每次都学习更复杂的模式,并通过更多的正则化来控制其过度拟合的趋势。要强调的一件重要事情是,如果您看到您的模型精度/损失停留在某个值附近,这可能是因为学习率太小,因此使您的优化器停留在损失函数的局部最小值附近;增大 LR,或者尝试另一个优化器。
现在是时候尝试另一种类型的架构了,尽管它不是文本分类的最佳选择,但众所周知,它在处理文本数据集时会取得非常好的效果。让我们开始吧。
更进一步——1D 卷积神经网络
我希望你还和我在一起,因为这是谈论收敛时最快的模型之一——它需要更便宜的计算成本。根据以前的经验,我知道它倾向于在小数据集上非常快地过度拟合。从这个意义上来说,如果你感兴趣的话,我会实现它来告诉你怎么做,并且给你一个关于它如何工作的概述。
它使用与用于图像分类的经典 2D 变换网相同的原理。卷积层从 1D/2D 张量中提取面片(取决于任务和层的类型),并对每个面片应用相同的卷积变换(得到几个子序列作为输出)。我不会深入解释,因为这超出了本文的范围,但是如果你想完全理解这些层是如何工作的,我建议你查看一下之前推荐的书。这些层最重要的事实是,它们可以识别序列中的模式——在一个句子的某个位置学习的模式可以在后来的不同位置甚至在另一个句子中识别。
1D 通信网是这样实现的:
model3.add(layers.Embedding(max_words, 40, input_length=max_len))
model3.add(layers.Conv1D(20, 6, activation='relu',kernel_regularizer=regularizers.l1_l2(l1=2e-3, l2=2e-3),bias_regularizer=regularizers.l2(2e-3)))
model3.add(layers.MaxPooling1D(5))
model3.add(layers.Conv1D(20, 6, activation='relu',kernel_regularizer=regularizers.l1_l2(l1=2e-3, l2=2e-3),bias_regularizer=regularizers.l2(2e-3)))
model3.add(layers.GlobalMaxPooling1D())
model3.add(layers.Dense(3,activation='softmax'))
model3.compile(optimizer='rmsprop',loss='categorical_crossentropy',metrics=['acc'])
history = model3.fit(X_train, y_train, epochs=70,validation_data=(X_test, y_test))
其中 Conv1D 层负责计算 卷积运算,而 MaxPooling1D 层的主要任务是降低每个卷积输出的维度。一旦执行了卷积运算,MaxPooling 窗口将提取其中的最大值,并输出最大值的面片。在这种类型的配置中,强调正则化的重要性是很重要的,否则你的网络将会学习无意义的模式,并以极快的速度过度适应——仅供参考。
为了对比之前模型的表现,这是上一个时期达到的指标:
Epoch 70/70
645/645 [==============================] - 5s 7ms/step - loss: 0.3096 - acc: 0.9173 - val_loss: 0.5819 - val_acc: 0.8195
其最佳验证准确率约为 82%。即使我已经实施了非常激烈的调整,它还是过拟合得非常快。
验证我们的最佳模型
在这一点上,迄今为止最好的模型是双向 RNN。请记住,这些指标是通过从很少到零的超参数调整获得的。为了更好地理解它的预测,让我们看看它的混淆矩阵:
最佳模特的困惑矩阵-作者图片。
从上面的图像中,我们可以推断出:81%的正面评级被归类为正面,80%的负面评级被归类为负面,91%的中性评级被归类为中性。这些并不是最好的预测,但却是建立更好模型的良好基础。在商业场景中,在最简单的情况下,您需要接近 95%。
如果您想测试它如何处理您自己的输入,只需计算下面几行:
sentiment = ['Neutral','Negative','Positive']sequence = tokenizer.texts_to_sequences(['this data science article is the best ever'])
test = pad_sequences(sequence, maxlen=max_len)
sentiment[np.around(best_model.predict(test), decimals=0).argmax(axis=1)[0]]
输出将是:
'Positive'
最后的想法
好了,我们已经到了这篇文章的结尾。我鼓励您自己实现所有模型,并专注于超参数调优,这是需要较长时间的任务之一。一旦你达到一个好的数字,我会在这里见你,指导你通过该模型的部署😊。
有几种方法可以完成这样的任务。你可以使用谷歌云平台,走 Azure 之路,甚至更便宜的 Heroku 之路,但让我们诚实地说:大多数最大的公司都采用 AWS 作为他们的主要公共云提供商,这些家伙有一个奇妙的平台来构建、培训和部署 ML 模型:AWS SageMaker;那里有大量的文档。我将会发布另一个逐步讲解的教程,讲述如何在上面轻松地部署模型。我希望在那里见到你!
在 Tableau 上绘制蜘蛛图的简单方法——第二部分
用 Excel 在 Tableau 上编织蜘蛛图
在上一篇文章《在 Tableau 上画蜘蛛图的简易方法—第一部分》的最后,我们留下了一个问题:如何为我们的“蜘蛛”提供一个“web”背景。
有许多教程文章和视频教人们如何使用 Tableau 上的计算来绘制雷达背景,但我发现它们有点复杂,难以理解。我开发了这个简单的方法来从 Excel 中获取背景“web ”,并将“web”作为图片导入 Tableau。这非常简单明了,所以为什么不试着从现在开始“编织你自己的网”呢?
在本文中,我仍将使用第一部分中相同的大学排名示例来帮助您更好地理解这些步骤。
> > >第一步:在 Excel 绘制一张“网”
既然我们有 6 类**【品质】**,我们也应该在 Excel 中编织一个由 6 个角组成的网。
打开一个 Excel >复制 6 种品质及其分数并粘贴到 Excel > 【插入】 > 【图表】 > 【雷达】
删除图表上的所有标题、轴和标签>删除所有分数
在 Excel 中复制图表并将其粘贴为图片在 Microsoft Word 中将网页图片保存到您的本地设备
> > >第二步:将“web”导入 Tableau
在雷达图页中,点击**【地图】** > 【背景图像】 > 【添加图像…】
在**【浏览】** >中找到你的网页图片,选择合适的级别**【冲洗】**
> > >第三步:格式化【网页】
为 X 轴和 Y 轴找到合适的左右边框:
X 轴左侧= X 轴最小值,X 轴右侧= X 轴最大值
Y 轴底部= Y 轴最小值,Y 轴顶部= Y 轴最大值
删除所有的标题,标题,轴和边框,你将得到一个网络背景的雷达图!
为了让它更好看更可爱,你可以随心所欲地改变颜色、字体和形状!
如果您对本文有任何疑问,请随时联系我!我期待与您讨论数据科学和数据可视化!🙋♂️
一种在 Tableau 上绘制蜘蛛图的简单方法——第一部分
你厌倦了饼状图吗?试试蜘蛛图!
蜘蛛图也称为雷达图,它可以用来描述三维或三维以上的定量数据。基本上,每当你想用饼状图分析数据的时候,你都可以考虑是否要尝试更高级的雷达图。
Tableau 是现在最流行的数据可视化工具之一,但它没有内置的蜘蛛图。我读了许多关于如何在 Tableau 上构建雷达图的文章,在尝试了许多其他复杂的方法后,我找到了这个非常简单的方法。
在这篇文章中,我将使用 Kaggle 上发布的 2015 年加拿大大学排名数据集作为例子,尝试从就业、师资、出版、影响力、广度和专利 6 个维度来比较加拿大的大学。
数据集预览
让我们先看看我在 Tableau 上创建的雷达图。你也可以在 这里 **找到我在 Tableau 上创建的雷达图。**👈
> > >第一步:透视表数据
按住**【Ctrl】选择全部 6 个品质>右键>点击【支点】**
确保维度**【质量】名称在一列,维度的值【得分】**在另一列。
透视后的数据表
> > >第二步:创建计算字段
№1。【路径】
创建计算字段
**【路径】**字段告诉 Tableau“网络”应该走的顺序。
CASE [Quality]
WHEN 'employment' THEN 1
WHEN 'broad' THEN 2
WHEN 'influence' THEN 3
WHEN 'patents' THEN 4
WHEN 'publications' THEN 5
WHEN 'faculty' THEN 6
END
№2。【X 轴】
我们将使用 T 精确测量来指示我们的“蜘蛛网”的每个角的方向,X 轴是角度的 cos 值,Y 轴是坐标角度的 sin 值。
作者 乔纳森·特拉科维奇
例如,我们希望“就业”位于 30°方向,那么“就业”的 X 轴是[分数]* cos 30 =[分数](SQRT(3)/2),Y 轴将是[分数] sin 30 =[分数]*(1/2)
因为我们有 6 个维度划分 360 度,所以每个维度将位于 30 度、90 度、150 度、210 度、270 度和 330 度。
CASE [Quality]
WHEN 'employment' THEN [Score]*(SQRT(3)/2)
WHEN 'broad' THEN 0
WHEN 'influence' THEN [Score]*(-SQRT(3)/2)
WHEN 'patents' THEN [Score]*(-SQRT(3)/2)
WHEN 'publications' THEN 0
WHEN 'faculty' THEN [Score]*(SQRT(3)/2)
END
№3。【Y 轴】
CASE [Quality]
WHEN 'employment' THEN [Score]*(1/2)
WHEN 'broad' THEN [Score]*1
WHEN 'influence' THEN [Score]*(1/2)
WHEN 'patents' THEN [Score]*(-1/2)
WHEN 'publications' THEN [Score]*(-1)
WHEN 'faculty' THEN [Score]*(-1/2)
END
> > >第三步:筛选一所大学
将**【大学】**文件拖到“过滤器”框中,例如我选择了“女王大学”。
> > >第四步:构建多边形
- 将**【X 轴】**拖动到“列”中
- 将**【Y 轴】**拖动到“行”中
3.将**【质量】**拖到“细节”中
4.将**【路径】**拖动到“路径”中
然后我们得到了这个图表,嗯…😒看起来很“蠢”?放心吧!我们会在最后格式化它。
> > >第五步:绘制点数&标签
- 复制一个 Y 轴
- 将两个图表中的一个更改为“形状”
- 将**【质量】**拖入“标签”
- 将**【质量】**拖动成‘形状’
5.右键单击“形状”图>的**【Y 轴】**,单击【双轴】>选择【同步轴】
然后我们会得到这张图表。
> > >第六步:格式化
我们需要进行大量的格式化工作:
- 改变轴到固定和相同的长度和宽度。(这里 X: -300,+300,Y: -300,+300)
- 为多边形选择一种你喜欢的颜色,使其透明,也许可以给它添加一个边框。
- 更改标签的字体。
- 移除所有的边框和所有的线。
- 将**【大学】【质量】【分数】**添加到‘工具提示’中
最后,我们得到了雷达图。耶!!!!🥳:但是等等……这似乎和普通的雷达图有点不同?—我们没有为它提供一个“网”!
放心吧!我将在下一篇文章 中展示如何为我们的“蜘蛛”手动绘制背景“网”——一种在 Tableau 上绘制蜘蛛图的简单方法——第二部分 。👈与其他展示如何使用 Tableau 编码来绘制它的文章不同,我将使用一点“技巧”来使这个过程更容易和简单。
如果您对本文有任何疑问,请随时联系我!我期待与您讨论数据科学和数据可视化!🙋♂️
在自己的计算机上开始使用数据库的简单方法
结构化查询语言
介绍如何使用 SQLite 浏览器和管理自己的数据库。
由 djvstock 创建的技术向量
根据 StackOverflow 2020 开发者调查,SQL 是第三大最受开发者欢迎的语言。每个人都知道应该学习使用 SQL,但是实际创建和管理数据库又如何呢?
虽然您可以学习一些课程,让您在带有预定义表的浏览器上使用 SQL(这是一种不错的学习方法),但体验创建、管理自己的数据库并与之交互也是很有价值的。
SQLite 的 DB 浏览器( DB4S )是一个让任何人都可以访问关系数据库的工具。它允许您与 SQLite 数据库进行交互,整个数据库包含在一个文件中。运行它不需要服务器或大量配置。DB4S 和 SQLite 都是免费的!
如果您没有任何使用数据库或 SQL 的经验,这是一个可以帮助您快速掌握基础知识的工具。DB4S 有一个类似于 Excel 的电子表格界面,这意味着您可以在自己的数据库中创建和编辑表格,而无需使用 SQL。您还可以选择编写定制的 SQL 查询并查看结果。
使用 DB4S 是亲手创建和使用关系数据库的好方法。这篇文章将帮助您开始使用该工具。本演练分为 7 个部分:
- 在您自己的机器上安装和设置
- 创建数据库文件
- 使用 CSV 文件导入和导出表格
- 添加、修改和删除行(记录)和列
- 搜索和过滤记录
- 运行 SQL 查询
- 用图形或 SQL 查询可视化数据
1.在您自己的机器上安装和设置
你可以在 DB4S 网站这里查看安装细节。你可以下载 Windows 和 macOS 的最新版本。它也适用于基于 Linux 的发行版。
如果您在 macOS 上安装了 Homebrew,您也可以使用以下命令行安装最新版本:
brew cask install db-browser-for-sqlite
一旦在机器上安装了 DB4S,打开应用程序,就可以开始了!
2.创建数据库文件
当您打开 DB4S 时,在左上角会看到一个标有“New Database”的按钮。点击它,为你的数据库输入一个名字,然后点击“保存”到你想要的文件夹。
示例 SQLite 数据库创建
就是这样!您已经创建了第一个 SQL 数据库。您现在应该会看到:
空 SQLite 数据库
3.使用 CSV 文件导入和导出表格
现在让我们创建我们的第一个表。为此,我们将导入一个 CSV 文件,其中包含 Medium 热门页面上的部分元数据。我在一个早期的 Python 项目中获得了数据,你可以在这里查看。
CSV 看起来像这样:
中等流行页面元数据的 CSV 文件
要在 DB4S 上用这个文件创建一个表,您需要:
File > Import > Table from CSV file...
导入 CSV 以创建表格
之后,选择你想要的 CSV 文件并点击“打开”。
导入 CSV 以创建表格
这将在另一个窗口中提示几个定制选项。把名字改成容易记住的。如果列标题已经在您的 CSV 文件的第一行中,那么勾选复选框以确保 DB4S 能够识别它。它将移动第一行成为列名。然后点击“确定”。
导入 CSV 以创建表格
然后嘣!您已经创建了第一个表格。
将数据库文件导出为 CSV 文件同样简单。你所要做的就是在表格上点击右键,然后点击“导出为 CSV 文件”。
将表格导出到 CSV
或者要批量导出多个表,请执行以下操作:
File > Export > Table(s) as CSV file...
4.添加、修改和删除行(记录)和列
现在来看看我们在 DB4S 上的表。右键单击表格并选择“浏览表格”。
在 DB4S 中查看表
现在,您将看到一个经典的电子表格格式的表格。
在 DB4S 中查看表
如果您想添加一个新行,只需单击“New Record”,DB4S 就会创建一个新行(已经有了一个主键)供您填入值,就像在 Excel 上一样。在这种情况下,我们可能希望每次在 Medium 的热门页面中添加新内容时都这样做。如果数据库中已经存在值,DB4S 甚至会根据您输入的第一个字母建议一个行值。
在 DB4S 中添加记录
要删除一行,你只需要选择一行(点击最左边一列的主键),然后点击“删除记录”。
删除 DB4S 中的记录
完成所有更改后,单击“写入更改”保存所有修改并更新数据库中的表格。
将更改保存到 DB4S 中已编辑的表
现在,在表格上,您可以看到有一个名为“字段 1”的列。这是因为我的 CSV 摘录已经包含了一个索引列。由于 DB4S 会自动创建索引,所以我不再需要这个专栏了。
编写 SQLite 查询将允许您对表模式进行一些更改,但是没有单行的“删除列”功能可用。 SQLite docs 将为您提供一个如何删除列的变通方法,包括创建一个只包含所需列的新表,将数据从旧表复制到新表,并删除旧表。
在 DB4S 中,删除一列要简单得多。要删除列,请在数据库结构选项卡中,右键单击所需的表,然后单击“修改表”。
在 DB4S 中修改表
您将看到表中当前列的列表。选择您要删除的列,然后单击“删除字段”和“是”。
在 DB4S 中修改表
如果我们回到“浏览表”,我们会看到“字段 1”不再在表中。
检查表中 DB4S 的变化
5.搜索和过滤记录
早些时候,我们添加了作者为“Dana G Smith”的记录。如果我们想在表中查找 Dana 发表的所有文章,我们只需要在“Author”下的“Filter”框中写下名字。
在 DB4S 中过滤表
您也可以一次按多列添加筛选。如果我们想找到 2019 年所有阅读时间为 11 分钟的文章,你只需要填写两个过滤器列。表格会自动刷新,只显示您需要的结果。
在 DB4S 中过滤表
6.运行 SQL 查询
您可以通过“执行 SQL”选项卡运行各种 SQLite 查询。例如,如果我们想要查看阅读时间为 5 的所有文章,只需像前面一样在过滤器列中键入“5”就会显示一些不想要的结果。在这种情况下,我们还会得到阅读时间为“15”的文章。
我们不想在过滤器中看到的样本数据
为了解决这个问题,我们将编写一个基本的 SQL 查询来过滤结果,使读取时间仅为 5。
SELECT * FROM popular_metadata
WHERE "ReadingTime(mins)" = '5';
在 DB4S 上运行 SQL 查询
您可以轻松地将过滤后的结果保存到 CSV 文件中。点击下面圈出的按钮,选择“导出到 CSV”。
在 DB4S 上保存 SQL 查询
然后,您可以配置 CSV 输出并选择输出文件的位置。
在 DB4S 上保存 SQL 查询
您的结果文件现在将被过滤,只包含阅读时间为“5”的文章。
DB4S 中保存的 SQL 查询的 CSV 输出
7.用图形或 SQL 查询可视化数据
假设我们想要创建一个图表,查看一段时间内每天文章的总阅读时间。要在不使用任何 SQL 的情况下做到这一点,我们可以使用 DB4S plot 函数。点击“查看”,然后选择“绘图”。
不使用 SQL 在 DB4S 上绘制数据
这将打开一个新的对话框,让您选择要在图形的 X 轴和 Y 轴上显示哪些列。下面,我选择了“出版日期”和“阅读时间(分钟)”。DB4S 生成了一个条形图,向我显示每天以分钟为单位的阅读时间。
不使用 SQL 在 DB4S 上绘制数据
您还可以从 SQL 查询中生成图表。假设我们想统计每天发表的文章数量。我们可以编写一个简单的“GROUP BY”查询,并用图表显示结果。
首先,回到之前演示的“执行 SQL”窗口。然后填写您的 SQL 查询,运行它,单击“Plot ”,并为您的轴选择列。您将看到 SQL 查询生成的表格的图形版本。
用 SQL 在 DB4S 上绘制数据
到目前为止,我们已经使用 DB4S 完成了您自己的关系数据库的完整设置和使用!该工具简单的可视化界面允许您轻松开始创建和管理 SQLite 数据库。在您熟悉了这一点之后,我们还看了如何实际使用该工具来运行 SQL 查询,甚至用简单的图形来可视化数据。
这篇文章旨在帮助你开始。为了进一步阅读,我强烈推荐查看一下 SQLite 文档和 DB4S 文档。
如果你想看看如何使用 Pandas 向数据库写入数据,请随意查看这篇文章:
谁知道您可以在没有任何 SQL 的情况下添加到数据库中呢?
towardsdatascience.com](/using-just-one-line-of-code-to-write-to-a-relational-database-3ed08a643c5f)