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

龙哥盟 / 2024-10-14 / 原文

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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

主数据管理:数据战略的重要组成部分

原文:https://towardsdatascience.com/master-data-management-an-essential-part-of-data-strategy-db12411a05b2?source=collection_archive---------3-----------------------

Image from Pixabay

首先,什么是主数据管理(MDM)?主数据是指对企业业务至关重要的关键数据,通常用于多个学科和部门。 MDM 是建立和维护企业级数据服务,为整个企业和所有业务合作伙伴提供准确、一致和完整的主数据。主数据管理的概念起源于 2008 年左右,当时数据仓库和 ERP 应用程序在许多组织中流行起来。随着数据量和数据库数量的增加,以及用户输入和读取数据的数量的增加,确保使用正确的主数据定义变得越来越重要,以便在数据中有一个单一事实,没有差异、重复或过时。第一个例子与客户信息有关。在大型组织中,可能存在由多个应用程序或部门孤岛填充和管理的多个客户数据库,现实世界中的同一个客户可能会收到来自同一家公司的多封直接邮件或通知。随着数据的增长,主数据不仅包括客户信息,还包括其他关键数据资产,如潜在客户、供应商、小组成员和产品的数据。MDM 的实现一直是一个挑战,因为需要流程技术工具的所有三个方面来确保主数据在整个企业内得到协调和同步。

MDM 为什么重要?

随着最近大数据的爆炸式增长以及分析和物联网的快速发展,引用和应用高质量主数据的一致性变得前所未有的重要。企业不仅需要确保其关键数据资产得到高效和准确的管理,还需要通过加入或引用公司已经拥有的现有主数据来拥抱新的数据资产,以充分实现经济潜力。因此,MDM 需要成为公司增长和盈利的数据战略的重要组成部分,也是首席数据官(CDO)等高管的核心任务之一。

在过去的 10 年中,MDM 计划失败的主要原因有两个:1)只依赖技术和工具,没有业务部门的认可和支持;2)专注于修复和解决当前的数据问题,没有前瞻性思维。要使 MDM 成功,它首先需要是一个业务驱动的过程,并被业务部门和高管所接受。在许多情况下,建立和维护统一的主数据需要对业务流程进行根本性的改变,而一些最困难的 MDM 问题根本不是技术性的。接下来,前瞻性战略对于将MDM 作为组织中数据管理的重要组成部分至关重要,因为它主动为未来的成功奠定了基础。大量的经验告诉我们,当数据集刚刚被引入 ETL 和商业智能项目时,MDM 的实现是最容易和最平稳的。尝试修复现有的数据资产和流程通常需要高成本和大量的工作,这也可能会对当前的可交付成果产生很大的影响。下面的比较说明了在开始时实施 MDM 与修复现有数据和系统问题之间的巨大差异:

推迟实施 MDM

  1. 孤岛中的重复流程和昂贵的开发

2.无处不在的数据质量问题,没有简单的跟踪方法

3.客户满意度低

4.数据资产的潜力没有得到充分发挥

5.难以迁移到新的数据平台

从头实现 MDM

  1. 以更低的成本实现高效、快速的开发

2.数据质量问题更少,修复速度更快

3.客户满意度高

4.创造更多收入机会

5.需要时更容易迁移到新的数据平台

通过以上比较,很明显,MDM 应该是任何公司的数据战略的重要组成部分,并且应该具有前瞻性和长期承诺。换句话说,MDM 需要被视为一项投资,从长远来看,这将带来回报,并为公司在大数据、分析和物联网领域的增长和盈利能力奠定坚实的基础。

成功实施 MDM 的四个步骤

一旦制定了 MDM 策略,下一步就是在企业内部实现主数据管理。这是一个很大的话题,可以在一本书里深入探讨。在本文中,我将给出一个非常高层次的介绍,并指出成功实现 MDM 的 4 个关键步骤。每一个步骤都将保证在将来有自己的主题,有更多的阐述和详细的例子。

步骤 1:建立整个组织都接受的数据治理

这是 MDM 最关键和最重要的部分,也是最困难的部分。实施 MDM 需要数据治理委员会的承诺,该委员会通常具有以下结构:

  • 管理和咨询信息控制台—首席管理人员和部门主管
  • 信息管家—通常来自 IT 或 CDO 组织的数据治理经理/主管
  • 数据管家—来自每个业务部门的领域专家

该委员会的主要任务包括:

  • 建立数据治理政策和程序,并根据业务需求或数据、运营和技术的变化对其进行修订
  • 建立定期沟通渠道,明确传达和强化政策
  • 为数据问题建立正确的上报流程,确定优先级并明智高效地做出决策。
  • 确保所有利益相关方的认同和所有权

下面列出了数据治理委员会应该做出决策的一些关键领域:

  • 公司数据集的整体视图以及企业中的核心数据资产
  • 记录并定义在适当的安全性和法规约束下,数据资产应如何共享或使用
  • 为数据资产或数据对象中的数据元素建立标准定义和业务规则
  • 确定正确的行动或计划过程,以确保数据策略和程序在整个组织中得以实施和执行
  • 解决定义模糊或冲突

步骤 2:将 MDM 应用于新的数据添加或新的应用程序

永远记住,使 MDM 成功的最简单和最有效的方法是在创建数据时强制数据一致性。MDM 是一个长期项目,需要公司的长期投入。任何以方式改变数据的尝试都会使努力变得无效和昂贵。数据治理策略和定义通过两种渠道实现:1)通过任何新项目和应用程序开发;2)通过使用数据治理软件。许多组织的 MDM 实现停滞不前,因为他们在尝试修复现有系统和问题时面临高成本和高工作量;他们没有意识到,从 MDM 开始的最佳方式是将其应用于新项目,这将首先测试它,并使组织能够积累专业知识和经验。

此外,大部分数据治理应该作为数据相关项目的一部分直接实施到应用程序和报告中。例如,数据治理应该在以下技术实现中实施和传播其定义、策略和原则:

  • 数据库的逻辑和物理设计(数据建模)
  • 在 ETL 过程中定义列/字段名称和业务规则
  • 在报告引擎中定义显示名称和公式
  • 使用 ERP 和 Salesforce 等第三方软件时的配置和设置
  • 由质量保证(QA)测试和用户验收测试(UAT)强制执行

第三步:选择合适的 MDM 软件

理想的 MDM 软件应该具有以下功能:

  1. 引用和访问公司中主数据资产的元数据(例如,RDBMS、Hive、平面文件等。)
  2. 使信息和数据管理员能够在工具中轻松地定义和修改定义
  3. 能够检查数据并配置业务规则,以应用或实施数据本身中定义的内容

市面上有很多工具可以做 1)和 2),但是用同一个工具做 3)并不容易。这就是为什么一个 MDM 软件同时也可以是一个数据集成工具,或者说反之亦然。最近人工智能(AI)的快速发展使这种软件更加强大,增强了数据管理,在未来几年有着光明的前景。

请记住,工具仍然是工具。如果没有治理委员会和来自高层管理人员的赞助,软件本身就不能发挥魔力,也是不充分的。此外,每个部门的信息管理员和数据管理员的不断沟通和强化也比软件本身发挥着更重要的作用。

步骤 4:利用 MDM 功能管理现有和遗留系统

许多公司可能无法从零开始创建新的主数据集,这意味着他们需要改造现有的数据库和相关应用程序。将 MDM 应用于现有的数据资产通常需要大量的工作,由于的复杂性和成本,这也可能会失败或中止。为了使 MDM 工作取得成功,需要仔细规划,以建立一个包含多个阶段的路线图。有时,在数据或系统迁移到新平台之前,仅部分应用 MDM 可能是一个更好的策略,同时重点关注将 MDM 应用于正在添加的新主数据或正在构建的新应用程序和流程,以便将增强的新数据源与主数据结合起来。

结论

MDM 已经成为组织充分实现其数据集的收入和利润潜力的必要条件,但实现起来并不容易。MDM 首先需要成为数据战略的一个永久部分,这样公司才能有一个长期的承诺。接下来,它需要来自最高管理层的一致治理和赞助,以及来自 IT/CDO 部门的信息管家和业务部门的数据管家的持续努力。修复现有数据和系统问题的挑战不应该阻止企业采用 MDM。相反,将 MDM 应用到新的数据源和新的应用程序将为逐步将其成功应用到现有的数据和系统奠定基础。

最好的数据科学家每天使用的数据操作工具

原文:https://towardsdatascience.com/master-data-wrangling-in-r-fa74dd05b540?source=collection_archive---------28-----------------------

Photo by Simon Matzinger from Pexels

作为数据科学家,您所做的一切都是从数据操作开始的

dplyr 包有一组丰富的工具和函数,您可以使用它们进行数据辩论、探索性数据分析、特性工程等。

在接下来的几分钟里,我们将介绍一些绝对重要的函数,作为一名数据科学家,您会发现自己每天都在使用这些函数。

选择:展现重要的变量

dplyr 中可用的函数与您在 SQL 甚至 Python 中使用的函数密切相关,这取决于您正在执行的任务。

这里的主要区别是,使用 sql,您的代码可能看起来像这样……(并且您不会在dplyr select中包含聚合函数,但稍后会详细介绍)

SELECT mpg, cyl, carb 
FROM mtcars

相反,使用dplyr我们首先指定想要操作的数据集,然后使用管道操作符%>%有效地说,“嘿,这是我们的数据集,我调用的下一个动作或函数应该对它执行!”

因此,我们将有效地看到语法略有变化的函数翻转。继续这个例子,“嘿,mtcars 是我的数据集,我想从中选择 mpg、cyl 和 carb。”

您可以通过管道从一个函数传递到另一个函数。超级方便,容易习惯。稍后会有更多的介绍。

mtcars %>% 
   select(mpg, cyl, carb)

说到数据操作,我个人更喜欢 dplyr 的方法。对您可能正在执行或检查的任何数据操作进行逻辑分解要容易得多,因为您通过管道函数来有效地在每一行中重新创建数据集。

使用RSQL,您的输出将如下所示:

过滤器:给我我想要的!

您可以将 filter 看作是 dplyr 对 SQL 的 where 语句的回答。如果你不用 SQL 来思考,这差不多就是你如何去掉任何不符合你想要的标准的东西。

例如,假设您只想查看 4 缸汽车。

您可以声明mtcars %>%,然后调用包含您所关心的标准的filter函数。

mtcars %>% 
   filter(cyl == 4)

您的输出将如下所示:

您将看到所有记录都包含 4 个柱面。

其他条件运算符

您也可以使用其他条件操作符,比如<>。您可以在字符串、逻辑等上这样做。

mtcars %>% 
   filter(cyl >= 4)

我们现在可以看到各种各样的例子,其中cyl列大于或等于 4。

组合过滤器

想象这样一个场景,是的,您想要过滤掉cyl大于或等于 4 的记录...太好了;但是您还想过滤掉那些mpg小于 20 的记录。

您可以使用&|来组合这些标准。&表示两个标准都必须满足,而|将包括至少满足两个标准之一的记录。

你不局限于两个或三个或四个标准。您可以将任意数量的过滤器链接在一起!

看看这些例子!

mtcars %>% 
   filter(cyl >= 4 & mpg < 20)mtcars %>% 
   filter(cyl >= 4 | mpg < 20)

突击测验

您认为哪个代码片段会返回更多的记录?

第二个将总是返回更多(除非所有 4 缸或更多的车辆都少于 20 个mpg,那么它们将返回相同数量的记录。)

这是因为过滤器不太严格。只需满足两个标准中的一个,而&则需要满足两个标准。

您也可以使用逗号分隔标准,其行为与&操作符相同。

不要忘了把你的函数放在一起

到目前为止,你已经学习了两个关键函数,select & filter。您很可能想要连续组合输出。这个秘密就是管道操作员。

在执行了select操作之后,您现在有了一个新的数据集。它是mtcars加上你在上面做的任何操作。当您使用管道操作符(%>%)时,您实际上告诉了R下一个函数将作为该行输出的延续!看看下面我们是如何结合最后两个动作的。

mtcars %>% 
   select(cyl, mpg, carb)%>% 
   filter(cyl >= 4 & mpg < 20)

保存你的创作!

在我们讨论其他可以使用的函数之前,告诉您如何有效地保存数据集也是值得的。

你可以像在R中声明任何变量一样做这件事。<-

mtcars_sub <- mtcars %>% 
   select(cyl, mpg, carb)%>% 
   filter(cyl >= 4 & mpg < 20)

安排:让我们井然有序!

好了,现在这已经不碍事了...让我们进入arrange功能。

mtcars %>% 
   filter(cyl >= 4)%>% 
   arrange(mpg)

现在,假设您想颠倒顺序,从最高到最低查看mpg。你所要做的就是扔进一个desc()

mtcars %>% 
   filter(cyl >= 4)%>% 
   arrange(desc(mpg))

我们现在看到同样的输出从大到小排序mpg

变异:创建新变量

mutate函数是我们创建新列的方法。这可能是将多个列值相加,根据一个列的值创建分类桶,将宁滨分类细化,或者为其他任何内容创建额外的列。

我将在这里跳到一个例子中,但请记住,我对汽车的熟悉程度是有限的…因此,我对我即将创建的指标的效用的理解有点天真。

假设你想知道每缸的马力是多少。您需要声明新的变量名,然后包含如何计算这个新字段的逻辑。

mtcars %>% 
   mutate(hp_per_cyl = hp / cyl)

分组依据和汇总

总结一下,最后要涉及的主要dplyr操作是它的分组&聚合功能。

在 SQL 中执行聚合时,使用GROUP BY来声明分组变量。但是,聚合逻辑(平均值、总和、最大值、最小值、计数等。)位于SELECT语句中——我们在开始时讨论过。

对于这个例子,让我们按气缸数分组&然后看看平均每加仑英里数和马力。

mtcars %>% 
   group_by(cyl)%>% 
   summarize(mean_mpg = mean(mpg), mean_hp = mean(hp))

正如你可能已经猜到的,更高的气缸数与每加仑英里数成反比,与马力密切相关。

实际上,您可能只是评估这些特定变量之间的相关性,但这足以显示group_by & summarize的操作。

结论

Dplyr是一个非常有用的库,它包含了其他数据争论语言的功能,并且它将一个函数传输到另一个函数的格式允许您跟踪否则可能会非常混乱的查询。

Dplyr还提供了更多我们没有机会在这里详述的东西,但我们所涵盖的内容将为您扩展到dplyr的一些更复杂的功能(如mutate_eachsummarise_if以及许多其他功能)打下良好的基础。

让我知道你喜欢什么,你想了解更多!

在 @datasciencelessons 查看我的其他媒体帖子,并在 Twitter 上关注我 @data_lessons 。

一如既往,祝数据科学快乐!

原载于 2019 年 12 月 23 日http://datasciencelessons.com

Python 地理数据科学入门

原文:https://towardsdatascience.com/master-geographic-data-science-with-real-world-projects-exercises-96ac1ad14e63?source=collection_archive---------5-----------------------

教程、真实世界项目和练习

World countries GPD 2007 map

这是 Python 地理数据科学入门系列文章的第一篇,该系列文章由三部分组成。您将学习如何用 Python 阅读、操作和分析地理数据。本系列中的文章按顺序排列,第一篇文章奠定基础,第二篇文章介绍中级和高级地理数据科学主题。第三部分涵盖了一个相关的真实世界的项目,总结巩固你的学习。每个教程也有一些简单的练习来帮助你学习和练习。所有代码、数据集和 Google Colab Jupyter 笔记本都可以从本文末尾的链接获得。

在本系列中,我将只关注地理矢量数据。在下一个系列中,我们将学习卫星图像和栅格数据分析。

该系列包含三个部分:

  1. 地理数据科学导论
  2. 地理数据处理
  3. 地理数据科学项目

这是第一部分。在本教程中,我们将学习使用 Geopandas 加载和处理地理数据的基础知识。Geopandas 是 Python 中地理数据科学的主力,它建立在 pandas 和 Numpy 库之上。与 Pandas 数据框架一样,Geopandas 数据结构包含地理数据框架和地理系列。Geopandas 不仅提供了轻松读取和操作地理数据的能力,还可以执行许多基本的地理空间操作,包括其他几何操作、投影和地理分析。您还可以使用 Geopandas 可视化和绘制地图——它为 Matplotlib 库提供了一个高级接口——方法是在 GeodataFrame/GeoSeries 上使用.plot()方法。

这些是本部分“地理数据科学简介”的学习目标:

  1. 在 Geopandas 中读写地理数据。
  2. 投影并设置坐标参考系统(CRS)。
  3. 可视化地图

1.读取地理数据

在本教程中,我们将主要使用 3 个数据集:

  • 国家
  • 城市

地理(矢量)数据有不同的格式(Shapefiles、Geopackage、Geojson 等)。使用 Geopandas 加载大多数地理数据格式非常简单。我们可以使用.read_file().

让我们看一个读取数据的例子。在这种情况下,我们将读取国家数据集。

首先,我们创建了一个变量来保存文件路径,然后我们使用 Geopandas,.read_file() 方法来读取国家数据集。Geopandas 负责几何列,使我们能够执行地理处理任务,例如绘制地图。

开始数据探索的一个好方法是查看前几行、数据的形状以及数据的一般统计信息。这可以通过以下命令来实现。

  • 方法返回前 5 行。如果需要,可以调整要返回的行数,例如,.head(8)表示数据集中的前 8 行。
  • .shape()返回数据的行数和列数
  • .describe()可用于探索一些基本的统计细节,例如,平均值、标准差和百分位数。

这是前 5 行数据的样子。

countries Geodataframe — first 5 rows

另一个在 Geopandas 中读取数据的例子,这次我们将读取城市数据集。它以 Geojson 文件的形式出现,但我们用来读取国家/地区数据集的技术同样适用于此处。

我们也可以使用.head().shape().describe()进行同样的探索,以了解这个数据集是关于什么的。一旦我们进行了探索,我们就可以开始绘制地图了。

通过.plot()功能,在 Geopandas 中绘制地图很容易。由于我们有两个数据集国家和城市数据,我们可以将它们叠加并显示为地图。在这里,我们使用 Matplotlib 设置子情节,并将轴传递给 Geopandas .plot()函数。

这是输出图。只需两到三行代码,我们就能生成这张漂亮的地图。

Countries and cities of the world map — Change picture

你该做些小运动了。

练习 1.1:读取河流数据

练习 1.2:阅读河流数据集的前 5 行

练习 1.3:可视化河流数据集。

2.坐标系和投影

坐标参考系统表示我们的二维(平面)数据如何与地球上的实际位置相关联。它是将属性保持在各自位置的粘合剂。地理数据框架有。crs 属性,它可以给出数据中使用的原始 CRS。这些坐标很容易变换和投影。但是,要执行投影,必须有相同的 CRS,以便执行地理分析并从分析中获得正确的值。国家、城市和河流有相同的 CRS。让我们检查一下各国的客户登记系统。

这是上面代码{'init': 'epsg:4326'}的输出。EPSG 代表欧洲石油测量组织,是维护空间参考系统的权威机构。代码 4326 指示使用的地理坐标系,在本例中为 1984 年世界大地测量系统(WGS84)。

不同的 CRS 有不同的测量值。有些坐标以十进制度定义,有些则以米定义。在地理数据处理中,将数据从一种格式转换为另一种格式是很常见的。该源对于可视化和比较不同的投影非常有用:

[## 墨卡托 vs .罗宾逊:比较地图投影

比较墨卡托和罗宾逊的地图投影

map-projections.net](https://map-projections.net/compare.php?p1=mercator-84&p2=robinson&sps=1)

我们将把数据投射到墨卡托。当您远离赤道时,墨卡托投影、经纬度四边形会沿 x 轴和 y 轴拉伸。但首先,让我们看看国家数据集的几何列。

这是上面代码的输出。它只是打印出多边形的纬度和经度。这些坐标现在是十进制度。

0(多边形((117.7036079039552 4.163414542001791…
)1(多边形((117.703603607903955 2 4.163414544 420017…
)2(多边形((-69.6964699994-17.5996

让我们投射这些数据,看看变化。在本例中,我们投影到 EPSG:3395,这是广泛使用的墨卡托投影。

现在我们的几何列数据如下所示:

0(多边形((13102705.69639943 460777.6522179524…
)1(多边形((13102705.696399943 460777.6522179 524…
)2(多边形((-7737727-1963777.

由于投影,几何图形不再以十进制样式点测量,而是以米为单位。更容易理解地图的区别。让我们画出原始国家和预计国家。

Left WGS84 World map. Right World Mercator Projection map

请注意两张地图中 x 和 y 的不同比例。随着我们从赤道到两极越走越远,墨卡托投影扭曲了物体的大小。这就是为什么非洲看起来很小,而格陵兰岛看起来比它的面积大得多。

如果您尝试用未投影的数据覆盖投影的数据,那么您的数据将不会正确对齐。让我们看看我们是否能在投影国家的顶部绘制城市。请记住,我们没有规划城市。

Overlay Projected countries and unprojected cities

如您所见,城市在投影国家数据集中没有正确叠加。他们落在非洲附近,那不是他们该去的地方。为了正确地对齐它们,我们还需要对国家数据集进行相同的投影,EPSG:3395,这是一个练习。

练习 2.1:将城市数据转换为 EPSG:3395 投影,并在 countries_proj 的顶部绘制城市。

3.写入地理数据

我们可以轻松地将任何新创建的数据保存到本地磁盘。当您希望在其他时间访问该文件而不再次执行相同的操作时,这很有帮助。让我们拯救我们预测的国家。记住我们已经计划好了。Geopandas 有.to_file()方法。

这将保存您的文件。你可能想下载这个文件,因为我们正在使用 collab,没有用 Google drive 配置它。当您在 Google Colab 中关闭您的会话时,这将被删除。

如果您已经猜到我们还需要保存练习 2.1 中的预测城市,那么您是对的。这是本部分的最后一个练习。

练习 3.1:将在练习 2.1 中创建的投影城市文件保存到一个文件中

结论

在本教程中,我们已经讲述了加载和写入地理数据以及地理坐标系和投影的基础知识。在下一教程中,我们将学习使用 Geopandas 对地理数据进行地理处理和操作。该代码可从以下 GitHub 存储库中获得:

[## 沙卡姆/GDS

地理数据科学教程系列。在 GitHub 上创建一个帐户,为 shakasom/GDS 的发展做出贡献。

github.com](https://github.com/shakasom/GDS)

您也可以直接从以下链接运行 Google Collaboraty Jupyter 笔记本:

[## 谷歌联合实验室

编辑描述

colab.research.google.com](https://colab.research.google.com/github/shakasom/GDS/blob/master/Part1 - Introduction.ipynb)

掌握你的假设检验

原文:https://towardsdatascience.com/master-your-hypothesis-test-a-tutorial-on-power-bootstrapping-sample-selection-and-outcome-273d6739d3e5?source=collection_archive---------11-----------------------

关于电源、自举、样本选择和结果分析的教程。

Photo by Vienna Reyes

在本教程中,我们将浏览一个 FIFA '19 球员属性数据集以回答一个简单的问题:哪个国家出产更好的足球运动员?英格兰或西班牙。

本教程将涵盖哪些内容:

  1. 清理和设置数据
  2. 定义无效假设和替代假设,并确定α
  3. 功率和样本大小,以及自举
  4. 计算 T 值
  5. 计算 P 值
  6. 评估测试并得出结论

在我们开始之前,我想包括一个小备忘单,里面有一些与假设检验相关的常用术语和概念。当我阅读那些期望你已经了解你的主题的所有东西的教程时,这总是让我有点恼火…因为如果你知道,你可能就不需要教程了。

迷你测试小抄

P 值:

当研究问题的零假设(H 0)为真时, P 值或计算概率是发现观察到的或更极端的结果的概率——“极端”的定义取决于假设如何被检验

  • 当试图决定是否拒绝你的零假设时,p 值真的很有用。

Z 值(Z 分数):

“从技术上来说,一个 z - 分数是参考人群(一个已知已被记录的人群,就像 CDC 编制的这些关于人的体重的图表)的平均值的标准偏差数。A z - 得分为 1 比平均值高 1 个标准差。”

T 值:

t - 测量相对于样本数据变化的差异大小。

类型错误:

在统计假设检验中,一个 I 错误是拒绝一个真的零假设(也称为“假阳性”发现或结论),而一个型 II 错误是拒绝一个假的零假设的失败(也称为“假阴性”发现或结论)。

理论

这一节希望有助于澄清围绕假设检验的一些困惑。T 检验有两种类型:单尾和双尾。

单尾:

  • 单尾检验要求样本之间的差异在特定方向上。例如,如果我们想测试一个新的电子邮件营销策略。如果我们原来的策略有 30%的成功率,我们想看看我们的新策略是否更好,这意味着它的成功率高于 30%,我们将不得不使用单尾测试。

双尾:

  • 双尾检验要求样本之间的差异在任一方向
  • 当您想要找出两个样本平均值之间是否存在统计差异时使用。这与单尾检验不同,因为我们不关心差异是高还是低。
  • 非常适合我们在这个例子中所做的比较。

当执行双尾检验时,有一些事情需要考虑。

  1. 有没有两类可以比较?

例如:最初,我想比较重量和速度。但是为了进行假设检验,您需要为这些属性中的每一个属性建立一个类别。体重和速度与类别(即团队或国家)没有任何联系,因此很难对它们进行统计测试,而如果你想用这些模型建立线性回归将会非常容易。

2.两个数据集必须是独立的

为了收集有意义的数据,这两个数据集必须相互独立,这就是为什么重量和速度不起作用的原因,因为速度与重量成线性关系。

因此,对于这个例子,我们将使用基于两个独立数据集的双尾假设检验,希望找到每个国家生产的球员质量的统计差异。

既然我们已经想好了如何从概念上接近我们的测试,那么是时候实际制作东西了!

假设检验的步骤:

  1. 收集数据:

首要任务是收集有用的数据。对于这个例子,我使用的是来自视频游戏 FIFA 19 的玩家属性数据。数据需要被清理和组织,以便您以后在执行假设检验时可以方便地访问它。我使用 python、pandas、Numpy 和 Sci-kit learn 来执行这些测试。为了在 Jupyter 笔记本中使用这些工具,您必须导入它们。

import pandas as pd
import numpy as np
import seaborn as sns
import scipy
import matplotlib.pyplot as plt
from scipy import stats
from statsmodels.stats.power import TTestIndPower

根据我最初的问题,我知道我需要来自英格兰和西班牙球员的包含总体属性的数据。

注意:选择英格兰和西班牙是因为数据集中有大量来自这两个国家的球员。

fifa_df['Nationality'].value_counts().head()England      1662
Germany      1198
Spain        1072
Argentina     937
France        914

在下面的代码中,我使用 FIFA 19 数据创建了一个 DataFrame 然后将它们分成 Numpy 数组,我可以用它们来执行我的假设测试。

fifa_df = pd.read_csv('data 2.csv')fifa_df = fifa_df.drop(['Photo', 'Flag', 'Club Logo'], axis =1)overall_df= fifa_df[['Overall', 'Nationality']].dropna()finishing_df = fifa_df[['Finishing', 'Nationality']].dropna() #Selects Overall From English Born Players
overall_eng = overall_df[overall_df['Nationality'].str.contains("England")==True]#Selects Overall From Spanish Born Players
overall_spa = overall_df[overall_df['Nationality'].str.contains("Spain")==True]

我上面创建的是熊猫系列,包含了所有分别出生在英格兰和西班牙的玩家的核心。为了让我们的生活更轻松,让我们把这些系列变成 Numpy 数组。Numpy 数组非常通用,Numpy 库有大量有用的函数。

#Englishenglish_ov_df = overall_eng['Overall']
english_overall = np.array(english_ov_df)
english_overall#Spanishspanish_ov_df = overall_spa['Overall']
spanish_overall = np.array(spanish_ov_df)
spanish_overall

完美!因此,现在我们已经将我们的数据浓缩成一些东西,我们可以将它们输入到下面将要创建的函数中

2。定义无效假设和替代假设。

创建假设检验时,您需要定义一个空假设和替代假设。我喜欢这么想。

空:第一个数据集的 表示 与第二个数据集的 表示 相比没有任何统计差异。

Alt:第一个数据集的 表示 与第二个数据集的 表示 相比,确实有统计学差异。

那么我们应该如何写这个例子呢?

零:在英格兰出生的球员和在西班牙出生的球员在整体技能上没有统计学差异。

Alt:一个出生在英格兰的球员和一个出生在西班牙的球员在整体技能上有统计学上的差异。

Alpha :定义为。 05。通常,当运行双尾测试时,选择α值 0.05 作为误差的标准度量。如果你看下面的图表,两个尾端是阿尔法值。

Alpha = .05, but since it’s two-tailed- the alpha is split in half

3。功率、尺寸和自举

抽样是假设检验的主要部分。抽样背后的哲学很简单;利用真实人口实际上是不可能的(这将花费太多的时间和金钱),因此为了得出结论,我们必须从人口中取样,并得出结论,这些发现代表了整个人口。为了找到本例中的样本大小,我们将找到效果大小,我们可以用它来找到我们测试的功效。然后,power 将给出我们必须收集的样本的最小值,以满足约束条件。

from statsmodels.stats.power import TTestIndPower

科恩的 d :在计算幂之前,我们需要求解两个不同国家之间的科恩的 d。科恩的 d 效应大小衡量的是两组球员的 表示 之间的差异(在这种情况下,英格兰球员的整体技能vs 西班牙球员的整体技能)。这让我们对两组之间实际发生了多少变化有了一些了解。Cohen's d 效应大小的结果用标准差来衡量。在下面的代码中,您可以看到如何使用 python 函数计算 Cohen 的 d。

def calc_cohen_d(group1, group2):
    """Calculate and Define Cohen's d"""# group1: Series or NumPy array
# group2: Series or NumPy array# returns a floating point numberdiff = group1.mean() - group2.mean()n1, n2 = len(group1), len(group2)
    var1 = group1.var()
    var2 = group2.var()# Calculate the pooled threshold as shown earlier
    pooled_var = (n1 * var1 + n2 * var2) / (n1 + n2)

    # Calculate Cohen's d statistic
    d = diff / np.sqrt(pooled_var)

    return d# To use our function, we simply call it using the numpy arrays we created earlier. cohens_d = calc_cohen_d(english_overall, spanish_overall)
abs(cohens_d)0.939861699762249

评估测试的效果分为三个部分:

0.0–0.20 =小影响

0.20–0.50 =中等效果

0.50 + =大效果

科恩的 d 应该总是正的,这也是我们取绝对值的原因

根据我们的计算,我们的测试应该有很大的影响。下一步是通过确定我们的测试能力来计算我们的最小样本量:这也可以通过几行 python 代码来完成,如下所示:

# Define Variables 
effect = cohens_d
alpha = 0.05
power = 1
# sample 2 / sample 1   
ratio = len(spanish_overall) / len(english_overall)# Perform power analysis
analysis = TTestIndPower()
result = analysis.solve_power(effect, power=power, nobs1=None,ratio=ratio, alpha=alpha)print(f"The minimum sample size: {result}")
print(f"Number of players:{len(spanish_overall)}")The minimum sample size: 500.0
Number of players:1072

我们的能量测试结果很有希望。由于我们有很高的能级,当我们计算它们时,我们能够自信地得出结论。

关于电源的简短说明:

  • 功效用于确定测试出现 II 型错误的可能性。
  • 功效越高,测试出现第二类错误的几率越低,反之亦然。
  • 功率值介于 0 和 1 之间
  • 功率低于 0.80 的测试通常被认为太低。

该函数的输出告诉我们,为了获得 1.0 的功率水平,我们只需要使用 500 个样本。幸运的是,我们有 1072 个,有很多可以玩!

所以我们最终得到了样本量。我们对 采样 了解多少?

  • 它应该是随机的,以确保它能代表总体。
  • 我们的数据应该服从正态分布
  • 我们的价值观应该相互独立。

但是如果不是或者我们不确定呢?如果我们不确定,有一个非常有用的工具叫做 bootstrapping。自举模拟新的数据收集,我的意思是它从原始样本中随机抽取替换的新样本,计算平均值并创建现在可以用于运行测试的新数据。

这是因为假设您的原始样本已经代表了 人口 。所以只要你从原始样本中取样,它就应该模仿收集新的 真实 数据的动作,这些数据代表 总体 。比方说,你有一个完整的 cookie(群体),然后你掰下那个 cookie 的一半(原始样本)。然后从原始样本中分离出 2 个较小的片段(引导样本)。bootstrapping 背后的想法是(bootstrap samples)只是原始样本的一部分,尝起来就像原始 cookie 被分开之前的味道。下面的代码向您展示了如何做到这一点。

sample_means_overall_eng = []
for _ in range(1000):
    sample_mean = np.random.choice(english_overall,size=500).mean()
    sample_means_overall_eng.append(sample_mean)
len(sample_means_overall_eng)sample_means_overall_french = []
for _ in range(1000):
    sample_mean = np.random.choice(english_overall,size=500).mean()
    sample_means_overall_french.append(sample_mean)
len(sample_means_overall_french)

基本上,我们使用我们计算的样本大小(500)并根据随机抽样创建了 1000 个新样本。这在概念上就像我们去英格兰和西班牙,从每个国家的另外 1000 名玩家那里收集数据一样。

到了第四步,我们终于开始发现这些工作是否真的重要了!

4。计算 T 值(长距离):

这是看起来很吓人的 T-Stat(T 值)公式。

This is ugly…. so we broke it up into formulas!

这太难看了…所以我们把它分解成更小更简单的公式!

def calc_variance(sample):
    '''Computes the variance a list of values'''
    sample_mean = np.mean(sample)
    return sum([(i - sample_mean)**2 for i in sample])

上面的公式计算 Numpy 数组中的方差。

def calc_sample_variance(sample1, sample2):
    '''Computes the pooled variance 2 lists of values, using the calc_variance function'''
    n_1, n_2 = len(sample1), len(sample2)
    var1, var2 = calc_variance(sample1), calc_variance(sample2)
    return (var1 + var2) / ((n_1 + n_2) - 2)

此公式计算两个样本平均值的混合方差。

def calc_twosample_tstatistic(expr, ctrl):
    '''Computes the 2-sample T-stat of 2 lists of values, using the calc_sample_variance function'''
    expr_mean, ctrl_mean = np.mean(expr), np.mean(ctrl)
    n_e, n_c = len(expr), len(ctrl)
    samp_var = calc_sample_variance(expr,ctrl)
    t = (expr_mean - ctrl_mean) / np.sqrt(samp_var * ((1/n_e)+(1/n_c)))
    return t

这是泰姬陵。这个函数使用上面定义的两个函数来计算 T-Stat。

t_stat = calc_twosample_tstatistic(sample_means_overall_eng, sample_means_overall_spanish)t_stat-480.6580710651087

5。计算 T-Stat 和 P-Value(最简单的方法):

为了计算我们的 P 值并再次检查 T-Stat,我们将使用另一个导入的库。这个公式接受我们的两个样本均值,这两个均值与我们使用自举方法创建的数组相同,并输出一个 T 值和一个 P 值。

stats.ttest_ind(sample_means_overall_eng,
sample_means_overall_spanish)Ttest_indResult(statistic=-480.6580710651088, pvalue=0.0)

如您所见,T-Stat 与我们之前计算的完全相同!这是一个非常好的健全性检查,公式也给了我们一个 P 值。

6。评估我们的 P 值

当我们想要接受或拒绝我们的零假设时,我们想要参考我们的 p 值。在本教程的前面,我们将 alpha 定义为. 05。这意味着我们期望假设我们的零假设是正确的,我们的测试在 95%的情况下是正确的,而另外 5%是不正确的,因为随机机会。由于这是一个我们上面定义的 双尾检验 ,我们就把 alpha 误差一分为二,放在我们分布的两边。这意味着我们要寻找的 p 值是 0.025,也就是 2.5%。如果我们的 p 值小于或等于我们的预期误差,那么我们将拒绝我们的零假设。

这背后的逻辑有点反直觉。p 值是我们得到超出 95%置信区间的随机结果的可能性。如果 p 值小于我们的 alpha,这意味着超出 95%的结果不太可能是随机的,这意味着它是显著的,不应该作为错误被忽略。然而,如果 p 值高于我们的α值,这意味着在我们的 95%区间之外的结果很可能是随机的,所以我们不应该惊慌失措,也不会拒绝(也就是保持)我们的零假设。

结论:

对于我们的例子,由于我们的 p 值为零,这意味着我们将接受我们的替代假设,并得出结论,英格兰或西班牙球员的整体技能存在差异。

根据 FIFA 球员 19 数据集显示,西班牙球员明显优于英国球员。所以,如果你想成为一名职业足球运动员,或者你想让你的孩子成为下一个莱昂内尔·梅西,也许西班牙是你应该训练他们的地方。

一些旁注:

效应大小对功效/样本大小:效应大小和功效有负的线性关系。Power 帮助您确定样品的尺寸,以满足其要求。根据您的能力,您需要的样本数量将根据效果大小而变化。例如,如果您有一个大的效果尺寸,那么为了满足您的功率要求所需的样本数将会更少。就像上面的例子一样,如果我取 0.90 的幂而不是 1,那么最小样本量应该是 30 左右。这是因为两个样本平均值的效应大小非常接近于 1。

p 值与效应大小:评估假设检验的结果时,p 值是一个有用的工具。效应大小可以预测 p 值的结果。如果影响大小非常大,就像我们的测试中一样,那么有理由认为两个样本组的平均值之间存在显著的统计学差异。如果存在统计学上的显著差异,那么 p 值将非常接近于零,这意味着您将拒绝零假设。因此,您应该记住,如果您运行一个效应大小在 0.6 到 1.0 之间的测试,并且 p 值高于您的 alpha 值,您可能需要重新检查您的测试并确保没有出现错误。(我知道这一点,因为我在编写本教程时犯了这个错误)

Bootstrapping: Bootstrapping 并不总是必要的,事实上,它是一种被采用的方法,因为计算机几乎可以瞬间创建新数据。如果您有大量正态分布的数据,那么您不必进行引导。Bootstrapping 是一种在数据有限且可能无法完美分布时使用的工具。

我希望这篇教程有所帮助。我介绍了一些不同的策略,这些策略对于假设检验来说并不完全必要,但是我认为介绍更复杂的想法会有所帮助。如果你对代码感到好奇,想看看我的回购,它的链接 在这里 LinkedIn 上联系我!

还有,查一个我参与的 近期项目 。我们用足球数据按联赛得出了主场优势、阵型优化、球队属性的一些结论!

参考文献:

p 值定义:https://www.statsdirect.com/help/basics/p_values.htm

z 值定义:https://www . statistics show to . data science central . com/probability-and-statistics/z-score/

实力:https://www.statisticsteacher.org/2017/09/15/what-is-power/

类型错误:https://en.wikipedia.org/wiki/Type_I_and_type_II_errors

掌握数据科学和实现职业转型的 5 大常见问题

原文:https://towardsdatascience.com/mastering-data-science-certification-abf8a6afefb4?source=collection_archive---------17-----------------------

Photo by Johannes Andersson

最近,我一直在指导弗吉尼亚一所历史悠久的学校的商业分析硕士项目的应届毕业生。具有讽刺意味的是,尽管分析技能的需求很高,但残酷的现实是,这些学生发现即使在获得分析硕士学位后,也很难获得面试和工作。

这并不是说他们在从哪里获得分析技能方面做出了错误的选择——该计划涵盖了很多分析领域,并在计划结束时提供了与真实客户、真实项目的实践经验。

挑战在于掌握工作转换的复杂性,就像他们掌握了商业分析一样。从本质上来说,找工作就像营销——不是每个收到传单的人都会打电话接受邀请。但是有一些方法可以提高几率,下面是方法。

1.求职有一个漏斗。我曾经和想要成为分析专家的人聊过,他们申请了 5 份、10 份甚至 20 份工作,当他们没有得到一次面试机会时,他们会感到失望。我提醒他们,“不是你没有得到面试机会,而是你还没有得到的面试机会!”5 份、10 份、20 份甚至 50 份工作申请都不足以填满漏斗的顶端;不足以获得 20 次面试和一两个工作机会。

我对职业转换客户的经验法则是申请大约 180 份“目标”工作。如果他们没有获得 20 次面试机会,那么他们可能会得出结论,他们的简历有问题,但之前没有。如果他们完成了 20 次面试,却没有得到一两个机会,那么他们可以得出结论,他们在面试中做错了什么,但之前没有。当然,所有这些假设都已经满足:他们在Aryng analytics aptitude assessment中获得了 16 分或更高的分数,完成了核心课程,完成了客户项目(客户对此很满意),缩小了他们的目标工作概况,并根据他们的每个目标概况定制了简历。这些数字可能看起来更好,这取决于你所在地区、行业和经验水平等的需求。当然,如果你在公司内部调动或者通过你的关系网,你的漏斗会看起来更好。

2.锁定目标会增加你的胜算。不要盲目申请 180 的工作。相反,确定你的梦想轮廓。你的梦的轮廓是你从哪里来的函数。如果你在职业生涯的大部分时间里都是一家能源公司的项目工程师,那么在一家能源公司的工程、IT 或战略部门寻找一份分析工作将是你的最佳选择。

LinkedIn 工作和其他工作网站允许你根据这些和其他许多标准来筛选职位。筛选之后,寻找那些让你兴奋到迫不及待去申请并开始工作的工作。结果:你的目标梦的轮廓。从那里,寻找类似的工作。

要增加您的职务库,您可以通过删除一些早期标准来创建更多优先级较低的职务。例如,搜索能源行业的任何分析工作或石油和天然气等相关行业的工程分析工作。

3.定制简历不是可有可无的。在我咨询的几乎 100%的案例中,我都建议职业转型专家从头开始写简历。你的目标是做一份 8 秒钟的简历——一份经过 8 秒钟审核后就可以进入“是”堆的简历。你将如何做到这一点?我的书《把握你的分析职业转型》将为你提供指导,但简而言之,你要讲述一个引人注目的故事,讲述一位分析师在具有影响力的项目中展现出分析才能和分析技能的故事。你可以利用你的客户项目和课程项目以及你以前的工作经验来完成。一旦你有了一份主简历,一定要为你的每一份目标工作量身定制。

4.随着技能的提高,你不需要学习所有的工具和技术。分析更多的是一种心态,而不是学习如何使用工具或掌握每一项技术。一旦你知道了一个类别中的一个工具,你就可以很容易地申请到要求涉及同一类别中另一个工具的工作。例如,如果您知道如何使用 R 来操作数据和构建预测模型,那么如果您使用 SAS enterprise miner,只需几天时间就可以学会 SAS base 中的正确语法,从而达到相同或更短的持续时间。技术也是如此。学习最常用的数据科学技术,其余的可以在项目需要时随时掌握。在商业中,最常用的商业分析方法是聚合和关联分析。最常见的高级/预测技术包括逻辑回归、线性回归、决策树和 k 均值聚类。我会在我的书'每一个好决策的背后''的第三章和第六章分别谈论更多的方法和工具。

5.预计需要 9-12 个月的时间来提高技能和过渡。虽然我看到我的一些客户在 4 个月内就完成了转型,但这并不是大多数专业人士的真实写照。在职业转型专家开始申请工作之前,我的 Aryng 项目有 80 个小时的课程工作和两个月的客户项目,假设他们同时在工作目标和简历方面工作。我们的项目是最快、最快速、最适合工作的项目,但是大多数人仍然需要 9-12 个月来完成他们的过渡。大多数其他项目没有这么快,所以给自己一些时间来享受这个旅程。这不会一蹴而就。

如果你有更多的问题,需要我的个人指导,请点击这里的阿林分析能力评估,开始评估你的分析能力。

使用免费 GPU 在 Google Colaboratory 上掌握快速梯度提升

原文:https://towardsdatascience.com/mastering-fast-gradient-boosting-on-google-colaboratory-with-free-gpu-65c1dd47d1c5?source=collection_archive---------8-----------------------

On the photo NVIDIA K80 GPU, https://www.nvidia.com/ru-ru/data-center/tesla-k80/

决策树上的梯度推进 (GBDT)是一个最先进的机器学习工具,用于处理异构或结构化数据。处理数据时,完美算法的选择在很大程度上取决于数据的类型。对于同类数据,如图像、声音或文本,最佳解决方案是神经网络。对于结构化数据,例如信用评分、推荐或任何其他表格数据,最佳解决方案是 GBDT。

正因如此, Kaggle 比赛的大量获奖方案都是基于 GBDT。GBDT 也大量用于不同的推荐系统、搜索引擎和许多金融机构。

许多人认为 GBDT 无法通过 GPU 有效加速,但事实并非如此。在这篇文章中,我解释了如何使用 GPU 加速 GBDT。

对于 GBDT 实现,我将使用 CatBoost 。CatBoost 以其分类特性支持和高效的 GPU 实现而闻名。它不仅适用于分类数据,而且适用于任何数据,在许多情况下,它的性能优于其他 GBDT 图书馆。

该库是为领先的俄罗斯科技公司 Yandex 的生产需求开发的,后来大约一年半前在 Apache 2 许可下开源。

CatBoost

我的演示的测试环境将是 Google 联合实验室 。这是一个免费访问 GPU 运行时的机器学习研究工具。这是一个 Jupyter 笔记本电脑环境,不需要设置即可使用。

谷歌合作实验室免费提供相当老的 GPU——一个大约 11GB 内存的特斯拉 K80 GPU。随着新的 GPU,速度的提高将更加显著。但即使使用这种旧的 GPU,你也会看到令人印象深刻的速度差异。

下面你会发现在 Colab 中设置 CatBoost 的几个简单步骤,下载数据集,在 CPU 和 GPU 上训练模型,以及比较执行时间。

创建笔记本

导航到协同实验室并创建一个新的 Python 3 笔记本。

将 GPU 设置为硬件加速器

选择 GPU 作为硬件加速器有两个简单的步骤:

第一步。导航到“运行时”菜单并选择“更改运行时类型”

第二步。选择“GPU”作为硬件加速器。

导入 CatBoost

下一步是在环境中导入 CatBoost。大多数库都可以通过简单的快速安装在 Colaboratyro 中!pip 安装命令。

请注意,每次启动新的 Colab 会话时,都需要重新导入库。

!pip 安装 catboost

从 pypi 安装的 CatBoost 库支持 GPU,因此您可以直接使用它。要让它在你的机器上工作,你只需要安装一个 NVIDIA 驱动程序,其他一切都可以开箱即用。对于 Windows 来说也是如此,这使得想要在 GPU 上训练模型的 Windows 用户更加容易。

下载并准备数据集

是时候编码了!配置好环境后,下一步是下载和准备数据集。对于 GPU 训练来说,数据集越大,加速就越大。对一千个样本或更少的数据集使用 GPU 训练没有太大意义,但从大约 10,000 个样本开始,你将获得很好的加速。

我们需要一个大型数据集来展示 GPU 在 GBDT 任务中的能力。我们将使用 Epsilon ,它有 50 万个样本和 2000 个特征,包含在 catboost.datasets 中

下面的代码下载数据集大约需要 10-15 分钟。请耐心等待。

CPU 培训

为了消除关于 GBDT 在 GPU 上没有表现出大的速度增益的神话,我想比较一下 GBDT 在 CPU 和 GPU 上的训练时间。先说 CPU。下面的代码创建一个模型,对其进行训练,并测量训练的执行时间。它使用默认参数,因为它们在许多情况下提供了相当好的基线。

我们将首先训练我们所有的模型 100 次迭代(因为在 CPU 上训练它需要很长时间)。

运行此代码后,您可以将其更改为默认值 1000 或更多次迭代,以获得更好的质量结果。

CatBoost 将需要大约 15 分钟在 CPU 上训练 100 次迭代。

在 CPU 上拟合模型的时间:877 秒

关于 GPU 的培训

所有以前的代码执行都是在 CPU 上完成的。现在该用 GPU 了!

要启用 GPU 训练,您需要使用 task_type='GPU' 参数。

让我们在 GPU 上重新运行实验,看看结果会是什么时间。

如果 Colab 会给你显示“GPU 内存使用接近极限”的警告,按“忽略”即可。

在 GPU 上适应模型的时间:199 秒
GPU 比 CPU 加速:4.41 倍

如你所见,GPU 比 CPU 快 4 倍。它只需要 3-4 分钟,而 CPU 需要 14-15 分钟来适应模型。此外,学习过程仅需 30 秒,而不是 12 分钟。

当我们训练 100 次迭代时,瓶颈是预处理而不是训练本身。但是对于在大型数据集上获得最佳质量所必需的数千次迭代来说,这个瓶颈将是不可见的。你可以尝试在 CPU 和 GPU 上训练 5000 次迭代,再比较一次。

密码

上面所有的代码你都可以在 CatBoost 仓库找到,作为谷歌合作实验室的 教程

摘要

  • GBDT 训练在 GPU 上完美运行。
  • CatBoost 是一个超快速的 GBDT 实现,具有 GPU 开箱即用的支持。
  • Google Colaboratory 是一个有免费 GPU 支持的有用工具。

进一步阅读

[1] V .埃尔绍夫, CatBoost 使用 GPU 在决策树上实现快速梯度提升,NVIDIA 博客文章

[2] CatBoost GitHub

[3] R. Mitchell,梯度增强,决策树和 XGBoost 与 CUDA ,NVIDIA 博客文章

[4] LightGBM GPU 教程

使用 Selenium 和 Python 掌握 web 抓取艺术(第 1/2 部分)

原文:https://towardsdatascience.com/mastering-the-art-of-web-scraping-with-selenium-and-python-part-1-2-90a216199873?source=collection_archive---------24-----------------------

Selenium 是与网站进行高级交互的强大工具:登录、点击…让我们用它来抓取网页

Using Selenium to do web scraping requires a specific strategy to access the data you seek

或者 90%的网站,你不需要硒。事实上,简单的请求美丽组合组合就能完成任务。我写了一篇关于如何做到这一点的文章。

但是如果网站要求你在访问它的内容之前登录呢?如果您想要抓取的页面没有特定的 url,而您需要点击按钮并触发 javascript 操作才能到达正确的页面,该怎么办?

这就是本文的目标:在不简单抓取的网站上实现网页抓取。

安装 Selenium

Selenium 模拟 web 浏览器。实际上,你不仅可以模仿 Chrome,还可以模仿 Firefox、Safari 和 Edge。你需要在这里安装需要的组件。在本文的其余部分,我将使用 Chrome 模拟器。

使用以下内容安装 Python 包:

pip安装硒

用 Python 运行 Selenium

好了,现在让我们打开一个 Jupyter 笔记本,尝试运行以下代码:

导入 webdriver

浏览器= webdriver。chrome(executable _ path = '/usr/local/bin/chrome driver ')
browser . get(URL = " https://www . Facebook . com ")

Selenium opens a new Chrome window and goes to facebook.com

请注意,'/usr/local/bin/chrome driver '可能会为您而改变,无论您是在 Mac、PC 等设备上。

让我们登录:

browser . find _ element _ by _ XPath("//input[@ type = ' email ']")。send _ keys('your _ email _ address _ here')
browser . find _ element _ by _ XPath("//input[@ type = ' password ']")。send _ keys('your _ password _ here')
browser . find _ element _ by _ id(" log in button ")。单击()

这应该很好!如果弹出窗口出现,您可以在以后使用以下命令禁用它。

替换

浏览器= webdriver。chrome(executable _ path = '/usr/local/bin/chrome driver ')

与以下内容

选项=网络驱动程序。chrome options()
option . add _ experimental _ option(" prefs ",{ " profile . default _ content _ setting _ values . notifications ":2 })
browser = web driver。chrome(executable _ path = '/usr/local/bin/chrome driver ',chrome_options=option )

There can be a notification just after you logged in. You can automatically disable pop-ups with Selenium.

结论

硒入门没那么难。棘手的是提前准备好网页抓取方案。在下一篇文章中,我们将关注一个真实的 web 抓取用例,并设计一个具体的方案来实现它。

奖金

几个关于我如何使用 Selenium + Python 的例子

Selenium posting on Facebook

= >我自动在 70 多个脸书小组上发表了关于机器学习的文章。不幸的是,我最近重新运行了代码,发现脸书更新了网站以避免这种行为:/

Selenium filling an online quiz

= >我完成了之前公司的在线培训(约 40 次培训,每次约 120 个不同的问题),并在排行榜上获得第一名

= >我收集了多个网站的在线电影评论(千兆字节的文本数据,真的很酷,可以训练 ML 模型!)

而这只是冰山一角。你还可以做很多其他很酷的事情。

使用 Selenium 和 Python 掌握 web 抓取的艺术[第 2/2 部分]

原文:https://towardsdatascience.com/mastering-the-art-of-web-scraping-with-selenium-and-python-part-2-2-66ee4f3b5f44?source=collection_archive---------19-----------------------

Selenium 是与网站进行高级交互的强大工具:登录、点击…让我们用它来抓取网页

好吧,让我们做一些简单的事情:收集 Spotify 上所有可用的艺术家

That’s a robot scrolling through Spotify’s catalog of artists

⚠️Obviously,我需要在这里放一个免责声明⚠️
不要用这种方法倒卖你收集的数据,这些都是公司私有的。特别是,不要转售 Spotify 数据或对其做任何非法的事情。

第二点备注:既然 Spotify 有一个 API ,那么从网站获取数据就有点蠢了。然而,这是一个很好的练习你通常可以从网络抓取中获得比使用受限 API 更多(但更慢)的东西(虽然不确定 Spotify 是否如此)。

如果您错过了关于 Selenium 和 Python 的第一篇文章,请点击这里:

[## 使用 Selenium 和 Python 掌握 web 抓取艺术(第 1/2 部分)

Selenium 是与网站进行高级交互的强大工具:登录、点击…让我们用它来抓取网页

towardsdatascience.com](/mastering-the-art-of-web-scraping-with-selenium-and-python-part-1-2-90a216199873)

首先,了解网站是如何运作的

Spotify’s page when “a” was typed in the search bar

  1. 您需要登录才能看到艺术家
  2. 搜索时不会显示所有艺术家——否则你的浏览器会因加载的大量数据而崩溃……所以你需要发挥创造力,在避免浏览器溢出的同时获得比显示更多的内容
  3. 你需要以某种方式召集所有的艺术家。同样,这里需要一些创造力

研究 html

打开 Chrome 开发者工具,深入研究 html。艺术家的名字和相关联的 url 位于一个“div”标记中,该标记具有一个等于“Search__content”的类

现在您需要向下滚动,因为只显示了 50 位艺术家。我花了相当多的时间在这里,因为滚动不是在整个窗口,而是在艺术家标签。想法是:取最后一个加载的艺术家并滚动到它。

最后,回顾任务

如前一篇文章所见,登录部分很简单。

正常

搜索部分应该不是最难的:只需在搜索栏中写些东西,然后按回车键。有一个关于搜索完成后向下滚动的问题,以及你需要向下滚动多少次。
~还好好歹

彻底搜索似乎是最棘手的部分。我们不知道我们是否会得到 Spotify 上艺术家的完整列表,没有什么会告诉我们我们已经达到了 Spotify 上艺术家的最大数量。从这个,看起来有 100 万到 100 万 2M 艺术家。
~好吧总之

让我们言归正传。

然后设计你的网页抓取方案

Bot 指南

我们将为我们的网页抓取机器人设定两条准则:

  1. 它将滚动 4̶0̶ 100 次[ 更新:尝试了 40 次,但得到了太多的重复,搜索后改为 100 次
  2. 它将在目录中搜索两个字母的所有可能组合

我们可以估计大约 26x26 个搜索,大约 50 个结果/滚动导致
26 x 26 x 50 x 100 = 3 380 000 最大独特艺术家。注意,我们可能会有很多副本。

并行运行

您想要做的另一件事是将流程设置为并行执行。您不希望等待一个 python 脚本来完成所有工作,而是希望有多个 python 脚本来完成这项工作。

在这种情况下,我们可以设置 2̵6̵ 4bots [ 更新:试过 26 我的电脑死机了,还注意到打开 5 个以上窗口后页面停止刷新;我把它改成了 4 个机器人,每个机器人从一个不同的字母开始,第二个字母尝试 26 个字母。例:机器人 1 会尝试‘aa’,‘ab’,‘AC’,…,‘az’。注意,26 个[ 4 ] Chrome 会话将运行我的 Mac(我可怜的 Mac…)。不确定 Spotify 是否会自动检测同一个用户的多个活动会话并断开我的连接[ 更新:它不关心多个会话 ]。生活是有风险的,有时候你只能盲目去相信。

实时监控

在创建和运行脚本之前,您还需要实时监控流程的进展情况。我不知道如何做到这一点,但我可以想到看到所有机器人的进度条,他们完成的预期剩余时间,当前收集的艺术家数量…因此,多一个 Python 脚本将进行实时监控。

The Jupyter Notebook is monitoring in real-time the 5 web scraping bots. Note they have really different speed.

The number of artists found gets updated in real-time as well as the number of duplicates

还要估计一下需要的时间。滚动 1 次后,您将等待 1 秒钟加载结果。所以~2 分钟/搜。26 次搜索 x 2 分钟 x 6 次运行(4 个机器人同时运行),因此我可以在最乐观的情况下预计整个网页抓取方案将在 3 小时内完成。

让表演开始吧

1 Python script to search some artists, scroll down and save the list in a txt file

Launcher of multiple bots

Jupyter Notebook to monitor everything

我不得不承认我没有完成练习。我的电脑声音比机场还大,我知道我有足够的时间完成它,但无论如何,你得到的想法。

在 2 个小时内,我得到了 38174 个独特的艺术家,其中有 AC/DC,克里斯蒂娜·阿奎莱拉,暴力反抗机器,但没有蕾哈娜或阿姆。

掌握数据科学面试循环

原文:https://towardsdatascience.com/mastering-the-data-science-interview-15f9c0a558a7?source=collection_archive---------1-----------------------

2012 年,《哈佛商业评论》宣布数据科学将是 21 世纪最性感的工作。从那以后,围绕数据科学的炒作只增不减。最近的报告显示对数据科学家的需求远远超过供给。

然而,现实是这些工作大部分是为那些已经有经验的人准备的。另一方面,由于供求关系的变化,入门级的数据科学工作竞争非常激烈。数据科学家来自各种背景,从社会科学到传统的计算机科学背景。许多人还将数据科学视为重塑自我的机会,这将导致大量人员涌入,寻求获得他们的第一个角色。

让事情变得更复杂的是,与拥有更标准化面试流程的软件开发职位不同,数据科学面试可能会有巨大的变化。这部分是因为作为一个行业,仍然没有对数据科学家达成一致的定义。Airbnb 认识到了这一点,并决定将他们的数据科学家分成三路:算法、推理和分析。

https://www.linkedin.com/pulse/one-data-science-job-doesnt-fit-all-elena-grewal/

因此,在开始寻找角色之前,确定什么样的数据科学吸引你是很重要的。基于你对此的回答,你所学的内容和你将被问到的问题会有所不同。尽管类型不同,但一般来说,他们会遵循类似的面试循环,尽管问的特定问题可能会有所不同。在这篇文章中,我们将探讨在面试过程的每一步会遇到什么,以及一些技巧和准备方法。如果你在寻找一份可能在面试中出现的数据科学问题清单,你应该考虑阅读这个和这个。

编码挑战

编码挑战可以从简单的 Fizzbuzz 问题到更复杂的问题,例如使用杂乱的数据建立时间序列预测模型。这些挑战将根据问题的复杂程度进行计时(从 30 分钟到一周不等)。挑战可以在诸如 HackerRank 、 CoderByte 等网站上进行,甚至可以在公司内部解决方案上进行。

通常情况下,你会得到书面的测试案例,告诉你是否通过了一个问题。这通常会考虑正确性和复杂性(例如,运行代码需要多长时间)。如果没有提供测试,编写自己的测试是个好主意。面对数据科学编码挑战,你甚至可能会遇到统计方面的选择题,所以一定要问招聘人员你到底要考什么。

当你面临编码挑战时,记住公司并不总是在寻找“正确”的解决方案是很重要的。他们可能还在寻找代码可读性、良好的设计,甚至是特定的最佳解决方案。所以,即使通过了所有的测试案例,你也没有进入面试过程的下一个阶段,不要太在意。

准备:

  1. Leetcode 上的练习题,既有 SQL 也有传统的数据结构/算法题
  2. 复习数学和统计题的精彩。
  3. SQL Zoo 和 Mode Analytics 都提供了各种可以在浏览器中解决的 SQL 练习。

温馨提示:

  1. 开始编码之前,通读所有问题。这让你的潜意识开始在后台处理问题。
  2. 先从最难的问题开始,当你遇到困难时,先处理简单的问题,然后再处理较难的问题。
  3. 首先关注通过所有的测试用例,然后再考虑提高复杂性和可读性。
  4. 如果你做完了,还剩下几分钟,去喝一杯,试着清醒一下头脑。最后一次通读你的答案,然后提交。
  5. 没有完成编码挑战也没关系。有时,公司会在一周的时间限制内创造出不合理的乏味的编码挑战,需要 5-10 个小时才能完成。除非你绝望了,否则你可以走开,花时间准备下一次面试。

人力资源屏幕

人力资源筛选将包括行为问题,要求你解释简历的某些部分,你为什么想申请这家公司,以及你可能不得不在工作场所处理特定情况的例子。偶尔你可能会被问到一些简单的技术问题,也许是一个 SQL 或者一个基本的计算机科学理论问题。之后,你们将有几分钟时间提出自己的问题。

请记住,与你交谈的人不太可能是技术人员,所以他们可能对组织的角色或技术方面没有深刻的理解。记住这一点,试着把你的问题集中在公司,这个人在那里的经历,以及逻辑问题上,比如面试循环通常是如何进行的。如果你有他们无法回答的具体问题,你可以随时要求招聘人员将你的问题转给能够回答这些问题的人。

记住,面试是双向的,所以在投入更多时间去面试这家公司之前,找出任何危险信号对你最有利。

准备:

  1. 阅读角色和公司描述。
  2. 查找谁将是你的面试对象,并试图找到融洽的领域。也许你们都在某个特定的城市工作,或者在类似的非营利组织做志愿者。
  3. 在打电话之前仔细阅读你的简历。

温馨提示:

  1. 带着问题准备好。
  2. 让你的简历清晰可见。
  3. 找一个安静的地方接受采访。如果不可能,重新安排面试。
  4. 在通话的前几分钟,专注于建立融洽的关系。如果招聘人员想花几分钟谈论昨晚的篮球比赛,让他们去吧。
  5. 不要说你现在或过去公司的坏话。即使你工作的地方很糟糕,它也不会让你受益。

技术呼叫

在面试过程的这一阶段,你将有机会接受团队技术成员的面试。诸如此类的调用通常使用诸如 Coderpad 之类的平台进行,它包括一个代码编辑器以及一种运行代码的方式。偶尔你可能会被要求在谷歌文档中写代码。因此,您应该能够轻松地进行编码,而不需要任何语法突出显示或代码补全。就语言而言,Python 和 SQL 通常是您需要编写的两种语言,但是,这可能会因角色和公司而异。

这个阶段的问题复杂程度不一,从用 windows 函数解决的简单 SQL 问题到涉及动态编程的问题。不管有多难,你都应该在开始编码之前问清楚问题。一旦你对问题和期望有了很好的理解,就从一个强力的解决方案开始,这样你至少有东西可以用了。然而,一定要告诉你的面试官,在考虑优化之前,你首先是在用一种非最优的方式解决这个问题。在你做了一些工作之后,开始优化你的解决方案,让你的代码更具可读性。在整个过程中,用语言描述你的方法是有帮助的,因为面试官可能偶尔会帮你指引正确的方向。

如果你在面试结束时有几分钟时间,利用你正在和团队中的一名技术人员交谈这一事实。询问他们编码标准和过程,团队如何处理工作,以及他们的日常工作是什么样子。

准备:

  1. 如果你面试的数据科学职位是工程组织的一部分,确保阅读破解编码面试和编程面试要素,因为你可能有一个软件工程师进行技术筛选。
  2. 抽认卡通常是复习在这个阶段可能出现的机器学习理论的最佳方式。你可以自己制作,也可以花 12 美元购买这套。机器学习备忘单也是很好的复习资源。
  3. 查看 Glassdoor,了解可能出现的问题类型。
  4. 研究谁将面试你。拥有博士学位的机器学习工程师对你的面试会和数据分析师不一样。

温馨提示:

  1. 如果你被困住了,寻求帮助是没问题的。
  2. 和朋友一起练习模拟技术电话,或者使用像interview . io这样的平台。
  3. 在开始解决问题之前,不要害怕要求一两分钟来思考问题。一旦你开始了,向面试官介绍你的方法是很重要的。

带回家的项目

“带回家”在数据科学面试环节中越来越受欢迎,因为它们往往与你开始工作后将要做的事情联系得更紧密。它们可以出现在技术筛选之前的第一次人力资源筛选之后,也可以作为现场交付内容。公司可能会测试你处理模糊问题的能力(例如,这里有一个数据集,找到一些见解并向业务利益相关者推销),或者专注于更具体的交付成果(例如,这里有一些数据,建立一个分类器)。

如果可能的话,试着问一些澄清性的问题,以确保你知道他们在测试你什么,你的听众是谁。如果你带回家的观众是商业利益相关者,用技术术语填充你的幻灯片不是一个好主意。相反,把重点放在可行的见解和建议上,把技术术语留给附录。

虽然所有带回家的目标可能不同,但共同点是你将从公司接收数据。所以不管他们让你做什么,第一步总是探索性的数据分析。幸运的是有一些自动化的 EDA 解决方案,比如 SpeedML 。这里你主要想做的是调查数据中的异常。通常情况下,公司会综合生成数据,留下特定的复活节彩蛋供您寻找(例如,客户收入的幂律分布)。

一旦你完成了你的任务,试着从朋友或导师那里得到一些反馈。通常,如果你在一个带回家的项目上工作了足够长的时间,你可能会开始只见树木不见森林,所以从一个不了解你的背景的人那里得到反馈总是好的。

准备:

  1. 练习带回家的挑战,你可以从 datamasked 购买,或者通过查看这个 Github repo 上没有问题的答案。
  2. 复习可能对你的工作有帮助的库和工具。例如用于快速数据可视化的 SpeedML 或 Tableau。

温馨提示:

  1. 一些公司故意提供一个带回家的东西,要求你发邮件给他们以获得额外的信息,所以不要害怕联系!
  2. 一个好的带回家通常可以抵消现场的任何不良表现。理由是,尽管你不知道如何解决特定的面试问题,但你已经展示了解决他们日常可能遇到的问题的能力。因此,如果在做更多的 Leetcode 问题和润色你的现场演示之间做出选择,关注后者是值得的。
  3. 确保保存您所做的每个现场挑战。您永远不知道在未来的挑战中什么时候可能需要重用一个组件。
  4. 只要你陈述出来,就可以做出假设。在这种情况下,信息不对称是必然的,做一个假设比不断地用问题轰炸你的招聘人员要好。

现场

现场面试将由一整天的一系列面试组成,包括午餐面试,这通常是评估你的“文化契合度”。

重要的是要记住,任何让你走到这一步的公司都希望看到你成功。他们已经花了大量的金钱和时间面试候选人,将范围缩小到现场候选人,所以对你的能力要有信心!

确保向招聘人员要一份将要面试你的人的名单,这样你就有机会提前做一些调查。如果你面试的是一位主管,你应该集中精力准备更高层次的问题,比如公司战略和文化。另一方面,如果你面试的是一名软件工程师,他们很可能会让你在白板上写下一个编程问题。如前所述,这个人的背景会影响他们会问的问题类型。

准备:

  1. 尽可能多地阅读关于这家公司的资料。公司网站、、CrunchBase 、维基百科、最近的新闻文章、盲人、玻璃门,都是收集信息的绝佳资源。
  2. 和一个朋友进行一些模拟面试,这个朋友可以对你可能表现出的任何言语上的抽搐或回答中的漏洞给予反馈。如果你要在现场做一个带回家的演示,这尤其有用。
  3. 为常见的行为面试问题准备好故事,比如“说说你自己吧”、“为什么选择这家公司?”“告诉我一次你不得不与一个难相处的同事打交道的经历”。
  4. 如果你有软件工程师在现场,你很有可能需要温习一下你的数据结构和算法。

温馨提示:

  1. 不要太认真。这些面试官中的大多数宁愿回到他们的办公桌前做他们被分配的项目。所以,尽你所能让你的面试官有一次愉快的经历。
  2. 确保修整该部分。如果你去东海岸的一家财富 500 强公司面试,你可能需要比去西海岸的一家初创公司面试时穿得保守得多。
  3. 利用浴室和休息时间来调整自己。
  4. 问一些你真正感兴趣的问题。你在面试这家公司,就像他们在面试你一样。
  5. 现场结束后,给你的招聘人员和招聘经理发一封简短的感谢信。

要约和谈判

对于许多人来说,谈判可能看起来不舒服,尤其是对于那些没有行业经验的人。然而,现实是谈判几乎没有坏处(只要你礼貌对待),还有很多好处。

通常情况下,公司会通过电话通知你他们打算给你一份工作。在这一点上,当场承诺并接受提议可能很有诱惑力。相反,你应该表达你对这份工作的兴奋,并要求他们给你一些时间与你的另一半或朋友讨论。你也可以提前告诉他们你还在面试其他几家公司,你会很快回复他们。有时这些提议有截止日期,然而,这些通常是相当随意的,可以由你的一个简单请求来推动。

你的谈判能力最终取决于多种因素,但最大的因素是选择性。如果你手上有两个很好的报价,谈判会容易得多,因为你可以选择离开。当你在谈判时,有各种各样的杠杆可以利用。三个主要的是你的基本工资、股票期权和签约/搬迁奖金。每个公司都有不同的政策,这意味着一些杠杆可能比其他杠杆更容易拉动。一般来说,签约/调动是最容易谈成的,其次是股票期权,然后是底薪。因此,如果你处于弱势,要求更高的签约/搬迁奖金。然而,如果你处于强势地位,增加基本工资可能对你最有利。原因是,它不仅会在你加薪时起到更高的乘数作用,还会对公司福利产生影响,如 401k 匹配和员工股票购买计划。也就是说,每种情况都是不同的,所以一定要根据需要重新安排谈判的优先顺序。

准备:

  1. 关于谈判的最佳资源之一是 Haseeb Qureshi 写的一篇文章,详细描述了他如何从新兵训练营毕业生到收到来自谷歌、Airbnb 和许多其他公司的邀请。

温馨提示:

  1. 如果你不擅长即兴演讲,让招聘人员的电话转到语音信箱可能会有好处,这样你可以在给他们回电之前冷静下来。你不太可能会接到拒绝电话,因为这些通常是通过电子邮件完成的。这意味着当你给他们回电话时,你应该在心里预演当他们告诉你他们想给你一个机会时你会说什么。
  2. 对公司表现出真正的兴奋。招聘人员可以感觉到候选人只是为了钱,他们可能不太可能在谈判过程中帮助你。
  3. 总是把事情做得很好!即使你没有接受一家公司的邀请,对招聘人员保持礼貌和坦诚也是很重要的。科技行业可能是一个小得惊人的地方,你的声誉很重要。
  4. 不要拒绝其他公司或停止面试,直到你得到一份真正的工作。口头提议有被收回的历史,所以不要庆祝,直到你有书面的东西。

记住,面试是一种可以学习的技能,就像其他任何事情一样。希望这篇文章能让你对数据科学面试有所了解。

这个过程也不是完美的,有时你会因为不具备一些晦涩的知识而无法给面试官留下深刻印象。然而,通过反复的坚持和充分的准备,你很快就能找到一份数据科学的工作!

掌握 Google Colab 的功能

原文:https://towardsdatascience.com/mastering-the-features-of-google-colaboratory-92850e75701?source=collection_archive---------15-----------------------

在本文中,让我们了解更多关于 Google Colab 的信息,并测试它的特性。

Photo by Hrishikesh Mane on Medium

介绍

什么是 Google Colab 及其用法?

Google Colab 是一个数据科学和机器学习的研究工具。这是一个 Jupyter 笔记本电脑环境,不需要设置即可使用。它是迄今为止最顶级的工具之一,尤其是对于数据科学家来说,因为你不需要手动安装大部分的包和库,只需要通过调用它们直接导入即可。而在普通的 IDE 中,你需要安装库。Jupyter notebook 主要用于代码文档,它通常看起来像一篇博客文章。在过去的两个月里,我一直在使用 Google Colab,它对我来说是最好的工具。在这篇博客中,我会给你们一些掌握 Google Colab 的技巧和窍门。敬请关注,阅读所有要点。这些特性甚至是我一开始也很难实现的,现在我掌握了它们。让我们来看看谷歌 Colab 笔记本的最佳功能。

你可以在这里 访问 Google Colab 。去输入你的第一个程序。

特征

1)运行电池:

要“运行单元格”(单元格是您输入要执行的代码或文本的地方),您可以按“ Ctrl+Enter ”或“ Shift+Enter ”。我个人使用“ Shift+Enter ”是因为当你按下“ Shift+Enter ”时,它会运行那个特定的单元格并自动创建一个新的单元格,这是一个方便的功能,可以快速完成工作。

Using “Ctrl+Enter”

Using “Shift+Enter”

2)上传文件

如果你遵循一些随机的在线教程的步骤,这可能是一个非常痛苦的任务。但我有一个简单的解决方案,这是一个一步到位的过程,你不需要写额外的代码,或执行一些额外的任务,而你只需要手动上传到 Colab。这是做这件事的方法。

下图清楚地表明,您必须右键单击单元格左侧看起来像“ > ”的箭头标记。当你点击它时,你会发现一个有三个选项的标签,你只需要选择“文件”。然后,您可以在“上传选项的帮助下轻松上传您的文件。有一件事你要注意,你应该把文件上传到“ Samples 文件夹之外。给你,你的任务完成了。

Click on the Files tab to upload.

这是你上传文件到 colab 时的样子。

After uploading your file to the Colab.

Colab 中的教程

你知道 Google Colab 不仅用于输入代码,还是学习机器学习、熊猫和神经网络概念的好地方吗?确实可以在 Colab 找到一堆可以提升技能的教程。要找到这些教程,只需点击你左手边的 > ,然后点击“目录”->“更多资源”你就可以在那里找到一堆教程。

You can find many tutorials in Colab.

4)在笔记本中上传图片。

有时候你需要上传图片到笔记本上,只是为了把事情说清楚。当您按照在线教程操作时,添加图像有时会很困难。一个简单的方法,我发现,显然你必须使用一个免费的图像托管网站,以便在笔记本上呈现你的图像。要做到这一点,请使用“ TinyPic ”,这是上传图片的最佳网站,它提供了一系列链接供您选择,如 HTML、Url 等。你也可以上传视频到这个网站。

Choose one of the above links that fit your needs.

一旦你将图片上传到 TinyPic,那么你只需要根据你的要求复制链接,然后粘贴到“文本部分。给你,你的任务完成了。

Paste the link in the Text section

5)使用 Tab 完成代码。

这是 Colab 中最好的特性之一,称为“制表符补全”。制表符补全非常有用,尤其是当您不确定函数的方法时。它显示所有列出的方法,然后您可以选择您需要的方法。为此,您只需按下键盘上的“ Tab 键,就可以看到所有等效方法的完整列表。

Press the Tab key to use this option.

6)直接保存到 GitHub

Google Colab 为您提供了一个将项目保存到 GitHub 资源库的选项,这是一个非常方便的选项。这个选项有助于手动上传你的项目到你的 GitHub,而不是自动保存你的项目到你的库。为此,只需点击屏幕上方的“文件”选项卡,然后点击选项“在 GitHub 中保存一份副本”。

Click on the File Tab to upload to your GitHub

7)将您的项目保存为 PDF

这对我来说是一项痛苦的任务,除非我的教授教我如何去做。因为有时为了提高可读性,您可能需要发送笔记本的 PDF 文档。因为这个 IPYNB 文件是不可读的,除非您有一个解析器。因此,为了保存为 PDF 文档,你只需点击“ Ctrl-P ”,然后点击另存为“ PDF ”。给你,你的任务完成了。我知道这是一个简单的过程,但有时如果你不知道如何去做,这些简单的过程可能会令人头疼。

Press Ctrl-P or Print option.

8)导入库而不安装它们。

Google Colab 给了你一个独特的功能,甚至是最好的 IDE 都没有提供,比如"在没有安装的情况下导入库",你不需要在导入库之前手动安装任何库,你所要做的只是告诉例如 import pandas as pd ,然后你的工作就完成了,那些你必须在命令提示符中键入 pip install pandas 的日子已经一去不复返了,这很恶心。这确实是 Google Colab 最好的功能之一。但是有时你可能想要手动安装一些外部库。

以上是使用 Google Colab 的突出特点或提示,Google Colab 中的一切都是可用的,你只需动动脑筋就能实现它们。此外,我希望阅读这篇博客已经让你更好地了解如何像专业人士一样使用 Google Colab。感谢你们花时间阅读我的博客,请关注更多更新。请在下面的评论区告诉我你对这篇文章的看法。如果你对这篇文章有任何疑问,评论区都是你的。祝你有愉快的一天。

数据科学的数学:效用矩阵上的协同过滤

原文:https://towardsdatascience.com/math-for-data-science-collaborative-filtering-on-utility-matrices-e62fa9badaab?source=collection_archive---------16-----------------------

理解推荐引擎协同过滤模型背后的数学原理

我强烈推荐看看我的另一篇文章,作为推荐引擎的介绍:

[## 推荐引擎入门

它们是什么,它们是如何工作的,以及它们为什么伟大。

towardsdatascience.com](/a-primer-to-recommendation-engines-49bd12ed849f)

概述:什么是协同过滤?

协同过滤是一种使用用户和项目数据的推荐引擎。更具体地说,是个人用户对单个商品的评分。这样,基于来自其他用户的评级来推荐项目,因此,协作。这些数据可以用效用矩阵来表示,其中一个轴是用户,另一个轴是项目。协同过滤推荐引擎的目标是填补效用矩阵中的空白,因为不是每个用户都对每个项目进行了评级,然后输出评级最高的、先前未评级的项目作为推荐。

A simple utility matrix, with 4 users (columns) and 4 items (rows).

填充效用矩阵有三种主要技术:用户-用户、项目-项目和 SVD。我们将使用上面的简单效用矩阵逐一分析,尝试并预测用户 1 对项目 3 的评价。

用户对用户

计算效用矩阵的缺失值有两个主要步骤:

  1. 计算 U1 和所有其他用户之间的相似度
  2. 通过对其他用户的 I3 评分取平均值,计算 U1 对 I3 的评分,根据用户与 U1 的相似度对每个用户的评分进行加权

在这里,我们快速讨论一下相似性度量。常见的有:euclidean distance(T1 的一种具体形式)cosine similarity``Pearson correlation``Jaccard index等。从实验上来看,皮尔逊相关性被证明是最好的。对于这篇文章中的例子,我们将使用余弦相似度。

Left: cosine similarity of U1 to all other users; Right: weighted average of ratings for I3

因此,我们对 U1 和 I3 的预测评级是 4.34!另请注意,不同的相似性度量会给出略微不同的结果。

项目对项目

项目-项目协同过滤与用户-用户非常相似,但不是计算用户之间的相似性,而是计算项目之间的相似性。你想要的最终值是 U1 其他评分的平均值,用 I3 和其他项目的相似度加权

Left: cosine similarity of I3 to all other items; Right: weighted average of ratings for U1

采用这种逐项计算的方法,我们最终得到的预测值为 3.31——与我们之前的预测值 4.34 大相径庭。

需要注意几件事:

  • 当计算相似性时,一些来源说将缺失值视为 0,而一些来源在计算相似性时简单地忽略缺失值的整个行/列。
  • 一般来说,由于用户的独特品味,逐项方法更有效。
  • 在决定是使用用户-用户还是项目-项目时,您可能要考虑算法的复杂性。如果你有 m 个用户和 n 个项目,那么用户-用户的时间复杂度是 O(m ^ n ),项目-项目的时间复杂度是 O(m n)。如果你有更多的用户,你可能会选择条目,反之亦然。

奇异值分解

我们必须从一点点理论开始,来理解这些概念从何而来。奇异值分解(SVD)是矩阵分解的一种形式。矩阵分解是将一个矩阵分解成(通常是三个)矩阵的乘积。如果你还记得代数的话,当我们把二次方程分解成它们的线性部分(即 x + 2x + 1 = (x+1)(x+1) )时,也是类似的思路。

SVD 是由西蒙·芬克在 2007 年 Netflix 奖竞赛中一举成名的型号。如果你学过线性代数课程,奇异值分解通常是利用矩阵的特征值和特征向量将其分解为三个分量矩阵。Python 库中用于解决推荐引擎的算法名为SVD,但它并不完全分解你的效用矩阵。取而代之的是,它在做 SVD 的,并试图使用两个分量矩阵而不是三个分量矩阵来重建你的效用矩阵。如下所示,这两个矩阵可以被解释为项目矩阵和用户矩阵。

Decomposing the utility matrix into an item matrix and a user matrix.

潜在特征指的是所有物品或用户特征的某种抽象。只要你有相同数量的物品和用户的潜在特征,你就可以将矩阵相乘,得到一个与你的效用矩阵维数相同的矩阵。潜在特征的数量是一个可以在模型中调整的超参数。基于矩阵乘法,我们还可以看到,U1 对 I3 的评级值受到项目矩阵的 I3 行和用户矩阵的 U1 列的影响。

因为我们不能分解有缺失值的矩阵,所以我们必须采取另一种方法。这就是机器学习的用武之地。如前所述,我们现在将尝试用我们的项目矩阵和用户矩阵重新创建效用矩阵。这是使用梯度下降的方法完成的:交替最小二乘法

1.初始化

与所有使用梯度下降的模型一样,您必须从一些初始值开始。我们正在初始化两个分量矩阵。在这个例子中,我已经用全 1 初始化了我们的分量矩阵。

In blue: After initializing the component matrices with 1s, the recreated utility matrix is all 2s. In grey: the original utility matrix for comparison.

2.价值函数

在这个模型中,成本函数是允许我们比较我们原始效用矩阵和我们重新创建的效用矩阵中的相应值的任何度量。这意味着,我正在比较我的原始效用矩阵 4 中的 U1-I1 的评级与我重新创建的矩阵2 中的 U1-I1 的评级,并对矩阵中的所有值进行同样的操作。在这里,我使用均方根误差( RMSE:对每个个体的差值求平方,取平均值,然后求平方根)并在计算 RMSE 时将缺失值视为 0。

3.交替最小二乘法梯度下降

这种梯度下降的工作原理是通过一次改变一个分量矩阵中的一个值来尝试最小化成本函数(RMSE)。让我们从寻找项目矩阵中 I1 的第一个潜在特征的最优值开始。

如上图所示,通过改变这个第一个值(现在表示为未知的 x ,我们更新了我们重新创建的效用矩阵的整个第一行。通过矩阵乘法,这整个第一行变成 x + 1。因为矩阵的其余部分是静态的,我们可以通过第一行最小化我们的成本函数。因此,我们只是最小化那个二次方程,以得到 2.5 的最优 x

Our RMSE goes down!

用 2.5 替换 x ,我们重新创建的效用矩阵的第一行变成了 3.5,我们的 RMSE 从 1.75 下降到 1.58!这个过程一遍又一遍地重复,直到 RMSE 再也好不起来。需要注意的是,改变项目或用户矩阵中的一个值,会改变重新创建的效用矩阵的整个行或列。这维护了用户和项目之间的关系,这个过程被称为并行化。一遍又一遍地做这个过程(我是用 Python 库 Surprise 做的,我将在另一篇文章中介绍),我们最终得到 1.15 的 RMSE,这就是我们重新创建的效用矩阵的样子:

4.估价

基于此,我们可以猜测 U1 对 I3 的评分是 3.7!在一个更稀疏的矩阵中,每个用户有多个未知的评分,然后你会推荐以前最高的未评分项目。有趣的是,与我们的用户-用户(4.34)和项目-项目(3.31)预测相比,我们的 SVD 值 3.7 介于使用两个不同轴的相似性之间。

在实际操作中,如果有更多的数据,你可以对你的已知评分做一个train-test-split,然后测量 RMSE 在你的测试集中的实际评分值和它们在模型中的预测值。RMSE 将用于评估模型,不要与在执行此交替最小二乘梯度下降时用作成本函数的 RMSE混淆。RMSE 可以解释为你的预测评级与实际评级的平均偏差,即你的预测平均偏离多少颗星。

我喜欢的资源:

  • 推荐系统的矩阵分解技术:https://data jobs . com/data-science-repo/Recommender-Systems-[网飞]。pdf
  • 给你推荐:Netflix 奖和哈利南与 Striphas 制作的算法文化:https://journals . sage pub . com/doi/pdf/10.1177/1461444814538646
  • 莱斯科维克、拉贾拉曼和乌尔曼对大规模数据集的挖掘:http://infolab.stanford.edu/~ullman/mmds/book.pdf(特别是第 9 章对理解奇异值分解非常有帮助)
  • 惊喜的文档,我用于 SVD 的库:https://surprise.readthedocs.io/en/stable/index.html

“数学人”对数据科学和 STEM 是一种威胁

原文:https://towardsdatascience.com/math-people-are-a-danger-to-data-science-and-stem-20d6f920ccbf?source=collection_archive---------33-----------------------

为什么 STEM 似乎不是所有人都能接触到的,为什么它必须是。

关键要点

  • 你质疑所见的能力是你成为一个有价值的社区成员的原因。为了追求清晰,我们需要赞美问题。
  • 专家和非专家需要能够质疑科学程序和结果,以防止和纠正不良科学。
  • 在像数据科学这样的新领域,这两者都是如此,在这个领域,演示和可视化是传达信息的核心。

当我们小的时候,我们总是被问到这个问题“你是一个数学爱好者吗?”这种对儿童的分类意味着一些人会做数学,而另一些人不会,不管付出多少努力、时间或经验。问题是,我们谈论干细胞领域的这种简单而基本的方式会使重要的研究变得不直观,甚至不可想象。

至关重要的是,关于科学过程的失败和透明度的意义与我们谈论 STEM 领域的方式之间存在差异。我想讨论两个案例,它们以各自的方式至关重要,取决于提出问题、要求答案以及对研究过程和科学应用进行批判性思考的重要性。

从这些案例中吸取的经验教训可以应用于各个研究领域,但在考虑新兴的数据科学领域时具有独特的重要性。当我们面临迷恋数据可视化和时髦词汇的风险时,我们必须更加小心,不要停下来质疑这个过程的每一步。我们对待“失败”和误解的方式对于 STEM 教育、数据的道德使用和跨学科工作具有持久的重要性。

案例 1:拉库尔和格林(2014 年)

Figure 1 from LaCour and Green, 2014.

(这项研究已被广泛报道,所以这里是一个简短的概述。)

迈克尔·拉库尔是 2014 年加州大学洛杉矶分校政治科学系的一名有前途的研究生。他与唐纳德·格林合著了一项令人印象深刻的研究,唐纳德·格林目前是哥伦比亚大学伯吉斯政治学教授。这项研究的问题很简单:有没有可能通过一次对话改变选民对一个有争议问题的看法?拉票员被派出去拜访两个选民的家庭,谈论同性婚姻或回收(一个控制)。一些拉票者会谈论他们在同性群体中认识的人。其他游说者会透露他们是同性恋,并希望结婚。结果令人震惊。选民的想法变了。这是不朽的。拉库尔得到了一份普林斯顿大学助理教授的工作。

发表后不久,两名研究生大卫·布鲁克曼和约书亚·卡拉想要复制和扩展拉库尔和格林的工作。但是他们遇到了一些问题。这项研究在经济上怎么可能是可行的?此外,数据太完美了。2015 年 5 月,唐纳德·格林撤回了这篇文章。

Broockman and Kalla, 2016

但故事并不全是苦涩的。布鲁克曼和卡拉找到了一种方法,实际上正确地进行研究,关于变性恐惧症。他们的研究证明更加严谨。他们公布了他们的数据。他们公布了他们的代码。一切都是透明的。

他们于 2016 年在科学杂志上发表了他们的研究。2017 年,他们和 Jasjeet S. Sekhon 一起发表了他们关于改变这类田间实验设计的工作。这些学者坚持不懈地质疑和批判性地思考进行实验的过程,产生了令人难以置信的工作,不仅对学术界,而且对非学术界都有影响。

插曲:论专长

上面的例子说明,有时即使是专家也可能进行糟糕的科学研究。此外,当糟糕的科学发生时,其他专家有时没有抓住——拉库尔和格林的原始研究发表在科学上!当然,科学有严格的同行评议程序,但即使是专家也会漏掉一些东西。但是数字看起来不错。从所提供的一切来看,这看起来像是很好的科学。此外,人们希望拉库尔的结果是真实的。

同一领域的人需要对解释他们的方法、数据和思维过程负责。质疑事物是如何工作的,事物是如何被书写的,这是推动科学前进的唯一途径。我们必须考虑每一项个人工作能为更大的社区提供什么,以及它将如何影响其他研究人员和科学家。

尽管专家之间的对话对所有 STEM 领域的发展都很重要,但这些讨论似乎离那些认为自己不是技术人员或外行的人很远。专家们努力工作来赢得他们的证书和信誉。但是“专家”的标签也可能成为一个非专家真正应该参与的对话的障碍。布鲁克曼和卡拉能够部分建立在先前的研究基础上,是因为他们处于被尊重和倾听的地位。有时候,非专家的声音会产生真正的、持久的影响。这让我们回到了几十年前医疗保健的一个重要时期。

案例 2:行动起来和 1980 年代的艾滋病行动主义

美国医疗行业的各个方面都充满了争议,从医疗保险到医疗事故。临床试验是医学研究的一个关键部分,因此新药和新疗法可以(安全地)提供给病人。

The New York Times, July 22, 1998, page B1

在 20 世纪 80 年代,艾滋病是一个巨大的、致命的公共问题。医疗行业正在争先恐后地寻找治疗方法,同时遵循他们的方案:长时间的小型临床试验。人们不应该同时参加多个试验,这样结果就不会被污染……但是人们正在死去。他们不知道他们是否服用安慰剂或实际药物。

公开的同性恋群体及其盟友动员了他们的社会资本和金融资本,以一种“非专家”以前没有真正做过的方式介入医疗领域。他们去参加医学会议;他们自学成才。最重要的是,他们与医疗专业人员分享了他们的生活经验。虽然现在患者理解医疗过程似乎很正常,但这在当时并不规范。

这些被认为是该领域之外的人,不可逆转地改变了激进主义和医学研究,尤其是在公共危机时期。他们能够利用自己的“非专家”经验——基本数据——来说,医疗专业人员遗漏了一个非常重要的部分。生命比一部分人精心设计的协议更重要。作为非专家,他们看到了问题,并努力成为解决方案的一部分。

数据科学的含义:“你是一个数学人吗?”

专家和非专家之间清晰的交流是科学探索和进步的核心。但是这个问题,“你是一个数学人吗”掩盖了局外人知识在追求理解非常小众的概念中的重要性。我们不都是这么聊着 STEM 长大的吗?“他们是数学界的人。”“我只是不是一个学数学的人。”

有些人似乎对事物有诀窍。然而,即使像西蒙妮·比尔斯这样的明星运动员也必须在健身房里投入大量时间。一名歌手花费数年时间磨练自己的声音。厨师在厨房工作,完善每一种调料,每一种酱料。

那么,为什么我们坚持告诉人们我们所有人都有一个天生的 STEM 门槛呢?

当我们延续“数学人”和“非数学人”之间的这种划分时,我们就阻止了个人认识到科学是建立在失败和误解之上的。我们允许人们迷恋科学,认为看起来不错,但实际上并不好。

如果布鲁克曼和卡拉没有想过如何进一步推动拉库尔和格林的研究,他们可能永远也不会找到一种方法来使实地实验更加高效和有效。如果行动积极分子没有相信并争取成为医学研究对话的一部分,不清楚艾滋病研究需要多长时间才能赶上。

越来越多的公司现在正在雇用数据科学家,专注于花哨的可视化、大数据和机器学习。在这种环境下,问一个问题,尤其是作为一个非技术人员,会让人觉得你在拿自己的名誉冒险。问一个在这个行业工作了很长时间的人一个问题,会让人感到害怕。我看起来无知吗?我看起来落伍了吗?但这是这些问题最重要的时候。我们不能因为别人的模型或数字有一定的可信度,就认为他们是绝对可靠的。

与以往任何时候相比,不知道事物是如何组合在一起的力量更大。失败可能会产生难以置信的成效和影响。这不同于仅仅敲打键盘直到你的代码工作,或者运行每一个可以想象的测试直到它“工作”——因为从概率上来说,至少有一个测试可能成功。

这是关于系统的提问,对社区贡献的严格忠诚,而不是吹捧任何个人的荣誉,并在别人还没有想到的地方寻找答案。当研究一个技术领域时,如果你的非技术朋友有问题,批判性地思考它们,因为他们可能会发现一些你永远不可能发现的东西。对于那些认为自己不是技术人员或外行,并对某些事情有疑问的人。大声点。你可能会对结果感到惊讶。

参考资料和进一步阅读

  • 《行动起来:艾滋病的治疗和外行专家意见》(哈里·柯林斯和特雷弗·平奇,2002 年)
  • 《数据科学的再现性危机》(扎克·斯科特 2019 年 5 月 17 日)
  • “具有调查结果的现场实验设计:选择更高效、更稳健和更道德设计的框架”(大卫·e·布鲁克曼、约书亚·卡拉和贾斯吉特·s·塞孔,2017 年)
  • “持久减少变性恐惧症:上门拉票的现场实验”(大卫·布鲁克曼和约书亚·卡拉 2016)
  • 《如何要求医学突破:艾滋病斗争的教训》 (NPR 愤怒的另一面,2019 年 2 月 9 日)
  • 《走向可复制性:平衡隐私与出版》(扎克·斯科特 2018 年 5 月 31 日)
  • “我们发现了社会科学最大的骗局之一。以下是我们学到的东西。”(大卫·布鲁克曼和约书亚·卡拉 2015 年 7 月 22 日)
  • “当接触改变思想:一个传递对同性恋平等支持的实验”(迈克尔·拉库尔和唐纳德·p·格林,2014)

如何进入数据科学——数学还是编码

原文:https://towardsdatascience.com/math-vs-coding-data-science-43e216b4f671?source=collection_archive---------5-----------------------

对于那些仍然在决定数学和编码哪个更重要的人来说

如果我知道机器学习算法的整个数学逻辑,但我不能很好地编码,我有机会进入数据科学领域吗?

如果我只是勉强知道那些机器学习算法背后的数学,但我能很好地编码,我有资格成为一名数据科学家吗?

我希望我在大学毕业前努力进入数据科学时知道这个答案。

我的一些背景,我来自一个数学背景,在大学期间没有学很多编程课程。我在大学学的编程语言包括 R,C++,Matlab。

Matlab 不是开源语言,主要用于研究行业。r 没有 Python 那样的大型社区,尤其是在与数据科学相关的库中。C++ (C 族)仍然是编程的根本,所以如果你正在学习编码,我还是会建议你学习 C 族的语言。

我实习的时候,行业里用的大多是 Python。所以,我还是要靠自己去捡 Python。除此之外,我只学了一门和机器学习的数学相关的课程。

我感到不知所措,因为我不仅要学习数学,同时还要提高我的编码技能。因此,在那个时候,我想知道我应该把更多的精力放在编码上还是放在学习数学上。

数学或编码

我将分享我对当前行业中哪个更受欢迎的观点。

让我问你一个问题。如果你是数据科学的技术负责人,你已经有很多博士为你工作,但想进一步扩大你的团队。你心中有两个候选人,一个编码比较好,一个数学概念比较好,你会倾向于哪个候选人?

这个问题没有对错之分,但从我的观察来看,通常情况下,他们会更喜欢那些在编码方面有更好技能的人。

你可能会想,为什么?

原因很简单,因为大部分数据科学方向的项目,将由博士提供,他们应该更有见识。因此,谁能更快地实现多种方法,谁就能成为最后的赢家

那么,你可能会问,统计是数据科学的基础,你是在告诉我,为了进入数据科学,只需要学习如何很好地编码?🤔

不,数学在数据科学中仍然非常重要。更好地理解数学的人将会是那些能够提出新想法来改进机器学习模型的人。

目前市场上有大量的机器学习模型。因此,了解在什么样的场景中使用什么样的模型肯定会节省你很多时间。除此之外,当先前表现很好的型号,突然性能下降,你将能够找出可能的原因。

但是,如果您只是想进入数据科学领域,您不需要在数学部分深入研究太多细节。数据科学不仅仅是知道如何推导或求解数学方程。更重要的是,知道如何定义和解决商业问题

例如,你在一家电子商务公司工作。你有一个自动分类列表的任务。或许,你需要做的第一步是定义问题,也许陈述一个时间表和你需要达到的精确度。下一步,您将思考模型可能面临的一些问题,并且需要澄清。

比方说,如果房源名称和图片属于不同的类别,那么房源应该如何分类?应该按图片分类还是按房源名称分类?

在理解了你的团队同意的标准操作程序(SOP)之后,只有你才能开始这个项目。

回到主题,数据科学高度要求的技能之一是派生 GitHub 代码并在数据集上试用的能力。因此,如果你擅长编码,那么无论编程语言是什么,你都能够测试不同的方法。

例如,您正在使用给定的数据集训练 NER(命名实体识别)模型。让我们想象一下,目前还没有用 Python 写的关于 NER 的代码,唯一可用的代码是用 Java 写的,由斯坦福大学提供。因此,拥有不同编程语言的知识绝对是一个优势,这样你就可以节省用 Python 编写整个代码的时间来训练模型。

另一方面,如果你更多地研究机器学习的数学部分,你会对你应该关注的指标更加敏感,这取决于不同的问题。假设您正在处理一个信用欺诈项目。你应该关注的指标不再是准确性,而是 f1 的分数。因为您的目标是不仅能够识别尽可能多的欺诈案例,而且还能保持准确性。

最后的想法

数学和编码在数据科学中同样重要,但如果你正在考虑在数据科学领域转行或开始职业生涯,我会说编码或编程技能比深入研究各种机器学习模型的数学更重要。

开始做更多真实世界的项目,在面试时能够清晰地陈述和回答问题,一定会增加你进入数据科学的机会。

进入数据科学很难,但是记住不要放弃,继续努力。

你所有的努力很快就会有回报,不管有多难,都要坚持下去。

关于作者

Low 魏宏是 Shopee 的数据科学家。他的经验更多地涉及抓取网站,创建数据管道,以及实施机器学习模型来解决业务问题。

他提供爬行服务,可以为你提供你需要的准确和干净的数据。你可以访问 这个网站 查看他的作品集,也可以联系他获取抓取服务

你可以在 LinkedIn 和 Medium 上和他联系。

线性判别分析是如何得名的?

原文:https://towardsdatascience.com/mathematical-insights-into-classification-using-linear-discriminant-analysis-9c822ad2fce2?source=collection_archive---------25-----------------------

Photo by Franck V. on Unsplash

尽管是宣传最差的机器学习分类工具之一,但线性判别分析(LDA)在各种设置中可以匹配甚至优于逻辑回归。LDA 经常在机器学习中用于降维,但它也可以有效地用于分类。在本文中,我们将深入研究 LDA 的数学基础分类。

在分类中,我们考虑 K 个类{1,2,3,…,K}和一个输入向量 X。我们将 X 分类为属于使 P(Y=i | X)最大化的类 I。

LDA 分类依赖于贝叶斯定理,该定理规定:

这个公式表明,我们可以将 X 属于每个类的概率与输入在每个类中取值的概率联系起来。为了简单起见,我们假设只有一个输入变量,在这种情况下,X 只是一个数字。

我们可以将 P(X|Y)视为一个概率密度函数,如下图所示,其高度告诉我们输入值为 X 的概率,我们有 K 个图,每个类一个。如果图的高度很大,则获得值 X 的概率很高,如果高度很低,则概率很小。

因为我们希望上述公式易于使用,所以我们选择了一个具有良好数学特性的概率密度函数——由以下等式给出的正态分布:

这是 LDA 的一个关键假设。如果输入变量来自近似正态分布,该技术将更好地工作,并且该近似值越小,性能就越差。

将正态分布代入贝叶斯定理,我们得到

为了简单起见,我们还假设只有 2 个类,所以 i=0 或 1,并且这些类对于 x 共享相同的方差。

我们想找到最大化这个值的类。

看到指数会让我们想到对数,因为对数不会改变集合的排列顺序,所以我们继续简化

这些项中的许多项在不同的类中保持不变,因此无助于确定哪个类具有最大的概率。我们可以把它们去掉,只剩下判别函数

我们可以将 X 分类为产生最大判别函数值的那一类。注意,公式在 X 轴上是线性的,这也是 LDA 这个名字的由来。

现在让我们来看一个简单的例子!

将种子设置为 10(这对可再现性很重要),我们使用 R 从均值为 1、方差为 1 的正态分布中随机生成 10000 个点,我们将其指定为组 1(红色)。我们还从均值为+1、方差为 1 的正态分布中随机生成 10000 个点,我们将其指定为第 2 组(蓝色)。我们希望使用 LDA 将一个输入分类为属于这两个组中的一个。从下图中,我们看到 X=0 很好地将两个组分开。

在这种情况下,每组有 10000 个,因此每个组都有均等的机会获得输入。因此 P(Y=0) = P(Y=1) = 0.5。同样,第 1 组的平均值为-1.002,第 2 组的平均值为 0.996。计算我们得到的标准差的估计值

将这些值代入组 1 的判别函数,我们得到

对于第二组,我们得到

我们可以看到,当 X>0.003 时,X 将被分类为属于第 2 组,否则被分类为属于第 2 组。这非常接近理论上存在于两个这样的正态分布之间的 X>0 的真实截止值。

注意我们可以放宽 K=2 的要求,将 X 设为多维向量,导出类似的判别公式。我们只需要计算鉴别函数 K 次,而不是两次。

如果我们放松 Var(X)在 K 个类中是常数的约束,我们会得到一种稍微不同的技术,称为二次判别分析或 QDA。但这是另一篇文章的主题。

感谢您的阅读,并在下面留下您的意见或问题!

梯度下降背后的数学直觉

原文:https://towardsdatascience.com/mathematical-intuition-behind-gradient-descent-f1b959a59e6d?source=collection_archive---------9-----------------------

梯度下降中更新规则的数学推导——机器学习和深度学习中最流行的优化算法

梯度下降是一种寻找函数最小值的迭代优化算法,最常用于机器学习和深度学习。

介绍

如果你在生活中曾见过或听说过“梯度下降”这个术语,你肯定会遇到下面这个等式:

Gradient Descent - parameter update step

和下图:

Cost vs Weight in Gradient Descent

在上式中,L 是损失函数(或成本函数),而 θ 是成本函数所依赖的任何参数。在神经网络(或深度学习)的情况下,这些是权重( W )和偏差( b )。

目标是找到损失函数的全局最小值。这些参数在训练算法的每次迭代期间被更新,直到我们达到损失函数的最小值。

在深度学习(或神经网络)的背景下,我们根据权重和偏差写出上述等式,如下:

weight and bias update in gradient descent

这是梯度下降优化算法中的基本步骤,在训练的每次迭代期间执行。
我们来数学推导一下这个方程(不要慌!你只需要高中基础微积分就可以做到这一点)。这样做之后,无论何时你遇到参数更新步骤,你都会知道它的起源,并且感觉更有力量!

通用学习算法

让我们首先快速回顾一下一般的学习算法:

general learning algorithm

这里的“直到满意”是一个主观条件,可以是许多停止标准中的一个,如达到阈值损失值或重复某个固定次数等。

参数更新步骤

注意,更新步骤包括添加一些变化δw,δbwb 。我们很快就会发现那些确实是损失的负偏导数 w.r.t wb 分别是**-𝛿l/𝛿w- 𝛿L/𝛿 b 其中 L = f( wb )。

让我们用数学公式来表达这些:

注意,我们还没有引入学习率α。我们先来了解一下学习率的需求。

需要学习率

我们知道 θ 是向量,δθ也是向量。
让我们考虑这两个向量的和:

vector sum of θ and Δθ

很明显,与单个矢量相比,两个矢量的合成和相当大。这是因为我们迈出了一大步δθ。我们需要在这个方向上迈出一小步,这样向量和就很小。这也很重要,因为如果我们对参数 θ 进行如此大的更新(δθ,我们可能会错过损失函数 l 的全局最小值。因此,我们引入学习率来限制我们对参数 θ 进行更新的大小。

vector sum of θ and αΔθ

注意如何借助学习率α < 1, we limit the amount of update we make to θ

现在让我们找出δθ的正确值,它将减少损失值。

在我们继续之前,让我介绍一下著名的泰勒级数,我们将用它来求δw,δb,从而得到δθ

泰勒级数及其在梯度下降中的应用

Taylor series

泰勒级数用于找出距离 x 点δx 处的函数值,已知该函数在该点的导数。

让我们用泰勒级数来求δw 的值。
在这种情况下,函数 f 将是损失函数 L,我们对 L 进行级数展开(wδw)。
我们必须找到一个δ
w的值,使得 L(wδw)<L(w)。

Taylor series for loss function in terms of w

在这一步,我们可以推断,我们需要第二项为负,新的损失小于旧的损失。

但是 Loss L(θ) 是一个多元函数。它不仅是重量 w 的函数,也是偏差 b 的函数。我们将它们表示为一个向量 θ = [ wb
所以我们需要写下泰勒级数的向量形式来求δθ。

vector form of Taylor series for parameter vector θ

这里∇ L(θ) 代表损耗 w.r.t θ的一阶梯度。 梯度无非是函数 w.r.t 对其每个参数的偏导数的向量。
类似地∇将是一个向量的二阶偏导数等等。

实际上,学习率α非常小(0.001,0.00001 等。),所以α,α,…将非常小,它们对损耗 L 的贡献可以忽略不计。因此它们可以从等式中忽略。最后的等式将变成

updated equation for loss

寻找δθ的最佳值

由于我们希望更新后的损耗L(θ+αδθ)小于之前的损耗 L(θ) ,并且由于损耗是一个正的量,上述等式中的第二项必须是负的。
所以我们需要这样的δ值 θ 所以使得第二项的点积为负,即我们需要

condition for new loss to be negative

我们知道这一点

cosine of angle between 2 vectors is their dot product divided by product of their magnitudes

我们还知道 cos β 位于-1 和 1 之间,即-1 ⩽ cos β ⩽ +1。
因此,

现在我们希望点积尽可能的负(这样损耗可以尽可能的低)
但是从上面的不等式可以看出,它能获得的最大负值是-k。

现在,为了使点积为-k,cos β 必须等于-1。
cos β = -1 对应 β = 180

由于这两个矢量方向相反,从矢量的性质我们知道

最终参数更新步骤

现在,如果我们在通用学习算法的参数更新步骤中替换这些值,它变成

updated parameter update step in learning algorithm

现在,我的朋友,这个等式与我们开始推导的完全相似。
每次使用此规则更新参数(w 和 b)时,训练集的损失将会减少,直到不能再减少,即当斜率(或偏导数)变为 0 时。

Result in decrease of loss due to iterative update steps

多重权重和偏差的梯度下降规则(矢量化符号)

我们已经导出了单个权重和偏差的更新规则。
在现实中,深度神经网络具有许多权重和偏差,它们被表示为矩阵(或张量),因此我们的更新规则也应该被修改,以同时更新网络的所有权重和偏差。

注意,大多数深度学习文本使用符号δ而不是∇来表示方程中的梯度。

gradient descent update rule for deep neural network

结尾部分

这一个就到此为止。希望看完这些,你对梯度下降算法有了更直观的认识。

梯度下降的数学直觉

原文:https://towardsdatascience.com/mathematical-intuition-of-gradient-descent-3d593c561da2?source=collection_archive---------25-----------------------

数学推理可以被看作是两种能力的结合,我们可以称之为直觉和独创性

这是给好奇的人的。每个人都知道梯度下降以及如何将其应用于成本函数的公式:

for j=0 to n

但是在本文中,我们将关注上面公式中突出显示的部分,以理解梯度下降背后的直觉:为什么从θ的每个分量中减去这个因子会引导我们最终达到最佳θ?所以,基本理解“梯度下降是如何工作的?”。

指导步骤:

  1. 渐变矢量
  2. 梯度向量代表什么?
  3. 将梯度向量应用于成本函数

1.渐变向量:

假设我们有一个成本函数 J,它依赖于两个独立变量θ0 和θ1。那么 J 的梯度向量:

∇G= < ∂J ∕ ∂θ0 , ∂J / ∂θ1 >

在哪里,

函数的∂J ∕ ∂θ0=导数保持θ1 不变。

∂J ∕ ∂θ1 =函数 j w r tθ1 保持θ0 不变的导数。

我们来分析一下。假设函数 J 相对于θ0 和θ1 的曲线如下所示:

如果碗形三维图形被平行于 zθ0 平面的一个平面以特定的θ1 值切割,它将产生一个二维抛物线,如下所示:

偏导数∂J ∕ ∂θ0 表示特定θ1 的二维抛物线的切线斜率,反之亦然,∂J ∕ ∂θ1.也是如此特定(θ0,θ1)处的梯度向量是以这些斜率作为其分量的向量。

2.梯度向量代表什么?

在我们得到答案之前,我们需要了解等高线图的概念。如果 J 的上图被平行于θ0θ1 平面的平面在特定的 z=z1 水平上切割,它将产生一个二维圆,使得对于圆上的每个点,函数 J 将给出一个常数 z1 值。许多这样的图在不同的 z 水平给出了多维曲线的等高线图。

slicing at z=25

Contour Plot of J(θ0 ,θ1)

在等高线图中,梯度向量垂直于水平面,并始终指向更高的水平面,即指向 j 值更高的水平面。这种行为有其逻辑原因,但这需要另一篇关于多变量微积分概念的文章。

3.将梯度向量应用于成本函数

因为我们需要找到使 J 值最小的θ0 和θ1 的值,所以我们在与梯度向量相反的方向上移动与梯度向量的大小成比例的距离(因为它是到下一个水平表面的垂直距离,所以它是到下一个水平表面的最短距离)。

假设我们在 A 点,坐标θ0=a,θ1=b,水平面 z=4。我们想移动到下一个更低水平的表面,比如 z=3。我们有带方向和大小的梯度向量来引导我们到这个较低水平表面 z=3 处的新的点(θ0’,θ1’)。因此通过简单的向量数学,

θ0’= a+(-∂j∕∂θ0)= a-∂j∕∂θ0

θ1' = b + (-∂J ∕ ∂θ1) = b - ∂J ∕ ∂θ1

这是我们开始用的梯度下降公式。重复该过程,直到收敛,即,直到我们到达最低水平表面。Alpha 是学习率乘以梯度向量,以减少达到最低级别表面所需的步骤数。

如你所见,最终的汇聚点很大程度上取决于初始点。

我希望你有直觉。当你被一个又一个的公式轰炸时,这似乎有点令人不知所措。但是,每件事背后都有一个数学推导的逻辑。你只需要好奇。

数学编程——数据科学进步的关键习惯

原文:https://towardsdatascience.com/mathematical-programming-a-key-habit-to-built-up-for-advancing-in-data-science-c6d5c29533be?source=collection_archive---------5-----------------------

我们展示了如何通过模拟飞镖的随机投掷来近似计算圆周率的值。这是建立数学编程习惯的一小步,而数学编程应该是初露头角的数据科学家必备的一项关键技能。

注意

这个故事也被列为 KDnuggets 平台上点击率最高的故事之一。

介绍

数学编程 的精髓在于你建立了一种习惯,将数学概念编码起来,尤其是那些涉及到一系列计算任务的系统化的概念。

这种编程习惯对于从事分析和数据科学的职业非常有用,因为人们每天都要遇到各种各样的数字模式并理解它们。数学编程的能力有助于快速数字分析的快速原型化,这通常是建立数据模型的第一步。

几个例子

那么,我所说的数学规划是什么意思呢?不是已经在各种 Python 库中内置和优化了一堆数学函数吗,比如 NumPy 和 SciPy ?

是的,但这不应该阻止你从头开始编写各种数值计算任务,并养成数学编程的习惯。

这里有一些随机的例子,

  • 通过蒙特卡罗实验计算圆周率——模拟随机向棋盘投掷飞镖
  • 构建一个包含所有处理复数的方法的函数或类(Python 已经有了这样一个模块,但是你能模仿它吗?)
  • 给定每只股票的方差,通过模拟多种经济情景,计算投资组合的平均回报率
  • 模拟并绘制随机行走事件
  • 模拟两个球的碰撞,并根据随机的起点和方向计算其轨迹

如您所见,这些示例可以非常有趣,并且接近真实生活场景。因此,这种技术也带来了为离散或随机模拟编写代码的能力。

当你在网上浏览一些数学性质或概念时,你是否有一种冲动,想用你最喜欢的编程语言编写一段简单的代码来快速测试这个概念?

如果是,那么恭喜你!你有数学编程的根深蒂固的习惯,这将带你在追求令人满意的数据科学职业生涯中走得更远。

为什么数学编程是数据科学的关键技能?

数据科学的实践需要与数字和数字分析建立极其友好的关系。然而,这并不意味着要记忆复杂的公式和方程式。

发现数字模式的能力,以及通过编写简单代码快速检验想法的能力,对一名初露头角的数据科学家大有裨益。

这类似于电子工程师亲自操作实验室设备和自动化脚本,运行这些设备来捕捉电信号中的隐藏模式。

或者,想想一位年轻的生物学家,她擅长在载玻片上制作细胞横截面样本,并在显微镜下快速运行自动化测试,以收集数据来测试她的想法。

重点是,虽然整个数据科学企业可能由许多不同的组件组成,如数据争论、文本处理、文件处理、数据库处理、机器学习和统计建模、可视化、演示等。—对想法的快速实验通常只需要扎实的数学编程能力。

很难准确指出发展数学编程技能所需的所有必要元素,但是一些常见的元素是,

  • 模块化编程的习惯,
  • 对各种随机化技术的清晰认识
  • 能够阅读和理解线性代数、微积分和离散数学的基本主题,
  • 熟悉基本的描述性和推断性统计
  • 关于离散和连续优化方法(如线性规划)的初步想法
  • 基本熟练掌握核心数字库和函数所选择的语言,其中数据科学家想要测试她的想法

您可以参考这篇文章,它讨论了在数据科学的基本动手数学中应该学习什么。

[## 数据科学的基本数学

成为更好的数据科学家需要掌握的关键主题

towardsdatascience.com](/essential-math-for-data-science-why-and-how-e88271367fbd)

在本文中,我们将通过讨论一个非常简单的例子来说明数学编程,这个例子使用向棋盘投掷随机飞镖的蒙特卡罗方法来计算圆周率的近似值。

通过投掷(许多)飞镖来计算圆周率

这是一种通过模拟向棋盘投掷飞镖的随机过程来计算圆周率值的有趣方法。它不使用任何复杂的数学分析或公式,而是试图从纯物理(但 随机 )过程的仿真中计算圆周率的近似值。

这种技术属于蒙特卡罗方法的范畴,其基本概念是模拟随机过程,当重复大量次数时,会产生一些感兴趣的数学量的近似值。

想象一个正方形的镖靶。

然后,里面画了一个圆的镖靶接触到它的所有边。

然后,你朝它扔飞镖。随机。这意味着有些落在圈里,有些落在圈外。但是假设没有飞镖落在棋盘之外。

在投掷飞镖游戏结束时,你计算落在圆圈内的飞镖占投掷的飞镖总数的百分比。将这个数字乘以 4。

结果数字应该是圆周率。或者,如果你投了很多飞镖,这是一个很接近的近似值。

有什么想法?

这个想法非常简单。如果你投出大量的飞镖,那么一个飞镖落在圆内的概率正好是圆的面积与方板的面积之比。在基础数学的帮助下,你可以证明这个比例是π/4。所以,要得到圆周率,你只需要把这个数乘以 4。

这里的关键是模拟投掷许多飞镖,以便使(落在圆圈内的飞镖的)分数等于概率,这一断言仅在这一随机事件的大量试验的限度内有效。这来自大数定律或概率的频率主义定义。

Python 代码

在我的 Github repo 中给出了一个 Jupyter 笔记本,展示了 Python 代码。请随意复制或叉。步骤很简单。

首先,创建一个函数来模拟飞镖的随机投掷。

然后,编写一个函数,根据给定的落点坐标,确定一个飞镖是否落在圆内,

最后,写一个函数,模拟大量的飞镖投掷,从累积结果中计算出圆周率的值。

但是规划不能就此停止。我们必须测试近似值有多好,以及它如何随着随机投掷的次数而变化。与任何蒙特卡洛实验一样,我们希望随着实验次数的增加,近似值会变得更好。

这是数据科学和分析的核心。仅仅编写一个打印出预期输出并停止在那里的函数是不够的。必要的编程可能已经完成,但科学实验不会在没有进一步探索和测试假设的情况下就此停止。

我们可以看到大量的随机投掷可以重复几次来计算一个平均值,得到一个更好的近似值。

简单的代码,丰富的思想

这项技术背后的理论和代码看起来非常简单。然而,在这个简单练习的表象背后,隐藏着一些非常有趣的想法。

函数式编程方法:技术的描述可以用一个整体代码块来编码。然而,我们展示了任务应该如何被划分成模拟真实人类行为的简单功能

  • 扔飞镖,
  • 检查镖的落点坐标并确定它是否落在圆圈内,
  • 重复这个过程任意次

为大型程序编写高质量的代码,使用这种 模块化编程 风格是有指导意义的。

突现行为:在这段代码中,没有使用任何涉及圆周率或圆的性质的公式。不知何故,圆周率的值出现在集体行动中,集体行动是向一块木板随机投掷一串飞镖,然后计算一个分数。这是 涌现行为 的一个例子,其中一个数学模式通过它们之间的相互作用从一组大量重复的同类实验中涌现出来。

频率主义者对概率的定义:概率的定义有两大类,两个激烈对立的阵营——频率主义者和贝叶斯主义者。作为一个频率主义者,很容易将概率定义为一个事件的频率(作为随机试验总数的一部分)。在这个编码练习中,我们可以看到这种特殊的概率概念是如何从大量重复的随机试验中产生的。

随机模拟 : 飞镖的核心功能在其核心使用了一个随机生成器。现在,计算机生成的随机数并不是真正的随机,但出于所有实际目的,它可以被假设为一。在这个编程练习中,我们使用了 Python 的random模块中的统一随机生成器函数。这种随机化方法的使用是随机模拟的核心,它是数据科学实践中使用的一种强有力的方法。

通过重复模拟和可视化来测试断言:通常,在数据科学中,我们会处理随机过程和概率模型,这些都必须基于大量的模拟/实验来测试。因此,当务之急是以渐进的方式思考,并以统计上合理的方式测试数据模型或科学论断的有效性。

摘要(也是对读者的挑战)

我们展示了培养数学规划的习惯意味着什么。本质上,它是从编程的角度来思考,以测试您在头脑中开发的数学属性或数据模式。这个简单的习惯可以帮助未来的数据科学家发展良好的实践。

用简单的几何恒等式、随机模拟的概念和概率的频率主义定义演示了一个例子。

如果你想寻求更多的挑战,

可以通过模拟一个随机行走事件来计算圆周率吗?

如果你想叉这个趣味练习的代码, 请叉这个回购

如果您有任何问题或想法要分享,请联系作者在tirthajyoti【AT】Gmail . com。另外,你可以查看作者的 GitHub 资源库中其他有趣的 Python、R 或 MATLAB 代码片段和机器学习资源。如果你像我一样对机器学习/数据科学充满热情,请随时在 LinkedIn 上添加我或在 Twitter 上关注我。

[## Tirthajyoti Sarkar - Sr .首席工程师-半导体、人工智能、机器学习- ON…

佐治亚理工学院理学硕士- MS,分析这一 MS 计划传授理论和实践…

www.linkedin.com](https://www.linkedin.com/in/tirthajyoti-sarkar-2127aa7/)

数据科学数学

原文:https://towardsdatascience.com/mathematics-for-data-science-e53939ee8306?source=collection_archive---------5-----------------------

你是否被寻找资源来理解数据科学和机器学习背后的数学所淹没?我们掩护你。

动机

学习数据科学或机器学习的理论背景可能是一次令人畏惧的经历,因为它涉及多个数学领域和一长串在线资源。

在这篇文章中,我的目标是建议一些资源来建立必要的数学背景,以便开始并运行数据科学实践/研究工作。这些建议源自我自己在数据科学领域的经验,以及对社区建议的最新资源的跟进。

然而,假设你是机器学习的初学者,并希望在该行业找到一份工作。在这种情况下,我不建议在开始实际工作之前学习所有的数学知识。你可能会感到气馁,因为你一开始就提出了这个理论?)之前的练习(好玩!)。这种自下而上的方法适得其反。

我的建议是反过来做(自顶向下的方法),学习如何编码,使用 PyData 栈(Pandas,sklearn,Keras 等)。),动手构建真实世界的项目,使用库文档和 YouTube/Medium 教程。然后,你会开始看到更大的画面,注意到你缺乏理论背景,去理解那些算法是如何工作的;那一刻,学数学对你来说就有意义多了!

这是神奇的 fast.ai 团队的一篇文章,支持自上而下的学习方法

[## 提供深度学习的良好教育 fast.ai

不幸的是,这是几个关于深度学习的资源开始的地方——要求学习者跟随…

www.fast.ai](https://www.fast.ai/2016/10/08/teaching-philosophy/)

另一个是 Jason Brownlee 在他的金矿“机器学习大师”博客中写的

[## 你做错了。为什么机器学习没那么难

像数学、物理、甚至计算机科学这样的技术课题都是采用自下而上的方法来教授的。这个…

machinelearningmastery.com](https://machinelearningmastery.com/youre-wrong-machine-learning-not-hard/)

资源

我会把资源分成三个板块(线性代数、微积分、统计&概率);资源列表没有特定的顺序。资源多样化,包括视频教程、书籍、博客和在线课程。

线性代数

线性代数用于机器学习,以理解算法如何在引擎盖下工作。都是关于向量/矩阵/张量运算;不涉及黑魔法!

  1. 可汗学院线性代数系列(初学者友好)。
  2. 编码矩阵教程(和书)。
  3. 3Blue1Brown 线性代数系列 。
  4. fast.ai 线性代数 for coders 课程,与现代 ML 工作流程高度关联。
  5. Coursera 第一门课程机器学习专精的数学。
  6. 《应用线性代数导论——向量、矩阵和最小二乘》一书。
  7. 麻省理工线性代数课程,综合性很强。
  8. 斯坦福 CS229 线性代数复习。

结石

在机器学习中利用微积分来制定用于训练算法以达到其目标的函数,即损失/成本/目标函数。

  1. 可汗学院微积分系列(初学者友好)。
  2. 3Blue1Brown 牙石系列。
  3. Coursera 第二门课程机器学习专业化的数学。
  4. 深度学习论文需要的矩阵演算。
  5. MIT 单变量微积分。
  6. 麻省理工学院多元微积分。
  7. 斯坦福 CS224n 微分学复习。

统计与概率

两者都用于机器学习和数据科学,以分析和理解数据,发现和推断有价值的见解和隐藏的模式。

  1. 可汗学院统计与概率系列(初学者友好)。
  2. 看理论:概率统计的直观介绍。
  3. 介绍来自 Udacity 的描述性统计。
  4. 来自 Udacity 的推断统计简介。
  5. 来自 Coursera 的 R 专门化统计。
  6. 斯坦福 CS229 概率论复习。

额外材料

  1. 深度学习书第一部分。
  2. CMU 数学背景为 ML 课程。
  3. 机器学习用数学书。

所以,这就是我为了公共利益放弃我精心策划的数学书签文件夹!我希望这有助于您扩展您的机器学习知识,并消除您对发现 sklearn/Keras/pandas import 语句背后发生的事情的恐惧。

我们非常欢迎您通过查看所列资源或添加新的显著资源来投稿。

Matplotlib+ Seaborn + Pandas:统计数据可视化的理想融合

原文:https://towardsdatascience.com/matplotlib-seaborn-pandas-an-ideal-amalgamation-for-statistical-data-visualisation-f619c8e8baa3?source=collection_archive---------4-----------------------

探索性数据分析包括两个基本步骤

  1. 数据分析(数据预处理、清理和处理)。
  2. 数据可视化(使用不同类型的图来可视化数据中的关系)。

Pandas 是 python 中最常用的数据分析库。python 中有大量用于数据可视化的库,其中 matplotlib 是最常用的。Matplotlib 提供了对情节的完全控制,使情节定制变得容易,但它缺乏对熊猫的支持。Seaborn 是一个构建在 matplotlib 之上的数据可视化库,与 pandas 紧密集成。

这个职位将负责,

  1. seaborn 有不同类型的地块。
  2. 熊猫和 seaborn 的整合如何帮助用最少的代码制作复杂的多维情节?
  3. 如何在 matplotlib 的帮助下定制使用 seaborn 制作的情节?

谁应该阅读这篇文章?

如果你有 matplotlib 和 pandas 的工作知识,并且想探索 seaborn,这是一个很好的起点。如果你刚刚开始学习 python,我建议在对 matplotlib 和 pandas 有了基本的了解之后再回到这里。

1.Matplotlib

尽管许多任务仅使用 seaborn 函数就可以完成,但理解 matplotlib 的基础知识是必不可少的,原因有两个:

  1. 在幕后,seaborn 使用 matplotlib 绘制情节。
  2. 一些定制可能需要直接使用 matplotlib。

下面是 matplotlib 基础知识的快速回顾。下图显示了 matplotlib 的解剖图。

要理解的三个主要类是 图形

数字

它指的是你看到的整个图形。在同一个图中可以有多个子图(轴)。在上面的例子中,我们在一个图中有四个子图(轴)。

轴线

坐标轴指的是图中的实际点。一个图形可以有多个轴,但给定的轴只能是一个图形的一部分。在上面的例子中,我们把四个轴放在一个

轴是指特定图中的实际轴(x 轴/y 轴)。

本文中的每个例子都假设所需的模块和数据集已经被加载,如下所示

让我们试着用一个例子来理解

plt.subplots()创建单个 人物 实例,(nrows*ncols)轴 实例,并返回创建的 人物 实例。在上面的例子中,由于我们已经传递了 nrows=1ncols=1 ,所以它只创建了一个 实例。如果 nrows > 1ncols > 1 ,它会创建一个轴网格,并将它们返回到一个( nrows * ncols)numpy 数组中。

定制轴类最常用的方法有

这里有一个例子,使用上述一些方法进行一些定制

现在我们已经回顾了 matplotlib 的基础知识,让我们继续学习 seaborn

2.海生的

seaborn 中的每个绘图函数要么是一个 图形级 函数,要么是一个 轴级 函数,了解两者的区别是必不可少的。如前所述,一个图形指的是你看到的整个图形,而 Axes 指的是图形中的一个特定的子图。 轴级 函数绘制到单个 matplotlib 轴上,不影响图形的其余部分。另一方面,一个 图形级 函数控制整个图形。一种思考方式是,一个 人物级 函数可以调用不同的 轴级 函数在不同的轴上绘制不同类型的支线剧情

2.1 轴级功能

以下是 seaborn 中所有轴级函数的详尽列表

要使用任何轴级函数,有两点需要理解

  1. 向轴级函数提供输入数据的不同方式。
  2. 指定用于绘图的轴。

2.1.1 向轴级功能提供输入数据的不同方式

有三种不同的方法将数据传递给轴级函数

  1. 列表、数组或系列

将数据传递给轴级函数的最常见方式是使用列表、数组或序列等可迭代对象

**

2.使用熊猫数据帧和列名。

seaborn 受欢迎的主要原因之一是它能够直接处理熊猫数据帧。在这个传递数据的方法中,列名应该传递给 xy 参数,数据帧应该传递给 数据 参数

**

3.仅传递数据帧

在这种传递数据的方法中,只有 Dataframe 被传递给 data 参数。将使用此方法绘制数据集中的每个数值列。该方法只能用于以下轴级功能

这种传递输入数据的方法的一个具体用例是使用上面提到的任何轴级函数比较数据集中多个数值变量的分布

*sns.boxplot(data=iris)*

2.1.2 指定用于绘图的轴

seaborn 中的每个轴级函数都有一个显式的 ax 参数。传递给 ax 参数的轴将被用于绘图。这在控制哪些轴用于绘图方面提供了很大的灵活性。
例如,假设我们想要查看账单总额和小费之间的关系(使用散点图)以及它们在同一张图中不同轴上的分布(使用箱线图)。

每个轴级函数还会返回绘图所在的轴。如果一个 Axes 已经被传递给 ax 自变量,将返回相同的 Axes 对象。然后,返回的 Axes 对象可用于使用不同方法(如 Axes.set_xlabel()、Axes.set_ylabel()等)的进一步定制

如果没有轴传递给 ax 参数,seaborn 将使用当前(活动)轴进行绘图。

在上面的例子中,即使我们没有明确地将 curr_axes(当前活动的轴)传递给 ax 参数,seaborn 仍然使用它来绘图,因为它是当前活动的轴。
id(curr _ Axes)= = id(scatter _ plot _ Axes)返回 True 表示它们是相同的轴。

如果没有轴被传递给 ax 参数,并且没有当前活动的轴对象,seaborn 创建一个新的轴对象进行绘图,然后返回该轴对象

seaborn 中的轴级函数没有任何控制图形大小的直接参数。但是,由于我们可以指定哪些轴用于绘图,通过在 ax 参数中传递轴,我们可以如下控制图形大小

2.2 图形级功能

在探索多维数据集时,数据可视化最常见的用例之一是在不同的数据子集上绘制同一图表的多个实例。seaborn 中的 图级 函数就是为这个用例量身定制的。一个 图形级 函数可以完全控制整个图形,并且每次调用一个图形级函数时,它都会创建一个新的图形,该图形可以包括多个轴,所有这些都以有意义的方式组织起来。seaborn 中三个最通用的图形级函数是 FacetGrid、PairGrid、JointGrid

2.2.1 面网格

考虑以下用例,我们希望在不同的数据子集上可视化总账单和小费之间的关系(通过散点图)。每个数据子集通过以下变量
1 的值的唯一组合进行分类。日(星期四,Fri 星期六,太阳)
2。吸烟者(不管这个人是不是吸烟者)。性别(男性或女性)
这在 matplotlib 中很容易做到,如下所示

上述代码可以分为三个步骤:

  1. 为每个数据子集创建一个轴(子图)
  2. 将数据集划分为子集
  3. 在每个轴上,使用对应于该轴的数据子集
    绘制散点图

步骤 1 可以在 seaborn 中使用 FacetGrid()
完成,步骤 2 和步骤 3 可以使用 FacetGrid.map()完成

使用 FacetGrid,我们可以使用 色调 参数创建将数据集分割成三维的轴。
一旦我们创建了 FacetGrid,我们可以使用 FacetGrid.map()在所有轴上绘制相同类型的图,方法是将图的类型作为参数传递。我们还需要传递用于绘图的列的名称。

因此,“Matplotlib 提供了很好的支持来制作具有多个轴的图,但是 seaborn 通过将图的结构与数据集的结构直接链接来构建它”。使用 FacetGrid,我们既不必为每个子集显式创建轴,也不必将数据显式划分为子集。这分别由 FacetGrid()和 FacetGrid.map()在内部完成。
我们可以将不同的轴级函数传递给 FacetGrid.map()。

此外,seaborn 提供了三个图形级函数(高级接口),它们在后台使用 FacetGrid()和 FacetGrid.map()。
1。relplot()
2。catplot()
3。lmplot()
上面的每个图级函数都使用 FacetGrid()创建多个轴,并在 种类 参数中取一个轴级函数,然后在内部传递给 FacetGrid.map()。因此,上述三个函数在可以传递给它们中的每一个的轴级函数方面是不同的。

显式使用 FacetGrid 比直接使用 relplot()、catplot()或 lmplot()等高级接口提供了更多的灵活性;例如,使用 FacetGrid(),我们还可以将自定义函数传递给 FacetGrid.map(),但是对于高级接口,您只能使用 种类 参数中内置的轴级函数。如果不需要这种灵活性,可以直接使用高级接口

上述三个图形级函数以及 FacetGrid 都返回 FacetGrid 的一个实例。使用 FacetGrid 实例,我们可以访问各个轴,然后可以使用这些轴来调整绘图(如添加轴标签、标题等)。此外,与控制 matplotlib 图形的大小相比,控制图形级别函数的大小是不同的。我们可以使用 高度纵横比 参数来设置每个面(子情节)的高度和纵横比,而不是设置整体的图形大小。

更多示例请参考 FacetGrid 。

配对网格

PairGrid 用于绘制数据集中变量之间的成对关系。每个子图显示了一对变量之间的关系。考虑以下用例,我们想要可视化每对变量之间的关系(通过散点图)。这可以在 matplotlib 中轻松完成,如下所示

上面的代码可以分为两步

  1. 为每对变量创建一个轴
  2. 在每个轴上,使用对应于该变量对的数据
    绘制散点图

步骤 1 可以使用 PairGrid()
完成,步骤 2 可以使用 PairGrid.map()完成。

因此,PairGrid()为每对变量创建轴,PairGrid.map()使用对应于该对变量的数据在每个轴上绘制绘图。我们可以将不同的轴级函数传递给 PairGrid.map()

在对角线轴上绘制散点图是没有意义的。可以在对角线轴上绘制一种图形,在非对角线轴上绘制另一种图形。

还可以在上三角轴、对角轴和下三角轴上绘制不同种类的图。

如果您不需要 PairGrid()的所有灵活性,Seaborn 还提供了一个高级接口 pairplot()来绘制变量的成对关系。它在后台使用 PairGrid()和 PairGrid.map()。

*sns.pairplot(data=iris)*

PairGrid()和 PairPlot()都返回 PairGrid()的一个实例。使用 PairGrid()实例,我们可以访问各个轴,然后可以使用这些轴来调整绘图,如添加轴标签、标题等

更多示例请参考对网格

接缝网格

当我们想要在同一个图中绘制双变量分布和边际分布时,使用 JointGrid。两个变量的联合分布可以使用 散点图/**/regplo**t 或 kdeplot 可视化。变量的边际分布可以通过 直方图 和/或 kde 图可视化。 用于关节分布的轴级函数必须传递给 JointGrid.plot_joint()。用于边际分布的轴级函数必须传递给 JointGrid.plot_marginals()

如果你不需要 JointGrid()的所有灵活性,seaborn 还提供了一个高级接口 jointplot() 来绘制双变量分布和边际分布。它在后台使用 JointGrid()和 JointGrid.plot_joint()。

JointGrid()和 jointplot()都返回 JointGrid()的一个实例。使用 JointGrid()实例,我们可以访问单个轴,然后可以使用这些轴来调整绘图,如添加标签、标题等

更多例子请参考接合栅格

摘要

seabornpandas 整合在一起,有助于用最少的代码制作复杂的多维情节。seaborn 中的每个绘图函数要么是一个 轴级 函数,要么是一个 图形级 函数。 一个轴级 函数绘制到单个 matplotlib 轴上,不影响图形的其余部分。另一方面, 图形级 功能控制整个图形。她的是轴级和图形级函数的快速总结

轴级别

数字级

欢迎提供使本文更好的建议/技巧。感谢阅读!!!

Matplotlib 教程:学习 Python 强大的绘图库的基础知识

原文:https://towardsdatascience.com/matplotlib-tutorial-learn-basics-of-pythons-powerful-plotting-library-b5d1b8f67596?source=collection_archive---------3-----------------------

Photo by rawpixel on Unsplash

什么是 Matplotlib

为了进行必要的统计推断,有必要可视化您的数据,Matplotlib 是 Python 用户的一个解决方案。对于那些使用 Python 和 NumPy 的人来说,这是一个非常强大的绘图库。Matplotib 最常用的模块是 Pyplot,它提供了一个类似 MATLAB 的接口,但它使用 Python,并且是开源的。

安装 Matplotlib

要在本地计算机上安装 Matplotlib,请打开 Python 命令提示符并输入以下命令:

python -m pip install -U pip
python -m pip install -U matplotlib

我假设你希望涉足数据科学和机器学习的世界,因此我建议你从这里下载 anaconda 包发行版。它安装了 python,Jupyter notebook 和其他重要的 python 库,包括 Matplotlib,Numpy,Pandas,scikit-learn。Anaconda 支持 Windows、MacOS 和 Linux。要快速开始使用 Matplotlib 而无需在本地机器上安装任何东西,请查看 Google Colab 。它免费提供与你的 Google Drive 账户相关联的云端 Jupyter 笔记本,并且预装了所有重要的软件包。您也可以在 GPU 上运行您的代码,这有助于加快计算速度,尽管我们在本教程中不需要 GPU 计算。要快速开始使用 Google Colab,请查看这篇令人惊叹的文章。

一般概念

Matplotlib 图形可以分为以下几个部分:

图形:是一个完整的图形,可以包含一个或多个轴(图)。你可以把图形想象成一块包含情节的画布。

轴:就是我们一般认为的剧情。一个图形可以包含多个轴。它包含两个或三个轴对象(在 3D 的情况下)。每个轴都有一个标题、一个 x 标签和一个 y 标签。

****轴:它们是像数字线一样的物体,负责生成图形界限。

****艺术家:图上能看到的一切都是艺术家,比如Text物体、Line2D物体、collection物体。大多数艺术家都被绑在斧头上。

Pyplot 入门

Pyplot 是 Matplotlib 的一个模块,它提供了简单的功能来添加绘图元素,如线条、图像、文本等。当前图形中的当前轴。

制作一个简单的情节

import matplotlib.pyplot as plt
import numpy as np

这里我们导入 Matplotlib 的 Pyplot 模块和 Numpy 库,因为我们将要处理的大部分数据都是以数组的形式出现的。

我们将两个数组作为输入参数传递给 Pyplot 的plot() 方法,并使用show()方法调用所需的绘图。请注意,第一个数组出现在图的 x 轴上,第二个数组出现在 y 轴上。现在我们的第一个图已经准备好了,让我们添加标题,并分别使用方法title()xlabel()ylabel()命名 x 轴和 y 轴。

我们还可以使用方法figure()指定图形的大小,并将值作为行和列长度的元组传递给参数figsize

对于每个 X 和 Y 参数,您还可以以字符串的形式传递可选的第三个参数,该参数指示绘图的颜色和线型。默认格式是 b- ,表示蓝色实线。在下图中,我们使用 go 表示绿色圆圈。同样,我们可以进行许多这样的组合来格式化我们的情节。

我们也可以通过在plot()方法中传递 X 和 Y 轴的多组参数来绘制多组数据,如图所示。

一个图形中的多个图:

我们可以使用subplot()方法在一个图形中添加多个图。在下图中,我们使用这种方法来分离两个图形,这两个图形在前面的例子中绘制在相同的轴上。subplot()方法有三个参数:它们是nrowsncolsindex。它们表示行数、列数和子图的索引号。例如,在我们的例子中,我们想要在一个图中创建两个子图,这样它就在一行两列中出现,因此我们在subplot()方法中传递参数(1,2,1)(1,2,2)。请注意,我们已经为两个支线剧情分别使用了title()方法。我们用suptitle()的方法给图做一个集中的标题。

如果我们希望我们的子图在两行和一列中,我们可以传递参数(2,1,1)(2,1,2)

当我们想要很多支线剧情的时候,上面的制作支线剧情的方法就变得有点乏味了。更方便的方法是使用subpltots()方法。注意两种方法中的不同。该方法采用两个参数nrowsncols分别作为行数和列数。该方法创建了两个对象:figureaxes,我们将它们存储在变量 fig 和 ax 中,这两个变量分别用于更改图形和轴级别的属性。请注意,这些变量名是任意选择的。

用 Pyplot 创建不同类型的图形

1)条形图

条形图是最常见的图形类型之一,用于显示与分类变量相关的数据。Pyplot 提供了一个方法bar()来制作带参数的条形图:分类变量、它们的值和颜色(如果你想指定的话)。

为了使用方法barh()制作水平条形图,我们还可以传递一个参数(及其值)xerryerr(在上述垂直条形图的情况下)来描述数据中的差异,如下所示:

为了创建水平堆叠的条形图,我们使用了两次bar()方法,并在提到条形图的索引和宽度时传递参数,以便将它们水平堆叠在一起。另外,请注意使用了另外两种方法legend()来显示图表的图例,以及xticks()来根据条形的位置标记 x 轴。

类似地,为了将条形图垂直堆叠在一起,我们可以使用参数bottom并在下面提到我们想要堆叠的条形图作为它的值。

2)饼图

另一种基本类型的图表是饼图,可以使用方法pie()制作。我们也可以传入参数来定制饼图,以显示阴影、分解一部分、倾斜一个角度,如下所示:

3)直方图

当我们在查看像身高和体重、股票价格、顾客等待时间等本质上连续的数据时,直方图是一种非常常见的图表类型。直方图的数据在其频率范围内绘制。直方图是概率和统计中非常常见的图形,是各种分布(如正态分布、t 分布等)的基础。在下面的例子中,我们生成了一个包含 1000 个条目的随机连续数据,并将其划分为 10 个相等的层,根据其频率进行绘制。我们使用了 NumPy 的random.randn()方法,该方法生成的数据具有标准正态分布的特性,即均值= 0,标准差= 1,因此直方图看起来像正态分布曲线。

4)散点图和三维绘图

散点图是广泛使用的图形,尤其是在可视化回归问题时非常方便。在下面的例子中,我们输入任意创建的身高和体重数据,并将它们绘制成图表。我们使用xlim()ylim()方法分别设置 X 轴和 Y 轴的极限。

上面的散射也可以三维可视化。为了使用该功能,我们首先导入模块mplot3d,如下所示:

from mpl_toolkits import mplot3d

一旦模块被导入,通过将关键字projection='3d'传递给 Pyplot 模块的axes()方法就创建了一个三维轴。一旦创建了对象实例,我们就将我们的参数高度和重量传递给scatter3D()方法。

我们还可以创建其他类型的三维图形,如线图、曲面图、线框图、等高线图等。上面的例子以简单的线图的形式如下:这里我们使用方法plot3D()而不是scatter3D()

摘要

希望这篇文章对你有用。如果你喜欢这篇文章,请表达你的赞赏。在我们结束这篇文章之前,这里列出了所有出现的方法。

  • plot(x 轴值,y 轴值)-绘制一个简单的折线图,其中 x 轴值对应 y 轴值
  • show()-显示图形
  • title(" string ")-按照字符串的指定设置绘图的标题
  • xlabel(" string ")-按照字符串的指定设置 x 轴的标签
  • y label(" string ")-按照字符串的指定设置 y 轴的标签
  • figure()-用于控制一个图形的级别属性
  • subplot(nrows,ncols,index)-向当前图形添加一个 subplot
  • sup title(" string ")-它为字符串指定的图形添加一个公共标题
  • 支线剧情(nrows,ncols,figsize)——一个在单一调用中创建支线剧情的便捷方式。它返回一个图形和轴数的元组。
  • set _ title(" string ")-一种轴级方法,用于设置图形中支线剧情的标题
  • 条形图(分类变量、值、颜色)-用于创建垂直条形图
  • barh(分类变量、值、颜色)-用于创建水平条形图
  • 图例(loc)-用于制作图表的图例
  • xticks(索引,分类变量)—获取或设置 x 轴的当前刻度位置和标签
  • 饼图(数值,分类变量)-用于创建饼图
  • hist(值,箱数)-用于创建直方图
  • xlim(起始值,结束值)-用于设置 x 轴值的限制
  • ylim(起始值,结束值)-用于设置 y 轴值的限制
  • 散点图(x 轴值,y 轴值)-绘制 x 轴值与 y 轴值的散点图
  • 轴()-将轴添加到当前图形中
  • set _ xlabel(" string ")-用于设置指定为字符串的绘图的 x 标签的轴级别方法
  • set _ y label(" string ")-用于设置指定为字符串的绘图的 y 标签的轴级别方法
  • 散点图 3D(x 轴值,y 轴值)-绘制三维散点图,其中 x 轴值与 y 轴值相对应
  • plot3D(x 轴值,y 轴值)-用 x 轴值与 y 轴值绘制三维折线图

在 Excel 中做矩阵乘法的三种方法— fastai 第二部分,第八课

原文:https://towardsdatascience.com/matrix-multiplication-part2-lesson8-34c9b77855c4?source=collection_archive---------26-----------------------

fastai“从基础开始”的第二部分终于出来了。我不记得上一次对 MOOC 这么兴奋是什么时候了。课程一对外发布,我就开始深入挖掘,加深对深度学习和底层概念的理解。

这次我决定听从杰里米和雷切尔的建议,写博客。这篇特别的文章解释了杰里米在第八课中实现的各种矩阵乘法方法。我将使用微软 Excel 进行说明。

所以让我们开始吧!

矩阵乘法

了解 Jeremy 提到的矩阵乘法的一个很好的互动场所是:

matrixmultiplication.xyz

从图中可以看出,我们对第二个矩阵进行转置,将元素相乘并相加,得到结果。例如,结果矩阵中的第一项15来自1*2 + 6*2 + 1*1 = 2 + 12 + 1 = 15

虽然这种解释在视觉上令人愉悦,但以我的拙见,很难将其转换为代码。所以还是用 Excel,换一种方式理解矩阵乘法吧!

EXCEL 中的矩阵乘法

考虑大小为4x33x4的两个矩阵 AB
注意:在本文中,我将使用粗体符号 AB 来指代矩阵。使用粗体符号引用向量和矩阵是常见的做法。

Matrices A and B

从我们之前看到的图像中,如果你还记得的话,我们对 B 进行了转置,并将 A 的行与 B 的列相乘,得到了结果矩阵。相反,这次让我们跳过转置这一步,直接将行和列相乘。

因此, A 的第 0 行与 B 的第 0 列逐元素相乘,得到的逐元素乘积相加得到结果矩阵 C 中位置[0][0]处的第一项。

下面是它在 Excel 中的样子:

C[0][0] = 11 + 105 + 100*9 = 1 + 50 + 900 = 951

类似地,我们通过将 A 的第 0 行和b的第 3 列逐元素相乘得到C[0][3]。在 excel 中,它看起来像:

C[0][3] = 14 + 108 + 100*12 = 4 + 80 + 1200 = 1284

最后我们按照同样的过程遍历 C 中的每个空盒子,得到最终结果。

C[3][3] = 44 + 408 + 400*12 = 16 + 320 + 4800 = 5136

我们走吧!我们就是这么做矩阵乘法的!那很容易,不是吗?我们现在不仅理解了矩阵乘法,而且还在 Excel 中实现了它!多酷啊。

我个人认为现在你已经准备好处理一些与矩阵乘法相关的规则了(或者简而言之 MatMul ):

  1. ar,acA. 中的行数和列数,同样,设br, bcB. 中的行数和列数,那么为了执行矩阵乘法,需要ac == br。为什么?嗯,正如你在 excel 中看到的,我们将行和列元素相乘,然后将中间乘积相加,得到最终结果。如果维数不匹配,并且一个向量比另一个向量长,我们就不能再进行元素乘法了!
  2. 生成的矩阵的维数将总是ar,bc。即行数来自 A ,列数来自 B.

方法 1:使用 3 进行循环

这里有另一个免责声明,在 Excel 中实现矩阵乘法时,我们不仅理解了它,而且还复制了 Jeremy 的第一个使用 3 进行循环的方法。下面是它在代码中的样子:

def matmul1(a,b):
    ar,ac = a.shape
    br,bc = b.shape
    assert ac==br
    c = torch.zeros(ar, bc)
    for i in range(ar):
        for j in range(bc):
            for k in range(ac): #or br
                c[i,j] += a[i,k]*b[k,j]
    return c

希望你现在能更好地理解它。如果没有,这将是一个很好的时机,可以停下来试验一下代码,看看到底发生了什么。我保证,和我们 Excel 版本一样!

好吧,我假设你花了一些时间思考代码,那么,让我们来讨论一下吧!

  • 为什么前两个循环在range(ar)range(bc)?嗯,正如你在规则 2 中所记得的,我们得到的矩阵将会有维度ar,bc。从 Excel 中我们看到,我们逐个遍历了 C 的每个元素,因此,要遍历ar行和bc列,我们需要 2 个用于range(ar)range(bc)中的循环。
  • 那么,为什么第三个 FOR 循环在range(ac) #or br里呢?从规则-1 中,我们知道ac==br,所以我们是否将range(ac)range(br)放在第三个循环中并不重要。本质上,这是单个元素相乘并相加的地方。根据我们之前的 Excel 示例,对于C[0][0],这是步骤C[0][0] = 1*1 + 10*5 + 100*9 = 1 + 50 + 900 = 951发生的地方,最后我们将继续下一个框。相乘并相加的项数等于ac or br

真的是这样!这是给你的方法 1!这里有一首记住矩阵乘法的歌。(这个我最早是从 fast.ai 上了解到的,原作者不详)

希望现在你已经明白两个矩阵是如何相乘的了。如果没有,这里的是可汗学院的另一个教程。

方法 2:使用逐元素乘法

所以到目前为止,我们一直在解析结果矩阵 C 中的每个位置,寻找单个元素的乘积,然后将它们求和。如果你记得的话,类似于,C[0][0] = 1*1 + 10*5 + 100*9 = 1 + 50 + 900 = 951。当然,肯定有别的办法吧?如果我们不做单个乘积,然后求和,而是一次将向量相乘,得到一个结果向量,然后将结果向量求和,得到最终元素,会怎么样?

m = tensor([1, 2, 3])
n = tensor([10, 10, 10])
m*n>>tensor([10, 20, 30])

到目前为止,我们一直在寻找单个产品10, 20, 30并将它们组合在一起10 + 20 + 30 = 60。但是,真的,所有这些都可以替换为:

m = tensor([1, 2, 3])
n = tensor([10, 10, 10])
(m*n).sum()>>tensor(60)

如果您还记得的话,在range(ac) #or br中最里面的循环是找到单个产品并添加它们。好吧,我们可以替换这个循环来执行向量元素方式的乘积,并在最后放一个.sum(),PyTorch/NumPy 有能力为我们执行元素方式的运算!

下面是它在 excel 中的样子:

C[0][0] = sum(A[row 0] * B[col 0])

类似地,我们通过将 A 的第 0 行的向量与 B 的第 3 列的向量相乘,并将结果向量相加,得到C[0][3]

C[0][3] = sum(A[row 0] * B[col 3])

最后我们按照同样的过程遍历 C 中的每个空盒子,得到最终结果。

C[3][3] = sum(A[row 3] * B[col 3])

注意这和方法-1 有什么不同吗?这一次,我们只是说,要想出类拔萃或 PyTorch,请将 A 的第 0 行与 B 的第 0 列相乘,并对结果向量求和,得到答案。而不是做1*1 + 10*5 + 100*9。例如:对于C[0][0],该方法将 A tensor([1,10,100])第 0 行的矢量与 B tensor{[1,5,9])第 0 列的矢量相乘,得到中间积矢量tensor([1,50,900]),并求和得到C[0][0]位置的结果为tensor(951)

在代码中,它看起来像:

def matmul2(a,b):
    ar,ac = a.shape
    br,bc = b.shape
    assert ac==br
    c = torch.zeros(ar,bc)
    for i in range(ar):
        for j in range(bc):
            c[i,j] = (a[i,:]*b[:,j]).sum()
    return c

因此,我们只需使用两个 FOR 循环来解析 C、的每个位置,并在该位置输入相应的结果。如果i,j代表 C 中的行和列位置,这看起来像..

i:0,j:0
a:tensor([  1,  10, 100]),b:tensor([1, 5, 9])
tensor([[951.,   0.,   0.,   0.],
        [  0.,   0.,   0.,   0.],
        [  0.,   0.,   0.,   0.],
        [  0.,   0.,   0.,   0.]])
---
i:0,j:1
a:tensor([  1,  10, 100]),b:tensor([ 2,  6, 10])
tensor([[ 951., 1062.,    0.,    0.],
        [   0.,    0.,    0.,    0.],
        [   0.,    0.,    0.,    0.],
        [   0.,    0.,    0.,    0.]])
---
i:0,j:2
a:tensor([  1,  10, 100]),b:tensor([ 3,  7, 11])
tensor([[ 951., 1062., 1173.,    0.],
        [   0.,    0.,    0.,    0.],
        [   0.,    0.,    0.,    0.],
        [   0.,    0.,    0.,    0.]])
---
i:0,j:3
a:tensor([  1,  10, 100]),b:tensor([ 4,  8, 12])
tensor([[ 951., 1062., 1173., 1284.],
        [   0.,    0.,    0.,    0.],
        [   0.,    0.,    0.,    0.],
        [   0.,    0.,    0.,    0.]])
---
i:1,j:0
a:tensor([  2,  20, 200]),b:tensor([1, 5, 9])
tensor([[ 951., 1062., 1173., 1284.],
        [1902.,    0.,    0.,    0.],
        [   0.,    0.,    0.,    0.],
        [   0.,    0.,    0.,    0.]])

等等..直到我们得到完整的矩阵 C

tensor([[ 951., 1062., 1173., 1284.],
        [1902., 2124., 2346., 2568.],
        [2853., 3186., 3519., 3852.],
        [3804., 4248., 4692., 5136.]])

方法-3:广播

注意到一个共同的主题了吗?每次都要将每一行 A 与每一列 B 相乘,得到 C 。你注意到重复了吗?我们正在将 A bc中同一行的向量乘以!我们重复这个过程ar次!

有没有办法将 A 的行向量与 B 的所有列相乘,得到 C 中的相应行?是的,有!进入广播……
注意:我不会解释广播,杰里米在这里做得很好。

相反,让我们看看这段神奇的代码

for i in range(ar):
        c[i] = (a[i,:].unsqueeze(-1).expand_as(b)*b).sum(dim=0)

像往常一样,让我们在 Excel 中复制!这会让事情变得非常简单。让我们分步骤做吧。

步骤-1) 选择第一行的 A a[i,:]。我们选择第 0 行作为示例。

Select row 0 of A

步骤-2) 取其转置 a[i,:].unsqueeze(-1)

Take transpose of row 0 of A

步骤-3) 将柱矩阵展开为 B a[i,:].unsqueeze(-1).expand_as(b)

Expand column matrix as B

步骤-4) 元素乘以 B a[i,:].unsqueeze(-1).expand_as(b)*b

Element wise multiply with B

步骤-5) 沿行求和,得到 C 的第 0 行

Sum along side row dimension to get row 0 of C

每排一个的完整广播过程看起来像这样:

Broadcasting as a whole

我希望现在你能收到的广播!那么,让我们看看它在代码中是什么样子的..

def matmul3(a,b):
    ar,ac = a.shape
    br,bc = b.shape
    assert ac==br
    c = torch.zeros(ar,bc)
    for i in range(ar):
        c[i] = (a[i,:].unsqueeze(-1).expand_as(b)*b).sum(dim=0)
        print(f"i:{i}")
        print(c)
    return c

输出如下所示:

i:0
tensor([[ 951., 1062., 1173., 1284.],
        [   0.,    0.,    0.,    0.],
        [   0.,    0.,    0.,    0.],
        [   0.,    0.,    0.,    0.]])
i:1
tensor([[ 951., 1062., 1173., 1284.],
        [1902., 2124., 2346., 2568.],
        [   0.,    0.,    0.,    0.],
        [   0.,    0.,    0.,    0.]])
i:2
tensor([[ 951., 1062., 1173., 1284.],
        [1902., 2124., 2346., 2568.],
        [2853., 3186., 3519., 3852.],
        [   0.,    0.,    0.,    0.]])
i:3
tensor([[ 951., 1062., 1173., 1284.],
        [1902., 2124., 2346., 2568.],
        [2853., 3186., 3519., 3852.],
        [3804., 4248., 4692., 5136.]])

这正是我们所期望的,并且与我们的 Excel 版本相同!

仅此而已!我们已经成功地介绍了包括广播在内的三种矩阵乘法方法。

Google sheet 上图可以在 这里找到 。感谢阅读!如果您有任何问题,请随时拨打https://linkedin.com/in/aroraaman/联系我。

加速矩阵乘法

原文:https://towardsdatascience.com/matrix-multiplication-the-pytorch-way-c0ad724402ed?source=collection_archive---------12-----------------------

让我们用 Python 写一个矩阵乘法的函数。

我们首先找到两个矩阵的形状,并检查它们是否可以相乘。(matrix_1 的列数应该等于 matrix_2 的行数)。

然后我们写 3 个循环来逐元素地乘矩阵。最终矩阵的形状将是(矩阵 _1 的行数)乘以(矩阵 _2 的列数)。

现在让我们创建一个基本的神经网络,我们将使用这个函数。

在本文中,我们将使用 MNIST 数据集进行演示。它包含 50,000 个手写数字样本。这些数字本来就是 28*28 的矩阵(或者拆包后一个线性向量中的 784 个值)。

因此,我们的神经网络将 784 个值作为输入,并将 10 个类作为输出。

现在让我们从 MNIST 验证集中提取 5 个元素,并在这个模型中运行它们。

我们看到,对于仅仅 5 个元素,我们花费了650 milliseconds来执行矩阵乘法。这个比较慢。让我们试着加快速度。

为什么速度很重要?

矩阵乘法构成了神经网络的基础。训练神经网络时,大多数操作都需要某种形式的矩阵乘法。因此,做得好、做得快真的很重要。

source: fast.ai course: Deep learning from the foundations

我们将通过消除循环并用 PyTorch 函数代替它们来加速矩阵乘法。这将给我们 C 速度(PyTorch 之下)而不是 Python 速度。让我们看看它是如何工作的。

消除最里面的循环

我们从消除最里面的循环开始。消除这种循环背后的想法是,我们可以一次对一行(或一列)进行操作,而不是一次对一个元素进行操作。看看下面的图片。

我们有两个张量,我们想把它们的元素加在一起。我们可以写一个循环来实现,或者我们可以使用 PyTorch 的 elementwise 操作 (直接 a + b)来实现。

用同样的想法,我们将消除最里面的循环

我们直接做

我们的函数现在看起来如下:

运行大约需要1.55 milliseconds,这是一个巨大的改进!

如果您不熟悉索引语法,a[i,:]意味着选择ith行和所有列,而b[:,j]意味着选择所有行和jth列。

我们可以编写一个小测试来确认我们更新后的函数给出的输出与原始函数相同。

确实如此。

消除第二个循环

我们现在可以继续消除第二个循环。这是最激动人心的部分,因为这一次,我们将从这里开始

去做

为此,我们需要了解一些被称为 的广播

广播

假设您想要从数据集中的每个数据点减去平均值。同样,你可以写一个循环来这样做,或者你可以利用广播。

在广播中,我们取较小的张量,并通过较大的张量进行广播,使它们具有可比较的形状。一旦它们有了可比较的形状,我们就可以对它们执行 元素运算 。让我们看另一个例子。

你看到那里发生了什么吗?张量 c 被广播,因此它的行数与 m 的行数相同。我们可以通过expand_as()函数找到广播后张量的样子。

这是最精彩的部分。PyTorch 实际上并不复制值。它只是假装这样做。我们来看看t的收纳和造型

张量 t 仍然只存储为[10,20,30],但是它知道它的形状应该是 3*3。这使得广播内存高效。

使用广播,我们将广播 matrix_1 的第一行,并用 matrix_2 的整体进行操作。我们的函数现在看起来如下:

而且只需要402 micro seconds跑!

这是我们能以灵活的方式做的最好的事情。如果你想做得更好,你可以用 爱因斯坦求和 来做。

但是最快的方法是使用 PyTorch 的matmul功能。

它之所以这么快是因为它在底层也使用汇编语言代码。

这就是本文的全部内容。

如果你想了解更多关于深度学习的知识,你可以看看我下面的深度学习系列。

[## 深度学习系列

我所有关于深度学习的文章的系统列表

medium.com](https://medium.com/@dipam44/deep-learning-series-30ad108fbe2b)

参考:

从基础开始深度学习:fastai 。

机器学习的矩阵发展

原文:https://towardsdatascience.com/matrix-phylogeny-for-machine-learning-7a9e65b8f8aa?source=collection_archive---------28-----------------------

线性代数术语,可视化

Source.

如果你像我一样,你用图片思考,而不是文字。

在我自学数学的时候,我不断被各种线性代数术语轰炸:对称矩阵这个,正常矩阵那个,正规矩阵这个和那个。

在某个时候,我屈服了,做了我在这个世界上最喜欢的事情——制作了一个所有事情如何组合在一起的图表:)我将把它贴在这里,以防其他人需要帮助消除歧义,并且是像我一样的视觉人。

事不宜迟,我们开始吧:

Right click and “save image as” to download.

自述文件

这张图应该从上到下阅读。我真的建造了它,主要是正方形矩阵。

我做的第一个也是最关键的一个分离是,我根据 a)它们的特征值/向量(“eig”)和 b)它们的行列式行为(“det”)将矩阵分成两种类型。这给了我们两个独立的分支去探索(分别是左和右)。

方框之间的黑色(垂直)箭头表示遗传关系。任何盒子必然是其正上方盒子的子类型,并且必然继承其父的任何属性。例如,每个正规矩阵必然可对角化,每个对称矩阵必然正规。这也意味着每个对称矩阵都有 n 个线性无关(L.I .)特征向量(继承自可对角化矩阵)和与其共轭转置矩阵交换(继承自正常矩阵)。

彩色(非垂直)箭头填充矩阵类型的关系间隙,否则矩阵类型不会位于另一个矩阵类型之下。例如,因为正交矩阵位于不同的分支,比如说正常和对称,所以仅跟随黑色垂直箭头不足以理解它们之间的关系。所有正规矩阵都是正交的吗?正交矩阵都是正规的吗?

我没有费心去填写每一段可能的关系,只是那些感觉重要的。顺便说一下,如果你更喜欢表格,这是我在画箭头之前填写的表格:

(matrices on top defined through matrices on the left)

接下来,颜色。方框内的蓝色文字是我能为每种矩阵类型找到的最好/最简洁的定义。有时,我还用蓝色包含了有用的知识属性,例如“λ是实数”(特征值是实数)或“∃奇异值分解”(存在一个对角形式,可以通过奇异值分解到达)。

方框颜色:

  • 灰色方框=终端和不太有趣的方框。
  • 蓝框=通过光谱定理连接(见图表底部)。
  • 橙色细框=复杂等价物(该图是关于真实矩阵的,但我忍不住包括了一些流行的复杂版本)。
  • 白盒=正常,不属于以上。

箭头颜色:

  • 红色=双向“不一定”关系
  • 橙色=单向“不一定”关系
  • 绿色=旋转矩阵既有缺陷又无缺陷的特殊情况(分别在实数和复数上)

最后几件事:

  • 右下角的数字代表每种类型的示例矩阵。
  • 我在底部加入了谱定理,并列出它是如何根据 A =恰好可对角化、正常还是对称而变化的。这应该是不言自明的。
  • 我还包括了正定矩阵的 5 个规则(从吉尔伯特·斯特朗令人敬畏的 YT 讲座这里偷来的),因为为什么不呢。

活文档

这张图已经尽我所能的完整了,但是我确信我遗漏了一些东西(甚至可能弄错了一些东西🤭🤭🤭).

把这当作一个活的文档——如果你在下面评论任何想法/修正,我会添加修改并更新帖子。

快乐学习!

大声喊出来 机器学习的数学——如果你对 ML 背后的数学比 MOOCs 通常进入的更详细,这是一个惊人的自学资源。完全公开:我从那里偷了树的总布局:)

使用匈牙利最优分配算法最大化白象中的群体幸福

原文:https://towardsdatascience.com/maximizing-group-happiness-in-white-elephants-using-the-hungarian-optimal-assignment-algorithm-17be4f112746?source=collection_archive---------24-----------------------

了解带有 Python 示例代码的匈牙利(Munkres)最优分配算法,以最大化群体优先于个人的偏好。

It’s July so we can talk about Christmas, right? Photo by Kira auf der Heide on Unsplash

如果你曾在圣诞节前后参加过一次“白象”活动,你可能会感到焦虑,因为你最终得到了一份你不想要的礼物。问题是,有些人带着他们真正喜欢的礼物回家,而有些人可能带着他们不想要的礼物回家,即使这些礼物对其他人来说可能更有价值!在经历了几个累赘之后,我不得不考虑是否有一个更好的方式来分配礼物,以便最大化群体的满意度,而不是少数幸运儿的满意度。也就是说,你可能得不到你的首选礼物,但是团队作为一个整体会更开心,这样下一年就会有另一个累赘。毫不奇怪,有一个有效的图论算法设计来解决这个问题。

让我们考虑一个简单的场景,其中四个玩家(Alex、Brad、Chloe 和 Daisy)正在参与一个白象。按顺序打开礼物后,每个人都觉得礼物的分配不是很理想。他们觉得如果他们知道每个人有多喜欢每份礼物,他们就可以重新分配礼物,以确保整个团队在一段时间内最满意。为此,每个人都要写下自己对每件礼物的喜爱程度,分数范围是 1-100,100 是最喜欢的,结果可能是这样的:

╔════════════╦══════╦══════╦══════╗══════╗
║ Person\Gift║ Apron║ Beer ║Candle║ Dart ║
╠════════════╬══════╬══════╬══════╣══════╣
║   Alex     ║ 100  ║ 20   ║ 13   ║ 41   ║
║   Brad     ║ 14   ║ 100  ║ 21   ║ 99   ║
║   Chloe    ║ 31   ║ 43   ║ 100  ║ 21   ║
║   Daisy    ║ 52   ║ 50   ║ 41   ║ 100  ║
╚════════════╩══════╩══════╩══════╝══════╝

在这种情况下,很明显亚历克斯喜欢围裙,布拉德喜欢啤酒,克洛伊喜欢蜡烛,黛西喜欢飞镖。通过如此分配礼物,该组的总快乐(喜好偏好)最大化到 400。然而,让我们考虑一个更复杂的场景,其中人们最喜欢的项目重叠:

╔════════════╦══════╦══════╦══════╗══════╗
║ Person\Gift║ Apron║ Beer ║Candle║ Dart ║
╠════════════╬══════╬══════╬══════╣══════╣
║   Alex     ║ 99   ║ 99   ║ 13   ║ 41   ║
║   Brad     ║ 14   ║ 99   ║ 21   ║ 11   ║
║   Chloe    ║ 31   ║ 95   ║ 21   ║ 51   ║
║   Daisy    ║ 52   ║ 50   ║ 51   ║ 11   ║
╚════════════╩══════╩══════╩══════╝══════╝

在这种(可能)更现实的情况下,最大化群体幸福的最佳任务应该是什么并不那么直观。亚历克斯、布拉德和克洛伊都喜欢啤酒,但不清楚谁应该喝啤酒,以最大限度地提高群体偏好,而不是只有一个人?我们可以通过置换当前分配的所有可能组合并搜索哪个组合提供组的最高偏好值来以强力方式解决这个问题。

这是上面代码的输出。我们得到行和列的索引,使组的偏好最大化到 300。指数表明亚历克斯应该有围裙,布拉德啤酒,克洛伊飞镖,黛西蜡烛。

>> 
Total preference: 300
Row: [0, 1, 2, 3] Col: (0, 1, 3, 2)

上图显示了所有组合的首选项。上面的暴力代码在人少的时候运行得很快,但是它的伸缩性很差,求解时间为 O(N!)。当我们以 10 个人和 10 件物品的团队规模运行模拟时,我们可以计时可能需要多长时间。

>>
Total preference: 8.555711154285648
Row: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Col: (7, 3, 0, 8, 5, 2, 6, 4, 9, 1)
1 loop, best of 3: 37.2 s per loop

在我的 Macbook Pro 上,这花了 37.3 秒,非常慢。它所花费的时间呈指数增长,所以想象一下,如果你试图为一个 20 人的大白象解决这个问题,需要多长时间!。

幸运的是,这个问题在几十年前就已经解决了,被称为匈牙利算法。它也被称为 Munkres 算法,第一个解决方案实际上可以追溯到 19 世纪 90 年代。匈牙利算法在 O(N⁴) 多项式时间内解决问题,甚至下降到 O(N)。这个算法是在 Scipy 包中实现的,但是它解决的是最小化一个成本矩阵,而不是像我们的场景那样最大化一个值。虽然我们可以简单地对成本矩阵求逆(乘-1),但这里有一个稍加修改的版本,以便于选择是否求解偏好最大化。让我们看看使用这个函数需要多长时间。

>>
Total preference: 8.555711154285648
Row: [0 1 2 3 4 5 6 7 8 9] Col: [7 3 0 8 5 2 6 4 9 1]
100 loops, best of 3: 2.74 ms per loop

与运行蛮力方法所需的 37.3 秒相比,匈牙利算法实现在不到 3 毫秒的时间内解决了问题!让我们看看引擎盖下,了解发生了什么事。

Under the hood. Photo by Erik Mclean on Unsplash

上面的代码实现基于 Bob Pilgrim 的描述,该描述将该方法分为 6 个步骤。然而,该算法的要点可以用以下 5 个步骤来解释。

第一步:遍历每一行,从该行的所有项目中减去最大值项目。这将使每行中最大的项目等于 0。

第二步:检查每一列,从该列的所有项目中减去最大值项目。这也将使列中最大的项目等于 0。

第三步:画出穿过所有 0 的最少的线。

第四步:如果在 n x n 矩阵中画出了 n 条线,则有可能进行最优分配,算法结束。如果行数小于 n ,则转到步骤 5。

第五步:找到没有被任何行覆盖的最大条目,从没有被划掉的每一行中减去这个条目,并把它加到被划掉的每一列中。回到步骤 3。

让我们用我们的示例矩阵来逐步实现这一点。

╔════════════╦══════╦══════╦══════╗══════╗
║ Person\Gift║ Apron║ Beer ║Candle║ Dart ║
╠════════════╬══════╬══════╬══════╣══════╣
║   Alex     ║ 99   ║ 99   ║ 13   ║ 41   ║
║   Brad     ║ 14   ║ 99   ║ 21   ║ 11   ║
║   Chloe    ║ 31   ║ 95   ║ 21   ║ 51   ║
║   Daisy    ║ 52   ║ 50   ║ 51   ║ 11   ║
╚════════════╩══════╩══════╩══════╝══════╝

步骤 1:从每一行中减去每一行的最大值(99,99,95,52)。

╔════════════╦══════╦══════╦══════╗══════╗
║ Person\Gift║ Apron║ Beer ║Candle║ Dart ║
╠════════════╬══════╬══════╬══════╣══════╣
║   Alex     ║ 0    ║ 0    ║ -86  ║ -58  ║
║   Brad     ║ -85  ║ 0    ║ -78  ║ -88  ║
║   Chloe    ║ -64  ║ 0    ║ -74  ║ -44  ║
║   Daisy    ║ 0    ║ -2   ║ -1   ║ -41  ║
╚════════════╩══════╩══════╩══════╝══════╝

步骤 2:从每列中减去每列的最大值(0,0,-1,-41)。

╔════════════╦══════╦══════╦══════╗══════╗
║ Person\Gift║ Apron║ Beer ║Candle║ Dart ║
╠════════════╬══════╬══════╬══════╣══════╣
║   Alex     ║ 0    ║ 0    ║ -85  ║ -17  ║
║   Brad     ║ -85  ║ 0    ║ -77  ║ -47  ║
║   Chloe    ║ -64  ║ 0    ║ -73  ║ -3   ║
║   Daisy    ║ 0    ║ -2   ║ 0    ║ 0    ║
╚════════════╩══════╩══════╩══════╝══════╝

第三步:用最少的行数划掉 0(x 表示划掉)。

_______________x      x
╔════════════╦══════╦══════╦══════╗══════╗
║ Person\Gift║ Apron║ Beer ║Candle║ Dart ║
╠════════════╬══════╬══════╬══════╣══════╣
║   Alex     ║ 0    ║ 0    ║ -85  ║ -17  ║
║   Brad     ║ -85  ║ 0    ║ -77  ║ -47  ║
║   Chloe    ║ -64  ║ 0    ║ -73  ║ -3   ║
║   Daisy    ║ 0    ║ -2   ║ 0    ║ 0    ║x
╚════════════╩══════╩══════╩══════╝══════╝

第四步:在未覆盖的项目中找出最大值(-3 at Chloe,Dart),从所有未覆盖的项目中减去它(Alex:Chloe,Candle:Dart)。然后我们把这个值加到线的交点上(雏菊,围裙:啤酒)。返回步骤 3,测试最优分配。

_______________x      x
╔════════════╦══════╦══════╦══════╗══════╗
║ Person\Gift║ Apron║ Beer ║Candle║ Dart ║
╠════════════╬══════╬══════╬══════╣══════╣
║   Alex     ║ 0    ║ 0    ║ -82  ║ -14  ║
║   Brad     ║ -85  ║ 0    ║ -74  ║ -44  ║
║   Chloe    ║ -64  ║ 0    ║ -70  ║ 0    ║
║   Daisy    ║ -3   ║ -5   ║ 0    ║ 0    ║x
╚════════════╩══════╩══════╩══════╝══════╝

我们回到步骤 3,测试最优分配。

_______________x      x     x       x
╔════════════╦══════╦══════╦══════╗══════╗
║ Person\Gift║ Apron║ Beer ║Candle║ Dart ║
╠════════════╬══════╬══════╬══════╣══════╣
║   Alex     ║ 0*   ║ 0    ║ -82  ║ -14  ║
║   Brad     ║ -85  ║ 0*   ║ -74  ║ -44  ║
║   Chloe    ║ -64  ║ 0    ║ -70  ║ 0*   ║
║   Daisy    ║ -3   ║ -5   ║ 0*   ║ 0    ║
╚════════════╩══════╩══════╩══════╝══════╝

我们完了!我们划掉了所有的零,最小的行数等于矩阵的形状。亚历克斯应该拿围裙,布拉德拿啤酒,克洛伊拿飞镖,黛西拿蜡烛。

这里有一个简短的视频,也很好地解释了这个过程

结论

在本教程中,我们看了如何解决一个最优分配问题,其中每个任务或项目必须与一个人匹配,以最大化总喜欢值。我们展示了使用所有组合来解决问题的暴力方法对于大规模的组来说是难以处理的,但是匈牙利算法可以在几分之一秒内解决它。

我希望这有所帮助,也希望今年冬天你会倾向于在你的白象上尝试一下。我可以看到它在给家庭成员或公司员工分配任务时也很有用。节日快乐!

请随意查看我关于统计和机器学习的其他帖子

[## 量化时间序列数据之间同步性的四种方法

用于计算同步指标的样本代码和数据,包括皮尔逊相关、时滞交叉相关…

towardsdatascience.com](/four-ways-to-quantify-synchrony-between-time-series-data-b99136c4a9c9) [## 为什么有重要变量的模型可能是无用的预测器

统计模型中的重要变量不能保证预测性能

towardsdatascience.com](/why-models-with-significant-variables-can-be-useless-predictors-3354722a4c05) [## 机会是不够的:用排列评估模型的重要性

当训练机器学习模型进行分类时,研究人员和数据科学家经常比较他们的模型…

towardsdatascience.com](/chance-is-not-enough-evaluating-model-significance-with-permutations-e3b17de6ba04)

参考

[## 匈牙利算法—维基百科

匈牙利方法是一种组合优化算法,在多项式时间内解决指派问题

en.wikipedia.org](https://en.wikipedia.org/wiki/Hungarian_algorithm) [## 蒙克雷斯

当选择每个赋值时,不考虑行和列。提出的问题是关于…

csclab.murraystate.edu](http://csclab.murraystate.edu/~bob.pilgrim/445/munkres.html) [## 匈牙利最大匹配算法|精彩的数学和科学维基

匈牙利匹配算法,也称为 Kuhn-Munkres 算法,是一种...

brilliant.org](https://brilliant.org/wiki/hungarian-matching/)

利用数据最大限度地利用稀缺的维护资源

原文:https://towardsdatascience.com/maximizing-scarce-maintenance-resources-with-data-8f3491133050?source=collection_archive---------29-----------------------

政府和非政府组织面临的一个共同问题是如何将有限的资源发挥最大的作用。通常,这些组织必须在信息不完全透明的情况下做出决策。这篇文章展示了如何使用数据分析和建模来帮助组织在这种情况下最大化他们的资源。

为了将这些概念付诸实践,我们将使用以下场景:

坦桑尼亚的大部分人口依赖当地的水泵作为他们清洁水源的主要来源。不幸的是,这些水泵有时会坏掉——限制了清洁水的获取,直到水泵修好。坦桑尼亚农业部负责维护这个由数千台水泵组成的网络;然而,该部门几乎没有能力主动跟踪任何单个水泵的状态。 部门主管要求我们帮助她确定下一年应该修理哪些油井的优先顺序。她估计她的部门每天最多可以部署五名员工,每人每天可以访问一个站点。

好消息是,自 2002 年以来,该部门一直在记录他们在全国各地访问的每台水泵的数据(包括水泵是否正常工作)。这些数据使我们能够建立一个模型,该模型可用于预测水泵是否正常工作,是否正常工作但需要维护,或者是否正常工作。有了这个模型,我们可以开始帮助该部门在未来优先安排维护行程。为此,我们获得了描述约 14K 水泵位置的数据,该部门希望我们预测这些位置内的维护需求。

第 1 部分:构建预测模型

初始基线模型利用 RandomForest 估计值,在使用未用于建立模型的数据进行预测时,大约 70%的时间正确地将水泵分类为功能性/需要维修/非功能性。经过一些进一步的工作,模型的准确性增加到了大约 80%(如果您对模型构建过程感兴趣,模型背后的所有代码都可以在 Github 上找到)。请注意,我们可以探索进一步改进我们的模型;然而,80%的准确率将足以解决这个问题(稍后将详细介绍)。

如下所示,我们的模型使用该部门提供的数据进行了以下预测:

此时,我们可以向部门报告,我们的模型已经识别出 4,774 台可能需要维修的水泵,并对自己的出色工作表示满意。对吗?我们可以这样做,但是部门可能会不太高兴…

如上所述,该部门每天只能修理 5 口井,假设 252 个工作日(美国时间表),该部门在下一年只能修理 1260 台水泵。这意味着我们需要优先服务哪些泵。

第 2 部分:对我们的预测进行优先排序

鉴于我们无法维修我们的模型预测需要维修的所有水泵,我们应该优先维修我们的模型最有把握实际损坏的水泵。这样做相对来说是微不足道的,我们只需查看我们的模型分配给数据集中表示的每个水泵的“非功能性”概率。对这些概率进行排序,可以让我们确定 1260 个我们最有把握损坏的水泵。

这种方法将我们的关注点从最大化我们的模型的整体精度分数转移到一个称为 k 处的精度的度量。这就是为什么我们的模型“足够好”,有 80%的精确度。考虑到我们有限的资源,我们真的只关心我们的模型对我们有能力修复的水泵的预测。因此,我们在 k 处测量的准确度,在这种情况下 k=1,260,大大高于我们的总体准确度分数。投入到将模型的准确性提高到 80%以上的努力将会被放错地方。

有了我们的预测优先级,我们现在可以自信地向部门提交我们的建议。要做到这一点,我们可能应该将我们的优先预测可视化如下:

幸运的是,当我们即将把最后的演示文稿发送给印刷商时,一个想法悄悄潜入我们的脑海……'我不想成为一个维护团队,开车走遍全国各地去访问这些分散的站点。也许还有其他因素需要考虑。

第 3 部分:最大化影响

虽然准确性很重要,但在确定服务水泵的优先级时,我们可能还需要考虑许多其他因素。例如,考虑以下情况可能是有意义的:

  • 人口:多少人被水泵影响?
  • 距离:这个水泵离其他不工作的水泵有多近?

通过将这些指标与油井失效的预测概率相结合,我们可以得出每个水泵的“影响分数”。得出我们的影响分数的公式可能如下所示:

根据影响评分对水泵访问进行优先排序,这使我们建议该部门维修以下水泵:

此外,除了对部门的维护访问进行优先排序,我们还可以量化它们的潜在影响:

下一年对优先水泵的维修将 增加约 60 万人获得清洁水的机会

最后一点,重要的是要考虑我们的影响评分可能会有偏差或产生意想不到的结果。例如,如上图所示,我们的影响得分公式明显偏向于水泵和人口密集的地区,这意味着偏远地区的人口更有可能得不到服务。优先井的变化如下图所示:

在现实世界中,这种意外后果可能需要我们调整影响评分公式,以更好地代表我们的意图。

结论

在这篇文章中,我们回答了几乎每个组织都面临的一个关键问题:我们如何部署稀缺资源以产生最大影响。在这个人为的例子中,我们考虑了如何对我们的模型所识别的机会进行优先级排序。此外,我们探讨了为什么最大化准确性本身可能不是正确的答案。为此,我们研究了如何将准确性之外的因素融入到优先推荐中。

我希望你喜欢这篇文章,我很乐意在推特上与你联系。如果你想深入这篇文章背后的代码,所有这些都可以在的公共知识库中找到。

脚注

[1]该场景基于驱动数据描述的情况。分析使用由驱动数据提供的数据。

[2]每个地点的人口在 0,1 的范围内缩放,与预测的概率大小相同。

[3]根据经度和纬度,使用 KMeans 估计量,通过创建 5 个聚类来确定距离。这五个集群各自“代表”该部门维修水泵的一名可用工人。然后,从每个地点所属的质心的纬度和经度中减去该地点的纬度和经度。然后计算该位置坐标和质心坐标之间差值的绝对值的平均值。最后,该值在范围 0,1 内进行缩放,与预测概率的大小相同。

机器学习基础(二)

原文:https://towardsdatascience.com/maximum-likelihood-estimation-984af2dcfcac?source=collection_archive---------6-----------------------

最大似然估计

这是我认为机器学习基础的一系列主题的第二部分。第一部分介绍了概率论,我们将在这篇文章中重点介绍它。如果您需要复习概率,请查看第一部分:

[## 概率——机器学习的基础(第一部分)

机器学习所需的概率论概念概述

towardsdatascience.com](/probability-fundamentals-of-machine-learning-part-1-a156b4703e69)

介绍

最大似然估计 (MLE)是一种在给定一些观测数据的情况下估计模型参数的频率主义方法。使用 MLE 的一般方法是:

  1. 观察一些数据。
  2. 写下我们认为数据是如何产生的模型。
  3. 将我们模型的参数设置为在给定数据的情况下最大化参数可能性的值。

我们将涵盖创建模型、理解似然性以及使用最大似然估计过程来拟合参数的基础知识。

模型

一个模型是我们对一些事件或过程的信念、假设和简化的正式表示。让我们看几个例子来阐明这个观点。

示例:抛硬币

我们想要建立一个投掷特定硬币的模型。我们知道些什么?

  • 硬币有两面和一条边。
  • 这些面有不同的设计。
  • 硬币可以放在正面或边缘(见下图,硬币放在边缘)。
  • 硬币的重量。
  • 硬币的直径和厚度。

Photo by Ryan Thomas Ang on Unsplash

我们可以做出什么样的假设?

  • 不同的设计可能导致硬币的重心稍微偏向一边。
  • 没有办法测量硬币翻转时受到的力或角度。

让我们先试着写下一个没有简化的模型:

  • 硬币的初始位置来自伯努利分布。这代表脚蹼手更喜欢开始时硬币正面朝上,而不是正面朝下。
  • 施加在硬币上的力是按指数分布的。
  • 力施加的角度是从区间[-π,π]上的截尾正态分布画出的。
  • 硬币的质心在一个以硬币中心为原点的系统中的某个坐标(x,y,z)上。
  • 重力是…好了,我想你明白了。

现实世界可能很复杂。有时候,一个简化的模型可以做得一样好或者更好。让我们做一个简化的模型:

  • 掷硬币的结果来自伯努利分布,正面概率为 p ,反面概率为(1- p )。

我们的简化模型只有一个参数!在第一部分中,我们了解到,我们可以通过简单地抛几次硬币并计算得到的人头数来估计这个参数。拟合复杂的模型需要更多的翻转和困难的计算。那么哪个模型是对的呢?我最喜欢引用乔治·博克斯的话:

“所有的模型都是错的,但有些是有用的。”

有用性是设计模型时的关键指标。在这种情况下,我宁愿使用简化模型,尽管我知道它是错误的。我怎么知道这是错的?我给硬币边缘着地的概率赋值为 0。我从未在现实生活中见过这种情况,所以我做了一个简单的假设,认为这种情况不会发生。

示例:线性模型

在本例中,我们将使用上图。我们希望建立一个数据模型,以便在给定 x 的情况下预测 y 的未来值。数据看起来几乎像一条线,所以让我们从它开始作为我们的模型。

Equation of a line.

如果潜在的关系实际上是线性的,我们如何解释我们观察到的偏差?想象一下,我们正在使用一个传感器来收集这些数据。大多数传感器的测量都有一定的误差。类似地,我们可以认为与模型的偏差是由易出错的传感器引起的。通常将误差建模为均值为零、方差为σ的高斯分布。平均值为零会将误差平均分布在线的两侧。方差越大,偏差越大。让我们在模型中加入一个高斯噪声项。得到的模型有三个参数:高斯的斜率、截距和方差。

Linear model with Gaussian error.

可能性

在这两个例子中,我们根据一些参数写下了我们的模型。一般来说,我们可能有任意数量的参数,所以让我们将它们的整个集合称为 θ (theta)。我们怎么知道 θ 的值应该是多少?这就是可能性发挥作用的地方。在第一部分中,我们讨论了连续随机变量取特定值的可能性。我们从参数固定在某个值的分布的概率密度函数(PDF)中得到这种可能性。给定我们观察到的数据,让我们将可能性视为 θ 的函数,而不是固定参数。对于 PDFf(x|θ)的连续分布,似然函数变为:

类似地,对于具有概率质量函数(PMF) P( x | θ )的离散分布,似然函数变为:

我们通常有不止一个数据点来为我们的决策提供信息。我们如何计算整个数据集合 X 的可能性?让我们看一下典型的情况,数据是独立同分布的( iid )。同分布意味着每个数据点来自具有相同参数的相同分布。第一部分介绍了独立性,这意味着对于任意两个数据点 xy ,P( x,y)= P(x)P(y)。抛硬币是 iid 数据的一个很好的例子。每一次翻转都使用相同的硬币,并且翻转的结果与之前的翻转无关。对于 iid X,我们将似然函数重写为:

Likelihood is the product of probability density for each data point.

请注意似然函数中的乘积运算符。很多时候,个体可能性是非常小的数字。取小数字的乘积会产生更小的数字,计算机很难用有限的精度来表示这些数字。为了缓解这些数字问题(以及后面提到的其他便利),我们经常使用似然函数的对数,恰当地命名为对数似然。为什么记录日志会有帮助?对数的乘积法则说 log(x⋅y) = log(x) + log(y)。所以取对数就把我们的乘积变成了总和!对数似然可以写成:

Log-likelihood is the sum over the log of the likelihood for each point.

对数也是单调的,这意味着更大的输入产生更大的输出。因此,对数似然函数的最大值将出现在与似然函数的最大值相同的位置。许多概率分布被写成指数形式或包含指数。对数和指数相互抵消,对数允许我们将指数转化为乘积。这两者都留给我们更简单的方程来最大化。

最大概似法

你可能已经把这些碎片拼在一起了,但是让我们再一次回顾我们的目标。我们可以根据概率分布为我们的数据写一个模型。接下来,我们可以在模型的参数上写下一个函数,该函数输出这些参数生成我们的数据的可能性(或对数可能性)。MLE 的目的是找到该函数的最大值,即最有可能产生观察数据的参数。

假设我们有一些从方差为 4 的高斯分布生成的数据,但是我们不知道平均值。我喜欢把最大似然法想象成取高斯,在所有可能的平均值上滑动,并选择使模型最适合数据的平均值。我在下面创建了这个过程的可视化,我们看到对数似然的最大值出现在平均值为 2 处。事实上,这是创建直方图的分布的真实平均值!

我们如何用数学方法来完成这个过程?如果你熟悉微积分,你会知道你可以通过求导并设置它等于 0 来找到一个函数的最大值。函数的导数代表原函数的变化率。如果你看上面的对数似然曲线,我们会发现最初它是正向变化的(向上移动)。它达到一个峰值,然后开始向负方向变化(向下移动)。关键是在峰值时,变化率为 0。因此,如果我们知道导数的函数形式,我们可以将它设为 0,并求解最佳参数。

抛硬币 MLE

让我们从之前的抛硬币模型中推导出 MLE 估计量。我将在以后关于线性回归的文章中讨论线性模型的 MLE 估计量。

回想一下,我们通过伯努利分布来模拟抛硬币的结果,其中参数 p 代表获得正面的概率。首先,让我们写下单次翻转的可能性函数:

Likelihood function for Bernoulli distribution.

我已经用数学上方便的方式写出了伯努利分布的概率质量函数。花一秒钟自己验证一下,当 x =1(正面)时,概率是 p ,当 x =0(反面)时,概率是(1-p)。

现在,让我们假设我们看到下面的翻转序列:

X =正面,正面,反面,正面,反面,反面,反面,正面,反面,反面。

因为掷硬币是 iid 的,我们可以把看到一个特定序列的可能性写成每一次单独掷硬币的乘积:

Likelihood of a sequence of flips.

插入我们的数据,我们得到:

l(p)=pp⋅(1-p)⋅p⋅(1-p)⋅(1-p)⋅(1-p)⋅p⋅(1-p【1

注意,对于每个正面,我们得到一个因子 p ,对于每个反面,我们得到一个因子(1- p )。让我们把这个归纳为用 h 正面掷硬币:

Likelihood for n coin flips with h heads.

我们想找到最大化这个函数的 p 。为了使我们的工作容易些,让我们把双方的情况都记录下来。这将降低指数,并将乘积转化为总和。求和的导数比求积更容易(对数似然的另一个便利之处)。记住,我们可以这样做,因为最大化对数似然的 p 与最大化似然的 p 是相同的。我们的对数可能性是:

Log-likelihood of n coin flips with h heads.

为了找到最大值,我们要对这个函数相对于 p 求导。如果你对微积分不太熟悉,重要的是你知道导数是函数的变化率。在这种情况下,导数是:

Derivative of the log-likelihood with respect to p.

我们将导数设置为 0,以找到函数的最大值(其中变化率为 0)。设上面的等式等于 0,求解 p (自己试试)给我们:

The MLE estimate of p is the number of heads divided by the number of flips!

事实证明,我们硬币的最大似然估计就是正面数除以翻转数!这非常直观,如果你掷一枚公平硬币( p = 0.5) 100 次,你会得到大约 50 个正面和 50 个反面。

结论

最大似然估计是一种将我们的模型与数据拟合的强大技术。MLE 提供的解决方案通常非常直观,但它们完全由数据驱动。这意味着,我们拥有的数据越多,我们的解决方案就越精确,反之亦然。在以后的文章中,我们将会看到包含我们先前对模型的信念的方法,这将在低数据情况下帮助我们。

准备好第三部分了吗?:

[## 机器学习基础(三)

信息论

towardsdatascience.com](/fundamentals-of-machine-learning-part-3-b305933f00cd)

下次见!

最大似然估计解释-正态分布

原文:https://towardsdatascience.com/maximum-likelihood-estimation-explained-normal-distribution-6207b322e47f?source=collection_archive---------1-----------------------

维基百科对最大似然估计(MLE)的定义如下:

通过最大化似然函数来估计分布参数的一种方法,使得在假设的统计模型下观察到的数据是最可能的。

为了理解这个定义,让我们看一个简单的例子。假设我们有一些连续的数据,我们假设它是正态分布的。通过假设正态性,我们简单地假设我们的数据分布的形状符合流行的高斯钟形曲线。我们不知道的是曲线有多“粗”或“细”,或者峰值出现在 x 轴的什么位置。

We assumed the general Gaussian bell curve shape, but we have to infer the parameters which determine the location of the curve along the x-axis, as well as the “fatness” of the curve. Our data distribution could look like any of these curves. MLE tells us which curve has the highest likelihood of fitting our data.

这就是估计或推断参数的地方。从统计学上我们知道,我们的高斯分布的具体形状和位置分别来自于 σμ 。换句话说,μ和σ是我们感兴趣的参数。这两个参数定义了我们的曲线,正如我们看到的正态分布概率密度函数(PDF)一样:

我们如何使用 MLE?

仍然记住我们的正态分布示例,目标是确定我们数据的μ和σ,以便我们可以将我们的数据与其最有可能的高斯钟形曲线相匹配。用我们的语言来说,技术上是正确的,我们可以说,我们正在寻找一条曲线,在给定一组曲线参数的情况下,使我们的数据的概率最大化。换句话说,我们最大化数据的概率,同时最大化曲线可能性。也许后一种解释是更直观的思考问题的方式,但两者都是正确的,我们将使用第一种视角来处理问题。

为了使用最大似然估计,我们必须做出两个重要的假设,它们通常一起被称为 i.i.d. 假设。这些假设表明:

  1. 数据必须独立分布。
  2. 数据必须完全相同地分布。

换句话说, i.i.d. 假设要求任何给定数据点的观察不依赖于任何其他数据点的观察(每个收集的数据点都是独立的实验),并且每个数据点都是从具有相同参数的相同分布族中产生的。

数学

通常,参数μ和σ一起表示为一组参数θ,即:

我们可以将问题建立为条件概率问题,其目标是在给定θ的情况下最大化观察到我们的数据的概率。对于大小为 n 的数据集,从数学上来说,它看起来类似于:

然而,因为我们正在处理一个连续的概率分布,上述符号在技术上是不正确的,因为观察到任何一组连续变量的概率都等于零。从概念上讲,这是有意义的,因为我们可以在连续域中得出无限多的可能变量,并且将任何给定的观测值除以无穷大总会得到零概率,不管观测值是什么。

我们需要考虑概率密度而不是概率。不去探究两者之间区别的技术细节,我们将只陈述连续域中的概率密度类似于离散域中的概率。因此,在这个最大化问题中可以使用概率密度。为了纠正我们的符号,我们会说:

我们希望将观察数据的概率密度最大化为θ的函数。换句话说,我们希望找到μ和σ值,使得这个概率密度项尽可能高。我们习惯于将 x 作为约定俗成的自变量。但在这种情况下,我们实际上是把θ作为独立变量,我们可以把 x_1,x_2,… x_n 看作一个常数,因为这是我们观察到的数据,不能改变。

从概率论中,我们知道多个独立事件全部发生的概率称为联合概率。我们可以将每个数据点观察视为一个单一事件;因此,我们可以将我们的精确数据集的观察视为一系列事件,并且我们可以如下应用联合概率密度:

记住,目标是通过找到最优θ来最大化这个概率密度项。为了用数学方法表示这一点,我们可以说,我们寻求这一项相对于θ的“argmax ”:

因为我们在寻找一个最大值,我们的微积分直觉应该告诉我们是时候对θ求导,并将这个导数项设置为零,以找到我们沿着θ轴的峰值位置。这样,我们可以将联合概率密度项的 argmax 等同于联合概率密度项对θ的导数等于零时的情形,如下所示:

现在,唯一的问题是,这不是一个很容易计算或近似的导数。幸运的是,我们可以在这个场景中应用一个简单的数学技巧来简化我们的推导。实际上,我们可以使用单调函数来改变导数项,这将简化导数计算,而不会改变最终结果。单调函数是两个变量之间保持原始顺序的任何关系。单调函数要么总是增加,要么总是减少,因此,单调函数的导数永远不会改变符号。我们这里使用的单调函数是自然对数,它具有以下性质(不包括证明):

所以我们现在可以把我们的问题写成如下。请注意,下面第三项和第四项之间的等式是一个性质,其证明没有明确显示。

为什么可以使用这种自然对数的技巧?由于自然对数的单调递增性质,采用原始概率密度项的自然对数不会影响 argmax,这是我们在这里感兴趣的唯一度量。当然,它改变了我们的概率密度项的值,但它没有改变全局最大值相对于θ的位置。从数学上讲,我们可以把这个逻辑写成如下:

为了进一步说明这一概念,这里有几个函数沿着它们的自然对数(虚线)标绘,以表明沿着 x 轴的最大值的位置对于该函数和该函数的自然对数是相同的,尽管最大值本身显著不同。

垂直的黑色虚线表示函数与其自然对数之间的最大值对齐。这些线绘制在 argmax 值上。如我们所述,这些值对于函数和函数的自然对数是相同的。这就是为什么我们可以在这个问题中使用我们的自然对数技巧。

回到现在的问题,我们有:

我们希望求解θ,以获得最佳参数,使我们的观察数据与高斯曲线最佳拟合。现在让我们考虑一下我们要推断的两个参数,μ和σ,而不是符号表示θ。我们将切换到梯度符号:

让我们从求关于μ的梯度开始。我们将在这里用正态分布的 PDF 代替 f (x_i|μ,σ)来做这件事:

使用这里没有证明的自然对数的属性,我们可以将其简化为:

此外,

设最后一项等于零,我们得到μ的解如下:

我们可以看到,我们的最优μ与我们的最优σ无关。现在,我们将以类似的方式,通过对σ求梯度来求解σ:

设最后一项等于零,我们得到σ的解如下:

现在我们有了。如果我们最近做过统计,我们的最佳μ和σ导数应该看起来很熟悉。这些参数计算出的公式与我们用于平均值和标准偏差计算的公式完全相同。这不仅仅是巧合。这是正态分布的一个性质,假设我们可以进行独立同分布假设,这个性质就成立。

但是在这里理解 MLE 的关键是将μ和σ 而不是视为我们数据集的均值和标准差,而是将而不是视为最有可能拟合我们数据集的高斯曲线的参数。当我们将 MLE 应用于贝叶斯模型和分布时,这种思路将会派上用场,在贝叶斯模型和分布中,计算中心趋势和离差估计量不是那么直观。

贝叶斯定理的最大似然估计

原文:https://towardsdatascience.com/maximum-likelihood-estimation-from-bayes-theorem-6cc7f0db9adb?source=collection_archive---------13-----------------------

可能最流行和最简单的参数估计方法之一是最大似然估计,贝叶斯定理作为一个独立的天才,有许多应用。但是有没有可能把 ML(不是机器学习)看成是贝叶斯定理的一个应用呢?让我看看。

让我们用一个非常基本和简单的瓮和球选择问题来概括贝叶斯定理,这种问题是贝叶斯定理应用的第一个问题。问题陈述如下:

假设你有三个相同的罐子,里面装着相同的球。第一个瓮包含 3 个黑球和 3 个红球,第二个瓮包含 4 个黑球和 2 个红球,第三个瓮包含 1 个黑球和 5 个红球。蒙上眼睛,从三个瓮中随机选择一个,然后随机抽取一个球。让抽出的球是红色的球。那你一开始选的是哪个骨灰盒?

The setup of urn and balls

一个典型的贝叶斯定理问题。不是吗?让我们解决它。

设 A1、A2、A3 分别是选择第一、第二和第三 urn 的事件。设 B 是选择一个红球的事件。由于骨灰盒是相同的,其中一个是随机选择的,因此

P[A1]=P[A2]=P[A3] …(1)

因为只有这三个 urn,所以选择其中任何一个都是必然的,我们得到 P[A1]+P[A2]+P[A3]=1 …(2)

从(1)和(2)可以清楚地看出,P[A1]=P[A2]=P[A3]=1/3

现在 P[B | A1]= P[从 3 个红球和 3 个黑球中选择一个红球]=3/(3+3)=3/6

P[B | A2]= P[从 2 个红球和 4 个黑球中选择一个红球]=2/(2+4)=2/6

P[B | A3]= P[从 5 个红球和 1 个黑球中选择一个红球]=5/(5+1)=5/6

但是你蒙着眼睛抽了球,所以你不知道 B|A1,B|A2,B|A3 这三个事件发生了哪一个。或者具体地说,A1、A2 和 A3 中的哪一个已经实际发生。现在给定手头的附加信息,即所选球是红色的,让我们使用贝叶斯定理计算 P[A1|B],P[A2|B]和 P[A3|B]。

所以,P[A1 | B]=(P[B | A1]* P[A1]/(P[B | A1]* P[A1]+P[B | A2]* P[A2]+P[B | A3]* P[A3])

或者,P[A1 | B]=(3/6)(1/3)/[(3/6)(1/3)+(2/6)(1/3)+(5/6)(1/3)]= 3/10

同样,P[A2 | B]=(P[B | A2]* P[A2]/(P[B | A1]* P[A1]+P[B | A2]* P[A2]+P[B | A3]* P[A3])

或者,P[A2 | B]=(2/6)(1/3)/[(3/6)(1/3)+(2/6)(1/3)+(5/6)(1/3)]= 2/10

最后,

P[A3 | B]=(P[B | A3]* P[A3])/(P[B | A1]* P[A1]+P[B | A2]* P[A2]+P[B | A3]* P[A3])

或者,P[A3 | B]=(5/6)(1/3)/[(3/6)(1/3)+(2/6)(1/3)+(5/6)(1/3)]= 5/10

我们发现事件 A3|B 在 3 个事件中概率最高。

因此可以得出结论,最有可能的是第三个瓮被选中。这也很明显,因为第三个瓮有最多的红球。

到目前为止还好,没什么特别的,没什么有趣的。

让我们集中注意力。

我们为什么不按照时间顺序来安排与问题相关的不同行动呢?我们去吧。

Time wise ordering of actions

这个简单问题的主要吸引力在于,在状态 C 中,你必须猜测在状态 a 中发生了什么。蒙住眼睛发生的动作实际上对你来说是未知的。所以基本上这是一个根据手头的数据(球的颜色)知道所选的未知骨灰盒的过程。

让我们停止贝叶斯问题,转到统计推断。什么是统计推断?是认识未知的过程。比如:估计一个总体的一些参数。那么什么是参数呢?描述一个群体并且对我们来说未知的感兴趣的量。那么我们如何估计参数呢?有几种方法可以做到这一点(一种这样的方法是最大似然估计或 MLE),但对于每一种这样的方法,你至少需要一个样本。样本只不过是你所知道的总体的一部分。

现在让我们把注意力集中到 MLE 上。MLE 的下划线理论是什么?给定手头的样本,下划线参数的估计值是多少,以使观察到的样本最有可能获得,即获得给定样本的可能性最大。

不是 ML 估计也是时光倒流吧?因为群体是由一些参数指定的。当从总体中选择样本时,样本是由于一个或多个参数而生成的,但不幸的是,您并不了解它,因此需要基于生成的样本来获取关于它的知识。

找到与贝叶斯问题的相似之处?我希望如此。让我们处理一个简单的最大似然估计问题。

假设你有一个样本 X1,X2,X3,X4 和 X5 be 5 iid 观测值(抽球)来自一个 N(t,1)分布(某瓮)t 未知(但是哪个瓮,你不知道)。基于样本的给定值(所选球的颜色)提供 t 的最大似然估计值(哪个瓮最有可能包含所选球)。

上面给出了一个真正的 ML 估计问题。但是让我们再次解决瓮和球的问题,唯一的区别是现在有无限多个瓮,因为 t 可以取-无穷大到+无穷大之间的任何值。

设 B 是已经产生给定的 5 个观察样本的事件。

因为 t 可以取无穷多个值,并且它们是不可数的无穷个,所以我们不能定义 A1 是事先选择 N(t1,1)的事件,A2 是事先选择 N(t2,1)的事件,等等。取而代之,让我们定义一个 t 的连续分布,因为所有的正态分布都被假定为是等可能性的,所以概率陈述是

对于所有允许的 t 值,f(t)=c。

并且 T 是选择 N(t,1)的事件。

现在类似于球和瓮的问题,我们需要找到

P[T|B],然后推断出 P[T|B]最大的特定 T。

根据贝叶斯定理,

P[T | B]= P[T]* P[T]/P[B]…..(*)

我们有,

由于这里的 t 既不是有限的,也不是不可数无限的,所以在 P[B]通过全概率定理的表达式中,用积分代替求和。

所以,

因此从(*),

显然,分母是一个常数,因为它不含 t,并且手头的样本是固定的。

所以要找到使 P[T|B]最大化的 T,数学公式是

但实际上是什么呢?不就是 ML 估计的提法吗?是的,的确如此。(我知道我们通常最大化对数似然,但这仅仅是出于计算目的)。

答对了。!!

一开始,在真正的瓮和球问题中,假设每个瓮被选中的可能性是相等的,因此答案将是拥有最多红色球的瓮?同样的假设在 MLE 中是有效的。但是如果骨灰盒被选中的概率不同呢?然后仅仅通过看球的颜色,你不能给出任何解决方案。

类似地,在参数估计中,如果你预先假设参数的分布对于参数的所有允许值都不是常数,那么仅仅通过观察手头的样本,你不能得出关于参数估计值的结论。

在统计学或机器学习领域,贝叶斯方法起着非常重要的作用,而所有这些方法的基础都是贝叶斯定理。这个定理非常简单容易。那它有什么特别的?我的意思是用条件概率规则,P[A|B]=P[A 和 B]/P[B]

类似地,P[B|A]= P[A 和 B]/P[A],因此 P[A 和 B]=P[B|A]*P[A]

替换上式中的,P[A|B]=P[B|A]*P[A]/P[B]。就是这样。这只是一些条件概率的数学公式。

但是这个定理的美妙之处在于,你是,实际上在改变一个确定事件的概率。什么是确定的事件?如果 P[A]=1,则调用 A 的事件是确定事件。任何已经发生的事件都是确定的事件。2014 年国际足联 WC 德国夺冠的概率有多大?是 1。当你掷两次 6 面无偏骰子,第一次输出是 5,第二次输出是 1 的概率是多少?答案是(1/6)*(1/6)=1/36。但是当你掷两次 6 面无偏骰子,第一次输出是 5,第二次输出是 1 的概率是多少?答案是 1/6,因为 P[第一个输出是 5]=1,因为它已经发生了。

现在想想,在骨灰盒问题中,你已经选择了一个骨灰盒,所以它是一个确定的事件。P[B|A1]=1 或 P[B|A2]=1 或 P[B|A3]=1 中的任何一个必须为真。但是因为你不知道是哪一个,这个定理实际上允许你回到过去并且弄清楚。

因此,这个定理在统计学上是一个独立的天才,因为它提供的突破性思想是无与伦比的。

感谢您的阅读,任何批评或反馈都欢迎在评论区,或者您可以通过我的 LinkedIn 个人资料联系我

[## SOUMALYA NANDI -联合健康组织助理数据科学家| LinkedIn

查看 SOUMALYA NANDI 在全球最大的职业社区 LinkedIn 上的个人资料。SOUMALYA 有 4 份工作列在…

www.linkedin.com](https://www.linkedin.com/in/soumalya-nandi-95176569/)

现实生活中的最大似然估计:优化学习时间

原文:https://towardsdatascience.com/maximum-likelihood-estimation-in-real-life-optimizing-study-time-d5cc083d25b4?source=collection_archive---------15-----------------------

Photo by Mika Baumeister on Unsplash

最大似然估计是一种广泛应用于机器学习的统计技术。它用于选择模型的参数。

考试季节到了,这一次你想更有效地利用你的学习时间。你提前做了计划,并确保跟踪你在过去几轮中为每场考试学习了多少,以及你得了多少分。你最终得到了这个数据集

Beautiful dummy data 😁

绘制数据可以更容易地看出你花在考试学习上的时间和最终成绩之间的相关性。

和前几轮考试一样,你面临的最大挑战是,你有多场考试,每场考试相隔几天。你想制定一个学习计划,让你最大限度地提高成绩,但保证你有足够的时间投入到每场考试中。

你是做什么的?

线性模型来救援了!

根据每次考试的学习时间,思考一种最大化成绩的方法,你记得上面散点图中的相关性。你可以使用线性回归来帮助计算出你会得到多少分数,给定你可以为考试投入的学习时间。

这是最能描述当前问题的模型

你是根据你学习的时间来预测考试成绩的。你可以使用自己选择的统计软件,对数据集进行线性模型拟合。

现在你可以输入你计划学习多长时间,并根据模型的方程式检查你可能获得的分数。

这里是我们模型的总结,使用 Python 的 statsmodels 模块获得。

我们可以看到,最小二乘法用于将模型(粉色线)拟合到数据集。参数β0β1,也称为模型的系数,分别对应于 consttime

因此,我们有了模型,并用 Python 计算了参数,但问题仍然存在:我们实际上是如何估计参数的?

幕后的数学

很棒的是,我们可以使用统计软件来完成所有繁重的工作,并为我们的数据集拟合一个线性模型。

但是参数是怎么得到预估的呢?

这些值是随机选取的吗?

这就是统计学家 R. A .菲舍尔想出一个好主意的地方!他发现,我们可以建立一个模型,然后估计参数,使它们最大化获得数据集中观察到的值的可能性。

换句话说,我们正在估计参数,以使观察到数据集中的值的概率(即可能性)尽可能高。

但在我们开始钻研数学之前,这里有一些关于我们数据集的假设:

  • 每个数据点都是独立的
  • 我们的数据集遵循正态分布
  • 我们模型中的误差也遵循正态分布
  • 我们的产出是连续的

在计算参数时,这些假设非常方便。它们促进了某些数学属性的使用,最终简化了计算!

1.解码似然函数

到目前为止,我们知道参数必须最大化似然函数

可能性函数实际上是一种条件概率。它依赖于参数,因为我们将只选择最大化观察数据概率的参数值。

让我们用θ来表示参数。

我们的线性模型,有两个未知参数—β0,β1

所以我们可以将似然函数改写为

迄今为止,我们

  • 解读可能性的含义
  • 写下线性模型的可能性表达式,作为条件概率

2.概率密度函数

现在我们知道可能性是一个条件概率,是时候开始深入数学了。

根据我们的假设,我们的数据集遵循正态分布,我们正在处理连续数据。因此,我们将使用正态分布的概率密度函数来定义可能性。

因为每个数据点都是相互独立的,所以通过使用概率密度函数中的 Pi 符号,数据集中所有点的概率被表示为乘积。

为了简化即将到来的计算,我们可以将可能性转化为对数可能性。

当选择每个参数的值时,这是我们想要最大化的!

但是我们可以让这个表达式更简单。由于我们最大化了与参数 beta 0beta 1 相关的可能性,我们实际上可以忽略其中不包含 beta 0beta 1 的任何术语。

可能性表达式就变成了

这个求和看起来眼熟吗?

大家回想一下,我们的线性模型定义为 y = beta0 + beta1x +误差。如果我们求解这个误差方程,我们得到误差= y-β0-β1。

以上是 误差平方和

而且,因为我们也假设我们模型中的误差遵循正态分布,在这种情况下使用最大似然法进行参数估计与计算普通最小二乘法完全相同!

在实践中,在这些假设下,最大化可能性与最小化误差平方和是相同的。

这就是为什么大多数时候我们会看到普通的最小二乘法用于将线性模型拟合到数据集。

3.(最后)估计参数

这是我们停下来的地方

为了得到参数值,我们将计算关于β0β1 的偏导数。

从相对于β0 的偏导数开始。

搞定一个,还剩一个!

计算关于β1的偏导数,我们得到

每当我们使用一些统计软件将线性模型拟合到我们的数据集时,这些都是在幕后发生的计算。

如果我们计算数据集的每个表达式,我们将确认 beta 0= 37.4571beta 1= 12.0495 ,这是模型摘要中显示的确切值。

感谢阅读!

五月版:数据科学职业

原文:https://towardsdatascience.com/may-edition-careers-in-data-science-ae4a955e515f?source=collection_archive---------17-----------------------

自《哈佛商业评论》宣布数据科学家是“21 世纪最性感的工作”以来,已经过去了将近九年。从那时起,数据科学领域作为一个整体已经迅速成熟。这些发展中值得注意的是在职业生涯中,从数据科学训练营的兴起到数据科学的本科课程。

因此,进入数据科学领域变得非常困难,因为竞争非常激烈,随之而来的是手头职位的技术要求很高。但是不要害怕,因为 TDS 就在你身边。我们收集了八篇优秀的文章,涉及广泛的数据科学职业生涯的不同方面,既有利于数据科学的有志之士,也有利于已经在该领域工作但希望了解更多未来轨迹的人。我们希望这些文章能进一步告诉你在数据行业实现职业生涯的正确方向。

Haebichan Jung——Recurly 的编辑助理/数据科学家

没人会告诉你的数据科学工作申请

由爱德华·哈里斯 — 6 分钟阅读

我是一名物理学家,在 YC 的一家初创公司工作。由于我们公司的工作,我收到了许多电子邮件,询问我关于数据科学职业的建议。

如何在你梦想的公司找到一份数据科学家的工作——我的 Airbnb 之旅

由凯利彭 — 8 分钟读完

我一个月前刚开始在 Airbnb 的新工作,是一名数据科学家,我仍然觉得我在这里太幸运了。

如何构建数据科学组合

由迈克尔·加拉尼克 — 17 分钟读完

数据科学怎么找工作?了解足够的统计学、机器学习、编程等知识以便能够找到工作是很困难的。我最近发现的一件事是,相当多的人可能拥有找工作所需的技能,但没有作品集。

绿角数据科学家的 5 大错误

由简·扎瓦日基 — 6 分钟阅读
你狂学在线课程,并获得了你的第一份数据科学工作。避免这些错误,马上就能成功。

掌握数据科学面试循环

安德烈·里斯科夫——12 分钟阅读

2012 年,《哈佛商业评论》宣布,数据科学将是 21 世纪最性感的工作。从那以后,围绕数据科学的炒作只增不减。最近的报告显示,对数据科学家的需求远远超过供应。

理想的数据科学家的个人资料是什么样的?

由乔治刘 — 6 分钟读完

如果你是一名数据科学求职者,你一定一直在想应该在简历上写些什么技能才能接到电话;如果你想进入这个领域,你可能已经挠了很多次头,想知道学习哪些技术才能成为一个有吸引力的候选人。

给有抱负的数据科学家的六条建议

通过本·韦伯 — 6 分钟读取

数据科学是一个需求巨大的领域,部分原因是它似乎需要作为数据科学家的经验才能被聘为数据科学家。但我合作过的许多最优秀的数据科学家都有从人文科学到神经科学的不同背景,要脱颖而出需要经验。

我们也感谢最近加入我们的所有伟大的新作家,夏羽·比洛多,莱·奎弗莱克,杰弗里·石,安东尼奥·德·佩里奥,亚历山大·什罗普希尔,纳西尔·赫梅德,斯蒂芬·福特汉姆,诺姆·尼默,达西·里德,贝蒂·罗德里格斯 特伦特·戴尔奥罗,尼尔·钱德拉纳,拉塔纳·普克迪,亚当·迪克,肖·卢,郝明·宁,阿内·贝拉萨蒂吉等等。 我们邀请你看看他们的简介,看看他们的工作。

从 MBA 到 IBM 数据科学家:格雷格·拉弗蒂专访

原文:https://towardsdatascience.com/mba-to-ibm-data-scientist-exclusive-interview-with-greg-rafferty-8eebdc689c05?source=collection_archive---------9-----------------------

独家 TDS 采访

TDS 与 IBM 的首席数据科学家讨论公司的工作流程、内部 NLP 项目以及获得第一份数据科学工作。

TLDR: TDS 采访了 IBM 首席数据科学家 Greg Rafferty。Greg 深入研究了 IBM 的数据科学工作流,他负责的具体项目类型,以及他在 TDS 上写的 TwitterBot 文章,这篇文章让他获得了 NLP 专家的声誉,这在他获得 IBM 职位的过程中发挥了很小的作用。

面试官:Haebichan Jung,Recurly 数据科学家,TowardsDataScience.com 编辑助理**

受访者:Greg raff erty,IBM 首席数据科学家**

专注于你以前在国际领域的工作,你能告诉我们你在国外做了什么吗?

格雷格:我大部分时间都在为美国政府做援助工作。我在亚美尼亚生活了几年,在俄罗斯生活了几年。最初它不是数据科学。我主要做项目管理。我在清洁能源项目中工作。我有机械工程的背景,所以我在这些项目上做了一点机械工程。但主要是管理。在亚美尼亚呆了几年后,我去了俄罗斯,继续我的工作。后来,我在一家初创公司做商业分析师。那是我进入科技行业的时候。之后,我来到旧金山,进入了数据科学领域。

最初是什么让你想到了我们的亚美尼亚和俄罗斯?这些是你感兴趣的地区吗?

这既是个人的也是职业的。我提到过我以前是机械工程师。我在采矿业工作,我们在俄罗斯有几个客户,所以我和他们一起工作,为了更好地交流,我开始学习语言。当我获得工商管理硕士学位时,我们与圣彼得堡州立大学有一所姐妹学校。所以我有了一个很好的机会去那里上课。我在圣彼得堡呆了几个月,我喜欢那里,所以我的职业生涯开始与俄罗斯和前苏联国家建立这种势头。2008 年经济崩溃时,我有机会去了亚美尼亚,与政府合作这些援助项目。我真的很想尝试一下,这是一个很好的时机,我做到了。

你在 1990 年开始是一名机械工程师,那么你是如何进入商界的呢?这是一个艰难的转变吗?

实际上非常顺利。我最初是一名机械工程师,后来我开始从事人事管理方面的项目工作,当时我的想法是继续在这家公司工作,并领导一些海外合资企业。在这家公司,他们有各自的 MBA,所以我通过这家公司获得了我的 MBA 学位。

他们实际上支持我,所以我在攻读 MBA 的同时继续工作,这很有回报,但也很紧张。全职在校期间有一份全职工作。这是一个两年的问题,做得很好,度过了一段美好的时光。当我完成的时候,经济正在崩溃,在这家公司做经理的机会真的很少,至少在接下来的几年里,所以这就是为什么我选择那个时间去尝试一些新的东西。

数据和分析何时成为职业生活的一部分?

作为一名工程师,我使用大量的数据和分析。我会建立简单的回归模型,但没有超越 excel。我在莫斯科为一家初创公司工作时就开始编程了。这时候我建立了我的深度模型,不是深度学习,而是可以在 excel 中处理的模型。我确实非常喜欢它。所以当我回到美国时,我的工作非常繁重,这是我第一次接触 SQL。

在那个时候,我开始研究更多的机器学习模型,我真的很喜欢它。然后,我去了训练营“激励”,以便将自己推向极限,真正学习数据科学。

什么是镀锌?

激励是一个训练营。3 个月的沉浸式课程,全日制,大约每天 8-12 小时,每周 5-6 天。只有 3 个月的时间,所以你可以真正摆脱困境,把自己推向边缘,进入数据科学。如果你有基础课程,那会很有帮助,因为它不像硕士课程那么紧张。所以你确实需要知道你会得到什么,这样你才能自己填补空白。

你是如何在 IBM 找到自己的?

所以我一直在 Coursera 平台上工作,自己研究数据科学,并在 Gallup 上做了几个项目,做了另一个非常大的项目,观察特朗普的 Twitter 流。这让我在 NLP(自然语言处理)方面有点名气。IBM 正在寻找 NLP 数据科学家。通过一些关系,我被介绍给了招聘经理,这似乎是一个非常合适的机会。我直接从 galilep 转到 IBM,在 IBM 工作了大约 18 个月。

我一直在做大量的人工智能工作,大量的 NLP 工作,以及一些基于客户的基本分析工作。我是一个咨询团队的成员,所以我经常出差,并且只和客户打交道。我做的很多工作都是和一个客户一起完成的。

在 IBM 你能做什么样的很酷的 NLP 项目?

我做过的最酷的项目之一,我们称之为“无监督注释”,实际上我已经申请了专利。我希望能通过。它所做的是收集成千上万的文档,并识别这些文档的内容。它对它们进行聚类,并对这些注释应用注释,这样您就可以围绕它们构建一个知识图表。

IBM 有一个名为 Knowledge Studio 的工具,这是一个手动注释过程,大约需要三周时间来建立一个手动注释模型。那是非常劳动密集的,不是有趣的工作,需要一个领域专家来做。所以你必须让一个律师给这些文件做三个星期的注释,这真的不是一个很好的时间利用。

所以这个工具做的是,我用 Word2Vec,我用聚类,然后我用一些 IBM Watson API 的特征提取工具。通过这个管道,它创建这些注释。它获取这些文档,并在知识工作室中创建这个知识图表。那是我参与的最大的项目。

** [## 单词嵌入和 Word2Vec 简介

单词嵌入是最流行的文档词汇表示之一。它能够捕捉…的上下文

towardsdatascience.com](/introduction-to-word-embedding-and-word2vec-652d0c2060fa)

这是你为 IBM 开发的内部软件,而不是为其他公司开发的咨询工作吗?

正确。这个项目是内部项目。我们正在寻找可能想要使用它的客户,如果我们能找到一个,那么我们当然会将其应用到我们更广泛的沃森产品中,然后提供给任何人。但目前它仍处于概念验证阶段。

这是 IBM 的正常工作流程吗(制造内部产品,然后吸引外部客户)?

那实际上是一个非常罕见的工作流程。只有少数团队使用这种方法将产品推向市场。大多数情况下,客户提出用例,IBM 确定解决方案,然后直接为客户构建解决方案。如果这个用例可以扩展到其他客户,那么每个合同都是不同的。有时客户拥有知识产权,有时 IBM 拥有,有时有一些共享。但如果 IBM 保持对知识产权的控制,那么我们将为一个客户构建它,但如果它适用于其他用例,我们将围绕其他客户销售它。

这些项目的时间表是什么?

我参与的一些项目只有一周,而有些项目可能长达数年。我做过的最长的项目大概有六个月。我现在正在做的项目是一个我们有两年合同的项目。我不知道我是否会全职参与这个项目,因为有很多不同的工作流,根据你的技能,不同的顾问会加入或离开来填补空缺。但我知道有些顾问做同一个项目做了 12 年。有各种不同类型的项目,不同的安排。这取决于你的技能。

团队是如何组建的?

我的团队,应用人工智能团队,我们经常一起工作,但有时我们会在不同的项目上完全独立地工作。我现在正在做的项目,实际上是我在领导这个团队。由我来决定是否出租。我在印度有三名离岸数据科学家,还有两名本地的岸上数据科学家。对于离岸公司,我想雇用我认识的人。我已经知道了他们技能的名声,所以我带了两个人去我的团队。

执行手头任务的重要特质/技能是什么?

作为一名数据科学家,有各种各样的技能,具体的数据科学技能取决于项目。这可以是从 NLP 到深度学习的任何东西,也可以只是基本的分析。但是 IBM 的每个人都有一个共同点,那就是他们都是顾问。他们需要能够与客户合作。他们需要与高管开会,并能够明智地讨论解决方案。他们需要销售产品。这不是向客户推销解决方案。了解客户的需求,了解我们如何更好地帮助客户。所以当我说卖的时候,这不是我们去找他们说你需要买这个的地方。但是我们深刻理解他们需要什么,以及我们如何改进他们。这不是真正的积极销售。这更像是被动销售,我们向他们展示价值,他们说他们想要。这是一项对顾问来说非常有价值的技能。

所以软硬技能都很重要。

你提起那件事很有趣。昨晚,我和我们的一个合伙人就此进行了一次谈话。他说,如果你是技术技能组合中的前百分之一,你将成为 IBM 的摇滚明星。如果你在以客户为中心的软技能中名列前茅,你也会成为摇滚明星。但是如果你不在前 1%,那么你真的需要具备这两种技能。所以大多数人确实需要有一套基于客户的技术技能。

切换齿轮,你能告诉我们更多关于你在 TDS 上写的 TwitterBot 吗?

这个想法是在川普刚刚解雇詹姆斯·科米的时候产生的。他解雇了他他在推特上说,很遗憾他不得不解雇迈克·弗林,因为弗林向联邦调查局撒谎。每个人都站出来说,那会妨碍司法公正。如果你知道他对联邦调查局撒谎并要求科米不要调查。特朗普对此的反驳是,嗯,我没有写推文,是我的律师写的,是他发的。

所以我说我要做的是分析他的推特流,并试图确定谁在写这些推文,是特朗普还是他的一个助手。我可以这样做的方式是,在他担任总统之前,特朗普总是从安卓设备上发推特,而他的工作人员总是从 iPhones 上发推特。我有推特的数据,你可以看到来源。我用这个来源作为标签,建立了一个模型来确定谁在发微博。在那之后,我建造了一个 TwitterBot,它可以监听特朗普的 Twitter 流,每当他发推文时,它都会捕捉到这条推文,并将其发送给模型。然后,它会再发一条推文,说特朗普刚刚发了这条推文,我有 90%的信心,这是特朗普实际写的。之后,我在 TowardsDataScience 上写了一篇长文,讲述了我构建的功能、结果,以及我如何构建 TwitterBot 并将其投入使用。

关于推特机器人的更多信息,请查看格雷格的原帖:

[## 谁在椭圆形办公室发微博?

我如何建立一个机器学习模型来预测特朗普或他的一个助手是否通过他的账户发了推文

towardsdatascience.com](/whos-tweeting-from-the-oval-office-96ea5b60c03)

对于 TDS 社区,尤其是那些从商业分析、管理等领域转型的人,你有什么至理名言或建议??

我会说最重要的事情,尤其是如果你正在寻找你的第一份工作,是获得一个 Github 页面,并在其中填充真正有趣的项目。项目可能与公司没有直接关系,但你却迫不及待地想要告诉人们。这种热情真的会在面试中表现出来。这是我在面试人时寻找的关键因素之一。建立关系网,然后写博客也很有帮助,因为这真的显示了你的热情。确保你做的每一件事都体现了这一点。

再次感谢 Greg Rafferty 的采访。你可以在这里找到他的 TDS 帖子:

[## Greg Rafferty -走向数据科学

阅读 Greg Rafferty 在《走向数据科学》中的文章。我比烤肉酱还大胆。每天,格雷格·拉弗蒂和…

towardsdatascience.com](https://towardsdatascience.com/@raffg) [## Haebichan Jung - Medium

阅读容格在媒介上的作品。数据科学家@ Recurly |编辑助理@ TDS。每天,Haebichan…

medium.com](https://medium.com/@haebichan)

另外还要感谢卢多维克·贝尼斯坦特和YK·苏吉对项目的审核、指导和支持。**

每个人的直觉

原文:https://towardsdatascience.com/mcmc-intuition-for-everyone-5ae79fff22b1?source=collection_archive---------1-----------------------

容易吗?我试过了。

我们都曾听说过蒙特卡洛马尔可夫链。有时在阅读贝叶斯统计时。有时在使用像 Prophet 这样的工具时。

但是 MCMC 很难理解。每当我读到它,我都注意到症结通常隐藏在数学噪音的深层,不容易破译。

我不得不花很多时间去理解这个概念。

这篇博客旨在简单地解释MCMC方法,并知道它们的用处。我将在我的下一篇文章中深入探讨更多的应用。

所以让我们开始吧。

MCMC 由两项组成 蒙特卡罗马尔可夫链 。让我们一个一个地谈论个别术语。

蒙特卡洛?

Simulation

简单来说,我们可以把蒙特卡罗方法看作简单的模拟。

蒙特卡洛 方法得名于摩纳哥的蒙特卡洛赌场。许多纸牌游戏需要赢庄家的概率。

有时候,计算这种概率可能在数学上很复杂或者非常棘手。但是我们总是可以运行一个计算机模拟来多次模拟整个游戏,并且将概率视为赢的数目除以玩的游戏数目。

这就是你需要知道的蒙特卡罗方法。

没错,只是一种简单的模拟技术,名字很花哨。

马尔可夫链?

那么既然我们已经得到了 MCMC 的第一部分,我们还需要了解什么是 马尔可夫链 。但是,在跳到马尔可夫链之前,让我们先了解一点关于马尔可夫性质的知识。

假设你有一个 M 个可能状态的系统,你从一个状态跳到另一个状态。

先不要迷茫。系统的一个具体例子是天气从热到冷再到温和状态的变化。或者另一个系统可能是股票市场,它从熊市跳到牛市,再跳到停滞状态。

马尔可夫性质表示,给定一个在特定时间点处于状态Xn的过程,概率Xn+1 =k,其中 k 是该过程可以跳转到的 M 个状态中的任何一个,将仅取决于它在给定时刻处于哪个状态。而不是它是如何达到当前状态的。

从数学角度来说:

直觉上,你不关心市场到达牛市的状态顺序。下一个状态是“熊”状态的概率仅仅由市场当前处于“牛”状态的事实决定。

从实际情况来看,这也是有道理的。

如果一个过程表现出马尔可夫性质,那么它被称为马尔可夫过程。

为什么马尔可夫链很重要?

重要的是因为它的静止 分布

那么什么是平稳分布

在下面的例子中,我将通过实际计算来解释平稳分布。假设你有一个股票市场的马尔可夫过程,如下所示。

你有一个转移概率矩阵

transition Probabilities, Q

定义了从 Xi 状态到 Xj 状态的概率。在上面的转移矩阵 Q 中,

给定当前状态,下一个状态为“牛市”的概率为“牛市”=0.9

给定当前状态,下一个状态将是“熊”的概率是“牛”=0.075

诸如此类。

现在,我们从一个特定的状态开始。让我们从熊市开始。我们可以用向量的形式把自己的状态定义为【牛、熊、停滞】。所以我们的起始状态是[0,1,0]

我们可以通过将当前状态向量乘以转移矩阵来计算下一个状态的概率分布。

看看概率加起来是怎样的 1。下一个状态分布可以由下式求出

诸如此类。最终,你会到达一个稳定状态 s,在那里我们会收敛:

对于上述转移矩阵 Q,平稳分布 s 是:

您可以通过编程获得静态分布,如下所示:

Q = np.matrix([[0.9,0.075,0.025],[0.15,0.8,0.05],[0.25,0.25,0.5]])
init_s = np.matrix([[0, 1 , 0]])
epsilon =1
while epsilon>10e-9:
    next_s = np.dot(init_s,Q)
    epsilon = np.sqrt(np.sum(np.square(next_s - init_s)))
    init_s = next_sprint(init_s)
------------------------------------------------------------------
matrix([[0.62499998, 0.31250002, 0.0625    ]])

你也可以从任何其他状态开始;你会达到同样的平稳分布。 改变代码中的初始状态,如果你想看的话。

现在我们可以回答这个问题了- 为什么平稳分布很重要?

稳态分布很重要,因为它可以让你定义一个系统在随机时间的每个状态的概率。

对于这个特定的例子,你可以说 62.5%的时间市场将处于牛市状态,31.25%的时间将处于熊市,6.25%的时间将处于停滞状态。

Random Walk

直觉上,你可以把它想象成一个链条上的随机行走。 你处于一个状态,你在给定当前状态的情况下,通过看到下一个状态的概率分布来决定下一个状态。 根据节点概率,我们可能会比其他节点更频繁地访问一些节点。

这就是谷歌在早期互联网时代解决搜索问题的方式。问题是根据页面重要性对页面进行排序。谷歌用 Pagerank 算法解决了。

Google Pagerank 算法中,你可能认为一个州是一个页面,而一个页面在稳定分布中的概率是它的相对重要性。

Woah!这是很多信息,我们还没有开始讨论 MCMC 方法。如果你现在还和我在一起,我们现在可以进入正题了。

那么什么是蒙特卡罗马尔可夫链(MCMC)?

在回答这个关于 MCMC 的问题之前,我先问一个问题。我们都知道贝塔分布。我们知道它的 pdf 函数。但是我们能从这个分布中抽取一个样本吗?你能想出一个办法吗?

Think….

MCMC 为我们提供了从任意概率分布中抽样的方法。当我们想从后验分布中取样时,这是最需要的。

以上是贝叶斯定理。有时我们需要从后面取样。但是计算后验概率和归一化常数(也称为证据)容易吗?在大多数情况下,我们能够找到可能性 x 先验的函数形式。

但是我们无法计算证据(p(D))。为什么?

让我们扩大证据。

如果 H 只取 3 个值:

p(D) = p(H=H1)。p(D|H=H1) + p(H=H2)。p(D|H=H2) + p(H=H3)。H3

P(D)很容易计算。如果 H 的值是连续的呢?能不能像现在这样简单地写出来,H 可以取无穷大的值?这将是一个很难解决的积分。

我们想从后面取样,但我们想把 p(D)当作一个常数。

根据 维基百科 :

马尔可夫链蒙特卡罗 (MCMC)方法是一类基于构建以期望分布为其平稳分布的马尔可夫链,从概率分布 中进行 采样的算法。在许多步骤之后,链的状态被用作期望分布的样本。样品的质量随着步骤数的增加而提高。

所以让我们用一个例子来解释这一点:

假设我们要从 贝塔分布 中抽取样本。测试版的 PDF 为:

其中 C 是归一化常数。它实际上是α和β的一些函数,但我想说明我们并不真的需要它来从β分布中采样,所以我把它当作一个常数。

对于 Beta 版来说,这是一个有点棘手的问题。

实际上,你可能需要处理更难的分布函数,有时你不知道归一化常数。

MCMC 方法让我们的生活变得更容易,因为它为我们提供了可以创建马尔可夫链的算法,该马尔可夫链将 Beta 分布作为其平稳分布,因为我们可以从均匀分布中采样(这相对容易)。

如果我们从一个随机状态开始,并基于某种算法反复遍历下一个状态,我们将最终创建一个马尔可夫链,该马尔可夫链将贝塔分布作为其平稳分布,并且我们在很长时间后所处的状态可以用作贝塔分布的样本。

一种这样的 MCMC 算法是 Metropolis-Hastings 算法

大都会-黑斯廷斯算法

Hill Climbing

直觉:

第一,目标是什么?

直觉上,我们想要做的是在某个(凹凸不平的)表面(我们的马尔可夫链)上走来走去,以这样一种方式,我们在每个位置花费的时间量与该位置的表面高度成正比(我们需要从中采样的期望 pdf)。

例如,我们愿意在海拔 100 米的山顶上花费两倍于在附近海拔 50 米的山上花费的时间。好的一面是,即使我们不知道表面上点的绝对高度,我们也可以这样做:我们只需要知道相对高度。例如,如果一个山顶 A 的高度是山顶 B 的两倍,那么我们在 A 的时间将是在 B 的两倍。

提出新地点的方案和接受新地点的规则更复杂,但基本思想仍然是:

(1)挑选一个新的“拟定”位置;

(2)算出那个位置比你现在的位置高多少或低多少;

(3)从概率上来说,按照与地点高度成比例地花费时间的总体目标,留在原地或移动到那个地点。

MCMC 的目标是 从某种概率分布 中抽取样本,而不必知道它在任何一点的确切高度(我们不需要知道 C)。

如果正确设置了“漫游”过程,您可以确保达到这一比例(花费的时间和分布的高度之间)。

算法:

现在让我们更正式地定义这个问题。

设 s=(s1,s2,…)。sM)是期望的平稳分布。我们想创建一个具有这种平稳分布的马尔可夫链。我们从具有 M 个状态的任意马尔可夫链开始,转移矩阵为 P,因此 pij 表示从状态 I 到 j 的概率。

直觉上我们知道如何在这个马尔可夫链上徘徊,但是这个马尔可夫链并不具备所需的平稳分布。

这个链确实有一些平稳分布(这对我们没有用)

我们的目标是改变我们在这个马尔可夫链上徘徊的方式,使得这个链具有期望的平稳分布。

为此,我们:

  1. 从随机的初始状态 I 开始。
  2. 通过查看转移矩阵 p 的第 I 行中的转移概率,随机选择新的提议状态
  3. 计算称为接受概率的度量,其定义为:aij=min(sj.pji/si.pij,1)。
  4. 现在掷一枚硬币,正面朝上。如果硬币正面朝上,接受提议,即移动到下一个状态,否则拒绝提议,即停留在当前状态。
  5. 重复很长时间

很长一段时间后,这个链将会收敛,并且将会有一个稳定的分布 s。然后我们可以使用这个链的状态作为来自任何分布的样本。

在对 Beta 分布进行采样时,我们使用 PDF 的唯一时间是找到接受概率,在这种情况下,我们将 sj 除以 si,即归一化常数 C 被取消

贝塔分布的抽样:

MCMC Sampler

现在让我们继续讨论贝塔分布的抽样问题。

贝塔分布是[0,1]上的连续分布,它在[0,1]上可以有无限个状态。

让我们假设在[0,1]上具有无限状态的任意马尔可夫链 P 具有转移矩阵 P,使得 pij = pji =矩阵中的所有元素。

我们不需要矩阵 P,正如我们将在后面看到的,但我想让问题描述尽可能接近我们建议的算法。

  • 从 Unif(0,1)给定的随机初始状态 i 开始。
  • 通过查看转移矩阵 p 的第 I 行中的转移概率,随机选取一个新的提议状态。假设我们选取另一个 Unif(0,1)状态作为提议状态 j。
  • 计算一个称为接受概率的度量:

这简化为:

因为 pji=pij,并且在哪里

  • 现在扔一枚硬币,很有可能击中头部。如果问题悬而未决,接受提议,即进入下一个州,否则拒绝提议,即停留在当前州。
  • 长时间重复

代码:

理论已经讲够了,让我们继续讨论 python,来创建我们的 Beta 采样器。

让我们对照实际的β分布检查 MCMC 采样β分布的结果。

正如我们所看到的,我们的采样β值与β分布非常相似。因此,我们的 MCMC 链达到了稳定状态。

我们确实在上面的代码中创建了一个 beta 采样器,但是相同的概念普遍适用于我们想要从中采样的任何其他分布。

结论

那是一个大帖子。恭喜你走到了尽头。

本质上, MCMC 方法可能比较复杂,但是它们给了我们很大的灵活性。您可以使用 MCMC Sampling 对任何分布函数进行采样。它们通常用于在推断时对后验分布进行采样。

您也可以使用 MCMC 来 求解具有大状态空间的问题。 例如:背包问题或解密。你可以在我的下一篇博文中看到一些有趣的例子。继续收听。

您可以关注的最新、最好的资源之一是加利福尼亚大学的贝叶斯统计专业。

我将来也会写更多这样的帖子。让我知道你对这个系列的看法。在 等我,或者订阅我的 博客 了解他们。和往常一样,我欢迎反馈和建设性的批评,可以在推特@ mlwish}上找到。

参考

  1. 概率导论约瑟夫·K·布利茨坦,杰西卡·黄
  2. 维基
  3. 堆叠交换

MDLI 报告:2019 年以色列机器学习评论

原文:https://towardsdatascience.com/mdli-report-the-israeli-machine-learning-review-2019-fdc408d31454?source=collection_archive---------19-----------------------

关于以色列机器学习前景的完整报告,包括平均工资、人口统计、最常用的图书馆等。

今年,就像去年一样,我们在机器&深度学习以色列社区成员中分发了一份全面的调查。该调查针对数据科学家和相邻角色,评估专业人员的工作条件、普遍面临的挑战、流行的开发工具等。令人印象深刻的是 569 名受访者参与了今年的调查(相比去年的 225 名受访者),代表了该领域多元化的专业群体。在本报告中,我们将讨论调查结果,并为您提供由 Omri Goldstein 完成的对这些结果的深入分析。调查由两部分组成:一部分是关于个人和职业信息,另一部分是关于职业和技术事务的更多信息。

调查的中心话题之一是平均工资,这是根据受访者的经验和教育水平来衡量的。今年,我们的调查得到了不少于 402 名全职工作人员的回复——这代表了该领域的现状。

人口统计数据

在 569 名受访者中,74.1%认为自己是男性,25.3%认为自己是女性。与去年的女性比例相比,这是一个重大进步。然而,这一数字似乎是我们努力接触更多女性参与者的结果,而不是因为有更多的妇女在实地工作。此外,调查受访者的平均年龄为 32.7 岁,其中 50%在 29 至 35 岁之间:

男女之间的年龄分布没有差别,尽管与年龄有关的其他变量描绘了一幅有趣的画面。在特拉维夫,平均年龄为 30 岁,而在中央区,平均年龄为 33 岁,如下图所示:

特拉维夫是最具代表性的城市,无论是作为家庭基地还是工作目的。特拉维夫吸引了近一半居住在中心区的受访者就业,四分之一居住在海法的受访者,三分之一居住在耶路撒冷的受访者,以及略少于一半来自南区的受访者。特拉维夫也是唯一一个被调查者更经常提到的工作城市,而不是他们生活的城市。

在雇主方面,我们研究了不同类型的组织——从公司到军队。正如所料,我们最年轻的受访者为 IDF(以色列国防军)工作。平均而言,年龄最大的受访者为政府工作,年龄中位数为 36 岁,而为初创公司工作的受访者年龄中位数仅为 32 岁:

最常见的职称是数据科学家、研究员或科学家、深度学习工程师、机器学习工程师、软件开发人员、算法开发人员、分析师和 CTO。这一结果并不令人惊讶,因为该调查是针对广义上的数据科学家的,但这些结果也没有反映高科技行业的整体情况。与此同时,调查受访者最常见的学位是计算机科学(包括电子工程、软件工程和生物信息学)、工程和精确科学(数学、物理、统计和其他工程学科)、生命科学(化学、生物和脑科学)和经济学。在学位科目方面,值得注意的是,学位科目与工作岗位之间有直接联系:

计算机科学毕业生真的可以在所有工作岗位上找到,而大多数精确科学、工程和生命科学毕业生的角色是数据科学家。此外,软件工程师通常是计算机科学毕业生,数据分析师大多来自精确科学,其他职位由生命科学和经济学毕业生分享。

如果我们在 MCA(PCA 的分类姐妹程序)的帮助下将每个回答者的工作职位、教育水平和学术专长可视化到 2D 地图中,它允许我们发现以下内容。我们可以发现变量之间的以下关系:

你可以看到几个集群的形成。在左下角,经济学毕业生和数据分析师角色之间有一个链接,尽管相当多的经济学毕业生也是数据科学家。在中间,您可以看到 STEM 毕业生和数据科学家角色之间的联系。在左侧,拥有计算机科学学士学位的受访者与软件工程师和深度学习工程师角色相关联。在右上角,在一个较小的集群中,您可以找到被聘为研究人员的博士学位持有者。在中心,CTO、算法开发人员和机器学习工程师之间还有另一种轻微的联系,他们的教育水平相似,但他们有不同的学术专长。由于这一群体的多样性,他们的职称也趋于多样化。

工作和招聘

招聘行业在过去几年发生了变化,这在我们的调查结果中非常明显。像 Woo 和幸灾乐祸这样的招聘公司已经改变了求职者寻找工作的方式,尽管大多数受访者似乎没有大规模使用这些公司的服务。LinkedIn 仍然是最受欢迎的招聘网站,超过 400 名受访者表示他们使用 LinkedIn。下一个最受欢迎的策略是通过朋友和家人找工作。最后,受访者还使用我们的社区就业委员会,不到一半的受访者使用招聘机构。

工资范围

全职员工的平均工资为每月 31000 NIS(8830 美元),比去年增加了 2000 NIS(568 美元)。50%的受访者认为他们的月工资在 22,500 至 37,500 NIS(6,408 至 10,681 美元)之间,这表明存在显著差异:

今年男女平均工资的差距是 2600 NIS(740.5 美元),这意味着 8%的工资差距(与去年的数字相似)。男性平均月收入为 31500 NIS(8946 美元),而女性为 29000 NIS(8236 美元)。

研究人员和科学家的工资最高,平均月薪为 36000 NIS(10224 美元)。紧随其后的是那些拥有 CTO 或机器学习工程师头衔的人,他们的平均月薪为 3.5 万 NIS(合 9940 美元)。另一方面,分析师的平均月薪为 19000 NIS(5396 美元)。

女性占人口样本的 23%,45%的分析师职位由女性担任,这可以部分解释工资差距。不管怎样,男性数据科学家每月收入 31000 NIS(8830 美元),比女性高出 3000 NIS(284 美元)。从 37000 NIS(10508 美元)到 34000 NIS(9656 美元),在男性和女性研究人员中也可以发现类似的工资差距。

教育水平是影响工资的一个重要因素。与去年的调查结果类似,最常见的教育水平是硕士学位(51%的受访者),其次是学士学位(33%),博士学位(12%)。同样显而易见的是,工资随着教育水平的提高而增长——学士学位持有者的平均收入为 27000 NIS(7668 美元),硕士学位持有者的平均收入为 31000 NIS(8830 美元),博士学位持有者的平均收入高达 38000 NIS(10792 美元)。这一趋势在下面的场景中尤其有趣:虽然硕士学位持有者的平均工资男女相似,但男女博士学位持有者的工资差距令人震惊——相比之下,男性平均工资为 41000 NIS(11644 美元),女性平均工资仅为 27000 NIS(7668 美元)。

这种工资差距的部分原因似乎是,大约一半的女性拥有生物学、化学或脑科学的博士学位,而不是计算机科学或工程的博士学位。与此同时,拥有博士学位的男性 82%都是计算机科学或工程方面的专家:

这就把我们带到了下一个话题,即基于学术专业的工资范围。最常见的专业,伴随着巨大的工资差距,是计算机科学——超过 56%的受访者表示。另外 28%的人专攻工程、物理、数学或统计学,其余的人分布在生命科学、经济学和社会科学领域。在这些专业中,计算机科学家的工资最高,平均月薪为 33000 NIS(&9372)。紧随其后的是工科毕业生,平均月薪为 28000 NIS(7952 美元)。排在第二位的是经济学毕业生,平均月薪为 25000 NIS(7100 美元)。作为额外的观察,还值得注意的是,与计算机科学和工程毕业生不经常拥有博士学位相反,几乎所有生命科学毕业生都拥有博士学位。

当然,影响薪水的另一个因素是年龄。不出所料,薪水会随着年龄和经验的增长而增加。男性和女性都是如此,尽管工资差距仍然很突出——特别是在一些工作中最高级的职位持有者中。

从数字上看,工资差异较大的一个原因(除了教育水平或工作经验年限)是我们的受访者中有 14 人在为 IDF 工作。这降低了 20 多岁年龄段受访者的平均工资。薪资差距较大的另一个原因是,最高的薪资大多出现在公司和初创企业(被称为“高科技”行业)。与此同时,政府、金融、大学等部门的薪水都比较低。注意,一些薪酬最高的公司是跨国公司,比如谷歌、亚马逊、脸书等等:

如果我们考虑到跨国公司的公司规模,那么可以理解(尽管是推测性的)为什么这些公司的薪酬也可能是最高的。然而,无论公司规模如何扩大,公司内部员工的工资仍会波动。对于雇佣超过 10,000 名员工的公司来说尤其如此,25%的受访者月薪超过 46,000 NIS(13,064 美元):

请注意,当将工资分布作为一个变量的函数呈现时,可能会产生误导性的结果。例如,生命科学毕业生的平均工资与工程毕业生的工资一样高,尽管生命科学毕业生拥有的博士学位比工程师多。我们还看到,所有 20 多岁的受访者的平均工资都有下降的趋势,因为有一批受访者在为以色列国防军工作。很难完全抵消变量之间的各种相关性,如果我们设法做到这一点,将某些原因归因于这些相关性可能会被证明是额外的挑战。

职业和技术问题

数据科学家日常工作中不可分割的一部分是他或她处理的数据,以及他或她获取这些数据的方式。因此,我们将调查的很大一部分用于围绕数据的问题。 62.7%的受访者表示他们独立收集数据,没有使用额外的数据源。相比之下,26.8%从数据聚合器收集数据,17.8%从谷歌搜索收集数据,15.4%从大学或非营利组织运营的数据库收集数据。其余受访者从 GitHub 或政府网站收集数据。

当深入调查时,我们发现了关于所用数据类型的有趣结果: 46.3%的受访者使用关系数据,而 43.7%的受访者使用视觉数据(即图像)。排在第三位的是文本数据,有 39.3%的受访者使用,其次是传感器数据,有 27.3%的受访者使用。排名最后的是视频数据,只有 19.8%的受访者使用过,而音频数据只有 8.8%的受访者使用过。

在了解了哪些类型的数据是受欢迎的以及它们是如何收集的之后,是时候进一步深入了解我们的调查受访者如何处理他们的数据了。我们的下一步是解决日常数据科学中使用的方法和技术。在这种情况下,结果也是千差万别,许多回答者使用了非常不同的技术。排在最前面的是 67.9%的受访者使用的神经网络,其次是 51%的受访者使用的 CNN 和逻辑回归。45.8%的受访者使用随机森林,36.6%使用决策树。然后,31.7%使用集合方法,30.1%使用 SVM,29.5%使用 RNN。排名最末的是 15.9%的受访者使用的 GANs。

现在的问题是,我们的调查对象使用哪些库来执行所有这些技术。 TensorFlow 是使用最多的库,50.6%的受访者投票支持它。第二是 Keras,有 46.6%的受访者使用,第三是 PyTorch,有 40.5%的受访者使用。排名第四的是 Gensim,只有 7.6%的受访者使用,排名最后的是 Matlab,有 7.3%的受访者使用。

我们以下面的问题结束:工作者在实践数据科学时面临的最大挑战或最大障碍是什么?不出所料,与去年的调查结果类似, 60.7%的受访者的主要问题是“脏数据”,这对他们的工作流程和产出有害。

第二个问题是数据不可获得或不可用,35.1%的受访者指出了这一点。基于这些答案,当今数据科学的关键问题是数据本身,特别是如何收集高质量的数据。最后一个问题是该领域的人才短缺,29.3%的受访者提到了这个问题。数据和信息科学领域的人才短缺是众所周知的问题,该领域人力的缺乏阻碍了许多公司加速发展。

下面的问题涉及到本质上不一定是技术性的方面。24.7%的受访者表示,他们面临的非技术问题是收到难以找到答案的不清楚的问题,而 17.6%的受访者表示缺乏他们可以寻求建议的领域专家。最后,15.6%的受访者提到了定义数据科学家角色的困难以及在数据科学领域工作意味着什么。

摘要

总的来说,今年的调查结果与去年相比没有明显变化。随着该领域的需求越来越多,平均工资往往会增加,而且这种趋势似乎会持续到未来。尽管进入门槛很高,但我相信我们会看到更多人试图融入该领域,迈出机器学习的第一步。我们甚至可能会看到更多的人从非经典的切入点进入这个领域,例如,不同的工作路径和其他学术专业(这种模式已经变得很突出)。另一方面,我们也可能会看到传统公司或老牌创业公司进入该领域,研究他们如何才能最好地实施数据科学,以造福于他们的业务。

去年提出的另一个要点是,该领域的大多数雇主都集中在中央区(“Gush Dan”),更具体地说,是特拉维夫。我倾向于认为大多数人才库都集中在这些领域。无论如何,我们正在看到更多的机器学习社区在耶路撒冷和海法出现,因此明年的调查结果有可能在这方面讲述一个不同的故事。

明年可能见证的最后一个变化是,TensorFlow 的主导地位可能会下降,转而支持 PyTorch,py torch 越来越受欢迎。现在判断谁将领导队伍以及以色列社区是否会证实这一点还为时过早,但我们可以相对肯定地说,PyTorch 的存在在未来一年将大幅增长。

意义表征与 SRL:假设存在某种意义

原文:https://towardsdatascience.com/meaning-representation-and-srl-assuming-there-is-some-meaning-741f35bfdd6?source=collection_archive---------9-----------------------

对意义表征及其需要的详细描述

什么是意义表征

意义表征可以被理解为微妙的语言细微差别和我们关于世界的常识性非语言知识之间的桥梁。它可以被看作是一种捕捉语言输入意义的形式结构。在这样做的时候,我们假设任何给定的语言结构都有一些可以用来表达世界状态的东西/信息。

我们如何意识到有人赞扬或侮辱了我们?这就是对意义表征的需求产生的地方。我们通过将语言输入分解成有意义的结构并将其与我们对现实世界的知识联系起来来理解这一点。在这种情况下,它可以是我们对一个特定的人的了解,我们对以前的经历和与那个人的关系的了解,我们对那个特定时刻的了解等等。

如何表达一个句子的意思

有四种常用的意义表示语言:

  • 一阶逻辑
  • 使用有向图的抽象意义表示
  • 使用文本形式的抽象意义表示
  • 基于帧或槽的过滤器表示

在下图中,句子“我有一部电话”有四个联系人。

这些方法之间没有太大的区别。他们都认为意义表征是由与对象相对应的结构、对象的属性以及它们之间的关系构成的。

SRL——为什么还要学习和理解一种表现形式?

类似的事件可以用各种不同的结构和句子的混合体来表达。像语义角色标签这样的表征帮助我们捕捉表达相同思想的不同句子之间的共同结构。它帮助我们在我们描述事件的各种方式中识别和提取事件和参与者。我们也有像深层角色和主题角色这样的其他表现形式,但它们有其局限性。深层角色是特定于某个事件的,而主题角色则捕捉了深层角色的参与者之间的语义共性。尽管主题角色是最古老的语义概念之一,但是一致同意的规则要么是非常抽象的级别,即非常少的规则——仅代表少数高层次的想法,要么是非常低级的级别,即大量的规则——详细地代表特定的事件。语义规则可以被看作是一种在高层次和低层次的结构化表示中表示任何语言结构的方法。

SRL 或者如我们所知,语义角色标注帮助我们理解谓词和它的论元之间的语义关系。它帮助我们回答诸如谁在何时何地对谁做了什么之类的问题。语义角色标注是为每个谓词的每个论元自动找到语义角色的任务。

语义角色标记—随着时间的推移而进步

关于语义关系的最古老的工作可以追溯到公元前 8 世纪左右。as . t . a . ̄dhya ̄ȳı——8 本书的集合,描述了 3959 部佛经中梵语的语言结构——一个类似于现代形式语言理论机制的规则体系。̄dhya ̄y ̄ı也有一套规则来描述动词和名词论元之间的语义关系,回答诸如谁在何时何地对谁做了什么之类的问题。这是已知最古老的关于事件和参与者之间语义表达的著作。

如果没有各种语言资源的开发,获得训练 SRL 模型的特征是不可能的,例如,Fillmore(1968)和 Gruber(1965)的主题规则的现代表述,Levin-List 形式的 3100 个英语动词和相应语义类的列表(1993),Kippler 等人的将 Levin-List 链接到 WordNet 和 FrameNet(2000),如 Penn TreeBank(1993 和以后)的大型句法注释英语语言数据语料库, 用语义角色注释句子语料库,如 PropBank(语义注释的 Penn treebank 英语)和 FrameNet 一组定义的框架特定语义角色,称为框架元素,包括一组使用这些谓词的谓词。

当前大多数 SRL 方法都是基于有监督的基于特征的机器学习算法。以下伪代码给出了基于特征的 SRL 模型的更多见解:

*def SemanticRoleLabel(words):
     semantic_role_dict = {}
     ## parsing the words to get maximum coverage
     parsed_words = Parse(words) 
     for each predicate in parsed_words:
         for each node in parsed_words:
     #a feature extraction function to extract needed features
             node_feature = ExtractFeature(node, predicate, parse)
     #a 1 of N class classifier to get semantic role
             semantic_role = Classify_Node(node, parse, featurevector)

        semantic_role_dict[node] = semantic_role
     return semantic_role_dict*

大多数 SRL 系统是建立在语义角色自动标注(Gilda 和 Jurafsky,2000)的基础上的,它包括的特征有:支配谓词、短语类型、成分中心词、成分到谓词的路径等。研究人员也花了很多时间提出最佳的分类方法和优化技术。

SRL 邮报第三波神经网络

语义角色标记的深度模型的大多数当前技术状态是基于使用双向 LSTM 网络处理生物标记的输入数据作为参数和相关的嵌入层。网络的深度一般在 6 到 8 LSTM 层左右。是由何等人提出的网络架构师模型。(2017)在他的作品《深层语义角色标签:什么起作用,下一步是什么》中。

The goal is to maximize the probaility of tag-sequence y -- given the input sequence of words.
y^ = argmaxP(y|w)y∈T

在此之后,最近的其他工作也引入了一些伟大的想法,并进一步提高了模型的准确性,看起来在不久的将来,这些网络还会有更多的迭代。谭等将自关注引入到基于 LSTMs 的网络中,以获得更好的准确性和更好的全局优化,【何】等将句法信息作为另一个输入点添加到网络中,以获得输入数据的更详细表示。来自斯特鲁贝尔等人的最新作品。结合了多头自我关注和语法信息,以实现最先进的结果。该模型 LISA 是一个结合了多头自我关注和多任务学习的神经网络模型,它采用仅使用原始标记作为输入的语法,仅对序列进行一次编码,以同时对所有谓词执行解析、谓词检测和角色标记。通过训练一个注意力头来关注每个单词的语法双亲来合并语法。

最后,语义角色标注是一种强大的方法,它弥合了人类语言和计算机理解之间的鸿沟。随着神经网络的快速发展和声控助手的快速发展,SRL 只会成为一个更重要的研究领域。

参考资料:

  • 伦纳德·布龙菲尔德选集
  • 语言科学史。1.泰尔班德
  • 宾州树木银行
  • 语义网络:它们的计算和用于理解英语句子
  • 语义角色的自动标注
  • 带自我关注的深层语义角色标注
  • 语义角色标注语法,是,还是不是
  • 语义角色标注的语言信息自我注意
  • 伯克利框架网络项目
  • CoNLL-2005 共享任务介绍:语义角色标注
  • 语音和语言处理—第 14 章,第 18 章
  • 语义理论的结构

有意义的指标:累积收益和 Lyft 图表

原文:https://towardsdatascience.com/meaningful-metrics-cumulative-gains-and-lyft-charts-7aac02fc5c14?source=collection_archive---------5-----------------------

如今,所有大公司都非常依赖他们的数据科学能力。就分析的复杂性和多样性而言,业务数据单元变得越来越大,越来越复杂。然而,将数据科学解决方案成功交付到业务现实中很大程度上取决于调查结果的。即使开发的模型提供了出色的准确性分数,如果它们不符合各种商业利益相关者的需求,它们也可能被忽略。

所有受欢迎的 ROC AUC 分数对于业务部门来说信息不足,因为它对于非技术经理来说是抽象的。出于后一个原因,我将提出两个有意义的指标,每个分析师在说明他们的模型结果时都应该考虑:累积收益和提升图。我将展示电信行业中客户流失案例研究的例子。

想象一个业务场景,当一家电信公司决定通过向其 20%的客户提供一个月的无限制数据使用来最小化客户流失率。其中一位经理建议,为了使促销不偏不倚,应该按照姓氏顺序向每五位顾客发送一份礼物。决定差不多了:除非有人为这次营销推广提出更好的策略。

有了客户的样本数据(实际上可以从我的 GitHub 访问),我们将决定建立一个 RandomForestClassifier 模型来预测促销开始前的客户流失。然后我们会对数据进行预处理,去掉不必要的列,消除多重共线性,可视化。最后一步:用 GridSearchCV 进行模型训练和优化。然而,这篇文章不是关于这个项目的;这是关于你的发现的可解释性。这个案件的问题仍然没有答案。

为此,我将展示累积增益和升力曲线。累积收益曲线是一条评估曲线,用于评估模型的性能,并将结果与随机选择进行比较。它显示了根据该模型,当考虑到某一百分比的人口最有可能成为目标时,所达到的目标的百分比。在 python 中,我们提供了 scikitplot 库 ,它将为我们制作绘图。

*import scikitplot as skplt# Deriving Class probabilities
predicted_probabilities = model_rf_best_params.predict_proba(x_test)# Creating the plot
skplt.metrics.plot_cumulative_gain(y_test, predicted_probabilities)*

首先,我们根据模型的输出对所有的观察值进行排序。在水平轴的左侧,我们根据模型将最有可能成为目标的观察值放置在右侧,反之亦然。在我们的例子中,在水平轴的 20%点,具有最高概率的 80%观察值被定位。在垂直轴上,曲线指示该曲线中包括的所有目标的百分比。因此,如果我们可以瞄准 20%的观察值,模型将确保总共 80%的搅动者在这个组中,而随机选择将只提供 20%的目标。

除了累积增益曲线之外,升力曲线也是一种广泛使用的模型性能可视化方法。确切地说,lift 是对目标模型在预测或分类具有增强反应的病例(对于整个人群)方面的性能的一种度量,相对于随机选择目标模型进行测量。构建升力曲线遵循与形成累积增益曲线相似的过程。事实上,它是从增益图中推导出来的。首先,我们在水平轴上排列观察值,最有可能成为左边的目标,反之亦然。在垂直轴上,提升曲线指示该组中包括的目标比平均目标多多少倍。Lift 计算为分类和随机模型的累积收益之比。考虑 20%的提升(期望的提升目标);我们可以注意到,前 20%的观察值包含了 80%的目标。如果目标的平均发生率是 20%,那么升力是 4。因此,与没有模型的随机寻址相比,该模型允许为该组寻址四倍多的目标。

*#Scikitplot library is there to help
skplt.metrics.plot_lift_curve(y_test, predicted_probabilities)*

最终,我们准备好展示营销策略的发现。借助我们的模型,如果公司向 20%的客户提供免费促销,我们可以锁定 80%的顾客。而在随机选择的情况下,我们只能关注 20%的搅拌器。

因此,我们能够观察到累积增益和升力图是决策和模型评估的有用工具。它们不仅相对容易被有技术背景的专业人士理解,也相对容易被其他人理解。最终,这些图表可以应用于各种领域,如市场细分目标、财务预算、人力资源评估等。

对于完整的实现,请参考我的 GitHub 库并随意使用该数据进行相同的分析,还包括其他分类模型:GradientBoostingClassifier、LogisticRegression 等。

尝试,失败,学习,成功。

数据挖掘和机器学习中的相似性度量

原文:https://towardsdatascience.com/measures-of-proximity-in-data-mining-machine-learning-e9baaed1aafb?source=collection_archive---------0-----------------------

在分析过程中执行数据转换

Video version of the story, if you are into that sort of thing

我之前的一个帖子 里,我讲过 评估数据挖掘的数据质量&机器学习算法 。这个就继续那个,如果还没看的话,这里看一下以便对我在文章中要讲的话题和概念有一个恰当的把握。

两个对象之间的接近度是两个对象的相应属性之间的接近度的函数。接近度是指相似度和相异度。相似性和不相似性很重要,因为它们被许多数据挖掘技术使用,如聚类、最近邻分类和异常检测。

我们将从高级定义开始讨论,并探索它们之间的关系。然后,我们继续讨论具有一个简单属性的两个数据对象中的接近度,并继续讨论具有多个属性的对象。

请容忍我的概念部分,我知道这可能有点无聊,但如果你有强大的基础,那么没有什么可以阻止你成为一名伟大的数据科学家或机器学习工程师。

什么是相似性?

→这是两个对象相似程度的数字度量。

→对于更相似的一对对象,该值更高。

→通常为非负值,介于 0 和 1 之间。

0 ~没有相似性,1 ~完全相似

什么是不同?

→它是两个对象不同程度的数值度量。

→对于更相似的一对对象,较低。

→范围 0 至无穷大

变换函数

这是一个函数,用于将相似性转换为不相似性,反之亦然,或者将接近度转换为特定范围。例如:

s' = (s-min(s)) / max(s)-min(s))

在哪里,

s’=新转换的邻近测量值,

s =当前接近度测量值,

最小值 =邻近测量值的最小值,

最大值 =最大接近度测量值

这个转换函数只是所有可用选项中的一个例子。

简单属性之间的相似和相异

具有多个属性的对象的接近度通常通过组合单个属性的接近度来定义,因此,我们首先讨论具有单个属性的对象之间的接近度。

Introduction to Data Mining — Pang-Ning Tan, Michael Steinbach, Vipin Kumar

为了更好地理解它,让我们看一些例子。

  • 考虑由一个名义属性描述的对象。如何像这样比较两个物体的相似度?名义属性只告诉我们对象的独特性。因此,在这种情况下,如果属性值匹配,则相似性被定义为 1,否则,相反定义的相似性为 0。
  • 对于具有单个序数属性的对象,情况更复杂,因为需要考虑关于顺序的信息。考虑一个衡量产品质量的属性,等级为{差、一般、好、好、极好}。我们有三个产品 P1,P2,& P3,质量分别为极好,良好,&还行。为了比较有序的数量,它们被映射到连续的整数。在这种情况下,如果刻度分别映射到{0,1,2,3,4}。那么,不同(P1,P2)= 4–3 = 1。
  • 对于区间或比率属性,两个对象之间相异度的自然度量是它们值的绝对差值。例如,我们可以通过说“我重了十磅”来比较我们现在的体重和一年前的体重

如果你不知道不同的属性类型,即名义的、序数的、区间的和比率的,那么让阅读我以前的关于属性到不同类型的分布的文章。

** [## 数据挖掘之旅

数据导论

towardsdatascience.com](/journey-into-data-mining-3b5ccfa5343)**

接下来,我们将分别讨论数据对象之间的相似性和不相似性。事不宜迟,让我们开始吧。

数据对象之间的差异

我们从讨论距离开始,距离具有不同的性质。

欧几里德距离

在一维、二维、三维或更高维空间中,两点 x 和 y 之间的欧几里德距离 d 由以下公式给出:

Introduction to Data Mining — Pang-Ning Tan, Michael Steinbach, Vipin Kumar

其中 n 是维数, x(k)y(k) 分别是 xyk属性(组件)。

举例:

Introduction to Data Mining — Pang-Ning Tan, Michael Steinbach, Vipin Kumar

闵可夫斯基距离

它是欧几里得距离的推广。它由以下公式给出:

其中 r 是一个参数。以下是闵可夫斯基距离的三个最常见的例子。

r = 1 。城市街区(曼哈顿、出租车、、L1 定额)距离。一个常见的例子是汉明距离,它是仅具有二进制属性的两个对象之间,即两个二进制向量之间不同的位数。

r = 2 。欧几里德距离( L2 范数)。

r =无穷大。上确界( L(最大),或 L(无穷大)范数)距离。这是对象的任何属性之间的最大差异。这由以下公式定义:

举例:

Introduction to Data Mining — Pang-Ning Tan, Michael Steinbach, Vipin Kumar

距离,如欧几里德距离,有一些众所周知的性质。如果 d(x,y) 是两点之间的距离, xy ,那么以下性质成立。

  1. 积极性

a) d(x,y) > 0 对于所有 xy

b) d(x,y) = 0 仅当 x = y

2.对称**
d(x,y) = d(y,x) 对于所有 xy**

3.三角形不等式****

d(x,z) ≤ d(x,y) + d(y,z) 对于所有点 x,yz

满足所有这三个属性的度量被称为度量。****

数据对象之间的相似性

对于相似性,三角形不等式通常不成立,但对称性和正性通常成立。明确地说,如果 s(x,y) 是点 xy 之间的相似性,那么相似性的典型性质如下:

  1. s(x,y) = 1 仅当 x = y 时。(0 ≤ s ≤ 1)
  2. s(x,y) = s(y,x) 对于所有 xy 。(对称)

对于相似性度量,没有三角形不等式的一般模拟。

****二进制数据的相似性度量被称为相似性系数,其值通常在 0 和 1 之间。两个二进制对象之间的比较使用以下四个量来完成:

Introduction to Data Mining — Pang-Ning Tan, Michael Steinbach, Vipin Kumar

简单匹配系数

其定义如下:

Introduction to Data Mining — Pang-Ning Tan, Michael Steinbach, Vipin Kumar

雅克卡系数

其定义如下:

Introduction to Data Mining — Pang-Ning Tan, Michael Steinbach, Vipin Kumar

比较这两种相似性方法的示例:

Introduction to Data Mining — Pang-Ning Tan, Michael Steinbach, Vipin Kumar

余弦相似度

文档通常表示为向量,其中每个属性表示特定术语(单词)在文档中出现的频率。余弦相似度,是一种最常见的度量文档相似度的方法。如果 xy 是两个文档向量,那么

Introduction to Data Mining — Pang-Ning Tan, Michael Steinbach, Vipin Kumar

在哪里?表示点积||x|| 定义向量 x 的长度。

****余弦相似度度量的一个例子如下:

Introduction to Data Mining — Pang-Ning Tan, Michael Steinbach, Vipin Kumar

相关性

它是对具有二元或连续变量的对象的属性之间的线性关系的度量。两个对象 xy 之间的相关性定义如下:

Introduction to Data Mining — Pang-Ning Tan, Michael Steinbach, Vipin Kumar

其中使用的符号在标准中定义为:

Introduction to Data Mining — Pang-Ning Tan, Michael Steinbach, Vipin Kumar

直到现在我们已经定义并理解了数据对象之间的相似性和不相似性度量。现在,让我们讨论一下邻近计算面临的问题。

邻近度计算中的问题

  1. 如何处理具有不同尺度和/或相关属性的酪蛋白,
  2. 如何计算由不同类型的属性(例如,定量和定性属性)组成的对象之间的接近度,以及
  3. 当属性具有不同的权重时,即当并非所有属性对对象的邻近性的贡献相等时,如何处理邻近性计算。

选择正确的邻近测量

以下是一些可能有帮助的一般观察。首先,邻近度量的类型应该适合数据的类型。对于许多类型的密集、连续数据,通常使用公制距离度量,如欧几里德距离

连续属性之间的接近度通常用差异来表示,而距离度量提供了一种将这些差异组合成整体接近度的明确方法。

对于通常由不对称属性组成的稀疏数据,我们通常采用忽略 0–0 匹配的相似性度量。从概念上讲,这反映了这样一个事实:对于一对复杂的对象来说,相似性取决于它们共有的特征的数量,而不是它们都缺少的特征的数量。对于这类数据,可以使用余弦相似度雅克卡系数

以上只是一些需要坚持或者可以遵循的建议。它们没有涵盖所有类型的现有数据集。接近度测量的最终确定取决于问题。

我们对邻近度的讨论到此结束。

这个帖子的后续是这里。

** [## 数据挖掘和机器学习中的数据预处理

有了详细的概念…

towardsdatascience.com](/data-preprocessing-in-data-mining-machine-learning-79a9662e2eb)**

我将免费赠送一本关于一致性的电子书。在这里获得你的免费电子书。

如果你喜欢阅读这样的故事,那么你应该 在你的收件箱 中收到我的帖子,如果你想支持我成为一名作家,考虑注册成为一名媒体成员。每月 5 美元,你可以无限制地阅读媒体上的故事。如果你注册使用我的链接,我会赚一小笔佣金,不需要你额外付费。

** [## 加入我的推荐链接-塔伦古普塔

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

tarun-gupta.medium.com](https://tarun-gupta.medium.com/membership)

感谢阅读。如果你喜欢这个,去看看我在这个索引中的其他文章。

[## 标记故事列表的快速链接—感谢您的访问

我也有一份以快节奏出版为目标的出版物。读书成为作家。

tarun-gupta.medium.com](https://tarun-gupta.medium.com/thank-you-for-visiting-my-profile-9f708062c75e)**

监控和改进用于训练深度学习模型的 GPU 的使用

原文:https://towardsdatascience.com/measuring-actual-gpu-usage-for-deep-learning-training-e2bf3654bcfd?source=collection_archive---------7-----------------------

关于运行权重和偏差的一个令人兴奋的事情是,我们可以研究模型如何在真实世界场景中实际使用它们的计算资源,并且,由于我们正在使监控 GPU 和内存变得容易,我们希望通过查看人们如何利用他们的计算资源来帮助我们的用户。

对于接受 GPU 培训的用户,我查看了他们在所有运行中的平均利用率。自发布以来,我们已经跟踪了大量用例、技术和框架的运行。近三分之一的用户平均利用率低于 15%。平均 GPU 内存使用量非常相似。我们的用户往往是经验丰富的深度学习实践者,GPU 是一种昂贵的资源,所以我很惊讶地看到如此低的平均使用率。

这里有几个简单、具体的建议来提高 GPU 的使用率,几乎适用于所有人:

  1. 在整个训练过程中持续测量您的 GPU 使用情况

不测量就无法提高 GPU 使用率。使用 nvidia-smi 等有用的工具来捕捉您的使用情况并不难,但发现问题的一个简单方法是跟踪一段时间的使用情况。任何人都可以使用我们构建的 wandb python 包,通过添加两行代码来跟踪 GPU、CPU、内存使用和其他指标

import wandb
wandb.init()

wandb.init()函数将创建一个轻量级子进程,该子进程将收集系统指标并将它们发送到 wandb 服务器,您可以在服务器上查看这些指标,并使用如下图形进行比较:

进行单一测量的危险在于 GPU 的使用会随着时间而变化。这是我们在用户 Boris 训练 RNN 时看到的常见模式;训练中期,他的使用率从 80%骤降到 25%左右。

你可以在 https://app.wandb.ai/borisd13/char-RNN/runs/cw9gnx9z/system 的看到他完整的数据和训练日志。

我们经常看到的一个与多 GPU 相关的情况是,在训练过程中,一些 GPU 停止处理任何负载。在这个示例中,两个 GPU 都开始进行计算,但几分钟后,所有负载都被发送到一个 GPU。这可能是有意的,但这通常是代码中难以捕捉的 bug 的迹象。

我们看到的另一个常见问题是,有很长一段时间没有使用 GPU,这通常与培训中的测试或验证阶段或一些数据预处理的瓶颈相对应。这是一个典型的图表,在 8 个 GPU 上进行训练,其中所有的 GPU 都在固定的时间间隔内关闭并等待一段时间。

2)确保你的 GPU 是瓶颈

这是我们看到的一种常见情况——系统内存被大量使用,并且内存使用量似乎在逐渐增加。随着内存使用率的上升,GPU 使用率下降。当人们试图在本地不可用的数据集上进行训练时,我们也经常看到网络成为瓶颈。

3)尝试增加你的批量

这并不是在所有情况下都有效,但是一种可能提高 GPU 利用率的简单方法是增加批处理大小。批处理的梯度通常在 GPU 上并行计算,因此只要有足够的内存将整个批处理和神经网络的多个副本放入 GPU 内存,增加批处理大小就可以提高计算速度。

如果我增加批处理大小,而其他什么都不改变,我可能会得出结论,增加批处理大小会加快计算速度,但会降低模型性能。以下是我用批量 32、64 和 128 训练 CIFAR 的结果。

事实上,在 StackOverflow 上有许多的论文和一个的置顶帖警告大批量生产。有一种简单的方法可以让更大的批量工作得相当好。随着批量的增加,提高学习速度。直观地说,这是有意义的,批量大小是训练算法在进行一步之前查看的样本数量,学习率大致是该步的大小。因此,如果模型看更多的例子,它可能会舒服地迈出一大步。这是在论文中推荐的一个并行化卷积神经网络的奇怪技巧以及随后的精确、大型迷你批处理 SGD:在 1 小时内训练 ImageNet中,作者在看到性能损失之前设法将批处理大小增加到 8000。

我尝试在我自己的模型上增加批量的学习率,并得到了相同的结论。当我将学习率乘以 4,将批量增加 4 时,我的模型训练得更快,每一步学习得也更快。

脸书的论文做了一些奇特的事情,使模型在非常大的批量下工作良好,他们能够获得相同的性能,但速度要快得多,每批高达 8000 个样本。

这些巨大的批量对于分布式训练来说是有意义的,论文中从较低的学习率开始,然后逐步提高的方案在这种情况下看起来非常有价值。如果你正在一个 GPU 上训练,并且没有最大化你的利用率,我有一个快速的建议:加倍你的批量大小和加倍你的学习速度。

您可以在批量报告中深入了解我运行的更多数据。

结论

GPU 变得越来越快,但如果训练代码没有完全使用它们也没关系。好消息是,对于大多数训练机器学习模型的人来说,仍然有许多简单的事情要做,这将显著提高效率。

还有另一种可能更大的资源浪费:闲置的 GPU。我们没有衡量这一点,但我从许多与我们合作的公司那里听说过。很难有效地为 GPU 排队工作,在典型的工作流程中,研究人员将设置大量的实验,等待它们完成,然后花相当多的时间消化结果,而 GPU 却处于闲置状态。这超出了 wandb 的范围,但是像 Paperspace 和亚马逊的 Sagemaker 这样的工具可以很容易地根据需要上下旋转资源。

感谢

感谢萨姆·波廷杰、凯里·菲尔普斯、詹姆斯·查姆、焰炟·厄尔利希、斯蒂芬妮·谢尔的编辑和反馈。

贝塔几何负二项分布— CLTV 预测模型

原文:https://towardsdatascience.com/measuring-customers-value-using-python-lifetimes-d8b19a04e9c1?source=collection_archive---------14-----------------------

与 CLTV 相关的近期、频率和货币

使用概率建模方法的 CLTV

Image by author

https://sarit-maitra.medium.com/membership

C 客户生命周期价值(CLTV)是现代以客户为中心的商业场景中最重要的指标之一。它是一个指标,表明在整个关系中,一个企业可以从单个客户那里合理期望的总收入。与 CLTV 的业务不仅量化的关系,但优先考虑的 CRM 活动,并采取必要的步骤,以保持现有的客户满意。这也有助于公司关注那些未来能带来更多收入的潜在客户。

80%的结果来自 20%的原因,这就是所谓的 80/20 法则或帕累托法则……维尔弗雷多·帕累托。

如果我们把帕累托法则放在商业环境中,我们可以有把握地假设 20%的关键客户贡献了 80%的业务收入。许多研究开发了评分机制(例如预测客户未来行为的回归模型)。在所有的实证分析中,对客户过去行为的衡量是他们未来行为的关键预测指标。通常的做法是通过调查近期、频率和货币(RFM)特征来总结客户过去的行为。

让我们使用下面一些简单的等式:

客户价值=平均订单价值(AOV)购买频率*

  • 流失率:流失率是没有再次订购的客户的百分比。
  • 客户寿命= 1/流失率
  • 流失率= 1-重复率

上面的公式看起来很简单;然而,在给定历史数据的情况下,预测未来销售额和美元值的 CLTV 测量涉及预测分析方面的复杂性。这可以使用回归技术或概率建模方法来完成。

目标:

我们的目标是建立一个概率模型,在非合同环境下预测个人业务层面的 CLTV。利用本练习的结果,经理应该能够:

  • 区分活跃客户和不活跃客户,
  • 为个人客户生成交易预测,
  • 预测整个客户群的购买量。

方法:

此处展示的随机模型以贝塔几何负二项分布(BG/NBD)框架为特色,以捕捉一段时间内的交易流。BG/NBD 讲述了客户如何/何时变得不活跃的故事。

BG/NBD 只需要关于每个客户过去购买历史的两条信息:“最近”(最近一次交易发生的时间)和“频率”(在特定时间段内进行了多少次交易)。用于表示该信息的符号是[X = x,t(x),T],其中 X 是在时间段(0,T)和 t(x) (0 < t(x) ≤T) is the time of the last transaction. Using these two key summary statistics, SMC(2) derive expressions for a number of managerially relevant quantities, such as:

E[X(t)], the expected number of transactions in a time period of length t, which is central to computing the expected transaction volume for the whole customer base over time.

P[X(t) = x], the probability of observing x transactions in a time period of length t.

E[Y (t)| X = x, t(x), T], the expected number of transactions in the period (T,T + t] for an individual with observed behavior (X = x, tx, T).

Therefore, customers will purchase at a randomly distributed interval within a time range. After each purchase they have a certain probability of dying or becoming inactive. Each customer is different and have varying purchase intervals and probability of going inactive.

Let’s explore the data.

BG/NBD Model:

  • Frequency (F) is the number of repeat purchases the customer has made.
  • T represents the age of the customer which is equal to the duration between a customer’s first purchase and the end of the period under study.
  • Recency (R) is the age of the customer when they made their most recent purchases. This is equal to the duration between a customer’s first purchase and their latest purchase.
  • Monetary Value

After doing the necessary cleaning and creating a new data frame containing CustomerID, InvoiceDate (remove the time) and adding a new column (‘sales’) :

data[‘InvoiceDate’] = pd.to_datetime(data[‘InvoiceDate’]).dt.date
data = data[pd.notnull(data[‘CustomerID’])]
data = data[(data[‘Quantity’]>0)]
data[‘Sales’] = data[‘Quantity’] * data[‘UnitPrice’]
cols_of_interest = [‘CustomerID’, ‘InvoiceDate’, ‘Sales’]
data = data[cols_of_interest]
print(data.head())
print(data[‘CustomerID’].nunique())

We can make some observations here. There are 4339 customers and 12346 made single purchase, so the F and R are 0, and the T is 325 days.

df[‘frequency’].plot(kind=’hist’, bins=50)
print(df[‘frequency’].describe())
print(sum(df[‘frequency’] == 0)/float(len(data)))

As shown, both frequency and recency are distributed quite near 0. Among all customers, >)中观察到的交易数量,其中 38%的人只进行了零次重复购买,而其余的样本(62%)被分成两个相等的部分:31%的客户群进行了一次重复购买,而另外 31%的客户群进行了一次以上的重复购买。类似地,就近期而言,大多数消费者在他们一生中的早期进行了最后一次购买,然后变得不活跃。事实上,我们一半的客户的最后一次重复购买是在不到一年的时间内(准确地说是 252 天),因为他们第一次购买了 75 个分位数。

现在让我们开始讨论模型:

我们首先需要将客户概率模型与数据相匹配,以便它能够反映他们的行为和模式。这是通过查看每个人的频率、最近和年龄并调整其参数来实现的,以便更好地反映我们的客户群购买的时间间隔。

不同客户的参数也各不相同,因此它是通过两种分布计算的,以便更准确、更灵活地拟合数据。从数学上讲,这是通过在两个分布上取方程的期望值来完成的。

bgf = BetaGeoFitter(penalizer_coef=0.0)
bgf.fit(df[‘frequency’], df[‘recency’], df[‘T’], )
print (bgf)

# Plot
gbd = beta.rvs(bgf.params_[‘a’], bgf.params_[‘b’], size = 50000)
ggd = gamma.rvs(bgf.params_[‘r’], scale=1./bgf.params_[‘alpha’], size = 50000)
plt.figure(figsize=(14,4))
plt.subplot(121)
plt.title(‘Heterogenity of $p$’)
temp = plt.hist(gbd, 20, alpha=0.75)
plt.subplot(122) 
plt.title(‘Heterogenity of $\lambda$’)
temp = plt.hist(ggd, 20, alpha=0.75)

可视化 F/R 矩阵;

给定 R(上次购买的年龄)和 F(重复交易的次数),频率/最近矩阵计算客户在下一个时间段的预期交易次数。

该矩阵在 Y 轴上具有客户的最近度,在 X 轴上具有频率,并且热图组件显示了在交叉点处客户在一个单位时间内将进行的未来购买的预测数量。最有可能点餐的顾客是那些之前下过很多订单,最近才被看到的顾客。

plot_frequency_recency_matrix(bgf)

RF 图描绘了客户在下一年的预期购买量,以及在给定频率/近期的情况下,他们仍然存在的可能性。直观上,我们可以看到,高频率和新近性的客户有望在未来购买更多,并有更高的机会活着。白色区域的客户也很感兴趣,因为他们离开公司的几率是 50/50,但我们仍然可以预计他们在接下来的一年中会购买大约 2 到 2.5 次。这些客户可能需要一些客户服务才能回来购买更多。有趣的是,对于一个固定的近期,更频繁的客户更有可能被认为是死了。这是模型的一个属性,说明了一个清晰的行为故事:

如果我们观察到一个更长时间的不活动,而不是顾客以前的间隔时间,那么一个更频繁购物的顾客就更有可能死去。

我们可以看到,如果客户购买了 120 次,而他们最近一次购买(R)是在 120 天之前,那么他们就是你的最佳客户(右下角)。最冷漠的顾客是那些在右上角的顾客:他们很快买了很多东西,几个星期都没见过他们。(20,50)周围的尾部代表不经常购买,但最近没有看到的客户,所以他们可能会再次购买-我们不确定他们是已经死亡还是只是在购买之间。

每个客户活着的概率:

我们可以根据每个客户的频率和新近度来想象他们活着的概率。

plot_probability_alive_matrix(bgf)

最近购买的客户几乎肯定是“活着”的。那些大量购买但不是最近购买的顾客,很可能已经退出。他们过去买的越多,就越有可能辍学。它们被显示在右上方。

从最佳到最差排列客户:

让我们将客户从“下期最高预期购买量”到最低进行排序。模型揭示了一种方法,该方法将使用客户的历史记录来预测客户在下一时期的预期购买量。

t = 31*3
df[‘predicted_purchases’] = bgf.conditional_expected_number_of_purchases_up_to_time(t, df[‘frequency’], df[‘recency’], df[‘T’])
df.sort_values(by=’predicted_purchases’).tail(10)

此处列出了我们的前 10 名客户,该模型预计他们将在未来 3 个月内购买。我们可以看到,已经进行了 131 次购买的客户,并且是最近购买的,很可能会在下一期再次购买。predicted_purchases 列显示他们的预期购买数量,而其他三列表示他们当前的 RFM 指标。BG/NBD 模型认为,这些人在不久的将来会进行更多的购买,因为他们是当前的最佳客户。

评估模型拟合度(纳入异质性):

拟合模型后,我们有兴趣看看它与我们的数据有多相关。首先是将我们的数据与用我们拟合的模型参数模拟的人工数据进行比较。

plot_period_transactions(bgf)

这两者几乎相同,表明该模型非常适合,并且相当好地预测了校准周期中的周期数。未来会重复购买 0、1、2、3 … 6 次的预期顾客数量。对于每次重复购买的数量(x 轴),我们绘制出模型预测的数量和实际数量。正如我们所看到的,在最多 6 次重复购买的情况下,fit 几乎没有错误。让我们做下一个事实检查。

但是,计算总误差百分比(预测交易/实际交易-1)和校准期间完成的每笔交易的误差百分比总是一个好主意。这将有助于我们量化模型与现实的接近程度。

模型测试:

summary_cal_holdout = calibration_and_holdout_data(data, ‘CustomerID’, ‘InvoiceDate’,
 calibration_period_end=’2011–06–08',
 observation_period_end=’2011–12–9' )
print(summary_cal_holdout.head())

bgf.fit(summary_cal_holdout[‘frequency_cal’], summary_cal_holdout[‘recency_cal’], summary_cal_holdout[‘T_cal’])
plot_calibration_purchases_vs_holdout_purchases(bgf, summary_cal_holdout)

在该图中,我们将数据分为采样(校准)和验证(维持)两个阶段。样本期从年初至 2011 年 6 月 8 日;验证期跨越剩余的持续时间(2011 年 6 月 9 日至 2011 年 12 月 9 日)。该图根据重复购买的次数(x 轴)对校准期内的所有客户进行分组,然后对维持期内的重复购买进行平均(y 轴)。该图根据重复购买的次数(x 轴)对校准期内的所有客户进行分组,然后对维持期内的重复购买进行平均(y 轴)。橙色和蓝色线分别表示 y 轴的模型预测和实际结果。这些线彼此非常接近,这表明该模型在预测每个客户的订单数量方面相差不远。

该模型能够准确预测样本外客户群的行为,该模型低估了 4 次购买和 5 次购买后的行为。

客户交易预测:

根据客户历史,我们现在可以预测个人未来的购买情况:

t = 10
individual = df.loc[12347]
bgf.predict(t, individual[‘frequency’], individual[‘recency’], individual[‘T’])

0.15727742663038222

模型预测客户(id:12347)未来 10 天的交易为 0.157。

关键要点:

客户是企业最重要的资产,CLTV 允许在客户群中评估他们当前和未来的价值。CRM 策略和营销资源分配是基于这一指标。如果我们考虑以客户为中心的业务,企业不仅需要预测客户的保留率,还需要分析客户的购买行为。BG/NBD 是与帕累托/NBD 相关的行为故事中的一个微小变化,但是更容易实现。从指数分布过渡到几何过程(以捕捉顾客流失)不需要任何不同的心理学理论,也没有任何值得注意的管理含义。

我可以到达这里

衡量金融动荡和系统风险

原文:https://towardsdatascience.com/measuring-financial-turbulence-and-systemic-risk-9d9688f6eec1?source=collection_archive---------9-----------------------

这个项目展示了两种测量金融风险的独特方法。

  • 要通过电子邮件接收指标值的定期更新,请点击此处。
  • 金融动荡和系统性风险指标目前都在这里主持。
  • Python 脚本和文档可以在这里找到。

内容

  • 简单地说
  • 金融动荡指标
  • 系统性风险指标
  • 数据集
  • 销售宣传(或“这两个指标如何为您赚钱/省钱”)

简单地

这个项目展示了两种测量金融风险的独特方法。

金融动荡指标衡量全球金融市场随时间的波动。这很重要,因为:

  1. 我们可以预测金融动荡的未来路径,因为金融动荡在时间上是高度持续的。
  2. 在金融动荡时期,你可以通过规避风险资产来省钱,因为金融资产价格在动荡时期往往会下跌(相对于非动荡时期而言)。

马克·克里茨曼和李元镇在他们题为“头骨、金融动荡和风险管理” (2010)的论文中讨论了这两种说法。

系统性风险指标衡量全球金融市场长期以来的系统性风险。这很重要,因为如果系统性风险很高,那么全球金融市场就彼此“紧密耦合”,这表明金融冲击往往会传播得更快、更广。马克·克里兹曼、李元镇、塞巴斯蒂安·佩奇和罗伯托·里戈本在“作为系统风险衡量标准的主要成分” (2010)中支持这一观点。

一个有用的类比:《三只小猪》

使用这个类比,系统风险处理的是你的房子是用稻草、树枝还是砖块建造的。湍流处理大坏狼在你家吹得有多厉害。因此,系统性风险并不一定表明金融危机迫在眉睫,只是表明全球市场更容易受到动荡的影响。

本文的其余部分将如下进行。

  • 对于这两个指标,我们将讨论它们的原始计算和用例(正如它们的创建者所建议的),以及我个人对计算的修改。
  • 接下来,我们将回顾用于计算这两个指标的数据集。
  • 最后,我们将分析这两个指标在之前的金融危机中的表现。本练习将展示投资者如何通过谨慎解读这两个指标来减轻其在之前危机中的损失。

金融动荡指标

Kritzman 和李(2010)提出了基于马氏距离的“金融动荡的数学度量”。

定性:金融动荡是指

  • 资产价格的波动异常之大。
  • 资产价格变动违反了现有的相关性结构(相关资产的“脱钩”和不相关资产的“趋同”)。

如果两个条件都满足,湍流将比仅满足其中一个条件时更高。

定量:

From “Skulls, Financial Turbulence, and Risk Management” (2010)

金融动荡的用例包括对投资组合进行压力测试,构建抗动荡的投资组合,以及扩大风险敞口。更多详情请见 Kritzman 和李(2010) 。

本文主要关注“扩大风险敞口”用例。

我个人对计算的修改。在上面的方程(2)中,方程的左手边在我的湍流图中被称为“原始湍流”。为了创建一个更平滑,更可解释的湍流度量,我计算了“原始湍流”系列的指数加权移动平均(EWMA),并将其称为“湍流”。这意味着“湍流”系列中的每个数据点都等于所有先前“原始湍流”值的 EWMA,其中较新的“原始湍流”值被赋予较高的权重。衰减因子“alpha”设置为每个值权重的半衰期为 12 周(12 周大约相当于一个财政季度的长度)。

系统风险指标

Kritzman、Li、Page 和 Rigobon (2010)引入了“一种衡量隐含系统风险的方法,称为吸收比率”。

定性:如果全球资产价格变动可以大部分由少数独立因素解释,那么就存在高系统性风险。

定量:吸收比(AR)等于(资产收益协方差矩阵的)固定数量的特征向量所解释或“吸收”的一组资产收益的总方差的分数。

From “Principal Components as a Measure of Systemic Risk” (2010)

AR的主要用例是以各种方式表明市场脆弱性。更多详情见 Kritzman 等人(2010) 。

本文着重于使用 AR 来提供解释湍流指数的上下文。

我个人对计算的修改。首先,我计算 250 周(250 周大约是 5 年)的资产回报协方差矩阵。对于每个新的数据点,该窗口向前移动。第二,我的系统性风险图中的“系统性风险”系列不是使用上面的 AR 公式,而是资产收益协方差矩阵的所有特征值的基尼系数。这样我们就不用任意选择上面 AR 公式分子中的特征向量个数了。

数据集

理论上,这两个指标都可以在任何金融资产池中进行计算。为了给我的资产池选择资产,我使用了以下标准:

  1. 涵盖全球所有主要金融市场。因此,我的资产池包括 6 个国际股市指数。
  2. 包括描述多个投资者风险回报维度的资产类别。例如:
  • 美国资产国际资产
  • 股票(有风险)对美国国债(“无风险”)
  • 侵略性行业(周期性)vs. 防御性行业(反周期性)
  • 小市值(风险较大)与大市值(风险较小)
  • 长期债务(风险较大)与短期债务(风险较小)
  • 高收益债券(风险较高)与投资级债券(风险较低)

考虑到这些因素,最终的资产池是:

我使用雅虎财经获得了资产池中每项资产的每周价格/回报,因为较高频率(每日数据)包含太多的噪音(随机性),而较低频率(每月数据)包含的信息远远少于每周数据。

销售宣传(或者,“这两个指标如何为您赚钱/省钱”)

利用这两个指标作为金融危机的“预警信号”,投资者可以获得更高的绝对收益更低的波动性(如下图所示)。

本文的剩余部分将追踪上图中假设的“基于湍流的策略”的主要决策点。

考虑一个可以做出以下三种选择的投资者:

  1. 100%投资于美国股市(标准普尔 500 指数)。
  2. 50%投资于美国股票市场。
  3. 0%投资于美国股市(投资者持有现金)。

让我们从这位投资者的角度出发,从 1996 年 11 月开始。他 100%投资于美国股市。决策点在以下图表中进行了编号。上图是动荡,下图是系统性风险。

Top chart is Turbulence, bottom chart is Systemic Risk

第 1 号决定:1998 年 8 月 28 日。1997 年亚洲金融危机发生在去年。动荡指数已经飙升至 5.53(高于一个月前的 4.85),所以现在可能是从桌上拿走一些钱的好时机。将股票市场敞口降至 50%。

第 2 号决定:2003 年 6 月 6 日。此前几年经历了几次动荡(1998 年俄罗斯金融危机和 LTCM 救助,科技股泡沫)。既然震荡像再次跌破 4.50,现在是重新进入市场的好时机。不断上升的系统性风险并不令人担忧,因为动荡一直在稳步下行。将股票市场敞口增加到 100%。

第 3 号决定:2007 年 8 月 24 日。湍流指数飙升至 4.07(高于 5 周前的 3.05)。这一点再加上几年来累积的系统性风险,凸显了谨慎的必要性。将股票市场敞口降至 50%。

第 4 号决定:2008 年 3 月 28 日。湍流指数飙升至 5.72,(高于两周前的 5.05)。系统性风险最近也有所上升。事情可能很快会变得糟糕,所以将股票市场敞口降至 0%。

2009 年 10 月 23 日第 5 号决定。随着次贷危机最糟糕的时期过去,动荡指数降至 5.00 以下,并似乎呈下降趋势。将股票市场敞口提高至 50%。

第 6 号决定:2010 年 5 月 3 日。动荡跌破 4.00,继续其下降趋势。将股票市场敞口提高至 100%。

第 7 号决定:2011 年 19 月 8 日。我们正处于欧洲债务危机的阵痛之中。动荡指数跃升至 4.10(高于 4 周前的 3.33),系统性风险仍在上升。将股票市场敞口降至 50%。

第 8 号决定:2012 年 4 月 27 日。欧洲债务危机似乎暂时得到了控制。尽管系统性风险继续增加,但动荡已降至 3.50 以下,因此将股票市场敞口提高至 100%。

第 9 号决定:2016 年 5 月 2 日。动荡在 4.00 以上蔓延,而系统性风险已经积累了几年。与此同时,经济乐观情绪开始降温。现在似乎是将股票市场敞口降至 50%的好时机。

第 10 号决定:2016 年 2 月 9 日。随着市场紧张情绪的消退,动荡回落到 3.50 以下,这表明将股票市场敞口增加到 100%是安全的。

要通过电子邮件定期接收指标值更新,请点击此处。

如果您还有任何问题,请随时联系我。

测量机器学习

原文:https://towardsdatascience.com/measuring-machine-learning-945a47bd3750?source=collection_archive---------12-----------------------

从台式机,到单板机,再到微控制器

Talking at Crowd Supply’s Teardown conference in Portland, OR, on Saturday the 22nd of June 2019.

这是我 2019 年 6 月在俄勒冈州波特兰市举行的 Crowd Supply拆机 大会上的演讲记录。虽然视频是给定的谈话,但文字稿已经扩展了一些自它出现以来发生的事件的细节。

机器学习传统上与重型、耗电的处理器联系在一起。它是在大型服务器上完成的。即使采集数据的传感器、摄像头和麦克风本身是本地的,控制它们的计算机却在远处,决策过程都托管在云中。但这正在改变,事情正在走向边缘。

现在,对于任何已经存在一段时间的人来说,这不会是一个惊喜,因为在整个行业的历史中,取决于技术的状态,我们似乎在瘦客户端和胖客户端架构之间摇摆不定。要么我们的大部分计算能力和存储隐藏在机架中,有时是远程服务器,要么是在离家更近的大量分布式系统中。我们又回到了分布式系统。或者至少是两者的混合体。这并不奇怪,机器学习有一个相当好的划分,可以在开发和部署之间进行。

最初,算法是在一大组样本数据上训练的,这通常需要一个快速强大的机器或集群,但然后将训练好的网络部署到需要实时解释真实数据的应用程序中,这非常适合低功耗的分布式系统。毫无疑问,在这个部署或“推理”阶段,我们看到了向本地处理或边缘计算的转变,如果你想用最新的术语来说,就是现在。

这是一件好事。最近,马萨诸塞大学阿姆赫斯特分校的研究人员为训练几种常见的大型人工智能模型进行了生命周期评估。他们发现,这一过程可以排放相当于超过 62.6 万磅的二氧化碳——几乎是普通美国汽车一生排放量的五倍。

Source: Strubell et al. (📊: MIT Technology)

现在我已经听到了很多关于这项研究的消息,我对它有一些问题,以及它如何看待机器学习。首先,它关注的机器学习类型是自然语言处理(NLP)模型,这是社区中正在发生的事情的一小部分。

但这也是基于他们自己的学术工作,他们的最后一篇论文,他们发现建立和测试最终论文价值模型的过程需要在六个月的时间内训练 4789 个模型。这不是我在现实世界中训练和建立任务模型的经验。这种分析到目前为止还不错,但是它忽略了一些关于如何使用模型的事情,关于开发和部署这两个阶段。

因为使用一个经过训练的模型并不需要花费任何资源来训练它,就像软件一样,一旦经过训练,模型就不再是实物了。它不是一个物体。

一个人使用它并不能阻止其他人使用它。

你必须将沉没成本分摊给使用它的每个人或每个对象——可能是数千甚至数百万个实例。在一些会被大量使用的东西上投入很多是可以的。这也忽略了这些模型可能存在多久的事实。

我成年后的第一份工作是在一家现已倒闭的国防承包商工作,当时我刚从大学毕业。在那里,除了其他事情,我建立了视频压缩的神经网络软件。要明确的是,这是在第一次,也许是第二次,机器学习流行的时候,回到 90 年代初,那时机器学习还被称为神经网络。

我围绕神经网络构建的压缩软件在视频流中留下了相当具体的假象,如今我仍不时在视频中看到某些大型制造商的产品中出现这些假象,这些制造商可能在国防承包商破产后以低价收购了该承包商的知识产权。

那些网络,大概现在被埋在一个包裹在黑盒子里的软件堆栈的底部,外面写着“这里是魔法”——我留下的文档可能是那么糟糕——因此仍然存在,大约 25 到 30 年后。

这使得接近预先训练好的模型变得相当重要,也就是俗称的“模型动物园”。因为当你在一个训练过的模型和一个二进制文件,模型被训练过的数据集和源代码之间做类比时。事实证明,这些数据对你——或者至少对大多数人——没有训练好的模型有用。

因为让我们现实一点。机器学习最近成功背后的秘密不是算法,这种东西已经潜伏在后台几十年了,等待计算赶上来。相反,机器学习的成功在很大程度上依赖于谷歌等公司设法建立的训练数据语料库。

在很大程度上,这些训练数据集是秘方,由拥有它们的公司和个人紧密持有。但这些数据集也变得如此之大,以至于大多数人,即使他们有,也无法存储它们,或基于它们训练新的模型。

所以不像软件,我们想要源代码而不是二进制代码,我实际上认为对于机器学习,我们大多数人想要模型,而不是数据。我们大多数人——开发人员、硬件人员——应该着眼于推理,而不是训练。

公平地说,我现在先声明这是一个相当有争议的观点。

然而,正是预训练模型的存在,让我们能够在机器学习的基础上轻松快速地构建原型和项目。这是那些不关注机器学习,而只想把事情做好的人真正想要的。

A retro-rotary phone powered by AIY Projects Voice Kit and a Raspberry Pi. (📹: Alasdair Allan)

直到去年,中端单板计算机,如 Raspberry Pi,还在努力达到其能力的极限,在不与云通信的情况下,执行相当简单的任务,如热词语音检测。然而,在过去的一年里,事情发生了很大的变化。

因为在过去一年左右的时间里,人们意识到并不是所有的事情都可以或者应该在云中完成。旨在以大幅提高的速度运行机器学习模型的硬件的到来,以及在相对较低的功耗范围内,不需要连接到云,开始使基于边缘的计算对许多人来说更具吸引力。

围绕边缘计算的生态系统实际上已经开始感觉到足够成熟,真正的工作终于可以完成了。这就是加速器硬件的用武之地,比如谷歌的 Coral Dev Board,这些都是领先的指标。

The Coral Dev Board from Google. (📷: Alasdair Allan)

在这个可笑大小的散热器下面是一个叫做边缘 TPU 的东西。这是我们在过去六个月左右看到的定制硅浪潮的一部分。旨在加速边缘的机器学习推理,不需要云。不需要网络。拿数据来说。根据数据采取行动。把数据扔掉。

但这是一个关于数据隐私的完全不同的话题。

The Edge TPU performance demo. On the left we have MobileNet SSD model running on the Edge TPU, on the right we have the same model running on the CPU of the Dev Board, a quad-core ARM Cortex A53. The difference is dramatic, inferencing at around 75 frames per second, compared to 2 frames per second.

新一代定制硅的差异是巨大的,目前市场上有谷歌、英特尔和英伟达的硬件,较小公司的硬件即将推出,或已经投入生产。

其中一些旨在加速现有的嵌入式硬件,如 Raspberry Pi,而另一些则设计为模块上系统(SoM)单元的评估板,将于今年晚些时候量产。

An edge computing hardware zoo. Here we have the Intel Neural Compute Stick 2 (left, top), a Movidus Neural Compute Stick (left, bottom), the NVIDIA Jetson Nano (middle, top), a Raspberry Pi 3, Model B+ (middle, bottom), a Coral USB Accelerator (right, top), and finally the Coral Dev Board (right, bottom).

但在我们研究定制芯片之前,我们应该先看看树莓派。直到最近树莓 Pi 3 的型号 B+ 是你能买到的最快的树莓 Pi,它是围绕 64 位四核 ARM Cortex-A53 构建的,主频为 1.4GHz。你应该记住 Cortex-A53 不是一个性能核心,它被设计为一个中档核心,为了提高效率。

在上安装 TensorFlow 的树莓 Pi 曾经是一个困难的过程,然而到了去年年中,一切都变得容易多了。

**$** sudo apt-get install libatlas-base-dev
**$** sudo apt-get install python3-pip
**$** pip3 install tensorflow

然而,它实际上有点有趣,很难找到一个关于如何做推理的好教程。你会发现很多关于“如何开始张量流”的教程都在谈论训练模型,有些甚至在你训练完模型后就停止了。他们懒得用它。

我觉得这有点令人费解,大概这说明了目前围绕机器学习的社区文化。仍然有点模糊,学术性质的。你会在密码学中看到类似的怪异之处,很多关于数学的讨论,却很少使用它

无论如何,当你使用一个物体检测模型,比如 MobileNet,你期望返回一个边界框时,这大概就是你对一幅图像进行推理的方式。

def inference_tf(image, model, label):
  labels = ReadLabelFile(label) with tf.gfile.FastGFile(model, 'rb') as f:
  graph_def = tf.GraphDef()
  graph_def.ParseFromString(f.read()) with tf.Session(config=tf_config) as sess:
  sess.graph.as_default()
  tf.import_graph_def(graph_def, name='') picture = cv2.imread(image)
  initial_h, initial_w, channels = picture.shape
  frame = cv2.resize(picture, (300, 300))
  frame = frame[:, :, [2, 1, 0]]  # BGR2RGB
  frame = frame.reshape(1, frame.shape[0], frame.shape[1], 3) **out = sess.run([sess.graph.get_tensor_by_name('num_detections:0'),
              sess.graph.get_tensor_by_name('detection_scores:0'),
              sess.graph.get_tensor_by_name('detection_boxes:0'),
              sess.graph.get_tensor_by_name('detection_classes:0')],
              feed_dict={'image_tensor:0': frame})** num_detections = int(out[0][0])
  for i in range(num_detections):
    classId = int(out[3][0][i])
    score = float(out[1][0][i])
    print(labels[classId], 'score = ', score)

给我们的代码一个包含两个可识别对象的测试图像,一个香蕉和一个苹果,给了我们合理形状的边界框。

Our test image 🍎🍌and resulting bounding boxes.

当使用谷歌的 MobileNet 模型 v2 和 v1 对进行基准测试时,运行代码给我们大约每秒 2 帧。现在,v1 模型的处理器密集程度比 v2 稍低,通常返回的检测结果可信度也稍低。我还使用了一种叫做“深度方向可分离卷积”的东西来减少模型的大小和复杂性,这样会降低检测的可信度,但会加快速度。无论如何,每秒 2 帧并不太好。但是它给了我们一个码尺来查看加速器硬件。

现在,英特尔率先向市场推出旨在加速机器学习的定制芯片。他们实际上远远领先于其他人,因为他们收购了一家名为 Movidius 的初创公司,然后在 2016 年重新命名了他们的芯片。采用有点缓慢,但定制硅已经在许多地方出现,大多数你看到宣传自己为机器学习加速器的板、卡、棒和其他部件实际上都基于它。

我们来看看英特尔自己的产品,叫做神经计算棒。事实上,已经有两代英特尔硬件围绕两代 Movidius 芯片发展起来。

我的桌子上有这两个,不出所料,我是一个早期采用者。

The Intel Neural Compute Stick 2. (📷: Alasdair Allan)

现在事情开始变得有点棘手了。因为不幸的是,你不能只在英特尔的硬件上使用 TensorFlow。你必须使用他们的 OpenVINO 框架,当然这意味着你不能只是使用现成的 TensorFlow 模型。

幸运的是,你可以将 TensorFlow 模型转换为 OpenVINO 的 IR 格式,这很好,因为如果你试图比较事情的时间,你可能会希望所有东西都或多或少保持相同,这意味着我真的需要在这里和其他地方使用相同的模型。然而,这被证明是一个症结,因为我们需要转换 TensorFlow 模型的软件不包括在安装在树莓 Pi 上的 OpenVINO 工具包的精简版本中。

这意味着我们需要一台运行 Ubuntu Linux 并安装了 OpenVINO 的 x86 机器。幸运的是,我们不需要连接神经计算棒。我们只需要一个完整的 OpenVINO 安装,我们可以在云中完成。因此,最简单的方法是在像数字海洋这样的云提供商上启动一个实例,然后在云实例上安装 OpenVINO 工具包并运行模型优化器,这是一款可以将我们的 TensorFlow 模型转换为英特尔的 OpenVINO IR 格式的软件。

不幸的是,事实证明将模型从 TensorFlow 转换到 OpenVINO 是一种黑色艺术,并且除了最基本的模型之外,说明并没有真正涵盖如何转换任何东西。不是公式化的。据我所知,获得这方面帮助的最好也是唯一的地方是英特尔开发人员专区的计算机视觉论坛。整个事情非常令人沮丧,需要对你要转换的模型的细节有一个适度深入的理解。

但是一旦你最终转换了你的模型,你就可以用你的图像来反对它。代码略有不同,但只有在细节上,基本内容是一样的。

def inference_openvino(image, model, weights, label):
  labels = ReadLabelFile(label) plugin = IEPlugin(device="MYRIAD")
  net = IENetwork(model=model, weights=weights) input_blob = next(iter(net.inputs))
  out_blob = next(iter(net.outputs)) exec_net = plugin.load(network=net) picture = cv2.imread(image)
  initial_h, initial_w, channels = picture.shape
  frame = cv2.resize(picture, (w, h))
  frame = frame.transpose((2, 0, 1)) 
  frame = frame.reshape((n, c, h, w)) **res = exec_net.infer(inputs={input_blob: frame})** if res:
   res = res[out_blob]
   for obj in res[0][0]:
     if ( obj[2] > 0.6):
       class_id = int(obj[1])
       print(labels[class_id], 'score = ', obj[2])

这里我们得到了更好的性能,大约每秒 10 帧。因此,通过将您的推理卸载到英特尔的 Movidius 芯片上,我们看到了 5 倍的改进。尽管你应该记住我们在这里对神经计算棒并不完全公平,但 Raspberry Pi 3 只有 USB 2,而神经计算棒是 USB 3 设备。会有节流问题,所以你看不到全速优势,你可以看到。

The NVIDIA Jetson Nano. (📷: Alasdair Allan)

接下来是 NVIDIA Jetson Nano 。围绕一个 64 位四核 Arm Cortex-A57 CPU 运行在 1.43GHz,旁边是一个 NVIDIA Maxwell GPU 和 128 CUDA 核心。这是一个相当重的硬件,它真的需要可笑大小的散热器。

现在,理论上我们可以将 TensorFlow 模型放在 NVIDIA 硬件上,但事实证明,虽然它可以工作,但一切都运行得非常慢。傻乎乎地慢慢。看着计时,我有点怀疑“本地”TensorFlow 是否真的被卸载到 GPU 上。如果你想让事情快速运行,你需要使用 NVIDIA 的 TensorRT 框架优化你的 TensorFlow 模型,可以预见的是这是愚蠢的困难。虽然实际上不像试图使用英特尔的 OpenVINO 工具包那样不透明。

TensorFlow (on the left, dark blue bars) and TensorRT models (on the right, the light blue bars).

然而,在使用 TensorRT 优化您的模型后,事情进行得更快了,Jetson Nano 具有大约每秒 15 帧的推理性能。

The Coral Dev Board from Google. (📷: Alasdair Allan)

回到 Coral Dev 板。该板是围绕 ARM 四核 Cortex-A53 构建的,带有一个可移动的模块上系统,带有谷歌的 Edge TPU 。这是他们的加速器硬件做所有的工作。Dev 板本质上是 EdgeTPU 的演示板。但是,与英特尔和 Movidius 不同的是,看起来谷歌并不打算只销售硅片。如果你想在 TPU 边缘地区制造产品,你必须在 SoM 上购买,今年晚些时候它将会大量上市。

The Coral USB Accelerator. (📷: Alasdair Allan)

然而,你也可以在类似神经计算棒的形状因子中获得 EdgeTPU,尽管谷歌的 USB 加速器棒有一个 USB-C 连接器。

可以预见的是,你当然不能只使用现成的张量流模型。Coral hardware 希望 TensorFlow Lite 模型能够在 Edge TPU 上运行。

这是量化第一次出现。TensorFlow Lite 旨在在移动和嵌入式硬件上运行特别优化(量化)的模型。神经网络的量化使用允许降低权重的精度表示的技术,并且可选地,激活 s 用于存储和计算。

本质上,我们用 8 位来表示张量,而不是 32 位数字。这使得低端硬件上的事情更容易,但也使得硬件上的事情更容易优化,因此有了边缘 TPU。

一旦您将 TensorFlow 模型转换为 TensorFlow Lite,这与您的预期一样痛苦,并且只适用于以“量化感知”方式训练的模型。你必须把模型扔给 EdgeTPU 编译器。这曾是网络版,但现在也有了离线版。

def inference_edgetpu(image, model):
   engine = DetectionEngine(model)
   labels = ReadLabelFile(label) img = Image.open(image)
   initial_h, initial_w = img.size
   frame = img.resize((300, 300)) **ans = engine.DetectWithImage(frame, threshold=0.05,
                                relative_coord=False, top_k=10)** if ans:
     for obj in ans:
       print(labels[obj.label_id], 'score = ', obj.score)

另一方面,一旦你有了 TensorFlow Lite 格式的模型,使用推理机的代码就非常简单了。运行速度也快了很多,我们在这里看到的是每秒 50 到 60 帧。

我们也是吗?嗯,看起来这个 …

谷歌的 EdgeTPU 击败了所有竞争者,甚至当我通过 Raspberry Pi 上的 USB 2 连接 USB 加速器而不是使用完整的 USB 3 连接来抑制它时。当连接到 USB 3 时,我希望它的性能或多或少与开发板相当。

不出所料,Jetson Nano 位居第二,两代英特尔硬件都在后面,虽然他们有先发优势,但这也意味着硬件时代开始显现。

Inferencing speeds in milli-seconds for MobileNet SSD V1 (orange) and MobileNet SSD V2 (red) across all tested platforms. Low numbers are good!

那么,优势 TPU 硬件胜出?

不,这么快。Coral 硬件的一大优势是量化,如果我们在其他平台上使用 TensorFlow Lite 会发生什么。嗯,它在英特尔硬件上根本不能工作,只有 OpenVINO 支持。

然而,尽管现在还为时尚早,TensorFlow Lite 最近引入了对 GPU 推理加速的支持。使用具有 GPU 支持的 TensorFlow Lite 运行模型应该可以减少在 Jetson Nano 上进行推理所需的时间。这使得 NIVIDIA 和 Google 平台之间的差距有可能在未来缩小。据我所知,大约一周前,他们在努力追捕。

但我们能做的,是再看看树莓派。

可惜 Google 维护的官方 TensorFlow wheel 没有收录 TensorFlow Lite,真的不知道为什么。但幸运的是,有一个社区维护的轮子可以做到这一点。

**$** sudo apt-get update
**$** sudo apt-get install build-essential
**$** sudo apt-get install git
**$** sudo apt-get install libatlas-base-dev
**$** sudo apt-get install python3-pip
**$** git clone [https://github.com/PINTO0309/Tensorflow-bin.git](https://github.com/PINTO0309/Tensorflow-bin.git)
**$** cd Tensorflow-bin
**$** pip3 install tensorflow-1.13.1-cp35-cp35m-linux_armv7l.whl

使用 TensorFlow Lite 的代码与 TensorFlow 有些不同,比它的老大哥更深入底层。但是看起来差不多。

def inference_tf(image, model, label):
 labels = ReadLabelFile(label) interpreter = tf.lite.Interpreter(model_path=model)
 interpreter.allocate_tensors() input_details = interpreter.get_input_details()
 output_details = interpreter.get_output_details()
 height = input_details[0]['shape'][1]
 width = input_details[0]['shape'][2]
 floating_model = False picture = cv2.imread(image)
 initial_h, initial_w, channels = picture.shape
 frame = cv2.resize(picture, (width, height))
 input_data = np.expand_dims(frame, axis=0) interpreter.set_num_threads(4)
 interpreter.set_tensor(input_details[0]['index'], input_data)
 **interpreter.invoke()** detected_boxes = interpreter.get_tensor(output_details[0]['index'])
 detected_class = interpreter.get_tensor(output_details[1]['index'])
 detected_score = interpreter.get_tensor(output_details[2]['index'])
 num_boxes = interpreter.get_tensor(output_details[3]['index']) for i in range(int(num_boxes)):
   classId = int(detected_class[0][i])
   score = detected_score[0][i]
   print(labels[classId], 'score = ', score)

我们看到原始 TensorFlow 图和使用 TensorFlow Lite 的新结果之间的推理速度增加了大约 2 倍。

左边的黄色条是 TensorFlow Lite 结果,右边的红色条是我们的原始 TensorFlow 结果。似乎对物体检测的可信度没有任何影响。

这让你怀疑是否有量化的东西。因为看起来你真的不需要更多的准确性。

就在上个月,Xnor.ai 终于发布了他们的 AI2GO 平台公测版。他们一直在进行封闭测试,但我听到关于他们的传言已经有一段时间了。他们做的不是 TensorFlow,甚至不是很接近。这是新一代的二进制体重模型。有一些技术白皮书,我目前正在费力地阅读它们。

但是测试这些东西很容易。您可以在线配置一个模型“包”,然后将其下载并安装为 Python wheel。

**$** pip3 install xnornet-1.0-cp35-abi3-linux_armv7l.whl
Processing ./xnornet-1.0-cp35-abi3-linux_armv7l.whl
Installing collected packages: xnornet
Successfully installed xnornet-1.0
**$**

推理就是这么简单,一个图像进去,一个检测到的物体列表和相关的边界框出来。

def inference_xnor(image):
  model = xnornet.Model.load_built_in()
  img = Image.open(image)
  initial_w, initial_h = img.size 
  picture = img.resize((300, 300)) **boxes = model.evaluate(xnornet.Input.rgb_image(picture.size,
                                                 picture.tobytes()))** for box in boxes:
    label = box.class_label.label
    print ('Found', label)

然而,给 AI2GO 我们的测试图像包含两个可识别的物体,一个香蕉和一个苹果,与我们习惯于 TensorFlow 的边界框相比,确实给了我们一些奇怪的边界框。

Our test image 🍎🍌and resulting bounding boxes for TensorFlow (left) and AI2GO binary weight models (right).

这有点不同。没有错。不疯狂。但绝对不一样。

但是把它放在一边,它真的很快,比 TensorFlow Lite 快 2 倍,TensorFlow Lite 比 tensor flow 快 2 倍。

将此结果与我们的原始结果进行比较,这使得树莓 Pi 3,模型 B+几乎可以与除 Edge TPU 之外的所有产品相竞争,当然,Edge 也使用量化模型。

这让你想知道我们是否已经提前开始优化硬件,只是有点太快了。如果我们可以从软件中获得那么多的杠杆作用,那么也许我们需要等到嵌入式领域的软件足够成熟,这样我们才知道优化什么?这也使得微软决定暂时坚持使用 FPGA,而不是像其他人一样推出自己的定制 ASIC,看起来更加明智。

只是一些值得思考的东西…

The new Raspberry Pi 4, Model B. (📷: Alasdair Allan)

这也使得最近刚刚发布的新款树莓 Pi 4,Model B 的到来更加有趣。因为虽然我们还不能运行 TensorFlow Lite,但我们可以让 TensorFlow 和 Xnor.ai AI2GO 框架在新板上工作。

Inferencing time in milli-seconds for the Raspberry Pi 3 (blue, left) and Raspberry Pi 4 (green, right).

NEON 的容量大约是 Raspberry Pi 3 的两倍,对于编写良好的 NEON 内核来说,我们可以期待这样的性能提升。正如预期的那样,我们看到原始 TensorFlow 基准测试和 Raspberry Pi 4 的新结果之间的推理速度提高了大约 2 倍,同时使用 Xnor AI2GO 平台的推理速度也有类似的提高。

然而,当我们从谷歌的 Coral USB 加速器的结果中看到一个更大的变化。Raspberry Pi 4 增加了 USB 3.0,这意味着我们看到原始结果和新结果之间的推理速度提高了大约 3 倍。

Inferencing time in milli-seconds for the for MobileNet v1 SSD 0.75 depth model (left hand bars) and the MobileNet v2 SSD model (right hand bars), both trained using the Common Objects in Context (COCO) dataset with an input size of 300×300. The (single) bars for the Xnor AI2GO platform use their proprietary binary weight model. All measurements on the Raspberry Pi 3, Model B+, are in yellow, measurements on the Raspberry Pi 4, Model B, in red. Other platforms are in green.

相反, Coral USB 加速器通过 USB 2 而不是新的 USB 3 总线连接时的推理时间实际上增加了 2 倍。这个有点令人惊讶的结果很可能是由于新的 Raspberry Pi 的架构变化。随着 XHCI 主机现在位于 PCI Express 总线的远端,系统中潜在地存在更多的延迟。根据流量模式,您可以想象,与流相反,阻塞使用通道可能会更慢。

新的 Raspberry Pi 4 的性能提升使其成为一个非常有竞争力的边缘机器学习推理平台,与所有定制芯片相比,它的表现相当好。

当然,在加速器硬件出现的同时,我们也看到了机器学习在低功耗硬件上的出现。

微控制器,不是微处理器,我到目前为止谈论的定制硅实际上是嵌入式硬件堆栈的高端。

今年早些时候在 TensorFlow 开发峰会上正式宣布的是面向微控制器的 TensorFlow Lite】。这是专门为裸机系统设计的 TensorFlow 发行版,核心库只有 16KB。绝对清楚。虽然玩加速器硬件很有趣,而且它确实很快,但我实际上有点认为这是边缘计算的未来。

现在还为时尚早,但我开始认为,未来一两年,机器学习实践中最大的增长领域很可能是推理,而不是训练。

The OpenMV Cam H7 with an IR camera running blob tracking during ARM Dev Day. (📷: Alasdair Allan)

世界上有很多相机,这可能是我们最好的传感器,加入机器学习会让这些传感器变得更好。在微控制器上运行的 TensorFlow Lite 使这一点变得非常重要,它使这一点在那些相机中已经可用的功率和处理范围内变得容易实现。

你是否认为那是一个好主意是另一回事。

The SparkFun Edge board, top (left) and bottom (right).

SparkFun Edge 是一块旋转起来充当微控制器 TensorFlow Lite 演示板的板。它是围绕 Ambiq Micro 的最新 Apollo 3 微控制器构建的。这是一款 ARM Cortex-M4F,运行频率为 48MHz,采用 96MHz 突发模式,内置蓝牙。

它使用每 MHz 6 到 10 μA 的电流。因此,在深度睡眠模式下,蓝牙关闭时,功耗仅为 1 μA。这是非常低的功耗,Raspberry Pi 的功耗约为 400 mA,相比之下,ESP32 的功耗在 20 到 120 mA 之间。可能是最接近的比较,北欧的 nRF52840 大约消耗 17mA。该主板的核心芯片运行速度最快,功耗预算低于许多微控制器在深度睡眠模式下的功耗,它运行 TensorFlow Lite。

The TensorFlow Lite for Micro-controllers “Yes/No” demo.

在由单个硬币电池供电的微控制器板上进行实时机器学习,应该可以持续几个月,甚至几年。不需要云,不需要网络,没有私人信息离开董事会。

至少在公开市场上,目前这是在我们当前硬件能力的绝对极限下的机器学习,它不会比这更便宜或更弱,至少在最近到之前。

The SparFun Artemis.

这是 SparkFun Artemis 。同样的 Ambiq Apollo 3 芯片,在一个 10 × 15 mm 的模块中,应该在下个月的某个时候通过 FCC/CE 的批准,如果一切顺利,在那之后很快就可以量产了。

它完全兼容Arduino,因为 SparkFun 已经在 Ambiq 的硬件抽象层之上构建了自己的内部 Arduino 内核。现在,您可以在 Arduino 开发环境中使用这款低功耗芯片,如果您需要更低的级别,可以从您的 Arduino 代码进入 HAL。

The “official” Google port of TensorFlow Lite for Micro-controllers.

当然,有人将 TensorFlow 演示和用于微控制器的 TensorFlow Lite 一起移植到 Arduino 开发环境只是时间问题。结果是阿达果先到达那里。

从 Arduino 环境中提供用于微控制器的 TensorFlow Lite 是一件大事,就像更多预训练模型的可用性一样,这将是新兴边缘计算市场中机器学习可访问性的巨大变化。可以说,或许推动 Espressif ESP8266 成功的主要因素之一是 Arduino 兼容性的到来。

看看机器学习是否也会发生同样的事情,这将是一件令人着迷的事情。

链接到以前的基准

如果您对之前基准测试的细节感兴趣。

[## 基准边缘计算

比较 Google、Intel 和 NVIDIA 加速器硬件

medium.com](https://medium.com/@aallan/benchmarking-edge-computing-ce3f13942245) [## 在 Raspberry Pi 上测试 TensorFlow 和 TensorFlow Lite

我最近坐下来对市场上出现的新加速器硬件进行了基准测试,旨在加快…

blog.hackster.io](https://blog.hackster.io/benchmarking-tensorflow-and-tensorflow-lite-on-the-raspberry-pi-43f51b796796) [## 在 Raspberry Pi 上测试 Xnor AI2GO 平台

我最近坐下来对市场上出现的新加速器硬件进行了基准测试,旨在加快…

blog.hackster.io](https://blog.hackster.io/benchmarking-the-xnor-ai2go-platform-on-the-raspberry-pi-628a82af8aea) [## 在新的 Raspberry Pi 4,Model B 上对机器学习进行基准测试

新的树莓派快了多少?这样快多了。

blog.hackster.io](https://blog.hackster.io/benchmarking-machine-learning-on-the-new-raspberry-pi-4-model-b-88db9304ce4)

入门指南的链接

如果你对我在基准测试期间使用的任何加速器硬件感兴趣,我已经为我在分析期间查看的谷歌、英特尔和英伟达硬件整理了入门指南。

[## 手动珊瑚开发板

开始使用谷歌新的 Edge TPU 硬件

medium.com](https://medium.com/@aallan/hands-on-with-the-coral-dev-board-adbcc317b6af) [## 如何使用 Raspberry Pi 将新固件刷新到 Coral Dev 板上

开始使用谷歌新的 Edge TPU 硬件

medium.com](https://medium.com/@aallan/how-to-use-a-raspberry-pi-to-flash-new-firmware-onto-the-coral-dev-board-503aacf635b9) [## 亲手操作 Coral USB 加速器

开始使用谷歌新的 Edge TPU 硬件

medium.com](https://medium.com/@aallan/hands-on-with-the-coral-usb-accelerator-a37fcb323553) [## 开始使用英特尔神经计算棒 2 和 Raspberry Pi

英特尔 Movidius 硬件入门

blog.hackster.io](https://blog.hackster.io/getting-started-with-the-intel-neural-compute-stick-2-and-the-raspberry-pi-6904ccfe963) [## NVIDIA Jetson Nano 开发套件入门

英伟达基于 GPU 的硬件入门

blog.hackster.io](https://blog.hackster.io/getting-started-with-the-nvidia-jetson-nano-developer-kit-43aa7c298797)

衡量绩效:准确性

原文:https://towardsdatascience.com/measuring-performance-accuracy-db54b6dca250?source=collection_archive---------14-----------------------

这篇文章开始了一个关于性能指标的新系列,并简要讨论了最广为人知的方法:准确度= #正确/总数。要点:当数据集平衡时,准确性是最有用的。

考虑一组猫和狗的照片。您想要建立一个模型来确定照片是猫还是狗。假设你有一个总是猜“猫”的天真模型。下面是准确性如何根据数据的偏斜而变化:

正如你所看到的,如果数据集包含的猫的照片比狗的照片多得多,一个总是猜测“猫”的愚蠢模型的准确性仍然很高。这个模型对猫长什么样、狗长什么样一无所知,但如果只看精度,我们可能会认为模型表现不错。

在不平衡数据集上训练机器学习模型的一个风险是,该模型可能会学习总是输出多数类作为其预测。这不是一个有用的模型,但它会达到很高的精度。

以下是关于如何使用准确性来判断机器学习模型的提示:

  • 如果你的类是平衡的(相同数量的猫和狗),那么准确度是一个有用的性能指标
  • 如果你的类是不平衡的,那么计算“朴素模型准确度”为“多数类中的实例数/总实例数”然后,当你查看你的机器学习模型的准确性时,你可以将其与天真模型的准确性进行比较。
  • 如果你有 80 张猫的照片,20 张狗的照片,你的天真准确率是 80%;因此,在这个数据集上达到 80%的机器学习模型并不比天真的模型做得更好
  • 另一方面,一个达到 95%的机器学习模型学到了东西!
  • 如果您的类别不平衡,您还应该计算比准确度更能提供信息的性能指标,例如接收器操作特征下的面积(也称为 AUROC、AUC、c-statistic)或精确度-召回曲线下的面积(AUPRC)

为了准确就是这样!本系列关于性能指标的后续文章将讨论 AUROC 和 AUPRC。

图片来源:小猫、小狗

原载于 2019 年 2 月 16 日http://glassboxmedicine.com

衡量业绩:AUC (AUROC)

原文:https://towardsdatascience.com/measuring-performance-auc-auroc-8c8bbfe9be91?source=collection_archive---------16-----------------------

受试者操作特征(AUROC)下的面积是一个性能指标,可用于评估分类模型。AUROC 会告诉您您的模型是否能够正确排列示例:

  • 对于临床风险预测模型,AUROC 告诉您随机选择的经历了某一事件的患者比随机选择的未经历该事件的患者具有更高的预测风险评分的概率( ref )。
  • 对于二进制手写数字分类模型(“1”对“0”),AUROC 会告诉您随机选择的“1”图像比随机选择的“0”图像具有更高的“1”预测概率

因此,【AUROC 是一个“区分”的性能指标:它告诉你模型区分案例(正面例子)和非案例(负面例子)的能力。)0.8 的 AUROC 意味着该模型具有良好的区分能力: 80%的时候,该模型将正确地为随机选择的有事件的患者分配比随机选择的无事件患者更高的绝对风险。

如何解释 AUROC ( ref )

图:ROC 曲线(根据这幅漫画修改)

上图显示了一些 ROC 曲线示例。给定曲线的 AUROC 就是其下方的面积。

最差的 AUROC 是 0.5,最好的 AUROC 是 1.0。

  • 0.5 的 AUROC(上图中红色虚线下的区域)对应于抛硬币,即无用的模型。
  • 小于 0.7 的 AUROC 是次优性能
  • 0.70–0.80 的 AUROC 是良好的性能
  • 大于 0.8 的 AUROC 是极好的性能
  • AUROC 为 1.0(上图中紫色线下的区域)相当于一个完美的分类器

如何计算 AUROC

AUROC 计算为 ROC 曲线下的面积。ROC 曲线显示了跨不同决策阈值的真阳性率(TPR)和假阳性率(FPR)之间的权衡。有关 TPR、FPR 和决策阈值的回顾,请参见衡量绩效:混淆矩阵。

在绘制的 ROC 曲线中(例如上一节的图),决策阈值是隐含的。决策阈值是显示为轴的而不是。AUROC 本身也没有明确显示;这意味着,显示的 ROC 曲线下的面积。

ROC 曲线的 x 轴是假阳性率,ROC 曲线的 y 轴是真阳性率。

  • ROC 曲线总是从左下角开始,即对应于决策阈值 1 的点(FPR = 0,TPR = 0 )(其中每个例子都被分类为阴性,因为所有预测的概率都小于 1)。)
  • ROC 曲线总是在右上角结束,即对应于决策阈值 0 的点(FPR = 1,TPR = 1 )(其中每个例子都被分类为阳性,因为所有预测的概率都大于 0)。)
  • 创建曲线的中间点是通过针对 1 和 0 之间的不同决策阈值计算 TPR 和 FPR 来获得的。对于一个粗糙的、有角度的“曲线”,你可以只使用几个判决阈值:例如判决阈值[1,0.75,0.5,0.25,0]。对于更平滑的曲线,您可以使用许多决策阈值,例如[1,0.98,0.96,0.94,…,0.08,0.06,0.04,0.02,0]的决策阈值。

下图显示了根据真实数据计算的 ROC 曲线,在 ROC 曲线的锯齿状本质中,使用离散决策阈值更容易理解:

(图来源)

为二元分类任务计算测试集 AUROC 的步骤:

  1. 训练你的机器学习模型
  2. 使用定型模型对测试集进行预测,这样测试集中的每个示例都有介于 0 和 1 之间的分类概率。
  3. 使用测试集的模型输出预测概率,计算不同决策阈值的 TPR 和 FPR,并绘制 ROC 曲线。
  4. 计算 ROC 曲线下的面积。

实际上,您不需要编写代码来手动计算 AUROC。许多编程语言中都有计算 AUROC 的函数。例如,在 Python 中,您可以执行以下操作:

导入 sklearn.metrics

fpr,tpr,thresholds = sk learn . metrics . roc _ curve(y _ true = true _ labels,y_score = pred_probs,pos _ label = 1)#正类为 1;负类为 0
auroc = sk learn . metrics . AUC(FPR,tpr)

首先,向函数 sklearn.metrics.roc_curve()提供基本事实测试集标签(作为向量 y_true)和模型的预测概率(作为向量 y_score ),以获得输出 fpr、tpr 和阈值。fpr 是具有针对不同阈值计算的假阳性率的向量;tpr 是具有不同阈值的计算的真阳性率的向量;thresholds 是一个带有实际阈值的向量,只是在您想要检查它的情况下提供的(在下一个函数中,您不需要显式的 thresholds 向量。)向量 fpr 和 tpr 定义了 ROC 曲线。然后将 fpr 和 tpr 向量传递给 sklearn.metrics.auc()以获得 AUROC 最终值。

何时使用 AUROC

对于不平衡数据,AUROC 比准确性更能提供信息。这是一个非常常见的性能指标,使用各种软件包很容易计算,因此为执行二元分类任务的模型计算 AUROC 通常是一个好主意。

了解 AUROC 的局限性也很重要。AUROC 可能对模型的性能“过于乐观”,这些模型是为反面例子比正面例子多得多的数据集构建的。许多真实世界的数据集都符合这一描述:例如,您可能会认为在从普通人群中抽取的数据集中,健康的人(“疾病阴性”)比患病的人(“疾病阳性”)多得多。)在这些真阴性支配真阳性的情况下,可能很难用 AUROC 来区分两种算法的性能。

为什么?在负样本比正样本多得多的情况下,假阳性数量的大幅提高只会导致假阳性率的小幅变化。这是因为假阳性率被计算为假阳性/(假阳性+真阴性),如果我们在分母中有大量的真阴性,那么仅仅通过改变假阳性就很难改变假阳性率。

假装算法 1 比算法 2 的假阳性少得多(即算法 1 更好)。如果数据有很多真阴性,算法 1 和算法 2 的假阳性率不会有太大差别,它们的 AUROCs 也不会有太大差别。

要点:AUROC 是一个有用的指标,但是你应该知道 AUROC 并没有捕捉到大量负面例子对算法性能的影响。另一个不会被真阴性“淹没”的性能指标是精确召回曲线下面积(AUPRC ),这将在以后的帖子中讨论。

本节的参考(也是额外深入讨论的重要资源):精确召回和 ROC 曲线之间的关系

如果我的模型预测了两个以上的类怎么办?

你可以分别计算每个类的 AUROC,例如,假设你的任务由许多不同的二进制分类任务组成:A 类与非 A 类,B 类与非 B 类,C 类与非 C 类等等。

命名法

受试者操作特征下面积的最常见缩写是“AUC”这是一个糟糕的术语,因为 AUC 只是代表“曲线下面积”(并没有具体说明什么曲线;ROC 曲线仅仅是隐含的)。因此,在这篇文章中,我更喜欢缩写 AUROC。你也可以看到 AUROC 被称为 c 统计量或“一致性统计量”

上图是一个 "auroch" ,不要和一个" AUROC ":)混淆。奥罗克牛是一种现已灭绝的牛,曾经生活在北非、欧洲和亚洲。(杜克+DS 的另一名成员带给你的自然琐事,他在一次关于“AUROC”缩写的讨论中让我想起了 auroch。)

结束了!请继续关注未来关于 AUROC 的表亲 AUPRC 的帖子。

原载于 2019 年 2 月 23 日http://glassboxmedicine.com

测量性能:AUPRC 和平均精度

原文:https://towardsdatascience.com/measuring-performance-auprc-e71819c26425?source=collection_archive---------14-----------------------

精确召回曲线下的面积(AUPRC)是一个有用的性能指标,用于在您非常关心寻找正面例子的问题设置中的不平衡数据。例如,您可能正在构建一个分类器来检测胸部 x 射线中的气胸,并且您希望确保找到所有气胸,而不会错误地将健康肺标记为气胸阳性。如果您的模型获得了完美的 AUPRC,这意味着您的模型找到了所有的阳性样本/气胸患者(完美回忆),而没有意外地将任何阴性样本/健康患者标记为阳性(完美精确)。“平均精度”是计算 AUPRC 的一种特殊方法。

如何解读 AUPRC

Figure: PR Curves, from scikit-learn

上图显示了一些 PR 曲线示例。给定类别的 AUPRC 就是其 PR 曲线下的面积。

解释 AUPRC 比解释 AUROC ( 接收器工作特性下的区域)要稍微棘手一些。这是因为 AUROC 的基线永远是 0.5——一个随机的分类器,或者一次抛硬币,会得到 0.5 的 AUROC。但是对于 AUPRC,基线等于阳性分数(斋藤等人),其中阳性分数计算为(#阳性样本数/总样本数)。这意味着不同的类别有不同的 AUPRC 基线。一个有 12%阳性的类的基线 AUPRC 是 0.12,所以在这个类上获得 0.40 的 AUPRC 是非常好的。然而,98%阳性的类的基线 AUPRC 为 0.98,这意味着在该类上获得 0.40 的 AUPRC 是不好的。

对于许多真实世界的数据集,尤其是医学数据集,阳性率通常小于 0.5,这意味着 AUPRC 的基线值低于 AUROC。因此,AUPRC 的绝对值通常小于 AUROC。例如,可以获得 0.8 的 AUROC 和 0.3 的 AUPRC。我认为这是 AUPRC 在文献中不像 AUROC 那样经常被报道的一个原因。获得 0.8 的性能“听起来更令人印象深刻”,尽管手头上更有意义的数字可能是 0.3 AUPRC。不要让趋势让你气馁;AUPRC 是一个关键的计算指标,适用于对阳性结果进行正确分类非常重要的问题,例如,根据实验室测试预测患者的诊断,或预测患者是否会出现并发症,或预测患者是否需要去医院。你可以同时报告 AUPRC 和 AUROC。

如何计算 AUPRC

AUPRC 计算为 PR 曲线下的面积。PR 曲线显示了不同决策阈值的精确度和召回率之间的权衡。

(注意,“回忆”是真阳性率(TPR)的另一个名称。因此,AUPRC 和 AUROC 都利用 TPR。有关 TPR、精度和决策阈值的回顾,请参见测量性能:混淆矩阵。)

PR 曲线的 x 轴是召回率,y 轴是精确度。这与 ROC 曲线相反,ROC 曲线的 y 轴是召回,x 轴是 FPR。类似于绘制的 ROC 曲线,在绘制的 PR 曲线中,决策阈值是隐含的,并且不显示为单独的轴。

  • PR 曲线开始于左上角,即对应于决策阈值 1 的点(召回= 0,精度= 1 )(其中每个例子都被分类为否定的,因为所有预测的概率都小于 1)。)注意,具有最大输出值的示例的基础事实标签(正或负)对 PR 曲线的外观有很大影响。
  • PR 曲线在右下角结束,这里 recall = 1,precision 较低。这对应于决策阈值 0(其中每个例子都被分类为肯定的,因为所有预测的概率都大于 0。)注意,接近零的召回精度的估计往往具有高方差。
  • 创建 PR 曲线的中间点是通过计算 1 和 0 之间的不同决策阈值的精度和召回率来获得的。对于一个粗略的“角度”曲线,你可以只使用几个决策阈值。对于更平滑的曲线,可以使用许多决策阈值。

为什么要看精度和召回率的权衡?同时考虑召回率和精确度是很重要的,因为您可以使用将所有内容标记为肯定的朴素分类器来实现完美的召回率(但精确度较差),也可以使用将所有内容标记为否定的朴素分类器来实现完美的精确度(但召回率较差)。

为了计算 AUPRC,我们计算 PR 曲线下的面积。有多种方法可以计算 PR 曲线下的面积,包括下梯形估计量、插值中值估计量和平均精度。

我喜欢用平均精度来计算 AUPRC。在 Python 中,平均精度的计算方法如下:

import sklearn.metrics
auprc = sklearn.metrics.average_precision_score(true_labels, predicted_probs)

对于此函数,您需要提供一个基本事实标签的向量(true_labels)和一个来自模型的相应预测概率的向量(predicted_probs)。) Sklearn 会利用这些信息为你计算平均精度。

在函数文档中,“平均精度”将精度-召回曲线总结为在每个阈值达到的精度的加权平均值,召回从前一个阈值的增量作为权重。[……]这种实现是不插值的,不同于使用梯形规则输出精度-召回曲线下的面积,后者使用线性插值,可能过于乐观。”

其他章节参考:Boyd 等人,“精确度-召回曲线下的区域:点估计和置信区间。”

AUPRC &真底片

PR 曲线的一个有趣特征是它们根本不使用真正的负值:

  • Recall = TPR =真阳性/(真阳性+假阴性)。回忆可以被认为是分类器将所有正例正确标记为正例的能力。
  • 精度=真阳性/(真阳性+假阳性)。精确度可以被认为是分类器不将阴性样本错误标记为阳性样本的能力(参考

因为 PR 曲线在任何地方都不使用真负值,AUPRC 不会被数据中的大部分真负值“淹没”。您可以在具有 98%负样本/2%正样本的数据集上使用 AUPRC,它将“关注”模型如何处理 2%正样本。如果模型很好地处理了正例,AUPRC 就会很高。如果模型在正面例子上表现不佳,AUPRC 将会很低。

具有讽刺意味的是,AUPRC 通常在其基线最低时最有用,因为有许多数据集具有大量真阴性,其目标是尽可能好地处理一小部分阳性。

如果我的模型预测了两个以上的类怎么办?

您可以假设您的任务由许多不同的二进制分类任务组成,并计算 A 类与非 A 类、B 类与非 B 类、C 类与非 C 类等的 AUPRC。

总结

  • AUPRC 的计算方法有很多种,包括平均精度。
  • 当一个模型找到所有的正例(完全回忆)而没有意外地将任何负例标记为正例(完全精确)时,它实现了完全 AUPRC。
  • AUPRC 的基线等于阳性分数。如果数据集包含 8%的癌症样本和 92%的健康样本,则基线 AUPRC 为 0.08,因此在这种情况下获得 0.40 的 AUPRC 是很好的!
  • 当你非常关心你的模型正确处理正例时,AUPRC 是最有用的。
  • AUPRC 的计算根本不涉及真负值。

关于特色图片

天平的特色图像从这里的修改为。

原载于 2019 年 3 月 2 日【http://glassboxmedicine.com

衡量绩效:困惑矩阵

原文:https://towardsdatascience.com/measuring-performance-the-confusion-matrix-25c17b78e516?source=collection_archive---------19-----------------------

混淆矩阵是使用模型对数据集的预测来计算的。通过查看混淆矩阵,您可以更好地了解您的模型的优点和缺点,并且可以更好地比较两个备选模型,以了解哪一个更适合您的应用程序。传统上,混淆矩阵是使用模型对保留测试集的预测来计算的。

这是一个混淆矩阵:

列标签“实际阳性”和“实际阴性”是指数据集中的基本事实标签,即手写数字是真正的 1 还是 0,患者是否真正被诊断患有疾病(1)或不是(0),胸部 x 光片是否实际显示肺炎(1)或不是(0)等。

行标签“预测正”和“预测负”指的是您的模型的预测,即您的模型认为标签是什么。

注意混淆矩阵(TPs,FPs,FNs,TNs)内的条目是计数:

  • 真阳性(TPs):模型正确分类为阳性的阳性样本的数量
  • 真实否定(TNs):模型正确分类为否定的否定例子的数量
  • 假阳性(FPs):被模型错误分类为阳性的阴性样本的数量(即被错误分类为“阳性”的阴性样本)
  • 假阴性(FNs):被模型错误分类为阴性的阳性样本的数量(即被错误分类为“阴性”的阳性样本)

真阳性率和假阳性率

您可以使用混淆矩阵来计算真阳性率(TPR)和假阳性率(FPR)。稍后将需要 TPR 和 FPR 来计算接收机工作特性(AUROC)下的面积,AUROC 是一个流行的性能指标。

真阳性率=真阳性/所有阳性=真阳性/(真阳性+假阴性)

假阳性率=假阳性/全部阴性=假阳性/(假阳性+真阴性)

( ref

(在上面的公式中,FNR =假阴性率,TNR =真阴性率,这些是可以从混淆矩阵中计算出来的其他量。)

精度

你也可以使用混淆矩阵来计算精度。稍后将需要精度以及真实的阳性率(也称为“召回”),来计算精度-召回曲线下的面积(AUPRC),这是另一个流行的性能指标。

精度=真阳性/(真阳性+假阳性)

(参考)

决策阈值

决策阈值允许您将预测概率转换为预测标签。如果模型输出概率,则必须使用决策阈值将这些概率转换为预测标签。一旦你有了预测的标签,你就可以计算一个混淆矩阵。您还需要预测标签来计算 AUROC 和 AUPRC,使用不同的决策阈值进行计算。

“决策阈值”就是您选择用来与某个概率进行比较的数字,以决定该概率应该指示正类还是负类。

常见的决策阈值是 0.5,这意味着任何小于 0.5 的概率都被认为是否定类别的一部分,而任何大于 0.5 的概率都被认为属于肯定类别。

然而,实际上你可以选择任何你想要的决策阈值。您可以将决策阈值设为 0.99,这样一个例子的预测概率必须大于 0.99 才能被认为是“肯定的”。这意味着你的大多数例子会被认为是负面的。

极限决策阈值

如果选择决策阈值为 0,则每个示例都将被认为是正面的:

  • 这意味着每个例子要么是真阳性,要么是假阳性
  • 真正的正率将是 1 (TPR = TP / (TP + FN)但 FN = 0,所以 TPR = TP/TP = 1)
  • 假阳性率将是 1 (FPR = FP / (FP + TN)但是 TN = 0,所以 FPR = FP/FP = 1)
  • 精度的值将取决于数据的偏差。如果数据集中实际阳性和实际阴性数量相等,则精度为 0.5(精度= TP / (TP + FP) = 50 / (50+50) = 0.5)。如果实际阳性多得多,精度会大于 0.5;如果实际底片多得多,精度会小于 0.5。

如果选择决策阈值 1,则每个示例都将被认为是负面的:

  • 这意味着每个例子要么是真阴性,要么是假阴性
  • 真正的正率将是 0 (TPR = TP / (TP + FN)但是 TP = 0,所以 TPR = 0)
  • 假阳性率将是 0 (FPR = FP / (FP + TN)但是 FP = 0,所以 FPR = 0)
  • 从技术上讲,精度将是未定义的(精度= TP / (TP + FP) = 0/0)

如何选择决策阈值

决策阈值的选择取决于模型的下游应用。

例如:在某些医疗应用中,假阴性可能比假阳性更糟糕,例如,在皮肤病学照片的自动分类中,您不想错过一个黑色素瘤病例。在这种情况下,您希望选择较低的决策阈值,以便将更多的示例分类为阳性,这将降低您的假阴性率,但会增加假阳性率。

例子:想象一下,在一个社会中,预测模型被用来决定罪犯是应该被说服还是被释放。在这种情况下,假阳性可能比假阴性更糟糕,例如,如果模型错误地确定一个无辜的人有罪,并把那个人送进监狱,那就太糟糕了。(谢天谢地,这一场景仍在反乌托邦科幻小说中,至少目前如此……)

AUROC 和 AUPRC 曲线还可以帮助您直观地了解不同决策阈值导致的权衡,并帮助您为模型的下游应用选择一个好的决策阈值。

其他名称

  • 真正的阳性率也称为敏感度、回忆率或命中率
  • 精确度也称为阳性预测值(PPV)

混乱矩阵的更多细节

维基百科上有一篇关于混淆矩阵的伟大文章。它包括关于可以从混淆矩阵计算的其他量的更多细节,包括特异性(也称为选择性或真阴性率)和阴性预测值。

敬请关注未来关于 AUROC 和 AUPRC 的帖子,这两个都是机器学习模型非常有用的性能指标。

原载于 2019 年 2 月 17 日http://glassboxmedicine.com

营销分析——衡量客户终身价值(CLTV)

原文:https://towardsdatascience.com/measuring-users-with-customer-lifetime-value-cltv-94fccb4e532e?source=collection_archive---------13-----------------------

CLTV 客户生命周期作为营销技术堆栈

CLTV 测量到设备有效的营销策略

【https://sarit-maitra.medium.com/membership 号

C 客户生命周期价值(CLTV)是一项定量分析,是现代以客户为中心的商业场景中最重要的指标之一。多年来,它一直是直复营销的主要概念,并在营销领域得到越来越多的考虑。在这里,我们将试验一个可实施的 CLTV 模型,该模型对于市场细分和为获取、保留和交叉销售分配营销资源是有用的。模型的选择是基于系统的理论分类法和嵌入客户行为的假设。

数据收集:

相关数据总是任何预测的基础,CLTV 也不例外。以下是我们可能想要回答的一些例子/问题:

  • 每位特定顾客已经在你的商店消费了多少钱?
  • 每个特定的客户实际上已经成为客户多久了?
  • 每个特定客户的年龄是多少?年龄是客户画像的重要组成部分。
  • 每位顾客对折扣和优惠的反应如何?如果我们知道谁更有可能做出反应,我们就可以制定策略,将营销资金准确地花在这些人身上,并得到一个结果。

业务问题:

本文的目的在于研究下面提到的商业问题。我将演示如何使用线性回归为 CLTV 建立预测模型。

  • 如何识别最赚钱的客户?
  • 一个公司怎样才能提供最好的东西并获得最大收益?
  • 如何细分盈利客户?
  • 需要花费多少预算来获得客户?

计算 CLTV 的方法很少。

让我们用一些简单的等式:

  • 客户价值=平均订单价值(AOV)购买频率*

  • 流失率:流失率是没有再次订购的客户的百分比。
  • 客户寿命= 1/流失率
  • 流失率= 1-重复率

让我们获取数据并深入了解数据中的信息。

数据的统计分布:

条形图清楚地显示,我们来自英国的业务数量最多。从描述性统计数据中,我们可以看出,这一部分的数量处于负值。这实际上是不可能的。这可能是订单取消或退货。因此,我们需要过滤大于零的数量。此外,我们还将为 CLTV 分析过滤所需的列。我们需要数据集中的 CustomerID、InvoiceDate、InvoiceNo、数量和单价。

data = uk_data[(uk_data[‘Quantity’]>0)]data=uk_data[[‘CustomerID’,’InvoiceDate’,’InvoiceNo’,’Quantity’,’UnitPrice’]]
data[‘TotalPurchase’] = uk_data[‘Quantity’] * uk_data[‘UnitPrice’]

现在,我们将计算(a)当前日期和每个客户最后一次购买日期之间的天数,(b)每个客户的订单数量,(c)每个客户的购买价格总和。还可以通过重命名列来进一步纯化数据。

data_group= data.groupby(‘CustomerID’).agg({‘InvoiceDate’: lambda date: (date.max() — date.min()).days,
 ‘InvoiceNo’: lambda num: len(num),
 ‘Quantity’: lambda quant: quant.sum(),
 ‘TotalPurchase’: lambda price: price.sum()})# Change the name of columns
data_group.columns=[‘num_days’, ’num_transactions’, ’num_units’, ’spent_money’]
data_group.head()

CLTV 使用公式:

现在,我们将使用前面提到的公式计算 CLTV。

# Average Order Value
data_group[‘avg_order_value’]=uk_data_group[‘spent_money’]/uk_data_group[‘num_transactions’]#Purchase Frequency purchase_frequency=sum(uk_data_group[‘num_transactions’])/uk_data_group.shape[0]# Repeat Rate
repeat_rate=uk_data_group[uk_data_group.num_transactions > 1].shape[0]/uk_data_group.shape[0]#Churn Rate
churn_rate=1-repeat_rate
purchase_frequency,repeat_rate,churn_rate

Output: (90.37107880642694,0.9818923743942872,0.018762577

利润率和 CLTV:

让我们假设企业赚取 25%的利润。

# Profit Margin
data_group[‘profit_margin’]= data_group[‘spent_money’]*0.25# Customer Value
data_group[‘CLTV’]= data_group[‘avg_order_value’]*purchase_frequency)/churn_rate#Customer Lifetime Value
data_group[‘cust_lifetime_value’]=data_group[‘CLTV’]*data_group[‘profit_margin’]

CLTV 的预测模型:

现在我们将使用线性回归模型来预测 CLTV。在将数据推至回归模型之前,我们需要做一些数据准备。

uk_data['month_yr'] = uk_data['InvoiceDate'].apply(lambda x: x.strftime('%b-%Y')) # Extract month and year from InvoiceDate.

# creating a pivot table taking the columns as input, and groups the entries into a two-dimensional table in such a way that provides a multidimensional summation of the data.sale=uk_data.pivot_table(index=[‘CustomerID’],columns=[‘month_yr’],values=’TotalPurchase’,aggfunc=’sum’,fill_value=0).reset_index()sale[‘CLV’]=sale.iloc[:,2:].sum(axis=1) # sum all the months sale
sale.head()

现在,让我们为现有客户建立一个回归模型。我们需要一组因变量(y)和自变量(X)。因此,我们将把过去六个月的数据作为自变量,把三年的总收入作为因变量,然后按照通常的 ML 过程分割训练和测试数据。

X=sale[[‘Dec-2011’,“Nov-2011”, ‘Oct-2011’,“Sept-2011”,’Aug-2011',’Jul-2011']]
y=sale[[‘CLV’]]#split training set and test set
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)linreg = LinearRegression() # instantiate
linreg.fit(X_train, y_train) # fitting the model to the training datay_pred = linreg.predict(X_test) # make predictions on the testing setprint(linreg.intercept_)
print(linreg.coef_)

模型评估:

让我们打印 R 平方,这是由模型解释的方差的比例,平均绝对误差(MAE),均方误差(MSE),均方根误差(RMSE)。

print(“R-Square:”,metrics.r2_score(y_test, y_pred))
print(“MAE:”,metrics.mean_absolute_error(y_test,y_pred))
print(“MSE”,metrics.mean_squared_error(y_test, y_pred))
print(“RMSE:”,np.sqrt(metrics.mean_squared_error(y_test, y_pred)))

r 平方值:0.96486386866

梅伊:56860 . 68686868686

最小二乘误差 21 . 58686868686

RMSE:18966 . 868686868686

当部署模型时,ML 算法有助于理解模式;它还会根据客户的 CLTV 预测对他们进行分类。考虑到 CLTV 可以找出最有利可图的客户,营销策略在这里很重要,但我们如何从他们那里获利,将取决于所采用的营销策略。此外,忠诚度计划可以基于这些见解来制定。

局限性:

目前还不清楚如何使用回归模型来预测未来很长一段时间内的购买者行为动态,然后将其全部绑定到每个客户的现值。

购买行为需要两个阶段——(a)定义 RFM 变量 1 和(b)得出因变量的值。如果我们能够仅仅使用第一阶段的数据来预测未来的购买行为,那就更好了。此外,最令人感兴趣的是利用所有可用数据进行模型校准,而不使用任何数据来创建回归型分析的因变量。

RFM 变量只是潜在行为特征的不完善指标。不同的数据“切片”将产生不同的 RFM 变量值,从而产生不同的评分模型参数。当我们利用一个时期的观察数据来预测未来的行为时,这具有重要的意义。

结论

LR 接近完美地预测了普通顾客一生中的消费。CLTV 帮助设计一个有效的商业计划,也提供了一个扩大业务的机会。然而,正如已经讨论过的,很多将取决于营销策略来获取利润。一般来说,营销自动化平台管理客户生命周期。营销平台协调营销活动,同时也自动化销售线索和客户在渠道中的流动。营销部门使用这些软件应用程序来计划、协调、执行、管理和衡量他们在多个渠道的营销活动,并自动执行重复性任务。

我这里可以连接

MeCab 用法并将用户词典添加到 MeCab

原文:https://towardsdatascience.com/mecab-usage-and-add-user-dictionary-to-mecab-9ee58966fc6?source=collection_archive---------19-----------------------

这是一个英语 MeCab 教程,面向那些不在 - 说日语的人的程序员

Photo by David Emrich on Unsplash

如果你是一个在日本工作的 NLP 工程师,你一定听说过文本分割库 MeCab。这个库在日本的学术界和工业界都被广泛使用。如果你的母语不是日语,使用这个工具可能会有困难,因为文档大部分是由日本人写的。所以我写这篇教程来减轻负担。

装置

Environment:
- macOS Mojave 10.14.6
- Xcode: 11.0 
- python 3
- pip 19.1

安装 MeCab 和字典。没有这些依赖项,mecab-python3 就无法工作。

$ brew install mecab
$ brew install mecab-ipadic

您可以运行mecab命令来尝试交互界面

$ mecab
おはようございます
おはよう    感動詞,*,*,*,*,*,おはよう,オハヨウ,オハヨー
ござい   助動詞,*,*,*,五段・ラ行特殊,連用形,ござる,ゴザイ,ゴザイ
ます  助動詞,*,*,*,特殊・マス,基本形,ます,マス,マス
EOS

安装 SWIG 。我们必须安装这个库,否则,安装 mecab-python3 时会出现错误。

$ brew install swig$ swig -versionSWIG Version 4.0.1Compiled with clang++ [x86_64-apple-darwin18.6.0]Configured options: +pcrePlease see [http://www.swig.org](http://www.swig.org) for reporting bugs and further information

最后安装 mecab-python3。

$ pip install mecab-python3Collecting mecab-python3
  Downloading [https://files.pythonhosted.org/packages/97/9f/3e5755e0488f608e3c2d18a0f3524434ebf36904b8fd4eec74a3e84416a9/mecab_python3-0.996.2-cp36-cp36m-macosx_10_6_intel.whl](https://files.pythonhosted.org/packages/97/9f/3e5755e0488f608e3c2d18a0f3524434ebf36904b8fd4eec74a3e84416a9/mecab_python3-0.996.2-cp36-cp36m-macosx_10_6_intel.whl) (14.1MB)
     |████████████████████████████████| 14.1MB 2.4MB/s 
Installing collected packages: mecab-python3
Successfully installed mecab-python3-0.996.2

安装程序已完成。我们可以写个剧本试试。

import MeCab
mecab = MeCab.Tagger("-Ochasen") # Create a MeCab object
malist = mecab.parse("NECが二位、東芝がモトローラを抜いて二年ぶりに三位になる。") # morphological analysis
print(malist)# output
NEC  エヌイーシー    NEC  名詞-固有名詞-組織
が      ガ      が      助詞-格助詞-一般
二      ニ      二      名詞-数
位      イ      位      名詞-接尾-助数詞
、      、      、      記号-読点
東芝    トウシバ        東芝    名詞-固有名詞-組織
が      ガ      が      助詞-格助詞-一般
モトローラ      モトローラ      モトローラ      名詞-固有名詞-組織
を      ヲ      を      助詞-格助詞-一般
抜い    ヌイ    抜く    動詞-自立       五段・カ行イ音便        連用タ接続
て      テ      て      助詞-接続助詞
二      ニ      二      名詞-数
年      ネン    年      名詞-接尾-助数詞
ぶり    ブリ    ぶり    名詞-接尾-一般
に      ニ      に      助詞-格助詞-一般
三      サン    三      名詞-数
位      イ      位      名詞-接尾-助数詞
に      ニ      に      助詞-格助詞-一般
なる    ナル    なる    動詞-自立       五段・ラ行      基本形
。      。      。      記号-句点
EOS

添加用户词典

根据官方文件显示,添加自定义词典有 2 种方式,更改“系统词典”和添加“用户词典”。如果我们改变“系统字典”,我们必须编译字典并重新安装。所以我们选择添加一个新的“用户词典”。

确定格式

首先,我们必须将自定义词典写入一个 CSV 文件,格式如下。

表層形,左文脈 ID,右文脈 ID,コスト,品詞,品詞細分類 1,品詞細分類 2,品詞細分類 3,活用型,活用形,原形,読み,発音Surface type, left context ID, right context ID, cost, part of speech, sub POS 1, sub-POS 2, sub-POS 3, conjugation type, conjugation form, original form, ruby, pronunciation

Each line contains 13 features. For example, if we want to add noun words (活用しない語), like location, people’s name, we could write like below.

工藤,1223,1223,6058,名詞,固有名詞,人名,名,*,*,くどう,クドウ,クドウ

But if we want to add adjectives or verb (活用する語), we have to add all their conjugation type (活用型) and conjugation forms (活用形). See the below example for the adjective “いそがしい”.

いそがしい,120,120,6078,形容詞,自立,*,*,形容詞・イ段,基本形,いそがしい,イソガシイ,イソガシイ
いそがし,128,128,6080,形容詞,自立,*,*,形容詞・イ段,文語基本形,いそがしい,イソガシ,イソガシ
いそがしから,136,136,6079,形容詞,自立,*,*,形容詞・イ段,未然ヌ接続,いそがしい,イソガシカラ,イソガシカラ
いそがしかろ,132,132,6079,形容詞,自立,*,*,形容詞・イ段,未然ウ接続,いそがしい,イソガシカロ,イソガシカロ
いそがしかっ,148,148,6078,形容詞,自立,*,*,形容詞・イ段,連用タ接続,いそがしい,イソガシカッ,イソガシカッ
いそがしく,152,152,6078,形容詞,自立,*,*,形容詞・イ段,連用テ接続,いそがしい,イソガシク,イソガシク
いそがしくっ,152,152,6079,形容詞,自立,*,*,形容詞・イ段,連用テ接続,いそがしい,イソガシクッ,イソガシクッ
いそがしゅう,144,144,6079,形容詞,自立,*,*,形容詞・イ段,連用ゴザイ接続,いそがしい,イソガシュウ,イソガシュウ
いそがしゅぅ,144,144,6079,形容詞,自立,*,*,形容詞・イ段,連用ゴザイ接続,いそがしい,イソガシュゥ,イソガシュゥ
いそがしき,124,124,6079,形容詞,自立,*,*,形容詞・イ段,体言接続,いそがしい,イソガシキ,イソガシキ
いそがしけれ,108,108,6079,形容詞,自立,*,*,形容詞・イ段,仮定形,いそがしい,イソガシケレ,イソガシケレ
いそがしかれ,140,140,6079,形容詞,自立,*,*,形容詞・イ段,命令e,いそがしい,イソガシカレ,イソガシカレ
いそがしけりゃ,112,112,6079,形容詞,自立,*,*,形容詞・イ段,仮定縮約1,いそがしい,イソガシケリャ,イソガシケリャ
いそがしきゃ,116,116,6079,形容詞,自立,*,*,形容詞・イ段,仮定縮約2,いそがしい,イソガシキャ,イソガシキャ
いそがし,104,104,6080,形容詞,自立,*,*,形容詞・イ段,ガル接続,いそがしい,イソガシ,イソガシ

长元音

下面是一个长元音现象的演示。

今日,,,10,名詞,副詞可能,*,*,*,*,今日,キョウ,キョー
労働,,,10,名詞,サ変接続,*,*,*,*,労働,ロウドウ,ロードー

“今日” and “労働” are the surface form. “10” is the cost. Lower cost means this word has a high frequency in the corpus. “名詞” is the POS tag. “一般” is the sub-POS tag, which can be ignored. The final three columns represent “original form”, “ruby”, and “pronunciation”. The ruby character means how a word should be pronounced. But in real conversation, people usually ignore the vowel letters (a e i o u, アイウエオ in Japanse) to pronounce a word easier. This phenomenon usually occurs with long vowels.

在下面的例子中,“ゥ”将被忽略。

キョウ -> キョー
ロウドウ -> ロードー

The Romanji of “今日” is “kyou”. The “o” and “u” are both vowels, so this is a long vowel. When we pronounce “今日”, “u” will be ignored. So the pronunciation becomes “kyo” and “o” produce as a long vowel, /uː/.

使用 CSV 文件扩充字典

对于下面的演示,我构建一个foo.csv文件并输入一些名词。

二位,,,10,名詞,一般,*,*,*,*,*,二位,ニイ,ニイ
三位,,,10,名詞,一般,*,*,*,*,*,三位,サンイ,サンイ

接下来我们需要编译这个 CSV 文件。

Mac(与自制软件一起安装)

$ cd /home/foo/bar # the path where the foo.csv exists
$ /usr/local/Cellar/mecab/0.996/libexec/mecab/mecab-dict-index \
-d /usr/local/lib/mecab/dic/ipadic \
-u foo.dic \
-f utf-8 \
-t utf-8 foo.csv reading foo.csv ... 2
emitting double-array: 100% |###########################################|

选项:

  • d:系统字典目录
  • u:输出用户词典的名称
  • f:CSV 文件的编码
  • t:输出用户字典文件的编码

确保用户字典创建成功。

$ ls 
foo.csv foo.dic

将 foo.dic 移动到一个新目录。

$ mkdir /usr/local/lib/mecab/dic/user_dict
$ mv foo.dic /usr/local/lib/mecab/dic/user_dict

接下来,我们需要添加路径到mecabrc文件。

vim /usr/local/etc/mecabrc

更改如下

; userdic = /home/foo/bar/user.dic
->
userdic = /usr/local/lib/mecab/dic/user_dict/foo.dic

如果您有多个用户字典文件,您可以将它们写在一行中。

userdic = /usr/local/lib/mecab/dic/user_dict/foo.dic, /usr/local/lib/mecab/dic/user_dict/foo2.dic, /usr/local/lib/mecab/dic/user_dict/foo3.dic

好了,就这些。

试试用户词典

$ echo "NECが二位、東芝がモトローラを抜いて二年ぶりに三位になる。" | mecabNEC  名詞,固有名詞,組織,*,*,*,NEC,エヌイーシー,エヌイーシー
が      助詞,格助詞,一般,*,*,*,が,ガ,ガ
二位    名詞,一般,*,*,*,*,*,二位,ニイ,ニイ
、      記号,読点,*,*,*,*,、,、,、
東芝    名詞,固有名詞,組織,*,*,*,東芝,トウシバ,トーシバ
が      助詞,格助詞,一般,*,*,*,が,ガ,ガ
モトローラ      名詞,固有名詞,組織,*,*,*,モトローラ,モトローラ,モトローラ
を      助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
抜い    動詞,自立,*,*,五段・カ行イ音便,連用タ接続,抜く,ヌイ,ヌイ
て      助詞,接続助詞,*,*,*,*,て,テ,テ
二      名詞,数,*,*,*,*,二,ニ,ニ
年      名詞,接尾,助数詞,*,*,*,年,ネン,ネン
ぶり    名詞,接尾,一般,*,*,*,ぶり,ブリ,ブリ
に      助詞,格助詞,一般,*,*,*,に,ニ,ニ
三位    名詞,一般,*,*,*,*,*,三位,サンイ,サンイ
に      助詞,格助詞,一般,*,*,*,に,ニ,ニ
なる    動詞,自立,*,*,五段・ラ行,基本形,なる,ナル,ナル
。      記号,句点,*,*,*,*,。,。,。
EOS

We can see the “二位” and “三位” are recognized as a word.

如果我想知道成本,我们可以改变输出格式。%m是表层形式,%c是成本,%H是逗号分隔的词性、变位、阅读等列表。你可以在这些文件中找到更多细节, EN 版,和 JP 版。

$ echo "NECが二位、東芝がモトローラを抜いて二年ぶりに三位になる。" | mecab -F '%m %c %H\n'NEC 13835 名詞,固有名詞,組織,*,*,*,*
が 3866 助詞,格助詞,一般,*,*,*,が,ガ,ガ
二位 10 名詞,一般,*,*,*,*,*,二位,ニイ,ニイ
、 -2435 記号,読点,*,*,*,*,、,、,、
東芝 1426 名詞,固有名詞,組織,*,*,*,東芝,トウシバ,トーシバ
が 3866 助詞,格助詞,一般,*,*,*,が,ガ,ガ
モトローラ 4897 名詞,固有名詞,組織,*,*,*,モトローラ,モトローラ,モトローラ
を 4183 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
抜い 7346 動詞,自立,*,*,五段・カ行イ音便,連用タ接続,抜く,ヌイ,ヌイ
て 5170 助詞,接続助詞,*,*,*,*,て,テ,テ
二 2914 名詞,数,*,*,*,*,二,ニ,ニ
年 8465 名詞,接尾,助数詞,*,*,*,年,ネン,ネン
ぶり 7451 名詞,接尾,一般,*,*,*,ぶり,ブリ,ブリ
に 4304 助詞,格助詞,一般,*,*,*,に,ニ,ニ
三位 10 名詞,一般,*,*,*,*,*,三位,サンイ,サンイ
に 4304 助詞,格助詞,一般,*,*,*,に,ニ,ニ
なる 5063 動詞,自立,*,*,五段・ラ行,基本形,なる,ナル,ナル
。 215 記号,句点,*,*,*,*,。,。,。
EOS

查看我的其他帖子 中等 分类查看
GitHub:
bramble Xu LinkedIn:徐亮 博客:bramble Xu

参考

  • https://qiita.com/TomOse/items/90a6addda3b0419f40e3
  • https://taku910.github.io/mecab/dic.html
  • https://www.kanjifumi.jp/keyword/chi/
  • https://www . wiki wand . com/en/元音 _ 长度#/Phonemic _ 元音 _ 长度
  • https://rooter.jp/data-format/mecab_user_dictionary/
  • https://github.com/buruzaemon/natto/wiki/Output-Formatting
  • https://taku910.github.io/mecab/format.html

使用 Python 中的深度学习库的媒体偏见检测

原文:https://towardsdatascience.com/media-bias-detection-using-deep-learning-libraries-in-python-44efef4918d1?source=collection_archive---------6-----------------------

Photo by Pablo García on Unsplash

我不止一次遇到过你能马上看出他们政治倾向的新闻故事。这是因为新闻媒体很可能总是有偏见。我在想,如果我们可以用眼睛识别这些模式,那么我们肯定可以建立一种算法,利用文本中的信息来识别书面媒体的偏见。在这份报告中,我将描述我是如何做到这一点的。我使用 Python 环境和 Tensorflow 和 Keras 构建了一个神经网络,能够很好地识别新闻故事是左倾还是右倾。我更进一步,试图不仅识别偏见,还识别故事的出口(或来源)。我将详细描述我用来构建和训练网络的方法,以及我用来可视化结果和性能的方法。开始了。

所有数据均来自 Andrew Thomson 创建的All News数据集。它是免费的,你可以随时下载。它被分成三个大的 CSV 文件,每个文件都包含一个如下所示的表格:

News Outlets raw table

因为我们只对内容和经销店名称感兴趣,所以我们将关注两列。列 3 包含出版物或经销店名称,而 9 包含内容。然后,我们需要提取这些信息并相应地存储起来,以便我们可以继续进行分析。但是首先,让我们导入所有需要的模块(如果需要,为最新版本修改您的代码,例如:TensorFlow 2):

Modules for the pipeline

上面描述的每个文件包含大约 50,000 个条目,因此为了加快分析速度,我们可以提取一部分数据。为了节省时间,我决定用这个简单的技巧随机选择大约 40%的文章(当然你可以改变):

p = 0.4
df = pd.read_csv('articles.csv',header=None,skiprows=lambda i: 1>0 and random.random() > p)

这将从 articles.csv 中提取一小部分数据,等于 p.

下一步可能是我们整个流程中最主观的一步。我们给新闻媒体分配了左或右倾向。为了简单起见,我决定每边只使用两个,并使用allsides.com和mediabiasfactckeck.com来分配他们的偏差。基于从这些网站和其他来源提取的信息,我决定将《大西洋》、《纽约时报》《纽约时报》《纽约邮报》、以及《布莱巴特》归为左偏。然后,我从原始文件中筛选出包含这些网点的所有行,使用:

创造了一系列的故事:

n_s = list(n_s_b.iloc[:,9].values) + list(n_s_p.iloc[:,9].values) \
 + list(n_s_a.iloc[:,9].values) + list(n_s_n.iloc[:,9].values)

请注意, n_s 是一个数组,它只包含根据从上述代码中提取的原始数组中的名称排序的所有故事的内容,因此布莱巴特邮报故事排在第一位,然后是大西洋纽约时报。

太好了!下一步做什么?一个重要的预处理步骤,特别是因为我们正在处理自然语言处理,是删除可能给分析增加噪声的单词。我决定删除经销店的名称,这通常在故事中被提及,因为它会给我们的分析增加“偏见”。这可以通过以下方式简单实现:

n_s = [word.replace('New York Post','') for word in n_s]
n_s = [word.replace('Breitbart','') for word in n_s]
n_s = [word.replace('New York Times','') for word in n_s]
n_s = [word.replace('Atlantic','') for word in n_s]

下一步是创建一个类数组。我们知道每个媒体有多少文章,也知道他们的政治偏见。我们可以创建两个数组,一个用于出口分类器,一个用于偏差分类器,其中:

如果您遵循这些方法,您可以看到 classes_All 是一个长度等于 n_s 的数组,它包含从 1 到 4 的整数,每个整数对应于四个出口中的一个,而 classes_Bias 包含 1 表示被认为向右倾斜的出口,包含 2 表示向左倾斜的出口(请参见前面的代码以进一步理解这一点)。像这样, n_s 是我们的特征数组(已经被清理过),因为它包含一个故事列表,这两个数组是我们的类数组。这意味着我们几乎完成了预处理。

关键的最后一步是将故事(实际新闻)转换成神经网络可以理解的东西。为此,我使用了来自 TensorFlow Hub 的令人惊叹的通用句子编码器,它可以将任何给定的句子(在我们的例子中,是一个新闻故事)转换为长度为 512 的嵌入向量,因此最终我们将得到一个大小为 number_of_stories X 512 的数组。这是通过以下方式完成的:

注:我以前用类似的方法对文学运动进行分类,如果你愿意,你可以在这里查看。

要计算嵌入矩阵,我们只需运行我们刚刚定义的函数:

e_All = similarity_matrix(n_s)

终于!我们完成了预处理! e_All 是我们的特征数组,而 classes_Allclasses_Bias 是我们的类数组。现在,我们已经准备好用 Keras 构建一个分类器了。

我不想花太多时间解释如何建立一个神经网络,在《走向数据科学》和许多其他来源中发表了许多实践文章,你可以阅读并跟随非常好的教程来这样做,⁴ ⁵.在这里,我将简单地介绍一个产生良好结果的架构。这个架构是之前许多迭代中的一个,也是我个人发现有效的一个。说了这么多,我们来深究一下吧!我构建的分类器如下所示:

News Bias classifier. Image rendered with ann-visualizer.

它有一个 512 个神经元的输入层(每个嵌入值一个)和两个 40 个神经元的隐藏层,每个隐藏层都有一个固定丢失分数为 0.25 的丢失层。它还有一个使用 Softmax 激活函数的输出层,其中有四个神经元对媒体出口进行分类,两个神经元对媒体偏差进行分类(此处未显示)。就代码而言,它看起来像这样:

Media Bias Classifier

对于这两种情况(出口和偏差),除了优化器的学习速率以及输出层中的神经元数量(四个或两个)之外,所有参数都是相同的。直观地说,更简单的解决方案(偏差情况下的二进制)应该更快地得到优化。为此,我决定使用 0.00015 的学习率进行出口分类,0.0005 的学习率进行偏差分类。

最后,在检查结果之前,我们需要将数据分成训练集和测试集。为此,我们将使用一个分层洗牌拆分器,所以看起来像这样:

这样做了,我们只需要训练网络。我们可以通过以下方式做到这一点:

现在我们准备检查结果!

我们先来看网点分类。训练后(在 8 核 CPU 机器上大约 15 分钟,不需要 GPU),验证和训练精度曲线如下所示(可视化代码在本文后面提供):

这是什么意思?嗯,首先,验证集的精度几乎是 0.80,这可以认为是好的。记住,这是来自四家媒体的准确性!也就是说,这个神经网络仅基于书面语义内容,就能以相对较好的性能识别出被报道新闻的来源,非常酷!现在让我们看看损失,以验证我们的模型是否合适:

由于两条曲线“看起来”一样(它们之间的差异很小),我们可以说,我们的神经网络已经学习了足够通用的规则,以避免过度拟合,但又足够具体,以在验证集上产生良好的性能,这是一种始终是 desirable⁶.的深度学习质量考虑到这一点,我们现在可以查看混淆矩阵以更深入地了解结果:

很明显,来自【新工作岗位】的新闻故事被分类得更准确,但这可能是因为这两个类别的代表性更高。我们可以尝试重采样的方法来平衡类,但现在我会保持这种方式,并回到我们的二进制分类任务重采样,在接下来的段落中描述。**

接下来,我们可以探索媒体偏见分类的结果。记住,这是一个二元分类器(要么向左倾斜,要么向右倾斜)。第一,精度和损耗曲线:

如果你问我,我会印象深刻!我们得到了几乎 0.9 的准确度,这意味着,有效地,如果一个新闻故事偏向左边或右边,我们可以很好地识别。混淆矩阵呢?

看起来不错,但很明显,左倾的报道没有被充分代表,因此准确性没有完全反映这里正在发生的事情。光是准确性就可能会误导人。另一个对不均匀的类别分布有帮助的度量是 F1 score⁷.我们可以很容易地用 sklearn 的内置函数来计算它,所以只需这样做就行了:

*from sklearn.metrics import f1_score
f1_score(y_test,news_DNN.predict_classes(X_test))*

这引发了:

*>>> 0.78*

很好,但不完美。我们可以尝试使用过采样器来平衡训练集 only⁸中的类,以获得更好的结果。我将使用惊人的 Python 库 imblearn 中的 SMOTE,所以只需在拟合之前添加这一行:

使用平衡数据进行训练后,混淆矩阵现在看起来像这样:

更平衡。F1 和精度呢?分别为 0.80 和 0.88。非常好!

注意:所有可视化都是使用 seaborn 完成的。下面是我编写的创建所有图形的代码:

Code to visualize results

Photo by AbsolutVision on Unsplash

在本文中,我向您介绍了我构建、训练和可视化新闻出口/偏见分类器的步骤,结果非常好。我们能够得到出口分类的相当准确的分数,这表明文本的性质本身就可能包含关于给定故事在哪里写的信息。对于这种规模的样本,很难得出精确的结论,但想法是存在的,我们可以使用 Keras、TensorFlow 和 Python 中的可视化库来对新闻故事进行分类。更值得注意的是,偏见可以与非常好的表现联系在一起,这意味着在某种程度上,书面媒体中的语义规则隐含着政治偏见。在某种程度上,我们从一开始就知道这一点,但有趣的是,我们注意到这些信息是存在的,并且使用适当的工具可以自动识别。你认为这种方法还能解决什么问题?

现在您已经有了工具,您可以复制代码并在自己的项目中使用它。

感谢阅读!

参考资料:

[1]媒体偏见图表,https://www.adfontesmedia.com/

[2]布达克、c .戈埃尔、s .、&饶、J. M. 公正与平衡?通过众包内容分析量化媒体偏见。 (2016) 舆情季刊80 (S1),250–271。

[3]Keras 深度学习简介,https://towards data science . com/Introduction-to-Deep-learning-with-Keras-17c 09 E4 f 0 EB 2

[4]使用 Keras 的实用机器学习,https://towards data science . com/Practical-machine-Learning-with-Keras-19 d0e 5b 2558

[5]使用 Keras 构建深度学习模型,https://towards data science . com/Building-A-Deep-Learning-Model-using-Keras-1548 ca 149d 37

[6]https://machine learning mastery . com/how-to-choose-loss-functions-when-training-deep-learning-neural-networks/

[7]准确度、精密度、召回率还是 F1?https://towards data science . com/accuracy-precision-recall-or-f1-331 FB 37 C5 CB 9

https://beckernick.github.io/oversampling-modeling/

民主党初选中的媒体偏见

原文:https://towardsdatascience.com/media-bias-in-the-democratic-primary-66ffb48084db?source=collection_archive---------13-----------------------

媒体中有两种类型的偏见在起作用,它们都造成了不公平:语气上的偏见和音量上的偏见。例如,一篇攻击贝托·奥罗克使用拉丁裔昵称的专栏文章在语气上带有偏见;一张候选人筹款信息图包括了除杨安泽之外的所有顶级筹款人,这是中偏见的一个例子。

One rating

这两种类型的偏置在 2016 中非常 可见 ,但是确定音量偏置比音调偏置要容易得多,所以我将主要使用五三十八中可用的数据,集中讨论音量偏置。除非另有说明,平均或合计投票数按照本文中的生成。即使在对民主党人普遍友好的“蓝色”媒体中,对不同候选人报道的基调也有很大差异,我目前的印象是蓝色媒体更喜欢不太可能当选的候选人,特别是伊丽莎白·沃伦。

我将介绍几种衡量媒体偏见的方法,大部分是基于比较民意测验数字和媒体报道。

哪些候选人得到了更多的媒体报道,为什么?

媒体在数量上的偏见既普遍又不公平。然而,平等时间规则在很久以前就被废除了,候选人得到的报道量也大相径庭。民主党全国委员会曾试图公开表示赞同将辩论台上的候选人视为平等,但即使在辩论台上,候选人也没有获得平等的时间。

比较这两个职位是非常惊人的。乔·拜登在一周内获得的报道比乔·塞斯塔克在过去一年中获得的报道还多。然而,当我们考虑他们在民调数字、筹款和支持方面的差异时,媒体偏向于报道拜登作为领先者是可以理解的。

在某种程度上,这是不公平的;但这种不公平可以客观地基于这样一个事实:拜登比塞斯塔克更知名、更受欢迎。这是一场有利于领先者、不利于苦苦挣扎的竞争者的赛马偏见,而不是对塞斯塔克或拜登的偏见。

比较媒体报道和民意测验

大多数覆盖率差异的答案是投票。我认为在那之后剩下的就是媒体对特定候选人的支持和反对。

For legibility, candidates with aggregate polling less than 1% shown separately.

媒体报道既推动民意调查,也受民意调查的推动,因此从长远来看,两者密切相关。一些异常现象可以通过逐月分解数据来解释,比如汤姆·斯特耶在图表上的位置是一个迟到的候选人。然而,其他异常现象仍然无法解释。

从这一大背景来看,媒体显然更青睐伊丽莎白·沃伦而非伯尼·桑德斯,科里·布克而非贝托·奥罗克,以及许多其他候选人而非杨安泽。

在民调支持率较低的候选人的后场,来自内陆州的温和派(麦克·班尼、史蒂夫·布洛克、约翰·希肯卢珀和蒂姆·瑞恩)被忽视,而来自沿海州的政客(柯尔斯顿·吉利布兰德、杰伊·英斯利、埃里克·斯瓦尔韦尔和比尔·白思豪)则受到了青睐。然而——我要重复这一点——在低于 1%的范围内,很难对投票平均值的任何有意义的差异有任何信心。

Please note that the axes here are log-scaled, which means that the anomalies are very large anomalies.

Coverage is measured by total clips plus total stories from 538’s media tracking data. The exclusion of low polling weeks is quite significant for a handful of low-polling candidates, but is necessary to adequately show the relationship between the major candidates.

如果我们随着时间的推移更仔细地观察这些数字,它们通常在任何给定的一周和任何给定的一个月内相互关联。“赛马”覆盖面很广,大多数时候,大多数候选人在每个投票点都获得了类似的覆盖水平。

某一周或某一月的一些个别例外可以用新闻事件来解释。为了避免专注于任何单一新闻事件的影响,我将着眼于在一个中等或典型的一周内报道和投票之间的关系。当同一个候选人相对于他们的投票,一周又一周地重复和持续地被过度报道或报道不足时,媒体偏见是最简单的解释。

Median coverage per polling point; median difference between actual and predicted amount of coverage using a linear model; and median polling average.

民意测验和报道之间的关系并不完全相称;它倾向于在高端和低端偏离。这个问题的自然答案是做线性回归。

这向我们展示了两种略有不同但相关的媒体偏见的衡量标准。线性模型更可取,因为它考虑了更多的信息,并且不涉及除以接近零的数字。

从这两个指标来看,贝托·奥罗克显然受到了亏待,尽管他在民意调查中平均排名第七,但他的支持率在所有候选人中排名第二。我们同样可以强调杨安泽、史蒂夫·布洛克、乔·塞斯塔克和迈克·格拉维尔相对于他们的投票经常被低估。

在正面报道偏见方面,媒体更喜欢报道伊丽莎白·沃伦、科里·布克、柯尔斯顿·吉利布兰德和比尔·白思豪。或许值得注意的是,无论用哪种方法来衡量,皮特·布蒂吉格似乎都得到了恰到好处的覆盖。对于所有其他候选人来说,这些指标更加复杂;我们可以在其他候选人之间做出一些相对的决定,但不清楚他们在媒体报道量方面经历了净正面还是净负面的偏见。

候选人作为覆盖面的竞争者:评估每一个案例

这里我们谈到了几个主要问题。一个是民意调查和报道有一个很大的——但不是完全的——比例关系。我们能够自信地识别的异常是基于具有相对相似的投票数的候选人之间的成对比较。幸运的是,我们可以采用所有这些异常的成对比较,并使用它们来生成相对于投票的媒体偏向方向的评级。

根据我的分析,在数据中有 921 个案例,一个候选人在一周内得到的报道比另一个候选人少,尽管事实上他们在那一周和前一周的民调都更好。有一个很好的数学工具可以从一系列成对的比赛中梳理出竞争者的相对实力:它被称为 Elo 评级,以物理学家和国际象棋选手 Arpad Elo 命名。

Here, the polling average is determined by aggregating over all polls in the frame, so the figures are slightly different.

通过 Elo 评级公式进行 921 个两两比较,可以让我们衡量媒体对候选人无法解释的偏好。

有两个候选人的评分表明他们受到了媒体的强烈冷落:杨安泽(评分 675)和贝托·奥罗克(评分 836)。

尚不清楚第三名应该属于伯尼·桑德斯(1022)还是乔·拜登(958)。由于乔·拜登在每周的选举中都处于领先地位,他的支持率被人为压低了;他只能“输”给民调数字更低的候选人。温和派政治家作为一个群体往往低于平均水平。令人惊讶的是,这包括皮特·布蒂吉格(1068),他在这个主题的其他方面看起来接近平均水平。

值得注意的高评级候选人包括柯尔斯顿吉利布兰德(1408)和伊丽莎白·沃伦(1335);在仍在竞选的候选人中,伊丽莎白·沃伦显然是媒体的宠儿。用这种方法排名最高的候选人是埃里克·斯瓦尔维尔、比尔·白思豪、杰伊·英斯利和塞斯·莫尔顿。值得再问一次,重要程度是多少?

这些考生有多少故事和片段得与失?

如果我们将数据集中的 921 个两两比较,削减到每周,我们可以确定覆盖范围的最小变化,这将消除任何明显的冷落。这样做可以正确看待正音量偏差:塞斯·莫尔顿可能会被报道,而不是其他不知名的候选人,但几乎没有报道受到威胁。

根据这一标准,科里·布克脱颖而出,超过了克里斯汀·吉利布兰德和伊丽莎白·沃伦。最受冷落的候选人显然又是贝托·奥罗克和杨安泽。

关于媒体中音量偏差的地理位置的一个小说明

将候选人按其选区的地理位置(沿海大陆、内陆大陆、非毗邻地区或缺少以前的选区)进行分类显示了一个非常有趣的模式。

前十名候选人的选区是沿海州、区或城市,现在覆盖面更广了。内地考生被覆盖较少。这实际上是一个非常一致的划分;考虑到主要媒体的地理和人口统计,这也是可以理解的。

没有内地考生有明确的正体积偏差;最接近的是皮特·布蒂吉格和艾米·克洛布查尔,他们在大多数方面都接近中立。有没有沿海候选明确负体积偏差;最接近的是乔·拜登,尽管如此,他在报道竞争中绝对领先。

由于选举团的政治战场既不在 Acela 走廊,也不在西海岸,媒体的地理偏见可能会阻碍提名更有可能当选的候选人。

影响和效果

从上面的分析中,有几个明确的结论。首先,我们可以清楚地发现少数候选人似乎吸引了过多的媒体报道。与民调数字相近的候选人相比,伊丽莎白·沃伦、科里·布克、柯尔斯顿·吉利布兰德和比尔·白思豪都在媒体报道中占据显著位置。由于伊丽莎白·沃伦在“蓝色”媒体上的报道也一直是积极的,这可能助长了她的崛起。

其次,我们可以确定两位候选人明显受到了媒体偏见的影响。杨安泽和贝托·奥罗克都经历了媒体过度稀少和负面的报道..难怪贝托挣扎着选择退出,也难怪杨安泽的支持者抱怨#央媒封杀。

根据他的筹款和民意调查,杨安泽早就应该成为公众讨论的一个重要部分。不这样做的后果是消极的。

第三,有一些知名度较低的候选人渴望得到报道,他们没有足够的时间向潜在选民宣传自己的观点。这包括已经退出的约翰·希肯卢珀和蒂姆·瑞恩;以及麦克·班尼、史蒂夫·布洛克、约翰·德莱尼和乔·塞斯塔克。所有这些候选人都有比皮特·布蒂吉格更典型的总统候选人背景。

Sanders’ polling is steady; Gabbard’s polling has been climbing in spite of (or perhaps because of) a recent spate of negative coverage.

第四,有一些证据支持伯尼·桑德斯和塔尔西·加巴德的支持者经常指责的语气偏见。这两位候选人和杨安泽似乎都不太可能退出。

显而易见的媒体偏见,如果继续下去,可能会对最终的民主党候选人造成伤害。民主党全国委员会可能面临另一轮关于试图操纵初选的指控。媒体本身也会因为在音量或语气上公然偏袒而失去信誉。

鉴于民主党全国委员会和“蓝色”媒体对偏见的指控是可信和有根据的,推动对进入初选的候选人进行公平、透明和公正的报道就更加重要了。

媒体监测 2.0:从数据到洞察

原文:https://towardsdatascience.com/media-monitoring-2-0-from-output-to-insight-ecf0d926b4ec?source=collection_archive---------30-----------------------

在营销和传播专业人士的生活中,媒体监控是热门且不可或缺的。测量就是了解,事实上在我们当前的时代,可能性是无穷无尽的。监控工具和数字解决方案的数量正在增长,如今一切都可以测量。所以我们必须注意到这一点,对吗?数据无处不在,收集、监控和分析数据从未如此简单。然而,我们现在面临挑战。我们如何应对假新闻?我们如何继续在我们的数据中找到相关性,并将其转化为理解,并最终转化为具体行动?在本博客系列的第 1 部分,我们将讨论媒体监控领域需要的转变,以及如何将这种转变应用到您的媒体监控策略中。

它从“为什么”开始

西蒙·西内克的黄金圈,谁没听说过?他认为,为了取得成功,作为一家公司,你必须从“为什么”这个问题开始,然后从那里赋予“如何”和“什么”以实质内容。这听起来很有逻辑,而且现在已经被许多组织所使用,但是仍然有很多人主要用“如何”和“什么”来交流。

这个模型很实用,因此很容易应用到其他策略和日常事务中。作为一名营销和传播专业人士,不断问自己为什么要做这些事情是很重要的。你为什么要做某些决定?为什么这是你的策略?您会选择哪些定位和分析主题,为什么?你为什么要通过核心信息 X 和 Y 以及媒介 Z 来传达这一点?

这也可以通过监测和测量来转化;为什么你甚至需要监控?为什么需要这个输出?你想要什么,你能用这个做什么?这对证明你的策略有什么帮助?

“为了监控而监控是没有用的,浪费时间、金钱和精力。”

衡量你想要衡量的东西,并正确地去做

从战略沟通目标和围绕这些目标形成的政策着手。可能这些没有被清楚地表达出来,这有助于观察整体的组织策略(也就是伞)。我们的定位是什么,我们为什么要这样做?我们如何通过交流赋予它实质内容,为此需要什么?从“为什么”开始可以确保更多地关注核心任务和战略规划,减少对当前问题的浪费。

这同样适用于监测及其实施。监控可以被视为“如何”,由“为什么”形成,并导致“什么”。但就其本身而言,它毫无意义。看看下面的例子:

X 组织

原因:可持续发展是我们 2019 年定位的重要支柱。我们希望创造更积极的媒体能见度和积极的基调,通过正确的媒体向正确的利益相关者传达正确的信息,并能够在必要时不断改进这些事情。
如何:监控媒体的可见性、影响力、情感、利益相关方、媒体来源和核心信息
如何:洞察主动活动和自有及盈利媒体的传播效果

如你所见,如果没有“为什么”,那么“如何”和“做什么”就没什么意义。此外,定义这一点不仅有助于您将更多的注意力放在媒体监控活动上,还可以创建内部支持来说服投资管理人员。毕竟,您提供了对监控所能提供的东西的洞察力。

获得更多洞察力和概览

为了使您的媒体监控活动具有针对性和相关性,将这些活动与沟通和/或业务战略和计划相协调是非常重要的。

以荷兰皇家航空公司为例,该公司在其网站上广泛交流对公司重要且相关的重要话题,以及所有这些问题的处理方式。

作为一名传播专业人员,使用这些类型的主题作为媒体监测的指南是有用的,以便深入了解围绕这些主题所做的努力的影响。作为一个组织,你的承诺和言论在多大程度上与你的实际行动相符?媒体在多大程度上(以正确的方式)采纳了你的核心信息,这些信息最终会到达正确的目标群体手中吗?通过这种方式,你可以更有针对性地进行监控,你会发现更容易找到真正重要的正确报告。

“控制媒体对自己的监控,而不是被过量的新闻淹没。”

因此,在荷航的案例中,需要监控媒体对“荷航小心”主题的影响,以及主动报道的比例或媒体中的核心信息。

从输出到洞察

一旦你把重点放在了你的媒体监测上,并与战略主题联系起来,提供一个背景也是很重要的。好东西,所有的主题和话题的监控,但是这个输出告诉我什么?我们做得好吗?我们走上正轨了吗?这是由什么驱动的?

只有当您能够集成数据输出并将其与目标和 KPI 联系起来时,它才会变得有趣。您可以根据这个来设置输出,以便能够判断您需要按下哪个按钮,或者使用这个输出来制定 KPI。对于后者,您可以使用监控作为构建 KPI 的基线度量。

如果我们使用前面提到的组织 X 的例子作为起点,从输出到洞察的转换看起来是这样的:

组织 X
产出:
假设 2019 年 1 月监测的产出为主题可持续性的 500 条消息(占媒体总报道量的 5%)。这些信息中有 15%是您自己主动/ PR(主动)的结果,10%是积极的语气。这三大核心信息似乎只在地区新闻网站上可见。

集成:
就其本身而言,上面的输出并不能说明什么。想到的问题大概是“那又怎样?”。这里是上下文;2019 年 1 月,组织 X 的目标是至少 10%的可持续发展主题报告,除此之外,关于前 3 个核心信息的 KPI 至少有 10%的主动报告、5%的积极情绪和全媒体可见性。

洞察力
通过在目标和 KPI 之间建立联系,结果立即有了意义。我们从建立这种联系中得到了什么启示?1 月份可持续发展的可见性低于预期(5%对 10%),但比预期更积极(15%对 10%)和更积极(10%对 5%)。换句话说,该公司的举措产生了影响,并以正确的语气采取了措施,但知名度仍然有限。此外,这显然与我们在媒体上的可见性目标和核心信息不匹配。为什么我们的核心信息似乎在地区新闻网站上传播得如此之好?我们可以采取什么措施来提高媒体在整个董事会中的知名度?

通过从“为什么”的角度来处理和组织媒体监督,你创造了相关性和价值,有了一个概览,并保持控制。这一转变非常重要,它将激励你更加关注战略项目和计划的影响,并向你所在组织的管理层展示这一点的附加价值。在本博客系列的第 2 部分中,我们将进一步阐述在管理层提供证据和创建内部支持的过程。

用卷积神经网络进行医学诊断

原文:https://towardsdatascience.com/medical-diagnosis-with-a-convolutional-neural-network-ab0b6b455a20?source=collection_archive---------15-----------------------

浅谈人工智能在医疗保健中的应用。

Image licensed from Adobe Stock

2018 年美国美国食品药品监督管理局批准使用一种叫做卷积神经网络的人工智能形式的医疗设备来检测糖尿病成年人的糖尿病视网膜病变( WebMD,2018 年 4 月)。医学图像处理代表了人工智能(AI)世界中的一些“低挂果实”,其使用才刚刚开始。人工智能有望将专业人士从数小时的乏味任务中解放出来。如果运用得当,它可以带来更好的患者结果和更低的医疗成本。

糖尿病视网膜病变是糖尿病患者失明的最常见原因,也是工作年龄成人失明的主要原因。总之,患有各种类型糖尿病的人都有风险,并且患糖尿病的时间越长,风险越大。这种疾病始于视网膜中微小血管的肿胀和微动脉瘤。在晚期病例中,这些受损的血管会导致生长因子的分泌,从而引发新血管的增殖。这些新血管生长在视网膜表面,并进入眼睛的玻璃体凝胶中。这些新血管很脆弱,可能会渗漏和出血,随着疤痕组织的积累,病情会变得更糟。视网膜脱落会导致视力受损和全盲,因此早期诊断至关重要(美国国家眼科研究所——糖尿病眼病相关事实)。

眼科医生诊断这种情况的一种工具是眼底照相术,它使用一种专门的相机来拍摄患者的视网膜照片。这是一个健康视网膜的图像:

Healthy Retina — Image licensed from Adobe Stock

这是一个被诊断为“增生性糖尿病视网膜病变”的视网膜,这是疾病阶段的最严重分类:

Proliferative Diabetic Retinopathy — Image licensed from Adobe Stock

在这种严重的情况下,很容易看到浅色的斑点,这是急性疾病的指标之一。在疾病的早期阶段,肿胀和微动脉瘤更难发现。幸运的是,这是一项非常适合人工智能的任务。

我的目标是创建一个卷积神经网络,这是几种最先进的人工智能方法之一,可以正确地将眼底图像分为五类:

  • 不存在 DR(糖尿病视网膜病变)
  • 轻度 DR
  • 温和的 d
  • 重度 DR
  • 增生性 DR

卷积神经网络(CNN)可以用先前已经被正确分类的图像的例子来训练。

我从位于印度泰米尔纳德邦钦奈的亚太远程眼科协会举办的一场竞赛中获得了这个项目的原始图片。该数据集包括 3,662 个预先分类的眼底图像,包括疾病所有阶段的实例。

为了大大简化 CNN 的工作方式,CNN 通过使用多层“节点”和无数次“分析”和“加权”结构、模式等迭代来学习。它在图像中识别。帮助它正确识别的结构/模式(例如,这是狗还是猫?)或分类(我的用例)图像被“奖励”较高的“权重”,而一个有害或无用的图像被“惩罚”较低的“权重”构建这些“层”和“权重”的方式有无数种,处理它们所需的计算能力从微不足道到不可能。有用的 CNN 没有被广泛使用,直到非常非常快的计算机和 GPU 变得更加便宜——这是最近的发展。

这张图展示了我用来评估 CNN 的两个指标:

从左到右代表迭代(在机器学习中称为“时期”),其中模型已经完成一次并生成预测。蓝线代表 CNN 对它“研究”的图像的预测的准确性,橙线代表对它没有“分析”但可以“自测”的图像的预测的准确性。当训练精度继续提高,但验证精度开始下降时,就是“过拟合”开始的时候。在这一点上,CNN 在识别它已经研究过的图像方面变得如此之好,以至于在对它没有“研究”过的图像进行分类方面变得“更差”一般来说,更高的验证准确性是目标,所以我们希望在验证准确性达到峰值时阻止 CNN 了解更多信息。如果 CNN 在这一点上的性能不够,则需要调整 CNN 中的一些或所有层和权重,以改善最终输出。

做出这些调整可能是一个非常复杂的过程。在我的 CNN 中,所有的图像都被缩小到只有 128 像素乘 128 像素的大小,然而 CNN 使用了超过 2700 万个“可训练的”参数。

CNN 的最终评估是使用一组 CNN 从未“见过”的眼底图像完成的。下图称为混淆矩阵,显示了 CNN 预测每个疾病阶段分类图像的准确程度:

Confusion Matrix

左上角的矩形显示,当 CNN 将一幅图像分类为“无 DR”时,其准确率为 98%,这是一个非常好的结果。不幸的是,当它预测“轻度 DR”时,只有 44%的时间是正确的。它似乎在区分“轻度”和“中度”类别的图像方面有最大的困难。46%的实际“轻度 DR”图像被错误地归类为“中度 DR”。我相信,通过对层和权重进行更多的“调整”,这种性能可以得到改善。

我对数据科学改善我们所有人生活的潜力充满热情,我期待着这些技术在现实生活中的应用。

这个项目的完整代码和数据集可以在我的 GitHub 库这里看到。

人工智能的好处——用于疟疾检测的医学图像分析

原文:https://towardsdatascience.com/medical-image-analyses-for-malaria-detection-fc26dc39793b?source=collection_archive---------27-----------------------

在这篇博客中,我们将讨论为什么疟疾检测对于早期检测薄血涂片中寄生细胞的存在是重要的,以及一些人对此的实践。

介绍

疟疾是一种致命的传染性蚊媒疾病,由疟原虫寄生虫引起。这些寄生虫通过受感染的雌性按蚊的叮咬传播。虽然我们不会深入了解这种疾病的细节,但疟疾有五种主要类型。

现在让我们看看这种疾病在下面的情节中有多致命的意义。

很明显,疟疾在全世界流行,尤其是在热带地区。这个项目的动机是支持这种疾病的特性和致命性。最初,如果被感染的蚊子叮咬,蚊子携带的寄生虫会进入你的血液,并开始破坏携带氧气的红细胞。通常,疟疾的主要症状有点像流感或病毒,一旦被蚊子叮咬,你通常会在几天或几周内感到不适。然而,这些致命的寄生虫会在你的身体里沉睡一年多而没有任何问题!所以,延误正确的治疗会导致并发症甚至死亡。因此,疟疾的早期有效检测将拯救生命。

解决问题的方法

尽管疟疾病毒没有以变异蚊子的形式出现,但它确实让人感觉像是一个变异问题。这种致命的疾病在世界不同地区已经达到流行病甚至地方病的比例——每年在杀死大约 40 万人。在世界上的其他地方,它几乎不存在。一些地区特别容易爆发疾病——某些因素使得一个地区更有可能被疟疾感染。

  • 高度贫困
  • 缺乏适当的医疗保健
  • 政治不稳定
  • 疾病传播媒介的存在(例如蚊子)〔6〕

由于这些问题的混合,我们在构建模型时必须记住一些事情:

  • 可能缺少一个可靠的电源
  • 电池供电的设备具有较少的计算能力
  • 可能缺少互联网连接(所以在云上训练/存储可能很难!)

传统的疟疾检测方法

有几种方法和测试可用于疟疾的检测和诊断。

这些包括但不限于厚薄血涂片检查、聚合酶链反应(PCR)和快速诊断测试(RDT)。我不打算涵盖所有的方法,但事实是,传统的测试通常使用一种替代方法,特别是在高质量的显微镜服务不能轻易提供的情况下。

血液的显微镜检查是诊断疟疾最著名的方法。将患者的血液涂在载玻片上,并用造影剂染色,这有助于识别红细胞内的寄生虫。

一名训练有素的临床医生在 100 倍的放大倍数下检查 20 个微观视野,从 5000 个细胞中计数含有寄生虫的红细胞(世卫组织方案)。

感谢 Carlos Atico】关于数据科学见解的博客

因此,疟疾检测肯定是一个密集的手动过程,也许可以通过深度学习实现自动化,这是本博客的基础。

用于疟疾检测的深度学习

深度学习模型,或者如果我必须说得更具体一些,卷积神经网络(CNN)已经被证明在各种各样的计算机视觉任务中非常有效。虽然我们假设你对 CNN 有所了解,但如果你不了解,请点击这里的这篇文章,深入了解它们。简而言之,CNN 模型中的关键层包括卷积层和池层,如下图所示。

卷积神经网络(CNN)可以自动提取特征和学习过滤器。在以前的机器学习解决方案中,特征必须手动编程——例如,大小、颜色、细胞的形态。利用卷积神经网络(CNN)将大大加快预测时间,同时反映(甚至超过)临床医生的准确性。

CNN 从我们的数据中学习等级模式。因此,他们能够学习图像的不同方面。例如,第一卷积层将学习小的和局部的图案,例如边缘和拐角,第二卷积层将基于来自第一层的特征学习更大的图案,等等。

您可以浏览 Rajaraman 等人的一篇非常有趣的研究论文' 预训练卷积神经网络作为特征提取器,用于改进薄血涂片图像中的寄生虫检测 ' 。它解释了上述论文中提到的数据的六个预训练模型。在检测疟疾和非感染样本时获得 95.9%的准确率。

数据集解释

让我们看看这个问题集使用了什么数据,我非常感谢李斯特山国家生物医学通讯中心(LHNCBC)的研究人员,他们是国家医学图书馆(NLM)的一部分,他们仔细收集并注释了健康和受感染血液涂片图像的数据集。你可以从官方网站下载这些图片。

他们还推出了一个移动应用程序,可以在连接到传统光学显微镜的 andriod 智能手机上运行(Poostchi 等人,2018 年)。在孟加拉国吉大港医学院医院收集 150 名恶性疟原虫感染患者和 50 名健康患者的吉姆萨染色薄血涂片并拍照。智能手机的内置摄像头可以获取每个微观视野的幻灯片图像。这些图像由泰国曼谷的玛希多-牛津热带医学研究中心的专家幻灯片阅读者手工注释。

注意:现在,在我们开始之前,我想指出,我既不是医生,也不是医疗保健研究人员,我远不如他们有资格。不过,我确实对将人工智能应用于医疗保健研究感兴趣。本文的目的不是深入宣传人工智能将取代工作岗位并接管世界,而是展示人工智能如何有助于疟疾检测、诊断并通过低成本有效且准确的开源解决方案减少人工劳动。

这是我们训练数据的样子

注:我正在使用谷歌 colab 和代码将根据相同的,我建议大家使用谷歌 colab 的方便。

让我们来看看代码:

密码

初始化

%reload_ext autoreload
%autoreload 2
%matplotlib inline

google colab 上的虚拟机测试

如果谷歌的服务器很拥挤,你最终只能访问 GPU 的一部分。如果您的 GPU 与另一台 Colab 笔记本共享,您将看到可供您使用的内存量减少。

!/opt/bin/nvidia-smi
!nvcc --version

当我开始运行这里描述的实验时,我很幸运:我有 11441 MB 的 RAM!我的输出如下所示:

Mon Nov  4 05:40:26 2019       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 418.67       Driver Version: 418.67       CUDA Version: 10.1     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla K80           Off  | 00000000:00:04.0 Off |                    0 |
| N/A   49C    P8    30W / 149W |      0MiB / 11441MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2018 NVIDIA Corporation
Built on Sat_Aug_25_21:08:01_CDT_2018
Cuda compilation tools, release 10.0, V10.0.130

导入库

在这里,我们导入所有必需的包。我们将使用 fast.ai V1 库,它位于 Pytorch 1.0 之上。fast.ai 库提供了许多有用的功能,使我们能够快速轻松地建立神经网络并训练我们的模型。

from fastai.vision import *
from fastai.metrics import error_rate
from fastai.callbacks import SaveModelCallback# Imports for diverse utilities
from shutil import copyfile
import matplotlib.pyplot as plt
import operator
from PIL import Image
from sys import intern   # For the symbol definitions

一些实用程序功能:导出和恢复

现在,这里有一个用于部署的导出网络和一个用于创建拷贝的导出网络

# Export network for deployment and create a copydef exportStageTo(learn, path):
    learn.export()
    # Faça backup diferenciado
    copyfile(path/'export.pkl', path/'export-malaria.pkl')

#exportStage1(learn, path)

恢复部署模型,例如为了继续微调

# Restoration of a deployment model, for example in order to continue fine-tuningdef restoreStageFrom(path):
  # Restore a backup
  copyfile(path/'export-malaria.pkl', path/'export.pkl')
  return load_learner(path)

#learn = restoreStage1From(path)

现在让我们下载 NIH 数据集,我们今天将在上面工作:

!wget  --backups=1 -q https://ceb.nlm.nih.gov/proj/malaria/cell_images.zip
!wget  --backups=1 -q https://ceb.nlm.nih.gov/proj/malaria/malaria_cell_classification_code.zip
!ls -al

wgetbackups=1 参数将允许您在下载失败的情况下多次重复命令行,而无需创建大量新版本的文件。

最后一行的输出应该是这样的:

total 690400
drwxr-xr-x 1 root root      4096 Nov  4 10:09 .
drwxr-xr-x 1 root root      4096 Nov  4 05:34 ..
-rw-r--r-- 1 root root 353452851 Apr  6  2018 cell_images.zip
-rw-r--r-- 1 root root 353452851 Apr  6  2018 cell_images.zip.1
drwxr-xr-x 1 root root      4096 Oct 30 15:14 .config
drwxr-xr-x 5 root root      4096 Nov  4 07:26 data
-rw-r--r-- 1 root root     12581 Apr  6  2018 malaria_cell_classification_code.zip
-rw-r--r-- 1 root root     12581 Apr  6  2018 malaria_cell_classification_code.zip.1
drwxr-xr-x 1 root root      4096 Oct 25 16:58 sample_data

让我们解压缩 NIH 细胞图像数据集:

!unzip cell_images.zip

这将产生一个非常大的详细输出,如下所示:

Archive:  cell_images.zip
   creating: cell_images/
   creating: cell_images/Parasitized/
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144104_cell_162.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144104_cell_163.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144104_cell_164.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144104_cell_165.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144104_cell_166.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144104_cell_167.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144104_cell_168.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144104_cell_169.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144104_cell_170.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144104_cell_171.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144348_cell_138.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144348_cell_139.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144348_cell_140.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144348_cell_141.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144348_cell_142.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144348_cell_143.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144348_cell_144.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144823_cell_157.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144823_cell_158.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144823_cell_159.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144823_cell_160.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144823_cell_161.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_144823_cell_162.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145042_cell_162.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145042_cell_163.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145042_cell_164.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145042_cell_165.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145042_cell_166.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145042_cell_167.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145422_cell_163.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145422_cell_164.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145422_cell_165.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145422_cell_166.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145422_cell_167.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145422_cell_168.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145422_cell_169.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145609_cell_144.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145609_cell_145.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145609_cell_146.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145609_cell_147.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145609_cell_148.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145609_cell_149.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145609_cell_150.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145609_cell_151.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145938_cell_167.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145938_cell_168.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145938_cell_169.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145938_cell_170.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145938_cell_171.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145938_cell_172.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145938_cell_173.png  
 extracting: cell_images/Parasitized/C100P61ThinF_IMG_20150918_145938_cell_174.png  
and .......... so on

准备您的数据

cell_images 文件夹的名称改为 train ,然后将 mv 放在一个新的 data 文件夹的上面,这样 fast.ai 就可以用它来自动生成 train,验证测试设置,不用再大惊小怪了

!mv cell_images train
!mkdir data
!mv train data

深入研究数据文件夹

如果还没有安装树命令,请安装它:

!apt install tree

让我们现在运行命令

!tree ./data --dirsfirst --filelimit 10

这将显示文件夹的树状结构:

./data
└── train
    ├── Parasitized [13780 exceeds filelimit, not opening dir]
    └── Uninfected [13780 exceeds filelimit, not opening dir]3 directories, 0 files

变量初始化

bs = 256                # Batch size, 256 for small images on a T4 GPU...
size = 128              # Image size, 128x128 is a bit smaller than most of the images...
path = Path("./data")   # The path to the 'train' folder you created...

创建培训和验证数据束

有了 fast.ai 就没必要了:如果你只有一个‘train’文件夹,你可以在创建 DataBunch 时通过简单地传递几个参数来自动分割它。我们将把数据分成一个训练集 (80%)和一个验证集 (20%)。这是通过imagedatabunch . from _ folder()构造函数方法中的 valid_pct = 0.2 参数完成的:

限制你的扩展:这是医学数据!你不要幻想数据…

例如,扭曲会让你的图像严重失真,所以不要这样做!

这个数据集很大,所以也不要旋转图像。让我们坚持翻转…

tfms = get_transforms(max_rotate=None, max_warp=None, max_zoom=1.0)
# Create the DataBunch!
# Remember that you'll have images that are bigger than 128x128 and images that are smaller,   
# so squish them all in order to occupy exactly 128x128 pixels...
data = ImageDataBunch.from_folder(path, ds_tfms=tfms, size=size, resize_method=ResizeMethod.SQUISH, 
                                  valid_pct = 0.2, bs=bs)
#
print('Transforms = ', len(tfms))
# Save the DataBunch in case the training goes south... so you won't have to regenerate it..
# Remember: this DataBunch is tied to the batch size you selected. 
data.save('imageDataBunch-bs-'+str(bs)+'-size-'+str(size)+'.pkl')
# Show the statistics of the Bunch...
print(data.classes)
data

print() 将输出转换和类:

Transforms =  2
['Parasitized', 'Uninfected']

最后一个中的数据命令将简单地输出 ImageDataBunch 实例的返回值:

ImageDataBunch;Train: LabelList (22047 items)
x: ImageList
Image (3, 128, 128),Image (3, 128, 128),Image (3, 128, 128),Image (3, 128, 128),Image (3, 128, 128)
y: CategoryList
Uninfected,Uninfected,Uninfected,Uninfected,Uninfected
Path: data;Valid: LabelList (5511 items)
x: ImageList
Image (3, 128, 128),Image (3, 128, 128),Image (3, 128, 128),Image (3, 128, 128),Image (3, 128, 128)
y: CategoryList
Uninfected,Parasitized,Parasitized,Parasitized,Parasitized
Path: data;Test: None

看一下扩充的数据集群

data.show_batch(rows=5, figsize=(15,15))

ResNet18

ResNet18 要小得多,所以我们会有更多的 GPU RAM。我们将再次创建数据批量,这次批量更大。

我也用过 ResNet50,它给出了 92%的准确率。

但是 ResNet18 非常适合这些数据,在这篇博客中,我们将使用它,

现在,创建学习者:

learn18 = cnn_learner(data, models.resnet18, metrics=error_rate)

如果您的 Colab 环境没有 ResNet18 的预训练数据,fast.ai 会自动下载它:

Downloading: "https://download.pytorch.org/models/resnet18-5c106cde.pth" to /root/.torch/models/resnet18-5c106cde.pth
46827520it [00:01, 28999302.58it/s]

让我们来看看这个模型:

learn18.modelThis will list the structure of your net. It is much smaller than the ResNet34, but still has a lot of layers. The output will look like this:Sequential(
  (0): Sequential(
    (0): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
    (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (2): ReLU(inplace=True)
    (3): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
    (4): Sequential(
      (0): BasicBlock(
        (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU(inplace=True)
        (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (1): BasicBlock(
        (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU(inplace=True)
        (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (5): Sequential(
      (0): BasicBlock(
        (conv1): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
        (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU(inplace=True)
        (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (downsample): Sequential(
          (0): Conv2d(64, 128, kernel_size=(1, 1), stride=(2, 2), bias=False)
          (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        )
      )
      (1): BasicBlock(
        (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU(inplace=True)
        (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (6): Sequential(
      (0): BasicBlock(
        (conv1): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
        (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU(inplace=True)
        (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (downsample): Sequential(
          (0): Conv2d(128, 256, kernel_size=(1, 1), stride=(2, 2), bias=False)
          (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True).......... and so on

让我们训练它

我们将再次使用 fit_one_cycle HYPO 训练策略。将训练限制在 10 个时期,以观察这个较小网络的行为:

learn18.fit_one_cycle(10, callbacks=[SaveModelCallback(learn18, every='epoch', monitor='accuracy', name='malaria18-1')])
# Save the model
learn18.save('malaria18-stage-1')
# export the model stage
exportStageTo(learn18, path)

下表显示网络学习到大约 96.1%的准确度,并且建议网络不应该被进一步训练:时段#8 和#9 之间的损失显示出 0.005 的减少,但是准确度保持不变,这表明网络已经开始过拟合。

epoch 	train_loss 	valid_loss 	accuracy 	time
0 	0.543975 	0.322170 	0.901107 	01:08
1 	0.354574 	0.198226 	0.927055 	01:07
2 	0.256173 	0.173847 	0.938487 	01:08
3 	0.197873 	0.157763 	0.943930 	01:09
4 	0.163859 	0.148826 	0.947197 	01:08
5 	0.143582 	0.142058 	0.948104 	01:08
6 	0.130425 	0.134914 	0.949918 	01:09
7 	0.118313 	0.132691 	0.951551 	01:09
8 	0.112078 	0.132101 	0.952459 	01:09
9 	0.107859 	0.131681 	0.952096 	01:09

让我们生成一个分类解释并查看混淆矩阵和损失曲线。

interp = ClassificationInterpretation.from_learner(learn18)losses,idxs = interp.top_losses()len(data.valid_ds)==len(losses)==len(idxs)

让我们来看看混淆矩阵:

interp.plot_confusion_matrix(figsize=(5,5), dpi=100)

让我们来看看损失:

learn18.recorder.plot_losses()

ResNet18 在大约 290 批次后开始有点过度拟合。

记住我们的 bs 在这里是 512,在 ResNet34 是 256。

微调模型

这里我们将介绍另一个 fast.ai HYPO:自动选择的可变学习率。我们将让 fast.ai 为每个历元和每个层选择使用哪个学习速率,提供一个我们认为足够的学习速率范围。我们将训练 30 个纪元的网络。

# Unfreeze the network
learn18.unfreeze()

learn18.fit_one_cycle(30, max_lr=slice(1e-4,1e-5), 
                    callbacks=[SaveModelCallback(learn, every='epoch', monitor='accuracy', name='malaria18')])
learn18.save('malaria18-stage-2')
# export fo deployment
exportStageTo(learn18, path)

在这里,我们的 fast.ai 模型经过一些微调后达到了大约 97%的准确率,这已经足够好了。

然而,验证失败,成为上一个时代更糟糕的。这表明我们从大约第 20 纪元开始就已经过度拟合

因此,如果我们要部署模型,请选择具有 20 个历元的模型,并注意这是最好的精度,至少对于此网络,我们可以使用不同的网络来获得更好的结果。

结果

interp = ClassificationInterpretation.from_learner(learn18)losses,idxs = interp.top_losses()len(data.valid_ds)==len(losses)==len(idxs)interp.plot_confusion_matrix(figsize=(5,5), dpi=100)

learn.recorder.plot_losses()

这比我们以前吃过的要好。让我们看看损失曲线:

在这里,我们看到网络似乎在 500 批次后开始过度拟合,这将证实我们从上面的结果表中推断的怀疑。如果你看上面的曲线,你会看到验证损失在训练的最后三分之一开始增加,表明这部分训练只是过度拟合了网络。

现在我将把这个任务交给你们,调整网络或使用任何技术来控制这种情况。

提示:在每个纪元后保存你的模型。

快乐学习

关注 MachineX 了解更多信息”

  • 领英
  • 推特

参考

  • PyImagesearch::用 Keras 进行深度学习和医学图像分析 —以 Adrian rose Brock 2018 年 12 月 3 日的疟疾图像为例;
  • 来自 NIH 的疟疾数据集——来自疟疾筛查者研究活动的薄血涂片图像的分割细胞库;
  • TowardsDataScience::利用深度学习检测疟疾——人工智能造福社会——医疗保健案例研究——Dipanjan(DJ)Sarkar 对上述内容的评论;
  • PeerJ::Sivaramakrishnan Raja Raman 等人的预训练卷积神经网络作为特征提取器,用于改进薄血涂片图像中的疟原虫检测 —上述帖子的作者基于其工作的原始科学论文。

基于概率层和 Grad-Cam 的医学图像分析

原文:https://towardsdatascience.com/medical-image-analysis-using-probabilistic-layers-and-grad-cam-42cc0118711f?source=collection_archive---------26-----------------------

解开卷积神经网络的“黑箱”

对医疗保健中用于图像分析的人工智能应用的兴趣正在快速增长。学术期刊中关于机器学习的出版物数量呈指数增长,因此在日常临床实践中已经实现了几种图像识别应用。准确的算法可以作为医生的额外诊断工具,以促进和加快工作流程,最重要的是,提高诊断过程的准确性。

图像分析算法应该被添加到医生的工具箱中,而不是被视为医学专家的潜在替代品。尽管医生关心并负责病人的健康,但大多数医生并不熟悉机器学习算法的数学细节。因此,医疗应用不应该充当“黑匣子”,而是提供关于模型如何得出其预测的额外信息。本博客展示了获取这些信息的两种可能的技术:概率层,可用于解决模型预测的不确定性,Grad-CAM 是一种展示哪些像素对模型结果贡献最大的方法。在这个博客中,我们将重点关注皮肤镜图像,但提出的技术也适用于其他医学领域(如放射学和病理学)。

基础架构

将使用 Kaggle 的 public HAM(“人对机器”)10000 数据集来说明这两种技术,该数据集包含 7 类色素性皮肤损伤的超过 10000 个图像,包括几种类型的皮肤癌(即黑色素瘤和基底细胞癌)和侵入性较小的类型,如良性角化病样损伤和生理性黑素细胞损伤。

Examples of images in the HAM10000 dataset

尽管数据集包含了年龄和位置等对皮肤病变分类有价值的附加特征,但出于说明的目的,本博客将仅关注成像数据。在左边的几个例子图像,所有获得的皮肤镜描述。

首先,使用具有预定义权重的 VGG16 架构来训练基本卷积神经网络。第一层的重量被冻结,只有最后 6 层被重新训练。添加了具有 softmax 激活功能的额外致密层。

在 10 个时期的训练之后,迁移学习模型产生了 82%的验证准确度。此时,模型的输出由一个数组组成,该数组表示图像属于 7 个类别中的每一个类别的概率(见下文)。

[[2.3303068e-09 1.2782693e-10 1.4191615e-02 1.8526940e-14 3.9408263e-02 9.4640017e-01 2.1815825e-11]]

这些预测已经可以在正确的方向上指导医生,但是模型的“思考”方法的附加信息将增加对这些深度学习模型的理解和信任。接下来的章节将说明概率层和 Grad-CAM 在这方面的价值。

概率层

向模型架构添加概率层是评估模型预测不确定性的一种有效方法。“正常”层和概率层之间的根本区别在于,概率层假设权重具有某种分布,而不是点估计。概率层通过变分推理逼近权值的后验分布。本质上,后验分布通过高斯分布替代函数来近似。在每次向前传递期间,概率层的权重从该代理分布中被采样。

因此,多次引入相同的输入将导致每次预测略有不同。在分类问题中,模型将产生每一类的概率分布。这种概率分布可用于评估模型预测的不确定性:如果不确定性有限,重复的预测将彼此非常接近,而预测的广泛分布意味着较大的模型不确定性。

本博客将重点介绍一个特定概率密集层(Flipout)的实现,使用 Tensorflow 概率模块可以轻松实现。我们使用相同的方法添加密集翻转层,而不是将普通密集层添加到预定义的 VGG16 网络。Flipout 的完整数学背景由 Wen 等人描述,可在的找到。

训练完模型后,我们的密集 Flipout 层的输出乍一看是相似的:一个数组表示 6 个类中每一个的概率。然而,如上所述,由于翻转层在每次向前传递时从分布中采样权重,所以同一图像的每次预测略有不同。通过多次重复对某一图像的预测,可以获得 7 类皮肤损伤中每一类的概率分布。

Density plots of two images passing through the network 100 times

左边的每幅图像显示了属于“黑色素细胞痣”(蓝色)或“黑色素瘤”(橙色)类别的图像的概率分布,这是通过将每幅图像通过网络 100 次而产生的。x 轴反映图像属于其中一个类别的概率,而图的高度表示分布密度。

医生的附加信息的价值可以用所描绘的密度图来说明。让我们看看左边的图:通过“正常”卷积神经网络传递第一幅图像将产生“黑色素细胞痣”(蓝色)类的低点估计和“黑色素瘤”(橙色)类的高点估计。概率翻转层能够评估这些预测的不确定性。具体来说,左图显示“黑色素细胞痣”类别的预测(低)概率变化很小。然而,“黑色素瘤”类别的分布有更多的变化,这意味着图像属于“黑色素瘤”类别的概率是相当不确定的。

总之,“正常的”卷积神经网络将为每一类提供一个概率,而包含概率翻转层的模型产生每一类的概率分布,因此可以用于评估模型预测的不确定性。医生可以使用这些额外的信息来更好地理解预测,并使用他/她的知识来确认或排除某个诊断。

Grad-CAM

梯度加权类激活映射(Grad-CAM)是一种从卷积神经网络的最终卷积层提取梯度的方法,并使用该信息来突出显示对图像属于预定义类的预测概率最负责的区域。

Grad-CAM 的步骤包括用随后的全局平均池提取梯度。添加了 ReLU 激活函数,以仅描绘对预定义类别有积极贡献的图像区域。可以在原始图像上绘制所得到的注意力地图,并且可以将其解释为用于识别模型“关注”的区域的视觉工具,以预测图像是否属于特定类别。鼓励对 Grad-CAM 背后的数学理论感兴趣的读者通过 https://arxiv.org/abs/1610.02391阅读 Selvaraju 等人的论文。

下面的代码演示了用我们的基本模型实现 Grad-CAM 的相对容易性。

这些图像展示了黑色素瘤的原始图像和使用 Grad-CAM 算法创建的叠加注意力图的相同图像。这些图像清楚地说明 Grad-CAM 产生了对日常临床实践有用的额外信息。该注意力图反映了皮肤损伤的哪些部分对模型的预测影响最大。这一信息可能对指导皮肤活检寻找可疑诊断的确认有价值。此外,如果该算法的预测是准确的,那么在不同的患者中重复使用该算法并结合视觉特征将增加医生对该算法预测的信任。

结论

卷积神经网络有可能为放射科医生、皮肤科医生和病理学家等几个医学专业提供额外的诊断工具。然而,仅仅提供类别预测的模型是不够的。我们认为,引入方法,如添加概率推理和 Grad-CAM,可以深入了解模型的决定性属性,因此对于医生理解并开始在日常临床实践中采用机器学习算法至关重要。

关于作者

Rik Kraan 是医学博士,在荷兰数据科学咨询公司 Vantage AI 担任数据科学家。请随时通过rik.kraan@vantage-ai.com联系

特别感谢 理查德 洛克

媒介合伙人计划计算作家收入的新模型——线性回归分析

原文:https://towardsdatascience.com/medium-partner-programs-new-model-for-calculating-writer-s-earnings-using-basic-linear-regression-bddf8ef7e431?source=collection_archive---------22-----------------------

2019 年 10 月 22 日,medium 公布了计算作家收入的新模型。根据这种新模式,收益将根据媒介会员的阅读时间来计算。你可以从这篇文章中找到更多关于新模式的信息: 改进我们计算作家收入的方式

新模式自 2019 年 10 月 28 日起生效。我查看了过去 5 天(2019 年 10 月 28 日至 2019 年 11 月 2 日)我在这种新模式下的收益。对于给定的故事,我很好奇,也很兴奋地想知道我的日常收入与媒体成员的阅读时间之间的关系,所以我转向数据分析来寻找答案。

1.使用新模型赚钱的所选故事的数据集

这是我的一些故事的数据集,这些故事使用新的模式赚了钱。

Daily earnings versus member reading time for selected stories using the new partner program model.

2.收入与会员阅读时间相关系数的计算

使用 Excel 中的 CORREL() 函数,我们发现相关系数为 0.93,表明收益与会员阅读时间之间存在较强的正相关关系。

3.基本线性回归分析

为了量化收入与会员阅读时间之间的关系,我们使用 Excel 进行了基本的线性回归分析。

通过简单的回归分析,我们发现了收入($)和会员阅读时间(分钟)之间的关系:

注意:这种关系仅适用于成员阅读时间在 11 分钟到 255 分钟的范围内,该范围用于训练模型。

我们使用拟合模型预测每日收入,使用会员阅读次数的原始训练数据,发现均方误差由下式给出:

4.使用归一化特征的线性回归

由于成员读取时间包含范围[11,255]内的值,我们决定在执行线性回归分析之前对我们的特征进行归一化。以下是使用归一化要素的线性回归分析的输出:

我们使用使用归一化特征的拟合模型,使用会员阅读次数的原始训练数据来预测每日收入,并发现均方误差由下式给出:

将其与我们的原始拟合进行比较,我们看到有轻微的改进,但是 MSE 值的差异并不太显著。

因此,基于我们的简单模型,我们已经证明了收入与会员阅读时间的关系如下:

该等式可用于预测会员阅读时间在[11,255]分钟范围内的收入。

5。每日收入可变性的来源

我认为收益的可变性可以用一个非常简单的模型来解释。根据对数据的观察,收入似乎是根据所有成员的平均每日阅读时间计算的。

由于每个成员每月支付 5 美元的费用,让我们假设 medium 使用 2 美元的维护费,这样剩下 3 美元的余额可用于支付给作者。

假设一个月有 30 天,这意味着一个成员每天的价值是 3 美元除以 30,即 0.1 美元。在所有会员平均每天阅读时间为 5 分钟的一天,收益率将为 0.1 美元除以 5 分钟或$ 0.02/分钟。然而,在所有会员平均每天阅读时间为 10 分钟的一天,收益率将是 0.1 美元除以 10 或0.01 美元/分钟

这个简单的模型可以解释收益率的每日变化。

总之,我们已经展示了如何使用合作伙伴计划的最新模型,使用简单的线性回归模型来预测作家的收入。随着越来越多的收入数据从新的媒体合作伙伴计划模型中获得,我们希望在未来扩展这种计算方法。

认识一下 Yauhen:白俄罗斯第一位也是唯一一位 Kaggle 特级大师。

原文:https://towardsdatascience.com/meet-yauhen-the-first-and-the-only-kaggle-grandmaster-from-belarus-ee6ae3c86c65?source=collection_archive---------18-----------------------

与 Yauhen Babakhin 的对话:H2O.ai 的数据科学家和 Kaggle 竞赛的特级大师。

竞争数据科学不仅仅是简单地应用算法来获得最佳模型。参加这些比赛的主要收获是,它们提供了一个学习和培养技能的绝佳机会。这些知识可以用于一个人的学术或职业生活中。 Kaggle 是数据科学竞赛最知名的平台之一,它提供了一个就一些最有趣的机器学习问题进行竞争的机会。经验丰富的人参加这些比赛。有些人做得非常好,并获得了卡格尔大师的称号。在这个系列中,我揭示了卡格尔大师们的惊人故事。

在本次采访中,我将与yau hen Baba Khin a Kaggle 竞赛特级大师、数据科学家H2O.a i. Yauhen 拥有应用数据分析硕士学位,在数据科学领域拥有超过五年的经验。Yauhen 恰好是白俄罗斯第一届 Kaggle 比赛的特级大师,在经典机器学习和深度学习比赛中都获得了金牌。

以下是我与雅亨对话的摘录:

  • 你是白俄罗斯第一位 Kaggle 比赛特级大师。Kaggle 最初吸引你的是什么,你是什么时候赢得第一次胜利的?

Yauhen: 我从 Edx 上的一门在线课程开始了我的数据科学之旅。作为课程的一部分,有一个 Kaggle 比赛,这是我第一次接触到 Kaggle 的概念。我在比赛中排名第 450 位(在公共排行榜上排名前 50 位),但这是一次很好的学习机会,也是继续学习数据科学的动力。大约六个月后,我参加了第二次 Kaggle 比赛,并在那里获得了银牌。

Yauhen’s Kaggle Profile

目前,我是白俄罗斯第一个也是唯一一个 Kaggle 特级大师,但是有很多 Kaggle 大师,数据科学社区发展非常快。

  • 你在经典的机器学习和深度学习比赛中都有金牌。你觉得哪些比赛更有挑战性?

Yauhen: 我会说所有的比赛都具有挑战性,但如果让我选择,我会说参加深度学习比赛相对更难。深度学习比赛需要很长的训练时间,所以不可能快速迭代。这使得评估所有的假设变得很困难,人们犯错误的可能性也小得多。

  • 你通常如何处理一个难题?

Yauhen: 我一般会在一个比赛推出后等一两个星期。如果竞争存在一些问题,如数据泄露、数据不正确等。,这些都位于前几周,节省了很多时间。

然后,就像其他人一样,我从探索性数据分析部分开始,然后是假设生成、建立本地验证,并尝试不同的想法和方法。通常,我会创建一个文档,存储所有这些想法、假设、论文和资源,我认为它们可以为这个特定的比赛服务。有时这样的文档甚至可以包含多达 20 页的文本。

除了上面的方法,我在比赛期间关注所有的论坛和核心讨论,以获得对同一问题的不同意见。

  • 您最近在 Kaggle days China 上发表了演讲,您谈了哪些话题,体验如何?

这是我第二次参加卡格尔节。五月,我参加了 Kaggle Days 的迪拜版,做了一个关于伪标签的演讲。这次在北京,我参加了一个关于“机器学习管道中的常见错误”的研讨会我准备了几条管道,观众必须找出其中的错误。

Yauhen(7 from L) with other H2O.ai Kaggle Grandmasters during H2O world New York

我喜欢卡格尔日的形式。它允许参与者参加卡格尔大师们举办的讲座和研讨会。此外,在活动的第二天,与会者将参加由 Kaggle 大师提供指导的 8 小时线下比赛。

  • 就数据科学而言,您最喜欢的资源是什么?你更喜欢哪种编程语言?

Yauhen: 随着机器学习和数据科学的飞速发展,很难跟踪每一种可能的资源。所以,我试着把自己限制在一个特定的领域或者一个我目前正在解决的特定问题上。

首先,我将命名为开放数据科学社区(ods.ai) 。它主要是一个讲俄语的 slack 社区,拥有大约 4 万名成员和几乎每个数据科学主题的频道。在这里,人们可以在几秒钟内快速获得任何数据科学概念的信息。然而,如果我需要更深入地理解任何材料,我会直接去找一些博客帖子、论文、youtube 视频等。

说到编程语言,我使用 R 语言开始了我的数据科学之旅,但现在我主要使用 Python

  • 作为 H2O.ai 的一名数据科学家,你的角色是什么?你在哪些具体领域工作?

Yauhen(3 from R) with other ‘Makers’ during the H2O Prague Meetup

Yauhen: 我目前在做计算机视觉领域的 AutoML 模型。H2O.ai 的无人驾驶人工智能已经可以处理表格、时间序列和文本数据。现在,我们正在前进,使用无人驾驶人工智能和图像数据来解决分类、分割、物体检测等问题

这个想法是,一旦用户提供了一个包含图像路径和图像标签的 CSV 文件,无人驾驶人工智能应该在时间限制下,自动从这些数据中建立最佳模型。这将需要自动化所有的超参数搜索,例如学习率、优化器、神经网络架构等。和训练过程,如时期数、扩充选择等。此外,这个过程在时间和内存使用方面应该是高效的。我们正在努力,并取得了一些积极的成果。

  • 你通过 Kaggle 学到的最好的东西有哪些是你在 H2O.ai 的专业工作中应用到的?

Yauhen: 我用影像资料参加过几次 Kaggle 比赛。它提供了一个很好的背景,让你知道什么想法在实践中最有效,哪些可以自动化。此外,我会继续阅读竞赛获胜者的解决方案,即使我没有参加某个特定的竞赛。

这样的实用技巧一般不会在任何书籍或在线课程中描述。这就是为什么 Kaggle 允许一个人保持在该领域发展的边缘,并不断改善我们的计算机视觉问题的 AutoML 管道。

Yauhen presenting a session on the capability of Driverless AI with image data at H2O World New York,2019

  • 你想在 ML 中应用你的专业知识吗?

我在很多领域都有丰富的经验,比如经典的机器学习、自然语言处理和计算机视觉。但是,我从来没有处理过音频数据。因此,应用一些技术来解决问题是很有趣的,例如音频记录的分类或自然语言理解等等。

  • 给刚刚开始或希望开始数据科学之旅的数据科学有志者一句忠告?

Yauhen: 在我看来,人们应该记住,数据科学之旅在理想情况下应该是理论知识和实践经验的结合。

仅仅阅读书籍、博客文章、浏览在线课程不会给你任何实践经验。你只能获得一些理论上的理解,而不能应用于实践。另一方面,直接进入应用程序也将成为一个猴子的工作。运行 simple fit()-predict()并盲目复制公共 Kaggle 内核,而不了解幕后发生了什么,也将使你一事无成。

所以,我会建议选一门好的网络课程,完成它所有的练习。此外,参加 Kaggle 竞赛,应用你刚刚从论文、书籍、博客等中学到的理论方法。通过这种方式,你会牢牢掌握基本原理,也会理解它们的实际用途。

这次采访是另一个很好的例子,展示了像 Yauhen 这样的人如何以系统的方式努力工作来实现他们的目标。他们定义了一条清晰的道路,并朝着他们的目标努力。从这次谈话中另一个很大的收获是,拥有良好的理论知识只在一定程度上有用。然而,真正考验你理解力的只有当你将所学付诸实践的时候。

阅读本系列的其他采访:

  • Rohan Rao:数据科学家从数独到 Kaggle 的旅程
  • Bojan Tunguz:从学术界到 Kaggle:物理学家如何在数据科学中找到爱情
  • Shivam Bansal:数据科学家,负责 Kaggle 上的“有益的数据科学”竞赛。

Meetup 总结:R 中的调查和衡量发展

原文:https://towardsdatascience.com/meetup-recap-survey-and-measure-development-in-r-2df3549e5af6?source=collection_archive---------28-----------------------

你有没有在医生那里做过调查或者参加过工作面试,并且想知道这些数据到底是用来做什么的?关于如何从自我报告调查数据中可靠地测量“潜在”特质,如抑郁或忠诚,有一系列长期存在的方法,其中许多来自心理学。

虽然测量是从人体运动学到教育等领域的一种常见方法,但它通常是在 SPSS 或 MPlus 等专有工具中进行的。关于 R 中的调查开发,确实没有太多的在线培训,但是该程序无法通过像[psych](https://cran.r-project.org/web/packages/psych/index.html)[lavaan](http://lavaan.ugent.be/)这样的包来进行。

整个夏天,我向大克利夫兰 R 用户会议小组介绍了以下长达一小时的 R 调查发展研讨会。视频和幻灯片在下面。您还可以在 RStudio Cloud 上访问演示中使用的所有代码、文件和资源。

幻灯片:

有群体间联系的成员更有可能在 NBA 在线论坛上使用负面语言

原文:https://towardsdatascience.com/members-with-intergroup-contact-are-more-likely-to-use-negative-language-in-online-nba-discussion-9f937837f0b1?source=collection_archive---------36-----------------------

本博客总结了我们的 CSCW 2019 论文" 野外的群际接触:表征 NBA 相关讨论论坛中群际与单群成员的语言差异。 ”由【】谭*。*****

近年来,人们越来越关注世界政治中的两极分化和部落主义。人们会将自己视为社会“部落”的成员,并对其他群体产生敌意。在社交媒体时代,Twitter、Reddit 和脸书等平台可能导致美国共和党和民主党进一步分裂。

为了减少偏见,在具有不同意识形态的人之间建立桥梁,一个建议的策略是让人们走出他们的“回音室】,鼓励与对立群体的群体间接触。这一策略已被证明在许多离线环境中有效,因为人际互动可以挑战人们对彼此的刻板印象。硅谷的一些服务提供商正在他们的社交媒体平台上试验这一策略。在 2018 年接受《华盛顿邮报》采访时,Twitter 首席执行官杰克·多西表示,他的公司正在测试一些功能,这些功能将在 Twitter 的时间表中推广不同的观点,以解决错误信息,减少“回音室”

然而,所提出的战略可能不会取得理想的结果。事实上,最近几项实验研究已经在网上平台上对它进行了测试,我们看到了相互矛盾的结果:群际效应既可以有正效应,也可以有负效应。在先前的研究中有这些矛盾的结果,我们相信观察研究允许研究人员在野外描述群体间接触的特征,并在不同的背景下提供有价值的补充证据。事实上,随着在线群体的出现,在相当长的时间内大规模观察群体间的联系和个人行为已经成为可能。

Reddit 上 NBA 相关社区的群际设置

我们利用 Reddit 的 NBA 相关论坛的现有结构来识别用户的群体从属关系和职业体育背景下的群体间联系,这是一个不同于政治的新领域。我们选择职业运动队的在线粉丝群作为我们的测试平台,原因如下:

  1. 职业体育在现代生活中起着重要的作用。美国民众 2015 年观看体育比赛的时间超过310 亿小时,2017–2018 年美国国家篮球协会(NBA)赛季的上座率达到2200 万。
  2. 与政治环境类似,职业体育在本质上无疑是竞争性的。运动队的球迷可以把对方球队的球迷当成敌人,有时甚至会搞暴力。体育迷也倾向于认为媒体和来自对立球队的支持者很可能会对他们喜欢的球队有不公平的看法,就像意识形态不同的人一样。
  3. /r/NBA subreddit 致力于所有 NBA 球队的球迷之间就任何与 NBA 有关的讨论进行互动。它代表了一个开放和多样化的群体间接触的环境。更重要的是,/r/NBA 的一个独特机制,被称为 flair ,让我们可以轻松识别球迷的球队归属。

The illustration of NBA-related discussion forums (also known as subreddits) on Reddit.

上图说明了我们的框架。NBA 有 30 支球队,每支球队都在 reddit 上有自己的讨论论坛(以下简称 team subreddit),相应球队的球迷可以在这里聚集并讨论新闻、比赛和任何其他与球队相关的话题。中央的/r/NBA 标志代表/r/NBA,不同球队的球迷在这里进行团体间的接触。鉴于 team subreddit 和/r/NBA 的不同性质,我们首先定义两个设置:

  1. 团际设定:/r/NBA。
  2. 组内设置:每支球队的子区(如湖人的子区和凯尔特人的子区)。

基于这两个设定,我们根据他/她在/r/NBA 中的行为(缺失)来确定一个球队的球迷是否暴露在群际接触中,我们称之为群际状态。总而言之,我们将球队的球迷分为以下两类:

  1. Intergroup(红色图标):在赛季中同时在附属球队 subreddit 和/r/NBA 发帖的球队球迷。
  2. 单组(蓝色图标):赛季中只在所属球队 subreddit 发帖而不在/r/NBA 发帖的球队球迷。

在比较之前,我们确保群际和单组成员在附属团队子群中的任何可观察特征上先验平衡,这表明对团队的忠诚度相似。为了实现这一点,我们采用匹配技术:对于每个单组成员,我们将他/她与来自同一附属团队的最相似的不匹配组间成员进行匹配,其中相似性是基于可观察的活动特征来测量的(查看我们的论文以了解详细信息)。

组内语言差异

我们发现群际成员比单组成员在他们所属的小组中更情绪化。这反映在他们对负面词汇、脏话和仇恨言论的使用上。举例来说,下图比较了所有团队(all)中组间成员和单组成员使用负面词汇的情况。我们在两个最大的(GSW,LAL)和最小的(DEN,ORL)子团队中看到了相同的趋势,这两个子团队是由至少有 100 个单组成员的团队中的订户数量排名的。我们进一步在右上角显示了所有 30 个团队的散点图,以说明我们的发现在团队之间是稳健的。此外,我们还比较了这两组成员之间的积极语言使用,但我们没有发现他们之间的一致差异(更多细节见我们的论文)。

The comparison of negative word usage between intergroup and single-group members in the 2018 season.

The top-10 over-represented words used by intergroup (red) and single-group (blue) members in the 2018 season.

为了进一步解释群际和单群成员在语言使用上的差异,我们确定了一个更有可能被群际和单群成员使用的区别词列表。上图显示,单组成员在附属团队 subreddit 中评论时更加友好和冷静,使用更多礼貌用语,如“同意”、“感谢”、“帮助”。此外,“座位”表明一些单组成员是当地球迷,因为他们经常讨论有关参加现场比赛的信息。相比之下,组间成员使用更多的脏话,谈论更多的裁判(可能是抱怨)。

不同层次的群际接触

****我们的观察研究表明,高水平群际接触的成员倾向于使用更多的负面语言,但群际接触水平如何影响负面语言的使用存在不同的机制。我们根据用户在组间设置(/r/NBA)中的评论分数,对所有 30 个团队子编辑中的用户进行分组,并为他们分配标签 1、2、3、4 或 5。较大的标签表明较高水平的群体间接触。我们还为单组成员分配标签 0。下图显示了不同群体间接触水平的成员之间的负面语言使用差异。群体间接触水平较高的成员通常在语言使用上更消极:他们倾向于使用更多的负面词汇和脏话,并在附属团队 subreddit 中产生更多的仇恨言论评论。然而,趋势不一定是线性的。例如,水平 1 的组间成员在左侧的消极词汇使用上与单组成员没有显著差异,而水平 5 的组间成员在两个图中都呈现出从先前水平的显著跳跃。

Negative and swear word usage of members with different intergroup contact levels in the 2018 season.

同一用户的组内行为与组间行为

到目前为止,我们已经证明了群际成员在他们所属的团队子群中使用更多的负面语言。但这是为什么呢?通过比较他们在组间环境和组内环境中的行为,我们发现他们在组间环境中使用更多的负面语言,因为他们比在组内环境中使用更多的负面词汇和脏话,并产生更多的仇恨言论。请注意,这种比较自然适用于受试者:我们在两种情况下比较同一个人。我们的结果表明,尽管在附属团队 subreddit 中,群际成员比单群成员更情绪化,但他们并不像在群际环境中那样“令人发指”。相比较而言,当去 intergroup setting 与其他队组的粉丝对抗时,他们往往会有更多的负面互动,并互相 troll。

Intergroup members use more negative words in the intergroup setting than in the intragroup setting in the 2018 season.

社交媒体会导致两极分化吗?

Twitter、Reddit 和脸书已经成为政治讨论和错误信息的重要平台。服务提供商正在设计新的功能,主动让人们接触到反对的观点。然而,所提出的解决方案可能会增加极化。与几十年的线下实验不同,这些实验大多表明对立团体成员之间长时间的亲密接触会产生积极影响,贝尔等人和我们的工作的结果表明,在网上遇到来自对立团体的观点可能会使他们更加坚持自己的观点。通过研究群体间接触影响个体态度的可能机制,对这种对比有几种可能的解释。首先,在社交媒体上创建的评论通常很简短。这些没有足够上下文的短消息可能不会增强对对立群体的了解。第二,讨论结构可能会促进负面互动的传播。 Cheng 等人研究了上讨论的演变,表明讨论线索中现有的钓鱼评论显著增加了将来出现钓鱼评论的可能性。第三,社交媒体交流的匿名性和自发性可能不利于培养同理心。总之,根据环境和接触的性质,组间接触可能导致不同的结果。

我们能为不同的群体设计更好的在线论坛吗?

我们工作中的发现表明,社交平台设计者应该考虑在线塑造群体间联系的策略。正如上面所暗示的,推荐用户关注对立团体或对立观点的成员是不够的。需要试验更好的设计策略来鼓励民间和更广泛的群体间接触。考虑不同水平的群体间接触如何以不同方式缓和个人意见也是有益的。在群体间接触的背景下,内容适度可能是未来研究的一个有前途的领域。类似地,传播在线信息的一种强有力的方式是通过社会共识线索和在线认可(例如,支持票、赞)。然而,简单地推广最受欢迎的内容有时会有问题。早期研究表明,带有更多情感负载词的推文可能会受到喜爱或转发,政治家可能会有意使用这种策略来最大化 Twitter 上的影响。这种类型的行为会引起对立群体的负面反应,并推动整个讨论向更情绪化和可能两极分化的内容发展。因此,重要的是开发评论排名系统,认识到群体间的联系,并优先考虑建设性的互动。

Keras & Tensorflow 中基于深度卷积网络的模因文本生成

原文:https://towardsdatascience.com/meme-text-generation-with-a-deep-convolutional-network-in-keras-tensorflow-a57c6f218e85?source=collection_archive---------6-----------------------

这篇文章的目标是描述如何为文本生成构建一个深度的 conv 网络,但是比我读过的一些现有文章更有深度的 T2。这将是一个实用的指南,虽然我建议了许多最佳实践,但我不是深度学习理论的专家,也没有读过每一篇相关的研究论文。我将讨论数据清理、训练、模型设计和预测算法。

步骤 1:构建培训数据

我们将从中提取的原始数据集是来自 Imgflip meme 生成器用户的大约 1 亿条公共 Meme 说明。为了加快训练速度和降低模型的复杂性,我们只使用 48 个最流行的模因和每个模因正好 20,000 个标题,总共 960,000 个标题作为训练数据。然而,由于我们正在构建一个世代模型,因此标题中的每个字符都将有一个训练示例,总计约 45,000,000 个训练示例。这里选择了字符级生成而不是单词级,因为模因倾向于使用拼写和语法…呃…创造性地。此外,字符级深度学习是单词级深度学习的超集,因此如果你有足够的数据,并且你的模型设计足以学习所有的复杂性,则可以实现更高的准确性。如果你尝试下面的成品模型,你也会发现 char 级别会更有趣!

如果第一个模因标题是“制造所有模因”,则训练数据看起来如下。我省略了从数据库读取和执行初始清理的代码,因为它非常标准,并且可以通过多种方式完成。

training_data = [
    ["000000061533  0  ", "m"],
    ["000000061533  0  m", "a"],
    ["000000061533  0  ma", "k"],
    ["000000061533  0  mak", "e"],
    ["000000061533  0  make", "|"],
    ["000000061533  1  make|", "a"],
    ["000000061533  1  make|a", "l"],
    ["000000061533  1  make|al", "l"],
    ["000000061533  1  make|all", " "],
    ["000000061533  1  make|all ", "t"],
    ["000000061533  1  make|all t", "h"],
    ["000000061533  1  make|all th", "e"],
    ["000000061533  1  make|all the", " "],
    ["000000061533  1  make|all the ", "m"],
    ["000000061533  1  make|all the m", "e"],
    ["000000061533  1  make|all the me", "m"],
    ["000000061533  1  make|all the mem", "e"],
    ["000000061533  1  make|all the meme", "s"],
    ["000000061533  1  make|all the memes", "|"],

    ... 45 million more rows here ...
]
# we'll need our feature text and labels as separate arrays later
texts = [row[0] for row in training_data]
labels = [row[1] for row in training_data]

和机器学习中的大部分事情一样,这只是一个分类问题。我们将左边的文本字符串分类到大约 70 个不同的桶中,桶是字符。

我们来解一下格式。

  • 前 12 个字符是 meme 模板 ID。这使得模型能够区分我们正在喂它的 48 种不同的迷因。该字符串用零填充,因此所有 id 的长度相同。
  • 01是当前被预测文本框的索引,一般 0 是顶框,1 是底框,虽然很多模因更复杂。这两个空格只是额外的间隔,以确保模型可以将框索引与模板 ID 和 meme 文本区分开来。注意:关键是我们的卷积核宽度(见后文)不超过 4 个空格加上索引字符,也就是≤ 5。
  • 之后是迄今为止迷因的文本,用|作为文本框的结束字符。
  • 最后,最后一个字符本身(第二个数组项)是序列中的下一个字符。

在训练之前,对数据使用了几种清理技术:

  • 修剪开头和结尾的空白,用一个空格字符替换重复的空白(\s+)。
  • 应用最小长度为 10 个字符的字符串,这样我们就不会产生无聊的一个单词或一个字母的模因。
  • 应用 82 个字符的最大字符串长度,这样我们就不会生成超长的模因,因为模型将训练得更快。82 是任意的,它只是使整体训练字符串大约 100 个字符。
  • 将所有内容都转换成小写,以减少模型必须学习的字符数量,因为许多模因都是大写字母。
  • 跳过带有非 ascii 字符的 meme 标题,以降低模型必须学习的复杂性。这意味着我们的特征文本和标签都将来自大约 70 个字符的集合,这取决于训练数据恰好包括哪些 ascii 字符。
  • 跳过包含管道字符|的 meme 标题,因为它是我们特殊的文本框结尾字符。
  • 通过语言检测库运行文本,跳过不太可能是英语的迷因说明。提高了我们生成的文本的质量,因为模型只需学习一种语言,而相同的字符序列在多种语言中可以有不同的含义。
  • 跳过我们已经添加到训练集的重复迷因标题,以减少模型简单记忆整个迷因标题的机会。

我们的数据现在可以输入神经网络了!

步骤 2:数据张量化

这可能是也可能不是一个词。有趣的事实:显然,我们在深度学习领域是异教徒,因为我们称多维数组为张量,而不是数学术语“全息”,这是一种不需要特殊变换属性的广义张量。但无论如何,张量听起来比全息更酷;)

首先,这是我们下面要做的所有事情的 python 导入代码:

**from** keras **import** Sequential
**from** keras.preprocessing.sequence **import** pad_sequences
**from** keras.callbacks **import** ModelCheckpoint
**from** keras.layers **import** Dense, Dropout, GlobalMaxPooling1D, Conv1D, MaxPooling1D, Embedding
**from** keras.layers.normalization **import** BatchNormalization
**import** numpy **as** np
**import** util  # util is a custom file I wrote, see github link below

神经网络对数字的张量(向量/矩阵/多维数组)进行操作,因此我们需要相应地重构我们的文本。我们的每个训练文本都将被转换为一个整数数组(一个秩为 1 的张量),方法是用数据中找到的大约 70 个唯一字符的数组中的相应索引来替换每个字符。字符数组的顺序是任意的,但是我们选择按字符频率来排序,这样当改变训练数据量时,它会保持大致一致。Keras 有一个 Tokenizer 类,你可以用它来做这件事(char_level=True ),但是我写了自己的 util 函数,因为它们肯定比 Keras tokenizer 快。

# output: {' ': 1, '0': 2, 'e': 3, ... }
char_to_int = util.map_char_to_int(texts)# output: [[2, 2, 27, 11, ...], ... ]
sequences = util.texts_to_sequences(texts, char_to_int)labels = [char_to_int[char] for char in labels]

这些是我们的数据按频率顺序包含的字符:

0etoains|rhl1udmy2cg4p53wf6b897kv."!?j:x,*"z-q/&$)(#%+_@=>;<][~`^}{\

接下来,我们将使用前导零填充整数序列,使它们都具有相同的长度,因为模型的张量数学要求每个训练示例的形状都相同。(注意:我可以在这里使用低至 100 的长度,因为我们的文本只有 100 个字符,但是我希望以后所有的池操作都能被 2 整除。)

SEQUENCE_LENGTH = 128
data = pad_sequences(sequences, maxlen=SEQUENCE_LENGTH)

最后,我们将整理我们的训练数据,并将其分成训练集和验证集。洗牌(使顺序随机化)确保数据的特定子集不总是我们用来验证准确性的子集。将一些数据拆分到一个验证集中,可以让我们衡量模型在我们不允许它用于训练的例子上的表现。

*# randomize order of training data*
indices = np.arange(data.shape[0])
np.random.shuffle(indices)
data = data[indices]
labels = labels[indices]*# validation set can be much smaller if we use a lot of data* validation_ratio = 0.2 ifdata.shape[0] < 1000000 else0.02
num_validation_samples = int(validation_ratio * data.shape[0])

x_train = data[:-num_validation_samples]
y_train = labels[:-num_validation_samples]
x_val = data[-num_validation_samples:]
y_val = labels[-num_validation_samples:]

第三步:模型设计

我选择使用卷积网络,因为卷积训练简单快速。我确实短暂地测试了一个两层 LSTM,但每次训练的精度比 conv 网络差,即使是这么小的 LSTM,预测的时间也比宇宙的年龄长(好吧,可能只是感觉太长了)。生成敌对网络是具有巨大潜力的美丽生物,但将它们用于文本生成仍处于早期阶段,我的第一次尝试也乏善可陈。也许这将是我的下一篇文章…

好了,下面是在 Keras 中用来构建我们的 conv 网模型的代码:

EMBEDDING_DIM = 16model = Sequential()model.add(Embedding(len(char_to_int) + 1, EMBEDDING_DIM, input_length=SEQUENCE_LENGTH))
model.add(Conv1D(1024, 5, activation='relu', padding='same'))
model.add(BatchNormalization())
model.add(MaxPooling1D(2))
model.add(Dropout(0.25))
model.add(Conv1D(1024, 5, activation='relu', padding='same'))
model.add(BatchNormalization())
model.add(MaxPooling1D(2))
model.add(Dropout(0.25))
model.add(Conv1D(1024, 5, activation='relu', padding='same'))
model.add(BatchNormalization())
model.add(MaxPooling1D(2))
model.add(Dropout(0.25))
model.add(Conv1D(1024, 5, activation='relu', padding='same'))
model.add(BatchNormalization())
model.add(MaxPooling1D(2))
model.add(Dropout(0.25))
model.add(Conv1D(1024, 5, activation='relu', padding='same'))
model.add(BatchNormalization())
model.add(GlobalMaxPooling1D())
model.add(Dropout(0.25))
model.add(Dense(1024, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(0.25))
model.add(Dense(len(labels_index), activation='softmax'))

model.compile(loss='sparse_categorical_crossentropy', optimizer='rmsprop', metrics=['acc'])

那里发生了很多事情。下面是所有代码正在做的事情:

首先,该模型使用 Keras 嵌入将每个输入示例从 128 个整数的数组(每个表示一个文本字符)转换为 128x16 的矩阵。嵌入是一个层,它学习一种最佳方式来将我们的每个字符从表示为整数转换为表示为类似于[0.02, ..., -0.91]的 16 个浮点数的数组。这使得模型可以通过在 16 维空间中将字符相互靠近嵌入来了解哪些字符被类似地使用,并最终提高模型预测的准确性。

接下来,我们添加 5 个卷积层,每个卷积层的内核大小为 5,1024 个滤波器,以及一个 ReLU 激活。从概念上讲,第一个 conv 层正在学习如何从字符构造单词,后面的几层正在学习构造更长的单词和单词链(n-grams),每一层都比前一层更抽象。

  • padding='same'用于确保层的输出尺寸与输入尺寸相同,否则宽度为 5 的卷积会使内核每侧的层尺寸减少 2。
  • 选择 1024 作为过滤器的数量,因为它是训练速度和模型精度之间的良好折衷,通过反复试验来确定。对于其他数据集,我建议从 128 个过滤器开始,然后增加/减少两倍,看看会发生什么。更多的过滤器通常意味着更好的模型准确性,但是训练更慢,运行时预测更慢,并且模型更大。但是,如果您的数据太少或过滤器太多,您的模型可能会过拟合,精度会直线下降,在这种情况下,您应该减少过滤器。
  • 在测试了 2、3、5 和 7 之后,选择了内核大小为 5。内核 2 和 3 的表现更差,内核 7 与内核 2 和内核 3 相似,但速度更慢,因为需要多训练 7/5 个参数。在我的研究中,其他人已经成功地在各种组合中使用了大小为 3 到 7 的内核,但我的观点是,大小为 5 的内核通常在文本数据上表现不错,并且您可以随时在以后进行实验,为您的特定数据集挤出更多的准确性。
  • 选择 ReLU 激活是因为它快速、简单,并且非常适合各种各样的用例。我从阅读一些文章和研究论文中得出的结论是,Leaky ReLU 或其他变体可能会对一些数据集产生轻微的改善,但并不保证会更好,而且在较大的数据集上不太可能明显。
  • 在每个 conv 图层后添加批次归一化,以便基于给定批次的均值和方差对下一图层的输入参数进行归一化。深度学习工程师还没有完全理解这种机制,但我们知道标准化输入参数可以提高训练速度,并且由于消失/爆炸梯度,这对于更深的网络变得更加重要。原批次归一化论文成绩斐然。
  • 在每个 conv 图层后添加一点点遗漏,以帮助防止图层简单地记忆数据和过度拟合。Dropout(0.25)随机删除 25%的参数(将其设置为零)。
  • MaxPooling1D(2)被添加到每个 conv 层之间,以将我们的 128 个字符的序列对半“挤压”成后续层中的 64、32、16 和 8 个字符的序列。从概念上讲,这允许卷积过滤器从更深层的文本中学习更抽象的模式,因为我们的 width 5 内核在通过每个 max pooling 操作将维度减少 2 倍后将跨越两倍的字符。

在所有 conv 层之后,我们使用一个全局最大池层,它与普通最大池层相同,只是它会自动选择缩小输入大小的程度,以匹配下一层的大小。最后的层只是具有 1024 个神经元的标准密集(全连接)层,最后是 70 个神经元,因为我们的分类器需要输出 70 个不同标签中每个标签的概率。

model.compile 步骤非常标准。RMSprop 优化器是一个相当不错的全面优化器,我没有尝试为这个神经网络改变它。loss=sparse_categorical_crossentropy告诉模型,我们希望它进行优化,从一组 2 个或更多类别(也称为标签)中选择最佳类别。“稀疏”部分指的是我们的标签是 0 到 70 之间的整数,而不是每个长度为 70 的独热数组。对标签使用一个热阵列会占用更多的内存、更多的处理时间,并且不会影响模型的准确性。不要使用一个热标签!

Keras 有一个很好的model.summary()函数,可以让我们查看我们的模型:

_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
embedding_1 (Embedding)      (None, 128, 16)           1136
_________________________________________________________________
conv1d_1 (Conv1D)            (None, 128, 1024)         82944
_________________________________________________________________
batch_normalization_1 (Batch (None, 128, 1024)         4096
_________________________________________________________________
max_pooling1d_1 (MaxPooling1 (None, 64, 1024)          0
_________________________________________________________________
dropout_1 (Dropout)          (None, 64, 1024)          0
_________________________________________________________________
conv1d_2 (Conv1D)            (None, 64, 1024)          5243904
_________________________________________________________________
batch_normalization_2 (Batch (None, 64, 1024)          4096
_________________________________________________________________
max_pooling1d_2 (MaxPooling1 (None, 32, 1024)          0
_________________________________________________________________
dropout_2 (Dropout)          (None, 32, 1024)          0
_________________________________________________________________
conv1d_3 (Conv1D)            (None, 32, 1024)          5243904
_________________________________________________________________
batch_normalization_3 (Batch (None, 32, 1024)          4096
_________________________________________________________________
max_pooling1d_3 (MaxPooling1 (None, 16, 1024)          0
_________________________________________________________________
dropout_3 (Dropout)          (None, 16, 1024)          0
_________________________________________________________________
conv1d_4 (Conv1D)            (None, 16, 1024)          5243904
_________________________________________________________________
batch_normalization_4 (Batch (None, 16, 1024)          4096
_________________________________________________________________
max_pooling1d_4 (MaxPooling1 (None, 8, 1024)           0
_________________________________________________________________
dropout_4 (Dropout)          (None, 8, 1024)           0
_________________________________________________________________
conv1d_5 (Conv1D)            (None, 8, 1024)           5243904
_________________________________________________________________
batch_normalization_5 (Batch (None, 8, 1024)           4096
_________________________________________________________________
global_max_pooling1d_1 (Glob (None, 1024)              0
_________________________________________________________________
dropout_5 (Dropout)          (None, 1024)              0
_________________________________________________________________
dense_1 (Dense)              (None, 1024)              1049600
_________________________________________________________________
batch_normalization_6 (Batch (None, 1024)              4096
_________________________________________________________________
dropout_6 (Dropout)          (None, 1024)              0
_________________________________________________________________
dense_2 (Dense)              (None, 70)                71750
=================================================================
Total params: 22,205,622
Trainable params: 22,193,334
Non-trainable params: 12,288
_________________________________________________________________

如果你不喜欢在脑子里做张量形状乘法,参数计数会特别有用。当调整我们上面讨论的超参数时,关注模型的参数计数是有用的,它粗略地表示了模型的学习能力总量。

第四步:培训

现在,我们将让模型进行训练,并使用“检查点”来保存沿途的历史和最佳模型,以便我们可以在训练期间的任何时间点使用最新的模型来检查进度和进行预测。

*# the path where you want to save all of this model's files* MODEL_PATH = '/home/ubuntu/imgflip/models/conv_model'
*# just make this large since you can stop training at any time* NUM_EPOCHS = 48
*# batch size below 256 will reduce training speed since* # CPU (non-GPU) work must be done between each batch
BATCH_SIZE = 256*# callback to save the model whenever validation loss improves* checkpointer = ModelCheckpoint(filepath=MODEL_PATH + '/model.h5', verbose=1, save_best_only=True)*# custom callback to save history and plots after each epoch* history_checkpointer = util.SaveHistoryCheckpoint(MODEL_PATH)*# the main training function where all the magic happens!* history = model.fit(x_train, y_train, validation_data=(x_val, y_val), epochs=NUM_EPOCHS, batch_size=BATCH_SIZE, callbacks=[checkpointer, history_checkpointer])

你只需要坐在这里,看着这个神奇的数字在几个小时内上升…

Train on 44274928 samples, validate on 903569 samples
Epoch 1/48
44274928/44274928 [==============================] - 16756s 378us/step - loss: 1.5516 - acc: 0.5443 - val_loss: 1.3723 - val_acc: 0.5891Epoch 00001: val_loss improved from inf to 1.37226, saving model to /home/ubuntu/imgflip/models/gen_2019_04_04_03_28_00/model.h5
Epoch 2/48
44274928/44274928 [==============================] - 16767s 379us/step - loss: 1.4424 - acc: 0.5748 - val_loss: 1.3416 - val_acc: 0.5979Epoch 00002: val_loss improved from 1.37226 to 1.34157, saving model to /home/ubuntu/imgflip/models/gen_2019_04_04_03_28_00/model.h5
Epoch 3/48
44274928/44274928 [==============================] - 16798s 379us/step - loss: 1.4192 - acc: 0.5815 - val_loss: 1.3239 - val_acc: 0.6036Epoch 00003: val_loss improved from 1.34157 to 1.32394, saving model to /home/ubuntu/imgflip/models/gen_2019_04_04_03_28_00/model.h5
Epoch 4/48
44274928/44274928 [==============================] - 16798s 379us/step - loss: 1.4015 - acc: 0.5857 - val_loss: 1.3127 - val_acc: 0.6055Epoch 00004: val_loss improved from 1.32394 to 1.31274, saving model to /home/ubuntu/imgflip/models/gen_2019_04_04_03_28_00/model.h5
Epoch 5/48
 1177344/44274928 [..............................] - ETA: 4:31:59 - loss: 1.3993 - acc: 0.5869

快进一下,下面是我们在每个时期的损失和准确性的一些闪亮的图表:

我发现,当训练损失/准确性比验证损失/准确性更糟糕时,这是模型学习良好而不是过度拟合的迹象。

顺便提一下,如果你使用 AWS 服务器进行培训,我发现最佳实例是 p3.2xlarge。这使用了他们截至 2019 年 4 月的最快 GPU(Tesla V100),该实例只有一个 GPU,因为我们的模型无法非常有效地利用多个 GPU。我确实尝试过使用 Keras 的 multi_gpu_model,但它需要使批处理大小更大才能真正实现速度提升,这可能会扰乱模型的收敛能力,即使使用 4 个 gpu,它也只能快 2 倍。4 个 GPU 的 p3.8xlarge 价格是 4 倍多,所以对我来说不值得。

第五步:预测

好了,现在我们有了一个模型,可以输出哪个字符应该出现在迷因标题中的概率,但是我们如何使用它从头开始创建一个完整的迷因标题呢?

基本前提是,我们用我们想要为其生成文本的任何迷因来初始化一个字符串,然后我们为每个字符调用一次model.predict,直到模型输出框尾文本字符|的次数与迷因中的文本框一样多。对于上面看到的“X All The Y”迷因,文本框的默认数量是 2,我们的初始文本应该是:

"000000061533  0  "

鉴于模型输出的概率为 70,我尝试了几种不同的方法来选择下一个角色:

  1. 每次选择得分最高的角色。这非常无聊,因为它每次都为给定的模因选择完全相同的文本,并且在模因中反复使用相同的单词。它一遍又一遍地吐槽“当你发现你的朋友是 X 所有 Y 迷因的最佳聚会”。它也喜欢在其他迷因中大量使用“最好的”和“派对”这样的词。
  2. 给每个角色一个被选中的概率,这个概率等于模型给它的分数,但前提是这个分数高于某个阈值(最高分的 10%对这个模型来说很好)。这意味着可以选择多个字符,但偏向于得分较高的字符。这种方法成功地增加了多样性,但较长的短语有时缺乏连贯性。这里有一个来自 Futurama Fry meme 的:“不知道她是说还是只是把我的一天放了”。
  3. 给每个角色一个相等的被选中的概率,但前提是它的分数足够高(最高分的 10%以上对这个模型效果很好)。此外,使用波束搜索在任何给定时间保持 N 个文本的运行列表,并使用所有字符得分的乘积,而不仅仅是最后一个字符的得分。这需要 N 倍的时间来计算,但在某些情况下似乎可以提高句子的连贯性。

我目前使用方法#2,因为它比波束搜索快得多,而且两种方法都给出了不错的结果。以下是一些随机的例子:

你可以自己玩最新的模型,从 imgflip.com/ai-meme 48 个迷因中的任何一个中产生。

下面是使用方法#2 进行运行时预测的代码。Github 上的完整实现是一个通用的波束搜索算法,因此只需将波束宽度增加到 1 以上,就可以启用波束搜索。

# min score as percentage of the maximum score, not absolute
MIN_SCORE = 0.1
int_to_char = {v: k for k, v in char_to_int.items()}def predict_meme_text(template_id, num_boxes, init_text = ''):
  template_id = str(template_id).zfill(12)
  final_text = ''
  for char_count in range(len(init_text), SEQUENCE_LENGTH):
    box_index = str(final_text.count('|'))
    texts = [template_id + '  ' + box_index + '  ' + final_text]
    sequences = util.texts_to_sequences(texts, char_to_int)
    data = pad_sequences(sequences, maxlen=SEQUENCE_LENGTH)
    predictions_list = model.predict(data)
    predictions = []
    for j in range(0, len(predictions_list[0])):
      predictions.append({
        'text': final_text + int_to_char[j],
        'score': predictions_list[0][j]
      })
    predictions = sorted(predictions, key=lambda p: p['score'], reverse=True)
    top_predictions = []
    top_score = predictions[0]['score']
    rand_int = random.randint(int(MIN_SCORE * 1000), 1000)
    for prediction in predictions:
      # give each char a chance of being chosen based on its score
      if prediction['score'] >= rand_int / 1000 * top_score:
        top_predictions.append(prediction)
    random.shuffle(top_predictions)
    final_text = top_predictions[0]['text']
    if char_count >= SEQUENCE_LENGTH - 1 or final_text.count('|') == num_boxes - 1:
      return final_text

你可以在 github 上查看所有代码,包括实用函数和一个样本训练数据文件。

第六步:???

第七步:显然,从人工智能生成的迷因中获利

结束了。

钢铁之躯:用经验贝叶斯估计寻找最佳点球手

原文:https://towardsdatascience.com/men-of-steel-finding-the-best-penalty-takers-with-empirical-bayes-estimation-aa0e126fb08b?source=collection_archive---------24-----------------------

当一切都归结为点球,你能相信谁?

Photo by Jannes Glas on Unsplash

可以说是足球比赛中最紧张的时刻,罚球是心理战:两个人,一个球和一个明显的进球机会。一个点球应该在职业水平上完成:句号。其他的都是失败。

这样的任务应该只要求拥有最冰冷血脉的玩家来完成。

有伟大的点球手,我们总是可以指望他们以惊人的节奏效率将球送到网后。还有一些人,他们令人沮丧的努力,注册商标的脚尖跑或近轨道打击,只是我们深感遗憾或无情嘲笑的来源。

你会认为罚点球很容易。或许花 5 分钟看这个视频。

那么谁是真正的超人:钢铁之躯呢?

你可以想象这将是一个简单的二级数学题。我们收集所有点球的记录,计算所有这些球员和 TADA 的相应转换率!

但是让我们看看真实的例子,看看这个简单的逻辑是如何失败的!!!

一方面,我们有克里斯蒂亚诺·罗纳尔多,他有五个金球奖,他的绰号“佩纳尔多”代表了他在球门前坚定不移的自我镇定,他有着令人印象深刻的 98 次点球中 85 次进球的记录(86.7%)。另一方面,我们有一个年轻的天才,阿森纳的尼古拉斯·佩佩,他最近对维拉的进球使他的进球总数达到 11 次成功 10 次(90.9%)。佩佩在点球上比罗纳尔多更好/更可靠吗?

当然,说那样的话会很可笑!!!

虽然年轻球员的得分比例略高,但这并不是很多证据:一个典型的球员几乎 80%的时间都可以得分,佩佩 90.9%的成功率可能是因为运气。另一方面,罗纳尔多有很多证据表明他高于普通球员。

我们如何系统地比较 85/98 和 10/11 这样的比率,并做出有意义的判断?

贝氏统计来救援:

我们发现这种困境的不仅仅是足球。由于低计数的不确定性,我们在处理成功/总数比率时肯定会出错。简单的解决办法就是设置一些门槛,过滤掉那些达不到最低要求的玩家。但这远非理想:我们丢弃了可能有用的信息。

让我后退一步,重新设计问题:我们想在某种程度上衡量一名球员天生的罚球能力。他的历史记录仅仅是对这种能力的估计。任务是根据他的历史记录更准确地评估他的能力。

我希望你能看到这是如何自然地把我们引向一个经典的贝叶斯设置:我们可以从对球员能力的一些的预先期望开始,通过 新证据更新它——也就是说,用他的实际得分记录,我们得到对他真实能力的更实际的估计。

为了更好地回顾贝叶斯框架,你可以看看我的其他文章:

* [## 贝叶斯统计如何说服我去健身房

一个有趣的旅程,进入线性回归理论与贝叶斯触摸(是的,我使用度量测量在这…

towardsdatascience.com](/how-bayesian-statistics-convinced-me-to-hit-the-gym-fa737b0a7ac) [## 寻找上帝的贝叶斯探索

贝叶斯定理和最基本问题的概率答案:“上帝存在吗?”

towardsdatascience.com](/a-bayesian-quest-to-find-god-b30934972473)

先验期望和经验贝叶斯;

我正踩在一颗地雷上。虽然贝叶斯设置有直观的意义,但要让人们在使用每个设置之前达成合理的一致几乎是不可能的。

一个人如何去具体说明他们先前的信念?尤其是如果你没有一个知情的猜测?一种方法可能是分配一个“平坦先验”——一个你指定你的参数的每一个值都是同等可能的先验。另一种方法是使用经验贝叶斯,其中你的数据用于估计先验。这里有一个问题:我没有事先对先验有一个固定的概念,而是在收集数据后查看数据并相应地估计先验分布,这样就可以避免所有的麻烦。

这种方法有很多优点。这很简单,而且它消除了(嗯,某种程度上)当我不得不选择自己的前科时可能产生的主观性。就我个人而言,我发现这种方法有助于我获得一定程度的稳定结果。平坦的先验或与数据不符的东西会导致奇怪的结果,例如负的后验概率。相信我,这并不少见。用经验贝叶斯我更有可能得到理智的答案。

听听著名统计学家布拉德利·埃夫隆对这种方法的看法:

自从我在 20 世纪 70 年代通过 Robbins 和 Stein 第一次接触以来,经验贝叶斯一直是我最感兴趣的话题。有时它仍然像魔法一样。[1]

DataCamp 的首席数据科学家大卫·罗宾逊也提供了一些很好的见解:

这基本上归结为我们有多少观察值:如果我们有很多,我们可以得到一个不太依赖于任何一个个体的好的估计。经验贝叶斯是对更精确的贝叶斯方法的一种近似(T0 )-----------------------就我们所拥有的数据量而言,这是一种非常好的近似。[2]

我知道,这感觉像是欺骗,而且确实如此。许多人认为先验信息是观测值的外生信息,因此批评使用实际数据来估计先验信息,因为这会低估建模误差。任何数据都会对使用相同数据来指定其某些特征的模型感到自满。

寻找先验—贝塔分布:

让我们看一下数据。

我收集了欧洲 6 个不同联赛 13 年的点球数据。看起来是这样的:

Records of penalty kicks — ranked by the total number of kicks taken. Our job is to ‘adjust’ the success ratio in order to compare these players.

如前所述,为了得到成功率先验的一个很好的近似值,我们将看看它的实际分布。

Left: the histogram of our actual penalty conversion rate . Right: The multiple shapes the Beta distribution can describe with its parameters. Source: Wikipedia

在这里,我们的任务是找到一个表征我们的经验惩罚转换率的分布:也就是说,(1)它在一个从 0 到 1 的范围内(没有负概率),(2)它需要灵活,在某种意义上,它可以代表我们在直方图中看到的东西,以及(3)如果当我们结合二项式分布的可能性时,它使我们的贝叶斯计算更容易——二项式分布描述了在试验中的成功次数(即:许多点球中的进球数),那就更好了。

瞧吧, 贝塔分布

贝塔分布在域[0,1]上,所以我们知道它不会比平坦先验差。它在域内高度灵活,其特征在于两个正的形状参数,分别用 αβ 表示(见上图)。

关于贝塔分布最好的部分是,它是二项分布的的共轭先验,这对我们的计算是个奇迹。我们可以从贝塔分布 B(α,β) 作为我们的先验开始,用来自二项分布的信息更新,其中sf失败(未命中),并且得到后验分布,其也是精确形式的贝塔分布* B(α + s,β + f) 这种分布的平均值是【α+s)/(α+β+s+f)***

简直神奇!!!

我在这篇文章的结尾加入了一些数学知识,以防你不相信!

让我们继续寻找我们最好的点球手:

估计我们实际数据的先验:

现在我们已经有了一个清晰的分析框架,是时候将它应用到我们的真实数据集了。

首先,让我们对转化率数据集进行贝塔分布拟合。这可以很简单地用 r 来完成

用这个方法,我得到一个估计值 α = 9.29β = 2.93。让我们看看这个估计与我们的数据有多吻合。

显然,它并不完美,但我们现在可以继续努力。

使用我们的经验先验更新每个玩家的统计数据:

我们现在可以继续,用我提到的公式找到每个玩家转换率的后验分布。即aβ分布形式 B(α + s,β+f)其中 sf 分别是成功和失败的次数。后验均值将为 (α + s)/ (α + β +s+ f)。

例如,c 罗和佩佩的点球转换率的后验分布均值将为:

我们可以将他们的后验概率分布(与其他玩家一起)绘制如下:

The posterior distribution of penalty conversion rate for a few players

我们可以看到,罗纳尔多的强劲记录导致非常高的后验均值和狭窄的可信区间,而佩佩的后验均值转换具有更大的可信区间,因为他的数据较少。与此同时,格里兹曼和桑切斯在点球方面并不出色。

十佳点球手:

在应用了经验贝叶斯估计和贝塔二项式后验计算之后,让我来介绍一下过去 13 年里的前 10 名受罚者。

所以事实证明,最佳点球手是萨利霍维奇和罗西,紧随其后的是布代布、马克·诺布尔和莱万多夫斯基。著名的点球手:兰帕德,杰拉德,哈里·基恩并不像他们声称的那么好。有趣的是,我们可以看到,对于这些玩家来说,在我们应用这个程序后,他们的转化率缩小了。我们可以将原始比率和调整后的比率绘制在图上,以评估调整情况。这一部分的灵感来自大卫·罗宾逊的一篇了不起的文章[2]。

Plot of actual vs adjusted conversion ratios

水平虚线显示了先验分布的平均值——如果我们没有关于玩家的任何信息,我们应该猜测玩家的成功率。然后,我们有了对角线 y = x ,显示实际进球得分平均值等于后验调整的数据点。

有两个有趣的观察。首先,我们可以看到,高于先前均值的点往往会缩小,而低于均值的点会向上膨胀。第二,受收缩影响最小的点是与大量观测相关联的点。当你思考时,这是完全有意义的:如果我们通过观察有很多证据,我们可以依靠实际的估计;否则,相信我们的数据趋向于总体均值是很有价值的。

结论:

好了,我刚刚介绍了经验贝叶斯估计的概念:我们可以利用我们数据的总体分布作为先验,以获得每个平均值的更现实的估计。然后,我们使用共轭先验的强大概念来绕过在我们的过程中计算后验分布的复杂性。贝塔-二项式组合如此受欢迎,以至于你可以把它应用到许多场景中:篮球、点击进入的 A/B 测试、学校食堂评级等等。

出于本文的目的,我方便地忽略了许多复杂性。首先,我们可以看出,我们先验的 beta 分布几乎不太适合。事实上,我们可以用两个 Beta 分布来拟合双峰分布,根据玩家属于每个分布的可能性,将他们分配到两个不同的组中。

你可以查看我解决这个问题的代码。

另一个复杂因素是,罚分转换率随着时间的推移而变化,并且在不同的联赛中有所不同。就我们考虑所有这些不同的因素而言,我们从简单的贝塔-二项式分布走了许多步,进入了 贝叶斯分层模型 的领域。这就是乐趣的开始!!!

附录:

本文的代码和更多内容可以在这里找到。

这是β-二项式共轭配对的一个简短证明。

设置很简单:我们观察一些成功计数 s ,我们认为它们遵循样本大小为 n 的二项式分布,成功率为我们的工作是找到给定 sr 的后验分布。

该是我们调用著名的贝叶斯公式的时候了——只针对连续变量:

似然函数 p(s|r) 和先验 p(r) 遵循明确定义的二项式和贝塔分布。

然后,我们的工作就是插入并找到后验分布。

结果是一种β分布形式 B(α + s,β + f)

[1]统计视图。(2015 年 6 月 1 日)。经验贝叶斯对我来说是最吸引人的话题。有时它仍然像魔法一样:布拉德利·埃夫隆访谈。

[2]罗宾逊,D. (2015 年 10 月 1 日)。理解经验贝叶斯估计(使用棒球统计)*

男人与男人:麻省理工学院深度技术训练营的经验

原文:https://towardsdatascience.com/mens-et-manus-lessons-from-mit-deep-technology-bootcamp-9760733e2146?source=collection_archive---------18-----------------------

Bootcamp Developer Kit

从实践中学习,永远不要害怕失败。

这个短语可以概括我在麻省理工学院深度技术训练营的所有经历,此外,紧张也很好地描述了教室里的每一天。虽然这篇文章的目的不是描述经验,但我想在解释定义、主题和趋势时给出一些想法。最后,分享这一点的想法是为了给一些灵感,解释一个深入技术的大画面,在那里可能会走得更远,特别是如果你是从数据科学或人工智能世界开始的话。

第一课:深度技术

那到底是什么呢?嗯,我发现我自己在第一天也遇到了同样的情况,谢天谢地我们的第一堂课由约书亚·西格尔带来,他帮助我们澄清了 Quora 和风险投资的一些定义:

  • 一套基于科学发现、工程、数学、物理和医学的尖端和颠覆性技术
  • “深度技术是工程与科学发现的结合点”
  • “具有改变世界影响潜力的有形发现或商业化”

对我来说,在度过了那些不眠之夜后,定义深层技术,如“使用尖端和颠覆性技术解决重大问题的切实可行的解决方案”,并且像所有由技术引发的解决方案一样,遵循“炒作周期”[1]有一天成为“高科技”,最终只是“技术”,以及解决方案需要跨越“鸿沟”才能获得成功的采用生命周期。

[1] The “Hype Cycle” (HC) and the “Technology Adoption Lifecycle” (TALC) models plotted together [Hype Cycle, 2012]

在训练营期间,我们发现并实践了一些深层技术促成因素,以构建具有社会或业务影响的最终项目:

  • 物联网
  • 人工智能
  • 机器人自动化
  • 虚拟和增强现实
  • 大数据
  • 区块链

第二课:物联网

我们生活在第五个互联网时代,机器对机器的交流已经成为现实,但这并不意味着高科技。另一方面,物联网是 m2m 的发展,是一项示范性的深度技术,因为它生成和传输要在本地或远程处理的数据,具有全球影响,最初也很难扩展,但经过努力,它将成为无缝的基本需求[麻省理工学院训练营]。

Evolution of Internet [Nokia Insight]

示例:

  • 信号动力学:我们有非常难得的机会去了解更多法德尔·阿迪布的工作,用几句话来概括就是物联网作为大影响推动者的最好例子。首先,我们深入了解了他在的论文关于使用 wifi 看穿墙壁,以及关于数字医疗的研究,他们试图建立一个无电池微型植入物用于药物输送。我强烈推荐去访问和检查他们的作品寻找灵感。

Wireless System for drug delivery

  • 自动驾驶汽车:如今是一个热门话题,在那里我们可以与专家 Sertac Karaman 交谈。他向我们展示了一个简短的时间表,在这个时间表中,我们了解了自动驾驶汽车的真实状态、背后的技术(传感器)、接下来的挑战(交通、 trolly 问题)以及我们有时间与一个 Turtlebot (一个低成本、带有开源软件的个人机器人套件)互动,编写一些代码/算法来让它移动。

We could make the Turttlebot move by itself!

第三课:虚拟和增强现实

因 Pokemon Go 等视频游戏或 Occulus 等设备而闻名,使人们开始谈论 AR 和 VR,因此在训练营期间,我们有机会知道背后的事情,这要感谢圣乔治·帕帕斯。

谈论现实——虚拟光谱可能会令人困惑,所以为了让它容易理解,我要感谢 Hackernoon 分享一个简短的想法。

“如果体验需要特殊的硬件来观看(比如耳机),那就是 VR。如果它使用计算机视觉来读取真实世界的信息,那它就是 AR。如果它既涉及扫描环境以获取数据,又涉及通过耳机进行显示以获得更深的沉浸感,那么它就是 AR 和 VR。”

Reality — Virtuality Spectrum [Hacker Noon]

在有了一个清晰的概念之后,认识到这些技术的用途是很重要的,感谢我们的讲师,我们发现了 ar 和 VR 作为与客户或用户交互的媒介,换句话说,一种传达丰富信息/环境的使能技术。例如,一些有趣的用途是:

  • 边缘型人格障碍虚拟现实
  • 增强博物馆体验的 AR
  • 用于培训人员的虚拟现实
  • AR 家具应用
  • 对我来说,最神奇的是使用虚拟现实模拟汽车驾驶,然后使用这些数据来训练自动驾驶模型!

考虑到应用程序的想法,现实情况是,如今要构建 VR 或 AR 的体验,存在一些平台或 SDK:Unity+Vuforia、 ARCore (Google)、 ARKit (Apple)和 STEAM VR 。我们有机会用 Unity+Vuforia 开发一些基本的 AR 示例,我不得不承认,它的工作给我留下了深刻的印象!

AR Example

第四课:区块链

在所有与比特币相关的炒作中,我对区块链背后的技术感兴趣它是如何工作的?有哪些挑战?所以作为客座讲师,我们被介绍给布莱恩·苏比纳拉。他友好地向我们解释了实际情况和未来。我对类似 智能契约 以及如何将事物之间的‘交流’使用 令牌 这样的概念很着迷。

例如,想象一个世界,我的自动驾驶汽车想要充电,所以首先我向汽车转账 50 美元,这是第一个合同,然后我的汽车向加油站付款是第二个合同,每个合同是一个由足够长的散列标识的,以避免重复,所有交易块都加入到一个链中, 很明显,这看起来并不太复杂,尽管交易中还有其他一些因素需要考虑,比如支撑链条的基础设施、避免假货的交易完整性、监管等。

实际上,存在一些倡议和文件(在特定部门)以及与区块链发展事物的平台。

  • 脸书天秤座
  • 开放音乐倡议
  • R3
  • 微软 Azure
  • 英格兰银行

第五课:创新和设计

多亏了玛丽亚·杨和桑杰·萨尔马,这些话题对我来说是最有趣的话题之一。

首先,我们讨论创新的理论。我想到的第一个例子是自行车。试着记住这些年来所有的模型,它们看起来几乎一样,这意味着创新的主导模型。但是像所有的创新一样,它在产品的生命周期中有一些阶段,例如,想象 2006 年的手机世界,主导设计是一个小屏幕和按钮,每个时期都发生了增量变化,突然 iPhone 作为破坏设备推出,所有这一切又重新开始。

Evolution of mobile phone [easytechnow]

有时存在 有意的创造性破坏 为了推出一项创新,还记得 2012 年苹果把接头换成实际的 lightning 端口或者被指责让老款 iPhones 变慢的时候吗?

当我们思考创新时,有时我们称之为颠覆所以在这里给出一些概念是有好处的“颠覆性创新,顾名思义,指的是一个概念,产品或服务,它通过颠覆现有市场或创造一个全新的市场来创造一个新的价值网络
[ 维玛 ]

因此,持续中断的一些示例如下:

  • MOOCs
  • 支付(微信支付、支付宝)
  • 实时视频

概念测试

在这堂课上,我们被要求思考不同的形式来测试产品,以获得用户反馈。这很有用,因为当我们开始开发一个产品或服务时,这对于了解我们用户的体验很重要例如,我们如何在没有开发无人驾驶汽车的情况下测试一个人的反应?还是来自某个服务的手机 app?或者超越我们如何测试人类去火星旅行?

[## 汽车-在路上-四方视图

这是在 Vimeo 上由 Wendy Ju 制作的“汽车-在路上-四轴视图”,这是高质量视频和热爱…

vimeo.com](https://vimeo.com/140935829)

如果你对这个话题感兴趣,我推荐你访问麻省理工学院设计实验室页面

第 6 课:构建我们的项目

每天课后,我们都努力构建功能原型和发布计划。我们的想法是在最后一天像初创公司一样向评委“推销”我们的产品/服务。在这里,我们面临许多挑战,第一个挑战是与我从未见过的全新的人一起工作(我们来自 4 个大洲!),我们每个人都有不同的技能或背景,第二步是选择一个真正有重大影响的想法(这是最难的),最后构建解决方案并进行推介。

Smart belt project

我们的想法

我们决定为老年人打造智能腰带,我们的重点是让他们有信心在不需要拐杖的情况下行走,因此原型有传感器来检测前方的物体,并在人摔倒时触发或检查温度和脉搏,为此我们使用了:

  • 两个超声波传感器
  • 一个蜂鸣器
  • 一个陀螺仪
  • 温度和心跳传感器
  • 全球(卫星)定位系统
  • 充电宝

我们的想法需要完整,所以它包括市场研究,财务预测,盈利能力分析,以及后端(NodeJS)和分析服务(Databricks)。

Backend and Analytics diagram

结论

这段经历完全值得,每天都在发现或深入一些东西,扩展我的知识,实践麻省理工学院的座右铭 ' 头脑和手'****(Mens et Manus)因为不仅仅是听或参加一个班,做出改变的最好方式是,我们需要用我们的头脑和手来构建实际的解决方案,以产生更大的影响,而一种方法就是使用深层技术。

PS 如果有任何问题可以在 Twitter 和 LinkedIn 上找我。

个人和集体的心智模型

原文:https://towardsdatascience.com/mental-models-in-and-of-individuals-and-collectives-d28fa62f0a4a?source=collection_archive---------25-----------------------

迈向超级智慧理论 中,我描述了一种基于卡尔·弗里斯顿首创的主动推理框架的集体智慧理论。正如主动推理所要求的那样,该理论意味着所有的集体(如团队和组织)都在一个隐含的世界集体模型的基础上运作——这为他们提供了理解观察结果和预测替代行动过程结果的能力(弗里斯兰语中的“政策”)。

如果我们接受定理的观点,即任何马尔科夫毯(因果原子子系统)总是可以被描述为执行某种形式的近似主动推理,这根本不是有争议的。然而,随着我逐渐理解,结论中有一些非常违反直觉的东西。需要解释的事实是,与人、动物、单细胞生物甚至人工智能体不同,集体由明显不同的自主成分组成— 能够作为集体行动。这种集体行动可以像一群鸟的一致行动一样简单,也可以像金融市场将关于未来预期的复杂信息纳入资产价格一样复杂(或者就此而言,一家公司采取复杂的商业战略和生产结构);最突出的一点是,成员是自主的(至少在涉及人类的例子中,会告诉你他们遵循自己的自由意志),然而集体可以非常准确地被描述为一个独立的主体。

事实证明,完全解决这个明显的矛盾需要彻底了解这些模型是什么,这是我在这篇文章中试图做的。在这样做的过程中,我将揭示一些深层的方式,在这些方式中,共性为我们作为个体和作为成员的所有能力提供了基础,而我们大肆吹嘘的差异扮演着关键但次要的角色。

这一员额的结构

在第一部分中,我提出了内部模型的统一理论(通常被称为个体代理的“心智模型”)。我总结了几个领域的发现,并在主动推理的背景下将它们形式化。我明确了 Friston 和其他在此框架内工作的人在许多论文中提出的各种代理实现之间的共性,以及与其他推理和通信理论的等价性。作为一个简短的题外话,我表明这个理论允许我们以一种一致且(理性地)令人满意的方式对认识论及其悖论进行推理。

第二部分,我将这一理论应用于代理人的集体,这些代理人对他们自己、其他代理人以及集体本身进行推理,从而获得了一个社会系统和符号学的理论。它的要点包含在下面的引理中:

  • 集体智慧集体认知加上集体行动。
  • 集体认知个体认知加上个体之间的沟通
  • 选择性交流(以及由此产生的集体认知)必然出现在一群兼容的智能体(即不同但共享功能相似性)中,每个智能体都具有一定水平的个体认知

然后,我简要地讨论了这个理论是如何通过上面的相同的构件为决策理论、经济学和伦理学提供基础的。

最后,在第三部分中,我通过代理结盟的概念,将这一点与同样基于共享模型的集体行动理论联系起来。我表明,至少在高层次上,由此产生的对集体智慧的描述令人满意地解决了上述个人和集体代理之间的紧张关系。

我强调这是一个从头开始的理论,完全基于主动推理和自然选择的假设。因此,它适用于任意系统的代理人和他们的环境(某些附带条件涉及他们的维度和动态特性)。特别是,除了作为例子,我没有提到人类或其他自然发生的因素的特征。

第一部分:什么是模型?

为了解决我们理解集体中的模型的主要程序,我们首先需要理解对于自然的或人工的智能体的典型例子来说什么是模型。然后我们将把这种理解移植到集体中。

概括一下:在主动推理中,一个主体 A 根据感官证据不断更新它的信念(示意性地表示为 s → b ,然后使用这些更新的信念来判断要遵循的“最佳”行动方案( b 𝜋).)“意义构建”的第一步被解释为(近似)贝叶斯推理: A 选择使“统计惊奇”最小化(下限)的信念-ln p(s | b,m)。这里假设 m 是世界的“固定”模型,捕捉 A 关于其环境的“知识”或“理解”。

所以我们想回答:代理的模型 m 实际上是从哪里来的?它看起来像什么?它是如何更新的?为什么具有不同信仰的代理人能够相互理解和理解?

以上是关于这个话题的一些想法。我并不声称对其中任何一个拥有所有权,因为我主要是从信息论、认识论、决策论、统计学、神经科学和计算机科学中重新包装其他人的想法。但是我以前从未见过它们以一种全面和可理解的形式组合在一起,所以这篇文章可能有助于推动这个领域的发展。

什么是模型?

就其核心而言,模型是一种工具,让代理人可以管理其内部状态,并使其感觉有用。这在过去是非常抽象的,但现在我们被内置模型的人工智能体所包围。它们存在于我们的手机、电脑和其他地方:神经网络。因此,让我们从“传统”机器学习的角度出发,这非常简单,也很容易推理,看看这会把我们带到哪里。

神经网络是一种软件系统,设计用于“行动”或解决问题(通常是模式匹配问题,如输入分类),使用“神经启发”方法,其中输出基于输入的加权和: out = F(w,in) 。这种情况下的“模型”只是一组权重 w,它在逻辑上不同于“架构”(F 的函数形式,通常非常精细,在层的数量和形状上有无限的可能性,以及连接它们的不同方式)。使用优化算法“训练”该模型,以使最佳权重适合输入的样本集。

现在,任何非平凡(即,足够大以学习有用的推理)的神经网络的参数空间将具有大量的自由度。用未经过滤、未经标记的自然输入来喂养无本金代理的白板方法将导致过度拟合、虚假关联和其他故障模式,从而导致数据无法用于行动——除非在极少数情况下,当实际环境足够简单(例如,非常清晰的奖励函数、非常干净的动态)且数据足够丰富时。这不仅使得设置权重的成本非常高(需要加载数据,因此训练算法的运行成本非常高),还意味着如果没有外部设计,这种形式的通用系统无法可靠地训练自身。

在“传统的”机器学习中,这个问题是通过在概念上将解决方案分成三个逻辑上独立的步骤来解决的:

  1. 设计:设计者(通常是人,但见下文)定义神经网络架构,并设置一些架构参数,如大小和层数。这通常只在设计代理(或产品功能)时进行一次。
  2. 训练:执行上面提到的权重优化,输入数据,直到代理可以在“测试集”中执行足够正确的推理(或者直到设计者用完训练数据)。这仅在数据“本质上”改变时才进行(例如,对于宏观经济模型,一年一次,或者当新用户使用预测键盘时)。
  3. 动作:当模型被认为是“训练好的”时,针对它的模式匹配只是矩阵乘法,可以安全地安装到芯片中,根据需要经常运行。

相比之下,在主动推理中,智能体没有为给定的训练数据集预先优化的奢侈:他们必须同时行动和学习,在进行过程中不断引导他们的内部状态。这种代理可能不是非常“科学”(因为它的行为不能被已知精度的模型所证明),但实际上非常有效,因为它可以校准其行为,以收集更多的数据,这种数据是它提高对世界的知识(认知价值)所需要的。但是这种代理如何克服上面提到的建模问题呢?

答案是代理人可以利用一个自然发生的事实:世界的不同方面以非常不同的速度变化。例如,“我附近是否有掠食者”的事实可能会因瞬间或地点而异,而“什么样的东西是掠食者”的事实很少改变(即,只有当代理发现新的掠食者,或移动到有不同种类掠食者的环境中时)。还有一些,如“天空是什么颜色”,变化更少,可能比代理本身的生命周期长得多。也就是说,存在动力学的自然层级:大部分相空间由“慢”(高度对称、缓慢变化、低复杂度)状态主导,但少数低维子区域“更快”,即呈现较低的对称性(随时间或位置的变化率更高);反过来,这些社区也有自己更快的口袋,等等。

注意这里有一点骗术:回答“我附近有捕食者吗?”取决于回答“什么样的东西是捕食者?”。一般来说,子区域具有形状:一个国家是否处于“快速”子区域取决于不同维度的值的组合,反映了世界的因果结构,因为它与代理相关。这就引入了相关性的概念。如你所料,这个概念是主观的,在某种意义上,与一个代理相关的东西可能与另一个代理不相关。

(作为题外话,有人可能会问这种等级制度的来源是什么。尽管所有非平凡的动力学都会有某种程度的这种现象,但在我看来,生命系统会产生自我维持的低对称性动力学,一直到生态系统水平,再到其组成部分最基本的特征尺度。[实际上,弗里斯顿建议我们可以 T10 将生命现象定义为这种自我维持的快速系统。]因此,在这样一个生态系统中存在一个主体的事实导致 经历生命共同创造和维持的动态。)

因此,代理可以只考虑状态的投影到“相关”子区域的区域,而不必整体理解每个状态。余数被忽略,被认为是常数,或其他条件不变

(注意,“慢”自由度的任何变化都被视为“噪声”,而“快”自由度的任何变化都被视为“信号”。这在我们后面讨论模型选择时会很重要。)

上述情况意味着代理学习两者:

  • 给定全相位空间中的状态,应用哪个投影(“经验法则”);
  • 给定一个预测状态,如何解释它(“信念更新”),这可能包括要应用的进一步预测。

这两个一起就是我们所认为的代理的全局模型:状态空间上的一组嵌套等价类,其中每个等价类定义一个本地模型或“上下文”,其中状态可以用少量上下文相关的参数来描述。然后,意义构建是将感官状态 s 转化为等价类 m 和参数 b 的“宁滨”行为;贝叶斯推理是挑选“最佳”箱+参数组合,近似贝叶斯推理只是评估箱+参数的一种计算成本低廉的方式。

因此,模型是“符号”和“非符号”世界之间的罗塞塔石碑:它们解释了神经元激活(或比特)及其相关性的“平面”数值状态空间如何映射到解释和信念的层次空间,这在某种程度上准确地反映了环境的因果结构。

在这一框架下,洞察力或“尤里卡时刻”的概念可以被描述为模型简化步骤,在这一步骤中,代理人找到了宁滨的改进,使他们能够以更简洁的方式理解一组观察结果。类似地,重新解释、范式转换或认知失调的概念被解释为在一种间断的平衡中,从模型树的一片叶子到另一片叶子进行观察。事实上,“在头脑中容纳两种对立观点的能力”可以从字面上理解为具体化、参数化和控制这种重新解释过程的能力。请注意,在不同模型的光照下,“回放”和重新评估历史感观的能力极大地帮助了重新解释。

一个例子:弗里斯顿规则学习者

考虑一下 Friston 在这篇论文中描述的游戏(我推荐改为看的对话)。在这个(略显做作的)设置中,以“找到正确的颜色”的任务形式给代理一个谜题,其中决定答案的线索位置由一个抽象的“规则”给出,如“如果中间圆圈的颜色是红色,那么答案由左边的圆圈给出”。Friston 的文章没有探索可以解决的结构最简单的代理设计(这可能是 ML 从业者所假设的)。该代理将可能的观察配置(或序列)集合作为其状态空间,并且给定足够的数据,将缓慢但肯定地耗尽该(非常大的)空间,并且在其内部参数空间中将规则重新创建为列联表。这当然是可行的,但是不太节约或者在概念上不现实——它没有解释我们认为真正有思维的生物解决这个难题的方式。

相反,代理被“告知”有一个规则,并且该规则由中心圆的颜色决定。也就是说,给它一个具体化的分类参数,或“bin”,代表三个可能的规则(与可能的颜色数量相同);它在重复试验中的学习任务是学习 3×3 关联矩阵,该矩阵给出正确颜色(根据反馈)和在每个位置看到的颜色之间的映射,并从那里回溯到每个试验中的活动规则。这些额外的假设允许代理可靠地学习规则,并且平均仅在 12 次尝试后就正确地解决任务。

然后,Friston 允许它的代理“睡眠”,他的意思是模型简化通过。代理“意识到”映射第一和第三规则的关联矩阵实际上是单位矩阵,并且指定那些相关性的参数可以被设置为常数(相应地为 1 或 0)。扁平化模型同时更简单(即存储和计算更便宜)并且更有效。

值得注意的是,所有这些都源于最小化自由能——首先相对于参数值,然后相对于模型空间本身。

模型的结构

如上图所示,模型是嵌套上下文的有向无环图。每个上下文(或框架,跟随 Bacharach )是一个提供稳定的对象、事实和关系的背景结构(本体论/分类学)的空间,在此基础上发生实例化(一组表示在给定推理时刻实际被认为是真实/相关的事件的激活)。每个实例化提供了一个选项“菜单”,必须从中挑选下一级实例化;按照同样的标准,每个实例化只有在它上面的所有级别的上下文中才有意义。

我们可以列出模型上的一些自然操作:

  • 细化:将一个叶节点展开成一个子图。之前被解释为离散事件的内容将被重新解释为上下文,以了解更多细节。
  • 折叠/识别:将一个子图概括成单个节点。
  • 横向/对角线连接:从先前不相关的子图中访问参数。

这些操作在模型的贝叶斯表示中是很自然的。在本文中,我们只能推测它们也以自然的方式映射到人脑中突触连接的变化。关于这方面的一些推测,见弗里斯顿的文章。

另外,这些嵌套模型形成了一个代数。进一步的工作应该允许我们使用代数拓扑和其他数学领域的工具来更深入地了解模型的结构。

关于信念的信念:认识论的基础

这种持续的、间断的平衡信念更新导致了记忆和信念的混乱结构,破坏了感官和事件输入流的简单性。理解“为什么 A 相信 P”需要凌乱的回溯,即使给出完整无损的历史数据;根据所有的证据重新评估这一信念甚至更加昂贵,而且在大多数现实环境中,可能是不可能的。

尽管如此,在许多情况下,对一个代理人来说,拥有关于其信念及其原因的信念似乎是有用的。“我相信我附近有一只食肉动物,因为我正在观察远处一个危险的形状,[在一个隐含的背景下,我知道某些形状是狮子]”。这种具体化简单地重复使用上面开发的机制来实现关于世界的信念,适应于关于代理人自己头脑的信念。

这可以被形式化为认识论的定量理论——为什么我们思考我们的信仰,并以我们的方式对证据做出反应。在这种叙事中,“知识”不同于“纯粹的真实信念”,是一种有用的虚构,代理人告诉自己,以便思考他们来之不易的信念。

有趣的是,这一理论正确地预测了这样的“二阶”信念或元信念通常被体验为事实(具有单位概率的断言),与“一阶信念”相反:你可能不确定附近有捕食者,但如果你认为有一个,那么你确定你是这样认为的。事实上,如上所述,主体几乎总是在给定的环境/框架内运作:一阶信念只在相应的框架内才有意义。由于元信念是指上下文/框架的谓词,它们只需要在重构的罕见时刻被允许是不确定的。否则,代理人会将那些最简单的描述作为纯粹的绝对事实。(元信念似乎甚至对反事实推理免疫——如果认为你正在读这篇文章,那会是什么样?—这引出了一些关于大脑如何实现它们的有趣问题。)

顺便提一下,哲学的“特质”是这种元信念的一种形式。你和我可能(相当肯定地)看到了某种波长的颜色,这种颜色被普遍认为是“红色”,但第二个事实是,你和我在精神上用“我看到红色”的形式描述我们自己的经历,这是一个独立的信念,我们每个人都独立地经历,与第一个不同,这是“私人的和直接可理解的”(用丹尼特的描述)。

The “redness of red” quale, a common example of meta-belief.

因此,这个理论允许我们用机械论的理由来化解关于感受性的长期争论和悖论,比如“你和我看到的颜色一样吗?”作为对世界的信念和对心灵的信念之间的简单分类混淆,它们确实具有不同的属性,因为它们指的是本质上不同的领域。

这并不是一个新的结论——相反,古代和当代的冥想练习,以及认知行为心理治疗,都将此作为一种戒律来教导,但现在我们确切地看到了为什么会出现这种情况。当然,你可能会怀疑那些倾向于此的人会继续要求非机械论的解释来解释感受性(关于经验的信念)和关于经验的信念之间的二元性。但是稍后,当我们讨论经验主义的道德含义时。

第二部分:集体如何才能有模式?

最后,让我们回到我最初的动机,这是关于集体智慧,或社会系统中超越其部分总和的智慧。我们如何在一个集体中做出有意义的事情?

(初步注释 1: 我不会花费太多精力试图说服你集体在明确定义的意义上确实是聪明的——参见我以前的文章中一些令人信服的论点。或者,你可以暂停怀疑,把下面的论点看作是解释一个论点的操作理论,不管这个论点是否成立。)

(初步注释 2: 在缺乏说明相关现象的具体模拟的情况下,下面的一些可能看起来像是未经证实的挥舞。我正在努力。与此同时,Friston 在过去几年中实施的模拟实例的广泛收集,其中一些非常复杂,应该表明这种操作描述也可以模拟,只要付出一些努力。)

可变性和相互可理解性

关键假设是:

  1. (公共物理环境)多个代理在共享环境下运行。
  2. (共同的社会背景)每个代理作为与其自身兼容的其他代理的群体的一部分而存在(在某种意义上,将在下面阐明)。

在上一篇文章中,我们讨论了假设#2 如何暗示当且仅当代理人能够“模拟他人”时,他们将有效地与他们的社会环境进行交互,这就是我们之前所说的替代性,也可以称为心理理论(一个相当混乱的术语,但显然是心理学文献中的标准),或人际推理(技术上准确,但有点拗口)。我们也概述了一个理论,关于假设#1 加上自由能原理是如何一起实现成功的替代性,以及由此产生的广泛的社会现象。

(顺便说一句,自从写了那篇文章,我发现了弗里斯顿及其合作者以前的一些论文——从 2008 、 2014 、2015——这些论文必须归功于以类似方式描述模拟另一个的代理的现有技术。我在这里描述的方法更深入一些,但我并不认为这是一种洞察力——它是主动推理框架的直接应用。)

该理论的要点是:

  • 代理持有他人的模型,形式为“他人=自我+差异”。这种表示在代理彼此确实相似的程度上是极其有效和准确的。校准这个模型(估计“差异”参数)只需要一些反事实推理的能力(类似于评估替代政策所需要的)。
  • 这种模拟其他代理的能力导致代理喜欢与相似的代理交互,这加强了相似性的感知——这创造了自我加强的
  • 代理不仅相互作用,而且与环境。在非常一般的情况下,一对结合的智能体在与环境交互时会比两个单独的智能体有更好的 T10 个体 T11 表现,因为每个智能体的行为都会向它们的同伴透露关于环境的信息。(这可以是关于世界当前状态的非常简单的信息,如在单细胞生物之间观察到的化学信号,或非常复杂的规则学习,如在鸟类和灵长类动物中发生的模仿学习。)在这种情况下,对代理之间的可变性的测量是有用的:代理将根据其位置、形状、内部参数等以稍微不同的方式运用环境。这导致了更丰富的结果。
  • 这对结合的代理满足在主动推理框架下被操作性地认为是自身代理的所有条件;这对“一起工作”的人被称为是一个复合代理
  • 此外,具有足够能力的代理人可以将配对本身视为“他者”;在某些条件下,这一对也可以说是把它的组成代理人设想为“其他人”。这为代理对齐创造了条件(见下文)。
  • 这种结构可以从成对扩展到多个代理和键的集合(网络)。这就是我们所定义的集体智慧(又名超级智慧):一个由单个智能主体通过纽带连接而成的复合物,它将自己的集体视为一个实体。根据弗里斯顿的定理,超神总是可以被说成是行动的,至少在某种程度上是如此(即,它有一点“意图”);我们将在下面描述代理结盟的机制,它允许集体的意图与个人的一致。这种调和反过来允许超神成为一个拥有可靠意图的真正稳定的代理人。

兼容性:这是个程度问题

从上面可以清楚地看到,兼容性不是二元的。根据可计算性理论,如果一对智能体的差异没有压倒任何一方的认知能力,则可以认为它们是兼容的。也就是说,即使是同卵双胞胎的连线也略有不同,即使是同一个人也会随着时间的推移改变连线,这并不是一个大问题——这种差异可以被表示为几个调整。但是当你考虑越来越多不同的代理时,你需要考虑到每个代理能够计算越来越复杂的反事实(“如果我是那样的话,我会怎么想?”).

似乎有理由假设,一个群体的代理人具有反事实模拟的内置机制,这种机制对于群体内代理人之间的典型差异范围可能是足够的。只有当一个主体能够接触到一个更通用的系统时,它才能将自己调谐到一个远在那个范围之外的“他者”,无论这个系统是内部的(例如,从其大脑皮层的其他用途中劫持来的符号系统)还是外部的(例如,像语言或计算机这样的符号系统)。

旁白:“过去和未来的自己”作为“他者”

软件开发人员长期以来一直在谈论“善待未来的自己”,例如,通过编写带有文档、注释和高测试覆盖率的高质量代码。后来我了解到,Bacharach 和其他人,如 Dyson ,至少在不同时间点的自我和他人之间看到了部分形式上的等价。毫无疑问,我们一直在和未来的自己交流,例如,通过留下提醒,我们不断试图解释我们过去和未来的自己的状态——“我在想什么?”、“一个月后我会后悔吗?”这是反事实模拟的又一次扭曲。有些人甚至认为记忆和交流在字面上是等同的。我不会走那么远——如果仅仅是因为跨时间的交流是单向的。但是对称性绝对值得更详细地探索。

世界中的知识:符号与交流

关于主动推理框架的一个值得注意的事实是,它对生物学是不可知的:一个代理的操作定义可以很容易地被理解为包括生物学上不属于它的系统组件,只要那些组件满足马尔可夫毯的因果条件。事实上,经常会发现复杂的代理人将其操作范围扩展到其生物学范围之外,特别是使用生物学外部状态作为其内部状态的扩展:“世界上的知识”与“头脑中的知识”。

这对于复合代理特别有用,因为两个代理运行的共享物理空间为符号提供了一个稳定的画布。我们将这些定义为物理状态,在状态空间的一个区域中,该区域是相互可访问的,并且与“重要”的环境动态解耦,并且因此被复合代理内在化。通过使用一组共享的符号,代理(a)可靠地提高彼此的性能,以及(b)通过持续观察每个对等体在给定符号的情况下“如预期”地行为来加强他们的联系。事实上,这个定义满足了所有常见的给定的符号要求;例如,它们显然是任意的,它们的物理表现除了信息容量之外没有任何要求(即,你需要至少一位的物理状态,如由两个代理的感知所分析的,来存储一位的符号)。

因此,我们有了一个从头开始的交流理论的轮廓:通过被制成媒介(可以像声波一样短暂,也可以像标记一样持久)的物理空间的内在化部分,代理人生产和消费符号;这些符号的进化与获得合适的媒介和上述效果(a)和(b)的相对进化益处成比例。

注意与奎因的语言理论的等价性。沟通不是建立在绝对客观事实之上的逻辑认知结构,而是随着时间的推移,由效用和重用驱动的近似模型的分层。与客观世界的对应是不稳定的、统计的和偶然的。此外,由于众所周知的可计算性结果(参见 Yudkowsky 的Map and Territoryfor a equivalent perspective ),即使对于任意强大的代理,这也是唯一可行的方法。

传播的货币:认知经济学和伦理学

我故意在上面用了“生产”和“消费”这两个词。综上所述,上述交流活动构成了认知经济。这种经济建立在共享模式的公地之上,被编码为知识(在头脑中和在世界中),作为允许交换发生的制度基础设施。所有抽象层次的语言,从低级的身体语言到专门的、高上下文的行话,都是这个基础设施中的层。

在这个共享环境的媒介中,代理人的交换产生了相互价值,但它们也是有代价的:不仅是用完带宽的运营成本,还有通过保持(或者更好的是增加)相互可理解性来维护公共资源的资本成本。忽视对认知共有物的维护会导致快速的、灾难性的交流中断,或者更确切地说,是语义分裂。

这让我们想到了认知伦理的概念。代理人有一个私人动机,在认知公共领域搭便车,或者视情况而定,甚至破坏交流以达到利己的目标。然而,该系统的长期繁荣需要负责任地维护公共资源。自从亚当·斯密(但直到几十年前才被人们认识到)以来,人类通常能够通过使用我们内置的道德协议来保护他们的公地免受这种破坏,这种道德协议由长期的、不对称的承诺、礼仪和赢得信任的概念组成。

据此,我假设认知承诺是将世界维系在一起的粘合剂。随着每一次交流——问候、交易、辩论、艺术表达——我们加强了一种隐性的信任,即我们是相似的实体,以相似的方式思考相同的外部现实。这种信任往往没有任何合理的理由(考虑到我们有限的带宽,经常混乱的信号,以及前面提到的私人激励)——日常信仰的跳跃,由我们天生的假设共性的倾向驱动。我们用这个认知承诺的网络作为合作和交流的基础,也就是说,生产对我们任何人都有价值的东西。

第三部分,结束游戏:集体中的主动推理

意义创造的全部意义在于对世界做出最佳反应——“没有体现就没有智慧”可能是主动推理运动的口头禅,如果它有的话。那么我们如何为集体拼凑这些呢?

关键的概念是我所谓的代理对齐。其核心是,每个代理人都认识到这个群体拥有共同的目标或共同的命运(参见 Bacharach 对这一概念的良好回顾,这一概念通常隐含在群体的社会科学讨论中)。这种对共同利益的共同认识可以是交易性的(每个代理人的私人利益由群体目标推动)目的性的(代理人分享超越严格私人利益的共同目标)或者两者兼而有之。对于这个讨论来说,重要的是 agentic alignment 允许 agent“作为一个群体行动”,在严格意义上是指(a)拥有一个作为包括他们在内的“超级 agent”的群体心智模型,(b)理解群体的目标是什么,以及(c)根据他们的心智模型选择推进群体目标的个体策略。

这是一个有趣的问题,上面的(c)是指“自己决定什么对集体有利”,还是“默默地服从命令,因为我被告知那是对集体有利”。本着本文的精神,我们假设,在某种程度上,代理共享一个共同的群体和世界的心理模型,这两个定义应该是相同的给定理想的代理。尽管如此,也可能是决策和遵循规则的不同心理机制导致了实践中不同的结果。

拼凑起来,我们对集体代理有了一个吸引人的描述,并看到它如何与自由意志不冲突。理论上:有认知能力的主体(我们赋予个体主体或“自由意志”的主体)之间的集体主体在一定程度上发生:( a)主体共享包括彼此和集体在内的共同世界模型,以及(b)主体拥有共同利益的共同知识,允许它们自愿地联合行动。

最后,我再一次指出,这一领域有深度的思考者以前曾涉足过这里。特别是受东方哲学启发的关于组织和社会制度的书籍,比如考夫曼的意义革命 绝对有它的要旨。这篇文章的原创性贡献,如果有的话,在于提供了一个从信息论到考夫曼和其他人已经掌握的一些基本真理的明确的、可形式化的和先验的逻辑结构。这给了我希望,这种特殊的结构将对其他人有用,无论是在证明关于社会系统的定理方面,还是在帮助社会系统——由人、人工代理或混合组成——通过严格的、理论上知情的干预变得更加集体智能。

如前所述,我并不认为这些想法有什么特别的价值。尽管如此,我还是喜欢认为,这种构建、综合和形式化它们的特殊方式将对其他人有用。非常感谢 Ananya Sheth、Pranav Gupta、Hannu Rajaniemi 和 Gianni 贾科姆利在过去几个月的讨论、反馈和鼓励!

使用 Python 合并电子表格–追加

原文:https://towardsdatascience.com/merging-spreadsheets-with-python-append-f6de2d02e3f3?source=collection_archive---------0-----------------------

将多个电子表格合并在一起是一项常见的任务。合并有两种方式:

  1. 追加 —电子表格层叠在一起

Three spreadsheets are appended into one based on column names

2.联接 —基于所选列的相同值水平联接电子表格列

Two spreadsheets are joined into one based on the same Name values

在本教程中,我们将侧重于追加。我将会写另一篇关于加入的教程。

放弃

我建立了一个工具mergespreadsheets.com可以很容易地附加文件。如果您需要快速追加,请随意尝试

先决条件

如果您不知道如何使用终端和 Python,或者如何使用 Python 和 Pandas 读写文件,那么请先阅读并浏览本教程:https://medium . com/@ love spreadsheets/intro-to-handling-spreadsheets-with-Python-c 6 a 35 E0 D8 de 8

文件

在本教程中,我们将使用三个文件。可以点击链接下载:marketing analyst names . xlsx, SalesRepNames.xlsx ,senior leadershipnames . xlsx

完整代码

这是追加三个文件的完整代码

Full Code for this tutorial

I .阅读所有三个电子表格

在与三个电子表格相同的文件夹中创建一个 python 文件,并将其命名为 append.py

首先我们要导入我们的 pandas 库,并给它一个缩写 pdpd 缩写是约定俗成的,从技术上来说你可以使用 import pandas 照原样,将代码中的所有 pd 替换为 pandas

import pandas as pd

我们将在没有任何额外参数的情况下读取第一个表,因为我们只有文本数据,第一行是列名,所以我们可以使用 pandas read_excel 命令读取所有三个文件,而没有任何参数

marketing_analyst_names = pd.read_excel("MarketingAnalystNames.xlsx")sales_rep_names = pd.read_excel("SalesRepNames.xlsx")senior_leadership_names =   pd.read_excel("SeniorLeadershipNames.xlsx")

现在我们有了三个变量,它们包含了包含 excel 文件中所有行列格式的值的数据框

二。合并所有三个数据框

现在,我们将合并所有三个数据框

  1. 我们将创建一个包含所有三个数据框的列表。列表中数据框的顺序将决定文件的追加方式
all_df_list = [marketing_analyst_names, sales_rep_names, senior_leadership_names]

2.追加所有三个数据帧的命令是一个单行函数。我们将使用我们的列表调用 pd.concat 函数,它将按照这个顺序追加我们的所有数据帧,并将追加的数据帧赋给变量 appended_df

appended_df = pd.concat(all_df_list)

追加是通过匹配相似的列名来完成的。如果列名不同,则追加不会将值堆叠在彼此之上。

我鼓励你们用不同的列名创建虚拟电子表格,看看追加是如何被影响的

三。写入 Excel 文件

既然我们已经有了追加的数据框,我们可以将其写入 Excel 文件。我们在附加的数据框上使用 to_excel 函数来实现这一点。我们还将添加参数 index=False ,它不会输出任何行号。(摆弄参数,看看哪个对你有意义)

appended_df.to_excel("AllCompanyNames.xlsx", index=False)

现在我们已经完成了代码,我们需要打开我们的终端并转到保存所有三个文件和我们的 append.py 文件的文件夹

如果你跟终端走散了,请先过一遍本教程:https://medium . com/@ love spreadsheets/intro-to-handling-spreadsheets-with-python-c 6 a 35 e 0d 8 de 8

我们将从我们的终端运行这个脚本

$ python append.py

瞧啊。我们现在应该有一个名为 AllCompanyNames.xlsx 的文件,与我们的三个电子表格和包含所有三个附加文件的 Python 脚本在同一个文件夹中!

与人工智能融合:如何使用 Keras 和 OpenBCI 制作脑机接口与 Google 通信

原文:https://towardsdatascience.com/merging-with-ai-how-to-make-a-brain-computer-interface-to-communicate-with-google-using-keras-and-f9414c540a92?source=collection_archive---------6-----------------------

E lon Musk 和 Neuralink 希望建立一个可以充当大脑第三层的脑机接口,让人类与人工智能形成共生关系。

但是如果你已经可以做到了呢?

在(非常)有限的形式下,你确实可以。

背景

脑机接口(Brain-Computer Interface,BCI)泛指在神经系统和电子设备之间建立直接连接的任何系统。这些装置可以通过手术植入大脑,也可以在体外。典型的范例包括允许用户控制致动器或键盘,允许设备向用户发送传感数据,或涉及传感数据和电机控制的双向通信(即接收电机控制输入并发送压力或温度传感数据的假肢)

历史上,神经假体一直是 BCI 研究的主要动机。这些技术包括为截肢者安装假肢、为聋人安装人工耳蜗,以及为癫痫患者提供深部脑刺激。这些设备已经改善了数百万人的生活,它们的广泛使用证明了大脑和电子设备之间实现直接双向通信的好处。然而,该技术的可能应用远远超出了医疗保健。即使在神经假体领域,我们也可以想象超越修复,考虑增强我们的能力,使之超过正常人的水平。总有一天,假肢会发展到以任何客观标准来衡量都比自然假肢优越的地步。这些肢体可能看起来和感觉起来就像正常的肢体,但会更加强壮和灵活。另一个例子是人造眼睛,其分辨率远高于人眼,能够放大或缩小,并能看到紫外线或红外线光谱。

当考虑认知和技能形成时,可能性变得更加有趣。最近的一项研究表明,刺激大脑的某些部分可以改善记忆的形成和回忆。其他的实验已经成功地将记忆人工植入动物体内。举个例子,也许可以应用这些研究的方法来提高你快速学习一种乐器的能力。或者,也许有可能将各种神经刺激器和传感器结合起来,开发一种“算术处理单元”,它可以检测大脑中与数学或逻辑推理相关的特定区域何时被激活,并与它们通信以增强能力。

埃隆·马斯克和 Neuralink 想要追求的正是这种认知增强的延伸。根据马斯克和许多领先的人工智能理论家的说法,人类相对于人工智能的智力进步的一个关键障碍是带宽问题:尽管计算机和人工智能变得越来越快,处理和生成知识的能力越来越强,但我们在做同样事情的能力方面面临着直接和根本的限制。我们主要通过我们的感官和解释语言的能力来获取信息。在你的眼睛和视觉皮层阅读和理解一个句子的时间里,计算机可以扫描成千上万页的文本。可以想象,在几十年的时间里,我们可能会有运行在专门的神经形态硬件上的高级人工智能,这些硬件具有世界如何工作的令人难以置信的精确模型,以及在几分钟内分析和理解数百万份文件的能力,做出远超人类理解的决策和推断。在一个越来越依赖人工智能驱动决策的世界,人类可能会发现自己在商业、科学和政治决策过程的所有部分都过时了。我们的大脑并没有进化到用数万亿颗棋子来下一盘棋,也没有进化到理解预先计划了数百万步棋的战略。正是对这个超级智能黑匣子的恐惧,激发了 Neuralink 、 Kernel 和其他几个相关组织目前的大部分工作。

BCI 技术的大多数前沿研究都试图最大限度地提高信息带宽,通常是通过将电极直接植入大脑或神经的侵入式方法。然而,非侵入性方法,特别是脑电图(EEG)和肌电图(EMG)被常规使用,并取得了相当大的成功。这些包括将电极放置在你的头部表面(EEG)或肌肉上方的皮肤上(EMG ),以测量下面累积的电活动。这些数据的粒度很低,与最终实现 BCI 研究更宏伟目标所需的精度和带宽水平相去甚远。尽管如此,EEG/EMG 支持的 BCI 已经取得了令人难以置信的成就,如用思想控制无人机、视频游戏和键盘,并且它们提供了进一步研究可能解开的可能性的一瞥。此外,像 Cognixion 和 Neurable 这样的几家公司正在探索基于 EEG 的脑机接口的真实世界应用,并且已经获得了大量的资金和支持,许多令人兴奋的项目正在进行中。

概述

在这个项目中,我们在你的神经系统和外部人工智能代理之间建立了一个直接的连接。这个代理可能是任何你能得到的 API:谷歌助手,Siri,Alexa,Watson 等。像 Dictionary 或 YouTube 这样的服务也符合条件,但这些服务会将应用程序局限于内容查询,而不是通用请求。

为了这个项目的目的,我们将直接查询谷歌搜索,因为它提供了最大的灵活性,也是最容易设置的。完成后,你应该能够简单地通过思考在谷歌上查询一些术语。

我们使用的技术利用了你的大脑在默念过程中产生的神经信号。这是当你慢慢地、有意识地阅读或思考时,发生在你大脑内部的“内心独白”。你可能已经注意到自己在默读的时候会这样做,有时你会在不知不觉中微妙地移动你的下巴和舌头。当你收到 SAT、MCAT、GRE 或其他标准化考试准备的提示时,你可能也遇到过这个概念。考生被建议避免默读,因为这是一个降低阅读速度的坏习惯。

我们能够利用默念,因为大脑向你的喉头发送与你想说的话相对应的信号,即使你并不打算大声说出来。通过将电极放置在你面部的喉部和下颌神经上,我们可以记录与特定单词对应的信号,并使用它们来训练深度学习模型,以辨别不同的单词。换句话说(没有双关语的意思),我们可以从你思考某个单词的行为中辨别出你在思考这个单词。

Brain and Laryngeal Nerves

这种技术有其局限性,它绝不是完美的,也不适合实际应用。然而,自从两年前由麻省理工学院媒体实验室首次在现实世界中演示以来,它已经被成功地用于允许用户做数学、打电话、订披萨,甚至在下棋时接受帮助的设备中。

MIT Media Lab AlterEgo Headset

设置&材料

所需的主要硬件工具是 OpenBCI 神经节板。有各种各样的其他硬件可供选择,但是我发现 OpenBCI 有一个最大的开发人员社区来提供支持。它花了你大约 200 美元,但是考虑到你可以用它建造难以置信的东西,它是非常值得的。

OpenBCI Board and Electrodes

除了电路板,你还需要电极和电线。一套金杯电极和电极凝胶应该花费 50 美元,应该工作正常。

神经节板

电极

电极凝胶

或者,你可以获得一个完整的 OpenBCI 入门套件,包括电路板和多种类型的干电极,以及一个电极头带,价格为 465 美元。有点贵,所以金杯设置完全没问题。不过,如果你打算尝试 BCI 的其他应用,比如虚拟现实(Unity VR 教程即将推出!),头带和干电极带来更好的体验。

生物传感入门套件

OpenBCI 还提供 8 和 16 通道板。这些将提供优越的数据质量,但 4 通道神经节将足以为这个项目。

配置

在 Linux 机器上,检查是否有 Python 3.4 或更高版本。打开您的终端并键入以下命令:

python3 --version

如果您没有 Python,或者您有旧版本,请输入:

$ sudo apt-get update
$ sudo apt-get install python3.6

现在,下载或克隆 pyOpenBCI 目录。

将目录更改为存储库,并运行以下命令来安装必备软件包:

$ pip install numpy pyserial bitstring xmltodict requests bluepy

您现在可以安装 pyOpenBCI 了

$ pip install pyOpenBCI

要查看一些操作,请将目录更改为pyOpenBCI/Examples并找到 print_raw_example.py 。用您最喜欢的代码编辑器打开这个文件,并在第 7 行进行如下修改:**

*board = OpenBCICyton(daisy = False)*

应改为:

*board = OpenBCIGanglion(mac=’*’)*

这使得 pyOpenBCI 能够为我们正在使用的特定电路板采用适当的模块。

现在,打开你的主板。

在您的计算机上,从示例 目录中键入以下命令:**

*$ sudo python print_raw_example*

嘣!!你的终端现在应该充满了来自电路板的原始输入数据流。

记录信号

既然我们可以获得原始信号,我们就可以开始设计和构建数据管道。首先,我们必须首先将原始数据转换成 LSL 流。LSL 指的是实验室流层,是由加州大学圣地亚哥分校斯沃茨计算神经科学中心开发的一种协议,旨在促进实时数据流的记录和分析。LSL 将我们的脑电图数据传输到本地主机,从那里它可以被其他应用程序或脚本拾取。

修改pyOpenBCI/Examples*中的 lsl_example.py 文件,删除我们不需要的 AUX 流,增加一个标记流:*****

我们现在必须定义一个实验设置,以我们想要的形式记录数据,并将其存储以备将来使用。我们希望该实验生成一个时间序列 EEG 数据的数据集,这些数据被分成多个区间,每个区间对应于一个单词的无声化。为了实现这一点,我们可以执行一个实验,开始 N 个间隔的记录会话,每个间隔持续 T 秒。给定区间内的所有样本都用区间索引和指示用户默写的特定单词来标注。

来自神经科技伯克利分校的 lsl-record.py 文件是一个很好的起点。根据我们定义的设置修改文件:

您可以调整术语库(第 64 行),在不同的上下文中尝试不同的单词组合。您也可以在每次会话前调整默认持续时间(第 12 行)。

现在是有趣的部分了!将电极插入电路板:

Left 4 channels are EEG in, right 2 channels are ground

按照以下配置将它们贴在脸上:

找一个安静的地方坐下,在不同的终端中输入以下行:

***// Terminal 1: converts raw data to LSL and streams it
$ sudo python lsl_example// Terminal 2: reads LSL data stream and executes experiment
$ sudo python lsl_record***

注意:我们作为 sudo 运行,以允许脚本检测板的 MAC 地址

这将启动指定持续时间的记录会话。你将被提示从你的词库中随机抽取一个单词,间隔 2 秒钟默读。录制过程可能会让人不舒服,容易入睡,所以最好在中间休息一下,进行多次小范围的录制。此外,如果频繁出现干扰(即突然移动或使不正确的单词不发音),我们的实验设置可能会导致数据质量差。

您可以设计和实现一个更灵活的设置,可以选择在注意到干扰时击一个键来删除当前和以前的间隔。另一个解决方法是进行多个小的会话,并在最后合并数据,丢弃干扰过大的会话。一些噪声是不可避免的,你不必太挑剔,因为随着样本数量的增加,模型变得更有弹性。

为了获得最佳结果,你的词库中的每个词至少要有 1000 个高质量的样本。

过程信号

一旦你有了足够的数据,就该为机器学习做准备了。

对数据进行适当的组合和预处理,使其具有以下格式:

Example Data Table

  • 单词是从 1 到 NumIntervals,的索引,T5 是总会话数中 SessionDuration/2 的总和
  • 术语对应于每个时间间隔显示的单词
  • [A,B,C,D]是脑电图通道
  • 每个单词、术语组合对应于大约 800 行数据

使用 numpy 将您的 CSV 文件导入 python。您应该将所有数据加载到脚本中的 NumLines x 6n array 中。

第一步是过滤数据,去除我们感兴趣的频率之外的噪声。信息 EEG 频率对应于以下频段:

EEG Wave Frequencies

对 4 Hz 至 100 Hz 之间的频率进行滤波似乎是合理的,但会失败,因为 60 Hz 是电网的频率(可能因国家而异),这必然是一个重要的噪声源。为了获得最佳结果,我们应该在 4 Hz 和 50 Hz 之间进行滤波。

我们可以使用 Scipy 的巴特沃兹滤波器来选择我们想要保持的频率范围。用下面的代码定义一个过滤器:

然后,生成一个时间戳列(因为我们合并了多个数据集,并使原始时间戳无效),并将过滤器应用于每个通道:

过滤后,使用下面的代码将数据重组为一个三维的 ndarrray 数组,其维度为IntervalLength x channel count x interval count****

我们用上面的代码有效地将时间序列数据转换成图像数据。这听起来可能有点不可思议,但是你可以把每两秒钟的间隔想象成一幅图像,每一个像素对应于在一个特定的(通道号线路号)坐标上获取的信号值。换句话说,我们有一堆间隔计数图像,每个图像的大小都是间隔长度* x 通道计数。*****

First 120 data points of an EEG interval

这项技术由 Justin Alvey 在一个类似的项目中演示,非常强大,因为它允许我们将时间序列数据视为图像数据,允许我们利用计算机视觉和卷积神经网络(CNN)的力量。您甚至可以通过将特定的默写绘制成图像来将其可视化

此外,使用 CNN 允许我们跳过傅立叶变换,因为神经网络可以学习各种频率(在每个图像上以模式出现),而无需明确指定它应该寻找什么频率。

现在我们准备开始建设 CNN。由于我们只有 1 个颜色维度,我们可以使用输入维度为 IntervalLengthChannelCount 的 1D CNN。您可以尝试不同的超参数和架构。我选定了一个卷积层、两个完全连接层和两个合并层。

有关一维 CNN 以及它们如何应用于时间序列数据的更详细分析,请参考 Nils Ackermann 的这篇文章。

我们现在有了一个模型,它应该能够将一段时间的脑电图数据与你的词库中的一个特定单词进行匹配。

让我们看看它做得有多好。将模型应用于测试数据,并将预测结果与实际结果进行比较。

***# Test Model
y_predicted = model.predict(X_test)***

用银行这两个词,我可以达到 90%的准确率。不出所料,随着单词的增加,准确率略有下降,三向准确率为 86%,四向准确率为 81%。

Sample truth chart from two word classification. Left is Actual, Right is Predicted

一种在不影响准确性的情况下增加术语库大小的可能方法是创建具有多词查询的分层“术语树”。然后,您可以在树上执行深度优先搜索——每一层的单词只与同一子树的同一层中的其他单词进行比较——以找到最佳匹配。

谷歌搜索

我们现在已经有了使用 BCI 查询谷歌的所有必要信息。定义特定子可视化和查询之间的映射,并进行适当的调用:

还有…

要想进行实时查询,请修改 lsl_record.py 脚本并将其作为一个模块导入。然后,您可以调用它来读取 LSL 流,以 2 秒的时间间隔响应用户输入。

就是这样!你现在不用说或输入一个字就可以搜索谷歌。

结论

你不能用一个三四个单词的术语库做太多事情(除非实现前面提到的术语树)。经历所有这些步骤来搜索到你最近的加油站的方向比正常的谷歌搜索稍微复杂一些。然而,重要的是要考虑这项技术的进一步发展可能会导致什么。我们可以想象这种设备的改进版和不太显眼的版本,与麻省理工学院团队已经拥有的版本没有太大区别,用于导航、网络查询、短信、智能家居管理或任何数量的日常任务。当与不断改进的人工智能助手的能力相结合时,这种可能性会进一步扩大。

基于脑电图的脑机接口的应用是世界各地公司和大学实验室的尖端研究最终可能实现的一小部分。心灵感应交流、超人智能、附加感官、模拟体验、人类意识数字化、与人工智能融合等都值得考虑。如果这些可能性得以实现,它们将不仅仅重新定义我们与技术的关系:它们还将重新定义对人类意味着什么。

参考文献

以下是我发现有助于完成这个项目和了解 BCIs 的资源和组织列表。我要特别感谢麻省理工学院媒体实验室的 AlterEgo 团队,他们是这个项目的最初灵感来源,也感谢 Alvey 先生和 NeuroTech Berkeley,感谢他们之前对 BCI 社区的代码和教程贡献。此外,我要感谢加州大学戴维斯分校的教职员工,特别是伊利亚斯·塔格科普洛斯、卡伦·莫克森和埃尔金·谢克尔博士,感谢他们一直以来的帮助和支持。

  • AlterEgo:一款个性化的可穿戴式无声语音界面
  • 利用深度学习“读取你的想法”——借助 Keras 和 EEG——贾斯汀·阿尔维
  • 神经科技伯克利 Github
  • 打开 BCI Gitub
  • 脑机接口:介绍

最后,我想对不断成长的 BCI/神经技术社区大声疾呼,他们为未来提供了无尽的支持、资源和热情。

  • NeuroTechX
  • BCI 红迪网
  • Reddit Neuralink
  • OpenBCI

如果您想进一步讨论或联系,请随时联系LinkedIn

更迷人的颗粒物天气

原文:https://towardsdatascience.com/mesmerizing-particulate-matter-weather-70ce6703da7f?source=collection_archive---------24-----------------------

两周前,我解释了看不见的颗粒物质——PM10 和 pm 2.5——是如何穿越欧洲的。(https://towards data science . com/invisible-clouds-of-particular-matter-move-cross-Europe-6b 39 e2d 57511)

在将近两周的时间里捕捉更多的数据,并稍微加快视频速度,你会对下午的天气有更好的了解。

大规模的运动显然比 PM 浓度的局部波动更重要。

仍然存在的问题是:项目经理从哪里来?是烧柴的炉子、交通、工业的结合,被天气收集并席卷了整个欧洲?

Photo by Alex Gindin on Unsplash

因果推理中估计治疗效果的元学习器

原文:https://towardsdatascience.com/meta-learners-for-estimating-treatment-effect-in-causal-inference-4f7071503401?source=collection_archive---------8-----------------------

揭开因果 ML 中 T-学习者、S-学习者和 X-学习者的神秘面纱

https://eng.uber.com/causal-inference-at-uber/

最近我看到优步在 github 上发布了caus AMLpython 库。它包括基于树的算法和在因果推理中估计治疗效果的元算法。我对这一努力感到非常兴奋——将最先进的机器学习技术与因果分析相结合。

知识库中有一个关于如何使用所有这些算法的很好的例子,在 Jupyter 笔记本上。对于没有听说过元学习者的人来说,这可能有点令人困惑。这篇文章我会试着解释代码中提到的一些元学习者,所有这些 T-学习者,S-学习者,X-学习者等等…

首先,我假设你已经知道什么是因果分析,以及它试图推断什么。如果不是,简要总结——因果关系试图回答‘如果’的问题。统计推断和机器学习技术关注 X 的变化如何与 Y 的变化相关联;然而,因果推理的重点是了解 X 对 Y 是否有因果影响,即 X 的变化是否会引起 Y 的变化——如果 X 不变,Y 还会变吗?

传统上,人们用平均治疗效果(ATE= E(Y=1)-E(Y=0)) 来衡量随机治疗组和对照组的差异。例如,兴趣的因果效应是使用优步的人们乘坐价格变化(降低价格)的影响:平均来说,如果我们降低价格,我们会获得多少次以上的乘坐。 吃了 ,在这种情况下,就是治疗组和对照组乘坐次数的期望值之差。

在这个例子中,一个正的 吃了 ,表明降低价格会增加使用优步的人数。负的 表示 表示价格变化降低了需求。一个等于零的估计值表明在乘坐次数方面提供治疗没有优势或劣势。确定一个 ATE 估计值是否可与零区分开(正的或负的)需要使用 p 值进行统计推断。

因为是对治疗的平均效果的估计,正的或负的并不表示任何特定的个体将受益于或受到治疗的伤害。**

随着包含个性化治疗的大型数据集的增加,我们希望超越平均治疗效果,了解治疗效果如何因人而异。一个替代是条件平均治疗效果(CATE,τ(X)= E[D | X = X]= E[Y(1)-Y(0)| X = X])它是以观察到的协变量为条件的治疗效果。**

元算法用于计算 、美食 。最常见的元算法采取两个步骤:

  1. 它使用基础学习者分别为控制组和治疗组估计结果的条件期望。
  2. 它取这些估计值之间的差值。

更具体地说,这里是回购中使用的几个元学习者。

  1. 网络学习者:

当基础学习器是基于树的方法时,我们称之为“T-学习器”,因为我们使用“二叉树”基础学习器来估计治疗组和对照组的两个响应。

步骤 1:我们使用任何监督学习来估计μ0(x) = E[Y(0)|X=x]和μ1(x) = E[Y(1)|X=x],我们将两个分类器表示为\hat{μ0}。和\hat{μ1(x)}。

步骤 2: T-learner 是{τ_ T(x)} = \ hat {μ1(x)}—\ hat {μ0(x)}

https://arxiv.org/pdf/1706.03461.pdf

2.s-学习者

“S-学习者”类似于“T-学习者”,只是当我们估计结果时,我们使用所有的预测值,而不赋予治疗变量特殊的作用,因此我们只需要一个“单一”估计值作为基础学习者。

治疗指示符作为类似于所有其他特征的特征被包括在内,而该指示符没有被赋予任何特殊的作用。

我们使用整个数据集上的任何基础学习器来测量预期结果μ(x,w) = E[Y_{obs}|X=x,W=w],将估计量表示为\hat{μ}

CATE 由下式给出:\hat{τ_s(x)}=\hat{μ(x,1)}-\hat{μ(x,0)}

https://arxiv.org/pdf/1706.03461.pdf

3.X-Learner

实际上,我们在对照组的数据往往比治疗组多。在我们在治疗组中只有非常少的数据点的情况下,使用 T-learner 会有问题,我们希望确保在数据非常小的情况下,我们不会对治疗组进行过度拟合。为了避免这个问题,一个需要思考的问题是——我们能利用来自对照组的信息来评估治疗组吗?这就是 X-learner 试图做的事情:使用来自控制组的信息为治疗组导出更好的估计值,反之亦然。它建立在 T-learner 的基础上,以类似“X”的形状使用训练集中的每个观察。这就是反事实发挥作用的地方。

第一步,我们使用任何基本学习器估计响应函数μ0(x)=E[Y(0)|X=x]和μ1(x)=E[Y(1)|X=x],将估计量表示为{μ0}和{μ1}

在第二步中,我们估算反事实,即基于控制结果估计值的治疗组中个体的治疗效果,以及基于治疗结果估计值的对照组中个体的治疗效果。方法是 Di1=Yi-\hat{\mu0(Xi)}和 Di0=\hat{\mu1(Xi)}-Yi0

第三步,我们使用估算信息估计τ1 和τ0。

最后,我们使用两个估计量{τ0}和{τ1}的加权平均值

https://arxiv.org/pdf/1706.03461.pdf

这是一个非常简短的 T 学习者、S 学习者和 X 学习者介绍。当我们进行在线实验或个性化推荐,想要衡量政策对个人的影响时,我们需要看到对个人层面的影响,而不是平均影响,或者当我们进行预测时,我们需要看到为什么会出现某种结果——无论是由于对该个人的政策变化。

使用元学习者可以帮助我们将机器学习算法与因果分析联系起来,并帮助我们理解结果发生变化的原因。他们可以将监督学习算法转化为 CATE 估计,帮助我们更好地理解预测结果。

参考:

Künzel,Sö ren R .等,“使用机器学习估计异质性治疗效果的金属载体。”美国国家科学院院刊 116.10(2019):4156-4165。交叉引用。网络。

** [## Uber/cau sall

该项目是稳定的,正在酝酿长期支持。它可能包含新的实验代码,对于这些代码,APIs

github.com](https://github.com/uber/causalml)

https://eng.uber.com/causal-inference-at-uber/**

元学习——人工智能一般化。

原文:https://towardsdatascience.com/meta-learning-ai-generalised-1007b9695fe1?source=collection_archive---------10-----------------------

人工智能学会学习,帮助从几个“镜头”中学习。

深度学习已经在各个领域取得了巨大的成功,并且正在继续展开它的翅膀。但是,训练任何传统神经网络模型的一个主要问题是需要大量的数据,并使用这些数据对许多标记的例子进行多次迭代更新。

我们来看一个猫 vs 狗分类的经典例子。虽然在过去的二十年里,我们已经使我们的模型越来越好,以增加准确性,但上述基本问题仍然存在。我们仍然需要大量贴有标签的狗和猫来获得相当的准确性。

人类如何用少得多的例子对它们进行分类。比方说,突然向你展示了两种新的动物,它们在视觉上就像猫和狗一样容易区分。我很确定任何正常人都可以在不到 100 个例子中获得相当的准确性。怎么会??多年来,我们已经了解了动物的基本结构。我们知道如何提取特征,如脸型、头发、尾巴、身体结构等..简而言之,我们已经掌握了学会学习的艺术。

元学习的目标基本上是学会学习,用最少的数据将人工智能推广到许多不同的场景。你可以说,迁移学习不也是这样吗?嗯,是的,这是朝着正确的方向发展,但还不够远。已经观察到,随着网络被训练的任务偏离目标任务,预训练网络的益处大大降低。元学习建议在两个层次上构建学习问题。第一个是在每个单独的任务中快速获取知识。这个过程是由第二个引导的,第二个过程是从所有的任务中慢慢提取信息。

元学习算法可以大致分为三类—

经典的基于梯度下降的方法

这类方法背后的直觉是再次使用标准梯度下降更新来使神经网络一般化到各种各样的数据集。

在这种方法中,我们使用一组数据集,每个数据集有几个例子,假设每个数据集有 k 个例子,用于“ k-shot 学习”。设数据集的集合为 p(T)。假设我们的模型是一个参数化的函数ₜₕₑₜₐ.如果我们从参数 θ、开始,我们知道模型随着每个单独数据集的标准梯度下降更新而更新。

我们希望我们的模型能够适用于大范围的数据集。因此,我们需要 p(T)中所有数据集的误差总和以及更新后的参数。这可以用数学方法表达如下—

对于 p(T)中的一批数据集,我们用一个标准 SGD 更新来更新 θ w.r. t .上面提到的元目标

我们可以看到,通过模型的梯度反向传播元损失包括计算导数的导数。这可以使用 TensorFlow 支持的 Hessian-vector products,来完成。

最近邻方法

这组方法的指导思想是最近邻算法不需要任何训练,但是性能取决于所选择的度量。

它们包括一个将输入域映射到特征空间的嵌入模型和一个将特征空间映射到任务变量的基本学习器。元学习的目标是学习一个嵌入模型,使得基础学习者能够很好地跨任务进行概括。这里是嵌入的基于距离的预测规则。我们将看一个具体的例子,匹配网络来理解工作原理。

匹配网络支持一组 k 个图像标签对的例子 S={(xᵢ ,yᵢ)}到分类器 cₛ(x',该分类器在给定测试例子 x’的情况下定义了输出 y’上的概率分布。S → cₛ(x')定义为 P(y'|x ',s),其中 p 由神经网络参数化。因此,给定一个新的示例 S’的支持集,我们简单地使用由 P 定义的参数神经网络来为每个测试示例 x’😛(y ' | x ',S’)预测适当的标签 y’。简单地说,我们可以说—

y cap and x cap — new example

the attention mechanism

上述方法让人想起 KDE 和 kNN 算法。

fg 是适合 x cap 和 xᵢ的嵌入式神经网络,这取决于任务。它们是用于图像任务(如 Inception)的深度 CNN 或用于语言任务的简单形式单词嵌入。

使用辅助空间的基于模型的方法

我们人类在处理东西的同时,也储存了表示以备将来使用。所以这些算法试图通过一些辅助内存块来模拟它。基本的策略是学习它应该放入记忆中的表示类型,以及它以后应该如何使用这些表示进行预测。

在这些方法中,输入序列和输出标签是按顺序给出的。一个数据集 d yₜ)}={dₜ}={(xₜ,其中 t 表示时间步长。xₜ.之后没有给出输出标签 yₜ对于每个数据集,输入和输入理想标签是混乱的。期望模型在给定的时间步输出 yₜxₜ(i.e.的适当标签。因此,它被迫将数据样本存储在内存中,直到找到合适的标签,之后可以绑定并存储样本类信息以备后用。

我们要讲的这个具体实现中的记忆模块是神经图灵机(NTM) 。它基本上是一个图灵机(读写头在一个内存块上)和一个 LSTM ( )或者有时是简单的基于神经网络 ) 的控制器。NTM 外部存储器模块中的存储器编码和检索是快速的,每个时间步都有可能将向量表示放入或取出存储器。这种能力使得 NTM 成为元学习和低射预测的完美候选,因为它既能够通过缓慢更新其权重进行长期存储,又能够通过其外部存储模块进行短期存储。

在某个时间步骤 t,给定 xₜ ,LSTM 控制器给出一个密钥 kₜ 用于访问存储器矩阵 Mₜ

Softmax 用于产生读写向量。

这是 rₜ.用来获取记忆的

这被用作下一个控制器状态的输入以及基于软最大值的分类器的输入。

少镜头学习的元迁移学习

原文:https://towardsdatascience.com/meta-transfer-learning-for-few-shot-learning-7c3c85e81687?source=collection_archive---------22-----------------------

摘要

元学习被提出作为一个框架来解决具有挑战性的少数镜头学习设置。关键的想法是利用大量类似的少量任务,以便学习如何使基础学习者适应只有少量标记样本可用的新任务。由于深度神经网络(DNNs)倾向于仅使用少数样本进行过度拟合,元学习通常使用浅层神经网络(SNNs),从而限制了其有效性。在本文中,我们提出了一种新的少镜头学习方法,称为【MTL】,它学习将一个 深度 NN 用于 少镜头学习任务 。具体来说,元指的是训练多个任务,迁移是通过学习每个任务的 DNN 权重的缩放和移位函数来实现的。此外,我们引入了 硬任务(HT)元批量 方案作为 MTL 的有效学习课程。我们使用(5 类,1 次)和(5 类,5 次)识别任务在两个具有挑战性的少数镜头学习基准上进行实验:miniImageNet 和 Fewshot-CIFAR100。与相关工作的广泛比较验证了用提出的 HT 元批量 方案训练的我们的 元迁移学习 方法达到最佳性能。消融研究还表明,这两种成分都有助于快速收敛和高精度。

贡献

  • 一种新的 MTL 方法,学习转移大规模预训练的 DNN 权重,以解决少数镜头学习任务。
  • 一种新颖的 HT 元批量学习策略,强制元迁移“在艰难中更快更强地成长”。
  • mini ImageNet 和 Fewshot-CIFAR100 上进行了大量的实验,取得了最先进的性能。

管道

我们提出的少镜头学习方法的流水线包括三个阶段:(a)在大规模数据上的 DNN 训练,使用所有训练数据点;(b)基于预训练的特征提取器,元转移学习(MTL)学习缩放和移位(SS)的参数。学习由提议的 HT 元批处理来调度;元测试是对一个看不见的任务进行的,它包括一个基础学习者微调阶段和一个最终评估阶段。输入数据沿箭头排列。名称以粗体显示的模块在相应的阶段得到更新。具体来说,SS 参数是通过元训练学习的,但在元测试期间是固定的。基础学习者参数针对每个任务进行了优化。

元迁移学习

(a)参数级微调(FT)是一种常规的元训练操作,例如在 MAML【1】。它的更新适用于所有神经元参数,𝑊和𝑏.(b)我们在元迁移学习中的神经元级缩放和移位(SS)操作。它们减少了学习参数的数量,避免了过拟合问题。此外,他们保持大规模训练参数(黄色)冻结,防止“灾难性遗忘”。

硬任务元批处理

在我们的元训练管道中,我们有意识地在每个任务中挑选失败案例,并将它们的数据重新组合成更难的任务,以便进行不利的重新训练。我们的目标是迫使我们的元学习者“在艰难中成长”。

该图显示了有和没有硬任务元批处理在准确性和收敛速度方面的性能差距。(a)(b)在 mini ImageNet 上 1 拍和 5 拍;(d)(e)few shot-cifar 100 上的 1 发、5 发和 10 发。

实验

迷你图像网

Fewshot-CIFAR100

参考

[1] Chelsea 等人,“用于深度网络快速适应的模型不可知元学习”在ICML 2017
[2] Oreshkin 等人,“TADAM:改进的少镜头学习的任务相关自适应度量”在 NeurIPS 2018

链接

项目页面:https://mtl.yyliu.net/

论文:http://open access . the CVF . com/content _ CVPR _ 2019/papers/Sun _ Meta-Transfer _ Learning _ for _ little-Shot _ Learning _ CVPR _ 2019 _ paper . pdf

代码:https://github.com/y2l/meta-transfer-learning

幻灯片:https://yyliu.net/files/meta-transfer-learning-slides.pdf

方法选择提示

原文:https://towardsdatascience.com/method-selection-pro-tip-ca733f6ae973?source=collection_archive---------14-----------------------

我经常从寻求方法选择建议的同事那里听到两个问题的快速解答

我准备研究 X,你觉得研究 X 的时候用哪种方法最好?

我不确定。我自己不研究 X。有没有看别人研究 X 用过的方法?我研究 Y,这里是我如何选择我的方法。我跟踪研究 y 的其他人,我跟踪他们用过的方法和他们还没用过的方法。我使用这些信息来通知(证明)我的方法选择。

Photo by Markus Winkler on Unsplash — “Searching” for methods. — More on attributions.

所以我给你的建议是找到 x 最近的出版物或研究,搞清楚他们用了什么方法,为什么。看看他们是否推荐其他人使用相同的方法或不同的方法。然后找到第二个最近的 x 的出版物或研究,重复这个过程。几轮之后,你会有一个方法列表,当你试图研究 x 时,这些方法可能会对你有所帮助。

好吧,我接受了你的建议。现在我有这三种方法可以选择。你认为我应该选哪一个?

你不是第一个经历这种情况的人。另外,我不确定我知道你问题的答案。但是我有一些建议。在这种情况下,许多人会使用这三种方法来实现分析。如果结果一致,太好了!听起来你有强有力的证据支持这个发现。这意味着您的结果对于多种方法和/或规格都是稳定的。

如果你的结果不一致,也很好!意味着你有强有力的证据支持需要进一步研究 X。这意味着对可用数据应用最广为人知的方法会返回不确定的结果。

[## 加入我的介绍链接媒体-亚当罗斯纳尔逊

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

adamrossnelson.medium.com](https://adamrossnelson.medium.com/membership)

感谢阅读

把你的想法和主意发给我。你可以写信只是为了说声嗨。如果你真的需要告诉我是怎么错的,我期待着尽快和你聊天。推特:@ adamrossnelson| LinkedIn:亚当·罗斯·纳尔逊 |脸书:亚当·罗斯·纳尔逊。

处理不平衡数据

原文:https://towardsdatascience.com/methods-for-dealing-with-imbalanced-data-5b761be45a18?source=collection_archive---------0-----------------------

Python 中有效处理不平衡数据集的指南

Photo by Ales Nesetril on Unsplash

不平衡类是机器学习分类中的一个常见问题,其中每个类中的观察值比例不成比例。在包括医疗诊断、垃圾邮件过滤和欺诈检测在内的许多不同领域中都可以发现类别不平衡。

在本指南中,我们将看看处理不平衡的班级问题的五种可能的方法。

重要说明:本指南将只关注解决不平衡类,而不会解决其他重要的机器学习步骤,包括但不限于特征选择或超参数调整。

数据

我们将使用 Kaggle 上提供的信用卡欺诈检测数据集。数据集高度不平衡,只有 0.17%的交易被归类为欺诈。完整的笔记本可以在这里找到。

我们的目标是正确分类欺诈交易的少数类别。

不平衡班级的问题

大多数机器学习算法在每个类别的样本数量大致相等时效果最佳。这是因为大多数算法都是为了最大限度地提高精度和减少误差而设计的。

准确性的问题

在这里,我们可以使用 DummyClassifier 来总是预测“不欺诈”,这只是为了说明准确性会有多么令人误解。

我们得到了 99.8%的准确率——甚至没有训练一个模型!让我们将其与逻辑回归进行比较,逻辑回归是一种经过实际训练的分类器。

也许并不奇怪,与上面的虚拟分类器相比,我们的准确度分数下降了。这告诉我们,要么我们在逻辑回归模型中做错了什么,要么准确性可能不是我们衡量绩效的最佳选择。

让我们来看看一些流行的处理阶级不平衡的方法。

1.更改绩效指标

正如我们在上面看到的,当评估不平衡的数据集时,准确性不是最好的衡量标准,因为它可能会产生误导。可以提供更好洞察力的指标包括:

  • 混淆矩阵:显示正确预测和错误预测类型的表格。
  • 精度:真阳性数除以所有阳性预测数。精度也叫阳性预测值。它是对分类器准确性的一种度量。低精度表示大量的误报。
  • 召回:测试数据中真阳性数除以阳性值数。回忆也称为敏感度或真实阳性率。它是对分类器完整性的一种度量。低召回率表示大量的假阴性。
  • F1:得分:准确率和召回率的加权平均值。

让我们看看当我们将这些 F1 和回忆分数应用到上面的逻辑回归时会发生什么。

这些分数看起来并不令人印象深刻。让我们看看我们可以尝试哪些其他方法来改进我们的新指标。

2.改变算法

虽然在每个机器学习问题中,尝试各种算法是一个很好的经验法则,但它对不平衡的数据集尤其有益。决策树通常在不平衡数据上表现良好。他们通过学习 if/else 问题的层次结构来工作,这可以迫使这两类问题都得到解决。

虽然我们的准确度分数略低,但 F1 和召回率都比逻辑回归有所增加!看来对于这个特定的问题,随机森林可能是一个更好的选择模型。

3.重采样技术-过采样少数类

我们的下一个方法开始我们的重采样技术。

过采样可以定义为添加少数类的更多副本。当您没有大量数据要处理时,过采样可能是一个不错的选择。

我们将使用 Scikit-Learn 中的重采样模块从少数类中随机复制样本。

重要提示

在尝试过采样技术之前,一定要分成测试集和训练集!在分割数据之前进行过采样可以允许在测试集和训练集中出现完全相同的观察结果。这可能会使我们的模型简单地记住特定的数据点,并导致对测试数据的过度拟合和不良概括。

重采样后,我们每个类的数据点比例相等!让我们用平衡的训练数据再次尝试我们的逻辑回归。

我们的回忆分数增加了,但 F1 比我们的基线逻辑回归或上面的随机森林低得多。让我们看看欠采样是否会有更好的表现。

4.重采样技术-欠采样多数类

欠采样可以定义为去除多数类的一些观察值。当你有大量数据时,欠采样可能是一个不错的选择——想想数百万行。但缺点是我们删除了可能有价值的信息。这可能导致对测试集的欠拟合和不良概括。

我们将再次使用 Scikit-Learn 中的重采样模块从多数类中随机移除样本。

同样,我们有相同比例的欺诈和非欺诈数据点,但在这种情况下,用于训练模型的数据量要小得多。让我们再次应用我们的逻辑回归。

在这种情况下,欠采样的表现不如过采样。让我们尝试另一种处理不平衡数据的方法。

5.生成合成样本

一种类似于上采样的技术是创建合成样本。这里我们将使用 imblearn 的 SMOTE 或合成少数过采样技术。SMOTE 使用最近邻算法来生成新的合成数据,我们可以使用这些数据来训练我们的模型。

同样,只在训练集中生成新样本很重要,以确保我们的模型能够很好地推广到看不见的数据。

在生成我们的合成数据点之后,让我们看看我们的逻辑回归是如何执行的。

我们的 F1 分数提高了,召回率与上面的上采样模型相似,对于我们的数据,这里优于欠采样。

结论

我们探讨了处理不平衡数据集的 5 种不同方法:

  1. 更改绩效指标
  2. 改变算法
  3. 过采样少数类
  4. 欠采样多数类
  5. 生成合成样本

对于这个特定的数据集,随机森林和 SMOTE 似乎是我们在这里尝试的最佳选项之一。

这些只是处理不平衡数据集时可以尝试的许多方法中的一部分,并不是一个详尽的列表。其他一些可以考虑的方法是收集更多的数据或选择不同的重采样比率——您不需要 1:1 的比率!

您应该总是尝试几种方法,然后决定哪种方法最适合您的问题。

利用损失函数深入挖掘度量学习

原文:https://towardsdatascience.com/metric-learning-loss-functions-5b67b3da99a5?source=collection_archive---------9-----------------------

撰稿人:杰克·巴格利昂,塞图·哈里什·科勒鲁

深度学习中的最新进展使得使用深度度量学习网络来学习一组图像的相似性度量成为可能,该网络将视觉上相似的图像映射到嵌入流形中的附近位置,并将视觉上不相似的图像彼此分开。使用这种方法学习的深度特征导致具有紧凑的产品内差异和良好分离的产品间差异的良好区分的特征,这是具有更好的视觉搜索引擎的关键。此外,学习这种区别性特征使得网络能够很好地对看不见的产品图像进行归纳,最终在嵌入空间中形成新的聚类。

(a) Separable Features (b) Discriminative Features

我们训练这些网络类似于其他深度学习网络,但具有不同的损失函数,在训练期间,这些网络在嵌入空间中明确地将相似的图像推到一起,并将不同的图像彼此拉开。在任何情况下, t 在训练期间,我们将训练数据集中的图像输入到网络,并将它们映射到嵌入空间。我们使用损失函数计算这些映射的惩罚,并使用适当的优化技术调整网络权重。在执行推理时,我们从嵌入层提取特征,并执行最近邻搜索来识别相似图像。

[## 使用深度度量学习来学习区分

一种使用卷积神经网络训练用于物体识别的可扩展深度学习模型的方法。

towardsdatascience.com](/deep-metric-learning-76fa0a5a415f)

在这篇文章中,我们将概述一些广泛使用的损失函数,用于学习度量学习嵌入。

Training and inference routine for Metric Learning Models. Note that, although there are various effective training routines available to achieve the same objective, here we are only concerned about the most basic and well-generalized training framework, shown in the picture.

对比损失

为了最小化两个相似图像的特征之间的距离并迫使不相似的图像特征彼此分开,对比损失函数在损失函数中独立地编码相似性和不相似性这两个度量。它直接处理两个相似图像的图像特征之间的距离,并且如果两个不同的图像特征没有被距离余量 α 分开,则它们之间的距离被包括在损失中。在这个意义上,损失函数定义如下。

这里, m 是在小批量中可用的锚阳性示例产品对的数量。Dᵢⱼ = ||f(xᵢ) — f(xⱼ)||是深层特征之间的距离 f(xᵢ)和 f(xⱼ)分别对应于图像 xᵢ和 xⱼ。yᵢⱼ= +/-1 是一对(xᵢ,xⱼ)是否共享相似标签的指示符。[.]⁺是铰链损失函数 max(0,.).每对特征向量独立生成一个损失项,如下图所示。

Edges colored red represent example pairs sharing similar labels and contributes to a loss term via Dᵢⱼ. This term addresses intra-class variance. On the other hand, blue represents example pairs with different product labels and uses α — Dᵢⱼ to generate a loss number. This term addresses inter-class separation among the feature clusters.

为了计算大小为 N 的数据集在每一步的损失,我们必须执行 O(N)成对距离计算。如果我们采用与随机梯度下降相似的方法,使用大小为 B 的小批量,则计算量为 O(B)量级。然而,如果我们从原始数据集中随机选择小批量,我们很可能会在小批量中没有任何正配对,因此我们不会在此设置中优化类内方差。因此,需要明确地为每个小批量选择相当数量的阳性对,优选接近小批量大小的约 50%,以获得紧凑的类内方差和大的类间分离。举个例子,比如说,我们设置小批量为 B=32 ,那么,

-我们将随机选择 16 产品。
-接下来,我们将从每个 16 产品中挑选 2 张随机图片。
-现在,在尺寸为 32 的小批量中,我们有 16 正对和 15 * 16 负对。

这个额外的手工挑选小批量的步骤将确保损失项也捕获类内方差,而没有任何额外的计算成本。

尽管对比损失函数很容易理解,但是当我们设置恒定的裕量 α 时,它并没有说明所有负面例子的视觉差异的程度。这将嵌入空间限制为仅具有所有可能失真的子集,同时将视觉上不同的产品训练和排列为视觉上相似的相似距离。例如,有三个图像,产品 A、产品 B 和产品 C 如下所示。直观上,产品 A 和产品 B 在视觉上比产品 A 和产品 C 更相似。然而,当我们设置$\ alpha$的恒定边距时,我们将产品 B 和产品 C 的特征向量从产品 A 的特征推开$\ alpha$的边距,假设它们具有相似的视觉相异度。

Product A and B are visually similar, with different product labels. Product C is visually different from the other two products. Despite having a different scale of visual similarity, margin α is constant for all three products.

三重损失

三重损失可能是度量学习中最流行的损失函数。三重损失接受三重深度特征(xᵢₐ、xᵢₚ、xᵢₙ),其中(xᵢₐ、xᵢₚ)具有相似的产品标签,而(xᵢₐ、xᵢₙ)具有不同的产品标签,并且调整网络,使得锚(xᵢₐ)和正(x)、d 之间的距离小于锚(x)和负(x)、d 之间的距离

这里,Dᵢₐ,ᵢₚ = ||f(xᵢₐ) — f(xᵢₚ)||₂,Dᵢₐ,ᵢₙ = ||f(xᵢₐ) — f(xᵢₙ)||₂.每个损失项独立考虑与预定义锚例相关的三元组来计算损失,如下图所示。

In a triplet (X1, X2, X3) red-colored line connects an anchor example X1 and positive example X2. Solid blue line connects anchor X1 and negative example X3, that shares different product labels. Unlike contrastive loss, each loss term addresses intra-class variance and inter-class separability together.

由于损失裕度不是直接基于两个嵌入之间的距离,而是基于三元组中的对之间相对于锚的相对距离,因此与对比损失相比,它考虑了任意嵌入空间失真。

虽然三重损失可以解决对比损失函数的这个问题,但是它在计算上是昂贵的。在用 B 三元组的小批量训练期间,我们将需要计算小批量中所有可能的三元组之间的距离,这导致超过 O(N ) 个可能的(不一定有效的)三元组,当训练大型数据集时,这在计算上是不可行的。例如,在一个简单的场景中,一个数据集有 20 个不同的产品类,每个包含 15 个图像,可以有 2 个来自 15 个图像的 20 个组合= 2100 个有效三元组( 2100 个可能的锚正示例对,每个从数据集中选择一个负产品示例)。为了得到所有可能对的总损失,需要 2100 / m 次小批量(大小为 m )迭代。此外,随着训练收敛,大多数三元组满足正对和负对距离之间的余量约束。它导致大多数三元组的少量贡献。这导致学习缓慢,从而收敛缓慢。

为了解决这种较慢的训练收敛,在大多数训练例程中,基于负面挖掘的方法是常见的。

提升结构损失

当训练具有三重损失目标的 CNN 时,它在产生损失时未能利用完整的小批量信息,这主要是因为正和负产品示例仅针对给定的锚示例被预定义。提升结构损失的想法是使用批次中可用的所有 O(B ) 对,而不是 O (B) 个单独的对,来改进小批次优化。下图显示了如何通过成对距离的距离矩阵扩展此功能以充分利用小批量。

An anchor and positive example pair, (X1, X2) and their interaction with remaining pairs in a mini-batch.

请注意,一对节点中的两个节点都独立地与微型批次中所有可用的负节点进行交互。在某种意义上,它不同于三重损失项,它不定义仅考虑预定义锚的负点,忽略小批量中可用的所有其他负点。它还将正面例子视为找到其负面例子并促成损失项的锚。有助于 CNN 训练有更快更好的收敛。

需要注意的是,如上图所示,对于给定的 X1 和 X2 对,随机从小批量的例子中选择否定乘积的例子,并不能像“否定那样促进更快的网络收敛。为了提高收敛速度,作者建议对给定对中的每个示例单独挖掘''硬'否定,如下图所示。

Hard negatives with respect to X1 and X2 are shown in solid blue line. Although X1 considers X6 as a negative it interacts with all the available negatives in a mini-batch.

提升结构损失函数最小化稳定网络训练的平滑上限。具体而言,给定小批量图像的提升结构化损失函数可以写成如下。

其中,Dᵢⱼ = ||f(xᵢ) — f(xⱼ)||₂. PN 分别是小批量生产的所有正负线对。

n 对损耗

多类 N 对损耗类似于提升结构损耗,因为它在给定的小批量中生成损耗项的同时补充了多个负乘积样本,并且不会像三重损耗和对比损耗那样遭受较慢的收敛。

For each loss term L, an anchor example (X1) of a given pair (X1, X2)
utilizes N-1 negative product examples available in a mini-batch (that is X4 and X6 here), when N is the number of pairs available in a mini-batch.

使用 N 对示例,按照下面的等式生成损失。

其中 N 是具有相似产品标签的图像对的总数。如果我们将 f 视为特征向量, f+ 视为权重向量,右手边的分母视为似然函数 P(y=y+) ,则上述等式类似于多类逻辑损失(即 softmax 损失)。此外,当训练数据集包含大量产品类时,此损失函数的性能会更好。 N (不同对的数量)的值越大,近似越精确。

使用 N 对损失超过提升结构损失的一个好处是,它试图以概率方式优化正锚点和负乘积样本之间的余弦相似性。换句话说,它计算一对特征之间的余弦相似性,并尝试在小批量中使用成对比较来增加这些特征在同一产品类中的概率。由于余弦相似性度量(以及概率)是比例不变的(如下图所示),N 对损失往往对训练期间的特征变化具有鲁棒性。

N-Pair loss directly addresses the cosine similarity between an anchor(x1) and positive example(x2), and compare it to the similarity between positive example and other negative examples in a probabilistic manner.

角度损失

与上面讨论的度量学习方法相反,其更集中于优化绝对距离(对比损失)或相对距离(三重损失、提升结构损失、N 对损失),角度损失提出根据负边缘的角度对三重三角形内部的三阶关系进行编码。

与 N 对损耗类似,它通过定义考虑角距离(余弦)的损耗函数,受益于比例不变性。它促使负特征向量远离正聚类,并拖动正点彼此靠近,如下图所示。

使用下面陈述的损失函数有几个优点:

-与欧几里德距离不同,角(余弦)距离是相似性变换不变的度量。当考虑角度几何时,它不仅受益于尺度不变性,而且还引入了旋转不变性。尽管图像特征在训练时经常被重新缩放,但对于固定的α裕量,∠n ≤ α总是成立。简而言之,损失项中的角度几何视图对特征图的局部变化更鲁棒。

——余弦法则解释 ∠n 的计算需要三角形的所有三条边。相比之下,原来的三联体只考虑到了两个方面。增加的约束鼓励优化的鲁棒性和有效性。

-当欧几里德被用作距离度量时,为损失项选择损失余量 m 不是一件简单的任务。这主要是因为随着数据集规模的增长,目标产品类之间的类内差异变化很大。在没有有意义的参考的情况下,调整这样的超参数是至关重要的。相比之下, α 设置起来更简单,因为它具有比例不变的特性。

此外,角度损失可以很容易地与传统的度量学习损失函数相结合,以提高整体性能。下面给出了它与 N 对损耗函数结合使用的一个例子。

λ 是 N 对和角度损耗之间的权衡权重。 λ 的默认值始终设置为 2。 α 可在 3560 度之间设定。

发散损失

尽管上面解释的所有度量学习目标函数都将给定图像嵌入到嵌入流形中,但是它们不一定明确地查看同一图像的各个方面。发散损失通过不同的系综模块探索这一观点。发散损失是一个正则化的术语,我们可以将它添加到联合监管的度量学习损失函数中。它增加了由不同集成模块学习的图像特征之间的距离。换句话说,它鼓励每个学习者关注输入图像的不同属性,如下图所示。

这里, (xᵢ,yᵢ) 是所有训练样本和标签的集合。 L₁ 是针对 mᵗʰ 学习者的度量学习损失函数 L₂ 是用于使每个学习者的特征嵌入多样化的正则化项 mλ 是控制正则化子强度的加权参数。

其中 xᵢ 是对应于图像 x 的特征向量。Dᵢₐ,ᵢₚ表示由两个不同的学习者 ap 嵌入的图像的特征嵌入之间的距离度量。 m 是发散损失的余量,通常设置为 1。【]⁺表示铰链功能 max(0,)

Divergence loss pulls apart the feature embeddings of different learners. In other words, it encourages feature instances, learned via different ensemble module, to attend different parts of an imaged object (X6 here). It results in diverse embedding space for all learners. Each learner individually satisfies the similarity constraint of projecting similar product labels nearby.

发散损失拉开了不同学习者的特征嵌入。换句话说,它鼓励通过不同集成模块学习的特征实例参与成像对象的不同部分(这里是 X6)。它为所有学习者带来了不同的嵌入空间。每个学习者单独满足附近投影相似产品标签的相似性约束。

结论

在本文中,我们讨论了一族度量学习损失函数,它在训练基于距离度量学习的卷积神经网络结构中起着至关重要的作用。这些损失函数使得网络能够解决传统对象识别例程的一些限制,因为它们可以用较少的可用图像实例来处理产品类别,并且使得灵活的系统可以容易地扩展到新产品类别。

尽管基于这些损失函数的度量学习网络在为我们的客户构建有效的视觉搜索解决方案方面已经显示出巨大的成功,但是这种系统的训练在计算上是昂贵且耗时的。在大小为 N 的数据集上计算损失并采取梯度步骤的顺序为 O(N )O(N ) ,这限制了我们在梯度下降方法中使用小批量(大小为 B )。这可能会将计算减少到 O(B )O(B ) ,但是我们如何构造迷你批处理变得极其重要。

在随机梯度下降中,我们通过随机抽样数据集和合理的批量大小来构建迷你批量。然而,例如,如果我们在三联体损失函数中使用随机抽样构建小批量,我们很可能不会得到任何违反裕度的正对甚至负对。在这种情况下,迷你批次的损耗贡献将非常小,因此是训练中的梯度步长。因此,通过采用小批量梯度方法,我们可能会减少小批量的计算量,但如果小批量没有足够的损失贡献,我们可能会进行更多的计算来达到最佳点。因此,对训练数据集进行采样并构建小批量的方法对于加快度量学习训练是至关重要的,以便它能够提供关于损失的足够信息,同时不会太大。

参考

[1]哈德塞尔,r .,乔普拉,s .,&勒昆,Y. (2006 年 6 月)。通过学习不变映射进行降维。2006 年 IEEE 计算机学会计算机视觉和模式识别会议(CVPR’06)(第 2 卷,第 1735-1742 页)。IEEE。

[2]文,杨,张,王,李,乔,(2016 年 10 月).一种用于深度人脸识别的鉴别特征学习方法。在欧洲计算机视觉会议上(第 499-515 页)。斯普林格,查姆。

[3]f .施罗夫、d .卡列尼琴科和 j .菲尔宾(2015 年)。Facenet:人脸识别和聚类的统一嵌入。IEEE 计算机视觉和模式识别会议论文集(第 815-823 页)。

[4] Oh Song,h .,Xiang,y .,Jegelka,s .,& Savarese,S. (2016 年)。基于提升结构特征嵌入的深度度量学习。IEEE 计算机视觉和模式识别会议论文集(第 4004-4012 页)。

[5]索恩·k .(2016 年)。具有多类 n 对损失目标的改进深度度量学习。神经信息处理系统的进展(第 1857-1865 页)。

[6]王军,周,方,文,刘,林,于(2017)。带有角度损失的深度度量学习。IEEE 计算机视觉国际会议论文集(第 2593–2601 页)。

[7] Kim,w .,Goyal,b .,Chawla,k .,Lee,j .,& Kwon,K. (2018 年)。用于深度度量学习的基于注意力的集成。《欧洲计算机视觉会议论文集》(ECCV)(第 736–751 页)。

度量和 Python

原文:https://towardsdatascience.com/metrics-and-python-850b60710e0c?source=collection_archive---------12-----------------------

在三篇系列文章中,我们将描述一组基本的统计概念和用于回归和分类的度量标准

Photo by Isabella Christina on Unsplash

作为一名程序员,我缺乏对数学和统计概念的研究。现在有了更多的经验,我决定汇编并分享一些我遇到的不同问题的度量标准和概念。

在这一系列文章中,我们将简要回顾它们的用法、公式、示例以及在 Python 中的实现,这样我们就可以一起看到它们,并且在必要时手头有这个图表。
这里是第一部分,指的是回归案例中最常用的指标。

数据集和模型

在本文中,我们使用了关于房价的 Kaggle 数据集,因为这是一个我们许多人都熟悉的回归的典型例子。
基本的工程特征已经完成,能够呈现一个最低限度的合理模型,作为度量标准开发的范例。

from scipy.stats import boxcox_normmax
from scipy.special import boxcox1p
from sklearn.linear_model import LinearRegressiontrain = pd.read_csv('../input/home-data-for-ml-course/train.csv')
y = train.SalePrice.reset_index(drop=True)features = train
end_features = ['OverallQual','GrLivArea','GarageCars','GarageArea','TotalBsmtSF','1stFlrSF','FullBath','TotRmsAbvGrd','MSSubClass','MSZoning']
features = features[end_features]features['MSSubClass'] = features['MSSubClass'].apply(str)
features['MSZoning'] = features.groupby('MSSubClass')['MSZoning'].transform(lambda x: x.fillna(x.mode()[0]))objects = [col for col in features.columns if features[col].dtype == "object"]
features.update(features[objects].fillna('None'))numeric_dtypes = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
numerics = [col for col in features.columns if features[col].dtype in numeric_dtypes]
features.update(features[numerics].fillna(0))for i in numerics:
    features[i] = boxcox1p(features[i], boxcox_normmax(features[i] + 1))X = pd.get_dummies(features).reset_index(drop=True)#----------------- The model
reg = LinearRegression().fit(X, y)
y_pred = reg.predict(X)

回归度量摘要

这是一个简单的表格,包含了我们将要描述的指标,表格的最后一列是我们模型的结果。

平均绝对误差

MAE 测量一组预测中误差的平均大小,不考虑它们的方向。它是预测和实际观察之间的绝对差异的测试样本的平均值,其中所有个体差异都具有相同的权重。

https://www.dataquest.io/blog/understanding-regression-error-metrics/

平均绝对误差使用与数据相同的标度。这被称为依赖于尺度的精度度量,因此不能用于使用不同尺度的系列之间的比较。

https://www.dataquest.io/blog/understanding-regression-error-metrics/

from sklearn.metrics import mean_absolute_error
print ('Sk MAE: ' + str(mean_absolute_error(y,y_pred)) )def MAE(predict,target):
    return (abs(predict-target)).mean()print ('My MAE: ' + str(MAE(y_pred,y)))

MSE:均方差

MSE 是一个风险函数,对应于平方误差损失的期望值。MSE 几乎总是严格为正(且不为零)的事实是因为随机性或者因为估计器没有考虑到能够产生更精确估计的信息。MSE 是对估计量质量的一种度量,它总是非负的,值越接近零越好。

https://www.geeksforgeeks.org/ml-mathematical-explanation-of-rmse-and-r-squared-error/

“最小化 MSE 是选择估值器的关键标准:见最小均方误差。在无偏估计量中,最小化 MSE 等价于最小化方差,而做这件事的估计量就是最小方差无偏估计量。然而,有偏估计量可能具有较低的 MSE 参见估计器偏差。

在统计建模中,MSE 可以表示实际观测值和模型预测的观测值之间的差异。在这种情况下,它用于确定模型与数据的吻合程度,以及是否可以在不明显损害模型预测能力的情况下删除一些解释变量。"

https://www.geeksforgeeks.org/ml-mathematical-explanation-of-rmse-and-r-squared-error/

from sklearn.metrics import mean_squared_error
print ('Sk MSE: ' + str(mean_squared_error(y,y_pred)) )def MSE(predict,target):
    return ((predict-target)**2).mean()
print ('My MSE: ' + str(MSE(y_pred,y)) )

RMSE:均方根误差

RMSE 是一个二次评分规则,也衡量误差的平均幅度。它是预测值和实际观测值之间的平均平方差的平方根。

https://www.includehelp.com/ml-ai/root-mean-square%20error-rmse.aspx

RMSE 和梅的比较

相似之处:

  • 用感兴趣变量的相同单位表示平均模型预测误差。
  • 范围从 0 到∞并且与误差方向无关。
  • 值越低越好。

差异:

  • 在求平均值之前求平方根,RMSE 给大误差一个相对较高的权重,所以当不希望有大误差时,RMSE 应该有用。
def RMSE(predict, target):
    return np.sqrt(((predict - target) ** 2).mean())
print ('My RMSE: ' + str(RMSE(y_pred,y)) )

MAPE:平均绝对百分比误差

在统计中预测方法的预测精度的度量,例如在趋势估计中,也用作机器学习中回归问题的损失函数。它通常用百分比来表示准确度。

虽然 MAPE 的概念听起来非常简单和令人信服,但它在实际应用中有重大缺陷 [*] ,并且有许多来自 MAPE 的关于缺陷和误导性结果的研究

https://www.dataquest.io/blog/understanding-regression-error-metrics/

def MAPE(predict,target):
    return ( abs((target - predict) / target).mean()) * 100print ('My MAPE: ' + str(MAPE(y_pred,y)) )

RMSLE:均方根对数误差

在 RMSLE 的情况下,你取预测值和实际值的对数。所以基本上,改变的是你测量的方差。我相信,当预测值和真实值都是巨大的数字时,如果不想惩罚预测值和实际值之间的巨大差异,通常会使用 RMSLE。

RMSLE 衡量实际和预测之间的比率。

对数(pi+1)对数(ai+1)对数(pi+1)对数(ai+1)

可以写成 log((pi+1)/(ai+1))log((pi+1)/(ai+1))

当值是巨大的数字时,如果不想惩罚巨大的差异,可以使用它。

此外,当您希望对低估的惩罚比对高估的惩罚更多时,也可以使用这种方法。

让我们看看下面的例子

情况 a) : Pi = 600,Ai = 1000 — RMSE = 400,RMSLE = 0.5108

情况 b) : Pi = 1400,Ai = 1000 — RMSE = 400,RMSLE = 0.3365

import mathdef RMSLE(predict, target):
    total = 0 
    for k in range(len(predict)):
        LPred= np.log1p(predict[k]+1)
        LTarg = np.log1p(target[k] + 1)
        if not (math.isnan(LPred)) and  not (math.isnan(LTarg)): 
            total = total + ((LPred-LTarg) **2)

    total = total / len(predict)        
    return np.sqrt(total)print ('My RMSLE: ' + str(RMSLE(y_pred,y)) )

R and R 平方:决定系数

R and R 平方帮助我们了解我们的回归模型与一个非常简单的模型相比有多好,该模型仅预测来自作为预测的训练集的目标的平均值。

https://www.datasciencecentral.com/profiles/blogs/r-squared-in-one-picture

def R2(predict, target):
    return 1 - (MAE(predict,target) / MAE(target.mean(),target))def R_SQR(predict, target):
    r2 = R2(predict,target)
    return np.sqrt(r2)print ('My R2         : ' + str(R2(y_pred,y)) )
print ('My R          : ' + str(R_SQR(y_pred,y)) )

调整后 R

表现等同于基线的模型会将 R 平方值设为 0。模型越好,r2 值越高。具有所有正确预测的最佳模型会给出 R 平方为 1。但是,在向模型中添加新要素时,R 平方值要么增加,要么保持不变。R-Squared 不会因添加对模型没有任何价值的要素而受到惩罚。因此,R 平方的改进版本是调整后的 R 平方

http://www.haghish.com/statistics/stata-blog/stata-programming/adjusted_R_squared.php

def R2_ADJ(predict, target, k):
    r2 = R2(predict,target)
    n = len(target)
    return (1 -  ( (1-r2) *  ( (n-1) / (n-(k+1)) ) ) )k= len(features.columns)
print ('My R2 adjusted: ' + str(R2_ADJ(y_pred,y,k)) )

摘要

将主要的回归度量放在一个表中,并为它们中的每一个编写函数,这是一种极好的个人体验。在同一个练习中使用它们,因为这让我能够比较它们的用途,理解它们的公式,并在撰写文章时有一个完整的画面。
希望这篇文章是有用的,欢迎任何评论或更正。

下周我们将发表这个系列的第二部分,一篇关于分类度量的文章……

来源

[## 绝对平均误差

在统计学中,平均绝对误差(MAE)是两个连续变量之间差异的度量。假设 X 和是…

en.wikipedia.org](https://en.wikipedia.org/wiki/Mean_absolute_error) [## 梅和 RMSE——哪个指标更好?

平均绝对误差与均方根误差

medium.com](https://medium.com/human-in-a-machine-world/mae-and-rmse-which-metric-is-better-e60ac3bde13d) [## 教程:了解线性回归和回归误差度量

人类大脑的构造是为了识别我们周围世界的模式。例如,我们观察到如果我们练习…

www.dataquest.io](https://www.dataquest.io/blog/understanding-regression-error-metrics/) [## RMSE 和 R 平方误差的数学解释

RMSE:均方根误差是回归线与数据点拟合程度的量度。RMSE 也可以是…

www.geeksforgeeks.org](https://www.geeksforgeeks.org/ml-mathematical-explanation-of-rmse-and-r-squared-error/) [## 均方误差

在统计学中,估计量的均方误差(MSE)或均方偏差(MSD)

en.wikipedia.org](https://en.wikipedia.org/wiki/Mean_squared_error) [## 均方根误差(RMSE) |机器学习

首页“机器学习/人工智能均方根误差(RMSE):在这篇文章中,我们将学习…

www.includehelp.com](https://www.includehelp.com/ml-ai/root-mean-square error-rmse.aspx) [## 均方根偏差

均方根偏差(RMSD)或均方根误差(RMSE)(有时也称为均方根误差)是一个…

en.wikipedia.org](https://en.wikipedia.org/wiki/Root-mean-square_deviation) [## 欢迎使用销售预测、库存计划、需求计划、销售和运营预测软件

预测 101:预测误差测量统计和如何使用它们的指南误差测量统计发挥…

www.forecastpro.com](https://www.forecastpro.com/Trends/forecasting101August2011.html) [## 平均绝对百分比误差

平均绝对百分比误差(MAPE),也称为平均绝对百分比偏差(MAPD),是衡量…

en.wikipedia.org](https://en.wikipedia.org/wiki/Mean_absolute_percentage_error) [## RMSE 和 RMSLE(对数误差)之间有什么区别,高 RMSE 是否意味着…

回答(第 1 题,共 2 题):均方根误差(RMSE)和均方根对数误差(RMSLE)都是技术…

www.quora.com](https://www.quora.com/What-is-the-difference-between-an-RMSE-and-RMSLE-logarithmic-error-and-does-a-high-RMSE-imply-low-RMSLE)

https://en.wikipedia.org/wiki/Coefficient_of_determination

[## 每个人都应该知道的机器学习的 11 个重要模型评估指标

概述评估模型是构建有效机器学习模型的核心部分,有几种评估方法…

www.analyticsvidhya.com](https://www.analyticsvidhya.com/blog/2019/08/11-important-model-evaluation-error-metrics/?utm_source=twitter.com&utm_medium=social) [## 在 Stata 中计算调整后的 R 平方

2014 年 11 月 23 日更新|快速提示| |简介| |算法| | r2_a 程序| |分析| |练习|…

www.haghish.com](http://www.haghish.com/statistics/stata-blog/stata-programming/adjusted_R_squared.php) [## 决定系数

在统计学中,决定系数,表示为 R 2 或 r 2,读作“R 的平方”,是…

en.wikipedia.org](https://en.wikipedia.org/wiki/Coefficient_of_determination)

度量和 Python II

原文:https://towardsdatascience.com/metrics-and-python-ii-2e49597964ff?source=collection_archive---------15-----------------------

在之前的文章中,我们采用了回归问题的度量指南。现在我们来看看分类问题中最常用的指标

Photo by Miguel A. Amutio on Unsplash

数据集

我们创建一个包含三个数组的数据集:真实值、预测值和似然值。
real _ values:0 到 1 之间有 1000 个元素的数据集。
pred_values :真实数据集的变体,模拟预测,只改变前 150 个值。
【prob _ values】:pred _ values 数组,但包含概率为 0 或 1 的百分比,而不是实际值 0 或 1。它将用于 ROC 图表和召回与精确对比。

real_values = []
prob_values = []
pred_values = []for k in range(0,1000):
   value = random.uniform(0, 1)
   real_values.append(int(round(value,0))) if k < 150:
      value2 = random.uniform(0, 1)
      prob_values.append(value2)
      pred_values.append(int(round(value2,0)))
   else:
      prob_values.append(value)
      pred_values.append(int(round(value,0)))

混淆矩阵

混淆矩阵本身不是一个指标,但它是对真实数据和预测进行分类的重要工具,因此它的组成部分是第一组指标的触发器。

from sklearn.metrics import confusion_matrix
import scikitplot as skplt
print(confusion_matrix(real_values, pred_values))
skplt.metrics.plot_confusion_matrix(real_values, pred_values,figsize=(8,8))

二元分类—表 2.1

https://kreilabs.com/wp-content/uploads/2019/12/Metrics_table.pdf

您可以在https://kreilabs . com/WP-content/uploads/2019/12/Metrics _ table . pdf中下载完整文件

在这里,我们可以看到 matrix_metrix 例程中表指标的 pyhton 实现:

import sklearn.metrics
import mathdef matrix_metrix(real_values,pred_values,beta):
   CM = confusion_matrix(real_values,pred_values)
   TN = CM[0][0]
   FN = CM[1][0] 
   TP = CM[1][1]
   FP = CM[0][1]
   Population = TN+FN+TP+FP
   Prevalence = round( (TP+FP) / Population,2)
   Accuracy   = round( (TP+TN) / Population,4)
   Precision  = round( TP / (TP+FP),4 )
   NPV        = round( TN / (TN+FN),4 )
   FDR        = round( FP / (TP+FP),4 )
   FOR        = round( FN / (TN+FN),4 ) 
   check_Pos  = Precision + FDR
   check_Neg  = NPV + FOR
   Recall     = round( TP / (TP+FN),4 )
   FPR        = round( FP / (TN+FP),4 )
   FNR        = round( FN / (TP+FN),4 )
   TNR        = round( TN / (TN+FP),4 ) 
   check_Pos2 = Recall + FNR
   check_Neg2 = FPR + TNR
   LRPos      = round( Recall/FPR,4 ) 
   LRNeg      = round( FNR / TNR ,4 )
   DOR        = round( LRPos/LRNeg)
   F1         = round ( 2 * ((Precision*Recall)/(Precision+Recall)),4)
   FBeta      = round ( (1+beta**2)*((Precision*Recall)/((beta**2 * Precision)+ Recall)) ,4)
   MCC        = round ( ((TP*TN)-(FP*FN))/math.sqrt((TP+FP)*(TP+FN)*(TN+FP)*(TN+FN))  ,4)
   BM         = Recall+TNR-1
   MK         = Precision+NPV-1 mat_met = pd.DataFrame({
'Metric':['TP','TN','FP','FN','Prevalence','Accuracy','Precision','NPV','FDR','FOR','check_Pos','check_Neg','Recall','FPR','FNR','TNR','check_Pos2','check_Neg2','LR+','LR-','DOR','F1','FBeta','MCC','BM','MK'],     'Value':[TP,TN,FP,FN,Prevalence,Accuracy,Precision,NPV,FDR,FOR,check_Pos,check_Neg,Recall,FPR,FNR,TNR,check_Pos2,check_Neg2,LRPos,LRNeg,DOR,F1,FBeta,MCC,BM,MK]}) return (mat_met)

当我们调用 matrix_metrix 函数时:

beta = 0.4
mat_met = matrix_metrix(real_values,pred_values,beta)
print (mat_met)

Note: Prevalence is 0.505, code has a mistake at first version

预测值和实际值

https://en.wikipedia.org/wiki/Confusion_matrix

TP =真阳性

TN =真阴性

FP =假阳性 —相当于假警报或 I 类错误

FN =假阴性— 相当于遗漏或II 型错误

总费率*

https://en.wikipedia.org/wiki/Confusion_matrix

患病率:用于衡量总人口中数据的平衡。
可以测量阳性或阴性的发生率,并且两个商数之和= 1,一个平衡的数据集将给出接近 0.5 的系数
如果相反,其中一个因素接近 1,另一个接近 0,我们将得到一个不平衡的数据集。

精度:它是系统成功的度量,正面和负面成果的总和超过总人口,表明模型的成功程度。根据案例研究的灵敏度的成本,以及数据的平衡(患病率)。

预测利率*

https://en.wikipedia.org/wiki/Confusion_matrix

PPV——精确度的阳性预测值

NPV —负面预测值

PPV 和 NPV 描述了诊断测试或其他统计测量的性能。高结果可以被解释为表明这种统计的准确性。PPV 和 NPV 不是测试固有的;它们还取决于流行率。⁴

FDR —错误发现率(第一类)【四】

——漏报率

check_Pos: PPV + FDR = 1

check_Neg: FOR + NPV = 1

条件利率*

https://en.wikipedia.org/wiki/Confusion_matrix

回忆、灵敏度、检测概率和功效是相同的度量,根据研究领域的不同,它们采用不同的名称和应用。
在涉及二元分类问题的文献中,召回一词的使用更为频繁。

“敏感性特异性是二元分类测试性能的统计测量,在统计学中也称为分类函数,广泛用于医学:

灵敏度测量被正确识别的实际阳性的比例。

特异性(也称为真阴性率)衡量被正确识别为真阴性的比例(例如,被正确识别为没有患病的健康人的百分比)。⁵

FPR — 假阳性率(或误报率)是某一特定检验错误拒绝零假设的概率。

FNR —假阴性率是指在测试中产生阴性测试结果的阳性比例,即,假设正在寻找的条件存在,阴性测试结果的条件概率。

在统计假设检验中,这个分数用字母β表示。测试的“功率”(或“灵敏度”)等于 1β。

组合费率*

https://en.wikipedia.org/wiki/Confusion_matrix

不要与似然比测试混淆。

LR (+ -) 似然比:用于评估执行诊断测试的价值。⁶

or—诊断优势比是对诊断测试⁷有效性的一种衡量

二元分类—表 2.2

https://kreilabs.com/wp-content/uploads/2019/12/Metrics_table.pdf

从用于表 1 的 matrix_metrix 函数中,我们还获得了该表 2 的值:

F1 分数

在二进制分类的统计分析中, F1 得分(也称为 F 得分F 度量)是测试准确度的度量。它同时考虑了测试的精度 p 和召回率 r 来计算分数: p 是正确阳性结果的数量除以分类器返回的所有阳性结果的数量, r 是正确阳性结果的数量除以所有相关样本(所有本应被识别为阳性的样本)的数量。F1 分数是精确度和召回率的调和平均值,其中 F1 分数在 1 时达到其最佳值(完美的精确度和召回率),在 0 时最差。⁸

f-贝塔 Score⁹

β是用于分数分析的参数,如果我们使用β等于 1,我们就有调和平均值;然后我们有了 F1 的分数 :

我们可以采取一些经验法则:

  • 为了给精度更多的权重,我们必须在 0–10<Beta<1之间选择一个 Beta 值
  • 为了给回忆更多的权重,我们在区间1<Beta<+无穷大* 中挑选一个 Beta 值*

ROC 对比精确召回和 AUC ⁰

我们可以在中找到一篇关于这些工具的概念和实现的优秀且非常完整的文章。

ROC —接收操作特性

它是针对 0.0 和 1.0 之间的多个不同候选阈值的假阳性率(x 轴)与真阳性率(y 轴)的关系图。换句话说,它绘制了虚警率与命中率的关系图。

精确召回曲线

精确度-召回率曲线是不同阈值的精确度(y 轴)和召回率(x 轴)的曲线图,很像 ROC 曲线。无技能分类器是一种不能区分类别的分类器,它在所有情况下都会预测随机类别或恒定类别。无技能线的变化是基于积极类和消极类的分布。它是一条水平线,带有数据集中阳性案例的比率值。对于平衡数据集,这是 0.5。

AUC —曲线下面积

曲线下面积(AUC)可用作模型技巧的总结。

我们基于上述文章编写了以下代码

*#ROC Implementation
from sklearn.metrics import roc_curve
from sklearn.metrics import roc_auc_score
from matplotlib import pyplotfpr, tpr, thresholds = roc_curve(real_values, prob_values)
auc = roc_auc_score(real_values, prob_values)
print('AUC: %.3f' % auc)pyplot.plot(fpr, tpr, linestyle='--', label='Roc curve')
pyplot.xlabel('False Positive Rate')
pyplot.ylabel('True Positive Rate')
pyplot.legend()pyplot.show()*

*#Precision-recall implementationprecision, recall, thresholds = sklearn.metrics.precision_recall_curve(real_values,prob_values)pyplot.plot(recall, precision, linestyle='--', label='Precision versus Recall')
pyplot.xlabel('Recall')
pyplot.ylabel('Precision')
pyplot.legend()pyplot.show()*

Sklearn 的其他实现和指标

这里有一个简单快速的关于二元分类值的报告

这里有一个直接从 sklearn 获取许多指标函数:

*def sk_metrix(real_values,pred_values,beta):
   Accuracy = round( sklearn.metrics.accuracy_score(real_values,pred_values) ,4)

   Precision  = round( sklearn.metrics.precision_score(real_values,pred_values),4 )

   Recall     = round( sklearn.metrics.recall_score(real_values,pred_values),4 ) F1         = round ( sklearn.metrics.f1_score(real_values,pred_values),4)

   FBeta      = round ( sklearn.metrics.fbeta_score(real_values,pred_values,beta) ,4) MCC        = round ( sklearn.metrics.matthews_corrcoef(real_values,pred_values)  ,4) Hamming    = round ( sklearn.metrics.hamming_loss(real_values,pred_values) ,4) Jaccard    = round ( sklearn.metrics.jaccard_score(real_values,pred_values) ,4) Prec_Avg   = round ( sklearn.metrics.average_precision_score(real_values,pred_values) ,4) Accu_Avg   = round ( sklearn.metrics.balanced_accuracy_score(real_values,pred_values) ,4) mat_met = pd.DataFrame({
'Metric': ['Accuracy','Precision','Recall','F1','FBeta','MCC','Hamming','Jaccard','Precision_Avg','Accuracy_Avg'],
'Value': [Accuracy,Precision,Recall,F1,FBeta,MCC,Hamming,Jaccard,Prec_Avg,Accu_Avg]}) return (mat_met)*

调用 sk_metrix 函数

*sk_met = sk_metrix(real_values,pred_values,beta)*

摘要

混淆矩阵中产生的指标数量非常大,根据用例来细化每个指标的使用可能很难涵盖。最常见的指标可能是 F1 评分、ROC、精确回忆 AUC、患病率和敏感性。

这一系列文章旨在创建一个表格,在该表格中可以快速找到每个案例研究中使用的大多数指标的指南;掌握它们的应用超出了我们的范围,似乎也相当困难。
记住表格可以下载成 pdf 格式。

在下一篇文章中,我们将在表 2.3 中看到更多的分类指标和推荐系统的具体指标

参考

https://en.wikipedia.org/wiki/Confusion_matrix

[1]第一类错误

[2]第二类错误

[3]https://medium . com/Mercado libre-datablog/cost-sensitive-class-in-fraud-prevention-263170 D8 fcfe

【4】阳性和阴性预测值(分别为 PPVNPV )分别为统计和诊断测试中阳性和阴性结果的比例,分别为真阳性和真阴性结果。【1】“PPV 和 NPV 描述了诊断测试或其他统计测量的性能。高结果可以被解释为表明这种统计的准确性。PPV 和 NPV 不是测试固有的;它们也取决于流行程度。【2】使用贝叶斯定理可以推导出 PPV。虽然有时用作同义词,但是阳性预测值通常是指由对照组建立的,而测试后概率是指个体的概率。然而,如果个体的目标状况的预测试概率与用于建立阳性预测值的对照组中的患病率相同,则两者在数值上相等。

(https://en . Wikipedia . org/wiki/Positive _ and _ negative _ predictive _ values)

https://en.wikipedia.org/wiki/Sensitivity_and_specificity

[6]https://en . Wikipedia . org/wiki/Likelihood _ ratios _ in _ diagnostic _ testing # positive _ Likelihood _ ratio

[7]https://en.wikipedia.org/wiki/Diagnostic_odds_ratio

[8]https://en.wikipedia.org/wiki/F1_score

[9]http://www . marcelonet . com/snippets/machine-learning/evaluation-metrix/f-beta-score

[10]https://machine learning mastery . com/roc-curves-and-precision-recall-curves-for-class ification-in-python/

用于评估机器学习分类模型的度量

原文:https://towardsdatascience.com/metrics-for-evaluating-machine-learning-classification-models-python-example-59b905e079a5?source=collection_archive---------7-----------------------

Photo by Chris Liverani on Unsplash

在机器学习领域,有三种主要的问题:回归、分类和聚类。根据您正在处理的问题的类型,您将希望使用一组特定的指标来衡量您的模型的性能。这可以用一个例子来很好地说明。假设一家公司声称已经开发出面部检测算法,可以以 99.9%的准确率识别恐怖分子。抛开道德影响不谈,这应该会立即引发一个危险信号。恐怖分子只占人口的很小一部分(我找不到实际的统计数据,但我们假设是 0.001%)。因此,通过假设没有人是恐怖分子(即编写一个始终返回 false 的程序),我们可以达到 99.9%以上的准确率。因此,准确性不是评估模型性能的好指标,因为它错误地将每个恐怖分子分类,但仍然获得了很高的分数。

混淆矩阵

另一方面,混淆矩阵将区分被正确分类为非恐怖分子的样本数量和被正确分类为恐怖分子的样本数量。混淆矩阵被分成 4 个象限。

https://commons.wikimedia.org/wiki/File:Binary_confusion_matrix.jpg

真阳性:

解读:你预测的是正的,这是真的。

你预测那个人是恐怖分子,他们确实是。

真阴性:

解读:你预测的是负数,这是真的。

你预测那个人不是恐怖分子,而他们实际上不是。

假阳性:(1 型错误)

解读:你预测的是正的,是假的。

你预测那个人是恐怖分子,但他们实际上不是。

假阴性:(2 型错误)

解读:你预测的是负数,这是假的。

你预测那个人不是恐怖分子,但他们确实是。

精确度/召回率

有时,使用数字来评估模型的性能比依赖库来可视化混乱矩阵更容易。

在现实世界中,你会遇到分类问题,分界线迫使你在高精度和高召回率之间做出选择。在某些情况下,精度越高越好。例如,诊断中出现一些假阳性可能会更好,而不是让任何真正患有疾病的人从裂缝中溜走,逃避治疗。其他时候,最好有更高的召回率,就像垃圾邮件过滤器一样。在用户的收件箱里放几封垃圾邮件比把重要的邮件归类为垃圾邮件更容易被接受。为了形成更好的判断,我们可以用图形来表示精确度和召回率之间的权衡。

https://commons.wikimedia.org/wiki/File:ROCCurve.png

如果我们可以使用一个单一的分数,而不是每次都测量召回率和精确度,这将会更容易。首先,我们可以试着取两个结果的平均值。例如,假设一个垃圾邮件检测器的准确率为 80%,召回率为 37%,那么平均准确率为 58.5%。现在,假设我们构建了垃圾邮件检测器,它不会将任何电子邮件视为垃圾邮件(类似于恐怖分子的例子)。如果非垃圾邮件明显多于垃圾邮件,我们的模型将被解释为性能良好。具体来说,如果 300,000 封电子邮件是垃圾邮件(不是垃圾邮件), 500 封是垃圾邮件,那么将所有电子邮件分类为垃圾邮件的模型将获得 100%的精确度,因为它正确地分类了所有垃圾邮件,并且召回率为 0%,因为它错误地分类了所有垃圾邮件。如果我们取平均值,我们仍然会得到 50%,这有点误导,因为垃圾邮件检测器的整个目的是检测垃圾邮件。

正是由于上述原因,我们使用调和平均值而不是算术平均值来计算平均值。调和平均值总是更接近较小的数,而不是较大的数。

回到我们的垃圾邮件检测器的例子。如果精度等于 100%,召回率等于 0%,则调和平均值等于 0%。我们把这个值叫做 F1 分数

ROC / AUC

类似于精确度/召回率曲线,接收器操作者特征(ROC)图提供了一种优雅的方式来呈现在不同阈值下产生的多个混淆矩阵。ROC 绘制了真阳性率和假阳性率之间的关系。

  • 真阳性率=召回率=灵敏度=真阳性/(真阳性+假阴性)
  • 假阳性率= 1–特异性=假阳性/(假阳性+真阴性)

https://en.wikipedia.org/wiki/File:Basic_AUC_annotated.png

值得注意的是,假阳性率是 1 减去特异性,这意味着假阳性率越接近 0,特异性就越高(回忆)。因此,为了获得特异性和敏感性的最佳值,我们需要选择左上角的一个点。

另一方面,曲线下面积(AUC)使得将一条 ROC 曲线与另一条进行比较变得容易。例如,红色 ROC 曲线的 AUC 大于蓝色 ROC 曲线的 AUC。因此,对于相同量的特异性,与红色曲线相关的模型实现了更高的灵敏度。

https://commons.wikimedia.org/wiki/File:ROC_curve.svg

密码

在前面的例子中,我们将看一下前面所有正在运行的指标。

import pandas as pd
from matplotlib import pyplot as plt
plt.style.use('dark_background')
from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import roc_curve
from sklearn.metrics import auc
from sklearn.metrics import precision_recall_curve
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
from sklearn.metrics import f1_score
from sklearn.metrics import average_precision_score
from inspect import signature

为简单起见,我们将使用 sklearn 提供的一个数据集。

breast_cancer = load_breast_cancer()X = pd.DataFrame(breast_cancer.data, columns=breast_cancer.feature_names)y = pd.Categorical.from_codes(breast_cancer.target, breast_cancer.target_names)encoder = LabelEncoder()y = pd.Series(encoder.fit_transform(y))

这些指标将用于衡量我们的模型做出的预测与测试集中包含的样本之间的差异。

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)

我们将使用随机森林分类器,但任何分类算法都可以。

rf = RandomForestClassifier()rf.fit(X_train, y_train)

我们称 predict_proba 方法 r 而不是 predict 以获得一个概率列表,该列表表示样本属于给定类别的可能性。这类似于深度学习中常用的 softmax 激活函数。

probs = rf.predict_proba(X_test)

roc_curve方法需要一个单一的特征。因此,我们采用肿瘤是恶性的预测概率。

malignant_probs = probs[:,1]fpr, tpr, thresholds = roc_curve(y_test, malignant_probs)roc_auc = auc(fpr, tpr)

在这个例子中很难看到,但我们通常会选择左上角的一个点,它将产生最佳的灵敏度和特异性。AUC 为 0.98 意味着在特异性和敏感性之间几乎没有权衡。

plt.title('Receiver Operating Characteristic')
plt.plot(fpr, tpr, 'y', label = 'AUC = %0.2f' % roc_auc)
plt.legend(loc = 'lower right')
plt.plot([0, 1], [0, 1],'r--')
plt.xlim([0, 1])
plt.ylim([0, 1])
plt.ylabel('True Positive Rate')
plt.xlabel('False Positive Rate')
plt.show()

接下来,让我们看看其他一些指标来评估我们模型的性能。首先,我们使用我们的模型根据上一步的概率对数据进行分类。

y_pred = rf.predict(X_test)

快速提醒一下,precision 测量的是真阳性,而不是真阳性加上假阳性。

precision_score(y_test, y_pred)

召回衡量的是真阳性与真阳性和假阴性之比。

recall_score(y_test, y_pred)

F1 分数使用调和平均值结合了精确度和召回率。

f1_score(y_test, y_pred)

选择对应于右上角的阈值数量将导致精确度和召回率的最佳组合。

precision, recall, threshold = precision_recall_curve(y_test, y_pred)
average_precision = average_precision_score(y_test, y_pred)step_kwargs = ({'step': 'post'} if 'step' in signature(plt.fill_between).parameters else {})
plt.step(recall, precision, color='r', alpha=0.2, where='post')
plt.fill_between(recall, precision, alpha=0.2, color='r', **step_kwargs)
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.ylim([0.0, 1.0])
plt.xlim([0.0, 1.0])
plt.title('2-class Precision-Recall curve: AP={0:0.2f}'.format(average_precision))

最后的想法

我们用来评估模型性能的度量标准的选择取决于问题的性质。对于分类模型,我们可以使用精度、召回率、f1 得分或 ROC 曲线来衡量性能。

不平衡分类的度量

原文:https://towardsdatascience.com/metrics-for-imbalanced-classification-41c71549bbb5?source=collection_archive---------3-----------------------

数据科学中的指标概念极其重要。如果你不知道如何正确评估当前的结果,你也无法提高它们。对度量的错误理解也会导致对模型容量的错误估计和对问题状态的错误理解。当前的故事将揭示分类问题的流行度量的本质。所有讨论的指标都将在 NumPy 中实现,以满足他们的需求。讨论的指标列表包括:精确度、召回率、F1、MCC 和 ROC-AUC

问题定式化

分类问题将是两个 MNIST 数字 0 和 6 之间的二进制分类,因为它们非常相似,很难区分它们本身。考虑到 metrics 的目的是深入了解不平衡分类问题,让阳性类别(6 位数)占少数,更具体地说,阳性样本总数将是阴性样本的 30%左右。我们正在使用的模型是基本的逻辑回归。以下代码片段的完整源代码可以在 github 找到。

流行指标

衡量分类的一个非常简单的标准是基本准确性,即正确预测与数据集中样本总数的比率。然而,在不平衡类的情况下,这种度量可能是误导性的,因为高度量不能显示少数类的预测能力。您可能有 99%的准确率,但对您真正感兴趣的类的预测能力仍然很差(即异常检测,其中异常是数据集中罕见的类)。为了更好地理解当前模型的预测能力,让我们从待分类样本的四种可能情况开始

  • 真阳性(TP)—样本的标签为阳性,且被归类为阳性
  • 真阴性(TN) —样本的标签为阴性,且被归类为阴性
  • 假阳性(FP)—样本标签为阴性。,但它被归类为阳性
  • 假阴性(FN)—样本标签已贴上。,但它被归类为否定的

基于这四个量,我们可以导出不平衡类的以下度量

真阳性率(也有灵敏度召回)

召回指标显示了选择了多少相关样本,这意味着我们的模型可以预测我们数据集中所有感兴趣的样本。

假阳性率(也称脱落)

精度

精度指标告诉我们有多少预测样本是相关的,即如果样本不正确,我们将样本分类为正确样本的错误。

真阴性率(也称特异性)

F1-得分

F1 指标是精度和召回率的调和平均值,计算如下

对于不平衡的分类场景,这个度量是一个很好的选择。F1 的取值范围在[0,1]内,其中 1 为完美分类,0 为完全失败。

MCC (马修斯相关系数)

对于不平衡分类,mcc 是非常好的度量,即使类的大小相差很大,也可以安全地使用

其范围在 1 和 1 之间,其中 1 分表示完美预测,0 分表示随机预测,1 分表示预测分数和真实标签值之间完全不一致。

ROC-AUC 为二元分类

ROC 指标的性质和上面列出的简化形式将在下一节详细介绍。

尽管很难一下子快速理解上述公式。让我们先在 NumPy 中实现它们。 y_true 会是一个带有二进制真标签的 numpy 数组, y_score 也是带有二进制标签的 numpy 数组,但是预测的

现在让我们实现一些基本的模型,例如逻辑回归(我将使用 PyTorch 中实现的一个)并在不平衡数据集上训练它(正类占少数)。将对来自 MNIST 数据集的 0 和 6 位数字进行训练(0 是负类,6 是正类,即“1”,与负类相比,仅由 30%的正类样本组成)。

我故意选择了导致不完美训练结果的参数,得到了 77%的准确率

77%的单一值是一个相当模糊的结果,所以让我们对计算的分数运行 show_metrics 函数

现在,我们有了更多关于获得的性能的信息。真正例子的数量相当少,因为它们是少数,模型很难识别它们。假阳性的数量等于 0,这意味着如果单个负类不是正类,则该模型不将其分类为正类,因此我们可以说,如果该模型预测属于正类,则它是完全确定的。真阴性的数量很大,因此假阴性的数量也很大,这意味着大多数看到的样本被预测为阴性样本。原因是我们的数据集主要由阴性样本组成,评估阶段相应的阳性/阴性标签比例也是如此。召回我们的预测是 0.02,这意味着模型选择阳性类别非常糟糕(大多数真正的阳性类别没有被正确预测)。另一方面,精度等于 1.0,这意味着被分类为阳性的所有样本确实是阳性的。 F1 指标很低,这意味着模型对阳性和阴性样本的区分很差, mcc 也是如此。

ROC-AUC

ROC 代表接收器工作特性,最初被设计为区分噪声和非噪声的度量。ROC 是通过绘制真阳性率(在 y 轴上)对假阳性率(在 x 轴上)的分数来创建的。ROC-AUC 度量显示由 ROC 曲线获得的曲线下面积。我们如何准确地获得 ROC 曲线?让我们假设二进制分类模型输出范围为[0,1]的真实值,其可以被解释为样本为正的概率。我们可以说,如果模型的输出大于 0.5,那么样本就是正的,但是 0.5 并不是类阈值的唯一选择。例如,如果大部分样本是负的,那么模型将倾向于预测比正样本更多的负样本,并且输出将偏向左侧。因此,我们可以将阈值向左移动,并获得少数类预测的正确估计值(假设如果模型输出得分≥ 0.4,则已经令人印象深刻,并且样本可以被视为阳性)。ROC 曲线是通过将阈值从 0 移动到 1 来获得的,并且用于获取 TPR 和 FPR,考虑到所有预测≥阈值被视为阳性样本。阈值通常等于预测中的唯一值。让我们用 numpy 手工实现这个简单的算法

结果曲线为

来自上述实施例的 ROC-AUC 度量是 0.979。ROC-AUC 度量可以在[0,1]的范围内变化,其中 1 分表示分类器具有完美的预测能力并且从不出错,0.5 分完全是随机猜测,低于 0.5 分意味着如果我们颠倒结果(将 0 的预测变为 1,反之亦然),我们实际上得到比现在更好的模型。在输出 0 和 1 标签而不是连续分数的二元分类器的情况下,我们不能移动我们的阈值,因此在图上只有一个点(单对获得的值 TFR 和 FPR)。在这种情况下,ROC-AUC 可以直接计算为两个三角形的面积,这样的公式我们在上一节已经看到过。

结论

作为结论,我建议只有在职业完全平衡的情况下才使用准确度,否则使用 F1 和 MCC。通过精确度和召回率来查看正面和负面评估比率也是有用的。

机器学习中的性能度量

原文:https://towardsdatascience.com/metrics-ml-2563f9e47faa?source=collection_archive---------9-----------------------

在本文中,我提供了几个用于评估模拟某些行为的模型性能的指标的简要概述。这些指标将模拟输出与一些实际情况进行比较。

分布比较

詹森-香农散度

詹森-香农散度(JSD)测量两个分布(即地面真实和模拟)之间的相似性。描述这一指标的另一种方式是两个分布之间的差异量。
JSD 是库勒贝克-利布勒散度的对称化和平滑版本,或 D(p,q) ,它描述了概率分布 pq 之间的散度。需要注意的一点是 D 并不是对称的,因为 D(p,q) 不等于 D(q,p)

假设我们有一个样本 x ,我们想要测量 x 出现在真实分布 p 而不是模拟分布 q 中的可能性。似然比(LR)将对此进行测量:

LR>1 表示 p(x) 更有可能,LR < 1 表示 q(x) 更有可能。现在,为了获得数据集 x,的总体比率,我们取每个样本的乘积:

我们采用对数比来改进计算:

其中 log(LR) 值> 0 表示 p(x) 更好地拟合,而值> 0 表示 q(x) 更好地拟合数据。使用该值,我们可以更好地量化一个模型优于另一个模型的程度,方法是回答如果从 p(x)进行采样,每个样本平均会在多大程度上表明 p(x)q(x) 更好地描述数据。这也叫它的预测能力。

如果假设 N 接近无穷大,那么我们得到期望值:

JSD 通过以下方式对此进行对称和平滑处理:

科尔莫戈罗夫-斯米尔诺夫试验

Kolmogorov-Smirnov 检验(KS 检验)是两个连续的一维概率分布相等的非参数检验,其检验统计量量化了两个分布之间的距离。如果 KS 统计值高或 p 值低,则支持两个分布相同的假设。

第一步是对样本中的测量值进行排序,然后计算累积概率 S(x) ,即所有测量值小于 x 的分数。在这种情况下,S(x1 )= 0,S(xn ) = 1。给定累积分布函数 S(x) 的 Kolmogorov–Smirnov 统计量是两个累积概率之间的最大绝对差值:

如果样本来自 S(x) ,那么当 n 趋于无穷大时 Dn 收敛到 0。计算出统计数据后,您可以参考适当的 Kolmogorov-Smirnov 表,并根据您的样本大小找到临界值,其中如果 D 大于临界值,则零假设被拒绝。

非参数检验与参数检验

非参数测试不假设数据集遵循特定的分布,而参数测试需要某些假设。然而,非参数检验要求数据集中的不同组具有相同的可变性/分散性。参数测试在以下方面表现良好:

  • 当分布是偏斜的和非正态的。
  • 当每个组的传播不同时。
  • 当您需要更强大的统计能力时。

当您想要评估中位数超过平均值时,非参数检验表现良好。参数检验可以检测出由于尾部变化而引起的偏态分布均值的变化。非参数分析关注的是相对不受尾部变化影响的中位数。

一对一的比较

均方根误差

均方根误差(RMSE)是模拟预测值与地面真实值之间差异的测量值。主要用于回归,标量值。计算 RMSE 的第一步是通过实际值减去预测值来计算残差。
下一步是对这些残差的平方求平均值,然后对该平均值求平方根。平方然后平方根的目的是去除负值。

决定系数(R 平方)

决定系数(R 平方)量化了与没有独立变量的基线模型相比,模拟的好坏程度,基线模型总是预测 y 的期望值。主要用于回归,即预测值与实际值之间的一对一比较。

R-squared 是介于 0 和 1 之间的任何值,其中越接近 1 的值表示模型所占的方差比例越大。对于不包含常数项的方程,有可能得到负的$R $表示拟合实际上比仅拟合一条水平线更差。如果该值低于 0,则不能解释为相关的平方,这很好地表明应该将常数项添加到模型中。

应用中的一个例子是,让我们假设 R 平方=93%,那么地面真实数据中 93%的变化可以通过我们的模拟来解释。

序列比较

动态时间扭曲

动态时间弯曲(DTW) [2]是时间序列分析中两个时间序列相似程度的度量。DTW 寻找两个序列之间的最佳对齐,而不是查看每个时间序列上两点之间的欧几里德距离。
我们首先计算时间序列 1 (A)和时间序列 2 (B)之间的距离矩阵。该矩阵在纵轴上为一个时间序列绘制了点,在横轴上为另一个时间序列绘制了点。然后,我们基于这些值和选定的距离度量 D(通常为欧几里德距离)来计算距离:

Distance matrrix( from Regina J. Meszlnyi, Petra Hermann, Krisztian Buza, Viktor G and Zoltn Vidnynszky 2017) [1]

在计算出距离矩阵之后,你通过回溯和贪婪搜索来构造弯曲路径,或者弯曲路径 W=(w_1,w_2,…,w_n)以最小化距离。使用扭曲路径,您可以通过对路径内的距离求和来获得距离值:

距离越小,时间序列越相似。

秩偏重叠

分级偏置重叠(RBO) [3]通过计算不同深度的重叠来测量可能包含或不包含相同项目的无限分级列表之间的相似性,通过使用几何级数(一种收敛级数)来界定这些深度的平均重叠。RBO 在 0 到 1 的范围内,其中 0 表示最大不相交,1 表示相同。
可以证明几何级数的不定和是有限的,由下式给出:

几何级数是一组项,其中连续项之间有一个恒定的比率。一个例子是:

几何级数的使用允许我们明确地模拟用户的行为,因为几何级数中的值随着深度的增加而减少,允许你模拟从给定的排名位置 ii +1 的可能性。

参考

[1]里贾纳·梅兹莱尼、佩特拉·赫尔曼、克里斯提安·布扎、维克托·加尔和 Zoltan·维德尼扬斯基。使用动态时间弯曲的静息态 fMRI 功能连接性分析。神经科学前沿,11(2 月):1{17,2017。

[2]斯坦萨尔瓦多和陈欣健。FastDTW:在线性时间和空间中实现精确的动态时间扭曲。智能数据分析,11:561{580,2007。

[3]威廉·韦伯、阿利斯泰尔·莫阿特和贾斯汀·佐贝尔。不确定排序的相似性度量。美国计算机学会信息系统汇刊,28(4):1{38,2010。

评估您的语义细分模型的指标

原文:https://towardsdatascience.com/metrics-to-evaluate-your-semantic-segmentation-model-6bcb99639aa2?source=collection_archive---------0-----------------------

您如何知道您的细分模型表现良好?在这里找到答案。

Illustration of IoU and Dice Coefficient.

放射分割。我最喜欢的任务。我会做一个深度学习模型,让它变得更好,更训练有素…但是等等。我如何知道我的模型表现良好?换句话说,语义分割最常见的度量标准是什么?这里有一个关于基本指标的简明指南,你需要知道这些指标以确保你的模型表现良好。我还在下面包含了 Keras 实现。

如果你想了解更多关于深度学习的语义分割,请查看 George Seif 的这篇中型文章。

[## 基于深度学习的语义分割

指南和代码

towardsdatascience.com](/semantic-segmentation-with-deep-learning-a-guide-and-code-e52fc8958823)

内容:

  1. 像素精度
  2. 并集上的交集(雅克卡指数)
  3. 骰子系数(F1 分数)
  4. 结论、注释、总结

1.像素精度

像素精度也许是概念上最容易理解的。它是图像中被正确分类的像素的百分比。

虽然很容易理解,但这绝不是最好的指标。

乍一看,可能很难看出这个指标的问题。为了揭示这个指标的真实情况,这里有一个场景:假设您通过您的分割模型运行了下面的图像()。右边的图像是基础事实,或注释(模型应该分割的内容)。在这种情况下,我们的模型试图在卫星图像中分割船只。

Image from Vlad Shmyhlo in article: Image Segmentation: Kaggle experience (Part 1 of 2) in TDS

你看你的分割准确率 95% 。太棒了。让我们看看你的分段是什么样子的!

不完全是你所希望的,嗯。我们的计算有问题吗?没有。完全正确。只是有一节课是原图的 95%。因此,如果模型将所有像素分类为该类别,则 95%的像素被准确分类,而另外 5%的像素没有被准确分类。因此,尽管你的准确率高达 95%,但你的模型返回的是一个完全无用的预测。这是为了说明高像素精度并不总是意味着优越的分割能力。

这个问题叫做阶层失衡。当我们的类极度不平衡时,意味着一个类或一些类在图像中占主导地位,而其他一些类只占图像的一小部分。不幸的是,类不平衡在许多真实世界的数据集中普遍存在,因此它不能被忽略。因此,我向您展示了两个更好地处理这个问题的替代指标:

2.并集交(IoU,Jaccard 索引)

交集-并集(IoU),也称为 Jaccard 指数,是语义分割中最常用的指标之一,这是有充分理由的。欠条是一个非常简单的指标,非常有效。

IoU calculation visualized. Source: Wikipedia

在阅读下面的陈述之前,先看看左边的图片。简单地说, IoU 是预测分割和实际情况之间的重叠面积除以预测分割和实际情况之间的联合面积,如左图所示。该指标的范围为 0–1(0–100%),0 表示没有重叠,1 表示完全重叠的分段。

对于二值化(两类)或多类分割,图像的平均 IoU 是通过取每一类的 IoU 并对它们进行平均来计算的。(在代码中实现略有不同)。

现在,让我们通过使用与第 1 节相同的场景来尝试理解为什么这个度量比像素精度更好。为了简单起见,让我们假设所有的船(彩色盒子)都属于同一个类。

但是等等,在我们的语境中重叠和联合到底是什么?上图展示了一幅非常清晰的画面,但我发现在预测与事实的背景下有点难以理解,因为它们不一定像上图描绘的那样重叠。让我们一起来看看预测的分割和地面的真相。

Predicted segmentation (Left) Ground truth annotation (Right)

先算船欠条吧。我们假设图像的总面积是 100 (100 像素)。首先,让我们考虑一下船只的重叠部分。我们可以假设我们将预测的分割(左)直接移动到地面真实(右)的上方,并查看是否有任何船像素重叠。因为没有像素被模型分类为船只,所以有 0 个重叠的船只像素。

Union 包括从两幅图像中被分类为船只的所有像素,减去重叠/交叉。在这种情况下,有 5 个像素(这是一个任意的数字选择)被分类为船只总数。减去为 0 的重叠/相交,得到 5 作为并集的面积。经过计算,我们得知欠条仅仅是 47.5%!参见下面的计算。

详细计算如下:

船只:重叠面积= 0,联合面积= (5+0)-0 =5

重叠面积/联合面积= 0%

现在对于黑色背景,我们做同样的事情。

背景:重叠面积= 95,联合面积=(95+100)-95 = 100

重叠面积/联合面积=95%

均值 IoU =(船只+背景)/2 =(0%+95%)/2 =47.5%

哇哦。这比我们计算的 95%的像素精度低了很多。很明显,47.5 是我们细分成功的更好的指标,或者更恰当地说,是缺乏成功的指标。

下面是我在自己的项目中使用的一个很好的 Keras 实现:

from keras import backend as Kdef iou_coef(y_true, y_pred, smooth=1):
  intersection = K.sum(K.abs(y_true * y_pred), axis=[1,2,3])
  union = K.sum(y_true,[1,2,3])+K.sum(y_pred,[1,2,3])-intersection
  iou = K.mean((intersection + smooth) / (union + smooth), axis=0)
  return iou

y_true 和 y_pred 都是mxrxcxn其中 m 是图像的数量,r 是行数,c 是列数,n 是类数。

3.骰子系数(F1 分数)

简单地说,骰子系数是 2 *重叠面积除以两幅图像中的总像素数。(参见第 2 节中对联合区域的解释)。

Illustration of Dice Coefficient. 2xOverlap/Total number of pixels

因此,对于 1 和 2 中使用的相同场景,我们将执行以下计算:

两幅图像的总像素数合计= 200

船舶:重叠面积= 0

*(2 重叠面积)/(总像素组合)= 0/200 = 0

背景:重叠面积= 95

(2 重叠面积)/(总像素组合)= 952/200 = 0.95

骰子=(船只+背景)/2 =(0%+95%)/2 =47.5%

在这种情况下,我们得到了与借据相同的值,但情况不会总是这样。

骰子系数与借据非常相似。它们是正相关的,这意味着如果一个人说模型 A 在分割图像方面比模型 B 好,那么另一个人也会这么说。像欠条一样,它们的范围都是从 0 到 1,1 表示预测和真实之间的最大相似度。

为了更好的理解它们之间的区别,我推荐阅读下面的栈交换答案:

[## f1/骰子得分与借据

begingroup $你的思路是正确的。有几件事很快就发生了。根据这两个指标的定义,我们…

stats.stackexchange.com](https://stats.stackexchange.com/a/276144)

下面是 Dice 系数的一个实现,输入条件与第 2 节中指定的相同:

def dice_coef(y_true, y_pred, smooth=1):
  intersection = K.sum(y_true * y_pred, axis=[1,2,3])
  union = K.sum(y_true, axis=[1,2,3]) + K.sum(y_pred, axis=[1,2,3])
  dice = K.mean((2\. * intersection + smooth)/(union + smooth), axis=0)
  return dice

4.结论、注释、总结

总之,语义分割最常用的指标是 IoU 和 Dice 系数。我已经在 Keras 中包含了代码实现,并将在下一篇文章中更深入地解释它们。

正如你们中的一些人可能已经注意到的,我故意排除了关于真阳性、真阴性、假阳性和假阴性的讨论和解释。虽然很重要,但我认为它们混淆了我在本文中试图强调的对这些指标的清晰概念理解。

我希望这篇文章能让你对每个指标有更深入的了解,这样你就可以在实现过程中或阅读文献时有更深的理解。

用简单的英语理解回归模型的基本度量

原文:https://towardsdatascience.com/metrics-to-understand-regression-models-in-plain-english-part-1-c902b2f4156f?source=collection_archive---------7-----------------------

ML 概念解释

数据科学访谈期望对这些指标有直观的理解

Photo by Volkan Olmez on Unsplash

很容易记住这样的规则,比如 RMSE 和梅的值应该低,R 的平方和其他味道的 R 的平方值应该高。但是,数据科学面试对候选人的期望并不高。他们不会问你 R 平方值是 0.6 还是 0.7 更好。人们可能会问这样的问题,比如您将使用哪些指标来评估回归模型,以及为什么要使用那个指标?此外,如果你的角色就像公司里的分析翻译,你可能需要用简单的方式向企业解释复杂的概念。所以,这篇文章是关于直观地解释它们,而不是提供代码。很容易从 sci-kit 学习文档或 Stackoverflow 中找到关于如何计算这些分数的代码块。

让我们考虑一个由 11 个观测值(n)创建的简单线性回归模型,这是一个非常少的例子,但应该足以证明这一点。这些观察值用橙色点表示,线性回归方程或最佳拟合线用绿色表示。

Fig 1. Simple Linear Regression Example

从图 1 我们可以说,线性回归模型并不完美。直线上有四个点,其他点在任一方向上远离直线。橙色点是 y 的实际值,而蓝色箭头在回归线上的起点是预测ŷ.

平均绝对误差

如果我们考虑所有的橙色点,并计算预测与实际相差多少,我们会得到该点的误差值。这就是 y 和ŷ.的区别为了计算 MAE,

  1. 取 11 个可用观测值中每一个的 y 和ŷ的绝对差值:⎮yᵢ-ŷᵢ⎮其中 i ϵ [1,数据集中的总点数]。
  2. 对每个绝对差值求和,得到总误差:σ⎮yᵢ-ŷᵢ⎮
  3. 将总和除以观察总数,得到平均误差值:σ⎮yᵢ-ŷᵢ⎮/n

梅=σ⎮yᵢ-ŷᵢ⎮/n

每次观察都会产生误差值,误差值可以是任意整数。它可以是零、负数或正数。如果我们简单地将这些误差值相加,得出总误差,我们可能会得到一个不能给出真实性能的数字。

很少的正值会导致误差增大,而很少的负值会导致误差减小,最终导致统计数据不能指示模型性能。所以,我们只考虑实际值和预测值的差异。

注:还有 平均偏差误差 是将所有误差值相加,不取绝对值。我个人没用过,所以我在跳绳。

均方误差

如何计算 MSE?

  1. 取 11 个可用观测值中 y 和ŷ的差值:yᵢ-ŷᵢ
  2. 平方每个差值:(yᵢ-ŷᵢ)
  3. 平方和值:σ(yᵢ-ŷᵢ)其中 i ϵ [1,数据集中的总点数]
  4. 除以观察总数:σ(yᵢ-ŷᵢ)/n

MSE =σ(yᵢ-ŷᵢ)/n

这四个步骤应该会给出该模型的 MSE。但是,我们为什么要消除差异呢?

假设你有两个基于 1000 个例子创建的模型。对于这两个模型,您计算了 MAE,发现完全相同。但是模型之间有一个很明显的差异。一个模型的每个观测值都有一个微小的误差值,而另一个模型有一个极端的误差情况,误差值要么非常高,要么非常低。现在哪款比较好?

如果你是房地产经纪人,想提供房子的估价,你可能希望你的估价有一点偏差,而不是非常准确或不准确。在这种情况下,惩罚较大幅度误差的模型将有助于我们选择合适的模型。我们可以通过计算 MSE 来实现。

通过对实际值和预测值之间的差值求平方,我们能够只考虑负的误差值并惩罚更高的误差值。假设有两个回归模型,误差值分别为-1,- 2,3,2(模型 A)和 1,-5,1.5,0.5(模型 B)。这两种模型的 MAE 都是 2。但是,MSE 将是 3.5 和 7.125。因为模型 B 有一个很大的误差(-5),它受到 MSE 的严重影响。

另一种解释 MSE 的方法是,误差值的方差(误差分布有多广)!

均方根误差

这基本上是 MSE 的平方根。继续使用上面的相同例子,3.5 和 7.125 MSE 将是 1.87 和 2.67 RMSE。唯一的区别是,RMSE 将与目标变量有相同的单位,而 MSE 有平方单位。因为 MSE 是误差值的方差,所以 RMSE 是误差的标准差。

均方根对数误差

在参加 Kaggle 比赛之前,我没有用过这个。当实际值和预测值的观测值都很大时,与其他较小的观测值相比,这对观测值的误差会很大。例如,你可能会遇到一个房地产数据集,其中有很好的组合,包括昂贵的豪宅、普通的房子和超便宜的快要散架的房子,比如这些房子。如果一个模型预测价值 100,000 美元的小公寓为 50,000 美元,那么它就差了很多,但如果同一模型预测豪宅的价格为 900,000 美元,而不是 850,000 美元,我们可以认为它很接近。相同的错误值$50k 在相同的数据集中既巨大又微不足道。因此,在这种情况下,为了避免造成误差的实际值和预测值之间相对较大的差异,我们使用 RMSLE

对数通常是用小得多的数量表示大数的一种方便方法。检查这个,10000 的对数值是 4,而 5000 的对数值是 3.6989。当回归模型的 y 和ŷ值变化很大时,较高的数量级会显著增加 RMSE、MSE 和 MAE 的误差。

计算 RMSLE :

  1. 获取预测+ 1 和实际+ 1 的对数值,并取二者之差,或者获取预测+ 1 和实际+ 1 之比的对数值:(log(yᵢ+ 1)—log(ŷᵢ+1))或 log((yᵢ+1)/(ŷᵢ+1))(注: 对于预测和实际,如果预测或实际为零,则加+1 以避免未定义的错误)
  2. 将每个值平方并求和:σ(log(yᵢ+1)-log(ŷᵢ+1))
  3. 取和的平方根得到 rmsle:√σ(log(yᵢ+1)-log(ŷᵢ+1))

它也可以被认为是考虑预测和实际之间的比例而不是差异的指标。如果 pred₁= 5 万美元,actual₁= 8 万美元,pred₂= 50 万美元,actual₂= 80 万美元。那么在这两种情况下,log ((P+1)/ (A+1))将是相同的。

这里我不打算用房地产的例子来简化计算。假设我们在同一个数据集上有两个不同回归模型的 y(实际值)和 Y^(Predicted 值,如下所示:

型号 A:

10,14,18,120,140,1,2

Y^: 十,十三,十八,一百,一百三十,一,二

型号 B:

Y : 10,14,18,120,140,1,2

Y^: 6,9,7,119,130,1.1,1

对于 y 和 Y^的这些值,模型 a 的 RMSE 是 10.217,而 RMSLE 是 0.0938,而模型 b 的 RMSE 是 7.25,而 RMSLE 是 0.4737。如果我们只拿 RMSE 来说,B 型可能看起来更好。但是,如果你只是浏览一下结果,很明显模型 A 表现得更好,RMSE 得分更高只是因为一个预测偏离了很多,这也是更高的量级。

考虑 RMSLE 的另一种方式是,当人们想要惩罚低估多于高估时,RMSLE 工作得很好。例如,模型 A 预测价值 80 万美元的房子为 60 万美元,而模型 B 预测同样的房价为 100 万美元。尽管这两个预测相差 20 万美元,但模型 A 的 RMSLE 值(0.2876)高于模型 B(0.2231),而 RMSE 值保持不变。

决定系数或 R 的平方

我们有 RMSE、MSE、MAE 等指标。通过比较几个模型或同一模型的几个不同版本的这些值,我们可以选择最佳模型。但是,在我们完成一个模型之后呢?所选择的模型适合数据吗?有改进的余地吗?我们可以用 R 平方值来回答这个问题。

回到房地产的例子,假设你有 1,000 行数据,这些数据具有不同的特征来决定一个地区的房价。你只有 10 秒钟来评估该地区一栋新房子的价值。最好的选择是什么?就拿那 1000 套房子的均价报出来,作为新房的估价。尽管这不是一个很好的预测,但很有可能它肯定比随机猜测的错误要少。这被称为基线模型或均值模型或与 x 轴平行的无关系线。因此,我们可以将其与我们更好的线性回归模型进行比较,看看这个模型有多好。这是 R 平方值给我们的。

因此,如果我们取用平均线计算的误差平方和(SSEM)用回归线计算的误差平方和(SSER)之间的差,我们就可以得到由于使用回归线而不是平均线而减少的误差量。该差值除以平均线的误差平方和给出了与平均线相比回归线减少的误差比例,基本上是 R 平方值!

R****=(SSEM—SSER)/(SSEM)= 1—(SSER/SSEM)

该值始终在[0,1]之间。它也被解释为由模型解释的方差,因为 SSE 基本上是误差的方差,并且通过使用回归模型而不是均值模型,方差减少了一定的量,并且这种误差的减少是由模型“解释”或由模型解释的。

在下一篇文章中,我将谈论 调整的 R 平方,预测的 R 平方,残差图,变量的 P 值,回归系数。 敬请期待!

注:

您可能会看到一些等式的分母是 n-p,而不是 n,其中 p 是用于创建模型的独立变量的数量。根据我在在线零售行业的工作经验,这并不重要,因为通常 n >>> p,因此 n-p 倾向于 n。但是在遇到小样本的经典统计中,n 与 n-p 会产生显著的差异。但是为什么在经典统计中要用 n-p 或者自由度呢?这可能是一个潜在的博客帖子!

我喜欢用简单的方式解释复杂的概念。如果你有任何问题或者只是想联系,你可以在 Linkedin 上找到我或者发电子邮件到 manojraj.dobbali@gmail.com 找我。

另外,我推荐阅读 neptune.ai 的另一篇博文:https://Neptune . ai/blog/performance-metrics-in-machine-learning-complete-guide

使用深度学习的微生物分类

原文:https://towardsdatascience.com/microbe-classification-using-deep-learning-e84312046334?source=collection_archive---------16-----------------------

利用 fast.ai 文库对 12 种微生物进行分类

Photo by Pietro De Grandi on Unsplash

问题:使用光学显微镜进行微生物鉴定非常耗时,并且需要训练有素的微生物学家。深度学习算法能否成功区分 12 种不同类别的微生物?

数据:迪巴斯(http://misztal.edu.pl/software/databases/dibas/)

整个数据集包含 33 个不同属和物种的 660 幅图像。作为一个概念验证项目,我今天将只研究 12 个不同的类别:鲍曼不动杆菌、以色列放线菌、脆弱拟杆菌、白色念珠菌、产气荚膜梭菌、粪肠球菌、大肠杆菌、单核细胞增生李斯特菌、淋病奈瑟菌、变形杆菌。、铜绿假单胞菌、金黄色葡萄球菌

我选择了这 12 种微生物,因为它们是数据集中更具医学相关性的微生物。

每个类别包括大约 20 幅图像,分辨率为 2048 x 1532 像素。样品进行革兰氏染色,并在油浸下使用 100 倍物镜进行评价。图像是用装有 SC30 照相机的 Olympus CX31 显微镜拍摄的。

设置:

  • Jupyter 笔记本带 fasti.ai v1 库
  • ResNet-50 型号
  • 英伟达 RTX 2060 6GB

结果:准确率 99.6%

Photo by Ian Matyssik on Unsplash

第一部分:图像处理

我决定把图片分成更小的块,因为 2048 x 1532 的原始尺寸相当大。例如,看看下面的原始图像。微生物在物理上很小,如果我们将其大小调整为 224 x 224,边缘和集群等重要特征可能会丢失。

Original 2048 x 1532 image

我编写了一个自定义函数来将图像分解成 224 x 224 的块。

def process_image(im):
    imarray = np.array(im)
    im_h, im_w = imarray.shape[:2]
    block_h, block_w = 224, 224

    for row in np.arange(im_h - block_h +1, step = block_h):
        for col in np.arange(im_w - block_w +1, step = block_w):
            im1 = imarray[row:row+block_h, col:col+block_w, :]
            im1 = Image.fromarray(im1)
            global i
            global path
            im1.save(path + "\img" + f"{i}" + ".png")
            i+=1
    print("completed")

我运行了每个类的代码,根据需要更改了文件夹名称。

from PIL import Image
import numpy as np
import os
i=0
path = r"C:\bacteria\**Staphylococcus.aureus**\edited"
for file in os.listdir(r"C:\bacteria\**Staphylococcus.aureus**\raw"):
    filename = r"C:\bacteria\**Staphylococcus.aureus**\raw" + f"\{file}"
    im = Image.open(filename)
    process_image(im)

最终产品看起来像这样:

224 x 224 image blocks

对于大多数原始图像,微生物均匀地分布在载玻片上。但是,某些类别(如念珠菌)的载玻片不太均匀,包含空白区域。为了解决这个问题,我仔细查看了最终产品,并手动删除了空白幻灯片。

我们现在已经为模型构建和培训做好了准备。

Photo by Robert Katzki on Unsplash

第二部分:培训

首先,我们导入必要的模块。

from fastai.tabular import *
from fastai.vision import *
path = r"C:\bacteria\data"

我的文件夹结构:父文件夹(C:\细菌\数据)→带有类名的子文件夹(C:\细菌\数据\念珠菌)→图片

np.random.seed(42)
data = ImageDataBunch.from_folder(path, valid_pct=0.2,
        ds_tfms=get_transforms(), size=224, num_workers=4, bs=32).normalize(imagenet_stats)data.classes, data.c, len(data.train_ds), len(data.valid_ds)

我们有 12 个不同的类,有 10,234 个训练图像和 2,558 个验证图像。

learn = cnn_learner(data, models.resnet50, metrics=accuracy).to_fp16()

Fasti.ai 支持混合精度训练,添加一样简单。to_fp16() 构建学习器时。对于那些使用英伟达 RTX 显卡的人来说,混合精度大大加快了训练速度,并将内存需求减半。Eric 有一篇关于这方面的优秀文章,你可以在这里阅读:https://towardsdatascience . com/RTX-2060-vs-gtx-1080 ti-in-deep-learning-GPU-benchmarks-priest-RTX-vs-most-贵-gtx-card-cd47cd9931d2

learn.fit_one_cycle(4)

即使没有训练最高层,结果看起来也相当不错。我们现在将解冻顶层,并找到一个合适的学习率。

learn.unfreeze()
learn.lr_find()
learn.recorder.plot()

我以降低的学习率进一步训练了整个模型。

learn.fit_one_cycle(10, max_lr=slice(7e-5, 9e-4))

在 10 个周期结束时,我们达到了 99.6%的准确率。没有明显的过度拟合,因为训练和验证损失是相似的。让我们来看看混淆矩阵。

interp = ClassificationInterpretation.from_learner(learn)
interp.plot_confusion_matrix(figsize=(10,10), dpi=100)

主要错误似乎来自变形杆菌对假单胞菌和大肠杆菌对变形杆菌。这是可以理解的,因为所有 3 个物种都是革兰氏阴性杆菌,它们染色并且在光学显微镜下看起来相似。让我们来看看损失最大的图片。

interp.plot_top_losses(6, figsize=(15,15))

总之,在这个相当困难的任务上,我们达到了令人钦佩的 99.6%的准确率。事实上,我对这种表现感到相当惊讶,因为很难在视觉上区分某些类。比如你能分辨出葡萄球菌吗?金黄色葡萄球菌和肠球菌。fecalis 分开?

也许这个模型正在学习我还没有认识到的特征,需要进一步的工作来提高这个模型的“可解释性”。

感谢阅读!

Photo by Ethan Dow on Unsplash

微服务架构:简要概述以及为什么您应该在下一个项目中使用它

原文:https://towardsdatascience.com/microservice-architecture-a-brief-overview-and-why-you-should-use-it-in-your-next-project-a17b6e19adfd?source=collection_archive---------3-----------------------

微服务架构的背景以及微服务架构相对于整体架构的优势

背景

在软件开发的早期,编程语言的门槛很高,只有拥有科学和数学博士学位的人才能使用这些编程语言。1964 年,通用编程语言 BASIC 被开发出来。它降低了门槛,使得所有系的非博士学生也可以编写程序。随着 20 世纪 60 年代计算应用的快速增长,软件变得庞大而复杂。计算机科学家试图用古老而成熟的技术来解决软件系统的复杂性:分而治之

大卫·帕纳斯 于 1972 年发表了他的开创性论文“ 关于将系统分解成模块 ”的标准,其中引入了 M 余度和 I 信息隐藏的概念。同样, 埃德格·w·迪杰斯特拉 在他 1974 年发表的论文【论科学思想的作用】中引入了分离的概念。Parnas、Dijkstra 和其他人的工作导致了 20 世纪 70 年代模块化软件开发的兴起,其原则是将一个大型复杂的软件系统分解成通过内部接口通信的松散耦合、高度内聚的模块。简单来说,“松散耦合意味着模块之间的依赖性应该非常低,而“高度内聚”意味着一个模块应该专注于单个或相似的功能。随着 20 世纪 90 年代互联网和 Web 的兴起,软件系统在商业应用中变得广泛,变得更加复杂和庞大。尽管模块化被用来降低软件应用程序的复杂性,但由于软件子系统的软模块边界容易被跨越和误用,它通常没有帮助。另一种软件架构模式在 20 世纪 90 年代非常流行,用于开发商业应用程序:分层架构。通常,业务 Web 应用程序分为几个层:表示层、业务层和数据库层。****

在 1997 年, Brian FooteJoseph Yoder已经分析了许多商业应用并发表了“ 大泥球 ”的论文。该文件指出

Big Ball of Mud

大多数商业应用程序都存在以下问题:

  • 无节制的增长
  • 太多的责任
  • 缺乏适当的架构
  • 意大利面条代码
  • 让它工作。掩盖在地毯下的问题

在 21 世纪后期,由于移动互联网(Wifi、智能手机)和更快网络的兴起,软件行业发生了寒武纪大爆发。此外,软件开始吞噬世界,除了传统的软件/技术公司,几乎所有类型的公司都开始开发或使用软件,如银行、保险、餐馆、酒店、音乐、驾驶等。许多新公司,如脸书推特优步网飞Spotify 带来了创新的想法、积极的战略、快速的方法,这导致了他们的应用程序呈指数级增长。突然,组织和软件工程师发现单一架构不能处理现代、快节奏或网络规模软件开发的挑战。

单片架构的局限性

  • ****应用程序扩展:随着成功的 Web 规模公司享受指数级增长,他们的软件也需要支持高水平的可扩展性。有时,只有软件的一部分(例如 CPU 密集型或 I/O 密集型)需要单独扩展和处理(用多语言编程实现)。单片软件作为一个单元工作,使用单一的编程语言开发,使用单一的技术堆栈。要实现水平扩展,整个应用程序都需要进行扩展。相应地,由于单片软件只支持一种编程语言,所以不可能用其他编程语言或其他技术栈来实现其中的一个模块。
  • ****开发速度:为了缩短上市时间,现在每个公司都希望有快速的特性开发。在一个大型的、复杂的、通常有几百万行的单片应用程序中,添加新功能是非常缓慢的,因为这样一个单片应用程序给开发人员带来了巨大的认知负担。巨型单片应用程序的模块是紧密耦合的,这给添加新功能带来了额外的挑战。因此,在一个单一的应用程序中添加新功能通常很慢,而且非常昂贵。
  • ****开发扩展:公司通常希望通过雇佣更多的开发人员来并行开发,以获得竞争优势或抓住唾手可得的果实。开发人员不能在一个巨大的、整体的、紧密耦合的代码基础上自主工作,并且经常需要额外的同步,以防止彼此的工作发生冲突。增加更多的开发人员并不会产生更多的功能,有时甚至会产生更少的功能。同样,由于理解整个整体代码库的认知负荷很高,新员工或应届毕业生通常需要很长时间来编写第一行高效的代码。2008 年,我在柏林的一家电信公司面试,那里的技术经理带着自豪的微笑告诉我,他们有数百万行 C++代码库,新开发人员只能在 3-6 个月后才能编写出高效的代码。
  • ****发布周期:大型整体式应用程序的发布周期通常太长,通常需要 6 个月到 2/3 年,再加上因其规模而导致的几个月到几年的延迟。在现代,大的发布周期通常使公司处于竞争劣势,因为在这个大的发布间隙内,新公司可以来抢走它的市场。
  • ****模块化:在单片架构中,模块之间的边界往往是内部接口。一旦应用程序变大,模块之间的界限就开始瓦解。因此,通常在整体架构中的模块是紧密耦合的,而不是“松散耦合,高度内聚”的双重格言。如果我们将软件开发与社会相比较,那么整体模块化就像道德的、宗教的规则,我们知道这些规则不能确保社会的法律和秩序。
  • ****现代化:由于许多因素(例如,利用现代硬件、浏览器、网络带宽、技术堆栈或吸引优秀的开发人员),现有的成功应用程序需要现代化。整体应用程序的现代化通常既昂贵又耗时,因为它需要在不中断服务的情况下对整个应用程序进行大规模现代化。

微服务架构

在 2010 年代,其他颠覆性技术的出现对软件开发格局产生了重大影响: 云计算 ,容器化(DockerKubernetes), DevOps 。同样,一些高效、轻量级的新编程语言如 GolangRustSwift 出现,而一些高效、易用、轻量级的编程语言如 、JavaScriptPython 成为主流。软件开发模式也发生了变化。 瀑布 软件开发模式几乎被抛弃,取而代之的是快速、迭代、增量的软件开发方法论: 敏捷软件开发 。计算机硬件也发生了巨大的变化,更便宜、更快的主内存和多核 CPU 的崛起。数据存储领域也发生了变化。新的数据库技术如【NoSQL】NewSQL涌现并成为主流

为了应对现代软件应用的复杂性,利用云计算、容器化、DevOps、现代编程语言的优势,满足现代软件开发(快速开发、横向扩展)的需要,2012 年出现了一种新的软件架构风格: 微服务架构 。那么,到底什么是微服务架构呢?微服务架构有许多定义,以下是我的定义:

微服务架构是关于将软件系统分解成可独立部署的自治单元,这些自治单元通过轻量级、语言不可知的方式进行通信,它们一起实现业务目标。

****微服务架构也使用与分而治之相同的技术来处理软件系统的复杂性,如模块化单片架构,其中复杂的软件系统被分成许多微服务,这些微服务通过外部接口进行通信。模块化整体架构和微服务架构的主要区别在于,每个微服务都可以独立部署,而所有模块通常作为一个整体部署(部署整体)。如中所示

Monolith vs Modular Monolith vs Microservices

上图,单片应用程序是一个单元(紧密耦合),就像一个立方体。模块化应用程序就像一个立方体,可以包含小模块,但是模块不能分开,只能一起部署。微服务就像一个由乐高积木制成的乐高立方体,积木松散耦合,易于分离,所有的乐高积木一起构成了这个立方体。

优势

  • ****应用扩展:首先,微服务通常是无状态的,如果使用 DockerKubernetes 或其他基础设施仔细部署,微服务可以在几秒钟内提供水平扩展。事实上,正是这种高度的横向扩展使得像网飞、Spotify、优步、谷歌这样的公司从整体架构转向微服务架构。其次,如果一个微服务是 CPU 密集型的,那么它可以用 CPU 优化编程语言(C/C++,Rust)来实现,而其他微服务可以用解释语言(Java,PHP)来实现。
  • ****开发速度:微服务的规模往往相当小(几百到几千)。由于规模的原因,在微服务中添加新功能通常会更快。
  • ****开发扩展:微服务是自治的,可以独立开发。因此,开发人员的可扩展性更好,因为不同的开发人员/团队可以自主地在不同的微服务上工作,而不会碰到彼此的代码。因此,公司可以很容易地雇佣更多的开发人员,并扩大开发规模。类似地,由于其规模,微服务给新雇佣的开发人员或应届毕业生带来的认知负荷很小,新开发人员通常可以在几天内编写出高效的代码,而不是几周或几个月。
  • ****发布周期:在我看来,微服务架构最酷的特点就是每个微服务都是可独立部署的。因此,微服务应用中的软件发布周期要短得多,而且有了 CI/CD ,每天都可以发布几个版本。
  • ****模块化:在微服务架构中,微服务之间的边界是很难跨越的外部接口,即物理(网络)。因此,正确设计的微服务通常提供“松散耦合、高度内聚”的模块化。如果把软件开发比作社会,那么微服务调制就像严格的国家、国际法律,带有警察/惩罚。众所周知,通常严格的国家和国际法律可以确保社会的法律和秩序。
  • ****现代化:由于微服务是松散耦合的,并且只能通过语言无关的方式相互通信,因此单个微服务可以很容易地被新的微服务所取代,新的微服务可以使用新的编程语言和技术堆栈来开发,而不会影响整个系统。微服务架构的现代化是渐进的,而不是大爆炸。

不足之处

像生活中的任何事情一样,微服务架构也有它的价格和相当多的缺点。它绝不是一把能够解决软件应用程序或组织中所有问题的金锤。毫不奇怪,同为微服务专家的 萨姆·纽曼 在他广受好评的书《 构建微服务 》中,提出了一个场景,即在没有适当的架构/考虑的情况下从整体架构转向微服务架构,从而导致噩梦般的状况。还有一些类似“ 再见微服务:从 100 个问题儿童到 1 个超级巨星 ”或“2018 年微服务疯狂之死 ”的博文,作者们在其中讨论了他们从 Monolith 转向微服务架构所遭受的大量磨难和痛苦。以下是微服务架构的一些缺点:

  • 设计复杂性:整体架构通常为业务应用提供“一刀切”的解决方案。例如,如果一个 Web 应用程序有几千行代码或几百万行代码,那么 Monolithic Architecture 会给出相同的解决方案(Enterprise Java 或 Ruby on Rails 或 PHP)。但在微服务架构中,根据应用和用例,可能有许多解决方案。因此,如果针对错误的应用规模/类型采用了错误的解决方案(例如,给成年人穿上小孩的衣服,反之亦然),那么微服务架构注定会失败。此外,设计微服务具有挑战性,因为与单片相比,移动部件要多得多。通常情况下,设计糟糕的微服务比整体服务更糟糕。
  • ****分布式系统复杂性:微服务通常是分布式系统,我们知道,与单机系统相比,分布式系统非常复杂,面临着一系列独特的挑战。对分布式系统的详细讨论超出了本文的范围,但是感兴趣的读者可以阅读“ 分布式系统的谬误 ”。简而言之,分布式微服务会出现以下问题: 整体系统延迟更高,网络故障或单个节点故障会使整个系统宕机,操作复杂性更高
  • ****运营复杂度:复杂的单片应用一旦分解成许多微服务,复杂度往往会从源代码转移到运营上。日志记录、监控等简单操作变得更加复杂,因为需要处理的不是一个系统,而是更多的系统。通常,现有的测井/监测工具不适合微服务,需要新的测井、监测工具。跟踪在微服务中也非常重要,它可以衡量单个微服务对服务请求的性能/延迟。与单片应用相比,微服务中的完整系统测试同样非常复杂。同样,服务发现和弹性也需要新的基础设施。正如著名的计算机科学家和微服务大师 Martin Fowler 指出的那样,由于操作的复杂性,微服务架构的初始开发速度比整体架构慢。

Source: https://martinfowler.com/bliki/MicroservicePremium.html

  • 安全:软件系统中的安全通常是房间里的大象,每个人都可以看到,但没有人愿意谈论。保护一个软件应用程序是困难的,保护数百个通常是分布式系统的微服务是一个相当大的挑战。
  • 数据共享和数据一致性:理想情况下,每个微服务都应该有自己的数据存储。缺点是微服务需要在它们之间共享数据来实现业务目标。数据一致性是另一个挑战,因为不推荐使用传统的两阶段锁定来支持分布式数据库中的一致性,原因有二:它不可伸缩,并且许多现代数据存储不支持它。大多数现代的 NoSQL 数据库 只提供 最终一致性 需要仔细设计。
  • 通信复杂性:正如已经讨论过的,微服务通过流程/网络边界实现了严格的模块化和开发自主性。缺点是服务只能通过物理网络进行通信,这最终会导致更高的网络延迟。微服务之间的通信方式有很多种:同步通信使用 RESTgRPC异步通信使用 消息队列消息代理 其中各有利弊。同步通信更容易实现,但会导致所谓的分布式整体。通过消息传递的异步通信提供了更多的灵活性,但代价是更高的实现复杂度。在微服务架构中,根据应用选择正确的通信机制也具有挑战性。****

结论

的确,设计和实现微服务架构具有挑战性,与单片软件架构相比,需要范式转变。同样,微服务架构也绝不是能够解决各种应用复杂性问题的灵丹妙药。另一方面,也绝不是炒作带动发展或者 货邪教 。考虑到一切,我相信微服务架构对于现代软件开发来说是一个非常有用和方便的工具。 对于通常开发复杂软件的大型企业来说,微服务架构是解决复杂性并在市场中具有竞争力的唯一途径 。对于中小型企业来说,微服务架构也应该用于可持续的软件开发,这可以带来长期的好处。值得注意的是,微服务架构的早期采用者( Spotify、网飞、Linkedin、亚马逊、谷歌)凭借其微服务架构取得了超越竞争对手的显著竞争优势。

如果你觉得这很有帮助,请分享到你最喜欢的论坛上( Twitter,脸书,LinkedIn )。高度赞赏评论和建设性的批评。感谢阅读!

如果你对微服务架构感兴趣,也可以看看我下面的文章:

**** [## 有效的微服务:10 个最佳实践

正确实施微服务架构的 10 个技巧

towardsdatascience.com](/effective-microservices-10-best-practices-c6e4ba0c6ee2) [## 微服务架构及其 10 个最重要的设计模式

微服务架构、每个微服务的数据库、事件源、CQRS、Saga、BFF、API 网关、扼杀者、电路…

towardsdatascience.com](/microservice-architecture-and-its-10-most-important-design-patterns-824952d7fa41) [## 透过宣传看:模块化整体软件架构真的死了吗?

现代软件开发中模块化整体软件体系结构的真实性检验

medium.com](https://medium.com/@md.kamaruzzaman/looking-beyond-the-hype-is-modular-monolithic-software-architecture-really-dead-e386191610f8)****

微软人工智能简介—第 1 部分

原文:https://towardsdatascience.com/microsoft-introduction-to-ai-part-1-879e31d6492a?source=collection_archive---------10-----------------------

Image used under licence from Getty Images.

机器学习

你是不是有点像我,想要学习人工智能,尽管对其中涉及的数学感到有点害怕?也许你认为这些概念太难理解,你会力不从心。我最近完成了微软人工智能入门课程,并写了课程笔记来帮助我记住我所学的知识。我试着用一种简单的方式来写这些笔记,让它们更容易阅读。我最近成为一名阿姨,买了几本与技术和空间相关的儿童书籍,我真的很喜欢作者和插画师如何设法简化复杂的主题。因此,我受到启发,以类似的方式处理这些话题,简化它们,使它们更容易理解。

  • 如果你想了解课程笔记和其他与技术和产品设计相关的笔记背后的一些背景信息,你可以在这里找到更多。 *

摘要

微软人工智能入门课程提供了人工智能的概述,并探索了为人工智能提供基础的机器学习原则。从这门课程中,你可以发现将人工智能功能集成到应用程序中的基本技术。学习如何使用软件来处理、分析和提取自然语言的含义。了解软件如何处理图像和视频,以人类的方式理解世界。了解如何构建智能机器人,实现人类和人工智能系统之间的对话。

Image created by the author. Microsoft Introduction to Artificial Intelligence Course

这个课程需要大约 1 个月的时间来完成,所以我写的 1 篇中型文章包含了一周的内容。这意味着你只需要大约 18 分钟就可以读完一周的内容,这是一种快速的学习方式。没有证书的课程是免费的,但是,如果你想要一个证书作为完成的证明,是要收费的。有一些与本课程相关的实验,我不会包括在笔记中,因为我认为最好的学习方法是实际做实验。然而,如果你想了解人工智能背后的基本理论,并想以一种可能比其他资源简单得多的方式来学习它,这些笔记是有用的。我试着用通俗易懂的语言来写它,并加入了视觉效果来帮助说明这些想法。如果你没有时间学习这门课程,这些笔记会很有用,这是快速浏览核心概念的一种方法。或者,如果你像我一样学过这门课,你可以用这些笔记来记住你学到的东西。

指导老师:

graeme Malcolm——微软学习体验的高级内容开发人员。

摘要

本课程分为四个部分,包括:

1。机器学习(*这篇中型文章将只关注这一部分)

了解关于人工智能和机器学习的基础知识。

2.语言与交流

学习如何使用软件来处理、分析和提取自然语言的含义。

3.计算机视觉

了解如何使用软件处理图像和视频,以我们的方式理解世界。

4.以对话为平台

了解如何构建智能机器人,实现人类和人工智能系统之间的对话交流。

Image created by the author.

机器学习

本课程的“机器学习”部分将涉及以下主题:

什么是人工智能?

什么是机器学习?

监督

无人监督的

回归

分类

使聚集

Illustration by Michael Korfhage for HR Magazine SHRM.

什么是人工智能?

人工智能(AI)是一种让人们通过与智能软件合作来完成更多工作的方式。你可以把它想象成让科技更人性化。人工智能是一种可以从现代世界中可用的大量数据中学习的技术。从这些数据中学习,它可以理解我们人类的语言,并以类似的方式做出反应。是技术可以像我们人类一样看待和解释这个世界。

Illustration by Justin Middendorp.

什么是机器学习?

机器学习(ML)为人工智能提供了基础。

那是什么呢?

机器学习使计算机能够学习并根据数据做出预测或决策,而无需显式编程。顾名思义,这是一种利用数据训练软件模型的技术。模型是现实世界过程的数学表示。模型从训练案例(训练情况或示例)中学习,然后我们可以使用训练好的模型来预测新的数据案例。这一点的关键是要理解,从根本上说,计算机非常擅长一件事,那就是执行计算。为了让计算机根据数据做出智能预测,我们只需要一种方法来训练它进行正确的计算。

我们从包含历史记录的数据集开始,我们通常称之为“案例”或“观察”。每个观察值包括数字特征。数字特征基本上是我们正在处理的项目的特征,每个特征都有一个数字值。

Illustration by Vecteezy.

我们称数字特征为 x。

总的来说,我们也有一些我们试图预测的值,我们称之为 Y。我们使用我们的训练案例来训练机器学习模型,以便它可以根据 X 中的特征计算 Y 的值。因此,用非常简单的术语来说,我们正在创建一个对一组特征“X”进行操作的函数,以产生预测“Y”。如果这令人困惑,请不要担心,在下一节我们开始应用真实世界的例子时,这将更有意义。

现在一般来说,有两大类机器学习,它们被称为监督的非监督的

监督

在监督学习场景中,我们从包括我们想要预测的变量的已知值的观察开始。我们称这些为“标签”。由于我们从包含我们试图预测的标签的数据开始,我们可以仅使用一些数据来训练模型,并保留其余的数据,这些数据可用于评估模型的性能。然后,我们使用机器学习算法来训练一个模型,使特征符合已知标签。

因为我们从已知的标签值开始,所以我们可以通过将函数预测的值与我们已知的实际标签值进行比较来验证模型。然后,当我们对模型运行良好感到高兴时,我们可以将它用于标签未知的新观察,并生成新的预测值。

In this example we know the value of both X (numeric feature) and Y (variable we want to predict). Since we know X and Y we can use this algorithm to train our model. Once the model has been trained and we are happy that it works well we can use this model to calculate Y for when X is unknown. Illustration by Vecteezy.

无人监督的

无监督学习不同于监督学习,因为这一次我们在训练数据集中没有已知的标签值。我们通过寻找观察值之间的相似性来训练模型。在模型被训练之后,每个新的观察值被分配到具有最相似特征的观察值的聚类中。

In this example the value Y is unknown and so the way we train the model is through finding similarities between the observations. The observations are categorised in clusters that have similar characteristics. Once we train the model based on these clusters we can use it to predict the value of Y by assigning a new observation to a cluster. Illustration by Vecteezy.

回归

好吧,让我们从一种叫做“回归”的监督学习技术开始。假设我们有一些健康试验参与者的历史数据。我们有一些信息,比如他们做了什么运动,消耗了多少卡路里,还有很多关于他们的数据和信息。在这种情况下,我们可以使用机器学习来预测任何新参与者在进行一些练习时可能会燃烧多少卡路里。当我们需要预测一个数值时,比如一笔钱或一个温度或卡路里数,我们使用的是一种叫做回归的监督学习技术。

例如,让我们假设 Rosy 是我们健康研究的参与者。这里她正在做一些举重练习。当 Rosy 第一次报名参加这项研究时,我们收集了一些关于她的数据。我们还在她锻炼时收集数据,并使用健身监视器智能手表捕捉数据。

现在我们要做的是使用 Rosy 运动中的特征来模拟燃烧的卡路里。这些数字特征(X)是她的年龄、体重、心率、持续时间等等。在这种情况下,我们知道所有的功能,我们知道 231 卡路里的标签值(Y)。因此,我们需要一个算法来学习操作 Rosy 所有锻炼功能的函数,以给我们一个 231 的结果。

Illustration by Vecteezy.

当然,只有一个人的样本不可能给我们一个通用的函数。因此,我们需要做的是从许多不同的参与者那里收集相同类型的数据,并根据这个更大的数据集来训练我们的模型。

Illustration by Vecteezy.

在我们对模型进行了训练,并且我们有了一个可以用来计算我们的标签 Y 的通用函数之后,我们就可以在这样的图表上绘制针对 X 值的特定特征计算的 Y 值。

Image created by the author.

然后我们可以插入 X 的任何新值来预测未知的 y。

Image created by the author.

现在,因为我们从包含我们试图预测的标签的数据开始,所以我们可以仅使用一些数据来训练模型,并保留其余的数据来评估模型性能。

然后,我们可以使用模型来预测评估数据的 (F(X)) ,并将预测或评分标签与我们知道为真的实际标签进行比较。预测水平和实际水平之间的差异就是我们所说的“残差”。残差可以告诉我们模型中的误差水平。

Image created by the author.

现在有几种方法可以测量模型中的误差,其中包括均方根误差(RMSE)平均绝对误差(MAE) 。这两个都是模型中误差的绝对度量。

Image created by the author.

例如,RMSE 值为 5 意味着测试误差的标准偏差为 5 卡路里。当然,根据你的预测,绝对值会有很大的不同。5 卡路里的误差似乎表明这是一个相当好的模型。但是,如果我们预测一次锻炼需要多长时间,误差为 5 个小时,这将是一个非常糟糕的模型。

因此,您可能希望使用相对度量来评估模型,以 0 到 1 之间的相对值来表示更一般的错误级别。相对绝对误差(RAE)相对平方误差(RSE) 产生一个度量,其中误差越接近 0,模型越好。

Image created by the author.

决定系数(CoD(R2)) 我们有时称之为 R 的平方是另一个相对度量,但这一次更接近 1 的值表示非常适合该模型。

Image created by the author.

分类

我们已经了解了如何训练回归模型来预测数值。现在是时候看看另一种叫做分类的监督学习了。分类是一种技术,我们可以用它来预测某样东西属于哪个类或类别。最简单的变体是二进制分类(1 和 0),我们预测一个实体是否属于两个类别中的一个。它通常用于确定实体的真假。

例如,假设我们在我们的健康诊所里有很多病人,我们收集了一些个人信息。我们运行一些测试,我们可以确定哪些病人是糖尿病患者,哪些不是。我们可以学习一个可以应用于这些患者特征的函数,对于糖尿病患者给出结果 1,对于非糖尿病患者给出结果 0。

Illustration by Vecteezy.

更一般地说,二元分类器是一个可以应用于特征 X 以产生 Y 值 1 或 0 的函数。

Illustration by Vecteezy.

这个函数实际上不会计算 1 或 0 的绝对值,它会计算 1 和 0 之间的值。我们将使用一个阈值(图中的虚线)来决定结果应该计为 1 还是 0。

The threshold is represented as the dotted line. Image created by the author.

当您使用模型来预测值时,根据结果值落在阈值线的哪一侧,结果值被分类为 1 或 0。

Image created by the author.

因为分类是一种监督学习技术,所以我们保留了一些测试数据,以使用已知标签来验证模型。

Image created by the author.

如果模型预测的测试观察值为 1,而实际的标签值为 1,则被视为真阳性(TP)。

Image created by the author.

类似地,在模型预测为 0 而实际标签为 0 的情况下,这些是真阴性(TN)。

Image created by the author.

现在,阈值的选择决定了如何将预测分配给类别。在某些情况下,预测值可能非常接近阈值,但仍然分类错误。您可以移动阈值来控制预测值的分类方式。在糖尿病模型的情况下,可能有更多的假阳性(FP)更好,但减少假阴性(FN)的数量,以便更多处于糖尿病风险中的人被识别。

Image created by the author.

模型产生的真阳性(TP)、假阳性(FP)、真阴性(TN)和假阴性(FN)的数量对于评估其有效性至关重要。

Image created by the author.

这些的分组通常显示在下面显示的所谓的混淆矩阵中。这为计算分类器的性能度量提供了基础。最简单的衡量标准是准确性,即正确分类的案例数除以案例总数。

Image created by the author.

在这种情况下,有 5 个真阳性(TP)和 4 个真阴性(TN)。还有 2 个假阳性(FP),没有假阴性(FN)。这给了我们总共 11 个预测中的 9 个正确预测,准确率为 0.82%或 82%。

Image created by the author.

这可能看起来是一个非常好的结果,但也许令人惊讶的是,作为一个模型性能的衡量标准,准确性实际上并不那么有用。假设只有 3%的人口患有糖尿病。我可以创建一个模型,简单地总是预测零,它会有 97%的准确性,但它对识别潜在的糖尿病患者完全无用。

一个更有用的度量可能是被分类为阳性的病例中实际上是阳性的比例。这种度量被称为精度。换句话说,在所有被分类为阳性的情况中,哪些是真的而不是假的警报。

Image created by the author.

在这种情况下,有 5 个真阳性,2 个假阳性。因此,我们的精度是 5 / (7),即 0.71,即 71%的阳性病例实际上是糖尿病,29%是假警报。

Image created by the author.

在某些情况下,我们可能需要一个对我们正确识别的阳性案例的比例敏感的指标。我们将这一指标称为召回。召回率的计算方法是将真阳性的数量除以真阳性和假阴性的总和。换句话说,有多少比例的阳性病例被正确识别?

Image created by the author.

在这种情况下,有 5 个真阳性,没有假阴性。所以我们的召回率是 5/5,当然是 1%或 100%。因此,在这种情况下,我们正确地识别了所有糖尿病患者。现在回忆实际上有另一个名字,有时它被称为真阳性率。

Image created by the author.

与实际的阴性数量相比,假阳性的比率是相等的。在这种情况下,我们有 2 个假阳性和 4 个真阴性。所以我们的假阳性率是 2/(6)也就是 0.33。

Image created by the author.

您可能还记得,我们得到的指标是基于 0.3 左右的阈值(蓝色虚线),我们可以像这样绘制该阈值的真阳性率和假阳性率。

Image created by the author.

如果我们将阈值移回 0.5,我们的真实阳性率将变为 4/5 或 0.8。我们的假阳性率是 1/6 或 0.16,我们可以在这里画出来。

Image created by the author.

将阈值进一步移动到 0.7,我们得到的真阳性率为 2/5 或 0.4,假阳性率为 0/6 或 0。

Image created by the author.

如果我们为每一个可能的阈值速率绘制曲线,我们将得到一条曲线,如下图所示。这就是所谓的受试者操作者特征,ROC 图。现在曲线下的面积(AUC) 是该模型预测效果的一个指标。通常,您希望看到一个大的 AUC,曲线尽可能靠近图表的左上角。一个完美的分类器应该从左边一直向上,然后沿着顶部给出 AUC 为 1。现在,你总是可以用一条对角线来比较,这条对角线代表了如果你简单地做一个 50-50 的猜测,这个模型的表现有多好。AUC 是 0.5。所以你只是简单地随机猜测,50%的时间是对的,50%的时间是错的。在这种情况下,我们的模型的 AUC 为 0.9,这意味着我们的模型肯定优于猜测。

The area under the curve (AUC) is an indication of how well the model predicts. Generally, you want to see a large AUC with a curve staying as close as possible to the top left corner of the chart. What is shown in the blue graph is a good example of a model that is outperforming a 50–50 guess. Image created by the author.

使聚集

嗯,我们已经看到了一些监督学习的例子,特别是回归和分类,但是无监督学习怎么样呢?现在,使用无监督学习技术,你没有一个已知的标签来训练模型。但是,您仍然可以使用一种算法来查找数据观察中的相似之处,以便将它们分组到聚类中。

例如,假设我们的健康诊所有一个网站,其中包含文章、医学和健康生活方式出版物的链接。现在我可能想自动将相似的文章分组在一起。

Illustration by Vecteezy.

或者,我想对我们的研究参与者进行细分,我们可以根据相似的特征对他们进行分类。

Illustration by Vecteezy.

有许多方法可以创建聚类模型,我们将研究一种最流行的聚类技术,称为 k 均值聚类

Image created by the author.

现在,理解 k-means 的关键是记住我们的数据由多行数据组成,每一行都有多个特征。现在,如果我们假设每个特征都是一个数值,那么我们可以将它们绘制成坐标。现在我们在二维网格上绘制两个特征。但实际上,多个特征将在 n 维空间中绘制。

然后,我们决定要创建多少个称为 k 的聚类。我们在随机位置绘制 k 个点,这些点代表我们的聚类的中心点。

k points are represented as the stars in the diagram. Image created by the author.

在本例中,k 为 3,因此我们创建了 3 个集群。接下来,我们确定每个点最接近三个质心中的哪一个,并相应地将这些点分配给聚类。

Image created by the author.

然后,我们将每个质心移动到点及其簇的真实中心。

Image created by the author.

然后,我们根据最近的质心重新分配聚类中的点。

Image created by the author.

我们只是重复这个过程,直到我们有很好的分离集群。

Image created by the author.

那么,我所说的完美分离是什么意思呢?嗯,我们需要一组尽可能将数据分开的集群。为了测量这一点,我们可以比较聚类中心之间的平均距离。

Image created by the author.

此外,聚类中的点与其中心之间的平均距离。

Image created by the author.

最大化该比率的集群具有最大的分离。我们还可以使用聚类之间的平均距离与点和聚类质心之间的最大距离的比值。

Image created by the author.

现在,我们可以评估聚类算法结果的另一种方法是使用一种叫做主成分分析(PCA) 的方法。在这种方法中,我们将簇中的点分解成方向。我们将 PCA 分解的前两个部分表示为一个椭圆。

Image created by the author.

第一主成分沿着椭圆的最大方差或长轴的方向,第二主成分沿着椭圆的短轴。与第一个群集完全分离的群集显示为椭圆,椭圆的长轴垂直于第一个群集的椭圆。

Image created by the author.

每第二个集群被合理地很好地分开,但不是完全分开。

Image created by the author.

那么它将具有不完全垂直于第一个椭圆的主轴。如果第二组与第一组分离得很差,那么两个椭圆的长轴将几乎是共线的。

Image created by the author.

所以椭圆可能更像一个圆,因为第二个聚类不太明确。

一锤定音

感谢您阅读这篇文章,这是微软人工智能入门课程的第 1 部分。如果你觉得这很有帮助,请查看我的媒体账户或数据科学的所有 4 个部分。如果你对本文中的一些概念有困难(不要担心,我花了一些时间来理解这些信息),并且你需要更多的信息,那么就免费注册参加微软人工智能入门课程。与这些笔记一起观看课程视频很有帮助。

  • 如果您想了解课程笔记和其他与技术和产品设计相关的笔记背后的一些背景信息,您可以通过这里找到更多信息。 *

有点背景

大家好,我是 Christine:)我是一名产品设计师,已经在数字领域工作了相当一段时间,在许多不同的公司工作过;从大型公司(多达 84,000 名员工),到中型企业,再到仍在扬名立万的小型初创企业。尽管我有很多经验,但我是一名产品设计师,害怕受到邓宁-克鲁格效应的影响,所以我不断尝试教育自己,我总是在寻找更多的光明。我相信,要成为一名伟大的设计师,你需要不断磨练自己的技能,尤其是如果你在不断变化的数字空间中工作。

微软人工智能简介—第 2 部分

原文:https://towardsdatascience.com/microsoft-introduction-to-ai-part-2-f7cfb6a5f1e3?source=collection_archive---------16-----------------------

Image used under licence from Getty Images.

语言和交流

你有没有好奇过,科技究竟是如何阅读、破译、理解我们人类的自然语言的?像 Cortana、Siri、Alexa、Google 这样的 AI 助手是如何帮助我们完成简单的问题和任务的?像谷歌这样的搜索引擎如何检索与我们的查询相关的信息,尤其是当它们是用自然语言表达的时候?这是“微软人工智能导论”课程笔记的第二部分。深入自然语言处理(NLP)的激动人心的世界,了解如何使用软件来处理、分析和提取我们语言的含义。

背景

(如果看过 第一部 )跳过背景信息

对于那些没有看过本系列第 1 部分的人,这里有一些背景信息。我一直想学习人工智能(AI ),尽管对其中涉及的数学感到有点害怕,并认为一些概念可能超出了我的深度。幸运的是,我的好奇心战胜了我的恐惧,所以我开始学习一些与人工智能相关的课程。我最近完成了微软人工智能入门课程,并写了课程笔记来帮助我记住我所学的知识。我试着用一种简单的方式来写这些笔记,让它们更容易阅读。我最近成为一名阿姨,买了几本与技术和空间相关的儿童书籍,非常喜欢作者和插图画家如何设法简化复杂的主题。因此,我受到启发,以类似的方式处理这些主题,简化它们,使它们更容易理解,特别是对那些和我一样最初对人工智能感到恐惧的人。

  • 如果您想了解课程笔记以及其他与技术和产品设计相关的笔记背后的更多信息,您可以在此找到更多信息。 *

摘要

(看过 的跳过摘要第一部 )

微软人工智能入门课程提供了人工智能的概述,并探索了为人工智能提供基础的机器学习原则。从本课程中,你可以发现将人工智能功能集成到应用程序中的基本技术。学习如何使用软件来处理、分析和提取自然语言的含义。了解软件如何处理图像和视频,以人类的方式理解世界。了解如何构建智能机器人,实现人类和人工智能系统之间的对话。

Image created by the author. Microsoft Introduction to Artificial Intelligence Course

这个课程需要大约 1 个月的时间来完成,所以我写的 1 篇中型文章包含了一周的内容。这意味着你只需要大约 29 分钟就可以读完这篇文章,这是一周的内容。那是一种快速的学习方法。没有证书的课程是免费的,但是,如果你想要一个证书作为完成的证明,是要收费的。本课程有相关的实验,我不会在笔记中列出,因为我认为最好的学习方法是实际做实验。然而,如果你想了解人工智能背后的基本理论,并想以一种可能比其他资源简单得多的方式来学习它,这些笔记是有用的。我试着用通俗易懂的语言来写它,并加入了视觉效果来帮助说明这些想法。如果你没有时间学习这门课程,这些笔记会很有用,这是快速浏览核心概念的一种方法。或者,如果你像我一样学过这门课,你可以用这些笔记来记住你学到的东西。

教官:

graeme Malcolm——微软学习体验的高级内容开发人员。

摘要

(看过 的跳过大纲第一部分 )

本课程分为四个部分,包括:

1.机器学习

了解关于人工智能和机器学习的基础知识。

2.语言和交流(*这篇中型文章将只关注这一部分)

学习如何使用软件来处理、分析和提取自然语言的含义。

3.计算机视觉

了解如何使用软件处理图像和视频,以我们的方式理解世界。

4.以对话为平台

了解如何构建智能机器人,实现人类和人工智能系统之间的对话交流。

Image created by the author.

语言和交流

课程的“语言和交流”部分将涉及以下主题:

文本处理入门

文本分析简介

字频率

术语频率—逆文档频率

堵塞物

情感分析

自然语言处理入门

文本分析

演讲

翻译

语言理解智能服务

路易斯是什么?

创建 LUIS 应用程序

使用 LUIS 应用程序

改进 LUIS 应用程序

Illustration by Vecteezy.

文本处理入门

文本分析简介

作为人类,我们通过书面和口头语言交流,进化成了聪明的问题解决者。沟通是成功合作的关键。所以人工智能需要包括与数字实体自然交流的能力。软件需要能够理解文本,从我们人类使用的语言中提取语义甚至情感。我们还需要能够与人工智能代理交谈,并让他们做出适当的回应,即使在我们参与对话时也是如此。因此,在接下来的章节中,我们将看看如何处理文本和语音,以使人工智能能够进行语言和交流。

Illustration by Vecteezy.

字频率

好吧,让我们来试验一下这个想法:一个单词或术语在正文中出现得越频繁,这个单词在语义上就越重要。换句话说,一个单词的出现频率可能会告诉我们一些关于文章意思的信息。所以在下面的例子中,我们友好的机器人最近一直在温习他的莎士比亚,他想理解《罗密欧与朱丽叶》中的这句话。现在,我们可以开始做一些频率分析,只需简单地统计文本中每个单词的出现次数。注意下图中我忽略了标点和大小写。如果有任何非字母字符,比如数字,我也会忽略它们。

Illustration by Vecteezy.

我们可以在下面的柱状图中看到这些词频。实际上,我们可能可以做的是将更频繁出现的单词移到图表的开头,并按照频率降序显示它们,作为一个帕累托图

Image created by the author.

现在请注意,最常用的词之一是“a ”,我们也有像“that”、“as”和其他常用词,这些词对于从文本中提取语义并不十分有用。现在我们把这些叫做停用词。如果我们去掉了停用词,我们就能更清楚地了解文章的内容,如下图所示。

Image created by the author.

出现频率最高的词是‘名字’,这确实是朱丽叶在剧中这一部分所说的。

让我们用 Python 中的一些代码来尝试一下。首先,让我们加载一些文本,例如“Moon.txt”。

不要担心,你不需要知道如何用 Python 为这个特定的课程编码。所示的例子只是为了了解我们如何利用技术进行基本的词频分析。虽然对它有一个基本的了解是很有用的。我发现这个 链接是学习一点 Python 的好地方。我相信还有更多更好的资源。

然后,我们可以通过删除数字和标点符号来规范文本,并将文本转换为小写。

然后我们得到单词的频率分布。

你会得到这样的频率分布。

a        4
accept   1
again    1
against  2
ago      1
all      4
and     12
any      1
are      5
around   1
as       2
ask      1

然后我们可以将分布绘制成一个帕累托图,你会得到一个如下图所示的图表。

Image created by the author.

然后我们可以删除停用词,这将基本上从帕累托图中删除所有停用词。

术语频率—逆文档频率

简单的词频可能是查看单个文档的一种相当有效的方式,但是当您有大量文档时,常见的词可能会在多个文档中频繁出现。简单地统计一个单词总共出现的次数可能无法反映它在单个文档中的重要性。因此,为了解决这个问题,我们使用了一种更复杂的衡量单词重要性的方法,这种方法结合了两个指标,即术语频率和逆文档频率

词频

先说词频。这只是一个术语在文档中的相对频率。在下图所示的例子中,我们的机器人一直在继续研究莎士比亚。在这段引文中,“sweet”这个词在总共 14 个单词中出现了一次。

Illustration by Vecteezy.

现在,单词“rose”在本文档中以相同的频率出现。所以它看起来同样重要。

Image created by the author.

在另外两个引语中也有类似的故事。单词“sweet”和单词“prince”在第二个引号中出现了一次。“甜蜜”一词再次出现在第三段引文中,同样的还有“悲伤”。

Image created by the author.

逆文档频率

现在我们来看看逆文档频率。这是术语出现在其中的文档的相对数量的度量。其计算方法为总文档数除以包含该术语的文档数。

Image created by the author.

现在术语“rose”只出现在第一个引用中,所以我们可以计算它在该文档中的相对重要性,如下所示。然而,“sweet”出现在所有三个引号中,将其在单个文档中的相对重要性降低到零。

Image created by the author.

其他引文也是类似的情况。“Prince”和“sorrow”得分较高,因为它们没有在其他文档中出现,因此在它们出现的文档中相对更重要。

Image created by the author.

最后,我们只需将 TF 乘以 IDF,就可以计算出每个术语对它们出现的文档的整体重要性。正如您在下面看到的,单词“sweet”在文档集合中的流行有效地淡化了它在单个文档中的重要性。

Image created by the author.

Image created by the author.

让我们通过代码来尝试一下。首先,我们从标准化 3 个文本块开始,例如第一个示例中的“Moon.txt”、“Gettysburg.txt”和“Cognitive.txt ”,然后查看文档。

然后让我们获得每个文档中前三个单词的 TF-IDF 值。

您应该得到这样的结果:

Top words in document 1
        Word: space, TF-IDF:  0.01193
        Word: go, TF-IDF:  0.01193
        Word: sea, TF-IDF:  0.00894
Top words in document 2
        Word: nation, TF-IDF:  0.01662
        Word: dedicated, TF-IDF:  0.01329
        Word: great, TF-IDF:  0.00997
Top words in document 3
        Word: services, TF-IDF:  0.02134
        Word: microsoft, TF-IDF:  0.01423
        Word: cognitive, TF-IDF:  0.01423

堵塞物

现在,有时候有些词非常相似。这些单词来自同一个词根,我们在文档中使用它们。我们希望确保这些词得到同等对待。现在,我们的文学机器人继续从莎士比亚的戏剧中找到有趣的引文。在下面的例子中,有三个引号包含了词根相同的单词,分别是“sweet”、“sweeting”和稍不常用的“sweeting”。

Illustration by Vecteezy.

词干提取是一种用于识别具有共同词根的单词并将其视为相同单词的技术。

Image created by the author.

一种常见的技术是使用一种叫做波特算法的东西。波特算法根据辅音、元音、常见字母组合和词尾以及其他语法元素的模式,定义了将单词分解为常见词干的规则序列。

现在让我们用代码试一试。首先,我们查看一些文本中未切分单词的频率。本例中的文本是“KennedyInaugural.txt”。

然后,我们使用波特斯特梅尔算法对单词进行词干分析。你应该得到一个帕累托图,显示词干及其频率。

Image created by the author.

情感分析

情感分析是一种技术,我们可以用来分析文本,并试图辨别文本是否表明作者是高兴还是不高兴,或者对某些事情持中立态度。它经常被用来分析推文、网站上的客户评论、电子邮件,基本上是任何我们知道写文本的人当时的感受很重要的信息。情感分析使用机器学习分类算法来生成 0 到 1 之间的情感得分。接近 1 的分数表示积极情绪,而接近 0 的分数表示消极情绪。该模型用带有情感关联的大量文本进行预训练。

Illustration by Vecteezy.

自然语言处理导论

文本分析

自然语言处理(NLP)使人工智能系统能够做的不仅仅是使用词频的统计分析。使用 NLP,我们可以构建能够提取关键短语以确定要点和主题的应用程序。我们可以通过超越文本中积极词汇的存在并检查所说内容的语义来提高情感分析的准确性。

Illustration by Vecteezy.

让我们来看看微软文本分析 API ,看看它是如何从文本中提取语义和情感的。所以文本分析 API 是一个认知服务,你可以在这里了解。为什么不试一试。

我们要做的是使用这个 API 来说明如何比较几个不同的文档,并从中获取一些信息。下面显示了一些 Python 代码,这些代码查看了两个文档中的短语“葛底斯堡地址”(doc2Txt)和“微软认知服务网站”(doc3Txt)。

不要担心,你不需要知道如何用 Python 为这个特定的课程编码。所示的例子只是为了了解我们如何利用技术从文本中提取语义和情感。

所以我们有一些文本和变量,我们会跳过。然后我们将调用这个 API 的 keyPhrases 方法。我们传递包含我们想要分析的文本的主体,然后我们得到一个响应,这个响应是一个文档集合的相邻文档。我们将浏览每个文档,只显示文档 ID,然后显示在该文档中找到的所有关键短语。

所以当我们继续运行时,我们会得到,对于文档 1,这些关键词:新的国家,伟大的内战,人民,自由的新生,伟大的战场..等等。所以我们从那份文件中获得了相当有用的关键词。

Document 1 key phrases:
  new nation
  great civil war
  people
  new birth of freedom
  great battlefield
  great task remaining
  fathers
  final resting place
  measure of devotion
  brave men
  dead
  poor power
  note
  larger sense
  world
  unfinished work
  proposition

然后从文档 2 我们得到:语音开发人员,微软认知服务,视觉识别,一组 API。因此,我们对这些文件的内容有了更全面的了解,而不是仅仅分析单个单词。

Document 2 key phrases:
  speech
  developers
  Microsoft Cognitive Services
  vision recognition
  set of APIs
  application
  services available
  personal computing experiences
  evolving portfolio of machine learning APIs
  enhanced productivity
  emotion
  intelligent features
  video detection
  language understanding
  SDKs
  systems

现在,我们可以用文本分析 API 做的另一件事是我们可以做情感分析。所以我这里有几个简单的例子,比如“哇!“认知服务棒极了”和“我讨厌计算机不理解我”。

这一次我们将调用相同的 API,但是我们调用的是情感方法。同样,我们得到一个文档列表。我们要做的是假设情绪是负面的,除非我们看我们得到的分数,这个分数大于 0.5。这是一个介于零和一之间的分数。因此,如果得分大于 0.5,我们将认为该文档是正面的。否则我们会认为它是负面的。

因此,当我们继续运行时,文档 1 肯定会返回正值,而文档 2 返回负值。

Document: 1 = positive
Document: 2 = negative

演讲

到目前为止,我们专注于解析文本,但是自然语言当然也包括语音。现在,为了处理语音,我们必须认识到有两种模式需要协同工作。首先,有一个声学模型将音频与声音单元或音素相匹配,这些单元或音素定义了特定的单词片段在给定的语言中如何发音。

Illustration by Vecteezy.

然后有一个语言模型提供了一个单词序列的概率分布。因此,在下面这个例子中,听起来好像我们在试图传达一些关于水果、船和家具的信息…

Illustration by Vecteezy.

…信息更有可能是关于对座位的满意度。

Illustration by Vecteezy.

让我们来看一些在人工智能应用中使用语音的真实例子。

同样,不要担心不太了解如何用 Python 编码。下面的例子只是为了让我们了解如何将技术用于语音。

为了使用语音,我们将使用 Bing 语音 API,这也是微软的认知服务之一。我们将使用语音 API 将一些语音转换成文本。请随意试用微软语音转文本 API 。接下来要发生的是,我们要对着电脑的麦克风说话,我们要把语音转换成文本。所以我们下面要做的是使用语音识别库。它有一个叫做识别器的东西,我们将启动它。然后我们用麦克风作为声源,他们只听对着麦克风说的话。

然后我们要把它发送给这个 recognize_bing 方法。因此,我们将去识别 _bing,这将转到 bing 语音 API。我们会传入捕捉到的音频。我们将为语音服务传递密钥,以便它对我们进行身份验证,然后我们应该会得到听到的内容的副本。

如果它因为环境噪音而听不清楚,我们会收到一条消息说声音不清楚。如果出现其他问题,我们会看到其他错误消息。

所以我们会运行这段代码。然后我们对着麦克风说“西班牙的雨主要落在平原上”。回来的是所说内容的抄本。

Say something!
Here's what I heard:
"The rain in Spain stays mainly in the plain."

因此,我们能够发送音频,既可以直接从麦克风发送,也可以作为音频文件发送。所以,如果你有已经录制好的文件,你想把它们转录成文本,你可以这样做。上传音频文件,然后返回的是音频中的文本。

那么反过来呢?如果我真的想把一些现有的文本转换成语音呢?

现在,我们通常对人工智能应用程序做的事情之一是通过对它们说话来与它们互动,然后让它们用语音来回应。那么我们该怎么做呢?同样,我们可以使用相同的 API,但使用不同的方法。首先,我们只是简单地得到我们想要转换成语音的文本。所以我们会输入一些文本,然后把它发送出去。

我们使用一些 XML 来设置。所以我们在这里使用 ElementTree 元素来构建一个 XML 结构。我们将创建一个 XML 文档,其中包含我们想要使用的声音的所有信息。有不同的声音可用,所以我们将指定这个 JessaRUS 作为声音,并在头中指定关于我们想要返回的内容的各种其他信息。我们已经得到了输出格式,我们得到的将是一个 16 位的单声道音频流。现在重要的一点是,我们在轴令牌中解析它,所以我们在轴令牌上得到载体。

然后我们将得到的是包含已合成文本的音频流。我们调用这个合成的方法,我们将得到这个音频流,然后我们可以做一些事情。

因此,我们将取回这些数据,并在播放器中简单地播放,这样当它回来时,您就可以听到它了。

然后我们继续运行它。然后我们需要输入一个短语。

我们取回音频,然后回放。

所以你可以看到这个 API 是如何向 AI 服务提交输入的。您可以与 API 服务对话,并让它理解所说的内容。然后,您可以以文本的形式表达响应,然后以语音的形式回放该响应。你可以试试语音转文本 API 和文本转语音 API ,点击超链接亲自体验一下。

翻译

到目前为止,所有使用文本和语音的例子都假设我们是在用英语工作。但是如果我们需要与说另一种语言的人合作呢?

Illustration by Vecteezy.

让我们来看看微软翻译器 API 。现在对于翻译,实际上有两个认知服务 API,一个用于文本,一个用于语音。我们将把重点放在文本上,但是你可以使用它们中的任何一个来自动翻译许多不同的语言。

让我们来看看,我们首先要找一些我们想要翻译的文本。我们将输入一些文本。然后是 fromLangCode,输入是我们要翻译的语言。对于 languageCode,输入是我们想把代码翻译成什么语言?

我们定义了一些参数,所以这次我们不会传递关于身体的信息。我们实际上是在传递这些参数。参数基本上是我们要翻译的文本,我们要翻译成的语言和我们要翻译的语言。

所以我们跳过这些,然后我们把这个叫做 api.microsofttranslator.com。这是一个 GET 请求,我们将把它传递给这个 URL。我们放弃了这一切。

然后我们会得到翻译,因为这是文本翻译器,它会以文本形式返回。我们继续运行并输入一些文本。

这就是我们想要翻译的文本。那是什么语言?那是英语,所以 EN 是语言的代码。

我们想把它翻译成什么语言?法语很好。

我们得到了法语翻译。

所以我们有了这个翻译 API。我们可以很快提交一些文本,并让它立即翻译成我们选择的另一种语言。这对于把来自不同语言、不同国家的人们聚集在一起并使他们能够交流非常有用。

语言理解智能服务

路易斯是什么?

语言理解智能服务(LUIS)是一种认知服务,您可以使用它来为需要响应人类交流的应用程序实现自然语言处理。现在我们通过话语与路易斯互动,这些话语是需要解释的语言片段。

Illustration by Vecteezy.

从这些话语中,LUIS 识别出最可能的意图,这是输入的预定义目标或动作。在这种情况下,话语被映射到图书飞行意图。

Illustration by Vecteezy.

现在,意图被应用于在话语中识别的实体。在这种情况下,话语包括一个位置实体‘纽约’和一个日期时间实体‘本周末’。

Illustration by Vecteezy.

要开始使用 LUIS,你需要将其配置为 Azure 服务。现在,微软提供了语言理解智能服务,就像 Azure 中的任何其他认知服务一样,所以我们将使用 Azure 门户来完成这项工作。你可以通过这里了解更多关于 LUIS 的信息。

创建 LUIS 应用程序

在这里,我们将展示使用 LUIS portal 创建一个应用程序的快照,该应用程序具有意图和实体以及我们需要的所有东西,以便理解该语言。首先,我们在 Azure 订阅中创建一个 LUIS 资源。在那里,您可以访问 LUIS 应用程序门户,在那里您可以创建 LUIS 应用程序。

Image created by the author.

因此,首先要做的是创建一个新的应用程序,这将要求为此应用程序命名。我们称之为“家庭自动化”,我们将用英语来表达,因为这是这个应用程序将要使用的语言。你可以添加一些描述。然后点击“完成”并创建新应用程序。

Image created by the author.

这是我们的应用,叫做家庭自动化。

Image created by the author.

我们可以直接打开它。你可以看到,我们可以在这个界面中工作、创建和测试我们的应用程序。现在,我们要做的第一件事是考虑应用程序的意图。

Image created by the author.

所以我们要创造一个意图。因此,在用户界面的“意向”选项卡上,我们将单击“创建新意向”。应该会出现一个弹出窗口。我们会给这个意图一个名字。我们正在构建的应用程序的目的是有效地打开和关闭灯,所以我们的意图之一是打开灯。所以我们就叫它‘开灯’吧。

Image created by the author.

然后这就去创造了一个叫做“点亮”的意图。我们已经准备好开始添加话语,这将成为人们尝试和启动这一意图的方式。我们可以放入多个样本,但为了简单起见,我们将在这里放入一个简单的例子,即“开灯”。所以我们在这里有一个“开灯”的表达,这将表示有意开灯。

Image created by the author.

我们要做的是突出“光”这个词。你可以在下图中看到,它把这些小方括号放在它周围,我们可以用它来表示这个东西是一个实体。你也可以去浏览一些预先构建的实体,或者你可以创建一个新的实体。在这里,我们将创建一个名为“光”的新实体。

Image created by the author.

这创造了一个新的实体叫做光。这是一个简单的实体。我们可以创建更复杂的实体,随着你更深入地探索 LUIS,你会发现这些更复杂的实体的用途,但在这种情况下,我们有一个简单的实体,称为“光”。

Image created by the author.

我们可以看到,它现在被强调为我们话语中的一个实体。所以我们创造了这种光的意图,也创造了一种表达方式。我们可以创建多个话语,但在这种情况下,我只创建了一个,并指定这个光是一个实体。

Image created by the author.

我们将回到意图,在这里创建第二个意图。因为如果我们想打开灯,我们很可能也想关掉它。

Image created by the author.

Image created by the author.

我们再一次插入一句话,说明光在这种情况下是一个实体。它已经知道了那个叫做光的实体,所以它被列出来了。我们只需选择它,这就是该实体的另一个实例。

Image created by the author.

所以现在我们有几个非常简单的意图。每个意图都有一个话语告诉我们这个意图就是我们想要做的。我们在那些话语中指定了“光”这个词是这个意图所涉及的实体。所以我们要做的是继续训练这个应用程序,让它知道如何将这些话语应用到这些意图中。

Image created by the author.

一旦它被训练好,我们就可以测试它了。

Image created by the author.

它会在边上弹出一个小测试窗口,我们在这里输入一句话“开灯”。

Image created by the author.

它从那回来,暗示这是为了光的意图。这就是它认为的意图。

Image created by the author.

实际上,我们甚至可以尝试我们没有为话语输入的文本。我们可以试试“开灯”这样的方式。它再次亮着灯,表明它 100%确信这就是我们想要的。尽管这不是我们最初指定的确切表达,但它足够聪明地意识到,它足够接近我们可能的意思。

Image created by the author.

因此,我们现在已经创建了我们的应用程序,并添加了两个意图。我们已经为这些意图创造了话语,识别了实体,并对其进行了测试。我们现在准备出版这本书。

Image created by the author.

因此,如果我们单击此处的“publish”选项卡,我们可以选择将其发布到生产插槽或转移。在这种情况下,我们将把它发布到生产环境中,然后看看我们在资源和密钥方面想做些什么。

Image created by the author.

现在已经有一把钥匙了。当我们创建应用程序时,生成了这个密钥来测试它,所以有一个测试密钥可以使用。现在,如果我们真的要发布到产品中,那么我们可能要做的是使用我们为 LUIS 创建的 Azure 资源中的一个密钥。

Image created by the author.

因此,我们可以添加一个密钥,并为我们的应用程序分配一个密钥。

Image created by the author.

我们现在已经将这个应用程序与一个密钥相关联,这样我们就可以将它投入生产,并为我们希望对服务计费的密钥使用适当的端点。这将允许我们使用生产级别密钥将其投入生产。因此,您可以在这里看到,我得到的是这个端点,客户端应用程序将使用这个端点连接到我们的 LUIS 应用程序,以启动这些意图。

Image created by the author.

使用 LUIS 应用程序

在之前的演示中,我们创建了一个 LUIS 应用程序,并将其作为服务发布。现在让我们看看如何从客户端使用该应用程序。因此,之前我们创建了 LUIS 应用程序,并使用如下所示的选项将其发布到生产插槽。这是我们的客户端应用程序连接到 LUIS 应用程序的端点。

Image created by the author.

Image created by the author.

我们所做的是在客户端代码中复制这个端点。我们已经得到了一些 Python 代码,并刚刚将该端点粘贴到这里。这就是我们的客户端应用程序用来建立 HTTP 连接的端点 URL。在这种情况下,只有这个 Python 脚本,它将连接到我们的 LUIS 应用程序。

那我们要做什么?好了,我们要连接,然后我们将输入一个命令。因此,我们将得到一个输入命令的提示,我们必须键入该命令,然后将该命令发送到 LUIS 应用程序。

这里有一点代码,如果命令中有空格,就会弄乱 URL,所以我们只需用一个小加号替换它们,这样它们就可以正确地编码到 URL 中。那我们就把这些放在一起。这将是我们的请求,然后我们将把它提交给我们的端点并得到响应。响应将以字符串的形式返回,我们只需对其进行解码。它实际上是一个二进制数组,我们将对它进行解码,它将把它作为一个 JSON 文档加载。

然后,在 JSON 文档中,我们将寻找得分最高的意图,并获得该意图。如果灯亮着,我们将显示一个合适的图像。如果灯熄灭,我们将显示另一个合适的图像。如果完全是别的东西,我们将显示另一个图像。这就是基本的逻辑,我们发送命令,我们得到 LUIS 应用程序所说的命令意图,然后我们将做出适当的响应。

所以我们继续运行这段代码。它会要求我们输入一个命令。所以我们将输入我们的一个话语来打开灯。

我们得到的回应是一张灯亮着的照片。

Image created by the author.

我们输入“开灯”,但我们的原话是“开灯”,但词序没有影响。它仍然设法找出这是正确的命令。

让我们再运行一次,并尝试其他方法。让我们命令它关灯。

Image created by the author.

正如您所看到的,它已经显示了适当的响应,显示了灯不亮时的图像。

Image created by the author.

通过这个非常简单的例子,你已经看到了我们可以在哪里构建一个 LUIS 应用程序,指定意图,为这些意图提供一些示例话语,然后训练该应用程序。然后,该应用程序能够响应来自客户端的请求,并发回关于我们认为用户想要的意图的适当信息。应用程序可以基于此做出适当的响应。

改进 LUIS 应用程序

因此,我们已经看到了如何构建 LUIS 应用程序,以及如何使用与实体相关的意图来训练它,并解释话语,以决定哪个意图是想要的。但我们真正想了解的是,这是如何随着时间的推移而发展的。我们如何提高 LUIS 应用程序的性能,以便它能够理解不同的话语并正确地解释它们。让我们来看看所谓的主动学习,这是一种随着时间的推移改善我们服务的方式。因此,我们将使用在之前的演示中创建的相同客户端应用程序。我们试着关灯,关灯后我们得到了适当的回应。让我们去尝试一些不同的东西,比如说“关灯”。

Image created by the author.

Image created by the author.

在这种情况下,LUIS 应用程序无法识别正确的意图。它基本上发回了一个“无”的响应,我们在这里显示了一个大问号,因为“关灯”不是我们训练 LUIS 应用程序时使用的任何话语。这在逻辑上将被解释为开灯或关灯的意图,因此该意图是未知的。实际上没有,我们得到了这样的回答。

Image created by the author.

如果我们回头看看我们的 LUIS 应用程序。在这个 Build 选项卡上,我们可以查看一些端点话语。我们可以在这些话语中看到“关灯”。这是我们刚刚尝试过的,它与零对齐。当它试图识别时,它的得分是 0.29。它只是不能弄清楚它与哪个意图相关,但我们能做的是现在去将它与如下所示的关灯意图对齐。

Image created by the author.

所以它现在与这个意图一致。因此,我们将进入并重新培训该应用程序,现在如果我们进行测试,我们将尝试我们刚刚改变的意图。因此,我们有我们的“熄灭灯”,这返回为关灯。所以它现在把它和关闭它的意图联系起来。因此,我们能够根据从我们的客户端应用程序获得的一些输入来重新训练我们的模型。

Image created by the author.

如果我们只是再次发布它,我们只是将它重新发布到我们的生产插槽中。既然已经重新发布了,我们可以回去再次尝试我们的应用程序。所以我们只要运行我们的代码。这一次,当我们运行“关灯”命令时,我们得到了适当的响应。它现在实际上能够识别出意图是熄灯意图,如下所示。

Image created by the author.

Image created by the author.

一锤定音

感谢您阅读这篇文章,这是微软人工智能入门课程的第 2 部分。如果你觉得这很有帮助,那么请查看我的媒体账户或数据科学 T2 的所有 4 个部分。如果你对本文中的一些概念有困难(不要担心,我花了一些时间来理解这些信息),并且你需要更多的信息,那么就免费报名参加微软人工智能入门课程。与这些笔记一起观看课程视频很有帮助。

  • 如果您想了解课程笔记和其他与技术和产品设计相关的笔记背后的一些背景信息,您可以在这里找到更多信息。 *

有点背景

大家好,我是 Christine:)我是一名产品设计师,已经在数字领域工作了相当长一段时间,并在许多不同的公司工作过;从大型公司(多达 84,000 名员工),到中型企业,再到仍在扬名立万的小型初创企业。尽管我有很多经验,但我是一名产品设计师,害怕受到邓宁-克鲁格效应的影响,所以我不断尝试教育自己,我总是在寻找更多的光明。我相信,要成为一名伟大的设计师,你需要不断磨练自己的技能,尤其是如果你在不断变化的数字空间中工作。

微软人工智能简介—第 3 部分

原文:https://towardsdatascience.com/microsoft-introduction-to-ai-part-3-cb21d7a5e119?source=collection_archive---------17-----------------------

Image used under licence from Getty Images.

计算机视觉

为了让机器像我们一样看待世界,它依赖于计算机视觉。计算机视觉是人工智能的一种形式,计算机可以“看到”世界,分析视觉数据,然后了解环境和情况。你可能没有意识到,但你很可能每天都在使用计算机视觉。我们用它来解锁面部和指纹识别应用程序。我们的家都安装了使用计算机视觉的安全监控系统。自动驾驶汽车和无人机用它来避开障碍物。计算机视觉是人工智能的一个非常有趣的领域,它的未来充满了许多惊人的机会。这是“微软人工智能导论”课程笔记的第三部分。让我们来看看计算机视觉的奇妙世界。让我们学习如何使用软件来处理图像和视频,以我们的方式理解世界。

背景

(如果看过 第一部 第二部 )跳过背景信息

对于那些没有看过这个系列的第 1 部分或第 2 部分的人来说,这里有一些背景信息。我一直想学习人工智能(AI ),尽管对其中涉及的数学感到有点害怕,并认为一些概念可能超出了我的深度。幸运的是,我的好奇心战胜了我的恐惧,所以我开始学习一些与人工智能相关的课程。我最近完成了微软人工智能入门课程,并写了课程笔记来帮助我记住我所学的知识。我试着用一种简单的方式来写这些笔记,让它们更容易阅读。我最近成为一名阿姨,买了几本与技术和空间相关的儿童书籍,非常喜欢作者和插图画家如何设法简化复杂的主题。因此,我受到启发,以类似的方式处理这些主题,简化它们,使它们更容易理解,特别是对那些和我一样最初对人工智能感到恐惧的人。

  • 如果您想了解课程笔记以及其他与技术和产品设计相关的笔记背后的更多信息,您可以在此找到更多信息。 *

摘要

(如果看过 第一部 第二部 )

微软人工智能入门课程提供了人工智能的概述,并探索了为人工智能提供基础的机器学习原则。从这门课程中,你可以发现将人工智能功能集成到应用程序中的基本技术。学习如何使用软件来处理、分析和提取自然语言的含义。了解软件如何处理图像和视频,以人类的方式理解世界。了解如何构建智能机器人,实现人类和人工智能系统之间的对话。

Image created by the author. Microsoft Introduction to Artificial Intelligence Course

这个课程需要大约 1 个月的时间来完成,所以我写的 1 篇中型文章包含了一周的内容。这意味着你只需要花大约半个小时来阅读这篇文章,它是一周的内容。那是一种快速的学习方法。没有证书的课程是免费的,但是,如果你想要一个证书作为完成的证明,是要收费的。本课程有相关的实验,我不会在笔记中列出,因为我认为最好的学习方法是实际做实验。然而,如果你想了解人工智能背后的基本理论,并想以一种可能比其他资源简单得多的方式来学习它,这些笔记是有用的。我试着用通俗易懂的语言来写它,并加入了视觉效果来帮助说明这些想法。如果你没有时间学习这门课程,这些笔记会很有用,这是快速浏览核心概念的一种方法。或者,如果你像我一样学过这门课,你可以用这些笔记来记住你学到的东西。

讲师:

graeme Malcolm——微软学习体验的高级内容开发人员。

摘要

(跳过教学大纲如果你看过 第一部分 第二部分 )

本课程分为四个部分,包括:

1.机器学习

了解关于人工智能和机器学习的基础知识。

2.语言和交流

学习如何使用软件来处理、分析和提取自然语言的含义。

3.计算机视觉(*这篇中型文章将只关注这一部分)

了解如何使用软件处理图像和视频,以我们的方式理解世界。

4.作为平台的对话

了解如何构建智能机器人,实现人类和人工智能系统之间的对话交流。

Image created by the author.

计算机视觉

本课程的“计算机视觉”部分将涉及以下主题:

图像处理入门

图像处理基础

均等

过滤

边缘检测

角点检测

处理图像和视频

图像分类

映象分析

人脸检测和识别

视频基础

视频索引器

视频索引器 API

Illustration by Vecteezy.

图像处理入门

图像处理基础

在我们探索如何处理和分析图像之前,我们需要了解计算机是如何看待图像的。例如,这里我们友好的机器人有一张全家福。

Illustration by Vecteezy.

作为一幅数字图像,这实际上被表示为一组数字,表示 0 到 255 之间的像素强度。因为这是一幅彩色图像,所以它可以表示为一个三维阵列,每个维度对应于图像中的红色、绿色和蓝色色调。

3 rectangles of Red, Green and Blue (RGB). Image created by the author.

具体取决于图像的格式以及您希望如何处理它。例如,我们可以将这个图像转换成灰度。当它转换为灰度时,现在可以用二维数组表示。

Illustration by Vecteezy.

现在有各种各样的库可以在 Python 中处理图像。因此,让我们来看看一些简单的代码来加载,显示和转换图像。

别担心,你不需要知道如何用 Python 为这个特定的课程编码。所示的例子只是为了了解如何使用代码来加载、显示和转换图像。虽然对它有一个基本的了解是很有用的。我发现这个 链接是学习一点 Python 的好地方。我相信还有更多更好的资源。

下面是这段代码执行的描述。因此,我们在这里添加这个 matplotlib 内联小命令,因为我们希望能够在笔记本中显示图像。这就是我们能够与笔记本中的单元格内联的方式。然后我们导入了一些我们想要使用的库。对我们来说真正重要的是 matplotlib.pyplot 库和 PIL 库,它们允许我们处理图像。我们要做的就是使用 curl 从这个 GitHub 库中抓取一张图片并下载下来。然后我们就打开它展示一下。注意,我们把它作为一个 np 数组打开,一个 Numpy 数组。所以让我们继续运行它。

Image created by the author.

所以我们下载了这张图片,这是一张海滩的图片。让我们来看看它的一些数字特性。

首先,那个图像是什么类型的东西?这是一个多维数组。因此,虽然我们把它看作一个图像,但它显然只是用一组值来表示。

数组中的值是什么类型的呢?它们实际上是无符号整数,8 位整数。换句话说就是 0 到 255 之间的值。数组中的数字实际上标识了每个点的像素强度。

让我们来看看图像的形状。我们有一个 433 乘 650 的矩形,实际上我们有它的 3 个维度。433 乘 650 是图像的尺寸。3 代表不同的矩形,因为它是彩色图像。我们有一个红色的,一个绿色的和一个蓝色的。

现在我们能做的是把这个图像转换成灰度,我们可以用上面的代码来完成。一旦我们把它转换成灰色,我们就把它显示成灰度图像,我们来看看它的形状。让我们继续运行它。

Image created by the author.

这次仍然是 433 乘 650,但是,现在只有一个矩形。这是因为我们现在用灰度显示图像。我们不需要红绿蓝(RGB)图层。因此,我们能够通过将它转换成灰度级来使它成为单通道图像。通常,当您进行某种图像分析时,这是一种简化过程的好方法,方法是去掉多个通道,专注于一个灰度通道。

均等

因为一幅图像实际上是一个数值数组,这些数值的分布可以告诉你一些关于图像包含的颜色或阴影范围或其中的物体的信息。您可以将这些绘制成直方图,以查看值的分布。您还可以使用累积分布函数(CDF)来查看像素值是如何累积的。y 轴上的每个点显示 x 轴上的所有值的频率,包括 x 轴上的值。

Illustration by Vecteezy.

对于图像处理来说,像素值相对均匀的分布通常是好的。不均匀的分布可能表示图像中存在需要均衡的极端对比度。因此,您可以标准化图像,以均衡像素分布。完美均衡图像的 CDF 将显示一条直的对角线。

Illustration by Vecteezy.

让我们看看使用 Python 规范化图像的例子。在 Jupyter notebook 中,我们要做的第一件事是为像素强度中所有不同的可能值创建一个包含 256 个面元的直方图。我们将创建一个直方图,这样我们就可以看到这些值的分布情况,我们可以用下面的代码来实现。

当我们运行这段代码时,我们会看到直方图形式的这些值的分布。直方图显示了图像中不同灰度的分布。

Image created by the author.

我们可以做的另一件事是,我们可以使用这个累积分布函数(CDF)。这基本上显示了到目前为止所有值的分布。

我们只要继续运行它。我们会得到下图。

Image created by the author.

在完美的标准化图像中,CDF 将是完美的直对角线。如你所见,它的末端有一些曲线,我们有一个相当不均匀的值分布。为了简化处理过程,我们可能要做的是对其进行均衡。此刻的不均匀可能表明图像中的对比度存在一些问题,因此我们希望平衡对比度。为此我们有下面这个函数。

所以让我们继续运行它。

Image created by the author.

正如我们所见,均衡后的图像色调更加均匀。我们还可以使用下面的代码查看直方图和 CDF 图。

让我们继续运行它。

Histogram. Image created by the author.

Cumulative Distribution Function (CDF). Image created by the author.

对于直方图,我们仍然可以看到一些峰值,但我们可以看到中间的峰值更加平稳,因此值的分布更加均匀。我们的 CDF 或多或少有一条对角线。因此,我们当然已经平衡了直方图中的值,这可能会使我们更容易使用这些值来尝试和提取一些特征。

过滤

有时,您需要处理的图像可能包含噪声。这通常被称为盐和胡椒或分散。这使得难以检测图像中的特征,因为噪声模糊了细节。您可以通过应用滤镜来消除图像中的噪声。例如,高斯滤波器的工作原理是定义图像的一部分,并根据周围像素的加权平均值确定中心像素的亮度值。较粗的像素比较远的像素具有更大的权重。因此平均值被分配给中心像素,然后移动补片。重复该过程,直到处理完整个图像。

Image created by the author.

高斯滤波器通常会产生模糊效果。这是因为它平均了像素强度,即使在图像的边缘或角落有对比阴影的区域也是如此。

Image created by the author.

因此,作为替代方案,中值滤波器的工作方式与高斯滤波器相同,只是它将中值应用于中心像素。这种方法可以更好地去除细节图像中的小区域噪声,因为它倾向于保持图像相同区域中的像素值相似。这与它们离对比区域有多近无关。

Image created by the author.

所以让我们用代码来尝试一下。我们可以给图像添加一些噪声。所以这段代码基本上会使用一种高斯模糊产生一些随机噪声。

我们可能要应用一个过滤器,以便连接,澄清和清除一些噪音。我们可能采用的一种方法是应用高斯滤波器。当我们在图像上移动蒙版时,这基本上是对像素进行平均。因此,在这种情况下,我们将创建一个大小为 10 个像素的遮罩,我们将运行该遮罩,这就是下面的代码所执行的操作。

我们可能希望采用比高斯滤波器不那么引人注目的东西,并应用类似中值滤波器的东西,我们不是取平均值,而是取中值。这可能有助于清理图像和消除所有斑点。我们可以通过下面的代码来实现。

边缘检测

准备好图像后,您可以使用各种技术从中提取特征。例如,您可以使用边缘检测算法来寻找颜色或强度的对比边缘。边缘检测算法对于指示图像中的形状或对象的边界非常有用。例如, Sobel 边缘检测算法的工作原理是将图像上的一种操作与之前看到的高斯和中值滤波器相结合。但是,这一次我们应用的矩阵是一个两阶段蒙版函数,它应用于图像中的像素强度值,以根据强度的变化计算梯度值。应用此遮罩来查找每个像素的水平渐变。姑且称之为 Gx 吧。

Image created by the author.

然后应用这个掩模来检测垂直梯度,我们称之为 Gy。

Image created by the author.

然后,我们将为每个像素计算的 x 和 y 梯度值的平方相加。我们用平方根来确定每个像素的梯度值,然后计算这些值的反正切来确定已经检测到的边缘的角度。

Image created by the author.

这是一些 Python 代码。这里我们创建了一个名为 edge_sobel 的函数,它穿过图像。我们所做的是,首先我们将图像转换成灰度。Sobel 边缘检测仅适用于灰度图像和一维图像,因此我们将它转换为灰度图像以防万一。然后,我们将采取我们的水平通过,并获得水平边缘。然后我们将垂直通过。所以记住有两个通道,边的 X 和 Y。然后,我们在这里应用斜边函数,基本上是将它们的平方相加,然后求平方根,得到不同边缘的实际幅度。然后我们将在这里应用这个函数来归一化它。然后我们返回,并在我们的图像中显示这些边缘。当你运行该代码时,它会遍历图像,并通过应用特定的 Sobel 算法来检测相当复杂的边缘。

所以我们能够接受图像实际上只是数字的事实。从这些数字中,我们能够获取这些特征,并提取它们,以便我们可以在图像中使用它们。

角点检测

当掩模水平或垂直移动时,边缘检测器使用梯度来寻找对比度和像素强度。然而,要检测图像中的角点,您需要检测任何方向上的强度对比度。哈里斯角点检测器算法通过测试图像的补丁来工作。在多个方向上移动补片,并比较每个位置的像素强度。现在,在图像的无特征区域,没有明显的差异,所以没有检测到角,如下图所示。

Image created by the author.

现在让我们在一个包含边的区域中尝试补丁。在这种情况下,当补片在一个方向上移动时,强度存在差异,但当补片沿着边缘移动时,强度不存在差异。所以这里也没有角。

Image created by the author.

现在让我们把补丁放在包含一个角的区域。任何方向的运动都会导致强度的变化。所以这看起来像是一个角落。哈里斯算法的公式有点复杂,它使用了一些微积分和矩阵数学。然而,这个算法在很多语言中都有实现,包括 Python。

Image created by the author.

Image created by the author.

让我们用一些 Python 代码来尝试一下。

下面是对上面代码执行情况的描述。我们得到的是一个我们定义的名为 corner_harr 的函数,我们将指定一个图像和一个最小距离。这里真正重要的东西来自 skimage 图书馆。从这个库中,我们导入了 corner_harris,它应用了寻找角点的算法,还有一个叫做 corner_peaks 的东西。我们将使用它来过滤掉所有较低幅度的角点,这样我们就只剩下图像中比较突出的角点了。因此,我们将继续工作,我们的方式通过图像,然后过滤它的基础上的距离,我们已经指定的角落的大小。现在我们要做的只是简单地传递我们的均衡图像。记得我们之前学过如何均衡图像。因此,我们将传递我们的均衡图像,然后我们将绘制结果。我们得到了哈里斯结果。我们基本上要绘制图像,我们要绘制哈里斯算法检测到的角点。所以我们把它们标成红色的小标记,这样我们就能看到角的位置了。当您运行该代码时,您会看到它返回了最突出的角。

从这里我们看到,因为我们的图像实际上只是一组数字,我们能够应用这些数学公式和算法来提取特征,并从图像中辨别某种意义。这确实是人工智能技术在处理图像时正在做的事情。

Illustration by Vecteezy.

处理图像和视频

图像分类

我们已经研究了各种处理图像并从中提取特征的方法。希望你已经看到,对于计算机来说,图像只是数字数组,可以在上面进行数学和统计运算。这意味着我们可以将类似的机器学习技术应用于图像,就像我们对任何其他数据所做的那样。例如,我们可以通过给图像添加标签来训练分类模型,如下图所示的汽车图像和火箭图像。然后,我们可以使用分类模型来预测新图像的适当标签。

Illustration by Vecteezy.

定制微软计算机视觉认知服务提供了一个构建定制图像分类器的框架,这样你就可以构建人工智能解决方案,识别对你来说重要的物体图像。因此,为了了解自定义图像分类,我们将使用自定义视觉 API 。

让我们想象一下,我们正在为一家非常专业的杂货商公司工作,我们所做的只是销售胡萝卜和苹果。我们真正希望能够做到的是自动检测一个物体是胡萝卜还是苹果。因此,让我们来看看我们可以如何做到这一点。当我们从人工智能程序的角度来看这些时,我们可以使用一种分类方法。

所以我们要做的第一件事就是去这个自定义视觉 ai 。这是一项我们可以注册的服务,可以通过微软认知服务获得。我们可以根据自己定制的图像分类集专门创建项目。

Image created by the author.

因此,我们将在这里创建一个新项目,我们就称它为水果和蔬菜。如果你喜欢,有各种现有的领域或主题领域,这显然属于食物的范畴,所以我们将选择食物。我们将创建一个项目。

Image created by the author.

一旦我们创建了项目,首先需要的是一些图像。我们需要使用一些现有的图像来训练我们的分类模型,对于这些图像,我们已经知道合适的标签是什么。所以我们要去添加一些图像。

Image created by the author.

这里我们有一些胡萝卜的图片,所以我们将继续抓取这些胡萝卜并上传它们。我们将添加一个标签“胡萝卜”并上传这些文件。这将把它们添加到项目中,并给它们分配标签胡萝卜,这样我们就知道这些是我们的胡萝卜图片。好的,这是我们得到的一组图像。

Image created by the author.

Image created by the author.

现在我们将添加一些苹果的其他图像。我们也将对它们进行标记。

Image created by the author.

我们想要做的是使用这些图像来训练我们的分类模型。这里没有太多的图片。显然,你添加的图片越多,你的模型就越有辨识度,但这应该足够了。所以开始吧,开始我们的训练。它将训练这些,我们将保留一些图像来做一些测试。

Image created by the author.

我们最终获得了令人印象深刻的 100%的性能,这是因为图像非常小,它们之间几乎没有什么可说的,但你会获得更真实的精度和召回率,这取决于你上传的图像数量。太好了,我们已经训练好了我们的模型。

Image created by the author.

我们将把它设置为这个特定项目的默认模型。

Image created by the author.

我们将从客户端应用程序中获取我们需要的信息,以便实际调用这个分类模型并使用它。有几种方法可以做到这一点,你可以上传一张图片或者你可以指定一个图片的 URL 来测试它。我们将使用一个 URL,所以我们需要预测键,这是我们项目中的键。这就是我们的身份。我们需要从我们的项目的网址。如下所示,它给了我们完整的网址。

Image created by the author.

现在让我们看一些 Python 代码。

下面是对上面代码所执行的内容的描述。基本上,我们正在导入药丸库和地图断层实验室管道或库,这样我们就可以显示图像等等。我们在这里导入了一些 HTTP 库,这样我们就可以发出 HTTP 请求。我们将在该请求中传递一些 JSON,这样我们就有了 JSON 库,所以我们只需发出请求就可以调用该 API。这是我们想要分类的图像的 URL,所以它基本上被称为 test.jpg。我们要测试一下,看看这是苹果还是胡萝卜。我们已经在这里得到了我们的预测密钥,这是来自我们帐户的密钥。我们不需要更改它,我们需要更改的是这里的项目 ID,我们将更改它,这就是我们刚刚创建的项目。基本上,我们在这里要做的(conn.request)是将 HTTP 请求的头设置为内容类型 is application/json。我们传递一个 JSON 请求,这是预测键,所以这是我们预测服务的键。没有任何参数,但有一个主体,我们的主体只是由一些 JSON 组成,它表示 URL,然后是图像的 URL。这就是我们测试图像的 URL。然后我们要做的是创建到认知服务的 HTTP 连接。我们将在这里把它发布到自定义 vision 版本 1 预测 URL 上。我们将传入我们的项目 ID,在它的末尾有一个 URL。那么基本上只有主体和头中的参数作为一个 HTTP 请求被传递。我们得到了回应。这个响应将会是一个 JSON 响应,我们将会把它加载到一个解析过的 JSON 文档中。现在实际将要发生的是,它将返回所有可能应用于图像的标签。它会搜索每个标签,并指出它认为自己是正确标签的概率。所以我们会得到一个标签列表。请记住,图像可以有多个相关联的标签。我们要做的是找到最可能的标签。最有可能正确的标签,我们将按照标签的正确顺序对这些预测进行排序。然后,我们将显示该图像及其上方的标签。

所以让我们继续运行它。

Image created by the author.

它所做的是,它已经预测到正确的标签是一个“苹果”,这肯定是我们的图像,看起来非常像一个苹果。因此,我们为图像建立了一个定制的分类器,专门处理我们需要处理的图像。我们能够使用它来自动检测和识别我们的人工智能应用程序看到的不同图像。

映象分析

有时你可能需要一个更通用的解决方案,不仅可以区分特定类别的对象,还可以开始理解图像中的内容。你可能需要能够识别各种类型的日常物品,并可能描述更复杂的场景,甚至可能阅读图像中的文本。

Illustration by Vecteezy.

计算机视觉 API 是一种认知服务,已经使用数百万张图像进行了训练,并建立了光学字符识别能力。让我们来看看吧。现在要使用 vision API ,你必须在你的 Azure 订阅中添加一个服务。完成后,您应该有一些访问键,可以用来从客户端应用程序连接到它。现在我们可以去写一些代码了。我们已经设置了网址。这是一个位置特定的,因此根据您提供它的位置,URL 可能会有所不同,然后是您的特定服务的密钥。

所以我们继续运行它。我们已经填充了这些变量,随时可以使用。现在我们要做的第一件事是抓取一个图像文件并显示它。下面的代码使我们能够做到这一点。

当我们运行这段代码时,它应该会打开一个图像。

Image created by the author.

我们要做的是,我们将使用计算机视觉 API 来获取该图像的一些特征。就像我们对自定义分类或我们构建的自定义分类器所做的那样,我们可以获取一些标签,我们现在只需从中获取一些标签。我们将使用下面的代码来实现这一点。我们没有训练过这个。这是由微软训练出来的,它是由成千上万的图片训练出来的,所以这里有大量的信息。

使用上面的代码,我们要做的是设置我们的头,但是把它放在一个 application/json 内容类型中,这样它会传递一些 json。我们将传递密钥,以便通过身份验证。然后我们这里有一些参数,基本上我们要说的是,这些是我们想要你返回的东西。我们希望您返回类别、描述和一些关于颜色的信息。我们可以指定一大堆其他的东西,但我们真正想要做的是对图像进行分类,给出一些关于图像的描述,如颜色。我们会把这些用英语描述的细节带回来。那么主体就是指向我们想要分析的图像的 URL。因此,我们将向 vision v1 analysed 方法发出 HTTP POST 请求,传递这些信息,然后我们将得到响应。返回的响应是 JSON,因此我们将直接读取该 JSON。一旦我们得到了它,我们就可以为我们的图像 URL 获取图像特征。这就是这个函数的作用。然后,我们将显示推荐的描述。让我们继续运行它,返回的结果如下:

tags: umbrella, tree, palm.
captions: A close up of an umbrella.

我们实际上可以看到返回的完整响应,并通过下面的代码查看进一步的细节。

这是它返回的内容:

因此,我们训练了这些图像,或者说微软已经使用数百万张图像训练了这些图像,通过简单地对照 API 分析图像,实际上给你一些相当准确和有用的信息。

人脸检测和识别

作为人类,我们天生就有识别面孔的能力。这就是为什么我们经常可以想象我们在随机的事物中看到脸,比如云和月亮。当我们与人工智能软件合作时,我们可以使用实时摄像机和图像来使计算机看到他们周围的世界。人脸检测,即确定图像中是否存在人脸的能力,是人工智能的一项重要能力。特别是如果这可以与人脸识别相结合,以匹配多个图像中的同一个人或识别特定的个人。

Illustration by Vecteezy.

face api 是一种认知服务,旨在处理面部和图像。我们需要做的第一件事是提供界面 API 。一旦你设置好了,你应该有一些我们的客户端应用程序需要的键。face api 是一种认知服务,旨在处理人脸和图像。我们现在要写一些代码。我们需要做的第一件事是指定连接到服务所需的 URI 和密钥。我们只需要初始化这些变量。

现在是 face API,有一个认知 face SDK,它是作为一个 Python 包提供的,所以它可以作为一个包装器。我们还将安装 pillow API,它同样用于处理图像。

所以我们将运行这些。所以现在我们想做的是拍摄一张照片,看看我们能否在照片中发现一张脸。我们可以用下面的代码来实现。

使用上面的代码,我们将要做的是获得一堆导入。我们在这里导入了 cognitive face API 作为 CF。我们可以在 CF 库上使用许多函数来简化工作。因此,我们将从我们的特定服务设置 URI 的基本 URL,并将密钥设置为我们的密钥。这意味着我们准备好进入并调用我们自己的服务实例。现在,我们将从一个 URL 中抓取一张人脸图像,并附带一个文件。我们将获取它,然后调用 face detect 方法,在那个 URL 中传递它,看看我们是否得到了关于人脸的任何信息。现在,如果在该图像中检测到一个或多个人脸,我们将获得这些人脸 id 的集合。这当然可以检测图像中的多张脸,我们实际上可以处理所有的脸,但在这个例子中,我们只关心第一张脸。因此,我们将获取 ID,它将为该面部分配一个 ID。然后我们就去看看那个 ID 是什么样子的。然后我们将抓取图像本身,打开并显示它。对于找到的每一张脸,在这种情况下,我们只关心找到的每一张脸的第一张,我们要去找到这张脸在图像中的位置。然后我们要在脸部周围画一个蓝色的矩形。我们得到的是面部的左上角坐标以及宽度和高度,因此我们可以用它来绘制一个矩形。然后我们只展示那张脸。

所以让我们继续运行代码。这是它传回的图像,毫无疑问,我们在它检测到的脸部周围有一个蓝色的矩形。

Image created by the author. Photo of Graeme Malcolm — Senior Content Developer at Microsoft Learning Experiences.

好的,如果我们已经得到了这个图像,我们想把它和另一个图像进行比较。也许我们正在实现某种自动人脸检测系统,我们可以用它来确保进入大楼的安全。我们希望我们建筑中的人工智能解决方案能够识别这个人,并将其与另一幅已被识别的图像进行比较,看看是否是同一个人。下面的代码就是这么做的。

使用上面的代码,我们要做的是抓取另一个图像并打开它。我们将在该图像上进行面部检测,并拍摄该图像,完全按照我们之前所做的那样进行操作。我们会说这里有一个图像,告诉我有没有一张脸,如果有,告诉我它在哪里。更重要的是,我们会得到一个 ID,所以我们得到的是第二张脸的 ID。我们已经知道了第一张脸的身份。所以我们会得到第二张脸的身份。我们有这个功能来验证面部。我们将传入两个 face IDs,并从我的 face API 中使用这个 verify 方法来查看第一个 ID 是否与第二个 ID 相同。它可以检查是否是同一个人,如果是,我们将画一个矩形包围的脸。如果不是同一个人,我们将使用红色矩形,如果是同一个人,我们将使用绿色矩形。有一个与此相关的置信度,它告诉我们在这场比赛中它有多自信。所以我们可以继续运行代码。

Image created by the author. Photo of Graeme Malcolm — Senior Content Developer at Microsoft Learning Experiences.

我们可以看到,这张图片周围有一个绿色的矩形,表明它与另一张图片是同一个人。它也有 91%的置信度。如果该图像与先前的图像不匹配,则置信水平会低很多,并且矩形会是红色的。这对 AI 来说真的是很有用的东西。如果你想一想这样一个事实,当我们与人打交道时,我们经常会认出他们。我们知道我们是谁,我们可以分辨出我们以前是否见过那个人。这只是一种将它扩展到人工智能的方式,让人工智能能够首先识别人脸,然后将它们与其他图像或这些人脸的其他记忆进行匹配。

视频基础

所以到目前为止,我们已经考虑了如何处理静态图像,我们可以做很多事情。然而,世界在不断变化,视频正成为网络上更普遍的媒体格式。

这是一个人走路的短片。事实上,这个视频实际上只是一系列被称为帧的静态图像。它们以特定于格式的编解码器进行编码,并封装在一个容器中,该容器还包括一个标头,其中包含有关格式持续时间等的元数据。

Illustration by Vecteezy.

现在来看看如何处理一些视频,我们将运行一些非常简单的 Python 代码,它将抓取一个视频并播放它,同时查看其中的帧。首先让我们安装这个名为 AV 的库。所以我们安装了它,安装了这个包,我们现在可以开始做一些视频的事情了。

!conda install av -c conda-forge -y

现在,我们将抓取一个小视频文件,并在笔记本上播放。

Image by tenor.

我们来看看视频中的画面。我们将计算帧数,并使用下面的代码显示第 25 帧。

使用上面的代码,我们将打开该视频,然后进入容器并获取将为我们提供帧的视频编解码器。我们将遍历每一帧,检查索引是否是 25 号。换句话说,我们找到第 25 帧,并将其转换为图像,以查看该帧的外观。它将继续对帧进行计数,一旦我们到达帧列表的末尾,我们将取出当前所在的帧,并减去 1,因为帧索引从零开始。我们将减去 1,这将告诉我们现在视频中有多少帧。这是一个小视频,因此这不是计算较大视频帧数的最有效方法。

当我运行它时,它能够运行它,它在视频中找到 111 帧,这是第 25 帧的样子。

Image by tenor.

这个过程将是我们对视频所做的许多工作的基础。

视频索引器

视频索引器是一种认知服务,它汇集了我们在本课程中迄今为止看到的许多人工智能功能。这是人工智能如何帮助自动化耗时任务的一个很好的例子,如编译和编辑视频文件的元数据。这是视频索引器用户界面的样子。我们已登录该服务并上传了一段视频。

Image created by the author.

这是一段视频,摘自微软的另一门课程。视频没有被修改,只是被上传了。如果我们从这里开始播放,我们实际上可以看到一些见解出现。在右手边,你可以看到有人在这里。它识别了两张不同的脸。

Image created by the author.

所以我们要去告诉它正确的名字。

Image created by the author.

Image created by the author.

它也收集了一些关键词。这是从一门关于统计学的课程中找到的,它找到了关键词“统计学基础方法论”。它获得了一些情绪,大约 53%的时间是正面的,大约 47%的时间是中性的。所以这是一个相当积极的视频。

Image created by the author.

我们也可以使用这些关键词“统计学基础方法”跳转到视频的一部分,或者“统计学课程”的一部分。我们还可以看到,它自动为该视频生成了一份抄本。

Image created by the author.

它生成了英文文本,但我们可以将其更改为法文。

Image created by the author.

Image created by the author.

我们也可以搜索一个词,例如“数据”。它将尝试并找到数据出现在抄本中的位置,并自动跳转到视频的该位置。

Image created by the author.

我们可以去编辑这些见解。例如,我们可以将成绩单从“这不是一个统计课程傻瓜”编辑为“这不是一个完整的统计课程”。

Image created by the author.

我们可以即时进行修改和编辑,并发布视频,让所有这些见解都可用。这将帮助人们在视频中导航和查找内容。所有这些都可以在这个用户界面和 API 中获得。所以我们可以写一段代码,上传一段视频,自动生成这些见解,然后下载生成的见解。它能够分析这些内容,因此这是一个非常令人印象深刻的人工智能应用,可以分析视频、音频,进行一些文本分析,并做各种有趣的事情,让需要管理大量视频文件的人的生活变得更加轻松。

视频索引器 API

视频不是特别有意思,除非显示一些运动。例如,想象一个用于监控濒危物种或安全地点的摄像机。人工智能可以帮助你找到运动发生的帧,而不是观看整个视频。也许您想更具体一些,只突出显示视频中人脸可见的点,或者甚至识别视频中人的特征。

Illustration by Vecteezy.

Illustration by Vecteezy.

为了分析我们的视频,我们将使用视频索引器 API。因此,在我们的代码中,我们引用帐户和帐户 ID。

viLocation = 'trial'
viAccountID = 'YOUR_ACCOUNT_ID'

所以我们将运行代码来设置这些变量。接下来我们要做的是创建一个视频索引器 API 订阅。

viKey = 'YOUR_PRIMARY_KEY'

好了,现在让我们来看看连接和使用 API 的过程。我们要做的第一件事是得到一个访问令牌。现在有各种不同级别的访问令牌,我们首先需要的是一个帐户级别的访问令牌,以便我们可以连接到我们的视频索引器帐户。所以我们这里有一些代码可以做到这一点。

使用上面的代码,我们将发出一个 HTTP 请求,基本上我们将连接到我们的视频索引器 API。我们将传入我们的 a 密钥,并传入我们需要访问令牌的位置和帐户 ID。我们应该以 JSON 文档形式取回访问令牌。如果我们运行那个代码,它会返回 JSON。这是我们从中提取的值。它只是一个访问令牌,一个很大很长的令牌,我们用它来建立到 API 的认证连接。

好了,现在我们已经可以开始使用视频索引器 API 了。我们要做的是上传一个视频,用下面的代码进行处理:

因此,我们运行代码,并得到一个带有为该视频设置的一些元数据的响应。其中一个是视频 ID。你可以获得视频 ID,但这太繁琐了,所以你可以做的是运行一些代码来获得视频 ID。

这段代码解析 JSON 并获取 ID。

videoID: a6c7b509ad

现在上传视频,处理需要一点时间。所以你可能只是想检查上传的视频的状态。下面的代码允许您检查状态。

State: Processing

视频处理完成后,我们现在准备好连接并开始获得一些见解。然而,为了做到这一点,我们需要不同级别的访问令牌。我们需要一个视频级别的访问令牌,我们可以用下面的代码得到它。

这是视频访问令牌,和上次的想法一样,一个又大又长的安全令牌。我们使用该令牌来观看视频。我们可以从视频索引器网站上获取用户界面的元素,并将其嵌入到我们自己的应用程序中,只需使用这样的代码。我们将获取该 URL,传入我们特定视频和令牌的各种细节。然后我们会在笔记本的 iframe 中显示它。

因此,我们想要做的是使用视频索引器,通过下面的代码来获得对该视频中实际发生的事情的深入了解。

它返回的是如下所示的一些见解。

我们得到了一些关于视频的元数据,看起来至少有一张脸。它说有一张脸的出现在 14 秒后结束,它从 8.3 秒开始。我们不知道那个人是谁,我们有一个已知的身份证,但全是零。让我们去获得视频中面部识别的细节,python 代码如下。

让我们继续使用这段 python 代码以缩略图的形式查看这张脸。

正如你所看到的,它返回了下面的缩略图。

Image created by the author. Photo of Graeme Malcolm — Senior Content Developer at Microsoft Learning Experiences.

然后,我们可以使用下面的代码查看缩略图的细节。

Image created by the author. Photo of Graeme Malcolm.

正如我们所看到的,这个人是未知的,但是我们知道这个人是这门课的讲师格雷姆·马尔科姆。我们可以编辑这个,把未知数改为格雷姆·马尔科姆。

Image created by the author. Photo of Graeme Malcolm.

由于我们现在已经训练人工智能知道这是格雷姆·马尔科姆,我们可以再次测试它,看看它是否能识别它是格雷姆·马尔科姆。为此,我们需要重新加载分解,并检查更新的面部细节。我们可以用下面的代码来实现。

正如我们在元数据中看到的,它现在识别出这是 Malcolm Graeme。

Image created by the author.

一锤定音

感谢您阅读这篇文章,这是微软人工智能入门课程的第 3 部分。如果你觉得这很有帮助,那么请查看我的媒体账户或数据科学 T2 的所有 4 个部分。如果你对本文中的一些概念有困难(不要担心,我花了一些时间来理解这些信息),并且你需要更多的信息,那么就免费报名参加微软人工智能入门课程。与这些笔记一起观看课程视频很有帮助。

  • 如果您想了解课程笔记和其他与技术和产品设计相关的笔记背后的一些背景信息,您可以通过这里找到更多信息。 *

有点背景

大家好,我是 Christine:)我是一名产品设计师,在数字领域工作了很长时间,在许多不同的公司工作过;从大型公司(多达 84,000 名员工),到中型企业,再到仍在扬名立万的小型初创企业。尽管我有很多经验,但我是一名产品设计师,害怕受到邓宁-克鲁格效应的影响,所以我不断尝试教育自己,我总是在寻找更多的光明。我相信,要成为一名伟大的设计师,你需要不断磨练自己的技能,尤其是如果你在不断变化的数字空间中工作。

微软人工智能简介—第 4 部分

原文:https://towardsdatascience.com/microsoft-introduction-to-ai-part-4-d310033bdb07?source=collection_archive---------19-----------------------

Image used under licence from Getty Images.

对话是一个平台

对话式人工智能允许人们每天通过语音、文本和触摸,用类似人类的自然语言与应用程序、网站和设备进行交流。它提供了一种引人入胜且直观的与技术互动的方式,这种方式正在彻底改变人类与机器的关系。我们已经从一个必须学习和适应机器的世界进化到一个它们正在学习如何理解我们并与我们互动的世界。

“为了让人和机器一起工作,他们需要能够以更自然的方式进行交互,而对话是我们交换信息的首选方式。”

— Murray Campbell,IBM 杰出的研究员和深蓝的架构师

人工智能的进步将使计算机的对话能力变得更加复杂,为计算领域的巨变铺平道路。这是“微软人工智能导论”课程笔记的第四部分,也是最后一部分。了解智能对话机器人以及如何实现人类和计算机之间的自然交流。

背景

(跳过背景信息如果你看过 第一部 第二部 第三部 )

对于那些没有看过这个系列的第一部、第二部或第三部的人来说,这里有一些背景信息。我一直想学习人工智能(AI ),尽管对其中涉及的数学感到有点害怕,并认为一些概念可能超出了我的深度。幸运的是,我的好奇心战胜了我的恐惧,所以我开始学习一些与人工智能相关的课程。我最近完成了微软人工智能入门课程,并写了课程笔记来帮助我记住我所学的知识。我试着用一种简单的方式来写这些笔记,让它们更容易阅读。我最近成为一名阿姨,买了几本与技术和空间相关的儿童书籍,非常喜欢作者和插图画家如何设法简化复杂的主题。因此,我受到启发,以类似的方式处理这些主题,简化它们,使它们更容易理解,特别是对那些和我一样最初对人工智能感到恐惧的人。

  • 如果您想了解课程笔记以及其他与技术和产品设计相关的笔记背后的更多信息,您可以在此找到更多信息。 *

摘要

(如果看过 第一部分 第二部分 第三部分 )

微软人工智能入门课程提供了人工智能的概述,并探索了为人工智能提供基础的机器学习原则。从这门课程中,你可以发现将人工智能功能集成到应用程序中的基本技术。学习如何使用软件来处理、分析和提取自然语言的含义。了解软件如何处理图像和视频,以人类的方式理解世界。了解如何构建智能机器人,实现人类和人工智能系统之间的对话。

Image created by the author. Microsoft Introduction to AI course

这个课程需要大约 1 个月的时间来完成,所以我写的 1 篇中型文章包含了一周的内容。这意味着你只需要花大约半个小时来阅读这篇文章,它是一周的内容。那是一种快速的学习方法。没有证书的课程是免费的,但是,如果你想要一个证书作为完成的证明,是要收费的。本课程有相关的实验,我不会在笔记中列出,因为我认为最好的学习方法是实际做实验。然而,如果你想了解人工智能背后的基本理论,并想以一种可能比其他资源简单得多的方式来学习它,这些笔记是有用的。我试着用外行人的术语来写它,并加入了视觉效果来帮助说明这个想法。如果你没有时间学习这门课程,这些笔记会很有用,这是快速浏览核心概念的一种方法。或者,如果你像我一样学过这门课,你可以用这些笔记来记住你学到的东西。

教官:

Graeme Malcolm——微软学习体验的高级内容开发人员

摘要

(跳过教学大纲如果你看过 第一部分 第二部分 第三部分 )

本课程分为四个部分,包括:

1.机器学习

了解关于人工智能和机器学习的基础知识。

2.语言与沟通

学习如何使用软件来处理、分析和提取自然语言的含义。

3。 计算机视觉

了解如何使用软件处理图像和视频,以我们的方式理解世界。

4.将对话作为一个平台(*这篇中型文章将只关注这一部分)

了解如何构建智能机器人,实现人类和人工智能系统之间的对话交流。

Image created by the author.

对话是一个平台

本课程的“计算机视觉”部分将涉及以下主题:

僵尸工具简介

什么是 Bot?

微软机器人框架

创建基本机器人

频道

打造智能机器人

机器人智能

创建 QnA 服务

创建 QnA 机器人

Cortana 技能

Image used under licence from Getty Images.

机器人简介

什么是机器人?

想想你通过即时通讯、社交媒体、电子邮件或其他在线技术与其他人交流的频率。对我们大多数人来说,这是我们常用的联系方式。现在,机器人是人工智能代理,它们使用这些类型的通道进行通信,通过与其他人使用的相同通信通道,实现与软件服务的自然对话。1950 年,艾伦·图灵设计了一个被称为图灵测试的模仿游戏,并假设如果对话足够自然,你可能不知道你是在和一个人还是一台计算机对话。随着人工智能变得越来越复杂,这正在成为现实。

Illustration by Vecteezy.

微软机器人框架

微软机器人框架提供了一个构建和发布机器人的平台。您可以使用 bot builder SDK 或 Azure bot 服务来创建您的 bot 并将其作为 web 服务发布。您可以通过一个或多个渠道提供您的机器人,如 Skype 或其他流行的消息和社交媒体平台。bot 连接器服务处理您的 bot 与用户参与其中的通道之间的消息交换。每个交互都是一个活动,可以是一条消息,也可以是一个可视元素,比如包含图像、按钮或输入字段的卡片。当用户开始与机器人对话时,活动在通道和机器人之间自动路由。您还可以将您的机器人与认知服务集成,以便它能够智能地响应用户输入。

Image by Microsoft.

创建一个基本机器人

让我们来看看如何使用 Azure bot 服务创建一个基本的 Bot。因此,我们现在在 Azure 门户中,我们将创建一个新的 web 应用程序机器人。为此,我们只需向您的帐户添加一个新资源。我们可以在人工智能&认知服务中找到它,或者只是简单地搜索机器人。在搜索结果中有一个 web 应用程序机器人,我们将创建其中的一个。

Image created by the author.

Image created by the author.

Image created by the author.

因此,我们的机器人需要的第一件事是一个名称,在这个例子中,我们将把它称为“ShoutyBot”。我们还需要在这里填写一些其他的东西。我们将为它创建一个资源组,以便集中管理所有相关资源。我们需要选择要部署的位置,因此我们将选择最近的数据中心。然后,我们需要为这个机器人选择定价层,有许多可用的定价选项。在这个例子中,我们将使用免费的。然后我们需要给它一个应用程序名称,它将创建一个 Azure web 应用程序来支持这个机器人,因此我们为它指定了一个应用程序名称,在这种情况下,它只是采用了与机器人相同的名称。

现在,我们将选择我们的机器人所基于的模板,根据您想要构建的机器人类型,您可以使用许多不同的模板。我们将简单地使用节点。JS 基本 bot 模板生成一些简单的节点。JS 代码来创建一个非常简单的机器人。接下来是进行设置这些设置。

Image created by the author.

我们选择了免费层,因此我们不需要支付任何费用,但我们仍然需要设置服务计划,因此我们将设置该计划。

Image created by the author.

Image created by the author.

完成后,我们将创建一个存储帐户来存储机器人使用的一些数据,它会自动为其生成一个名称,因此如果我们满意,我们不需要进行任何更改。然后,它将创建一些应用程序洞察力,以便我们可以跟踪机器人的使用情况。这就是我们需要创建的所有设置。我们将继续创建我们的机器人。

它将继续验证这些设置,并确保我们准备就绪。一旦验证通过,它就会启动并开始创建我们的机器人。当部署成功时,我们会收到一条小消息,告诉我们已经创建了 bot。如果我们去看看 Azure 订阅中的资源组,我们可以看到他们有一个名为 ShoutyBot 的资源组。

Image created by the author.

如果我们在那里看一下,我们可以看到与我们的机器人相关的所有不同的资源。因此,它们都将在这个资源组中一起管理,机器人本身是这里列出的第一个“ShoutyBot”。

Image created by the author.

因此,我们将去看看,这里有许多页面,我们可以用来配置和使用我们的机器人。我们要做的第一件事是转到这个构建页面,这将让我们访问一个在线代码编辑器。

Image created by the author.

现在,我们可以在浏览器中在线编辑我们的机器人代码,或者我们可以在任何 IDE 中本地使用它,如 visual studio 或类似的东西。我们可以将代码下载为 zip 文件,并对其进行同步,甚至配置一种叫做持续部署的东西。因此,我们可以将代码放在源代码控制系统中,并与实际的在线机器人同步。在本例中,我们将使用在线代码编辑器,因此我们将打开它,进入这个在线环境。我们目前没有自述文件—没有为此创建的自述文件;但是我们能做的是开始查看我们的机器人的代码,它在这个 app.js JavaScript 文件中。有一些基本的代码被放在一起,以便在微软机器人框架上与我们的机器人一起工作,这是每当我们发送某种消息时机器人实际上做出响应的一点。

Image created by the author.

这是发送响应的代码,你可以看到它非常简单——它只是一个简单地说“你说了”的函数,它会重复用户对机器人说的任何话。

Image created by the author.

这并不是非常有用,所以我们要对它做一点小小的修改来证明我们可以做到。这不会真的更有用,但至少我们会看到它有所作为。所以我们要把它改成大写。所以我们现在所做的就是编写代码,这样无论何时我们对机器人说话,它都会用大写字母喊回来。

Image created by the author.

我们已经完成了,现在可以关闭这个代码编辑器,回到 Azure 门户中的 bot。我们要做的是在网络聊天中测试这个机器人。我们只需在网络聊天中点击测试,当机器人准备好测试时,我们只需输入一条消息。我们应该从 ShoutyBot 那里得到一个大写的回应——hello。所以你可以看到创建一个非常简单的机器人是非常容易的。只需在 Azure 门户中创建设置,然后对代码做一个小的修改,我们就会得到一个定制的消息。

Image created by the author.

我们现在可以做的是将这个机器人作为网络机器人部署在网页上,供人们使用。我们可以看到,如果我们在渠道中寻找,这里有这个网络聊天代码。我们可以在这里编辑这个频道,以获取密钥和代码,我们需要将该机器人嵌入到网页中,并使其可供人们使用。因此,我们非常简单地组装了一个 bot,并使用 Azure Bot 服务进行了部署。

Image created by the author.

Image created by the author.

频道

我们已经看到了如何使用 bot 框架创建一个简单的 Bot,现在我们准备尝试通过各种不同的渠道来使用它。这是我们之前创建的 Shoutybot,我们已经看过了网络聊天频道,在那里我们可以获得代码,将该 bot 嵌入到网页中。我们还可以使用很多其他渠道,比如 Cortana、微软团队、Skype、Bing 甚至电子邮件。因此,我们可以使用这些选项中的任何一个,为用户创建一种与我们的机器人交流的方式,就像他们与其他人交流一样,例如通过发送 Skype 消息或打电话。

Image created by the author.

构建智能机器人

机器人智能

因此,我们已经看到了如何建立一个基本的机器人,并将其连接到一个频道,但是,要使你的机器人有用,你需要把某种智能背后。你可以将你的机器人与认知服务集成,以理解文本、语音等自然语言,分析图像或视频。你甚至可以用它在网上搜索相关信息,提供专家信息和基于知识库的建议。当然,你可以结合这些能力来创建复杂的基于对话的人工智能体验,并使用户和软件能够以一种自然的方式一起工作。

Illustration by Vecteezy.

创建 QnA 服务

我们已经看到了如何创建一个基本的 bot,以及如何使用 Microsoft bot 框架来允许用户通过多个通道连接到该 bot,尽管我们创建的 bot 并不那么有用。我们真正需要的是机器人背后的某种人工智能服务,它将提供用户真正想要使用的有价值的东西。所以我们将使用一个名为 QnA 服务的认知服务来创建一个非常简单的例子。让我们来看看如何做到这一点。

Image created by the author.

我们现在在 QnA 制造商网站,这是一个门户网站,我们可以在这里使用我们的 QnA 服务来创建我们可以在我们的机器人中使用的知识库。因此,我们将了解一下如何创建新的知识库,这个过程分为三步。第一步是在我们的 Microsoft Azure 订阅中创建 QnA 服务的实例。

Image created by the author.

Image created by the author.

我们将继续操作,然后单击“创建 QnA 服务”。它将打开另一个选项卡,让我们登录 Azure 门户。然后,我们可以继续创建一个新的问答制作服务。所以我们给它一个独特的名字“QnAJokes ”,因为它将包含一个知识库,里面有一些相当糟糕的笑话,为此道歉。我们将选择要创建该服务的订阅,以及托管该服务的管理定价层。在本例中,我们将为此选择自由层,以便我们能够开发它。我们会有一些限制,但它让我们免费开发它。我们将为这个资源组创建一个名为 QnAJokes 的资源组,我们还必须选择搜索定价层。当知识库被搜索时,我们有一个单独的定价层,我们将再次选择免费层,因为这将有助于开发它。我们将把它存储在美国西部的数据中心,然后我们需要为此创建一个 web 应用程序——为我们的 QnAJokes 创建一个 Azure 应用程序。我们将有一些应用洞察,以便我们可以分析这项服务发生了什么,我们将把这些存储在一个中心位置。我们将继续操作,单击“create ”,它将验证这些设置。然后,它将启动并提供我们的 QnA Maker 服务和 web 应用程序来托管它。

然后,当我们的 QnA 服务部署完成后,我们可以返回到我的 QnA Maker。我们将刷新页面,以便获得关于我们实际部署的 QnA Maker 的所有信息,它将列出我们在此提供的 QnA 服务。因此,第二步是将我们即将创建的知识库连接到我们刚刚部署的 QnA 服务。因此,我们将使用我们的 Microsoft Azure 目录 ID,我们将指定创建服务的订阅。因此,我们正在创建一个新的知识库,它将为 QnA 服务提供服务。

Image created by the author.

然后我们需要给这个知识库起个名字,所以我们就称它为“Jokebook”。

Image created by the author.

现在,我们已经准备好填充我们的知识库,如果我们的网站上有一个现有的 FAQ 站点,或者如果我们有一个包含 FAQ 的文件,我们可以继续使用它们来填充它。或者,我们可以继续手动创建知识库,这就是我们在本例中要做的。

因此,我们会说创建您的知识库,我们准备好开始创建我们想要在知识库中包含的问题和答案。最初,这里什么也没有,所以我们要添加一个 QnA 对。我们要问的问题是“为什么鸡要过马路”,与之相应的答案是“到另一边去”。因此,我们在那里得到了我们的响应,我们将继续添加另一个 QnA 对。所以我们可能会有一个问题,比如“什么是红色的,看不见的”,这个问题的答案是“没有西红柿”。最后,我们将在这里添加一些东西,以便当某人第一次与知识库交互时,他们会说“你好”,并且会得到“你好”的响应。这不是一个真正的问题答案,这只是一种互动的方式,并得到适当的回应。我们已经在那里添加了这些值,我们将继续保存并训练知识库。

Image created by the author.

所以在它被训练之后,我们可以继续测试它。我们只需简单地输入一条消息“hello ”,然后得到相应的响应“hello”。“为什么鸡要过马路”而我得到的是适当的回应“为了到另一边”。所以我的知识库在工作。我得到了适当的回应。

Image created by the author.

这一切似乎都很合理,所以我们准备发布这个相当简单的知识库,以便我们可以在机器人或应用程序中使用它。因此,我将点击“发布”。

Image created by the author.

为了发布它,它将把 QnAs 从测试索引移动到生产索引,这样我们就可以从我们将要创建的 bot 中访问它。所以我们会继续出版。然后将我们的知识库部署到我的 QnA maker web 服务中。我们实际上可以看到一个示例请求,我们将使用它来连接并使用它。它有各种各样的信息,在这个 URL 中有各种各样的键,当我们尝试连接一个机器人时,我们将需要这些信息,我们将在以后构建这个服务。

Image created by the author.

创建 QnA 机器人

我已经创建了一个 QnA 知识库,我们可以用它作为机器人的后端。所以现在我们只需要继续创建这个机器人。现在我们在 Azure 门户中准备创建我们的机器人。因此,我们将继续添加一个新的 web 应用程序机器人。

Image created by the author.

Image created by the author.

当我们创建我们的机器人时,我们必须给它一个名字,所以我们要称它为“bad skins”。我们将把它放入我们想要使用的适当订阅中,并将它放入我们之前为 QnA 服务创建的现有资源组中。所以我们要把我们放在西边。我们将为此选择合适的定价层,然后我们需要一个应用程序名称。我们将使用适当的模板,我们将使用允许我们使用 QnA maker 的模板。

这次我们将坚持使用 C#,只是为了改变一下,但我们要做的是选择问答模板。它将在美国西部创建应用服务计划,并将为该机器人创建一些存储和一些应用见解。我们将继续并选择“create ”,现在我们将验证这些设置。

Image created by the author.

它将启动并部署新的机器人,当机器人部署完成后,我们就可以开始查看该资源了。在准备使用它之前,我们必须进行一些更改,因为我们必须将它连接到我们的 QnA 服务。为此,我们将查看该应用程序服务的应用程序设置,并加载这些设置。如果我们向下滚动一点,我们可以看到我们需要使用的许多不同的应用程序设置,其中一些是专门用于 QnA 服务的。我们需要一个 QnA 身份验证密钥、一个端点主机名和一个知识库 ID。

Image created by the author.

现在,我们可以在我们部署的 QnA 知识库中获得所有这些信息。

Image created by the author.

这就是我们需要将机器人连接到 QnA 知识库的三个设置。因此,我们将继续保存这些设置,这已经为我们更新了这些应用程序设置。所以我们现在准备去测试我们的机器人。我们可以在网络聊天界面中进行测试。

Image created by the author.

它来了,我们准备好开始了,所以我们可以礼貌地说你好,然后我们从 bad 笑话 hello 得到我的回应。“小鸡为什么要过马路”而我们得到了“到另一边”的恰当回应。因此,我们现在创建了一个机器人,并将其连接到我们的 QnA 知识库。然后,我们可以通过机器人可以连接到的任何常规渠道来部署该机器人,它将使用该知识库来回答用户提交给它的问题。

Image created by the author.

Cortana 技能

像 Cortana 这样的个人助理越来越受欢迎,人们可以通过它来跟踪信息、自动完成任务等等。这些人工智能助手可以了解我们关心的事情,它们可以帮助简化我们的日常生活。现在你可以把你用 bot 框架发布的一个 bot 连接到 Cortana 作为一项技能。这使得用户能够通过 Cortana 界面与你的机器人进行交互。

这是我们之前创建的机器人,它连接到我们的问答服务,我们想在 Cortana 中使用它。因此,如果我们看看这个机器人的通道,我们可以看到它连接到网络聊天,现在正在运行,但我们可以继续将其添加到 Cortana 通道。

Image created by the author.

因此,如果我们继续进行配置,并设置我们自己与一个组织,在这里,我们只是简单地向一个组织注册这个机器人。所以我们要去登记。当 bot 注册后,我们可以看到 Cortana 已经列在频道列表中。如果我们现在去看看我们的商店门户,看看机器人,你可以看到有 bad 笑话机器人。

Image created by the author.

现在它已经被注册为这个组织的一部分,我们可以在这里看到关于 Cortana 技能的各种信息。所以我们想做的是进去看看这里的发布设置。我们可以做的一些事情是给它起一个名字,所以 bad jeans 是技能的名字,并给一个调用名——换句话说,我们要用这个短语告诉 Cortana 这是我们想要与之交互的服务。

Image created by the author.

我们将继续下去,只是发布出来准备使用。这意味着,如果我们只是像平常一样使用电脑,然后去 Cortana,我们现在可以说“问一些不好的笑话,为什么鸡要过马路”。Cortana 对此进行了思考,然后它意识到我们正在尝试连接到这种叫做 badjokes 的技能。

Image created by the author.

为了让它连接,我们需要给它一些权限,所以我们会同意与该技能共享我的信息。这种情况只发生在第一次,我们得到正确的回应“到另一边去”。然后我们可以问一个不同的关于糟糕笑话的问题,“什么是红色的,看不见的?”我们得到的回应是“没有西红柿”。因此,我们已经能够使用我们创建的机器人,并将其连接到问答服务,这样我们就有了一个问答知识库。然后我们能够使用 Cortana 作为一个通道与之互动,并通过输入问题甚至说话来互动地获取信息。

Image created by the author.

一锤定音

感谢您阅读本文第 4 部分,这是微软人工智能入门课程的最后一部分。如果你觉得这很有帮助,那么请查看我的媒体账户或数据科学 T2 的所有 4 个部分。如果你对本文中的一些概念有困难(不要担心,我花了一些时间来理解这些信息),并且你需要更多的信息,那么就免费报名参加微软人工智能入门课程。与这些笔记一起观看课程视频很有帮助。

  • 如果您想了解课程笔记和其他与技术和产品设计相关的笔记背后的一些背景信息,您可以在这里找到更多信息。 *

有点背景

大家好,我是 Christine:)我是一名产品设计师,已经在数字领域工作了相当一段时间,在许多不同的公司工作过;从大型公司(多达 84,000 名员工),到中型企业,再到仍在扬名立万的小型初创企业。尽管我有很多经验,但我是一名产品设计师,害怕受到邓宁-克鲁格效应的影响,所以我不断尝试教育自己,我总是在寻找更多的光明。我相信,要成为一名伟大的设计师,你需要不断磨练自己的技能,尤其是如果你在不断变化的数字空间中工作。

微软恶意软件预测—关于如何可视化数据、设计功能和训练模型的简要概述

原文:https://towardsdatascience.com/microsoft-malware-prediction-a-brief-overview-on-how-to-visualize-data-engineer-features-and-222ea727be5a?source=collection_archive---------24-----------------------

简介:

一个寒冷的冬日,我打开电脑开始工作,不知道前方会有一场大雪。我耐心而愉快地启动电脑,开始阅读我的电子邮件。突然,我的浏览器打开了,我震惊地看到我的浏览器上有一条消息,要求我给税收机构汇些钱。显然,在盛怒之下,我中了圈套,点击了一个发件人发来的附件,看起来像是我的一个同事。我花了几乎一天半的时间才找到清除威胁并确保我安全的方法。从那天起,我小心翼翼地检查我的电子邮件和浏览互联网。不仅如此,我总是想办法找出为什么一个人会成为目标,以及如何找出他/她的电脑成为目标的可能性。当我发现微软恶意软件预测数据可以公开获得时,我很想深入了解并找到更多关于这些数据的信息。我的最终目标是开发一个应用程序,从一个人的电脑上收集数据,并判断电脑是否容易受到攻击。首先,让我们看看计算机和反病毒/恶意软件市场。

防病毒/恶意软件市场:

在发达国家(北美、欧洲和大洋洲),台式电脑的使用份额仍大幅领先于移动设备(手机和平板电脑)。在所有的操作系统中,微软(MS) Windows 占据了全球 77%的市场份额,Mac OS 以 13%的份额紧随其后,谷歌 Chrome 占 6%(美国市场),Linux 占 2%。由于 MS Windows 是市场上的主要操作系统,个人和商业计算机都容易成为病毒和恶意软件攻击的目标。目前的防病毒市场份额估计约为 37 亿美元[ 2 ],预计到 2024 年将达到 35 亿美元左右。市场上有许多反病毒公司(迈克菲、赛门铁克、卡巴斯基、Bitdefender、ESET、趋势科技、Avira、Avira 仅举几例);然而,微软 Windows Defender 作为 Windows 10 中的常驻杀毒软件,已经占据了 50%的市场份额,保护了近 5 亿台电脑。[ 3 , 4 ]在微软 Windows Defender 之前,微软 Security essential 是杀毒软件的替代品。考虑到全球范围内通过 MS Windows Defender 和 MS Security Essential (MSE)受保护的设备数量超过 5 亿台,显然微软已经收集了大量关于设备、防病毒状态和威胁的数据。对微软或其他公司或用户来说,知道什么是威胁因素或可能性是有益的。用户是否可以仅通过考虑多种因素(设备形式、Windows 版本、防病毒及其版本以及任何其他相关变量)来评估他/她的计算机是否容易受到攻击。在这篇文章中,我将简要评估这些数据,并使用两个模型来训练和测试这些数据。

数据:

这项研究的数据和专栏(特征)描述通过 Kaggle 恶意软件预测竞赛公开提供,可在此处找到。我仅下载了培训数据,并尝试在我的个人电脑上分析和可视化这些数据。然后,我利用了 Google cloud Colab 平台,因为它有可访问的处理资源。解压缩后的训练数据为 4 GB,占用大约 2 GB 的 RAM。我使用了一个特征类型定义字典来避免大量的内存使用。对数据的简要分析表明,该数据集有 892 万条记录,包含 83 个列/特征。

可视化和分析数据:

我绘制了“HasDetections”功能(目标列)的分布图,以查看数据是否在检测到恶意软件或未检测到恶意软件的位置之间平均分布。然后,我尝试分离二进制列(那些值为 0 和 1 的列)并绘制它们的分布图(图 1)

相关图有助于我们理解这些特征是正相关还是负相关。如果特征是强相关的,我们可以使用其中一个特征,而不是使用多个特征,从而节省计算资源。可以看出,除了少数几列(它们彼此相邻并且负相关,例如 RtpStateBitField—IsSXSPassiveMode)之外,其余数据不相关或者稍微相关。

我还绘制了受感染机器的数量与“平台”、“外形”以及设备是否是“游戏机”的对比图 Windows 10 是受攻击最多的平台(或者记录数据最多的平台)。

应该注意的是,正在使用的笔记本电脑数量是正在使用的台式机数量的三倍。其他外形的设备落后于笔记本和台式机。

最终的图表清楚地显示,游戏电脑几乎不到台式机的一半。但是,游戏桌面比非游戏电脑更容易被感染(比较红色、绿色、橙色和蓝色)。

这些数据清楚地表明,如果某人拥有台式机并且不是游戏玩家,则不应该成为攻击的热门目标。这些数据给了我一个线索,那就是使用 Windows 10 的台式机使我更容易受到攻击。

特征工程:

为了准备用于训练的数据,我需要评估数据中的空值。我计算了任意特性列中 null 值的总数和百分比。我决定丢弃/忽略空值超过 25%的特性(有 9 列),并估算其余的特性。下图显示了不同列中缺失值的百分比。

如果你有兴趣阅读不同的插补方法,可以查看这个链接。插补是一个计算密集型过程(CPU ),为了节省时间和我的处理资源,我首先随机采样/选择了整个数据集的 20%;并将所有 NaN 替换为非数字特征/列的平均值。对于数字和文本/字符串特性,我用模式值替换了 NaN。用数字列中的平均值替换 NaN 值会将该列转换为非数字列。我通过检查 nan 的数量是否为零来验证该过程。在对分类特性进行热编码之后,我删除了原始分类列,并将所有特性连接在一起。在下一阶段,我保留了以下分类列(ProductName、Platform、Processor、Census _ OSArchitecture、Census_FlightRing、Census_GenuineStateName),并删除了其余的列。我应该声明,反病毒版本是一个重要的功能;然而,在这个阶段,我把它放在一边。

培训、测试和参数调整:

我将使用两种不同的算法来训练和测试数据。由于预测值(标签)是数字的(0 或 1),我将使用逻辑回归和 XGBoost 模型,并将使用网格搜索来调整参数。我对逻辑回归使用了四种不同的复杂性(0.1、1、2、10),对 XGBoost 使用了五个参数组合的三重搜索(15 次拟合)。

逻辑回归训练的错误率与复杂性

两个模型基于最佳参数的预测结果如下:

逻辑回归:

精度= 0.6099

回忆= 0.6064

精确度= 0.6061

混淆矩阵是:

[[13847 12978]

[ 8077 18549]]

XGBoost 型号:

精度= 0.6089

回忆= 0.6056

精确度= 0.6055

混淆矩阵是:

[[13899 12874]

[ 8210 18468]]

结论和未来工作。

正如人们所观察到的,用它们的最佳参数测试的两个模型在两位有效数字内产生几乎相同的精确度、召回率和准确度。在没有任何硬件加速(没有 GPU)的情况下,在 Colab Python 3 平台上训练模型,logistic 回归 fit 用了近 33 分钟,XGBoost 用了 36 分钟。

我的下一步是将这一分析提升到下一个级别,并改进模型的培训/测试:

  • 使用整个数据集训练模型,并在单独提供的测试数据集上测试模型。
  • 通过链式方程使用多元插补对数据进行插补。
  • 使用其他可以使用分类数据(没有编码)的模型。
  • 使用所有分类功能,包括防病毒版本功能。

最终目标是开发一个应用程序,从你的电脑中获取数据,并预测成为攻击目标的概率。如果你感兴趣,可以在这里找到这个分析的源代码。如果你有任何意见或问题,请随时给我写信。

“微软恶意软件预测”及其 900 万台机器

原文:https://towardsdatascience.com/microsoft-malware-prediction-and-its-9-million-machines-22e0fe8c80c8?source=collection_archive---------13-----------------------

深度学习来预测机器是否会被恶意软件感染。

Kaggle 最近完成了竞赛“微软恶意软件”,它要求你预测一台计算机是否被感染。竞赛声明

“恶意软件行业仍然是一个组织完善、资金充足的市场,致力于规避传统的安全措施。一旦计算机被恶意软件感染,犯罪分子会以多种方式伤害消费者和企业。拥有超过 10 亿的企业和消费者客户,微软非常重视这个问题,并在提高安全性方面投入巨资。”

作为一名网络安全从业者,这是一个拥有大量数据的绝佳机会,可以尝试提出以下问题:

  • “为什么电脑会被感染?”
  • “最大的贡献者是什么?”
  • “补丁打得怎么样了?”

不幸的是,竞赛回答了更多关于机器学习的问题,而不是恶意软件预防或修补最佳实践。

目标:找到恶意软件!

这个 Kaggle 竞赛提供了表格数据供我们探索,也是我在专注于商学院、电路板设计和进入新的工作角色后第一次跳回 Kaggle 竞赛。

以下是我 8 天疯狂编码过程中的学习点。(你可以在 Github 这里找到我的比赛代码,并且可以在你空闲的时候运行它。)

这场比赛的数据集相当大,如果你的 GPU 中没有足够的 RAM,你可以迁移到云环境或减少功能或设置以使其工作。我用的是一台定制的电脑,配有 8gb 内存的显卡。

对问题的初步看法:

在查看数据之前,有必要了解变量的数量。这个数据集中有超过 900 万个机器标识符,到比赛结束时,我已经为每台计算机找到了大约 100 个不同的类别。

是的,这只是试图确定计算机是否被感染的十亿个数据点中的一小部分。

通过查看各列,我们可以看到一些功能在确定计算机是否会被感染时是如何有用的。像这样的项目:

  • 操作系统的版本
  • AV SIG version:AV 产品的签名
  • AVProductsInstalled:安装的 AV 产品数量

这 3 个特征显然是确定机器是否会被感染的候选特征。毕竟,如果您没有更新您的反病毒签名,没有运行反病毒产品,或者正在运行 Windows XP,您是一个更容易的目标。

其他值稍微困难一些,需要一点特性工程:

  • census _ internalbaterynumberofcharges:我们知道台式机是零费用的
  • CountryIdentifier:设备声称来自的国家表明恶意软件可能有多流行。
  • Wdft_IsGamer:他们玩游戏吗?这与其他危险的在线行为有关联吗?他们使用机器的方式不同吗?
  • census _ InternalPrimaryDisplayResolutionHorizontal:可以计算百万像素。所有小型显示器的标准是什么?大显示器?

在这些情况下,特征的重要性是微妙的。这就是这些完成的乐趣所在。

这不是一个时间序列…或者是?

可能都是合规培训吧。然而,我一直想把这变成一个时间序列问题。毕竟,问题不在于哪个 AV 存在,而在于它们已经过时多久了。

安全部门被告知要不断更新补丁。如果我们不知道某样东西有多过时……我们怎么能确定它是否更容易被感染。

然而,比赛组织者明确表示,这不是一个时间序列问题。作为一个目光短浅的愚蠢行为,这并没有阻止我试图创造数字来预测电脑是否过时。

我不是唯一一个,当人们发现你如果电脑有自动更新,并且你将 AVSigversion 的发布日期与那个日期进行比较时,竞争对手陷入了一个大陷阱。

许多人猜测,比赛仍然有时间序列元素隐藏在数据中,这是有充分理由的。很多 Kaggle 比赛都有隐藏数据。一些用户讨论了来自训练集的 AVSignatures,并将其与公共/私有进行了比较,您会看到这些 AVSignature 时间变量发生了显著的左移。Chris Deotte 提供了一个很好的例子。训练集看起来比公共/私有数据集有更旧的数据。

在追踪虚假时间序列问题时,我会做几件不同的事情:

1.构建我的验证集是为了使用更新的数据,确保它是公共/私有数据集的更好表示。

2.我创建了关于修补后天数的附加参数。通过设置最后一个已知补丁的基线,我可以看到这个值离提供的输出有多远。这项技术为不合规天数提供了优秀的指标。我对此感到特别自豪,但去掉了这个功能,因为我没有看到不同型号的改进。

此外,有一个外部数据集发现了反病毒签名与其解决的漏洞数量之间的相关性。那么我们如何利用这一点呢?

理想情况下,我们希望看到哪些补丁已经发布,以及系统是否在打补丁方面落后。如果我们知道一个系统有多少补丁是过时的,我们就能够为此创建一个特性。然后,我们将能够看到保持项目最新与检测之间是否存在关联。

然而,由于我们没有这些数据,我尝试通过获取最近的日期来猜测数据是何时获取的。这些数字与任何令人兴奋的事情都没有关联,也没有被证明非常有用。

需要注意的是,这更多是因为竞争。作为实践者,如果我们知道机器被收集的日期,我们就可以设计出更多的特性(比如暴露的漏洞数量、隐藏的补丁等等)。)来扯点有意思的见解。

更智能地使用内存

面对如此庞大的数据集,内存成为许多人的一个重要问题。甚至加载数据都很困难,因为所有数据都是以 int64 格式输入的。甚至 bools 都是以 int64 开头。这种臃肿的内存分配方法导致一些机器在加载时崩溃。

快速提醒一下,

  • Int16 — float16: 2 字节
  • Int32 — float32: 4 个字节
  • Int64 — float64: 8 字节

仔细检查并减少一点,你可能看起来是在浪费时间。2 字节还是 8 字节谁在乎?每个人都应该!

当有 800 万条记录和 100 列时,您需要存储大约 6.4 千兆字节信息。此外,您需要加载一个测试集,这将是另一个 6.3 千兆字节。突然,您看到了 12.7 GB 的数据,其中大部分都浪费了空间。

因此,我甚至无法将它加载到消费级 GPU 中。NVIDIA 1080 TI 最高可达 11 GB。通过使用 dtypes,我们可以将它减少很多。

第一个技巧是在合理的情况下将数据类型设置为较小的大小。足够让你加载数据而不会出现内存错误。

为此,您需要进行一些理智检查。您需要在如何减少 dtype 的同时为所有唯一变量保留足够的空间之间进行平衡。让我们记住这个城市有 800 万条记录。只有 X 个唯一的城市标识符。我们被传递了一个城市 id,因此我们可以看到城市“42”7000 次,而城市“28930”只出现了 2 次。

类别也是如此。这些数据通常以字符串的形式出现,因此,我们使用类别来表示这些数据是唯一的,并对它们进行分组。

如果数组的大小小于 32,768 个 uniques,可以安全地将其转换为 int16。唯一的城市数量超过 100,000,所以我们使用 float32 而不是 Int64。IsBeta 是布尔型的,所以我们可以把它设为 int8。

如果我们把它做得太小,我们会有问题,但是如果它太大,我们会浪费空间,这带来了我对 reduce_mem_usage ( 在这里找到)的热爱,它会为您的数据和您的惟一值找到最佳值。虽然您必须手动加载数据集,但您不必花费更多时间来为所有变量寻找最佳值。

在运行 reduce_mem-usage 之后,您可以看到内存的显著减少。突然我们有了更小的东西。正如你在下面看到的,我的大小从 7 GB 降到了 1.67 GB

这样我就可以将更多数据放入 GPU 的数据帧中。

很棒的东西!

用泡菜分开

我喜欢的另一个方法是将程序分成两部分。

  • 数据构建器 - 我在这里探索、创建特征、移动和操作数据。使用 pickle 保存信息,并为学员移动信息
  • 学习者 - 建立模型,运行学习纪元。

通过将构建者和学习者分开,我可以保持代码更干净,并且它允许我更容易地用不同的选项运行它。再加上实验进行的比较快。如果学习者遇到问题,我可以从重置中减去 10 分钟。

我们表现如何?

最后,我们列出了每台机器感染恶意软件的可能性。理想情况下,我们应该看到一个最高数字在 0 或 1 上的马鞍。如果你只花几个训练时期,你会看到这个太空入侵者的样子,暗示着我们需要更多的训练才能到达那里。它不如顶级的公共内核有效,这有点令人失望。

我应该做得更好的事情:

更多的数据探索和特征工作- 可能最大的问题是没有更好地理解一些特征在问题中的重要性。我应该多检查一下相互依赖。

数据二次抽样——通常当数据集变得这么大时,你应该返回并把项目分成二次抽样,然后再汇总结果。

对抗分析 -我需要更好地理解如何比较我的训练集、验证集和公开测试。这看起来并不像我希望的那样相互靠近。

AUCROC——我使用交叉熵作为损失函数。然而,我应该更深入地研究使用 AUCROC 来代替。虽然我可以打印出一个指标,但我无法更好地探索它的可行性。

嵌入大小——看起来一些嵌入向外扩展,在测试集中有许多 1 或 2 的唯一值的例子。例如,如果芝加哥只有 2 个样本,是否应该使用该特性?它既不能帮助你确定是否有感染。

我应该把它作为一个张量来保持事物快速前进。

午夜黑客 1:可视化我的 Swiggy 订单历史

原文:https://towardsdatascience.com/midnight-hack-episode-1-visualizing-my-swiggy-order-history-f1cce25cbff6?source=collection_archive---------9-----------------------

却没有耐心去阅读?别担心。

下面是 可视化仪表盘 仪表盘预览 下面是项目 Github 链接

现在是晚上 11 点,当我在去订多份午夜餐的路上时,我心想:

我不太清楚自己的点餐习惯。有趋势吗?我能否从我的订购历史中获得一些有意义的见解?

当我在 Swiggy(一个印度食品订购和交付应用程序)上浏览甜点选项时,我试图弄清楚如何才能获得我的订单历史数据。现在,我从过去的经验中了解到,有时友好的请求会奏效。让我们试试那个。

所以是的,那没有成功,但是有志者事竟成。

我大概可以在订单历史页面上拦截对 Swiggy 应用的网络请求。我知道像 Drony 这样的应用可以做到这一点。但是我必须开发一个定制的应用程序,以便遍历所有的订单页面并汇总结果。aggggggghhhhhhhhh……好像工作量太大了。我们称这个计划为 b 计划吧。如果没有别的办法,b 计划会回来的。

我想网络会是更好的选择。相对更容易黑。我只希望他们的网站上还有订单历史页面。

耶,他们有一个功能齐全的网站。我以为他们已经完全移动化了。嗯,对我来说不错。他们甚至有订单历史页面。我现在泪流满面。戴夫眼泪:')

让我们打开 chrome 开发工具,看看一些网络请求,好吗?

Order list response

GET request headers

哦,那个甜甜的 JSON 回复:)

看起来 order_id 是分页的参数。

他们似乎在使用 CSRF 代币。查看请求头,似乎他们使用 cookies 来维护会话,并使用 CSRF 令牌来避免第三方客户端请求。我以为他们会使用一些简单的 JWT 令牌,所以我打算使用 python 来处理网络请求,但我想这不是一个选项。

最好通过浏览器访问 API。不确定这是否可行,但让我们试一试。

var xmlHttp = new XMLHttpRequest();
xmlHttp.open( “GET”, “[https://www.swiggy.com/dapi/order/all?order_id=](https://www.swiggy.com/dapi/order/all?order_id=)", false );
xmlHttp.send( null );
console.log(xmlHttp.responseText);

当我登录时,这个简单的 JS 片段应该能够使用会话 cookies 获取订单数据。

Order response through JS snippet

而且成功了:')

我没想到它会和他们采取的所有安全措施一起工作,但是嘿嘿嘿…..

现在,我所要做的就是修改脚本,这样它就可以对所有页面进行分页,并为我提供汇总数据。

order_array=[]
order_id=’’
page = 1try {
    while(true){
        var xmlHttp = new XMLHttpRequest()
        xmlHttp.open( “GET”, “[https://www.swiggy.com/dapi/order/all?order_id=](https://www.swiggy.com/dapi/order/all?order_id=)"+order_id, false )
        xmlHttp.send( null )
        resText=xmlHttp.responseText
        var resJSON = JSON.parse(resText)
        order_id=resJSON.data.orders[resJSON.data.orders.length-1].order_id
        order_array=order_array.concat(resJSON.data.orders)
        console.log(“On page: “+page+” with last order id: “+order_id)
        page++
    }
}
catch(err) {
    console.log(order_array)
}

Complete order history

总计 53 页和 518 订单。

*看着他松软的肚子。

还不错。一点也不差。*内心呐喊

现在,我可以添加一些代码来保存文件中的数据,但有一个更简单的方法。右键单击数据>存储为全局变量。使用命令复制复制剪贴板中的数据。

copy(temp1)

将其粘贴到记事本中并保存。瞧,现在你有了整个 Swiggy 的历史。

文本数据5MB ,信息很多。最初,我想以文本形式获得一些见解,但是,看看这些数据,最好创建一个可视化的仪表板。

我真的没有任何创建可视化的经验,但是在浏览了大量的文档和评估工具之后,比如 J upyter Notebooks,Matplotlib,Plotly,Dash;我决定和达什一起去。它有一个非常直接的布局过程,并且与 python 配合得很好。

现在是第二天下午 4:20。经过一整夜的分析和设计,这是最终的结果。

Screencap of Visualization Page

你可以在这里 查看我的可视化仪表盘 。如果您想可视化自己的 Swiggy 订单历史,所有需要的资源都托管在 这里

我认为我从这个项目中得到的最有用的见解是我在食物上花了多少钱,这也是从一个单一的来源得到的。我不知道自己在 Swiggy 上花了多少钱。

直到下一次…

千禧一代最喜欢的水果:用 ARIMA 模型预测鳄梨价格

原文:https://towardsdatascience.com/millennials-favorite-fruit-forecasting-avocado-prices-with-arima-models-5b46e4e0e914?source=collection_archive---------20-----------------------

It’s a fruit. — Photo by Thought Catalog on Unsplash

如果你知道关于金融的第一件事,你就会知道在千禧年和白色栅栏之间的唯一障碍是鳄梨吐司。如果信息时代的孩子们能站起来,离开早午餐桌,把他们捣碎的鳄梨和荷包蛋放在全麦面包上,那么他们也许能买得起他们在爱荷华州艾姆斯的梦想中的两居室。明明

为了声援千禧一代的鳄梨吐司引发的金融危机,我想更深入地研究一下美国最受欢迎的水果。是的,鳄梨是一种水果——甚至是一种浆果。我的研究还表明,鳄梨实际上并不是烤面包制造商为了卖出更多烤面包的阴谋。

因此,在这篇文章中,我将分析来自哈斯牛油果委员会(HAB) 的数据,这是一个为行业专业人士提供全球牛油果价格研究和数据的贸易组织。如果你想了解鳄梨相关的研究,你可以在这里找到数据。

数据

HAB 数据集由从 2015 年 1 月 4 日到 2018 年 3 月 25 日的 168 周每周时间序列数据组成。在此期间,该数据集提供了美国 54 个地区的常规和有机鳄梨的平均价格和总量数据,总计超过 18,000 次观察。

所以让我们进入正题——我们的鳄梨长什么样?

视力测试告诉我们,有机鳄梨的平均价格比传统鳄梨更高,也更不稳定。深究这些数字,所有地区传统鳄梨的平均价格为 1.16 美元,标准差为 0.26 美元。同时,有机鳄梨的平均价格为 1.65 美元,标准差为 0.36 美元。

然而,看看销售的鳄梨,发现有机鳄梨只占同期美国销售的所有鳄梨的 3%。2015 年 1 月至 2018 年 3 月期间,消费者购买了超过 3300 万个常规鳄梨和不到 100 万个有机鳄梨。

我们知道传统鳄梨的平均价格更高,在销售方面远远超过有机鳄梨。所以,这就提出了一个问题——价格和销售量之间的关系本质是什么?

(Conventional) Pearson’s Correlation = -0.51 p-value<0.001 | (Organic) Pearson’s Correlation = 0.02 p-value=0.75

在为期 168 周的研究中,传统鳄梨的平均价格和销售量呈中度负相关。这里没有什么不寻常的,而是经济学的基本原理——需求量随着价格的下降而增加。

有机鳄梨讲述了一个不同的故事。有机鳄梨的价格标签和销售量之间没有统计上的显著关系。需求持平,这意味着无论价格如何,消费者都不太可能大幅改变他们的需求量。背景对于理解这种关系很重要。

研究表明,收入较高的消费者、小孩和/或大学学历的人比他们的同龄人更有可能成为“忠实”的有机消费者。在这种情况下,“投入”表示消费者在有机水果和蔬菜上的支出高于其家庭收入的平均水平。因此,有理由认为定期有机鳄梨消费者属于一个非典型的人群。不幸的是,我没有足够的资源来找出这种平淡关系背后的因果因素,但我当然可以(也很乐意)大胆猜测。经常购买有机商品的消费者(可能)更有可能出于某种原则而购买。也许消费者认为有机食品比非有机食品更健康或更道德。因此,由于有机食品价格的简单变动,有机消费者不太可能消费非有机食品,因此我们对有机鳄梨的需求曲线是平坦的。

Right: Average Price (USD) | Left: Total Volume (Avocados Sold)

接下来,我想快速浏览一下各个地区的价格和销量。东北人(我的人民)和华盛顿人(也是我的人民)为这个国家的有机和传统鳄梨支付了最高的价格。东北人平均为传统鳄梨支付 1.34 美元,为有机鳄梨支付 1.86 美元。与此同时,普通鳄梨的全国平均价格为 1.09 美元,有机鳄梨为 1.55 美元。

就数量而言,西方人平均每周消费最多的鳄梨,包括传统的和有机的。西方人每周消费超过 618 万个传统鳄梨和 22 万个有机鳄梨。与全国平均水平相比,西方人消费了美国销售的 18%的传统鳄梨和 23%的有机鳄梨。

有很多鳄梨吐司。

预报

我认为可以很有把握地说,就买得起我前面提到的那套两居室而言,这艘船已经航行了几千年。我的意思是,美国人每周在鳄梨上花费大约 700 万美元,所以几千年来对白色栅栏的所有希望都应该破灭。

谢天谢地,根据皮尤研究中心的调查,我属于 Z 世代。当然,这意味着我需要了解鳄梨经济将如何影响我实现与栅栏相关梦想的机会。

为此,我求助于 ARIMA 预测。 A uto- R 过度 I 积分 M 移动 A 平均模型是一类通用模型,允许通过“差分”使预测模型稳定平稳性是预测中的一个重要条件,因为非平稳性会破坏传统置信区间、假设检验和预测的可靠性。

ARIMA 模型可以分为三个部分,AR,I 和 MA。首先,AR 组件描述了一个线性多元回归,其中给定数量的 Y 的先前值作为 Y(t)的预测值。I 分量描述了使模型稳定所需的差分顺序。MA 组件类似于 ar 组件,因为它将滞后值引入模型。然而,滞后值是以前的误差项,而不是以前的值。

感谢像我这样的 ARIMA 新手,Rob Hyndman 在 R 中的“预测”包配备了 auto.arima 函数。Auto.arima 测试了几个 arima 模型,并根据 Akaike 信息标准选择了最佳模型,为选择最终模型提供了一个良好的起点。

使用扩展的 Dickey-Fuller 检验,检验可能偏向 OLS 估计量的单位根,我得出结论,对于我的四个模型——常规价格、常规交易量、有机价格和有机交易量——中的每一个,一阶差分都是必要的。此外,我选择使用季节性 ARIMA 模型,它包含另一组给定期间(在本例中为 52 周或一年)的 AR、I 和 MA 参数。

那么,我们能从我们的模型中学到什么?首先,我们的平均价格模型似乎告诉我们,鳄梨价格在每年的秋季达到顶峰。2017 年 10 月,传统鳄梨达到 1.65 美元的峰值,我们的模型预测,秋季的峰值将持续到 2018 年和 2019 年。然而,该模型预测,在接下来的两年里,传统鳄梨的价格将呈下降趋势。2015 年至 2018 年间,常规鳄梨的平均价格为 1.09 美元。2018 年至 2020 年,预测平均价格为 1.01 美元,下降约 7%。

与之形成鲜明对比的是,该模型预测有机鳄梨价格将在波动性较小的支撑下温和增长。2018 年至 2020 年的预测平均价格为 1.84 美元,而 2015 年至 2018 年为 1.55 美元。该模型当然显示了有机鳄梨价格的温和上涨趋势。

然而,平均价格的增长也部分归因于波动性的降低,预测期内价格的标准差从 2015 年至 2018 年期间的 0.36 美元标准差降至 0.16 美元。

据预测,在 2018 年至 2020 年期间,传统和有机鳄梨的销量都将出现强劲增长。传统鳄梨产量预计将增长 40%以上,平均每周售出 3370 万至 4760 万个鳄梨。

有机鳄梨预计会经历更迅猛的增长。预计 2015 年至 2018 年之间的持续增长趋势将持续到 2019 年,2018 年至 2020 年之间的增长率将高达 74%。2015 年至 2018 年间,供应商每周售出约 97 万个有机牛油果。2018 年至 2020 年间,这一数字预计将跃升至 168 万个有机鳄梨。

讨论

我认为这些模型真的很令人兴奋。首先,在模式识别方面,有趣的是看到模型在季节趋势上有所回升。价格模型捕捉到了秋季的价格上涨,而交易量模型捕捉到了每年 2 月鳄梨交易量的峰值。

此外,诊断看起来相当不错。平均绝对百分比误差(MAPE)用于测量预测值和观测值之间的误差,因此较低的值表示模型拟合度较好。在四个模型中,有机体积模型的 MAPE 最高,约为 6%,表明该模型的准确率约为 94%。我对这种契合度非常满意,我对所有的车型都很有信心。至少,我像一个预测新手一样自信。

如果我不得不发表评论(我很乐意这样做),我会说有机鳄梨产量的增长预测有些乐观。我不确定仅仅两年 74%的增长有多现实,但是测试几个模型得出了类似的结果。

或者,我认为传统的鳄梨价格模型有些悲观。随着 2015 年以来秋季价格上涨逐年增加,我很惊讶该模型预测整体价格下降。然而,如果这种情况持续到 2020 年,你将不会看到我在早午餐时抱怨。

结论

朋友们,这就是我对 ARIMA 天气预报的小小介绍,还有一个像鳄梨这样有价值的测试主题。尽管传统鳄梨的价格可能会下降,但鳄梨销量的增加似乎将阻止下一代人实现郊区房产天堂的梦想。

我希望你喜欢我对预测的尝试,我希望很快回到这个主题,有更多改进的 ARIMA 模型和其他更复杂的模型。嘿,也许投资有机鳄梨种植者——你可能会看到 74%的回报。

嗯,可能不会。

读心术算法

原文:https://towardsdatascience.com/mind-reading-algorithms-368bdf412eb2?source=collection_archive---------17-----------------------

推荐系统介绍

Photo by Virginia Johnson on Unsplash

今晚的游戏计划:一顿热饭,一张温暖的床,和几个小时的网飞。最棒的是,你即将让它发生。

你把钥匙放在前门,转动锁,把门推开…

《黑镜》的最后一集有点令人不安。也许今晚我应该给索尔打个电话……

你已经穿过前门一半了…

…可能不会像《绝命毒师》那么好,但是…等等,那是什么?

附近正在播放音乐。你出去听着。它来自你大楼旁边的那家新商店。这是你过去几天一直在想的一首歌。商店前面铺着红地毯。

“电子商店”,你喃喃自语,读着商店顶部发光的红色霓虹灯上的内容。你几次路过这里时,都没怎么注意这个地方。

你将对展出的东西进行快速检查。毕竟,几分钟的逛街不会伤害任何人。

你走进商店,注意到里面灯光明亮。有各种各样的货架上摆放着物品,一些店员在移动和整理物品。商店中心有一个小舞台,配有一张沙发和一个小架子。

仔细一看,你注意到舞台上小小的架子上只有你的尺码和你喜欢的运动品牌的跑鞋。你一直在考虑重新开始跑步。

是我做点什么的时候了吗?

你挑选了一双鞋,走向收银台。在去那里的路上,你看到一个放着跑步衬衫和裤子的架子。看一眼就会发现,有些可以和你的新鞋搭配成一套很棒的衣服。你很快就会看到。

我不能像个业余选手一样出去!

现在你有了完整的跑步装备,你可以继续去收银台了。在把东西交给店员时,你注意到一张海报,上面是你最喜欢的演员在跑马拉松。他们穿的衣服几乎和你将要购买的一样。唯一的区别是,你漏掉了他们戴的智能手表。

几率有多大

店员微笑着指着收银台旁边展示的智能手表。你愉快地忍受着。

离开商店后,几个小时后,你开始反思你的疯狂消费。除了装备和智能手表,你还买了一副太阳镜、蛋白粉、健身房订阅和健康计划。

也许逛街并没有那么有害……

对于实体店来说,这似乎是一个遥不可及的故事,但却是许多互联网服务的基础。故事中的E(vil)store用来吸引你注意力的策略,你可以在这篇文章的参考资料中找到一个现有的数字类比。这些技术中的大多数都与被称为推荐系统的领域相关。

现在推荐人无处不在。很有可能你正在阅读这篇文章是因为一个建议产生的。他们负责用户在 Amazon⁴购买的 35%的东西,人们在网飞观看的 75%的东西,以及在 YouTube⁵.观看的 70%的时间

这些算法在我们的社会中是如此根深蒂固,以至于人们甚至开始警惕他们的 risks⁶.反 vaxxers,平地球支持者和其他阴谋论者已经学会操纵这些系统,以不成比例的高比率推荐他们的内容。那些主张一个由互联网驱动的新启蒙时代的人很可能没有想到今天的 YouTube。

到目前为止,这篇文章并没有帮助恢复推荐系统的形象。但我的目标是关注他们积极的一面。推荐者为我们提供了一项有价值的服务:通过减少选择的不确定性来做出决策。此外,正如我们将在接下来的章节中看到的,在一个充满无限选择的数字世界中,这不是一件容易的事情。

通过这篇文章,我想分享一个关于推荐人的什么,为什么,如何的直观想法。我不打算涵盖实现或技术细节。所以,如果这就是你想要的,请小心。

简而言之,如果你需要向老板解释什么是推荐人,这篇文章可能会有所帮助。相反,如果你需要为你的老板建立一个推荐者,这篇文章可能有助于在你搜索其他文章时分散他的注意力!

推荐系统 101

推荐系统推荐器是一套技术,用于根据用户的需求向他们推荐最合适的项目。尽管这个定义听起来很简单,但它隐藏了许多细节。

在推荐者的上下文中,一个项目是一个非常具有延展性的想法。它可以是娱乐应用程序中的电影或歌曲,也可以是约会应用程序中可能的爱情或配偶。基于项目的质量,推荐器试图猜测哪些项目最适合推荐给给定的用户。因此,如果你有看动作片的历史,你很可能更喜欢收到像《速度与激情》这样的推荐,而不是网飞最新的浪漫剧。

合适也是一个主观的问题。从用户的角度来看,你期望一个推荐者为你的需求尽可能快地提供最好的选择,并且支付最少的费用。另一方面,一家企业试图谋生,因此推荐者提供建议的方式需要反映这一目的。人们可以预期,用户和企业的需求有时会发生冲突。

查尔斯·杜希格(Charles Duhigg)推广了一个建议走得太远的生动例子。在《习惯的力量》一书中,他提到了一个案例,一位愤怒的父亲通过定向广告发现他十几岁的女儿怀孕了。广告公司利用他女儿的购买历史,认为她可能很快就会需要婴儿服装,并为此发送了优惠券。不知情的父亲收到了邮件,发现了优惠券。在向公司代表投诉后不久,从他女儿那里得知她确实怀孕了。

在这篇文章中,我选择了推荐系统的定义,它并不局限于软件计算机系统。这是因为这些系统不是只有大的技术公司才能建立的技术问题。此外,它们不局限于数字世界,甚至不局限于人类事务。

狩猎采集文明需要向他人推荐他们生存的最佳觅食地。国王们有部长小组来建议政府重要领域的行动方针。即使在动物界,蚂蚁也会留下痕迹,向蚁群中的其他成员提示去 food⁷.的最佳路线

最近,推荐系统的使用扩展到广泛的数字服务。在选择过多的应用程序中,这变得很有必要。对这种系统的研究始于 70 年代的杜克大学。然而,第一个基于软件的推荐系统 Tapestry 花了 20 年才问世。它是在施乐帕洛阿尔托研究中心(PARC)开发的,并发表在 1992⁸.的《美国计算机学会通讯》杂志上

Xerox PARC researchers during an informal meeting⁹. Probably complaining about all the cat images filling their inboxes.

由于电子邮件的使用越来越多,施乐 PARC 公司的研究人员试图用 Tapestry 处理他们收到的所有不必要的文件。这个系统利用人们的合作,根据他们的反应来标记文档。然后,这些标签被用来创建个人过滤器,减少每个用户收到的文档数量。例如,爱丽丝可以创建过滤器,只接收鲍勃和乔标记为有趣的文档,接收玛丽·⁰.标记为重要的文档

但是,一个最初作为文档过滤器的算法是如何在我们今天的数字服务中如此根深蒂固的呢?这就是我们将在下一节讨论的内容。

为了简单起见,从现在开始我们将只关注基于软件的推荐器,并且将使用广义的术语推荐系统、推荐器系统和 推荐器来指代它们。

小书架和无限书架的问题

想象一下,你将要在你的镇上开一家书店。现在亚马逊主导了市场,这感觉是一个可怕的想法。即便如此,没有人会阻止你的创业动力。你已经签了一个小但位置好的地方的租约,还计划向顾客提供你的招牌浓缩咖啡。

不久前,您收到了来自几家出版社的书籍目录,今天您需要挑选哪些书籍将会摆满书架。但是,当你通读第一个目录时,做决定会越来越困难。

我应该订购保罗·柯艾略的新书吗?…

饥饿游戏系列怎么样?…

还有我的朋友德里克最近出版的《牧场着装专家的回忆》?

书架的空间限制了你一次可以拥有多少本书。因为你可能想长期生存下去,所以明智的做法是只向公众提供最受欢迎的书籍。对不起,德里克……

在这种情况下,照顾顾客的个人需求是不可能的,因为你没有足够的空间放这么多书。如果你想赚钱,你需要展示你知道的有需求的东西。一些客户可能找不到他们想要的书,但是大多数人只要买了最受欢迎的书就会很开心。

现在,想象几年过去了。你的策略非常有效。顾客对你选择的书籍和招牌浓缩咖啡非常满意。如此之多,以至于一家大型连锁书店最近出高价收购你的书店。他们想任命你为首席执行官来推动他们新建立的数字战略。

最后,你再也不用担心有限的货架空间了。该公司的主页是一个无限的、完全可定制的书架。此外,你可以访问像亚马逊一样大的库存。你只需要从 5000 万本书中找出哪些书展示给你下个月期待的 1000 万名顾客……嗯……

你可以坚持以前的策略,在主页上给每个顾客展示最受欢迎的书籍。然而,数以百万计的顾客对你向他们展示的东西不感兴趣。此外,你不会开发你的巨大库存的潜力。最终结果可能是数百万愤怒的顾客和业绩不佳的销售。

另一个选择是在主页上显示所有可用的书籍。尽管如此,你还是面临着选择悖论的风险。当人类面对丰富的选择时,非但没有感到快乐,反而变得烦躁和焦虑。因此,你很有可能最终会让顾客更加恼火,减少销售额。

你担任首席执行官才几周,董事会已经在重新考虑你的任命……

绝望中,你走出办公室,走进雨夜。看着天空,你尖叫,要求一条出路…

突然,你的手机震动了…

你在雨中花了几秒钟努力解锁手机,直到你能看到通知…

“想看什么?在你湿淋淋的屏幕上,一条来自网飞的小横幅上写着“我们建议黑镜:Bandersnatch”。

呃…谢谢,但现在不是时候…

或者……是吗?

这就是推荐系统介入的地方。通常,以不太戏剧化的方式。

在向用户提供所有可能的选择或向所有用户提供通用选择之间存在一条中间道路。通过使用推荐器,可以向每个用户提供一些经过深思熟虑的建议。

为此,你不需要关心书籍的受欢迎程度。您可以将每个客户的兴趣与书籍的属性(如流派、长度和作者)相匹配。例如,你可能会发现一些客户会对《光明使者》系列而不是《权力的游戏》(GoT)反应更好。在网上书店,这是你可以也需要关心的事情。在实体店,这些顾客很可能需要购买 GoT 系列。

在线世界和现实世界满足顾客需求的差异被称为长尾。下图有助于理解这一现象。水平轴上的每个条形代表一个项目。这些条按照流行度(在垂直轴中表示)以递减方式排序。

The Long Tail. Physical stores define what they show to users by their shelf space limitations. Online stores use Recommenders to define what to show.

垂直虚线左边的条是实体店由于空间限制可以展示的商品。相比之下,网上商店可以展示所有的商品:尾巴和受欢迎的商品。推荐器旨在解决在线环境中显示过多选项的问题。

到目前为止,我们已经看到了什么是推荐器以及它们解决的问题。现在,我们将回顾推荐者产生建议的不同方式。

神奇的推荐者和在哪里可以找到他们

除了推荐器的 WhatWhy 之外,了解这些系统通常是如何构建的也是有意义的。为此,我们将回顾标准的六类推荐人⁴以及哪些科技公司使用了它们⁵:

  • 基于内容(CB): 推荐与用户喜欢的项目相似的项目。为了识别相似性,推荐器使用项目的特性或特征。对于书籍推荐者,该算法可以使用流派、作者或书籍长度作为推荐类似书籍的特征。使用者:脸书和亚马逊
  • 协同过滤(CF): 推荐其他口味相似的用户过去喜欢的用户项目。CF 背后的推理是“两个或两个以上在一个领域有相似兴趣的人也倾向于购买其他领域的相似物品或产品。”使用者:亚马逊、脸书、LinkedIn 和 Twitter
  • 人口统计:根据用户的人口统计资料推荐商品。这些系统通常按照特定于业务的规则对用户进行细分,并基于这些细分生成推荐。使用人:易贝
  • 基于知识:通过将明确的用户需求与商品特征相匹配来推荐商品。例如,您指定卧室的数量、占地面积,网站会返回最佳匹配房屋的列表。
  • 基于社区:利用用户朋友的喜好推荐物品:告诉我你的朋友是谁,我告诉你你喜欢什么。
  • 混合:这种类型的推荐器推荐结合了两种或两种以上先前技术的项目。一个典型的例子是将协同过滤方法与基于内容的系统相结合。使用者:亚马逊和网飞

在这六种类型的推荐器中,前两种,基于内容和协同过滤,是最受欢迎的。这两个网站上都有丰富的资料。如果你想深入挖掘推荐者或者自己建立一个,就从这里开始吧。

结束语

本文从推荐系统的技术介绍开始。然而,经过一点研究,我注意到已经有数百篇文章有类似的目标。

因为我没有动力去做同样的事情,所以我把一些叙述和理论混合在一起,写了这篇科学怪人的文章。我希望它对理解推荐者有所帮助,也许会给你——至少——一个同情的笑声。

我们现在处于一个时代,这些算法正在塑造我们日常生活的重要部分。我们应该理解我们在社交媒体订阅源、在线购物建议和其他数字服务中看到的东西背后的含义。本文试图以一种可理解的方式填补这一空白。

我希望你喜欢这篇文章。如果你有任何问题或意见,请随时给我留言。

后续步骤

最后,如果你想了解更多关于推荐者的信息,我有一些建议作为起点:

理论

  • 挖掘海量数据集,第九章
  • 推荐系统手册

申请

  • Python 初学者推荐系统
  • 基于 PySpark 的推荐系统
  • 用 TensorFlow 构建协同过滤推荐系统

数据集

  • 电影镜头
  • TMDB 5000
  • 带有消费者评级的餐厅数据

参考

[1] Mailchimp,什么是重定目标? (2019,访问日期)

[2] R. Reshef,了解协同过滤方法 (2015)

[3] A .钱德拉舍卡,f .艾买提,j .巴西利科和 t .杰巴拉,网飞的艺术作品个性化 (2017)

[4] I. MacKenzie、C. Meyer 和 S. Noble,零售商如何跟上消费者步伐 (2013 年)

[5] A. Rodriguez, YouTube 的推荐驱动了我们观看的 70%(2018)

[6] G. Chalot,YouTube 上的 Twitter 帖子的推荐 (2019)

[7] R. Sharma,R. Singh,推荐系统从古代到现代的演变:调查 (2016)

[8] R. Sharma,R. Singh,推荐系统从古代到现代的演变:调查 (2016)

[9]计算机历史,施乐 PARC (2019,访问日期)

[10] Huttner,Joseph,从 Tapestry 到 SVD:为推荐系统提供动力的算法综述 (2009)

[11]_ Curly _ Council,这是一个我可以预见自己会进入的职业 (2013)

[12] P .希伯特,选择的悖论,10 年后 (2017)

[13] J. Leskovec,A. Rajaraman,J. Ullman,挖掘海量数据集,第 9 章 (2014)

[14] F. Ricci,L. Rokach,B. Shapira,推荐系统手册介绍,第 1 章 (2011)

[15] R. Sharma,R. Singh,推荐系统从古代到现代的演变:调查 (2016)

读心术正义女士

原文:https://towardsdatascience.com/mind-reading-lady-justice-215ec8e2c2f5?source=collection_archive---------27-----------------------

使用机器学习预测法院判决

Photo by walknboston

几个月前,我正在寻找一个机器学习的兼职项目,这时我撞上了联邦承包商不当行为数据库。由非营利组织政府监督项目 (POGO)策划,数据库中的每个条目都代表一家为联邦政府工作的公司被指控违反法律或法规的事件。POGO 公开发布数据库,以阻止联邦机构与罪犯签署进一步的协议。

一个示例条目:

**Instance**            Inadequate Number of Anesthesiologists in Texas
**Contractor(s)**       Humana
**Misconduct Type**     Consumer Affairs
**Date Type**           Date of Consent Orders
**Date**                10/8/2018
**Contracting Party**   None
**Enforcement Agency**  State/Local
**Court Type**          Administrative
**Disposition Type**    Fine
**Total Penalties**     700000

上图中,你可以看到保险公司 Humana 被指控在德克萨斯州的医疗保健网络中没有足够的麻醉师。他们必须是联邦承包商才能进入数据库,但没有列出合同方,所以违规不是特定工作的一部分。德克萨斯州政府将他们告上行政法庭,最终他们被罚款 70 万美元。

我决定开发一个机器学习软件,它可以根据数据库中的其他信息预测承包商不当行为的结果。在上面的例子中,如果系统正确地预测到 Humana 将被罚款,那么它将运行良好。

还有其他机器学习系统 预测 法院案件结果。在我看来,最强有力的价值主张是,知道你胜诉的可能性有助于你决定你应该有多愿意庭外和解,这要么改善结果,要么节省时间和金钱。对于这个项目,我们可以想象,要么是被指控行为不当的承包商,要么是指控他们的执法机构,可能会为法院判决的足够好的预测买单。出于我在这里的目的,我没有考虑一些对熟悉这一法律领域的人来说显而易见的事情,例如,我的系统不知道只有当法院类型是Criminal时结果Found Guilty才是可能的。

我开始筛选我的系统可用的输入字段或特征。我放弃了日期字段,因为它的含义不一致,还放弃了承包商的身份,因为我希望我的预测器同样适用于没有事故记录的承包商。这给我留下了四个特征,都是绝对的。

High level data flow of prediction in this project

和机器学习问题一样,我的主要问题是可用的数据量有限。POGO 的数据库维护得很好,但只有大约 2500 个条目。在分离出一些测试数据后,我降到了 2000 以下。并且一键编码我的分类特征使维度数量膨胀到 112。虽然还可以更好,但这个比例符合通常使用的经验法则,即每个特性有十个训练示例。但是我也有 14 个目标类,或者可能的结果,来匹配输入,所以我没有让我的期望太高。

在建模之前,我t-SNEd 并绘制了数据:

The relatively orderly separation between the colors here implies it should be possible to make decent predictions. Click through to explore individual incidents.

准备好开始建模,我从 scikit-learn 建立了一系列标准分类器,在缺乏更具体目标的情况下,通过对所有可能结果进行平均的 F₁评分来比较它们。非线性支持向量分类器表现最好,径向基函数核 SVC 位于顶部,平均 F₁为 0.663。不是特别靠谱,但是比猜测好多了。(随机猜测处置类型但频率正确的虚拟分类器得分为 0.087。)

说客数据

不当行为数据库的前提是,政府机构倾向于错误地重新雇用有不良记录的承包商,忽略更合适的投标。如果这种偏袒是真实的,它会不会也影响到不当行为案件的判决呢?例如,如果一家公司的高管与政府决策者生活在同一个社交圈,那么该公司可能会赢得不应得的合同,也会得到监管机构的宽大处理。如果是这样的话,知道一家公司关系良好将有助于我们更好地预测他们在法庭上的结果。

我决定加入第二个数据源,这个数据源反映了一家公司在华盛顿的整体影响力。游说似乎是一个很好的起点。由于 2007 年通过的透明法,国会游说者被要求公开报告关于他们的客户、员工和活动的信息。每个季度,每个游说公司都会提交一份包含这些信息的披露表,然后以 XML 文件的形式在网上公开。

为了从披露表中获取数据,我必须编写代码来解析它们,并提取我需要的部分。这些表格是由游说公司手工填写的,标准化程度很低,具有固有的灵活结构(例如,列出的游说者人数各不相同),所以我不得不在获取干净数据时制定启发式规则。在我的探索性分析中,我很高兴地看到,无论是谁在管理众议院游说者的披露,都没有费心从生产数据库中删除他们的测试提交,留下了几十个标题类似Ms. QA Test Cycle 6.0.0的表格。

一旦我的数据提取开始运行,我试图从原始数据库中找出哪些承包商也被列为游说公司的客户。令我惊讶的是,通过编写一些简单的字符串匹配代码,我能够为其中的 70%找到说客。我从说客披露的信息中提取了几个字段,并将其添加到承包商数据集中,即:

  • 承包商是否有说客
  • 游说公司将他们列为客户的总次数
  • 这些条目下列出的个人游说者的总数

将这些特征添加到我的数据集中,并重新运行基于 RBF 的 SVC,我的平均 F₁略有提高,从 0.663 提高到 0.676。

这一结果表明,了解一家公司游说努力的规模有助于你判断他们在法庭上会得到什么结果。很难说为什么。也许公司明确地与国会议员合谋来逃避起诉。也许法官会无意识地偏袒更有声望的公司,这些公司也往往有更多的说客。也许公司雇佣了很多说客以为他们可以绕过监管,但是他们还是被抓住了。我的最佳猜测是,这只是钱的问题;在法庭上花更多钱请律师的公司,可能也会花更多钱请律师代表他们去见国会议员。

有很多方法可以改进这个项目,但是我最感兴趣的是引入另一个新的数据源。我们可以通过将游说者的数据与同一家公司更丰富的信息来源进行比较,来测试这些数据是否提供了任何独特的见解,这些信息来源在商业上有很多。另一种选择是提取与不当行为指控本身相关的特征。在法律文件上使用自然语言处理和其他技术是研究和创业的活跃领域。考虑到项目的范围,我最满意的是我能够获得两个最初看起来不相关的公开可用的数据源,并迅速将它们组合起来,以产生对我的预测器的具体改进。

你可以在这里找到我这个项目的代码。

Luke Persola 是旧金山的一名数据科学家和工程师。我目前正在寻找一个全职的数据科学职位!更在

关注机器:关于数据科学工作和人工智能未来的播客

原文:https://towardsdatascience.com/mind-the-machines-a-podcast-about-data-science-jobs-and-the-future-of-ai-a450eb67b1e1?source=collection_archive---------27-----------------------

自从我们推出sharpes minds以来,我们已经了解了很多关于数据科学就业市场的情况。我们已经采访了数千名有抱负的数据科学家,我们已经让 100 多人获得了他们在该领域的第一份工作,我们已经就人工智能的未来展开了比我们能够计数的更激烈的争论。

我们还认识了很多优秀组织中的全明星数据科学家、数据分析师和机器学习工程师,如谷歌大脑、Twitter Cortex、亚马逊、特斯拉汽车、微软等,这样的例子不胜枚举。我们从与这些有趣的人交谈中学到了很多,所以我们想与更多的观众分享一些。那就是你!

让我们知道你的想法,并在 Twitter @jeremiecharris 、 @neutronsNeurons 和 @russ_poll 上与我们联系!

程序员的正念

原文:https://towardsdatascience.com/mindfulness-for-programmers-da6f92147b8f?source=collection_archive---------22-----------------------

编程时 3 个简单的练习

Photo by Fatos Bytyqi on Unsplash

有时候我讨厌编码,就像我喜欢编码一样。我的脚本无法运行,毫无帮助的模糊错误不断在屏幕上嘲笑我,我只想用手提钻钻进我的笔记本电脑,收集球,声称周二是开始周末的合适日子。代码有严格的规则,任何有严格规则的东西在某些时候都会令人非常沮丧。这可能看起来很愚蠢,但是如果我让它发生,我不能解决的一段代码可能会毁了我一整天。

应对挫折

如果我能足够早地意识到我将变得非常沮丧,并且这可能是我最好离开一会儿或寻求某人帮助的时刻之一,我可能会挽救我的一天免受破坏,并通过打破沮丧循环为自己赢得一些时间。这就是正念发挥作用的时候。

如果我从不感到沮丧(或者我的代码非常完美,从不出错),我需要正念吗?

正念带来创造力

在我看来,编程是一门需要创造力和创新的艺术。我所知道的最好的程序员是有创造力的,并且在他们所有的项目中寻求创造力。令人惊讶的是,作家和程序员有很多共同点。如果你坐在电脑前,至少 80%的时间盯着屏幕,按照严格的语法规则书写,你可能是其中之一。虽然成为一名作家听起来像是梦想中的生活,但当许多人想象一名作家从他可爱的办公桌上看着日落,在他的笔记本电脑旁边放着一杯酒,一堆纸上潦草地写着长句时,大多数人认为程序员的生活是孤独、乏味、无聊的,浪漫主义显然已经死亡,创造力是一个愚蠢的词。

正如我在之前关于正念和创造力的文章中提到的,一个有创造力的头脑需要休息和空间。研究已经多次表明,正念练习和冥想对创造性思维有积极的效果。这对于被认为是浪漫的作家来说很重要,但对于程序员来说也很重要。

[## 为了增加你的创造力,什么都不要做。

达到目标的关键可能是简单地学习如何什么都不做。

medium.com](https://medium.com/swlh/to-increase-your-creativity-do-nothing-dcc39d7eb4d1)

断开连接

当我在编程时,我经常全神贯注于我的任务,我的大多数同事也是如此。它代表了我们最有效率、最专注、处于他们所谓的“T0”表现模式“T1”的时刻。尽管如此,我注意到许多程序员(包括我自己)当他们真正专注于他们的任务并与外界断开联系时,会变得稍微粗鲁、不体贴或只是沉默寡言。尽管专注对生产力有积极的影响,但我们大多数人都必须在团队中工作,并不是每个人都会在一天中的同一时间获得“专注时刻”。我们都没有头顶上的灯亮着,表示“走开,我在区域”当它发生时,大多数试图联系我们的人通常没有打扰我们的目的(希望如此)。当有人在可以被定义为“错误的时刻”向我寻求帮助时,注意到我现在(或曾经)在这个区域的事实帮助我做出了适当的反应。

作为一名程序员,开始练习正念的简单步骤

1。感受你的键盘

作为一名程序员和作家,我花在触摸键盘上的时间可能是全世界最多的。当你意识到你的手在一天中的大部分时间都放在一台你几乎没有联系的机器上时,这听起来可能有点悲伤。一天中的一些时刻,我试着用心打字,并意识到我的手指在知道字母在哪里方面有多快,以及留心它会使它变得更糟、更好或只是有点奇怪。像这样的小练习可以让你回到现实,让你暂时摆脱思绪。当我开始疯狂地打字,并因打字错误或感觉与任务脱节而感到沮丧时,我会试着深呼吸几次,看着自己打字的手,表现得好像它们有自己的想法。

2。引导冥想

我安装了几个应用程序(比如 Headspace 或者 Insight Time )就开始冥想了,从一周一次到一周几次。公平地说,正常的练习一开始会感觉非常奇怪。开始几次我非常不安。我坐在地板上,或者椅子上,什么也不做,观察我的呼吸,或者感觉我屁股在座位上的重量。经常出现的许多想法之一是“我到底在这里做什么?我有更好的事情要做,我太忙了,没时间听这些废话。尽管如此,我还是坚持住了,每次练习时不安的感觉一点点减少。

一些被引导的练习可以是非常灵性的,比如说联系、审视你自己等等。其他人会非常实际,会给你简单的指导,让你的头脑安静下来,进行简单的冥想练习。选择适合你的。我讨厌人们说得太多,所以既然我现在知道了冥想的基本步骤,我更喜欢使用应用 Insight Timer,因为它有一个简单的计时器(因此得名),有一首好听的轻音乐,我可以选择冥想多长时间。

3。每当你的代码运行/编译时,深呼吸几下或者站起来

每当我运行我的代码时(或者每隔一段时间,这取决于代码运行的速度),我试着活在当下,深呼吸几下,然后意识到我是否感到不安、无聊或者还好。我有时会站起来,走到厕所或咖啡机旁,在那里我会做一个简短的冥想散步,感觉我的脚接触地板,注意颜色、灯光、人和声音。当我正在解决代码中的一个错误,并希望避免再次使用手提钻钻孔时,这是一个非常有用的练习。

自己补练习!

显然,你可以利用你的日常活动和提醒(例如,在你每天站起来的时候关注你的身体姿势),自己进行任何正念练习,只要它有助于你处于当下,注意你的任务和注意他人。对于一般的日常正念练习,我很推荐《如何训练一头野象 》这本书。它和大象完全没有关系,但是如果你想从正念练习开始,它是一个很棒的工具。

"如果在正念中完成,任何任务都是麻烦的感觉将很快消失."—一行禅师

更多关于念动编程、数据科学、机器学习、AI 或领导力的文章,关注我 推特

如果你想阅读更多我的故事

[## 韧性作为座右铭:如何获得成功所需的一项技能

所有的成功故事都有一个共同点。但是这个技能可以教吗?

medium.com](https://medium.com/swlh/resilience-as-a-motto-how-to-get-the-one-skill-required-to-succeed-9c1af901082d) [## 你能成为榜样吗?

STEM 领域的女性需要更多的榜样。但是如果他们已经在外面了呢?

medium.com](https://medium.com/swlh/can-you-be-a-role-model-68e52c9f759a)

MindfulR —应用商店评论挖掘

原文:https://towardsdatascience.com/mindfulr-how-app-store-review-mining-can-boost-growth-improve-product-and-increase-monetization-4d50e20e9834?source=collection_archive---------23-----------------------

你有没有被淹没在思绪中?你希望变得更加专注和专注吗?

冥想已经被证明可以减轻压力,提高注意力,为健康、宁静的睡眠创造合适的条件。训练头脑比许多人想象的更具挑战性。因此,引导冥想应用市场有了巨大的增长,以帮助人们改善心理健康,获得更多的正念。

基于我过去在 6 个不同冥想应用中的经历,我一直想知道哪一个应用应该推荐给哪一种类型的观众。因为每个应用程序都有不同的内容,解决心理健康方面因人而异的特殊问题。所以我想:“为什么不挖掘应用评论的数据来比较这些应用呢?”。我挑选了 App Store 和我自己的经历认可的前 6 个冥想应用来分析——head space、Calm、 Insight Timer 、Oak、冥想工作室和 Shine 。

为了保持文章的简洁,我只展示了一些精选的可视化效果,并对代码进行了匿名处理。更多的可视化和数据集可以在我的 Github 上找到

[## 吉金恩/明德富尔

对顶级冥想应用的应用商店评论的自然语言处理分析

github.com](https://github.com/giginghn/mindfulR)

你准备好今天获得一些正念了吗?

本帖期待什么?

  1. 概观
  2. 数据
  3. 应用评级分布
  4. 应用评级季节性
  5. 每个版本的应用评级
  6. 情感分析
  • AFINN 词典
  • NRC 词典

7.文本挖掘

  • 二元模型分布
  • 二元关系

8.使用自然语言处理的上下文分析

  • 词性标注
  • 每个应用评论中的独特名词
  • 每个应用评论中的唯一动词

9.结论

这个帖子的灵感来自于: 的伟大作品

  1. 泰勒 西姆兰·瓦斯塔
  2. App Store 评论挖掘与 R 作者弗雷德里克·塞德洛夫
  3. 《圣经》中整齐的文字、词性、独特的词语 作者安德鲁·海斯

1。概述

为什么 app 评论分析很重要?

应用程序评论可以包含来自用户的宝贵见解,这些见解可以纳入产品改进流程,包括用户可用性、UX/用户界面、痛点、产品支持,等等!应用评论最棒的地方在于,它们经常是最新的,所以你可以利用它们来获得最新的见解。因此,利用最先进的文本分析来提高用户满意度和构建杀手级应用程序是至关重要的!

评分和评论对你的应用有多重要?

  • 应用评级揭示了用户喜爱的应用功能,这有利于市场研究和竞争分析
  • 应投入 App 评论情感分析,了解用户行为,在竞争中取得领先优势
  • 对已有产品或新产品的评论进行情感分析可以更容易地预测客户趋势,可以制定策略来利用它们
  • 根据 Bright Local 的调查,85%的消费者对在线评论的信任程度不亚于个人推荐
  • 评级和评论对应用程序在应用程序搜索结果(ASO)中的排名有很大影响
  • 应用评论可以让用户在产品改进过程中感受到参与和影响,这最终会增加用户的忠诚度
  • 据 Appentive 称,他们的研究表明,移动应用可以积极影响品牌的声誉,用户下载未知品牌的评分高的应用的可能性是知名品牌评分低的应用的 8 倍
  • 对正面和负面的评论(或错误)进行分类可以有利于 UX 的改进或特性建议,从而提高效率并促进未来的优先级

下面是一个简洁的例子,说明了文本分析如何作为基础来构建更强大的功能,以加速应用程序的增长并提高其健康程度。

2。数据

a .使用的工具:

我在这个分析中使用了大量的 R 包,但是上面的 6 个包是我用来操作和挖掘文本数据的主要工具。我将谈论我特别用于文本分析的四大工具:

  1. itunesr 是一个健壮的包,它读取 App Store review 的 API 并提取到 R

阅读 App Store API 的一个小缺点是,用户只能导出每个国家最新的 500 条评论。因此,这将导致 6 个冥想应用程序的聚合数据不具有相同的日期范围。

  1. dplyr 是 R 中非常流行的工具,被许多数据科学家广泛使用。我们将使用 dplyr 中的 tidytext 来标记评论并删除停用词。

  2. spaCyr 是 Python 中的 spaCy 和 r 之间的集成。这是用于自然语言处理的最先进的工具,如词性标注、名称实体标注、翻译等。它还可以利用机器学习来进行预测。

4.脸书预言家是一种基于加法模型预测时间序列数据的程序,其中非线性趋势符合每年、每周和每天的季节性,加上假日影响。它最适用于具有强烈季节效应的时间序列和几个季节的历史数据。 这是我在 iPython Jupyter 笔记本:D 中编写的项目中唯一的包

我将使用itunes Sr包简要介绍一下我的数据收集过程:

  1. 安装包后,我去 App Store 找我要刮的 App ID

2.将应用 ID 和国家代码一起插入到包命令中

3.出于分析的目的,我们可以

只保留美国的人口,所以我使用国家代码“us”

4.最后,我输入了行号,让它知道应该检索多少行评论,在本例中是每个应用程序最近的 500 行

b .数据帧概述

数据结构

以下是数据框的一个片段

在让你对我们的数据有一个大概的了解之后,让我们直接进入分析。我将首先向您介绍高级分析流程,然后我们开始挖掘 6 款冥想应用的季节性、情绪和独特性。

3。App 评分分布

a. App 评分分布

总体而言,这 6 款应用中的大多数在 App Store 上获得了相当高的评分。但是,有一些亮点我想指出来:

  • 可悲的是,《平静》的 1 星低评数量约等于 5 星低评数量,我们将在后面的文章中更多地讨论人们评价低的原因
  • Shine 与 calendar 也遵循类似的模式,1 星相对于 2 星、3 星和 4 星评价较高
  • 橡树对我来说是最突出的,因为它几乎没有任何 5 星评价,接受 4 星评价

b .一段时间内的评级数量

从每个应用程序的评分量可以看出,Headspace,Calm,Insight Timer 和 Shine 在 2019 年 2 月至 7 月期间都有最近的 500 条用户评论。然而,Oak 和冥想工作室没有太多的用户参与,所以他们最近的 500 条评论包含了从 2017 年到现在的评论。

4。App 评分季节性

了解平均收视率在一个月的不同日子里是如何变化的会很有趣。操纵时间序列数据来检测一周中各天的季节性,以发现季节性和高/低评级之间是否存在任何相关性,这也很重要。

首先,我们根据每月的每一天来查看应用评级的平均分布。

从这个柱状图来看,评级在整个月内波动几乎相同。因此,检查季节性图更有帮助。为了使数据平稳,并绘制出一周中各天的季节性,我使用了来自脸书预言家的时间序列包来拟合每周季节性模型。

从拟合模型中,我们可以看到 Headspace、calculate、冥想工作室和 Shine 通常在一周开始时评级较低,而在一周结束时评级攀升。另一方面,Oak 和 Insight Timer 从周一到周四有相当高的收视率,然后他们就暴跌了。

→这可用于制定策略,在应用程序中显示何时发送用户应用程序评级弹出窗口,以获得最高评级。

5。每个版本的应用评级

为了了解用户对每个具有更新功能的新版本的反应,我们可以绘制每个应用程序版本的平均评分。这将为公司提供衡量每个发布版本成功与否的大图。

6。情绪分析

在对应用评级进行整体概述后,我想全面了解每个评论的核心,以及每个词的情绪如何影响应用的整体品牌。为此,我们需要将复习句子分解成单词,这可以通过 R tidytext 中的标记化文本来完成。

机器学习和 NLP 算法中有一个常用短语——垃圾进,垃圾出。没有同样好的数据,我们不可能有最先进的结果。因此,我们首先清理和删除停用词,标点符号和罕见的短语。文字清理功能请参考我的 Github。

然后,我们在 3 种通用词典中分析情感:

  • Finn RUP Nielsen 的“AFINN”

“AFINN”词典给单词打分在-5 到 5 之间,负分表示消极情绪,正分表示积极情绪。

  • 来自赛义夫·穆罕默德和彼得·特尼。

“NRC”词典将单词分为积极、消极、愤怒、期待、厌恶、恐惧、快乐、悲伤、惊讶和信任等类别。

答)阿芬:

由于“AFINN”会根据积极/消极的程度给这些词分配一个情感分数,我计算了分数的总和以及这些词在每次评论中出现的次数,列出了计数最多的前 20 个词,并绘制了它们的分布图。

从图表中我们可以看到,6 款冥想类 app 在评论中的正面词都多于负面词,尤其是“爱”这个词在评论中出现了 2500 多次。

“焦虑”是最负面的词,这是有道理的,因为这些冥想应用程序旨在解决焦虑,并给用户带来更多的快乐。然而,如果我们看第二个最消极的词,我们有“支付”。

当我查看 6 个应用程序的订阅价格时,他们仍然收取非常高的价格——大约 59 美元到 69 美元/月。我认为情况不应该是这样的,因为这些应用程序旨在缓解压力,改善心理健康,而不是给用户增加更多的经济负担。因此,解决和改进这些应用程序,让世界各地的人们更容易使用,将是一个新出现的问题。Headspace Student 的案例是一个很好的例子,说明了这款应用如何让有需要的人买得起。

我还对每个应用程序的分布进行了细分,并绘制了积极和消极字数之间的比较。这张图表证实了我们之前的评级分布图,即 Calm 仍然是负面评价高、1 星评级多的应用程序。

为了了解应用的情绪如何随着时间的推移而发展,我们可视化了每个应用的应用评论数据中的平均情绪得分。

我们可以看到,对应用程序评论的看法随着时间的推移而波动,然而,Oak 是唯一一个应用程序评论情绪得分最稳定的应用程序,并且直到现在都在略微下降。

b. NRC 词典

NRC lexicon 是 Saif M. Mohammad 和 Peter D. Turney 在“众包一个单词情感关联词典”的研究中的惊人成果,该词典将单词分为不同的类别,而不仅仅是积极和消极的类别——愤怒、预期、厌恶、恐惧、快乐、悲伤、惊讶和信任。

请遵循他们网站上关于如何为您的项目检索数据集用于非商业用途的说明:【http://sentiment.nrc.ca/lexicons-for-research/】

对于 NRC lexicon 的最后一次可视化,我使用雷达图来查看每个应用程序中的评论如何根据这八种情绪相互叠加。

根据 NRC 雷达图,我们清楚地看到,与用户评价中的其他 5 款应用相比,Calm 缺乏“快乐”、“预期”,尤其是“信任”。同时,冷静的评论更倾向于“愤怒”和“悲伤”。

→这可能是为什么与其他应用程序相比,Calm 的差评如此之多的原因之一。但是是因为教训还是因为付出才让人对平静感到忧郁? 让我们在接下来的几个环节中一探究竟。

7。文本挖掘

到目前为止,我们认为单词是一个词,意思是个体单位,以及它们与情感的关系。然而,大多数有见地的文本分析通常基于单词之间的关系,无论是检查哪些单词倾向于紧随其他单词,还是检查哪些单词在同一文档中同时出现。这被称为 N-grams 单词分析。

通过检查单词之间的关系,我们提供了更多关于单词在评论中如何措辞的上下文,而不仅仅是情感。在这篇文章中,我在二元模型中标记了评论并分析了数据。

a .二元模型分布

在 bigrams 标记化之后,我对每个应用程序中的前 20 个词进行了排名,并绘制了它们的分布。

总的来说,大多数应用程序都提供指导冥想课程,但顿悟计时器似乎在这个功能上胜过其他应用程序。另一方面,Oak 是唯一一款提供 引导和非引导冥想 课程以及有效呼吸练习的应用。

如果我们仔细看看 Calm,除了它的主要功能“睡眠故事”和“入睡”之外,还有许多词围绕着订阅和支付问题,如“支付 70”、“70 美元”或“花钱”,而其他 5 个应用程序则不是这样。

Headspace 主要关注正念、生活方式和压力缓解,因此用户如何享受他们的指导冥想以“”是完全令人惊讶的。这很有趣,因为 Sleep Story 是 Calm 上最受欢迎的功能,现在用户正在转向 Headspace。

→在检查了 bigrams 之后,我们对 Calm 如何接受这些评论家的评论有了更好的了解,同时也揭示了用户喜爱的每个应用程序的功能。

b .二元模型关系

除了分布图之外,我们还可以查看二元模型关系网络,以便在更清晰的上下文中充分理解短语是如何相互连接的。

8。使用 NLP 进行上下文分析

我们一直在使用 tidytext 来标记单词,并应用不同的词汇来分析单词的情感。现在,我进一步尝试机器学习方法。在这篇文章的 NLP 部分,我使用 spaCy 来对标记进行词汇化,并应用词性标注(POS tagging)。这种方法的目的是更深入地挖掘每个应用程序的用户评论的独特名词和动词。

答:词性标注:

你可以通过我的 Github 找到在 R 中实现 spaCy 的代码,这里我只给你展示了词汇化和词性标注的结果数据框。

在我们跳入寻找 App 评论中独特的名词和动词之前,我们要计算每个词的 词频-逆文档频率(tf-idf) 来确定它们的独特性。Tf-idf 只是作为一个词出现在文档中的频率,但被该词在总共 6 个应用程序的评论中的频率所抵消。

在这一节中,我给出了 tf-idf 对 6 个应用程序中独特的名词和动词的概述,并只展示了一些最重要的应用程序的 wordcloud 图。

b .独特名词

以下是每个应用程序中出现频率最高的 3 个名词的 tf-idf 概述。

我们注意到 Insight Timer 和冥想工作室共享一个最常见的名词“老师”,因为这两个应用程序强调从不同的老师那里选择冥想课程的灵活性。

现在我对每个应用程序进行 wordcloud 绘图,看看每个应用程序有哪些独特的名词脱颖而出。

  • 顶空

这个图加强了我们上面的发现。尽管 Sleepcast 在 Headspace 上并不是一个大张旗鼓宣传的功能,但这个隐藏的 gem 功能显然是一个杀手级应用!此外, 友好可爱的动画 似乎极大地吸引了更多用户对应用的参与。

  • 洞察计时器

顿悟计时器专注于传统的冥想方法,因此毫不奇怪,该应用程序中最独特的名词是“”、“ 祈祷 ”、“ ”等。此外,我们可以在应用程序上发现一些杀手级功能,如 课程书签个人资料统计 。**

  • 冥想工作室

冥想工作室似乎是最好的应用程序,可以让用户选择各种各样的 冥想老师 ,并将冥想的 遗产 【传递给更多的人。""也许是冥想工作室的潜在市场利基,因为它在其他应用程序的其他地方没有提到。

b .独特动词

以下是每个应用程序中出现频率最高的 3 个动词的 tf-idf 概述。

现在让我们来挖掘这些独特动词的 wordcloud 情节!

  • 平静

我们现在完全可以理解 App Store 上差评冷静的原因了。评论中提到的大多数动词大多与认购问题相关— 【取消】【退款】【折腾】【rip】【退出】** 等。这是红旗,以冷静的价格策略来赢回用户,并有更多的战略货币化计划!**

  • 橡木

Oak 给用户一种成就感,这种成就感带有个人色彩。他们用橡木“ 【挣徽章】 ”、 上升 ”和 振动 。然而,设计或用户可用性仍然相当“”以供用户在应用程序中导航。

  • 闪耀

尽管 Shine 也面临类似的问题,如冷静对待“ ”取消 ”付款,但在 App 评论上的动词频率要少得多。另一方面,灵儿似乎做得很好,通过冥想帮助用户“ 反映 ”、“ 杂志 ”、“ 认知 ”和“ 连接

8。结论

这个项目花费了我大量的时间和精力,但帮助我学会了如何在应用商店评论中利用文本挖掘和自然语言处理,并对产品、增长和盈利产生影响。

对于那些对其他冥想应用的可视化感兴趣的人,他们可以在这里找到。请随意阅读我的 Github Repo 并摆弄数据&代码。

我知道每个单词的不同大小会有更多的改进空间,请随时通过我的 Linkedin 或 Twitter 与我分享你可能发现的任何有趣的事情。

鸣谢:我要感谢 Simran Vasta、Keith 阿蒂恩萨、陈彦蓉和 Sylvia Tran 与我分享资源并帮助我完成这篇文章。我觉得自己很幸运,在我的生命中有这么多了不起的人。

** [## 吉金恩/明德富尔

对顶级冥想应用的应用商店评论的自然语言处理分析

github.com](https://github.com/giginghn/mindfulR)**

数据科学家的最小熊猫子集

原文:https://towardsdatascience.com/minimal-pandas-subset-for-data-scientists-6355059629ae?source=collection_archive---------5-----------------------

您需要的所有熊猫功能

熊猫是一个巨大的图书馆。

对于 pandas 来说,数据操作轻而易举,它已经成为 it 的一个标准,许多并行化库,如 Rapids 和 Dask,都是按照 Pandas 的语法创建的。

尽管如此,我总的来说还是有一些问题。

在 Pandas 中有多种方法可以做同样的事情,这可能会给初学者带来麻烦。

这启发了我想出一个我在编码时使用的熊猫函数的最小子集。

我都试过了,目前,我坚持一种特定的方式。它就像一个思维导图。

有时是因为它很快,有时是因为它更易读,有时是因为我可以用我现有的知识来做。而且有时候因为知道某个特定的方式长期下去会很头疼(想多指标)

这篇文章是关于用一种简单明了的方式来处理 Python 中的大多数数据操作。

通篇都是一些零星的建议。

我将使用 IMDB 上过去十年中 1000 部流行电影的数据集。你也可以在 Kaggle 内核中跟随。

一些默认的熊猫要求

尽管 Jupyter 笔记本很好,但在与熊猫一起工作时,有些事情仍然需要详细说明。

有时候你的笔记本不会把所有栏目都给你看。如果你打印数据帧,有时它会显示所有的行。在导入熊猫时,您可以通过设置自己的一些默认值来控制这种行为。你可以使用将这个添加到你的笔记本上来实现自动化。

例如,这是我使用的设置。

import pandas as pd
# pandas defaults
pd.options.display.max_columns = 500
pd.options.display.max_rows = 500

用熊猫读取数据

我们做的第一件事是读取数据源,这是代码。

df = pd.read_csv("IMDB-Movie-Data.csv")

推荐: 我本来也可以用pd.read_table来读文件的。问题是pd.read_csv的默认分隔符是,,这样可以节省一些代码。我也真心不明白pd.read_table的用途

如果您的数据在某个 SQL 数据源中,您可以使用下面的代码。您将获得数据帧格式的结果。

# Reading from SQL Datasourceimport MySQLdb
from pandas import DataFrame
from pandas.io.sql import read_sqldb = MySQLdb.connect(host="localhost",    # your host, usually localhost
                     user="root",         # your username
                     passwd="password",   # your password
                     db="dbname")         # name of the data basequery = "SELECT * FROM tablename"df = read_sql(query, db)

数据快照

看到一些数据总是有用的。

您可以使用带有选项的简单的headtail命令来指定行数。

# top 5 rows
df.head()# top 50 rows
df.head(50)# last 5 rows
df.tail()# last 50 rows
df.tail(50)

您还可以使用以下命令查看简单的数据帧统计信息。

# To get statistics of numerical columns
df.describe()

# To get maximum value of a column. When you take a single column you can think of it as a list and apply functions you would apply to a list. You can also use min for instance.print(max(df['rating']))# no of rows in dataframe
print(len(df))# Shape of Dataframe
print(df.shape)---------------------------------------------------------------
9.0
1000
(1000,12)

推荐: 一般用 Jupyter 笔记本工作, 我特别注意让笔记本的前几个单元格包含这些数据的快照 。这有助于我随时看到数据的结构。如果我不遵循这个实践,我注意到我在代码中重复了很多次.head()命令。

处理数据框架中的列

a.选择列

出于某种原因,Pandas 允许您以两种方式选择列。像df.Title一样使用点运算符,像df['Title']一样使用方括号

我更喜欢第二个版本。为什么?

从长远来看,使用方括号版本会更好,这有几个原因。

  • 如果您的列名包含空格,那么点版本将不起作用。比如df.Revenue (Millions)不会工作而df['Revenue (Millions)]’会。
  • 如果您的列名是countmean或任何 pandas 预定义的函数,它也不会工作。
  • 有时您可能需要在列名上创建一个 for 循环,其中列名可能在变量中。在这种情况下,点符号将不起作用。例如,这是可行的:
colname = 'height'
df[colname]

虽然这不会:

colname = 'height'
df.colname

相信我。省几个字不值得。

建议:停止使用点运算符 。它是一个源自不同语言(R)的结构,应该保留在那里。

b.获取列表中的列名

您可能需要一个列列表,以便进行后续处理。

columnnames = df.columns

c.指定用户定义的列名:

有时您想根据自己的喜好更改列名。我不喜欢我的列名中有空格,所以我这样更改它们。

df.columns = ['Rank', 'Title', 'Genre', 'Description', 'Director', 'Actors', 'Year',
       'Runtime_Minutes', 'Rating', 'Votes', 'Revenue_Millions',
       'Metascore']

我本可以用另一种方式。

在这种情况下,两个版本都很重要。当我必须更改许多列名时,我使用上面的方法。当我必须更改一两个列的名称时,我会使用:

df.rename(columns = {'Revenue (Millions)':'Rev_M','Runtime (Minutes)':'Runtime_min'},inplace=True)

d.设置特定列的子集:

有时,您只需要处理数据帧中的特定列。例如,分离数字列和分类列,或者移除不必要的列。比如说在我们的例子中。我们不需要描述、导演和演员栏。

df = df[['Rank', 'Title', 'Genre', 'Year','Runtime_min', 'Rating', 'Votes', 'Rev_M', 'Metascore']]

e.查看列类型:

调试时非常有用。如果您的代码抛出一个错误,说明您不能添加一个strint,您将希望运行这个命令。

df.dtypes

在数据帧上应用函数:Apply 和 Lambda

applylambda是我在熊猫身上学到的一些最好的东西。

每当我为一个新的列或过滤器构建复杂的逻辑时遇到困难,我就会使用applylambda

a.创建列

您可以通过多种方式创建新列。

如果你想要一个列是列的和或差,你可以使用简单的基本算法。在这里,我得到了基于 IMDB 和标准化 Metascore 的平均评级。

df['AvgRating'] = (df['Rating'] + df['Metascore']/10)/2

但是有时我们可能需要围绕新列的创建构建复杂的逻辑。

举一个复杂的例子,假设我们想要基于各种因素构建一个自定义的电影评分。

比方说,如果电影是惊悚片,我想在 IMDB 评分保持小于或等于 10 的条件下,在 IMDB 评分上加 1。如果一部电影是喜剧,我想从评分中减去一分。

我们怎么做呢?

每当我掌握了如此复杂的问题,我就使用apply/lambda。让我首先向您展示我将如何做这件事。

def custom_rating(genre,rating):
    if 'Thriller' in genre:
        return min(10,rating+1)
    elif 'Comedy' in genre:
        return max(0,rating-1)
    else:
        return rating

df['CustomRating'] = df.apply(lambda x: custom_rating(x['Genre'],x['Rating']),axis=1)

一般结构是:

  • 您定义了一个函数,该函数将接受您想要处理的列值,以得出您的逻辑。在这里,我们最终使用的两列是流派和评级。
  • 沿着 axis=1 的行使用带有 lambda 的应用函数。一般语法是:
df.apply(lambda x: func(x['col1'],x['col2']),axis=1)

您应该能够使用 apply/lambda 创建几乎任何逻辑,因为您只需担心自定义函数。

b.过滤数据帧

熊猫使过滤和子集化数据框架变得相当容易。您可以使用普通运算符和&,|,~运算符对数据帧进行过滤和子集化。

# Single condition: dataframe with all movies rated greater than 8df_gt_8 = df[df['Rating']>8]# Multiple conditions: AND - dataframe with all movies rated greater than 8 and having more than 100000 votesAnd_df = df[(df['Rating']>8) & (df['Votes']>100000)]# Multiple conditions: OR - dataframe with all movies rated greater than 8 or having a metascore more than 90Or_df = df[(df['Rating']>8) | (df['Metascore']>80)]# Multiple conditions: NOT - dataframe with all emovies rated greater than 8 or having a metascore more than 90 have to be excludedNot_df = df[~((df['Rating']>8) | (df['Metascore']>80))]

很简单的东西。

但有时我们可能需要进行复杂的过滤操作。

有时我们需要做一些操作,而仅仅使用上面的格式是做不到的。

例如:我们假设 我们想要过滤电影标题中字数大于或等于 4 的那些行。

你会怎么做?

尝试下面的会给你一个错误。显然,你不能做任何简单的事情,比如用一个系列分割。

new_df = df[len(df['Title'].split(" "))>=4]
-------------------------------------------
AttributeError: 'Series' object has no attribute 'split'

一种方法是首先使用 apply 创建一个标题中包含字数的列,然后对该列进行过滤。

#create a new column
df['num_words_title'] = df.apply(lambda x : len(x['Title'].split(" ")),axis=1)#simple filter on new column
new_df = df[df['num_words_title']>=4]

这是一个非常好的方法,只要你不需要创建很多列。但我更喜欢这个:

new_df = df[df.apply(lambda x : len(x['Title'].split(" "))>=4,axis=1)]

我在这里做的是 我的 apply 函数返回一个可以用来过滤的布尔值。

现在,一旦你理解了你只需要创建一个布尔列来过滤,你就可以在你的apply语句中使用任何函数/逻辑来得到你想要构建的复杂逻辑。

让我们看另一个例子。我会试着做一些复杂的事情来展示这个结构。

我们想找到收入低于该年平均收入的电影?

year_revenue_dict = df.groupby(['Year']).agg({'Rev_M':np.mean}).to_dict()['Rev_M']def bool_provider(revenue, year):
    return revenue<year_revenue_dict[year]

new_df = df[df.apply(lambda x : bool_provider(x['Rev_M'],x['Year']),axis=1)]

这里有一个函数,可以用来写任何逻辑。只要我们能够处理简单的变量,这就为高级过滤提供了强大的功能。

c.更改列类型

我甚至使用 apply 来更改列类型,因为我不想记住更改列类型的语法,也因为它让我可以做更复杂的事情。

在 Pandas 中,更改列类型的常用语法是astype。因此,如果我的数据中有一个str格式的名为 price 的列。我可以这样做:

df['Price'] = newDf['Price'].astype('int')

但有时并不会如预期般奏效。

你可能会得到错误:ValueError: invalid literal for long() with base 10: ‘13,000’.也就是说,你不能将一个带有“,”的字符串转换为整型。要做到这一点,我们首先要去掉逗号。

在一次又一次地面对这个问题之后,我现在已经完全停止使用astype 了,只使用 apply 来改变列类型。

df['Price'] = df.apply(lambda x: int(x['Price'].replace(',', '')),axis=1)

最后,还有progress_apply

progress_applytqdm包附带的单一功能。

这为我节省了很多时间。

有时,当您的数据中有很多行,或者您最终编写了一个非常复杂的 apply 函数时,您会发现 apply 可能需要很长时间。

我见过应用程序在使用 Spacy 时花费数小时。在这种情况下,您可能希望看到带有apply的进度条。

你可以使用tqdm来实现。

在笔记本顶部进行初始导入后,只需将apply替换为progress_apply,一切都保持不变。

from tqdm import tqdm, tqdm_notebook
tqdm_notebook().pandas()df.progress_apply(lambda x: custom_rating_function(x['Genre'],x['Rating']),axis=1)

你会看到进度条。

推荐: 每当看到要创建自定义复杂逻辑的列,就想到applylambda。也尝试使用progress_apply

数据帧上的聚合:g roupby

groupby会在你想汇总数据的时候出现很多次。Pandas 通过groupby功能让你高效地完成这项工作。

有很多方法可以使用groupby。我见过很多版本,但我更喜欢一种特定的风格,因为我觉得我使用的版本简单、直观,并且可以针对不同的用例进行扩展。

df.groupby(list of columns to groupby on).aggregate({'colname':func1, 'colname2':func2}).reset_index()

现在你看到它是非常简单的。你只需要担心提供两个主要的信息。

  • groupby的列列表,以及
  • 列和要应用于这些列的函数的字典

reset_index()是一个重置数据帧索引的函数。每当我执行 groupby 时,我总是应用这个函数,您可能会认为它是 groupby 操作的默认语法。

让我们来看一个例子。

# Find out the sum of votes and revenue by yearimport numpy as np
df.groupby(['Year']).aggregate({'Votes':np.sum, 'Rev_M':np.sum}).reset_index()

您可能还想按多列进行分组。这相当简单。

df.groupby(['Year','Genre']).aggregate({'Votes':np.sum, 'Rev_M':np.sum}).reset_index()

推荐: 坚持一个语法对于groupby.不喜欢我的就挑自己的但是坚持一个。

处理多个数据帧:连接和合并:

a. concat

有时我们从不同的来源获得数据。或者有人带着多个文件来找你,每个文件都有特定年份的数据。

我们如何从单个数据帧创建单个数据帧?

这里我们将人工创建我们的用例,因为我们只有一个文件。我们首先使用已知的基本过滤操作创建两个数据帧。

movies_2006 = df[df['Year']==2006]
movies_2007 = df[df['Year']==2007]

这里我们从两个数据帧开始:movies_2006包含 2006 年发行的电影的信息,而movies_2007包含 2007 年发行的电影的信息。我们希望创建一个包含 2006 年和 2007 年电影的单一数据框架

movies_06_07 = pd.concat([movies_2006,movies_2007])

b.合并

您将遇到的大多数数据永远不会出现在单个文件中。其中一个文件可能包含特定电影的评级,另一个文件可能提供电影的投票数。

在这种情况下,我们有两个需要合并的数据帧,这样我们就可以在一个视图中拥有所有的信息。

这里我们将人工创建我们的用例,因为我们只有一个文件。我们首先使用已知的基本列子集操作创建两个数据帧。

rating_dataframe = df[['Title','Rating']]
votes_dataframe =  df[['Title','Votes']]

我们需要在一个数据框架中包含所有这些信息。我们该怎么做?

rating_vote_df = pd.merge(rating_dataframe,votes_dataframe,on='Title',how='left')rating_vote_df.head()

我们为这个合并函数提供了四个属性——第一个 DF、第二个 DF、在哪一列上连接以及连接标准:['left','right','inner','outer']

推荐: 我通常最后总是用left join。你将很少需要使用outerright.来连接,实际上无论何时你需要做一个right 连接,你实际上只需要一个左连接,在合并函数中数据帧的顺序是相反的。

重塑数据框架:熔化和透视表(reverseMelt)

大多数时候,我们并没有得到我们想要的精确形式的数据。

例如,有时我们可能有列中的数据,而我们可能需要行中的数据。

让我们再创造一个人为的例子。你可以看看下面我用来创建这个例子的代码,但是真的没关系。

genre_set = set()
for genre in df['Genre'].unique():
    for g in genre.split(","):
        genre_set.add(g)
for genre in genre_set:
    df[genre] = df['Genre'].apply(lambda x: 1 if genre in x else 0)working_df = df[['Title','Rating', 'Votes',
       'Rev_M']+list(genre_set)]working_df.head()

所以我们从这样一个working_df开始:

现在,这并不是一个特别好的存放数据的结构。如果我们有一个只有一个列类型的数据帧,我们可能会更喜欢它,并且我们可以为同一部电影重复多行。所以电影《普罗米修斯》可能有三行,因为它有三种类型。我们如何做到这一点?

我们使用melt:

reshaped_df = pd.melt(working_df,id_vars = ['Title','Rating','Votes','Rev_M'],value_vars = list(genre_set),var_name = 'Genre', value_name ='Flag')reshaped_df.head()

所以在这个融化函数中,我们提供了五个属性:

  • 数据帧名称=工作数据帧
  • id_vars:仅在当前表单中需要的变量列表。
  • value_vars:我们希望融合/放入同一列的变量列表
  • for value _ vars 的列名
  • value _ name:value _ vars 的值的列名

还剩下一件事。对于普罗米修斯,我们看到它是一部惊悚片,旗帜为 0。标志 0 是我们可以过滤掉的不必要的数据,我们将得到我们的结果。我们只保留带有标志 1 的类型

reshaped_df  = reshaped_df[reshaped_df['Flag']==1]

如果我们想回去呢?

我们需要将一列中的值变成多列。怎么会?我们用pivot_table

re_reshaped_df = reshaped_df.pivot_table(index=['Title','Rating','Votes','Rev_M'], columns='Genre', 
                    values='Flag', aggfunc='sum').reset_index()re_reshaped_df.head()

我们为 pivot_table 函数提供了四个属性。

  • 索引:我们不想改变这些列结构
  • 列:将该列分解为多个列
  • 值:使用此列进行汇总
  • aggfunc:聚合函数。

然后我们可以使用fillna用 0 填充缺失的值

re_reshaped_df=re_reshaped_df.fillna(0)

推荐: 多列对一列:melt和一列对多列:pivot_table。做melt——stack还有其他方式做pivot_table : pivotunstack.不要管他们,只用meltpivot_table。这有一些合理的原因,比如unstackstack会创建多索引,我们不想处理这个问题,而且pivot不能将多个列作为索引。

结论

有了熊猫,选择就越少

在这里,我试着描述了熊猫中我最常用的一些最有用的功能。

Pandas 是一个庞大的库,有很多功能和定制选项。这使得你必须有一个思维导图,在这个思维导图中,你要坚持使用特定的语法来处理特定的事情。

我在这里分享了我的,你可以继续下去,随着你对这个库的理解的增长,它会变得更好。

我希望这篇文章对你有用,值得你花时间。我试图让这尽可能简单,但是你可能总是问我或者查看文档中的疑问。

全部代码和数据都发布在 Kaggle 内核中。

另外,如果你想学习更多关于 Python 3 的知识,我想从密歇根大学调出一门关于学习中级 Python 的优秀课程。一定要去看看。

我以后也会写更多这样的帖子。让我知道你对他们的看法。在 媒体 关注我或者订阅我的 博客 了解他们。一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter @mlwhiz 联系到我。

尽量减少 Python 中 for 循环的使用

原文:https://towardsdatascience.com/minimize-for-loop-usage-in-python-78e3bc42f03f?source=collection_archive---------10-----------------------

蟒蛇短裤

如何以及为什么应该在 Python 代码中最小化 for 循环的使用?

Photo by Etienne Girardet on Unsplash

Python 为我们提供了多种风格的编码。

在某种程度上,它是相当包容的。

一个人可以来自任何语言,开始写 Python。

但是,学会写语言和用优化的方式写语言是两回事。

在这一系列名为 Python Shorts 的帖子中,我将解释 Python 提供的一些简单但非常有用的构造,一些基本的技巧和我在数据科学工作中经常遇到的一些用例。

在这篇文章中, 我将谈论 Python 中的 ***for*** 循环以及你应该如何尽可能避免它们。

编写 for 循环的 3 种方法:

让我用一个简单的例子来解释这一点。

假设你想在一个列表中取 的平方和。

每当我们想要计算 n 维中两点之间的距离时,这是机器学习中我们都面临的一个有效问题。

使用循环可以很容易地做到这一点。

事实上,我将向你展示三种我见过人们使用的完成相同任务的方法,并让你自己选择你认为最好的方法。

x = [1,3,5,7,9]
sum_squared = 0for i in range(len(x)):
    sum_squared+=x[i]**2

每当我在一个 python 代码库中看到上面的代码,我就明白这个人来自 C 或 Java 背景。

一个稍微大一点的的做法是:

x = [1,3,5,7,9]
sum_squared = 0for y in x:
    sum_squared+=y**2

好多了。

我没有给名单编索引。我的代码可读性更好。

但是,pythonic 的方法仍然是在一行中。

x = [1,3,5,7,9]
sum_squared = sum([y**2 for y in x])

这种方法叫做列表理解,这可能是我喜欢 Python 的原因之一。

在列表理解中也可以使用if

假设我们想要一个偶数的平方数列表。

x = [1,2,3,4,5,6,7,8,9]
even_squared = [y**2 for y in x if y%2==0]
--------------------------------------------
[4,16,36,64]

***if-else?***

如果我们想要偶数的平方和奇数的立方呢?

x = [1,2,3,4,5,6,7,8,9]
squared_cubed = [y**2 if y%2==0 else y**3 for y in x]
--------------------------------------------
[1, 4, 27, 16, 125, 36, 343, 64, 729]

太好了!!!

所以基本上遵循特定的准则:每当你想写一个for陈述的时候,你应该问自己以下问题:

  • 没有for环能做到吗?大多数蟒蛇
  • 使用列表理解可以做到吗?如果有,就用吧。
  • 不索引数组可以吗?如果没有,可以考虑使用enumerate

什么是enumerate?

有时我们既需要数组中的索引,也需要数组中的值。

在这种情况下,我更喜欢用枚举而不是索引列表。

L = ['blue', 'yellow', 'orange']
for i, val in enumerate(L):
    print("index is %d and value is %s" % (i, val))
---------------------------------------------------------------
index is 0 and value is blue
index is 1 and value is yellow
index is 2 and value is orange

规则是:

如果没有列表也可以,那就不要索引列表。

试着用字典理解

还可以尝试使用字典理解,这是 Python 中一个相对较新的功能。语法非常类似于列表理解。

让我用一个例子来解释。我想为 x 中的每个值得到一个(key: squared value)的字典。

x = [1,2,3,4,5,6,7,8,9]
{k:k**2 for k in x}
---------------------------------------------------------
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

如果我想要一个偶数值的字典呢?

x = [1,2,3,4,5,6,7,8,9]
{k:k**2 for k in x if x%2==0}
---------------------------------------------------------
{2: 4, 4: 16, 6: 36, 8: 64}

如果我们想要偶数键的平方值和奇数键的立方数呢?

x = [1,2,3,4,5,6,7,8,9]
{k:k**2 if k%2==0 else k**3 for k in x}
---------------------------------------------------------
{1: 1, 2: 4, 3: 27, 4: 16, 5: 125, 6: 36, 7: 343, 8: 64, 9: 729}

结论

最后,我要说的是,虽然将你从其他语言中获得的知识转移到 Python 中似乎很容易,但如果你一直这样做,你将无法欣赏到 Python 的美妙之处。当我们使用 Python 的方式时,它会更加强大,也更有趣。

所以,当你需要一个 **for** 循环的时候,使用列表理解和字典理解。如果需要数组索引,使用 **enumerate**

避免像瘟疫一样形成循环

从长远来看,您的代码将更具可读性和可维护性。

另外,如果你想了解更多关于 Python 3 的知识,我想向你推荐密歇根大学的一门优秀的中级 Python 课程。一定要去看看。

将来我也会写更多初学者友好的帖子。让我知道你对这个系列的看法。在 媒体 关注我或者订阅我的 博客 了解他们。

一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter @mlwhiz 联系。

原载于 2019 年 4 月 23 日https://mlwhiz.com

数据科学中最少的可行领域知识

原文:https://towardsdatascience.com/minimum-viable-domain-knowledge-in-data-science-5be7bc99eca9?source=collection_archive---------15-----------------------

Image by Gerd Altmann from Pixabay

大约十年前,当我完成物理学博士学位时,源源不断的物理学家转向金融、生物学和其他非常需要定量技能的领域。这种举动在很大程度上是由一种信念推动的,这种信念带有一丝傲慢,即一个人在攻读物理学博士学位时获得的建模专业知识可以转移到其他领域。这些举措有些成功,有些失败。据我所知,最终取得成功的物理学家是那些谦逊地认识到高效建模在很大程度上取决于某个领域的语义,并有毅力学习相关领域知识的人。

在我读完博士后的几年里,小溪变成了波浪。现在有一个从定量领域到各种工业和研究部门的大规模迁移。在完成博士学位后的某个时候,我也加入了这群领域移民——数据科学家。从我自己和我的同行的经验来看,我很确定十年前对我的物理学家同行来说是正确的,对数据科学家来说也是正确的。没有足够的领域知识,根本不可能进行有用的数据科学研究。

这不是一个新的认识。数据科学家最古老的原型来自 Drew Conway,他把数据科学家描绘成精通数学/统计、编程(黑客技能)和领域知识(实质性专业知识)的人。然而,尽管有大量的书籍、文章、课程和自助指南致力于数据科学的数学/统计和编程方面,但很少有关于数据科学的关键领域方面的文章。在这篇文章中,我将根据我和我的同龄人的经验,提出我自己对这个话题的观点。

自从“数据科学家”被宣布为 21 世纪最性感的工作,数据科学对不同的人有着不同的含义。我认为数据科学是为复杂系统建立计算模型的行为,同时利用适度到大量的数据。领域知识为构建这些模型提供了背景。领域知识有三个主要的可区分但又相互关联的方面:问题上下文、信息上下文和数据收集机制。

问题语境

如果一个人不明白自己需要解决什么,那么他解决问题的机会就很小。但是理解数据科学中的问题上下文真正意味着什么呢?考虑推荐系统的例子。没有人愿意为了建推荐系统而建推荐系统;也许一个企业想增加收入,并相信建立一个推荐系统将有助于实现这一目标。

第一步是明确并正式确定目标,例如增加收入。数据科学家构建的模型将用于计算某些东西。数据科学家需要具备领域知识,以清楚地阐明领域特定的假设,这些假设可用于将问题目标与计算的数量相关联。在推荐系统的例子中,该模型可以计算用户对产品的亲和力。使用这种计算,可以向用户显示他最接近的产品(由模型计算)。这里的假设是,如果向用户展示他们最喜欢的产品,那么他们就有更大的可能性购买这些产品,从而增加企业的收入。

通常情况下,无法直接衡量一个模型是否实现了它的目标。相反,我们需要基于代理——评估指标——来做出判断。数据科学家需要能够提供推理(最好是定量的和数据驱动的),说明为什么选择的评估指标是合适的。通常,这归结为一个归属问题。例如,可以使用点击率作为在线产品推荐系统的评估指标。然后,我们需要一个合理的模型,将一部分收入归因于推荐产生的点击。这需要数据科学家了解用户如何浏览网上商店。

给定一个模型和一个数据集,人们只能计算出一定精度的数量。通常,建立具有中等至良好精度的模型相对容易,但是需要大量投资来提高超过这一点的精度。另一方面,实际需要的准确度在很大程度上取决于手头的问题。数据科学家应该非常清楚准确性的不断提高所产生的价值。在许多情况下,价值与准确度的关系图看起来像一个 s。如果低于某个阈值,模型将生成几乎为零或负值的值,之后会有一个范围,在该范围内,准确度的小增量将导致价值的成比例或指数回报,然后会有一个阈值,在该阈值之后,准确度的任何进一步增加都将导致回报递减。值对精度图的其他轮廓也是可能的。见这篇阐述这个话题的优秀作品。只有当数据科学家很好地理解了提高准确性带来的回报(即产生的额外价值)时,他才能就什么级别的准确性足够好做出明智的决策。

数据科学问题几乎从来都不是无约束优化问题,总是存在约束。这些限制中的一些本质上是技术性的,例如对可用计算资源量的上限。其他约束将是与域相关的,例如与公平性和隐私相关的约束或者与用户体验相关的约束。数据科学家需要具备领域知识,以理解这些约束设置的界限,并确保模型保持在这些界限内——否则,模型在生产中就没有什么希望了。

如果可能的话,数据科学家会理解问题的背景

  • 将问题目标形式化,并将其与模型的计算量和评估指标联系起来
  • 至少画一个价值与准确度的半定量图表
  • 表明模型与问题的约束是一致的

信息背景

问题上下文处理模型的输出。信息语境处理其输入。围绕大数据和机器学习的大肆宣传已经在某些方面产生了的想法,即人们可以简单地将原始数据放在算法的一端,而在另一端生成有意义的见解。那个算法不存在 —深度学习或者其他。

深度学习相当成功的一个领域是图像识别(尽管考虑到深度神经网络对敌对攻击的敏感性,人们应该小心不要夸大这种情况)。如今,我们甚至有预先训练好的图像识别模型,人们可以下载并使用,只需很少甚至不需要微调。

让我们考虑一下这一成功背后的原因。图像总是由像素组成。像素具有颜色和强度的属性,并且它们总是排列在规则的网格上。出于图像识别的目的,我们希望答案在某些变换下不变,例如平移、旋转和光照变化。这些信息都不是从 math/stat 或黑客那里获得的。相反,它们是图像领域知识的一部分。在图像识别方面取得成功的机器学习模型,例如那些使用卷积神经网络的模型,就是建立在这一领域知识的基础上的。

从某种意义上说,图像识别是一个“容易”的领域。图像是几何对象,因此更容易形式化关于图像的领域知识。自然语言处理最近在建立通用模型方面也取得了一些成功。同样,虽然书面文本不像图像那样结构化,但人们仍然可以将单词识别为语言的基本实体,文档是单词的有序列表,即数据有一些自然的结构。

不幸的是,大多数领域中的数据并不具有这样的自然结构。对于大型跨国公司或研究机构来说,它们也不够大或有趣,不足以投资构建特定领域的算法。在这些领域中,由在战壕中工作的数据科学家来确定数据的信息上下文。

有人可能认为信息上下文只不过是数据中的结构。但远不止如此。算法的训练数据或模型的输入,如一组向量或张量,或有序的标记列表,它们都有结构。但是,它们本身没有任何信息上下文。信息上下文本质上由领域中可识别的概念组成——实体、关系及其属性。例如,像素(实体)、它们的颜色和亮度(属性)以及它们在网格中的相对位置(关系)形成了图像域中的信息上下文。数据科学家应该能够确定相关的信息上下文,并将其分配给数据。

强调信息背景的原因之一是可解释性。记住,可解释性总是特定于领域的。如果一个人不理解领域的概念,他就很难建立可解释的模型。但是,它超越了模型的可解释性,进入了模型的可改进性。尽管模型与数据一起工作,但建模发生在概念层面。对于一个名副其实的“数据科学家”来说,她应该能够设计出明智的策略来逐步改进模型,而不仅仅是基于试错法(hyper)的参数调整。没有对该领域的概念性理解,根本不可能设计出这样的策略。

如果可能的话,数据科学家会理解信息上下文

  • 根据实体、关系及其属性,形式化领域的相关概念
  • 将算法的训练数据集和结果模型的输入/输出映射到前面提到的概念形式。

数据收集机制

大多数(如果不是全部的话)数据驱动的建模方法对可用数据集相对于感兴趣的总体的代表性做出一些假设。在实践中,这种假设很少得到满足,这限制了人们对最终模型的信任。数据集的非代表性程度强烈地依赖于数据收集机制,而数据收集机制又依赖于领域。在其他地方,我已经详细讨论了这个代表性假设在不同的场景中是如何被违反的。我将不在这里重复讨论。可以说,数据科学家需要对数据收集机制有一个清晰的理解,以理解模型输出的健壮性。

理解数据收集机制也很重要,还有另一个原因。一般来说,有两种方法可以提高模型性能— (i)更强大的算法,(ii)更高质量和/或更多数量的数据。数据科学家需要对数据收集机制有足够的了解,以确定是否有任何手段可以获得更高质量或更多的数据。

考虑这样一个场景,我们被要求对所有在一个房间中生成的图像进行分类(包括带标签的数据)。假设我们已经建立了一个相当精确的模型。基于更强大算法的任何进一步改进都需要在算法开发方面进行大量投资。然而,假设我们可以控制房间里的照明。在这种情况下,我们可能会调整照明以获得更好的图像质量,从而更好地建模,而无需在构建更强大的算法方面进行巨额投资。

如果可能的话,数据科学家会理解数据收集机制

  • 确定由于数据集的非代表性而导致的模型的局限性
  • 设计减轻非代表性问题的技术,例如,为显示随机预测制定勘探预算
  • 建议调整数据收集机制,这可能会导致更好的模型性能。

在这篇文章的结尾,我将重申我在开头说过的话。一个人在定量领域学到的建模技能可以高度转移到其他领域。但是,你只能建立正确的模型,如果你知道什么是正确的模型。世界上所有的数学或黑客都不足以解决这个问题。花点时间去真正理解你要塑造的是什么,威尔。语境才是王道!

医学文档的挖掘和分类

原文:https://towardsdatascience.com/mining-and-classifying-medical-text-documents-1876462f73bc?source=collection_archive---------8-----------------------

临床数据科学

使用 Scikit-Learn 和 Streamlit 为自然语言处理开发和部署机器学习应用程序。

Photo by Annie Spratt on Unsplash

介绍

在医疗领域,会产生来自多个专业的大量(数字)文本文档,无论是患者健康记录、信件还是临床研究文档。事实上,文本数据,通常是非结构化,促成了全球数据量的巨大增长——仅社交媒体一项。因此,从文本中检索信息成为一项越来越重要的任务。

这篇文章的目的有两个:

  1. 演示方法为 文本挖掘文档分类用于 自然语言处理
  2. 展示使用 Scikit-Learn 和 Streamlit 在 Python 中自动生成文本分类器的应用的开发部署

最终产品看起来像这个应用程序,名称为 医学语言模型学习者(MLML) 。(原始数据可在 kaggle 上获得)。)

自然语言处理 ( NLP )是语言学、计算机科学、信息工程、人工智能的一个子领域,涉及计算机与人类(自然)语言之间的交互,特别是如何编程计算机处理和分析大量的自然语言数据。

Possible look of a Streamlit application. (image by author)

语言建模

Andrew Ng explaining embeddings, sequence models, recurrent neural networks.

嵌入

一个重要的考虑是,文本由 字符串 组成,但是数学模型依赖于数字,有不同的方式将文字转换成数字向量。另外,根据问题的定义,对语言建模有不同的可能性。一个常见的任务是将来自某个领域的序列(例如某种语言的文本/语音)映射到另一个领域的序列(例如另一种语言的文本/语音),称为 序列到序列模型 。例如,为了从文本( [文本到语音](http://An important consideration is the fact that text consists of strings, but mathematical models rely on numbers.) )生成语音,使用 递归神经网络 以及预训练的单词(例如用于单词表示的 全局向量手套)。在那种情况下,一个单词就变成了一个 n 维空间中的向量,类似于具有 n 个主成分的空间中的数据点。

不同的维度(也称为 、潜在变量 )可以被认为是描述单词的属性/特性,例如面包、水果和苹果等单词的属性“可食用”;像椅子、汽车和动物这样的词会出现在相反的方向。因此,在这个维度上,“苹果”和“椅子”会相距更远,但是“苹果”和“水果”会更近。至于“动物”这个词,这应该是中间的某个地方,因为有些动物是被吃掉的。请注意,通常不可能提取不同潜在变量的含义。

由于这些嵌入,与 1 选 1 的 K 编码方法相比,维数降低了。例如,具有 K 个单词的字典在 1-out-of-t 10】K 空间中具有 K 个维度(每个单词都是与所有其他单词正交的向量),但是嵌入可以将维度降低到 100,从而降低计算复杂度。(如果 K =10.000 且 n =100,则压缩系数为 100。)

预训练的嵌入可以下载,不必先构建。然而,每一个可能的单词都必须已经在嵌入中可用——或者嵌入必须首先被训练。嵌入是与上下文无关的,即单词“bank”在类似于“bank account”或“he sat on a bank”的表达中被视为相似。

词汇袋

或者,可以忽略语言的顺序方面,将文本建模为单词的集合( 单词袋 方法)。这是文本挖掘中最常见的表现形式,是从文本中获取高质量信息的过程。为了以这种方式描述文本,通过使用最频繁出现的单词n-grams(根据文本中的单词总数进行原始计数或归一化)来构建字典,但是这样的字典可能不太具有区分性,因为每个文本都包含像“a”、“the”、“is”等表达。****

为了解决这个问题,开发了一种叫做 词频-逆文档频率 ( tf-idfTFIDF )的解决方案;tf-idf 是一个数字统计量,旨在反映一个单词对文档集合中的一个文档有多重要。tf-idf 值与单词在文档中出现的次数成比例地增加,并根据语料库中包含该单词的文档数量进行修改,这有助于调整某些单词通常更频繁出现的事实。tf-idf 是当今最流行的术语加权方案之一;数字图书馆中 83%的基于文本的推荐系统使用 TF–IDF。

术语频率-逆文档频率

词频(针对每个文档进行计算)通常是特定单词 i (例如“子宫颈”)的计数除以文本 L 中的总单词量,从而调整文档长度。

逆文档频率通过计算包含单词 i 的文档的逆分数( N/ni )并应用对数变换来获得。出现在几乎每个文档中的单词在对数变换之前将具有接近 1 的值,因此在对数变换之后接近 0。

tf-idf 是为一组 N 文档中的每个文档 k 中的每个单词 i 定义的。它由 tf 和 idf 相乘计算得出。这样,几乎每个文档 k 中都出现的一个字 i 降低了 tf-idf 值。对于文本挖掘,在字典中保留具有低 tf-idf 值的单词是没有意义的,因为它们对于特定的文档类没有区别。

想象一下,一个数据科学家想要建立一个区分生物和法律文档的模型;他应该关注哪些单词?像“是”或“a”这样无处不在的词一点帮助都没有,但是像“蛋白质”或“合同”这样的术语有帮助——这些是有趣的。如果模型应该进一步区分生物文档的子类(更高的分辨率),它需要细化字典。例如,“DNA”、“酶”或“途径”等词在微生物学中比在生态学中使用得更频繁,而“生物多样性”、“栖息地”或“种群”等词则相反。如果期望所述更高的分辨率,可能需要更大的字典。或者,人们必须更有选择性地将最大和最小 tf-idf 值包括在尺寸为 d 的字典中。

tf-idf 计算的结果是一个维数为 N x D 的矩阵,即文档数乘以字典大小,其中填充了用作特征的 tf-idf 值T3。注意,这很可能是一个 稀疏矩阵 。此外,在矩阵构造过程中存在可调参数,并且显然 tf-idf 变换对于模型性能具有一些影响。

sci kit-作为文本文档的内置转换器学习。

**import** pandas **as** pd **from** sklearn.feature_extraction.text **import** TfidfVectorizer
**from** sklearn.preprocessing **import** LabelEncoder
enc = LabelEncoder()# Load data.
data = pd.read_csv("mtsamples.csv", index_col=0, usecols=[0,1,2,4])
data = data.dropna()
samples = data.transcription
text_labels  = [label_name.lower() for label_name in data.medical_specialty]
labels = enc.fit_transform(np.array(text_labels))# Transform data.
max_df = 0.2
min_df = 0.001
max_features = 1000
ngram_range = (1,1)tfidf_vectorizer = TfidfVectorizer(max_df=max_df, min_df=min_df, max_features=max_features, stop_words='english', ngram_range=ngram_range)tfidf = tfidf_vectorizer.fit_transform(samples)
feature_names = tfidf_vectorizer.get_feature_names()

由于有几个自由参数,Streamlit 可用于构建滑块来更改值,并手动尝试不同的组合;这样,可以快速评估许多不同的选项。

**import** streamlit **as** st
**from** streamlit.logger **import** get_logger# Title.
st.sidebar.header("Constructing dictonary of words.")# Upper bound for tf-idf value.
max_df = st.sidebar.slider("Maximum tf-idf value for a word to be considered.", min_value=0.05, max_value=0.4, value=0.3, step=0.01)# Lower bound for tf-idf value.
min_df = st.sidebar.slider("Minimum tf-idf value for a word to be considered.", min_value=0.00, max_value=0.05, value=0.01, step=0.01)# Size of dictionary.
max_features = st.sidebar.slider("Size of dictionary.", min_value=100, max_value=1000, value=500, step=100)

最终产品看起来应该是这样的。

Checkboxes and sliders. (image by author)

降维

一个可能的应用是根据医学文档的医学专业对其进行分类。一旦构建了文档-单词矩阵,并且将文本转换成数学表示,就可以使用维数减少方法,例如 截断奇异值分解 和图表库,例如 Altair 来可视化它们。

**from** sklearn.decomposition **import** TruncatedSVD
**import** altair **as** alt# Dimensionality reduction.
dim_red = TruncatedSVD(n_components=2)
data_red = dim_red.fit_transform(tfidf)# Plot.
scatter = alt.Chart(data_red,title="dimensionality reduction",height=400).mark_circle().encode(x='principal component 1', y='principal component 2', color=alt.Color('class', scale=alt.Scale(scheme='blues')),tooltip=["class"]).interactive()st.altair_chart(scatter)

Dimensionality reduction of medical documents. (image by author)

该图显示了两个主成分空间中的不同文档,解释了原始 tf-idf 空间中的最高方差。已经可以看出,这些类之间有很多重叠——至少对于构造的字典来说是这样——并且分类器的性能会很低。

数据集包含 40 个类。然而,还不知道一个特定的类在数据集中出现的频率。例如,可以预期在倾斜的数据集中,低丰度类被错误分类的频率更高,因此丢弃或合并稀有类可能是合理的。

模型结构

为了建立文本模型,可以使用任何分类算法,例如 随机森林;与 逻辑回归 相比,随机森林的优势在于可以构造任意形状的决策边界,而无需基扩展。为了找到最佳的随机森林超参数,可以执行网格搜索。

**from** sklearn.ensemble **import** RandomForestClassifier# Number of trees.
n_estimators = 1000# Define classifier.
forest_clf = RandomForestClassifier(n_estimators=n_estimators, max_depth=None, max_leaf_nodes=None, class_weight='balanced', oob_score=True, n_jobs=-1, random_state=0)# Define grid.
parameters = {'max_leaf_nodes':np.linspace(20,35,14,dtype='int')}# Balanced accuracy as performance measure.
clf = RandomizedSearchCV(forest_clf, parameters, n_iter=10, cv=3,iid=False, scoring='accuracy',n_jobs=-1)# Train/optimize classifier.
classifier = clf.fit(tfidf, labels)# Retrieve optimum.
forest = classifier.best_estimator_
feature_importances = forest.feature_importances_
indices = np.argsort(feature_importances)[::-1]

手动调整这些超参数可能也很有趣。(在当前版本中,只有一个文本输入容器,所以必须将字符串转换为整数。)

st.sidebar.header("Customizing the model.")n_estimators = st.sidebar.text_input('Number of trees in random forest.', '1000')max_leaf_nodes = st.sidebar.text_input('Maximum number of leaf nodes in a tree.', '25')max_depth = st.sidebar.text_input('Maximum depth of a tree.', '5')class_weight = st.sidebar.selectbox("Class weights for the model.",('balanced','balanced_subsample'))

Input and selection fields. (image by author)

为了解释该模型,从随机森林获得的特征重要性应该在用条形图训练之后进行评估。

# Retrieve values.
feature_importance = classifier.feature_importances_# Plot.
bars = alt.Chart(feature_importance, height=400, title="discriminative power of features").mark_bar(color='steelblue', opacity=0.7).encode(y='features:N', x='feature importance:Q', tooltip="feature importance")st.altair_chart(bars)

Feature importance of words to discriminate between documents. (image by author)

可以看出,大多数重要程度是相似的。由外袋得分确定的整体表现较低(0.41)。很可能在类别之间有太多的重叠,这由维度减少来支持。

模型评估

评估模型相对于F1 得分混淆矩阵 进行计算。

****from** sklearn.metrics **import** f1_score, confusion_matrix# Retrieve values.
y_true = labels
y_pred = classifier.predict(tfidf)# Compute scores.
f1_score_ = f1_score(y_true,y_pred,average="weighted")
cm = confusion_matrix(y_true,y_pred)# Plot.
heat = alt.Chart(source, height=500, title="confusion matrix").mark_rect(opacity=0.7).encode(x='predicted class:N', y='true class:N', color=alt.Color('count:Q', scale=alt.Scale(scheme='blues')), tooltip="count")
st.altair_chart(heat)**

F1 分数为 0.49,因此精确度和/或召回率较低。从混淆矩阵中可以看出,该模型在区分医学文档方面存在困难。目前,文档之间使用的单词似乎过于相似,即许多相同的单词在不同的医学专业中使用,或者根本找不到任何模式。

Confusion matrix for all classes. (image by author)

显然,该模型现在可以用于预测。在这种情况下,必须提供一个样本作为输入,将其转换为 tf-idf 格式,并提供给分类器,然后分类器将返回该样本属于任何类别的概率预测。

部署

应用程序中的代码应该如下所示:

**LOGGER = get_logger(__name__)def run():
   # code for appif __name__ == "__main__":
    run()**

为了在本地测试它,终端被打开并被引导到带有“app.py”文件的位置。键入以下代码启动本地测试会话。

**streamlit run app.py**

要在云提供商如 Heroku 上部署应用程序,需要一个帐户和 git 。首先,创建一个文件名为“setup.sh”、内容如下的 shell 脚本

**mkdir -p ~/.streamlit/echo "\
[general]\n\
email = \"email@website.com\"\n\
" > ~/.streamlit/credentials.tomlecho "\
[server]\n\
headless = true\n\
enableCORS=false\n\
port = $PORT\n\
" > ~/.streamlit/config.toml**

接下来,创建一个 requirements.txt 文件。它的内容应该是这样的。

**pandas
sklearn
numpy
streamlit
altair**

对于 Heroku 来说,必须编写一个所谓的 Procfile ,其中包含以下代码行——假设该应用程序名为“app.py”。请注意,Procfile 没有类型规范。

**web: sh setup.sh && streamlit run app.py**

该应用程序可以部署在终端中(这里是在 Unix/Mac 操作系统上)。为此,shell 和所有文件都是定向的。

**$ cd Documents/Projects/App**

接下来,必须在 Heroku 上创建一个应用程序(这里命名为“myapp”)。之后,使用“app.py”文件在目录中初始化 git 存储库。

**$ git init
$ heroku git:remote -a myapp**

代码被提交到存储库并部署在 Heroku 上。

**$ git add .
$ git commit -am "make it better"
$ git push heroku master**

最后,应用程序应该是在线的。

Photo by Chris Ried on Unsplash

用组学和机器学习诊断疾病

原文:https://towardsdatascience.com/mining-biomarkers-from-breath-2975740b2d24?source=collection_archive---------22-----------------------

临床数据科学

使用特征选择方法发现生物标记。

Photo by Robina Weermeijer on Unsplash

介绍

组学领域包括生物学(名称以后缀-组学结尾)中的各个学科,如 基因组学蛋白质组学代谢组学糖组学中的组学问题 中的组学问题的共同点是变量(特征)的数量远大于样本的数量,因此遭受所谓的 维数灾难 ,因此需要控制模型复杂度的方法(例如正则化)。

通过研究不同人群(例如健康和非健康患者)的基因组蛋白质组代谢组,研究人员旨在发现疾病的潜在机制,同时也发现可用于诊断/监测疾病的新的 生物标志物 。来自肺病学的一个例子(基于在医疗设备开发、生物标记发现和病理学领域的一些出版作品)很好地说明了这一点。关于 呼吸分析 、是诊断学中的一项新兴技术,能够实现呼吸成分表征。

“小”分子在肺部从血液分配到空气中,然后被呼出。这些化合物通常是属于某些代谢途径的代谢物(偶尔我们也会发现从环境中吸收的分子,如污染物/增塑剂)。疾病可以通过改变基因组、转录组或蛋白质组(例如,由于 活性位点 的突变或阻断)来扰乱路径,因此将导致代谢组的“移位”。

这个想法是通过 质谱 监测呼吸成分的“扭曲”(以及代谢组的变化)。为此目的,受试者对着一个装置呼气,在 15 到 20 分钟的短暂实验中获得呼吸成分(作为每个单独化合物的信号 强度)。相比之下,血液测试(或多或少)是痛苦的,可能需要几个小时到几天,直到测试结果出来。由于是非侵入性和快速的,呼吸分析将是临床领域的一个巨大突破。通常,在一个实验中可以测量多达两千种不同的化合物,其中一个研究问题是如何从这些数据中找到生物标志物。(例如,研究人员在最近的一项研究中研究了肺癌患者呼出气体的成分。)

在本研究中,检验了该方法的再现性再现性,并在一个月的时间内收集了四名受试者的数据。尽管没有发现病理——因为所有受试者都应该是健康的——但这里的想法是展示一些从呼吸中检索生物标志物的可能技术。

预处理

分析是在 Python 中完成的,带有像 Pandas 、 Matplotlib 和 Scikit-Learn 这样的库。首先,导入所有库。

**import** pandas as **pd**
**import** matplotlib.pyplot as **plt
from** sklearn.feature_selection **import** SelectKBest, f_classif
**from** sklearn.ensemble **import** RandomForestClassifier
**from** sklearn.manifold **import** TSNE

现在,数据被加载到具有多级索引的数据框中。

filename = 'metabolites.xlsx'
data = pd.read_excel(filename, header=0, index_col=[0,1])

在下一步中,必须清理数据。因为它包含一些现在不相关的列,所以它们将被删除(“就地”以节省内存)。

data.drop(columns=['CO2','V','Q','p'], inplace=**True**)

此外,由于测量中有许多伪像,因此去除它们也很重要。为此,太弱和太强的信号(低于/高于某个阈值的中值)被确定,并且相应的特征被丢弃(阈值由领域知识确定)。

data.drop(columns=data.keys([data.median().values<1e5], inplace=**True**)
data.drop(columns=data.keys([data.median().values>1e9], inplace=**True**)

在 104 次实验中得到的特征数是 1510。我们将通过绘制直方图来查看所有信号的分布。

fig = plt.figure(figsize=(2.95,2.95))
ax = fig.add_subplot(111)
ax.hist(data.values.flatten(), 40000, stacked=**True**, density=**True**)
plt.show()

Figure 1: Distribution of intensities across all metabolites, subjects, and experiments. (image by author)

所得的强度分布如下所示,并且数据不是正态分布的,即大多数代谢物的强度较低。其强度与血浆中代谢物的浓度成正比,也与其 波动性膜通透性 成正比。不能蒸发或不能透过细胞膜扩散的代谢物是不可测量的。

因此,如果代谢物 A 比代谢物 B 的强度更高,血液水平不一定要包含相同的关系,甚至可能完全相反——只是因为代谢物 A 可能更具挥发性或渗透性。只要存在从血液水平到信号强度的唯一映射,这就不是问题。此外,将不会有一个单独的分子作为一种特定疾病的标记,而是一整套分子,你可以想象这将更加可靠。

特征选择

Figure 2: Representation of all metabolites in all experiments. (image by author)

在将每个特征缩放到 0 和 1 之间的范围后(归一化),通过将数据绘制成图像来“从顶部”查看数据可能是有用的。首先,有一些特征(代谢物)在大多数实验中强度较低。接下来,有许多样本显示强度降低,这可能暗示了 批次效应 。最后,大多数特征以相似的方式表现,均匀地分散在 0 和 1 之间的区间中。(有可能在绘制图像之前对患者或分子集进行聚类,这称为 聚类图 。)

数据现在可以被挖掘了。提取受试者中具有不同水平的分子的一种可能性是进行单变量统计测试。由于有两组以上,方差分析( F 检验 )是选择的方法。该算法将找到最重要的分子(即具有最低的 p 值)。

selector = SelectKBest(f_classif, k=9)
data_red = selector.fit(data, data.index.get_level_values("Subject")).transform(data)
selected_features = data.columns[selector.get_support()]

由于这是一种参数方法,每个受试者的强度分布必须是正态的,这可以通过绘制小提琴图来检查。为了自动生成概述,使用了下面的代码块。

for i in range(0,9):
    to_plot = [data_reduced[data.index.get_level_values("Subject")==1,i]/max(data_reduced[:,i]),             data_reduced[data.index.get_level_values("Subject")==2,i]/max(data_reduced[:,i]),          data_reduced[data.index.get_level_values("Subject")==3,i]/max(data_reduced[:,i]),         data_reduced[data.index.get_level_values("Subject")==4,i]/max(data_reduced[:,i])] fig = plt.figure(figsize=(2.95,2.95))
    ax = fig.add_subplot(1,1,1)
    ax.set_title(selected_features[i])
    vp = ax.violinplot(to_plot, widths=0.2, points=100, showmeans=False, showmedians=True, showextrema=True)
    ax.set_ylim((0, 1.2))
    ax.set_ylabel('normalized intensity / a.u.')
    ax.set_xlabel('subject')
    plt.show()

Figure 3: Statistically significant different biomarkers. (images by author)

尽管一些分子的分布范围很广,但受试者之间的差异是明显的。这种特征选择方法的缺点是它受样本大小的驱动。对于许多样本,组间的每个微小差异都可能具有统计学意义,尽管这可能是不相关的。

一个 随机森林 也可以确定最重要的特征来区分四个主体。特征的重要性可以在训练后恢复。

forest = RandomForestClassifier(n_estimators=5000)
forest.fit(data, data.index.get_level_values("Subject"))
importances = forest.feature_importances_

Figure 4: Feature importances as determined by a random forest. (image by author)

相应的特征重要性标绘了所有有助于区分四个受试者的分子。或者,一个规则化的支持向量机神经网络会做类似的工作。请注意,这些分子中的一些(例如 C10H10、C14H24)之前已经被发现,因此这些方法之间存在一致性

结论

最后,知道受试者是否与他们自己聚集在一起,也就是说,如果每个受试者都有一些“平均”的呼吸成分,围绕着它波动,这可能是有趣的。为此,我们可以使用像 t 分布随机邻居嵌入 这样的无监督学习方法。

dim_red = TSNE(n_components=2, perplexity=30)
Y = dim_red.fit_transform(data)

标记的大小设置为与之前发现的分子之一成比例(C13H16)。

fig = plt.figure(figsize=(2.95,2.95))
ax = fig.add_subplot(111)
ax.scatter(Y[:, 0], Y[:, 1], c=data.index.get_level_values("Subject"), cmap=plt.cm.viridis, s=50*data['C13H16']/np.max(data['C13H16']), edgecolors='k', alpha=0.75)
plt.show()

Figure 5: Scatter plot that captures the complete metabolome. Each subject clusters with himself (more or less). (image by author)

事实上,受试者似乎有一种呼吸印记,这种印记在一个月的时间内或多或少是稳定的。(注意,如果使用稀疏的 主成分分析 来代替,负载的大小也可以用作特征选择方法。)

这个简短的分析表明,在不久的将来,呼吸分析可以用作诊断疾病(甚至可能识别个体)的技术。

Photo by Jair Lázaro on Unsplash

挖掘 Twitter 数据进行事件情感分析

原文:https://towardsdatascience.com/mining-live-twitter-data-for-sentiment-analysis-of-events-d69aa2d136a1?source=collection_archive---------9-----------------------

Twitter 是一个丰富的信息来源。从每分钟的趋势到围绕主题的一般性讨论,Twitter 是一个项目的巨大数据源。此外,Twitter 已经为开发人员构建了一个惊人的 API 来使用这些数据。我们能追踪一个事件,看看人们在想什么吗?随着事件的发展,有可能对世界的想法进行情绪分析吗?我们能否追踪 Twitter 数据,看看它是否与影响股市走势的新闻相关?当我最近开始挖掘 Twitter 数据时,这些是我脑海中的一些问题。

Let’s Use Twitter for Sentiment Analysis of Events

如果你更喜欢听这个博客的音频版本,我也为这个博客录了一段播客——在这里我会详细介绍每个步骤,包括注意事项和需要避免的事情。你可以在苹果播客、 Spotify 或 Anchor.fm 上听,或者在我最喜欢的播客应用之一:阴天上听。

Audio version of this available in podcast episode

让我们进入使用 Twitter 数据进行事件情感分析的步骤:

1.获取 Twitter API 凭据:

首先,访问这个链接并访问一个开发者账户。

Apply for access to Twitter API

一旦您注册,您将有权访问消费者令牌,消费者秘密,访问密钥以及访问秘密。你将需要提到申请 API 访问的原因,你可以提到“学生学习项目”或“学习使用 Python 进行数据科学”等原因作为理由。

2.在 Python 中设置 API 凭证:

将您的凭证保存在一个配置文件中,并运行source ./config将密钥作为环境变量加载。这是为了避免在 Python 脚本中暴露您的键。确保不要将这个config文件提交到 Github 中。
我们将用 Python 中的tweepy库来访问 Twitter API。它是原始 Twitter API 的一个很好的包装器,为创建 API URLs 和 http 请求提供了大量的支持。我们只需要提供第一步中的密钥,Tweepy 负责与 Twitter API 对话——这很酷。
运行pip install tweepy在您的虚拟环境中获得tweepy包。(我一直在用[pyenv](https://github.com/pyenv/pyenv-virtualenv)管理不同版本的 Python,印象非常深刻。您还需要[pyenv-virtualenv](https://github.com/pyenv/pyenv-virtualenv)包来为您管理虚拟环境——但这本身是另一个博客)
在 Python 中,您可以键入:

import os
**import json
import** tweepy
**from** tweepy **import** Stream                   # Useful in Step 3
**from** tweepy.streaming **import** StreamListener # Useful in Step 3consumer_key = os.getenv(**“CONSUMER_KEY_TWITTER”**)
consumer_secret = os.getenv(**“CONSUMER_SECRET_TWITTER”**)
access_token = os.getenv(**“ACCESS_KEY_TWITTER”**)
access_token_secret = os.getenv(**“ACCESS_SECRET_TWITTER”**)auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth)

这将设置您的环境变量,并设置可用于访问 Twitter API 数据的api对象。

3.通过流式 API 获取推文数据:

设置好凭证后,现在是时候通过 API 获取 Tweet 数据了。我喜欢使用流式 API 来过滤我感兴趣的话题的实时推文。还有 Search API,它允许您搜索历史数据,但是正如您从这个图表中看到的,它对免费访问的限制很少,最多可以访问过去 7 天的数据。对于付费计划,根据我在网上看到的情况,价格可以从 149 美元到 2499 美元/月(甚至更多)——我在 Twitter 网站上找不到确切价格的页面。

Types of Categories for Twitter Search API

要设置流式 API,您需要定义自己的类方法on_data,该方法从流式 API 的data对象中执行一些操作。

**class** listener(StreamListener):
    **def** on_data(self, data):
        data = json.loads(data)
        # Filter out non-English Tweets**if** data.get(**"lang"**) != **"en"**: **return True****try**:
            timestamp = data[**'timestamp_ms'**]            
            # Get longer 280 char tweets if possible
            **if** data.get(**"extended_tweet"**):
                tweet = data[**'extended_tweet'**][**"full_text"**]**else**:
                tweet = data[**"text"**]
            url = **"https://www.twitter.com/i/web/status/" +** data[**"id_str"**]
            user = data[**"user"**][**"screen_name"**]
            verified = data[**"user"**][**"verified"]  **                
            write_to_csv([timestamp, tweet, user, verified, url])

        **except** KeyError **as** e:
            print(**"Keyerror:"**, e)

        **return True

    def** on_error(self, status):
        print(status)

我没有包含write_to_csv函数,但它可以使用csv库实现,一些例子可以在这里看到。

你也可以将推文保存到 SQLite 数据库 esp 中。如果有几十万条推文。SQLite 还允许您通过 SQL 命令对所有信息进行命令行访问。对于 CSV,你必须在笔记本上加载一个熊猫数据框。只是看你更喜欢哪个工作流程了。通常情况下,您可以保存到 SQLite 数据库中,并使用 pandas 中的read_sql命令将其转换为 dataframe 对象。这允许我从命令行和 pandas 访问数据。

最后,运行这个函数stream_and_write来启动流 API 并调用我们上面写的监听器。最主要的是使用extended模式调用Stream API,因为它会让你访问更长的、潜在的信息丰富的推文。

**def** stream_and_write(table, track=**None**):
    **try**:
        twitterStream = Stream(auth, listener(), 
                               tweet_mode=**'extended'**)
        twitterStream.filter(track=["AAPL", "AMZN", "UBER"])**except** Exception **as** e:
        print("Error:", str(e))
        time.sleep(5)

另一件需要注意的重要事情是,您可以使用流式 API 跟踪的项目数量。在我的测试中,我无法跟踪超过 400 个左右的track列表中的项目。在构思你的想法时,请记住这一点。

4.获取情感信息:

一旦我们收集了所有的 tweet 数据,情感分析可以在上面的监听器中完成,也可以离线完成。
我们可以在 Python 中使用开箱即用的情感处理库。从我看到的,我喜欢 TextBlob 和 Vader 感悟。TextBlob提供主观性评分和极性评分。Vader提供一个posneuneg和一个compound分数。对于两个库的-1 和 1 之间的单个情感分数,使用来自 TextBlob 的polarity和来自 Vader 情感的compound
根据维达情怀的 Github 页面,

VADER 情绪分析。VADER (Valence Aware 字典和情感推理器)是一个基于词典和规则的情感分析工具,专门针对社交媒体中表达的情感,对其他领域的文本也很有效。

对于 TextBlob,

**from** textblob **import** TextBlob
ts = TextBlob(tweet).sentiment
print(ts.subjectivity, ts.polarity) # Subjectivity, Sentiment Scores

对维德来说:

**from** vaderSentiment.vaderSentiment **import** SentimentIntensityAnalyzer
analyzer = SentimentIntensityAnalyzer()
vs = analyzer.polarity_scores(tweet)
print(vs["compound"], vs["pos"], vs["neu"], vs["neg"])

将情绪信息与推文一起保存,可以让您随着时间的推移为不同的股票或事件构建情绪得分图。Vader vs TextBlob 将取决于您自己的项目,我也尝试了上述两个库的组合,但不知何故喜欢使用一个库完成不同任务的简单性。
理想情况下,你可以用对你来说重要的东西来训练你自己的情感分析模型,但这需要收集你自己的训练数据,并建立和评估一个机器学习模型。为了能够捕捉像“我期待一部精彩的电影,但结果不是”这样的句子中的负面情绪,我们需要能够处理序列数据的模型,并认识到not to be正在否定早先的amazing,这需要从神经网络中的长短期记忆(LSTM)细胞建立的模型。训练和建立一个 LSTM 情感分析网络可能是另一篇博文,如果你有兴趣阅读,请在下面留下评论。

5。剧情情感信息:

当曼联在冠军联赛四分之一决赛中 0:3 输给巴塞罗那时,我绘制了这种情绪。正如你所看到的,情绪随着时间的推移而下降,当球队在 4 月 16 日下午比赛时,情绪开始下降。

Sentiment Dropping as Manchester United lose to Barcelona

虽然情绪得分在体育赛事中表现不错,但股市呢?以下是高通(QCOM)在苹果放弃与高通的诉讼的一周内的表现(确切消息来自 4 月 16 日)。我们预计围绕这一消息的积极情绪会显著增加,但很难在下面得出结论:

QCOM stock performance during the week when their lawsuit with Apple was dropped

这使得从情感分析中提取 alpha 变得更加困难。我觉得这是一个很好的工具,可以用来观察新闻事件或体育活动的情绪,但试图将情绪与股市表现联系起来更难,因为这涉及到过滤掉嘈杂的推文,还需要做大量的特征工程工作来获得信号。

6.在 AWS 或 Google 云平台上进行设置:

你不希望在你的计算机上运行流式 API,因为当你关闭它时,脚本也会停止。您应该在 AWS EC2 实例或 Google 云平台服务器上运行它。我不打算详细说明如何设置,有很多很棒的资源可以使用[AWS和GCP]。使用tmuxscreen运行上述脚本,并在 Twitter 上访问您感兴趣的话题!

从 Twitter 上获取数据和构建情感分析引擎非常有趣。正如你所期望的那样,看到事件的向下或向上的情绪趋势是非常令人满意的。下一步将是准确地绘制情绪,而不是先保存推文,这将需要像[dash](https://plot.ly/products/dash/)这样的库。

祝你探索 Twitter 数据好运——愿你能如你所愿看到趋势!感谢阅读。

资源:
1。text blob:【https://textblob.readthedocs.io/en/dev/
2。维德:https://github.com/cjhutto/vaderSentiment3。获得 Twitter API 访问:https://developer.twitter.com/en/apply-for-access
4。比较其中一些库的博客:https://Neptune . ai/blog/情操分析-python-text blob-vs-Vader-vs-flair

在 IBM 云平台上挖掘 Twitter

原文:https://towardsdatascience.com/mining-twitter-on-ibm-cloud-platform-2adab9fb60ed?source=collection_archive---------23-----------------------

在 IBM 云存储上将 Tweets 保存为 JSON

This photo is made from a photo in this ©twitter post and ©IBM Watson Studio Logo

去年,我开始了对网络说服的多学科研究。我找不到足够的推特数据集。我需要创建自己的推特数据集,让我能够实现研究目标。

Twitter 免费 API 是有限的,根据我的经验,它会在检索 4000 条左右的推文后暂停大约 15 分钟。为了克服这一点,我使用了时间循环。我需要一个云平台来检索带有时间循环的 50 个查询的推文。

我第一次尝试从 twitter 流中检索推文是在 Watson——IBM 云平台上。Tweet 对象呈现为 JSON,因此保存它们是明智的。嗯——在 IBM 云存储上保存为 JSON 和在本地保存是不一样的。此外,以前没有人问如何做,尽管如此,回答它,所以这里是我的答案。

关于 IBM Watson studio 的几句好话:它是一个非常友好的云计算平台,尤其是对于第一次使用它的人。你可以在这里报名。点击几下之后,你就可以在 Jupyter 笔记本上工作了。你可以在这里阅读关于如何开始使用沃森工作室。

连接

在处理任何云项目时,一个必要的步骤是将您的项目连接到您的项目资源。正如我所说,Watson Studio 非常友好,只需两次点击:一次点击工具栏上的三个垂直点,第二次点击Insert project token,如下图所示:

将创建如下代码:

作为该项目的管理员,您可能需要批准这一点,但 Watson 将指导您并重新引导您。

在 Watson 上工作时,您可能需要在每次重新连接时安装[tweepy](https://www.tweepy.org/) 。为了检索推文,这些是最少的必要导入和安装:

为了连接到 twitter API ,你需要一个 twitter 开发者账户和你的账户凭证。访问您的密钥和令牌的一种方式是通过应用和应用详细信息——如果需要,您还可以在那里重新生成它们。
如此处所示:

稍后插入您的凭证,如下所示:

在连接您的项目和资源,并连接到您的 twitter API 之后,下一步是检索 tweets。

检索推文

在下面的代码要点中,有一个如何使用 tweepy 的示例,它包含过滤器、查询、语言和要检索的项数。你可以过滤推文并使用任何你喜欢的查询。

保存到 JSON

挖掘 twitter 数据的最后一步是保存它。
沃森存储上的节约语法是:

project.save_data(data=json.dumps(all_data),file_name=data.json,overwrite=True)

与本地保存 JSON 文件的语法不同:
with open(data.json, w) as f: ... json.dump(all_data, f)

在 Wason 上加载数据也只需两次点击:

它将插入连接到您的云存储的代码,将添加所需的导入,并将数据作为 pandas 数据帧读取。它看起来像这样:

使用 Watson studio 非常简单:

1.连接到云资源和 twitter API。

2.检索推文。

3.节约。

Photo by freestocks.org from Pexels

现在,至于理解 twitter 元数据?好吧,那是另一个时间的另一篇博文。

墙上的魔镜魔镜谁是他们当中最喜欢猫的?

原文:https://towardsdatascience.com/mirror-mirror-on-the-wall-who-is-the-most-cat-of-them-all-b078a0b7f632?source=collection_archive---------32-----------------------

询问训练过的神经网络对世界的看法。

Riddle me this: How does a cat look like to you?

训练神经网络

用神经网络进行图像分类现在已经不是什么新鲜事了。通常,训练神经网络的过程是这样的:

为了训练这样一个神经网络,我们需要大量的训练数据。训练数据中的每一项都由一幅图像和一个标签组成(标签告诉我们图像上显示的是什么对象)。

网络显示图像并产生一些输出(红框)。将此输出与预期结果(绿框)进行比较。考虑到网络的“错误程度”,下次它会做得更好。

神经网络的输出是一系列数字。列表的长度等于网络可以检测到的不同对象的数量(上图中为 2)。列表中的每个数字对应于该对象出现在当前图像中的概率。

逆转训练

我们已经看到神经网络是如何被训练用于图像分类的。但它到底学到了什么?

有一篇很好的博文描述了一种可视化神经网络各个部分所学内容的方法:

[## 如何用 40 行代码可视化卷积特征

发展解释网络的技术是一个重要的研究领域。本文解释了您可以如何…

towardsdatascience.com](/how-to-visualize-convolutional-features-in-40-lines-of-code-70b7d87b0030)

扩展本文的思想,我们可以使用网络来生成在特定类别中产生最高置信度的图像。例如:“生成一张你最确信是一只猫的图片。”

下图显示了实现这一目标所需的培训过程中的细微变化:

我们不是从随机网络开始,而是从随机图像开始。预期的结果是对我们想要可视化的类赋予 100%的置信度。

[## DDI 编辑推荐:5 本让你从新手变成专家的机器学习书籍|数据驱动…

机器学习行业的蓬勃发展重新引起了人们对人工智能的兴趣

www.datadriveninvestor.com](https://www.datadriveninvestor.com/2019/03/03/editors-pick-5-machine-learning-books/)

然后更新最初的随机图像,使其更符合预期的结果。运行这个程序几次(希望如此)会揭示网络认为猫长什么样。

ImageNet

对于这个实验,我使用了一个在 ImageNet 数据集上预先训练的神经网络。这个数据集包含超过 1400 万张图片,每张图片属于 1000 个类别中的一个。

我在谷歌实验室上运行了可视化程序。如果你需要帮助在 Colab 上做你自己的深度学习实验,这里有一篇博客文章,详细介绍了如何设置你的环境:

[## 为深度学习实验设置 Google Colab

不是每个人都有带 GPU 的本地机。幸运的是,你可以免费得到一个。

medium.com](https://medium.com/datadriveninvestor/setting-up-google-colab-for-deeplearning-experiments-53de394ae688) [## 在 Google Colab 上加速你的图像训练

获得一个因素 20 加速训练猫对狗分类器免费!

medium.com](https://medium.com/datadriveninvestor/speed-up-your-image-training-on-google-colab-dc95ea1491cf)

我的实现严重依赖于这个笔记本:

[## nbviewer 笔记本

想法如下:我们从包含随机像素的图片开始。我们将评估模式下的网络应用于…

nbviewer.jupyter.org](https://nbviewer.jupyter.org/github/anhquan0412/animation-classification/blob/master/convolutional-feature-visualization.ipynb)

1000 节课

既然一切都准备好了,我就开始实验。为 imagenet 中 1000 个不同的类中的每一个生成一个图像需要几个小时,但谢天谢地 GoogleColab 坚持下来了,没有崩溃。

生成的图像大多不是很有趣。我筛选了整个堆栈(是的,通过所有 1000 张图片…)并挑选了最好的。

以下是我的首选,大致分为几类。尽情享受吧!

(如果没有时间看完所有图片,可以滚动到底部。最好的在那里)

随机对象

这些图像通常显示一个对象的多次出现,相互堆叠。

衣服

水果

混搭程式

军事保护

军事武器

数字

涂鸦

技术的

工具

景色

这些图像通常不仅显示生成它们的物体,还显示某种周围的场景。

衣服

食物

运动

商店

动物

啊,是的,动物。他们不可爱吗?嗯,除了蟑螂可能…

国产+熊

昆虫

海洋的

厚皮

热带的

最好的

下面的图片是我个人最喜欢的,拼图玩具以很大优势赢得了第一名。

个人最爱

自然的

运动

技术的

就是这样。我希望你喜欢这场画展。让我知道哪个是你最喜欢的!

镜子、自动驾驶卡车、无意识偏见和机器学习/人工智能

原文:https://towardsdatascience.com/mirrors-self-driving-trucks-unconscious-bias-and-machine-learning-artificial-intelligence-24c162c55eb?source=collection_archive---------34-----------------------

https://www.youtube.com/watch?time_continue=82&v=ARJ8cAGm6JE

这个月我去拜访了我在爱尔兰的一个朋友,他刚刚改造了一所房子。她买了一面大镜子,问现场的工人是否可以把它挂在餐厅里,然后她就出去了。当她回来时,她发现虽然镜子被正确地挂在墙上,但她只能在镜子里看到自己的头顶。考虑到镜子已经存在了几个世纪,而且它们的用途也很好理解,为什么镜子被挂得这么高呢?会不会是挂镜子的人只能看到自己,而无法进入他人的体验?

给定精确的统计数据,机器人会做得更好吗?2014 年,爱尔兰男性的平均身高为 178.9 厘米(5 英尺 10 英寸),女性的平均身高为 165.1 厘米(5 英尺 5 英寸)。也许机器人在摆放位置上会更客观?

我再次阅读和与跨行业的人聊天,思考各种形式的无意偏见。对于那些喜欢了解他人思维基础的读者,你可以通过阅读这篇纽约时报文章或这篇来自麻省理工学院的白皮书来了解我的想法。还有,我刚刚开始读这本书。

让我们从一个有趣的事实开始:美国劳工统计局预计,在 2006 年到 2028 年间,55 岁及以上的美国工人的比例将从 16.8%上升到 25.2%。2018 年,55 岁以上潜在工薪阶层的比例为 23.1 %。2019 年 7 月,他们的失业率约为 2.7%。如果你从事技术和/或软件行业,看看你的办公室。你看到这些超过 55 岁的工人了吗?他们中有没有人参与针对这群打工仔的产品设计?

鉴于预测在不到十年的时间里,超过四分之一的潜在劳动力年龄将超过 55 岁,这将是机器人可能做出更理性决定的又一个例子吗?如果人们的预期是,人口中某一部分的工薪阶层将会增加,那么机器人/智能代理进行招聘是否反映了对更大的潜在客户同理心的需求?根据最近的一篇关于雇佣的文章,我们确实知道,按照人类的雇佣方式,在美国,科技工作者的平均工资在 40 岁之后会趋于稳定。

一个聪明的代理人真的会做得更好,在招聘中更少年龄歧视吗(假设相同的技能)?也许不是。基于 ImageNet 轮盘;如果把外表考虑进去的话,肯定不是。人工智能模型对训练数据的依赖意味着,同样的偏见(甚至可能被标记数据的一小部分人放大)可能会使智能代理比人类更有偏见。

https://www.travelblog.org/Photos/2494174

转向自动驾驶卡车或其他自动驾驶车辆。无人驾驶车辆的一个明显好处是,机器比人类需要更长的时间才会疲劳。人们最初可能会认为,对于卡车运输公司来说,让他们的司机在公路上睡觉,而卡车自己行驶,然后让司机接管更具挑战性的外城/内城地区或有驼鹿的山口,会更安全、更具成本效益。这种方法将保持目前每辆卡车一名司机的做法,并利用我们现有的公路基础设施。可能会增加一些州提议的卡车专用车道。

从我们对个人主义和对汽车的热爱的历史偏见中退一步,如果为了长途运输和公共交通而放弃或建设宝贵的土地是一个挑战,你将如何设计一个既能处理轻轨又能处理小型货运的系统?轮子?足迹?集装箱在下面,人坐在上面?你将如何装载它们?如果这能让变形金刚想起你的童年,那就更好了!

无意识的偏见可以被那些经验有限的人和那些“思想陈旧”的人植入非人类的“智力”中:那些年龄在 30-90 岁之间的人,他们的思想因为工作或生活环境缺乏改变而变得停滞不前。

周末愉快,尽情发挥你的想象力,挑战你的偏见!

使用机器学习进行股票投资组合选择的冒险经历

原文:https://towardsdatascience.com/mis-adventures-in-utilising-machine-learning-for-stock-predictions-a5b16199b857?source=collection_archive---------20-----------------------

多期远期预测中防止数据泄漏的痛苦

前言

作为一名初出茅庐的数据科学家,我最近建立了一个机器学习模型,以预测和选择沪深 300 指数(上海和深圳证券交易所市值排名前 300 的股票)中表现出色的股票组合。

结果很有希望,但还不够好。我的模型成功地选择了一个股票投资组合,该投资组合的表现一直优于基准指数(在 200 天的时间内累计超额收益至少为 5%),但是如果将经纪费用和滑点计算在内的话…好吧,我只能说我现在不会把钱押在我的模型的预测上!

那么我为什么要写这篇文章呢?嗯,因为我徒劳地试图搜索关于我在构建这个模型的过程中所面临的一些挑战的文章/建议,因此有了(错误的)冒险,我真诚地希望在某个地方,有一天,处于相同情况的人可以从这篇文章中得到一些用处。或者我发现我真的不擅长网上搜索。无论哪种方式,学习都会发生!

问题陈述

使用机器学习模型,结合基本面和技术指标,预测和选择由沪深 300 指数股票组成的投资组合,其表现将优于基准指数。

数据

数据的主要来源是对晨星的试用订阅。

使用的技术特征是:

  1. 两个周期之间收盘价的百分比变化
  2. 两个周期之间收盘价的指数加权移动平均值的百分比变化
  3. 每日收盘价的差异
  4. 平均营业额
  5. 两个周期之间每日交易量的指数加权移动平均值的百分比变化
  6. 每日交易量的差异

这些都是为不同时期或不同时期的排列计算的。

使用的基本特征是:

  1. 股本回报率
  2. 利润率
  3. 利润变化
  4. 收入变化
  5. 价格收益比
  6. 市净率
  7. 价格销售比

这些数据都来自季度财务报告,并根据其行业名称进行了标准化(使用晨星的行业名称)

为防止数据泄露,季度财务报表数据将仅在该季度结束后一个月使用,因为这将是上市公司发布季度财务报表的最后日期。

此外,使用的主要经济指标有:

  1. 中国财新制造业 PMI
  2. 中国财新服务业 PMI
  3. 中国国家统计局制造业采购经理人指数
  4. 中国国家统计局非制造业采购经理人指数
  5. 中国消费价格指数
  6. 中国 GDP 同比

为了防止数据泄露,经济指标数字只在公布后的下一个交易日使用。

Quick peek at the feature space

由于只有 10 个季度的财务报表,我可以用来建模的数据时间范围只有 2017 年 10 月至 2019 年 11 月。

此外,由于一些公司的财务报表中缺少一些字段,我原本打算投资 300 只股票,但现在只投资了 225 只。

尽管如此,这仍然是一个不错的数据块。没问题!然而…

(错误的)冒险开始了…

挑战:防止多期远期预测中的数据泄漏

我设法找到的关于股票预测的大部分(如果不是全部的话)倾向于一个时期的前瞻性预测。那些展望未来多个时期的通常属于自回归类型。

这也不是我对这个模型的想法。

我真的不希望为这个模型创建一个高/中频算法策略,因为我通常采取基本的交易方法。该模型的主要目的是识别股票的实际交易价格和假定内在价值之间的重大差异,这些修正将需要多个周期(至少几天)才能实现,如果它们真的发生的话。

因此,假设持有期为 5 期,将目标变量建立在未来 5 期的收盘价上是有意义的,对吗…?

All done!

唉,事实并非如此。

例如,如果培训拆分于 2019 年 10 月 28 日结束,则 2019 年 10 月 22 日至 2019 年 10 月 28 日的 5 期提前收盘价格实际上仍然未知。

The target Close prices boxed in red cannot be used!

虽然我使用 240 个周期进行训练,并且我的 X 变量实际上不包括日期,但这个看似很小的泄漏实际上导致了我的预测结果的巨大(并且完全没有根据的)超越。

为什么不直接去掉 X 变量的最后 5 个周期呢?因为这导致了我的预测结果表现严重不佳(这一次,完全有理由)。

解决方案:在一个训练周期的每个可能的截止日期对数据进行切片,并在移位时使用该周期的最后收盘价作为填充值。

对每个训练期的数据进行切片,可以确保“未来”的收盘价不会被包含在内。然后,我们可以继续向前移动收盘价,并使用该期间的最后收盘价作为填充值。

If it’s stupid but it works… it might still be stupid.

在这里,如果股票在 5 天持有期结束时的表现超出基准指数 5%以上,则观察值被标记为正 1 级。

然后,将这些目标变量的切片集添加到字典中,该字典可以由模型针对每个特定的训练期调用。

我不认为这是一个优雅的解决方案,因为在使用这些填充值时,目标变量可能会被贴错标签。但是将这一考虑与训练期最后几天获得的信息进行权衡,我认为这是值得的,因为它确实提高了我的模型的结果。

当然,如果有人能想到更优雅的解决方案,请分享!

结论

这似乎是一个很好的休息的地方,现在结束这篇文章,并衡量这是否对任何人都有帮助或感兴趣。如果是这样的话,我很乐意享受我在这个项目过程中遇到的后续不幸,例如尝试使用 GridSearch 来调整分类模型的超参数,其中模型的(离散)预测的准确性并不能真正反映股票投资组合的实际(连续)价格。甚至是一些有效的方法。

因为最终每一个股票选择模型都是根据它的表现来评估的,所以这是我的模型。该模型的预测(蓝线)在 200 个交易日内产生了高于基准指数(橙线)10%的累积超额收益,但这是假设没有经纪成本和交易滑点…所以,是的,还有很长的路要走。

The model’s portfolio generates 10+% of accumulated excess returns over the benchmark index for a 200 trading day period

再说一次,我只是一个初出茅庐的数据科学家,我总是渴望听到并向在座的各位学习。这仍然是一项正在进行的工作,我绝对欢迎社区的任何意见或建议!

感谢您的阅读,欢迎随时通过 Linkedin 联系我!

数据和统计误导。

原文:https://towardsdatascience.com/misleading-with-data-statistics-c6d506bdb9cf?source=collection_archive---------6-----------------------

统计在我们的生活中扮演着重要的角色。我们每天都在有意识或无意识地使用它们。如今,数据无处不在,由于我们系统的信息过载,做出正确的决策变得越来越困难。如果应用正确,统计学可以让我们更好地处理和理解我们周围的世界。我们应该能够根据更完整的信息做出更好的决策。但是如果统计数据是误导性的呢?

如果有人想骗你相信一些你本不该相信的事情,该怎么办?调整数据及其统计结果的螺丝钉在哪里?这篇文章带你走过使用数据统计时的陷阱。目标是理解操作数据的最常见的实践,并避免由于误导信息而做出错误的决策。

数据和统计的问题。

数据在辩论中有很大的力量和权威。这是一个挑战:经常有一个编造的数字来强调一个扯淡的故事。但是由于这个数字的权威性,如果这个数字是真的,我们就不那么怀疑了。一个来自锐步旧广告的真实例子很好地展示了这种效果:

“与普通运动鞋相比,这款鞋被证明可以让你的腿筋和小腿增加 11%的力量,让你的臀部增加 28%的弹性……只需步行!”。

这听起来太权威了——基于锐步可能在非常激烈的研究中收集的数据。将其与以下没有具体数字的版本进行比较:

"这只鞋会让你的腿筋和小腿变得更硬,还能锻炼你的臀部."

事实是,这些数字完全是捏造的,该品牌必须为第一次声明支付巨额罚款。但是怎么才能防止自己被困住呢?

了解根本原因

无论是在商业、科学还是你的私人环境中,如果你了解“错误”数据的根源,你就能避免被它误导。在处理数据时,陷阱可能出现在每个步骤中。因此,本文揭示了处理数据时最常见的陷阱。

生成数据时的陷阱

每个数据科学家面临的最具挑战性的任务之一是获得正确的数据来处理。对于正确的数据,我们指的是最真实地反映人口或“真实世界”的样本。通过下面探讨的各种不同技术,在数据采集过程中可能会发生一些操作或陷阱。让我们来看三个常见的例子:

糟糕/有偏差的采样 使用非随机样本的数据在历史上发生过多次,这是糟糕预测和误导数据的开始。发生在样本选择上的重大错误,排除了一个真正具有代表性的要素。

典型的例子是总统选举中糟糕的民意调查抽样。1948 年,《芝加哥论坛报报》刊登了“杜威打败了楚门”,这是基于实际选举前的一次电话调查。那时电话还不是标准。它们主要是为上层阶级提供的。但是当意识到样本不是随机的时,已经印了几千份了。上图是杜鲁门总统手里拿着一个假新闻样本在笑。

Truman holding the “Fake News”.

加载问题 每当涉及到生成数据时,这些数据必须来自一个中立的资源。加载题恰恰相反。它们已经包含了一个不合理的或有争议的假设,目的是操纵输出。一个很好的例子是产品经理向他们的用户征求反馈:“你喜欢我们为你打造的产品的什么?”这个问题已经暗示了用户喜欢这个产品。如果你想收集一些反馈并自我吹捧,这很好——但这与生成有用的数据或统计无关。

错误轮询 与加载问题密切相关的是错误轮询。它通常用于影响相应样本的答案。

“你认为我们应该帮助不稳定的国家保持自由和民主吗?”

和...相对

"你支持我们在其他国家与他们的现任政府进行军事斗争吗?"

你可以清楚地看到这两个问题的区别和抹黑运动。第一个试图支持国家干预,第二个试图相反。在许多情况下,看一下民意测验是非常有意义的——你通常会获得比答案本身更多的见解。

处理数据的陷阱

一旦完成数据生成和采集,就对数据进行处理。数据转换、清洗、切片和切割会产生许多误导性的结果。下面是三个最常见的问题:

挑选/丢弃不利的数据 在研究中,你得到一个大数据集并不得不处理它是很常见的。在最好的情况下,研究问题已经被定义,研究者有一定的压力产生结果。但是如果发现的结果不是很有趣呢?如果你有那么多数据,会产生有趣的结果,尽管它们只是一种信心。通过丢弃不利的数据或从数据集中挑选一些片段,人们很容易产生有趣的结果。

Temperature Anomaly 2002–2013 (Source: NASA)

气候变化就是一个很好的例子:为了强调气候变化始终如一且不会改变的说法,数据的时间范围往往局限于 2000 年至 2013 年。如果观察这个特定的提取物,它可能看起来温度异常总是相同的。

只有在包括完整数据框架的大图中,正温度异常的强烈和快速变化才变得可见。

Temperature Anomaly Complete (Source: NASA)

显著性&质量 我们经常看到实验被进行,结果被呈现,没有统计学意义。在商业环境中,这在所谓的 A/B 测试中经常发生。

A/B 测试环境中的统计意义是你的实验的原始版本和测试版本之间的差异不是由于错误或随机机会造成的可能性有多大。例如,在一个带有绿色按钮的测试版本中,7%的转化率并不一定意味着它比转化率为 5%的替代样本表现得更好,如果你只有 200 个访问者的样本大小的话。有几个选项可以确保你的假设的显著性,要么通过标准化软件,要么通过我们自己计算。在这里你可以找到一个计算器来检查你最后一次 A/B 测试的重要性。

数据挖掘 数据挖掘(Data Dredging)也称为 p-Hacking,描述的是在没有任何焦点和假设的情况下分析一个数据集的过程。通过寻找和测试重要变量的不同组合,大量的假设将被测试。如果你在 p 值的帮助下测试很多假设,很可能你有一个 1 型(或 2 型)错误。原因很简单,因为有太多的测试,错误地拒绝或接受假设的统计概率增加了。但是让我们来看一个你可能在商业生活中经历过的真实例子。

在之前的文章中,我们预测了客户是否会流失,这具有统计学意义。但是让我们假设你有一个糟糕的数据集,并且你的测试显示没有统计学意义。然后你开始为每一个客户特征创建一个假设。然后砰——最后你的测试表明你的一个假设很重要:“金发的客户两年后更有可能流失。”

通过运行如此多的测试,一个随机假设可能会显得有意义,仅仅是因为进行了如此多的测试。但事实上结论是“假阳性”——这意味着测试有 5%(95%的显著性水平)的几率出错。

数据交流中的陷阱

每当统计数字和数据被用来支持创作者的意图时,建议不时地对其进行批判性的审视。

数据可视化 尤其是在数据可视化方面,人们喜欢做一些小的调整,这对信息消费者来说意义重大。用图表误导人的方法有很多。以下是最常见的一些摘录。

  • 截断的 y 轴:在基线不为零的情况下比较数据时,如下图所示的数据可视化可以比以前更生动。

Same Data — different Y-Axis

  • 遗漏数据,通常称为“省略数据”,指的是图表中缺少几个数据点,例如只显示第二年的每个数据点。解释和决策是基于一半的信息。
  • 不适当的缩放:这种方法通常用于时间序列或随时间的变化,并在两个方向上起作用:要么 y 轴不适当地增加,因此变化似乎不太强烈。或者为了使效果看起来比以前更有决定性,不恰当地降低了 y 轴。

错误的因果关系/结论

虽然在数据中发现有统计学意义的见解是增加价值的开始,但你还必须能够正确地解释结果。如何不解释结果的一个很好的例子是亚伯拉罕·瓦尔德和丢失弹孔的故事。长话短说,二战期间他是统计研究小组的一员。空军向 Wald 提出了一个问题:太多的飞机被击落,而简单地增加 armpur 的整体重量会使它太重。他们问如何有效地增加装甲。

(Hypothetical Image)

沃尔德调查了从战场返回的飞机,收集数据并进行分析。他发现了子弹多的地方和子弹少的地方。首先,直觉上认为应该在子弹较多的地方放置更多的装甲。但这是错误的结论。由于统计样本是返回的飞机,子弹完整较少的区域是重要的区域,可能目标击中了没有返回的飞机。

“先生们,你们需要在没有洞的地方放更多的装甲板,因为那些没有返回的飞机上的洞就在那里。”—亚伯拉罕·瓦尔德

隐藏上下文

有用的数据可视化使大量数据易于理解和解释。观众应该能够看到展示的数据并快速找到重要信息。如果出现过多或不相关的数据,观众可能看不到相关信息。一次显示的数据越多,就越难发现具体趋势。用太多的数据误导通常是用来误导观众从小的,但相关的见解。

结论

统计数据很有可能被滥用。尤其危险的是它以某种权威来强调每一个论点的力量。“如果有明确的证据,甚至一个数字这么说,那么它一定是正确的”,这是观众经常的反应。尽管基于误导性数据和统计数据的错误决策非常有用,但数据也有能力提供深刻的见解,推动更好的决策,并允许做出预测。那么我们该怎么办呢?

通过了解产生误导性数据和统计数据的一些最常见的过程,我们大大减少了自己陷入困境的机会。通过以负责任、可理解和道德的方式正确部署数据和统计,我们积极地为一个更好的知情世界做出贡献——这听起来是不是一个令人惊叹的未来使命?😃


您可能感兴趣的其他已发表文章:

应用机器学习算法提高创业估值

消除流失是增长黑客 2.0

动手:预测客户流失

了解如何创建自己的样本数据集


缺失数据和插补

原文:https://towardsdatascience.com/missing-data-and-imputation-89e9889268c8?source=collection_archive---------12-----------------------

缺失的数据会扭曲研究结果,增加计算费用,并使研究人员感到沮丧。近年来,处理缺失数据在生物和生命科学等领域变得越来越普遍,因为我们看到了管理不当的空值 的非常直接的后果。对此,有更多样的方法来处理出现的缺失数据。

这对于提高研究的有效性来说是非常好的,但是对于那些积极主动的数据科学家来说却有点棘手。这篇博客文章将向您介绍一些处理缺失数据的有用概念,并让您开始使用一些现在就可以尝试的切实可行的方法来清理 Python 中的数据。

Photo by Carlos Muza on Unsplash

为什么要做任何事?

您可能会问自己—为什么我需要处理丢失的数据?为什么不让睡觉的狗躺着?首先,缺失值(称为 NaN、Null 或 NA)会带来计算上的挑战,因为。想一想——如果你要对一列数值求和,发现少了一个,那么 5 + NA 是多少?如果我们不知道等式中的第二项,我们的结果本身就是 NA。所以我们真的不能从丢失的值中得到任何有意义的东西,而且它混淆了大多数期望处理非空情况的程序。

除此之外,丢失数据还会导致三个主要问题:

  1. 偏见
  2. 更费力的处理
  3. 结果效率降低

这些都是丢失数据的非常严重的副作用(如果不仅仅是恼人的话),所以我们想找些事情来处理我们的空单元格。这就是“归罪”的由来。

插补

《韦氏词典》分享了“估算”一词的“金融”定义,即“通过对其贡献的产品或过程的价值进行推断,为某物分配一个价值这绝对是我们在这里要思考的——我们如何才能推断出与缺失的真实值最接近的值?

作为一个题外话——思考和考虑这个术语可能来源于它的神学背景是很有趣的。在这里,它的意思是“归因于正义、罪恶等的行为或过程”。对一个与另一个人有相似品质的人,"如"使徒们的著作告诉我们,如果我们接受基督,基督的义的诋毁是给我们的。"只是我们前进时的一些思考。

缺失数据机制

在研究插补时,您可能会发现数据缺失有不同的原因。这些原因是基于它们在缺失数据机制缺失和观察值之间的关系而给出的术语。它们帮助我们找到合适的数据处理方法,因此对有一个基本的了解真的很有帮助。以下是 4 个最典型的 3 个,你可以在“分析因素”上了解更多。

  1. 完全随机失踪(MCAR)

这可能是最容易想到的—在这种情况下,数据以完全一致的速度丢失。例如,一个缺少 5%来自青年调查的响应的数据集。这是因为在进行调查的那一天,所有学生中有 5%请了病假,所以在整个数据集中,这些值的缺失率是一致的。

2。随机失踪(三月)

尽管名字相似,但 MAR 值比 MCAR 值更复杂,也更容易找到。这些例子表明,如果我们知道另一个变量,丢失数据的比率就可以得到完美的解释。例如,想象上面的数据集缺少 10%的女生回答和 5%的男生回答。这是因为在学校传播的疾病影响年轻女性的可能性是年轻男性的两倍。这变得更加复杂,也更加现实,因为多个变量会影响数据集中缺失值的比率。

3。非随机缺失(MNAR)

在这种情况下,某个值的缺失取决于真实值本身。这是一个非常循环的例子,但是我喜欢这个视频中给出的例子,在一项图书馆调查中丢失价值的比率,该调查收集了他们的名字和未归还图书馆书籍的数量。随着囤积书籍数量的增加,这个调查问题中缺失值的百分比也在增加。这个方法的问题是,因为丢失的值依赖于值本身,我们很难推导出它丢失的比率。

Python 中的实用探索与可视化

在用 Python 处理数据时,Pandas 是一个强大的数据管理库,用于组织和操作数据集。它的一些术语来源于 R,并且是建立在 numpy 包之上的。因此,它有一些令人困惑的方面,值得在丢失数据管理方面指出。

内置两个功能,熊猫。DataFrame.isna() 和熊猫。DataFrame.isnull() 实际上做完全同样的事情!甚至他们的文件都是一样的。你甚至可以在熊猫的代号中确认这一点。

这是因为熊猫的数据框架是基于 R 的数据框架。在 R 中,na 和 null 是两回事。阅读这篇文章了解更多信息。然而,在 python 中,pandas 构建在 numpy 之上,numpy 既没有na 值,也没有空值。相反,numpy 有 NaN 值(代表“不是一个数字”)。因此,pandas 也使用 NaN 值 。

此外,名为missingno的 Python 包是一个非常灵活的、用 matplotlib 构建的缺失数据可视化工具,它适用于任何 pandas 数据框架。只需pip install missingno开始,查看这个 Github repo 了解更多。

A “missingno” visualization of cyclist dataset — with Sparkline on the side

充分可视化丢失的数据是理解您正在处理的丢失数据机制以及丢失数据的规模和要处理的热点的第一步。

单一插补方法:

从最简单的开始,向更复杂的方向发展,下面描述了处理缺失值的一些最常见的方法及其相关的优缺点。

(请注意,数据集中的一项或一行被称为“观察值”)

  1. 行(列表式)删除:去掉整个观察。
  • 简单,但是会引入很多偏差。

An example of listwise deletion

2.均值/中值/众数插补:对于所有非缺失的观测值,计算该变量观测值的均值、中值或众数,并用其填充缺失值。数据的分布是决定使用哪个描述符的必要信息。

  • 如果缺失数据少于 3%,可以使用,否则会引入太多偏差,并人为降低数据的可变性

3.热卡或冷卡插补

“热卡插补”:找出所有其他变量相似的样本对象,然后随机选择其中一个值填写。

  • 很好,因为受到预先存在的值的约束,但是随机性引入了隐藏的可变性,并且计算量很大

“冷板插补”:系统地从在其他变量上具有相似值的个体中选择值(例如,每个集合的第三个项目)。该选项消除了热卡插补的随机性。

  • 受到预先存在的值的积极约束,但是随机性引入了隐藏的可变性,并且在计算上是昂贵的

Example of basic hot deck imputation using mean values

4.回归插补

“回归插补”:填写缺失变量在其他变量上回归得到的预测值;你不是只取平均值,而是根据其他变量取预测值

  • 保留插补模型中涉及的变量之间的关系,但不保留预测值的可变性。

“随机回归插补”:回归的预测值,加上一个随机残差值。

  • 这具有回归插补的所有优点,但增加了随机成分的优点。

单一估算的挑战

这些都是处理缺失值的好方法,但是它们确实包含了标准误差中未说明的变化。下面的“分析因子”再次完美地解释了这种权衡:

由于估算的观测值本身是估计值,它们的值有相应的随机误差。但是当你把估计值作为数据点输入时,你的软件并不知道。因此,它忽略了额外的误差源,导致标准误差和 p 值都太小。”

此外,单一插补中的值可能会因当前数据集中的特定值而有偏差,并不代表全部人口的总值。那么我们如何减少这两个挑战的影响呢?

多重插补

大约 20 年前,多重填补是统计学上的一个巨大突破,因为它解决了许多缺失数据的问题(尽管,不幸的是,不是全部)。如果做得好,它导致无偏的参数估计和准确的标准误差。

单一插补为缺失观察变量提供了一个单一值,而多重插补为缺失观察变量提供了多个值,然后对它们进行平均得到最终值。

Examples of “data signatures” from different samples

为了获得这些平均值,多重插补方法将对数据集的 5-10 个独特样本进行分析,并对每个**进行相同的预测分析。该点的预测值将作为该运行的值;这些样本的数据签名每次都会改变,这导致预测略有不同。这样做的次数越多,结果的偏差就越小。

一旦你取了这些值的平均值,分析它们的分布是很重要的。如果他们是聚类,他们有一个低标准差。如果不是,可变性很高,可能是值预测不太可靠的迹象。

虽然这种方法更加无偏,但是它也更加复杂,并且需要更多的计算时间和能量。

结论

最后,我们看了看:

  1. 处理数据集中缺失值的重要性
  2. “插补”的意义(和根源)
  3. 数据可能丢失的不同原因(丢失数据机制)
  4. 在 Python 中探索和可视化缺失数据的方法
  5. 单一插补方法
  6. 多重插补的一种解释

但这只是一个开始!关于这个话题的更多信息,请查看本帖的链接资源。

**热卡和随机回归都适用于多重插补。这是因为估计值的随机成分使每个估计值略有不同,重新引入了软件可以在建模标准误差中包含的变化。

缺失数据?

原文:https://towardsdatascience.com/missing-data-cfd9dbfd11b7?source=collection_archive---------14-----------------------

减轻痛苦的框架和软件包

Photo by Markus Spiske on Unsplash

在我成为一名数据科学家的旅程开始三个星期后,我正式接受了洗礼……也就是火的洗礼!我选择参加 Flatiron 的数据科学 15 周训练营,以从金融领域转型。到目前为止,这个项目已经超出了预期(我的期望很高)。虽然课程很严格,节奏很快,但它的结构很好,教师致力于帮助学生学习,我的团队很棒——每个人都很友好,乐于助人,聪明,毫无疑问会继续完成伟大的事情。这一系列的博客文章是献给他们的…为未来的数据科学家干杯!

我们在课堂上涵盖了大量的信息,所以当我在课外发现一些有助于提高我的观点或技能的东西时,我会用接下来的几篇帖子来分享它。我也期待着阅读我同学的帖子!更广泛地说,本系列面向对数据科学感兴趣的任何人。

在学习数据科学时,首先认识到的一点是数据清理非常耗时(许多人认为这是工作中最不愉快的方面)。估计显示 60-80%的时间花在清理和组织数据上,只有很少一部分时间花在分析上(有趣的部分)。有了这个统计数据作为背景,我想我应该分享一些我发现的有用的技术和库,以使数据清理过程更容易。具体来说,我将重点讨论如何处理丢失的数据。我是一个视觉学习者,我喜欢框架,所以这篇文章的目的是通过提供一个识别和处理缺失数据的基本过程

  1. 介绍“缺失数据机制”——对缺失进行分类的标准词汇(对缺失数据的处理有影响),以及
  2. 演示 Python 的用处缺少 库。

一些背景信息…对于这个分析,我使用了 Titanic 数据集,因为它易于访问(你可以在这里下载它)并且它不需要领域知识来理解数据(例如,不像医疗保健数据)。我没有把它分成训练集和测试集,因为这里的目标只是覆盖(和发现)缺失数据的问题。最后,所有代码都是 Python。

步骤 1:做一些探索性的数据分析(EDA)

EDA 对于理解数据集的特征以及(特别是与当前主题相关的)发现任何可能隐藏的缺失值是至关重要的。你可以用无数种方式来分析泰坦尼克号的数据,但这里有一些我制作的图表,应该足以满足我们的目的。

Insights from EDA help inform treatment of missing data

第一行按性别划分人口。如你所见,男性数量超过女性,比例约为 65/35。然而,在生存问题上,雌性占优势。接近 75%的女性存活下来,相比之下只有不到 20%的男性存活。对于任何看过泰坦尼克号的人来说,这并不奇怪——妇女和儿童首先登上救生艇。总的来说,男女的平均年龄非常接近(女性 27 岁,男性 29 岁)。

第二行是事情变得更有趣的地方。我们看到船上大多数人都是 3 等(换句话说相对贫穷)。大多数伤亡属于第三类也就不足为奇了;穷人最后才登上救生艇,如果有的话。另一个观点是,不同阶层的中值年龄差异很大。最后,所有第二行图表上都有一个神秘的问号——它是一个伪装成真实值的空值!

从 EDA 中,我们已经获得了一些关键的见解,这些见解将延续到我们对缺失数据的分析中。我们必须转换“?”转换为空值/缺失值,并决定如何处理它,我们知道乘客等级和性别可能会成为我们可能需要做的任何插补的因素。

步骤 2:识别数据中缺失的类型

缺失数据机制

Source: From my research, this is the consensus framework for treating missing data

识别缺失类型有助于缩小处理缺失数据的方法范围。缺失数据机制是标准框架。其中,有三种类型的缺失:

  1. 完全随意失踪(MCAR)。缺失值与观察到的或缺失的数据集中的其他值没有关联。“没有任何系统性的事情发生,使得一些数据比其他数据更有可能丢失(分析因素)。”例如,如果一个班里的几个学生有一天因为他们自己的原因碰巧缺席,那就是 MCAR。
  2. 随意失踪(MAR)。“缺失值的倾向和观察到的数据之间有系统的关系,但是没有缺失数据。”此外,还有一个无法直接观察到的潜在原因。继续我们的课堂例子,现在是流感季节,一些学生生病了。
  3. 不随意遗漏(MNAR)。缺失和它的值有关系,缺失或非缺失。某种价值的缺失,取决于真正的价值本身。扩展前面的例子,假设有一个全州范围的标准化考试日,许多学生缺席。也许对标准化考试没有安全感的学生最有可能缺席。缺失数据是否因为实际值而缺失是一个很难回答的问题。在我们的课堂例子中,问题是最有可能在考试中表现不佳的学生是否被遗漏了。

有一些测试可以诊断缺失数据的类型,如 MCAR 的Little’s Test,但是区分 MAR 和 MNAR 的唯一正确方法是测量一些缺失数据。然而,这在大多数情况下是不可能的,因此对缺失类型的分类实际上是分析缺失数据中的模式,并依靠领域专业知识来指导决策。幸运的是,有一个简化缺失模式评估的库。

探索缺失数据的一个好方法是用 missingno 可视化它。首先要看的图表是无效矩阵。在泰坦尼克号的数据集中,在我们替换了“?”之后值为空值时,矩阵显示有四列数据缺失(乘客等级、年龄、客舱分配和乘客登机的港口)。您可以对功能集中的任何列进行排序,以观察缺失之间的潜在关系。Pclass 和 Age 中有缺失值,但它们似乎与其他缺失值不相关。这是 MAR 的典型情况,因为可能有无法直接观察到的丢失值的原因。在这种情况下,悲剧发生后很难保存记录。

Nullity Matrix from Missingno Library

另一个伟大的可视化是条形图。它给出了每个特征的缺失程度的更多细节。我们看到,Pclass 丢失了大约 5 %, Age 丢失了 20 %,而 Cabin 几乎丢失了。

Bar Chart from Missingno Library

最后两个图表允许我们进一步探索相关性(即列之间缺失的相关性)。热图函数显示不同要素的缺失值之间没有强相关性。这很好;低相关性进一步表明数据是错误的

Heatmap from Missingno Library

树状图功能创建缺失的树形图。它通过将相似的缺失列分组来描述缺失的相关性。特征为零,完全预测对方的存在。一个变量可能总是为空,而另一个变量被填充,或者它们可能总是都被填充,或者都为空(没有遗漏文档)。查看泰坦尼克号数据集,船上的失踪倾向于更类似于 Pclass 而不是 Age 等等。

Dendrogram from Missingno Library

步骤 3:处理缺失的数据

既然我们已经确定了数据中的缺失,让我们讨论一些处理它的主要方法。

删除。优点:简单;CONS:假设 MCAR 并引入偏见,如果不是 MCAR 的话。下面重点介绍了三种类型,但您可以在⁴.的统计解决方案找到更全面的讨论

  • 列表式删除(完整案例分析)删除有一个或多个缺失 values⁴.的记录的所有数据
  • 成对删除(可用案例分析)利用记录中没有丢失的特征。例如,相关性衡量两个变量之间的强度。对于每一对有数据的变量,相关系数将把这些数据考虑进去。因此,成对删除可以最大限度地利用 basis⁴.分析的所有可用数据
  • 当特征的大部分数据为缺失值时,执行列删除

单一插补。

  • 均值/中值插补通过用集中趋势的测量值替换缺失值来完成。优点:相对简单;CONS:减少差异
  • 热甲板法是一种将缺失值与具有非缺失值的相似观测值进行匹配,并用相似的非缺失 observation⁵.值对缺失值进行估算的技术两种方法是最近邻法和匹配模式法。优点:受教育程度更高;CONS—计算成本更高,耗时更长
  • 单一回归插补中,数值由回归方程预测。具有完整特征的观测值用于预测缺失数据的值。因为单一回归假设缺失值落在回归线上,所以它减少了 variance⁵.
  • 随机回归旨在通过用残差项增加每个缺失值的预测值来减少偏差。以这种方式,方差被保留,并且估计是无偏的

多重插补。优点:不偏不倚;CONS:复杂

  • 链式方程多元插补(MICE) 是较为流行的多元插补方法之一。多重插补比其他缺失数据方法有许多优势。建立多重插补,而不是单一插补,说明了插补的统计不确定性。此外,链式方程方法非常灵活,可以处理不同类型的变量(例如,连续变量或二元变量)。多重插补涉及多次填充缺失值,从而产生多个“完整的”datasets⁶.

敏感性分析

  • 最佳-最差和最差-最佳情况敏感性分析可用于显示由于缺失数据导致的不确定性范围。敏感性分析可以显示不同于主要分析的假设如何影响 obtained⁷.结果参见这篇来自 BMC 医学研究的论文以获得进一步的解释。当您的数据是 MNAR 时,这是最佳解决方案。否则,收集更好的数据。

结论

在本文中,我提供了一个有用的框架和库,用于分类和可视化丢失的数据。在本系列的剩余部分,我将对缺失的泰坦尼克号数据应用上述的一些插补方法,并探索每种方法的效果。

参考

[1] G. Press,清理大数据:最耗时、最不愉快的数据科学任务,调查显示 (2016),福布斯

[2] K. Grace-Martin,如何诊断缺失数据机制 (2019),分析因素

[3] Bilogur, Missingno:一个缺失的数据可视化套件 (2018),开源软件杂志,3(22),547

[4]统计解决方案,缺失数据:列表式与成对式,统计解决方案博客

[5] I. Eekhout,单一插补方法,Iris Eekhout 博客

[6] M. Azur,E. Stuart,C. Frangakis,P. Leaf,链式方程的多重插补:它是什么,如何工作? (2011),《国际精神病学研究方法杂志》

[7] J. Jakobsen,C. Gluud,J. Wetterslev,P. Winkel,在随机临床试验中,何时以及如何使用多重插补法处理缺失数据——流程图实用指南 (2017),BMC 医学研究方法 17,162

R 中 tidyverse 的值可视化缺失

原文:https://towardsdatascience.com/missing-value-visualization-with-tidyverse-in-r-a9b0fefd2246?source=collection_archive---------11-----------------------

关于如何使用 ggplot2、dplyr、tidyr 查找和可视化缺失数据的简短实用指南

在探索性数据分析(EDA) 期间,寻找缺失值是一项重要任务。它们会影响机器学习模型的质量,需要在训练模型之前进行清理。通过检测缺失值,您还可以评估数据检索过程的质量。这个简短的实用指南将向您展示如何找到缺失的价值,并通过 tidyverse 生态系统将它们可视化。 tidyverse 是数据科学的 R 包集合。在他们的主页上写道“…所有的包共享一个潜在的设计哲学、语法和数据结构。”

数据集

该数据集是从一个电子商务网站上刮下来的,包含产品数据。您可以通过评估缺失值来检查数据检索的质量。具有大量缺失值的要素可能表明该要素的提取逻辑存在问题,或者数据由于其他原因而缺失。

df %>% 
   head(10)

数据集包含 11 个变量,共 2172 行。

缺少值的表

您可以对数据集中每个要素的缺失值进行计数:

missing.values <- df %>%
    gather(key = "key", value = "val") %>%
    mutate(is.missing = is.na(val)) %>%
    group_by(key, is.missing) %>%
    summarise(num.missing = n()) %>%
    filter(is.missing==T) %>%
    select(-is.missing) %>%
    arrange(desc(num.missing))

您可以使用 tidyr 的 gather 函数将列折叠成键值对。然后,创建一个新的逻辑特征,在缺少值的情况下该特征成立。您对键和新逻辑特征进行分组以进行计数。然后过滤逻辑特征以获得缺少值的计数。您跳过不需要的行,并根据缺少的值的数量进行排序。

可视化丢失的数据

表格及其行和列由我们的语言系统读取。这个系统非常慢。

图形与我们的视觉系统互动,比语言系统快得多。这就是为什么在大多数情况下你应该使用图表而不是表格的原因。

您可以在 ggplot2 中用一个简单的条形图直观显示上面的聚合数据集:

missing.values %>%
  ggplot() +
    geom_bar(aes(x=key, y=num.missing), stat = 'identity') +
    labs(x='variable', y="number of missing values", 
         title='Number of missing values') +
    theme(axis.text.x = element_text(angle = 45, hjust = 1))

您可以通过计算每个要素缺失值的百分比来改进该图。这样更有意义。通过交换轴可以改善视觉外观,使特征名称更具可读性。根据长度对条进行排序是另一个改进。正确的轴标签总是必须的。使用红色作为缺失值(=坏)的视觉提示是因为红色代表危险,你必须采取行动。

missing.values <- df %>%
  gather(key = "key", value = "val") %>%
  mutate(isna = is.na(val)) %>%
  group_by(key) %>%
  mutate(total = n()) %>%
  group_by(key, total, isna) %>%
  summarise(num.isna = n()) %>%
  mutate(pct = num.isna / total * 100) levels <- (missing.values  %>% filter(isna == T) %>%     
           arrange(desc(pct)))$keypercentage.plot <- missing.values %>%
      ggplot() +
        geom_bar(aes(x = reorder(key, desc(pct)), 
                     y = pct, fill=isna), 
                  stat = 'identity', alpha=0.8) +
        scale_x_discrete(limits = levels) +
        scale_fill_manual(name = "", 
                          values = c('steelblue', 'tomato3'), 
                          labels = c("Present", "Missing")) +
        coord_flip() +
        labs(title = "Percentage of missing values", 
             x = 'Variable', y = "% of missing values")percentage.plot

在这个图中,您以与前面类似的方式汇总数据:不是计数,而是计算百分比。然后将数据链接到 ggplot 可视化部分。

该图显示您在产品尺寸(dim_x,dim_y,dim_z)的特征的抓取过程中遇到了问题:几乎 100%的值都丢失了。您可以看到 sales.rank、sales 和 reviews.count 有相同数量的缺失值。这些值似乎相互关联。

您可以通过绘制数据集中的每一行来以另一种方式显示缺失值,以获得进一步的见解。

row.plot <- df %>%
  mutate(id = row_number()) %>%
  gather(-id, key = "key", value = "val") %>%
  mutate(isna = is.na(val)) %>%
  ggplot(aes(key, id, fill = isna)) +
    geom_raster(alpha=0.8) +
    scale_fill_manual(name = "",
        values = c('steelblue', 'tomato3'),
        labels = c("Present", "Missing")) +
    scale_x_discrete(limits = levels) +
    labs(x = "Variable",
           y = "Row Number", title = "Missing values in rows") +
    coord_flip()row.plot

这个图可以让你发现我们的条形图中找不到的模式。您可以看到不同要素的缺失值之间的联系。

特性 sales_rank 和 sales 的缺失值实际上是相互关联的。这是你所期望的。在条形图中,您可以看到 reviews_count 具有大约相同百分比的缺失值。您可能会期望与销售和销售排名相关联。我们的第二个图显示没有关联,因为值在不同的行中丢失。

您可以用 gridExtra 包将这两种可视化合二为一。

grid.arrange(percentage.plot, row.plot, ncol = 2)

结论

您以两种方式可视化了数据集中的缺失值,这为您提供了关于数据集中缺失值的不同见解。这样,您可以找到数据抓取器逻辑中的弱点。您可以看到 ggplot2 中的图形语法和 dplyr 中的数据操作语法是非常强大的概念。

2019 年 2 月 5 日由延斯·劳弗撰写

随意分享!

原载于 2019 年 2 月 5 日【jenslaufer.com】

缺少值—不要丢弃它们!

原文:https://towardsdatascience.com/missing-values-dont-drop-them-f01b1d8ff557?source=collection_archive---------21-----------------------

作为我招聘过程的一部分,我让潜在的数据科学候选人进行数据挑战。数据挑战要求候选人接受提供的数据,通过模型开发过程,并以分类模型结束。除非我在高层招聘,否则我不会期望整个数据科学工作流程尽善尽美——在高层,我会寻找一种深思熟虑、符合逻辑的方法来解决手头的问题。这通常暴露在代码的前 50 行中,其中候选项基于缺失值的任意阈值丢弃特性。我见过 40%、80%以及介于两者之间的各种水平。我也看到过因为缺少一个值(超过 100 个特征中的一个)而丢弃整个观察值的情况。由于这种… 激进的缺失值处理方法,一名候选人最终放弃了超过 50%的观察值。

最终,阈值并不重要,重要的是我们放弃了这些特性,甚至没有考虑特性是什么,以及缺少值意味着什么。实际上,我最后明确地问过一个候选人这个问题。我收到了大约 10 个连续的数据挑战,每个挑战都丢失了 70%以上的值。她的挑战的其余部分相当不错,所以我直截了当地问她,在没有探索这个特性的情况下,你怎么会认为这是个好主意呢?她的回答大致是“我在网上看到有人这么做了。”再说一遍,这些都是初级角色,我不追求完美。然而,这不是我获得工作的方式——我们可能无法就解决问题的正确方法达成一致,但我需要执行某些步骤的合法理由。

随机与系统缺失值

我们正在处理的缺失价值观在我们如何对待它们的问题上扮演着重要角色。在的报告(第 2.1 节,但实际上,您应该阅读全部内容)中,阅读关于系统和随机缺失值的内容是非常值得的。此外,一个奇妙的旁注, pyvtreat 现在在 PyPi 上发布!

不管怎样,系统的和随机的缺失值有什么区别,更重要的是,为什么有关系?

  • 系统性的:值缺失有一些逻辑上的原因。有可能这个特性不适用于观察。
  • 随机:数据收集随机失败,缺少值没有特定的业务/流程原因。可能导致随机缺失值的几个例子是传感器故障或流程中断。

这是两种截然不同的情况,因此应该区别对待。在我们有系统性缺失价值的情况下,缺失的价值对整个过程有意义——它的缺失是有原因的。这使得总括方法成为一种无效的方法——我们应该仔细考虑如何处理每个特性的缺失值,而不仅仅是考虑这种适当的处理:

df.fillna(0,inplace=True)

具体例子

我在这里经常引用的例子是 Lending Club 数据集中的一个特征,自上次拖欠以来的几个月。大约少了 65%。这个特性测量的是贷款申请人有一个拖欠账户已经有多长时间了,这在表面上看起来很重要,但是很多申请人最终放弃了它!回想一下随机缺失值和系统缺失值,您认为这种情况会发生在哪里?这很可能是一个具有系统性缺失值的功能,它之所以缺失是因为它不适用,或者更明确地说,他们没有拖欠账户。以下是我见过的一些针对这一特征(以及所有其他特征)的处理方法:

  • 用 0 填充—这告诉我们的算法,自他们上次拖欠以来已经过了 0 个月(意味着它基本上发生在昨天)。这给了我们的算法大量不正确的信息和噪音
  • 用中位数填充——这个没那么可怕,但是真的不准确。同样,我们假设这是一个系统性缺失的值。填充中间值意味着 50%有过犯罪行为的人口有更长的时间,因此看起来风险更小。在现实中,这可能会为算法创建一个令人困惑的非线性关系,因为中位数两边的数据可能比中位数风险更大。
  • 放下观察/特写——阅读文章标题!

关于违约率的一些信息以及它与这一特性的关系。如果价值较低,比如不到一年,违约率约为 24%。随着拖欠时间的增加,该值呈下降趋势,最终约为 21%。没有拖欠债务的人口的违约率徘徊在 18%左右。这个特性中肯定有一些预测能力,而上述方法不允许这个特性以它所能达到的预测能力运行。相反,我们有办法填充这个值,以防止算法迷失在噪声中。

  • 用负数填充—这对于基于树的模型或其他非参数方法特别有用。这里的真值应该≥ 0,所以负数会把这个总体拆分成一个单独的类别。但是如果我处理的是线性模型呢?
  • 填入一个较大的值-拖欠时间越长,该客户的风险越低,因此我们可以填入一个较大的值,向我们的模型表明该人群的风险低于其余人群。

如果我选错了方法怎么办?

所有这些都有点像猜谜游戏。很多时候,很难真正知道这些值是随机丢失的还是系统丢失的,除非您公司的数据收集实践非常强大且记录良好,并且非常了解上下文以及它与您的分析的关系。如果我选择了错误的方法会发生什么?有一件事你应该永远做,努力给你的算法完整的信息,万一你选择了一个令人难以置信的可怕的方法。有一件事(同样来自精彩的 vtreat 论文):创建一个新的二进制特征,作为该值最初是否丢失的标志。如果您的新要素缺失,则该要素的值为 1,如果有值,则该要素的值为 0。对于这一具体特征,这基本上是一个“他们是否有过拖欠”标志,它显然对你的预测非常有帮助。

数据科学是一个艰难的领域,要求候选人和从业者在处理问题的方式上具有逻辑性和智慧。数据科学工作流程中最具挑战性也是最重要的部分之一是处理杂乱的数据。你处理这件事的方式显示了你将手头的问题概念化并提出一个可靠的解决方案的能力,同时为你的模型提供了巨大的提升。这一步带来的提升几乎和特性工程一样重要,但是后面会有更多的介绍!

有问题吗?反馈?想聊聊数据科学和数据策略?伸出手来!https://www.linkedin.com/in/brettnebeker/

错误的身份:为什么媒体使用人形机器人来代表人工智能是个坏消息

原文:https://towardsdatascience.com/mistaken-identity-why-the-media-using-humanoid-robots-to-represent-ai-is-bad-news-c2c1e8a9cb62?source=collection_archive---------24-----------------------

用闪闪发光的银色机器人男人的图片来代表 AI,一直都很讨厌。这也有损害行业的风险。

“Am I the problem?”

在 2018 年的一篇伟大的文章中,亚当·盖特吉痛斥“人工智能的真正丑闻:糟糕的股票照片”。他捕捉到了“拨弄键盘的机器人手指”和“1998 年的机器人通用 3D 模型”的天真和可预测性,这些模型用于说明关于人工智能的文章。当时,最佳实践人工智能团队正在整理成千上万的文章,以建立我们开放的人工智能用例及案例研究库,所以这一点很重要;我们笑了,并热情地转发了这篇文章。

本周,我在英国上议院就人工智能问题向跨党派议会小组提供了证据。我在台上与埃森哲(Accenture)和微软(Microsoft)等公司的名人讨论企业采用的障碍。一个反复出现的话题是高管教育。显然,人工智能和机器学习不是简单的话题——理解它们需要时间,我们仍在计算新技术将产生什么样的经济和商业影响。闪亮的银色机器人通常被用来说明解释这一切的文章。

但我越来越清楚,闪亮的机器人插图正在为技术和行业积累问题。

  1. 首先,它设定的期望值太高。狭义(以任务为中心的工具)和一般(一般人类智能)人工智能之间的区别很重要。后者离科学的飞跃还有一段距离——前者就在我们身边。然而,将这种技术想象成闪闪发光的银人表明,这种技术是关于后者的,并将在一夜之间改变世界。不会的。
  2. 其次,它误导了 AI 可以和应该用于的东西。如果被认为是更平凡的东西——“有态度的电子表格”是一种讨论中的描述——那么它将更好地帮助非技术人员想象他们可能使用技术做什么。
  3. 这表明人工智能的主要潜在商业利益是通过工作自动化取代人类。研究人工智能的组织刚刚开始将他们的问题从“这项技术能做什么?”到“使用这项技术的投资回报率(ROI)是多少”?在这里,人形机器人的心理形象是有问题的,因为它推动了对自动化和用机器人取代人类工作的关注。到目前为止,人类工作替代的例子比宣传的更有限。众所周知,自动取款机的引入与银行职员数量的增加是并行的,类似的事情也可能发生在客服聊天机器人身上。
  4. 这让高管们很难看到人工智能带来的真正商业利益。当机器开始阅读来自病人的医疗扫描时,在商业或社会层面上,受益的将不是看扫描的员工数量的潜在减少。这将是一个消除流程瓶颈和引入常规先发制人扫描的机会,从而挽救许多人的生命。扩大以前的短缺具有巨大的经济和社会效益——而这并不是通过估算(边际)FTE 减少量来最好理解的。
  5. 它强化了人工智能潜在的恶性形象——模糊了“人工智能伦理”问题的真正来源。电影 iRobot 向我们展示了漂亮闪亮的银色机器人成为黑暗面的代理人,迎合了几代人关于机器背叛其制造者的负面故事。更紧迫的是,人们更容易相信这些算法是“种族主义者”或“性别歧视者”,而不是相信它们被灌输了糟糕的人类生成的数据。如果我们围绕人工智能的伦理问题沟通不畅,那么解决这些问题将变得更加困难。
  6. 最后,这将有助于对感知的“炒作”产生过度反应。在未来几年的某个时候,人们将评估人工智能分娩的现实。自动驾驶汽车还需要 5 年时间。闪亮的银色机器人仍将是虚拟的。他们会失去兴趣。对他们来说,这将是一个错误——就像 2000 年 dot.com 股灾后远离互联网一样。因为人工智能将改变世界——只是(还)不是以人形的形式。

因此,这不可避免地提出了一个问题——使用什么样的图像更好?感谢你的想法。

Get real

数据科学家犯的十二个错误

原文:https://towardsdatascience.com/mistakes-data-scientists-make-e915abd3b2df?source=collection_archive---------19-----------------------

成为更好的数据科学家

Nepal — photo by author.

专家是在一个非常狭窄的领域里犯了所有可能犯的错误的人。

尼尔斯·玻尔——量子物理学家

本文列出了我自己和其他人在学习和实践数据科学时经常犯的错误。

模式存在于科学家犯的数据错误中——在这里你也可以从中学习:

  1. 不标绘目标,
  2. 不考虑维度,
  3. 学习率太高,
  4. 不去想错误从何而来,
  5. 不理解偏差和差异,
  6. 对全连接神经网络的宽度和深度的痴迷,
  7. 不关注 PEP 8,
  8. 不放弃目标,
  9. 不缩放目标或特征,
  10. 在开发过程中不使用数据样本,
  11. 覆盖原始数据,
  12. 不使用$HOME 存储数据。

1.不标绘目标

预测是数据科学家和数据分析师的区别。数据分析师分析过去,数据科学家预测未来。

数据科学家通常使用监督机器学习来进行预测。监督学习的基本过程是使用特征x来预测目标y

理解目标的分布是任何监督学习项目的第一步。目标的分布会影响数据科学家的许多决策,包括:

  • 使用什么模型,
  • 是否需要缩放,
  • 如果目标具有应该被移除的异常值,
  • 如果目标不平衡。

我们预测的目标可以是连续的数字(回归),也可以是离散的类别(分类)。

回归目标

在回归问题中,数据科学家希望了解目标的以下信息:

  • 最小值和最大值,
  • 目标是如何正常分布的,
  • 如果分布是多模态的,
  • 如果有异常值。

直方图将回答所有这些问题,使其成为在回归问题中可视化目标的绝佳选择。下面的代码生成了一个包含四个分布的玩具数据集,并绘制了一个直方图:

直方图显示了生成该数据集的两个正态分布和两个均匀分布。

分类目标

在分类问题中,数据科学家希望了解目标的以下信息:

  • 有多少个班级,
  • 班级的平衡程度如何。

我们可以用柱状图来回答这些问题:

柱状图表明我们有三个班级,并且表明我们的“做梦”班级代表不足。

2.不考虑维度

维度为理解世界提供了结构。

低维数据的价值

低维表示比高维表示更有价值。这是因为在低维空间做决策更容易。

以决定是步行还是乘公共汽车为例——这个决定取决于是否下雨。

如果给你一个天气的高维表示(比如卫星图像中的像素),在你决定如何旅行之前还有很多工作要做。

相反,如果您可以访问天气的低维表示(例如下雨的概率),则可以仅使用单个阈值参数来做出决策。商业中的许多其他决策都是低维的——比如去/不去或者一个项目或者雇佣/不雇佣。

请注意,数据科学家的大部分工作都是使用机器学习来降低维度:

  • 使用卫星图像中的像素来预测太阳能输出,
  • 使用风力涡轮机性能数据来估计未来故障的概率,
  • 利用客户数据预测客户终身价值。

每个低维输出可以被一个业务方式使用,而高维数据不能

与高维原始数据输入不同,低维输出可用于决策:

-太阳能输出可用于指导能源交易商的行动,
-高风力涡轮机故障概率可导致派出维护团队,
-低客户寿命估计可导致营销预算资金减少。

以上是预测和控制相互作用的例子。你越能预测这个世界,你就越能控制它。

这也是数据科学家的工作定义——做出导致行动的预测——改变企业运营方式的行动。

高维数据的挑战

在高维空间工作的困难是维度的诅咒

为了理解维数灾难,我们需要对数据的空间密度进行推理。

我们可以想象一个密集的数据集——在一个小空间内有大量不同的样本。我们也可以想象一个稀疏的数据集——一个大空间中的少量样本。

当我们添加维度时,数据集的密度会发生什么变化?它变得不那么密集,因为数据现在更加分散。

然而,随着维度的增加,数据密度的降低不是线性的,而是指数性的。随着维度的增加,空间变得更加难以理解。

为什么增长是指数级的?因为这个新维度不仅需要根据其他维度(线性)来理解,还需要根据其他维度与其他维度的组合来理解

这种组合与其他组合一起导致指数增长。

这是维度的诅咒——随着我们增加维度,空间呈指数增长。下面代码显示了这种效果:

空间的大小越大,机器学习模型需要做的理解工作就越多。

这就是为什么在没有信号的情况下添加功能是痛苦的。模型不仅需要了解它的噪声,还需要考虑噪声如何与每隔一列的每个组合进行交互。

数据科学工作流中应用维度诅咒的四个领域

从理论上理解维度是第一步。接下来是在数据科学的日常实践中应用它。下面我们将通过几个实际案例来说明数据科学家无法将维数灾难应用到他们自己的工作流程中。

1.过多的超参数

数据科学家可能会浪费时间进行过多的网格搜索——在时间和计算上都很昂贵。复杂网格搜索的动机来自一个好的地方——对好的(甚至是完美的)超参数的渴望。

然而,我们现在知道,只增加一个额外的搜索就意味着训练模型的指数增长——因为这个新的搜索参数需要结合其他所有搜索参数进行测试。

另一个错误是窄网格搜索 —在小范围的超参数上搜索。对数标度比小的线性范围更能提供信息:

不同的项目需要不同数量的网格搜索,包括模型和它们的超参数。我发现我经常构建两个网格搜索管道:

-一个用于比较不同的模型(使用迄今为止为每个模型找到的最佳超参数)
-一个用于比较单个模型的不同超参数

我将从比较第一个管道中的模型开始,然后在第二个网格搜索管道中对单个模型做进一步的调优。一旦模型得到合理的调整,它的最佳超参数就可以放入第一个网格搜索管道。

对单个模型的微调通常是一次搜索一个参数(最多两个)。这使得运行时间很短,并且也有助于发展关于改变超参数将对模型性能产生什么影响的直觉。

2.太多功能

作为一名初级数据科学家,我有一个误解,那就是添加功能没有成本。把它们都放进去,让模型自己算出来!我们现在可以很容易地看到这一点的幼稚——更多的功能有指数级的成本。

这个误解来自于对深度学习的一个根本性误解。

看到计算机视觉中的结果,深度神经网络从原始像素中完成所有的特征工程工作,我认为对其他数据使用神经网络也是如此。我在这里犯了两个错误:

-不理解卷积神经网络的有用归纳偏差
-不理解维数灾难

我们现在知道添加更多功能的成本是指数级的。这也应该改变你如何看待一次性编码,这大大增加了模型需要理解的空间,数据密度低。

3.指标太多

在数据科学项目中,使用诸如培训或测试性能等指标来判断性能。

在行业中,数据科学家将选择与业务目标一致的指标。不同的指标有不同的权衡,数据科学家的部分工作是选择与业务目标最相关的指标。

然而,初级数据科学家报告一系列不同的指标是很常见的。例如,对于一个回归问题,他们可能会报告三个指标:

  • 平均绝对误差,
  • 平均绝对百分比误差,
  • 均方根误差。

再加上报告测试和训练错误(或每个交叉验证折叠的测试和训练),度量的数量变得太多,以至于无法浏览并做出决策。

选择一个最符合你业务目标的指标,并坚持下去。降低度量标准的维度,以便您可以对其采取措施。

4.太多模型

数据科学家很幸运能够获得许多开源包(如“scikit-learn ”)中模型的高质量实现。

当数据科学家重复训练一组模型,而没有考虑为什么这些模型应该并行查看的原因时,这可能会成为一个问题。线性模型被一遍又一遍地训练,从未见过笔记本外面的光。

我经常看到新的数据科学家训练线性模型、SVM 和随机森林。一个有经验的数据科学家只会训练一个基于树的集合(随机森林或 XGBoost),并专注于使用特征重要性来设计或丢弃特征。

为什么基于树的集合是一个好的初始模型?几个原因:

  • 它们可以用于回归或分类,
  • 不需要缩放目标或特征,
  • 训练可以跨 CPU 核心并行化,
  • 它们在表格数据上表现良好,
  • 特性的重要性是可以解释的。

3.学习率太高

如果在训练神经网络时有一个值得研究的超参数,那就是学习率。

将学习速率设置得太高会使神经网络的训练不稳定。学习率的作用很直观——更高的学习率意味着更快的训练。

神经网络的第二个最重要的参数是批量大小。

批量大小不太直观 —较小的批量大小意味着较高的方差梯度,但是批量的一些值正在使用该方差来突破局部最小值。

一般来说,批处理大小应该尽可能大,以提高渐变质量-通常它会受到 GPU 内存的限制(尤其是图像)。

4.不去想错误从何而来

统计误差的三个来源是:

  • 抽样误差——使用对较大总体的子集估计的统计数据,
  • 抽样偏差——与其他样本相比具有不同概率的样本,
  • 测量误差——测量值与真实值之间的差异。

即使量化这些误差的大小通常是不可能的,定性地思考统计数据中的误差来自哪里仍然是有价值的。

思考训练和测试的采样和分布之间的差异有助于提高机器学习模型的泛化能力,以免它在生产中无法泛化。

错误的另一个有用的思考工具是 IID 的概念——数据应该是独立的&同分布的:

-独立采样(无采样偏差),
-同分布(无采样或测量误差)。

IID 是统计学习中关于数据分布和抽样质量的一个假设——而且几乎总是一个被打破的假设。

5.不理解偏差和差异

监督学习模型的预测误差有三个组成部分-偏差、方差和噪声:

  • 偏差是缺乏信号 —模型看不到可用于预测目标的关系。这是不合适的。可以通过增加模型容量(通过更多的层/树、不同的架构或更多的功能)来减少偏差。
  • 方差是信号的混淆噪声——训练数据中的模式,在测试时不会出现在数据中。这太合身了。可以通过添加训练数据来减少方差。
  • 噪音是难以控制的——一个模特能做的最好的事情就是避免它。

机器学习模型的错误通常是由于这三者的结合。通常,数据科学家将能够做出改变,导致偏差和方差之间的权衡。

数据科学家可以利用三个常用的杠杆来用偏差换取方差(反之亦然):

  • 增加模型容量 —增加模型容量会减少偏差,但会增加方差(额外的容量可用于适应噪声)。
  • 减少模型容量 —减少模型容量(通过正则化、剔除或更小的模型)将减少方差,但会增加偏差。
  • a 添加数据 —更多的数据将减少方差,因为模型有更多的例子来学习如何从信号中分离噪声。

更多的数据对偏倚没有影响。

更多的数据甚至会使偏倚变得更糟,如果额外的抽样是有偏倚的。

带有偏差的额外数据采样只会让您的模型有机会更精确地判断错误——有关偏差、采样偏差和数据量之间关系的更多信息,请参见 Chris Fonnesbeck 关于数据科学统计思维的演讲。

6.痴迷于全连接神经网络的宽度和深度

对全连接神经网络架构的痴迷伴随着构建它们的过程。构建神经网络需要定义架构——这肯定很重要吧?

然而,当谈到完全连接的神经网络时,架构并不真的那么重要

只要你给模型足够的容量和可感知的超参数,一个全连接的神经网络将能够学习具有多种架构的相同功能。让你的渐变和你赋予它们的容量一起工作。

一个恰当的例子是 2015 年的强化学习论文信任区域策略优化,它使用一个简单的前馈神经网络作为移动任务的策略。运动任务使用平面输入向量,具有简单的全连接架构。

Schulman et. al (2015) Trust Region Policy Optimization

完全连接的神经网络的正确思维模式是深度为两到三,宽度设置在 50 到 100 之间(或者 64 到 128,如果你想融入酷的计算机科学人群)。如果您的模型是低偏差,考虑通过另一层或额外的宽度增加容量。

简单全连接架构的一个有趣改进是宽&深架构,它将宽记忆功能交互与深不可见的学习功能组合混合在一起。

Cheng et. al (2016) Wide & Deep Learning for Recommender Systems

7.没有关注 PEP 8

程序必须写给人们阅读,并且只是附带地给机器执行。

艾贝尔森&苏斯曼——计算机程序的结构和解释

代码风格很重要。我记得我很困惑,为什么更有经验的程序员对代码风格如此挑剔。

编程五年后,我现在知道他们来自哪里。

以预期方式布局的代码需要更少的努力来阅读和理解代码。

糟糕的代码风格会给读者带来额外的负担,让他们在考虑实际代码之前就理解你独特的代码风格。

8.不放弃目标

如果你曾经得到一个训练误差极低的模型,很可能你的目标是一个特征。

我们都做过一次。

9.不缩放目标或特征

这是我在调试机器学习项目时给出最多的建议。每当我看到高亏损(高于 2 或 3),这是一个明确的信号,表明目标没有被调整到一个合理的范围。

规模很重要,因为未缩放的目标会导致较大的预测误差,这意味着较大的梯度和不稳定的学习。

我所说的扩展是指标准化:

或标准化:

请注意,这些东西的名称之间缺乏一致性——规范化通常也称为最小-最大缩放,甚至标准化!

以下面的例子为例,我们试图从发言人数和开始时间来预测有多少人参加了一个讲座。我们的第一个管道没有缩放特征或目标,导致大的误差信号和大的梯度:

我们的第二个管道需要时间来适当地缩放特征和目标,从而产生具有适当大小梯度的误差信号:

类似的逻辑也适用于特征——未缩放的特征可以支配和扭曲信息通过神经网络的方式。

10.在开发过程中不使用数据样本

在编写处理数据的代码时,这是一个显而易见的问题——如果每次修复 bug 时都使用完整的数据集来运行数据处理,这将是开发人员时间上一个代价高昂的错误。

您可以使用整数索引粗略地处理数据样本:

pandas允许您一次仅加载数据的一个子集(避免将整个数据集拉入内存):

控制调试

控制这一点的一个简单方法是变量——这就是你在 Jupyter 笔记本中要做的:

或者更简洁地使用命令行参数:

运行脚本data.py时可以控制:

11.覆盖原始数据

原始数据是神圣的,永远不应该被覆盖。这在程序内部和磁盘上都是正确的。

12.不使用$HOME 存储数据

这不是一个错误——但这是一个极大地简化了我生活的模式。

在 Python 中管理路径可能很棘手。有几件事可以改变路径查找 Python 的工作方式:

-用户克隆源代码
-虚拟环境安装源代码
-用户从哪个目录运行脚本

出现的一些问题是由这些变化引起的:

  • os.path.realpath将根据虚拟环境安装您的包的位置而变化
  • os.getcwd将根据用户运行 Python 解释器的位置而变化

将数据放在一个固定的、一致的地方可以避免这些问题 —除了用户的`HOME '目录之外,您不需要获取任何相关的目录。

解决方法是在用户的$HOME目录下创建一个文件夹,用它来存储数据:

这意味着您的工作是可移动的——对您的同事和远程机器都是如此。

感谢阅读!

如果你喜欢这篇文章,请随时在媒体上关注我,或者在 LinkedIn 上联系我。

请务必查看我的其他帖子:

[## 充分利用 Jupyter 实验室

下一代笔记本工具指南。

towardsdatascience.com](/getting-the-most-out-of-jupyter-lab-9b3198f88f2d) [## 丹尼尔·丹尼特的四种能力

理解计算控制算法的一个有用的想法。

towardsdatascience.com](/daniel-c-dennetts-four-competences-779648bdbabc)

原载于 2019 年 9 月 14 日https://adgefficiency.com

降低机器学习的风险

原文:https://towardsdatascience.com/mitigating-risk-of-machine-learning-2eac3f9f84ab?source=collection_archive---------10-----------------------

Photo by Markus Spike on Unsplash

当你的机器学习应用程序出现问题时,通常问题和风险会比原因更困扰你。根据麦肯锡的研究,以下因素会增加您的 ML 应用程序的风险

  • 数据困难
  • 技术问题
  • 安全障碍
  • 行为不端的模特
  • 互动问题

我们通常有适当的验证框架来减轻与高姿态应用程序相关的风险。故意修改现有的验证框架可以帮助缓和与复杂的机器学习相关联的风险,但这些往往被证明是徒劳的,无法克服机器学习应用程序提出的障碍。

对于像价格预测这样的 ML 应用程序,应用收入管理规则是有用的,例如通过机器学习算法来避免价格下降到阈值以下或达到天空水平。有时,您可以将决策保持在等待状态,以便进行手动验证。这种模型的含义可能是最小的,并且可以由这种验证或控制框架来控制。但机器学习决策往往非常敏感,在现实世界中需要超高的精度。随着这些算法变得复杂,与之相关的风险也变得复杂。

大多数情况下,由于与机器学习相关的风险和现有验证框架的无能,组织将努力达成共识,以将机器学习实施到他们的任务关键型应用程序中。还有其他因素导致机器学习没有达成共识。例如,组织正在努力应对如此复杂的处理所需的计算能力,大多数情况下,基础架构成本成为一个巨大的因素。对基础设施的担忧通常会导致云提供商的出现,但与云服务相关的数据风险同样会出现。无论如何,我们之前讨论的功能风险实际上造成了机器学习炒作曲线的自然下降。

对于机器学习,目前还没有业界公认的风险框架,但以下技巧可以减轻痛苦。

风险识别方法

Photo by Markus Spike on Unsplash

风险识别对组织来说并不新鲜,同样的原则和框架可以扩展到机器学习应用程序。找出机器学习算法做出的决策如何影响业务至关重要。因此,识别与机器学习模型相关的风险至关重要,因为它们会非常迅速地直接影响业务。例如,一个不必要的有偏见的产品推荐会很快让你的用户离开。此外,机器学习的演变和适应将非常快,可能没有时间来纠正初始阶段出现的错误。

增强验证框架和决策控制

Photo by Daria Nepriakhina on Unsplash

我们讨论了现有的验证框架,这些框架可以被增强以适应机器学习应用。我们要怎么做呢?

机器学习模型比传统程序更复杂,因为它们处理一组复杂的数据。战术设计决策应该在模型接受训练之前做出。与机器学习相关的风险将出现在从设想到实施的生命周期的几乎所有阶段。对验证框架的增强也应该覆盖几乎所有的生命周期阶段,因为它们以传统的方式存在,有了这些补充。

  • 透明度和可解释性:

机器学习模型通常是黑箱,有许多模糊的决策层。这使得应用程序的审计和可跟踪性非常具有挑战性。机器学习驱动的应用程序通常需要透明。组织渴望了解数据是如何被处理以做出决策的。如果你真的想将风险最小化,你的模型的开放性和可解释性应该被放在首位并被评估。

  • 特色工程:

建立机器学习模型是为了从数据中识别模式,而数据往往很复杂。由于数据的数量和性质,数据是复杂的。考虑非结构化数据进入自然语言识别的情况。在处理之前,通常需要特征工程将非结构化数据转换成结构化数据。这些过程也在快速改造,并且定制包装复杂,因为它们能够为模型评估进行不同的数据转换。随着它们变得越来越复杂,也应该进行风险评估。

  • 数据质量控制:

机器学习应用程序和传统应用程序的主要区别之一是从数据中学习模式的能力。传统的应用程序被绑定到它们被编程的路径上,并且一旦被部署就不能调整。机器学习模型能够从数据中获得洞察力,并据此采取行动。这种行为需要干净和高质量的数据,否则算法将无法提供预期的准确性。组织中存在的孤岛限制或阻碍了高质量数据的流动,使应用程序变得脆弱。

  • 超参数

超参数调整是大多数 ML 工作中的一种常用方法,可以通过多种方式实现。但是调优应该在运行模型之前完成。无论是默认值、手动配置还是程序配置,这些参数在优化算法方面都具有重要作用。数据驱动的模型优化是最小化数据集泛化的第二种方法,也可以在许多情况下找到。然而,这些变量的选择是由试错法驱动的,并依赖于启发式经验。

  • 模型偏差

应该考虑偏差的两个方面。我们都知道数据中确实存在偏倚,我们可以采取措施减少偏倚。当我们消除偏差时,模型精度将会提高。其中一个方面在用于分析的数据中,另一个方面在动态数据中。至关重要的是,现有模型的任何新参数都不应导致决策偏差。有时还需要将操作分阶段进行,以确保模型得到一致认可。考虑我们之前讨论的价格预测的例子。我们可能会引入分阶段定价,以了解客户的支付意愿,避免任何价格偏见。

  • 生产准备和校准

机器学习应用的一些情况需要反馈回路和基于实时反馈的改进。考虑强化学习或在线学习,这种对模型的实时更改可能会导致性能随着时间的推移而下降。这种校准有两个方面。一个是这种校准的需要,另一个是校准过程本身。

  • 模式治理

机器学习有两个阶段。一个是模型构建本身,另一个是为消费做好准备。大多数时候人们并不关心后面的部分。应该小心管理数量庞大且不断增长的生产模型,并且应该清楚地维护模型与其他对象的链接。

复习和巩固

Photo by André Bandarra on Unsplash

当您第一次在生产中部署机器学习应用程序时,这只是一个开始。您仍然需要仔细检查和强化您的模型,以支持环境、数据和参与者的变化。这对于降低与洗钱相关的风险至关重要。你可能需要一个专门的机器学习应用程序的所有者来持续监控应用程序,审查模型,并在需要时做出更改。

利用机器学习减缓气候变化

原文:https://towardsdatascience.com/mitigation-of-climate-change-with-machine-learning-197f09c00fac?source=collection_archive---------24-----------------------

Photo by @prijpkema Unsplash

能源、交通和建筑领域的商机

我目前的重点是人工智能的安全,因此我认为解决气候危机是这种情况下的最高优先事项——可以说是最高风险。在 6 月份的国际机器学习会议(ICML)上,6 月 14 日的会议当天,气候变化是一个明显的焦点。会议的所有视频和演示都可以在线观看。不过,我要说的是 6 月 10 日发布的一个帖子,与这次关于 climatechange.ai 的会议有关(这个页面很有用!)。我将简要地看一下 arXiv 上发布的一篇名为 用机器学习 应对气候变化的论文的一些片段。

这篇论文有 53 页长,所以我将只提供讨论内容的一瞥。本文关注不同的领域,我将在与缓解 相关的中涵盖其中的三个领域,简单总结几点来帮助您了解深入研究本文本身是否有价值。我将概述的三个领域是:

  1. 能源方面的机会
  2. 运输中的机遇
  3. 建筑行业的机会

呼吁合作

我最喜欢这篇论文的一点是,它立即被框定为合作的号召。作者强调,机器学习不是 【银弹】 。他们强调的应用是有影响力的,但他们同时认为没有一个解决方案可以“修复”气候变化。“…光有技术是不够的—减少气候变化的技术已经存在多年了,但很大程度上还没有被社会大规模采用。”

论文作者有:大卫·罗尔尼克、普里亚·l·东蒂、林恩·h·卡克、凯利·科昌斯基、亚历山大·拉科斯特、克里斯·桑卡兰、安德鲁·斯拉文·罗斯、尼古拉·米洛耶维奇-杜邦、娜塔莎·雅克、安娜·瓦尔德曼-布朗、亚历山德拉·卢乔尼、甘特·马哈拉杰、埃文·d·舍温、s·卡蒂克·穆卡维里、康拉德·科尔丁、、卡拉·戈梅斯、吴恩达、戴密斯·哈萨比斯、约翰·c·普拉特

缓解和适应

该文件首先概述了气候变化领域的几个已知事实,即排放量不断增加,却没有减少的趋势。然后就滚入了减缓 ( 减排)和适应 ( 为不可避免的后果做准备)的思路。这些不同的问题可以被视为产生影响的机会。

缓和是这篇短文 的重点。

这份报纸是给谁的?

在介绍之后不久,他们概述了针对这些不同群体的本文:

  1. 研究人员和工程师:鼓励解决方案,并通过论文中所做的工作来识别需要概念创新的领域。
  2. 企业家和投资者:几个商业机会被勾勒出来。其中有:电力公司的精细太阳能预报;帮助减少个人能源消耗的工具;以及对气候变化的金融影响的预测。
  3. 企业领导:确定商业案例,优化供应链以减少浪费,并为精准农业提供软件/硬件工具。
  4. 地方和国家政府:讨论如何为决策收集数据,并指导未来发展计划。他们强调智能交通系统;城市建筑能耗自动评估技术:和改善灾害管理的工具。

这份报告结构简单,用一系列标签将不同的类别分开,如高杠杆、长期和高风险。因此,如果你找到一个你想进一步探索的领域,并深入到论文的特定领域,这将对你有所帮助。你会很高兴地看到,它结构良好,并给出了一个容易访问的主题概述。

减缓气候变化

电力系统是机器学习技术可以发挥作用的第一个领域。人工智能被称为新的电力,因为它有改变整个行业的潜力。有趣的是,电力本身就是人工智能准备改造的行业之一。”

1.能源领域的机会

它们概述了社会在能源部门必须采取的关键行动:

  • 迅速过渡到低碳电力来源 (如太阳能、风能、水能、核能),逐步淘汰碳排放源(如煤炭、天然气和其他化石燃料)。
  • 减少现有碳排放发电厂的排放量 ,因为向低碳燃料的过渡不会一蹴而就。
  • 在所有国家和环境中实施这些变革 ,因为电力系统无处不在

这些是可以做到,并在以下方面进一步概述:(1)发电和需求预测;(2)改进调度和需求;(3)加速材料科学;(4)核裂变和核聚变;(五)核电厂;(6)减少生命周期化石燃料的排放;(7)减少系统浪费;(8)模拟排放;(9)改善电力供应;(10)低数据设置;(11)

2.运输行业的机会

在经历了能源方面的改进后,他们转向运输工作,以同样的方式陈述需要做的事情:

  • 减少运输活动 。目前,三分之二以上的运输排放来自公路旅行,但航空旅行的排放密度最高,而且所占份额越来越大。
  • 提高车辆效率 。ML 可以改进车辆工程,实现智能基础设施,并提供政策相关信息
  • 减少燃料的碳冲击 。致力于改善这些任务的物流,例如通过提供更好的需求预测,可以提高运输效率。通常,ML 解决方案与强有力的公共政策相结合是最有效的。
  • 转向低碳选项,像 rai l .电气化公路和铁路,可以有非常低的 GHG 排放——当然,假设电力主要由低碳发电机产生。

同样,这可以在以下方面进行探索:(1)理解运输数据;(2)建模需求;(3)共享移动性;(4)货运路线和整合;(5)为效率而设计;(6)自动驾驶汽车;(七)电动汽车;(8)替代燃料;(9)乘客偏好;(10)改善低碳选择。

3.建筑业的机会

建筑物消耗的能源占全球能源相关排放的四分之一,然而在论文中,他们声称结合易于实施的修复和最先进的解决方案可以将现有建筑物的排放减少 90% (乐观!)。今天,建筑物几乎不消耗能源是可能的。在这一节中,他们没有清楚地列出需要做什么,但是我会根据结构尽量压缩。它的主要焦点似乎集中在两个方面:

  • 优化建筑。在设计新建筑和改善现有建筑时,有许多技术可以降低成本和 GHG 排放。ML 可以通过(I)对能耗数据建模和(ii)优化能源使用(在智能建筑中)来加速这些解决方案。
  • 城市规划。地区一级的数据往往无法获得。最大似然法可以通过两种方式帮助获取数据:在存在单个建筑的能源使用数据的情况下,最大似然法可以用于推导更高层次的模式。在完全缺乏能源使用和基础设施数据的地方,ML 可以推断出来。
  • 城市运营中的数据最近,数据和 ML 在提高这些领域的效率方面变得越来越常见,从而引发了智慧城市的概念。虽然“智能城市”一词包含了各种各样的技术,但这里我们只讨论与减少 GHG 排放相关的应用。

进一步的小节包括:(1)能源使用模型;(2)智能建筑;(3)地区一级的能源使用;(4)收集基础设施数据;(5)智慧城市的数据;(6)低排放基础设施。

你会看报纸吗?

正如我在引言中提到的,我正在就此写一些笔记,以鼓励你更深入地研究这篇论文。当然,这份文件并不全面,只是概述了几个问题。在结论中,他们说:

像所有技术一样,机器学习并不总是能让世界变得更好,但它可以。在应对气候变化的斗争中,我们已经看到了 ML 在跨领域领域做出的重大贡献[…]我们强调 ML 只是解决方案的一部分;它是一个跨领域支持其他工具的工具。解决气候变化问题有可能造福社会,并为机器学习领域提供新的方向。我们设想的解决方案需要与计算机科学内外的领域进行对话,这不仅会带来新的应用领域,还会带来适用于整个 ML 的新的方法论见解。【加粗补充】

因此,本着他们结论的精神,我可以提出以下几点思考:

  1. 用 ML 做出改变
  2. 你在 ML 方面的努力只是解决方案的一部分
  3. 与其他领域合作

报告在结论中提出了另一套建议,我也将在此概述:

  • 。确定你的技能如何有用——我们希望这篇文章能提供一个起点。
  • 协作 。寻找合作者,他们可能是研究人员、企业家、已建立的公司或政策制定者。请记住,对于我们在这里讨论的每个领域,都有该领域的专家了解它的机会和陷阱,即使他们不一定了解 ML。
  • 。听听你的合作者说什么是需要的,并且更广泛地收集意见,以确保你的工作会产生预期的影响。突破性的技术会产生影响,但对世俗问题的精心构建的解决方案也会产生影响。
  • 部署 。确保您的工作部署在可以实现其影响的地方。我们呼吁机器学习社区将其技能作为应对气候变化的全球努力的一部分。

虽然简短,我当然希望这篇文章在某种程度上有所帮助。

感谢您的阅读。这是第 500 天的第 56 天。我每天写一篇关于人工智能的新文章。

混合绘图比例和自定义 violinboxplot 实现

原文:https://towardsdatascience.com/mixed-plot-scales-and-custom-violinboxplot-68cc8c5d6ead?source=collection_archive---------11-----------------------

混合比例图和自定义 violinboxplot

简而言之,这篇文章解决了以下两个问题:

1.我们如何创建具有远异常值的数据分布的综合可视化?

通常,我们使用线性和对数尺度(用于捕捉异常值),但在这里,我们将研究创建混合轴的可能性,以各种类型的尺度的任意混合,应用于所需的间隔。

2.根据数据分布,我们如何结合箱线图、紫线图和动态标度的优点?

我们将提出一个 violinboxplot 的自定义实现,提供广泛的自定义参数,这些参数控制异常值的呈现、模式和计数的自定义注释、基于任意百分点的线性/对数轴分割。它处理数据数组和按列列表分组的数据帧。

这篇博客中的所有例子都是用 python/matplotlib 实现的,可以在 Github 上找到。

混合 matplolib 轴秤

让我们首先选择一个函数(sin ),该函数将生成我们将用来演示混合秤概念的数据集。

x = np.arange(-80,80, 0.1)
y = np.sin(x)
plt.title('Linear scale plot of a sinusoid')
plt.xlabel('x')
plt.ylabel('y')
plt.plot(x, y);

如果我们把这个数据集当作一个黑盒,数据科学家可能会出于各种原因,希望以最小的努力,通过在不同的时间间隔使用不同的尺度,获得图形的动态分辨率。例如,他可能想想象:

  • 1 <= y <= 0.5 using a linear scale
  • 0.1 <= y <= 0.5 using a log scale
  • -1<= y <= 0.1 using a linear scale

The first naive solution is to create 3 different plots with the chosen axis scales on chosen intervals.
在这篇文章中,我们将探讨 matplotlib 在不同比例下显示原始图形的能力,从而提供统一的可视化。

在本帖中,我们将介绍两种方法:

  1. 使用轴分隔线
  2. 使用网格规格

轴分割器

**from** **mpl_toolkits.axes_grid1** **import** make_axes_locatable

Matplotlib 的函数 make_axes_locatable 允许我们在给定的轴上添加一个新的轴。在下面的示例中,对数轴是从原始线性轴创建的。
通过设置任意的 y 限制,我们可以控制渲染图的哪一部分,并且我们可以创建图连续性的印象。
Sharedx 参数允许共享同一个 x 轴,并防止 x 刻度标签被重新渲染。

plt.title('Split plot in 2 parts: linear: [0.5, 1] and log: [0.01, 0.5]')
linearAxis = plt.gca()
linearAxis.plot(x, y)
linearAxis.set_ylim((0.5, 1))divider = make_axes_locatable(linearAxis)
logAxis = divider.append_axes("bottom", size=1, pad=0.02, sharex=linearAxis)
logAxis.plot(x, y)
logAxis.set_yscale('log')
logAxis.set_ylim((0.01, 0.5));

我们可以在给定输入轴上的 4 个潜在位置(顶部/底部/上/下)使用附加轴。下面的代码说明了链接 2 个轴,在顶部和底部。

logAxis = plt.gca()
logAxis.plot(x, y)
logAxis.set_yscale('log')
logAxis.set_ylim((0.01, 0.5))divider = make_axes_locatable(logAxis)
linearAxis = divider.append_axes("top", size=1, pad=0.02, sharex=logAxis)
linearAxis.plot(x, y)
linearAxis.set_ylim((0.5, 1))
linearAxis.set_xscale('linear')
linearAxis.set_title('Plot split in 3 scales: linear: [0.5, 1], log: [0.01, 0.5], linear: [-1, 0.01]');linearAxis1 = divider.append_axes("bottom", size=1, pad=0.02, sharex=logAxis)
linearAxis1.plot(x, y)
linearAxis1.set_yscale('linear')
linearAxis1.set_ylim((-1, 0.01));

GridSpec implementation

另一个选择是使用 matplotlib 的 GridSpec,它在调整组件大小和使用方面提供了更多的灵活性。我们可以预先定义超级剧情的数量,它们的相对大小(height_ratios),支线剧情之间的距离(hspace)。
一旦创建了独立轴,我们就可以设置比例和所需的限制。

**import** **matplotlib.gridspec** **as** **grd**
gs = grd.GridSpec(3, 1, wspace=0.01, hspace=0.05, height_ratios=[0.33, 0.33, 0.33])ax1 = plt.subplot(gs[0])
ax2 = plt.subplot(gs[1])
ax3 = plt.subplot(gs[2])
ax1.set_xticks([])
ax2.set_xticks([])ax1.plot(x, y)
ax1.set_yscale('linear')
ax1.set_ylim((0.5, 1)) ax2.plot(x, y)
ax2.set_yscale('log')
ax2.set_ylim((0.01, 0.5)) ax3.plot(x, y)
ax3.set_yscale('linear')
ax3.set_ylim((-1, 0.01));

自定义紫色位图

让我们从生成几个反映多种场景的数据分布开始:

  • 反映高斯分布的单峰数据
  • 高斯数据与异常值的组合
  • 具有多个(7 个这样的分布)的数据集,说明了输入分布的比较可视化
  • 由一列或多列组成的数据帧,用来说明比较数据的分布
data1 = [np.round(np.random.normal(10, 0.4, 50), 2)]
data1SharpEnd = [[e **for** e **in** data1[0] **if** e > 9.9]]
data1Spread = [
    np.concatenate([
        np.round(np.random.normal(10, 0.2, 1000), 2), 
        np.round(np.random.normal(80, 0.3, 5), 2)
        ]) 
    ] data2 = [
    np.concatenate([
        np.round(np.random.normal(10, std/10, 1000), 2), 
        np.round(np.random.normal(80, std, np.random.randint(0, 24) * std), 2) ]) 
            **for** std **in** range(1, 7)
        ]
labels7 = ['A', 'B', 'C', 'D', 'E', 'F', 'G']

基于一个现有数据集,我们可以定义一个数据框架:

df = pd.DataFrame()
df['values'] = data1Spread[0]
df['col1'] = np.random.choice(['A', 'B'], df.shape[0])
df['col2'] = np.random.choice(['C', 'D'], df.shape[0])

为了更好地理解底层数据分布,让我们创建一个利用箱线图和紫线图的绘图函数:

**def** plotDistributions(inputData, title):
    *"""*
 *This method plots inputData with:*
 *- matplotlib boxplot*
 *- matplotlib violinplot*
 *- seaborn violinplot*
 *"""*
    globalMax = np.max(np.concatenate(inputData))
    globalMin = np.min(np.concatenate(inputData))

    plt.figure(figsize =(14, 4))
    plt.suptitle(title) plt.subplot(121)
    plt.grid()
    plt.title('Matplotlib boxplot')
    plt.boxplot(inputData, vert= **False**);
    plt.axvline(x = globalMax, c ='red', label = 'Global max', alpha = 0.5)
    plt.axvline(x = globalMin, c ='red', label = 'Global min', alpha = 0.5)
    plt.legend() plt.subplot(122)
    plt.grid()
    plt.title('Matplotlib violinplot')
    plt.violinplot(inputData, vert= **False**, showmeans=**False**, showmedians=**True**, showextrema=**True**);
    plt.axvline(x = globalMax, c ='red', label = 'Global max', alpha = 0.5)
    plt.axvline(x = globalMin, c ='red', label = 'Global min', alpha = 0.5)
    plt.legend()

我们可以使用 seaborn 来可视化数据帧

sns.violinplot(x = 'values', y='col1', data = df)
plt.figure()
sns.violinplot(x = 'values', y='col2', data = df)

但是,seaborn 希望只将 group by 中用于汇总结果的一列指定为 y。如果我们想要基于多个特征的组合进行聚集,我们必须在调用绘图函数之前进行。

在上面的图中,我们可以发现哪些缺点?

  • 如果能在一个图形中结合箱形图和小提琴图的分辨率就好了。Seaborn 通过内部参数提供了一种合并箱线图的方法,但其定制的可能性是有限的。
  • 如第二张图所示,如果我们正在处理一个有很大异常值的分布,整体可视化会丢失极端情况下的细节。如果我们可以使用第一部分中讨论的示例来创建一个定制的统一视图,并在目标间隔上使用任意的比例,会怎么样呢?

其他一些需要考虑的问题包括:

  • 我们如何使用自定义注释来丰富绘图,例如,为每个数据集指示点数和其他任意度量,如模式?
  • 能不能提供一个超参数,把我们认为是离群点的点都从可视化中去掉?

如果我们从这最后一点开始,我们可以想出一个方法,去掉所有大于给定标准偏差数(默认为 3)的点。

在上面的图中,我们可以发现哪些缺点?

  • 如果能在一个图形中结合箱形图和小提琴图的分辨率就好了。Seaborn 通过内部参数提供了一种合并箱线图的方法,但其定制的可能性是有限的。
  • 如第二张图所示,如果我们正在处理一个有很大异常值的分布,整体可视化会丢失极端情况下的细节。如果我们可以使用第一部分中讨论的示例来创建一个定制的统一视图,并在目标间隔上使用任意的比例,会怎么样呢?

其他一些需要考虑的问题包括:

  • 我们如何使用自定义注释来丰富绘图,例如,为每个数据集指示点数和其他任意度量,如模式?
  • 能不能提供一个超参数,把我们认为是离群点的点都从可视化中去掉?

如果我们从这最后一点开始,我们可以想出一个方法,去掉所有大于给定标准偏差数(默认为 3)的点。

**def** removeOutliers(data, thresholdStd = 3):
    *"""*
 *This method returns all values which are farther away*
 *than thresholdStd standard deviationa*
 *"""*
    noOutliers=[]
    mean = np.mean(data)
    std =np.std(data)
    **if** std == 0:
        **return** data **for** y **in** data:
        z_score= (y - mean)/std 
        **if** np.abs(z_score) <= thresholdStd:
            noOutliers.append(y)
    **return** noOutliers

violinboxplot 的实现

在 github 上找到完整代码。我们将只展示前面介绍的数据集的结果。该自定义实现呈现:

  • (可选)绿色表示每个分发的模式
  • (可选)在每一行的末尾返回每个分布的计数
  • 可以渲染或隐藏异常值
  • 可选的 logpercentile 指定一个百分比值(0.9),在该值下,渲染将以线性比例进行,该百分比值使用 logscale
  • 该方法可以将一组数组或一个数据帧作为输入,这些数组或数据帧可以通过一组列(y)来分组

在一列或多列上使用数据框架和聚合的结果:

未来的工作

未来的一项改进是自动检测所有渲染分布的模式,并通过使用上一篇文章https://github . com/ciortanmadalina/modality _ tests/blob/master/kernel _ density . ipynb中提供的代码来估计 PDF。这可以对一些感兴趣的区域进行估计,例如对数标度将是很好的选择。

使用 fastai 的混合精确训练

原文:https://towardsdatascience.com/mixed-precision-training-using-fastai-435145d3178b?source=collection_archive---------7-----------------------

介绍

图像分类是深度学习的 Hello World。对我来说,这个项目是用胸部 x 光检测肺炎(T2)。由于这是一个相对较小的数据集,我可以在大约 50 分钟内训练我的模型。但是如果我告诉你,只要增加一行代码

我们可以减少训练时间(理论上减少 50%),而不会显著降低精确度。但是首先…

为什么这很重要?

我使用的数据集包括大约 4500 张图片。它花了 50 分钟的唯一原因是因为图像是高清的。

然而,如果我们将同一个项目扩展到现实世界的应用程序,可能会有更多的图像。看看斯坦福的 Chexpert 数据集。

此外,我训练了一个模型来预测一种疾病,但在现实中,我们将不得不预测比两类疾病更多的疾病。在这种情况下,减少培训时间确实是一个优势。这将降低资源成本,帮助我们更快地进行实验。那么我们该怎么做呢?

我们变得不那么精确。

事实证明,有时,在深度学习中使事情不那么精确会使它更好地概括。

杰瑞米·霍华德

神经网络中的精度

在神经网络中,所有的浮点数,即我们的输入、权重和激活都是用 32 位存储的。使用 32 位给了我们很高的精度。但是更高的精度也意味着需要更多的计算时间和更多的内存来存储这些变量。如果我们只用 16 位呢?

半精度

减少内存使用的一种方法是以一半精度(16 位)执行所有操作。

根据定义,这将占用 RAM 中一半的空间,并且理论上可以让您的批处理大小翻倍。增加的批量意味着并行执行更多的操作,从而减少培训时间。然而,这也带来了一些问题。

半精度的问题

  1. 不精确的重量更新:

我们将模型的权重更新如下:

w = w - learning_rate * w.gradient

以半精度执行该运算的问题是,w.grad通常非常小,我们的learning_rate也是如此,这会使等式的第二项非常小,以至于根本不会发生更新。

2.梯度下溢:

类似于不精确的权重更新,如果我们的梯度太小(低于可以使用 16 位表示的值),它们将被转换为 0。

3.激活爆炸:

一系列矩阵乘法(前向传递)很容易导致神经网络的激活(输出)变得如此之大,以至于它们达到 NaN(或无穷大)

解决这些问题的办法就是使用 混合精度训练

source: https://arxiv.org/pdf/1710.03740.pdf

混合精确训练

全朱庇特笔记本。

顾名思义,我们做任何事情都不会有一半的精度。我们在 FP16 中执行一些操作,而在 FP32 中执行其他操作。更具体地说,我们以 32 位精度进行权重更新。这解决了问题#1。

为了克服梯度下溢,我们使用称为梯度缩放的东西。我们将损失函数乘以一个比例因子。我们这样做是为了避免梯度下降到 FP16 可以表示的范围之下,从而避免它被 0 取代。我们还要确保缩放因子不会大到导致我们的激活溢出。

使用这些思想,我们避免了半精度的问题,并有效地训练我们的网络。

最后的想法

使用混合精度训练的想法只出现了几年,并不是所有的 GPU 都支持它。但是这是一个值得了解的想法,并且在将来会被更多的使用。

结果表明,该方法在不影响精度的情况下,减少了训练时间。

这就是本文的全部内容。

如果你想了解更多关于深度学习的知识,可以看看我在这方面的系列文章:

[## 深度学习系列

我所有关于深度学习的文章的系统列表

medium.com](https://medium.com/@dipam44/deep-learning-series-30ad108fbe2b)

~快乐学习。

混合策略梯度和 Q-学习

原文:https://towardsdatascience.com/mixing-policy-gradient-and-q-learning-5819d9c69074?source=collection_archive---------18-----------------------

策略梯度算法是强化学习算法的一个大家族,包括强化、A2/3C、PPO 等。Q-learning 是另一个家族,在过去几年中有许多重大改进:目标网络、双 DQN、经验重放/采样…

我一直想知道是否有可能取二者之长,创造出更好的学习算法。当我发现刻薄的演员评论家时,这个梦想实现了。

快速背景

在强化学习中,有奖励,目标是建立一个代理,使其在一集内的整体奖励最大化。这个数量是:

从时间 t 开始,其中 r 是奖励,γ是折扣因子。无穷大代表一集的结束,所以如果它几乎肯定是有限的,我们可以取 gamma = 1。

实际上,我们有一个策略π,它是每个状态 s 的动作的概率分布。这意味着我们希望从 t 开始最大化 G 的期望值,我们将这个数字称为值。

我们也可以定义 Q,它是以一个动作为条件的值:也就是说,从状态 s 开始并使用动作 a 的期望总回报。

这个想法

现在我们需要的东西都有了。我们的目标是找到使 v 最大化的策略π。π是从状态集到动作集的静态函数。因此,我们可以使用神经网络来近似它。使用一点微积分,我们可以计算我们的网络参数θ的梯度,以便得到众所周知的策略梯度:

但是另一种写法是:

这就是我所说的平均梯度。人们大多使用第一个公式,去掉对行动的期望(根据大数定律,一个实现近似遵循期望),用 Q 作为使用当前政策给出的行动观察到的总回报。但是我们为什么不用第二个公式,没有任何近似呢?问题是,我们没有任何观察到的其他行动的回报,除非模拟大量的轨迹(在一棵非常大的树上行走,在每个节点的多个行动之间进行选择)。实际上这正是人们用树搜索做的事情,像、UCT、PO-UCB/T 方法。但现在是深度学习时代,为什么不直接近似这些无法直接观测到的 Q 值呢?

这就是 Q-learning 的由来。我们将使用网络预测 Q 值,就像 Q 学习一样,但是我们的策略不会是ε贪婪的,取值的 argmax。我们将使用平均梯度公式更新我们的策略。这就是 MAC 算法

例如,如果我们拿一个像 breakout 这样的经典 Atari 游戏,我们将创建一个具有两个输出的卷积神经网络:一个用于 Q 值,具有线性激活,另一个用于策略,具有 softmax 激活。两者的长度都等于游戏中动作的数量。

我们的损失将如下所示(在 tensorflow 1 中。x):

优势

方差缩减

正如作者在论文中所说,也正如我根据自己的经验观察到的,学习差异大大减少了。这是预期的:由于 MAC 实际上是“共同”政策梯度的期望值,使用一点 Jensen 不等式证明其方差更低。直觉上,平均导致较小的方差,假设我们的神经网络给出了 Q 值的良好评估。

这一点对于许多真实世界环境非常重要,这些环境在转移矩阵(给定所采取的行动,下一个状态将是哪个状态)和奖励函数中通常具有非常高的方差。真实环境的动态并不平滑,很多现象甚至是混沌的。

Q 网络作为代理

这对我来说是一个巨大的方面,但似乎作者自己并没有真正看到这一点。MAC 将策略从环境动态中分离出来:Q 值就像是策略和环境之间的代理。在我看来,MAC 是 EPG 的离散版本[2]!正如 EPG(DDPG 的推广)擅长无限多个动作(连续动作空间),MAC 擅长大量动作(减少方差)。

这个“代理”带来了 Q-learning 的一个非常重要的特性:离策学习!更准确地说,在 PPO [3]中,我们可以更有效地采样,多次重用数据。Q 值学习是监督学习,因此在监督学习中,我们可以执行多个时期。这个小细节真的是助推算法,也是今天 PPO 如此受赞赏的主要原因。

使用最先进的技术

由于 MAC 使用 DQN,大多数技术可以重用,如目标网络或分布式 RL [4]。我体验了后者,结果令人印象深刻,结合 MAC。对于策略梯度部分,我们可以使用自然梯度(像在 PPO 中),例如信任区域和二阶方法。

弱点

MAC 的一个大缺点(实际上也是我发现的唯一缺点)是,它在几个问题上的表现不如 A2C。我的解释是,与其容量和数据质量相比,训练网络来预测 Q 值有时可能太难了。

结论

强化学习是一个非常年轻的研究课题,但是已经收集了很多有趣的论文。许多概念和问题依赖于 AI 的一般理论,独立于纯粹的深度学习,我认为这在今天是一个非常好的观点。

Mean actor critic 是一个有趣的算法,它以一种独特的方式解决了强化学习的常见问题,但也对该学科的局限性提出了疑问。深度强化学习是通往 AGI 的黄金之路吗?或者只是大山上的一块石头…

[1] Cameron Allen、Melrose Roderick Kavosh Asadi、Abdel rahman Mohamed、George Konidaris 和 Michael Littman。刻薄演员评论家(2017)。链接

[2]卡米尔·克洛克和西蒙·怀特森。预期政策梯度(2017 年)。链接

[3]约翰·舒尔曼、菲利普·沃尔斯基、普拉富拉·德里瓦尔、亚历克·拉德福德、奥列格·克里莫夫。近似策略优化算法(2016)。链接

[4]马克·贝勒马尔、威尔·达布尼和雷米·穆诺斯。强化学习的分布视角(2017)。链接

用 PersLay 混合拓扑和深度学习

原文:https://towardsdatascience.com/mixing-topology-and-deep-learning-with-perslay-2e60af69c321?source=collection_archive---------9-----------------------

Source: Sky Motion / Shutterstock.com

在前一篇中,我提出了拓扑数据分析及其主要描述符,即所谓的持久性图。在这篇文章中,我想展示如何将这些描述符与神经网络结合起来,为基于深度学习和拓扑的应用开辟道路!

什么是持久性图?

简而言之,持久性图是平面中表示数据拓扑的一组点:图中的每个点实际上都见证了数据中拓扑特征的存在。此类特征可以是连接的组件(0 维拓扑)、回路(1 维拓扑)、空腔(2 维拓扑)等。

在下面的例子中,我展示了一个从零的图像(显示在右下角)计算出的持久性图的例子。这个想法是通过逐步增加像素来过滤图像。更具体地说,我们仅从那些灰度值大于给定阈值的像素开始,并且让该阈值从大值减小到低值,直到最终所有像素都存在。在这个过程中,可能会发生一些拓扑变化(例如创建和合并连接的组件和/或孔洞),而持久性图会准确地编码这些变化。每次拓扑事件发生时,都会在持久性图中产生一个点,该点的坐标提供了该事件发生的阈值。

Example of computation of a persistence diagram from an image (source: https://www.dropbox.com/s/hihxt8cuz265bf9/phd.pdf?dl=0).

这个描述符很有趣,特别是因为它编码了拓扑信息,这是不寻常的,并且通常是对机器学习中更传统的描述符编码的信息的补充。然而,由于持久性图的空间不是结构化的(例如,不可能以一致的方式添加两个持久性图),在过去几年中已经定义了几个特征图,即,将持久性图嵌入到希尔伯特空间(例如有限维欧几里得空间)中。它们中的大多数现在可以在 scikit-learn 兼容库 sklearn_tda 中获得。

PersLay:持久性图表的层

今天,我想介绍一个我和我的合著者在过去几个月里开发的便利工具,它叫做PersLayPersLay 是一个神经网络层,它适合处理持久性图,并且概括了我上面提到的大多数特征图。更具体地说,文献的每个特征图都可以由 PersLay 用适当的参数生成。这尤其意味着特征图可以在训练期间即时学习。不再需要密集的交叉验证!!

此外,由于任何后续的神经网络都可以在 PersLay 之后插入,它允许持久性图被任何架构处理,无论它有多复杂。

PersLay 的定义实际上很简单 :-)事实上,当一个人希望以一种可微分的方式将持久性图转化为向量(以便可以反向传播)时,首要的要求是对图点的排列保持不变。假设您必须处理两组点,它们唯一的区别在于点的排序:您可能希望输出是相同的!

生成排列不变且可微分的特征图的最简单方法可能是将持久性图的每个点变成一个向量,然后对所有这样的向量求和,最终得到一个向量(实际上,可以使用许多其他操作来代替求和,考虑取最大值、平均值、最大的 n 值……)。这正是 PersLay 的定义。

Definition of PersLay for a persistence diagram Dg. In this equation, w(p) is a weight function, phi is a vector transformation, and op is any permutation-invariant operation (source: https://arxiv.org/pdf/1904.09378.pdf).

PersLay 的模块化

原来TDA 文献中的所有特征地图实际上都符合这个一般方法!根据将图点转化为向量的方式以及所使用的排列不变运算,可以看出应用上述方法相当于计算余辉图像、余辉景观、余辉轮廓 …

以持久性景观为例。这个方法是第一个被定义来处理持久性图的特性图。其定义如下:对于平面上的每个点 p ,统计该点 p 位于左上角有余辉图点的正方形内的余辉图点数。由此,你得到了平面上的分段常数函数。第 k- 个持续景观被定义为包含具有函数值 k 的所有点的平面区域的边界。通过随机采样点并评估这些点上的持久性景观,该边界最终被转化为一个数字向量。

Example of persistence landscape computation (source: http://www.jmlr.org/papers/volume16/bubenik15a/bubenik15a.pdf)

事实证明,持久性景观可以被认为是 PersLay 的特殊实例!事实上,生成持久性景观的一个更简单的方法是将一个三角形函数与每个持久性图点相关联,并对该函数进行采样以获得向量。那么第 k 个持续性景观就是这些向量的每个坐标的第 k 个最大值!

PersLay parameters for the generation of persistence landscapes (source: https://arxiv.org/abs/1904.09378).

持久性图的简单架构

这使得持久性图可以在各种各样的任务中使用,这在以前是无法实现的!事实上,即使对于成千上万的持久性图,用传统的分类器(如 SVM 或随机森林)对所有可能的特征图进行交叉验证也太昂贵了(就运行时间而言)。另一方面,用 PersLay 的几行代码就可以做到:-D

更准确地说,PersLay 的输出可以用作任何后续神经网络的输入。在与 PersLay 相关的文章中,我们研究了一个简单的架构,其中从每个数据点生成几个持久性图,并且这些图中的每一个都由特定的 PersLay 通道单独处理。然后将所有通道的输出连接起来(带有一些附加功能),我们使用一个完全连接的层来产生具有正确维度的结果。

A simple architecture using PersLay.

对于那些想了解更多这方面知识的人,有一个关于 PersLay 和这种架构的教程,里面有一些很酷的图分类应用。我真的希望你也对这种神经网络和拓扑数据分析的新组合感到兴奋。除了分类之外,神经网络还有许多其他应用,所以请继续关注其他即将发布的帖子!

混合建模从零开始,在 R

原文:https://towardsdatascience.com/mixture-modelling-from-scratch-in-r-5ab7bfc83eef?source=collection_archive---------1-----------------------

从 K-means 到高斯混合建模,浓缩在几行代码中

在机器学习文献中, K-means高斯混合模型 (GMM)是第一个描述的聚类/无监督模型[1–3],因此,应该是任何数据科学家工具箱的一部分。在 R 中,可以使用kmeans()Mclust()或其他类似的函数,但是要完全理解那些算法,需要从头开始构建它们。网上搜索会引导你找到许多有用的教程,但是你很难找到完全透明的 R 代码。我遇到的最好的例子是 R-bloggers 上的一篇优秀文章'高斯混合建模介绍'。

但我仍然有点不满意。这就是我一直在寻找的东西:

  • A-to-Z 算法(数据->算法->结果)
  • 独占使用 R 基础包(无隐藏计算)
  • 多变量情况(不仅仅是单变量或双变量)
  • 优雅的代码(K-means 和 GMM 之间的平行极简)
  • 用于绘制算法迭代动画的选项

我上面提到的代码满足了大约一半的需求(从 A 到 Z,优雅的 GMM 多元代码)。我通过更多的研究完成了剩下的部分,结果如下。请注意,我将这篇文章写得很短,重点放在算法的本质上。方程式可以在维基百科和 ML 教材上找到。r 代码被注释只是为了给出足够多的关于建模步骤的细节。我还为 K-means 和 GMM 使用了相同的结构来突出它们之间的明显相似之处(即分别是 期望最大化 算法的硬版本和软版本)。

我们的数据

为了说明,我们将把那些聚类算法应用于著名的 虹膜数据集 。在 20 世纪初,Edgar Anderson 收集数据量化了三种鸢尾花的形态变异:鸢尾海滨鸢尾杂色鸢尾。该数据集由 3 个物种的 50 个样本和 4 个特征组成:萼片和花瓣的长度和宽度[4]。英国统计学家和遗传学家罗纳德·费雪(1890–1962),一个几乎是单枪匹马为现代统计科学奠定基础的天才【5】,然后在“分类问题中多重测量的使用’【6】中使用这个数据集作为线性判别分析 (LDA)的例子。从那时起,Iris 数据集已经成为简单多维聚类问题的教科书示例(尽管 Fisher 显然使用了 LDA 的标签,LDA 是一种监督学习模型)。iris数据集包含在 R datasets包中。

X <- iris[,1:4]
y <- iris[,5]y_col <- c('#7DB0DD', '#86B875', '#E495A5')pdf('dat_iris.pdf')
pairs(X, lower.panel = NULL, col = y_col[y])
par(xpd = T)
legend(x = 0.1, y = 0.4, legend = as.character(levels(y)), fill = y_col)
dev.off()

The Anderson/Fisher Iris flower dataset | Features and labels from the R datasets package; photographs of the 3 Iris species, source: Wikipedia; and original data, Table 1 of [6].

k 均值

我们从优秀的综述“数据聚类:50 年后的 K-means”[7]中了解到,聚类方法的发展是一项跨学科的努力,有来自分类学家、生物学家、心理学家、统计学家、工程师等的众多贡献。“数据聚类”一词首次出现在 1954 年一篇关于人类学数据的文章的标题中。在现有的所有聚类算法中,K-means 算法是最流行和最简单的。它有着丰富多样的历史,因为它是在 1956 年至 1967 年间在不同的科学领域独立发现的[8–9]。下面的注释 R 代码对此进行了描述:

# finds partition such that squared error between empirical mean
# and points in cluster is minimized over all k clusters
km.fromscratch <- function(X, k){
  p <- ncol(X)  # number of parameters
  n <- nrow(X)  # number of observations
  Delta <- 1; iter <- 0; itermax <- 30
  while(Delta > 1e-4 && iter <= itermax){
    # initiation
    if(iter == 0){
      centroid <- X[sample(nrow(X), k),]
      centroid_mem <- centroid
    }

    # equivalent to E-step
    d <- sapply(1:k, function(c) sapply(1:n, 
      function(i) sum((centroid[c,] - X[i,])^2) ))
    cluster <- apply(d, 1, which.min)

    # equivalent to M-step
    centroid <- t(sapply(1:k, function(c) 
      apply(X[cluster == c,], 2, mean)))

    Delta <- sum((centroid - centroid_mem)^2)
    iter <- iter + 1; centroid_mem <- centroid
  }
  return(list(centroid = centroid, cluster = cluster))
}# run K-means
km <- km.fromscratch(X, 3)
pairs(X, lower.panel = NULL, col = km$cluster)
table(y, km$cluster)

我们来对比一下打包的算法km.pkg <- kmeans(X, 3):

以下动画基于建议的 R 代码,但使用pairs()功能的面板选项绘制了集群球形决策边界的半径。为了清楚起见,这在前面的代码中没有显示,因为它的大小已经翻倍了!然而,附录中提供了完整的代码。与鸢尾属物种标记相比,我们得到了 88.7% 的(对于 setosa 没有错误,对于 versicolor 有 3 个错误分类的观察值,对于 virginica 有 14 个错误分类的观察值——注意,结果可能会因随机启动而略有变化)。使用kmeans()内置的 R 函数会产生类似的结果,但速度更快。

K-means clustering of the Iris dataset | The different iterations to convergence, with radius of the cluster spherical decision boundary plotted.

高斯混合模型

高斯混合(高斯混合模型或 GMM)是最广泛使用的混合模型。GMM 可以被描述为具有高斯密度的 K-均值的软版本。下面是多维情况下的 R 代码,这意味着我们采用全张量,这是通过多元正态分布和协方差矩阵的特征分解来了解 GMM 所有复杂性的最佳方式。我们开始吧:

# Uses EM algorithm with multivariate normal
# distribution to estimate cluster probability
mvnorm.cov.inv <- function(Sigma) {
  # Eigendecomposition of covariance matrix
  E <- eigen(Sigma)
  Lambda.inv <- diag(E$values^-1)   # diagonal matrix
  Q <- E$vectors
  return(Q %*% Lambda.inv %*% t(Q))
}#multivariate Gaussian pdf
mvn.pdf.i <- function(xi, mu, Sigma)
  1/sqrt( (2*pi)^length(xi) * det(Sigma) ) * 
  exp(-(1/2) * t(xi - mu) %*% mvnorm.cov.inv(Sigma) 
  %*% (xi - mu)  )mvn.pdf <- function(X, mu, Sigma)
  apply(X, 1, function(xi) mvn.pdf.i(as.numeric(xi), mu, Sigma))gmm.fromscratch <- function(X, k){
  p <- ncol(X)  # number of parameters
  n <- nrow(X)  # number of observations
  Delta <- 1; iter <- 0; itermax <- 30
  while(Delta > 1e-4 && iter <= itermax){
    # initiation
    if(iter == 0){
      km.init <- km.fromscratch(X, k)
      mu <- km.init$centroid; mu_mem <- mu
      w <- sapply(1:k, function(i) length(which(km.init$cluster == i)))
      w <- w/sum(w)
      cov <- array(dim = c(p, p, k))
      for(i in 1:p) for(j in 1:p) for(c in 1:k) cov[i, j, c] <- 
        1/n * sum((X[km.init$cluster == c, i] - mu[c, i]) *
        (X[km.init$cluster == c, j] - mu[c, j]))
    }

    # E-step
    mvn.c <- sapply(1:k, function(c) mvn.pdf(X, mu[c,], cov[,, c]))
    r_ic <- t(w*t(mvn.c)) / rowSums(t(w*t(mvn.c)))

    # M-step
    n_c <- colSums(r_ic)
    w <- n_c/sum(n_c)
    mu <- t(sapply(1:k, function(c) 1/n_c[c] * colSums(r_ic[, c] *
      X)))
    for(i in 1:p) for(j in 1:p) for(c in 1:k) cov[i, j, c] <-
      1/n_c[c] * sum(r_ic[, c] * (X[, i] - mu[c, i]) * r_ic[, c] *
      (X[, j] - mu[c, j])) Delta <- sum((mu - mu_mem)^2)
    iter <- iter + 1; mu_mem <- mu
  }
  return(list(softcluster = r_ic, cluster = apply(r_ic, 1,
    which.max)))
}# run GMM
gmm <- gmm.fromscratch(X, 3)
pairs(X, lower.panel = NULL, col = gmm$cluster)
table(y, gmm$cluster)

我们来对比一下来自library(mclust)gmm.mclust <- Mclust(X, 3):

同样,为了清楚起见,本代码中没有显示迭代过程中椭圆的绘制,如下面的动画所示(完整代码请参见附录)。与鸢尾属物种标记相比,当将每个观察分类到最高聚类概率时,我们得到了 96.7% 的准确度(对于 setosavirginica 没有错误,对于 versicolor 有 5 个观察被错误分类)。但是,请注意,结果可能会因随机参数初始化而略有不同;运行几次算法来研究这种可变性。使用Mclust()也能得到类似的结果(但Mclust()显然要快得多)。如果我们详细比较两种聚类算法的结果,我们可以看到,是 K-means 做出的球形假设使其在 Iris 数据集上的性能略差于 GMM。

Gaussian Mixture Modelling of the Iris dataset | The different iterations to convergence, with elliptic distribution of each cluster plotted.

现在看看这两种算法之间的相似之处,两者都由三个步骤构成:初始、E 步骤和 M 步骤的 期望最大化【EM】算法【10】。EM 是一种简单而强大的迭代算法,它在给定参数的情况下推断聚类(E 步骤),然后在给定预测聚类的情况下优化参数(M 步骤)之间交替进行。

。既然你已经理解了这两个经典聚类算法的步骤,我推荐你使用正式的 R 函数(kmeans()Mclust()等)。),已经过基准测试,效率要高得多。

[1] C. M. Bishop,模式识别和机器学习 (2006),Springer

[1] C. M. Bishop,模式识别和机器学习 (2006),Springer

[2] T. Hastie 等人,统计学习、数据挖掘、推理和预测的要素 (2009),Springer,第二版。

[3] K. P. Murphy,机器学习,概率视角 (2012),麻省理工学院出版社

[4] E .安德森,鸢尾属植物中的物种问题 (1936),密苏里植物园年报

[5] A .哈尔德,一部数理统计史 (1998),威利

[7] A. K. Jain,数据聚类:50 年后的 K-means (2010),模式识别字母

[8] H .施泰因豪斯,《关于各方的材料分工》 (1956 年),《波罗乃兹科学院公报》

[9] J. MacQueen,多变量观测值的一些分类和分析方法 (1967),第五届伯克利研讨会

[10] A. P. Dempster 等人,通过 EM 算法从不完整数据中获得最大似然 (1977),皇家统计学会杂志

附录:动画 K 均值

wd <- getwd()# finds partition such that squared error between empirical mean
# and points in cluster is minimized over all k clusters
km.fromscratch <- function(X, k, plot = F){
  p <- ncol(X)  # number of parameters
  n <- nrow(X)  # number of observations
  Delta <- 1; iter <- 0; itermax <- 30
  class_col <- c('#7DB0DD', '#86B875', '#E495A5')
  while(Delta > 1e-4 && iter <= itermax){
    # initiation
    if(iter == 0){
      centroid <- X[sample(nrow(X), k),]
      centroid_mem <- centroid
    }

    # equivalent to E-step
    d <- sapply(1:k, function(c) sapply(1:n, function(i) sum((centroid[c,] - X[i,])^2) ))
    cluster <- apply(d, 1, which.min)
    # equivalent to M-step
    centroid <- t(sapply(1:k, function(c) apply(X[cluster == c,], 2, mean)))

    rad <- sapply(1:k, function(c) max(sqrt(d[cluster == c,c])))
    if(plot){
      i <- 1
      idx <- matrix(rep(seq(p), p), ncol = p, nrow = p)
      idx <- idx[lower.tri(idx)]
      idy <- matrix(rep(seq(p), each=p), ncol = p, nrow = p)
      idy <- idy[lower.tri(idy)]
      theta <- seq(0,1,0.01) * 2*pi

      png(paste0(wd, '/fig_kmeans/iter', iter, '.png'))
      pairs(rbind(X, centroid), lower.panel = NULL, asp = 1,
            col = c(class_col[cluster], rep('black', k)), main =
            paste0('iter=',iter), panel=function(x, y, ...) {
              points(x, y, col = c(class_col[cluster], rep('black', k)))
              lines(centroid[, idx[i]][1]+cos(theta)*rad[1], 
                    centroid[, idy[i]][1]+sin(theta)*rad[1], 
                    col=class_col[1])
              lines(centroid[, idx[i]][2]+cos(theta)*rad[2], 
                    centroid[, idy[i]][2]+sin(theta)*rad[2], 
                    col=class_col[2])
              lines(centroid[, idx[i]][3]+cos(theta)*rad[3], 
                    centroid[, idy[i]][3]+sin(theta)*rad[3], 
                    col=class_col[3])
              i <<- i+1
            })
      dev.off()
    }

    Delta <- sum((centroid - centroid_mem)^2)
    iter <- iter + 1; centroid_mem <- centroid
  }
  return(list(centroid = centroid, cluster = cluster))
}# run K-means
km <- km.fromscratch(X, 3, plot = T)
table(y, km$cluster)library(magick)
list.files(path = paste0(wd, '/fig_kmeans/'), pattern = '*.png', full.names = T) %>% 
  image_read() %>%
  image_join() %>%
  image_animate(fps=1) %>%
  image_write('fig_kmeans_anim.gif')

附录:动画 GMM

library(reshape)   #cast()
wd <- getwd()# Uses EM algorithm with multivariate normal
# distribution to estimate cluster probability
mvnorm.cov.inv <- function(Sigma) {
  # Eigendecomposition of covariance matrix
  E <- eigen(Sigma)
  Lambda.inv <- diag(E$values^-1)   # diagonal matrix with inverse of eigenvalues
  Q <- E$vectors                    # eigenvectors
  return(Q %*% Lambda.inv %*% t(Q))
}#multivariate Gaussian pdf
mvn.pdf.i <- function(xi, mu, Sigma)
  1/sqrt( (2*pi)^length(xi) * det(Sigma) ) * 
  exp(-(1/2) * t(xi - mu) %*% mvnorm.cov.inv(Sigma) %*% (xi - mu)  )mvn.pdf <- function(X, mu, Sigma)
  apply(X, 1, function(xi) mvn.pdf.i(as.numeric(xi), mu, Sigma))gmm.fromscratch <- function(X, k, plot = F){
  p <- ncol(X)  # number of parameters
  n <- nrow(X)  # number of observations
  Delta <- 1; iter <- 0; itermax <- 30
  class_col <- c('#7DB0DD', '#86B875', '#E495A5')
  while(Delta > 1e-4 && iter <= itermax){
    # initiation
    if(iter == 0){
      km.init <- km.fromscratch(X, k)
      mu <- km.init$centroid; mu_mem <- mu
      w <- sapply(1:k, function(i) length(which(km.init$cluster == i)))
      w <- w/sum(w)
      cov <- array(dim = c(p, p, k))
      for(i in 1:p) for(j in 1:p) for(c in 1:k) cov[i, j, c] <- 
        1/n * sum((X[km.init$cluster == c, i] - mu[c, i]) *
        (X[km.init$cluster == c, j] - mu[c, j]))
    }

    # E-step
    mvn.c <- sapply(1:k, function(c) mvn.pdf(X, mu[c,], cov[,, c]))
    r_ic <- t(w*t(mvn.c)) / rowSums(t(w*t(mvn.c)))# M-step
    n_c <- colSums(r_ic)
    w <- n_c/sum(n_c)
    mu <- t(sapply(1:k, function(c) 1/n_c[c] * colSums(r_ic[, c] *
      X)))
    for(i in 1:p) for(j in 1:p) for(c in 1:k) cov[i, j, c] <- 
      1/n_c[c] * sum(r_ic[, c] * (X[, i] - mu[c, i]) * r_ic[, c] *
      (X[, j] - mu[c, j]))cluster <- apply(r_ic, 1, which.max)
    if(plot){
      i <- 1
      idx <- matrix(rep(seq(p), p), ncol = p, nrow = p)
      idx <- idx[lower.tri(idx)]
      idy <- matrix(rep(seq(p), each=p), ncol = p, nrow = p)
      idy <- idy[lower.tri(idy)]

      if(iter < 10) iter4plot <- paste0('0', iter) else iter4plot <- iter

      png(paste0(wd, '/figs_gmm/iter', iter4plot, '.png'))
      pairs(rbind(X, mu), lower.panel = NULL, asp = 1, 
        col = c(class_col[cluster], rep('black', k)), main =
        paste0('iter=',iter), panel=function(x, y, ...) {
              points(x, y, col = c(class_col[cluster], rep('black', k)))
              xi <- seq(min(X[, idx[i]])-1, max(X[, idx[i]])+1, 0.1)
              yi <- seq(min(X[, idy[i]])-1, max(X[, idy[i]])+1, 0.1)
              grid <- expand.grid(xi = xi, yi = yi)
              grid['z'] <- mvn.pdf(grid, mu[1,c(idx[i],idy[i])],
                cov[c(idx[i],idy[i]),c(idx[i],idy[i]), 1])
              z <- cast(grid, xi ~ yi)
              contour(xi, yi, as.matrix(z[,-1]), 
                levels = c(.1, .5, .9), col = class_col[1], 
                add = T, lty = 'solid', labels = '')
              grid <- expand.grid(xi = xi, yi = yi)
              grid['z'] <- mvn.pdf(grid, mu[2,c(idx[i],idy[i])], 
                cov[c(idx[i],idy[i]),c(idx[i],idy[i]), 2])
              z <- cast(grid, xi ~ yi)
              contour(xi, yi, as.matrix(z[,-1]), 
                levels = c(.1, .5, .9), col = class_col[2], 
                add = T, lty = 'solid', labels = '')
              grid <- expand.grid(xi = xi, yi = yi)
              grid['z'] <- mvn.pdf(grid, mu[3,c(idx[i],idy[i])], 
                cov[c(idx[i],idy[i]),c(idx[i],idy[i]), 3])
              z <- cast(grid, xi ~ yi)
              contour(xi, yi, as.matrix(z[,-1]), 
                levels = c(.1, .5, .9), col = class_col[3], 
                add = T, lty = 'solid', labels = '')
              i <<- i+1
            })
      dev.off()
    }

    Delta <- sum((mu - mu_mem)^2)
    iter <- iter + 1; mu_mem <- mu
  }
  return(list(softcluster = r_ic, cluster = cluster))
}gmm <- gmm.fromscratch(X, 3, plot = T)
table(y, gmm$cluster)library(magick)
list.files(path = paste0(wd, "/figs_gmm/"), pattern = "*.png", full.names = T) %>% 
  image_read() %>%
  image_join() %>%
  image_animate(fps=1) %>%
  image_write("fig_gmm_anim.gif")

可变自动编码器的混合 MoE 和 VAE 的融合

原文:https://towardsdatascience.com/mixture-of-variational-autoencoders-a-fusion-between-moe-and-vae-22c0901a6675?source=collection_archive---------12-----------------------

一种无监督的数字分类和生成方法

变分自动编码器(VAE) 是试图学习输入空间形状的神经网络的典范。一旦经过训练,该模型可用于从输入空间生成新样本。

如果我们有输入数据的标签,那么也可以在标签上设定生成过程。在 MNIST 的情况下,这意味着我们可以指定我们想要为哪个数字生成图像。

让我们更进一步……我们能在完全不使用标签的情况下根据数字来决定生成过程吗?我们能用无监督的方法达到同样的结果吗?

如果我们想依赖标签,我们可以做一些简单得令人尴尬的事情。我们可以训练 10 个独立的 VAE 模型,每个模型都使用一位数的图像。

那显然可以,但是你用的是标签。那是作弊!

好吧,我们根本不用它们。让我们训练我们的 10 个模型,在把它传给合适的模型之前,用我们的眼睛看一下每张图像。

嘿,你又作弊了!虽然您不使用标签本身,但您确实会查看图像,以便将它们发送到适当的模型。

好吧……如果我们让另一个模特学习路线,而不是自己做路线,那根本不算作弊,不是吗?

对!😃

我们可以使用 11 个模块的架构,如下所示:

A manager module routing an input to the appropriate expert module

但是经理如何决定将图像传递给哪个专家呢?我们可以训练它来预测图像的数字,但是我们不想使用标签!

唷…我还以为你要作弊呢…

那么,我们如何在不使用标签的情况下培训经理呢?这让我想起了一种不同类型的模型——专家混合模型。让我绕个小圈子来解释一下 MoE 是如何工作的。我们需要它,因为它将是我们解决方案的关键组成部分。

向非专家解释的专家组合

MoE 是一个监督学习框架。你可以在 Coursera 和 YouTube 上找到 Geoffrey Hinton 的精彩解释。MoE 依赖于根据𝑥→𝑦映射对输入进行分段的可能性。看看这个简单的函数:

地面实况被定义为𝑥的紫色抛物线

In complex datasets we might not know the split points. One (bad) solution is to segment the input space by clustering the 𝑥’s using K-means. In the two parabolas example, we’ll end up with 𝑥’’ as the split point between two clusters. Thus, when we’ll train the model on the 𝑥

So how can we train a model that learns the split points while at the same time learns the mapping that defines the split points?

MoE does so using an architecture of multiple subnetworks — one manager and multiple experts:

MoE architecture

The manager maps the input into a soft decision over the experts, which is used in two contexts:

First, the output of the network is a weighted average of the experts’ outputs, where the weights are the manager’s output.

Second, the loss function is

𝑦¡ is the label, 𝑦¯¡ is the output of the i’th expert, 𝑝¡ is the i’th entry of the manager’s output. When you differentiate the loss, you get these results (I encourage you to watch the 视频了解更多详情):

  1. 经理为每个专家决定它对损失的贡献大小。换句话说,管理者选择哪些专家应该根据他们的误差来调整他们的权重。
  2. 管理器以这样一种方式调整它输出的概率,使得答对的专家将比没答对的专家获得更高的概率。

这个损失函数鼓励专家专攻不同种类的输入。

拼图的最后一块……是𝑥

让我们回到我们的挑战!MoE 是一个监督学习的框架。当然,我们可以把𝑦换成𝑥,在无人监管的情况下,对不对?MoE 的强大之处在于,每位专家都专门研究输入空间的不同部分,并具有唯一的制图𝑥→𝑦.如果我们使用映射𝑥→𝑥,每个专家将专注于输入空间的不同部分,在输入本身中具有独特的模式。

我们将使用 VAEs 作为专家。VAE 的部分损失是重建损失,其中 VAE 试图重建原始输入图像𝑥:

MoE architecture where the experts are implemented as VAE

这种架构的一个很酷的副产品是,管理器可以使用图像的输出向量对图像中的数字进行分类!

在训练这个模型时,我们需要小心的一件事是,管理器可能很容易退化为输出一个常量向量——不管手头的输入是什么。这导致一个 VAE 专用于所有数字,而九个值不专用于任何数字。在教育部的论文中描述了一种减轻损失的方法,即在损失中增加一个平衡项。它鼓励管理者的输出在一批输入中达到平衡:

说够了,训练时间到了!

Images generated by the experts. Each column belongs to a different expert.

在最后一张图中,我们看到了每个专家都学到了什么。在每个时期之后,我们使用专家从他们擅长的分布中生成图像。第 I 列包含第 I 个专家生成的图像。

我们可以看到,一些专家很容易地专注于一个位数,例如— 1。有些人被相似的数字搞糊涂了,比如专家既擅长 3 又擅长 5。

An expert specializing in 2

还有什么?

使用一个简单的模型,不需要太多的调整,我们得到了合理的结果。最理想的情况是,我们希望每个专家专门研究一个数字,从而通过管理器的输出实现完美的无监督分类。

另一个有趣的实验是把每个专家变成他们自己的 MoE!它将允许我们学习 vae 应该专门化的分级参数。例如,一些数字有多种绘制方式:7 可以有或没有删除线。这种变化的来源可以由层次结构中第二级的教育部来模拟。但是我会为以后的帖子留些东西…

原文由我在发表。

ML 算法:一种 SD (σ)-贝叶斯算法

原文:https://towardsdatascience.com/ml-algorithms-one-sd-σ-bayesian-algorithms-b59785da792a?source=collection_archive---------13-----------------------

机器学习贝叶斯算法介绍

当面对各种各样的机器学习算法时,要问的明显问题是“哪种算法更适合特定的任务,我应该使用哪种算法?”

回答这些问题取决于几个因素,包括:(1)数据的大小、质量和性质;(2)可用的计算时间;(3)任务的紧迫性;以及(4)你想用这些数据做什么。

这是我在之前的文章中写的许多算法中的一部分。在这一部分中,我试图尽可能简单地展示和简要解释可用于贝叶斯任务的主要算法(尽管不是全部)。

贝叶斯算法:

一个算法家族,其中所有算法都有一个共同的原则,即每对被分类的特征都是相互独立的。朴素贝叶斯分类器是一组基于贝叶斯定理的分类算法。贝叶斯公式提供了 P(A|B)和 P(B|A)之间的关系

朴素贝叶斯

朴素贝叶斯算法假设它使用的每个特征在给定某个类的情况下有条件地相互独立。它提供了一种从 P(c),P(x)和 P(x|c)计算后验概率 P(c|x)的方法。例如,假设你有几封邮件已经被归类为垃圾邮件。现在假设您想将一封新邮件分类为垃圾邮件或垃圾邮件。朴素贝叶斯认为这个问题是“给定包含特定单词的新电子邮件是垃圾邮件/垃圾邮件的概率是多少”(例如,包含单词“伟哥”的电子邮件被分类为垃圾邮件/垃圾邮件的概率)。

需要考虑的一些事情:

适用于非常大的数据集-您可以对小数据集使用朴素贝叶斯分类算法,但精度和召回率会非常低

由于算法有一个独立性的假设,你确实失去了利用特征之间的相互作用的能力。

高斯朴素贝叶斯

一般术语朴素贝叶斯指的是模型中的独立性假设,而不是每个特征的特定分布。到目前为止,我们还没有提到每个特征的分布,但是在高斯朴素贝叶斯中,我们假设概率的分布是高斯的(正态)。由于正态分布的假设,高斯朴素贝叶斯用于我们所有特征都是连续的情况。例如,如果我们考虑虹膜数据集,特征是萼片宽度、花瓣宽度等。它们在数据集中可以有不同的值,如宽度和长度,因此我们不能根据它们的出现次数来表示它们,我们需要在这里使用高斯朴素贝叶斯。

需要考虑的一些事情:

它假设要素的分布是正态的

当我们所有的特征都是连续的时,通常使用它

多项式朴素贝叶斯

术语多项式朴素贝叶斯简单地告诉我们每个特征都有一个多项式分布。当我们有离散数据时使用它(例如,电影分级从 1 到 5,因为每个分级都有一定的频率来表示)。在文本学习中,我们有每个单词的计数来预测类别或标签。该算法主要用于文档分类问题(文档是否属于体育、政治、科技等类别)。).分类器使用的特征/预测值是文档中出现的单词的频率。

需要考虑的一些事情:

用于离散数据

适用于容易转换为计数的数据,例如文本中的字数。

平均单相关估计量(AODE)

AODE 是一种半朴素贝叶斯学习方法。它是为了解决流行的朴素贝叶斯分类器的属性独立性问题而开发的。它通过对所有模型进行平均来实现,在所有模型中,所有属性都依赖于该类和一个单独的其他属性。它经常以少量增加计算量为代价开发比朴素贝叶斯更精确的分类器。

需要考虑的一些事情:

将它用于名义数据在计算上比常规的朴素贝叶斯更有效,并且实现了非常低的错误率。

贝叶斯信念网络(BBN)

一种概率图形模型,通过有向非循环图表示一组变量及其条件依赖关系。例如,贝叶斯网络可以表示疾病和症状之间的概率关系。在给定症状的情况下,该网络可用于计算各种疾病出现的概率(另一个例子见上图)。BBN 是一种特殊类型的图表(称为有向图)以及一组相关的概率表。另一个例子是扔硬币。硬币可以有两个值——正面或反面,各有 50%的概率。我们把这些概率称为“信念”(即我们认为国家硬币=头像是 50%)。

需要考虑的一些事情:

BBNs 使我们能够对不确定性进行建模和推理

BBNs 最重要的用途是根据对事件的实际观察修正概率

可用于了解导致某个问题的原因,或者在计算生物学和医学等领域的风险分析和决策支持中,给定一个操作产生不同影响的概率。

贝叶斯网络

贝叶斯网络是一种概率图形模型(概率性的,因为它们是根据概率分布构建的)。这些网络可用于预测、异常检测、诊断、自动洞察、推理、时间序列预测和不确定情况下的决策。这些网络的目标是模拟条件依赖,因此也是因果关系。例如:如果你在屋外,开始下雨,你的狗很可能会开始叫。这反过来会增加猫藏在沙发下的可能性。所以你可以看到关于一个事件(雨)的信息是如何让你对一个看似不相关的事件(藏在沙发下的猫)做出推断的。

需要考虑的一些事情:

你可以用它们来预测未来

有助于解释观察结果

贝叶斯网络非常便于表示多个事件之间的相似概率关系。

隐马尔可夫模型(HMM)

HMM 是一类概率图形模型,它允许我们从一组观察变量中预测一系列未知(隐藏)变量。比如根据某人穿的衣服类型(观察到的)来预测天气(隐藏变量)。这可以是泳衣、雨伞等。这些基本都是证据。

已知 HMM 用于强化学习和时间模式识别,例如手写、语音、词性标注、手势识别和生物信息学。

HMM 回答这样的问题:给定一个模型,序列 S 发生的可能性有多大?给定序列 S 和隐藏状态数,使 S 的概率最大化的最佳模型是什么?

需要考虑的一些事情:

隐马尔可夫模型适用于基于特征序列进行识别的应用。

hmm 可用于建模由以确定的(或典型的)顺序发生的不同阶段组成的过程。

HMM 需要在一组种子序列上训练,并且通常需要比简单马尔可夫模型更大的种子。

条件随机字段

训练序列模型的经典 ML 模型。它是一种区分分类器,模拟不同类别之间的决策边界。判别模型和生成模型之间的区别在于,判别模型试图模拟条件概率分布,即 P(y|x),而生成模型试图模拟联合概率分布,即 P(x,y)。他们的基本原则是,他们对连续输入应用逻辑回归。隐马尔可夫模型与 CRF 有一些相似之处,其中之一是它们也用于顺序输入。CRF 最常用于 NLP 任务。

假设你有朋友生活中某一天的一系列快照。你的目标是给每张图片贴上它所代表的活动的标签(吃饭、睡觉、开车等等。).一种方法是忽略快照具有顺序性质的事实,并建立每个图像的分类器。例如,您可以了解到在凌晨 5 点拍摄的黑暗图像通常与睡眠有关,而带有食物的图像往往与吃有关,等等。然而,由于忽略了顺序方面,我们丢失了很多信息。举个例子,如果你看到一张嘴的特写照片会发生什么——是关于说话还是吃东西?如果你知道之前的快照是你朋友吃东西的照片,那么这张照片更有可能是关于吃东西的。因此,为了增加我们的标签器的准确性,我们应该考虑附近照片的标签,而这正是条件随机场所做的。

需要考虑的一些事情:

CRF 预测对应于输入序列的最可能的标签序列

与 HMM 相比,由于 CRF 没有 HMM 那样严格的独立性假设,所以它可以适应任何上下文信息。

CRF 也避免了标签偏差问题。

在算法的训练阶段,CRF 在计算上非常复杂。当有新数据可用时,很难重新训练模型。

如果你对我的更多作品感兴趣,你可以看看我的 Github ,我的学者页面,或者我的网站

ML 算法:一种基于 SD (σ)实例的算法

原文:https://towardsdatascience.com/ml-algorithms-one-sd-σ-instance-based-algorithms-4349224ed4f3?source=collection_archive---------6-----------------------

基于实例的机器学习算法简介

当面对各种各样的机器学习算法时,一个显而易见的问题是“哪种算法更适合特定的任务,我应该使用哪种算法?”

回答这些问题取决于几个因素,包括:(1)数据的大小、质量和性质;(2)可用的计算时间;(3)任务的紧迫性;以及(4)你想用这些数据做什么。

这是我在以前的文章中写的许多算法中的一部分。
在这一部分中,我试图尽可能简单地展示和简要解释可用于基于实例的任务的主要算法(尽管不是全部)。

基于实例的算法:

这些算法不执行显式归纳,而是将新的问题实例与训练中看到的实例进行比较,这些实例已经存储在内存中。

K-最近邻(KNN)

可用于分类和回归问题。KNN 存储所有可用病例,并通过其 K 个邻居的多数投票对新病例进行分类。通过在整个训练集中搜索 K 个最相似的实例(邻居)并总结这 K 个实例的输出变量,对新的数据点进行预测。例如,如果我们取 K=3,并且我们想要决定一个新的例子属于哪一类,我们考虑离新的例子最近的 3 个点(通常是欧几里德距离)。

对于回归问题,这可能是平均输出变量:

需要考虑的一些事情:

选择 K 的最佳值最好通过首先检查数据来完成(您可以使用弯头方法)。

这是一种监督学习算法。

学习矢量量化(LVQ)

作为分类算法开发。它能够支持二元(两类)和多类分类问题。K 近邻的一个缺点是,您需要保留整个训练数据集。LVQ 是一种人工神经网络算法,允许您选择要保留多少训练实例,并准确学习这些实例应该是什么样子。实例数量的值在学习过程中被优化。

需要考虑的一些事情:

这是一种监督学习方法

如果您发现 KNN 在数据集上给出了很好的结果,请尝试使用 LVQ 来减少存储整个训练数据集的内存需求。

自组织映射(SOM)

一种无监督的深度学习模型,主要用于特征检测或降维。SOM 不同于其他人工神经网络,因为它应用竞争学习,而不是纠错学习(如梯度下降的反向传播),并且在某种意义上,它们使用邻域函数来保持输入空间的拓扑属性。SOM 执行从高维空间到二维空间的拓扑有序映射。换句话说,它产生训练样本集的输入空间的二维表示。

例如,让我们看看手写数字数据集。SOM 的输入是高维的,因为每个输入维度表示 28×28 图像上一个像素的灰度值,这使得输入是 784 维的(每个维度是 0 到 255 之间的值)。

如果我们将它们映射到 20x20 SOM,并根据它们的真实类别(从 0 到 9 的数字)对它们进行着色,我们将得到以下结果:

真实类别根据左下方的颜色进行标注。

看一下黄色区域。这就是 6 被映射到的地方,请注意与其他类别有一点重叠。相比之下,看看左下方,绿色和棕色的点重叠的地方。这就是高级官员在 4 和 9 之间感到“困惑”的地方。

SOM 的另一个例子是 NLP。我们可以用它对 200 万份医学论文进行分类。SOM 将创建一组意思相似的单词:

右下方的单词与大脑相关,右上方的单词与医学影像相关。

需要考虑的一些事情:

SOM 输出任意数量指标的 2D 图。

我们可以使用 SOM 对数据进行聚类,而不需要知道输入数据的类成员。

局部加权学习(LWL)

LWL 背后的基本思想是,不是为整个函数空间建立全局模型,而是基于查询点的相邻数据为每个感兴趣的点创建局部模型。

为此,每个数据点成为一个加权因子,它表示该数据点对预测的影响。通常,与当前查询点邻近的数据点比远离的数据点接收更高的权重。基本上,假设你想预测未来会发生什么。你可以简单地进入你以前所有经历的数据库,然后抓住一些相似的经历,将它们组合起来(也许通过加权平均,更强地加权更多相似的经历),并使用组合来做出预测。

需要考虑的一些事情:

LWL 方法是非参数的。

如果你对我的更多作品感兴趣,你可以看看我的 Github ,我的学者页面,或者我的网站

最大似然算法:一个标准差(σ)-回归

原文:https://towardsdatascience.com/ml-algorithms-one-sd-σ-regression-47b01d8d51f9?source=collection_archive---------26-----------------------

机器学习回归算法简介

当面对各种各样的机器学习算法时,要问的明显问题是“哪种算法更适合特定的任务,我应该使用哪种算法?”

回答这些问题取决于几个因素,包括:(1)数据的大小、质量和性质;(2)可用的计算时间;(3)任务的紧迫性;以及(4)你想用这些数据做什么。

这是我在以前的文章中写的许多算法中的一部分。
在这一部分,我试图尽可能简单地展示和简要解释可用于回归任务的主要算法(尽管不是全部)。

回归算法:

回归分析是一种预测建模技术,调查因变量(目标)和自变量(预测值)之间的关系。它可用于时间序列建模、预测和寻找变量之间的因果关系。例如,你可以用它来找出司机草率驾驶和交通事故数量之间的关系。

回归分析有几个好处:

它告诉我们因变量和自变量之间的重要关系。

它告诉我们多个自变量对因变量的影响强度。当我说多个独立变量时,我指的是几个 x,例如在“时间延迟和方向对触觉对象识别的影响”中,我们将时间延迟和方向作为 x,将对象识别作为 y。

普通最小二乘回归(OLSR) 线性回归中的一种方法,通过创建一个模型来估计未知参数,该模型将最小化观察数据和预测数据(观察值和估计值)之间的误差平方和。
基本上是计算每个 Xi 的系数( β )的一种方法:

找到β系数的方法是最小化误差,因此称为“最小二乘回归”。当相加时,偏差首先被平方,所以正值和负值之间没有抵消。

OLSR 有一些局限性:冗余信息/两个解释变量之间的线性关联(即共线性)会导致对系数的误解,因此我们需要比 x 变量更多的观测值。为了克服这些,你可以使用 PCR (主成分回归)。

线性回归 用于估计实际价值(房屋成本、通话次数、总销售额等)。)基于连续变量。

需要考虑的一些事情:

自变量和因变量之间必须有线性关系。

多重回归存在多重共线性(多重回归模型中的多重共线性是两个或多个解释变量之间高度线性相关的关联)。

线性回归对异常值非常敏感。

线性回归是一种参数回归。这意味着,它假设因变量和自变量之间的关系的性质是已知的(例如,是线性的)。

您可以使用度量 R-square(R2)-由线性模型解释的响应变量变化的百分比来评估模型性能。

逻辑回归 用于根据给定的独立变量集估计离散值(如 0/1、是/否、真/假等二进制值)。

需要考虑的一些事情:

它用于分类问题。

它不需要因变量和自变量之间的线性关系。

逐步回归 在我们处理多个自变量时使用。它会将特征一个接一个地添加到您的模型中,直到为您的特征集找到最佳分数。逐步选择在向前和向后之间交替,引入和移除满足进入或移除标准的变量,直到获得一组稳定的变量。

需要考虑的一些事情:

它使用 R 平方、t-stats 和 AIC 度量等统计值来识别重要变量。

多元自适应回归样条(MARS

高维数据的灵活回归建模,搜索有助于最大化预测准确性的交互和非线性关系。

这种算法本质上是非线性的(这意味着您不需要通过手动添加模型项(平方项、交互效应)来使您的模型适应数据中的非线性模式)。MARS 是一种非参数回归——它没有对因变量与预测变量之间的关系做出任何假设。相反,它允许回归函数直接由数据“驱动”。MARS 通过一组系数和完全由回归数据确定的所谓基函数(预测值)来构建因变量和自变量之间的关系。

需要考虑的一些事情:

MARS 在数据挖掘领域非常流行,因为它不假设任何特定类型或类别的关系(例如,线性、逻辑等)。)在预测变量和感兴趣的因变量(结果变量)之间。

如果你面对预测者和目标之间复杂的非线性关系,火星可能是有用的,尤其是在高维空间。

连续预测和分类预测都可以用于 MARS。然而,基本的 MARS 算法假设预测变量本质上是连续的。

因为 MARS 可以处理多个因变量,所以也很容易将该算法应用于分类问题。

火星倾向于过度拟合数据。为了克服这个问题,MARS 使用了一种修剪技术(类似于分类树中的修剪),通过减少其基函数的数量来限制模型的复杂性。基函数的选择和修剪使得该方法成为预测器选择的非常有力的工具。基本上,该算法将只选取那些对预测做出“相当大”贡献的基函数(和那些预测变量)。

在回归树模型也适用的情况下,MARS 特别有用,例如,在预测变量上分层组织的连续分割产生准确的预测。

您应该将 MARS 视为回归树的一般化,其中“硬”二元分割被“平滑”基函数所取代,而不是将其视为多元回归的一般化。

局部估计散点图平滑(黄土) 一种用于拟合两个变量之间的平滑曲线,或拟合结果与多达四个预测变量之间的平滑曲面的方法。基本上,它是一种用于回归分析的工具,通过散点图创建一条平滑的线,帮助您看到变量之间的关系并预测趋势。这个想法是,如果你的数据不是线性分布,你仍然可以应用回归的想法。您可以应用回归,这被称为局部加权回归。当自变量和因变量之间的关系是非线性时,可以应用黄土。目前,大多数算法(如经典的前馈神经网络、支持向量机、最近邻算法等。)是全局学习系统,其中它们用于最小化全局损失函数(例如误差平方和)。相比之下,局部学习系统会将全局学习问题分成多个更小/更简单的学习问题。这通常通过将成本函数分成多个独立的局部成本函数来实现。全局方法的缺点之一是有时没有参数值可以提供足够好的近似。但接下来是黄土——全局函数逼近的替代方法。

需要考虑的一些事情:

黄土图通常用于拟合散点图的直线,在散点图中,噪声数据值、稀疏数据点或弱相互关系会干扰您查看最佳拟合直线的能力。

那么我该如何选择使用哪一个呢?

在选择正确的模型之前,数据探索应该是您的第一步(确定变量的关系和影响)。

要比较模型的优劣,您可以使用不同的指标,如参数的统计显著性、R 平方、调整后的 R 平方、AIC、BIC 和误差项。

交叉验证是评估用于预测的模型的最佳方式-将您的数据分为训练和验证。观察值和预测值之间的简单均方差为您提供了预测准确性的度量

还要记住,像套索、岭和弹性网(保持阅读)这样的正则化方法在数据中变量之间的高维度和多重共线性的情况下工作得很好。

如果你对我的更多作品感兴趣,你可以看看我的 Github ,我的学者页面,或者我的网站

ML 算法:一种 SD (σ)-正则化算法

原文:https://towardsdatascience.com/ml-algorithms-one-sd-σ-regularization-algorithms-728af0e92f84?source=collection_archive---------25-----------------------

机器学习正则化算法简介

当面对各种各样的机器学习算法时,要问的明显问题是“哪种算法更适合特定的任务,我应该使用哪种算法?”

回答这些问题取决于几个因素,包括:(1)数据的大小、质量和性质;(2)可用的计算时间;(3)任务的紧迫性;以及(4)你想用这些数据做什么。

这是我在以前的文章中写的许多算法中的一部分。
在这一部分,我试图尽可能简单地展示和简要解释正则化任务的主要算法(虽然不是全部)。

正则化算法:

我发现这些算法特别有用。大多数数据科学家会发现他们的一些模型在他们职业生涯的某个时候过度拟合。这些算法背后的一般思想是,它们试图最小化甚至防止过拟合。

岭回归 ( L2 正规化)

它的目标是解决数据过度拟合的问题,以及当数据出现多重共线性时(多重回归模型中的多重共线性是两个或多个解释变量之间高度线性相关的关联)。在特征变量之间存在高度共线性(独立变量之间存在近似线性关系)的情况下,标准线性或多项式回归模型将会失败。岭回归给变量增加了一个小的平方偏差因子。这种平方偏差因子使特征可变系数远离这种刚性,将少量偏差引入到模型中,但极大地减少了方差。

需要考虑的一些事情:

脊很好地避免了过度拟合。

如果数据集中有一个包含大量要素的模型,并且希望避免模型过于复杂,请使用正则化来解决过度拟合和要素选择问题。

岭有一个主要缺点,它包括最终模型中的所有 N 个特征。

当您有高度相关的变量时,岭回归会使两个系数相互缩小。Lasso 有点无所谓,一般都是挑一个不选一个。

根据上下文,我们不知道选择哪个变量。弹性网是两者之间的折衷,它试图同时收缩和进行稀疏选择。

最小绝对收缩和选择算子(拉索,L1 正则化

与岭回归相反,它只惩罚高系数。当超参数θ足够大时,Lasso 具有迫使某些系数估计精确为零的效果。因此,可以说 Lasso 执行变量选择产生的模型比岭回归产生的模型更容易解释。基本上,它减少了可变性,提高了线性回归模型的准确性。

需要考虑的一些事情:

Lasso 是一种用于执行线性回归的正则化技术。

Lasso 是逐步回归和其他模型选择和降维技术的一种替代方法。

在我们有大量特征的情况下,LASSO 对于特征选择很有效(它减少了冗余的特征并识别出重要的特征)。

它将系数缩减为零(与将系数的“平方值”作为惩罚项添加到损失函数的 Ridge 相比)。

如果一组预测值高度相关,lasso 只选择其中一个,并将其他预测值缩减为零。

其他方法,如交叉验证、逐步回归,对于减少过度拟合和执行特征选择相当有效。但是,它们主要处理少量的功能。山脊线和套索适用于大量要素。

弹力网

结合了套索和脊的特点。弹性网减少了不同特征的影响,同时没有消除所有的特征。Lasso 将消除许多特征,并减少线性模型中的过度拟合。岭将减少在预测 y 值时不重要的要素的影响。弹性网结合了 Lasso 中的要素消除和 Ridge 模型中的要素系数减少来改善模型的预测。

需要考虑的一些事情:

当你有几个高度相关的变量时,使用弹性网。

当有多个相关的特征时很有用。Lasso 可能会随机选择其中一个,而 elastic-net 可能会两个都选。

研究表明,当用于具有高度相关预测值的类似数据时,弹性网技术可以优于 LASSO。

最小角度回归(LARS)

类似于向前逐步回归。在每一步,它都会找到与响应最相关的预测值。当存在具有相等相关性的多个预测器时,不是沿着同一预测器继续,而是在预测器之间的等角方向上继续。最小角度回归就像向前逐步回归的一个更“民主”的版本。它遵循向前逐步回归的相同一般方案,但是没有将预测器完全添加到模型中。该预测器的系数仅增加,直到该预测器不再是与剩余 r 最相关的预测器。然后,邀请一些其他竞争预测器“加入俱乐部”。它从所有系数都等于零开始,然后找到与 y 最相关的预测值。它在与 y 相关的符号方向上增加系数,然后在此过程中获取残差,当其他一些预测值与 r 的相关性与第一个预测值一样大时停止。

需要考虑的一些事情:

当维数明显大于点数时,这是有用的

如果两个变量与响应的相关性几乎相等,那么它们的系数应该以大致相同的速率增加。

如果数据是高维的或者有多重共线性,就不能很好地工作。

如果你对我的更多作品感兴趣,你可以看看我的 Github ,我的学者页面,或者我的网站

时间序列的 ML 方法

原文:https://towardsdatascience.com/ml-approaches-for-time-series-4d44722e48fe?source=collection_archive---------0-----------------------

时间序列数据的机器学习方法

用非常规模型模拟时间序列

在这篇文章中,我尝试了一些机器学习技术来分析时间序列数据,并探索它们在这种情况下的潜在用途。

在这第一篇文章中,只开发了索引的第一点。其余的有一个单独的帖子,可以从索引中访问。

注意:这项工作是在 2017 年初完成的,所以很可能有些库已经更新了。

索引

1 —数据创建、窗口和基线模型
2 —遗传编程:符号回归
3 —极限学习机
4 —高斯过程
5—卷积神经网络

1 —数据创建、窗口和基线模型

1.1 —数据创建

在这项工作中,我们将对非均匀间隔时间序列数据进行分析。我们将创建 3 个随机变量 x1x2x3 的合成数据,并向这些变量的一些滞后的线性组合添加一些噪声,我们将确定 y,即响应。

这样,我们可以确保函数不是 100%可预测的,响应取决于预测器,并且存在由预测器的先前滞后对响应的影响引起的时间依赖性

该 python 脚本将在给定时间序列数据的情况下创建窗口,以便以一种我们可以为模型提供尽可能完整的信息的方式来构建问题。

让我们看看,首先,我们有哪些数据,我们将采用什么样的治疗方法。

N = 600

t = np.arange(0, N, 1).reshape(-1,1)
t = np.array([t[i] + np.random.rand(1)/4 **for** i **in** range(len(t))])
t = np.array([t[i] - np.random.rand(1)/7 **for** i **in** range(len(t))])
t = np.array(np.round(t, 2))

x1 = np.round((np.random.random(N) * 5).reshape(-1,1), 2)
x2 = np.round((np.random.random(N) * 5).reshape(-1,1), 2)
x3 = np.round((np.random.random(N) * 5).reshape(-1,1), 2)

n = np.round((np.random.random(N) * 2).reshape(-1,1), 2)

y = np.array([((np.log(np.abs(2 + x1[t])) - x2[t-1]**2) + 0.02*x3[t-3]*np.exp(x1[t-1])) **for** t **in** range(len(t))])
y = np.round(y+n, 2)

然后,我们有一个函数 y,它是 3 个独立随机变量的响应,并带有一个附加噪声。此外,响应与独立变量的滞后直接相关,而不仅仅是与它们在给定点的值相关。这样我们确保了时间依赖性,并且我们强制我们的模型能够识别这种行为。

此外,时间戳的间隔也不均匀。通过这种方式,我们强化了这样一个想法,即我们希望我们的模型能够理解时间依赖性,因为它们不能仅仅根据观察值(行)的数量来处理序列。

我们包含了指数和对数运算符,目的是在数据中引入高度非线性

1.2 —窗户框架

这项工作的所有模型所遵循的方法是通过固定的窗口来重塑我们所拥有的信息,这些窗口将在给定的时间点从最近的过去给模型提供尽可能最完整的信息,以便实现准确的预测。此外,我们将检查将响应本身的先前值作为独立变量如何影响模型。

让我们看看我们将如何去做:

图中只显示了时间轴和响应。记住,在我们的例子中,还有 3 个变量负责 t 的值。

顶部的图片显示了一个选定(固定)尺寸 w 的窗口,在本例中为 4。这意味着,模型将映射包含在该窗口中的信息,预测点在 t+1 。响应的大小中有一个 r,因为我们可能想要预测过去的几个时间步长。这将是一种多对多关系。为了简单和更容易可视化,我们将使用r=1

我们现在可以看到滑动窗口的效果。通过将窗口移动一个时间步到未来,并像我们在上一步中所做的那样继续,获得模型将具有的用于找到映射函数的下一对输入-输出。

那好吧。我们如何将它应用到当前的数据集?让我们看看我们需要什么,并建立我们的助手功能。
但是首先,我们不希望时间是绝对值,我们更感兴趣的是知道哪一个是观察之间的经过时间(记住数据不是均匀分布的!).因此,我们创建一个 t,看看我们的数据。

dataset = pd.DataFrame(np.concatenate((t, x1, x2, x3, y), axis=1), 
                       columns=['t', 'x1', 'x2', 'x3', 'y'])

deltaT = np.array([(dataset.t[i + 1] - dataset.t[i]) **for** i **in** range(len(dataset)-1)])
deltaT = np.concatenate((np.array([0]), deltaT))

dataset.insert(1, '∆t', deltaT)
dataset.head(3)

现在我们知道了数据集的样子,让我们重新创建我们希望我们的帮助函数在一个表的方案上做什么。

对于尺寸为 4 的窗户:

我们的函数要做的是展平窗口中包含的所有信息,即 W 窗口中的所有值,以及我们希望进行预测的时间戳。

这样,我们可以有两个不同的方程来模拟我们的系统,这取决于我们是否包括以前的响应值作为新的预测值。

该函数必须返回的结果应该如下所示:

我们将能够创建l = n - (w+r) +1窗口,因为我们丢失了第一行,因为我们没有关于 Y(0) 的第一个值的先前信息。

我们提到的所有滞后就像模型的新预测器(在这个可视化中,不包括先前的值 Y ,它们将遵循与 Xi 相同的值)。然后,我们希望进行预测的时间戳(经过的时间)∏t(4),以及预测应该是什么的对应值 Y(4) 。请注意,所有第一个∏t(0)都被初始化为 0 ,因为我们希望将每个窗口标准化为相同的范围。

下面是为实现这一过程而创建的代码。有一个函数 WindowSlider,通过它我们可以创建对象来构造不同的窗口,改变参数。

3 —基线模型

“总是先做简单的事情。只在需要的时候运用智慧”——萨德·斯塔纳

创建窗口

w = 5
train_constructor = WindowSlider()
train_windows = train_constructor.collect_windows(trainset.iloc[:,1:], 
                                                  previous_y=**False**)

test_constructor = WindowSlider()
test_windows = test_constructor.collect_windows(testset.iloc[:,1:],
                                                previous_y=**False**)

train_constructor_y_inc = WindowSlider()
train_windows_y_inc = train_constructor_y_inc.collect_windows(trainset.iloc[:,1:], 
                                                  previous_y=**True**)

test_constructor_y_inc = WindowSlider()
test_windows_y_inc = test_constructor_y_inc.collect_windows(testset.iloc[:,1:],
                                                previous_y=**True**)

train_windows.head(3)

我们可以看到窗口是如何为每个预测带来的,剩余变量过去(window_length)时间步长的记录,以及∏t的累加和。

预测=当前

我们将首先从一个简单的模型开始,该模型将给出最后一个值(每个预测点的当前值)作为下一个时间戳的预测。

*# ________________ Y_pred = current Y ________________* 
bl_trainset = cp.deepcopy(trainset)
bl_testset = cp.deepcopy(testset)

bl_y = pd.DataFrame(bl_testset['y'])
bl_y_pred = bl_y.shift(periods=1)

bl_residuals = bl_y_pred - bl_y
bl_rmse = np.sqrt(np.sum(np.power(bl_residuals,2)) / len(bl_residuals))
print('RMSE = **%.2f**' % bl_rmse)
print('Time to train = **0** seconds')## RMSE = 11.28

结论我们已经有了一个值,可以与即将得出的结果进行比较。我们应用了给定我的当前值作为预测的简单规则。对于响应值更稳定(即平稳)的时间序列,这种方法有时比最大似然算法表现得更好。在这种情况下,数据的曲折是众所周知的,导致预测能力很差。

多元线性回归

我们的下一个方法是建立一个多元线性回归模型

*# ______________ MULTIPLE LINEAR REGRESSION ______________ #***from** **sklearn.linear_model** **import** LinearRegression
lr_model = LinearRegression()
lr_model.fit(trainset.iloc[:,:-1], trainset.iloc[:,-1])

t0 = time.time()
lr_y = testset['y'].values
lr_y_fit = lr_model.predict(trainset.iloc[:,:-1])
lr_y_pred = lr_model.predict(testset.iloc[:,:-1])
tF = time.time()

lr_residuals = lr_y_pred - lr_y
lr_rmse = np.sqrt(np.sum(np.power(lr_residuals,2)) / len(lr_residuals))
print('RMSE = **%.2f**' % lr_rmse)
print('Time to train = **%.2f** seconds' % (tF - t0))## RMSE = 8.61 
## Time to train = 0.00 seconds

结论

我们可以看到多元线性回归模型是如何无法捕捉到反应行为的。这可能是因为响应和独立变量之间的非线性关系。此外,正是这些变量的滞后影响了给定时间的响应。因此,对于找不到映射此关系的模型,这些值位于不同的行中。

我很想检查一下我们在解释窗户结构时所做的假设。我们说过,我们希望为每个预测点建立一个完整的信息集。因此,预测能力应该增加后,建设的窗口…让我们去吧!

带窗口的 MLR

*# ___________ MULTIPLE LINEAR REGRESSION ON WINDOWS ___________* **from** **sklearn.linear_model** **import** LinearRegression
lr_model = LinearRegression()
lr_model.fit(train_windows.iloc[:,:-1], train_windows.iloc[:,-1])

t0 = time.time()
lr_y = test_windows['y'].values
lr_y_fit = lr_model.predict(train_windows.iloc[:,:-1])
lr_y_pred = lr_model.predict(test_windows.iloc[:,:-1])
tF = time.time()

lr_residuals = lr_y_pred - lr_y
lr_rmse = np.sqrt(np.sum(np.power(lr_residuals,2)) / len(lr_residuals))
print('RMSE = **%.2f**' % lr_rmse)
print('Time to train = **%.2f** seconds' % (tF - t0))## RMSE = 3.84
## Time to train = 0.00 seconds

哇!这绝对是一大进步。现在我们有一个非常强大的模型要打败。似乎有了新的窗口,模型能够找到整个窗口信息和响应之间的关系。

2 —符号回归

符号回归是一种回归分析,它搜索数学表达式的空间,以找到最适合给定数据集的模型。

符号回归的基础是 遗传规划 ,因此,它是一种进化算法(又名遗传算法——GA)

简单总结一下算法是如何工作的,首先我们需要理解一个数学表达式可以表示为一个树形结构,如上图所示。

这样,算法将从第一代的大量树木开始,根据适应度函数来测量,在我们的例子中是 RMSE。然后,每一代中最好的个体在它们之间进行交叉,并且应用一些突变,以包括探索和随机性。当满足停止标准时,该迭代算法结束。

这个视频是对基因编程的精彩解释。

型号

****

结论

我们已经看到,符号回归表现出令人难以置信的好,几乎完美地符合验证数据。

令人惊讶的是,我通过只包含四个最简单的操作符(加、减、乘、除)获得了最好的准确性,缺点是需要更多的训练时间。

我鼓励你尝试模型的不同参数并改进结果!

3 —极限学习机

极端学习机是一种重要的涌现机器学习技术。这些技术的主要方面是它们不需要学习过程来计算模型的参数。

本质上,EML 是一个单层前馈神经网络 (SLFN) 。ELM 理论表明,该隐藏层的权重值不需要调整,因此与训练数据无关。

通用逼近属性 意味着,如果 EML 有足够的隐藏神经元和训练数据来学习所有隐藏神经元的参数,它可以以期望的精度解决任何回归问题。

EML 还受益于模型结构和正则化,这减少了随机初始化和过度拟合的负面影响。

给定一组 N 个训练样本(x, t)。具有 L 个隐藏神经元输出的 SLFN 是:

目标与网络的输入和输出之间的关系是:

隐藏的神经元分两步将输入数据转换成不同的表示。首先,通过输入层的权重和偏差将数据投影到隐藏层,然后对结果应用非线性激活函数。

实际上,ELMs 是以矩阵形式作为普通神经网络来求解的。矩阵形式如下所示:

这就是这个方法的重要部分。给定 T 是我们想要达到的目标,使用摩尔-彭罗斯广义逆可以找到具有最小平方误差的系统的唯一解。因此,我们可以在一个单独的操作中计算隐藏层的权重值,这将导致预测目标 t 的误差最小的解决方案

使用奇异值分解计算这个伪逆

在这篇文章中,有一个关于 EML 如何工作的详细描述,以及一个用于 EML 的高性能工具箱的包,以及在 MATLAB 和 Python 中的实现。

模型

不考虑 y 的先前值作为特征

RMSE = 3.77
Time to train 0.12

考虑 y 的先前值作为特征

RMSE = 6.37
Time to train 0.00

结论

我们可以看到 EML 对我们的数据有很强的预测能力。此外,如果我们把以前的反应值作为预测值,结果会更糟。

毫无疑问,EML 是需要继续探索的模型,这是一个快速的实现,已经显示了它们的强大功能,它们能够通过简单的矩阵求逆和很少的运算来计算精度。

在线学习

EMLs 最大的优势在于,对于实现在线模型来说,它们在计算上非常便宜。在这篇文章中有更多关于更新和 downdate 操作的信息。

在几行中,我们可以说模型变得自适应,并且如果预测误差超过一个稳定的阈值,这个特定的数据点被合并到 SVD 中,因此模型不需要昂贵的完全再训练。这样,模型可以适应过程中可能发生的变化,并从中学习。

4 —高斯过程

这篇文章是一系列文章的一部分。首发哨车发现在这里

高斯过程是随机变量的集合,使得这些随机变量的每个有限集合都具有多元正态分布,这意味着它们的每个可能的线性组合都是正态分布的。(高斯过程可以看作多元正态分布的无限维推广)。

GP 的分布是所有那些随机变量的 联合分布 。简而言之,GPs 使用确定点之间相似性的核函数来预测一个看不见的点的值。

这个视频是预测二氧化碳水平的高斯过程的精彩快速介绍。
这本书是高斯过程的主要指南。

GP 的一个明显的优势是,我们在每次预测时都获得一个标准偏差,这可以很容易地用来计算预测的置信区间。

模型

一个非常简单的 CNN 游戏:

不考虑 y 的先前值作为特征

RMSE = 2.320005
Time to train 4.17

考虑 y 的先前值作为特征

如果我们不向模型显示响应的先前值,那么验证的性能要差得多。

结论

我们已经看到高斯过程是另一种具有高预测能力的奇妙方法。该模型在引入以前的响应值作为预测值时也得到更差的结果。

主要的一点是,我们可以通过调整内核的几乎无限组合来寻找随机变量的组合,它们的联合分布更好地符合我们的模型。我鼓励您尝试您自己的内核并改进这些结果!

5-卷积神经网络

这个想法是,窗口的前一个值定义为一个 画面 在给定时间过程的状态。

因此,我们对图像识别使用并行性,因为我们希望找到将“图片”映射到响应值的模式。我们在timeseries.py中包含了一个新函数WindowsToPictures()

该函数将我们一直使用的窗口作为输入,并为响应中的每个值创建一个图片,该图片包含所有列的窗口长度的所有先前值。

如果我们还记得第一章中对窗户的改造,这一次,窗户不会变平。相反,它们将被堆叠在 3D 张量的第三维中,其中每个切片将是用唯一响应值映射的图片。下面是一个例子:

模型

不考虑 y 的先前值作为特征

RMSE = 4.21

考虑 y 的先前值作为特征

RMSE = 3.59

结论

对于多变量时间序列预测,将过程的先前状态作为每个时间步的过程图似乎是一种合理的方法。

这种方法允许将问题构建成任何类型的问题,例如金融时间序列预测、温度/天气预测、过程变量监控…

我仍然想考虑创建窗口和图片的新方法来改善结果,但对我来说,它看起来像一个防止过度拟合的健壮模块,正如我们在峰值中看到的那样,它从来没有超过实际值。

我很想知道你想出什么来改善它!

ML 基础:贷款预测

原文:https://towardsdatascience.com/ml-basics-loan-prediction-d695ba7f31f6?source=collection_archive---------2-----------------------

一个简单问题的完整数据科学管道

Photo by Dmitry Demidko on Unsplash

问题是:

梦想住房金融公司处理所有房屋贷款。他们遍布所有城市、半城市和农村地区。在公司确认客户贷款资格后,客户首先申请住房贷款。

该公司希望根据填写在线申请表时提供的客户详细信息自动执行贷款资格流程(实时)。这些详细信息包括性别、婚姻状况、教育程度、受抚养人人数、收入、贷款金额、信用记录等。为了实现这一过程的自动化,他们提出了一个问题来确定客户群,即那些有资格获得贷款金额的客户,以便他们可以专门针对这些客户。

这是一个分类问题,给定关于申请的信息,我们必须预测他们是否会偿还贷款。

我们将从探索性数据分析开始,然后是预处理,最后我们将测试不同的模型,如逻辑回归和决策树。

该数据由以下行组成:

**Loan_ID :** Unique Loan ID**Gender :** Male/ Female**Married :** Applicant married (Y/N)**Dependents :** Number of dependents **Education :** Applicant Education (Graduate/ Under Graduate)**Self_Employed :** Self employed (Y/N)**ApplicantIncome :** Applicant income**CoapplicantIncome :** Coapplicant income**LoanAmount :** Loan amount in thousands of dollars**Loan_Amount_Term :** Term of loan in months**Credit_History :** credit history meets guidelines yes or no**Property_Area :** Urban/ Semi Urban/ Rural**Loan_Status :** Loan approved (Y/N) this is the target variable

探索性数据分析:

我们将使用 seaborn 进行可视化,使用 pandas 进行数据处理。可以从这里下载数据集:https://data hack . analyticsvidhya . com/contest/practice-problem-loan-prediction-iii/

我们将导入必要的库并加载数据:

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
%matplotlib inline
import numpy as nptrain=pd.read_csv("train.csv")
test=pd.read_csv("test.csv")

我们可以使用 head 函数来查看顶部的几行

train.head()

Image by Author

我们可以看到有一些缺失的数据,我们可以使用 pandas describe 函数进一步探究这一点:

train.describe()

Image by Author

一些变量有缺失值,我们必须处理,而且申请人收入、共同申请人收入和贷款金额似乎也有一些异常值。我们也看到大约 84%的申请者有信用记录。因为 Credit_History 字段的平均值为 0.84,并且它有两个值(1 表示有信用记录,0 表示没有)

研究数字变量(主要是申请人收入和贷款金额)的分布是很有趣的。为此,我们将使用 seaborn 进行可视化。

sns.distplot(train.ApplicantIncome,kde=False)

Image by Author

分布是偏斜的,我们可以注意到相当多的异常值。

由于贷款金额有缺失值,我们不能直接绘制它。一种解决方案是删除缺失的值行,然后绘制它,我们可以使用 dropna 函数来实现

sns.distplot(train.ApplicantIncome.dropna(),kde=False)

Image by Author

受过良好教育的人通常应该有较高的收入,我们可以通过绘制教育水平与收入的关系来验证这一点。

sns.boxplot(x='Education',y='ApplicantIncome',data=train)

Image by Author

分布非常相似,但我们可以看到毕业生有更多的离群值,这意味着高收入的人最有可能受过良好的教育。

另一个有趣的变量是信用历史,为了检查它如何影响贷款状态,我们可以将其转换为二进制,然后计算信用历史每个值的平均值。接近 1 的值表示贷款成功率高

#turn loan status into binary 
modified=train
modified['Loan_Status']=train['Loan_Status'].apply(lambda x: 0 if x=="N" else 1 )
#calculate the mean
modified.groupby('Credit_History').mean()['Loan_Status']OUT : 
Credit_History
0.0    0.078652
1.0    0.795789
Name: Loan_Status, dtype: float64

有信用记录的人更有可能还贷,比例为 0.07 比 0.79。这意味着信用历史将是我们模型中的一个有影响的变量。

数据预处理:

首先要做的是处理缺失值,让我们先检查每个变量有多少个缺失值。

train.apply(lambda x: sum(x.isnull()),axis=0)
OUT:
Loan_ID               0
Gender               13
Married               3
Dependents           15
Education             0
Self_Employed        32
ApplicantIncome       0
CoapplicantIncome     0
LoanAmount           22
Loan_Amount_Term     14
Credit_History       50
Property_Area         0
Loan_Status           0
dtype: int64

对于数值,一个好的解决方案是用平均值填充缺失值,对于分类,我们可以用众数(出现频率最高的值)填充它们

#categorical
train['Gender'].fillna(train['Gender'].mode()[0], inplace=True)
train['Married'].fillna(train['Married'].mode()[0], inplace=True)
train['Dependents'].fillna(train['Dependents'].mode()[0], inplace=True)
train['Loan_Amount_Term'].fillna(train['Loan_Amount_Term'].mode()[0], inplace=True)
train['Credit_History'].fillna(train['Credit_History'].mode()[0], inplace=True)
train['Self_Employed'].fillna(train['Self_Employed'].mode()[0], inplace=True)
#numericaldf['LoanAmount'].fillna(df['LoanAmount'].mean(), inplace=True)

接下来,我们必须处理离群值,一个解决方案是删除它们,但我们也可以对它们进行对数变换,以消除它们的影响,这是我们在这里采用的方法。有些人可能收入很低,但有很强的共同收入,所以一个好主意是把他们放在一个总收入栏里。

train['LoanAmount_log']=np.log(train['LoanAmount'])
train['TotalIncome']= train['ApplicantIncome'] +train['CoapplicantIncome'] train['TotalIncome_log']=np.log(train['TotalIncome'])

绘制贷款金额日志的直方图我们可以看到它是一个正态分布!

Image by Author

建模:

我们将在模型中使用 sklearn,在此之前,我们需要将所有分类变量转换为数字。我们将使用 sklearn 中的 LabelEncoder 来实现这一点

from sklearn.preprocessing import LabelEncoder
category= ['Gender','Married','Dependents','Education','Self_Employed','Property_Area','Loan_Status'] 
encoder= LabelEncoder()
 for i in category:   
  train[i] = encoder.fit_transform(train[i]) 
  train.dtypesOUT:
Loan_ID               object
Gender                 int64
Married                int64
Dependents             int64
Education              int64
Self_Employed          int64
ApplicantIncome        int64
CoapplicantIncome    float64
LoanAmount           float64
Loan_Amount_Term     float64
Credit_History       float64
Property_Area          int64
Loan_Status            int64
LoanAmount_log       float64
TotalIncome          float64
TotalIncome_log      float64
dtype: object

现在我们所有的变量都变成了我们的模型可以理解的数字。

为了尝试不同的模型,我们将创建一个函数,该函数接受一个模型,对其进行拟合,并测量其准确性,这意味着在训练集上使用该模型,并在同一集上测量误差。我们将使用一种称为 Kfold cross validation 的技术,它将数据随机分为训练集和测试集,使用训练集训练模型,并用测试集验证它,它将重复 K 次,因此命名为 Kfold,并取平均误差。后一种方法可以更好地了解模型在现实生活中的表现。

#Import the models
from sklearn.linear_model import LogisticRegression
from sklearn.cross_validation import KFold   #For K-fold cross validation
from sklearn.ensemble import RandomForestClassifier
from sklearn.tree import DecisionTreeClassifier, export_graphviz
from sklearn import metricsdef classification_model(model, data, predictors, outcome):
  #Fit the model:
  model.fit(data[predictors],data[outcome])

  #Make predictions on training set:
  predictions = model.predict(data[predictors])

  #Print accuracy
  accuracy = metrics.accuracy_score(predictions,data[outcome])
  print ("Accuracy : %s" % "{0:.3%}".format(accuracy))#Perform k-fold cross-validation with 5 folds
  kf = KFold(data.shape[0], n_folds=5)
  error = []
  for train, test in kf:
    # Filter training data
    train_predictors = (data[predictors].iloc[train,:])

    # The target we're using to train the algorithm.
    train_target = data[outcome].iloc[train]

    # Training the algorithm using the predictors and target.
    model.fit(train_predictors, train_target)

    #Record error from each cross-validation run
    error.append(model.score(data[predictors].iloc[test,:], data[outcome].iloc[test]))

  print ("Cross-Validation Score : %s" % "{0:.3%}".format(np.mean(error)))

现在我们可以测试不同的模型,我们将从逻辑回归开始:

outcome_var = 'Loan_Status'
model = LogisticRegression()
predictor_var = ['Credit_History','Education','Married','Self_Employed','Property_Area']
classification_model(model, train,predictor_var,outcome_var)
OUT : 
Accuracy : 80.945%
Cross-Validation Score : 80.946%

我们现在将尝试一个决策树,它应该会给我们更准确的结果

model = DecisionTreeClassifier() predictor_var = ['Credit_History','Gender','Married','Education'] classification_model(model, df,predictor_var,outcome_var)OUT:
Accuracy : 80.945%
Cross-Validation Score : 78.179%

我们在准确性上得到了相同的分数,但在交叉验证上得分更低,更复杂的模型并不总是意味着更好的分数。

最后,我们将尝试随机森林

model = RandomForestClassifier(n_estimators=100)
predictor_var = ['Gender', 'Married', 'Dependents', 'Education',
       'Self_Employed', 'Loan_Amount_Term', 'Credit_History', 'Property_Area',
        'LoanAmount_log','TotalIncome_log']
classification_model(model, train,predictor_var,outcome_var)OUT: 
Accuracy : 100.000%
Cross-Validation Score : 78.015%

该模型在准确性上给了我们满分,但在交叉验证上得分很低,这是过度拟合的一个很好的例子。该模型很难推广,因为它非常适合训练集。

对此的解决方案包括:减少预测器的数量或调整模型参数。

结论:

在本文中,我们已经讨论了数据科学的大部分内容,即 EDA、预处理和建模,并且使用了基本的分类模型,如逻辑回归、决策树和随机森林。了解更多关于这些算法背后的主干逻辑,以及处理数据采集和部署阶段将会很有趣。我们将在下一篇文章中尝试这样做。

ML 设计模式#2:检查点

原文:https://towardsdatascience.com/ml-design-pattern-2-checkpoints-e6ca25a4c5fe?source=collection_archive---------18-----------------------

在训练期间保存模型的中间权重可以提供弹性、泛化和可调性

偶尔为 ML 工程师设计的一系列设计模式。 完整列表在此。

机器学习流水线的关键步骤是训练模型(使用 Keras 中的model.fit())、评估模型(使用model.evaluate())、导出模型(使用model.save())、部署模型(使用gcloud ai-platform versions create)以及通过访问模型的 REST API 使用模型进行预测。然而,有时使用检查点对训练和评估循环进行更多的控制会更好。

一个检查点是一个模型的整个内部状态(它的权重,当前学习率等)的中间转储。)以便框架可以在任何需要的时候从这一点继续训练。包括检查点后,ML 管道变成:

换句话说,你训练一些迭代,然后评估模型,检查它,然后再拟合一些。完成后,保存模型,并像平常一样部署它。

保存中间检查点有几个好处:

  • 韧性:如果你正在进行非常长时间的训练,或者在很多机器上进行分布式训练,那么机器出现故障的可能性就会增加。如果机器出现故障,TensorFlow 可以从最后保存的检查点恢复,而不必从头开始。此行为是自动的— TensorFlow 会查找检查点并从最后一个检查点恢复。
  • 泛化:一般来说,训练时间越长,训练数据集上的损失越低。然而,在某一点上,被搁置的评估数据集上的误差可能停止减小。如果您有一个非常大的模型,并且没有进行充分的正则化,则评估数据集上的误差甚至可能开始增加。如果发生这种情况,返回并导出具有最佳验证错误的模型会很有帮助。这也被称为提前停止,因为如果您看到验证错误开始增加,您可以停止。(当然,一个更好的想法是降低模型复杂性或增加正则化,这样就不会发生这种情况)。您可以返回到最佳验证错误或提前停止的唯一方法是,如果您已经定期评估和检查模型。
  • 可调性:在一个表现良好的训练循环中,梯度下降的表现是,你可以根据你的大部分数据快速到达最佳误差的邻域,然后通过优化拐角情况慢慢收敛到最低误差。现在,假设您需要定期根据新数据重新训练模型。你通常希望强调新的数据,而不是上个月的关键案例。你最好不要从最后一个检查点开始训练,而是从蓝线标记的检查点开始:

要在 Keras 中检查模型,请提供一个回调:

trainds = load_dataset('taxi-train*', TRAIN_BATCH_SIZE, tf.estimator.ModeKeys.TRAIN)
evalds = load_dataset('taxi-valid*', 1000, tf.estimator.ModeKeys.EVAL).take(NUM_EVAL_EXAMPLES)steps_per_epoch = NUM_TRAIN_EXAMPLES // (TRAIN_BATCH_SIZE * NUM_EVALS)shutil.rmtree('{}/checkpoints/'.format(OUTDIR), ignore_errors=True)
checkpoint_path = '{}/checkpoints/taxi'.format(OUTDIR)
**cp_callback = tf.keras.callbacks.ModelCheckpoint(checkpoint_path, 
                                                 save_weights_only=True,
                                                 verbose=1)**history = model.fit(trainds, 
                    validation_data=evalds,
                    epochs=NUM_EVALS, 
                    steps_per_epoch=steps_per_epoch,
                    verbose=2, # 0=silent, 1=progress bar, 2=one line per epoch
                    **callbacks=[cp_callback]**)

尽情享受吧!

ML 设计模式#4:键控预测

原文:https://towardsdatascience.com/ml-design-pattern-4-keyed-predictions-a8de67d9c0f4?source=collection_archive---------25-----------------------

导出您的模型,以便它通过客户端密钥

给 ML 工程师的一系列偶然的设计模式。 完整列表在此。

通常情况下,您可以在模型将被实时提供的同一组输入上训练您的模型。然而,在许多情况下,让您的模型也传递一个客户端提供的密钥可能是有利的。

Client-supplied keys are essential for high-performance serving infrastructure. Photo by Florian Berger on Unsplash

服务基础设施的热点

如果您的模型被部署为 web 服务并接受单个输入,那么哪个输出对应于哪个输入是非常清楚的。如果模型接受一组输入会怎么样?您可能会认为,第一个输出实例对应于第一个输入实例,第二个输出实例对应于第二个输入实例,等等,这应该是显而易见的。但是,这种 1:1 的关系会在您的服务基础设施中产生大量热点,因为无论哪个服务器节点不幸接收到特别大的请求,都需要计算阵列中所有实例的输出。这些热点将迫使你使你的服务器比他们需要的更强大。

当然,如果接收节点可以将实例外包给一个集群,收集所有结果输出,然后将它们发送回来,效率会高得多。但是如果它这样做了,那么输出就会变得混乱。客户端如何判断哪个输出对应于哪个输入?

传递键

解决方案?让客户端提供一个与每个输入相关联的键。例如,假设您的模型使用三个输入(a、b、c)进行训练,显示为绿色,以产生输出 d,显示为黄色。让你的客户提供(k,a,b,c)给你的模型,其中 k 是一个。这个键可以简单到给输入实例编号 1、2、3 等等。然后,您的模型将返回(k,d ),因此客户端将能够计算出哪个输出实例对应于哪个输入实例。

Clients supply a key with each input instance, so that they can disambiguate the outputs

这与您进行批量预测时会遇到的情况完全相同,因此键在这种情况下也很有用。

为什么密钥应该由客户提供?

等等……为什么服务器不能在调用模型之前给接收到的输入分配键,然后在发送输出之前删除键呢?为什么要求客户指定一个键?

这是因为键在其他一些情况下也很有用——异步服务和评估。如今许多生产机器学习模型是神经网络,神经网络涉及矩阵乘法。如果您可以确保矩阵在特定的大小范围内和/或特定数字的倍数内,GPU 和 TPU 等硬件上的矩阵乘法会更有效。因此,累积请求(当然达到最大延迟)并分块处理传入的请求会很有帮助。因为块将由来自多个客户机的交叉请求组成,所以在这种情况下,键也需要有某种客户机标识符。

如果您正在进行持续评估,记录有关预测请求的元数据会很有帮助,这样您就可以监视性能是全面下降,还是仅在特定情况下下降。如果关键点确定了所讨论的情况,这种切片就容易多了。

因为高性能服务器将支持多个客户端,由一个集群支持,并批量处理请求以获得性能优势,所以最好提前做好计划—要求客户端为每个预测提供密钥,并要求客户端指定不会导致与其他客户端冲突的密钥。

如何在 Keras 中传递密钥

为了让您的 Keras 模型通过密钥,在导出模型时提供一个服务签名。

例如,这是获取一个模型的代码,否则该模型将接受 4 个输入(is_male、mother_age、multiplies 和 importation _ weeks ),并让它还接受一个键,该键将与模型的原始输出(婴儿体重)一起传递给输出:

# Serving function that passes through keys
[@tf](http://twitter.com/tf).function(input_signature=[{
      'is_male': tf.TensorSpec([None,], dtype=tf.string, name='is_male'),
      'mother_age': tf.TensorSpec([None,], dtype=tf.float32, name='mother_age'),
      'plurality': tf.TensorSpec([None,], dtype=tf.string, name='plurality'),
      'gestation_weeks': tf.TensorSpec([None,], dtype=tf.float32, name='gestation_weeks'),
      'key': tf.TensorSpec([None,], dtype=tf.string, name='key')
}])
def my_serve(inputs):
    feats = inputs.copy()
    key = feats.pop('key')
    output = model(feats)
    return {'key': key, 'babyweight': output}tf.saved_model.save(model, EXPORT_PATH, 
                    signatures={'serving_default': my_serve})

请注意,即使原始模型没有用服务函数保存,上面的代码也可以工作。只需使用 tf.saved_model.load()加载模型,附加一个服务函数并使用上面的代码片段!

Load a SavedModel, attach a non-default serving function and save it.

尽情享受吧!

ML 设计模式#5:可重复采样

原文:https://towardsdatascience.com/ml-design-pattern-5-repeatable-sampling-c0ccb2889f39?source=collection_archive---------10-----------------------

使用分布良好的列将数据分为训练/有效/测试

给 ML 工程师的一系列偶然的设计模式。 完整列表在此。

许多机器学习教程会建议您将数据随机分成训练、验证和测试数据集:

df = pd.DataFrame(...)rnd = np.random.rand(len(df))
train = df[ rnd < 0.8  ]
valid = df[ rnd >= 0.8 & rnd < 0.9 ]
test  = df[ rnd >= 0.9 ]

问题是,这在许多现实世界的情况下都失败了。原因是这些行很少是独立的。例如,如果您正在训练一个预测航班延误的模型,则同一天航班的到达延误将彼此高度相关。这叫做,是做机器学习时要避免的重要问题。

Use the Farm Fingerprint hashing algorithm on a well-distributed column to split your data into train/valid/test

解决方案是基于日期列拆分数据集:

SELECT
  airline,
  departure_airport,
  departure_schedule,
  arrival_airport,
  arrival_delay
FROM
  `bigquery-samples`.airline_ontime_data.flights
WHERE
  ABS(MOD(FARM_FINGERPRINT(date), 10)) < 8 -- 80% for TRAIN

除了解决最初的问题(数据泄漏),这还为您提供了可重复性:

  1. FARM_FINGERPRINT 是一种开源哈希算法,在 C++(因此:Java 或 Python)和 BigQuery SQL 中实现一致。
  2. 任何给定日期的所有航班都属于同一个分段——列车、有效或测试。这是可重复的,与随机种子无关。

选择拆分列

如何选择要拆分的列?日期列必须具有几个特征,以便我们能够将其用作拆分列:

  1. 相同日期的行往往是相关的,这也是我们希望确保相同日期的所有行都在相同的拆分中的主要原因。
  2. 日期不是模型的输入(从日期中提取的要素(如 dayofweek 或 hourofday)可以是输入,但不能使用实际输入进行分割,因为经过训练的模型不会看到 20%的可能输入值)。
  3. 必须有足够的日期值。因为您正在计算散列值并寻找相对于 10 的模,所以您至少需要 10 个唯一的散列值。当然,你拥有的独特价值观越多越好。为了安全起见,取模的分母为 3–5 倍,因此在这种情况下,您需要 50 个或更多的唯一日期。
  4. 标签必须在日期之间分布均匀。如果结果是所有的延迟都发生在 1 月 1 日和一年中的其他时间,没有延迟,这将不起作用,因为分割的数据集将是倾斜的。为了安全起见,请查看一个图表,并确保所有三个拆分都具有相似的标签分布(根据出发延误或其他输入值)。您可以使用 Kolomogorov-Smirnov 测试来实现自动化。

变体 1:单一查询

您不需要三个单独的查询来生成训练、验证和测试分割。您可以在一个查询中完成,如下所示:

CREATE OR REPLACE TABLE mydataset.mytable ASSELECT
  airline,
  departure_airport,
  departure_schedule,
  arrival_airport,
  arrival_delay,
  **CASE(ABS(MOD(FARM_FINGERPRINT(date), 10)))
      WHEN 9 THEN 'test'
      WHEN 8 THEN 'validation'
      ELSE 'training' END AS split_col**
FROM
  `bigquery-samples`.airline_ontime_data.flights

变体 2:随机拆分

如果你想要一个随机的分裂,但只需要可重复性呢?在这种情况下,您可以简单地散列行数据本身。这里有一个简单的方法:

SELECT
  airline,
  departure_airport,
  departure_schedule,
  arrival_airport,
  arrival_delay
FROM
  `bigquery-samples`.airline_ontime_data.flights **f**
WHERE
  ABS(MOD(FARM_FINGERPRINT(**TO_JSON_STRING(f))**, 10)) < 8

请注意,如果您有重复的行,那么它们将总是以相同的拆分结束。如果这是一个问题,请在选择查询中添加一个唯一 id 列。

ML & DL 学习路径

原文:https://towardsdatascience.com/ml-dl-learning-path-66edc2e5bd91?source=collection_archive---------10-----------------------

为 ML & DL 提供的无数在线课程&mooc 指南

you could be lost even before you begin

继我之前关于我从商业智能到机器学习世界的转变的帖子之后,(https://towards data science . com/from-Business-Intelligence-to-data-science-94a 1fd 866231),我想分享一下我在这条路上参加的许多在线课程的学习经验。我相信一些关于这些课程顺序的指导会对那些对机器学习感兴趣的新手有很大帮助。此外,我还会指出我在完成其中一些课程(以及没有完成其中一些课程)时遇到的困难程度。

在深入细节之前,让我分享一下我选择以下课程的指导原则——编程语言的选择。当我几年前开始学习这些课程时,机器学习社区广泛采用 R 或 Python 作为编程语言。(在某种程度上,R 在当时的竞争中领先)我甚至以“R 编程”的课程开始介绍 R。但我相信,Python 在机器学习和高级分析的可用库方面很快赶上了 R,并很快受到欢迎。此外,我认为 Python 对于数据科学家/分析师来说是一种更好的语言,因为它是一种多功能的语言,使人们能够在广泛的领域编写项目代码——机器学习、Spark 上的大数据编程、文本挖掘和自然语言处理、用于深度学习的 Pytorch 等(人们甚至可以使用 Python 框架编写 web 应用程序)。此外,不断进入行业的新框架(如 h20 等)支持 python APIs,因为它在编码社区中很受欢迎。顺便说一句,我并不是说选择 R 的人不能学到很多东西,但是了解 python 有利于轻松地过渡到相关框架。

机器学习课程

  1. 斯坦福大学的机器学习——吴恩达

Machine Learning by Stanford

我猜,这实际上是你开始机器学习之旅的地方,由大师(吴恩达)亲自讲授这门课程。很少有人能像他那样清楚地解释这些概念。本课程将为你提供机器学习/高级统计的一些基本技术,如线性/逻辑回归。如果我没记错的话,他用房价数据集的例子解释了这些概念。

我没有完成这门课程,因为它要求用一种叫做 octave 的语言来完成练习,我相信这种语言类似于 Matlab,我太懒了,不想为了完成这门课程而学习一种新的语言。然而,我建议这是你学习道路上的第一站。

https://www.coursera.org/learn/machine-learning

2。用 Python 掌握机器学习——杰森·布朗利

Machine Learning Mastery

杰森·布朗利是该领域为数不多的专家之一(杰瑞米·霍华德是另一位),他提倡自上而下的学习方法。他本人拥有博士学位,但他强烈主张,要成为一名成功的 ML 专业人士,博士并不是必要条件,最重要的是知道如何对数据应用不同的算法以获得结果。稍后,深入研究算法的具体细节。

他的网站https://machinelearningmastery.com/是你在 python 中搜索 ML 相关内容时会遇到的第一批网址之一,并提供了一些非常有用的学习资源。他提供了关于使用 python 进行机器学习/深度学习的电子书,我通过他关于 ML 的电子书“使用 python 掌握机器学习”第一次体验了 scikit learn python 库。除了使用 scikit learn library 之外,人们还将学习在 ML 项目生命周期中要遵循的典型过程,该过程用公开可用的数据集来说明。

预期学习时间—2-4 周,如果你计划每周花几个小时的话。如果你真的迷上了它,你可以在一两个周末轻松度过。你可以把它作为你将来任何项目的参考书

3。华盛顿大学的机器学习专业。讲师——卡洛斯·盖斯特林&艾米丽·福克斯

Machine Learning Specialization

一旦我理解了使用 python 库在数据上应用 ML 算法——scikit learn,我对使用 python 的 ML 专门化课程的搜索将我带到了这个课程。讲师是 Carlos Guestrin 和 Emily Fox,他们共同创建了后来被亚马逊收购的 Dato,他们是华盛顿大学 CS 系的杰出教授。

这是一门由四部分组成的课程,涵盖了最大似然、回归、分类和聚类的基础知识。回归课程在华盛顿房价数据集的帮助下,介绍简单的多元线性回归的概念。分类课程将通过使用决策树的线性模型和非线性模型,介绍这类算法的核心概念。Carlos G 清晰地解释了这些概念,并主要使用直觉来发展对决策树和 glm 模型的理解。他使用公开的亚马逊消费者评论,通过分类技术来预测评论的情绪。(他的插图如此生动,以至于我仍然记得他用评论来分类情绪的长颈鹿玩具)

人们在现实生活中遇到的大多数解决方案都属于分类问题领域,例如,对客户流失、客户产品倾向、高级文本分类等建模,因此如果有帮助的话,可以只做分类课程。

预计研究时间— 各部分 8-12 周

【https://www.coursera.org/specializations/machine-learning?

4。如何赢得数据科学竞赛:向顶级 Kagglers 学习-Coursera

how to win DS competition?

对于渴望在竞争中获胜的 ML 工程师来说,这是一门伟大的课程。在这门课中,我发现了许多在书本和其他课程中找不到的新颖、实用的概念。我认为这是顶级卡格勒人赢得像卡格勒这样的大联盟比赛的终极实用指南。

我能从这门课中回忆起的一些有用的概念是均值因子编码,数据泄漏。我无法完成这门课程,因为我没有太多时间参加比赛,但我肯定会推荐这门课程。

https://www.coursera.org/learn/competitive-data-science

5。H2O H2O 实用机器学习— Coursera

h2o.ai

这是 H2O 公司提供的一门课程,该公司提供自己的开源机器学习/人工智能框架/库,用于在 Spark 等分布式计算框架上进行更快的计算。在 Garner 的魔力象限中,它被提供 ML 框架的供应商评为有远见者。鉴于这一框架目前被广泛采用,将这一框架添加到一个人的剧目中肯定会有所帮助。我也希望有更多的时间来完成这门课程,但是我强烈推荐它。

https://www.coursera.org/learn/machine-learning-h2o

深度学习课程

  1. 【深度学习专业化(Deeplearning.ai)

deeplearning.ai

这是一套关于深度学习的 5 门课程,从入门课程开始,涵盖所有主要类型的 DL 网络 CNN,RNN。这是吴恩达的名言“人工智能是新的电力”,在整个课程中,他借鉴了他在百度的经验。除了课程内容,他还分享了他对深度学习和人工智能领域顶级人物的采访,包括 Andrej Karpathy、Ian Goodfellow 等,标题为“深度学习的英雄”。

在入门课程中,他讲述了神经网络的基础知识,并使用 numpy 库实现了一个工作示例。后来,他使用 tensorsflow 库和 tensor 做了同样的事情。从那里,他涵盖了 CNN 的主题,并解释了图像分类的概念,对象检测,面部检测等。最后,他完成了序列模型(RNN)及其在自然语言处理领域的适用性,NLP。

尽管有使用 tensorflow 的手工示例,但由于我选择 Pyspark 作为深度学习的首选库,所以我不太关注本课程的实践练习。

预期学习时间——每门课程 8-10 周

【https://www.coursera.org/specializations/deep-learning

2。程序员实用深度学习— Fast.ai

fast.ai

杰瑞米·霍华德和瑞秋·托马斯共同创立了专注于深度学习培训内容的 Fast.ai 公司,fast.ai library 对 pytorch 的作用就像 Keras 对 tensorflow 的作用一样。这是一个高度优化深度学习应用程序所需代码的库。在分享课程信息之前,有必要提一下 Jeremy H 编码原则。

与 Jason Brownlee 类似,Jeremy H 来自“自上而下学习方法”学派,该学派主张在深入研究深度学习的具体细节之前实践应用深度学习的实践方面。事实上,他引用了使用自下而上的方法来学习深度学习是多么错误的例子。在开始深度学习之旅之前,一个人不可能学会统计学、数学或计算机科学博士学位以及其他任何与之相关的东西。他是排名第一的卡格勒,是为什么不需要博士学位就能在深度学习应用和研究领域取得成功的经典例子。

这个免费课程大约有 7 个部分,每个部分处理深度学习中的一个不同主题,包括 NLP,CNN,RNN 等。他是我选择 pytorch 而不是 tensorflow 作为深度学习库的原因之一,因为根据他和其他像 Andrej Karpathy 这样的伟人的说法,pytorch 使编码相对于 tensorflow 更简单。此外,根据 Jeremy H 的说法,他所尊重的每个研究人员都将 Pytorch 用于他们的研究目的。此外,它有助于它基于 python 风格,使任何 python 机器学习工程师都能很快掌握。

预计学习时间- 如果想对内容做到恰如其分,完成 1 部分大概需要 2 周时间。尽管我必须承认,我只是浏览了一些内容,因为我想快速了解内容。我当然想把它作为项目的参考来源。

https://course.fast.ai/

3。深度学习纳米学位-uda city

Udacity DL Nanodegree

在参加了杰瑞米·霍华德关于深度学习的课程后,我对深度学习的驱动力增强了,我对 pytorch 认证课程的搜索使我进入了这个课程。Udacity 最初在 tensorflow 中提供这门课程,但由于 pytorch 在研究社区中取得的成功,内容被转移到了 pytorch。另一个加强了我对 Pytorch 的选择的例子是,除了 Pytorch 之外,2018 年所有开源项目中第二重要的更新超过了 Tensorflow。

本课程由多名讲师提供,涵盖神经网络和深度网络的基础知识。从这里开始,它涵盖了所有重要的主题,如主要用于图像分类任务的 CNN(卷积神经网络),用于自然语言处理任务的 RNN(递归神经网络),GANS(生成对抗性神经网络),以及关于在 AWS 上部署生产规模的深度学习模型。

这门课最酷的部分是针对上述每个主题的项目。人们开始编写应用程序,可以根据狗的图像对狗的品种进行分类(CNN),自动生成电视脚本(RNN),使用一组人脸创建假的面部图像(GANs),在 AWS 上部署情感分类器模型,并实时接受评论和返回响应。

预计学习时间- 4 个月

https://in.udacity.com/course/deep-learning-nanodegree-nd 101

4。深度学习研究员 PyTorch 的深度学习实践— Udemy,新加坡国立大学

Udemy — Pytorch Course

当我在寻找 pytorch 培训的内容时,我偶然在 Udemy 上看到了这个课程,并开始浏览。尽管大部分概念看起来像是在重复,但我发现它有助于在 pytorch 上进行实践,并且一些概念用不同的直觉进行了解释。

例如,讲师非常直观地解释了卷积层(即滤波器)中的特征映射的概念以及它的名字的由来。在我看来,有时对同一个主题的不同观点会增强对这个概念的理解,从而加深对它的回忆。

预期学习时间-2-3 个月

https://www.udemy.com/practical-deep-learning-with-pytorch/

感谢你通读这篇文章,我希望你会觉得有用。我想接着在博客、youtube 视频和播客上发一篇我认为值得一听的帖子。

[ML]酒店评分的特征转换、自然语言处理和分类建模

原文:https://towardsdatascience.com/ml-feature-transformation-nlp-and-classification-modeling-on-hotel-scoring-94107353a015?source=collection_archive---------18-----------------------

结合数字特征和文本评论来建立分类模型(神经网络、Xgboost、逻辑)

0.摘要

0.1 奖励

这篇文章的目的是,在我之前的尝试中,我试图为每家酒店的点评者评分建立一个预测模型。事实证明,预测能力并不令人满意,T2 R T3(决定系数)徘徊在 T4 0.4 到 0.5 T5 之间。因此,在这项任务中,我将尝试一种不同的方法,首先将评论者的分数离散化为三个有序类别—低、中、高,然后建立一个分类模型。看看在简化分类方法下是否达到更高的预测能力。该模型应该更容易将评审者的分数分为三个级别,而不是要求得出精确的预测分数。

0.2 数据集的信息

原始数据集从 Booking.com 收集,并在[ Kaggle ]平台上共享。该数据集包含 50 万条酒店评论,收集了 14 个特征,包括数字评分和文本评论。

0.3 车型性能快速汇总

在比较了 MLP、Xgboost 和 Logistic 的模型性能后,我最终选择了 Logistic 模型。结果表明,逻辑斯蒂模型不仅比其他模型表现更好,尽管差距很小,而且在训练上也有相当好的效率。在此任务中还实施了超参数微调,但是结果显示默认配置和优化参数设置之间没有显著的性能差异。

最终模型准确率达到 0.62,F1 评分达到 0.61。如果我们看得更深一点,每一个阶层在人口中所占的份额分别是 35%、29%、36%,与每一个阶层的预测结果的精度分别是 68%、47%、65%相比,我们可以说 Logistic 模型的精度一般是的两倍。

0.4 报告的结构

1.数据预处理

在这一部分,原始数据将经过一系列预处理,以便成为高质量的、随时可用的数据集。它包括缺失值移除、重复移除和异常值移除的实现。

2.探索性可视化

探索性分析包括目标变量和所有特征的统计汇总。可视化数据并观察要素的分布情况。

3.特征工程—离散化

在更加熟悉手头的数据后,我将首先把目标变量分成三组——低、中、高。基于目标变量的分布来定制每个箱的范围,因此,目标变量具有不相等的箱宽度。

4.特征工程—日志转换

从分布图中可以看出,这些特征是高度倾斜的。在模型中输入时,最好使用正态分布特征。因此,大多数数字特征将具有对数变换,并且也被缩放以具有相同的单位,为稍后的建模做准备。

5.特征工程——词语标记化

这个数据集的优势在于它包含酒店客人的文本评论以及他们的评分。因此,我们实际上可以利用文本提供的信息来提高预测模型的准确性。在本节中,文本将通过词条化和标记化进行预处理。然后给单词分配根据 TF-IDF 公式计算的值。

6.相关性分析

在这一部分,我将检查特征工程是否增加了目标变量(评审者的分数)和输入特征之间的相关性。结果显示在相关矩阵中。

7.不同型号的试验

有许多模型非常适合分类案例。在这里,在我的第一次尝试中,我将比较三种模式的性能— 逻辑回归、Xgboost 决策树和神经网络。超参数设置为默认值。

8.微调造型

从上述模型中,选择性能最好的模型作为最终模型,然后通过网格搜索对模型的超参数进行微调,以进一步提高其精度。最终模型将在测试数据集上进行测试,并与默认配置的模型进行比较。

1.预处理数据

Columns in Dataset

︽ 检查数据集行中是否有缺失值或重复值。未完成的行和重复的行将从数据集中删除。

总共有 3268 行包含缺失值和 526 个重复行。删除这些记录后,最终数据集仍有 511,944 条记录。

对数据的样子感兴趣,可以查看链接[ Kaggle ]。

2.探索可视化

︽ 在此部分,将分别显示目标变量和所有其他数值特征。

2.1 目标变量的分布(reviewer_score)

事先,我为下面的可视化定义了一个绘图函数。

Function — Plot Histogram and Mean/Median Line

**Result:**

很明显,评论者的分数分布是左倾。有很大一部分分数分布在 9.5 分及以上。

Distribution of reviewer_score

2.2 特征分布

  • 平均分数
  • 评论总数
  • 附加得分次数
  • 复习 _ 总计 _ 负数 _ 字数
  • 复习总字数

以下几组网格图显示了每个数字特征的 QQ 图和直方图。 QQ-plot 增加可读性,以检查特征是否遵循正态分布。此外,在内核分布旁边增加了一行理论正态分布,用于直方图比较。下面是创建 QQ-plot 和直方图并排的定义函数。

Function — Plot QQ-Plot and Histogram Alongside

**Result:**

我们可以看出,除了平均分数和平均分数之外,几乎所有的特征都是左偏或右偏。根据显示的证据,需要对这些特征进行转换和归一化,以便在使用这些特征作为输入时建模可以达到更高的精度。

QQ-Plot and Histogram over Each Numerical Feature (Before Transformation)

3.特征工程—离散化

3.1 目标变量

︽ 关注目标变量— 审核人 _ 分数,将分为三组。绑定间隔如下,

  1. 低:数值< = 8.0。
  2. 中:8.0 <值< = 9.5。
  3. 高:9.5 <值< = 10.0。

Function — Bin up Variable

**Result:**

Bin Size and Share of Target Variable

离散化后,目标变量分成三组,每组分别为 35%、29%、36%

4.特征工程—测井转换

4.1 功能

数值特征首先进行对数变换,然后缩放到范围(0,1)内。通过这种方式,数值将具有带有分类特征的相同单位,稍后也将被热编码为(0,1)虚拟值。

Log Transformation and MinMax Scaling

**Result:**

从 QQ 图和直方图中,我们可以看出,即使经过变换,特征仍然不太符合正态分布,但至少它们现在不那么偏斜了。

QQ-Plot and Histogram over Each Numerical Feature (After Transformation)

5.特征工程——单词标记化

5.1 整理文本

︽ 在清理文本数据时,我首先将两个独立的评论(一个负面,一个正面)连接成一个,然后让它去掉空白和其他标点符号。

Preview of Text Review (Before Concatenated and After)

5.2 词汇化和标记化

在对文本进行分词之前,我使用分词器进一步提取每个单词的词根,从而剔除不同形式单词的派生词。

然后停止字被忽略,并通过 max_dfmin_df 指定字选择阈值。

二元语法用于标记化,这样我们可以考虑短语中相反的意思,例如非常好不好

随后选择第一个 2500 记号作为模型输入。

Lemmatize and Tokenize

**Result:**

Samples of Tokenized Word (Both Uni-gram and Bi-gram)

6.相关性检验

︽ 下面,我将呈现 target (reviewer_score)和所有其他特征之间的相关性,包括特征转换之前和之后。看看相关性是因为变换而被放大了还是保持不变。

Function — Plot Correlation Matrix

**Result:**

通过观察这种相关性,我得出了一些有趣的发现。

  1. 对于离散化的目标变量(reviewer_score_class ),所有特征的相关性(无论是否经过变换)似乎稍弱。比方说(平均分数与审阅者分数)的相关性为 0.36 ,而(平均分数与审阅者分数类)的相关性为 0.34
  2. 转换后的特征与目标变量有更强的相关性。实际上,当这些转换后的特征作为输入时,这对于后续的建模是一个好兆头。

Correlation Matrix (Target, Discretized Target, and Standardized Features)

7.不同模型的试验

︽:现在是整个任务的关键部分——建模。我将首先在三个不同的模型上进行实验,多感知机、Xgboost 和逻辑回归

这些模型将基于它们在测试数据集上的性能(F1 分数)进行比较。最佳模型将进行到下一部分,即超参数微调。这样我们可以进一步提高它的准确性。

7.1 MLP 模式—培训

7.2 Xgboost 模型—培训

7.3 物流模型——培训

7.4 功能重要性

在拟合 Xgboost 模型时,我们从中获得了额外的好处。Xgboost 可以为我们提供特征重要性的图表,这样我们就可以告诉我们什么样的特征对数据分类更有帮助和影响。

Plot Top Feature Importance From Xgboost Model

**Result:**

快速排序在这里,我们可以从特性重要性图(Xgboost)中看出,确定的前 5 个重要特性是,

  1. review _ total _ negative _ words _ count _ STD(数字)
  2. review _ total _ positive _ words _ count _ STD(数字)
  3. average_score_std(数字)
  4. 位置(单词)
  5. 五线谱(word)

值得注意的一点是,这里我选择同时使用单字和双字作为输入特征,似乎最重要的标记是单字,而不是一个双字排在前 20 个重要特征中。

Feature Importance Ranking

7.5 最终选择的模型:逻辑回归

结果是,逻辑回归在测试数据集上达到了最佳性能(F1 分数),尽管只是很小的差距。但考虑到它在如此大量的数据和特征(超过 2000 个特征)上的训练效率,这确实令人印象深刻。

因此,在下一节中,我将进一步微调逻辑回归的超参数。但总的来说,三个模型在分类数据集方面都表现得很好,准确率都在 60% 以上,相比之下随机猜测的准确率在 33% 左右,这是一个相当大的预测能力增益。下表列出了更多详细信息。

Table of Performance over Models

8.微调选择的模型

︽ 在这一部分,我将进一步微调逻辑模型的超参数,看看它是否能进一步提高模型的性能。

被微调(网格搜索)的超参数是 C惩罚。这两个参数都负责模型的正则化。

8.1 微调模型-培训

通过热图可视化,我们甚至可以更好地掌握不同超参数组合的整体性能。让我们看看下面的图表。

在热图中绘制网格搜索分数的函数参考了Python 机器学习入门 初学者必备的 ML 书。

Function — Plot Grid Search Scores in Heat map

**Result:**

Score Heatmap over Parameters

选择的最佳参数是 C0.5L1

似乎一旦 C 超过 0.5,模型的性能就达到了平稳状态。精度没有提高。

此外,微调带来的好处似乎微不足道,没有显著的改善。因为右上角的大多数分数始终保持在 0.61。

8.2 网格搜索前后的性能

现在,让我们检查一下,相对于没有超参数微调,它获得了多少改进。

**Result:**

Score of Before and After Grid Search on Test Data

结论

在对评论者的评分进行清理、转换、训练和微调分类模型的所有努力之后。该模型在识别低分和高分方面表现很好,但在识别处于中间的 T2 分数方面表现不佳。

参见回忆,该模型实际上只能识别出所有得分中的 31% ,这意味着其余的 69% 被错误地归类为低水平或高水平。

尽管如此,如果我们看看精度,那么至少模型达到了 47% 的准确度,这意味着对于每个被标记为中等的样本,有 47%的几率是正确的。与随机猜测的结果相比, 29% 。这仍然被认为是一个重大的收获。

综合 jupyter 笔记本可以在这个链接找到:【 Github 】。如果你喜欢这篇文章,欢迎在下面留下你的反馈。让我们一起把这个模型改进得更好!!!

参考:

[1] 定制矢量器类(版本 0.20.2),sckite-learn

[2] A. Muller,用 Python 进行机器学习的介绍 (2018),github

[3] S. Hallows,探索 XGBoost 的使用及其与 Scikit 的集成-Learn (2018),kaggle

[4] S. Miller,XGBoost with Python(2018),数据科学中心

[5] J. Brownlee,Python 中 XGBoost 的特征重要性和特征选择 (2016),机器学习掌握

[6] J. Brownlee,Python 中如何用 XGBoost 保存梯度增强模型 (2016),机器学习掌握

雪花中的 ML 第 2 部分:k 均值聚类

原文:https://towardsdatascience.com/ml-in-snowflake-part-2-k-means-clustering-b943c829477?source=collection_archive---------26-----------------------

我们喜欢的理解世界的方式之一是将相似的事物组合在一起。

在设计中,我们把颜色分成不同的色调。在销售和市场营销中,客户通常被细分以适应他们的差异。在统计学中,聚类是一种广泛使用的无监督学习技术,用于帮助组织数据集。

您可能已经从我以前的故事中注意到,雪花不仅仅可以用于检索或聚合数据。它可以大规模扩展到各种与数据相关的任务,并与更传统的工作负载和平共存。

在这个故事中,我将演示在雪花中运行的 k-means 聚类,其方式可以很好地扩展到大型数据集。这是最终产品的一个快速可视化画面:

The large dots are the cluster centroids, small dots are the data points

什么是 k-means?

我将把解释留给专家,StatQuest 有一个很棒的视频描述了 k-means 聚类是如何工作的:

雪花实现

首先,从我们账户中的样本数据中获取一些天气数据:

It’s always good beach weather in Australia

这是一个很大的表,所以为了节省时间,我只是快速地从顶部切下一百万行并对它们进行采样。

现在,我们将创建一个表来跟踪不同表和列的 k-means 元数据:

我们稍后将介绍质心列的用途。

我们希望能够将源表中的每一行分配给一个特定的集群,因此为此添加一个额外的列。

使用存储过程将整个事情联系在一起。完整的源代码是这里,但我会一步一步地解释。

调用 k-means 存储过程如下所示:

call k_means('AUSTRALIAN_WEATHER', 'LAT,LON','CLUSTER_INDEX', 5, 10)

简单地说:对于 AUSTRALIAN_WEATHER 表中的每一行,使用 10 次迭代训练,将纬度和 LON 组合分配给 5 个分类中的一个。将最后一个集群标识符放入 CLUSTER_INDEX 列。

该存储过程执行以下操作:

  1. 从 KMEANS_CLUSTERS 表中删除“AUSTRALIAN_WEATHER”中“LAT,AUSTRALIAN”的任何现有分类元数据。
  2. 从表中随机抽取 5 行样本,并使用这些样本的纬度和 LON 值作为 5 个初始聚类的中心点(或“质心”)。
  3. 将这些初始聚类质心插入到 KMEANS_CLUSTERS 表中。此后,KMEANS_CLUSTERS 表如下所示:

These are just randomly chosen points, now the k-means algorithm takes over and moves them around.

4.定义了分类后,存储过程现在使用用户定义的函数(UDF)将每一行分配给最近的分类:

For some reason this preview is being truncated, see here for the full code: https://gist.github.com/jamesweakley/edd9edfa3d9cffe3134e8e0f83670844

存储过程生成 SQL,该 SQL 将此 UDF 用作 UPDATE 语句的一部分:

5.更新所有记录的分类索引后,存储过程通过获取每个分类的平均 x 和 y 值来计算新的质心:

步骤 4 和 5 循环重复,直到所有的迭代用完。每次,当记录从一个群集移动到另一个群集时,群集质心通常会稍微移动。

"你是如何做出如此酷的观想的?"

很高兴你问了。

雪花有一个特性叫做时间旅行,基本上就是说你可以在定义的时间旅行窗口内从任意时间点查询一个表。

为了利用这一点,我首先为 Tableau 提供了一个定制查询,该查询将检索我在过去一个小时内运行的每个查询的准确时间戳,我在这里更新了 AUSTRALIAN_WEATHER 表:

select END_TIME::timestamp_ntz as END_TIME
from table(information_schema.query_history_by_user(USER_NAME => CURRENT_USER(), END_TIME_RANGE_START => TIMESTAMPADD(hour,-1,CURRENT_TIMESTAMP())))
where QUERY_TEXT like 'update "AUSTRALIAN_WEATHER"%'
order by start_time asc

结果如下:

然后,当查询您的实际表时,您可以创建一个从该列表中取值的参数:

并使用“at”限定符从参数中选择时间点。

把这个加到你的桌面上,你就有了一个时间旅行装置!