艺术风格的神经算法:总结与实现
使用 Pytorch 进行风格转换
神经风格,或神经转移,允许用一种新的艺术风格再现一幅给定的图像。在这里,我介绍由 Leon A. Gatys、Alexander S. Ecker 和 Matthias Bethge 提出的神经式算法。该算法接收样式图像、内容图像和输入图像,输入图像可以是空白的白色图像或内容图像的副本。因此,它改变输入图像,使其类似于后一个图像的内容和前一个图像的风格。在开始之前,我想感谢亚历克西斯·雅克的文章。
原则
虽然这个名字可能会让你认为它确实是将样式转移到另一个图像中,但是这个想法是生成一个内容和样式图像之间距离最小的图像。因此,甚至有可能从一个完全白色的图像开始,并实现期望的结果,这是本文中提出的。关于技术细节,总体想法是使用预先训练的网络,并通过反向传播最小化这些距离。
细节
卷积神经网络(CNN)摘自本文。
如上所述,该算法需要三幅图像,目标是生成一幅内容和样式图像之间距离最小的图像。为了实现这一点,作者使用预训练的 VGG-19 网络,并计算输入图像和目标图像(内容和风格图像)的特征图之间的距离。因此,他们计算了 CNN 特定层面的内容和风格损失。
内容损失
内容损失摘自本文。
作者使用平方误差损失来测量内容图像和输入图像的特征表示之间的距离,分别表示为 P 和 F。
风格丧失
为了计算风格损失,作者使用了 Gram 矩阵。因此,我们通过展平以[N,C,W,H]的形式给出的输入来获取所有 C 个特征向量,导致它具有[N x C,W x H]的形状。最后,我们将这个矩阵与它自身的转置相乘,得到一个 Gram 矩阵,它给出了我们的特征相关性。最后,风格损失由风格和输入 gram 矩阵之间的平方误差损失给出。
全损
总损失摘自本文。
总损失是两个损失的加权和。作者提到,默认比率α/β要么是 1×10^−3,要么是 1 × 10^−4.
模型和标准化
我们将导入 VGG-19 预训练网络,因此我们还需要通过减去平均值并除以标准偏差来归一化我们的图像。
最后,我们将计算 VGG-19 在特定深度层的损失。此外,作者提到用平均层替换最大池层会产生更平滑的图像。因此,我们需要一个新的顺序模块来包含所有这些。
训练详情
与训练网络不同,我们希望优化输入图像。因此,我们使用 L-BFGS 算法来运行我们的梯度下降,并将我们的图像作为张量传递给它进行优化。比率α/β是 1×10^−6.
结果
上图显示了内容和样式图像以及生成的输入图像。此外,您可以看到我们的输入图像在整个梯度下降过程中是如何变化的。
哈萨克斯坦阿斯塔纳。
最后,我想再展示几张我喜欢的图片:)。
哈萨克斯坦阿拉木图。
俄罗斯莫斯科。
一些遗言
我提出了一个简单而有趣的基于 CNN 的算法。然而,已经有更多的方法以不同的方式完成这项任务,特别是在实时情况下。如果你有兴趣,鼓励你进一步研究这个领域。完整的代码可以在我的 GitHub 上找到。
纸
相关文章
https://medium.com/tensorflow/neural-style-transfer-creating-art-with-deep-learning-using-tf-keras-and-eager-execution-7d541ac31398 https://medium.com/artists-and-machine-intelligence/neural-artistic-style-transfer-a-comprehensive-look-f54d8649c199
一种新的反人脸识别系统
LowKey 是由马里兰大学的研究人员开发的一种新的反面部识别系统。了解它是如何工作的。
托拜厄斯·图利乌斯在 Unsplash 上的照片
随着深度学习的改进,面部识别软件变得越来越强大。相应的,面部识别软件的隐私担忧也增加了。许多面部识别系统通过抓取互联网上公开的图片来建立数据库,这意味着你的脸可能在你不知道的情况下存在于某个数据库中。避免这个问题的一个方法是不要把你的脸贴到网上。然而,在社交媒体时代,这可能是不可行的。另一种解决方案是改变图像来欺骗面部识别软件,同时保持图像质量,以便您仍然可以使用该图像。这是马里兰大学的一些研究人员发明的“低调”方法。
LowKey 利用了这样一个事实,即大多数面部识别系统都是使用神经网络构建的,众所周知,神经网络对于对抗性攻击很脆弱。对抗性攻击是对神经网络输入的微小改变,导致网络对输入进行错误分类。理想情况下,用例如下。你对一张自拍进行低调的对抗性攻击,然后上传到互联网上。这张低调的照片是由面部识别数据库拍摄的。稍后,您走到外面,监控摄像头拍下您的照片(称为“探头图像”)。但是,它无法将您的探头图像与数据库中的低调图像进行匹配。你安全了。
来源:低调的论文
详情:
LowKey 的目标是在所有面部识别深度学习系统中表现良好。然而,我们不知道我们试图击败的一些深度学习系统的架构。如果我们训练我们的对抗性攻击来击败我们可以访问的一个特定的面部识别神经网络,我们不能保证这将在现场对抗其他网络。这个问题没有完美的解决方案。
低调的研究人员决定在当前最好的开源面部识别神经网络的集合上训练他们的对抗性攻击,希望模型的集合能够让他们的攻击具有更好的推广性。首先,对于集合中的每个模型,研究人员在输入图像上计算该模型的输出。然后,他们对输入图像应用低调对抗性攻击,并使用低调修改的图像作为输入来计算模型的输出。接下来,他们计算两个输出之间的差异。他们对集合中的每个模型都这样做,然后计算差异的总和。他们的目标是使这个总数最大化。这个和越大,面部识别神经网络就越不可能将真实图像和低调修改的图像分类为相同的。
其次,研究人员希望修改后的图像仍然能够被人类识别。为了实现这一目标,他们决定最小化原始图像和低调图像的 LPIPS 指标。 LPIPS (学习感知图像块相似度)是两幅图像之间基于人类的相似性度量。较低的 LPIPS 意味着较高的相似性。
因此,LowKey 有两个目标:基于开源面部识别模型的集合最大化原始图像和 LowKey 图像之间的距离,以及最小化相同两幅图像之间的 LPIPS。在数学符号中,总目标可以写成:
来源:低调的报纸
澄清:
- x 是原始图像
- “x”是低调的形象
- n 是训练集合中模型的数量
- f_i 是第 I 个系综模型
- a 是图像预处理函数
- g 是高斯平滑函数
请注意,第一个目标有两个版本,一个有高斯平滑函数,另一个没有。研究人员包括了高斯平滑函数版本,因为它改善了结果。利用梯度上升训练总目标,并且最终的 x’作为低调图像输出。
低调的研究人员发布了一个在线网络工具,如果你想自己试试的话。这里可以找到这里。例如,这是它对样本图像所做的操作:
资料来源:Unsplash的 Ali Kazal】
结果和限制:
研究人员通过尝试破解两个商业可用的面部识别 API 来测试 LowKey,即亚马逊 Rekognition 和微软 Azure Face。在这两种 API 上,LowKey 都能够保护用户的面部,因此他们被识别的概率低于 3%。在没有低调保护的情况下,两个面部识别系统识别面部的准确率超过 90%。这是一个巨大的差异。
然而,当与其他可能是机密的面部识别系统进行测试时,LowKey 是否也能工作,还有待观察。此外,面部识别系统绕过低调保护的一种方法是用低调图像作为训练数据的一部分来训练系统。这可能会导致一场军备竞赛,其中像 LowKey 这样的反面部识别算法被发布,面部识别公司通过训练考虑到该算法的新模型来做出反应,导致新算法被发布,等等。换句话说,低调有一天可能不再有效。
然而,不管这些疑虑,LowKey 是在互联网和机器学习时代迈向隐私的重要一步。LowKey 证明了一个直观简单的对抗性攻击可以欺骗当前的图像识别系统,同时保持图像质量。更多详情,请参考原文此处。
电影制作的新方法
对电影统计数据的探索性数据分析显示,一种新的趋势已经掌控了这个行业,并已经为一些关键角色创造了巨额利润。
自 19 世纪诞生以来,电影业已经取得了长足的发展,不仅成为我们日常生活中的主要娱乐来源,也成为我们现代社会的核心文化支柱。随着新技术的发展,这种增长已经达到了全球水平,电影制作人现在能够接触到世界各地的观众。
强调一些关键数字:2019 年全球票房价值 422 亿美元(其次是 2020 年因新冠肺炎疫情而受到重创)。仅在美国,自 2000 年以来每年制作的电影数量就增长了 4 倍,从 200 部增长到 2019 年的 800 部。
当然,衡量这个行业的标准不再仅仅包括票房数字,自 20 世纪 90 年代以来,电视连续剧在我们的日常娱乐中占据了更加突出的位置,特别是随着网飞或 Prime Video 等流媒体平台的出现。今天,随着大多数人拥有至少一个流媒体服务订阅,我们发现自己处于“流媒体战争”的新时代。目前,流媒体方式的主要传播者网飞(净资产:400 亿美元)以 2.0764 亿用户保持着领先地位,其中大部分用户位于美国和加拿大。紧随其后的是 Prime Video,亚马逊拥有 2 亿 Prime 服务用户。
显然,今天这种媒体的力量及其接触世界各地受众的能力怎么强调都不为过。然而,虽然电影的主要目的是娱乐,但重要的是要注意到它们的额外作用,既作为社会、社会规范和价值观的反映,有时也作为其影响者。
电影已经成为我们文化和历史的重要组成部分。因此,它们也可以被看作是我们过去的记录——它们清楚地反映了当时的社会状况。在他们各自的情节中,他们描绘了当时社会所持有的当代价值观、趋势、问题和信仰。
然而,社会是可塑的。它随着时间的推移而发展和变化。因此,在过去 100 年的每十年里,我们都会看到反映社会意识形态和规范变化的主流电影。关于这种变化的例子,只要看看《007:邦德:T1》系列电影就知道了。我们只需要考虑一下 007 的反派角色的演变,就可以把他们和当时的政治形势联系起来。
今天,电影业出现了一种新趋势,反映了当前的社会变化。这一趋势就是多元化,忽视这一趋势可能会让电影制作人损失数百万未开发的收入。
为了理解这一新趋势,我采用了数据驱动的方法来探索电影制作行业与多元化相关的关键方面。
I .电影业的地理多样性
正如我们所知,作为电影业发展的发源地,好莱坞长期以来一直主导着全球舞台。因此,过去几十年主要见证了美国文化的各种状态主导了屏幕,明显反映了美国在二战后崛起为超级大国,在苏联解体后的 20 世纪 90 年代达到了影响力的顶峰。
然而,自 21 世纪以来,国际舞台上出现了一种新的范式,表明随着世界走向以更大的多边主义为特征的新世界秩序,美国在全球政治层面的影响力正在减弱。因此,本分析探讨的多样性的一个方面是电影制作中地理多样性的演变。电影业是否反映了这一政治趋势?
这就是我们在观察前 20 个国家的票房数字时所看到的情况,这些数字是根据其电影产业的利润规模来衡量的。
撇开 2020 年与大流行相关的崩溃不谈,有两点立即凸显出来:
(1)美国电影业与世界其他地区之间不可思议的差距(不出所料)。
(2)中国电影业利润的指数级增长,正在迅速赶上美国。
放大其余国家,我们看到以下内容:
总体上有积极的增长趋势。因此,在探索日益增加的地理多样性时,更恰当的比较是比较这些国家自 2000 年以来的增长率,如下所示:
有趣的是,美国在过去 20 年的年增长率中排名倒数第三,新电影增长率约为 4%,平均增长率约为 2.5%,相比之下,排名前十的国家虽然拥有明显较小的产业,但年票房利润都至少增长了 10%。
因此,电影业增长最快的市场都是国际性的,其中中国、印度和巴西占主导地位,年平均增长率超过 20%。因此,随着国际观众对更能反映其文化和社会的原创内容的需求迅速增长,这些市场可能为电影制作人提供一个在竞争对手中脱颖而出的有趣机会。
当然,随着疫情对已经占主导地位的流媒体行业的推动,地理多样性应该成为主要参与者中更重要的考虑因素,因为就提供这些服务的服务提供商数量而言,美国以外的市场竞争明显较弱,如下图所示。
网飞已经在利用地理多样性的机遇,开发当地产业,制作越来越多反映当地文化和语言的新内容,包括热门歌曲和一些我最喜欢的:鲁邦(法)、 Dix Pour Cent/Call My Agent!(法兰西) Casa de Papel/Money Heist (西班牙) Fauda (以色列)。
二。电影业中的选角多样性
回顾美国电影,过去几年发表了许多文章,批评好莱坞在选角选择上的最后一个多样性,一些运动开始出现,如 2015 年的#OscarsSoWhite 和 2016 年的# whitewashedOUT,以及非洲裔美国人、拉丁裔、亚裔、LGBTQ 和其他社区的多个多样性代表协会为他们缺乏代表性而大声疾呼。
人们已经在采取措施打造更平衡、更具代表性的演员阵容,像《黑豹》和《疯狂富裕的亚洲人》这样的电影经常被认为是朝着正确方向迈出的指示性步骤。
因此,这项分析探讨了自 2010 年以来在这方面发生的变化,通过检查过去十年中 100 位票房收入最高的演员的“明星得分”,这是一项根据他们出演的票房收入最高的电影数量分配给每个演员的统计数据。
到 2020 年,非洲裔美国演员的平均明星分数上升了 72%,美国土著/阿拉斯加土著演员上升了 36.7%,亚洲演员上升了 21.5%,夏威夷土著/太平洋岛民演员从不存在上升到 377.5。
此外,当比较 2010 年和 2020 年票房前三的演员时,我们看到 2010 年的阵容是:小罗伯特·唐尼、泰勒·洛特纳和希亚·拉博夫,2020 年的是:塞缪尔·L·杰克逊、道恩·强森和丹娜·古瑞拉。
然而,虽然已经取得了重要进展,但仍需要取得更多进展,以建立一个更具包容性和代表性的电影业,不因肤色或其他因素而有所歧视。事实上,仍然有迹象表明,虽然电影业已经开始挑选更多不同肤色的演员,但这些演员仍然倾向于出演次要和不太重要的角色。
在表演艺术中,衡量一部电影中一个角色重要性的标准是计费数。根据维基百科的定义,计费是一个术语,指的是戏剧、电影、电视等演职员表的顺序和其他方面。相应地,角色越重要,计费号越低。然而,这一分析表明,在过去的 10 年里,有色人种演员,特别是非裔美国人、亚裔和美洲土著/阿拉斯加土著演员的平均收入,详见下表。
虽然这清楚地表明,在社会层面上还有更大的改进空间,但发生的巨大变化清楚地表明了新的多元化趋势的本质,这种趋势既抓住了社会,也反映了整个电影业。
电影制作人应该欣然接受这一趋势,尤其是考虑到这样做不仅有利于社会进步,而且从这类电影产生的收入来看,不仅有利可图,还可能使他们的电影获得重要的文化地位。
三。接受和好评
当然,当讨论电影业的新趋势时,必须探讨的一个方面是接受和好评。因此,除了不可避免地提到奥斯卡奖(被广泛认为是业内最重要和最负盛名的奖项)之外,必须给予电影评论家应有的重视,这些独立的声音对电影和整个行业的艺术形式有着深刻的了解。
去年,奉俊昊的《T2 寄生虫》成为奥斯卡 92 年历史上第一部赢得奥斯卡最佳影片奖的外语片,成为头条新闻。除此之外,奉还获得了最佳导演奖,虽然与历史性的爆冷相比没有那么轰动,但仍然意义重大,特别是在奖项变得更具包容性方面,因为他成为继李安之后第二位获得该奖的亚洲人,李安于 2005 年凭借《T4》中的《卧虎藏龙》获得该奖,并于 2012 年凭借《少年派的奇幻漂流》获得该奖。
奥斯卡奖是由美国委员会投票决定的,有一个专门的最佳国际电影类别,现实是,在过去 20 年里,越来越多的非美国电影被提名为最佳影片的主要类别。随着寄生虫终于打破了历史记录,我们肯定会在下一个十年看到更多的选择。
由于它与电影评论家有关,这项分析仅限于比较 IMBd 的数据集有史以来 1000 部最伟大的电影中的美国与非美国电影,结果显示,虽然美国拥有来自单个国家的最多电影(考虑到其在该行业的主导地位,这并不令人惊讶),但总体而言,来自非美国国家的电影数量更多,排名靠前的国家是法国、英国、日本和意大利。
结论
电影制作行业在 2010 年代经历了一个变革的十年,尤其是对更大多样性的呼吁。随着电影成为社会意识状态的代表,人们对努力创造一个更具包容性和多元化的行业所达到的里程碑的印象深刻的接受,突显了更广泛的社会对更大多样性的偏好。通过利用这种趋势和响应这种胃口,电影制作人一定会增加他们的利润和他们作品的文化意义。
正如这一分析所表明的,通过采取更大的行动来实现更多的包容性,并在电影中捕捉这一趋势,电影制作人可以在地理上与竞争对手区分开来,增加他们的电影在全球的文化意义,并通过挖掘未被充分代表的观众对更大代表性和包容性的渴望来创造更多利润。
当然,电影作为一种艺术形式,并不是简单的代表。通过这个行业不可思议的力量和影响,特别是由于新技术的发展,他们也成为有影响力的人,因此,可以用来改变看法和挑战他们的观众对任何问题的看法。因此,通过捕捉这一趋势,并利用清晰和明显的努力将多样性问题融入电影制作,电影可以发挥温和影响社会规范的作用,减少仇恨和歧视,增加接受和包容。
在 Github 上查看完整的分析和数据来源!
AWS 中 ETL 的新竞争者?
运行大规模的 ETL 工作,而没有一大群开发人员在背后支持你
由 Unsplash 上的 Pietro Jeng 拍摄
ETL——或提取、转换、加载——是处理传入数据的常见模式。通过将“转换”集中到一个单独的批量操作中,它允许有效地使用资源,这通常比它的流处理对应物更容易开发和维护。它还非常适合对数据集进行一次性调查,用户可以编写一些自定义代码来对数据集执行一些分析,导出一些结果供以后使用。这种常见的模式是许多数据科学探索的基础,但根据我的经验,我经常发现实现它既笨拙又低效。在本文中,我将概述一项新技术,我认为它可能是数据科学家(和开发人员)武库中的一个有价值的工具。
首先介绍一下我的背景。我是一名软件开发人员,专攻 AWS 数据科学基础设施,拥有软件工程硕士学位。我愿意认为这使我在编写和部署远程运行的代码时不会无精打采,但我发现运行大规模的 ML/数据作业充其量也是具有挑战性的。这一领域的大多数大型技术,例如 Spark,都非常复杂,需要开发团队来维护基础设施,这使得即使是中型公司也完全无法实现。
让我们探索一些不需要开发人员维护的单用户解决方案,重点关注以下评估点:
- 迭代开发的部署速度
- 费用
- 基础设施要求
- 易于与软件开发实践集成(代码林挺、版本控制、构建系统)
其中一项技术是 AWS Glue ETL Jobs ,该技术旨在通过隐藏底层基础设施来简化转换功能的运行,用户只需提供代码库。虽然 Glue 一旦配置好就能很好地工作,但即使是最有经验的开发人员也会感到害怕和沮丧。它不直观的用户界面和糟糕的文档使它很难学习,甚至更难调试,我发现 Spark(Glue ETL 的底层技术)的重要知识是有效使用的必要条件。
图 AWS Glue 的一个错误示例,几乎没有给出任何线索!
这并不全是坏事,一旦你掌握了胶水,它会变得非常强大。DynamicFrame 库(它包装了 spark 数据帧)非常适合读写数据到胶合表,只需一行代码(如果您坚持符合 PEP-8,还需要几行代码……)就可以将几乎无限量的数据写到分区表中——这仍然让我感到困惑!如果您有可以使用 DynamicFrame 导入的大规模数据集,这使得 Glue 成为一个很好的工具,但对于其他任何东西来说效率都很低。
举个简单的例子,作为一种常见的模式,我花了大量的时间来创建 ETL 作业,以便从存储在 S3 的原始数据生成新的数据集——然后将转换后的数据存储回 S3,然后执行分析。听起来很简单,对吗?
假设我在本地机器上有我的代码,我想创建一个粘合作业来运行这个代码,我必须:
- 通过 AWS CLI 将我的脚本上传到 S3(希望第一次能成功……)
- 转到 AWS 控制台
- 转到粘附页面
- 创建新工作
- 为作业配置 IAM 角色,以使用相关权限运行
- 输入你的剧本在 S3 的位置
- 如果需要,设置 ENI 以确保跨 VPC 的数据访问
- 包括任何所需库的 zip 依赖项—(尽管没有 C 扩展,所以祝您使用 pandas 好运!)
- 添加计划
- 运行作业
这甚至不涉及如何开发脚本,我的意思是只需看看将开发端点附加到 Pycharm 的说明!(https://docs . AWS . Amazon . com/glue/latest/DG/dev-endpoint-tutorial-py charm . html)
这并没有将 Glue 设置为日常数据科学/机器学习探索的好工具。简而言之,当根据上面定义的规范进行评估时,Glue ETL 是:
- 由于缺乏良好的本地测试,很难快速迭代新的脚本版本
- 由于火花记录,很难有效地调试
- 由于远程代码编辑和笨拙的部署,与软件工程过程集成具有挑战性
- 易于集成到 S3 和胶水表
那么还有什么其他选择呢?让我们介绍一下我们的竞争者。元流!
Metaflow 是一个相当新的工具,将于 2019 年底推出。它由网飞设计和制造,是一个开源工具,将权力还给数据科学家,降低复杂性,提高迭代速度。它包含一个 Python/R 客户端库,用于编排用户的构建和一组需要用户部署的 AWS 资源(以 Cloudformation 堆栈的形式)。所以,玩笑开够了——让我们探索一下为什么我现在在 Python ETL 工作中使用 Metaflow。
在 Metaflow 上开发新代码轻而易举
Metaflow 添加了一些新的注释来提供其功能,但编排的基础使用了 python、类和方法的既定特性(作为一名“受过经典训练”的软件工程师,这让我感到非常高兴)。流程是一个类,流程中的步骤是函数,每个步骤都链接到下一个要执行的步骤。然后,可以对流程或步骤应用注释,以添加进一步的配置。
# An example of a Metaflow Flow running locally
class TestFlow(FlowSpec): @step
def start(self):
print(“This is the start step!”)
self.next(self.process) # Runs the process step next @step
def process(self, inputs):
print(“This is the process step!”)
self.next(self.end) # Then the end step @step
def end(self):
print(“This is the end step!”)if __name__ == ‘__main__’:
TestFlow() # This initialises the Flow then runs the start step
我想我还没有找到像 Metaflow 这样无缝的工具来切换代码的远程部署。只要对我的步骤做一个注释,我就可以从在笔记本电脑上运行我的流变成在 EC2 上运行 64 核的庞然大物,就这么简单。
# Same Flow as before, but will run on the Cloud!
class TestFlow(FlowSpec): @batch(cpu=64, memory=2000) # Each step get's these resources
@step
def start(self):
print(“This is the start step!”)
self.next(self.process) @batch(cpu=64, memory=2000)
@step
def process(self, inputs):
print(“This is the process step!”)
self.next(self.end) @batch(cpu=64, memory=2000)
@step
def end(self):
print(“This is the end step!”)if __name__ == ‘__main__’:
TestFlow()
元流易于管理
因此,如果你不熟悉 AWS,请耐心听我说,这可能有点难以接受。Metaflow 提供了一个 cloudformation 堆栈来部署其基础设施。这是最精简的基础设施,提供了使用平台所需的所有部件。这种单一的堆栈易于部署和使用,每月维护成本仅为 40 美元左右。然而,这是 Metaflow 最大的缺点,它需要一些关于 AWS 的知识来大规模维护,但是打开和拆除单个堆栈是微不足道的,也是我最希望能够做到的事情。
数据可以直接存入元流
Metaflow 的另一个重要特性是它的元数据存储,允许流中的不同步骤共享数据,并在执行完成后将数据保存到 S3 中。在我之前创建 ETL 管道的例子中,我不需要自己将数据存储到 S3 中,因为 Metaflow 会为我做这件事。因此,当我回来执行我的分析时,我可以获得我的流的最新版本并提取数据集。这使得 Metaflow 对于临时和计划的数据“汇总”都非常强大,而不必管理复杂的数据库。
# A portion of a Flow showing the metadata storage and retrieval
@step
def start(self):
print(“This is the start step!”)
self.message = “Metaflow metadata is cool!” # Saved to S3
self.next(self.process)@step
def process(self, inputs): # Loads message from S3 and into self.
print(f”Let’s print the previous steps message {self.message}”)
self.next(self.end)
除去基础设施成本,在 Metaflow 上运行作业是很便宜的
由于 Metaflow 在幕后使用 Batch,您可以将其配置为使用现货定价。这使得实例成本实际上可以忽略不计,并且由于 Metaflow 可以自动处理重试,因此 SPOT 实例离线的风险很小。在这种情况下,我运行一个 64 核流不到一小时,计算成本为 1.10 美元,这与 Glue 的 16DPU 工作成本形成了鲜明的对比,后者大约为一小时 7 美元。
图 2:运行一个 64 核任务的现货价格快照。
元流流可以轻松调度
虽然 Metaflow 非常适合开发工作流,但是它如何管理生产版本呢?不出所料,太好了。将 @schedule 注释添加到您的流类将允许它的一个表示被推送到 Step 函数,在那里它可以被任何 AWS 事件桥调度/规则触发。这允许许多可能性。想在文件写入 S3 时触发它吗?很简单,只需将步骤函数启动事件附加到规则上,就可以了。
# Will run every hour
@schedule(hourly=True)
class TestFlow(FlowSpec): @step
def start(self):
print(“This is the start step!”)
self.next(self.process) @step
def process(self, inputs):
print(“This is the process step!”)
self.next(self.end) @step
def end(self):
print(“This is the end step!”)if __name__ == ‘__main__’:
TestFlow()
总之,对于我和我的工作流来说,Metaflow 已经被证明是一个强大的工具。它有一些缺点,例如必须管理基础设施,但它丰富的功能(其中许多我还没有谈到)使它成为那些负担不起大规模数据平台的人的优秀工具。在以后的博客文章中,我将探索减轻这些缺点的方法,并更深入地利用 Metaflow 的特性。
物理教育研究的新数据集
70,000 份学生对实验物理态度的调查数据集
这篇文章描述了来自 70,000 份科罗拉多实验物理科学学习态度调查(E-CLASS)的免费使用数据集。你可以在这里找到这个数据集:https://github.com/Lewandowski-Labs-PER/eclass-public
照片由 Tra Nguyen 在 Unsplash 上拍摄
整个社会科学领域都存在复制危机。许多研究在重新评估时不能产生相同的结果(例如,在 PER 中,所学课程的证明,而不是之前在中所证明的分数,最能预测学生是否继续攻读物理学位课程)。在某些情况下,如果数据可以免费获得,不同机构的研究可以进行比较,看看结果是否可以重复。数据共享还鼓励数据的长期保存,这保持了数据的完整性,并可以作为未来科学家的培训工具。自由开放的数据也鼓励围绕特定研究问题的对话。可以用不同的方法重新分析结果,以进一步确定结果。在物理教育研究领域,基本上没有可供研究的大型、免费和公开的数据集。
我们使用科罗拉多实验物理科学学习态度调查(E-CLASS)创建了一个大型(70,000 人响应)数据集。这些数据涵盖了 133 所大学,599 门独特的课程和 204 名教师,是在 2016 年至 2019 年期间收集的。该调查评估了一名物理课学生对用实验室技能解决物理问题的态度。在本帖中,我们将介绍数据集和与数据集交互的 python 库。我们鼓励您下载数据集并自己使用它!
E 级数据集
E-CLASS 旨在帮助教师和 PER 研究人员衡量不同实验室课程实施和干预的影响。它是为了解决各种各样的学习目标而开发的,这些学习目标可以粗略地归类为探索学生的认识论和对实验物理的期望。为了能够处理如此大范围的目标,该调查不是为了衡量一个或几个潜在因素而设计的。此外,该调查旨在衡量学生从入门课程到更高级课程的思路进展。为了达到这一点,许多问题是针对入门或高级水平。因此,我们强调,虽然可以考虑“总体”E 级分数,但评估的真正力量来自于检查对个别问题的回答,特别是那些与特定课程的学习目标相一致的问题。
E-CLASS 数据集包含 39505 个调查前响应和 31093 个调查后响应。在某些情况下,学生可以不止一次地回答调查。因此,共有 35380 个对预调查的独特回应和 28282 个对后调查的独特回应。在这种情况下,“独特”被定义为调查前或调查后的第一个回答。该数据集代表了 133 所独特的大学、204 名独特的教师和 599 门独特的课程。该数据集包含入门课程和“一年级以上”课程(BFY)学生的数据。如下图所示,在数据收集期间,每学期收集的数据总量有所增加。
自 2016 年开始自动在线管理以来,学生对 E-CLASS 的累计响应数量。与 BFY 实验室相比,从介绍性课程中收集的学生反馈更多,因为这些课程往往有更多的注册人数。此外,一般来说,更多的学生对前调查作出反应,而不是后调查,这说明了不同的两条线之间的每个实验水平。目前,数据集中总共有 70598 个响应。图片作者。
电子课堂本身由 30 个李克特式问题组成,用来评估学生的知识和对专家的期望。学生被要求从他们的观点和预测实验物理学家的观点对每一个陈述做出回应(从非常同意到非常不同意)。在某些情况下,专家式的回答是不同意。数据已经被预处理以转换 Likert 响应,使得所有数据都在非专家(在数据集中用 1 表示)到专家样(在数据集中用 5 表示)的五点标度上。到目前为止,所有的研究都是通过首先将五分尺度折叠为三分尺度来完成的,但全部范围都包含在公共数据集中。我们警告研究人员,该调查的设计不能可靠地区分量表两端的两个最外层点(即“同意”和“非常同意”或“不同意”和“非常不同意”)。此外,仅在课后调查中,学生被问及哪些项目(30 个项目中的 23 个)对于在课程中获得好成绩是重要的。最后,学生们还被问了一系列关于人口统计、兴趣和职业规划的问题。
DataHelper Python 库
除了数据集本身,我们还编写了一个库来帮助研究人员访问数据。虽然原始数据在几个表中都是 CSV 格式的,但用户通常希望以某种方式缩减数据集,例如只缩减参加入门课程的学生,或者只缩减对前后调查都有反应的学生。下面我们展示一些如何做到这一点的代码示例。
DataHelper 库需要 pandas,并使用 pandas 范式来组织数据。
要导入数据集,我们只需使用以下 cod
**import** DataHelper
e **=** DataHelper**.**eclass_data()
这段代码导入库,然后在e
对象中创建完整的数据集。这个e
对象可以用来访问底层数据。例如,如果我们想打印回应的总数,我们可以使用函数e.get_buffy_pre()
和e.get_intro_pre()
。
print('total number of pre responses:',e**.**get_buffy_pre()**.**shape[0]**+** **+** e**.**get_intro_pre()**.**shape[0])>>> total number of pre responses: 39505
这些函数分别返回只包含 BFY 数据和介绍数据的pandas
数据帧。因此,返回 dataframe 的shape
会给出行数。
如果我们只想获得匹配的数据,我们可以执行类似的操作:
print('Number of matched responses intro:', e**.**get_intro_matched()**.**shape)
print('Number of matched responses bfy:', e**.**get_buffy_matched()**.**shape)>>> Number of matched responses intro: (19445, 175)
>>> Number of matched responses bfy: (3096, 175)
其中函数e.get_intro_matched()
为我们执行匹配操作。
github 资源库中有许多示例笔记本。
你可以在这里找到数据集和 DataHelper 库https://github.com/Lewandowski-Labs-PER/eclass-public
本帖汇总论文https://journals . APS . org/prper/abstract/10.1103/physrevphyseducres . 17.020144
分析工作流管理的新观点
数据分析/项目管理/教育
由分析专家为分析专家制定的工作流程
作为一名新的分析专家,我所面临的最困难的问题之一是管理和优先化我的项目的能力。我在公司做的大部分工作都是独自完成的,因为我没有一个适合我的分析团队。可以想象,项目堆积起来,你必须找到管理这些项目的方法,同时还要完成实际的开发/分析工作。
我研究了许多不同的项目管理和工作流方法,但是我面对的最大问题是任何大的项目管理/工作流方法(例如敏捷、Scrum 等)。)是因为他们是面向 5 人以上的团队,以提高效率。尽管如此,我花了一些时间修补不同的方法来创建我自己对 PM/工作流方法的看法,并结合来自不同方法的概念,使其适合一个分析师。我觉得这种方法最适合我,但不一定最适合你,所以你必须通过自己的经历找到最适合你的方法。无论您是单独的分析师,还是在团队中工作并需要帮助跟踪您自己的项目和任务,此工作流都是您开始工作的好地方。让我们上车吧!
免责声明:我是一个相对较新的分析专家。这并不是要告诉你你到底需要知道什么,而是从我的经历中给你一些实用的建议。更多信息请查看 走向数据科学 。如果你目前在跟踪你的项目和试图找到更有效率的方法上有困难,请继续阅读!
工作流程概述
我对分析 PM/工作流方法学的理解来自几个不同的方法学,即看板、功能驱动开发(FDD) 和软件开发生命周期(SDLC) :
- 看板: 看板对于展示生产的流程非常有用。如果你曾经走过软件开发团队,看到所有这些带有专栏和便签的大白板,那就是看板。它对于查看生产中可能出现瓶颈的地方也非常有用,这很好,因为您可以看到您需要关注的地方。我为这个工作流程创建了一个概念模板,你可以在这里找到。
- 特征驱动开发(FDD): 特征驱动开发是敏捷中的一门学科。它的重点是围绕系统创建功能。我发现这种方法很有用,因为我通常会有人来找我,因为他们需要在现有流程中添加一些东西(比如测量一个新的指标)或修复一些东西(Tableau 中的图表显示不正确)。这两个任务都涉及过程的一个“特征”,而不是整个过程。
- 软件开发生命周期(SDLC): 这是我自己采用的主要方法,因为我认为它是任何工作流或 PM 方法中最自然的流程。虽然我不是软件开发人员,但我已经调整了方法以更好地适应分析工作。
话虽如此,以下是我对分析工作流方法的概述:
- 要求
- 设计
- 发展
- 测试
- 质量保证/部署
- 维护
我还提到了该工作流中的几个不同的“角色”,如下所述:
- 客户: 请求项目的个人或团队。这并不一定意味着他们将是唯一使用您的解决方案的人,但他们通常是拥有领域知识并能在问答过程中提供帮助的人。我也称他们为“客户”,因为我的工作流程是以我为之服务的人或团队为中心的,类似于顾问-客户关系。
- 利益相关者: 支持本项目开发的任何人(即数据库架构师)或者将利用您的解决方案满足其数据需求的任何人(即客户团队)。
让我们浏览一下每个阶段,以便更好地了解每个阶段的功能!
1)要求
在你开始一个项目之前,你需要知道这个项目的需求是什么。这包括以下内容:
- 最终产品是什么?
- 需要使用哪些数据?
- 不同交付的截止日期是什么?
- 什么利益相关者对这个项目的发展至关重要?
如你所见,这是你计划项目的时候。这也是流程中最重要的阶段,因为没有什么比构建一个流程或模型,却发现最终用户实际上需要的东西与您构建的不同更糟糕的了。
注: 无论“客户”是谁,我都尽量在每个阶段完成后给他们一个更新。这有助于避免出现上述情况,即沟通出现中断,并且构建了不需要构建的东西。
2)设计
在我有了项目的所有需求之后,我开始设计解决方案。这可能是一个 Tableau 仪表板,一个新的 ETL 过程,市场研究分析,等等。在这种方法中,设计是关于绘制和构建解决方案的基本结构或框架。如果这是一个 Tableau 仪表板,我将在一些纸上勾画出每张纸需要放在仪表板上的什么位置,以及它将向最终用户传递什么信息。如果这是一个 ETL 项目,我会绘制一个基本流程图(或者在 Alteryx 中构建基本流程)。这有助于将需求保持在方法的最前沿,这样您就可以被“客户”的要求所约束。这也是您可以在开始开发解决方案之前发现客户可能想知道的问题的时候。
3)发展
开发是任何开发 PM/工作流方法的核心,在这里也是如此。在这个阶段,您将从之前的阶段中取出您的设计,并开始有条不紊地完成每个“功能”(例如,在 Alteryx 公式工具中编写情感分析算法)。在这个过程中,我从 FDD 中提取并按特性构建的原因是因为它有助于将项目分解成可管理的块。如果你是一个单独的分析师或在一个小团队中工作,这很好,因为你可能同时有许多活动的项目在进行,所以这给了你可衡量的可交付成果,如果客户要求更新,你可以与他们交流。“哦,我能够在你的广告仪表板上完成情感计算”比“哦,是的,我正在做你的项目,应该很快就能完成”要好。这种方法是关于仆人领导和客户服务的。在一天结束的时候,你希望你的分析工作能让某人的生活变得更好。根据我的经验,这个过程实现了这一点,同时也使得项目对于单独的分析师或小团队来说更易于管理。
“这种方法完全是关于仆人领导和客户服务的。在一天结束的时候,你希望你的分析工作能让某人的生活变得更好。以我的经验来看,这个过程实现了这一点,同时也使项目对于单独的分析师或小团队来说更易于管理。”
4)测试
那么为什么“测试”和“问/答”是在各自的阶段呢?在这种方法中,测试完全是关于单独的分析师做他们自己的技术问答工作。这是您看到解决方案中缺陷的地方,并且可以在解决方案到达客户端进行 Q/A 之前修复它们。例如,如果我在 Alteryx 中构建 ETL 过程,我可能希望看到该过程如何处理不同的日期数据类型,或者手动计算我的生产数据行,以确保我在管道中创建的所有计算都输出正确的数据。在测试时,我也会尝试单独测试解决方案的所有特性。例如,如果我在一个 Tableau 仪表板上工作,我会测试我可能有的所有不同的过滤器以及任何集合,并选择一些选项以确保一切正常工作。
5)问答和部署
与测试阶段相比,问答更多的是关于数据质量和最终用户输出。我通常会创建一个样本报告或加载少量数据,并将其发送给任何重要的利益相关者以及客户。客户端将能够从最终用户的角度告诉您是否有些事情看起来不对劲,或者数据是否看起来不对。这是一个非常好的实践,可以让您在解决方案投入生产之前对其充满信心。
说到生产,“部署”是让解决方案为生产做好准备的子阶段。这可能意味着自动化一些数据输入功能,这些功能可能是您在开发过程中手动完成的,例如提取 2021 年全年的数据,而不是根据当天提取上周的数据,或者改变仪表板上的颜色,使其更加美观。
6)维护
这个阶段通常发生在其余阶段之后,以及解决方案投入生产一段时间之后。客户端需求是动态的,可能会在解决方案部署一个月后发生变化。这个阶段是为了对你的解决方案进行小的改变和调整,这不会花太多时间。我通常会在项目启动后的两周内将项目留在维护阶段。之后,我会认为该项目已经完成。
注意: 你构建的大多数解决方案在生产过程中可能需要润色,所以尽管你构建的所有东西在技术上可能都需要维护,我通常会将项目留在实际维护阶段 2 周,因为那些是最容易出现错误的解决方案,可能会优先处理。
结论
虽然这是我个人的工作流程,但请记住,每个人都有自己的偏好来提高自己的工作效率。我发现更严格的流程有助于我跟踪我的项目和任务,然而,我知道许多成功的分析专家更喜欢更灵活的工作流程。我希望你会发现这种方法很有用,并从中构建自己的工作流!请继续关注可能的第 2 部分,包括项目示例…
看看我的其他文章吧!
</10-tips-for-a-successful-internship-e8f0c14cd3d3>成功实习的 10 个秘诀
联系我或接收更多内容,在 Twitter 上关注我@BMNAnalytics!
思考不确定时代建模的新方法
不确定时代的建模:方法、行为和结果
疫情或新冠肺炎的传播——首先在中国和南韩,然后在欧洲和美国——非常迅速,让大多数政府、公司和公民措手不及。这场全球健康危机在几周内发展成为经济危机和供应链危机。2020 年 3 月初,全球确诊病例不到 10 万例,截至 1 月 28 日,已激增至 1.01 亿多例,死亡人数超过 210 万。
这个星球上几乎每个人生活的方方面面都受到了新冠肺炎的影响。从直接影响(如死亡、住院、感染)到间接影响(如失业、在家工作、精神健康),病毒几乎影响了这个星球上的每个人。不确定性触及了新冠肺炎统治下生活的方方面面——从健康、行为到经济影响。不确定性往往会助长恐惧、愤怒和沮丧等情绪反应,这种情绪驱动的行为[Firth-Butterfield-etal-2020]往往优先于理性的决定和行动。
除了不确定性之外,个人、公司、决策者和政府都不得不在很少或没有经验、很少历史数据的情况下,在很短的时间内做出决定。高级分析和人工智能模型已被广泛用于帮助解决这些不确定性[Rao-etal-2020]。模型是一种正式的数学表示,可以应用于或校准以适应数据,已被广泛使用。在人类历史上,也许没有任何数据模型比新冠肺炎的感染和死亡曲线更容易辨认。几乎每个人,从印度的农民到美国疾病控制和预防中心(CDC)的主任,都对它们很熟悉。但是这些模型也因其预测的不一致性而招致批评。
那么,模型想要捕捉什么呢?他们能帮助我们做什么决定?我们用什么技术来建立这些模型?
covid 19 影响的系统视图
新冠肺炎的影响是广泛的,全球性的,涉及生活的许多方面,也深刻地影响着我们的生活和生计。对影响的所有不同方面进行建模的最佳方式是采用系统级视图,并隔离关键系统以及这些系统之间的交互。一旦我们有了宏观层面的视图,我们就可以构建那些与我们想要在消费者、公司或国家层面做出的具体决策直接相关的系统的更精细的微观层面的视图。这将使我们变得有弹性——考虑到来自其他相关系统的关键驱动因素,同时也是动态的,我们可以专注于手头的即时决策。图 1 显示了所考虑的所有宏观和微观因素的系统级视图。
图 1:疫情的宏观和微观系统观及其对社会的影响
新冠肺炎疾病进展无疑是影响所有其他宏观层面系统的关键系统。许多疫情水平的不确定性,如疾病的不确定性(例如,感染率、潜伏期、扩散过程、增长率、住院率和死亡率)、测试(例如,诊断测试、抗体测试、准确性)、数据(例如,住院人数、死亡人数)和治愈(例如,治疗药物——其功效和何时可用、疫苗——其功效、试验、批准和规模化可用性)都会影响疾病的进展。这些不确定性具有很强的局部性和时间依赖性,例如,在不同的时间对不同的国家、州甚至是邻近地区产生不同的影响。
疾病的发展无疑会影响政府干预,这是我们的第二个宏观体系。基于国家的社会距离、经济活动的缩减和启动,如学校、酒吧、餐馆等的开放和关闭。实施或解除封锁的时间和持续时间都会对经济活动和人们的行为产生影响。
令人惊讶的是,公民行为已经成为疫情最重要的宏观层面系统组成部分之一——疾病的传播和经济活动反弹或停滞的能力【Firth-Butterfield-etal-2020】。虽然一些国家和美国的一些州在执行行动限制方面非常成功,其公民遵守了政府的干预措施,但其他州要么没有实施限制,要么公民没有遵守。当我们通过消费者需求、劳动力安全以及最终公司的财务可行性来考虑其对公司的微观影响时,这种宏观层面的动态变得极其重要和具有挑战性。
由政府干预推动的经济是另一个主要的宏观体系组成部分,由于疫情、其公民的行为以及政府为减轻公民和公司的经济痛苦而实施的财政刺激,政府干预抑制或促进了经济活动。
所有这四个宏观层次的系统组件都与微观层次的系统组件相互作用。客户、劳动力、公司、需求和供给是四个关键的微观层面的组成部分。客户和员工是公民的微观变体。一个地区或邮政编码内的公民在参与消费产品和服务时被视为客户,在参与为公司工作的经济活动时也被视为劳动力。公司满足消费者的需求,同时也生产商品或中间产品,为其他公司供货。公司也雇佣劳动力来生产商品和服务。所有这些互动都是通过支撑经济的现金来实现的。
在微观层面,需求的不确定性(例如,对航空旅行和旅游等一些产品和服务的需求大幅下降,或对卫生纸等产品的需求大幅增加)、供应链中断、劳动力安全、生产率和时间安排是经济活动的主要影响因素。这些因素加上政府是否提供财政支持,决定了公司的财务可行性(即利润、利润率、流动性和破产),以及个人的购买力、收入水平和就业状况。
制定战略或运营决策不仅需要了解系统层面的观点和组件之间的相互作用,还需要了解关键驱动因素和这些相互作用的性质(例如良性或恶性反馈循环)。考虑到需要做出决策的速度,高管们需要关注疫情的显著影响,以及疫情如何改变正常的反馈回路。
新冠肺炎建模与决策
确定了新冠肺炎系统的关键系统级组件后,我们现在来看看已经构建的特定模型,以及它们帮助我们做出的决策。
疾病进展:流行病学模型
模拟传染病发展的经典方法被称为 SIR 模型。这三个字母记录了一个人在感染过程中的不同状态,例如,变得 S 易受感染,然后 I 被感染,最后 R 从中恢复。这种类型的建模的进一步改进捕获额外的状态,如 SEIRD 模型(易感、暴露、感染、恢复和死亡)捕获暴露和死亡状态。新冠肺炎疫情已经产生了许多这样的模型-为不同的国家构建-捕获更多的国家。例如,一篇论文[Khalil-etal-2012]记录了上述 SEIRD 状态以及接触、隔离、未隔离和免疫状态。其他一些[Kompella-et al-2020;Silva-et-al-2020]记录有症状前和无症状前、有症状和无症状状态、住院和危急状态。一个模型捕获的感染状态越多,就越有利于精细的决策制定。这确实使模型更加复杂,并且需要更多的数据来校准模型。
对疾病进展进行建模的原因是为了能够进行不同的干预,以帮助减少感染、住院、死亡等。以及重返工作岗位和重启经济。这就引出了下一组模型。
政府干预&效果:行为模式
行为模型捕捉可以实施的不同限制和干预,以及它们在减少疾病传播方面的有效性。这些模型模拟干预措施,如居家命令(SHOs)或社会距离限制,并评估它们如何影响流行病学模型所描述的疾病进展。许多这些模型[Chen 等人-2020]具有时空维度,并且可以通过位置和政治关系来估计对这些命令的遵守情况。来自智能手机的移动数据可以帮助跟踪公民的移动,而不一定要识别他们,以评估封锁甚至社交距离干预的有效性。错误信息[Leitner-2020]对个体依从性和疾病进展的作用也可以使用这些方法进行研究。
经济影响:经济模型
当与行为模型结合时,流行病学模型也可以用于分析不同干预的经济影响。这些模型[Silva-etal.2020]允许政策制定者分析社会距离干预的不同情景,这些情景具有不同的流行病学和经济影响。Silva 等人在他们的模型中考虑了七种不同的情景:(1)什么也不做,(2)一级防范,(3)有条件的一级防范,(4)垂直隔离,(5)部分隔离,(6)使用面罩,以及(7)使用面罩以及 50%的社会隔离坚持率。
这些模型不仅有助于通过各种干预机制减少疾病的传播,还可用于以安全的方式重返工作岗位。例如,王等人的论文评估了纽约市的分阶段重新开放策略及其对城市内公共交通、小汽车交通和微观交通方式的影响。
不确定时间的建模方法
三种特定的建模方法或技术已被用于建立这些流行病学、行为和经济模型。历史上,基于方程的方法已被用于传染病传播的建模【段等-2015,亨特等-2018】。微分方程用于定义每个状态(例如,易感、传染性等)中的群体随时间变化的速率。然后随着时间的推移求解这些方程,以了解疾病的动力学。模型中更多的状态意味着需要更多的方程来捕捉相互作用的动力学,因此模型更复杂。基于方程的方法也被称为系统动态(SD)模型。
用于建立流行病学模型的第二种方法是基于主体的模型(ABM)。在基于代理的模型中,每个个体被表示为一个代理,他们与其他代理和环境交互。媒介从一种状态(例如,易感、传染性等)变化到另一种状态,并且运行许多这些媒介提供了疾病传播的总体动态。基于等式的方法将每个状态中的所有个体视为单个“隔间”,并且不允许任何个体差异。然而,在基于代理的模型中,每个代理都是独一无二的,这使得我们可以更自然地对前面讨论过的行为方面进行建模。
最近,机器学习——深度学习和强化学习——被用来建立这些模型。最近的方法是将新冠肺炎病例和死亡与地方层面的社会经济、健康和行为风险因素相结合,并使用深度学习[Fox-etal-2020]来更好地预测疾病进展。同样,强化学习[Kompella-etal-2020]正被用于优化缓解政策。
总之,理解疾病发展的动力学及其对个人行为和经济的影响的必要性导致了基于主体、系统动力学和机器学习模型的复兴。假设、数据、模型、政府干预和人类行为之间丰富的相互作用使得这些模型很难建立,但对于以系统的方式评估不同的策略非常有用。
参考文献
来自新冠肺炎建模的教训:数据、模型和行为的相互作用。“世界经济论坛。全球议程,2020 年 5 月 12 日。
Rao,a .和 Firth-Butterfield,k .“3 种方式——正在转变高级分析和人工智能”世界经济论坛。全球议程,2020 年 7 月 23 日。
埃及疫情流感基于主体的建模智能系统参考图书馆(2012):205–218。
莱特纳斯蒂芬。"关于流行病和信息流行病产生的动力"心灵&社会(2020 年):
陈,m .等.传播居家医嘱的因果估计ArXiv abs/2005.05469 (2020)。
Silva,Petrô nio C.L .等人," COVID-ABS:一种基于主体的新冠肺炎流行病模型,用于模拟社会距离干预的健康和经济影响。“混沌、孤子&分形 139 (2020): 110088。
行为惯性对纽约市公共交通重开策略的影响abs/2006.13368 (2020)。
AICov:一个用于人口协变量新冠肺炎预测的综合深度学习框架。ArXiv abs/2010.03757 (2020)。
Kompella,v .等.“优化新冠肺炎减缓政策的强化学习。ArXivABS/2010.10560(2020)。
传染病流行病学基于主体的模型和基于方程的模型的比较 AICS (2018)。
段文伟,范,周刚,郭炳忠,邱,:传染病模型的数学和计算方法:综述。计算机科学前沿 p. (2015)。https://doi.org/10.1007/s11704-014-3369-2
人工智能和意识的“无废话”指南
人工智能概论系列的第 5 部分
什么是意识?资料来源:Juan Rumimpunu viaUnsplash
“人工智能对人工大脑的探索已经将意识的神秘转化为有期限的哲学.”
麻省理工学院教授马克斯·泰格马克博士
H 又是 ello!距离我上次发帖已经有一段时间了,但是我希望能再次加快速度,至少每两周发布一次这些故事*。因此,记住这一点,欢迎来到探索人工通用智能(AGI)系列的第 5 部分!如果你错过了前四部分,请在这里查看,从第一部分开始。本周我们将关注意识:这个难以捉摸、被误用、令人困惑的术语,它往往会引发存在主义危机…*
具体来说,本周我们要讨论以下问题:
- 什么是意识?
- 意识与思考思考有关吗?
- 什么是感觉,它和意识有什么不同?
- 现在的 AIs 有意识吗?
下周,在第 6 部分,我们将开始寻求阐明一个 AGI(或原型 AGI)可能被创造的实际的、可能的方法,并将主要处理认知建筑的令人难以置信的迷人的世界。
在这个系列中,每周/每隔一周会有一个新的帖子出现(我希望如此),如果有问题、评论或澄清,可以随时给(mferg@mit.edu 发电子邮件。尽情享受吧!
免责声明:毫无疑问,有些人更有资格对我将涉及的问题和主题进行深入的讨论,从情感到神经形态计算。对于这些人来说,这个系列只是对这些主题的介绍,因此,如果为了简洁而省略或浓缩了一些内容,请见谅。我真的只是想要这个系列,以及激发它的课程,作为一个相关 AGI 主题的调查,这些主题通常在学习人工智能或人工智能时不会被教授。还要注意:这个系列与麻省理工学院或其品牌没有任何关系——我只是喜欢在周末写一些我感兴趣的东西,麻省理工学院并不正式认可这里陈述的观点。
第一部分:什么是意识?
剧透警报:没人知道。
“我存在,仅此而已,我觉得这令人作呕。”
――萨特, 存在与虚无
我真的认为我们生活在计算神经科学的黄金时代。新的、强大的视觉、理解、注意力和语言模型正以极快的速度出现,随着它们朝着更像人类的方向发展,不可避免地会出现“它们到底有多像人类?”的问题出现了。请注意,这是一个相当复杂的问题,类似人类可能意味着许多不同的事情;然而,我直觉地感觉到,当大多数人问这个问题时,它倾向于承担意识的内涵。也就是说,随着这些模型变得越来越复杂,它们是在接近某种有意识的东西吗?
这篇文章试图超越对人工智能和意识的大肆宣传,并对现实生活中人工智能和神经科学实验室提出的问题做一个很好的概述,并试图消除人工智能和意识讨论中的一些“手动波动”。在我们的实验室里,我们不谈论意识甚至是一个笑话,因为它是一个如此沉重的术语,一个经常在没有严格纪律的情况下使用的术语,实际上指的是什么。
在研究和试图理解意识思维时,我一直牢记两件事:
- 任何试图声称他们已经理解了意识的本质或者解开了意识的秘密的人都很可能是错误的,或者试图向你推销某些东西。
- 你越研究它,你拼错“意识”这个词的次数就越多。
第一点是 Patricia Churchland 博士的解释[1],它很重要,因为截至 2021 年 9 月,我们完全不知道意识是什么,由什么组成,或者它来自哪里;我们几乎无法定义它,更不用说重现它了。我们有一些理论仍然需要进行实证检验,但没有确定的答案。
我知道这个答案并不十分性感,但我不能真诚地给你一个半生不熟或“胡说八道”的答案——科学现在根本不知道,声称它知道也是错误的。
然而,从现象学的角度来看,我们可以描述有意识和无意识是什么样子。感觉就像你是这个东西,从两只眼睛往外看,控制一个身体,思考。如上所述,意识是一个非常有内涵的词,当人们提到它时,他们可以指很多不同的东西,比如感觉、意识、自我意识、思考和体验。一些神经科学家认为意识是极其复杂系统的涌现属性,这意味着它只是……当大脑变得足够复杂时才出现。许多人被它吸引,包括我自己,因为它是我们对世界知识的一个巨大缺口,有许多进步和事实有待发现。传统上,意识已经被放逐到不可证伪的假设领域,因为众所周知,即使试图提出一个具体的理论也是一个困难的问题。因此,由于意识这个术语本身的复杂性质,我们将尝试解开一些常见的“类型”。
我们要画的意识类型之间的第一个(也可能是最大的)区别是在注意力和现象学(或 a vs. p )之间。简而言之,注意力意识是指意识到某些刺激,许多认知架构都实现了这种确切的机制。我意识到写这个帖子,现在是什么时间,我的手现在正在做什么,等等…另一方面,现象学 c 意识指的是 qualia[2];也就是说,用纳格尔的话来说,成为一只蝙蝠是什么感觉?在模拟中体验自己会是什么感觉?这种类型呼应了感受性、感觉和身心问题,这些都是我们在这个系列讲座中讨论过的。所以,现在许多原型 AGI 系统是有注意力意识的,但真正的乐趣是现象学性质的。
注意力:狗知道什么?现象学:当是一只狗是什么感觉?来源:Michael Dziedzic via Un spash。
意识这个词的另一个“类型”或区别来自安东尼奥·达马西奥,是核心五延伸。 核心 意识就像一个打开/关闭的开关,一个有机体是清醒的,意识到一个时刻,现在,和一个地方,这里[3]。有机体是警觉的,但不关心未来或过去,也没有自我意识。另一方面,当我们通常谈论意识时,我们指的是扩展意识:警觉,关注过去和未来。这通常被认为是人类特有的;你可能会说像猪和牛这样的动物有核心意识,但很难说它们延伸了核心意识。
最后,意识的最后一个区别我们将谈论一个相当众所周知的区别,那就是 无意识 , 潜意识 和前意识之间的区别。这些类型具体地并且通常是指注意力意识的类型:
- 无意识一般表示缺乏意识,不管什么原因【3】。
- 前意识一般是无意识的一个子集,一般表示影响有意识的行为[3]。
- 潜意识,对我们来说,和前意识是一样的【3】。
这里有一个很好的例子:无意识思维由一个人看到和听到的东西组成,但没有有意识地处理。无意识头脑可以储存这些信息,供有意识头脑以后检索,当我们可以科学地证明这一点时,它就被认为是前意识[3]。
所以,我们已经解开了一些关于意识的术语。在阐明它是什么,它从哪里来,或者更有趣的是,如何复制它方面,科学站在哪里?让我们来看看尝试这种解释的三种主要理论:
综合信息论【4】:
- 由托诺尼提出,由克里斯托弗·科赫倡导。
- 简而言之,这是一个功能主义理论,依赖于所谓的综合信息,这是一个网络“影响自己”的可测量程度。这是一个严重的过度简化,但在实验室设置和临床应用中已经显示出非凡的前景。
- phi(综合信息)多的东西更有意识。
- 想多读多学,强烈推荐科赫的书生活本身的感觉。
全局/神经元工作空间理论【5】
- 由 Bernard Baars 提出,并对认知体系结构的发展以及心理和行为建模产生了重大影响。
- 基本上是无意识过程基于注意力意识的显著性来竞争的一种方式,更重要的刺激是你意识到的。
- p 意识有一点棘手,目前的 G/NWT 对如何实现现象意识基本上不置可否。
- 下周当我们谈到认知架构时,我们会再次讨论。
注意图式理论
- 由普林斯顿神经科学家迈克尔·格拉齐亚诺提出。
- 唯物主义理论认为 p-状态是由注意力图式构成的,很像 GWT。在这里了解更多:【nih.gov注意力图式理论:主观意识的机械论解释
我知道这是很多信息;然而,人们用一生的时间来研究意识,而我们只有几千个单词。不要害怕。重要的是要介绍一些基本概念,这样我们才能理解意识在 AGI 身上的明显应用。
同样重要的是要注意,这些是关于不同作者认为意识(p 和 a)可能如何实现的模型/提议——这些模型需要进一步的验证、数据、研究和/或证伪。那确实是关于意识的棘手之处,也是为什么许多现代神经科学家、认知科学家和人工智能研究人员对这个术语犹豫不决——很难确定一个可以在医院、实验室或人工智能模型中得到经验验证的可测试假设。然而,IIT 已经在这一领域取得了长足的进步,如果你感兴趣的话,可以具体参见[6]和[7]了解更多的细节。
第二部分:意识与思考有关思考吗?
或者就我们而言,思考思考思考?
“波洛,”我说。“我一直在想。”
“一个令人钦佩的练习,我的朋友。继续吧。”
――阿加莎·克里斯蒂,末日之屋
我的狗能坐下来反思自己的行为吗?他能把自己投射到未来去考虑我会如何反应吗?比如说,如果他决定咬我的鞋或者在鹿粪里打一个漂亮的滚。大多数人可能会说,不,甚至狗也不具备这种能力,这是人类独有的技能,而且,从我的狗不回避鹿粪来看,我很可能会同意。这种反思的能力,在更高或者更抽象的层面上思考,思考认知本身就是元认知,那就是思考思考。更具体地说,元认知:
- 是一个基本概念,指的是任何知识,或认知过程,指的是,监测或控制认知的任何方面[8]。
- 被许多认知架构实现或在工作中,并被认为是心智的基石能力,至少在高级心智中是如此[9]。
- 很多时候,它被编写成一个“观察者”程序,可以观察情况,监控输入和重要系统,并做出相应的反应。我们将在下周的认知架构课上讨论更多。
- 问题是,我们需要p-意识来进行自我反省和思考吗?
最后一点是真正棘手的,也是许多研究这一问题的人的眼中钉。似乎为了真实地反映你的行为和动机,你必须有某种的内在模型来代表你是一个现象学的存在:也就是说,为了思考我自己,首先必须有一个我自己…深刻的东西!
但是,撇开 hooplah 不谈,元认知与意识有着深刻的联系和交织,不幸的是,我们并没有完全理解这种关系的本质和程度。
所有这些关于思考的思考…来源:Kazi Mizan via Unsplash
第三部分: 什么是觉知,它和意识有什么不同?
避免混乱的快速绕道
“真的有可能把自己的感受告诉别人吗?”
――列夫·托尔斯泰,安娜·卡列尼娜
两个经常被误用和混淆的术语是感觉和意识,甚至在神经科学和人工智能文献中也是如此。我尽力从解开这一困惑的研究人员那里找到最常见的主题,并将其列出如下:
- 感知力就其本身而言,仅仅意味着感觉或感知事物的能力。另一方面,从人类的角度来看,Sapient 用来指聪明的。
- 有些东西可以有知觉但没有意识,比如我的狗(在这种情况下是核心意识但不是扩展意识)。
- 一头牛能感觉到疼痛,体验到被关在笼子里或被带往死亡的感觉吗?我认为是这样的,尽管我将在这里推测,并说这与我们将体验到的感觉不一样,而是更“原始”——也就是说,他们可以感受到,但并不真正思考这些感觉。
- 一般来说,共识是感知是通往意识的道路:任何有意识的东西都必须有感知,但不一定是反过来[10]。对你们这些哲学书呆子来说,感知对于意识来说是必要的,但还不够。
我喜欢用最简单的方式来思考这个问题,还是从狗的角度。我和许多其他人可能会认为,狗显然是有感情的,也就是说,它们能感觉到疼痛和悲伤。然而,他们并不像我们一样有意识,因为他们没有时间上的“我随着时间的推移”,或者像“哇,你知道,我真的可以吃一个很好的鹿粪卷”这样的想法。如果我做得很快,迈克甚至不会注意到!”。他们只是在此时此地经历一些事情,并基于这些经历感受一些事情。
第四部分:现在的人工智能有意识吗?
号码
“有一个帕特里克·贝特曼的想法,某种抽象;但是没有真实的我,只有一个实体,一个虚幻的东西。虽然我可以隐藏我冰冷的目光,你可以握我的手,感觉到肉体紧紧抓住你的手,也许你甚至可以感觉到我们的生活方式可能是相似的,但我就是不在那里。”
——帕特里克·贝特曼,《美国惊魂记》(1991)
我纠结于引用一句美国精神病患者的话,不是因为它无关紧要,而是因为帕特里克·贝特曼是一个令人憎恶的人。这也是这本书的目的:揭示 80 年代美国典型的华尔街雅皮士兄弟亚文化的丑陋面。我认为布莱特·伊斯顿·埃利斯抓住了这一点,我也认为他抓住了这种虚幻而短暂的自我意识,这种自我意识甚至存在于人类中——当你有一个人在各种意义上看起来都很正常,但在元认知或反思意识缺失的地方会发生什么?如果我们人类很难看到另一个人在这方面的缺失,我们怎么可能准确地评估一个动物,甚至一台机器?
好吧,回到我的文学话题:人工智能离全面的 p 意识还很远。一个案例可以,也应该被提出,一些尖端的认知架构是有注意力意识的,但是还没有任何东西实现 p 意识。我没有提出很多坚定的观点,但这是我支持的观点,我很乐意就此进行辩论。
甚至不清楚当大多数人讨论“人工智能和意识”时,他们指的是哪种人工智能:简单的前馈人工神经网络?贝叶斯推理机?线性分类器?一个循环脉冲神经网络?所以,即使这个答案相当枯燥,也要知道人工智能(还)没有意识,很可能一段时间内都不会。然而,我个人确实相信,我们将破解这一密码,并有朝一日创造出一台人工意识机器;但是现在,人类可能只能坚持用老式的方式创造意识思维:)
更多的数据,需要测试来理解意识。资料来源:Olga Guryanova viaUnsplash。
TL;速度三角形定位法(dead reckoning)
现代神经科学不知道意识是什么,但我们有一些关于它可能由什么组成的理论。需要更多的测试、验证、数据和工作才能真正知道,但目前,没有“人工智能”是有意识的,很可能在一段时间内不会。
其他需要考虑的问题:
- 你如何看待“ 复杂系统的突现性 ”关于意识的假说?
- 你认为你能形式化意识吗?
- 重访:你认为我们能在计算机(即图灵机)中实现现象学意识吗?
“我不能假装我没有恐惧。但我最主要的感觉是感激。我爱过也被爱过;我被给予了很多,我也给予了一些回报;我阅读、旅行、思考、写作。
最重要的是,在这个美丽的星球上,我是一个有意识的生物,一个有思想的动物,这本身就是一种巨大的特权和冒险。"
―――奥利弗·萨克斯,感恩
参考资料:
- 帕特里夏·史密斯·丘奇兰。触动神经:作为大脑的自我。诺顿公司,2014 年。
- 《哲学季刊》第 32 卷第 127 号。(1982 年 4 月),第 127-136 页。
- 意识的新科学:探索大脑、心智和自我的复杂性。普罗米修斯图书公司,2016
- https://iep.utm.edu/int-info/
- https://online library . Wiley . com/doi/10.1002/9781119132363 . ch16
- https://www . frontiersin . org/articles/10.3389/fnhum . 2018.00042/full
- https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6703193/
- 罗伯特·威尔逊和弗兰克·凯尔。麻省理工学院认知科学百科全书。麻省理工学院出版社,1999 年。
- 富兰克林,斯坦和乌玛·拉马姆西。"动机、价值观和情感:一枚硬币的三面."第六届表观遗传机器人国际研讨会会议录,法国巴黎,2006 年 9 月,隆德大学认知研究。№128.2006.
- 里斯拜伦。第四时代:智能机器人、有意识的计算机和人类的未来。ATRIA Books,2019。
关于作者
Mike Ferguson 是麻省理工学院 DiCarlo 实验室的计算研究开发人员(ML/AI)。他致力于大脑评分,这是一个测量人工神经网络有多像大脑的工具。他于 2021 年春季毕业于弗吉尼亚大学,获得了计算机科学和应用数学学士学位,以及认知科学和哲学学士学位。他是《一周挑战》一书的参与者,在三年内阅读了超过 155 本关于人工智能、哲学以及对人类意味着什么的书籍。他和他的伯恩山犬“博伊·温斯顿”以及收养的边境牧羊犬“影子”住在马萨诸塞州的梅尔罗斯。
一种构建知识图的无代码方法
利用像 KgBase 这样的无代码平台从关系数据中获得新的见解
Niklas Ohlrogge 在 Unsplash 上拍摄的照片
我们周围的世界充满了不同实体之间丰富的关系。我们可以在我们的社交网络、企业内部的组织结构图,甚至维基百科上的所有出版物中找到有意义的链接。
这些联系中的数据包含丰富的信息,从中可以得出深刻的见解,这就是知识图擅长捕捉这些关系的地方。
本文深入探讨了我们如何利用无代码平台,如 KgBase 来创建知识图,并给出了一个涉及药物副作用分析的例子。
目录
【1】快速知识简介图表(2)无代码平台的崛起
(3)创建我们第一个无代码知识图表
(1)知识图表快速介绍
知识图组织来自现实世界实体(例如,对象、事件、概念)网络的数据,并捕捉它们之间有意义的(又名语义 ) 关系。
样本知识图|图片来源:斯坦福 CS 520
在其最简单的形式中,知识图是一个有向带标签图,它由三个部分组成:节点、边和标签。
我们来看上面知识图中用红色圈出的例子(**Albert Einstein**
→ **Germany**
)。节点是阿尔伯特·爱因斯坦(人)和德国(国家)边是这一对节点之间的连接,标签代表关系的含义(即阿尔伯特·爱因斯坦出生在德国)。
由于知识图在大规模表示实体和关系方面的可靠性,以及企业在从蓬勃发展的数据存储中提取价值方面日益增长的需求,知识图最近受到了欢迎。
它们目前广泛用于研究和行业的许多应用中,例如聊天机器人、搜索引擎和产品推荐。
奥马尔·弗洛雷斯在 Unsplash 上拍摄的照片
(2)无代码平台的崛起
尽管对编程大肆宣传,但大多数人确实不(也不需要不)知道如何编码。重要的是,组织需要那些知道如何用正确的工具解决问题的人。
无代码解决方案的可用性使数据科学民主化,允许非技术用户执行复杂的分析任务,而无需编写任何代码。
这些解决方案围绕用户友好的用户界面构建,用户只需单击、拖放元素,即可执行一系列自动化功能。
KgBase 是专门为知识图构建的无代码平台的一个例子,它提供了一个即插即用的系统,使用户能够以不同的方式查看各种关系和实体中的数据。
(3)创建我们的第一个无代码知识图
让我们探索一下如何用 KgBase 在仅仅五个步骤中创建图形。我们将对 13 种常用处方药的副作用进行探索性分析。
数据来源于斯坦福网络分析项目( SNAP )。具体来说,我们有三个数据子集(来自原始 ChChSe-Decagon 数据集)要处理:
- drugs . CSV→该组 13 种药品的药品名称和药品代码
- 副作用. CSV→副作用名称及对应代码(MedGen 概念 ID)
- 匹配-药物-副作用. csv →药物及相应副作用的表格数据
match-drug-side-effect.csv |图片作者
步骤 1 —创建项目
登录后,我们将看到仪表板登录页面。点击空白文件夹(带有 + ),使用空白模板开始一个新项目,并给项目命名,例如药物副作用**。**
作者图片
步骤 2 —导入数据
在项目创建之后,已经有一个默认的节点标题为表 1。现在的目标是为三个数据集中的每一个创建一个节点。
我们首先通过点击表 1 名称旁边的省略号()菜单将默认节点重命名为药品 ,并选择编辑以更改节点标签。
作者图片
从这里,我们可以导入数据。在数据选项卡中,点击齿轮图标并从菜单中选择导入数据**。**
作者图片
找到 DRUGS.csv 进行上传,然后在随后的配置 csv 文件部分勾选包含标题行和创建列两个复选框,然后点击继续**。**
作者图片
至此,我们完成了包含 DRUGS.csv 数据的第一个节点。然后我们再添加和两个节点,并对剩下的两个数据集重复上面的指令。
我们通过点击添加按钮来添加节点,我们可以将这两个节点命名为副作用和匹配表。
作者图片
这样做好之后,我们就要有三个节点:药物、副作用、匹配表。
步骤 3 —设置标签
我们将标签设置为药物和副作用的名称,这样我们的图表将显示名称而不是难以理解的代码。****
我们首先从列标题旁边的省略号下拉菜单中选择“用作标签”。确保对所有三个节点的执行此操作,以便药物名称和副作用名称列最终会在旁边有一个灰色的“标签指示器。****
作者图片
步骤 4 —定义节点之间的关系
转到’匹配表’节点,定义所有节点之间的关系。我们点击药品名称栏旁边的省略号菜单,选择“到关系”。
作者图片
我们选择“一对一关系”按钮(因为这是一对一的名称映射),然后单击下一个的。****
作者图片
在下一页,我们将被要求指定一个目标节点标签。我们的目标节点标签( drug_name )已经存在于药品节点中,所以我们在点击 Convert 之前从现有的表格中选择合适的标签。
作者图片
我们对副作用重复这一步骤,其中我们为匹配表节点中的 side_effect_name 与副作用节点中的匹配 side_effect_name 创建了一个对一关系**。**
当该步骤成功完成时,我们将看到标签在匹配表中以浅蓝色突出显示。
作者图片
步骤 5—将表转换为关系
最后一步是根据源列和目标列将整个匹配表转换成关系**。来源是药物名称,,目标是副作用名称,因为我们希望将每种药物与其副作用联系起来。**
我们通过点击匹配表节点的省略号菜单并选择‘To relationship’来执行此转换。
作者图片
在下一页,我们定义相应的源和目标列,然后选择 Convert 。
作者图片
在转换时(需要 5 到 10 分钟),我们将完成我们的知识图,而无需编写任何代码!
(4)可视化知识图
让我们来看看我们构建的知识图的可视化。我们通过点击顶部栏的图表选项卡来完成,页面将显示图表(基于整个网络的随机样本)。
作者的知识图|图像的可视化
红色节点代表药物,而蓝色节点代表副作用。我们可以很容易地看到,根据淋巴结大小,阿司匹林的副作用数量最多。
当我们选择单个副作用时,例如反射减弱**,我们可以看到哪些药物可能会导致特定的副作用。**
作者的知识图|图像的可视化
用户界面中还有大量选项可用于更深入的分析。这些选项包括将图形限制为特定属性的过滤器和基于预定义约束定位路径的复杂查询。
你可以在 这里 浏览这个项目的公共文件夹。
(5)用业务元数据丰富分析
除了创建知识图表, KgBase 还是一个开放协作的知识图表库的所在地,其中包含全球 10 万多家公司的业务数据。这个丰富的数据库使用户能够将分散的数据符号联系在一起,并消除冗余的映射过程。
例如,对医药公司’ Amgen’ 的简单搜索会返回其通用业务标识符( UBID )和相应的元数据,如品牌映射和财务标识符(例如,CUSIPs、ISINs、DUNS、FIGI 编号等)。)
UBID 知识库中的搜索结果|作者图片
本着开源协作的精神,用户可以通过贡献尚不存在的业务元数据来丰富这个数据库。
例如,“列克制药”的 UBID 是由一名投稿人提供的,该信息随后被批准和添加。
向 UBID 知识图谱库添加元数据|作者图片
(6)结论
关于知识图的能力,我们只看到了冰山一角。例如,企业还可以使用知识图创建通用数据源来连接跨不同领域的多个数据源。
在过去,构建知识图需要大量的工作,但是无代码平台使得非专家创建、集成和维护这样的系统变得更加容易。
因此,看到这些平台继续变得越来越主流并帮助使用知识图表的好处大众化就不足为奇了。
在你走之前
欢迎您来到,与我一起踏上数据科学学习之旅!关注我的媒体页面和 GitHub 以了解更多精彩的数据科学内容。同时,享受构建知识图表的乐趣!
使用 TigerGraph 的地理空间布局功能绘制 UFO 目击图的无代码方法
将 TigerGraph 的地理空间布局功能用于自定义数据集
介绍
概观
在之前的博客中,我们利用 TigerGraph 的新冠肺炎入门套件,通过地理空间布局功能来绘制旅游事件地图。现在让我们看看如何为自定义数据集使用地理空间布局功能。在这种情况下,我们将使用 Kaggle 的 UFO 目击数据集。让我们投入进去吧!
旅程
- 介绍
- 设置 TigerGraph 3.2 解决方案
- 创建模式
- 准备并加载数据
- 绘制目击地图
- 后续步骤
工具和资源
- TigerGraph 云
- Kaggle (特别是 UFO 数据集)
第一步:建立一个 TigerGraph 3.2 解决方案
首先,我们将推出一个免费的 TigerGraph 3.2 云解决方案。为此,导航至https://tgcloud.io/并登录或注册。
在左侧边栏中,选择“我的解决方案”,然后按蓝色的“创建解决方案”按钮。
点击“我的解决方案”,然后点击“创建解决方案”(图片由作者提供)
在第一页上,确保您的版本是 3.2,并选择空白的初学者工具包。按下一步。
创建一个空白的 3.2 解决方案(图片由作者提供)
不要更改第二页上的任何内容。本质上,这只是为你创造了一个免费的解决方案。
第二页保持原样(图片由作者提供)
在第三页上,更新特定解决方案的信息。
将此更新到您的解决方案中(图片由作者提供)
最后,在第四步,确认一切正常,然后点击“提交”
仔细检查一切并提交!(图片由作者提供)
等到你的状态变成绿色,然后按下四个方块并从下拉菜单中选择“GraphStudio”来启动 GraphStudio。
当你的状态变成绿色时,按下四个方块,然后从下拉列表中点击“GraphStudio”
完美!现在您已经准备好创建您的模式了。
第二步:创建模式
让我们首先基于数据创建模式。为此,点击“全局视图”,然后创建一个新的图表(我称之为不明飞行物)。
点击“全局视图”并从下拉菜单中点击“创建图表”(图片由作者提供)
输入 Graphname(如“UFO”)(图片由作者提供)
要开始设计模式,请按“设计模式”选项卡。
点击进入“设计模式”标签(图片由作者提供)
要添加(局部)顶点,请按顶部的加号按钮并适当编辑属性。
按加号添加一个局部顶点(图片由作者提供)
适当地更新属性。(图片由作者提供)
要添加边,请单击箭头,然后单击要连接的两个顶点。
用箭头添加一条局部边,然后单击要连接的两个顶点(图片由作者提供)
根据需要编辑属性(图片由作者提供)
至于模式设计,虽然我们可以使它更复杂,但我选择将国家、州和城市分成顶点(用它们的值作为主 id 和属性),并将其余数据添加到主 id 为 DateTime 的景点顶点中。
图表的模式(图片由作者提供)
瞄准顶点的属性(图片由作者提供)
一旦创建了模式,按向上键发布模式,您就可以进入下一步了!
按向上箭头发布模式(作者图片)
第三步:准备和加载数据
接下来,我从 Kaggle UFO 目击数据集下载了 complete.csv 文件,并上传到 GraphStudio。为此,导航到“将数据映射到图形”选项卡,然后单击“添加数据文件”选项。
导航到“地图数据”选项卡,然后单击“添加数据文件”选项。(图片由作者提供)
按加号,上传 CSV,然后添加。
选择 CSV,然后按“添加”按钮。(图片由作者提供)
然后,我将 CSV 映射到适当的顶点和边。为此,您可以单击 CSV,按下带有“将数据文件映射到顶点或边”悬停数据的交叉箭头,然后适当地映射数据。
绘制数据图(图片由作者提供)
最后,我通过导航到“Load Data”并按下 play 按钮将数据加载到图表中。
转到“加载数据”选项卡并按下播放按钮。(图片由作者提供)
之后,在图表统计中,您应该会看到图表中所有的顶点和边。
您应该可以看到图中的顶点和边(图片由作者提供)
完美!现在我们可以绘制数据。
第四步:绘制景点地图
最后,使用“Explore Graph”选项卡,我绘制了数据。我首先选择了 100 个景点。
导航到“探索图”并选择 100 个观察点。(图片由作者提供)
接下来,我单击强制并选择地理空间地图选项。这样,顶点就就位了!
测绘结果(图片由作者提供)
从这一点,我可以说大多数的 UFO 目击事件,至少从这个样本来看,是来自美国的。我探索了更多的数据,并放大了美国,以了解更多关于这些目击事件的信息。
只有美国地图(图片由作者提供)
从这里,我可以在 GraphStudio 中微调我的数据探索等等,而无需编写任何代码。
第五步:下一步
完美!既然您已经在这个自定义图表上使用了地理空间映射功能,那么您现在可以轻松地在自己的项目中使用它。如果您有任何问题或遇到任何错误,请随时在社区论坛上发表。
https://community.tigergraph.com/
此外,你可以和更多的 TigerGraph 开发者在社区 Discord 上聊天。
祝你在你的项目中使用这些地图好运,我迫不及待地想看看你创造了多么棒的项目!
数据源
使用的数据来自 Kaggle 这里是,没有指定许可证。西格蒙德·阿克塞尔在这里从 NUFORC 数据中搜集、地理定位和时间标准化了这个数据集。
一个非流行病学家对美国新冠肺炎疫苗接种公开数据来源的统计检查
试图合成一个复杂的数据集网络
图片作者:尼克·费因斯
2021 年 3 月 29 日,我收到了印第安纳州卫生部的电子邮件邀请我接种新冠肺炎疫苗。我没有密切关注疫苗的推出,我正在寻找经验。我的目标是更好地理解疫苗接种运动。在本文发表时,大约 25%的美国人口已经接种了疫苗。我试图获得一些背景资料,并在新冠肺炎的误传世界中梳理出什么是事实,什么是虚假的。从我对 COVID 数据集的早期研究中,我希望看到数据实践的发展。这是跟踪一个非常重要的现实世界现象的一个资金充足的最佳尝试,因此它是数据结构和“最佳实践”的一个很好的例子。作为一个数据猴,很难忽视。所有的代码都是公开的,可以在这里找到:
数据源
- 《纽约时报》新冠肺炎州级病例跟踪系统(
cvd
)维护着州级每日新增病例和死亡人数数据 定义 - 牛津新冠肺炎政府响应跟踪系统(OxCGRT,又名
oxf
)描述了与政府政策相关的事件时间表,但不太详细。数据 定义 - OWID (
vax
)结合多种来源数据 定义维护每日接种疫苗和完全接种疫苗的人数 - 美国人口普查州级人口(
pop
)是基于美国人口普查工作数据 定义对美国人口最全面和最纯粹的估计
连接这些数据源需要清理转换。这些转换的代码在这个博客中进行了总结,在这里我就不赘述了。然而这些代码都可以在公开回购中找到。
数据质量报告
新冠肺炎纽约时报
开始:2020–01–21
结束:2021–03–31
今天:2021–04–01
接种反应变量全状态记录:
- 开始时间:2020 年 3 月 13 日
- 结束时间:2021 年 3 月 31 日
- 未满:【<=2020–03–12]
- subset of states always reporting: [Washington]
Conclusions:
- We remove the data prior to 2020–03–13.
OxCGRT
Starts: 2020–01–01
结束:2021–03–30
今日:2021–04–01
接种反应变量全状态记录:
- 开始时间:2020 年 9 月 14 日
- 结束时间:2021 年 3 月 29 日
- 未满:[2020–12–08,> = 2021–02–12]
结论:
- 我们假设在 2020 年 9 月 14 日之前,没有已知的疫苗接种,因此这些人实际上是 0
OWID 疫苗接种数据(州级数据)
开始:2020–12–20
结束:2021–03–31
今天:2021–04–01
接种反应变量全状态记录:
- 开始时间:2020 年 9 月 14 日
- 结束时间:2021 年 3 月 29 日
- 未满:[2020–12–08,> = 2021–02–12]
结论:
- 除了每个州何时开始提供疫苗之外,这个数据集可能对一些问题有用。
- 不能用于确定疫苗接种活动的早期时间表,即开始日期。
- 反映了疾病预防控制中心如何将疫苗接种归属于各州的政策变化,该政策从 2021 年 2 月 19 日开始实施。这将在这篇博客中一瞥而过,但是解释这个噩梦所需的策略值得在第二篇文章中讨论。代码可在 github 中获得。
清洁任务的非详尽总结
- 我们将连接数据集的关键索引是日期和州名,因此我们在数据集之间符合日期和州名
- 牛津数据集要求将关键变量编码为类别,该数据集描述了与政府政策实施相关的大致时间表,包括美国各州的疫苗接种活动
- 由于疫苗接种数据集在 COVID 病例跟踪数据集之后开始,因此我们在疫苗接种数据集可用之前用 0 填充日期。
- 异常移除。在 OWID 数据集中,起始观测值是异常的。我认为这是因为数据实际上没有涵盖真正的开始日期,所以第一次观察从零开始进行了不合理的跳跃。
- 人口调整。每个源数据集可能已经提供了人口调整后的估计值,也可能没有。我们选择使用疫苗接种、新增病例和死亡的非调整来源观察,所有人口估计都始于独立来源的 2019 年美国人口普查。
调查目标
问题在一开始就被定义,以集中工作并避免迷失在数据的海洋中。可能目前有 1000 多个数据源,它们形成了一个复杂的相互依赖的网络。尝试以某种有意义的方式来度量这种相互依赖性将是一项有趣的后续任务。选择 4 个数据集来回答我们的问题,但它们也包括许多其他变量。所以专注是关键。
调查将围绕 3 个主要问题展开:
- 每个州什么时候开始接种疫苗,谁是第一个,最后一个,平均水平?统计显著?
- 哪些州在给人们接种疫苗和完全接种疫苗方面最快、最慢、一般?统计显著?
- 哪些州看到了疫苗接种对减少新病例的最大、最小和平均影响?统计显著?
该调查将试图解释以下主要混淆因素:
- 在开始接种疫苗时,冠状病毒检测呈阳性的人口比例是多少?(例如,合格人口的规模有多大?)
- 人群中发生了多少个人之间的高风险活动?
- 发生了多少误诊?数据集中有多少噪音?哪些州最擅长报告病例?
- 接种了哪种疫苗?
- 与疫苗相比,行为改变在多大程度上影响了病例/死亡的减少?
每个州从哪一天开始接种疫苗,谁是第一个,最后一个,平均?统计显著?
冠状病毒疫苗的采购在州一级进行,并非所有的州都同时开始。这里,我们考虑每个州的疫苗接种日期变为非零(“0-不可用”)。统计显著性的度量基于日期的分布,我们将描述异常和统计显著性异常。绘制密度图,每天,我们计算开始接种疫苗的州的数量。所以,我们需要计算疫苗首次出现的日期。
如果你知道更多关于这个过程是如何运行的,以及为什么一些州比其他州更慢地实施他们的第一批疫苗,请随时留下评论。作者也没有排除牛津数据集在具体日期上出错的可能性。
疫苗接种的早期、正常和晚期状态
第一个州:俄克拉荷马州(2020–12–11)
最后一个州:亚利桑那州(2021–01–05)
平均日期:(2020–12–15)
中位数日期:(2020–12–15)
标准差:3.74 天
异常和统计显著性
典型的州于 2020 年 12 月 15 日开始为其人口接种疫苗。有 3 个州起步较晚,从最晚的开始:亚利桑那州、内布拉斯加州和密苏里州(按此顺序)。亚利桑那州和内布拉斯加州可被视为统计显著异常,因为它们超过平均值的 3 个标准偏差。
vax_start_dates_oxf = []
for state, data in oxf.df.groupby('state_name'):
a = data[data['vaccination_policy'] != 0.0]
b = a.sort_values('date').iloc[0]
c = b.to_dict()
vax_start_dates_oxf.append(c)
vax_start_dates_oxf = pd.DataFrame(vax_start_dates_oxf)
first_vax = vax_start_dates_oxf.date.min()
vax_start_dates_oxf['days_from_first'] = vax_start_dates_oxf['date'].apply(lambda x: (x-first_vax).days)
vax_start_dates_oxf['days_from_first'].hist(
bins=vax_start_dates_oxf['days_from_first'].max(),
figsize=(16,3), grid=True,
)
州疫苗接种开始日期的 z 分数(图片由作者提供)
接种疫苗的速度:哪些州在给人们接种疫苗和完全接种疫苗方面最快、最慢、一般?统计显著?
加载了两个数据集,其中包含有关全州推广速度的信息。目标是尽快为尽可能多的公民接种疫苗。所以每天我们都会考察一个“步伐排行榜”。我们将为每个日期计算一个函数,该函数根据接种疫苗的受试者和完全接种疫苗的受试者的数量返回各州的有序列表。为此,我们将使用 OWID 数据集,其中包含已接种疫苗的数量。我们将向数据集添加两个新值:
- 各州 2019 年人口普查人口实施的疫苗接种
- 从开始算起的天数
首先,我们观察接种过疫苗的受试者,然后详细讨论等级排序背后的分布,以检验显著性。
我们研究的变量来自 OWID 中的底层数据。
adj_vax['adj_total_vaccinations'] = adj_vax.apply(
lambda x: x['total_vaccinations'] / float(state_to_pop[x['location']]),
axis=1
)
adj_vax['people_vaccinated_%pop'] = adj_vax.apply(
lambda x: x['people_vaccinated'] / float(state_to_pop[x['location']]),
axis=1
)
adj_vax['people_fully_vaccinated_%pop'] = adj_vax.apply(
lambda x: x['people_fully_vaccinated'] / float(state_to_pop[x['location']]),
axis=1
)
adj_vax['days_from_start'] = adj_vax.apply(
lambda x: (x['date'] - state_to_start[x['location']]).days,
axis=1
)
速度领先和统计显著性
为了确定领先是否具有统计显著性,我们将使用“领先步速”的分布作为步速测量的(k-1)-th
和k-th
观察值之间的%差异。因此每天会有 50 次观察,N=40*50=2000
接近于一个显著样本量的观察来检验这个问题。因为我们是根据每日排名的有序列表计算领先速度的,所以我们通过顺序统计进行建模,并将通过比较j-th
和k-th
“领先速度”的分布来检验“领先就是领先”的假设,其中j != k
。
疾病预防控制中心政策变化引起数据质量问题
(彭博,2021–01–21)描述了我们观察到的people_vaccinated
和people_fully_vaccinated
的累计和在减少的问题。影响 OWID 数据集的 CDC 政策变化的生效日期并不完全相同,因此这使得各州疫苗制度之间的比较变得复杂。我最初是通过寻找变化大到足以导致接种疫苗的人数少于政策变化前一天的例子来发现这一政策变化的影响的。对于该系列变得非单调的州来说,那一天肯定是开始,华盛顿特区将经历巨大变化是有道理的,因为它是联邦雇员相对于人口最集中的地方。然而,这很可能不是影响的程度-其他国家可能有更微妙的影响,但仍然很大。有没有人开发出方法来解释和量化 CDC 政策变化的影响?
应对疾病预防控制中心政策变化的一些挑战包括:
- 各州在不同的日子开始了新的 CDC 计数程序
- 各州经历了不同的影响大小,其中一些很难检测到,而华盛顿特区经历了巨大的影响,因为 CDC 开始以不同的方式计算联邦管理的疫苗,其他州可能影响很小。那么这个怎么衡量呢?
因此,对策以一个规则为中心,该规则可以确定 cdc 政策的开始生效日期,因此我们可以根据各州是在政策之前还是之后对它们进行分组。我们通过计算 CDC 政策宣布生效后的标准差来检查dod_%diff_state_people_vaccinated
的异常情况,并发现数量大于平均值的 2 个标准差dod_%diff_state_people_vaccinated
。最合适的日期是 2021 年 2 月 17 日
当前排名
自然,疫苗的首次展示在一些地方比其他地方进行得更好。最大的问题是为什么一些州比其他州快得多,以及一些瓶颈是否基于政治地位。
最快的疫苗推广速度
至少接种一次疫苗
最快的是至少接种一次疫苗,占 2019 年美国人口普查人口的百分比。(截至 2020 年 4 月 7 日)(图片由作者提供)
完全接种疫苗
最快全面接种疫苗占 2019 年美国人口普查人口的百分比。(截至 2020 年 4 月 7 日)(图片由作者提供)
疫苗推出最慢
至少接种一次疫苗
在 2019 年美国人口普查中,接种疫苗至少一次的比例最慢。(截至 2020 年 4 月 7 日)(图片由作者提供)
完全接种疫苗
按 2019 年美国人口普查人口的百分比计算,最慢到完全接种疫苗。(截至 2020 年 4 月 7 日)(图片由作者提供)
当我们观察完全接种疫苗的人口百分比与至少接种一次疫苗的人口百分比时,疫苗接种的领导者发生了变化。虽然新罕布什尔州和康涅狄格州在至少给人们接种一次疫苗方面做得很好,但他们在给人们接种疫苗方面做得不够好。特别是在新罕布什尔州,该州在至少接种一次疫苗方面排名第二,但在完成接种方面排名第 22。落后者也会改变。例如,密西西比州在全国至少给人口接种一次疫苗方面是第三慢的,但在完成疫苗接种方面仅是第八慢的。其他值得注意的变化包括华盛顿特区,它不算太差,在至少接种一次疫苗方面排名第 15,但在完成接种疫苗方面排名第 5。当然,最极端的对比是新罕布什尔州,该州在接种一次疫苗方面表现出色,但在完成接种方面还可以。
哪些州见证了全面接种疫苗对减少新发病例的最大、最小和平均影响?统计显著?
据称,Moderna 和辉瑞公司的疫苗在预防该病毒方面有大约 90%的有效性。因此,我们将绘制已完全接种疫苗的人口百分比相对于新增病例数的图表。我们希望看到一个直接和明显的趋势来加强这些说法。我们可以看看在完成疫苗接种方面最有效的州,比如新墨西哥、南达科他和阿拉斯加。然而,在这种情况下,前 3 名的人口密度都很低。康涅狄格和新泽西可能是很好的例子,因为他们在为人口全面接种疫苗方面做得很好,并且人口相对密集和活跃。
解决方案设计:
- 将纽约时报的
cvd
数据集与adj_vax
数据集连接起来。我们想要一个右连接,所以我们保留来自cvd
的索引,并添加来自adj_vax
的观察值 - 看专栏:纽约时报的
cases
和 OWID 的people_fully_vaccinated_%pop
说明现有的免疫力、畜群和疫苗接种
免疫的两个主要来源导致易感染新冠肺炎病毒的人群显著减少。群体免疫发生在人们感染病毒后,他们在一段时间内是免疫的。根据在伦敦英国公共卫生主办的塞壬研究的 Susan Hopkins在《自然》杂志(2021 年 1 月 14 日)上总结的说法,患有新冠肺炎病毒的人几乎不可能在几个月内患病。疫苗免疫是指人们不太可能因为被戳而感染病毒。
将疾病时间表考虑在内导致实施了 3 个数量,这使得能够对每个州的弱势人群进行估计。数据集的聚合使分析变得复杂,因为我们缺少关键信息。也就是说,我们不知道当时有多少患者被诊断为t
死亡或康复。在这种情况下,数据很难解释,因为我们不知道疾病最初被发现后几周的结果。但是,即使在“有人应该知道”检测呈阳性的病人是康复了还是死了的情况下,我们也没有这些信息。也许有,但是在发表的时候,这个数量还不知道。
我们使用 3 个假设来控制免疫人群,如下所示:
vax_imm_lag = 14
:接种疫苗的人在完全接种后vax_imm_lag
天开始免疫case_incub_pd = 10
:人们感染新冠肺炎病毒并开始出现症状的间隔天数case_imty_pd = 4
:一个人拥有 covid 几个月后,他们可以再次获得它
我们利用以下这些量实现逻辑:
cvd_and_vax = pd.merge(
left=cvd.df, right=adj_vax,
how='left', left_on=['date', 'state'],
right_on=['date', 'location']
).copy()
cvd_and_vax[['total_vaccinations', 'total_distributed', 'people_vaccinated',
'people_fully_vaccinated_per_hundred', 'total_vaccinations_per_hundred',
'people_fully_vaccinated', 'people_vaccinated_per_hundred',
'distributed_per_hundred', 'daily_vaccinations_raw',
'daily_vaccinations', 'daily_vaccinations_per_million',
'share_doses_used']] = cvd_and_vax[['total_vaccinations', 'total_distributed', 'people_vaccinated',
'people_fully_vaccinated_per_hundred', 'total_vaccinations_per_hundred',
'people_fully_vaccinated', 'people_vaccinated_per_hundred',
'distributed_per_hundred', 'daily_vaccinations_raw',
'daily_vaccinations', 'daily_vaccinations_per_million',
'share_doses_used']].fillna(0.,)cvd_and_vax.dropna(subset=['state'])
del cvd_and_vax['location']cvd_and_vax['cases_%pop'] = cvd_and_vax.apply(
lambda x: compute_fn(
a=x['cases'],
b=apply_dic(state_to_pop, x['state']),
fn=lambda a,b: a/b),
axis=1
)
cvd_and_vax['deaths_%pop'] = cvd_and_vax.apply(
lambda x: compute_fn(
a=x['deaths'],
b=apply_dic(state_to_pop, x['state']),
fn=lambda a,b: a/b),
axis=1
)
cvd_and_vax.index = cvd_and_vax['date']### state-level calcs ###
# an adjusted population measurement accounting for people who have been immunized and
# we have a challenge adjusting the population because if we adjust by deaths and cases, we are double counting
# this is a cost of having aggregated non-subject level data sets. It's impossible to know how to account for
# the cases and deaths in a harmonious way
# - increase people_immd by people_fully_immunized on (t-vax_imm_lag) days ago
# - increase people_immd by cases on (t-case_incub_pd) days ago
# - decrease people_immd by cases that happened more than case_imty_pd*30 days ago
# - don't do anything with deaths because not that many people have died in the grand schemevax_imm_lag = 14 # vaccinated people are immune starting X days after the fully vaccinated
case_incub_pd = 10 # days between people contract covid-19 and start being symptomatic
case_imty_pd = 4 # months after a person has covid, they can get it againstate_level_cvd_and_vax = []
for state, data in cvd_and_vax.groupby('state'):
tmp = data.copy()
tmp['new_daily_cases'] = tmp['cases'] - tmp['cases'].shift(1)
tmp['new_daily_deaths'] = tmp['deaths'] - tmp['deaths'].shift(1)
tmp['people_fully_vaccinated_%pop_immLagAgo'] = tmp['people_fully_vaccinated_%pop'].shift(vax_imm_lag)
tmp['new_daily_people_fully_vaccinated'] = tmp['people_fully_vaccinated'] - tmp['people_fully_vaccinated'].shift(1)tmp['people_immd'] = \
tmp['new_daily_cases'].shift(case_incub_pd) \
+ tmp['people_fully_vaccinated_%pop_immLagAgo'] \
- tmp['new_daily_cases'].shift(case_imty_pd*30)tmp['people_immd_%pop'] = tmp.apply(
lambda x: compute_fn(
a=x['people_immd'],
b=apply_dic(state_to_pop, x['state']),
fn=lambda a,b: a/b),
axis=1
)
state_level_cvd_and_vax.append(tmp)state_level_cvd_and_vax = pd.concat(state_level_cvd_and_vax, axis=0)
state_level_cvd_and_vax['new_daily_cases_%pop'] = state_level_cvd_and_vax.apply(
lambda x: compute_fn(
a=x['new_daily_cases'],
b=apply_dic(state_to_pop, x['state']),
fn=lambda a,b: a/b),
axis=1
)
state_level_cvd_and_vax['new_daily_deaths_%pop'] = state_level_cvd_and_vax.apply(
lambda x: compute_fn(
a=x['new_daily_deaths'],
b=apply_dic(state_to_pop, x['state']),
fn=lambda a,b: a/b),
axis=1
)# compute vulnerable population which is the (census "POP" - people_immd)
state_level_cvd_and_vax['vpop'] = state_level_cvd_and_vax.apply(
lambda x: compute_fn(
a=apply_dic(state_to_pop, x['state']),
b=x['people_immd'],
fn=lambda a,b: a-b),
axis=1
)state_level_cvd_and_vax['new_daily_cases_%vpop'] = state_level_cvd_and_vax.apply(
lambda x: compute_fn(
a=x['new_daily_cases'],
b=x['vpop'],
fn=lambda a,b: a/b),
axis=1
)
state_level_cvd_and_vax['new_daily_deaths_%vpop'] = state_level_cvd_and_vax.apply(
lambda x: compute_fn(
a=x['new_daily_deaths'],
b=apply_dic(state_to_pop, x['state']),
fn=lambda a,b: a/b),
axis=1
)
实际上,我们正在观察 14 天前对新冠肺炎病毒免疫的人口百分比与每日新增病例和每日新增死亡人数的对比。然而,我们没有用总人口来衡量新增病例和新增死亡,而是减去了完全接种疫苗的人群和过去 4 个月内患有 covid 的人群。所有州之间的比较如下图所示:
from scipy.optimize import curve_fit
from scipy.stats import linregress
def do_linregress(df, xcol, ycol):
linfn = lambda x,a,b: a*x+b
expdata = df.dropna(subset=[xcol, ycol], how='any').copy()
return linregress(
x=expdata[xcol],
y=expdata[ycol]
) ax1 = state_level_cvd_and_vax.plot.scatter(
x='people_fully_vaccinated_%pop_immLagAgo', y='new_daily_cases_%vpop', figsize=(16,7), s=2)cases_reg = do_linregress(
df=state_level_cvd_and_vax,
xcol='people_fully_vaccinated_%pop_immLagAgo',
ycol='new_daily_cases_%vpop'
)
plt.plot(
state_level_cvd_and_vax['people_fully_vaccinated_%pop_immLagAgo'],
state_level_cvd_and_vax['people_fully_vaccinated_%pop_immLagAgo']*cases_reg.slope+cases_reg.intercept,
'g--', label='linear fit: slope={}, intercept={}, r^2={}'.format(cases_reg.slope,cases_reg.intercept,math.pow(cases_reg.rvalue,2)))
ax1.legend(loc="upper right")ax1.set_ylim(0.,.00125)print('Assumption: immLag = {}: days after second vaccination for immunity'.format(vax_imm_lag))
截至 14 天前完全接种疫苗的人口百分比与非免疫人口中每日新发病例的流行率。(图片由作者提供)
我们看到有一个明显的下降趋势,表明随着各州接种疫苗越来越多,新冠肺炎的流行程度越来越低。让我们看看一些最好的疫苗接种者和最差的疫苗接种者。这是一个好消息,与我们的希望一致,疫苗正在发挥作用。让我们往下钻。这种方法的一个问题是,虽然总体趋势是负面的,但各国看到的是不同的现实。
人口密度高的州:领先的新泽西州(8)和康涅狄格州(5)对落后的哥伦比亚特区(-5)和佐治亚州(-1)
更密集的人口应该会看到更集中的影响,因为人们彼此接触得更多(乔什昆、耶尔德勒姆和冈杜兹,2021 )。在那项研究中,94%的传播可以用人口密度和风来解释。新泽西州和康涅狄格州由纽约市大都会区主导,而华盛顿特区是华盛顿特区,佐治亚州是亚特兰大。
康涅狄格州排名第五,24.1%的人口接种了全部疫苗。新泽西州排名第八,其 22.6%的人口接种了全部疫苗。我们看到康涅狄格州对新病例的疫苗有轻微的负面影响,我们注意到趋势的解释方差非常低。随着疫苗接种的增加,新泽西州的新病例实际上呈上升趋势。
康涅狄格州:截至 14 天前完全接种疫苗的人口百分比与非免疫人口中每日新发病例的患病率。(图片由作者提供)
新泽西州:截至 14 天前完全接种疫苗的人口百分比与非免疫人群中每日新发病例的患病率。(图片由作者提供)
佐治亚州是全国接种速度最慢的州,只有 14.1%的人口接种了全部疫苗。哥伦比亚特区是第五慢的,有 16.0%的人口完全接种了疫苗
格鲁吉亚:截至 14 天前完全接种疫苗的人口百分比与未免疫人口中每日新发病例的流行率。(图片由作者提供)
哥伦比亚特区:截至 14 天前完全接种疫苗的人口百分比与未免疫人口中每日新发病例的患病率。(图片由作者提供)
效果最明显的是乔治亚州,该州是全国最慢的全面接种者。这表明,除了疫苗之外,其他因素也是原因之一。
结论
在以这种方式检查了所有的州之后,看来疫苗的效果和它减少新病例的能力充其量是微弱的。没有清晰明显的效果可以看出来。对该国最好和最差的疫苗接种者的比较得出了一个令人困惑的结果。新病例的总体趋势似乎是负面的,然而,如果不是因为疫苗,那么这将只是政府出台的无数政策导致的暂时下降。随着这些政策的到期,我们可能会看到病毒的死灰复燃。我们解释了一些大的混淆,但更多的存在。我可以看到这将是人们的全职工作,以检查和跟踪各种数据收集,数据清理和建模问题可能存在于此。
基于强化学习的火车站非平凡电梯控制系统
思想和理论
为什么火车站的电梯不同,RL 如何优化整体服务质量
动机
没有电梯,今天的城市生活是无法想象的,电梯控制器算法已经通过不同的技术进行了很好的研究,包括强化学习[1]。浏览参考文献给人的印象是,大多数研究都集中在安装在高层建筑中的电梯上,而对安装在火车站中的电梯几乎没有讨论。然而,火车站的电梯也值得关注,因为它们与建筑物中的系统有着明显的不同。
电梯-列车-车站系统通常具有以下特性:
- 不同列车线路的列车站台位于不同楼层。已经进入车站的人想要去一个特定的楼层乘火车,而已经乘火车到达的人将离开车站或者在另一个楼层换乘火车。
- 在高峰时间,不存在像大楼里那样每个人都去的一个方向。一些人可能想离开火车站,而另一些人可能想在另一层楼换车。
- 乘火车到达车站的人几乎同时在电梯前等候,而从车站外面来的人不一定属于这种情况。
- 电梯通常是为携带沉重行李或婴儿推车的人保留的,因此它们可能没有巨大的载客量。此外,那些有婴儿车的人可能没有第二个选择,只能呆在电梯等候名单上,直到被运送。
一个很好的例子是巴黎的里昂火车站,它有两个地下楼层,在这两个楼层上你可以分别找到两个不同的列车线站台。
从我个人的经验来看,带着我的婴儿车乘电梯从一楼到二楼换乘火车通常需要相当长的时间。
在下文中,我将模拟一个电梯-火车-车站环境,该环境可以很容易地根据您自己的目的进行修改和重用,并实现强化学习以获得电梯控制器的最佳策略。
电梯-火车站系统
考虑具有 3 层的火车站中的电梯,使得 0 层是作为入口/出口的底层,而 1、2、3 层是列车站台。在 0 层等电梯的人是从外面来的,愿意上楼去乘火车,而其他楼层的人是由预定的火车带来的,要么出站,要么去另一个楼层换换口味。我们假设人们可以在任何时候从外面到达 0 层,而人们同时在火车上到达正楼层。
为了简单起见,我们首先考虑一部单独的电梯。这种简化实际上并没有消除太多的一般性,因为在列车站台上总是只有一部电梯可用。
正三层是不同铁路线的列车站台:1 层 A 线,2 层 B 线,3 层 C 线。每 10 分钟,A 线第一分钟到达,B 线第二分钟到达,C 线第三分钟到达。另外,每一趟列车到站,都会有 5 个人一起加入电梯的等候名单。这是有道理的,因为一般来说,只有那些带着行李或婴儿车的人想乘电梯,而其他人会选择这种耗时的选择。对于每个乘火车到达的人,他将有{0.2,0.2,0.6}的概率分别去另外两层和底层。同时,我们假设每 30 秒,在每 10 分钟的前 3 分钟,有 0.9 的概率有一个人将加入 0 楼的等候名单。对于一楼的每一个人,他将有 1/3 的概率去地下三层的每一层。
这部电梯的最大载客量是 5 人。看起来容量很小,但是请记住,他们也有自己的行李!此外,电梯每次停止需要 10 秒钟,从一层到另一层需要 2 秒钟。
首先,我们有:
- 一层,三层。
- 电梯等候名单中的三组 5 名预定人员和一组非自发人员。
- 载客量为 5 人的电梯。
图吹是系统的草图(忘了我画的不好吧,我从幼儿园就没什么进步)。
作者图片:电梯火车站系统插图
构建 RL 环境
在继续下一步之前,我在这一节的开始给出了强化学习的一些必要元素。
简而言之,在 RL 中,主体以离散时间或连续时间与环境交互。在时间步骤中,代理根据环境的当前状态根据特定策略应用动作,导致新的状态并接收测量状态转换质量的奖励。RL 的目标是学习一个策略,或者是确定性的,或者是概率性的,以最大化累积回报。
让我们回到电梯控制器系统。
环境状态是 R⁷向量(楼层 _ 0 _ 上,楼层 _ 1 _ 上,…,楼层 3 下,占用,位置),其中 floor_i^{up/down}是 1 或 0,是 1。如果需要在电梯外的楼层 I 上升/下降,占用是电梯内乘客总数的整数,并且定位电梯所在的当前楼层。请注意,我们只允许在 0 层上行,在 3 层下行。
功能的报酬定义为-(占有率+总和 _i floor_i^{up/down}),即电梯内外的需求总数。换句话说,奖励为 0 的唯一情况是没有乘客在系统中等待,无论是在电梯内部还是外部。
为了构建 RL 环境,我使用了 open AI Gym,这是一个用于开发和比较强化学习算法的工具包。如何构建一个定制的健身房环境不是本文的目的,读者可以在 want [2]中找到关于他们自己的 RL 环境的说明。下面是电梯类的 init 和 reset 函数。
import gym
from gym import spaces
class Elevator(gym.Env):
metadata = {**'render.modes'**: [**'human'**]}
def __init__(self):
*#observation space
# states0: floor_0_up
# states1: floor_1_up
# states2: floor_1_down
# states3: floor_2_up
# states4: floor_2_down
# states5: floor_3_down
# states6: occupancy
# states7: position* super(Elevator, self).__init__()
self.done = 0
self.reward = 0
self.states = np.zeros(8)
self.states[0]=1
self.last_time = 0
self.time = 0
self.max_occupancy = 5
self.action_space = spaces.Discrete(3) *# 0 stop, 1 up, 2 down* self.observation_space = spaces.MultiDiscrete([2,2,2,2,2,2,6,4])
def reset(self):
self.states = np.zeros(8)
*#suppose that there are already 2 people
# waiting on the first floor at the beginning of the session* self.states[0]=1
self.last_time = 0
self.time = 0
self.floor_0_waiting = 2
self.floor_0_waiting_list = [1,2]
self.floor_1_waiting = 0
self.floor_1_waiting_list = []
self.floor_2_waiting = 0
self.floor_2_waiting_list = []
self.floor_3_waiting = 0
self.floor_3_waiting_list = []
self.inside_list = []
self.done = 0
self.reward = 0
return self.states
对更多细节感兴趣的人可以在 Github 上获得本文的完整代码。
培训和结果
为了训练这个系统,我将使用 DQN 深度 Q 网络。注意,对于给定的初始状态和动作,RL 系统的总累积回报也称为 Q 值。理想的策略应该是最大化 Q 值的策略,Q 值通常是未知的,因此产生 Q 学习作为代理的“备忘单”[3]。DQN 旨在通过深度神经网络来逼近 Q 值。在我的实现中,我在稳定基线的帮助下构建了一个大小为 64 的两层 DQN,这是一组基于 OpenAI 基线的强化学习算法的改进实现。这个实现只需要 3 行代码:
elevator= Elevator()
elevator.reset()
model = DQN(**'MlpPolicy'**, elevator, verbose=0)
model.learn(total_timesteps=1e5)
在训练之前,我让电梯做随机动作,从训练开始到清空等候名单需要 800 多秒。而在 1e5 训练时间步骤之后,在我的本地试验中,电梯设法在 246 秒内清空了等候名单,也就是说,4 分钟而不是 10 多分钟(根据我的经验,我有时在火车站排队等候超过 10 分钟!).这突出了电梯控制器系统的显著改进。
结论
当然,我对系统做了许多简化,例如,火车上的人同时加入等待,当没有火车经过时,没有其他人会加入,但训练的结果仍然令人兴奋。此外,我认为系统中只有一部电梯,但在某些车站可能并非如此。作为下一步,值得在系统中增加更多的电梯,并考虑一个多代理 RL 系统来做进一步的优化。
参考
[1]徐苑·卢西恩·布索尼乌和罗伯特·巴布什卡,电梯控制的强化学习,2008 年。https://www . science direct . com/science/article/pii/s 1474667016392783
[2] Adam King,从头开始创建定制的健身房环境——一个股票市场的例子。https://towards data science . com/creating-a-custom-open ai-gym-environment-for-stock-trading-be 532 be 3910 e
[3]使用 Python 中的 OpenAI Gym 进行深度 Q 学习的实践介绍。https://www . analyticsvidhya . com/blog/2019/04/简介-deep-q-learning-python/
Rust 编程语言的简短介绍
从这里开始,快速学习一门快速、安全、现代的语言
图片来自维基共享资源
你最喜欢的编程语言是什么?
如果你的答案不是生锈,那么请阅读这篇文章。最后,你的答案可能会改变!
在这篇文章中,我将教你 Rust 编程的基础知识。足以让你开始并创建自己的程序。
在文章的最后,我会指导你一些非常好的深造方向。
您可以在 Rust 培训期间以小词典或查找文章的形式回到本文。
学习一门新的编程语言就像学习任何其他语言一样。最快的方法是尝试一下,在这种情况下,你不需要来自不同国家的朋友或飞机。你只需要你的新朋友 Rust 编译器。相信我,它会是一个真正的好朋友。
因此,请随意编写代码,尝试自己的例子,或者像阅读任何其他文章或书籍一样,简单地用一杯浓咖啡阅读这篇文章。
让我们开始吧…
目录
安装和第一个项目
变量
数据类型
∘ 数字
∘ 布尔值
∘ 字符串、 & str 和字符
集合
∘ 数组
∘ 元组
∘ 向量
∘ 哈希映射
函数
控制流和循环
∘ 条件
∘ 循环
Rust 已经存在,如果你想学习一门既安全又经得起未来考验的现代表演语言,Rust 是一个不错的选择。
Rust 是一种系统编程语言,运行速度极快,几乎可以防止所有的崩溃,并消除数据竞争。
尽管 Rust 被归类为系统编程语言,但你真的可以在 Rust 中构建任何东西。你只需要牺牲一些时间。作为回报,你得到的是安全和惊人的速度。
Rust 以难学而闻名,但我认为这实际上取决于最初的方法和心态。
你只需要在编码时有一点不同的想法——就像一个乡下人!
安装和第一个项目
Rust 的安装没有痛苦,这要感谢一个叫做 rustup 的小工具。
你可以按照这里的说明安装 Rust或者只是通过谷歌搜索。
当你安装了 Rust 和它神奇的软件包管理器——Cargo——之后,你就可以开始工作了。
假设您想要创建一个名为“rusty_cli”的项目。
在您的文件系统上找到一个您想要放置项目的位置。然后将自己“cd”到命令/终端中的位置。
当您在想要放置项目的文件夹中时,只需使用cargo new rusty_cli
。
Cargo 将施展它的魔法,创建一个它理解的项目结构,包括一个名为src
的文件夹,里面是一个名为main.rs
的文件。
文件main.rs
是程序的入口点。为了运行程序,你有几个不同的选择使用货物。
您可以使用cargo run
在调试模式下运行主文件,或者使用cargo build
创建可执行文件。这个可执行文件将存储在target/debug
中。
你不必使用 cargo 来编译和运行 Rust 程序,但它是一个非常友好的工具,我强烈推荐使用它。
当您准备好构建最终的可执行文件时,您可以使用命令cargo build --release
对其进行编译和优化。该命令将在target/release
而不是target/debug
中创建一个可执行文件。
这些优化使 Rust 代码运行得更快,但编译时间上的损失很小。
变量
Rust 中的变量是使用let
关键字定义的,默认情况下是不可变的。我们来举个例子。下面的代码将还没有编译。
如果你一直跟随,那么你会看到编译器抱怨类似“不能给不可变变量赋值两次”。
为了解决这个问题,我们可以采取以下措施:
注意,如果我们把关键字mut
放在变量名的前面,那么变量就变得可变了。
另外,请注意 Rust 中的表达式是如何工作的。表达式是返回值的东西。如果你加上分号,你就抑制了这个表达式的结果,这在大多数情况下是你想要的。
当我们一会儿谈到函数时,这一点会更清楚。
数据类型
数据类型通常与算术运算密切相关,但我不会花太多篇幅来讨论这个问题,因为对数字的常见运算也适用于 Rust。
Rust 中的许多数据类型与其他语言共享。我们有整数类型,如i32
或i64
,也有浮点数类型,如f64
。
我们还有数据类型bool
,它可以包含值true
或false
*,*我们有string
, *&str*
和char
用于存储文本数据,还有tuple
,array
,vector
和hash map
作为一些常见的集合。
在此之上,我们有structs
、 *methods*
和associated functions
作为 OOP 语言中类和方法的替代,还有一个有趣的类型叫做trait
,有点像接口,例如 Go 。
除了用于结构化相关数据的结构和元组结构,我们还有在 Rust 语言中起核心作用的类型enum
。
其中一些类型的用法最好通过例子和自己的实验来学习,但是,我认为在这一点上一些最初的解释和例子是合适的。
数字
请注意,当您声明变量时,您可以选择通过在声明中显式声明来指定数据类型。
如果我们想存储一个包含大小为 8 位的无符号整数的变量,我们必须像下面这样做:
如果你刚刚写了let age = 18;
,那么 Rust 会推断出年龄的类型是i32
。
布尔运算
Rust 中称为“布尔”的布尔与其他语言中的布尔相似。语法是true
和false
(注意小写),一个例子是let b = true;
。
字符串、字符串和字符
字符类型用单引号写成,如*‘c’*,表示数据类型的关键字是char
。
Rust 中的字符串比 Python 中的要复杂一些,但这是因为 Python 中隐藏了很多细节。嗯,没有那么多铁锈!
这样做的原因是为了防止将来处理字符串时出现错误。Rust 中的一个常见概念是,该语言通过处理编译时可能出现的错误来确保安全性。无论如何,这是一件好事,但它对程序员提出了一些要求。
字符串被实现为字节的集合,当这些字节被解释为文本时,还有一些方法提供有用的功能。
字符串比许多程序员认为的更复杂。这是因为它们对程序员来说很自然——毕竟,我们现代人习惯于在日常生活中处理文本。
然而,由于我们认为有意义的子串和机器如何解释子串之间存在差异,事情并不像看起来那么简单。我们需要一种叫做编码的东西作为机器和大脑之间的桥梁。
我们不会深入编码世界的细节,但是如果你发现自己有一天晚上无法入睡,那么尽一切办法进行一次研究之旅,深入研究编码,它比你想象的更令人着迷!
Rust 在UTF-8
中对字符串进行编码,与 Python 不同,我们可以让字符串在 Rust 中生长。
如上所述,Rust 有不止一种类型的字符串。类型String
和类型str
,后者通常以&str
、的形式出现,被称为字符串片或字符串文字。
一个String
被存储为一个字节Vec<u8>
的向量,并带有方便的方法:
我们将很快处理向量。现在,你可以把它们看作一个典型的数组。
这两种类型的字符串之间到底有什么区别,现在就跳过,但是我能说的是,如果你做一个如下的变量:
let s = "Towards Data Science";
那么 s 将是&str
类型。如果你想将"Towards Data Science"
存储为一个字符串类型,你可以
let s = "Towards Data Science".to_string();
或者相当于:
let s = String::from("Towards Data Science");
这两种类型的主要区别在于&str
是不可变的,存储在堆栈上,而字符串类型可以是可变的,因此存储在堆上。
如果你不知道栈和堆,不要担心。了解它们最重要的一点是,访问和写入堆栈要比堆快得多。
在整个运行期间,存储在堆栈上的数据需要具有固定的大小。这意味着如果一个变量被允许增加大小,那么它需要被存储在堆中。
这两种类型也是相关的,正如名称 string slice 所表明的那样,&str
是一个字符串类型的子串,不管这意味着什么(试着自己找出答案)。
由于这是一个简短的介绍,我们现在将离开这个主题和这个数据类型,但字符串的数据类型是一个丰富而令人兴奋的主题,我鼓励你在阅读完这篇文章后深入研究这个主题。
收集
在 Rust 中,我们有许多集合,但其中一些比另一些使用得更多。
排列
例如,Rust 中的数组就像 Go 中的数组。它的大小是固定的,因此可以存储在堆栈中,这意味着快速访问。
在数组中,一次只能存储一种数据类型。
语法类似于 Python 的 list:
let rust_array = [1, 2, 3];
您可以像在 Python 中一样访问特定的元素。rust_array[0]
给了我们第一个元素,在这个例子中是 1 。
元组
tuple 类型通常在 Rust 中用于在一个集合中存储不同的数据类型。
我们可以用点符号来访问元素:
矢量
Vectors 是 Rust 中最常用的集合之一,因为就像 Python 的列表或 Go 的切片一样,Rust 中的 vector 的大小可以增长。
它只能保存一种数据类型,但是正如您稍后将看到的,有一些方法可以解决这个问题。不过,我们必须知道一种叫做enum
的类型,才能开始写这方面的内容。
正如你所想象的,向量可以增长的事实使它成为一个非常重要的类型。
要创建一个新的空向量,我们可以调用Vec::new
函数:
let mut v: Vec<i32> = Vec::new();
一旦创建完成,我们现在就可以将元素放入其中。例如,v.push(1)
将在v
后追加 1,现在大小已经增大。
如果您想实例化包含元素的向量,我们有一个方便的宏:
let v = vec![1, 2, 3];
稍后我们会看到更多的宏。
从向量中获取元素有两种方法。在这种情况下,我们可以像在 Python 中那样用 v[i] 符号获取第 i 个元素。但是我们需要小心,向量实际上有足够的元素。
如果它有更少的元素,而我们试图访问一个不存在的元素,那么我们将在运行时得到一个错误!这很危险,所以 Rust 有另一种方法来访问 vector 中的元素。
我们像let second = v.get(1);
一样访问它
现在second
将属于Option<T>
类型,我还没有介绍过,但是很快你就会知道这意味着什么,以及如何获取值。
我们也可以在 for 循环中迭代向量,但是因为我还没有讨论循环,所以我会向你展示语法。
哈希映射
哈希映射就像 Python 中的字典或 Go 中的映射,类型用HashMap<K, V>
表示。它存储了类型为K
的键到类型为V.
的值的映射
要初始化和填充散列映射,我们可以执行以下操作:
insert
方法通过一组键和值作为参数将数据推入散列映射。
如果您想访问哈希表中的数据,我们也有get
方法。具体来说,
let a = articles.get(&String::from("Python Graph"));
将返回一个Option
类型,我们可以从中获取值。符号&
也将很快被涵盖。
当我们想通过一个键来更新哈希表,并且不确定它是否已经存在时,我们有几种选择。其中之一是方便的entry
方法:
articles.entry(String::from("Rust")).or_insert("https://www.cantorsparadise.com/the-most-loved-programming-language-in-the-world-5220475fcc22");
如果这个键已经在散列映射中,那么我们将得到一个对它的可变引用,如果没有,那么我们将把参数中指定的数据插入到or_insert
中。参考文献将在稍后解释。
功能
功能是 Rust 最重要的特征之一。
我们已经看到了起特殊作用的 main 函数,但是我们当然也能够创建其他函数。
语法很简单。下面是 Rust 中另一个函数的例子:
注意,我们需要告诉 Rust 函数接受哪种数据类型作为输入,以及它将输出哪种类型。这是一件好事,因为它可以防止许多错误。
关于 Rust 的另一个有趣的事情是,你不必通过一个return
关键字显式地告诉 Rust 你返回了什么。如果函数中的最后一条语句没有尾随分号,那么这就是函数返回的内容。
这通常也适用于花括号中的代码块。很像 Scala。
在上面的例子中。函数plus_one
返回x+1
,其中 x 是函数作为参数接受的整数。
在 Rust 中,我们有一个return
关键字,但它通常只在你想提前返回某个东西时使用。
控制流程和循环
控制流操作的语法通常最好通过自己做一些小练习来学习。
情况
看看下面的程序,并尝试修改它:
我们看到 Rust 中的注释是用双斜线或者多行注释的/* blah blah */
来完成的。还要注意我们如何能够用关键字return
提前返回一些东西。
if, else if, else
的语法类似于 Go 的。布尔表达式周围不需要括号,这对可读性很好。
环
在 Rust 中,我们有几种不同的循环。
如果你想要一个无限循环,我们有loop
,它当然应该在某个时候被打破。因此,Rust 还有一个方便的特性,使您能够打破特定的循环,而不仅仅是内部循环。
下面的例子是从《锈书》中借来的,我们都应该把它放在枕头下(或者在这个时代保存为书签)。
请注意,我们如何通过'label: loop
语法标记循环,并通过稍后基于某些条件调用该标记来中断特定的循环。
我们还有一个 while 循环,使用起来非常直观:
接下来当然是 for 循环,其语法如下:
我们能够在迭代器上循环,你是否必须让你的数据类型成为迭代器当然取决于类型本身。注意,这种语法很像 Python 中的语法,只是在 Python 中很少需要改变类型。
所有权和借款
Rust 真正区别于其他语言的一个特征是它处理内存的聪明的所有权系统。
你看,不同的编程语言以不同的方式处理内存。在一些语言中,你必须自己分配和释放内存,这使得你的代码很快,并给你低级别的控制。可以说你“离金属更近了”。这方面的一个例子是 C 。
在其他语言中,你有一个垃圾收集器,它可以确保你的安全并自动清理内存。这既方便又安全,但不是免费的。它会减慢程序的速度。这方面的例子包括 Python 、 Java 和 Go 以及许多其他的。
Rust 采取了一种完全不同的内存管理方法。Rust 在一个被称为所有权的系统中结合了安全性和速度。
正如铁锈书所说:
因为所有权对于许多程序员来说是一个新概念,所以确实需要一些时间来适应。好消息是,你对 Rust 和所有权系统的规则越有经验,你就越能自然地开发出安全高效的代码。坚持下去!
——锈书。
首先,让我们陈述所有权的规则:
- Rust 中的每个值都有一个变量,称为它的所有者。
- 一次只能有一个所有者。
- 当所有者超出范围时,该值将被丢弃。
有意思…是什么意思?
考虑以下代码:
这实际上将而不是编译。为了理解这一点,让我们从所有权的角度来看。
首先,变量s1
通过取得值String::from("Hi")
的所有权而进入范围。然后变量s2
获得该值的所有权,我们从所有权规则中知道,只能有一个所有者。
这意味着变量s1
不再有效。在《铁锈》中,我们谈到了“一个被移动的价值”。所以真正发生的是所有权或价值被转移到了s2
,因此在那之后我们无法访问s1
。
如果s1
和s2
是例如i32
,那么这就不会发生,因为它们的值会被复制。这与 Rust 如何存储不同的值有关。如果一个值存储在堆上,那么这些规则适用,但是如果它存储在栈上,因此实现了Copy
特征,那么将会发生一个简单的值拷贝。
让我们看另一个例子,在这里我们将看到函数也可以获得所有权。
下面的例子也是来自铁锈书。
你可以通过查看评论清楚地看到发生了什么。当一个变量作为参数传递给一个函数时,该变量的所有权被转移到该函数,并且该变量在当前范围内变得不可访问。
另外,请注意,如果存储在堆上的变量(例如字符串或向量)超出范围,那么只有在所有权在此之前没有移动的情况下,才会释放内存。
在这一点上,我确信这看起来有点限制和麻烦,你甚至不能在不转移所有权的情况下打印出变量,从而使变量不可访问。
当然,有一个系统可以解决这个问题。
这个系统叫做借力。任何其他语言都有指针。Rust 有引用,这些引用与借用规则配合得很好。
考虑以下代码:
这实际上编译和运行没有任何问题。前缀被称为引用,当一个函数被赋予一个引用或者一个变量被赋予一个引用时,它们并不拥有它的所有权。
在上面的例子中,我们需要在println!
宏中使用变量s1
,因此我们不能让函数calculate_lenght
获得所有权。这个函数只是借用了一个不可变的引用,这个引用的值被分配给了我们想要的s1
。
我们也可以有可变的引用,但是有一些规则来管理这个特性,以避免诸如竞争条件等讨厌的问题。
引用的规则如下:
- 在任何给定的时间,你可以拥有或者一个可变引用或者任意数量的不可变引用。
- 参考必须始终有效。
记住这一点的方法是,它就像任何其他文件。一次将读权限分配给几个不同的人是没问题的,因为在这种情况下不会发生任何不好的事情。但是,如果您同时授予几个人对一个文件的写访问权限,可能会出现很多问题。
这就是当你在 Git 中遇到合并冲突时发生的事情,对吗?我们不应该在代码中出现这个问题,因为 Rust 不知道如何处理这个问题。因此,在任何给定时间最多只能有一个可变引用。
结构、枚举和方法
结构和枚举在很多方面都是 Rust 的核心构件。如果你来自面向对象的语言,你会有宾至如归的感觉。
当我们引入哈希映射时,我们创建了一个articles
哈希映射来存储文章。然而,如果我们想保存更多关于它们的信息,比如出版商或长度(分钟)呢?
我们可以定制包含这种结构化信息的数据类型吗?嗯,是的。
看一看以下内容:
在文件的底部,我们创建了一个名为Article
的结构。我们现在能够在一个容器中存储相关数据。链接、料盒和长度数据称为字段,我们可以用点符号来访问它们,稍后我们会看到。
让我们看看如何使用impl
语法在结构上实现方法。
该程序的输出如下:
The article "The Most Loved Programming Language in the World" is about 4 minutes long and is published in Cantors's Paradise.Please go to https://www.cantorsparadise.com/the-most-loved-programming-language-in-the-world-5220475fcc22 to read it.The article "How to Give Your Python Code a Magic Touch" is about 6 minutes long and is published in Towards Data Science.Please go to https://towardsdatascience.com/how-to-give-your-python-code-a-magic-touch-c778eeb9ac57 to read it.
枚举很像结构,但是在枚举中,可以有给定数据类型的子类型,这非常有用。
请考虑对我们的代码进行以下更改:
这个程序的输出是:
The article "How to Give Your Python Code a Magic Touch" is about 6 minutes long and is published in Towards Data Science.Please go to https://towardsdatascience.com/how-to-give-your-python-code-a-magic-touch-c778eeb9ac57 to read it.Programming article coming up!The article "The Most Loved Programming Language in the World" is about 4 minutes long and is published in Cantors's Paradise.Please go to https://www.cantorsparadise.com/the-most-loved-programming-language-in-the-world-5220475fcc22 to read it.
这里介绍了几个新特性,同时也收集了一些旧特性。
首先,注意我们如何创建了一个包含两个变量的Story
枚举:Mathematics
和DataScience
。这很方便,因为回想一下在上面的 vector 小节中,我们说过 vector 只能保存一种类型。嗯,我们已经创建了一个保存类型Story
的向量,但是它有一些变体,这些变体不一定包含相同的类型。
DataScience
和Mathematics
都包含类型Article
,但是如果我们愿意,我们也可以选择String
和f64
。
然后我们还引入了match
控制流操作符,它在这种情况下接受一个 enum 并检查它的变量。如果找到匹配,我们就执行一些代码。
非常简单,但是非常强大。
回想一下,vectors 和 hash maps 上的 get-method 都返回了某种叫做Option
的类型。
Option
是一个有两个变体的枚举:Some
和None
。
Rust 迫使你以可控和安全的方式处理None
值,不像其他语言。
注意,我们可以有嵌套的匹配子句。此代码的输出将与之前相同,但也是一行:
We have less than three elements...
这样,我们可以安全地处理丢失的值。
错误处理
Rust 需要像其他编程语言一样处理错误。没有不出错的软件。
但是在 Rust 中,我们有 enums 供我们使用,这意味着安全的错误处理!
有时候我们真的需要让程序崩溃。这听起来可能很奇怪,但是如果一个错误是不可恢复的和危险的,那么最好关闭它。
这可以通过panic!
宏来完成。
panic!
宏通过在关闭前清除内存来结束。这需要一点时间,这个行为是可以修改的。
大多数时候,我们实际上能够优雅地处理错误。这是通过Result
枚举完成的。
我们还没有谈到泛型,所以这对你来说应该没什么意义。
只需将T
替换为任何数据类型,将E
替换为任何错误类型。
你现在不需要得到所有这些。但是我认为你已经抓住了要点。File::open
返回一个Result
枚举,它可能包含错误,也可能不包含错误。
可以用模式匹配来提取和处理。一旦你学会了闭包,你将有更多的选择。
试验
Rust 中的测试内置于语言本身的结构中。看看下面的片段:
您应该为您编写的每个文件添加一个测试模块。我们还没有讨论 Rust 中的模块,但是你已经明白了。
如果你运行cargo test
,所有的测试都会自动运行。
在 Rust 中测试的巨大优势是极其有用的编译器。事实上,Rust 开发软件的最佳实践是使用测试驱动开发(TDD)。
这是因为编译器为您的问题提供了很好的解决方案。以至于它几乎可以帮你写代码。
看看这个小教程,明白我的意思:
高级概念:一般类型、特征、生存期、闭包和并发性
关于 Rust 还有很多需要学习的地方,但是如果你一直这么做,你肯定是在正确的轨道上。
这个标题中的特性是你接下来应该关注的,但我会从这里重新引导你,因为这只是一篇介绍性的文章,而不是一本成熟的书。
如果您还不是 Medium 的成员,但想要无限制地访问像这样的故事,您只需点击下面的:
https://kaspermuller.medium.com/membership
进一步阅读的资源:
锈书:
铁锈举例:
文档:
让我们生锈吧:
https://www.youtube.com/channel/UCSp-OaMpsO8K0KkOqyBl7_w
TDS 贡献者注意事项
在假期期间,我们稍微放慢了脚步
对于 TDS 团队来说,2021 年是多事之秋,也是激动人心的一年。随着我们越来越接近终点线,我们将需要一些时间来充电和喘口气。虽然我们将在接下来的几周内继续发布新的帖子,但审查提交内容(来自现有和新作者)的周转时间可能会比通常轻松的速度更长。
无论如何,如果你想与我们分享你的新作品,尽管去做吧——只是要记住,我们可能需要更多的时间来审阅它(并回复你的疑问、问题和评论)。作为一种选择,我们也邀请你在 1 月 3 日之前坚持你的令人兴奋的新项目,那时我们将全力以赴,并渴望阅读你的草稿。
谢谢大家的理解!对于任何庆祝这个月的人,我们祝你节日快乐、安全、轻松。
我们迫不及待地想在 2022 年再次见到你,
TDS 团队
西蒙·因芬格在 Unsplash 上的照片
一种基于词包划分平均的文档嵌入新方法
实践教程
如何获取向量嵌入的集合并对其进行平均,从而保持其流形结构的多意义主题性。
比阿特丽斯·佩雷斯·莫亚在 Unsplash 上的照片
这是“嵌入、集群和平均”系列的第三篇文章。在深入本教程之前,我建议先阅读前面两篇文章:使用 PyTorch 和 ResNeXt-WSL 从图片中提取丰富的嵌入特征和使用 UMAP 和 GMM 在嵌入空间中进行流形聚类。
在本教程中,我们将使用 ResNext-WSL 模型、UMAP 变换提供的稀疏主题表示、GMM 聚类模型从 COCO 图片中提取嵌入,并为图片集(单词包文档)生成嵌入表示。我们将展示为什么传统的平均技术对于由几个多主题对象组成的文档不太适用,并且我们将扩展分区平滑逆频率(P-SIF) 方法以适用于单词和文本之外的通用领域。
单词袋模型
单词袋模型将文档表示为对象(单词)的加权集合。每个文档都表示为一个词频矩阵,其中行是文档,列是可能值集(词汇表)中的单词,值是该单词在文档中出现的次数。
对于本教程,我们将假设文字就是图片,文档可以是它们的任意集合。为了方便起见,我们将使用 COCO 类别来定义文档,并使用词频来对应图片中该类别的注释数量。
COCO 范畴词袋模型的词频矩阵
如果我们对每行中的术语频率求和,我们会得到以下分布:
每个文档的词频总和
文件尺寸的分布
我们可以观察到,person 和 chair 是数据集中非常受欢迎的注释,但平均来说,每个文档(类别)由一百个单词(图片)组成,我们知道每个单词可能代表多个上下文。
单词加权平均
表示每个文档的简单方法是获取每张图片的嵌入向量,并基于词频进行加权平均。通过这样做,我们将在图片的相同嵌入空间中表示文档,这是一个方便的属性。然而,正如我们将在底部的比较部分看到的,对许多多主题单词进行平均,最终会得到所有文档的几乎相同的向量。很难保留单词中的原始信息,因为它们会相互补偿,从而导致扁平的信息量较少的向量。
术语频率-逆文档频率(tf-idf)平均
tf-idf 是一个统计量,它测量一个单词在它们的集合(语料库)中对一个文档有多重要。一个单词在文档中出现得越频繁,重要性就越低。很可能,罕见的单词将具有更高的权重。
这种技术对于文本数据非常有效,可以过滤掉常见的单词,如 the、a、an、is、at、on,并赋予关键字以重要性。当单词字典(所有可能图片的集合)不遵循语言分布时,这种技术不会给出很大的改进。
我们这种平均的主要问题不在于每个单词的权重,而在于代数运算(和/均值),它去除了向量的所有信息成分。
由 COCO 超级类别着色的 TF-IDF 文档矩阵的 PCA 3D 投影
我们可以看到,属于同一个超级类别的文档倾向于彼此靠近地聚集在一起,但是这种分离不是很明显。
分区 SIF 加权平均
我们介绍的新方法受到了 P-SIF 平均方法的启发。
关键的直觉是:
- 使用稀疏编码对“主题”中的所有“单词”进行聚类(论文作者称之为字典学习,但对我们来说,它们是流形聚类)。
- 针对每个题目,用平滑逆频做图片的加权平均。
- 连接每个主题中的平均向量。
- 去掉第一个主成分。
P-SIF 文档平均算法概述。图片作者。
让我们一步一步来。
主题聚类
原始论文通过字典学习算法使用稀疏编码,例如 K-SVD ,k-means 的一种推广,用于稀疏编码。类似于 PCA,K-SVD 将通过奇异值分解(SVD)学习单词的稀疏表示,并将每个单词表示为原子的线性组合。每个原子就像一个星团的质心。因此,该算法通过交替学习数据的稀疏编码和更新原子以更好地适应数据来工作。这就像在单个算法中优化 SVD 和 k-means。
在上一篇文章中,使用 UMAP 和 GMM 的嵌入空间中的流形聚类,我们已经讨论了那些线性投影和 k-means 在数据以流形结构排列的情况下的局限性。此外,截至今天,除了论文作者在相关 GitHub 库中提供的内容之外,我们找不到任何 K-SVD 算法的成熟实现。因此,我们用 UMAP 和 GMM 的组合代替了 K-SVD。
SIF 平均值
为了执行平滑逆频率(SIF ),我们首先需要计算每个单词出现在文档 p 中的概率。
p(单词)的分布,单词在文档中出现的概率
然后,我们可以计算作为平滑参数α的函数的 SIF 权重(我们已经使用了 0.001 的值)。
为了执行 SIF 文档平均,我们必须将文档中的每个单词乘以 SIF 权重和单词主题概率。现在,我们可以用组合权重对每个主题中的单词进行平均。
连接主题向量
在上一步中,我们为每个文档和主题生成了一个向量。串联只是将所有这些主题向量堆叠在一起。我们可以把连接向量看作是保存单词包中大部分原始信息的一种方式。只有属于特定主题的单词将对嵌入主题子空间中的平均或文档坐标有贡献。
在我们的教程中,我们嵌入了维数为 2048 和 40 的聚类向量。因此,每个文档现在都以 2048*40 = 81920 的尺寸表示。很高,是吧?
我们可以通过在平均之前减少单词的嵌入空间或者通过减少主题的数量来减少这个维度。这两个方面在之前的聚类步骤中已经被次优化了。我们可以,但不是强制性地,用缩减的 UMAP 空间(50 维)替换原始的单词嵌入空间。因此,我们可以获得大小为 50*40 = 2000 维的文档向量。
一般来说,我们可以应用任何降维变换,而不一定是聚类过程中使用的那个。重用用于聚类的相同 UMAP 空间的便利选择不应该限制许多可用的选项。聚类步骤的目的是发现主题并将单词分配给主题概率。
去掉第一个主成分
为了使 SIF 平均技术有效,并与其背后的理论数学相一致,我们需要去除公共话语向量。这个想法是,所有的单词都是根据一个取决于微话题(本地话语)的过程生成的。然而,所有的文档都将共享这个话语的一个组成部分,这个组成部分可以使用 SVD 删除。作为代理,我们因此可以使用 PCA 计算第一主分量,然后从平均和连接之后获得的文档嵌入矩阵中减去它。
重构误差去除文档向量的主分量,点表示第一分量
我们还可以观察到,通过保留剩余的 50 个组件,我们可以在不损失信息的情况下进一步降低文档向量的维数。
左边的图是原始空间中连接的文档向量的重构曲线,而右边的图是 UMAP 空间中的重构曲线。点代表第一个主成分。
我们还可以观察到,通过保留剩余的 50 个组件,我们可能已经进一步降低了文档向量的维数,而没有显著的信息损失。
结果比较
为了测试我们的结果,我们将计算每对文档之间的余弦相似度(在我们的例子中是 COCO 图片类别)。我们应该期望相似的文档,属于相同 COCO 超级类别的文档,与剩余的文档相比具有更高的相似性。
我们比较了 6 种配置:
- 一袋单词
- UMAP 空间中的词汇袋
- TF-IDF
- UMAP 空间中的 TF-IDF
- p-SIF
- UMAP 空间中的 p-SIF
我们可以绘制每个配置的相似性矩阵的热图:
相似性矩阵(单词袋)
相似性矩阵(UMAP 空间中的单词包)
相似性矩阵
相似性矩阵(UMAP 空间中的 TF-IDF)
相似矩阵
相似矩阵(UMAP 空间中的 P-SIF)
我们可以观察到,具有传统单词包和 TF-IDF 平均的 UMAP 变换导致完全误导的结果,其中所有文档以相似的表示(和相似的余弦距离)结束,并且可能在 UMAP 空间的区域中没有任何实际意义。TF-IDF 变换没有产生任何相关的差别。我们已经预料到这种技术对于非语言发行版来说效果不佳。我们最终可以看到,无论是在原始嵌入空间还是在 UMAP 空间,我们修正的 p-SIF 确实提供了更稀疏和更一致的结果。
为了更好地形象化它们的表现,让我们计算属于和不属于同一个超级类别的文档对之间的平均余弦相似度的比率。较高的比率对应于较好的表示。
每个超范畴中所有配对的余弦相似性之内和之外的平均比率。
我们可以观察到,p-SIF 在所有超级类别中都占主导地位,其中一些类别(如动物、电器、电子产品)的性能提升了 7 倍以上。通过对所有超级范畴的结果进行微平均,我们可以总结为一个单一的指标:平均余弦相似性内/外的总比率。
所有超级范畴中所有配对的余弦相似性之内和之外的平均比率。
我们的 p-SIF 被证实是在多上下文情况下用于文档嵌入平均的更好的技术。原始空间中的 p-SIF 和 UMAP 空间中的 p-SIF 之间的差异是极小的,但是允许我们将向量的大小减少大约 40 倍。
结论
在这篇文章中,我们提出了一个重新适应版本的分块平滑逆频率(p-SIF) 算法。我们已经用 UMAP + GMM 的组合代替了 K-SVD 字典学习步骤。我们认为后者是一种更适合嵌入向量的词袋模型的技术,这些向量由深度神经网络生成,并排列在高维空间的流形中。我们已经证明了保留平均到 COCO 超级分类文档中的原始图片的多个主题和上下文的有效性。这种新提出的技术可以用于测量文档之间的相似性,但是也可以用于在新的特征空间中生成平均嵌入向量,该新的特征空间被定制用于表示一般文档可能表示的多义主题。
阅读“嵌入、聚类和平均”系列的前两篇文章:
使用 PyTorch 和 ResNeXt-WSL 从 COCO 图片中提取丰富的嵌入特征。
你可以在 https://github.com/gm-spacagna/docem 找到代码和笔记本。
原载于 2021 年 1 月 9 日【https://datasciencevademecum.com】。
一种将语音识别集成到认证系统中的新方法
人工智能应用
这个系列的最后一部分
马特·博茨福德从 Unsplash 拍摄的照片
在本系列的前两部分中,我们回顾了现有的认证系统和基于 EEG 的认证系统的局限性的部分。这一部分将深入研究基于语音的系统、相关工作及其局限性,并提出一个将自动语音识别用于身份验证系统的想法。
术语语音识别、语音识别和基于语音的身份验证系统将在本文中互换使用。
1.1 优势
与包括虹膜扫描、面部识别和指纹扫描在内的其他类型的身份认证相比,语音识别具有许多重要优势。首先,它通常用于手机认证,因为所有手机都配有麦克风。第二,集成到家用电器和汽车等其他设备中具有成本效益[19];第三,由于物联网设备的快速扩展,它对大多数消费者来说是方便和熟悉的。最后,它已经被证明在某些情况下非常准确[20]。
1.2 组件
语音认证系统中通常使用客户端应用程序和服务器。为了认证用户,客户端应用程序将捕获他们的声音并向服务器发出 API 请求。服务器分析音频并选择是否验证用户[21]。当用户加入一个系统时,除了他们的人口统计信息之外,他们必须提供他们的音频记录。背景噪声总是首先被消除,以确保训练过程不偏斜,因此总是首先进行语音活动检测(VAD)。Zhou 等人[22]利用 LTSD 方法将每个话语划分为重叠的帧,并根据该帧中语音活动的可能性为每个帧分配分数。将收集该概率,以便提取包含声音活动的所有区间。图 2 描绘了由通过记录形成的包络。然后,他们采用离散傅立叶变换提取梅尔频率倒谱系数(MFCC)作为特征,然后在高斯混合模型(GMM)中使用,以计算它们属于该模型的可能性。
通常,在说话人识别中为每个说话人训练一个 GMM。然后,对于每个输入信号,收集特征向量的列表,并且计算属于每个模型的向量的总概率。最后,其模型与输入最匹配的说话者将被选为答案[22]。”
图 2:图中的尖峰对应于用户说了一个单词[ 21 ]的峰值
1.3 限制
基于语音的身份验证系统中最典型的方法有以下两种。第一种是让一个人重复同一句话几次,然后建立一个由声纹范围组成的通用模板。缺点是声纹太广,准确率会不如单个密码或口令。第二种方法是用单个句子制作声纹,并将其用作声纹。甚至,在这种情况下,攻击者可以简单地捕获并窃取身份验证尝试,然后重放它以获得访问权。鉴于这些缺点,Shoup 等人[21]认为,虽然语音认证不能作为独立的认证模式,但作为双因素认证协议的一部分,它将是一种可接受的替代方案。另一个缺点是声纹对一个人来说是唯一的,并且不容易被修改;因此,保护声纹和声音模型至关重要。
因为基于语音的身份验证方法过于笼统,容易被窃取,并且难以更改。设置身份验证以区分用户并允许用户选择他们的密码标准是解决问题的一种方法。
让我们从建议的系统原型开始吧!
2.1 原型
拟议系统将包括两个阶段:
注册方法最初采用说话人识别 API 来捕获用户的声纹并产生相关特征,以便 API 可以在认证阶段识别和验证用户。然后,在系统的后端,用户需要为他们的语音密码(VoicePass)配置规则,并开发一个语音识别 API 来将用户的规则(音频)转换为文本。例如,规则可以包括语言、口令/密码短语中的字符数以及特定短语。所有规则设置输入都将在后端以某种方式被散列。密码将是灵活的,规则将是简单易记的,但 VoicePass 必须遵守只有用户知道的某些限制。为了使其更强大,更能抵御在线攻击,密码不能与上次相同。下图描述了该系统的原型。登录后,用户将被转到网站,表明她已被成功确认,或者她将被要求重新记录她的 VoicePass,因为她的话语不符合要求,或者系统没有将用户识别为设置 VoicePass 的人。用户尝试登录的次数将受到限制。
左图:建议的身份验证系统的注册流程,包括语音注册和设置 VoicePass 规则。右图:登录过程。(图片由作者提供)
2.2 示例
例如,考虑一个英语语音通行证,其中包含单词“Shanghai”和“Singapore ”,长度为 15 到 20 个字符;在这种情况下,即使系统根据第一步提取的特征验证了用户,他们仍然必须通过第二步;因此,在认证过程中,如果用户说“上海是一个拥有数百万人口的充满活力的城市,新加坡也是同样充满活力但人口较少”,她将被验证;相比之下,在核查过程中,任何不符合标准的声明都将被拒绝。例如,“尽管上海正下着倾盆大雨,但加拿大今天天气很好”将不会被验证。攻击者可能会捕获用户的话语并绕过第一阶段。如果不知道系统的密码规则,即使它们包括用户的最后一个密码,也不可能访问。此外,如果用户以普通话或西班牙语配置 VoicePass,不熟悉这些语言的攻击者将会发现更难危害系统。
2.3 优势
该系统的优点包括以下几点:1 .与复杂的密码短语相比,规则易于记忆,用户可以跨多个平台修改规则的一个元素(例如,在前面的示例中,将“新加坡”更改为“加拿大”),同时保持 VoicePass 的可记忆性。2.只要对手没有违反规则,它就能抵抗肩窥、暴力攻击、欺骗和字典攻击。3.它继承了本系列第 3 部分中讨论的基于语音的身份验证系统的优点。
2.4 制约因素
该系统受到以下限制:1 .说话人识别和语音识别 API 的准确性至关重要,因为系统非常依赖它们的性能。2.注册和验证可能需要一些时间,系统可能的延迟应该不会让用户不堪重负。不过,这可以通过改进部署过程来解决。3.尽管改变先前的语音传递选项会增加系统的安全性。然而,(自动语音识别系统)ASR 系统有许多缺点,因为它们容易受到在线和离线攻击[23]。
2.5 结论
万岁!迄今为止,我们已经取得了很大成就:)
我们研究了当前的身份验证方法,并深入比较了基于 EEG 和基于语音的系统,包括架构、采用的方法、安全性、可记忆性和可用性,以及方案的局限性。尽管这两种方法都有好处,但不能忽视其局限性;因此,额外的考虑是为了避免一些障碍,并可作为未来研究课题的建议。
感谢你花时间阅读我的博客。请留意更新,并随时在 Linkedin 上发表评论或联系我。
https://www.linkedin.com/in/fangyiyu/
第 2 部分后的参考资料:
[19] R. G. Zick 和 J. Olsen,“语音识别软件与 ED 中医生制图的传统转录服务”,《美国急诊医学杂志》,第 19 卷,第 4 期,第 295-298 页,2001 年。
[20] D. J. White、A. P. King 和 S. D. Duncan,“作为行为研究工具的语音识别技术,“行为研究方法、仪器、&计算机,第 34 卷,第 1 期,第 1–5 页,2002 年。
[21] A. Shoup,T. Talkar,J. Chen,A. Jain,语音认证方法综述与分析,2016。
[22] X. Zhou,Y. Wu,和 T. Li,“X. Zhou,Y. Wu,和 T. Li”,数字信号处理:说话人识别最终报告(完整版),【2012。
[23] H. Abdullah,K. Warren,V. Bindschaedler,N. Papernot 和 P. Traynor, Sok:我们的语音识别系统中的错误:对自动语音识别和说话人识别系统的攻击概述,2021 年 IEEE 安全和隐私研讨会(SP)。IEEE,2021 年,第 730–747 页。