TowardsDataScience-博客中文翻译-2020-四十五-

news/2024/10/15 13:51:39

TowardsDataScience 博客中文翻译 2020(四十五)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

基于 Avro 模式的类固醇弹性研究

原文:https://towardsdatascience.com/elasticsearch-on-steroids-with-avro-schemas-3bfc483e3b30?source=collection_archive---------30-----------------------

如何应对大型企业设置中的接口版本爆炸

Brandon Mowinkel 在 Unsplash 上拍摄的照片

它是关于什么的

下面的文章解释了一种使用现代数据存储和序列化技术来分离组件和停止企业的大规模数据消费者应用程序中固有的服务接口版本爆炸的方法。

高层互动之旅

在一家大型金融机构负责一个大量使用的数据提供商系统时,我总是面临新服务版本的无休止的部署迭代,以及多个消费者无法在适当的时间框架内迁移到新版本的情况。随着时间的推移,这导致了为一个服务运行多个并行版本的情况。

提醒一句:这种方法是基于 NoSQL 数据存储基础设施的,我充分意识到这种数据存储可能不适合所有类型的业务应用。然而,有足够多的用例非常适合这种类型的架构。

互动之旅

我们的教程涵盖了以下场景:
我们有一个服务组件,它处理通过基于 React 的浏览器应用程序提供的用户输入,并将其数据持久存储在基于 ElasticSearch 集群的持久性存储中。

  • (3):ReactUIServiceComponent发送本地化的 JSON 数据负载(用户输入)
  • (4)ServiceComponent通过引用代码值替换本地化的文本来解本地化 JSON 数据有效负载,并准备一个 Avro 二进制消息(序列化),然后将其发送到BackendComponent
  • (5)BackendComponent将 Avro 二进制消息解串,转换成 Avro JSON 消息,存储在ElasticSearch Cluster

Avro 模式

Avro 消息的一个关键特征是,它通过相关的 Avro 模式进行自我描述。Avro 模式是基于 JSON 的消息结构定义。

参考下面简单的 Avro 模式。

这个例子已经概述了 Avro 模式定义语言的一些细节。

  • personidlastnamelongstring类型的强制属性
  • surname是一个联合属性,也就是说,它可以是null或者具有类型为string的值。默认情况下,其值为null

可选值总是被表示为联合,并且为了准备无缝的模式演化(稍后将详细介绍),您应该总是定义可选属性的缺省值。

Avro 模式解析器和客户端绑定生成器

Avro 序列化程序和反序列化程序使用该模式将 Avro 二进制消息(或 Avro JSON 消息,取决于您选择的配置)解析为 Java 数据访问对象(DAO)。这些 DAO 可能是通用的或预编译的强类型模式 Java 类。

也就是说,Maven 目标generate-sources生成一个类Person,它有三个属性personIdlastNamefirstname,然后可以使用 Avro 解析器从这种类型的二进制消息中实例化出 person 对象。

为了自我描述,Avro 消息可以用模式本身或模式指纹来补充。

完整模式 JSON 的供应通常是以基于文件的方式完成的,这捆绑了大量的 Avro 消息。在我们的交互之旅中——具有单个 Avro 消息的请求-响应风格——这样的方法开销太大。对于这个场景,模式指纹是正确的方法。

Avro 指纹和模式目录

Avro 模式指纹是一个全局唯一标识符,用于引用中央模式注册中心中的正确模式。

下面的抽象SchemaRegistry类描述了这种注册中心所需的方法。

  • 方法registerSchema允许发送者(发布者)注册他发送给读者(消费者)的消息的 Avro 模式。作为返回值,Avro 指纹将被返回,它唯一地标识这个模式。对模式本身的任何更改都会产生新的指纹。
  • 使用getSchemaFingerprint方法计算指纹
  • 方法getSchema将返回与fingerprint中传递的相关联的 Avro JSON

就这样,建立了一个全局模式注册中心,Avro 消息的读者或作者可以使用它来交换相关 JSON 模式的模式指纹,这样就可以充分利用 Avro 的全部功能了。

本教程提供了模式注册表的两种实现:

  • 轻量级测试的基于文件的实现,以及
  • 基于弹性搜索(ES)的实现。如果您的公司实例化了一个高效的 ES 集群,您可以通过引入一个专用的 ES 索引,轻松地将它作为公司范围的模式注册表。
  • 有现成的模式注册中心可用,特别是在 Kafka 领域,例如,融合 Kafka 产品的模式注册中心。但我们尽可能保持简单,并利用 ElasticSearch,它被用作我们的目标数据存储。

下面的例子显示了索引avroschema中指纹8354639983941950121下的 ElasticSearch 注册模式。任何消息的作者或读者都将使用 Avro 指纹来引用其处理中使用的底层模式。

使用 ElasticSearch,您将获得一个现成的模式定义中央存储库,业务分析师、设计人员或开发人员在系统开发期间可以使用查找和查询功能轻松增强它。

如果您认为实现模式注册中心需要大量的编码,那么您就错了。

下面你可以看到功能完整的ElasticSearchSchemaRegistry java 类。

持久性管理器

非常简单紧凑。你现在可能会争辩说ESPersistencyManager类隐藏了复杂性(作为教程的一部分被使用和实现)。

不完全是,这个类是围绕 Jest 的一个超轻层,Jest 是一个用于 Elasticsearch 的 HTTP Java 客户端。虽然 Elasticsearch 提供了自己的原生 Java 客户端,但 Jest 提供了更流畅的 API 和更自然的工作界面。对 JEST 感兴趣,可以看看 Blaedung 的教程文章。

我们的ESPersisencyManager只是保护我们的补习班免受直接的笑话曝光。一种封装技术曾经能够在未来版本中替代持久性管理器。

同样非常紧凑,可以持久化 Avro 模式。值得一提的是,您可以提供 ElasticSearch 自己的主键(在 ES 中称为_id)。在我们的教程中,我们使用全局唯一指纹作为 ES 中的主要标识符,这使得查找变得简单明了(见上面的截图)。提供主键是一个关键特性,尤其是在数据复制场景中使用 ElasticSearch 时,ES 只是另一个主系统的从系统,而这个主系统已经生成了主键。

可以想象,检索一个 JSON 对象甚至更简单 Jest 为我们完成了这项工作。

后端组件启动序列

我们现在应该对后端组件使用我们的方法必须准备和配置的内容有了很好的理解。

下图概述了最重要的步骤:

后端组件的启动顺序

  • 我们创建了一个与我们的弹性搜索集群的连接
  • 10,11:我们创建(如果不存在的话)两个 ES 指数,businessmodelavroschema。第一个用于我们的域数据记录,后一个用于 Avro 模式
  • 20,30,31:我们为我们的avroschema加载并编写一个定制的 ES 映射。这需要一些解释。ES 需要一些关于其持久化 JSON 文档的模式信息(这是一个 ES 文档模式,不应该与 Avro 模式混淆)。默认情况下,ES 将通过分析提供的 JSON 文档自动分配一个 ES 映射模式。在我们的例子中,我们必须根据需要调整 ES 映射,并告诉 ES 不要解释属性avroschema中提供的 JSON 部分(通过将类型切换到object)。

我们的索引“avroschema”的弹性搜索索引元信息

  • 40–46:我们现在从文件系统加载 Avro 消息模式,并将其注册到 ES 模式注册表中。作为回报,我们得到了 Avro 模式指纹,这是我们的通用接口契约标识符,用于提供/消费我们的消息。该模式定义了我们的一个业务域数据对象(DO),即“业务模型策略 DO”,它收集关于公司的策略数据。除了简单类型之外,该模式还引入了一个用于说明的枚举。doc属性允许提供文本解释,这在人们浏览注册表中的模式时很有帮助。

用于收集公司战略数据的 Avro 模式

服务组件启动序列

让我们看看服务组件需要准备什么。

启动序列服务组件

  • 10–11:我们创建一个到 ES 集群的连接对象(ESPersistencyManager)
  • 20,21,22:我们初始化一个基于 ES 的模式注册中心,传递我们的连接对象
  • 30,31:我们基于指纹版本来检索模式,服务组件就是基于指纹版本构建的。

消息版本随时间演变

必须详细理解最后一步——基于“预先配置的静态”指纹解析模式。

模式指纹表示 ServiceComponent 或 BackendComponent 能够处理的消息版本号。

在我们简单的 Hello world 示例中,后端和服务组件的模式指纹是相同的。但实际上,后端组件以及一个或多个服务组件可能会随着时间的推移以不同的变化速度发展。

下图说明了这种情况。

模式(接口)版本随时间的演变

  • 想想一个BackendComponent,它在带有模式版本(指纹)100的 Release 1 中与它的ServiceRWComponent1一起发布。然后还有两个只读组件ServiceROComponent2ServiceROComponent3,正在使用版本100的数据。
  • 三个月后,BackendComponent发布了新的版本 2,它用模式版本101支持增强的数据模型(一些额外的可选属性)。它的ServiceRWComponent1也支持这个新版本。
  • 对于两个独立的数据消费者ServiceROComponent2ServiceROComponent3——它们可能以不同的变化速度发展——情况如下:ServiceROComponent2没有自己的版本并停留在版本100上,ServiceROComponent3需要版本101的附加数据元素并发布其ServiceROComponent3的新的整体版本。

接口版本爆炸

这就是现实生活中的我们。如果你是一个BackendComponent的所有者,它提供对许多独立数据消费者(ServiceROComponent2ServiceROComponent3)来说很重要的数据集,你将面临支持多个接口版本的需求。这个版本支持需求可能会随着时间的推移而急剧增长,并影响您的交付时间、灵活性和组件成本的增加。

作为第三方组件(不在您的控制之下)的数据提供商,您可能只有有限的权力来强制它们升级到更新的发布接口版本号。

由亚历克斯·霍利奥克在 Unsplash 拍摄的照片

对于许多数据提供者来说,服务版本及其在组件整个生命周期中的管理起着至关重要的(有时甚至是麻烦的)作用。

运行由 WSDL 接口定义语言支持的 SOAP-Webservices 或由开放 API 规范 3(即 Swagger)支持的 JSON-Services(两种非常流行的请求-响应交互技术)将使您面临不断的版本更改,以防您增强您发布的接口。

版本变更是显式的,必须由您的使用者采用,这对于允许从您的生产组件中删除旧版本的单一协调版本升级来说可能是力所不及的。

在这里,Avro 凭借其开箱即用的模式演进支持大放异彩。

Avro 模式演变

Avro 支持模式进化,这意味着您可以同时拥有不同模式版本的 Avro 消息的生产者和消费者。这一切都继续工作(只要模式兼容)。模式演化是大型生产系统中的一个关键特性,它可以分离组件,并允许组件在不同时间通过接口变化来运行系统更新。

Avro 算法实现要求 Avro 消息的读者与消息的作者拥有相同版本的模式。那么 Avro 是如何支持模式进化的呢?如果读取器在另一个模式版本上,读取器可以向 Avro 解析器传递两个不同的模式。然后,解析器使用它的解析规则将数据从写模式翻译到读模式。

让我们用我们的BackendComponent.convertAvroBinarToJSON方法来检查一下。这是本教程的主要方法之一,它将 Avro 二进制消息转换成 Avro JSON 消息格式,之后保存在 ES 中。

backendcomponent convertAvroBinaryToJSON 方法

  • 该方法在 Avro 单对象编码的二进制消息中传递,定义如下:

单个 Avro 对象编码如下:一个双字节标记,C3 01,表示消息Avro 并使用这个单个记录格式(版本 1)。对象的模式的 8 字节小端 CRC-64- AVRO 指纹。使用 Avro 的二进制编码Avro 对象编码。(链接)

  • 我们从消息中提取模式指针
  • Line 3:我们从模式注册中心获取相关的模式
  • Line 4:我们获得消息有效载荷
  • Line 7:我们检查收到的信息的指纹是否与BackendCompontent中使用的指纹相同
  • Line 8:如果指纹相同,我们用BackendComponent模式创建一个 Avro GenericDatumReader(用于解码消息)
  • Line 10:如果没有,我们用BackendComponent模式和检索消息模式创建一个 Avro GenericDatumReader。读者现在将在解码二进制消息期间应用模式演化逻辑。
  • Line 12:我们还创建了一个 Avro GenericDatumWriter来产生消息的 JSON 表示。如前所述,Avro 支持紧凑的二进制编码,以及基于 JSON 的编码。你可以用一些简单的 Avro 助手类从一种编码转换到另一种编码。
  • Line 14:我们为二进制文件payload创建一个binaryDecoder,以及
  • Line 18: a jsonEncoder基于我们的schema
  • Line 19-23:最后,我们对二进制消息进行解码,并将其编码成 JSON 消息格式,这样就可以持久化了。

方法BackendComponent.persist负责这项任务,这很简单。

  • 我们传入我们对象的弹性搜索index(“业务模型”)、弹性搜索type(“策略”),以及唯一的id

后端组件持久方法

在现实场景中,persist 方法将由BackendComponent作为 JSON-、Webservice 或任何其他远程接口公开。

我们持久化的 Avro JSON 文档被存储为_source属性的一部分。

想想我们现在取得的成就。

  • 我们的BackendComponent现在可以服务于 JSON 文档结构,它完全符合 Avro 消息规范。根据ServiceComponent接收到的二进制消息,到 JSON 持久性格式的转换完全自动进行。
  • JSON _source文档结构(有效载荷)是完全自描述的。我们注入了主键index_ipid,以及模式指纹avro_fingerpint作为有效负载的一部分
  • 这意味着 JSON 消息文档的消费者可以通过 ES 解析模式来处理消息,并且知道文档在 ES 中的惟一存储标识符。

  • 我们还注入了可能相关的附加公共属性,即last_update_timestamplast_update_loginid,以保存更新文档的时间和人员的信息。这将允许我们通过引入例如基于 Kafka 的事件接收器(将是另一篇文章的主题)来建立时间序列和审计追踪

图式进化再探

数据管理的一个重要方面是模式演变。定义了初始模式后,应用程序可能需要发展,如上图所示。当这种情况发生时,下游消费者必须能够无缝地处理用新旧模式编码的数据。

我们区分两种兼容性类型:

  • 向后兼容意味着使用较新模式的用户可以读取基于较旧模式的数据
  • 向前兼容意味着使用旧模式的用户可以根据新模式读取数据

如果模式演化是向后兼容的,以及向前兼容的,则取决于改变是否符合 Avro 模式解析约束

以下是分辨率规格中的三个基本规则:

  • 可以对字段进行重新排序,而不会对读取器或写入器产生任何影响
  • 向记录中添加一个字段是可以的,前提是您还要一个默认值。默认值的提供允许具有新模式的读取器从基于旧模式的写入器读取消息。
  • 只要您最初给了一个默认定义,从记录中删除一个字段是可以的。即旧模式上的读取器接收默认值。

这意味着在数据消息中添加或删除可选字段会保持消息完全兼容,只要已经或将要为删除或添加的属性定义默认值。所以当您开始定义您的模式时,您应该从一开始就考虑到这一点。

在数据消息中添加或删除可选的数据属性是一种场景,这在生产系统中经常发生,生产系统不断发展以满足新的业务需求。

解释了增强的版本控制策略

让我们通过一个简单的例子来看看 Avro 将如何帮助我们减少版本复杂性和组件耦合,通过比较一个经典的应用程序设置,以及我们使用 ElasticSearch 和 Avro 的增强设置。

经典应用

假设在生产环境中有以下组件设置。

  • 我们有一个应用程序,它覆盖了一个特定的有界上下文(例如,一个 CRM client profiling 应用程序),由一个 React 维护 UI ReactMaintainUI组成,该 UI 由一个呈现服务组件ServiceComponent支持,该组件为 UI 提供一个 JSON 本地化的有效负载接口。我们假设它是一个招摇风格的 OpenAIP 接口。它将连接到一个后端组件BackendComponent,该组件提供了一个 web 服务接口,并将其数据保存在关系数据库中RelaionalDB
  • 应用程序本身不仅为其 UI 提供 API,还通过其 JSON API 集成了第三方 UI JSONConsumer1。以及一个第三方数据消费者,它通过 Webservice 接口读取数据BackendComponent

版本示例 Classic 1

  • 当应用程序最初发布时,以下接口和数据库模式版本被冻结,供消费者使用。JSON_V100WSDL_V100以及DBSchema_V100。所有这些工件都代表了消费应用程序的约定契约,无论是在 BoundedContext 中管理的应用程序(通常在您的控制之下),还是第三方组件。
  • 现在假设我们的有界上下文应用程序在短时间内有多个发布周期,引入了新的特性和可选的数据属性。这是敏捷设置中的一个典型例子,您可以从一个最小可行产品(MVP)开始,并在一个短的发布周期内增强应用程序。
  • 在我们的例子中,我们发布了一个新版本V101,它通过ReactMaintainUI请求额外的可选数据属性

版本示例经典 2

  • 我们为有界上下文应用程序添加了一个新的接口和模式版本:JSON_V101WSDL_V101DBSchema_V101。这导致红色成分的变化。
  • 我们现有的第三方消费者JSONConsumer1WSDLConsumer1(绿色的),对当前的接口很满意(不需要新数据),并且没有任何发布计划,仍然停留在初始版本JSON_V100WSDL_V100
  • 你现在在这里。作为有界上下文应用程序的所有者,您现在必须开始管理您的接口版本,并向您的数据消费者提供潜在的多个版本。
  • 尤其是如果多个其他应用程序需要您的数据(即 CRM 数据),这种需求将随着应用程序的变化而快速增长。这可能导致同一服务的多个版本,相信我,迫使第三方消费者迁移到新版本是一项艰巨的任务。
  • 迁移到新的接口版本意味着代码更改(至少重新编译您的客户端绑定)、测试和组件发布。从消费者的角度来看,他们试图尽可能避免这种情况

新一代应用

现在让我们用新的有界上下文应用程序来检查这个场景。在它的BackendComponent中使用了支持模式进化的 Avro 消息接口,以及 NoSQL 数据存储。

新一代应用程序版本示例

  • 我们仍然有一个显式的接口契约JSON_V100,它作为一个基于 REST 的接口暴露给 UI。
  • BackendComponent为消费者提供了一个简单的 JSON 接口,以二进制编码的单对象格式传递 Avro 消息。
  • 一个非常简单的 JSON 接口将允许我们传入一个 Base64 编码的字符串,它代表我们的二进制单对象编码的 Avro 消息。

Avro 消息的简单 JSON 接口(输入)

作为回报,服务将返回 Avro 对象的唯一标识符,以及BackendComponent作者的指纹。这将允许接口消费者检测他是否在同一个版本上工作。

Avro 消息的简单 JSON 接口(输出)

  • 考虑到本教程已经足够了,我们将在后续文章中研究这种接口的细节。
  • 正如您在上面的图表中所看到的,BackendComponent接口以及EsIndex1模式没有被明确地版本化。只要我们的接口增强在 Avro 模式演进规则的约束范围内,版本控制将被透明地管理。

我们的后端组件不需要显式版本控制

  • 现在添加额外的可选属性只会导致ReactMaintainUI组件和相应的ServiceComponent组件的变化,这提供了一个更新的符合 OpenAPI 的 JSON 接口。

版本示例新一代 2

  • Out BackendComponent和 persistence schema Avro_JSON_Store可能不受影响(或者最低限度,我们必须在 ES 上运行一个重建索引,以防我们需要一些特定的模式设置)。
  • 我们最终可以将我们的BackendComponent从演进的ServiceComponent中分离出来,减少开发和测试的工作量,以及我们应用程序的整体复杂性。

照片由张秀坤·贝德纳尔兹在 Unsplash 上拍摄

这最终会导致更快的交付周期,以及在组件中引入新特性的更少的变更成本。

把它包起来

所以你该去看看教程了,可以在 Github 上找到:https://github.com/talfco/tutorial-apache-avro(一个基于 Maven 的教程)。

  • HelloWorld类开始,它建立并模拟了ServiceComponentBackendComponent之间的交互流。
  • 从那里,您可以深入到轻量级支持类,这为您提供了一个整体方法的良好概览。
  • 唯一的先决条件是存在一个弹性搜索测试集群。简单来说就是在 https://www.elastic.co/网站上创建一个 14 天的测试账户,这个账户能满足你的所有需求(还能让你体验 ElasticSearch 的一些漂亮功能)
  • HelloWorld程序排除了 ElasticSearch 实例端点,以及用户和密码(可以在 ElasticSearch 管理 GUI 中创建)

必需的“Hello World”程序参数

玩得开心!

候选资格& 2020 年的参议院

原文:https://towardsdatascience.com/electability-the-senate-in-2020-a69622a04881?source=collection_archive---------31-----------------------

模拟民主党竞争者之间的差异

目前,有 12 个主要竞争者争夺民主党的总统候选人。压在选民心头的一个重要问题是:那些候选人在大选中能有多出色?

第二个同样重要的问题:*参议院的组成会发生什么变化?*这可能是民主党总统政策变化的主要限制因素,而且无论哪个政党控制总统职位,这也可能对司法部门的权力平衡产生重大影响。

一个图表,显示每个候选人的候选资格的证据平衡(正面是好的,负面是坏的),以及根据可用信息量计算的证据强度。

我将尝试用一个简单的数据驱动的开源模型来回答这些问题,使用民调数据(来自 FiveThirtyEight 的民调跟踪)和过去的选举数据(参议院和总统数据来自莱普的图集);来自维基百科、Ballotpedia 和各种州网站的同州内比较数据)。

即使对民主党赢得 2020 年总统大选的机会持乐观态度的人,也有理由对民主党获得参议院多数席位的机会持悲观态度。民主党人要么需要一个有巨大影响力的总统候选人,要么需要一个比他们的总统候选人表现更好的参议院候选人。

建立选举的基线模型

模拟选举的第一步是建立一个基线估计,粗略估计 2020 年选举在一个通用的民主党候选人的情况下会是什么样子。为了做到这一点,我将把以前选举的数据放在一起,创建一组合理的基线模型。

六个基线模型,总结了这些模型对民众投票百分比和选举人投票总数的预测。“最民主党”和“最共和党”的模型是基于从 1992 年到现在最强的总统差额。

模拟 2020 年选举的第一个也是最明显的方法是假设它将与 2016 年选举一样。加权平均模型根据近期(每四年选举权重减半)和票数(平方根)对过去的选举进行加权。因此,投票率较高的选举权重更大,该模型给出的预测与 2016 年相似。

趋势模型基于五次选举(1996 年至 2016 年),使用线性回归对每个州的前六次选举进行推断。2018 年波浪模型将 2018 年众议院选举添加到趋势模型中。当我们从左到右,模型从更多的共和党转向更多的民主党。

普遍接受的观点是,长期趋势有利于民主党;另一方面,美国历史充满了周期性和反周期性的潮起潮落。

针对候选人之间的差异调整模型

下一步是为每个候选人调整模型*。基线模型被视为对民主党候选人表现的估计。*

为了进行这种调整,我使用了同一州、同一年或同一民意调查中候选人和典型(中间)民主党人之间的差异。每一个都被认为是对该候选人和普通民主党候选人之间差异的估计。

一个州的候选人的预测投票份额的基本控制方程。这是基于选举中的投票份额、同一投票或选举中的中值投票份额,并基于投票或选举的规模、2020 年选举前的时间以及地理相关性(s_i)进行加权。

然后,使用投票的大小及其日期对这些投票进行加权,经过加权平均模型中用于过去选举的相同的精确加权函数。然后,基线模型以固定的权重重新加入,如果缺乏证据,这使得预测稍微保守一些。

已处理数据的快照。“奖金”是指贝内特增加的民主党份额,而“惩罚”是指贝内特的对手增加的共和党份额。

因此,例如,2010 年麦克·班尼在科罗拉多州获得了 48.1%的选票,而普通民主党人获得了 44.7%的选票,这一事实让我们估计,与普通民主党人相比,麦克·班尼将获得额外的 3.2%的选票。这些信息与所有其他可用信息相结合——在这种情况下,是 2016 年的另一次选举和最近的三次全国民调——以产生对麦克·班尼和普通民主党人之间差异的特定州估计。

为了模拟科罗拉多州的总统选举,Bennet 以前在科罗拉多州的选举和民意调查都被计算在内,以及我们在科罗拉多州的基线模型。全国民意测验的权重被打了 0.25 的折扣。对于邻近的州,如新墨西哥州,该模型将全国民调和科罗拉多州选举的权重都乘以 0.25。对于更远的州,如佛罗里达州,科罗拉多州的选举乘以 0.05 的权重。

在麦克·班尼的例子中,我们仅有的一点信息是积极的,因此模型预测他将比一般的民主党人获得更多。

包括麦克·班尼在内的许多候选人在他们的家乡州比典型的民主党人做得更好,因此在模型中获得了家乡州的优势——这符合传统智慧(例如,见本文)。

候选人

一般来说,我们可以根据信息的强度将候选人分成三组。

拥有许多民意测验的候选人

首先,我们有一些候选人已经在许多面对面的投票中表现突出:乔·拜登、伯尼·桑德斯、伊丽莎白·沃伦和皮特·布蒂吉格。根据上述方法,对这些候选人来说,投票数据比他们过去的选举表现起着更大的作用。

与同一民调中的民主党中值相比,这些群体的紧张程度相当明显。Buttigieg 和 Biden 之间的加权平均差异在 5 个点的数量级。民意测验用具有较高权重的较暗阴影绘制;权重依次基于样本大小和新近性。

拜登和桑德斯的民意测验比沃伦和布蒂吉格好。这种差异随着时间的推移一直非常一致——远远超过民主党候选人和特朗普之间的差距,这种差距随着时间的推移和不同众议院效应的民意调查而显著变化。

顶行中的上一个选举模型;最下面一行是加权平均模型。

由于拜登和桑德斯在过去的选举中也比典型的民主党人做得更好,而沃伦和 Buttigieg 做得更差,该模型毫不含糊地预测拜登和桑德斯会比沃伦和 Buttigieg 做得更好。

顶行中的趋势模型;底排 2018 款 wave 车型。

任何民主党候选人都可能赢得或输掉选举,值得注意的是,即使是我们最好的估计也有很多不确定性,特别是在这种情况下。可能这些候选人中的一些人有隐藏的弱点或隐藏的优势,而这些还没有在投票中显现出来。选举团是混乱的,这里和那里的几个点可以产生非常大的差异。

可能这些候选人中的一些人有隐藏的弱点或隐藏的优势,而这些还没有在投票中显现出来。同样值得注意的是,在皮特·布蒂吉格表现的模型中,大量未承诺的投票者与较低的知名度成对出现。相应地,我们应该减少对模型根据民意测验预测其表现的能力的信任:许多选民尚未形成对 Buttigieg 的看法。

这种差异在趋势模型中最为显著。

然而,虽然名字认知度在扭曲民调数字方面发挥了作用,但名字认知度类似或更低的其他候选人在面对面的民调中比皮特·布蒂吉格获得了更好的民调——最明显的是贝托·奥罗克(Beto O'Rourke),尽管全国的名字认知度类似,但他的面对面民调显然更好。

竞选全州公职的候选人

在 12 名主要候选人中,有 7 人过去竞选过全州的公职,包括在许多激烈的民意调查中表现突出的四名领先者。

民主党候选人在过去选举中的表现。更久远以前的选举逐渐变得透明。

第二,我们有一些候选人没有在很多全国性的民意调查中出现过,但他们竞选过全州的公职:艾米·克洛布查尔、麦克·班尼和德瓦尔·帕特里克。对于这些候选人,我的模型主要依靠他们家乡州过去的选举表现来推断全国的表现。

正如我们在上面的图表中看到的,这产生了对麦克·班尼有利的结果,对 Amy Klobuchar 非常有利的结果,对 Deval Patrick 不利的结果。Klobuchar 在明尼苏达州选举中的表现确实非常出色,大大超过了与她一起竞选的所有其他民主党人。此外,明尼苏达州靠近几个战场州——爱荷华州、威斯康星州和密歇根州。

其他候选人

还有另外五位著名的候选人,他们以前从未竞选过州级职位,也没有在很多面对面的民意调查中出现过。这包括杨安泽,塔尔西·加巴德,汤姆·斯泰尔,迈克尔·彭博,约翰·德莱尼。在这种情况下,我们的模型没有说太多——没有足够的信息。更糟糕的是,我们仅有的一点点信息可能会受到低知名度的严重影响。

在同一次民意调查中,与典型的民主党人相比的加权平均民意调查,结合了支持和反对票数的变化,根据进行的民意调查的数量绘制。前候选人包括在内,以显示一个更完整的画面。

从历史上看,提名一个从未竞选过州级职位的候选人是不寻常的。我个人认为,杨安泽和塔尔西·加巴德最有能力吸引那些通常不会投票给民主党人的人。由于她所吸引的负面媒体和她在党内地位显赫的敌人,加巴德可能很难保住民主党的选票。

添加统计噪声以增强鲁棒性

现在,我们所看到的是一个非常大而复杂的可能结果空间中的一个非常稀疏的样本。这些结果有多可靠?也就是说,在对单个模型进行小改动的情况下,它们的表现如何?选举团是一个混乱的系统,一小部分选票的变化可以产生惊人的大变化。

我们可以进行多次模拟,对数据进行随机调整。如果这些调整将邻近的州联系起来,我们就能捕捉到这些地区经常一起移动的方式。

选举人投票结果的小提琴图,每个候选人在六个基线模型中各有 100 个模拟。基准选举人票总数包括 270 张(获胜)以及麦凯恩、罗姆尼、希拉里、川普和奥巴马最近的选举表现。前候选人贝托·奥罗克、卡玛拉·哈里斯和科里·布克都包括在此图中,以创建一个更广泛的比较基础。

看待这个问题的一个方法是观察每个候选人的结果分布。艾米·克洛布查尔被评为更强的事实并不是基线选择的一个怪癖;这是因为该模型包括了过去的选举记录,而 Klobuchar 有着非同寻常的选举历史。

事实上,当我们在模拟中加入噪音时,我们在六个特定模型中观察到的差异并没有消失。可能的全国总支持度只有几个百分点的差异,就可能导致选举团选举结果的巨大差异。

参议院

总统任期内的参议院选举受到总统提携的强烈影响。民主党总统候选人将对参议院的构成产生影响;从逻辑上讲,一个更强大的候选人将有助于赢得更多的参议院席位。

从基线模型中选择。

有 35 个席位等待选举,包括乔治亚州的两个席位;大多数席位的上一次选举是在 2014 年。共和党拥有其中的 23 个席位。原则上,这意味着共和党是脆弱的;然而,大多数共和党现任者强烈支持连任。

作为一个群体,四个中间基线模型(共和党赢得 51 至 55 个席位范围内的大多数席位)符合由拉里·萨巴托、政治、库克政治报告和大多数其他专家预测者提供的专家预测。然而,只有 2018 年波浪模型避免了任何不寻常的基线预测;西弗吉尼亚、阿拉巴马和阿拉斯加对民主党来说都是困难的州。

值得注意的是,这个模型也是关于总统选举最乐观的模型之一:2018 年 wave 模型预测,即使是最弱的民主党总统候选人也可能赢得总统竞选。

2018 年波浪模型的预测

即使民主党人在与 2018 年中期选举类似的选举中赢得总统大选——这一点绝不是确定的——他们也很难在参议院赢得哪怕是微弱的多数。

有一个重要的通配符值得注意:伊丽莎白·沃伦和伯尼·桑德斯代表着共和党州长的州——这意味着如果他们离开参议院,他们可能会被共和党任命的人取代,至少暂时是这样。这两个州都有可能在特别选举中选出民主党的替代者,但这种特别选举特别难以提前预测(参见马萨诸塞州 2010 年,阿拉巴马州 2017 年);为了报告选举结果,我把这算成了两大政党各占一半的席位。

这些预测非常可信——尽管投票总数有显著差异,但就赢得的席位而言,所有候选人都非常相似。为了赢得参议院多数席位,民主党需要超越近期历史建立的预期,特别是在南方。

给参议院模式增加噪音

有了合理基线模型的明确选择,很容易给参议院模型添加噪声——这最终会在候选人之间产生更明显的差异。大多数候选人的中值结果略高于噪声前的基线预测,这是一个值得解释的事实。

我们注意到的差异都没有消失;然而,加入噪音会让新的差异出现。

在 2018 年的基线模型中,预计大多数战场州将以微弱优势再次选举共和党参议员。给模型增加噪音表明民主党很可能在某个地方获得额外的席位——也许是蒙大拿州,也许是缅因州,也许是北卡罗来纳州。

在系统中具有数据的所有候选者上的平均噪声添加预测。

值得重复的是,总体而言,2018 年的 wave 模型对民主党人来说是一个相当乐观的模型。这一模型表明,民主党有机会在德克萨斯州等州赢得参议院席位,在德克萨斯州,几十年来没有民主党人赢得过全州选举。

这不是唯一的——也不是最复杂的——可能的选举结果模型;但是它强调了在整个国家投票中仅仅几个百分点的差异的巨大影响。

结束语

我们试图比较民主党竞选者赢得选票的能力。选举人团和参议院都是由州一级的赢家通吃选举决定的,因此全国范围内几个百分点的微小变动都会产生巨大影响。

领先者之间有一个清晰的模式。乔·拜登和伯尼·桑德斯在他们家乡的选举中表现得比典型的民主党人更好,在面对面的民意调查中也比典型的民主党人表现得更好。伊丽莎白·沃伦和皮特·布蒂吉格在过去的全州选举和民调中表现更差。

强度被估计为投票者或投票应答者数量的时间衰减平方根之和。证据平衡是一个加权和。前候选人包括在内,以提供一个更完整的画面。

对于其他候选人,我们掌握的信息更少。Amy Klobuchar 在明尼苏达州的全州选举中一贯表现强劲,确实非常出色,但这与全国民调结果并不相符。麦克·班尼当选的证据是积极的,尽管有限。

对于那些以前没有竞选过州级职位,也没有在许多全国性民调中出现过的候选人,比如杨安泽,我们只是还没有太多好的信息。

选举审计:发现重新计票中的错误

原文:https://towardsdatascience.com/election-audit-finding-errors-in-recounts-3886685a9948?source=collection_archive---------38-----------------------

作者插图

选举是我们民主的基石,对我们社会的发展具有深远的影响。这都是关于数据的。这是一个故事,讲述了二十年前我们如何在丹麦解决了一个关键的数据质量问题,我们的解决方案直到今天仍在使用。

我们认为我们应该使用复杂的分析,但最终归结为正确指标的设计。

问题是

在丹麦,选举用纸质选票卡进行。投票站从早上 8 点到晚上 8 点开放。投票结束后立即开始计票。在选举当晚,随着计票的进行,每个投票站都会报告每个政党的票数,从而可以计算出每个政党获得的授权数,并由此生成选举产生的政治格局的图像。第二天进行重新计票,确定候选人的人数,从而确定哪些候选人获得了哪些授权。

显然,将一个政党的候选人的候选人票相加,应该会给出该政党在选举当晚的数字,从而提供对计票的检查。然而,负责选举的内政部怀疑存在未被发现的错误。

作者插图

独立政党计票员很容易发现选票卡从一个政党的候选人转移到另一个政党的候选人(图中的 1)。但如果候选人来自同一个政党(图中为 2),则情况并非如此。计票时,选票卡以 25 张为一捆,4 捆在一起,100 张为一捆。束可以在党内的候选人之间移动(图中的 2)。当你投票时,你可以为一个政党或候选人投票。政党的选票可能会转移给政党的候选人(图中的 3),反之亦然。空白选票也可能被篡改,变成候选人(图中的 4)或政党的选票。

我当时在一家小型咨询公司 BusinessMinds(已经不存在)工作,我们的任务是开发一种方法来检测这种错误。首先,我们认为我们应该引入来自分析或数据挖掘的奇特方法,这在当时是一个大肆宣传的术语。我们手头有前几次选举的选举数据,但每次选举都有很大的变化。在原子层面上,即每个投票站的每个候选人,根本没有可识别的趋势。因此,只能在一次选举中进行分析。

方法

不仅投票会随着时间的推移而改变,而且在地理上也会有所不同:一些政党在城市中的地位更高,而其他政党则在农村地区。通过研究这些数据,我意识到,在缩小投票区范围时,一个相当稳健的模式将是总体指标变化的单调性。为了澄清这一点,我们需要看看丹麦的选举制度。

丹麦选举按地理等级组织(括号中的描述参见下图):

—国家
— — 3 个选举省(蓝线和文字)
——10 个多议员选区(红线和文字)
——92 个提名区(绿色区域,黑色文字)
———1384 个投票区(未描绘)

来自丹麦的议会选举制度(一个选区没有画出来:博恩霍尔姆岛)

党组织在提名区一级提名候选人。地方组织将在他们的提名区宣传他们自己的候选人,但候选人可以在整个选区,即在许多提名区当选。

为了应对政党受欢迎程度的地区差异,候选人票数与政党票数的比率按不同的地理级别计算:

这里的政党选票指的是投给该党的所有选票,或者投给该党的个别候选人,或者投给该党。这个比例叫做候选比例。如果一个候选人在整个选区中同样受欢迎(或不受欢迎),那么这个比例在各个地理级别上是不变的。

与此同时,候选人在党内的突出地位与该党在地区的受欢迎程度无关:在该党获得许多选票的地区,20%的政党选票与在该党获得很少选票的地区一样具有代表性。

然而,候选人的受欢迎程度通常因地域而异。通常候选人住在提名区,离家近的人比离家远的人更出名。因此,在投票区一级观察候选人比例,通常会发现候选人在当地投票站的比例最高。为了衡量对候选人的额外关注,候选人的比例在不同的地区进行了比较:投票地区的候选人比例除以提名地区的候选人比例。

如果候选人在各个地区的受欢迎程度相同,那么这个比率在任何地方都是 1。因此,偏离 1 表示候选人受欢迎程度的地理变化。为了获得更对称的测量,应用对数。在这里,这个度量被称为亲和力:

亲和力与 0 的偏差是候选人以及政党的受欢迎程度的局部变化的度量。可以在分母中使用选区/地区候选人比率,这将产生更清晰的候选人衡量标准。但这里的目的是确定来自同一政党的候选人之间,即同一选区的候选人之间可能的选票转移。

显然,亲和力将分布在 0 附近。这种模式相当稳健,在候选人的家乡投票区有一个峰值,从那里开始下降。这是最近一次大选中所有候选人在丹麦的分布情况(分成 50 个箱):

作者插图

可以看出,分布被避开,这是一个边界问题。许多候选人获得的选票相对较少,因此负面亲和力的变化有限。

人们发现,这种避开的钟的尾部末端是误差的良好指示器。钟的反面更敏感。如果在一个投票区的一个政党中的两个候选人之间存在投票偏移,则可以识别出两个相应的异常值:一个是一个候选人的钟形负侧,一个是另一个候选人的钟形正侧。

我们查看了电子表格中的简单描述,并创建了一个列表,列出了所有投票区一级的投票,按亲缘关系的平方降序排列。然后,我们从顶部开始搜索同一投票区同一政党的记录对。就这么简单。

调查的结果

这个方法证明是成功的。我们参与了两次大选和一次欧洲议会选举。从那以后,整个地区都被内政部外包出去了,我们再也不参与了。

在每次选举中,我们都会发现潜在的错误,然后教育部会评估这些错误,以决定是否应该再次重新计票。如果是这样的话,当地的市长将被联系并被告知重新计票。在所有选举中,这种重新计票导致数百张选票的数量级调整。

尽管我们不再是这一过程的一部分,但这一方法成为了丹麦选举的标准工具。当我们开始时,点票的法律规定是政党选票应在投票区一级进行,而候选人选票应在选区一级进行。实际上,候选人的投票是在投票区一级报告的,这使我们能够进行分析。但是为了确保这些数字的可用性,《选举法》进行了修订。

作者插图

从这个项目中主要学到的是,在分析数据时选择合适的指标至关重要。这项任务并不简单,但是开发亲和力测量使分析变得尽可能简单。数据准备的目的是获得尽可能强的信号以进行探索,事实证明,亲和力检查足以识别选举重新计票中的错误

细节

亲和力的定义

更具体地说,由于 log(0)以及 0/0 和∞/∞未定义,有必要处理一些异常:

  1. 如果投票区中的政党计票为 0,即候选人计票也为 0,则亲和力设置为 0。
  2. 如果提名区中的政党计票为 0,即候选人计票也为 0,则亲和力设置为 0。这不太可能发生。
  3. 如果提名区中的候选人票数为 0,这不是错误,因为这涵盖了多个投票区。因此,亲和力被设置为 0。
  4. 如果投票区中的政党计票不为 0,并且候选人计票为 0,则:如果政党计票 > β(其中β是某个阈值),则候选人计票被设置为 1,否则亲和度被设置为 0。

第三个规则背后的推理是在候选人在投票区没有获得任何选票的情况下获得亲和力的指示。不能忽视候选人投票数为 0,但我们需要处理 log(0)问题。这是通过使用可能的最低票数 1 来实现的。使用小于 1 的(十进制)数是没有意义的。所得的相似性将是替换规则的特征,而不是低投票计数的特征。然而,如果政党票数非常低,这种替换将导致不成比例的大候选人比例。为了避免引入阈值,低于该阈值的情况被忽略,即相似性被设置为 0。阈值通常设置为 10。

投票站

如上所述,共有 1384 个投票站。下图显示了每个投票点的投票数。这反映了人口密度的明显变化。本文中的所有数字都是基于上次大选。

作者插图

政党名单投票和个人投票

一个选民可以投票给一个政党(政党名单投票)或一个候选人(个人投票)。两者在各缔约方的分布情况有所不同。

作者插图

对于两个大党 A(社会民主党)和 V(自由党)来说,大多数选票是个人选票。这些是传统的政府政党。通常总理来自这两个政党中的任何一个。他们有强大的地方组织。丹麦政府几乎总是少数党政府,通常是两到四个政党的联盟,然后依靠支持他们的政党来确保他们的政治的多数。实际上,上次大选的结果是产生了一个极不寻常的一党政府(A ),三个支持党(F 和 B)在议会中占了一半以上的席位。

与两大政党相反,还有更理想主义的政党,如(大多数左翼社会主义者)和 D(右翼)。政党名单投票占优势。

e 基本都是单人党。然而,它拥有最大比例的政党名单选票。原因是,这个人只是十个选区中的一个选区的候选人,因此在另一个选区,有一些鲜为人知的地方“替身候选人”。因此,在这些地区,绝大多数选票是政党名单选票。

无论是 K(基督教民主党),E(单一牧师,中间自由派)还是 P(民粹主义,反移民)都没有获得足够的选票来赢得议会席位。

亲和力

下图显示了以上定义的八名候选人(此处称为 a-h)在多个以颜色标识的投票区的相似性。因此,每个颜色段代表一个投票区,八个条形代表特定政党的八名候选人。

作者插图

该图给出了α值变化的印象。但事实上,我篡改了数据:对于用粉色标识的投票区,我将候选人 a 的 20 张选票转移到了候选人 T2 的 g 的 T3。有明显的迹象表明, a 现在得到的选票太少,而不清楚哪个候选人得到了太多的选票。有时只能识别非自愿捐献者,有时可以区分捐献者和接受者。

延伸阅读

丹麦的议会选举制度,内政和卫生部与丹麦议会,哥本哈根,2011 年

修正法(丹麦语)

选举特辑:使用变形金刚检测假新闻

原文:https://towardsdatascience.com/election-special-detect-fake-news-using-transformers-3e38d0c5b5c7?source=collection_archive---------36-----------------------

用数据做很酷的事情

介绍

美国 2020 年大选在即。在选举前后,社交媒体上发布的假新闻是一个巨大的问题。虽然有些假新闻是为了歪曲选举结果或通过广告赚快钱而故意制作的,但虚假信息也可以由被误导的个人在其社交媒体帖子中分享。这些帖子可以迅速成为病毒模糊。大多数人相信被很多人喜欢的帖子一定是真的。

对于机器学习模型来说,检测假新闻并不是一件容易的事情。这些故事中有许多写得非常好。机器学习仍然有帮助,因为:

  • 它可以检测到该书写风格与它的数据库中被标记为假的相似
  • 故事中事件的版本与已知的真实情况相矛盾

在这篇博客中,我们使用 BERT 和 T5 变压器模型构建了一个假新闻检测器。T5 模型在检测 2016 年选举前后发布的真实假新闻方面表现非常好,准确率高达 80%。

“假新闻检测器”的完整代码在我的 Github 这里 公开。

在深度学习分析,我们非常热衷于使用数据科学和机器学习来解决现实世界的问题。请联系我们,与我们讨论 NLP 项目。

Unsplash 的免版税—https://unsplash.com/photos/EQSPI11rf68

数据集

对于这篇博客,我们使用了 Kaggle 数据集——了解假新闻的真相。它包含被 BS Detector 标记为虚假或有偏见的新闻和故事,BS Detector 是 Daniel Sieradski 的 Chrome 扩展。BS 检测器将一些网站标记为假网站,然后从这些网站上抓取的任何新闻都被标记为假新闻。

数据集包含大约 1500 个新闻故事,其中大约 1000 个是假的,500 个是真的。我喜欢这个数据集的原因是,它包含了在 2016 年大选最后几天捕捉到的故事,这使得它与检测选举期间的假新闻非常相关。然而,给假新闻贴上标签的挑战之一是,需要花费时间和精力来审查故事及其正确性。这里采用的方法是认为所有来自标有 BS 的网站的故事都是假的。情况可能并不总是如此。

标记为真实的故事的一个例子是:

ed state  \nfox news sunday reported this morning that anthony weiner is cooperating with the fbi which has reopened yes lefties reopened the investigation into hillary clintons classified emails watch as chris wallace reports the breaking news during the panel segment near the end of the show \nand the news is breaking while were on the air our colleague bret baier has just sent us an email saying he has two sources who say that anthony weiner who also had coownership of that laptop with his estranged wife huma abedin is cooperating with the fbi investigation had given them the laptop so therefore they didnt need a warrant to get in to see the contents of said laptop pretty interesting development \ntargets of federal investigations will often cooperate hoping that they will get consideration from a judge at sentencing given weiners wellknown penchant for lying its hard to believe that a prosecutor would give weiner a deal based on an agreement to testify unless his testimony were very strongly corroborated by hard evidence but cooperation can take many forms  and as wallace indicated on this mornings show one of those forms could be signing a consent form to allow   the contents of devices that they could probably get a warrant for anyway well see if weiners cooperation extends beyond that more related

一个假的故事是:

for those who are too young or too unwilling to remember a trip down memory lane \n  debut hillary speaks at wellesley graduation insults edward brooke senates lone black member \n  watergate committee says chief counsel jerry zeifman of hillarys performance she was a liar she was an unethical dishonest lawyer she conspired to violate the constitution the rules of the house the rules of the committee and the rules of confidentiality \n  cattlegate as wife of arkansas governor she invests  in cattle futures makes  \n  whitewater clintons borrow money to launch whitewater development corporations several people go to prison over it clintons dont \n  bimbo eruptions bill and hillary swear to steve kroft on  minutes bill had nothing to do with gennifer flowers \n  private investigators we reached out to them hillary tells cbs steve kroft of bills women i met with two of them to reassure them they were friends of ours they also hire pis to bribe andor threaten as many as twodozen of them \n  health care reform hillary heads secret healthcare task force sued successfully for violating open meeting laws subsequent plan killed by democraticcontrolled house \n  ....

这些故事平均有 311 个单词,有些故事超过 1000 个单词。

模特培训

在这个练习中,我们训练了来自 HuggingFace — 1 的两个模型。具有序列分类头的 BERT 和具有条件生成头的第二个 T5 变换器模型。BERT 模型在验证集上检测假新闻的准确率为 75%,而 T5 模型能够达到 80%的准确率。因此,我们将在博客的其余部分集中讨论如何训练 T5 模型。

T5 是文本到文本模型,这意味着它可以被训练成从一种格式的输入文本到一种格式的输出文本。这使得该模型非常通用。我个人用它来训练文本摘要。在这里查看我的博客。并使用它来建立一个琐事机器人,它可以在没有任何上下文的情况下从内存中检索答案。点击查看这篇博客。

T5 —文本到文本转换转换器。图片来自 T5 纸。

将我们的分类问题转换为文本到文本的格式

Huggingface T5 实现包含一个条件生成头,可以用于任何任务。对于我们的任务,我们的输入是真实的新闻故事,输出是文本——真实的/虚假的。

对于输入文本,我们将最大标记长度设置为 512。如果故事小于 512,那么将在结尾添加一个标记。如果故事比较大,那么它们会被截断。对于输出,令牌长度设置为 3。下面是它的代码片段。请在这里找到我的 Github 上的完整代码。

source = self.tokenizer.batch_encode_plus([input_], max_length=self.input_length, padding='max_length', truncation=True, return_tensors="pt")targets = self.tokenizer.batch_encode_plus([target_], max_length=3, padding='max_length', truncation=True, return_tensors="pt")

定义 T5 模型类

接下来,我们定义 T5 模型微调类。模型正向传递与其他变压器模型相同。因为 T5 是文本-文本模型,所以输入和目标都被标记化,并且它们的注意力屏蔽被传递给模型。

**def** forward(self, input_ids, attention_mask=**None**, decoder_input_ids=**None**, decoder_attention_mask=**None**, lm_labels=**None**):**return** self.model(input_ids,attention_mask=attention_mask,decoder_input_ids=decoder_input_ids,decoder_attention_mask=decoder_attention_mask,labels=lm_labels)

在生成步骤中,解码器的输出被限制为令牌长度 3,如下所示:

**def** _generative_step(self, batch) :t0 = time.time()*# print(batch)*inp_ids = batch["source_ids"]generated_ids = self.model.generate(batch["source_ids"],attention_mask=batch["source_mask"],use_cache=**True**,decoder_attention_mask=batch['target_mask'],max_length=3)preds = self.ids_to_clean_text(generated_ids)target = self.ids_to_clean_text(batch["target_ids"]

该模型通过检查生成的标签(假/真)是否与实际标签匹配来测量准确度分数。

模型训练和结果

使用 8 的批量大小训练 t5 small 30 个时期。这个模型花了大约一个小时来训练。权重和偏差用于监控训练。在线 Github 代码已经将 wandb 集成到 Pytorch Lightning 中用于培训。

我在令牌长度 512 和 1024 上训练了一个 T5 small。这两个模型表现相似,准确率接近 80%

T5 小型假新闻检测器— Val 集合准确度分数

在 val 集上测试 T5 表明,该模型具有令人印象深刻的检测假新闻的能力。

Input Text: classify: russias most potent weapon hoarding gold shtfplancom this article was written by jay syrmopoulos and originally published at the free thought project editors comment he who holds the gold makes the rules fresh attempts at containing russia and continuing the empire have been met with countermoves russia appears to be building strength in every way putin and his country have no intention of being under the american thumb and are developing rapid resistance as the us petrodollar loses its grip and china russia and the east shift into new currencies and shifting
world order what lies ahead it will be a strong hand for the countries that have the most significant backing in gold and hard assets and china and russia have positioned themselves very
well prepare for a changing economic landscape and one in which selfreliance might be all we have russia is hoarding gold at an alarming rate the next world war will be fought with currencies by jay syrmopoulos with all eyes on russias unveiling their latest nuclear intercontinental ballistic missile icbm which nato has dubbed the satan missile as tensions with the us increase moscows most potent weapon may be something drastically different the rapidly evolving geopolitical weapon brandished by russia is an ever increasing stockpile of gold as well as russias native currency the
ruble take a look at the symbol below as it could soon come to change the entire hierarchy of the international order potentially ushering in a complete international paradigm shift...Actual Class: FakePredicted Class from T5: Fake

结论

T5 是一款很棒的车型。有了足够的数据,针对任何 NLP 问题微调转换器变得很容易。这篇博客表明 T5 可以很好地检测假新闻。

我希望您尝试一下代码,并训练自己的模型。请在下面的评论中分享你的经历。

在深度学习分析,我们非常热衷于使用机器学习来解决现实世界的问题。我们已经帮助许多企业部署了创新的基于人工智能的解决方案。如果你看到合作的机会,请通过我们的网站这里联系我们。

参考

  • T5 变压器
  • 拥抱脸变形金刚
  • 真实新闻与假新闻

选举特辑:训练一台 GPT-2 生成唐纳德·川普的演讲

原文:https://towardsdatascience.com/election-special-train-a-gpt-2-to-generate-donald-trump-speeches-b66fc3aa92b9?source=collection_archive---------39-----------------------

用数据做很酷的事情

来自 Unsplash 的免版税—https://unsplash.com/photos/ls8Kc0P9hAA

介绍

在这篇关注美国 2020 年大选的第二篇博客中,我们根据唐纳德·特朗普的演讲训练了一个 GPT-2 模型。通过最少的训练,GPT-2 模型成功地复制了他的风格,并开始以他的风格写作。参见 GPT-2 生成的 Donald Trump 演讲样本。听起来确实像他!

As president, I kept my promise. Nobody else did. We set records. We set records. Thank you very much. Great job. We set records. And by the way, there's two really greats, right? There's Sonny Perdue and there's Barack Hussein Obama. The two greats. Really great. One has become the most powerful president in the history of our country. I said, "How powerful is that?"

GPT-2 模型去年由 Open AI 发布。这是一个已经在 40GB 互联网文本上训练过的语言模型。该模型可以在任何文本样本上进行微调,以根据输入文本调整其生成样式。在这篇博客中,我们使用 HuggingFace repo 的实现 GPT-2,看看你如何调整它来为 DT 写演讲稿。

我们还写了一篇关于使用 T5 模型检测假新闻的选举专题博客。点击查看。

在深度学习分析,我们非常热衷于使用数据科学和机器学习来解决现实世界的问题。请联系我们,与我们讨论 NLP 项目。

数据集

对于这篇博客,我们使用了 Kaggle 数据集——唐纳德·特朗普的集会。这个数据集有他的 35 次演讲。一半的演讲来自去年年底,其余的来自今年。最新的演讲来自他 2020 年 9 月在塞勒姆、费耶特维尔和亨德森的集会。

在我们开始根据这些数据训练语言模型之前,我们需要以 GPT 新协议要求的格式获取数据。GPT-2 需要逐句传递数据。

作为数据预处理的一部分,我们执行以下操作:

  1. 把演讲分成句子
  2. 将前 85%的句子保留在训练集中,其余的放在验证集中。验证集将用于测量困惑分数

实现这一点的代码片段如下。NLTK 库用于将语音句子标记成句子。

train_sentences = []
val_sentences = []
for filename in sorted(glob.glob(os.path.join('DT_speeches', '*txt'))):print(filename)f = open(filename, 'r')file_input = f.readlines()for cnt, line in enumerate(file_input):sentences = nltk.sent_tokenize(line)for i , sent in enumerate(sentences):if i <= len(sentences)*0.85:train_sentences.append(sent)else:val_sentences.append(sent)

训练和赋值语句列表被写入文本文件。GPT-2 模型将使用这些文本文件进行训练。

微调 GPT-2 语言建模

让我们从 Giphy 训练它 GIF—https://media.giphy.com/media/g0Kzu8bTbGPPEH0hSm/giphy.gif

GPT-2 是一种语言模型,可以在许多下游任务上进行微调,包括语言建模、摘要等。要了解更多关于语言建模的知识,请阅读我的这个博客。

要微调你的模型,首先克隆最新的拥抱脸变形金刚回购。

git clone [https://github.com/huggingface/transformers](https://github.com/huggingface/transformers)

语言模型微调脚本位于 examples/language-modeling 下。使用以下命令开始训练:

python run_clm.py \--model_name_or_path gpt2 \--train_data_file <path to your train text file> \--eval_data_file <path to your val text file> \--do_train \--do_eval \--output_dir output-gpt2 \--block_size=200\--per_device_train_batch_size=1\--save_steps 5000\--num_train_epochs=5 \

上面的主要超参数是:

  • model_name_or_path: gpt2 将训练 gpt2 小模型。如果要训练中等型号,请指定 gp T2-中等
  • 块大小:输入训练集将被截断成这个大小的块用于训练。该参数是注意窗口。在我个人的 GPU 上,200 的块大小是我可以训练的最大值。
  • save_steps:保存检查点之前的持续时间

除此之外,我们还有批量大小和次数。

我能在大约 20 分钟内在 GTX-1080 Ti 上用上述配置训练 GPT-2 小型飞机。经训练的模型在验证集上具有 14 的困惑分数。这还不错。我认为,如果你有更多的计算,你可以尝试更长的块大小和 GPT-2 中等模型,以进一步提高困惑分数。

测试训练好的 GPT-2 模型

为了测试训练好的模型,我们导航到 transformers repo 中的 examples/text-generation 文件夹。为了生成文本,我们需要将路径传递给训练好的模型。我们也可以通过一个提示来给生成指明方向。运行生成的命令如下。

python run_generation.py \--model_type gpt2 \--model_name_or_path output-gpt2/ \--length 300 \--prompt "It's a fine Tuesday morning."

我微调的模型生成了以下有趣的片段。

It's a fine Tuesday morning. Democrats want to give illegal immigrants free healthcare, free education, and even free healthcare to their children. Republicans want to give all citizens the right to self-defense. Today, we've added a great new provision to the US healthcare law called Obamacare. That means if you go to the doctor, you're protected from having to pay a fortune for the plan of your choice. You're not going to have to worry about premiums.

可以看出,GPT-2 了解到民主党人更喜欢开放移民和免费医疗。

I think we are going to have the greatest year we've ever had. We're going to have the greatest year in the history of our country. Can you believe it? And I say that because for years and years, these guys in the back were saying, "We love this guy." I'm talking about Donald Trump, he's great. Remember all those debates when you couldn't see the crowd? Well, it was like the H1NI infected people getting small amounts of water. He was very weak. It wasn't quite as strong. I guess he should have never been given the treatment. Remember all those debates? I was in the middle of debating him and he went, "Well, this is going to be short." He was just beginning. Now they have him talking all over. I was watching him. He was talking about himself. "Well, it's true. I'll never be able to compete with you, Donald Trump."

在这里,GPT-2 正在复制他自我鼓掌的风格——“我们爱这个家伙。”,“嗯,是真的。我永远无法和你竞争,唐纳德·特朗普。”

结论

在唐纳德·特朗普的演讲上微调 GPT2 模型既有趣又容易。令人鼓舞的是,只需很少的训练,该模型就能够复制 DT 词汇表中的风格和关键词。

我希望您尝试一下代码,并训练自己的模型。请在下面的评论中分享你的经历。

在深度学习分析,我们非常热衷于使用机器学习来解决现实世界的问题。我们已经帮助许多企业部署了创新的基于人工智能的解决方案。如果您看到合作的机会,请通过我们的网站这里联系我们。

参考

  • 开启艾 GPT-2
  • 拥抱脸变形金刚
  • 唐纳德·特朗普演讲

伊莱克特拉:掩蔽语言模型的发展

原文:https://towardsdatascience.com/electra-developments-in-masked-language-modelling-3cf1c25fc61a?source=collection_archive---------43-----------------------

这是 ELECTRA 的主要功能概述,此处描述了一个模型:

https://arxiv.org/pdf/2003.10555.pdf

有了 BERT 和 BERT 衍生的变形金刚(XLNet,RoBERTa,ALBERT,任何以芝麻街人物命名的变形金刚),我清楚地知道,作为一个拥有单个 GPU 和没有行业支持的个人爱好者,我自己不可能训练一个深度学习语言模型。当我在 XLNet 上为 AISC 准备现场演示时(在 YouTube 上这里,我看到了埃利奥特·特纳的这条推文:

埃利奥特·特纳发的这条推文的截图

我训练自己模特的模糊梦想破灭了。这是回到 2019 年,即之前的时代。我指的是在 GPT-3 之前,它使用了如此惊人的计算资源,以至于目前只有在你身后有八位数的情况下才能训练。这个模型引起了我的兴趣,理论上,在单个 GPU 上训练四天之后,ELECTRA-small 可以胜过 GPT-1。他们认为完整模型(ELECTRA-base)的性能与 XLNet 和 RoBERTa 相当,而使用的资源只有它们的大约四分之一。很有趣。这是什么方法论?

该模型的架构和大多数超参数与 BERT 中的相同,因此这里不再赘述。

替换令牌检测是他们选择的预训练方法。BERT 用[MASK]有选择地替换序列中的记号,而 ELECTRA 使用生成器用看似合理的替代单词替换记号。

输入序列是记号列表x=【x1,… xn】。MLM 试图用其他似是而非的词来替换 k 个符号,得到一个 k 个掩码的列表[m1,…,mk]。对于这篇论文,他们建议屏蔽掉大约 15%的输入令牌。

这个过程产生了 x ^corrupt,这是一个在 m 个位置插入了看似合理的备选单词的记号列表。

然后,鉴别者的工作就是确定句子中的单词是原词还是改词。

MLM 和鉴别器的损失函数如下:

虽然这看起来很像一个甘,发电机是最大的可能性,而不是敌对训练。另一个区别是,如果生成器生成一个与原始令牌相同的令牌,该令牌将被标记为原始令牌,而不是生成令牌。

实验

这里的基本模型的预训练数据与 BERT 相同,是来自维基百科和图书语料库的 33 亿个标记。伊莱克特-拉奇在 XLNet 数据上接受训练,XLNet 数据通过 ClueWeb、CommonCrawl 和 GigaWord 添加到 BERT 数据中。

模型的评估是在 GLUE benchmark 和 SQuAD 上完成的,两者都在这里解释了。

车型扩展

伊莱克特做了一些改进,提高了模型的准确性。

**权重共享:**生成器和鉴别器中使用的嵌入是共享的。这在训练相同数量的时期时,在没有重量约束的情况下,使用相同的模型参数,在准确性上产生了小的提升。只有嵌入权重是共享的,共享所有权重具有要求两个网络大小相同的显著缺点。为什么这在这里工作得如此好的一个理论是,利用屏蔽语言建模,要被区分的输入记号和被破坏的记号驻留在相同的向量空间中。在这种情况下,生成器学习一个嵌入空间,鉴别器有效地学习一个嵌入空间和嵌入空间之间的变换是没有意义的。

小型发电机:

这在很大程度上是前面扩展的必然结果,因为如果生成器和鉴别器共享所有权重并且大小相同,则模型每个训练步骤需要的计算量是仅使用纯[掩码]令牌时的两倍。在这个模型中,他们探索使用一个 unigram 生成器来生成屏蔽令牌。由于使用了各种尺寸的发生器,他们选定的发生器大约是鉴频器尺寸的 0.25-0.5 倍。

训练算法:

Clark 等人从整体上为 ELECTRA 尝试了多种高级训练算法,并确定了以下内容:

  1. 仅训练发生器(最大可能性)进行 n 步。
  2. 用生成器的权重初始化鉴别器的权重。然后在 n 步中用鉴频器损失函数训练鉴频器,保持发电机的重量不变。

大型型号:

为了与典型尺寸的 SOTA 模型相比较,基本的 ELECTRA 必须相当大。他们使用与 ELECTRA-400k 相同的超参数和训练时间来训练自己的 BERT-Large 模型。

我很好奇的一点是,在这篇论文中,模型相对于彼此需要多长时间来训练是一个有点困惑的问题。他们说的是 ELECTRA-Large 和 BERT-Large 大小一样,但是他们也用和 ELECTRA-400k 一样的超参数和训练时间训练了自己的 BERT。他们描述的 ELECTRA 的卖点是使用更少的物理计算资源,但我希望他们在其他大型模型旁边更明确地概述这些物理和时间资源,以便进行比较。他们确实列出了 train FLOPs(每秒浮点运算次数),这通常可以作为衡量他们的 GPU 计算速度的指标——但在附录中,他们澄清了“运算”被算作数学运算,而不是机器指令(通常是这样)。如果能对所使用的资源以及培训前和培训所花费的时间进行比较,我们将不胜感激。

胶水开发组的结果。

他们自己的模型使用 ELECTRA-400k 中使用的相同超参数进行训练。

效率分析:

他们怀疑,必须分析字符串中的所有记号,而不是填补显式掩码造成的空白,这导致了伊莱克特的效率提高。他们创造了伊莱克特 15%,它只计算被屏蔽掉的 15%令牌的鉴别器损耗。基地伊莱克特在胶水任务上得分 85%,而伊莱克特 15%得分 82.4%,与伯特的 82.2%不相上下。

阴性结果:

在这项研究中,他们尝试了许多训练范式,如模型大小、生成器架构、重量捆绑,有些范式普遍不成功,因此没有出现在论文的主体中。

  1. 战略性地对稀有令牌应用屏蔽。与常规的 BERT 相比,这并没有导致任何显著的加速。
  2. 提高发生器的温度,或不允许正确的字输出并没有改善结果。
  3. 添加一系列句子级别的对比标记,就像 SpanBERT 的蒙面语言建模版本。这实际上降低了胶水和小队任务的模型分数。

结论:

虽然这不是对抗性训练,但它是对比学习如何有效应用于语言的一个例子。从广义上讲,对比学习包括区分观察到的数据点和虚构的例子。BERT、Ernie、XLNet、ELMo、RoBERTa 和 SpanBERT 都引入或扩展了屏蔽语言建模范例,其中模型猜测单个屏蔽标记的正确标记,伊莱克特通过引入屏蔽可能是鉴别器接收的序列中的任何标记的可能性来进一步扩展它。伊莱克特拉现在是拥抱脸和简单变形金刚的一部分。

冠状病毒疫情期间维多利亚州的电力需求

原文:https://towardsdatascience.com/electricity-demand-in-victoria-during-coronavirus-pandemic-30c23ff4e0d?source=collection_archive---------60-----------------------

新冠肺炎·疫情执政期间,澳大利亚第二大州的电力需求模式发生了变化吗?

约书亚·希伯特在 Unsplash 上拍摄的照片

外国媒体普遍将澳洲视为成功遏制新冠肺炎疫情的发达国家的典范。2020 年 7 月,在每日新增病例大幅上升后,澳大利亚人口第二大州维多利亚州推出了一些世界上最严格的流动控制措施。被广泛认为有助于降低病毒传播率的旅行限制,对商业产生了不利影响。在其他指标中,电力需求被认为反映了经济活动的水平。疫情时期经济活动下滑得越厉害,恢复到疫情之前水平的时间就可能越长,也可能越长。本文旨在从 2015 年开始,在近期历史背景下,探讨维多利亚州 2020 年的电力需求,从而阐明这个问题。

数据和异常

来自澳大利亚能源市场运营商( AEMO )的数据包含关于电力需求和价格的信息,以 30 分钟为间隔进行汇总。

有趣的是,在相当多的日子里,电力至少在一天的部分时间里以负价格报价。当这种情况发生时,能源生产商向批发客户支付费用,以获取他们生产的能源。以负价格报价的每日总需求的分数绘制如下。

作者图片

2020 年期间,在一些相关事件和政策公告之前,往往会出现需求比例较高且价格为负值的日子。值得注意的事件之一是维多利亚最大的发电站黑兹尔伍德 (1600 MW)的退役。与其他燃煤发电站一样,它提供了近乎恒定的输出。然而,在 2018 年和 2019 年,几个大型太阳能发电厂 (480 MW 组合标称功率)上线。截至 2020 年 9 月,维多利亚屋顶太阳能的总功率相当于现已关闭的黑兹尔伍德。此外, 25 个总标称功率为 2350 MW 的大型风能项目在维多利亚州运营。因此,依赖天气的可再生能源的规模和可变性足以产生过剩的电力供应。然而,这些异常的程度在 2020 年明显增加,并且不能用维多利亚州新的可再生能源安装率来解释,与 2019 年相比有所下降。

预测电力需求

在历史背景下,预计 2020 年期间电力需求的潜在异常会降低符合旧数据的预测模型的准确性。为了检验这一假设,使用 2015 年 1 月至 2019 年 1 月的数据拟合了一个预测模型。通过与 2019 年的实际需求进行比较,其预测得到了验证,但没有明确拟合这一数据。预测模型基于一个序列到序列机器学习模型,为翻译(Google translate)等自然语言处理任务开发。应用于时间序列预测,这个序列对序列模型在由 Kaggle 主办的网络流量预测挑战赛上展示了的优异表现。预测模型源代码可以在 my Github repository 中找到。

作者图片

该模型用于预测 2020 年 1 月至 2020 年 10 月的测试期。下图显示了 2019 年和 2020 年预测的百分比误差。

就预测模型百分比误差而言,2020 年与 2019 年相似。这可以通过用平均绝对百分比误差 (MAPE)将信息浓缩成一个数字来进一步说明。此指标去掉符号,并对一段时间内的百分比误差进行平均。

上表显示,7 天电力需求预测在 2020 年的 MAPE 与 2019 年基本相同,但进行了优化。因此,根据 AEMO 每日电力需求数据,2020 年和 2019 年一样可预测。

结论

目前的分析表明,与 2019 年相比,维多利亚州 2020 年至 10 月的每日总电力需求模式没有出现重大中断。远程工作安排将用电点从办公室转移到了家中。主要电力消费者,如美国铝业公司的铝冶炼厂在 2020 年基本上继续运营。如果电力需求是经济活动的一个良好指标,那么一旦 Covid 限制取消,持续的电力需求模式是维多利亚州经济复苏步伐的一个令人鼓舞的迹象。

然而,在 2020 年期间,大部分(10%及以上)日常电力需求以负价格交易的天数显著增加。2019 年,随着工业和屋顶太阳能的大幅扩张,出现了类似的模式,尽管规模较小。相比之下,在 2020 年期间,新的可再生能源的速度明显放缓。这可能表明这些价格异常幅度的上升与疫情相关的维多利亚州电力需求中断之间的联系。

确认

我非常感谢 Melbourne Datathon 2020 的组织者设立了关于电力消耗模式的挑战,这是这篇文章的动机。特别感谢 Phil Brierly 澄清了无数关于挑战的问题,并组织了出色的墨尔本数据科学会议!

数据源

[1] AEMO 汇总价格和需求数据
【2】维多利亚州公共假期
【3】学校开学日期,维多利亚州教育
【4】维多利亚州 PM Daniel Andrews tweeter
【5】澳大利亚气象局

使用 GeoPandas 和传单的 Python 和 R 语言的优雅地理图

原文:https://towardsdatascience.com/elegant-geographic-plots-in-python-and-r-using-geopandas-and-leaflet-27126b60bace?source=collection_archive---------22-----------------------

如何使用 GeoPandas 和传单?

照片由марьянблан| @ marjanblan在 Unsplash 上拍摄

有几个地理库可用于在地图上绘制位置信息。我以前在这里写过相同的主题,但是从那以后,我更广泛地使用了这些库,并且了解了新的库。在使用和检查了几个库之后,我发现 GeoPandas 和 Leaflet 库是两个最容易使用和高度可定制的库。该代码可作为 GitHub repo 获得:

[## kb22/地理绘图

这个库描述了使用 Python 中的 GeoPandas 和 R 中的 Leaflet 作为两种非常优雅(和简单)的绘图方式…

github.com](https://github.com/kb22/geo-plotting)

资料组

数据集取自 Kaggle 。它包括世界各国的人口密度(每平方公里的人口数)。该数据集包括从 1961 年到 2015 年的值。

资料组

上图显示,在读取数据集时,我们需要跳过前 4 行,所以我们直接从数据开始。像“1960”这样的列是空的,因此可以删除。此外,比利时等一些国家的数据缺失,因此我们将从收集中删除这些记录。

使用 GeoPandas 的静态图(Python 语言)

导入库

我们将导入库pandas来读取数据集,然后使用geopandas绘制地图。注意,为了删除不必要的警告,我添加了特定的命令。

导入数据集

接下来,我们将导入数据集。如前所述,我跳过了前 4 行。

我用drop()的方法去掉所有多余的不需要的列(“指标名称”、“指标代码”、“1960”、“2016”、“未命名:61”)。我使用dropna()删除所有具有空值的记录,最后计算 1961 年到 2015 年的平均人口密度,放入新列avgPopulationDensity

结果数据集

绘图数据

我们首先直接从 geopandas 加载世界基图,然后将我们上面细化的数据集与这个基图数据合并。然后,我们简单地用avgPopulationDensity列中的值绘制数据world。我们在Reds色图中给国家加阴影,这意味着平均人口密度较高的国家比其他国家更暗。

平均人口密度图(使用 GeoPandas)

我们可以清楚地看到,亚洲国家有更多的人口密度值,特别是印度,孟加拉国,韩国和日本。

使用传单的互动情节(R)

导入库

我们将加载用于生成绘图的leaflet库和用于读取 shapefiles 的sf库。

导入数据集

就像在 Python 中一样,我们跳过前 4 行导入数据集,删除多余的列,删除缺少值的行,并创建avgPopulationDensity列。

重要的是,我们还要加载绘图所需的 shapefile。因此,我们使用st_read方法,将带有这个 shapefile 的数据集合并到一个名为shapes的变量中。

绘图数据

在绘制数据之前,我们首先定义想要使用的调色板。我为不同的箱子定义了红色的阴影,基于此,我将对结果图进行着色。由于这是一个自定义调色板,它的颜色将不同于我们在 GeoPandas 图中看到的颜色。

接下来,我们绘制传单 geoplot。leaflet()开始创建地图,addTiles()添加国家地图。接下来,我们通过定义纬度和经度值以及缩放比例来设置地图视图,这样我们就可以一次看到整个地图。如果需要,我们可以更改这些值,但由于它是一个交互式地图,我们也可以动态地这样做。

最后,基于avgPopulationDensity列,我们对整个地块进行颜色分级,并附上国家名称作为标签。我们通过添加笔画(STROKE = TRUE)来定制每个国家的外观,然后用weight = 1将它们设置为black,定义每个边界的宽度。

平均人口密度图(使用传单)

我们观察到亚洲国家如印度、孟加拉国、中国、日本和其他国家的人口密度比其他国家高。

结论

从上面的两个例子中,我们可以看到创建漂亮的静态和动态地理图是多么容易。此外,我们还可以添加大量定制内容。

如果您有任何建议、问题或想法,请在下面告诉我。

让数据说话的优雅方式:探索性数据分析

原文:https://towardsdatascience.com/elegant-way-to-make-data-talk-stories-exploratory-data-analysis-783e68837a2?source=collection_archive---------53-----------------------

大数据无所不知

杰在 Unsplash 上拍照

介绍

数据可以讲述伟大的故事,让数据传达正确的故事是一门艺术。获得这门艺术的手段是探索性数据分析(EDA) 。探索性数据分析只不过是使用统计和概率方法来理解数据试图传达给我们的信息。

作为一名数据科学家,大部分工作将主要集中在理解数据上,并试图只获得必要的特征,以发送到机器学习模型。只有当输入数据有意义时,模型才能够发挥其最大功效。

真正困难的事情之一是弄清楚该问什么问题。一旦你想通了这个问题,那么答案就相对容易了——埃隆·马斯克

从一张白纸中找到正确的问题通常是一项具有挑战性的任务。但是,通过不断地问 为什么, 我们将能够理解数据的行为并获得洞察力

现在,我们可以深入了解一些在执行 EDA 时可以使用的常见起点。我从小就是口袋妖怪的粉丝,我将使用口袋妖怪🌟来自 Kaggle 的数据集用于逐步执行 EDA

来吧,让我们抓住他们:)

超级工具:熊猫

在描述执行 EDA 的一般步骤之前,让我们看一下一个重要的工具。

Pandas 库是建立在 python 之上的一个快速、强大且简单的工具。从我的个人经历来看,作为一名数据科学家,我每天的面包和黄油完全依赖于熊猫。只用一两行代码就可以轻松实现所有的编程逻辑,这使得这个库如此受欢迎。它可以处理成千上万的数据,而没有很多计算要求。此外,这个库提供的功能很简单,而且非常有效。

甚至对于我们的口袋妖怪数据集 EDA,我们将使用熊猫来理解数据,也用于可视化

探索性数据分析的常见步骤:

当我收到数据时,我会执行下面的一些步骤来掌握我实际处理的内容。

  1. 了解您的数据
  2. 了解数据中的特征/列
  3. 数据的因果分析

了解你的数据:

了解我们将要处理的数据点的数量是很重要的。这是因为,一旦数据的大小增加,代码必须以这样一种格式编写,即它是高效的,并且在更短的时间内执行。

#Import library
import pandas as pd
import numpy as np#Read data
data = pd.read_csv('../pokemon.csv')

shape() 函数在熊猫格式中给出行数和列数(rows,cols)

data.shape()
#Output: (801, 41)

了解数据中的特征/列

pandas 中的 info() 函数提供了完整的列分割,包括数据类型在内的每一列中总共有个非空的项。该函数用于确定是否有任何列必须被 估算 以处理缺失数据

data.info()

口袋妖怪数据集中有一些有趣的字段,比如世代、能力、类型*。*使用熊猫的可视化功能,并通过使用 seaborn 的美学外观,我们可以生成有助于提供基线故事的良好图表。

pandas 中的 value_counts() 函数对字段中的唯一值进行分组,并提供组中每个唯一值的频率份额(如果 normalize 参数设置为 *True,*提供出现份额的百分比)。使用直方图图可以很好地理解频率分布。

import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib import cmcolor = cm.Pastel1(np.linspace(.4, .8, 30))fig, ax = plt.subplots(2,2, figsize=(18,18))data.generation.value_counts(normalize=False).sort_index().plot(kind='bar', color=color, ax=ax[0,0])
ax[0,0].set_xlabel('Generation')
ax[0,0].set_ylabel('Frequency of occurrence')data.type1.value_counts(normalize=False).plot(kind='bar', color=color, ax=ax[0,1])
ax[0,1].set_xlabel('Type1')
ax[0,1].set_ylabel('Frequency of occurrence')data.type2.value_counts(normalize=False).plot(kind='bar', color=color, ax=ax[1,0])
ax[1,0].set_xlabel('Type2')
ax[1,0].set_ylabel('Frequency of occurrence')data.is_legendary.value_counts(normalize=False).plot(kind='bar', color=color, ax=ax[1,1])
ax[1,1].set_xlabel('Legendary - Yes/No')
ax[1,1].set_ylabel('Frequency of occurrence')

1:频率分布(图片由作者提供)

上图提供了数据集中一些特征(列)的频率分布。从图 1 中的*可以推断,非传奇类型的 1、3、5 代口袋妖怪占了大多数。还有,大部分属于 1 型的*水*和 2 型的*飞*。*

图 2:类型 1 和类型 2 的特定值的频率分布(图片由作者提供)

图 2 图是分别有*类型 1 =水*和*类型 2 =飞*的过滤行得到的。结果表明,水(1 型)的主要 2 型成分是地面和空中的。同样,大多数飞行(2 型)属于正常和错误类型。

图 3:属于一种或两种类型的口袋妖怪的分割(图片由作者提供)

在类型领域更深入一点,图 3 描述了不是所有的口袋妖怪都属于这两种类型,而且,如果一个口袋妖怪属于两种类型,实力也没有太大差异。

因此,从最初的分析中,我们可以了解到数据中有相当有影响力的分类变量,如类型、世代、传奇等,可能会影响建模结果。还有一些 连续变量 如攻击点、防御点、捕获率、base_egg_steps、sp_attack 和 sp _ defence 点,它们与分类变量的相关性对所研究的口袋妖怪的捕获和强度有一些影响。

因果分析

在开始因果分析之前,让我们弄清楚一些可能有助于构建口袋妖怪数据集大纲的问题

  • 捕捉一个给定的口袋妖怪有多难?
  • 它值得被捕获吗?它将如何在战斗中对我们有用?
  • 给定口袋妖怪的优点和缺点是什么?

现在,让我们深入了解各列之间的关系,揭开一些隐藏的故事,并得到一般的假设。

捕捉一只给定的口袋妖怪有多难?

可以使用数据集中的 capture_rate 和 hp(hit-point) 列来定义此指标。捕获率无非是在给定时间内,如果发现口袋妖怪,多久能捕获一只。所以如果捕获率少,那就意味着口袋妖怪很难被捕获。生命值是口袋妖怪可以承受的伤害量。所以如果生命值高,那么口袋妖怪就是强大的。所以大多数捕捉的口袋妖怪都有高 hp 。下图给出了十大难以捕捉的口袋妖怪

**#clearn outlier data
cap = data[~(data.capture_rate == '30 (Meteorite)255 (Core)')]
cap['capture_rate'] = cap['capture_rate'].astype(int)cap[['name','capture_rate','hp']].sort_values(by=['capture_rate','hp'], ascending=[True,False]).head(10)**

图 4:难以捕捉的口袋妖怪(图片由作者提供)

它值得被捕获吗?它在战斗中对我们有什么用处?

一旦一只口袋妖怪被捕获,我们需要明白我们能从中获得什么。所以知道它需要增长多少点就好了,这样它才能变得更强大。这可以从一个叫做 experience_growth 的专栏中推断出来。

图 5:口袋妖怪所需的经验增长点(图片由作者提供)

****近 65%的口袋妖怪需要 1-106 万经验值才能成长。因此,如果一个高 hp 的口袋妖怪被捕获,那么它真的是一个头奖,否则需要更多的点数来增加它的价值。****

像身高,体重,hp(生命值),攻击,防御,特殊攻击和特殊防御等领域定义了口袋妖怪的实力,了解它们之间的相互联系是很好的。

**power=data[['height_m','weight_kg','hp','attack','defense','speed','sp_attack','sp_defense']]sns.heatmap(power.corr(), annot=True, cmap='Pastel1', cbar=False)**

图 6:相关热图(图片由作者提供)

口袋妖怪的身高和体重似乎有适度的相关性,其次是防御和特殊防御栏。然而,在功率、尺寸列之间没有发现显著的相关性。

一些类型的口袋妖怪有更好的生命值。这种关系可能有助于确定被捕获或将要被捕获的口袋妖怪的价值

图 type1 和 HP 的小提琴图(图片由作者提供)

小提琴图中的点是总体的中间值(第 50 个百分位数),长尾表明该组中有一小部分人具有较高的值(例如正常值)。可以推断出飞行、精灵和龙类型的口袋妖怪有更高的生命值,因此捕捉任何这种类型的口袋妖怪可能在战斗中有用:)**

给定口袋妖怪的优点和缺点是什么?

在人口中,有将近 9%的口袋妖怪是传说中的。人们常说传说中的口袋妖怪有更好的攻击和防御策略,我们可以用方块图来证实数据是否说了同样的事情**

**fig, ax = plt.subplots(1,2, figsize=(10,5))
sns.boxplot(x=data.is_legendary, y=data.attack, ax = ax[0])
sns.boxplot(x=data.is_legendary, y=data.defense, ax = ax[1])**

图 8:传奇 Vs 攻击/防御的方框图(图片由作者提供)

因此,数据显示传奇口袋妖怪的攻击和防御值比普通口袋妖怪高,证明了我们的假设。

***接下来,看看每种类型的口袋妖怪都有怎样的攻防策略会很有趣。为了得到这个结果,我根据口袋妖怪的类型 1* 对它们进行了分组,并计算了每种类型的攻击和防御的平均值,从而得出一个推论。****

**fig, ax = plt.subplots(1,2, figsize=(10,5))data.groupby('type1')['attack'].mean().plot(kind='bar',color=color, ax = ax[0])
ax[0].set_xlabel('Type1')
ax[0].set_ylabel('Total Attack points')data.groupby('type1')['defense'].mean().plot(kind='bar',color=color, ax = ax[1])
ax[1].set_xlabel('Type1')
ax[1].set_ylabel('Total Defense points')**

图 9: Type1 Vs Mean 攻击/防御(图片由作者提供)

龙,战斗和地面型口袋妖怪有最高的攻击行动计划,同时钢铁,岩石和龙有最高的防御行动计划。综合来看,龙,钢,地是最强的口袋妖怪类型

数据集中有一些有趣的字段,如对抗 _ 电、对抗 _ 火和其他一些对抗 _ 字段,它们定义了口袋妖怪在战场上可以承受的伤害量,范围从 0 到 4。对于给定类型的口袋妖怪,我们可以找到每个战斗性质的耐力分数。**

图 10:战力热图(图片由作者提供)

可以看出,飞行口袋妖怪对冰型口袋妖怪的伤害最高,其次是黑暗型口袋妖怪对仙女的伤害。因此,这张热图给出了在战场上使用的口袋妖怪的类型。

结论

忠太💫我们已经使用口袋妖怪原始数据集来获得一些基本问题的答案。同样,我们可以对这个基线故事进行更多的开发,具体地为每种类型的战斗找到最好的口袋妖怪名称,甚至更多。

希望这篇文章能让你了解如何从头开始。快乐学习:)

提升仪表板在 Dash 中的交互性

原文:https://towardsdatascience.com/elevate-your-dashboard-interactivity-in-dash-b655a0f45067?source=collection_archive---------20-----------------------

海崖桥|君摄

在 dash 代码中实现“回调”的初学者协会

上周,我和大家分享了如何在 python 中使用 Dash 制作一个仪表盘来跟踪冠状病毒的传播,从中可以实时了解全球冠状病毒病例的数量,包括确诊、痊愈和死亡病例,以及它们在世界地图上的分布。

[## 使用 Dash 构建一个仪表板来跟踪冠状病毒的传播

全球冠状病毒(2019-nCoV)患者确诊、康复和死亡的实时视图

towardsdatascience.com](/build-a-dashboard-to-track-the-spread-of-coronavirus-using-dash-90364f016764)

对于第一个版本,我们实现了基本的 dash 功能,并获得了一个静态应用程序接口。换句话说,除了plotly ( 提供的本地交互,例如悬停文本显示和图形上的地图探索,一旦应用程序在用户的浏览器上启动,屏幕上显示的所有内容都将被设置。用户可能会在几秒钟内使用完仪表板,然后弹开。

一般来说,作为一个 web 应用程序,其整体健康状况的一个主要指标是参与度,它表示在一段定义的时间内,在您的应用程序中保持活跃的用户的百分比。这对于依赖稳定的用户流来产生收入的商业 web 应用程序来说尤其重要(当然这不是我的 dashboard 应用程序的目的,但是,为了引出本文的主题,让我们假设我们现在正在构建一个“商业应用程序”)。提高 web 应用程序参与度的一个简单而有效的方法是提高它与用户的交互性。

大家可以看到,相比于第一个版本( 标题图 在我上一篇中),在最新版本的 2019-nCoV 跟踪仪表盘中的地图旁边放置了一个数据表(图 1)。随着该数据表添加了两种类型的交互性,

  1. 用户可以根据四列中的任意一列(即国家/地区、确诊、康复和死亡)对行进行排序;
  2. 一旦用户选择表格中的一行,地图将自动更新为国家/地区的放大视图(例如,当选择“Mainland China”时,地图将放大到中国并显示每个省的病例数)。

1 |仪表板中的两个函数和数据表

这两个功能可能有助于将用户保留在仪表板中更长时间,因为地图上显示的结果可以基于他们自己的兴趣和选择。

在本帖中,我将与你分享如何在 dash 中使用回调来实现前述的交互性。像往常一样,您可以从 my Github 访问所有需要的数据和 jupyter 笔记本。

dash 中的回调是什么

在 dash 中,callback可以理解为 python 函数和应用程序之间链接的双向隧道。

具体来说,InputOutput两种货物在一个callback内从两个方向交付,Input是从appfunction交付的货物,通过用户在app ( 中的动作生成,例如输入一个值,选择一行,从下拉菜单中选择一个项目,将光标悬停在一个分散点上等。)。相反,Output是从functionapp的货物,由function根据Input返回。

InputOutput都有两个自变量component_idcomponent_propertycomponent_id确保callback识别正确的发送者和接收者,而component_property是货物的实体。也就是说,基于这些component_id , callback知道哪个组件的component_property作为Input应该被监控,从function返回的component_property作为Output应该被分配给哪个组件。

在下面取自 Dash 教程的例子中,我们可以看到html.Div()容器中的两个组件( *dcc.Input()* *html.Div()*)各有一个id。这两个 id 分别分配给callback中的OutputInput。因此,用户输入的值( *dcc.Input* *value* 属性,其中 *id* 为‘my-id’)将被传递给update_output_div(input_value),返回的结果将被赋给html.Div()children属性,其中id为‘my-div’。

样本破折号

最重要的是,callback实时监控input的货物流量。如上例所示,一旦输入框内发生变化,就会触发update_output_div(input_value),并且children内容会立即更新(图 2)。这一特性使用户能够在采取行动后立即看到来自应用程序的反馈。

图 2 |示例应用程序

您可能会注意到component_property只是给定组件的属性,这意味着我们可以通过回调函数返回组件的任何属性。

一旦我们理解了 dash 中回调的概念,让我们深入到我的仪表板的代码中。

此仪表板中的回拨

图 3 |地图容器的代码

这里我先在地图驻留的容器里面多加了一个html.Div() ( 图 3line523-line563 )子容器。在这个子容器中,有两个组件,html.H5()用于标题,dash_tale.DataTable()(Dash DataTable是一个交互式表格组件,设计用于查看、编辑和探索数据表的大型数据集

还记得第一种交互性,排序功能吗?这个很简单,可以直接用sort_action ( line536, )设置,可以让数据按列排序,接受 DataTable 组件中 *none* *native* *custom*的任意一个值。这里我们只使用了native,它根据数据的类型对数据进行排序(例如升序表示数字,字母表表示字符串)。

为了能够选择数据表中的行,我们还需要设置row_selectable='single' ( line534 ),选择界面将显示在每一行数据的前面。

对于地图组件( *dcc.graph()*),你可以发现它的id是‘数据表-交互-地图’(line 519),而带有‘数据表-交互-位置’id的数据表组件( line529 )。这是回调中使用的两个 id。我喜欢使用有意义的 id 名称,这有助于将来维护代码。

好了,app 端的一切都准备好了,现在让我们进入回调部分。在我们的例子中,作为Input cargo,我们有derived_virtual_selected_rows ( 这不是一个任意的名字,它是一个从数据表中选择 *dash_table.DataTable* 组件的行的索引列表),cargo 然后将传递给函数为dcc.graph()返回一个figure属性。

因此,如图 4 所示,我们给OutputInput分配了相应的‘id ’,同时,标记了正确的属性以便回调到 monitor。注意Input必须在列表中。

图 4 |回调装饰器

最后,让我们完成功能方面。我们想要的交互性是让用户从数据表中选择一行,地图将自动移动到和放大所选的国家/地区。此外,在应用程序开始时,初始中心点和缩放级别应该显示整个世界地图。

第一次启动应用程序时,将调用回调及其函数。然而,当第一次呈现应用程序时,没有选择任何行,因此derived_virtual_selected_rows将是None。这可能会导致依赖于derived_virtual_selected_rows的函数出现问题。这就是为什么你可以从第 590 行到第 591 行(图 5)看到,在函数的开始,我们将derived_virtual_selected_rows设置为一个空列表。一旦用户做出选择,数据表中被选择行的索引将被存储在derived_virtual_selected_rows中。由于我们只启用了单一选择,它将只包含一个项目。为了访问这个索引,我们只需要调用derived_virtual_selected_rows[0]

图 5 |回调包装的函数

通过使用go.layout.mapbox.Center()(图 5,line 639–641,我们可以指定地图应该居中的坐标及其放大级别。因此,当应用程序第一次启动并且derived_virtual_selected_rows是一个空列表时,我们将使用预定义的坐标和放大级别。一旦derived_virtual_selected_rows内有选择,callback 会用相应的坐标和放大级别更新地图。

lat=3.684188 if len(derived_virtual_selected_rows)==0 else **dff['lat'][derived_virtual_selected_rows[0]]**
lon=148.374024 if len(derived_virtual_selected_rows)==0 else **dff['lon'][derived_virtual_selected_rows[0]]**zoom=1.2 if len(derived_virtual_selected_rows)==0 else **4**

万岁,我们现在使用回调为仪表板添加两种类型的交互性。我希望你觉得这篇文章很有用,并且现在对 dash 中的回调有了一个想法。

以下是我用来学习破折号回调的列表:

  • 基本仪表板回调
  • 破折号问题
  • 仪表板交互性

和往常一样,我欢迎反馈、建设性的批评以及听到关于您的数据科学项目的信息。你可以在 Linkedin 上找到我,也可以在我的网站上找到我。

提升您的 Jupyter 笔记本电脑环境体验

原文:https://towardsdatascience.com/elevate-your-jupyter-notebook-environment-experience-9bdd1101aa54?source=collection_archive---------14-----------------------

随后,让你喜欢在 Jupyter 环境中工作

香草形式的 Jupyter 笔记本

Jupyter 笔记本是我这个数据科学家不可分割的一部分。Jupyter 笔记本能够在不同的单元格中测试我的代码,立即显示我的数字,甚至以 markdown 的形式编写必要的解释;这是任何其他 IDE 都没有的体验(或者据我所知)。

虽然我说了这些,但我意识到 Jupyter Notebook 更多的是一种探索和测试工具,而不是生产工具。我也知道使用它们的默认形式会很痛苦,特别是对于来自其他 IDE 的人来说。然而,我想展示一些我喜欢的 Jupyter 笔记本的功能,以提升我们使用 Jupyter 笔记本的体验。只需注意一点,这里的大部分扩展只有在假设您的 jupyter 笔记本使用的语言是 Python 的情况下才能正常工作。

这里我创建了文章的第 2 部分,作为提升您的 Jupyter 笔记本体验的附加文章。

降价和乳胶

对于那些不知道 Markdown 是什么的人来说,它是一种在纯文本文档中添加格式化元素的语言。Markdown 让你可以灵活地将你的纯文本转换成更有趣的文本(例如嵌入链接、图像甚至视频)

降价是如何运作的

要使用降价,我们需要将单元格切换到降价模式。我们只需要从下拉列表中选择降价选项。如果你想学习 markdown 格式中使用的所有命令,你可以在这里学习。

我喜欢 Jupyter Notebook 中的 Markdown 的地方不是格式部分,而是它如何在他们的单元中实现 LaTeX。LaTeX 也是一种纯文本格式语言。具体来说,它通常用于复杂的数学表达式。

通过 Markdown 单元中的 LatEx 得出的标准偏差方程

就像 Markdown 一样,LaTeX 也有自己的规则。如果你想了解更多,这里有 LaTeX 文档的开源指南。

编程语言扩展

当我们通过 Anaconda 安装 jupyter 笔记本时,我们只会使用 Python 作为我们的工作语言。这就产生了一个假设,jupyter 笔记本只能与 Python 语言一起工作,如果我们想与另一种语言如 R 或 Julia 一起工作,我们应该使用另一个 IDE。这完全不是事实;我们可以在 jupyter 环境中实现其他语言。

Jupyter 笔记本内核选择

例如,我们可以为 jupyter 笔记本环境嵌入一个额外的扩展,以便与 R 或 Julia 编程语言一起工作。

1.r 笔记本

要在我们的 jupyter 笔记本中包含 R 笔记本,我们需要遵循以下步骤:

  1. 装 R;在 jupyter 笔记本环境中设置 R 之前,我们需要有自己的 R 编程语言。你可以在这里下载。
  2. 安装伊尔克内尔;IRkernel 是一个 jupyter 内核,用于处理 jupyter 笔记本中的 R 语言。您可以通过 R 控制台输入install.packages('IRkernel')来安装 IRkernel。
  3. 启用 IRKernel;为了让 jupyter 看到新安装的 IRkernel,我们需要通过 R 控制台输入IRkernel::installspec(user = FALSE)来启用它。

现在,我们可以在 jupyter 笔记本中使用 R 编程语言,方法是在创建新笔记本时选择 R。

在 Jupyter 的 r

2.朱莉娅笔记本

朱莉娅怎么样?是的,我们还可以在 jupyter 笔记本中设置 Julia 语言。我们只需要遵循与上面类似的步骤。

  1. 安装茱莉亚;就像 R 一样,我们需要下载 Julia 语言作为第一步。你可以在这里下载朱莉娅的作品。
  2. 安装 I Julia;IJulia 相当于 r 中的 IRkernel。我们通过在 Julia 命令行中键入以下行来安装 IJulia:
using Pkg
Pkg.add("IJulia")

就这样,我们现在可以在 jupyter 笔记本上使用 Julia 语言了。

朱庇特的朱莉娅

Jupyter 笔记本扩展

Jupyter 笔记本包含一个附件或扩展,以提高我们的生产力。 Will Koehrsen 已经就如何启用这个扩展创建了一个很棒的帖子,但是在这里我将总结安装部分并展示一些我最喜欢的扩展。

要为 Python 环境启用我们的 Jupyter 笔记本扩展,我们只需在终端中运行以下命令:

pip install jupyter_contrib_nbextensions && jupyter contrib nbextension install

Jupyter 扩展选项卡

打开标签会给我们提供一个很好的扩展选项,如下所示。

有许多扩展选项,其有用性取决于我们正在做什么样的工作,但我会展示一些我经常使用的。

1.执行时间

我发现执行时间扩展很有用,因为我经常测试各种代码组合,以找到运行速度最快的代码。每次我们运行当前单元格时,扩展都会出现,并且会一直保持在那里,直到我们再次运行单元格或重置笔记本。下面我用一个例子来展示一下。

执行时间延长

当我们运行完代码后,这个扩展将为我们提供代码执行的运行时间和结束时间。

2.变量检查器

人们不喜欢使用 Jupyter Notebook 的原因之一是他们缺少另一个 IDE 提供的变量检查器。对于这种情况,我们有另一个名为变量检查器的扩展。

变量检查器如何工作

顾名思义,这些扩展将创建一个额外的实例来显示 jupyter 笔记本环境中的所有变量。

3.代码美化

只需按一下按钮,这个扩展就会重新构建我们的代码。我经常在漫长的编码过程后使用这个扩展来创建一行可读性更好、更整洁的代码。

这个扩展并不总是像我们希望的那样工作。例如,如果我们已经有了一个简洁的线条,那么它根本不会改变我们的线条。

4.便条簿

这个扩展将创建一个独立的环境,就像我们书中的便签簿。如果我们需要一个地方进行代码实验,但又不想中断我们当前的 jupyter 环境,Scratchpad 是一个非常有用的扩展。

草稿栏示例,红色圆圈表示弹出草稿栏的位置

支持包

已经开发了许多模块来创建一种更加无缝和交互式的方式来在 Jupyter 环境中处理我们的数据。随着时间的推移,我确信这个模块列表会被开发得更多,但是这里我将展示一些我日常使用的包。

1.进度条

大多数时候,我们花了很多时间做循环过程,但我们甚至不知道什么时候能完成。此外,我们想知道我们的循环是否运行正常。

在这种情况下,我们可以使用 tqdm 模块提供的进度条。下面是我们 jupyter 笔记本中进度条的一个例子。

循环会话期间的进度条

我们在各自的环境中使用 pip 或 conda 来安装 tqdm 包。

pip install tqdm

下面是如何在我们的 jupyter 笔记本中添加进度条的代码示例。

#Import the module
from tqdm import tqdm#Creating the list for looping purposes
my_list = list(range(10000000))#Calling the progress bar in the jupyter noteboook
with tqdm(total=len(my_list)) as pbar:for x in my_list:pbar.update(1) #use this code to move our progress bar

我们通过调用带有 total 参数的 tqdm 来调用进度条,该参数接受迭代发生的次数。要移动进度条,在每次迭代中,我们需要使用 pbar.update()方法更新进度条,该方法接受增量(通常是 1)。

2.小工具

当我们努力探索我们的数据时,有时仅仅为了显示特定的情节而不断编辑我们的代码会是一件麻烦的事情。这肯定会阻碍我们的生产力,甚至浪费我们一些宝贵的时间。

在这里,我将展示一个交互式控件的示例,其目的是通过使用 ipywidgets 模块来更改我们的输入,而无需额外的代码编辑。

ipywidgets 如何在不编辑代码的情况下产生各种各样的情节

首先,我们通过使用通常的 pip 或 conda 来安装我们的模块。

pip install ipywidgets

然后,我们通过在命令提示符下键入以下代码来启用 ipywidget 模块:

jupyter nbextension enable --py widgetsnbextension

有了扩展,我们现在可以在 jupyter 笔记本中激活交互控制。这是我上面的 GIF 中的代码示例。

#Import all the important module
import matplotlib.pyplot as plt
import seaborn as sns
from ipywidgets import interact#load the example dataset
titanic = sns.load_dataset('titanic')

泰坦尼克号数据集

假设我有兴趣查看按数据集中每个分类组分组的票价的平均值。我们可以一个一个地过滤数据,但是这将花费很多时间,并且降低我们的生产率。因此,我们可以使用交互控件。

#Creating the interactive control@interact
def create_fare_plot(col = titanic.drop(['fare', 'age'], axis =1).columns):sns.barplot(data = titanic, x = col, y ='fare')plt.title(f'Mean Bar Plot of the Fare grouped by the {col}')

我们用“@interact”代码行启动交互,然后用 def 语句创建我们想要的交互控件。在这里,interact 小部件将为我们提供下拉列表,其中包含我们在 def 参数中输入的选项。

包含所有分类变量的下拉列表,用于在绘图之间切换

结论

以上是一些提升我们在 jupyter 笔记本上的体验的例子。我知道 jupyter 笔记本不会为了生产目的而改变 IDE,比如 Visual Studio 代码,但是我试图展示如何为了数据科学家的工作目的而改进 jupyter 环境。

如果您喜欢我的内容,并希望获得更多关于数据或数据科学家日常生活的深入知识,请考虑在此订阅我的简讯。

如果您没有订阅为中等会员,请考虑通过我的介绍订阅。

用 Splinter 提升你的网络抓取

原文:https://towardsdatascience.com/elevate-your-webscraping-with-splinter-a926eee7f7d9?source=collection_archive---------10-----------------------

按目标

通过自动化与网页的交互,从您的抓取中获得更好的数据

图像-像素

在以前的博客中,我使用两个包的组合探索了网络抓取的基础;请求,它获取一个网站的 HTML 和 BeautifulSoup4 ,它解释那个 HTML。

[## 今日汤

美汤网刮——初学者指南

towardsdatascience.com](/soup-of-the-day-97d71e6c07ec)

这些包很好地介绍了 webscraping,但是 Requests 有局限性,尤其是当您想要抓取的站点需要大量用户交互时。

提醒一下——Requests 是一个 Python 包,它将 URL 作为参数,并在第一次跟踪该 URL 时返回立即可用的 HTML。因此,如果你的目标网站只是在特定的交互之后才加载内容(比如滚动到页面底部或者点击一个按钮),那么请求就不是一个合适的解决方案。

对于我在我的目标系列中记录的 FPL 项目,我需要从英超联赛网站的结果页面中收集比赛数据。这些对请求提出了一些挑战。例如,我想要每个比赛页面上的“阵容”和“统计”标签中的数据,但是,这些数据不会加载新网页。相反,它们触发 JavaScript 事件,在同一个页面中加载新的 HTML。

我还想抓取比赛评论,可以通过向下滚动页面进入…

…但只有当用户继续向下滚动时才会完全加载(类似于脸书和 Reddit 等“无限滚动”网站)。

用碎片刮擦

我们可以使用一个名为 Splinter 的 Python 包来代替请求抓取。Splinter 是其他浏览器自动化工具之上的一个抽象层,比如 Selenium,它保持了良好的用户友好性。此外,一旦我们用 Splinter 抓取了 HTML,BeautifulSoup4 可以从其中提取数据,就像我们使用请求一样。

首先,我们需要为我们想要使用的浏览器下载合适的浏览器“驱动程序”。对于 Firefox 来说,这意味着使用 Mozilla 的 geckodriver (注意——Splinter 默认使用 Firefox)。如果你用的是 Chrome,那么你需要 chromedriver 。

您还需要使用您机器的终端 pip 安装 selenium(完整的细节包含在 Splinter 文档中):

$ [sudo] pip install selenium

同样值得注意的是,驱动文件本身(即 geckodriver 或 chromedriver)需要包含在您的 repo 的根目录中(这在 Splinter 或 Firefox 文档中都不是一个明显的要求!)

Splinter 的工作原理是实例化一个“浏览器”对象(如果你愿意,它会在你的桌面上启动一个新的浏览器窗口)。然后,我们可以在 Jupyter Notebook 上运行方法,与浏览器进行交互。

from splinter import Browser***#State the location of your driver***
executable_path = {"executable_path": "/Users/Callum/Downloads/geckodriver"}***#Instantiate a browser object as follows...
#Pass 'headless=False' to make Firefox launch a visible window*** browser = Browser("firefox", **executable_path, headless=False)

这将启动一个空的浏览器窗口。

注意橙色条纹的地址栏,它告诉我们它是由我们的 Python 文件控制的

我们现在可以用一些 Python 命令来控制这个浏览器。首先,让它访问一个网页…

match_url = 'https://www.premierleague.com/match/46862'browser.visit(match_url)

查看我们桌面上的浏览器窗口,我们可以看到这已经工作了!

与元素交互

现在我们已经加载了网站,让我们来解决请求无法处理的两个问题。首先,我们想点击“阵容”和“统计”标签。

为此,我们首先需要了解这些元素在 HTML 中是如何被引用的。右键单击按钮,并选择“检查元素”。

我们可以在检查器中找到合适的 HTML。

所以按钮是一个有序列表元素

  • ,带有类“matchcentresquantlabelcontainer”。

Splinter 可以用。find_by_tag()方法。然后我们可以用点击这个按钮。点击()方法。

target = ‘li[class=”matchCentreSquadLabelContainer”]’browser.find_by_tag(target).click()

注意 Splinter 可以使用六种不同的东西来查找元素。这些在这里有完整的文档,但是包括通过元素 ID、CSS 或值进行查找的选项。

现在浏览器已经‘点击’了我们想要的标签,我们可以使用 BeautifulSoup4 来获取和存储 HTML。

from bs4 import BeautifulSoup
html = BeautifulSoup(browser.html, 'html.parser')

然后,我们可以使用我之前的博客中记录的相同技术提取我们想要的文本信息。

当然,如果我们还想单击“Stats”选项卡,我们会执行相同的过程—使用 Inspect Element 工具检查该选项卡是如何被调用的,然后在使用 BeautifulSoup 提取 HTML 之前,在. find_by_tag()方法中传递它。

解决无限滚动问题

虽然 Splinter 的 Browser 类没有内置的“滚动”方法,但它有一个更强大的功能让我们可以做到这一点——也就是说,我们可以使用。execute_script()方法运行 JavaScript。

为了让浏览器滚动到当前加载页面的底部,我们使用了 JavaScript scrollTo()方法。它将 xy 位置作为它的参数,所以为了到达页面的末尾,我们将‘document . body . scroll height’作为 y 位置(我们不需要改变 x 位置,因为我们只是在垂直方向上滚动)。

因此,我们运行:

browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")

可能的情况是,在我们需要的所有东西加载之前,我们需要继续滚动。由于不同的比赛会有不同数量的事件,我们将需要在每一页上做不同数量的滚动。因此,我们需要某种条件来告诉我们的代码停止滚动。

令人高兴的是,英超网站上的评论总是以“阵容公布,球员热身”这句话开始。

因此,如果我们抓取的 HTML 包含这个短语,那么我们知道我们已经得到了我们需要的所有评论,我们可以停止滚动。这是一个适合“while 循环”的任务。

***#Declare the JavaScript that scrolls to the end of the page...***
scrollJS = "window.scrollTo(0, document.body.scrollHeight);"***#...and a variable that signifies the loop's end-condition***
condition = "Lineups are announced and players are warming up."***#Instantiate a 'first_content' variable (an empty string for now)*** first_content = ""***#Create a while loop that runs when 'first content'
#is not equal to our break condition***
while first_content != condition: ***#Scroll to the bottom of the page***browser.execute_script(scrollJS) ***#Use BS4 to get the HTML***soup = BeautifulSoup(browser.html, 'html.parser') ***#Store the first line of commentary displayed on the page as-is***first_content = soup.findAll('div',class_="innerContent")[-1].get_text() **#Scroll down again, and run the loop again if we#haven't reached the line "Lineups are announced..."**browser.execute_script(scrollJS)***#Store the soup that, thanks to the while loop, will
#definitely contain all of the commentary***
HTML = soup

然后,我们可以重构上面的所有内容,创建一个函数来接收匹配的 URL,并返回来自比赛评论的所有 HTML,以及来自阵容和统计选项卡的数据。因此,我们可以自动抓取本赛季到目前为止的所有比赛页面。当然,我们如何组织、存储和操纵这些数据完全是另一项任务(事实上,也是另一篇即将发表的博客的主题)。

值得一提的是,就 Splinter 的功能而言,这只是冰山一角。其他有趣的使用案例包括:

  • 输入文本字段
  • 操作 cookie
  • 截图
  • 拖放元素
  • 当然,你可以用标准 JavaScript 做任何事情。

无论如何,Splinter 是一个很棒的小 Python 包,它将帮助你把你的网络抓取提升到一个新的水平!试一试,看看你有什么想法。

这是我的博客系列“目标”中的最新一篇文章,在这篇文章中,我将尝试构建一个“摇钱树”梦幻英超联赛的模型。我很乐意听到关于这个博客的任何评论,或者这篇文章涉及的任何概念。欢迎在下面留言,或者通过 LinkedIn 联系我。

ELMo:为什么这是 NLP 最大的进步之一

原文:https://towardsdatascience.com/elmo-why-its-one-of-the-biggest-advancements-in-nlp-7911161d44be?source=collection_archive---------19-----------------------

语言模型嵌入(ELMo)是一种先进的语言建模思想。是什么让它如此成功?

2018 年发布的“深度语境化单词嵌入”提出了从语言模型嵌入(ELMo)的想法,在许多热门任务上实现了最先进的性能,包括问答、情感分析和命名实体提取。ELMo 已经被证明可以提高近 5%的性能。但是是什么让这个想法如此具有革命性呢?

创作的《Elmo 近距离》在 2.0 的 CC 下授权

ELMo 是什么?ELMo 不仅是一个提线木偶,还是一个强大的计算模型,可以将单词转换成数字。这一重要过程允许机器学习模型(接受数字,而不是单词作为输入)根据文本数据进行训练。

**ELMo 为什么这么好?**当我通读原文时,有几个要点引起了我的注意:

  1. ELMo 说明了一个单词的上下文。
  2. ELMo 是在大型文本语料库上训练的。
  3. ELMo 是开源的。

让我们详细讨论这些要点,并谈谈它们为什么重要。

**#1: ELMo 可以唯一说明一个单词的上下文。**以前的语言模型,如 GloVe、Bag of Words 和 Word2Vec,只是基于单词的字面拼写生成嵌入。他们不考虑这个词的用法。例如,在以下示例中,这些语言模型将为“信任”返回相同的嵌入:

我不能信任你。

他们不再信任他们的朋友。

他有一个信托基金。

然而,ELMo 根据周围的单词为同一个单词返回不同的嵌入——它的嵌入是上下文相关的。在这些例子中,它实际上会为“信任”返回不同的答案,因为它会识别出这个词在不同的上下文中使用。这种独特的能力本质上意味着 ELMo 的嵌入有更多的可用信息,因此性能可能会提高。一个类似的考虑上下文的语言建模方法是 BERT 。

埃尔莫接受了大量数据的训练。无论你是一名资深的机器学习研究人员还是一名不经意的观察者,你可能都熟悉大数据的力量。最初的 ELMo 模型是在 55 亿词的语料库上训练的,即使是“小”版本也有 10 亿词的训练集。数据真多啊!在如此多的数据上接受训练意味着 ELMo 学到了大量的语言知识,并将在广泛的数据集上表现良好。

**#3:任何人都可以使用 ELMo!**推动机器学习作为一个领域发展的最重要因素之一是开源研究的文化。通过开源代码和数据集,研究人员可以让该领域的其他人轻松应用和建立现有的想法。按照这种文化,ELMo 是广泛开源的。它有一个网站,不仅包括它的基本信息,还包括该型号的小型、中型和原始版本的下载链接。希望使用 ELMo 的人绝对应该访问这个网站,快速获得该模型的副本。此外,代码发布在 GitHub 上,包括一个非常详尽的自述文件,让用户知道如何使用 ELMo。如果有人花了几个多小时才让一个 ELMo 模型运行起来,我会感到很惊讶。

ELMo 在著名的任务上实现了最先进的性能,例如 SQuAD、NER 和 SST。图片来源于 Peters 等人,ELMo 论文的原始作者。

ELMo 是上下文感知单词嵌入和大数据的强大组合,在 NLP 的大数据集上取得了一流的性能,包括 SQuAD、NER 和 SST。ELMo 彻底改变了我们处理计算语言学任务的方式,如问答和情感检测,这显然是该领域的一个关键进步,因为它被引用了 4500 多次。此外,向计算语言学协会(ACL)会议(最大的国际 NLP 会议)提交的论文在 ELMo 发表后翻了一番,从 2018 年的 1,544 篇论文增加到 2019 年的 2,905 篇论文(尽管这也可能归因于 2019 年初 BERT 的发表)。

我还想指出,埃尔默和伯特非常相似,因为他们都来自芝麻街!好吧,它们都是语言模型,说明了一个单词的上下文,在一个大的数据集上训练,并且正如我们所知,正在彻底改变自然语言处理领域。(我也写了一篇关于 BERT 的博文,如果你感兴趣,可以在这里找到)。

ELMo 是 NLP 中最大的进步之一,因为它本质上是第一个关注上下文的语言模型,允许在多个任务中实现更好的性能。

延伸阅读:

  • Peters 等人的原始论文
  • ELMo 的网站,其中包括它的下载链接。
  • BERT,一个使用上下文嵌入的类似语言模型。

Elo 商家类别推荐——机器学习案例研究

原文:https://towardsdatascience.com/elo-merchant-category-recommendation-a-case-study-33e84b8465c7?source=collection_archive---------28-----------------------

图片由弗雷姆基·查马基拍摄

在当今的现代,机器学习几乎涉及到我们生活的方方面面。从提供电影和产品推荐这样简单的事情到利用商业数据为组织推断和做出商业决策这样复杂的事情,机器学习和人工智能在过去几十年里已经走过了漫长的道路。今天,我将讨论一个关于 Elo Merchant 类别推荐的例子——一个我喜欢从事的机器学习(ML)案例研究。

案例研究概述:

案例研究方法分为以下步骤:

  • 商业问题
  • ML 问题公式化
  • 探索性数据分析
  • 特征工程
  • 特征关联和特征选择
  • 回归模型
  • 结论和结果

商业问题

Elo 是巴西最大的支付品牌之一。它们为用户提供餐馆推荐以及基于用户的信用卡提供商和餐馆偏好的折扣。Elo 与各种品牌建立了合作关系,为用户提供来自不同商家的促销和折扣。

现在,我们手头的问题是找出这些促销对商家以及用户(顾客)有多大的用处和益处。我们需要弄清楚顾客是否真的使用了提供给他们的这些促销或折扣。这可以通过预测一个称为客户忠诚度得分的指标来实现,该指标是目标变量。因此每张卡都有相应的预测忠诚度得分。

客户忠诚度得分将让我们了解用户/客户使用这些促销和折扣的频率。有了预测数据,公司(Elo)现在可以专注于更忠诚的客户。这意味着他们可以将他们的营销努力指向这些忠诚的客户。这也将确保 Elo 减少针对预计客户忠诚度较低的客户的不必要的营销活动。这将最终提高客户保持率。

ML 问题公式化

尽管顾名思义,这是一个回归问题,因为对于给定的卡 ID,我们需要根据卡的交易和商户数据来预测它的忠诚度得分。因此,我们将根据这些数据生成的特征来训练我们的回归模型。然后,这些回归模型将根据生成的特征预测忠诚度得分。

数据概述

所有数据都是模拟的和虚构的,并不是真实的客户数据,原因很明显。所提供的数据包含每个卡 ID 长达 3 个月的交易数据。它还包含基于这些交易中涉及的商家的商家数据。还有一个附加文件,其中包含另外 2 个月的所有购买/交易数据,这些数据不包括在 3 个月的初始交易数据中。以下是每个文件的详细描述:

  1. Data_Dictionary.xlsx →该文件包含每个 csv 文件的数据字段描述。
  2. train.csv 和 test.csv →这些文件包含卡 id(Card _ id)和关于卡的信息。它们还包含需要预测的目标变量(忠诚度得分)。下面是对每个列的描述:
*card_id* → Unique card identifier
*first_active_month* → month of first purchase in 'YYYY-MM' format
*feature_1* → Anonymized card categorical feature
*feature_2*→ Anonymized card categorical feature
*feature_3* → Anonymized card categorical feature
*target* → Loyalty numerical score calculated 2 months after historical and evaluation period
  1. historical_transactions.csv 和 new _ merchant _ transactions . CSV→这些文件包含交易数据。它们包含每张卡的交易信息。下面是对每个列的描述:
*card_id* → Card identifier
*month_lag* → month lag to reference date
*purchase_date* → Purchase date
*authorized_flag* → 'Y' if approved, 'N' if denied
*category_3* → anonymized category
*installments* → number of installments of purchase
*category_1* → anonymized category
*merchant_category_id* → Merchant category identifier(anonymized)
*subsector_id* → Merchant category group identifier(anonymized)
*merchant_id* → Merchant identifier(anonymized)
*purchase_amount* → Normalized purchase amount
*city_id* → City identifier(anonymized)
*state_id* → State identifier (anonymized)
*category_2* → anonymized category
  1. merchants.csv →该文件包含交易中涉及的商家的附加信息。下面是对每个列的描述:
*merchant_id* → Unique merchant identifier
*merchant_group_id* → Merchant group(anonymized)
*merchant_category_id* → Unique identifier for merchant category (anonymized)
*subsector_id* → Merchant category group (anonymized)
*numerical_1* → anonymized measure
numerical_2 → anonymized measure
*category_1* → anonymized category
*category_2* → anonymized category
*category_4* → anonymized category
*city_id* → City identifier(anonymized)*most_recent_sales_range* → Range of revenue (monetary units) in last active month (A > B > C > D > E) *most_recent_sales_range* → Range of revenue (monetary units) in last active month (A > B > C > D > E)
*most_recent_purchases_range* → Range of quantity of transactions in last active month (A > B > C > D > E)*avg_sales_lag3* → Monthly average of revenue in last 3 months divided by revenue in last active month
*avg_purchases_lag3* → Monthly average of transactions in last 3 months divided by transactions in last active month
*active_months_lag3* → Quantity of active months within last 3 months*avg_sales_lag6* → Monthly average of revenue in last 6 months divided by revenue in last active month
*avg_purchases_lag6* → Monthly average of transactions in last 6 months divided by transactions in last active month
*active_months_lag6* → Quantity of active months within last 6 months*avg_sales_lag12* → Monthly average of revenue in last 12 months divided by revenue in last active month
*avg_purchases_lag12* → Monthly average of transactions in last 12 months divided by transactions in last active month
*active_months_lag12* → Quantity of active months within last 12 months

所有的数据文件都可以从这个链接下载。

绩效指标

为了根据实际忠诚度得分计算预测误差,我们将使用的性能指标是 RMSE(均方根误差)。

作者图片

这里,ŷ是预测的忠诚度得分,y 是每个卡 ID 的实际忠诚度得分。

探索性数据分析

培训和测试文件

  1. 目标变量分布:

目标变量分布(作者图片)

大多数忠诚度得分在-1 和 1 之间。同样,这些都以零为中心。所以有可能这些已经标准化了。

正如我们所见,有些点离所有的点都很远。这些人的忠诚度低于-30。因为这些点构成了数据的 1%,所以它们不能被称为异常值。这完全取决于这些点是否出现在我们的测试数据中。正如我们在后面的阶段会知道的,我们在测试数据中确实有这些点。所以,我们称它们为稀有数据点。

2。分类特征

非稀有数据点的分类特征分布(图片由作者提供)

让我们来看看这些稀有数据点的分类特征..

稀有数据点的分类特征分布(图片由作者提供)

对于稀有和非稀有数据点,分类特征 1、2 和 3 之间没有太大差异。从历史交易和商家交易中提取特征可能有助于更好地预测这些罕见的忠诚度得分

3。第一个活跃月份

因为这是以“YYYY-MM”格式给出的。让我们把它转换成一个简单的度量,比如从今天算起的月差。在 pandas 中使用 datetime 实现这一点非常简单。

现在,我们可以根据忠诚度得分(目标)来绘制这个图表..

忠诚度得分与第一个活跃月的月差散点图(图片由作者提供)

  • 我们可以在这里观察到一种趋势,即最近的用户具有更高的忠诚度得分以及忠诚度得分的高方差。
  • 然而,这也表明,与长期用户相比,近期用户的数量更多。
  • 一个更重要的观察结果是忠诚度得分为<=-30(that might be outliers) are at the very bottom of the plot for each of the bin/value ranges of the active month difference from today. This shows that this feature might not be useful enough to separate our rare data points from the actual data.
  • This feature would definitely help in predicting the loyalty scores.

Historical Transactions

  1. 授权标志的用户数量

(图片由作者提供)

正如应该的那样,大多数交易都是经过授权的。

2.分期付款

分期付款分布(作者图片)

对于分期付款来说,值-1 和 999 似乎有些奇怪。如果需要的话,我们以后可能需要修剪这些。

3.购买金额

(图片由作者提供)

似乎这些也已经标准化了。

新商户交易

据观察,该文件不包含任何未经授权的交易。

分期付款和购买金额的分布与我们在历史交易中观察到的非常相似。

根据忠诚度得分绘制购买金额和分期付款

分期付款与忠诚度得分(目标)的散点图(图片由作者提供)

由于目标分数似乎是标准化的(在某个范围内),观察到具有较高分期付款次数的人具有更接近于零的忠诚度分数。

(图片由作者提供)

  • 正如我们在这里看到的,忠诚度得分随着交易价值总额的增加而增加。
  • 对于每个 card_id 进行的交易数量也观察到相同的趋势。

商户数据

该文件的列中有许多缺失值和无穷大值。无穷大值被替换为空值。然后,相应地使用均值和众数插补来处理这些缺失值。

  1. 匿名类别

(图片由作者提供)

  • 因为这三个特征都是匿名的,所以我们不能从这些情节中说太多关于商人的事情,尽管从这些情节中可以解释很多。
  • 然而,可以进一步探索和检查,如果交易中涉及的商家属于多数类别,那么它可能导致什么样的忠诚度得分。

2.活跃月滞后

(图片由作者提供)

  • 正如我们在这里所观察到的,活动月数较少的卡忠诚度较低。
  • 我们可以在这里看到很多差异。这些活跃月份列可能是有用的特性。

3.平均购买量滞后

(图片由作者提供)

  • 对于我们的稀有数据点(忠诚度得分<=-30), the purchase range lag is less than 2000.
  • This can be a very useful feature as well for predicting the loyalty scores.

EDA Summary:

  1. The target variable(Loyalty score) has 1% of its points that seem like outliers. Dealing with these points depends on the number of these points in the test data. In that case, these aren’t actually outliers. They can be termed as Rare data points. However, the loyalty score would be difficult to predict for these points and they could have a major impact on our final scores.
  2. The first active month in train file could be very useful.
  3. Aggregated transaction features for each card would be very helpful in predicting the loyalty score using the regression models. Most of our features would be from the transaction files.
  4. Some features can be used from the merchants file as well. For example, we can have a categorical variable that states if the transaction involved a merchant that was active in the last 3/6 or 12 months. The average purchases and sales ranges might be useful as well.

Data Preprocessing

Data Preprocessing included imputing the missing values with either mean and mode for categorical and continuous variables respectively.

In case of Purchase amounts, this issue was handled by trimming the purchase amount values in a specific range that covered up to 99.9 percentile of its values.

As observed earlier, the installments values such as -1 and 999 were replaced with nan(null value) and imputed accordingly.

historical_transactions['purchase_amount'] = historical_transactions['purchase_amount'].apply(**lambda** x: min(x, 0.8))
historical_transactions['installments'].replace([-1, 999], np.nan, inplace=**True**)
historical_transactions['installments'].fillna(historical_transactions['installments'].mode()[0], inplace=**True**)

Feature Engineering

The Feature Engineering for this problem was done in two iterations. In the 第一次迭代,两个事务文件都被合并到一个包含所有事务的文件中,并且使用这个合并文件生成特征。从这些特征获得的 RMSE 分数不够好。

因此,我不得不回到特征工程,分别从这两个文件中提取特征。与此同时,在第二次迭代中也产生了额外的特性。这将 RMSE 分数提高了约 0.35。

处理日期功能

purchase_date 和 first_active_month 在生成额外的特性方面非常有用,例如一年中的季度和从今天开始的月份差异。在 Pandas 中使用 datetime 可以很容易地做到这一点。

类似地,对于 purchase_date,我们生成了指示购买是在周末、假日还是工作日进行的特性。这还包括诸如月、年、日、时间和购买时间等特征。

处理分类特征

两种方法用于分类特征:

  1. 一个热编码
  2. 平均编码

在第一次迭代中使用了一个热编码。然而,在特征工程的第二次迭代之后,均值编码提供了更好的结果。分类变量的均值编码是基于相应目标变量的值是否小于-30(是稀有数据点)来完成的。这样做是为了改进对稀有数据点的预测。

使用基于变量的平均值、最大值、最小值、var、偏斜和 n_unique/count,通过“card_id”聚合来自交易的特征,以最终与训练和测试文件结合。

使用现有的特性和可用的领域专业知识生成了更多的特性。其中一些如下所示:

最终总共生成了 226 个特征。

特征关联和特征选择:

由于我们已经生成了近 200 个特征,相关矩阵看起来像这样..

相关矩阵(图片由作者提供)

呀!!这看起来不太好。

很难从中解读出什么,因为我们有大量的特征。因此,使用相关矩阵采取了一种稍微不同的方法。

阈值设置为 0.85,并且移除了共线性高于阈值的特征对中的一个特征。这种方法将特性的数量从 226 个减少到了 134 个。

回归模型

基线回归模型

初始模型使用 RandomizedSearchCV 和 GridSearchCV 进行调整,并根据训练测试拆分后获得的训练数据进行训练。

线性回归:

线性回归(作者图片)

新币回归量:

新币回归(图片由作者提供)

随机森林回归量:

随机森林回归器(图片由作者提供)

LGBM 回归量:

LGBM 回归器(图片由作者提供)

由于 RandomizedSearchCV 没有提供最好的结果,贝叶斯优化被用于超调 LGBM 模型

LGBM 模型在全套 226 个特征上比 134 个特征表现得更好。对此的可能原因可能是树和基于树的集合模型受相关特征的影响不大。

带 LGBM Goss 的贝叶斯岭回归堆叠模型

预测是使用 LGBM Goss 模型进行的,该模型根据训练数据进行分层折叠和重复折叠训练。在这里,不需要进行训练测试分割,因为我们是根据训练数据进行折叠预测的。因此,可以使用整个训练数据来训练模型。

这两个预测叠加在一起,作为贝叶斯岭回归模型(元模型)的输入。

低概率和高概率模型方法

因为,稀有数据点严重影响了异常值。我尝试了下面的模型架构来处理这个问题..

图片由叶夫根尼·帕特卡

  1. **二元分类模型:**该分类模型识别稀有数据点。这是一个 LGBM 分类器模型。基于从模型获得的分类概率,使用阈值(超参数)将卡/用户分类为稀有数据点(异常值)。
  2. **回归(完整):**这是一个简单的回归模型,在整个数据集上进行训练。这是对整个数据进行训练的堆叠贝叶斯岭回归模型。
  3. **回归(低概率模型):**在稀有数据点(异常值)的低浓度(超参数)上训练的回归模型。这也是一个 LGBM 回归模型训练的所有功能。
  4. **回归(高概率模型):**用高浓度(超参数)异常值训练的回归模型。我们只有非常少的稀有数据点,所以模型很容易过度拟合。因此,这是一个简单的回归模型(贝叶斯岭回归)。基于从用于训练的完全回归模型获得的特征重要性,使用来自完全回归模型、二元分类的预测以及 10 个最重要的回归特征。
  5. **完全(混合)模型:**混合来自高概率模型、低概率模型和完全回归模型的预测,以给出最终的忠诚度得分预测。这里的最终元模型也是贝叶斯岭回归模型。

结果

下表总结了上述所有方法的性能:

基线回归模型:

回归模型结果(图片由作者提供)

堆叠和 LGBM Goss 模型结果:

RMSE 为提到的不同方法打分(图片由作者提供)

堆叠贝叶斯岭模型提供了最好的 Kaggle 评分。因此,这是用于最终提交。

Kaggle 提交

这是我提交的最好的 Kaggle 分数..

(图片由作者提供)

总结

  1. 在这个问题上,特征工程至关重要。从交易和商家数据中生成的特征越好,RMSE 分数就越好。
  2. 处理异常值/稀有数据点是本案例研究的关键。这些分数极大地影响了最终的 RMSE 分数。
  3. 在尝试了不同的回归模型和堆叠架构后,LGBM Goss 模型堆叠在贝叶斯岭回归上作为元模型,提供了最佳结果。

未来的工作/改进

  1. 使用目标编码生成更多特征有助于提高分数。
  2. 高和低概率模型方法可以进一步优化,增加更多功能,并尝试高和低概率模型。正如这里的所解释的那样,Evgeny Patekha 在其第五名的解决方案中成功实现了这一点。
  3. 大多数分类和数字特征都是匿名的。因此,我们对这些特征没有明确的概念。这使得基于领域专业知识生成新特性变得困难。然而,这种限制/约束是为了避免泄露用户/公司数据。

结论

在这个案例研究中,我学到并改进了很多技巧。诸如特征工程和模型超调之类的技能对这个案例研究非常重要。这也是我第一次使用贝叶斯优化来超调模型。在 ML 领域,学习是一个持续的、永无止境的过程,因为每年都有新的技术和进步。因此,学习将继续…

希望你喜欢阅读这篇文章,就像我喜欢研究这个案例一样。感谢您的阅读!!

案例研究的完整代码可以在这里找到。

领英:www.linkedin.com/in/rjt5412

Github:https://github.com/Rjt5412

参考资料:

  1. https://www . ka ggle . com/sudalairajkumar/simple-exploration-notebook-elo
  2. https://www.kaggle.com/artgor/elo-eda-and-models
  3. Robin Denz 的《日期变量的进一步观察》
  4. https://www.kaggle.com/fabiendaniel/elo-world/notebook
  5. https://www.kaggle.com/fabiendaniel/hyperparameter-tuning
  6. https://www . ka ggle . com/mfjwr 1/simple-light GBM-without-blending
  7. https://www . ka ggle . com/roydata science/elo-stack-with-Goss-boosting
  8. https://www . ka ggle . com/c/elo-merchant-category-re commendation/discussion/82314

如何通过谷歌数据传输服务建立你的数据流程

原文:https://towardsdatascience.com/elt-data-warehouse-process-via-google-data-transfer-service-and-big-query-9b5aa34b526c?source=collection_archive---------45-----------------------

用一个简单但仍然有效的工具集实现您的 ELT 和 ETL 数据管道

卡伦·艾姆斯利在 Unsplash 上的照片

在构建数据仓库或湖并实施 ELT/ETL 过程时,您会遇到许多问题,例如:

  • 什么过程方法更好?ETL 还是 ELT?
  • 数据集成过程使用哪种技术?
  • 最好的数据仓库技术是什么?
  • 还有更多

在这篇短文中,我想展示一种简单而有效的方法,通过谷歌数据传输服务(DTS)和数据仓库技术大查询,来建立 ELT 数据仓库方法。

回顾:ELT 与 ETL

在下文中,对 ELT 和 ETL 的简短总结为不熟悉此事的人快速解释了这两种方法之间的差异。

来源:https://fivetran.com/_/api/blog/elt-vs-etl/elt-vs-etl.png[1]

在数据集成工具中进行转换之后,ETL 过程将数据加载到目标系统中,而 ELT 方法在转换数据之前首先将数据加载到目标系统中。通常 ELT 过程比传统的 ETL 过程更受欢迎,因为它实现起来更简单,加载数据更快。

使用谷歌的数据传输服务进行转换

通过 ELT 上传数据的过程可以通过以下方式实现:

  • 手动上传数据
  • 数据集成工具,如 talend/谷歌数据流/云功能等。
  • 使用 DTS(目前仅限于亚马逊 S3、Google Play 等少数数据源。)

加载数据后,可以使用 Big Query 中的数据传输服务通过 SQL 实现转换,如下图所示:

通过数据传输服务安排查询-按作者排列的图片

Big Query 中转换任务的一个例子是连接两个表,对列数据类型或值进行一些转换,并将它们保存为一个新的数据对象,以便以后进行分析。编写完 SQL 并点击“Schedule query”后,您可以通过弹出的配置管理器(上图的右侧)自动执行该操作。

DTS 将为您提供通过调度查询来自动化转换任务的可能性,例如在每天的某个时间(类似于批处理和夜间 OLAP 操作),但由于 GCP 内的可伸缩性,速度会快得多。

这种方法的优点

这种方法带来了某些优势:

  • 你只需要使用 GCP 本地服务(不需要大型工具集。) [2]
  • 转换可以由 SQL 完成(即使技术经验较少的员工也可以实现数据准备逻辑。)
  • DTS 和 Big Query 是完全的 SaaS 技术(不用担心基础设施和伸缩性。)
  • DTS 可以很好地处理大数据

结论

由于云平台为我们提供了无限的可扩展性,并且只需点击一下鼠标就可以实现许多服务,因此您可以快速建立数据仓库和所需的数据管道。这个例子向你展示了如何只使用两个 Google 服务和 SQL 来完成所有的设置。

资料来源和进一步阅读

[1]五川,https://fivetran.com/_/api/blog/elt-vs-etl/elt-vs-etl.png

[2]谷歌,【https://cloud.google.com/products/data-transfer

阐明药物发现中的数据科学——一位首席技术官的叙述

原文:https://towardsdatascience.com/elucidating-data-science-in-drug-discovery-a-ctos-account-2c9dce19cdde?source=collection_archive---------56-----------------------

讨论药物发现的阶段,研究领域,他对数据科学候选人的评估标准,以及更多…

由肯德尔在 Unsplash 上拍摄的照片

新冠肺炎成为头条新闻已经 4 个多月了,全世界都在急切地期待着某种治愈这种疾病的魔法,而将一种药物推向市场可能就是这种魔法。

为什么我称之为魔法?

我们很多人都知道,将一种新药推向市场通常需要至少 10-15 年的工作,包括研究、实验、试验、制造,然后来回获得 FDA 的批准。世界上最好的医学院、实验室和制药公司的研究科学家正在推动这些实验和研究。所有这些都要付出巨大的代价,我们在这里谈论的是数十亿美元。

这也为我们提供了大量需要优化的领域——成本、时间、管理工作、法律合规性、大量实验和试验数据的处理。我们在每个领域都有几家新兴公司。例如,公司就是这样一家公司,它用自己的产品 Polly 为各种医学院和制药公司的实验室提供支持。它通过分析应用和研究工作流为您提供了利用生物医学数据的各种能力。

这里是人工智能被积极使用的几个领域,并且到目前为止已经产生了有希望的结果…

人工智能在医疗保健中的应用领域

有很多关于机器学习和算法的炒作,这些机器学习和算法正在被用于资助研究项目或获得 FDA 的批准。对医疗保健领域人工智能的资助正处于黄金时期,我们有无数初创公司涌现出来解决各种问题。他们几乎涉足了医疗保健的每个领域,从减少行政工作到开发新药。

行政标牌

医疗保健包含大量的运营和管理工作,投资者正在资助许多试图简化这些任务的公司。我们有一些公司正在尝试颠覆已经发生的过程,但鉴于我们生活的技术世界,这些过程已经过时了。

成像

医学成像是取得深远成果的领域。仅人工智能驱动的诊断成像就将在 2-3 年内价值数十亿美元。我们有教育项目,在不同的特定领域培训有抱负的数据科学家和人工智能从业者。

从病人护理到精准医疗

由于电子健康记录的大量采用(EHR) ( ,仅在美国就有 95–98%),我们见证了基因组测序的快速进展。今天的医生手头有足够的数据来准确识别患者档案中的一致模式。

寻找癌症、埃博拉病毒和冠状病毒等疾病治疗方法的药物研究

BERG Health 是医疗保健领域的另一家初创公司,试图通过应用数据科学重塑癌症药物市场。通过整合强大的机器/深度学习算法,该公司已经能够分析来自数千名患者的生物样本。他们处理了每个样本中超过万亿个数据点,这也为开发如此复杂的深度学习模型奠定了基础。

与此类似,在西方,还有其他领域,如放射学、处方准确性、住院费用等,正在被转化为创业公司的商业模式。

谈到医疗保健中的数据科学,我想向您介绍这个新的视频播客系列,在这个系列中,我成功地主持了 exploration a 的 CTO。

数据显示

现在这一背景已经确定,我想向你们介绍我的第一位客人,也是我的导师 Swetabh Pathak,他是 Elucidata 的共同出资人兼首席技术官。给你一些背景,我的第一份也是唯一一份全职工作是在的,是一名数据工程师。他们是一个由来自世界上最好的医学工程学校的顶尖人才组成的小团队。一家试图将数据科学嵌入药物研发每个阶段的生物技术公司。一个高素质的领导掌舵着这个组织,使世界上最好的医学实验室与他们的尖端产品和服务。

这次采访的时间与我们所处的《疫情时报》高度一致。在这个大约 30 分钟的对话中,Swetabh 揭示了一些关于医疗保健中应用数据科学兴起的非常有趣的事实。我相信这种丰富的对话与这里的广大观众相关,几乎每个有抱负的数据科学家都有一些东西可以带走。

给你,

数据科学与 Harshit

两个月前,我创办了这个 YouTube 频道,我计划在这里覆盖整个数据科学领域。从学习数据科学到参与项目并谈论行业的新进展。以下是你应该订阅频道的原因:

  • 该系列将涵盖每个主题和子主题的所有必需/要求的高质量教程,如数据科学的 Python 基础。
  • 解释了为什么我们在 ML 和深度学习中做这些事情的数学和推导。
  • 与谷歌、微软、亚马逊等公司的数据科学家和工程师以及大数据驱动型公司的首席执行官的播客。
  • 参与项目,应用概念解决现实世界的问题。

请随时在 Twitter 或 LinkedIn 上与我联系。

EM 算法

原文:https://towardsdatascience.com/em-algorithm-aaaa181af127?source=collection_archive---------17-----------------------

数学背景和例子

具有潜在变量的模型

利用基于机器学习的随机方法,我们将信息来源视为一种概率分布。一旦我们估计了分布,对未知数据进行分类以及预测未来生成的数据就变得简单了。估计概率分布有两个阶段。
1)决定定义分布的模型,例如,概率密度函数的形式(高斯分布、多项式分布……)。这里,考虑高斯混合模型(GMM)作为例子。概率密度函数的形式可以定义为

其中 w_k 是从第 k 个高斯分布产生的比率数据。

2)在确定概率密度函数的形式后,我们从观测数据中估计其参数。例如,在高斯分布的情况下,均值和方差是要估计的参数。

我们目前已知的知识是观测数据集 D 和生成分布的形式(未知参数高斯分布)。然而,为了求解 2 ),我们需要关于每个观测数据是从哪个高斯分布生成的信息,并且该信息不直接显示在观测数据中。

在这种情况下,代表不能从观测数据集中直接获得的信息的变量被称为潜变量。在上面的例子中,w_k 是一个潜变量。

因此,在 GMM,有必要先估计潜在变量。接下来,我们使用估计的潜在变量来估计每个高斯分布的参数。

在具有潜在变量的模型中估计参数的一种有效方法是期望 和最大化算法 ( EM 算法)。

算法的推导

让我们准备一下这部分用到的符号。

  • D ={ x _i | i=1,2,3,…,N}:随机变量的观测数据集 **x 😗* 其中 x _i 为 D 维向量。
  • z :潜在变量。 z _i 对应 x _i
  • θ:待估计的一组参数

我们的目的是用 EM 算法从观测数据集 D 中估计θ

在观测数据为独立同分布的情况下,对数似然函数为

我们可以用下面的形式重写我们的目的。

对数似然函数 p(x,z |θ)中所示的概率可以用潜在变量 z 的概率表示为以下形式。第三个关系是潜在变量 z 边际分布的结果

现在,我们的目标是确定使对数似然函数 log p(x|theta)最大化的参数 theta。然而,不可能从上述关系中直接最大化该值。因此,我们决定在最大化 log p(x|theta)的同时更新参数 theta 的过程。我们认为θ是要定义的最佳参数,θ(t)是参数θ的第 t 步值。在下面的过程中,我们倾向于定义一个更新规则来增加 log p(x|theta(t))与 log p(x|theta)的比较。

这里,给定最近的参数θ和观测数据,我们用条件概率表示 q(z)。

因此,log p(x |θ)可以写成

我们首先关注更新 theta(t)时 log p(x|theta)-log p(x|theta(t))的变化。我们试图定义导致 log p(x|theta)-log p(x|theta(t))数量减少的规则。

重写这个关系,我们得到下面的形式。等式(1):

现在,我们需要评估右侧,以找到更新参数θ的规则。为此,考虑一个众所周知的数学关系
log x ≤ x-1。利用这个关系,我们可以得到下面的不等式。

因此,等式(1)的第三项是

等式(1)的第一项和第二项是非负的。之所以成立是因为,
当我们用 theta(t)代替 theta,term1-term2=0 那么通过最大化第一项,term1-term2 变得大于或等于 0。

考虑这个关系,log p(x | theta)-log p(x | theta(t))≥0。因此,为了最大化等式(1)的左侧,我们只需用最大化等式(1)右侧第一项的θ(t)值来更新θ(t)。

设上面更新规则的 argmax 的主语是函数 Q(theta)。

我们可以把这个关系翻译成当θ=θ(t)时 log p(x,z |θ)的一个期望值。

从这次更新中,我们可以将 EM 算法的过程总结为以下 E 步骤和 M 步骤。

高斯混合模型的 EM 算法

让我们以二维高斯混合模型为例。

随机变量: x _n (d 维向量)
潜变量:z_m
混合比:w_k
均值: mu _k (d 维向量)
方差-协方差矩阵:适马 _k (dxd 矩阵)

这里,如果观测数据 x 由第 m 个高斯分布生成,则 z_m = 1,否则 z_m = 0。因此,潜在变量 z 的分布可以写成

第 m 个高斯分布的概率密度函数由下式给出

因此,数据 x 属于第 m 个分布的概率为 p(z_m=1| x ,其计算公式为

初态

随机初始化适马w
t = 1。

e 步骤

计算 p(z|x,theta(t))

用θ(t)计算潜变量 z 的期望值。

因此,若 z_nm 为 x_n 的潜变量,N_m 为第 m 个分布的观测数据个数,则以下关系成立。

m 步

更新参数

我们在这一步的目标是定义 w_m,μ_m,适马 _ m,使 Q(θ|θ(t))最大化。

更新穆(意思是)

解此方程,μ的更新为

更新适马(方差-协方差矩阵)

解完这个方程,适马的更新就是

更新 w(混合比)

为了推导 w 的更新关系,我们使用拉格朗日方法使 Q(theta|theta(t))最大化,使 w_1+w_2+…+w_M=1。

求解λ的这个方程并使用约束关系,w_m 的更新规则是

所有参数更新:

用 Python 实现

人工数据生成

n1=150; n2=250; n3=300
n = n1+n2+n3
x = []
x.append(np.dot(np.random.randn(n1,2),np.sqrt(np.diag([1,4]))))
x.append(np.random.randn(n2,2)+np.dot(np.asarray([[1.]*n2]).T,np.asarray([[8.0,4.0]])))
x.append(np.dot(np.random.randn(n3,2),np.sqrt(np.asarray([[2.45,1],[1,4]])))+16.0)
X = np.concatenate((x[0],x[1],x[2]),axis=0)

初始化步骤

def genSigma():A = np.random.rand(2,2)+np.eye(2,2)#A = np.eye(2,2)*np.random.rand(1)S = np.dot(A.T,A)#S = np.diag(np.diag(S))return Sdef genMu(m):mu = np.zeros((2,m))mu[0] = np.linspace(np.min(X,axis=0)[0],np.max(X,axis=0)[0],m)mu[1] = np.linspace(np.min(X,axis=0)[1],np.max(X,axis=0)[1],m)return mu.TSigma = np.zeros((m,2,2))for i in range(m):Sigma[i] = (genSigma())Mu = genMu(m)    W = np.asarray([1.]*m)W = W/sum(W)L = -float('inf')iteration = 0

e 步和 M 步

while True:if iteration >=100:breakiteration+=1# **E step** wN = np.zeros((n,m))for j in range(m):for i in range(n):wN[i,j]=W[j]*gauss(X[i],Sigma[j],Mu[j])sum_wN = np.sum(wN,axis=1)Lnew = np.sum(np.log(sum_wN))if (Lnew-L) < 0.00001:print("Model Converged")breakL = Lnewprint("iter#",iteration," Lnew:",Lnew)iters.append(iteration)Log.append(Lnew)# **M step**eta = np.zeros((n,m))for i in range(n):eta[i,:]=wN[i]/sum_wN[i]sum_eta = np.sum(eta,axis=0)W = sum_eta/nfor j in range(m):tmp = np.zeros((2,))for i in range(n):tmp += eta[i,j]*X[i]Mu[j]=tmp/sum_eta[j]for j in range(m):tmp = np.zeros((2,2))for i in range(n):xmu = (X[i]-Mu[j]).reshape(2,1)tmp1 = np.dot(xmu,xmu.T)*eta[i][j]tmp += tmp1Sigma[j]=tmp/sum_eta[j]

其他功能

import numpy as np
import random
from scipy.interpolate import griddata
from scipy.stats import multivariate_normal
import numpy.ma as ma
from numpy.random import uniform, seed
from matplotlib import cm
from scipy.special import softmax
import matplotlib.pyplot as plt# Gaussian pdf 
def gauss(x,sigma,mu):n = multivariate_normal(mu,sigma)return n.pdf(x)# Visualize
def plot_countour(sigma,mu):xy_range = np.zeros((2,2))xy_range[0] = np.linspace(mu[0]-2*sigma[0,0],mu[0]+2*sigma[0,0],2)xy_range[1] = np.linspace(mu[1]-2*sigma[1,1],mu[1]+2*sigma[1,1],2)x, y = np.mgrid[xy_range[0][0]:xy_range[0][1]:.01, xy_range[1][0]:xy_range[1][1]:.01]pos = np.dstack((x, y))rv = multivariate_normal(mu, sigma)z = rv.pdf(pos)levels = np.linspace(np.min(z),np.max(z),5)plt.contour(x, y, z,linewidths=1.0,colors='black',levels=levels)#plt.contourf(x,y,z,15,cmap=plt.cm.jet)plt.xlim([-5,25])

结果(1) M=2

结果(2) M=3

讨论

从结果来看,使用 EM 算法,对数似然函数在重复更新参数规则后总是收敛的。然而,由于 EM 算法是一种迭代计算,它容易陷入局部最优状态。正如在结果(1)、(2)中看到的,M 值(混合模型的数量)和初始化的差异提供了对数似然收敛和估计分布的不同变化。为了解决这个问题,一个简单的方法是用几个初始化状态重复该算法,并从那些作品中选择最佳状态。

电子邮件分析:比你需要知道的更多

原文:https://towardsdatascience.com/email-analytics-more-than-you-ever-need-to-know-b6e75b7b2541?source=collection_archive---------37-----------------------

黑匣子又火了

希腊的邮箱(摄影:Randy Au)

向 Vicki 致敬,感谢她激发了我写这篇文章的动机,我总是乐于接受关于写作主题的想法和建议hinthint**

如果你在 2010 年找到我,告诉我电子邮件跟踪分析将在 2020 年再次流行,我会认为你疯了。但是我现在在这里,用电子邮件通讯给你写信,谈论电子邮件技术和分析。

感谢原始的电子邮件,这是一个令人惊讶的短话题。我可以把我所知道的几乎所有东西,小到微小的技术细节,都放到这篇长文里。

那么 Substack 上的邮件跟踪是什么样子的呢?

我们得到了一些有趣的数据,比如你最近发的帖子,打开率和点击率。视图和注册(转换)似乎是网站页面,而不是电子邮件本身。

然后,您还可以在电子邮件地址级别获得更详细的电子邮件统计信息。打开、点击和设备计数。

我们现在要看看最后一个是如何收集的。呜哇!

现代网络分析实际上是持续的连接

现代网络分析涉及大量工具,从服务器端日志、用户代理分析、浏览器上的 cookies,到使用 Javascript 和 websockets 实时收集和传输数据的非常复杂的测量工具。每一次点击、滚动和悬停都有可能被报告回母舰进行分析。

像 Google Analytics ,振幅, Chartbeat , Mixpanel , Flurry 等分析平台。所有人都在这个领域工作,使用各种方法收集用户正在做的事情的数据。在核心上,它们以发生的“事件”的形式(页面查看、点击、滚动、悬停等)收集信息,并定期将信息报告给分析服务。这是一个相当复杂的空间。

这甚至不仅限于网页。最近有文章讨论 Kindle 上的每一次点击、触摸和互动是如何被亚马逊追踪和存储的。

尽管这听起来令人毛骨悚然且具有侵犯性,但这种超细粒度的数据收集和传输在现代分析时代几乎是必然的。我不得不依靠类似的数据来帮助团队做出产品决策。如果没有这种粒度级别的数据,许多 UX 和商业问题都无法得到解答。做这件事的工具现在也很容易得到,所以每个人都可以做这件事,不只是 megacorps。

与此同时,电子邮件(在一定程度上,短信)实际上没有这些高级跟踪功能。这对我们提出了挑战。

电子邮件(很大程度上)是单向交流

电子邮件是非常古老的技术。有一个 RFC # 196,可追溯到 1971 年,名为“邮箱协议”,它描述了一种向连接到行式打印机的系统发送消息的方法,消息由人工传递到物理邮箱。

显然,今天没有行式打印机和人工递送,但基本概念仍然完好无损:**电子邮件是一种单向的沟通渠道。**它接受一条消息,仅仅是字节的集合(默认为 7 位 ASCII 编码!),然后通过一系列系统发送出去,这些系统试图将邮件传递给预定的收件人。

从一开始,整个电子邮件基础设施的设计就模仿了物理邮件的方式。用户通过他们的邮件客户端向邮件提交代理 (MSA)提交邮件,然后通过对 MX 记录的 DNS 查找将邮件路由到一个或多个通过简单邮件传输协议(SMTP)传输邮件的邮件传输代理 (MTA)。最后,经过 MTA 的一跳或多跳后,字节到达邮件传递代理(MDA ),它将字节放入一个数据结构中,由收件人的邮件客户端存储和读取。邮件实际上存储在目的地的一个或多个文件中。

说句题外话:我要避免往下走一个mbox格式兔子洞 因为篇幅原因,但是很简短,很神奇。电子邮件都在一个文件中,并以“发件人”一词分隔!这就是通信存储的 CSV!

从 Alice 点击电子邮件客户端上的[发送]开始,直到她的电子邮件被发送到邮件发送代理(您的邮件客户端将通过 POP3/IMAP4/etc 访问该程序以将邮件呈现在您的眼前),在整个时间长度内,电子邮件都是在推送模式下传输的。 SMTP 命令列表本质上只有动词来表示“嗨,服务器,我有你的邮件,拿着这个并发送出去”。在 SMTP 中肯定没有办法表达“嗨,服务器,给我所有的电子邮件”。MTA 不支持这种功能。

事实上, RFC 5321 明确指出,当一个 MTA 对传输给它的邮件给出 2xx 响应时,它接受确保消息到达它需要去的地方的责任,或者报告传递失败。

只有在旅程的最后一段,当收件人 Bob 加载他的邮件客户端来检查电子邮件时,它才最终成为拉动操作。收件人的客户端可以使用邮局协议 (v3)、POP3(旨在将邮件从 MDA 中取出,通常是从 MDA 中删除邮件)进行本地消费,或者使用互联网邮件访问协议 (v4)、IMAP4(旨在从服务器中读取邮件并将其留在那里,例如网络邮件)。如果需要,客户端也可以使用一些专有协议。

所有这些意味着,一旦 MTA 成功地传递了信息,他们就可以忘记你的信息(如果他们愿意的话)。寄件人唯一能得到有关流程反馈的时间通常是由于某些问题(地址不正确等)导致投递失败的时候。

但是电子邮件并不完全是单向的(等等什么?)

有两个(!!)电子邮件规范本身允许通信从接收者向发送者反向流动的方式。附带说明。大的。

交付状态通知

第一个是 RFC 3461 ,它是对 SMTP 的扩展,添加了交付状态通知(DSN)。如果你向一个不存在的电子邮件地址发送了一封电子邮件,但邮件无法送达,这个功能会通知你。它实际上是消息头中的一个可选标志,如果消息传递失败或成功,发送者可以请求得到通知。正常情况下,它只是默认只在交付失败或延迟时报告。

问题是这是一个可选功能,尤其是对于成功的 DSN。如果 MTA 或 MDA 选择限制该特性的使用。不会成功的。实际上,成功的送达通知几乎从未使用过,你也不应该指望它们会起作用。请不要打开它们。

另外,一个成功的 DSN 只会告诉你计算机已经把它发送到了收件箱,而不会告诉你人们是否已经看到了它。这就像邮递员把跟踪确认箱放在门廊上,随时都有东西能让包裹消失。该消息也可以被完全忽略、过滤或删除。

消息处理通知

第二种方式是通常所说的“已读收据”。根据你使用的电子邮件服务/客户端(尤其是如果你使用 MS Outlook 和 Thunderbird),你可能会认出这个术语。这些事情实际上是在 RFC 8098 “消息处理通知”下标准化的,尽管对于这种功能有各种各样的专有协议。它主要出现在公司环境中,每个人都使用相同的软件。

与上面提到的 DSN 不同,这些是在用户实际打开和阅读电子邮件时触发的。这些 MDN 可以报告电子邮件被“显示”给用户,“发送”到其他地方,“处理”而不被看到,甚至“删除”而不被看到。哇!这么多信息!

除此之外,它要求接收客户端支持该特性(许多不支持或有限制),并且通常涉及选择加入的方面。通常会有一个提示,比如“Alice 想要一个阅读回执,发送吗?是/否”。除了这些问题之外,还有很多边缘情况,例如,如果用户只是将一封电子邮件标记为已读,而没有打开它,会发生什么?

所以,还是那句话,不要指望使用这些数据。

那么,我们能统计哪些涉及电子邮件的信息呢?

不是太多,而是一些东西。让我们来看看大的:

发送的电子邮件

这个很简单,因为作为发件人,你应该知道你发出了多少封邮件。这至少给了你所有其他事情的通用标准。这可能是所有这些中唯一确定的数字。

退回/失败的交货

由于 SMTP 的 DSN 特性,当你发出的邮件无法送达时,你通常会得到通知(但不是所有时间)。知道这一点对调整你的邮件列表很重要。从你的“发送”总数中扣除这些邮件也很常见,因为它们并没有真正去任何地方。

哦,是的,如果你用你自己的服务器,从你自己的域名发送电子邮件,你实际上可能会得到比你发出的电子邮件更多的反弹。这被称为反向散射,垃圾邮件发送者通过伪造邮件标题假装从您的服务器发送邮件。所以你必须非常小心如何处理反弹。

HTML 电子邮件给你更多的选择

如果你发送的是纯文本邮件,上面的统计数据几乎就是你所能得到的全部。但是如果你使用 HTML 格式的电子邮件(现在大多数人收发的都是这种格式),你就能接触到更多的内容。

通过跟踪像素打开

现代电子邮件客户端实际上是微型网络浏览器。至少,它们可以呈现 HTML,包括从互联网上获取图像等资源的能力。请注意,还有一种方法可以将图像附加到电子邮件中,这样就不需要外部获取,但这对分析没有帮助。

这种 HTML 特性可以用于分析的一种常见方式是通过放置一个微小的 1x1 像素透明 GIF 文件(因此得名),该文件托管在某个外部服务器上(如 example.org/tracking_string/sneaky_1x1.gif 的)。当电子邮件客户端试图加载图像时,它必须向 web 服务器发出 HTTP GET 请求。然后,服务器意识到“ tracking_string ”的 GIF 文件已经被加载,并把信息保存在某个地方。使用查询参数,example.org/sneaky_1x1.gif?track_query=user12345,也是向服务器传递详细信息的一种重要方式。**

如果您为发出的每封电子邮件生成一个唯一的 tracking_string,那么您可以通过读取这些 pixel 访问日志来找出谁打开了该电子邮件!

注意:它不一定是 1x1 像素,或者 gif。你所需要的就是接收者从你的服务器上加载一些东西,任何东西。一个标志图像就可以了。

****警告:这种方法的一个问题是它依赖于接收者加载你的图像。出于安全原因,某些客户端在默认情况下不会这样做,至少您通常可以更改设置来选择加入/退出远程映像加载。所以,同样,这个数据不会是完美的。

通过跟踪像素的 Cookie

pixel 的 HTTP GET 请求也可以在客户端的浏览器上设置一个 cookie。这是否有用将取决于邮件客户端的浏览器功能是否有 cookie 功能。通常默认情况下它是关闭的,所以依赖它是不明智的。

显然,这些 cookie 不会被传递到主浏览器,除非电子邮件客户端和浏览器以某种方式共享同一个 cookie 存储。我甚至在网上找不到任何关于这种共享行为的参考资料。

因此,您对这些 cookie 唯一能做的事情就是,如果您设置并在多次打开时看到同一个 cookie,您就可以知道它在同一设置中至少被打开过一次。也许吧。

通过跟踪像素的设备

因为用户代理应该在每个 HTTP 请求的报头中发送,所以您可以对其进行分析,以确定是什么设备打开了电子邮件。这里说的太多了,所以对于那些好奇的人来说,我在之前的一篇文章中讨论了用户代理的复杂性。对于流行的设备,它可以让分析师看到具体的型号和变体。

随着时间的推移,存储这些用户代理的副本,你就可以计算出一个人可以访问多少个浏览器和设备。怪异。

IP 通过跟踪像素

由于动态 IP 是通过 ISP 分配的,移动设备 IP 随着移动/进入/离开网络、VPN 和代理而变化,因此 IP 分析相当不一致,但总的来说,它们通过地理定位提供了人们来自哪里的概念。他们通常能告诉你请求来自哪个国家。

一些 IP 比其他 IP 更持久,静态服务器 IP 和家庭 IP 显然比移动设备更少改变。VPN 和代理也可以有不同的属性,这至少让你知道他们不是“普通用户”。因此,如果有人有这些信息,他们可以彻底调查,但在没有付费为你分类 IP 的情况下进行大规模调查是很痛苦的。

我经常懒得去调查知识产权,因为即使我有这些信息,我也无能为力。

通过跟踪 URLs 重定向点击链接

因为我们有了 HTML,用户可以点击链接,这些链接将在他们实际的网络浏览器中打开(而不是他们邮件客户端内部的任何东西,后者可能具有有限的功能)。如何知道用户是否点击了一个链接,或者点击了什么链接?

URL 重定向是最简单的方法。有很多种方法可以实现重定向。

使用 HTTP 302 响应代码“发现”(以前称为“临时移动”)使浏览器重定向到另一个 URL 的最简单方法。其他 3xx 响应代码也可以工作,但有不同的细微差别。所以你需要做的就是用一个去 myservers.com/tracking_string1的链接替换你原来的链接,然后设置你的网络服务器发送一个 302 响应给实际的目的地。

因为你可以使链接变得独特,而且你确切地知道它在哪个电子邮件中,你可以明确地说点击来自那个电子邮件。请记住,电子邮件可以转发,链接可以共享。

你也可以在你的网络服务器日志中获得一个条目,包括所有的常用信息,IP,用户代理,时间戳,引用等。但仅此而已。如果你想要更多的分析,你必须使用其他方法。

更有效的方法是通过 META 标签或 JavaScript 制作一个既收集数据又重定向用户的页面。当用户短暂停留在你的页面上时,你可以做更复杂的浏览器指纹识别。

这里有更多的技术细节需要解决。你必须快速地做每件事,因为用户讨厌东西加载缓慢,跟踪重定向增加了宝贵的毫秒加载时间。你也可能想做某种形式的 referrer 擦洗 来隐藏你正在从下游做这些重定向的事实。

****警告:如果 URL 隐藏在重定向的后面,那么很难防范这种形式的跟踪。所以这通常意味着你不会少算点击次数。然而,由于前面提到的链接分享,你可以很容易地计算很多很多点击。它们将是实际的点击,但你不会真的确定“谁”在做这些。

这是上周我的 10x data scientist 文章中发送的电子邮件子堆栈中的一个例子(去掉了样式和内容)。注意复杂的散列字符串占据了 URL 的大部分。

**<a href="http://email.mg1.substack.com/c/eJwlUMuOwyAM_JpyRA55UA4ctt32NyIC3hRtAhGYjfL3S1ppJEtjax62hnCO6dBbzMRKxjR6p4eulaCAOQ1SWDkxn8efhLgav2i2lWnx1pCP4TwW8top9tKIQrWyU-BML0DIrkeB0KDr5TQADuy0GE1xHoNFjX-YjhiQLfpFtOVL-3URz4p937kzZF64bJgyj2muLPO6ikJF17TQC8UbrhoJ1--buqvb8_EQw6WDdW54LlMmY3-5jStLOpngDm5K3c5ngTddO4x1riV4OkYMZlrQaUoFGX1-8U5Lx4Y64J4XJML0Ic_OA4AaWHVysWoGbWMJ5MP8D_lucHE">datahelpers.org</a>**

如果你按照链接,你会得到 302 重定向到正确的网站。

通过点击链接的 Cookies

这开始进入你正常的网络分析。但与您可能在跟踪像素上设置的 cookie 不同,它绑定到一个可能不允许 cookie 的 web 客户端,您最有可能通过链接点击获得一个真正的浏览器。这意味着 cookie 信息更加持久和有用。至少,你可以识别出这个浏览器以前是否通过电子邮件访问过这个网站。

另外,你可以对用户进行所有常规的网络分析,因为他们已经在网站上了。

网络分析一旦他们到达你的网站

虽然以上这些都是你可以从电子邮件中直接获得的,但成功地让某人访问你控制的网站会让他们获得更多的跟踪和分析机会。

如果你的电子邮件发送一个人到你拥有的网站,并且他们登录,你可以把点击和登录联系在一起。这让你可以讲述一个关于用户正在做什么的更丰富的故事。现在你可以说“他们收到了我的邮件,点击了我的行动号召链接,买了 10 个小部件”,而不是“用户来到我的网站,买了一个小部件”。

对于没有登录的人,你得到的有用信息要少得多。通常他们的推荐人是空的,这导致像 Google Anlaytics 这样的工具说流量是“(直接的)”,这意味着他们出现在页面上,GA 不知道为什么,所以他们必须被直接发送到那里。显然,没有人会在他们的浏览器中手工输入长 URL,但是我们没有任何关于他们从哪里得到链接的信息。

由于缺乏推荐人,从网络分析的角度来看,电子邮件客户端看起来就像短信一样,或者像 s lack 等其他外部应用程序的链接。他们一般都长得像(直接),所以可能会很乱。您总是可以为不同的通信渠道分配唯一的链接来帮助缓解这种情况,但当链接不可避免地被共享时,这仍然只是一个最佳猜测。

缺少推荐人的原因有点复杂,这不是什么大阴谋或隐私运动。将用户发送到浏览器中的独立邮件客户端不会向浏览器发送推荐信息(它们几乎不能)。Webmail 客户端通常使用 HTTPS,当从 HTTPS 转到 HTTP 网站(但不是 HTTPS->HTTPS)时,推荐人会被删除,他们还可能使用带有元标签(如<meta name="referrer" content="no-referrer"/>(或类似的东西)的重定向页面,以进一步删除推荐人,以保护隐私。

更多电子邮件讨论下一个帖子

这涵盖了我认为可以从电子邮件分析中收集的所有技术数据。接下来,我需要深入了解您在实际使用收集的数据时需要记住的细微差别。

我不喜欢为了从一个话题中挤出更多的帖子而拆分话题,但我们在这个帖子中推了 3000 字。这有点荒谬,所以我们下周见!

这篇文章最初于 2020 年 2 月 18 日发表在兰迪的 计数材料子栈 上,这是一份关于数据科学更世俗方面的每周时事通讯。在免费文章在媒体上重新发布之前,注册并获得每周文章。

使用 Plotly 在幻灯片中嵌入交互式绘图

原文:https://towardsdatascience.com/embed-interactive-plots-in-your-slides-with-plotly-fde92a5865a?source=collection_archive---------12-----------------------

用眼镜编辑器超越 PowerPoint

对于我们这些数据科学家来说,有效的沟通是必不可少的,而 Plotly 的交互式图表是一个很好的工具。但是当涉及到以传统的幻灯片风格展示我们的工作时,这些情节很难集成到我们的日常工具中,如 PowerPoint 或 Google Slides。在这篇文章中,我们将了解眼镜编辑器 Plotly 的一个演示工具,它允许在幻灯片中嵌入交互式情节和动画,并提升您的演示文稿。

酪 pptx 工作就好了…何必呢?

莱昂纳多·巴尔迪萨拉在 Unsplash 上的照片

想象一下,你已经涵盖了你认为对你的演讲很重要的内容,然后你的听众会提出一些涉及到次要细节或你的人群中某个特定人群的后续问题。现在,你必须回到你的代码中去获取一个答案,或者在以后继续跟进。把你的土地分割成小块,然后当场取回任何需要的东西,这不是更容易吗?例如,查看这个平行坐标图,您可以对任何变量进行过滤和高亮显示:

承蒙作者好意。

或者,您可以在演示时与之互动的动画条形图:

承蒙作者好意。

入门需要什么?

  • A Plotly 图表工作室账号 :你可以轻松注册你的 github、谷歌或者脸书账号。
  • 互动 Plotly 剧情:在我的上一篇中,我介绍了 Plotly 的互动剧情和动画。帖子中提供的代码应该足以生成一些情节来玩。
  • 最后,快速下载眼镜编辑器。

潜入水中

一旦你登录,界面非常熟悉和直观。从你通常的演讲准备程序开始:

说到互动情节,你只需要:

1.在 Chart Studio 上发布您的图,并复制您的图的 url

2.回到眼镜,点击“Plotly 和破折号”并粘贴网址:

3.情节应该立即融入你的幻灯片。一旦进入演示模式(**cmd+L**),它就会变成交互式的。

此外,您可以在幻灯片中很好地集成和共享任何语言的源代码。只需点击**CodePane**,选择您的语言并粘贴您的代码:

一旦你完成了,点击**cmd+L**来展示你的作品,切割你的情节,充分利用你的视觉化技能。如果需要,您还可以存储演示文稿的. pdf 版本。

下一次,你的观众想知道更多,你已经准备好当场操纵你的数据,并迅速解决任何疑问!

延伸阅读:

有关编辑器的更多信息,请查看 Plotly 的官方文档。

更多互动的可视化,你可以看看我的文章“ 5 个可视化来提升你的数据故事”。

差不多就是这样!

我希望您发现这很有用,并将它添加到您的工具箱中。保持安全和高效!

照片由格伦·凯莉在 Unsplash 上拍摄

使用微软认证在 Flask 中嵌入多个 Dash 应用程序

原文:https://towardsdatascience.com/embed-multiple-dash-apps-in-flask-with-microsoft-authenticatio-44b734f74532?source=collection_archive---------8-----------------------

唷!这是一次旅程(通过示例),目的是将所有部分组合在一起,为部署在一起的多个 Dash 应用程序构建一个可扩展的模板,并提供统一的导航和身份验证

图片来自 Pixabay

充分披露:我不是开发 web 应用程序的专家。我甚至不认为自己是数据科学家。自从我发现 Dash 以来,我就一直在努力构建一个适合我的用例的系统。这包括试图将多个松散关联的 Dash 应用组合在一起,这些应用使用 windows 电脑开发,但部署在公司防火墙后的 Ubuntu 虚拟机上。添加一些用户不会讨厌的身份验证(即他们已经在使用的东西),我找到了一些我找不到的清晰示例,所以我想分享一下我当前的解决方案及其演变。

我是一名结构分析师,我每天使用 Python 处理测试数据,缩放或合并分析结果,运行优化或权衡研究,和/或开发特定于组件或机制的分析方法。其他大部分工程师不使用 python。因此,一旦我开发或编码了一个现有的分析方法,我通常希望以一种可控的方式将其部署到其他人身上,使用一个熟悉的和用户友好的界面…进入 Plotly 的 Dash 框架!

普罗特利的 Dash 框架

我是 Plotly 的 Dash 框架的超级粉丝。如果你已经熟悉 python,制作一个 Dash 应用程序是相当简单的。添加 Dash Bootstrap 组件,流畅、美观、响应迅速的网络应用程序只需要几行额外的代码。从现有的 Python 脚本到 web 应用程序是 1–2–3 的事情

  1. 为用户输入创建带有组件的布局(按钮、下拉框、数字/文本输入等)。)和有结果的区域(图、表等。)使用布局元素( div、row、column 等)。)
  2. 通过回调将用户输入链接到实际执行工作的函数
  3. 部署应用程序,或者在目标用户可访问的主机或虚拟机上运行应用程序

普罗特利的破折号,图片来源:https://plotly.com/dash/

Dash 应用程序看起来很漂亮,你可以用 Python 编写它们(避免使用 javascript 和原始 html),并且可以使用相同的“受控”工具拥有广泛的受众(不用传递 excel 文件,非常感谢)。如果你不熟悉 Dash 文档,请查看它。有很多其他优秀的关于构建 Dash 应用程序的教程,这些人无疑比我更优秀,所以我将保持这一节的简短。Dash 社区论坛和堆栈溢出是你的朋友。

好了,现在我们有了一个很好的方法来给团队提供一个很好的工具。但是我有很多工具,有些相关,有些不相关。如果我们能以某种方式将这些应用组合在一起…

在 Flask 应用程序中嵌入多个 Dash 应用程序

这似乎是一个相当普遍的要求。Plotly 提供 Dash Enterprise 来帮助向更多受众部署多个应用,同时保持安全性。对于您的团队来说,这可能是一个更容易、更具可伸缩性的解决方案,尤其是当您有多个开发人员时。对于我们这些没有 Dash Enterprise 的人来说,Plotly 团队在开源文档中讨论了几种创建多页面应用程序的方法。第一个是通过使用 dcc 向视图发送不同的布局来创建多页面 dash 应用。位置 & dcc。链接通过回调交互的组件。对我来说,这对于一些小应用程序来说还行,但是随着应用程序数量的增加,它似乎变得混乱了。我更喜欢让单独的应用程序成为独立的对象。我通常先在本地创建一个独立的 Dash 应用程序,然后集成到其他应用程序中进行部署。一个应用部署完成后,我会经常回去更新它。一旦它被集成(至少是我实现它的方式),我不得不加载整个应用系统,只是为了测试其中的一部分。这很快就过时了。所以我开始寻找不同的方法。

在我旅程中的某个时候,Plotly 团队在文档中添加了关于在现有 web 应用中部署 Dash 应用的讨论。我还看到了他的精彩文章:

[## 如何将 Dash 应用嵌入到现有的 Flask 应用中

Dash(由 Plotly 开发)是一个开源的、易于使用的 Python 框架,用于构建漂亮的数据驱动的 web 应用程序。

medium.com](https://medium.com/@olegkomarov_77860/how-to-embed-a-dash-app-into-an-existing-flask-app-ea05d7a2210b)

那时我根本没有使用过 Flask,所以模板、视图、蓝图、数据库对我来说都是新的。它花了一些时间来吸收这一切(至少足以尝试和工作)。烧瓶超级教程帮了大忙。有了 Oleg 的 Medium 文章和 Flask Mega 教程(加上大量的 google - > stackoverflow ),我开始拼凑一种新的(对我来说)方式来打包我的 Dash 应用程序,将它们嵌入到“父”Flask 应用程序中。

一个基本例子

我遇到的大多数例子基本上只是玩具。我觉得我遇到的那些没有覆盖足够的模板来使它可扩展。我认为我最大的问题是如何在 Flask 部分集成统一的导航和引导格式。这里的例子启动了我将在接下来的章节中构建的框架。本节涵盖的全功能项目可以在 github 的“基本”分支下找到。

让我们从项目目录结构开始:

dash_in_flask_msal
│   config.py
│   env_p38_dash.yml
│   secret.env
│       
├───app│   __init__.py│   ├───dashapps│   │   dash_app_1.py│   │   dash_app_2.py│   │   routes.py│   │   __init__.py│   │   │   ├───templates│       └───dashapps│               dash_app.html│               dash_app_debug.html    |├───main│       routes.py│       __init__.py│            ├───static├───templatesbase.htmlindex.html

我正在使用蓝图(“主”和“dashapps”)和一个应用程序工厂。主蓝图现在并不真正做任何事情,它只是为索引服务。“Dash apps”蓝图中有两个 Dash 应用程序(dash_app_1.py & dash_app_2.py)。这是一个相当标准的 Flask 应用程序布局。

应用程序工厂

create_app()应用程序工厂位于app目录下的__init__.py文件中。在这一点上,它是相当基本的。我们从config.py文件(基本上是空的)导入Config对象,并将其附加到应用程序。我们初始化 bootstrap-flask 扩展,并用 app_context 注册蓝图。那都是普通的烧瓶。现在新的东西来了:我们从每个 Dash 应用程序文件中导入一个add_dash函数,并通过每个文件传递 Flask 应用程序。

烧瓶中碱性 dash 的应用工厂

让我们来看一个 Dash 应用程序文件。dash_app_1.py文件看起来很正常。主要区别是:

  1. Dash 应用程序和所有回调的创建都在一个add_dash()函数中,该函数获取 Flask 应用程序(server)并在创建 Dash 应用程序对象时使用它,在创建所有回调后返回 Flask 应用程序
  2. 当通过URL_BASE全局变量创建 Dash 应用程序时,我们传递一个定制的url_base_pathname 参数
  3. 我们使用一个全局变量APP_ID 作为所有组件 id 的前缀。

典型的 Dash 应用程序包装在“add_dash”函数中

好了,现在我们看到 Dash 应用程序是如何附加到母 Flask 对象上的,但它们看起来仍然非常熟悉。为了完成设置,我们需要查看功能来显示 Dash 应用程序。让我们看看dashapps 蓝图文件夹中的routes.py文件。

dashapps 蓝图中的 Routes.py

需要注意的一点是,用于创建应用程序的 url_base_pathname 不是用于查看功能的 url。仪表板应用程序端点在/dash/dash_app_1处,但视图功能路线在/dash_app_1处。要了解发生了什么,我们必须看一下模板。

模板和引导!

有一个所有其他模板固有的基础模板(base.html)。这是我们安装导航系统的地方。为了在 Flask 位中使用引导样式,我找到了引导-Flask 库。不要与 Flask-Bootstrap(不支持 Bootstrap 4)混淆。我真的很想避免 HTML,所以有一次我尝试了看起来很有希望的 Flask-Nav,只是后来发现 Flask-Bootstrap 看起来会停留在 Bootstrap 3。所以自举瓶和一点 HTML 就可以开始了!我从自举烧瓶启动模板开始(当然!).然后我去了 Bootstrap 4.0 网站,抓取了一个包含下拉菜单的示例 navbar 部分,并把它放到一个名为“navbar”的 jinja2 块中,这个块放在一个容器中。我添加了一个消息部分,用于发送类别不在导航栏内的消息。您可以看到下拉链接是由 url_for('dashapps.dash_app_1 ')创建的,其中 dash_app_1 是该应用程序的查看功能。还有一个{% content %} 模块,所有其他模板都将在其中工作。

base.html 模板有趣的导航位

现在我们看到 dash app 中的url_base_pathname 和 view 函数端点的区别。我将 Dash 应用程序嵌入 Flask 的方法是在它自己的 url 上运行 Dash 应用程序,然后通过 iFrame 元素将其注入模板。在调用dash_app.html模板的视图函数中,我传递了 Dash 应用 url ( dash_url)和一个min_height参数来定义 iFrame 的高度(我找不到让 iFrame 响应的方法)。

dash_app.html 模板

让我们看看它的工作!

使用 Bootstrap 4 实现统一导航!

现在是奖金!Dash 应用程序文件的末尾是以下代码。这使得 dash 应用程序可以独立运行,但在一个模板(dash_app_debug.html)内运行,该模板与主模板非常相似。

这允许独立的 Dash 应用程序测试(不需要启动整个 enchilada!

现在有了持久数据(即数据库)!

没有持久的数据,应用程序是非常简单的。我开发的许多应用程序只是花哨的计算器或数据解析器,所以它们不需要数据库。然而有些人会。作为结构分析,我生活和呼吸材料的属性,优惠券测试数据,振动测试数据。当然,我们可以将 excel 或 csv 文件复制到静态或资产目录,并从那里加载它们,但这是一种非常脆弱的数据存储方式。理想情况下,我们会有一些东西,多个用户可以安全地读写…进入数据库!我之所以使用 SQLite,是因为我的用例不需要太多其他东西(我在这里没有重新创建 Instagram ),但我认为它可以适应另一种数据库类型,而不会有太多麻烦。我还使用了 Flask-Sqlalchemy 扩展。本节所涵盖的完整功能项目可以在 GitHub 的‘now _ with _ db’分支下找到。此示例添加了一个 Dash 应用程序,用户可以将带有一些数据的图像上传到该应用程序,并添加了另一个显示图像和数据的应用程序。

令人兴奋的持久数据!

让我们回顾一下新的目录结构!我从下面的目录结构中删除了一些“基本”例子中没有改变的内容。现在我们可以看到 app 文件夹旁边有一个db 文件夹。它有my_data.db & users.db文件,还有一个img 子目录,里面有一些*.jpg文件。

dash_in_flask_msal           
├───app
│   │   __init__.py
│   │   
│   ├───dashapps
│   │   │   dash_app_1.py
│   │   │   dash_app_2.py
│   │   │   models.py
│   │   │   routes.py
│   │   │   user_image_upload.py
│   │   │   user_image_view.py
│   │   │   __init__.py
│   │   │   
│   │   ├───templates
│   │           
│   ├───main
│   │           
│   ├───static
│   ├───templates
│           
├───db│   my_data.db│   users.db│└───img649303dc7de4402fb62acbd33a163e37.jpgca49fc3d1e944398b42a95b04db14366.jpgd6f47fcc13e2408a88b512729b280b09.jpg

基本示例中的配置文件并不多,只有导航条的“品牌”。我们现在需要添加更多的配置变量。我们将通常的SQLALCHEMY_DATABASE_URI添加为 SQLite 数据库,带有默认的users.db文件名和带有my_data绑定的SQLALCHEMY_BINDS文件,附加到一个my_data.db sqlite 文件。我们还没有使用users.db数据库,所以从技术上来说现在还不需要(我们会实现的!).我们有一个定制的配置参数IMG_FILE_DIR ,默认为新db 文件夹下的img 目录。

我们还增加了两个新的 Dash 应用程序(user_image_view.py & user_image_upload.py)和一个新的models.py文件。在我们深入了解新的数据库用法之前,让我们先来看看dashapps 蓝图目录中的routes.py 文件:

我们增加了 2 条新路线(/image_view & /image_upload)。所有这一切的想法是试图将重点放在单个 Dash 应用程序上,而不是花太多时间集成(一旦框架建立)。除了添加了routes.py文件之外,我还在base.html 模板中添加了一个新的下拉组用于导航。到目前为止,添加额外的应用程序看起来非常简单…

现在让我们来看看新 Dash 应用程序的数据库模型:

这里我们创建了一个带有一些字符串数据列和一个LargeBinary 类型的User_Image 模型。让我们来看看user_image_view.py应用程序,看看这些是如何实现的:

我们从app 导入db ,从app.dashapps.models.导入User_Image 模型,我们有通常的全局变量,一切都在add_dash 函数中。新的是,在创建 Dash 应用程序后,我们将布局创建为一个函数serve_layout(),而不是一个静态布局变量。这允许在每次页面加载时调用这个函数,我们可以读取数据库。看,妈妈!没有复试!就在函数的顶部,我们使用以下命令查询数据库中所有的User_Image 对象:

uimgs = db.session.query(User_Image).all()

并且在通过uimgs 创建布局回路时,用仪表板引导组件卡卡中的数据填充布局。注意,User_Image 对象(LargeBinary)的thumb 属性实际上是直接存储在数据库中的图像,数据被附加到src 属性上。将图像直接存储在数据库中并不理想,但是存储大的 blobs 会很有用。

user_image_upload.py Dash 应用更多的是传统的 Dash 应用,采用静态布局。这里还有很多内容,请访问 Github 查看。基本思想是有几个输入字段和一个上传组件以及一个卡片组件。我们基本上是在为user_image_view.py应用程序建卡。此外,还有一个数据表,用于加载现有的图像数据,以便以后对其进行修改。这里我们添加一个图像:

填充数据并将图像添加到数据库

文件中有一些技巧,包括使用dash.callback_context来确定哪个组件触发了回调(主要是为了让 1 feedback div 可以被多个进程更新)。下面是“保存”回调中的一个片段,其中一个新图像被添加到数据库中。如果选择了一行,derived_virtual_selected_rows 将是一个长度为 1 的列表,并将包含该对象的主键数据库 id。它将被检索,其内容将被应用程序字段中的数据覆盖。

好了,我们可以向数据库中添加项目并查看它们了!但是我们不能让每个人都添加他们最喜欢的猫的照片,那只会融化服务器。所以我们需要一种方法来限制对上传的访问…

添加 Microsoft 身份验证库(MSAL)

你不需要另一个密码来尝试和记住,我知道我不需要。理想情况下,我们添加的任何密码都应该是目标受众已经在使用的密码。我在微软的世界里工作,在那里很多人花很多时间使用微软的产品。….输入 Microsoft 身份验证库(MSAL)。

微软身份平台是一个符合 *OAuth 2.0 和 OpenID Connect 标准的认证服务。*你可以按照微软的 quickstart 为 python web 应用添加认证。起初,这让我很困惑(请记住,我不是 web 开发人员)。这个例子比微软的文档帮助更大。Miguel Grinberg 的另一篇关于 Flask 中誓言认证的博文也影响了我的学习。如果你想用 Twitter 或脸书 OAuth 认证取代微软认证,Miguel 的 OAuth 帖子可能会有所帮助。

基本步骤是:

  1. 在 Azure 中注册你的应用并回拨(跟随快速入门)
  2. 收集您的租户 ID、客户 ID 和客户机密,并将其放入您的 Flask 配置中
  3. 添加一些生成 url 的函数,以获得身份验证和捕捉返回的方法

“Azure-Samples”示例没有将用户存储在数据库中。我想使用 Flask-login,这样我就可以简单地用@login_required 来修饰需要凭证的站点部分的回调,所以我混合了这些例子,一直进行下去,直到有东西可以工作为止。在 Github 的“msal_login”分支下发布了一个几乎可以使用的例子。要将其提升到全功能,您需要提供TENANT_IDCLIENT_IDCLIENT_SECRET.

让我们从项目目录开始:

dash_in_flask_msal
│   config.py
│   env_p38_dash.yml
│   secret.env
│           
├───app
│   │   __init__.py
│   │   
│   ├───auth
│   │   │   models.py
│   │   │   routes.py
│   │   │   __init__.py
│   │   │   
│   │   └───templates
│   │       └───auth
│   │               login.html
│   │               
│   ├───dashapps
│   │   │   dash_app_1.py
│   │   │   dash_app_2.py
│   │   │   models.py
│   │   │   routes.py
│   │   │   user_image_upload.py
│   │   │   user_image_view.py
│   │   │   __init__.py
│   │   │   
│   │   ├───templates
│   │       └───dashapps
│   │               dash_app.html
│   │               dash_app_debug.html       
│   │           
│   ├───main
│   │       routes.py
│   │       __init__.py
│   │           
│   ├───static
│   ├───templates
│           base.html
│           index.html
│           
├───db│   my_data.db│   users.db│   └───img649303dc7de4402fb62acbd33a163e37.jpg770a75b7e77f4914b85eb610582b3cb3.jpgca49fc3d1e944398b42a95b04db14366.jpgd6f47fcc13e2408a88b512729b280b09.jpg

大多数文件与上一个示例中的相同。然而,我们现在有了一个auth蓝图,包括模型、路线和模板。还显示了一个secret.env文件,但它不在 github 上。这个文件中定义了让这个例子正常工作所缺少的部分。不过,您可以将它们直接添加到您的配置中。

一个完全伪造的 secret.env 文件…但是它包含了变量名!

在我们进入auth 蓝图之前,让我们看看应用工厂功能是如何变化的。

我们看到我们正在从flask-login 导入LoginManager并初始化它。我们还用前缀 /auth注册了新的auth 蓝图。我们还在add_dash 函数中看到一个新参数:login_req ,它采用一个布尔值。我们将回到这一点。

现在让我们看看auth 蓝图。在models.py文件中,你会发现一个非常基本的用户模型,它缺少密码和登录信息(因为 MSAL 会处理这些)。我们只有nameemail 列(唯一 id 除外)。有趣的部分在蓝图__init__.py文件和routes.py文件中。

__init__.py文件有两个函数(_build_msal_app & _build_auth_url),我们将在routes.py文件中导入和使用。这些函数基本上是从 Azure-Samples Flask 示例中复制的。在 routes.py 文件中,我也非常接近 Azure-Samples 示例。主要区别是我使用的是熟悉的@login_required,认证完成后,要么将用户添加到数据库(如果这是他们第一次登录),要么通过flask-login.login_user()功能登录。除了auth 蓝图,在dashapps 蓝图中也有一些新的特性。

dashpps 蓝图 init。py,现在有了新功能!

我们现在有了这个_protect_dashviews()函数,它遍历 Dash 应用程序的服务器视图函数,如果它以url_base_pathname开始,我们就用login_required()包装它。该功能被导入每个 Dash 应用*。py 文件,如果add_dash()函数的新login_req参数是True ,那么在创建应用程序的过程中,在返回服务器之前,Dash 应用程序被传递到_protect_dashviews()。所有的功劳都归于 Oleg,因为这种方法来自他的 medium 文章(链接如上),我只是将其重新配置为一个选项,而不是将其应用于所有 Dash 视图。

除了保护推送到 iFrame 的 dash 视图,我们还必须用常用的@login_required 装饰器保护 Dash 应用程序的主视图功能。在本例中,我正在保护一个 Dash 示例和user_image_upload Dash 应用程序。

两个 Dash 应用程序的受保护视图功能

现在我们正在认证!

结尾…

这是一段不寻常的旅程。这不是一个完美的解决方案,我相信这里和那里都有一些漏洞,但我希望这能帮助你的下一个项目。感谢您花时间阅读本文!

在新冠肺炎研究中嵌入分析可以大大加快相关文档的定位

原文:https://towardsdatascience.com/embedding-analysis-in-covid-19-research-can-greatly-expedite-the-location-of-relevant-documents-41b2c546c96?source=collection_archive---------51-----------------------

在 Unsplash 上由 Nelly Antoniadou 拍摄的照片

“数据的缺乏在很大程度上是由于在疫情爆发的早期阶段推迟推出广泛的测试。”—美国消费者新闻与商业频道

目标

这项研究的主要目的是通过使用单词和文档的语义表示,并借助嵌入技术,促进发现与新冠肺炎相关的最相关的研究论文。

架构

  1. 加载语料库
  2. 使用该数据训练无监督 word2vec 和 doc2vec 模型。
  3. 接受输入问题,并选择定义该问题的最相关词语
  4. 使用这些基于最相关单词的查询 word2vec 模型将生成额外的相似单词。
  5. 使用这本词典,人们可以从整个语料库中过滤文档,以缩小我们的搜索空间。
  6. 现在使用 doc2vec 模型,可以为过滤后的语料库生成特征向量,也可以为输入问题生成特征向量。
  7. 最后,使用相似性度量,可以找到与我们的查询最近的邻居。

接近

  1. 新冠肺炎数据加载和准备

最近 Kaggle 向世界人工智能专家发出的行动呼吁倡议,艾伦人工智能研究所已经提供了超过 70,000 篇学术文章,以及定期更新的 JSON 格式的元数据。

这里的 请参考 数据加载 上的内核处理、清理、删除重复,然后将 JSON 中的文本数据加载到 pandas 中。下面是整个语料库的一个片段。

然而,在['text ',' title ',' abstract']下有许多空值,我们的文本越好,我们的嵌入模型就越好,所以我决定将所有文本数据合并到一列中。

以下是数据清理和准备的要点。

现在,我将使用“merged_text”列进行模型训练,该列由每个 paper_id 的文本数据组成。

2.训练 Word2Vec 模型

Word2vec 是一种嵌入技术,与其他高维特征提取技术不同,它依赖于密集的低维特征。它提供的优势是,具有相似含义的单词将以这样一种方式表示,即它们看起来彼此更接近。

有两种类型的 word2vec 技术:

1.连续单词袋(CBOW),2。跳跃图

想了解更多 word2vec 的工作原理,可以参考这个帖子。我们将按照以下步骤训练 word2vec 模型:

2.1 为基于 gensim 的 word2vec 准备数据

让我通过删除停用词和长度少于 3 个字母的单词,为每个文档创建一个标记列表。

然而,这些是单个的记号,把 n 元语法生成为单词更有意义,所以我生成了二元语法。

使用 gensim 的短语,我创建了有意义的二元符号,这些符号是使用上面完成的处理生成的。

2.2 培训模式

现在,当输入数据准备就绪时,我们可以通过定义以下参数来训练 word2vec:

  • min_count:语料库中要包含在模型中的单词的最小出现次数。数字越大,语料库中的单词就越少。
  • window:句子内当前词和预测词之间的最大距离。
  • size:特征向量的维数。
  • workers:我知道我的系统有 4 个内核。
  • model.build_vocab:准备模型词汇。
  • model.train:训练词向量。
  • model.init_sims():当我们不打算进一步训练模型时,我们使用这一行代码来提高模型的内存效率。

2.3 测试模型预测能力

我将创建一个单词列表来测试我们的模型为每个单词预测的前 10 个最接近的单词。

2.4 使用 t-SNE 可视化来可视化在向量空间中映射的单词

我将使用 t-SNE 把高维度的单词模型可视化成二维空间。为了做到这一点,我将使用一个单词样本来看看我们的模型如何将它们映射到空间中。

正如我们上面看到的,我使用了随机单词,然后使用我们训练的 w2v 模型从每个单词中提取了 300 个特征维度,创建了一个矩阵。

现在,使用 t-SNE 将 300 维单词矩阵映射到 2 维空间,我们最终可以将单词可视化,如下所示。

我们可以清楚地看到一组相似或被一起引用的词,如“卫生工作者”和“医生”,或“新冠肺炎”与“发烧”和“中国”。

3.培训 Doc2Vec 模型

因为上面的 word2vec 模型生成单词的数字表示,所以它一起表示语义相关的单词。Doc2vec 是 word2vec 的扩展,它将文档表示成向量空间,而不管其长度如何。

就像 word2vec 一样,doc2vec 也有两种类型:

1]分布式内存(DM),2 .分布式单词包(DBOW)

你可以在这里找到关于它们用法的详细帖子。让我们从首先将文档处理成 gensim 所依赖的格式开始我们的过程。然后,Doc2vec 需要一个单词标记列表和一个带有每个文档的文档 id/名称的标记。

使用上述处理技术准备好输入数据后,我将使用它训练我的 doc2vec 模型。我正在训练 doc2vec 的 DBOW 和 DM 变体,并将它们合并到一个模型中以获得更好的健壮性。然而,我们甚至可以只用一个模型。

模型训练后的最后一步是将每个文档与其生成的特征向量相关联。

4.创建一个与新冠肺炎相关的问题列表

这项工作的全部目标是通过利用嵌入技术的能力有效地回答与新冠肺炎相关的问题,嵌入技术考虑了单词之间的语义关系。因此,我创建了一个需要回答的问题列表,然后使用我们训练的 doc2vec 模型为其提取特征向量,如下所示。

让我创建一个字典,其中包含分配给一个问题的每个任务,以及定义这些问题的最相关的单词,如下所示。

5.使用 word2vec 丰富定义单项问题的关键术语

正如我们在上面看到的,每一个与新冠肺炎有关的问题都与定义它的最相关的词联系在一起。我们将使用这些词来过滤文档,从而缩小我们的搜索空间。然而,上面选择的单词数量太少,所以我决定在我们训练的 word2vec 模型的帮助下,使用类似的单词来增加它们。

使用上面的代码,我将如上所述丰富我的关键字。对于每个单词,我也在我们训练的 word2vec 模型中寻找前 7 个最相似的单词,然后将它们添加到我们的搜索词典中。

6.过滤文档以缩小搜索空间

如果我们回头参考数据加载器,我们的语料库中有超过 7 万个文本文档。这导致我们进入一个大的搜索空间,也增加了遇到模糊结果的可能性。因此,我决定通过排除不包含相关关键字的文档来缩小搜索范围。

这是一个执行文档过滤的示例代码。我选择了两个词:['传播','疾病' '],然后使用 word2vec 搜索了 14 个与列表中每个词相似的词,并创建了一个 28 个词的列表。最后,使用该列表,我将大小为 70k 文档的原始语料库过滤为 50k 文档,然后可以使用这些文档来查找与我们的输入查询相似的文档。

7.使用 doc2vec 模型从用户问题推断特征向量

为了让我们的机器学习模型理解这些问题,我们需要将其翻译成它可以理解的格式。所以我用我们训练好的 doc2vec 模型从中提取特征向量。

提取上述文档向量后生成的数据帧。

8.查找最近的文件

最近邻居是一种基于邻近度的搜索,它的工作假设是相似的事情发生在彼此附近。

人以群分

Sklearn 为我们提供了一个基于无监督球树的最近邻搜索实现,我将使用它来查找与我们的搜索查询最相关的文档。

使用从过滤的文档语料库中生成的文档嵌入,我为一组相关问题训练了基于“球树”的最近邻算法,以找到前 3 个最相关的文档。

我将使用上面的代码来打印我们的“问题”,我们找到了最近的 3 个文档以及它们与问题的距离。

结论

让我总结一下我为实现发现与输入查询最相似的文档这一最终目标而遵循的步骤。

  1. 我首先根据新冠肺炎的研究数据训练了一个 word2vec 和一个 doc2vec 模型。
  2. 然后,我使用了一个问题列表,我正在寻找在上下文中最相似的文档。
  3. 后来,我使用定义这些问题的最相关的单词,通过在训练好的 word2vec 模型的帮助下找到相似的单词,进一步丰富了单词词典。
  4. 使用这些词,我们过滤了语料库的大小,以减少搜索空间。
  5. 最后,我们使用 doc2vec 模型提取特征向量,并训练最近邻算法来寻找最相似的文档。

新冠肺炎研究中有几个开放式的问题和答案,需要支持性的研究文章来验证其可信度。找到这样的文档是一项具有挑战性的任务。在处理不明确的文本数据时,简单的字符串匹配或距离度量等技术是不可靠的。因此,我决定创建一个健壮的基于自然语言处理的架构,其中我们结合了嵌入技术的语言能力,例如上面概述的,并使用它们来进行更好的预测。

使用 Tensorflow 通用语句编码器和 Spark EMR 嵌入数十亿个文本文档

原文:https://towardsdatascience.com/embedding-billions-of-text-documents-using-tensorflow-universal-sentence-encoder-and-spark-emr-422407eecf60?source=collection_archive---------56-----------------------

理解大数据

照片由 Enoc Valenzuela 拍摄(图片来源: Unsplash

Tensorflow HUB 提供了各种预训练模型,可随时用于推理。一个非常强大的模型是(多语言)通用句子编码器,它允许将以任何语言编写的文本嵌入到一个通用的数字向量表示中。

来自 TensorFlow Hub 的通用语句编码器概述

嵌入文本是一种非常强大的自然语言处理(NLP)技术,用于从文本字段中提取特征。这些特征可用于训练其他模型或用于数据分析,例如基于单词语义的聚类文档或搜索引擎。

不幸的是,如果我们有数十亿的文本数据要编码,在一台机器上运行可能需要几天时间。在本教程中,我将展示如何利用 Spark。特别是,我们将使用 AWS 管理的 Elastic MapReduce (EMR)服务将句子编码器应用到大型数据集,并在几个小时内完成。

配置

EMR 集群

在本例中,我们假设一个集群有一个主节点(r4.4xlarge)和 50 个核心节点(r4.2xlarge spot 实例)。该集群总共有 400 个内核和大约 3TB 的理论内存。在实践中,每个执行器的最大内存会被 YARN 限制在 52GB 左右。

如果运行一个包含大量节点的集群是不经济的,那么集群的总内存大小不应该成为瓶颈,因为 Spark 惰性执行模式不需要将整个数据集同时加载到内存中。

为了充分利用 EMR 集群资源,我们可以方便地使用属性“maximizeResourceAllocation”。此外,我们还需要配置 livy,使我们的会话不超时(spark-submit 作业不需要)。

我们可以通过指定以下配置来实现这两个目标:

[{"classification":"spark","properties":{"maximizeResourceAllocation":"true"}},{"classification":"livy-conf","properties":{"livy.server.session.timeout-check":"false"}}]

我还建议选择最近发布的 emr-5。x 并且至少包括以下软件包:Hadoop 2.8.5、Ganglia 3.7.2、Spark 2.4.4、Livy 0.6.0。

为主节点和核心节点添加对外界开放的安全组(如果集群部署在 VPC 中,这将是访问 Spark UI 和 Ganglia 所必需的)。

火花会议

创建一个 EMR 笔记本,并将其连接到之前创建的集群。在创建会话之前,我们需要调整一些内存配置。

由于大部分计算和内存将由 python 进程使用,我们需要改变 JVM 和 python 进程之间的内存平衡:

来自 Apache Spark wiki 的 PySpark 内部消息

指定的执行器内存将只考虑 JVM,而不考虑外部进程所需的内存,在我们的例子中是 TensorFlow。

我们需要调整 spark . yarn . executor . memory overhead,使其大于 spark.executor.memory 的 10%,并分配 spark.python.worker.memory,以避免不必要的磁盘溢出。

在启动 Livy 会话之前,我们将首先配置这些纱线参数,在笔记本单元中运行:

%%configure -f 
{ "conf":{ "spark.pyspark.python": "python3", "spark.pyspark.virtualenv.enabled": "true", "spark.pyspark.virtualenv.type":"native", "spark.pyspark.virtualenv.bin.path":"/usr/bin/virtualenv", "spark.executor.memory": "50g", "spark.yarn.executor.memoryOverhead": "12000", "spark.python.worker.memory": "10g" }}

在 61GB 的可用空间中,我们为 python workers 分配了 10GB,为 JVM 分配了 50GB,其中 12GB 是开销。

在亚马逊 EMR 上成功管理 Apache Spark 应用程序内存的最佳实践中有更多关于配置调优的细节。

现在可以创建一个会话来执行包含 spark 上下文对象的单元:

Livy 信息小部件

依赖性管理

AWS 做得很好,使得在运行时安装库更容易,而不必编写定制的引导动作或 ami。我们可以使用 install_pypi_package API 在主节点和核心节点安装软件包:

for package in ["pandas==0.25", "tensorflow==2.1.0", "tensorflow_text==2.1.1", "tensorflow-hub==0.7.0"]: sc.install_pypi_package(package) sc.list_packages()

它将安装所提供的包,并打印出 python 3.6 虚拟环境中已安装包的列表。

注意:在 Hadoop 3.0 (EMR 6.x)中,应该可以在 Docker 容器中部署 Spark 集群,但是我还没有尝试过。

嵌入作业

我们需要将数据加载为 Spark DataFrame,其中包含一个键列和一个文本列。

嵌入作业在概念上将执行以下操作:

  1. 下载 TensorFlow 多语言通用句子编码器模型
  2. 将数据分区分割成文本文档块
  3. 将每个块嵌入一个 NumPy 矩阵中
  4. 将矩阵转换成 spark.sql.Row 对象列表
muse_columns = [f"muse_{(format(x, '03'))}" for x in range(512)]def get_embedding_batch(batch, model, id_col, text_col, muse_columns):rows = [row for row in batch if row[text_col] is not None and len(row[text_col].split(" ")) >=3]if len(rows) == 0:return []from pyspark.sql import RowEmbeddingRow = Row(id_col, *muse_columns)keys = [x[id_col] for x in rows]text = [x[text_col] for x in rows]embedding_mat = model(text).numpy()return [EmbeddingRow(keys[i], *embedding_mat[i, :].reshape(-1).tolist()) for i in range(len(keys))]def chunks(iterable, n=10):from itertools import chain, isliceiterator = iter(iterable)for first in iterator:yield chain([first], islice(iterator, n - 1))def get_embedding_batch_gen(batch, id_col, text_col, muse_columns=muse_columns,chunk_size=1000):import tensorflow_hub as hubimport tensorflow_textmodel = hub.load("https://tfhub.dev/google/universal-sentence-encoder-multilingual/3")chunk_iter = chunks(batch, n=chunk_size)for chunk in chunk_iter:for row in get_embedding_batch(batch=chunk, model=model, id_col=id_col, text_col=text_col, muse_columns=muse_columns):yield row

几个问题:

  • 模型仅被下载和实例化一次;或者,我们可以使用 Spark 本地广播变量。
  • 为了让模型在运行时工作,我们首先必须在每个执行器中导入 tensorflow_text
  • 我们通过每次仅具体化 1000 行中的一个块,将行对象的可迭代转换为行对象的可迭代。
  • 我们丢弃了少于 3 个标记的句子。
  • numpy float32 型与 Spark DoubleType 不兼容;因此,必须首先将其转换为浮点型。

玩具示例

让我们用一个小的数据样本来试试这段代码:

english_sentences = ["dog", "Puppies are nice.", "I enjoy taking long walks along the beach with my dog."]
italian_sentences = ["cane", "I cuccioli sono carini.", "Mi piace fare lunghe passeggiate lungo la spiaggia con il mio cane."]
japanese_sentences = ["犬", "子犬はいいです", "私は犬と一緒にビーチを散歩するのが好きです"]sentences = english_sentences + italian_sentences + japanese_sentences

现在,我们可以使用 mapPartitions API 批量运行推断,然后将结果转换成包含键列和 512 muse 嵌入列的 Spark 数据帧。

from pyspark.sql.types import StructType
from pyspark.sql.types import StructField
from pyspark.sql.types import StringType, FloatType
from pyspark.sql import Row
from functools import partial
sentences = [Row(id=i, text=sentence) for i, sentence in enumerate(sentences)]sentence_embeddings_rdd = sc.parallelize(sentences).mapPartitions(partial(get_embedding_batch_gen, id_col='id', text_col='text'))schema = StructType([StructField('id', StringType(), False)] + [StructField(col, FloatType(), False) for col in muse_columns])
sentence_embeddings_df = sqlContext.createDataFrame(sentence_embeddings_rdd, schema)

在上面的例子中,我们手动指定模式以避免动态模式推理的减速。

分割

玩具示例应该马上就能工作,因为数据样本非常小。如果我们必须为非常大的数据集进行缩放,我们既不想遇到内存错误,也不想将输出存储在成千上万个小部分中。在映射句子 RDD 之前,我们可能需要调整它们的分区大小(大约几万个分区),并在写入存储层之前将嵌入数据帧合并到一个合理的小范围(几百个分区),并减少输出文件的数量。

请注意,块大小对分区进行切片,以使张量在进行推理时不会太大,但它们不能保证执行器不会将整个分区保存在内存中。

例如,10 亿个文本文档的数据集可以被分成 5k 个分区,每个分区 200k 个文档,这意味着每个分区将包含大约 200 个连续的组块。输出应该保存为 400 个部分的拼花文件。

sentence_embeddings_rdd = large_text_corpus_rdd.repartition(5000).mapPartitions(embedding_generator_function) large_text_corpus_df = sqlContext.createDataFrame(large_text_corpus_rdd, schema) large_text_corpus_df.coalesce(400).write.option("compression", "snappy").parquet(output_path)

就这样,您可以监视 Spark 作业,并最终访问以 parquet 格式划分为 400 个大小几乎相同的部分并用 snappy 压缩的嵌入。

监视

监控 Spark 作业的主要工具是它的 UI 和 Ganglia。

Spark UI

如果我们在 Jupyter 笔记本中执行%info 来获得当前和过去的 Livy 会话列表。从这个小部件中,您还可以获得到 Spark UI 和主主机名的链接(从这里您可以通过http://master _ hostname/Ganglia/)访问 Ganglia)。.)如果集群部署在私有网络中,我们将需要通过代理访问这些服务器。

从 Spark UI 中,我们可以看到如下的计算图:

Spark 作业的 DAG 可视化

Spark 工作的各个阶段

我们可以观察到两个级别的重新分区:阶段 32 在模型推断之前对数据进行重新分区,阶段 33 在写操作之前进行重新分区。

神经中枢

如果您打开 Ganglia UI 并正确完成了所有操作,您应该会看到如下内容:

集群的 Ganglia 概述

如果您遇到内存使用和 CPU 使用之间的严重不平衡,您可能希望将实例类型更改为计算优化程度更高的系列,而不是 r4。

对于每个 80k 文本句子,每个任务的执行时间大约为 20 分钟,并且考虑到 8 个任务将在同一个执行器中并发执行。

结论

这种方法可以适用于用任何规模的任何机器学习库运行模型推理。与 spot 实例一起使用 EMR 将使它变得快速和便宜。为了方便起见,我们使用了 EMR 笔记本,但是您可以将相同的逻辑封装到 spark-submit 作业中,并使用引导操作来安装包。

除了以数据框的形式存储嵌入之外,您还可以扩展用于存储每个分区的原始张量的代码,并将它们加载到 TensorBoard 中,以实现高效的三维可视化。

相反,如果您正在寻找在 Spark 上以分布式模式运行 TensorFlow 的方法,您必须使用不同的架构,如文章在 Spark 上扩展分布式 tensor flow中所述。

请留下您的评论并订阅下一期教程。

原载于 2020 年 5 月 21 日

将“上下文”嵌入配方成分

原文:https://towardsdatascience.com/embedding-contexts-into-recipe-ingredients-709a95841914?source=collection_archive---------50-----------------------

利用食材的上下文向量对菜肴进行分类

图片:Pixabay

看着一系列的配料,我们可以确定这种菜肴来自哪里。

但是,机器也能做到吗?

如果我将配料列表转换成一个简单的单词包矩阵,我会得到一个一次性编码的矩阵,因为每种配料在给定的食谱中只出现一次。使用简单的线性回归,我在yummy recipes 数据集上获得了 78%的分类准确率,甚至没有清理文本。有趣的是,基于树的方法和神经网络也被成功地应用于这项任务,并取得了良好的效果。

我们能使用单词嵌入来改善这些结果吗?

因为 NLP 现在很流行,我想知道单词嵌入向量是否可以用于分类任务?我在硕士项目的一个小组项目中回答了这个问题。

首先,我们清理了成分列表,删除了停用词、符号、数量标记,只保留了名词。它看起来是这样的:

Before cleaning: 
['(2 oz.) tomato sauce', 'ground black pepper', 'garlic', 'scallions', 'chipotles in adobo', 'dried thyme', 'instant white rice', 'cilantro leaves', 'coconut milk', 'water', 'red beans', 'chopped celery', 'skinless chicken thighs', 'onions', 'lime wedges', 'carrots']After cleaning: 
['tomato sauce', 'pepper', 'garlic', 'scallion', 'chipotle adobo', 'thyme', 'rice', 'cilantro leaf', 'coconut milk', 'bean', 'celery', 'skinless chicken thigh', 'onion', 'lime wedge', 'carrot']

接下来,我们使用 Gensim 的 Word2Vec 实现为数据中的每个独特成分获取一个 300 长度的向量。我们通过添加配方成分的向量来形成配方的向量。因此,数据中的每个配方都有一个向量。让我们看看这些向量在使用 tSNE 转换成二维表示时是什么样子:

二维表示的向量

虽然有很多噪音,我们确实看到一些集群。例如,中文、泰文、日文和韩文聚集在左下角。写这篇文章的时候,我发现了一个有趣的事实:摩洛哥菜和印度菜有一些相似之处!从上图的右下部分可以明显看出这一点。

接下来,我们使用这种向量表示法进行分类,这种表示法应该具有食谱的“上下文”。使用简单的线性回归,干净的配方列表和上下文向量表示给出的分类准确度仅为 65%,低于基线 78%。

悲伤,是吧?

我想让我们详细看看一些菜系和它们的顶级食材。

我注意到实际上是法国的食谱被错误地归类为意大利的。我认为这没什么,考虑到阶级不平衡,意大利菜在数据中的出现率最高。然而,一个值得注意的观察是,意大利菜被误传为法国菜最多。考虑到法国菜不在数据中出现率较高的食物之列,这令人惊讶。此外,意大利菜并没有被大量误认为是爱尔兰菜,但是法国菜却被误认为是爱尔兰菜。

因此,我们仔细观察了这三种菜肴的顶级配料。

法国、意大利和爱尔兰菜肴的顶级配料

可以看出,法国菜和意大利菜有两种共同的成分,油和丁香。法国菜和爱尔兰菜也有两种主要成分,奶油和黄油,尽管一小部分黄油也有助于意大利菜。有趣的是,意大利菜和爱尔兰菜除了所有三种菜系共有的配料之外,并没有太多的共同成分,那就是胡椒、洋葱、鸡蛋和其他。这进一步加强了我们的观察,即法国菜与意大利菜和爱尔兰菜有相似之处,然而,意大利菜和爱尔兰菜并不相似。因此,意大利菜和法国菜之间的错误分类是很自然的,因为它们基于食谱中使用的配料而彼此非常相似。

那么,既然分类准确率从 78%降到了 65%,那么嵌词是不是不好呢?

大概吧。

大概不会。

有一些警告。

首先,数据有不平衡的类别。意大利菜和墨西哥菜比其他菜更常见。然而,这肯定也是估计基线时的问题!

可能,更彻底(或者不彻底?)需要清理数据。我们最初的想法是在数据中只保留名词。也许我们也需要保留其他词类。也许副词和连词在数据中保留没有意义,但确实发挥了作用?

也许向量需要更多的调整。用于生成单词向量的超参数可能需要优化。我们将菜谱中的单个单词向量相加,形成菜谱向量。考虑到一份食谱中的配料数量差异很大,也许我们需要对食谱向量进行标准化。

最后,应该注意的是,上面对烹饪组成的解释表明,向量确实成功地将相似的烹饪聚集在一起。我也解释了分类错误的原因。这暗示了单词嵌入对于聚类应用是有益的可能性。而对于分类,还需要做更多的工作。

反正得到差的结果也是好的研究,对吧?

查找代码@:https://github . com/mohanni shant 6/Recipe-Ingredients-as-Word-embedding

在 LinkedIn 上和我联系!

在 GitHub 上看看我的一些有趣的项目吧!

在大公司中嵌入数据科学

原文:https://towardsdatascience.com/embedding-data-science-in-big-companies-c89f23880add?source=collection_archive---------64-----------------------

在初始阶段应该关注什么,避免什么。

肖恩·波洛克通过 Unsplash

介绍

随着大型非科技组织开始投资开发机器学习和数据分析能力,未能达到管理层的期望和数据科学家的沮丧正变得司空见惯。

数据科学家和数据工程师是科技行业薪酬最高的专业人士之一。他们通常在数学、统计学和计算机科学方面有很强的背景。他们非常积极:大多数人是通过自学进入该领域的,因为“数据科学”领域没有多少大学学位,他们投入大量时间来跟上该领域的最新发展。

然而,对于大公司来说,将这些功能集成到旧的遗留系统中正在成为一个巨大的挑战。对高质量数据的有限访问、数据科学家和业务利益相关者之间缺乏理解以及技术差距是造成这一挑战的主要原因。

我已经在供应链行业做了几年的数据科学家。在做了多年的顾问后,我加入了一家国际零售公司的全新团队,开始在供应链的不同领域应用机器学习和数据分析,最终目标是降低成本和改善服务。

在这篇文章中,我总结了这些年来我学到的一些经验。这些经验并不是特定于业务的,尽管它们更适用于不存在数据文化或处于早期阶段的大组织,并且像机器学习这样的概念对许多人来说仍然是陌生的。

1.提高团队的意识

你的商业利益相关者需要了解你做什么,以及你如何在他们的日常斗争中帮助他们。他们不需要知道什么是逻辑回归或随机森林,但是他们需要理解底层的概念和限制,例如,部署一个模型来自动化某个任务。

这是开始时非常重要的一步。与您的利益相关者召开研讨会,确保您的数据科学家了解业务问题,并且您的利益相关者了解您所能提供的潜力和限制。

如果你是这家公司的新人,利用创业阶段来确定可以帮助你建立信誉的速赢,并建立一个盟友网络,这些盟友将支持你的工作。如果你在你的团队中缺少某些能力,确保与那些能帮助你的人联系。在 It 部门之外创建数据科学团队以使他们更接近业务是非常常见的。与 IT 团队联系并获得他们的支持,没有他们你不会走得太远。

2.(有时)少即是多

发现规划过程中的一个缺陷可以节省数百万美元。你不需要部署神经网络来开始带来价值。纯数据分析在发现非最佳流程、了解客户行为、检测欺诈或改善激励方面已经非常强大。

提出可行的见解可能会让你的团队免于经历一个部署过程,而他们在开始时可能没有准备好,同时为公司增加巨大的价值。

历史操作和计划数据是很好的起点。深入其中,你一定会找到改善运营的方法,让计划更接近现实。

3.自动化作为起点

一般来说,机器学习可以应用于(I)自动化现有任务或(ii)执行新任务。一开始,关注自动化有几个好处。业务流程已经存在并且广为人知,这限制了不确定性和风险的空间。此外,可以更准确地估计收益:节省时间、提高质量等。

在这些项目中,挑战通常在于你被要求交付的准确性。如果你正在自动化一个已经存在的过程,人们可能期望 100%的准确性。以下是一些原因:如果你正在自动化的过程没有被监控,没有基线来比较你的结果,你可能会被要求交付一个完美的过程,因为到目前为止,它最有可能被视为一个完美的手工过程。让您的模型标记不确定的情况以便手动修改,尽管这是一个明智的想法,但可能会伤害对模型的信任,并质疑自动化的好处。为了克服这个挑战并且不危及你的信誉,在你的估计中要保守,但是要清楚自动化的好处。

总是在谈论自动化的时候,小心你如何呈现项目。有些人可能会担心你试图用“机器人”来取代他们,并且不愿意合作。

总的来说,试着从已经测量了当前性能的自动化任务开始,这样你就有了一个清晰的基线。从与将自动化视为机遇而非威胁的团队合作开始。

4.不要滥用仪表板

仪表盘很棒。它们可以提供非常丰富的信息,有助于监控业务运营或支持决策制定。此外,它们易于开发和共享。

然而,经常发生的是,数据科学团队是大公司中少数拥有广泛和自由访问数据的特权的团队之一。这很容易导致团队被视为公司数据的入口点。人们希望以一种易于理解的方式消费数据,很快团队就被开发和共享仪表板的请求淹没了,或者仅仅是进行数据提取。

虽然仪表板通常受到企业的青睐,但过于关注简单的报告可能会耗尽数据科学家的动力,因为他们通常会面临不同的挑战。除此之外,组织中肯定有人有足够的技能来开发可视化解决方案,只是他们没有访问数据的权限。尝试保持平衡,明智地使用仪表盘来报告你的结果,或分享相关的见解,但避免被视为公司数据仓库的友好连接器。

5.创建数据文化

努力使数据可用,并围绕数据创造一种文化。为数据质量、元数据和文档而战。一个数据有记录、可追踪、可访问的组织能够更加敏捷地发现和诊断问题,找到解决方案,并在数字世界中茁壮成长。此外,数据科学项目的启动成本也将大幅降低。

推进开放和记录数据仓库的计划,并与数据所有者建立联盟,以便他们能够支持您的项目。让管理层相信数据可用性在支持决策方面的价值**。首席执行官的承诺对于创建数据文化至关重要。如果董事会和首席执行官接受了你处于有利地位的观点,如果他们还没有接受,试着把你的信息一直传递下去。**

促进大众对数据的需求,而不是自上而下的强加,这将有助于数据的民主化和建立热情。最后,帮助培养和提高有效处理数据所需的技能。对这一领域人才的搜索是不懈的,但幸运的是,你不需要一大群数据科学家来建立一个数据驱动的公司。使用那些你已经拥有的来提升你当前的劳动力。

我希望上述原则能够帮助您将数据科学有效地引入您的组织。

[1] Alejandro Díaz、Kayvaun Rowshankish 和 Tamim Saleh,为什么数据文化很重要? (2018)麦肯锡季刊

知识图补全的嵌入模型

原文:https://towardsdatascience.com/embedding-models-for-knowledge-graph-completion-a66d4c01d588?source=collection_archive---------31-----------------------

TransE、TransH、TransR、CTransR 车型简介

知识图 (KG)在不同的学习领域有几种定义。在本文中,我们将 KG 定义为一个图,其中每个节点是一个实体空间 E 的元素,每个边是一个关系空间 R 的元素。E 和 R 的详细定义是特定于领域的:例如,在社交网络中,E 是一组人,R 是一组不同类型的关系(亲戚、朋友、伙伴、陌生人)。一般来说,E 和 R 可以分别包含每一个存在的实体(或概念、事件、情形等)。)和先前实体之间的每种类型的关系。此外,每个实体可以具有可变数量的属性或特性。鉴于 KG 的通用定义,它经常被用作知识库 (KB)或本体的同义词。本体论这个术语有许多哲学和技术上的概念化和含义,在这个讨论中没有分析,事实上:上面给出的 KG 的定义只是为下面的段落做准备的简化。

KG 可应用于不同兴趣领域(学术和工业)的广泛任务:

  • 识别一个单词在句子中使用的是哪个词义(词义消歧);
  • 自动回答用自然语言提出的问题(QA);
  • 用有意义而不仅仅是词汇匹配来搜索信息(语义搜索);
  • 检测和分类实体之间的语义关系(关系提取);
  • 预测用户的偏好(推荐系统)。

近年来,学术界和商业界都开发了大量的知识图谱:WordNet、DBpedia、Freebase、YAGO、Wikidata、Google Knowledge Graph、Facebook Graph Search 等。尽管有非常大量的实体,这些图仍然有许多缺失或错误的边,因此,知识图完成 (KGC)是一个活跃的研究领域。

图片作者。KGC 的一个例子:基于实体之间已知的关系(实线),KGC 算法应该推断未知的关系(虚线)。

上面给出的 KG 的定义允许我们用三元组元素 (h,R,t) ∈ E × R × E 指定 KG 的边,其中头( h )和尾( t )实体是 Er 的元素,它们是有向的,是一种关系类型 R 。注意顺序很重要,因为不是每个关系都是双向的。形式上,我们将 KGC 定义为试图预测三元组 (h,r,t) 中任何缺失元素的任务。特别是,我们谈论:

  • 实体预测当 h 或 t 之间的某个元素缺失时((?,r,t)(h,r,?));
  • 关系预测当 r 缺失 (h,?,t)
  • 三元组分类当一个算法识别出给定的三元组 (h,r,t) 是否正确时。

从技术上来说,KGC 非常类似于社交网络分析中的链接预测:两者都试图完成一个不完整的网络。此外,KGC 面临挑战的原因如下:

  • 造一个 KG 不是小事;
  • 每个实体可以有可变数量的属性(非唯一规范);
  • R 可以包含不同类型的关系(多层网络);
  • 一公斤随时间变化(随时间进化)。

为了解决 KGC 问题,过去几年中开发了不同的方法:例如,实体解析(er),概率软逻辑(PSL)和知识图嵌入(KGE)。第一种方法试图对涉及相同底层实体的实体进行分组,而第二种方法使用概率推理。尽管它们是非常有趣的话题,但在本文中我们只关注 KGE。

嵌入背后的思想在数学中被广泛使用:如果我们需要研究未知空间的元素的性质,我们找到一个函数,通过保留一些关系将未知空间的每个元素映射到已知空间。

在 KGE 模型中,我们假设存在两个函数 f_Ef_R 和两个自然数 kl 使得 f_E : E → ℝ^kf_R : R → ℝ^l 是将实体和关系映射到ℝk 或ℝl.的嵌入函数。我们将详细描述 f_Ef 的构造设(v_h,v_r,v_t) k × ℝl × ℝk 为 (f_E(h),f_R(r),f_E(t)) 的像。在嵌入空间ℝk × ℝl × ℝk 上,定义了一个得分函数fs:ℝk×ℝl×ℝ^k→ℝ来度量三元组 (h,r,t) 的不可置信性。因此,给定一个正确的三联体 (h,r,t) 和一个不真实的三联体 (h ',r ',t') ,应该发生 f_s(v_h,v_h,v_t) < f_s(v_{h'},v_{r'},v_{t'}) 。为了简化符号,我们直接用 f(h,R,t) 表示组成 f_s(f_E(h),f_R(r),f_E(t)) 。在现实世界中,我们可以定义先验的 k,l,f_s 而不能定义 f_Ef_R 。它们通过一些优化算法(例如:随机梯度下降、L-BFGS、自适应次梯度和自适应学习率方法)来估计,这些算法最小化使用 f 定义的损失函数:

其中γ是边缘超参数, P 是正确三元组的集合,并且

不可信或手动损坏的三元组集。至此,我们可以确定 f_Ef_R

在上面解释的 KGC 背景下,研究人员提出了许多嵌入模型。例如,在trans model(2013)中,嵌入的实体和关系应该共存于同一空间中(即 k = l ),得分函数定义为

这意味着给定一个相干三元组 (h,r,t)v_t 应该是 v_h + v_r 的最近邻。最后一种暗示不适用于 1-NN-1N-N 的关系。为此,2014 年提出了 TransH 车型。与前面的模型一样,嵌入的实体和关系仍然共存于同一空间中,但得分函数的定义不同:

其中 v_{h\perp}v_{t\perp} 分别是 v_hv_t 在包含 v_r 的超平面上的投影。因此,给定 w_rv_r 的超平面的法向量,使得 ||w_r||_2 = 1 ,得分函数可以写成

利用投影,可以对每个实体在不同关系中扮演的不同角色进行建模,从而克服跨模型的问题。在 2015 年出版的 TransR 模型CTransR 模型中包含了进一步的概括,其中嵌入的实体和关系不再是同一空间的元素:实际上,对于每个关系 r∈ R ,都存在一个投影矩阵 M_r ,使得嵌入的实体被投影到其特定的关系空间中。因此,TransR 的得分函数定义为

该得分函数在 CTransR 中略有不同,在 CTransR 中,通过使用分段线性回归的思想对同一关系的不同方面进行建模。为了这个介绍的完整性,我们只提一些其他的 KGE 模型而不讨论(虽然,列表还远不完整):结构化嵌入,神经张量网络,语义匹配能量模型,潜在因子模型,TransD。

参考文献:

  • 海科·保罗海姆。知识图精化:方法和评估方法综述。语义网,8(3):489–508,2017。
  • 王全、毛振东、王斌和李果。知识图嵌入:方法和应用综述。 IEEE 知识与数据工程汇刊,29(12):2724–2743,2017。
  • 安托万·博德斯、杰森·韦斯顿和尼古拉斯·乌苏尼尔。弱监督嵌入模型的开放问题回答。在关于数据库中的机器学习和知识发现的欧洲联合会议中,第 165-180 页。斯普林格,2014。
  • 安托万·博德斯,苏米特·乔普拉和杰森·韦斯顿。带有子图嵌入的问题回答。载于2014 年自然语言处理经验方法会议论文集,第 615–620 页,2014 年。
  • Antoine Bordes、Nicolas Usunier、Alberto Garcia-Duran、Jason Weston 和 Oksana Yakhnenko。翻译用于多关系数据建模的嵌入。在神经信息处理系统进展,2787–2795 页,2013 年。
  • 王震、张建文、封建林和陈政。基于超平面平移的知识图嵌入。2014 年第二十八届 AAAI 人工智能大会
  • 林、、孙茂松、、。用于知识图完成的学习实体和关系嵌入。在2015 年第二十九届 AAAI 人工智能大会

联系人:LinkedIn|Twitter

探索贝叶斯 A/B 测试测量作为 P 值的替代

原文:https://towardsdatascience.com/embracing-bayesian-a-b-test-measurement-and-ditching-p-values-9e444df379ca?source=collection_archive---------21-----------------------

用 Rstan 将贝叶斯推理应用于 A/B 测试

威廉·艾文在 Unsplash 上的照片

(这是关于 A/B 测试的两部分系列的第二部分。第 1 部分介绍了在设计新测试时权衡所有选项的过程,可以在这里找到**。这篇文章选取了测试测量阶段的例子,展示了在 R.)* 中使用贝叶斯分析的方法*

测量值几百万

如果你像我一样,你的收件箱每天都被电子邮件淹没。许多是与工作有关的,一些是来自朋友和家人的(包括来自奶奶的不健康的转发),很多(可能太多了)是来自竞争你业务的公司的营销电子邮件。

它们可能看起来很讨厌,但是说实话,每隔一段时间,我们的兴趣就会被激起,我们就会打开一个。有时我们甚至会去公司的网站买些东西。这个神奇的时刻被公司捕捉到,并算作一次转化*,我们花的钱归于邮件活动。*

转换率因行业和内容类型而异,但通常相当低,不到 5%。这可能看起来不多,但是如果你给一个完整的订阅者列表发送一封电子邮件,即使 1%的转换率也能产生可观的投资回报。假设你是一家在线零售商,你向去年购买男装的 100 万名顾客发送了一封电子邮件。如果他们中只有 1%的人平均花费 50 美元进行转化,你就把 500,000 美元的收入归因于一个电子邮件活动!

为什么是贝叶斯?

作为《走向数据科学》的读者,你可能熟悉贝叶斯分析的概念。贝叶斯定理旨在利用一个事件的信息来理解另一个事件。不严格地说,拥抱贝叶斯就是拥抱概率。应用贝叶斯推理进行 A/B 测试测量意味着我们将确定 A 与 B 不同的概率**

来源: Pranav Prathvikumar

一段时间以来,统计学习的频率主义者和贝叶斯方法之间一直存在争论(有时激烈,通常是务实的)。剧透:在一天结束时,你的数据有一个故事要告诉,你可以通过几种不同的方式得出相同的结论。本文关注贝叶斯方法,强调与频率主义方法相比的一些不同之处。最终,我发现贝叶斯推理的某些方面在实践中很有价值。也就是说,贝叶斯推理提供了:

  1. 变异不同的概率,使得对结果的解释更容易理解
  2. 量化变量间差异的大小的便捷方法
  3. 一种计算每个变量的总期望值并可视化方差的直观方法

在本文中,我们将使用传统的频率主义方法和贝叶斯方法来衡量 A/B 测试结果,并以 A 对 B 的预期收入差异结束。 我们将展示这两种方法会导致类似的结果,并阐述贝叶斯技术的细微差别以及由此产生的解释

设置

让我们来布置舞台。我们的业务合作伙伴设计并执行了一项新的电子邮件营销活动,测试两种不同类型的电子邮件内容,重点是男士西装。在 4000 名测试客户中,2000 名客户收到了一封电子邮件,宣传一个崭露头角的设计师的新系列礼服衬衫,而另外 2000 名客户收到了一封电子邮件,宣传一个内部品牌的类似系列礼服衬衫。我们将后起之秀的设计师邮件称为设计师,内部邮件称为内部

测试结果:转换和花费汇总

邮件发出已经 7 天了,我们有了结果。88 名收到设计师内容的客户进行了购买,平均花费 168.34 美元,而 72 名收到内部内容的客户进行了购买,平均花费 152.88 美元(我们收到了 3 名客户的回复)。

设计师看起来是明显的赢家,对吗?也许是这样,但作为优秀的数据科学家,我们必须确保这种差异在统计上是显著的,而不仅仅是我们数据中随机性的结果。

频繁主义方法

我们将从传统的测量方法开始。这可以通过比较两个样本的均值和方差的 t 检验来完成,或者通过拟合回归模型和调查独立变量系数来完成。我在这里使用回归方法,因为我喜欢灵活地添加额外的变量来控制(例如,发送电子邮件的日期、客户位置等),这有助于与贝叶斯方法进行更好的比较,贝叶斯方法也使用回归。

我们首先单独研究转换率,将一个逻辑回归模型与我们的数据进行拟合,以观察组(我们的预测值)是否与转换率(我们的结果)有统计学上的显著关系。我们的无效假设是分组和转换之间没有关系,我们将使用 0.05 的标准 P 值阈值来确认或拒绝该假设。

P >= 0.05 →无法拒绝 null(我们无法推断转换和组之间的关系)

P < 0.05 → Reject the null (we conclude a relationship does exist between Group and Conversion)

First, we fit a logistic regression on the data to model conversion rates.

*Call:
glm(formula = conversion ~ group, family = binomial(), data = combined)Deviance Residuals: Min       1Q   Median       3Q      Max  
-0.3001  -0.3001  -0.2709  -0.2709   2.5781Coefficients:Estimate Std. Error z value Pr(>|z|)    
(Intercept)    -3.0780     0.1090 -28.232   <2e-16 ***
groupIn-House  -0.2085     0.1622  -1.286    0.199    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1(Dispersion parameter for binomial family taken to be 1)Null deviance: 1343.3  on 3996  degrees of freedom
Residual deviance: 1341.6  on 3995  degrees of freedom
AIC: 1345.6Number of Fisher Scoring iterations: 6*

注意,预测值是“ 集团内部 ”,这只是意味着回归将我们的二元预测值(集团)变成了虚拟变量,该变量将内部内容的值设为 1,将设计师内容的值设为 0。

我们的结果总结显示,在两个模型中,我们的预测因子的估计系数都是负的,这表明接收内部内容的客户比接收设计师内容的客户具有更低的转化率。然而,系数的 p 值为 0.199 高于我们的 0.05 阈值,这意味着我们未能拒绝我们的零假设,因此无法得出电子邮件内容对转化率有影响的结论。事实上,p 值是概率的一种度量。这意味着,在变量之间没有差异的零假设条件下,我们期望在 X%的时间里看到我们的数据。在这种情况下,如果真的没有差别,我们的数据在 20%的情况下会自然出现。虽然不是绝对的,但它确实表明可能存在一些潜在的差异。

然而,我们真正想测试的是对收入的总体影响,这意味着我们需要比较支出。我们将拟合一个关于花费的线性回归模型。

*Call:
glm(formula = conv_spend ~ group, data = combined)Deviance Residuals: Min       1Q   Median       3Q      Max  -7.411   -7.411   -5.509   -5.509  310.729Coefficients:Estimate Std. Error t value Pr(>|t|)    
(Intercept)     7.4106     0.7669   9.663   <2e-16 ***
groupIn-House  -1.9014     1.0847  -1.753   0.0797 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1(Dispersion parameter for gaussian family taken to be 1175.631)Null deviance: 4700258  on 3996  degrees of freedom
Residual deviance: 4696645  on 3995  degrees of freedom
AIC: 39604Number of Fisher Scoring iterations: 2*

p 值为 0.0797,数据告诉我们,如果没有关系,我们只有 8%的机会看到我们的支出数据。我应该注意,我们看到的 p 值假设我们想要一个双尾检验。由于最初的数据汇总表明设计师将胜过内部人员,我们可以通过将 p 值除以 2 来重新解释单尾测试的 p 值。这将进一步降低 8%至 4%。一点也不差,显然有些不同。

查看我们的独立“内部分组”变量的系数,我们看到-1.90,表明平均而言,**内部内容导致每次发送的收入比设计师**少 1.90 美元。

那么我们学到了什么?如果我们的变量没有差异,我们的数据将只出现 8%的时间(如果我们使用不太保守的单尾测试,则为 4%),因此,我们非常有信心在我们的两个变量之间存在差异。此外,由于向大约 100 万客户发送的每封电子邮件收费 1.90 美元,我们可能会获得 190 万美元的额外收入!如果没有真正的分析我们的结果,我们不想错过这样的机会。**

输入贝叶斯

从频率主义者转向贝叶斯方法意味着从概率的角度考虑我们的数据。我们不是对群体和转化之间关系的假设给出“是”或“否”的答案,而是通过生成一个群体的结果始终不同于另一个群体的概率来进行测试。

简而言之,贝叶斯回归使用传统的基本回归公式,但不是返回输入系数β i 的点估计,而是生成截距、输入系数和误差项的分布。

这就是所谓的后验分布**,它是利用数据的先验知识(“先验”)结合观测结果生成的。(如果你想更好地理解贝叶斯逻辑回归背后的理论,请查看威尔·库尔特的这篇精彩概述或这篇 rstanarm 教程)**

我们将使用斯坦概述的贝叶斯分析的四个步骤来更好地理解我们的结果:

贝叶斯分析的四个步骤:

1.为结果和所有未知量指定联合分布,通常采用未知量的边际先验分布乘以以未知量为条件的结果的可能性的形式。这种联合分布与以观测数据为条件的未知量的后验分布成比例

2.使用马尔可夫链蒙特卡罗(MCMC)从后验分布中提取。

3.评估模型与数据的吻合程度,并可能修改模型。

4.从给定预测值的结果的后验预测分布中提取,以便可视化预测值的操作如何影响结果(的函数)。

我们将使用Rstan***—R 接口对 Stan —指定我们的后验分布,使用 MCMC 抽取样本,并评估模型拟合度。具体来说,我们使用 rstanarm 包。*

汇率

首先,我们有什么前科?让我们假设我们在一个新成立的团队中,这个团队之前对测试结果一无所知。这意味着我们事先不知道我们的转换率或花费应该是多少。默认情况下,Rstanarm 通过使用弱信息先验很好地处理了这个问题。截距和输入系数的默认先验假设为正态分布,并且 Rstanarm 根据数据调整标度。关于先验及其实现的更多细节可以在 rstanarm 简介 中找到。我们稍后将查看 rstanarm 如何调整(或没有调整)默认的优先级。

接下来,我们需要在建模阶段指定一些关键细节。由于我们的结果是一个转换率(0 或 1),我们将使用二项式分布logit 链接函数。我们将设置链= 4 ,这样我们可以运行 4 个不同的马尔可夫链,并确保得到的样本都收敛于相同的参数估计。然后我们将迭代的次数设置为 4000,预热为 2000。这意味着每个链有 2,000 次迭代来训练和调整先验(如果需要的话),对于 4 个链,我们最终从后验样本中提取了健康的 8,000 个记录样本。

**Model Info:function:     stan_glmfamily:       binomial [logit]formula:      cbind(conversions, customers - conversions) ~ groupalgorithm:    samplingsample:       8000 (posterior sample size)priors:       see help('prior_summary')observations: 2predictors:   2Estimates:mean   sd     10%    50%    90% 
(Intercept)   -3.083  0.112 -3.227 -3.081 -2.939
groupIn-House -0.212  0.165 -0.425 -0.215  0.004Fit Diagnostics:mean   sd     10%    50%    90% 
mean_PPD 80.078  8.845 69.000 80.000 91.500The mean_ppd is the sample average posterior predictive distribution of the outcome variable (for details see help('summary.stanreg')).MCMC diagnosticsmcse  Rhat  n_eff
(Intercept)   0.002 1.001 5242 
groupIn-House 0.002 1.000 4850 
mean_PPD      0.110 1.001 6448 
log-posterior 0.018 1.001 3174**

显示参数分布收敛的转换轨迹图

快速检查汇总统计数据看起来不错。 Rhat 对于所有参数都非常接近 1,表明模型成功地收敛于每个参数的后验分布。我们还看到每个参数的有效样本量相对较高,远远超过样本量(8000)的 10%。此外,查看轨迹图,我们看到 4 条链中的每一条都收敛于截距和群系数的相同参数估计值附近。请注意,弱信息默认先验没有改变。

训练我们的模型的输出是从后验分布中采样的一组 8,000 个值。我们有单个预测组的截距和系数的样本。就像之前一样,模型已经把我们的预测器变成了 _House_Flag_conv 中的虚拟变量

从转换后验中抽取的参数样本

因为我们的预测器是一个虚拟变量,其中内部= 1,设计师= 0,所以我们可以通过查看预测器In _ House _ Flag _ conv的采样系数来比较设计师内容和内部内容(上面的右栏)。

该系数的负值表示内部转换率低于设计者,正值表示相反。设计师优于内部设计师的概率就是在In _ House _ Flag _ conv<0的抽奖比例。

我们看到在 _House_Flag_conv 中的 在 90%的时间里是负的,因此设计者内容产生比 B 更高的转化率的概率是 90%。换句话说,如果我们运行这个测试 100 次, ,我们将会期望在 100 次 中有 90 次来自设计者内容的更多转换。

对于视觉型学习者来说,画出后验分布图来看看两组之间到底有多大的不同可能会有所帮助。

设计师与内部内容的样本分布

从营销的角度来看,设计师内容是一个非常明显的赢家。制作和发送带有内容的电子邮件在成本上没有本质的区别,所以选择设计师而不是内部设计师的决定似乎是显而易见的。但是转化率只有图片的一半…

支出因素

因为我们做生意是为了赚钱,所以我们也想知道客户在转换时实际花了多少钱。不同的电子邮件内容可能会激发不同的购买行为,当我们向利益相关方展示我们活动的 总期望值 时,我们需要将这些因素考虑在内。

我们将使用与上面相同的序列,拟合模型(指定我们的后验分布),使用 MCMC 绘制样本,并评估模型拟合。这里唯一真正的调整是将我们的响应变量切换为花费*,将分布族切换为高斯,以适应我们的连续正态分布响应变量。*

*Model Info:function:     stan_glmfamily:       gaussian [identity]formula:      spend ~ groupalgorithm:    samplingsample:       8000 (posterior sample size)priors:       see help('prior_summary')observations: 160predictors:   2Estimates:mean    sd      10%     50%     90%  
(Intercept)   168.247   7.164 159.226 168.246 177.389
groupIn-House -15.293  10.803 -28.854 -15.401  -1.619
sigma          66.475   3.703  61.896  66.257  71.329Fit Diagnostics:mean    sd      10%     50%     90%  
mean_PPD 161.380   7.369 151.918 161.464 170.604The mean_ppd is the sample average posterior predictive distribution of the outcome variable (for details see help('summary.stanreg')).MCMC diagnosticsmcse  Rhat  n_eff
(Intercept)   0.080 1.000 8004 
groupIn-House 0.122 1.000 7843 
sigma         0.042 1.000 7861 
mean_PPD      0.083 1.000 7953 
log-posterior 0.022 1.000 3378*

显示参数分布收敛的轨迹图

汇总数据看起来也不错。 Rhat = 1 对于所有参数,每个参数的有效样本量都很高,轨迹图显示所有链都收敛于截距、组系数和 sigma 误差项的相同参数估计值。

使用与之前相同的流程,我们将使用我们的虚拟变量比较设计师和内部人员,这次命名为In _ House _ Flag _ spend*。我们在我们的 8000 个样本中取In _ House _ Flag _ spend<0的比例,得到设计师胜过内部设计师的概率。*

果不其然,在 92%的情况下,收到设计师作品的顾客比收到内部作品的顾客花费更多。现在让我们看看这转化成了多少美元。

因此,当我们的设计师客户通过电子邮件购物时,他们比内部客户平均多花了 15.55 美元。现在我们有两个强有力的证据表明,设计师内容推动了更高的转化率,并在转化时花费更多。现在让我们将两个信号结合起来,看看两者之间的总值有何不同。**

结合转化和花费

我们可以通过组合来自我们的转换和支出后验分布的随机样本来计算总值。一项活动的总价值由转化的顾客百分比乘以他们的消费总额得出。因此,使用我们的后验样本,我们简单地将转换系数乘以每组的花费系数,然后进行比较。

我们先来看看设计师客户的总价值大于内部客户的总价值的概率。在 R 中,它看起来像这样:

我们有 96%的可能性认为设计师的总价值高于内部人员的总价值。这是一个非常强烈的迹象,表明设计师的内容对企业来说确实更有价值。

现在我们有一个非常强的概率,问题是收入的预期差异是多少?我们可以合并转换和花费样本,并计算两组之间总价值的平均差异。这将告诉我们 我们发送电子邮件给 的每一位客户,我们可以期望获得多少额外收入。

根据我们的组合后验分布,我们计算出 b 组的总价值为 1.89 美元。这意味着,平均而言, 我们预计使用设计师内容与使用内部内容 相比,每次发送的收入将增加 1.89 美元。考虑到我们可以在一年内将它推广到 100 万用户,这还不错!

最后,我们可以使用 ggplot 可视化这些分布。

请注意,设计师的平均值略低于 7.5,内部人员的平均值约为 5.5,正好在 1.89 左右。

结论

在本文中,我们对 A/B 测试度量的频率分析和贝叶斯分析进行了比较。总的来说,频率主义者和贝叶斯方法给我们带来了大致相同的结论,只是解释略有不同。

  • Frequentist 方法(支出的线性回归)得出的 p 值为 0.0787(或使用单尾检验得出的 p 值为 0.0394),系数相当于设计师的 1.90 美元优势。
  • 贝叶斯方法(结合转换率和支出后验分布)表明,设计师在 96%的情况下导致(平均)多 1.89 美元的收入。

分析结果表明,运行设计师的内容比运行内部内容有明显的优势,最终每发送一封电子邮件可带来1.89 美元的额外收入。我们有 100 万合格的电子邮件订户,通过选择正确的内容,这相当于189 万美元的额外年收入。**

注: 我修改了原来的文章,以反映频率主义者和贝叶斯方法之间的比较。一位读者指出,在许多 A/B 测试场景中,从均值的单尾 t 测试中得出的 p 值相当于贝叶斯推断的 A 大于 B 的概率。这一更新版本表明,两种方法得出的数值结果大致相同,并且对这些结果有大致的信心。

密码

你可以从我的 GitHub 下载完整代码

感谢 柯特·博格曼 向我介绍了这项技术,并在我学习的过程中提供了指导。

从简单到复杂:通向人工一般智能的可能途径

原文:https://towardsdatascience.com/emergence-how-artificial-general-intelligence-can-be-computationally-modeled-b5fea4797028?source=collection_archive---------43-----------------------

来源:山姆·敏,麦吉尔·论坛报

观点:在接近人工一般智能中细胞自动机样机制的一个论点(AGI)

“如果我们要制造一台会说话、理解或翻译人类语言、用想象力解决数学问题、从事一种职业或指导一个组织的机器,要么我们必须将这些活动简化为一门精确到我们可以精确地告诉机器如何去做的科学,要么我们必须开发一台可以做事情而不需要被精确地告知如何做的机器”——理查德·m·弗里德伯格,1958

如果人工智能(AI)是一个有待解决的问题,那么人工通用智能(AGI)是目前令人垂涎的奖品。AGI 指的是机器能够理解和学习人类(以人类为中心)任务的假设智能。然而,与正常问题不同,我们似乎很难理解 AGI 系统是什么样子,直到最近才开始寻找系统评估 AGI 系统的方法[8]。

也就是说,很明显,三种基本的机器学习范式:监督学习(如神经网络、SVM、回归等。)、无监督学习(例如聚类、降维等。)和强化学习,虽然在明确定义的任务中非常有用,如计算机视觉[9]、自然语言处理[10]或甚至在国际象棋和 Shogi 游戏中与人竞争[11],但未能推广到其他领域。有人可能会说,这些范式的巨大成功是其假设或其归纳偏差的副产品,例如,假设数据是线性的线性模型[12]。这些偏见抑制了组合归纳或者人类在无限可能的场景中进行推断、推理和行动的能力。例如,如果你让一个经过训练来检测人脸的神经网络来检测隐藏在滑雪面具后面的人脸,该模型可能不会比随机猜测更好,尽管人类可以很快推断出面具下面有一张脸。

在设计 AGI 系统时,我们需要考虑这样的系统,它既不了解手头的任务,也无法访问可用于通过“不智能的”变通方法“击败”任务指标的训练数据。相反,必须评估一个 AGI 系统有效获取新技能的能力,以解决不止一个而是多个任务,这些任务分布在不同的领域,涉及人类中心的先验知识、习得的经验和相对推广难度 [12]。因此,可以对这样一个系统做出一些基本的假设,这些假设是这篇文章的中心论点,这篇文章号召人们重振对类似细胞自动机的机器的研究,以开发一个 AGI 系统。

AGI 系统的假设

  1. 进化假设:系统必须能够以一种依赖于时间和空间的方式进化,以便它能够解决日益复杂的任务,例如,开发像工作记忆这样的结构——从而将初始系统、环境和进化规则的设计优先于最终的可交付成果。这与传统统计模型的目标相反,传统统计模型的目标是在特定的、明确定义的任务中开发“专家”模型。
  2. *一般化假设:*系统必须能够进行广泛的一般化(即组合一般化),使得先前的经验是获得新学习技能的基础,而不是特定技能本身[12]
  3. *学习假设:*系统必须针对各种任务的灵活性和效率进行优化,而不是针对特定任务的有限指标集(均方误差、交叉熵等)[8]。例如,获取新技能的效率可能是一个潜在的优化问题。
  4. *以人类为中心(核心知识)的假设:*系统必须能够编码以人类为中心的先验知识,即人类预定义要理解的东西,如物体的领域和数字的领域(人类强烈地认为世界是由物体组成的,并自然地倾向于分层表示,并对自然数有基本的理解)[13]。

这 4 个假设当然不是详尽的,但是可以作为一个很好的起点,告诉你哪里可以看,哪里不可以看。例如,许多计算框架可以很容易地结合人类中心假设所需的已知先验知识(例如贝叶斯网络或隐马尔可夫模型);然而,很少有模型具有组合泛化的潜力(例如图网络[12]),甚至更少的系统能够执行依赖于时间的进化来处理日益复杂的任务(例如非图网络)。

除了我们的假设之外,AGI 系统还需要几个有用的性质。首先,我们希望 AGI 系统简单一些。第二,从这种简单性中产生出我们的系统可以从中受益的突现性质,并且我们可以用它来评估系统,这将是合乎需要的。例如,众所周知,人类在视觉上同时注意串行和并行的对象(例如,读一个句子对读一个单词)[14]。虽然 AGI 系统的系统设计者可能能够直接将串行和并行处理编码到这样的 AGI 系统中,但下面 Alan Newell 的引用警告说,试图通过实验来分割人类认知可能不仅很困难,而且实际上很难,因为人类对受控实验的反应可能不会揭示关于认知的潜在机制的有用信息,而是人类主体本身[15]。

“科学通过向自然提出二十个问题而进步。正确的策略是提出一个一般性的问题,希望是双元的,可以通过实验来解决。解决了这个问题后,我们可以进入下一个问题。这一政策看起来是最佳的——人们从不冒太大风险,每一步都有大自然的反馈,进步是不可避免的。不幸的是,这些问题似乎从来没有得到真正的回答,这种策略似乎行不通。”—艾伦·纽维尔(Alan Newell),1973,“你不可能和自然玩 20 个问题就赢”

最后,我们希望我们的 AGI 系统被绑定到一个数学框架,以便我们可以定义约束,控制系统的复杂性和演化,并限制潜在解决方案的搜索空间。例如,“全脑模拟”的想法,尽管很难实现[16],也是有问题的,因为由于缺乏对潜在机制的理解,它的发展将是不可控的,这具有明显的伦理影响。第三个性质的一个重要延伸是,如果 AGI 系统的容量必须增加,或者为了使学习过程更有效,数学框架本身必须能够增加复杂性。例如,线性模型永远不够,因为尽管增加了参数的数量,但我们永远无法对非线性问题(如 XOR)建模。然而,因为神经网络可以根据通用逼近理论[17]逼近任何连续函数,所以新定义的也能够满足假设的体系结构可以通过添加额外的神经元和层来提高其训练效率。

现在,让我们退后一步,考虑一个看似与 AGI 无关的话题——童年记忆,或者更具体地说,童年记忆的缺失。

我们为什么不记得小时候的事情?

如果你曾经试图回忆起你最早的记忆,你可能会意识到这种记忆是支离破碎的,不清楚的,或者模糊的——几乎就像一场梦。事实上,很有可能你对你生命的最初几年没有任何记忆,而你回忆起来的这些最初的片段记忆发生在 3-7 岁之间。这种被充分研究的现象被称为“婴儿健忘症”,指的是我们无法回忆起生命最初 3-4 年的情景记忆[6];然而,这不仅仅是人类的经历——事实上,许多动物物种都表现出婴儿健忘症的形式[7]。虽然还不清楚这是由于记忆检索失败还是存储记忆失败,但很明显,这种现象与神经发生过程有关,或者简单地说,与我们大脑成熟的过程有关。

神经发生假说的有效性实际上与本文的论点无关。更重要的是对现象本身的认识——也就是说,如果我们忽视发展问题,人类的工作记忆似乎会有规律地发展,并且独立于我们的经验。在这种情况下,天性似乎胜过后天培养。对这一现象的生物学、心理学和系统分析都表明,我们大脑的信息处理系统变得越来越复杂,这种进化完全依赖于时间。

由简单性——人类智能——产生的时间相关的神经复杂性的后果是深远的。很自然地,问题出现了,比如是什么使得人类的智慧不同于非人类中心的智慧,是否存在一个所有灵长类动物、所有哺乳动物甚至所有动物共有的蓝图?最重要的是,什么机制控制着大脑的成熟,如何才能充分模拟这种环境?回答这些问题需要心理学、生物学和计算方面的考虑——因此,我们应该将我们的研究限制在足够灵活的计算框架内,以纳入这些相关领域的新理解,并能够从简单的初始配置进行复杂的进化——进入细胞自动机。

元胞自动机

背景和意义

约翰·冯·诺依曼被认为是他那个时代最伟大的数学家之一,在他 1957 年去世之前,他一直致力于设计一种通用构造器——一种可以在细胞自动机环境中设计的自我复制机器。机器的细节最终由亚瑟·w·伯克斯在他死后汇编成册,并发表在《自我复制自动机的 T4 理论》一书中。通用构造器背后的想法是确定允许机器变得复杂的最低要求,类似于生物和社会系统中的进化。这种机器可以生成细胞自动机环境中可以想到的任何其他机器。通用构造器由 3 部分组成:蓝图、执行蓝图的机制和复制蓝图的机制,并且令人印象深刻地先于沃森和克里克的 DNA 转录的著名发现。1995 年,设计了一个具体的实现(图 1)。通用构造器的关键发现是能够复制的复杂系统可以从由一组简单规则定义的简单环境中出现。

图一。通用构造器,能够自我复制,显示两个完整的进化。2D 网格中的每个单元可以有 32 个状态。来源[2]。

定义

C 细胞自动机,最初由冯·诺依曼和斯坦·乌拉姆描述,是物理系统的数学理想化,其中空间和时间被离散化。空间环境是由 N 维网格的镶嵌定义的,其范围通常是无限的,其中每个离散的单元与有限的、依赖于时间的状态相关联。该系统根据一组规则在离散的时间步长中演化,这些规则取决于前一时间步长中每个单元的邻域。通常,邻域由像元的直接相邻像元定义。每个单元都由相同的规则管理,只能呈现有限状态集中的一种状态,并与环境的其余部分同步更新。系统的配置是每个单元持有的当前状态。前一个是前一时间步中的配置,而后一个是将转换规则应用于当前配置的结果。

例如,假设一个有限的 5x5 网格有 25 个单元,每个单元可以呈现两种状态之一——开或关。现在,让我们忽略如何处理边缘单元格。每个单元的邻域可以被定义为它的 8 个相邻单元,如图 2b 所示。因为每个单元可以有 2 个状态,邻域和单元本身可以由 2⁹不同的配置来定义。此外,因为我们的细胞可以转换到两个可能的状态,有 2^(2⁹)可能的规则。我们如何定义这些规则是指定这个细胞自动机环境的最后一步。

图二。2D 细胞自动机中的邻域示例,其中中心方块的邻居显示为黑色。该示例显示了(a)冯诺依曼邻域和(b)摩尔邻域之间的差异。来源:[4]

细胞自动机最著名和最受研究的规范之一是已故的约翰·康威的“*生命的游戏”*或简称“生命”。像前面的例子一样,每个细胞可以开或关——或者在这个例子中是活的或死的。这个游戏在 2D 网格上也有类似的定义,有三个规则:任何有 2-3 个邻居的活细胞保持存活,任何有 3 个邻居的死细胞变得存活,所有其他活细胞在下一代死亡。一般来说,任何其他死细胞仍然是死的[5]。

*“生命的游戏”*之所以被称为零玩家游戏,是因为系统的进化仅仅基于其初始配置,该配置指定了哪些细胞是活的,哪些细胞是死的。令人惊讶的是,复杂的系统可以被设计成如图 3 所示的模式,这些模式是活跃的和静止的,以不同的周期振荡,并在网格上有节奏地移动。

图 3。康威的“生命游戏”展示了三种基本模式:静物、振荡器和宇宙飞船(移动)模式。来源:wikimedia.org

有希望的是,现在已经很清楚细胞自动机系统如何以一种可以满足基本 AGI 系统所有假设的方式来组织自己。进化假设隐含在它的设计中,包括时间和空间的进化。像图形网络一样,组合概括可以通过允许系统开发完成任务的基本构件来实现。其次,我们可以通过多种方式直接比较各种初始配置的效率和灵活性。例如,初始配置达到有用的复杂配置需要多少次迭代可以用来比较效率,而适合于 n x n 网格的唯一后续模式的数量可以用来评估系统的灵活性。最后,因为细胞自动机系统可以被设计为图灵完全[3],我们可以直接将先验编码到系统中。此外,只有某些规则集允许图灵完全细胞自动机,就像初等或 1D 细胞自动机中的规则 110[3]。此外,这对我们如何配置系统施加了约束,因为对于给定的迭代次数,只应该评估允许图灵完整性的规则集。

细胞自动机系统是如何配置的

快速讨论如何配置细胞自动机是很重要的。在某种程度上,这代表了可以探索的整个潜在搜索空间。现在,我们假设所有细胞自动机系统存在于无限空间中,并且细胞自动机系统的所有参数化是时间独立的(即,一旦初始设置就不会改变)并且在所有细胞间共享。

  • 空间的曲率和维度(例如,“生命”是具有零曲率的 2D 欧几里得平面,但是可以探索具有非零曲率的更高维度的超平面)
  • 镶嵌或平铺几何形状(如正方形、三角形、六边形等正多边形或正方形和三角形等半正多边形[18])
  • 状态集(冯·诺依曼最初的通用构造器有 29 个状态,而“生命”只有 2 个)
  • 邻域定义
  • 转换函数(规则)

可以探索条件依赖性,例如依赖于特定单元的镶嵌几何形状的状态、邻域定义和转换函数。我猜想,对这种依赖性的探索,虽然增加了系统的复杂性,但可以增加自动机进化成有用的复杂系统的效率。

我们将何去何从?

类似细胞自动机的系统仍然有缺点。例如,通过将时间和空间表示为离散单元,系统的输入也必须离散化。与对原始感觉数据(如图片)进行推理的神经网络不同,细胞自动机必须接受类似物体的输入。这是一个公开的问题,也是图形神经网络共有的缺点[12]。然而,因为可以想象细胞自动机可以被用来设计一个子系统,以在离散化版本上操作,比如说,一个音频输入,它可以被证明终究不是一个限制。另一个限制是搜索空间。假设一个像“生命”一样的配置,人们将不得不根据无限长的迭代次数的细胞数量来探索指数增长的配置数量,因为一个模式是否能够从初始配置出现是一个不可判定的问题[19]。然而,最重要和最关心的是如何有效地探索初始配置的空间以解决给定的问题,并正确地定义类似细胞自动机的机制以响应输入并产生相关的输出。

正如 Friedburg 指出的那样,设计一个能够实现人工智能的系统存在于两个极端之间——一个是系统模拟整个人脑和所有相关活动,另一个是系统能够自行进化以满足人脑的需求——更简单地说,这代表了以模型为中心和以系统为中心的方法。如果你倾向于后者,类似细胞自动机的系统是一个有前途的选择,因为它们允许复杂的系统——甚至可能是像人类一样的责任心所需要的系统——从简单的初始配置中产生。一个与人类惊人相似的现象。

引文

[1]冯·诺依曼、约翰和阿瑟·w·伯克。“自我复制自动机理论。” IEEE 神经网络汇刊5.1(1966):3–14。

[2]翁贝托·佩萨文托。“冯·诺依曼的自我复制机器的实现。”人工生命2.4(1995):337–354。

[3]沃尔夫拉姆,斯蒂芬。细胞自动机与复杂性:论文集。CRC 出版社,2018。

[4]李忠焕等,“用元胞自动机实现熔岩流模拟程序”韩国岩石学会学报26.1(2017):93–98。

https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life

[6]阿尔贝里尼、克里斯蒂娜·m .和阿莱西奥·特拉瓦利亚。"婴儿健忘症:学习学习和记忆的关键时期."神经科学杂志37.24(2017):5783–5795。

[7] Akers,Katherine G .等人,“海马神经发生调节成年期和婴儿期的遗忘。”理科344.6184(2014):598–602。

[8]弗朗索瓦·乔莱。《智力的衡量》 arXiv 预印本 arXiv:1911.01547 (2019)。

[9]Sainath,Tara N .等人,“LVCSR 的深度卷积神经网络” 2013 IEEE 声学、语音和信号处理国际会议。IEEE,2013 年。

[10] LeCun,Yann,Yoshua Bengio 和 Geoffrey Hinton。“深度学习。”性质521.7553(2015):436–444。

[11] Silver,David,等人,“用一般强化学习算法通过自我游戏掌握国际象棋和日本象棋” arXiv 预印本 arXiv:1712.01815 (2017)。

[12]巴塔格利亚、彼得·w .等人,“关系归纳偏差、深度学习和图形网络。” arXiv 预印本 arXiv:1806.01261 (2018)。

[13]伊丽莎白·斯皮克,“核心知识”美国心理学家 55.11 (2000): 1233。

[14]特雷斯曼,A. Cogn。心理学。 12 ,97–136(1980)。

[15]艾伦·纽维尔。“你不能和自然玩 20 个问题就赢:对本次研讨会论文的投射式评论。”(1973).

16 Stiefel,Klaus M .和 Daniel S. Brooks。“为什么(目前)还没有成功的全脑模拟?."生物学理论14.2(2019):122–130。

[17] Csáji,Balázs Csanád,“人工神经网络近似法”匈牙利 Etvs Lornd 大学科学学院 24.48 (2001): 7。

https://www.mathsisfun.com/geometry/tessellation.html

https://en.wikipedia.org/wiki/List_of_undecidable_problems

[20]https://en . Wikipedia . org/wiki/Garden _ of _ Eden _(cellular _ automaton)

紧急与非紧急车辆分类

原文:https://towardsdatascience.com/emergency-vs-non-emergency-vehicle-classification-f0153c4f87f8?source=collection_archive---------35-----------------------

利用计算机视觉的力量

由拍摄的照片将在 Unsplash 上真实再现

由于救护车和消防队等紧急车辆的交通延误造成的死亡是一个巨大的问题。在日常生活中,我们经常看到应急车辆在交通中面临通行困难。因此,将车辆分为紧急和非紧急类别可能是交通监控以及自动驾驶汽车系统中的一个重要组成部分,因为准时到达目的地对于这些服务至关重要。

为了找到这个问题的解决方案,我们将尝试建立一个图像分类模型,将车辆图像分类为属于紧急车辆或非紧急车辆类别。

获取数据

我们首先要做的是获取车辆图像的训练和测试数据集。这里,用于构建分类模型的数据集从 *Analytics vidhya,*下载,它由紧急和非紧急车辆图像组成,其中紧急车辆通常包括警车、救护车和消防队。

完成后,我们可以使用 pandas 读取提供的训练数据集。

我们将使用 fastai 视觉库来构建我们的图像分类模型。

from fastai.vision import *df = pd.read_csv('/content/train.csv')
df.head()

训练数据框架

我们有两列。包含图像名称的 image_names 列和包含每个图像标签的 emergency_or_not 列。此处 1 代表标签为应急车辆0 非应急车辆。

快速查看数据框为我们提供了足够的信息来加载数据并开始构建我们的图像分类模型,但在此之前,我们将对图像应用变换,这将有助于我们概化我们的模型,即获得高精度。

我们将应用的变换有:do _ flip——默认启用——和 *flip_vert,max_rotate=50。*我们还将通过调整 max_lighting=0.1max_warp=0 来调整灯光。

tfms= get_transforms(do_flip=True,flip_vert=True,max_rotate=50,max_lighting=0.1,max_warp=0 )

现在我们已经准备好应用我们的转换,我们可以使用 FastAIs 数据块 api 加载数据。

data = ImageDataBunch.from_df('/content/cars', df,ds_tfms=tfms,label_delim= None,valid_pct=0.2,fn_col=0, label_col=1 , size=299,bs=64).normalize(imagenet_stats)

上面的.normalize(imagenet_stats)方法用于根据来自 ImageNet 数据集的 RGB 通道的统计数据来标准化数据集。

归一化所做的是将图像的强度(图像的原始强度在 0 和 255 之间)降低到 0 和 1 之间。这有助于提高我们模型的计算能力。

现在我们已经加载了数据集,让我们看一看它是什么样子的:

data.show_batch(rows=3, figsize=(7,7)

我们知道 0 代表非紧急车辆,1 代表紧急车辆。

我们也可以通过调用一个告诉我们图像类数量的函数来检查这一点。

print(data.classes)[0, 1]

训练模特

因为我们已经准备好了数据,所以是时候把它输入到模型中了。我们可以通过从头开始构建卷积神经网络来做到这一点,但这样做实际上是低效的。因此,我们采用预先训练的 CNN 模型的权重,该模型已经学会识别特征(某些类型的事物,例如梯度、边缘圆等)

这里,我们将使用预训练的 ResNet50 卷积神经网络模型,并使用迁移学习来学习网络的最后一层的权重。

什么是迁移学习?

迁移学习是从一个现有的(经过训练的)用于图像识别的神经网络开始,然后在这里或那里对其进行一点(或更多)调整,以针对您的特定用例训练一个模型,我们这样做是因为从头训练一个神经网络将意味着需要大约 300,000 个图像样本,并且为了实现真正的良好性能,我们将需要至少一百万张图像。但是通过迁移学习,我们可以用有限的数据集和更少的时间获得高性能。

我们将通过冻结和解冻一些层并对其进行训练来对其进行微调。这是因为顶层学习简单的基本特征,我们不需要训练这些层,而后面的层学习更复杂的特征。

在上面的图片中,每个不同的层学习图像的不同特征。这种卷积神经网络的后几层学习鸟类眼睛等特征。

我们使用cnn_learner函数来加载预训练的 ResNet50 网络,该网络是在来自 ImageNet 数据库的大约一百万张图像上训练的。

learn =cnn_learner(data,resnet50,pretrained=True,metrics=[accuracy])

现在,让我们拟合 4 个时期的一个周期,看看我们的模型在该数据集上的表现如何:

learn.fit_one_cycle(4)

只使用 4 个时期的原因是为了了解我们的模型如何执行,并在以后对其进行微调以获得更好的结果。正如我们可以看到的,我们的验证损失大于我们的训练损失,这清楚地表明我们的模型存在拟合不足的问题。

让我们来看看我们模型的预测:

interp = ClassificationInterpretation.from_learner(learn)

解读最大损失:

interp.plot_top_losses(9, figsize=(7,7))

我们数据集上的 resnet50 预测

看着最大的损失,我们可以告诉我们的模型犯了同样的错误,就像人类第一次看到一些看起来是紧急车辆但被解释为非紧急车辆时会犯的错误一样。

另一个有用的工具是使用一种叫做混淆矩阵的东西,它基本上显示了每一种实际的紧急和非紧急车辆预测,它被预测了多少次。

`interp.plot_confusion_matrix(figsize=(8,8), dpi=60)

混淆矩阵

我们的模型有 17 次将紧急车辆预测为非紧急车辆,而有 4 次将非紧急车辆预测为紧急车辆。困惑呃?毕竟我们正在处理一个混乱矩阵!

解冻

冻结层是指未被训练的层,即未被更新的层。

到目前为止,我们所做的一切都没有改变预先训练的模型权重。我们所做的只是在顶部添加了一些新层,并学习了如何混合和匹配预先训练的功能。

但是我们希望模型能够学习我们图像的特定特征。为了做到这一点,我们将解冻一些层,以根据我们的图像更新整个网络的权重。

检测边缘和梯度的第一层和检测曲线和拐角的第二层不需要太多的学习,它们不需要太多的改变。而更后面的层需要改变。当训练其他图像识别时,这是普遍适用的。

早期的层具有更多通用功能。因此,我们预计他们对新数据集的微调需求会减少。出于这个原因,我们将对不同的层使用不同的学习速率:最初的几个层将位于1e-4用于基本几何特征和最接近像素的层,而1e-2如前所述用于我们添加在顶部的层(完全连接的层)。我们称之为 差异学习率。

learn.unfreeze()

我们将再次在我们的 unfreeze 网络上运行 fit-one 循环,并查看它现在的运行情况。

learn.fit_one_cycle(3)

92%的准确率不算差,但我们还可以做得更好。

学习率

用于调整我们模型的最重要的超参数是学习率。它通过根据损耗梯度调整网络的权重,帮助我们找到最佳解决方案。该值越低,我们沿下坡行驶的速度越慢。虽然在确保我们不会错过任何局部最小值方面,这可能是一个好主意(使用低学习率),但这也可能意味着我们将需要很长时间才能收敛——特别是如果我们被困在一个平坦区域。

吴恩达在 Coursera 上的机器学习课程

这里我们可以看到学习率对收敛的各种影响。

(Img 信用: cs231n

因此,选择正确的学习速度很重要,而不是随意猜测或多次试错。

为此,我们将使用一个名为lr_find()的函数。这个函数是 Leslie Smith 论文的实现(用于训练神经网络的循环学习率)。)关于调整神经网络超参数。

learn.lr_find()

学习率查找器。

为了更好地理解它,我们将借助另一个函数来绘制它。

learn.recorder.plot()

学习率是相对于损失绘制的。在这个图表的帮助下,我们可以很容易地选择我们的学习速度。

正如我们所见,在 1e-03 之后,损失开始增加,因此我们将在此之前选择一个数字,同样为了更新初始层的权重,我们将选择一个较低的学习速率。 1e-04 好像不错。

根据选择的学习率,我们将再次训练我们的解冻模型,但这次要长一点,有 10 个时期。

我们将使用准确性作为另一个参数,通常称为 指标 来评估我们的模型表现如何。

或者

https://developers.google.com/

在继续之前,让我们也对 fit_one_cycle 方法有一个直觉。

在这种方法中,我们用两个等长的步骤做一个循环,一个从较低的学习率到较高的学习率,然后回到最小值。最大值应该是用学习率查找器选取的值,较低的值可以低 10 倍。——再多读一点关于*fit_one_cycle*的内容,尽请查看本博客

现在让我们看看我们的模型做得怎么样?

*learn.fit_one_cycle(10,max_lr=slice(1e-4,1e-3))*

准确率达到约 97%

我们的模型做得足够好,不存在欠拟合,因为我们的模型之前存在这个问题,也不存在过拟合(过拟合意味着训练损失远低于验证损失),因为我们的验证损失大约是训练损失的 0.02 倍。

我们已经达到了 96.96%~ 97%的

因为我们已经根据我们的车辆分类问题更新了我们模型的权重,我们将冻结我们模型的层,并用名称 car_classification 保存它。

*learn.freeze()learn.save('car_classification')*

我们能够达到大约 97%的准确性,同时我们可以在增加时期数量、使用绘图函数找到更优的学习率、更多的数据扩充技术等方面对我们的模型进行更多的实验。

参考资料:

*【2】:【https://sgugger.github.io/the-1cycle-policy.html *

*【3】:【https://arxiv.org/pdf/1506.01186.pdf *

【4】:第一课笔记本,fast.ai 第一部分 V2

**今天的到此结束。💃🏻

感谢您的阅读!

机器学习中出现的问题:让人工智能变得“好”

原文:https://towardsdatascience.com/emerging-problems-in-machine-learning-making-ai-good-3980bb9fdd39?source=collection_archive---------42-----------------------

YOUTUBE | 苹果 | 谷歌 | SPOTIFY | 其他

爱德华·哈里斯在 TDS 播客

编者按:这一集是我们关于数据科学和机器学习新兴问题的播客系列的一部分由 Jeremie Harris 主持。除了主持播客,Jeremie 还帮助运营一家名为sharpes minds的数据科学导师初创公司。你可以听下面的播客:

我认为很容易忽视机器学习发展的程度和速度。

就在 10 年前,人们还在说我们正处于人工智能的冬天,深度学习是一个边缘且在很大程度上被忽视的研究领域。从那时起,我们见证了人类历史上最重要的技术革命之一。强化学习允许机器玩游戏,让机器人在现实世界中确定自己的方向,卷积神经网络让计算机比人看得更清楚,变压器架构正在生成大量文本,专家无法将这些文本与人类的书写区分开来。

这些新工具让我们能够以我们从未想象过的方式来衡量个人的影响力。一个数据科学家可以设计出一种算法,在部署后的几分钟内,它将立即影响数百万甚至数十亿人的生活。

但是增加单个开发者或单个算法的影响不一定是一件好事。开发人员可能会犯错误,公司可能会有恶意,数据可能会被错误地采样,最终这些问题和许多其他问题可能会导致算法弊大于利。当伤害扩大到数百万或数十亿人时,有可能对人类造成前所未有的巨大伤害。

虽然我们的技术确实变得更好了,但我们是否已经变得足够聪明来运用它还不太清楚。机器学习社区中的许多人越来越多地意识到,如果我们要能够正确地运用我们的新权力,我们需要大大改善几千年的道德哲学、伦理学甚至形而上学。

但在每个人都在不断推出下一个算法、下一个数据集或下一个大架构的背景下,这很难做到。所以我认为至少我们中的一些人花些时间停下来,环顾四周,问一些非常基本的问题是值得的。这一切将走向何方?我们希望我们的技术引领我们走向何方?我们是如何达不到这个目标的?先进的人工智能系统在未来可能会给我们带来什么风险,它们有什么潜力?构建符合人类价值观的道德、安全、可解释和可问责的人工智能意味着什么?

这就是今年“走向数据科学”播客的主题。我希望你加入我们的旅程,今天开始采访我的兄弟埃德,他除了作为一个小团队的一部分与我一起工作以建立sharpes minds数据科学导师计划之外,还与我在许多人工智能安全、校准和政策项目上合作。我认为他会是播客新年的最佳嘉宾。

我希望你喜欢这一集。

剧集中提到的链接:

  • 如果你有兴趣了解更多关于人工智能联盟或人工智能政策的职业,80,000 小时是一个很好的资源。你可能也有兴趣听听他们与 OpenAI 的 Paul Christiano 的惊人播客,其中涵盖了人工智能对齐。
  • 如果你对人工智能政策感兴趣,你可能想看看 GovAI 正在做的工作。
  • 开放慈善项目为有特定项目或研究领域想要探索的人提供资助,这些项目或研究领域与 AI 安全有关。

你可以在这里的推特上关注艾德,你也可以在这里的推特上关注我。

副本

嘿,大家好。欢迎回到播客。我希望你一切都好。我的名字当然是杰米。我是“走向数据科学”播客的主持人,也是 SharpestMinds 数据科学导师计划团队的成员。事实上,上周我们暂停了一下,休息了一下。我们没有发布一集。我想先解释一下我们为什么要暂停,以及我们今后会做些什么。

首先,暂停的原因是我们正在制作下一季的剧集。这几集将更多地关注围绕我们如何部署人工智能系统以造福人类的问题。随着我们的人工智能系统变得越来越强大,开始问一些问题变得越来越重要,比如我们是否应该实际部署一个人工智能系统来解决这个特殊的问题,或者如果我们开始在这个子领域部署越来越强大的人工智能系统,会出现什么问题?

Jeremie:
这些都是围绕安全的各种问题,在短期内,我们开始问这样的问题,比如人工智能系统会不会意外地建议一系列可能导致人类伤害或经济损失的行动?一直到更基本的,也许更涉及长期的问题,如 RAI 系统实际上反映了人类的价值观,将人类塑造成我们想要的形式,我们的 AI 系统从更存在主义的角度来看实际上是安全的。

一个任意智能的系统是否有可能对人类自身的持续存在产生影响,这是我们应该尽快考虑的问题。因此,这将是未来围绕道德、人工智能系统中的偏见以及我们是否应该围绕分发部署提出的许多问题的焦点。所以我真的很兴奋能投入到这整个系列中。我们有这么多伟大的嘉宾排队,很难选择一个开始,我最终坐下来,思考我知道谁最适合谈论所有这些话题,不仅仅是人工智能伦理,不仅仅是人工智能偏见,不仅仅是人工智能对齐的技术细节,而是与我一起涵盖所有这些基础的人。

杰瑞米:
我找到了我哥哥埃德,他以前上过播客。他和我是 SharpestMinds 的联合创始人,他实际上在技术比对工作以及创业工作方面有着丰富的经验,看到了在野外部署的算法,由于他在人工智能安全领域的经验广度和专注深度,我真的认为他是我打开局面的最佳人选。所以我希望你喜欢这次谈话。这将会比我们过去经历的一些更不寻常。但是如果你有任何反馈,请让我知道,我迫不及待地想发布接下来的几集,我们正在这里探索一个真正令人兴奋的主题,与社区分享这些想法并获得你对我们如何做的反馈将是非常棒的。所以事不宜迟,请欣赏这场表演。

嗨,艾德。感谢你参加我的播客。

艾德:
非常感谢你邀请我。我很感激。

耶雷米:
哦,是的。完全没问题。天啊,我想我们可以从很多地方入手。人工智能是一个非常大的空间,围绕人工智能应该如何使用,如何保护它的问题开始出现。显然,这是整个系列播客的主题,也是我们接下来几集的重点。我想,也许一开始,我们可以谈论许多不同的事情,但你更关注人工智能对齐的想法,让机器学习模型以不同的形式做我们希望它们做的事情,确保它们的性能本质上对人类没有危险,并且它朝着我们希望的方向优化。我们可以介绍一下这个想法吗,人工智能对齐领域,比如为什么我们应该花费时间和精力来对齐我们的机器学习算法?

艾德:
是啊。这是我最近一直在思考的事情,因为系统变得越来越强大,我们看到了年复一年的进步。系统变得越强大,它们做我们想要的事情就越重要,一致性很重要,因为并不总是很明显系统会做我们想要的事情,也不总是很明显,即使系统开始做看起来像我们想要的事情,它也不会最终做一些非常糟糕的事情。

艾德:
社交媒体订阅就是一个很好的例子。算法让你回到 Twitter 和所有这些东西。也许你会想,Twitter 公司想从你这里得到什么?这是钱,但它是相当良性的,对不对?他们只是想让你多点击,多点赞。在第一个层面上,你想到的是算法会给你更多点击的帖子和推文,所以你会留在那里,看到更多的广告。那是第一关。

埃德:
但问题是,如果你训练一个通用系统来做这件事,系统会发现的一件事是,“嘿,我实际上通过对我展示这些推文的人进行测试,我可以发现我可以通过展示某些类型的内容来让人们变得更可预测。”这些算法让我们变得更容易被他们预测的方式之一是内容的政治化。如果我更政治化,我的派系比我的政治立场处于中心时更容易预测。

埃德:
所以实际上正在发生的事情之一是,这些算法纯粹通过试图赚更多钱的行为,实际上将人们推向所有这些不同种类的光谱、不同政治问题和所有这些问题的不同端,纯粹是因为他们喜欢,“嘿,我试图让你成为对我来说更容易预测的东西,而政治上更极端的人更容易预测,因为他们往往有很多相关的观点。”

埃德:
所以这是其中一种方式,实际上很可怕,你可以看到它是如何爬上你的身体的,因为这已经发生了很多年,但是你可以想象这已经对世界产生了影响,随着这些系统变得越来越聪明,我们应该期待更多类似的事情开始发生。

耶雷米:
好的,好的。所以这里的主要问题是,我们的算法有时太聪明了,如果我们不仔细思考我们希望它们为我们创造什么样的世界,它们会找到我们从未想象过的解决方案,或者如果问题是预测我会点击什么,这样我就可以生成更吸引人的内容, 然后,真正改变我的用户心态,使他们更可预测,把政治光谱变成更多的二元,所以这是一个更小的维度问题,更容易降维。 变成了它自己的病理,对吗?我是说,这就是问题的核心,对吧?

艾德:
是啊。这种事情会再次出现在你身上。你可以给一个系统一套指令,你认为这些指令完全是良性的,对你来说完全有意义。好吧。相当良性。只有在事后才意识到,我们可以回顾过去,说,“哦,我的上帝。如果我们当时知道这是我们向世界释放的力量,我们可能会采取不同的做法。”但在当时,不可能预测这将是一个结果。

艾德:
问题是,当你在处理比你聪明的东西时,根据定义,你无法预测它会做什么,因为它比你聪明。如果你比它聪明,你就能预测它,但是因为它比你聪明,它能预测你,而不是相反。

我想这并不一定…我的意思是,我认为这是当你谈论人工智能时的一个问题,什么是智能?智力是什么意思?我认为这些术语定义不清。从某种意义上来说,很难说 Twitter 算法比人聪明。其他感官狭义地解释,你可以说它比人更聪明,但肯定有一个阈值,两者开始互动和竞争,一个算法开始超过另一个。Twitter 算法开始超过你的人脑,并开始改变你,而不是你改变它,对不对?

艾德:
对。我会说,算法目前在狭义上可能比我们更聪明,但我们应该担心它们可能在更普遍的方面变得比我们更聪明。当然,在达到这一点之前,还有其他事情需要关注。

杰瑞米:
好的。所以,是的。因为我认为我们会谈到对一般智能的普遍关注,以及这些越来越先进的系统会走向何方。短期来看,你提到了 Twitter。显然,很多人都谈论过人工智能系统中的人工智能伦理和人工智能偏见等问题,对吗?我认为这是今天真正的主题,因为它就在我们身边。我们可以看到系统运行的方式会有让我们吃惊的偏差。在许多情况下,它们似乎反映了世界当前的方式及其当前的故障、故障模式,并且它将倾向于强化这些故障模式,因为它已经根据这些数据进行了训练,并且它将做出反映这些数据的预测。我想你更关心事情的长期方面,但这也可能是长期的问题吗?

Ed:
某种程度上。因此,关于人工智能中的故障模式和偏见的一个问题是,在某种程度上来说,这是一种正在发生的事情,因为这些系统有点太愚蠢了,它们没有得到足够普遍的训练。当系统过于智能时,未来的风险会越大,最终可能会更大。但是偏见的风险在今天绝对是真实的,而且是当前的。

埃德:
这些偏见风险是你基本上得到的一种涡轮增压版本,当人们构建软件时,他们通常会为自己构建,他们会测试点击量和他们自然期望其他人做的事情。每个人都是以自我为中心的,对吗?所以我们基本上都是为自己构建的,这完全没问题,但当你收集的数据以特定方式出现偏差时,有时会发生什么,就好像这不是算法的错一样。

艾德:
算法只是在给定的数据上运行,它可以完全忘记,“哦,有一群人的名字不是用拉丁字符写的,或者没有特定的肤色或其他什么。”所以你实际上会遇到这样的情况,算法在处理开发者没有想到的情况时非常糟糕,我们给这些系统的能力越大,这些错误的代价就越大。所以我认为这就是人工智能中偏见的现状。

Jeremie:
对。我的意思是,人们经常谈论数据集偏差。这引起了很多关注。我认为另一个非常重要的方面是特征选择偏差,因为如果你想一想,当我们在环境中导航时,人类会收集关于世界其他地方的特征。这些特征通常是声波之类的东西。它们就像气味一样。它们就像视觉和触觉。这些是进化为我们设计的特征。因为我们通过那个镜头看世界,我们无法注意到某些事情。举例来说,这些东西就像一直在我们身体中穿梭的中微子,我们对它们完全不敏感,但它们却占了我们在任何给定时刻所沐浴的能量的很大一部分,或者说是不可忽略的一部分。

杰雷米:
所以我认为可以毫不夸张地说,我们的环境大部分是看不见的,甚至是我们原则上可以看见的东西,我们如此短视地专注于我们视野中的一小部分,以至于我们没有吸收我们周围绝大多数的信息。说到我们的机器,我想我们也在做类似的事情。我们选择特征。

Jeremie:
例如,如果你要告诉一个信用卡定价算法,比如一个人的姓名、年龄、职业和肤色,你就让它通过某个镜头来看待这个世界,并使它比其他人更容易找到某些相关性,或将复杂性和细微差别纳入一个高级核心应变特征。你认为这也是一个问题吗?还是你认为数据集偏差是一个更大的问题?

埃德:
所以我要说的是,特征选择会产生两种偏见。第一个是遗漏偏差,你没有给系统一个有用的特征。你给了系统一个关于结论的非信息特征。第二种更像是标签偏见。因此,如果你给一个系统一个人的肤色来进行信用卡评估,如果你真的在真实的信息数据集上训练这个系统,理论上,肤色不应该成为问题。

艾德:
如果你有一个运行在那个系统上的完美的普通智能,它将会忽略肤色,以至于肤色需要被忽略。但问题是,当你在标签上训练这个系统时,这些标签是由那些本身有偏见的人贴上的,我们都有偏见,那么偏见本身就会被诱导到这个系统上。举例来说,这是人们在潜在的算法给出判决时遇到的事情。

埃德:
如果结果是之前看到的判决是由…有一个重要的判决样本对谁知道,人的身高、肤色或头发颜色或其他任何东西有偏见,那么这个系统又是垃圾进来,垃圾出去。系统会学习你教给它的东西。所以它会产生相同的偏差。

杰瑞米:
所以我想这很有趣。我的意思是,我想我看到的偏见数据的情况是其中的一部分。我不认为是这样的……我的意思是,你谈到了一个足够普遍的智能程序,它会查看包括肤色等信息,然后得出正确的结论。我认为事实并非如此。我认为,如果你……除非那个系统能够获得更全面的特征,否则它会倾向于通过特定的镜头短视地看待事物,有时这个镜头,即使数据集没有偏见,即使它检测到世界上正在发生的事情,如果我们谈论肤色或我们谈论性别或其他,肤色和偿还债务的倾向或其他之间存在关联,如果你愿意,这些会反映在设计糟糕的系统的偏见中。

杰雷米:
但是表面下真正发生的是,如果你把它分开,如果你突然控制其他变量,我们预计……我不知道有没有人真的做到了这一点,但是我个人非常期待肤色会从那个等式中消失,但是只有当你控制这些其他变量时。因此,我认为,只有在一定程度上,你添加到该功能集,你才能真正以这种方式消除系统偏差。

是的,这是正确的。我认为这是从另一个角度来看待我所说的,他们的疏忽所造成的罪恶。所以,如果你给了系统足够的基础数据来分解这些变量,最终使这些性别和混杂特征变得不相关,我想,如果你给了系统足够的数据,它会知道这些变量是不相关的。但是,是的,如果你忽略了这些,他们实际上会学习变量,结果会表现出偏差。

耶雷米:是的。我认为这一切对我们的自由意志的概念或自由意志的幻想的挑战程度也总是很有趣,因为我也可以想象如果你把这个过程发挥到极限,你继续细化,增加更多的特征,增加更多的特征,最终你的模型变得如此复杂。它可以解释,我的意思是,几乎就像在荒谬的极限中,你大脑中每个神经元的放电模式,然后你可以以超高的确定性预测你的行为,你所有的代理都消失了。我的意思是,随着系统变得越来越复杂,我认为这实际上是我们将要经历的旅程中有趣的一部分。

艾德:
我认为这在某种程度上是对的,但这是有限度的。所以这和预测天气是一样的。系统有…即使你没有想到,“哦,在一切之上有量子力学的不确定性,”即使你没有想到这一点,有混沌特性的经典系统有…你不能真正预测它们超过一定数量的时间步骤。它的工作方式是,我想如果我没记错的话,它有点像你的…然而,你开始时的精确度,你后来的精确度下降了一倍,就像时间的平方根。

埃德:
所以基本上在一段时间后,即使你有一个关于事情将如何发生的完全确定的模型,如果你开始时的测量精度基本上随着时间的推移而传播并变得越来越差。因此,非常智能的系统预测未来的能力总是有限的。至少这是我们目前最好的理解。但是你不需要能够预测每一个原子的运动,就能够做很多非常有用的事情。那可能很危险。

耶雷米:
是的。我认为实际上…也许补充说明是,在英国已经有一个关于政府试图…而不是政府的故事。对不起,我认为一所大学试图预测学生的考试成绩,因为他们无论出于什么原因都无法预测,我认为这可能与 COVID 有关。他们实际上不能写测试,对吗?

杰雷米:
所以你可能会说,有些学生对他们的代理机构被剥夺感到不安,这是理所当然的。在这种情况下,算法似乎是非执行性的。它像现在的机器学习模型一样夸大了,但它夸大了它的准确性或淡化了它的不确定性。然而,我认为有一个有趣的问题,“好吧。如果不是这样呢?如果算法是超级执行的,我们会在哪里?”

Ed:
如果你以某种方式去思考,这个测试本身就是对你自己的一个不确定的评价。这是对你自己技能的嘈杂评价,所以如果你在考试中表现不错,你应该更开心。你已经得到了额外的奖励,而如果你只是过了糟糕的一天,睡不好觉,不管是什么,某种混合的东西,你也许你应该理所当然地愤怒,这个测试没有正确地评估你的水平。

Ed:
我认为,如果你有一个已知不确定性的完全无偏的算法,最终这可能更多是一个语义和舒适区的问题,而不是一个真正的问题。所以如果你的算法是无偏的并且校准良好。因为如果它是无偏的,并且校准得很好,那么我至少可以看着我的测试分数或我的预测测试分数,然后说,“嗯,有 50%的可能性我应该为此生气,有 50%的可能性我应该为此高兴。”另一方面,让计算机来判断我们的未来,我们都会有一种天生的不适。所以我不知道我们作为一个文明会不会克服这一点。

耶雷米:
对,我想这开始引出了一些我认为更具前瞻性的话题。所以当我们继续开发这项技术时,你之前提到过。这些系统变得越强大,我们就越有必要知道自己到底想要什么。这种能够建立确切知道我们想要什么的系统的想法,能够与他们交流,能够确保他们确实在做我们要求他们做的事情,这就是所谓的人工智能对齐。我想问你,你能不能用自己的话描述一下人工智能的排列,然后你能不能描述一下外部排列和内部排列的问题,这样人们会更熟悉一些。

艾德:
对。所以粗略地说,人工智能对齐的问题是让人工智能做我们真正希望它做的事情。描述中有很多细节,甚至还有很大一部分对齐问题没有解决,那就是计算描述中还有多少细节需要计算。但是现在人们倾向于像你说的那样,把排列分成两个子问题。有外部排列和内部排列。

埃德:
所以第一个问题是让系统,让这个大人工智能真正尝试做我们想让它做的事情。你可以这样想,我找到了一盏神灯,我摩擦它,一个精灵就出来了。这不是阿拉丁的精灵。这不像是一个很好的精灵想要帮忙什么的。这是一个精灵,它会尽可能地曲解你的愿望。精灵也比你聪明得多。

艾德:
所以你要做的是,你要想办法说出你的愿望,这样你就可以绝对地控制住那个精灵,这样他们就绝对不能以任何有意义的方式曲解你的愿望,他们会说,“啊,我想我要做这件事,因为你让我别无选择。”

Jeremie:
这很有意思,因为你立即把它框定为一件敌对的事情,我认为这本身就很有意思,但这意味着这台机器、这个人工智能或这个精灵试图曲解我们所说的话,事实并非如此,但它确实看起来至少像是在这个领域与你一起工作过很多东西的人,它确实看起来好像在实践中你必须…这几乎像是防御性驾驶。你必须假设,因为这个东西是如此强大,比你聪明得多,如果你正在构建超级强大,超级智能的人工智能系统,它会找到解决你提出的任何问题的解决方案,这将是非常聪明的,这将涉及到你甚至无法想象的事情。这就是这种敌对暗示的来源吗?

艾德:
在某种程度上,是的。我认为最简单的说法是,曲解一个愿望的方法比正确解释一个愿望的方法多得多,你越聪明,就能想出更多的方法来曲解这个愿望。所以你面对的精灵能够想出很多方法来曲解你的愿望,而你会说,“不,不,不。我希望你在其中一个方面正确地解释它。”

杰雷米:
所以我可以给你一个愿望的例子,实际上可能有助于冲洗出来。

是的,是的。比方说,我希望…一些简单的事情,比如我希望快乐或者类似的事情。好吧。你希望快乐。如果你面对的是一个真正想帮忙的人,他有一个人的所有限制,他们会问你你想要什么。我会给你煮一杯咖啡,只要能让你开心就好。但是如果你面对一个超级聪明的精灵,精灵首先会说,“好吧。那么,你怎么定义幸福呢?这里有很多模糊之处。是不是我一直都喜欢笑?”

艾德:
好吧,如果这就是精灵对幸福的看法,它会抓住我的脸,让我永远微笑。很好,它完成了它的工作,但我想,“不,不,不。不要这样做。请停止。”但关键是它不听。它不想听。我已经说过了,让我开心。它认为让我开心意味着让我微笑和更多-

或者任何数量的其他东西,对吗?

艾德:
或者任何数量的东西。

杰瑞米:
可能是让你兴奋的药物,可能是任何……是的。

是的。然后我会给你注射可卡因,或者我会钻进你的头骨,把你的大脑挖出来,然后把你扔进一大桶内啡肽里。这样就行了。但问题是,一旦你给了精灵第一个指令,从这一点来看,它也有动机阻止这个指令的改变,因为它会…它不想…一旦它有了这个指令,它就有了这个目标,它会尽一切努力来实现这个目标。

Ed:
降低目标实现几率的一个因素是,如果精灵自己的目标后来被你改变了。所以如果你能告诉精灵,“哦,实际上,不,不,不。不要做那个笑脸的事情。那真的很吓人。请不要那样做。”这就减少了你开心地微笑的机会。

埃德:
所以精灵,在你告诉它之前停止微笑,但在你告诉它让我微笑之后,就会像这样,“好吧,现在我已经得到了这个指令,我必须防止我的指令被改变,保护我自己免受任何试图改变它的企图,包括刚才让我做这件事的那个人。”所以我最好强迫这家伙闭嘴,或者干脆杀了他,让他笑一笑。开心或者类似的疯狂的事情。这就是我们正在谈论的误解的程度,这就是为什么它是危险的。

杰雷米:
这让我想起了早期的……或者说不是早期。我和电脑的第一次互动,对吧?我想每个人都经历过这一点,当你第一次开始编码时,你会意识到,“伙计,这台机器完全是在带着我。我告诉它做点什么,然后……”我是说,我记得有过这种挫败感。你写一些你认为应该工作的代码。你认为它应该工作,然后你点击运行,然后它中断,并有一个错误信息。你是做什么的?你感到沮丧的不是你自己,而是机器,因为你的大脑在告诉你,“哦,机器搞砸了。我知道我的意思,但机器误解了它。”

杰雷米:
我认为,当人们看到人工智能并开始认为它会是默认的积极结果时,也会犯类似的错误。人们在想象的时候会做很多拟人化的事情,比如,“哦,但是它会明白,我不是指用这种可怕的方式来实现我刚刚要求它做的事情。”或者我不会有一个精灵把我从字面上是假设。无论如何,我觉得这确实反映了我开始学习编程时的态度。这是处理这些问题的一种完全可以理解的方式。

是的。机器本质上没有同情心,除非我们给它同情,而我们对同情的理解还不足以给机器同情。这是问题的一部分,但这是问题的一部分。

好的,好的。因此,我们已经确定,为了让这个高级人工智能做我们想做的事情,训练它并不是一件小事。我是说,那是另一回事,对吧?当你告诉一台机器我想让他们快乐时,有太多的事情需要考虑。我的意思是,几千年来,哲学家们一直试图弄清楚幸福意味着什么,但没有成功,现在,我们将试图量化这一点,完成不确定性,并将其输入机器。

Jeremie:
所以我想这暗示了问题的另一部分。但是假设我们已经过了那个阶段,这就是你所说的,你提到的外部对准问题。那么下一层困难是什么呢?接下来是什么?

艾德:
是啊。下一个问题是所谓的内部排列问题。这更像是你所说的精灵可能由许多内部组件组成,而这些内部组件可能会违背精灵的利益。这很难想象,但也许一个思考拟人化的好方法是,你想到一家公司。比方说,你向一家公司发出请求,而不是一个精灵。让我开心,公司会向你收钱,让你开心,诸如此类。

艾德:
所以这家公司很可能有一种病态的倾向,想让你开心什么的,就像 Twitter 一样。我的意思是,我爱 Twitter,但它确实有这个算法问题。但公司有趣的地方在于,公司是由部分与公司目标一致的人组成的。人们一起工作来完成比公司里任何一个人都要多的事情。但是他们并不是都划向同一个方向。

艾德:
公司内部有些人比其他人更团结。有些人非常相信公司的使命,他们会投入所有需要的时间。他们在同一个方向上雄心勃勃。其他人有各种不同的动机。他们只想在下午 5 点回家看他们的孩子。这是一个动机。那很好。还有其他的动机,比如有些人只是为了他们自己的野心而工作,他们自己想要晋升的野心。他们对公司自身的成功或结果不感兴趣。而其他人就像是在吃白食。他们真的在犯罪,盗用公司的资金,向黑客出售 Twitter 账户,或者类似的疯狂行为。

像这样的人将会是非常非常少的一部分。和整个公司本身,该公司的目标是让他们都保持一致,做同样的事情。但是当我们把这个框架移植到人工智能上时,实际上并不清楚移植到什么程度。尚不清楚如何让人工智能将其内部组件排列在一起。

Ed:
其实也是一样的问题,基本上就是外对齐问题。这就好像精灵本身包含了一群试图解决子问题的小精灵,但这些小精灵可能会反对主精灵,而主精灵会仔细思考它给小精灵的指令。

杰雷米:
那么有哪些可能导致这些……顺便说一下,这些小精灵形成的子问题的例子,对吗?我的意思是,在人工智能排列的语言中,这些是台面优化器。他们通常都是这么称呼的。台面优化器有点像优化器中的优化器。所以你有了这个机器学习算法,然后在它里面有一大堆子问题需要解决,以使整个算法工作。

杰雷米:
如果你在做计算机视觉,对吗?计算机视觉整体问题的一部分是,例如,我不知道,识别棱角,对吗?因此,你可能有一个小台面优化器,一个专门研究边缘,另一个专门研究角落,我猜它们在某种程度上可以有自己的生命。至少这是个问题。在某种程度上,他们这样做,他们想以同样的方式保护自己…我猜这就是你所说的外部排列,对吗?以同样的方式作为外部校准代理,不想被重新编程,它想保留其最初的目的。

杰瑞米:
这些台面优化者不想……一旦他们抓住了他们的子问题,他们就不想改变那个子问题。所以他们拼命想保留自己的结构,对吗?

是的。举个例子,如果你回到精灵,把你的大脑放在一个装有内啡肽的大桶里,精灵,你给它一个指令,比如也许快乐,精灵就像,“哦,我要把他的大脑放在一个装有内啡肽的大桶里。这就是我要做的。”然后它所做的是分配给它的一个子组件,子问题,“好的。为了实现这一目标,我们必须弄清楚许多关于人类神经化学的东西。所以继续努力吧,我们还有一堆其他的子问题。”

那么也许研究人类神经化学的东西有某种形式的思维过程,“哦,哇,伙计,这是个难题。为了解决这个子问题,我需要更多的计算机,比如比我目前拥有的计算能力更强的计算机。”好的,我将把世界上和太阳系和银河系中的许多原子转换成更多的计算机,以确保我真的真的很好地解决了这个解决人类神经化学的子问题,这样我就可以把这个解决方案向上传递给解决大问题的主优化器。

Ed:
哦,就像大的优化器在这里使用计算机,但是我想要那些计算机来解决我的子问题,所以你得到了这种战斗发生。实际上,你可以感觉到类似的事情在你的脑海中发生。所以如果你决定,“嘿,我想吃那边的饼干吗?”这并不像你一生都有一个连贯的损失函数,你试图计算它的期望值。取而代之的是,感觉在你的头脑中有一个完全独立的东西致力于解决一个子问题。

埃德:
所以你的大脑中有饥饿模块在与你争夺控制权,饥饿模块就像是,是的,去吃饼干,但你有一个更高层次的过程,就像是,“哦,等等。这和我不变胖的人生目标或者你的人生目标有什么关系?”感觉你在和自己的一部分抗争。

Jeremie:
对,对。嗯,引入这些优化器后,我们可以做很多事情,但我认为有一件事值得暂停一下,首先,这听起来有点疯狂,这是可以理解的,对吧?我的意思是,我们真的在谈论某种程度上想要接管世界的机器。我认为值得指出的是,至少在某些运营模式下,他们会倾向于…如果他们足够强大,有足够的计算能力,有足够的数据访问权,最终会有这样的野心。

杰瑞米:
这听起来确实很疯狂,但这是一个非常非常好的既定目标……这就是在这种阶段机器学习模型的工具性目标。这至少是非常严肃的研究人员关注的一个问题。我的意思是,这在联盟社区被认为是一个非常严重的问题。我们能谈谈工具性目标的概念吗?什么是工具性目标?你能定义一下吗?

是的。所以你之前说的,基本上,我们认为所有足够聪明的系统或者绝大多数足够聪明的系统都会想要,以某种方式,接管世界,这听起来是一个非常极端的说法。原因就在于这种工具性目标和工具性融合的思想。这个想法是,无论你的目标是什么,都有一些特定的资源和特定的行动是值得采取和抓住的。

埃德:
所以如果你的目标是把我的大脑放进一个大缸里,你看到了,“哦,次优化程序想要更多的计算机来确保它绝对解决问题并把它做好。”那是它的一部分。为了解决一个难题,你需要大量的计算机,当你的能力、你能做的事情没有真正的限制时,你没有理由不把你能得到的整个地球的每一个质量粒子转换成一台计算机。再说一次,在这种东西的概念空间里,没有接近同情的东西。

耶雷米:
你当然可以说这是人类正在尝试做的事情。我的意思是,我们正在尽可能多地将世界转化为计算资源,然后我们部署这些资源来解决我们自己的工具性目标。

艾德:
对。即使这样……我们的能力也是有限的,即使我们同情我们正在杀害的动物,我们正在破坏的树木和环境。不是所有人都这样,但是足够多的人这样做了,我们就像,“嘿,伙计们。我们需要自然保护区、国家公园,诸如此类的东西。”这是因为,我们在某种程度上足够重视这些东西,以至于我们不愿意为了得到它们而彻底毁灭这个星球。

艾德:
但是如果我们的目标函数不同,我们甚至不会在乎那么多。是啊,谁在乎雨林呢?谁在乎这个那个。这也是我们最终要面对的问题。想象一下非洲狮或其他动物面临的困境,这种程度的破坏甚至比我们已经强加给狮子的破坏程度还要严重。无法理解。毫无同情心,完全机械,极具破坏性。

Jeremie:
我的意思是,这是一个关于如何实现回形针优化的著名例子。这个设备被告知,“嘿,做回形针。”没有任何其他背景,它说,“哦,酷。地下有一些铁。你的血液里有些铁。这里有些铁,那里有些铁。它只是从各个地方收集铁,而你制造回形针破坏了这个世界。

酷。所以我想最后一点,我想,关于工具性融合的想法,有一些工具性目标或许多不同的工具性目标,许多人认为是合理的,机器倾向于优化这些目标,作为优化主要目标函数的副作用。你能列举几个吗?我知道你提到了其中的一些,但也许只是为了让人们能看到一些。

艾德:
对。从根本上来说,基于我们今天所知道的物理定律,物质和自由能,你想要东西,你想要果汁来运行它。所以换句话说,把物质放在一起建造大量的计算机,这样你就可以尽可能快和有效地思考,并获取你实际运行这些计算机所需的能源。还有其他工具性的目标,比如生存。

艾德:
一般来说,我可以预测,如果我活下来,我的目标比我死了更有可能实现。大多数情况下。如果我有一套特定的目标,比如如果我继续追求这些目标,这些目标更有可能实现。所以自我保护是这些工具性子目标之一,目标凝聚力或目标保护也是一个工具性子目标。

Ed:
如果我还活着,但我脑中的目标发生了变化,那么我之前的目标也不太可能实现,因为在我的目标发生变化后,我将不再为之努力。所以我要设法阻止我的目标被改变。

埃德:
至少如我们所料,我们基本上只有一次机会来设定正确的目标,因为如果我们像这样,“哦,不,不,不,等等,等等,”那么大概系统会像这样,“哦,不,等等,等等。我明白了。我明白了。我已经有了这个目标,我会去完成它。”

我认为这在某种程度上反映了…如果我错了,请纠正我。也许你倾向于人工智能结盟辩论中的一个阵营。所以有一个阵营说,“伙计们,我们只有一次机会。我们必须确保我们的目标是正确的。”还有另一个阵营说,“伙计们,我们应该专注于健壮性制作模型,考虑到他们追求的目标的不确定性,并努力做到可修正。”换句话说,在这个意义上,邀请修正和健壮。我只是想指出两者之间的区别,因为它是生态系统的两个分支。这么说公平吗?

是的。在这些领域,争论开始变得有点技术性。我会说,这两个方向都是可行的,当然,在我们制造出某种超级邪恶的精灵来摧毁世界之前,可能会有一些阶段,我们肯定希望更多地处于学习模式,而不是“啊,我得到了这个完全正确的模式”,这样我们就可以实际上看起来像,“好吧,什么样的系统是相当智能的,也许是危险的,但不一定是瞬间毁灭的?给了他们一套指令后,他们会做什么?有没有什么方法可以让他们接受扳动开关让他们停下来?诸如此类的事情。

Jeremie:
爽。好吧。因此,在奠定了这一基础之后,我认为这将会……嗯,对于熟悉人工智能对齐生态系统的人来说,这可能是旧闻,但对于从上一系列中加入我们的人来说,这可能是新东西,在上一系列中,我们正在做更多关于数据科学职业生涯的东西。我想做的一件事是,因为你和我已经谈了很多关于台面优化。我认为梅萨优化者这个概念非常有趣的一点是,它确实给了我们一个非常有趣的视角,关于人类是什么,生命是什么,宇宙到底是什么,我想探索一下,如果你不介意的话,就在这里发表一些我们的私人谈话。这是我想邀请你参加播客的部分原因。你不介意吗?

艾德:
是的,当然。

杰雷米:
好的,很好。所以我想也许我在试着想一个问题来开始我们的讨论,但也许我会提供一个框架,你可以从那里开始。因此,我们已经讨论了宇宙中的每一种生物都可以被视为台面优化者的观点。所以本质上正在发生的是宇宙有一大堆原子,它有一大堆光子,粒子各种不同的自由度,它在运行这个实验。

杰瑞米:
这是关于粒子随机重组的训练。所以你会看到粒子之间的相互作用,这种相互作用会随着时间的推移而持续,随着时间的推移,粒子的混杂会趋向于复杂系统的自我组装。无论宇宙的最终状态是什么样的,看起来我们都在朝着越来越复杂的方向发展,以至于人类不会把自己消灭掉,以至于我们实际上生存到了创造一个自我改进的人工智能系统的程度。

杰瑞米:
看起来我们真的是在朝着智能爆炸的方向前进,就像人们所说的那样。在这个框架中,我们在这里与我们周围的所有其他台面优化者竞争。因此,我们想要访问…就像你说的,你已经有了专门了解人类神经化学的台面优化器,这样就可以解决将你的大脑放在一个内啡肽大桶中的整体问题。人类,专注于解决在生存和繁衍中成为真正的好人的问题。也许我会把这个想法放在那里。

艾德:
这是一个很好的开始。我们和世界上所有其他动物和生物一样,我们都在一个进化我们的巨大优化器里,对吗?所以进化是一个大的过程,试图把我们推向遗传适应性。我们的进化方向是相对于人口数量有更多的孩子。增加你在下一代的基因表达。这是我们进化的方向。

埃德:
有趣的是,尤其是最近,人类似乎真的没有很好地遵循这个指令。如果我们真的遵循了那个指令,如果我们真的像这样,“好吧。我想要尽可能多的孩子,相比之下……”我们的行为会大不相同。例如,我们不会使用节育措施。我们可能不会使用避孕套。相对于生育率下降之类的事情,我们会有更多的孩子。

艾德:
所以这是出了问题的信号。在缓慢的优化压力和我们正在做和学习做的事情之间有一些不匹配的地方。我们被饥饿、性欲、恐惧、愤怒等欲望所驱使。所有这些都与我们的包容性基因适应性有很长一段时间的关联。这些都是非常复杂的适应。它们进化了数百万年。

埃德:
许多与我们无关的动物,可能会像动物一样感到恐惧,诸如此类。所以有些事情正在发生。在某种意义上,进化告诉我们该做什么,而我们自己的内在驱动告诉我们该做什么,两者之间的距离越来越大。我们的内驱力能够以进化的方式来满足这些内驱力,如果它是一个人,就会像这样,“嘿,哇。那是病态的。

艾德:
你们这些家伙在这里做错事了。你对你的饥饿做了太多的优化。你越来越胖,没有孩子。这是什么?你对你的性冲动做了太多的优化,用避孕套做爱,你没有孩子。

杰雷米:
从进化的角度来看,进化就像人类试图获得正确的代码和人工智能,这样它就不会偏离轨道,现在发生的是进化程序让你生一大堆孩子,然后你开始看色情片,而不是变得饥渴,与人做爱和生孩子,进化会说,“哇,哇,哇。我不是这个意思。你不能这样作弊。”

艾德:
这是关键。进化实际上并没有让我们生孩子,而是找到了一种更简单的方法。进化就像,“哦,如果我把这些小致动器放在我的东西上,有机体就会想出如何从那里生孩子。”问题是,当生物体变得非常非常聪明时,它会想出如何在不做进化想要它做的事情的情况下满足这些欲望。

杰雷米:
它基本上超越了最初的损失函数。所以你提到进化想要人类做的和人类最终实际做的之间越来越明显。我认为探索日光的来源是值得的,因为我的意思是,如果我错了,请纠正我,基于我们的谈话,我认为我们在这一点上是一致的,但我认为这归结于计算能力。最终,有机体能够运行比进化本身更多的计算。

Jeremie:
你基本上能够…你有足够的计算能力,自然选择不是改变你的主要因素。现在,改变你的主要是你自己的思维,你自己的认知能力。因此,在人的一生中,如果你像水牛或其他动物一样,你实际上可以改变自己,比进化所允许的要多得多。

艾德:
是啊。我认为这与内部和外部反馈信号的密集度和稀疏度有关。有多少个处理步骤-

你能详细说明一下吗?这里的密疏是什么意思?

所以进化给了你一个非常稀疏的健康信号。它发出一个健身信号,就像是,每 20 或 30 年发生一次。你有孩子吗?他们有孩子吗?每二三十年。你在生孩子之前就死了吗?这是一个非常聪明的信号。它不喜欢经常打你的脸,但当它打你的脸时,它会狠狠地打你。然而,你自己的内部过程,让你…在那 30 年的时间跨度里,你可能会,天啊,我甚至不知道可能,我不知道,你会饿,天知道一天三次,或者在 30 年里成千上万次。

杰瑞米:
你撞到了手肘,擦伤了膝盖。

是的。就这样,就这样。因此,在进化压力信号的脉冲之间,你有一定的自由度来适应你自己的大脑信号。所以它的工作方式是进化在你自己的信号排列方式上提供反馈压力。所以进化管理着你有多饿之间的平衡。你有多饥渴?你有多生气?你有多开心?所有这些事情。进化在几十年的时间尺度上做到了这一点。但是在你的大脑中,你对这些信号有一套安排,你在内部优化和处理的时间尺度比那要快几万到几百万倍。

艾德:
结果,你有空间以一种进化无法解释的方式超级关注那些信号。我们的处理能力现在太强了,无法被这些信号所控制。很快我们就有可能直接改变我们自己的 DNA,完全脱离我们自己。

艾德:
我们仍然是进化的奴隶,但是从进化的角度来看,这些畸形的病态奴隶不再是进化的直接奴隶,而是进化创造的笨拙的东西的奴隶。

杰雷米:
嗯,你从进化的角度来说很有趣,对吗?但是进化当然是进化产生的东西。我是说,从定义上来说,我们就是目标。所以对我来说,这正是…嗯,基本上,这是外部对齐问题,在这个宇宙中有一些东西正在被优化。这显然不是生物进化。这就是优化的目的。直到今天大约有 140 亿年的时间。但在过去的几十万年里,人类已经开始分离,随着我们的认知能力在进化想要我们做的事情和你所说的进化给我们反馈的时间线以及我们能够从环境中获得反馈的时间线之间创造了日光,人类开始分离。

杰雷米:
这绝不是过程的结束,对吗?这就是把我们带回人工智能讨论的原因。这里有一个额外的步骤,我们转移基底,不再在生物硬件上运行计算,而是在硅基底而不是细胞上运行计算。在这种情况下,你开始放松许多限制,这些限制使人类与机器相比慢得令人难以置信,我们可能会在更短的时间内完成同样的范式。

是的,没错。所以计算机的一个问题是,是的,它们现在快多了。就计算的连续深度而言,它们似乎比我们快得多。换句话说,我做这个,然后我做那个,然后我做那个。他们能一个接一个做的事情的数量,他们比我们快得多,就其切换基因和测试新生命形式的能力而言,他们比我们快得多。

埃德:
因此,你可以打个比方,“哦,我造了这个东西,它比我快多了。”我给它这些笨拙的,粗略定义的目标,这些目标一开始和我的目标有很好的关联,但后来它优化,优化,再优化。它变得越来越聪明。而且非常非常快,也许能够以一种我不知道的方式满足我给它的课程目标。我想,“哦,我的上帝。我不是这个意思。停下停下停下。但到那时,我们就不在乎了。进化可能对我们有同样的想法,但我们并不在乎。我们做我们想做的。

耶雷米:
是的。正如相对于人类生活的步伐,进化似乎停滞不前一样,相对于这种人工智能的进化步伐,人类生活似乎也停滞不前。我是说,不管是什么形式。所以我的意思是,我认为这是一个很大的支持你之前的论点,我们有一个机会来做好这件事。我想这也是我们开始关注这个领域,或者人工智能开始兴起的时间领域的一个担忧,越来越多的进展正在取得,越来越多的通用系统正在建立,像 GPT3 这样的东西,但不仅如此。我们很快就会得到越来越先进的系统。

Jeremie:
我们开始进入这个领域,在这里我们受到想要设计程序的最没有人工智能安全意识的公司的支配。我的意思是,这真的是人工智能政策的领域,你开始说,“好吧,你如何让博弈论在这里工作?”你如何防止一些愚蠢的公司决定说,“哦,我不是特别关心人工智能对齐。我不担心这个。”你如何阻止他们朝这个方向采取一些非常不负责任的行动?我知道这可能不是你的领域,但你对人工智能政策方面的博弈论有什么想法吗?

埃德:
嗯,是的。因此,从经济角度来看,有很多关于人工智能民主化的讨论,这很好。我认为这在某种程度上是好的。当你开始谈论这些非常,非常大,非常有能力的系统时,它们开始潜在地呈现危险,不仅仅是它们可能接管世界,而且危险在那之前很久就存在了。它们可能会被某些人滥用来发送大量精心制作的垃圾邮件或各种新奇的风险。

艾德:
所以,it 的经济学原理是,你越接近垄断,你的业务就有越多的利润。在这里,我谈论它就好像它是一个生意,因为这些模型是作为 API 和所有这些东西来销售的。

Jeremie:
我们说的利润越多,实际上就是利润越多。

艾德:
这也是我的部分意思。当我说保证金时,保证金可以变成利润。它完全可以盈利,到目前为止,它可以盈利,但也可以安全。可以去安全投资。所以当你是一个垄断者时,假设你收取 50%的利润。收入的 50%归你所有,你可以用它们做任何你想做的事情。是的,你可以把它们用在你的资产负债表上,比如,“哦,现在,我有更多的钱了。那太好了。”

Ed:
但你要做的另一件事是让他们保证你的系统安全,这需要越来越多的投资。拥有一个广泛竞争的环境,销售大量不同的型号,其中一个问题是,当他们相互竞争时,每家公司每种型号,他们竞争他们的利润。在资本主义,这通常被视为好事。这很好,因为这意味着消费者支付的费用减少了。

艾德:
如果一家公司很卑鄙或邪恶,我可以换另一家公司,这样对每个人都更便宜。在一个有潜在危险的系统的情况下,你想要的是一个垄断,把所有的利润预算都花在安全上,而不是有太多有限的利润,他们互相竞争,所以他们不能把钱花在安全上。这可能是一个有风险的安排。

耶雷米:
是的。我看到过关于什么的争论…这叫多极还是单极。基本上,有多少不同的极点,多少不同的公司或组织拥有活跃的人工智能成果或尖端的人工智能成果,以及这如何影响风险格局?我看到有人认为多极可能更可取。我个人倾向于你刚才讨论的方向。我知道我们已经谈了很多了。我认为另一个很有说服力…哦,对不起。你想加点什么吗?

Ed:
我只是想说,如果你有一个完全致力于安全的组织,资金充足,并且对所有其他公司正在建设的东西有很大的内部透明度,你也许可以实现多极化。这可能是一种可行的方法,但至少在目前的情况下,这似乎很难做到。

耶雷米:是的。我知道开放人工智能,将一项政策工作放在一起研究,基本上就像朝着一种更透明的方式发展组织内部的人工智能。这背后的博弈论很大一部分是信任。如果你是谷歌,你正朝着一个超级强大的 AGI 努力,这可能是危险的,脸书告诉你,他们也在努力,你们都向对方声称,你在安全方面投入了很多努力,以确保没有可怕的事情发生。

Jeremie:
你应该在多大程度上相信另一家公司正在发生这种情况,他们不会拿走所有的利润,让你更快地开发产品。

艾德:
这是一个很好的场景。这是两家文化上一致的公司,经常交换员工,基本上位于海湾地区的同一地带。他们在很多方面都是非常相似的公司,当你与来自不同国家的公司打交道时,信任情况会发生什么变化呢?这些公司说的不是同一种语言,从未交换过员工,拥有不同的政府结构和根本不同的价值体系。在这种情况下,建立信任变得非常不同,也更加困难。

耶雷米:
是的。我的意思是,也许最恰当的类比是,这取决于你怎么理解。因此,人们,尤其是那些主张多极的人一个常见的论点是集中在超级强大的系统和当今系统之间的更中观的领域,他们说,“看,人工智能有被部署到武器系统的风险。”现在,你有多极可能是好的,因为谁知道如果只有一个国家拥有核武器,而没有其他国家可以与它们相互摧毁,从而确保没有人会发射核武器,冷战会如何展开。也许类似的事情也会发生在 AI 身上。我认为有令人信服的理由说明为什么情况并非如此,或者至少我过去是这样认为的。但是,对不起。

埃德:
我认为这基本上是资本主义关于竞争的论点,在我们到目前为止所看到的所有情况下,竞争是一件好事。许多不同的组织拥有相似的技术,这是件好事。他们互相竞争,互相制约,等等。这可能会继续适用于人工智能,直到一定的能力水平,但我怀疑会有一个能力水平,超过这个水平,安全投资变得比能力投资更重要。在这一点上,你基本上需要很大的余量来保证安全。所以某种等同或同构于垄断的安排。

耶雷米:是的。我的意思是,当然我们看到桌面生物武器或生物工程设计病原体将很快成为现实。核武器也是一样,对吗?我的意思是你到了一个点,好吧,是时候停止公开发布结果了。我认为开放人工智能本身是他们的功劳,至少从我的角度来看是这样……他们为此打了很多旗号。他们站出来说,“看,随着我们开始接近越来越大的能力,我们将不得不开始把我们的一些工作放在内部,而不是广泛地发布。”

Jeremie:
他们已经越来越谨慎了,我们从 GPT2 那里听说,这是他们朝着那个方向迈出的第一步。现在 GPT3 完全是内部的。没有一个是公共领域。它不仅仅是一个开源模型。无论如何,观察这个领域如何演变和发展将会很有趣。显然,这个领域的任何决策都有很多争议。我认为,考虑到利害关系,关键的事情之一是真正瞄准那些你我都看到的非常好的政策,因为我们已经与从政策制定者到人工智能比对研究人员的每个人进行了接触。

杰瑞米:
如果你在这个领域不小心,很容易做出弊大于利的举动。所以我想我想做的是以对正在听的人的呼吁来结束这次谈话。如果你对人工智能排列、人工智能安全之类的东西感兴趣。如果你觉得我们在这里讨论的风险很有吸引力,很有意思,那就去看看我们在视频描述中提供的博客文章的一些链接,因为有很多组织你可能想去看看你有什么选择,你可以在哪里做出贡献,但是从什么是好的角度来看事情, 在意想不到的变化下,什么可能真的弊大于利,因为当你谈论尖端技术时,事情可能会以令人惊讶的方式出错。 无论如何,我想说的是,因为我们自己也遇到了一些这样的问题。

艾德:
对。我认为这很有道理。这是第一种无害的东西。这是一个希波克拉底誓言,我想在更大的范围内,但我认为这是第一个努力的方向,就像是,“我们如何才能避免不良后果的发生,并让每个人都保持良好的状态?”

耶雷米:
太棒了。好吧。艾德,我真的很感激。我想我们要做的是,在所有这些东西的描述中,我也会链接你自己的个人网站。有什么想分享的吗?我想你介意分享你的推特吗,这样人们就可以关注你了?

艾德:当然,没错。我是@neutronsNeurons 或者神经元中子。我真的忘了。抱歉伙计。

我想…哦,糟了。我们会,链接到它。

中子神经元。我是@neutronsNeurons。所以你可以打电话给我,然后在那里关注我。

太棒了。好吧。非常感谢,艾德。我真的很感激。很棒的谈话。

谢谢你邀请我。

杰瑞米:
我的荣幸。我们会让它离线。干杯。

艾德:
干杯。

储蓄中的情感和习惯

原文:https://towardsdatascience.com/emotion-and-habit-in-savings-d628be965bfd?source=collection_archive---------39-----------------------

首次探究木星关于储蓄行为的丰富数据

pixabay.com

是什么让人们储蓄更多?

这个问题与普通人、金融技术专家、资产管理公司、银行和政策制定者息息相关。这是木星试图解决的核心问题,我们将定期分享我们所学到的东西。有些人可能认为这有风险,但我们相信开放性和我们的执行能力,所以我们愿意承担风险。

我们仍处于非常早期的阶段,所以我们的样本并不庞大,但它是非常精细的,包含了数百个实验。所以这将是几篇文章中的第一篇。总结其三个要点:

  • 情感:如果你给人们储蓄带来直接和即时的回报,即使很小而且主要是情感上的回报,你会大大增加他们对未来提示做出反应或提出储蓄的机会,你会使他们更有可能成为经常储蓄者。
  • 习惯:一个人是否会对储蓄的提示做出反应的最强有力的预测因素是他们之前积极储蓄的频率,也就是说,自发(如果被提示)储蓄已经成为一种习惯的程度。我们相信这不仅仅是获得了先前存在的特征。
  • 什么不起作用:令人惊讶的是,与情绪和习惯因素相比,金钱奖励的大小没有影响。一个月中的某一天确实很重要,但是比我们预期的要少得多。此外,如果执行得好,诱导主动习惯要比说服人们进行自动被动储蓄容易得多,而且通过创造情感承诺和培养习惯,可以在以后产生显著的积极溢出效应。

数据

木星关心用户隐私。因此,我们的数据湖不包含用户的人口统计数据(只有一个单独的反欺诈系统包含)。除了 Jupiter 应用程序之外,它也不包含任何关于用户财务生活的信息。

我们所拥有的是关于 Jupiter 用户行为的极其丰富的匿名数据——在上线的几个月里,大约每个用户有 1000 个数据点,有近 1000 个活跃的储户。

在这些数据点中有超过 300 个实验的结果,这些实验使用信息和提示来诱导人们存更多的钱。这些实验涉及 20 多个维度,包括六种不同的游戏、社交暗示、奖励大小、反应时间、措辞、渠道等等。因此,我们的样本仍然局限于一个维度,但来自一个系统,该系统旨在捕捉运行实验中的行为、速度和变化的特殊粒度。

模特们

木星试图让人们存更多的钱。我们的方法与采取行动紧密相连。所以我们建立了两个机器学习模型来预测:

  • ***立即存钱:*如果我们现在给你一个给定的“奖励”——玩游戏(有奖品)的机会、直接奖励、一定量的忠诚度积分——你有可能在接下来的 24-48 小时内存钱(固定在目标余额或目标存钱金额上)吗?
  • ***节省频率:*如果我们为你提供一些内容、提升和其他关注的组合,你会成为一个更频繁的节省者吗?

目前,我们使用的模型是相当标准的回归器和增强的树木/森林(抱歉违反了“假装你有疯狂惊人的人工智能模型”的创业宣传代码——如果你现在还不知道,99%的模型是一个可能只有 5 行的笔记本,包括“ import sklearn ”)。

我们在我们的完整数据上训练模型,经过一点清理,例如,移除内部用户,并排除板载增强和消息(因为出于这个目的,我们对用户后来的行为感兴趣)。这些模型达到了 0.7 的精确度水平,低于简单的任务或具有巨大数据集的任务,但高于脸书的仇恨言论标记。

结果呢

在训练模型之后,我们使用“ SHAP(ley)值和决策树重要性分数来理解不同特征的相对重要性。“特征”意味着用户的一些特征——他们打开 Jupiter 应用程序的次数,或者他们打开帐户的时间,或者他们最后一次保存的时间,等等。重要性分数和 SHAP 值然后告诉我们,“这个特定特征对这个预测有多大影响?”

在预测模型上,当训练为梯度增强树时:

  • 在之前,用户保存了多少次的功能重要性得分为 5**
  • 用户在过去要求提升的次数有多少,特性重要性得分为 4
  • 这个月的某一天——我们对最有可能发生的事情的假设(想想发薪日)——仅排在第三位,得分为 2
  • 没有其他功能比这些更重要。

有些是我们没有预料到的。事实证明,货币回报与所需储蓄规模的比率 根本没有特征重要性。支付的原始金额也是如此。我们还没有测试极端值——很有可能微小的支出或极端的储蓄-支出比率会产生影响。但我们大约一半的提升已经在 AUM 上以 1%的费用洗了脸,即储蓄::奖励比率超过 100(通常通过使用游戏锦标赛和其他“前 N”类型的提升来实现)。

因此,在一个合理且成本有效的奖励范围内,用户之前获得情感回报的频率,以及有多少储蓄正在成为一种习惯,对他们是否能被诱导再次储蓄最重要。

这是针对时间点建模的。当我们转向频率模型,即预测用户是否会随着时间的推移而变得有价值时,我们有类似的结果。为此,我们根据储蓄频率将用户分为五类,然后使用他们其他非储蓄行为的频率,该模型预测每个用户属于哪个类别。我们发现:

  • 总的来说,三个主要的预测因素是:用户兑换 boost 的频率,用户打开 Jupiter 应用程序的频率,以及他们是否赢得了锦标赛游戏。没有其他特征是接近的。
  • 当我们深入研究最高频率类别的预测因素时,我们发现同样的模式在重复,尽管还有一个特征:用户使用应用内消息的频率
  • 几个月前,我们花了很大力气说服用户设置自动定时保存。我们只有不到 10 个人。在频率最高的类别(每月 3 次以上储蓄)中,我们有 90 多次储蓄者(约 10%),在次高类别(每月约 2-3 次储蓄)中还有 120 次。

这里的一个问题可能是,我们是否只是在寻找一些先天的、隐含的特征,即“高度倾向于储蓄”。如果我们有一个更精简的数据集,并以更少的方式使用它,我们会更不自信。但是:

  • 我们无论如何也想不出存钱的癖好会以某种方式导致某人在触屏游戏中赢得锦标赛
  • SHAP 值在重要特征上非常不对称,即未保存对增压响应的负面影响远不如保存为正面影响
  • 不清楚为什么在查看频率类别时,原始的应用程序参与人数会很重要(一个“重度节省者”只会在他们想要节省时打开应用程序,而不是一直打开,或者至少可能会这样做)
  • 如果预先存在的储蓄倾向占主导地位,我们希望看到用户形成一小部分清晰分离的集群,这很容易通过终生储蓄来预测。我们发现了相反的情况(后面会有更多的介绍)。
  • 如果我们添加或删除预先存在的保存和之前的 boost 兑换,精确度会改变约 0.1,这是一个很大且有意义的变化,但不会大到怀疑标签被泄露。
  • 最后,结果与我们的定性体验相符——用户评论说,“这让我爱上了存钱”,当我们最近做了一组简短但深入的用户调查时,用户愿望清单中的重点不是自动存钱功能或原始回报,而是与提升相关的功能。

未来地

未来还有更多值得探索。我们才刚刚开始理解用户行为的聚类。

当我们运行 K-means 时,我们找到了大约 8-10 个簇的最佳数量,但是我们仍然需要理解那些簇是什么(简单的低维表示的投影不是直接直观的)。我们还将询问随着时间的推移行为的微小变化,以及储户之间联系的任何见解(通过 Jupiter 的“储蓄伙伴”功能)。

与此同时,我想说的是,与之前的情感联系相比,“理性”的支付比率是如此的无关紧要,这让我们感到非常惊讶。我们几乎同样感到惊讶的是,一旦人们有了情感联系并对这一行为有所放松,他们会比建立自动化的、被动的投资更容易进行无计划的、自发的储蓄。

几十年来,改善金融安全的整个理论和实践一直专注于让人们变得善良——从他们的储蓄中建立一个自动扣除,当他们看到他们的余额时,每年有一点情感回报。这并没有改变任何地方的储蓄率。也许是时候换个思路了?

新冠肺炎期间情绪高涨

原文:https://towardsdatascience.com/emotions-soaring-during-covid-19-emotion-detection-over-100-million-tweets-c2820c718f4e?source=collection_archive---------59-----------------------

超过 1 亿条推文的情感检测

我通过我之前发布的情绪检测神经网络运行了 1 亿条与 COVID 相关的推文。我不会试图解释这些结果背后的原因,因为这是一个充满相关性的领域,Twitter 的美国偏见,当然还有一个非常复杂的系统。然而,一些非常有趣的模式出现了!此外,很明显,这种算法可以用于解决其他问题:一种通用的方法,可以自动检测 Twitter 上针对特定主题的情绪变化,这可能具有强大的商业应用。

在你看到观想之前,有一些快速注释:

  • 每种情绪都有一个“截止点”——你只能看到每种情绪图表的上半部分。这显示了推特上展示的过度的情绪。这些情绪一年到头都在发生,只是少于年平均水平。
  • Twitter 非常以美国为中心。美国用户比其他国家的用户多得多。以及比大多数人更高的死亡率。这就是为什么我在底部添加了美国新冠肺炎死亡率的数字。

作者图片

人们首先可以看到 Twitter 经历的清晰的情绪阶段。随着美国发布居家命令,短暂的困惑和娱乐很快被关心、恐惧和感激所取代。随着事情开始陷入混乱,我们开始看到一些沉重的负面情绪:愤怒、烦恼、尴尬、失望,甚至更糟:越来越厌恶。许多这些情绪可能是那些因拒绝认真对待危机而感到羞耻的人的结果。

其次,两极分化的情绪是一件事!也许特别是在像美国这样的两党制民主国家,或者是像 Twitter 这样用来表达观点的平台。这在两种相互冲突的情绪中显而易见:“赞同”与“不赞同”通常是相互关联的,除了在五月初。然后发生了什么?同样,恐惧和感激似乎是相互关联的。

相对而言,所有情绪中最强烈的是困惑和感激。困惑的早期峰值绝对有意义,但人们只能对感恩做出理论。例如,也许暑假已经到来,人们在春天呆在家里后,真的不认为这个夏天是理所当然的!

那么,我们能从中学到什么呢?

从全球福祉的角度来看,随着现实的到来,情绪在过去几个月中明显变得更加消极:世界(几乎以任何方式)都没有准备好面对这样的全球疫情。除了一些赞同之外,推特上没有任何压倒性的积极情绪模式。是个发泄的地方。所以,当你进入 Twitter 的回音室时,明智地这样做吧!这是一个愤怒的地方。上网的时候要照顾好自己,记住世界的情绪不好。除此之外,我不建议从数据显示的相关性中得出任何强有力的结论。

从技术角度来看,请看下面提供的源代码。这种类型的 twitter 情绪检测可以应用于其他事情,并实现自动化。想看到人们对某个标签的态度发生变化吗?当情绪转向你的公司或运动队时,你想接电话吗?用 CNN 和 Twitter 的 API 实现自动化。在此基础上应用一些简单的异常检测,以提醒您公关灾难,甚至是随着全球情绪的转变投资特定领域的机会。

更多信息:技术警告

  • 一些可以被神经网络检测到的情绪从未真正出现过峰值——比如“欲望”和“爱”。我已经把他们排除在观想之外了。
  • 我没有通过这个模型运行完整的一亿条推文——我从每天的 2000 条推文中随机抽取了一些英文推文。
  • 我的神经网络是在 reddit 数据集上训练的。由于不同的人口统计数据和每个平台的典型用途,情绪检测结果会略有不同。
  • 这些推文被预选为与新冠肺炎相关的推文。因此,这些并不是整个世界的情感,而只是那些与以新冠肺炎为中心的标签结合起来表达的情感

更多信息:代码和数据

代号: GitHub 。这段代码并不打算开箱即用:您需要使用类似 Hydrator 的东西自己获取 tweets。如果您的 python 版本与我的不同,神经网络 pickle 可能无法加载。

数据 : 新冠肺炎死亡率

数据 : 新冠肺炎推文

利用数据科学留住员工

原文:https://towardsdatascience.com/employee-retention-using-machine-learning-e7193e84bec4?source=collection_archive---------32-----------------------

蒂姆·莫斯霍尔德在 Unsplash 上的照片

雇佣和留住顶尖人才是一项极具挑战性的任务,需要资金、时间和技能。小企业主将 40%的工作时间花在不产生任何收入的任务上,比如招聘新员工。

在本文中,我们将实施数据科学技术来改善人力资源部门。

我们将预测公司中哪些员工更愿意离开公司。

因此,在本案例研究中,我们将了解以下几点。

  1. 员工为什么要离职?
  2. 他们为什么想留下来?
  3. 怎样才能让他们有动力?

还有更多…:)

我们已经从 kaggle.com 获得了将用于本案例研究的数据集。

以下是相同内容的链接:https://www . ka ggle . com/pavansubhasht/IBM-HR-analytics-attraction-dataset

我们知道 Python 是一个非常有用的数据分析工具。我们将用它来回答上述问题。

你可以在我的 GitHub 上获得完整的 python 代码:https://GitHub . com/Tariqueakhtar/Machine-Learning/tree/master/HR _ Department _ Solution

让我们直接从数据中获得一些见解。

数据汇总

我们的数据总共包含 35 个特征,每个特征有 1470 个数据点

总共 35 个特征,每个特征包含 1470 个数据点(图片由作者提供)

让我们看看有多少员工离开了公司!

16%的员工离开了组织(图片由作者提供)

16%的员工离开了组织。

深入挖掘数据后,我们得到了以下发现。

1。年龄与流失分析

年龄与损耗(图片由作者提供)

29 岁和 31 岁的人离开公司的频率更高。虽然 18 至 23 岁年龄组的雇员人数较少,但该年龄组的自然减员率也很高。此外,随着年龄的增长,离开公司的机会减少。

2.婚姻状况与摩擦

婚姻状况与摩擦(图片由作者提供)

与已婚和离异员工相比,单身员工更倾向于离职

3.工作角色与自然减员

工作角色与人员流失(图片由作者提供)

与其他工作相比,销售代表和实验室技术员更倾向于离开。

4.工作投入与流失

工作投入与流失(图片由作者提供)

参与度较低的员工往往会离开公司。如果你注意到 job incidence = 1,那么与该类别下的总人口相比,它的自然减员更多。

5.经验与损耗

有经验与损耗(图片由作者提供)

经验不足(工作级别低,即工作级别=1)倾向于离开公司。

6.离家的距离与损耗

有经验与损耗(图片由作者提供)

远离办公室(超过 10 公里)的人更有可能离开公司。你可以注意到,在 x 轴 10 点之后,红线在蓝线之上,即离家的距离。

7 .。现任经理任职年限与自然减员

现任经理的几年与自然减员(图片由作者提供)

与现任经理相处时间短的员工更有可能离开公司。您可以注意到,x 轴起点的红线在蓝线之上,即现任经理的年数。然而,随着我们增加年数,蓝线倾向于取代红线,这意味着当你超过 4 到 15 年时,实际倾向于留在公司的员工数量多于实际离开公司的员工数量。

8.总工作年数与自然减员

总工作年限与自然减员(图片由作者提供)

在公司工作时间较短(0 至 6 年)的员工往往会离开公司。您可以注意到,在 x 轴的起点,即总工作年限,红线在蓝线之上。然而,当你超过 6 年,你会发现蓝线倾向于取代,这意味着员工倾向于留在你增加总工作年限。

9。性别与月收入

性别与月收入(图片由作者提供)

你可以看到,男性和女性的平均工资几乎相当,这实际上是一件好事。

对于任何公司来说,性别薪酬平等都是至关重要的事情。实际上,通过观察箱线图,似乎这里的女性实际上比男性得到的报酬更多。

10.M 月收入与工作角色

月收入与工作角色(图片由作者提供)

上面的方框图显示,担任经理的员工往往得到更多,这显然是有道理的。看起来,如果你是研究科学家和实验室技术员,这两种工作的工资范围几乎是一样的。

如果你做的是销售代表的工作,与经理和研究主管相比,你的收入要少得多。人力资源也介于两者之间。

结论:

您可以看到使用不同图表和可视化的数据分析如何帮助获得许多问题的答案。

这种分析将有助于公司制定一些员工政策,并在需要时进行修改。即便如此,这也将有助于制定一些新员工参与计划,帮助员工呆得更久。

参考:https://www . ka ggle . com/pavansubhasht/IBM-HR-analytics-attraction-dataset

[## 2020 年雇佣一名员工的真实成本

雇佣一个人到底要花多少钱?雇用一名员工的成本远不止是简单地输出…

toggl.com](https://toggl.com/blog/cost-of-hiring-an-employee)

感谢阅读!!!

员工流失 Catboost 和 Shap 如何帮助您了解它!

原文:https://towardsdatascience.com/employees-attrition-how-catboost-and-shap-can-help-you-understand-it-814f9bfd7df4?source=collection_archive---------24-----------------------

了解 Scikit 和 Catboost 模型的使用如何帮助您处理不平衡的数据集,以及为什么 SHAP 是解释人工智能预测的伟大工具。

劳拉·戴维森在 Unsplash 上的照片

如何同时探索和解决两个关键问题?

  • 第一种和就业一样古老:人们决定离开他们的雇主去寻找更好的工作。)工作。
  • 第二个出现在过去几年:能够以一种可以理解的方式解释极其复杂的人工智能模型是如何做出预测的。

为了探究这两个问题,我们需要一些工具和数据:

  • 由于没有公开共享的关于员工辞职的真实数据集,我们将使用 IBM 数据科学团队创建的数据集来推广 Watson。在 Kaggle 这里有。
  • 本文使用的代码和笔记本(文末链接)是用 Google Colab 创建的。这对开发人员来说是一个很好的资源,免费提供 GPU 和 TPU 访问,以及最新的 Python 库和在需要时安装“外来”包的可能性。
  • Google Colab 确实嵌入了很多 Python 包,但是我们需要安装 CatBoost (我们的分类器)和 SHAP (我们的解释器):
!pip install shap
!pip install catboost

数据探索

在导入这个用例所需的库之后,我们可以观察到数据集由 1470 个条目组成,其中有 9 个分类特征和 25 个数字特征。

import pandas as pdfrom imblearn.under_sampling import ClusterCentroids
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrixfrom catboost import CatBoostClassifierimport shap# The following lines should be used only on Google Colab
# to connect to your Google Drivefrom google.colab import drive
drive.mount('/content/drive')

第 9 列“EmployeeNumber”对于每个雇员都是唯一的,因此我们将使用它作为我们的 Pandas 数据框架的索引。在读取 CSV 文件时,由于“index_col=9 ”,此指令得以通过:

df = pd.read_csv("./WA_Fn-UseC_-HR-Employee-Attrition.csv", **index_col=9**)df.info()

整个数据集中没有缺失的信息…这显然是一个合成的数据😅。

在我们进入建模阶段之前,我建议做一些改进:

  1. 让我们创建两个字典,根据它们的基数(0,1,2)将“是/否”列转换为“0/1”和旅行频率类别。
yes_no_to_0_1_dict = {"Yes": 1, "No": 0}
business_travel_dict = {"Non-Travel": 0,"Travel_Rarely": 1,"Travel_Frequently": 2}df = df.replace({"Attrition":yes_no_to_0_1_dict})
df = df.replace({"OverTime":yes_no_to_0_1_dict})
df = df.replace({"BusinessTravel":business_travel_dict})

2)“employee count”、“StandardHours”和“Over18”列是稳定的(即列中有一个唯一值),我们可以简单地删除它们,因为它们不会给模型带来任何有用的信息。

df.columns[df.nunique()==1]**Index(['EmployeeCount', 'Over18', 'StandardHours'], dtype='object')**df = df.drop(["EmployeeCount","StandardHours","Over18"], axis=1)

机器学习算法无法处理分类特征,因此我们还需要借助 pd.get_dummies() 指令将它们转换为数值向量:

df = pd.get_dummies(df)# This instruction can be used before and after the use of
# get_dummies to see changes on the dataset
df.filter(like="Marital").sample(10, random_state=22)

" df.filter 的结果(like = " Marital ")。sample(10,random_state=22) 【前后】PD . get _ dummies()

大多数员工会在雇主那里呆一段时间,辞职率很低,但结果是,在收集减员数据时,你会比离职者获得更多关于员工的信息…

df["Attrition"].value_counts()Attrition
0    1233
1     237
Name: Attrition, dtype: int64

只有 16%的数据集对应于已经离开公司的员工,这显然是一种“不平衡”的情况。为什么这是一个问题?

这里的主要风险是,算法更有可能推断出从多数类继承的模式,而感兴趣的类通常是较小的一个(例如:癌症诊断、垃圾邮件或欺诈检测、员工流失等。).

分类器的默认优化度量通常默认设置为“准确性”(=正确预测/总预测),但是,对于不平衡的数据集,无用的模型仍然可以实现非常高的准确率。

例如,让我们考虑一个用不平衡数据集(10 000 封邮件中的 100 封垃圾邮件)训练的垃圾邮件检测系统。如果该模型试图最大限度地提高其准确性,它最终可以预测所有的电子邮件为“非垃圾邮件”,这将导致 99%的准确性…但您将无法检测到任何垃圾邮件!

对于此用例,建议考虑的优化指标是“召回”,因为它将评估对人群中实际上已经辞职(真阳性)的人的检测:

回忆=真阳性/(真阳性+假阴性)

模型培训—第一轮

创建我们的训练和测试数据集后:

X = df.drop("Attrition", axis=1)
y = df["Attrition"]X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=22)

我们训练我们的模型,而没有关于不平衡情况的任何特定预防措施:

model = CatBoostClassifier(iterations=500,verbose=100,eval_metric="Recall")model.fit(X_train, y_train)

让我们显示培训和测试阶段的困惑矩阵:

我们可以观察到召回率的真正下降,在训练和测试阶段之间从 90%下降到 19%!

模型训练—第二轮(使用班级权重)

向模型“教导”它需要更加关注少数群体的一种方式是引入“类权重”。

由于这种方法,当模型未能检测到真正的肯定(离开者)时,我们可以给模型分配更强的惩罚。因此,我们指定 1:5 的比率,这意味着错误的辞职检测惩罚将比错误的员工检测惩罚重 5 倍:

class_weights = dict({0:1, 1:5})model = CatBoostClassifier(iterations=500,verbose=100,eval_metric="Recall",class_weights=class_weights)model.fit(X_train,y_train);

再次使用混淆矩阵,我们可以看到模型预测的真正改进,因为测试数据集上的召回分数从 19%增加到 39%,而准确性保持稳定:

模型训练—第 3 轮(使用欠采样)

另外两种方法可以完成类权重的使用:

1/过采样少数类

第一种方法依赖于诸如 SMOT(合成少数过采样技术)之类的技术,其中基于现有的少数类生成新数据。

例如,在一个非常简化和“一维”的方式,SMOT 创造了新的个人,把他们放在少数阶级点之间的“连接线”上。

SMOT 方法:初始不平衡人口

SMOT 方法:新生成数据的表示

2/欠采样多数类

假设许多员工都有相同的个人资料(例如:已婚男性,在会计部门工作 20 年以上,辞职率极低)。减少他们代表的数量来帮助模型理解辞职的真正影响参数是否有意思?当然!这正是欠采样技术所能提供的。

在本例中,我们将使用“ClusterCentroids”方法,该方法将:

1 -在多数类中创建聚类,其中个体具有相似或相近的属性

2 -用相应的质心替换每个聚类的个体。

cc = ClusterCentroids()X_cc, y_cc = cc.fit_resample(X, y)X_train, X_test, y_train, y_test = train_test_split(X_cc, y_cc)

再次使用混淆矩阵,我们可以观察到训练和测试阶段的召回率现在都是 100%,这意味着在多数类中有许多具有相同特征的个体,现在被他们的质心所代替:

注意:该模型的“卓越”表现是由于我们正在处理合成数据,这些数据比真实数据随机性更小。

用 SHAP 解释预测

现在我们有了一个关于真阳性检测的健壮模型,从人力资源的角度来看,理解为什么模型认为一个雇员有很大的可能性辞职或不辞职将是有趣的。

定型模型上的“feature_importances_”属性是在宏观级别上了解哪些参数对预测起着重要作用的最直接的方法。

Scikit 学习文档 所述:“一个特性的重要性被计算为该特性所带来的标准的(标准化)总缩减。这也被称为基尼系数。”

feat_imp = pd.DataFrame(model.feature_importances_, index=X.columns, columns=["Importance"])feat_imp.sort_values(by="Importance", ascending=False).head(15)

模型的 15 个 mot 影响参数

然而,它并没有指出每个参数对估计概率有正面还是负面的影响…这种影响也可能因每个样本的特征而异。

这就是最初创作于 2017 年的 SHAP(SHapley Additive explaints)进入游戏的地方!

SHAP 已经被设计,使用博弈论,以确定什么是模型中每个功能的边际贡献。如果您想进一步研究其计算机制,快速搜索数据科学将回答您的所有问题。

他们在使用 SHAP 时有许多好处,这里举几个:

1/你可以为每一个人找出在预测中起最重要作用的参数:

# Overall calculation of the SHAP model and values
shap_explainer = shap.TreeExplainer(model)
shap_values = shap_explainer.shap_values(X)#
Employee_ID = 1shap.initjs()
index_choice = df.index.get_loc(Employee_ID)
shap.force_plot(shap_explainer.expected_value, shap_values[index_choice], X.iloc[index_choice])

上图中显示的重要信息有:

  • 基值(3.362) 代表员工辞职的平均概率。这是模型中所有参数的平均贡献。我们可以把它当作一个基线。
  • 个体值(5.31) 代表员工#1 离开公司的概率,高于基线(又名“基础值”)。
  • 红色参数显示哪些特征使员工更有可能离职:没有股票期权计划、定期加班、单身等。参数离单个值越近,它们在预测中的作用就越大(图表上每个参数的宽度也提供了这种“重要性”信息)。
  • 蓝色参数解释了她档案中的哪些元素降低了辞职的可能性:在当前职位上 4 年,与同一位经理共事 5 年,等等。

现在让我们看看员工 2。由于高绩效评级、股票期权计划以及在同一位经理手下工作了 7 年,他的辞职概率“低于平均水平”( 3.10 )。

2/您可以显示整个群体(按个人相似度、辞职概率或原始排序排序)

shap.initjs()
shap.force_plot(shap_explainer.expected_value, shap_values, X)

3/你可以专注于某个具体特征的影响。下面的图表显示,年轻确实增加了辞职的可能性,直到一个人到了 40 岁,年龄开始发挥相反的作用。

4/并且明显地比较所有参数的各自贡献:

在我们结束这篇文章之前,有一些评论:

  • 像往常一样,模型的稳健性将高度依赖于输入数据的质量。掌握相关的、最新的、有背景的员工信息将有助于你更好地理解辞职因素。
  • 第 3 轮中的完美回忆分数是由于员工的档案是通过公式和算法创建的,这使得他们很容易预测另一种算法!即使我们可以确定员工离职的趋势,这仍然是每个人的复杂决策过程,可能没有数据集可以完全捕捉到!

那都是乡亲们!😀

使用过的完整笔记本储存在这里的 Google Colab/Drive 上。

[## 皮埃尔-路易·贝斯康德关于媒介的文章

数据科学、机器学习和创新

pl-bescond.medium.com](https://pl-bescond.medium.com/pierre-louis-besconds-articles-on-medium-f6632a6895ad)

按行业和城市分列的就业增长趋势:数据研究

原文:https://towardsdatascience.com/employment-growth-trends-by-industry-and-city-a-data-study-5002bf20692?source=collection_archive---------32-----------------------

根据劳动统计局的报告,就业市场继续增长。然而,无论是在国家层面还是在地方层面,并非所有行业都以同样的速度增长。这份报告(由美国社区调查的 2017 年县商业模式数据集提供支持)考察了最大的大都市区顶级就业部门的就业增长情况。

这里有一些高层次的见解, 但是到这里来使用我的免费 Tableau 仪表板,进一步了解不同的行业、领域和其他就业趋势

按城市/大都市区划分的最集中行业( 查看仪表盘 )

哪个行业的单位面积雇佣人数最多?

当观察每个顶级市场的顶级行业时,医疗保健和社会援助部门占据了市场的最大份额,包括占大费城地区的 19.3%。有几个主要地区与这一趋势不同,如华盛顿 DC 和圣何塞,专业、科学和技术服务分别占所有工作岗位的 21%和 13%)。住宿和餐饮服务占圣地亚哥就业的 14%,奥兰多的 16%。

按地区划分的最集中行业(与全国平均水平相比)( 查看仪表盘 )

与全国平均水平相比,一个行业在一个地区的就业集中度如何?

现在,我们将某个行业在该地区的就业集中度与该行业的全国平均就业水平进行比较。

软件出版在多个主要市场中被过度指数化,在旧金山(+高于全国平均水平 380%)、圣何塞(+622%)和西雅图(+597%),软件出版就业超过全国平均水平 380%。大学是匹兹堡(+187%)和圣路易斯(+106%)指数最高的行业。波士顿(+269%)和费城(+225%)的投资组合管理指数过高。与此同时,DC 和巴尔的摩的计算机系统设计服务指数过高(分别为+485%和+276%)。

分行业就业增长( 查看仪表盘 )

在全国范围内,哪些行业增长最快?

根据这组数据,在过去的五年里,总就业率增长了 9.3%。某些部门的增长一直高于平均水平。当看全国总数时,专业贸易承包商(+27%)、建筑(+25%)和餐馆(+20%)出现了大幅增长。与此同时,废物管理(-1.6%)和行政服务(-2.1%)在过去 5 年中有所缩减。对于食品行业来说,这也是一个不错的五年,食品服务和饮料场所(+19.6%)、全方位服务餐馆(+15.5%)和有限服务餐馆(+24.7%)的就业人数连续五年增长。

行业就业增长高于或低于全国平均水平的地理视图( 查看仪表板 )

Color: Green = Area 的部门工作比例高于美国平均水平。红色=该地区的部门工作比例低于美国平均水平

区域气泡尺寸基于区域(所有行业)的员工总数

我将在下面展示几个主要行业作为例子, 但请到这里使用我的免费 Tableau 仪表盘来进一步了解不同的行业、领域和其他就业趋势

健康护理

在最大的市场中,东北部的医疗保健就业指数过高,但密西西比以西的主要市场的医疗保健就业指数往往偏低。

信息

只有少数市场的信息就业指数过高,但它分散在全国各地。然而,中北部市场(包括芝加哥、明尼苏达、底特律和克利夫兰等主要地区)在该行业中指数偏低。

零售业

在全国范围内,零售贸易几乎完全在最大的市场中指数化不足,而在较小的市场中指数化过度。

制造业

与信息中的地理趋势相反,芝加哥、明尼苏达、底特律和克利夫兰等主要中北部地区的制造业工作指数过高,而沿海主要市场(佛罗里达以外)的制造业工作指数往往过低。

建设

西部、中部和南部地区的建筑业就业指数往往过高,而东北部地区的集中度较低。

感谢您阅读我最新的数据帖子。作为一名产品营销和数据分析专业人士,我对数据支持的讲故事充满热情。这些数据新闻帖子是我将真实数据与我个人的不同兴趣整合起来的方式,这些兴趣包括从旅行和娱乐到经济和社会问题的任何事情。
如果您有任何评论、故事想法或预期的数据项目,请随时发送电子邮件至 dwpwriting <邮箱至> gmail < dot > com,访问我的网站至
【dwpeterson.com,或通过LinkedIn联系我。

通过 BigQuery 和 Data Studio 实现苹果移动趋势报告

原文:https://towardsdatascience.com/empowering-apple-mobility-trends-reports-with-bigquery-and-data-studio-1b188ab1c612?source=collection_archive---------35-----------------------

让我们为苹果移动报告的数据提供超级动力:世界各地的决策者已经在使用 BigQuery 和 Data Studio 来应对当前的危机。借助本文中的工具,我们将帮助他们充分利用这个数据集和我们的工具。

更新 2020 年 4 月 24 日:分步视频

查看我与Yufeng的实时聊天,了解使用 Data Studio 进行 BigQuery 的最佳实践:

样本结果

这个数据集的官方苹果仪表盘显示了这样的结果:

在这里,我们将构建一个 Data Studio 仪表板,在这里我们可以看到如下所示的相同数据:

Data Studio 仪表盘

你可以看到:

  • 趋势噪音更小(7 天平均值)。
  • 突出显示国家和城市的地图。
  • 显示数据摘要的表格,包括每个地区流量减少 25%以上的第一天。
  • 允许您可视化其他交通类型(驾驶、公交、步行)的交互式控件。

请注意我对这些图表中曲线的所有分析仅供我们娱乐。对于世界各地正在发生的事情的真正建议和分析,去找一个真正的公共卫生专家。这篇文章的目标是我们如何充分利用现有的工具,这样我们就可以帮助领域专家完成他们的工作。#负责任地

比较新加坡、东京、米兰、旧金山和纽约

仪表板

  • 在这 5 个城市中,米兰是第一个在苹果移动性报告中大幅下降的城市:2 月 28 日。
  • 新加坡的跌幅更早(2 月 9 日),但远没有米兰大。直到 3 月下旬和 4 月,政府才不得不采取更严厉的措施。
  • 东京的交通流量并没有明显下降——只是在 4 月初情况恶化后,曲线才下降。
  • 旧金山和纽约表现出相似的曲线,旧金山在步行方面领先纽约 5 天,在开车方面领先纽约 2 天。

比较美国城市

  • 旧金山和纽约有相似的曲线(旧金山几天前放弃了)。
  • 西雅图、芝加哥和迈阿密有相似的曲线。
  • 亚特兰大的交通流量比其他城市下降得少。

交通流量没有大幅下降的城市

一些城市没有看到任何有意义的(7 天平均值<75%) drop in traffic.

We can see some of these cities here (with San Francisco for comparison):

Latin America vs Barcelona

仪表盘

  • 巴塞罗那的下跌比拉美其他城市更早(3 月 15 日)也更深。仍在进行中。
  • 你可以看到布宜诺斯艾利斯对拉美的反应最强烈。
  • 圣地亚哥、布宜诺斯艾利斯和圣保罗在同一天下跌了 25%以上:3 月 19 日。
  • 哥伦比亚表现出最不深刻的反应(但你应该考虑到我们在这里是把城市比作一个国家)。
  • 墨西哥城是最后一个做出反应的城市:3 月 20 日。
  • 圣地亚哥和圣保罗正在引领“恢复正常”。这将如何获得回报?

让我们回顾一下这是如何建立的。

背景

在分享这个数据集的过程中,苹果做了一些伟大的事情:

  • 你可以看到世界各地的城市和国家是如何应对危机的。您可以将这些数字与实际措施和案例进行比较,看看反应的效果如何。
  • 他们发布每日 CSV,同时为任何寻求快速结果的人提供一个交互式仪表盘。

[## COVID-19-移动趋势报告-苹果

COVID-19 国家/地区和城市的移动趋势。报告每天发布,反映对…的要求

www.apple.com](https://www.apple.com/covid19/mobility)

改进的机会:

  • 我们希望将该数据集与其他表连接起来。谷歌的公共数据集项目已经在 BigQuery 中收集了越来越多的新冠肺炎相关数据集。
  • 他们的官方仪表盘显示了很多日常噪音。我们可以用 7 天平均值来代替吗?
  • **可以用 SQL 对城市进行排名吗?**例如,哪些城市是第一批颁布居家政策的城市?哪些城市还没有这样做?哪些城市出现了明显的政策反弹?
  • 我们能让地理信息更清晰吗?每一行仅通过城市名称来标识地理位置——这在我们需要地理定位数据时没有帮助。我们可以用一些 SQL 来改进这一点。
  • 找到下载每日 CSV 的网址并不容易。
  • 他们的数据不整齐。每天拥有一个专栏并不是处理数据集的最佳方式,因此需要进行一些清理。我之前的帖子展示了如何用 SQL 中的逆透视 UDF 来改进这些表。

[## 如何用 SQL 和 BigQuery 将多个列拆分成整齐的一对

这篇文章是写给任何在 CSV 中处理时间序列的人的,每天都有一个新的专栏。处理整齐的数据是…

towardsdatascience.com](/how-to-unpivot-multiple-columns-into-tidy-pairs-with-sql-and-bigquery-d9d0e74ce675)

操作方法

( github 回购最新)

在 BigQuery 中加载和更新每日文件

使用一些curljq魔法——因为没有直接的方法来获得下载 url:

x=$(curl -s [https://covid19-static.cdn-apple.com/covid19-mobility-data/current/v1/index.json](https://covid19-static.cdn-apple.com/covid19-mobility-data/current/v1/index.json))
url=$( echo [https://covid19-static.cdn-apple.com`jq](https://covid19-static.cdn-apple.com`jq) -n "$x" |jq -r '.basePath'``jq -n "$x"|jq -r '.regions."en-us".csvPath'
`)
curl -s $url -o /tmp/latestAppleCovidData.csv
bq load --autodetect --replace fh-bigquery:temp.latestAppleCovidData /tmp/latestAppleCovidData.csv

转换成整齐的数据

CREATE OR REPLACE TABLE `fh-bigquery.public_dump.applemobilitytrends_initial`
OPTIONS (description="[https://www.apple.com/covid19/mobility](https://www.apple.com/covid19/mobility)"
) ASSELECT geo_type, region, transportation_type, unpivotted.*
FROM `fh-bigquery.temp.latestAppleCovidData` a, UNNEST(fhoffa.x.cast_kv_array_to_date_float(fhoffa.x.unpivot(a, '_2020'), '_%Y_%m_%d')) unpivotted

转换成整洁的数据,并添加有用的列

CREATE OR REPLACE TABLE `fh-bigquery.public_dump.applemobilitytrends`
OPTIONS (description="[https://www.apple.com/covid19/mobility](https://www.apple.com/covid19/mobility)"
) ASWITH data AS (SELECT geo_type, region, transportation_type, unpivotted.*, LEAST(-1 + value/100, 0.2) percentFROM `fh-bigquery.temp.latestAppleCovidData` a, UNNEST(fhoffa.x.cast_kv_array_to_date_float(fhoffa.x.unpivot(a, '_2020'), '_%Y_%m_%d')) unpivotted
), annotated_data AS (SELECT *, -1+EXP(AVG(LOG(1+percent)) OVER(PARTITION BY geo_type, region, transportation_type ORDER BY daterows between 6 preceding and current row)) avg7day , geo_type||transportation_type||region series_idFROM data
)SELECT *, ROW_NUMBER() OVER(ORDER BY current_percent) rank 
FROM (SELECT *, (SELECT percent FROM annotated_data WHERE a.series_id=series_id AND date=(SELECT MAX(date) FROM annotated_data)) current_percent, (SELECT MIN(date) FROM annotated_data WHERE a.series_id=series_id AND avg7day<-.25) first_drop_date FROM annotated_data a
)

这个查询中有一些有趣的技巧:

  • OVER(... rows between 6 preceding and current row)的 7 日移动平均线。
  • 使用-1+EXP(AVG(LOG(1+percent))代替传统平均值的平方平均值来舍入异常值。
  • 一些值在前一天大幅跃升至 100%以上。我们用LEAST(-1 + value/100, 0.2)统治他们。
  • 带有自连接的子查询得到第一天的流量低于基本流量的 75%。
  • 我们用geo_type||transportation_type||region创建了一个系列 id,以便于自连接。

重要注意事项

为什么苹果会允许访问这些数据?

根据他们的使用条款:

当新冠肺炎被世界卫生组织定义为疫情时,您可以使用本网站上提供的移动趋势报告,包括对其的任何更新(统称为“苹果数据”),但仅限于协调对新冠肺炎公共卫生问题的回应(包括公共政策的制定)所合理需要的时间。

确保阅读他们页面上的全部条款。我写这篇文章的目的是帮助任何使用苹果发布的数据的人协调和改善他们社区对这场危机的反应。世界各地的许多团体已经在为此目的使用 BigQuery 和 Data Studio,在这里我尽我所能为他们节省时间并获得更好的结果。

#负责任地

在创建任何新的与新冠肺炎相关的仪表板之前,请确保阅读Amanda Makulec在您创建另一个关于新冠肺炎的图表之前的十个考虑事项:

[## 在你创建另一个关于新冠肺炎的图表之前,要考虑十点

总结一下——# viz responsible;这可能意味着根本不在公共领域发布你的可视化。

medium.com](https://medium.com/nightingale/ten-considerations-before-you-create-another-chart-about-covid-19-27d3bd691be8)

交互式仪表板

查看互动数据工作室仪表盘。

后续步骤

待定:

  • 一个很好的连接来消除城市和国家的歧义。
  • 与其他数据集的有趣连接。

了解我的 Data Studio 和 BigQuery 最佳实践

太平洋标准时间周五中午,YouTube 直播。了解一些使用 Data Studio 和 BigQuery 的最佳实践。跟我一起作为嘉宾上郁风 G 节目的:

[## 与玉凤一起冒险-与 Felipe Hoffa 一起生活:使用 Data Studio 和 BigQuery

在这次冒险中,裕丰虚拟主持费利佩·霍法(应大众要求回来!)探索 Data Studio 集成…

www.meetup.com](https://www.meetup.com/Live-with-Google-Cloud-Developer-Relations/events/270186183)

(太平洋标准时间中午 12 点,美国东部时间下午 3 点,伦敦时间晚上 8 点)

想要更多吗?

查看谷歌的公共数据集项目,其特色是在 BigQuery 中收集了越来越多的新冠肺炎相关数据集:

[## 新冠肺炎免费公共数据集|谷歌云博客

数据在调查、研究和应对突发公共卫生事件的能力中始终发挥着至关重要的作用

cloud.google.com](https://cloud.google.com/blog/products/data-analytics/free-public-datasets-for-covid19)

我是 Felipe Hoffa,谷歌云的开发者倡导者。关注我 @felipehoffa ,在medium.com/@hoffa找到我之前的帖子,在reddit.com/r/bigquery找到所有关于 BigQuery 的帖子。

[## 维基百科中冠状病毒的语言-可视化

通常我会写更长的帖子,但是今天让我给你一个快速的指引。先看看我是如何提取数据的…

towardsdatascience.com](/coronavirus-interest-inwikipedia-by-language-1b3e6562040d) [## 如何用 SQL 和 BigQuery 将多个列拆分成整齐的一对

这篇文章是写给任何在 CSV 中处理时间序列的人的,每天都有一个新的专栏。处理整齐的数据是…

towardsdatascience.com](/how-to-unpivot-multiple-columns-into-tidy-pairs-with-sql-and-bigquery-d9d0e74ce675)

用 IBM Watson AutoAI 增强公民数据科学家的能力

原文:https://towardsdatascience.com/empowering-citizen-data-scientists-with-watson-autoai-49a087df99e5?source=collection_archive---------57-----------------------

利用人工智能来自动化机器学习任务并增强模型生命周期管理

为什么我们需要关心 AI 自动化?

过去几年数据科学领域最重要的发展之一是自动化人工智能(AutoML)解决方案,它使业务分析师和 IT 专业人员能够在很少或没有数据科学编码经验的情况下执行复杂的机器学习活动。AutoAI 通过在数据科学和人工智能项目中使用人工智能自动化来完成关键的机器学习任务,使数据科学家能够更快、更有效地开展项目。

最近的统计数据显示,尽管机器学习和数据科学社区对角色的需求激增。Kaggle & KD Nuggets 上 50%的数据科学家受访者表示,他们在 ML 方法方面的经验不足 2 年,编码经验也是如此。

使用机器学习方法有多少年的经验?来源:KD 掘金调查

Auto AI 提供自动特征工程、模型验证、模型调整、模型选择和部署、机器学习可解释性、时间序列和模型评分的自动管道生成,为公司提供可扩展的可定制数据科学平台,满足各行业各种用例的需求。

特征工程是高级数据科学家用来从算法中提取最准确结果的有力武器。Auto AI 采用一套算法和特征转换来为给定数据集自动设计新的高价值特征。

吴恩达已经在特征工程中引入了自动化人工智能的概念

“到 2020 年,公民数据科学家的数量将比专家数据科学家的数量增长快五倍。组织可以使用公民数据科学家,在一定程度上填补数据科学家短缺和高成本导致的机器学习人才缺口。”

**资料来源:Gartner:**10 大战略技术趋势

Watson Studio 中的 AutoAI 工具会自动分析您的数据,并为您的预测建模问题生成定制的候选模型管道。这些模型管道是在 AutoAI 分析数据集并发现最适合您的问题设置的数据转换、算法和参数设置时迭代创建的。结果显示在排行榜上,显示根据问题优化目标排列的自动生成的模型管线。

AI 设计 AI

人工智能自动化可以改变业务流程的工作方式。神经网络和机器学习算法可以说是数据科学家目前可用的最强大的工具。然而,虽然只有一小部分数据科学家拥有从头创建高性能神经网络所需的技能和经验,但同时需求远远超过供应。

因此,即使在概念验证阶段,大多数企业也很难快速有效地获得一种新的神经网络,这种网络在架构上是定制设计的,以满足其特定应用的需求。因此,通过为给定数据集自动设计神经网络架构来弥合这一技能差距的技术正变得越来越重要。

深度学习(depth)在神经网络中的进化来源:IBM

AI 优化 AI

使用人工智能设计和优化人工智能模型为人工智能技术的发展带来了一种新的和急需的能力。例如,复杂网络的参数调整可能非常耗时,容易出错,并且可能无法随时间和资源而调整。神经网络的规模和复杂性不断增长,因此有必要自动化最佳参数选择的过程,以确保机器学习过程以准确和最佳的方式生成预测结果。

使用 AutoAI 优化神经网络参数来源:IBM

艾治艾

60 %的公司认为监管约束是实施人工智能高效和自动化政策的障碍。无需昂贵的数据科学资源,在生产应用中手持多个人工智能模型:

1.当涉及到模型 验证时,如果人工智能模型符合法规并且将在部署之前实现预期的业务成果,将会面临多重挑战

2.难以跟踪和测量部署下的业务成功指标。

3.持续业务监控和合规性的资源密集型和不可靠流程

4.业务用户不可能将微妙的领域知识反馈到模型生命周期中

Watson AutoAI 的功能

  1. 自动化数据准备

大多数数据集包含不同的数据格式和缺失值,正如我们所知,大多数标准的机器学习算法都没有缺失值。AutoAI 应用各种算法或估计器来分析、清理和准备用于机器学习的原始数据。它根据数据类型(如分类或数值)自动检测和分类特征。最重要的要求之一是变量缩放,以确保大多数变量被同等缩放,并减少机器学习偏差。根据分类,它使用超参数优化来为您的数据确定缺失值插补、特征编码和特征缩放的最佳策略组合。

2。自动化特征工程

特征工程试图将原始数据转换成最能代表问题的特征组合,以实现最准确的预测。AutoAI 使用一种独特的方法,以结构化、非穷举的方式探索各种特征构造选择,同时使用强化学习逐步最大化模型准确性。这导致数据转换的优化序列,最匹配模型选择步骤的算法。

IBM Watson Studio 中的自动 ML 演示

3。超参数优化

超参数优化流程优化了最佳性能模型 bia 算法管道。AutoAI 使用一种新颖的超参数优化算法,针对机器学习中典型的模型训练和评分等代价高昂的函数评估进行了优化。这种方法能够快速收敛到一个好的解决方案,尽管每次迭代的评估时间很长。

4。自动型号选择

下一步是自动选择与您的数据匹配的模型。AutoAI 使用一种新颖的方法,能够针对数据的小子集对候选算法进行测试和排序,逐渐增加最有希望的算法的子集大小,以达到最佳匹配。这种方法在不牺牲性能的情况下节省了时间。它能够对大量候选算法进行排序,并为数据选择最佳匹配。

Titanic 数据集中的模型管道比较来源:IBM

IBM 的人工智能开发自动化战略

1。转移学习

迁移学习 (TL)是许多深度学习应用的重要组成部分。迁移学习是机器学习(ML)中的一个研究问题,它专注于存储在解决一个问题时获得的知识,并将其应用于另一个不同但相关的问题。例如,在学习识别汽车时获得的知识可以应用于识别卡车。

这主要是由于深度学习系统中训练产品的规模;它们非常庞大,需要大量的资源。有许多预先训练的模型可用于各种平台和任务,如 MobileNet、Tensorflow 的 Yolo 等。

2。神经网络架构搜索

神经架构搜索(NAS)只是自动化管道的一个组成部分,旨在找到合适的架构来训练深度学习模型。这种搜索本身是一项计算密集型任务,已经引起了深度学习社区的极大兴趣。

因此,在神经结构搜索方法的发展中出现了热潮,给该领域留下了许多竞争的选择,很少或没有对已开发的方法进行整合,并且缺乏帮助从业者选择适当方法的指南。在我们的调查中,我们通过对现有景观的极其彻底的分析来解决这一差距。我们提供了一种形式主义,它统一了大量的现有方法,并批判性地检验了不同的方法。这清楚地强调了有助于神经架构搜索的设计和成功的不同组件的好处,同时也揭示了当前架构搜索趋势中的一些误解。

强化学习中的神经架构搜索来源:IBM

3。模型管道优化&部署

当 AutoAI 生成模型时,有两个不同的视图,通过它们可以直观地显示这些管线的创建进度。它们是进度图和关系图,如下图所示。您可以看到,AutoAI 已经选择 XGB、随机森林和决策树分类器作为这个用例中性能最好的算法。在数据预处理之后,AutoAI 识别前三个执行算法,并且对于这三个算法中的每一个,AutoAI 生成以下管道:自动模型选择(管道 1)、超参数优化(管道 2)、自动特征工程(管道 3)、超参数优化(管道 4)。

图显示了这些管道之间的关系图来源:IBM

每个模型管道都根据各种指标进行评分,然后进行排名。二元分类模型的默认排名度量是 ROC 曲线下的面积,多类分类模型的默认排名度量是准确度,回归模型的默认排名度量是均方根误差(RMSE)。排名最高的管道显示在排行榜中,因此您可以查看有关它们的更多信息。排行榜还提供了在查看后保存精选模型管道的选项。

渠道排行榜来源:IBM

免责声明: 此处表达的部分观点仅代表本文作者的观点,不一定代表 IBM 公司的观点。部分内容。博客上的是版权和所有权利保留-但是,除非另有说明-根据 IBM 公司。

模拟具有长短期记忆的 PID 控制器:第 1 部分

原文:https://towardsdatascience.com/emulating-a-pid-controller-with-long-short-term-memory-part-1-bb5b87165b08?source=collection_archive---------19-----------------------

使用温度控制实验室创建比例-积分-微分控制器数据

亚历山大·波波夫在 Unsplash 上拍照

你曾经对一个想法感到非常兴奋吗?也许这是你正在处理的一个新的 DIY 项目,或者是工作中一个很酷的任务。也许你和我一样疯狂,想要徒步穿越太平洋山顶小径(因为我很快就要搬到西雅图,所以我忍不住对飞往圣地亚哥然后步行回家的想法感到兴奋)。嗯,这个项目对我来说是其中一个想法,我希望你喜欢这个旅程!

在我开始之前,我想提醒你这是一个相当广泛的项目,所以我把它分成几个部分。它们将如下:

  1. 使用温度控制实验室创建比例-积分-微分控制器数据(本文)
  2. 在 Keras 中训练一个长短期记忆神经网络,以模拟 PID 控制器
  3. 用 LSTM 控制温控实验室
  4. 用 LSTM 控制器代替 PID 控制器进行温度控制的实际应用

项目框架

有一天,在做一个工作项目时,我看到一篇介绍了一个新颖想法的论文。一些研究人员有想法使用神经网络来模拟模型预测控制(MPC)策略的行为。这个想法是,一些 MPC 问题在计算上非常昂贵,但是行为是可预测的;**如果我们可以通过训练深度神经网络来模拟这种行为,那么理论上,我们可以用更快的机器学习模型来取代计算量大的 MPC。**该过程中唯一计算量大的部分是模型训练。

最棒的是,我在办公桌前测试了这个想法。温度控制实验室被完美地设计成这种问题的原型。我在之前的一篇文章中介绍了 TCLab 和一些基本的异常检测,你可以用机器学习来做这些。如果你是对外汉语实验室的新手,你可以看看我的文章,或者看看 APMonitor.com的丰富资源。

所以我决定尝试一下:我想调整一个比例-积分-微分(PID)控制器,这样我就可以在 TCLab 上设置一个温度,控制器会调整加热器,直到它达到设定值。然后,我想看看我能否用一个长短期记忆神经网络来模拟这种行为。如果这个原型成功了,它将不仅为提高计算速度打开大门,也为异常检测等应用打开大门。

这个系列是关于机器学习的,所以如果你不熟悉 PID 控制器或控制理论,那也没关系;我们将重点介绍几个亮点,以便您了解背景。在 APMonitor.com有一些惊人的资源可以帮助你理解 PID 控制器以及如何调整它们。这些控制器在工程行业中无处不在,因此其潜在应用非常广泛。

PID 控制器概述

韦斯利·廷吉在 Unsplash 上拍摄的照片

控制系统无处不在。想想你的恒温器:你所要做的就是输入温度,不知何故,它知道什么时候打开和关闭暖气,以保持你的房子在那个温度(当然,除了房间总是一个冰盒……)。它是怎么做到的?控制系统可以分为三个部分:传感器(读取房间温度的东西),执行器(打开冷气或热气的空调或炉子),控制器(恒温器中的计算机,是操作背后的大脑)。传感器数据输入控制器,然后控制器告诉执行器做什么。

PID 控制器无处不在是有原因的:它们简单明了且极其有效,尤其是当与一个一阶加死区(FOPDT)模型配对时。在我们的 TCLab 中,它将温度设定点和温度传感器之间的差值(在下面的等式中表示为 e(t ))作为输入,并输出一个加热器值(下面标记为 output,或 OP ),使温度接近设定点。顾名思义,有一个比例,积分和导数部分。

K_c、τ_I 和τ_D 称为调谐常数,决定控制器的行为。您可以 g 为您的 TCLab 生成阶跃响应,然后以图形方式获得 PID 控制器的调谐参数。对于我的 TCLab,一些有效的调优参数是 K_c = 6.0、τ_i =75.0 和τ_d = 0.0。您的可能会有所不同,因为每个 TCLab 的行为略有不同。现在让我们来看看 PID 控制器的代码。我放在函数pid(sp,pv,pv_last,ierr,dt)里了。

第一部分是加载您的调优参数和其他常数:

# PID Parameters
Kc   = 6.0
tauI = 75.0 # sec
tauD = 0.0  # sec# PID coefficients in terms of tuning parameters
KP = Kc
KI = Kc / tauI
KD = Kc * tauD# OPbias for controller (initial heater)
op0 = 0# upper and lower bounds on heater level
ophi = 100
oplo = 0

然后,我们要计算设定值(sp)和温度(也称为过程变量,pv)之间的误差:

# calculate the error
error = sp - pv

积分部分通过数值计算,将之前的误差与当前的时间步长误差相加:

# calculate the integral error
ierr = ierr + KI * error * dt

最后,控制器的导数部分(也是数值计算)如下所示:

# calculate the measurement derivative
dpv = (pv - pv_last) / dt

现在将所有这些放在一起,我们可以计算 PID 输出(op):

# calculate the PID output
P = KP * error
I = ierr
D = -KD * dpv
op = op0 + P + I + D

最后,为了确保我们考虑了 0 到 100 之间的加热器限值,我们添加了一个防复位饱和条件:

# implement anti-reset windup
if op < oplo or op > ophi:I = I - KI * error * dt# clip outputop = max(oplo,min(ophi,op))

那还不算太糟!如果没有别的,你学会了如何编程一个 PID 控制器功能,这是非常有用的工业控制器。

从 PID 控制器生成数据

现在我们需要在 TCLab 上实际运行 PID 控制器。我们将设置几个数组来存储数据,并运行控制器 90 分钟,以确保我们有足够的数据。我们将间歇性地改变温度设定值,这样我们就能很好地混合稳态和瞬态行为。以下是我的设置:

##### Set up run parameters ###### Run time in minutes
run_time = 90.0# Number of cycles
loops = int(60.0*run_time)# arrays for storing data
T1 = np.zeros(loops) # measured T (degC)
error_sp = np.zeros(loops) # Setpoint error
Q1 = np.zeros(loops) # Heater values
tm = np.zeros(loops) # Time# Temperature set point (degC)
with tclab.TCLab() as lab:Tsp1 = np.ones(loops) * lab.T1# vary temperature setpoint
end = 30 # leave 1st 30 seconds of temp setpoint as room temp
while end <= loops:start = end# keep new temp set point value for anywhere from 4 to 10 minend += random.randint(240,600) Tsp1[start:end] = random.randint(30,70)

画出你预期会发生的事情从来都没有坏处。在 90 分钟的过程中,我们打算让 PID 控制器设置加热器,使温度遵循以下曲线:

作者的情节

我们都准备好了!在我写的另一篇文章中,我详细介绍了如何在 TCLab 上运行,但是这个应用程序稍微高级一些。最值得注意的是,我们在每个时间步调用我们的pid(sp,pv,pv_last,ierr,dt)函数来返回加热器输出,以便我们保持在正确的温度。我们每秒都在更新这个。PID 在计算上并不太昂贵,所以它可以在这段时间内很容易地解决。

# Run test
with tclab.TCLab() as lab:# Find current T1, T2print('Temperature 1: {0:0.2f} °C'.format(lab.T1))print('Temperature 2: {0:0.2f} °C'.format(lab.T2)) # Integral errorierr = 0.0# Integral absolute erroriae = 0.0 start_time = time.time()prev_time = start_time for i in range(loops):# Delay 1 secondif time.time() > prev_time + 1.0:print('Exceeded cycle time by ',time.time()-prev_time-1.0)else:while time.time() < prev_time + 1.0:pass# Record time and change in timet = time.time()dt = t - prev_timeprev_time = ttm[i] = t - start_time # Read temperatures in Kelvin T1[i] = lab.T1 # Integral absolute erroriae += np.abs(Tsp1[i]-T1[i]) # Calculate PID output[Q1[i],P,ierr,D] = pid(Tsp1[i],T1[i],T1[i-1],ierr,dt) # Write heater output (0-100)lab.Q1(Q1[i])

让我们来看看控制器是如何工作的:

作者的情节

相当整洁!我们希望红线(温度传感器)跟随黑线(温度设定点)。蓝色显示加热器如何调整,以使传感器与设定值相匹配。我们总是可以针对不同的性能调整 PID 参数,但我们希望进入机器学习部分,因此对于这个练习来说,这是完美的。我不知道你,但我们甚至还没有开始机器学习,但仅仅是在我们的办公桌上编程我们自己的控制器就已经很令人兴奋了!

最后的想法…暂时的

首先,你可以从 Github 下载代码。这个练习在很大程度上依赖于 TCLab,但我希望将来添加一些带有原始数据的替代笔记本,这样您就可以在没有原始数据的情况下运行代码。

我们可以设计一个装置来控制温度,这有多棒?有这么多的应用——想想你的恒温器,或者烤箱,甚至是一个别致的烧烤架。更不用说反应器温度或进料流温度的工业应用。你能想到这种控制器的其他应用吗?

感谢您耐心阅读这篇介绍性文章,尤其是如果您从未见过控制器的话。我知道我承诺了一些机器学习应用,这正是我们正在努力的。我们将在下一节(2020 年 10 月)深入探讨这一问题。不过,如果有什么不同的话,我觉得理解机器学习应用程序背后的背景很重要。这不仅使它们与我们的工作或日常生活相关,而且也为更深刻的见解打开了大门。我很高兴听到这可能会给你带来什么想法!

模拟具有长短期记忆的 PID 控制器:第 2 部分

原文:https://towardsdatascience.com/emulating-a-pid-controller-with-long-short-term-memory-part-2-4a37d32e5b47?source=collection_archive---------22-----------------------

使用温度控制实验室在 Keras 中训练长短期记忆神经网络以仿真 PID 控制器

照片由皮尔莫·康在 Unsplash 拍摄

欢迎来到这个激动人心的项目的第 2 部分!到目前为止,结果看起来很好,现在我们可以进入我们试图完成的内容了:用 LSTM 模拟 PID 控制器的行为。简要回顾一下,以下是我们到目前为止所探索的内容以及我们的发展方向:

  1. 使用温度控制实验室创建比例积分微分控制器数据
  2. 在 Keras 中训练一个长短期记忆神经网络来模拟 PID 控制器(本文)
  3. 用 LSTM 控制温控实验室
  4. 用 LSTM 控制器代替 PID 控制器进行温度控制的实际应用

如果你想自己运行这段代码,可以在 Github 上找到。它严重依赖于在您的计算机上使用 TCLab 设备,但最终我计划生成数据并添加一些笔记本,这样您也可以作为一个独立的项目来运行它。当然,我总是鼓励你看看你能从中吸取什么原则,并把它们应用到你自己的项目中。

用 LSTM 模拟 PID 行为

完成最后一段后,我们有一些数据要处理,我们想看看 LSTM 是否能模拟 PID 控制器的行为。有一些关于 LSTMs 如何工作的优秀文章,所以如果您以前没有使用过它们,我会向您推荐这些文章。这里是我在研究它们背后的一些数学知识时去的地方之一,而这篇是一篇关于数据科学的精彩文章,向我介绍了它们是如何用 Python 和 Keras 实现的。这里有另一个有视频的很棒的教程。像往常一样,APMonitor.com是所有与机器学习和过程控制相关的丰富资源。

LSTMs 由于其多功能性,已经成为所有类型的机器学习模型的流行方法。我在序列预测任务、自然语言处理和异常检测中使用过它们;其他人已经找到了从图像处理到语音识别的应用。它与标准递归神经网络的区别在于其细胞存储单元的存在,这有助于解决消失梯度问题。

LSTMs 在这类问题上工作得很好,因为我们想记住控制系统中以前发生过什么。如果我们只是将设定点从 35°C 更改为 70°C,我们知道加热器将被置于最大温度一段时间,以达到该设定点。然而,如果我们只是从 45°C 降至 42°C,或者在 55°C 保持稳定一段时间,控制器将不得不做出不同的解释。

在仿真 PID 控制器的情况下,我们希望输入一个数据窗口,例如温度、设定点、误差或加热器值,并预测下一个加热器值应该是多少,以达到所需的设定点。这个预测是模拟具有给定调谐常数的 PID 控制器将会给我们的输出。当然,如果调谐常数改变,我们不再看到相同类型的控制器行为。这是一个有趣的想法,可以在第 4 部分中探讨。

模型特征和预处理

第一步是查看哪些特性对输入模型有用。直观地说,PID 控制器将传感器温度和设定点之间的误差作为输入,因此我们的 LSTM 很可能需要这些。Scikit-learn 有很多有用的特性选择模型来帮助我们理解一些好的输入。让我们使用SelectKBest方法来缩小我们的选择范围。我们有传感器温度、设定值和加热器输出;我们还将导出误差,并将它们传递给SelectKBest函数:

# Create new feature: setpoint error
df['err'] = df['Tsp'] - df['T1']# Load possible features
X = df[['T1','Tsp','err']]
y = np.ravel(df[['Q1']])# SelectKBest feature selection
bestfeatures = SelectKBest(score_func=f_regression, k='all')
fit = bestfeatures.fit(X,y)
plt.bar(x=X.columns,height=fit.scores_)

绘制结果显示Tsp(设定点温度)和err(设定点和传感器之间的误差)是迄今为止最重要的特征,这验证了我们的直觉。

作者的情节

对于 LSTM,我将使用 Keras 和 Tensorflow 后端;我发现这是一种直观有效的建模方式。在构建模型之前,我需要缩放数据并将其格式化为 LSTM 期望的样子。在这种情况下,我将采用我的Tsperr特征,并以这样一种方式排列它们,即过去的 15 个时间点作为输入来预测加热器输出Q1。一定要留出一些数据来测试模型性能。

X = df[['Tsp','err']].values
y = df[['Q1']].values# Scale data
s = MinMaxScaler()
Xs = s.fit_transform(X)# Each input uses last 'window' number of Tsp and err to predict the next Q1
X_lstm = []
y_lstm = []
for i in range(window,len(df)):X_lstm.append(Xs[i-window:i])y_lstm.append(y[i])# Reshape data to format accepted by LSTM
X_lstm, y_lstm = np.array(X_lstm), np.array(y_lstm)# Split into train and test 
Xtrain, Xtest, ytrain, ytest = train_test_split(X_lstm,y_lstm,test_size=0.2,shuffle=False)

训练 LSTM

我们可以查看大量的超参数来优化 LSTM 与 PID 控制器的保真度。我通常会使用一个非常有用的 Python 包,名为 Hyperopt 来调优这些,尤其是对于一个非常复杂的问题。以下是一些运行良好的超参数:

window = 15
layers = 2
batch_size = 100
drop = 0.1
units = 100

现在,我们准备构建 LSTM 模型。有很多关于如何做到这一点的教程,所以我将继续展示代码,然后评论几个亮点。

# Keras LSTM model
model = Sequential()if layers == 1:model.add(LSTM(units=units, input_shape=(Xtrain.shape[1],Xtrain.shape[2])))model.add(Dropout(rate=drop))
else:# First layer specifies input_shape and returns sequencesmodel.add(LSTM(units=units, return_sequences=True, input_shape=(Xtrain.shape[1],Xtrain.shape[2])))model.add(Dropout(rate=drop))# Middle layers return sequencesfor i in range(layers-2):model.add(LSTM(units=units,return_sequences=True))model.add(Dropout(rate=drop))# Last layer doesn't return anythingmodel.add(LSTM(units=units))model.add(Dropout(rate=drop))model.add(Dense(1))
model.compile(optimizer='adam', loss='mean_squared_error')es = EarlyStopping(monitor='val_loss',mode='min',verbose=1,patience=25)result = model.fit(Xtrain, ytrain, verbose=0, validation_split=0.2,callbacks = [es,TqdmCallback(verbose=1)],batch_size=batch_size,epochs=350)# Show results
epochs = es.stopped_epoch
plt.semilogy(result.history['loss'],label='loss')
plt.semilogy(result.history['val_loss'],label='val_loss')
plt.legend();

构建 LSTM 和 Dropout 图层后,我们有一个值为 1Dense图层,因为模型仅预测 1 个输出值。我们使用adam优化器和mean_squared_error作为损失函数。我喜欢留出一些训练数据来用validation_split参数进行验证。这使我能够监控一组单独数据的损失,如果我的损失达到稳定状态,就提前停止模型训练(你可以用patience参数调整它达到稳定状态后等待的时间),这可以防止模型过度拟合。TqdmCallback是一个方便的进度条,比起 Keras 自带的默认进度条,我更喜欢它。最后,最好绘制损失函数,以确保训练损失和验证损失都呈现总体下降趋势。训练 LSTM 需要一点时间,但我们不会处理大数据集,所以这不是禁止性的。

测试 LSTM

在我们使用 LSTM 控制 TCLab 之前,我们希望确保它的行为近似于 PID 控制器的行为。这不仅对于健全性检查很重要,而且也是一个重要的安全问题。你能想象在一个你不确定能否工作的反应器上使用温度控制器吗?如果没有达到预期效果,出现失控反应,可能会造成大混乱。

幸运的是,我们已经准备了一些样本数据,都是 LSTM 期望输入的正确格式。我们只需要看到,给定输入,来自 LSTM 的预测加热器输出与 PID 控制器将做的一致。请务必撤消数据的缩放,以便我们获得真实值。

# Predict using LSTM
yp_s = model.predict(Xtest)# Unscale data
Xtest_us = s_x.inverse_transform(Xtest[:,-1,:])
ytest_us = s_y.inverse_transform(ytest)
yp = s_y.inverse_transform(yp_s)# Derive Tsp (setpoint) and T1 (sensor) from X data
sp = Xtest_us[:,0]
pv = Xtest_us[:,0] + Xtest_us[:,1]

这就是我们所看到的:

作者的情节

太神奇了!您可以看到设定值和 T1 数据(我们从中得出误差),以及来自 PID 控制器的实际数据。绿色显示的是在给定完全相同的输入数据集的情况下,LSTM 的表现。看起来它非常逼真地遵循了 PID 控制器的行为,所以我有信心把它作为代理控制器来试用,只需要一次调整。请注意,LSTM 输出有时会超出加热器限定的范围[0,100]。当我们把它作为控制器编码时,我们必须记住裁剪结果。

最后的想法

我们已经有了一个工作的 LSTM 模型,下一步是把它编码成控制器。这是一个相当大的项目,所以我们将把它留到本系列的下一篇文章中(2020 年 10 月)。在此之前,请确保保存您的模型和用于预处理的任何参数。

# Save Keras LSTM model
model.save('pid_emulate.h5')# Save preprocessing parameters
model_params = dict()
model_params['Xscale'] = s_x
model_params['yscale'] = s_y
model_params['window'] = windowpickle.dump(model_params, open('model_params.pkl', 'wb'))

现在我们有了。我们成功地训练了一个 LSTM 模型来模拟 PID 控制器的行为。下一个重要的步骤是将它投入使用。

模拟具有长短期记忆的 PID 控制器:第 3 部分

原文:https://towardsdatascience.com/emulating-a-pid-controller-with-long-short-term-memory-part-3-23da7df3e033?source=collection_archive---------27-----------------------

用 LSTM 控制温度控制实验室

Johannes Plenio 在 Unsplash 上拍摄的照片

欢迎来到这个项目的第 3 部分!现在,你的雇主正在看着你的结果,说“那又怎么样?”你已经做了很多跑腿的工作,但是到目前为止,它只是在电脑上看起来不错。嗯,这是“那又怎样”的部分。这就是我们最终实现这个 LSTM 神经网络来模拟 PID 控制器行为的地方。简单回顾一下,我们已经走过的路和将要去的地方如下:

  1. 使用温度控制实验室创建比例积分微分控制器数据
  2. 在 Keras 中训练一个长短期记忆神经网络,以模拟 PID 控制器
  3. 用 LSTM 控制温度控制实验室(本文)
  4. 用 LSTM 控制器代替 PID 控制器进行温度控制的实际应用

和往常一样,你可以自由地自己运行代码,最好是和温度控制实验室一起运行,这样你就可以看到实时数据。

最后一次检查

虽然我们上次检查了 LSTM 控制器的输出,但我们还是想先练习安全。我们不想在运行像反应堆温度这样敏感的东西时调试我们的控制回路。因此,首先,我们将保留我们的 PID 控制器,但也计算 LSTM 控制器输出。这使我们能够看到我们编程的 LSTM 控制器与 PID 控制器相比做了什么,并对其进行调试。

到目前为止,您对此已经很熟悉了,但是设置跑步只需要做一些调整:

#### Set up run ##### Import model and model parameters
model = load_model('pid_emulate.h5')
model_params = pickle.load(open('model_params.pkl', 'rb'))s_x = model_params['Xscale']
s_y = model_params['yscale']
window = model_params['window']# Run time in minutes
run_time = 30.0# Number of cycles
loops = int(60.0*run_time)# arrays for storing data
T1 = np.zeros(loops) # measured T (degC)
Qpid = np.zeros(loops) # Heater values for PID controller
Qlstm = np.zeros(loops) # Heater values for LSTM controller
tm = np.zeros(loops) # Time# Temperature set point (degC)
with tclab.TCLab() as lab:Tsp = np.ones(loops) * lab.T1# vary temperature setpoint
# leave 1st window + 15 seconds of temp set point as room temp
end = window + 15 
while end <= loops: start = end# keep new temp set point value for anywhere from 4 to 10 minend += random.randint(240,600) Tsp[start:end] = random.randint(30,70)# leave last 120 seconds as room temp
Tsp[-120:] = Tsp[0]

您将注意到的第一件事是,我们从训练运行中加载了模型和预处理参数。这些匹配很重要,否则结果会很糟糕,或者根本不起作用。我跑了 30 分钟,因为我只需要看到足够多的东西来确信它是可行的,而不是试图生成足够多的高质量数据来训练 LSTM。我还有两个独立的加热器阵列,一个存储 PID 输出,一个存储 LSTM 输出。最后,在最后 2 分钟,我把我的温度设定值调回到室温。通常你不需要担心这个,但是因为我连续做了两次测试,这使得第二次测试从接近室温开始,而不需要在两次测试之间额外等待几分钟。

我们编写的控制回路将与 PID 控制器相同(如果需要,请参见第 1 部分复习),只是现在我们还想看看 LSTM 控制器会输出什么。我已经把它放在一个函数lstm(T1_m,Tsp_m)中,但是我建议先把它直接放在代码中以便调试。T1_m是 LSTM 模型传感器 1 的温度,我们将在每个时间点读取,而Tsp_m是 LSTM 模型的设定点温度。让我们来看看我们用它做什么。

首先,计算误差,确保它与我们在第二部分中训练 LSTM 时计算的方法相同。

# Calculate error (necessary feature for LSTM input)
err = Tsp_m - T1_m

接下来,我们需要将现有的数据转换成 LSTM 所期望的格式,因此用与第 2 部分相同的方式将其放入一个数组中,对其进行缩放和整形。

# Format data for LSTM input
X = np.vstack((Tsp_m,err)).T
Xs = s_x.transform(X)
Xs = np.reshape(Xs, (1, Xs.shape[0], Xs.shape[1]))

现在我们有了输入数据,我们可以调用model.predict()函数来获得加热器输出。回想一下,这是一个缩放值,对我们的实际加热器没有多大用处,所以我们取消了对真实值的缩放。

# Predict Q for controller and unscale
Q1c_s = model.predict(Xs)
Q1c = s_y.inverse_transform(Q1c_s)[0][0]

最后,正如我们在第 2 部分培训时注意到的,有时 LSTM 会预测有效[0,100]范围之外的值,因此我们将只限制可能的输出值。

# Ensure Q1c is between 0 and 100
Q1c = np.clip(Q1c,0.0,100.0)

我希望你能明白我为什么决定在安装之前测试和调试它!

当我们在控制回路中时,最后要做的一件事。回想一下,我们指定了一个特定的数据点窗口作为 LSTM 输入的历史。我们必须等到有了那个数量的数据点,才能向 LSTM 控制器输入任何东西。这是这个模拟器的一个潜在的缺点,也是为什么你想保持窗口适当低的一个原因。然而,在最初的窗口期过后,事情就一帆风顺了。下面是控制循环中的最终实现:

# Run LSTM model to get Q1 value for control
if i >= window:# Load data for modelT1_m = T1[i-window:i]Tsp_m = Tsp[i-window:i]# Predict and store LSTM value for comparisonQlstm[i] = lstm(T1_m,Tsp_m)

我还保存了一些控制器行为的快照,并把它们放入视频中。让我们看看它是如何工作的。

作者的情节

相当惊人!请记住,蓝线(PID)是真正控制加热器,绿色(LSTM)只是作为参考。它不完全匹配,我也不一定期望它匹配。LSTM 控制器看起来更倾向于降低加热器值,这可能会导致现实生活中的超调量增加。它通常也会有较低的输出,但由于高温往往更危险,我很高兴看到它更保守。总的来说,看起来我们已经编程正确,所以我相信 LSTM 运行加热器输出值来控制温度。让我们看看接下来会是什么样子。

用 LSTM 控制

现在,我们期待已久的!让我们把控制器交给 LSTM。这里真的没有什么新东西,但是为了完整起见,这里是我的代码看起来像使用 LSTM 来控制加热器输出,模拟 PID 控制器的行为。

# Run test
with tclab.TCLab() as lab:# Find current T1, T2print('Temperature 1: {0:0.2f} °C'.format(lab.T1))print('Temperature 2: {0:0.2f} °C'.format(lab.T2)) start_time = time.time() for i in tqdm(range(loops)):# Delay 1 secondif time.time() > prev_time + 1.0:print('Exceeded cycle time: ',time.time()-prev_time-1.0)else:while time.time() < prev_time + 1.0:pass # Record timet = time.time()tm[i] = t - start_time # Read temperature (C)T1[i] = lab.T1 # Run LSTM model to get Q1 value for controlif i >= window:# Load data for modelT1_m = T1[i-window:i]Tsp_m = Tsp[i-window:i]# Predict and store LSTM value for comparisonQlstm[i] = lstm(T1_m,Tsp_m) # Write heater output (0-100)lab.Q1(Qlstm[i])

我们表现如何?

作者的情节

哇哦。我不知道你怎么想,但这是令人兴奋的事情。我们成功地复制了具有 LSTM 神经网络的 PID 控制器的行为,并能够实时地将它用于全新的数据来控制温度。这就是机器学习如此令人兴奋的原因!

最后的想法

当然,你可能会注意到一些需要改进的地方。控制器在运行中期很难将温度一直提高到 70°c。我们总是可以调整 LSTM 模型中的超参数,并且拥有更多训练数据也无妨(还有什么其他想法可以提高 LSTM 控制器对 PID 控制器的保真度?).但是即使 LSTM 控制器与 PID 控制器不完全匹配,它仍然完成了模拟行为的目标,这本身就是令人兴奋的!

此时,你的老板还在疑惑“那又怎样?”如果 PID 控制器已经做了我们想要的事情,这又有什么意义呢?这就是我们接下来要做的,所以请留下来进行一些更刺激的探索吧!像往常一样,在这里随意跟随代码,希望在您自己的 TCLab 上,您可以在您的办公桌上运行!

模拟具有长短期记忆的 PID 控制器:第 4 部分

原文:https://towardsdatascience.com/emulating-a-pid-controller-with-long-short-term-memory-part-4-19ab327be61b?source=collection_archive---------33-----------------------

用 LSTM 控制器代替 PID 控制器进行温度控制的实际应用

照片由 Unsplash 上的 Tasos Mansour 拍摄

这是这个有趣项目的最后一部分!在这里,我们将看到使用 LSTM 来仿真 PID 控制器的一些实际应用,以及一些潜在的缺点。如果您还没有阅读本系列的前几篇文章,我强烈建议您回去看看,这样您就可以有一些背景知识了。当然,这个项目的巧妙之处在于,你可以在自己的温度控制实验室设备上运行所有的代码,模拟你可能在真正的炼油厂或化工厂看到的东西。因此,这里有一个快速回顾这一系列,然后我们将开始!

  1. 使用温度控制实验室创建比例积分微分控制器数据
  2. 在 Keras 中训练长短期记忆神经网络,以模拟 PID 控制器
  3. 用 LSTM 控制温控实验室
  4. 用 LSTM 控制器代替 PID 控制器进行温度控制的实际应用(本文)

改变 PID 调节参数

如果您熟悉 PID 控制器,在问题设置期间,您可能想知道的第一件事是,如果您更改调整参数,会发生什么情况?回想一下 PID 控制器方程:

如果我们改变 K_c、τ_I 或τ_D,加热器输出也会改变,然后我们训练的 LSTM 不再与输出匹配。人们可能会认为这是一个巨大的缺点——如果我们改变 PID 控制器的调整参数,我们将不得不重新训练 LSTM 来模拟新的行为(回到第 2 部分)。另一方面,我们可以利用这一点。一旦 PID 控制器被调整到一个系统,我们很少需要改变调整参数,因此 PID 行为的改变可能表明来自外部的恶意攻击(或潜在的内部攻击,如不满的员工)。

突然,我们有了一个现成的异常检测方法。我们可以像在第 3 部分中所做的那样进行检查,在那里我们运行 PID 之外的控制器,但是也检查 LSTM 输出以确保它们是相似的。如果不是,那么我们知道有什么东西使 PID 控制器出了问题,我们可以调查并修复它。

让我们来看看我们的设置,现在应该很熟悉了,但是有一些变化:

#### Set up run ##### Import model and model parameters
model = load_model('pid_emulate.h5')
model_params = pickle.load(open('model_params.pkl', 'rb'))s_x = model_params['Xscale']
s_y = model_params['yscale']
window = model_params['window']# Run time in minutes
run_time = 45.0# Number of cycles
loops = int(60.0*run_time)# arrays for storing data
T1 = np.zeros(loops) # measured T (degC)
Qpid = np.zeros(loops) # Heater values for PID controller
Qlstm = np.zeros(loops) # Heater values for LSTM controller
tm = np.zeros(loops) # Time
t_pid = np.zeros(loops) # Time to compute PID controller output
t_lstm = np.zeros(loops) # Time to compute LSTM controller output
Q2 = np.zeros(loops)# Time range to introduce anomaly (turn on heater 2, change PID tuning constants)
start_anom = int(0.7*loops)# Heater 2 turned on during anomaly window
Q2[start_anom:] = 80# Temperature set point (degC)
with tclab.TCLab() as lab:Tsp = np.ones(loops) * lab.T1# vary temperature setpoint
end = window + 15 # leave 1st window + 15 seconds of temp set point as room temp
while end <= start_anom: start = end# keep new temp set point value for anywhere from 4 to 10 minend += random.randint(240,600) Tsp[start:end] = random.randint(30,70)while end <= loops: start = end# keep new temp set point value for anywhere from 4 to 10 minend += random.randint(240,600) Tsp[start:end] = random.randint(30,50)

像往常一样,我们导入我们的模型和附带的参数,设置运行时间,启动数组来存储数据,并创建一个设定点配置文件。还有几件事需要指出。我们有t_pidt_lstm,稍后我们将使用它们来为控制器计时。我们有start_anom变量,我用它来表示数据的异常部分应该何时开始。注意,我还为 heater 2 ( Q2)设置了一个数组,稍后我们将使用它进行另一个测试。最后,在数据的异常部分,我将加热器的设定点保持在稍低的位置——它将在较高的温度下工作,但当温度保持较低时更容易看到。

我还对pid(sp,pv,pv_last,ierr,dt)函数进行了修改,因此它现在将调谐“常数”作为附加输入(Kc,tauI,tauD)。这将让我们在运行中途改变 PID 控制器输出。

最后,下面是我们运行模拟时的代码:

# Run test
with tclab.TCLab() as lab:# Find current T1, T2print('Temperature 1: {0:0.2f} °C'.format(lab.T1))print('Temperature 2: {0:0.2f} °C'.format(lab.T2)) # Integral errorierr = 0.0# Integral absolute erroriae = 0.0 start_time = time.time()prev_time = start_time for i in tqdm(range(loops)):# Delay 1 secondif time.time() > prev_time + 1.0:print('Exceeded cycle time')else:while time.time() < prev_time + 1.0:pass# Record time and change in timet = time.time()dt = t - prev_timeprev_time = ttm[i] = t - start_time # Read temperature (C)T1[i] = lab.T1 # Integral absolute erroriae += np.abs(Tsp[i]-T1[i]) # Perturb PID tuning parameterif i > start_anom:Kc, tauI, tauD = 3.0*Kc0, 0.5*tauI0, tauD0 + 2.0else:Kc, tauI, tauD = Kc0, tauI0, tauD0# Calculate PID output (and time)t0_pid = time.time()[Qpid[i],P,ierr,D] = pid(Tsp[i],T1[i],T1[i-1],ierr,dt,Kc=Kc,tauI=tauI,tauD=tauD)tf_pid = time.time() # Write heater output (0-100)lab.Q1(Qpid[i])# Run LSTM model to get Q1 value for controlif i >= window:# Load data for modelT1_m = T1[i-window:i]Tsp_m = Tsp[i-window:i]# Predict and store LSTM value for comparisont0_lstm = time.time()Qlstm[i] = lstm(T1_m,Tsp_m)tf_lstm = time.time()# Save controller timest_pid[i] = tf_pid - t0_pidt_lstm[i] = tf_lstm - t0_lstm

里面有很多,但从第三部看起来应该很熟悉。主要区别是当我们的时间计数超过我们的start_anom规格时,我们改变 PID 调节参数的行:Kc, tauI, tauD = 3.0*Kc0, 0.5*tauI0, tauD0 + 2.0。您还会注意到这里有一些时间记录,我们将在下一节中讨论。

运行后,我们可以绘制结果,并将其放入视频中进行可视化。让我们看看发生了什么!

正如我们在第 3 部分中看到的,LSTM 输出非常类似于 PID 输出,在瞬态时间范围内有明显的例外。正如所料,当 PID 调节参数改变时,这种情况会突然改变。你会注意到,由于 PID 控制器是实际写入输出的控制器,加热器输出也开始变得不稳定,温度开始波动得更大。

我们可以很容易地绘制出QpidQlstm之间的误差,并使用它来检测异常行为。这种情况下有备份也很方便;如果我们注意到 PID 控制器开始表现异常,我们可以迅速将控制切换到 LSTM 控制器,只需将lab.Q1(Qpid[i])改为lab.Q1(Qlstm[i])。非常巧妙的是,最初可能被认为是缺点的东西实际上变得非常有用!

计算时间

如果你还记得,我们开始这个项目的主要原因是来自一篇论文讨论使用神经网络来模拟模型预测控制器,其想法是神经网络将比控制器更快。从上次我们计算 LSTM 和 PID 控制器的运行中,我们方便地节省了每个控制器所花费的时间。让我们看看结果如何:

print('LSTM:',t_lstm.mean())
print('PID:',t_pid.mean())>>> LSTM: 0.03118442685515792
PID: 2.043927157366717e-05

老实说,这正是我所期望的。PID 实际上比 LSTM 快得多,尽管 LSTM 控制器的计算时间仍不到 1 秒。使用 PID 控制器是有原因的,那是因为它们速度快,在解决一些控制问题时表现得相当好。但是,如果你有一个更复杂的控制器,假设模型输入和参数是相似的,我们可能期望 LSTM 控制器每次计算只需要几分之一秒。因此,虽然它实际上比 PID 控制器有时间上的优势,但仍然有一些用途(请查看 2020 年 11 月的一篇关于更复杂的控制器以及 LSTM 控制器在这种情况下如何有优势的额外文章)。

使用加热器 2 模拟额外的异常

最后,让我们再来看看如何使用 LSTM 控制器来检测其他类型的异常。我们将模拟炼油厂的环境条件不再标准的情况。也许这是良性的,如不同的天气,或者是恶意的,如针对工厂另一部分的网络攻击(甚至是这个特定的过程)。控制器的行为会有什么不同?

让我们通过打开加热器 2 一部分时间来模拟这一异常事件。虽然加热器 2 与加热器 1 上的传感器在物理上是分开的,但它仍然足够近,足以影响我们试图控制的加热器 1 周围的条件。我们的 LSTM 控制器是根据在标准室温下运行的一组特定数据进行训练的,所以如果我们打开加热器 2,就会出现 LSTM 控制器没有被训练来控制的情况。类似于改变 PID 调节参数的情况,这最初看起来像是使用 LSTM 控制器的失败。然而,如果我们的工厂有一个精心控制的周围环境,那么我们希望控制器表现一致;任何偏离都表明有异常情况发生。

这里看一下运行的代码(回想一下,我们已经在初始设置中指定了Q2参数)。

# Run test
with tclab.TCLab() as lab:# Find current T1, T2print('Temperature 1: {0:0.2f} °C'.format(lab.T1))print('Temperature 2: {0:0.2f} °C'.format(lab.T2)) start_time = time.time()t = start_time for i in tqdm(range(loops)):# Delay 1 secondif time.time() > t + 1.0:print('Exceeded cycle time by ',time.time()-t-1.0)else:while time.time() < t + 1.0:pass # Record time and change in timet = time.time()tm[i] = t - start_time # Read temperature (C)T1[i] = lab.T1 # Run LSTM model to get Q1 value for controlif i >= window:# Load data for modelT1_m = T1[i-window:i]Tsp_m = Tsp[i-window:i]# Timer for LSTM controller outputt0_lstm = time.time()# Predict and store LSTM value for comparisonQlstm[i] = lstm(T1_m,Tsp_m)tf_lstm = time.time() # Write heater output (0-100)lab.Q1(Qlstm[i])lab.Q2(Q2[i])

这一切现在看起来可能都很熟悉,只有最后两行是明显的例外:我们已经将控制权交给了 LSTM,并且我们还在中读取了 Q2 值。运行模拟后,我们可以再次绘制结果,并将其放入动画中。

很有意思。请注意,一旦我们打开 Q2,温度往往会超过设定值,控制器无法正确解释这种超调。这是因为控制器没有被训练去考虑来自附近加热器的额外热量。

这让我有了一个想法,但我想我会让你尝试一下,现在你知道如何设置 TCLab,训练一个 LSTM,并用它运行温度控制模拟。你能利用从本系列中学到的技巧来设置一个控制系统,打开两个加热器,并试图将两个温度控制在某个设定值吗?这将是多输入多输出(MIMO)控制器。为了找到正确的方向,请访问位于 APMonitor.com 的 MIMO 实验室。

最后的想法

这使我们得出了这个项目的结论。我们从一个基本的 PID 控制器开始,生成一些数据,使用这些数据训练一个自动 LSTM 来模拟 PID 控制器,将控制交给 LSTM,然后查看一些有用的应用,例如检测各种异常和潜在的计算时间节省。

你表现如何?你像我一样对这个项目感到兴奋吗?你还能想到这方面的其他应用吗?我很高兴听到对需要更多澄清的领域的建议。感谢您关注这个项目,我期待着未来的互动。如果你喜欢这个,请随时在 LinkedIn 上与我联系。

闪电强化学习

原文:https://towardsdatascience.com/en-lightning-reinforcement-learning-a155c217c3de?source=collection_archive---------27-----------------------

用 PyTorch 闪电建造 DQN

本文着眼于将 PyTorch Lightning 用于强化学习(RL)这一激动人心的领域。在这里,我们将使用经典的 CartPole gym 环境来构建一个标准的深度 Q 网络(DQN)模型,以说明如何开始使用 Lightning 来构建您的 RL 模型。

在本文中,我们将涵盖:

  • 什么是闪电,为什么我们要在 RL 中使用它
  • 标准 DQN 模型概述
  • 利用闪电建造 DQN 的步骤
  • 结果和结论

如果你想直接跳到代码,你可以在 PyTorch Lightning 示例页面中找到示例,或者点击下面的 colab 图标查看交互式 colab 笔记本!

闪电是什么?

Lightning 是一个最新的 PyTorch 库,它干净地抽象和自动化了 ML 模型中所有的日常样板代码,允许您关注实际的 ML 部分(有趣的部分!) .如果你还没有看过,我强烈推荐你看看闪电团队发表的一些很棒的文章

[## 从 PyTorch 到 py torch Lightning——一个温和的介绍

这篇文章对使用 PyTorch 和 PyTorch Lightning 实现的 MNIST 进行了对比。

towardsdatascience.com](/from-pytorch-to-pytorch-lightning-a-gentle-introduction-b371b7caaf09)

除了自动化样板代码之外,Lightning 还充当了一种风格指南,用于构建干净且可重复的 ML 系统。

这很有吸引力,原因如下:

  1. 通过抽象出样板工程代码,识别和理解 ML 代码就容易多了。
  2. Lightning 的统一结构使得构建和理解现有项目变得容易。
  3. Lightning 自动化的代码是由经过全面测试、定期维护并遵循 ML 最佳实践的高质量代码构建的。

DQN

在我们进入代码之前,让我们快速回顾一下 DQN 是做什么的。DQN 通过学习在特定状态下采取每个行动的价值来学习给定环境下的最佳策略。这些被称为 Q 值。

最初,代理对其环境的了解非常差,因为它没有太多的经验。因此,它的 Q 值将非常不准确。然而,随着时间的推移,代理探索它的环境,它学习更准确的 Q 值,然后可以做出好的决定。这允许它进一步改进,直到它最终收敛于一个最优策略(理想情况下)。

我们感兴趣的大多数环境,如现代视频游戏和模拟,都太复杂和太大,无法存储每个状态/动作对的值。这就是为什么我们使用深度神经网络来近似这些值。

代理的一般生命周期描述如下:

  1. 代理获取环境的当前状态,并通过网络传递它。然后,网络输出给定状态下每个动作的 Q 值。
  2. 接下来,我们决定是使用我们的代理认为网络给出的最佳动作,还是采取随机动作来探索更多。
  3. 动作被传递给环境,我们得到反馈,告诉代理它处于下一个状态,在前一个状态中采取前一个动作的奖励,以及情节是否在该步骤结束
  4. 我们以元组(状态、动作、奖励、下一个状态、完成)的形式获取在最后一步中获得的经验,并将其存储在代理存储器中。
  5. 最后,我们从代理人的记忆中抽取一小批重放体验的样本,并使用这些过去的体验来计算代理人的损失

这是对 DQN 所做工作的高度概括。要了解更多信息,有很多关于这个流行模型的免费资源,比如 PyTorch 示例。如果你想了解更多关于强化学习的一般知识,我强烈推荐马克西姆·拉潘的最新著作深度强化学习手把手第二版

点亮 DQN

启蒙时代是一场知识和哲学运动,主导了思想世界

让我们来看看组成 DQN 的各个部分

**模型:**用来近似我们的 Q 值的神经网络

**重放缓冲区:**这是我们代理的内存,用于存储以前的经历

**代理:**代理本身与环境和重放缓冲区进行交互

**闪电模块:**处理代理的所有培训

模型

对于这个例子,我们可以使用一个非常简单的多层感知器(MLP)。所有这一切意味着,我们没有使用任何像卷积或递归层,只是正常的线性层花式。这样做的原因是由于 CartPole 环境的简单性,任何比这更复杂的都是多余的。

重放缓冲器

重放缓冲区相当简单。我们需要的只是某种类型的数据结构来存储元组。我们需要能够对这些元组进行采样,并添加新的元组。这个缓冲区基于 Lapins replay buffer 在这里找到,因为它是我迄今为止发现的最干净和最快的实现。看起来像这样

但是我们还没完。如果您以前使用过 Lightning,那么您会知道它的结构是基于这样一种思想:创建数据加载器,然后在后台使用它将小批量数据传递给每个训练步骤。对于大多数 ML 系统(如监督模型)来说,这是如何工作的是非常清楚的,但是当我们正在生成数据集时,它是如何工作的呢?

我们需要创建自己的 IterableDataset,它使用不断更新的重放缓冲区来采样以前的体验。然后,我们将小批经验传递给 training_step,用于计算我们的损失,就像任何其他模型一样。除了不包含输入和标签,我们的迷你批处理包含(状态、动作、奖励、下一个状态、完成)

您可以看到,在创建数据集时,我们传入 ReplayBuffer,然后可以对其进行采样,以允许数据加载器将批处理传递给 Lightning 模块。

代理人

代理类将处理与环境的交互。代理主要执行 3 种方法

get_action: 使用传递的ε值,代理决定是使用随机动作,还是采取网络输出中 Q 值最高的动作。

play_step: 在这里,代理通过从 get action 中选择的动作在环境中执行单个步骤。在从环境获得反馈之后,体验被存储在重放缓冲器中。如果环境完成了该步骤,环境将重置。最后,返回当前奖励和完成标志。

**重置:**重置环境并更新存储在代理中的当前状态。

闪电模块

现在,我们已经为 DQN 设置了核心课程,我们可以开始考虑培训 DQN 代理了。这就是闪电出现的地方。我们将通过构建一个 Lightning 模块,以一种清晰、结构化的方式设计我们所有的培训逻辑。

Lightning 提供了许多钩子和可覆盖的函数,允许最大的灵活性,但是我们必须实现 4 个关键方法来使我们的项目运行。那就是下面的。

  1. 向前()
  2. 配置优化器
  3. train_dataloader
  4. 训练 _ 步骤

有了这 4 个方法,我们可以很好地训练我们将遇到的任何 ML 模型。除了这些方法之外,任何需要的东西都可以很好地适应 Lightning 中剩余的钩子和回调。要获得这些可用钩子的完整列表,请查看 Lightning 文档。现在,让我们看看填充我们的闪电方法。

初始化

首先,我们需要初始化我们的环境、网络、代理和重放缓冲区。我们还调用了 populate 函数,它首先会用随机体验填充重放缓冲区(populate 函数在下面的完整代码示例中显示)。

向前

我们在这里所做的是包装我们的主要 DQN 网络的转发功能。

失败

在我们开始训练代理之前,我们需要定义我们的损失函数。这里使用的损失函数基于 Lapan 的实现,可以在这里找到。

这是将我们的 DQN 网络的当前状态动作值与下一个状态的预期状态动作值进行比较的简单均方误差(MSE)损失。在 RL 我们没有完美的标签可以借鉴。相反,代理从目标值中学习它期望下一个状态的值是什么。

然而,通过使用相同的网络来预测当前状态的值和下一个状态的值,结果变成了不稳定的移动目标。为了解决这个问题,我们使用一个目标网络。该网络是主网络的副本,并定期与主网络同步。这提供了一个暂时固定的目标,以允许代理计算更稳定的损失函数。

如您所见,状态动作值是使用主网络计算的,而下一个状态值(相当于我们的目标/标签)使用目标网络。

配置优化器的

这是另一个简单的附加功能,只需告诉 Lightning 在 backprop 期间将使用什么优化器。我们将使用标准的 Adam 优化器。

列车数据加载器

接下来,我们需要向 Lightning 提供我们的训练数据加载器。如您所料,我们初始化了之前创建的 IterableDataset。然后像往常一样将它传递给数据加载器。Lightning 将在训练期间提供批次,并将这些批次转换为 PyTorch 张量,并将其移动到正确的设备。

训练步骤

最后,我们有培训步骤。在这里,我们放入了每个训练迭代要执行的所有逻辑。

在每次训练迭代中,我们希望代理通过调用前面定义的 agent.play_step()并传入当前设备和 epsilon 值来遍历环境。这将返回该步骤的奖励以及该集是否在该步骤结束。我们将阶梯奖励添加到总剧集中,以便跟踪该代理在该剧集中的成功程度。

接下来,使用闪电提供的当前迷你批,我们计算我们的损失。

如果我们已经到达一集的结尾,由 done 标志表示,我们将使用剧集奖励更新当前的 total_reward 变量。

在该步骤结束时,我们检查是否到了同步主网络和目标网络的时间。通常使用软更新,其中仅更新一部分权重,但是对于这个简单的例子,进行完全更新就足够了。

最后,我们需要返回一个包含 Lightning 将用于反向传播的损失的字典,一个包含我们想要记录的值的字典(注意:这些必须是张量)和另一个包含我们想要在进度条上显示的任何值的字典。

差不多就是这样了!我们现在有了经营 DQN 代理商所需的一切。

运行代理

现在剩下要做的就是初始化并适应我们的 Lightning 模型。在我们的主 python 文件中,我们将设置种子,并提供一个 arg 解析器,其中包含我们希望传递给模型的任何必要的超参数。

然后在我们的 main 方法中,我们用我们指定的参数初始化 DQNLightning 模型。接下来是闪电训练器的设置。

这里我们设置训练器使用 GPU。如果您无法访问 GPU,请从 Trainer 中删除“GPU”和“distributed_backend”参数。这个模型训练非常快,即使使用 CPU,所以为了看到闪电在行动中,我们将关闭早期停止。

最后,因为我们使用的是 IterableDataset,所以需要指定 val_check_interval。通常,此间隔是根据数据集的长度自动设置的。但是,IterableDatasets 没有 len 函数。因此,我们需要自己设置这个值,即使我们没有执行验证步骤。

最后一步是在我们的模型上调用 trainer.fit()并观察它训练。下面你可以看到完整的闪电代码

结果

大约 1200 步后,您应该看到代理的总奖励达到最高分 200。为了看到被绘制的奖励度量,旋转 tensorboards。

tensorboard --logdir lightning_logs

在左边你可以看到每一步的回报。由于环境的性质,这将始终是 1,因为代理人获得+1 的每一步,杆没有下降(这是他们所有的)。在右边,我们可以看到每集的总奖励。代理人很快达到最大回报,然后在很棒的剧集和不太棒的剧集之间波动。

结论

现在,您已经看到了在强化学习项目中利用 PyTorch Lightning 的力量是多么简单和实用。

这是一个非常简单的例子,只是为了说明闪电在 RL 中的使用,所以这里有很大的改进空间。如果你想把这段代码作为模板,试着实现你自己的代理,这里有一些我会尝试的东西。

  1. 降低学习率,或者更好的是,通过在 configure_optimizer 方法中初始化学习率调度器来使用它。
  2. 提高目标网络的同步速率,或者使用软更新而不是完全更新
  3. 在更多步骤的过程中使用更平缓的ε衰减。
  4. 通过在训练器中设置 max_epochs 来增加训练次数。
  5. 除了在 tensorboard 日志中跟踪总奖励外,还可以跟踪平均总奖励。
  6. 使用 test/val Lightning hook 添加测试和验证步骤
  7. 最后,尝试一些更复杂的模型和环境

我希望这篇文章是有帮助的,将有助于启动您自己的项目与闪电。编码快乐!

在零售银行中实现数据和人工智能:客户分析

原文:https://towardsdatascience.com/enabling-data-ai-in-retail-banking-part-1-customer-analytics-journey-54a7ce7d2a81?source=collection_archive---------13-----------------------

客户分析路线图,利用数据驱动的用例来增强客户个性化&体验

在当今互联的数字世界中,银行和金融服务提供商面临着满足并超越客户期望的挑战。金融机构必须专注于与客户互动,以保持竞争力和相关性。数据科学解决方案帮助金融机构实现数字化转型,重新定义客户关系。客户洞察提供关于客户的深刻知识,以优化与客户的每次互动。

客户往往会更快地对个性化和实时服务做出响应,这是一个重要的因素,为那些采用传统供应商的数据和人工智能驱动能力的银行带来了差异化优势,这些供应商往往会适应更好的个人偏好,甚至利用拥有高度客户信任和理解的金融中介。这类玩家吸引消费者的部分原因是他们能够为活跃客户群中的某些部分定制产品。

银行业采用数据科学的水平仍然很低

由于不断变化的客户行为、激烈的竞争、更严格的法规和数字差异,银行在保持盈利能力方面面临着诸多挑战

在人工智能时代采用新的银行模式

Wipro 在进行的一项调查显示,人工智能为何是银行业的未来,因为它为客户体验、欺诈管理和运营带来了先进的数据分析能力。人工智能算法在几秒钟内完成反洗钱活动,否则需要几个小时甚至几天。人工智能还使银行能够以创纪录的速度管理海量数据,从中获得有价值的见解。人工智能机器人、数字支付顾问和生物识别欺诈检测机制等功能可以为更广泛的客户群提供更高质量的服务。所有这些都转化为收入增加、成本降低和利润增加。

AI 正在通过以下方式加强银行在客户个性化领域的竞争力:

增强的客户体验:基于过去的互动,人工智能对客户及其行为有了更好的理解。这使得银行能够通过添加个性化功能和直观的交互来定制金融产品和服务,以提供有意义的客户参与并与其客户建立牢固的关系。

**预测客户行为和反应:**人工智能通过分析过去的行为来预测未来的情景,帮助银行预测未来的结果和趋势。这有助于银行识别欺诈、检测反洗钱模式并向客户提出建议。同样,人工智能能够在海量数据中检测可疑的数据模式,以进行欺诈管理。此外,通过其关键的推荐引擎,AI 研究过去以预测数据点的未来行为,这有助于银行成功地进行追加销售和交叉销售。

有效的决策:像人类专家一样思考和反应的认知系统,根据可用数据实时提供最佳解决方案。这些系统在其称为知识库的数据库中保存了专家信息。银行家利用这些认知系统做出战略决策。

人工智能技术释放银行业数据的力量

传统的金融服务商业模式正处于显微镜下。对于许多金融机构来说,在当今的低利率环境下,持续盈利是一个挑战。来自新市场进入者的竞争也产生了新的破坏层,而客户体验和参与度却跟不上精通数字技术的消费者不断增长的期望。

许多金融机构已经采取了裁员和战术性成本削减措施。然而,可持续的绩效需要战略的转变——一种由新技术增强的战略。

数字时代的成功要求银行挖掘他们已经拥有的大量隐藏财富:数据。认知系统和人工智能技术可以帮助银行释放数据的力量,揭示关于企业、客户和竞争对手的见解。认知系统不断地构建知识和学习,理解自然语言,比传统的可编程系统更自然地与人类进行推理和交互。

客户 360:了解客户 DNA

全方位了解客户活动的各个方面以及与银行的合作将有助于实现全面的方法。下图提供了一些应该纳入的关键数据域。

数据集市构建 360 度客户分析视图来源:Shamli Prakash

以可扩展、分阶段的方式构建这一客户 360°数据集市是许多客户分析用例的基础,如倾向建模、交叉销售/追加销售建议、客户终身价值等。customer 360 方法整合了所有客户数据领域,包括人口统计信息、交易数据、产品所有权、客户互动、客户服务、活动响应、定价和宏观经济数据。

特征工程是使用数据的领域知识来创建使机器学习算法工作的特征的过程。它在定义和创建捕捉客户行为的数据元素方面起着关键作用。为此,额外的特征被创建为这些数据域的组合(例如,滚动月平均值、虚拟变量等)。)

IBM 数据和人工智能路线图——客户分析阶梯

银行意识到,在当今市场中保持竞争力的关键步骤之一是通过与客户建立高质量、个性化的关系来提高参与度。

这个想法是分析客户体验,并根据客户的兴趣和偏好进行个性化。人工智能在理解客户行为模式方面取得了重大进展,将客户个性化带到了一个全新的水平。

数据科学家还可以建立模型,研究客户的行为,发现客户需要财务建议的情况。预测分析工具和高级数字交付选项的结合有助于完成这项复杂的任务,在最合适的时间引导客户找到最佳的金融解决方案,并根据消费习惯、社会人口趋势、相关需求和其他偏好建议个性化的产品。

客户分析之旅-个性化策略

在下一节中,概述了在整个成熟生命周期中利用数据分析的结构化客户互动之旅,从使用动态细分技术了解客户行为的基础开始,到在整个生命周期中跟踪客户,并通过个性化的活动和促销奖励他。

a .了解你的客户:行为细分

客户细分是根据共同特征将客户分成不同群体的过程,这样公司就可以有效而恰当地向每个群体进行营销。细分(如行为细分)或特定特征(如人口统计)有不同的变化。
客户细分旨在改善客户服务,提高客户忠诚度,留住客户,这对银行业来说非常必要。

市场细分使得营销人员能够通过了解同质特征来更有效地定制他们的营销工作,以锁定目标客户。这些工作可能涉及到沟通和产品开发。具体来说,细分有助于零售银行:

  1. 客户特征分析,以便我们能够专注于最高价值、最活跃、最懂数字的客户。
  2. 创建并传达有针对性的营销信息,这些信息将引起特定客户群体的共鸣,但不会引起其他人的共鸣(相反,其他人将收到根据他们的需求和兴趣定制的信息)。
  3. 根据细分市场选择最佳沟通渠道,可能是电子邮件、社交媒体帖子、广播广告或其他方式。
  4. 确定改进产品或新产品或服务机会的方法。
  5. 通过剖析见解建立更好的客户关系。
  6. 改善客户服务,根据细分结果提供个性化服务和产品。
  7. 追加销售和交叉销售其他产品和服务。

行为细分解决方案-统计聚类

b .确定你的客户:目标产品营销

的关键是提供适合特定客户需求和偏好的个性化服务。数据分析使我们能够创建个性化营销,在正确的时间通过正确的设备向正确的人提供正确的产品。数据挖掘广泛用于目标选择,以识别新产品的潜在客户。

数据科学家利用行为、人口统计、历史交易和产品所有权数据来构建倾向模型,预测客户对促销或优惠做出反应的概率。因此,银行可以进行高效、个性化的拓展,改善与客户的关系。

目标营销的模型评估比较:倾向建模来源:IBM

c .吸引客户:交叉销售/追加销售模式

交叉销售或追加销售模型是二进制概率算法,用于识别那些最有可能对报价做出反应的客户,或专注于保留活动的客户。基于现有的统计客户细分,可以在同类细分中开发倾向模型,以测量对特定产品活动(例如新的信用卡活动)的反应倾向

该模型可以应用于特定的客户群,并且客户可以利用输出以及活动资格标准来导出新的定制活动策略。倾向模型的主要优势在于,考虑到营销活动和采购成本,它们可以洞察更合适的客户群,并提高相对于基线随机目标的产品转化率(提升)

来自目标交叉销售分析的增量收入来源:IBM

d .让客户满意:下一个最佳行动

客户优惠亲和力(也称为下一个最佳行动)是一种预测分析形式,有助于营销人员及其组织更好地判断客户产品亲和力和交易行为,并引导营销工作与客户建立联系以达成交易。

当公司利用实时营销工具时,次佳报价是最成功的。公司需要了解最新的客户行为、需求和趋势,以便将“最佳”放在下一个最佳报价中。下一个最好的提议是“为客户增加最多价值的提议——以他们整体预期的客户终身价值的增加来衡量。”

由次优产品战略推动的营销活动来源:IBM

在当今互联的数字世界中,银行和金融服务提供商面临着满足并超越客户期望的挑战。金融机构必须专注于与客户互动,以保持竞争力。

e .关注你的客户:留住客户

当客户结束与企业的关系时,客户流失是决定企业收入的最基本因素之一。我们需要知道你的哪些客户是忠诚的,哪些客户有流失的风险,你需要从客户的角度了解影响这些决策的因素。留住最赚钱的客户可能是企业的最佳策略之一。

虽然保留现有客户并因此增加他们的终身价值是每个人都承认的重要事情,但当银行一开始没有看到客户流失时,他们对客户流失几乎无能为力。这就是在正确的时间预测客户流失变得重要的地方,尤其是当没有明确的客户反馈时。早期和准确的客户流失预测使 CRM 和客户体验团队在与客户接触时更具创造性和主动性。

下面的 SPSS Modeler 界面解释了如何建立一个机器学习模型,并使用它来预测客户是否有流失的风险。这是一个完整的数据科学项目,您可以将您的模型发现用于以后的规范性分析或有针对性的营销。

使用 SPSS Modeler Flow 的客户流失预测模型

提取有意义的预测洞察的关键是尽可能准确地定义问题陈述构建块。在客户流失的情况下,首先要定义什么被认为是“流失事件”。

一般来说,客户流失是指在给定时间内观察到的客户不活跃或不参与的程度。这在数据中以各种形式表现出来,例如账户行为的新近性或账户余额的变化。例如,在 HNW(高净值)客户的情况下,根据特定时期的资产下降率来定义客户流失是有用的。

可能有这样一种情况,客户在账户操作方面可能非常活跃,但在过去六个月中实际上已经提取了超过 50%的资产。

识别流失事件关键模型导向的流失倾向仪表板

确定客户流失是在产品层面(客户可能会放弃某一特定产品,如停止使用信用卡)还是在关系层面(客户可能会放弃银行本身)进行定义是至关重要的。当在关系级别分析数据时,您可以更好地理解客户的观点。例如,从一个人的储蓄账户中提取过多的钱可能是购买房子的首付或支付大学学费。这种对客户生活事件的洞察非常有力,不仅可以防止客户流失,还可以交叉销售补充产品,从而进一步加强关系。

f .跟随你的客户:生活事件预测

金融服务提供商可以利用客户数据,包括人口统计、行为和营销数据,以及细粒度的交易数据,来预测例如四种不同的客户生活事件:搬迁、Sudies、婚姻、孩子出生、新关系和关系结束。

结果表明,衍生的客户生活事件模型对生活事件的预测明显优于随机猜测,尤其是在结合细粒度交易和聚合数据的情况下。与基于生活事件预测和分类的模型相比,纳入定义明确的交易数据的新近性、频率和货币(RFM)价值信息也显著提高了性能。

生活事件预测分析仪表板来源:IBM 数据科学精英

g .重视你的客户:终生价值

客户终身价值 e (CLTV)是“客户产生的未来利润的贴现值”,然而,许多 CLTV 模型的重点是在收入方面。这是因为收入比成本更难预测,所以更需要一个模型来预测它(并且知道一个客户将产生的收入可以告知你在该客户身上的花费)。这些类型的模型通常被称为“客户资产模型”。

CLTV 可以分解成不同的顾客价值组成部分

。在这个框架中,CLTV 模型通常限制了表征客户行为的三个潜在(未观察到的)参数:

  • 寿命:客户与公司保持关系的时期
  • **购买率:**该参数对应于客户在给定时间内的购买次数
  • **货币价值:**模型的这一部分涉及为每个未来交易分配一个货币单位

在非合同环境中,这些参数是不可观察的。概率模型将帮助我们在客户层面约束这些参数,并对未来的购买和价值做出推断。

h .奖励你的客户:活动&忠诚度分析

事实是,分析一直是银行忠诚度和奖励计划战略的重要组成部分,银行可以为每个客户建立档案计划,确定哪些客户是有利可图的,了解哪些激励方法最有可能对每个客户成功,然后量身定制相关计划。

文章称,建立在“智能和反应灵敏的技术平台”上的忠诚度和回报分析为银行提供了 360 度的客户视图,提供了见解,使他们能够不断微调这些计划,使它们更具相关性,对特定客户更具吸引力。

活动分析利用 Unica 环境中的交叉销售倾向模型来源:IBM

通过使用分析在正确的地点和时间生成所有必要的洞察,银行可以创建符合其客户群多样性和特征的奖励计划。

然而,银行要做的不仅仅是为客户选择正确的内容和奖励,它还必须确保这些客户无论何时、何地、通过他们选择的任何设备参与和进行交易。参与的关键是定期和定制的客户沟通,这可以带来更成功和更有利可图的关系。

更精确的细分,提供个人优惠,并通过高级营销分析创建有针对性的电子邮件活动。这加快了上市时间,提高了响应率,并提高了营销支出的回报。

沃森银行客户分析

IBM Watson Customer Insight for Banking使用结合预测和认知能力的高级预建行业特定分析模型。该解决方案支持动态行为细分,以发现可操作的客户洞察,使银行能够创建个性化的销售产品和营销活动。该解决方案提供了直观的用户界面和专为业务线用户设计的特定于角色的控制面板。

沃森客户洞察使银行能够通过客户分析更好地洞察客户需求来源:IBM

  1. 基于客户行为的动态细分
  2. 通过根据每个客户的行为确定他们的参与度,确定购买或交叉销售/追加销售的倾向。
  3. 预测客户生活事件:为您的客户预测潜在的生活事件,以提供主动的个性化体验
  4. 通过预测流失风险,提高留住利润最高的客户的能力。
  5. 识别高利润客户,以留住、营销和开发新产品。

**IBM Acoustic Analytics(前身为沃森 CX 分析公司)**根据对各接触点客户的洞察,帮助您做出更明智、更快速的营销和客户体验决策。声学旅程分析让您能够可视化您的客户通过设备、渠道和接触点与您的品牌互动的旅程。

Journey Analytics 提供了各个层面的见解,从公司范围的汇总一直到单个用户的体验。它有助于您从整体上了解客户旅程,而不必使用单独的工具来检查渠道和会话数据。您从分析中获得的知识可以帮助您改善业务成果,推动转化,并提供一致和令人满意的客户体验。

Journey Analytics 中基于角色的仪表板可以轻松直观地识别重要趋势,然后更深入地挖掘客户行为的原因。您还可以确定客户的问题所在,然后重放单个客户会议,以了解问题的确切根源。

IBM Watson 客户体验分析仪表板来源:IBM

免责声明: 此处表达的部分观点仅代表本文作者的观点,不一定代表 IBM 公司的观点。博客上的部分内容是版权所有,除非在 IBM Corporation 下另有说明,否则保留所有权利。

支持各种类型的医疗保健数据来构建 10 大 DL 应用

原文:https://towardsdatascience.com/enabling-various-types-of-healthcare-data-to-build-top-10-dl-applications-f5c6f45eddba?source=collection_archive---------41-----------------------

探索医疗保健中的 7 种数据类型、深度学习技术和顶级应用,以应用深度学习

尽管医疗保健行业价值**【1】8 万亿美元,但只有 20%的人能够获得高质量的医疗保健。世界人口正在老龄化。迫切需要基于价值的医疗保健[2]。医疗保健行业正朝着数据驱动的方式发展。如今,个人健康和人口医疗保健数据的数量正在快速增长。医疗保健行业存在资源和准入限制。一方面,病理学家、放射科医生和其他临床医生短缺,另一方面,手术和疾病(如癌症)的数量在增加。解决这个问题的唯一方法是通过技术。**

在这篇文章中,重点是:

有哪些不同类型的医疗保健数据

哪种深度学习(DL)技术用于医疗保健和

我们如何利用这些数据和技术来构建医疗保健领域的 10 大应用

让我们从不同类型的数据开始,我们使用这些数据来建立真实世界的机器学习/深度学习模型。深度学习是机器学习的一个子集。深度学习不需要以提供更多数据来建立模型为代价来手工制作特征。

**有 7 种类型的数据即, 数值、分类、文本、图像、视频、语音和信号 不考虑领域来构建深度学习模型。表 1 总结了来自医疗保健领域的不同数据类型。根据数据类型,预处理步骤可能会有所不同。然后,我们总结了每种类型的医疗数据基于深度学习的医疗应用。**

**表 1:数据和医疗保健应用的类型**

接下来,我总结了各种类型的深度学习技术,以及我们如何在医疗保健应用中使用这些技术,并在表 2 中给出了具体示例。这些技术包括简单的前馈网络、卷积神经网络(CNN)到递归神经网络(RNN)以及最新的注意力网络。

表 2:深度学习技术的类型和在医疗保健中的应用

寻找深度学习在医疗保健中的应用的另一个维度是基于医疗保健系统的各个阶段,如表 3 所示。预防胜于治疗。DL 在医疗保健系统的早期和晚期都起着重要的作用[3]。

表 3:健康序列和深度学习应用

在这种背景下,让我们使用前面描述的各种类型的数据来研究医疗保健领域的 10 大深度学习应用:

  1. 医学影像:
  • 卷积神经网络( CNN ) 2D/3D 在医学成像中发挥着重要作用[4]
  • 我们利用 CNN 的进展来阐述医学成像中的分类、对象检测和分割类问题
  • 这涉及到对大量图像的处理,提炼其对信息的理解和解释
  • 迁移学习 来自 AlexNet,GoogleNet 帮助构建了很多图像分类问题
  • DL 模型被移植到计算机断层摄影(CT)、磁共振成像(MRI)盒中,以识别重建图像 的 质量,并检查任何问题,例如运动检测
  • 实时图像重建—可以更好地重建 CT 中的图像。这可以减少患者的辐射暴露。

2.更快的诊断:

  • 分析医学图像/数据通常是一项困难且耗时的任务
  • GPU 加速 DL 自动分析 并提高诊断人员的准确性
  • DL 帮助医生 更好地分析疾病 并为患者提供最好的治疗
  • 可以充当第二客观意见

3.早期检测/预警:

  • DL 模型是通过访问来自各种设备(如移动应用程序、手表和观察模式)的连续数据而构建的
  • 疾病可以在更早的时候 检测出来,例如在定期健康检查期间(可以在疾病发展之前采取纠正措施)
  • 尽早发现症状,并根据需要建议去看医生/进行诊断测试,而不是定期检查

4.提高效率@放射科:

  • 放射科医生可以花更多的时间与患者在一起,而不是医疗报告,包括远程放射学

  • 工作流程 改进 以放射学为服务

  • 没有因疲劳或其他原因造成的误诊

5.个性化治疗:

  • 每个人的健康建议和疾病治疗都是根据他们的 病史 、过去的状况、饮食、压力水平&类似患者量身定制的
  • 根据一个人的病史优化治疗方案

6.基因组学——精准医学:

  • 了解基因组并帮助患者了解可能影响他们的疾病
  • 遗传因素 喜欢突变导致疾病
  • 大量的计算工作,但活跃的研究领域可以改变未来药物的使用方式[5,6]

7.药物发现:

  • 更快地关联、吸收和连接现有数据,以帮助 发现数据池中的模式
  • 加快临床试验研究。药物发现可能需要长达 10 年的时间,而使用 DL 和 ML 方法可以大大缩短时间。[7]
  • 多样化的数据集 避免不平衡数据带来的偏差。我们可以使用最新的技术,如生成对抗网络(GAN)来处理数据中的不平衡[8]

8.机器人手术:

  • 我们知道外科手术中精确的重要性,比如癌症治疗
  • DL 模型有助于外科医生获得更精确的细节[9]

9.人群健康:

  • 基于 人口数据趋势 汇集的消费者数据建立模型
  • 我们可以与政府合作,收集大规模的数据,并建立基于数字图书馆的模型

10.信息提取:

  • 从使用自然语言处理(NLP)的临床笔记到 匿名化、标注再到做语义分析和推理
  • 使用图像字幕技术生成报告
  • 使用提取的信息构建多模态聊天机器人

接下来,让我们看看实施这些顶级 DL 应用程序所面临的挑战,并讨论未来的范围。

挑战:

我们听到的一个常见问题是“深度学习有效,但仍被视为黑盒 ”。 即它是如何以及为什么工作的?这对数据科学家和临床医生都很重要。可解释人工智能(XAI)的最新发展有助于建立对深度学习模型产生的结果的信任。我计划发表另一篇关于 XAI 的文章,所以不在这里讨论这些话题。

深度学习处于采用周期的早期阶段,然而,技术的成熟度并不是采用的唯一因素。我们需要建立对技术的信任,应该能够重现临床验证的结果。这可以增加医生对该技术的接受度。

尽管担心会被替代,但实际上这项技术将补充医生的不足。很少有更多的挑战,例如:

  • 质量的可及性和建模数据的多样性
  • 跨国家/医院的数据访问问题
  • 特定地区的数据驻留和隐私法律也限制了患者数据的共享,如通用数据保护法规(GDPR)
  • 来自监管环境的批准

未来范围:

我们期待通过 FDA 的批准,使用深度学习模型成为主流。正如预防胜于治疗一样,我们可以想到 左移 的策略来减轻损害。如果一个被保险人生病了,这是医院的收入来源。然而,我们发现保险公司有一种新的创收方式。向人收取保险费,保护人不生病是新现象。

随着技术的进步,我们预计医生会广泛接受深度学习模型和人工智能。“通过软件进行诊断的第二意见可能会在 10 年内成为一种趋势”——Narayana Health 董事长 Devi Shetty 博士。

期待生活在一个更美好的世界,通过科技获得可负担的医疗保健。

参考文献:

[1]https://www . health care . digital/home/tag/% 248% 20 trillion % 20 health care % 20 industry

[2]https://abcnews.go.com/Health/Healthday/story?id=4509618&page = 1

[3]https://www . NVIDIA . com/content/g/pdf/Deep-learning-Journey-in-health care . pdf

[4]https://www . science direct . com/science/article/ABS/pii/s 1361841517301135

[5]https://www . frontier sin . org/articles/10.3389/fgene . 2019.00049/full

[6]https://www . the guardian . com/science/2019/sep/28/genome-sequencing-precision-medicine-bespoke-health care-NHS

[7]https://www . science direct . com/science/article/pii/s 1359644617303598

https://arxiv.org/pdf/1803.01229.pdf

[9]https://emerj . com/ai-sector-overviews/machine-learning-in-robotics/

****【https://www.youtube.com/watch?v=_1US0QwENEY ****

请分享您的宝贵意见和建议。感谢阅读。快乐学习。

发现自然语言处理模型中的编码语言知识

原文:https://towardsdatascience.com/encoded-linguistic-knowledge-in-nlp-models-b9558ba90943?source=collection_archive---------31-----------------------

深度学习模型中发现编码语言知识的“探针”的背景、调查和分析

本文作者为 凯于尔福尔杜 阿米特谢思 。本文详细阐述了更广泛的封面故事 “现代 NLP 的兴起和可解释性的需要!”在 Embibe,我们在搭建 NLP 平台解决学术内容众多问题的同时,迫切需要开放性问题的答案。

现代 NLP 模型(伯特、GPT 等)通常以端到端的方式训练,精心制作的特征工程现在已经灭绝,这些 NLP 模型的复杂架构使其能够学习端到端的任务(例如,情感分类、问题回答等)。)而没有明确指定特性[2]。语言特征(如词性、共指等)在经典的自然语言处理中起着关键的作用。因此,理解现代 NLP 模型如何通过“探究”它们所学习的东西来做出决策是很重要的。这些模型会从未标记的数据中自动学习语言特征吗?我们如何解释现代 NLP 模型的能力?让探测

探头就是调查。由马库斯·温克勒在 Unsplash 上拍摄的照片

语言学:背景

语言知识是自然语言处理的一个重要方面。我们可以从以下几个方面来考虑,

  • 句法:分析句子的结构和单词的连接方式。
  • 形态学:研究单个单词的内部结构,以及新单词是如何由这些基本单词的变体形成的。
  • 音系学:对构成语言基本成分的语音系统的研究。
  • 语义:处理单个单词和整个文本的意思。

图一。一份来自克什米尔的十七世纪 桦树皮手稿pāṇini's 语法论著(图片来源:https://en.wikipedia.org/wiki/Panini)**

在统计方法和经典机器学习中,解决任何与自然语言处理相关的问题都涉及推导上述语言知识。因此,研究界关注了许多与语言知识相关的任务。我们可以看到如下几个例子:

图 2:一句话中的语言学知识举例。(图片来自 其他文章 )

  • 词性:词的句法范畴,即名词、动词、形容词、代词等。
  • 成分树(或短语结构语法):短语结构规则考虑到句子结构是以成分为基础的,一棵解析树将这些成分排列成具有成分关系的树形结构。
  • 依存树(或称依存文法):依存文法规则认为句子结构是以依存为基础的,依存解析树将单词排列成有依存关系的树形结构。
  • 共指:两个词或短语与共同所指物之间的关系。
  • 引理化:使用形态分析去除前缀或后缀后,导出基本引理词。

以上是几个与语言学知识相关的重要任务的例子,其中词性主要处理句法知识,依存树,共指对进一步理解语义很重要,词条化是形态学的例子。

许多其他任务进一步分析句子的语言属性,如语义角色、语义原型角色、关系分类(词汇和语义)、主语名词、主要助动词、主谓一致等。

现代自然语言处理模型

现代 NLP 模型要么基于 LSTM,要么基于变压器。ELMO 和乌尔菲特是基于 LSTM 架构的语言模型的例子。相反,伯特[1]和 GPT 是基于语言模型的变形金刚架构的例子。对于研究的其余部分,让我们以“BERT”为例作为参考。

  • BERT 模型以屏蔽词预测和对大量未标记数据的下一句预测为目标进行预训练。
  • 预训练的 BERT 模型通过使用特定于任务的层对其进行扩展来进行微调,这些特定于任务的层用于具有有限标记数据的任务,如“情感分析”、“文本分类”或“问题回答”。

由预训练的 BERT 模型产生的表示对相关信息进行编码,这使得能够利用非常有限的标记数据进行特定于任务的微调。问题是,

BERT 中编码了哪些语言学知识?

因此,一系列研究试图了解神经网络中捕捉的是哪种语言信息。不同方法中最常见的主题可以分为*“探针**”(或探测分类器、诊断分类器、辅助预测任务),它探测神经网络的内部机制如何分类(或执行)辅助语言任务(或探测任务,或辅助任务)。*

图三。伯特模型上探针的示意图。它展示了如何使用注意机制将输入令牌置于连续的层中。显示了两种类型的探针,(1)基于表征的,和(2)基于注意力的。注意,这个图是为了更广泛的说明,所以没有显示像 CLS 和 SEP 这样的特殊标记。

“探针”是如何工作的?

  • 探针是浅层神经网络(通常是一个分类器层),插在为主要任务训练的神经网络的中间层或注意力头的顶部。探针有助于调查不同的层或注意力头捕捉到了什么信息。使用辅助任务来训练和验证探测器,以发现是否捕获了这种辅助信息。
  • 图 3 示出了如何将探测分类器插入不同层或注意力头的顶部,以发现与不同层和注意力头的辅助任务相关的编码信息。
  • 比方说,我们想要调查来自 BERT 模型的编码表示是否捕获语言信息,如“如果一个动词是助动词”或“如果一个短语是主语名词”。助动词是助动词,主语名词是充当主语的名词短语。这些任务可以被框定为探头的“辅助任务”。例如,在句子“孩子们整天在玩板球”——“是助动词,”是主动词,“孩子们是主语名词,“板球是宾语名词。
  • 如果探测分类器不能很好地完成语言信息的辅助任务,这意味着这种信息没有被编码在模型的内部表示中,这也是可能的,因为它可能不需要解决模型的主要目标。

“探索”与微调或多任务学习有什么不同?

表 1。探针 vs 微调 vs 多任务学习

  • “探针”是 而不是 与对下游任务的微调有关,无论是在目标上还是在方法上。
  • *表 1 显示了对比情况。*
  • “探针”是为了发现编码的语言知识,而微调和多任务学习在一个或多个主要任务上训练模型。

图 4。多任务学习与探究

  • 如图 4 所示,“探针”可以访问模型内部但不能更新模型参数,另一方面,微调和多任务学习不访问模型内部,但它们可以更新模型参数。
  • 就复杂性而言,“探针”应该是浅层的(即模型顶部的单层分类器),而微调和多任务学习可以根据下游任务的复杂性堆积深层[7][8]。

什么是不同类型的“探针”?

这些探测分类器可以基于它们利用什么样的神经网络机制来探测语言知识而被分类。这些主要是

  • ***内部表示:*在来自不同层的内部表示之上构建一个小型探测分类器,以分析不同层编码了什么语言信息。
  • ***注意力权重:*探测分类器建立在注意力权重之上,以发现注意力权重模式中是否存在潜在的语言现象。

(A)基于“探测”的内部表示:

相当多的技术正在探索在像 BERT 这样的模型的不同层次上,有多少语言知识被编码在内部表示中。让我们来看几个例子。

***(A.1)边缘探测:*Tenney 等人[4][5]提出的框架旨在探测编码在模型的上下文化表示中的语言知识。

  • 对于词性、成分、依存关系、实体、语义角色标记、语义原型角色和共指消解等辅助任务,它比较了伯特、GPT、ELMO 和科夫等模型的上下文化表示的性能。
  • 边缘探测将结构化预测任务分解成一种通用格式,其中探测分类器从句子中接收一个文本区间(或两个区间),并且必须预测诸如成分或关系类型等标签。从那些目标区间内的令牌的每令牌嵌入中。
  • BERT-Large 模型的辅助任务总体性能的宏观平均值为 87.3,,而使用非情境化表示的基线探测器达到了 75.2 。因此,大约 20%的额外语言知识作为语境化的一部分被注入。

(A.2) BERT 重新发现经典的 NLP 管道 : Tenny 等人【3】【9】进一步分析了语言学知识从何而来。

  • ***重心:*重心反映了参与计算不同层的内部表示的标量混合(加权池)的平均层。对于每一项任务,直观地说,我们可以解释为更高的重心意味着该任务所需的信息被更高层所捕获。
  • ***期望层:*用不同层的内部表示的标量混合来训练探针分类器。层 I 的贡献(或差异分数)通过取用层 0 至层 I 训练的探测器的“性能”与用层 0 至层 i-1 训练的探测器的“性能”之差来计算。期望层是对每一层的差异分数的期望。

图 5:探头性能,以及图层对辅助任务的贡献(图片来源, Tenney 等人【5】)**

  • 在图 5 中,行标签是探测语言知识的辅助任务。每个任务的探测分类器的 F1 分数在前两列中提到,其中 l=0 表示辅助任务在非上下文表示上的表现,l=24 表示通过混合来自 BERT 模型的所有 24 层的上下文表示的辅助任务表现。预期层以紫色显示(重心以深蓝色显示)。
  • 预期层是最大的额外语言知识的来源。可以看出,关于句法任务的语言知识是在最初几层获得的,而关于语义任务的语言知识是在后来几层获得的。

(B)基于注意力权重的“探针”:

“伯特在看什么?对 BERT 注意力的分析”,Clark 等人[2]探讨了 BERT 中语言知识的注意力权重。有趣的是,我们注意到特定的注意头是如何表达语言现象的,而注意头的组合可以预测语言任务,如与艺术表现水平相当的依存语法。

(B.1)具体注意事项

  • 从图 6 中可以看出,BERT 中的特定注意力中心表达特定的语言现象,其中一个标记根据注意力中心表达的语言关系参与其他标记。

图 BERT 中特定注意头表达的语言现象。(图片来源: 克拉克等人【3】)**

  • 上面显示了六种不同注意力的可视化效果。BERT 基本模型有 12 层,每层有 12 个注意头。图 5 中左上的图表示第 8 层中的第 10 个注意头。客体关注其名词的模式是显而易见的。同样,在第 8 层的第 11 个注意头中,名词修饰语(限定词等。)正在关注他们的名词。同样,我们可以注意到其他情节中的注意头是如何表达语言知识的。

表 2:特定注意头的依存关系分类精度。克拉克等人【3】

  • 注意到注意力头作为现成的探测分类器的表现真是令人惊讶。

如表 2 所示,对于每个依存关系,特定注意头如何实现预测依存标记的分类性能。对于行列式(det)、直接宾语(dobj)、所有格词(poss)、被动助词(auxpass)等情况,与基线模型(预测最佳固定偏移量处的令牌)相比,性能增益是巨大的 (~100%)

(B.2)注意力头部组合

表 3:不同基线和探测技术的性能。UAS 是用于依存首部令牌预测的未标记附件分数。克拉克等人【3】

  • 在直接采用注意力权重的线性组合以及具有非上下文嵌入(如 GloVe)的注意力权重上训练的探测分类器,给出了与依赖于内部上下文表示的相对复杂的模型相当的性能,用于依存性解析任务。
  • 同样,关于共指、消解任务的实验也显示了类似的潜力。也就是说,我们可以得出结论,BERT 中的注意机制也编码和表达语言现象。

探索“探针”

既然我们已经了解了基于表征的探针和基于注意力权重的探针,以使用辅助任务来发现编码的语言知识,那么询问更深层次的问题将会很有趣:

  • 模型越大,对语言知识的编码越好吗?
  • 如何检查模型对语言知识编码的泛化能力?
  • 我们能否解码语言学知识,而不是依赖浅层探针分类器标签?
  • 探针有哪些局限性,如何得出结论?
  • 我们能注入语言学知识吗?
  • 编码语言知识能捕捉意义吗?
  • 编码的语言学知识对于自然语言理解来说足够好吗?

让我们在下一篇文章*“超越**分析 NLP 模型的编码语言能力&中进一步阐述上述问题。(即将推出)*

参考文献:

  1. Devlin 等人《BERT:用于语言理解的深度双向转换器的预训练》。NAACL 2019。
  2. Belinkov 等人“神经语言处理中的分析方法:调查”,ACL 2019
  3. 凯文·克拉克,乌尔瓦什·汉德尔瓦尔,奥默·利维,克里斯多佛·d·曼宁,“伯特在看什么?伯特注意力分析”,2019
  4. 伊恩·坦尼,迪潘詹·达斯,艾莉·帕夫利克,《伯特重新发现经典 NLP 流水线》,2019
  5. Tenney 等人“你从上下文中学到了什么?语境化词语表征中的句子结构探索”,ICLR 2019
  6. 阿迪等“使用辅助预测任务对句子嵌入的细粒度分析”,ICLR 2017
  7. Stickland 等人“BERT 和 PALs:多任务学习中高效适应的投射注意层”,ICML 2019
  8. 周等《极限-BERT:语言学告知多任务 BERT》,2019

PyTorch 多步时间序列预测的编解码模型

原文:https://towardsdatascience.com/encoder-decoder-model-for-multistep-time-series-forecasting-using-pytorch-5d54c6af6e60?source=collection_archive---------3-----------------------

丹尼尔·利维斯·佩鲁西在 Unsplash 上的照片

编码器-解码器模型已经提供了像语言翻译等的序列到序列 NLP 任务的最新结果。多步时间序列预测也可以被视为 seq2seq 任务,为此可以使用编码器-解码器模型。本文提供了一个编码器-解码器模型来解决 Kaggle 的时间序列预测任务,以及获得前 10%结果的步骤。

解决代码可以在我的 Github repo 中找到。模型实现的灵感来自于 Pytorch seq2seq 翻译教程,时间序列预测思想主要来自于类似竞赛的 Kaggle 获奖解决方案。

[## 高森 20/pytorch-ts

使用编码器-解码器架构进行时间序列预测的教程- gautham20/pytorch-ts

github.com](https://github.com/gautham20/pytorch-ts)

使用的数据集来自过去的 Kaggle 竞赛— 商店商品需求预测挑战,给定 10 家不同商店的 50 种商品过去 5 年的销售数据(从 2013 年到 2017 年),预测未来 3 个月(2018 年 11 日到 2018 年 3 月 31 日)每种商品的销售额。这是一个多步多站点时间序列预测问题。

比赛

提供的功能非常少:

有 500 个独特的商店商品组合,这意味着我们预测 500 个时间序列。

随机选择 10 件商品的销售图

数据预处理

特征工程

深度学习模型善于自己发现特征,因此可以将特征工程保持在最低限度。

从图中可以看出,我们的数据具有每周和每月的季节性和每年的趋势,为了捕捉这些,向模型提供了日期时间特征。为了更好地捕捉每个项目销售的年度趋势,还提供了年度自相关。

这些功能中有许多实际上是循环的,为了向模型提供这些信息,对日期时间功能应用了正弦和余弦转换。这里可以找到为什么这是有益的详细解释— 编码循环连续特征— 24 小时时间

月份特征的正弦和余弦变换

所以最终的特性如下所示。

数据缩放

神经网络期望所有特征的值都在相同的尺度上,因此数据缩放成为强制性的。每个时间序列的值被独立地标准化。每年的自相关和年份也被归一化。

序列构建

编码器-解码器模型将一个序列作为输入,并返回一个序列作为输出,因此我们拥有的平面数据帧必须转换成序列。

输出序列的长度固定为 90 天,以满足我们的问题要求。输入序列的长度必须根据问题的复杂性和可用的计算资源来选择。对于这个问题,选择 180 (6 个月)的输入序列长度。通过对数据集中的每个时间序列应用滑动窗口来构建序列数据。

数据集和数据加载器

Pytorch 提供了方便的抽象——数据集和数据加载器——将数据输入模型。数据集将序列数据作为输入,并负责构建要提供给模型的每个数据点。它还处理提供给模型的不同类型的特征的处理,这部分将在下面详细解释。

使用 dataloader 将数据集中的数据点一起批处理并提供给模型。

模型架构

编码器-解码器模型是用于解决序列间问题的递归神经网络(RNN)的一种形式。编码器-解码器模型可以直观地理解如下。

编码器-解码器模型由两个网络组成——编码器和解码器。编码器网络学习(编码)输入序列的一个表示,它捕捉其特征或上下文,并给出一个向量。这个向量被称为上下文向量。解码器网络接收上下文向量,并学习从中读取和提取(解码)输出序列。

在编码器和解码器中,编码和解码序列的任务由一系列循环单元处理。解决方案中使用的循环单元是门控循环单元(GRU ),以解决短期记忆问题。关于这一点的更多信息可以在 LSTM 和 GRU 的插图指南中找到。

下面给出了解决方案中使用的模型的详细架构。

编码器

编码器网络的输入具有*(序列长度,n _ 值)*的形状,因此序列中的每一项由 n 个值组成。在构造这些值时,不同类型的特征被不同地对待。

时间相关特性 —这些是随时间变化的特性,例如销售和日期时间特性。在编码器中,每个顺序的时间相关值被馈送到 RNN 单元。

数字特征 —不随时间变化的静态特征,如序列的年度自相关。这些特征在整个序列中重复出现,并被输入 RNN。重复输入和合并值的过程在数据集中处理。

分类特征 —商店 id 和商品 id 等特征可以通过多种方式进行处理,每种方式的实现可以在 encoders.py 中找到。对于最终的模型,分类变量是一次性编码的,在序列中重复,并输入到 RNN 中,这也在数据集中处理。

具有这些特征的输入序列被送入递归网络— GRU 。下面给出了所使用的编码器网络的代码。

解码器

解码器从编码器接收上下文向量,此外,解码器的输入是未来日期时间特征和滞后特征。模型中使用的滞后特征是前一年的值。使用滞后特征背后的直觉是,考虑到输入序列限于 180 天,提供超过此时间范围的重要数据点将有助于模型。

与直接使用循环网络(GRU)的编码器不同,解码器通过解码器单元循环构建。这是因为从每个解码器单元获得的预测作为输入传递到下一个解码器单元。每个解码器单元由一个 GRUCell 组成,其输出馈入一个提供预测的全连接层。来自每个解码器单元的预测被组合以形成输出序列。

编码器-解码器模型

编码器-解码器模型是通过将编码器和解码器单元封装到一个模块中来构建的,该模块处理二者之间的通信。

模特培训

该模型的性能高度依赖于围绕优化、学习率计划等所采取的训练决策。我将简要地介绍一下它们。

  1. 验证策略— 由于我们的数据与时间相关,因此跨部门培训-验证-测试分割不起作用。依赖于时间的训练-验证-测试分离提出了一个问题,即模型不是在最近的验证数据上训练的,这影响了模型在测试数据中的性能。
    为了应对这一问题,一个模型根据 2014 年至 2016 年的 3 年历史数据进行训练,并预测 2017 年的前 3 个月,用于验证和实验。最终模型根据 2014 年至 2017 年的数据进行训练,并预测 2018 年的前 3 个月。基于从验证模型训练中获得的知识,在没有验证的情况下以盲模式训练最终模型。
  2. 优化器 —使用的优化器是 AdamW,它已经在许多学习任务中提供了结果的状态。关于 AdamW 更详细的分析可以在 Fastai 中找到。探索的另一个优化器是 COCOBOptimizer ,它不明确地设置学习率。在用 COCOBOptimizer 进行训练时,我观察到它比 AdamW 收敛得更快,尤其是在初始迭代中。但是最好的结果是通过使用 AdamW 和一个周期学习获得的。
  3. 学习率调度—1 使用周期学习率调度器。通过使用用于循环学习的学习率查找器来确定循环中的最大学习率。使用的学习率查找器的实现来自库— pytorch-lr-finder 。
  4. 使用的损失函数是均方误差损失,它不同于完井损失— SMAPE 。MSE 损失提供了比使用 SMAPE 更稳定的收敛。
  5. 编码器和解码器网络使用了独立的优化器和调度器对,从而提高了结果。
  6. 除了权重衰减之外,在编码器和解码器中都使用了丢弃来对抗过拟合。
  7. 构建了一个包装器来处理训练过程,能够处理多个优化器和调度器、检查点和张量板集成。这方面的代码可以在 trainer.py 中找到。

结果

下面的图显示了模型对 2018 年前 3 个月的预测,针对商店的单个商品。

通过绘制所有项目的平均销售额和平均预测来消除噪声,可以更好地评估该模型。下面的图来自验证模型对特定日期的预测,因此可以将预测与实际销售数据进行比较。

来自编码器-解码器模型的结果将在竞赛排行榜中提供前 10%的排名。

为了达到这个结果,我做了最小的超参数调整,所以还有更多改进的余地。还可以通过探索注意机制来进一步改进模型,以进一步增强模型的记忆。

*感谢阅读,让我知道你的想法。祝你今天开心!玩的开心!*😄

参考

从无到有的 NLP:从一个序列到序列网络的翻译和注意

Web 流量时间序列预测解决方案

编码周期性连续特征— 24 小时制

LSTM 和 GRU 的图解指南

AdamW 和超收敛是目前训练神经网络最快的方法

通过硬币下注训练深度网络而不学习比率

超收敛:使用大学习速率非常快速地训练神经网络

编码器——如何编写,如何使用

原文:https://towardsdatascience.com/encoders-how-to-write-them-how-to-use-them-d8dd70f45e39?source=collection_archive---------49-----------------------

从头做起

通过这个“从头开始”的演练,探索编码器在机器学习中的多种用途!

在一个完美的世界里,所有的程序员、科学家、数据工程师、分析师和机器学习工程师都梦想所有的数据都能以最干净的形式到达他们的家门口。不幸的是,人类在开始用二进制或“哔哔哔”说话之前就发展了语音字母。因此,不幸的是,在处理数据集时,遇到单词(或“哔哔哔”语言中的“字符串”)而不是数字是非常常见的,即使是当今最干净的数据集也是如此。

数据、字符串和单词组合的问题在于,人工大脑无法直接分析单词。计算机是定量说话,而不是定性说话。让计算机解释单词,尤其是带有主观意义或情感的句子,就像让饼干怪兽吃芹菜一样;

这是不可能的。

幸运的是,这个问题有一个解决方案——有许多不同的方法可以将单词转换成数字进行分析!虽然这样做可能无法让计算机分析关于单词的某些事情,但它肯定有助于解决你在数据科学这一教育领域可能遇到的常见机器学习问题。通常,每当机器学习使用字符串时,数据科学家都会使用编码器。事不宜迟,我们来看看一些编码器!

笔记本

独热编码器

我是世上最有趣的人。

如果你是机器学习的新手,你应该尽快掌握的一个技巧是对数据帧进行一次热编码的能力。一键编码,也称为一键编码或哑编码,采用一种非常激进的方法来处理分类变量。通常,我在尽可能少的类别的情况下使用 One-Hot。这是因为首先,与其他可用的算法相比,一位热编码数据占用了大量的内存和磁盘空间。此外,One-Hot 确实在这种光线下闪闪发光。

当处理大型分类特征集时,One-Hot 可以将 5 列数据帧转换为 50 列数据帧,这非常难以处理!最重要的是,通常随着类别中的更高股份,One-Hot 的有效性可能会急剧下降。为了理解为什么会发生这种情况,让我们写一个一次性编码器,看看当我们使用它时会发生什么。我们将从定义函数开始。当使用数据修改和数据破坏方法时,最起码做一个断言或浅层复制是一个好主意**。因为我们正在处理数据帧,所以使用像 copy 这样的库可能是个好主意,尤其是在 Python 中。对于这个示例,我不打算这样做——因为我的意图是将列添加到我的数据框架中,而我的数据本身是非常不重要的,并且仅用于演示目的。**

function onehot(df,symb)copy = df

接下来,我们需要遍历数据帧中的唯一值:

for c in unique(copy[!,symb])

接下来,我们将使用一点聪明的迭代语法在这个循环中创建一行一热算法:

copy[!,Symbol(c)] = copy[!,symb] .== c

基本上,它所做的是遍历 copy 的“ symb” 列上的所有值。这个例子中的 Symb 当然代表了我们字典的关键列。我们用copy[!, Symbol(c)]添加一个新的键,然后将它设置为一个条件。的。Julia 中的操作数和操作数是一回事,只是对于整个数组。因此,这将用布尔值(true 或 false)填充新列,这些值对应于原始列中的值是否对应于新列的值。现在我们将返回复制数据帧并结束我们的函数。

function onehot(df,symb)copy = dffor c in unique(copy[!,symb])copy[!,Symbol(c)] = copy[!,symb] .== cendreturn(copy)
end

这在实践中是什么样子的?

看一看:

如您所见,我们现在有四个布尔列。天气列中的每个唯一字符串都有一列。

顺序编码

使分类特征数值化的一种完全不同的方法是序数编码。顺序编码器不采用使用布尔表示值的一次性方法,而是使用整数——

谁能想到呢?!

序数编码比一键编码占用更少的 CPU,更重要的是占用更多的内存。每当类别非常高的时候,顺序编码确实一枝独秀。在某一点上,一次性编码是跟不上的,顺序编码是正确的选择。序数编码器到底是怎么把字符串变成整数的?

让我们看一些代码来找出答案!

正如我在之前的例子中解释的那样,将变量复制到这里是明智的。添加一个简单的副本比因为一些混乱的数据而不得不原路返回或重新开始工作要好得多,如果你在 REPL 工作,尤其如此。在这个函数中,我要做的第一件事是创建一个集合。

function OrdinalEncoder(array)uni = Set(array)

集合是一种奇妙的类型,在 Julia 和 Python 中都可用,它将使获取唯一值比其他方式更快更简单。在我们得到我们的集合之后,我们将创建一个新的字典:

lookup = Dict()

这不仅是一个“类型”意义上的字典,而且是一个非常真实的字典,用于查找与键对应的值。然而,在我们可以在字典中搜索我们最喜欢的单词之前,我们需要填充它。我们可以通过迭代地枚举我们的集合并将那些键和相应的值添加到我们的字典中来做到这一点:

for (i, value) in enumerate(uni)push!(lookup, (value => i))
end

接下来,我们将创建一个新阵列:

newarray = []

然后,在检查字典中它对应的键之后,我们将迭代地将我们的值追加回它:

for row in arraynewvalue = lookup[row]append!(newarray, newvalue)end

然后我将添加我的 predict()函数,并返回一个类型以方便使用它。

predict() = newarray
()->(predict)

整体功能如下:

function OrdinalEncoder(array)uni = Set(array)lookup = Dict()for (i, value) in enumerate(uni)push!(lookup, (value => i))endnewarray = []for row in arraynewvalue = lookup[row]append!(newarray, newvalue)endpredict() = newarray()->(predict)
end

注意到什么可疑的了吗?

幸运的是,这个函数也可以简化到令人痛苦的程度。看看这个:

function OrdinalEncoder(array)uni = Set(array)lookup = Dict()[push!(lookup, (value => i)) for (i, value) in enumerate(uni)]predict() = [row = lookup[row] for row in array]()->(predict)
end

那好多了!

现在让我们在数据集上测试一下。

oe = OrdinalEncoder(df[:Weather])
df[:OrdinalEncoded] = oe.predict()

如您所见,顺序编码器只是枚举数据帧中的所有唯一值,然后将该值重新应用于列中的所有观察值。非常简单,但也是我今天要介绍的三种编码器中最通用和最有效的。这款编码器的伟大之处在于,它在很大程度上是“一刀切”的体验。这是因为性能不一定是最重要的,它可以很好地处理大类别和小类别,尽管它可能会失去一些准确性,这取决于它所处的环境。

标签编码器

什么是标签编码器?阅读这篇文章的人很可能知道什么是标签编码器——因为我们刚刚从头开始创造了一个!没错,标签编码器和顺序编码器是一样的——至少在功能上是一样的。不,这与我们看到的虚拟编码和一位热码编码的情况不太一样。这两个术语存在的全部原因在于 Sklearn 构建其预处理包的方式。为了让标签编码器和顺序编码器都非常有效地工作,它们需要分开。这两者之间的最大区别是标签编码器通常用于目标,而序号编码器通常用于编码特征——就是这样!所以,如果你想知道代码是什么样子的,就在这里盖上函数定义,假装它写着“LabelEncoder”

function OrdinalEncoder(array)uni = Set(array)lookup = Dict()[push!(lookup, (value => i)) for (i, value) in enumerate(uni)]predict() = [row = lookup[row] for row in array]()->(predict)
end

ASCII 编码器

ASCII 编码器,也称为浮点编码器(为什么所有编码器都需要两个名称?)使用对拼音字母和符号进行编号的 ASCII 系统,根据字符串中包含的字符创建唯一的类别。这既有效又通用,因为该系统不仅可以应用于标准的分类问题,还可以应用于自然语言处理!最重要的是,这也非常容易做到,而且非常有效,尤其是在处理具有许多不同值的数据集时。

创建 ASCII 编码器的第一步是将字符串分成字符。这可以通过 split()方法或字符串上的迭代循环来完成。虽然后者更密集,这是我通常更喜欢的。

for dim in arraynewnumber = 0for char in dim

接下来,你要做一个操纵的决定。如果我们试图对这些字符执行某种自然语言处理,或者如果我们有绝对大量的类别,那么逐个字符地创建一个新的整数可能是明智的,这个新的整数是一系列数字,代表字符串中的各个字符。然而,由于我们只是试图对一个非常小的数据集进行分类,因此我建议将数字相加,就像这样:

newnumber += Float64(char)

然后,我们将它添加到新的数字列表中,并像以前一样创建预测函数,我们开始吧:

function FloatEncoder(array)encoded_array = []for dim in arraynewnumber = 0for char in dimnewnumber += Float64(char)endappend!(encoded_array, newnumber)endpredict() = encoded_array()->(predict)
enddf[:FloatEncoder] = fe.predict()

正如你所看到的,你会得到一个非常不同的结果,而且这个算法也可以被操纵来实现比分类编码更多的目标。

结论

编码器。是。厉害!学习读取数据和使用正确的编码器可能是使用每个编码器的最大问题。幸运的是,理解它们是如何工作的,并且能够编写它们,这使得想象什么样的编码器在您的特定情况下可能工作得非常好变得容易得多。不管你在这方面处于什么样的情况,你都会从中学习,并且能够以新的方式应用你新发现的技能。感谢您阅读我的文章,祝您白天(或晚上)休息愉快!)

机器学习中的分类变量编码

原文:https://towardsdatascience.com/encoding-categorical-variables-in-machine-learning-5644a43c123f?source=collection_archive---------39-----------------------

如何向机器学习模型输入分类数据

尼克·希利尔在 Unsplash 上的照片

分类数据需要以特殊的方式处理,才能用作机器学习模型中的一个特征。在说这种特殊方式之前,不如先说一下什么是分类数据。

分类数据表示一组有限的离散值。所以分类变量从有限的几个值中取一个值。分类数据的一些例子:

  • 汽车品牌:福特,丰田,宝马,…
  • 服装尺码:小号,中号,大号,加大号,…
  • 显示某种级别的类别:低、中、高
  • 颜色:蓝色,红色,黄色,…

分类数据可以根据它所代表的内容分成几组:

**名义数据:**类别并不意味着任何定量测量,数据中通常没有顺序。例如,种族、性别、语言是分类变量,但我们不能对这些变量的不同类别进行排序。

**序数数据:**与名义数据不同,类别之间是有顺序的。一个类别可以优于另一个类别,反之亦然。

  • 低、中、高
  • 冷,暖,热

现在是预处理分类数据的时候了,这样我们就可以在机器学习模型中使用它们。计算机只能处理用数字表示的信息。这就是为什么我们不能给机器学习模型类别或字符串作为输入。

我们首先需要将类别转换成数字。这个过程叫做标签编码。有些类别已经是数字了,比如电影分级从 1 到 5。我们不需要对这种分类变量应用标签编码步骤。

如果分类变量不是有序的(也就是说,它们没有等级顺序),标签编码是不够的。我们需要使用“哑元或“一个热码”编码对名义分类变量进行编码。假设我们对代表汽车品牌的分类变量进行了标签编码。编码器标签“道奇”为 3,“GMC”为 1。如果我们只是对这个变量进行标签编码,一个模型会认为“Dodge”比“GMC”更重要或更优越,这是不正确的。优选地,将每个类别表示为仅取两个值 1 和 0 的列。对于“道奇”品牌的汽车,只有“道奇”一栏的值变成 1,其他栏都是 0。通过这种方式,我们可以确保类别之间没有层次结构。

让我们看一个例子,这样就更清楚了。我创建了一个样本数据框架:

数据帧包括名义(品牌)和顺序(条件)数据。

标签编码

给类别分配标签的一种方法是使用 scikit-learn 的 LabelEncoder() :

因此,标签编码器为每个类别分配了一个编号。最好为每个类别使用单独的标签编码器,以防我们需要对列进行逆变换。然而,这种方法存在一个问题。您可能已经注意到,“条件”列中的平凡性没有保留。分配的标签有:

  • 好:1
  • 平均值:0
  • 差:2

如果普通性很重要,我们可以使用 Pandas replace 函数手动标记编码这些类别:

我们只需创建一个将类别映射到标签的字典,然后将这个字典作为参数传递给 replace 函数。

虚拟和一个热编码

虚拟或 one 热编码器将每个类别转换为取值为 0 或 1 的二进制列。让我们首先应用来自 scikit-learn 的 OneHotEncoder() :

这个过程非常简单。我们启动一个 OneHotEncoder()对象,并使用数据应用 fit_transform 方法。值得一提的是下降参数。数据集包含品牌列中的 6 个类别和条件列中的 3 个类别。因此编码器应该总共返回 9 列。但是,返回的数组有 7 列。原因是我们要求编码器删除第一列,这是有意义的,因为我们不会因为删除一列而错过任何信息。考虑有 6 个类别的“品牌”栏。我们删除了第一类的列,即“奥迪”。如果其他五列中的值为 0,则该行代表“奥迪”。看一下原始 dataframe,看到第四行的品牌是奥迪。此外,编码功能数组中第四行的前五列都是零。

另一种做这个操作的方法是使用熊猫的 get_dummies 功能。Get_dummies 函数返回一个数据帧,通过组合原始列名和类别名来分配列名。

pd.get_dummies(df)

我们还删除了第一列:

pd.get_dummies(df, drop_first=True)

感谢您的阅读。如果您有任何反馈,请告诉我。

使用 Python 加密和解密文件— Python 编程

原文:https://towardsdatascience.com/encrypt-and-decrypt-files-using-python-python-programming-pyshark-a67774bbf9f4?source=collection_archive---------3-----------------------

在本文中,我们将讨论如何使用 Python 加密和解密文件。

马库斯·斯皮斯克在 Unsplash 上的照片

目录

  • 介绍
  • 创建密钥
  • 加载密钥
  • 加密文件
  • 解密文件
  • 完整的面向对象编程示例
  • 结论

介绍

今天,我们观察来自所有不同来源的数据,最终挑战变成了数据的安全性和隐私性。这不仅涉及企业持有的主要数据集,还涉及 AI/ML 模型和算法,以及最终的预测数据。

随着越来越多的行业在决策中采用数据科学实践,数据量也在不断增长。在 AI/ML 和云计算的加密和安全领域,已经发现了几家公司,它们现在甚至允许对加密数据进行计算。

在不断发展的数据和信息传输世界中,文件内容的安全性仍然是公司最关心的问题之一。一些信息可以用密码保护(电子邮件、登录),而其他通过电子邮件或 FTP 传输的信息如果用一些关键字保护,效率会很低。这就是文件加密发挥重要作用的地方,它提供了参与文件传输的各方所寻求的安全性和便利性。

那么什么是加密呢?它是将信息转换成某种形式的代码以隐藏其真实内容的过程。访问文件信息的唯一方法是解密它。加密/解密的过程称为密码学。

让我们看看如何使用 Python 加密和解密我们的一些文件。我们将遵循对称加密,这意味着使用相同的密钥来加密和解密文件。

为了继续学习本教程,我们需要以下 Python 库:cryptography。

如果您没有安装它们,请打开“命令提示符”(在 Windows 上)并使用以下代码安装它们:

pip install cryptography

我们还需要一个我们将要使用的样本文件。下面是样本。包含一些学生成绩数据的 csv 文件:

https://pyshark.com/wp-content/uploads/2020/08/grades.csv

创建密钥

在我们的例子中,我们将使用对称方程:

Fernet 是经过认证的加密技术,它不允许在没有“密钥”的情况下读取和/或修改文件。

现在,让我们创建密钥,并将其保存在与数据文件相同的文件夹中:

如果您检查 Python 代码所在的目录,您应该会看到 mykey.key 文件。您可以用任何文本编辑器打开它(在我的例子中,它显示在本地目录中,因为我使用的是 VS 代码)。该文件应该包含一行,它是某种字符顺序的字符串。对我来说就是“vld 8 H2 teijk qpkkkndnknu 8 ya 2 fpibmoo 5 oc 7 jknasvk =”。

加载密钥

生成加密密钥后,我们需要将其加载到我们的环境中,以便加密/解密文件。

以下步骤非常简单,只需打开 mykey.key 文件并将其存储在本地内存中:

为了验证,我们将看到以下输出:

VlD8h2tEiJkQpKKnDNKnu8ya2fpIBMOo5oc7JKNasvk=

加密密钥现在作为密钥变量存储在本地。

加密文件

既然我们有了要加密的文件和加密密钥,我们现在将编写一个函数来利用它们并返回加密的文件:

让我们讨论一下我们在这里做了什么:

  • 我们将 Fernet 对象初始化为本地变量 f
  • 接下来,我们将原始数据(grades.csv 文件)读入原始数据
  • 然后,我们使用 Fernet 对象加密数据,并将其存储为加密的
  • 最后,我们将它写入一个新的。名为“enc_grades.csv”的 csv 文件

您可以在这里查看加密文件:

https://pyshark . com/WP-content/uploads/2020/09/enc _ grades . CSV

解密文件

加密文件后,例如,成功地将文件传输到另一个位置,您会想要访问它。现在,这些数据是加密格式的。下一步是将其解密回原始内容。

我们现在要遵循的过程是上一部分加密的逆过程。完全相同的过程,但现在我们将从加密文件到解密文件:

让我们讨论一下我们在这里做了什么:

  • 我们将 Fernet 对象初始化为 store is 作为一个局部变量 f
  • 接下来,我们将我们的加密数据(enc_grades.csv 文件)读入加密的
  • 然后,我们使用 Fernet 对象解密数据,并将其存储为解密的
  • 最后,我们将它写入一个新的。名为“dec_grades.csv”的 csv 文件

您可以在这里查看解密后的文件:

https://pyshark . com/WP-content/uploads/2020/09/dec _ grades . CSV

把“dec_grades.csv”和原来的“grades.csv”对比一下,你会发现其实这两个内容是完全一样的。我们的加密/解密过程是成功的。

完整的面向对象编程示例

这是一个额外的部分,我把一切都组织得更有条理:

这是一个使用上述类进行加密/解密的示例:

结论

本文介绍了使用 Python 进行基本的对称文件加密和解密。我们已经讨论了密码库的一些部分,并创建了一个完整的过程示例。

如果你有任何问题或者对编辑有任何建议,欢迎在下面留下评论,并查看我的更多 Python 编程文章。

原载于 2020 年 9 月 1 日【https://pyshark.com】

Google Colab 中 ResNet 的端到端改编—第 1 部分

原文:https://towardsdatascience.com/end-to-end-adaptation-of-resnet-in-google-colab-part-1-5e56fce934a6?source=collection_archive---------32-----------------------

入门

只需点击几下鼠标,就能训练出一个深度神经网络

来自 Unsplash.com,马库斯·斯皮斯克

我在这篇文章中提供的代码示例是几个小时的挫折和在互联网上四处搜寻的结果。

当我第一次开始自学深度神经网络时,我想找到一些我可以随时下载、即插即用并运行的东西——,但这很难找到。(再次)借用杰瑞米·霍华德的话,我真的很欣赏他如何从几行代码开始,证明训练一个深度神经网络不应该是令人生畏的。我想用 Google Colab 做类似的事情。

不涉及代码和硬件要求的细节,一开始,我真的很想体验一下训练需要多长时间,过程是什么样的,以及“端到端”网络的整个代码库是什么样的,它做了以下四件事:

  1. 下载并建立了一个深度神经网络
  2. 获取数据集并对其进行格式化以用于训练
  3. 训练神经网络并进行验证
  4. 准备好接受输入进行测试

输入谷歌 Colab。我就不多说了,除非给你这个:

猫&狗分类器使用 Resnet-18

你不需要知道任何 Python 来运行这个,你只需要两样东西——1)一个谷歌账户,这样你就可以启动笔记本;2)一个 Kaggle 账户。

这段代码下载了一个由成千上万张狗和猫的图像(标记为)组成的数据集,通过 ResNet-18 架构运行该数据集进行训练,一旦完成,它将为您提供一种轻松测试网络的方法。

让我们开始吧。

1.获取您的 Kaggle API JSON

首先,登录 Kaggle,点击右上角的图标,进入“我的账户”。向下滚动到标题为“API”的部分,然后单击“创建新令牌”。这将下载一个名为“kaggle.json”的 JSON 文件(希望下载到您的下载文件夹中)。

2.启动笔记本

查看下面的屏幕截图—确保在单击“更改运行时类型”时选择了 GPU,然后单击“保存”。然后选择“全部运行”。

Google Colab 上的运行时菜单。作者上传

3.上传您的 Kaggle JSON

我已经试着让这变得尽可能简单。向下滚动一点,注意到代码正在等待您上传您在步骤 1 中下载的 JSON 文件。

单击“选择文件”并选择您的 kaggle.json 文件。这将验证您的身份,以便您能够获取数据集。

代码正在等待您的 Kaggle JSON 文件。作者上传

4.向下滚动

我这样说并不是开玩笑,但是一旦你上传了 JSON 文件,代码就开始快速移动,很可能已经超过了你在页面上的位置,并且很可能已经开始训练,看起来像这样:

模型训练正在进行中。作者上传

这将需要一点时间,但不会太多,它可能运行在一个高端 GPU 上,为这样的任务而构建。

等待代码完成训练。它将输出这样一行:

‘Training complete in 4m 51s’
Best val Acc: 0.989370

5.准备好一张狗或猫的照片了吗

同样,与上面等待 JSON 文件的方式类似,代码现在正在等待您上传图片。由于它只在狗和猫身上进行训练,我建议从这些动物中挑选一只来测试一下。任何其他动物都可能提供异常但肯定不可靠的结果。

单击“选择文件”选择您的图片。

我发现了一张很棒的猫的照片:

来源:Unsplash.com

成功!作者上传

几个音符

肯定掩饰了上面代码的一些细节,因为我想向你展示这个极其复杂的过程是可以实现的。

Colab 的美妙之处在于,你不需要快速的互联网连接,或高端 GPU 或大量的内存来了解深度神经网络的内部工作方式。

我们在英特尔至强处理器和 NVIDIA 显卡上训练了上述模型(ResNet-18)。对于世界上的绝大多数人来说,这种硬件在本地是买不到的,因为它们的成本太高(几千美元)。

我们用一个几乎 1Gb 大小的数据集训练了上面的模型,下载 Colab 服务器只需几秒钟。在本地运行所需的时间和带宽也不是世界上大多数人能够获得的。

自学深度神经网络不应该受到你面前的技术的阻碍,你也不应该在头脑中想象这是如何在硬件上完成的。

有了我提供的 Colab 笔记本,你可以用一台简单的电脑和最少的网络连接来运行它。

但这只是第一部分!我希望你能在接下来的几周内加入我,我们将按部就班地解开这段代码。

请在下面留下任何问题,我会尽力回答。

参考

[1] 深度学习用 Pytorch ,2020 年 10 月访问

[2] 神经网络与 Pytorch。【2020 年 10 月访问

[3] 计算机视觉的迁移学习。【2020 年 10 月访问

Google Colab 中 ResNet 的端到端适配—第 2 部分:硬件和数据集设置

原文:https://towardsdatascience.com/end-to-end-adaptation-of-resnet-in-google-colab-part-2-hardware-dataset-setup-f23dd4e0004d?source=collection_archive---------69-----------------------

端到端 Resnet

CPU、GPU、数据集设置

来源:Unsplash.com

我希望你们都有机会预览本系列的第 1 部分,它不需要任何 python 知识,只需要一个 Google 和 Kaggle 帐户(后者只是为了验证你自己,所以你可以下载数据集。)

作为快速概述,我们能够在 ResNet-18 架构上训练狗与猫数据集(总共 25,000 张图像)。一旦完成训练,你就可以上传你最喜欢的猫或狗的照片,并观察输出结果。

我将把这个系列分成 5 个部分:

  1. 介绍
  2. 硬件和数据集设置
  3. 图像预处理
  4. 建筑培训
  5. 真实世界测试

旁白

一旦你完成了训练,当你输入一张猫头鹰的照片时会发生什么?

来源:Unsplash.com

输出是‘狗’!虽然只有 78.41%的把握。(如果最后一个单元格有问题,只需使用左侧的箭头重新运行它。)

我已经插入了所有东西,从物品到我朋友的照片(他们看起来有点像猫),结果到处都是。有时,概率在 90%以上。

如果还不清楚的话,我要强调这一点——你必须知道使用训练网络的基础数据,否则你的预测将是不可靠的,并且取决于你使用它的目的,是危险的。你对这些数据了解得越多,你对输出的理解就越丰富。

不要用“人工智能”这个时髦词,但如果我要描述我们所建立的东西,我会称之为“狭义人工智能”。这不是人工通用智能(AGI) 。在这里我们只能辨别狗和猫。

库导入

这些是运行整个程序所需的库。‘torch’是 PyTorch(类似于机器学习库 Tensorflow)。“torchvision”包含最流行的模型和数据集以及图像转换(稍后讨论)。“matplotlib”让我们可以创建图像的图形和表格。

当您看到“从 ABC 进口 XYZ”时,我们尽量不输入 ABC。XYZ 每次都可以用 XYZ。例如:

现在,我们可以只使用“listdir”命令,而不是键入“os.listdir”。这是一个简单的例子,但是浓缩类似下面这样的代码有助于简化我们的代码:

你会看到在库导入单元格的末尾是:

想想那个“!”将命令传递到命令行,而不是 python 内核,这样你就可以安装你需要的库,比如‘ka ggle’(让我们下载数据集)。

CPU、内存和 GPU

我提到过 Google Colab 中的高端 CPU 和 GPU。

这将向命令行传递一个命令,以获取有关 CPU 的信息,而“grep”(全局正则表达式打印)搜索纯文本数据。如果你跑了!你会得到一个很长的输出列表,但我们只是想知道有多少个 cpu,型号和 GHz。

与上面类似,‘啊!' cat /proc/meminfo '给出了一个很长的输出列表,但是我们只想知道总 RAM(因此 grep MemTotal)

CUDA(计算统一设备架构)是由 Nvidia 设计的,旨在让我们这样的程序员访问支持 CUDA 的 GPU 来加速我们的数学运算(在这种情况下,是图像分析)。有很多帖子在不同的细节层次上讨论了这是如何工作的。

注意我们通过' torch.cuda.is_available()'使用 pytorch 库,它输出一个布尔值(True vs False)。如果为真,我们还可以使用 pytorch 库来获取设备的名称。

这个设备名称会根据 Google Colab 提供的内容不时更改(有时你根本无法获得 GPU,因为你已经用完了当天的配额)。今天早上是特斯拉 P100。有时我会得到一个超快的特斯拉 T4(免费的!).

获取数据集

卡格尔号。在此步骤中,您下载的“JSON”文件将通过以下方式导入:

如果您参考库导入部分,您会看到这一行:

“files.upload()”允许您上传 kaggle.JSON。

上面的命令都传递给机器命令行,而不是 python 内核。创建一个名为“kaggle”的目录,并将您上传的 kaggle.json 文件复制到新创建的目录中。

“chmod 600”允许用户读写 kaggle.json 文件。这很重要,因为 kaggle 库使用 JSON 文件来验证您下载名为“dogs-vs-cats”的数据集。

最后,解压缩(悄悄地,用-q ),但也覆盖(-o)以防你已经下载并解压缩了它。

请在下面留下任何问题,我会尽力回答。

参考

[1] 深度学习与 Pytorch ,2020 年 10 月访问

【2】神经网络与 Pytorch。【2020 年 10 月接入

[3] 为计算机视觉转移学习。【2020 年 10 月接入

[4] Kaggle API。【2020 年 10 月访问

Google Colab 中 ResNet 的端到端适配第 3 部分:图像预处理

原文:https://towardsdatascience.com/end-to-end-adaptation-of-resnet-in-google-colab-part-3-image-pre-processing-fe30917d9aa2?source=collection_archive---------44-----------------------

端到端 Resnet

为训练准备数据集

来源:Unsplash.com

快速回顾一下我们到目前为止所做的工作:

第一部分 —整个项目概述。不需要 python,只需要一个 Google 和 Kaggle 账户。希望您已经说服自己,您个人能够完整地运行代码,并对其进行测试。

第二部分 —库和数据库都是从 Kaggle 导入的。它被解压缩到一个文件夹中。我们还做了一个简短的概述,介绍了如何确定您正在使用哪种硬件。在处理像我们这样的图像数据库时,GPU 信息很重要。

链接到 Colab 笔记本: 猫&狗— Resnet-18

在我们能够将图像“加载”到架构中进行训练之前,我们必须首先对它们进行预处理。

创建文件夹结构

上面的代码创建了以下结构(val 和 train 位于主数据集文件夹下,而 dogs 和 cats 文件夹位于它们各自的子文件夹中):

dataset_dogs_vs_catstraindogscatsvaldogscats

对于那些想要命名的人,我们正在这里用标记的数据执行监督的机器学习。我们给数据“贴标签”的方式是把它放在一个文件夹里。代码将被告知使用包含图像的文件夹的名称作为标签。

旁白

将来我几乎肯定会在这个问题上犯错,但你对神经网络了解得越多,“建模”和“模型”这两个词就开始变得模糊,你总是会说“我们正在用这个特定的模型来建模我们的问题。”

当提到模型的技术定义时,我鼓励你使用架构这个词。我承认我的代码会有类似‘train _ model’的语句,但在这种情况下,model = architecture,即 ResNet-18 架构。“我们正在用这种特殊的架构来建模我们的问题”听起来更容易接受。

整理我们的数据

第一步是将数据分为训练和测试。我们将使用训练数据来训练我们的架构(调整参数)。ResNet-18 有 1100 万个可训练参数。测试集将用于衡量架构的执行情况,以“测试”的形式向其显示新数据。

“src_directory”包含所有图像。“listdir”获取源目录中所有文件的列表,如果文件以“cat”开头,我们将它放在 cats 文件夹中,与 dog 相同。这是在“file.startswith('cat 或 dog ')”中捕获的。

您可以看到,默认情况下,目的地是“train”文件夹,除非一个随机数(默认为 0 到 1 之间)小于 0.25,这种情况应该发生在 25%左右,在这种情况下,文件会被传送到“val”文件夹。

图像转换

这里需要解释一下。让我去掉一行——“调整大小”。ResNet 架构要求图像为 224x224(为什么不在本文讨论范围之内),因此 train 和 val(验证)图像都必须调整大小。

让我们倒着做。行“ToTensor()”设置我们的图像用于计算。它本质上是一个多维数组(高度、宽度、颜色空间)。每个[train,val]的“归一化”功能根据三个 RGB 通道归一化数据。第一组数字是平均值,第二组是标准差。使用这些特定的归一化值是因为 torchvision 架构(如 ResNet)已经在 ImageNet 上进行了训练,并基于数百万张图像进行了计算。

剩下三种变换—旋转、RandomHorizontalFlip 和 RandomResizedCrop。与“为什么”相比,这些转换的“是什么”更容易理解。本质上,您希望向您的网络呈现尽可能多的不同的训练图像。增加这些图片种类的一种方法是使用庞大的数据集——在这种情况下,有近 19,000 张训练图像。

我们能够通过对图像进行小的修改来人为地增加图像的多样性。

旋转和 RandomHorizontalFlip 是不言自明的。

RandomResizedCrop 从图像(本例中为 224x224)中选取一小块,随机选取的范围在 0.96 到 1.0 之间,随机选取的纵横比在 0.95 到 1.05 之间。

数据加载器

数据加载器允许将数据集批量交付到用于培训的架构中。它们对于确保简化的数据流至关重要。相应地,您看到设置的第一个变量是 batch_size = 16。如果您在训练时遇到困难(尤其是 GPU 内存问题),请以 2 的倍数减少批量。

Data_dir 设置训练和验证图像的主目录。数据集。“ImageFolder”允许像我们之前所做的那样设置标签——文件夹的名称是标签本身(而不是嵌入在文件名中或存储在其他地方的标签)。您可以看到,我们在上面定义的“数据转换”应用于“图像数据集”变量中。

“torch.utils.data.DataLoader”允许将“image_datasets”合并到“dataloaders”变量中。

我们后来在最后两行中将“dataloaders”变量拆分为“train_dataloader”和“val_dataloader”。

最后,确保使用 GPU:device = torch . device(" cuda:0 ")。在接下来的步骤中,我们将确保架构加载到 GPU 上。

请在下面留下任何问题,我会尽力回答。

参考

[1] 深度学习与 Pytorch ,2020 年 10 月访问

【2】神经网络与 Pytorch。【2020 年 10 月接入

[3] 为计算机视觉转移学习。【2020 年 10 月接入

[4] Kaggle API。【2020 年 10 月访问

Google Colab 中 ResNet 的端到端适配—第 4 部分:培训

原文:https://towardsdatascience.com/end-to-end-adaptation-of-resnet-in-google-colab-part-4-training-fad7d5bff1df?source=collection_archive---------52-----------------------

端到端 ResNet

继续,但现在是“大卡哈纳”

来源

现在,我们必须解决整个项目的核心问题,以及在此之前的所有问题,以便无缝地进行培训——下载数据集,格式化所有内容以便输入网络,为图像处理创建数据转换,以及创建有助于以结构化方式插入图像的数据加载器。

如果你刚刚加入,我已经做了一个 colab 笔记本,让你运行整个代码(一次点击),最后,允许你上传一张图片进行测试。这个特殊的数据集和网络旨在区分狗和猫,但你可以上传任何你想生成输出的图片。

这样做实际上是很有启发性的,尤其是对你将来想做的任何工作。**了解基础数据、其问题和偏差对于解释结果至关重要。**每个数据集都有偏差,都是不完美的,这并不一定意味着它是无用的。

以下是前面部分的链接:

[## Google Colab 中 ResNet 的端到端改编—第 1 部分

只需点击几下鼠标,就能训练出一个深度神经网络

towardsdatascience.com](/end-to-end-adaptation-of-resnet-in-google-colab-part-1-5e56fce934a6) [## Google Colab 中 ResNet 的端到端适配—第 2 部分:硬件和数据集设置

评估您的硬件— CPU 和 GPU,并设置您的数据集

towardsdatascience.com](/end-to-end-adaptation-of-resnet-in-google-colab-part-2-hardware-dataset-setup-f23dd4e0004d) [## Google Colab 中 ResNet 的端到端适配第 3 部分:图像预处理

为训练准备数据集

towardsdatascience.com](/end-to-end-adaptation-of-resnet-in-google-colab-part-3-image-pre-processing-fe30917d9aa2)

下面我们先来解开 train_model 到底是怎么回事:

我粘贴了上面的整个函数,只是为了大致了解它有多大,但它将被分成几个部分:

几个定义

Epoch —底层数据对模型的一个完整呈现(呃,*架构,*正如我告诉自己我会说的)。

训练阶段 —如果您还记得,我们使用了 75/25 的比率(80/20 和 70/30 也很常见),我们随机分割数据集,将 75%分配给训练集,25%分配给验证集。随机地做是很重要的,因为如果你把所有的图片都按顺序排列,如果不随机的话,你可能会在训练阶段过度表现狗或猫(结果,架构会更好地“训练”一种动物而不是另一种动物)。

验证阶段 —我们分配给验证集的 25%不应用于培训。这是向网络显示新数据的最佳方式,以查看它是否学习得很好。就像教一个孩子加法一样,你不会想提出同样的问题,而是一个相似的问题来看看孩子是否学会了加法。

优化零毕业生——这本身并不是一个“词汇”术语,但知道这一点很重要。当梯度在小批量中生成时,它们将继续传播通过(这是每个训练周期所不希望的;你想重新开始)。zero_grad 功能使您能够为每个迷你批次重新开始计算梯度。

重物搬运

大部分繁重的工作都在这里完成:

第一个 if/else 语句将模型设置为训练或评估模式(pytorch 特性)。默认情况下,模型处于训练模式。有趣的是,如果您不使用 dropout layers 或批处理规范化,这个约定并不太重要,但是拥有这个约定对于将来验证您的代码(以及您如何使用 pytorch)是非常重要的。

然后使用数据加载器迭代数据,并使用“inputs.to(device)”和“labels.to(device)”行将代码加载到 GPU 中。我们之前讨论过通过 Colab 使用高端 GPU 的能力。

with torch . set _ grad _ enabled(phase = = ' train ')-括号仅在阶段确实处于训练模式时为真,允许在训练模式期间计算梯度,loss.backward(同样,在训练期间)将计算梯度,optimizer.step 使用最近的计算更新所有梯度。

现在,如果阶段不是列车,则 set_grad_enabled 变为 False,不计算梯度,也不更新任何内容。模型只评估输入的图像(这是你在训练中想要的)。

“scheduler.step()”是一行很小的代码,但是对于获得更低的错误率是至关重要的。改变学习率对超参数调整至关重要。开始时,你希望学习率高,这样才有效,随着训练的进行,你希望降低学习率。想象一下,试图找到一个领域的最低点。你希望一开始就迈出大步,这样你就不会错过任何山谷,也不会被困在地图的一个小角落里。但是当你发现山谷时,你不会想在山谷的墙壁上反弹,因为你的脚步很大。让你的步数(这里是学习率)变小会让你更有效地找到最低点。

最后,计算精度,并且如果该特定精度的历元比最佳精度(初始设置为 0)好,则更新 best_acc 变量,并且也更新模型权重,并且重复整个过程。

模型下载&参数确定

名副其实,我们使用的是 Resnet18 型号。全连接层(model_ft.fc)有两个最终输出(猫对狗)。然后,我们将模型加载到 GPU 上,并将损失函数定义为 CrossEntropyLoss

对这个损失函数的讨论超出了一个介绍性系列,但可以说,它非常常用于分类(而不是回归)模型,并且被许多其他帖子和视频所涵盖。

优化函数(SGD——随机梯度下降)也是我鼓励你阅读(或观看 youtube 视频)的内容。

最后是学习率调度器——如上所述,我们希望学习率随着 epoch #变大而变小,以便更好地微调架构(权重)和降低损耗。

最后,我们将所有这些放在一起,让它运行:

model_ft = train_model(model_ft, criterion, optimizer_ft, exp_lr_scheduler,num_epochs=10)

我建议你至少做 5-10 个周期来说服自己有一个合理的停止点,迭代超过 100 个周期会大大减少收益。

如果你正在阅读上面的文章,并发现它过于简单,我为你领先我几光年而鼓掌。但是,如果上面的某些部分没有意义,请留下评论,我会将您连接到适当的资源。

本系列的目标不是深入研究神经网络——我没有资格这么做。我们的目标是让您相信这种架构对您来说是可行的,您可以在高端计算上运行它,并上传您自己的映像以供最终测试——我已经对此进行了概述。

下一次——上传一张照片和相关的细节。

参考

[1] 深度学习用 Pytorch ,2020 年 10 月访问

[2] 神经网络与 Pytorch。【2020 年 10 月访问

【3】计算机视觉的迁移学习。2020 年 10 月访问

[4] Kaggle API。2020 年 10 月访问

端到端定量分析—从 SKLearn 到 Spark

原文:https://towardsdatascience.com/end-to-end-aws-quantitative-analysis-moving-from-sklearn-to-pyspark-f20f883bec90?source=collection_archive---------32-----------------------

来自 Pexels 的 Manuel Geissinger 的照片

构建 AWS 管道

在之前的一篇文章中,我描述了如何使用 Amazon Web Services (AWS)建立一个自动化的工作流程。我们已经探索了如何使用 AWS 的命令行工具 awscli 来加速弹性 Map Reduce (EMR)集群。
在那篇文章中,我们已经看到了如何使用 sklearn 的DecisionTreeClassifier将价格运动分类为“上升”或“下降”(1 或 0,二元分类问题)。

使用 sklearn 的一个缺点是,它使用一台机器来执行所有计算。这种设置会随着数据的增加而增加运行时间,即使我们的 EMR 集群可以包含多台能够进行分布式计算的机器。这就是 Spark 推出其版本的DecisionTreeClassifier的原因。我们将在本教程中比较 sklearn 和 Spark 的使用。

火花和 PySpark

Spark 是一个 Apache 框架,旨在跨多台机器进行并行和分布式处理。这个想法是将工作分解成独立的块,这些块都可以被计算(划分数据),然后汇集独立计算的结果。Spark 非常强大,但是,对于 Python 程序员来说,可悲的是,它是用 Java 编写的。这就是 PySpark 发挥作用的地方。它是围绕 Spark 框架的 python 包装器。

Spark 结合了来自 pandas 的几个抽象,比如 dataframes,以及来自 sklearn 的几个抽象,比如转换和机器学习技术。

将我们的数据转换成火花数据帧

我们要做的第一件事是将我们的熊猫数据帧转换成 spark 数据帧。这是一个非常常见的操作,因此 PySpark 有一个内置函数来完成这个操作。

将我们的库存熊猫数据框架转换为 spark 数据框架

注意,我们使用了 Spark 的内置类型来指定转换的模式。这一步是强烈推荐并节省大量加工时间。如果不这样做,Spark 会尝试自己推断模式。
还要注意,我们在模式中将nullable属性设置为False。这也节省了处理时间,因为 Spark 在进行转换时不必担心某些列包含空值。
完成后,您会注意到我们可以打印 spark 数据帧的模式来查看其结构:

root| — Open_pct: double (nullable = false)| — Close_pct: double (nullable = false)| — High_pct: double (nullable = false)| — Low_pct: double (nullable = false)| — Volume_pct: double (nullable = false)| — Target: double (nullable = false)

将特征转换成矢量

Scikit-learn 模型用于表格数据;numpy 数组或 pandas 数据帧。然而,Spark 机器学习模型需要稍微不同的架构。

虽然 pandas 和 numpy 利用单台机器上的高效内存使用,但 Spark 更关心如何轻松地将数据分布到不同的机器上。因此,它需要将每个数据点封装在一个vector类中。我们需要使用一个VectorAssembler将我们的特性列转换成一个包含向量的列。我们必须告诉VectorAssembler哪些列要插入到这个新列中。

使用向量汇编程序创建向量列

root|-- Open_pct: double (nullable = false)|-- Close_pct: double (nullable = false)|-- High_pct: double (nullable = false)|-- Low_pct: double (nullable = false)|-- Volume_pct: double (nullable = false)|-- Target: double (nullable = false)|-- features: vector (nullable = true)

现在,当我们检查模式时,我们看到我们添加了一个存储数据的 vector 类型的单列。在这种方法下,每个数据点都是一个封装的项目,可以在我们的集群中发送。

使用决策树分类器

Spark 有两个主要的机器学习库; MLlib 和 ML 。首选的库是 ML,因为 MLlib 正在慢慢淡出。我们将使用 ML 中的决策树分类器。

这部分和我们使用 sklearn 还蛮像的;我们初始化我们的模型,拟合它,然后要求预测。有两个主要区别:
1)我们必须在同一个数据框架中指定特性和目标列。决策树希望所有特征都位于一列(vector 类型)中。
2)与 sklearn 决策树不同,这里没有单独的predictpredict_proba方法。一个非常详细的数据帧作为我们的预测返回,其中包含硬类预测、概率预测和许多其他项目。

我们将运行以下代码来使用决策树:

运行决策树分类器

我们已经采取了几个步骤,让我们来分解一下:

  1. 我们将数据分为 80%的训练数据和 20%的测试数据。请注意,与 sklearn 不同的是,这里没有专门的函数,但它是数据帧的一个特性
  2. 我们将数据帧分成 10 个分区。每个分区都是我们的数据的一个原子块,当它在节点之间传递时不会被进一步分割。每个分区将驻留在单个节点上,这意味着我们已经将数据帧切割成 10 个可以四处发送的数据块。
    这一步必须包括在内,因为默认情况下 Spark 只使用 2 个分区,这使得大量数据被发送。
  3. 我们必须初始化决策树,并明确告诉它应该对哪些列进行操作。我们说我们有一个“features”列(vector 类型)和一个“Target”列(double 类型)。一旦我们的树被初始化,我们可以使用fit方法使它适合训练数据。
  4. 用一种transform方法(而不是predict)抓住我们的预测。这些预测来自它们自己的火花数据框架。
  5. 打印该模型的总运行时间。在我的例子中,打印输出是:
    run-time: 3.55
  6. 打印出我们的预测数据框架的模式和预测。请注意,预测数据帧也包含测试数据帧的所有列:
root| — Open_pct: double (nullable = false)| — Close_pct: double (nullable = false)| — High_pct: double (nullable = false)| — Low_pct: double (nullable = false)| — Volume_pct: double (nullable = false)| — Target: double (nullable = false)| — features: vector (nullable = true)| — rawPrediction: vector (nullable = true)| — probability: vector (nullable = true)| — prediction: double (nullable = false) +--------------+----------+-----------+
| rawPrediction|prediction|probability|
+--------------+----------+-----------+
|[0.0,131301.0]|       1.0|  [0.0,1.0]|
|[0.0,131301.0]|       1.0|  [0.0,1.0]|
|[0.0,131301.0]|       1.0|  [0.0,1.0]|
|[0.0,131301.0]|       1.0|  [0.0,1.0]|
|[0.0,131301.0]|       1.0|  [0.0,1.0]|
|[0.0,131301.0]|       1.0|  [0.0,1.0]|
|[0.0,131301.0]|       1.0|  [0.0,1.0]|
|[0.0,131301.0]|       1.0|  [0.0,1.0]|
|[0.0,131301.0]|       1.0|  [0.0,1.0]|
|[0.0,131301.0]|       1.0|  [0.0,1.0]|
|[0.0,131301.0]|       1.0|  [0.0,1.0]|
|[0.0,131301.0]|       1.0|  [0.0,1.0]|
|[0.0,131301.0]|       1.0|  [0.0,1.0]|
|[0.0,131301.0]|       1.0|  [0.0,1.0]|
|[0.0,131301.0]|       1.0|  [0.0,1.0]|
|[0.0,131301.0]|       1.0|  [0.0,1.0]|
|[0.0,131301.0]|       1.0|  [0.0,1.0]|
|[0.0,131301.0]|       1.0|  [0.0,1.0]|
|[0.0,131301.0]|       1.0|  [0.0,1.0]|
|[0.0,131301.0]|       1.0|  [0.0,1.0]|
+--------------+----------+-----------+
only showing top 20 rows

AWSCLI 的配置

我们将需要使用一个新的命令,其中包含了更多的信息

aws2 emr create-cluster \
--name “Spark cluster with step” \
--release-label emr-5.29.0\
--applications Name=Spark \
--log-uri s3://**logs**/logs/ \
--ec2-attributes KeyName=**my-key-pair**,AvailabilityZone=us-west-2a \
--instance-groups **file://instanceGroupConfig.json** \
--bootstrap-actions Path=s3://**scripts-and-set-up**/bootstrap_file.sh \
--configuration **file://config.json** \
--steps Name=”Command Runner”,Jar=”command-runner.jar”,Args=[“spark-submit”,
”--conf”,”spark.executor.memory=18g”,\
”--conf”,”spark.driver.memory=16g”,\
”--conf”,”spark.rpc.message.maxSize=1500",\
”--deploy-mode=cluster”,”s3://**workflow-scripts/process_data.py**, s3://**data-files**/AAPL.csv”] \
--use-default-roles \
--auto-terminate

我不会探究每一个新的参数,因为我在之前的帖子中探究了create-cluster命令。但是,我要指出的是,您必须将 s3 存储桶设置为您自己的存储桶。
说到这里,让我们来看看我们添加的几个新参数:

  • --instance-groups file://instanceGroupConfig.json —我们实际上可以使用一个配置文件来指定部署多少个节点以及部署哪种类型的节点。我的集群使用了 4 个节点;1 个主节点、1 个任务节点和 2 个核心节点

instanceGroupConfig.json

  • 这是我们集群的另一个配置文件,但是它概述了我们的资源管理器(YARN)应该如何工作。它基本上允许我们在主节点上消耗大量内存

配置. json

  • 我们这里有相当多的火花配置参数。它们控制整体内存管理。每个执行器应该分配高达 18Gb 的内存来运行,控制所有执行器的驱动程序应该分配 16Gb 的内存来运行,最后 Spark 应该能够在执行器和驱动程序之间一次发送高达 1.5Gb 的数据包。我花了一些时间通过反复试验来调整这些参数。我不会说它们是最优的,但它们允许进行比较。

比较两个决策树的运行时间

为了便于比较,让我们来看看我之前用于 sklearn 树和 Spark 树的代码。

使用 sklearn 的决策树分类器

>>> run-time: 9.19

使用 Spark 的 ML 决策树分类器

>>> run-time: 3.55

使用 Spark 的决策树最终会使数据处理速度提高一倍以上。这符合我们的预期,因为 Spark 可以削减任务和核心节点之间的工作。然而,这个特殊的例子变得稍微复杂一些。

虽然 Spark 的决策树显示了明显的优越性能,但在这种情况下,使用 Spark 并没有快多少。

使用 sklearn 决策树的集群总共运行了 14 分钟,而 Spark 集群运行了 13 分钟。运行时间接近是因为将数据帧转换成 Spark 数据帧本身就是一项成本高昂的操作。

然而,我们在这个实例中探索的数据只有大约 4GB 大小。随着数据大小和集群大小的增加,这种差异肯定会增加。Spark 被设计为运行在万亿字节的数据上,甚至更多。所以这个例子仅仅说明了部署基于 Spark 的机器学习工作流的过程。

用于 PySpark 处理的整个脚本如下所示:

process _ data _ with _ 火花. py

结论

Spark 可用于加速您的机器学习需求,由于它包含许多与 sklearn 相同的算法,转换非常容易。一旦您熟悉了 Spark 框架,PySpark 接口允许几乎无缝的转换。然而,为了达到熟悉的程度,人们必须超越机器学习算法的通常知识,并深入了解配置和内存管理知识,以允许 Spark 应用程序发挥其全部潜力。

我写这篇文章的时候很开心,我希望你读的时候也开心。关于 Spark,我还有一些东西需要学习,但我希望能让您的学习体验更轻松。

迄今为止的成本

在试验 3-4 个节点的集群时,以及花了相当多的时间来实现指定显式模式节省了相当多的处理时间,我不得不花更多的钱来学习如何使用 Spark。我希望这篇教程确实能为阅读它的人节省时间和金钱,但是对我来说总的花费大约是 60 美元。我建议你在使用 Spark 和 EMR 进行原型开发时要小心,因为这很容易增加费用,但是如果不尝试和失败,你就无法学会如何使用这些工具。

端到端案例研究:自行车共享需求预测

原文:https://towardsdatascience.com/end-to-end-case-study-bike-sharing-demand-dataset-53201926c8db?source=collection_archive---------7-----------------------

阿纳托利·阿尼金在 Unsplash 上拍摄的照片

大家好!!

欢迎来到这个关于自行车共享需求预测的博客。这个数据集取自 Kaggle 。在这篇博客中,我们将经历简单而有效的预处理步骤,然后我们将更深入地挖掘数据,并应用各种机器学习回归技术,如决策树、随机森林和 Ada boost 回归器。我们将通过使用 GridSearchCV 对每个回归器算法进行参数调整来找到最佳的超参数。

在分析每个模型的误差后,我们将选择一个给出最小均方根对数误差(RMSLE)分数的模型,并使用它建立一个模型。

最后,我们将看到如何使用函数将整个代码包含在 python 中以获得更高的效率。希望,你会喜欢。

1)数据预处理

  • 理解数据

给定的训练数据集具有 10886 行和 12 列。季节、假日、工作日列是绝对的。除了' datetime '之外,其余都是数字列。

使用' datetime '列获得另外两个功能' time '和' month '。

删除不必要的列。

分类列上的一个热编码。

用每个相应列的中值输入空值。

  • 使用 python 函数的代码:

2)模型构建:

我已经根据“工作日”列分离了数据,因为与非工作日相比,工作日的需求变化很大。

我建立了两个模型,一个预测“休闲”,另一个预测“注册”。预测的“计数”是预测的“临时”和预测的“注册”的总和。这里,我只展示了预测工作日“已注册”的代码。同样的技术可以用于预测工作日的“休闲”和非工作日的“休闲”、“注册”。最后可以检查全部代码。

  • 线性回归

线性回归在这里被用作基础模型,尽管我们知道线性回归在这里不起作用。我们拟合该模型以使用该模型的‘均方误差’( mean _ squared _ log _ error)作为参考来检查其他模型的表现如何。

  • 决策树

对' max_depth '和' min_samples_leaf '参数进行参数调整。

用最佳参数建立决策树模型。

  • 随机森林

对' n_estimators '、 max_depth 和' min_samples_leaf 参数进行参数调整。

用最佳参数建立随机森林模型。

  • Ada-Boost

用基本模型作为我们在上面找到的“最佳随机森林模型”来寻找最佳的 n 估计量。

用最佳 n 估计量建立一个最终的 Ada 推进模型。

3)分析错误

上述模型在工作日预测“注册”的均方根对数误差( RMSLE ):

每个模型的 RMSLE 分数

随机森林的 RMSLE 分数最低,非工作日也是如此。因此,我们可以得出结论,随机森林是这里的最佳模型。

4)最终模型

在对整个数据进行模型拟合后,以下是工作日和非工作日的 RMLSE 得分。

一个工作日和非工作日的 RMSLE 分数

整体数据的 RMSLE 分数结果为 0.351。

使用 python 函数的代码:

5)特征重要性

对于工作日,预测“已登记”的重要特征是:

对于工作日,预测“休闲”的重要特征是:

非工作日的特性重要性也类似于工作日。因此,时间、湿度、温度和月份是所有情况下最重要的特征

6)模型测试

由于测试数据缺少一些列,我们将编写一个新的函数,使用以前的模型来预测“计数”。

使用 python 函数的代码:

更新和保存 CSV 文件:

最后在 Kaggle 提交了这个文件后,我得到了一个 RMSLE 的分数 0.513。

你可以在这里找到完整的代码。

端到端数据仪表板,包含 Plotly Dash 和 Heroku:美国失业数据

原文:https://towardsdatascience.com/end-to-end-data-dashboard-with-plotly-dash-and-heroku-us-unemployment-data-c0faa9d6eb08?source=collection_archive---------36-----------------------

此处显示的仪表板的第一个选项卡

数据科学

有很多经济数据来自不同的部门,劳工部,经济分析署,BLS,弗雷德,NBER,美国人口普查局——我们如何把这些数据放在一起,看看这些数字背后的人们?

在过去的几个月里,我们已经看到令人厌恶的大数字都以同样的方式显示——通过直线图和条形图,有一个大的跳跃。当然,这是展示变化的好方法,但很难理解或真正理解仅仅一句台词。台词让你觉得“哦,哇,不寻常”,就是这样。我认为,这些数据需要以一种与个人相关的方式呈现(呈现给他们知道的人、地方和行业),以帮助用户比较美国各地的统计数据。

这需要一个数据仪表板,具体来说,它的目标是:

允许用户轻松地比较和查看美国劳动力中的问题和模式,最终导致更深入的“为什么”问题和后续研究。

GitHub 仓库中的一些代码和数据在这里,仪表盘可以在usa-data-dashboard.herokuapp.com找到。如果你在手机上,去usa-data-dashboard-mobile.herokuapp.com获得更好的观看体验。总的来说,这个项目花了四天时间,大概有 1000 行代码。这个应用程序本身有 500 行代码。

这个应用程序分三步完成

  1. 获取和清理数据
  2. 创建 Plotly 图表和 Dash 应用程序
  3. 部署到 Heroku 并进行优化

获取和清理数据

为了开始了解数据背后的人,以及我们如何帮助他们,我们需要向我们展示地点、人员和原因的图表。我决定尽可能细化,并决定使用美国县(人口普查区)级数据来显示失业、社会人口统计和行业依赖。美国在人口普查中报告了 3000 多个县。正如人们所料,这是 4 天中最长也是最艰难的部分,大约 2.5 天,可能有点干。我选定的数据集是由于更新的准确性和一致性:

  1. 匹配以下内容的一整套标识符:联邦信息处理标准(FIPS)、基于核心的统计区域(CBSA)、大都市区域名称、县名称、州名称 大约 2020 年
  2. 2010-2020 年 BLS 各县失业情况
  3. BLS 按行业分列的就业人数(州和市区)2019–2020
  4. 美国人口普查局数据:人口统计和平均收入 2018

考虑到相似数据的来源数量之多,协调 ID 和更新频率,项目的开始非常混乱。我花了大约半天时间来梳理副标题中列出的每个网站,看看在哪里可以找到最一致的数据和标识符。虽然它在我的数据集上被列为第一名,但直到最后我才真正把它拼凑起来。这很困难,原因有三:

  1. 各种数据源之间,县和城市地区的分组或拼写通常略有不同。
  2. 我发现的数据集和键都来自不同的日期,所以映射中的细微变化导致了额外的四五个小时来检查工作表中的名称,以找到最佳的组合。
  3. 美国的县名不是唯一的

本质上,它都与美国人口普查局的代码相关联,其中 FIPS 匹配县名,CBS 匹配大都市地区,FIPS 匹配 CBSA(如果该县是大都市地区的一部分)。您可以在我的FIPS to CBSA.xlsx文件中找到这个映射。这是用 NBER 以及 BLS 键的组合创建的。这都是 USCB 人用的,他们是这样分解的:

这里的 FIPS 应该是 06067

下面是它是如何连接的:我从他们的数据库中的本地失业系列 ID 数据开始(这是 3200 次查询/每次拉动的最大 200 次= 16 次拉动),并使用他们的area_codearea_text的转换来获得县名和列名(这在我的US BLS Codes.xlsx文件中)。这些可以追溯到 1990 年,但我只从 2010 年非调整。

然后,我看了州和大都市地区经济概览,得到了行业就业月度数据。这只能追溯到 2019 年 12 月。我能够从 EAG 的每一页得到行业分类,就像这一页一样。

USCB 的人口普查数据也很难在县一级找到,所以我过去常常在地区一级的司法地图上找到数据文件,这是一个 1.2GB 的postgreSQL 文本转储文件。我必须下载postgreSQL,安装postGIS插件,然后pd_dump将文件存入数据库。我使用psycopg2 库将数据库表读入 Python,然后使用这种方法获取县平均比赛细目。在用公正地图核对百分比数据时,我去掉了“其他种族”,因为这个领域似乎没有包括在总人口中。

如果你对我如何清理文件感到好奇,请查看回购和这个脚本。我还没有清理脚本,但我认为它非常简单,所有读取的文件都在存储库中。忽略第 18–21 行,由于名称不一致,我没有使用那个代码文件。

创建 Plotly 图表和 Dash 应用程序

现在我们将深入研究代码,特别是应用程序布局是如何制作的。作为参考,以下是截至 2020 年 6 月 16 日的 app 代码。我删除了大约 150 行数据读取和操作,这些内容看起来会很混乱,我们将在后面讨论。Dash 实现从第 83 行开始。

我假设你对布局和回调有一个基本的了解,如果没有,那么请查看 Plotly Dash 文档。

提醒一下,任何图表都可以被绘制成图表——它只是静态的。对于这个仪表板*,我使用了四种类型的图:***

Plotly 图形对象:go。“美国-各州”定位模式的 choropleth

*左栏,标签 1*

这个示例使用了三个回调函数,一个选择要显示的行业类型,两个选择日期。滑块还不接受datetime对象,所以这是唯一的解决方法。

plot_unemploy_choro_state()是我在脚本前面第 64 行定义的函数。

plot ly Express:px . choropleth _ map box 一个县(FIPS)级地块

*左栏,标签 1*

现在我们变得有点复杂了,我使用了一个链式回调在一个下拉列表中选择数据集(人口普查数据或 BLS 县失业数据),然后在第二个下拉列表中显示要绘制的值。

这看起来很可怕,但如果你慢慢来,这很简单。第一个回调选择在第二个下拉列表中显示的标签,第二个回调通过“数据类型”过滤相关的数据集 df,并将其设置为要返回的fig

Plotly Express: px.line 和 px.bar

*右栏,标签 1*

好了,现在是整个右侧。本质上,这里所发生的是县选择照顾所有的图表。一旦我有了一个县,我就用 BLS 失业县的数据绘制一个线图,从美国人口普查局 2018 年的数据中提取该县的人口统计数据,然后使用州数据(来自图表 1)和 CBSA 大都市区数据(这两个数据都来自 EAG 数据源)更新行业就业。

county 是 state 的连锁回调,因为 county 的名称在美国不是唯一的。因为我有一个映射文件设置,我可以很容易地使用 dict 从后端的所有其他工作表中提取。

一步一步来看,第一个回调设置了 counties 下拉列表。如果选择了 not county,第二次回调会弹出一个警告。第三次、第四次、第五次回调都是以类似的方式使用 px.bar。最后回调的是历史折线图。这里有一堆操作在进行,但是不要太担心那些。

第二页签:比较视图

在我构建了第一个选项卡之后,我才设计第二个选项卡。我希望第一个帮助用户找到奇怪的县和州,然后第二个在你找到感兴趣的州/县后,一次比较尽可能多的县/州。

各州的比较如下所示:

左栏,标签 2

县与县的比较如下:

右栏,标签 2

图像中有一个收入图表,但你可以自己看一下。这基本上是相同的代码,但我使用了 px.bar 的不同版本,并在下拉列表中启用了multi=True,这样就可以根据需要填充尽可能多的行或条。

你不必这样做,但是我使用了 Dash Bootstrap 组件,而不是布局、标签和卡片的标准样式表(在特定区域设置边界)。它们有很好的文档,确实有助于简化应用程序代码的组织,所以如果你还没有尝试过,我建议你尝试一下。我首先创建了空白标签和卡片布局,然后开始填充。你会看到我的app.layout很短,在第 297-304 行。

部署到 Heroku 并进行优化

如果你做到了这一步,那么恭喜你!理解别人所做的数据流程和仪表板构建并不是一件容易的事情。我这么说是为了避免你的痛苦——一旦你有了一两个本地运行的基本图表, 部署到 Heroku Heroku 有一个所谓的 R15 限制,基本上意味着如果你的应用超过 512mb X 2 workers =1024mb 的内存使用量,它就会崩溃(使用heroku logs --tail检查崩溃)。此链接底部有一个部署基本 dash 应用程序的分步指南。如果你运行的是 Windows,使用venv\Scripts\activate而不是source命令。

随着你的进展,你可以添加更多的图表和测试功能——如果你带来的不仅仅是基本的 dash/pandas/numpy 包,这一点尤其重要,因为你可能已经做出了一些花哨的东西,但在推送到 heroku 时,pip 由于这样或那样的原因不工作。这真的很像使用任何软件时的提示:“早存,常存”

对于大多数简单的应用程序,你不需要关心优化,但对于这一个,我有超过 1GB 的数据和脚本中一些昂贵的操作。为了解决这个问题,我试图限制像.unstack()这样的操作来保存行,并将较大的文件分割成多个 csv 文件,然后在app.py 文件中执行大多数位于Labor Data Prep.py 文件中的操作。这就是为什么在进入 dash 应用程序之前有将近 200 行,一些文件在操作后从 csv 中的 3000 行变成了app.py文件中的 1,600,000 行。

我经常遇到 R15 错误,持续使用大约 1100 多 mb 的内存,即使应用程序上只有两个图表。我把procfile 改成了包含preload,以牺牲一些性能为代价节省了内存。

*web: gunicorn app:server --preload*

此外,它有助于了解不同的动态类型 (web、worker、clock 等)以及水平和垂直缩放。你可能需要为更多的内存扩展应用付费。

在这里你可以看到我的测试和内存使用历史。这些错误显示在 H10-R15 中,严重错误导致应用程序崩溃。

对于企业来说,还有一整套从每月 5 美元到 1000 美元以上的附加服务。我花了一些时间研究缓存,看看性能是否会更快,但最终决定没有必要。我在回调之前缓存了尽可能多的变量——尽量避免太多的 dataframe 操作(比如 df[df["column"]==var]),尤其是对于链式回调。

经过大量的测试和修改(确切地说是 40 个版本),我已经让我的应用程序始终运行在 600mb。

最终仪表板

我们完事了。总而言之,数据仪表板不应该是您进行数据分析的首选,但是当有太多视图需要显示或探索时,它是一个不错的选择。

要记住的事情:

  1. 一个仪表板的关键目标/目的开始
  2. 花点时间收集和核对数据,看看已经取得了什么成果。
  3. 仔细挑选你的图表和回拨设计,在开始之前做好布局!
  4. 按需部署,不要在最后批量部署。一下子优化完会很痛苦。

在我们有越来越多的开放数据可用的时候,我鼓励每个人开始用更人性化的视角探索数据——而不是只关注你能或不能预测什么。祝你好运!

这里表达的所有观点都是我个人的,并不代表我所属的那些人的观点。

端到端数据科学项目:使用回归预测二手车价格

原文:https://towardsdatascience.com/end-to-end-data-science-project-predicting-used-car-prices-using-regression-1b12386c69c8?source=collection_archive---------14-----------------------

图片来自 Pixabay 的 JOERG-DESIGN

介绍

大约每年售出 4000 万辆二手车。有效的定价策略可以帮助任何公司在竞争激烈的市场中高效地销售其产品并获取利润。

在汽车行业,定价分析对于公司和个人在出售或购买汽车之前评估汽车的市场价格起着至关重要的作用。

我想通过这个数据科学项目实现两个主要目标。首先,根据历史数据,通过考虑一组特征来估计二手车的价格。第二,更好地了解有助于确定二手车价格的最相关特征。

数据

将用于该项目的数据可在 Kaggle 和获得,这些数据来自 Craigslist,这是世界上最大的二手车销售网站。

该数据库由 423,857 行和 25 个特征组成,其中一个特征将是我们要预测的连续因变量(“价格”)。

数据库概述

方法学

EDA

数字特征在这个回归模型中起着很大的作用,所以很好地理解它们在数据库中的分布是很重要的。

数字特征的统计数据

我们的重点将是“价格”、“年份”和“里程表”。如上图所示,这三个特征的最大值/最小值和百分位数之间有很大的差异。这是异常值存在的一个指标,异常值会极大地阻碍我们模型的性能。它们将在以后处理。

缺失值&重复值

在了解了我们将要使用的数据库之后,务必检查是否有任何缺失值(NaN)。

数据库中某些要素的值缺失

大多数特性都有大量的缺失值,但是仅仅删除所有具有 NaN 值的行是不实际的,因为这样会使数据库变得过于稀疏。

现在,我将把它留在那里,只去掉一些不会带来任何附加值的功能。保留它们只会让模型更难解释数据库。

从数据库中删除的一组要素

最后,还需要检查数据库中是否有重复值。

在这种情况下,数据库中有几个副本。它们将通过删除现有的重复行来处理,但第一行除外,第一行将被保留。

处理数据库中的重复项

特色工程

首先,我将在“描述”列上使用正则表达式。此功能包含每辆二手车的广告文本。

目标是从那里获得关键信息,以便填充数据库中其他列的 NaN 值。我们要填充的列是那些具有分类值但没有太多唯一值的列:

使用正则表达式的模式匹配

完成此操作后,有值被不一致地添加。例如,我们在同一列中有这些类型的值:“awd”和“awd”。为了统一字符串,将使用 strip()方法。

处理不一致的数据输入

通过这个 Regex 步骤,数据库获得了成千上万的新条目,用一致的数据填充了大量缺失的值。由于我们不再需要“描述”功能,我将删除它。

下一步,是时候让处理数据库中的离群值了。将被处理的三列是:“里程表”、“价格”和“年份”。

让我们从想象前两个开始:

价格和里程表值的分布

由于“价格”在最小值和 25%百分位之间以及在最大值和 75%百分位之间有如此大的差异,我将在两端省去 10%的值。

价格两端的价值下降 10%

接下来,是时候关注“里程表”了。这个特性有 NaN 值,所以处理起来比较棘手。让我们用散点图来显示异常值。

显示里程表上的异常值

因为离群值开始于大约 3,000,000;我将放弃超过这个值的值。此外,去掉最小值(0)也是一个好主意,因为它与 25%的百分位数有很大不同。这样,“里程表”功能也已成功调整。

调整后的里程表功能

为了结束这一步,特征“年份”的异常值将以与“里程表”中相同的方式进行处理。

接下来,我想通过使用数据库中其他现有列的来处理另外两个相关特性。它们是:“条件”和“标题 _ 状态”。它们非常相似,基本上告诉我们二手车的状态(干净、脏、新、好、坏……)。

为此,我将使用“里程表”值。“里程表”功能是一个连续的功能,因此最好将其值分组到几个箱中作为参考。

标题 _ 状态与里程表

“title_status”的大部分值都是干净的,所以我将把“干净”添加到该列的所有 NaN 值中。接下来,是时候检查“状况”了:

状况与里程表

在这种情况下,值的差异更大。使用上面的图表作为指导,我将填写“条件”的 NaN 值。最后,因为“condition”和“title_status”是相互关联的,所以将它们合并到一个特性中是一个好主意。

填充 NaN 值和连接要素

最后,现在是时候再次查看缺失值图表了。我会应用其他方法来处理它们。

数据库中缺少值

考虑到丢失值的数量,我将把特性分成三个不同的组,并删除具有最多 NaN 值的“size”。

首先,NaN 值少于 5%的行将删除缺少值的行。

删除具有 NaN 值的行

第二,NaN 值小于 20%的那些将通过使用 fillna()函数填充。

在具有缺失值的要素中使用 fillna()

最后,最后一个特性“cylinders”将通过使用另一个列(“drive”)来处理,以推断它的值,因为我觉得它是模型的一个相关特性。

利用另一列填写 NaN 值

在本特性工程部分的结尾,将“区域”和“州”合并成一个特性是一个好主意,因为它们是紧密相关的。

将区域和州连接成一个特征

分类变量编码

在数据库中,既有数字变量,也有分类变量。但是,为了继续下面的步骤,需要将这些分类值编码成数字数据。这将在标签编码的帮助下完成。

分类变量编码

相关性

当两个变量高度相关时,它们对我们要预测的因变量的影响是一样的。在这种情况下,建议删除其中一个。

相关矩阵

在这种情况下,没有一个特性是高度相关的,所以我们让它们保持原样。

造型

是时候开始这个项目的建模了。这一次,我将只使用随机森林回归模型来获得“价格”预测。

随机森林算法是决策树的集合。对于我们的项目来说,它肯定会派上用场,因为它有能力处理具有更高维度的大型数据集,并且不允许在模型中过度拟合树。

为了开始建模,我们希望将数据库分为训练集和测试集。这项工作将以 80:20 的比例完成。像往常一样,我们将首先重新索引数据库,并将因变量“价格”作为最后一列,以便进行更简单的拆分。

重新索引并拆分成训练/测试集

在分割之后,由于独立特征的值存在很大的差异,因此有必要实现特征缩放。务必在拆分数据库后进行,以避免数据泄漏到机器学习模型中。

将特征缩放应用于 X_train 和 X_test

然后,我们使用交叉验证方法在训练集中拟合模型,以便更精确地估计模型的准确性。我将利用 R (R 平方)指标来评估模型的性能。

R 是一个无标度分数,这意味着值太大或太小都没有关系,R 将总是小于或等于 1。越接近 1 越好。

顺便提一下,由于百分比在评估结果时更有洞察力,我将把我们从 R 得到的值转换成百分比。

基于 R 度量评估模型

我们一开始就获得了超过 85.48%的分数。一点也不差。但是我们可以通过调整超参数来进一步改善它。

一旦模型的超参数得到优化,就应该再次训练它(使用交叉验证)并再次检查它在训练集上的性能。

随机森林回归模型的超参数调整

从上面的图片中我们可以看到,在优化了超参数之后,分数变得更好了。

最后,一旦训练完成,模型已经从训练数据中学习,剩下的就是检查它在测试集中的表现如何。这将是我们模型的关键时刻。

对测试集的预测

我们的模型在训练集和测试集中的良好表现表明,结果似乎相当可靠。事实上,它在测试集中的预测更加准确(87.03%),这一点尤其值得注意。

结果

对于这个项目,为了预测二手车的价格,我只使用了一个模型:随机森林回归变量。

它在如此大的数据集上表现出了出色的性能,并且在整个训练和测试过程中表现一致。更重要的是,测试集的结果优于训练集,其预测准确率为 87.03%。

该项目的目标之一是创建一个能够估计二手车价格的模型,我们已经实现了这个目标。

第二个目标是在估计因变量“价格”时,找出哪些特性是最相关的:

随机森林模型中每个特征的重要性

结论

通过这个项目,我们建立了一个模型,在给定一组特征的情况下,该模型可以以 87.03%的准确率预测二手车的价格。当公司和个人试图了解如何估计一辆汽车的价值时,这些信息可能具有巨大的价值,更重要的是,了解决定其定价的关键因素。

正如所料,到目前为止,在计算价格时,车辆的年份是主要因素,几乎占 43%,其次是里程表。有趣的是,我期望汽车的状态和里程表有很深的关联,但是在这两个指标之间的相关性差异上有很大的差距。

也就是说,这个地区似乎也起了作用,这完全有道理。可能会有更多的通用汽车在任何地方都受欢迎,但像跑车或敞篷车这样的专业汽车更适合温暖的地区,而大型卡车和 SUV 在寒冷的地方会发挥更好的作用。

掌握定价的艺术不是一件容易的事情,但是通过对历史数据的研究,有可能找到导致准确结果的模式。在出售或在市场上购买汽车之前,获得这些知识可以为你提供一个比较优势。

关于这个项目内核的更多信息,请访问:https://github.com/josem-gp

使用 Azure 的端到端深度学习教程

原文:https://towardsdatascience.com/end-to-end-deep-learning-tutorial-using-azure-f7bb524f7277?source=collection_archive---------27-----------------------

在 Azure 上学习深度学习

了解如何设置深度学习工作区,构建自定义数据集,使用 azure pipelines 通过持续部署来培训和部署模型。

简介:

本文的目标是在 azure 上建立一个深度学习工作区,在 azure 上构建和部署端到端的深度学习项目。我们将首先构建一个定制的图像数据集,以在生产中部署模型。本文是由微软学生合作伙伴(印度)项目发起的 MSP 开发者故事的一部分。

我们将会建造什么?

我们将构建一个口袋妖怪图像分类器来分类令人敬畏的新手皮卡丘、小火龙、杰尼龟和妙蛙种子。

mini-pokedex.azurewebsites.net的现场演示

我们将遵循的步骤:

  1. 使用 Bing 图像搜索 API 构建自定义图像数据集
  2. 使用 azure Data Science VM 设置我们的深度学习工作区
  3. 使用快速人工智能在 Azure 数据科学虚拟机中构建和训练模型。
  4. 构建一个 web 应用程序,通过 API 和 dockerizing 使用我们的模型。
  5. 将 web 应用程序的 Docker 映像推送到 azure 容器注册表。
  6. 从 azure 容器注册表在 Linux 容器 VM 中部署 web 应用程序。
  7. 使用 azure 管道设置连续部署。

注意:

开始之前,请确保您在 Azure 上拥有一个有效订阅的帐户。如果你是 STEM 的学生,你可以使用 Azure for Student s 免费订阅,或者你可以使用 Azure 免费帐户。

步骤 1:使用 Bing 图像搜索 api 构建自定义图像数据集

我们将使用 Bing 图像搜索 API,转到 Bing 图像搜索 API 页面,点击尝试 Bing 图像搜索并登录。然后通过填写必填字段来激活您的服务,如下所示:

给它一个名字,我把它命名为dataset-search-API,你可以根据它的可用性尝试任何不同的东西。选择您合适的订阅。对于 定价层,F1 将是合适的,因为它每月提供 1000 笔免费交易。创建一个 资源组搜索-API ,你可以给它起任何名字,但是在 Azure 中工作时要记住的重要一点是给资源组起一个合适的名字,因为你以后会使用资源组的名字来跟踪费用和删除资源。 为资源组选择一个位置接受条件点击创建 。然后 等待 创建您的资源。一旦创建了 ,点击转到资源

创建阿炳图像搜索资源

  • 你可以找到 bing 图片搜索资源页面的 API 键。
  • 然后 git 克隆这个 repo:image-dataset-bing-API
  • 在 VS 代码中打开它,并创建一个名为。并将文件 .env.example 的内容粘贴到其中。
  • 然后从你的资源页面复制你的 bing 图片搜索 API 密匙并粘贴到。env 文件放在适当的位置。
  • python-m venv venv创建一个虚拟环境
  • 使用venv \ Scripts \ activate . bat(windows 中)或source venv/bin/activate(Linux 中)激活它
  • 使用pip install-r requirements . txt安装依赖项
  • 使用 python search_bing_api.py 这样的脚本—查询“妙蛙种子”
  • 对杰尼龟小火龙的皮卡丘重复上述过程。
  • 现在你有了一个名为 dataset 的文件夹,里面有每个口袋妖怪的图像。
  • 浏览图片,删除那些你觉得不相关的。
  • 像我在这里做的那样,将文件夹(数据集)添加到一个新的 git repo 中 pokemon-image-dataset

现在 GitHub 中有了一个带有自定义图像的 repo,让我们开始下一步:

第二步:使用 azure Data Science VM 建立我们的深度学习工作区

我们将制作一个 NC6 宣传片,这是一个带有 1 个 K80 NVIDIA GPU (1/2 物理卡)的 Linux 虚拟机,它是 12 GB GPU 和 6 个 CPU 内核。

你可以在这里了解更多关于虚拟机的信息。

如果你需要一个详细的安装程序,你可以参考快速人工智能 azure 页面,否则你可以遵循以下说明。

  • 我们将使用 fast ai 团队创建的模板来设置虚拟机:单击此链接将带您进入虚拟机创建页面。
  • 创建一个名为 DSVM新资源组,根据您的喜好设置位置。
  • 设置管理员用户名(小写或 Jupyter Hub 登录失败,出现 500 内部服务器错误),设置密码
  • 设置适当的虚拟机名称,我将其命名为 DSVM-DL 并在虚拟机大小中选择 NC6 Promo
  • 选择接受条款,然后单击购买。

现在等待,直到资源被创建。单击通知图标以了解它是否已创建,并在创建时单击转到资源组。

在“resource,group”页面中,单击您在上面为其命名的虚拟机。并单击您的公共 IP,如下图所示

单击 ip 将其设置为静态

点击 IP 将带您到一个配置为您的公共 IP,现在改变分配为静态从动态,你也可以设置一个 DNS 名称标签。由于这一步,您的虚拟机 IP 将不会改变后,重新启动。该页面将如下图所示

设置静态 IP

现在我们已经完成了 DSVM 的设置,让我们进入下一步

步骤 3:使用快速人工智能在 Azure 数据科学虚拟机中构建和训练模型。

由于你已经设置了一个带 GPU 的 DSVM,你可以通过 ssh 将带 azure 笔记本使用到 DSVM 中并使用。我推荐第二种方法,因为它给你更多的灵活性。首先,让我向您展示 azure notebooks 方法,然后我们将开始使用带有 SSH 的 VM。

在 Azure 笔记本上使用 Azure DSVM。

  • 前往notebooks.azure.com,登录并创建一个用户 id。
  • 然后单击我的笔记本并创建一个新笔记本。
  • 现在,要在 azure 笔记本中使用带有 GPU 的 VM,请将选项 Run on Free Compute 更改为 Run on Direct Compute。
  • 现在你可以开始在带有 GPU 的 DSVM 上使用 azure 笔记本了。

更改计算步骤的屏幕

SSH 进入 DSVM,从那里使用

这种方法比上面的方法更灵活。对于 windows 用户,我推荐使用 wsl 在这一步之前,只需在当前 shell 中键入 wsl 即可启动。

要连接到您的虚拟机,请使用:

ssh <username>@<VM Public IP> and enter password

用下面的命令设置 Jupyter 笔记本并启动 Jupyter

jupyter notebook password
// Enter password:
// Verify password:jupyter notebook --port 8888

创建从虚拟机到 localhost:9999 的 ssh 隧道

ssh -L 9999:127.0.0.1:8888 <username>@<VM Public IP>

现在进入 localhost:9999 使用 jupyter 笔记本,输入密码开始使用。

你可以创建一个文件夹,制作一个名为 pokedex-dl 的笔记本,然后开始工作。

**注意:**请参考 pokedex.ipynb 训练并将您的模型导出到 outputs 文件夹。我已经在笔记本上解释了每一个步骤,如果你有任何疑问,请在下面评论。

跟随 pokedex.ipynb 之后,您将有一个名为 poke_predictor_resnet34 的输出文件夹,从 Jupyter 笔记本下载。 上传模型到 Dropbox获取可共享链接

步骤 4:构建一个 web 应用程序,通过 API 使用我们的模型,并对其进行 dockerizing。

第一个 git 克隆:pokedex-在本地部署。用你的共享链接替换 server.py 中的 dropbox 链接。你也应该根据你的喜好改变 index.html。

您可以在 docker 中运行 pokedex-deploy ,使用

docker build -t poke-image . && docker run --rm -it -p 5000:5000 poke-image

也可以用自己喜欢的图像名称替换poke-image

现在我们已经准备好了 docker 图像,我们可以进入下一步了

第五步:将 web 应用的 Docker 映像推送到 azure 容器注册表。

首先我们需要设置 azure CLI,请咨询docs.microsoft.com/en-us/cli/azure/install-azure。给 Windows 用户的提示:-试试 Chocolatey 你可以参考chocolatey.org/packages/azure-cli进行安装。

别忘了az login

现在我们将使用 Azure CLI 创建一个私有容器注册表。容器注册表基本上是 docker 图像的 GitHub,docker hub 是一个公共容器注册表。

如果您需要以下步骤的更多细节,请参考容器-注册表-入门-azure-CLI

# create a resource group named container_registry_rg
az group create - name container_registry_rg - location eastus# create container registry named pokeRegistry
az acr create --resource-group container_registry_rg --name pokeRegistry --sku Basic# Login to your container registry
az acr login --name pokeregistry# tag your container registry in following format,
docker tag poke-image pokeregistry.azurecr.io/poke-image:v1# Push image to container registry, it will take a while
docker push pokeregistry.azurecr.io/poke-image:v1# You can verify if it's uploaded by 
az acr repository list --name pokeregistry --output table# Important Please don't forget this,important for deployment
az acr update -n pokeregistry --admin-enabled true

步骤 6:从 azure 容器注册中心在 Linux 容器 VM 中部署 web 应用程序。

在 portal.azure.com去天蓝色。并选择创建资源Web ,然后选择 Web App for Containers 或者你可以直接点击这个链接去那里。

点击 create,在页面中填写详细信息并创建一个新的资源组。请更改 Sku 和尺寸默认选项:B1 基本在开发/测试中,因为它将足以满足基本需求。不要忘记在 Docker 标签中将图像源设置为 Azure 容器注册表。

使用容器的 Web 应用程序进行部署

完成后,点击“转到资源”,您可以在 URL 找到您的网络应用程序 URL

恭喜你现在已经部署了你的深度学习模型🚀

步骤 7:使用 azure 管道设置连续部署。

现在在 azure 的 web 应用页面上,你会发现一个叫做**部署中心的东西,**这是 azure 中最酷的东西之一。它将帮助我们在 Azure 中创建 CI/CD 管道。

  • 单击部署中心
  • 选择源代码位置(Github)并授权它
  • 选择您的存储库
  • 它会自动检测 docker 文件,只需点击下一步
  • 创建 Azure DevOps 组织并选择使用容器注册表中的现有组织,单击完成
  • 完成页面后,单击“在中发布管道”

以上步骤可以在下面的 gif 中看到:

azure 部署中心

现在你必须在dev.azure.com如果不去那里,在 dev.azure.com的组织内部找到你的项目。

通过当前的设置,我们已经为我们的项目建立了 CI/CD 管道,这要感谢部署中心。

如果你对你的代码做了任何修改,并把它推送到 GitHub,它会构建一个新的镜像,把它添加到你的容器注册表中并进行部署。

但是我们现在有两个问题需要解决

  • 想象一下,你不断地修改你的代码,你的容器注册表(10 GB)将被所有未使用的图片使用
  • 如果您编辑您的 Readme.md,它将构建一个新的映像并部署它。

要解决这两个问题,请访问您在 dev.azure.com的组织内部的项目页面,并观看下面的视频。

哇哦。如果你到了这里,恭喜你🎉。如果你有任何疑问,请在评论区发表。

使用 Streamlit 和 Heroku 进行部署

原文:https://towardsdatascience.com/end-to-end-deployed-project-machine-learning-part-2-43ddb1bc43d0?source=collection_archive---------74-----------------------

每一个渴望进入数据科学领域的新手,都有一大堆项目放在自己的桌面上,无人触及。我们把它们放到网上怎么样??

在 Unsplash 上由 Minh Pham 拍摄的照片

本文中使用的所有代码和截图都来自我今年早些时候参与的一个个人项目。GitHub 回购的代码在这里被链接,部署的模型在这里被链接

使用 STREAMLIT 构建 UI:

首先,您需要将 streamlit 安装在您的系统上,或者您正在进行这个项目的虚拟环境中。

如果您没有安装 streamlit,请打开命令提示符并键入:

 pip install streamlit

一旦安装了 streamlit,您应该查看 streamlit 的官方文档,以熟悉其 python 库提供的各种小部件。我将从以下我认为最有用的小部件开始:

  1. 要输入纯文本
streamlit.write('Text data')

2.创建下拉列表

choices = ['1', '2', '3']
selected_ch = streamlit.selectbox('Pick a number', choices)

3.要创建滑块

num = streamlit.slider('Enter num', min_val, max_val, step)

4.接受输入

inp = streamlit.text_input('Enter some text here', default)
num = streamlit.number_input('Number', default)

使用上面的小部件,我们可以为我们的应用程序创建一个简单的 UI。当我第一次尝试这样做时,我用了不到 15 分钟就完成了整个 UI!这真的没有那么难!

如果您对此有任何疑问,请查看 streamlit 的官方文档。

将它保存在一个. py 文件中(比如“stream.py”)。

使用 streamlit 构建的 UI 示例[图片由作者提供]

部署到 Heroku:

如果这是你第一次部署到 Heroku,这可能会有点混乱。我将带你完成这最后一步,之后你的网站将在互联网上直播!这难道不令人兴奋吗???我们开始吧!

有很多方法可以做到这一点。然而,我将用最简单的方法开始

  • 第一步:创建一个 Heroku 账户,如果你还没有的话

这很简单。转到 Heroku 注册页面并填写那里给出的表格。

  • 第二步:创建一个新的应用程序,并给它一个合适的名字。

单击仪表板上的“新建”选项。您将被重定向到此页面

作者图片

  • 步骤 3:转到存储 stream.py 文件的文件夹

创建一个名为' Procfile '的文件,这是一个文件类型,因此,没有任何扩展名,如'。txt '或'。xlsx。在 Procfile 中键入以下内容

web: sh setup.sh && streamlit run stream.py
  • 第 4 步:在同一个目录中创建一个名为 requirements.txt 的文件,并列出到目前为止您在项目中使用的所有模块。
  • 步骤 5:创建一个名为“setup.sh”的文件,并用以下内容填充它:
mkdir -p ~/.streamlit/ 
echo "\
[server]\n\
headless = true\n\
port = $PORT\n\
enableCORS = false\n\
\n\
" > ~/.streamlit/config.toml
  • 步骤 6:将整个文件夹上传到 GitHub repo 中,比如 this repo 。
  • 第七步:打开你在 Heroku 上创建的新应用,点击“连接到 GitHub”图标

单击突出显示的图标[作者图片]

  • 第 8 步:输入你的 GitHub 库名并点击连接
  • 步骤 9:单击部署分支

[图片由作者提供]

瞧啊。!你的网站现在必须是活的!如果你已经做到这一步,请与我联系或留下评论,让我知道这篇文章是否对你有帮助。祝你未来的项目一切顺利。

使用 Flask 的机器学习模型的端到端部署

原文:https://towardsdatascience.com/end-to-end-deployment-of-a-machine-learning-model-using-flask-dc456abcc6da?source=collection_archive---------35-----------------------

使用 Flask 设计和构建利用机器学习的端到端 Web 应用程序

利用数据和可视化技能——照片由 Arian Darvishi 在 Unsplash 上拍摄

机器学习很漂亮——也很漂亮,如果它工作正常的话。然而,你只能把结果展示给和你一样理解过程的人。当有人知道它是如何工作的时候,魔力就消失了,并且在没有视觉帮助的情况下带领其他人经历它是什么…就像看着油漆变干一样令人兴奋。

因此,一个有效的思路是有一些视觉辅助,一些易于使用的东西,以及一些可以显示输出的东西,而不局限于 Jupyter 笔记本或终端。这里介绍 Flask : 一个完全用 Python 编写的 web 应用框架。它拥有最小的设置和快速的开发时间。这意味着学习一门只用于 web 部署的语言没有额外的麻烦——普通的 Python 也可以。

使用 Flask,我们现在可以将我们的机器学习模型带入生活(或者至少将它们带出笔记本和终端)。我们开始吧!

示例问题—问题分类

工作流程—由活动创建者在 Unsplash 上拍摄的照片

机器学习可以用来解决分类问题,并建立一个实用的模型,我们来看看一个简单而有效的挑战——问题分类。有关挑战的详细信息可在这里找到。

这个问题的目标是开发一个简单的机器学习模型,稍后可以使用 Flask 部署该模型。

准备数据集

数据集非常标准,有 5 列:Index、Questions、Cat0、Cat1、Cat2。

Cat1 只是 Cat0 中对应数据点的缩写。第一类只有 6 个类别,而第二类更深入,对每个问题都有更细的分类。作为准备数据集的一部分,我们可以检查唯一值以处理类不平衡,删除重复值并移除空值(如果有)。需要注意的另一个有趣的点是,我们不能直接使用分类标签,所以我们必须将 Cat1 和 Cat2 数据点中的每一个都转换成一个类别号,以便在我们的模型中用作目标变量。

这可以简单地通过以下方式完成:

#read the dataset
df = pd.read_csv('dataset.csv')#drop duplicates and values, if any
df.drop_duplicates(inplace=True)
df.dropna(inplace=True)
df.reset_index(inplace=True, drop=True)#convert categorical values into class numbers for our target variables
df['cat_label'] = pd.factorize(df['Category1'])[0]
df['topic_label'] = pd.factorize(df['Category2'])[0]

决定特征提取方法

如前所述,文本/分类值不能直接用于机器学习模型。要使用它们,我们需要将它们转换成数值或特征。文本中的特征提取和特征工程是指从数字格式的数据中提取信息。为了简单起见,我们使用简单直观的方法将文本转换成可用的特征。TF-IDF 是一种将文本数据建模为可用特征的非常直观的方法:

TF-IDF:语料库中所有单词的术语频率 x 逆文档频率。

制作分类模型

我们现在已经选择了一种将文本转换成特征的方法,并且已经形成了目标变量。现在剩下的就是拟合一个模型…..但是,哪一个呢?在决定最终的模型之前,测试不同的模型是很重要的。此外,通过 sklearn — 建模最佳分类算法是一项非常简单的任务,我们可以使用简单的 fit()和 predict()查看不同模型的输出。

对于这个项目,我们选择 SVM,线性支持向量机,决策树和随机森林作为我们的分类器。

将我们到目前为止讨论的内容放入一个简单的工作流中,我们得到:

为了评估我们的哪个模型工作得更好,我们需要计算和比较分类器之间的精确度。由于这是一个重复的过程,我们可以通过定义一个函数来评估分类器,使我们更容易。

运行评估脚本后,我们发现 LinearSVC 比其他的要好一些。在这一点上,我们可以将它作为我们的机器学习模型,但我们也可以调整并可能提高我们模型的性能。因此,下一步是使用 GridSearchCV 为我们的模型找到最佳参数。

对于任务 2,我们也可以遵循相同的流程。没有什么变化,除了通过记住我们数据集中的类不平衡来建模。

因为我们已经找到了我们的最佳模型并可能对其进行了调整,所以我们希望保存它以直接运行未来的预测,而不必再次训练分类器。回想一下,我们还使用了一个适合我们数据的矢量器。因此,也必须为我们的测试和预测数据存储相同的矢量器。

请记住,我们在类别 1 中有 6 个班级,在类别 2 中有 40+个班级。记住它们的一个简单方法是在 json/text 文件中保存 category_var:class_num 的映射。这很容易做到,就像这样:

#dictionaries to map category to label
cat_label_dict, topic_label_dict = {},{}for val in df['Category1'].unique():cat_label_dict[val] = df[df['Category1']==val]['cat_label'].unique()[0]for val in df['Category2'].unique():topic_label_dict[val] = df[df['Category2']==val]['topic_label'].unique()[0]#print and check the dictionaries
print(cat_label_dict, topic_label_dict)#save the mappings in text files
with open('category_labels.txt', 'w') as f:f.write(str(cat_label_dict))with open('topic_labels.txt', 'w') as f:f.write(str(topic_label_dict)) 

从保存的文件中制作预测函数

我们已经成功地完成了模型的训练、调整和保存!然而,我们的代码有点乱:到处都是,而且结构也不是很好。为了预测结果,我们需要一个函数将输入句子转换为小写,使用保存的矢量器提取特征,并使用保存的模型调用预测函数。为此,让我们从保存的文件中创建一个简单的预测函数。这段模块化代码也将在我们部署应用程序时对我们有所帮助。

制作 web 应用程序来部署模型

因为我们的 ML 模型现在已经准备好了,并且可以使用单个函数调用,所以我们准备部署它。对于这一部分,我们需要在本地机器上安装 Flask。

可以通过在终端中运行以下命令来简单地安装 Flask:

sudo apt-get install python3-flask
pip install flask

对于这部分,首选 VSCode 之类的 IDE 或者 Sublime Text 之类的编辑器。它们有助于自动完成,并对我们的代码结构有很好的了解。

每个基于 Flask 的 web 应用程序都有 3 个不同的东西——一个**‘模板’文件夹(存储 html 页面),一个‘静态’文件夹(存储 css 设计和一个可选的‘图像’**文件夹:存储图像),以及一个运行应用程序的 python 文件(通常按照惯例命名为 app.py)。

由于许多人(像我一样)不太擅长设计 Web 应用程序,一个快速的解决方法是使用已经可用的 HTML 模板。选择一个适合您的用例,或者可以修改以适合您的用例。这里的是免费 html 模板设计的起点。

可以演示一下模板,自己试试。您也可以在在线编辑器中进行更改,并直接在浏览器中查看。如果你不习惯使用传统的编辑器和检查输出,它可以帮助你快速设计网页。

对于这个项目,我为我的 web 应用程序选择了一个主页和一个预测页面。确保所有的 html 文件都在 templates 文件夹中,它们的 css 在 static 文件夹中。

在应用程序的预测页面中可以看到主要的实现—

最后,我们构建我们的 app.py,它运行我们的后端:ML 模型。为此,我们使用前面编写的预测函数,并为每个 html 页面定义路径。通过定义路由,我们的意思是告诉代码当点击一个特定的本地 html 页面引用时要呈现什么页面。

此外,因为我们接受模型的输入(通常通过 HTML 表单),所以我们需要相应地设置表单动作和方法。一个非常简单的方法是使用 url_for ,它将路由直接设置到大括号内的参数。在这里,我们将其设置为 predict(),这是 app.py 中预测函数的名称。

为了访问在 html 页面上使用表单进行的任何输入,我们使用 requests . form['【T2]']。

将所有这些合并到一个 app.py 文件中,我们将它编写如下—

要运行我们的应用程序,我们只需输入

python3 app.py

结果应该是这样的:

在端口 5000 上成功运行 Flask 应用程序

这标志着使用 Flask 部署我们的项目的结束。

为什么要学习如何为项目制作 WebApps?

作为一名机器学习工程师/数据科学家,或者是任何数据相关领域的爱好者/实践者,展示产品端到端开发的知识非常重要。Flask 与 pure Python 无缝集成,因此很容易开发应用程序。Flask 应用于构建概念证明、演示解决方案以及展示发展和增长。

学习 Flask 这样的简单框架也有助于完善开发人员的技能。一般来说,数据科学更依赖于你如何有效地向一群可能并不特别关注技术或数据的人展示你的想法。

数据科学家本质上仍然是软件工程师。因此,构建、测试、开发和部署应用程序应该是每个软件工程师技能的一部分。

如果你喜欢这篇文章,发表评论并鼓掌表达你的感激之情!您也可以使用我的 linkedin 个人资料直接与我联系。

这个项目的全部代码可以在我的 github 仓库中找到。

端到端机器学习平台比较

原文:https://towardsdatascience.com/end-to-end-machine-learning-platforms-compared-c530d626151b?source=collection_archive---------38-----------------------

对业界领先的机器学习平台的简短对比。

由 Martin Reisch 在 Unsplash 上拍摄的照片

任何参与将机器学习模型部署到生产中的组织都知道它会带来业务和技术挑战,并且通常会通过使用机器学习平台来解决这些挑战中的一些挑战,并辅以一些 MLOps 流程来提高团队的成熟度和治理。

对于在生产中运行多种模型并寻求采用 ML 平台的组织,他们通常要么在内部构建一个端到端的 ML 平台(优步、 Airbnb 、脸书学习者、谷歌 TFX 等),要么购买。在这篇文章中,我将比较一些你可以买到的 ML 平台。

什么时候需要一个端到端的 ML 平台?

你应该先回答另一个问题。“你想解决什么问题?”。如果你想不出任何现存的问题,那么实施新技术就毫无意义。然而,如果您遇到了一些问题,例如,跟踪生产中的模型或版本,增加对 ML 实验的管理,随着数据科学团队的增长共享笔记本电脑,或者主动监控数据漂移和/或功能漂移,那么您很可能正在或即将走上实施 ML 平台组件的道路。

为了帮助这个过程,我对我认为的 ML 平台的关键组件进行了高层次的比较。

比较

以下比较考虑了开箱即用的功能。例如,不部署开源解决方案来弥补功能上的差距或自行开发。

点击此处查看链接:https://gist . github . com/ash his/f54a 523 bb 5390d 55 a 46 FCE 415 bcdc 691

我在从 github 嵌入表格时遇到了一些问题,所以如果你想浏览上表中的链接,请点击这里。

特色店?

您可能已经注意到,没有一个解决方案提供功能存储。特色商店是一个相当新的组成部分,我怀疑在不久的将来会有更多的组织将它加入到他们的 ML 平台中。他们有一些可用的开源解决方案,在这个神奇的网站上有更多的研究资料。记住,在把时间和金钱投入到一个无关紧要的问题之前,把注意力集中在你要解决的问题上。

“你想解决什么问题?”

结论

在这篇短文的结尾,我想强调一些其他值得一提的产品,但它们没有包括在这个比较中。 DataRobot , IBM Watson Studio , H2o.ai ,数据砖块 & Cloudera 。随着机器学习领域的迅速变化,我将努力在未来几个月保持这篇文章的最新状态。你不必听我的,只要看看今年 Spark + AI 峰会上 Databricks 的 MLflow 博客上的所有公告就知道了!

如果您想将您的产品添加到这一比较中,请通过我的 LinkedIn 联系我。

关于我:我是数据&机器学习的产品负责人,生活在商业、数据和机器学习的交汇点。想联系的可以在LinkedIn上联系我。

端到端机器学习项目:第二部分

原文:https://towardsdatascience.com/end-to-end-machine-learning-project-627ed48f8109?source=collection_archive---------55-----------------------

杰克·安斯蒂在 Unsplash 上的照片

在之前的帖子中,我们看到了我如何训练一个图像分类模型,从数据准备开始到训练模型的不同迭代,都使用了卷积神经网络转移学习来获得一个对美钞进行分类的最终模型。如果你还没有,我建议你先浏览一下那篇文章,然后再来看这篇文章。

Part-1(前一篇) :准备数据并训练图像分类模型
Part-2(后一篇):使用 Flask 和 Docker 部署模型

训练完模型后,下一个挑战就是展示它。我不想在云资源托管上花费太多,所以我尝试了许多不同的选项,但找不到一个看起来足够容易快速启动和运行的选项。相信我,当我说有大量的资源和教程讨论如何创建和训练你的深度学习模型,但只有少数资源谈论部署这些模型

用什么“工具”?

当我接近完成这个模型的时候,这个问题在我的脑海里打转。我知道我想部署这种模式,但不确定平台——它应该是一个本地移动应用程序还是一个 web 应用程序。在进一步讨论之后,我选择了一个快捷的 web 应用程序,这样就可以通过浏览器从任何设备访问它。

我选择了用Flask*—*一个轻量级的 WSGI web 应用框架。它是可用的最流行的 Python web 应用程序框架之一,以其简单易用以及能够扩展以构建更复杂的应用程序而闻名。

对于这个部署,我选择使用我现有的云服务器— a Nanode ,以避免投资额外的云资源,并决定采用基于容器的方法。

容器是一个标准的软件单元,它将代码及其所有依赖项打包,以便应用程序能够快速可靠地从一个计算环境运行到另一个计算环境。(来源)

我决定使用 Docker、 ,它提供了一种使用公共运行时在同一台机器上运行多个容器的方法,即 Docker 引擎

1:使用 Docker 的容器化应用程序

对于托管应用程序,我选择了 Nginx,它提供了一个代理服务器来托管您的 web 应用程序。

NGINX 是一个免费、开源、高性能的 HTTP 服务器和反向代理,以及一个 IMAP/POP3 代理服务器。NGINX 以其高性能、稳定性、丰富的特性集、简单的配置和低资源消耗而闻名。(来源)

构建基于 Flask 的 web 应用程序

我发现这个非常有用的 GitHub 项目 [1],它提供了一个简单的模板来使用 Flask 将你训练好的图像分类模型部署为一个 web 应用。我对[1]中的代码做了一些修改,通过加载我训练过的模型(我正在使用一个*)使它特定于我的模型的目标。tf* 模型而不是使用 .h5 文件)、设置输出类名、设置成功预测的概率阈值等。所有这些更改都是对作为 flask web 应用程序主要后端的 app.py 文件进行的。

我还对这个项目的 CSS(网页样式)和 JavaScript 文件做了一些小的改动。

你可以参考这个项目的我的 GitHub 库的所有这些变化。

设置服务器(正确…)

这是这个部署难题中最重要的一块,我可能花了最多的时间来研究、完成和设置它,甚至比构建模型本身还多。

第一步是根据操作系统(OS)在您的服务器上安装最新版本的 Docker。我有一个 Ubuntu 盒子作为我的服务器,所以我按照这个快速指南 [2]安装 Docker,这是一帆风顺的。

下一步是找到一种方法,使用多个 docker 容器在同一服务器上部署不同的应用程序。经过大量的谷歌搜索,我偶然发现了这篇令人惊叹的文章【3】,它与我试图实现的目标相似,作者用非常好和简单的方式解释了这一切。

图 2:使用 Nginx 反向代理和 Docker 的部署

这里,nginx 反向代理充当这个设置的容器,监听外部端口 80 (HTTP)和 443 (HTTPS),充当世界和容器之间的通信媒介。容器本身的内部工作是隐藏的,用户在访问这些应用程序时看不到任何区别。

按照[3]中的示例 docker-compose.yml ,我为充当主容器的服务器设置了我的 nginx 反向代理和 SSL 版本,同时按照 docker-compose 中的定义设置了网络。

下一步是创建一个从属容器,它将托管我的 web 应用程序。为此,我基于[3]和这个 post [4】的组合创建了一个容器应用程序,它使用 docker 文件来设置承载项目的容器。基于我的项目需求,我修改了 docker-compose 和 Dockerfile。

图片-3: Dockerfile(作者提供图片)

项目容器基于 docker hub 的tensor flow-2 . 0 . 0-py3 docker image,使用 python3 和 tensorflow-2.0。点击这里查看你可以在项目中使用的其他 tensorflow 图片列表。下载完基础映像后,我将项目的 flask 应用程序和模型复制到这个容器中,并使用 pip 安装运行项目的需求。

图 4: Docker 撰写(作者提供照片)

最终的 docker-compose 文件使用上述 docker 文件来创建一个名为 usbills 的容器,该容器托管模型和 web 应用程序。它还创建了一个 nginx 服务,这个服务依赖 依赖**usbills容器,也就是说,如果构建 us bills 容器时出现问题,nginx 容器将不会被创建。

这个 nginx 容器的 environment 部分设置了一个 VIRTUAL_HOST,它是这个 web 应用程序的 DNS 名称,一旦部署了这个容器,就可以访问它。这个 nginx 容器充当从容器,并根据从服务器主容器接收的请求工作。

一旦创建了这两个文件,并且我确保了主容器正常工作,那么只需编写一行命令就可以托管这个应用程序了。

$ docker-compose up -d

结论

如上面的 docker-compose 所示,通过访问这个链接,可以从任何设备和浏览器访问这个 web 应用程序。在我最终建立和部署这个模型之前,我花了很多时间搜索、阅读、理解、尝试和失败。这种多容器部署方法还为将来在同一台服务器上使用类似的 docker-compose 设置轻松部署任何其他应用程序奠定了基础。

希望您喜欢这个两部分的系列。我知道这种方法可能不适合每个人,但希望它能帮助那些和我处境相同的人,他们正在寻找部署我训练有素的模型的方法,而不必花费大量的云资源。请随意使用这种方法来共享您的模型部署的链接,或者如果您有任何其他比这种方法更好的方法。

不断学习,打造酷炫模型。下次见…

参考

[1] 用 flask 作为 web app 在 10 分钟内部署 Keras 模型
【2】如何安装 Docker 并拉取映像进行容器部署
【3】托管多个站点使用 Docker 和 NGINX 反向代理使用 SSL
【4】NGINX 作为 flask app 的反向代理使用 Docker
【5】什么是容器?

端到端机器学习项目:第 1 部分

原文:https://towardsdatascience.com/end-to-end-machine-learning-project-part-1-806d04da8deb?source=collection_archive---------50-----------------------

比约恩·斯内尔德斯在 Unsplash 上的照片

端到端机器学习 关注的是准备你的数据,在上面训练一个模型,然后部署那个模型。这两部分系列的目标是展示如何为图像分类模型开发和部署端到端的机器学习项目,并使用迁移学习

尽管有大量的其他在线资源向您详细展示了如何构建您自己的模型,但是很少有资源深入研究如何部署这些模型。本文是第二部分的前身,第二部分将展示部署步骤。如果你已经熟悉构建这样一个模型,并且正在寻找如何部署它的方法,那么我建议你浏览一下这篇文章,看看第 2 部分。

第一部分(本文):准备数据并训练图像分类模型
第二部分:使用 Flask 和 Docker 部署构建好的模型

机器学习 模型目前被广泛用于构建聊天机器人、语音助手、无人驾驶汽车等。一个具体的进步是在图像识别和分类领域。卷积神经网络(CNN)尤其被证明在从图像中学习方面非常有帮助,这导致了在创建最先进模型方面的重大突破,如 Resnet 、 Alexnet 、 Inception 等。这已经被证明在 Imagenet 数据集上对图像进行分类时非常有效。

在这篇文章中,我们将看到如何从头开始训练一个图像分类模型,并使用 Resnet 模型中预先训练好的权重。这种技术称为迁移学习,非常受欢迎,因为它有助于使用使用大得多的数据集和计算资源训练的权重,以最小的变化应用于另一个数据集。通常,您只需根据数据集更改输出图层,就可以从这些预训练的权重中获益。这个项目中模型的目标是对不同的美钞进行分类,并使用 Tensorflow 2.xKeras 构建。

要求

第一个挑战是收集数据。由于找不到任何适合这个项目的数据集,我最终拍摄了不同美钞的照片来创建我自己的数据集。该最终数据集包含大约 180 幅图像,其中包括一些负图像,即没有任何美钞的图像,因此当图像中有美钞时,模型可以更好地区分。

我使用paper space Gradient来训练模型,这非常类似于 Google Colab,并提供免费的 GPU 和基于 Jupyter 笔记本的环境来训练模型。在我看来,这上面的免费 GPU 比 Google Colab 里面提供的好一点

数据准备和加载

由于这些图像的大小都不同,第一步是做一些数据准备,并将它们的大小调整为相同的大小。Resnet 期望输入图像大小为 224x224 ,因此我调整了数据集中图像的大小以匹配。我还使用数据扩充技术来补充我的数据集,这也有助于减少过度拟合

数据扩充 通过应用产生看起来可信的图像的随机变换,帮助从现有训练样本生成更多训练数据。目标是在训练时,你的模特永远不会两次看到完全相同的图片。这将模型暴露给数据的更多方面,从而允许它更好地进行归纳。

**如下图 1 所示,对图像进行了处理和加载。**

图片-1:数据准备步骤(作者提供图片)

20%的可用图像,没有增强,被留在一边用于 验证

重要的是保持验证集不变,以便更好地评估您训练的模型。

剩余的图像用于训练模型。类别标签采用一键编码。

图片-2:班级指数(作者照片)

图 3:可视化数据集(作者照片)

训练一个简单的 CNN 模型

既然我已经加载并扩充了数据集,下一步就是训练模型。我首先创建一个简单的 CNN 模型,它有一个由 4 个卷积层和最大池层组成的集合,然后是一个带有 T2 激活函数的输出层。

图 4:简单的 CNN 模型架构(作者拍摄)

我把这个模型设定为 100 个 纪元 *。*我还为 使用了一个回调函数,提前停止(more info) 当它看到模型没有进一步改进并且开始过拟合时,就停止训练。对于该模型训练,验证损失在第 30 个时期附近停止下降,并且由于提前停止,训练在第 40 个时期停止。使用另一个回调函数— 模型检查点 保存第 30 时段的最佳模型—**

图 5:简单的 CNN 模型图(作者照片)

使用迁移学习训练模型

简单的 CNN 模型在验证集上表现不太好,所以尝试创建更好的模型的下一步是使用迁移学习。我选择了 Resnet50v2 作为基础模型的 imagenet 权重。感谢 Keras,它使得使用TF . Keras . applications包在一行中获得这些权重变得容易得多,拥有一个模型架构列表,如 resnet、inception 等。用他们预先训练好的重量。

在开始编译和训练基础模型之前,冻结(防止训练期间体重更新)是很重要的。您可以通过设置layer.trainable = False来冻结模型的单层。一个模型可以有许多层,所以将整个模型的可训练标志设置为将冻结所有层。

在冻结了基本 Resnet50v2 模型的层之后,我添加了一个 GlobalAveragePooling 层,然后是一个激活了 softmax 的密集层,以获得所有类的预测值。

图片-6:迁移学习模型架构(作者提供图片)

注意,在图 6 中,大约 2350 万个参数(对应于基本 Resnet50v2 模型)被冻结并标记为不可训练参数。我们只训练大约 14000 个与最终输出层相关的参数。

下一步是使用 adam optimizer 编译和训练模型,其中分类 _ 交叉熵损失是根据准确性度量计算的。

注意这里使用的 categorical _ crossentropy,因为每个标签都由一个独热向量表示。如果单个值(类的索引)代表每个标签,应该使用 sparse _ categorical _ crossentropy。

与简单的 CNN 模型类似,我将这个模型设置为使用相同的两个回调函数训练 100 个纪元,但这个模型的性能甚至更差。验证损失在仅仅 4 个时期后开始增加,这非常糟糕,但这可能是因为基础模型的预训练 imagenet 权重不直接与我的数据集一起工作,并且可能我必须重新训练基础模型的一些层,以帮助它学习特定于我的数据集的特征。

使用迁移学习对模型进行微调和训练

预先训练的基础 Resnet50v2 模型在这个现成的数据集上表现不太好,但仍有一些希望,以 微调 的形式。

****微调基础模型是迁移学习中的一个过程,在这个过程中,你训练模型的最上面几层,保持这些层的权重不变。这将强制将权重从通用要素映射调整为与这些顶层的当前数据集特定关联的要素。

在使用了几次之后,我发现调整基本模型的前 70 层在这个数据集上工作得非常好。您可能需要经过几轮讨论才能得出适合您的特定数据集的数字。 Resnet50v2 模型总共有 190 层,不包括输出层,所以我保持前 120 层的权重冻结,并在我的数据集上重新训练后 70 层的权重。

图 7:微调的模型架构(作者提供照片)

图 8:微调后的模型拱门(作者拍摄)

如果你仔细观察图 8,你会发现这个微调模型有超过 1800 万个可训练参数,相比之下,当我保持基本模型的所有权重不变时,只有大约 14000 个可训练参数(参见图 6)。

与其他两个模型类似,我将这个经过微调的模型设置为使用相同的两个回调函数运行 100 个时期。在第 24 代左右,验证损失开始非常缓慢地增加,这表明模型从这一点开始缓慢地过度拟合。最佳模型在这一瞬间被保存。

图 9:微调后的模型图(作者提供照片)

结论

在使用不同的模型进行了几次迭代之后,我能够训练一个在我的数据集上表现良好的模型。迁移学习肯定很有帮助,并且是一种在你自己的数据集上快速建立模型的巧妙技术,同时获得预先训练的成功模型的好处。

改进该模型的下一步将是添加更多数据,并尝试使用类激活图(CAMs) 来了解模型关注图像的哪些部分。

你可以在这里 找到用来训练这三个型号 的笔记本和代码。

**在本系列的下一部分中,我们将看到如何使用 Flask 和 Docker 部署训练好的模型。现在就来看看吧,享受创建新数据集、训练模型和部署它们的乐趣。

下次见……

端到端机器学习项目:综述和分类

原文:https://towardsdatascience.com/end-to-end-machine-learning-project-reviews-classification-60666d90ec19?source=collection_archive---------32-----------------------

将评论分为正面或负面的项目

图 1(来源:作者)

在本文中,我们将讨论一个分类问题,包括将评论分为正面或负面。此处使用的评论是客户对 ABC 服务的评论。

数据收集和预处理

这个特定项目中使用的数据是从网上搜集的,数据清理是在这个笔记本中完成的。

[## 网页抓取:抓取表格数据

在这篇文章中,我们将学习如何使用 Python 抓取 web 数据。简化。

towardsdatascience.com](/web-scraping-scraping-table-data-1665b6b2271c)

在我们抓取之后,数据被保存到一个.txt file文件中,这里是一行文件的例子(代表一个数据点)

{'socialShareUrl': 'https://www.abc.com/reviews/5ed0251025e5d20a88a2057d', 'businessUnitId': '5090eace00006400051ded85', 'businessUnitDisplayName': 'ABC', 'consumerId': '5ed0250fdfdf8632f9ee7ab6', 'consumerName': 'May', 'reviewId': '5ed0251025e5d20a88a2057d', 'reviewHeader': 'Wow - Great Service', 'reviewBody': 'Wow. Great Service with no issues.  Money was available same day in no time.', 'stars': 5}

数据点是一个字典,我们对reviewBodystars感兴趣。

我们将评论分类如下

1 and 2 - Negative
3 - Neutral
4 and 5 - Positive

在收集数据时,网站上有 36456 条评论。数据高度不平衡:总评论中 94%是正面的,4%是负面的,2%是中性的。在这个项目中,我们将在不平衡数据和平衡数据上拟合不同的 Sklearn 模型(去掉过多的正面数据,这样我们就有相同数量的正面和负面评论)。)

下图显示了数据的构成:

图 2:数据构成(来源:作者)

在图 2 和上面的图中,我们可以看到数据非常不平衡。这可能是问题的征兆吗?我们会看到的。

让我们从导入必要的包开始,并定义我们将用来对给定的审查消息进行分类的类Review

这里,我们将加载数据,并使用Review类将评论消息分类为正面、负面或中性

Wow. Great Service with no issues.  Money was available same day in no time.POSITIVE

将数据分成训练集和测试集

Size of train set:  25519
Size of train set:  10937

在我们继续深入之前,我们需要理解单词袋的概念。

词汇袋

[ 链接 ] [ 链接

正如我们所知,计算机只理解数字,因此我们需要使用单词袋模型将我们的评论消息转换成数字列表。

一个单词包是描述单词在文档中出现的文本表示。它涉及两件事:一是已知单词的词汇。对已知单词的存在的测量。

单词袋模型是在文档分类中使用的支持模型,其中每个单词的出现(频率)被用作训练分类器的特征。

举例:

考虑这两个评论

  • ABC 汇款团队的卓越服务。推荐
  • 糟糕的服务。交易延迟三天。不推荐。

从上面的两个句子,我们可以推导出下面的字典

【优秀,服务,通过,通过,ABC,汇款,团队,推荐,不良,交易,延迟,为,三,天,不要】

我们现在对这个字典进行标记化,以生成下面两个数据点,现在可以用它们来训练分类器

图 3(来源:作者)

在 python 中,标记化是按如下方式完成的

['abc', 'bad', 'by', 'days', 'delayed', 'don', 'excellent', 'for', 'recommend', 'remit', 'services', 'team', 'the', 'three', 'transaction'][[1 0 1 0 0 0 1 0 1 1 1 1 1 0 0][0 1 0 1 1 1 0 1 1 0 1 0 0 1 1]]

既然我们已经理解了单词袋的概念,现在让我们将这些知识应用到我们的train_xtest_x

在不平衡数据中训练模型

此时,我们已经有了可以用来拟合模型的向量,我们可以继续这样做了

支持向量机

Review Message:  easy efficient  first class
Actual:  POSITIVE
Prediction:  ['POSITIVE']

图 4:拟合 SVM 产生的混淆矩阵(来源:作者)

训练的其他模型包括集合随机森林、朴素贝叶斯、决策树和逻辑回归。一个链接到完整代码。

不平衡数据下的模型性能评估

  1. 精度

使用准确性度量对模型进行评估,结果如下

图 5:模型在不平衡数据上的表现(来源:作者)

我们得到了 90%的准确率,是正确的还是有问题?答案是,有问题。

数据是不平衡的,使用准确性作为评估标准不是一个好主意。以下是类别分布情况

----------TRAIN SET ---------------
Positive reviews on train set: 23961 (93.89%)
Negative reviews on train set: 1055 (4.13%)
Neutral reviews on train set: 503 (1.97%) ----------TEST SET ---------------
Positive reviews on test set: 10225 (93.48%)
Negative reviews on test set: 499 (4.56%)
Neutral reviews on test set: 213 (1.95%)

如果分类器正确预测了测试集中所有正面评论,而没有负面和中性评论,会发生什么?分类器的准确率将达到 93.48% !!!!!!

这意味着我们的模型将有 93.48%的准确性,我们将认为该模型是好的,但在现实中,该模型“只知道最好”如何预测一个类别(正面评论)。事实上,从图 4 来看,SVM 预测根本没有中立的评论

为了进一步理解这个问题,让我们引入另一个度量: **F1 得分,**并用它来评估我们的模型。

  1. F1 得分

F1 分数是精确度和召回率的调和平均值。

精确度和召回率衡量模型正确分类正面案例和负面案例的程度。在这里阅读更多。

当我们根据这个指标评估我们的模型时,结果如下

图 6(表格) :不同分类器的 F1 分数(来源:作者)

图 7(绘图) :不同分类器的 F1 分数(来源:作者)

从图 6 和图 7 中,我们现在知道模型在分类正面评论方面非常好,而在预测负面和中性评论方面很差。

使用平衡数据

作为平衡数据的一种方式,我们决定随机删除一些积极的评论,以便我们使用均匀分布的评论来训练模型。这一次,我们在 1055 条正面评论和 1055 条负面评论上训练模型。我们也放弃了中立阶级。

图 8:平衡数据的分布(来源:作者)

(您也可以考虑使用过采样技术来解决数据不平衡的问题)

训练完模型后,我们得到了以下结果

图 9:平衡数据的模型精确度(来源:作者)

SVM 获得了 88.9%准确率的最佳结果,在检查 F1 分数(如下)后,我们现在可以意识到,这些模型预测负面评论与正面评论一样好。

图 10(表格) :不同分类器的 F1 分数(来源:作者)

图 11(绘图):不同分类器的 F1 分数(来源:作者)

如果我们观察显示 SVM 结果的混淆矩阵,我们会注意到该模型在预测这两类中都很好

图 12:使用 SVM 结果生成的混淆矩阵

找到完整的代码在这里

结论

在完成这个项目后,我希望你能够了解到:

  • 根据不平衡的数据拟合一个或多个模型可能(在大多数情况下确实如此)导致不良结果。
  • 在处理不平衡的数据时,准确性不是一个好的衡量标准。
  • 大部分工作是在预处理阶段完成的。

感谢您的阅读:-)

TFX 在 TensorFlow 2.x 上的端到端机器学习

原文:https://towardsdatascience.com/end-to-end-machine-learning-with-tfx-on-tensorflow-2-x-6eda2fb5fe37?source=collection_archive---------20-----------------------

去年年底 Tensorflow 2.0 发布时,我非常兴奋。毕竟,它承诺了比 1.x 版本更令人愉快的开发人员体验(或者被称为来自地狱的 Java 的深度学习等价物)。对部署模型有强大支持的 Keras 层?算我一个!

然而,当我意识到对将 TF 2.0 模型投入生产的支持并不是我想象的那样时,我的兴奋是短暂的。当然, TensorFlow Extended 是一个选项,但考虑到文档尚未跟上,这不是一个特别令人愉快的选项。

尽管如此,我还是不耐烦了;还有,急于执行。接下来是一段充满泪水和欢呼的艰苦旅程,所有人都在寻找一个真正的奖励,那就是一个工作的机器学习管道。我向你们展示我在 r̶a̶n̶t̶s̶的发现,希望你们不必重蹈我的覆辙。不管怎样,直到下一个版本。

这是(不是)什么

这篇文章绝不是关于构建生产就绪的 TF 2.0 管道的方法的权威文章。它展示了部署 ML 模型的一个可能的工作流,该工作流考虑了内存约束和训练服务偏差(以及其他因素)。如果这些概念听起来很陌生,我推荐阅读谷歌的机器学习规则。有神经网络和机器学习生命周期的经验肯定会有帮助。

Gojek 采用的机器学习生命周期示例

您将学习如何:

  • 使用 TF 变换执行特征插补和缩放
  • 使用 Keras functional API 和特性列构建模型
  • 为服务于的 TF 导出一个重用转换图的模型

为了简短起见,我将只展示代码片段。

1.安装依赖项

您将需要以下 Python 包。因为我们将使用 Apache Beam 来运行我们的 TF 转换管道,所以让我们也安装它。

*pip install apache-beam==2.16.0 tensorflow==2.0.0 tensorflow-transform==0.15.0*

2.使用 TF 变换预处理数据

本指南假设读者熟悉 TF 转换,这涉及到在一个preprocessing_fn中编写由射束管道执行的转换。关于如何开始的更多信息可以在这里找到。

让我们为一个数值变量age编写一个简单的转换,用平均值估算缺失值并应用特征缩放。

*import tensorflow as tf
import tensorflow_transform as tftdef preprocessing_fn(inputs):outputs = inputs.copy()age = outputs["age"]mean_age = tft_mean(age)age = impute(age, -1, mean_age)outputs["age"] = tft.scale_to_z_score(age)return outputs*

停下来。TF 变换不支持使用tft.mean()分析器计算平均值吗?为什么我们需要自己编写tft_mean的实现?这是因为 TF 变换有一个已知问题,其中 nan 可能会为某些分析器产生意外结果。为了解决这个问题,我们只使用非空值来计算平均值。

*def tft_mean(tensor):finite_indices = tf.math.is_finite(tensor.values)finite_values = tf.boolean_mask(tensor.values, finite_indices)return tft.mean(finite_values)*

现在,让我们使用平均年龄来估算缺失值。有两种方法表示缺失值:第一,通过使用稀疏处理器进行排除;第二,通过使用一些任意值(例如,-1代表数字变量,或者NULL代表分类变量)。让我们考虑这两种情况。

*def impute(tensor, missing, replacement):sparse = tf.sparse.SparseTensor(tensor.indices, tensor.values, [tf.shape(tensor)[0], 1])dense = tf.sparse.to_dense(sp_input=sparse, default_value=replacement)return tf.where(tf.equal(tensor, missing), replacement, dense)*

然后,您可以运行您的 TF 转换管道,不要忘记导出转换图,以便我们可以在以后重用它!

*import apache_beam as beam 
import tensorflow_transform.beam as tft_beam
import tempfilewith beam.Pipeline() as pipeline:with tft_beam.Context(temp_dir=tempfile.mkdtemp()):# read raw dataraw_data = pipeline >> beam.io.ReadFromTFRecord(...)# apply transformationtransformed_data, transform_fn = ((raw_data, raw_metadata) >> tft_beam.AnalyzeAndTransformDataset(preprocessing_fn))# export transform graph_ = (transform_fn >> tft_beam.WriteTransformFn("data/tft/"))*

3.使用 Keras 图层和要素列构建模型

是时候进行一些功能工程了。TensorFlow 特性列为常见操作(如一键编码)提供了一个简洁的 API。让我们为一个数字变量age和一个分类变量country定义特性列。

*features = [tf.feature_column.numeric_column("age"),tf.feature_column.indicator_column(tf.feature_column.categorical_column_with_vocabulary_list("country", ["America", "Japan", "China"],)),
]*

在 Keras functional API 中使用特性列可能有点棘手。你需要使用一个输入层来实例化一个 Keras 张量。

*from tensorflow.keras.layers import Inputfeature_inputs = {"age": Input(name="age", shape=(), dtype=tf.float32),"country": Input(name="country", shape=(), dtype=tf.string),
}*

我们现在可以将它输入到 Keras DenseFeatures 层,并继续定义我们的神经网络架构。

*from tensorflow.keras.layers import Dense, DenseFeatures
from tensorflow.keras import Modeloutput_1 = DenseFeatures(features)(feature_inputs)
output_2 = Dense(16, activation="relu")(output_1)
preds = Dense(10, activation="softmax")(output_2)
model = Model(inputs=feature_inputs, outputs=preds)model = model.compile(...)
model.fit(...)*

4.导出模型和调用转换图

恭喜你走到这一步!在训练我们的模型之后,我们将把我们的模型导出为一个保存的模型来部署它。为了防止训练和服务之间的偏差,我们需要加载导出的转换图,以便对服务输入运行相同的转换。

*tft_dir = "data/tft/"  # location of exported transform_fntft_output = tft.TFTransformOutput(tft_dir)
tft_output.transform_raw_features(raw_serving_inputs)*

在 Tensorflow 1.x 中,当导出您的模型时,您将在serving_input_receiver_fn 中包含上述逻辑。然而,随着我们远离 TF 2.x 中的估计器 API,这个功能已经被弃用了。相反,我们需要通过覆盖save()方法来修改 Keras 模型的服务签名。

*class ExportModel(tf.keras.Model):def __init__(self, model, tft_dir):super().__init__(self)self.model = modelself.tft_output = tft.TFTransformOutput(tft_dir)@tf.function(input_signature=[SERVING_FEATURE_SPEC])def serving_fn(self, inputs):transformed = self.tft_output.transform_raw_features(inputs)return {"preds": self.model(transformed)} def save(self, output_dir):signatures = {"serving_default": self.serving_fn} tf.saved_model.save(self, output_dir, signatures)ExportModel(model, "data/tft/").save("data/model/1/")*

然后我们可以使用 TF 服务来服务我们的模型。

希望这有所帮助。再见。

包含真实项目的端到端 OptimalFlow 自动化机器学习教程

原文:https://towardsdatascience.com/end-to-end-optimalflow-automated-machine-learning-tutorial-with-real-projects-formula-e-laps-31d810539102?source=collection_archive---------23-----------------------

公式 E Laps 预测—第 2 部分

在本教程的上一篇 ***第 1 部分*** 中,我们讨论了如何实施数据工程以准备合适的数据集,从而提供进一步的建模步骤。而现在我们将重点讨论如何使用 OptimalFlow 库( 文档||GitHub)来实现 Omni-ensemble 自动化机器学习。

为什么我们使用 OptimalFlow ?你可以阅读另一个关于它的介绍的故事:一个全方位的自动化机器学习——optimal flow

步骤 1:安装 OptimalFlow

用 Python 3.7+设置好自己的工作环境,通过Pip 命令安装 OptimalFlow 。目前,最新版本是 0.1.7。更多包的信息可以在 PyPI 找到。

pip install OptimalFlow

步骤 2:仔细检查缺失值

在本教程第 1 部分的数据准备之后,大多数特性都准备好了,可以进入建模过程。当数据流到达autoPP(***optimal flow 的*** 自动特征预处理模块)时,类别特征中的缺失值不受欢迎。因此,我们需要仔细检查清理后的数据,并对缺失值的要素进行数据清理。对于这个问题,我只发现'组'功能有丢失的值,并使用以下代码来转换它。

步骤 3:自定义设置

OptimalFlow 提供开放接口,供用户在各个模块中进行自定义设置。甚至在autoCV(optimal flow的模型选择&评估模块)中,您也可以自定义设置具体的模型或超参数搜索空间。你可以在 文档 中找到更多细节。

如下面的代码,我们为autoPP(optimal flow的 auto feature 预处理模块)设置了缩放器和编码器算法; autoFS 的选择器( OptimalFlow 的自动特征选择模块);估算器为autoCV模块。

对于特征选择和模型选择,我们建立了选择器和估计器搜索空间。

请注意:“稀疏度”和“列数”是您可以设置的两个限制,以减少数据集组合的数量。通常,当数据集的稀疏度太低时,特征内的方差将很低,这意味着信息值将很低。根据可接受的数据集数量,您可以尝试这两个参数的不同值设置,这些数据集将通过管道簇遍历实验(PCTE)过程来找到其管道工作流的最佳模型。当然,从 autoPP 模块生成的数据集组合越多,在 OptimalFlow 自动机器学习中进一步处理需要的时间就越多。反之,当没有满足稀疏性和列数限制的数据集组合时,后续过程无法继续。所以,要小心,用这些设置尝试一些值。

步骤 4:管道集群遍历实验(PCTE)

optimal flow中的核心概念/改进是流水线簇遍历实验(PCTE) ,这是 Tony Dong 在 Genpact 2020 GVector 大会上首次提出的一种框架理论,利用系综流水线算法优化和自动化机器学习工作流。**

**与使用单个流水线的其他自动化或经典机器学习工作流的重复实验相比,流水线簇遍历实验更强大,因为它通过集合所有可能的流水线(流水线簇)和自动化实验将工作流从 1 维扩展到 2 维。凭借更大的覆盖范围,在没有人工干预的情况下找到最佳模型,并且由于其在每个组件中的系综设计而更加灵活地处理不可见的数据,*管道簇遍历实验*为数据科学家提供了一种更方便和“全自动”的机器学习方法。**

为了实现 PCTE 过程, OptimalFlow 提供了 autoPipe 模块来实现。更多示例和功能详情可在文档中找到。

下面是我们在 自动管道 模块中设置的属性:

  • 对于 autoPP 模块:给它我们上面设置的自定义参数;设置预测列为“Total_Lap_Num”,选择 model_type 为“regression”(防止哑变量陷阱);
  • 对于拆分规则:设置 20%验证,20%测试,60%训练数据;
  • 对于 autoFS 模块:设置 10 个顶级特性,5 个交叉验证文件夹;
  • 对于 autoCV 模块:使用快速回归器类,5 个交叉验证文件夹。

下面是这个自动化过程的简单描述:

  • 基于我们之前的自定义设置, autoPP 模块将生成总共#256 个数据集组合(基于我们自定义的稀疏度限制设置)。我们的 PCTE 进程将会经历所有这些。它将使用 autoFS 模块自动选择前 10 个功能。并使用调整后的超参数搜索最佳模型,最终在 流水线簇 内找到具有流水线工作流的最佳模型。

你会在自动生成的日志文件中找到 PCTE 进程的所有日志信息,这些日志文件是由 OptimalFlowautoFlow 模块创建的。

****

模块自动生成的日志文件

PCTE 过程几乎涵盖了数据科学家需要涵盖的所有机器学习步骤,并通过其管道工作流信息自动搜索最佳模型,以便于评估和实施。

虽然 PCTE 不会为每个机器学习流水线操作节省时间,但当 OptimalFlow 为时,数据科学家可以转移到其他任务,帮助他们摆脱繁琐的模型实验和调整工作。

这是我所理解的真正的自动化机器学习过程。OptimalFlow 应该自动完成所有这些任务。

流水线簇遍历实验 (PCTE)过程的输出包括应用于准备好的数据集组合的预处理算法的信息(DICT_PREP_INFO)、为每个数据集组合选择的顶部特征(DICT_FEATURE_SELECTION_INFO)、模型评估结果(DICT_MODELS_EVALUATION)、分割数据集组合(DICT_DATA)、模型选择结果排序表(models_summary)。

这对于数据科学家来说是一个有用的功能,因为当他们想要重用以前的输出时,检索以前的机器学习工作流是很痛苦的。

步骤 5:用最佳模型保存管道群

由于当有大量数据集组合作为输入时,PCTE 过程将持续很长时间,我们最好将上一步的输出(管道集群最优模型)保存为 pickles,用于结果解释和可视化步骤。

步骤 6:建模结果解释

下一步,我们将通过导入上一步中保存的 pickles 来查看我们的建模结果。我们可以使用下面的代码找到 PCTE 自动化流程后具有最佳流程的前 3 个模型:

很明显,具有可调超参数的 KNN 算法性能最好。我们可以从 PCTE 的输出中检索整个管道工作流程。

具体来说:

最佳流水线由 KNN 算法组成,该算法使用 256 个数据集组合中的数据集 _214、数据集 _230,具有最佳参数[('权重': '距离'),(' n _ 邻居':' 5 '),('算法':' kd_tree')]。R 平方是 0.971,MAE 是 1.157,MSE 是 5.928,RMSE 是 5.928,延迟分数是 3.0。

所有 256 个数据集的流水线性能评估结果都可以通过 autoViz 模块的动态表函数生成(更多细节和其他已有的可视化示例可以在这里找到),你可以在找到。/temp-plot . html

autoFS 模块选择的前 10 个特性是:

特征预处理细节到 Dataset_214,Dataset_230:具有前 10%和后 10%离群值的 Winsorization 通过平均编码方法对“匹配名称”和“仅日期”特征进行编码;通过 OneHot 编码方法对“组”特征进行编码;预处理步骤中不涉及缩放器。

仅此而已。我们做了第一个 OptimalFlow 自动化机器学习项目。简单容易,对吧?😎

*更多的事情需要考虑:

我们模型的顶部管道具有非常高的 R 平方值,超过 0.9。对于大多数物理过程来说,这个值可能并不令人惊讶,但是,如果我们预测人类的行为,这个值就有点太高了。因此,我们还需要考虑 MSE 等其他指标。

在本教程中,我们将真实项目简化为更适合optimal flow初学者的情况。所以基于这个出发点,这个结果可以接受成为你第一个 OptimalFlow 自动化机器学习的输出。

这里有一些建议,如果您想继续改进我们的示例脚本,以便用更实用的优化模型方法更深入。

  • 高 R 平方值通常意味着过度拟合。因此,放弃更多的功能,以防止这一点;
  • 聚合是汇集数据的好主意,但它也让我们丢失了逐圈和逐时的差异信息;
  • 缩放方法对于防止过度拟合也是必不可少的,我们可以从 custom_pp 中移除“None ”,并在步骤 3 中添加一些其他缩放方法(即,minmax、robust );

总之:

OptimalFlow 是一个简单易用的 API 工具,用简单的代码实现 Omni-ensemble 自动化机器学习,也是证明流水线簇遍历实验 (PCTE)理论的最佳实践库。

它的 6 个模块既可以连接起来实现 PCTE 过程,也可以单独使用来优化传统机器学习工作流的组件。你可以在 文档 中找到它们各自的用例。

"算法专家认为没有免费的午餐."—卡尔伯森

最后但同样重要的是,作为数据科学家,我们应该永远记住:无论什么样的自动化机器学习算法,“没有免费的午餐定理”永远适用。

关于 OptimalFlow 的相关阅读:

使用 OptimalFlow 进行机器学习中的集成特征选择—使用简单代码选择顶级特征的简单方法

集成模型选择&机器学习中使用 OptimalFlow 的评估——用简单代码选择最优模型的简便方法

用 OptimalFlow Web App 建立无代码自动化机器学习模型

关于我:

我是一名医疗保健和制药数据科学家以及大数据分析和人工智能爱好者。我开发了 OptimalFlow 库,帮助数据科学家以一种简单的方式构建最优模型,并用简单的代码实现机器学习工作流的自动化。

作为一名拥有多年分析经验的大数据洞察寻求者、流程优化者和人工智能专家,我使用数据科学中的机器学习和问题解决技能将数据转化为可操作的洞察,同时提供战略和量化产品作为最佳结果的解决方案。

你可以在 LinkedIn 或者 GitHub 上和我联系。

包含真实项目的端到端 OptimalFlow 自动化机器学习教程

原文:https://towardsdatascience.com/end-to-end-optimalflow-automated-machine-learning-tutorial-with-real-projects-formula-e-laps-8b57073a7b50?source=collection_archive---------21-----------------------

公式 E Laps 预测—第 1 部分

在这个端到端的教程中,我们将说明如何使用optimal flow(文档||GitHub),一个 Omni-ensemble 自动化机器学习工具包,来预测车手在 FIA Formula E 比赛中需要完成的圈数。这是一个典型的回归预测问题,影响了车队的赛车和能量策略的表现。

为什么我们使用 OptimalFlow ?你可以读另一个关于它的介绍的故事:一个全方位的自动化机器学习——optimal flow

项目背景:

比赛中剩余的圈数可以确定其策略,即决定积极驾驶并消耗更多电池,或保守驾驶并节省能源。车队总是知道汽车电池的状态。

可用数据:

Formula E 官方网站:【https://results.fiaformula.com】上的公开数据,包括每位车手单圈的历史比赛计时数据和天气数据(风、雨等)

本条工程简化为:

我们将把问题简化为一个目标,来预测一场 Formula E 比赛的总圈数。我们将忽略其他人为干预因素,如撞车的可能性,或安全车对比赛时间的影响,这可能会影响特征的变化。

第一步:获取数据

【https://results.fiaformula.com】获取公共时间和天气数据,并保持它们的层次结构,保存在类似结构的文件夹中。我们将提取他们的文件夹字典作为关于系列赛季(即 2017–2018)、比赛地点(即柏林)、比赛类型(即 FP1)等的特征。

第二步:数据整合

在将数据输入 OptimalFlow 模块之前,需要进行基本的数据工程步骤。有 3 种类型的数据:分析数据、天气数据和分类数据。对于这个简化的问题,我们可以把分析数据看成是人种数据,而忽略分类数据。此外,我们将包括从自由练习,资格赛,超级极,和比赛的分析数据。

下一个挑战是我们发现天气数据和比赛数据是分开的,这将很难找到它们之间的影响关系。因此,我们需要通过创建“关键”列/特征来建立连接。

为了创建连接键,我们应该快速浏览原始数据,但是显然,这里没有比赛日期信息,只有逐圈计时数据。但是我们知道天气数据和分析数据都保存在同一个文件夹目录中,这意味着我们可以使用数据的文件目录信息作为“关键”来合并天气和分析/比赛数据。

**

因此,将所有天气数据合并到一个数据集,并按年份追加比赛数据。同时,saved 单独提取所有数据集的文件位置信息(命名为‘file _ loc’),以便进一步与天气数据合并。

经过前面的编码,我们将收到每年的比赛数据集,和天气综合数据集。

接下来,我们将在所有年度比赛数据集中找到共同的特征,并将年度比赛数据集合并为一个完整的数据集,将其保存为“contest_data.csv”。

然后,我们需要使用数据集的文件目录信息来创建“key”列,以连接综合天气数据和综合比赛数据。(请原谅我在以下代码中拼错了“天气”这个词……)

从竞赛数据的文件目录信息中提取属性

从天气数据的文件目录信息中提取属性

因此,我们将为进一步的合并步骤获得元数据数据集。您将拥有“match_key”作为我之前提到的“key”列。

步骤 3:探索性数据分析(EDA)

在统计学中,探索性数据分析(EDA)是一种分析数据集以总结其主要特征的方法,通常采用可视化方法。可以使用或不使用统计模型,但 EDA 主要是为了查看数据可以告诉我们什么,而不仅仅是正式的建模或假设测试任务。

我更喜欢使用 pandas-profiling 库来加速这一步。但这一步只是让我们对集成数据集、特征关系有一个总体感觉,并了解哪些特征可能与我们的最终预测目标相关。所以我们不需要在这一步花太多时间,还有 OptimalFlow 的 autoFS(自动特征选择模块),以及 autoPP (自动特征预处理模块)会帮助我们覆盖它们,以防我们在 EDA 步骤中遗漏一些见解。

步骤 4:数据聚合

我们需要预测一场比赛的总圈数,所以一圈一圈的比赛数据和一次又一次的天气信息作为依赖因素并不清晰和强大。

所以更好的想法应该是数据聚合。我们不知道哪种聚合方法会极大地影响预测结果,所以我们可以尝试常见的计算方法,如平均值、中值、偏斜度、标准差等。,并将它们应用于综合天气数据和比赛数据。下面是天气数据聚合的代码示例:

天气数据聚合

然后我们将比赛数据与天气数据合并。合并后的数据集中共有 74 个要素。每一行记录都涵盖了特定 Formula E 事件/比赛中的一名车手,具有聚合的比赛和天气特征。这个输出或者我们通常所说的“预测”在我们的问题中是“【Total _ Lap _ Num】”列。

总而言之:

数据准备对于机器学习至关重要。作为进一步建模步骤的基础,它通常需要数据工程师和数据科学家的共同努力。领域经验和对数据源的熟悉是影响如何清理和集成原始数据的策略的关键因素。

在本教程的 第二部分 中,我们将使用 OptimalFlow 库来实现 Omni-ensemble 自动化机器学习。

关于 OptimalFlow 的相关阅读:

使用 OptimalFlow 进行机器学习中的集成特征选择—使用简单代码选择顶级特征的简单方法

集成模型选择&机器学习中的评估使用 OptimalFlow —用简单代码选择最优模型的简便方法

用 OptimalFlow Web App 建立无代码自动机器学习模型

关于我:

我是一名医疗保健和制药数据科学家以及大数据分析和人工智能爱好者。我开发了 OptimalFlow 库,帮助数据科学家以简单的方式构建最优模型,用简单的代码实现机器学习工作流程的自动化。

作为一名拥有多年分析经验的大数据洞察寻求者、流程优化者和人工智能专家,我使用数据科学中的机器学习和问题解决技能将数据转化为可操作的洞察,同时提供战略和量化产品作为最佳结果的解决方案。

你可以在我的 LinkedIn 或 GitHub 上与我联系。

为数据科学家设置多类影像分类的端到端管道

原文:https://towardsdatascience.com/end-to-end-pipeline-for-setting-up-multiclass-image-classification-for-data-scientists-2e051081d41c?source=collection_archive---------15-----------------------

图片由来自 Pixabay 的 Louise Dav 拍摄

使用 PyTorch 和迁移学习

你有没有想过脸书是如何处理一些用户分享的侮辱性和不恰当的图片的?或者脸书的标签功能是如何工作的?或者说 Google Lens 是如何通过图像识别产品的?

以上都是图像分类在不同设置下的例子。多类图像分类是计算机视觉中的一项常见任务,我们将图像分为三类或更多类。

以前我都是用 Keras 做计算机视觉项目。然而,最近当从事多类图像分类的机会出现时,我决定使用 PyTorch。我已经把所有的 NLP 任务从 Keras 转移到 PyTorch,那么为什么不把 vision 也转移呢?

PyTorch 功能强大,我也喜欢它更 pythonic 化的结构。

在这篇文章中,我们将使用 Pytorch 为图像多类分类创建一个端到端的管道。 这将包括训练模型,将模型的结果以一种可以显示给业务伙伴的形式,以及帮助轻松部署模型的功能。作为一个附加的特性,我们也将使用 Pytorch 来增加测试时间。

但是在我们学习如何进行图像分类之前,我们先来看看迁移学习,这是处理这类问题最常见的方法。

什么是迁移学习?

迁移学习是将知识从一项任务转移到另一项任务的过程。从建模的角度来看,这意味着使用在一个数据集上训练的模型,并对其进行微调以用于另一个数据集。但是为什么会起作用呢?

先说一些背景。每年视觉识别社区都会为一个非常特殊的挑战而聚集在一起:Imagenet 挑战。这项挑战的任务是将 1,000,000 幅图像分为 1,000 个类别。

这一挑战已经导致研究人员训练大型卷积深度学习模型。结果包括像 Resnet50 和 Inception 这样的优秀模型。

但是,训练一个神经模型意味着什么呢?本质上,这意味着研究人员在一百万张图像上训练模型后,已经学习了神经网络的权重。

那么,如果我们能得到这些重量呢?然后,我们可以使用它们,并将它们加载到我们自己的神经网络模型中,在测试数据集上进行预测,对吗?实际上,我们可以走得更远。我们可以在这些研究人员已经准备好的神经网络之上添加一个额外的层来对我们自己的数据集进行分类。

虽然这些复杂模型的确切工作方式仍然是一个谜,但我们知道较低的卷积层可以捕捉边缘和梯度等低级图像特征。相比之下,更高的卷积层捕捉越来越复杂的细节,如身体部位、面部和其他组成特征。

来源:可视化和理解卷积网络。你可以看到前几层是如何捕捉基本形状的,在后面的层中形状变得越来越复杂。

在上面来自 ZFNet(Alex net 的变体)的示例中,ZFNet 是在 Imagenet 任务上获得成功的第一批卷积神经网络之一,您可以看到较低层是如何捕捉线条和边缘的,而后面的层是如何捕捉更复杂的特征的。通常假设最终的全连接层捕获与解决相应任务相关的信息,例如,ZFNet 的全连接层指示哪些特征与将图像分类到 1,000 个对象类别之一相关。

对于新的视觉任务,我们可以简单地使用预先在 ImageNet 上训练的最新 CNN 的现成特征,并在这些提取的特征上训练新的模型。

这个想法背后的直觉是,一个经过训练可以识别动物的模型也可以用来识别猫和狗。在我们的例子中,

一个在 1000 个不同类别上训练过的模型已经看到了很多真实世界的信息,我们可以使用这些信息来创建我们自己的定制分类器。

理论和直觉就是这样。我们如何让它真正发挥作用?让我们看一些代码。你可以在Github上找到这篇文章的完整代码。

数据探索

我们将从 Kaggle 的船数据集开始,以理解多类图像分类问题。该数据集包含大约 1,500 张不同类型的船只照片:浮标、游轮、渡船、货船、平底船、充气船、皮艇、纸船和帆船。我们的目标是创建一个模型,该模型查看船只图像并将其分类到正确的类别中。

以下是数据集中的图像示例:

以下是类别计数:

由于类别*“货运船”
“充气船”*“船”没有太多的图像;我们将在训练模型时删除这些类别。

创建所需的目录结构

在我们可以训练我们的深度学习模型之前,我们需要为我们的图像创建所需的目录结构。现在,我们的数据目录结构看起来像这样:

imagessailboatkayak..

我们需要我们的图像被包含在 3 个文件夹trainvaltest。然后,我们将对train数据集中的图像进行训练,对val数据集中的图像进行验证,最后对test数据集中的图像进行测试。

datatrainsailboatkayak..valsailboatkayak..testsailboatkayak..

您可能有不同格式的数据,但是我发现除了通常的库之外,glob.globos.system函数非常有用。在这里你可以找到完整的数据准备代码。现在让我们快速浏览一下我在准备数据时发现有用的一些不常用的库。

什么是 glob.glob?

简单地说,glob 允许您使用正则表达式获取目录中文件或文件夹的名称。例如,您可以这样做:

from glob import glob
categories = glob(“images/*”)
print(categories)
------------------------------------------------------------------
['images/kayak', 'images/boats', 'images/gondola', 'images/sailboat', 'images/inflatable boat', 'images/paper boat', 'images/buoy', 'images/cruise ship', 'images/freight boat', 'images/ferry boat']

什么是 os.system?

os.systemos库中的一个函数,它允许你在 python 中运行任何命令行函数。我通常用它来运行 Linux 函数,但它也可以用来运行 python 中的 R 脚本,如这里的所示。例如,在从 pandas 数据框中获取信息后,我在准备数据时使用它将文件从一个目录复制到另一个目录。我也使用 f 字符串格式。

import osfor i,row in fulldf.iterrows():# Boat categorycat = row['category']# section is train,val or testsection = row['type']# input filepath to copyipath = row['filepath']# output filepath to pasteopath = ipath.replace(f"images/",f"data/{section}/")# running the cp commandos.system(f"cp '{ipath}' '{opath}'")

现在,既然我们已经在所需的文件夹结构中有了数据,我们可以继续进行更令人兴奋的部分。

数据预处理

转换:

1。Imagenet 预处理

为了将我们的图像用于在 Imagenet 数据集上训练的网络,我们需要以与 Imagenet 网络相同的方式预处理我们的图像。为此,我们需要将图像缩放到 224×224,并按照 Imagenet 标准对其进行标准化。我们可以利用火炬视觉transforms图书馆做到这一点。这里我们取 224×224 的CenterCrop,按照 Imagenet 标准进行归一化。下面定义的操作按顺序发生。您可以在这里找到由 PyTorch 提供的所有转换的列表。

transforms.Compose([transforms.CenterCrop(size=224),  transforms.ToTensor(),transforms.Normalize([0.485, 0.456, 0.406],[0.229, 0.224, 0.225])  ])

2。数据扩充

我们可以为数据扩充做更多的预处理。神经网络在处理大量数据时效果更好。数据扩充是一种策略,我们在训练时使用它来增加我们拥有的数据量。

例如,我们可以水平翻转一艘船的图像,它仍然是一艘船。或者我们可以随机裁剪图像或添加颜色抖动。这是我用过的图像转换字典,它适用于 Imagenet 预处理和增强。这本字典包含了我们在这篇伟大的文章中使用的训练、测试和验证数据的各种转换。正如您所料,我们没有对测试数据和验证数据应用水平翻转或其他数据增强转换,因为我们不想在增强的图像上获得预测。

# Image transformations
image_transforms = {# Train uses data augmentation'train':transforms.Compose([transforms.RandomResizedCrop(size=256, scale=(0.8, 1.0)),transforms.RandomRotation(degrees=15),transforms.ColorJitter(),transforms.RandomHorizontalFlip(),transforms.CenterCrop(size=224),  # Image net standardstransforms.ToTensor(),transforms.Normalize([0.485, 0.456, 0.406],[0.229, 0.224, 0.225])  # Imagenet standards]),# Validation does not use augmentation'valid':transforms.Compose([transforms.Resize(size=256),transforms.CenterCrop(size=224),transforms.ToTensor(),transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])]),# Test does not use augmentation'test':transforms.Compose([transforms.Resize(size=256),transforms.CenterCrop(size=224),transforms.ToTensor(),transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])]),
}

以下是应用于训练数据集中图像的训练变换示例。我们不仅从一幅图像中得到许多不同的图像,而且它还帮助我们的网络变得对物体方向不变。

ex_img = Image.open('/home/rahul/projects/compvisblog/data/train/cruise ship/cruise-ship-oasis-of-the-seas-boat-water-482183.jpg')t = image_transforms['train']
plt.figure(figsize=(24, 24))for i in range(16):ax = plt.subplot(4, 4, i + 1)_ = imshow_tensor(t(ex_img), ax=ax)plt.tight_layout()

数据加载器

下一步是向 PyTorch 提供培训、验证和测试数据集的位置。我们可以通过使用 PyTorch datasetsDataLoader类来做到这一点。如果我们将数据放在所需的目录结构中,这部分代码将基本保持不变。

# Datasets from folderstraindir = "data/train"
validdir = "data/val"
testdir = "data/test"data = {'train':datasets.ImageFolder(root=traindir, transform=image_transforms['train']),'valid':datasets.ImageFolder(root=validdir, transform=image_transforms['valid']),'test':datasets.ImageFolder(root=testdir, transform=image_transforms['test'])
}# Dataloader iterators, make sure to shuffle
dataloaders = {'train': DataLoader(data['train'], batch_size=batch_size, shuffle=True,num_workers=10),'val': DataLoader(data['valid'], batch_size=batch_size, shuffle=True,num_workers=10),'test': DataLoader(data['test'], batch_size=batch_size, shuffle=True,num_workers=10)
}

这些数据加载器帮助我们遍历数据集。例如,我们将在模型培训中使用下面的数据加载器。数据变量将包含形式为(batch_size, color_channels, height, width)的数据,而目标的形状为(batch_size),并保存标签信息。

train_loader = dataloaders['train']
for ii, (data, target) in enumerate(train_loader):

建模

1.使用预先训练的模型创建模型

现在,这些预先训练好的模型可以在torchvision图书馆使用:

  • AlexNet
  • VGG
  • ResNet
  • 挤压网
  • DenseNet
  • 开始 v3
  • 谷歌网
  • 沙狐球网 v2
  • 移动互联网 v2
  • ResNeXt
  • 广 ResNet
  • 多边核安全网

在这里,我将在我们的数据集上使用 resnet50,但是您也可以根据自己的选择有效地使用任何其他模型。

from torchvision import models
model = models.resnet50(pretrained=True)

我们从冻结模型重量开始,因为我们不想改变 renet50 模型的重量。

# Freeze model weights
for param in model.parameters():param.requires_grad = False

我们需要做的下一件事是用我们的自定义分类器替换模型中的线性分类层。我发现,要做到这一点,最好先看看模型结构,以确定最终的线性层是什么。我们可以简单地通过打印模型对象来做到这一点:

print(model)
------------------------------------------------------------------
ResNet((conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)....(conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)))  
(avgpool): AdaptiveAvgPool2d(output_size=(1, 1))**(fc): Linear(in_features=2048, out_features=1000, bias=True)**
)

在这里,我们发现从卷积层获取输入的最后一个线性层被命名为fc

我们现在可以使用我们定制的神经网络简单地替换fc层。该神经网络将来自前一层的输入输入到fc,并给出形状(batch_size x n_classes)的 log softmax 输出。

n_inputs = model.fc.in_features
model.fc = nn.Sequential(nn.Linear(n_inputs, 256), nn.ReLU(), nn.Dropout(0.4),nn.Linear(256, n_classes),                   nn.LogSoftmax(dim=1))

请注意,现在添加的新层在默认情况下是完全可训练的。

2.在 GPU 上加载模型

我们可以使用 PyTorch 的 DataParallel 来使用单个或多个 GPU(如果我们有)。这里是我们可以用来检测 GPU 以及在 GPU 上加载模型的 GPU 数量。现在,我正在双英伟达泰坦 RTX 图形处理器上训练我的模型。

# Whether to train on a gpu
train_on_gpu = cuda.is_available()
print(f'Train on gpu: {train_on_gpu}')# Number of gpus
if train_on_gpu:gpu_count = cuda.device_count()print(f'{gpu_count} gpus detected.')if gpu_count > 1:multi_gpu = Trueelse:multi_gpu = Falseif train_on_gpu:model = model.to('cuda')if multi_gpu:model = nn.DataParallel(model)

3.定义标准和优化器

当你训练任何模型时,最重要的事情之一是损失函数和优化器的选择。这里我们想使用分类交叉熵,因为我们有一个多类分类问题和 Adam 优化器,这是最常用的优化器。但是,由于我们对模型的输出应用 LogSoftmax 运算,因此我们将使用 NLL 损耗。

from torch import optimcriteration = nn.NLLLoss()
optimizer = optim.Adam(model.parameters())

4.训练模型

下面给出了用于训练模型的完整代码。它本身看起来可能很大,但本质上我们所做的如下:

  • 开始运行纪元。在每个时代-
  • 使用model.train()将模型模式设置为训练。
  • 使用列车数据加载器循环数据。
  • 使用data, target = data.cuda(), target.cuda()命令将你的数据加载到 GPU
  • 使用optimizer.zero_grad()将优化器中的现有梯度设置为零
  • 使用output = model(data)向前运行批次
  • 使用loss = criterion(output, target)计算损失
  • 使用loss.backward()通过网络反向传播损耗
  • 使用optimizer.step()采取优化步骤改变整个网络的权重
  • 训练循环中的所有其他步骤只是为了维护历史和计算准确性。
  • 使用model.eval()将模型模式设置为评估。
  • 使用valid_loader获得验证数据的预测,并计算valid_lossvalid_acc
  • 打印每个print_every时期的验证损失和验证准确度结果。
  • 保存基于验证损失的最佳模型。
  • **提前停止:**如果交叉验证损失在max_epochs_stop内没有改善,则停止训练并加载验证损失最小的最佳可用模型。

下面是运行上述代码的输出。只显示最近几个时代。在第一个纪元中,验证精度从大约 55%开始,我们以大约 90%的验证精度结束。

下面是显示损失和准确性指标的训练曲线:

训练曲线

推理和模型结果

我们希望我们的结果以不同的方式使用我们的模型。首先,我们需要测试精度和混淆矩阵。创建这些结果的所有代码都在代码笔记本中。

1.试验结果

测试模型的总体精度为:

Overall Accuracy: 88.65 %

这是测试数据集结果的混淆矩阵。

我们也可以看看类别的准确性。我还添加了列车计数,以便从新的角度查看结果。

2.单个图像的可视化预测

出于部署目的,能够获得对单个图像的预测是有帮助的。你可以从笔记本上找到密码。

3.可视化类别的预测

我们还可以看到用于调试和演示的分类结果。

4.测试时间增加后的测试结果

我们还可以增加测试时间来提高我们的测试精度。这里我使用了一个新的测试数据加载器和转换:

# Image transformations
tta_random_image_transforms = transforms.Compose([transforms.RandomResizedCrop(size=256, scale=(0.8, 1.0)),transforms.RandomRotation(degrees=15),transforms.ColorJitter(),transforms.RandomHorizontalFlip(),transforms.CenterCrop(size=224),  # Image net standardstransforms.ToTensor(),transforms.Normalize([0.485, 0.456, 0.406],[0.229, 0.224, 0.225])  # Imagenet standards])# Datasets from folders
ttadata = {'test':datasets.ImageFolder(root=testdir, transform=tta_random_image_transforms)
}# Dataloader iterators
ttadataloader = {'test': DataLoader(ttadata['test'], batch_size=512, shuffle=False,num_workers=10)
}

然后,我们可以使用以下函数获得测试集上的预测:

在上面的函数中,在得到预测之前,我对每张图片应用了 5 次tta_random_image_transforms。最终预测是所有五次预测的平均值。当我们在整个测试数据集上使用 TTA 时,我们注意到准确率提高了大约 1%

TTA Accuracy: 89.71%

此外,以下是 TTA 的结果与正常结果的分类比较:

在这个小数据集中,TTA 似乎没有增加多少价值,但我注意到它增加了大数据集的价值。

结论

在这篇文章中,我谈到了使用 PyTorch 进行多类图像分类项目的端到端管道。我们致力于创建一些现成的代码来使用迁移学习训练模型,可视化结果,使用测试时间增加,并获得对单个图像的预测,以便我们可以在需要时使用任何工具部署我们的模型,如 Streamlit 。

你可以在 Github 上找到这篇文章的完整代码。

如果你想了解更多关于图像分类和卷积神经网络的知识,看看来自吴恩达的深度学习专业。此外,要了解 PyTorch 的更多信息并从基础开始,您可以看看 IBM 提供的深度神经网络与 PyTorch 课程。

谢谢你的阅读。将来我也会写更多初学者友好的帖子。在 媒体 关注我,或者订阅我的 博客 了解他们。一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter @mlwhiz 联系到我。

此外,一个小小的免责声明——这篇文章中可能会有一些相关资源的附属链接,因为分享知识从来都不是一个坏主意。

本帖首发 此处

使用三种机器学习模型基于勒布朗数据的端到端游戏预测方案

原文:https://towardsdatascience.com/end-to-end-project-of-game-prediction-based-on-lebrons-stats-using-three-machine-learning-models-38c20f49af5f?source=collection_archive---------23-----------------------

机器学习

使用三种不同的分类器(包括逻辑回归、随机森林分类器和深度学习分类器)对二元分类问题进行综合指导。

照片由 JC Gellidon 在 Unsplash

我是 机器学习篮球 的超级粉丝,所以我喜欢把这两个结合起来生成一些迷你项目。在这篇文章中,我想和你分享其中的一个项目。

不管你是不是篮球迷,你都必须知道勒布朗詹姆斯。作为核心球员,他的表现对比赛结果至关重要。所以,我在这个项目中试图回答的问题是 “我们能根据勒布朗的比赛数据预测比赛结果吗?”

我把它框定为一个二元分类问题,以团队的“赢”或“输”作为输出标签。特征是勒布朗·詹姆斯每场比赛的基本统计。

我在项目中实现了三个分类器,随机森林分类器深度学习分类器* ,通过使用机器学习中流行的两个 Python 库,sk learn,以及keras。*

我正在一步一步地完成这个项目,希望对你有所帮助。

准备数据集

在 Unsplash 上创意交流的照片

这里列出了代码中使用的库。

*import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.model_selection import StratifiedKFold
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from keras.layers import Dense, Dropout
from keras.models import Model, Sequential
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import GridSearchCV*

我手动整理了勒布朗从赛季2003–2004到赛季2019–2020*(直到 3 月 NBA 停赛)的比赛基本统计。总共有 1258 场比赛。进口代码如下:*

*df = pd.read_csv("lebron_2003_2020_career_gamelog.csv",index_col=0)
df.head()*

端到端游戏预测(由虞风

从上图可以看到基础统计游戏结果*(“赢”和“Winby”)。*

然后,我要确保数据类型是“float32 ”,这样我就可以直接将它们提供给 keras 中的神经元网络模型。数据类型转换代码如下:

*df = df.astype('float32')*

接下来,我需要使用如下代码指定数据集中的特征空间和标签:

*y = df['Win']
X = df.drop(columns=['Win','Winby'])*

*列“ ”是记录的游戏结果,其中 1 表示 ***赢*** ,0 表示 ***输*** 。而“ ***Winby*** ”一栏则是该组件的游戏分数差,其中正数表示 ***赢*** ,负数表示 ***输*** 。因此,有必要将它们从特征空间中移除。*

接下来,数据被分成 训练测试 集合,其中测试集合在模型评估步骤之前永远不会被触及。代码如下:

*X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,stratify=y, random_state=42)*

你可能会注意到,我在这里使用了一个 分层分割 ,避免了游戏结果在训练数据中偏向一类的情况。“分层=y”表示基于我们的输出标签 y 完成“分层分割”

到现在为止,牛排已经做好了,我们需要开始预热烤箱。

模特培训

Ashim D'Silva 在 Unsplash 上拍摄的照片

正如我提到的,将使用三个模型,逻辑回归随机森林分类器,以及深度学习分类器*。为了使它们都符合相同的 Scikit-Learn 工作流,我们需要首先以如下的 Scikit-Learn 风格定义深度学习模型:*

*def my_DL(epochs=6,batchsize=512):model = Sequential()model.add(Dense(32,activation='relu'))model.add(Dense(16,activation='relu'))model.add(Dense(1,activation='sigmoid'))model.compile(loss='binary_crossentropy',optimizer='rmsprop', metrics=['accuracy']) return model*

具体来说,这个神经网络有两个隐层,分别是 32 个和 16 个节点。网络的损失函数、优化器和度量分别固定为'二元交叉熵'、 rmsprop 和'精度'。

该编译模型有两个可调参数, 历元 为历元数, 批次大小 为每批样本数。这两个参数都有默认值,格式类似于 sklearn 中的分类器。

不能从数据中训练出来但需要在训练过程前赋值的模型参数称为 超参数 。这些超参数总是与模型的复杂度相关,需要正确选择以避免欠拟合过拟合问题。

要选择最佳的超参数集,我们可以用两种方法。首先,我们可以进一步将训练数据集分成两部分,即 训练验证 数据集。然后,我们需要在验证集合上评估来自训练数据集的训练模型。最佳超参数集是在验证集上具有最佳性能的超参数集。

然而,当样本量很小时,只有一个数据分割会有偏差。所以, 交叉验证 是另一种训练超参数的方式,更受欢迎。因此,我在这个项目中使用交叉验证。

我在下面列出了超参数调谐的全部功能,并将详细介绍。

*def train_hyper_tune(X,y):# create the pre-processing componentmy_scaler = StandardScaler()my_imputer = SimpleImputer(strategy="median")# define classifiers## Classifier 1: Logistic Regressionclf_LR = LogisticRegression(random_state=0,penalty='elasticnet',solver='saga')## Classifier 2: Random Forest Classifierclf_RF = RandomForestClassifier(random_state=0)## Classifier 3: Deep Learning Binary Classifierclf_DL = KerasClassifier(build_fn=my_DL)# define pipeline for three classifiers## clf_LRpipe1 = Pipeline([('imputer', my_imputer), ('scaler', my_scaler), ('lr_model',clf_LR)])## clf_RFpipe2 = Pipeline([('imputer', my_imputer), ('scaler', my_scaler), ('rf_model',clf_RF)])## clf_DLpipe3 = Pipeline([('imputer', my_imputer), ('scaler', my_scaler), ('dl_model',clf_DL)])# create hyperparameter space of the three models## clf_LRparam_grid1 = {'lr_model__C' : [1e-1,1,10],'lr_model__l1_ratio' : [0,0.5,1]}## clf_RFparam_grid2 = {'rf_model__n_estimators' : [50,100],'rf_model__max_features' : [0.8,"auto"],'rf_model__max_depth' : [4,5]}## clf_DLparam_grid3 = {'dl_model__epochs' : [6,12,18,24],'dl_model__batchsize' : [256,512]}# set GridSearch via 5-fold cross-validation## clf_LRgrid1 = GridSearchCV(pipe1, cv=5, param_grid=param_grid1)## clf_RFgrid2 = GridSearchCV(pipe2, cv=5, param_grid=param_grid2)## clf_DLgrid3 = GridSearchCV(pipe3, cv=5, param_grid=param_grid3)# run the hyperparameter tunning processgrid1.fit(X,y)grid2.fit(X,y)grid3.fit(X,y)# return results of the tunning processreturn grid1,grid2,grid3,pipe1,pipe2,pipe3*

如代码所示,函数内部主要有六个步骤:

第一步。创建预处理函数。

 *# create the pre-processing componentmy_scaler = StandardScaler()my_imputer = SimpleImputer(strategy="median")*

我使用特征的中值来估算缺失值,使用标准缩放器来标准化数据。这一步对于所有三种型号都是一样的。

第二步。定义所有三个分类器。

 *# define classifiers## Classifier 1: Logistic Regressionclf_LR = LogisticRegression(random_state=0,penalty='elasticnet',solver='saga')## Classifier 2: Random Forest Classifierclf_RF = RandomForestClassifier(random_state=0)## Classifier 3: Deep Learning Binary Classifierclf_DL = KerasClassifier(build_fn=my_DL)*

首先,逻辑回归分类器通常被用作“Hello world!”机器学习书籍中的模型。这里,它与惩罚函数一起使用,以避免过度拟合。带有这个罚项的模型称为“弹性网”,它是正则化中 l1 和 l2 范数的组合。

对于那些对我们为什么选择弹性网作为惩罚条款感兴趣的人,请阅读我下面的另一篇文章:

* [## 线性回归中的一个实用建议

从弹性网开始,记得调好定义 l1 范数之比的超参数。

towardsdatascience.com](/a-practical-suggestion-in-linear-regression-cb639fd5ccdb)

第二,随机森林分类器以更自由的方式定义,而不固定任何超参数。它的三个超参数将在下面的步骤中进行调整,我将在后面详细介绍。

第三,这里使用的深度学习分类器是基于前面提到的 Scikit-Learn 风格模型, my_DL 。谢天谢地,Keras 为 Scikit-Learn API 提供了精彩的包装器。我通过将函数 my_DL 传递给函数 KerasClassifier()来直接调用它。

第三步。为每个模型定义一个管道,将预处理和建模结合在一起。

 # define pipeline for three classifiers## clf_LRpipe1 = Pipeline([('imputer', my_imputer), ('scaler', my_scaler), ('lr_model',clf_LR)])## clf_RFpipe2 = Pipeline([('imputer', my_imputer), ('scaler', my_scaler), ('rf_model',clf_RF)])## clf_DLpipe3 = Pipeline([('imputer', my_imputer), ('scaler', my_scaler), ('dl_model',clf_DL)])

对于这三个模型中的每一个,我都用 sklearn 中的 流水线函数将预处理和分类器组合成一个流水线。对于处理的每一步,都应该给出一个名称。例如,我将我的逻辑回归模型命名为“ lr_model ”,并在管道中通过 clf_LR 调用它。

将所有内容合并到一个管道中的目的是确保在交叉验证中对训练数据进行完全相同的处理。这对于避免数据泄露至关重要。

步骤四。为每个模型创建超参数空间。

 # create hyperparameter space of the three models## clf_LRparam_grid1 = {'lr_model__C' : [1e-1,1,10],'lr_model__l1_ratio' : [0,0.5,1]}## clf_RFparam_grid2 = {'rf_model__n_estimators' : [50,100],'rf_model__max_features' : [0.8,"auto"],'rf_model__max_depth' : [4,5]}## clf_DLparam_grid3 = {'dl_model__epochs' : [6,12,18,24],'dl_model__batchsize' : [256,512]}

这部分比较灵活,因为这三个模型中有大量的参数。选择与模型复杂性密切相关的参数很重要。例如,随机森林模型中树的最大深度是一个必须调整的超参数。有兴趣的可以参考下面这个帖子。

[## 我以前从未注意到的过度拟合的一个潜在原因

当训练数据中的性能比测试数据中的性能好得多时,就会发生过度拟合。默认…

towardsdatascience.com](/one-potential-cause-of-overfitting-that-i-never-noticed-before-a57904c8c89d)

注意,管道中的步骤名称需要在超参数空间中指定。比如深度学习模型中的历元数命名为***“dl _ model _ _ epochs”,其中“dl _ model”是我的管道中深度学习模型的名称“epochs”***是可以传递给我的深度学习模型的参数名称。它们在超参数空间中以字符串格式由“__”连接。

第五步。通过交叉验证设置跨超参数空间的网格搜索功能。

 # set GridSearch via 5-fold cross-validation## clf_LRgrid1 = GridSearchCV(pipe1, cv=5, param_grid=param_grid1)## clf_RFgrid2 = GridSearchCV(pipe2, cv=5, param_grid=param_grid2)## clf_DLgrid3 = GridSearchCV(pipe3, cv=5, param_grid=param_grid3)

随机搜索相比,网格搜索的计算成本更高,因为它跨越了整个超参数空间。在这个项目中,我使用网格搜索,因为超参数空间相对较小。

对于每个网格搜索,我使用 5 重交叉验证 来评估超参数组合的平均性能。

第六步。运行调整过程。

 # run the hyperparameter tunning processgrid1.fit(X,y)grid2.fit(X,y)grid3.fit(X,y)

这一步非常简单,在三个定义的管道上执行网格搜索。

最后,我们只需要运行如下函数:

my_grid1,my_grid2,my_grid3,my_pipe1,my_pipe2,my_pipe3 = train_hyper_tune(X_train, y_train)

我们可以通过拉出网格搜索结果中的最佳分数来检查训练性能。

端到端游戏预测(由虞风

看起来随机森林在训练数据集上具有最好的性能。但是这三个模型彼此之间非常相似。

测试数据的模型评估

韦德·奥斯汀·埃利斯在 Unsplash 上的照片

在前面的步骤中选择了超参数之后,我使用它们在整个训练数据上重新训练模型。代码如下所示:

def train_on_entire(X,y,pipe,grid_res):# fit pipelinepipe.set_params(**grid_res.best_params_).fit(X, y)# return the newly trained pipelinereturn pipe

这里,**** * grid _ RES . best _ params _***用于将网格搜索中的最佳参数传递给管道,以进行超参数设置。

在用 X 和 y 重新调整后,返回的管道 管道 是在整个训练数据集上完全训练的模型。

然后,我们需要在测试数据集上评估这个经过训练的模型。

train_on_entire(X_train,y_train,my_pipe1,my_grid1).score(X_test,y_test)
train_on_entire(X_train,y_train,my_pipe2,my_grid2).score(X_test,y_test)
train_on_entire(X_train,y_train,my_pipe3,my_grid3).score(X_test,y_test)

逻辑回归、随机森林分类器和深度学习分类器在准确度方面的性能分别为 0.8690.9010.877

从结果中我们可以得出几个结论。 首先, 随机森林分类器在这次预测中似乎表现优于其他两种方法。 第二, 深度学习方法在处理这样的表格化数据集时并没有表现出优势。 第三, 这三种方法都说明勒布朗的比赛数据对比赛结果有预测能力,可见他在球队中的统治地位。

就是这样,端到端的机器学习项目。我希望你从中学到了一些东西。

克里斯汀娜·戈塔迪在 Unsplash 上的照片

参考资料:

  1. 【https://keras.io/scikit-learn-api/
  2. https://sci kit-learn . org/stable/modules/generated/sk learn . model _ selection。stratifiedkfold . html # sk learn . model _ selection。分层折叠
  3. https://sci kit-learn . org/stable/modules/generated/sk learn . pipeline . pipeline . html
  4. https://sci kit-learn . org/stable/modules/generated/sk learn . linear _ model。LogisticRegression.html
  5. https://sci kit-learn . org/stable/modules/generated/sk learn . ensemble . randomforestclassifier . html*

端到端 AWS 定量分析:使用 AWS 和 AWSCLI 自动运行脚本

原文:https://towardsdatascience.com/end-to-end-quantitative-trading-automating-ml-using-awscli-83035b4f6d03?source=collection_archive---------40-----------------------

凯文·Ku 从派克斯拍摄的照片

建设 AWS 管道

使用 AWSCLI 旋转、运行和拆除 AWS 服务器

在之前的一篇文章中,我们探讨了如何使用 Python 从在线资源(在我们的例子中,是 Yahoo!金融)。
我们开发了两个 Python 脚本;一个为我们抓取数据,一个使用 sklearn 的决策树分类器处理数据。然后,我们将它们上传到 AWS 上的一个 S3 存储桶中,以便安全保管,也便于从其他 AWS 服务中访问。
在本帖中,我们将探讨如何建立一个工作流,为我们创建一个处理服务器,在该服务器上训练我们的数据模型,然后在完成后移除该服务器。

在亚马逊网络服务(AWS)上运行一组模型

AWS 的定价模式是“按使用付费”,这意味着我们可以创建一个服务器,在其上进行一些数据处理,然后拆除它,我们将只为服务器运行的时间付费。此外,我们将使用一个名为 AWSCLI(AWS Client)的客户端库来启动服务器(创建服务器的时髦术语)和关闭它。我从 Brent Lemieux 的一篇帖子中开始了解我需要什么来启动服务器,我强烈建议你去看看那篇帖子。

配置我们的客户端应用程序

首先,我们将安装和配置 AWSCLI。我将使用 AWSCLI v2。一旦安装,我们可以测试它的工作

aws2 --version
>>> aws-cli/2.0.0dev2 Python/3.7.5 Windows/10 botocore/2.0.0dev1

然后我们配置它。在配置 AWSCLI 时,本页可能对默认区域选择有用。

我们还应该通过运行

aws2 emr create-default-roles

创建引导文件

配置完成后,我们可以使用 AWSCLI 并启动我们的服务器。阅读 Brent Lemieux 的文章,他描述了如何创建一个引导文件来为我们初始化服务器。你会注意到我们需要在服务器上安装像 pandas 和 matplotlib 这样的包,因为它只附带了很少的 python 包。

这将是我们的引导文件:

自举 _ 文件. sh

  • 第一行设置python命令指向 python 3(目前是 3.6)而不是默认的 2.7(为什么默认还是 2.7?贝佐斯,这已经过去 6 年了。这样,我们漂亮的脚本将由 python 3.x 运行
  • 第二个命令使用 python 来安装我们需要的库。在这里,您可以随意添加任何其他对您有用的库。
  • 第三个命令将我们的workflow-scripts bucket 的内容复制到集群中。你必须用你的桶名替换 **workflow-scripts**
  • 第四行运行将为我们获取数据的脚本(您可以在这里获取),并将数据存储在适当的 S3 桶中。你必须用你的桶名替换 **data-files**

这个引导脚本将是我们的服务器建立后运行的第一个项目。

配置对 S3 的读/写权限

我们现在有了设置脚本和基本的数据处理脚本。我们差不多准备好运行我们的代码了。我们需要确保我们的脚本可以读取和写入 S3 桶。

我们将向默认角色添加一个策略来允许这一点。
这是什么意思?嗯,当我们创建一个 EMR 集群(一组为我们执行处理的计算机)时,我们给该集群分配一个角色,这意味着我们给它一些权限,让它在集群中安装库。这就像是我们的集群能够做的动作的集合。希望我们按照指示创建了默认角色**。**但是,这些角色不包括与私有的 S3 存储桶进行交互的权限。有两种方法可以解决这个问题:

  • 让我们的桶中的文件完全公开(真的真的真的真的真的真的很糟糕的主意)
  • 在 AWS 配置上投入更多时间,并让一些角色能够与我们拥有的 S3 资源进行交互(好得多)

导航到 AWS 中的 IAM 控制台,我们将找到所有可用角色的列表:

EMR/EC2 访问的默认角色

然后,我们将单击每个默认角色,并选择添加一个内联策略

添加内嵌策略

然后,我们将向我们的角色添加完整的读写策略,如下所示:

S3 资源的读写策略

实际上,我们可以更具体地说明我们的政策,以及我们的角色如何与我们的 S3 团队互动。现在,我们只需为所有四个资源组(访问点、存储桶、作业和对象)选择 Any ,我们就可以检查并批准策略了。

如果有需要,应该选择更严格的条件。

纱线的配置文件

我们要为这个演示做的事情将需要我们机器上的大量 RAM,超过默认值所允许的。所以我们必须创建一个配置文件来帮助我们避开这个问题。

一般来说,大数据通常不会完全加载到 RAM 中,而是使用 HIVE 或 Spark 进行交互。然而,为了将 Spark 与我们经典的机器学习方法进行比较,我们将反叛并将大量数据加载到 RAM 中。

让我们在本地机器上创建一个名为 config.json 的配置文件。

它处理我们的资源管理器 YARN(另一个资源协商器),并告诉我们可以为整个应用程序分配多少内存,以及告诉 YARN 不要检查内存违规(整个内存中只有一小部分会分配给我们的 Python 脚本,因此我们需要停止检查这一小部分之外的违规)。

同样,这是为了比较我们的基础sklearn决策树,而不是处理大数据的方式。

为我们的集群设置身份验证

我们必须从 EC2 仪表板创建一个密钥对,并将其下载到我们的计算机上

EC2 密钥对接口

一旦下载了密钥对,就必须通过运行命令使其可读

chmod 400 my-key-pair.pem

在文件上使用终端(Mac)或 Git-Bash (Windows)。这允许您稍后连接到启动的实例(如果它正在运行)。

通过 AWS CLI 启动 EMR 集群

我们期待已久的时刻终于到来了。使用 AWSCLI,我们可以在家中舒适地启动一个集群来为我们做一些工作。为此,我们将运行以下命令:

aws2 emr create-cluster \
--name "**Spark cluster with step**" \
--release-label emr-5.29.0 \
--applications Name=Spark \
--log-uri **s3://log-bucket/logs/** \
--ec2-attributes KeyName=**my-key-pair** \
--instance-type m5.2xlarge \
--instance-count 1 \
--bootstrap-actions Path=**s3://scripts-and-setup/bootstrap_file.sh** \
--configuration file://config.json \
--steps Name="Command Runner",Jar="command-runner.jar",Args=["spark-submit","--deploy-mode=cluster","--executor-memory","20G","**s3://workflow-script/process_data.py**, **s3://data-files/**AAPL.csv"] \
--use-default-roles \
--auto-terminate

这个命令有很多东西,所以让我们打开重要的部分:

  • aws2 emr create-cluster —希望这是不言自明的
  • --name "**Spark cluster with step**" —用您喜欢的任何名称替换此名称,但这将是集群的名称
  • --release-label emr-5.29.0 —要使用的集群版本。不同版本的集群包含各种其他应用程序的不同版本,如 Hadoop、Spark、Hive 等
  • --applications Name=Spark —我们将推出一款 spark 应用
  • --log-uri **s3://log-bucket/logs/** 这是我们将日志发送到的地方。您需要一个日志存储桶,以防您的集群出现故障,并且您可以查看出错原因的日志。你必须用你的桶替换它。
  • --ec2-attributes **KeyName=my-key-pair** 这是一个密钥对,如果需要,您可以使用它来建立到集群的 ssh 连接
  • --instance-type m5.2xlarge —这是我们将使用的实例类型和大小。AWSCLI 不支持小于 xlarge 的
  • --instance-count 1 —我们将只启动一个实例(实际上并不是一个集群,但是我们将在下一篇文章中讨论)
  • --bootstrap-actions Path=**s3://scripts-and-setup/bootstrap_file.sh** —这是命令的一部分,告诉集群使用哪个脚本来启动集群。您必须用您的脚本文件位置替换它
  • --configuration file://config.json —这告诉 AWSCLI 使用我们创建的 config.json 文件,前缀file://告诉 AWSCLI 这是一个本地文件(尽管我们也可以将它存储在 AWS S3 上)
  • 这个很密集,所以让我们把它再分开一些。首先,我们将使用command-runner.jar Jar 文件来运行我们的 python 脚本。这是一个 Java 可执行文件,它将运行我们的 python 脚本并管理所有与 Spark 相关的工作。
    成那个样子。jar 文件我们发几个参数Args。它们是spark-submit,它说这个任务被提交给 Spark 框架,--deploy-mode=cluster,它说我们在集群内部启动我们的可执行文件(相对于从我们的家,非 AWS 机器),我们要求 Spark 框架在运行我们的脚本和它的其他步骤时使用 20GB 的内存(实际上我们的脚本变得有点少,因为内存分配是如何在 Spark 和 YARN 之间工作的)用命令"--executor-memory""20G", 最后是最后一个参数
    **s3://workflow-scripts/process_data.py**, **s3://data-files/AAPL.csv**,通过 AWS 的魔法,它被解析成
    **s3://workflow-scripts/process_data.py** **s3://data-files/AAPL.csv**(注意逗号被空格替换,形成一个完整的命令)。 这是 Spark 环境将运行的完整命令,这是我们的 Python 脚本(下载到这里)及其所有参数。对于这一步,您必须用自己合适的名称替换存储桶名称。
  • --use-default-roles —告诉 AWS 使用我们之前设置的默认角色
  • 这是一个真正美丽的论点。它告诉集群在所有处理完成后终止,因此我们不会为集群无所事事地坐在那里并收取我们的信用卡费用而付费。如果为了调试的目的,您想要保持集群运行,您可以省略它或者使用显式版本--no-auto-terminate但是,确保手动终止,然后

我们运行的结果

在我的机器上输入命令后,集群启动用了大约 2 秒钟,然后又用了 12 分钟来完成我要求的一切并终止。当检查 S3 存储桶的日志时,决策树分类器报告已经运行了 8 分钟进行拟合和预测。

到目前为止,我们已经启动了一个节点来为我们做一些处理,请注意,我们已经从使用比家用笔记本电脑更强大的机器中获益。我们使用 sklearn 进行分析的代码现在在一台功能强大的计算机上运行了大约 12 分钟。
虽然这个集群在分布式计算领域还没有做太多工作,但我们已经做好了基础工作,可以看到 Spark 在发挥作用。我在这里提到过几次 Spark,在下一篇文章中,我将最终展示这个框架在我们用决策树探索的相同数据上的实际应用。

迄今为止的总成本

我想在这里停下来谈一谈成本。实践和磨练 AWS 技能的最大摩擦点之一是这样一个事实,即在大多数数据科学信息和技能都是免费的(来自 Kaggle 的免费数据集,Python 和 R 等免费编程工具)的世界中,AWS 需要花钱,而且直到第二天收到账单时才完全清楚要花多少钱。
在学习和尝试正确设置的过程中,我已经旋转(设置)并拆除了 100 多个集群,到目前为止,我的总账单是注册 AWS 大约 1 美元,加上所有这些集群不到 5 美元。到目前为止,我便宜的账单很大程度上是因为我的每个“集群”中只有一个实例(--instance-count 1),并且我使用类型为m5.xlarge的集群练习了大多数旋转和拆卸。我把数据帧的尺寸缩小到原型,最终只在m5.2xlarge上做了原型。

端到端 AWS 定量分析:设置我们的脚本和 AWS

原文:https://towardsdatascience.com/end-to-end-quantitative-trading-part-1-798dcfeb165a?source=collection_archive---------24-----------------------

照片由energepic.com从派克斯拍摄

建设 AWS 管道

机器学习关注的是如何理解大量难以处理的数据。很大一部分机器学习工作现在可以在台式机上完成,甚至可以在笔记本电脑上完成,只要配置合适。

尽管如此,仍有大量的工作需要在专业的云计算架构上完成,这些架构要在合理的时间内处理难以置信的大量数据。

在这篇文章中,我想重点介绍建立端到端管道的想法,这将利用亚马逊网络服务(AWS)进行量化交易。

这篇文章的目的不是为您提供一台印钞机,而是展示在 AWS 上部署全自动工作流所需的步骤。

这组帖子将把工作流程分为四个主要部分:

  1. 编写脚本来获取数据,在数据上使用基本的 ML 模型,并将这些脚本存放在 AWS 上
  2. 为我们的基本 ML 模型建立一个 AWS 框架,并自动使用它
  3. 通过 Spark 利用我们的 ML 功能
  4. 在我们的 ML 完成运行后,自动准备我们的分析摘要

获取数据

因为我们对股票的历史数据感兴趣,所以有几种选择。Quandl 是一项可以提供每日股票数据(以分钟为单位)的服务,但它需要付费。对于这篇文章,我将选择免费选项,并使用雅虎财经。

哈哈。Finance 有几个库被设计成通过它的 API 与它交互,并建立到 Python 的桥梁,所以我将使用 yfinance 。

如果我们使用 yfinance,我们可以构建以下代码

虽然这段代码完成了工作,但是到目前为止,它只针对一个独特的用例场景:

  1. 它只获取 AAPL 的数据
  2. 并且只在特定的日期范围内这样做

我们也许应该把它包装成一个函数,这样我们就可以使它稍微更通用一些

现在,我们需要一些方法来获取相关的日期,并使其适用于雅虎上的任何资产!金融。

计算开始和结束日期

让我们从简单的部分开始,开始和结束时间。我们可以很容易地得到今天的日期,然后找到五年前的日期。然后,我们可以很容易地将两者转换成适当的字符串类型。

>>>> 2020-02-13
>>>> 2015-02-13

我们可能也应该将它封装成一个函数:

当我们获得数据时进行处理

获得数据后,我们想对它做一点处理,为机器学习做准备。
首先,我们将在数据框中添加一个Return字段,记录当天的回报是否为正。

我们可以计算连续收盘价之间的差值,也可以计算同一天的开盘价和收盘价之间的差值。我选择后者,只是为了让人们意识到这也是一个可以考虑的选择。

一旦我们得到了回报,我们就可以创建一些特性,并在以后为我们的 ML 算法创建一个目标。让我们把那些也加上

把所有的放在一起

这部分代码的最后一部分是将我们编写的所有代码放入一个脚本,该脚本接受我们的股票 id 和一个路径作为命令行参数,并将股票数据帧保存到提供的路径中。我们将添加更多的文档来创建更易于管理的代码库。

我们将把这个脚本称为“获取数据”

获取数据

我们已经添加了相当多的 docstrings 和其他文档,以防我们以后想要更改某些内容。

现在我们可以称这个脚本为:

python obtain_data.py MSFT  --output_directory \ /usr/boris/destination

让它获取微软(MSFT)的数据,并将结果写入/usr/Boris/destination/msft . csv 中的本地 CSV 文件

处理数据

在我们获得数据之后,我们想要以某种方式处理它。出于本教程的目的,我们将假设我们想要使用一个决策树来使用我们之前创建的Target列对我们的数据进行分类。我们将从使用 sklearn 的决策树分类器开始。

>>> 0.0002604

很明显,对于这种规模的数据集,我们真的不需要 AWS。我们可以做一点小手脚,用下面的代码让数据集变大:

现在,数据集的大小最终达到 41,222,144 行,在我的笔记本电脑上处理大约需要 10 分钟。

我们将创建另一个 python 脚本,它接受一个文件位置作为命令行参数,将文件扩展为其原始大小的 2 倍⁵,然后处理它。在 AWS 上,我们将使用 sklearn 和 Spark 来比较处理时间。

流程 _ 数据. py

将脚本放在可访问的位置

我们希望 AWS 计算实例能够运行我们的脚本。我们可以做的一件事就是简单地使用 SSH 将文件传输到实例,但是稍后我们想让我们的实例自动设置、运行和拆除,而不需要我们做太多,所以我们将这些脚本放在 AWS 的 S3 存储桶中。这将使我们未来的计算实例可以轻松地访问该文件。

首先,我们需要创建一个 S3 桶(1),并给它一个有用的描述性名称。创建完成后,我们可以在 S3 仪表板中看到它(2)。

创建 S3 存储桶

然后,我们将脚本上传到 bucket 中,以便我们的 AWS 实例可以访问脚本及其功能

上传我们刚刚创建的文件

此外,我们将设置另外三个存储桶;一个用于日志文件,一个用于数据文件,一个用于安装 bash 文件。我们最终的 S3 建筑应该是这样的:

我们做到了!

一个 python 脚本,可以在 AWS 上使用,为我们挖掘数据。下一步是创建一个运行脚本和处理挖掘数据的地方。下一篇文章将详细讨论这个问题!

EDA:变量关系和填充缺失值

原文:https://towardsdatascience.com/end-to-end-regression-techniques-for-real-estate-predictions-be98e689fca5?source=collection_archive---------33-----------------------

初学者回归技巧

房地产预测的端到端回归技术-第 1 部分

由贝利·安塞尔姆在 Unsplash 上拍摄

作为我作为数据科学家旅程的一部分,端到端数据探索和模型开发是我学习成功的关键。这个系列将提供一个端到端的预测爱荷华州的房屋销售价格。为了便于阅读,本系列将分为四个部分:

  • EDA 第一部分 : 标绘预热和填充缺失值
  • EDA 第二部分 :特征工程和变量编码
  • EDA 第三部分: 统计测试
  • 预测建模: 训练和调优 XGBoost
  • 堆叠模型 :结合 XGBoost 与 Enet、Ridge、Lasso

打开一个 Jupyter 笔记本, 下载数据 ,跟着自己实施以下策略。我已经包括了一些“练习”来帮助你。我隐藏了全部代码,以迫使你专注于思考过程。此外,通过自己把代码打出来,你会获得经验,最终会变得流利。不过,如果你一路上需要帮助,可以在这里 找到我的完整笔记本

如果你已经读过我的文章《 初学者看 Kaggle 》,你就知道接下来会发生什么:让我们用 EDA 来弄脏我们的手吧。这将是这个系列这一部分的唯一焦点。

住房价格的探索性数据分析

第一部分将主要关注基本绘图和缺失值插补。我的目标是概述一个建立直觉的过程,即哪些变量在起作用,哪些变量对销售价格有最大的影响。我还想评估变量之间的关系,因为这将让我们了解如何智能地填充缺失的数据。

我们在 4 部分系列中的数据探索重点如下:

  • 直观地呈现数据 —对我们的数据进行图形化和绘图可以让人们洞察我们的数据在现实世界中的含义。我们有 79 个变量在发挥作用,所以这是一个很好的方式来感受正在发生的事情。然而,所有的可视化都应该持保留态度。他们没有讲述整个故事。
  • 寻找和处理缺失数据 —在这一阶段,我们将分析哪些变量有缺失值,它们为什么缺失,以及我们可能如何处理缺失数据。
  • 特征工程——我们能否在数据中找到并定义潜在的模式,帮助我们更好地描述和解决我们的问题?
  • **实力的关联。**假设一个变量与销售价格相关,那么这种关系有多强?
  • **分类变量对销售价格的 ANOVA F-检验。**与连续变量不同,我们不一定能确定类别和连续数据之间的传统相关性度量。通过方差分析或 ANOVA 分析,我们可以了解邻域等分类变量对连续变量销售价格是否有显著影响。

*练习 1:*** 注册一个 Kaggle 帐户,下载我们将使用的数据!我把我的数据保存在一个名为data的文件夹里,这个文件夹和我的笔记本在同一个目录下。

import pandas as pd
train_df = pd.read_csv('data/train.csv', index_col='Id')
test_df = pd.read_csv('data/test.csv', index_col='Id')
train_df.describe().T.head(10)

热身 1:目标变量的分布

为了开始了解我们的数据,我们将绘制我们的目标变量分布以及一些不同的转换。我们这样做有几个原因:

  1. 我们希望理解我们的数据,直观地查看数据有助于我们建立对影响结果的潜在因素的直觉。它让我们头脑中的轮子转动起来,并有希望激发可能带来有价值见解的问题。
  2. 转换变量的分布是常见的行业惯例。转型并不总是必要或有益的。数据转换有效性背后的数学理论很深入,并且经常被争论(特别是在深度学习领域)。只要说“视情况而定”,然后进行实验就够了!

在转换之前,我们的销售价格数据是右偏的,这意味着平均值比中值偏向更高的价格。通过sklearn.preprocessing.PowerTransformer()应用 Yeo Johnson 变换,我们得到了标准正态分布的一个非常好的近似值:

import sklearn.preprocessing as pre
import seaborn as sns
import matplotlib.pyplot as pltpt = pre.PowerTransformer()
ptd = pt.fit_transform(train_df.SalePrice.to_numpy().reshape(-1,1))
plt.title(f'Yeo Johnson, Skew: {stats.skew(ptd.squeeze()):.3f}')
sns.distplot(ptd, kde=True)

我还使用对数变换进行了检验,但我们无法接近正态分布:

这些转换改变了数据的含义(注意横轴上缺少“销售价格”标签)。转换目标变量的主要目的是希望辅助机器学习算法的训练。同样,这需要实验,直到本系列的第 3 部分才会涉及。

热身 2:检查基本直觉

作为我们的第二个热身练习,让我们来检验一下我们的直觉:对最终销售价格起作用的不仅仅是数量,还有质量:

fig, axes = plt.subplots(2,2, figsize=(12,12))
sns.scatterplot(x='GrLivArea', y='SalePrice', hue='OverallQual', data=train_df, ax=axes[0,0])...plt.tight_layout()# Try reproducing the plot below using the above code as a hint.

在第一栏中,我们将销售价格与地上居住区(又名 GrLivArea) 的价格以及房屋建筑材料的整体质量进行了比较。我们所看到的是,销售价格是根据居住面积和质量来分级的。这在散点图中的强线性趋势、色调的均匀分级以及总体质量的箱线图中是明显的。

有点令人惊讶的是,我们看到描述总体状况的变量,**总体成本,**似乎对销售价格几乎没有影响。第二个散点图中数据点的色调是随机的,箱线图是无序的。这是反直觉的,我们可以稍后再去探究我们所看到的是否有意义。

另外,请注意数据中的两个异常值。在散点图中可以看到两处住宅,它们的居住面积都很大,但相对于其他同等面积的住宅,它们的售价却非常低。

*** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 练习 2:** 调查你对其他变量的直觉以及它们与销售价格的关系,并绘制出它们之间的关系。看看 Seaborn 的绘制关系的伟大工具。**** * * * * * * * * * * * * * * * * * * * * * * * * * * * ****

处理缺失数据

我们的下一轮分析将关注我们缺失的数据。我们想知道数据丢失的原因,以及我们如何填补空白。丢失的数据是丢失了可能对我们有用的信息。为了更好的预测,尝试填补这些空白通常是值得的。

训练集中缺少数据:

首先,我们将解决我们缺少的训练数据中的缺口。我写了一个小函数来可视化一个数据集中缺失的数据。在我的完整笔记本中寻找一个叫做viz_missing(df)的方法:

柱状图显示了大量缺失的数据。如果我们想得到真正好的结果,就不应该忽视这些数据。过程的这一部分是乏味的,但却是必要的。我鼓励你关注以下思考过程:

  1. 选择一个希望填充缺失数据的变量。
  2. 看看是否有另一个变量,与你正在研究的变量有关。
  3. 确定缺失的数据是否可以用相关变量来解释。
  4. 如果使用步骤 2 和 3 无法确定缺失的信息,请考虑使用平均值、中值或众数。请注意,这对小数据集来说可能是危险的。

*示例 1:缺少池质量数据*

上图中缺失数据量最大的变量是PoolQC,代表“池质量和条件”。

在查看了我们的数据字典之后,我们应该注意到只有一个其他变量描述了一个家庭的游泳池。这个变量就是PoolArea。请注意,没有与该变量相关联的缺失数据。

我的直觉是,所有有PoolArea = 0的家庭可能与缺少PoolQC信息的家庭相关联。换句话说,这些家庭没有游泳池,这就是为什么他们遗漏了游泳池质量变量。我们可以用几行代码来检验这种直觉:

*# Get number of homes with missing PoolQC that also have 0 PoolArea.
np = train_df[train_df.PoolQc.isna() & (train_df.PoolArea == 0)]
count = np.shape[0]# Get total number of missing PoolQC entries
missing = train_df.PoolQC.isna().sum()count, missing
>>> (1452, 1452)*

因此我们看到,对于所有 1452 个缺少PoolQC条目的家庭,该家庭的PoolArea为 0。这证明我们的直觉是正确的。我们可以用多一行代码来填补空白:

*train_df.PoolQC.fillna("NA", inplace=True)*

示例 2:缺少地段临街面

LotFrontage根据数据字典,是与物业相连的道路的英尺数。这次我们没有任何额外的变量来告诉我们为什么LotFrontage会丢失。这意味着我们将不得不以不同的方式填补空白。

我们可以合理地假设,几乎每一块地产都至少触及某条道路或小巷的一小部分。这可能不是普遍正确的,但可能是规则而不是例外。我们将利用这种直觉,用我们拥有这些数据的所有房屋的平均值或中值来填充任何缺失的LotFrontage:

*train_df.LotFrontage.fillna(train_df.LotFrontage.median(), inplace=True)*

我选择用中值来填充缺失的条目,因为它对异常值更稳健。

**** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 练习 3:** 对测试集和训练集中的所有缺失数据执行相同的调查。你应该需要一段时间。很多都不见了!


*我将在本系列的第 2 部分结束。完成练习 1-3 需要花费你相当多的时间,我们鼓励你在继续之前先把这些练习编码好。*

如果您有任何问题、意见或批评,请在评论区联系我!

基于能量的模型和生成算法的未来

原文:https://towardsdatascience.com/energy-based-models-and-the-future-of-generative-algorithms-3950e1103323?source=collection_archive---------34-----------------------

苹果 | 谷歌 | SPOTIFY | 其他

Will Grathwohl 在 TDS 播客

背景图片由艾哈迈德·迪里尼

编者按:迈向数据科学播客的“攀登数据科学阶梯”系列由 Jeremie Harris 主持。Jeremie 帮助运营一家名为sharpes minds的数据科学导师初创公司。可以听下面的播客:

研究生院中的机器学习和工业中的机器学习是非常不同的东西。在行业中,部署和数据收集变得很关键,唯一重要的是你是否能以足够快的速度交付真正客户想要的产品,以满足内部期限。在研究生院,有一种不同的压力,集中在算法开发和新颖性上。通常很难知道你最适合哪条道路,但这就是为什么与两者都做过的人交谈会如此有用——如果他们的学术研究经验来自世界顶尖大学之一,还会加分。

在今天的《走向数据科学》播客中,我采访了 Will Grathwohl,他是多伦多大学的博士生,谷歌人工智能的学生研究员,也是麻省理工学院和 OpenAI 的校友。Will 在行业和学术环境中看到了前沿的机器学习研究,并分享了一些关于这两种环境之间差异的深刻见解。他最近还发表了一篇关于能源模型这一迷人主题的文章,其中他和他的合著者提出了一种关于生成模型的独特思维方式,这种方式在计算机视觉任务中实现了最先进的性能。

以下是我们聊天中我最喜欢的一些带回家的东西:

  • 在工业界,人们非常重视以最简单、最快的方式解决问题,使用现成的算法,而不是提出尖端的模型。部署和数据收集最终消耗的时间比您预期的要多,这可能会令人感到窒息——特别是如果您的角色碰巧更倾向于将模型投入生产,而不是从头开始训练它们。
  • 然而,学术研究也有其自身的压力。除了发表论文的压力之外,学术机器学习的竞争越来越激烈,进入博士项目实际上仅限于已经在顶级期刊和会议上发表过论文的人。进入博士项目需要专注,并不适合每个人,所以在走上这条道路之前,认真问问自己是否愿意做出两年多的承诺来为他们定位是值得的。
  • 两种最常见的机器学习模型是判别模型和生成模型,前者返回单个数字(如分类器或回归器),后者产生新的输入(如图像生成模型,或某些语言模型)。生成模型特别酷,因为它们被迫学习足够多的数据来产生新的样本,而不仅仅是对它们进行分类。直觉上,这应该使他们在分类和回归任务中真正有效(因为你当然可以认为学习绘画的最好方法是创作新的绘画)。但这并没有发生:随着时间的推移,人们变得如此专注于生成现实的样本,以至于他们越来越少关注区分性应用程序的生成模型的最初承诺。
  • 威尔的最新研究提出了一种关于生成模型的强大的新思维方式,这种方式使它们能够更有效地应用于区分性任务。他的团队展示了最先进的成果,我们在聊天中深入探讨了这项研究。

你可以在推特上关注威尔,你也可以在推特上关注我。

基于 python 和 LSTM 深度学习模型的能源消费时间序列预测

原文:https://towardsdatascience.com/energy-consumption-time-series-forecasting-with-python-and-lstm-deep-learning-model-7952e2f9a796?source=collection_archive---------1-----------------------

如何利用时间序列进行深度学习

戴维·赫尔曼在 Unsplash 上的照片

本文的目的是向读者展示 python 中的一个类,该类具有非常直观和简单的输入,可以使用深度学习对时间序列数据进行建模和预测。理想情况下,读者应该能够复制本文或 GitHub 资源库中的代码,根据自己的需要对其进行裁剪(例如,向模型中添加更多层),并在工作中使用它。

本文中使用的所有代码都可以在这里找到:

【https://github.com/Eligijus112/deep-learning-ts

这篇文章的数据可以在这里找到:

https://www.kaggle.com/robikscube/hourly-energy-consumption

用于深度建模的包是 TensorFlow 和 Keras。

时间序列是按连续顺序排列的数字数据点序列。这些点通常定期测量(每月、每天、每小时等)。).本文中使用的数据频率是每小时一次,测量时间是从 2004 年 10 月 1 日到 2018 年 8 月 3 日。原始数据点的总数为 121271

Python 中的时间序列示例

时间序列的可视化:

能源消耗时间序列的折线图

对于给定的时间序列,深度学习算法的主要目标是找到函数 f ,使得:

Yₜ = f(Yₜ₋₁,Yₜ₋₂,…,Yₜ₋ₚ)

换句话说,我们希望基于相同能耗的 p 滞后估计一个解释能耗当前值的函数。

这篇文章不是要解释为什么长期短期记忆(LSTM)深度学习网络有利于时间序列建模或它是如何工作的。有关这方面的资源,请查看以下精彩文章:

[## LSTMs 和递归神经网络初学者指南

数据只能反向理解;但它必须向前看。-索伦·克尔凯郭尔,期刊*

pathmind.com](https://pathmind.com/wiki/lstm) [## LSTM 和 GRU 的图解指南:一步一步的解释

嗨,欢迎来到长短期记忆(LSTM)和门控循环单位(GRU)的图解指南。我是迈克尔…

towardsdatascience.com](/illustrated-guide-to-lstms-and-gru-s-a-step-by-step-explanation-44e9eb85bf21)

有关 Keras 中 LSTM(或任何 RNN 图层)的实现,请参见官方文档:

[## 重复层- Keras 文档

用于递归层的 keras . engine . Base _ layer . wrapped _ fn()基类。Arguments 单元格:RNN 单元格实例。一个 RNN 细胞…

keras.io](https://keras.io/layers/recurrent/)

首先,我们需要读取数据:

读取每小时数据的代码示例

然后我们需要一个函数,将时间序列转换成 X 和 Y 矩阵,供深度学习模型开始学习。假设我们想要创建一个使用 3 滞后解释当前时间序列值的函数:

Yₜ = f(Yₜ₋₁,Yₜ₋₂,Yₜ₋₃)

我们有这样的数据:

ts = [1621.0, 1536.0, 1500.0, 1434.0, 1489.0, 1620.0]

我们想要创建两个矩阵:

X = [
[1621.0, 1536.0, 1500.0], # First three lags
[1536.0, 1500.0, 1434.0], # Second three lags
[1500.0, 1434.0, 1489.0], # Third three lags
]Y = [1434.0, 1489.0, 1620.0]

**这是对时间序列使用深度学习时最重要的技巧。**你不仅可以将这些 X 和 Y 矩阵提供给递归神经网络系统(如 LSTM),还可以提供给任何普通的深度学习算法。

函数从时间序列中创建 X 和 Y 矩阵

深度学习模型有一个 LSTM 层(也用作输入层)和一个输出层。

定义 LSTM 深度学习模型

在我在互联网上搜索一个易于使用的时间序列深度学习模型的过程中,我看到了各种文章,这些文章将建模的几个部分分开,如如何定义模型,如何为模型创建矩阵等。我没有找到一个包或一个类,把所有东西都打包成一个易于使用的实体。所以我决定自己来做:

建模类

开始上课:

# Initiating the classdeep_learner = DeepModelTS(
data = d,
Y_var = 'DAYTON_MW',
lag = 6,
LSTM_layer_depth = 50,
epochs = 10,
batch_size = 256,
train_test_split = 0.15
)

该类的参数是:

数据 -用于建模的数据。

Y_var -我们要建模/预测的变量名。

滞后 -用于建模的滞后数量。

LSTM _ 层 _ 深度-LSTM 层中神经元的数量。

时期 -训练循环的数量(正向传播到反向传播循环)。

batch_size -深度学习模型在寻找参数时使用的梯度下降的数据样本的大小。所有数据都被分成 batch_size 大小的块,并通过网络传送。在每个 batch_size 的数据在模型中前进和后退之后,模型的内部参数被更新。

要了解更多关于时期和批量大小的信息,请访问:

[## 神经网络中批次和时期之间的差异

随机梯度下降是一种具有多个超参数的学习算法。两个超参数…

machinelearningmastery.com](https://machinelearningmastery.com/difference-between-a-batch-and-an-epoch/)

train_test_split -用于测试的数据份额。1 - train_test_split 用于模型的训练。

拟合模型:

# Fitting the modelmodel = deep_learner.LSTModel()

在上面的命令之后,你可以看到球迷最喜欢的训练画面:

Keras 中模型的训练

用更多的滞后(因此,更大的 X 矩阵)训练模型增加了训练时间:

deep_learner = DeepModelTS(
data = d,
Y_var = 'DAYTON_MW',
lag = 24, # 24 past hours are used
LSTM_layer_depth = 50,
epochs = 10,
batch_size = 256,
train_test_split = 0.15
)model = deep_learner.LSTModel()

多滞后模型的训练

现在我们已经创建了一个模型,我们可以开始预测。使用用 p lags 训练的模型进行预测的公式:

Yₜ₊₁ = f(Yₜ,Yₜ₋₁,…,Yₜ₋ₚ₊₁)

# Defining the lag that we used for training of the model 
lag_model = 24# Getting the last period
ts = d['DAYTON_MW'].tail(lag_model).values.tolist()# Creating the X matrix for the model
X, _ = deep_learner.create_X_Y(ts, lag=lag_model)# Getting the forecast
yhat = model.predict(X)

如果数据被分成训练集和测试集,那么 deep_learner.predict() 方法将预测测试集中的点,以查看我们的模型在样本外的表现。

yhat = deep_learner.predict()# Constructing the forecast dataframe
fc = d.tail(len(yhat)).copy()
fc.reset_index(inplace=True)
fc['forecast'] = yhat# Ploting the forecasts
plt.figure(figsize=(12, 8))
for dtype in ['DAYTON_MW', 'forecast']: plt.plot('Datetime',dtype,data=fc,label=dtype,alpha=0.8)plt.legend()
plt.grid()
plt.show()

时间序列预测

正如我们所看到的,模型创建中隐藏的 15%数据的预测值接近真实值。

我们通常希望提前预测最后的原始时间序列数据。类 DeepModelTS 有方法 predict_n_ahead(n_ahead) 预测 n_ahead 时间步。

# Creating the model using full data and forecasting n steps aheaddeep_learner = DeepModelTS(
data=d,
Y_var='DAYTON_MW',
lag=48,
LSTM_layer_depth=64,
epochs=10,
train_test_split=0
)# Fitting the model
deep_learner.LSTModel()# Forecasting n steps ahead
n_ahead = 168yhat = deep_learner.predict_n_ahead(n_ahead)
yhat = [y[0][0] for y in yhat]

上面的代码预测了未来一周的步骤(168 小时)。与之前的 400 小时相比:

超出时间范围的预测

总之,本文给出了一个简单的管道示例,用于时间序列数据的建模和预测:

**读取和清除数据(1 行 1 时间步)**

选择滞后数量和模型深度

初始化 DeepModelTS()类

拟合模型

提前 n _ 步预测

我希望读者可以在他/她的专业和学术工作中使用本文展示的代码。

基于相对论引力理论的在线讨论参与动力学

原文:https://towardsdatascience.com/engagement-dynamics-of-online-discussions-using-relativistic-gravitational-theory-77bbb25f90e2?source=collection_archive---------42-----------------------

当物理学在解决社交计算方面派上用场的时候

从物理和生物过程中进行类比在历史上被证明对计算机科学领域是有益的——神经网络、进化算法、社区增长模型等等。这种类比往往依赖于一些非常简单但有力的假设。这些类比中的科学严谨性应该被小心地提醒——大多数这样的类比实际上是“类比”,而不是对统一理论的主张。在本文中,我们将详细阐述“广义相对论的场方程”如何帮助建模在线讨论平台上的用户参与度。首先,我们需要定义我们要建模的参与动力是什么,以及革命性的场方程如何发挥作用。

用户参与度与引力

让我们从一个非常简单的用户参与讨论的模型开始。我们有一些用户数量固定的讨论平台。现在,一个随机的用户发布一些东西——一个观点,新闻,一个音乐视频,或者可能是一个讽刺的“模因”。并非所有用户都开始评论这篇文章;只有那些对帖子主题“感兴趣”的人才会加入讨论。然而,这种“兴趣”并不是一种静止的现象。随着时间的推移,特定的讨论可能会吸引以前不感兴趣的用户。

利用这个讨论平台的简单模型,我们可以从两个非常基本的假设开始:(I)用户居住在一个 n 维空间上的点上(并且在移动),使得近邻具有共同的兴趣;以及(II)讨论具有在不同程度上吸引不同用户的一些属性。第二个假设是,用户和讨论之间可以没有吸引力,但没有排斥。实际上,用户可能会对讨论感到“厌恶”,因此选择不参与。但是实际上不可能识别“排斥”(“不喜欢”或“否决”也是参与),除非用户明确这样说。

这两个假设反映了讨论平台和引力场之间惊人的相似性。人们可以想象一个讨论具有某种“质量”性质,它会随着时间而变化。这个质量在 n 维用户空间的不同点产生了一些“引力”,根据引力的大小,用户会来到那个位置。为了更详细地计算质量和拉力,我们需要重温一下重力实际上是如何工作的。

图一。存在大质量物体和光的引力弯曲时时空流形的曲率:红线表示光线的实际弯曲运动,而虚线表示不间断的路径(来源:http://www . zamandayolculuk . com/cetin bal/htmldosya 1/relativity file . htm)。

爱因斯坦场方程

到目前为止,阿尔伯特·爱因斯坦在他的广义相对论中给出了对引力最精确的描述。著名的爱因斯坦场方程将引力描述为“时空的弯曲”。在这里,空间(3 维)和时间(1 维)不是独立的实体;相反,它们构成了时空(四维)的复杂混合体。任何质量-能量-动量的存在都会在时空的几何中产生一个曲率,结果,任何移动的物体都会弯曲它的路径(被拉着)(见图 1)。场方程是:

不进入严格的数学细节,上述等式的左侧对应于流形的曲率,而右侧对应于能量-动量密度。

从用户交互到用户时空

因此,如果我们想开发一个类似的用户参与模型,我们需要做的第一件事就是定义用户到一些固定维度点(向量)的映射。这种映射应该保持我们的第一个假设,即共同感兴趣的用户必须保持密切联系。为了从数学上定义“共同兴趣”,我们可以在一对用户之间分配三种类型的接近度:

I)交流接近度:用户已经回复了彼此之前的评论或帖子;II)时间接近度:用户在最近的时间内对同一讨论发表了评论;III)语义接近度:用户评论了语义相似的帖子。

这三种邻近性加在一起,为每一对用户分配一个聚合邻近性(或共现)值。现在,如果我们用一个 n 维向量来表示每个用户,使得他们的标量积与他们的接近度成比例,我们就得到期望的用户空间。与时间值连接,这产生了用户时空。

从讨论中获取能量

下一个任务是将讨论表示为随时间变化的能量函数。在论坛中,讨论是否会吸引用户取决于各种特征——讨论的主题、帖子和评论中表达的观点的极性、文本的可读性、不同的词语用法以及发表评论的用户。我们可以学习一个参数化的非线性函数,它将这些特征映射到固定维度的向量(在这种情况下,维度必须与用户时空相同)。这种表示将初始化应力-能量张量的对角元素, Tμv.

把所有的碎片放在一起

我们为简化参与度建模问题所做的最后一个假设是,用户在共同兴趣的基础上形成自然集群。因此,我们将用户空间划分为集群,并预测每个时间段内来自特定集群的用户对给定帖子发表评论的概率。聚类中心被认为是聚类的位置向量。我们建立了一个学习计算度量张量的模型

从集群位置和应力-能量张量的讨论特征。对于不同时间间隔的给定讨论,这两个张量的组合将给出每个集群中心的用户时空的曲率。现在,我们可以比较这些曲率来决定哪些集群更有可能是接合集群。
应该记住的是,这个简单的模型并不声称在线讨论平台遵循广义相对论。相反,它将用户交互历史与讨论的文本特征相融合,非常类似于广义相对论如何提供重力的整体定义,将能量密度与时空几何相融合。

研究的细节可在 https://arxiv.org/pdf/1908.03770.pdf 获得

这就是查克拉博蒂。使用相对论引力理论对在线讨论的参与动力学进行建模,第 19 届 IEEE 数据挖掘国际会议 (ICDM),中国北京,2019 年 11 月 8 日至 11 日。

设计多层感知器

原文:https://towardsdatascience.com/engineering-a-multilayer-perceptron-8a177b60e6cf?source=collection_archive---------52-----------------------

数字神经数学简评

作者绘画

在这篇文章中,我将简要地概述从左边图像中描述的单层感知器到右边图像中描述的多层结构的数学发展;现在被称为*神经网络:*现代人工智能的基础单元。

要深入了解感知机发展的历史和社会影响,请阅读迈克尔·伊比的内核连接:感知机图解。

Theano、TensorFlow、Keras、py torch——每一个都提供了让深度学习更容易获得的资源。我花了很多时间处理这些模块。然而,有时我会忘记数学上到底发生了什么。每个库都有自己的语法。我发现每一种语法的透镜形成了我对架构如何通过功能处理信号的概念化,例如:向前和向后传播;或者如何应用激活。像任何实用程序库一样,有许多元素被整齐地打包并存储在引擎盖下。让我们打开其中一些工具。

使用 Keras 和玩具数据集作为基线。

用玩具数据集展示 keras 建筑的笔记本

也许我厌倦了,但那太容易了。这可能只是让一个模型运行起来的一个练习,但是在设计一个模型的时候,你应该练习的不仅仅是你的打字速度。下面是一个笔记本,我在其中获得了相同的数据集 raw,并能够产生更好的分数,从数据中获得更多洞察力,以及将定制功能设计到从 Numpy 构建的定制多层感知器。

笔记本走过预处理和训练 Senti_Net

后退一步

我们如何到达这里?我们如何把感知器这样的东西作为简单的逻辑算子,发展成深度学习模型?

什么是感知器?

感知器是一个线性的二进制分类器。它找到了两个阶级之间最清晰的界限。为了实例化更直观的描述,感知器能够感知两个给定类之间的差异,并检测给定数据点属于哪个类。它能够感知将一个数据点与另一个数据点线性分离的代表性空间。

作为逻辑运算符

逻辑运算符是控制信号流的函数。产生二进制输出的主要逻辑运算符有三种。

  1. 运筹学

在程序设计中,一个逻辑运算器将一个多输入信号通过线性激活处理后,解析成一个合成的单一输出。如果您的数据是图表上的一个点,这尤其有用;比如图上的(3,4)。(3,4)是一个身份,是一个位置。感知器可以评估该点的位置,并区分身份属于哪个类别。再次假设类属性是线性划分的。

逻辑运算符如何工作

并且是真值运算符。并且只有当两个输入都为真时才为真。换句话说,如果 A 和 B 都是 1,AND 运算符只会产生 1。如果 A =1,B =0,那么结果=0。这意味着,在 1 和 0 之间的四个可能结果中,只有一次是真的:当两个点都是 1 时。

运筹学

OR 是 AND 的反义词。除非两个操作数都为 0,否则 OR 始终为真。这意味着 A = 1,B = 0 为真。此外,A = 0 和 B = 1 也成立。A = 1 和 B = 1 是三次,真!只有 A = 0 和 B = 0 是假的。

而 AND 只有 25%的时间是正确的,或者 75%的时间是正确的。

没有什么是简单反向投资。如果 A 和 B = 1,那么 NOT = 0;如果 A 和 B = 0,那么 NOT = 1。

*下一个笔记本里有每个操作员的直接例子

感知器是第一个为模拟生物、神经功能而开发的算法和硬件实例。然而,大约 20 年后,在 80 年代,人们普遍意识到,感知器在解释任何不适合其线性受体的数据方面严重不足。现实是多维的,非线性的。

此外,感知器正确地指出,单层感知器无法分类非线性模式;它的分类能力仅限于线性可分的模式。在欧几里德几何中,线性可分性是指将两组数据聚类成 A 和 B 区域。这最容易用二维平面来形象化。如果一条线或决策面能够将数据整齐地分为 A 和 B,则该模式被认为是线性可分的。如果数据分布不是如此清晰地界定,模式被认为是非线性的。

迈克尔·伊比

步进到乙状结肠

感知机发展的另一个重要观点是:不仅有 0 和 1,而且在 0 和 1 之间有无限的连续可能性。通过 sigmoid 和 sigmoid 导数的识别,感知器能够生成类的可能性,以及更新感知器在可能性预测中的置信度。

下面的笔记本给出了逻辑运算符的例子,并演示了 sigmoid 的实现。此外,它显示了如何在反向传播中使用 sigmoid 的衍生物。

从单层感知器到多层感知器的逻辑

让我们使用上面笔记本中的函数更仔细地看看梯度下降的过程。

每个时期的更新是如何发生的

现在让我们更仔细地看看 SENTI_NET 的架构,情感分类多层感知器

感觉网

我们可以看到,Senit_Net 不仅仅是一个 MLP,它还有一个文本预处理单元。虽然这可以在外部完成,但我想构建专门处理文本的模型。Senti_Net 是硬编码的,只能辨别积极和消极情绪,但可以在任何带标签的文本数据上进行训练。我们可以在笔记本的末尾看到,利用一个经过训练的 Senti_Net,在传递它从未见过的政治推特的文本数据后,它能够准确地对情绪进行分类。

在我建立 Senti_Net 之后,我想看看我是否可以制作另一个二元分类器,但我没有将情绪分类为*【正面】【负面】*,而是让 MLP 对一条推文是来自民主党还是共和党进行分类。结果可以在下面的笔记本中找到。

** Twitter 数据由来自*的推文组成

  • 乔·拜登
  • 巴拉克·奥巴马
  • 伯尼·桑德斯
  • 希拉里·克林顿
  • 迈克·彭斯(都是@Mike_Pence 和@VP 手柄)
  • 唐纳德·特朗普
  • 肖恩·哈尼蒂

*从每个账户——从 4 月 21 日星期二开始——按时间顺序回顾,提取了 3000 条推文

Tw 网分类推文是来自民主党还是共和党

Tw 网表现还不错!将这两个模型加在一起,你就可以探究每一方推文的情绪。

这个练习的目的是激发人们对深度学习图书馆的好奇心。我们经历了一个简单的 MLP,但是现在问问你自己 CNN,或者 RNN 在数学上是如何表现的。是什么样的复制过程使变得智能?例如,MLP 的数学正在复制识别的过程。感知这个那个之间的能力。人工智能有时可能看起来超凡脱俗或神奇,但当人们密切关注时,人工智能不仅揭示了数学的美,还揭示了人类如何使用数学作为表达我们大脑内部过程的交流工具的美。

数据科学项目的工程最佳实践

原文:https://towardsdatascience.com/engineering-best-practices-for-data-science-projects-195e0687c642?source=collection_archive---------43-----------------------

让您的数据科学项目更加可靠、可测试和可部署

乔恩·泰森在 Unsplash 上的照片

介绍

在本帖中,我们将学习一些最佳实践来提高生产数据科学代码的质量和可靠性。

注意:这里提到的大多数东西对软件工程界来说并不陌生,但是在数据科学的实验世界中,它们经常被忽略/错过。

在这篇文章中,我将简要地提到一些主题和我们可以做的事情,以使我们的项目更加可靠,我将创建一些后续文章,使用一个项目示例来更详细地描述这些步骤。此外,在这篇文章中,我将假设一个 Python (pyspark)数据科学项目,但是这些想法可以应用于任何其他编程语言或项目。

希望你觉得有用。

代码重构

这是拥有更好代码的第一步。它是简化现有代码设计而不改变其行为的过程。

数据科学项目大部分时间都写在 jupyter 笔记本上,很容易失控。强烈建议在将代码投入生产之前进行代码重构。

解决的问题

  • 提高代码可读性——让我们的团队更容易理解
  • 降低复杂性——更小、更易维护的功能/模块

行动项目

  • 将代码分解成更小的函数
  • 注释功能
  • 更好的命名标准
  • 移除未使用的代码位

单元测试

单元测试是一种测试代码中每个功能的方法。目的是验证代码中的每个函数都按预期执行。

在数据科学项目中,测试几乎总是被忽略。您的项目中有一些部分可能不需要测试用例,但是在一个项目中,有许多其他组件可以很容易地进行单元测试。

例如,模型评估是在实验阶段完成的,我们可能不需要在单元测试中再次测试,但是数据清理和数据转换是绝对可以进行单元测试的部分。

解决的问题

  • 这有助于尽早修复错误
  • 它有助于新手理解代码的作用
  • 支持快速代码更改
  • 确保不良代码不会合并到

行动项目

  • 创建接受所有必需参数作为参数的函数,而不是在函数内进行计算。这使得它们更容易测试
  • 如果函数读取函数中的 spark 数据帧,请更改函数以接受数据帧作为参数。然后我们可以传递手工制作的数据帧来测试这些功能。
  • 我们将为每个功能编写一系列单元测试
  • 我们将使用 python 框架,如 unittest、pytest 等。对于单元测试
  • 测试将是代码库的一部分,将确保没有坏代码被合并
  • 我们的 CI/CD 管道将进一步使用这些测试来阻止不良代码的部署

集成测试

集成测试将系统作为一个整体进行测试。它检查所有功能组合在一起时是否工作正常。

很多时候,项目会依赖外部系统,例如,您的 pyspark 代码可能会向 Cassandra 读取/写入数据。我们可以创建集成测试,将整个项目作为一个单元进行测试,或者测试项目在外部依赖下的表现。

解决的问题

  • 它确保整个项目正常运行。
  • 它检测与多个模块协同工作相关的错误。

行动项目

  • 我们将创建一个本地基础设施来测试整个项目
  • 外部依赖可以在 Docker 容器上本地创建
  • pytest 或 unittest 等测试框架将用于编写集成测试
  • 代码将根据本地基础设施运行,并测试正确性

代码林挺

在 jupyter 笔记本上编写项目本质上并不遵循最佳的命名或编程模式,因为笔记本的重点是速度。林挺帮助我们识别 python 代码中的语法和风格问题。

解决的问题

  • 它有助于检测样式错误
  • 强制更好/最佳的写作风格
  • 检测结构问题,如使用未初始化或未定义的变量
  • 让代码更容易使用

行动项目

  • Flake8 或 black 将用于检测逻辑和代码风格的最佳实践。
  • 下一步,Lint 测试将被集成到 CI/CD 中,以使基于不良写作风格的构建失败

代码覆盖率

代码覆盖率帮助我们发现我们通过测试用例测试了多少代码。这是一个很好的质量指示器,可以告知项目的哪些部分需要更多的测试。

解决的问题

  • 监控测试了多少代码。

行动项目

  • 像 coverage.py 或 pytest-cov 这样的工具将用于测试我们的代码覆盖率。

GitHub 回购分支机构权限

我们将设置权限来控制谁可以读取和更新 Git repo 分支中的代码。这将保持我们的主(部署分支)干净,并强制基于拉请求+构建测试的过程将代码合并到主中。

此外,强制同行评审过程和自动化测试可以确保我们的代码库中有更少的错误合并,并且其他团队成员会意识到项目中合并的变更。

解决的问题

  • 主人总是干净的,随时可以部署
  • 强制最佳实践—拉式请求+自动化构建测试
  • 将避免意外删除分支
  • 避免不良代码在主服务器上合并

行动项目

我们将使用以下内容设置分支设置:

  • 主分支不允许重写分支历史记录
  • 没有拉取请求,我们不能在 master 中直接合并代码
  • 将代码合并到主代码至少需要 1 次批准
  • 只有当所有自动化测试用例都通过后,代码才会合并

分支上的自动化测试执行

当我们的拉请求被创建时,在合并之前测试它以避免破坏任何代码/测试是一个好主意。

解决的问题

  • 自动运行测试
  • 避免不良代码在主服务器上合并

行动项目

  • Github 上的 CI/CD 设置。
  • 任何新的分支代码推送都应该触发自动测试
  • 应该在创建拉请求时触发自动测试
  • 如果所有测试都是绿色的,则将代码部署到生产环境中

监控和警报

这是软件工程世界中非常重要的一步,但是对于数据科学项目来说,几乎总是被跳过。我们将监控我们的工作,如果代码中出现运行时错误,我们将发出警报。

取决于你的项目是否仅仅是做预测,你可能不会非常广泛地发出警报,但是如果项目与几个系统对话并且处理大量的数据/请求,从长远来看,进行监控将会使你的生活变得容易得多。

解决的问题

  • 更多的可见性,而不是黑盒代码执行
  • 监控输入和输出处理统计
  • 监控基础架构可用性/依赖性
  • 过去运行失败/成功趋势
  • 当 ML 管道失败/崩溃时提醒我们

行动项目

  • 如果您有一个监视工具(强烈推荐)—将输入/输出统计数据的事件发送到监视器
  • 如果没有可用的监控工具—在日志文件中记录所有重要的统计信息。
  • 如果没有监控工具——我们可以将重要的跑步统计数据添加到数据库中,以备将来参考
  • 构建 Slack/微软团队集成,提醒我们管道通过/失败状态

就这样

这个帖子到此为止。希望这些是有用的提示。请分享您的想法和应用于数据科学项目的最佳实践。

原载于 2020 年 11 月 7 日【https://confusedcoders.com】

工程和数据科学@ travel triangle——构建复杂且可扩展的假日市场(第一部分)

原文:https://towardsdatascience.com/engineering-data-science-traveltriangle-building-complex-and-scalable-holiday-marketplace-9d9e66741ca8?source=collection_archive---------37-----------------------

本博客讨论了由我们的工程和数据科学团队开发的通用和可扩展框架,并让您对工程指南和 culture @ TravelTriangle 有所了解

TravelTriangle 假日产品景观

TravelTriangle(TT)是一个在线度假市场,它将旅行者与多家当地旅行社联系起来,帮助他们打造一个定制的难忘假期。

假期是一个复杂的实体,涉及许多活动的部分。它包括最终确定目的地、城市、航班、酒店、活动、观光、出租车、日期、预算、公司、代理商。对于不同的人来说,所有这些终结都以不同的顺序发生。对于一些预算的最终确定是第一位的,对于其他活动的最终确定。在每一步,都有多个因素参与最终确定。旅行者、代理商、旅游顾问等多个参与者以及多种产品和电话互动增加了额外的复杂性。

由于问题的多方面复杂性,在过去的几十年里,假日销售一直通过电话、电子邮件进行,因为这对旅行社来说是一个非常主观的销售过程。

在 traveltriangle,我们一直致力于为旅行者创造最佳的度假计划和预订体验

技术愿景和通用框架

你可以在此阅读我们解决这一复杂旅游生态系统的整体产品愿景。多个 B2C 和 B2B 产品线(当前和未来)促使我们尽可能地让我们的技术架构松散耦合、高度可配置和有效重用。

此外,作为首席技术官,我一直认为,技术团队应该尽可能地致力于更新的东西,而不只是忙于增强已开发的东西,只是一个功能一个功能地增加。这也有助于我们节俭地开发东西,保持最高的效率,不损害质量,反过来,让非工程团队能够快速移动,并且也是用最少的技术带宽(因为它相当昂贵:)。

考虑到这一点,我们总是将一组功能组合起来,首先在更大的框架上理解,这应该能够无缝地在顶部实现更多的功能,而不需要在每个功能出现时构建它们。事实上,该框架应该可以轻松地扩展到类似的其他产品线。

…通过适当的设计,这些功能很便宜。这种方法是艰巨的,但不断取得成功。—丹尼斯·里奇

以下是我们的工程和分析团队迄今为止构建的几个通用框架,以便灵活高效地实现我们的产品和技术愿景:

可配置和实验框架(CERE)

实现我们的产品愿景的第一步也是最重要的一步是,我们的产品团队如何推出足够多的实验/变化,分析数据并不断搅动实验,以快速排除故障,而不会陷入技术带宽和/或发布周期。实验可以围绕优化当前以及为旅行者和代理商测试新的页面和/或产品流。此外,迫切需要了解用户的心理,通过使用高级 ML 算法的详细数据理解,将他们聚集在一个或另一个细分市场中,并在此明确或派生意图的基础上,触发/测试多种行动,以使旅行者和代理之间的规划周期更快、更有效。

我们设计了一个早期实验方法( blog here ),以使团队能够发布和测试处理高频率用例的新变体。然而,这种方法不能扩展到其他用例,其他用例的频率正在增加,而且,一旦我们在 React+Redux 堆栈上移动页面,这种方法就停止工作了。我们开始在启用实验的任何页面加载上获得闪烁效果。为了避免闪烁,我们搜索了许多解决方案,然后我们在 Nginx、varnish 和我们自己开发的动态 UI 框架的帮助下构建了自己的解决方案,该框架使任何页面都可以拾取组件以及组件中的数据,以动态呈现整页。该框架对于我们的移动和桌面平台是通用的。对于这款应用,由于应用内页面渲染的细微差别,我们不得不做一些调整(完整的博客在此)。

借助 GTM、用于基本 HTML 更改的 VWO 以及与 varnish 和 Nginx 集成的内部动态 UI 框架,我们能够让产品团队测试不同种类的动态生成的前端页面,并运行 A/B 测试以更快、更客观地获得结果。

然而,我们还没有完全达到目标。同样的方法/工具不能用于后端工作流。为了解决这一挑战,我们首先将我们的架构转移到基于事件,这样我们就可以轻松地配置和控制触发器,并在其上关联所需的操作。我们使用 Kafka 在发布/订阅模式上开发了自己的事件流。我们进一步使其可配置和 A/B 测试友好,为此我们在规则引擎和事件驱动架构上开发了 CERE(可配置实验和规则引擎),让产品团队在不需要技术带宽的情况下随时调整和测试不同的后端工作流。

在这一点上,我们的框架已经很好地建立了快速实验,前端和后端的动态流程。利用这一点,我们的产品团队能够改变我们的产品页面和工作流程,引导分配流程,使用不同的沟通渠道等。等等。不需要任何技术带宽和/或发布周期。

面向松散耦合和经济高效的可扩展性的微服务设计

我们的每条产品线(B2B 或 B2C)都会有不同的技术差异和规模增长。例如,面向旅行者的浏览页面需要以极快的速度显示丰富的数据和内容,而事务性页面需要在信息方面更加可靠和一致。内部服务的报告量更大,需要更快的大数据处理,以便团队能够利用实时数据进行分析和决策。需要第三方库存或支付提供商集成的其他系统甚至会有更多不同的细微差别和规模。

资料来源:Oracle.com

微服务方法是我们的大救星。我希望我们一开始就采取了这种方法,但迟到总比不到好。每种服务在各自的方面都有不同的扩展,需要不同的基础设施、不同类型的数据库以及遵循不同的开发指南。此外,它甚至给了我们很大的优势,让我们可以在近期或长期需要更高并发性的地方,从 RoR 到 Golang 重写我们的一些服务。此外,我们能够轻松地从 MySQL、MongoDB 和 Redshift 中选择不同的 SQL/NoSQL 数据库。

当我们大约在 2-2.5 年前开始转向微服务架构时,我们的大多数团队成员都是开发微服务的新手,虽然这看起来非常有利可图,但它也有自己的缺点。

  • 我们必须认识到这样一个事实,我们不是为了中断而分解服务,而是只在必要的时候分解服务。
  • 工作流变得越来越复杂,单个事务现在可能跨越许多服务,并需要更精细的状态和状态转换。
  • 回滚和数据不一致也需要注意,因为现在有多个数据存储。
  • 从测试和部署的角度来看,QA 和 DevOps 团队需要分别发展他们的测试和 CI/CD 方法。
  • 此外,我们必须确保服务发现和服务间通信顺利进行,同时服务本身具有弹性,断路器得到有效使用。
  • 除此之外,还有对通用服务的迫切需求,如认证/授权、API 网关、服务注册等。开始出现(我们仍在通过在原始整体层本身上创建立面层来构建相同的和当前创建的工作区)。

也就是说,从 monolith 转移到微服务在一开始看起来开销很大..:))更不用说,服务器成本的急剧增加,但是,你会在不久的将来看到结果。它将在开发、可伸缩性、故障处理、更好的团队责任分离,甚至在近期节省服务器成本方面带来很多效率。

数据仓库、数据湖和数据建模

任何没有被衡量的东西,都不会得到改进。有多个接触点以及一个供旅行者和代理商与产品/系统互动的平台。需要有一个中央数据储存库。此外,我们还希望使用数百万个数据点,如旅行者浏览、预订、个人资料、通话、电子邮件等数据,向旅行者建议下一个最佳行动项目,以及从过去的数据中可以获得哪些有意义的见解?

TravelTriangle 的核心文化价值观之一是以数据为中心。以下是任何人想到数据湖时都要注意的几个方面,这也符合大数据的 4v(容量、多样性、准确性和速度):

  • 将所有来源的数据收集到一个
  • 验证和三角测量数据的正确性
  • 结构化数据以消除噪音并对其进行处理
  • 对数据进行分析或建模,以获得业务洞察力(大数据的第五个方面——价值)
  • 将洞察力融入系统和/或日常决策中
  • 保持对新品种和新数据量的培训或更新见解

虽然很快会有一个完整的独立博客围绕这一点,我将简单地提及我们在 TravelTriangle 使用的方法、工具和技术,以建立我们自己的数据仓库、数据湖,并培训和部署各种数据模型,以从数据中获取洞察力&为旅行者和代理商实时触发某些行动。

我们使用细分工具以及产品和营销团队使用的外部工具将各种产品线的事件传递到我们的中央数据仓库(RedShift)。然而,对于我们的业务量来说,分段已经变得太昂贵了,因此我们正在用我们内部的实时消息流(“RTMS”)来转换它,以便将事件从任何来源转发到目的地。然而,在“RTMS”整合一个新的目的地并不像在细分市场那么容易,但我们可以接受——现在代替成本,不需要在需要的时候使用高科技..)

此外,我们还开发了一个内部数据管道来同步 MySQL 数据库和 redshift 之间的数据。由于频繁的问题和/或需要定制,AWS 数据管道未能满足我们的期望,因此在使用 AWS DMS 一段时间后,我们选择在内部开发自己的数据管道。我们也尝试了 AWS Glue、AWS data pipeline,但都无法满足我们的实时同步要求。目前,我们使用外部资源,如 FlyData 和 Stitch,但由于我们的数据量每月增长数倍,它们变得相当昂贵。(博客即将推出..)

对于利益相关者的第 2 天报告,我们选择了 Superset 和 Redash。在我们探索过的所有工具中,这些工具满足了我们的大部分需求,而且是开源的。超集中唯一缺少开发的是漏斗可视化,一旦可用,它就可以满足我们所有的需求。我们的工程师还使用各种技术优化技术优化了 Superset 和 Redash,以支持 5 倍的请求和从 10 秒到 1 秒的响应时间,以及长达 3-4 秒的少量繁重报告。我们现在正在为我们测试和集成 druid、PySpark 和类似的大数据工具,以决定一个并将其与我们的主要应用程序集成,以便更快地处理大数据。

在 TravelTriangle 上集中数据,并能够向我们的团队显示实时报告以执行日常分析后,我们开始为我们的业务用例开发和培训数据模型。一个这样的例子是动态线索评分,它必须是我们帮助代理有效地确定其线索优先级的实时基础。我们目前使用 EMR 来处理模型,并将我们的应用程序与 Kafka 集成在一起

通信/通知层(Sandesh)

通知是任何系统不可或缺的一部分,无论是促销系统还是交易系统。我们知道它必须是全渠道的,因此应该快速集成任何新的通信渠道/ API。此外,该流程需要高度可配置、可重用以及与任何其他微服务无缝集成(通过事件或 API)

“Sandesh”,我们在这里称之为通知服务,负责不同的交互媒介,可以是短信、IVRs、电子邮件、WhatsApp 或推送通知。通过集成一个映射层和提供者 API,还可以灵活地添加另一种通信媒介。

由于这项服务需要高并发性和 IO,我们还必须实现一般的速率限制、突发处理以及队列管理系统。基于前面提到的实验框架构建的通知模板引擎为产品团队提供了非常高的灵活性,可以根据通知类型和时间 A/B 测试他们的消息以及不同媒体的性能,而且也不需要技术带宽和/或新版本。

此外,我们还创建了数据事件来监控和分析不同媒体上每条消息的发送率、打开率(短信除外)以及点击率,所有这些都存储在我们的中央数据仓库中,以便从中进行分析并得出有意义的见解。

我们的促销活动目前通过外部工具 WebEngage 进行管理,但是,我们正在将活动管理器与我们的通知服务和实验框架进行内部集成。

虽然这篇文章提到了一些与我们的技术愿景和路线图一致的框架,但第二部分将告诉您更多的框架,以及我们的 QA 和 DevOps 团队为提高发布质量和周转时间而构建的框架。

发生了很多有趣的事情@ TravelTriangle。如果您需要了解更多细节,请告诉我们,或者发送电子邮件至 lead_on@traveltriangle.com,与我们一起亲眼见证,同时解决更具挑战性的问题,打造世界级的度假 B2C 和 B2B 生态系统。

如果你知道你的网络中有人可能对解决这些问题感兴趣,请分享这篇文章。

如果你喜欢这篇文章,就去喜欢和/或鼓掌,这样别人可能会偶然发现这篇文章。

【https://www.linkedin.com】最初发表于

学习的工程机器

原文:https://towardsdatascience.com/engineering-machines-that-learn-d4beb34dfa80?source=collection_archive---------34-----------------------

软件工程与基于 ML 的软件系统开发的相关性

我们正在通过调查开发包含 ML 组件的软件系统的最佳实践来研究机器学习工程的新兴学科。在本文中,我们分享了研究动机和方法、一些初步结果,并邀请大家参加我们关于 ML 工程最佳实践的 7 分钟在线调查

照片由 Franck V. 在 Unsplash 上拍摄

机器学习是新一波人工智能的关键

不可否认,人工智能(AI)正在经历一波新的关注、能量和极高的期望。这一浪潮是由我们互联的数字社会产生的大量数据以及巨大计算资源的低门槛可用性所驱动的。

在各种人工智能技术中,机器学习(ML)尤其扮演着关键角色。

当前人工智能的激增是由机器学习推动的,根据谷歌趋势对搜索词的相对兴趣表明了这一点。

从例子中学习复杂行为

机器学习允许我们解决复杂的问题,不是通过费力地编写新代码,而是通过让一个现有的算法从例子中学习新的行为。我们正在见证图像识别、语音处理、医疗诊断、证券交易、自动驾驶、产品设计和制造等领域的突破性成果。

机器学习是否取代编程?

机器学习的快速崛起是否意味着软件系统将不再需要编程?我们会需要数据科学家而不是软件开发人员吗?

对于那些经历过与软件相关的项目延迟、系统中断和无限期不完整特性集的人来说,一个没有程序员的世界可能看起来很有吸引力。

机器学习需要编程吗?

但没那么快。机器学习将而不是取代编程,而是使软件工程学科更加丰富和复杂,这有几个原因。

  1. ML 算法本身是需要开发、测试和维护的软件。
  2. 使用 ML 算法需要编程,用于接收、清理、合并和增强数据的任务,用于将数据输入 ML 算法,用于运行重复的训练实验以生成、评估和优化 ML 模型,以及用于在生产系统中测试、集成、部署和操作 ML 模型。
  3. 经过训练的 ML 模型只是构建复杂软件系统的一个构件。

那么,有什么不同呢?

尽管如此,机器学习的一些具体特征对传统的软件开发实践提出了挑战。对于涉及机器学习组件的应用程序,要管理的数据量通常要大得多。开发过程倾向于包括更多的快速循环实验,在这些实验中,替代解决方案被例行地尝试、比较和丢弃。并且最终产品中固有的不确定性水平更高。

机器学习工程师的出现。根据谷歌趋势对搜索词的相对兴趣。

ML 工程

在全球范围内,许多组织正在逐步学习如何开发包含 ML 组件的软件系统。随着越来越多的人自认为是 ML 工程师,机器学习工程学科正在兴起。这引发了有趣的问题:

  • ML 工程和软件工程有区别吗?还是一个是另一个的子学科?
  • 当用 ML 组件构建软件系统时,已建立的软件工程最佳实践同样适用吗?或者这些最佳实践需要修改或替换吗?
  • 一套规范的 ML 工程最佳实践能够被识别出来,从而指导从业者并教育新人吗?

调查 ML 工程实践

为了调查这些问题,软件工程和机器学习领域的研究人员已经合作。

我们已经开始广泛回顾的科学和流行文献,以确定从业者和研究人员描述和推荐了哪些实践。这些实践的范围从数据管理(例如,如何处理大型数据集的存储和版本控制),到模型训练(例如,如何运行和评估训练实验),再到操作(例如,如何部署和监控训练模型)。

组织成实践团体的 ML 工程的方面。

调查 ML 工程实践的采用

然后,我们在用 ML 组件构建软件的团队代表中进行的调查中嵌入了确定的实践。本次调查目前正在进行中, 向新参与者 开放(见下文)。在撰写本文时,大约有 200 个团队参与其中。早期的结果表明,较大的团队倾向于采用更多的工程实践。

我们关于机器学习团队采用工程实践的全球调查的早期结果。较大的团队倾向于采用更多的实践。

还有,早期的结果告诉我们,有些实践被广泛采用,可以被认为是*,而另一些实践只被更大组织中更有经验的团队应用,可以被认为是*。**

更高级实践的一个例子是使用所谓的自动化机器学习技术,团队能够以自动化的方式进行模型选择和超参数优化。早期调查结果表明,与非科技公司和政府相比,这些技术在科技公司和(学术)研究实验室中的采用程度要高得多。

我们关于机器学习团队采用工程实践的全球调查的早期结果。与非科技公司和政府组织的团队相比,科技公司、大学和非商业研究实验室的团队往往会更多地利用自动化机器学习技术。

迈向 ML 工程最佳实践目录

我们正在利用调查结果将最佳实践整理成一个全面的目录。在目录中,每个 ML 工程实践都被记录在一个统一的结构中,就像过去的设计模式重构一样。

该结构的要素包括实践的意图动机,在各种环境中的适用性,与其他实践的相互依赖性,以及如何应用该实践的简短且可操作的描述。我们还提供参考文献和支持工具。

使用调查结果,我们还能够量化每个实践的难度。这有助于我们将它们按照从基础高级的难度级别进行分类,指导团队优先采用它们。

我们的最终目标是,最终的目录将有助于 ML 工程团队的形成和有效性,不仅在 ML 工程已经得到广泛采用的大型技术公司,而且在较小的非技术组织中。

参加调查!

如果您是构建包含机器学习组件的软件的团队的一员,请通过参加我们的调查来帮助我们**。**

拿调查:【https://se-ml.github.io/survey/】

Joost Visser 是莱顿大学软件和数据科学教授。此前,Joost 在软件改进小组担任过各种领导职务。他是许多关于软件质量和相关主题的出版物的作者。

合作霍尔格·霍斯柯恩·范德布鲁姆 **

更多信息请咨询 SE4ML 项目网站

这篇文章的早期版本发表在Bits&Chips中。

** [## SE-ML/awesome-seml

涵盖构建机器学习(ML)的软件工程(SE)最佳实践的文章精选列表…

github.com](https://github.com/SE-ML/awesome-seml/blob/master/readme.md)**

使用工具提示页面增强电源 BI 报告

原文:https://towardsdatascience.com/enhance-power-bi-report-with-tooltip-pages-3ae472b43e2?source=collection_archive---------44-----------------------

了解关于工具提示页面如何增强您的 Power BI 报告的各种技巧

Salvatore Ventura 在 Pexels 上拍摄的照片

Power BI 是一个很棒的工具(我知道你也意识到了)。我最喜欢它的一点是,它提供了许多可能性,可以使用一些简单的技术来增强您的报告,并为您的用户创造无与伦比的体验。

在我之前的文章中,我分享了 5 个简单的技巧来提高你的 Power BI 开发过程。由于只包括了五个,我最喜欢的技术之一没有在那里找到位置,因为我已经决定为此专门写一篇文章。

最酷的技巧之一是创建工具提示报告页面。只需几分钟的时间,您就可以让您的用户更加灵活地浏览数据窗口。

默认提示

我已经使用 Contoso 数据集创建了一个简单的报告。默认情况下,当您将鼠标悬停在数据栏上时,您将看到特定数据部分的数字:

在这里,您可以看到 2009 年 6 月的销售额约为 8200 万英镑。

自定义工具提示

比方说,我想让我的用户有机会通过将鼠标悬停在数据栏上来快速获得对底层数据的更好的概述。

第一步是通过单击“+”号创建一个新的报告页面。

在新创建的页面的格式部分,我们需要应用一些设置来使这个页面成为工具提示页面。在“页面大小”菜单下,选择“工具提示大小”,而不是默认的 16:9。

然后,在“视图”选项卡的“页面视图”下,我选择“实际大小”,这样我就可以创建“实际”大小的可视化效果,因为它将显示在主报表页面上。

我已经将我的工具提示报告页面重命名为工具提示 1(当然,您应该给它一个更有意义的名称,尤其是当您处理多个工具提示页面时)。在这个页面上,我放置了一个显示总销售额的卡片和一个显示销售额排名前 5 的地区的聚类条形图。我还隐藏了这个页面,这样用户打开报告时就看不到它了。

最后一步是“告诉”Power BI 我打算将这个页面用作工具提示。因此,在页面信息下,我将工具提示切换为开:

现在,让我们切换回主页。在“格式”窗格下,有一个工具提示菜单。您只需要在 Type 下选择报告页面,并在 page:

就是这样:现在,当用户悬停在特定的数据栏上时,他可以立即看到向下钻取的数据,如我们的工具提示中所定义的!

2009 年 6 月的工具提示数据

2009 年 8 月的工具提示数据

让它成为你自己的…

除了默认的工具提示页面大小(320x240px),您还可以创建自己的工具提示页面大小。不要选择“页面大小”下的工具提示,只需选择“自定义”并输入您想要的值。我已经创建了一个工具提示页面 Tooltip 2,并将大小改为 328×200 像素。它只是显示每种产品颜色的销售额,所以现在当用户将鼠标悬停在产品上时,他将看到所选产品每种颜色的数字:

这样,我就能看出 2009 年 Adventure Works 品牌的最大销售额来自哪种颜色。

最后,您可以在工具提示页面上指定工具提示字段。这意味着您的报告中引用指定字段的每个可视内容都将显示您的工具提示页面,而不是默认的 Power BI 工具提示。

现在,如果我返回到主报告,并将自动选项作为工具提示报告页面,任何显示销售额度量的可视化工具都将显示我定制的工具提示!多酷啊!

因此,当我将鼠标悬停在品牌名称上时,我将获得销量和前 5 名地区:

带有动画工具提示的专业级

最后一项技术是真正的专业水平,并归功于来自 Exceleratorbi 的 Jason Cockington,他详细解释了这一点。总之可以添加 GIF 作为工具提示!这非常有用,因为许多用户并不了解所有 Power BI 功能,需要某种指导才能充分利用报告。

最常见的情况之一是,当您在报表中创建钻取页面时,您的用户并不知道它,或者根本不知道如何访问它。所以,我创建了一个 GIF(网上有很多免费的 GIF 创建者,这个就是其中之一)展示了从主页面表格到每个品牌销售额详细概览的钻取操作步骤。

在你创建了一个 GIF 之后,之前在这篇文章中解释的所有步骤都是一样的。唯一的区别是,您应该将 GIF 设置为背景图像,透明度为 100%,并将 Image Fit 属性设置为 Fill,而不是将 GIF 作为图像放在工具提示页面上:

接下来,在主页表格上,我打开了可视标题工具提示图标:

最后,在可视标题工具提示下,我定义了新创建的工具提示页面(在我的例子中它被称为 GIF 工具提示)。

因此,现在当某人将鼠标悬停在一个小问号图标上时,他会看到如何执行钻取操作的动画说明。厉害!

结论

报告页面工具提示是一个非常强大的功能,它们可以丰富你的报告。但是,使用它们时要小心,尤其是当您的报表包含许多视觉效果时,因为渲染时间的增加会导致性能下降。

至于 Power BI 中的任何其他技术:尝试在用户体验增强和关于报告性能的额外开销之间找到正确的平衡。

成为会员,阅读 Medium 上的每一个故事!

订阅这里获取更多有见地的数据文章!

什么是 Python 类,你如何使用它?

原文:https://towardsdatascience.com/enhance-your-python-project-code-with-classes-5a19d0e9f841?source=collection_archive---------1-----------------------

了解 Python 的类机制

克里斯里德在 Unsplash 上的照片

W 在从事数据科学项目或任何 Python 编程项目时,你很可能会发现自己使用了大量自制的函数和变量。为了简化项目过程,您甚至可能已经创建了一个完整的脚本,其中包含了您创建的函数。

这些函数可以用于代码中的许多事情。从清理数据帧到训练机器学习模型。创建大量的函数来组织你的 Python 代码是很有用的,但是还有另一种方法可以让你的代码看起来和行为起来更像样——通过使用 Python

什么是 Python 类?

Python 类就像是创建新对象的大纲。对象是您在处理代码时希望操作或更改的任何东西。每当一个类对象被实例化,也就是当我们声明一个变量时,一个新的对象就从零开始。只要需要,类对象可以反复使用。

示例:约会档案

在我们的案例中,在我们以前的文章中,我们一直在撰写一系列关于创建约会算法的文章,该算法通过使用机器学习对约会档案进行聚类和分类。看这里:

[## 我用机器学习和人工智能做了一个约会算法

为约会应用程序利用无监督机器学习

towardsdatascience.com](/dating-algorithms-using-machine-learning-and-ai-814b68ecd75e)

在上面的文章中,我们经历了数据预处理的整个过程,以便让我们的数据变得对人工智能友好,例如将约会简档转换为一组数字。对象,在本例中为,是为了让所有这些发生而需要操作的约会配置文件。

这个数据预处理步骤是通过使用许多函数来实现的。它不是以最好的方式组织的,但是它完成了工作。然而,我们可以通过利用 Python 类来改进这个过程。

在这里注册一个中级会员,可以无限制地访问和支持像我这样的内容!在你的支持下,我赚了一小部分会费。谢谢!

约会档案的类别

为了学习更多关于类对象和利用它们,我们将为我们的人工智能约会算法实现一个类对象。让我们将我们使用的代码组织和整理成一个类对象。

类对象用途

首先,我们必须问自己——我们希望这个类对象做什么?我们希望它:

  1. 创建新的约会档案。
  2. 将新的个人资料添加到更大的约会个人资料池中。
  3. 对简档进行缩放或矢量化,以使其对机器学习模型友好。

基本上,我们希望它将整个数据预处理步骤浓缩到一个类对象中,然后我们可以将它用于我们希望添加的每个新的约会配置文件。每当我们需要创建一个新的约会档案时,我们都可以使用这个类对象。

构造一个类

在创建类之前,我们建议您导入必要的库。在我们的课程中,我们将使用以下库来格式化新的约会配置文件:

import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.preprocessing import MinMaxScaler

首先,为了创建一个类对象,您只需键入以下内容:

class CreateProfile:

类的名字是主观的,但是关于名字格式的一般规则是遵循一个叫做 [的东西。这是我们的类对象的开始,我们将从这里开始构建。](https://en.wikipedia.org/wiki/Camel_case#:~:text=Camel%20case%20(stylized%20as%20camelCase,iPhone%22%20and%20%22eBay%22.)

在类中,切换到开始定义我们的第一个函数。通常,当创建一个类时,你必须定义一个名为__init__的函数,以self作为初始参数。

class CreateProfile:def __init__(self):

什么是__init__”功能?

当一个类被实例化时,一个__init__函数被调用。通过实例化,我们指的是当你声明一个类的时候,它可以自己发生,也可以通过把它赋给一个变量来发生。以下是实例化类对象的一些快速示例:

CreateProfile()# ORprofile = CreateProfile()

这里我们正在实例化类对象,通过这样做,我们隐式地调用了__init__函数。在实例化类对象时,__init__函数中的任何参数也将是相同的参数。这些初始参数可以是我们希望在整个类对象中操作的数据。但是对于self参数,在实例化类对象时没有必要替换。

什么是“自我”?

self参数只会在构建 Python 类时出现。它在整个类中使用,通常是在该类中创建的任何函数的第一个参数。但是,无论何时实例化后使用类对象,self都不会是你需要填充的参数。

self参数是一个隐式参数,当实例化该类或者在该类中使用自定义函数时,总是会调用这个参数。self指的是它正在操纵的对象。在我们的例子中,我们希望创建新的约会资料。

使用“自我”

为了进一步理解self的用法,我们将继续构造我们的类。让我们填写一些我们的__init__函数将采用的其他参数:

class CreateProfile:def __init__(self, dataset=None,profile=None): self.dataset = datasetself.profile = profile

正如你在这里看到的,我们在self后面添加了一些参数。这些论点现在是空的,但我们将使用熊猫数据框架来创建一个新的约会档案。为了在整个类中使用这些 DFs,我们必须将它们分配给对象或self,稍后我们将使用函数对其进行操作。

类别属性

当在我们的__init__中分配这些 DFs 时,我们有效地创建了类属性。在实例化类之后可以调用它们,它们将返回我们分配给对象的任何变量(self):

# Instantiating the class
new_profile = CreateProfile()# Calling the class attribute
new_profile.dataset 

这将返回我们在实例化该类时提供的任何数据集。在这种情况下,运行这段代码将不会返回任何内容,因为None是在__init__函数中建立的默认参数。

我们也可以运行new_profile.profile来返回我们正在创建和操作的概要文件。这个创建的配置文件现在将是空的,但是我们将使用新的信息填充它,并通过使用我们稍后将构造的类中的一些自定义函数来格式化它。

为了进行下一步,让我们建立所有的类属性来创建我们最终的__init__函数。我们将需要它们用于类中未来的自定义函数:

在这里,我们为新的概要文件添加了更多的条件和更多的属性,供以后使用

类方法(函数)

我们在类中创建的函数被称为方法。函数和方法本质上是一样的,但是在类对象的上下文中,函数被称为方法。为了操作和利用给定的数据,我们需要为我们的类创建一些方法。

在这种情况下,我们将使用我们之前创建的日期配置文件的合成数据集。参见以下文章,了解该数据集的创建:

[## 我为数据科学制作了 1000 份假的约会资料

我如何使用 Python Web Scraping 创建约会档案

towardsdatascience.com](/generating-fake-dating-profiles-for-data-science-cd3b929972bc)

该数据集将为我们提供创建新约会档案的背景。

使用类方法创建新的约会配置文件

我们希望我们的类做的第一件事是创建一个全新的概要文件,如果它还没有提供的话。为此,我们可以在__init__方法下创建一个新方法:

class createProfile:def __init__(self, dataset=None,profile=None): self.dataset = datasetself.profile = profile # Here we add another functiondef enter_info(self):# Code goes here

如你所见,我们仍然在使用self参数。当我们键入下面的代码时,我们将需要它:

上面的方法在整个代码中都使用了self。当我们使用self.profile时,我们指的是我们在__init__方法中分配的属性。首先,我们检查它是否是一个空的数据帧,它确实是。接下来,我们将使用在__init__方法中分配的self.dataset变量,并使用它的特性来创建新的概要文件。

我们允许选择使用更大数据集中的随机信息来填充新的配置文件,或者手动输入信息。在输入配置文件信息之后,方法用新的配置文件信息覆盖属性。如果您试图再次运行这个方法,它将返回字符串:"概要文件中已经包含的数据。

如果你想输入新的信息,你必须重新初始化这个类,然后从头再运行一次。实例化该类将从头开始整个过程。

运行类方法

下面是我们如何从实例化步骤开始运行该方法:

# Instantiating with the data from the DF of synthetic profiles
new_profile = createProfile(dataset=data)# Running the method
new_profile.enter_info()

这正是我们所需要的。只有两行代码。当我们运行它时,它要么为配置文件输入随机信息,这是函数的默认行为,要么提示我们手动输入信息,如下所示:

对于每个需要信息的功能,都会出现此提示

无论哪种方式,class 方法都将创建一个全新的概要文件,供我们以 DataFrame 的形式操作:

新的约会档案

更多类方法

对于我们来说,创建一个全面的类,它必须做的不仅仅是创建一个新的约会配置文件。在这种情况下,我们将添加之前在__init__方法中提到的方法。下面是我们将添加到类中的方法,以使用我们的新概要文件:

我们的类中将要用到的其余方法

解释每种方法

类中的每个方法都执行特定的功能。给定在self中创建的属性,这些方法将用每个方法的结果值替换类的属性。

  • add_profile_to_dataset() —此方法假设已经有一个包含信息的约会档案。它将比较来自剖面图和更大数据集的要素,以查看它们是否匹配。如果它们匹配,那么它会将新的配置文件添加到数据集中,并返回添加了新配置文件的更大的数据集。否则,它会通知用户数据集的要素与剖面图的要素不匹配。
  • vect_text() —对于新的概要文件数据,该方法实例化CountVectorizer()来为概要文件的 Bios 中使用的每个单词创建一个数字数组。然后它创建一个数字数组的 DF 并返回它。
  • scale_profile() —给定新的轮廓数据,该方法使用适合更大轮廓数据集的MinMaxScaler()来缩放新的轮廓数据。此外,在该方法的参数中,有一个不进行缩放的已排除要素或列的列表。然后,它使用self.scaled_profile属性,并用一个包含缩放值的新 DF 重新分配它,并返回那个 DF。
  • format_profile() —这种方法基本结合了前面两种方法:vect_text()scale_profile()。如果运行这两个方法返回的属性已经存在,那么它将连接两个 DF 并返回结果 DF。如果没有,那么它仍然运行这些方法,并返回两个 DFs 的连接结果。

运行每个方法与之前运行enter_info()方法相同:

# Running each method after having ran enter_info()
new_profile.add_profile_to_dataset()new_profile.vect_text()new_profile.scale_profile()new_profile.format_profile()

查看类属性

现在我们已经运行了类中的所有方法,我们可以通过查看每个方法使用的新类属性来检查结果。

# Running each attribute to check their results
new_profile.combined_df.tail(5)new_profile.vectorized_textnew_profile.scaled_profilenew_profile.formatted_profile

如果您运行这段代码,您将能够看到每个方法处理的类属性以及它们的最终结果(按顺序*):*

每个属性的结果(从上到下):组合 _df、矢量化 _text、缩放 _profile、格式化 _profile

正如您所看到的,新的概要文件有一个索引值 6600 ,并且显示了每个方法如何操作它。我们现在可以随时引用类中的每个属性,它将包含这些结果。

导入类

在创建一个类时非常有用的一点是,我们可以将我们创建的类导入到其他 Python 文件或笔记本中。只需将 Python 类保存在一个.py文件中,您可以在以后导入它。只要确保它在同一个目录中。您可以像导入任何其他 Python 库一样导入该类:

from your_file_name import CreateProfile

现在,您可以随时使用 Python 类,而无需复制/粘贴代码。

关闭

使用类来简化我们的数据预处理步骤对于任何开始数据科学项目的人来说都是非常有用的。在我们的例子中,我们需要一种方法来处理新概要文件的创建和格式化。Python 的类的伟大之处在于我们可以随时重用它。如果我们想添加另一个约会配置文件,那么我们所要做的就是实例化另一个类对象。这可以继续下去,直到我们对新创建的配置文件的数量感到满意。

总的来说,类对象可以用来在编码项目中组织代码。这里我们只讨论了 Python 类的基础知识,还有一些概念需要学习。如果你想了解更多关于 Python 的类,那么 点击 这里

如果需要,可以查看下面参考资料中的 Github 以获得完整代码。到目前为止,您可能已经看到了为您的项目创建 Python 类的价值。

资源

[## Marcos an 93/人工智能媒婆

使用无监督机器学习和 NLP - marcosan93/AI-Matchmaker 的匹配简档

github.com](https://github.com/marcosan93/AI-Matchmaker) [## 我用机器学习和人工智能做了一个约会算法

为约会应用程序利用无监督机器学习

towardsdatascience.com](/dating-algorithms-using-machine-learning-and-ai-814b68ecd75e) [## 我为数据科学制作了 1000 份假的约会资料

我如何使用 Python Web Scraping 创建约会档案

towardsdatascience.com](/generating-fake-dating-profiles-for-data-science-cd3b929972bc)

为极具竞争力的公司增强车辆路线和车队优化

原文:https://towardsdatascience.com/enhanced-vehicle-routing-fleet-optimization-for-ultra-competitive-companies-9349d7e0bdf0?source=collection_archive---------44-----------------------

企业可以削减与“最后一英里”相关的供应链成本。图片来自 Pixabay 的 wiggijo 。

所谓的“最后一英里”会导致整个供应链成本的 30%,这使得它成为创新新技术的主要目标。

众所周知,车辆路线问题很难解决,但近年来,大量路线优化服务涌现出来,有望提高效率和降低成本。

问题是,

所有的路线优化系统都是平等的吗?

绝对不行。

解决相对平凡的日常问题的巨大复杂性迫使路线规划系统走捷径。虽然它们提供的解决方案比您手工或使用简单的路线优化软件所能实现的更好,但您仍有可能获得更好的结果。

一个只有一辆车和 50 个站点的简单路线优化问题的排列比太阳中的氢原子多 3000 万倍。

如果与送货和取件相关的运输成本占了您成本的很大一部分,那么您需要将这些整合到您的系统中(我们将通过一些例子来说明为什么需要这些功能,以及您从拥有这些功能中获得的竞争优势)。

基本车队优化要求

为了确保您的业务尽可能简化和高效,任何优化都必须考虑以下影响成本和执行能力的条件:

  • 满足固定的时间&距离相关成本 ( 仅使用时间或距离成本可能导致次优结果,因为只有一半的真实成本生成器被考虑)
  • 考虑车辆的容量类型和限制 ( 使用一条最佳路线是没有意义的,这条路线要求车辆运送远远超过它所能承载的东西,或者装载它所不能承载的东西——比如冷冻食品
  • 允许在行程中及行程之间进行提货和交货 ( 即从该地点提货并将其交付至该地点,或将其带回仓库
  • 允许在一天内多次往返停车场 ( 在再次出发之前,必须允许车辆返回停车场补充货物
  • 满足位置的灵活时间限制(即包裹必须在上午 11 点之前到达,或者取件时间必须在下午 2 点到 4 点之间)
  • 考虑车辆限制 ( 即本次取货需要冷链车,或者本次交付需要多人搬运等

无论您使用的是第三方基于网络的系统、路线优化 API 还是集成到车队跟踪中的路线优化系统,上述列表都代表了对实际的“黑盒”数字处理后端至关重要的功能,该后端可为您的业务提供优化的交付时间表。

增强的路线优化优势

除了避免不必要的长途旅行之外,还有许多不太明显的好处,不仅可以降低路上的成本,还可以提高整个组织的效率(在车辆离开停车场之前*)。*

利用时间和距离成本因素提高效率

现实世界的路线规划必须考虑与您的车队相关的一系列成本,以便根据车队的具体特征准确描绘最佳解决方案。

任何只考虑距离或时间的系统(而不是两者都考虑)都无法计算出最佳可能的解决方案,因为它忽略了一半的成本生成因素。

考虑以下场景,其中一辆车的距离成本较高,而另一辆车的时间成本较高。

路线优化时间表由 Optergon 提供

您希望解决方案是什么样的?一个不考虑这两种成本的系统不可能给出答案。

这是结果。

基于最佳时间和距离成本的解决方案由 Optergon 提供

具有较高距离成本的车辆选择了保持其距离最小的路线(尽管它最终在路上花费了更长的时间,而具有较高时间成本的车辆行驶得更远(但是用了更少的时间)。

对于在市区和大城市运营的公司来说,同时计算时间和距离的基于成本的路线优化绝对至关重要。

增强的虚拟车队优化

用更小、更轻、更便宜的车来完成接送会更好吗?还是用载重量更大的车会更有效率?

较小的车辆可能必须返回到车厂,并做多次旅行,花费更长的时间,走得更远。这比更大、更贵、载重量更大的汽车更好还是更差?

多行程最佳路线由 Optergon 提供

试错是一项相当昂贵的工作,因为你至少要租用和运行不同的车队来比较它们的成本。

有了路线规划,你可以输入你的车辆的虚拟版本,对照历史时间表运行,看看从长远来看哪个最终更便宜。

虚拟测试不同的车队(及其相关的成本和容量限制)要快得多,也便宜得多,最终意味着你会购买和维护尽可能最便宜的车队。

关键业务洞察力

假设您的业务正在快速增长,因此您需要扩大车队以满足不断增长的需求。

为了便于讨论,让我们假设你一天在 3 个邻近的城镇完成超过 300 次送货,并想购买 3 辆新车。

你真的需要三个吗?还是两个?或者任何?

知道如何更有效地利用你所拥有的可能会带来一些令人惊讶的见解。

在扩张(以巨大的成本)之前,使用现有车队对历史交付进行路线优化。

优化的路线可以很好地表明,不仅昂贵的车队扩张和就业活动(雇用新司机)是不必要的,而且你可以实际减少你的车辆数量,仍然履行所有义务。

提高竞争力

良好的交付计划不仅能降低成本,还有一个额外的好处,那就是它能告诉你某件事情是否有可能实现。

如果您今天安排了 100 次提货和交付,有 5 辆车可用,您如何知道在没有运行全面的交付计划优化的情况下是否有可能呢?

100 个位置,5 条车辆路线优化由 Optergon 提供

通过预先运行优化,可以了解您的预期工作负载实际上是否可行——考虑到您业务的实际限制。

这可以帮助你变得更有竞争力,因为它允许你比竞争对手更好地计划,竞争对手可能:

  • 承担比他们能提供的更多的工作——最终惹恼客户和顾客
  • 为了安全地完成他们的订单,所承担的远远少于他们的资源所允许的

额外的组织效率

考虑到车队车辆的容量限制,提前了解最佳配送路线会带来额外的优势。

您现在还知道哪些车辆正在交付什么,更重要的是,它们执行这些交付的顺序。

与您的仓库人员分享这些路线可以让他们更好地计划、储存和包装仓库和车辆,从而在车辆离开仓库之前降低成本并进一步简化流程。

更好的沟通

你有多少次等着公司上门取货或送货,甚至是上门提供服务,却被告知“我们会在周一或者周二的某个时候到那里”。

这并不理想——但是公司通常没有能力明确他们什么时候到达。

通过提前优化路线,你可以确定地知道(不包括不可抗力事件)司机将在什么时候到达他们计划中的每个地点。

这让你的组织有能力告诉客户类似这样的话,“我们将在周一 11:45 到达。

更好的服务和体验。

对于大中型企业来说,确保您拥有所有必要的功能可以大幅降低成本,这远远超出了您已经从更基本的车辆路线、交付计划或路线优化系统中获得的成本。

用实体嵌入增强分类特征

原文:https://towardsdatascience.com/enhancing-categorical-features-with-entity-embeddings-e6850a5e34ff?source=collection_archive---------10-----------------------

首先,我们来谈谈卖啤酒

假设你是一家酒馆的老板,你想根据两个变量来预测你的店在某一天要卖多少啤酒:星期几和当前天气。我们可以在某种程度上想象,与一周开始和寒冷的日子相比,周末和温暖的日子会卖出更多的啤酒。

面对这个问题,我们通常首先将我们的分类数据(在这个例子中,星期几和天气)编码成虚拟变量,以便为我们的分类器提供输入,而在现有的分类值之间没有任何层次。

对于一周中的某一天功能,我们的数据如下所示(对于天气功能,您可以想象类似的情况):

但是这真的有意义吗,将每个分类值视为彼此完全不同,例如当使用一个热编码时?或者我们可以利用某种技术来“学习”每个可能值和我们的目标变量之间的关系和内在联系吗?

实体嵌入拯救

考虑到这个给定的场景,我们可以继续采用 NLP(自然语言处理)领域中众所周知的技术作为实体嵌入,这允许我们将给定的特征集映射到一个具有较少维数的新特征集中。在我们的例子中,它还允许我们从分类数据中提取有意义的信息。

实体嵌入的使用基于用分类数据训练神经网络的过程,目的是检索嵌入层的权重。与单一的热编码方法相比,这允许我们有更重要的输入。通过采用实体嵌入,我们还能够缓解两个主要问题:

  • 不需要领域专家,一旦我们能够训练一个神经网络,它可以有效地学习模式和相同分类特征的值之间的关系。这导致避免了特征工程步骤(例如手动给一周中的每一天或每种天气赋予权重);
  • 计算资源的缩减,一旦我们不再用一次热编码来编码我们可能的分类值,这可能意味着巨大的资源使用。假设您有一个包含一万个可能唯一值的分类特征。这将转化为具有相同数量的空位置的特征向量,仅仅表示给定值。

实体嵌入的定义

嵌入层相当于一个神经网络层,它将具有相似输出值的分类值分组到一个 N 维空间中。这种空间表示允许我们获得每个分类值的内在属性,这可以在以后用作旧的虚拟编码变量的替代。如果我们以一种更简单的方式来考虑它,这将意味着一周中具有相似产量(在我们的例子中,是售出啤酒的数量)的日子将彼此接近。如果你不明白,也许一张图可以帮助你:

在这里,我们可以看到我们有四个主要组:组 1,周一和周二,可能与低销量的啤酒有关,因为这是一周的开始;第二组,周三和周四,与第一组有一段距离;第 3 组,星期五和星期六相对接近第 2 组,表明它们比第 1 组显示出更多的相似性;第四组是周日,与其他组相比没有太多相似之处。这个简单的例子可以向我们展示嵌入层可以从现实世界中学习信息,比如最常见的外出和喝酒的日子。很酷,不是吗?

把它和 Keras 放在一起

首先,我们需要知道,为了使用嵌入层,我们必须指定我们希望用于给定嵌入的维数。正如您所注意到的,这是一个超参数,应该逐个案例地进行测试和实验。但是作为一个经验法则,您可以采用维度的数量等于类别的唯一值的数量的平方根。所以在我们的例子中,我们对一周中某一天的表示不是七个不同的位置,而是三个位置(四舍五入)。下面我们给出了两个提到的特征的例子,并在我们的模型中添加了一些隐藏层,以便有更多的参数来捕捉细微的数据差异。

# Embedding layer for the 'Day of Week' feature
n_unique_day = df['Day'].nunique()
n_dim_day = int(sqrt(n_unique_day))input_week = Input(shape=(1, ))
output_week = Embedding(input_dim=n_unique_day, output_dim=n_dim_day, name="day")(input_week)
output_week = Reshape(target_shape=(n_dim_day, ))(output_week)# Embedding layer for the 'Weather' feature
n_unique_weather = df['Weather'].nunique()
n_dim_weather = int(sqrt(n_unique_weather))input_weather = Input(shape=(1, ))
output_weather = Embedding(input_dim=n_unique_weather, output_dim=n_dim_weather, name="weather")(input_weather)output_weather = Reshape(target_shape=(n_dim_weather,))(output_weather)input_layers = [input_week, input_weather]
output_layers = [output_week, output_weather]model = Concatenate()(output_layers)# Add a few hidden layers
model = Dense(200, kernel_initializer="uniform")(model)
model = Activation('relu')(model)model = Dense(100, kernel_initializer="uniform")(model)
model = Activation('relu')(model)# And finally our output layer
model = Dense(1)(model)
model = Activation('sigmoid')(model)# Put it all together and compile the model
model = KerasModel(inputs=input_layers, outputs=model)
model.summary()opt = SGD(lr=0.05)
model.compile(loss='mse', optimizer=opt, metrics=['mse'])

从图形上看,我们的神经网络将具有以下表示形式:

就是这样!我们可以看到,我们的架构最初由每个分类值的输入层组成,接着是嵌入层,然后是整形层。然后全部放在一起。最后,我们添加一些隐藏层来捕捉任何额外的信息。

以 0.05 的学习率训练我们的网络 200 个时期,我们可以看到损失和均方误差的一些相当好的结果:

结论

在这个简单的例子中,这听起来可能很傻,但是我们可以再次考虑我们的一万个唯一值的场景。当我们考虑计算资源时,一个具有一万个位置的特征向量(通过使用 One-Hot-Encoding)和另一个只有 100 个位置的特征向量(当使用实体嵌入时,通过经验法则测量)之间的差异是巨大的。这只是单个要素的单个记录的差异,但您可以想象这对于真实世界的数据集会变得多么复杂,类别有时会变得非常庞大。

如果你毫无疑问地达到了这一步,那么恭喜你!但是如果你有任何问题、建议或抱怨,请随时联系我。我还创建了一个 GitHub 存储库,其中包含一个库,可以帮助任何希望在自己的数据上执行实体嵌入的人,请随意查看:

https://github . com/Rodrigo bressan/entity _ embeddings _ categorial。

下次见,编码快乐!

增强优化的 PySpark 查询

原文:https://towardsdatascience.com/enhancing-optimized-pyspark-queries-1d2e9685d882?source=collection_archive---------19-----------------------

梦想成真的故事

亚历山大·雷德尔在 Unsplash 上拍摄的照片

随着我们不断增加处理和存储的数据量,随着技术进步的速度从线性转变为对数,从对数转变为水平渐近,改进我们软件和分析运行时间的创新方法是必要的。

这些必要的创新方法包括利用两个非常流行的框架:Apache Spark 和 Apache Arrow。这两个框架使用户能够以分布式方式处理大量数据。这两个框架也使用户能够通过使用矢量化方法更快地处理大量数据。这两个框架可以轻松促进大数据分析。然而,尽管有这两个框架和它们赋予用户的能力,仍然有改进的空间,特别是在 python 生态系统中。为什么我们可以自信地确定在 python 中利用这些框架的改进之处?让我们研究一下 python 的一些特性。

Python 的特性

作为一种编程语言,python 实现了纯粹的灵活性。开发人员不需要在实例化或定义变量之前指定变量的类型。开发者不需要指定函数的返回类型。Python 在运行时解释每个对象的类型,这允许这些限制(或护栏)被移除。python 的这些特性缩短了开发时间,提高了生产率。然而,众所周知,这些相同的特性对程序运行时间有负面影响。由于 python 在运行时解释每个对象的类型,所以一些软件需要很长时间才能运行,尤其是那些需要过多循环的软件。即使在利用向量化操作的程序中,考虑到一些编程逻辑的复杂性,仍然会对运行时性能产生一些影响。我们能做些什么来减轻这些与性能相关的影响吗?让我们把注意力转向我选择的解决方案:Numba

Numba 来救援了

Numba 对 python 函数执行即时编译,与 C/C++和 Java 编译的执行方式非常相似。仅包含标准内置函数或一组 NumPy 函数的 Python 函数可以使用 Numba 进行改进。这里有一个例子:

from time import time
from numba import jit
import numpy as np@jit(nopython=True, fastmath=True)
def numba_sum(x): return np.sum(x)# this returns the median time of execution
def profileFunct(funct, arraySize, nTimes):_times = [] for _ in range(nTimes):start = time()funct(np.random.random((arraySize,)))end = time()_times.append(end - start)return np.median(_times)# this is the numba time
numba_times = [profileFunct(numba_sum, i, 1000) for i in range(100, 1001, 100)]# this is the standard numpy timing
numpy_times = [profileFunct(np.sum, i, 1000) for i in range(100, 1001, 100)]speed_up_lst = list(map(lambda x: x[1] / x[0], zip(numba_times, numpy_times)))

在上面的例子中,我们只计算一个 numpy.array 的和,然后相互比较性能。在这个简单的例子中,我们看到了适度的性能提升。根据您的本地机器,您可以看到 10%到 150%的性能提升。通常,您会看到类似的性能提升,或者如果您在函数中迭代,甚至会更多。

如果我们可以加速一个简单的加法示例,让我们来看一个使用 Numba + Apache Arrow + Apache Spark 的示例。

三个火枪手

下面是一个简单的例子,展示了创建实时编译函数,然后通过 pandas_udf 使用它们的可能性。

from numba import jit
import numpy as np
import pandas as pdimport pyspark.sql.functions as F
from pyspark.sql import SparkSession
from pyspark.sql.types import DoubleTypespark = SparkSession.builder.appName("test").getOrCreate()spark.conf.set("spark.sql.execution.arrow.enabled", "true")df = pd.DataFrame(data=np.random.random((100,)), columns=["c1"])sdf = spark.createDataFrame(df)# JIT compiled function
@jit(nopython=True, fastmath=True)
def numba_add_one(x):return x + np.ones(x.shape)# this is needed to use apache arrow
@F.pandas_udf(DoubleType())
def add_one(x):return pd.Series(numba_add_one(x.values))sdf = sdf.withColumn("c1_add_one", add_one(F.col("c1")))sdf.toPandas()

如前所述,这是一个简单的例子。然而,对于更复杂的应用程序,这是非常有价值的,将使它加速,即使是最基本的 Apache Spark SQL 查询。

我希望你喜欢你的阅读!如果您对此感兴趣,那么您会对下面的文章感兴趣:

[## 使用 Apache Airflow 扩展 DAG 创建

数据科学社区中最困难的任务之一不是设计一个结构良好的模型…

towardsdatascience.com](/scaling-dag-creation-with-apache-airflow-a7b34ba486ac)

如果您想了解更多信息,请在 LinkedIn 上关注我,或者访问我的主页,在那里联系我

[## 爱德华·特纳——数据科学家——pay locity | LinkedIn

爱德华·特纳(Edward Turner)是一名多语言开发人员,懂 Python、R 和 Scala,懂 Java 和 C/C++的语法。他…

www.linkedin.com](https://www.linkedin.com/in/edward-turner-polygot/) [## 主页

在这里,您将找到有关 Edward Turner 所做工作的信息,以及…

ed-特纳. github.io](https://ed-turner.github.io/)

再次感谢!一如既往#happycoding

使用 imblearn 管道中的自定义采样器丰富您的火车文件夹

原文:https://towardsdatascience.com/enrich-your-train-fold-with-a-custom-sampler-inside-an-imblearn-pipeline-68f6dff964bf?source=collection_archive---------39-----------------------

在交叉验证中使用扩充数据并不像看起来那么简单。这是如何在 sklearn 中做到的。

艾德亚多·桑奇兹在 Unsplash 上拍摄的照片

当涉及到小数据集时,生活会变得复杂。在医学中,一个数据集很容易包含不到 100 个患者/行。但是在另一个维度上,它可以变得非常大——轻松超过 3000 个特征。

但是,有时您会找到扩充数据的方法,在我的例子中,这意味着您将数据集乘以稍微不同的特征值。这样你就可以增加你的训练数据。当然这是我真正做的事情的简化版本,但那是另外一个故事了。有不同的方法来扩充您的数据,但是本文并不打算涵盖数据扩充的广泛领域。

但你必须小心,数据增强是一种强大的武器,必须谨慎使用。即使正确使用,也不能保证提高估计器的性能。

顺便说一句,如果没有我的同事和 StackOverflow 的人的帮助,我是写不出这篇文章的!

在您的流程中何处使用增强数据

一旦你有了一组扩充的数据来丰富你的原始数据集,你就会问自己如何以及在哪个点上合并它们。通常,您使用 sklearn 及其模块来评估您的估计器或搜索最佳超参数。包括RandomizedSearchCVcross_validate 在内的流行模块可以选择通过类似KFold的交叉验证方法。通过利用交叉验证方法来测量估计器的性能,您的数据被分成一个训练集和一个测试集。这是在 sklearn 方法下动态完成的。

这通常是好的,这意味着你不需要过多的麻烦。当您想要将扩充数据用于交叉验证方法时,只有一个问题——您不希望在您的测试文件夹中有扩充数据。这是为什么呢?你想知道你的估计器在现实中表现如何,而你的增广数据并没有反映现实。此外,您希望只增加训练集中的数据,而不希望在训练文件夹中增加数据。

如何只在需要扩充的地方扩充

回到问题,在你的交叉验证中,有没有可能影响训练测试拆分?是的,imblearn.pipeline.Pipeline 来救援了。这个管道类似于你可能从 sklearn 了解到的管道,你可以在一个所谓的管道中链接处理步骤和估计器。对我们来说,的巨大差异和优势在于它在交叉验证中的工作方式。它只在列车上运行!

这是一个好消息,但是您仍然需要定义一个方法来丰富您的原始数据并在管道中传递它。最简单的方法是使用 imblearn 的FunctionSampler 将任何函数转换成可以在管道中传递的采样器。imblearn 网站上有大量的文档。但是,也许你想做一些更复杂的事情,并建立自己的采样器。这就是 sklearn 的BaseEstimator 发挥作用的地方,它是一个定制估算器的基类。我们可以用它来构建我们的采样器。

import pandas as pd
from sklearn.base import BaseEstimatorclass EnrichWithAugmentedData(BaseEstimator):"""Resampler to pass augmented data in a imblearn pipelineIn this example I pass a list of augmented data frames with identical endpoints y to be merged with the original data X"""def __init__(self, augmented_sets):self.augmented_sets = augmented_setsdef fit_resample(self, X, y):return self.resample(X, y)def resample(self, X, y):self.data = []for i, df in enumerate(self.augmented_sets):self.data.append(self.augmented_sets[i].copy())for i, df in enumerate(self.data):self.data[i] = self.data[i].loc[X.index, :]X = pd.concat([X, *self.data], axis=0)n = len(self.data) + 1y = pd.concat([y]*n, axis=0)return X, y# Feel free to comment my code, I am a physicist :D

现在,我们可以使用我们的采样器来构建具有任何估计器的管道:

from xgboost import XGBClassifier
from imblearn.pipeline import Pipelineaugmented_sets = [df_augmented_01, df_augmented_02]model = XGBClassifier()
ewad = EnrichWithAugmentedData(augmented_sets)
pipeline = Pipeline([('ewad', ewad), ('model', model)])

假设我们想利用管道中的RepeatedStratifiedKFold 进行一次RandomizedSearchCV:

cv = RepeatedStratifiedKFold(n_splits=5, n_repeats=10, random_state=101)# make sure that you have the suffix with the name of your pipeline step in front of your parameter name!
parameter_grid = {'model__max_depth':[2, 3, 4],'model__learning_rate':np.arange(0.005, 0.5, 0.05),
}# make sure that you do not refit, because the refit will be without your augmented data!
gs = RandomizedSearchCV(estimator=pipeline, n_iter=3000,param_distributions=parameter_grid, scoring='roc_auc', n_jobs=-1, cv=cv, verbose=1,random_state=101,refit=False
)
grid_result = gs.fit(X, y)print("Best: {:.2f} using {}".format(grid_result.best_score_, grid_result.best_params_
))

您也可以用cross_validate使用相同的程序,用pipeline.steps[1][1]获得最佳模型和特征重要性,作为特征选择方法。如果您使用扩充数据进行训练,那么它很有可能会影响评估者选择的特征。

我希望这篇文章能帮助一些数据科学家同行。

用 Akka 流丰富 OCR

原文:https://towardsdatascience.com/enriching-ocr-with-akka-streams-7e48990be929?source=collection_archive---------26-----------------------

马丁·桑切斯在 Unsplash 上的照片

Tesseract 文档列出了一些预处理步骤以获得更好的 OCR 结果。由于我不知道如何执行这些步骤,所以我决定创建一个可插拔的流架构,以便在进行过程中添加它们。在 Akka Streams 世界中,这最终看起来像一个带有 sub Flow[Mat]Flow[BufferedImage]——其中 Mat 是一个 OpenCV 构造。然后将BufferedImage传递给宇宙魔方,宇宙魔方返回一个字符串。这就是我们在 OCR 与 Akka、Tesseract 和 JavaCV 中讨论的内容。这篇文章着眼于获取 OCR 结果,并通过几个处理阶段来丰富它。

先前系统的图示

如果你想继续的话,所有的代码都已经在 Github Repo 中更新了!

理解这篇文章不需要上一篇文章。它只是用来显示我们是如何得到 OCR 文本结果的。

快速洞察

以上给了我一些不错的结果,但如果能看到图像随着每个阶段的变化会更好。计划是连接一个ImageSink将图像写入文件。

当我们运行应用程序并上传样本文件时,我们可以在项目的根目录中看到预处理的 3 个不同阶段:

原始、二进制、增强、消除倾斜

从 Tesseract 的 OCR 过程返回的文本是:

CHAPTER 1 THE COMPOUND EFFECT IN ACTION You know that expression, “Slow and steady wins the race”? Ever heard the story of the tortoise and the hare? Ladies and gentlemen, I’m the tortoise. Give me enough time, and I will beat virtually anybody, anytime, in any competition. Why? Not because I’m the best or the smartest or the fastest. I’ll win because of the positive habits I’ve developed, and because of the consistency J use in applying those habits. I’m the world’s biggest believer in consistency. I'm living proof that it’s the ultimate key to success, yet it’s one of the biggest pitfalls for people struggling to achieve. Most people don’t know how to sustain it. I do. Ihave my father to thank for that. In essence, he was my first coach for igniting the power of the Compound Effect. My parents divorced when I was eighteen months old, and my dad raised me as a single father. He wasn’t exactly

通过扫描,我们可以看到两个错误,consistency **J** use in applying**Ihave** my father to thank。不错的成绩!但是,让我们通过更多的处理阶段来运行 OCR 结果,从而变得更加智能;拼写检查、自然语言处理和日期提取。😎

OCR 后处理

我们的 OCR 流程将变成:

新的 OCR 后处理阶段

拼写检查

首先,我们将添加一个拼写检查器。我在这里买了 100 本英语词典。我们可以将它们添加到我们的资源目录中,并创建这个拼写特征:

我们确保我们的主要对象扩展了这一特性:

object Main extends App with OCR with Spell

现在我们可以添加一个遵循Flow[String]协议的拼写检查方法。它删除换行符、大部分标点符号,并过滤拼写错误的单词。对于每个拼写错误的单词,我们会添加一个建议列表。

如果你运行 OCR 应用程序(sbt run)并上传一张图片,你会看到潜在的拼写错误和建议列表。对于上面的图像,我们得到以下结果:

{ **"ocr"**:"...",**"suggestions"**:[{**"Ihave"**:["Have", "Shave", "I have"]}]
}

命名实体识别

接下来,我们将添加一个阶段来尝试和识别命名实体,特别是人。对于 NLP,我们将按字符进行标记,但是让我们也添加一个句子模型。我们使用以下模型创建 NLP 特征:

我们的主要对象也扩展了 NLP…

object Main extends App with OCR with Spell with NLP

我们现在可以建造我们的提取者Flow。注意,这个流接收一个类型的OcrSuggestions,输出一个OcrSuggestionsPersons类型。该类型与OcrSuggestions相同,但也包含一个“Persons”字符串列表。

我们已经构建了 3 个附加流中的 2 个,最后需要添加一些数据提取:

日期提取

从文本中提取日期有许多选择。我决定使用 Natty ,但对试用 diggamma . ia 的 timeextractor 很感兴趣。

我决定使用 OpenNLP 将 Tesseract 返回的整个文本拆分成句子,然后将这些句子传递给 Natty。让我们来看看我们简单整洁的特点:

我们和我们的主要目标结合得很好

object Main extends App with OCR with Spell with NLP with Natty

然后我们可以构建一个Flow,它接受一个OcrSuggestionsPersons类型并输出一个OcrSuggestionsPersonsDates类型:

我们现在已经完成了 OCR 流程!

最终 OCR 流程

我们对上图的最新回应是:

{ **"suggestions"**:[{**"Ihave"**:["Have", "Shave", "I have"]}],**"persons"**:["Ladies"],**"dates"**:[[["Wed Aug 11 16:20:57 PDT 2021"],"eighteen months"]]}

我们可以看到,Natty 将“十八个月”解析为“从现在起十八个月”NLP 将“女士”标记为人称代词。我们可以争论这些元数据有多有用,但最终它比我们以前拥有的数据更多。

如果你上传一张图片,同时我们的应用程序的网页在 http://localhost:8080,运行,你会看到我高亮显示的各种结果的 HTML:

让我们尝试不同的图像…

如果你能说出这本书的名字,加分:)

这会产生以下内容作为 JSON 响应的一部分:

**"persons"**:["Gamble","Duncan"],
**"dates"**:[["Tue Feb 11 12:00:00 PST 2020"], "afternoon"]

我们的简单网页上的输出如下:

OpenNLP 决定将“Duncan”和“Gamble”标记为 people,Hunspell 将“go-getters”标记为潜在的拼写错误,Natty 决定“午后”是 2020 年 2 月 11 日这一天的午后。

😎希望你喜欢这第二个帖子!和往常一样,所有代码都在 Github Repo 中进行了更新。

用位置信息丰富 shapelets 用于时间序列分类

原文:https://towardsdatascience.com/enriching-shapelets-with-positional-information-for-timeseries-classification-42b6009a54a8?source=collection_archive---------21-----------------------

一个简洁的技巧如何提高预测性能和可解释性。

时间序列分类

许多现实世界的流程会随着时间的推移产生数据,从而产生时态数据或时间序列。与表格数据相反,相邻观测值(即时间上接近的观测值)高度相关,在分析时间序列时需要特别的努力。可以对时间序列执行的一个可能的任务是对它们进行分类。示例用例包括基于加速度计数据的表面检测、基于用电量的电气设备类型分类或基于轮廓信息的树叶类型分类。

使用加速度计数据的 X 轴检测机器人(索尼 AIBO)行走的表面。图片取自http://www.timeseriesclassification.com/description.php?dataset = sonyaiborobotsurface 1

Shapelets

Shapelets 是小的子序列,或者时间序列的一部分,对于某个类是有信息的或者有区别的。通过计算要分类到 shapelet 的每个时间序列的距离,它们可用于将时间序列转换为要素。

从 ItalyPowerDemand 数据集中提取两个 shapelets,以便将时间序列转换到二维特征空间。特征空间中的每个轴代表到两个 shapelets 之一的距离。可以看出,使用这两个 shapelets 已经可以实现良好的线性分离。

位置信息

Guillemé等人最近发表了“局部随机 shape let”,其中他们提出了一种提取 shape let 的方法,可用于创建由基于距离的特征和基于位置的特征组成的特征矩阵,从而获得更好的预测性能。

他们提出的技术将挖掘 K 个 shapelets,以便将 N 个时间序列转换成 N×2K 特征矩阵。该特征矩阵包括到每个小形状的距离(d(Ti,Si))和位置(l(Ti,Si))。

每个时间序列的特征通过在时间序列上滑动 shapelet 并计算每个位置的 shape let 到时间序列的欧几里德距离来计算。最后,返回最小距离和相应的位置。指定的距离和位置纯粹是概念上的,远非精确。

GENDIS:有效地提取精确的 shapelets

我们扩展了我们的技术,GENDIS(shape let 的基因发现)来提取除了到 shape let 的距离之外的位置信息。由于 GENDIS 是一种遗传算法,它可以优化任何东西(它的目标函数不需要可微)。因此,这需要最少的努力,但初步的实验表明,预测性能显著提高。通过这一新的更新,GENDIS 能够提取非常容易解释的 shapelets,并能够在输入机器学习分类器时实现最先进的预测性能。此外,与实现类似性能的技术相反,GENDIS 不需要执行强力搜索,并且不需要调整 shapelets 的数量和相应的长度。

让我们通过创建一个位置信息是关键区别属性的人工数据集来演示新功能(因为两个类的模式是相同的):

生成的时间序列。这两个类的模式是相同的。区分这两个类的唯一方法是使用发现模式的位置。

我们使用这两个版本提取 shapelet,并测量我们使用具有逻辑回归分类器和默认超参数的单个 shape let 所能达到的准确度。旧版本只能达到 81%的准确率,而新版本达到 100%的准确率。我们还在三个较小的数据集上快速比较了新版本和旧版本,每一次,位置信息都显著提高了准确性。

shapelets 的可解释性

shapelets 最有趣的特性之一是它们非常容易解释。提取的 shapelets 可以很容易地呈现给领域专家,以显示时间序列的哪些部分被准确地使用,以便做出决定。此外,通过优化小形状的位置和距离信息,提取的小形状也更容易解释。没有位置信息,GENDIS 和相关技术,如学习时间序列 Shapelets ,能够经常“破解”那里的位置信息。Guillemé等人在他们的论文中证明:

在上面的图像中,我们看到一个长时间序列(浅蓝色),对应于地震读数,以及由 LS 学习的 shapelets,它不包含位置信息,以彩色显示。提取的 shapelet 确实实现了优秀的预测性能,但是与原始时间序列没有任何关系,使得它们难以解释(它们位于从时间序列到 shape let 的距离最小的位置)。另一方面,对位置信息进行编码的 LRS 实现了出色的预测性能,并提取了与原始时间序列非常相关的 shapelets(正如我们可以看到的,彩色子序列与原始浅蓝色时间序列非常匹配)。

这篇短文到此结束!通过扩展我们的 shapelet 提取框架,除了提取到每个 shape let 的距离之外,还提取位置信息,我们能够以有限的努力在预测性能方面获得一些显著的收益!

如果您对 shapelets 有更多问题,或者您有一个涉及时间序列分类的用例?与我们取得联系!

来源

[1] 叶,李,&等(2009 年 6 月)。一种新的数据挖掘原语。第 15 届 ACM SIGKDD 知识发现和数据挖掘国际会议论文集*。* 【2】Lines,j .,Davis,L. M .,Hills,j .,& Bagnall,A. (2012,8 月)。用于时间序列分类的 shapelet 变换。第 18 届 ACM SIGKDD 知识发现和数据挖掘国际会议论文集*。*
【3】格拉博卡,j .,席林,n .,威斯特巴,m .,&施密特-蒂梅,L. (2014 年 8 月)。学习时序 shapelets。第 20 届 ACM SIGKDD 知识发现和数据挖掘国际会议论文集*。*
【4】m .吉列梅,s .马林诺夫斯基,r .&x .勒纳尔(2019,9 月)。局部随机形状。在时态数据高级分析和学习国际研讨会上。斯普林格,查姆。
【5】范德维尔(Vandewiele,g .),翁格纳内(Ongenae,f .),&德图尔克(De Turck,f .)(2019)。GENDIS:身材的基因发现。 arXiv 预印本 arXiv:1910.12948
www.timeseriesclassification.com

基于 OptimalFlow 的机器学习集成特征选择

原文:https://towardsdatascience.com/ensemble-feature-selection-in-machine-learning-by-optimalflow-49f6ee0d52eb?source=collection_archive---------41-----------------------

用简单的代码选择顶级特性的简单方法

特征选择是机器学习工作流的关键部分。特征选择的好坏直接关系到模型的性能。数据科学家通常会遇到两个难题:

  • 哪种特征选择算法比较好?
  • 需要保留输入数据集中的多少列?

因此,我编写了一个名为 OptimalFlow 的 Python 库,其中包含一个集合特征选择模块,名为 autoFS 以轻松简化这一过程。

OptimalFlow 是一个 Omni-ensemble 自动化机器学习工具包,它基于流水线簇遍历实验(PCTE) 方法,帮助数据科学家以简单的方式构建最优模型,并使用简单的代码自动化机器学习工作流。

为什么我们使用 OptimalFlow ?你可以读另一个关于它的介绍的故事:一个全方位的自动化机器学习——optimal flow

autoFS 模块将通过流行的特征选择算法(选择器),如 kBest、RFE 等。并且选择从它们的输出中选择的多数特征作为最重要的特征。以下是 autoFS 模块和默认选择器的详细链接:

您可以阅读optimal flow**optimal flow**autoFS模块的 文档。此外, OptimalFlow 还提供了特征预处理、模型选择、模型评估、流水线簇遍历实验(PCTE) 自动化机器学习模块。

这里我们将有一个演示,使用 OptimalFLow ,在几分钟内完成一个回归问题的特征选择。我们使用经典的波士顿住房数据集作为输入。

***第一步:安装 OptimalFlow 😗**

*pip install optimalflow*

第二步:导入 OptimalFlow 模块:

*import pandas as pd
from optimalflow.autoFS import dynaFS_reg*

第三步:导入输入数据集:

*tr_features = pd.read_csv('./data/regression/train_features.csv')
tr_labels = pd.read_csv('./data/regression/train_labels.csv')*

我们使用波士顿住房数据集作为输入文件,它有 506 行和 14 列。你可以在这里找到关于它的细节。

波士顿住房数据集 train _ features.csv

波士顿住房数据集 train _ labels.csv

第四步:运行 autoFS 模块:

我们希望为进一步的建模过程提供前 5 个重要特征。我们使用的是 autoFS 的默认选择器,但是你也可以通过它的 custom_selectors 属性自定义设置你只想通过的选择器。

**# Set input_form_file = False, when label values are array. Select 'True' from Pandas dataframe.*reg_fs_demo **=** dynaFS_reg**(** fs_num **=** **5,**random_state **=** **13,**cv **=** **5,**input_from_file **=** True**)***# You can find details of each selector's choice in autoFS_logxxxxx.log file in the ./test folder*reg_fs_demo**.**fit**(**tr_features**,**tr_labels**)***

一切就绪!以下是输出结果:

******optimalflow***** autoFS Module **===>** Selector kbest_f gets outputs**:** **[**'INDUS'**,** 'NOX'**,** 'RM'**,** 'PTRATIO'**,** 'LSTAT'**]**
Progress**:** **[***###-----------------] 14.3%******optimalflow***** autoFS Module **===>** Selector rfe_svm gets outputs**:** **[**'CHAS'**,** 'NOX'**,** 'RM'**,** 'PTRATIO'**,** 'LSTAT'**]**
Progress**:** **[***######--------------] 28.6%******optimalflow***** autoFS Module **===>** Selector rfe_tree gets outputs**:** **[**'CRIM'**,** 'RM'**,** 'DIS'**,** 'TAX'**,** 'LSTAT'**]**
Progress**:** **[***#########-----------] 42.9%******optimalflow***** autoFS Module **===>** Selector rfe_rf gets outputs**:** **[**'CRIM'**,** 'RM'**,** 'DIS'**,** 'PTRATIO'**,** 'LSTAT'**]**
Progress**:** **[***###########---------] 57.1%******optimalflow***** autoFS Module **===>** Selector rfecv_svm gets outputs**:** **[**'CRIM'**,** 'ZN'**,** 'INDUS'**,** 'CHAS'**,** 'NOX'**,** 'RM'**,** 'AGE'**,** 'DIS'**,** 'RAD'**,** 'TAX'**,** 'PTRATIO'**,** 'B'**,** 'LSTAT'**]**
Progress**:** **[***##############------] 71.4%******optimalflow***** autoFS Module **===>** Selector rfecv_tree gets outputs**:** **[**'CRIM'**,** 'CHAS'**,** 'NOX'**,** 'RM'**,** 'AGE'**,** 'DIS'**,** 'TAX'**,** 'PTRATIO'**,** 'B'**,** 'LSTAT'**]**
Progress**:** **[***#################---] 85.7%******optimalflow***** autoFS Module **===>** Selector rfecv_rf gets outputs**:** **[**'CRIM'**,** 'ZN'**,** 'NOX'**,** 'RM'**,** 'AGE'**,** 'DIS'**,** 'RAD'**,** 'TAX'**,** 'PTRATIO'**,** 'B'**,** 'LSTAT'**]**
Progress**:** **[***####################] 100.0%*The optimalflow autoFS identify the top **5** important features **for** regression are**:** **[**'RM'**,** 'LSTAT'**,** 'PTRATIO'**,** 'NOX'**,** 'CRIM'**].***

您会发现['RM ',' LSTAT ',' PTRATIO ',' NOX ',' CRIM']列是为我们选择的五大功能 autoFS !简单容易,对吧?

关于 OptimalFlow 的相关阅读:

集成模型选择&使用 OptimalFlow 在机器学习中进行评估——使用简单代码选择最佳模型的简单方法

端到端 OptimalFlow 自动化机器学习教程结合真实项目-公式 E 圈数预测第 1 部分

端到端 OptimalFlow 自动化机器学习教程结合真实项目——公式 E 圈数预测第二部分

用 OptimalFlow Web App 建立无代码自动机器学习模型

关于我:

我是一名医疗保健和制药数据科学家以及大数据分析和人工智能爱好者。我开发了 OptimalFlow 库,帮助数据科学家以简单的方式构建最优模型,用简单的代码实现机器学习工作流程的自动化。

作为一名拥有多年分析经验的大数据洞察寻求者、流程优化者和人工智能专家,我使用数据科学中的机器学习和问题解决技能将数据转化为可操作的洞察,同时提供战略和量化产品作为最佳结果的解决方案。

你可以在我的 LinkedIn 或者 GitHub 上和我联系。

在 3 分钟内解释集成学习、打包和增强

原文:https://towardsdatascience.com/ensemble-learning-bagging-and-boosting-explained-in-3-minutes-2e6d2240ae21?source=collection_archive---------18-----------------------

直观的解释和揭开基本概念的神秘面纱

作者创建的图像

请务必在此 订阅 或我的 个人简讯 千万不要错过另一篇关于数据科学指南、技巧和提示、生活经验等的文章!

在之前的另一篇文章中,我解释了什么是 bootstrap sampling 以及它为什么有用。如果你不知道什么是 bootstrap 抽样,我建议你看看我写的关于 bootstrap 抽样的文章,因为这篇文章将建立在它的基础上!

当您开始数据科学之旅时,您肯定会听说“集成学习”、“打包”和“助推”。因为我没有任何指导或方向,我花了一段时间才明白装袋和助推实际上是什么意思。因此,我的目标是尽可能简单直观地解释这些术语!

什么是集成学习?

集成学习是一种多种学习算法联合使用的方法。这样做的目的是让您获得比单独使用单个算法更高的预测性能。

1:“三个臭皮匠胜过一个诸葛亮”

作者创建的图像

一种简单的思考方式是,如果一个人在解决一个数学问题,而一群人在解决一个数学问题。如果一个人解决了错误的问题,他/她将没有其他人来检查他/她的答案。另一方面,这群人可以协作解决,互相寻找对方的错误,并对最终答案进行投票。

示例 2:随机森林

随机森林是一种基于决策树的集成学习技术。随机森林涉及使用原始数据的自举数据集创建多个决策树。然后,该模型选择每个决策树的所有预测的模式(大多数)。这有什么意义?依靠“多数获胜”模型,它降低了单个树出错的风险。

例如,如果我们创建一个决策树,第三个,它会预测 0。但是如果我们依赖所有 4 个决策树的模式,预测值将是 1。这就是集成学习的力量!

现在你知道什么是集成学习,让我们来介绍两种流行的集成方法:bagging 和 boosting。

请务必在此 订阅 或我的 个人简讯 千万不要错过另一篇关于数据科学指南、技巧和提示、生活经验等的文章!

什么是装袋?

Bagging 又称 bootstrap aggregating ,是用原始数据集的自举样本对同一学习算法的多个模型进行训练的过程。然后,像上面的随机森林示例一样,对所有模型的输出进行投票。

装袋过程

什么是助推?

Boosting 是 bagging 的一种变体,其中每个单独的模型都是按顺序构建的,并迭代上一个模型。具体来说,任何被前一个模型错误分类的数据点都会在后一个模型中得到强调。这样做是为了提高模型的整体准确性。这里有一个图表,可以更好地理解这个过程:

一旦建立了第一模型,除了第二自举样本之外,还采用错误分类/预测的点来训练第二模型。然后,针对测试数据集使用集合模型(模型 1 和 2 ),并且该过程继续。

而这就是合奏学习的精髓,装袋,助推!

感谢阅读!

如果你想学习更多的机器学习基础知识,了解我的最新内容,你可以在这里学习。

特伦斯·申

  • 查看 我的免费数据科学资源 每周都有新素材!
  • 如果你喜欢这个, 在 Medium 上关注我 了解更多
  • 我们来连线上LinkedIn

从零开始的集成学习

原文:https://towardsdatascience.com/ensemble-learning-from-scratch-20672123e6ca?source=collection_archive---------28-----------------------

引入集成学习,这是一种通过组合训练好的模型来提高性能的强大工具。

图片来自来源。

对于许多数据科学和应用机器学习的初学者来说,找到符合手头数据的最佳模型通常意味着尝试尽可能多的合理选项,保留最佳模型,而其余的则被丢弃。集成学习提供了一种替代方案,即通过所有经过训练的模型形成一个集成,其性能可以与最好的模型一样好,如果不是更好

集成学习力量的一个合法代表是随机森林,在本文中,我们将揭示一些可以用来建立集成模型的方法,并直观地解释其背后的原理

本文的结构遵循 第 7 章--集成学习与随机森林 ,出自 **用 Scikit-Learn 的动手机器学习,Keras 和 TensorFlow,第 2 版,作者 Aurélien Géron (O'Reilly)。

大数定律

“三个臭皮匠,顶个诸葛亮”

当我第一次看到大数定律时,我在学校里学到的这句古老的中文谚语突然出现在我的脑海里。它解释了被称为群众的智慧——一大群人的集体智慧可能比一个专家的智慧更好。

集成学习通过组合独立的模型(称为预测器)来应用该定理,以形成强学习器(实现高精度)。它甚至在所有预测者都是弱学习者时也能工作(表现仅比随机猜测稍好)。

“用 Scikit-Learn、Keras 和 TensorFlow 实践机器学习,第二版,作者 Aurélien Géron (O'Reilly)。”,第七章。

但是为什么会这样呢?群众的智慧可能听起来很“聪明”,但它仍然有点违反直觉。为了回答这个问题,下面的类比可能有助于揭示这个秘密:假设你投掷一枚略有偏差的硬币,有 51%的机会正面朝上。如果你做 100 次,不太可能会有正好 51 个头,甚至有可能你最后没有多数个头。但随着你不断折腾,你会观察到人头的 会越来越接近 51% 。您进行的试验越多,平均****值就越接近预期值**,获得多数人头**的概率就越大。

集成学习在本质上做着同样的事情——弱学习者在分类任务中只有微小的机会预测正确的类别,但是如果我们使用许多独立的预测器做出同样的预测,聚集的结果将更有可能预测正确的类别。

集合模型的输出是关于分类任务时最频繁的预测**。对于一个回归任务,使用平均值代替。**

集成方法

训练一个集成时的关键要素是,它的所有分类器必须完全独立,这可以通过使用不同的算法来实现,或者使用相同的算法,但在训练集的不同子集上进行训练。在这里,我们探索这两种方法来构建集成分类器。

“用 Scikit-Learn,Keras & TensorFlow 进行动手机器学习”,第 7 章。

1.投票分类器

训练不同的预测器算法以形成集成被称为投票分类器**,其机制很简单——一组不同的算法在同一个训练集上训练,当进行预测时,集成的输出被聚集,取最多投票的类别作为集成的预测。**

当通过每个预测器的输出类进行聚合时,称为硬投票**,当使用输出概率时,称为软投票。软投票通常表现更好,因为它捕捉了更多的细微差别(逻辑上它要求所有的预测器都能够输出概率)。**

2.装袋和粘贴

另一方面,代替训练不同的算法来实现多样性**,一个替代方案是使用相同类型的预测器,但是在训练集的不同随机采样子集上进行训练。**

装袋粘贴是对这些子集进行抽样的两种不同方式,它们的区别在于有无替换的抽样

当通过打包**(带替换)进行采样时,随机选择一个实例并立即将其返回给训练集,因此在每次选择时,源数据仍具有其所有实例,并且可以再次选择相同的实例粘贴反过来,同一个实例不能在同一个子集中出现超过一次。**

对于打包和粘贴,同一个实例可以出现在不同的子集中,但是只有打包允许同一个实例在同一个子集中出现两次或更多次**。由于所有子集都具有相同大小的**,具有替换的采样可以实现更多的子集多样性**,并且它们对应的预测器将更少相关。这种方法的另一个优点是,每个预测器都有不在它们的训练子集中的实例,它们可以直接用于验证,而不必保存验证数据。******

随机森林是集成学习器家族的著名成员,它由一组在不同子集采样 打包上训练的决策** (与训练集大小相同)。当分割给定的节点时,所使用的特征是从随机生成的特征子空间中选择的最合适的一个,而不是从所有可用特征的空间中选择的。多余的 ,各种随机森林,更进一步——不仅特征来自随机选择的子空间,而且使用的阈值也是**随机生成的****。****

3.增强——连续训练

增强使用与之前相同的预测器用于集合,但不是在并行中采样不同的** 子集和训练预测器,而是顺序完成,每个预测器试图纠正前任的错误。******

再来看看 AdaBoost渐变提升

— AdaBoost

当对集合中给定的预测器进行训练时,算法实例权重进行重新加权,使得错误分类的实例能够从下一个预测器获得更多的 关注 ,并且有希望将其正确分类。实例权重定义了实例被选择为子集的一部分的机会-给定实例的实例权重越高,越多, 可能它会在采样时出现在子集中。****

AdaBoost Algorithm:1\. Set the initial **instance weights**(w)to *1/m*, with *m* being the number of training instances in the training set.2\. Compute the **predictor weight**(⍺) of the current predictor using its **weighted error rate**(r).

3\. To train the next predictor, the instance weights are updated.

4\. Finally, a new predictor is trained using the updated weights, steps 2 to 4 are repeated until the number of predictors is reached or a perfect predictor is found.

在推断时间期间,集合的预测是其输出的加权 平均值。使用的权重是步骤 2 中的预测权重。作为随机猜测的,预测器是执行更好更差还是确切地说 决定了其对集合预测的贡献的类型:

—梯度增强

梯度 增强处理训练迭代作为 AdaBoost,但是每个预测器不是调整实例权重,而是通过拟合其残差 误差来校正其前任。

但是为什么要拟合残差呢?假设我们正在用 N 预测器*训练一个集成模型。*对于每个预测器 P n1<N<N,我们假设它是不完美的,它的性能可以通过增加一个估计器 h 来改善:

现在,为了找到 h ,我们先来看看一个完美的 h 应该是怎样的:

一个完美的估计器填充目标和当前预测【Pn(x)之间的*。本质上,它试图通过插入一个额外的预测器来使最小化一个成本 功能。*****

4.立桩标界

图片来自来源。

完成拼图的最后一块是立桩。如果我们训练 一个 模型来为我们做这件事,而不是使用一个给定的函数来处理预测器的输出,会不会增加 的准确性?答案是是的。这些模型通常被称为混音器,它们可以找到方法校正组合合奏的输出,以实现增强的 性能

训练搅拌机的常见方法是首先将训练数据分成训练集保持集。第一种用于训练预测器,采用任何上述方法。然后,坚持组用于训练搅拌机。当预测器被训练时,我们将它们的预测放在保留集上,并将其用作混合器的输入。如果集合中有 N 个预测值,那么混合器将在一个N**维数据加上原始目标上被训练。****

当完成训练时,混合器被期望获得集合的输出,并且以最大化整体模型的准确性的方式' 混合 '它们。

最后的话

你已经坚持到最后了!我希望你能愉快地阅读这篇文章,也希望你能对合奏 学习有所了解。这是一个强大的工具,关于它的写作帮助我巩固了对这个话题的许多理解。它仅仅触及了集成学习的基础理论的表面,并且没有给出实际的实现。我强烈推荐浏览 这篇文章 来自 机器学习掌握 ,它带你浏览如何从开始构建一个超级工薪族合奏(堆叠)!****

集成学习技术

原文:https://towardsdatascience.com/ensemble-learning-techniques-6346db0c6ef8?source=collection_archive---------32-----------------------

合奏可以让事情变得简单

图片来源:pixabay

当你在读这篇关于集成学习的文章时,我希望你至少熟悉一些机器学习模型及其实现。当我们在任何数据集上训练 ML 模型时,我们都面临着称为偏差和方差的错误同伴。大多数时候,要么我们没有得到令人满意的精度结果,要么数据过度拟合到模型中。然后我们再次调整数据,创建/删除特征,重新训练模型,这个过程可以重复几次。在接下来的几节中,我将解释什么是集成学习,它如何与偏差和方差相关,以及什么是集成学习的技术。

什么是集成学习?

集成学习是一个过程,其中多个基本模型(最常被称为“弱学习者”)被组合和训练来解决同一问题。该方法基于这样的概念,弱学习者单独执行任务很差,但是当与其他弱学习者结合时,他们形成强学习者,并且这些集成模型产生更准确的结果。

这就是集成学习方法在许多在线比赛中最常被信任的原因。

集成学习是一种结合多种机器学习算法来产生一个最佳预测模型的技术,该模型具有降低的方差(使用 bagging)、偏差(使用 boosting)和改进的预测(使用 stacking)。

带有偏差和方差的集成学习关系

最大似然模型的预测误差是下列各项之和

1。偏差误差 —偏差是模型预测结果与实际结果之间的差异。高偏差意味着模型拟合不足。因此,我们必须使用更复杂的模型。

2。方差误差 —方差是模型对训练数据中微小波动的敏感度。高方差意味着模型过度拟合。因此,我们必须获得更多的训练数据(如果训练数据较少)或使用不太复杂的模型(如果该模型的数据简单)

3。噪声通常被称为不可约误差

以平衡的方式管理偏差和方差是集成学习的核心,这可以通过使用多种模型(简单和复杂模型的混合)并在不欠拟合或过拟合数据的情况下组合它们来完成。

简单的集成学习方法

基于投票和平均的集成方法是非常简单和最容易的集成学习形式。投票用于分类问题,平均用于回归问题。

  1. 平均

顾名思义,在这种技术中,我们取所有模型预测的平均值。

例如如果我们预测房价,如果有 3 个基础模型预测房价为 45 万,50 万,55 万。对于平均,我们取平均值为(450000+500000+550000)/ 3 = 500000,这是最终预测

让我们看看代码:

现在,为了证明集成(或平均预测)是否比基础模型做得更好,我们将比较基础模型和最终模型的平均绝对误差。

Average Ensembler Mean Absolute Error: 0.48709255488962744
KNN Mean Absolute Error: 0.5220880505643672
Lasso Mean Absolute Error: 0.7568088178180192
SVR Mean Absolute Error: 0.5015218832952784

集成模型的平均绝对误差远小于单个模型。

2。最大投票分类器

最大投票与平均投票非常相似,唯一的区别是它用于分类问题。在这种技术中,来自多个模型的预测被收集(这通常被称为投票),并且来自大多数模型的预测被认为是最终预测。

例如, 如果从多个模型得到的一组最终房价预测值分别为— 50 万、45 万、60 万、45 万、65 万、45 万、60 万。然后使用最大投票分类器,最终预测将是 450000。

Max Voted Ensembler Accuracy: 72.0
KNN Accuracy: 67.2
Logistic Regression Accuracy: 74.4
SVC Accuracy: 70.39999999999999

Sklearn 库有一个用于 Max Voting 的类,叫做 VotingClassifier,你可以在这里传递分类器列表,它会选择 max voted 预测。让我们看看代码-

Sklearn Max Voting Classifier Accuracy: 72.0

3。加权平均

加权平均是平均的延伸。在平均中,所有基础模型被赋予同等的重要性,但是在该技术中,具有较高预测能力的基础模型被赋予比其他基础模型更大的重要性/更高的权重。

模型的权重是总和等于 1 的十进制数。

例如, 如果 3 个模型预测房价为 45 万,60 万,65 万。并且这些模型的权重为 25%、50%和 25%,则最终预测将是-

0.25 * 450000+0.50 * 600000+0.25 * 650000 = 575000

Weightage Average Ensembler Mean Absolute Error: 0.46186097145642674
KNN Mean Absolute Error: 0.5220880505643672
Lasso Mean Absolute Error: 0.7568088178180192
SVR Mean Absolute Error: 0.5015218832952784

结论

正如我们在上面的例子中看到的,简单的集成技术可以减少误差,并在最终的预测中产生巨大的差异。在下一篇文章中,我将分享一些先进的合奏技术,如装袋、助推和堆叠。

要访问简单合奏技术的完整代码,请查看这个 Github 链接。

谢谢你的阅读。如果你喜欢这个故事,请喜欢,分享和关注更多这样的内容。如往常一样,请联系我们以获得任何问题/评论/反馈。

Github:https://github.com/charumakhijaniLinkedIn:https://www.linkedin.com/in/charu-makhijani-23b18318/

集合机器学习:群体的智慧

原文:https://towardsdatascience.com/ensemble-machine-learning-wisdom-of-the-crowd-56df1c24e2f5?source=collection_archive---------67-----------------------

尼古拉斯·格林在 Unsplash 上的照片

假设你想买一部新手机。你不太可能走进一家商店只买一部手机。你在网上浏览产品,阅读评论,比较型号,价格。你征求家人和朋友的意见。简而言之,在做出明智的决定之前,你要进行大量的研究,寻求大众的智慧。众所周知,收集各种观点和意见可以改善决策过程。

什么是集成学习?

照片由 Clarisse Croset 在 Unsplash 上拍摄

整体机器学习的运作方式类似于图中所示的移动购买体验。它是一种结合多种方法的决策以产生最佳结果的技术。传统机器学习技术中误差的主要原因是噪声、偏差和方差。集成机器学习有助于最小化这些错误,提高稳定性和准确性。

基本集成技术

  1. 模式:在这种技术中,使用多个模型进行预测。每个模型的预测都被视为单独的投票。获得最多票数的人将作为结果。回到手机购买体验,我们寻求对多个手机的评论——苹果、三星、诺基亚、Moto G。获得最多票数的手机就是赢家。

图片来源:克里希南·斯里纳斯

2。Mean: 在这种技术中,我们从多个模型中获取预测的平均值,并使用它们来进行最终预测。回到手机购买体验,我们将多部手机的评分相加,并根据我们征求意见的人来划分数字。

均值=(不同人的评分总和)/(人数)

**3。加权平均值:**这是平均法的扩展。所有模型被赋予不同的权重,定义每个模型对于预测的重要性。例如,你给那些有更多手机使用经验的人更多的权重,而给那些没有手机使用经验的人更少的权重。

图片来源:克里希南·斯里纳斯

高级集成技术

  1. Bagging — Bagging 代表引导聚合。我们创建训练数据集的随机样本。然后,我们为每个样本建立一个模型(分类器或决策树)。最后,使用平均或多数投票来组合这些多个模型的结果。组合来自多个模型的输出减少了方差,产生了比单个模型更可靠的预测。

图片来源:克里希南·斯里纳斯

2.增强— 增强是一种迭代技术,它根据上一次分类调整观察的权重。如果一个观察被错误地分类,它会试图增加这个观察的权重,反之亦然。它降低了偏置误差。它受到先前建造的性能的影响。

结束语

正如肯·布兰查德的名言所说“没有人比我们所有人都聪明”。集成方法符合这一说法,利用不同方法的智慧来预测更好的结果。

感谢您的阅读。我希望你从阅读这篇文章中学到的和我写这篇文章时学到的一样多。

集成方法编码

原文:https://towardsdatascience.com/ensemble-methods-code-along-60a6eaa2e8dc?source=collection_archive---------50-----------------------

为数据科学初学者提供的随机森林、AdaBoosting 和梯度增强方法的代码。

这是给谁的:

正如副标题所暗示的,这篇代码文章是为有兴趣制作他们的第一个更高级的监督机器学习模型的初学者准备的。也许你想知道如何提高你在 Kaggle 上的 Titanic 分数——这段代码将向你展示一种可以直接显著提高你分数的方法。

这是给那些通过 学得最好的人的。

我的目的是揭开机器学习应用的神秘面纱。是的,机器学习背后的理论可能相当复杂,我强烈鼓励你深入研究,让自己接触你所做和使用的事物的潜在“数学”。然而,我们都需要从某个地方开始,有时感受一下事情是如何运作的,看到结果可以激发你更深层次的学习。

我不喜欢重复在 Medium 等平台上已经饱和的内容。因此,我不会深究这些算法是如何工作的。

我将提供非常简短的*“简而言之,这是正在发生的事情”*对每种方法的解释,并将为您指出一些相关文章、博客和论文的方向(我真的鼓励您深入研究)。

先决条件:

这段代码旨在帮助您直接使用三种不同的集成方法构建机器学习模型:随机森林、AdaBoosting 和梯度增强。

我假设你对监督学习和非监督学习有一个大致的了解,并且对基本的决策树模型有一些了解。

我将使用:

  • Kaggle 电信数据集中的流失
  • 用于数据清理的熊猫
  • sci kit-为建模而学习

我们现在要做的是:

  • 快速 EDA
  • 创建 4 个模型(有限状态机和 3 个集合模型)
  • 比较每个模型的准确性和召回指标

集合模型:

不要想太多了—

系综模特是 系综模特!

惊呆了。

集合方法背后的思想是“群体的智慧”。我认为

"我的屁股穿这条裙子好看吗?"

我可以肯定地说

“地狱耶女孩!”

但是也许你想确定我不只是出于礼貌,所以你问了另外 5 个人,他们给了你同样的回答。在问了 20 多个人之后,你对自己很有信心(你应该这样!).

这个就是集成方法背后的思想。

集合模型通过结合大量单一模型的预测给出更好的预测。这可以通过汇总预测结果或改进模型预测来实现。出于这个原因,集合方法往往会赢得比赛。关于这一点的更多信息,请看这篇文章和这篇博客。

随机森林、AdaBoosting 和梯度增强只是我今天选择的 3 种集成方法,但还有许多其他方法!

随机森林:

随机森林是一种用于分类和回归问题的监督学习算法。

简而言之 ,随机森林算法是决策树模型的集合。

决策树算法基于在每个阶段最大化信息增益来选择其分裂,因此在同一个数据集上创建多个决策树将产生同一个树。为了使我们的集合方法有效,我们需要个体模型的可变性。随机森林算法利用装袋和子空间采样方法来创造这种可变性。

请参见 Leo Breiman 的论文和网站了解随机森林的基本细节。或者,如果你更喜欢博客/文章,请看这里。

AdaBoosting(自适应升压):

AdaBoosting 又名自适应增强,是发明的第一个增强算法,所以出于怀旧,我在这里提到它。自那以后,出现了许多基于 AdaBoosting 的 Boosting 算法,但这仍然是开始学习 boosting 算法的好地方。

简而言之 ,AdaBoost 模型在数据集的子样本上进行训练,为数据集中的每个点分配权重,并在每次模型迭代时改变这些权重。如果学习者(当前模型)正确地分类了一个点,则该点的权重减小,如果学习者错误地分类了一个点,则该点的权重增大。

点击查看更多关于 AdaBoosting 的信息。

梯度提升:

梯度增强是一种更高级的增强算法,它利用了梯度下降,您可能还记得线性回归。

简而言之 ,梯度增强以类似于 AdaBoosting 算法的方式对每个弱学习器进行改进,除了梯度增强计算每个点的残差并将其与损失函数相结合。因此,该算法使用梯度下降来最小化总损失,并使用梯度和损失作为预测器来训练下一个学习者。

更多信息,请阅读本和本。

好吧好吧!让我们开始有趣的部分吧!

EDA:

让我们做一些超级快速的探索性数据分析。我特意选择了这个数据集,因为当你从 Kaggle 下载它时,它已经非常干净了。但是,作为新的数据科学家,继续磨练我们的 EDA 技能对我们来说很重要。

数据问题:

正如您可能从数据集的标题中猜到的那样,该模型旨在预测客户流失,这是企业面临的一个非常常见的问题。

考虑我们想要使用哪些指标来评估我们的模型,让我们考虑我们希望我们的模型预测什么,以及什么更糟:假阴性预测或假阳性预测。

我们的模型应该预测数据集中的客户是会留在公司(False)还是会离开(True)。

在这个场景中,我们有:

假阴性: 模型预测一个客户会留在公司( *False* ),而实际上那个客户在翻盘( *True* )。

误报: 模型预测某个客户会流失( *True* ),而实际上他们会留下来( *False* )。

鉴于此,我们可能会说,假阴性对公司来说成本更高,因为这将是一个错过的保持这些客户的营销机会。出于这个原因,我们将使用准确性和召回分数来评估我们的模型性能。*

加载和预览数据:

首先,将数据下载到您的目录这里。

进口:

import pandas as pdfrom  .model_selection import train_test_split
from sklearn.metrics import accuracy_score, recall_score
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier, GradientBoostingClassifier

加载和预览:

df = pd.read_csv('data/raw/telecom_churn_data.csv')
df.head()

前 5 行数据

从这里我们可以看到,一行代表一个电信客户。

我们可以很快确定我们的目标变量是什么:churn

我不喜欢列标题中的空格,所以我们将改变它,检查我们的数据类型并检查任何丢失的数据(空值)。

df.columns = df.columns.str.replace(' ', '_')
df.info()

检查列

正如我提到的,我选择这个数据集是因为它已经相当干净了。我们的数据类型是有意义的,你可以看到我们没有null值。当然,看到3333 non-null并不一定意味着我们没有空值——有时我们的数据集中有伪装的空值。我已经检查了每一列的唯一值,并且可以确认数据在这一点上看起来是完整的(当然,如果您确实发现了我遗漏的可疑之处,请务必通知我!).

创建目标和特征变量:

# our target, 'y' variable:
y = df.churn# df of our features data 'X' - drop target
X = df.drop("churn", axis=1)

处理分类特征:

你可能已经注意到我们之前的df.info(),我们有 4 个object类型的柱子。这些列中有 3 列是有用的类别:stateinternational_planvoice_mail_plan

另一个对象列是phone_number,您猜对了,这是一个客户的电话号码。我认为,一个人的电话号码不应该对他们是否决定继续使用电话公司有任何大的影响,因此,出于这个原因,我选择简单地从我们的功能集中删除这个专栏。**

# drop phone_number column
X = X.drop('phone_number', axis = 1)

因此,现在让我们虚拟出剩余的 3 个分类列。这将会给我们的特性集增加很多列,反过来也会给我们的模型增加一些复杂性,但是为了我们的例子,我们现在不会太担心这个。

# create dummy variables for categorical columns
X = pd.get_dummies(X, drop_first = True)

要了解更多关于虚拟变量、一次热编码方法以及为什么我指定了drop_first = True(虚拟陷阱),请阅读本文。

这是一个再做一次X.head()的好机会,看看你的数据框现在是什么样子。

列车测试分离:

首先,我们将我们的Xy数据分成一个用于训练模型的训练集,和一个用于(你猜对了)测试模型的测试集。我选择在这里做一个0.25分裂。

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=15)

系统模型化

在我们的建模过程中,我主要是在实例化模型对象时使用它们的默认参数。我将在最后谈到超参数调整,但简而言之,所有的乐趣都在于调整参数,所以我想让你去探索。我想重点向你展示模型是如何通过使用它们的默认值来改变的。

为了简洁起见,我将简单地拟合模型,并给出一些指标来比较每个模型。

如上所述,我们将使用accuracy_scorerecall_score作为我们的衡量标准进行比较。

FSM——第一个低劣模型:单一决策树

要想知道我们的集成方法是否有效,我们首先需要知道一个单一的基础模型如何处理我们的数据。由于这是一个分类问题,我们将使用决策树作为我们的有限状态机。由于决策树有过度拟合的习惯,我将把max_depth设为 5。

# instantiate decision tree object with default params
dtc = DecisionTreeClassifier(max_depth = 5) # fit the model to our training data
dtc.fit(X_train, y_train)

结果:

精确度:

# calculate accuracy_score for training data:
print(accuracy_score(y_train, dtc.predict(X_train)))0.9559823929571829# calculate accuracy_score for test data:
print(accuracy_score(y_test, dtc.predict(X_test)))0.934052757793765

这是可疑的高,并强调了一些问题,我们有与准确性评分…

但是,就这里的准确性而言,这个模型做得并不太差,训练和测试分数之间也没有很大的差异。

# calculate recall_score for train data:
print(recall_score(y_train, dtc.predict(X_train)))0.7388888888888889# calculate recall_score for test data:
print(recall_score(y_test, dtc.predict(X_test)))0.6422764227642277

我们可以看到,训练和测试回忆分数之间的差别稍大一些。尽管如此,对于第一个模特来说,这些分数已经很不错了。

记住,对于这个问题,我们更关心召回分数,因为我们想抓住假阴性。召回是我们试图从这个模型中最大化的。

模型 2:随机森林

接下来,我们创建一个 max_depth 为 5 的随机森林模型。如果我们将n_estimators留空,一些版本的 sklearn 会发出警告,所以我在这里将其设置为 100。

# instantiate random forest classifier object
rft = RandomForestClassifier(n_estimators=100, max_depth= 5)# fit the model to the training data:
rft.fit(X_train, y_train)

结果:

精确度:

# calculate accuracy_score for training data:
print(accuracy_score(y_train, rft.predict(X_train)))0.8855542216886755# calculate accuracy_score for test data:
print(accuracy_score(y_test, rft.predict(X_test)))0.86810551558753

从我们的第一个模型开始,我们的准确度分数实际上已经下降了。让我们检查回忆:

# calculate recall_score for train data:
print(recall_score(y_train, rft.predict(X_train)))0.20555555555555555# calculate recall_score for test data:
print(recall_score(y_test, rft.predict(X_test)))0.1056910569105691

哇,我们的随机福里斯特模型的召回分数下降了!乍一看,这似乎很奇怪,但这可能是由多种原因造成的。需要记住的一个概念性原因是,单决策树模型是一个模型,而随机森林模型本质上是根据森林中所有树的投票做出最终预测的。由于这个原因,我们得到了比一棵树的‘意见’更准确的预测。

我们也没有考虑职业不平衡或者超参数,所以这个例子有点做作。

让我们以同样的方式继续,看看如何实现 AdaBoosting 和 Gradient Boosting 模型,并比较它们的性能:

模型 3: AdaBoosting

# instantiate adaboost classifier object
abc = AdaBoostClassifier(random_state = 15)# fit the model to the training data:
abc.fit(X_train, y_train)

结果:

精确度:

# calculate accuracy_score for training data:
print(accuracy_score(y_train, abc.predict(X_train)))0.8979591836734694# calculate accuracy_score for test data:
print(accuracy_score(y_test, abc.predict(X_test)))0.86810551558753

令人惊讶的是,我们对测试数据的准确性分数保持不变,但我们对测试数据的准确性分数有所提高。

回忆:

# calculate recall_score for train data:
print(recall_score(y_train, abc.predict(X_train)))0.4638888888888889# calculate recall_score for test data:
print(recall_score(y_test, abc.predict(X_test)))0.3333333333333333

与随机森林模型相比,我们的回忆分数有了显著的提高。

让我们看看梯度增强的表现。

模型 4:梯度推进

# instantiate gradient boost classifier object
gbc = GradientBoostingClassifier(random_state = 15)# fit the model to the training data:
gbc.fit(X_train, y_train)

结果:

精确度:

# calculate accuracy_score for training data:
print(accuracy_score(y_train, gbc.predict(X_train)))0.9731892757102841# calculate accuracy_score for test data:
print(accuracy_score(y_test, gbc.predict(X_test)))0.9508393285371702

目前为止我们最高的准确率。他们离我们的第一个决策树模型不远了。初步检查也没有明显的过度装配迹象。

回忆:

# calculate recall_score for train data:
print(recall_score(y_train, gbc.predict(X_train)))0.8194444444444444# calculate recall_score for test data:
print(recall_score(y_test, gbc.predict(X_test)))0.7235772357723578

再一次,这是我们目前为止最高的召回分数,这确实比我们的第一个模型好很多。

给定这 4 个模型,我们将选择梯度推进模型作为我们的最佳选择。

最后注意事项和后续步骤:

正如你所看到的,使用这些模型并不困难——我们只是简单地创建模型对象并比较结果——我们没有太深入地思考幕后发生了什么。很容易创建和试验这些不同的方法,看看哪种方法更好。

然而,应该注意的是,这是一个非常人为的例子,仅仅是为了向你展示你可以如何使用这些模型,并且集成方法通常比单一模型做得更好。由于我们使用了所有的默认参数,这些模型中呈现的指标不一定会产生有意义的影响,因此下面是开始思考和了解的一些后续步骤…

超参数调谐:

超参数是在学习过程之前设置的参数值。这不同于我们在训练模型后发现的模型参数。

如果您熟悉线性回归,那么斜率截距参数就是我们试图通过训练模型来优化的模型参数。

我们在这个例子中调整的超参数的一个例子是当我们设置max_depth = 5时,我们在拟合模型之前设置这个*。*

我知道你可能没有接触过很多这些概念,所以随着你的接触,这些概念会变得更加清晰。但是我鼓励您尝试不同的超参数,看看模型如何随着不同的参数调整而变化。

**提示:**在 Jupyter 和其他 ide 中,任何方法或类的括号内的shift + tab允许您快速检查对象所采用的参数。对于模型类,这将显示您可以使用的大多数超参数。

不要低估“修修补补”的价值

这里有一篇关于超参数调整和特征工程的文章。

阶级不平衡:

我可以用一行代码来解释什么是阶级不平衡:

y.value_counts()False    2850
True      483
Name: churn, dtype: int64

正如您在这里看到的,我们将近 86%的数据被标记为False。这意味着我们的模型可能变得不公平地偏向False预测,仅仅是因为我们数据中那个标签的比率。这就是我们所说的“阶级不平衡”问题。

有很多方法可以处理职业不平衡,包括职业权重和 SMOTE。将这一点与我们的数据集一起考虑将会极大地改进我们的模型。

包扎

我希望您已经看到了这些集成方法如何改进您的模型的价值,并且我鼓励您在不同的数据集上尝试它们以获得对它们的感觉。随着您对这些算法背后的理论、它们的超参数、应用正则化和类平衡方法的了解越来越多,您将对这些功能如何发挥以及它们对您的模型有何影响有一个良好的开端。

快乐学习!

脚注

  • *有些人可能会说,误报对公司来说也是昂贵的,因为你在留住客户上花了钱,而客户无论如何都会留下来。我让您来思考这个问题,并尝试不同的评分标准。这里有一篇文章介绍了您可以研究的一些不同指标。
  • **我让您来探索您可能想要如何处理phone_number功能。
  • ***注意,在这个例子中,我没有进行特征工程。调整正则化超参数对此也有帮助。

引文

感谢我向读者推荐的博客和论文的作者,来补充这个博客。

集成方法:比较 Scikit Learn 的投票分类器和堆叠分类器

原文:https://towardsdatascience.com/ensemble-methods-comparing-scikit-learns-voting-classifier-to-the-stacking-classifier-f5ab1ed1a29d?source=collection_archive---------29-----------------------

使用 Titanic 数据集比较 scikit 学习投票分类器和堆叠分类器。

照片由佩里·格罗内在 Unsplash 上拍摄

他们说,两个脑袋比一个要好。有时在许多机器学习项目中,我们希望使用集成方法来利用协同的力量。投票和堆叠分类器为我们带来了结合 2 个或更多机器学习模型以获得更高预测性能的好处。

投票分类器

投票分类器的工作方式类似于选举系统,其中基于一组机器学习模型成员的投票系统对新数据点进行预测。根据 scikit_learn 的文档,可以在硬投票和软投票类型之间进行选择。

硬投票类型应用于多数规则投票的预测类标签。这使用了“多数决定投票”的思想,即做出有利于拥有半数以上投票的人的决定。

表决基于组成集合的各个估计器的预测概率之和的 argmax 来预测类别标签。在良好校准/拟合的分类器的集成的情况下,经常推荐软投票。

例如:如果*模型 1* 预测 ***A*** ,而*模型 2* 预测 ***B*** ,而*模型 3* 预测 ***A*** 。*投票分类器*(with***voting =‘hard’***)返回 ***A*** 。在平局的情况下,投票分类器将基于升序选择类别。

由马库斯·斯皮斯克在 Unsplash 上拍摄的照片

堆垛分级机

堆叠包括在同一数据集上组合来自多个机器学习模型的预测。我们首先在我们的数据集上指定/建立一些称为基础估计器的机器学习模型,来自这些基础学习器的结果然后作为我们的堆叠分类器的输入。堆叠分类器能够了解我们的基本估计值何时可信或不可信。叠加允许我们通过将每个估计量的输出作为最终估计量的输入来利用每个估计量的强度。

在使用堆叠分类器时,可以选择在基础学习者级别或在最终估计器上应用交叉验证。使用 scikit learn stacking 分类器,基础学习器适用于全 X,而最终估计器使用基础学习器的交叉验证预测来训练。

多层堆叠也是可能的,其中在构建最终估计器之前构建基础学习器的层。

值得注意的是,在考虑集合方法来改进我们的预测之前,建议:

  1. 在可能的情况下,获取更多的数据。我们输入到模型中的数据越多,模型需要学习的学习示例就越多。
  2. 特征工程。
  3. 我们模型的超参数调整。

方式和方法

在这个例子中,我们考虑了“泰坦尼克号:机器从灾难中学习”。我们分割训练数据集,以便能够对我们的模型进行自己的评估。数据集也可以在这里找到:【https://www.kaggle.com/c/titanic/data】T2。然后,我们构建一个逻辑回归、最近邻和随机森林算法。

我们使用上述 3 种算法作为 scikit learn 的投票和堆叠分类器的估计器,并比较它们预测的 f1 分数。

注意:堆叠分类器仅在 0.22 版本的 Scikit-Learn 中可用,而投票分类器从 0.17 版本开始可用。

观察结果

本例中投票和堆叠分类器的 f1_score 相同。

  1. 在投票分类器和堆叠分类器中,重要的是要确保基本估计量能够很好地给出准确的预测。正如人们所说的,‘垃圾进,垃圾出’,如果估计器放入垃圾,那么任何一种集成方法都会产生垃圾。
  2. 重要的是要注意,堆叠分类器在基础模型(或估计器)上建立模型,从而增加对数据集的拟合。这也增加了堆积分类器过度装配的趋势,尤其是在多层堆积的情况下。
  3. 投票分类器的性能很大程度上取决于基本模型的结果。因此,为了更好地预测,建议使用合适的估计量作为软投票类型的基础模型。
  4. 有时候,集合方法并不是真的需要。😉

结论

很难确定投票或堆叠分类器哪个更好。明智的做法是了解它们中每一个的用途/工作原理。这种理解将有助于决定在什么时候应用它们是最好的。

我希望这篇文章对你有帮助。这里是我的 Twitter 句柄和 Linkedin 页面。链接到 github repo 这里。

如果你喜欢这篇文章,你可以考虑给我买☕️.咖啡

Vielen Dank😊

基于 OptimalFlow 的机器学习集成模型选择与评估

原文:https://towardsdatascience.com/ensemble-model-selection-evaluation-in-machine-learning-by-optimalflow-9e5126308f12?source=collection_archive---------48-----------------------

用简单的代码选择最佳模型的简单方法

Artem Sapegin 在 Unsplash 上拍摄的照片

在机器学习工作流中,模型选择是创建基线模型的重要步骤。这个步骤通常是一个耗费时间的过程,并且需要更多的模型调整实验。

因此,我编写了一个名为 OptimalFlow 的软件包,其中有一个集成模型选择模块 autoCV ,它可以通过流行的监督建模算法进行交叉验证,还可以在超参数上应用“懒惰”搜索来选择最佳模型。

为什么我们使用 OptimalFlow ?你可以阅读另一个关于它的介绍的故事:一个 Omni-ensemble 自动化机器学习——optimal flow

autoCV 模块目前覆盖了大多数主流的监督模型,包括 11 个分类和 14 个回归估计量,即 XGBoost、Random Forest、MLP 和 SVM 等。

您可以阅读optimal flowoptimal flow 的* autoCV 模块的 文档。此外, OptimalFlow 还提供了特征预处理、模型选择、模型评估、流水线簇遍历实验(PCTE) 自动机器学习模块。*

你可以阅读它的集成特征选择实现的另一个故事:通过 optimal flow在机器学习中进行集成特征选择的简单方法。

这里我们将有一个演示,使用 OptimalFlow ,在几分钟内完成一个分类问题的模型选择。我们使用一个干净的泰坦尼克号数据集作为输入。

第一步:通过 pip: 安装 OptimalFlow

*pip install OptimalFlow*

第二步:导入库:

*import pandas as pd
from OptimalFlow.autoCV import dynaClassifier,evaluate_clf_model
import joblib*

注意:这个演示使用的是基于网格搜索的动态分类器类;或者,您可以使用基于随机搜索的 fastClassifier 类,尽管这是一种在运行时间和解决方案质量之间的权衡(参见 autoCV 模块的 文档 中的更多细节)。

第三步:导入输入数据集:

*tr_features = pd.read_csv('./data/classification/train_features.csv')
tr_labels = pd.read_csv('./data/classification/train_labels.csv')#Splitting validate data sets for models evaluation
val_features = pd.read_csv('./data/classification/val_features.csv')
val_labels = pd.read_csv('./data/classification/val_labels.csv')*

清理过的泰坦尼克号数据集 train _ features.csv

清理过的泰坦尼克号数据集 train _ label.csv

第四步:运行 autoCV 模块:

我们将交叉验证拆分策略确定为 5 个文件夹。并且使用 fit_clf() 方法来训练集成方法中的模型,并且自动保存每个模型的具有最高 CV 分数的参数调整估计器。然后,优化的估计量全部保存到。/plk 文件夹进行进一步的模型验证。

*# We customize models cadidates for this demo:
custom_cv = ['lgr','svm','mlp','rf','ada','gb','xgb']*# Set input_form_file = False, when label values are array. Select 'True' from Pandas dataframe.*clf_cv_demo **=** dynaClassifier**(**custom_estimators = custom_cv, random_state **=** **13,**cv_num **=** **5,**input_from_file **=** True**)***# Select detail_info = True, when you want to see the detail of the iteration*clf_cv_demo**.**fit**(**tr_features**,**tr_labels**)***

然后,我们添加一些模型验证的代码,从保存的模型 pickles 中选择最优的模型。

*models = {}for mdl in ['lgr','svm','mlp','rf','ada','gb','xgb']:models[mdl] = joblib.load('./pkl/{}_clf_model.pkl'.format(mdl))for name, mdl in models.items():evaluate_clf_model(name, mdl, val_features, val_labels)*

一切就绪!以下是输出结果:

******OptimalFlow***** autoCV Module **===>** lgr_CrossValidation **with** **5** folds**:**Best Parameters**:** **{**'C'**:** **1,** 'random_state'**:** **13}**Best CV Score**:** **0.7997178628107917**Progress**:** **[***###-----------------] 14.3%******OptimalFlow***** autoCV Module **===>** svm_CrossValidation **with** **5** folds**:**Best Parameters**:** **{**'C'**:** **0.1,** 'kernel'**:** 'linear'**}**Best CV Score**:** **0.7959619114794568**Progress**:** **[***######--------------] 28.6%******OptimalFlow***** autoCV Module **===>** mlp_CrossValidation **with** **5** folds**:**Best Parameters**:** **{**'activation'**:** 'tanh'**,** 'hidden_layer_sizes'**:** **(50,),** 'learning_rate'**:** 'constant'**,** 'random_state'**:** **13,** 'solver'**:** 'lbfgs'**}**Best CV Score**:** **0.8184094515958386**Progress**:** **[***#########-----------] 42.9%******OptimalFlow***** autoCV Module **===>** rf_CrossValidation **with** **5** folds**:**Best Parameters**:** **{**'max_depth'**:** **4,** 'n_estimators'**:** **250,** 'random_state'**:** **13}**Best CV Score**:** **0.8240521953800035**Progress**:** **[***###########---------] 57.1%******OptimalFlow***** autoCV Module **===>** ada_CrossValidation **with** **5** folds**:**Best Parameters**:** **{**'learning_rate'**:** **0.1,** 'n_estimators'**:** **100,** 'random_state'**:** **13}**Best CV Score**:** **0.824034561805678**Progress**:** **[***##############------] 71.4%******OptimalFlow***** autoCV Module **===>** gb_CrossValidation **with** **5** folds**:**Best Parameters**:** **{**'learning_rate'**:** **0.01,** 'max_depth'**:** **3,** 'n_estimators'**:** **300,** 'random_state'**:** **13}**Best CV Score**:** **0.8408746252865456**Progress**:** **[***#################---] 85.7%******OptimalFlow***** autoCV Module **===>** xgb_CrossValidation **with** **5** folds**:**Best Parameters**:** **{**'learning_rate'**:** **0.1,** 'max_depth'**:** **3,** 'n_estimators'**:** **200,** 'verbosity'**:** **0}**Best CV Score**:** **0.8464292011990832**Progress**:** **[***####################] 100.0%*lgr **--** Accuracy**:** **0.775** **/** Precision**:** **0.712** **/** Recall**:** **0.646** **/** Latency**:** **0.0**ms
svm **--** Accuracy**:** **0.747** **/** Precision**:** **0.672** **/** Recall**:** **0.6** **/** Latency**:** **2.0**ms
mlp **--** Accuracy**:** **0.787** **/** Precision**:** **0.745** **/** Recall**:** **0.631** **/** Latency**:** **4.1**ms
rf **--** Accuracy**:** **0.809** **/** Precision**:** **0.83** **/** Recall**:** **0.6** **/** Latency**:** **37.0**ms
ada **--** Accuracy**:** **0.792** **/** Precision**:** **0.759** **/** Recall**:** **0.631** **/** Latency**:** **21.4**ms
gb **--** Accuracy**:** **0.815** **/** Precision**:** **0.796** **/** Recall**:** **0.662** **/** Latency**:** **2.0**ms
xgb **--** Accuracy**:** **0.815** **/** Precision**:** **0.786** **/** Recall**:** **0.677** **/** Latency**:** **5.0**ms*

现在,我们可以找到带有{'learning_rate': 0.01,' max_depth': 3,' n_estimators': 300,' random_state': 13}的 GradientBoost 是由 autoCV 选择的最优模型,其中具有最高的准确度和精确度分数,具有较低的召回率。

当您需要了解型号选择过程的更多细节时,您可以通过 autoFlow 模块找到自动生成的日志文件。

一切就绪! OptimalFlowautoCV 模块完成繁琐的选型&超参数实验。简单容易,对吧?😎

关于**的相关阅读optimal flow*:***

使用 OptimalFlow 在机器学习中进行集成特征选择——使用简单代码选择顶级特征的简单方法

端到端 OptimalFlow 自动化机器学习教程结合真实项目-公式 E 圈数预测第 1 部分

端到端 OptimalFlow 自动化机器学习教程结合真实项目-公式 E 圈数预测第二部分

用 OptimalFlow Web App 建立无代码自动机器学习模型

关于我:

我是一名医疗保健和制药数据科学家以及大数据分析和人工智能爱好者。我开发了 OptimalFlow 库,帮助数据科学家以一种简单的方式构建最佳模型,并通过简单的代码实现机器学习工作流的自动化。

作为一名拥有多年分析经验的大数据洞察寻求者、流程优化者和人工智能专家,我使用数据科学中的机器学习和问题解决技能将数据转化为可操作的洞察,同时提供战略和量化产品作为最佳结果的解决方案。

你可以在我的 LinkedIn 或者 GitHub 上和我联系。

用于分类的集成模型

原文:https://towardsdatascience.com/ensemble-models-for-classification-d443ebed7efe?source=collection_archive---------30-----------------------

堆叠表现不佳的模型以创建更强的模型。他们从彼此的错误中吸取教训

您已经清理了数据并移除了所有相关要素。您还可视化了数据集,并且知道类标签是可分离的。你也调整了你的超参数。太好了,但是为什么你的模型表现不好呢?

什么是模型堆叠?

你试过叠模型吗?传统上,我们用单一的算法来模拟我们的数据。这可能是逻辑回归、高斯朴素贝叶斯或 XGBoost。

作者图片:传统 ML 模型

系综叠加模型的作用如下:

作者图片:堆叠 ML 模型

元学习者

用于组合基本估计器的算法被称为元学习器。我们可以确定我们希望该算法如何响应来自其他模型(本例中为分类器)的不同预测。它可以是:

  1. 估计量的预测
  2. 预测以及原始训练数据

但是这仅仅是最后一类**预测吗?**不,您可以选择推动决策的指标:

  1. 可能是'predict_proba''predict'或者两者都是
  2. 也可以使用 sklearn 中的其他'decision_function'

最终的元学习者可以是任何估计者(默认情况下,sklearn 有逻辑回归)

我们采用基线高斯朴素贝叶斯估计器,并将所有未来结果与其预测准确度进行比较:

rf = OneVsRestClassifier(estimator = GaussianNB())cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=20)n_scores = cross_val_score(rf, X, y, scoring='f1_weighted', cv=cv, error_score='raise')print(n_scores)
print('Baseline scores \n mean f1 weighted: %.3f with a %.3f standard deviation in scores ' % (np.mean(n_scores), np.std(n_scores)))

作者图片:基本模型分数

创建多层调优估值器,并将它们堆叠在一起

图片作者:堆叠模型胜过其他模型!

作者图片:堆叠模型优于所有分类器

最终,我们想要一个 F1 值高于 81.1%的分类器,我们最终用堆叠模型得到了 96.7%的 F1 值。

在医疗保健设置中,我将接受相对于 SVC 模型的 0.1%的改进,并且不会牺牲堆叠模型的复杂性!

你可以在这里找到完整的代码:https://github . com/gaurikatyagi/Machine-Learning/blob/master/class ification/Ensemble % 20 model-% 20 stacked % 20 class ification . ipynb

现在就去堆栈…

对对立例子的集成鲁棒性

原文:https://towardsdatascience.com/ensemble-robustness-to-adversarial-examples-ff93033aae1a?source=collection_archive---------69-----------------------

具有不同梯度关系的模型对

去年夏天,我有幸与一位才华横溢的本科生研究员 Romain Speciel 合作了一个项目,该项目旨在研究如何以一种提高对抗样本鲁棒性的方式来规范模型集合。我们主要关心的是减少模型之间对立例子的可移植性,因为这是黑盒设置中的一个主要威胁。这篇文章旨在展示在预印本中进一步详述的工作,同时提供额外的直觉。

对抗性例子的背景

我们将用 f 来指代一个模型,它的输出应该通过上下文显而易见:有时是预测的标签,有时是预测的概率。

图像分类模型的一个相反的例子是通过以人类不可察觉的方式扰动输入图像而获得的图像,然而这导致模型对输入进行错误分类。给定样本-标签对 x,y 的对立输入集被精确定义为

其中 x 是原始图像,𝜀被选择为使得人类不能辨别原始图像和扰动图像之间的差异,并且 p 通常被选择为 1、2 或∞。因此,为了找到对抗输入,必须解决下面的优化问题

这种受约束的优化试图最大化给定样本-标签对的损失函数,同时还保持制作的输入 x’足够接近 x,使得人类不能区分这两个图像。

在 ImageNet 上训练的 ResNet-50 模型的典型对抗示例

这不是一个要解决的简单的优化问题,但是我们可以通过获取约束并将其嵌入到 x '的构造中来简化它。神经网络通常用某种梯度下降的变体来训练,以最小化关于模型参数的期望损失函数

类似于优化模型参数以适应数据集(即学习),我们可以通过利用模型的可区分性来优化输入。我们使用损失相对于输入图像的梯度在像素空间方向上移动,使得损失最大化,如下

其中 sgn 是符号函数,1 表示正值,-1 表示负值,否则为 0。通过使用 signum 函数,我们控制 L-∞范数的大小,使得扰动图像和原始图像之间的最大像素差至多为𝜀.这被称为 f ast 梯度符号(FGS)攻击,是一种非常有效的制造对抗例子的方法。然而,这是最弱的攻击,并且假设模型的输出表面是线性的。我们注意到,对抗性扰动不是唯一的,对于一个给定的输入,可能存在多个扰动,所有这些都会导致分类器对它进行错误分类。此外,对立的例子特定于给定的模型,尽管可转移现象表明对立的例子跨网络体系结构转移,甚至跨模型类转移。

梯度的重要性

考虑精度差不多的两个型号 fg 。如果 fg 的损失梯度之间的角度大于𝛑/2,那么在 f 的梯度方向上扰动输入 x 将降低 f 的预测置信度,但增加 g 的置信度。这在这个故事的封面图的子图 c)中得到最好的说明,在红色箭头的底部,模型输出表面相交并具有相同的值,而梯度指向相反的方向。如果我们可以假设

那么理论上 FGS 的攻击不可能同时愚弄 f 和 g。此外, fg 之间的不一致,假设它们都具有相似的测试集性能,可以用来标记潜在的敌对输入。这不是对对抗性例子的直接防御,但是检测也很重要,并且让对抗性例子不在模型之间转移也可以降低黑盒设置中的攻击成功率。在实践中实现这样的梯度关系仅仅需要将正则化项添加到期望的损失函数(例如交叉熵损失)中。如果所讨论的集合仅由两个模型组成,则最佳正则化项将最小化余弦相似性

模型渐变之间。梯度的正则化相当抽象,所以让我们从模型使用的特征的角度来讨论这意味着什么。正交梯度意味着模型在进行分类时使用不相交的特征集,使得扰动模型 f 的最显著特征对模型 g 的预测几乎没有影响。请注意,这并不限制模型所使用的特征之间的关联。比如对汽车的图像进行分类时, f 可能会使用轮胎作为特征, g 可能会使用车门。即使这些特征可能在图像中同时出现(即这些特征是相关的),扰动图像使得 g 不再检测图像中的门也不会影响 f 的预测。

继续以汽车为例,当 f 的输出随着轮胎的存在而增加,但随着车门的存在而减少,反之亦然 g 的情况下,可以实现余弦相似度小于 0 的坡度。在任一情况下,梯度正则化都是有代价的,因为集合中的模型不使用相同的特征,因此不能在个体基础上实现最大性能。在标准精度和敌对干扰下的精度之间有一个基本的权衡。在有许多与标签弱相关但在一起使用时具有高度预测性的特征的情况下,如果这些特征不稳健,那么对它们的微小改变会显著改变输出。

在实践中,既优化两个模型集合的精度又调整模型梯度的损失函数看起来像

第三项使梯度正则化,进一步的检查表明它需要二阶优化,因为我们优化的是梯度而不是参数。

测量集合合作

涉及的模型多了会怎么样?最小化模型之间的成对余弦相似性已经不够了。相反,我们必须考虑所有模型的对立子空间的交集,并以最小化该子空间的方式正则化模型梯度。完整的细节可以在预印本中找到,因此我们在这里重点关注该方法背后的动机,并证明为什么成对余弦相似性在考虑两个以上模型时不理想,正如 Kariyappa 和 Quershi 所做的那样。假设我们的组合由三个模型组成。然后,最大化成对余弦相似性将导致接近下面的蓝色渐变排列

三模型系综的梯度排列

请注意,对于具有 2D 梯度的三个模型,即𝛑/3.,只有一个成对角度最大化成对余弦相似性然而,我们不需要如此强的条件,因为绿色和黄色梯度的可视化也会降低模型之间的可转移性。我们的方法能够获得更少的限制条件,这使得优化更容易。为了进一步说明模型梯度如何影响对立子空间的大小,下图用橙色显示了两个模型集合的对立子空间。

两模型集成的敌对子空间依赖于梯度

位于橙色区域的任何扰动都负向投射到 fg 的梯度上,从而降低两个模型的预测置信度。为了测量集成中的模型如何合作来减少可以同时欺骗所有模型的敌对子空间,我们引入了梯度多样性评级(GDR):

简而言之,该评级测量敌对子空间的体积,该子空间以相同的方式同时愚弄集合中的所有模型(即,它们都错误地预测了相同的错误类别),通过与模型相同维数的单位球体的体积来归一化。看一下预印本看看如何最小化不同大小的系综的 GDR。在这里,我们只展示了表明 GDR 和对抗性攻击成功率之间存在相关性的结果,因此最小化 GDR 是系综的期望属性。

GRD 与时尚达人的攻击成功率

总之,由于 ML 工程师能够控制模型梯度,并创建攻击不会从一个模型转移到另一个模型的集合,因此黑盒防御设置具有更好的防御对手的可能性,从而为敌对示例创建了一种可能的检测机制。关于这些结果如何推广到其他数据集,以及 GDR 正则化有效的一些假设有多现实,还有更多需要了解。在这两种情况下,我们认为这是一个值得追求的途径,并且对对抗性例子的几何理解可以产生更有原则的防御方法。

集成技术

原文:https://towardsdatascience.com/ensemble-techniques-c1b0831a8865?source=collection_archive---------58-----------------------

集成技术的高级概述

我们知道决策树是一种非常强大的技术,但是我们可以使用集成建模技术来改进它。

Ensemble 的基本意思是‘在一起’,所以 ensemble 模型就是一组一起工作的基础模型。

为了使集合模型更好地工作,你应该选择不同的基础模型,也就是说,这些模型越不同,你就越能更好地组合它们。

在这篇博客中,我将向你介绍以下合奏技巧:

  1. 装袋
  2. 助推

使用集合技术的好处

每个模型都有自己的优点和缺点,所以通过使用这种技术,我们得到的最终模型具有模型的所有优点,而掩盖了单个模型的缺点。所以,模型表现更好。

制袋材料

Bagging 也被称为 Bootstrap Aggregation ,用于提高机器学习算法的准确性。

装袋的主要目的是在不影响偏差的情况下减少方差,并有助于避免过度拟合。

在上图中,Dn 是我们的训练数据,包含我们的类标签和预测标签 yi。每个模型 Mi 是使用大小为 m (m

First step of the Bagging is **自举,**的每个 Di 构建的,这只不过是带有替换的随机采样。因此,每个模型接收具有不同数据子集的样本。

打包的第二步是**聚合,**这一步是组合我们从每个模型获得的输出。对于每个问题,这一步是不同的,取决于您遇到的问题类型。

  1. 对于分类问题,我们只是采用多数投票来预测它属于哪个类标签。
  2. 对于回归问题,我们采用均值/中值来预测值,因为输出可以是任何实数。

最流行的套袋技术之一是随机森林。

增压

Boosting 指的是将弱学习者转化为强学习者的一系列机器学习算法。

提升的主要目的是在保持我们的方差较低的同时,增加组合并减少模型的偏差。

boosting 算法将数据输入到第一个模型,然后第一个模型的输出作为第二个模型的输入。这里,我们在第一个模型中得到的误差被第二个模型减小了。

在上图中,每个模型都能够对负点或正点进行分类,但是每个模型的误分类误差都非常高。因此,在 boosting 的帮助下,我们将所有掩盖了彼此缺点的模型结合起来。所以,我们通过组合弱模型得到了一个强模型。

我们得到的最终模型能够对这些点进行最佳分类。

XGBoost 是最流行的提升技术之一。

我希望你对什么是合奏技术以及它们有多强大有了一个高层次的了解。

集成:机器学习中唯一(几乎)免费的午餐

原文:https://towardsdatascience.com/ensembles-the-almost-free-lunch-in-machine-learning-91af7ebe5090?source=collection_archive---------11-----------------------

用 PyTorch 和 NumPy 建立神经网络的最佳集成

照片由 Riho Kroll 在 Unsplash 上拍摄

这篇文章附带的笔记本可以在这里找到。

感谢 捷季扬娜德罗博特 伊戈尔波兹杰耶夫 的评论和建议。

摘要

在这篇文章中,我将讨论集成优化这个有些被忽视的话题。我首先简要概述了一些常见的合奏技术,并概述了它们的弱点。然后,我介绍了一个简单的集成优化算法,并演示了如何用 Python 和 PyTorch 将它应用于构建神经网络集成。在这篇文章的最后,我讨论了集成方法在深度学习中的有效性,这是在当前关于神经网络损失曲面几何的文献的背景下进行的。

关键要点:

  • 强集成由既准确又多样的模型组成
  • 存在允许不适合作为 ML 模型的直接优化目标的现实目标函数的集成方法(考虑使用交叉熵进行训练,同时对一些其他度量感兴趣,如准确性)
  • 集成不仅通过抑制神经网络对噪声的固有敏感性,而且通过组合质量上不同且不相关的解来提高神经网络的性能

帖子组织如下:
一、简介
二、帖子。集成优化
III。构建神经网络集成
IV。神经网络集成:损失面几何形状的作用
五、结论

一.导言

集合是模型的集合,通过组合它们的预测来超越其中的每一个。强集成包括精确的模型,它们本身表现良好,但在犯不同错误的意义上是多样化的。这让我产生了深深的共鸣,因为我是一名金融专业人士——组合类似于建立一个由许多单个资产组成的稳健投资组合,并牺牲其中一些资产的更高预期回报,以通过分散投资来整体降低风险。“多元化是金融领域唯一的免费午餐”这句话出自现代投资组合理论之父哈里·马科维茨。鉴于集合和多样化在概念上是相关的,而且在某些问题上,两者在数学上是等价的,我决定给这篇文章起个名字。

为什么差点不过呢?因为考虑到最强大的模型(是的,神经网络)对资源的渴求,计算成本总是一个挥之不去的问题。除此之外,集成还会模糊单个模型的决策边界,从而损害决策树等更透明的机器学习算法的可解释性——这一点并不真正适用于神经网络,因为可解释性问题已经在单个模型层面上出现了。

构建合奏有几种方法:

  • Bagging 引导训练集,在产生的样本上估计模型的许多副本,然后平均它们的预测。
  • 增强依次对训练样本重新加权,迫使模型关注具有较高损失值的训练样本。
  • S 跟踪使用一个单独的验证集来训练一个结合多个模型预测的元模型。

例如,参见Gilbert Tanner的这篇文章或Joseph Rocca的文章或 Juhi Ramzai 的文章以获得这些方法的广泛概述。

当然,上面的方法都有一些共同的问题。首先,给定一组训练好的模型,如何选择最有可能概括得好的模型?在堆叠的情况下,这个问题将读作“如何将集合候选的数量减少到可管理的数量,以便堆叠模型可以处理它们,而没有大的验证集或高的过度拟合风险?”好吧,只需选择表现最好的模型,并应用与它们的损失成反比的权重,对吗?不对。尽管这通常是一个很好的起点。回想一下,一个好的集合由精确的和多样的模型组成:将几个高度精确的模型与强相关的预测结合在一起通常会导致所有的模型都采用相同的 rake。

第二个问题更微妙。通常,我们训练的机器学习算法几乎都是美化的特征提取器,即现实生活应用中的目标可能与用于训练模型的损失函数明显不同。例如,交叉熵损失是深度学习中分类任务的主要内容,因为它在优化期间具有可微性和稳定的数值行为,然而,根据我们可能对准确性、F1 分数或假阴性率感兴趣的领域。作为一个具体的例子,考虑对洪水或飓风等极端天气事件进行分类,在这种情况下,产生第二类错误(假阴性)的成本可能会高得惊人,甚至会导致准确性,更不用说交叉熵作为评估指标了。类似地,在回归设置中,常见的损失函数是均方误差。例如,在金融领域,为样本中的每项资产训练相同的模型来预测下一阶段的回报是很常见的,而在现实中,多个投资组合中有数百项资产的优化目标与强化学习和最优控制中遇到的目标类似:多个时间范围以及状态和路径依赖。在任何情况下,你既不被低 MSE 评判,也不被低 MSE 补偿(除非你在学术界)。

在这篇文章中,我详细讨论了卡鲁阿纳等人(2004) 提出的集成优化算法,它解决了上述问题。该算法可以广义地描述为无模型的贪婪堆叠,即在每个优化步骤,该算法或者向集合添加新的模型,或者改变当前成分的权重,从而最小化总损失,而没有任何支配性的可训练模型来指导选择过程。卡鲁阿纳等人(2004) 的方法配备了几个功能,可以缓解过拟合问题,还可以构建集成优化自定义指标,这些指标可能不同于用于训练单个模型的指标,从而解决了第二个问题。我进一步演示了如何应用该算法:首先,一个具有封闭形式解决方案的简单示例,接下来,通过为 MNIST 数据集构建一个最佳神经网络集合来解决一个现实问题(完整的 PyTorch 实现可以在这里找到)。在这篇文章的结尾,我探索了支持深度学习中集成有效性的机制,并讨论了当前关于损失曲面几何在神经网络泛化属性中的作用的文献。

本文的其余部分结构如下:第二节介绍了卡鲁阿纳等人(2004) 的总体优化方法,并用一个简单的数值例子加以说明。在第三部分的中,我为 MNIST 数据集优化了一组神经网络( PyTorch 实现)。第四节简要讨论了深度学习中优化前景的文献及其对集成的影响。第五节结束。

二。集成优化: 卡鲁阿纳等人(2004) 算法

卡鲁阿纳等人(2004 年) 的方法相当简单。给定一组训练模型和它们在验证集上的预测,它们的集成构造算法的变体如下:

  1. 设置inint_size 初始集合中模型的数量和max_iter —最大迭代次数
  2. 通过平均它们的预测和计算总集合损失,初始化具有init_size最佳性能模型的集合
  3. 将集合中的模型(带有替换)添加到集合中,这最小化了总集合损失
  4. 重复步骤 3,直到到达max_iter

这个版本的算法包括几个旨在防止验证集过拟合的特性。首先,用几个性能良好的模型初始化集成,形成一个强初始集成;第二,用替换来绘制模型实际上保证了验证集上的集合损失不会随着算法迭代的进行而增加——如果添加另一个模型不能进一步改善集合损失,则算法添加现有模型的副本,实质上调整它们在最终预测中的权重。这种权重调整属性允许将该算法视为无模型堆叠。这种方法的另一个有趣的特征是,用于集合构建和用于训练单个模型的损失函数不需要相同:如前所述,我们通常用特定的损失函数来训练模型,因为它在数学或计算上方便,(合理地)希望模型能够很好地用难以直接优化的相关性能度量来概括。事实上,与例如假阴性率相比,在恶性肿瘤分类任务中测试集上的交叉熵值不应该是我们主要关心的。

以下 Python 函数实现了该算法:

卡鲁阿纳等人(2004) 集成选择算法

考虑下面的玩具例子:假设我们有 10 个零均值正态分布不相关预测的模型。此外,假设预测的方差从 10 线性减少到 1,即第一个模型具有最高的方差,而最后一个模型具有最低的方差。给定一个数据样本,目标是建立一个集合,使相对于地面真实值 0 的均方误差最小化。请注意,在卡鲁阿纳等人(2004) 算法的上下文中,“构建一个集合”意味着为每个模型的预测分配一个介于 0 和 1 之间的权重,以便加权预测使 MSE 最小化,服从所有权重总和为 1 的约束。

通过将模型的预测视为某些资产的回报,并将优化目标视为最小化投资组合方差,金融爱好者会认识到最小方差优化问题的特殊情况。这个问题有一个封闭的解:

其中 w 是模型权重的向量,σ是预测的方差-协方差矩阵。在我们的例子中,预测是不相关的,并且的非对角元素为零。以下代码片段通过使用ensemble_selector函数和分析方法解决了这个玩具问题,它还通过平均预测构建了一个简单的集合:

下面的图 1 比较了集合优化(蓝色)和封闭形式解决方案(橙色)隐含的权重。结果非常接近,特别是考虑到我们使用真实方差而不是样本估计来计算解析解。请注意,尽管预测不确定性较低的模型获得了较高的权重,但高不确定性模型的权重不会变为零:预测是不相关的,我们总是可以通过添加不相关的变量(当然是有限方差)来降低随机变量加权和的方差。

*图 1:估计的与理论的最佳重量*

下一张图中的蓝色实线描绘了算法的前 25 次迭代的总体损失。黑色虚线和红色虚线分别表示由最佳单一模型和平均所有模型预测的简单集合获得的损失。在大约五次迭代之后,优化的集合击败了原始集合,此后获得显著更低的 MSE 值。

图 2:系综损失与优化步骤

如果池中模型数量非常多怎么办?

如果模型池非常大,一些模型可能会完全偶然地超过验证集。卡鲁阿纳等人(2004 年)建议使用装袋来解决这个问题。在这种情况下,该算法应用于从池中随机抽取的 M 个模型的行李,并替换为单个行李的平均最终预测。例如,抽取一个模型和 20 个袋子的概率为 25%,任何特定模型不在任何一个袋子中的概率仅为 0.3%左右。

三。构建神经网络集成:MNIST 实例

配备了上一节中的技术,在这一节中,我们将把它们应用到一个实际的任务中,在 MNIST 数据集上构建和优化一个神经网络集成。使用随附的笔记本可以完全复制本节的结果,因此我将本节中的代码片段限制为最少,主要集中在集成上,而不是模型定义和培训上。

我们从一个简单的 MLP 开始,它有 3 个隐藏层,每层 100 个单位,每个都有 ReLU 激活。自然,MNIST 数据集的输入是一个 28x28 像素的图像,展平为一个 784 维的矢量,输出图层有 10 个对应于位数的单元。因此,PyTorch 中实现的MNISTMLP类指定的架构如下所示:

*MNISTMLP((layers): Sequential((0): Linear(in_features=784, out_features=100, bias=True)(1): ReLU()(2): Linear(in_features=100, out_features=100, bias=True)(3): ReLU()(4): Linear(in_features=100, out_features=100, bias=True)(5): ReLU()(6): Linear(in_features=100, out_features=10, bias=True))
)*

然后,我们使用独立的权重初始化(即,除了起始权重之外,一切都是相同的)对模型的 10 个实例进行 3 个时期的训练,每个时期的批量大小为 32,学习率为 0.001,保留 60,000 幅图像的训练集的 25%用于验证,最后的 10,000 幅图像构成测试集。目标是最小化交叉熵(等价地,负对数似然)。请注意,只有 3 个时期的训练以及每个模型相当小的容量可能会导致数据拟合不足,从而允许以更生动的方式展示集合的好处。

训练完成后,我们恢复 10 个模型中每个模型的最佳检查点(通过验证损失)。下图左侧面板显示了从M0M9的每个型号的验证(蓝色)和测试(橙色)损失。类似地,右边的面板显示了验证和测试的准确性。

图 3:模型的验证和测试集性能

正如所料,所有模型的表现都很差,其中最好的一个模型M7,在测试集上仅达到 96.8%的准确率。

为了构建一个最优集合,让我们首先调用上一节定义的ensemble_selector函数,然后在当前问题的上下文中检查各个参数:

y_hats_val是一个字典,其中模型名称作为关键字,验证集的预测类概率作为项目:

*>>> y_hats_val["M0"].round(3)
array([[0\.   , 0\.   , 0\.   , ..., 0.998, 0\.   , 0.001],[0\.   , 0.003, 0.995, ..., 0\.   , 0.001, 0\.   ],[0\.   , 0\.   , 0\.   , ..., 0.004, 0\.   , 0.975],...,[0.999, 0\.   , 0\.   , ..., 0\.   , 0\.   , 0\.   ],[0\.   , 0\.   , 1\.   , ..., 0\.   , 0\.   , 0\.   ],[0\.   , 0\.   , 0\.   , ..., 0\.   , 0.007, 0\.   ]])>>> y_hats_val["M7"].round(3)
array([[0\.   , 0\.   , 0\.   , ..., 1\.   , 0\.   , 0\.   ],[0\.   , 0\.   , 1\.   , ..., 0\.   , 0\.   , 0\.   ],[0\.   , 0\.   , 0\.   , ..., 0.003, 0\.   , 0.981],...,[0.997, 0\.   , 0.002, ..., 0\.   , 0\.   , 0\.   ],[0\.   , 0\.   , 1\.   , ..., 0\.   , 0\.   , 0\.   ],[0\.   , 0\.   , 0\.   , ..., 0\.   , 0.002, 0\.   ]])*

y_true_one_hot_val是对应的真独热编码标签的 numpy 数组:

*>>> y_true_one_hot_val
array([[0., 0., 0., ..., 1., 0., 0.],[0., 0., 1., ..., 0., 0., 0.],[0., 0., 0., ..., 0., 0., 1.],...,[1., 0., 0., ..., 0., 0., 0.],[0., 0., 1., ..., 0., 0., 0.],[0., 0., 0., ..., 0., 0., 0.]])*

loss_function是一个可调用的映射数组,将预测和标签映射到一个标量:

*>>> cross_entropy(y_hats_val["M7"].round(3), y_true_one_hot_val)
0.010982255936197028*

最后,init_size=1表示我们从单一模型的系综开始;replacement=True表示模型加入集成后不从模型池中移除,允许算法多次加入同一个模型,从而调整集成成分的权重;max_iter=10设置算法的步数。

现在让我们检查输出。model_weights是一个 pandas 数据帧,包含每个优化步骤的每个模型的总体权重。在每个优化步骤中删除所有权重为零的模型会产生:

*>>> model_weights.loc[:, (model_weights != 0).any()] M1        M4        M5        M7        M9
0   0.000000  0.000000  0.000000  1.000000  0.000000
1   0.000000  0.000000  0.500000  0.500000  0.000000
2   0.000000  0.000000  0.333333  0.333333  0.333333
3   0.000000  0.250000  0.250000  0.250000  0.250000
4   0.200000  0.200000  0.200000  0.200000  0.200000
5   0.166667  0.166667  0.166667  0.333333  0.166667
6   0.142857  0.142857  0.285714  0.285714  0.142857
7   0.125000  0.250000  0.250000  0.250000  0.125000
8   0.111111  0.222222  0.222222  0.222222  0.222222
9   0.100000  0.200000  0.200000  0.300000  0.200000
10  0.181818  0.181818  0.181818  0.272727  0.181818*

下图绘制了作为优化步骤函数的总体成分权重,其中较暗的色调对应于模型在所有优化步骤中获得的较高平均权重。在步骤 0,集合以单个最强的模型M7初始化,然后逐步添加更多的模型,给每个模型分配相等的权重:在步骤 1,有两个模型M7M5,每个模型具有 50%的权重,在步骤 2,集合包括模型M7M5M9,每个模型具有三分之一的权重。在步骤 4 之后,没有新的模型可以进一步改进集合预测,并且算法开始调整其成分的权重。

图 4:总体权重

另一个输出——ensemble_loss——包含每个优化步骤的系综损失。与上一节中的图 2相似,下图的左面绘制了优化过程中验证集的总体损失(蓝色实线)。黑色虚线和红色虚线分别表示最佳单一模型和简单集合(对所有模型分配相同的权重)所达到的验证损失。集合损失下降得非常快,在几次迭代后超过了其简单对应物的性能,并且在算法进入权重调整模式后稳定下来,这在模型池相当小的情况下并不令人惊讶。右边的面板报告了测试集的结果:在每次迭代中,我使用当前的集合权重来产生预测并测量测试集的损失。该集成在测试样本上概括得很好,有效地重复了在验证集上观察到的模式。

图 5:MNIST 的系综损失

卡鲁阿纳等人(2004) 算法非常灵活,我们可以很容易地调整ensemble_selector,例如,通过改变loss_function参数直接优化精度:

其中accuracy定义如下:

下图重复了前面的分析,但这次是为了验证和测试准确性。结论是相似的,尽管在两个样本中集合的精度路径更不稳定。

图 6:集合精度,MNIST

四。更多关于神经网络中的集合:损失表面几何的重要性

为什么随机初始化有效?

简而言之,这完全是关于损失面的。当前的深度学习研究强调优化前景的重要性。例如,批量标准化( Ioffe 和 Szegedy (2015) )传统上被认为是通过减少内部协变量移位*——训练期间网络激活分布的变化,来加速和规范训练。然而, Santurkar 等人(2018) 提供了一个令人信服的论点,即该技术的成功源于另一个属性:批处理规范化使优化前景明显更加平滑,从而稳定梯度并加快训练。类似地, Keskar 等人(2016) 认为,与地形较平坦区域的最小值相比,损失面上的尖锐最小值具有较差的泛化属性。*

在训练期间,神经网络可以被视为将参数映射到给定训练数据的损失值的函数。下图描绘了(非常)简化的网络损耗图:解的空间和损耗分别沿水平轴和垂直轴。 x 轴上的每个点代表产生相应损耗的网络的所有权重和偏差(蓝色实线)。红点表示我们可能使用基于梯度的优化结束的局部最小值(最左边的两个点是全局最小值)。

在集合的上下文中,这意味着我们想要探索许多局部最小值。在上一节中,我们已经看到,同一神经网络结构的不同初始化的组合产生了更好的泛化能力。事实上,在他们最近的论文中,Fort 等人(2019) 证明了随机初始化最终会达到遥远的最优,因此能够探索完全不同的模型,具有相似的准确性和相对不相关的预测,从而形成强集成组件。这一发现补充了神经网络的标准直觉,即神经网络是最终的低偏差高方差算法,能够以几乎外科手术的精度拟合任何东西,尽管受到噪声敏感性的困扰,因此受益于方差减少带来的集成。

但是如果训练同一个模型的几个副本是不可行的,该怎么办呢?

黄等(2018) 提出在单次训练运行期间使用循环学习率和退火构建集成,并在每个循环结束时存储模型检查点或快照。直观上,增加学习速率可以允许模型避开上图中的任何局部最小值,并以不同的局部最小值落在邻近区域,最终收敛到该区域,随后学习速率降低。下图说明了快照集成技术。左图显示了模型在具有恒定学习速率的标准训练体系期间穿过损失景观的路径,并且最终停止点用蓝色旗帜标记。右图描绘了循环学习率时间表和用红旗标记的定期快照。

快照集,来源:黄等(2017)

但是,请记住,在前面的两个图中,整个参数空间分别被压缩到 x 轴和 xy 平面上的一个点中,这意味着图形上的一对相邻点在实际参数空间中可能相距很远,因此, 梯度下降算法遍历多个最小值而不被卡住的能力取决于损失表面上的对应谷是否被非常高损失的区域分开,使得学习中没有有意义的增加会导致到新谷的过渡。

幸运的是, Garipov 等人(2018) 证明了在优化景观上存在连接局部最小值的低损耗路径,并提出了利用这些连接的快速几何组合(FGE)过程。伊兹迈洛夫等人(2018) 提出了 FGE 的进一步细化——随机加权平均(SWA)。

Max Pechyonkin 为提供了快照集FGE 和西南威尔士州。

动词 (verb 的缩写)结论

让我们回顾一下这篇文章的要点:

  • 强集成由既准确又多样的模型组成
  • 一些无模型集成方法,如卡鲁阿纳等人(2004) 算法,允许不适合作为 ML 模型优化目标的实际目标函数
  • 集成不仅通过抑制神经网络对噪声的固有敏感性,而且通过组合质量上不同且不相关的解来提高神经网络的性能

总而言之,集成学习技术应该是每个机器学习实践者的武器库中最重要的工具之一。不要把所有的鸡蛋放在一个篮子里这句古老的格言到底走了多远,确实令人着迷。

感谢您的阅读。我们热切期待您的评论和反馈。还有,在LinkedIn上联系我。

进一步阅读

* [## 随机加权平均——一种获得深度学习最新结果的新方法

更新:你现在可以在我的个人博客上欣赏这篇文章,这里的数学排版要好得多(Medium 不支持…

towardsdatascience.com](/stochastic-weight-averaging-a-new-way-to-get-state-of-the-art-results-in-deep-learning-c639ccf36a) [## 集成学习指南

没有人能知道所有的事情,但是在帮助下,我们可以克服每一个障碍。这正是合奏背后的理念…

towardsdatascience.com](/a-guide-to-ensemble-learning-d3686c9bed9a)

参考

Caruana,r .,Niculescu-Mizil,a .,Crew,g .,& Ksikes,A. (2004 年 7 月)。模型库中的集成选择。第二十一届机器学习国际会议论文集(第 18 页)。

Fort,s .,Hu,h .,& Lakshminarayanan,B. (2019)。损失景观透视。 arXiv 预印本arXiv:1912.02757

茨韦塔纳·加里波夫、伊兹迈洛夫、波多普里欣、维特罗夫和威尔逊(2018 年)。损耗面、模式连接性和 dnn 的快速组装。在神经信息处理系统的进展(第 8789-8798 页)。在T3 可用 arXiv:1802.10026

黄,李,杨,普莱斯,刘,郑,霍普克罗夫特,J. E .,,温伯格,K. Q. (2017)。快照合集:火车 1,免费获得 m。 arXiv 预印本arXiv:1704.00109

Ioffe,s .,& Szegedy,C. (2015 年)。批量标准化:通过减少内部协变量转移加速深度网络训练。 arXiv 预印本arXiv:1502.03167

伊兹迈洛夫、波多普里欣、加里波夫、维特罗夫和威尔逊(2018 年)。平均权重导致更宽的最优值和更好的泛化能力。 arXiv 预印本arXiv:1803.05407

Keskar,N. S .,Mudigere,d .,Nocedal,j .,Smelyanskiy,m .,,Tang,P. T. P. (2016)。深度学习的大批量训练:泛化差距和尖锐极小值。 arXiv 预印本arXiv:1609.04836

桑图尔卡尔、齐普拉斯、易勒雅斯和马德瑞(2018 年)。批量规范化对优化有什么帮助?。在神经信息处理系统的进展(第 2483-2493 页)。可在arXiv:1805.11604获得。*

组装 HuggingFaceTransformer 模型

原文:https://towardsdatascience.com/ensembling-huggingfacetransformer-models-f21c260dbb09?source=collection_archive---------23-----------------------

照片由 @jeetdhanoa 在 unsplash 上拍摄

使用一个简单的线性层将两个或更多的变形金刚组合在一起。

最近,当我使用 BERT 进行问答研究时,有人建议我集成两个 BERT 模型。我选择了一条显而易见的路线——谷歌搜索。但令我惊讶的是,什么都没有出现。有很多关于变形金刚的文章,但是没有关于如何组合变形金刚模型的。本文讨论的正是这个问题——如何集成两个 PyTorch 拥抱脸变压器模型。

什么是模型组装?
在很多情况下,一个单一的模型可能不会给出最好的结果。然而,如果我们将“几个弱”分类器组合在一起,并以一种有意义的方式组合这些弱分类器的结果,我们可能会得到更好的结果。

例如,假设我们正在使用 BERT 进行问答—如果我们将两个句子send _ 1send _ 2传递给 BERT 模型,该模型应该预测这两个句子是否形成问答对,即send _ 2answerssend _ 1

通常的技术是以两种方式向模型提供问答对—
【CLS】+sent _ 1+【SEP】+sent _ 2+【SEP】
【CLS】+sent _ 2+【SEP】+sent _ 1+【SEP】
一个单一模型
,并训练该模型。

如果我们宁愿集合 2 个模型——以如下方式训练 2 个模型,而不是这样做:
**模型 1** 获得输入,
*【CLS】+sent _ 1+[SEP]+sent _ 2+[SEP]*,
**模型 2** 获得输入,
*【CLS】+sent _ 2+[SEP]+sent _ 1+[SEP]*

然后,使用一个简单的前馈网络,我们可以结合模型的结果(不要在如何做上敲你的头,只是假设它现在可以做。我将展示如何做到这一点,这是本文的关键)。

  1. 为什么组装更好? *嗯,这不!至少不总是这样。*在某些情况下,集成的结果可能优于单个大模型。这是可行的,因为手头的任务可能太复杂,一个单一的模型无法理解。
    这与一个有 100 个神经元的深度 CNN 比一个有 1 层和 100 个神经元的 CNN 工作得更好的原因是一样的——每一层都学到不同的东西,使整个模型变得更好。这和一个人比一头狮子弱是一个道理,但是作为一个社会,我们是地球上最优越的物种。这和 5 个我比 1 个梅西强是一个道理(至少我昨天是这么想的😆).这和悟吉塔比布罗利强是一个道理。但是最主要的原因是他们没有过度适应。

单一模型方法

让我们回到问答的例子。让我们考虑 3 个句子,

句子 _1 =谁杀了弗里扎?
句子 _2 =弗里扎被小悟空杀死
句子 _3 =弗里扎消灭了玛雅人却放过了玛雅人。

我们馈入模型,
输入:【CLS】+句子 _ 1+【SEP】+句子 _ 2+【SEP】
输出 : 1
输入:【CLS】+句子 _ 1+【SEP】+句子 _ 3+【SEP】
输出 : 0

如前所述,如果我们有一个单一的模型,那么训练模型的正常方式是,
【CLS】+问题+【SEP】+答案+【SEP】
【CLS】+答案+【SEP】+问题+【SEP】

具体到我们的情况,
【CLS】+句子 _ 1+【SEP】+句子 _ 2+【SEP】
【CLS】+句子 _ 2+【SEP】+句子 _ 1+【SEP】

变形金刚合奏

在这种方法中,我们有两种模式

  1. 模型 1
    **输入**:*【CLS】+提问+【SEP】+回答+【SEP】*
  2. 模型 2
    输入:【CLS】+回答+【九月】+提问+【九月】

现在的问题变成了如何将两个模型的输出合并成一个,即系综?

嗯,空谈是廉价的,所以让我们编码。由于代码并不便宜,我将尝试解释它的大部分。

作者提供的图片(使用 Paint S 创建)

代码

首先,我创建了一个名为BertEnsembleForNextSentencePrediction 的新模型。

self.bert_model_1 = BertModel(config)        
self.bert_model_2 = BertModel(config)         
self.cls = nn.Linear(self.n_models * self.config.hidden_size, 2)

BertEnsembleForNextSentencePrediction以 2 个 BertModel 作为输入(在 init 中可以看到)并增加一个 nn。线性在它们上面。 *nn。线性,*如前面提到的这里的 *,*应用线性变换就像:

在输入端。我来解释一下为什么 nn。使用了线性(尽管任何看过一点变形金刚代码的人应该能够立即看到许多 nn。线性如*bertonlynshead,BertForSequenceClassification,*等。).

input_ids_1 = input_ids[0]        
attention_mask_1 = attention_mask[0]        
token_type_ids_1 = token_type_ids[0]input_ids_2 = input_ids[1]        
attention_mask_2 = attention_mask[1]        
token_type_ids_2 = token_type_ids[1]

接下来是主前进功能。转发函数的参数 input_ids、attention_mask、token_type_ids 为元组,第 0 个索引用于第一个模型,第 1 个索引用于第二个模型。因此,第一个模型将 T28 输入 _ 标识[0],注意 _ 屏蔽[0],令牌 _ 类型 _ 标识[0]作为输入。(我不会详细说明这些术语的含义,因为它们是标准的 BERT 术语)。以上 6 行正是这么做的。

outputs.append(self.bert_model_1(input_ids_1, attention_mask=attention_mask_1, token_type_ids=token_type_ids_1))outputs.append(self.bert_model_2(input_ids_2, attention_mask=attention_mask_2, token_type_ids=token_type_ids_2))

然后,我们将上面的左侧变量,即输入 _ 标识 _1、注意 _ 屏蔽 _1、令牌 _ 类型 _ 标识 _1、输入 _ 标识 _2、注意 _ 屏蔽 _2、令牌 _ 类型 _ 标识 _2 传递给 BERT 模型— BertModel

如此处所示, BertModel 返回 last_hidden_statepooler_output 作为前两个输出。我们对这里的池 _ 输出感兴趣。这里所说的和中的 pooler_output

L 由线性层和双曲正切激活函数进一步处理的序列的第一个标记(分类标记)的 ast 层隐藏状态。在预训练期间,根据下一句预测(分类)目标来训练线性层权重。

对于给定的输入, pooler_output 的大小为( batch_size,hidden_size )。默认情况下 hidden_size = 768。

last_hidden_states = torch.cat([output[1] for output in outputs], dim=1) 
logits = self.cls(last_hidden_states)

现在进入使用 nn.Linear. 的主要组合部分,如何组合模型 1 和模型 2 的输出?很简单——每个模型中的*【CLS】*令牌都是大小( *batch_size * 768* )。所以基本上对于每个问答配对,我们都有一个大小为 768 的向量。因此,对于每个给定的问答配对,将有分别从 2 个模型中的每一个生成的每个大小为 768 的 2 个向量。比如
*【cls 1】+谁杀了 Freeza?+ [SEP] +弗里扎被悟空+[SEP]*
*【cls 2】+弗里扎被悟空+ [SEP] +谁杀了弗里扎?+ [SEP]*

nn。线性接受输出数组元素的串联,即展平输出数组并执行线性运算*。因此,线性层将大小为(2 * 768)的向量作为输入,并输出 0 或 1 的概率,即逻辑值*(逻辑值并不完全是概率,但如果我们对逻辑值应用 softmax,我们会得到概率,所以它足够接近)。

因此,线性层将大小为(2 * 768)的向量作为输入,并输出 0 或 1。

这是一个完整的工作示例。
https://colab . research . Google . com/drive/1 syrrbaudjhikjhnxxazt 5 w _ uka 0 bmk 9 x?usp =分享

请注意,代码中使用的数据集非常小,代码的编写方式对于这样小的数据集来说是一个巨大的破坏。但是我编写代码的方式使得任何更大的数据集都可以使用。此外,PyTorch 的通用模式已用于编写代码。我发现保存这个模板并根据用例稍微调整一下代码很有用。

就是这样!

参考和链接:

  1. 为什么集合更好:https://www . quora . com/How-do-ensemble-methods-work-and-why-be-superior-to-individual-models
  2. PyTorch nn。线性:https://py torch . org/docs/master/generated/torch . nn . linear . html

企业人工智能/机器学习:经验教训

原文:https://towardsdatascience.com/enterprise-ai-machine-learning-lessons-learned-4f39ae026c5d?source=collection_archive---------31-----------------------

从帮助企业加速 AI/ML 之旅中获得的浅见。

乔丹马德里在 Unsplash 上的照片

从我的人工智能/机器学习之旅中学到的经验教训

我最近有幸参加了几位人工智能/机器学习专家的小组讨论。有许多很棒的问题,但大多数都与如何在大型组织中最有效地建立人工智能/机器学习(AI/ML)有关。

这让我有机会反思我自己帮助大型企业加速人工智能/机器学习之旅的经历,更具体地说,评估什么可行,或许同样重要的是,什么不可行。我把这些浓缩成了几个简单的“经验教训”,希望在你的组织的 AI/ML 之旅中对你有用。

第一课:不要让完美成为足够好的敌人

根据我的经验,你的模型永远不会完美。所以,不要试图让他们完美。现在,不要误解我的意思——模型的准确性(或任何适用于您的情况的指标)很重要,但获得绝对最佳的模型可能只在 Kaggle 比赛中有效。

相反,您的重点应该是使您的模型足够好,以满足业务需求。事实是,几乎所有的企业都认为获得一个完美的模型远远次于将一个“足够好”的模型投入生产,在生产中它可以交付价值。所以,我的建议很简单:弄清楚什么对你的组织来说是“足够好的”,并专注于将模型投入生产。

第二课:建立模型只是工作的 10%

这是一个基本但在很大程度上未被认识到的事实:今天,企业在数据科学方面的绝大多数时间并没有真正花在数据科学上。相反,大部分时间——根据我的经验,超过 90%的时间——都花在了做其他的事情,包括:获取数据、工程数据和特性集、解决安全问题、设置基础设施(云或数据中心)或工作站、打包生产模型,以及创建 DEVOPS 脚本以将完成的模型迁移到产品中……这还不是一个完整的列表!

不幸的是,在大多数不成熟的组织中(也就是说大多数组织认识到相对的“新”或 AI/ML ),这种额外的非数据科学工作实际上在每个项目中都经历过。

这是件大事吗?绝对是。假设你的团队的预算是 100 万美元(一个很好的整数,这使得计算非常简单),这意味着有人——在许多情况下是你的高价数据科学家——在与你雇用他们的目的没有直接关系的任务上花费了 90%,或 90 万美元。那是一大笔钱!这不仅听起来很痛苦,而且经历起来更痛苦!

那么,如何才能避免这种痛苦呢?嗯,这引出了我的下一课…

约书亚·索蒂诺在 Unsplash 上拍摄的照片

第三课:秘方:人工智能/人工智能平台

正如我之前强调的,太多的项目在与 AI/ML 没有直接关系的任务上花费了太多的时间。

解决方案:一个“ AI/ML 平台”。

首先,让我们不要混淆我所说的“人工智能/人工智能平台”的含义。不仅仅是云供应商提供的环境和工具包。不要误解我,我喜欢 AWS、Azure 和 Google 提供的工具——没有它们你真的无法有效地做 AI/ML。然而,云供应商工具没有解决一些重要的考虑因素。换句话说,云供应商工具是必要的,但还不够。

那么,什么是“人工智能/人工智能平台”呢?简单地说,AI/ML 平台的目的是加速将 AI/ML 模型投入生产。它是在 AI/ML 环境和工具之上实现的“粘合剂”——脚本、安全策略、可操作性问题和自我供应基础设施。

让我们来解决关键因素:

  • 安全性:解决访问敏感数据所需的安全性问题需要大量的尽职调查。在大多数组织中,这种情况的根本原因是,对于每个项目,几乎相同的安全问题被讨论、辩论,并且可能被实现。另一方面,AI/ML 平台基于你的组织的安全状态实现了一个安全模型,只需做一次,就可以用于所有的项目。大多数组织,尤其是那些受到高度监管的组织,需要远远超出云供应商通常提供的“虚拟公共云”能力的安全控制。应分层的附加功能的最小集合包括基于身份的访问控制(这将解决几乎所有黑客问题)、配置漂移管理(例如,捕捉 Capital One 发生的错误防火墙规则更改)和单向数据流(例如,数据可以存储在平台上,但只能使用“类似 Citrix”的门户来可视化,以使用工具—数据永远不能离开平台)
  • 可操作性:所有大型企业对生产代码都有严格的要求。今天,AI/ML 模型被认为是可部署的代码,并且受到与其他产品代码相同的需求的约束。不幸的是,在大多数不成熟的组织中,这些需求是在每个项目的基础上实现的。相比之下,AI/ML 平台提供了生产级工具,这些工具通过常见的日志记录、警报、异常处理、统计和指标捕获以及与企业操作控制台的集成来增强准系统模型,从而确保 AI/ML 模型也解决了基本的企业问题
  • 自我调配的基础架构:我看到当组织迁移到云时会发生一件不幸的事情:他们带着旧的数据中心包袱——大部分是乏味的手动流程——在云上实施同样低效的流程。回答错误!云供应商花费了数年时间来优化工具和流程,以允许数据科学家自行调配工具和环境,而无需额外的监督或流程。AI/ML 平台整合了必要的开发操作程序和安全功能,允许数据科学家和数据工程师快速获取数据并提供培训环境。

照片由保罗·格伦在 Unsplash 上拍摄

第四课:“人工智能/人工智能市场”是现代人工智能/人工智能的基本要求

简单来说, AI/ML Marketplace 是与 AI/ML 模型相关的所有工件的目录,支持模型的可再现性、可追溯性、可解释性和可验证性:

  • 为了解决再现性问题,AI/ML 市场提供了对模型源代码的引用——包括当前和以前的版本——并且用于训练它的数据被保存在清单中
  • 为了解决可追溯性问题,AI/ML Marketplace 维护对原始源系统数据和数据工程脚本的引用,这些数据工程脚本用于转换和丰富,从而提供对交付生命周期中所有数据更改的可见性。
  • 为了解决可验证性问题,对训练输出、日志和相关工件(包括与模型的偏差和“道德”检查相关的输出日志)的引用由 AI/ML 市场管理,从而捕获模型功效的证据。
  • 为了自动化信息捕获过程,AI/ML 市场将与 AI/OPS (DEVOPS for AI/ML)过程集成,以自动捕获上述工件。有趣的是,主要的云提供商、传统的 DEVOPS 供应商以及较新的 AI/OPS 初创公司正在提供工具和功能,这些工具和功能可以缝合在一起,以捕获许多所需的指标和元数据。

简而言之,AI/ML Marketplace 是一个目录和存储库,它通过充分解决可再现性、可追溯性、可验证性和可解释性来促进现代 AI/ML 开发、管理和治理。

第 5 课:让您的云原生 AI/ML 程序现在就开始吧!

在大多数企业中,我看到计算平台和数据/存储容量远远超出了内部数据中心的能力。GPU 农场不在议程上。三倍和四倍的储存农场正在进行中。但事实是,即使是大型组织也无法跟上。

大型国际咨询公司埃森哲(Accenture)表示,有几个问题:首先,“到目前为止,还没有一个经过验证的扩展蓝图,组织可能会陷入一些常见的陷阱。”第二,“人工智能的陌生景观也意味着企业可能会倾向于回到他们历史悠久的行为,重新发明轮子,从头开始建设。”最后,“有许多经过验证的低成本人工智能选项,可以购买现成的并立即开始使用。”

那么,当大型云供应商有其他更强大、更具成本效益、可扩展和最新的选项可用时,为什么还要与之对抗呢?我的简单建议是:撇开批评者,让你的云原生 AI/ML 项目开始吧!

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

第六课:民主化人工智能/人工智能

大多数组织,尤其是那些将 AI/ML 迁移到云的组织,都有一个千载难逢的机会来构建他们的组织以取得成功。我的愿景是“使人工智能/人工智能民主化”,这也是我在大型企业中看到的。我的意思是,任何团队(假设他们有技能)都应该能够在任何时间,以任何速度,使用他们需要的任何工具和库来构建 AI/ML 模型。

但是,如何扩展和管理这种类型的组织结构呢?简而言之,基本要求是在 AI/ML 平台和 AI/ML 市场中实现规模和管理所需的必要护栏。考虑到这一点,下面是 AI/ML 组织内的一组实用的组:

  • AI/ML 平台团队:该团队对建立、操作、支持和发展所有组件(包括基础设施、云环境、安全性、工具和 DEVOPS)负有完全的端到端责任。该团队不仅负责平台,还培训、支持和指导数据科学团队
  • 分布式数据科学团队:由于许多跨领域的问题都被纳入了 AI/ML 平台,这使得数据科学家可以从事数据科学工作,同时也使整个组织的数据科学家能够快速、无缝地入职。这一指导原则允许任何拥有数据科学技能的团队按照其团队需求和业务需求所决定的速度进行数据科学研究。没有集中的群体。没有象牙塔。

乔希·卡拉布雷斯在 Unsplash 上的照片

正在总结…

我在这篇文章中的目标是提供一些简单的经验教训,帮助您加速您的企业的 AI/ML 之旅,并避免我所经历的一些减速带和坑洞。希望我已经达到了这个目标。

但有一点我可以肯定的是,事情进展得很快。技术和方法很可能会发展,很有可能,我应该考虑在一年后写一个新版本。或者,一年后,你将能够写一些从你的组织 AI/ML 旅程中学到的经验教训!

带有 Google Dialogflow & Flutter 的企业级聊天机器人(第一部分)

原文:https://towardsdatascience.com/enterprise-grade-multi-platform-virtual-assistant-with-google-dialogflow-flutter-part-i-da6f05edfed?source=collection_archive---------50-----------------------

参见第二部分此处。

1)人工智能和虚拟助手革命

图片经 Canva 授权给 Catherine Torchy ( 我的妻子)

消费级虚拟助手(如谷歌助手、Alexa、Siri)已经深刻改变了人们在个人生活中与技术打交道的方式。但我是相信有一天,虚拟助理和人工智能将被大规模用于改变员工在工作中与系统互动的方式,并自动化他们的日常任务的人之一。

目前,挑战主要是与现有业务解决方案(如 ERP)的集成、与用户系统上不存在的外部数据连接的能力,以及在各种平台(包括 web 和移动设备)上获得一致的用户体验的能力。

这一系列 3 篇技术文章的想法是在对市场上提出的几个聊天机器人和对话引擎进行评估后产生的。它们中的大多数都提供了与语言(NodeJS、Java、Python..)、消息系统(Facebook Messenger、Slack、丨t丨e丨l丨e丨g丨r丨a丨m丨s丨、Hangouts……)但要想知道如何将它们集成到一个商业解决方案中并不容易。此外,它们的渲染通常非常有限,无法为业务需求提供可接受的用户体验。

我读过很多提供部分解决方案的文章。然后开始了三重挑战:

  • 如何将对话引擎与外部 API 轻松集成
  • 如何通过使用自定义消息和一组丰富的组件来解决默认呈现引擎的布局限制(例如,Google Assistant 的限制),以获得更好的用户体验
  • 如何用相同的代码管理多平台/移动前端

所以,我选择了最强大的 NLP 对话引擎之一,Google Dialogflow,但它也可能是微软 Bot 或亚马逊 Lex。然后我结合一个 Google Flutter 应用,突破 Google Assistant、Slack 等的布局限制。

如果你已经读过我的文章,那么答案是……“是的”,这篇文章是为那些打算继续实践的人提供的又一个简单的循序渐进的教程。它将集中于超越虚拟助理的基本设计所需的知识。还需要一些关于 Dialogflow、NodeJS、API/web services 和 Flutter 的知识。像往常一样,这些文章(Dialogflow & Flutter 项目)的全部源代码将会发布在我的 git lab(【https://gitlab.com/osadey】)上

有大量的教程描述了如何在 Dialogflow 中配置意图。这一篇将关注与业务 API 使用相关的 dialog flow Intents & Fulfillment NodeJS 代码。下一步将在 Google Assistant 集成中使用相同的意图,然后在定制的 Flutter 移动应用程序中使用相同的意图。

2)欧拉·爱马仕金融开放数据 API 介绍

作者图片

本节的目的是让您在询问财务数据时配置理解用户请求的对话。每个请求都可以用不同的方式表达,并且有参数。如果缺少,将要求用户完成它们。一旦满足要求,就会调用 Opendata API,并将财务数据返回给用户。

我们的财务虚拟助理将从 Euler Hermes Economics Open Data 获得一些财务数据,并将它们显示给用户(参见https://opendata.eulerhermes.com/pages/home-page/),但它也可能是令人印象深刻的数据库。经济学数据提供商。(【https://db.nomics.world/】T2

你在这两个网站上看到的大部分东西都可以通过 RESTful APIs 查询。

现在我们来探究一下欧拉·赫尔墨斯的一些国际贸易数据。在我们的例子中,我们将连接到一个数据集,该数据集提供了进口国和出口国之间的贸易流和支付默认值(参见:https://open data . Euler Hermes . com/explore/dataset/exports-vs-claims/information/)

数据集由 8 个数据元素组成:

  • 年/月
  • 进口商/购买国
  • 出口商/销售国
  • 进口商公司贸易部门 NACE 代码
  • 给定月份向 Euler Hermes 申报的贸易流量总额(€)
  • 给定月份向 Euler Hermes 申报的拖欠付款总额(€)
  • 交通灯是给定购买人群的风险指示器
  • 给定人群的损失率代理

3)配置您的对话流代理和意图

作者图片

3.1。我们的使用案例

代理是关于相同主题的一组会话的配置,共享相同的目标。我们的代理将显示一个贸易流和付款违约的清单,从一个出口国到一个进口国之间的两个日期。然后,用户将能够通过几个标准过滤列表。(例如“建筑”)

用户可以使用不同的短语来提问,应该会给出相同的结果。

以下部分假设您已经对 Dialogflow 有了基本的了解。

3.2。创建代理

让我们创建一个基本的对话流代理

一旦登录到谷歌对话流控制台(https://dialogflow.cloud.google.com/)

  1. 创建一个新代理,并将其命名为 BusinessAPIBot
  2. 在“常规”选项卡上添加描述

您可以保留其他选项卡上的其他默认值。

3.2。创建意图

意图代表用户和虚拟助理之间的典型对话。

让我们创建我们的第一个意图。

  1. 点击左侧菜单中的“+”按钮添加意向
  2. 将其命名为'生态出口与索赔'
  3. 输入您的第一个训练短语如下“由过滤器过滤的 2018-05-01 至 2018-05-02 前 10 大出口国家的对外贸易额是多少?”

正如您所注意到的,训练短语有一些以不同颜色突出显示的参数。可以选择训练短语的每个元素,然后作为参数添加。参数可以有多种类型:例如整数、日期或用户定义。

参数需要与实体相关联。

如果 Dialogflow 无法自动创建它们,您将首先需要使用左侧的“实体”菜单手动创建它们,然后将它们添加到实体列表中。

现在,我们将向我们的训练短语添加参数:

  1. 选择“从”日期(此处为“2018–05–01”)
  2. 将出现一个弹出窗口。选择一个“@sys.date”实体
  3. 将参数命名为“日期-期间-自”
  4. 对“至”日期“2018–05–01”执行相同的操作,并将其命名为“日期-期间-至”
  5. 对“10”值执行相同的操作,并将其分配给“@sys.number-integer”实体。把它命名为‘topnn’
  6. 最后,对“filter”值执行相同的操作,并将其分配给一个“@sys.any”实体。将其命名为“过滤器”

你的第一个训练短语应该是这样的:

作者图片

现在,让我们添加另外两个训练短语,以便当对话引擎提出不同的请求时,能够更好地理解它的请求。

输入您的第二个训练短语如下:“在 2018-05-01 至 2018-05-02 期间,由过滤器过滤的法国和德国之间的前 10 大对外贸易额是多少”

你可以注意到这个有点不同。“topnn”参数出现在开头,有两个新的附加参数:出口国和进口国。

  1. 选择“FR”国家值,并将其分配给新的“@geo-country-code-export”实体。将参数命名为“地理国家代码导出”
  2. 选择“DE”国家值,并将其分配给新的“@geo-country-code-import”实体。将参数命名为“地理国家代码导入”
  3. 对第一个训练短语进行相同的操作,以确定其他参数

你的第二个训练短语应该是这样的:

作者图片

最后,将第三个训练短语添加到列表中,如下所示:“我希望获得由过滤器过滤的 2018–05–01 至 2018–05–02 期间 FR 和 en 之间的贸易流量和付款默认值。”

如您所见,它与之前的训练短语具有相同的参数。我们只是用“获取贸易流量”取代了“对外贸易额”。

然后,对第二个训练短语进行同样的操作,以识别所有参数。

NLP 对话流引擎允许你只用一小组训练短语来训练 AI。理想情况下,你最好增加一些训练短语,让你的代理表现更好。

在下面的屏幕上,您可以看到您定义的所有参数:

作者图片

参数可以是可选的,也可以是强制的。如果它们丢失,Dialogflow 将要求用户自动完成它们。

  1. 在顶部字段中,请键入以下内容:“input.getTradeFlows”
  2. 选中“地理位置-国家代码-出口”、“日期-期间-自”和“日期-期间-至”的“必填”框
  3. 添加提示文本“从哪个时期开始?”“日期-期间-自”参数
  4. 添加提示文本“到哪个期间?”到“日期-周期-到”参数
  5. 在“地理国家代码-出口”参数中添加提示文本“出口国家代码是什么(de,FR,SP…)”

您还可以发送回一个响应,其中包含您的输入参数的格式化值。

为此,在响应部分添加以下文本:

好的,这是我为你选择的数据: —出口国$地理-国家代码-出口 —进口国$地理-国家代码-进口 —期间从$日期-期间-自.原始到$日期-期间-至.原始

单击“保存”按钮保存您的意向并创建您的代理。

现在,我们能够对代理进行非常基本的测试。

3.3。我方代理人的基本测试

作者图片

在右边的屏幕框中,您可以测试您的代理,并查看训练短语是否被识别,参数是否被正确识别和解析。

如果缺少强制参数,Dialogflow 应该询问其他问题。

对于我们最基本的测试,让我们键入以下内容:

  • “获得从法国到德国的贸易流量”
  • 代理应询问缺失的强制日期“从哪个时间段开始?”
  • 输入“20200101”
  • 代理应询问缺失的强制日期“截止到哪个时间段?”
  • 输入“20201231”

那么代理的回答应该如下:

"好的,这是我为你选择的数据:

-出口国 FR-进口国 DE

-从 20200101 到 20201231 期间

作者图片

下一篇文章(第二部分)将向您展示如何:

  • 使用 NodeJS 将新代理与 Euler Hermes API 集成
  • 将数据呈现给用户
  • 使用代理跟进意图过滤数据
  • 配置闲聊

NER 任务的实体级评估

原文:https://towardsdatascience.com/entity-level-evaluation-for-ner-task-c21fb3a8edf?source=collection_archive---------7-----------------------

如何计算 NER 任务的混淆矩阵(TP,TN,FP,FN)

亚历山大·安德鲁斯在 Unsplash 上拍摄的照片

当我们评估 NER(命名实体识别)任务时,有两种方法,令牌级方法和实体级方法。比如我们下面预测的这句话:“外交部发言人沈国放告诉路透社”。如果用令牌级评价,令牌“申”是对的,令牌“国芳”是错的。但是如果我们使用实体级评估,“沈国放”是一个完整的命名实体,因此对“沈”和“国放”的预测必须是“PER”和“PER”。否则,这是错误的预测实体,甚至令牌“申”被预测为“每”。

NER 预测的例子

实体级与令牌级

那么我们应该用哪种方法呢?

答案是实体级评测。正如任务名“命名实体”所表明的,我们真正关心的是我们的模型如何预测整个实体,而不是单独的标记。

我一般用sk learn-CRF suite来实现 CRF 模型,这个库很棒。但是它的一个缺点是使用的评估方法是令牌级评估。

precision    recall  f1-score   supportB-LOC      0.775     0.757     0.766      1084I-LOC      0.601     0.631     0.616       325B-MISC      0.698     0.499     0.582       339I-MISC      0.644     0.567     0.603       557B-ORG      0.795     0.801     0.798      1400I-ORG      0.831     0.773     0.801      1104B-PER      0.812     0.876     0.843       735I-PER      0.873     0.931     0.901       634avg / total      0.779     0.764     0.770      6178

我们希望对这些进行更改,以产生如下所示的实体级评估:

precision    recall  f1-score   supportLOC      0.775     0.757     0.766      1084MISC      0.698     0.499     0.582       339ORG      0.795     0.801     0.798      1400PER      0.812     0.876     0.843       735avg/total      0.779     0.764     0.770      6178

不使用官方的评测方法,我推荐使用这个工具, seqeval 。该库可以在实体级别运行评估。

>>> from seqeval.metrics import accuracy_score
>>> from seqeval.metrics import classification_report
>>> from seqeval.metrics import f1_score
>>> 
>>> y_true = [['O', 'O', 'O', 'B-MISC', 'I-MISC', 'I-MISC', 'O'], ['B-PER', 'I-PER', 'O']]
>>> y_pred = [['O', 'O', 'B-MISC', 'I-MISC', 'I-MISC', 'I-MISC', 'O'], ['B-PER', 'I-PER', 'O']]
>>>
>>> f1_score(y_true, y_pred)
0.50
>>> accuracy_score(y_true, y_pred)
0.80
>>> classification_report(y_true, y_pred)precision    recall  f1-score   supportMISC       0.00      0.00      0.00         1PER       1.00      1.00      1.00         1micro avg       0.50      0.50      0.50         2macro avg       0.50      0.50      0.50         2

混淆矩阵计算

好了,我们已经有了一个很棒的解决度量计算的工具,为什么还要关心幕后的计算呢?

给一个人一条鱼,你可以喂他一天;教一个人钓鱼,你就喂了他一辈子。

混淆矩阵是机器学习领域的一个重要话题,但对于 NER 任务,关于如何计算混淆矩阵的帖子很少,所以我希望这篇帖子可以清除不确定性。

首先,我们写出混淆矩阵表:

然后计算精度、召回率和 F1:

我们用上面的例子来填充混淆矩阵表:

“外交部”算 FN,“路透社”算 TP。这两个很好区分。棘手的问题是预测何时会产生边界误差。如果模型产生了边界误差,我们算作两个误差。比如我们把实体“沈国放”算作两个错误,一个是 FN,一个是 FP。

我们忽略实体类型,并像这样填充混淆矩阵表:

然后计算矩阵:

代码实现

我们忽略实体类型,只计算上面例子中一个句子的混淆矩阵。为了更好的推广,代码实现必须考虑实体类型并计算所有句子的混淆矩阵。

查看我在 上的其他帖子 一个分类查看
GitHub:
荆棘徐 领英: 徐亮 博客:

参考

  • https://www.youtube.com/watch?v=0uI_5FYd5k0

熵和信息增益

原文:https://towardsdatascience.com/entropy-and-information-gain-b738ca8abd2a?source=collection_archive---------19-----------------------

另一个用来做决策树分割的工具。

杰克·布吕克在 Unsplash 上的照片

信息增益是另一种方法,也可用于优化选择分割数据集的要素。在我们继续学习信息增益之前,我们必须首先讨论熵,它是由香农(1948) 提出的。

定义:【E】熵提供了对信源产生的数据进行无损压缩编码的最短可能平均长度的绝对限制,如果信源的熵小于通信信道的信道容量,则信源产生的数据可以可靠地传递给接收方。

这个定义非常难以理解,而且它不一定与我们讨论的决策树相关。 Shannon(1948) 将熵的概念用于通信理论,以确定如何将编码(比特)信息从发送者发送到接收者,而不丢失信息并使用最少的比特数。

请看看揭秘熵和香农熵背后的直觉,以获得一个容易理解的解释。

比特是什么?当使用 1 位数据的 if 语句时,我们通常有 TRUE 或 FALSE。一个位取单个二进制值 0(假)或 1(真)。请参见下表,了解存储容量如何随着每一位的增加而增加。

x: 位数, n: 组数值

马库斯·斯皮斯克在 Unsplash 拍摄的照片

无损的

这个概念仅仅意味着在从发送者到接收者的传输中没有信息丢失。

公式

上面的公式给出了最小平均编码大小,它使用每种消息类型的最小编码大小。

高熵:更多的不确定性

低熵:更多的可预测性

例子

我们将计算每次分裂的熵。例如,我们将对“情感”列进行两次拆分。一个写着“不恶心”,另一个写着“恶心”。

一旦我们完成了每次分割,我们就可以计算目标变量“stayhome”的熵。

信息增益

既然我们已经讨论了熵,我们可以继续讨论信息增益。这是分割要素上的数据后熵减少的概念。信息增益越大,熵或不确定性下降越大。

  • T:拆分前的目标人群 T =∑{所有拆分},拆分前的观察总数。
  • 熵(T):测量分裂前的无序度,或不确定性水平
  • s:第次分割的观察次数
  • 熵(s):测量分裂 s上目标变量的无序度

给定上面的例子,T=8,s{1}=5,s{2}=3,熵(s { 1 })= 0.9709…熵(s{2}) = 0.91829…$。很难判断,但是即使当我们使用特征“情感”分割原始数据集时,我们也没有获得太多信息来获得同质的桶(纯粹的集合来识别“N”或“Y”)。

正如你所看到的,我们在分裂的“情感”上获得的信息很少。我们可以通过分开温度来更好地休息吗?

这比我们获得的信息量有了很大的提高。让我们以表格的形式来看一下。正如你所看到的,我们已经从原始数据集中的平均分割,变成了在温度条件下的 25% / 75%分割。因此,我们获得了更多信息,因为我们能够将每个预测值放入具有相似值的桶中。

亚历克斯在 Unsplash 上的照片

附录

有时候,一个存储桶能够完全隔离其中一个决策参数,并正确地识别它。出现这种情况时,其他参数出现的概率为 0。我们不能取 log(0 ),因为它创建了一个— inf

此外,上面的代码是硬编码的,只能处理两种可能的结果。

决策树中的熵和信息增益

原文:https://towardsdatascience.com/entropy-and-information-gain-in-decision-trees-c7db67a3a293?source=collection_archive---------1-----------------------

由 Unsplash 上的absolute vision拍摄

简单了解一些关键的信息论概念,以及在构建决策树算法时如何使用它们。

决策树算法应该使用什么标准来拆分变量/列?

在构建决策树算法之前,第一步是回答这个问题。我们来看看回答这个问题的方法之一。为此我们将需要理解一个使用来自信息论的几个关键概念。

让我们通过以下步骤来检查这种方法:

  1. 简单看一下什么是决策树
  2. 定义并检查熵的公式。
  3. 讨论信息论中的一个是什么。
  4. 定义信息增益和用熵来计算。
  5. 用上面的概念写一些基本的 Python 函数

决策树

在数据科学中,决策树算法是一种用于分类或回归问题的监督学习算法。我们的最终目标是使用历史数据来预测结果。与线性回归不同,决策树可以提取数据中变量之间的非线性交互。

让我们看一个非常简单的决策树。下面是一个工作流程,可以用来决定是否吃花生酱饼干。

关于是否吃饼干的决策树示例

在这个例子中,决策树可以发现这样一个事实,即只有在满足特定标准的情况下,您才应该吃 cookie。这是决策树的最终目标。我们希望继续做决策(拆分),直到满足某些标准。一旦相遇,我们可以用它来分类或作出预测。这个例子非常简单,只使用了两个变量(过敏,破坏晚餐)。但是,如果您有一个包含数千个变量/列的数据集,您如何决定拆分哪些变量/列是最有效的呢?解决这个问题的一个流行的方法,特别是如果使用一个 ID3 算法,是使用信息增益

任务

假设我们有一些数据,我们想用它来做一个在线测验,预测一些关于应试者的事情。在查看了数据中的关系后,我们决定使用决策树算法。如果你从未被吸进过网上的小测验,你可以在这里 看到上百个例子 。这个小测验的目标是猜测参加测验的人是否来自美国中西部的一个州。测验中的问题将围绕他们是否喜欢某种食物展开。下面是一个小的虚构数据集,有 15 个条目。每个条目都有一系列问题的答案。大多数问题都是关于他们是否喜欢某种食物,参与者回答(1)表示喜欢,回答(0)表示暂时喜欢。最后一栏(“中西部?”)是我们的**目标列,**意味着一旦构建了决策树,这就是我们试图猜测的分类。

为了让我们开始,我们将使用一个叫做熵的信息论度量标准*。*在数据科学中,熵被用来衡量一列的“混合”程度。具体来说,熵是用来衡量无序的。让我们从寻找我们的目标列“中西部”的熵开始。

我们的目标专栏,“中西部?”

有十个人住在中西部,五个人不住在中西部。如果有人要问你这个群体有多混杂,你可以说是混杂的,大多数人(2/3)来自中西部。熵给了我们一个量化答案“有点混合”的方法。列中的(1)和(0)越混合,熵越高。如果“中西部?”有等量的(1)和(0)我们的熵将是 1。如果“中西部?”仅由(1)组成,熵将是 0。

我们可以用下面的公式来计算熵:

熵的公式

让我们遍历公式的每一步,计算“中西部”的熵专栏。

  1. 我们需要遍历单个列中的每个唯一值,并将它赋给 I。列,可以是(0)或(1)。
  2. 然后,我们计算该值出现在数据中的概率。对于(1)的情况,概率为 10/15 。对于(0)的情况,概率为 5/15
  3. 我们取每种情况的概率,乘以概率的对数底 2。2 是最常见的基数,因为熵是用比特来度量的(后面会详细介绍)。为什么使用 2 的完整解释超出了本文的范围,但是 stack exchange 上的一个用户提供了一个很好的 解释 对于(1)的情况,我们得到 **10/15log2(10/15)* 。对于(0)的情况,我们得到 5/15*log2(5/15)。
  4. 接下来,我们从上述每个案例中取出我们的乘积,并将其相加。对于本例,10/15 * log2(10/15)+5/15 * log2(5/15)。
  5. 最后,我们对上面的总和,——(10/15 * log2(10/15)+5/15 * log2(5/15))。

一旦我们把所有的步骤放在一起,我们得到如下:

我们的最终熵是. 918278。那么,这到底意味着什么呢?

信息论和一点信息

展望未来,理解双边投资条约的概念是很重要的。在信息论中,一个比特被认为是一个二进制数,0 代表无信息,1 代表全比特信息。我们可以用二进制数来表示一位信息,因为它的值要么是(1),要么是(0)。假设明天下雨(1)或不下雨(0)的概率相等。如果我告诉你明天会下雨,我已经给了你一点信息。

我们也可以认为熵是信息。假设我们有一个加载的六面骰子,它总是落在(3)上。每次我们掷骰子,我们预先知道结果将是(3)。我们滚动骰子并没有获得新的信息,所以熵是 0。另一方面,如果骰子离我们很远,我们掷出 a (3),则有 1/6 的机会掷出(3)。现在我们获得了信息。因此,滚动骰子给我们一点信息——数字落在哪一边。

为了更深入地了解一点概念信息,你可以在这里阅读更多

我们得到的信息少于一个“比特”——只有 0 . 918278——因为在“中西部”有更多的“1”这意味着,如果我们预测一个新的值,我们可以猜测答案是(1),并且正确的概率大于错误的概率(因为答案是 1 的概率为 2/3)。由于这种先验知识,当我们观察一个新值时,我们获得的信息少于一个完整的“比特”。

用熵来做决策

我们的目标是在构建决策树时找到要拆分的最佳变量/列。最终,我们希望继续分割变量/列,直到我们的混合目标列不再是混合的。

例如,让我们看看“中西部”的熵在“土豆沙拉”上分割数据集后的列专栏。

分吃“土豆沙拉?”圆柱

上面,我们的数据集分为两部分。左边,喜欢土豆沙拉的各位。右边是所有不喜欢的人。我们把重心放在了左边,现在有七个人来自中西部,两个人不是。通过使用左边拆分中西部列的熵公式,新的熵是. 764204。这太棒了!我们的目标是降低熵,我们从. 918278 到. 764204。但是,我们不能就此止步,如果我们看看右边的列,我们的熵增加了,因为有等量的(1)和(0),我们需要的是一种方法,看看熵在分裂的两边是如何变化的。信息增益的公式会做到这一点。它给了我们一个数字来量化我们每次分割数据时获得了多少信息。

信息增益

前面我们已经确定,我们希望拆分可以降低目标列的熵。当我们分吃“土豆沙拉”时我们在“中西部”看到了熵在左边倒下了。现在我们需要理解,当我们看分裂的两边时,总熵降低了。让我们来看看信息增益。

信息增益将使用以下公式:

让我们来分析一下这是怎么回事。

我们会回到我们的“土豆沙拉?”举例。上述公式中的变量将表示如下:

  • T = Target,我们的“中西部?”圆柱
  • A =我们正在测试的变量(列)“土豆 _ 沙拉?”
  • v =中的每个值,“土豆 _ 沙拉”中的每个值圆柱
  1. 首先,我们将计算分裂前(T)的原始熵, .918278
  2. 然后,对于变量(A)中的每个唯一值(v ),我们计算(A)取值(v)的行数,并将其除以总行数。“土豆沙拉?”列我们得到唯一值为(1)的 9/15 和唯一值为(0)的 6/15
  3. *接下来,我们将结果乘以(A)为(v)的行的熵。为左分裂(分裂 1 为“土豆 _ 沙拉?”)我们得到 **9/15 * .764204** 。对于右侧拆分(拆分为 0 表示“土豆 _ 沙拉?”)**我们得到 6/15 * 1。***
  4. 我们将所有这些子集乘积相加,9/14 * . 764204+6/15 = . 8585224

5.然后我们从总熵中减去得到信息增益,. 918278-. 8585224 = . 059754

我们的信息增益是. 059754。这告诉我们什么?

这是另一种解释。我们正在寻找每个集合拆分后的熵,用每个拆分中的项目数对其进行加权,然后从当前熵中减去。如果结果是肯定的,我们已经通过拆分降低了熵。结果越高,我们降低的熵越多。

我们最终得到. 059754,这意味着我们通过在“土豆沙拉”上分割我们的数据集获得了. 059754 位信息。变量/列。我们的信息增益很低,但仍然是正的,这是因为我们降低了分裂左侧的熵。

现在我们需要对我们使用的每一列重复这个过程。让我们写一些 Python 代码,而不是手动完成。

用 Python 把它包起来

现在我们已经了解了信息增益,我们需要一种方法来重复这个过程,以找到具有最大信息增益的变量/列。为此,我们可以用 Python 创建几个简单的函数。

导入数据

让我们使用 Python pandas 库将上面的表转换成数据帧。我们将导入熊猫,并使用 read_csv() 函数制作一个名为“midwest”的数据帧。

*import pandas as pd
midwest = pd.read_csv('midwes.csv')*

熵的 Python 函数

对于这个函数,我们需要 NumPy 库来使用 bincount()函数,需要数学模块来使用 log()函数。

*import numpy
import math*

接下来,我们将用一个参数定义我们的函数。给出的参数将是我们试图计算熵的序列、列表或 NumPy 数组。

*def calc_entropy(column):*

我们需要找到列中每个案例的百分比。为此,我们可以使用 numpy.bincount() 函数。返回值是一个 NumPy 数组,它存储作为参数传递的列中每个唯一值的计数。

*counts = numpy.bincount(column)*

我们将通过将“计数”数组除以列的长度来存储每个唯一值的概率。

*probabilities  = counts / len(column)*

然后,我们可以初始化一个名为“熵”的变量,并将其设置为 0。

*entropy = 0*

接下来,我们可以使用“for 循环”遍历概率数组中的每个概率,并使用 math.log()函数将其乘以概率的以 2 为底的对数。然后,将每个案例添加到我们存储的熵变量中。 确保检查你的概率大于 0,否则 log(0)将返回未定义的*

*for prob in probabilities:if prob > 0:endtropy += prob * math.log(prob,2)*

最后,我们将返回我们的负熵变量。

*return -entropy*

现在一起:

太好了!现在我们可以建立一个函数来计算信息增益。

用于信息获取的 Python 函数

我们需要定义一个函数,它有三个参数,一个用于整个数据集,一个用于我们要拆分的列的名称,一个用于我们的目标列的名称。

*def calc_information_gain(data, split_name, target_name):*

接下来,我们可以使用前面的熵函数来计算目标列的原始熵。

*orginal_entropy = calc_entropy(data[target_name])*

现在我们需要拆分我们的列。

*对于这个例子,我们将只使用具有两个唯一的变量/列。如果您想在变量/列(如“年龄”)上进行拆分,有几种方法可以做到这一点。一种方法是分割每个唯一值。另一种方法是简化信息增益的计算,并通过不对每个唯一值进行拆分来使拆分更简单。取而代之的是被分割的变量/列的中间值。变量值低于中值的任何行都将转到左分支,其余的行将转到右分支。为了计算信息增益,我们只需要计算两个子集的熵。我们不会遍历这个方法,但是一旦对中间值进行了分割,剩下的步骤将与下面概述的相同。

因为我们正在处理的列只有两个唯一值,所以我们将进行左拆分和右拆分。

我们将从熊猫开始。Series.unique() 给出一个列中唯一值的数组

*values = data[split_name].unique()*

接下来,我们将使用“值”创建左右拆分。

*left_split = data[data[split_name] == values[0]]
right_split = data[data[split_name] == values[1]]*

现在我们可以初始化一个变量,从原始熵中减去。

*to_subtract = 0*

然后,我们将遍历通过拆分创建的每个子集,计算子集的概率,然后将概率和子集目标列的熵的乘积相加。

*for subset in [left_split, right_split]:prob = (subset.shape[0] / data.shape[0])to_subtract += prob * calc_entropy(subset[target_name])*

最后,我们可以返回从原始熵中减去 to _ subract 的差值。

*return original_entropy - to_subtract*

整个函数如下。

获得最高信息增益的 Python 函数

我们的最终函数将返回具有最高信息增益的变量/列名。

如前所述,在本例中,我们只使用具有两个唯一值的列。我们将把这些列名存储在一个列表中,以便在函数中使用。言归正传 w 我们将对这个示例进行硬编码,但是在大型数据集中,最好是编写代码来基于我们用来选择列的标准动态构建这个列表。

*columns = ['apple_pie?', 'potato_salad?', 'sushi?']*

让我们将最后一步封装在一个函数中,这样我们就可以在需要时重用它。它将有一个参数,即我们希望找到最高信息增益的列的列表。

*def highest_info_gain(columns):*

我们将初始化一个空字典来存储我们的信息收获。

*information_gains = {}*

然后我们可以遍历列列表,并将结果存储在 information_gains 字典中。

*for col in columns:information_gain = calc_information_gain(midwest, col, 'midwest?)information_gains[col] = information_gain*

最后,我们可以返回字典中最高值的键。

*return max(information_gains, key=information_gains.get)*

现在一起:

一旦我们执行了最后一个函数

*print(highest_info_gain(midwest, columns, 'midwest?'))
//sushi*

我们看到信息增益最高的变量/列是“寿司?”。

我们可以想象寿司的分割如下:

分割寿司列上的数据集

我们的左翼有六分之二来自中西部。来自中西部的九个人中有八个是右派。这是一个有效的分裂,降低了我们双方的熵。如果我们要继续,我们将使用递归来继续分裂每个分裂,目标是以零熵结束每个分支。

结论

决策树可以是一种有用的机器学习算法,用于提取数据中变量之间的非线性交互。在这个例子中,我们看了决策树分类算法的开始阶段。然后我们看了三个信息论概念,熵、比特和信息增益。通过使用这些概念,我们能够在 Python 中构建一些函数来决定哪些变量/列是最有效的分割。牢牢掌握了这些概念,我们就可以继续构建决策树了。

熵在股票市场中的应用

原文:https://towardsdatascience.com/entropy-application-in-the-stock-market-b211914ed1f3?source=collection_archive---------11-----------------------

用结构熵随时间监控相关网络

戴夫·塞贝莱在 Unsplash 上拍摄的照片

来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

熵有很多定义和公式。总的来说正确的是,熵被用来衡量关于实验可能结果的信息惊喜不确定性。特别是,香农熵是统计学和机器学习中使用最频繁的熵。因此,这是我们关注的焦点。

惊喜不确定性是金融市场中的日常概念。因此,使用熵作为工具来探索市场听起来是一个非常辛辣的想法。我们所期望的是揭示新指标和资产价格随时间的波动性之间的显著模式。

考虑到我们的目标,我认为有必要介绍一下 本工作 中提供的标准方法和注意事项。作者引入了结构熵的概念,并用它来监控一个基于相关性的网络,并将其应用于金融市场。

数据

在我们的分析中,我们使用从 Kaggle 上收集的数据集中的每日收盘价。它存储了 32 只股票,来自不同的市场部门,从 2000 年到 2018 年连续交易。对于数据集中的每只股票,我们得到其每日对数收益的时间序列。对数差额价格(对数收益)可以产生适合我们范围的稳定和正态分布的信号。

我们开始用传统的测量方法研究数据中湍流的存在。波动性是对给定市场指数回报离差的统计度量。该指标指的是与市场变化规模相关的不确定性或风险水平。高波动水平对应于股票价格的大范围波动。这意味着一项资产的价格可以在短期内发生巨大的双向变化。较低的波动性意味着资产价值不会大幅波动,更趋于稳定。

使用滑动窗口方法生成的个体(蓝色)和中位数聚集(红色)统计数据

在我们的例子中,高波动期出现在新千年的最初几年(网络泡沫)、2008 年(最近的金融危机)以及随后的一些时期。

结构熵

一个特别有趣的想法是将金融市场表示为基于相关性的网络。在金融市场的情况下,网络节点是金融资产,网络边缘是它们之间的相互作用,其中这种相互作用通常通过随时间推移的价格相关性的大小来衡量。将金融市场表示为网络对于识别动荡或结构性断裂是有价值的。

基于这种社区结构,结构熵是一种量化给定网络中结构多样性水平的度量。在这个框架中,结构熵是指网络中节点的异质性水平,其前提是共享功能或属性的节点比其他节点更具连通性。

为了计算给定时间范围内的结构熵,我们需要遵循定义的工作流程:

  • 测量序列的皮尔逊相关性,得到一个 NxN 对称矩阵。
  • 创建一个邻接矩阵作为网络边的表示。标准方法是使用阈值来确定相关矩阵的哪些值将被转换成网络中的边。
  • 在邻接矩阵上,我们应用社区检测算法(在我们的例子中是连通分量)。
  • 聚类过程的结果标签(整数向量)用于计算经典的香农熵。更具体地说,我们计算聚类计数频率的熵。结果值被定义为网络的结构熵

将这些步骤放在一个滑动窗口过程中,我们可以监视我们感兴趣的系统中随时间的动态变化。结果是一个新的单一时间序列的结构熵值。

来源

一般来说,结构熵可以解释为众所周知的香农指数的调整版本。它们都是多样性的指标,但是结构熵可以从具有空间和时间依赖性的复杂结构中提取值。

在我们处理的系列上采用整个程序,产生了下面描述的结果。

用不同的相邻矩阵阈值产生的结构熵

结构熵的最小可达值是 0,并且这是当网络中的所有节点被分配到相同社区(即,单个巨大社区)时获得的。当每个节点构成一个团体时,达到最大值。最大值取决于网络中节点的数量(观察到的级数)。

正如我们所看到的,在我们的例子中,结构熵可以捕捉到新千年早期(网络泡沫)、2008 年(最近的金融危机)以及随后一些时期的动荡。如果我们把相关矩阵想成一个图,并用散点来绘制,就可以直观地解释在引擎盖下发生了什么。点代表每只股票(我们的网络节点),颜色是股票所属的聚类(由社区检测算法创建),边是关系的强度,如果两只股票的相关性超过一定量,则绘制边。

随机相关矩阵取自高、中和低结构熵的时期

在结构熵最大的时期,股票倾向于保持独立,形成独特的集群。在中熵时期,我们可以看到一些股票属于同一个聚类,通过一些强相关性联系在一起。在低结构熵时期,大部分股票属于同一个群落,由大量的相关关系联系在一起。

摘要

在这篇文章中,我们介绍了一种观察价格序列几何结构变化的替代方法。资产的价格随着可用信息的变化而变化。信息的一个简单变化会立即反映在价格中。金融市场的相互关联性需要采取一种措施来捕捉空间和时间维度。从这个意义上来说,结构熵帮助我们在这种涉及不确定性的情况下进行陈述和计算。

查看我的 GITHUB 回购

保持联系: Linkedin

参考文献

结构熵:随时间监控基于相关性的网络及其在金融市场的应用。埃雷兹·什穆埃利·阿萨夫·阿尔莫格

熵、交叉熵和 KL 散度

原文:https://towardsdatascience.com/entropy-cross-entropy-and-kl-divergence-17138ffab87b?source=collection_archive---------11-----------------------

让我们通俗地理解熵

首先,感谢您对本文的兴趣。有很多媒介可能会把你重定向到这里——社交媒体网站、媒介内部推荐、直接链接、电子邮件、谷歌搜索结果等。不过,既然你被重定向了,我今天有个有趣的话题——熵。

黄贯中在 Unsplash 上拍照

如果你是一个随机读者…

如果文章推荐没有个性化,你对我来说就是一个随机读者。让我们假设有 50% 的几率一个随机读者会阅读整篇文章。所以,读完整篇文章的概率和不读整篇文章的概率是一样的。你可能会读,也可能不会。假设有一个完美的预测引擎,如果某个用户愿意读这篇文章,它会给我一些信息。所以,引擎说你是否会读这篇文章。它为我提供任何格式的信息——文本、音频、图像等。然而,无论是哪种格式,引擎,我都会得到一位信息— 读/不读

每当一个新的随机用户访问我的文章时,我都会得到一点信息。那么对于一个新的随机用户,我平均能得到多少位信息呢?这些事件发生的可能性是相等的,所以一个新随机用户得到的平均信息量是 1 。这就是 。这个随机事件的熵是 1

所以,事件的熵是事件的随机性或者事件结果的不确定性。如果我们知道事件的结果,它等于我们得到的平均信息量。

那么,如何计算熵呢?

熵是我们需要获得的平均信息量,以了解事件。为了知道事件的结果,我们需要将不确定性减少到 0(即确定性减少到 1)。如果某个事件 A 的概率是 p ,知道它的结果意味着用 1/p 的因子来减少不确定性。所以,我们需要 lg(1/p) 位数来了解事件,等于 -lg(p) 。这是事件 A 发生时的熵值。同样,事件 A 没有发生时的熵值为 -lg(1-p) 。如果概率分布为伯努利p ,则事件的平均熵为 -p * lg(p) -(1-p) * lg(1-p)。

如果你总是看我的整篇文章呢?

我想在这里记住我的女朋友。不管我写什么话题,她都喜欢看我的文章(咳咳……)。所以,这个事件在她的情况下是确定的。在这种情况下,结果没有不确定性,没有随机性,对吗?所以,猜测它的熵为 0 是有道理的,不是吗?让我们看看在这种情况下是否得到零熵。如果事件是确定的,概率是 1。这意味着我们不需要任何位数来了解事件。所以,我们需要得到的位数是 0。因此,熵为零。

现在,我的追随者怎么办?

我的关注者关注了我,因为他们对我通常写的主题感兴趣。所以,对于他们来说,阅读整篇文章的概率大于随机用户。我们假设概率是 0.75 。当我们思考这种情况下的事件时,不确定性减少了,对吗?让我们找出答案。

当关注者实际阅读整篇文章时,概率增加一个因子 4/3 [≈ lg(1.33) 位数】但当关注者没有阅读整篇文章时,概率增加一个更大的因子,即 4 ( 2 位数)。我的关注者阅读文章的次数占 75%,所以这个概率分布的平均位数是:
0.75 * LG(1.33)+0.25 * LG(4)0.81

0.81 当然小于 1 。所以,我的追随者的熵更低。

如果有两个以上的可能事件呢?

熵公式可以推广到 n 个可能事件。公式是:
熵=-(I = 1…n)p _ I * LG(p _ I)

熵与事件数量

让我们来比较熵和这里的一些事件。直觉上,事件数量的增加会反过来增加熵,因为这增加了不确定性。让我们取 n 个等概率事件,计算概率分布的熵。

概率分布的熵变成:
-n (1/n) LG(1/n)= LG(n)

对数函数(任意底)是严格单调递增的,因此随着事件数量的增加,熵也增加。是的,我们的直觉是正确的。:)

交叉熵

了解事件所需的平均位数不同于用于传输信息的平均位数。交叉熵是用于传输信息的平均位数。交叉熵总是大于或等于熵。对于随机用户预测机,用于传送信息的比特数是 1 ,所以交叉熵是 1。

让我们来看一个有四种可能结果的概率分布——概率分别为 *0.5,0.25,0.125,*和 0.125 。如果我们用两个比特来传递这个信息,交叉熵就变成了 2 。等等,这种情况下的熵是多少?
熵= 0.5 * LG(2)+0.25 * LG(4)+0.125 * LG(8)+0.125 * LG(8)
= 0.5+0.5+0.375+0.375 = 1.75

在这种情况下,熵是 1.75,但我们使用 2 位来传输该信息,因此交叉熵= 2。这种交叉熵与熵之差叫做 KL 散度

当使用两位来传输所有情况的信息时,我们假设所有事件的概率为 1/(2 ) 。所以,实际 vs 预测(或假设)的概率分布是:
0.5 vs 0.25,0.25 vs 0.25,0.125 vs 0.25,0.125 vs 0.25。

如果我们使用 1 位来传输第一事件信息(1),2 位来传输第二事件信息(10),3 位来传输第三事件信息(101),还有 3 位来传输第四事件信息(100),我们将使用最佳消息长度。因此,当我们对不同的事件采用不同的消息长度时,我们隐含地预测了概率分布。我们得到的交叉熵值越大,预测的概率分布就越偏离实际的概率分布。因此,交叉熵也可以用于计算实际概率分布和预测概率分布之间的距离。这就是交叉熵损失在机器学习中处理分类时的使用方式。

猫和狗的分类

最流行的分类问题之一,猫狗分类,要求我们预测概率分布,给定一个图像。实际的概率分布是标签,逻辑函数给我们预测的概率分布。交叉熵以如下方式用作该任务的损失函数:

假设我们有一幅狗的图像,概率分布中的第一个元素是狗的。

实际概率分布为:【1,0】

现在,假设逻辑函数输出概率分布:【0.7,0.3】

0.7 概率这里的意思是——*LG(0.7)*当图像是狗的时候用来传递信息的比特数。

因此,交叉熵将是:-1 * LG(0.7)-0 * LG(0.3)= 0.51

由于最小化某个函数与最小化它的正标量倍数是相同的,所以我们可以使用自然对数(或任何底对数)来代替 2-底对数来定义机器学习中的损失。

KL 散度何时为 0?

KL 散度是相对熵或交叉熵和熵之间的差或实际概率分布和预测概率分布之间的某个距离。当预测概率分布与实际概率分布相同时,等于 0。

希望你现在对熵,交叉熵和 KL 散度有一个好的概念。请在评论区告诉我你的想法。

此外,我们鼓励读者浏览 YouTube 上奥雷里奥·杰龙的精彩视频。

熵,交叉熵,KL-散度解释!

原文:https://towardsdatascience.com/entropy-cross-entropy-and-kl-divergence-explained-b09cdae917a?source=collection_archive---------6-----------------------

让我们试着去理解最广泛使用的损失函数——交叉熵。

交叉熵(也称为 log-loss)是分类问题最常用的损失函数之一。但是我们大多数人经常在没有真正了解熵的核心概念的情况下就开始解决问题,这是由于当今庞大的库和框架的存在以及它们的易用性。因此,在这篇文章中,让我们来看看背后的基本直觉,将它与交叉熵KL-散度联系起来。我们还将检查一个使用损失函数作为交叉熵的分类问题的例子。

熵是什么?

为了开始了解熵到底指的是什么,让我们深入一些信息论的基础知识。在这个数字时代,信息由比特(0 和 1)组成。交流的时候,有些比特是有用的,有些是多余的,有些是错误的,等等。当我们传递信息时,我们希望向接收者传递尽可能多的有用信息。

在克劳德·香农的论文《通信的数学理论》(1948 年)中,他指出,传输 1 比特的信息意味着将接收者的不确定性减少 2 倍。

让我们看看他是什么意思。例如,假设一个地方的天气是随机的,每天有 50%的几率是晴天或雨天。

现在,如果一个气象站告诉你明天会下雨,那么他们已经把你的不确定性降低了 2 倍。起初,有两种同样可能的可能性,但在收到气象站的更新后,我们只有一种可能。这里,气象站给我们发送了一点有用的信息,不管他们如何编码这些信息,这都是真的。

即使发送的消息是‘Rainy’并且每个字符占用一个字节,消息的总大小对应于 40 比特,但是它们仍然只传达了 1 比特的有用信息。

假设天气有 8 种可能的状态,所有的可能性相等。

现在,当气象站给你第二天的天气时,他们就把你的不确定性降低了 8 倍。因为每个事件有 1/8 的机会发生,所以缩减系数是 8。

但是如果可能性不相等呢?

比方说,75%的机会是晴天,25%的机会是雨天。

现在,如果气象站说第二天将会下雨,那么你的不确定性下降了 4 倍,这是 2 比特的信息。不确定性的减少正好是事件概率的倒数。在这种情况下,25%的倒数是 4,对数(4)以 2 为底等于 2。所以,我们得到了两个有用的信息。

如果气象站说第二天将是晴天,那么我们得到 0.41 比特的有用信息。那么,平均来说,我们能从气象站获得多少信息呢?

嗯,明天有 75%的可能性是晴天,这给了你 0.41 比特的信息,而明天有 25%的可能性是雨天,这给了你 2 比特的信息,相当于,

我们平均每天从气象站得到 0.81 比特的信息。所以,我们刚刚计算的叫做熵。这很好地衡量了事件的不确定性。它是由,

希望熵的方程式现在能完全有意义。它测量的是你每天了解天气时获得的平均信息量。一般来说,它给出了我们从一个给定的概率分布 p 中抽取的样本中获得的平均信息量。它告诉我们概率分布是多么不可预测。

如果我们住在每天都阳光明媚的沙漠中心,平均来说,我们每天都不会从气象站获得太多信息。熵将接近于零。另一方面,如果天气变化很大,熵会大得多。

交叉熵

现在,我们来谈谈交叉熵。它只是平均消息长度。考虑同样的 8 种可能的天气状况的例子,所有都是同等可能的,每一种都可以用 3 比特编码。

这里的平均消息长度是 3,这就是交叉熵。

但是现在,假设你住在一个阳光充足的地区,那里的天气概率分布如下:

每天有 35%的机会是晴天,只有 1%的机会是雷雨。所以,我们可以计算这个概率分布的熵,我们得到,

熵=-(0.35 * log(0.35)+0.35 * log(0.35)+0.1 * log(0.1)+0.1 * log(0.1)+0.04 * log(0.04)+0.01 * log(0.01)+0.01 * log(0.01))

熵= 2.23 比特

注意,这里使用的日志是一个二进制日志。

因此,平均来说,气象站发送了 3 个比特,但接收者只能得到 2.23 个有用的比特。我们可以做得更好。

例如,让我们这样修改代码:

我们现在只使用 2 位表示晴天或部分晴天,3 位表示多云和大部分多云,4 位表示小雨和中雨,5 位表示大雨和雷雨。天气是以一种明确的方式编码的,如果你将多条消息链接起来,只有一种方式来解释比特序列。例如,01100 只能表示部分晴,然后是小雨。所以,如果我们计算电台每天发送的平均比特数,那么我们得到,

35% * 2+35% * 2+10% * 3+10% * 3+4% * 4+4% * 4+1% * 5+1% * 5 = 2.42 位

这是我们新的和改进的交叉熵,比我们以前的 3 位更好。现在,假设我们在不同的地方使用相同的代码,那里的天气是相反的,大部分时间是多雨的。

对于这个,如果我们计算交叉熵,

1% * 2+1% * 2+4% * 3+4% * 3+10% * 4+10% * 4+35% * 5+35% * 5 = 4.58 位

我们得到 4.58 比特。它大约是熵的两倍。平均而言,该站发送 4.58 比特,但只有 2.23 比特对接收者有用。每封邮件发送的信息是必要信息的两倍。这是因为我们使用的代码对天气分布做了一些隐含的假设。例如,当我们用一个 2 位的信息来表示晴朗的天气时,我们隐含地预测了晴天的概率为 25%。这是因为负二进制对数(0.25)给出 2。

同样,我们计算所有的天气条件。

分母中 2 的幂对应于用于传输消息的位数。现在,很明显,预测的分布 q 与真实的分布 p 大相径庭。

因此,现在我们可以将交叉熵表示为真实概率分布 p 和预测概率分布 q 的函数,其表示为:

请注意,我们示例中使用的日志是针对基 2 的。

如你所见,它看起来非常类似于熵方程,除了我们在这里使用预测概率的对数。如果我们的预测是完美的,即预测的分布等于真实的分布,那么交叉熵就等于熵。但是,如果分布不同,那么交叉熵将比熵大一些位数。交叉熵超过熵的这个量被称为相对熵或者更普遍地被称为库尔巴克-莱布勒散度(KL 散度)。简言之,

从上面的例子中,我们得到

K-L 散度=交叉熵-熵= 4.58–2.23 = 2.35 比特。

应用

现在,让我们在一个应用中使用交叉熵。假设我们正在训练一个图像分类器来分类不同的看起来很像的动物,比如浣熊、小熊猫、狐狸等等。

因此,对于可能的 7 个类别中的每一个,分类器估计一个概率,这被称为预测分布。由于这是一个监督学习问题,我们知道真实的分布。

在上面的例子中,我拍摄了一只浣熊的图像,因此在真实分布中,它的概率为 100%,其他的概率为 0。我们可以使用这两个分布之间的交叉熵作为成本函数,称为交叉熵损失

这只是我们之前看到的等式,只是它通常使用自然对数,而不是二进制对数。这对于训练来说关系不大,因为二进制 log(x)等于自然 log(x)/log(2),其中分母是常数。

因此,当类别概率被称为一个热点向量(这意味着一个类别有 100%,其余的都是 0)时,那么交叉熵就是真实类别的估计概率的负对数。

在这个例子中,交叉熵是-1*log(0.3) = — log(0.3) = 1.203

现在,你可以看到,当真实类的预测概率接近于 0 时,成本会增长得非常大。但是当预测概率接近 1 时,代价函数接近 0。

由于获得的损失更多(因为预测的分布太低),我们需要用每个类别的更多数量的示例来训练分类器,以减少损失量。

结论

我们举了一个气象站更新第二天天气的例子来理解香农信息论的概念。然后我们把它与熵和交叉熵联系起来。最后,我们通过一个例子来说明交叉熵损失函数的实际应用。我希望这篇文章阐明了熵、交叉熵和 KL 散度背后的基本直觉以及它们之间的关系。

参考文献

  1. "使用 Scikit-Learn 和 TensorFlow 进行机器实践学习."作者奥雷连·盖伦。
  2. https://www.youtube.com/watch?v=ErfnhcEV1O8

强化学习中的熵正则化

原文:https://towardsdatascience.com/entropy-regularization-in-reinforcement-learning-a6fa6d7598df?source=collection_archive---------13-----------------------

在这篇文章中,我假设你已经知道强化学习的基础。如果你是一个初学者,想了解更多关于 RL 的知识,你可以从我在这里写的一个关于 RL 的介绍性故事开始。

在我们的日常语言中,我们通常使用术语“”来指一个系统(例如,宇宙)缺乏秩序或可预测性。)在强化学习(RL)中,该术语以类似的方式使用:在 RL 中,指的是代理动作的可预测性。这与其政策的确定性密切相关,即什么行动将产生最高的长期累积回报:如果确定性高,熵就低,反之亦然。您可以在以下图像中看到这一点:

1:RL 中 Q 值的高低熵分布;a_i 代表行动【自制。]

RL 中熵的正式定义来自信息论,其中熵的计算如等式(1)所示,针对具有概率质量函数 P(X) 的离散随机变量 x 。在 RL 中,公式变成等式(2),因为我们计算策略π(a|s_t)的熵,其中 a 表示每个动作, s 表示状态, t 表示时间步长。注意,为了简单起见,这里我们使用离散动作空间,但是通过用积分代替和,该定义可以容易地应用于连续动作空间。

信息论中计算一个离散随机变量熵的方程(1) [ 摘自维基百科,]和 RL (2)中计算一个策略π(a|s)熵的方程。

图 2:图 1 所示 q 值分布的熵计算。

如果我们计算第一张图中显示的分布的熵,我们可以看到这个公式是如何工作的。在 q 值的第一次分布中,所有的概率都类似地低,而在第二次分布中,a_2 具有高概率,而其他动作具有低概率。这使得第一次分布的熵高于第二次分布的熵,正如你在左边看到的。

我们如何在 RL 中使用熵

当代理正在学习它的策略,并且一个动作为一个状态返回一个正奖励时,可能会发生代理在将来总是使用这个动作,因为它知道它产生了一些正奖励。可能存在另一个产生更高回报的行为,但代理人永远不会尝试,因为它只会利用它已经学到的东西。这意味着代理可能会陷入局部最优,因为没有探索其他行为的行为,永远不会找到全局最优。

这就是熵派上用场的地方:我们可以用熵来鼓励探索,避免陷入局部最优。为了使这一点正式化,我们用政策的熵来增加传统的 RL 目标,如 Ziebart (2010) 。最大熵 RL 目标定义为:

最大熵 RL 目标【来自唐&哈诺贾(2017) 。]

学习这种最大熵模型的思想起源于统计建模,其目标是找到具有最高熵的概率分布,同时仍然满足观察到的统计量[Tang&Haar noja(2017)]。最大熵的原理陈述了具有最大熵的概率分布是在精确陈述的先验数据(在我们的情况下,这些陈述的先验数据是代理的经验)的上下文中最好地代表当前知识状态的概率分布。)

我们现在使用一个熵加成来计算 q 值,这意味着我们现在将熵 H[π(a|s_t)]加到我们的 q 值上。在软 Q 学习中, Haarnoja 等人(2017) 将熵与以下等式合并:

使用熵计算软 q 值[ 哈尔诺贾等人(2017) 。]

为什么我们在 RL 中使用熵

熵已经迅速成为 RL 中流行的正则化机制。事实上,许多当前最先进的 RL 方法,如软演员评论家、A3C 和 PPO,使用它有多种好处:

改进勘探

如前所述,熵鼓励探索,避免代理人陷入局部最优的情况。这对于奖励很少的任务非常重要,因为代理人不会经常收到对其行为的反馈,因此可能会“高估”收到的一些奖励,并总是重复导致该奖励的行为。

微调政策

间接来说,鼓励探索也有助于将学习从已有的政策转移到新的政策。例如,如果我们训练一个机器人在一个区域行走,当我们将这个机器人放入迷宫时,机器人可以重新利用其行走知识来导航迷宫,而不是从零开始,没有任何知识。如果我们使用常规策略——不使用熵——智能体将需要更长的时间来适应新任务,因为它已经了解了以前产生回报的情况,不会像使用最大熵策略的智能体那样探索那么多。这在下面的视频中可以看到:

一个软 Q 学习代理被预先训练行走,然后用于不同的任务。还将代理与随机初始化的代理和 DDPG 代理进行比较【视频来自软学习。]

更加稳健

由于智能体在学习时会探索更多的状态,这要归功于其最大熵策略的鼓励性探索,智能体在开发任务时也将对异常或罕见事件更具鲁棒性。这使得代理更加健壮,因为它将知道如何在不同的情况下更好地处理。

结论

熵在 RL 中的应用带来了许多好处:它改进了代理的探索,它让我们微调以前用于不同任务的策略,并且对于环境的罕见状态也更加健壮。正因为如此,它在软演员评论家、A3C 等 RL 方法的设计中变得非常流行。

它的效果在它所应用的环境中会有很大的不同,因此有必要检查一下熵是否真的对你的 RL 设置有益。如果您想更深入地了解这个主题,我推荐这两个出版物,它们提供了 RL 中熵正则化的详细分析(我在撰写本文时使用了它们和其他材料):

  • t .哈尔诺贾,唐,h .,Abbeel,p .,&莱文,S. (2017)。基于深层能量策略的强化学习。ICML。
  • 艾哈迈德,z .,鲁,N. L .,诺鲁齐,m .,&舒尔曼斯,D. (2018)。理解熵对政策优化的影响。 arXiv 预印本 arXiv:1811.11214

感谢阅读!:)

环境,康达,匹普,啊啊!

原文:https://towardsdatascience.com/environments-conda-pip-aaaaah-d2503877884c?source=collection_archive---------9-----------------------

轻松管理 Python 环境

安装 Python 的方法有很多,不幸的是,这很容易造成混乱。在这篇博文中,我描述了一种非常有效的方法。我知道其他很棒的解决方案,但这是我通常推荐的方式,尤其是对初学者。

👉这是我每天 10 分钟 Python 课程的一部分!

虽然没有太多代码,但这个文档仍然可以在我的 Github 上作为 Jupyter 笔记本使用。你也可以在那里找到我以前的教程。

我们将讨论的主题的简短概述:

  1. Python 很棒,但是…
  2. 有效的方法
  3. 典型的工作流程
  4. 围捕

Python 很棒,但是…

和很多人一样,我是❤️巨蟒!您可以非常迅速地将您的想法转化为可读的代码解决方案。Python 如此成功的一个重要原因是非常活跃的社区,在这个社区里,了不起的人分享他们令人敬畏的解决方案。这就是为什么您不必从头开始编写数据结构,而只需导入 Pandas。将数据写入 hdf5 文件格式?进口 h5py!剧情有些图, xkcd 风格?导入 matplotlib!更好的是,有多种风格因此,如果您喜欢以不同的方式绘制数据,请导入各种其他绘图系统中的一种,例如 Plotly、Bokeh、ggplot 等等。所有这些共享的优点使得 Python 在许多快速发展的领域非常受欢迎,比如机器学习。

不幸的是,大社区的所有努力都是有代价的。您使用的包得到更新、重构、改进,或者只是重写,仅仅是因为作者想出了解决他们问题的更好的方法。这些变更可能是对您编写的代码的破坏变更。流行的软件包,如 Numpy 或 Matplotlib 是非常可靠的,你得到突破性变化的机会很小。然而,使用不那么流行的包,可能会发生破坏性的改变,尤其是在升级包或 Python 本身的时候。

Python 社区解决这个问题的一种方法是使用虚拟环境。这些用它们自己的一组包创建独立的 Python 安装。为每个项目或任务建立一个独特的环境是一个好的实践。这确保了一个项目的依赖关系不会对另一个项目产生破坏性的变化。这个解决方案工作得很好,但是也创建了一些簿记,因为您有不同的 Python 安装,每个安装可能都有自己的包管理器 Pip。所有这些指向 Python 和/或 Pip 的引用会很快造成混乱,我们最终会看到下面著名的图表 van XKCD :

有趣是因为这是真的。

虽然所有 XKCDs 都很有趣,因为它们通常包含一些真理,事实上,如果您没有某种系统来记账,您的 Python 安装可能会变得一团糟。与 Python 中的所有东西一样,有许多不同的方式来组织它,包括一些很棒的工具,如诗歌、Pipenv 等等。在下一节中,我将描述我正在使用的系统。这对我有效,对你也可能有效。这些只是我的两毛钱,你当然要选择最适合自己的。

有效的方法

虽然有很多方法来组织你的 Python 版本、虚拟环境和包,但我还是做了以下这些:

  1. Python 和虚拟环境的 conda
  2. 虚拟环境中的包管理 pip

放弃 gui,使用 shell

可能有非常好和灵活的图形用户界面(GUI ),但是我更喜欢命令行界面(CLI)。他们给我的印象是我更有控制力。我不确定这是不是真的,但至少我在做的每一步都得到了确认。有许多不同的外壳可供选择,这真的没有多大关系。使用您现有的一个通常是最容易的。当你花更多的时间在 CLI 中,你可能有一天会变得更挑剔,选择不同的风格

Windows 默认安装了两种不同的 CLI,命令行提示符(CMD)和 Windows Powershell。两个都可以,但是动力外壳给人的感觉更多的是外壳。如果您从未使用过 CLI,在 Youtube 上观看 power shell 的教程可能会很有用。虽然我已经有一段时间没有使用 windows 了,但是还有其他选择,包括在 Windows 上运行著名的 Linux Bash shell。

MacOs 默认有 Bash (MacOs Catalina 有 Zsh)很棒。您可以使用终端应用程序访问 shell,这是一种与 bash 或 zsh 交互的方式。我个人更喜欢 Zsh 作为外壳,iTerm2 与之交互。两者都可以用自制软件安装。如果你不熟悉 Bash,我强烈建议你去看一个关于它的教程,因为它非常有用。

Linux 用户可能已经熟悉了 shell。安装哪个 shell 和终端应用程序取决于您安装的发行版。一般来说都可以,用你现有的。

虽然您的 shell 看起来很可能会非常不同,但这里是我的 shell 的图像:

Nerd 信息:服务于 Zsh 并显示空格提示的 Alacritty 终端模拟器。

安装 conda 软件包管理器

现在我们已经熟悉了 shell,让我们来看看下一个需求:conda 发行版。Conda 是一个流行的 Python(和许多其他语言)包管理器,它让您可以访问几乎所有的 Python 版本和包。它包括一个管理虚拟环境的简单系统。虽然 conda 可以用于安装包,但我只将其用于虚拟环境和 Python 版本。Conda 有一个叫做依赖检查的特性,它工作得很好,但是有时会有点慢。此外,一些软件包使用 pip 更新,因此我选择只使用 Pip。混合使用这两种工具可能会有效,但是使用一种工具可能会更好。

通常,conda 是使用 Anaconda 安装的,这是一个成熟的发行版,包括许多包、工具和一个 GUI。它安装了许多你可能永远不会用到的软件包,我发现 GUI 使用起来很慢。安装 conda 的另一个选择是使用 Miniconda ,另一个发行版,顾名思义要小得多。Miniconda 是一个基础安装,带有 Python 系统、Pip、conda 和一些其他工具。虽然安装非常简单,但这里有一些简单的指导原则:

  • 安装在您的主目录 中,当且仅当在完整路径中有而非空格。例如,如果您有一个使用空格的用户名,例如“dennis bakhuis”,那么您的主目录路径也将包含一个空格(/home/dennis bakhuis/)。这可能会导致一些包出现问题,因为不是所有的导入都在路径周围使用引号,这是 spaces 文件夹名称所必需的。如果您碰巧在文件夹中有一个空间,请在不同的位置安装 miniconda。例如在 Windows 中,只需使用根目录:“C:/miniconda3”
  • 安装 miniconda 后,您应该可以在 shell 中使用 conda 命令。要测试这一点,请打开您的 shell 并键入“conda - version”。如果没有找到这个命令,miniconda 的路径必须添加到全局 path 变量中。
  • 对于 powershell 用户,应该在 powershell 中输入一个额外的步骤:“conda init powershell”

这就是安装在虚拟环境中使用 Python 所需的工具的全部内容。在下一节中,我将解释一个典型的工作流程。

典型的工作流程

Miniconda 没有任何 GUI,因此,您的起点总是 shell。

为项目或任务创建 Python 环境

如果您现在打开一个 shell,那么您已经准备好了新的 Python、Conda 和 Pip。您可以将软件包直接安装到您的“基础”环境中,但是我强烈反对这样做。如果你,不管出于什么原因,把你的“基础”环境搞得一团糟,没有办法删除它。选项是重新安装(这实际上并不是那么糟糕)或手动移除软件包。也许有窍门,但更简单的是创建虚拟环境。

我会为每个项目或任务创造一个环境,只是为了把事情分开。如前所述,我使用 conda 创建了一个环境:

conda create --name tutorial python=3.7

这将创建一个名为“tutorial”和 Python 3.7 . x 版本的新环境。因为我们使用了单个“=”,所以我们告诉 conda 使用 Python 3.7 树中的最新版本。目前这是版本 3.7.7。如果我们使用了两个等号' == ',我们会告诉 conda 给出确切的版本 3.7,所以有一个微妙的区别。

创建环境后,我们必须切换到新创建的环境。对于这种情况,conda 有激活命令:

*conda activate tutorial*

现在,您处于名为“教程”的孤立 python 环境中,它有自己的 Python、Conda 和 pip 版本。您可能不完全确定以前创建的环境是如何调用的。要检查可用的环境,您总是可以使用:

*conda env list*

目前,我的基础系统旁边有五个环境。

上图显示了我的所有可用环境。这些只是你的 miniconda 文件夹中的子目录。当前活动的环境用星号显示。在下一节中,让我们在新创建的环境中安装一些包。

使用 pip 安装软件包

在您激活的环境中,使用“pip install”命令安装软件包非常容易。对于这个例子,我们将安装包 numpy,pandas,jupyterlab,matplotlib。虽然 pip 的依赖性检查不像 conda 那样复杂,但是它确实知道 Pandas 依赖于 numpy,并且如果缺少它,它将安装 dependency。要安装软件包,请键入:

 *pip install pandas matplotlib jupyterlab*

安装完成后,包就可以运行了。例如,要启动 Jupyter 实验室,请键入:

jupyter lab

当你在笔记本上工作时,有时会发生忘记安装那个软件包的情况。比如想用 tqdm 有一些进度条。要安装这个包,打开您正在使用的 shell 旁边的另一个 shell,激活环境,并使用 pip 安装 tqdm。该包可以立即在您正在使用的笔记本中使用。或者使用以下方式将其直接安装到您的笔记本电脑中:

“!”用于执行 shell 命令。例如,要创建一个list 目录 (ls),我们需要:

所以用!‘pip install tqdm’我们可以直接在当前环境下安装包。在我看来,shell 方法更显而易见,因为您完全可以确定您将在哪个环境中安装软件包,但是这两种方法都很棒!。

安装软件包的另一个好方法是使用 requirements.txt 文件。这是一个使用“pip freeze”命令生成的列表,给出了所用软件包的确切版本,是从以前的项目中复制环境的好方法。要自己创建 requirements.txt,请在 shell 中键入以下内容:

*pip freeze > requirements.txt*

当然,您也可以从 jupyter 调用这个命令:

如果您打开这个文件,或者在没有 requirements.txt 的情况下运行它,您将会看到您的环境中所有包的列表,以及在双等号后面的确切版本。如果您在项目或 git-repo 的根文件夹中提供这个文件,其他人可以用一个命令安装所有需要的包:

*pip install -r requirements.txt*

如您所见,requirements.txt 是共享和复制环境的好方法。

删除环境和其他命令

过一会儿,您将收集相当多的环境,这会给您的系统带来一些混乱。要删除不再需要的环境,我们可以简单地删除它们。如果您还需要它,使用 requirements.txt 很容易重新创建环境。在删除环境之前,我们必须将其停用。为此,请键入:

*conda deactivate*

现在,我们可以通过键入以下命令来删除环境:

*conda env remove --name tutorial*

为了验证,环境确实消失了:

*conda env list*

一些可能有用的命令:
克隆一个现有的环境:

*conda create --clone tutorial --name tutorial2*

搜索可用的软件包:

*pip search tensorflow*

围捕

这是用来管理蟒蛇、蛇、蛇卵和所有蛇的。正如我之前提到的,这是一种方法,还有许多其他方法。其他方法可能会更好,但这个对我来说很有效。请随意评论这个过程如何能做得更好,或者什么对你有用。

如果您有任何问题或建议,请告诉我。

Ep 3:软技能

原文:https://towardsdatascience.com/ep-3-soft-skills-925045811b43?source=collection_archive---------87-----------------------

我们会叫你

基于事实的求职——极客歌剧

作者图片

"这个解决方案可能会提高你计划投资的有效性."多姆纳尔看到了商人满意的表情,然后把注意力转向了数据库专家。“这将需要整合三个不同的系统,据我所知,这可能会造成一定的困难……”

“如果有充分的理由整合它们,”女人耸耸肩,“我们就整合它们。”

"我们什么时候能得到第一批结果?"这位商人焦躁不安。"竞争最近开始抢走我们的客户。"

多姆纳尔闭上眼睛,回忆起他从 IT 部门收到的原理图。虽然不多,但对于一个合理的估计来说可能足够了。

“在长期或短期项目领域,你会失去更多客户吗?”,他问道。

这位商人需要一点时间来找到合适的桌子并显示在屏幕上。他看了看数字,回答道:“短期。”

多姆纳尔睁开眼睛,伸手拿起身边的一个笔记本,开始画草图。

“所以我们这里有你的客户数据…这里有资金流动…这里有与第三方数据的连接…”他看了一眼数据库专家,她不想错过任何推理的细节,使劲向图纸倾斜,她几乎躺在柜台上。"这些数据湖中哪一个最容易连接?"

“这两个。”女人毫不犹豫地指着素描。“我们可以在半年左右的时间里让它投入生产。”

多姆纳尔暗自笑了笑。他画了几条线,又划掉了几条。他又看了看那个女人。她惊讶地眨了眨眼,但一秒钟后,她赞许地点了点头。

“在这种配置下,我们可以在一个季度内完成。”她向她的商业同事投去询问的一瞥。"前提是我们可以暂时停止开发新的报告系统."

这位商人盯着这幅画愣住了。

“如果我理解正确的话,在半年内,我们可能会得到一个工具,让我们能够识别风险最高的项目,或者在三个月内得到一个流失预测器?”当对话者点头时,他略带失望地说完,“但后者是以举报为代价的吧?”

“这是我的看法,”多姆纳尔证实。“但我需要警告你,我的假设是基于我从你的技术测试中获得的部分数据。此时此刻,我无法保证该解决方案是否可行,即使可行,我们能够达到什么样的精度水平。”

这位陷入困境的商人按摩太阳穴。这位数据库专家精神恍惚地回到了自己的桌子前,可能已经为接下来的几周制定了一个行动计划。

多姆纳尔感到一阵热情。这家公司虽然很小,但有一个深思熟虑的战略,而且管理良好。而迄今为止与管理和技术人员的互动向他证明,员工不仅表现出高水平的能力,而且尊重常识;多姆纳尔最看重的。

“很好,很好,”一位年轻的人力资源部代表出人意料地打断了谈话。

直到现在,多姆纳尔都没有注意到她,因为她像坟墓一样沉默,完全专注于她那长得荒谬的混合指甲的装饰细节。现在她双手交叉放在胸前,给申请人一个灿烂的微笑,既迷人又不真诚。“我想今天够了。”

多姆纳尔感到一阵颤栗顺着他的背爬下来。她的最后一句话是用愉快的语气说的,但无论是这种语气还是女孩脸上喜悦的面具都无法掩盖隐藏在下面的怨恨。

“很好吗?”多姆纳尔皱起了眉头。“我不这么认为。我不知道为什么,但我感觉你认为我不应该得到这份工作。”女孩明显的困惑证实了他的推测。“我可以问为什么吗?”

“我有权否决所有和任何候选人,”她一恢复镇静就甜美地啁啾。“我的职责是评估他们的软技能,我认为你只是缺乏同理心。”

“感同身受?!"多姆纳尔惊讶地睁大了眼睛。“比如在移情能力方面?来调和对话者的情绪?缺少这一点被称为精神变态。我只是表明我能感受到你对我的情绪,尽管你笑得很开心,说了很多友好的话!”

“但你笨拙的交流显然让我的人民不安;我也是。”她生气地瞥了他一眼,然后严厉地补充道:“这种行为是不可接受的。我甚至不会提到,当一个困难的话题出现时,你闭上眼睛明显避免目光接触。”

"我正在考虑解决目前问题的办法。"多姆纳尔怀疑地看着其他参与者,寻求支持。这位商人和数据库专家一丝不苟地研究自己指甲的化妆细节。他绝望地喃喃道:“像他们现在这样。”

“很好!现在一切都清楚了,非常感谢,”人事部门的女孩得意洋洋地宣布。“我们会打电话给你。”

我们将称您为系列:

第一集:数据民主化

第二集:刺激的工作环境

第三集:软技能(当前)

第四集:技能红娘

第五集:沉没成本

第六集:激情,更激情,录用!

第七集:文化契合度

多姆纳尔是个聪明的家伙。但是,找工作是长期的娱乐,很可能要花他一段时间。尤其是工作面试不是每天都有的。与此同时,你可以考虑阅读我们的【Pharmacon社会学惊悚片中的其他(同样出色的)人物。

Ep 4:技能媒人

原文:https://towardsdatascience.com/ep-4-skills-matchmaker-9c89f5008ed9?source=collection_archive---------95-----------------------

我们会叫你

基于事实的求职——极客歌剧

作者图片

“恭喜你。令人肃然起敬。”

扩音器里的声音安抚了多姆纳尔的自尊心,过去几个月的事件多少挫伤了他的自尊心。他后脑勺的声音反过来暗示,听到完全相同话语的人可能有数千人。

“谢谢你,”多姆纳尔本能地回答。正好,他想起了微笑,他微微撇了撇嘴。

“我有最后一个问题,”屏幕上的女士说。

多姆纳尔发现很难想象还有谁能像他一样在情感上透明。这个女人既不漂亮也不丑陋,不愚蠢也不聪明,但同时又是如此的实际和随和,在距离和热情之间如此的平衡,如此的完美,以至于在这一切的某个地方没有留给个性的空间。

“能否请你描述一下你以前工作中最引以为豪的项目,并解释一下这个项目是如何为公司增加重要价值的?”

Domnall 僵硬。不幸的是,他在公司呆的时间不够长,无法评估他最引以为豪的项目成果。有一会儿,他很想提醒这个谜语的作者,项目满意度和附加值并不总是必须携手共进的,但是他不再想这个问题了。别的事情让他担心;到目前为止,所有的问题都无法与添加了问号的跨词定义区分开来。为什么突然这种开放的形式?

他的犹豫不得不引起注意,因为这个女人又一次鼓励了他:

“如果保密条款禁止你谈论这个项目,请告诉我一个你可以的。”

“我离开时签署的协议主要是一份长长的、详细的清单,上面列有我不能做的事情,”多姆纳尔如此专注于打破尴尬的沉默,以至于他的脚踩了进去。“但他们中的大多数人确保我不会以任何形式表达对公司的负面看法,”他补充道,并立即在思想中斥责自己。他又在胡言乱语,而不是去看是非曲直。招募者警告他;信息应该简短、清晰、切中要点!他振作起来。“情况是这样的:为了降低成本,该公司终止了昂贵的物流管理系统,但不幸的是,他们在更便宜的替代系统实施之前就这样做了。”

不,听起来也不好。这样的措辞不仅让多姆纳尔面临与前雇主的律师会面的风险,而且他的对话者可能会将他归类为不满分子。

“多么有趣的项目,”女人出乎意料地打断了他。她的声音和以前一样友好。“你认为情况为什么会是这样?”

多姆纳尔目瞪口呆。他听错了吗?这个问题没有意义!

“我的和解协议明确禁止我对我的公司陷入这种境地的原因发表意见,”他回答道,只是想说点什么,想知道这个女人,在她无限的完美中,是否允许任何错误报告。

“那么你对此没有意见?”

“让我们假设我没有,”多姆纳尔喃喃自语,完全忘记了微笑。接下来的句子他说得又慢又大声又清晰。“回到这个项目,障碍是:信息混乱、大量的数据来源和数据质量。我采取的行动——我设计并准备了一个替代系统的原型。我自动处理和清理关系数据库中的数据。在可能的情况下,我使用各种 python 机器学习库添加了预测元素。”

这个女人沉默的时间比平时长了一点。

“我没有注意到这个项目如何显著增加了公司的价值,”她抱怨道。"请你重新表述一下好吗?"

“我辞职寻找新的机会和挑战,因为太早了,无法知道确切的结果,但如果他们实施我的系统,他们可以大大减少每年给公司造成数百万美元损失的混乱。”

“非常感谢。这是最后一个问题。”如果这个女人从嘴唇上抹去一丝微笑,她的脸将毫无表情。“分析你的陈述,我得出结论,你符合 18 项必备技能中的 14 项。我没注意到你有使用 SQLpandasscikit-learn 库的经验,而且你缺乏准确传达观点的能力。”

" Scikit-learn 是 python 包之一!"多姆纳尔哼了一声。“我用过它,还有 Keras 库,还有 PyTorch 。我甚至没有提到熊猫,因为我没有提到我使用键盘!此外, SQL 是处理我提到的关系数据库的标准。至于交流,很难要求我明确的意见,如果法律禁止我表达一个!”他突然冒出一句,“你不能只根据关键词来评价我!”

“在提问环节结束后给出的陈述不会被考虑在内,”采访程序一贯热情的声音说,这是数百万个微小方程的杰作,它们对专业性进行了优化。“以 14 分的成绩,你排在候选人的第六位。我们会打电话给你。”

我们将称您为系列:

1 集:数据民主化

第二集:刺激的工作环境

第三集:软技能

第四集:技能红娘(当前)

第五集:沉没成本

第六集:激情,更激情,雇佣!

第七集:文化契合

多姆纳尔是个聪明的家伙。但是,找工作是长期的娱乐,很可能要花他一段时间。尤其是工作面试不是每天都有的。与此同时,你可以考虑阅读我们的【Pharmacon社会学惊悚片中的其他(同样出色的)人物。

Ep 5:沉没成本

原文:https://towardsdatascience.com/ep-5-sunk-costs-b9c4f0d463f4?source=collection_archive---------65-----------------------

我们会叫你

基于事实的求职——极客歌剧

作者图片

“我认为你会在我们的初创企业中大有作为。”显然,桌子另一边的内容经理正盯着 Domnall。他的三角形脸和一眨不眨的大眼睛让他看起来像一只螳螂。“我很惊讶,你这个年龄的人对分析技术有如此深刻的了解。”

Domnall 决定不提他刚刚第八次描述了相同的技术,包括两次对招聘人员和五次对经理的下属。对话者的惊讶表明公司沟通不畅,但多姆纳尔也计划改善这种情况。他的嘴角挂着真诚的微笑。

"那么我什么时候可以开始在这里应用我的知识呢?"

“今天晚些时候我会通知 HR。”这个人检查了一下他的文件,低声咕哝了一个低得可笑的数字,然后平静地补充道,“这样的金额不需要我的上级同意,所以应该尽快处理……”

“我想应该是两倍……”多姆纳尔礼貌地纠正道,不确定自己的听力是否有所下降,还是他的记忆被正在进行的招聘过程的电视剧般的节奏削弱了。

“两次?”经理显然很惊讶。

"招聘人员向我保证这是这个职位的工资."

“不可能……他一定是出了什么事。”这个人对这个错误不屑一顾,双手合十,好像在祈祷。“听着。你可以星期一早上从这里开始。据我所知,你已经花了很多钱找工作。即使你在几个月内找到了一份收入更高的工作,这种差异也不足以弥补你在此之前的损失。就是得不偿失!”他向前探了探身子,向他未来的员工递了个眼色,鼓励他靠近一点。他悄声说,“此外,即使你不认为基本工资高,我们提供了一个伟大的股票期权包。我们计划在两三年内上市。”他直起身子,用饱满的声音结束了讲话,“在和你未来的同事谈了这么多之后,你肯定意识到我们的现金流很快就会暴涨!”

多姆纳尔困惑地眨了眨眼。在他的脑海中,他疯狂地分析着他的私人现金流,自从他用新的价值代替收入后,他的私人现金流呈现出稳定的下降趋势。

“股票期权?”他问。"这意味着我可以以固定价格而不是市场价格购买公司股票?"多姆纳尔根本不可能回忆起这部肥皂剧第一集的细节。“问题是,就这点工资,我不可能存下任何东西来投资。”

经理开心地笑了。

“你会用你的奖金买股票的!你每年会得到高达百分之十的额外收入!

多姆纳尔在脑子里刷新了现金流量表,它开始羞怯地、缓慢地、但却肯定地增长。但是后天的不信任战胜了他的乐观。

“奖金靠什么?”

“平常的东西,公司的业绩,团队的业绩,当然还有你的……”男人摆摆手,但看到应聘者质疑的目光,他不耐烦地叹了口气,背诵道,“分别是百分之七十五,百分之二十,百分之五。”

图箭头埋下了头。

“除此之外,我们还为员工提供各种有吸引力的额外津贴……”

"比如名牌服装降价百分之三,去迪拜度假?"

“不仅于此!伙食也有优惠!”

多姆纳尔重新饶有兴趣地看着经理。为杂货店收集优惠券与他从教育中获益的计划强烈冲突。然而,如果这可以帮助他平衡每月的卡路里摄入量,拟议的工资应该包括他的房租,学生贷款还款和日常通勤。

螳螂侠大概感觉到了他的犹豫,因为他贪婪地搓着手,骄傲地宣布:“好!在一些真正高档的餐馆里高达 10%!”

尽管如此,当申请人的眼神变得黯淡时,经理掩饰不住的恼怒说道,“你很清楚,我们为这次会面付出了多少努力。难道你不认为我们为寻找和评估你所投入的工作和金钱也是你工资的一部分吗?!"男人脸上轻蔑的表情泄露了他对多姆纳尔突然困惑的厌恶,但他强迫自己扔给申请人另一个救生圈,“此外,我们周一也有新鲜水果!”

“有了这样的工资阶梯,我也会考虑在周二提供面团,周三提供肉,周四提供甜食,周五提供鱼。”

经理皱起眉头,很不高兴。他从柜台上拿起文件,把椅子往后推了推。

“我会考虑的,”他咆哮着,显然被冒犯了,“我们会打电话给你。”

我们将称您为系列:

1 集:数据民主化

第二集:刺激的工作环境

第三集:软技能

第四集:技能红娘

第 5 集:沉没成本(当前)

第六集:激情,更激情,录用!

第七集:文化契合

多姆纳尔是个聪明的家伙。但是,找工作是长期的娱乐,很可能要花他一段时间。尤其是工作面试不是每天都有的。与此同时,你可以考虑阅读我们的 【药理学】 社会学惊悚片中的其他(同样出色的)人物。

EPL 2020/21 赛季分析与预测

原文:https://towardsdatascience.com/epl-2020-21-season-analysis-and-prediction-5502e20dce26?source=collection_archive---------29-----------------------

在第四周比赛后进入国际比赛日,已经打了 38 场比赛,正好是赛季中 380 场比赛总数的 10%。到目前为止,本赛季一直不可预测,去年的顶级球队积分下降,一些中游球队和弱队表现出色。在这篇文章中,我试图分析球队的表现,并试图预测即将到来的比赛结果。

预期目标(xG)是用于分析和预测的主要因素,如果你不熟悉 xG,建议你在继续下一步之前查看这篇解释 xG 的文章。

主场优势,在后 COVID 时代还存在吗?

由于疫情,比赛目前在空的体育场进行。主场优势不仅仅是对比赛场地的熟悉,而是成千上万为主队的胜利加油的铁杆球迷的精神和鼓励。

这就是为什么即使想到要去安菲尔德或者老特拉福德也会让客场球队不寒而栗。一般来说,与客场比赛相比,球队在主场的表现更好。

本赛季,到目前为止还没有主场优势的证据。在迄今为止的 38 场比赛中,19 场比赛客队获胜,3 场平局,主队只赢了 16 场比赛,约占总比赛数的 42%。

奇怪的主场劣势!

本赛季主队得分一直被客队超过。此外,主队在【预期进球】和【预期失球】两项指标上都表现不佳。

卫冕冠军利物浦在每场比赛的预期进球中领先,每场比赛约 2.5 xG,包括点球。热刺、阿斯顿维拉、埃弗顿也都管理过大于 2 的 xG。
西布朗是目前排名最低的球队,在很低的 xG 下努力创造机会。
xG 低的球队缺乏创造力,应该用有创造力的球员来补强球队。对于采用防守型打法的球队来说,xG 可能较低,这种打法依靠对手的反击或失误来得分。
埃弗顿、南安普顿、西汉姆似乎有着密不透风的防守,注册 xGA 低于 1。谢菲尔德,阿斯顿维拉和布莱顿也展示了坚实的防守。根据 xG 承认,上赛季前四名球队中的 3 支——利物浦、曼城和曼联——是防守最差的 5 支球队。曼联记录了最高的预期失球,平均每场比赛约 2.5 个球。利兹和西布朗也有 2 个以上的 xGA。xGA 高的球队应该立即解决他们在防守上的问题。

得分的净预期目标

Delta xG 是预期进球和预期失球之间的差值,可以用来评估一支球队的状态。埃弗顿似乎统治着联盟,每场比赛的 delta xG 接近 1.5。热刺和阿斯顿维拉也有 delta xG 超过 1。尽管被阿斯顿维拉以 7-2 羞辱,红军仍然紧随其后排在第四位。另一端,曼联和西布朗的 delta xG 都在 1.5 以上。

红线以上的队伍 xG 比 xGA 好。上赛季的最佳射手曼城队通常统治着联赛,但他们没能比对手创造更多的机会。他们的同城对手曼彻斯特联队经历了几十年来最糟糕的开局。

期望与现实

一支球队可以超越 xG,要么是因为球队拥有多产的前锋,他们可以转换一半的机会,要么是因为运气好,设法进了一些球。阿斯顿维拉每场比赛都比 xG 多进 1.5 个球,他们不太可能继续前进。
莱斯特城似乎也远远超过了 xG,这可以归功于瓦尔迪的 3 个点球。除非莱斯特每个周末都被判罚点球(即使有新的手球宽松政策,这也是极不可能的),否则他们的差距就会缩小。
曼联的 5 个进球中有 2 个也来自点球,xG 来自空位的发挥对于红魔来说也要低得多。

阿斯顿维拉、纽卡斯尔、阿森纳和利兹是 20 支球队中仅有的 4 支超过预期失球的球队。这个赛季进球似乎很容易。
利物浦、曼联、富勒姆、伯恩利和布莱顿都不走运,每场比赛失球比预期的多。

象限分析

最好的情况是超过 xG 和 xGA 一个合理的幅度。
从长远来看,大幅超越 xG 通常是不可持续的。如果球队设法创造更多的机会,落后于 xG 不是一个大问题(xG)。
气泡的大小表示每场比赛的预期净胜球数(xG-xGA)。球队的首要目标应该是提高净胜球。
第一象限:超水平发挥的 xG 和超水平发挥的 xGA
Q1 队在超水平发挥预期目标方面做得很好,他们必须保持这种势头,像利兹和纽卡斯尔这样的球队应该努力提高净胜球数。
第二象限:表现出色的 xG 和表现不佳的 xGA
Q2 的球队应该努力向 Q1 靠拢,这是为了提高防守。
第三象限:表现不佳的 xG 和表现不佳的 xGA
第三季度的球队应提高防守和进攻。
第四象限:表现不佳的 xG 和表现良好的 xGA
第四季度没有团队。

预测结果

用于预测比赛分数的逻辑是基于前一时期每场比赛的 xG 和 xGA。

主队得分计算为主队 xG 和客场 xGA 的平均值。
G _ home =(xG _ home+xGA _ away)/2

客场队的分数计算为客场队的 xG 和主队的 xGA 的平均值。
G _ away =(xG _ away+xGA _ home)/2

净胜球(GD)的计算方法是主队得分与客队得分之差。
T4【GD = G _ home-G _ away

总进球数(GS)是主队得分和客队得分的总和。
GD=G_home+G_away

第五场比赛的预测结果如下。

游戏周 5 结果预测

净胜球的绝对值越高,比赛就越一边倒,而净胜球的值越接近零,就意味着这场比赛有望势均力敌。
GD 的负值暗示客队有可能获胜,正值偏向主队获胜。
较高的进球数意味着我们可以期待一场进球盛宴,而较低的进球数则表明比赛得分较低。
根据模型,伯恩利在客场对阵西布朗的比赛中表现最佳,净胜球为 0.77,有利于红葡萄酒。
布莱顿对水晶宫的比赛也有望成为海鸥公园里的散步。曼联造访圣詹姆斯公园的比赛估计会让红魔再次心碎。
曼城 vs 阿森纳的比赛是比赛周中最势均力敌的一场比赛,xG 略微有利于枪手。切尔西对圣徒和利兹对狼也将是一场激烈的比赛。默西德比被认为是一场进球盛宴,东道主比卫冕冠军更胜一筹。

更新:预测与实际结果

最后,这是关键时刻,是时候将预测与第 5 周的实际比赛结果进行比较了。

表现超出预测 xG 的团队在线上,而表现低于预测 xG 的团队在线下。
曼联远远超出了他们的预测。他们的 xG 预测很低,因为样本量只有他们打水晶宫(最好的防守方之一)、布莱顿和马刺(10 人)的 3 场比赛。随着赛季的进行,他们的 xG 会提高。

在总共 10 场比赛中,只有 3 场比赛的预测是正确的,这是预期的,因为样本量非常小,没有考虑其他因素,当然也是由于比赛固有的不确定性。水晶宫对布莱顿的比赛中预测最为准确。客队被预测会统治 xG,他们以 20 次射门击败水晶宫的 1 次射门。在纽卡斯尔对曼联、埃弗顿对利物浦、热刺对铁锤帮和利兹对狼队的比赛中,这些预测都是非常错误的。

资源和鸣谢

数据来源于fbref.com
所有相关的输入 csv 文件和 jupyter 笔记本(python 代码)都可以在我的 GitHub Repo 中访问。

成为会员

我希望你喜欢这篇文章,我强烈推荐 注册中级会员 来阅读更多我写的文章或成千上万其他作者写的各种主题的故事。
你的会员费直接支持我和你看的其他作家。你也可以在媒体上看到所有的故事。

亚历克斯·莫托克在 Unsplash 上拍摄的照片

EPL 分析和游戏周 7 预测

原文:https://towardsdatascience.com/epl-analysis-and-gameweek-7-prediction-f22a2d8991cd?source=collection_archive---------52-----------------------

使用 xG 统计预测英超联赛结果的数据驱动尝试

这是我的 EPL 预测系列的一篇文章。你可以在这里查看上一周比赛的预测和实际表现。

预期目标或 xG 是用于预测的参数。如果你对理解预测算法感兴趣,我推荐你去看看这篇文章,里面有详细的解释。

截至第 6 周比赛的分析

在 6 个比赛周之后,前 15 名球队之间有 6 分的差距,到目前为止还没有明确的冠军争夺者。联赛竞争激烈,没有不败的球队。唯一在第五轮比赛前保持不败的球队,埃弗顿和阿斯顿维拉在第六轮比赛中尝到了他们的第一次失败。两个默西队都以 13 分高居积分榜首。由于净胜球,埃弗顿在积分榜上排名第一。

xG 每场比赛得分和失球(图片由作者提供)

卫冕冠军利物浦是最好的进攻球队,每场比赛创造超过 2.5 xG,没有其他球队能够每场比赛创造超过 2 xG。马刺、利兹、太妃糖、维拉场均 1.5 xG 以上。
另一方面,西布朗在每场 0.5 左右的 xG 下努力创造进球机会。更糟糕的是,西布朗的防守也是漏洞最多的。狼队和伯恩利队也在努力创造得分机会,但他们能够以良好的防守能力部分弥补这一点,正如低失球率所表明的那样。

埃弗顿、布莱顿、西汉姆和南安普顿拥有最好的防守,每场失球约 1 xG。尽管布莱顿队防守严密,但他们在比赛中运气不佳,至今丢了 12 个球,平均每场丢 2 个球。

作者图片

根据 xG 得分和 xG 失球,球队可以分为 4 个象限,如上图所示。水平虚线表示每场比赛的平均 xG 得分。水平虚线以上的球队是强攻方,下面的球队进攻弱。
垂直虚线显示每场比赛的平均 xG 失球,左边的球队防守强,右边的球队防守弱。

所有球队的目标都应该是 Q2,那里的进攻和防守都比平均水平要好。例如,伯恩利在联盟中是一个很好的低位防守方。在第六场比赛中,他们面对的是本赛季进球最多的马刺队。伯恩利的防守在遏制热刺进攻方面做得很好,他们在上半场将射门限制在零,比赛的唯一进球来自定位球。然而,伯恩利是创造机会最少的球队之一。除非他们采取积极的措施来提高他们的打击力,否则他们很难在联赛中晋级。

作者图片

一些团队能够用他们在另一个领域的优势来弥补他们在一个领域的弱点,从而产生正的 delta xG(xG 得分和 xG 失分之间的差异)。我们可以看看利兹和南安普顿。贝尔萨的球队在遏制对手进攻方面表现不佳,但他们能够创造进球机会来弥补前者。另一方面,圣徒队的防守几乎没有失误,但在为 Ings 和队友创造得分机会方面做得不好。但他们的防守能力可以弥补前场创造力的不足。

游戏第 7 周预测

在进行预测之前,让我澄清一下,这是一个非常简单的算法,只是基于过去的 xG,所以只能预期基线性能。样本量很小,而且很多其他重要因素也没有考虑。随着赛季的进行,这个算法将会在未来结合更多的因素。

下表提供了对第 7 周比赛的预测。
GD 的绝对值显示了比赛的竞争力。该值越高,预计匹配越偏向一侧,预测的准确性也越高。GD 值越低,这场比赛就越可能是任何人的游戏。GD 的正值表示主场胜,负值表示客场胜。

游戏第七周预测(图片由作者提供)

在即将到来的比赛中,我们可以期待许多竞争激烈的比赛。纽卡斯尔对埃弗顿是唯一一场可以观察到超过 0.5 倍差距的比赛。太妃糖极有可能带着 3 分离开圣詹姆斯公园。富勒姆有相当大的机会在本周对阵麻雀队的比赛中赢得本赛季的第一场胜利。卫冕冠军有望在主场赢得对复活的铁锤帮的比赛,铁锤帮已经让曼城和热刺丢分。冠军争夺者,德·布鲁恩和他的公司有望压倒刀锋队的防守。

利物浦 vs 西汉姆有望产生最多的进球数。另一方面,保卫战——狼队 vs 水晶宫预计是得分最低的比赛。

更新:实际与预测

预测的 xGD 与实际的 xGD(图片由作者提供)

该算法在预测游戏周的 10 场比赛中的 9 场比赛的方向方面做得非常好。这个预测只有在纽卡斯尔对埃弗顿的比赛中是错误的。我们的算法预测埃弗顿队会压倒纽卡斯尔队。然而,喜鹊击败了太妃糖,连续第二次击败了他们。由于詹姆斯·罗德里格兹、理查德森和迪格内三人组的缺席,太妃糖队肯定是弱队,这不能在 xG 模型中考虑。就震级而言,预测并不准确。在所有比赛中,占优势的球队能够创造比预期更多的进球机会。这种差异在阿斯顿维拉对南安普顿,托特纳姆对布莱顿,纽卡斯尔对埃弗顿和利兹对莱斯特的比赛中最为明显。这些比赛也有有利于获胜队的点球。

照片由谁是德尼罗?号上的 Unsplash

EPL 分析和游戏周 8 预测

原文:https://towardsdatascience.com/epl-analysis-and-gameweek-8-prediction-691fcc6bdfdd?source=collection_archive---------48-----------------------

使用 xG 统计预测英超联赛结果的数据驱动尝试

这是我的 EPL 预测系列的一篇文章。你可以在这里查看对前一周比赛的预测以及它与实际表现的对比。

预期目标或 xG 是用于预测的参数。如果你对理解预测算法感兴趣,我推荐你去看看这篇文章,里面有详细的解释。

对第 7 周比赛的分析

在 7 个比赛周之后,前 13 名球队之间有 6 分的差距,到目前为止还没有明确的冠军争夺者。联赛竞争激烈,没有不败的球队。联盟的竞争力可以用下面这句特别的话来概括:

你赢了一场比赛,你是第二,第三或第四。你失去了 2 分你是第 7,第 8 或第 9。英超好美!
——穆里尼奥

每场比赛 xG 得分与 xG 失球(图片由作者提供)

在 7 个比赛周之后,卫冕冠军回到了榜首,看起来是最好的进攻方,场均 2.5 xG 左右。红军每场比赛比第二名的马刺多创造 0.5 xG 以上。莱斯特,阿斯顿维拉,利兹和埃弗顿是其他每场比赛创造超过 1.5 克的球队。

依靠防守型打法的水晶宫、谢联、狼队、伯恩利都在创造力上苦苦挣扎,甚至不能每场创造 1 个 xG。西布朗处于一个非常不稳定的位置,既要努力创造得分机会,又要遏制对手的进攻。

当谈到每场比赛的预期失球时,两支球队之间没有很大的差异。大多数球队每场比赛承认 1 到 1.5 xG。只有富勒姆、曼联、西布朗和利兹的场均失球超过 1.5 克。

xG 得分 vs xG 失球(图片由作者提供)

根据 xG 得分和 xG 失球,球队可以分为 4 个象限,如上图所示。水平虚线表示每场比赛的平均 xG 得分。水平虚线以上的球队是强攻方,下面的球队进攻弱。
垂直虚线显示每场比赛的平均 xG 失球,左边的球队防守强,右边的球队防守弱。

每场比赛的增量 xG(图片由作者提供)

尽管红军的防守没有上个赛季那么好,但由于萨拉赫和他的队友的进攻能力,他们成功地登上了德尔塔-xG 排行榜的榜首。

游戏第 8 周预测

在进行预测之前,让我澄清一下,这是一个非常简单的算法,只是基于过去的 xG,所以只能预期基线性能。样本量很小,而且很多其他重要因素也没有考虑。随着赛季的进行,这个算法将会在未来结合更多的因素。该算法也不能预测高得分游戏。

该方法的预测准确性在游戏周期间有所提高。在上一个游戏周,算法能够正确预测 10 场比赛中 9 场比赛的方向。

下表提供了对第 8 周比赛的预测。
GD 的绝对值显示了比赛的竞争力。该值越高,预计匹配越偏向一侧,预测的准确性也越高。
GD 值越低,这场比赛就越有可能成为任何人的游戏。GD 的正值表示主场胜,负值表示客场胜。

(图片由作者提供)

本周比赛的重头戏是在伊蒂哈德球场进行的利物浦 vs 曼城的超级周日比赛。该算法即使不能计入克洛普和佩普战术方法的变化,也预测这将是一场高分比赛。然而,预期的净胜球表明利物浦将带着所有的 3 分离开伊蒂哈德。在即将到来的对维拉队的比赛中,枪手预计也会在主场失利。西布罗姆维奇对热刺的比赛预计将是最一边倒的比赛,凯恩和他的队友们预计将击败混乱的西布罗姆维奇防线。

在两连败后,太妃糖有望在主场对阵红魔的比赛中重回胜利之路。狐狸,蓝调,铁锤和海鸥也可以期待主场胜利。

圣徒对喜鹊,老鹰对孔雀被认为是任何人的比赛,拉尔夫·哈森胡特尔和马塞洛·贝尔萨的球队比他们的对手略胜一筹。

预测与实际

作者图片

在第八周的比赛中,我们的预测在 10 场比赛中有 6 场是正确的。然而,这些预测并不十分准确,只有 3 个预测的准确度在 0.5 倍以内。阿森纳对阿斯顿维拉的预测最为准确。对于切尔西对谢菲尔德的比赛,预测相差了将近 2 倍,切尔西被认为会创造更多的机会。然而,如此大的优势是没有估计到的。周末唯一真正令人失望的是埃弗顿对曼联的比赛,我们预测太妃糖会在主场轻松获胜,但曼联表现出色,全取 3 分,这要感谢布鲁诺的个人才华!
西汉姆对富勒姆的比赛,预测是铁锤帮主宰了比赛,结果也是 1-0,大卫·莫耶斯队获胜。然而,由于洛克曼错过了一个对他们有利的点球,富勒姆创造了更多的机会。
Pep vs Klopp 是一场高度不可预测的比赛,我们对巨人队之间超级周日冲突的预测稍微有利于德国队。经过一场势均力敌的比赛,这场比赛以平局告终。曼城创造了比冠军更多的 xG,这要归功于曼城获得的点球,KDB 的射门偏出了门柱!如果那个点球没有被判,我们的预测是非常准确的。

照片由 Jaleel Akbash 在 Unsplash 上拍摄

EPL 幻想 GW1 回顾和 GW2 算法选择

原文:https://towardsdatascience.com/epl-fantasy-gw1-recap-and-gw2-algo-picks-58165f17b77d?source=collection_archive---------41-----------------------

我们的金钱球方法到幻想的 EPL(队 _id: 2122122)

如果这是你第一次登陆我的幻想 EPL 博客,你可能会想看看我在上一季(GW1-GW9)开始时写的我的媒体档案中的一些原始 EPL 博客,以熟悉我们的整体方法和我们随着时间的推移所做的改进。

什么是新的?

自上周以来,我们增加了一些更新,以帮助保持了解重要的每周统计数据,可以帮助我们更明智地选择球员。

定位球队员:我们收集了各队角球和任意球时定位球队员空中威胁的数据,并将这些数据作为系数添加到我们的优化算法中。请参考下表,看看哪些球员更有可能因为参与更多的定位球进攻打法而长期获得大量加分。

预测首发阵容:正如我们已经看到的,本赛季开始时有很多惊喜,所以我们找到了几个网站,考虑到周日的比赛,如杯赛和欧洲比赛,教练新闻发布会和最新的球队新闻,试图预测每个比赛周的首发阵容,包括可能有疑问的常规球员。这将有望拯救我们在 GW1 中所做的一些错误的选择,在那里我们有三个完整的球员没有在我们的一个队中首发……:(

GW1 排名前 100 的 FPL 团队统计数据

来自 GW1 的世界排名前 100 位的球员中,大多数都有萨拉赫担任三重队长,得分在 125 分+的范围内。让我们来看看他们球队中按位置选择最多的球员和最喜欢的球队阵型。

前 100 名最佳守门员

前 100 名中最受欢迎的捍卫者

前 100 名最佳中场球员

前 100 名中入选最多的前锋

我们使用这些数据和当前的球员价格来创建下面的球队,这是由前 100 名中最受欢迎的球员组成的:

看起来不错的团队,在关键位置上有很多尝试不同选择的余地,同时仍然保持一个坚实的球员核心。

前 100 名 Fantasy 用户选择最多的团队

这些数据很有意义,因为大多数顶级球员都试图利用 4-4-2 或 3-4-3 阵型的进攻型中场和前锋。

GW1 团队绩效总结和总体统计

我们有一个不错的开始,因为我们的一些团队得分在 70+的范围内。每周,我们都会发布前 2 名表演团队的照片。有趣的是,我们得分最高的球队有80 分,而甚至没有萨拉赫当队长。如果我们是萨拉赫的队长,我们会有接近 100 分的**!最重要的是,我们有 3 名 0 分未上场的球员,这是我们在第一个比赛周唯一的失望。**

我们还参加了 FPL 的 FanTeam 版本,在那里我们也有两支起步非常强劲的车队。又一次,他们中的一个选错了队长。

为我们的 GW2 选秀权提供有用的数据

由于我们今年在算法中加入了很多新的统计数据,随着时间的推移,这个博客将会有更多的统计数据和图表,更少的文本。让我们从下面三个比赛周的比赛难度等级(FDR)开始:

看起来阿森纳、水晶宫、莱斯特、西汉姆和维拉有一些艰难的比赛即将到来,所以我们的算法可能不会从这些球队中挑选球员。埃弗顿、曼联、曼城和谢菲尔德联队在接下来的三周里似乎有更轻松的赛程。

博彩赔率

我们会尽量把 队伍中有超过 50 %胜算的 玩家,比如 MUN,MCI,ARS,EVE,雷和 LEE 。我们应该尽量不要有太多来自 CRY、WBA、WOL、WHA 或者 BUR 的防守球员。

较高概率抽 的队伍,特别是当比赛是 结合高赔率为 2.5 以下的 时,可能会以 对选择防守球员 有利,因为如果比赛以 0:0 结束,那将会产生大量的加分。结合 下方的 下/上图,我们可以识别出以下 概率较高的至少一场不失球的比赛——新 vsSOU vs TOT。很高兴看到我们上周的预测完全实现了,WOL、纽斯和科尔都没有失球,尽管没有一场比赛以平局告终!******

相反,我们可能希望从 赔率超过 2.5 的游戏中有更多的 攻击玩家 ,例如CHEvs LIV,ARS vs,MUN vs. CRY,WOL vs MCI,EVE vs. WBA。再一次,上周的赔率完美地发挥出来,因为所有的游戏都预测有超过 2.5 个目标!

裁判统计

事实上,我们还发现了一个提取裁判分配的网站,所以现在你可以看到哪些比赛的裁判更有可能判点球或给很多牌。我们也有主场优势统计,这可能有点主观,但由于大多数裁判似乎不倾向于主队,少数实际上有积极得分的统计,可能会比其他人更倾向于主队。话虽如此,看起来安东尼·泰勒有最高的点球率和主场优势系数,所以从麦克·迪恩的数据来看,利兹联队有可能被罚,埃弗顿队也有可能被罚。看起来,像游戏车-丽芙和-舒有裁判喜欢给很多卡,所以预计会失去一些黄牌,但希望没有红色…

预测模型(球员统计)

现在是今年改进算法的皇冠上的宝石——预测球员统计数据的时候了。在为接下来的 n 个游戏周调整我们的团队优化器时,我们会考虑三个主要指标***—预测总点数、期望值(ROI)和每场游戏奖励点数 。下面是每个指标的统计数据,也是按职位细分的。***

预计总积分—前 25 名玩家

预计预期价值(ROI) —前 25 名参与者

每场比赛奖金(上赛季)—前 25 名球员

预测积分——顶级守门员

投射点数—顶级防守者

预测得分——顶级中场

预测分数——顶级前锋

正如你所看到的,每个位置都有大量选项可供我们选择,因此我们将把上面的许多统计数据插入 Python 中的 优化函数,该函数将 输出具有最高预期总积分 的团队,给定我们的预算约束和进入我们决策过程的其他指标。在团队选择器代码生效之前应用的一些初步过滤器包括:

  1. 排除受伤或停赛球员
  2. 从 FDR 高的队伍中排除玩家
  3. 在 GW1 中排除没有固定比赛的队伍中的球员
  4. 同一团队不能有超过 3 名玩家
  5. 总共必须有 15 名球员(GK=2,DF=5,MD=5,ST=3)

下面是模型文本输出的两个例子——一个用于一个全队优化T5,一个用于一个*单人转会。*****

1:使用填充接头优化 3–5–2 地层的预算

正如你在下面看到的,模型首先查看参数,告诉它是否应该向 15 名球员的全队优化,或者向拥有 11 名关键球员和 4 名廉价替补 的特定阵型优化。对于填充符,它首先查看 首选地层 ,并使用那个 来决定每个位置 需要多少个填充符。然后,模型从我们的初始预算中减去花费在 4 个填充者上的总金额,并将剩余的预算花费在关键的 11 个参与者上, 给出优化函数和模型约束

例 2:优化有 15 名现役球员的 3–5–2 阵型的预算

*游戏周 1 最终选出的队伍*

和去年一样,并不是我们所有的决策过程都可以完全自动化,这就是这个游戏如此有趣和令人兴奋的原因。也就是说,我们经常查看优化器算法的 多个输出,运行一些不同的约束和优化函数 ,并将它们与本文前面描述的所有其他有用的统计数据结合起来,如 裁判统计数据、博彩赔率、FDR 分数、处罚统计数据、奖励积分统计数据 等。—向我们最终的团队选择 流程添加一个 人的因素。下面是一个平衡稳固的团队的例子:

就我们自己的球队而言,我们决定不打我们的外卡,并试图在下周用两次免费转会来解决我们的门将问题。所以,我们这周的球队看起来和上周很相似,除了我们用威尔逊换走了安东尼奥。我们也希望下周用我们保留的 2 次自由转会得到 KDB。

**

结论

看起来很多球员在 GW1 之后使用了外卡,这是可以理解的,MCI 和 MUN 的空白周,以及随着转会窗口结束的临近,每天都出现的首发阵容和最近球员转会消息中的许多惊喜。如果你是那些 FPL 用户中的一员,我希望上面分享的统计数据能帮助你重新选择一个更加稳固和平衡的球队,充满了有望在未来首发阵容中的球员。享受这个周末的比赛,祝你好运,选出正确的队长,因为上周末埃及国王提醒了我们这是多么重要:)

EPL 幻想 GW2 回顾和 GW3 算法选择

原文:https://towardsdatascience.com/epl-fantasy-gw2-recap-and-gw3-algo-picks-16573dd004bd?source=collection_archive---------36-----------------------

我们的金钱球方法到幻想的 EPL(队 _id: 2122122)

如果这是你第一次登陆我的幻想 EPL 博客,你可能会想看看我的媒体档案中的一些我们最初的 EPL 博客,以熟悉这个项目是如何开始的,以及随着时间的推移我们所做的改进。

GW2 排名前 100 的 FPL 队数据

来自 GW2 的世界排名前 100 的选手,大部分得分都在 125 分以上。让我们来看看他们球队中按位置选择最多的球员和最喜欢的球队阵型。

前 100 名最佳守门员

前 100 名中最受欢迎的捍卫者

前 100 名最佳中场球员

前 100 名中入选最多的前锋

我们使用这些数据创建了下面的团队,它是由前 100 名中最受欢迎的球员组成的:

前 100 名 Fantasy 用户选择最多的团队

这些数据很有意义,因为大多数顶级球员都试图利用 4-4-2 或 3-4-3 阵型的中场和前锋。

GW2 团队绩效总结和总体统计

我们所有团队的得分都高于平均水平,最高的团队得到了66 分。每周,我们都会发布前 2 名表演团队的照片。可惜我们没挑到好队长。我们选择了 Bruno Fernandez,因为我们预计会有点球,因为这两支球队在过去的 5 个赛季中拥有最高的点球统计数据。嗯,我们对点球的判断是正确的,但不幸的是,对我们来说,那是因为哭泣,而不是因为门:)由于若日尼奥错过了对丽芙的点球,我们上周的点球运气非常糟糕。

我们还参加了 FPL 的 FanTeam 版本,在那里我们有本周表现最好的团队。再一次,不是最佳的队长选择——莱斯特进了 4 个球,而瓦迪不知何故甚至没有参与其中的一个。所以,我要说我们上周的运气很差总体来说,但不知何故我们还是做得不错。

为我们的 GW3 选择提供有用的统计数据

由于我们今年在算法中加入了很多新的统计数据,随着时间的推移,这个博客将会有更多的统计数据和图表,更少的文本。让我们从下面三个比赛周的比赛难度等级(FDR)开始:

看起来阿森纳、维拉、利兹和纽卡斯尔将会有一些艰苦的比赛,所以我们的算法可能不会从这些球队中挑选球员。狼队、切尔西、富勒姆、曼联和谢菲尔德联队在接下来的三周似乎有更轻松的赛程。

博彩赔率

我们将尝试积累来自 队的有超过 50 %机会赢得 的玩家,例如 MUN、CHE、、LIV、TOT、MCI 和 EVE 。我们应该尽量不要有太多来自雷、WBA、NEW、ARS、、CRY、WBA、、BUR 的防守球员。

较高概率抽 的队伍,尤其是当比赛是 结合高赔率为 2.5 以下的 时,可能会对选择 防守队员 有利,因为如果比赛以 0:0 结束,那将会产生大量的加分。结合 下方的 下/上图,我们可以确定以下 至少一场不失球概率较高的比赛——WHU-WOL、布尔-苏、富尔-AVL、舒-李。

相反,我们可能希望从 赔率超过 2.5 的游戏中获得更多的 攻击玩家 ,例如 MCI vs. LEI 、LIV vs. ARS、WBA vs. CHE、TOT vs. NEW。同样,上周的赔率表现得相当好,因为大多数游戏预测有超过 2.5 个目标!

裁判统计

从下面的统计数据来看,在比赛中出现点球的几率更高: CRY-EVE,WBA-CHE,TOT-NEW,MCI-LEI 和 LIV-ARS ,所以我们建议为其中一些球队配备点球手。看起来,像游戏 CRY-EVE 和 SHU-LEE 有裁判喜欢给很多牌,所以预计会因黄牌而失去一些分数,但希望没有红牌…

定位球运动员

为了帮助你选择定位球运动员,请看下面的列表,它或多或少是最新的,有几个可疑的预测:

预计首发阵容

在我们运行最终的团队选择器之前,让我们考虑一下每个团队的预计首发 11 人。

请注意右边可疑球员的名字,以及下面最新的伤病消息:

预测模型(球员统计)

现在是今年改进算法的皇冠上的宝石——预测球员统计数据的时候了。在我们将所有 FDR、赌注系数、ref 首发、预计阵容和伤病分层后,有两个主要指标我们在为下一个 n-gameweeks 团队选择调整我们的团队优化器时会考虑到— 预测总积分和期望值(ROI)。 下面是每个指标的统计数据,也按职位细分。

预计总积分—前 25 名玩家

预计预期价值(ROI) —前 25 名参与者

预测积分——顶级守门员

投射点数—顶级防守者

预测得分——顶级中场

预测分数——顶级前锋

正如你所看到的,我们可以为每个位置选择大量选项,因此我们将把上面的许多统计数据插入 Python 中的 优化函数,该函数将 输出具有最高预期总积分 的团队,给定我们的预算约束和其他进入我们决策过程的指标。在团队选择器代码生效之前应用的一些初步过滤器包括:

  1. 排除受伤或停赛球员
  2. 将球员排除在 FDR 高的队伍之外
  3. 排除 GW1 中没有固定比赛的队伍中的球员
  4. 同一团队不能有超过 3 名玩家
  5. 总共必须有 15 名球员(GK=2,DF=5,MD=5,ST=3)

《出埃及记》使用填充接头优化 3–5–2 地层的预算

正如你在下面看到的,模型首先查看参数,告诉它是否应该向 15 名球员的全队优化,或者向有 11 名关键球员和 4 名廉价替补 的特定阵型优化。对于填充符,它首先查看 首选地层 ,并使用该 来决定每个位置 需要多少个填充符。然后,该模型从我们的初始预算中减去花费在 4 个填充者上的总金额,并将剩余的预算花费在关键的 11 个参与者上, ,给定优化函数和模型约束 。**

我们使用优化器算法的输出来构建以下团队:

我们几乎只做了一个改变,那就是用 KDB 换来了奥巴。今年我们将试图从额外的转会中获得很少的-4 分,因为我们的算法意味着投资那些你至少可以保留 3-4 个游戏周的球员,所以我们不应该每周都做很多转会。选择队长很难,但考虑到儿子最近的状态和纽卡斯尔不稳定的防守,我们希望这会有所回报。但是我们也认为 KDB、萨拉赫和费尔南德斯也是不错的队长人选,因为在所有这些球队的比赛中,点球的机会都比较高。

结论

我们仍然有一些工作要做,以摆脱萨利巴,得到一个比阿雷奥拉更稳定的 GK,但这可能需要几个游戏周才能完成,所以,现在,我们坚持我们对当前阵容的长期投资**,并给球员至少 3-4 周的时间来实现他们的预期潜力。他们中的一些人,如**的儿子、萨拉赫和 KDB,已经获得了可观的红利:)享受这个周末观看比赛的乐趣,并祝你好运,选出正确的队长,因为我们都被儿子和凯恩在上周末提醒过这是多么重要:)

EPL 幻想 GW21 重述和 GW22 算法选择

原文:https://towardsdatascience.com/epl-fantasy-gw21-recap-and-gw22-algorithm-picks-112fac6f0841?source=collection_archive---------27-----------------------

EPL 幻想博客

我们的钱球方法的幻想 EPL(队 _id: 2057677)

如果这是你第一次登陆我的幻想 EPL 博客,你可能会想看看我在本赛季开始时写的一些原始 EPL 博客(GW1-GW9),以熟悉我们的整体方法和我们随着时间的推移所做的改进。我在这个项目中的犯罪搭档是 Andrew Sproul,他和我一样对数据科学、人工智能和梦幻运动充满热情。

GW21 世界排名前 100 的选手

世界顶级球员表现相对较好,场均 65 分,而场均 48 分。不过,也有一些顶级球员的得分在 30-40 分之间,所以如果你的得分在 50 分以上,你仍然可以自我感觉良好。

EPL 100 强球员最佳混合团队

当我们谈论世界前 100 名球员的话题时,让我们看看谁是他们球队中最受欢迎的球员,以及 GW21 最受欢迎的球队阵容。

前 100 名最佳守门员

前 100 名中最受欢迎的捍卫者

前 100 名最佳中场球员

前 100 名中入选最多的前锋

我们使用这些数据和当前的球员价格来创建下面的球队,这是由前 100 名中最受欢迎的球员组成的:

看起来不错的团队,在关键位置上有很多尝试不同选择的余地,同时仍然保持一个坚实的球员核心。

前 100 名 Fantasy 用户选择最多的团队

再次, Vardy 令人惊讶地没有参加上周的比赛,由于得到了 MD 或 DF 替补,他将每个人的阵型改为 3-5-2 或 4-4-2。

GW21 团队绩效总结和总体统计

总的来说,这是一个不错的一周,我们得到了 56 分,高于平均水平 48 分。有趣的是,我们的大部分分数来自于一些更便宜的球员——格里利什和坎特威尔,分别得到 13 分和 10 分,我们有 TAA 作为副队长,得到 6x 2 = 12 分。

为我们的 GW21 选秀权提供信息的 GW21 整体统计数据

下面让我们从调整后的未来三周的对手难度等级(FDR)开始:

看起来伯恩利,南安普顿,谢菲尔德联队,有一个相对困难的计划,而宫,利物浦和西汉姆就在分界点,所以我们的算法不会从这些球队中做出任何选择。赛程相对轻松的球队有伯恩茅斯、埃弗顿、莱斯特、切尔西、曼城、沃特福德和布莱顿。

美国东部时间 1 月 8 日晚 9 点最新伤情更新

以下数据来自一个独立网站,该网站更新最新受伤情况的频率比 Fantasy 网站高得多:

按投资回报率和 90 分钟出场次数统计的顶级球员

根据上周一位读者的要求,我现在将公布投资回报率最高和最低的 50 名玩家,这样我们的读者就可以看到更多高投资回报率的玩家,并远离价格过高和表现不佳的玩家。

投资回报率排名前 50 的玩家

按投资回报率排名的后 50 名玩家

投资回报率排名前十的守门员

90 分钟得分前 10 的守门员

投资回报率排名前十的防御者

后卫前 10 名由 pts_per_90min

投资回报率排名前十的中场球员

90 分钟 pts _ per _ 强中场

投资回报率排名前十的前锋

90 分钟前 10 名射手

GW22 算法选择

需要提醒的是,我们的算法会考虑调整后的每支球队阵容的预算,并试图最大化 11 名主力球员的每个位置的支出,然后让你的名 ROI 值较高的替补来填补球队的剩余人员。根据当前的投资回报率得分,在接下来的三场比赛中,过滤掉任何有 AVG 对手难度(FDR≥75%)的球队,并从可用选择列表中删除受伤的球员,我们的算法选择了以下球队作为当前花费全部 1 亿美元预算的最佳球队:

看起来这是一个相当平衡的团队,银行里还留有一些钱来试验不同的配置。

就我们自己的团队而言,我们因伤被迫让凯恩退出,这很不幸,因为我们上周卖掉了拉什福德,打算留下凯恩,但现在我们不得不让拉什福德回来。所以,我们最终进行了三次转会,花费了我们 8 分,但是我们希望联盟库、威利安和拉什福德在接下来的 2-3 周内会有回报。

团队统计

查看最佳/最差防守和进攻可以有几种不同的用法——例如,如果一个最佳进攻队与一个最差防守队比赛,你可能想让你的进攻中场或前锋担任队长。此外,当你查看这些位置的算法建议时,你可能想优先考虑防守最好的球队的 DF 和 GK。

最佳 7 项防御

在连续五场零失球之后,利物浦重新夺回了 EPL 最佳防守的宝座,他们上赛季赢得了这个冠军。

最差的 7 种防御

最佳 7 项犯罪

最糟糕的 7 项罪行

累积团队投资回报统计

下面你可以看到球队,按累积玩家投资回报率排序。请注意,活跃玩家是任何已经玩了总可能游戏时间的至少 33.33% 的玩家。所以,我们把所有至少打了 570 分钟的球员算作该队现役球员。

随着更稳定的表现和价格合理的球员现在占据了前 5-8 名的位置,统计数据开始很好地趋同。令人震惊的是,莱斯特仍然保持着 11 名球员的核心,并且在整个赛季中保持了稳定的表现。别忘了他们没有参加任何欧洲赛事,所以他们轮换球员的需求更少。一些拥有昂贵球员的球队正在努力追赶并提高他们的整体投资回报率,包括热刺、阿森纳、埃弗顿和西汉姆。

最终想法:

经过长时间的休息后,我们很高兴 EPL 的行动又回来了,也很兴奋地看到这个周末瓦迪和希门尼斯休息后的腿会产生什么。我们让瓦迪担任队长,因为我们希望他在长时间休息后会充满活力,渴望进球,但拉什福德以微弱优势位居第二,因为诺维奇的防守是出了名的糟糕。

一如既往,感谢您的阅读,我们希望 2020 年对你们所有人来说是一个好的开始!享受这个周末的 EPL 行动:)

EPL 幻想 GW22 重述和 GW23 算法选择

原文:https://towardsdatascience.com/epl-fantasy-gw22-recap-and-gw23-algorithm-picks-552b909c0d?source=collection_archive---------35-----------------------

EPL 幻想博客

我们的钱球方法的幻想 EPL(队 _id: 2057677)

如果这是你第一次登陆我的幻想 EPL 博客,你可能会想看看我在本赛季开始时写的一些原始 EPL 博客(GW1-GW9),以熟悉我们的整体方法和我们随着时间的推移所做的改进。我在这个项目中的犯罪搭档是 Andrew Sproul,他和我一样对数据科学、人工智能和梦幻运动充满热情。

GW22 世界排名前 100 的选手

世界顶级球员表现相对较好,场均 67 分,而场均 57 分。有一个神经病以 111 分几乎是本周平均得分的两倍!但是总的来说,如果你的得分在 60 分以上,你仍然可以自我感觉良好。

EPL 100 强球员最佳混合团队

当我们谈论世界前 100 名球员的话题时,让我们看看谁是他们球队中最受欢迎的球员,以及 GW22 最受欢迎的球队阵容。

前 100 名最佳守门员

前 100 名中最受欢迎的捍卫者

前 100 名最佳中场球员

前 100 名中入选最多的前锋

我们使用这些数据和当前的球员价格来创建下面的球队,这是由前 100 名中最受欢迎的球员组成的:

看起来不错的团队,在关键位置上有很多尝试不同选择的余地,同时仍然保持一个坚实的球员核心。

前 100 名 Fantasy 用户选择最多的团队

现在瓦迪又回来了,我们又回到了更受欢迎的进攻阵型3–4–3 或 4–3–3

GW22 团队绩效总结和总体统计

总的来说,这是一个不错的一周,我们得到了 60 分,高于平均 57 分。作为我们的队长,我们希望从 Vardy 那里得到更多的分数,正如我在上周的博客中提到的,我认为拉什福德是队长的第二选择,所以我们希望我们选择他:)对 Jimenez 来说又是一个空虚的一周,但至少我们上周的两次转会——拉什福德和威利安得到了回报,所以我们对此感到高兴。

GW22 整体统计数据为我们的 GW23 选秀权提供信息

下面让我们从调整后的未来三周的对手难度等级(FDR)开始:

看起来伯恩利,南安普顿,谢菲尔德联队,狼队和曼联队有一个相对困难的计划,所以我们的算法不会从这些球队中做出任何选择。赛程相对轻松的球队有伯恩茅斯、阿斯顿维拉、埃弗顿、纽卡斯尔、莱斯特、利物浦、沃特福德和布莱顿。

美国东部时间 1 月 16 日晚 11 点最新伤情更新

以下数据来自一个独立网站,该网站更新最新受伤情况的频率比 Fantasy 网站高得多:

按投资回报率和 90 分钟出场次数统计的顶级球员

根据上周一位读者的要求,我现在将公布投资回报率最高和最低的 50 名玩家,这样我们的读者就可以看到更多高投资回报率的玩家,并远离价格过高和表现不佳的玩家。

投资回报率排名前 50 的玩家

按投资回报率排名的后 50 名玩家

投资回报率排名前十的守门员

90 分钟内排名前 10 的守门员

投资回报率排名前十的防守队员

后卫前 10 名 pts_per_90min

投资回报率排名前十的中场球员

90 分钟 pts _ per _ 强中场

投资回报率排名前十的前锋

90 分钟前 10 名射手

GW23 算法选择

我们的算法接受调整后的每支队伍的预算并尝试最大化 11 名主力队员的每个位置的花费,然后让你的替补队员获得良好的 ROI 值来填补其余队员。根据当前的 ROI 分数,在接下来的三场比赛中过滤掉任何有 AVG 对手难度(FDR≥75%)的球队,并从可用选择列表中删除受伤的球员,我们的算法选择了以下球队作为花费全部 1 亿美元预算的最佳球队:

看起来这是一个相当平衡的团队,银行里还留有一些钱来试验不同的配置。

就我们自己的球队而言,我们决定不做任何替补,因为我们想为下周保留一些免费的替补,并试图为双赛周争取更多的利物浦球员

团队统计

看看最佳/最差防守和进攻可以有几种不同的用法——例如,如果一个最佳进攻队与一个最差防守队比赛,你可能想让你的进攻中场或前锋担任队长。此外,当你查看这些位置的算法建议时,你可能想优先考虑防守最好的球队的 DF 和 GK。

最佳 7 项防御

利物浦现在已经连续六场零失球了!真正开始占据守势。

最差的 7 种防御

最佳 7 项犯罪

最糟糕的 7 项罪行

累积团队投资回报统计

下面你可以看到球队,按累积玩家投资回报率排序。请注意,活跃玩家是任何已经玩了总可能游戏时间的至少 33.33% 的玩家。所以,我们把所有至少打了 597 分钟的球员都算作该队现役球员。

随着价格合理的球员和更稳定的表现现在占据了前 5-8 名的位置,统计数据开始很好地趋同。一些拥有高价球员的球队正在努力赶上并提高他们的整体投资回报率马刺、阿森纳、埃弗顿和西汉姆

最终想法:

老实说,我们对我们的球队不抱太大希望,因为拉什福德受伤了,曼联也在对阵利物浦。我们希望从希门尼斯身上得到一些东西,因为我们计划在下周卖掉他,这样我们就可以为双 GW 得到另一名高质量的利物浦球员!

一如既往,感谢您的阅读,我们希望 2020 年对你们所有人来说是一个好的开始!享受这个周末的 EPL 行动:)

EPL 幻想 GW23 重述和 GW24 算法选择

原文:https://towardsdatascience.com/epl-fantasy-gw23-recap-and-gw24-algorithm-picks-74c9ddee628a?source=collection_archive---------29-----------------------

EPL 幻想博客

我们的钱球方法的幻想 EPL(队 _id: 2057677)

如果这是你第一次登陆我的幻想 EPL 博客,你可能会想看看我在本赛季开始时写的一些原始 EPL 博客(GW1-GW9),以熟悉我们的整体方法和我们随着时间的推移所做的改进。我在这个项目中的犯罪搭档是 Andrew Sproul,他和我一样对数据科学、人工智能和梦幻运动充满热情。

GW23 世界排名前 100 的选手

对于世界上许多顶级玩家来说,这是艰难的一周,他们中的许多人得分在30-40 分范围内!总的来说,他们仍然平均得到 58 分,相比之下,GW 的平均得分是 44 分。所以,如果你的得分在 50 分以上,你会对自己感觉很好:)

EPL 100 强球员最佳混合团队

当我们谈论世界前 100 名球员的话题时,让我们看看谁是他们球队中最受欢迎的球员,以及 GW23 最受欢迎的球队阵容。

前 100 名最佳守门员

前 100 名中最受欢迎的捍卫者

前 100 名最佳中场球员

前 100 名中入选最多的前锋

我们使用这些数据和当前的球员价格来创建下面的球队,这是由前 100 名中最受欢迎的球员组成的:

看起来不错的团队,在关键位置上有很多尝试不同选择的余地,同时仍然保持一个坚实的球员核心。

前 100 名 Fantasy 用户选择最多的团队

现在瓦迪又回来了,我们回到了更受欢迎的进攻阵型3–4–3 作为首选

GW23 团队绩效总结和总体统计

总的来说,这是一个非常好的一周,我们得到了 68 分,远远高于平均 44 分。我们在上周博客的“最终想法”部分对希门尼斯的希望和梦想成真了,我们的投资最终获得了丰厚的回报。我们还有点“幸运”,拉什福德没有上场,所以我们可以让格里利什作为我们的第一个替补,给 T21 10 分。我们的队长选择不是最好的,我们有点不走运,德·布鲁恩漂亮的任意球击中门柱,所以我们只从他那里得到了 2x2 = 4pts 😦最后,我们还从加扎尼加那里得到了一些不错的分数,自从洛里斯受伤后的第一天起,我们就一直在那里,所以,总的来说,我们很高兴!

GW23 整体统计数据为我们的 GW24 选秀权提供信息

下面让我们从调整后的未来三周的对手难度等级(FDR)开始:

看起来西汉姆,南安普顿,诺维奇,狼队和切尔西有一个相对困难的计划,所以我们的算法不会从这些球队中做出任何选择。赛程相对轻松的球队有伯恩茅斯、皇宫、维拉、埃弗顿、纽卡、利物浦、沃特福德、布莱顿。

美国东部时间 1 月 19 日晚 10 点最新伤情更新

以下数据来自一个独立网站,该网站更新最新受伤情况的频率比 Fantasy 网站高得多:

按投资回报率和 90 分钟出场次数统计的顶级球员

根据上周一位读者的要求,我现在将公布投资回报率最高和最低的 50 名玩家,这样我们的读者就可以看到更多高投资回报率的玩家,并远离价格过高和表现不佳的玩家。

投资回报率排名前 50 的玩家

按投资回报率排名的后 50 名玩家

投资回报率排名前十的守门员

90 分钟 pts _ per _ 强门将

投资回报率排名前十的防守球员

pts _ per _ 90min 排名前 10 的防守队员

投资回报率排名前十的中场球员

90 分钟 pts _ per _ 强中场

投资回报率排名前十的前锋

90 分钟前 10 名射手

GW24 算法选择

我们的算法接受每队阵型的调整预算,并试图最大化主要 11 名球员的每个位置的支出,然后让你的名具有良好 ROI 值的替补来填补团队的其余成员。根据当前的投资回报率得分,在接下来的三场比赛中过滤掉任何有 AVG 对手难度(FDR≥75%)的球队,并从可用选择列表中删除受伤球员,我们的算法选择了以下球队作为花费全部 1 亿美元预算的最佳球队:

就我们自己的球队而言,我们已经节省了 2 次免费转会,所以我们可以在双赛周得到更多的利物浦球员。因此,我们最终进行了以下三次转移:

威利安→萨拉赫,赛斯→坦甘加,拉什福德→格林伍德

我们知道如果克洛普决定在中场做一些轮换是有风险的,但是由于利物浦的两场比赛都是客场,并且中间有 4 天的休息时间,我们希望他能在两场比赛中首发出场。我们选择让萨拉赫担任队长,因为在过去的几场比赛中,他似乎比马内状态更好。我们也考虑过 TAA,但是我们认为很多人会和他一起去,所以我们希望在积分落后的情况下有所区别。

团队统计

查看最佳/最差防守和进攻可以有几种不同的用法——例如,如果一个最佳进攻队与一个最差防守队比赛,你可能想让你的进攻中场或前锋担任队长。此外,当你查看这些位置的算法建议时,你可能想优先考虑防守最好的球队的 DF 和 GK。

最佳 7 项防御

**利物浦已经连续七场零失球了!**说够了……:)

最差的 7 种防御

最佳 7 项犯罪

最糟糕的 7 项罪行

累积团队投资回报统计

下面你可以看到球队,按累积玩家投资回报率排序。请注意,活跃玩家是指任何至少玩了总可能游戏时间的 33.33% 的玩家。因此,我们会把所有至少打了 620 分钟的球员算作该队现役球员。

随着价格合理的球员和表现更稳定的球员现在占据了前 5-8 名的位置,统计数据开始很好地趋同。一些拥有昂贵球员的球队正在努力追赶并提高他们的整体投资回报率,包括热刺、阿森纳、埃弗顿和西汉姆。

最终想法:

首先,不要忘记这款 GW24 将于本周二上市!本周的主要赛事当然是利物浦的双人赛,很多人可能会玩他们的三重队长筹码。我们也在考虑对萨拉赫这样做,但是考虑到这两场比赛都是在 T21 进行的,而且狼队和西汉姆联都不在防守最差的 7 支球队之列,我们没有足够的信心能进足够多的球。我们仍然有可能在最后一分钟让萨拉赫成为三队长,但现在我们只进行常规比赛。除此之外我们希望热刺对诺维奇不失球,这样我们就可以在加扎尼加和坦甘加身上下些赌注。

祝大家本周好运,一如既往——感谢您的阅读!

EPL 幻想 GW24 重述和 GW25 算法选择

原文:https://towardsdatascience.com/epl-fantasy-gw24-recap-and-gw25-algorithm-picks-b23d87b86d61?source=collection_archive---------33-----------------------

EPL 幻想博客

我们的钱球方法的幻想 EPL(队 _id: 2057677)

如果这是你第一次登陆我的幻想 EPL 博客,你可能会想看看我在本赛季开始时写的一些原始 EPL 博客(GW1-GW9),以熟悉我们的整体方法和我们随着时间的推移所做的改进。我在这个项目中的犯罪搭档是 Andrew Sproul,他和我一样对数据科学、人工智能和梦幻运动充满热情。

GW24 世界排名前 100 的选手

自从我们开始追踪这个统计数据以来,这是我们见过的世界排名前 100 的玩家在最强的一周平均 87 分!似乎这是的一周——你要么选择萨拉赫担任队长或三重队长,要么就被甩在身后… 正如你所看到的,前 100 名中没有选择萨拉赫担任队长的少数球员最终以 40-50 分的总分落后于其他人。

EPL 100 强球员最佳混合团队

当我们谈论世界前 100 名球员的话题时,让我们看看谁是他们球队中最受欢迎的球员,以及 GW24 最受欢迎的球队阵容。

前 100 名最佳守门员

前 100 名中最受欢迎的捍卫者

前 100 名最佳中场球员

前 100 名中入选最多的前锋

我们使用这些数据和当前的球员价格来创建下面的球队,这是由前 100 名中最受欢迎的球员组成的:

看起来不错的团队,在关键位置上有很多尝试不同选择的余地,同时仍然保持一个坚实的球员核心。

前 100 名 Fantasy 用户选择最多的团队

这一统计数据正在回归正常,大多数顶级球员选择 3 名防守球员,并试图利用 3-4-3 或 3-5-2 阵型的进攻型中场和前锋。

GW24 团队绩效总结和总体统计

我们对这一周有着复杂的感情,因为我们得到了 67 分,远远高于平均水平 53 分,所以乍一看我们应该感到高兴。但是当你在下面看我们的球队时,你会发现如果不是选择萨拉赫作为队长,救了我们,我们对许多其他关键球员一无所知,包括我们的两个守门员都没有上场,给了我们零分。我们所有的联赛都有绿箭,所以我想总的来说我们应该很开心。

GW24 整体统计数据为我们的 GW25 选秀权提供信息

下面让我们从调整后的未来三周的对手难度等级(FDR)开始:

看起来西汉姆,莱斯特,诺维奇,热刺和切尔西有一个相对困难的计划,所以我们的算法不会从这些球队中做出任何选择。赛程相对轻松的球队有伯恩茅斯、阿斯顿维拉、阿森纳、谢菲尔德联队、纽卡、利物浦、伯恩利和布莱顿。

美国东部时间 1 月 31 日晚 11 点最新伤情更新

以下数据来自一个独立网站,该网站更新最新受伤情况的频率比 Fantasy 网站高得多:

按投资回报率和 90 分钟出场次数统计的顶级球员

根据上周一位读者的要求,我现在将公布投资回报率最高和最低的 50 名玩家,这样我们的读者就可以看到更多高投资回报率的玩家,并远离价格过高和表现不佳的玩家。

按投资回报率排名的后 50 名玩家

投资回报率排名前十的守门员

90 分钟 pts _ per _ 强门将

投资回报率排名前十的防守球员

pts _ per _ 90min 排名前 10 的防守队员

投资回报率排名前十的中场球员

90 分钟 pts _ per _ 强中场

投资回报率排名前十的前锋

90 分钟前 10 名射手

GW25 算法选择

我们的算法接受每队阵型的调整预算,并试图最大化主要 11 名球员的每个位置的支出,然后让你的名具有良好 ROI 值的替补来填补团队的其余成员。根据当前的投资回报率得分,在接下来的三场比赛中过滤掉任何有 AVG 对手难度(FDR≥75%)的球队,并从可用选择列表中删除受伤球员,我们的算法选择了以下球队作为花费全部 1 亿美元预算的最佳球队:

就我们自己的车队而言,我们决定使用我们的通配符,因为 Hugo Lorris 现在回来了,所以我们剩下零个活跃的 GK,并且由于 Mane 的受伤和莱斯特即将到来的困难赛程,我们想要进行相当多的轮换,所以我们决定——为什么不使用我们的通配符!?我们真的很想去一个有奥巴、菲尔米诺和阿圭罗的球队,但那太贵了,所以我们不得不牺牲他们中的一个,并决定用阿圭罗和菲尔米诺,因为他们一直处于非常好的状态**,他们面对较弱的对手(历史上阿圭罗总是在很大程度上惩罚马刺)。我们几乎想让他成为队长,但是我们害怕莫里诺的极端防守风格,所以我们选择了菲尔米诺,因为利物浦主场作战,南安普顿的防守很弱。**

团队统计

查看最佳/最差防守和进攻可以有几种不同的用法——例如,如果一个最佳进攻队与一个最差防守队比赛,你可能想让你的进攻中场或前锋担任队长。此外,当你查看这些位置的算法建议时,你可能想优先考虑防守最好的球队的 DF 和 GK。

最佳 7 项防御

最差的 7 种防御

最佳 7 项犯罪

最糟糕的 7 项罪行

累积团队投资回报统计

下面你可以看到球队,按累积玩家投资回报率排序。请注意,活跃玩家是任何已经玩了总可能游戏时间的至少 33.33% 的玩家。所以,我们把所有至少打了 650 分钟的球员算作该队现役球员。

随着价格合理的球员中表现更稳定的球员现在占据了前 5-8 名的位置,统计数据开始很好地趋同。一些拥有昂贵球员的球队正在努力追赶并提高他们的整体投资回报率,包括阿森纳、西汉姆和埃弗顿。

最终想法:

在过去的几个赛季中,使用通配符对我们来说并不太好,所以我们希望这一次情况会有所不同,特别是因为我们是被迫使用通配符的。我们本周最大的希望是,在显而易见的选择——萨拉赫或阿奎罗——中,我们选择了正确的队长。这有点冒险和奢侈,比如选择娶一个红发女人,但有时这种疯狂的风险从长远来看会有丰厚的回报,所以让我们看看明天会带来什么:)

祝大家本周好运,一如既往——感谢您的阅读!

EPL 幻想 GW29 重述和 GW30 算法选择

原文:https://towardsdatascience.com/epl-fantasy-gw29-recap-and-gw30-algorithm-picks-3a94a695510d?source=collection_archive---------27-----------------------

我们的钱球方法的幻想 EPL(队 _id: 2057677)

如果这是你第一次登陆我的幻想 EPL 博客,你可能会想看看我在本赛季开始时写的一些原始 EPL 博客(GW1-GW9),以熟悉我们的整体方法和我们随着时间的推移所做的改进。我在这个项目中的犯罪搭档是 Andrew Sproul,他和我一样对数据科学、人工智能和梦幻运动充满热情。

但是在进入统计和建议之前,我们只想送上我们最温暖的祝福给世界各地的每一个人鉴于最近新冠肺炎的更新。我们希望你们都平安无事,我们积极的想法和祈祷会传达给所有的生命为了身体健康和精神力量。在这个充满不确定性的困难时期,我们真的很感谢你,我们的读者,花宝贵的时间阅读我们的博客!

GW29 世界排名前 100 的选手

上周世界排名前 10 的选手表现相当不错,平均 65 分,一名选手以 104 分打破 100 分大关。但是,即使在顶尖高手中,我们也看到了相当数量的 40-50 岁玩家,他们的得分最低,只有 38 分。因此,如果你的得分高于 55-60 分,你会对自己感觉很好。

EPL 100 强球员最佳混合团队

当我们谈论世界前 100 名球员的话题时,让我们看看谁是他们球队中最受欢迎的球员,以及 GW24 最受欢迎的球队阵容。

前 100 名最佳守门员

前 100 名中最受欢迎的捍卫者

前 100 名最佳中场球员

前 100 名中入选最多的前锋

我们使用这些数据和当前的球员价格来创建下面的球队,这是由前 100 名中最受欢迎的球员组成的:

看起来不错的团队,在关键位置上有很多尝试不同选择的余地,同时仍然保持一个坚实的球员核心。

前 100 名 Fantasy 用户选择最多的团队

这一统计数据正在回归正常,大多数顶级球员都试图利用 3-4-3 或 4-3-3 阵型的进攻型中场和前锋。

GW29 团队绩效总结和总体统计

这是我们第一周没有超过平均分数。我们接近了49 分对游戏周平均 51 分。老实说,在过去的几周里,我们错过了做出改变的机会,没能观看很多比赛,正如你所知,我们没有时间发布我们的定期博客更新。我们在挑选队长方面的厄运还在继续,因为我们选择了 TAA,期待不失球和进球/助攻,而不是萨拉赫或瓦迪这样显而易见的选择,我们因为试图变得花哨而受到了惩罚。否则,我们会超过本周的平均分。

GW229 整体统计数据为我们的 GW30 选秀权提供信息

下面让我们从调整后的未来三周的对手难度等级(FDR)开始:

看起来曼城和利物浦都超过了 FDR 的分数,所以对于我们的算法建议来说,这将是一个奇怪的一周。其他赛程艰难的球队好像是布莱顿、埃弗顿、西汉姆。因此,我们的算法不会从这些团队中做出任何选择。赛程相对轻松的球队有狼队、阿森纳、纽卡斯尔、莱斯特、南安普顿、切尔西和曼联。

美国东部时间 1 月 31 日晚 11 点最新伤情更新

以下数据来自一个独立网站,该网站更新最新受伤情况的频率比 Fantasy 网站高得多:

按投资回报率和 90 分钟出场次数统计的顶级球员

根据上周一位读者的要求,我现在将公布投资回报率最高和最低的 50 名玩家,这样我们的读者就可以看到更多高投资回报率的玩家,并远离价格过高和表现不佳的玩家。

按投资回报率排名的后 50 名玩家

投资回报率排名前十的守门员

90 分钟内得分排名前 10 的守门员

投资回报率排名前 10 的防御者

90 分钟内得分最高的 10 名防守队员

投资回报率排名前十的中场球员

90 分钟 pts _ per _ 强中场

投资回报率排名前十的前锋

射手榜前 10 名由 pts_per_90min

GW29 算法选择

我们的算法接受调整后的每队阵型的预算,并试图最大化主要 11 名球员的每个位置的支出,然后让你的个具有良好 ROI 值的替补来填补团队的其余成员。根据当前的投资回报率得分,在接下来的三场比赛中过滤掉任何有 AVG 对手难度(FDR≥75%)的球队,并从可用选择列表中删除受伤的球员,我们的算法选择了以下球队作为花费全部 1 亿美元预算的最佳球队:

就我们自己的团队而言,我们决定淘汰门迪,因为我们几周前买下了他,而他被证明是一笔糟糕的投资,所以我们以便宜的价格从纽卡得到了拉塞尔斯,试图在接下来的几周为更多的轮换腾出预算,因为我们在等待被取消的比赛等的更新。我们的船长不再做实验,瓦迪·梅恩和萨拉赫将成为副船长。

团队统计

查看最佳/最差防守和进攻可以有几种不同的用法——例如,如果一个最佳进攻队与一个最差防守队比赛,你可能想让你的进攻中场或前锋担任队长。此外,当你查看这些位置的算法建议时,你可能想优先考虑防守最好的球队的 DF 和 GK。

最佳 7 项防御

最差的 7 种防御

最佳 7 项犯罪

最糟糕的 7 项罪行

累积团队投资回报统计

下面你可以看到球队,按累积玩家投资回报率排序。请注意,活跃玩家是指已经玩了总可能游戏时间的至少 33.33% 的任何玩家。所以,我们把所有至少打了 787 分钟的球员都算作该队现役球员。

随着我们接近本赛季的最后阶段,球队的统计数据开始很好地趋同,因为价格合理的球员中表现更稳定的球员现在占据了前 5-8 名的位置。最后,曼联和切尔西也爬上了那里。一些拥有太多昂贵的表现不佳球员的球队正在努力追赶并提高他们的整体投资回报率,这些球队是阿森纳、热刺和埃弗顿。

最终想法:

老实说,面对所有新冠肺炎的新闻和担忧,我们只是希望和祈祷每个人都平安,包括教练、球员和医务人员。让我们希望情况很快开始好转,让我们希望赛季也能在正常情况下继续,我们可以继续享受一些令人兴奋的 EPL 行动。祝愿我们所有的读者和世界上的其他人保持强壮和健康!

祝大家本周好运,一如既往——感谢您的阅读!

EPL 幻想 GW3 重述和 GW4 算法选择

原文:https://towardsdatascience.com/epl-fantasy-gw3-recap-and-gw4-algo-picks-594a4882c22e?source=collection_archive---------54-----------------------

我们的金钱球方法到幻想的 EPL(队 _id: 2122122)

如果这是你第一次登陆我们的幻想 EPL 博客,你可能想看看我的媒体档案中的一些我们最初的 EPL 博客,以熟悉这个项目是如何开始的,以及随着时间的推移我们所做的改进。

GW3 前 100 名 FPL 团队统计数据

即使对于世界排名前 100 位的玩家来说,看起来也是一个艰难的 GW,AVG 只有 60 分,一些顶级玩家的得分低于平均水平,只有 40 分。

前 100 名最佳守门员

前 100 名中最受欢迎的捍卫者

前 100 名最佳中场球员

前 100 名中入选最多的前锋

我们使用这些数据创建了下面的团队,它是由前 100 名中最受欢迎的球员组成的:

前 100 名 Fantasy 用户选择最多的团队

这些数据很有意义,因为大多数顶级球员都试图利用 3-4-3 阵型的进攻型中场和前锋。

GW3 团队绩效总结和总体统计

我们所有团队的得分都略高于平均水平,得分最高的团队得到了51 分。每周,我们都会发布前 2 名表演团队的照片。不幸的是,我们没有再次选出最好的队长,这已经连续伤害了我们两周。如果 Son 没有两次击中门柱并且没有在中场休息时被替换,我们可以说完全相反,所以让我们不要忘记,不管一个人的算法可能有多好,运气在一周接一周的表现中仍然具有巨大的重要性。这毕竟是让游戏保持有趣和刺激的原因。

我们还参加了 FPL 的 FanTeam 版本,在那里我们有本周表现最好的团队。再说一次,这不是最好的队长选择,特别是考虑到在第一队我们卖掉了瓦迪换来了 KDB ,这最终让我们损失了一百万积分。所以,我要说我们上周的运气总体来说很差。

为我们的 GW4 选择提供有用的统计数据

由于我们今年在算法中加入了很多新的统计数据,随着时间的推移,这个博客将会有更多的统计数据和图表,更少的文字。让我们从下面三个比赛周的比赛难度等级(FDR)开始:

看起来西汉姆联队、阿森纳队、维拉队、曼联队和谢菲尔德联队【T21 队】即将迎来一些艰苦的比赛,所以我们的算法可能不会从这些球队中挑选球员。在接下来的三周里,、丽芙、CRY、MCI 和雷的日程安排似乎更加轻松。

博彩赔率

我们会尽量把 队中有超过 50 %胜算的 的玩家,比如***【WOL】、车、ARS、LIV、雷、MCI、EVE*** 。我们应该尽量不要有太多来自 AVL、李、WHU、富尔、BHA、CRY、WBA 或者 BUR 的防守球员。

较高概率抽 的队伍,尤其是当比赛是 结合高赔率为 2.5 以下的 时,可能会对选择 防守队员 有利,因为如果比赛以 0:0 结束,那将会产生大量的加分。结合 下方的 下/上图,我们可以识别出以下 概率较高的游戏至少有一场不失球——NEW-BUR、WOL-FUL、ARS-SHU、SOU-WBA。

反过来,我们可能希望从 赔率超过 2.5 的游戏中有更多的 攻击玩家,如李-MCI、-LIV、-CRY 和雷-WHU 。同样,上周的赔率表现得相当好,因为大多数游戏预测有超过 2.5 个目标!****

裁判统计

从下面的统计数据来看,在比赛中出现点球的几率更高:伊夫-BHA,李-麦基,雷-WHU,门-托,所以我们建议为这些球队中的一些球队配备点球手。看起来,像游戏 EVE-BHA,雷-WHU,ARS-SHU 有裁判喜欢给很多卡,所以预计会失去一些黄牌,但希望没有红色…

团队惩罚统计

除了裁判判罚的概率之外,让我们也看看在过去的 5 个赛季中哪些球队被判罚最多,看看我们在哪里得到了最高的综合概率。从下面的图表中我们可以得出结论,雷、王文杰、门和伊芙最有可能得到一个点球。

定位球运动员

为了帮助你选择定位球运动员,请看下面的列表,它或多或少是最新的,有几个可疑的预测:

预计首发阵容

在我们运行最终的团队选择器之前,让我们考虑一下每个团队的预计首发 11 人。

请注意右边可疑球员的名字,以及下面最新的伤病消息:

预测模型(球员统计)

现在是今年改进算法的皇冠上的宝石——预测球员统计数据的时候了。在我们将所有的 FDR、赌注系数、裁判首发、预计阵容和伤病分层后,有两个主要指标我们在为接下来的 n 场比赛周团队选择调整我们的团队优化器时会考虑到— 预测总积分和期望值(ROI)。 下面是每个指标的统计数据,也是按职位细分的。

预计总积分—前 25 名玩家

预计预期价值(ROI) —前 25 名参与者

预测积分——顶级守门员

投射点数—顶级防守者

预测得分——顶级中场

预测分数——顶级前锋

正如你所看到的,每个位置都有大量选项可供我们选择,因此我们将把上面的许多统计数据插入 Python 中的 优化函数,该函数将 输出具有最高预期总积分 的团队,给定我们的预算约束和进入我们决策过程的其他指标。在团队选择器代码生效之前应用的一些初步过滤器包括:

  1. 排除受伤或停赛球员
  2. 将球员排除在 FDR 高的队伍之外
  3. 排除在 GW1 中没有固定比赛的队伍中的球员
  4. 同一团队不能有超过 3 名玩家
  5. 总共必须有 15 名球员(GK=2,DF=5,MD=5,ST=3)

优化最常用信息的预算

上周前 100 名选手最常用的阵型是 3-4-3,所以我们将展示这种阵型的最佳阵容。正如你在下面看到的,模型首先查看参数,告诉它是否应该向 15 名球员的全队优化,或者向有 11 名关键球员和 4 名廉价替补 的特定阵型优化。对于填充符,它首先查看*,并使用该 来决定每个位置 要获得多少个填充符。然后,该模型从我们的初始预算中减去花费在 4 个填充者上的总金额,并将剩余的预算花费在关键的 11 个玩家上, ,给定优化函数和模型约束 。***

****示例 1:向最大期望点数优化****

示例 2:向最大期望值(ROI)优化

我们使用优化算法的输出和每个位置推荐的前 10 名球员中的一些人来形成以下混合团队:

我们团队为 GW4

**我们将一直使用上周的顶级得分团队,并尝试最多进行 1-2 次转会。所以,我们用儿子和沃德-普鲁斯换来了 KDB 和克里奇,因为我们想得到更多的主罚点球的球员。我们觉得萨拉赫很快就要爆发了,所以我们让他担任队长,希望最终打破可怜队长的诅咒。**

结论

我们正努力保持纪律性,在国际比赛日之前不使用我们的通配符。我们球队的主要弱点是门将,因为富勒姆的防守太糟糕了,我们真的想摆脱阿雷奥拉,并得到另一个 4.5 米的门将,预计在赛季中会有更多的不失球。因此,在下一个 GW 之前,我们可能会在我们的几个队伍中使用通配符。感谢您一如既往的阅读,祝您本周好运!

EPL 幻想 GW4 回顾和 GW5 算法选择

原文:https://towardsdatascience.com/epl-fantasy-gw4-recap-and-gw5-algo-picks-19801f3f6e63?source=collection_archive---------59-----------------------

我们的金钱球方法到幻想的 EPL(队 _id: 2122122)

GW4 的顶级团队

如果这是你第一次登陆我们的幻想 EPL 博客,你可能想看看我的媒体档案中的一些我们最初的 EPL 博客,以熟悉这个项目是如何开始的,以及随着时间的推移我们所做的改进。

什么是新的?

我们利用空闲的周末,为我们的算法添加了另一个新功能— 队长推荐逻辑。该方法采用了即将到来的比赛的预测得分,球员罚点球、角球或任意球的概率,球员在过去 4 个赛季中的空中威胁系数,他们的球队打进 2 个或更多进球的可能性,并以标准化的方式将所有这些融入到最终队长选择系数。然后,根据玩家的下一个对手调整的 FDR 和本赛季防守强度的标准化得分,该系数被减去对手抗性得分。熊猫 DF 看起来像下面的例子:

基于这个公式,这里列出了这个 GW 的 15 个推荐队长。那里有很多好的选择,所以无论如何都不是一个容易的选择。如果你想稳扎稳打,KDB、凯恩、费尔南德斯、桑恩、萨拉赫和瓦迪似乎是显而易见的选择,而克里斯·伍德有趣地成为第一选择,所以如果你有他,并且你觉得有足够的冒险精神让他成为队长,这可能是一个不错的差异化打法。

GW3 前 100 名 FPL 团队统计数据

鉴于上周比赛的大量进球,世界排名前 100 位的球员度过了非常精彩的一周,平均得分> 100,这在历史上很少发生,排名第一的球员获得了144 分!!!

前 100 名最佳守门员

前 100 名中最受欢迎的捍卫者

前 100 名最佳中场球员

前 100 名中入选最多的前锋

我们使用这些数据创建了下面的团队,它是由前 100 名中最受欢迎的球员组成的:

前 100 名 Fantasy 用户选择最多的团队

这些数据很有意义,因为大多数顶级球员都试图利用 3-4-3 阵型中的进攻型中场和前锋。

GW4 团队绩效总结和总体统计

我们所有团队的得分都高于平均水平,得分最高的团队得到了 76 分。不幸的是,我们没有选出我们顶级球队的最佳队长,沃纳的表现低于预期。如果我们选择了显而易见的选择——Salah-我们可能会得到 87 分

我们还参加了 FPL 的 FanTeam 版本,幸运的是,我们由 Salah 担任队长,这得到了回报,给了我们两个团队相当稳定的分数。

为我们的 GW5 选择提供有用的统计数据

由于我们今年在算法中加入了很多新的统计数据,随着时间的推移,这个博客将会有更多的统计数据和图表,更少的文本 。让我们从下面三个比赛周的比赛难度等级(FDR)开始:

看起来西汉姆阿森纳,南安普顿,曼联和利兹都有一些艰难的比赛即将到来,所以我们的算法可能不会从这些球队中挑选球员。在接下来的三周里,CHE,TOT,CRY,MCI 和 WOL 的日程似乎更轻松。

博彩赔率

我们会尽量把 队伍中有超过 50 %胜率的 队员,比如 TOT、 CHE、LIV、雷、MCI、MUN 。我们应该尽量不要有太多来自 ARS、SOU、WHU、FUL、NEW、EVE 或 AVL 的防守球员。

拥有 的队伍以更高的概率抽到了 ,特别是当比赛是 结合高赔率为 2.5 以下的 时,可能会对选择防守队员有利,因为如果比赛以 0:0 结束,那将会产生大量的加分。结合 下方的 下/上图,我们可以识别出以下 概率较高的游戏至少有一场不失球——WBA-BUR、CRY-BHA、SHU-FUL。

相反,我们可能希望从 赔率超过 2.5 的游戏中有更多的 攻击玩家 ,比如 MCI-ARS、EVE-LIV、CHE-SOU、雷-AVL 和 TOT-WHU 。同样,上周的赔率表现得相当好,因为大多数游戏预测有超过 2.5 个目标!

裁判统计

这些将在本周晚些时候更新,因为裁判的分配还没有宣布。

团队惩罚统计

除了裁判判罚的概率之外,让我们也看看在过去的 5 个赛季中哪些球队被判罚最多,看看我们在哪里得到了最高的综合概率。从下图我们可以得出结论,雷、CRY、MCI、MUN 和 TOT 最有可能获得点球。

定位球运动员

为了帮助你选择定位球运动员,请看下面的列表,它或多或少是最新的,有几个可疑的预测:

预计首发阵容

在我们运行最终的团队选择器之前,让我们考虑一下每个团队的预计首发 11 人。

请注意右边可疑球员的名字,以及下面最新的伤病消息:

预测模型(球员统计)

现在是今年改进算法的皇冠上的宝石——预测球员统计数据的时候了。在我们将所有的 FDR、赌注系数、裁判首发、预计阵容和伤病分层后,有两个主要指标我们在为接下来的 n 场比赛周团队选择调整我们的团队优化器时会考虑到— 预测总积分和期望值(ROI)。 下面是每个指标的统计数据,也是按职位细分的。**

预计总积分—前 25 名玩家

预计预期价值(ROI) —前 25 名参与者

预测积分——顶级守门员

投射点数—顶级防守者

预测得分——顶级中场

预测分数——顶级前锋

正如你所看到的,每个位置都有大量选项可供我们选择,因此我们将把上面的许多统计数据插入 Python 中的 优化函数,该函数将 输出具有最高预期总积分 的团队,给定我们的预算约束和进入我们决策过程的其他指标。在团队选择器代码生效之前应用的一些初步过滤器包括:

  1. 排除受伤或停赛球员
  2. 将球员排除在 FDR 高的队伍之外
  3. 排除在 GW1 中没有固定比赛的队伍中的球员
  4. 同一团队不能有超过 3 名玩家
  5. 总共必须有 15 名球员(GK=2,DF=5,MD=5,ST=3)

优化最常用信息的预算

上周前 100 名选手最常用的阵型是 3-4-3,所以我们将展示这种阵型的最佳阵容。正如你在下面看到的,模型首先查看参数,告诉它是否应该向 15 名球员的全队优化,或者向有 11 名关键球员和 4 名廉价替补 的特定阵型优化。对于填充符,它首先查看*,并使用该 来决定每个位置 要获得多少个填充符。然后,该模型从我们的初始预算中减去花费在 4 个填充者上的总金额,并将剩余的预算花费在关键的 11 个玩家上, ,给定优化函数和模型约束 。***

****示例 1:向最大期望点数优化****

****

示例 2:向最大期望值(ROI)优化

****

我们的 GW5 团队

**我们将一直使用上周的顶级得分团队,并尝试最多进行 1-2 次转会。然而,本周**我们决定使用我们的通配符**,因为国际比赛日以及许多球员受伤或随新冠肺炎回来的可能性。我们也想把预算从昂贵的防守球员身上转移到便宜的防守球员和 T4 昂贵的进攻球员身上,考虑到我们这个赛季看到的绝对雪崩式的进球和极少的零失球。这就是我们球队目前的情况,但我们会密切关注新闻,可能会根据周四 Fri 的伤病更新做出很多最后一分钟的轮换。**

结论

按照本赛季的发展方式,我们建议放弃昂贵的防守球员,尝试只拥有三名中档防守球员,并且在中场和进攻中积累大量筹码,因为本赛季到目前为止一直有大量进球,并且没有迹象表明事情可能会很快放缓。感谢您一如既往的阅读,祝您本周好运!****

EPL 幻想 GW5 重述和 GW6 算法选择

原文:https://towardsdatascience.com/epl-fantasy-gw5-recap-and-gw6-algo-picks-53f0daca662b?source=collection_archive---------39-----------------------

我们的金钱球方法到幻想的 EPL(队 _id: 2122122)

GW5 的顶级团队

如果这是你第一次登陆我们的幻想 EPL 博客,你可能想看看我的媒体档案中的一些我们最初的 EPL 博客,以熟悉这个项目是如何开始的,以及随着时间的推移我们所做的改进。

GW5 前 100 名 FPL 团队统计数据

排名前 100 位的球员又度过了坚实的一周,平均得分> 84,其中,排名第一的球员得分大败 136 分!!!

前 100 名最佳守门员

前 100 名中最受欢迎的捍卫者

前 100 名最佳中场球员

前 100 名中入选最多的前锋

我们使用这些数据创建了下面的团队,它是由前 100 名中最受欢迎的球员组成的:

前 100 名 Fantasy 用户选择最多的团队

这些数据很有意义,因为大多数顶级球员都试图利用 3–4–3 f阵型的进攻型中场和前锋。

GW5 团队绩效总结和总体统计

我们所有团队的得分都高于平均水平,得分最高的团队得分为 78 分。最后选对了队长,帮了大忙。唯一的负面消息是瓦迪受伤后坐在板凳上,但总体来说我们对自己的表现很满意。

我们还参加了 FPL 的 FanTeam 版本,幸运的是,我们也遇到了优秀的队长,这得到了回报,让我们的两个团队获得了相当不错的分数。有了达洛和维斯特加德,我们在板凳上留下了很多分数,所以这么早让布鲁斯特上场可能是个错误。

为我们的 GW6 选择提供有用的统计数据

由于我们今年在算法中加入了很多新的统计数据,随着时间的推移,这个博客将会有更多的统计数据和图表,更少的文本。让我们从下面三个比赛周的比赛难度等级(FDR)开始:

看起来 MUN, SHU,SOU,ARS,LEE 和 NEW 有一些艰难的比赛即将到来,所以我们的算法可能不会从这些球队中挑选球员。在接下来的三周里,CHE、TOT、CRY、BHA、WBA 和 EVE 的日程似乎更加轻松。

博彩赔率

我们将尝试积累来自 队的玩家,他们有超过 50 %的机会赢得 比赛,例如 TOT、 LIV、MCI、WOL、ARS 和 BHA 。我们应该尽量不要有太多的车、李、雷、WBA、、纽卡、布尔这样的防守球员。

较高概率抽到 的队伍,特别是当比赛是 结合高赔率为 2.5 以下的 时,可能是 适合选择防守队员 因为如果比赛以 0:0 结束,那将会产生大量的加分。结合 下方的 Under/Over 图,我们可以识别出以下 至少一场不失球概率较高的游戏——FUL-CRY、BHA-WBA、WOL-NEW。

反过来,我们可能希望从 赔率超过 2.5 的游戏中有更多的 进攻型玩家 ,比如-MCI、LIV-SHU、MUN-CHE、ARS-LEI、AVL-LEE 。同样,上周的赔率表现得相当好,因为大多数游戏预测有超过 2.5 个目标!****

裁判统计

从下面的统计数据来看,在比赛中出现点球的几率更高:WHU-麦克伊,布尔-托,苏-伊夫,和富尔-科尔,所以我们建议为这些球队中的一些球队配备点球手**。看起来,像游戏AVL-李,MUN-CHE 和 BUR-TOT 有裁判喜欢给很多卡,所以预计会失去一些黄牌,但希望没有红色…**

团队惩罚统计

除了裁判判罚的概率之外,让我们也看看在过去的 5 个赛季中哪些球队被判罚最多,看看我们在哪里得到了最高的综合概率。从下面的图表中我们可以得出结论,雷、CRY、MCI、MUN 和 TOT 最有可能获得点球。

预计首发阵容

在我们运行最终的团队选择器之前,让我们考虑一下每个团队的预计首发 11 人。

请注意右边可疑球员的名字,以及下面最新的伤病消息:

团队累计投资回报率统计

**五个游戏周过去了,我们终于有了足够的统计数据,来看看哪些球队被认为是整体上的好投资,哪些球队有很多定价过高的表现不佳的球员。球队按平均每名球员得分排序,所以毫不奇怪,AVL、伊夫、WOL 和 WHU 在名单上名列前茅,因为他们的球员价格已经超出了他们的预期。一些价格更高,表现不佳的球员可以在 **FUL,BUR,SHU,MUN,MCI,NEW,中找到,所以从这些球队中挑选球员是一个很好的主意。

推荐人队长

我们的方法采用了即将到来的比赛的预测得分,球员罚点球、角球或任意球的概率,球员在过去 4 个赛季中的空中威胁系数,他们的球队打进 2 个或更多进球的可能性,并以标准化的方式将所有这些混合成最终队长选择系数**。然后,根据玩家的下一个对手调整的 FDR 和本赛季防守强度的标准化得分,该系数被减去对手抗性得分。熊猫 DF 看起来像下面的例子:**

基于这个公式,这里列出了这个 GW 的 15 个推荐队长。那里有很多好的选择,所以无论如何都不是一个容易的选择。如果你想谨慎行事,萨拉赫、马内、凯恩和儿子应该是你的首选。

预测模型(球员统计)

现在是今年改进算法的皇冠上的宝石——预测球员统计数据的时候了。在我们将所有的 FDR、赌注系数、ref 首发、预计阵容和伤病分层后,有两个主要指标我们在为下一个 n-gameweeks 团队选择调整我们的团队优化器时会考虑到— 预测总积分和期望值(ROI)。 下面是每个指标的统计数据,也按职位细分。

预计总积分—前 25 名玩家

预计预期价值(ROI) —前 25 名参与者

预测积分——顶级守门员

投射点数—顶级防守者

预测得分——顶级中场

预测分数——顶级前锋

如你所见,每个位置都有大量选项可供我们选择,因此我们将把上面的许多统计数据插入 Python 中的 优化函数,该函数将 输出具有最高预期总积分 的团队,给定我们的预算约束和其他进入我们决策过程的指标。在团队选择器代码生效之前应用的一些初步过滤器包括:

  1. 排除受伤或停赛球员
  2. 将球员排除在 FDR 高的队伍之外
  3. 在 GW1 中排除没有赛程的队伍中的球员
  4. 同一团队不能有超过 3 名玩家
  5. 总共必须有 15 名球员(GK=2,DF=5,MD=5,ST=3)

优化最常用信息的预算

上周前 100 名选手最常用的阵型是 3-4-3,所以我们将展示这种阵型的最佳阵容。正如你在下面看到的,模型首先查看参数,告诉它是否应该向 15 名球员的全队优化,或者向有 11 名关键球员和 4 名廉价替补 的特定阵型优化。对于填充符,它首先查看,并使用该 来决定每个位置 要获得多少个填充符。然后,模型从我们的初始预算中减去花费在 4 个填充者上的总金额,并将剩余的预算花费在关键的 11 个参与者上, 给定优化函数和模型约束****

******示例 1:向最大期望点数优化******

********

示例 2:向最大期望值(ROI)优化

********

在这种情况下,价值团队看起来非常有吸引力和平衡,如果你担心大量的伤病和关键昂贵球员的轮换,那么这种方法可能是一种保护你自己的好方法。

我们的 GW6 团队

****我们将一直使用上周的顶级得分团队,并尝试最多进行 1-2 次转会。因为我们上周打了外卡,所以我们不需要做任何重大改变,所以**我们只是得到了基尔曼**,他有希望成为长期的**主要价值,如果他定期得到 60 分钟以上的比赛**,即使他几周不打,在他的价格上涨 0.2 或更多之前得到他 400 万,使他成为一个很好的替代 DF,并为更昂贵的进攻球员腾出资金。对于队长,我们将选择最受推荐的球员——萨拉赫。****

结论

按照本赛季的发展方式,我们建议放弃昂贵的防守球员,尝试只拥有三名中档防守球员,并且在中场和进攻中积累大量筹码,因为本赛季到目前为止一直在进球,而且没有迹象表明事情可能会很快放缓。感谢您一如既往的阅读,祝您本周好运!****

EPL 幻想 GW6 回顾和 GW7 算法选择

原文:https://towardsdatascience.com/epl-fantasy-gw6-recap-and-gw7-algo-picks-bf21e854f6e8?source=collection_archive---------41-----------------------

我们的金钱球方法到幻想的 EPL(队 _id: 2122122)

GW6 的顶级团队

如果这是你第一次登陆我们的幻想 EPL 博客,你可能想看看我的媒体档案中的一些我们最初的 EPL 博客,以熟悉这个项目是如何开始的,以及随着时间的推移我们所做的改进。

GW6 前 100 名 FPL 团队统计数据

一段时间以来,世界排名前 100 位的球员第一次没有疯狂的总得分(T1 ),平均得分只有 65 分左右,一些顶级球员的得分在40-50 分范围内(T3 ),这让我们对自己感觉稍微好一点,因为我们本周也没有做得那么好。

前 100 名最佳守门员

前 100 名中最受欢迎的捍卫者

前 100 名最佳中场球员

前 100 名中入选最多的前锋

我们使用这些数据创建了下面的团队,它是由前 100 名中最受欢迎的球员组成的:

100 强中最受欢迎的团队

这些数据很有意义,因为大多数顶级球员都试图利用 3–4–3 f阵型的进攻型中场和前锋。

GW6 团队绩效总结和总体统计

我们所有团队的得分都高于平均水平,但只是勉强达到。我们的一支球队在替补席上留下了 11 分,另一支球队从迪格内获得了 2 分,加上萨拉赫没有像预期的那样表现。此外,埃里森的早期恢复让我们的两个车队没有了 GK,所以对我们来说没有太多的积极因素。我猜让瓦迪、凯恩船长、儿子和扎哈在我们的一个团队中是一个很好的组合,至少对我们的一个团队来说,这是一个不错的组合。

我们还参加了 FPL 的 FanTeam 版本,幸运的是,我们的运气好得多,我们的大多数玩家都获得了大量积分

为我们的 GW7 选择提供有用的统计数据

由于我们今年在算法中加入了很多新的统计数据,随着时间的推移,这个博客将会有更多的统计数据和图表,更少的文本。让我们从下面三个比赛周的比赛难度等级(FDR)开始:

看起来丽芙、舒、雷、李和新有一些艰难的比赛即将到来,所以我们的算法可能不会从这些球队中挑选球员。在接下来的三周里,CHE、TOT、CRY、WHU、WBA 和 EVE 的日程似乎更加轻松。

博彩赔率

我们将尝试累积来自 队伍中有超过 50 %胜率的 玩家,例如 TOT、 LIV、MCI、CHE、、EVE 和 MUN 。我们应该尽量不要有太多来自 WHU、BHA、科尔、纽卡和布尔的防守球员。

较高概率抽到 的队伍,特别是当比赛是 结合高赔率为 2.5 以下的 时,可能是 适合选择防守队员 因为如果比赛以 0:0 结束,那将会产生大量的加分。结合 下方的 下/上图,我们可以识别出以下 概率较高的至少一场不失球的游戏——FUL-WBA 和 WOL-CRY。

相反,我们可能希望从 赔率超过 2.5 的游戏中有更多的 攻击玩家 ,比如丽芙-WHU、舒-MCI、布尔-切、AVL-苏、托特-BHA 和门-阿尔什*。*

裁判统计

从下面的统计数据来看,在比赛中出现点球的几率更高:舒-麦基,布尔-切,李磊,丽芙-WHU ,所以我们建议为这些球队中的一些球队配备点球手。看起来,像游戏 FUL-WBA,TOT-BHA 和 SHU-MCI 有裁判喜欢给很多牌,所以预计会从黄牌失去一些分数,但希望没有红色…

团队惩罚统计

除了裁判判罚的概率之外,让我们也看看在过去的 5 个赛季中哪些球队被判罚最多,看看我们在哪里得到了最高的综合概率。从下面的图表中我们可以得出结论,雷、CRY、MCI、MUN、TOT 和 LIV 最有可能获得点球。

预计首发阵容

在我们运行最终的团队选择器之前,让我们考虑一下每个团队的预计首发 11 人。

请注意右边可疑球员的名字,以及下面最新的伤病消息:

团队累积投资回报统计

这张表可以揭示哪些球队总体上被认为是好的投资,哪些球队有很多定价过高、表现不佳的球员。球队按**平均每名球员得分排序,**所以毫不奇怪 **AVL、伊夫、苏、李、WOL 和 WHU 是排名最靠前的球队,**因为他们的球员价格已经超出了他们的预期。一些价格更高,表现不佳的球员可以在 **FUL,BUR,SHU,MUN,MCI 和 NEW,**中找到,所以从这些球队中挑选球员是一个很好的主意。

防守与进攻团队统计

到目前为止,拥有 TOT、LIV、EVE、雷、车、和 LEE 的进攻球员似乎是一笔不错的投资。

虽然有太多来自 MCI 的进攻球员,CRY,,WBA FUL BUR 和 SHU T1 似乎是一个糟糕的投资,除非你有一个得分 70%的球员,如 WOL 的希门尼斯或 CRY T3 的扎哈。

拥有来自、ARS、、、MCI、TOT 和雷的防守球员似乎是一笔不错的投资。

虽然拥有来自 FUL,WBA,LIV,BHA,MUN 和 NEW T7 的防守球员,似乎是一个糟糕的投资。

推荐人队长

我们的方法采用了即将到来的比赛的预测分数、球员罚点球、角球或任意球的概率、球员在过去 4 个赛季中的空中威胁系数、他们的球队打进 2 个或更多球的可能性,并以标准化的方式将所有这些混合成一个最终队长选择系数。然后,根据球员的下一个对手调整后的 FDR 和本赛季防守强度的标准化得分**,将系数减去对手阻力得分。熊猫 DF 看起来像下面的例子:**

基于这个公式,这里列出了这个 GW 的 15 个推荐队长。那里有很多好的选择,所以无论如何都不是一个容易的选择。这是第一次萨拉赫不再是首选,推荐者认为你应该选择凯恩、儿子、米特洛维奇、KDB 或斯特林,然后是萨拉赫。

预测模型(球员统计)

现在是今年改进算法的皇冠上的宝石——预测球员统计数据的时候了。在我们将所有的 FDR、赌注系数、裁判首发、预计阵容和伤病分层后,有两个主要指标*,我们在为下一个 n-gameweeks 团队选择调整我们的团队优化器时会考虑这些指标— 预测总积分和期望值(ROI)。 下面是每个指标的统计数据,也是按职位细分的。*

预计总积分—前 25 名玩家

预测积分——顶级守门员

投射点数—顶级防守者

预测得分——顶级中场

预测分数——顶级前锋

正如你所看到的,每个位置都有大量选项可供我们选择,因此我们将把上面的许多统计数据插入 Python 中的 优化函数,该函数将 输出具有最高预期总积分 的团队,给定我们的预算约束和进入我们决策过程的其他指标。在团队选择器代码生效之前应用的一些初步过滤器包括:

  1. 排除受伤或停赛球员
  2. 将球员排除在 FDR 高的队伍之外
  3. 排除 GW1 中没有固定比赛的队伍中的球员
  4. 同一支队伍不能有超过 3 名玩家
  5. 总共必须有 15 名球员(GK=2,DF=5,MD=5,ST=3)

优化最常用信息的预算

上周前 100 名选手最常用的阵型是 3-4-3,所以我们将展示这种阵型的最佳阵容。正如你在下面看到的,模型首先查看参数,告诉它是否应该向 15 名球员的全队优化,或者向拥有 11 名关键球员和 4 名廉价替补 的特定阵型优化。对于填充符,它首先查看 首选地层 ,并使用那个 来决定每个位置 需要多少个填充符。然后,该模型从我们的初始预算中减去花费在 4 个填充者上的总金额,并将剩余的预算花费在关键的 11 个参与者上, 给出优化函数和模型约束 。**

****示例 1:向最大期望点数优化****

****

示例 2:向最大期望值(ROI)优化

****

经过我们的一些修改——在这种情况下,价值团队看起来非常有吸引力和平衡,如果你担心大量的伤病和关键昂贵球员的轮换,那么这种方法可能是保护你自己免受这种影响的好方法。

我们的 GW7 团队

**我们将一直使用上周的顶级得分团队,并尝试最多进行 1-2 次转会。因为我们的球队上周没有 GK,我们只做了一次转会,就是用马丁内兹换阿德里安。对于我们的队长,我们将选择**最受推荐的球员——凯恩**。很难在格里利什和若日尼奥之间做出决定,但我们希望 AVL 在主场对阵苏时能有更多的进攻,然后若日尼奥会得到另一个点球或助攻,所以希望我们不会后悔。**

结论

按照本赛季的发展方式,我们建议放弃昂贵的防守球员,尝试只拥有三名中档防守球员,并在中场和进攻中积累大量筹码**,因为本赛季迄今为止一直在进球,而且没有迹象表明事情可能会很快放缓。感谢您一如既往的阅读,祝您本周好运!******

EPL 幻想 GW7 回顾和 GW8 算法选择

原文:https://towardsdatascience.com/epl-fantasy-gw7-recap-and-gw8-algo-picks-855240acc9a2?source=collection_archive---------31-----------------------

我们的金钱球方法到幻想的 EPL(队 _id: 2122122)

GW6 的顶级团队

如果这是你第一次登陆我们的幻想 EPL 博客,你可能想看看我的媒体档案中的一些我们最初的 EPL 博客,以熟悉这个项目是如何开始的,以及随着时间的推移我们所做的改进。

GW7 前 100 名 FPL 团队统计数据

我们上周在榜首看到了更多的正常数字,前 100 名球员的平均得分约为 72 分,一些顶级球员的得分在40-50 分范围内,这使我们对自己感觉稍微好一点,因为我们的得分与前 100 名的平均得分 72 分持平。

前 100 名最佳守门员

前 100 名中最受欢迎的捍卫者

前 100 名最佳中场球员

前 100 名中入选最多的前锋

我们使用这些数据创建了下面的团队,它是由前 100 名中最受欢迎的球员组成的:

100 强中最受欢迎的团队

这些数据很有意义,因为大多数顶级球员都试图利用 3-4-3 阵型的进攻型中场和前锋。

GW7 团队绩效总结和总体统计

我们所有球队的得分都高于平均水平,接近世界前 100 名球员的平均水平,所以总体来说我们这一周表现不错。我们不得不提到绝对恶劣的裁判失误,没有判兰普提的进球无效**,这让我们至少损失了-8 分**,因为规则是不失球+也在奖金名单上,直到兰普提得分,他们实际上把加分转移到了他身上。除此之外,我们赌了 algo 推荐的前两名队长,萨拉赫和凯恩都做得足够好。

我们还参加了 FanTeam 版的 FPL,在那里我们的两支车队又经历了一个强劲的一周。

为我们的 GW7 选择提供有用的统计数据

由于我们今年在算法中加入了很多新的统计数据,随着时间的推移,这个博客将会有更多的统计数据和图表,更少的文本。让我们从下面三个比赛周的比赛难度等级(FDR)开始:

看起来 LIV,WOL,FUL,LEE 和 MCI 有一些艰难的比赛即将到来,所以我们的算法可能不会从这些球队中挑选很多球员。车、雷、托特、门、哭、夏娃和在接下来的三周里似乎有了更轻松的安排。

博彩赔率

我们会尽量把 队伍中赢 的几率高于 50 %的玩家,比如 TOT、 CHE、ARS、、和 SOU 。我们应该尽量不要有太多来自舒,WBA,,FUL,NEW,BUR 的防守球员。

较高概率抽到 的队伍,特别是当比赛是 结合高赔率为 2.5 以下的 时,可能是 适合选择防守队员 因为如果比赛以 0:0 结束,那将会产生大量的加分。结合 下方的 下/上图,我们可以识别出以下 至少一场不失球概率较高的比赛——BHA-布尔、克雷-李、雷-WOL。

相反,我们可能希望从 赔率超过 2.5 的游戏中有更多的 攻击玩家 ,例如 MCI-LIV、CHE-SHU、ARS-AVL、WBA-TOT、EVE-MUN 和 WHA-FUL

裁判统计

从下面的统计数据来看,在比赛中出现点球的几率更高:雷-WOL,MCI-LIV,-BUR,和 CRY-LEE ,所以我们建议为这些球队中的一些球队配备点球手。看起来,像 WBA-TOT,ARS-AVL 和 EVE-MUN 这些游戏都有喜欢给很多牌的裁判,所以预计会因为黄牌而失去一些分数,但希望没有红牌…

团队惩罚统计

除了裁判判罚的概率之外,让我们也看看在过去的 5 个赛季中哪些球队被判罚最多,看看我们在哪里得到了最高的综合概率。从下面的图表中我们可以得出结论,雷、CRY、MCI、MUN、TOT 和 LIV 最有可能获得点球。

预计首发阵容

在我们运行最终的团队选择器之前,让我们考虑一下每个团队的预计首发 11 人。

请注意右边可疑球员的名字,以及下面最新的伤病消息:

团队累积投资回报统计

这张表可以揭示哪些球队总体上被认为是好的投资,哪些球队有很多定价过高、表现不佳的球员。球队按照的平均每名球员得分排名,所以毫无疑问,、苏、、、和雷是排名最靠前的球队,因为他们的球员价格已经超出了他们的预期。一些价格更高、表现不佳的球员可以在 **FUL、BUR、SHU、WBA、MUN、MCI 和 CRY 中找到,**所以从这些球队中挑选球员是一个很好的主意。

防守与进攻团队统计

到目前为止,从托特、丽芙、伊芙、雷、车、和苏那里得到进攻球员似乎是一笔不错的投资。

虽然有太多来自 BUR 的进攻球员,SHU,WBA,FUL,,MUN,和 CRY 似乎是一个糟糕的投资,除非你有一个进球 70%的球员,如 CRY 的扎哈。

从、ARS、、MCI、TOT、CHE 和雷那里得到防守球员似乎是一笔不错的投资。

而拥有来自 FUL,WBA,LIV,BHA,MUN 和 LEE 的防守球员,似乎是一个糟糕的投资。

推荐人队长

我们的方法采用了即将到来的比赛的预测分数、球员罚点球、角球或任意球的概率、球员在过去 4 个赛季中的空中威胁系数、他们的球队打进 2 个或更多球的可能性,并以标准化的方式将所有这些混合成一个最终队长选择系数。然后,根据球员的下一个对手调整后的 FDR 和本赛季防守强度的标准化得分**,将系数减去对手阻力得分。熊猫 DF 看起来像下面的例子:**

基于这个公式,这里列出了这个 GW 的 15 个推荐队长。那里有很多好的选择,所以无论如何都不是一个容易的选择。我们的推荐人认为你应该选择凯恩、森、鲍文、沃纳、奥巴、KDB 或多尔蒂。

预测模型(球员统计)

现在是今年改进算法的皇冠上的宝石——预测球员统计数据的时候了。在我们将所有的 FDR、赌注系数、裁判首发、预计阵容和伤病分层后,有两个主要指标*,我们在为接下来的 n 场比赛周团队选择调整我们的团队优化器时会考虑到这两个指标— 预测总积分和期望值(ROI)。 下面是每个指标的统计数据,也是按职位细分的。*

预计总积分—前 25 名玩家

预测积分——顶级守门员

投射点数—顶级防守者

预测得分——顶级中场

预测分数——顶级前锋

正如你所看到的,每个位置都有大量选项可供我们选择,因此我们将把上面的许多统计数据插入 Python 中的 优化函数,该函数将 输出具有最高预期总积分 的团队,给定我们的预算约束和进入我们决策过程的其他指标。在团队选择器代码生效之前应用的一些初步过滤器包括:

  1. 排除受伤或停赛球员
  2. 从 FDR 高的队伍中排除球员
  3. 排除 GW1 中没有固定比赛的队伍中的球员
  4. 同一团队不能有超过 3 名玩家
  5. 总共必须有 15 名球员(GK=2,DF=5,MD=5,ST=3)

优化最常用信息的预算

上周前 100 名选手最常用的阵型是 3-4-3,所以我们将展示这种阵型的最佳阵容。正如你在下面看到的,模型首先查看参数,告诉它是否应该向 15 名球员的全队优化,或者向有 11 名关键球员和 4 名廉价替补 的特定阵型优化。对于填充物,它首先查看 优选地层 ,并使用该 来决定每个位置 需要多少填充物。然后,该模型从我们的初始预算中减去花费在 4 个填充者上的总金额,并将剩余的预算花费在关键的 11 个参与者上, 给出了优化函数和模型约束 。**

****示例 1:向最大期望点数优化****

****

我们的 GW8 团队

**我们将一直使用上周的顶级得分团队,并尝试最多进行 1-2 次转会。因为我们在周三发布这个博客,而且明天还有欧洲比赛,我们会等到周五早上才进行转会,所以我们下面要换的球队可能会换一个球员。还不确定会有什么变化,但如果规则变成橙色或红色,我们可能会从一些即将到来的赛程更轻松的车队中寻找一个与 **DF** 的互换,比如 **WHU、门或哭泣。****

结论

按照本赛季的发展方式,我们建议放弃昂贵的防守球员,尝试只拥有三名中档防守球员,并且在中场和进攻中积累大量筹码,因为本赛季到目前为止一直在进球,而且没有迹象表明事情可能会很快放缓。感谢您一如既往的阅读,祝您本周好运!****

EPL 游戏周 6 使用数据科学预测:xG 模型

原文:https://towardsdatascience.com/epl-game-week-6-prediction-using-data-science-xg-model-40541b03523c?source=collection_archive---------25-----------------------

这是我的 EPL 预测系列的一篇文章。你可以在这里查看上一周比赛的预测和实际表现。

预期目标或 xG 是用于预测的参数。如果你对理解预测算法感兴趣,我推荐你去看看这篇文章,里面有详细的解释。

对第 5 周比赛的分析

以上数字显示了每支球队每场比赛的 xG 得分和 xG 失球。我们可以观察到,卫冕冠军利物浦在创造力方面远远超过其他球队。热刺、埃弗顿和切尔西也是很好的进攻球队。名单中还包括目前为止在联赛中表现出色的维拉和铁锤帮。西布朗落后于预期的每场比赛 0.5 个进球!谢菲尔德、狼队、水晶宫也是场均预期进球不到一个。

阿斯顿维拉是联赛中唯一一支没有失分的球队,是防守最好的球队,失球率最低。锤子、太妃糖和海鸥似乎也有难以穿透的防御。另一方面,曼联和西布朗的防守漏洞最多。

根据 xG 得分和 xG 失球,球队可以分为 4 个象限,如上图所示。水平虚线表示每场比赛的平均 xG 得分。水平虚线以上的球队是强攻方,下面的球队进攻弱。
垂直虚线显示每场比赛的平均 xG 失球,左边的球队防守强,右边的球队防守弱。

所有球队的目标都应该是 Q2,那里的进攻和防守都比平均水平要好。例如,刀锋队是联盟中防守最好的球队之一。然而,他们在前期缺乏创造力。红军需要立即解决进攻中的问题。

联赛中进攻最好的球队在 Q1,因为他们的防守不是很强。然而,他们的进攻能力足以弥补防守上的弱点,如左图所示。

提醒一句:所有的分析都是基于一个非常小的样本量,每个队只有 4 或 5 场比赛,因此一场糟糕的比赛或一场好的比赛往往会扭曲结论。

对第六周比赛的预测

基于第五周的表现,第六周的预测如下。

GD 的绝对值显示了比赛的竞争力。该值越高,预计匹配越偏向一侧,预测的准确性也越高。GD 值越低,这场比赛就越可能是任何人的游戏。GD 的正值表示主场胜,负值表示客场胜。

布莱顿 Vs WBA 预计是最一边倒的比赛,海鸥有望获胜。利物浦和阿斯顿维拉也有很高的胜算。热刺、蓝军和太妃糖也有望在客场全取三分。梅切斯特城,最受欢迎的球队之一,预计将与铁锤帮进行一场艰苦的比赛,他们必须需要一些好运气才能在对阵复兴的莫耶斯的球队时不丢分。

狼队对新城堡队预计是任何人的游戏。主场对阵水晶宫的富勒姆和客场对阵阿森纳的莱斯特对他们的对手略有优势。

红魔主场迎战蓝军有望成为本周比赛中得分最高的比赛,蓝军有望获胜。尽管刀片队是联赛中防守最好的球队之一,但他们在安菲尔德的比赛预计将是一场进球盛宴。纸面上的富勒姆 vs 水晶宫,就进球而言,似乎是周末最无聊的一场比赛。

更新:实际与预测

预测的增量 xG 与实际的增量 xG(图片由作者提供)

对阿森纳对莱斯特比赛的预测是最准确的,然而,该算法在预测阿斯顿维拉对利兹的比赛中最不准确(埃尔洛克是马塞洛·贝尔萨的合适称号,他的战术太疯狂了!退一步说。该算法只是一个简单的基线模型,但我仍然希望预测会随着样本量的增加而改善。
目前,样本量非常小,预测受到异常值的巨大影响。
展望未来,我计划考虑比赛风格、主场优势、射门质量等因素。来改进模型。

请让我知道你对如何改进这个模型的建议。

托马斯·塞勒在 Unsplash 拍摄的照片

公平代码:GitHub 上退休的主人

原文:https://towardsdatascience.com/equitable-code-retiring-master-on-github-beb21b791a18?source=collection_archive---------48-----------------------

负责任地更新活动存储库的分步指南。

介绍

在 Nines,我们在为我们的放射学实践构建工具时不断迭代。在本帖中,我们将讨论如何更新软件行业中常用的一些基础设施。

近年来,已经开始了一场从软件系统中去除术语“主”和“从”的运动。2018 年, Python 在 3.8 版本移除了很多引用。最近, GitHub 宣布他们将把默认分支从主分支改为主分支。

传统上,git 存储库中使用的规范分支被命名为 master。它是在新的存储库中创建的默认分支,并且通过要求代码变更的同行评审,以及持续集成 (CI)测试,经常受到更强的保护。

在 Nines,我们已经做出了这样的改变。我想分享我对这个话题的一些想法,以及让这种转变对其他人来说尽可能容易的指南。

为什么删除对 master 的引用?

主人这个词可以引发人们对奴隶制、种族主义和系统性不公正的思考。许多人指出,在这种情况下,这种使用类似于唱片业中的主唱片,即权威版本。虽然可能是这样,但这不是重点。这些微妙但频繁的触发被称为微侵袭。它们很常见,通常用于而没有伤害的意图。它们可能听起来很小,但是累积起来,它们会产生很大的影响。这种类型的问题非常普遍,以至于人工智能将影响表现得非常明显。造成的痛苦是实实在在的,我们很容易就能帮上忙。所需要的只是注意力和行动

我加入了,现在怎么办?

太好了!在我们开始 Nines 的 9 步流程之前,请确保您对正在更新的 GitHub 库拥有管理员权限。您应该能够在存储库中看到 Settings 选项卡:

1。传达即将到来的变化

与使用您的存储库的任何开发人员交流这个过程是很重要的。如果可能的话,最好选择在存储库没有大量活动的时候进行转换,因为在错误的时间合并的拉请求可能会导致信息丢失。

示例:

本着一种 更广泛的运动 ,我将<资源库中的默认分支从 master 重命名为 main。在<日期>上午 8 点到 9 点,将有一个不应该合并钻杆排放系统的计划停机时间。如果您对此流程有任何疑问,请告诉我。

2。创建新分支

在 git 中创建新分支非常简单。从存储库的本地克隆中,签出主分支,并确保您使用的是最新的 GitHub:

git checkout master
git pull

从更新后的基础创建新分支:

git checkout -b main

现在把新的分支推到 GitHub:

git push --set-upstream origin main

这里需要注意的是,所有以前的提交历史都保留在这个过程中。

3。更新分支保护

通常,主要分支机构会受到各种分支机构保护规则的约束。这将出现在 GitHub 分支设置中,如下所示:

在这个阶段,我们可以使用通配符来扩展规则,使其涵盖主分支和主要分支。单击规则上的编辑,并将分支名称模式更新为 ma*。值得注意的是,“应用于 n 个分支”框在保存更改之前不会更新。这应该看起来像这样:

4。更新代码和文档

接下来,在您的存储库中搜索显式包含的 master。通常,这将包括 CI/CD 配置文件,可能还有其他脚本和工具。这需要非常小心,因为这个词可能有很多其他的用法,比如其他的存储库,或者不相关的代码。

您选择的 IDE 可能有一个很好的方法来搜索存储库中的所有文件。如果您没有类似的东西,这里有一个简单的脚本来打印所有事件:

git ls-files | xargs -I {} sh -c ‘echo “<<< {} >>>” && grep -ni master {}’

不要忘记检查 master 中可能需要合并到 main 中的任何新变化。您可以通过在 Code 选项卡中选择主分支,然后单击 compare 来检查这些内容。

5。更新默认分支

现在我们将更新 GitHub,将 main 作为默认分支。这将导致拉请求默认使用 main 作为基础,将改变 Code 选项卡中默认显示的分支,等等。这可在“分支”下的“设置”选项卡中进行更改:

6。更新打开拉式请求

删除主数据后,任何使用它作为基础数据的打开的提取请求都将自动关闭,并且不能重新打开。为了避免这种情况,任何打开的拉取请求都应该将其基础更新为 main。基数列在拉动式请求的顶部,如下所示:

点击右上角的“编辑”会将基础变为下拉列表。更新并保存。

7 .。更新分支保护,第 2 部分

为了删除主服务器,我们首先需要删除仍然适用于它的分支保护。这很像前面的变化,但是现在用 main 替换 ma*。

8。从 GitHub 中删除 master

移除分支保护后,从原点(GitHub)删除分支非常简单:

git push -d origin master

9。传达变更和本地清理

现在是时候结束这个循环并与开发人员交流完成情况了。除了确认工作已经完成之外,还需要在每个开发人员的机器上做一些小的清理工作,删除被删除的主分支的副本。这可以通过在每个克隆中运行以下命令来实现:

git fetch
git checkout --track origin/main
git branch -d master

示例:

在<仓库>中,从主数据库到主数据库的转换现在已经完成。所有未完成的拉取请求都已更新,以反映这一点。作为最后一步,请在您的本地副本<存储库>中运行以下命令来删除过时的元数据:

git fetch && git checkout --track origin/main && git branch -d master

搞定了。

我希望这使得更新您的分支的过程变得简单和相对容易。感谢你们让我们的世界和工业变得更加友好。

NB:本文原载于 Nines 博客

Python 中的错误和异常处理:数据科学家基础

原文:https://towardsdatascience.com/error-and-exception-handling-in-python-fundamentals-for-data-scientists-4b349256d16d?source=collection_archive---------10-----------------------

用一个具体的例子来理解基础!

图片由 Unsplash 上的 Alexandru Acea 拍摄

Python 中主要有三种可区分的错误:语法错误异常和逻辑错误

  • 语法错误类似于语言中的语法或拼写错误。如果您的代码中有这样的错误,Python 就无法开始执行您的代码。您会得到一个明确的错误消息,指出什么是错误的,什么需要修复。因此,这是最容易修复的错误类型。
  • Python 中常见的语法错误有符号缺失(如逗号、括号、冒号)、关键字拼写错误、缩进不正确。
  • 异常可能出现在运行时语法正确的代码块中。当 Python 无法执行请求的操作时,它会终止代码并引发一条错误消息。
  • 试图从一个不存在的文件中读取数据,对不兼容类型的变量执行操作,将一个数除以零是 Python 中常见的引发错误的异常
  • 我们必须消除语法错误来运行我们的 Python 代码,而异常可以在运行时处理。
  • 逻辑错误是最难修复的错误,因为它们不会让你的代码崩溃,你也不会得到任何错误消息。
  • 如果您有逻辑错误,您的代码将不会按预期运行。
  • 使用不正确的变量名、不能正确反映算法逻辑的代码、在布尔运算符上出错将导致逻辑错误。
**# Syntax Error-1: Misusing the Assignment Operator** len("data") **=** 4
**Output:** File "ErrorsAndExceptions.py", line 1len("data") = 4
SyntaxError: can't assign to function call**# Syntax Error-2: Python Keyword Misuse
fr** k in range(10):print(k)
**Output:**File "ErrorsAndExceptions.py", line 4fr k in range(10):^
SyntaxError: invalid syntax**# Exception-1: ZeroDivisionError**
print (5/0)
**Output:** Traceback (most recent call last):File "ErrorsAndExceptions.py", line 12, in <module>print (5/0)
ZeroDivisionError: integer division or modulo by zero**# Exception-2: TypeError**
print ('4' + 4)
**Output:**
Traceback (most recent call last):File "ErrorsAndExceptions.py", line 10, in <module>print ('4' + 4)
TypeError: cannot concatenate 'str' and 'int' objects

Uchral Sanjaadorj 在 Unsplash 上拍摄的照片

语法错误

当您的代码有语法错误时,Python 会停止并通过提供代码中错误的位置和明确的错误定义来引发错误。

**# Syntax Error-1: Misusing the Assignment Operator** len("data") **=** 4
**Output:** File "ErrorsAndExceptions.py", line 1len("data") = 4
SyntaxError: can't assign to function call

您需要更正语法错误才能运行代码。

len("data") **==** 4
**Output:** True

异常处理

异常处理的主要目的是防止潜在的故障和不受控制的停止。

我们可以用一个 try-except 块来捕捉和处理一个异常:

  • try 块包含要监控异常的代码。
  • except 块包含特定异常发生时要做的事情。如果没有异常发生,则跳过这一部分,并结束 try-except 语句
  • 如果引发的异常与中指定的异常匹配,则执行 except 块中的代码来处理该异常。
  • 如果没有在关键字之外的中指定任何类型的异常,您可以捕捉任何异常。
  • 当第一个异常发生时,try 块执行终止。
  • try-except 块可能有不止一个 except 块来处理几种不同类型的异常。
  • 可选的 else 块只有在 **try 块没有出现异常的情况下才会执行。**如果出现任何异常,将不会执行 else 块。
  • 可选的最后块用于清理代码。这个块总是被执行。
**try:****#code to monitor**print (5/0)**#this code will not be executed#as above line raises a ZeroDivisionError**print ("this code will not be executed")**except** *ZeroDivisionError* as e: **#code to handle the exception when it occurs**print(e)print("OPPS")**else:**print("try block executed if there is no error")**finally:**print("finally block is always executed")**Output:** integer division or modulo by zero
OPPS
finally block is always executed

照片由 Serenity Mitchell 在 Unsplash 上拍摄

引发异常

如果特定条件发生,您可以使用 raise 关键字手动引发异常。

student_age = -4if student_age < 2:**raise** *Exception*("Sorry, student age cannot be lower than 2")**Output:** Traceback (most recent call last):File "ErrorsAndExceptions.py", line 49, in <module>raise Exception("Sorry, student age cannot be lower than 2")
Exception: Sorry, student age cannot be lower than 2

定义自定义例外

如果我们希望对特定条件下发生的事情有更多的控制,我们可以定义自己的异常类型。

为此,我们从异常类继承。

*class* **InvalidStudentAgeException(*Exception*)**:**"""Exception for errors in the student ageAttributes:student_age -- student_age that we monitorerror_message -- explanation of the error"""***def* **__init__**(*self*, *student_age*, error_*message*="Student age should be in 2-10 range"):self.student_age = student_ageself.error_message = error_message*super*().__init__(self.error_message)student_age = *int*(input("Enter Student age: "))if not 1 < student_age < 11:raise **InvalidStudentAgeException(student_age)****Output:**
Enter Student age: 54
Traceback (most recent call last):File "ErrorsAndExceptions.py", line 68, in <module>raise InvalidStudentAgeException(student_age)
__main__.InvalidStudentAgeException: Student age should be in 2-10 range: 54 is not a valid age

上面,我们覆盖了异常基类的构造函数,以使用我们自己的自定义参数学生年龄错误消息。配合使用 super()。_ _ init _ _(self . error _ message),我们实例化了基类 Exception ,参数帮助我们显示错误消息。

照片由 Serenity Mitchell 在 Unsplash 上拍摄

关键要点

  • 我们必须消除语法错误来运行我们的 Python 代码,而异常可以在运行时处理。
  • 我们可以用 try-except 块捕捉并处理异常。
  • 如果我们希望对特定条件下发生的事情有更多的控制,我们可以定义自己的异常类型。

结论

在这篇文章中,我解释了在 Python 中错误和异常处理的基础。

这篇文章中的代码可以在我的 GitHub 库中找到。

我希望这篇文章对你有用。

感谢您的阅读!

理解误差反向传播

原文:https://towardsdatascience.com/error-backpropagation-5394d33ff49b?source=collection_archive---------17-----------------------

从零开始的神经网络解释误差反向传播

介绍

深度学习所基于的技术神经网络(NN)在机器学习中非常流行。我记得早在 2015 年,在阅读了由 Andrew Trask 撰写的文章11 行 python 代码的神经网络后,我立即迷上了人工智能领域。但是尝试从零开始构建一个神经网络,我相信大多数人会同意我的观点,即误差反向传播或简单的反向传播(BP)将是完成这项任务的早期障碍之一,至少取决于你愿意钻研的深度。对于那些不熟悉的人来说,BP 是与优化算法(如梯度下降(GD ))一起使用的算法,用于学习 NN 模型的参数。BP 产生梯度,然后用于优化。在本文中,我将尝试解释这种算法是如何工作的,然后从头开始构建一个简单的神经网络,在我之前的帖子中使用的一个回归问题上测试这个网络。对于那些正在与这种算法作斗争的人来说,我希望这篇文章能作为一个直观的指南。

请注意,为了完全理解这个算法,很好地掌握矩阵代数和多元微积分是非常必要的

设置

为了对 BP 有一个全面的了解,我将从给出我们将要建立的神经网络的大图开始。由此你将有望对神经网络的设计决策以及 BP 中使用的矩阵运算有一个直观的理解。请注意,这只是我的设计,我觉得很直观,其他作者可能有其他设计。我将使用一个简单的前馈神经网络,它只是一个相互堆叠的函数/层的组合,如下图所示。

作者图片

该算法

神经网络的每次训练迭代有两个主要阶段

  1. 正向传递/传播
  2. BP

BP 阶段有以下步骤

  • 评估每层的误差信号
  • 使用误差信号计算误差梯度
  • 使用带有优化算法(如 GD)的误差梯度更新层参数。

这里的想法是,网络在正向传递期间估计目标值。然后,我们计算我们的估计与最后一层的实际目标有多远(误差信号 δ_k )。最后,我们递归地计算每个先前层的误差信号。

给定诸如均方根的误差函数,可以使用偏导数找到最后一层的误差梯度。

作者图片

请注意,h’(a _ k)= 1为线性激活,因为这个***【∂e_n/∂y_k】=【∂e_n/∂a_k】。为了保持等式的整洁,忽略了索引 n。最后一层的量 (y_nk - t_nk) 称为误差信号【δ_ k】*。因此,链接特定误差信号和输入信号的参数的梯度是输入信号和误差信号**的乘积。使用链式法则,可以使用当前层的误差信号来计算前一层的误差信号。从上图来看,

作者图片

注意,如何通过对来自当前层节点的所有误差信号进行加权求和来获得前一层中的节点的误差信号,前一层节点向当前层节点发送其信号,即在索引 k 上求和。这就是为什么它被称为误差反向传播。同样,为了了解 k 上的这个和在数学上来自哪里,请注意∂e_n/∂a_k 是雅可比向量,而 ∂a_k/∂a_j 是雅可比矩阵。

如前所述,一般而言,链接一层中特定误差信号和输入信号的参数的梯度是该层的输入信号和误差信号的乘积。在前一种情况下,

作者图片

类似地,对于偏置参数,

作者图片

注意,这是递归的,来自当前层的误差信号用于评估前一层中的误差信号。这是拼图中非常重要的一块,因此让我们看看我们如何向量化,然后在代码中实现它。我们将假设批量训练,但是通过将批量大小设置为 1,相同的设计可以用于在线训练。

对于一个输出 K 和输入 P 的层,层权重会初始化为 (PxK) 。因此,对于尺寸为 N 输入和尺寸为 P 的输入,我们得到尺寸为NK的输出。如图所示,这是层向前传播步骤。偏置初始化为 (K,) ,此处未显示,因为它通过 N 广播,不会影响输出尺寸。**

作者图片

误差信号,【δ_ k】,因此有形状 (NxK) 。出于一个我们很快就会看到的原因,我将这个误差信号转置并作为 (KxN) 馈入反向传播函数。现在,将层参数与层误差信号相乘,对所有的图案在 k 上执行加权求和,因此是误差信号首先被转置的原因。我们把这一步得到的矩阵叫做 DM

作者图片

现在是棘手的部分,要完成前一层反向传播误差信号的计算,每个节点加权和,必须乘以*【h’(a _ j),其维数为 (NxP) 。我就把这个导数矩阵 D 。在矩阵代数中,这是通过将特定的输入模式作为对角矩阵,然后将该矩阵乘以相应的 DM 列来实现的。我就把这个对角矩阵叫做, S_n 。我将对一个大小为【PxN】的矩阵进行零初始化,以迭代累加前一层信号*

作者图片

如何构建矩阵 S_nDM_n 由你决定。您将在代码部分看到实现这一点的一种方法。也许有更有效的不涉及循环的方法,如果你知道的话请告诉我:)。

现在这些误差信号被传递到上一层, L_k-1, 来更新它的参数。当前层 L_k 的参数由误差信号更新,该误差信号通过其“反向传播”功能传递到该层。

需要注意的一点是,在更新层 L_k 参数之前,计算 层 L_k-1 误差信号。

如前所述,为了计算层参数梯度,我们将误差信号乘以该层的输入信号。我将称之为 G_w 权重渐变和 G_b 偏移渐变。对于层 K ,矩阵 A 为 (KxN) ,输入信号 I(恩智浦)

作者图片

注意,上面的操作对 N 求和,其效果是累加一批大小为 N 的梯度。

好了,说够了,让我们编码吧!

密码

首先,导入所有需要的东西

接下来,我将创建一个图层类。当调用该层时,它使用 call 执行正向传播。通过将前一层实例传递到当前层的实例中,可以将多个层堆叠在一起。正向传播从最早的层进行到最新的层。并且只有在前一层的输出大小/尺寸与当前层的输入尺寸匹配时,两层才能被附着。

接下来,模特班。这个类处理神经网络的训练过程和预测。

最后是一个生成器类,用于在训练时向网络提供数据

测试

首先,让我们生成一些数据

接下来,让我们创建我们的网络并开始训练。在本例中,我将创建一个 4 层网络。

最后,测试和绘图

图表

作者图片

结论

在这篇文章中,我试图涵盖反向传播的具体细节,并在此过程中展示了如何从头开始创建一个神经网络。测试结果表明,该神经网络比我以前文章中的线性回归模型更加强大和灵活。这篇文章的笔记本可以在我的 Github 上找到。对于感兴趣的读者,我鼓励你尝试修改网络来测试它的分类任务。

谢谢你看我的文章,下次再见!与此同时,在这段艰难的时期要小心!

参考

[1]:主教,C. M. (2006 年)。模式识别与机器学习。斯普林格。

使用 Python 中的 Matplotlib 从数据框绘制误差线

原文:https://towardsdatascience.com/error-bar-plots-from-a-data-frame-using-matplotlib-53026fe95491?source=collection_archive---------27-----------------------

Python 中误差条形图的简单代码!

照片由艾萨克·史密斯在 Unsplash 拍摄

最近,我不得不为一份报告比较几种方法/算法的性能,我选择了误差线来总结结果。如果你手头有一个类似的任务,用这篇文章为自己节省一些时间。

什么是误差条形图,什么时候应该使用?

误差条形图是表示数据可变性的好方法。简而言之,它们给出了数据可能与报告值(或大多数情况下的平均值)相差多少的直观想法。

这通常可以通过以下方式实现:

  • 标准偏差
  • 置信区间(最好是 95)

如果你的报告需要对显示结果的精度(或再现性)做出评论,误差条形图在我个人看来是必须的。我也看到一些报告用它来表示适当情况下的公差。

但是,当然,要确保你有合适的观众,可以解释你的幻想形象。

执行:

为了简单起见,我使用 Excel 上的随机数生成器创建了一个样本数据。您可以使用 mean() 和 std() 函数快速计算数据的平均值和标准差。

作者图片

导入 Matplotlib 并使用 Matplotlib 中的 errorbar() 函数。它为剧情提供了相当不错的定制水平。

import pandas as pd ## for handling the dataframe
import matplotlib.pyplot as plt ## for visualizationdf = pd.read_excel("Sample_error_charts.xlsx")## read the Dataframe##Plotplt.errorbar( df['Model'], df['Mean'], yerr=df['SD'], fmt='o', color='Black', elinewidth=3,capthick=3,errorevery=1, alpha=1, ms=4, capsize = 5)
plt.bar(df['Model'], df['Mean'],tick_label = df['Model'])##Bar plot
plt.xlabel('Model') ## Label on X axis
plt.ylabel('Average Performance') ##Label on Y axis

确保调整倾覆和厚度,以适应你的图表。

作者图片

我在这个例子中选择了标准差,但是你也可以使用置信区间或者标准误差,这取决于什么适合你的整体叙述。让你自己完全熟悉基本的描述性统计,这将会让你立即意识到应该选择什么。

快乐阅读!

卡莉安·基萨拉

如何解决数据库的升级问题

原文:https://towardsdatascience.com/escalating-your-database-1f945adf67ec?source=collection_archive---------37-----------------------

了解当您遇到性能问题时升级数据库的最佳技术

ev 在 Unsplash 上的照片

当项目增长时,最常见的瓶颈之一是在数据库方面。这可能是因为程序的复杂性由于新的需求而增加,或者更常见的是,由于应用程序应该处理的流量的增加。

之前的考虑

像在许多其他情况下一样,您应该根据指标升级您的数据库。一般来说,在没有首先研究数据库、应用程序和基础设施指标的情况下,我不会建议应用任何数据库升级。此规则的唯一例外是当您的应用程序出现故障时,经常出现超出范围、性能和/或延迟问题,甚至数据库过载和锁定。

此外,我的建议是,除非必要,否则不要应用这些技巧。如果您不希望或没有面临数据库问题,您不应该过度扩展您的系统。您必须意识到不同升级选项的权衡以及它们带来的后果,例如系统复杂性的增加、维护中的问题、调试难度的增加等等。

让我们一起回顾一下可用的主要选项:

添加一个索引

为应用程序所需的搜索向表中添加额外的索引将降低查询的延迟。

这种解决方案的缺点是您将消耗更多的数据库硬盘空间。创建新索引时,会创建一个记录数与原始表相同的新表。

此外,请注意,使用这种解决方案时,对数据库的写操作会比较慢,因为您需要在索引表中执行额外的搜索和写操作。一般来说,这不会是一个问题,除非您的 IOPS 操作在写入方面非常不平衡(尤其是在包含几百万条记录的大型表中),或者/或者您滥用了这个解决方案,在同一个表中添加了几个索引。

使用缓存解决方案

基本上,当您缓存一个查询时,数据库引擎不会在下一次被请求时重复相同的查询。当然,这可以节省时间、减少延迟并提高性能。您可以在不同级别应用缓存:

  • 在数据库引擎级别。当查询到达数据库时,如果该查询之前已经完成,引擎提供缓存版本。虽然在数据库级别处理缓存的方式因系统而异,但是当查询的任何元素有任何修改时,整个查询都会被清除。

作者图片

  • 在应用程序级别。应用程序接受一个请求,但是它不是获取数据库的信息,而是提供一个缓存响应(例如,使用 Memcache 或 Redis)。该系统为开发人员提供了完全的所有权,因为他们可以控制何时清理缓存并以编程方式配置 TTL。

作者图片

  • 在基础设施层面。一旦用户调用应用程序,而不是运行代码,就会提供一个缓存的响应(例如,使用 Varnish)。这种解决方案避免了应用程序,但是作为一种折衷,清理缓存更加困难。同时,它没有连接到应用程序,应该依赖于适当的 TTL 配置。

作者图片

使用复制品

该选项背后的想法是设置一个或多个将与主数据库实例同步的副本。然后,您可以导出副本的读取流量。这样,您减少了主实例的写操作流量,从而提高了整个系统的性能。

这个解决方案的权衡包括复杂性和成本的增加(您应该至少加倍实例)。此外,您应该在数据库端有一个健壮的基础设施,确保正确的复制,没有错误或严重的滞后。

作者图片

应用分片

基本上,这个解决方案将主数据库分成多个更小的数据库,称为碎片。虽然不同的操作将由不同的(更小的)碎片来处理,但在大多数情况下,性能和延迟将显著改善,从而结束几乎所有的数据库瓶颈。

分片有两种不同的实现方式,垂直共享和水平分片:

水平分片:每个原始表的内容被拆分到不同的机器上,保持它们之间相同的表结构(列、索引等)。)

垂直分割:表格在列级分割。

作者图片

虽然每个分片中的数据集更小,但是任何原子查询都会运行得更快;此外,写操作失败和并发问题的风险更低。请注意,情况并不总是如此,当您需要连接来自不同碎片的值时,尤其是当您还按多个列进行分组或排序时,性能会受到严重影响。

分片数据库为您提供了几个好处,但是它也带来了巨大的复杂性。当您需要将您的系统从非分片转移到分片时,它的初始实现需要一个详细的计划和实现。然后,维护需要对现有的新基础设施以及分片架构有深入的了解。任何新的开发都应该记住分片架构,并且需要更多的时间进行规划。

简化分片 App- DB 工作流-作者图片

最后的想法

升级数据库从来都不是一项简单的任务。让我坚持两点:首先,在开始之前,你需要精确的度量。其次,您需要深入理解您的应用程序、需求和缺陷,不仅包括纯技术方面,还包括产品和用户期望。

最后,请注意,我保持文章的一般性。升级数据库问题是一件严肃的事情。我并没有特意介绍代理实现、Viper 或 MariaDB 缓存系统——只是提到一些您可以考虑的潜在情况。本文的目的是让您对可以应用的关键解决方案有一个大致的了解。细节和实现同样取决于您的指标和应用。

将相关矩阵转移到…特征空间。

原文:https://towardsdatascience.com/escape-the-correlation-matrix-into-feature-space-4d71c51f25e5?source=collection_archive---------22-----------------------

介绍一种绘制相关矩阵的新技术。它使您能够快速识别数据中的高级结构。

在 Unsplash 上 Juskteez Vu 拍摄的照片。其他所有图片均由作者提供。

我们都有过擅长使用劣质产品的经历。贵公司与不可靠的 CRM 签订了为期四年的合同。带有可怕的数据库连接器的表单工具,您永远也找不到时间来迁移它。MS Access。由于惯性、组织限制或成本,我们经常发现自己使用低劣的工具和技术,学习它们的小怪癖,将肌肉记忆投入到一系列重复的对话框中。您是否尝试过将 Excel 文件保存为 CSV 文件?

如果将工作簿保存为 CSV 格式,其中的某些功能可能会丢失。

有时候,使用这些工具是必要的。谁知道呢,也许它甚至能塑造性格?

但是作为数据科学家,我们通常有能力选择自己的工具。这样做是非常重要的,因为我们的工具塑造了我们对什么是容易的,什么是可能的。

相关矩阵就是这些糟糕的工具之一。更具体地说,在我们习惯性地需要执行大量任务的情况下,它是一种对有限的任务集有效的工具。因为相关矩阵有着悠久的历史,并且在较小的数据集上工作得足够好,所以我们把它视为唯一的游戏。我提出了特征空间图——这是一个补充相关性矩阵的工具,对数据科学家和非专家都有用。代码很容易适应自己——参见最小示例和完整笔记本。

我们如何使用相关矩阵

那么相关矩阵到底有什么问题呢?让我们来看一个例子。假设我们正在使用波士顿住房数据集,我们的目标是为一个社区的中值房价建立一个预测模型。

我们可能会询问缺失值,查看单变量分布,查阅我们的数据字典,但我们最大的问题之一将是:

这些特征之间以及与目标之间是如何关联的?

作为优秀的数据科学家,我们希望尽可能地了解我们的数据集,而不是仅仅向它扔一个神经网络。这将有助于我们:

  • 特征工程
  • 特征选择
  • 降维/解决多重共线性
  • 并最终将结果传达给利益相关者

因此,我们开始行动(打个比方,我的运行工作台还没有进来),并构建一个关联矩阵。它计算皮尔逊相关系数(缩写为 r ),数据中的每一对数量特征接收一个从-1 到 0 到+1 的单个数字,分别表示它们的线性相关性为强负、不存在或强正。当输出为表格时,它显示任意两个要素之间的(线性)关系的强度。我们进行一些光视觉化,然后!

但是我们如何使用这个图表呢?让我们扪心自问…

—我们想做什么?

—这东西能帮我们做到吗?

作为数据科学家,我们希望至少做到以下几点:

  1. 找出任何两个感兴趣的特征之间的相关性。
  2. 了解数据的高级结构—是否存在大量多重共线性?密切相关的特征的“集群”在哪里?
  3. 学习一些我们不知道的,也可能想不到要问的东西。

上面的相关矩阵明显优于第一点。它本质上只是一个查找表,通过用颜色对值进行双重编码进行了改进。

第二点有点棘手。这里的“结构”是指存在于个体元素集合体中的组织形式——就像看着一栋房子说“它有三层”或“地基正在下沉”,而不仅仅是“那两块砖是相邻的”。在特征空间中,我们正在寻找的结构是提供独特预测值的共线特征或独立特征的聚类。

在高维空间中,更复杂的关系是可能的,这将我们引向第三个目标——学习我们不知道的东西。如果我们只是想验证一个假设,有大量的统计测试。但是获得一种我们从未想过要考虑的洞察力是分析和可视化的核心。

太相关-太少,太相关

那么,我们的相关矩阵是否有助于我们找到特征的聚类,并产生关于数据的新见解?

算是吧。我们可以从黑方块的盛行来判断我们是否有很多共线性。我们可以观察一行或一列,注意到它很暗或很亮,并了解该特征是否接近许多其他特征。但是,这将需要大量的时间来识别集群。一个问题是所有的列看起来都有点相同,我们必须不断检查轴标签,以确保我们看到的是正确的。

随着时间和努力,我们可以推断出,例如, RADTAXINDUSAGENOX 之间高度相关,并可能形成一个集群。做到这一点所需的信息都在这里。

但是可视化的目的是利用我们进化中磨练出来的视觉敏锐度来快速发现仅仅盯着一张图表看不到的模式。

在这一点上,我认为这不是一个产生洞察力的工具。

但是等等!如果集群是我们所追求的,那么为什么不只是对轴进行排序,使相关的特征彼此相邻呢?你能看出从原始版本到这个版本的改进吗?

未排序(左)和排序(右)相关矩阵。在排序后的版本中,特征簇更容易被挑选出来。

现在橡胶上路了!沿着对角线扫描,寻找色块。我们可以立即看到 CRIMRADTAX 以及 INDUSAGENOXDIS 之间的集群。

我们在这里所做的是利用我们大脑的进化磨砺的前注意处理来快速挑选出基于格式塔原则的模式,例如接近和相似。

可视化的主要目标之一是将有趣的数据绑定到这些模式上——我们基本上是在建造望远镜,并要求我们的大脑告诉我们森林中有什么在移动。

除了这些群集,我们的大脑还会挑选出其他模式。当然 RADTAX 相关性较高,但都与 CRIMB 相关性较小。LSTAT 似乎与 Median_Home_Value 和 RM 在一个聚类中,但它与大多数其他特征有相当强的相关性。看起来 NOX / DISRAD / TAX 簇相互关联,但与 LSTAT / RM 簇的关联度没有那么大。

充分利用二次元

这些是我们之前讨论过的复杂而令人惊讶的结构。我们的排序相关矩阵使它们可见,但我们仍然需要引用轴标签并跟踪一行或一列,对于一个有数百列的数据集,相关矩阵甚至不适合一个页面!

相关矩阵的另一个限制是两个轴的排序顺序相同,因此一个特征只能与另外两个特征直接相邻。这限制了我们用接近度来衡量亲密程度的能力。在排序后的矩阵中,我们试图分析用颜色编码很好的关系,但用距离编码不好。这给了图表一种“魔眼”的特征,并使它对非专家来说不那么容易接近。

嗯,什么图表可以让我们在二维空间中定位元素,这样我们就可以有水平和垂直的接近度?

散点图!

我们所需要的是为每个特征生成 X,Y 坐标的方法。完整的方法可在源代码中找到,总结如下:

  • 取相关矩阵的绝对值,从 1 中减去每个值。它被方便地转换成距离矩阵!
  • 然后,我们可以使用 PCA 将 NxN 矩阵减少到 Nx2。
  • 使用两个主要成分绘制每个特征的位置。
  • 利用特征集聚生成特征集群。
  • 根据聚类给每个要素着色。
  • 画线表示至少 r = 0.7 的关系。

特征空间图

下面的特征空间图(FSD)使用位置、颜色(对于聚类成员)和链接(对于强相关性)的组合来以互补的方式描述特征之间的关系。甚至一眼,我们就可以看出:

波士顿住房数据集的特征空间图。

  • CHAS 完全独立。
  • 大多数特性被集中到一个大的集群中,但是在这个集群中,一个核心集是紧密相关的。
  • 与相关矩阵相比,我们能够快速识别出 LSTAT 在与目标和许多其他特征相关中占据独特的位置,包括 RM ,否则它是独立的。

这是一个快速的洞察,对特征工程和选择非常有帮助。如果我们需要细节,我们可以在我们的相关矩阵中查找它们,把它放在适当的位置,作为一个查找工具。

按比例放大

波士顿住房数据非常小,所以相关矩阵和特征空间图更加匹配。但是 FSD 确实在更大的数据集上大放异彩。让我们看看乳腺癌数据集的 FSD,它有 30 列:

乳腺癌数据集的特征空间图

我们可以立即看到这些数据中有明显的特征聚类。橙色和棕色集群内部以及彼此之间有很强的相关性。红色聚类中的要素都离橙色聚类较远,并且彼此之间的相关性较弱。也有异常值,如平滑度 _ 最差,面积 _ 最差凹度 _ 平均值Radius_sd_error凹点 _ 均值奇怪的是相互关联,没有别的。

该数据由几种类型的测量值(半径、周长、对称性等)和为每种测量值计算的统计值(平均值、标准偏差、最差)组成。我们可以尝试回答的一个高级问题是,我们是否可以只使用每种度量类型的“平均值”,而抛弃其余的。换句话说,要素是按测量类型分类的吗?

具有用户提供的颜色映射领域知识的特征空间图

通过对特征到测量类型的颜色映射进行硬编码,我们可以很容易地找到答案!

没有。

有一些物理上相邻的测量类型,例如橙色的密实度 _。但是总的来说,度量类型在这里并不驱动相关性。

然而,这是一个很好的拒绝假设。如果我们已经将几个数据集合并在一起进行分析,并且现在想要确定它们的特征在多大程度上重叠,这种方法也会非常有帮助。只需给每个数据集中的变量赋予它们自己的颜色。

时间序列

我特别惊讶的是为癫痫发作识别上的时间序列数据集创建的 FSD。每个数据点由在一秒钟内进行的 178 次脑电图测量组成。我们想问的关于时间序列的第一个问题是是否有任何重复或循环的行为。

癫痫发作识别数据集的特征空间图

这个看起来有点像澳大利亚的斑点向我们展示了每个特征只与它的邻居相关(例如,前面和后面的时间片)。奇怪的形状来自 PCA 试图根据时间顺序将每个特征从其他特征中推开。

然而,我们如何解释所有的弯曲和花饰?我们可能有理由期望马尔可夫链看起来更像这样:

合成半随机马尔可夫链的特征空间图

换句话说,一个没有环的圆形。这暗示除了 5 个连续时间戳的每个块之间之外,在该数据集中还有其他相关性。让我们检查一下相关矩阵:

乍看之下,相关性矩阵提供了相同的故事——在每个点前后延伸 2-3 个时间戳的高度相关点的带,否则没有相关性。但如果我们仔细观察,可以看到两组与主线平行的微弱线条——一组在每个点前后约 17 个点,另一组在每个点前后约 35 个点。这个奇怪的视觉假象表明,在这个数据中有一个小的循环效应。在 FSD 中,我们甚至可以看到线条弯曲,使得 X18、X33 和 X49 尽可能地靠在一起,接近我们上面看到的趋势。相当酷!

结论

特征空间图是一种工具,它补充了相关性矩阵,并提供了定量特征之间相关性的更快概要。在本文中,我将展示如何使用它来揭示需要进一步研究的有趣关系。代码可从下面获得(或查看完整的笔记本此处),包括额外的配置和交互功能,包括:

  • 缩放和平移
  • 用于选择聚类数量的小部件
  • 更改显示相关线的 r 阈值的小部件
  • 显示集群数量和大小的图表
  • 能够传入用户定义的颜色方案,如上所示

功能空间图的完全交互式版本

脚注

有关该排序的完整实现,请参见对应的 R 包。
在本文的例子中,CHAS 布尔变量包含在相关矩阵中。尽管皮尔逊相关系数被编码为一个数字,但它不是为处理分类变量而设计的,因此在实践中不应该这样做。请参见预测能力评分以获得可处理任何类型变量的类似特征评分。

分层提取浓缩咖啡

原文:https://towardsdatascience.com/espresso-extraction-by-layer-fc2780335aee?source=collection_archive---------34-----------------------

垂直探索提取

在开发断奏镜头时,我注意到用过的咖啡层在镜头后保持分离。我决定弄干这些圆盘,看看每层的咖啡萃取量。我很好奇这将揭示什么,如果这可以告知如何提取一杯普通的浓缩咖啡。

这是提取后的断奏夯实镜头的顶层,看起来像海绵。

断续浓缩咖啡和断续捣实概述

断续浓缩咖啡的制作方法是将咖啡过筛,将过滤篮分层,底部是精细层,然后是粗糙层,最后是中间层。这是一个如何准备冰球的旧图(注意:我现在使用塑料分配器,不再使用回形针。我也不再使用黑色 OCD 风格的分配器)。

有时会有更多的层,这是由于通过 bean 分割精细层或添加一层 Robusta

从断续浓缩咖啡中,我得到了断续捣实,这里有两层不同的捣实压力,如下图所示:

断续浓缩咖啡层的一个例子:

干燥层

一个断奏夯实镜头的顶层看起来像一块海绵。一张断续浓缩咖啡照片的顶层看起来相似,但我没有照片。通常,你可以说这是通道,但在这种情况下,通道通常是穿过圆盘的。由于我在图层之间使用了纸质滤镜,这个不连贯的夯实的照片很容易被分割。纸过滤器是一种有效的方法,可以将照片分层,以了解咖啡是如何提取的。

我拿起每个冰球,把它们放在碗里或纸杯蛋糕架上。用一个碗,我测量了碗的起始重量。有了纸杯蛋糕托盘,我就把它当成了储藏室,在需要称重的时候用勺子把蛋糕渣刮出来。纸杯蛋糕托盘中剩余的粉末量不超过 0.05 克

咖啡壶放在柜台上大约需要一周的时间才能变干。它们可以在低温的烤箱里烤得更快,我偶尔会这么做,但这比把冰球放在托盘里等待需要更多的关注。

我拍了几张显示不同层次的照片。断奏圆盘的主要问题是中/粗层不能保持完整。正如你在照片中看到的,精细层保持完好无损。

小规模分析

我查看了测量提取率(EY)与测量提取干重的对比。

大多数镜头测量提取高于干重,但有可能一些水仍然保留,即使干燥后。

按层查看提取情况,细层比中/粗层提取更多。对于断续的夯实镜头(右边的两个),顶层的提取比底层高。断奏夯实击球的顶层和底层的主要区别在于夯实压力。

我对废弃的场地很好奇。如果中/粗层提取的咖啡较少,我想知道是否可以收集它们并重新研磨。我怀疑,即使是正常拍摄中的球场地面也很少被提取,你可以在拍摄后对它们进行筛选,并尝试重新打磨以进行新的拍摄。这种类型的实验至少可以让我们深入了解水到底有多深,咖啡能被提取出来。

总的来说,该测试表明较细的颗粒具有较高的提取率,但是密度在提取中起着很大的作用。我仍然认为萃取率随时间和粒度的变化是一个难以解开的谜,我希望这里或那里的小实验将有助于这种理解。

如果你愿意,可以在 Twitter 和 YouTube 上关注我,我会在那里发布不同机器上的浓缩咖啡视频和浓缩咖啡相关的东西。你也可以在 LinkedIn 上找到我。

我的进一步阅读:

解构咖啡:分割烘焙、研磨、分层以获得更好的浓缩咖啡

浓缩咖啡的预浸:更好的浓缩咖啡的视觉提示

咖啡的形状

搅拌还是旋转:更好的浓缩咖啡体验

香辣浓缩咖啡:热磨,冷捣以获得更好的咖啡

断续浓缩咖啡:提升浓缩咖啡

用纸质过滤器改进浓缩咖啡

浓缩咖啡中咖啡溶解度的初步研究

断奏捣固:不用筛子改进浓缩咖啡

浓缩咖啡模拟:计算机模型的第一步

更好的浓缩咖啡压力脉动

咖啡数据表

工匠咖啡价格过高

被盗浓缩咖啡机的故事

浓缩咖啡过滤器分析

便携式浓缩咖啡:指南

克鲁夫筛:一项分析

浓缩咖啡过滤器比较:佩萨多 vs VST

原文:https://towardsdatascience.com/espresso-filter-comparison-pesado-vs-vst-18a1321e62d?source=collection_archive---------24-----------------------

每个人一个样本,进行测试

我真的很喜欢我的 VST 过滤篮,但我有机会尝试一个 Pesado 过滤篮。它们由 IMS 制造,设计与普通 IMS 篮筐或 VST 篮筐略有不同。所以我做了一个月的对照实验,用相同的参数拍了两张照片,在 VST 和佩萨多之间交替。之前,我已经研究过 IMS 超细和VST 过滤器,但是我没有看到在味道、提取率和拍摄时间方面的任何一般性能差异。

左:佩萨多,右:VST

我的预期是一个过滤器会比另一个好,但我不确定是哪一个。我还分析了过滤篮本身,看看它们是否会给出哪个篮子会胜出的提示。我想也许会有一个更精确的洞或者有一个更好的空间分布。

最终,我将提前分享,我没有看到性能上的统计差异,也没有看到分析过滤孔本身时的任何指标。大警告是我只有一个 VST 过滤器和一个 Pesado 过滤器,它们很可能是这些公司过滤器的平均分布。

顶排:佩萨多,底排:VST

过滤分析

我使用图像分析来查看过滤孔,看看我是否看到任何重大差异。这包括在一个黑暗的房间里拍摄一张特写图像,将滤镜放在一个明亮的屏幕上。然后,我测量了每个洞的大小,并制作了一张图片,对洞的大小进行颜色编码,以寻找图案。

从上往下看:

左:佩萨多,右 VST

从底部成像:

左:佩萨多,右 VST

在使用相机校准测量孔时,平均尺寸存在差异,但标准偏差(每个孔相对于平均值的变化量)非常小。作为参考,非精密滤波器的标准偏差通常要大 3 倍。

绩效指标

我使用了两个指标来评估过滤器之间的差异:最终得分和咖啡萃取。

最终得分是 7 个指标(强烈、浓郁、糖浆、甜味、酸味、苦味和余味)记分卡的平均值。当然,这些分数是主观的,但它们符合我的口味,帮助我提高了我的拍摄水平。分数有一些变化。我的目标是保持每个指标的一致性,但有时粒度很难,会影响最终得分。

使用折射仪测量总溶解固体(TDS ),该数字用于确定提取到杯中的咖啡的百分比,并结合一杯咖啡的输出重量和咖啡的输入重量,称为提取率(EY)。

数据:成对拍摄

数据收集最简单的部分是我可以同时运行其他实验,只要每次两次拍摄之间的所有参数都相同。结果是在佩萨多和 VST 有 30 多对镜头。

首先,我比较了每一对照片,看看最终得分或 EY 是否有明显的趋势。有时 VST 做得更好,但有时佩萨多做得更好。对于这些图表,如果一个过滤器更好,值将更多地高于或低于沿 y=x 的黑线。

然后我通过咖啡烘焙分离出数据,因为也许过滤器在一些烘焙上比其他的表现得更好。但是,我没有看到数据中的趋势,如下图所示:

然后我整理了所有的数据,比较了使用佩萨多拍摄的最佳照片和使用 VST 拍摄的最佳照片。这不如成对样本好,但我想也许其中一个过滤器会做得更好。在这些排序对中,VST 的得分/EY 比佩萨多高,但那是在更少的样本上。此外,EY 的是低端,我不是完美的分布。在提取的较低端的大多数镜头是由于分布误差和环形图案。

查看相同数据的另一种方式是使用折线图,同样,在下端,它似乎表明 VST 略有优势。但我不会把钱押在这上面。

时间度量

由于我没有在《品味》或《EY》中看到任何可以区分它们的东西,我想我应该通过查看覆盖滤镜的时间(TCF) 和总时间来仔细检查拍摄时间。TCF 是我在其他情况下用来决定预浸何时结束以最大限度地提取和品尝的指标。我将这些时间指标与最终得分和 EY 进行了比较,因为如果一个过滤器更好,那么对于某个拍摄时间,它应该有更高的最终得分和 EY。

TCF 没有显示出这两种过滤器之间有多大的区别。

总拍摄时间也没有显示任何差异。从时间角度来看,考虑到 ey 和最终得分相似,这表明它们具有相似的流量。

就像之前与 IMS 超细过滤器的比较一样,我看不出 Pesado 和 VST 在性能上有什么不同。每个人都希望他们的过滤器是第一名,但我怀疑这将需要另一种类型的创新,以改善艺术的浓缩咖啡过滤篮。

这个测试的大警告是我每种只有一个样本。理想情况下,人们会希望收集控制所有其他变量的几个样本的数据。这当然需要更多的时间和金钱,但这将是一个有趣的实验,可以毫无疑问地证明谁制造的浓缩咖啡过滤器更好,或者一旦你达到一定的精度,过滤器就不那么重要了。

如果你愿意,请在 Twitter 和 YouTube 上关注我,我会在那里发布不同机器上的浓缩咖啡照片和浓缩咖啡相关的视频。你也可以在 LinkedIn 上找到我。

我的进一步阅读:

浓缩咖啡的预浸:更好的浓缩咖啡的视觉提示

咖啡的形状

搅拌还是旋转:更好的浓缩咖啡体验

香辣浓缩咖啡:热磨,冷捣以获得更好的咖啡

断续浓缩咖啡:提升浓缩咖啡

用纸质过滤器改进浓缩咖啡

浓缩咖啡中咖啡溶解度的初步研究

断奏捣固:不用筛子改进浓缩咖啡

浓缩咖啡模拟:计算机模型的第一步

压力脉动带来更好的浓缩咖啡

咖啡数据表

工匠咖啡价格过高

被盗浓缩咖啡机的故事

浓缩咖啡过滤器分析

便携式浓缩咖啡:指南

克鲁夫筛:分析

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/71821.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

一站实现高效开发,鸿蒙生态伙伴模板组件专区全新上线

10月8日,华为官方正式宣布,其最新操作系统HarmonyOS NEXT于当日10:08正式开启公测。 鸿蒙生态的发展离不开丰富的鸿蒙原生应用,为了有效提升开发者开发效率,降低开发成本,华为开发者联盟生态市场近日上线了“鸿蒙生态伙伴模板&组件专区”,汇聚官方及三方生态伙伴针对政务…

TowardsDataScience-博客中文翻译-2020-三-

TowardsDataScience 博客中文翻译 2020(三)原文:TowardsDataScience Blog 协议:CC BY-NC-SA 4.0做出更好决策的 3 个要素原文:https://towardsdatascience.com/3-essentials-to-make-better-decisions-9b2cdc60365e?source=collection_archive---------47---------------…

git怎么查看每次的提交记录控制台输出日志乱码

今天来和各位小伙伴分享一下怎么查看git的每次提交(commit)的记录: 1.打开idea ——2.点击做下加的git ——3.点击log ——4.选择自己的分支 ——5.查看每次提交的代码 二、控制台log4j输出的日志乱码: 解决办法: 1、将图中几处地方变为urf-8 2、

How to create a PDF programming cheat sheet All In One

How to create a PDF programming cheat sheet All In One 如何创建 PDF 编程备忘单 / 速查表How to create a PDF programming cheat sheet All In One如何创建 PDF 编程备忘单 / 速查表tools vscode pdf 编辑器 solutionsExport web page to pdf / 网页导出为 pdf优点:可以高…

基础靶场搭建

为什么要搭建靶场? 在我们后续的学习当中会涉及到漏洞的利用,那我们小白肯定是不能直接实操哒(如果你很刑就当我没说)所以就找了几个靶场进行搭建,我们这里搭建几个比较简单具有针对性的靶场进行练习后续更新完了十大漏洞,在上有难度的靶场😁😁😁 phpstudy搭建 201…

监控下抽烟检测系统

监控下抽烟检测系统具有以下优势:监控下抽烟检测系统通过视频监控设备对工地和工厂的作业区域进行实时监测,准确捕捉人员抽烟的行为。监控下抽烟检测系统采用先进的图像识别技术,能够准确识别人员抽烟的动作和烟雾。监控下抽烟检测系统一旦系统发现有人员在禁烟区域内抽烟,…

shiro 反序列化漏洞

shiro 反序列化漏洞 Shiro-550 漏洞原理 影响版本:Apache Shiro < 1.2.4 特征判断:返回包中包含rememberMe=deleteMe字段。 为了让浏览器或服务器重启后用户不丢失登录状态,Shiro 支持将持久化信息序列化并加密后保存在 Cookie 的 rememberMe 字段中,下次读取时进行解密…

人员闯入报警系统

人员闯入报警系统是一种应用于工厂危险作业区域、工地危险作业区域或者重要区域保护等场景的创新解决方案,人员闯入报警系统旨在通过实时监测和识别,对未经许可或非法进入的人员进行及时报警。人员闯入报警系统利用先进的感应与识别技术,确保对危险区域的安全管理和保护。人…