TowardsDataScience 博客中文翻译 2020(九十六)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

气流调度间隔 101

原文:https://towardsdatascience.com/airflow-schedule-interval-101-bbdda31cc463?source=collection_archive---------2-----------------------

气流调度间隔可能是一个很难理解概念,即使对于从事气流工作的开发人员来说也很难理解。StackOverflow 上偶尔会出现一个令人困惑的问题:“为什么我的 DAG 没有按预期运行?”。这个问题通常表明气流调度间隔中的误解。在本文中,我们将讨论如何设置气流调度间隔,调度气流 Dag 的预期结果,以及如何通过示例调试气流调度间隔问题。

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

来源:阿伦视觉来自 Unsplash

气流如何调度 DAGs?

首先,气流不是流式解决方案。人们通常把它作为 ETL 工具或 cron 的替代品。由于 Airflow 有自己的调度程序,并且它采用 cron 的调度时间间隔语法,因此 Airflow 调度程序中最小的数据和时间间隔是分钟。在调度程序内部,唯一持续运行的是调度程序本身。

然而,作为一个非流式解决方案,以避免锤你的系统资源,气流不会看,并触发你的 Dag 的所有时间。它以一定的时间间隔安排监控,这是一个名为scheduler_heartbeat_sec的可配置设置,建议您提供一个大于 60 秒的数字,以避免生产中出现一些意外结果。原因是 Airflow 仍然需要一个后端数据库来跟踪所有的进程,以防崩溃。设置更少的心跳秒数意味着 Airflow scheduler 必须更频繁地检查以查看是否需要触发任何新任务,这会给 Airflow scheduler 及其后端数据库带来更大的压力。

最后,气流调度器遵循心跳间隔,并遍历所有 DAG,计算它们的下一个调度时间,并与挂钟时间进行比较,以检查是否应该触发给定的 DAG。

为什么你需要一个开始日期?

每个 DAG 都有自己的时间表,start_date 就是 DAG 应该被包含在气流调度程序中的日期。它还有助于开发人员在 DAG 的生产日期之前发布它。你可以在气流 1.8 之前更动态地设置start_date 。但是,建议您设置一个固定的日期,更多详细信息可参考“动态 start_date 上的宽松调度程序”。

我们应该使用哪个时区?

气流基础设施最初仅从 UTC 开始。尽管您现在可以将 Airflow 配置为在您的本地时间运行,但大多数部署仍然采用 UTC。在 UTC 下设置气流使跨越多个时区的业务变得容易,并使您在夏令时等偶然事件中的生活更加轻松。您设置的计划间隔将与您的气流基础设施设置相同。

如何设置气流调度间隔?

您可能熟悉定义 DAG 的语法,并且通常在 DAG 类的args下实现start_datescheduler_interval

from airflow import DAG
from datetime import datetime, timedeltadefault_args = {
    'owner': 'XYZ',
    'start_date': datetime(2020, 4, 1),
    'schedule_interval': '@daily',
}dag = DAG('tutorial', catchup=False, default_args=default_args)

为 schedule_interval 提供什么值?

气流调度器部分提供了关于您可以提供什么值的更多详细信息。当然,你需要一个 crontab 来处理scheduler_interval。如果你发现自己迷失在 crontab 的定义中,尝试使用 crontab guru ,它会解释你放在那里的内容。气流也给你一些用户友好的名字,如@daily@weekly。我发现这些名字不如 crontab 简洁明了。它也仅限于几个时间间隔,底层实现仍然是 crontab,因此您甚至可能想要学习 crontab 并接受它。此外,如果你只是想触发你的 DAG,使用手动schedule_interval:None

execution_date 和 start_date 有什么区别?

作为调度程序,日期和时间是非常必要的组件。在《气流》中,有两个日期你需要付出额外的努力去消化:execution_datestart_date。注意start_date与您在之前的 DAG 中定义的日期不同。

  • execution_date 是您期望 DAG 被触发的 start 日期和时间。
  • start_date 是 DAG 被触发的日期和时间,这个时间通常是指挂钟。

一个常见的问题是,“为什么 execution_date 不同于 start_date?”为了得到这个问题的答案,让我们看看一个 DAG 的执行情况,并使用**0 2 * * ***,这有助于我们更好地理解气流计划间隔。请参考以下代码作为示例。

调度程序 101 DAG

**0 2 * * *** 意思是每天凌晨两点气流会开始新的工作。我们可以让具有此间隔的 DAG 运行多天。如果你点击BrowseTasks Instances,你会看到执行日期开始日期。

我在 04–10 00:05:21(UTC)启动了这个新的 DAG,任何新的气流 DAG 通常首先会进行回填,这是默认启用的。正如您在下面的快照中所看到的, execution_date 按照预期完美地按天递增,时间也是预期的。另一方面, start_date 是气流调度程序开始任务的时间。

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

任务实例示例(作者图片)

在回填了所有之前的执行之后,您可能会注意到 04–09 不在这里,但是现在已经是 04–10 挂钟了。这里出了什么问题?

答案是:没什么问题。

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

来源:托尼·巴贝尔来自 https://gph.is/2jqoiRI

首先,Airflow 是用 ETL 思维构建的,这通常是一个 24 小时运行的批处理。考虑一个 ETL 作业,在 24 小时的窗口内,只有在 24 小时结束后才触发作业。同样的规则也适用于此,我们没有看到 04–09 上的 execution_date 是因为 24 小时窗口尚未关闭。从 **execution_date,**我们知道最后一次成功运行是在 04–08t 02:00:00(记住 execution_date 这里是 24 小时窗口的开始时间),它结束于 04–09t 02:00:00(不含)。那么,04-09 运行的 24 小时窗口是什么呢?就是 04–09t 02:00:00 到 04–10t 02:00:00,还没到。

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

执行数据和开始日期的关系(图片由作者提供)

气流调度程序何时运行 04–09 执行?它会一直等到 04–10 02:00:00(挂钟)。一旦 04–09 的执行被触发,您将看到 execution_date 为 04–09t 02:00:00,而 start_date 将类似于 04–10t 02:01:15(这随着 Airflow 决定何时触发任务而变化,我们将在下一节中介绍更多)。

鉴于上述背景,你很容易明白为什么的执行日期的开始日期不同。理解执行日期开始日期之间的区别将会非常有帮助,当你尝试基于执行日期应用你的代码并使用类似{{ds}}的宏时

另一种思考方式是:执行日期将接近前一个**开始日期。我们用一个更复杂的例子:**0 2 * * 4,5,6** ,这个 crontab 的意思是周四周五周六 02:00 运行

下面是挂钟或开始日期的日历,红色文本是预计的执行日期。如果您有这样的计划间隔,那么对于气流会在 04–09 触发 04–04DAG 执行,您应该不会感到惊讶。

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

时间间隔示例(图片由作者提供)

为什么触发 Dag 会有短暂的延迟?

从上面的例子中,虽然我们发现日期不同,但时间略有不同。例如,对于每日间隔,执行日期为 04–09t 02:00:00,开始日期为 04–10t 02:01:15。气流对那 1.25 分钟的延迟有什么作用?

这类似于一个会议场景。你可能不会按照日历上的时间开始会议。比如,你有一个每周一上午 10:00:00 的虚拟会议邀请( scheduler_interval )。在本周一上午 10:00:00(execution _ date),您从日历提醒中收到加入会议的通知,然后您单击该会议链接并开始您的虚拟会议。当您进入会场,会议开始时,时间是上午 10:01:15(start _ date)。

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

来源:优 X 创投来自 Unsplash

您可能已经注意到了 execution_date 和 start_date 之间的小延迟。理想情况下,它们应该是相同的,但现实并非如此。问题是为什么气流不会按时触发 DAG 并延迟其实际运行?正如我们之前讨论的,气流调度器不会一直监控 Dag。调度程序等待其下一个心跳来触发新的 Dag,这一过程会导致延迟。此外,即使调度程序准备在同一时间触发,您也需要考虑代码执行和数据库更新时间。以上原因都会造成调度的短暂延迟。

最终想法

我希望这篇文章可以揭开气流调度间隔是如何工作的。气流是一个内部复杂的系统,但对用户来说很简单。按照最初的 ETL 思维方式,理解气流调度器如何处理时间间隔可能需要一些时间。一旦您更好地理解了气流调度间隔,创建具有期望间隔的 DAG 应该是一个无障碍的过程。

希望这个故事对你有帮助。本文是我的工程&数据科学系列的部分,目前包括以下内容:

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

赵承志

数据工程和数据科学故事

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

你也可以 订阅我的新文章 或者成为 推荐媒介会员 可以无限制访问媒介上的所有故事。

如果有问题/评论,请不要犹豫,写下这个故事的评论或者通过 LinkedinTwitter 直接联系我。

气流—在任务之间共享数据

原文:https://towardsdatascience.com/airflow-sharing-data-between-tasks-7bbaa27eeb1?source=collection_archive---------6-----------------------

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

作者图片

如果你在网上寻找气流教程,大多数都会给你很好的介绍什么是气流。他们将从概念上谈论 ETL,DAG 是什么,构建第一个 DAG 并向您展示如何执行它。经常被忽略的是 DAG 的任务应该如何交换数据。

本文假设你至少对什么是气流及其工作原理有一个基本的了解。

如果你在网上寻找气流教程,大多数都会给你很好的介绍什么是气流。他们将从概念上谈论 ETL,DAG 是什么,构建第一个 DAG 并向您展示如何执行它。

经常被忽略的是这些任务应该如何交换数据。

在构建任务时要记住的一点是,任务必须是幂等的。简化一下我们的例子,这意味着如果使用相似的输入参数执行成功,那么无论您调用它们多少次,它们都会产生相同的结果。当与任务输入/输出相结合时,这可能并不总是显而易见的。

当考虑数据交换时,我们可以区分以下任务:

  • 根本不需要共享数据
  • 只分享一小块信息
  • 运算符本身存储作为其执行结果的数据
  • 可以以存储结果的方式编写的运算符
  • 使用气流挂钩保存或读取结果的自定义操作员

不需要数据共享

这种任务关系的简单例子是在第一个任务中在数据库中创建一个表,并在下一个任务中填充该表。

这里最重要的是执行顺序。我们需要确保表存在,以便我们可以写入它。在我们的例子中,我们只需要确保第一个任务在第二个任务的上游,我们就可以开始了:

create_table.set_upstream(populate_table)

或者用我最喜欢的语法:

create_table >> populate_table

共享小块数据

在这里,达格的 XComs 开始发挥作用。它们易于使用,并允许在运行 DAG 的任何任务之间共享数据。它们被永久地保存在 Airflow 的元数据数据库中,但是我考虑在单个 DAG 之外使用它们作为反模式。

我听说过人们使用 XCom 在任务间共享大数据集的情况,这肯定是可能的,但由于一些原因应该避免。

首先,它破坏了元数据数据库,打破了气流是什么的概念——一个应该最低限度地参与执行和数据存储的编排器。

第二,不是所有的东西都可以储存。基本上,XCom 数据是泡菜,泡菜也有其局限性。

此外,有时 XComs 可能包含敏感数据,在决定将其存储在 Airflow 的数据库中之前,您应该三思而行。

应该记住的是,如果任务返回结果,那么这些结果将可用于下一个任务的“拉取”。不幸的是,您知道它们是否返回结果的唯一方法是深入研究 Operator 的源代码(我强烈推荐这种方法,因为它将极大地提高您对气流如何工作的理解)。

我不知道使用 XCom 共享的数据的最大大小应该是多少,但是我想说,如果它能加速 DAGs 的开发,那么几 MB 是可以的。或者换句话说,如果你的任务的结果没有内置的结果“存储”,你会觉得懒惰🙂要编写单独的操作符,您可以考虑将其推送到 XCom。

具有“本地”结果存储的操作员

很容易知道 operator 是否会存储它的执行结果,因为它是传递给 operator 类的参数之一。这里的示例是“BigQueryExecuteQueryOperator ”,其中查询输出被保存到另一个表中:

execute_query = BigQueryExecuteQueryOperator(
    task_id="execute_query_save",
    sql="SELECT * FROM MY_DATASET.TABLE_IN",
    use_legacy_sql=False,
    destination_dataset_table="MY_DATASET.TABLE_OUT")

为了使用结果,流水线中的下一个任务必须到达 TABLE_OUT。

可以被“强制”存储数据的操作员

假设我们的操作符没有等效的“destination_dataset_table”参数。

当然,您可以通过继承“BigQueryExecuteQueryOperator”来编写自己的操作符,但有时更简单的选择是编写您的查询,以便将结果存储在某个地方。类似于:

INSERT INTO TABLE_OUT
SELECT <columns> FROM TABLE_IN

自定义操作员读/写

如果你运气不好,剩下的就是使用气流的钩子来完成这项工作。该选项既可用于写入任务的结果数据,也可用于在下一个必须使用它的任务中读取数据。是的,这意味着您必须编写一个自定义任务,例如如下所示:

def load_data(ds, **kwargs):
    conn = PostgresHook(postgres_conn_id=src_conn_id).get_conn() # Notice: cursor had to be named to make loading in batches work      (so called "server cursor")
    cursor = conn.cursor('serverCursor')
    cursor.execute(kwargs['query']) while True:
        records = cursor.fetchmany(size=10000)
        if not records:
            break
        *[ ... do something with records ...]* cursor.close()
    conn.close()

并使用例如“PythonOperator”来执行它:

load_and_transform = PythonOperator(task_id='load_and_transform',
    python_callable=load_data,
    op_kwargs={'query': 'SELECT * FROM TABLE_IN'},
    provide_context=True,
    dag=your_dag)

我希望这些简单的技巧能帮助你写出更可靠的任务。

旁注:如果你正在寻找在任务间传递数据时更友好的工具,可以看看与 Airflow 有很多相似之处的 impfect . io,并尝试修复 Airflow 的错误。请记住,使用它并不是完全免费的。

气流状态 101

原文:https://towardsdatascience.com/airflow-state-101-2be3846d4634?source=collection_archive---------15-----------------------

阿帕奇气流状态概述

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

(图片由 Unsplash 上的 Zbynek Burival 拍摄)

在 Airflow 中,为了描述等待执行后续步骤的 DAG 或任务的状态,我们定义了 State 来共享有关管道进度的信息。如果没有状态,任何 DAG 或任务的执行都会变成黑盒,您可能需要创建额外的外部标志或资源来检查状态,以帮助确定作业是完成还是失败。幸运的是,Airflow 提供了状态机制,并将最近记录的每个状态存储在其后端数据库中。这种方式不仅易于在 Airflow UI 或 DB 中查看任何作业的状态,而且它还是一个持久层,有助于在遇到故障时重新运行或回填。

在本文中,我们将讨论什么是气流状态,这些状态有哪些类型,如何使用气流状态进行测试和调试。可能有外部服务,气流也可能跟踪这些状态,但这些状态不在我们讨论的范围内。

国家在气流中做什么?

现实生活中状态的一个很好的例子就像交通灯。你会有三种状态:红色、黄色和绿色。红灯禁止任何车辆通行,而绿灯允许车辆通行。

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

走红绿灯(Gif By SPAR

气流状态的最基本用法是指定当前状态,并指定气流调度程序来决定未来的动作。虽然气流有更多的状态,类似于红绿灯,但也有一些共同的特征。

  • 没有双重状态。在气流中,状态是单个值。不允许双重状态。这样,一个同时有“Failed”和“UP_FOR_RETRY”的状态在这里就没有太大意义了。
  • 状态是静态的,或者是给定时刻的快照。Airflow 将状态保存在其后端数据库中,并且状态的更新不是一个连续的过程。由于 Airflow 调度程序的心跳间隔,您可能会遇到数据库中的状态更新滞后,调度程序停止运行的罕见情况。
  • 状态有一个定义的生命周期。气流库中有详细的生命周期图。状态必须遵循生命周期的流程,除了重试的情况,状态通常不能后退。

那些状态是什么?我什么时候能见到他们?

对于当前版本的气流 1.10.11,气流中的状态有两个主要类别:任务和运行。

  • Dagrun:成功,正在运行,失败;
  • 任务:成功、正在运行、失败、上游失败、已跳过、启动重试、启动重新计划、排队、无、已计划。

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

气流任务等级状态(作者供图)

DAG 是任务的集合;DAG 的状态就像你家里的主电源开关。如果它失败了,即使您让它的任务继续运行,气流调度程序也会忽略它,因为 dagrun 的状态是 failed。

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

DAG 级别的状态就像主电源开关(Ariel Victor 的黑白动画 GIF)

任务级别的状态处于更细粒度的级别,因为任务之间可能存在依赖关系。一些状态可能有多个连续的状态,这就是为什么在任务级别有更多的状态来处理更复杂的情况。例如,upstream_failed 表示当前任务由于上游失败而无法执行。

查看状态的另一种方式是查看状态是已完成还是未完成。完成状态意味着气流调度程序将不再监控它们,因此它不在调度和监控的范围内。另一方面,对于未完成状态,那些是待定状态,对于当前未完成状态将有即将到来的改变,但是最终目标是达到完成状态。

至于现在,已完成的状态是 SUCCESS,FAILED,UPSTREAM_FAILED(注意这一个在已完成状态列表中没有提到),和 SKIPPED,其余都是未完成状态。

让我们更详细地检查每个状态并进行讨论。

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

成功状态

成功 (在 dagrun 和任务级别|完成状态下):成功状态表示气流在运行作业时没有遇到任何错误,并且成功完成。在气流中,dagrun 有一个深绿色的圆圈,任务等级有一个深绿色的方块。即使对于一个虚拟任务,因为没有任何错误,虽然气流在这里没有执行任何有意义的事情,但它仍然会将虚拟任务视为成功,因为我们告诉气流不要运行任何东西,气流应该会将成功返回给我们。

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

运行状态

正在运行 (在 dagrun 和任务级别|未完成状态状态中):正在运行状态确定气流调度器已经将那些 dag 或任务分配给执行器。它正在监视(通过心跳)它的状态,执行器正在运行实际的作业。在气流中,dagrun 有一个浅绿色的圆圈,任务等级有一个浅绿色的方块。由于运行是一种未完成状态,因此在任何给定时间,您的 dag 或任务都可能失败,然后会导致重试或失败状态。此外,在任务级别,当给定的任务仍在运行时,如果您重新运行任务本身(通过清除其状态),有时气流调度程序会进入关闭状态,这是关闭和终止任务的外部请求。

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

失效状态

失败 (在 dagrun 和任务级|完成状态下):失败状态向用户指出在执行期间出现了问题,气流无法调度执行到底。在气流中,dagrun 有一个红圈,任务等级有一个红方块。由于气流中没有双重状态,对于部分成功,dagrun 仍然会标记为失败,以便用户进一步探索。另一方面,在任务层,Airflow 标记了确切的失败任务,并且该任务的所有下游都标记为 UPSTREAM_FAILED(如果 trigger_rule 默认为 all_success ),这很好地帮助用户立即找到失败的最初原因。

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

上游 _ 失败状态

UPSTREAM_FAILED *(仅限任务级|完成状态):*上游失败状态是指上游发生了一些错误的状态。您也可以有多个上游,在这种情况下,您可以考虑 trigger_rule ,它默认为 all_success 。在这种情况下,如果任何上游任务失败,就会得到 UPSTREAM_FAILED。然而,如果你不想有这种行为,气流提供了更多的选项,例如,你可以做 *one_success,*如果只有一个上游任务是成功的,它将继续当前的任务。

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

跳过状态

跳过 *(仅限任务级|完成状态):*跳过状态是已经被忽略执行的任务,调度器绕过该任务继续执行。在分支操作中,跳过一个任务通常是一种预期的行为,您有多个条件可以选择,一旦决定了其中的一些,未选择的将被标记为跳过。您还可以在不使用分支运算符的情况下明确标记跳过的任务,这涉及手动设置气流状态。每当您跳过一个任务时,它的所有下游任务也会被跳过。

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

启动重试状态

UP_FOR_RETRY (仅任务级|未完成状态):UP _ FOR _ RETRY 状态表示之前的尝试已经失败,因为该任务已经重试了多次,它被标记为准备重试。但是在下一次迭代中,任务需要等待多长时间才能重试呢?气流调度程序在重试时间间隔过后等待,并在下一个调度程序的心跳到达时启动。

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

启动重新计划状态

UP _ FOR _ schedule*(仅任务级|未完成状态)*:UP _ FOR _ schedule 是自 Airflow 1.10.2 以来新引入的状态,更多细节可以参考 Apache Airflow 1.10.2 新版本中的亮点。这种状态主要适用于传感器,它有助于避免消耗所有工作插槽,以便解决死锁情况。

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

排队状态

排队 (仅任务级|未完成状态):当任务等待执行器中的槽时,触发队列状态。队列状态只是一个等待执行程序在管道中执行簿记的列表,执行程序将任务分配给工作程序来运行实际的任务。一旦一个槽可用,就从队列中拉出一个任务(有优先级),工人将运行它。

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

无状态

(仅任务级|未完成状态):无状态可能会引起混淆,因为它在某些语言中表示未知。这里它只是一种描述新任务创建的方式,它的初始状态是未知的。当一个新的 dagrun 启动时,您会观察到 None 状态,它的所有任务首先都是 None。此外,如果您想要重新运行某些 Dag 或任务,一旦您清除了状态,所有这些状态都将变为 None 状态。在后端,如果是第一次启动 dagrun,尽管所有任务都处于 NONE 状态,但在任务被调度之前,您不会在 DB 中找到任何条目。然而,重新运行一个任务来清除它的状态是另一回事,在重新运行之前,您会在 DB 中找到它以前的状态。

已调度 *(仅限任务级|未完成状态)*已调度状态是让气流将任务发送给执行者运行。气流调度程序检查多种条件,以确定是否可以调度任务。例如,由于整个气流中的可用时隙,以及挂钟时间和计划时间之间的时间,任务可以被阻止进行计划。一旦满足了调度的所有条件,气流调度器就会将任务推进到调度状态。

一个令人兴奋的功能是改变气流用户界面的颜色。如果你不喜欢默认的,这个新特性是在 Airflow 1.10.11 中引入的,你可以在 UI 中自定义状态颜色

气流任务状态的生命周期

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

气流任务生命周期图(来自阿帕奇气流

该状态由气流调度器和执行器驱动和控制。Airflow 官方 GitHub 有这个生命周期图,很好地展示了状态流程图。我们已经讨论了每个状态和传感器的状态(UP _ FOR _ RESCHEDULE)。此图还显示了每个组件的可能状态列表。可选阶段转换是每个气流操作器的选项,由用户控制以可选地执行重试。尽管如此,所有其他阶段都必须遵循这个转换流程。

最终想法

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

五彩缤纷的国家(照片由汉娜·摩根Unsplash 上拍摄)

状态是气流生态系统中不可或缺的元素。状态就像气流中的安全带。它对每个 dagrun 和任务进行跟踪,每当 Airflow 调度器、执行器或工作器中出现崩溃时,状态会作为检查点执行,因此我们不必从头开始。此外,由于状态也显示在 Airflow UI 中,每个人都将其作为监控状态的中心位置。最后,Airflow 在内部使用状态来跟踪任务的进度,工程师可以依靠状态来执行更多定制的任务。我希望这篇文章能给你一个气流状态的基本概念,以及为什么理解每种状态之间的区别是必要的。干杯!!

希望这个故事对你有帮助。本文是我的工程&数据科学系列的部分,目前包括以下内容:

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

赵承志

数据工程和数据科学故事

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

你也可以 订阅我的新文章 或者成为 推荐媒介会员 无限制访问媒介上的所有故事。

如果有问题/评论,请不要犹豫,写下这个故事的评论或通过 LinkedinTwitter 直接联系我。

气流 vs .路易吉 vs .阿尔戈 vs. MLFlow vs .库伯流

原文:https://towardsdatascience.com/airflow-vs-luigi-vs-argo-vs-mlflow-vs-kubeflow-b3785dd1ed0c?source=collection_archive---------10-----------------------

选择任务编排工具

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

来源:作者

任务协调工具和工作流

最近,用于编排任务和数据工作流的新工具激增(有时被称为“MLOps”)。这些工具的数量会使我们很难选择使用哪些工具,也很难理解它们是如何重叠的,所以我们决定直接比较一些最流行的工具。

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

气流是最受欢迎的解决方案,其次是 Luigi。也有新的竞争者,他们都在快速成长。(来源:作者)

总的来说,Apache Airflow 是最受欢迎的工具,也是功能最广泛的工具,但是 Luigi 是一个类似的工具,更容易上手。当他们已经在使用 Kubernetes 时,Argo 是他们经常求助的一个团队,Kubeflow 和 MLFlow 服务于更多与部署机器学习模型和跟踪实验相关的利基需求。

在我们深入进行详细的比较之前,理解一些与任务编排相关的更广泛的概念是有用的。

什么是任务编排,为什么它有用?

较小的团队通常从手动管理任务开始,例如清理数据、训练机器学习模型、跟踪结果以及将模型部署到生产服务器。随着团队和解决方案规模的增长,重复步骤的数量也在增长。可靠地执行这些任务也变得更加重要。

这些任务相互依赖的复杂方式也在增加。当您开始时,您可能有一个需要每周或每月运行一次的任务流水线。这些任务需要以特定的顺序运行。随着你的成长,这条管道变成了一个拥有动态分支的网络。在某些情况下,一些任务会引发其他任务,而这些任务可能依赖于其他几个先运行的任务。

这个网络可以被建模为 DAG——一个有向无环图,它对每个任务以及它们之间的依赖关系进行建模。

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

流水线是一个有限的 DAG,其中每个任务最多有一个上游和一个下游依赖。(来源:作者)

工作流编排工具允许您通过指定所有任务以及它们如何相互依赖来定义 Dag。然后,该工具按计划以正确的顺序执行这些任务,在运行下一个任务之前重试任何失败的任务。它还监控进度,并在出现故障时通知您的团队。

像 Jenkins 这样的 CI/CD 工具通常用于自动测试和部署代码,这些工具和任务编排工具之间有很强的相似性——但也有重要的区别。尽管理论上你可以使用这些 CI/CD 工具来编排动态的、相互关联的任务,但是在一定的复杂程度上,你会发现使用更通用的工具比如 Apache Airflow 会更容易。

【想要更多这样的文章?注册我们的简讯。我们每周最多分享一篇文章,从不发送任何形式的推广邮件】。

总体而言,任何编排工具的重点都是确保集中化、可重复、可再现、高效的工作流:所有自动化任务的虚拟指挥中心。记住这一点,让我们看看一些最流行的工作流工具是如何组合起来的。

告诉我用哪一个

您可能应该使用:

  • Apache air flow如果你想要功能最全、最成熟的工具,你可以花时间去学习它的工作原理、设置和维护它。
  • Luigi如果你需要比气流更容易学习曲线的东西。它的功能更少,但更容易起飞。
  • 如果你已经深深地投入到 Kubernetes 生态系统中,并且想要以 pods 的形式管理你的所有任务,那么就用 YAML 而不是 Python 来定义它们。
  • kube flow如果你想使用 Kubernetes 但仍然用 Python 而不是 YAML 来定义你的任务。
  • MLFlow 如果你更关心跟踪实验或者使用 MLFlow 的预定义模式跟踪和部署模型,而不是寻找一个可以适应你现有定制工作流的工具。

对照表

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

(来源:作者)-获得更多机器学习技巧— 获取我们的每周简讯

为了快速概述,我们在以下方面对这些库进行了比较:

  • ****成熟度:基于项目的年龄以及修复和提交的数量;
  • ****人气:基于领养和 GitHub 明星;
  • ****简单:基于易于入职和采用;
  • ****广度:基于每个项目的专业化程度和适应性;
  • ****语言:基于您与工具交互的主要方式。

这些不是严格或科学的基准,但它们旨在让您快速了解这些工具是如何重叠的,以及它们彼此之间有何不同。更多细节,请看下面的头对头对比。

路易吉与气流

Luigi 和 Airflow 解决类似的问题,但 Luigi 要简单得多。它包含在单个组件中,而 Airflow 有多个模块,可以以不同的方式进行配置。Airflow 拥有更大的社区和一些额外的功能,但是学习曲线要陡峭得多。具体来说,Airflow 在调度方面要强大得多,它提供了一个日历 UI 来帮助您设置任务应该何时运行。使用 Luigi,您需要编写更多自定义代码来按计划运行任务。

这两个工具都使用 Python 和 Dag 来定义任务和依赖关系。如果你有一个小团队,需要快速上手,就用 Luigi。如果你有一个更大的团队,可以使用气流,一旦你度过了学习曲线,可以用最初的生产力打击来换取更多的权力。

路易吉对阿尔戈

Argo 建立在 Kubernetes 之上,每个任务作为一个独立的 Kubernetes pod 运行。如果您已经将 Kubernetes 用于您的大部分基础设施,这可能很方便,但是如果您没有,这将增加复杂性。Luigi 是一个 Python 库,可以和 Python 包管理工具一起安装,比如 pip 和 conda。Argo 是 Kubernetes 的扩展,使用 Kubernetes 安装。虽然这两个工具都允许你将任务定义为 Dag,但使用 Luigi,你将使用 Python 来编写这些定义,而使用 Argo,你将使用 YAML。

如果你已经投资了 Kubernetes,并且知道你所有的任务都是 pods,那么就使用 Argo。如果编写 DAG 定义的开发人员对 YAML 比对 Python 更熟悉,您也应该考虑这一点。如果您没有在 Kubernetes 上运行,并且团队中有 Python 专家,请使用 Luigi。

路易吉对库伯弗洛

Luigi 是一个基于 Python 的库,用于一般的任务编排,而 Kubeflow 是一个基于 Kubernetes 的工具,专门用于机器学习工作流。Luigi 是为编排一般任务而构建的,而 Kubeflow 则为实验跟踪、超参数优化和 Jupyter 笔记本服务提供了预构建的模式。Kubeflow 由两个不同的组件组成:Kubeflow 和 Kubeflow 管道。后者侧重于模型部署和 CI/CD,它可以独立于主要的 Kubeflow 特性使用。

如果您需要编排各种不同的任务,从数据清理到模型部署,请使用 Luigi。如果您已经使用了 Kubernetes,并且想要协调常见的机器学习任务,如实验跟踪和模型训练,请使用 Kubeflow。

Luigi vs. MLFlow

Luigi 是一个通用的任务编排系统,而 MLFlow 是一个更专业的工具,可以帮助管理和跟踪你的机器学习生命周期和实验。您可以使用 Luigi 来定义一般的任务和依赖项(例如训练和部署模型),但是您可以将 MLFlow 直接导入到您的机器学习代码中,并使用它的帮助器函数来记录信息(例如您正在使用的参数)和工件(例如经过训练的模型)。还可以使用 MLFlow 作为命令行工具,为用常用工具(如 scikit-learn)构建的模型提供服务,或者将它们部署到常用平台(如 AzureML 或 Amazon SageMaker)。

气流与阿尔戈

Argo 和 Airflow 都允许你将任务定义为 Dag,但是在 Airflow 中你用 Python 来完成,而在 Argo 中你用 YAML。Argo 作为一个 Kubernetes pod 运行每个任务,而 Airflow 生活在 Python 生态系统中。Canva 在选择 Argo 之前评估了这两个选项,您可以观看这个演讲,了解他们的详细比较和评估

如果你想要一个更成熟的工具,不在乎 Kubernetes,就用气流。如果您已经投资了 Kubernetes,并且想要运行在不同堆栈中编写的各种各样的任务,请使用 Argo。

气流与库伯流

Airflow 是一个通用的任务编排平台,而 Kubeflow 则专门专注于机器学习任务,如实验跟踪。这两个工具都允许使用 Python 定义任务,但是 Kubeflow 在 Kubernetes 上运行任务。Kubeflow 分为 Kubeflow 和 Kubeflow 管道:后一个组件允许您指定 Dag,但它更侧重于部署和模型服务,而不是一般任务。

如果您需要一个能够运行各种不同任务的成熟、广阔的生态系统,请使用 Airflow。如果您已经使用了 Kubernetes,并希望机器学习解决方案有更多现成的模式,请使用 Kubeflow。

空气流量与毫升流量

Airflow 是一个通用的任务编排平台,而 MLFlow 是专门为优化机器学习生命周期而构建的。这意味着 MLFlow 具有运行和跟踪实验、训练和部署机器学习模型的功能,而 Airflow 具有更广泛的用例,你可以使用它来运行任何一组任务。Airflow 是一组用于管理和调度任务的组件和插件。MLFlow 是一个 Python 库,可以导入到现有的机器学习代码中,也是一个命令行工具,可以用来训练和部署用 scikit-learn 编写的机器学习模型到 Amazon SageMaker 或 AzureML。

如果您想要一种有见解的、开箱即用的方式来管理您的机器学习实验和部署,请使用 MLFlow。如果您有更复杂的需求,并且希望更多地控制如何管理机器学习生命周期,请使用 Airflow。

阿尔戈对库伯弗洛

Kubeflow 的部分(如 Kubeflow 管道)是建立在 Argo 之上的,但 Argo 是为了编排任何任务而建立的,而 Kubeflow 专注于那些特定于机器学习的任务——如实验跟踪、超参数调整和模型部署。 Kubeflow Pipelines 是 Kubeflow 的一个独立组件,专注于模型部署和 CI/CD,可以独立于 Kubeflow 的其他功能使用。这两个工具都依赖于 Kubernetes,如果你已经采用了它,你可能会更感兴趣。有了 Argo,你可以使用 YAML 定义你的任务,而 Kubeflow 允许你使用 Python 接口。

如果您需要管理作为 Kubernetes pods 运行的一般任务的 DAG,请使用 Argo。如果你想要一个专注于机器学习解决方案的更有主见的工具,请使用 Kubeflow。

Argo vs. MLFlow

Argo 是一个任务编排工具,允许您将任务定义为 Kubernetes pods,并将其作为 YAML 定义的 DAG 运行。MLFlow 是一个更加专业化的工具,它不允许您定义任意的任务或它们之间的依赖关系。相反,您可以将 MLFlow 作为 Python 库导入到现有的(Python)机器学习代码库中,并使用其助手函数来记录工件和参数,以帮助进行分析和实验跟踪。您还可以使用 MLFlow 的命令行工具来训练 scikit-learn 模型,并将它们部署到 Amazon Sagemaker 或 Azure ML,以及管理您的 Jupyter 笔记本。

如果您需要管理一般的任务,并希望在 Kubernetes 上运行它们,请使用 Argo。如果您想要一种自以为是的方式来管理托管云平台的机器学习生命周期,请使用 MLFlow。

Kubeflow 与 MLFlow

Kubeflow 和 MLFlow 都是比通用任务编排平台(如 Airflow 或 Luigi)更小、更专业的工具。Kubeflow 依赖于 Kubernetes,而 MLFlow 是一个 Python 库,可以帮助你在现有的机器学习代码中添加实验跟踪。Kubeflow 允许您构建一个完整的 DAG,其中每个步骤都是一个 Kubernetes pod,但 MLFlow 具有内置功能,可以将您的 scikit-learn 模型部署到 Amazon Sagemaker 或 Azure ML。

如果你想跟踪你的机器学习实验,并在 Kubernetes 的支持下以更加定制的方式部署你的解决方案,请使用 Kubeflow。如果您想要一种更简单的方法来进行实验跟踪,并希望部署到 Amazon Sagemaker 等托管平台,请使用 MLFlow。

没有银弹

虽然所有这些工具都有不同的关注点和不同的优势,但是没有一个工具能够让您一劳永逸。在为选择哪种工具伤脑筋之前,通常重要的是确保你有好的过程,包括好的团队文化、无过失回顾和长期目标。如果你正在努力解决任何机器学习问题,请联系我们。我们喜欢谈论商店,您可以安排与我们的首席执行官进行免费通话。

航空业——预计复苏

原文:https://towardsdatascience.com/airline-industry-and-air-canada-stock-prediction-using-deep-learning-c92da3908a3b?source=collection_archive---------57-----------------------

使用深度学习和 DCF 预测加拿大航空公司未来三年的股价

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

伊森·麦克阿瑟在 Unsplash 上的照片

自从全球范围内的封锁和独特的冠状病毒的传播开始以来,全球的航空业一直不景气。

最近,也有很多关于沃伦巴菲特出售他在各航空公司的股份的新闻。与他的行动相反,价值投资者正在鼓励许多人持有航空公司股票,尤其是那些具有长期投资眼光和风险偏好的股票。

接二连三的新闻激起了我的兴趣,我决定进行一些自己的测试来验证我所看到和听到的新闻。

为了更好地理解(在个人层面)航空业和加拿大航空公司的表现,我研究了加拿大的飞机运行情况,使用 LSTM 模型预测加拿大航空公司的未来股票价格,并最终使用贴现现金流(DCF)法得出内在股票价值。

预测加拿大的飞机动向

我从 Stat Canada 收集了从 2015 年 1 月(主要机场)到 2020 年 4 月的飞机起降数据,并进行整理。随后,我在 2018 年 7 月创建了一个与飞机移动相关的指数,因为这是最高的数字-这将使我能够衡量未来牛市中飞机移动的水平。

首先,我创建了一年中所有十二个月的月平均值,并用它来创建每个月的季节性指数(即一个月的月平均值/所有月份的平均值)。然后,我计算了每个月的平均飞机力矩(指数值),并检查了这些值与 2020 年 1 月至 5 月受影响月份的“covid”值之间的差异。2020 年 4 月的指数值为 10,这与航空公司在受 covid 影响的月份削减 85-90%运力的报告相关。

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

4 月份的产能仅为“历史最佳月份”的 10%

此外,我假设 covid 以及国际旅行限制和封锁的影响将开始显现——至少在 2020 年 6 月底之前对企业和其他重要的经济驱动因素而言。考虑到飞机将不得不接受维护检查,飞行员将不得不在服役前重获“货币”,我将指数差向下调整了 2.5 点,以迎合保守的增长估计。

我的目的是预测价值,直到完成一个稳定的商业周期,因为这将表明飞机活动的正常化。

我发现飞机活动在 2022 年 5 月达到“covid 之前”的水平,并在 2023 年 12 月底稳定下来。

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

通过 Python 预测未来股票价格

我在 Python 中使用了一个简单的单变量 LSTM 模型来预测加拿大航空公司的未来价格(直到 2023 年 12 月)。在这里找到笔记本(你可以上传自己的数据集来运行测试)。

在航空业面临 9/11 事件的影响期间,我在航空公司股票的数据集上训练并验证了该模型。我选择这个数据集有两个原因。首先,这类似于现在的情况,顾客/公众害怕坐飞机。其次,这些年来,航空业受到了几乎是不可抗力的最严重打击,这导致了世界飞行方式的改变,引入了各种安全法规和检查。由于这将允许必要的业务增长延迟,我认为这将有助于预测更适合后 covid 经济,后者可能面临类似的限制。

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

红色-股票价格|蓝色-飞机运动

结果表明,加拿大航空公司的股价将在 2023 年 12 月徘徊在 16 美元,这是在经济稳定和复苏之后。

此外,为了衡量加拿大航空公司股票的当前价格,我使用了基本的现金流量贴现法(WACC-5.7%,EV/EBITDA-6x)和格拉汉姆法(TTM 每股收益,调整以反映当前 AAA 债券收益率,增长率为 4%)来计算加拿大航空公司股票的内在价值。

相应计算的内在价值为 9.90 美元和 12.3 美元。Python 模型预测底部为 3.5 美元,然后再次向上移动。

结果和解释

经济— 假设飞机起降代表了航空业的健康(航空业反过来代表了经济的健康),由于大多数旅行都是通过可自由支配的资金进行的,因此经济似乎将在 2021 年第三季度稳定增长,并将在 2022 年第三季度达到 Q2 之前的水平,然后在 2024 年 Q1 完全稳定。有趣的是,国际航空运输协会——一个全球航空公司协会预测,乘客需求将在 2024 年前才会恢复,这有点类似于我的模型对 2023 年 12 月的预测。

航空业— 虽然模型已经以相当初步的方式完成,但航空业似乎将需要三年的大部分时间来恢复。此外,观察消费者行为的变化以及它将如何影响航空旅行也是很有趣的,因为这将在很大程度上影响旅游和酒店业的未来。在目前裁员和储存飞机之后,航空公司如何扩大业务规模以满足更高的需求,也是一个有趣的问题。在长期裁员(通常为 6 个月)后,对飞机和机组人员进行各种检查和重新培训,将需要航空公司不断感受经济的脉搏,以便他们能够计划机组人员培训和飞机维护检查,以利用几年后的周期高峰。

加拿大航空股票— 根据最近收盘价(2020 年 5 月 15 日 14.62 美元),与通过 DCF 和格雷厄姆方法得出的内在价值平均值相比,加拿大航空股票被高估了 35%。这也许解释了为什么以发现价值股闻名的沃伦·巴菲特在今年早些时候抛售了他的航空公司股票。因此,除非你的投资期限是 7-10 年,并且很年轻/或者有很高的风险偏好,否则航空股(至少是加拿大航空)似乎是一个赔本买卖。

我想澄清的是,用于预测的方法和假设没有考虑到各种细微差别。所有观点/意见都是我个人的,所做的工作只是为了帮助我自己更好地理解疫情对经济的影响。此外,不能孤立地看待通过机器学习和 DCF 估值进行的预测。

人工智能与人类的共存以及为什么我们都应该关注它

原文:https://towardsdatascience.com/ais-coexistence-with-humans-and-why-we-should-all-be-concerned-37a8cc444600?source=collection_archive---------43-----------------------

对李开复《人工智能的超能力》的再思考

我们离完全的 AI 共存还有多远?

:这篇文章很大程度上是受李开复的‘AI 超能力’的启发,加上我个人的一些想法。许多观点是从他的书中摘录的,任何发现的相似之处都是有意的。

作为一名人工智能的学生、实践者和倡导者,我很幸运能够一窥人工智能技术在表面之下是如何工作的,并且在一定程度上也让我想象人工智能不仅在现在,而且在未来会有什么样的可能性。

对于普通人来说,人工智能被视为一种有可能在不同工作领域取代人类的技术,而且这种取代已经开始。然而,他们没有看到的是,人类和整个社会将在多大程度上受到人工智能革命的影响,就像工业革命和互联网繁荣如何戏剧性地改变了我们的生活方式一样。

让我感到害怕的是,如果人们继续忘记人工智能到底是什么以及它能做什么,郝在所谓的“人工智能精英”与世界其他人(她认为是“无用”的人)之间的反乌托邦世界可能会成为现实。

作为一名未来学家,我认为在过渡到人工智能驱动的世界时,每个人都应该意识到这一点。

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

来源:来自 istockphoto 的 BahadirTanriover

有了今天的人工智能技术,很大一部分工作将会、能够并且已经被取代

蒸汽机、缝纫机、电的发明都取代了工作。我们已经克服了。人工智能的挑战在于,这 40%,无论是 15 年还是 25 年,都比以前的革命来得更快。”

—李开复

上面的引用概括了 Lee 对我们目前生活的这场人工智能革命的预言——在未来 15 到 25 年内,世界上 40%的工作将被人工智能技术取代,关键的区别在于这种取代的变化率。

人工智能革命——第三次工业革命?

在人类历史上,我们从第一次工业革命中幸存了下来——这是一次向新制造工艺的大规模过渡,彻底改变了商品的生产方式。随后,我们在第二次工业革命中蓬勃发展,也被称为技术革命,这是一个商品和服务快速标准化和工业化的阶段,包括铁路网络、污水处理系统、电气化、海运、汽车等领域。

许多人现在将我们生活的时代称为人工智能革命,也可能是我们(未来)的孩子可能知道的第三次工业革命,因为商品和服务的消费方式已经发生了巨大的变化。相对于生产的商品数量,今天提供的服务的数量和类型已经激增,因为互联网使这成为可能。

不仅仅是互联网,而是支撑整个互联网生态系统的外围设备的快速发展,以及随之而来的人工智能的发展。

回到起点——人工智能的崛起

人工智能是一种在有明确输入和输出的问题上蓬勃发展的技术。通常,这些是优化问题(监督学习),如信用评分、垃圾邮件分类和情感分析。当输出没有被标记时(例如,垃圾邮件/非垃圾邮件,肯定/否定),我们也可以根据算法“认为”每个数据点应该被分类到什么类别来进行分类(无监督)。前面提到的是典型的传统机器学习方法(例如,随机森林、支持向量机、逻辑/线性回归、基于密度的模型),它们已经存在并被研究了很长一段时间。

导致这场人工智能革命的是深度学习技术进步的扩散和广泛采用。不是“创造”而是 采用 这项技术。

正如李所说,我们不是处在一个发现的时代,而是处在一个实施的时代。人们很容易被误导,因为媒体不断报道新的突破性成果,如谷歌的 DeepMind 和埃隆马斯克的 OpenAI 击败的 AlphaGoDota 2星际争霸 。回到 2016 年,李·塞多尔甚至无法想象一个计算机程序在围棋中击败他。如今,他已经(2019 年)从围棋退役,因为他认为“即使【他】成为№ 1,也有一个不能被打败的实体”[5]。

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

围棋、DotA 2 和星际争霸冠军被 AI 击败(图片来源:作者创作)

AlphaGo 之后, Dota 2Starcraft 等更复杂的实时多人在线对战竞技场(MOBA)游戏中的职业队伍也在人们认为不可能完成的任务中被废黜。在像 Go 这样的回合制游戏中,计算机程序可以可能穷尽游戏的所有可能状态(棋盘或游戏在任何给定时间点的状态),并预测下一步最佳行动应该是什么,在游戏的多次迭代中进行训练,并采用各种探索-利用策略。对于 MOBA 游戏,这些游戏状态指数(可能)为无穷大,包括额外的复杂性,如博弈论、不完全信息、长期规划和实时多人互动[3]。然而,人们不知道的是,这些突破实际上是同一基础技术的不同应用。

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

AlphaStar 在行动(来源:Deepmind 的博客

秘制酱?深度学习

深度学习使用神经网络——一种通过特定网络结构解析输入的独特方式——来训练模型,以理解输入和输出之间的线性和非线性关系。神经网络试图以类似的结构模拟我们大脑中的神经元,权重作为我们在决策时对每个特征(因素)的重视程度。这种捕捉非线性的能力是与传统机器学习模型的关键区别,传统机器学习模型本质上大多是线性的。

为什么不早点采用这项技术?

尽管深度学习自 2000 年代以来就已经存在,但直到 2016 年,由 Yann LeCun (人工智能的教父之一)领导的人工智能研究人员团队在世界上最大的图像识别比赛中超过了基准错误率 ImageNet ,社区才认识到它。当时,由于缺乏研究资金、计算能力和认可,很少被采用。

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

艾教父:(从左至右)约舒阿·本吉奥、扬·勒村和杰弗里·辛顿(图片来源:作者创作)

今天,随着 GPU 和 TPU 为我们的人工智能系统提供支持,人们能够将开源技术应用到许多不同的领域。过去由博士主导的领域现在不再有同样的准入门槛,因为推进技术需要先进的技术技能,而技术应用不需要同样的严格程度。这就是开源技术的魅力所在,它为人们提供了实验甚至改进的基础。

借助这项新技术,我们可以看到深度学习在不同行业的快速应用——从制造业到零售业到银行业,从蓝领工人到白人。人工智能时代是一个变革的时代,一个颠覆可能成为新常态的时代。我们经常看到行业被打乱,运营被打乱,我们的道路上可能挤满了自动驾驶汽车。

谁有被技术‘取代’的风险?

李将工作大致分为两类——体力劳动和认知劳动。在下面的两个图表中,纵轴描述了工作中的社会参与程度。

第一张图表代表体力劳动岗位的替代风险,横轴描述环境中的结构水平。如前所述,AI 非常擅长学习输入与输出有某种形式关系的任务(即近似f(x) = y)。不用说,基于规则的工作是最容易取代的,因为它不需要人工智能,只需要简单的自动化。

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

替换风险: 体力劳动(来源:作者创作,内容改编自李《AI 超能力》)

第二张图表代表了认知劳动工作的替代风险,横轴描述了所涉及的创造力水平。

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

替换风险: 认知劳动(来源:作者创作,内容改编自李《AI 超能力》)

人们可以观察到体力劳动和认知劳动之间的一些相似之处——与具有某种不可预测性或需要创新思维的工作相比,涉及重复工作和很少社交互动的基于规则的工作(体力或认知)风险更大。

被取代还是被置换?

虽然更多的“传统”工作可以被取代,但我认为这 40%受影响的工作中有很大一部分是被取代的,而不是被 T21 取代的。

人工智能从未被创造出来做人类的工作——至少不完全是。机器人就是为此而生的。你可能会问这有什么区别?在我看来,机器人代表了人工智能可以驻留的物理实体。换句话说,人工智能代表了机器人的“T2 大脑”。传统工作之所以会被取代,是因为我们只需要一个拥有“基于规则的大脑”的机器人。这就是工业革命发生并改变商品生产方式的原因。

然而,有了人工智能,我们试图解决的问题会成倍地(也许是无限地)变得更加困难。在医疗场景中,AI 很大程度上用于诊断甚至药物开发和患者监测的阶段。图像识别的使用在医疗保健中更加普遍,因为图像识别变得如此之好如此之快。这通常在 X 射线图像上进行,以在检测乳腺癌甚至新冠肺炎的迹象时识别异常。在前者中,已经确定人工智能在诊断乳腺癌方面“优于”医生,假阳性率降低了 1.2%,假阴性率降低了 2.7%[6]。

在银行业,人工智能用于识别交易中的异常情况(即欺诈)并批准贷款。在海事方面,AI 用于识别海上物体,防止碰撞。在电子商务中,人工智能被用来预测你可能会购买什么商品。在我们消费内容的网站上,人工智能被用来推荐我们可能想要观看或阅读的项目。在我们的 iPhones 上,人工智能被用来自动完成我们的文本,回答我们在谷歌搜索上键入的问题(也称为自然语言处理中的问答),甚至在我们懒得自己做的时候,使用语音识别为我们设置闹钟。

这里的底线是——**AI补充了我们做事的方式,因为它抽象出了我们可能必须提供客观意见的情感元素。**在乳腺癌诊断中,需要多名放射科医生做出判断,尤其是当这些判断不一致时。个体放射科医生一生中只能经历有限次数的 x 光检查,并且受到疲劳和容易出错的限制。人工智能系统可以在一天内通过同样数量的 X 射线,全天候工作,并提供类似甚至更高的准确性。这也适用于其他工作。

然而,由于做同样工作所需的人员数量将会减少,人员流动是不可避免的。新的补充性工作将会出现,以帮助这一过渡,例如需要了解如何操作这些人工智能驱动技术的人员。

剩下的问题是:

我们如何应对,更重要的是,如何适应人工智能带来的这些变化?

真正的人工智能危机

是的,AI 很吓人。

如果我们不知道它能做什么,那就太可怕了。如果我们无所事事,让我们的工作被取代,或者更糟糕的是,被人工智能取代,这也很可怕。

自满

在个人层面上,我们必须意识到人工智能的能力和可能性。思考人工智能如何影响我们的生活是很重要的。如果我们选择不理解人工智能到底是什么,我们就会失败,并有被取代或取代的风险。

在国家层面,各国需要开始思考和利用他们拥有的任何数据。政府在推动人工智能和技术的采用方面发挥了巨大作用,正如中国如何在几十年内从技术落后者加速成为人工智能超级大国一样。人工智能有一种赢者通吃的趋势,因为先行者可以扩大庞大的用户群,而这本身就会产生数据,从而形成一个自我延续的循环。

能力

我们在个人、企业和国家各个层面都承担责任。就个人而言,跟上这场人工智能革命是我们的责任。 提升技能 前所未有的重要。有了互联网上的大量可用资源,学习几乎任何技能现在都是可能的。

在企业和国家层面,变革通常来自高层。高级管理层和内阁部长需要鼓励创新,并拨出预算来鼓励创新。人才管理也是至关重要的,因为人工智能人才是稀缺和流动的。

合作的

在全球范围内,世界上可能不可避免地会出现一些人工智能巨头(在人工智能领域占据主导地位的公司和国家)。这无疑会造成贫富之间以及第一和第三世界国家之间的差距越来越大。随着强大的力量而来的是巨大的责任(是的,cheesy I know)——我真的希望这些人工智能大亨们能够共同努力,在国内和国际上弥合这一差距。

我们会在有生之年体验完全的人工智能自主吗?

简而言之,没有。

事实是,今天的人工智能没有许多人想象的那么好,但也没有我们担心的那么糟糕。我们常常害怕我们没有完全掌握的东西。

Lee 的书中,他将自主 AI 描述为第四波 AI(第一波是互联网 AI ,第二波是商业 AI ,第三波是感知 AI )。它代表了机器从极其复杂的数据集进行优化的能力与其新发现的感官能力的融合[1]。简而言之,当机器被赋予根据它感知的事物(无论是视觉还是听觉)做出决定的能力(T21)。这些与简单地基于一套规则运行的机器形成了鲜明的对比。

我们今天最接近的东西是自动驾驶汽车。然而,当谈到自主人工智能时,仍然有许多考虑和影响,人工智能伦理和治理发挥着巨大的作用。为了实现完全的人工智能自主,我们必须超越我们的有生之年去想象可能性。

遗言

人工智能塑造我们世界的方式每天都让我感到惊讶,我希望这篇文章能揭示出今天我们的生活与人工智能是如何融合的。更重要的是,理解人工智能对我们个人、工人和全球公民的影响,是创造一个未来几代人可以生活的更加公平的世界的基础。

如果你还没有读过李开复的《人工智能的超能力》,我强烈建议你读一读!

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

来源:故事镜头

支持我! —如果你喜欢我的内容并且没有订阅 Medium,请考虑支持我并通过我的推荐链接订阅这里 ( 注意:你的一部分会员费将作为推荐费分摊给我)。

参考资料:

[1] AI 超级大国——中国、硅谷与世界新秩序,李开复

[2] 人工智能超能力对抗所有其他超能力

【3】阿尔法星:掌握即时战略游戏星际争霸 2

【4】开启 AI — Dota 2

李·塞多尔退休了

[6] 人工智能“胜过”诊断乳腺癌的医生

人工智能的下一步:抽象和推理

原文:https://towardsdatascience.com/ais-next-step-abstraction-reasoning-db2d90e82799?source=collection_archive---------39-----------------------

用演示测试你的一般智力

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

抽象和推理语料库中包含的 600 个任务的一个小样本。

如果你想直接试一试: ARC 测试界面

人工智能在过去十年取得了突飞猛进的发展,解决了许多我们认为不可能完成的任务,但我们离类人智能还很远。最重要的是,创造人工智能的领先方法不像我们在自然界中看到的那样,使用庞大的数据库来学习模式识别。这与人类形成对比,人类拥有灵活的智力,允许我们只用少量样本就能胜任。为了帮助推动世界向前发展,一个新的挑战——抽象和推理语料库(ARC)——已经提出,它可能会取代图灵测试,成为人工智能的目标。除此之外,随着全球工程师在在线平台 Kaggle 上争夺奖项,对人工智能社区的挑战正迅速接近尾声。

弧形

2019 年 11 月发表的名为“论智力的衡量标准”的 64 页研究论文,概述了人工智能研究的历史,一个新的视角和抽象与推理语料库(ARC)。它是由资深深度学习研究员兼谷歌工程师弗朗索瓦·乔莱(Franç ois Chollet)提出的。在书中,他认为:

“ARC 可用于测量类似人类形式的一般流体智能,它可以在人工智能系统和人类之间进行公平的一般智能比较。”

这很重要,因为就像正在构建的人工智能一样,人类是非常面向目标的。通过提供一个单一的努力目标,我们可以衡量我们的表现,迭代,改进并努力超越基准。我们已经在人工智能的其他领域看到了非常相似的结果;当 MovieLens 数据集发布时,推荐系统实现了飞跃;图像识别社区随着 MNIST 和随后的 ImageNet 的发展而繁荣。希望 ARC 可以成为更普遍的智能人工智能系统的火花。

本文的另一个重要成果是系统智能的定义(如下所示)。这个等式在这里有点难以解释,但它可以解释为"智力是学习者在涉及不确定性和适应性的有价值的任务中将其经验和先验知识转化为新技能的速度。因此,最智能的系统只需要少量的经验,并根据这些经验猜测在许多不同的情况下会有什么样的结果。

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

乔莱对智力的定义。有趣的是,公式本身就需要很高的智力门槛来处理!

让我们通过一个来自 ARC 的例子更容易地看到这一点。作为 ARC 中所有任务的标准,我们从一些必须理解的例子开始,然后归纳为一个测试用例。

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

任务 11:星际飞船建造者(好吧,他们并没有真正的名字,但这更有趣)。这里的目标是采用基本模式并围绕它建造一艘“星际飞船”。这是通过将外部部分从中心向外延伸一个方块,将中心部分向对角线方向延伸两个方块来实现的。

在这个例子中,你必须用基本的图案围绕它们建造一艘“星际飞船”,注意基本的颜色。对于测试用例,只提供给你一张图片(比如说,最左边的那张),你必须猜测相邻的那张。对于我们来说,看到这种模式并假设(猜测)创建解决方案的下一步是什么是相对简单的,但建立一个人工智能来为一般情况做这件事是我们目前非常非常远的事情。

上面的例子相对简单,但是肯定有更复杂的。点击这里提供的链接选择“随机任务”来尝试一些挑战: 电弧测试界面 。如果你发现任何问题特别难,请在下面分享你的结果!感谢论文作者准备了这个界面并允许它自由发表。或者,在这里查看所有示例。

似乎很容易

但是是什么让人工智能变得如此困难呢?我们可以考虑像这里的一样手动编程每种情况。只需要一行日常语言就能表达的东西,却需要几十行代码。

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

任务 1:打开门户。用英语直截了当表达的东西,例如“用黄色填充绿色物体”,用代码来表达相对复杂。

“用黄色填充绿色对象”的示例变为:

def task_train001(x):
    green, yellow = color2num["green"], color2num["yellow"]

    def get_closed_area(arr):
        *# depth first search*
        H, W = arr.shape
        Dy = [0, -1, 0, 1]
        Dx = [1, 0, -1, 0]
        arr_padded = np.pad(arr, ((1,1),(1,1)), "constant", constant_values=0)
        searched = np.zeros(arr_padded.shape, dtype=bool)
        searched[0, 0] = True
        q = [(0, 0)]
        while q:
            y, x = q.pop()
            for dy, dx **in** zip(Dy, Dx):
                y_, x_ = y+dy, x+dx
                if **not** 0 <= y_ < H+2 **or** **not** 0 <= x_ < W+2:
                    continue
                if **not** searched[y_][x_] **and** arr_padded[y_][x_]==0:
                    q.append((y_, x_))
                    searched[y_, x_] = True
        res = searched[1:-1, 1:-1]
        res |= arr==green
        return ~res

    y = x.copy()
    y[get_closed_area(x)] = yellow
    return y

但这只是问题的一面。如果需要,我们可以编写任意长的代码,但我们在这里试图解决的问题是编写可以解决各种问题的代码,而不仅仅是我们手动编程的问题。

总的来说,对我们来说似乎简单的东西来源于论文所描述的“人类先天的先验”。这种先验知识指的是我们用来处理概念的东西,比如物体是什么,对称性是什么,或者排序什么东西意味着什么。任何系统都必须能够学习这些,或者至少将它们预先编程,然后开始将它们缝合在一起以找到解决方案。例如,我们可以编写关于对称性意味着什么的函数,或者我们可以创建一个能够学习对称特征的二维过滤器。

值得注意的是,在 ARC 的情况下,先验的数量保持在绝对最小值,这是使该数据集真正伟大的另一个因素。你可以将这与原始的图灵测试进行对比,在原始的图灵测试中,计算机必须模仿人类。要做到这一点,计算机必须对人类文化有充分的理解才能通过,这与智力没有直接关系。

让这项任务变得非常棘手的另一个原因是,输入量非常小,这意味着系统必须能够从少量训练样本中学习复杂的行为。出于这个原因,像深度学习这样最受欢迎的技术并不适合这个问题,因为它们通常需要数百万个训练样本。最重要的是,它们需要用于训练它们的数据和它们必须解决的问题之间的共性,这对于 ARC 来说并不成立。

这就是 ARC 真正有趣的地方。它正在推动边界,迫使研究人员提出创新的系统来解决前所未有的普遍问题。

一个解决方案?

论文发布后,在线平台 Kaggle 发布了一个竞赛:抽象和推理挑战。在这场比赛中,工程师们面临的挑战是在 ARC 中描述的任务上获得尽可能好的分数。我们不太可能在剩下的一个月里解决人工智能问题,但我们正在探索一些有趣的问题。迄今为止的主要尝试包括:

  • 卷积神经网络:乍看之下,CNN(处理图像以告诉你是否有猫的同一个系统)很适合这个问题,因为它们是为处理二维图像数据而建立的,可以建立强大的模式检测器。但是如前所述,这些系统不能很好地解决问题,性能也很差。
  • 细胞自动机:通过定义一套简单的规则,我们可以使用细胞自动机产生复杂的行为。如果你从未听说过它们,一定要查一下——它们超级酷!虽然到目前为止的探索大多是好玩的,但思考和触及智能的核心是很有趣的。
  • 决策树:ML 工程师的另一个拿手好戏是决策树。通过一些聪明的特征工程,有可能产生一些正确的答案,但是很难看出它如何一般化。
  • 遗传算法:从一些关于如何转换图像的函数(特定领域语言,DSL)开始,遗传算法采用一些随机函数并进化这些函数,类似于(在某种意义上)地球上生命的进化。有了一个定义良好的函数列表和一个关于什么“看起来不错”的强烈想法,这种方法似乎可以很好地执行。

您可以在 Kaggle 论坛上关注所有这些解决方案的更新,或者等到比赛结束后查看顶级选手的评论。

展望未来

这并不是贬低当前技术的力量。深度学习给了我们像自动驾驶汽车和象棋大师这样令人惊叹的技术。所有这些都是在一个庞大的经济体的背后发展起来的,这个经济体渴望通过能够像人类一样完成非常具体的任务的系统来实现自动化。经济需求和强大的社区解释了为什么这些系统如此流行和被大量研究。这篇论文提醒我们的是,还有其他值得探索的方向。让我们开始吧!

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

元胞自动机求解门户打开任务。信用: arseny-n

艾的凤凰计划时刻

原文:https://towardsdatascience.com/ais-phoenix-project-moment-b51f581711d8?source=collection_archive---------19-----------------------

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

艾的凤凰计划时刻

2018 年晚些时候,在亚利桑那州一段荒凉的双车道高速公路上,伊莱恩·赫尔茨贝格赢得了她从未想要的荣誉。

她成为第一个被自动驾驶汽车撞死的行人。

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

当汽车花费 290 到 520 美元的小财富时

她和 122 年前的一个女人布丽奇特·德里斯科尔有着相似的悲惨命运,她于 1896 年死于一项早期实验技术之手,当时她正在伦敦的傍晚散步:

一辆车。

普通大众喜欢把人工智能看作超人,在某种程度上他们是超人。他们可以击败世界上最好的围棋选手或 99%的 DOTA 2 选手,这是一款非常复杂的实时战略游戏。

但这并不意味着它们是完美的。即使今天最先进的人工智能也会犯严重的错误,包括大多数人会发现很容易克服的错误。

当我们把人工智能从棋盘游戏和视频游戏的狭窄领域中拿出来,放到现实世界中时,它们面临着一系列永无止境的边缘情况和意想不到的场景。这一点在高风险的自动驾驶汽车领域表现得最为明显,在这个领域,每一个错误都可能意味着生死之别。

Lyft 无人驾驶汽车部门研发负责人吕克·文森特(Luc Vincent)表示,无人驾驶汽车可能出现的问题几乎是无限的。

Lyft 自动驾驶汽车测试

Lyft 发现,当他们被其他司机超车时,他们的汽车正在刹车。另一家自动驾驶汽车公司 Zoox 发现他们的汽车无法处理黄色的左手转向灯,因为大多数转向灯都是绿色的。他们不得不请艺术家来绘制黄色的转向信号,并加载到他们的模拟软件中。很快,Zoox 的汽车在现实世界中看到它们的能力有了很大提高,但无论你做什么,总会出现另一种情况。

“这有点像打地鼠。“你解决了一个问题,另一个问题可能会出现,”应用直觉公司首席执行官合撒儿·尤尼斯说,根据 CNN 的优秀文章关于这个“世代型技术挑战”所面临的无尽困难

著名机器人专家、麻省理工学院荣誉退休教授罗德尼·布鲁克斯给写了一篇非常长且详细的帖子,解释了为什么他认为无人驾驶汽车比几乎所有人想象的都要遥远。他列举了几十个边缘案例:

  • 如果你沿着一条狭窄的单行道走,这条单行道被建筑挡住了,那么违反法律回到这条单行道上可以吗?
  • 这辆车能应付青少年恶作剧和大喊冲突的命令吗?
  • 汽车能理解警察或路边工作人员的手势吗?
  • 汽车能识别别人贴的假路牌还是损坏的路牌?

变得有鸭意识还是机器推理的局限性

所有这些场景对今天的人工智能来说都非常困难,因为它们没有更深层次的上下文意识或通用抽象推理。情境人工智能是人工智能研究的前沿,这就是为什么它得到了像 DARPA 这样的未来主义组织的资助。

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

DARPA 可解释人工智能框架

让人类如此神奇的是,我们善于从其他问题中抽象出解决方案,来解决我们从未见过的全新问题。我们可以研究物理定律、运动定律和惯性定律,建造一艘前所未有的火箭,并首次在月球着陆。

一个卷积神经网络 (CNN)可以研究火箭的例子,但如果没有现成的解决方案来建造火箭,那么它就不能发明一个。一个从未见过鸭子的 CNN 不会突然意识到鸭子的存在。

无人驾驶汽车推动了可能性的极限。关于我们现在已经有自动驾驶汽车自信地行驶在纽约市普通街道上的疯狂乐观的预测正在让位于现实检验意识,这可能比我们想象的要长得多。

在一个层面上,我们遇到了深度学习和强化学习的局限性。在最近的人工智能最大的会议之一 NeurIps 上,一些业界最耀眼的明星,包括蒙特利尔人工智能研究所 Mila 的主任 Yoshua Bengio,就人工智能的现状给出了一个发人深省的信息:

“我们有以非常狭窄的方式学习的机器,”本吉奥说。“他们需要比人类智能例子多得多的数据来学习一项任务,他们仍然会犯愚蠢的错误。”

机器人专家罗德尼甚至走得更远,他说,要拥有一辆真正的4 级或 5 级自动驾驶汽车,这意味着汽车不需要轮子,可以在除了最糟糕的天气条件之外的任何情况下行驶,并做出自己的决定,将需要某种接近人工通用智能的东西(AGI)。仅仅将一堆互不相连的神经网络缝合在一起,并希望更高形式的理解会神奇地出现是不够的。

要让一辆自动驾驶汽车在现实世界的混乱中工作,在司机按喇叭和插队的情况下,在坑坑洼洼、破损的交通灯或贴满贴纸的街道标志的情况下,我们很有可能无法在今天的人工智能艺术中实现这一目标。现在,我们是否能利用神经网络的魔力让自动驾驶汽车发挥作用,或者我们是否需要新的算法,将在全球顶尖 R&D 团队的实验室中决定,因为他们正在竞相寻找解决方案。

但是如果我们仔细观察,自动驾驶汽车的世界向我们展示了一个更加基本和根本的问题,这个问题正在摧毁数据科学团队,而且我们现在就可以解决这个问题。

红队崛起的凤凰

87%的数据科学项目从未投入生产是有原因的。

今天,大多数数据科学团队都不知道如何处理边缘情况,当我们的模型遇到现实生活时,这些情况就像野生兔子一样成倍增加。

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

一个 ConvNet 看到左边的图像是一个 45 英里每小时的标志!

自我学习的算法有各种各样的场景,只是我们无法预见,直到它们迎面而来。如果你的视觉检测系统有 97%的准确率,但检测到一个涂鸦覆盖的停车标志是 45 英里/小时的标志,它的准确率可能为零,因为有人会受伤或死亡。

即使是世界上最准确、最成功的 CNN,也常常在凌乱的现实世界中挣扎。麻省理工学院和 IBM 刚刚推出了 ObjectNet 数据集来展示这些算法在面对损坏的东西,或部分隐藏的东西,或以奇怪的角度放置的东西时表现得有多糟糕。该数据集花了三年时间整合,一些最先进的对象检测模型的准确率从 ImageNet 上的 97%下降到 ObjectNet 上的 50–55%。

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

提供图像识别功能的 ObjectNet 图像

仅仅测试准确性和收工已经不够了。准确性分数标志着一个模型的最低能力。这些分数就像你放在简历上为你在新工作中担保的两个人。它们表明你并没有那么无能,以至于你在这个世界上找不到两个人来说你的好话,仅此而已。

但是,要让像自动驾驶汽车这样复杂的东西成为现实,我们需要一种方法来解决快速扩散的边缘案例“打地鼠”的问题。要做到这一点,我们需要超越的整体精度,并转向对边缘案例的精度进行自动化测试。我们可以通过传统的软件编程来做到这一点。

人工智能开发有其独特的挑战,但在我们如何在一些最精英的编程团队上开发软件与数据科学团队现在和未来如何开发人工智能之间有很多重叠。

要理解为什么你只需要知道一点点编程的历史。

DevOps 是一个大问题的答案,当我们的应用程序开始变得太大太复杂,旧的编程方法无法熟练处理时,这个问题才浮出水面。早期的计算机应用程序比今天多方面的应用程序简单。它们主要是由公司开发团队为一个狭窄的用例构建的。有了这些隐藏在公司防火墙后面的应用程序,瀑布模型运行得非常好。只有几千个用户会接触那个应用程序,所以你可以把边缘情况保持在最低限度。

但是互联网改变了一切。随着上亿用户使用一个应用程序,越来越多的错误会出现,而在严格控制的环境中只有几千名用户。DevOps 来救援了。它使互联网规模的应用成为可能。

AI 再次改变游戏。

有了人工智能,我们面临着未知事物的指数级增长。

修复它的关键是单元测试。

我们可以把每一个边缘案例看作是一个需要自动化单元测试的 bug。

敏捷和 DevOps 风格编程的兴起教会了我们如何自动化测试,因为复杂的软件在广泛分布的编程团队的手中经历了无数的变化。软件团队经常发现,由于程序员签入依赖于损坏的库的代码,或者由于程序员剪切并粘贴旧代码而没有意识到它有缺陷,一个被压制的网络错误不知何故在一百次修订后又回来了。人工智能团队将需要开发自己的自动化边缘案件处理器,以处理欺诈检测系统,每当有人前往法国或在阿尔伯克基使用 ATM 机时,这些系统就会开始得到误报。

当我们调整算法的参数或重新训练新数据时,它突然开始出错,人工智能团队将不得不建立特殊的测试,以确保这些“错误”不会突然出现。自动驾驶汽车团队可能会创建一个 CNN,它擅长处理愤怒的人类司机切断他们的道路,但如果它突然又开始丢失贴有贴纸的街道标志,那也没什么关系。

为了构建一个更好的单元测试,工程团队将需要掌握机器学习操作(MLOps) 并学习构建一个良好的 MLOps 管道,可以快速发现并消除新的 bug。

在我为红帽 OpenShift Commons 的演讲中,我谈到了如何为人工智能团队建立一个 QA,我现在称之为人工智能红队。这是一个由快速响应的编码人员、工程师和数据科学家组成的团队,他们寻找人工智能异常的短期分类解决方案和长期解决方案。这是一个非常精英的团队,很像一个白帽黑客队,他们的工作是闯入网络,使他们免受黑帽的攻击。

AI 红队的工作就是墨菲定律的答案。他们专门破解 AI,再修复。他们负责找出未知的未知,并在伤害他人或伤害底线之前将它们公之于众。

在不太遥远的将来,我们将需要世界各地数以百万计的红色团队构建他们自己的 ObjectNets,并以真正的开源精神共享它们,以真正创造出可以安全地倒在单行道上或穿越暴雨和大雪的汽车。

把这当成是给 AI 的凤凰计划。

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

如果你不知道这本书,你应该知道。这是一本关于软件和业务转型的非常好的读物。任何一本书,只要能把软件开发和业务流程升级变成一次有趣的、超级娱乐性的旅行,书中充满了我们在现实世界中似乎都认识的人物,都是非常特别的。这本书有助于推广 DevOps 软件开发模型,但不仅如此,它还展示了我们如何通过在组织的每个级别上以不同的方式思考问题来解决过去的问题。

在人工智能时代,我们将不得不再次转变我们的理解和方法。

人工智能带来了新的挑战,这是我们手动编写所有软件并手动教给它道路规则时从未面临过的挑战。今天的软件正在自学道路规则。当它在红灯处右转时,最先进的人工智能团队已经准备好了。

现在是艾的凤凰计划的时刻。

为了建设未来,有时我们只需要回顾过去。

############################################

作者 【工程师】 亲博者播客我还运营了 实用 AI 伦理联盟 AI 基础设施联盟 ,两个倡导安全透明 AI 的开放社区。**

############################################

这篇文章包括亚马逊的会员链接。

############################################

阿凯克信息论

原文:https://towardsdatascience.com/akaike-information-criteria-942d1f554537?source=collection_archive---------19-----------------------

AIC 背后的想法

我们所有人都曾用 AIC 来选择模特。这个博客是关于 AIC 背后的想法,它是什么,为什么它被用于模型选择。虽然有人告诉我们如何计算 AIC,但至少没人告诉我为什么要这么做背后的逻辑——这篇博客将对此进行阐述。

AIC 是对样本外误差的估计。AIC 以信息论为基础。他称之为熵最大化原理,最小化 AIC 相当于最大化热力学系统的熵。因此,在信息论的语言中,我们可以说,当编码一个模型时(我们永远找不到确切的模型,一些信息在表示数据生成的过程中丢失了。

AIC 测量了相对信息损失。由于我们没有确切的模型,我们无法测量确切的损失。因此,我们测量不同模型之间的相对损失(我们必须从中选择我们的模型)。如果我们有 3 个 AIC 值分别为 100、102 和 110 的模型,那么第二个模型的 exp((100-102)/2)= 0.368 倍是第一个模型的概率,以最大限度地减少信息损失。同样,第三个模型的概率是第一个模型的 0.007 倍,以最大限度地减少信息损失。

AIC 由 **2 x 参数数量-2 log(似然)**给出

当选择模型(例如多项式函数)时,我们选择具有最小 AIC 值的模型。或者,如果我们可以选择前 2-3 个模型,收集更多的数据,并选择 AIC 最小的一次。这个博客是关于——这个 AIC 公式从何而来?

在 AIC,我们试图最小化模型和地面真实函数之间的 KL 差异。AIC 是对代理函数估计的计算。因此,最小化 AIC 类似于最小化 KL 与地面真实值的偏离,从而最小化样本外误差。下图显示了 AIC 的推导过程。

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

**图一。**推导第一部分

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

**图二。**推导第二部分

贝叶斯信息标准(BIC)的计算类似于 AIC。BIC 用 2 ln(n)k 代替 2k,这些被称为罚项。有争议的是,如果真实模型存在于模型组中,BIC 选择概率为 1 的真实模型,给定 n 趋于无穷大。由于我们在候选模型集中从来没有真正的真实模型,这个属性并没有被高度重视。此外,AIC 最大限度地降低了选择一个非常糟糕的模型的风险。

参考 1。维基百科 AIC 页面
2。AIC 的衍生

Albert 矢量化(带 Tensorflow Hub)

原文:https://towardsdatascience.com/albert-vectorization-with-tensorflow-hub-c6b892ed7ed4?source=collection_archive---------22-----------------------

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

我们使用来自 tensorflow-hub 的预训练 Albert 嵌入对输入文本进行矢量化。它被用作 Keras 层,因此可以很容易地扩展以构建深度学习模型。

BERT 的出现打破了 NLP 的传统范式。下游的模型构建现在是从一个以语言知识为基础的模型开始,而不是从零开始。ALBERT 可以被称为 lite BERT,它使用转换器-编码器架构,参数数量大大减少。在本文中,词汇大小也是 30K,与最初的 BERT 中使用的一样。ALBERT 区别于 BERT 的三个主要方面是分解嵌入参数化、跨层参数共享和句子顺序预测。

优于伯特

当人们试图简单地放大模型的隐藏尺寸时,BERT like 模型可能提供质量差的性能。诸如因子分解嵌入参数化之类的参数缩减技术用于将隐藏层的大小与词汇嵌入的大小分开,这使得在不显著增加参数大小的情况下增加隐藏大小变得容易。而跨层参数共享防止参数随着网络的深度而增长。因此,这两种技术都显著减少了传统 BERT 的参数数量,而没有恶化性能和提高参数效率。通过引入句子顺序预测的自监督损失(SOP ), ALBERT 的性能得到进一步改善。

在本文中,我们将使用 tensorflow-hub 模块的 keras 层格式获得相应文本的 ALBERT 向量。

1.设置环境

我们将使用 tensorflow keras API 制作一个模型,它将为文本输入提供 ALBERT 嵌入。环境设置包括安装所需的库和获取所需的 tensorflow-hub 模块以获得 ALBERT vectors。使用的库有:

#tensorflow==2.2.0
#tensorflow_hub=0.8.0
#sentencepiece==0.1.91
#tqdm==4.47.0
#seaborn==0.10.1
#numpy==1.19.0

我们将使用 TF2 保存的艾伯特模型格式。您可以直接使用 tfhub 上的模块进行推断。但是对于生产场景,最好将模块放在本地。为此,我们需要首先获取模块的 zip 文件并将其解压缩。

# mkdir albert_en_base
# mkdir 1
# wget [https://tfhub.dev/tensorflow/albert_en_base/1https://tfhub.dev/tensorflow/albert_en_base/1](https://tfhub.dev/tensorflow/albert_en_base/1https://tfhub.dev/tensorflow/albert_en_base/1)
# tar-xzf albert_en_base_1.tar.gztar-xzf albert_en_base_1.tar.gz
# rm -rf albert_en_base_1.tar.gzrm -rf albert_en_base_1.tar.gz

2.符号化

我们将把 ALBERT 模块作为 keras 层导入。

albert_layer = hub.KerasLayer("albert_en_base/1", trainable=False)

棘手的是,艾伯特模块不能直接输入文本。它需要经过一个预处理层。

首先,我们将使用 ALBERT tokenizer 对输入文本进行分词,它基于一个句子片断分词器,即子词级分词器。它是一个数据驱动的标记器,用来处理词汇表之外的单词。因为我们在每次输入时只有一个文本,所以句子的标记列表看起来像[“[CLS]”]+标记+ [“[SEP]”]。

sp_model_file = albert_layer.resolved_object.sp_model_file.asset_path.numpy()
tokenizer = FullSentencePieceTokenizer(sp_model_file)
stokens = tokenizer.tokenize(sentence)
stokens = stokens[:MAX_LEN]
stokens = ["[CLS]"] + stokens + ["[SEP]"]

例如,文本“车身由金属制成,具有高张力”会生成一个令牌列表,如下所示:

['▁the',
 '▁body',
 '▁is',
 '▁made',
 '▁of',
 '▁metallic',
 'a',
 '▁and',
 '▁deliver',
 'i',
 '▁high',
 '▁tension']

现在,我们需要 3 个输入序列,可以馈入艾伯特模块。

  • 标记 id:用于从 ALBERT vocab 字典中提取的句子中的每个标记。
  • mask ids:for each token,用于屏蔽仅用于序列填充的标记(因此每个序列都有固定的长度)。
  • Segment ids 表示一个句子序列(我们这里的例子),1 表示序列中有两个句子。
def get_ids(tokens, tokenizer, max_seq_length):
  """Token ids from Tokenizer vocab"""
  token_ids = tokenizer.convert_tokens_to_ids(tokens,)
  input_ids = token_ids + [0] * (max_seq_length-len(token_ids))
  return input_idsdef get_masks(tokens, max_seq_length):
  return [1]*len(tokens) + [0] * (max_seq_length - len(tokens))def get_segments(tokens, max_seq_length):
  """Segments: 0 for the first sequence, 1 for the second""
  segments = []
  current_segment_id = 0
  for token in tokens:
    segments.append(current_segment_id)
    if token == "[SEP]":
      current_segment_id = 1
  return segments + [0] * (max_seq_length - len(tokens))ids = get_ids(stokens, tokenizer, MAX_SEQ_LEN)
**# [2, 13, 1, 589, 17378, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]**masks = get_masks(stokens, MAX_SEQ_LEN)
**# [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]**segments = get_segments(stokens, MAX_SEQ_LEN)
**# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]**

3.艾伯特矢量化

现在我们已经准备好了所需的输入处理。我们将使用 tf keras API 建立一个模型,它将接受处理后的输入,并获得文本的 ALBERT 向量。输出艾伯特矢量包含 2 个矢量,一个是汇集输出和序列输出。pooled_output 是维度 1x768 的句子嵌入,序列输出是维度 1x(token_length)x768 的令牌级嵌入。

def get_model():
  input_word_ids = tf.keras.layers.Input(shape=(MAX_SEQ_LEN,), dtype=tf.int32,name="input_word_ids")
  input_mask = tf.keras.layers.Input(shape=(MAX_SEQ_LEN,), dtype=tf.int32,name="input_mask")
  segment_ids = tf.keras.layers.Input(shape=(MAX_SEQ_LEN,), dtype=tf.int32,name="segment_ids") pooled_output, sequence_output = albert_layer([input_word_ids, input_mask, segment_ids]) model = tf.keras.models.Model(inputs=[input_word_ids, input_mask,  segment_ids], outputs=[pooled_output, sequence_output])
  return model

制作 keras 模型的想法是通过添加所需的层和参数,轻松地将其扩展到任何分类模型。

现在所有的艰苦工作都完成了。将只需要一个推理函数来获得文本的相应艾伯特嵌入。

s = "This is a nice sentence."def get_albert_vec(s):
  stokens = tokenizer.tokenize(s)
  stokens = ["[CLS]"] + stokens + ["[SEP]"]
  ids = get_ids(stokens, tokenizer, MAX_SEQ_LEN)
  masks = get_masks(stokens, MAX_SEQ_LEN)
  segments = get_segments(stokens, MAX_SEQ_LEN)
  input_ids = np.asarray(ids, dtype=np.int32).reshape(1,22)
  input_masks = np.asarray(masks, dtype=np.int32).reshape(1,22)
  input_segments = np.asarray(segments, dtype=np.int32).reshape(1,22)
  return input_ids, input_masks, input_segmentsinput_ids, input_masks, input_segments = get_albert_vec(s)
pool_embs, word_embs = albert_model.predict(
      [[input_ids, input_masks, input_segments]]
)

为了快速检查句子嵌入的质量,让我们在一小组示例上运行它,并使用它们对应的归一化句子嵌入向量的点积来检查每对的句子相似性得分。

sentences = [
# Smartphones
"I like my phone",
"My phone is not good.",# Weather
"Recently a lot of hurricanes have hit the US",
"Global warming is real",# Asking about age
"How old are you?",
"what is your age?"]run_and_plot(sentences)

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

参考文献

[## sambit 9238/深度学习

此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…

github.com](https://github.com/sambit9238/Deep-Learning/tree/master/sarcasm_classifier/albert_tfhub) [## 从伯特到阿尔伯特:预训练的兰格模型

预训练语言模型的研究进展

medium.com](https://medium.com/doxastar/from-bert-to-albert-pre-trained-langaug-models-5865aa5c3762) [## ALBERT:一个用于语言表达自我监督学习的 Lite BERT

自从一年前 BERT 问世以来,自然语言研究已经采用了一种新的范式,利用了大量的…

ai.googleblog.com](https://ai.googleblog.com/2019/12/albert-lite-bert-for-self-supervised.html) [## 谷歌的 NLP 驱动的预训练方法 ALBERT 更精简&更刻薄

自然语言处理(NLP)是新兴技术中最多样化的领域之一。去年,搜索引擎…

analyticsindiamag.com](https://analyticsindiamag.com/googles-nlp-powered-pretraining-method-albert-is-leaner-meaner/) [## 视觉论文摘要:阿尔伯特(A Lite BERT)

考虑下面给出的一个句子。作为人类,当我们遇到“苹果”这个词时,我们可以:联想“苹果”这个词…

amitness.com](https://amitness.com/2020/02/albert-visual-summary/)

AlexNet

原文:https://towardsdatascience.com/alexnet-8b05c5eb88d4?source=collection_archive---------18-----------------------

用代码解释论文

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

照片由好股票照片

2012 年秋季 9 月,AlexNet 首次参加了 ImageNet 大规模视觉识别挑战赛(ILSVRC),并展示了 GPU 在深度学习方面的异常实力。点燃图像深度学习整个领域的火花是这样的。由 Alex Krizhevsky 与当今深度学习的大腕 Ilya Sutskever 和 Geoffrey Hinton 一起创建。这是任何进入深度学习领域的人阅读的第一篇论文。

所以,让我们回顾一下这篇论文,看看我们怎样才能重新创造,使它重现往日的辉煌。

网络

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

来源:https://papers . nips . cc/paper/4824-imagenet-class ification-with-deep-convolutionary-neural-networks . pdf

由于网络设计时 GPU 内存不足,因此必须通过结合 2 个 GPU 来训练。

  • 我们的输入是 224x224x3 的图片。(论文中给出的是 150,528 维,有点混乱)
  • 接下来,执行 96 个 11×11的卷积(今天,没有看到任何网络采用如此大的卷积),步长为 4 。然后,响应规范化(稍后解释)和池应用于层外。在这一层之后,网络分裂成两个相同的主干,直到完全连接。这样设计是为了考虑 GPU 的内存需求。
  • 接下来是 256 个 5x5 的滤波器,每个滤波器然后再次被响应归一化(稍后解释)并被汇集。
  • 第三、第四、第五层与 384 个内核相同,每个内核为 3×3
  • 由于这里内存的限制,作者不得不将 4096 个神经元分成两部分,每部分 2048 个。每个部分都从两个主干获得数据。
  • 当从两个茎获得数据时,再次重复完全连接的层
  • 最后,我们输入 1000 个神经元的密集层,即 ImageNet 中的类的数量。

网络的成功在于他们用过的伎俩。

局部响应标准化

这是他们使用的巧妙伎俩之一。

什么是局部响应正常化?

我们先来看看 ReLU。

ReLU(x) = max(0,x)

ReLU 最好的一点是,即使极少量的训练样本有一些激活,也会有学习。但是,缺点是它们是无限的。因此,他们控制他们的权重,并且,为了产生更好的特性,我们使用局部响应标准化。

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

来源:https://papers . nips . cc/paper/4824-imagenet-class ification-with-deep-convolutionary-neural-networks . pdf

这个公式乍一看很吓人,所以,我们来理解一下。

首先,在求和算子中,存在激活,我们对其求平方以消除正负效应。

现在,让我们来看看,求和运算符的范围是什么,给定一个 n ,它在其左侧迭代 n/2,在其右侧迭代N/2,同时考虑边界,即 0 和 N-1。

这进一步乘以因子 α ,以减少其与分子相比的值,从而保持分子中的激活值(如果 α 高,则分子中的激活将减少,从而导致渐变消失,如果太低,将导致渐变爆炸)。

增加 k 是为了防止被零除的错误。

最后,将 β 作为一个指数来决定该局部响应对所讨论的激活的影响,较高的 β 将更多地惩罚对其邻居的激活,而较低的 β 将不会对其邻居的所讨论的激活产生太多影响。

因此,局部反应标准化有助于我们找出那些对其邻居表现更好的激活。这也有助于提高网络的效率,因为一些神经元将充当网络的核心,所以计算将会很快。

此外,它有助于减少冗余特征,假设许多相邻神经元具有高值,则它们将通过局部响应归一化来归一化,从而抑制冗余的连续特征。

因此,局部反应正常化也在相邻神经元之间产生竞争,以更好地学习将自己与邻近的其他神经元区分开来。所以,你可以称之为竞争正常化

局部响应标准化不再使用,因为我们更喜欢批量标准化,它在批量水平上工作,以消除内部协变量的变化。

与不可训练并且没有正则化效果的局部响应归一化相比,批量归一化是可训练的并且具有正则化效果。

重叠池

这是他们用过的下一个酷招。

通常,我们使用非重叠池,如下所示:

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

图一(来源:阿布舍克·维尔马)

但是,在 AlexNet 中,使用了重叠池。

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

图二(来源:阿布舍克·维尔马)

我们来了解一下背后的直觉。

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

照片由迈克尔·达姆Unsplash 上拍摄

给定一幅图像,我们推断出图像中物体的形状和边界,因为边界的两边有明显的区别。这也有助于我们确定物体在图像中的位置。

让我们以上图为例。我们的注意力集中在图像的对象上,也就是说,在这种情况下,是女孩。我们可以清楚地定位图像中的女孩,因为我们可以在脑海中围绕女孩画出边界。

这就是我们推断的图像中的空间信息。

在非重叠汇集的情况下,我们可以看到,由于汇集的不连续性,将会丢失一定量的空间信息,因为所有高值都将被捕获。

但是,在重叠汇集的情况下,我们可以看到,随着高值,一些低值密度高的区域,它们也将得到保护。空间信息是两者的结果,因此,在重叠池的情况下,它将被更好地保存。

什么是过度拟合?

当网络开始关注某个特定的特征时,任何偏离都会导致错误的预测。这种超敏感性导致泛化能力差。

因此,如果使用非重叠池,那么,网络将继续集中主要特征,只会导致灾难性的过度拟合。

但是,在重叠池的情况下,由于空间信息是守恒的,网络不会轻易溢出。

现在我还没有看到这种技术被普遍使用。最合理的原因是批量标准化,它具有正则化效果,还可以防止过度拟合。因此,为了节省空间,我们使用正常的非重叠池。

数据扩充

他们使用的第三个技巧是数据扩充。

我们希望我们的神经网络能够很好地泛化,因此,我们通过进行一些简单的操作和动态操作来增强我们的数据,即增强的图像是在训练时生成的(就像在 AlexNet 中一样)。

AlexNet 使用图像翻译和水平反射。在他们拥有的 256x256 的图像中,他们随机选取了 224x224 的图像以及它们的水平反射。因此,随机获取补丁的行为就是图像转换。至于水平翻转,我们来看这个例子:

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

来源:阿布舍克·维尔马

他们使用的第二种增强手段是我在别处从未见过的。他们改变了训练样本中 RGB 通道的强度。

他们首先对整个 ImageNet 训练数据集的 RGB 像素执行 PCA。他们提取了每个通道的主要成分。然后,他们将这些主成分的随机部分添加到图像的每个像素中。

它对图像所做的是改变照明的颜色和强度。因此,它利用了自然图像的一个特性,即物体的标签对于光照参数是不变的。一只狗是一只在明亮的白光和黄灯下的狗,句号!

这是我第一次与这种增强幽会,还没有看到它被使用。由于当今数据的巨大规模,当我们今天有其他随机操作用于增强时,如缩放、倾斜等,经历寻找主成分的痛苦似乎是低效的。

拒绝传统社会的人

这是他们用的第四招。老实说,这不需要介绍,因为这是今天减少神经网络过度拟合的事实上的方法。

丢弃是随机关闭一些神经元,这样,每个神经元被迫学习不依赖于其邻居的特征,从而导致更健壮的特征。

最后,让我们来统计一下对这个网络帮助最大的是什么:

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

来源:阿布舍克·维尔马

如果您对什么是前 1 名和前 5 名错误感到困惑,那么,我们知道 ImageNet 总共有 1000 个类。正常的方法是预测对应于最终层中最高值的类别,这里称为 top-1。另一种方法是采用 top-k 方法(在这种情况下,k = 5),这里,我们将预测作为对应于最终层中具有前 5 个最高值的单元的类。如果在这 5 条中,有任何一条符合事实,那么,我们认为这是一个成功的预测。

培训策略

他们使用的优化器 SGD with momentum 至今仍在使用,但需要一个适当的训练计划,因此很难训练。所以,事实上的优化者是亚当。在 AlexNet 的情况下使用了 0.9 的动量。

训练批量 128,不错,符合所有关于深度学习的建议。批量样本数量越多,模型越好。

重量衰减也使用了 0.0005 的值。体重下降在今天仍然很流行,并被用于模特身上来提高她们的表现。

权重初始化使用标准偏差为 0.01 的零均值高斯分布完成。在偏置初始化的情况下,在第二、第四、第五和更高密度层的情况下,它们已经用 1 初始化偏置,而其他层的偏置用 0 初始化。这种初始化最初通过给 ReLU 正输入来帮助网络。

学习率最初设定为 0.01,每当验证错误率停止提高时,学习率就会降低 10 倍。

我们终于了解了 AlexNet 的一切。

编码时间

资料来源:阿布舍克·维尔马

如果你想试试这段代码,我建议 Google 的COLAB**。这个用的是 TensorFlow 2.2.0。**我在这里使用了简单的 MNIST 数据集,并调整其大小以适应 AlexNet 输入。为什么?因为如果我们输入 28x28 图像可用 MNIST,这不会编译。试试看!第一次卷积后,就没有什么可以应用最大池了。

现在,我已经尽我所能从论文中吸收了更多的内容。首先,我没有使用两个词干,因为这不是 GPU 空间匮乏的古代。所以,我用了一个单独的茎。

在要点的第 37 行之前,我已经加载了 MNIST 的数据并对其进行了整形。我只取了 MNIST 的一小部分,因为加载它并调整它的大小会溢出内存,导致内核被转储。

第 38 行,我已经用tf.keras.layers.Conv2D定义了第一层。滤镜数量为 96,滤镜大小为 11x11,激活为relu,我用过的最后一个不熟悉的kernel_initializer是用均值为 0,标准差为 0.01 的高斯分布初始化权重,在论文中有提到。如果你想知道偏差,默认情况下,它们被设置为零。

行 42 处,我们有tf.keras.layers.MaxPooling2D,其中我将过滤器大小设置为 3x3,步幅设置为(2,2)。

行 44 处,我们又有了tf.keras.layers.Conv2D。在这里,有一点改变了,我也使用了一个保存值onesbias_initializer。如论文中所述,这是为了在该层设置偏差 1。

线 48 处,我们有一个tf.keras.layers.MaxPooling2D就像 42 线一样。

50 线,我们有tf.keras.layers.Conv2D。滤波器数量为 384,滤波器大小为 3x3,激活为relukernel_initializer已用于使用均值为 0、标准差为 0.01 的高斯分布初始化权重,如论文中所述,最后bias_initializer已用于将偏差设置为 1,如论文中所述

线 53 和 57 处,遵循与线 50 相同的模式。

线 61 处,我们有一个tf.keras.layers.MaxPooling2D就像 42 线一样。

在第 63 行的处,一个Flatten层被用来去掉多余的尺寸。这是正在发生的转变:

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

来源:Deep Tech Talker

第 65 行Dense层使用了 4096 个单位(在论文中,每个词干有 2048 个单位),kernel_initializer被用于初始化平均值为 0、标准差为 0.01 的高斯分布的权重,bias_initializer被用于初始化偏差为 1,如论文中所述。

行 69 处,Dropout已被使用并设置为0.5。在论文中,辍学的价值并没有具体提到与网络的关系,但是,在关于辍学的讨论中,他们谈到了这个价值,因此,我使用了它。没有明确提到所使用的辍学。

线 71 处,遵循与线 65 相同的模式。

线 75 处,遵循与线 69 相同的模式。

第 77 行,我们有预测层,这里,我们有 10 个类,相比之下,在 AlexNet 中使用的 ImageNet 中有 1000 个类。使用激活softmax和 10 个单位的Dense层进行预测。此外,kernel_initializer已被用于初始化具有平均值 0 和标准偏差 0.01 的高斯分布的权重。偏差隐含地为 0。

第 83 行,我们有model.compile,在这里我们决定优化器、损失和模型的指标。作者使用了动量为 0.9、重量衰减为 0.0005 的 SGD,但是在 TensorFlow 中没有 SGD 的重量衰减功能。所以,我只用过动量 0.9 的 SGD。根据论文已经使用了 0.01 的学习率。论文中的指标是前 1 名(相当于准确性)和前 5 名。这两个指标都设置在这一行中。损失是用于多级分类的categorical_crossentropy

第 89 行处,当验证误差没有改善时,我使用了ReduceLROnPaleau来降低学习率。对于多少个时代,他们看到它是否在改变,这在的论文中没有提到。这由所用函数中的patience属性设置。factor属性允许我们在论文中提到的学习率没有提高时,将学习率除以 10。min_lr显示了学习率的下限,这是作者在训练时设定的最小学习率。

线 93 处,我们拟合模型。根据文件设定了 128 个批次和 90 个时期。

今天,我们回顾并了解了第一个将 GPU 带到阳光下的开创性网络。这个网络单枪匹马撬动了图像深度学习的时代。它让 GPU 变得流行起来,而且它们会一直存在下去。

PCA 背后的代数

原文:https://towardsdatascience.com/algebra-behind-pca-7d801226f4e6?source=collection_archive---------49-----------------------

让 PCA 变得伟大的代数概要!

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

罗马法师在 Unsplash 上拍摄的照片

在我进行的一些采访中,我们最终会谈到降维技术。PCA 绝对是最受考生欢迎的一个。我个人不喜欢深入挖掘与角色不相关的领域,因为我自己可能也不知道答案!但是我喜欢问他们是否知道 PCA 是如何工作的。虽然我并不期望应聘者知道确切的代数,但我喜欢看他们是否有一些直觉,他们是否只是不知道(这对我来说完全没问题),或者他们是否试图假装他们知道,这就是我的大脑用黄色旗帜提醒我的地方。

一些候选人开始谈论 PCA 如何使用特征向量来计算最终特征。这里是我喜欢问的地方,什么是特征向量,PCA 计算的特征向量是什么?这是大多数候选人开始动摇的地方。同样,即使这不是成为一名数据科学家必须知道的事情,我个人也更愿意得到诸如我不确定之类的答案,而不是候选人不知道的事情。

在这篇文章中,我希望能帮助人们对 PCA 的实际工作原理有一些基本的直觉,并且在面试中有信心回答这个问题。

特征分解:特征值和特征向量

Eigen 来自德语,意思是拥有,因此可以将特征向量和特征值转换为矩阵的自向量和自值。但这实际上意味着什么呢?

让我们后退一步,把本征态的定义正式化。我们将矩阵 A 的特征值 a 定义为:

一个 v =一个 v

换句话说,对向量实施线性变换(保持和与乘的变换),通过标量改变*。因此,当且仅当 vA 的特征向量时,对 v 应用矩阵 A 的点积只会改变向量的长度而不会改变其方向!注意 A 是一个n×n矩阵,在做特征分解时会有 n 个特征向量和 n 个特征值。***

只是澄清一下,不是所有矩阵和向量之间的点积都满足这个条件。

必须是一个方阵(行数与列数相同)才能进行特征分解。除此之外,为了很好地定义特征向量,所有特征值必须互不相同。

最后,同样重要的是要注意,所有的特征向量都是相互垂直的,每个特征向量都有自己的特征值。

PCA 的代数

为了理解 PCA 的代数是如何工作的,我们先来思考一下 PCA 的目标是什么。使用 PCA,我们希望减少完整数据集中的特征数量,尽可能多地保留原始数据中的信息,并删除最高的相关性。

但是等等!我们如何衡量这些相关性来确定方向的优先级?嗯,我们确实有一个矩阵来跟踪不同特征之间的相关性,这就是 协方差矩阵 ,所以让我们使用它吧!

关于这一点,有一个快速说明:有其他矩阵可用于 PCA,但协方差矩阵是最流行和直观的一种。

因此,我们可以对协方差矩阵进行特征分解,看看哪些是具有更高特征值的特征向量。对应于最高特征值( x1 )的特征向量将是指示数据中最高方差的特征向量,因此是特征之间相关性最小的方向。第二个( x2 )将是垂直于 x1 的第二高方差方向,以此类推。

简而言之,一旦计算出协方差矩阵,如果想将 n 维从 n 维减少到 m 维,就很简单:

  • 第一步:计算协方差矩阵的特征向量。
  • 第二步:设置特征值最高的前 m 个特征向量。这将是你的旋转矩阵 W, 其中 W 中的每一行对应于排序后的顶部 m 特征向量。 W 是一个 m x n 矩阵。
  • 步骤 3 :给定一个数据点 x, 可以通过执行线性变换*x’= W x .*找到在 m 维空间中的投影,给定 W 是一个 m x n 矩阵,x’

例子

让我们看看下面的例子,以便更清楚地了解发生了什么:

假设我们有两个特征:给定城市中一套公寓的大小和该套公寓的价格。我们的任务是将数据缩减到 1D 空间。给定的数据集如下左图所示。

一个人应该采取的步骤是()同样,有多种方法可以做到这一点,我们只是举一个例子!):

  • ****第一步:根据你的数据定义协方差矩阵,计算你的协方差矩阵的特征向量。
  • ****第二步:特征向量在中间的图片中显示为绿色。最长的特征向量是对应于最高特征值的特征向量(特征向量通常被归一化为 1,这只是为了可视化的目的)。很明显,它是指向最高方差的方向。这是一个人想要保持的方向,因为它包含了最多的信息。
  • ****第三步:一旦确定了最高特征值对应的特征向量,就要把数据点投影到后者定义的直线上。如右图所示。

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

图 1:(从左到右)a)原始数据集 b)原始数据集连同协方差矩阵特征向量 c)原始数据集在最高特征值对应的特征向量所定义的直线上的投影。

我希望这能让你对使用 PCA 时发生的事情有一个基本的概念!

人工智能中的算法偏差需要讨论(和解决)

原文:https://towardsdatascience.com/algorithm-bias-in-artificial-intelligence-needs-to-be-discussed-and-addressed-8d369d675a70?source=collection_archive---------20-----------------------

你在这件事上有责任…

介绍

当人工智能用于解决全球性问题时,算法偏差可能会开始出现,并可能导致意想不到的不便、负面影响和损害。

对于那些不熟悉术语“算法偏差”的人,我将在本文中提供一个合适的定义。

但是,如果你曾经遇到过一篇新闻文章,指出某种形式的歧视是由人工智能或自动化系统传达的,那么你就会遇到算法偏见。

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

新闻标题中的人工智能偏见

算法偏差这个话题并不新鲜,我将提供几年前的几个偏差的例子。

我现在写这篇文章的原因是因为人工智能系统和机器学习解决方案在解决全球问题方面的快速应用。

更具体地说,在撰写本文时,有公司 、数据科学家、机器学习工程师和人工智能爱好者已经接过了衣钵,利用他们的技能来帮助对抗新冠肺炎·疫情。

理应如此。

但同样重要的是,这些公司和有才华的个人要明白,大量的人使用他们的系统,所以当涉及到算法偏差的问题时,需要某种形式的审查。

让我们开始吧

算法偏差

算法偏差这个话题很重要,也有些复杂,但是它的定义很简单。

算法偏差是从计算机系统的输出中出现的缺乏公平性。《算法偏差》中描述的不公平有多种形式,但可以总结为一个群体基于特定分类的歧视。

算法偏见有几种形式,例如,种族偏见,年龄歧视,性别偏见等。

我不知道读者的年龄、种族或性别,但我可以向你保证,每个人都容易受到算法偏见的危害。

原因

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

Artem Maltsev 在 Unsplash 上拍摄的照片

算法偏差的真正原因是什么,我们真的能指责谁吗?

今天,算法和机器学习系统中的偏见是许多情况的结果。

深度学习模型的工作方式是利用神经网络的模式识别能力。

因此,可以说深度学习模型不能通过设计直接产生偏差,任何偏差的出现或原因都是神经网络的架构和设计之外的。

机器学习模型和人工智能系统产生的输出只是它们所接触的训练数据集的反映。

所以,我们需要退一步,观察训练数据。

对于那些不知道的人来说,训练数据是输入到神经网络的预期类别的例子。这些示例反映了在现实生活场景中使用时暴露给神经网络的数据。

我认为,在人工智能系统中,训练数据主要通过两种方式导致算法偏差。

  • 数据收集者持有的个人偏见
  • 环境偏差在数据收集过程中有意或无意地施加。

请注意,训练数据可能会以其他方式导致算法偏差。我就着重说上面提到的两个。

像你我这样的人通常会收集训练数据。有意或无意地,我们都有内部偏见,这些偏见可以在建立机器学习模型时涉及的数据收集过程中反映出来。

环境偏差可能是为旨在全球范围内使用的人工智能系统在本地获取训练数据的结果。人工智能系统可能没有用足够的数据进行训练,这些数据代表了它预期运行的实际场景。

它发生了,而且还在发生!

2015 年,Jacky Alciné写了下面这条推文。他的推文表达了他对谷歌照片背后的分类算法的担忧。该算法把他的朋友误归类为大猩猩。

谷歌声称已经解决了这个问题。但在 2018 年,《连线》再次测试了该系统,似乎谷歌的解决方案是避免将大猩猩和其他一些灵长类动物完全分类。他们似乎只是简单地解决了这个问题。

时间快进到 2020 年 4 月,仍有消息称谷歌图片标签服务在对装有物品的手臂进行分类时表现出种族偏见。这个标签系统似乎把一个拿着一个物体的黑手归类为枪。

手持的物体是一个温度计,很多你可能在最近的新闻中看到过。在当前的新冠肺炎疫情期间,这些温度计正成为一种熟悉的景象,因为它们被用作识别患病个体的方法。

这种形式的偏见,以及许多其他形式的偏见,正在实时发生。

想象一下,在未来的五十年里,先进的机器人执法系统开始管理社区,它们无法区分一个持有非威胁性物品的有色人种和一把真正的枪。

更可悲的是,这与许多人今天面临的现实并不遥远。唯一的区别就是缺少机器人。但这是一个完全不同的对话,这是不断提出的。

我们来谈谈解决方案。

解决方案?

当想到算法和人工智能偏差的解决方案时,一个词浮现在脑海中。

多样性。

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

图片来自 Unsplash

向前迈出的一步将是在人工智能行业的任何流程或项目的早期阶段纳入多样性工作。我们甚至可以追溯到鼓励学术机构的多样性。

我经历过技术领域缺乏多样性。在我读机器学习和计算机视觉理学硕士期间,我能数清整个课程中黑人学生的数量。准确地说是四个,包括我自己。这门课有 200 多名学生。

机构内部缺乏多样性可能不是故意的,但这一问题应该得到可悲的解决。如果我们有更多具有不同背景的个人收集数据并建立人工智能系统,我们可能会看到以前可能被忽略的数据集片段的包含。

在整篇文章中,我关注的是人工智能系统中存在的种族偏见。但我们也应该意识到可能出现的其他形式的偏见。例如,卡内基梅隆大学的研究人员在 2015 年进行的研究揭示了谷歌广告中存在的性别歧视。

长话短说,与男性同行相比,女性不太可能看到高薪工作广告。

同样,这些系统中偏差的原因不能直接确定,但是解决方案可以在与 AI 产品开发相关的所有过程中实施。

一个良好的开端将是确保训练数据确实代表这些人工智能系统被利用的实际场景。

在法律和决策部门可以看到另一种解决办法。有组织的机构正在推动关键的政策制定者确保减少算法偏差的措施是一项强制性措施,而不是一项选择

在大多数情况下,构建人工智能系统的工程师并没有内在的偏见和对特定人群的偏见。

然而,由于缺乏对其他文化和各行各业的接触,在开发系统预期运行的实际现实和创造者打算如何使用它之间可能存在脱节。

公司和组织内部的道德教育是减少算法偏差的解决方案之一。对员工进行文化和生活方式差异方面的教育可以让他们意识到社会中可能被忽视甚至没有考虑到的群体。

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

Jonas Jacobsson 在 Unsplash 上拍摄的照片

一些公司正在人工智能领域做出积极努力,以增加学术机构和人工智能课程中代表性不足的群体。就拿 DeepMind 奖学金项目 来说吧。

该项目提供的奖学金面向低收入背景的个人;非洲或加勒比遗产或妇女。

要解决全球性的挑战,需要来自各种背景的优秀人才和个人的共同努力。这就是我们开始看到的。

走向可信的人工智能开发是由研究人员共同努力定义的一套指导方针,使开发人员能够在他们的人工智能系统开发中负责任。

你从哪里进来

这篇文章的大部分读者可能受雇于人工智能行业,有些人甚至可能直接参与设计在几个软件产品中使用的机器学习模型。我赞扬您花时间阅读这篇文章,并邀请您进一步探讨这个主题。

你是算法偏差整体解决方案的重要组成部分。解决方案从你开始。数据收集者、机器学习工程师、数据科学家和研究人员都扮演着至关重要的角色。

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

陈奕迅Unsplash 上的照片

每个机器学习从业者都应该意识到算法偏差可能导致的问题和潜在损害。

这篇文章不是为了羞辱个人或公司而写的。

相反,它是为了向人工智能社区表明,在算法偏见的问题上存在着争论。

我相信,为减少人工智能偏见而采取的对话和行动的增加,应该与人工智能本身的进步速度成比例。

感谢阅读。

[## 作为机器学习工程师你需要的 5 个软技能(以及为什么)

包括成为任何劳动力的有用组成部分的提示

towardsdatascience.com](/5-soft-skills-you-need-as-a-machine-learning-engineer-and-why-41ef6854cef6) [## 机器学习工程师和研究人员之间的 7 个关键区别(包括工资)

包含有关期望薪资、工作量、可交付成果以及更多关键差异的信息。

towardsdatascience.com](/7-key-differences-between-machine-learning-engineers-and-researchers-salaries-included-b62c3aaebde9)

算法偏差和混淆矩阵仪表板

原文:https://towardsdatascience.com/algorithmic-bias-and-the-confusion-matrix-dashboard-3926e0c0d329?source=collection_archive---------35-----------------------

在预测分数的分布下,混淆矩阵如何表现

随着算法越来越多地对人类事务做出决策,这些算法及其所依赖的数据必须公平和无偏见,这一点非常重要。算法偏差的诊断之一是混淆矩阵。混淆矩阵是一个表格,显示了在预测中会出现什么样的错误。虽然每个处理数据的人都知道什么是混乱矩阵 什么是 ,但是对于它在不同种类的预测和结果分布以及可能的决策阈值范围下如何表现,获得直觉是一件更微妙的事情。

在本文中,我将介绍一个交互式的 混淆矩阵仪表板 ,您可以使用它来探索不同的数据集和预测模型,并观察混淆矩阵的行为。您可以加载自己的数据。其中两个数据集是纯粹的合成分布,你可以调整旋钮。另一组数据包含了一些综合的例子,这些例子说明了算法偏差是如何与环境不平衡区分开来的。我所说的环境失衡是指不同的群体可能天生拥有不同的特征分布,从而导致不同的结果分布。我提出了一种预测偏差的新方法,称为阳性预测比得分(PPRS ),它独立于混淆矩阵,而是比较预测得分范围内的阳性结果比曲线。

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

混淆矩阵仪表板——钟形负面和正面结果分布。

混淆矩阵仪表板还包括两组关于严重事件的真实数据,并附有一些预测模型。一个有趣的模型是用于预测刑事累犯的 COMPAS 模型。COMPAS 模型因所谓的算法偏差而受到抨击。这种说法是基于不同种族群体的混淆矩阵中出现假阳性和假阴性率的方式。然而,没有单一一致的方法来定义算法偏差。混淆矩阵仪表板允许我们探索潜在的数据分布和预测模型可能引起可能被误导的偏见指控的方式。

为了配合本文,我准备了一些视频来介绍主要概念。这篇文章的 2 分钟宣传片是:

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

本文视频版本。

算法偏差和混淆矩阵仪表盘—宣传片

预测得分

为了理解混淆矩阵的目的,考虑一个为二元结果变量产生预测分数的过程。分配分数后,我们进行实验并进行观察。观察结果被记录为正面或负面。多次这样做,我们可以建立两个结果分布作为预测分数的函数,一个分布用于正面结果,一个用于负面结果。

混乱矩阵仪表板允许你试验两种不同的交互式合成分布。一个合成分布定义了正面和负面结果的分数,这些分数以凸起或“钟形曲线”的形式下降。您可以控制正负分数凸起的高度、宽度和位置。第二种分布沿预测分数轴更均匀地放置正面和负面结果分数。随着分数的增加,你可以玩这些分布的上升和下降。

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

例如:苹果零食

这是一个真实的虚构的例子。这个例子开始很简单,但是它允许我们评估算法偏差和公平性的概念。

假设你正在为 500 个孩子的学校野餐打包快餐盒。一些孩子喜欢苹果,而另一些喜欢其他东西,如爆米花、饼干或饼干。你有两种点心盒,一种装苹果,一种装别的东西。你必须事先决定给每个孩子哪种盒子,然后贴上他们的名字,分发给他们。当每个孩子打开他们的零食盒子时,他们要么会对他们的零食感到满意,然后说“耶!”,否则他们会失望地说“Awwww”。

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

为了帮助你做出决定,你可以根据一些经验来预测每个孩子喜欢哪种零食。大一点的孩子喜欢苹果,而小一点的孩子不喜欢。高个子孩子喜欢苹果,而矮个子孩子不喜欢。阿普尔鲍姆先生班上的孩子倾向于喜欢苹果,而爆米花女士班上的孩子想要别的。没有硬性规定,只是有根据的猜测。

对于每个孩子,你给他们一个分数,表明他们想要一个苹果的预测。10 分意味着你很确定他们会想要一个苹果,比如在阿普尔鲍姆先生的班上,一个 10 岁的高个子。1 分意味着你确信他们不会想要苹果,就像爆米花女士班上一个较矮的 6 岁小孩。

对于每个孩子,在计算他们的预测分数后,你做出决定。你可以在 5 分的中间点做决定。或者,您可以将苹果零食阈值设置得更高或更低。例如,如果孩子们吃水果很重要,你就把门槛设得低一些,这样你就能抓住更多喜欢吃苹果的孩子。或者,如果你想尽量减少扔进垃圾桶的苹果片,那么你可以把门槛设得更高,这样分发的苹果零食就更少了。换句话说,您的决定取决于对不同类型错误的权衡。

野餐时,你记录下孩子们的反应。你写下你给他们的预测分数是多少,你是否根据决策阈值给了他们一个苹果,他们的反应是什么。这是你的决定的回报。

我们在一个表格中记录结果,表格中的行对应于孩子的偏好,列对应于你给每个孩子一份苹果零食或其他零食的决定。混淆矩阵计算表中每个象限的数字和比率。

原始计数表位于左上方,而比率表位于右侧。

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

混淆矩阵:计数、比率、条件使用测量。

评估绩效

你的表现取决于几个因素:

  • 你的预测与每个孩子的需求有多吻合。理想情况下,你的预测会将所有想要苹果的孩子(红色)分布在右边,而所有没有苹果的孩子(绿色)分布在左边。这样你就可以把门槛放在中间,正确预测每个孩子的偏好。

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

零食偏好的理想可分分布。

  • 有多少孩子真的想要苹果。这是基本比率,红色苹果小孩和绿色非苹果小孩的总比例。

此时,您可能需要花点时间在混淆矩阵仪表板中玩一下双单峰分布合成器。用分数排列正(红)和负(绿)凸起,使分布完全分开。然后,通过让分布重叠来增加决策的难度。左右滑动阈值,查看混淆矩阵中的计数和比率如何变化。

评估你的表现有多种方法。你可以关注你预测正确的孩子的比例(TPR 和 TNR)。(TPR:真阳性率又称为 敏感性 ,TNR:真阴性率又称为 特异性 。)或者你可以专注于你弄错的孩子(FPR:假阳性率,FNR:假阴性率)。或者,你可以关注你认为想要苹果的孩子的比例,然后他们真的想要了。这叫精度*。精度,也称为正预测值(PPV),是 Berk 等人称为条件使用度量[1]的四个术语之一,如底部表格所示。*

然后,这些度量可以进一步组合成聚合度量,其名称如“准确性”、F1 分数和 MCC。

ROC(接收器工作特性)Precision/Recall 曲线显示了随着决策阈值的变化,一些指标如何相互权衡。你可以在维基百科和许多其他解释网站上阅读所有关于这些措施的内容。

虽然这里我们只考虑二元决策,但多变量预测会产生更多行和列的混淆矩阵,以及对其他性能指标的阐述。

预测偏差

考虑两个孩子群体,其中一个总体上更喜欢苹果(较高的基本比率),而其他人不太喜欢苹果(较低的基本比率)。然后,从数学上证明,如果正分布和负分布重叠(通过设置决策阈值不能完全分离),那么这两个群体的混淆矩阵条目在假阳性率、假阴性率、假发现率和假遗漏率方面不可能相同【2】【3】。然而,这些都是评估决策过程中的公平性和偏见的有效候选者。换句话说,不存在单一的方法来确定一个决策过程是否偏向于或反对预测一个群体对另一个群体的正面和负面结果。

为了更深刻地理解这一事实,我为苹果零食决策问题生成了合成数据。一个孩子相对于其他孩子对苹果零食偏好被认为是四个属性的线性函数,这四个属性是年龄、身高、老师和宠物。公式如下:

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

年龄从 6 岁持续到 10 岁。身高从 40 到 60 英寸不等。Class 接受三个分类值中的一个,{Ms. Popcorn=0,Miss Fruitdale=1,Mr. Applebaum=2}。宠物取四个值之一,{乌龟=0,鱼=1,猫=2,狗=3}。系数 c 为属性提供权重。为了简单起见,我们将所有系数设置为 1.0,但是将属性值规范化为范围 0 到 1。这样,所有属性都同等重要。预测分数被标准化为 0 到 1 的范围,然后被视为孩子更喜欢苹果零食(1.0)或其他零食(0.0)的概率。为了绘制图表,预测分数被划分成一定数量的箱。对于这个问题,20 个箱很好地显示了分布曲线。

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

产生孩子们对零食的偏好。

为了生成合成孩子、他们的预测分数和偏好结果,我们对四个属性的生成器分布进行采样。对于年龄和身高这两个连续的属性,让我们使用一个线性生成器分布,它可以在整个范围内是均匀的,也可以向下限或上限倾斜。如果年龄的发生器分布向上倾斜,那么年龄大的假装孩子会比年轻的多。因为对苹果的偏好随着年龄的增长而增加,那么这将使预测得分的分布更加倾斜。

类似地,对于这两个分类属性,我们可以说所有的教师被分配的概率相等,或者不同。例如,如果将更多的孩子分配给 Applebaum 先生,那么分数分布将会倾斜得更高,因为 Applebaum 先生贡献的预测分数因子为 2(在范围规范化之前),而 Popcorn 女士的预测分数因子为 0。

一旦通过从生成器分布中取样给一个孩子分配了属性,我们就可以将他们的预测分数视为偏好苹果零食的概率。然后,根据概率,通过投掷一枚有偏向的硬币来为那个孩子生成一个假装的偏好结果,从而完成样本。由于统计的可变性,每个预测得分箱的阳性和阴性结果的数量将随着试验的不同而不同。出于这个原因,在这些例子中,我选取了 100,000 个假装的孩子作为样本,只是为了平滑统计数据。

结果是正面结果偏好分布(偏好苹果零食)和负面结果的分布(偏好其他零食)。混淆矩阵仪表板包括五种不同的实验条件,不同的发电机分布:

***条件 1。统一:*所有属性在其范围内被统一采样。由于中心极限定理,这产生了预测分数的钟形分布。作为基于预测分数产生孩子实际偏好的结果,这导致积极结果和消极结果的分布在空间上有些分离。在中间设置阈值表明,这种分布实现了 0.64 的真阳性和真阴性率,以及 0.36 的假阳性和假阴性率。精确度和阴性预测值都是. 64。ROC 曲线的面积为 0.7,这通常被认为是可接受的预测能力,但远非完美。

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

苹果零食条件 1:均匀发电机分布。

为了探索算法偏差的问题,我按性别分离了生成器分布。女孩为四个属性中的每一个获得一个生成器分布,而男孩可能获得不同的一个。这反映了一个事实,不管出于什么原因,结果可能是女孩在人群中有不同的年龄范围,不同的身高范围,被不同地分配给教师,或者对宠物有不同的偏好。统一实验从对男孩和女孩使用相同的生成器分布开始。因此,毫不奇怪,它们各自的预测分布是相同的。

***条件二。偏斜相同:*所有属性都用偏向高端的生成器分布进行采样。越来越多的年长和高的孩子出生,然后越来越年轻和矮。与爆米花女士相比,更多的孩子被安排在阿普尔鲍姆先生的班级。更多的孩子把狗作为宠物,而不是乌龟。结果,零食偏好倾向于更喜欢苹果零食而不是其他零食。在偏斜相同的条件下,女孩和男孩的生成元分布是完全偏斜的。因此,他们得到的苹果零食偏好分布是相同的。

***条件 3。偏斜相反:*女生的属性采样为偏高的生成器分布,而男生的属性偏低,即男生更年轻,更矮,在爆米花先生的班级里更多,有更多的乌龟和鱼而不是猫和狗。因此,女孩偏爱苹果,而男孩偏爱其他零食。总体而言,女孩喜欢苹果的基本比率为 58%,而男孩喜欢其他的基本比率也是 58%。

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

苹果零食合成数据——女孩和男孩倾向相反的偏好。

最有趣的是比较混淆矩阵的四个象限。(我将使用近似值来说明采样噪声。)以 10 为阈值,在预测得分范围的中间,女生表现出的真实正率为. 79,真实负率仅为. 46。这是因为女孩的偏好偏向偏好分数中点右侧的苹果偏好女孩(红色)更多。对男孩来说,情况正好相反。类似地,女孩显示出 0.54 的假阳性率,因为她们对绿色(其他零食)的偏好有一半落在阈值的右边。他们的假阴性率只有. 21。同样,对男孩来说,情况正好相反。有趣的是,Precision (PPV)和 NPV 更接近,虽然不完全相同。

人们可能会看到这些混乱矩阵,并决定预测评分和决策过程是有偏见的。我认为,对女孩的偏见取决于你是否喜欢苹果。然而,有一种方法可以将 TNR、FPR、FNR 和 TPR 这四个象限统一起来。即向上调整女生的决策阈值,向下调整男生的决策阈值,直到隔着三个 bin。例如,将女孩阈值设置为 12,将男孩阈值设置为 9。当您在混淆矩阵仪表板中进行这些调整时,您可以看到各个 ROC 曲线上的决策点发生了变化。

由于前面提到的数学约束,这种调整使对准的精度(PPV)更加之外,并随之带来其他条件使用度量 NPV、FDR 和 FOR。你不能拥有一切。但是,如果您愿意,您可以调整阈值,使四个条件使用术语更加一致,代价是使女孩和男孩的四个正比率和负比率度量值进一步分离。

一般来说,学者和政策专家会举手表示,由于在混淆矩阵中找不到算法偏差的单一统一度量,因此必须根据政策来确定。也就是说,人群之间哪种性能指标的差异是可接受的,哪种是不可接受的?

毫无疑问,基于政策的权衡决策是必不可少的。但是作为一个技术问题,在评估预测偏差时,我们可以做得比仅仅依赖混淆矩阵更好。

受苹果零食实验的启发,让我们考虑一种不同的方法来判断预测分数是否有偏差。这种方法关注分数的一致性来预测结果。对于一个给定的预测分数箱,结果是否显示女孩和男孩以相等的比例更喜欢苹果零食或其他零食,而不管多少女孩或男孩碰巧有那个分数?这就是所谓的校准公平性【2】。该属性源自一个名为阳性预测比率的值,该值就是每个条柱中阳性结果的比例。在预测分数的范围内,阳性预测率描绘出一条曲线,在混淆矩阵仪表板中用褐色绘制。

正向预测比得分

在偏斜的相反发生器分布下,女孩和男孩的积极预测比率曲线是相同的。点击 PPRS 标签下的复选框,将它们叠加起来进行比较。这意味着预测分数准确地反映了模拟孩子的偏好,不管这个孩子是喜欢苹果零食还是其他零食的人群中的一员。

这一观察激发了基于两个群体的阳性预测比率曲线之间的差异的偏倚的汇总测量。具体来说,计算两条曲线之间的面积的函数。有许多方法可以做到这一点。我选了一个非常简单的:

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

这是两个群体(1 和 2)的阳性结果与所有结果之比 r 的平方差在预测分数仓上的总和,通过因子进行加权和归一化。加权因子是两个总体之间每个箱中的最小计数。这种加权的动机是当样本很少时,在样本噪声下概率可能变化很大。当任一群体在一个箱中放置少量样本时,阳性预测率的差异不显著。PPRS 测量受到统计噪声的影响,这取决于每个箱的样本大小。

偏斜相反情况的 PPRS 是 0.01。一般来说,在我的估计中,低于 0 . 2 的分数表示相对一致的阳性预测比率曲线,可以认为是无偏的,而高于 0 . 6 左右的分数表示曲线中有一些显著的偏差,并表明预测偏差。

预测偏差是什么样子的?接下来的两个生成器分布提供了示例。

***条件 4。偏斜相反偏向女孩:*像偏斜相反实验一样,生成器分布被设置成使女孩的零食偏好偏向高的一边,而男孩则偏向低的一边。但这一次,女生的预测分数统一下移 0.1(左移 2 格)。

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

请注意,在这种情况下,女孩和男孩的偏好分布表面上看起来比条件 3 更相似。绿色和红色曲线更接近对齐。但是通过改变女孩的预测分数,在每个箱中,男孩和女孩之间的积极预测与箱中孩子数量的比率现在非常不同。女孩得到的苹果会比她们喜欢的少。这种差异反映在阳性预测比率曲线中,这些曲线现在明显分开。它们之间的差距提供了 1.0 的 PPRS,这是预测偏差的重要指标。

条件 5。均匀随机化女孩:**这个实验从女孩和男孩的相同均匀发生器分布开始,与条件 1 相同。除了这一次,一半的女孩被随机选中,并被分配一个随机预测分数。你可以看到女孩的积极和消极结果分布(红色和绿色曲线)变平了。ROC AUC(曲线下面积)下降,越来越少的女孩得到她们喜欢的零食。PPRS 是相对较高的 0.75。

这个项目的 GitHub repo 中提供了使用您自己版本的生成器发行版来生成苹果点心样本的 Python 代码[4]。

真实世界数据:泰坦尼克号生存

我们可以在混淆矩阵仪表板中检查真实数据。一个众所周知的数据集列出了 1912 年泰坦尼克号沉没时幸存和遇难的乘客。对于每位乘客,数据集将年龄、性别、家庭规模、票价等级和票价等特征制成表格。泰坦尼克号的生存预测任务是 Kaggle.com 号的一个开始项目,80%的准确率是典型的。对于这个数据集,我建立了两个模型;他们的预测包含在混淆矩阵仪表板中。一个简单的模型是逻辑回归,它为每个可能的特征值计算一个权重因子(在一些简单的特征工程之后)。更复杂的机器学习算法是梯度推进回归器。这使用了决策树的集合,并且可以考虑观察到的特征之间的复杂非线性相互作用。对于该数据集和特征,GBR 模型的表现略好于逻辑回归,AUC 为. 86,最佳 f1 值为. 78(决策阈值= 4)。

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

泰坦尼克号的生存——梯度推进回归模型。

泰坦尼克号模型展示了许多有趣的特性。男性的存活率为 19%,而女性为 74%。女人和孩子先上救生艇!适当地,预测算法显示两个相距很远的凸起。查看男性和女性数据子集,绿色的阴性结果冲击发生在男性亚群中,而红色的阳性结果冲击发生在女性中。在中点决策阈值为 5 时,女性的真实阳性率(预测存活,并且确实存活)和男性的真实阴性率(预测不存活,并且没有存活)都非常高。男性和女性乘客的假阳性和假阴性率高度不对称(FNR = .79(m)/.1(f),FPR = .02(m)/.58(f))。这反映了大多数男性的生存概率较低,而大多数女性的生存概率较低,尽管两个方向都有异常值。由于提供了相对简单的乘客特征集,模型无法可靠地预测异常值。在这些泰坦尼克号生存模型的男性/女性分类下,阳性预测比率曲线和 PPRS 不能提供信息,因为结果分布几乎没有重叠,为比较中等范围分数仓中的阳性预测比率留下非常稀疏的统计数据。

真实世界数据:布劳沃德县累犯

2016 年 5 月, ProPublica 发表了一项名为“机器偏见:全国各地都有用来预测未来罪犯的软件。而且对黑人有偏见。”【5】。这篇文章评估了一种叫做 COMPAS 的算法,该算法用于预测刑事案件中的累犯率。伴随本文的是一个 github 知识库,其中包含了用于评估 COMPAS 算法性能的数据和数据分析方法。

ProPublica 的文章提出了以下主张:

正如霍尔德所担心的那样,我们还发现了明显的种族差异。在预测谁会再次犯罪时,该算法对黑人和白人被告犯错误的比率大致相同,但方式非常不同。

  • 该公式特别容易错误地将黑人被告标记为未来的罪犯,错误地将他们标记为白人被告的比例几乎是白人被告的两倍。
  • 白人被告比黑人被告更容易被误标为低风险。”

关于算法偏差的说法令人担忧,这篇文章被大量引用。毕竟,公平起见,在无偏算法下,我们可能期望两个方向上的误差平均分布。ProPublica 的指控是基于黑人和白人亚群混淆矩阵中假阳性率和假阴性率的差异。

然而,我们从苹果零食的例子中看到,对偏见或不公平的解释并不简单。基本比率、混淆矩阵中的正比率和负比率以及条件使用度量(其中最著名的是精确度(PPV),但也包括负预测值(NPV)、错误遗漏率(FOR)和错误发现率(FDR))之间存在很强的相互作用。犯罪学、统计学和计算机科学文献已经详细讨论了这些算法之间的权衡,COMPAS 算法的公平性也引起了激烈的争论[1,6,7,8,9]。苹果零食的例子表明,不同群体之间偏好分布或结果概率的差异本身并不是预测偏差的指标。总的来说,不管出于什么原因,参加野餐的女孩可能比男孩更喜欢苹果零食。

我们可以使用混淆矩阵仪表板查看布劳沃德县累犯数据,并测试不同的决策阈值如何影响混淆矩阵及其导数分数。布劳沃德县的 COMPAS 决策阈值设定在十分位数 4。ProPublica 数据集不仅提供了由 COMPAS 算法产生的累犯预测,还提供了实际的预测分数,这些分数被称为“十分位数”,因为 COMPAS 报告的预测分数范围是从 1 到 10。该信息还允许我们比较亚群体间的阳性预测率曲线,并计算 PPRS(阳性预测率得分)。

检查混淆矩阵仪表板中的数据源 Broward recipiency-COMPAS 模型,我们证实,的确,在阈值为 4 时,黑人被告的假阳性率为. 42,而白人被告的假阳性率仅为. 22。白人被告的假阴性率是 0.5,而黑人被告的假阴性率是 0.28。

这种差异必须根据黑人被告的基本税率为 0.52,而白人被告的基本税率为 0.39 这一事实来评估。这反映在黑人被告堆积柱状图中红色(正)柱的数量更大。然而,类似于我们在苹果零食实验条件 3 中看到的,这种差异可以通过将黑人被告的决策阈值向上调整到 5,将白人被告的决策阈值向下调整到 3 来消除。这使两个群体的 TPR/FPR 点在 ROC 曲线上一致,尽管它进一步加剧了精确度和阴性预测值的差异。显然,为不同的受保护群体设置不同的门槛会被认为是不公平的。

问题是,FPR 和 TPR 的差异是由于预测偏差,还是由于两个亚人群之间环境特征的差异?值得注意的是,COMPAS 算法根据两组的实际累犯结果一致地分配预测分数。阳性预测比率曲线非常好地对齐,并且它们之间的间隙的 PPRS 测量获得相对小的值 0.17,表明良好的校准准确度。

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

布劳沃德累犯模型。

COMPAS 算法在 1-10 的十分位数范围内分配相对均匀的预测分数;与苹果零食合成数据不同,分布不是钟形的。除了基本比率之外,黑人和白人被告人群之间最明显的差异是黑人被告被分配到大致相同的位置,而白人被告被发现在较低的十分位数分数中所占比例更大,随着十分位数分数的增加而稳步下降。您可以使用混淆矩阵仪表板的近似线性数据源下拉菜单来近似这些分布,并查看混淆矩阵中的项如何响应。

布劳沃德县累犯的独立预测模型

调查累犯数据集的另一种方法是建立一个独立的模型,保证排除种族因素。假设我们观察到累犯与种族或性取向相关。那么这些因素实际上将是累犯的预测因素,在统计基础上。但是,在一个公平的社会中,我们同意应该根据个人的优点而不是根据他们碰巧属于哪个身份阶层来判断个人。

ProPublica 报道说,在大多数被告被关进监狱的时候,他们会回答 COMPAS 的调查问卷。这些信息被输入到 COMPAS 算法中。不清楚该算法到底使用了什么信息。如果使用种族或其他受保护的阶级因素,那么这可能是不公平的。

为了消除这种可能性,我们可以只提取直接基于犯罪记录的数据,并从中建立一个模型。与泰坦尼克号数据一样,我建立了线性回归模型和梯度推进回归模型。作为比较,两者都包含在混淆矩阵仪表板中。我仅从数据记录中提取了以下特征:

  • 年龄
  • 少年 _ 恶魔 _ 计数
  • juv_misd_count
  • 青少年 _ 其他 _ 计数
  • 先验计数
  • 电荷度
  • desc 充电

这些特征与年龄、前科和指控类型有关。在此数据集中,预订时只输入了一项费用,因此原始 c_charge_degree 和 c_charge_desc 要素有且只有一个值。

为了在算法中使用这样的特征,数据科学家将它们转换成可能与我们想要预测的结果相关的数字。因此,我做了一些特征工程。我将原始年龄分为五个年龄组:{ 18–22,23–33,34–50,51–59,60+}我将计数特征分为四个或五个类别的组。对于电荷描述,我创建了一个“一键”向量。我把所有与毒品相关的指控归为一项。我将少于 10 个实例的所有费用描述归入一个名为“其他”的费用类别。然后,对于每个类别,如果该费用在原始“c_charge_desc”特征中报告,则我指定 1,否则指定 0。最后,我加入了一个数字特征,这是适用的指控描述的平均累犯率。

为了训练模型,我们注意到报告变量的观察值‘two _ year _ recid’。如果被告再犯,结果值(或因变量)为 1,如果他们在两年内没有再犯,结果值为 0。

在预测时,独立特征被输入到模型中以产生预测分数。下面是 GBR 模型的结果,显示在混淆矩阵仪表板中。预测分布的形状不同于 COMPAS 模型。但是黑人被告和白人被告之间假阳性率和真阳性率的差距仍然存在。与 COMPAS 模型一样,通过为两个子群体选择不同的决策阈值(这被认为是不公平的),可以使这些混淆矩阵条目一致。最后,与 COMPAS 模型一样,阳性预测比率曲线排列良好,预测偏差的 PPRS 较低,徘徊在约 0.09。同样,这是排除了种族和性别特征的模型。

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

预测模型的一个问题是数据泄漏。尽管种族、性别或其他受保护的特征可能被正式排除在考虑之外,但这些因素有时可以从其他因素中推断出来。例如,众所周知,在设定保险费率时,邮政编码红线被用作种族的替代特征。

在女孩和男孩具有不同特征生成器分布的合成苹果零食数据的情况下,人们可能会将年龄、身高、老师和宠物这些看似良性的特征解释为孩子性别的反向通道指标。没关系。即使你直接把性别作为一个特征包括进来,女生和男生分布的形状还是一样的。我们在苹果零食条件 4 和 5 中实现预测偏差的方式不是通过在预测分布的形成中引入性别因素,而是通过干扰预测分数的应有值。

在布劳沃德累犯数据的情况下,有可能使用诸如年龄、前科、指控严重程度等特征。反映了刑事司法系统或社会中的种族偏见。我们不能在这里解决这些因素,我们也不能对基础数据或整个刑事司法系统的公正性下结论。在这里,我们只是根据收集的数据集,关注对未来实际记录在案的累犯的预测。

我的结论是,布劳沃德预测算法是而不是有偏的,因为它们在这两个亚群体之间的预测分数有差异分布。在保留基本比率(再分(红色)和非再分(绿色)计数的总数)的同时,将被告铲到预测得分轴的其他地方,会扭曲相应的正预测比率曲线,并增加预测偏差的 PPRS 度量。更正确的解释是,根据获取数据特征和结果的方式,黑人被告亚群固有地表现出更大比例的特征,这些特征将他们置于更高的预测分数。FPR、TPR 和有条件使用措施的差异是其不可避免的后果。

结论

这将是一个很好的逃避难题的选择不相容的和令人困惑的所谓偏见的措施仅仅基于混淆矩阵和它的衍生指标。在这篇文章中,我提出了一个新的预测偏差的衡量标准,积极预测比得分(PPRS)。这更直接地比较了作为亚群体间预测得分函数的结果的一致性,而不考虑控制混淆矩阵中术语的决策阈值。PPRS 测量与校准准确度一致,并且当群体具有不同的基础率和分布时,它不试图校正由于在决策阈值中进行选择而产生的比率差异。根据这一标准,在 Broward 累犯数据中观察到的种族群体之间的差异是由于其特征特性的环境分布的差异,而不是由于任何预测算法的偏见。

公平合理地使用算法和数据是一个巨大而困难的问题。社会通过无数的数据收集和决策过程发挥作用。早在信息时代到来之前,规则、指导方针和程序就已经进化到在经济和治理方面取得系统性成果。从这个意义上说,当人类遵循既定的政策时,他们是在执行一种算法决策。人类的判断带有主观性的好处和代价。除了严格的规则和正式的指导方针之外,人们还能够考虑那些数字和分类账不容易捕捉到的因素。因此,他们可能会有意识或无意识地权衡超出合法范围的因素。他们带来同情和洞察力,怨恨和怨恨。

形式化数据收集和算法的一个承诺就是效率和规模。要素的数量以及处理它们的速度和效率远远超过了训练有素的专业人员、官员和代理人的能力。

算法的第二个承诺是,它们允许在决策过程中控制因素和一致性。输入变量可能不会对人类背景故事进行编码,而人类背景故事可能会令人同情地左右决策。但是他们也排除了基于不公正的偏见而影响决策的因素。形式化算法的影响必须在系统层面进行评估。这包括理解如何收集数据,如何从数据中提取特征,以及如何做出算法决策。

因为计算算法采用了普通人不熟悉的技术,有时甚至连专家都难以完全理解或解释的过程(如一些机器学习算法),所以它们受到怀疑和审查是自然和适当的。当算法因为有偏差的数据或设计不当而做出糟糕的决策时,就必须被叫出来。相反,算法不应该因为正确计算出反映其系统环境令人不快的属性的结果而受到诽谤。这样做将会失去一个强大的工具,这个工具能够消除偏见和成见,增加社会的公平性。

混淆矩阵是一个相对简单的概念,无论预测分数是通过机器算法还是其他方式分配的。但是它在不同类型的数据下的行为是微妙而复杂的。通过交互式混淆矩阵仪表板,我们打算让算法和人类预测和决策的行为更加容易理解和透明。

参考

*[1] R. Berk,H. Heidari,S. Jabbari,M. Kearns 和 A. Roth,《刑事司法风险评估中的公平性:现状》,*社会学方法&研究,第 1–42 页,2017 年。

[2] J. Kleinberg、S. Mullainathan 和 M. Raghavan,“公平确定风险分值的内在权衡”,载于第八届会议。论理论计算机科学的创新(ITCS)* ,2017。*

[3] S. Goel,E. Pierson 和 S. Corbett-Davies,“算法决策和公平的成本”,载于2017 年第 23 届 ACM SIGKDD 知识发现和数据挖掘国际会议*。*

[4] E .索恩,“索恩/算法偏差”,2020 年。【在线】。可用:https://github.com/saund/algorithmic-bias

[5] J. Angwin、J. Larson、S. Mattu 和 L. Kirchner,“机器偏见:全国各地都有用来预测未来罪犯的软件。而且对黑人有偏见”2016 年 5 月。【在线】。可用:https://www . propublica . org/article/machine-bias-risk-assessments-in-criminal-pending/。

*[6] A. Flores,K. Bechtel 和 C. Lowenkamp,“假阳性、假阴性和假分析:对《机器偏见:全国各地都有用来预测未来罪犯的软件》的反驳。而且对黑人有偏见。”、“*联邦缓刑,2016 年第 80 卷。

[7] W. Dieterich,C. Mendoza 和 T. Brennan,“COMPAS 风险量表:证明准确性、公平性和预测性”,2016 年 7 月 8 日。【在线】。可用:https://www . document cloud . org/documents/2998391-ProPublica-commentation-Final-070616 . html .

[8] J. Angwin 和 J. Larson,“ProPublica 回应公司对机器偏见故事的批评”,2016 年 7 月 29 日。【在线】。可用:https://www . propublica . org/article/propublica-responses-to-companies-critical-of-machine-bias-story。

[9] J. Angwin 和 J. Larson,“研究人员说,犯罪风险得分的偏差在数学上是不可避免的”,2016 年 12 月 30 日。【在线】。可用:https://www . propublica . org/article/bias-in-criminal-risk-scores-is-mathematical-ability-researchers-say。

算法调色板

原文:https://towardsdatascience.com/algorithmic-color-palettes-a110d6448b5d?source=collection_archive---------29-----------------------

使用机器学习从图像生成调色板

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

特雷·拉特克利夫 ( 来源)用我生成的调色板拍摄的照片。

我最近在做一个项目,在这个项目中,我希望能够比较图像的外观和感觉,这促使我寻找一种使用机器学习来创建调色板的方法。

生成调色板可以被认为是一个伪装的聚类问题。我们希望将一幅图像的所有像素划分成最能代表该图像的 k 个不同的组。

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

来源:维基百科–RGB 色彩空间

我们可以把我们的图像看作是在 3D 色彩空间中绘制的点的阵列,而不是把我们的图像看作是像素的网格——每个像素都有一个红色、绿色和蓝色的值。红色有一个维度,绿色有一个维度,蓝色有一个维度,在每个维度中,一个点可以位于0255之间的任何位置。

假设我们希望创建一个由 8 种颜色组成的调色板来代表每张图片。这意味着我们想要找到 8 个能够给出每幅图像的最佳可能表示的聚类或分区。

有许多不同的聚类算法可供选择——每种算法都有自己的优缺点——但是为了这个项目的目的,我尝试了 K-Means 聚类和凝聚聚类。

我从电影只有上帝宽恕(2013) (使用网站 FILMGRAB )中挑选了 5 张样本剧照,因为它有丰富的调色板。

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

仍然来自只有上帝宽恕(2013) ,由 FILMGRAB 提供,使用 k-means 生成调色板。

上面是一个使用 K-Means 生成的电影静止图像和调色板的例子。正如你所看到的,该算法做了一个相当好的工作,没有太多的超参数调整,使一个很好的代表性调色板。此外,它允许您指定调色板的大小——这是其他一些聚类算法(例如 DBSCAN)所不具备的。

你可以在我的笔记本中看到更多生成调色板的例子。

算法挑战

事实证明,像 K-Means 这样的算法更喜欢高容量的颜色,而不是稀疏但突出的颜色。例如,参见下面的静止图像。

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

仍然来自《只有上帝宽恕》(2013) ,由 FILMGRAB 提供,使用 k-means 生成调色板。

K-Means 调色板可以很好地近似大多数颜色,但在查看图像时,您可能会期望它包含一些蓝色(如摔倒的拳击手的垫子或短裤上)或红色(如绳子上,或站立的拳击手的手套/服装等)。

回想一下 K-Means 是如何工作的,该算法试图将图像中的颜色划分为 k 组,由颜色空间中的 k 个平均点表示。在这种情况下,图像中没有足够的蓝色或红色被算法提取出来,所以它们被其他类似的、更丰富的颜色洗掉了。

为了解决这个问题,我们可以尝试一些方法。

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

仍然来自《只有上帝宽恕》(2013) ,由 FILMGRAB 提供,使用 K-Means 和聚合生成的调色板。

上图显示了使用 K-Means 和凝聚聚类生成的调色板。凝聚聚类选择在调色板中包括蓝色,尽管它失去了柔和的黄色,仍然没有包括任何红色。

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

仍然来自Only God forgible(2013),由 FILMGRAB 提供,带有 k-means RGB 和 HSV 生成的调色板。

另一种方法是将图像的颜色从RGB转换为HSVRGB将颜色表示为红色、绿色和蓝色通道强度的组合,而HSV将颜色表示为色调(基色的光谱)、饱和度(颜色的强度)和值(颜色的相对亮度或暗度)——你可以在这里了解更多关于的信息。上图显示了使用 K-Means 聚类和RGB颜色和HSV颜色为同一幅图像生成的调色板。正如你所看到的,HSV 方法包括蓝色和黄色(尽管仍然没有红色)。

为了进一步改善结果,一些选项包括组合技术(即凝聚聚类+ HSV 颜色),超参数调整,使用不同的算法(如 DBSCAN),以及调整颜色距离度量(如果你感兴趣,可以在这里阅读更多关于颜色差异的信息)。

烧瓶应用程序

作为最后的奖励,我决定创建一个简单的概念验证 API,用于从图像生成调色板。API 将图像 URL 作为参数,并使用 K-Means 生成调色板。

此外,我发现网站 Coolors 使得创建调色板 URL 变得很容易,因此 API 可以将调色板作为颜色的 2D 数组或 Coolors 调色板的 URL 返回。

例如,使用此图像…

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

还是出自只有上帝会原谅(2013) ,承蒙 FILMGRAB

API 将产生以下链接…

[## Coolors.co

在 Coolors.co 上查看和编辑调色板或创建自己的配色方案。

coolors.co](https://coolors.co/3c030b-050002-3967cd-152f63-760102-7e504c-110c33-b4d1df)

一起看,你会得到…

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

仍然来自《只有上帝宽恕》(2013) ,由 FILMGRAB 提供,k-means 生成调色板由 Coolors 提供。

你可以在我的 GitHub repo 里查看 Flask app,这里

结论

这是一个很短但很有趣的副业,这里肯定还有很多值得探索的地方。如果你认为你可能会感兴趣,一定要去看看电影抓取酷人

你可以在 GitHub 上找到我的代码,或者用 nbviewerBinder 查看笔记本。

感谢阅读!我很想听听你的想法。请在下面发表评论,或者在 LinkedIn 或 Twitter 上联系我。

算法复杂性

原文:https://towardsdatascience.com/algorithmic-complexity-244bde1c3548?source=collection_archive---------43-----------------------

真实网络中的社区发现算法

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

扎卡里的空手道俱乐部网络与 2 个社区确定。

由于真实网络的规模,使用强力算法来定义社区有时是不可行的。用于处理这些问题的算法,在最好的情况下,在多项式时间内运行。虽然,大多数时候,有必要探索随着网络规模增长的指数数量的可能性。第一个问题叫做 P 问题,第二个问题叫做 NP 问题

在接下来的章节中,我们将探究 P = NP 的问题,并大致介绍这种证实或反驳的后果。之后,介绍了一个根据算法的速度和内存需求来描述算法复杂性的系统——Big-O 符号。

p 对 NP 问题

P vs NP 问题由 Stephen Cook [1]于 1971 年提出,并在 2000 年被认为是计算机科学中最重要的公开问题之一[2]。这是克莱数学研究所定义的七个千年奖问题[3]中的六个问题之一。能够解决其中一个问题的人将获得 100 万美元的奖金。 P vs NP 问题可以表述为:每一个其解可以被计算机快速验证的问题是否也可以被计算机快速求解?【4】。

P 问题的特征在于可通过确定性图灵机(DTM)在多项式时间内求解。另一方面, NP 范畴包括那些仅使用非确定性图灵机(NTM)在多项式时间内可解的。它们都是一组二元决策问题的一部分。DTM 是一台没有分支的机器,每次只能进行下一步。这是一台普通电脑的工作原理。NTM 是一台概念性的机器,能够在每一步同时分析多项式数量的不同选项。因此,一个分支装置。一个快速验证的解意味着它可以在多项式时间内找到。计算机这个词指的是决定性的图灵机(DTM)。

虽然 P = NP 这个问题还没有答案,但是根据定义,这两个组之间存在联系。 NP 问题包括那些在 DTM 中其解可能无法得到但可以在多项式时间内验证的问题。这意味着每一个 P 问题都属于 NP 问题,验证一个解决方案总是比找到它容易。他们可以在多项式时间内找到它。平凡地,𝑃 ⊂ 𝑁𝑃.

一类不同的问题是 NP 完全问题。不仅是 NP,也是 NP 难(图 1)。当一个属于 NP 的算法可以化简为第一类中的另一个算法时,问题就是 NP 难的。这意味着 NP-hard 类中的任何问题至少和 NP 中的任何问题一样难解决。简化项意味着问题𝐴的输入可以使用多项式时间算法转换为问题𝐵的输入,并提供完全相同的输出。如果𝐴被简化为𝐵,这将会带来几个直接的后果:

  1. If𝐵∈𝑃,然后是𝐴∈𝑃;
  2. If𝐵∈𝑁𝑃,然后是𝐴∈𝑁𝑃;
  3. 如果𝐴是 NP 难的,那么𝐵就是 NP 难的。

因此,如果找到了 NP 完全问题的多项式时间的解,那么 P 对 NP 问题被解决,并且𝑃 = 𝑁𝑃.因此,不仅找到多项式解,而且证明𝑋问题是 NP 完全的也是基本的。根据上述定义,这可以分为两个步骤:

  1. 显示𝑋属于 NP。这可以通过在多项式时间内验证给定的解或找到𝑋的非确定性算法来完成;
  2. 展示𝑋是 NP 难的。通过将一个已知的 NP 完全问题简化为𝑋.问题在这种情况下,上面得到的第三个结果意味着𝑋是 NP 难的。

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

图 1 P vs NP 问题图示表示[5]。

尽管没有得到证实,但大多数计算机科学家𝑃 ≠ 𝑁𝑃相信这一点[6]。证明𝑃 = 𝑁𝑃将在现实世界中产生重要的影响。不仅生物模型将得到加强,而且运输系统、多媒体处理、经济模拟等方面的效率也将大大提高。另一方面,有基于𝑃 ≠ 𝑁𝑃.事实的真实系统其中之一是现代密码系统,它依靠质因数分解来保护数据。这个问题被认为是 NP

网络科学中很大一部分问题是 NP、NP 难或 NP 完全的。因此,该解决方案在例如寻找系统发育网络中的社区中的重要性就不足为奇了。

接下来给出算法时间/存储器复杂性的数学表示。

大 O 符号

在分析算法性能时,通常会考虑时间和内存的复杂性。当计算能力有限,需要进行大数据分析时,它们尤为重要。

在某些情况下,同一问题的解决方案可以在不同的时间范围内找到。出于这个原因,重要的是要有一种方法来上限绑定算法的执行时间,而且要估计它的平均值。这导致了 Big-O 符号的产生。

根据算法必须执行的指令数量和输入的大小,运行时间会有所不同。Big-O 符号提供了一种量化算法执行需求的方法,独立于运行它的机器。确定的复杂度可以是线性的、对数的、二次的、三次的、指数的…表 1 给出了一个有序的列表,按照最常见算法的执行时间(有一些例子)。

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

表 1 一些最知名的算法方法的时间复杂度。

在确定了算法的复杂性之后,就有可能预测执行该算法的机器的时间和内存需求。

定义

一个函数𝑓(𝑁)称为𝑂(𝑔(𝑁))如果常数𝑘和𝑁0 存在,使得 0 ≤ 𝑓(𝑁) ≤ 𝑘 × 𝑔(𝑁)对于全𝑁≥𝑁0 [12]。

参考

[1] S. A. Cook,“定理证明程序的复杂性”,第三届 ACM 计算理论年会论文集(STOC’71) ,1971 年。

[2] L. Fortnow,“P 与 NP 问题的现状”,《美国计算机学会通讯》,,第 52 卷,第 9 期,第 78–86 页,2009 年。

[3] C. M .研究所,“P 对 NP 问题”,[在线]。可用:https://www.claymath.org/millennium-problems/p-vs-NP-问题。[访问日期:2019 年 5 月 15 日]。

[4] N. Viswarupan,“P vs NP 问题”,Medium,2017 年 8 月 17 日。【在线】。可用:https://medium.com/@niruhan/p-vs-np-problem-8d2b6fc2b697.【2019 年 5 月 15 日获取】。

[5]“P 对 NP 问题”,维基百科,[在线]。可用:https://en.wikipedia.org/wiki/P_versus_NP_problem.【2019 年 5 月 12 日访问】。

[6] J. Rosenberger,“P 与 NP 民意测验结果”,*《美国计算机学会通讯》,*第 55 卷,第 5 期,第 10 页,2012 年。

[7] E. Ravasz,A. L. Somera,D. A. Mongru,Z. N. Oltvai 和 A. L. Barabá si,“代谢网络中模块化的层次组织”,*《科学》,*第 297 卷,第 5586 期,第 1551-1555 页,2002 年。

[8] M. E.J .纽曼和 m .格文,“发现和评估网络中的社区结构”,*《物理评论》。统计、非线性和软物质物理学,*第 69 卷,2004 年。

[9] M .格文和 M. E. J .纽曼,“社会和生物网络中的社区结构”,*美国国家科学院学报,*第 99 卷,第 12 期,第 7821-7826 页,2002 年。

[10] M. E. J. Newman,“检测网络中社团结构的快速算法”,*物理评论 E,*2004 年第 69 卷第 6 期。

[11] G. Palla,I. Deré nyi,I .法卡什和 T. Vicsek,“揭示自然和社会中复杂网络的重叠社区结构”,*《自然》,*第 435 卷,第 814-818 页,2005 年。

[12] T. H. Cormen,C. E. Leiserson,R. L. Rivest 和 C. Stein,《算法导论》,麻省剑桥:麻省理工学院出版社,2003 年。

算法投资组合对冲

原文:https://towardsdatascience.com/algorithmic-portfolio-hedging-9e069aafff5a?source=collection_archive---------6-----------------------

动态套期保值的 Python 和 Black-Scholes 定价

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

来自佩克斯叶戈尔·卡梅列夫的照片

来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

期权投资组合

直接暴露于特殊和系统风险的股票。另一方面,期权不仅暴露于标的资产,还暴露于利率、时间和波动性。这些风险是布莱克-斯科尔斯期权定价模型的输入(参见推导布莱克-斯科尔斯模型)。由于这些输入会影响所讨论的期权的价值,函数的偏导数可以告诉我们,当其中一个风险敞口发生变化,而其他风险敞口保持不变时,期权的价值会如何变化。让我们首先讨论这个期权定价模型的所有偏导数,然后用 Python 编写一个算法对冲系统。

希腊人

使用泰勒级数展开,我们可以得到所有的希腊人。希腊人告诉我们,当一个或多个期权敞口发生变化时,我们可以预期一个期权或期权组合会发生变化。需要注意的是,所有一阶近似都是线性的,而期权定价函数是非线性的。这意味着基础参数偏离初始偏导数计算越多,它就越不精确。这就是为什么希腊人通常是实时更新的,所以当某事发生变化时,我们可以不断地对期权或投资组合价值有一套新的预期(更多信息请参见 Python 中的期权希腊人)。

注意:在以下情景中,我们通常会考虑看涨和看跌期权,一些更高级的价差可能是多头或空头,具有不同的敞口平价。

三角洲

Black-Scholes 方程的基础资产的一阶偏导数称为 delta。Delta 是指当基础资产价格发生变化时,期权价值如何变化。在其他参数保持不变的情况下,将 delta 乘以标的资产的+/-1 美元的变化,将得到期权的新价值。对于多头买入和空头卖出头寸,Delta 为正值,对于空头买入和多头卖出头寸,Delta 为负值。

微克

Black-Scholes 方程的基础资产的二阶偏导数称为 gamma。Gamma 是指当基础资产价格发生变化时,期权的 delta 如何变化。将 gamma 乘以标的资产的+/-1 美元变化,保持所有其他参数不变,将得到期权 delta 的新值。本质上,gamma 告诉我们 delta 的变化率,给定基础资产价格的±1 变化。对于多头头寸,Gamma 始终为正,对于空头头寸,Gamma 始终为负。

低湿平原

Black-Scholes 方程的基础资产波动率的一阶偏导数称为 vega。Vega 是指当标的资产波动率发生变化时,期权价值如何变化。将 vega 乘以标的资产波动率的±1%的变化,保持所有其他参数不变,将得到期权的新价值。 Vega 对多头头寸为正,对空头头寸为负。

希腊字母的第八字

Black-Scholes 方程中期权到期前时间的一阶偏导数称为θ。θ是指期权价值如何改变久而久之。一般按年计算,theta 指的是一个期权在一天过去后的价值变化。对于空头头寸,θ为正,对于多头头寸,θ为负。

希腊字母的第 17 字

Black-Scholes 方程关于无风险利率的一阶偏导数称为 rho。Rho 是指期权价值随着利率的变化而如何变化。将ρ乘以利率的±1%的变化,保持所有其他参数不变,将得到期权的新价值。 Rho 对于多头买入和空头卖出头寸为正,对于空头买入和多头卖出头寸为负。

动态对冲

考虑以下情况:

一位同事目前持有 1000 份 NVDA 看涨期权的空头头寸,她希望对冲波动率、标的资产的变动以及标的资产的变动速度的风险。你在风险管理台上,提议构建一个动态对冲,每天进行再平衡(稍后会有更多)。我们怎样才能中和她对织女星,德尔塔和伽玛的暴露?

我们可以利用线性代数的第一周来帮助我们构建一个解决方案。

首先要意识到的是,为了中和对希腊的风险敞口,我们需要在其他期权中建立抵消头寸。有三个希腊人要中和,所以我们需要三个期权来创建三个希腊人和带有三个未知数的权重(其他可交易期权中的权重)的方程。然而,这里的技巧是认识到基础资产对自身的偏导数只是 1,这意味着基础资产的 delta 是 1,而所有其他希腊值都是 0。这意味着我们可以构建两个可交易期权的投资组合,找到适当的权重来中和希腊人,然后在基础资产中建立抵消头寸——有效地中和对所有三个希腊人的敞口。

用于动态对冲的 Python

考虑以下模拟欧式看涨和看跌期权的代码…

对于上述情况,请考虑以下条件…

  • 短 1000 NVDA 来电 @ 545
  • NVDA 价格 $543
  • NVDA 隐含波动率 53% (参见什么是隐含波动率?)
  • 期权到期前 1 个月
  • 30 天伦敦银行同业拆放利率 1.5%

使用这些输入,我们可以找到我们同事的期权头寸的理论价值…

32264.05329034736

这意味着我们的同事将因出售期权而获得 32264.05 美元的溢价。

希腊人呢?为了找到我们的同事在希腊语中的位置,我们可以把它们打印出来,然后乘以位置…

-523.8788365375873
-6.3495209433350475
-815.5392717775394

这意味着净投资组合 delta、gamma 和 vega 是…

  • 增量: -523.88
  • 伽马: -6.35
  • 织女星: -815.54

现在让我们考虑另外两个可交易的看涨期权,所有其他参数都相同,但两个执行价格分别是 550555

0.49991533666729754
0.006059078318647928
0.7782345099310374
0.47616874797224407
0.005771264702719988
0.741267420785845

调用选项 A:

  • 增量: 0.49991
  • 伽玛: 0.00605
  • 织女星: 0.77823

调用选项 B:

  • 增量: 0.47616
  • 伽玛: 0.00577
  • 织女星: 0.74126

基础资产(NVDA 股票):

  • △:1
  • 伽玛: 0
  • 织女星: 0

使用这些资产的组合,我们可以中和我们的投资组合对 delta、gamma 和 vega 的风险敞口。问题是怎么做?答案:线性代数。

希腊中性化

我们有兴趣中和当前投资组合中的希腊人可以表示为一个向量…

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

目标是找到我们能够交易的三种资产的权重,以抵消这些价值。首先,我们将设法压制 gamma 和 vega,然后使用底层资产压制 delta…

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

这意味着通过对包含可交易期权希腊价值的矩阵求逆,我们可以找到合适的权重…

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

我们可以使用 Python 来做到这一点…

注意:虽然我们在原始选项中有一个短位置,但我们乘以一个正 1000,因为我们想将矩阵反转为正伽玛,织女星位置

[[-1850\.    25.]
 [ 1950\.   -25.]]

我们已经有效地找到了矩阵的逆矩阵,点积将是两个可交易期权的最终权重…

[[ 8641.86804927]
 [-8006.91595494]]

利用这些重量,我们将有效地中和伽马射线和织女星的辐射…

[[ 0.]
 [-0.]]

现在伽马射线和织女星的辐射被中和了我们需要中和新的德尔塔的辐射。为了找到我们的新敞口,我们取我们投资组合中所有期权头寸与其各自 deltas 的和积…

[[-46.]
 [  0.]
 [ -0.]]

在我们的新期权头寸乘以原始希腊头寸后,我们发现我们的净 delta 头寸是-46。这意味着通过购买基础资产(NVDA)的 46 股,我们将拥有 delta、gamma 和 vega 中性投资组合。这意味着当基础资产价格、基础资产波动性或基础资产价格变化速度发生变化时,我们的期权组合的价值不会改变。这里列出的代码可以直接在一个实时交易系统中实现(参见算法交易系统开发Python 算法交易)

最终 Delta、Gamma 和 Vega 中性投资组合

  • -1000 个 NVDA 电话
  • 8641 调用 A 选项
  • -8006 调用 B 选项
  • 46 股 NVDA 股票

下一步是什么?

看看我的其他文章,了解更多关于期权、理论定价和波动交易的知识…

MACD 和 Python 的算法交易

原文:https://towardsdatascience.com/algorithmic-trading-with-macd-and-python-fef3d013e9f3?source=collection_archive---------7-----------------------

有了 MACD 十字战略

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

Photo by 贝莉儿 DANIST on Unsplash

机器学习交易对于每天进行数千笔交易的大型对冲基金来说效果很好。然而,私人交易者只是没有实时运行具有数百万参数的机器学习模型的设施。这就是为什么私人算法交易者使用技术指标进行自动交易。

什么是 MACD?

我今天要用的技术指标是 MACD,移动平均线收敛发散,这是一个动量指标,显示了两条移动平均线之间的关系。MACD 的计算方法是从 12 期均线中减去 26 期均线。

这条 MACD 线画在信号线上(9 周期均线)。这两条线的交点就是 MACD 指标的信号。如果 MACD 指标从下方与信号线交叉,这将是上升趋势。如果 MACD 指标从信号线上方交叉,这将是一个下降趋势。

概念:

为了在编程时有效率,为了心中有一个明确的目标,有必要创建一个关于程序应该如何工作的总体想法。这个程序应该能够绘制 MACD 信号和 MACD 线,并根据 MACD 指标的信号进行交易。一个好的程序还应该能够评估交易策略的盈利能力,从而对其进行优化。

代码:

import yfinance
import talib
from matplotlib import pyplot as plt

这些是我将在程序中使用的库。yfinance 用于下载股票的财务数据,talib 用于计算 MACD 指标的值。Matplotlib 用于绘制数据,以更好地理解技术指标。

data = yfinance.download('NFLX','2016-1-1','2020-1-1')
data["macd"], data["macd_signal"], data["macd_hist"] = talib.MACD(data['Close'])
fig = plt.figure()

这个脚本下载数据,然后计算 macd 值,比如信号和定义趋势的直方图。

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

作者图片

这是 MACD 指示器和信号线两条线的图形。这只是对程序进行故障排除,以确保指示器正常工作。正如我们所看到的,该指标显然是有效的,因为两条线经常相交。

def intersection(lst_1,lst_2):
    intersections = []
    insights = []
    if len(lst_1) > len(lst_2):
        settle = len(lst_2)
    else:
        settle = len(lst_1)
    for i in range(settle-1):
        if (lst_1[i+1] < lst_2[i+1]) != (lst_1[i] < lst_2[i]):
            if ((lst_1[i+1] < lst_2[i+1]),(lst_1[i] < lst_2[i])) == (True,False):
                insights.append('buy')
            else:
                insights.append('sell')
            intersections.append(i)
    return intersections,insightsintersections,insights = intersection(data["macd_signal"],data["macd"])

交集函数使用一种非常规的方式来寻找交集:

  1. 如果列表 1 中的值大于列表 2 中相同索引的值,则存储 True。否则,存储 False。
  2. 将此函数应用于大于 1 的索引。如果存储的值不同,则一定发生了交集。

这是计算相交的唯一方法,因为相交可能发生在真实点之间,使得不可能在两个列表中找到相似的点。

我们使用这个函数来寻找交叉点,并记下程序是卖还是买股票。

要做好一个股票交易程序,我们必须评估程序的盈利能力。

profit = 0
pat = 1
for i in range(len(intersections)-pat):
    index = intersections[i]
    true_trade= None
    if data['Close'][index] < data['Close'][index+pat]:
        true_trade = 'buy'
    elif data['Close'][index] > data['Close'][index+pat]:
        true_trade = 'sell'
    if true_trade != None:
        if insights[i] == true_trade:
            profit += abs(data['Close'][index]-data['Close'][index+1]) 
        if insights[i] != true_trade:
            profit += -abs(data['Close'][index]-data['Close'][index+1])

这个程序通过计算 true_trade 来计算盈利能力,true _ trade 存储值是上升还是下降。如果交易符合真实交易变量,交易就是盈利的。如果交易不匹配,交易就会失败。

运行程序时,利润为-288.26。什么?

发生了什么事?

我发现了这个错误,并一直试图扰乱耐心值,也就是交叉点形成后多久,交易就完成了。所有的值都是负数。当面对这样的问题时,其中值的极性都是错误的,人们可以很容易地改变极性。

在这种情况下,这是因为交集顺序不正确!当我们做交叉点时,我们做了与我们描述的策略相反的洞察!例如,如果 MACD 线从上方相交,程序会将其标记为价格上涨!这将使所有被认为是有利可图的交易变成亏损!

通过将交叉点代码更改为:

def intersection(lst_1,lst_2):
    intersections = []
    insights = []
    if len(lst_1) > len(lst_2):
        settle = len(lst_2)
    else:
        settle = len(lst_1)
    for i in range(settle-1):
        if (lst_1[i+1] < lst_2[i+1]) != (lst_1[i] < lst_2[i]):
            if ((lst_1[i+1] < lst_2[i+1]),(lst_1[i] < lst_2[i])) == (True,False):
                insights.append('buy')
            else:
                insights.append('sell')
            intersections.append(i)
    return intersections,insightsintersections,insights = intersection(data["macd_signal"],data["macd"])

我们获得 298 美元的利润!

结论:

我写了另一篇关于 RSI 的文章,那个程序用同样的数据只赚了 58 美元。这个项目赚了 298 美元,每笔交易买一股。这里有一些方法可以改进我的程序:

  1. 调整耐心变量

这个变量是相交后多长时间,将进行交易。用这个值做玩具,找到一个模式,并优化它以获得更好的结果。

2.找到最好的份额

这个算法对哪只股票最有效?在不同的公司上测试这个程序以进行评估。

我的链接:

如果你想看更多我的内容,点击这个 链接

用 Python 进行算法交易

原文:https://towardsdatascience.com/algorithmic-trading-with-python-8fbf1c279e77?source=collection_archive---------12-----------------------

为期货市场建立一个算法交易系统

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

照片致谢

定量发展

Python 已经迅速成为数据科学、机器学习和人工智能领域最强大的计算语言之一。在用 Java 写了一本关于算法交易系统开发的指南之后,我觉得是时候为 Python 写一本了;尤其是考虑到 Interactive Broker 新支持的 Python API。本文是一个 API 指南,通过定期参考我自己的实现和官方文档,帮助您入门和运行。

装置

假设您已经正确安装了 Python 并建立了适当的环境变量,要安装交互式代理的 Python API,您可以在命令行中调用 pip 包管理器。

pip install ibapi

这将把 ibapi 包安装到 Python 的默认版本中。如果你有多个版本的 Python(甚至可能是 Python2),你可能想安装 Python3 的包。

pip3 install ibapi

需要特别注意的是,如果您成功安装了软件包,但仍然出现 ModuleNotFound 错误,那么您很可能是在使用安装了 API 的不同 Python 版本运行 Python 脚本。如果你想下载源代码,或者看看 Java、C++和其他语言的 API 实现,你可以在这里下载:【https://www.interactivebrokers.com/en/index.php?f=5041。

接下来,我们需要一个网关来发出请求和接收来自交互代理的数据,我称之为服务器。从上面的链接(页面底部)下载 IB 网关,当你登录时,你会看到一个类似这样的界面…

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

导航到配置→设置→ API →设置,您可以配置您的 API 设置(主机、端口、只读等)。

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

连通性

在成功安装了交互式代理的 Python API 之后,就到了实现的时候了。直观上,这个 API 可以分为两个通信通道,一个从服务器读取,另一个向服务器写入…

EClient

EClient 类负责向服务器发送请求。这些请求被保存在一个队列中,直到这个队列被 run() 函数清除。该类将 EWrapper 作为参数,因为该 EWrapper 的实例是服务器用回调进行响应的地方。

新闻记者

EWrapper 类负责在回调函数中接收数据。

多线程操作

要构建一个算法交易系统,多个进程必须同时发生,这就是为什么我们必须将 EClient 持久化在它自己的线程上,这样读写就可以异步发生。如果你想了解更多关于多线程的知识,我写了一个快速入门指南,介绍如何用 Python 为金融开发多线程。

TradingApp 主类

要创建读写服务器的能力,需要创建 EClient 和 EWrapper 的两个子类。我将把 EWrapper 子类声明为 APIController,把 EClient 声明为 APISocket。主类将成为这两个实现的子类。

让我们分析一下这是怎么回事。正如我之前所说,EClient 类负责向服务器发出请求,而服务器则响应 EWrapper 类。通过创建 APISocket 和 APIController 子类,我们可以覆盖超类函数并编写自定义实现。在这个例子中,您可以看到 APIController 有两个回调,一个用于错误,一个用于连接。服务器只会调用@iswrapper 函数来响应对服务器的请求。为了在 main 类中发出连接请求,我们引用 self(API socket)并用 host、port 和 clientId 参数调用 connect。这将请求放在 EClient 队列中,但是正如我所说的,要构建一个算法系统,必须有并发读写的能力,所以我们将支持在请求队列自己的线程上清除请求队列(通过发出请求)。在运行 TradingApp 类的一个实例后,您将得到一个成功连接到服务器的消息,这个连接在 EClient 线程的生命周期中是持久的。

成功建立连接后,您将可以通过各种请求的形式访问来自服务器的所有类型的数据,在他们的文档中可以找到请求的完整列表。

流式市场数据

如果你对实时市场数据感兴趣,你需要购买一份市场数据订阅服务,最低账户金额为 2000 美元。

创建合同

合约是告诉服务器我们对什么工具感兴趣的交易/流/分析的类。输入参数非常简单,只引用感兴趣的特定证券。我一直在交易 E-mini NASDAQ-100,并将在这个例子中使用它。

# Create a new contract object for the E-mini NASDAQ-100
contract = Contract()
contract.symbol = "NQ"
contract.localSymbol = "NQM0"
contract.secType = "FUT"
contract.exchange = "GLOBEX"
contract.currency = "USD"

请求数据

要请求数据流,只需将请求放在连接请求下。

self.connect('127.0.0.1', 4002, 1)
self.reqMktData(1001, contract, "", False, False, [])

接收数据

要从服务器接收数据,请向 APIController 添加 tickPrice 和 tickSize 回调函数。

[@iswrapper](http://twitter.com/iswrapper)
    def tickPrice(self, reqId, tickType, price, attrib):
        super().tickPrice(reqId, tickType, price, attrib)
        # Do something with trading price[@iswrapper](http://twitter.com/iswrapper)
    def tickSize(self, reqId, tickType, size):
        super().tickSize(reqId, tickType, size)
        # Do something with trading volume

来自回调的请求

对实时数据流执行分析相对简单,因为数据可以间隔存储在数据缓存中,也可以内部存储在 APIController 中。然而,从回调函数发出服务器请求有点复杂,我想提供一个创造性的解决方案。

用 EClient 和 Contract 参数创建一个名为 signal 的新类(我用它在回调函数中下订单,但其他请求也可以),允许主类作为 EClient 作为 Signal 类的参数。那么这个 signal 类就是 APIController 的一个新参数,这样控制器就可以直接引用 self.signal.FUNCTION_IN_signal 或者 self . SIGNAL . e client . server _ REQUEST,分别在 SIGNAL 类或者 direct requests 中进行定制请求实现。

想要现场解说?

我制作了一个视频指南,进一步分解了交互式经纪人 API。

使用 Python 的 RSI 算法交易

原文:https://towardsdatascience.com/algorithmic-trading-with-rsi-using-python-f9823e550fe0?source=collection_archive---------4-----------------------

使用 talib 和 yfinance

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

美国宇航局在 Unsplash 拍摄的照片

机器学习是计算密集型的,因为算法是不确定的,因此必须随着时间的推移不断调整。然而,技术指标要快得多,因为等式不会改变。因此,这提高了它们用于实时交易的能力。

这里是 github 回购(广告)。

什么是 RSI?

要创建一个使用 RSI 的程序,首先要了解 RSI 指标。RSI 是相对强度指数的缩写。它是一个动量指标,使用价格变化的幅度来评估证券是超买还是超卖。

如果 RSI 值超过 70,则认为该证券超买,如果低于 30,则认为超卖。超买是指由购买产生的泡沫可能很快破裂,因此价格会下跌。这创造了一个强有力的切入点。

然而,好的做法是,只有当 RSI 值与超买线相交时,才卖出订单,因为这是一种更保守的方法。至少可以猜测 RSI 何时会达到最高点。

概念:

这个程序试图使用 talib(技术分析)库来实现 RSI 线和超卖超买线的交叉。该程序的大部分不是来自于对指标的编程(因为它已经在库中创建了),而是如何使用超卖和超买区域进行交易的实现。

代码:

import yfinance
import talib
from matplotlib import pyplot as plt

这些是该计划的先决条件。Yfinance 用于下载股票数据,talib 用于计算指标值。Matplotlib 当然是将数据绘制成图形。

data = yfinance.download('NFLX','2016-1-1','2020-1-1')
rsi = talib.RSI(data["Close"])

该脚本访问数据,并根据以下两个等式计算 rsi 值:

RSI step 1= 100[100/(1+平均损耗/平均增益)]

RSI step 2= 100[100/(1+平均平均损耗÷13+当前损耗/先前平均增益÷13+当前增益)]

fig = plt.figure()
fig.set_size_inches((25, 18))
ax_rsi = fig.add_axes((0, 0.24, 1, 0.2))
ax_rsi.plot(data.index, [70] * len(data.index), label="overbought")
ax_rsi.plot(data.index, [30] * len(data.index), label="oversold")
ax_rsi.plot(data.index, rsi, label="rsi")
ax_rsi.plot(data["Close"])
ax_rsi.legend()

该图显示了所有的超买和超卖区域,以及为股票收盘价计算的 RSI 值。这给了股票数据一个很好的可视化

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

作者图片

这是合成图。随着时间的推移,我们可以看到 RSI 值在不同部分之间波动。RSI 的好处在于它是相对的。这意味着信号的强度与实际值无关,而是与过去值的关系有关。

缺少的步骤:

通常,文章到此为止。他们在给出股票交易程序的初步代码后结束。有必要更进一步,真正评估股票交易程序,基于程序的盈利能力。这就是为什么我要交程序。

section = None
sections = []
for i in range(len(rsi)): 
    if rsi[i] < 30:
        section = 'oversold'
    elif rsi[i] > 70:
        section = 'overbought'
    else:
        section = None
    sections.append(section)

这个脚本记录了每个点所在的部分。它要么在超买,超卖或无区域,这是指在两条线之间。

trades = []
for i in range(1,len(sections)):
    trade = None
    if sections[i-1] == 'oversold' and sections[i] == None:
        trade = True
    if sections[i-1] == 'overbought' and sections[i] == None:
        trade = False
    trades.append(trade)

这个脚本整合了 RSI 交易的基本策略。交易策略是当价值离开超买和超卖部分时,进行适当的交易。例如,如果它离开超卖区,就进行买入交易。如果它离开了超买区,就进行卖出交易。

acp = data['Close'][len(data['Close'])-len(trades):].values
profit = 0
qty = 10
for i in range(len(acp)-1):
    true_trade = None
    if acp[i] < acp[i+1]:
        true_trade = True
    elif acp[i] > acp[i+1]:
        true_trade = False
    if trades[i] == true_trade:
        profit += abs(acp[i+1] - acp[i]) * qty
    elif trades[i] != true_trade:
        profit += -abs(acp[i+1] - acp[i]) * qty

这个脚本使用程序进行的交易来计算每笔交易的利润或损失。这给出了程序的最佳评价,因为它准确地锁定了要寻找的变量。qty 变量计算购买了多少股票。

运行程序后,计算的利润为:

Profit : $58.3

结论:

事实上,当考虑到风险回报比时,58.3 美元的利润实际上不是一个很好的投资。有很多方法可以改进我的程序:

  1. 调整耐心变量

这个变量是在 RSI 值之后多久,将进行交易。用这个值做玩具,找到一个模式,并优化它以获得更好的结果。

2.找到最好的公司

这个算法对哪只股票最有效?在不同的公司上测试这个程序以进行评估。

我的链接:

如果你想看更多我的内容,点击这个 链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值