TowardsDataScience 博客中文翻译 2019(四百一十三)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

超参数优化的随机搜索与网格搜索

原文:https://towardsdatascience.com/random-search-vs-grid-search-for-hyperparameter-optimization-345e1422899d?source=collection_archive---------7-----------------------

网格搜索是一种搜索技术,当涉及到超参数优化时,它已被广泛用于许多机器学习研究中。在探索搜索空间的其他方法中,一个有趣的替代方法是通过使用随机搜索技术来依赖随机性。

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

Photo by Andrew Ridley on Unsplash

介绍

机器学习研究人员想要解决的理想问题是承认一个凸目标函数,不需要超参数也不需要松弛,但足够强大,可以在看不见的数据上提供最小的误差。然而,超参数是一种必要的邪恶,它有助于将优化任务引导到搜索空间中的一个区域,该区域将对数据进行最大程度的概括。你可能听说过的一个超参数的例子是神经网络中的学习率。

再深入一点,以正则化线性模型为例。正则项被结合到目标函数中,以便实施确定的惩罚。两种众所周知的方法是对参数向量施加ℓ1-norm 和ℓ2-norm,以分别执行特征选择(套索)和控制模型的复杂性(脊)。

然而,实施处罚本身不足以充分利用正规化的好处。它们的影响需要用受控参数来优化,该受控参数被称为超参数,因为它需要在训练过程之前被设置。对于我之前提到的例子,只需要一个超参数;通常情况下,你会不得不处理一个以上的问题。

除了手动搜索超参数的良好候选值,优化超参数的最基本和最直接的方法是网格搜索(GS)技术。基本上,每个超参数的候选值列表被定义和评估。“网格”这个名称来源于这样一个事实,即所有需要的超参数中的所有可能的候选组合成一种网格。然后选择产生最佳性能的组合,优选在验证集中评估。

例如,假设α和β是将使用 GS 优化的超参数。基于一些假设的知识,我们可以猜测α和β的候选值分别为[1,2,3]和[20,60,80]。因此,我们可以通过以下方式设置值及其组合的网格:

 **α   
        1      2      3
   20** (1,20) (2,20) (3,20) **β  60** (1,60) (2,60) (3,60) **80** (1,80) (2,80) (3,80)

从我们刚刚建立的网格中,评估每个组合,并选择产生最佳性能的组合。在这个过程之后,也许我们可以发现(3,60)是我们问题的最佳选择。另一方面,全局最小值可能位于(2.57,58)。

然而,如果存在许多超参数并且搜索空间巨大,则该任务开始变得非常耗时,更不用说必须事先提供候选列表*。作为 GS 的替代,你可以通过随机搜索 (RS)技术来依赖随机性。*

在文献中,Bergstra & Bengio [1]在他们的论文中表明,在几个数据集上有几个学习算法的情况下,RS 比 GS 更有趣。如果你还没有读这篇论文,花点时间读读,它真的很有趣,有更多的细节需要把握。

虽然 RS 很容易理解和实现,但是可以通过使用这个 python 库来使用它。除此之外,这个库还提供了我们在这篇文章中没有提到的其他功能,比如并行运行和提供其他相关算法。试试看。

为了应用 RS,需要预先指定以下组件: (i) 函数,用于衡量候选集的好坏;(二)搜索空间;(三)试验次数。

所选择的候选者是在试验次数内评估目标函数的最佳输出的候选者。请注意,候选集将在运行时选择,不需要像 GS 要求的那样事先指定。**

最后,我必须提到还有其他更高级的超参数优化方法,比如贝叶斯优化。如果你的机器学习管道的下一步是超参数优化,去看看他们,但先给 GS 和 RS 一个尝试,也许你很适合使用他们。😃

密码

我会按照我的 jupyter 笔记本,使事情更容易显示。您可以随意运行它或者自己实现代码。请记住,一些代码片段使用在前面的代码片段中实现的代码,因此出现的顺序很重要。

这篇文章中提到的所有文件都在我的 GitHub 中。查看 本回购 本回购出!**

设置环境

假设你熟悉 Anaconda ,我已经准备了一个 yml 文件,这样你就可以像我一样快速设置环境,甚至是相同的库版本。这是文件的内容。

**name: grid-vs-random-search
channels:
 — conda-forge
dependencies:
 — python=3.6.9
 — numpy=1.16.5
 — matplotlib=3.1.1
 — jupyter=1.0.0
 — ipython=7.8.0
 — hyperopt=0.1.2**

一旦有了文件,就执行下面的命令来创建环境并安装所有必需的依赖项。

****$ conda env create -f environment.yml****

安装完成后激活环境。

****$ conda activate grid-vs-random-search****

一切就绪!让我们深入一些 python 代码。

配置绘图

如果你使用的是 jupyter 笔记本,配置 matplotlib 显示内嵌图像。否则,只进行导入。

Configuring plotting

定义成本函数

让我们定义一个非常怪异的非凸函数作为我们的代价函数。以下是我挑选的:

**ƒ(x) = 675 + (x-15)² + x² cos(xπ)**

然后我们可以为它定义一个 lambda,尽管常规函数也是可能的。

Defining the cost function

绘制成本函数

对我选择的函数的形状感到好奇吗?下面是非常漂亮地绘制它的代码。

Plotting the cost function

现在我展示我们的成本函数。你可以看到,有许多局部最小值使算法更难找到全局最小值,但一个好的方面是我们可以将其可视化。通常,你将不得不处理不太清楚的函数,更糟糕的是,在多维空间中。这就是为什么我们需要好的搜索算法。请注意,x 轴代表候选超参数,y 轴代表成本,因此越接近零越好。

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

Our weird cost function

定义一些助手代码

我们需要更多的辅助代码。以下是我是如何实现它们的——我添加了一些注释,以便更容易理解。花点时间去理解这里要做什么。

Defining some helper code

现在一切都准备好了,让我们做一些实验。正如您在代码中看到的,GS 的候选值将是根据在我们的区间上均匀分布的试验次数的值。另一方面,对于 RS,将按照随机搜索策略动态选择候选对象。运行 GS 和 RS 特定次数的试验后,将打印获胜策略的名称。

实验— 10 次试验

在我们的预算中有 10 个试验,让我们看看哪个搜索策略以最低的成本给我们带来价值。

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

Grid Search results in 10 trials

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

Random Search results in 10 trials

**Result (10 trials): Random Search is the winner!**

实验— 50 次试验

在我们的预算中有 50 次试验,让我们看看哪种搜索策略能以最低的成本给我们带来价值。

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

Grid Search results in 50 trials

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

Random Search results in 50 trials

**Result (50 trials): Random Search is the winner!**

实验— 100 次试验

在我们的预算中有 100 次试验,让我们看看哪种搜索策略能以最低的成本给我们带来价值。

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

Grid Search results in 100 trials

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

Random Search results in 100 trials

**Result (100 trials): Random Search is the winner!**

实验——500 次试验

在我们的预算中有 500 次试验,让我们看看哪种搜索策略能以最低的成本给我们带来价值。

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

Grid Search results in 500 trials

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

Random Search results in 500 trials

**Result (500 trials): Random Search is the winner!**

正如你在所有实验中看到的,RS 能够找到比 GS 更好的值。随着试验次数的增加,两种策略之间的差异变得越来越小,但是 RS 提供的微小改进对于达到您所期望的性能可能是至关重要的。

运行批量实验

有人可能会说只有四个实验可能是不可靠的,我完全同意,特别是因为我们正在处理随机的东西。那些实验只是为了给我们一些可视化的提示。因此,让我们批量执行实验,并计算每个策略赢了多少次。每批的实验次数就是试验次数。此外,我们将合计所选值的成本,以获得一些额外的见解。注意,因为 GS 是确定性的,所以对于相同次数的尝试,它将总是返回相同的结果;所以我们只测试 RS。

下面是运行这个实验的代码。

Running batch experiments

结果将以下列结构呈现:

**<execution counter>
Grid Search:   <victory counter>     (<cost sum>)
Random Search: <victory counter>     (<cost sum>)**

这是最终的结果:

**10
Grid Search:	5	(2935.44)
Random Search:	5	(3692.77)50
Grid Search:	16	(8119.40)
Random Search:	34	(6885.77)100
Grid Search:	8	(17449.96)
Random Search:	92	(9118.30)500
Grid Search:	221	(17441.61)
Random Search:	279	(20750.24)**

很酷的结果,不是吗?他们提出了以下见解:

  • 10-试验实验:显然,如果试验次数少,这两种策略都很难,我们可以通过计算平均成本来看出这一点。在实际场景中,尽可能多地设置试验次数是一个好主意。
  • 500 个试验的实验:如果试验的数量足够覆盖 GS 的整个搜索空间,两种策略变得更加等价,正如我们在图中可以看到的。尽管 RS 的成本总和高于 GS,但 RS 给出的最佳值比 GS 多很多倍。
  • 50 次试验和 100 次试验:在这些试验中,RS 表现出了更好的性能,不仅因为它比 GS 赢得了更多的次数,还因为它的成本总和更低。这表明,如果试验数量相当大,但不足以覆盖 GS 的整个搜索空间,那么使用 RS 可能比 GS 更有意义。

结束语

在本文中,我们设置并运行了实验来比较网格搜索和随机搜索这两种优化超参数的搜索策略。虽然我们的实验很简单,但它们提供了一些关于不同场景中策略行为的见解。根据我们所看到的一切,我会让您了解一些要点:

  1. 说到研究,很难说某样东西比另一样好。这个案例也不例外。因此,我建议在优化超参数时尝试这两种策略,可能的话结合使用这两种策略。
  2. 如果你有很多超参数,搜索空间很尴尬,可以考虑从 rs 开始。找到好的价值后,检查成本是否围绕它们有显著变化。如果是这样,您可以使用 GS 进行微调。
  3. 独立地,如果你在研究中使用了 GS 或 RS 并得到了好的结果,花些时间研究你得到的价值,也就是说不要简单地接受它们。也许这些价值观会让你对你试图解决的问题有新的见解,并可能把你的研究引向新的、更有趣的道路。

今天到此为止。感谢阅读!🙂

参考

[1] J. Bergstra,Y. Bengio,随机搜索超参数优化 (2012),机器学习研究杂志。

对我第一次 ML 部署的随想

原文:https://towardsdatascience.com/random-thoughts-on-my-first-ml-deployment-8e8c89df047f?source=collection_archive---------12-----------------------

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

Photo by Coen van de Broek on Unsplash

六个月前我不知道的五件事,在接下来的几个月里最好不要忘记

简单介绍一下背景:我目前在工作,这是一家快速发展的中型公司,在开发了一个强大且广泛使用的产品后,决定开始利用这些年来产生的数据为最终用户带来一些价值。数据科学团队在这一探索的开始并不是非常结构化,六个月后的今天,即使你可以开始注意到一些变化,这些变化都是自然试错过程的结果。因此,对于在结构化公司工作的更有经验的数据科学家来说,以下几点可能是显而易见的,这些结构化公司拥有模型投入生产的良好记录。但是,如果我想到六个月前的我,我可能会对阅读这样的帖子感兴趣,以避免浪费大量时间和 CPU 能力来训练无用的模型或寻找特定的模型,这些模型在几周前训练过,但在一堆无用的其他模型中丢失,主要是因为我保存所有 Jupyter 笔记本的文件夹中混乱不堪。

1.关注产品,而不仅仅是性能

在这几个月开发的所有项目的早期阶段,我专注于提高纸面上的性能,设计最复杂和性能最好的功能,只是后来发现这些功能并不实时可用,或者检索它们的过程成本太高,以至于不值得努力提高性能。举例来说,一个列表在发布后的头几个小时内收到的互动数量是一个很好的指标,可以用来判断它是不是一个骗局。然而,如果模型的目标是在上传他们的清单后的第一分钟内检测骗子,这个功能几乎没有用。

另一个重要的建议是尽快用来自产品最终使用场景的实时数据来测试模型。

快速发现开发的模型是不可靠的,这要比花几个月的时间研究某个东西,当它已经运行时才发现它是多么的无用要好的多。

我已经在这里和那里写了这个主题,我不会重写整个故事,但在多年期间收集的数据集中,所有样本都遵循相同的分布并不明显:处理这种复杂性使得处理真实数据比处理类似 Kaggle 的数据集更具挑战性。不要误解我的意思:它们很酷,最重要的是,它们是想尝试新技术的数据科学家们唯一可以免费获得的资源。唯一的误解是,它们远远不能很好地代表真实世界的数据集,这往往需要大量的努力(真的,很多)才能得到可用的样本,同时消除不良值和离群值。前一段时间,我读到一位高级数据科学家说,他越高级,他发展的技能就越多,主要是数据集清理和准备。我开始理解他的话了…

2.拥有计算机科学背景是关键

一个机器学习模型,不管它会变得多么复杂和深刻,最终都是一个软件人工制品,可能会作为一个 Web API 暴露在一个已经存在的基础设施之上。拥有计算机科学背景,或者至少对这些主题有扎实的理解,对于构建一个可以在持续数月的研究阶段后快速部署的数据产品是至关重要的。

根据经验:没有 CS 背景的人开发的模型越多,在生产中部署它就越困难,可能不得不降低性能或调整特性以适应最终的架构。

在我们的业务阶段,能够在训练模型的同时勾画出客户机-服务器架构可能比拥有一个专注于 ML 的博士学位更重要。当然,这是一个大胆的句子,可能它已经不再有效了(新的结构、新的项目、新的挑战);但在数据团队的早期阶段,随着尽快带来一些切实价值的严格要求,能够有一点点 CS 愿景是将模型从 Jupyter 笔记本中取出并在几周内(而不是几个月内)提供给用户的基础。

3.部署 ML 不是黑魔法

大约一年前,当我参加最后一次大学考试时,我对自己的理论 DS/ML 技能非常自信,渴望获得一些真实世界数据的实践经验,而我完全没有意识到,甚至有点害怕构建由这种复杂技术支持的实际数据产品。Jupyter 笔记本之后还有生活吗?

几个月后,我发现问题在于我认为在一个已部署的 ML 模型背后有谁知道是什么样的技术复杂性。一旦我有了要实际部署的东西,我对该领域研究得越多(再次,参见第 1 点),我就越注意到:a)如果有许多关于这种非常具体的方法的故事和经验,允许在 ImageNet 上增加 0.001%的精确度,那么关于如何实际向世界展示 ML 模型的例子和指南就非常少;b)最终,模型只是计算机函数,通常用 Python 编写,这种技术已经被数百万用户部署和使用了多年。我们公司学到的一个很好的经验是让数据科学家尽可能接近高级工程师,即使他们可能不太了解机器学习,但在构建可靠和健壮的软件产品方面有很多经验。

Python 脚本就是 Python 脚本,不管它做什么。

4.给 Jupyter 笔记本一个结构

我现在不会谈论这个问题的细节,但是在几周内每天工作 8 小时后,试验和草图想法的数量开始增加。Jupyter 笔记本,以及它们可能固有的所有问题,是每个数据科学项目可能非常长的研究阶段的事实上的标准。

一个项目越长越复杂,就要花费越多的时间,用几周前训练的略有不同的数据集来寻找特定的模型。

如果仔细跟踪每一个测试和实验可能有点大材小用,而且 Jupyter 笔记本的格式本身并不容易进行版本控制,那么在过去的几个月里,开始给文件夹和文件提供一个结构已经节省了我很多时间。

在我的日常工作中,笔记本主要可以分为四类:

  • 探索:初步数据集分析,包括总体测量、绘图和图表;
  • 清理:数据集被清理,异常值被检测并可能被移除,一些初始复杂特征被设计;
  • 实验性:模型(甚至每个笔记本不止一个算法)被训练和测试,更复杂的想法被尝试(每个笔记本不超过一个);
  • 部署:完整的管道,从数据集清理到预测。理想情况下,它可以从头到尾提供模型和预测。

创建的每个 Jupyter 笔记本必须在文件名中包含这些关键字之一,并带有实际文件内容的简要描述。一旦一个笔记本变得太复杂或者开始超出最初的范围,它会被重新排序一点,然后创建一个新的,可能会在之前的一些结果的基础上开始。另一方面:每个数据集的名称必须包含一个日期,以及对所包含特性的简要说明。

当我开始使用这种结构时——不幸的是在第一次使用后的几个月。fit()我在公司的办公室运行——我的效率大大提高了,并且很容易回到几周前训练的模型,或者使用更新的数据集或新功能重新运行相同的管道。

5.从容做

最后,而且主要是对未来的我的一个忠告,但是谁知道呢:做事是需要时间的,越早明白这一点越好。单个项目需要多次迭代,最重要的是,构建健壮可靠的软件是一个长期的过程,而不是冲刺。尽快用活数据测试模型,但是然后离线迭代,尝试不同的方法。

大多数复杂的解决方案并不总是给出更好的结果,但是构建超级复杂的模型可能是你确定这一点的唯一方法。

如果每个项目都需要结构和期限,那么 ML 研究,即使是在强烈关注产品的情况下完成的,也需要时间来发展和成熟:在无用的分支中浪费时间,只是为了发现它们有多无用,并可能在未来做得更好,这是该过程的基本部分。

随机连线神经网络

原文:https://towardsdatascience.com/randomly-wired-neural-networks-92098dbd5175?source=collection_archive---------14-----------------------

这篇博文将简要解释什么是神经架构搜索,以及它如何帮助你用数据集实现更好的建模结果。下面是一个论点,说明为什么你应该忽略高级算法,而使用一个简单得多的算法,随机连线神经网络。该算法使用图论和网络科学中的随机图形生成算法,将每个节点上的相同计算固定为 3×3 可分离卷积,并专注于节点之间的数据流(概念上类似于 ResNet 和 DenseNet 等架构)。

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

Exploring Randomly Wired Neural Networks for Image Recognition by Saining Xe, Alexander Kirillov, Ross Girshick, Kaiming He

神经结构搜索(NAS)描述了从特征工程→神经网络→自动神经网络设计的范式转变。有了卷积、池化和批处理规范化等构建模块,还不清楚它们是如何组合在一起的。你可以想象把这些积木组装起来,形成一个总的架构;功能强大,足以在图像分类、对象定位、语义分割和图像生成等各种应用中提取有用的特征。然而,在深度学习的当前状态下,你可能会更好地找到一个专门的架构。即使在影像分类问题的子集中,针对数据集进一步专门化的架构也有可能获得最佳结果。

那么我们如何为我们的数据集找到神经架构呢?

通常,NAS 算法和研究论文要么关注宏观架构,要么关注微观架构,有时两者都关注(例如 CoDeepNEAT)。微结构设计描述了设计适合宏观结构的数据流和计算模块的技术。设计宏观结构包括一些决策,例如这些模块化构建模块重复多少次,以及这些模块应该有多少种变化。宏架构设计位于超参数优化和 NAS 之间的灰色地带,需要做出决策,例如何时应用空间下采样以及阶段与阶段之间的特征映射数量,阶段描述一组保持相同空间分辨率(有时还有特征维度)的块。

几乎所有流行的 NAS 论文都是手动设计宏观架构。他们部署贝叶斯优化、进化算法、强化学习或可区分架构搜索来找到要集成到宏观框架中的微观/模块化模块。枚举所有微结构在计算上是难以处理的,因此在搜索算法上强加了许多先验。这些先验通常被编码到算法可用的离散搜索空间中。例如,在 NASNet 空间中,每个节点具有固定的输入度 2,并且在微架构中有 5 个这样的节点。

搜索空间中的这些先验/偏差支持一种假设,即基于不同操作的利用来优化配置神经架构。这种假设预测,类似于输入节点通过 3×3 卷积,然后与相同输入的零填充 2×2 最大池处理的结果连接,将是最成功的。显然,这个假设设想了一个更复杂的操作组合,然而我认为这个简单的例子传达了这个想法。

NAS 搜索空间中的这一先验反映了初始网络设计相对于 ResNet 或 DenseNet 设计的偏好。Inception / GoogLeNet 将输入块传递给单独的处理块,如 3x3 最大池和 1x1、3x3 和 5x5 卷积。然后,来自这些块的所有输出或者按元素相加,或者沿着特征轴连接,以形成微单元的输出。

ResNet 和 DenseNets 专注于处理操作之间的布线或数据流。

ResNet 使用简单的布线模式,实现了图像分类准确性的突破,并允许训练更深层次的神经网络。ResNet“跳过连接”从前一层(或微架构块)(l-1)获取输入,并将其向前发送到(l+1)。DenseNet 使用更密集的布线模式,将所有先前的输入发送到下一层。例如,层(l+4)将接收输入(l、l+1、l+2 和 l+3)。

随机连线神经网络

这篇文章的论点是,在神经架构搜索的背景下,连线>连接不同的操作。随机连线的神经网络对每个节点使用相同的运算,即 3×3 深度方向可分离卷积。这些网络不是专注于通过巧妙的路径连接不同滤波器大小的卷积等操作,而是在整个微体系结构中随机连接相同的操作。作者设计了随机有线网络的宏观结构。这包括对要素地图进行空间缩减采样的阶段数以及每个阶段应包含多少个结点等决策。这些网络最终看起来如下图所示:

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

Exploring Randomly Wired Neural Networks for Image Recognition by Saining Xe, Alexander Kirillov, Ross Girshick, Kaiming He

这些网络是使用随机图算法快速生成的,该算法使用试探法来控制整个网络中节点度(连接数)的分布。最有趣的是,其中一种算法(WS 算法)在网络科学中被用来模拟小世界网络。这描述了我们在社交网络中平均相距 6 跳的社会现象。这篇论文引用了神经科学对这种结构的启发,强调了线虫(蠕虫)的 300 个神经元连接体也具有这种小世界结构。

以下是这些网络与 NAS 方法相比的 ImageNet 性能,NAS 方法需要巨大的计算量:

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

如果你想了解随机连线神经网络论文的完整解释,以及随机图形如何转换为 DAG / CNN,请查看下面的视频!

感谢你阅读这篇关于随机连线神经网络的文章!我希望这能让你相信神经网络的连接是 NAS 未来不可或缺的一部分。此外,我希望您能采用这种算法来加速您的数据集的架构搜索并报告结果!

随机连线神经网络和最先进的精确度?是的,它有效。

原文:https://towardsdatascience.com/randomly-wired-neural-networks-and-state-of-the-art-accuracy-yes-it-works-9fb3cedc8059?source=collection_archive---------7-----------------------

如何设计出最好的卷积神经网络(CNN)?

想获得灵感?快来加入我的 超级行情快讯 。😎

尽管深度学习已经存在好几年了,但这仍然是一个没有答案的问题。

设计一个好的神经网络的大部分困难源于它们仍然是黑盒的事实。我们对它们是如何工作的有一些高层次的想法,但是我们并不真正了解它们是如何实现它们所做的结果的。

CNN 的一些线索

我们可以从一些线索入手。最近的研究为我们提供了一些 CNN 准确性提高的具体证据:

  • 提高图像分辨率
  • 增加网络深度
  • 增加网络宽度
  • 添加跳过连接(无论是密集连接还是剩余连接)

从直观的角度来看,深度学习的所有这些补充都是有意义的。提高图像分辨率可为网络提供更多数据。增加宽度和深度给了网络更多的参数。并且增加跳跃连接会增加网络的复杂性,从而增加表示能力。

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

Dense connections (left, DenseNet) and skip connections with a wide network (right, ResNeXt). Sources are linked.

为了发现更强大的网络,谷歌人工智能的研究团队开发了一种技术,让算法搜索好的网络。这被称为神经架构搜索 (NAS)。

神经结构搜索

NAS 是搜索寻找最佳 神经网络架构的算法。大多数 NAS 算法的工作原理非常相似。

首先定义一组可能用于我们网络的“构建块”。然后尝试通过将这些块的不同组合放在一起来训练网络。通过这种反复试验,NAS 算法将最终找出哪些数据块和哪些配置工作得最好。

事实证明,这种方法效果很好,达到了最先进的精度。它还发现了一些看起来非常奇怪的架构,你可以从下面的官方文件中看到:

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

NASNet blocks discovered by the NAS algorithm. Source

NAS 的伟大之处在于,我们可以看到一些神经网络体系结构,否则我们可能根本看不到。

然而,它也有自己的局限性。由于我们是从一组固定的数据块中进行采样,因此我们不会发现任何新的数据块。跳过连接的情况也是如此:NASNet 只允许跳过 1 个下采样级别的连接,但是如果其他类型的连接也可以工作呢?

脸书的人工智能研究团队通过尝试随机连线神经网络,在 NAS 上进行了新的尝试。直觉是,如果体系结构搜索的一般思想对固定的块和连接工作良好,也许用更宽的搜索空间(即随机连接)运行它将导致一些未探索的配置。

随机连线神经网络

由于该论文的作者希望特别关注线路即神经网络的连接,他们对网络结构做了一些限制:

  • 输入总是大小为 224x224 的图像
  • 这些区块总是一个雷鲁-conv-巴特诺姆三联体。三元组中的卷积始终是一个来自的 3×3 可分卷积,但除外。
  • 多个张量的聚合(例如当融合与其他张量的跳过连接时)总是以相同的方式完成——通过加权求和。这些权重是可以学习的,并且总是正的。
  • 网络的总是保持不变。多重卷积块的一般 CNN 结构,随后是下采样,反复重复直到最终的 softmax 分类器,已经成为最先进的网络设计中的标准。在这些研究实验中也采用了这种范式。

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

General structure of state-of-the-art CNNs, also adapted for this research. Source

224x224 的输入大小在 ImageNet 竞赛中是非常标准的,ImageNet 数据集用于对其他手工制作的网络以及 NAS 生成的网络进行基准测试。ReLU-Conv-BatchNorm 的三联体阻滞也很常见,并已被广泛证明在整个深层 CNN 中重复时可提供最先进的结果。

张量的聚合方式是一个小小的转变。大多数最先进的网络都是直接相加或无权重连接,但这是一个不应该对性能产生太大影响的小加法。上表所示的 CNN 分级设计也已成为 ResNets、DenseNets 和 NASNets 中使用的首选网络结构。

注意这并不完全是一个“随机神经网络”。没有完全从零开始的随机化。相反,CNN 设计的单个组件,即布线,在其他组件保持固定的情况下进行探索。

这是作者试图向读者传达的一个重要观点。我们还没有做完全随机的神经网络。但是我们开始对组件搜索空间做一些深入的探索——一步一个脚印。

有了这些约束,各种经典随机图模型被用来生成网络的随机布线。**

我说的随机是指随机

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

Some of the randomly wired networks. Source

随机网络打开了深度学习探索的大门

本研究的意义在于其主要的探索性思想:扩展 NAS 算法的搜索空间,以发现新的、更好的网络设计。虽然研究人员自己已经发现了一些伟大的设计,但手动搜索整个搜索空间实际上是不可行的。

这也延伸到另一点:如果我们正在扩大我们的搜索空间,我们将需要一个算法,在这种情况下,我们的网络生成器,要真正擅长搜索。它必须知道要寻找什么,或者至少有一些通过设计向它移动的趋势,就像梯度下降工作这样的优化算法一样。

架构搜索是深度学习研究的下一个前沿。它允许我们使用算法,而不是试错法来发现最佳架构。

目前,修复一些网络组件同时搜索其他组件(在本例中为布线)是有意义的。这就把问题简化成了一件小事,更容易处理。NAS 算法应该有一定程度的随机性,因为这是我们发现真正新颖的架构的唯一方法。

下一步当然是进一步扩展搜索空间和我们搜索算法的随机性。这意味着扩展到越来越多的网络组件,直到整个事情都是用算法设计的。

当我们放开 NAS 时会发生什么?它会选择像 2x4 这样的非正方形卷积吗?它提议使用反馈回路吗?网络变得更简单还是更复杂?

神经结构搜索提出了一个令人兴奋的新的研究领域。希望让搜索算法变得宽松,成为一种利用随机化的方式,为我们的优势,发现创造性的和以前从未想过的架构。

喜欢学习?

推特上关注我,我会在那里发布所有最新最棒的人工智能、技术和科学!也在 LinkedIn 上和我联系吧!

对特征进行排序,现在再次排序

原文:https://towardsdatascience.com/rank-the-features-now-rank-again-4dafd8cde3c8?source=collection_archive---------10-----------------------

机器学习和生物标记

40 种排列你的特征的方法和我的经验使用少量观察选择生物标记候选物(特征)

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

在这里,我讨论了以 40 种方式对特征进行排序的方法,以及一个不稳定模型的困难情况,这是由于数据中的变量比样本多得多。

作为一个额外收获,你将了解一点应用于癌症生物学的领域,并了解该领域数据集的特征。我解释了一个蛋白质组学数据集,我们用它来验证在发现蛋白质组学中寻找生物标记候选物的方法。

你可以在这里> 找到我的研究文章 <。
和我在这里的论文:赫伯勒,h .,&明希姆,R. (2019)。生物学中的计算方法:癌症生物标记、蛋白质网络和横向基因转移。圣保罗大学,圣卡洛斯。
http://www . teses . USP . br/teses/disponiveis/55/55134/TDE-15102019-145225/

概述

您可以阅读整篇文章或跳到以下部分:

  • 简介 : 我创建基于排名的稳定性管道的原因
  • 发现特征的重要性 : 小定义
  • 排名方法 : 对你的特征进行排名的方法
  • 稳定管道 : 了解稳定方法&特点
  • 验证和结果 : 通过候选生物标志物的使用案例了解稳定性管道结果

生物标志物的发现对癌症研究非常重要。例如,我们可以用它们来指导药物发现的实验、新的治疗方法和可以识别是否存在肿瘤或其类型的测试。

收集唾液来鉴别癌症比活组织切片检查的侵入性要小得多。

非侵入性测试通常是优选的,并且可以导致更快的诊断,因为它更容易更频繁地执行。例如,如果他们家族中有口腔癌史,或者有增加患癌症几率的习惯,他们可以每年检测唾液。人们试图避免或推迟侵入性或复杂的检查。

我们唾液中不同数量的蛋白质可以预测结果。

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

Figure 1 — I call this The Proteomics Paradox.Before) Proteomics data with many more features than observations; applying feature selection is a problem because we do not have enough observations. After) the result of a feature selection process on this data set; because we need to. We use this smaller set of features on follow-up experiments so we can increase the number of observations, being able to validate the candidate features with more statistical power (see Figure 2). We cannot guarantee they will perform well in follow-up experiments; yet, a decision needs to be made in the first step. With the larger number of observations, we test if the selected features can discriminate the classes. With a good accuracy, we celebrate; with a bad one, we can only test the importance of these features and report if they are good candidates or not, based on the large sample. The search restart removing the bad ones.

介绍

想象一下,如果数据中的一个小变化导致了非常不同的特征等级。

在大样本的情况下,你会认为至少排名是相似的。如果样本很小,而且有很多特征,那就不能指望了。

我们不能相信这里的结果。我们的样本太小了。然而,我们需要决定什么是我们问题的最佳特征。

如果我们对所有观察运行一个排序器,然后删除一个观察并再次运行排序器,我们将得到两个不同的等级。我们选择哪一个?

如果我对所有观察值使用 T 检验、Wilcoxon 检验或 Kruskal Wallis 检验,删除一个观察值并再次运行,我们将得到不同的 p 值。我们信任哪一个?

查看图 1 并阅读图例可以更好地理解它。

因为我们的样本太小,没有正确答案!

我们解决问题的方式是利用我们所拥有的,想象结果并采取行动。我们不可能有任何统计上的自信,但我们有能力掌握和理解我们的数据。

在当前的生物标志物发现管道中,由于技术的限制,我们从许多特征和少量观察(小样本)开始。

我们先选择一小组特征,然后在后续实验中增加样本量。下图说明了这些步骤。*【分析物】*是我们的特征,“*样本”*是我们的观察。在初始阶段,我们有许多特征和一些观察,这对于运行任何机器学习或统计方法来说都是一个可怕的场景。

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

Figure 2 — Example of a biomarker discovery process. In the first phases, we cannot identify sets of features to discriminate the classes with statistical confidence. Yet, we need to choose a set of features that will be used in the furthers phases, where, because of the smaller number of features, we can increase the number of samples — consequence of limitations of current Proteomics technologies. Source of the image: Del Campo, Marta & Jongbloed, Wesley & Twaalfhoven, Harry & Veerhuis, Robert & Blankenstein, Marinus & Teunissen, Charlotte. (2015). Facilitating the Validation of Novel Protein Biomarkers for Dementia: An Optimal Workflow for the Development of Sandwich Immunoassays. Frontiers in Neurology. 6.

在选择了最佳特性之后,我们可以在下一阶段增加观察的数量,例如在图中所示的验证和确认阶段。

这里的错误决定是有代价的:

如果我们最初选择了一组不好的特性,这意味着我们在几个月或几年的研究上浪费了数千美元!我们至少证明了他们不是好的候选人。

现在,这一挑战又增加了一个事实,即这些特征本质上是相互关联的。

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

Figure 3 — Example of correlation between features in Discovery Proteomics data. Features (proteins) CST1, CST2 and CST4 are correlated and found in similar quantities in the biological samples. Note: PYGM, ENO1, ALB and ADH1 are highly correlated because they were added to the samples, as I explain later in this article.

我们体内蛋白质的数量是相互依赖的。它们相互作用来执行过程,就像在一个公司里一样,并影响其他蛋白质的产生;同样,员工可以影响公司的成功和其他因素,并因此影响公司将雇佣多少新员工。

正如您将在本文中看到的,像 SVM-RFE 这样的方法可能会给高度相关的特征不同的权重,这意味着相似的蛋白质会出现在排序中的遥远位置,从而导致错误的结论和决定。

为了解决这个问题,我使用不同的方法和交叉验证对这些特性进行了一次又一次的排序,并比较了它们的得分。我最终得到一个高评分特性的列表,以及通过跟踪特性的权重和等级位置计算出的稳定性分数

军衔之间有许多不同。一种方法会说蛋白质 A 是最好的,而另一种方法会说它是最差的。

有了平均权重,并且知道当数据改变时以及在不同的等级中特征如何表现,我就可以在一定程度上有把握地决定什么是最重要的。

通过在生物样品中添加真实标记,我们验证了我们的方法在蛋白质组学中寻找潜在生物标记候选物的相关性。

我在这里引用的作品是我在圣保罗大学读博士期间,与 巴西生物科学国家实验室、 等机构合作完成的更大项目的一部分。

GitHub 资源库:【https://github.com/heberleh/proteins-stability】

发现特征的重要性

有许多方法可以找到作为数字的特征相关性,并选择一组候选特征。我在这里解释了 top-n selection 方法以及对特性进行加权和排序的流行方法。

我对我的特征有 40 个不同的观点(等级)。

统计方法和不同分类器组合到 6 种排序方法的乘积。

前 N 名功能

选择特征以创建模型的一种常见方法是从等级中选择前 N 名。 Scikit-Learn 例如,有SelectPercentileSelectKBest分别根据最高分的百分比和 k 个最高分来选择特性。

特征的重要性

分数或权重是衡量重要性的标准。例如统计测试中的 p 值和线性回归方程中的斜率(系数)。为了创建等级,我们使用这些数字对特征进行排序。

排名方法

我结合在 Scikit-learn 中定义的单变量和多变量算法实现了六类排序方法。

第一类称为类型 1—单变量**,由单变量方法组成,如 t 检验和信息增益。**

其他类别基于多元模型:

  • 类型 2 —单一得分:创建仅考虑一种蛋白质(对于每种可用蛋白质)的分类器,并基于在 k 倍交叉验证中计算的准确度对它们进行排序;
  • 类型 3 —属性的权重:训练分类器,并根据默认的特征加权方法对特征进行排序,例如线性模型的系数—每个特征的重要性通过 coef_ attribute 或 feature_importances_ attribute 获得;
  • 类型 4——递归特征消除:基于权重对特征进行排序,但是重复该过程 N 次,将最差的特征添加到排序的末尾,如针对 SVM- RFE 的情况所解释的;
  • 类型 5——稳定性选择:根据在 bootstrap 采样方案中被选为最佳的频率对特征进行排序。该方法使用 bootstrap 创建许多训练集,对于每个训练集,该算法计算每个特征的权重,并且如果它们的权重大于平均权重,则选择它们。频繁选择的功能被认为是稳定的,并位于排名的开头—查看官方知识库了解详细信息:https://github.com/scikit-learn-contrib/stability-selection
  • 类型 6 —准确度降低:使用所有特征计算 k 倍交叉验证准确度,然后,一次移除一个特征并重新计算准确度。与基础精度和移除特征后的精度的差异越大,该特征越相关;
  • ****类型 7 —递归特征添加:类似于类型 4。在这种情况下,不是从最差到最好来创建等级,而是通过从训练集中移除最好的特征并将其添加到等级的开始来创建等级,重复该过程直到所有特征都被排序。在我们的测试中,这在我们的蛋白质组学数据中表现得比 RFE 更好,我将在本文的验证部分解释这一点。

上述每种基于多变量的排序方法(类型 2 至 7)与不同的分类器结合使用。

我用 python 实现了脚本(https://github.com/heberleh/proteins-stability),并从 scikit-learn 中选择了经典的机器学习工具。仅考虑实现特征权重的分类器:

  • 线性 SVC
  • 决策树;
  • 随机森林;
  • 套索;
  • 山脊;
  • 线性判别分析。

共定义了 40 个分级器,它们是上述分级方法和分类器的组合。

在下一节中,我将解释这 40 个排名如何产生数百个待解释的排名,并帮助我们决定在接下来的研究中应该考虑哪些特征。

如果一个大的数据集?— — —

这里我们有一个小数据集。您可能会想办法将这些排序方法应用到更大的数据集,例如,通过使用抽样和并行性。如果你有成千上万的观察和特征,你可以:

  1. 去掉你知道不好的特征,明显不好的特征;
  2. 使用随机抽样或分层抽样来选择一组您可以处理的观察值;重复该过程,检查不同样本的要素在相同等级中的表现。

稳定性管道

在这个项目中,我们定义了一个分析管道,它结合了对特征进行排序的方法,通过简单和双重交叉验证来识别候选签名。

管道的一般概念说明如下:

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

Assessment of Stability and Relevance of Features in a Double Cross Validation scheme — 1) The original data set is divided into train and test sets in each iteration i of the outer loop of the double cross validation (k-fold cross validation). 2) The train set is used to create 40 ranks of proteins. 3) Signatures are created by selecting the top-N proteins and by creating all or random combinations. 4) Each signature is tested in a shuffle split cross validation. 5) Signatures with good score are selected. 6) Highly correlated proteins that were removed between steps 1) and 2) take place of their reference to form new signatures. 7) All signatures are tested again in a shuffle split cross validation, now with a greater number of splits than before. 8) With the new scores, signatures are selected again by a criterion that consider the score, the standard deviation and the frequency of proteins in good signatures. 9) The first round of evaluation of signatures outputs the best signatures, formed by the signatures with the highest scores among the even better signatures. 10) The best signatures are tested again by using different classifier models, including the Bagging and Voting classifiers. 11) The best pairs (signature, classifier) of each signature is tested with the independent test set. In the end of the DCV, the independent test scores are averaged to form the DCV score.

  1. 识别并分离相关蛋白质(训练集中仅保留 1 个代表)——这是减少多重共线性的一个步骤。您可能想要搜索线性模型、多重共线性和 VIF。关于主题的一篇文章在这里
  2. 计算排名
  3. 根据等级和小组合创建签名
  4. 评估分类器并选择最好的一个 —这里我创建随机签名(多个模型)并选择平均准确度最高的分类器。这种抽样方法被称为随机子空间
  5. ****使用选择的分类器评估签名;
  6. 识别更好最好签名**;**
  7. 对于每个最佳签名,选择最佳模型 —签名-分类器对;
  8. 计算排名前 10 位的蛋白质的频率
  9. 计算更好最佳签名中蛋白质的频率。

更一般地说,它创建了由一些分类器/排序器算法认为相关的特征集。然后,它通过建立分类器并使用交叉验证估计它们的预测能力来测试这些特征集。

选择的特征越多,其重要性就越大。

这就像一个贝叶斯方法**,我们会认为一个特征在一个高精度模型中的概率。**

现在,流水线中有一个外环,一个 k 倍采样。这将创建不同的数据集,对于每个循环,我们可以检查这些频率如何随着数据集的变化而变化。

例如,如果一个特征只在第一个循环中出现在许多好的分类模型中,这意味着这个特征实际上是不相关的。

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

The most frequent protein in the top-10 positions is the first protein in the plot: P00330_ADH1. Despite that, in one of the loops of a 9-fold sampling, referred as fold-0, this protein was not among the top-10. This should be an alert to the expert that is analysing the results. If our full data set was in fact the fold-0 and we decided to select only the top-10 proteins, this interesting protein would not be selected. In fact, as I explain later, this protein must be selected because it is a true marker. It was added in the biological samples so we could track the behaviour of the computational methods and the behavior of the Proteomics quantification technique and protocol. This protocol is not much precise in the Discovery phase because we are quantifying many proteins. Reducing the number of proteins to quantify will allow it to be more precise and increase the number of observations; having as consequence better statistical confidence.

这里用每组特征(签名)建立分类器,并且测量它们的准确度以判断相应的签名是好还是不好。

等级用于选择用于创建签名的特征。例如,只考虑排名中出现的前 20 个特征。这种启发式方法减少了计算时间。

排名也用于计算蛋白质在前 10 位的频率。选择前 10 个特征是 Discovery Proteomics 中的一个经验法则,这 10 个蛋白质然后在我们称为靶向蛋白质组学中进行分析,它们是我们的目标,因为它是一个小集合,我们可以提高精确度和观察的数量。

在下面的图片中,你可以看到前 10 个定位蛋白质组中每个蛋白质的出现频率,以及更好最好组签名。

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

好的更好的最好的套件在制造时就考虑到了灵活性。只选择具有最大精确度的模型是不公平的,例如 95%(有数百个具有最大精确度)。因为样本数量很少,我们不应该要求太严格。**

因此,“好”和“甚至更好”的集合代表了这种灵活性;例如,选择准确率> 90%的模型,然后选择> 93%,最后选择 95%。

在所有这些候选签名集上跟踪我们的特征的行为给了我们关于数据的更多信息和信心。在我们的研究中,我们在所有的分析方法中都发现了有趣的模式。

最后,在外循环中,最好的模型用独立的测试集再次测试——这导致了我们所说的双交叉验证** (DCV)。这是一篇关于 DCV 的文章。**

当我们有一个小的集合时,交叉验证(CV)的主要问题是估计过于乐观。进行 DCV 有助于我们理解简历验证的乐观程度。

根据我的经验,如果我们有 50%的 DCV 误差,我们会做得很好。

事实上,即使我们的数据集中有已知的真实标记,当考虑最佳签名时,我们得到的 DCV 误差> 60%。这意味着,尽管签名在交叉验证时工作良好,但在用新的观察结果进行测试时,它们的表现很差。

因此,如果我们的目标是减少过度拟合,我们不应该选择具有最高分数的签名。相反,这是分析具有不同 CV 分数的许多模型中特征的频率的动机之一。

验证和结果

在本节中,我将解释我们如何在 Discovery Proteomics 中用一个数据集验证我们的方法,以及如何通过我们的稳定性渠道成功地对真正的标记(特征)进行优先排序。****

如果我们选择 CV 分数最高的签名,我们最终会得到一个糟糕的 DCV 分数——正如我们所做的那样。出于这个原因,我们实现了分析管道,在这里我们跟踪不同视角下的特性得分。

我在这个项目中展示的总体想法是,当你有少量的观察数据时,你需要掌握数据,并在不同的条件下进行分析。然后,你需要选择启发法来优先考虑你的特性,记住你不应该太严格;您应该定义不同的阈值并进行比较。

真正的正面特征

真正积极的特征(标记)是优先的特征,事实上对我们的问题很重要。假阳性可能是被优先考虑的特征,但实际上它们并不会导致我们的类别的差异。

我们的目标是分析发现蛋白质组学(小样本和多特征)中计算方法和质谱技术定量的行为。

我们能否通过量化生物样本的蛋白质并用计算方法对其进行排序,从而从生物样本中识别出真正的标记?

这个问题的答案是既有又无。

不,因为如果你选择了错误的计算方法,他们可能无法识别真正的标记。

在我们的实验中,用不同的排序器对相同的数据集进行排序导致了许多分歧。在一些等级中处于顶端位置的蛋白质出现在其他等级中的最后位置。如果你选择了“错误的一群”排名者,你最终会变得极端偏见。

是的,因为正如我在我们的方法中所展示的,如果你运行许多方法并结合来自不同角度的信息来对蛋白质进行优先排序,就可以识别出真正的标记。

在这里,我向你展示了在我们的管道中计算的频率如何揭示真正的标记作为良好的候选。

真实标记的量化

我们真正的标记物是在定量之前在生物样品中定义的。

我们在生物样本中加入蛋白质,每堂课的浓度相同;不同班级浓度不同。

**有三类: C(对照)、 **TR(肿瘤切除)T(肿瘤)

他们参考了没有癌症的病人、切除了肿瘤的病人和有肿瘤的病人的唾液样本。这些蛋白质定量结果如下所示。

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

True markers’ intensities.

正如我们所看到的,尽管在一个类别的每个样品中加入了相同浓度的蛋白质,但是它们的定量强度不同。每个班的平均值不一样:C 班-1 左右,TR 班 0 左右,t 班 1 左右。

对特征分数进行排序

通过计算排名分数和改变数据集,我们发现了清晰的稳定性模式,如下图所示。

总之,我们发现了一组在大多数情况下被选为好的蛋白质,它们在热图中以红色显示。

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

Heat map showing the highest 50% average scores from 40 ranks of each protein for each training dataset (column, 9 columns refer to 9-fold sampling). The blue values are low scores or proteins that were removed from the training set due to filtering by p-value. We conclude that many proteins are unstable and it is clear that we have a potential smaller set of proteins (red lines) to be assessed. In fact, with this plot we could have already eliminated the blue lines and re-started the pipeline. In the current project, we just continued with all proteins to see where it would end if this pattern was not revealed.

我们还发现了一组频繁出现在排名前 10 位的蛋白质。这些蛋白质及其重量用箱线图表示。箱线图也显示了排名和数据之间的差异。在 B)中,我们有一个更好的权重图,因为我们只考虑每种蛋白质的最佳分数。在 A)中,我们看到所有蛋白质在某一点上都有不好的分数。

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

These are proteins that appeared in at least 33% of top-10 positions in ranks. A) The box-plot is showing weights from all ranks. B) The box-plot is showing the distribution of the 50% highest values from each of the 40 ranks. All the 50% highest values from each loop are considered, meaning we have 9*20=180 scores for each protein. This plot shows us the median of the weights and how they varied among ranks. Note that even if we get only the 50% highest weights, there are proteins which weights varied from 0.4 to 1.0. This is the instability that we try to address with our analytical pipeline; revealing to the experts that this can happen and showing them protein candidates based on their stability.

特征的频率

在对蛋白质进行评分和排序后,管道创建并测试蛋白质签名。下图向我们展示了管道是如何选择蛋白质的。选择的蛋白质越多(横条越大),它就越稳定和重要。

我们发现我们的标记蛋白,真阳性,是前 10 位中出现频率最高的蛋白之一,具有良好/甚至更好/最好的特征。

下图显示了在每个折叠(颜色)中,每个蛋白质在每个计算等级的前 10 个位置中被选择的频率。我们可以看到,出现在图中间的蛋白质并不经常位于前 10 位,大多数情况下,它们只在某些折叠中出现在前 10 位。这意味着,根据您从训练集中删除的每个观察结果,该蛋白质不再出现在前 10 位中,这表明如果我们选择该蛋白质用于后续实验,将会出现不稳定性和更高的风险。

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

Frequency in top-10 positions, in each fold of the k-fold sampling scheme. Colors represent the folds (different data sets).

下图与上图相似。这里,我们不计算前 10 个位置的频率,而是计算被选择形成组更好最好的签名的频率。同样,根据频率标准,在最好的蛋白质中发现了真正的标记。

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

Frequency of proteins in signatures.

我是不是穿太多了?

是的。我对这个小数据集掌握得越多,就越能适应我的模型。另一方面,我不得不。这是我唯一能想到的理解数据集的微小变化如何改变预测能力的方法。我们在这里假设我们有一组很大的观察值,但是其中可能包含一两个异常值。

执行一个简单的 k 倍采样向我们展示了方差。这里,我们使用一个外部 k 折叠,其中有许多 k 折叠,模拟从未考虑选择特征的新样本。如果你想估计所选特征的能力,DCV 是必要的。

最后,你需要展示所有的结果。使用 DCV 误差向专家解释假阳性的风险。

DCV 方案也给管道带来了一些问题,我将在下面解释——如果您不打算按原样使用这个特定的管道,请跳过它。

限制:因为在 k 倍采样的每次执行中,相关的蛋白质在管道的开始被分离,所以这些蛋白质的频率存在问题。一种标记蛋白可能会从一些训练集中删除,而不会从其他训练集中删除,从而导致频率低于应有的水平。在当前的图表中,你可以看到,即使这些蛋白质出现的次数较少,它们出现的频率也很高。发生这种情况是因为如果它的参考蛋白在一个好的信号中被选择,我将它们添加回去以创建信号——特别是用那个信号中被去除的蛋白替换参考蛋白。这并不理想,因为尽管它们高度相关,但它们可能具有不同的强度。类似的行为也发生在过滤步骤中,例如按 p 值过滤和错误发现率。一种解决方案是在外部 k 倍采样之前移除相关的蛋白质并过滤,但是这并不理想,因为在 DCV 中,我们不希望在 k 倍采样之前应用任何方法,以避免使特征选择过程产生偏差。如果在 DCV 流水线之前删除基于类信息的特征,那么一旦独立的测试集不应该成为任何处理的一部分,你就会使你的结果产生偏差。因此,需要一种更好的算法来跟踪蛋白质对,例如,总是使用相同的蛋白质作为参照。注意,当前版本是并行运行的,很难定义一个确定性的解决方案。然而,目前在管道中间添加蛋白质的方法对于当前的情况工作得很好。

结论

我们的管道并不是解决蛋白质排序问题的完美方案。完美的解决方案是将观测次数增加到数千次。

因为我们不能增加样本量,所以了解数据的行为对决策非常重要。

可视化、重新采样、平均和计算蛋白质的频率来测量它们的稳定性和能力有助于识别和理解蛋白质和方法的行为。

通过向生物样品中添加真实标记物,并使用我们的 Discovery 蛋白质组学方案对所有蛋白质进行量化,我们在本地验证了我们的管道。它能够突出真正的标记,如本文中的图所示。

在这里,我将其命名为“局部验证”,因为需要使用不同数据集的许多其他研究来实际验证用于任何发现蛋白质组学数据的方法。

尽管如此,我们的方法给出了关于机器学习和统计方法的行为的控制和突出信息,以及关于每种蛋白质如何表现这些方法给出的重要性的信息。

理解过度拟合很重要,因此它向所有参与该项目的研究人员表明,当我们的样本量小于因子/变量的数量时,我们不应该相信数字和 p 值。

在了解假阳性和假阴性的所有风险,以及方法和蛋白质在我们的分析管道中的表现后,我们可以更有信心地进行决策。

关于生物标志物的推荐文献

  • Kawahara,r .、Meirelles,G. V .、Heberle,h .、Domingues,R. R .、Granato,D. C .、Yokoo,s .……Leme,A. F. P. (2015)。综合分析选择癌症候选生物标志物进行靶向验证。Oncotarget,6(41),43635–43652。https://doi.org/10.18632/oncotarget.6018
  • Carnielli,C. M .,Macedo,C. C. S .,De Rossi,t .,Granato,D. C .,Rivera,c .,Domingues,R. R .,… Paes Leme,A. F. (2018)。结合发现和靶向蛋白质组学揭示口腔癌的预后信号。自然通讯,9(1),3598。https://doi.org/10.1038/s41467-018-05696-2
  • 德尔·坎波,玛尔塔&容布勒德,韦斯利&特瓦霍夫,哈里&韦厄斯,罗伯特&布兰肯斯坦,马里努斯&特尼森,夏洛特。(2015).促进痴呆新蛋白质生物标志物的验证:夹心免疫测定发展的最佳工作流程。神经学前沿。6
  • **y . Cun 和 h . f . frh lich(2012 年)。乳腺癌患者分层的预后基因标记——使用蛋白质-蛋白质相互作用的先验知识的基因选择方法的准确性、稳定性和可解释性。BMC 生物信息学,13(1),69。【https://doi.org/10.1186/1471-2105-13-69 **
  • Christin,c .,Hoefsloot,H. C. J .,Smilde,A. K .,Hoekman,b .,Suits,f .,Bischoff,r .,& Horvatovich,P. (2013 年)。临床蛋白质组学中生物标志物发现的特征选择方法的评价。分子和细胞蛋白质组学,12(1),263–276。https://doi.org/10.1074/mcp.M112.022566
  • Rifai,n .,Gillette,M. A .,和 Carr,S. A. (2015)。蛋白质生物标志物的发现和验证:通往临床应用的漫长而不确定的道路。自然生物技术,24(2006 年 9 月),971–983。https://doi.org/10.1038/nbt1235
  • Sanavia,f . AIO lli,g . Da San Martino,a . biso gnin 和 Di Camillo,B. (2012 年)。通过在学习过程中整合生物学知识来提高生物标志物列表的稳定性。BMC 生物信息学,13(补编 4),S22。https://doi.org/10.1186/1471-2105-13-S4-S22

通过维基百科页面浏览量对编程语言进行排名

原文:https://towardsdatascience.com/ranking-programming-languages-by-wikipedia-page-views-f810a04ec55b?source=collection_archive---------20-----------------------

在 python 中使用 API 和绘图的演示

对编程语言的流行程度进行排名有许多不同的方法。Tiobe Index 是一个流行的网站,它根据流行程度对编程语言进行排名。我还看过一些文章,人们通过查看工作列表的数量或堆栈溢出问题的数量来对编程语言的受欢迎程度进行排名。

今天,我将利用维基媒体应用编程接口,根据 2018 年初以来的总页面浏览量,对一系列编程语言进行排名。

幸运的是,python 自带了方便的内置请求库,这使得从 API 获取数据变得非常容易。我定义了一个简单的函数来从页面视图 API 获取页面视图数据。

API 请求函数:

import requests
import numpy as np
import pandas as pddef wikimedia_request(page_name, start_date, end_date = None):
    '''
    A fucntion that makes requests to the wikimedia pagecveiws APIParameters
    ----------
    page_name : string
    A string containing the name of the wikipeida page you would like pageviews for

    start_date : string
    a date string YYYY/MM/DD indicating the first date that the request should return

    end_date : string
    a date string YYYY/MM/DD indicating the last date that the request should return. defaults to system date
    Returns
    -------
    df : pandas DataFrame
    A dataframe with the article name and the number of pageviews.
    '''

    # get rid of the / in the date
    sdate = start_date.split("/")
    # join together the text that was split
    sdate = ''.join(sdate)
    # if an end date is not specified
    if end_date == None:
        #get the current date
        end_date = str(datetime.datetime.now())[0:10].split("-")
        edate = ''.join(end_date)
    else:
        # use date from end_date argument
        edate = end_date.split("/")
        edate = edate[0] + edate[1] + edate[2]
    # use these elements to make an api request
    r = requests.get(
        "[https://wikimedia.org/api/rest_v1/metrics/pageviews/per-article/en.wikipedia.org/all-access/all-agents/{}/daily/{}/{](https://wikimedia.org/api/rest_v1/metrics/pageviews/per-article/en.wikipedia.org/all-access/all-agents/{}/daily/{}/{)}".format(page_name,sdate, edate)
    )
    # get the json
    result = r.json()
    # convert to dateframe
    df = pd.DataFrame(result['items'])
    # the wikimedia api returns 2 extra zeros at the end of the timestamp for some reason
    df['timestamp'] = [i[:-2] for i in df.timestamp]
    # convert to datetime
    df['timestamp'] = pd.to_datetime(df['timestamp'])
    # set timestamp as index
    df.set_index('timestamp', inplace = True)
    # return the article and views columns
    return df[['article', 'views']]

一旦定义了这个函数,就可以很容易地与 list comprehension 结合使用,为多个页面创建页面视图的数据框架。我定义了一个我感兴趣的 20 种编程语言的列表(诚然这是一个有点随意的列表,这篇文章主要是为了演示一种技术),然后就这么做。

names = ['Python (programming language)', 'R (programming language)', 'Java (programming language)', 
         'Scala (programming_language)', 'JavaScript', 'Swift (programming language)', 'C++', 
         'C (programming language)', 'Clojure', 'C Sharp (programming language)', 'F Sharp (programming language)',
        'Julia (programming language)', 'Visual Basic .NET', 'Perl', 'Haskell (programming language)',
        'Go (programming language)', 'Ruby (programming language)', 'PHP', 'Bash (Unix shell)', 'TypeScript']dfs = pd.concat([wikimedia_request(x, start_date) for x in names])

我个人喜欢 python 列表理解,因为它们允许代码简洁、可读。本文中的大部分内容在其他语言中需要更多的代码。

图形流行度:

现在我有了编程语言的数据,我可以使用 pandas 和 matplotlib 创建一个简单的图,看看自 2018 年初以来,哪些语言的搜索量最多。

means = dfs.groupby('article').mean()['views']
means.sort_values(ascending = False).plot(kind = 'barh', color ='C0', figsize = (12,6))
plt.title('Total Wikipedia Page Views')
sns.despine()
plt.xlabel('Count of Page Views')
plt.ylabel("")
plt.show()

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

  • 在大多数语言排行榜上,python、java、javascript 和 C 争夺榜首
  • 从我的数据来看,python 是最受欢迎的
  • Python 的使用在过去几年里一直在增长
  • 这对我有好处,因为 python 是我使用的主要语言

我还对每种语言的页面每月搜索量的趋势感兴趣。哪些语言在兴趣上呈上升趋势?哪些语言呈现兴趣下降趋势?

我想制作简单的回归图来评估语言兴趣的时间趋势。这在 python 中有点难做到,因为 seaborn 的 regplot 不接受 datetime 对象。我改编了这个堆栈溢出答案的代码,用 python 创建了时间序列回归图。

def tsregplot(series, ax = None, days_forward = 10, color = 'C0'):
        '''
    A fucntion that makes requests to the wikimedia pagecveiws APIParameters
    ----------
    series : Pandas datetime index Series
    A pandas Series with datetime index

    ax : matplotlib axes object
    A matplotlib axes obect

    days_forward : int
    An integer indicating how many days to extend the regression line. This is set at 10 by default so that all points can show. increasing it can be used to forecast regression line foreward

    color : string
    A matplotlib color string 

    Returns
    -------
    ax : matplotlib axes object
    returns a matplotlib axes object with regplot
    '''
    series = series.reset_index()
    series.columns = ['date', 'value']
    if ax == None:
        series['date_ordinal'] = pd.to_datetime(series['date']).apply(lambda date: date.toordinal())
        ax = sns.regplot(
        data=series,
        x='date_ordinal',
        y='value',
        color = color
        )
        ax.set_xlim(series['date_ordinal'].min() - 2, series['date_ordinal'].max() + days_forward)
        ax.set_ylim(series['value'].min() - 1000, series['value'].max() + 1000)
        ax.set_xlabel('date')
        new_labels = [date.fromordinal(int(item)) for item in ax.get_xticks()]
        ax.set_xticklabels(new_labels)
    else:
        series['date_ordinal'] = pd.to_datetime(series['date']).apply(lambda date: date.toordinal())
        ax = sns.regplot(
        data=series,
        x='date_ordinal',
        y='value',
        ax = ax, 
        color = color
        )

        ax.set_xlim(series['date_ordinal'].min() - 5, series['date_ordinal'].max() + days_forward)
        ax.set_ylim(series['value'].min() * 0.9 , series['value'].max()* 1.1)
        ax.set_xlabel('date')
        new_labels = [date.fromordinal(int(item)).strftime("%m/%Y") for item in ax.get_xticks()]
        ax.set_xticklabels(new_labels)
        return ax

我可以创建一个简单的 for 循环,为 20 种语言中的每一种绘制时间序列回归图:

fig, ax = plt.subplots(10,2, figsize = (16, 20))
ax = ax.ravel()
counter = 0
for i, j in zip(dfs.article.unique(), names):
    string = i
    selected = dfs.query("article == '{}'".format(string))
    tsregplot(selected['views'].resample('M').sum()[:-1], ax = ax[counter])
    ax[counter].set_title(j)
    plt.tight_layout()
    counter += 1
plt.savefig('trendplots.png')

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

需要注意的几件事:

  • 基于维基百科的页面浏览量, python 的兴趣实际上一直在下降
  • 根据维基百科的页面浏览量,对朱莉娅感兴趣的人可能会增加,但这看起来更像是噪音。
  • 基于维基百科页面浏览量,对 Java 的兴趣在增长,对 Scala 的兴趣在萎缩。 Scala 是 Java 的一个更简单、更现代的替代品。这让我有点吃惊。
  • 人们对打字稿的兴趣急剧增长,这已经在的许多文章中有所记载
  • 根据维基百科的页面浏览量,人们对围棋的兴趣一直在适度增加。GO 经常被认为是服务器语言的 python 杀手。我自己也玩过一点围棋,但并不觉得它对我的工作(主要是数据科学)非常有用。

结论:

有许多不同的方法来排列编程语言。我目前找不到任何其他人使用维基百科页面浏览量来对编程语言进行排名(是的,有人可能已经这样做了,但这还不足以找到关于它的文章)。

我认为维基百科的页面浏览量是衡量人们对编程语言或其他公众感兴趣的话题的一种非常合理的方式。当我对一门新的编程语言感兴趣时,维基百科通常是我首先查看的地方。我认为也可以有把握地假设许多其他人也这样做。

代码可以在这里找到

使用 PageRank 和 Neo4j 排名最佳 UFC 拳手

原文:https://towardsdatascience.com/ranking-the-best-ufc-fighters-using-pagerank-and-neo4j-5385805b4515?source=collection_archive---------16-----------------------

综合格斗迷和专家们喜欢争论哪些拳手应该被认为是有史以来最伟大的拳手。然而,很多时候,这些排名是战士记录、个人偏见、Reddit 键盘战士的分析和直觉的主观混合。有没有更数据驱动的方式来集结战斗机排名?

在这篇文章中,我将展示如何使用 PageRank 算法(最初由 Google 开发,用于对网页进行排名)和 Neo4j 来对每个 UFC 重量级的最佳拳手进行排名。

获取数据

UFC 在 http://ufcstats.com 发布自 1993 年以来所有赛事的比赛结果。为了获得这些数据,我编写了一个 Python scraper 来抓取站点并保存结果。在这篇文章中,我提取了截至 2019 年 9 月 14 日(UFC 战斗之夜 158)的所有战斗数据。更深入的描述和使用例子可以在我的 github 这里找到。

当新的 UFC 事件发生时,scraper 检索所有历史战斗结果并用新的结果更新已经保存的数据。虽然没有在此分析中使用,但战斗中的统计数据,如着陆打击和战士属性,如到达,身高和出生日期,也可以使用刮刀。

以下是本文将使用的部分数据:

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

如上所示,与此分析最相关的四个字段是战士、对手、结果和部门。

设计图形数据模型

在将数据加载到 Neo4j 之前,让我们考虑一下我们希望如何在图形中表示数据:

  • 每架战斗机将被分配到一个节点。
  • 边将被定向,这样如果战士 A 输给战士 B,将会有一条边从战士 A 传到战士 B。
  • 比赛的划分和日期将被设置为边的属性。如果战斗机 A 在 2019 年与战斗机 B 在轻量级比赛,那么这些部门和日期属性将位于连接这些战斗机的边上。
  • 如果格斗者多次面对面,那么每次格斗都会有不同的边。

我们的图形数据模型的可视化表示如下:

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

简单地说,上图显示战斗机 A:

  • 在 2015 年的一场轻量级比赛中输给了拳手 B
  • 2016 年在一场轻量级比赛中输给了战斗机 C
  • 2017 年在次中量级赢得了与战斗机 C 的复赛

将数据加载到 Neo4j

有了我们的数据模型草图,我们现在可以开始将数据加载到 Neo4j 中。为此,我们将利用 Py2neo ,它允许 Python 与 Neo4j 交互。这使得从 Python 到 Neo4j 的数据工作流更加简单,并且可以将 Cypher 查询结果从 Neo4j 提取回 Python。

下面的要点显示了用于将比赛结果数据从 pandas 数据帧加载到在默认设置下运行的本地 Neo4j 实例中的代码:

在上面的代码中,我们只查看 fights 数据帧的 results 列中带有“W”的行,因为输的行只是赢的行的镜像(fighter 和 counter 对调)。对于每一场战斗,如果没有节点存在,我们为战斗者和他/她的对手创建节点,或者使用 Cypher 的MERGE子句将它们与已存在的节点匹配。再次使用MERGE,我们创建了战斗的输家和赢家之间的有向边关系。战斗机名称、部门、日期和方法等属性作为参数传入,这些参数被分配给图的节点或边的属性。

一旦加载了数据,我们就可以在 Neo4j 的浏览器中查看可视化的图表。以下是一个查询的结果,显示了康纳·麦格雷戈的所有对手,以及他们如何对付康纳和对方:

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

PageRank 的一个非常简短的解释

最初由拉里·佩奇和谢尔盖·布林开发的 PageRank 被用于谷歌的搜索引擎,对链接网页的相关性进行排名。在有向图中使用网页作为节点,链接作为边,PageRank 的大致思路如下:

  • 有许多其他页面链接到它的页面将有更高的相关性
  • 拥有来自高相关性页面的链接增加了相关性
  • 页面将相关性传递给它们链接到的邻居

以最初的网页排名用例为例,像 Twitter 这样的网站会有很高的 PageRank,因为有许多其他网站链接到它。同样,从 PageRank 的角度来看,一个带有 Twitter 等热门网站链接的网站也具有很高的相关性。下图展示了这一想法:

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

Source: Wikipedia

节点 B 具有最高的 PageRank,因为它不仅有许多链接到它的节点,还因为它有来自具有相对高相关性的节点的链接。尽管节点 C 只有一条指向它的链路,但它有很高的 PageRank,因为这条链路来自网络中最重要的节点 B。节点 A、D 和 F 的网页级别较低,因为它们只有几个相对不重要的节点与之链接。

理解了上面的例子,我们就可以看到 PageRank 也可以翻译成 UFC 战士了。具有更多胜利(更多边传入)和战胜高排名战士(来自重要节点的传入边)的战士将具有更高的 PageRank 排名。

虽然简短,但对 PageRank 的解释有望提供算法如何工作的一般概念。对于那些有兴趣了解更多的人,这个视频系列的视频 5-10 提供了一个很好的解释。

将 PageRank 应用于 UFC

方便的是,Neo4j 已经提供了 PageRank 的实现,所以我们可以很容易地将该算法应用于我们的 UFC 图。再次使用 Py2neo,下面的代码计算每个师的战斗机 PageRank 分数:

下面我们可以看到 PageRank 是如何对男女各个组别的前 10 名最佳拳手进行排名的:

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

Men’s top 10 PageRank scores by division

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

Women’s top 10 PageRank scores by division

调整 PageRank 分数

虽然 PageRank 排名看起来基本正确,但也有一些情况下粉丝可能会觉得有问题。例如,目前的轻量级冠军和不败拳手哈比布·努尔马戈梅多夫在历史排名中排名第三,尽管他击败了排名第二的迈克尔·约翰逊。约翰逊自己的排名似乎太高了,因为他在轻量级比赛中输了 8 次,所有这些都是由排名低于他的拳手造成的。此外,将唐纳德·赛罗内列为有史以来第一轻量级拳手是有问题的,因为他从未赢得过金腰带,也输给了许多排名低于他的拳手。

同样,在重量级比赛中,一些人可能会对前冠军丹尼尔·科米尔排名低于竞争者德里克·刘易斯四位提出异议,尽管科尔米耶此前击败了刘易斯和排名第一的斯蒂佩·米奥西奇。

这些差异从何而来?回想一下,PageRank 在计算分数时会考虑节点的传入边数。因此,总胜率越多(进洞边数越多)的拳手,他们的 PageRank 分数将会提高。因此,看起来 PageRank 的排名过于看重胜利的数量,或许也稍微低估了失败的数量。

最明显的例子是在轻量级比赛中,目前的冠军 Khabib Nurmagomedov 的记录是 12–0–0(W-L-D ),但仅排名第三,而排名第一的 Donald Cerrone 的记录是 17–6–0。Cerrone 比 Nurmagomedov 赢的多,主要是因为在 UFC 轻量级比赛中打得多(Nurmagomedov: 12,Cerrone: 23)。因此,尽管是冠军,尽管击败了排名很高的拳手,Nurmagomedov 的 PageRank 分数相对于 Cerrone 的有所下降,因为他的总比赛次数较少。

同样,迈克尔·约翰逊的第二总排名看起来很奇怪,因为约翰逊的记录是 9-8-0,其中包括输给努尔马戈梅多夫。事实上,约翰逊已经战胜了几个排名很高的轻量级选手,包括托尼·弗格森(第 5 名)、埃德森·巴尔沃萨(第 6 名)和达斯汀·普瓦里耶(第 7 名),这有助于提高他的 PageRank 得分。然而,他在轻量级比赛中仅有 0.50 的战绩让人质疑他的第二名排名,并表明损失并没有得到应有的重视。

基于上面的观察,我们需要以某种方式将拳手的记录纳入排名,这样胜率高或输球少的拳手的 PageRank 分数就会提高。

个性化页面排名

一种可能的方法是使用一种叫做个性化页面排名的页面排名算法。非常概括地说,个性化页面排名有利地偏向网络中的某些节点,从而增加这些节点的得分。但是,指定哪些节点应该接收偏置可能有点随意,并且可能会根据选择的节点而显著改变结果。例如,下表显示了轻量级部门的个性化页面排名,使用两种不同的标准来选择有偏向的节点:

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

Left: Personalized PageRank rankings with biased nodes of Khabib Nurmagomedov and Tony Ferguson. Right: Personalized PageRank rankings with biased nodes of Khabib Nurmagomedov, Tony Ferguson, and Gregor Gillespie

左边的表格使用偏向节点选择标准,即≥ 10 次战斗和≥ 90%的胜率,而右边的表格使用≥ 6 次战斗和≥ 90%的胜率。正如我们所看到的,第二个选择标准增加了一个额外的有偏向的节点,这导致了一个非常戏剧性的变化;Gregor Gillepsie 曾在左侧表格中排名第 60 位,当被列入有偏见的节点时,他突然上升到第 3 位。鉴于这些结果,选择有偏向的节点用于个性化 PageRank 可能不是最好的主意,因为 a)选择标准可以是任意的,b)结果根据选择的节点而显著变化。

对于感兴趣的人,这里是 Neo4j Cypher 查询,用于返回个性化的 PageRank 分数:

非二进制偏置节点选择

上述问题的一个潜在解决方法是对每个节点应用一个权重,可能是战士的胜率或 1/损失,并使用这些权重来计算每个节点的偏差。因此,不是二元选择是否偏置特定节点,而是每个节点基于它们的胜率或损失率接收不同程度的偏置。

不幸的是,Neo4j 目前还不支持这一功能,尽管根据 Neo4j 的 github 上的这个公开问题,它似乎正在工作中。我可能会写一个后续在未来当这是补充。

按胜率加权 page rank

将拳手的记录纳入排名的最简单的方法是简单地将每个拳手的 PageRank 乘以他们的 win %。虽然并不完美(失败会对战斗较少的战士产生更大的影响),但这将有助于平衡这样一个事实,即一些战士赢得更多,主要是因为总体上有更多的战斗,同时也增加了失败的影响。

使用该方法得到的修正排名(PageRank * Win %)如下表所示:

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

Men’s rankings: PageRank * win %

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

Women’s rankings: PageRank * win %

虽然很主观,但对以上修订排名的评估感觉更好。在轻量级比赛中,Khabib Nurmagomedov 和 Tony Ferguson 分别排名第二和第三,而迈克尔·约翰逊跌至第四。虽然唐纳德·塞罗内仍然保持第一名的位置,但塞罗内和努尔马戈梅多夫之间的差距已经明显缩小。在重量级比赛中,前冠军丹尼尔·科米尔从第八名上升到第六名,虽然在我看来还是有点低(应该比排名第五的德里克·路易斯高),但这是一个更合理的排名。

结论

在这篇文章中,我们展示了如何使用 PageRank 对 UFC 战士进行排名,并找出每个组别中的最佳选手。虽然不完美(大多数排名都不完美),但 PageRank 似乎在战士排名方面做得相对不错。

一个潜在的进一步改进是考虑战士的年龄。一些伟大的战士继续战斗,直到过了他们的巅峰时期,并遭受损失,这降低了他们的 PageRank 分数,增加了击败他们的人。很好的例子是中量级伟大的安德森·席尔瓦,他在过去的五场比赛中取得了 1 胜 4 负的成绩,以及轻量级传奇人物 BJ·佩恩,他在过去的五场比赛中取得了 0 胜 5 负的成绩。在一个伟大的斗士暮年打败他,不应该等同于在他全盛时期打败他。如果我们想找到最好的全盛时期的拳手,考虑年龄似乎是必要的。

也就是说,也许知道什么时候挂掉他们也是一个伟大的战士变得伟大的原因。

对于那些想自己探索数据的人来说,所有代码和数据都可以在我的 github 上找到。

对于 UFC/MMA 的粉丝来说,这些排名和你自己的相比如何?

说唱(机器)天才

原文:https://towardsdatascience.com/rap-machine-genius-935db7a260b?source=collection_archive---------36-----------------------

一个有抱负的说唱歌手应该关注哪些话题才能在 Genius.com 走红?简单回归分析

最大化观点的创造性咨询

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

Janelle Monae, by Shawn Anderson (Creative Commons license)

1.主要前提

a.激励性问题

对于我的回归项目,我从以下前提开始:假设我的朋友 Janelle 是一名有抱负的说唱歌手,她筹集的资金只够下周举行一次录制。这是她走红的机会,但她需要帮助决定录制哪些歌曲。在工作室的有限时间里,Janelle 应该做关于她的宗教信仰的那个,还是关于高级时装的那个?她能在不咒骂或吹嘘她希望拥有的豪车的情况下获得关注吗?

b.衡量一首歌的受欢迎程度

当然,如今衡量一首歌曲成功与否的最佳指标必须包含音乐流数据,因为这是目前大多数人听音乐的方式。但听众分散在多个服务中,包括 Spotify、Apple Music、Tidal、YouTube 等。即使假设他们公开了他们的数据,也很难将它们收集并汇编成一个单一的数据集。

c.警告

人们听一首歌的原因有很多,与歌词无关:也许他们已经喜欢上了这个艺术家,也许节拍非常适合跳舞,也许旋律非常吸引人。但没关系——我在这里的目的不是建立一个模型来预测准确的点击量,而是梳理出话题和流行度之间的一些关系。

2.网页抓取

a.Genius.com

我决定从歌词网站 Genius.com 收集信息。这是一个网站,提供一首歌的原始歌词,加上解释歌词意义的众包注释。假设你正在听德雷克的《上帝的计划》,歌词“把 O2 变成 O3”让你挠头。你可以访问这首歌在 Genius.com 的页面,了解 Travis Scott 在伦敦 O2 arena 与 Drake 一起表演时从舞台上摔了下来。整个人群都退了款,把 O2 变成了“O-free”

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

为了方便起见,Genius.com 公开了页面浏览量。当然,歌词特别复杂、引用模糊的流行歌曲在那里吸引的浏览量可能比你根据其受欢迎程度预计的要多。但接下来,我会把一首歌在 Genius.com 的浏览量作为一首歌受欢迎程度的代表。

b.Selenium Chrome 驱动程序抓取的数据

下一步是收集数据。我用 Selenium Chrome 驱动程序抓取了被赋予说唱标签的前 1000 首歌曲的页面链接。

然后我访问了列表中的每一页,收集了以下数据:歌词本身、浏览量、与歌曲相关的标签以及为解释歌曲歌词而贡献注释的人数。

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

我还跟踪艺术家、歌曲作者或制作人是否提交了歌词的解释。该网站称之为“经过验证的评论”,并用绿色而非灰色标记这些注释(见下文)。

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

c.特征工程

一旦我获得了 1,000 首歌曲中每一首歌曲的信息,我就使用一个简单的词袋模型来计算某个词在一首歌曲中出现的次数,然后根据歌曲中的词数对该计数进行归一化。例如,“服装”主题的特色是品牌名称,如“古驰”、“芬迪”、“普拉达”、“路易威登”、“迪奥”等。“诅咒”主题包含了 FCC 68 个禁用词中的大多数,“汽车”主题包含了特别著名的豪华汽车的品牌名称,如“布加迪”、“保时捷”和“法拉利”,而“宗教”主题包含了“上帝”、“主”、“耶稣”、“魔鬼”和“信仰”等词。

3.探索性数据分析

也许不出所料,大多数歌曲的歌词都很直白:除了 83 首以外,所有歌曲都带有某种诅咒的字眼。

快速的理智检查表明,我的话题确实找到了正确的歌曲:“衣服”指标中得分最高的歌曲是 Migos 的 【范思哲】Lil Pump 的和 Kreayshawn 的古驰古驰。《汽车总动员》也是如此:最佳射手是艾斯胡德的布加迪和美联社的 Yamborghini High。《诅咒》中出现了一些脏话,看到 Kanye West 在“宗教”指标上名列前茅,我并不感到惊讶。

4.建模

在确保数据相对干净,功能按照我预期的方式运行之后,我使用普通的最小二乘法建立了一个简单的线性回归模型,以页面浏览量为目标。然后,我应用了一个标准的缩放变换,接着是岭正则化,这样我就可以并排比较各种特征的系数。

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

a.最大特点:观众参与

让我们从两个最强的结果开始,它们具有高系数低 p 值。越多人对一首歌的页面做出贡献,这首歌的页面浏览量就越多。拥有一个“经过验证的”投稿人对页面浏览量也有积极的影响。

b.话题强度

就主题而言,唯一对页面浏览量有负面影响的是“宗教”类别。这是否意味着坎耶·韦斯特是对的?在中,耶稣行走 (2004),韦斯特斥责道:

他们说你可以说唱任何东西,除了耶稣

这意味着枪支、性、谎言、录像带

但是如果我谈论上帝,我的唱片就不能播放了,嗯?

没那么快。p 值有些高:0.23。相比之下,“汽车”功能对查看次数有积极影响,但其 p 值为 0.06,非常接近 0.05 的标准统计意义阈值。咒骂和奢侈服装有正系数,但它们也有较高的 p 值(分别为 0.842 和 0.358)。

5.结论

a.主题

那么,我会给我的朋友詹妮尔什么建议呢?我会建议她在宗教方面坚持己见。当然,系数是负的,但说唱歌手谈论他们的信仰并不常见,所以这可能有助于她脱颖而出。同样的,她不应该觉得为了适应而不得不诅咒。不过,她可能会发现谈论豪华车对她有利。她可以说唱她有多不在乎他们,并且仍然从这种观察到的提升中受益!

b.观众参与度

一旦这些歌曲向公众发布,我会请我的朋友们为 Genius 添加注释,因为这似乎会增加浏览量。Janelle 也应该自愿做出“经过验证”的贡献!这将提升观点,也确保人们明白她想说什么。

PS:作为一个额外的奖励,只是为了好玩,这里是各种服装品牌和流派标签在页面浏览量上的相对效果。

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

用 Azure 实现快速计算机视觉原型

原文:https://towardsdatascience.com/rapid-computer-vision-prototyping-with-azure-f051cc7462b7?source=collection_archive---------16-----------------------

本帖由亚历克斯·阿库洛夫和 瑞安·佩曼 合著,来自 Omnia AI,德勤加拿大的 AI 实践

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

Object-detecting trucks using a computer vision model on Azure Custom Vision

想象一下,快速构建和部署一个最先进的对象检测模型,而无需编写一行代码。计算机视觉工具和软件已经走过了漫长的道路,使这成为现实。

几年前,你必须知道如何编码,熟悉深度学习框架,并有耐心解读错综复杂的研究论文。在本文中,我们将向您展示如何在几分钟内构建一个对象检测原型模型,并解释新兴工具如何帮助“民主化”计算机视觉解决方案的创建。

Azure Custom Vision 让您无需编写一行代码即可构建和部署对象检测模型。

所有主要的云提供商都在竞相提供预构建的计算机视觉模型。从场景检测和内容审核到文本提取和情绪智能,这些现在都可以轻松实现。

然而,当谈到超越常见用例的界限时,AWS 和 Google 会向您介绍他们各自的数据科学笔记本环境。我们发现 Azure 采取了不同的方法。它的定制视觉产品让您无需编写一行代码即可构建和部署对象检测模型。对于想要测试他们的计算机视觉想法的团队来说,这意味着温和的学习曲线和快速的原型制作。

但是首先,这个想法应该解决一个适合计算机视觉的问题。

确定要解决的业务问题

计算机视觉模型应该为决策提供信息。在商业上,没有为了 AI 而 AI 的地方。总体业务目标是什么?阻碍我们实现目标的问题是什么?是否有图像或视频可以用于深度学习应用?这些是在识别计算机视觉的商业应用时要问的一些关键问题。

我们的目标是展示 Azure Custom Vision 的功能。为此,我们选择了一个监测港口作业中卡车到码头交通的样本问题。

在这一过程中,集中运营协调员必须通过实时视频传输(见下面的视频传输示例图像)持续监控航站楼交通,以确保航站楼车道不会拥堵到卡车涌入附近高速公路、扰乱当地交通的程度。

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

Terminal gate video feed (Source)

从协调者的角度来看,不断地检查几十个监视器中的一个来捕捉偶尔发生的拥塞是一项相当费时且平凡的任务。协调员是非常忙碌的人,在一个 24/7 的高压环境中工作,检查许多供应链事件的视频,如事故、火灾和非法侵入。

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

Typical supply chain operations center

为了帮助协调员专注于更关键的任务,让我们尝试通过在 Azure Custom Vision (ACV)上训练计算机视觉模型来证明自动化终端拥堵监控是可能的。

该过程可以分为 5 个步骤:

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

Machine Learning process for Computer Vision

1.获取图像

温哥华港在他们的网站上发布了他们的终端网络视频。为了训练一个高精度的模型,我们需要标记至少 100-150 幅图像。手动保存 100 多张网络摄像头图像是一项单调乏味的工作,所以让我们使用一个简短的 python 脚本来加快速度。注意,这是本文中我们使用代码来节省时间的唯一地方。

import urllib.request as r, time

*# Direct link to the terminal webcam feed*
imgURL = '''http://www1.pacificgatewayportal.com/webcams/Photos
/CentermMainGates/CentermMainGates_New.jpg?1430944227172'''

for i in range(100):
    r.urlretrieve(imgURL, f"images_{i}.jpg")  *# Scrapecurrent image*
    time.sleep(30)  *# Wait 30 seconds*

2.标签图像

接下来,我们去 www.customvision.ai ,创建一个账号和一个新项目。一旦完成,我们使用界面上传我们上面刮的图像。点击添加图片并导航至您想要上传的文件夹。

接下来,可以开始标记的任务。ACV 提供的界面是直观的,能够围绕你想要检测的每个对象绘制矩形边界框。多个 label 标签可以应用于每个边界框。在这种情况下,我们需要的唯一标签是卡车,但是在您的用例中可能有更多种类。

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

Process of labeling trucks

一般来说,对于一个有效的概念证明模型,建议每个标签至少标记 50 个图像。如果您的用例需要检测多种类型的对象,请确保您有足够的训练图像来捕捉不同的场景。

贴标签需要时间,但是如果您有一个想要原型化的定制业务问题,这是不可避免的。我们喜欢 Azure Custom Vision 的地方在于,该功能内置于解决方案中,使用起来非常直观。

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

What a labeled image looks like

3.训练模型

这是最简单的部分。使用一次点击,我们在 Azure Custom Vision 中训练一个神经网络,根据标记的样本在图像上检测卡车。该过程需要几分钟到几个小时,具体取决于训练图像数据集。

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

Complexity of Computer Vision model training is hidden from the user

4.评估模型

所以我们已经训练了一个模型,但是我们怎么知道它是好的呢?理想情况下,给定终端门的图像,模型应该检测图像中的每辆卡车。在这种情况下,检测意味着以一定的置信度将图像的矩形部分识别为卡车。

我们可以通过使用快速测试选项,用新的图像来尝试:

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

Quick Test allows us to immediately view model output

自定义视觉提供了一个方便的滑块来更改模型应该使用的最小置信度。如果我们将阈值滑动到 13%,模型将检测到更多的卡车,但假阳性的数量也会增加。这里需要达到一个平衡,在这种情况下,我们决定使用 50%的阈值。

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

Lowering probability threshold increases false positives

这还不错,但是模型没有检测到每辆卡车。更具体地说,在图像中的 14 辆卡车中,该模型至少有 50%的信心找到 8 辆。仅基于这张测试图,模型的召回为 8/14 = 57%。我们也可以说模型的精度是 8/8;也就是说,模型检测到的 100%的卡车实际上都是卡车(即没有误报)。

Azure Custom Vision 为模型的每次迭代提供了查全率和查准率。平均精度(mAP)是一个更复杂的描述方法,所以如果你感兴趣,我们将链接到一篇文章。作为参考,地图上的一般物体检测任务用最先进的模型徘徊在 60% 左右。

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

Key indicators to evaluate model’s performance

5.部署

一旦我们在 Azure Custom Vision portal 中训练了模型,它就已经通过 API 部署和可用了。从门户外部进行 API 调用将需要“设置”菜单中可用的预测端点和键。

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

Information needed to send request to model API node

微软还提供了一个有用的 API 测试工具,可以让你快速查看模型的原始输出——一个 JSON 字符串。

我们完了。

Azure Custom Vision 等工具真正大放异彩的地方

通过几个步骤和最少的代码,我们使用 Azure Custom Vision 创建了一个计算机视觉概念验证模型。虽然 ACV 肯定可以用于创建生产规模的解决方案,但在模型控制和定制方面有一些限制。如果你需要完全控制过程的每一个方面,那么不可避免地要使用深度学习 ML 框架。

我们认为,使用像 ACV 这样开箱即用的无代码工具的最重要价值在于,让人工智能概念证明启动并运行,以测试解决方案的可行性。虽然 Azure 是目前唯一一家提供无代码工具来创建 CV 模型的主要提供商,但鉴于该领域的巨大竞争,预计其他 PaaS 提供商也会效仿。

使用像 ACV 这样的工具的最大价值在于快速测试一个人工智能解决方案是否可行

这对企业来说是个好消息,因为它通过降低测试 CV 解决方案的成本,有效地降低了人工智能采用的门槛。考虑到世界上“数以百万计”的组织,根据谷歌主管杰夫·迪恩的说法,“有一个可以用机器学习解决方案解决的问题”,像这样的工具只能帮助推动人工智能的采用。

当然,有效的工具只是硬币的一面。创建人工智能解决方案的另一个必要因素是拥有理解数据科学和底层模型如何工作的合适人才,不管使用什么工具。不幸的是,T2 仍然严重缺乏人才。这是为什么你会看到专业服务公司等非传统参与者提供人工智能和分析服务来满足需求的部分原因。

事实上,这正是我们在德勤加拿大人工智能实践 Omnia AI 所做的事情:我们帮助组织使用 AI 来解决他们迫切的问题。像 ACV 这样的新兴工具可以在这一过程的早期发挥重要作用。

进步快还是理解浅?

原文:https://towardsdatascience.com/rapid-progress-or-shallow-understanding-663bdedc80c1?source=collection_archive---------12-----------------------

这是我对人工智能工具 Tensorflow 的体验的高度总结。如果你是第一次学习这个领域,我建议你从这个快速发展的领域的介绍开始。

如果有一件事我们都讨厌,那就是格式化书目。是的,你可能认为赞扬他人的工作很重要,是的,有条理很令人满意,但是真的有人关心准确无误的单词斜体吗?当然,你可以通过使用自动在线工具来完全避免这个问题,但是这种便利是有代价的吗?现在更容易的道路值得不去克服挑战为未来做准备吗?尽管这个例子很简单,但同样的问题困扰着生活中许多其他[更复杂]的情况。

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

The day before the deadline, trying to plump up the bibliography with non-Wikipedia links… Photo by Tim Gouw on Unsplash.

最近,我在研究人工智能算法时遇到了这个难题。我应该迅速尝试探索许多不同的主题,以实现该领域的各种应用,还是应该确保在更深的层次上熟悉这些概念?使这个决定变得更加困难的是,我想获得使用行业标准工具(如 Tensorflow 框架)的经验,这些工具可以在高层次上加速开发。在 Tensorflow 的帮助下,我在过去几周完成的项目是我刚开始接触人工智能时的五倍,但这种经历值得吗?

用人工智能赶时髦

我用 Tensorflow 做的第一个项目和我创建的一个比较老的项目类似(没有高层框架的帮助);在尝试建立 Tensorflow 遇到一些挫折后,我建立了一个计算机视觉算法,将图像分类为不同类型的衣服。也许,你认为这很简单,但你真的知道最新款的羊毛衫、运动夹克和商务休闲背心之间的区别吗?

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

I can’t tell Armani from a beluga whale, but have you met my AI friend? Photo by Hunters Race on Unsplash.

相比之下,我之前创建了另一个分类算法,但是是针对手写数字而不是服装。因此,我可以将我的旧项目的各个方面与 Tensorflow 的功能进行比较,我惊讶地发现这个框架是如此容易使用。我可以在 Tensorflow 中使用预构建的函数,而不是从头开始编写我使用的每个函数。

例如,我以前必须用数学公式定义一个激活函数,而我只是从 Tensorflow 的许多现有函数中选择一个。此外,该框架还帮助我设置了要使用的数据,而不是我必须下载、转换和处理成千上万的图像来训练算法。虽然这些功能确实很方便,但我只是因为之前的项目(更注重实践)才明白它们是如何工作的。最终,我为快速成功地创建了算法感到兴奋,但也担心这种新的简单性是否更好。

做着同样的事情…但方式不同

然后,我决定探索一种称为卷积神经网络(CNN)的算法来对手写数字进行分类,我已经用其他算法完成了这一工作。从本质上讲,CNN 的主要优势在于它在处理图像之前简化了图像,使得识别数字的主要特征更加容易。把它想象成试图解一个 3x3 的魔方;如果你不断从边缘抽离,事情会简单得多…

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

While the one on top entices me more than the one underneath, I’m not solving anything until the cube is 1x1. Photo by Olav Ahrens Røtne on Unsplash.

在这里,我发现这个项目比我的服装分类器更具挑战性,因为我以前从未使用过 CNN 算法。然而,Tensorflow 针对 CNN 的特定功能使我能够快速理解算法的过程。

具体来说,Tensorflow 使得为 CNN 创建最大池缩减采样层变得很容易,这是简化给定图像的关键步骤。我不再担心单独的计算,而是更加关注算法的结构以及这些层之间的相互作用。也就是说,我并没有获得多少实践经验来弄清楚如何最有效地对这些层及其功能进行编码。最终,我会很高兴与 CNN 的一些更自下而上的方面合作,并尝试在没有 Tensorflow 的帮助下重建一些计算,这就是为什么我想在一个不同的项目中重新讨论这个主题。

如果你不能理解人,让人工智能帮你做

有了这次简化数据的经历后,我创造了我最喜欢的项目:一种试图理解人类情感的算法。最后,我可以用我的秘密工具来为生物学争取额外的 5%了!

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

Students celebrating the wonder of AI to help negotiate marks… Photo by Vasily Koloda on Unsplash.

事实上,它只看电影评论来预测观众是否对这部电影满意。起初,我真的被计算机理解人类情感的可能性惊呆了。然而,这个问题的解决方案比我想象的要简单;该算法使用人们在评论中使用的词语来决定他们对这部电影是否满意。

举例来说,想想你是如何通过文本来判断你朋友的情绪的。他们有笑脸表情符号还是用大写的彩色名词?同样,该算法将人们在评论中使用的词语分为正面或负面,以预测他们对这部电影的感受。在发现这个简单的过程后,我更加理解了现实世界应用程序的影响。从商业上来说,了解顾客的感受让他们更快乐是非常好的,即使用来了解这些情绪的方法更加复杂。

我认为你的文章有点抄袭的味道

人工智能的这种实用潜力让我欢欣鼓舞,我想研究更复杂的人工智能算法。这就是为什么我用 Tensorflow 创建了我的第一个递归神经网络(RNN)。我还想在项目中融入一些随机的乐趣,所以我建立了一个模仿莎士比亚戏剧的算法。显然,唯一比用一篇写得很好的文章打动你的英语教授更好的事情是用一篇写得很好的文章打动你的计算机科学教授,这篇文章是用人工智能写成的莎士比亚式英语。

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

Your computer science professor after reading an AI’s Shakespearean essay. Photo by Ben White on Unsplash.

在整个项目中,我了解了 RNNs 背后的基础知识,以及它们与常规神经网络的不同之处。从根本上说,RNN 的主要优势是它从过去的结果中学习来创造新的结果,或者在问题的背景下,它使用以前的字母来预测新的结果。

此外,这是我开始利用 Tensorflow 的多样化功能的时候。首先,我尝试了不同的优化器来调整 RNN 的学习能力。很明显,我知道了常规梯度下降是多么耗时,随机梯度下降(SGD)通过使用小批量数据减少了计算,自适应矩估计(Adam)避免了陷入良好的设置,而不是找到最佳设置。同样,我试验了不同的激活,发现二元阶跃函数很容易计算,sigmoid 函数很适合分类算法,softmax 函数适合概率问题。

尽管能够快速尝试这些不同的函数并比较结果,我还是不能像我希望的那样强烈地理解 RNNs 的基础知识。当然,我知道该使用哪些函数,以及为什么它们对手头的问题有利,但是我并没有通过实验对 RNNs 工作背后的细节有很深的理解。为了解决这一限制,我需要更深入地研究 RNNs 背后的理论,这在 Tensorflow 已经为您预打包了一切的情况下是有问题的。

可可的人知道他们的工作有点疯狂…

有了 Tensorflow 的经验,我终于开始了我从事的最大的人工智能项目。使用 COCO 图像数据集(成千上万不同主题的图像集合),我创建了一个 RNN,它可以自动为图像生成标题。类似于莎士比亚的 RNN 使用每个字母来预测下一个,这个算法使用标题中的每个单词来预测下一个。而且这一次甚至没有抄袭去世已久的作家,大部分!基本上,它看的是这样一幅图像:

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

Photo by Jeremy Bishop on Unsplash.

然后描述说“一个在海浪上的古怪家伙,伙计。”然而,关键的挑战是在成千上万张图像上有效地训练这种算法。

甚至在我开始之前,我已经陷入了为算法下载和处理千兆字节的训练图像的挑战中。这种计算密集型的过程主要是硬件问题,因为 Tensorflow 已经证明了将图像转换为正确的数据格式的功能。有了这个障碍,开发算法主要是重复我在以前的项目中采取的步骤,然后等待…一小时又一小时的等待。虽然,最后,我还是很乐意尝试一个更大规模的项目。

我不确定 Tensorflow 就是不太流畅…

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

What your puns flow like with Tensorflow. Photo by Matt Hardy on Unsplash.

我和 Tensorflow 的故事到此结束。总之,我用这个高级框架在短短几周内创建了五个不同的项目。通过这个,我获得了多类神经网络的经验,这些神经网络中不同功能的优势,以及人工智能的众多应用。总的来说,我很感激能够快速通过这些挑战,但我确实觉得还缺少一些东西。现在,虽然我对人工智能领域的多个方面有了更多的了解,但我确实认为这些知识有点仅限于 Tensorflow 框架,而不是一般化。总的来说,拥有 Tensorflow 的易用性很有趣,但我绝对重视在没有高级框架帮助的情况下创建我的第一个人工智能项目。这是我能够欣赏在一个项目上投入大量工作来从零开始创造它所花费的时间和努力的唯一方式。

关键要点

  1. 进步快很方便,但是做了就很难对概念有深刻的理解。
  2. 有了以前的实践知识,我能够在创建服装分类器时欣赏 Tensorflow 的新的简单性。
  3. 我可以很容易地专注于 CNN 自上而下的架构,但我没有学习 Tensorflow 的自下而上计算的自动化。
  4. 很难衡量复杂的人类情绪,但检查相关因素就容易多了,比如一个人高兴或悲伤时的语言。
  5. 如果有一件事 Tensorflow 可以帮助初学者,那就是如何将数据处理成可用的形式。

如果你想亲自体验 Tensorflow 的快乐(和挫折…),这里有几个教程可以帮助你开始:

RAPIDS cuGraph——1.0 及更高版本的愿景和旅程

原文:https://towardsdatascience.com/rapids-cugraph-the-vision-and-journey-to-version-1-0-and-beyond-88eff2ce3e76?source=collection_archive---------12-----------------------

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

RAPIDS cuGraph 的愿景是让图形分析无处不在,让用户只从分析的角度思考,而不是技术或框架。这是我们 cuGraph 团队中的许多人已经努力了近二十年的目标。许多早期的尝试集中于解决一个问题或使用一种技术。那些早期的尝试为最初的目标工作,但是随着范围的改变(例如,转移到用静态图解决方案解决动态图问题)倾向于中断。限制因素通常归结为计算能力、易用性或选择不适合所有问题的数据结构。NVIDIA GPUs、CUDA 和 RAPIDS 完全改变了范式,加速统一图形分析库的目标现在已经成为可能。

最新的 NVIDIA GPU(RAPIDS 支持 Pascal 和更高版本的 GPU 架构)的计算能力使图形分析比 NetworkX 平均快 20 倍。此外,GPU 内部的内存速度允许 cuGraph 快速切换数据结构,以最大限度地满足分析需求,而不是局限于单一数据结构。cuGraph 正在与静态和动态图形数据结构的几个框架一起工作,以便我们总是有任何图形问题的解决方案。由于 Python 已经成为数据科学事实上的语言,允许在 Python 中进行交互和运行图形分析的能力使得 cuGraph 变得熟悉和平易近人。RAPIDS 将上面提到的所有图形分析优点与执行高速 ETL、统计和机器学习的能力结合在一起。更好的是,RAPIDS 和 DASK 允许 cuGraph 扩展到多个 GPU,以支持数十亿边图。

RAPIDS 的每个版本都附有一个或多个关于该版本特性的精彩博客(例如,参见 0.8 版博客[ 1 ]或Hadoop 后的生活)。这篇文章略有不同。虽然将讨论当前的功能,但主要焦点是展示 cuGraph 的愿景以及我们设想用户将如何与库进行交互。cuGraph 团队一直在努力提供一组丰富的初始特性。在过去的三个版本中(RAPIDS 是第一个包含 cuGraph 的版本),该团队提供了十几个算法。最初的目标是简单地发布 graph analytics,并通过熟悉的类似 NetworkX 的 API 提供。这在短期内很好,因为它提供了一条转向急流的捷径。然而,cuGraph 的开发将慢慢转向改进易用性、互操作性以及与 RAPIDS 其他部分的集成。这并不是一件容易的事情,因为 cuGraph 生态系统中还有很多东西需要添加。不要担心,推出新分析的目标将继续下去,因为有一个非常长的算法列表要发布。

属性图和高级工作流:cuDF、cuML 和 cuGraph 之间的联系

术语“属性图”自 2010 年以来一直在文献中讨论[2,3,4],最常用于在关系数据库中定义图的上下文中——我实际上在 2010 年之前构建了一个数据库支持的图系统,所以这个概念比文献更古老。更正式地说,属性图是一个有向多重图,其中每个顶点和边可以有多个属性。多重图意味着任意一对顶点之间可以有多条边。考虑一个网络,其中顶点代表服务器,每个服务器可以有多个 IP 地址(属性)。任何一对服务器之间都可以有多条边,每条边代表一个具有时间、端口和协议信息的不同连接。请参见下图。

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

A Multigraph with its DataFrame Representation

在 RAPIDS 中,属性图可以表示为数据框的集合。在简单的情况下,一个数据框用于顶点信息,另一个用于边,如上图所示。然而,多于两个数据帧也是可能的(并且是常见的)。一旦填充了属性图,就可以提取各种子图。例如,我们可以提取一个边仅通过端口 80 的子图:edge _ df = edges . query(’ port = = 80 ') 此外,我们可以使用 group_by 函数将所有的边卷成一条边。能够捕获所有属性并生成数据的不同视图的好处是属性图模型的强大。

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

Data Frame to rule them all

数据帧的概念是 RAPIDS 的核心——不仅仅是 RAPIDS 利用 Apache Arrow [ 5 ]规范通过允许零拷贝数据移动来确保流程之间的互操作性。数据帧的概念允许 RAPIDS 的所有组件交流、理解和共享数据。这是将它们结合在一起的核心概念。考虑类似上面的属性图,除了假设节点上有更多的属性——这可以是网络、社会或产品信息——并假设我们希望用图度量进一步丰富节点数据。我们可以(1)从边数据框构建一个图,然后(2)计算每个顶点的度数信息并将其添加回节点数据框。同样,(3)可以计算 PageRank 分数并加回。最后,我们可以(4)然后采用新丰富的节点数据框架,并对数据运行来自 cuML 的 K-Means,并查看数据如何聚类。这凸显了数据在 cuDF、cuML 和 cuGraph 之间移动的便利性——这都要归功于数据框架的强大功能。

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

在 Python API 层,RAPIDS cuGraph 完全支持数据帧,所有函数都接受并返回一个数据帧。CuGraph 还支持属性图,并正在努力更好地将这一概念集成到算法中。

技术和框架——静态、动态以及介于两者之间的一切

关于哪种技术是最好的:以顶点为中心的[6]还是以图形为中心的[7],在图形研究界已经争论了很多年。即使在 cuGraph 团队内部,我们也在争论哪种方法更好。但是 cuGraph 是关于分析的。cuGraph 没有选择一种技术,而是选择提供一组技术。对于任何分析,只要能提供最佳性能和可扩展性的技术都会被使用。此外,随着分析的定期更新和改进,底层技术也可能被替换掉。由于分析是通过定义良好的 API 公开的,因此任何变化(除了性能)对用户都是透明的。

在接下来的几个版本中,以下框架[ 8 ]将被整合到通过 cuGraph Python API 公开的 cuGraph 和分析中:

  • 来自德克萨斯 A&M 的蒂姆·戴维斯实验室的 GraphBLAS
  • 加州大学戴维斯分校约翰·欧文斯实验室的枪岩
  • 乔治亚理工学院的大黄蜂[ 11
  • NVIDIA 的 NV graph[12]

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

其中一些技术提供了动态数据结构,特别是动态压缩稀疏行(CSR)结构。有许多地方需要动态结构。最明显的是分析图表随时间的变化。随着数据的流入,可以监控和报告网络结构的变化。同样重要的是在分析中使用动态结构。在许多情况下,结果集的大小是未知的先验的 —例如稀疏矩阵乘法(SpGEMM)。能够即时折叠、扩展、添加和缩小图表或结果是一项强大的技术。

定制分析:原型、原语和批量同步并行

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

cuGraph 开发人员正致力于提供一个完整丰富的分析集(参见路线图部分)。每项分析都将定期重新审查和更新,以确保最佳性能。但是,在某些情况下,我们希望在完全优化之前先试用分析。在接下来的几个版本中,我们将推出一个包含样本代码和实验分析的“ proto ”模块。应该强调的是,它是实验性的。如果对该模块中的任何分析感兴趣,那么可以将其移到 cuGraph proper 中并进行优化。计划是我们将尝试分析,如果可行,然后花时间来改善分析。每份分析报告都将被定期审查和更新。更新可以通过更好的数据结构和数据移动,或者通过替换算法。该团队不断监测研究和最新技术。和以前一样,用户看到的只是更好的性能和/或可扩展性。

除了为 cuGraph 开发人员提供一个游戏区,用户还可以创建自定义分析。为了帮助促进算法开发,cuGraph 将提供一个原语集合。这些原语可以是现有的图形分析或低级功能。目标是最终将所有 graphBLAS 半环函数公开为图形原语。在 0.9 版本中,最初的原型分析之一是使用向前向后修剪方法计算强连通分量的例子。FW-BW-TRIM 执行向前的 BFS,然后向后的 BFS,然后寻找两者之间的公共集(交集)以形成一个组件。由于 BFS 算法已经是 cuGraph 的一部分,用于查找组件的原型分析在下面的代码片段中突出显示。

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

Prototype of Forward-Backward-Trim Strongly Connected Components

使用原语是构建定制分析的一种方法,另一种是通过使用数据帧和批量同步并行(BSP)编程模型。BSP [13,14]并不新鲜,它是由莱斯利·瓦里安开发的,并于 1990 年首次发表。这与 Pregel 在关系数据库中用于图形处理的基本模型相同。该过程包括设置一个值,例如每个顶点一个值,然后在所谓的“超步骤”中传播该值然后,以用户定义的方式聚集比例值,并将其指定给相关顶点。BSP 的优势在于它易于创建自定义分析,允许传播复杂的多列数据,并允许定义自定义聚合函数。缺点是速度慢。

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

Simplified BSP Example Looking just at Vertex 4

升级到 1.0 版本

急流 cuGraph 正在快速移动,并沿着多条路径运行。是的,我们打碎了东西。升级到 1.0 版意味着我们有了稳定的基础和不变的 API。我们还没有到达那里,但是我们正在接近那里。随着更多的技术进入 cuGraph,这些特性和原语是如何暴露的还没有完全具体化。此外,我们的目标不是拥有多个独立的基于技术的子路径,而是一个统一的视图。在 API 层之下,算法可以在不同的技术之间转换。为了帮助 cuGraph 更接近目标,该团队将推出一个完整的版本 0.11,专注于代码重构、组织和 API 更新。希望一个发布周期就足以重构代码,这样我们就有了一个坚实的基础来升级到 1.0 版本。

路线图总是不断变化的,所以把它当作一组目标,而不是硬性的截止日期:

发布 0.9

  • 多 GPU PageRank
  • 单 GPU 强连接组件

发布 0.10

  • 大黄蜂集成
    —卡茨中心性
    — K 核
  • Gunrock integrated
    —子图匹配【15】
  • GraphBLAS 集成
    — K 形桁架
  • nvGRAPH
  • 附加原语
  • 基础工程

发布 0.11

  • 我们正在进行一个发布周期,专注于一个主要的代码重构,以便所有的 API 都保持一致并更新到 C++。这将使我们为 1.0 版本做好准备。

发布 0.12

  • OpenCypher —简单查询
  • GraphBLAS 半环原语

未来版本…

哪个版本将是 1.0 版,目前还不知道,但 cuGraph 将准备就绪。

结论

RAPIDS cuGraph 专注于创建统一的图形分析功能,能够扩展到不同规模的问题,并根据分析需求利用不同的数据结构,同时提供数据科学家熟悉的易于使用的 API。我们当前的 1.0 版本路线图旨在为该功能奠定坚实的基础,我们打算在 1.0 版本之外进一步推进这一愿景。

如果你喜欢 cuGraph 正在做的工作,请在 GitHub 上给我们一颗星:https://github.com/rapidsai/cugraph

如果有什么你认为 cuGraph 应该继续努力的,那么就添加一个问题:https://github.com/rapidsai/cugraph/issues或者在谷歌讨论页面上开始讨论:https://groups.google.com/forum/#!forum/rapidsai

因为 RAPIDS 都是开源的,所以请跳进去写一些代码。

参考文献

  1. https://medium . com/rapids-ai/rapids-release-0-8-same-community-new-freedom-9 f 82 b 09 db 3 ad
  2. RDF*和属性图的协调。技术。众议员,http://arxiv.org/abs/1409.3288(2014)
  3. 罗德里格斯,硕士,纽鲍尔,p:从点和线的建设。Bul。我是。社会主义者信息。Sci。技术。36(6), 35–41 (2010)
  4. 伦佐的安格斯。"属性图数据库模型."AMW (2018 年)。
  5. https://arrow.apache.org/
  6. 田,y .,巴尔明,a .,科尔斯顿,S. A .,塔蒂孔达,s .,,麦克弗森,J. (2013)。从像顶点一样思考到像图形一样思考。VLDB 基金会会议录,7(3),193–204。
  7. Bader,d .,Bulu,a .,Gilbert,j .,Gonzalez,j .,Kepner,j .,& Mattson,T. (2014 年 7 月)。图爆破工作及其对亿亿级的影响。在 SIAM exa scale 应用数学挑战与机遇研讨会上 (EX14)
  8. https://news . developer . NVIDIA . com/graph-technology-leaders-combine-forces-to-advance-graph-analytics/
  9. http://faculty.cse.tamu.edu/davis/GraphBLAS.html
  10. https://gun rock . github . io
  11. https://github.com/hornet-gt/hornet
  12. https://developer.nvidia.com/nvgraph
  13. Leslie G. Valiant,并行计算的桥接模型,美国计算机学会通讯,33 卷 8 期,1990 年 8 月
  14. 麦科尔,W. F. (1994)。可扩展并行计算:一个宏大的统一理论及其实践发展。《IFIP 世界大会议事录》(第一卷,第 539-546 页)
  15. http://www . hpdc . org/2016/Posters/poster/O13-hpdc 16 _ Posters _ paper _ 17 . pdf

4 种很少教授的数据科学技能,这是你应该学习的

原文:https://towardsdatascience.com/rarely-taught-data-science-skills-that-you-should-look-to-acquire-ebb1a09520e4?source=collection_archive---------25-----------------------

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

什么是难以获得的数据科学技能,为什么你应该寻求获得它们

数据科学家短缺,随之而来的需求是培养越来越多的数据科学家。这越来越多地发生在课堂上,但很大一部分实践数据科学家仍然是自学的(在最近的 Kaggle 研究中,超过 1/4)。终身学习也很重要,无论你是受过正式培训的数据科学家还是自学,你都将继续学习,并将依靠 MOOC、教科书和其他自学的组合来完成。

因此,随着所有这些学习的发生,为了未来和现在的数据科学家的利益,有哪些专业技能是知道起来很重要但很难教授的?现实生活中的数据和理论上最大的差距在哪里?这里有 4 个领域不太可能被熟练地教授,但却是您在工作中取得数据科学成果的成功和能力的关键部分。

获取和清理数据

我向你保证一件事。在现实世界中开始一项数据科学实践,并不需要点击一个链接,下载一个 CSV 文件,然后继续你的快乐之路。这比要复杂得多(也耗时得多)

首先,您很可能需要找到您想要使用的数据源,并开始将数据拼接在一起,以形成类似于您希望使用的东西,然后进行广泛的练习,以确保数据是干净的和可用的。与此同时,您将会理解那些可能被用来创建您并不立即熟悉的特性的业务规则,以确保您正确地使用它们。除此之外,你可能想做的任何特征工程、插补和进一步的附加动作,很可能你已经花费了整个项目相当多的时间,只是在做准备。

要做到这一点,需要商业、技术和软技能的结合,还需要一点想象力,这些技能很难教授。绝对不要低估你将要做的数据准备和来源工作——以及在这方面的出色表现是如何帮助你完成剩下的工作的。

管理工作流程

为了大多数教学指南的完整性,使用一种编程语言或工具解释数据科学过程,不偏离所述工具。这给人的印象是,所有事情都可以而且应该在一个工具内完成。这当然是可能的,但不太可能有效。

为了提高效率,在数据科学过程的各个阶段,您很可能会从一个工具跳到另一个工具。你将在一个独立的工具中做你的 EDA,这个工具不同于你准备数据的工具,也可能不同于你用于可视化的工具。了解哪些工具适合您和您的组织,以便在最短的时间内实现您想要的最终结果,这是数据科学中的基本技能之一,但很少有人教授。不依赖工具,专注于快速操作,重点是实现可操作的结果。

讲故事和用数据来影响

尽管一些课程涉及一些基本的可视化技术,但很少有人真正谈到如何将数据科学成果与业务成果联系起来,以及如何有效地与非技术受众沟通,尽管这经常被认为是一项关键的数据科学技能。

你如何向不关心损失矩阵、置信区间等的观众传达你创造的结果?本质上,这是学习“软”沟通技巧和学习如何通过有效的演示技巧(以及有效的利益相关者管理)来演示和影响决策者的结合。

我会在后面的文章中详细讨论这个问题,但是我会说两件你可以马上做的事情,让你在这个领域变得更加有效。

学习如何进行财务预测,以确定你的模型所产生的洞察力的未来价值-

学习如何对你产生的任何见解进行财务预测,然后以此为手段对这些见解进行优先排序——这是一个非常有效但很少使用的工具。在展示之前,对你所做的工作进行估价——直接与你的商业利益相关者沟通——直接说出商业决策的语言。

如果你对使用商业预测模型感到不舒服,至少联系你组织内的商业团队成员,让他们模拟出实施你产生的任何可操作的见解对业务的价值。

例如,如果您正在为您的营销团队部署一个算法归因模型,该模型允许他们脱离最后一次点击/线性/或首次点击归因模型,请尝试找出这在 ROI 提升方面可能带来的价值,通过与以前的方法相比,为您的团队做出更好的预算分配决策。或者,部署的 NLP 模型能让您的员工团队在执行机械任务时节省多少时间?那这段时间又转化成了什么价值呢?

这并不容易,它需要不时地做出有根据的假设,然而,即使是预测值的“背面”草图,也比什么都没有好,并且在弥合数据和商业团队之间的差距方面大有帮助。

利用建筑来讲述故事。

讲述你所承担的过程背后的故事将有助于你的利益相关者理解和欣赏你的工作。这应该在宏观(“我有这个问题,我想用这个数据集来解决,我使用的方法是这样的,这使我能够实现这些结果……”)以及微观层面上完成。

在微观(洞察力)层面,使用构建可能是有效的。构建本质上是构建一个故事来传达单个数据洞察的信息,通常是通过对同一个图形/视图进行小的渐进调用来完成的。

假设您做了一个(客户)聚类练习。你的第一张幻灯片可以是你必须开始的所有数据点的散点图。第二个是在第一个基础上的可视化构建,显示已确定的关键集群。然后,您可能会有几张幻灯片放大到每个集群并查看每个集群的特征,然后在一个可视化(而不是图形化)视图中显示所有结果,在此视图中,您可能会进一步将您已经确定的集群人性化(比如给它们一个角色)。

利用构建,本质上允许你逐步揭示信息,并围绕你的见解编织一个故事,引导你的观众得出结论,而不仅仅是将数据堆砌在上面。

简而言之,洞察力层面的故事将会是这样的:“我有这些数据,我能够发现这些数据,因为这些数据是相关的,并且可以通过这样做来采取行动……”

良好的文档是良好团队合作的关键

问问你自己。你如何记录工作,如何使你的工作容易被未来的团队成员复制?你如何捕捉你的学习,以便它们可以被缩放并用作未来分析的基础?

你很可能会作为团队的一员工作,所以要成为最终的团队成员,通过好的文档让人们的(工作)生活更容易。
即使在几个月前,它也不会出现在我的列表中,但我认为它对数据科学家越来越重要。原因?有效性。

如果我要说什么的话,那就是数据科学家会选择阻力最小的有效途径。那么,拥有好的文档如何让你更有效率呢?

良好的文档使您能够

  • 向技术受众清楚地传达您的信息和方法(从而最大限度地减少理解方法和结果所花费的时间),允许交叉协作和快速提升技能。我上面提到的宏观讲故事——但是直接对你的同事和直接的团队成员讲
  • 潜在地使代码(或部分代码)可被那些希望采用类似方法或使用类似数据集的人重用。例如,如果您已经在第一时间清楚地记录了数据,为什么还要清理两次呢?
  • 向上管理。有喜欢关注细节的经理吗?通过组织你的想法和记录你的方法,让他们的工作更容易,节省你和他们的时间。

我在这里提倡的文档不仅仅是注释代码。本质上,你想要展示你所承担的过程和你所取得的结果。这里的愿景是,你将使用 Jupyter 笔记本或 R Markdown 来追溯描述你采取的步骤和你使用的方法。追溯是关键,因为当你在工作时,你在快速优化结果。这需要回顾和反思你所取得的成就,并为了他人的利益而记录下来。

在这样的文档中,会有直接从您的工作环境中提取的代码片段(包括已经注释的代码),现在您只需添加富文本元素来添加进一步的上下文。这种文件至少应包括:

  • 介绍
  • 问题的描述
  • 数据集的描述
  • 您使用的方法:
  • 准备数据的方法
  • 为获得结果而采取的机器学习/统计分析方法
  • 结果呢
  • 基于结果的建议

一旦你有了文档,它的读者是你团队中的其他技术人员,他们可能希望复制结果,从他们那里学习,或者利用他们做类似的事情。把它归档,加入你的文件夹。

结论

因此,如果你还在上大学,或者正在学习新技能以补充现有技能,请留意这些技能是如何获得的,在你的同龄人圈子中谁做得好,并开始模仿他们的行为,同时尝试你自己的各种技能,并将它们融入你自己的技能组合中。并非每项数据科学技能都可以教授,通常那些难以获得的技能会产生很大影响。

这个故事最初发表在这里

老鼠城:可视化纽约市的老鼠问题

原文:https://towardsdatascience.com/rat-city-visualizing-new-york-citys-rat-problem-f7aabd6900b2?source=collection_archive---------3-----------------------

你的邻居也是老鼠的热点吗?

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

Check out the interactive rat sighting map here: https://nbviewer.jupyter.org/github/lksfr/rats_nyc/blob/master/rats_for_nbviewer_only.ipynb

介绍

如果你曾经在纽约待过很长时间,你很可能会遇到老鼠。不管你是在等地铁还是在华盛顿广场公园散步,你碰到老鼠的几率都很大。如果你来自纽约,这些对你来说都不陌生。为了让其他人更好地理解这个问题有多严重,这里只是收集了一些快速的事实:

  • 有一篇维基百科文章详细介绍了这个问题。你所在的城市有没有关于老鼠的维基百科文章?
  • 根据这篇文章用统计方法捕捉的老鼠数量,纽约市大约有 200 万只老鼠。
  • 纽约市鼓励市民在看到老鼠时拨打 311。该市非紧急热线对老鼠的重视表明了这个问题的重要性。

众所周知,老鼠会传播致命疾病,因此对公众健康构成了严重威胁。除此之外,他们也是众所周知的负责电缆断裂,可能会导致火灾。因此,如果你住在纽约市,你肯定会想避开老鼠密集的街区甚至更小的区域。与此相反,纽约市最有可能希望在这些特定区域加大灭杀力度。问题是:你如何识别这些区域?

鼠迹的发展

在回答这个问题之前,让我们来看看这个问题在过去几年的历史。对于这篇文章,我依赖于纽约市提供的这个数据集,详细列出了从 2010 年 1 月到 2017 年 9 月的所有老鼠目击事件。在这段时间里,有 101,914 起报告的老鼠目击事件。虽然这已经是一个很高的数字,但实际看到老鼠的数量可能要高得多。仅在纽约期间,我就目睹了几次我没有报告的老鼠目击事件。然而,我们可以看看这些年来老鼠出现的数量的发展,看看这个城市消灭老鼠的努力是否有成效。

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

正如我们所看到的,2013 年,老鼠的数量有了转机,开始显著增加。2010 年有 10,452 起老鼠目击事件,而 2017 年有 17,080 起。这大约增加了 63%!尽管 2017 年似乎有所下降,但人们必须记住,2017 年的数据集截至 9 月,不包括 10 月、11 月和 12 月。数据似乎表明,老鼠数量增加了,或者老鼠进入了它们能够更频繁地与人类接触的区域。不管怎样,这都是一个令人担忧的发展。

让我们按社区来分析一下,看看在纽约市哪个地区老鼠最多。

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

显然,至少自 2010 年以来,布鲁克林一直是老鼠出没最多的地区。注:这里的纽约是指曼哈顿。另外,对于没有去过纽约的人来说:牙买加不是指加勒比海的牙买加岛,而是指牙买加皇后区。

在跳到我们的地图可视化之前,了解更多关于目击地点类型的信息也是很有趣的。大多数老鼠可能只在有很多机会隐藏和很少人类活动的地方被发现,例如建筑工地。对吗?不对。看一看:

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

大多数老鼠目击报告发生在 3+家庭公寓大楼。建筑工地在这份名单上仅排在第七位。另一个有趣而可怕的统计数据是,在大约 7 年的时间里,有 82 起医院里发现老鼠的报告。

地图可视化

对于我的热图可视化,我依赖于 2017 年报告的老鼠目击事件,因为这些是该地区潜在老鼠活动的最新指标。

曼哈顿下城

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

为了可视化鼠迹的密度,我使用 Python 包 follow 在传单地图上创建了热图。在曼哈顿下城看一看,似乎有一些老鼠热点,尤其是在东 2 街至东 6 街和 B 大道至 d 大道的区域。总体而言,汤普金斯广场公园周围的区域显示出非常高的老鼠目击密度。

市中心区

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

总的来说,市中心似乎没有曼哈顿下城那么拥挤。这里的热点包括 23 街和 28 街之间的区域以及地狱厨房的某些部分。

上东区和上西区

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

在这里,上西区似乎明显比上东区鼠患更严重。具体来说,100 号街以上和哥伦比亚大学以东的区域显示出高密度的鼠迹。

哈莱姆

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

除了西 133 街和 142 街之间的 Adam Clayton Powell Jr .林荫大道周围的区域,哈莱姆区一般不会出现具体的鼠迹。

布朗克斯区

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

布朗克斯区的老鼠出没密度相对较高。有趣的是,在布朗克斯区的西部似乎比东部更容易看到老鼠。

布鲁克林区

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

虽然在布鲁克林高地和威廉斯堡看到的老鼠相对较少,但特别是贝德福德-斯图文森和皇冠高地的部分地区似乎是大量老鼠的家园。

昆斯区

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

皇后区也没有显示出非常具体的模式。然而,如之前柱状图所示,老鼠密度最高的地区是牙买加。

结论和更详细的探索

如你所见,老鼠是纽约市的一个大问题。了解大量人口在哪里是试图减少他们的数量和降低他们造成的公共健康风险的第一步。

如果你有兴趣了解你自己的街道或你下次来纽约时要住的酒店所在的区域,请点击这里。我在 nbviewer 上托管了一个笔记本,可以让你交互使用热图。

参考资料:

[1]奥尔巴奇,乔纳森,纽约市的老鼠真的和人一样多吗? (2014),威利在线图书馆

[2]纽约市,纽约市老鼠目击事件 (2017),卡格尔

[3]布拉德利,瑞安,纽约的老鼠路径;城市里的动物如何到达它们要去的地方。 (2015),纽约时报杂志

[4] Frye,M. J .等人,纽约市挪威鼠体外寄生虫和相关病原体的初步调查,《医学昆虫学杂志》

根据“酒吧分数”对伦敦房产进行评级:伦敦房产市场的另一个视角

原文:https://towardsdatascience.com/rating-london-properties-by-their-pub-score-an-alternative-lens-on-the-london-housing-market-ed5524304014?source=collection_archive---------7-----------------------

我想很快买栋房子。

这是这个项目的亮点。我开始在各种房地产网站上寻找,虽然网站上的信息很棒,但我觉得如果我能掌握用于填充这些网站的数据,我就能以一种更数据驱动的方式来寻找房子。

本文共分五个部分:

  1. 获取住房数据
  2. 电子设计自动化(Electronic Design Automation)
  3. 可视化数据
  4. 在地图上绘制数据
  5. 计算有趣的指标,比如从每个房子工作的时间,以及每个房子的酒吧分数

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

出于各种原因,在整篇文章中,我不打算命名我想从中获取数据的站点,所以我将它称为“站点”。

步骤 1:获取并清理数据

这将是一项网络搜集工作,看起来绝不容易。由于网站的结构,每次您进行属性搜索时,您被限制在每页 25 个属性。更重要的是,如果你的搜索区域太大,你可以选择的页面数量被限制在 42 个(这在类似的项目中出现过几次——如果有人知道为什么,我会很感兴趣!)

有趣的事实——数字 42 是“生命的意义是什么”这个问题的著名答案在银河系漫游指南中。但这是为什么呢?有趣的是(或者不是),数字 42 有 ASCII 码*,在编程中是“全部”或“一切”的意思。

因此,我最初只限于在一个区域内寻找房产——Bermondsey。我想利用我的 LISA,所以房产的价值必须小于 450,000,这将我的搜索范围缩小到一个不错的数量。

一个简单而有效的组合,美丽的汤和请求,我有一个在我的搜索标准内的每个属性的链接列表。然后我遍历链接列表,再次使用 Beautiful Soup 和 Requests 来解析来自所述链接的信息。为了不给网站带来太多压力,我在每次请求之间留出了 5 秒钟的延迟。获取价格的简单代码如下所示:

def get_soup(url, params=None):
    r = requests.get(url, params=params)
    c = r.content    
    soup = BeautifulSoup(c, 'html.parser')
    return(soup)descriptions = []for index, row in listing_df.iterrows():
    url = row['property_link']
    time.sleep(5)
    soup = get_soup(url)
    price.append(soup.find('div', attrs={'class':'propertyHeaderPrice'})

这太棒了,非常有用——我可以获得详细信息,如添加的日期、房间数量、物业类型、价格、最近的车站等。

将它保存为一个 csv 文件/到一个数据库中,将这个脚本放到一个调度器中,你就可以开始了。

然而,我不满足于只获得伦敦某个特定地区的数据,哦,不。我想要所有的数据,主要是为了在一段时间内获得某种伦敦平均房地产价格跟踪器,以及比较整个伦敦的各种指标。

问题是双重的:

  • 我不能简单地搜索整个伦敦,因为这将产生太多的结果来迭代,我将无法获得超过 42 页的价值
  • 我不想逐一查看伦敦的每一处房产。网站上列出了“伦敦”某个区域内大约 25,000 处房产,我不想通过提交 25,000 个 get 请求就让他们的网站瘫痪。

我开始思考如何将搜索过程分解成更小的块,以便能够在不到 42 页的页面中查看每个块的所有属性。我最初的想法是行政区,尽管已经运行了一个脚本来获取每个行政区的属性数量,但是相当多的行政区有太多的属性。

然后我查看了地区,所以您的邮政编码的第一个字母在空格前,例如 SE8、EC2V、E1 等。原来只有 CR0(克罗伊登中心)的房产太多了,所以我觉得这是可以接受的(不确定我是不是反正要住在克罗伊登……)。

第二个问题是提交 25,000 个请求,所以我试着从一次显示 25 个属性的摘要页面中获取尽可能多的每个属性的关键信息。如果成功,这将把请求的数量减少到 1000 左右。

大多数关键信息都在那里,除了经度和纬度。幸运的是,该网站有一个“查看地图”功能,我认为必须有坐标,以准确地绘制每个属性。这个 map 视图一次允许 500 个属性,这不成问题(除了 Croydon ),而且在页面源代码的某个地方包含了机器可读的格式。这意味着,对于每个地区,我所要做的就是遍历结果的每一页以获得大部分细节,然后稍微更改 URL 以访问地图源代码,在 Beautiful Soup 和 JSON 的一点帮助下,我可以从中解析坐标。

幸运的是,每个属性都有一个唯一的标识符,所以两个数据集很容易匹配。

但是克罗伊登呢。虽然不确定我是否想住在克罗伊登,但我内心的完美主义者想要一个完整的数据集。结果发现只有不到 42 页,所以获取大部分数据相对简单。然而,地图上一次只允许显示 500 个属性,这就产生了一个问题。幸运的是,在放大/缩小时检查了 url,我意识到我可以在请求地图 url 时使用 viewport 参数,有效地将 Croydon 一分为二。经过大量的工程设计后,克罗伊登又重操旧业。

在调度器上完成这个任务后,我所要做的就是等待(这个过程总共运行了大约 1 小时 15 分钟)。

第二步:EDA

获得并清理数据后,它看起来像这样:

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

这一切都很好,但如果你像我一样,你是一个视觉型的人,所以我决定制作一些图表。

第三步:最初的观想

Matplotlib

一旦你掌握了它的窍门,Matplotlib 就非常棒,可以合理有效地用来制作一些基本的图表,例如:

  • 直方图

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

  • 条形图

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

  • 折线图

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

查看这些图表,有一些有趣的地方,例如在我的搜索范围内,伦敦的两张床的房产比任何其他大小的房产都多,而且似乎有一些围绕房产价格整数的聚类。

再做一点工作,你就可以画出每个地区每个房间大小的房屋数量/百分比:

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

我想了解的事情之一是每种房屋类型的价格如何变化,如套房、公寓、联排别墅等。在绘制该图时,似乎有相当多的房屋类别:

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

这需要我构建一个映射函数来映射到父属性类型。我拥有的财产类型有:

property_types_to_match = ['apartment',
 'barn conversion',
 'block of apartments',
 'chalet',
 'character property',
 'cluster house',
 'coach house',
 'cottage',
 'detached house',
 'duplex',
 'end of terrace house',
 'flat',
 'ground floor flat',
 'ground maisonette',
 'house',
 'link detached house',
 'maisonette',
 'manor house',
 'mews house',
 'penthouse',
 'property',
 'semi-detached house',
 'terraced house',
 'town house']

我决定我想匹配的是:

['apartment',
 'duplex', 
 'house',
 'maisonette',
 'other']

首先,我很好奇在我的价格范围内有没有“庄园”或“小木屋”。第二,幸运的是,pandas 有一个方便的“map”函数,我将一个属性类型字典放入其中,以映射父属性值。按母公司分组,并绘制价格和数量图,我们可以看到,套房是最便宜的房屋类型,而“其他”类别是最贵的。这里出售的公寓也比伦敦其他任何类型的房产都多:

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

这些类型的图表非常适合显示一些高级趋势,但我想看看是否有更好的方式来呈现数据。

我的下一个想法?

人人都爱地图

第四步:地图

输入 leav 和 geopandas。每个在映射数据中有不同的位置:

  • Folium 使您能够创建基于缩放级别进行聚类/去聚类的交互式地图
  • Geopandas 允许您按地理区域绘制数据框中的数据

我们先来看看叶子:

不可否认,安装叶子有点麻烦,但绝对值得。安装完成后,使用下面的三行代码导入它的一些特性:

import folium
from folium.plugins import MarkerCluster
from folium.plugins import FastMarkerCluster

从这里开始,创建地图非常简单,因为您有一个带坐标的数据框架:

# simple marker map
london_map = folium.Map(location=[51.4986, -0.0691],
                    zoom_start = 10)
for index, row in london_df.iterrows():
    folium.Marker([row['latitude'], row['longitude']], popup=row['address'])).add_to(london_map)# standard cluster map
london_cluster_map = folium.Map(location=[51.4986, -0.0691],
                    zoom_start = 10)
london_cluster_map.add_child(MarkerCluster(london_df[['latitude','longitude']].values.tolist()))# fast cluster map
london_fast_cluster_map = folium.Map(location=[51.4986, -0.0691],
                    zoom_start = 10)
london_fast_cluster_map.add_child(FastMarkerCluster(london_df[['latitude','longitude']].values.tolist()))

简单的标记图只是在每个属性位置绘制一个标记,而标准和快速聚类图引入了某种按位置的聚类。区别在于功能——标准聚类图允许您包含弹出窗口等。而快速聚类图不会。话虽如此,对于超过 25,000 个点,标准聚类图的绘制时间太长,所以我选择了快速聚类图,对于伦敦,它看起来有点像这样:

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

不幸的是,我不知道如何将交互式地图嵌入到媒体文章中,所以静态图像就可以了。放大后,看起来像这样:

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

你必须承认,如果你像我一样是一个数据呆子,这很酷。任何形式的交互都让我着迷——也许这就是我在编码生涯开始时对 Excel 感兴趣的原因。

好了,现在我们来看一下地质公园

为了充分利用 geopandas 包,我需要获得伦敦各区的形状文件。幸运的是,来自英国伦敦政府数据网站的数据(https://data . London . gov . uk/dataset/statistical-GIS-boundary-files-London)和其他各种开放数据集的组合使这一数据很容易获得。

同样,奇怪的是,安装 geopandas 有点痛苦,但一旦完成,只需导入它并读入您的形状文件:

import geopandas as gpddistrict_shape_file = 'london_postal_districts.shp'
map_df = gpd.read_file(district_shape_file)

这将为您提供一个标准的熊猫数据框架,但会识别形状文件中的几何图形,并为您提供如下内容:

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

我们需要做的下一件事是与您的其他数据集的按地区分组版本相结合,下面是一个示例:

map_df = map_df.set_index('postdist')mean_district_price = london_df.groupby('district')['price'].mean()
mean_district_price_df = pd.DataFrame(mean_district_price)
mean_district_price_df = mean_district_price_df.reindex(district_list, fill_value=mean_district_price_df['price'].max())map_df = pd.concat([map_df, mean_district_price_df], axis=1)

太好了,我们准备好开始策划了。如果您简单地使用下面的’ map_df.plot()',您将得到这些地区的轮廓,这是令人放心的:

fig, ax = plt.subplots(figsize=(16,9))map_df.plot(ax=ax)
ax.set(title='districts')plt.show()

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

绘制每个区的房产数量告诉我们与 matplotlib 图表中的数据相同的信息——克罗伊登比其他任何区都有更多的房产:

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

这本身并不是一个非常有趣的情节。

在我看来,有趣的情节是:

  • 每个区的平均房价,这告诉我,在这个城市或里士满的任何地方,我都买不起:

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

  • 挂牌出售的房产数量与各区内的房产总数之比,显示了各区内的住宅房产开发水平:

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

酷,现在我有了一些很酷的图表和地图,接下来呢…

当我评估一所房子是否在一个好的位置的时候,我寻找什么其他的东西?

第五步:用更多的数据重复

交通联系。

太好了,到 TFL 网站,那里有一个文件包含网络上所有电台的纬度/经度。接下来,我想尝试找到离我的数据集中的每个属性最近的三个站点,以及它们离属性的距离。

首先,我看了看距离:

由于地球的曲率,我不得不使用哈弗辛公式(【https://en.wikipedia.org/wiki/Haversine_formula】)来计算两组坐标之间的实际距离。

这在 python 中的快速实现如下所示:

def haversine(lon1, lat1, lon2, lat2):
    # convert decimal degrees to radians 
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2]) # haversine formula 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a)) 
    r = 3956 # Radius of earth in miles= 3956\. kilometers = 6371
    return c * r

现在,对于下一点,我知道有一种更快、更有效的方法来计算最近的 3 个站,但我不太清楚,所以我有效地在站和属性之间做了一个相当大的交叉连接:

no_properties ~ 25000
no_stations ~ 400
no_calculations = 400 * 25000 = 10,000,000

这就是 1000 万次计算,在我的机器上大约需要 12-13 分钟才能完成。如果有人有更有效的计算方法,请告诉我!

无论如何,在计算了到每个站点的距离后,我取了 3 个最小值,瞧,你得到了到三个最近站点的距离。

为了扩充这个数据集,我还使用 Google Distance Matrix API 来获取每个酒店的上下班出行时间。Google 让你免费拥有一定额度的积分,太棒了!对 API 的请求如下所示:

coords = list(zip(london_df['listing_id'],london_df['latitude'].tolist(),london_df['longitude'].tolist()))
responses = []
for id, lat, long in coords:
    url = '[https://maps.googleapis.com/maps/api/distancematrix/json'](https://maps.googleapis.com/maps/api/distancematrix/json')
    params = {'units':'imperial',
              'origins':str(lat) + ',' + str(long),
              'destinations':work_lat,work_long,
              'mode':'transit',
              'arrival_time':epoch_time,
              'key':google_routes_API_key}
    r = requests.get(url, params=params)
    response_json = r.json()
    responses.append(response_json)
responses_dict = dict(zip(london_df['listing_id'].tolist(),responses))

好的,传输指标达到。接下来呢?

酒馆。

每个人都喜欢好的酒吧,特别是当它有很好的啤酒/葡萄酒可供选择时,当它近到足以让你蹒跚而归,但又足够远到当你想睡觉时不会让你睡不着。

我偶然发现了整个英国的 POI 数据集,其中包含了英国几乎所有景点的纬度和经度,包括酒吧、文具店、电影院等。这是一座金矿,所以我仔细检查并提取了“酒吧/餐馆”类别中的所有兴趣点。我知道这包括餐馆,这有点令人沮丧,因为我真的不在乎我是否离芥末/nandos 那么近。但也只能这样了。

幸运的是,和 lat/long 一样,数据集也包含邮政编码,所以我接着检查并找到了包含在我有数据的地区内的所有酒吧(总共 298 家)。这相当于 1400 家酒吧。

对于每个酒吧,我想找到一个衡量“酒吧有多好”的标准——重新输入谷歌。谷歌有一个“地点”API,允许你输入世界上任何一个地方的名称/地址,它会尝试返回它在极其庞大的谷歌地图数据库中拥有的关于所述地方的各种数据。该查询如下所示:

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

不幸的是,我的数据集在不同的列中有一些缺失的/NaN 值,所以需要进行一些清理。例如,如果酒吧在 name 列中有一个 NaN 值,我就用母公司的名称来替换它,比如’ Wetherspoons ‘或’ O 'Neils '等。然后,我通过 places API 运行这些酒吧,并能够获得我的数据集中 99%的酒吧的各种指标,其中最重要的是平均评论评级、评论数量和价格水平。

我决定需要计算三个测量值来获得每栋房子的“酒吧分数”。这些是:

  • 附近酒吧的质量
  • 邻近的酒吧
  • 附近酒吧的数量

我还决定查看每所房子 1 英里内的酒吧,因此再次使用哈弗辛公式在酒吧和房子之间进行了相当大的交叉连接,以获得距离。然后,我只将每家酒店 1 英里范围内的酒吧作为单独的数据集,从中获取每家酒店的酒吧指标。

酒馆质量评分。

这只是简单地计算出每家 1 英里范围内酒吧的谷歌评分平均值。然后对所有酒店进行标准化,这样,靠近最低评级酒吧的酒店得分为 0,靠近最高评级酒吧的酒店得分为 1。

酒吧接近度得分。

这有点棘手。我认为 300 米是远离酒吧的最佳距离,因为它在磕磕绊绊的距离内,但应该足够远,不会听到任何深夜噪音。为了计算分数,我从每个距离测量中取 300 米,因此如果一个酒馆在 300 米之外,它将得到 0 分。然后我取了这个值的模,确保 300 米内的所有酒吧和更远的酒吧受到相同的惩罚。然后对每栋房子 1 英里范围内的酒吧进行平均,并对我的数据集中的所有酒店进行标准化。

酒馆数量评分。

这可以简单地计算为每栋房子 1 英里内的酒吧数量,并根据数据集中的所有属性进行归一化。

酒吧总分。

为了将这些计算出来的指标汇总成一个“pub 分数”,我必须考虑哪个值对我来说最重要。靠近一家评级最高的酒吧比靠近 5 家评级很差的酒吧好吗?我假设是的。

因此,我决定重要性的顺序是质量,接近度,数量。

为了计算得分,我使用了 2 个质量权重、1 个接近度权重和 0.5 个数量权重,并将它们汇总如下:

(2 倍标准化质量)+ (0.5 倍标准化数量)——(标准化接近度)

出于兴趣,我还使用了 rank 函数,这样我就可以根据 pub 分数查看数据集中排名最高和最低的属性。

为了将这些数据可视化,我将它们全部转储到一个 geopandas 数据框架中,并使用了方便的 shapely 函数" point" ",该函数将经纬度坐标转换为实际的可绘图点。我还决定要根据总分的值改变颜色,所以我使用了 matplotlib.colors 中非常方便的 LinearSegmentedColormap 函数和“plot”函数的“cmap”参数。好了,描述它没有用,下面是代码:

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

由此产生了以下情节:

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

当与先前导入的地区地图文件结合使用时。这表明,Streatham/Dulwich/Croydon 周围的地区是购买房产的最佳地点,如果你只关心酒吧的话…

我还绘制了数据集中一些地区的分布图,这些分布图显示,中央克罗伊登的房产得分差异很大,而诺丁山(W2)等地的房产得分似乎更高。这里,n 对应于数据集中每个区内的房产数量:

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

下一步:

  • 研究如何更有效地找到最近的“x”点
  • 查看学校/集水区的数据,以及这些数据与价格的关系
  • 研究用 python 绘制旅行时间等值线——任何想法都很好!

希望你觉得这很有趣!

给运动队评分——Elo 与输赢

原文:https://towardsdatascience.com/rating-sports-teams-elo-vs-win-loss-d46ee57c1314?source=collection_archive---------7-----------------------

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

Photo by Ariel Besagar on Unsplash

哪个更好?

介绍

在任何一项运动中,有许多方法可以决定谁是最好的团队或运动员。可以看看最近 5 场。最近 10 场比赛。你可以使用分数差。您可以根据哪些团队“感觉”最好来对他们进行评级。你可以看看花名册,看看哪个队有汤姆·布拉迪或詹姆斯。无论是权力排名,部门排名,还是其他什么——有科学的方法来评估团队,也有不科学的方法。以下是科学地决定一个好的分级系统的尝试。

什么是 Elo 评级?

首先,我觉得我打不过 538 对 Elo 的透彻描述。维基百科的页面也挤满了有用的信息。不过,我会简单介绍一下。

Elo 评级系统是一个非常简单却非常有效的评级系统。它最初是为国际象棋开发的,但没有什么是国际象棋特有的。Elo,以其原始形式,可以用于任何面对面的游戏。掰手腕、拼字游戏、乒乓球,应有尽有。人们也可以把团队,比如篮球队,看作是互相对抗的“玩家”。

每个玩家或团队都有自己的 Elo 等级。惯例是新玩家从 1500 分开始,但是 1500 分有点武断。当两名玩家玩游戏时,他们会在游戏开始前自动“下注”他们的 Elo 点数。这个赌注的大小被称为 K 值。胜者在比赛结束后获得分数,败者在比赛结束后失去分数。奖励的点数取决于初始评分的相对差异。举例来说,如果一个 1700 技能的玩家击败了一个 1300 技能的玩家,没有多少点数被奖励——这个结果是意料之中的。另一方面,如果 1300 级玩家击败 1700 级玩家,则几乎整个下注点数池都被奖励给 1300 级玩家,并从 1700 级玩家中扣除。

K 值或下注点数取决于游戏。在像棒球这样的运动中,K 值会很小。即使是最好的棒球队也很难赢得超过 70%的比赛。此外,他们在 MLB 打了 162 场比赛。所以,如果 MLB 最好的球队连续输了三场比赛,这可能没什么大不了的,他们仍然可能是联盟中最好的球队。你不想要一个大的 K 值,否则 Elo 评级会对连败反应过度。然而,在 NFL 或大学篮球赛中,最好的球队有望赢得 80%以上的比赛。在 NFL,也有一个小样本量。在这种情况下,允许更不稳定的 Elo 评级是可取的——一个 3 连败的球队可能不是联盟中最好的球队。此外,在短暂的一季中,您希望收视率快速调整。

如果我们对预测比赛结果感兴趣,Elo 评级是强有力的预测工具。它们甚至比输赢记录更有预测性,接近预测市场。这是假设你有一个好的 K 值。一旦你对 Elo 评级有所了解,你就能猜出好的 K 值。这篇文章的目的是给你一个达到最佳状态的科学方法。

一项实验

我声称 Elo 分数比输赢记录更能描述一个球员或球队的技术。我们不要认为这是理所当然的。首先,为了证明这一点,我将设计一个抽象的游戏,其中一些玩家比其他人更好,让他们互相玩。玩家将有一个输赢记录和一个 Elo 等级。然后,我们将能够在友好的环境中比较这些评级。在以后的文章中,我将使用容易获得的运动数据,看看这个过程在现实世界中是否可行,而不仅仅是一个友好的实验。这个实验的代码可以在我的 Github 页面上找到。

友好、可控的示例

在现实世界中,有一些 Elo 没有考虑到的复杂问题。比如一支球队会在休赛期选秀球员,变得更好或者更差。如果一个明星球员被交易或者受伤了,Elo 是不知道的。所以让我们设计一个没有混乱复杂情况的游戏。

运动球

有一种新游戏叫做运动球,一个由所有最好的运动球运动员组成的大联盟刚刚成立。来自世界各地的球迷都会去看他们最喜欢的运动球队。大联盟运动球有 32 名球员,球员总是在他们来自的城市之间的中点打球(以抵消主场优势)。虽然售票处不喜欢这一举措,但计算 Elo 收视率的人喜欢。

为了模拟真实能力,每个玩家都会有一个“真实等级”。当两名运动员比赛时,一个随机变量将被添加到真实评分中,这样较弱的队伍可以击败较好的队伍。否则,这将是一个无聊的实验。随机变化基本上是一种模拟运气和玩家当天感受的方式。

最后,为了模拟随时间的变化,每个玩家的真实评分将在每场比赛后随机调高或调低。赛季输赢记录将无法适应这些变化,但 Elo 将能够做到。这给了 Elo 一个在现实世界中也会有的优势。在 1000 个游戏赛季结束时,我们将比较真实评级、输赢记录和 Elo 分数。

密码

让我们首先创建一个玩家类来跟踪所有这些属性。

class Player(object):
    """Player Object"""
    def __init__(self, name, rtg, elo, nudge):
        super(Player, self).__init__()
        self.name = name # true rating
        self.rtg = rtg # elo rating
        self.elo = elo # wins, losses, ties
        self.wins = 0
        self.losses = 0
        self.ties = 0
        self.games_played = 0 # how much to nudge ratings
        self.nudge = nudge def nudge_rating(self):
        # decide to nudge up or down
        direction = random.randint(0,1)
        if direction == 0:
            self.rtg += self.nudge
        else:
            self.rtg -= self.nudge def add_win(self):
        self.wins += 1 def add_loss(self):
        self.losses += 1 def add_tie(self):
        self.ties += 1 def played_game(self):
        self.games_played += 1

我喜欢设置一个 settings.py 文件,方便调整参数。因此,让我们为我们的实验创建一些基本设置。

season_settings = {
    # the way it's coded, it must be even number of players
    'num_players':32,
    'num_games':1000,
    # average ratings for the teams
    'avg_rtg':100,
    # standard deviation of ratings (higher -> more difference in player skill)
    'std_dev': 5,
    # game by game variation amount:
    'game_var':7.5,
    # after each game, how much does the true rating change?
    'rtg_nudge':0.2
}
elo_settings = {
    'init_elo': 1500,
    'K': 2,
    'beta':400
}

我事先运行了几次,决定了一个合理的 K 值。本文的目的不是解释 Elo,而是最大化 Elo 的有效性。我鼓励你复制我的 Github repo,自己玩这些价值观。如果你想知道更多关于 beta 和 K 值的信息,我鼓励你阅读我上面给的链接。一旦我们决定了设置,我们可以创建一个联盟:

# array to store players
league = []
# table to track wins/losses
table_array = []# create league
for p in range(season_settings['num_players']): # initialize players
    player_name = fake.name() # assign random initial true ratings
    player_rtg = random.gauss(season_settings['avg_rtg'], season_settings['std_dev'])
    player_elo = elo_settings['init_elo'] nudge = season_settings['rtg_nudge'] player_entry = [player_name, player_rtg, 0, 0, 0, player_elo]
    table_array.append(player_entry) new_player = Player(player_name, player_rtg, player_elo, nudge)
    league.append(new_player)league_table = pd.DataFrame(table_array, columns=['Name', 'True Rating', 'Wins', 'Losses', 'Ties', 'Elo'])league_table = league_table.sort_values(by='True Rating', ascending=False)

注意:我使用了 faker 包来创建假名字。现在我们有 32 名技能分布正常的球员:

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

所以是时候打第一季的 Sportsball 了!我不会给出所有代码,但我会展示我用来运行比赛的 for 循环:

for i in tqdm(range(season_settings['num_games'])): # create random matchups (pops from league list)
    matchups = create_matchups(league) # reset league
    league = [] # play games
    for matchup in matchups:
        p1 = matchup[0]
        p2 = matchup[1]
        p1_score, p2_score = play_game(p1, p2)
        p1, p2 = update_players(p1, p2, p1_score, p2_score)
        league.append(p1)
        league.append(p2)

注意:我还使用了 tqdm 包来显示进度条。我再次鼓励你去我的 Github 看看所有的代码。下面是结果!(Sportsball 还没有季后赛,因为经理们无法就条款达成一致)。

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

恭喜艾琳·琼斯!她以最好的真实收视率开始了这一季,以最好的真实收视率结束了这一季。最熟练的玩家赢得最多!无意冒犯艾琳,但我们真的不在乎。更有趣的例子可能是布兰登·尼科尔斯,他在赛季开始时排名第 12,结束时排名第 2。他的 Elo 和他的获胜次数都表明他并不是一直以来都是第二好的。也许他在赛季末有了很大的进步?

突然间,我们进退两难。我们如何知道评级系统有多好?我们可以利用赢/输栏(平局判一半赢)和真实评分的相关性,来了解使用赢/输记录反映真实评分的效果。相关性为 88.2%。然而,这并不完美。如果布兰登·尼科尔斯在赛季末大幅提高,输赢记录不会准确反映真实的评级(显然不会)。Elo 评级显然还没有赶上布兰登的真正技能。它仍然认为茉莉布朗是第二好的。哈!是否应该提高 K 值,让 Elo 调整得更快?嗯嗯…

而且,如果你好奇的话:Elo 和 True Rating 的相关性是 88.6%。这远不是 Elo 比输赢更好的决定性证据。事实上,当我多次运行这段代码时,输赢有时关联得更好。然而,这种高度的相关性确实表明 Elo 是一种不错的球员评级方法。

因此,我们需要一种方法来对评级系统进行评级。就像收视率调查一样。这让我想到了一个神奇的附加物,荆棘得分。

什么是 Brier 分数?

Brier 评分是一种简单的预测评分方法。和 Elo 一样,我也不是最能解释的人。它们是我最喜欢的书之一《超级预言》的核心组成部分。我会尽我所能给出一个简短的概要。

假设我在预测天气。我认为有 30%的可能性会下雨。然后下雨了。说“这是一个可怕的预测”很有诱惑力,也很人性化。人类(我对此也有罪恶感)经常假设,如果有人站在错误的那一边,他们就是错的。每当有人说某件事有 65%的可能性,而它没有发生,就感觉那个人错了。但是那个人可能是完全正确的。事实上,有人可能会说有 5%的可能性会下雨,然后就下雨了,那个人仍然是对的。我保证我不是天气预报员或天气预报员辩护者。我们只是生活在一个不可预测的世界里,不可能的事件会发生。幸运的是,我们是体育球分析师,我们有一个 1000 场比赛的赛季来找出我们的错误!

Brier 分数基本上概括了预测误差。一个好的预测者会有一个最低的 Brier 分数。我将举维基百科上关于降雨预报的例子来说明:

  • 如果预测是 100%并且下雨,那么 Brier 得分是 0,这是可以达到的最好得分。
  • 如果预报是 100%并且不下雨,那么 Brier 得分是 1,这是可达到的最差得分。
  • 如果预测是 70%并且下雨,那么欧石南得分是(0.70−1)^2 = 0.09。
  • 如果预测是 30%并且下雨,那么欧石南得分是(0.30−1)^2 = 0.49。
  • 如果预测是 50%,那么不管是否下雨,欧石南的得分是(0.50−1)^2 = (0.50−0)^2 = 0.25)。

所以,这里有一个权衡。我可以选择对我的降雨预报非常保守。我可以说每天有 50%的机会下雨。在这种情况下,无论发生什么,我的 Brier 误差是每次预测 0.25。那完全没用。因此,任何高于这个值的误差都是不好的,在某些情况下,与预测相反可能会更好。

Brier 分数的优势在于,它惩罚了过于自信的预测者。当结果接近确定时,你会因为预测“我确定某事”而获得奖励,当结果不确定时,你也会因为预测“它可能会发生,我不确定”而获得奖励。

Brier 分数也有弱点,我将在以后的文章中详细阐述。假设我在沙漠里,那里几乎不下雨。然后我每天预测 0%就能有一个合理的 Brier 分数。一方面,这感觉像是欺骗。一到两次下雨,我会有一个巨大的误差(每天 1)。这是一项严厉的处罚。另一方面,预测(我在沙漠中)需要一定程度的知识,所以小一点的荆棘是有道理的。理想情况下,如果我是一个不错的预报员,我会在下雨前增加我预测降雨的机会…显然…

布赖尔和艾洛的自然结合

Elo 评级自然会给出玩家赢得游戏的百分比几率。这是内在计算的一部分。同样,输赢记录也可以做到这一点。如果一个玩家或团队赢得了 76%的比赛,那么期望他们在 76%的时间里赢得随机比赛似乎是合理的。因此,我们可以计算两者的误差。由于 Elo 评级考虑到了对手的实力,也应该随着时间的推移而调整,我们预计 Elo 的表现将优于输赢记录。但是让我们看看!

代码更改

我认为追踪错误最简单的方法是添加 Brier 错误和赢输错误作为玩家类变量。在每场比赛后,每个玩家的输赢预测和 Elo 预测都将与结果进行比较,并计算 Brier 误差。然后它将被添加到球员的赛季总误差中。在赛季结束时,所有球员的所有赛季误差将被加在一起。然后我们将除以游戏数量和玩家数量,得到每场游戏的误差。让最好的评级系统胜出。

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

结果

哇!那是意想不到的。输赢记录更能预测结果!Elo 的精确误差值为 0.41/场,W-L 记录方法的精确误差值为 0.27/场。与我们之前的 50/50 基准相比,这真的很糟糕!这意味着我们真的需要校准 Elo。让我们试着调整 K 值来提高 Elo。

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

事实证明 Elo 的收视率对每场比赛都反应过度了。我将 K 值改为 0.5,将 Beta 值改为 400,这使得 Elo 评级经常打破输赢记录。总而言之,Elo 误差平均约为 0.244,W-L 记录平均约为 0.262。

然后我开始玩季节长度。在更长的赛季,如 10,000 场比赛,有一个非常小的 K 值要好得多。在超长赛季中,Elo 似乎会跑掉,变得不准确。然后我把赛季长度改成了 10 场和 100 场,Elo 常规以高 K 值(比如 5)击败 50/50 预测和 W-L 纪录。

我不满意

0.24 听起来很糟糕,事实也的确如此。然而,如果你完美地预测了 70%的获胜概率,那么你的误差是 0.21。如果你完美地预测了 90%的获胜概率,那么你的误差是 0.09。欧石南的分数并不能很好地评估那些自然接近胜负的预测。

事实证明,可能有一种更好、更流行的方法来计算预测误差。敬请期待!

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

As your accurate predictions increase in likelihood, your Brier scores increase naturally. I apologize for the ugly Excel graph.

正如你所看到的,对于任何实际上胜负难料的游戏,即使有完美的预测准确性,你的 Brier 分数也不会比 0.25 好多少。完美的 Brier 分数可以通过一个显而易见的等式找到(除了我不得不画出它来看):-x + x。

我学到的是:

  • 欧石南分数在识别坏预测方面很棒。然而,当我模拟接近掷硬币的游戏时,他们会很纠结,因为最好的分数可能接近 0.25。
  • 当游戏结果的变化较小时,例如一个团队可以赢得 95%的时间,输赢记录似乎比 Elo 表现得更好。
  • 当有更多真正的技能移动性(rtg_nudge 设置)时,Elo 的表现优于预期的赢输。
  • 在超长赛季中,Elo 失去了控制。这不一定是对 Elo 的抨击,这是实验中的一种错误——由于随机漫步数学,某些比赛的实际获胜预期超过 100%。
  • 为了在极端情况下快速获得准确性(例如,当最好的队和最差的队比赛时),你必须提高你的 K 值。提高 K 值会损害中层团队的准确性。所以有一个权衡——要么在不均衡的比赛中准确,要么在胜负难分的比赛中准确。

总而言之,我觉得我学到了很多东西。

未来的职位和目标:

  • 通过各种手段提高 Elo。胜利的边缘,保持稳定,等等。
  • 测试同时使用盈亏和 Elo 的回归
  • 也许使用盈亏差额作为另一个基线工具
  • 对真实数据进行操作

等不及了!

给运动队评分——最大化一个通用系统

原文:https://towardsdatascience.com/rating-sports-teams-maximizing-a-generic-system-772144574a07?source=collection_archive---------10-----------------------

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

Photo by Markus Spiske on Unsplash

仅仅从一条分数线我们能得到多少信息?

介绍

我的第一篇媒体文章是关于预测运动结果的基本方法。它使用简单的盈亏记录作为基线。例如,如果芝加哥小熊队今年赢得了 58%的比赛,你会期望他们未来赢得 58%的比赛。那篇文章表明,由一位名叫 Arpad Elo 的物理学教授在 20 世纪 40 年代发明的一个简单的系统可以胜过单独使用输赢记录。

有一些好消息:现在不再是 20 世纪 40 年代,我们可以获得大量的数据和计算能力。此外,许多人(特别是 538 和哈佛教授马克·格利克曼)为改进通用评级系统做出了许多贡献。因为我对模特、运动等感兴趣。我已经决定汇编和比较这些评级系统。

为什么?

我对创建运动模型感兴趣,我认为任何模型中最基本的输入是对整体技能的估计。如果你只是用输赢来代表整体技能,你是在给自己设限,因为随着比赛越来越多,你依赖你的模型来推断赛季输赢记录有多重要。这导致使用多个输入(如过去 5 场比赛的记录,过去 10 场比赛的记录等)来尝试评估技能。我认为创建模型时最好的第一步是最大化(在合理的范围内)对整体技能的单一评估。最坏的情况下,它可以作为一个很好的基线。

丰富

  1. 数据 —在上一篇文章中,我用 Python 的随机库生成了假球员和假分数。不再!在这个故事中,我使用了 2003 年的真实大学篮球数据和 2000 年的真实 PGA 和欧洲巡回赛(高尔夫)数据。大约有 87,500 场大学篮球赛和 1,700 场高尔夫锦标赛。
  2. 在上一篇文章中,我使用了最基本的 Elo 形式。不再!我给 Elo 增加了大约四个特性来改进它。还记得我之前提到的格利克曼教授吗?他有自己的系统,我们也试试那个。这两个系统都可以对高尔夫球员个人或篮球队进行评级。
  3. 基线(Baseline)—如果我们在改善其他一切,为什么不同时改善我们的基线呢?之前我只是用一个球队的输赢百分比来预测比赛结果。虽然把自己和不如自己的对手相比感觉很好,但这不是一种非常科学的做事方式。相反,这一次,我将使用 Log5 方法,它包含了两个团队的胜率。我稍微修改了一下,如果两个队都是不败的或者两个队都是零胜,它保证返回 50%的胜率。
  4. 错误跟踪——上一篇文章没有一样是令人满意的!我们将使用交叉熵损失(也称为对数损失)而不是 Brier 分数。为什么?我的最佳答案是,因为这样更容易判断你的评级系统是否在改进,或者你只是在猜测。你会因为过于自信而受到更多的惩罚,因此它会迫使你的系统稍微保守一点。我发现这也是一个更受欢迎的误差函数,但我想这不是使用它的具体原因。

系统

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

Question: Which system is best?

1)日志 5

直截了当的说,Log 5 就是一个简单的配对比较公式,比较两队的胜负。

2) Elo 评级

同样,非常简单。如果你不知道 Elo 是什么,我推荐我的第一篇文章或者 538 个讲解者之一的

3)改进的 Elo

终于来了个新人!我从四个方面改进了 Elo:

  1. **胜率:**胜率很简单,更大的胜率意味着更多的 K 奖励(你的等级提升更快)。这在阿拉巴马橄榄球赛这样的情况下尤其有用。如果他们每场比赛都赢了 20+分,改进的 Elo 系统可以更快地调整其评级,以迅速将阿拉巴马州评为所有球队中的顶级。是的,实现有点复杂,我稍后会进一步解释。另一方面,这也适用于一场比赛输了 20 多分的球队。
  2. **衰减的 K 值:**从高 K 值开始考虑赛季初期的不确定性是有道理的。这使得收视率在赛季初调整得更快。随着赛季的进行,随着收视率有更多的数据可以确定,K 值会下降。如果一个赛季的主导球队在赛季后期遭遇三连败,收视率不会反应过度,因为 K 值较低。在我的实现中,我使用指数衰减,但是可能有更好的函数。
  3. **前科:**这只是季前赛排名的一个花哨词。经常被诽谤的季前赛排名包含信息,尽管有时是坏信息。该模型想知道是否每个人都认为肯塔基篮球队和杜克篮球队整个赛季都可能进入大学篮球队的前 10 名。这给了它一个向真实排名靠拢的良好开端。有了这个开端,就不太需要用超高的 K 值来启动收视率了。显然,季前赛排名对于像 NFL 这样的短赛季运动和像 MLB 这样的长赛季运动更有用。赛季越久,季前赛排名就越不重要。在大学篮球赛季,我发现最好每年保持一支球队 70%左右的收视率。
  4. **自相关预防:**还记得我说过实现胜利边际是复杂的吗?标准 Elo 的一个优势是它是平衡的,不会随着时间的推移而失控。基于胜率提升奖励 K 值打破了这种平衡。自相关预防项(ACP 项)使我们改进的系统保持平衡。

4)格里科

如果我告诉你…有一个完全不同的评级方法可以尝试?这个是我之前提到的格利克曼教授在 1995 年发明的。值得阅读论文本身,但我会尽力总结。Glicko 引入了两个主要组件。第一,它引入了不确定性。这是非常有用的。Elo 评级系统中的总体评级仅由一个数字表示。让我们以一个评级为 1750 的玩家(或团队)为例。问题是你不能 100%确定,在一个随机的日子,在随机的条件下,在最后一场比赛后的两个星期,玩家的准确等级是 1750。相反,你可以非常确定玩家的“真实”评级在 1650 到 1850 之间。在 Glicko 系统中,在这种情况下,评级偏差项将为 50。它将表示玩家的真实能力在 1750 的 100 分(两个评级偏差)内的 95%置信区间。

不确定性也可以修改。如果一个球员已经 3 个月没有比赛了,我们可以增加不确定性。如果一名球员的比赛成绩非常不稳定,格利克会保持很高的不确定性。

另一个介绍是“评级期”的概念。作为一个温和的剧透,我凭经验发现,在某些体育项目中,评分周期比其他项目更有效。Glicko 将一个评级周期内的所有匹配视为同时发生。这在高尔夫球比赛中很有用,当你同时与 100 多名其他选手比赛时。这不仅减少了计算时间,而且通过使用所有其他球员作为参考,Glicko 能够确定一轮得分的上下文。另一方面,在大学篮球中,它的效果就不那么好了。我发现三场比赛的收视率是最好的。篮球用一个收视率周期没多大意义。根据你如何将过去的游戏分成三组,你可能会得到不同的评分。你还在等待三场比赛来更新排名,所以你经常忽略最后一场或最后两场比赛来影响你的排名。

实现说明:我使用的是 Glicko 2,但我称它为 Glicko。我大量引用了 Github 用户 sublee 的这个实现。

大学篮球成绩

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

Error per game, averaged from 2003–2019. Less is better!

在上面的图表中,我展示了我尝试的评级系统中每场比赛的误差。周误差是从 2003 年到 2019 年所有赛季的那一周所有比赛的平均值。首先:哇!改进的 Elo 在微调时表现非常好。至关重要的是,它在赛季后期与其他评级系统保持着明显的差距。在运动模型中,当你为小数位而战时,那真的令人印象深刻!值得注意的是,它甚至在没有季前赛排名的情况下击败了格利克,这也是我可以在格利克系统中实现的。无论如何改进的 Elo 似乎更好!

在我看来,最奇怪的发现是我在赛季初改进的 Elo 实现的有效性。赛季初期的误差小于赛季后期的误差。我认为这主要是由于传统的优秀球队在赛季初与纸杯蛋糕对手“热身”。如果肯塔基打无名定向学校,改进的 Elo 将预测肯塔基赢的概率为 90%+并且当他们最有可能真的赢时,误差将非常低。

除了蛋糕时间表,可能还有其他解释。与漫长的休赛期相比,球队在赛季中发展和改变技能更多吗(因此更难预测)?休赛期花名册更替对球队能力的影响有多大?我认为误差随赛季的演变值得进一步探讨。赛季中的伤病,联盟与非联盟的比赛,以及研究教练的影响都将是有趣的方向。

第二个结果是,经过多次调整,我无法让格利克接近击败改进的埃洛。这令人惊讶,因为这应该是一个更好的系统!策划完这个,我才意识到格利克在大学篮球宇宙中的不足。不过,我们先不要把它扔掉!

此外,我隔离了 Elo 的单个改进,以表明它们都做出了贡献:

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

Improvement Isolation

个人的改进我没有完全优化,重点是他们都有所贡献。同样令人印象深刻的是,作为一个整体,它们看起来是一样的,甚至比它们各部分的总和还要好。我有点期待衰减 K 和先验是同一个问题的两种解决方案,但事实证明,它们甚至在一起都很有用。我用的代码,sans data,可以在这里找到

高尔夫成绩

注意#1:在 2019 年 7 月 9 日更新之前,我正在展示高尔夫 Glicko 的结果,这些结果比他们应该得到的要好。我允许一些数据泄漏来改善结果。

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

Each system was optimized as much as possible within reason.

注意#2:如果你想知道我是如何在高尔夫中使用 Log 5 的,我是通过对锦标赛中每场比赛的结果求和来完成的。因此,在一场 144 人的锦标赛中,每名玩家要参加 143 场比赛。

这次两个主要系统之间的结果非常接近!Glicko 以显著优势击败常规 Elo,甚至接近改进的 Elo。与改进的 Elo 相比,Glicko 以更少的计算和更少的参数调整获得了它的分数。就像我前面提到的,Glicko 在很多玩家同时玩游戏的情况下更有用。

在研究这篇文章时,我没有看到像 Glicko 这样的贝叶斯排名系统在短赛季的一对一比赛中有缺点。当然,我不能排除我可以做些调整来提高格利克在那里的表现。微软在他们大部分与 Glicko 密切相关的游戏中使用了 TrueSkillTrueskill 2 。这是有意义的,因为许多在线游戏多人比赛涉及两个以上的玩家。从我的实验来看,游戏设计师在面对面游戏中使用 Elo 版本可能会更好。

结论

总而言之,我完成了我想完成的事情。我比较了两种截然不同的运动项目的通用评分系统,发现两者的结果都不一样。一般来说,大多数进一步的改进将是微小的小数点或特定运动的变化。真是浪费时间,对吧?嗯,我打算将来也这么做。

当然,不言而喻,我们可以在格里克的基础上有所提高。马克·格利克曼也做了自己的改进(比如 2010 年的格利克助推系统)。也有基于 Glicko 系统的改进系统,如斯蒂芬森系统赢得了 2012 年 Kaggle 比赛。那些专注于国际象棋,但它们提供了从这里走向何方的线索。

最后,我想比较现实世界中已建立的排名系统与我在这里描述的系统之间的相关性。如果这些系统产生的排名与我自己的大相径庭,所有这些都是毫无用处的。为了简洁起见,我将只集中比较四个高尔夫排名系统。一,官方的世界高尔夫排名。这不是最好的系统,但已经使用了很长时间,任何高尔夫球迷都很熟悉。它把赢得高尔夫锦标赛和在大型锦标赛中表现出色看得比它应有的更重(因此它喜欢 4 次主要冠军布鲁克斯·科普卡)。另一个排名系统“DG 排名”,是由 datagolf.ca 创建的排名。数据高尔夫做了伟大的工作,我认为即使非高尔夫球迷也会喜欢看到他们创造的一些可视化。他们的总排名通常接近拉斯维加斯的赔率,是一个很好的参考,以了解高尔夫球员在任何特定时间的比较。

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

如你所见,这两个排名系统与 DataGolf 的排名有 85%或更多的关联!Elo 和 Glicko 也有很大的不同。由于它们不同,但提供了相似的预测精度,它们可能被组合起来形成一个更好的模型🤔。

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

DIY 雷伊·达里奥 ETF:如何用风险平价投资组合构建自己的对冲基金策略

原文:https://towardsdatascience.com/ray-dalio-etf-900edfe64b05?source=collection_archive---------6-----------------------

查看我们的 开源 Live Book 项目获取本文使用的代码。

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

7 November 2018; Ray Dalio, Bridgewater Associates on Centre Stage during day two of Web Summit 2018 at the Altice Arena in Lisbon, Portugal. Photo by David Fitzgerald/Web Summit via SportsfilePhoto by David Fitzgerald /Sportsfile. Image adapted by OpenQuants.com.

本月早些时候,彭博发表了一篇关于美国推出新的风险平价 ETF 的新闻文章。 RPAR 风险平价 ETF 计划基于风险在资产类别之间进行分配。根据彭博的说法,该基金将是美国第一个遵循这种量化方法的基金,将更多的资金分配给波动性较低的证券。

(RPAR 风险平价 ETF)有点像 Bridgewater,但他们只是为世界上最富有的机构做这件事。这里的想法是建立一个对每个人都有用的东西。— Alex Shahidi,Dalio 的 Bridgewater Associate 的前关系经理,RPAR 风险平价 ETF 的创始人。彭博

“风险平价”方法是由雷伊·达里奥的 Bridgewater Associates 在 1996 年创立全天候资产配置策略时推广的,Bridgewater Associates 是管理资产规模最大的对冲基金(1328 亿美元)。“全天候”是一个术语,用来指在有利和不利的经济和市场条件下都表现良好的基金。今天,一些经理在风险平价方法下采用了“全天候”概念。

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

Ray Dalio while giving a speech at the 10th anniversary celebration of charity Grameen America. Metropolitan Museum of Art, September 23 2017. Attribution: Grameen America [CC BY 3.0].

风险平价投资组合寻求在与每个资产类别或投资组合组成部分相关的风险之间实现均等的平衡。这样,低风险资产类别通常会比高风险资产类别拥有更高的名义配置。

风险对等大约是**平衡。**实现可靠平衡的最佳方式是基于对资产类别定价结构中固有的环境敏感性的基本理解来设计投资组合。这是全天候方法的基础。

风险平价策略在最近的历史(2010 年至 2017 年)中遭受了损失,因为牛市将股票推至创纪录高位,因此有利于股票集中的投资组合。然而,自 2018 年以来市场波动性的增加,地缘政治和贸易战风险的紧急情况,以及黄金等避险资产的增长,为加强多元化投资组合创造了条件。这在图 3.1 中得到证明,该图显示 S&P 风险平价策略在过去 12 个月(2018 年 8 月-2019 年 8 月)中的回报率接近 10%,是美国股票标准普尔 500 指数的两倍多。

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

Fig. 3.1 S&P 500 index versus S&P Risk Parity Index. Source: Bloomberg.

但是我们如何建立风险平价投资组合呢?它与传统的均值-方差模型相比表现如何?

在这篇文章中,

  1. 我们将展示如何建立自己的风险平价投资组合
  2. 我们将创建并比较两个指数的性能:
  • 风险均衡的 FAANG 公司的 FAANG 风险平价指数
  • FAANG 切线投资组合指数的 FAANG 公司的权重,使回报/风险比率是最佳的

到本文结束时,你将能够受雷伊·达里奥全天候方法的启发,创建自己的风险平价基金。作为我们开源 Live Book 计划的一部分,我们还提供了复制结果的代码。

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

风险平价投资组合——雷伊·达里奥方法

风险平价投资组合表示一类资产验证以下等式的投资组合(Vinicius 和 Palomar 2019 年):

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

其中 f 是衡量投资组合总风险的一次正齐次函数,而 w 是投资组合权重向量。换句话说,风险平价投资组合中每项资产的边际风险贡献是相等的。 f 的一个常见选择是投资组合的标准差,这是波动性的一个常见代表,即,

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

其中σ是资产的协方差矩阵。

在实践中,风险和投资组合经理在资产、国家、区域或行业层面都有他们遵循的风险指令或边际风险贡献界限。因此,风险平价组合的自然延伸是所谓的风险预算组合,其中边际风险贡献与预先分配的数量相匹配(Vinicius 和 Palomar 2019)。数学上,

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

切线投资组合——马科维茨方法

均值方差优化是现代投资组合理论中常用的量化工具,允许投资者通过考虑风险和回报之间的权衡来进行分配。

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

In 1990, Dr. Harry M. Markowitz shared The Nobel Prize in Economics for his work on portfolio theory.

在均值-方差框架中,目标是根据基线预期收益率μb 最小化投资组合风险σ,如下所示:

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

其中 m 是投资组合资产的预期收益向量。

我们将获得每个目标收益率μb 的最优(最小风险)投资组合,从而形成有效边界。图 3.4 中有效边界上的每一点都是在给定风险水平(标准差)的情况下,具有最小化风险的最优证券组合的投资组合。有效边界以下的点是表现较差的投资组合。它们要么提供相同的回报但风险更高,要么提供相同风险的更少回报。

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

Figure 3.4: Efficienty Frontier. Attribution: ShuBraque (CC BY-SA 3.0)

但是我们如何从有效边界选择投资组合呢?一种方法是从风险/回报的角度选择最有效的投资组合,即具有最高夏普比率(超额回报和投资组合标准差之间的比率)的投资组合。这个投资组合被称为切线投资组合,它位于资本配置线和有效边界的切点。

我们将在下一节实现平价风险和切线投资组合。

优化 FAANG:雷伊·达里奥对马科维茨

单一投资组合

我们将考虑 FAANG 公司调整后价格的对数收益,即由以下代码标识的股票:FB、AMZN、AAPL、NFLX 和 GOOG。

我们可以使用风险平价投资组合投资组合分别构建一个 FAANG 风险平价和切线投资组合。我们将首先考虑 2018 年的 FAANG 回报,以构建如下投资组合:

图 3.5 显示了平价和切线投资组合的投资组合权重。我们观察到切线投资组合集中了亚马逊和网飞的权重,两家公司的权重几乎相同,而脸书、苹果和谷歌被排除在投资组合之外。另一方面,平价投资组合在 FAANG 公司中呈现出均衡的权重分布,所有公司的权重都在 20%左右。苹果和谷歌的权重略高于 20%,而网飞是权重最低的公司(15%)。

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

Figure 3.5: Portfolio weights for parity and tangency FAANG portfolios considering returns from 2018.

图 3.6 比较了获得的平价和切线投资组合的(协方差)风险预算。正如所料,我们观察到平价投资组合的风险预算在投资组合资产中平均分配。另一方面,切线投资组合集中了亚马逊和网飞之间的风险,后者对应于投资组合风险预算的 56%以上。

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

Figure 3.6: Portfolio covariance risk budget for parity and tangency FAANG portfolios considering returns from 2018.

雷伊·达里奥法昂指数

“雷伊·达里奥 FAANG 指数”,即由 FAANG 公司组成的投资组合,再平衡以匹配相应的风险平价投资组合,会有什么表现?它会击败相应的短期投资组合吗?

为了回答这些问题,我们将考虑 2014 年 1 月 1 日至 2019 年 9 月 1 日期间 FAANG 公司的投资组合,并构建两个指数:

  1. 风险平价指数:每季度重新平衡投资组合权重,根据风险平价投资组合设定权重;
  2. 切线投资组合指数:根据切线投资组合重新平衡投资组合权重。

我们首先通过构建一个宽度为 12 个月、步长为 3 个月的滚动窗口来定义重新平衡日期,如下所示:

**library**(fPortfolio)
faang.returns.xts<-faang.returns["2014-01-01/2019-09-01"]
rWindows<-**rollingWindows**(faang.returns.xts, period="12m",
                         by="3m")

我们的重新平衡日期如下:

**print**(rWindows$to) ## GMT
##  [1] [2014-12-31] [2015-03-31] [2015-06-30] [2015-09-30] [2015-12-31]
##  [6] [2016-03-31] [2016-06-30] [2016-09-30] [2016-12-31] [2017-03-31]
## [11] [2017-06-30] [2017-09-30] [2017-12-31] [2018-03-31] [2018-06-30]
## [16] [2018-09-30] [2018-12-31] [2019-03-31] [2019-06-30]

接下来,我们计算每个再平衡日期的风险平价投资组合权重,考虑 12 个月窗口内的回报,如下所示:

我们现在计算 FAANG 切线投资组合的季度权重。我们利用f 组合包来计算滚动切线组合,如下所示:

图 3.8 显示了平价风险和切线投资组合的投资组合权重。我们观察到,随着时间的推移,风险平价权重相当稳定,与其他投资组合成分相比,网飞的权重略有不足。另一方面,切线投资组合权重在考虑的时间段内变化很大,这可能会对其维护带来挑战,因为其周转率可能相当高。切线投资组合在许多重新平衡日期中增持苹果和亚马逊,在所有重新平衡日期中减持谷歌。

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

Figure 3.8: Portfolio weights for (A) FAANG risk parity portfolios and (B) FAANG tangency portfolios.

我们将使用 FAANG 公司的时间序列以及风险平价和切线投资组合权重的时间序列来计算风险平价和切线投资组合指数的回报,如下所示:

图 3.9 显示了风险平价指数与切线投资组合指数的绩效汇总。令人惊讶的是,FAANG 风险平价指数大大优于 FAANG 切线投资组合指数,累计回报率为 169.48%,而切线投资组合指数为 109.65%。FAANG 风险平价指数在分析的大部分时间内也有相对较低的下降。

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

Figure 3.9: Performance summary for the risk parity index versus the tangency portfolio index

表 3.1 和 3.2 分别显示了风险平价和切线投资组合指数的日历回报。有趣的是,在切线投资组合指数累积回报为正的年份,风险平价指数的回报低于切线投资组合指数。相反,在切线投资组合指数累积回报为负的年份,风险平价指数的表现优于切线投资组合指数。这样,与切线投资组合相比,风险平价指数显示了“没那么好”但也“没那么差”的年回报率。

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

图 3.10 显示了滚动 252 天窗口中的性能摘要。同样,我们观察到风险平价指数比切线投资组合指数表现更好。与切线投资组合指数相比,风险平价指数在分析的大部分时间内具有更高的年化回报、更低的标准差和更高的夏普比率。如表 1 所示。3.3,风险平价指数的总年化回报率为 23.71%,标准差为 22.55%,夏普比率为 1.051,而切线投资组合指数的年化回报率为 17.22%,标准差为 26.42%,夏普比率为 0.652。

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

Figure 3.10: Performance summary in a rolling 252-day window for the risk parity index versus the tangency portfolio index

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

讨论和结论

在各种经济环境下,哪种资产组合最有可能带来长期的良好回报?

这是 Bridgewater Associates 在创建全天候基金之前提出的问题,其概念如今在所谓的风险平价策略中流行开来。

传统的资产配置方法往往容忍更高的风险集中度,目标是产生更高的长期回报。布里奇沃特认为这种方法有一个严重的缺陷:

如果短期风险的来源是高度集中于单一类型的资产,这种方法会带来长期回报不佳的重大风险,威胁到履行未来义务的能力。这是因为每种资产都容易受到持续十年或更长时间的不良表现的影响,这是由经济环境的持续变化引起的——T2 桥水。

在本文中,我们介绍了风险平价投资组合的概念,并将其与均值-方差模型进行了比较。我们通过构建 FAANG 风险平价指数并将其性能与 FAANG 切线指数进行比较,提供了一个简单的实际例子,FAANG 切线指数从均值-方差有效前沿中选择具有最优夏普比率的投资组合。

与切线投资组合指数相比,风险平价指数在分析的大部分时间里表现出更高的年化回报、更低的标准差和更高的夏普比率。当然,要谨慎对待结果。

在实践中,风险平价和均值-方差方法都被用于可能跨越多个资产类别的较大投资组合。当投资组合中存在不相关的资产时,这些方法会发挥作用,从而增加分散投资的潜力。此外,现代投资组合优化策略可能更加复杂,具有各种目标函数和约束。我们在这篇文章中的目标是给你一个良好的开端。请随意查看我们的 github 项目中的源代码,并实施您自己的策略!

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

参考

Vinicius,Ze 和 Daniel P. Palomar。2019. RiskParityPortfolio:风险平价组合的设计https://CRAN.R-project.org/package=riskParityPortfolio

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值