数据科学家二项分布教程
使用简单的 python 代码提高您的统计技能!
没有这些骰子,统计也很有趣!来源
在学习数据科学时,我们经常听到正确研究统计数据的重要性,特别是对概率的关注,在运行机器学习模型和验证测试时,没有办法否认这种知识的重要性。然而,如果你是统计学新手,或者你在高中时历史比数学好,你可能很难理解它。
在本教程中,我将通过一个示例来指导您如何在 python 中运行二项分布模拟,并在最后绘制经验累积分布函数图。我在这里不涉及这个主题的基础概念,所以如果你不熟悉二项分布,你可以先看看这篇优秀的文章。也就是说,让我们开始吧!
哦,但在此之前,欢迎你点击这里下载我正在使用的所有代码的笔记本。
首先:定义一个问题
统计的例子可以很抽象,毕竟什么是“成功案例”,还有为什么那些人痴迷于抛硬币和掷骰子?我认为学习东西的最好方法是在你容易理解的问题/情境中。
比方说,我们正在做一个选举池。我们将随机询问 10 个人,他们是否会在 2020 年投票选举特朗普为总统。我们将与另一组 10 个人反复重复这条线索,直到我们得到 10 万组的答案。我们的目标是发现每组中有 6 人或更多人回答“是”的概率。
但是等等,与其拿着你的纸和笔跑到外面去骚扰街上的人,不如让我们用 python 的能力来模拟一下。
我们首先检查我们是否拥有二项分布情形的所有元素:
- 是或否问题(因此是“二项式”部分):问题是他们是否会投票给特朗普,所以我们很好。
- 独立结果:一个人的答案不影响下一个答案。
- **氮、磷和大小。**我们有了试验次数(n),10 个人,每个人回答是§的概率,我们用 50%,我们实验的规模,10 万组。
太好了,那我们先做什么?模拟答案!我们可以使用NP . random . random()函数来实现。它会生成一个介于 0 和 1 之间的随机数,所以我们会将所有低于 0.5 的数字视为否,等于或高于 0.5 的数字会被视为是。让我们想象一下如何为 10 人小组得出答案:
> [0.9600173 0.69951205 0.99986729 0.2200673 0.36105635 0.73984099 0.99645573 0.31634698 0.13654458 0.38398001] > [ True True True False False True True False False False] > Total number of positive answers for this group: 5
所以从我们的第一组 10 个人中,有 5 个人回答说他们会投票给特朗普。现在我们只需要将同样的逻辑重现十万次!为此,我们需要做一个循环并使用函数 np.random.binomial() ,它需要参数: n(试验次数,或者在我们的例子中,每组的人数), *p(肯定答案的概率)*和 size(我们想要运行它多少次):
> There's a probability of 37.69% of Trump getting 6 or more supporters in a group.
那是什么意思?
理解如何解释这一结果很重要,因为这不是关于特朗普是否会当选,而是显示了在随机选择 10 人的情况下,6 人或更多人对“你会投票支持特朗普竞选总统吗?”这一问题的回答是肯定的可能性有多大。。
鉴于美国复杂的选举系统,这种模拟可以用于不同的选区,初始概率各不相同。我们假设有 50%的机会回答是或不是,但如果你在佛罗里达或加利福尼亚,这种情况就会改变,对吗?通过改变得到肯定答案的概率(p ),看看结果变化有多大:
- 对于 p=0.4 : 16.76% 获得 6 个以上支持者的几率;
- 对于 p=0.6 : 63.27% 获得 6 个以上支持者的几率。
经验累积分布函数(ECDF)
可视化二项分布最酷的方法之一是绘制 ECDF 来检查肯定答案的分布。这可以通过一个简单的 plt.scatter() 来完成,在 y 轴上输入分布的密度,范围从 0 到 1 (100%的样本),在 x 轴上输入我们在每组中得到的肯定答案的数量:
n= 0.4、0.5 和 0.6 时的 ECDF 曲线。注意曲线是如何变化的。
如何解读 ECDF 的情节?
将 x 轴上的值 6 作为参考。在左边的第一个图中,p=0.4,数字 6 略高于 0.8,这意味着超过 80%的分布低于该值,不到 20%的分布高于该值。这与我们的计算 p=0.4 或 16.76%完全匹配,对于其他两个图也是如此。
花几分钟时间比较这些图和值。一旦你有了这个想法,你会注意到理解 ECDF 情节是多么的强大和简单。
结论
在这个实践教程中,我想把你带出我们在学习二项式分布时遇到的所有同类例子,并向你展示如何使用不同的 p 值进行第一次模拟,以及如何用 ECDF 图可视化结果。我希望这篇文章能帮助你提高你的统计技能,也欢迎在评论中分享你的想法。
生物信息学:人工智能如何为生命研究做出贡献
来自 Pixabay 的背景和封面图片
它是什么,最近的发展和未来
生物学是对生命的研究——可能是科学最迷人的方面之一。更重要的是,它的很大一部分在小的水平上研究生命——DNA 链,有机化学,所有的一切。在大千世界里,研究小物品意味着海量数据;因此,哪里是数据科学大放异彩的更好领域?
生物信息学结合了生物学和数据科学,赋予了机器学习和人工智能方法一个真实而重要的目的。
生物信息学的主要目标是利用机器学习和数据科学的力量来探索太复杂而无法用手探索的生物系统和过程。它将数据科学方法与生物学任务联系起来。例如,一个显著的例子是药物发现和设计——世界上最强大的超级计算机 IBM Summit 花了 1 到 2 天时间搜索可以对抗冠状病毒的化合物的分子结构。它使用生物信息学代码进行模拟。
通常,复杂的生物学现象涉及许多生物学方面,因此不能用一种数据类型来解释。出于这个原因,生物信息学涉及对几种不同数据类型的相互联系的分析,应该对复杂的生物现象有一个整体的理解。
机器学习已经在生物信息学中用于预测和发现——随着高可用性和各种组学(分子水平)数据的兴起,机器学习——尤其是深度学习——变得更加频繁。
由于数据量巨大,生物信息学是数据科学的一个丰富分支。一个人类基因组中大约有多少个核苷酸(“片段”)?
答案是:D,仅在一个人类基因组中就有 350 万个核苷酸。拥有所有这些数据,再结合像序列比对这样的生物信息学方法,可以为美国医院和诊所提供一种更经济实用的诊断工具。
序列比对是指将不同的序列进行比对,以便比较相似性和差异性。这是生物信息学中的一个常见任务。来源。
机器学习的一个机会领域是基因组特征的预测,它描述了任何具有某种注释功能的基因组区域,如基因。
机器学习也可以用来预测 DNA 和 RNA 链的序列。像聚类这样的无监督方法可以用来寻找类似的 DNA 突变,像主成分分析这样的降维技术可以帮助降低高维数据的维度。
生物信息学在解决群体和进化遗传学问题方面也有巨大的潜力。进化,尤其是在人类或其他拥有大量种群的生物中,可能是一个极其困难和复杂的系统来建模。因为生物信息学能够利用机器学习的预测能力,生物学家可以窥视未来,看看最有可能的群体结果是什么,或者某个群体的 DNA 进化成特定版本的概率是多少。
生物信息学中的一个挑战是高级人工智能算法缺乏可解释性(“黑盒性质”)。虽然已经开发了几种方法来解释这些模型,例如,用于解释卷积神经网络的基于梯度的方法,但是对生物信息学中常见的复杂情况的解释是具有挑战性的,并且通常是遥不可及的。因为生物学家通常不仅关注模型的结果,还关注模型如何得出结论,强大的神经网络可能需要被更容易解释的模型所取代,如朴素贝叶斯或逻辑回归。
生物数据和高分辨率/高维度(维数灾难——稀疏性、多重共线性、过拟合)数据的噪声特性带来了额外的挑战。
数据错误,如基因位置不正确、污染序列、序列变异或差异、拼写错误和注释错误困扰着数据库。
尽管改进的机器学习方法和越来越多的数据显示出增加人类对生物现象的理解的巨大潜力,但由于缺乏对隐藏的生物因素(如样本中的群体结构或基因之间的进化关系)的了解,适当的机器学习模型仍然受到阻碍。如果没有适当考虑这些因素,模型可能会过度拟合,导致假阳性发现。
就像机器学习中的免费午餐定理一样,生物信息学中的任何问题都没有确定的方法。不同的机器学习方法将对应于对数据的不同基础假设。
生物信息学在新冠肺炎备受关注。生物信息学家进行的第一次生物信息学突破是在新冠状病毒的生物序列上。
几所中国大学和研究机构已经对新冠肺炎的基因组和晶体结构进行了测序和阐释,这是开发药物、诊断工具和疫苗的起点。
生物信息学家还开发了使用逆转录聚合酶链反应(RT-PCR)的诊断工具。这是使用生物信息学序列比对方法创建的。
通过使用化合物库和药物库,像橡树岭国家实验室的生物信息学家正在使用基于机器学习的计算方法来改变和试验候选药物。
这是通过利用现有的生物信息学化学工具修改现有冠状病毒药物的化学结构,然后进行大规模分子模拟来实现的。
生物信息学的前景非常光明。随着人工智能热潮推动生物信息学的发展,DNA 分析、人造器官和不可想象的新药、药物和疫苗正在迅速发展。
生物信息学是有效的,因为它使用计算机的能力和机器学习的效率来模拟和观察人类需要太长时间才能到达或从未想过要去的地方,并作为人类的导轨。
生物学家和数据科学家:文化鸿沟
亚历山大·提图斯的见解
来源:作者
生物学和数据科学领域有很多共同点。数据科学家和生物学家都分析数据集,试图理解这个世界。如今,数据科学对生物学越来越重要,因为生物学家越来越多地将机器学习和人工智能用于药物发现、医疗诊断和自动化重复任务。
尽管如此,这两个领域之间仍然存在巨大的文化差异。数据科学家和生物学家经常从非常不同的角度,使用不同的方法和不同的术语来处理同一个问题。
我们采访了高级再生制造研究所(ARMI)首席战略官兼《生物经济》主编 Alexander Titus。XYZ 。亚历山大最初是一名生物学家,后来获得了数据科学博士学位,现在正致力于弥合这两个领域之间的差距。
亚历山大的背景
亚历山大最初在大学学习生物化学和生物学,但在最后一个学期开始接触计算机科学。正如他所说的,
“我爱上了计算机科学,并意识到我一直在研究错误的东西。”
“我搬到了硅谷,想在科技领域的初创公司找份工作。但是我没有任何软件技能,所以我在做与编程无关的事情。然后,在真正的硅谷风格中,我把所有的时间都花在了地下室的黑客工作上:学习如何编码。学习统计学。最终学习机器学习。我考得足够好,可以去拿博士学位了。”
现在,作为一名战略执行官,亚历山大充当了数据科学家和生物学家之间的桥梁。他帮助 ARMI 做出正确的宏观决策,让再生制造成为现实。
【在 LinkedIn 、 Twitter 、他的播客 Titus Talks 、他的出版物 Bioeconomy.xyz 或alexandertitus.com了解更多关于 Alexander 的信息。]
生物学家应该学数据科学,还是数据科学家应该学生物学?
亚历山大已经看到人们在两个方向上拓宽了他们的技能,但他认为生物学家获得数据科学技能比反之更容易。他说:
“与我交谈过的创始人发现,让生物学家来教他们数学和编程,比让那些在数学和科学领域(而不是生物学领域)有着悠久历史的人来试图让他们了解他们错过的多年事实和信息要容易得多。”
但这两个方向都具有挑战性,Alexander 表示,数据科学基础的坚实基础对任何想要跟上不断变化的人都是有用的:
“编程变化真快。Python 很庞大,后来集成了 R。然后是所有的统计数据,然后是 TensorFlow,然后是 Keras。它只是不断变化。任何一套技能都会在几个月内过时。但学习这些技能的潜在能力是巨大的。”
事实上,亚历山大认为“学会学习”是大学教给人们的最重要的事情:
“我在大学里有一个教授,他总是告诉我,‘大学教你的唯一一件事就是如何在一个漫长的周末里学习任何东西。’这才是我真正需要的人们的心态。它是什么并不重要,因为有人将发明一些新的反向传播算法,或者一些我们将不得不使用的新框架。我们总是要去适应。”
“可解释性的文化差异”
数据科学家和生物学家从不同的角度看待同一个问题。来源:作者
每周了解更多关于在生物技术中应用数据科学的信息— 注册我们的每周简讯
生物学家和数据科学家处理问题的最大区别在于他们处理数据和假设检验的方式。
假设检验与机器学习
传统上,科学家会查看一个结果(患者 A 患了癌症,但患者 B 没有),做出一个假设(也许我们可以用这个特定的生物标记来诊断这个癌症),然后使用数据来测试这个假设(在两组患者中寻找那个生物标记:患癌症的患者和没有患癌症的患者)。
虽然使用机器学习的数据科学家也受到这种方法的指导,但侧重点不同。他们看着结果,做出一个更宽松或更宽泛的假设,比如:“也许这个结果可以用我在这个数据集中的一些变量来解释。”他们将数据输入机器学习算法,该算法可能会查看数十亿种可能的解释,然后自动锁定那些最能解释结果的模式。
这种使用更广泛的假设的过程对于许多生物学家来说是陌生的,并且常常让他们感到不舒服。正如亚历山大所说:
“在传统的生物学和化学中,你有一个非常具体的假设,你设计了一套非常具体的实验来测试它。一旦你到了那里,你就有了答案。这只是几个简单的数据点,表明你证明了这一点。
但是在数据科学中,你通常没有假设。你有一个宽松的假设,但你正在进行数据驱动的分析,以获得答案。”
生物学的狂热者:好的科学还是老式的方法?
这不仅仅是习惯的不同。这是人们非常强烈的观点——近乎狂热的信仰。亚历山大用宗教术语说:
“对于生物学家来说,没有假设是亵渎神明的。这与作为生物学家的训练和精神气质是如此的背道而驰。这几乎就像让人们质疑他们的科学宗教。生物学家会说,‘好吧,你是个没有假设的白痴。“你为什么没有一个假设,””
但是随着新的工具和技术允许我们更有效地探索数据,机器学习正变得越来越被接受。亚历山大说:
“有很多证据表明基于机器学习的分析有多好,有多有用。”
机器学习可以在数据中找到更复杂的关系
没有算法的帮助,科学家们只能进行有限的数据分析。传统上,生物学家在任何给定的实验中只考虑很少的变量,在数据中寻找简单的关系,他们只进行少数实验。
因此,难怪他们有时会发现很难理解机器学习为他们的领域提供的潜力。亚历山大赞同这种观点:
大多数来自生物和化学领域的科学家做少量的实验。他们使用一些简单的图表进行基本的 Excel 分析,以了解正在发生的事情。他们通常认为机器学习只是将更多的数据点打包到条形图的相同条中的一种情况;他们不太理解 维度 和 复杂性 带来了更多的数据和更多的变量。”
人类往往很难理解高维。Geoffrey Hinton 简洁地解释道:“要处理 14 维空间中的超平面,想象一个 3 维空间,大声对自己说‘14’。大家都这么干。”
但是机器并不局限于此。随着计算能力的提高和更先进的算法,机器学习不仅加快了传统分析的速度,还可以进行仅使用手动方法永远不可能进行的分析。机器经常可以找到几十个变量之间的相关性,而人类科学家通常一次只能看到一两个。
技术让我们能够收集更多的数据并进行更广泛的分析
从历史上看,严格的假设检验是有意义的。收集数据是昂贵的,所以生物学家接受培训,以确保他们只收集他们需要的东西,并专注于一个非常具体的问题。亚历山大承认这种狭隘观点背后的原因:
“以前,生物学家必须开发一个框架才能让实验成功。没有电脑。没有高维数据。没有深度学习。你只有足够的时间和金钱来收集非常具体的东西来证明你的假设。
但是现在收集数据太便宜了。第一个全基因组序列花费了 100 亿美元,而同样的东西现在只需要 800 美元。”
生成数据突然变得如此便宜和容易,这一事实产生了两种相互冲突的思想流派:一些科学家仍然更加保守,而另一些科学家则渴望充分利用更新的技术。正如亚历山大解释的那样:
“基本上,两种心态是:‘当你不知道你是否需要时,为什么要收集所有你能收集的数据?’与“为什么不呢?因为有一天你会需要它。”
新毕业生正在引领这种观点的转变
亚历山大认为,如果我们要弥合生物学和数据科学之间的文化鸿沟,我们仍然需要大的变革,但他乐观地认为,这种转变已经在进行中。当新毕业生进入实验室时,他们带来了关于如何更有效地做事的强烈意见。正如亚历山大所说:
“研究生们会问,‘为什么我们还在手工做这个?“为什么我们没有机器人来自动完成这项工作,也没有数据科学来分析它,””
并且有可能训练人们看到对方的观点。亚历山大亲身经历了这种转变:
“这一切都与取景有关。以我作为生物学家的经验来看,一旦你在数据科学方面接受过培训并有了经验,你就可以从两个角度来看待它。”
我们需要发展假设检验,而不是抛弃它
亚历山大提醒我们,机器学习并不完全取代假设检验。相反,科学实践需要发展和适应,这样我们才能释放久经考验的科学方法与机器学习潜力相结合的优势。
Alexander 认为这种混合方法遵循一个“轻”假设:被你的假设引导但不被限制。正如他所说:
“微生物测序就是一个很好的例子。我不是对我在停车场找到的每一种微生物进行测序,而是在我感兴趣的领域寻找微生物。如果我想寻找擅长处理黄金的微生物,那么我会去金矿而不是农民的地里收集微生物。这是一个假设。你还是不乱做事。但是你平衡一下,这是有用的。”
这不全是关于人才:专有格式和合法性的挑战
尽管找到理解数据科学的生物学家仍然是一个挑战,反之亦然,但亚历山大表示,该领域受到其他因素的影响更大:
“数据科学很少受到技术人才的阻碍。”
专有数据格式是数据科学家生存的祸根
数据文件可以用不同的方式格式化。许多文件类型(如 PDF 文件)都有开放的标准:任何人都可以实现软件来处理 PDF 文件,并访问其内部流程的细节。
相比之下,生物技术数据通常使用专有或封闭的数据格式,这使得理解和使用这些数据更具挑战性。亚历山大指出:
“我们正在努力避免使用任何以专有格式存储数据的东西。这是我的数据科学存在的祸根:当有一些文件类型我不能用任何旧电脑打开时。它让我发疯。规范化、标准化和获取原始数据非常困难。”
专有软件混淆了内部处理
不仅仅是访问数据;这也是为了准确理解数据已经经过了哪些预处理步骤。亚历山大描述了有时发现这一点所必需的侦探工作:
“这尤其具有挑战性,因为我们经常无法访问。软件都是专有的,我们不知道数据是如何在内部处理的——从原始数据到输出。我们不仅需要标准化一堆不同机器的输出,而且我们还必须弄清楚在数据到达那个阶段之前它们对数据做了什么。那很辛苦。”
软件供应商使用模糊的法律来获得数据的所有权
为了帮助驾驭这种专有软件和数据格式的局面,许多团队向专业软件供应商寻求帮助。亚历山大也尝试过这个,但是他没有好的经历。他描述了无意中签署合同会如何导致失去数据本身的所有权:
“我们采访并评估了许多软件供应商。我们询问他们将如何为此提供解决方案,以确保我们可以访问数据,并确保他们不会因为将数据存储在他们的系统中而最终拥有这些数据。围绕它有许多法律术语。”
你正在努力寻找人才还是驾驭技术?
我们喜欢听到不同的团队如何将机器学习与生物技术结合使用。如果您需要帮助或只是想聊天,直接联系我们的首席执行官。
生物≠技术
理解神经网络的一种稍微不同的方法
由 Unsplash 上的 chuttersnap 拍摄
每当我阅读一本关于神经网络的教科书时,介绍总是非常相似:它们大多以源自生物学的动机开始。这一直让我有点困扰。我绝不是生物学家,但在我看来,生物神经网络和人工神经网络之间存在相当大的差异:
- 神经网络(通常)具有确定的拓扑结构,并且通过修改权重来进行学习。另一方面,天然神经元不断改变它们的结构来学习。
- 生物神经元有一个“全有或全无”的策略:要么刺激通过,要么不通过,而人工神经元具有平滑的激活功能。
- 生物神经元有更高的容错能力。
因此,因为这些事情,我从来没有真正弄清楚为什么生物学概念的抽象数学表达在实践中如此有效。在这篇文章中,我想从一个不同的角度来探讨这个话题,即从统计学而不是生物学的角度。
逻辑回归:简介
为了接近神经网络,我们首先回到“经典机器学习”,特别是逻辑回归。让我们从一个简单的二元分类问题开始,即我们想要区分两个不同的类别。我们举一个简单的例子(见下图)。基于两个特征(任意命名为特征 1 和特征 2 ),我们想要确定给定数据点属于哪个类。
图 1:有两个类的简单分类问题
因此,为了更精确地描述我们的问题,我们需要一个模型来给出一个数据点属于类 1 的概率,给定特征 1 和特征 2:
一级方程式
为了使书写简单一点,我们将从现在开始用 y 表示我们的类,用 x1,x2 = x 表示我们的特征,即上面的表达式变成
公式 2
重要提示:记住我们只有两个类别,所以如果我们已经计算了一个数据点属于类别 1 的概率,我们就可以很容易地计算出该数据点属于类别 2 的概率:
公式 3
贝叶斯统计为我们提供了一条如何重构公式 1 的规则:
等式 1
边缘化允许我们将等式 1 改写为
等式 2
现在我们将分母和分子都除以 P(y1|x) P(x ),这样我们得到
等式 3
现在我们做最后一步,再次重写等式 3。
等式 4
我们基本上只是用一个指数函数代替分母中的方程。请记住,自然对数和指数函数相互抵消。
下一步真的很重要,因为它说明了为什么我们称这种分类技术为逻辑回归。逻辑回归的核心是我们搜索特征的权重,使它们接近我们的α:
等式 5
在我们的例子中,D 是 2,因为我们只有两个类。w0 是我们也加入的一个偏差。因此,为了完成区分这两个类别的任务,我们需要学习三个权重 w0、w1 和 w2。
逻辑回归:应用
我不想回顾这些参数的实际学习过程,因为已经有很多关于这个主题的优秀文章。因此,我们现在将直接跳到模型的应用!让我们用逻辑回归分析上面的数据(图 1)。经过 500 次训练后,我们得到了以下结果:
图 2:500 个时期后经过训练的逻辑回归
哇,看起来不错!我们的模型几乎可以完美地区分这两个类别。让我们尝试另一个数据集,看看模型的表现如何。
图 3:新的数据集
根据图 3 中的数据,我们得到了以下结果:
图 4:500 个时期后经过训练的逻辑回归
嗯,这个型号一点也不好用。它看起来更像是一条穿过数据的随机直线。这是什么原因呢?要得到答案,我们必须回头看看等式 5。我们在这里看到的是,逻辑回归将特征乘以一个权重,然后将它们相加。所以我们这里有一个线性模型。Logistic 回归只能学会对线性可分的数据进行分类,或者通俗地说,可以用一条直线明确划分的数据。我们这里的数据显然不是线性可分的,因为两个类别之间的边界呈抛物线形状。但是我们可以相当容易地克服这个问题。到目前为止,我们刚刚在模型中输入了两个值:特性 1 和特性 2。现在我们只添加第三个特性(特性 1)。所以我们只要平方特征 1 的值。再次对相同的数据进行训练,我们得到了图 5 中的结果。
图 5
有了这个额外的特性,我们的模型几乎完美地拟合了数据。但这真的是可行的解决方案吗?我们希望我们的模型尽可能通用,这样我们就可以适应尽可能多的不同数据分布。还有大量的非线性函数。因此,如果我们想要对除了平方值之外的许多数据集很好地执行逻辑回归,我们将必须添加输入要素的立方、正弦、平方根和所有其他种类的非线性函数。我们可以构建一个修改的逻辑回归,其中我们不直接将特征输入模型。取而代之的是,我们定义某种黑盒,它采用原始特征并应用各种线性和非线性变换。
不像以前那样处理数学方程,让我们用图表来说明标准逻辑回归(图 6)和我们的修改版本(图 7)。
图 6:标准逻辑回归图
图 7:修改后的逻辑回归图
这两张图片看起来奇怪地类似于神经网络——因为它们就是!让我们暂时记住这一点:标准的逻辑回归只不过是一个没有隐藏层的神经网络。我们的修改版本确实是一个带有隐藏层的神经网络。主要区别在于,在真实的神经网络中,我们不需要像在这里一样手工设计隐藏层中的函数。
神经网络分类
现在让我们将逻辑回归获得的结果与实际的神经网络进行比较。首先,我们尝试一个没有隐含层的神经网络(图 8)。
图 8:没有隐藏层的神经网络
毫不奇怪,这种神经网络的性能与标准的逻辑回归一样差。只有当我们开始添加具有非线性激活函数的隐藏层时,我们才能学习非线性关系。所以让我们尝试不同数量的隐藏神经元。
图 9:左:带有一个隐藏神经元的神经网络。右图:具有两个隐藏神经元的神经网络
图 10:左图:有 12 个隐藏神经元的神经网络。右图:有 50 个隐藏神经元的神经网络
正如我们在上面的图片中看到的,只有一个隐藏神经元的网络表现很差,而两个神经元似乎已经足以进行良好的分类。看起来网络能够在两边找到两个直线决策边界。但是我们添加的隐藏神经元越多,边界就越平滑。这在底部中心尤其明显。
现在让我们来看看我们网络的内部运作。我在这个项目中使用的 Keras 库使得查看隐藏层的输出变得相当容易。
图 11:具有一个神经元的隐藏层的输出
图 12:具有两个神经元的隐藏层的输出
图 13:具有 12 个神经元的隐藏层的输出
图 14:具有 50 个神经元的隐藏层的输出
具有一个和两个神经元的隐藏层的输出并不令人惊讶。用一个神经元,我们可以检测一个边界,但不能检测另一个,而用两个神经元,我们已经可以获得相当好的结果。查看具有 12 个和 50 个隐藏神经元的网络的输出,我们可以做出两个观察:
- 相当多的神经元的输出看起来非常相似。所以这可能是一个暗示,我们实际上不需要这么多隐藏的神经元,因为它们中的许多并没有增加任何额外的信息。
- 在前两个网络中,我们看到的不仅仅是近乎线性、非常清晰的边界,而是相当多的输出值在非常窄的范围内,没有形成清晰的边界。因此,这些输出可能有助于使整体分类更加平滑。
总的来说,我们对结果很满意。我们的网络只需要几个隐藏的神经元和几秒钟的训练,就能实现良好的转换,而不是像逻辑回归那样,必须对我们的输入特征进行良好的转换。
结论
我希望这篇文章能让你对神经网络有一个有趣的新看法,并让你更清楚地了解神经网络的想法来自哪里,以及它们为什么工作得这么好。所以,也许下次你遇到神经网络时,不要把它们仅仅视为生物神经元的抽象模型,而是非线性特征转换器(隐藏层)与逻辑回归(输出层)的结合——这是一个相当简单的概念,不是什么神奇的东西,也不是“一个可以工作的黑盒”!
生物认证方法
指纹、面部识别、手形、虹膜识别、视网膜识别、语音识别、击键动力学和手写签名
作者图片
长期以来,生物识别一直是未来身份认证的目标,预计生物识别身份认证将在很大程度上取代我们当前身份认证和访问控制的其他方式。生物识别系统可用于以下两种不同的模式。
- 【1–1】:确定一个人是否是他所声称的那个人。在验证模式下,系统通过将捕获的生物特征数据与存储在数据库中的模板进行比较来验证个人的身份。
- 【1-n】:确定人是谁。在识别模式中,系统通过在数据库中搜索所有用户的模板进行匹配来识别该人。
生物识别系统首先通过 从个人处获取 生物识别数据,然后 从数据中提取 特征集,最后 将 特征集与数据库中的模板进行比较,如下图所示。
作者图片
什么是生物识别技术?
生物特征的使用,或者具体地说是独特的人类特征,已经以一种或另一种形式存在了数百年,无论是对一个人的身体描述,还是最近的一张照片。生物特征认证技术根据评估的特征类型进行分类:生理属性或行为异常。
生理生物统计学
生理生物识别是基于根据作为人体的一部分获得的数据(如指纹、面部或眼睛虹膜)对一个人进行分类。
指纹识别
迄今为止最流行的生物特征识别,指纹识别,可以利用多种分类方法,基于细节,这些细节是在手指和拇指的手掌侧、手掌和脚底发现的表皮摩擦皮脊的再现。我们可以使用它们进行身份验证,因为基本原理如下。
- 指纹在一个人的一生中不会改变。
- 指纹有一般的脊线图案,可以对它们进行系统分类。
- 指纹是一种个人特征,因为还没有发现两个手指具有相同的纹线特征。
作者图片
手的几何形状
第二个最广泛使用的生物特征是手形。我们使用手的几何特征,例如手指的长度和手的宽度来识别个人。
面部识别
该系统通过数码摄像机记录面部图像,然后分析面部特征,如眼睛、鼻子、嘴巴和下巴边缘之间的距离。
虹膜识别
下图显示了人类眼睛的一部分。
作者图片
虹膜是眼睛瞳孔周围的有色组织,由具有许多沟和脊的复杂图案组成。
视网膜识别
基于视网膜的身份识别被认为是最安全的身份认证方法。视网膜识别通过获取内部身体图像,即必须以难以伪造的方式合作的自愿者的视网膜/脉络膜,来提供对个人的真实识别
行为生物测定学
它由从用户动作中获得的测量值组成,其中一些是从人体中间接测量的。
语音验证
声音验证系统不同于声音识别系统,尽管两者经常被混淆。语音识别是识别一个人说什么的过程,而语音验证是识别说话的人。
击键动力学
该系统测量和比较特定的定时事件,也称为“打字签名”。人们在键盘上打字的方式展示了一些独特的特性。
手写签名
签名识别系统试图根据人们的手写签名来认证他们
生物认证方法的比较
我们根据安全性、准确性、持久性、可用性、充分性和成本这六个特征对生物认证方法进行了比较,分为三个级别,分别是高、中和低。
下表提供了本帖中生物特征类型的快速比较。
生物认证方法的比较
安全性
这是系统在覆盖风险方面的优势,以及在考虑潜在攻击所代表的风险及其复杂性的基础上抵御潜在攻击的效率。
- 高安全性 :指纹、手形、虹膜、视网膜。
- 中等安全 :面部、声音、手写签名。
- 低安全 :击键动力学。
准确(性)
由于收集数据的环境不同,或者生物识别中使用的阅读器不同,不可能达到 100%的准确性。因此,必须定义某些性能阈值,以考虑可靠的生物识别技术。用于评估生物识别性能的两个常规指标是 FAR 和 FRR。
- 高精度 :指纹、虹膜、视网膜。
- 中等准确度 :面部、手部几何、手写签名、语音。
- 低精度 :击键力度。
持久
这是生物特征不应该随着时间而改变的条件。
- 高持久性 :指纹、面部、手形。
- 中持久性 :虹膜、视网膜。
- 低持久性 :语音、击键力度、手写签名。
可用性
方便用户和更贴近用户需求和要求的品质
- 高可用性:指纹、面部、按键力度和语音。
- 中等可用性:手形和手写签名。
- 可用性低:虹膜和视网膜。
费用
技术在整个认证系统中的经济影响,如实施成本、维护等。
- 高成本:手形、虹膜、视网膜、手写签名。
- 中等成本:指纹。
- 低成本:面部,语音和按键动力学。
适当
能够满足特定用户群(如零售、公司、私人和投资者客户)的需求和期望的质量。
生物认证技术的用户部分
生物识别是如何被黑的?
重放攻击
在重放攻击中,入侵者能够记录涉及生物识别系统或设备的成功登录会话,然后试图通过重放捕获的数据自行执行身份验证。
例如,在语音验证系统中,黑客能够截取并记录包括用户语音在内的数据。他稍后可能试图访问同一系统,并将回放先前捕获的记录数据。
伪造的证件
一些生物识别系统可能容易受到使用伪造凭证的攻击。例如,如果生物识别系统依赖于面部识别,黑客可以通过在摄像头前拿着用户的真人大小的照片来欺骗这样的系统。
被盗凭据
一些生物识别系统比其他系统更容易受到被盗凭证的攻击。但是一想到被偷的眼睛,我们就毛骨悚然。然而,我们认为如果你的生物识别系统是基于声音的,你是相当安全的,因为我们还没有听说一个被盗的喉被用来成功骗过生物识别系统。
结论
如今,生物特征数据提取可以很容易地实现,而不需要特定的传感器;因此,当利用现代技术时,例如配备有用于面部识别或指纹的嵌入式相机的移动设备,其实现可以是低成本的。
生物认证方法的类型
指纹
由于成本低、易于使用和部署,它们是部署最广泛的技术,甚至不包括警察指纹识别。
但是有许多方法可以击败生物指纹扫描技术,例如假乳胶手指,一种表面蚀刻有指纹的木头。我们可以通过强迫使用多个手指来解决这些问题。
面部识别
由于其成本,面部识别受益于高用户接受度,但尽管如此,它们在非标准环境中的性能较低。
除此之外,这种方法也很脆弱,允许使用不难获得的“自拍”进行认证。因此,它必须伴有额外的方法,如活性检测机制。
语音验证
语音验证受益于高接受率,因为它的高可用性和成本。
与面部识别类似,结果表明在非标准环境中表现不佳。因此,语音认证技术不能被认为是足够成熟的,同样,它们必须伴随或结合其他机制。
此外,语音识别算法必须能够容忍噪音,并且不应受到喉咙痛或感冒产生的声音变化的影响。
击键动力学
由于不需要特殊设备,这种方法几乎不需要成本;它的可用性和可接受性被认为是高的,因为在大多数情况下,它可以对用户透明地执行。
然而,这种技术的主要缺点是其在训练阶段的低准确性和低安全性;因此,它适合于实现连续认证。
简单对吗?
基于隐马尔可夫模型的笔迹生物特征识别
使用 hmmlearn 在 Python 中实现
数字签名正在兴起。由于我们中的许多人现在在家工作,许多机密的公司电子邮件需要在线签名。
伊恩古德费罗斯(Ian Goodfellows)发明的生成对抗网络(GAN)展示了如今在数据集上生成虚假数字是多么容易。这实际上只是一小步,也能够生成模仿任何人的笔迹风格的签名。但是那不是很危险吗?
我们能用机器学习来区分原始签名和人工制作的签名吗?我们确实可以!我们甚至不需要那些花哨的神经网络方法,我们可以用隐马尔可夫模型(HMM) 完全经典。在这篇文章中,我将展示我们如何结合 HMM 来分类签名是原始的还是模仿的。
这个项目的灵感大致来自朱利安·菲尔兹等人的论文。艾尔。发表于 2007 年,名为:基于 HMM 的在线签名验证。
介绍
即使隐马尔可夫模型不是最先进的,正如上面论文的出版日期“2007”已经表明的,它们仍然是每个数据科学家至少应该听说过的基本概念。当你想了解更近期的技术如递归神经网络时,理解 HMM 的工作方式会有启发,因为许多技术都是从 HMM 的基本思想发展而来的。
隐马尔可夫模型
隐马尔可夫模型可以在它们的计算中包括时间相关性。在下面的图 1 中,我们可以看到,从每个状态(雨天、晴天)我们可以来回转换到雨天或晴天,每个状态都有一定的概率在每个时间步长发出三种可能的输出状态(步行、购物、清洁)。总是需要提供开始概率(雨天 60%,晴天 40%)来开始计算链。
图 1 来自维基百科:隐马尔可夫模型
在我们的情况下,这意味着签名是从左到右,一个字母接一个字母地写。所以时间依赖关系包括笔移动形成一个字母的速度,压力和坐标。所有这些信息都可以考虑在内,以估计签名是由原作者书写还是伪造的可能性有多大。
图 1 表明我们需要预先了解:
- 开始概率(雨天 60%或晴天 40%) 向量
- 过渡(例如从多雨到多雨 70%) 矩阵,
- 排放(从雨天到步行 10%、购物 40%或清洁 50%) 矩阵
请注意,开始概率总计为 100%,对于矩阵转换和发射,每行总计为 100%。
高斯混合模型(GMM)
我们需要依赖于时间的数据并从中计算特征,然后我们可以拟合 GMM 来找到我们的 HMM 的参数。当我们有了 HMM 的参数,我们可以计算原始签名和模仿签名的分数。根据分数,我们可以对签名的真实性进行分类评估。
为什么我们首先要使用高斯混合模型来训练 HMM 参数?嗯,基本上 hmmlearn 为我们提供了三种选择:
- GMM-嗯
- 高斯 HMM
- 多项式 HMM
GMM 效果最好,因为估计我们特征的密度很可能不仅仅是单个高斯或单个分布,而是地面实况看起来更像一个山谷,可以通过 GMM 更好地近似。
我们可以利用 GMM 的所谓 EM(期望最大化)算法,让我们自动计算那些隐藏参数。EM 算法期望什么来计算隐藏参数?
答案是:特色。
GMM 使用 EM 算法计算其参数:
- 步骤 e:使用 GMM 参数(均值、方差)的当前估计值计算组件占用概率 P(M|x)
- 步骤 m:使用组件占用概率的当前估计值计算 GMM 参数。
我们必须选择 GMM 的超参数,它们是:
- m:高斯混合分量
- 学生:嗯,状态(晴天,雨天)
实际上,我们无法知道最佳的超参数集是什么,但是我们可以使用 K-Fold 交叉验证来找出答案。
等等什么,超参数,HMM 参数?
好的,超参数是我们人类需要选择的值。这也叫模式选择问题。模型参数是 GMM 和 EM 算法为我们计算的参数。
资料组
用于测量这些类型的特征(压力、速度等。),我们需要一个类似于下图最左侧所示的设备:
图 1 by [1]:提出的在线签名验证系统的体系结构。
我用的是 mobisig 数据集。它总共包含 83 个条目(49 个男性,34 个女性),我们稍后将把它们分成训练集、测试集和模拟集。签名是由 Margit Antal 等人收集的。艾尔。并于 2017 年发表在他们的研究论文中:mobi SIG 指画签名语料库上的在线签名验证 。
本文提供了一个签名示例。
图 2 by [2]:来自数据库的伪签名。第一列包含真实签名,第二列包含伪造签名。
可以看出,伪造签名包含了更密集连接的压力点。这篇论文解释了伪造是如何产生的。如果你愿意,你可以阅读它,但这篇文章的重点是我们如何检测这种伪造,而不是它是如何产生的。
包导入
我将使用 python 的HMM learn包,这样我就不用从头开始构建 HMM 了。
让我们从导入这个项目的默认包开始。我设置了随机种子,所以你会有和我完全一样的情节。
文件加载
此外,我们希望确保正确地加载数据集,如上面的代码片段所示。数据存储在字典中,每个人有两个条目(“原始”和“模仿”),每个条目被进一步分成多个签名。此外,所有签名都有几百或几千行带有时间戳 id(以毫秒为单位)。
特征抽出
回头看图 1,第一步是特征提取。如果数据点以零为中心并且具有标准化的标准偏差,则拟合高斯,尤其是混合高斯会更加有效和高效。从文献[1]中,我们可以得到以下归一化步骤:
图 3: 1。步骤:位置标准化
接下来,我们在归一化步骤之后提取四个特征。公式(2。步骤)从[3]中获得:
2.步骤:特征提取
规范化步骤 1 显示在代码的函数(第 1–2 行)中。图 3 中的公式只是对所有 x 和 y 求和,然后除以出现次数 n,因此只需取平均值。此外,增加了ε(e =NP . finfo)来防止除以零的错误。
第 2 步中的四个特征非常容易计算。x 和 y 上的点表示使用我们刚刚计算的赋范 x 和 y。除此之外,theta can 的计算与代码第 24 行中的公式完全一样。第 27 行用同样的方法计算路径速度。它只是平方根!
特别要注意的是对数曲率半径*,因为如果你仔细观察,你会发现作者希望θ也被归一化。因此,在计算ρ(ρ)的第 30 行,我们也调用θ**(θ)上的范数函数。***
我在代码中把最后一个特性称为 alpha,因为它听起来比 a 更好。它和代码第 33 行中的其他特性一样容易计算。
我将所有的特征添加到它们相应的列表中,因为我们需要将这些特征输入到隐马尔可夫学习函数中。
因此,我们完成了特征提取步骤。现在让我们建立模型。
哦不! 我们需要将数据分成训练、测试和模拟数据集。从提到的条目中,我使用前 25 个人作为训练示例,这是防止过度拟合的最小数量,其中一个条目对应于一个人的多个签名。所以列车组包含 25 个不同的人,他们有许多真实和伪造的签名。测试集包含另外 20 个不同的人,验证集(X_val)包含所有模仿的签名。
***X_train: (3940, 8)
X_test: (3140, 8)
X_val: (10338, 8)***
因为我说过所有签名的行长度是不同的,所以我总是需要跟踪当前长度,并将其附加到新的数据帧中。正确编程是相当困难的。在第 51 行,我将特性重命名为特性提取步骤中的名称。
需要注意的是,我在第 47–49 行调用了特征提取函数来计算特征。
建立 GMM-HMM 模型
为了训练 GMM HMM,我们需要看一下来自 hmmlearn 的文档。
我们需要两个基本变量:
- transmat(转换矩阵)(雨天,晴天)
- startprob(开始的初始概率矩阵)(60% 40% —根据 S 的数量( HMM 状态))
转移矩阵将被参数化,使得它以 50%的概率(0.5)对角填充,除了第一个和最后一个条目。这是 hmmlearn 在文档中建议的。startprob 矩阵也是如此,我从 hmmlearn 中选择了默认的初始化。
特征变量 X_train 现在包含一个时间戳和每行七个特征:
- x 和 Y 位置
- 压力
- 四个提取的特征
现在我们可以在下面代码的第 20 行创建模型。成分的数量和混合的数量在模拟签名的估计有多好方面起着重要的作用,但是正如已经说过的,我们无法知道最佳值是什么。因此,我尝试了不同的组合。让我们来看看这两个超参数是如何相互对抗的。
第 35、39 和 43 行中的 score 函数计算三个不同集合的分数。这些分数由 GMM 的目标函数计算得出,即负对数似然*。***
好了,让我们用不同的分量值和 GMM 值调用 fit_hmm 函数:
绘制 gif 图
当我们拥有一组分数不同于或低于原始签名(蓝色或绿色)的模仿签名时,我们称之为成功。
由我用 Matplotlib 创建:用户 3
由我用 Matplotlib 创建:用户 7
我们可以看到,HMM 状态的数量对分数的影响最大。我们希望分数尽可能将红点(模仿)与原始蓝点和绿点分开。七个或更少的 HMM 状态似乎很好地将红点从其余的中分离出来,并且 GMM 分量显然对输出的影响很小。
估价
如果我们在彩色点之间画一条线性分类线,
如果签名是假的,请分类
我们可以看到 HMM 能够多好地检测签名是否是伪造的。例如,我们将阈值设置为-2200,然后对新的签名进行评分。如果分数的值小于-2200,我们认为它是假的,如果分数大于-2200,我们认为它是原始签名。
延长
我们现在可以做的是保存分数,并训练例如逻辑回归来预测概率(0-100%),基于签名是否是原始的分数。这个逻辑回归可以用 sklearn 的准确度分数进一步扩展,以估计模型的不确定性。
结论
成功!我们可以成功地区分模仿签名和原始签名。一些也映射时间约束的最新方法是递归神经网络。但是现在,我们看到这也可以用非常经典的方法实现,比如 HMM。
要了解更多信息,你可以访问我的网站,并在我链接的社交媒体中添加我。如果你在这篇博文上给我鼓掌,我会很高兴的:)。
参考
[1] Julian Fierrez 等人。艾尔。、 HMM-based 在线签名验证:特征提取和签名建模 (2007)、科学直接
【2】马吉特·安塔尔、拉斯洛·佐尔特·绍博和图·NDE·托尔戴、* 在 MOBISIG 手指绘制签名语料库上的在线签名验证 (2017)、欣达维
【3】朱利安·菲尔雷兹等。艾尔。,基于局部和全局信息融合的在线签名验证系统 (2005), Springer***
这篇博文基于从弗里德里希·亚历山大大学埃尔兰根-纽伦堡的课程模式分析中获得的知识。我使用了 Christian Riess 博士演讲的部分内容来说明这篇文章的例子。所以所有权利归克里斯汀·里斯博士所有。
生物分子序列分析
第一部分:序列相似性搜索
在某种程度上,生物分子序列“只是”固定字母表上的字符串。这可能会吸引计算机科学家,即使他们发现分子生物学神秘而有趣,但他们绝对理解字符串和字母!
在 DNA 和 RNA 中,这个字母是 A、C、T 和 g。在蛋白质序列中,这个字母是组成蛋白质的 20 个氨基酸。当然,在序列内部和序列之间发生了很多事情。这是分子生物学家和生物技术人员的领域。
在这篇文章中,我们将讨论所有生物分子序列分析中最有用的计算算法和工具:在已知序列的数据库中搜索一个新序列,以找到相似的序列。
为什么序列相似性搜索很重要
考虑一个已知蛋白质序列的数据库,注释了关于它们的已知信息,例如它们的功能和它们的进化谱系。考虑一个新确定的序列。搜索数据库来寻找与这个新序列高度相似的序列可能会很有启发性。这可能有助于阐明这个序列在进化等级中的位置。它也可能产生对这个序列的功能作用的见解。
以新冠肺炎序列为例。谁知道在已知病毒序列的数据库中搜索会发现什么。
变异游戏
这将极大地有助于理解接下来的相似性搜索问题。相信我。
我们会挑选 DNA 序列。只是因为他们的字母表更容易描述。这个游戏的经验同样适用于蛋白质序列。
游戏的整体结构是:
- 我们从一组不同的序列开始。
- 我们将这些收集到一个数据库中,我们称之为“已知序列”。
- 我们以特定的方式突变其中的一些序列(我们将在后面讨论细节)。
- 这些产生了我们所认为的“新确定的”序列。
- 我们使用相似性搜索算法和工具在数据库中搜索这些“新确定的”序列。
- 如果一切顺利,在每种情况下,我们都希望找到产生突变序列的序列。(正如我们很快就会看到的那样,事情不会总是一帆风顺。)
变异模式
我们将重点介绍三种类型的变异操作:在某个位置插入一个新符号,删除某个位置的符号,用另一个符号替换某个位置的符号。第三个是通过一个替代矩阵来完成的,该矩阵捕获替换偏好。我们把这三个操作分别叫做 I,D,S。
我们假设 I 和 D 中的每一个都有一个固定的概率,这个概率不依赖于突变在序列中的位置。(这个假设可以放宽。在一些特殊的用例中,这非常有帮助。然而,它有训练数据和算法结果。)替换也将用概率来建模。
让我们看一个例子。(我们将概率表示为百分比。)说 P(I) = 5%,P(D) = 8%。这意味着在任何位置都有 5%的机会插入字符,8%的机会删除字符。我们假设插入的字符是随机选择的。(更高级的模型允许在要插入的字符上的分布取决于位置。在某些用例中,这非常有帮助。然而,这也使建模变得复杂。)
假设我们的替代矩阵是
A C T G
A **90%** 2% 4% 4%
C 7% **80%** 5% 8%
T 3% 5% **85%** 7%
G 6% 2% 3% **89%**
首先,我们来带出它的特点。每行总和为 100%。这是因为包括了自身替换。所以,在每一个位置,一定会发生一些替换。第二,对角线项接近 100%。这表明自我替换比改变符号的可能性要大得多。最后,注意我们的替换矩阵是不对称的。对称在这个阶段是额外的不必要的假设。
突变单个序列
让我们来做一个突变单个序列的心理模拟。我们将获得一个输入序列,并从左端开始,在每个位置上概率性地应用三个变异操作。我们将展示有变化的所有中间序列。
我们的首发顺序很傻;尽管如此,它将完成我们为它设定的任务。
AAAAAAAAAA → AA**T**AAAAAAAA → AA**T**AA**G**AAAAA → AA**T**AA**G**AAAA
^
第一个突变是紧接在位置 2 之后的 T 的插入。第二个是替换 A → G,我们用粗体标出了这两个。第三个是删除序列中倒数第二个字符。我们用^.标记了这一删除
最后,我们可以通过简单地多次重复这一过程来模拟更长期的进化。也就是说,我们对序列进行多次突变。毫不奇怪,我们通过的次数越多,最终的突变序列与我们开始时的序列差异就越大。由此产生的突变序列被称为(起始序列的)远源同源物。
突变多个序列
既然我们已经详细了解了突变单个序列所涉及的内容,让我们继续来突变几个。这当然是现实中发生的事情。对我们的目的同样重要的是,它将帮助我们更好地理解为什么序列相似性算法如此复杂。简而言之,我们突变的序列越多,就越难辨别突变序列是从哪个序列进化而来的。
为了阐明上一句的观点,我们将从一个比第一个更愚蠢的例子开始。
AAA → A**C**AA → ACA
ACC → A**A**C
TTT → **C**TT
AAA、ACC 和 TTT 这三个序列中的每一个都发生了突变。注意,第一个序列经历了两个突变。
现在让我们将已知序列的数据库设置为我们开始时的数据库:{AAA, ACC, TTT}
。可以考虑用 ACA 搜索一下。有理由期待会发现两个结果:AAA 和 ACC,因为它们都与 ACA 足够相似。接下来,考虑在数据库中搜索 CTT。在这种情况下,只有一个结果将被发现,TTT,在同一水平的相似性。
我们试图用这种比较来说明什么?
*The statistical significance of a search result depends on the number of search results on the same query that get found*.
结果 ACA → AAA 不像结果 CTT → TTT 那样具有统计显著性,因为对于查询 ACA 有两个足够相似的结果,而对于查询 CTT 只有一个。这也有直观意义吧?我们对 CTT → TTT 的结果更有信心,因为它是独一无二的。在 ACA → AAA 中不那么明显,因为它不是。
如果我们把这个例子扩大到现实,直觉会变得更有说服力。当在足够高的相似性阈值下搜索数百万个序列的数据库时,一个查询可能返回唯一的结果,第二个查询可能返回数千个结果。显然,第一个查询的结果比第二个查询的结果更重要。
编辑距离
至此,我们已经不严格地使用了术语“相似”和“相似性阈值”。现在让我们将它们形式化。这将有助于我们更具体地理解上述问题。它也是通向更高级的相似性度量的桥梁,我们将在讨论具体的相似性算法时看到。
两个序列的编辑距离是将一个序列转变成另一个序列所需的最小突变数。考虑(AAA,ACA)。它们的编辑距离是 1,因为我们可以通过一次替换将一个转换为另一个。
编辑距离是量化两个序列之间相似性的一个很好的近似度量。我们说“近似”有以下几个原因。首先,可能发生了比编辑距离所暗示的更多的突变。拿我们的例子 AAA → … → ACA。这涉及到两个突变。编辑距离建议一个。第二,编辑距离不能捕捉特定突变的不同概率:插入、缺失和特定替换。
好的,让我们用编辑距离的语言重新表达一下我们之前看到的例子。我们的数据库是{AAA, ACC, TTT}
。根据它搜索 ACA 会在编辑距离 1 处找到两个结果。搜索 CTT 在编辑距离 1 处找到一个结果。
所有三个结果到查询的编辑距离相同。然而,如前所述,第三个结果比前两个结果更具统计学意义。也就是说,它更值得信任。
显然,编辑距离无法衡量统计意义。我们需要一个独立的机制。我们就不详细讨论了。它体现了我们已经讨论过的原则:一个查询返回的结果越多,应该分配给其中任何一个的信任就越少。
在所谓的“局部比对”搜索的设置中,结果的统计显著性从“非常重要”到“极其重要”。到目前为止,我们还没有讨论“局部比对搜索”。所以读者可能不知道我们的意思。然而,我们认为在现阶段提出这一点是重要的。
序列相似性算法
我们已经看到了各种变异算子。现在让我们描述考虑到这些的序列相似性算法。
全局对齐
首先,我们需要另一个关键概念。两个序列(相同类型:DNA 或蛋白质)的全局比对是它们的符号之间的 1-1 对应,遵循序列顺序。让我们看一个例子。
A-CAT ACAT
| | | ||||
AAC-T AACT
我们看到 ACAT 和 AACT 两个序列的两个全局比对。左侧对齐中的“-”符号表示“‘无’与符号对齐”。这些实现了移动一个或另一个序列的效果,使得对准的符号是兼容的。第二次对齐不使用任何“-”符号。
凭直觉,读者可能会猜测左边的排列比右边的好。读者可能是对的。这个会在下面出来。
全球比对分数
接下来,我们描述全局比对分数的概念。最常用的形式,实际上也是我们将描述的算法所使用的形式,简单地将比对中各种比对对的分数相加。
这里有一个例子。考虑左边的对齐方式,可能表示为{(A,A),(-,A),(C,C),(A,-),(T,T)。该比对的分数可以描述为
S({(A,A),(-,A),(C,C),(A,-),(T,T)}) = **S(A,A)** + *S(-,A)* + **S(C,C)** + *S(A,-)* + **S(T,T)**
粗体的术语对应于我们之前在突变游戏中看到的替换。斜体术语对应于插入和删除突变。
关键的一点是,尽管序列相似性算法至少部分是由突变博弈的考虑所驱动的,但在实践中,当比较两个序列时,我们经常不知道哪个扮演祖先的角色,哪个扮演后代的角色。
事实上,在许多用例中,甚至可能不存在这样的关系。想象一下,试图辨别两个序列是否是不太远的祖先的兄弟。高度的序列相似性可能对此有所帮助。很明显,没有祖孙关系,只有兄弟姐妹关系。
鉴于以上所述,相似性算法对称地对待两个序列是有意义的。其结果是对齐中出现的’-‘不再能被解析为插入或删除。考虑对齐对(X=A-,Y=AA)。如果我们认为 Y 是祖先,那么’-‘可以被视为删除,如果我们认为 X 是祖先,那么’-‘可以被视为插入。由于这个原因,从现在起我们称 a 为’-’ an indel 。事实上,我们将更进一步。我们将使用术语 gap 来表示 indel ,因为它听起来更好。
其进一步的结果是,将间隙与实际字符对齐的成本是相同的,而不管间隙是在顶部还是在底部。
接下来,让我们根据上一段中提到的要点来改进我们的分数示例。 S (A,A)S(C,C)S(T,T)都是来自一个 DNA 置换矩阵的分数。 S (-,A)和 S (A,-)都由一个负数表示,称为缺口成本。这个数字是负数,因为它是成本。
现在让我们详细阐述一下 DNA 置换矩阵。这在性质上类似于我们之前看到的 DNA 替换矩阵,在突变游戏中。性质相似但不相同。
如果你想知道为什么两个替换矩阵会不同,请阅读下一段,否则跳过它(它有点长,而且有点偏离我们在这篇文章中的主要路径)。
由于前面讨论的原因,相似性算法对称地处理两个序列。这意味着我们的替换矩阵也需要对称。相比之下,进化替代矩阵不必如此。第二个原因是我们正在对单个比对对的分数求和。在我们的例子中,限于涉及替换的术语,这是 S (A,A) + S (C,C) + S (T,T)。如果替换矩阵条目是概率(就像在突变游戏中那样),我们将会进行乘法运算。实际上还有更多。我们就陈述一下,不做解释。符号的对齐对(X,Y)的得分 S (X,Y)被定义为 log [ P (X,Y)/[P(X)P(Y)],其中 P (X,Y)是在真实的全局对齐中看到对齐对(X,Y)的概率,而 P (X)和 P 【T
好吧,回到主路。出于说明的目的,甚至下面的替换矩阵就足够了:
S(X,Y) = 1 if X equals Y and -1 if not.
给定这个替代矩阵,我们想要选择一个绝对值小于 1 的缺口成本。我们把它设置成。
好了,现在我们已经准备好计算我们两个全球比对的精确分数了:
S({(A,A),(-,A),(C,C),(A,-),(T,T)}) =
S(A,A) + *S(-,A)* + S(C,C) + *S(A,-)* + S(T,T) **=** 1–½ +1–½ +1 = **2**S({(A,A),(C,A),(A,C),(T,T)}) =
S(A,A) + S(C,A) + S(A,C) + S(T,T) = 1–1–1+1 = **0**
第一次比对得分较高,如您所愿!
找到高分比对
我们现在知道如何进行全球比对。接下来,我们将介绍如何在众多比对中找到得分最高的比对。这是更多奇迹发生的地方。
给我们两个 DNA 序列 X 和 Y,置换矩阵 M,以及缺口成本 C < 0. Our aim is to find the highest-scoring alignment of X and Y.
The exhaustive search approach of generating every alignment, scoring each, and picking the one that scores the highest is excessively slow on long sequences. There are too many alignments to wade through!
Fortunately, there is a clever algorithm that is guaranteed to find an optimal alignment much faster. It uses an approach called dynamic programming.
The algorithm involves building a matrix S with n +1 行和 m +1 列其中 n 和 m 分别是 X 和 Y 的长度。
接下来,关键点来了。花时间去吸收它。不到一分钟,我保证。
*S*(i,j) is the score of a best alignment of the first *i* symbols in X with the first *j* symbols in Y.
为什么这很重要?该算法的关键思想是以最优方式解决问题的较小版本,并从这些版本中为较大版本构建最优版本。具体来说,我们从左上角开始填充矩阵,最终在到达右下角时停止。(我们将很快介绍完整的端到端示例。)
我们首先将 S (0,0)设置为 0。这是有道理的。没有要对齐的内容,因此它的得分为“nothing”,其数值转换为 0。(注意“没什么”不等于“不知道”。)
接下来,我们为所有的I0 设置 S ( i ,0)到 i *C,为所有的 j > 0 设置 S (0, j )到 j *C。为什么?考虑 S ( i ,0)。它是 X[1]的最佳比对的分数… i 带有空前缀 y .这样的对齐只有一个,其中 X[1… i 与 i 间隙对齐。这次对齐的分数是 i *C,同理,我们可以看出为什么 S (0, j )被设置为 j * C 。
下一个关键点现在来了。如何从 S 矩阵中到那时的分数计算出 S ( i , j )。这是公式
S(i,j) = max{ S(i-1,j-1) + M(Xi,Yj), S(i,j-1) + C, S(i-1,j) + C}
max 中的第一项对应于扩展 X[1… i -1】和 Y[1… j -1】添加对齐的对(X[ i ,Y[ j )。得到的比对分数为 S ( i -1, j -1) + M(X i ,Y j )。
max 中的第二项对应于扩展 X[1… i 和 Y【1… j -1】通过添加对齐的对(-,Y[ j ])。X 部分是一个间隙,因为正在延伸的路线中已经有 X[I]。
第三任期为第二任期,其中 i 和 j 互换。
S(i,j)被设置为“最佳中的最佳”,即这些项中的最大值。
到目前为止提出的算法仅找到最优全局比对的分数,而不是比对本身。在我们讨论后一个话题之前,让我们先来看一个端到端的例子,因为即使在评分部分也有很多东西需要学习。
示例
如果 x 等于 y ,我们将使用替换矩阵 S ( x , y ) = 1,否则为-1。我们会用差距成本。我们将计算 X = ACA 和 Y = AAC 的全局比对分数。(即使在这个简单的例子中,得到的分数矩阵也会惊人的丰富!)
**A A C**
0 -½ -1 -3/2
**A** -½ 1 ½ 0
**C** -1 ½ 0 3/2
**A** -3/2 0 3/2 1
在解释这个矩阵中的各种值之前,让我们检查一下最后的分数,即右下角的“1”是否正确。对于我们的替代矩阵和缺口成本,ACA 和 AAC 的最佳比对是
ACA-
| |
A-AC
这次比对的分数确实是 1。
现在让我们讨论一下这个矩阵中的一些不同的分数。第一行和第一列中的分数对应于将连续的缺口串与另一序列的前缀进行比对。我们之前已经看到过,这是一个初始化步骤。
接下来我们来看看分数 S (1,1)。这表示 A 与 A 的最佳比对分数。它应该是 1。它的值来自于项 S (0,0) + M(A,A) = 0 + 1 = 1。很容易检查到来自其他项的分数,即涉及 S (0,1)和 S (1,0)的分数较低。
接下来我们来看看分数 S (3,2)。这代表 ACA 与 AA 的最佳比对分数。我们可以看到这种排列必须是(ACA,A-A)的形式。它的分数是 2 –= 3/2,这正是我们所看到的。
从得分矩阵重建最佳比对
在许多用例中,例如数据库相似性搜索,对两个序列进行相似性评分就足够了。可以单独使用查询结果相似性得分来对相似性数据库搜索的结果进行排名。
在其他用例中,我们还需要找到实际的最佳匹配。我们现在涵盖这一点。
关键思想是这样的:当我们构建评分矩阵时,我们记录在计算单元格的值时使用了哪个术语。也就是在计算 S ( i 、 j )、 S ( i -1、 j -1)、 S ( i 、 j -1)、或 S ( i -1、 j 【T(如果使用了多个,如果我们想要找到所有的最优全局比对,我们应该记录所有的,或者如果我们只寻找一个,则任意地打破联系。)
让我们看看添加了额外元数据的示例版本。计算 S ( i , j ),D 表示使用了 S ( i -1, j -1),L 表示使用了 S( i , j -1),U 表示 S ( i -1)d、L、U 分别对应对角线、左、上。
**A A C**
0 -½ -1 -3/2
**A** -½ 1 (**D**) ½ (**D,L**) 0 (**L**)
**C** -1 ½ (**U**) 0 (**L,U**) 3/2 (**D**)
**A** -3/2 0 3/2 (**D**) 1 (**L,U**)
下面解释一下 S (2,3) = 3/2 附带的元数据。这个元数据是 d,我们看到 X[2]和 Y[3]都等于 C,因此我们可以看到 S (2,3) = S (1,2) + M(C,C)。
回溯阶段:一旦构建了完整的得分矩阵(包括元数据),通过反向“回溯”来重建实际的最优比对。这可以被视为仅仅跟随从矩阵的右下角单元开始的反向指针。
让我们在例子中说明这一点。我们从细胞(3,3)开始。这里附上的元数据是(L,U)。让我们任意选择:l。所以我们向左移动,在单元格(3,2)处结束。在单元格(3,2)中,我们有一个 d,所以我们对角移动到单元格(2,1)。在单元格(2,1)中,我们有一个 u,所以我们向上移动到单元格(1,1)。在单元格(1,1)中,我们有一个 D,所以我们对角移动到单元格(0,0)。
我们从终点出发,到达起点。所以我们结束了。(尽管如此,我们仍然需要填充一些细节——事实上,实际的对齐。)让我们按照采取行动的顺序来看看我们采取的行动。
(3,3) → L → (3,2) → D → (2,1) → U → (1,1) → D → (0,0)
太好了。但是对齐在哪里呢?这是我们接下来要讨论的。首先让我们再看一遍 2D 排列中的序列,这样我们就可以随着解释的展开来想象它们。
X\Y AAC
A
C
A
我们刚刚看到的脚手架上将会分层排列。我们的第一步是从单元格(3,3)中取出 L。想象它离开 Y[3] = C,停留在 X[3]。接下来,将此视为创建对齐对(-,C),即 X 中的一个缺口与 Y 对齐[3]。
我们的下一步是从单元格(3,2)中取出 D。想象这个移动离开 X[3]和 Y[2]。把这想象成创建对齐的对(X[3],Y[2]) = (A,A)。
我们的下一步是从单元格(2,1)中取出 U。这是一种进步。它创建了对齐的对(C,-)。我们的最后一步是从单元格(1,1)开始的 D。它创建了对齐的对(A,A)。
好的,让我们看看所有这些附加到我们的脚手架上。
(3,3) → **L** → (3,2) → **D** → (2,1) → **U** → (1,1) → **D** → (0,0)
X **—** **A** **C** **A**
Y **C** **A** **—** **A**
这是反向排列。逆转它给
ACA-
| |
A-AC
我们可以看到这是一个最佳的排列。
局部对准
通常我们感兴趣的是局部比对两个序列,而不是全局比对。在局部比对中,一个序列的连续切片与另一个序列的连续切片进行比对。这既包括找到相似的切片,也包括将它们对齐。
下面是一个局部对齐的例子。这一个在排列中没有任何间隙。
ACACT**TAACTTAACGAT**SACA
||||||||||||
GTCATCAGT**TAACTTAACAAT**GAGA
局部比对的一个常见用例涉及识别蛋白质序列中的保守区域。这种区域称为结构域,可以独立于蛋白质的其他部分进化和发挥功能。大多数蛋白质都有多个结构域。这些结构域决定了蛋白质的功能。因此,识别蛋白质序列中的结构域是非常有用的。典型地,这是通过对照具有已知结构域的蛋白质序列的数据库,对其结构域未被表征的蛋白质序列进行局部比对搜索来完成的。或者对照结构域序列数据库。
这是第二个涉及局部对齐的场景。我们有一个基因序列。我们感兴趣的是找到所有含有与其高度相似的基因的基因组。这包括以该基因的序列作为查询进行局部比对搜索,并以合适的全基因组序列数据库作为目标。
两个序列的最佳局部比对
先前描述的全局对齐算法可以被调整以找到最佳的局部对齐。
关键的变化包括用以下公式替换计算单元格得分的全局对齐公式
S(i,j) = max{ S(i-1,j-1) + M(Xi,Yj), S(i,j-1) + C, S(i-1,j) + C, **0** }
唯一不同的是加粗的 0。我们如何看待这一点?如果前三项都是负的,则该算法停止扩展先前的比对,而是从(X[i],Y[j])开始新的局部比对。此选项在全局对齐中不可用,只能进行扩展。全局对齐必须从单元格(0,0)开始。相比之下,局部对齐可以从任何单元格开始。
出于同样的原因,初始化步骤也被修改如下:
S(i,0) = 0 for all i; S(0,j) = 0 for all j
第二个变化涉及从哪里开始重建最佳局部比对。在全局对齐的情况下,是从 S ( m , n )其中 m 和 n 分别是 X 和 Y 的长度。在局部对齐的情况下,对齐可以在任何地方结束。因此,代表最佳局部比对末端的单元是包含评分矩阵中最大值的单元。追溯阶段从该单元开始。然后,它完全像全局对准器那样重建最优对准,除了它在其重建期间遇到的值为 0 的第一个单元处停止。
局部比对搜索:BLAST
局部和全局对齐算法都是计算密集型的。使用它们将查询与数据库中的每个序列进行比较可能会非常慢。
一种称为 BLAST(基本局部比对搜索工具)的工具放弃了寻找最佳比对的目标,而是通过一种更快的算法来寻找“足够好”的比对。BLAST 是所有生物分子序列分析中使用最广泛的软件。
下面是 BLAST 的工作原理。
首先,它识别查询序列中的 k -grams。(一个 k -gram 只是一个序列中长度为 k 的连续片段)。对于 DNA 序列来说, k 的默认值比蛋白质序列大得多。
接下来,它将新的k-克添加到这个列表中。这个步骤是特别为蛋白质序列而做的。它包括找到 k 个对于适当选择的替换矩阵来说分数足够高的图。不允许有缺口,所以这只是简单的计分。无评分矩阵;没有追溯。足够相似的 k 图对的构造可以离线完成。这加快了寻找与查询中相似的字母的过程。
接下来,BLAST 在数据库中查找所有包含这个列表中至少一个 k -gram 的序列。(计算机科学家,这类似于在搜索引擎中使用单词的倒排索引来查找候选文档。)
接下来,它考虑每个这样的事件,称为命中,并试图在两个方向上扩展它。将此过程视为旨在找到锚定在该命中点的最佳局部比对。
接下来,它计算比对的统计显著性分数。虽然细节很复杂,但高层次的目标是我们在本文前面讨论过的。这是为了考虑局部对齐偶然出现的可能性有多大。这个(机会)可能性低的时候分数就高。
最后,局部比对根据它们的统计显著性分数按顺序输出。
示例
我们的目的是用最简单的方式来说明 BLAST 算法。这个例子完全不现实。例如,它选择的 k 太小,在实践中不能很好地工作。
假设我们的查询序列是 ACATGA。假设我们选择 k = 3。该序列中的k-克为
ACA, CAT, ATG, TGA
下一步,添加更多类似于这些的k-gram,为了说明,想象一下,选择的替换矩阵认为替换 C ⇔ G 和⇔ T 是兼容的,其余的不兼容。假设选择分数阈值,使得最多允许这些替换中的一个,这将导致向上面的列表添加以下 k-gram
ACA → AGA, TCA, ACT, CAT → GAT, CTT, CAA, ATG → TTG, **AAG**, ATC
TGA → AGA, TCA, TGT
有一些重复的。还是,咻!
接下来,我们在数据库中搜索至少包含上面列表中一个 k -gram 的序列。假设我们发现的一个序列是 TTAC AAG ACC。这里,粗体区域标记了我们的 k 图列表中的一个热门图。接下来,我们将查询定位到这个命中的序列,如下所示。
ACATGA
|||
TTAC**AAG**ACC
接下来,只要分数保持增加,我们就尝试在两个方向上延伸对齐。在我们的例子中,这种对齐将覆盖整个查询序列。
关键环节
基本局部比对搜索工具(BLAST)寻找序列之间的局部相似区域。该程序比较…
blast.ncbi.nlm.nih.gov](https://blast.ncbi.nlm.nih.gov/Blast.cgi)
鸟箱
用康奈尔大学的 NABirds 数据预测包围盒。
这是我上一篇关于使用由康奈尔鸟类学实验室提供的鸟数据集进行图像分类的文章的续篇。在本文中,我超越了简单的分类,考虑对象检测,这可能更好地称为图像或对象定位。我不仅试图确定某个对象是否在给定的图片中,即检测组件中,而且还试图找出该对象在图像中的位置。
尽管我有自己的观点,但物体检测是文献中普遍使用的术语,我将遵循惯例。
关于 NABirds 数据的详细讨论可以在前面的文章中找到;我在这里仅仅回顾一下重点。有 48562 张图片,大致均匀地分布在 404 种鸟类的训练集和验证集之间。除了图像之外,还有大量的元数据,包括男性/女性、青少年/成人和其他适当颜色变化的几个分类和注释级别。最终结果是最细的 555 个类别。在最粗略的层次上,有 22 个类别,这在这里会更有意思。在任何层面上,数据都远未达到平衡;有些种类很常见,有些极其罕见。
这个项目的目标是双重的。首先,我只想预测图像中包含一只鸟的边界框。只有一个检测类 bird,模型必须找到鸟在图片中的位置。第二个任务是定位这只鸟,并预测它属于 22 个顶级类别中的哪一个,这大致对应于分类学中的目。下面列出了按常用名称描述字母顺序排列的类别以及图像数量。请注意,占所有鸟类一半以上的栖息鸟类是迄今为止最大的群体。敏锐的博物学家也会注意到,鸻形目(即滨鸟)被分成几个类别。
边界框
每个图像只有一个带标签的鸟和一个包含它的边界框。边界框是一个小矩形,包含模型正在搜索的图像中的对象以及尽可能少的其他内容。有三种方法来标记边界框,都涉及四个坐标。最简单的就是用盒子的左上角和右下角的坐标。(按照惯例,图像的左上角是(0,0),右上角是(宽度,高度))。或者,右下角可以替换为框的高度和宽度。第三种,也是数值上更稳定的,系统使用高度和宽度,但是用盒子的中心替换左上角。所有这三种方法都被对象检测网络用作输入,但是在训练神经网络时,大多数都转换为第三种系统。
带边框的闪亮鹰。从纳伯德的数据集中。
上图就是一个很好的例子。包围盒完全包围了这只闪亮的鹰,除了它的部分尾巴(尾巴在包围动物时很棘手)。盒子几乎尽可能的紧,同时仍然封闭整个动物。在我们的三种符号方案中,盒子将被编码如下:
- 左上,右下= (141,115),(519,646)。
- 左上,宽度,高度= (141,115),378,531。
- 中心,宽度,高度= (330,380.5),378,531。
在实践中,坐标通常被缩放为宽度和高度的百分比(即在 0 和 1 之间)。还通常使用盒子高度和宽度的对数标度变换,因为预测大盒子尺寸的小误差没有预测小盒子尺寸的小误差严重。
原则上,图像可以包含任意数量的包围盒,包围任意数量的不同类别的对象。我很幸运,NABirds 中的每个图像只有一个盒子。这对训练几乎没有影响,但是会使模型的评估稍微简单一些。
物体探测网络
用于对象检测的神经网络建立在用于图像分类的神经网络的基本架构上。图像分类网络由卷积层、跳过连接、初始层(一种层内分形层架构)、池层、批量标准化、丢弃和挤压激励组件的惊人复杂组合组成,但最终层很简单。全局平均池(GAP)层将最终张量折叠为单个特征向量,可选的批量归一化和丢弃层提供正则化,最终的密集层通常激活 softmax,提供最终分类。可以说,用于图像分类的神经网络只是一个复杂的特征提取器,然后是逻辑回归,间隙层标志着转变点。大多数对象检测网络的工作方式是从间隙层开始移除网络的顶部,并用更复杂的东西来替换它。
这涉及到锚盒。这些框中的每一个都以图像中的某个点为中心,并且具有图像的某个分数的高度和宽度。通常,有一个给定大小的锚框网格覆盖整个图像。全套锚盒是不同分辨率网格的集合;方框越大,网格点越少。如果锚定框与给定类的输入边界框的重叠足够大,则锚定框是该类的正锚定框。如果重叠过小,锚点就是负锚点,这些边界之间的任何内容都将被忽略。这种重叠的典型度量是 IoU(交集除以并集,听起来就是这样:两个框的重叠面积除以它们的组合面积)。典型的界限是正的 IoU > 0.7,负的 IoU < 0.3。
在执行 GAP 之前,最终的输出张量可以被视为特征向量的网格,每个特征向量预测图像的一小部分中对象的存在。一个非常简单(有点太简单)的对象检测模型可以只将一个分类层附加到网格中的每个向量,以及输出四个框坐标的第二个层。然后,可以使用损失函数来训练模型,该损失函数是 softmax 分类器和盒子坐标(通常是中心、宽度和高度,以保证数值稳定性)上的 MSE 回归损失之和。
如我所说,这有点太简单了,但也不算太简单。上述模型将对应于锚盒的最粗糙级别,因为 GAP 之前的最终张量具有比原始图像小得多的宽度和高度。在旧的 VGG16 网络的情况下,224x224 图像在最终处理之前离开 7x7x512 盒。我只能检测到 49 个可能的边界框,每个框对应一个 32×32 的子图像,这些子图像是通过将原始图像分割成 7×7 的网格而得到的。在实践中,我需要能够以多种分辨率搜索数千个可能的盒子中心。
维基共享资源
我可以通过使用网络的早期层来引入更好的分辨率。在这种情况下,我有 14x14 和 28x28 个网格可用。由于这些要素在网络中处于较早的位置,因此包含的信息较少,但我可以通过对较晚的要素进行向上采样并将结果添加回来来解决这个问题。每一层都对应于一个锚盒网格。对于现代对象检测模型来说,这仍然有点太简单了,现代对象检测模型学习各种分辨率层之间的复杂关系。在神经网络的最佳传统中,组合分辨率层的层本身可以堆叠在一起,以形成更丰富的特征。
可堆叠在一起的要素池图层示例。(谭明星、庞若明、郭诉乐)
在我有一个好的物体检测网络之前,有三个更重要的,虽然简单得多的改变必须被做。首先,softmax 必须在所有分类点被 sigmoid 替换。Softmax 并不真正处理任何对象的缺失,这将是大多数锚点最常见的输出,因此必须独立预测每个类的存在或缺失。第二,分类和回归损失在不同的尺度上;必须添加一个加权因子,以便两个响应都得到很好的训练。根据型号不同,class_loss + 10 * box_loss 或者 class_loss + 50 * box_loss 效果会很好。第三个,也可能是最简单的,是让每个锚定框中心对应于不同纵横比的多个锚定框。
效率检测
EfficientNet 系列网络的基本前提是,三个主要网络参数(层数、图像分辨率和每层过滤器)之间的简单关系可用于轻松生成一系列不同大小的图像分类模型,从适用于智能手机的小型模型到最先进精度所需的大型模型。EfficientDet 将相同的原理扩展到对象检测模型。基本高效网络主干以上述方式用作特征提取器。不同的分辨率级别由一系列双向特征金字塔网络(BiFPN)进一步处理,而不是在末端有一个间隙层。BiFPN 层的数量以及每层的信道数量随着主干网络的规模而增加。最后是几个卷积层,然后是分类和盒预测。
由于我在之前的项目中使用了 EfficientNet,EfficientDet 似乎是这个项目的自然选择。这带来了一些挑战。当我开始工作时,用 Colab 运行 EfficientDet 的唯一可行的选择是基于 PyTorch 的。(Tensorflow 已经发布了他们自己的实现)。到目前为止,我所有的工作都是在 Tensorflow 中完成的。学习在新环境中工作总是一个挑战,但我不介意。在 PyTorch 工作的真正缺点是我不能在 Colab 上使用 TPU。由于只能求助于 GPU,我被迫缩减了我可以比较的不同型号的数量。到目前为止,我只运行了 D0 到 D2,每个都有默认的输入大小。对象检测通常使用比简单分类更大的图像,这意味着批量大小必须更小,因此学习率必须更小。我只能对模型使用 4 的批量大小。初始学习率被设置为 0.0002,并且在验证损失没有改善的每个时期之后下降一半。我给了模型最多 100 个历元的训练选项,但通常发现我可以在 50 个历元时停止。
预处理
与所有图像处理神经网络一样,对象检测非常依赖于良好的图像预处理。大多数重要的预处理操作都涉及到变换,如移动和缩放,它们对边界框的影响和对图像的影响一样大。幸运的是,有一个软件包albuminations可以处理这个问题。我不知道 albumentations 应该是什么(如果有的话)(看起来拼写检查器也同样被难住了),但这个包包含的函数可以确保在图像分割问题的情况下,应用于图像的任何变换也可以应用于相关的边界框和/或图像遮罩。
NABirds 图像有各种大小,其高度和宽度的上限为 1024。大约一半的人一边的长度是 1024,另一边的长度在 600 到 900 之间。批处理需要固定的输入大小。这对于训练数据来说很容易,因为我从图像中随机截取了一个正方形,但是对于验证来说有点复杂。因为我不想因为裁剪验证图像而丢失任何信息,所以我改为重新调整尺寸,使较长的尺寸与输入尺寸相匹配,然后填充较小的尺寸,直到图像变成正方形。
D1 网络的示例验证图像。较长的维度已被重新调整为 640,较小的维度已被填充。Albumentations 已经调整了边界框坐标,以便它仍然覆盖鸟。原始数据来自纳伯德数据集
下面列出了我对训练数据使用的一组转换。
第一个操作是从原始图像中随机选取一个矩形裁剪,其大小介于完整图像和 10%之间,长宽比介于 4:3 和 3:4 之间,并将其重新调整为适当大小的正方形。我总是使用我正在使用的 EfficientDet 网络的默认输入大小。
第二阶段改变色调或亮度,但不是两者都改变,有 90%的可能性(即,十次中有一次它什么也不做)。第三阶段将图像转换为 1%的灰度。接下来的三个操作是沿垂直轴、水平轴和对角线轴翻转,每个操作有 50%的概率。抠图会用零替换图像中的一些小方块;它的功能类似于后续层的辍学。下面是由这些转换产生的训练图像的示例。
NABirds 数据集的原始数据
眼尖的读者会注意到,所有这些图像都包含边界框,尽管在一种情况下,框现在是完整的图像。如果随机裁剪根本不包含盒子会怎么样?很简单,我再试一次。预处理代码进行了多达 100 次尝试,以产生一个带有边界框的裁剪,然后返回到一个更简单的缺省值,该值仅在整个图像上执行调整大小操作。
我的验证转换如下。
所有这一切都是用零填充图像,直到我得到一个正方形,然后调整大小以适应模型。它的杰作如下。
NABirds 数据集的原始数据
培养
PyTorch 没有 Tensorflow 可用的 Keras 前端,这意味着训练模型需要更多的手动工作。关键的想法仍然相当简单。对于每批训练数据,向前传播以获得当前预测,然后向后传播以更新参数。我使用的完整的Fitter
类对于本文来说有太多的样板代码,但是我可以分享训练一个纪元的循环。
在每个训练时期之后,类似的循环执行验证。如果新参数是一个改进,则保存该模型。
确认
对象检测验证不是一件简单的事情。与为每个类别生成一个概率的图像分类不同,对象检测为输出中的每个类别和锚定框生成一个单独的概率和边界框。这是一个很大的数字。其中大部分可以简单地通过阈值处理而被容易地丢弃,即,如果某个锚中某个类别的分数足够低,我们可以毫不犹豫地丢弃它。实际上,大多数锚定框中的所有类别以及所有锚定框中的大多数类别都是这种情况。这仍然存在多个边界框被标记为正 id 的可能性。如果肯定的类别与真实的类别不匹配,那么就存在明显的错误分类,但是如果类别匹配,那么也有必要考虑边界框的准确性。
如上所述,对象检测模型依赖于锚盒。在模型被训练之后,这些锚点中的每一个都有一个输出。大多数都可以被忽略,因为它们的置信度很低。也有可能两个(或更多)相邻的锚会为同一个类产生正输出。在这种情况下,边界框将非常相似,并且只需要保存一个,即具有最高置信度得分的那个。非最大抑制是去除冗余包围盒的标准算法。
直到现在,我才能着手将模型的输出与地面事实进行比较。我有一些优势,因为我知道每张图片只有一个边界框;我可以通过仅考虑具有最高置信度的预测边界框来进行评估。用于测量准确性的指标专门处理精度和召回,因此我必须定义对象检测的真阳性、假阳性和假阴性。
- True Positive —预测的类别与实际相符,并且 IoU 大于某个阈值。
- 假阳性—预测的类别与实际相符,但 IoU 低于阈值。
- 假阴性-预测的类别与实际情况不符,或者没有预测到任何类别。
精确度是真阳性与所有预测阳性的比率,而召回率是真阳性与真实结果的比率。通俗地说,精确度是准确的真实预测的百分比,召回是被识别的肯定类别的百分比。
通过计算各种 IoU 阈值(0.5 和 0.75 是常见的)下的精度,并在 IoU 阈值范围(通常为 0.5 至 0.95,增量为 0.05)内平均精度(看似多余的命名为平均精度),来评估对象检测模型。)可以为召回计算类似的度量。
单类检测
我的两个问题中比较简单的一个就是找到图像中哪里有一只鸟,并返回包含它的盒子。我尝试了三种不同的模型,在 EfficientDet 系列中从 D0 到 D2,使用具有最高置信度得分的边界框作为预测。我只允许 0.5 以上的信心分;一些图像足以混淆模型,没有边界框满足该阈值,因此有一些假阴性。
假阳性更有意思。作为一个衡量标准,IoU 必须戴几顶不同的帽子。它说预测框必须覆盖一定量的基本事实框,而且基本事实框必须覆盖一定量的预测框。低 IoU 可能意味着模型在图像的错误部分检测到了鸟,但也可能意味着模型找到了鸟,但不够精确(即,盒子太大。)通常,假阳性将是检测到鸟的情况,并且将在边界框中,但是预测的坐标不够好。
直觉上,0.5 的借据分数似乎有点低。值得看一些例子,看看不同的 IoU 阈值是什么样的。记住,图像是二维的。当不止一个维度同时发生变化时,我们的大脑很难识别面积或体积何时会翻倍。让我们看看 IoU=0.8 在现实生活中意味着什么。
六幅图像,带有实际值(蓝色)和预测值(红色)边界框,IoU 约为 0.8。NABirds 数据集的原始数据
任何看到这些图片的人可能会猜测重叠度超过 90%,但实际上在所有情况下都略低于 80%。这表明 0.8,对于许多度量标准来说被认为是一个平庸的值,对于边界框来说并不是那么糟糕。同样值得注意的是,预测的盒子往往比“地面真相”更好人类注释者有其局限性。
即使欠条只有区区 0.5 英镑,在这些人看来也没什么问题。
about 0.5 左右。蓝色表示地面真相,红色表示预测。NABirds 数据集的原始数据
这两个示例都使用了来自 EfficientDetD0 的预测。随着我从 D0 增加到 D2,精度略有提高。
使用 0.5 的 IoU 作为阈值,模型具有近乎完美的精度。只有在少数情况下,预测的边界框不会与地面真实充分重叠。即使在 0.75 的较高阈值下,预测和地面实况至少十之八九匹配。平均精度是指 IoU 阈值在 0.5 至 0.95 之间时的平均精度,它略低,因为 IoU=0.9 以上的精度急剧下降。
平均召回率也接近完美,因为只有几百张图像没有任何置信度得分至少为 0.5 的边界框。
仅从指标来看,这些模型似乎表现良好。随着模型大小的增加,精确度会适度但持续地增加。从产出来看,我认为模型甚至可能比数字显示的更好。在许多情况下,预测的边界框明显优于人类标注的地面真实。在其他情况下,预测的盒子太大,只是因为模型假设鸟在树枝后面延伸,这是一种很常见的情况。在一个滑稽的例子中,预测的边界框没有覆盖地面真相,因为它捕捉到了鸟的反射(回想起来,在训练中允许垂直翻转可能是不明智的)。在另一个例子中,预测框找到了注释者遗漏的第二只鸟。我认为,如果地面真相标签更干净一点,模型的表现会更好。
检测到鸟反射(左)和第二只鸟(右)。NABirds 数据集的原始数据
多类检测
在康奈尔大学数据集中有 22 个顶级类别,每个类别对应于鸟类的一个目或科,每个类别都有共同的名称。添加类别检测使对象检测模型的分类(是什么)组件变得复杂,但是对单独的定位(在哪里)组件影响较小。因为我已经将肯定类的数量从 1 增加到 22,所以我需要降低我认为预测分数是肯定匹配的阈值。除了最高分(每张图片一个边界框)之外,我仍然放弃所有东西,所以我可以将相对较低的 0.1 分作为正面预测。
我怎么挑了 0.1?随机猜测会给我不到 0.05;我把它翻了一倍,认为两次随机的信心得分不会偶然发生。结果很好,所以我坚持了下来。
不足为奇的是,不同类别之间的准确度或多或少地与类别中图像的数量成正比。因为我在训练中没有试图均衡数据,所以图像总数为两位数的六个班级在它们之间的三个模型中得到了两个正 id。同时,栖息鸟类占 97–98%。一个令人满意的结果是,在 300 到 1000 张图片的订单中,增加模型大小可能会产生巨大的影响。真正的阳性率可能上升 10-20%(军舰鸟的阳性率更高)。全部真阳性结果如下。
多类对象检测问题中的标准过程是通过对所有类的精度进行平均来计算平均精度。鉴于类别不平衡的程度,我认为计算整个数据集的“未加权”平均精度是有益的。这当然会给我比标准加权精度更大的数字。我认为这两个数据点都有一定的价值。
请记住,当预测的顺序与基础事实相匹配,但预测和基础事实框的 IoU 太低时,就会出现误报。
正如所料,精度比单类检测器的精度低,并且随着模型的增加而缓慢增加,这也是所料。加权(即标准)平均精度要低得多,但也比未加权的度量以更快的速度增加。这反映了这样一个事实,即对于中等规模的班级来说,准确率显著提高。两组模型的 IoU 值分布非常相似;几乎所有精度的下降都反映了该模型现在必须区分 22 个订单。
进一步的工作
任何好的实验都为新问题打开了大门。在这种情况下,我可以想到几个。假设我可以保持足够高的批量大小(即找到使用 TPU 的方法),增加模型大小超过 D2 会如何影响准确性?我用 D3 做了一个实验,但是被迫将已经很小的批量减少了一半。最终结果是较低的召回和精度分数回落到 D0 水平。由于我没有做其他的改变,看起来这完全是因为批量的原因。
我一直怀疑较大的模型需要较低的学习率。D3 和更高版本在学习率更低的情况下会更好吗?
如果我使用全部 404 个物种,甚至全部 555 个类别,而不是 22 个类别,会发生什么?我所看到的关于物体检测的一切都表明,它不能轻松处理像图像分类那样多的类别。反正还没有。
也许对上述算法最有用的测试是在一些其他的鸟类数据集上进行,比如在各种非自然主义者的数据集中的鸟类。
参考
[1]格兰特·范·霍恩、史蒂夫·布兰森、瑞安·法雷尔、斯科特·哈伯、杰西·巴里、帕诺斯·伊皮罗蒂斯、彼得罗·佩罗娜和塞尔日·贝-朗吉。与公民科学家一起构建鸟类识别应用程序和大规模数据集:细粒度数据集集合中的小字。2015 年 CVPR 。
[2]谭明星、庞若明和郭诉乐。EfficientDet:可扩展且高效的对象检测。2020 年 IEEE 计算机视觉和模式识别会议录。
强化学习算法分类的鸟瞰图
“邀请所有有志 RL 从业者”系列第 3 集
在 Unsplash 上由伊尼基·德尔·奥尔莫拍摄的照片
在本系列的第一部分中,我们已经了解了强化学习(RL)中的一些重要术语和概念。在第二部的中,我们还学习了 RL 是如何应用在自主赛车上的。
在本文中,我们将了解强化学习算法的分类。我们不仅会学习一个分类法,还会从许多不同的角度学习几个分类法。
在我们熟悉了分类法之后,我们将在以后的章节中学习更多关于每个分支的知识。不浪费更多的时间,让我们深呼吸,做一杯巧克力,我邀请你和我一起学习 RL 算法分类的鸟瞰图!
无模型与基于模型
无模型分类法与基于模型分类法。[图片由作者提供,转载自 OpenAI Spinning Up]
对 RL 算法进行分类的一种方式是询问代理是否可以访问环境的模型。换句话说,通过询问我们是否能确切地知道环境将如何对我们的代理人的行动作出反应。
基于这个观点,我们有两个 RL 算法分支:无模型的和基于模型的:
- 基于模型的是 RL 算法的一个分支,它试图根据学习到的环境模型来选择最佳策略。
- 在无模型算法中,基于代理经历的试错法选择最优策略。
无模型算法和基于模型的算法都有各自的优缺点,如下表所示。
无模型算法和基于模型算法的优缺点。[图片由作者提供]
事实:无模型方法比基于模型的方法更受欢迎。
基于价值与基于政策
对 RL 算法进行分类的另一种方式是通过考虑算法优化了什么组件——值函数还是策略。
在我们深入探讨之前,让我们先了解一下政策和价值函数。
政策
策略π是从状态 s 到动作 *a,*的映射,其中π( a|s )是当处于状态 s. 时采取动作 a 的概率。策略可以是确定性的,也可以是随机的。
马库斯·沃利斯在 Unsplash 上拍摄的照片
让我们想象一下,我和你在玩石头剪刀布的游戏。如果你不知道这个游戏是什么,这是一个非常简单的游戏,两个人通过同时执行三个动作(石头/布/剪刀)中的一个向对方竞争。规则很简单:
- 剪刀打败了布
- 石头打败剪刀
- 纸打败了石头
考虑迭代石头剪子布的策略
- 确定性策略很容易被利用——如果你选择“石头”的频率高于其他选择,并且我意识到了你的行为,那么我就可以利用这一点,这样我就有更大的概率获胜。
- 一致随机策略是最优的——如果你的行为完全是随机的,那么我不知道应该采取什么行动才能打败你。
价值函数
价值函数是一个基于对未来回报的预测或称为回报来衡量一个状态有多好的函数。基本上,回报(Gt)是从时间 t 开始的“贴现”回报的总和。
,其中 γ ∈ [0,1]为折现因子。贴现因子旨在惩罚未来的奖励,原因有几个:
- 在数学方面很方便
- 打破状态转换图中的无限循环
- 未来回报的不确定性更高(即股票价格变动)
- 未来的回报不会带来直接的好处(也就是说,人们倾向于在今天而不是 10 年后享受快乐)
我们现在知道什么是回报了。我们来定义一下价值函数的数学形式!
价值函数有两种形式:
- 状态-价值函数(通常称为价值函数)是一个状态在时间 t: 的期望收益
- 状态-行为价值函数(通常称为 Q 值)是一个状态-行为对在时间 t: 的期望收益
Q 值与值函数的区别是动作优势函数(通常称为 A 值):
好了,我们已经学习了什么是价值函数和行为状态价值函数。现在,我们准备学习更多关于 RL 算法的另一个分支,该分支专注于算法优化的组件。
基于值和基于策略的算法。[图片由作者提供,转载自大卫·西尔弗的 RL 课程]
- 基于价值的 RL 旨在学习价值/动作-价值函数,以便生成最佳策略(即,最佳策略是隐式生成的)。
- 基于策略 RL 旨在使用参数化函数直接学习策略。
- 演员兼评论家 RL 旨在学习价值函数和政策。
下表列出了基于价值和基于策略的方法的优缺点。
基于值和基于策略的算法的优缺点。[图片由作者提供]
- 基于值的算法必须挑选最大化动作-状态值函数的动作,如果动作空间非常高维甚至是连续的,代价会很大,而基于策略的算法通过直接调整策略的参数来工作,不需要做最大化计算。
- 基于值的算法如果以“错误的方式”做事,可能会振荡/颤动/发散(更差的收敛特性/不太稳定),而基于策略的算法更稳定,具有更好的收敛特性,因为它们只对策略梯度做很小的增量改变。
- 基于策略的算法可以学习确定性和随机性策略,而基于值的算法只能学习确定性策略。
- 与基于值的算法相比,简单的基于策略的算法可能更慢,并且方差更大。基于值的方法试图挑选最大化动作-状态值函数的动作,该动作-状态值函数将朝着最佳策略(更快和更低的方差)的方向改进策略,而基于策略的方法只是迈出一小步,并朝着更稳定的方向平滑更新,但同时效率较低,有时会导致更高的方差。
- 基于策略的方法通常收敛于局部最优,而不是全局最优。
符合政策与不符合政策
还有另一种分类 RL 算法的方法。这次分类是基于策略的来源。
策略内与策略外算法。[图片由作者提供]
我们可以说被归类为 on-policy 的算法是在工作中学习的*。*“换句话说,算法试图从π采样的经验中学习策略π。
而被归类为非策略的算法是通过监视某人来工作的算法。“换句话说,算法试图从μ采样的经验中学习策略π。例如,机器人通过观察另一个人的行为来学习如何操作。
最后的话
乔丹·沃兹尼亚克在 Unsplash 上的照片
恭喜你坚持到这一步!!
阅读完本文后,您应该已经知道 RL 算法是如何基于几种观点进行分类的。在未来的几集里,我们会学到更多关于基于值和基于策略的算法。
请记住,我们的 RL 之旅仍处于早期阶段!我还有很多材料要和大家分享。所以,如果你喜欢这些内容,并想在接下来的两个月里继续和我一起学习,请关注我的媒体账号,以获得关于我未来帖子的通知!
关于作者
Louis Owen 是一名数据科学爱好者,他总是渴望获得新知识。他获得了最后一年的全额奖学金,在印尼顶尖大学 万隆技术学院 攻读数学专业。最近,2020 年 7 月,他刚刚以优异的成绩毕业。
Louis 曾在多个行业领域担任分析/机器学习实习生,包括 OTA ( Traveloka )、电子商务( Tokopedia )、fin tech(Do-it)、智慧城市 App ( Qlue 智慧城市 ),目前在 世界银行 担任数据科学顾问
查看路易斯的网站,了解更多关于他的信息!最后,如果您有任何疑问或任何要讨论的话题,请通过 LinkedIn 联系路易斯。
参考
https://donnie . id/posts/on-policies-in-reinforcement-learning-algorithms-and-AWS-deepracer/
https://spinningup.openai.com/en/latest/spinningup/rl_intro2.html
https://www.davidsilver.uk/wp-content/uploads/2020/03/pg.pdf
https://www.youtube.com/watch?v=bRfUxQs6xIM & list=PLqYmG7hTraZBKeNJ-JE_eyJHZ7XgBoAyb & index=6
比特币减半是一个毫无意义的里程碑
不要相信吹捧不存在的“供应减少”的专家
照片:德米特里·德米季科
比特币期待已久的减半于今天早些时候发生,其背景是加密货币的忠实追随者们真正的狂喜。有倒计时、直播视频事件和“当月亮时”的圣歌它破解了主流新闻,被视为密码中最大的事件。减半使得地球上几乎每一个比特币拥有者都热情地进行价格预测,并在网上发布。
所有这一切绝对是疯狂的。更糟糕的是,它建立在一个谎言之上,或者至少是比特币的主要支持者有目的的误导,他们应该更清楚这一点。
如今的比特币数量(18,375,000)与减半前的昨天一样多
让我们回忆一下减半实际上做了什么。很简单:它将比特币矿工的大宗奖励减半,从 12.5 新 BTC 降至 6.25。这极大地改变了采矿业的经济状况,降低了采矿业的利润。一些矿工可能会完全停止,损害比特币的散列率。
仅此而已。这就是减半所做的一切。它降低了新 BTC 产生的速度。这绝对无助于改变加密货币的实际供应量。不幸的是,大多数专家和比特币支持者都在宣扬相反的观点。让我们一点一点解构这种误导。
减半并没有减少 BTC 的供应量
比特币减半的典型故事是这样的:
- 每隔四年,比特币的供应量就会减半
- 供给减少,但需求不变,比特币的价格只能暴涨;因为相同数量的购买者购买更少数量的硬币
- 价格怎么可能不暴涨?毕竟,这是继比特币历史上的每一次减半之后的又一次。
希望这种叙述中明显的误导现在已经很清楚了。“供给”一词有多种含义,比特币社区中有太多的人在暗示绝对供给——即流通中的比特币数量——正在下降。这不是真的。如今的比特币数量(18,375,000)与减半前的昨天一样多。实际上,这个数字还在继续增加。它只是以较慢的速度这样做。
对“供应”的普遍误解对加密货币社区关于减半的想法产生了巨大的影响。真正的后果是我在上面列出的:矿工经济学、杂凑利率——相对来说是技术性的,很难看好比特币的价格。这是一个非常无聊的故事。
相反,比特币社区更喜欢事件的扭曲版本,即减半以某种方式改变了加密货币的基本供求。考虑到 BTC 的供应量不会发生任何变化,这就需要一种巨大的精神体操。然而,许多比特币“有影响力的人”正在完成一项可疑的任务,试图证明炒作的合理性:
拥有比特币社区最大追随者的 Pomp,真的通过屠杀经济在这里以身作则。
Pomp 把新的比特币日供应量(每天开采的极小数量的比特币)与比特币的绝对日供应量(即在任何一天有多少人希望卖出 BTC)混为一谈。如果你与比特币的日常需求(即,在任何一天有多少买家希望购买比特币)进行比较,后一个定义是唯一有意义的定义,但 Pomp 将两者完全混淆了。
上面的白色趋势线跟踪了一个非常流行的完全假设的“股票到流量”模型,该模型跟踪了 BTC 明显不可避免的涨到 100 万美元。正如你所看到的,这个模型的关键特征是比特币价格如何在减半时每四年“跳”一次。
神秘的是,BTC 价格并没有遵循这位理论家精心编造的霓虹绿趋势线,也没有在“明天这个时候”突破 10000 美元。
当需求增加时,价格就会上涨
这并不是说减半没有影响。真的会影响比特币矿工的底线。但很奇怪的是,这被视为一个看涨事件或加密货币的里程碑——如果有什么不同的话,矿工因缺乏利润而停止运营的风险可能会威胁到比特币的工作证明安全性。任何兜售减半将导致 BTC 价格飙升的“经济”证据的人,都应该受到高度怀疑。
减半无非是一个预先设定好的事件,让采矿变得更加困难
另一方面,围绕减半的纯粹数量和炒作也有可能产生自己的影响。所有狂热的预期和报道(包括主流新闻来源,这是罕见的)可能会驱使新一代买家购买闪亮的加密货币钱包,寻求在比特币火箭船预定的起飞前成为其中一员。这些买家是在不成熟的理论和不可靠的经济背景下被引进的,但最终 BTC 需求的任何显著增长都会提高其价格。
然而,尽管这种增长无疑可以归因于减半的数学魔力及其不存在的供应冲击,但真正的答案恰恰相反。比特币的供应量将保持不变,而推高价格的是不断增加的需求。
对于比特币来说,这是一个可悲又无趣的事实。尽管如此多的人通过减少供应来寻求“不可避免的”价格上涨的安全性,但这实际上并没有反映比特币的工作方式或 Satoshi 的设想。
减半只不过是一个预先设定好的事件,目的是让开采变得更加困难,并使比特币产量曲线变平。如果 BTC 最终真的“无所事事”,那将是因为对该资产的需求激增,而非矿业利润减少。
如果你对加密和区块链的影响感兴趣,你会喜欢我的新出版物技术统治。我会定期写一些关于技术如何改变社会的文章,比如我最近的一篇关于冠状病毒如何让大规模监控成为我们的新常态的文章。
Pandas 中的按位运算符和链接比较
Pandas 中的比较链接和运算符优先级的重要性
在学习熊猫的时候,很自然会有使用 Python 的布尔运算符(and
、or
等)的倾向。)来链接条件,因为在 Python 中就是这样做的。然而,这些不是我们应该在 Pandas(或 NumPy)中使用的操作符。让我解释一下为什么…
图片来自 Unsplash
在 Python 中,链接比较非常简单:
x = 4
x==4 and x%2==0
True
这里我们只是检查x
是否等于4
以及是否为偶数。同样,我们可以将多个条件链接在一起,如下所示:
*b = 'random string'
x==4 and x%2==0 and b.endswith('ing')
True*
这是因为我们正在比较布尔值(True
或False
)或true/falsy值(计算为True
或False
的值),对于上面的例子,这些值产生了一个表达式True and True and True
。
比较布尔数组
然而,一个常见的错误是认为这同样适用于布尔值数组,这是应用一些比较的结果。例如:
**x = np.array([2,4,6])
x%2==0 and x!=3
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()**
正如你所看到的,上面产生了一个ValueError
。这种情况下发生了什么变化?不同之处在于,我们不再比较布尔值,因为x%2==0
产生:
**array([ True, True, True])**
这显然既不是True
也不是False
。Python 通过错误告诉我们,我们需要对结果应用聚合函数来消除歧义,a.any()
或a.all()
。这样做会将数组缩减为一个值:
**(x%2==0).any()
True**
现在可以将其与另一个布尔值进行比较。
按位运算符
当我们处理一个数组或一个 Pandas DataFrame 列,并希望基于一个以上的比较进行过滤时,我们将需要计算基于元素的操作,在本例中,基于逻辑元素的 操作。
**我们已经讨论了 python 的布尔操作符为什么不是我们想要的,因为它们要求被比较的项可以被评估为True
或False
。对于基于逻辑元素的操作,我们应该使用 python 的按位操作符<<>>&|**~和 ^.
您可以将 python 的按位运算符视为布尔运算符,但它是基于元素应用的(在布尔数组上):
****x%2==0
array([ True, True, True])x==4
array([False, True, False])(x%2==0) & (x==4)
array([False, True, False])****
所以在这里,我们在两个结果布尔向量之间应用了一个按位 AND(&),这产生了另一个形状相同的数组,该数组是通过对其元素应用逐元素操作而得到的。
Python 对于所有布尔运算符以及下面列出的其他运算符都有一个等价的按位运算符:
x & y
做一个“按位AND
”。如果x
和y
的对应位为1
,则输出的每一位为1
,否则为0
。x | y
做一个“按位OR
”。如果x
和y
的对应位为 0,则输出的每一位为0
,否则为1
。~x
返回x
(NOT
)的补码——通过切换每个1
得到一个0
,每个0
得到一个1
。这个和-x-1
一样。x ^ y
做“按位异或”(XOR
)。如果y
中的位是0
,则输出的每一位与 x 中对应的位相同,如果y
中的位是1
,则输出的每一位是x
中位的补码。
我们还有按位移位操作符>>
和<<
(见这里的)。
运算符优先级
回到上面的例子,需要考虑的一个重要方面是,使用按位运算符时,括号很重要!****
这是因为按位运算符比比较运算符具有更高的优先级,这意味着按位运算将在比较运算的之前。********
在 Python 文档的表达式部分,在 运算符优先级 ,下,我们将找到一个包含所有 Python 运算符优先级的表格,从最低优先级(最少绑定)到最高优先级(最多绑定):
图片来自 python 文档
为了更清楚地理解上述内容,假设我们有一个包含乘法运算符( ***** )和幂运算符( ****** )的表达式:
******3*2**2
12******
由于取幂运算符的优先级更高(看它是如何出现在表中较低位置的),python 会先对2**2
求值,也就是4
,然后是3*4=12
。如果我们想给乘法一个更高的优先级,我们必须把表达式括起来:
******(3*2)**2
36******
在这种情况下,我们如何写数学表达式。
现在,这同样适用于按位运算符。由于==
的优先级比&
低,我们需要用括号括起比较表达式,以便首先对它们求值:
******(x%2==0) & (x==4)******
链式运算符比较
另一个常见的错误,是试图将连锁运营商视为:
******x = np.array([2,4,6])1<x<10
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()******
NumPy(或 Pandas)不支持这一点,它会产生一个ValueError
。这里的问题是,Python 在内部将上述内容转化为:
******(1 < x) and (x > 10)******
这又把我们带到了与上例相同的错误:and
隐式调用bool
,而NumPy
只允许隐式强制为单个元素的布尔值(不是带有size>1
的数组),因为带有许多值的布尔数组既不计算True
也不计算False
。
实际上在 PEP 535 中已经提出要实现这一点,尽管它仍然被推迟了。
在接下来的帖子中,我将讨论熊猫中更高级的比较操作,并回顾一些需要记住的有用提示。
非常感谢你花时间阅读这篇文章,希望你喜欢:)
“黑匣子”。没有办法确定算法是如何得出你的决定的。
人工智能黑匣子问题是基于无法完全理解为什么人工智能背后的算法会以这样的方式工作。
我们依赖机器学习,因为机器能够从经验和数据中学习,并在学习过程中不断改进。
但是如果我们不得不依赖它的一个模型, 我们怎么能信任一个像它的数据一样不精确的模型呢?
这一切都归结于透明度。
这是 AI 仍然可以为我们提供很多东西的地方。
虽然这在游戏或零售等行业可能是允许的,但对于在金融服务或医疗保健等高度监管行业运营的公司来说,这肯定是不可接受的。
照片由 Eugene Lim 在 Unsplash 上拍摄
如果你想了解更多,请访问oscargarciaramos.com
在高层次上,机器学习基本上是基于向机器提供大量数据,以便它们学习,并允许开发复杂的算法,这些算法可以推广和扩展到机器以前从未见过的其他数据。
然而,不管我们使用什么算法,有一个事实**:模型和它的数据一样好。 坏数据→坏模型 。**
我举个例子:如果我想自动识别猫的照片,模型识别狗,我们就有问题了!
现在是“借口”来了:
- 输入数据不好。
- 之前没有进行过数据清理。
- 设置和超参数配置不正确。
- 数据有偏差,这种偏差会转移到我们训练过的数据集。
- 模型训练不足,或者存在过拟合或欠拟合问题。
“喂,我们说的是猫狗!”。好吧,没什么事。
现在让我们来谈谈面部识别模型,我们想把它卖给一家安全公司,这样他们就可以检测潜在的“小偷”。模型失败了,我们该怪谁?我发誓每个人都会逃走,没有人会告诉你一个字。
那么回到最初的问题, 我们怎么能相信一个可以像它的数据一样不精确的模型呢?
我们需要透明度
太好了,我们想要透明。但是,我们在讨论机器学习,对吗?如果我们知道学习是如何工作的,我想就没有必要用数据来训练它了。我们只是从头开始编写模型代码,然后以 50K 的价格出售。我们有生意了!
抱歉,我的朋友,但事情不是这样的!
我们将模型的功能建立在数据的基础上,通过使用不同的算法,我们试图建立最准确的模型,以便我们可以推广到其他新数据。这是第一步,我们开始用四肢爬行。但是没有人会知道如何完美地行走。我们需要不断采取措施,用更好的数据,更好的超参数配置,更好的算法,更好的机器和资源迭代,尤里卡!
从开发人员或数据科学家的角度来看,这是完美的。让我们设身处地为消费者着想。我们无法控制模型,当它的表现不如预期时,我们该指责谁?数据、数据科学家、配置?
没有人知道这些问题的答案。
作为消费者,只能用模型,或者扔掉。没别的了。要么接受它,要么建立你的,恐怕我很清楚你的决定会是什么。但随着市场的进步,这种反应越来越让人无法接受。
但是我们不能回答这个问题的原因是什么呢?
1.无法解释的算法
用于建立模型的算法有多大的解释力?
当图像识别模型将狗识别为猫时,为什么会出现这种情况?也就是说,当模型得出诸如分类或回归之类的结论时,很难理解模型是如何得出该结论的。甚至像神经网络这样的技术也有这个问题。然而,并不是所有的机器学习算法都有相同的解释问题。决策树,由于其本质,是可以解释的,然而,当我们谈论随机森林时,我们失去了那些元素。
2.无形的训练数据
正如我们所说,模型的性能直接取决于它的数据。但是,拥有完美的、干净的、标记良好的数据并不总是能确保一个好的模型。为什么?如果训练数据不代表真实世界的数据,我们就会有问题。我们将无法推断出任何东西!
3.数据选择
“我想让你给我访问你正在使用的全部数据集”。
够了吗?号码
你真的知道这些数据中的哪些被用于训练模型吗?如果我们用你无法访问的其他数据来丰富它们,会怎么样?完全透明还意味着知道如何从可用的训练数据中选择数据,并且理想情况下能够在训练数据中使用与模型消费者相同的选择方法来查看哪些数据被包括在内,哪些数据被排除在外。
4.训练数据集中的偏差
“偏差”一词可以指三个方面:在模型中建立的权重和“偏差”的意义上,在导致过度拟合或不足拟合的方差的未补偿意义上,或者在最广泛理解的意义上,作为信息“偏差”,由我们基于自己的先入为主的概念直接引起。
5.模型版本控制
我们必须明白,模型不是在一次迭代中创建的,而是连续的。过去正常工作的东西现在可能会降低性能。新的数据,新的设置,你必须发展它。但是,所有这些变化都应该主动宣布,而不是被动地宣布,以避免出现问题,并确保在新型号表现不佳时,始终能够使用以前的版本。
那么,下一步是什么?
“我们需要让行业透明化”
企业需要他们可以信任的模型。随着我们的采用增加,实现人工智能系统的透明度至关重要。
人工智能在用于现实世界的推理时必须是可靠的。
欢迎发表评论或分享这篇文章。关注 me 以后的帖子。
如果你想了解更多,你可以在oscargarciaramos.com找到我
黑狗黑猫综合症——神话还是现实?
收容所被收养的猫和狗的颜色统计。为什么黑色动物会被收养者忽视
黑狗和黑猫
介绍
黑猫和黑狗综合症是由美国防止虐待动物协会(ASPCA)在 21 世纪初建立的。这被描述为一种现象,深色皮毛的宠物大部分时间被收养者忽视,而喜欢浅色皮毛的动物。它的发生通常是由于人们的信仰、迷信和联想。黑狗,尤其是大狗,通常在电影、书籍和其他媒体中被描绘成令人恐惧和好斗的形象。黑猫还被一种不同的迷信所包围,并与巫术联系在一起。总的来说,社会将黑色与邪恶和厄运联系在一起。
主要问题:黑猫和狗会被动物收容所忽视吗?
数据
这两个数据集:动物摄入量和动物结果取自 data.austintexas.gov奥斯丁动物收容所网站
动物摄入量数据集有 115,612 个条目和 12 个特征
动物结果数据集有 115,778 个条目和 12 个特征
我开始清理数据,删除对我的观察不重要的特征。我还从数据集中排除了其他动物类型。在探索性分析过程中,我筛选出了猫狗中最受欢迎的 24 种毛色,以便进一步探索和比较。
我把我的发现绘制在一个反图上,以观察进入收容所和被收容所收养的猫和狗的数量和百分比。
计数图,按颜色比较摄入和收养动物的百分比
正如预期的那样,在两种情况下都显示动物摄入多于产出。此外,最常见的猫颜色摄入是棕色平纹和黑色,最常见的狗颜色摄入是黑色/白色和棕色/白色。黑色的狗以 20%的摄入量排在第四位.
颜色重要吗?
为了了解收养是否真的取决于动物的颜色,我进行了卡方检验。p 值接近于零的极低测试表明,收养猫和狗非常依赖于皮毛颜色。
下一步是通过颜色找出平均被收养的猫和狗的百分比。
条形图显示每种动物颜色的收养百分比
上面的柱状图表明,黑猫和狗分别被平均 43.2%和 43.5%的人收养。对黑色动物来说还不错,考虑到这一比例高于其他一些动物的颜色,如猫的白色(33.3%)和狗的巧克力色(34.4%)
黑狗黑猫欣赏日
黑猫和黑狗赞赏日创办于 2013–2014 年,它们背后都有不同的令人心碎的故事。主要想法是突出和欣赏黑色的动物,并鼓励人们收养它们。美国的大多数收容所和动物中心开始通过收取收养费和给收养者提供一些福利来推广黑色宠物。为了增加对黑色宠物的收养,促销活动在 7 月至 8 月举行,因为黑猫的欣赏日是在 8 月 17 日,黑狗的欣赏日是在 10 月,因为黑狗的欣赏日是 10 月 1 日。
推广黑宠物真的增加了黑宠物被收养的数量吗?
对于这个观察,我只过滤了黑色的动物,并使用棒棒糖图来可视化每月的收养数量。
棒棒糖计划查看每月收养黑人动物的数量
看起来对猫的促销确实增加了黑猫在七月和八月被收养的数量,但是对黑狗的促销并不影响它们被收养的数量。另一个有趣的趋势是季节性采用。大多数猫在夏天被收养,狗在冬天被收养。
进一步探索
由于收容所对黑色动物的推广,自 2013 年以来,黑猫和狗的收养率有所增加。此外,黑色宠物的摄入量在 2013 年至 2019 年期间有所下降。
条形图显示每年黑人动物的摄入量和收养量
狗和猫在通过颜色被收养之前花了多少时间
下图显示,平均而言,动物在被收养前在收容所的时间不会超过一年,然而,也有很多异常值。我们可以看到狗中有更多的离群者,这是因为狗比猫有更难的收养过程。
用动物的颜色显示收养前在收容所度过的日子
最后
总结我的观察和数据分析,我可以得出这样的结论:黑猫和狗很难被收养,而且几乎总是被忽视。人们倾向于收养皮毛颜色更浅更亮的动物。黑猫和黑狗综合症是真实的,然而,这是在不久前。
目前的数据分析显示,由于促销活动和人们接受教育,黑狗和黑猫与任何其他颜色的狗和猫一样友好、可爱、忠诚,因此几乎 45%的黑色宠物被收养。
欣赏所有动物
注意:
这个项目是作为数据科学课程的一部分为 Lambda School(Bloom Technology now)完成的。
链接到源代码:
黑人的生命也很重要
不幸的现实
很难相信,但是…
医疗保健中的种族差异被很好地记录下来,防止它们仍然是一个全国性的问题。医疗保健中的种族差异极大地导致了不利的患者健康结果。根据国家健康科学中心的数据,尽管美国的健康水平和死亡率有了显著的提高,但是白种人和黑种人之间的健康差距在 1950 年仍然很大。
在男性中,死亡率的种族差异随着时间的推移有所增加。美国国家健康科学中心也报告说,美国黑人患有多种疾病,其后果比美国白人更糟糕。
黑人女性比白人女性更不容易患乳腺癌。然而,他们死于这种疾病的可能性要高出 40%[1]。
健康差异包括几个因素,如社会经济地位。属于高社会经济地位的人群通常拥有更好的健康状况。然而,社会经济地位并不能完全证明种族健康差异的合理性,这种差异甚至在高收入群体中也持续存在。
根据 2012 年全国医疗保健差异报告,在 191 项指标中,有 43%的指标显示,具有可比 SES 和保险的黑人患者比白人患者获得的护理质量更差[1]。
更多证据
- 一项研究分析了 100 多万名患有类似呼吸系统疾病的儿童的临床访问,报告称,与白人儿童相比,黑人儿童获得的抗生素较少[1]。
2.在美国进行的另一项全国性研究表明,失去一根手指的黑人儿童断指再植的可能性是白人儿童的一半[1]。
3.根据对 800,000 份出院记录的回顾,患有外周动脉疾病的黑人患者比白人患者有 77%的机会截肢[1]。
4.与白人女性相比,接受乳腺癌化疗的黑人女性更倾向于非标准治疗方案[1]。
因糖尿病和循环系统疾病入院的黑人和白人患者的再入院率有差异吗?
回答:是的
ggplot(readmission,
aes(x= number_inpatient,
y=number_emergency))+
geom_point(alpha=1/10,size=number_inpatient)+
geom_jitter()+ geom_smooth() +
facet_wrap(readmitted~diabetesMed, scales = “free” )+
labs(y=”Number of Inpatient”,
x=”Number of Emergency”,
title = “Number of Inpatient and Emergency by Readmission Status for Diabetic Patient”,
caption=”Each facet is scaled independently”)+
theme_light()
视觉叙事
作者照片
ggplot(readmission,
aes(y= num_medications,
x=num_lab_procedures, color=readmitted))+
scale_color_discrete()+
geom_point(alpha=1/100,size=number_diagnoses)+
geom_jitter(alpha=1/40)+
facet_wrap(~readmitted)+
labs(y=”Number of Medication”,
x=”Number of lab procedures”,
title = “Number of medications and lab procedures”)+
theme_dark()
作者照片
ggplot(readmission, aes(x=readmitted, color=age ))+
geom_histogram( stat = “count”, aes(fill=age))+
facet_wrap(~race,scales = “free”)+ scale_color_discrete()+
labs(y=”Number of patients”,
title = “Number of Readmissions by Race and Age”,
subtitle = “<30: readmitted within a month \n >30: readmitted after one month \n NO: Not readmitted “,
caption = “Note: Each facet is scaled independently”)
作者照片
分析显示,总体而言,患有类似疾病的美国黑人和白人患者受到了不同的对待。如下图所示,所有因素,如“实验室检查次数”、“住院患者就诊次数”、“门诊患者就诊次数”、“住院时间”、“诊断次数”、“药物治疗次数”都有显著差异。
作者照片(使用的软件:PRISM9)
如下所示,详细的分析还表明,与糖尿病黑人患者相比,糖尿病白人患者接受了更多的药物治疗和诊断测试。对于非糖尿病患者,美国白人接受了更多的实验室检查和诊断程序。然而,非糖尿病黑人和白人患者接受的药物治疗数量相似。
作者照片(使用的软件:PRISM9)
下面的分析表明,美国黑人比美国白人更有可能被重新接纳。
作者照片(使用的软件:PRISM9)
参考
[1]乔因特·柯,奥拉夫·EJ,贾·阿克。按种族和医疗场所划分的医疗保险受益人的 30 天再入院率。 JAMA。 2011 年;305(7):675–681.doi:10.1001/jama
布莱克-斯科尔斯期权定价是错误的
理论、假设、问题和从业者的解决方案
Black 和 Scholes (1973)提出的公式是欧式期权的标准理论定价模型。关键词是理论上的,因为布莱克-斯科尔斯模型做出了一些关键假设,但在实践中却立即遭到了违反。
关键模型假设:
- 没有交易成本
- 无套利
- 连续交易
理论与实践
布莱克-斯科尔斯模型依赖于复制投资组合的概念(更具体地说,一个抵消复制投资组合,或对冲——见波动性交易 101 )。复制投资组合反映了期权的现金流,它是通过在基础资产中建立一个相对于基础资产的布莱克-斯科尔斯方程的一阶偏导数的头寸(期权 delta)来实现的。完美抵消的复制投资组合和期权头寸的组合创建了风险中性的投资组合,该投资组合必须赚取无风险利率,在 无套利 的假设下,将微分方程的期权定价解绑定到 Black-Scholes 模型。
投资组合 H 由抵消复制投资组合和赚取无风险利率的期权组成
完整解释见 推导布莱克-斯科尔斯模型 。
然而,完美的复制投资组合只存在于理论上。假设基础资产遵循扩散过程(几何布朗运动,见鞅和马尔可夫过程)。这个过程提供了无限量的变化,为了保持一个完美的复制投资组合,我们必须随着期权的 delta 变化不断调整我们的头寸。理论上,我们假设 没有交易成本 和 连续交易 ,允许我们根据需要自由调整抵消复制投资组合。在实践中,尽管大多数人认为,除了潜在的流动性问题之外,大部分时间没有套利,但在期权的整个生命周期中,不断调整抵消复制投资组合将积累惊人的交易成本。学者和从业者实施了各种解决方案来寻找维持抵消复制投资组合的最佳频率和策略。在本文中,我想介绍这一研究潮流的创始人,他在 1985 年写了一篇名为带交易成本的期权定价和复制的论文。
利兰(1985)
利兰是第一个研究交易成本对期权价格影响的人。为了将期权价格重新绑定到 Black-Scholes 模型中,他开发了一种针对短期和长期头寸的方差修正方法。Black-Scholes 模型的这一修正方差旨在反映在期权有效期内维持复制投资组合所需的预期交易成本。其中 kappa 是交易成本占交易量的比例(复制投资组合调整或套期保值间隔)…
空头期权头寸的利兰方差
Leland 通过让套期保值区间之间的时间趋近于零,证明了他的方差修正方程,产生了与原始期权具有相同现金流的复制投资组合,在无套利假设下,再次将期权价格绑定到 Black-Scholes 模型。因此,具有这个修改的方差项的期权的 delta 更平坦,这降低了 gamma。直观上,交易成本在买入时会提高基础资产价格,在卖出时会降低基础资产价格,这可以被建模为基础资产价格的波动性高于实际价格。尽管利兰方差允许我们在期权价格模型中包含预期交易成本,但它并没有提到维持对冲的最佳频率或策略。
其他文献
如果你有兴趣了解更多关于对冲频率或策略问题的解决方案,请访问我的网站…
摘要:交易成本违反了布莱克-斯科尔斯模型的一个关键假设。这造成了不完美的复制…
romanthequant.com](https://romanthequant.com/research/)
学术研究为从业者提供了各种有用和不良的解决方案。我目前正在进行一个关于这个主题的文献综述,我有一个非常粗略的参考当前文献的草稿。
参考
利兰,H. (1985 年)。有交易费用的期权定价和复制。《金融杂志》,第 40 卷第 5 期,1283-1301 页。doi:10.2307/2328113
保鲁奇河(2020 年)。市场约束下的最优套期保值。我们的资本工作文件。
怪神经元。当神经科学和人工智能再次相遇。
神经科学和人工智能一直紧密相连,然而,是时候报仇了。
“责怪别人需要时间和精力来提升自己”。
L 让我们来谈谈神经科学。我们能够将一种主要的人工智能算法应用于我们的大脑吗?是的,你没看错!
是什么控制着我们每个人的思想、行为或争论?
的确,神经元。完美运行的无限神经回路。但是,这些神经元如何表现和顺应,以便不犯错误呢?想象你正在跑步,第一次你会摔倒,但一点一点地你会加快步伐,直到你完成第一场比赛。
那么一开始摔倒我们怪谁呢?那个神经元!或者是那个?大脑是如何从我们的错误中学习的?
深度学习的教父杰弗里·希尔顿(Geoffrey Hilton)博士以及其他伟大的特权思想认为,在这种机制背后是一种深度学习核心算法,它在大脑内部以同样的方式运行。
我们称之为“反向传播”。
如果你想了解更多,去 oscargarciaramos.com访问
以防你以前从未听说过这个概念。在很高的层面上,这个概念是基于从错误中学习的想法,并且在做一件特定的事情时变得更好。这将是一种“责怪”我们网络中的神经元连接错误的方式,以便逐步提高期望的输出。
尽管这种说法尚未得到验证,甚至被一些神经科学家斥为“生物学上不可能”,但深度学习技术和神经科学日益交织的事实,唤起了许多“来自过去的幽灵”。但是,在理解我们的大脑方面也面临新的挑战。
就人工智能而言,它将令人惊讶地成为理解我们人类如何学习的奥秘的一种方式。
回去怪他们吧!
根据神经科学学习的教条是基于“一起开火,一起连线”。这是什么意思?当我们想要学习做一件新的事情时,神经元通过突触相互连接,形成一个网络,这个网络慢慢完善,将允许我们学习做一项新的任务,比如跑步。
但是它实际上是如何工作的呢?
神经网络由不同的个体或神经元组成,这些个体或神经元只与它们的邻居进行交互。换句话说,单个神经元只接收来自其上游伙伴的信息,并将该信息委托或传输给其下游伙伴。这些连接的强度或阻力取决于什么?上 【突触重量】 。一个明喻可以是一个有力或无力的握手。正如你所知道的,取决于你握手的对象,并不总是强有力的握手是最理想的。学习的要点是基于“调整”或平衡我们所有握手的重量,这样我们才能得到我们想要的结果。
现在,想象所有的神经元和它们的邻居决定投票选举社区的“市长”。然而,他的对手出来了。谁投票不好,网络如何整体解决?我们不得不“责怪”某人,这样我们才能让结果变得更好。那是我们的“学习过程”。但是为了学习,我们必须“调整”权重,甚至在我们知道首先调整哪些连接之前。
早在 1986 年,希尔顿、大卫·鲁梅尔哈特和罗纳德·威廉姆斯发现,信息通过不同的神经层传播,如果我们观察获得的输出与预期的输出有多远,就有可能用数学方法计算出一个 误差信号 。该信号可以通过神经层传输,每个神经层基于其上层接收新的信号误差。
因此得名*“反向传播”**。*
想象一场足球比赛。小区域有四名球员,最后一名球员失败,不得分。教练会怎么做?。他将从最后一个触球的球员开始,判断他/她没有最终得分“有多内疚”,并将倒退判断谁需要“穿上他的靴子”进行调整,也就是说,他将改变他们的“突触重量”。**
玩家回到该区域,也就是说,我们再次计算同样的问题,然后… Goooaaaal!我们成功了!反向传播调整已经生效,网络将把新的突触权重作为参考,并继续学习。
那么,下一步是什么?
这一切有意义吗?
反向投影结合其他算法已经成为面部识别、自动文本转录甚至人工智能游戏胜利(如围棋或扑克)等领域的主导技术。
然而,至少到目前为止,大脑中类似反向传播信号的想法仍然是猜测。
你可能想知道为什么…
一个最强有力的原因是,一般来说,人工智能网络的配置不像生物网络,因此,我们不能推断它们的反向传播。
基本上,我们的大脑不能回到过去改变突触的重量。生物神经元不是这样工作的。它们可以通过更多的输入或激素或化学递质等其他类型的调节来改变它们的连接,但在不混淆生物神经元的情况下,将相同的物理分支和突触用于直接和反馈信号被认为是“不可能的”。
但是,如果我们将这一理论应用到我们的大脑中,我们可以开发一个新的层次,将生物学习与人工智能联系起来。
你觉得这篇文章有用吗?
欢迎发表评论或分享这篇文章。关注 me 未来岗位。
如果你想了解更多,你可以在oscargarciaramos.com找到我
与 R data.table 进行极快的数据争论
谁有时间用慢代码做数据科学?
照片由 Fotis Fotopoulos 在 Unsplash 上拍摄
更新 2020 年 3 月: 在这里你可以找到一个很有意思的data.table
和dplyr
的对比。
介绍
我最近注意到我写的每个 R 脚本都以library(data.table)
开头。这似乎是我写这篇文章的一个非常有说服力的理由。
你可能已经看到,随着机器学习社区的发展,Python 获得了巨大的人气,因此,熊猫图书馆自动成为许多人的主食。
然而,如果我有选择的话,我肯定更喜欢使用 R data.table 进行相对较大的数据集数据操作、深入探索和特别分析。为什么?因为它太快了,优雅而美丽(抱歉我太热情了!).但是,嘿,处理数据意味着你必须把代码颠倒过来,塑造它,清理它,也许…嗯…一千次,然后你才能真正建立一个机器学习模型。事实上,数据预处理通常占用数据科学项目 80–90%的时间。这就是为什么我不能承受缓慢而低效的代码(作为一名数据专家,我认为任何人都不应该这样)。
所以让我们深入了解什么是data.table
以及为什么许多人成为它的忠实粉丝。
1.那么 data.table 到底是什么?
data.table
包是 r 中data.frame
包的扩展,广泛用于大型数据集的快速聚合、低延迟的列添加/更新/删除、更快的有序连接以及快速的文件读取器。
听起来不错,对吧?你可能觉得很难接,但实际上 a data.table
也是data.frame
的一种。所以请放心,您为data.frame
使用的任何代码也将同样适用于data.table
。但是相信我,一旦你使用了data.table
,你就再也不想使用 base R data.frame
语法了。想知道为什么就继续读下去。
2.Data.table 非常快
从我自己的经验来看,使用快速代码确实可以提高数据分析过程中的思维流程。速度在数据科学项目中也非常重要,在这个项目中,你通常必须快速地将一个想法原型化。
说到速度,data.table
让 Python 和许多其他语言的所有其他包都相形见绌。这个基准显示了这一点,它比较了来自 R、Python 和 Julia 的工具。在一个 50GB 的数据集上进行五次数据操作,data.table
平均只用了 123 秒,而 Spark 用了 381 秒,(py)datatable 用了 712 秒,pandas
由于内存不足无法完成任务。
data.table 包中最强大的函数之一是fread()
,它与read.csv()
类似地导入数据。但它已经过优化,速度快得多。让我们看看这个例子:
require("microbenchmark")
res <- microbenchmark(
read.csv = read.csv(url("[https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data](https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data)"), header=FALSE),
fread = data.table::fread("[https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data](https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data)", header=FALSE),
times = 10)
res
结果将显示,平均而言,fread()
将比read.csv()
函数快 3-4 倍。
3.它直观而优雅
几乎所有使用data.table
的数据操作都是这样的:
来源:https://github.com/Rdatatable/data.table/wiki
因此,您编写的代码将非常一致且易于阅读。让我们以美国人口普查收入数据集为例进行说明:
dt <- fread("[https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data](https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data)", header=FALSE)
names(dt) <- c("age", "workclass", "fnlwgt", "education", "education_num", "marital_status", "occupation", "relationship", "race", "sex", "capital_gain", "capital_loss","hours_per_week", "native_country", "label")
在下面的例子中,我将比较 base R、Python 和 data.table 中的代码,以便您可以轻松地比较它们:
- 计算所有“技术支持”人员的平均*
age
*😗*
> 在 base R 中你大概会写出这样的东西:
*mean(dt[dt$occupation == 'Tech-support', 'age'])*
>在 Python 中:
*np.mean(dt[dt.occupation == 'Tech-support'].age)*
数据表中 >与:
*dt[occupation == 'Tech-support', mean(age)]*
正如你在这个简单的例子中看到的,与 Python 和 base R 相比,data.table
消除了所有重复dt
的冗余。这反过来减少了犯打字错误的机会(记住编码原则 DRY —不要重复自己!)
2.到所有男性工人按职业分类的总年龄*😗
> 在基地 R* 你大概会写:*
*aggregate(age ~ occupation, dt[dt$sex == 'Male', ], sum)*
>在 Python 中:
*dt[dt.sex == 'Male'].groupby('occupation')['age'].sum()*
数据表中与>对比*😗
*dt[sex == 'Male', .(sum(age)), by = occupation]*
by =
术语定义了您希望在哪个(哪些)列上聚合数据。这种data.table
语法一开始可能看起来有点吓人,但是一旦你习惯了,你就再也不会费心输入“groupby(…)”了。
3.为了有条件地修改列中的值,例如将所有技术支持人员的age
增加5
(我知道这是一个愚蠢的例子,但只是为了说明:)。
>在 base R 中,你可能不得不写下这可怕的一行(谁有时间写这么多次dt$
!):
*dt$age[dt$occupation == 'Tech-support'] <- dt$age[dt$occupation == 'Tech-support'] + 5*
>在 Python 中(有几个备选方案同样长):
*mask = dt['occupation'] == 'Tech-support'
dt.loc[mask, 'age'] = dt.loc[mask, 'age'] + 5*
或者使用np.where
:
*dt['age'] = np.where(dt['occupation'] == 'Tech-support', dt.age + 5, dt.age]*
>与数据表中的比较:
*dt[occupation == 'Tech-support', age := age + 5]# and the ifelse function does just as nicely:
dt[, age := ifelse(occupation == 'Tech-support', age + 5, age)]*
这几乎就像一个魔术,不是吗?没有更多繁琐的重复代码,它让你保持干爽。您可能已经注意到了data.table
语法中奇怪的操作符:=
。该操作符用于向现有列分配新值,就像在 Python 中使用参数inplace=True
一样。
4.重命名列在 data.table 中轻而易举。如果我想将occupation
列重命名为job
:
>在 base R 中,您可以写:
*colnames(dt)[which(names(dt) == "occupation")] <- "job"*
>而在 Python 中:
*dt = dt.rename(columns={'occupation': 'job'})*
>相对于数据表:
*setnames(dt, 'occupation', 'job')*
5.如何将函数应用到几列?假设您想将capital_gain
和capital_loss
乘以 1000:
>在底座 R:
*apply(dt[,c('capital_gain', 'capital_loss')], 2, function(x) x*1000)*
>在 Python 中:
*dt[['capital_gain', 'capital_loss']].apply(lambda x : x*1000)*
>相对于数据表:
*dt[, lapply(.SD, function(x) x*1000), .SDcols = c("capital_gain", "capital_loss")]*
您可能会发现 data.table 中的语法有点古怪,但是.SDcols
参数在许多情况下非常方便,data.table 语法的一般形式就是这样保留下来的。
结论:
从上面几个简单的例子可以看出,R data.table
中的代码在很多情况下比 base R 和 Python 中的代码更快、更干净、更高效。data.table
代码的形式非常一致。你只需要记住:
*DT[i, j, by]*
作为补充说明,通过键入和data.table
使用i
设置数据子集甚至允许更快的子集、连接和排序,你可以在这个文档或这个非常有用的备忘单中了解更多信息。
感谢您的阅读。如果你喜欢这篇文章,我会在以后的文章中写更多关于如何与 R 和 Python 进行高级数据辩论的内容。
炽热的 Python AsyncIO 管道
并发高效地处理大量流水线式 web、数据库和微服务请求
约书亚·牛顿在 Unsplash 上的照片
对于内存高效和可读的代码来说,流水线功能非常强大。在这些函数中,一个函数的输出输入下一个函数的输入。一些示例应用包括:
- 跨越不同但相关的数据源的多级 web 刮刀
- 具有数据提取、转换和处理步骤的机器学习管道
- 对大数据集进行逐行操作
使用 Python 的asyncio
库进行并发操作既快速又节省资源,尤其是对于 IO 绑定的任务。
本文将向您展示如何构建您自己的可以非常高效地运行的管道,尤其是如果您要进行大量的 IO 操作,如 web 请求或数据库查询。后续文章将通过提供一个库来抽象出下面显示的大部分底层机制,使之变得更加容易。
同步发电机管道
Python 生成器有一个send()
方法,可以用来在生成器调用yield
时将数据发送到生成器中。把它放入一个无限循环中,你会在你的管道中得到一个不断等待输入的阶段,用它做一些事情,然后发送到下一个阶段。
您可以使用这种基于推送的方法以扇出模式发送到多个其他生成器,因此我们假设我们有一个target
生成器的列表。
当我们从生成器函数创建生成器时,我们必须通过发送None
来初始化它。这使得生成器在功能代码中前进,直到遇到第一个yield
语句。
这里有一个完整的例子。
运行输出:
T2:已初始化参数:你好 T2
T1:已初始化参数:你好 T1
T1:已接收输入:1
T1: T1 发送 1
T2:已接收输入:1
T1:已接收输入:2
T1: T1 发送 2
T2:已接收输入:2
T1:已接收输入:3
T1: T1 发送 3
T2:已接收输入:3
时长:6.01299477
注:
- 我们将所有的输入(第 20–22 行)发送到第一阶段,它会通过管道自动传播
- 这都是同步代码。在发送下一个输入之前,第一个输入完全通过。
- 易于使用断点进行调试
- 我们必须反向构造和链接,因为
gen1
(即gen2
)的目标生成器必须存在,才能作为参数传递给 gen1 的生成器函数。
异步发电机管道
我们可以使用同步 python 生成器等待输入,但是使用协程异步处理输入(由 sleep 函数模拟)。我们通过将处理和发送代码放在async def
内部函数中来实现这一点。
在循环中的每一次迭代中,我们都会得到一个输入值,并生成一个 asyncio 任务。我们在一个全局tasks
列表中跟踪所有产生的任务。
我们的主函数也必须是一个运行在事件循环中的协程。这是由asyncio.run(main())
完成的。注意在 main 中,我们如何使用async.gather()
函数等待所有任务完成。这必须做两次,因为我们分两个阶段提交任务。现在很尴尬。
完整示例:
运行输出:
T2:用参数初始化:你好 T2
T1:用参数初始化:你好 T1
T1:用 T1_inner 创建任务,输入 1。
T1:使用 T1_inner 创建任务,输入 2。
T1:用 T1_inner 创建任务,输入 3。
T1:接收输入:1
T1: T1 发送 1
T2:用 T2_inner 创建任务,输入 1。
T1:接收输入:2
T1: T1 发送 2
T2:用 T2_inner 创建任务,输入 2。
T1:接收输入:3
T1: T1 发送 3
T2:用 T2_inner 创建任务,输入 3。T2:接收到的输入:1
T2:接收到的输入:2
T2:接收到的输入:3
持续时间:2.00000000001
注:
- 由于异步睡眠,运行速度更快
- 需要一个事件循环
- 很难知道什么时候所有的任务都完成了
- 关于
send
函数的竞争条件的一些问题
等待救援的队伍
asyncio.Queue
类也有一个方便的task_done()
方法。队列对象跟踪get()
和task_done()
被调用的次数。如果相同的次数,它假定从队列中取出的所有项目也已经被处理,并且它允许自己被加入(如果队列是空的)。这允许我们按顺序调用await on
q.join()
来了解一个阶段是否完成,并且我们可以避免多次调用asyncio.gather()
。
运行输出:
T2:用参数初始化:你好 T2
T1:用参数初始化:你好 T1
T1:用 T1_inner 创建任务,输入 1。
T1:用 T1_inner 创建任务,输入 2。
T1:用 T1_inner 创建任务,输入 3。
T1:接收输入:1
T1:接收输入:2
T1:接收输入:3
T1: T1 发送 1
T1: T1 发送 2
T1: T1 发送 3
T2:用 T2 _ 内创建任务,输入 1。
T2:用 T2_inner 创建任务,输入 2。
T2:用 T2_inner 创建任务,输入 3。
T2:已接收输入:1
T2:已接收输入:2
T2:已接收输入:3
持续时间:2.00000000005
注意:
input_q.task_done()
是调用内部函数的结尾- 我们没有把
send()
变成发电机,而是把put()
放在一个队列上 - 我们只需要收集一次任务
结论
我们可以通过使用 python 生成器来创建简单的同步管道。通过交换到 asyncio 队列和协程,我们可以拥有非常高效的 io 管道,并保持对我们生成的任务的控制。